Mathpack
This gem includes a collection of mathematical methods
Installation
Add this line to your application's Gemfile:
gem 'mathpack'
And then execute:
$ bundle
Or install it yourself as:
$ gem install mathpack
Information
Mathpack
includes following modules:
- SLE. Solves system of linear equations
- Statistics. Provides methods to analyze data samples
- Functions. Collects mathematical functions
- Approximation. Allows to approximate table and analytical functions by polynom
- NonlinearEquations. Solves nonlinear mathematical equations
- IntegralEquations. Solves integral second order Fredholm and Volter equations
- DifferentialEquations. Solves system of differential equations with left border initial conditions
- Integration. Integrates functions
- IO. Prints data
- Functional. Lambda functions
Statistics
Statistics
class have following methods
number
returns a number of elements in series
mean
returns a mean of series
variance
returns a variance of series
skewness
returns a skewness
kurtosis
returns a kurtosis
min
returns the minimal element of series
max
returns the maxinal element of series
raw_moment(n)
returns the nth raw moment of series
central_moment(n)
returns the nth central moment of series
empirical_cdf(x)
empirical distribution function value in x
empirical_pdf(x)
returns empirical probability density function value in x
print_empirical_cdf(filename)
allows to print empirical_cdf table function to filename
print_empirical_pdf(filename)
allows to print empirical_pdf table function to filename
trend
returns trend polynom coefficients
Usage
stat = Mathpack::Statistics.new([1, 2, 5, 6])
stat.number() #=> 4
stat.mean() #=> 3.5
stat.variance() #=> 4.25
stat.kurtosis() #=> -1.778546712802768
stat.skewness() #=> 0.0
stat.min() #=> 1
stat.max() #=> 6
stat.raw_moment(3) #=> 87.5
stat.central_moment(4) #=> 22.0625
stat.empirical_cdf(5.5) #=> 0.75
stat.empirical_pdf(3) #=> 0.07639393483317147
stat.print_empirical_cdf('cdf.csv') #=> nil
stat.print_empirical_pdf('pdf.csv') #=> nil
stat.trend(polynom_power: 1) #=> 1.7999999999999996*x - 0.9999999999999987
Functions
Functions
module includes a collection of popular functions.
gamma(x)
beta(x, y)
erf(x) (Laplace function)
dawson_plus(x)
dawson_minus(x)
NonlinearEquations
solve(params = {})
returns solution of nonlinear equation.
Parameters
- start - point to start iteration process
- eps - calculations accuraccy
Usage
Now you have no problems solving nonlinear equations. If you want, for example, to solve equation
You need to complete the following steps:
- Equation should look like
- For our equation
- Choose the calculations accurracy. For example
- Choose some point near the expected root of equation. For example
Then to solve equation you should call
Mathpack::NonlinearEquations.solve(start: 0, eps: 0.00001){|x| x**2 - Math.sin(x+1)})
Here is some other examples of solve usage
Mathpack::NonlinearEquations.solve(start: 0, eps: 0.00001){|x| x**2 - Math.sin(x+1)})
Mathpack::NonlinearEquations.solve(start: 0.01, eps: 0.00001){|x| 1/x - Math.log(x)})
Mathpack::NonlinearEquations.solve(start: 0.01, eps: 0.00001){|x| x**2 - 2*x + 1})
Mathpack::NonlinearEquations.solve(start: 0.01, eps: 0.00001){|x| Math.exp(x-2) - Math.sin(x)})
solve_system(params = {})
returns solution of system of nonlinear equations by Newton method
Parameters
- start - vector to start iteration process
- eps - calculations accuraccy
- f - vector of right part lambdas
- w_matrix - matrix W in Newton method
Usage
If you have system of equations
For example, if you have system
W matrix and f vector is equal
f = -> x, y { [x + y - 3.0, x**2 + y**2 - 9.0] }
w = -> x, y { [[1, 1], [2 * x, 2 * y]] }
Mathpack::NonlinearEquations.solve_system(start: [1, 5], eps: 1e-4, f: f, w_matrix: w) #=> [-1.829420851037002e-12, 3.0000000000018296]
IntegralEquations
solve_fredholm_2(params={})
returns solution of integral equation as a hash of nodes and values arrays.
Parameters
- from - left border
- to - right border
- lambda - lambda parameter
- k - kernel function (2 arguements)
- f - inhomogeneity function (1 arguement)
- eps - accuracy
Usage
Let we have the following integral equation
If you want to solve equation with accuracy 1e-5, you should call
k = -> x, t { 1.0 / (x + t**2)**0.5 }
f = -> x { 2*x + (x + 1)**0.5 - (x + 4)**0.5 }
Mathpack::IntegralEquations.solve_fredholm_2(from: 1.0, to: 2.0, lambda: 0.5, eps: 1e-5, k: k, f: f)
#=> {:x=>[1.0, 1.125, 1.25, 1.375, 1.5, 1.625, 1.75, 1.875, 2.0], :f=>[1.9999989550044168, 2.2499991010033416, 2.499999229316462, 2.7499993410739187, 2.9999994379022, 3.2499995215457123, 3.4999995936848047, 3.7499996558559117, 3.9999997094242845]}
solve_volter_2(params{})
returns solution of integral equation as a hash of nodes and values arrays.
Parameters
- from - left border
- to - right border
- lambda - lambda parameter
- k - kernel function (2 arguements)
- f - inhomogeneity function (1 arguement)
- eps - accuracy
Usage
Let we have the following integral equation
If you want to solve equation with accuracy 1e-3, you should call
k = -> x, t { Math.cos(x - t) }
f = -> x { 0.75 * Math.exp(x) + 0.25 * Math.cos(x) - 0.25 * Math.sin(x) }
Mathpack::IntegralEquations.solve_volter_2(from: 0.0, to: 1.0, lambda: 0.5, eps: 1e-3, k: k, f: f)
#=> {:x=>[0.0, 0.0625, 0.125, 0.1875, 0.25, 0.3125, 0.375, 0.4375, 0.5, 0.5625, 0.625, 0.6875, 0.75, 0.8125, 0.875, 0.9375, 1.0], :f=>[1.0, 1.0644951210235056, 1.1331511709098798, 1.2062365414157485, 1.2840369296892897, 1.3668564541117094, 1.455018842114489, 1.5488686946157586, 1.6487728320186184, 1.755121727033003, 1.868331029922017, 1.9888431921348702, 2.117129194673052, 2.2536903879456665, 2.3990604503055315, 2.5538074729214233, 2.718536179135541]}
DifferentialEquations
solve_cauchie_system(params={})
returns solution of differential equations system as a hash of nodes and values arrays for each function. For example, { x: [], u1: [], u2: [], ... }
Parameters
- from - left border
- to - right border
- system - array of lambdas representing each row of system
- y0 - array of values of derivatives on left border. Starts with first derivative
- eps - accuracy
Usage
Let we have following system of differential equations
where
If you want to solve this system with accuracy 1e-6, you should call
cauchie_problem = [ ->(x, u1, u2) { u2 }, -> (x, u1, u2) { - 1.0 / x * u2 + 1.0 / x**2 * u1 + 3.0 }]
Mathpack::DifferentialEquations.solve_cauchie_system(from: 1.0, to: 2.0, eps: 1e-6, system: cauchie_problem, y0: [1.0, 1.0])
#=> {:x=>[1.0,..., 2.0], :u1=>[1,...], :u2=>[1,...] }
SLE
solve(params = {})
returns solution of system of linear equations.
Parameters
- matrix - system matrix
- f - right part vector
Usage
Let's solve some system of linear equations. It can be written as
where A is n-n matrix, X - vector of unknown, B - vector
If you want to solve this system you should call
Mathpack::SLE.solve(matrix: A, f: B)
Parameter A can be Array or Matrix class. If Array is given result will be Array class. If Matrix is given result will be Matrix class.
a = [[1, 2, 3], [4, 5, 6],[3, 5, 2]]
b = [15, 30, 15]
Mathpack::SLE.solve(matrix: a, f: b) #=> [-1.0, 2.0, 4.0]
a = Matrix[[1, 2, 3], [4, 5, 6],[3, 5, 2]]
b = Matrix.row_vector [15, 30, 15]
Mathpack::SLE.solve(matrix: a, f: b) #=> Matrix[[-1.0, 2.0, 4.0]]
Approximation
approximate_by_polynom(params = {})
returns array of coefficients of polynom, approximating given function on [from, to] segment.
Parameters
- x - array of approximation nodes
- polynom_power - power of approximation polynom
- f - functions values in x if you have table function
generate_nodes(params = {})
returns nodes for approximation with some step.
Parameters
- from - first node
- to - last node
- step - step between nodes
print_polynom(coefficients)
returns a string representing polynom with given coefficients.
Usage
# Function to print polynom having it's coefficients
Mathpack::Approximation.print_polynom([1, -2, 1]) #=> x^2 - 2*x + 1
# Function to generate nodes for approximation. Only choose start value, end value and step
x = Mathpack::Approximation.generate_nodes(from: 0, to: 10, step: 0.25)
#=> [0, 0.25, ..., 10]
# Function that approximate given function by polynom with power polynom_power in approximation nodes x and returns coefficients of approximating polynom
result = Mathpack::Approximation.approximate_by_polynom(x: x, polynom_power: 5){ |x| Math.sin(x) }
#=> [0.0008009744982571882, -0.030619986086758588, 0.3805927651948083, -1.8481035413353888, 2.985465287759307, -0.3873066069630569]
# May be you want to print this polynom, let's call print_polynom function
Mathpack::Approximation.print_polynom(result)
#=> 0.0008009744982571882*x^5 - 0.030619986086758588*x^4 + 0.3805927651948083*x^3 - 1.8481035413353888*x^2 + 2.985465287759307*x - 0.3873066069630569
# If you have a table of values, where x - array of arguement values and f - array of function values, call approximate by polynom function with parameter f instead of block
result = Mathpack::Approximation.approximate_by_polynom(x: [1, 2, 3], f: [1, 4, 9], polynom_power: 2) #=> [1, 0, 0]
Mathpack::Approximation.print_polynom(result) #=> x^2
Integration
integrate(params = {})
returns integral value.
Parameters
- from - start of integration
- to - end of integration
Usage
Let you have the following integral:
Where a can be finite or equal to , and b can be finite or equal to
. To find value of integral you should call integrate method of Integration module.
Mathpack::Integration.integrate(from: a, to: b){ |x| f(x) }
Let's demostrate some examples of Integration module practical usage:
Mathpack::Integration.integrate(from: 0, to: 3.6){ |x| Math.sin(x) / x } #=> 1.8219481156495034
Mathpack::Integration.integrate(from: 0, to: Float::INFINITY){ |x| Math.exp(-x) / (x + 1) } #=> 0.5963473623136091
Mathpack::Integration.integrate(from: -Float::INFINITY, to: Float::INFINITY){ |x| Math.exp(-x**2) * Math.cos(x) } #=> 1.3803884100161075
IO
print_table_function(params = {})
writes table function values to file
Parameters
- filename - name of output file
- x - arguements array
- y - function values array
- labels - hash of labels names for x and y column
read_table_function(filename)
returns table function values hash, written to filename
Usage
If you have table function, represented by argument array and function values array, you should use print_table_function, that prints your data to filename file. If you have table function, written to filename file, you should use read_table_function, that
Mathpack::IO.print_table_function(filename: 'table.csv', x: [1, 2, 3], y: [2, 4, 6], labels: { x: 'x', y: 'f(x)'})
Mathpack::IO.read_table_function('table.csv') #=> { x: [1, 2, 3], y: [2, 4, 6] }
Contributing
- Fork it ( https://github.com/[my-github-username]/mathpack/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request