mathpack 0.4.4 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 218d151cc62bb32f4f7080413b396d4d11f585ee
4
- data.tar.gz: 8929b3f9775a341f3f491f1eb26bad71e490be51
3
+ metadata.gz: a8ce50434e6550fb905aa1cb215106fc208af310
4
+ data.tar.gz: 2bce06f9c4b43424bf26923d0ecf7c91789253d3
5
5
  SHA512:
6
- metadata.gz: c45dcf42f3b70354c4a536aa5a053b5c1390664cd857d463d1ba1175277a01647772465861c7d3ec0d805229e622eac0b0288be24899968e9c717cd38f80fc36
7
- data.tar.gz: 40d736560eb81d34c25c1dc985cdda85d838b8bc24c810469bed7ae6b6f562e5c7ff54f28de72c95a9021c13d8a6aeff2444f18963f2acde0026f8c216d598b8
6
+ metadata.gz: 8568cd24de9e9404a584e7f2723c62f604cfd5a9e8235f393f9f6438770b865dd0e569d8ce57d736f567b76c94edc7c1182efd484c17cc178bd6fdf01f2fcdc0
7
+ data.tar.gz: 5eb2691333cc2af964d925a4f7c3c6c75598c08c6229b6d321a6011e9003e7ceb89e463c13d99e47a7af149f2e4fbb44cf10bcb83ec4c9fe3ad05fa06dee9eff
data/README.md CHANGED
@@ -17,15 +17,17 @@ And then execute:
17
17
  Or install it yourself as:
18
18
 
19
19
  $ gem install mathpack
20
+
20
21
  ## Information
21
22
  `Mathpack` includes following modules:
22
23
  - **SLE**. Solves system of linear equations
23
24
  - **Statistics**. Provides methods to analyze data samples
24
25
  - **Functions**. Collects mathematical functions
25
26
  - **Approximation**. Allows to approximate table and analytical functions by polynom
26
- - **Equation**. Solves unlinear mathematical equations
27
+ - **NonlinearEquations**. Solves unlinear mathematical equations
27
28
  - **Integration**. Integrates functions
28
29
  - **IO**. Prints data
30
+ - **Functional**. Lambda functions
29
31
 
30
32
  ## Statistics
31
33
  `Statistics` class have following methods
@@ -51,10 +53,10 @@ returns the **nth** central moment of series
51
53
  empirical distribution function value in **x**
52
54
  #### empirical_pdf(x)
53
55
  returns empirical probability density function value in **x**
54
- #### print_empirical_cdf_to_csv(filename)
55
- allows to print empirical_cdf table function to **filename.csv**
56
- #### print_empirical_pdf_to_csv(filename)
57
- allows to print empirical_pdf table function to **filename.csv**
56
+ #### print_empirical_cdf(filename)
57
+ allows to print empirical_cdf table function to **filename**
58
+ #### print_empirical_pdf(filename)
59
+ allows to print empirical_pdf table function to **filename**
58
60
  #### trend
59
61
  returns trend polynom coefficients
60
62
 
@@ -72,8 +74,8 @@ stat.raw_moment(3) #=> 87.5
72
74
  stat.central_moment(4) #=> 22.0625
73
75
  stat.empirical_cdf(5.5) #=> 0.75
74
76
  stat.empirical_pdf(3) #=> 0.07639393483317147
75
- stat.print_empirical_cdf_to_csv('cdf') #=> nil
76
- stat.print_empirical_pdf_to_csv('pdf') #=> nil
77
+ stat.print_empirical_cdf('cdf.csv') #=> nil
78
+ stat.print_empirical_pdf('pdf.csv') #=> nil
77
79
  stat.trend(polynom_power: 1) #=> 1.7999999999999996*x - 0.9999999999999987
78
80
  ```
79
81
 
@@ -90,11 +92,11 @@ stat.trend(polynom_power: 1) #=> 1.7999999999999996*x - 0.9999999999999987
90
92
  #### dawson_minus(x)
91
93
  ![equation](http://latex.codecogs.com/gif.latex?D_%7B-%7D%28x%29%20%3D%20e%5E%7Bx%5E%7B2%7D%7D%5Cint_%7B0%7D%5E%7Bx%7De%5E%7B-t%5E%7B2%7D%7Ddt)
92
94
 
93
- ## Equation
95
+ ## NonlinearEquations
94
96
  #### solve(params = {})
95
97
  returns solution of nonlinear equation.
96
98
  ##### Parameters
97
- - *start* - point to start root search
99
+ - *start* - point to start iteration process
98
100
  - *eps* - calculations accuraccy
99
101
 
100
102
  ### Usage
@@ -108,14 +110,43 @@ You need to complete the following steps:
108
110
 
109
111
  Then to solve equation you should call
110
112
  ```ruby
111
- Mathpack::Equation.solve(start: 0, eps: 0.00001){|x| x**2 - Math.sin(x+1)})
113
+ Mathpack::NonlinearEquations.solve(start: 0, eps: 0.00001){|x| x**2 - Math.sin(x+1)})
112
114
  ```
113
115
  Here is some other examples of **solve** usage
114
116
  ```ruby
115
- Mathpack::Equation.solve(start: 0, eps: 0.00001){|x| x**2 - Math.sin(x+1)})
116
- Mathpack::Equation.solve(start: 0.01, eps: 0.00001){|x| 1/x - Math.log(x)})
117
- Mathpack::Equation.solve(start: 0.01, eps: 0.00001){|x| x**2 - 2*x + 1})
118
- Mathpack::Equation.solve(start: 0.01, eps: 0.00001){|x| Math.exp(x-2) - Math.sin(x)})
117
+ Mathpack::NonlinearEquations.solve(start: 0, eps: 0.00001){|x| x**2 - Math.sin(x+1)})
118
+ Mathpack::NonlinearEquations.solve(start: 0.01, eps: 0.00001){|x| 1/x - Math.log(x)})
119
+ Mathpack::NonlinearEquations.solve(start: 0.01, eps: 0.00001){|x| x**2 - 2*x + 1})
120
+ Mathpack::NonlinearEquations.solve(start: 0.01, eps: 0.00001){|x| Math.exp(x-2) - Math.sin(x)})
121
+ ```
122
+ #### solve_system(params = {})
123
+ returns solution of system of nonlinear equations by *Newton method*
124
+ ##### Parameters
125
+ - *start* - vector to start iteration process
126
+ - *eps* - calculations accuraccy
127
+ - *f* - vector of right part lambdas
128
+ - *w_matrix* - matrix *W* in Newton method
129
+
130
+ ### Usage
131
+ If you have system of equations ![equation](http://latex.codecogs.com/gif.latex?f_%7Bi%7D%28x%29%20%3D%200%2C%20i%20%3D%200%2C%201%2C%20...%2C%20N-1)
132
+
133
+ ![equation](http://latex.codecogs.com/gif.latex?f%28x%29%20%3D%20%5Cbegin%7Bpmatrix%7D%20f_%7B0%7D%28x%29%5C%5C%20%5Ccdots%5C%5C%20f_%7BN-1%7D%28x%29%20%5Cend%7Bpmatrix%7D)
134
+
135
+ ![equation](http://latex.codecogs.com/gif.latex?W%28x%29%20%3D%20%5Cbegin%7Bpmatrix%7D%20%5Cfrac%7B%5Cpartial%20f_%7B0%7D%28x%29%7D%7B%5Cpartial%20x_%7B0%7D%7D%26%5Ccdots%26%5Cfrac%7B%5Cpartial%20f_%7B0%7D%28x%29%7D%7B%5Cpartial%20x_%7BN-1%7D%7D%5C%5C%20%5Ccdots%26%5Cddots%20%26%5Ccdots%20%5C%5C%20%5Cfrac%7B%5Cpartial%20f_%7BN-1%7D%28x%29%7D%7B%5Cpartial%20x_%7B0%7D%7D%26%5Ccdots%26%20%5Cfrac%7B%5Cpartial%20f_%7BN-1%7D%28x%29%7D%7B%5Cpartial%20x_%7BN-1%7D%7D%5C%20%5Cend%7Bpmatrix%7D)
136
+
137
+ For example, if you have system
138
+
139
+ ![equation](http://latex.codecogs.com/gif.latex?%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D%20x_%7B1%7D%20+%20x_%7B2%7D%20-%203%20%3D%200%5C%5C%20%7Bx_%7B1%7D%7D%5E%7B2%7D%20+%20%7Bx_%7B2%7D%7D%5E2%20-%209%20%3D%200%20%5Cend%7Bmatrix%7D%5Cright.)
140
+
141
+ W matrix and f vector is equal
142
+
143
+ ![equation](http://latex.codecogs.com/gif.latex?W%28x%29%20%3D%20%5Cbigl%28%5Cbegin%7Bsmallmatrix%7D%201%20%26%201%5C%5C%202x_%7B1%7D%262x_%7B2%7D%20%5Cend%7Bsmallmatrix%7D%5Cbigr%29)
144
+
145
+ ![equation](http://latex.codecogs.com/gif.latex?f%28x%29%20%3D%20%5Cbigl%28%5Cbegin%7Bsmallmatrix%7D%20x_%7B1%7D%20+%20x_%7B2%7D%20-%203%5C%5C%20%7Bx_%7B1%7D%7D%5E%7B2%7D%20+%20%7Bx_%7B2%7D%7D%5E%7B2%7D%20-%209%20%5Cend%7Bsmallmatrix%7D%5Cbigr%29)
146
+ ```ruby
147
+ f = -> x, y { [x + y - 3.0, x**2 + y**2 - 9.0] }
148
+ w = -> x, y { [[1, 1], [2 * x, 2 * y]] }
149
+ Mathpack::NonlinearEquations.solve_system(start: [1, 5], eps: 1e-4, f: f, w_matrix: w) #=> [-1.829420851037002e-12, 3.0000000000018296]
119
150
  ```
120
151
 
121
152
  ## SLE
@@ -213,19 +244,24 @@ Mathpack::Integration.integrate(from: -Float::INFINITY, to: Float::INFINITY){ |x
213
244
  ## IO
214
245
 
215
246
  #### print_table_function(params = {})
216
- writes table function values to *.csv* file
247
+ writes table function values to file
217
248
  ##### Parameters
218
249
  - *filename* - name of output file
219
250
  - *x* - arguements array
220
251
  - *y* - function values array
221
252
  - *labels* - hash of labels names for *x* and *y* column
222
253
 
254
+ #### read_table_function(filename)
255
+ returns table function values hash, written to **filename**
256
+
223
257
  ### Usage
224
258
 
225
259
  If you have table function, represented by argument array and function values array, you should use
226
- **print_table_function**, that prints your data to **filename.csv** file.
260
+ **print_table_function**, that prints your data to **filename** file.
261
+ If you have table function, written to **filename** file, you should use **read_table_function**, that
227
262
  ```ruby
228
263
  Mathpack::IO.print_table_function(filename: 'table.csv', x: [1, 2, 3], y: [2, 4, 6], labels: { x: 'x', y: 'f(x)'})
264
+ Mathpack::IO.read_table_function('table.csv') #=> { x: [1, 2, 3], y: [2, 4, 6] }
229
265
  ```
230
266
 
231
267
  ## Contributing
@@ -1,8 +1,9 @@
1
1
  require 'mathpack/version'
2
2
  require 'mathpack/statistics'
3
- require 'mathpack/equation'
3
+ require 'mathpack/nonlinear_equations'
4
4
  require 'mathpack/sle'
5
5
  require 'mathpack/approximation'
6
6
  require 'mathpack/integration'
7
7
  require 'mathpack/io'
8
8
  require 'mathpack/functions'
9
+ require 'mathpack/functional'
@@ -0,0 +1,46 @@
1
+ module Mathpack
2
+ module Functional
3
+ @@minus = -> f,g { -> x { f.(x) - g.(x) } }
4
+ @@div = -> f,g { -> x { f.(x) / g.(x) } }
5
+ @@mult = -> f,g { -> x { f.(x) * g.(x) } }
6
+ @@norm = -> f { -> x { f.(x).abs } }
7
+ @@const = -> const { -> x { const} }
8
+
9
+ @@plus_eps = -> eps { -> f { -> x { f.(x + eps) } } }
10
+ @@min_eps = -> eps { -> f { -> x { f.(x - eps) } } }
11
+
12
+ @@inf = -> f,g { -> x { f.(x) < g.(x) } }
13
+
14
+ @@lim = -> f,eps,prec {
15
+ -> x {
16
+ @@inf.(@@norm.(@@minus.(@@plus_eps.(eps/2.0).(f), @@plus_eps.(eps).(f))) , @@const.(prec) ).(x) ? @@plus_eps.(eps).(f).(x) : @@lim.(f,eps/2.0,prec).(x)
17
+ }
18
+ }
19
+
20
+ @@derivative_sheme = -> f {
21
+ -> x {
22
+ -> eps {
23
+ @@div.( @@minus.(@@plus_eps.(eps).(f), @@min_eps.(eps).(f) ), @@mult.(@@const.(2), @@const.(eps))).(x)
24
+ }
25
+ }
26
+ }
27
+
28
+ @@derivate = -> f{
29
+ -> x {
30
+ @@lim.(@@derivative_sheme.(f).(x),1, 1e-16).(0)
31
+ }
32
+ }
33
+
34
+ @@n_times = -> n,f {
35
+ n == 1 ? f : -> x { f.(@@n_times.(n - 1,f).(x))}
36
+ }
37
+
38
+ @@nth_derivator = -> n {
39
+ @@n_times.(n,@@derivate)
40
+ }
41
+
42
+ def self.derivative(n, &f)
43
+ @@nth_derivator.(n).(f)
44
+ end
45
+ end
46
+ end
@@ -19,5 +19,9 @@ module Mathpack
19
19
  def self.dawson_minus(x)
20
20
  Math.exp(x**2) * Mathpack::Integration.integrate(from: 0.0, to: x) { |x| Math.exp(-x**2) }
21
21
  end
22
+
23
+ def self.heaviside(x)
24
+ x <= 0 ? 0 : 1
25
+ end
22
26
  end
23
27
  end
@@ -2,6 +2,7 @@ module Mathpack
2
2
  module Integration
3
3
  STEP = 0.0078125
4
4
  INTEGRATION_LIMIT = 1e2
5
+
5
6
  def self.integrate(params = {}, &f)
6
7
  if params[:from] == -Float::INFINITY && params[:to] == Float::INFINITY
7
8
  result = solve_oi(-INTEGRATION_LIMIT, INTEGRATION_LIMIT, &f)
@@ -7,9 +7,10 @@ module Mathpack
7
7
  @@numbers = %w{0 1 2 3 4 5 6 7 8 9}
8
8
  @@math_constants = { 'pi' => 'Math::PI' }
9
9
  @@math_functions = { 'ln(' => 'Math.log(', 'e**(' => 'Math.exp(', 'arctg(' => 'Math.atan(', 'arcsin(' => 'Math.asin(', 'arccos(' => 'Math.acos(', 'sin(' => 'Math.sin(', 'cos(' => 'Math.cos(', 'tg(' => 'Math.tan(', 'lg(' => 'Math.log10(' }
10
+
10
11
  def self.print_table_function(params = {})
11
12
  fail 'Arrays length dismatch' if params[:x].length != params[:y].length
12
- File.open(params[:filename] + '.csv'|| 'table_function.csv', 'w+') do |file|
13
+ File.open(params[:filename]|| 'table_function.csv', 'w+') do |file|
13
14
  file.write("#{params[:labels][:x]};#{params[:labels][:y]}\n") if params[:labels] && params[:labels][:x] && params[:labels][:y]
14
15
  params[:x].each_index do |i|
15
16
  file.write("#{params[:x][i]};#{params[:y][i]}\n")
@@ -20,7 +21,7 @@ module Mathpack
20
21
  def self.read_table_function(filename)
21
22
  x = []
22
23
  y = []
23
- data = File.read(filename + '.csv')
24
+ data = File.read(filename)
24
25
  rows = data.split("\n")
25
26
  rows.delete!(0) unless rows[0].split(';')[0].to_f
26
27
  rows.each do |row|
@@ -95,5 +96,16 @@ module Mathpack
95
96
  calculate = -> str { ->x { eval str.gsub('var', x.to_s) } }
96
97
  calculate.(valid_function)
97
98
  end
99
+
100
+ def self.count_diff(first_array, second_array)
101
+ if first_array.length == second_array.length
102
+ diff = Array.new(first_array.length){ |i| (first_array[i] - second_array[i]).abs }
103
+ elsif first_array.length == second_array.length * 2 - 1
104
+ diff = Array.new(second_array.length) { |i| (first_array[2 * i] - second_array[i]).abs }
105
+ else
106
+ fail 'Arrays length mismatch'
107
+ end
108
+ diff.max
109
+ end
98
110
  end
99
111
  end
@@ -0,0 +1,39 @@
1
+ module Mathpack
2
+ module NonlinearEquations
3
+ def self.solve(params = {}, &function)
4
+ xk1 = params[:start]
5
+ loop do
6
+ xk = xk1
7
+ xk1 = xk - function.call(xk) / derivative(xk, &function)
8
+ break if (xk1 - xk).abs < params[:eps]
9
+ end
10
+ xk1
11
+ end
12
+
13
+ def self.solve_system(params = {})
14
+ xk1 = params[:start].dup
15
+ loop do
16
+ xk = xk1.dup
17
+ w_xk = params[:w_matrix].call(*xk, *params[:additional_params])
18
+ f = params[:f].call(*xk, *params[:additional_params])
19
+ delta = Mathpack::SLE.solve(matrix: w_xk, f: invert(f))
20
+ xk1 = plus(xk, delta)
21
+ break if Mathpack::IO.count_diff(xk1, xk) <= params[:eps]
22
+ end
23
+ xk1
24
+ end
25
+
26
+ def self.invert(vector)
27
+ vector.map{ |element| -element }
28
+ end
29
+
30
+ def self.plus(first_array, second_array)
31
+ Array.new(first_array.length) { |i| first_array[i] + second_array[i] }
32
+ end
33
+
34
+ def self.derivative(xk, &function)
35
+ eps = 1e-5
36
+ (function.call(xk + eps) - function.call(xk - eps)) / (2 * eps)
37
+ end
38
+ end
39
+ end
@@ -52,11 +52,11 @@ module Mathpack
52
52
 
53
53
  def empirical_cdf(x)
54
54
  result = 0.0
55
- @series.each { |val| result += heaviside(x - val) }
55
+ @series.each { |val| result += Mathpack::Functions.heaviside(x - val) }
56
56
  result / number
57
57
  end
58
58
 
59
- def print_empirical_cdf_to_csv(filename)
59
+ def print_empirical_cdf(filename)
60
60
  step = 0.5 * (max - min) / number
61
61
  nodes = Mathpack::Approximation.generate_nodes(from: min - step, to: max + step, step: step)
62
62
  values = nodes.map { |x| empirical_cdf(x) }
@@ -66,11 +66,11 @@ module Mathpack
66
66
  def empirical_pdf(x)
67
67
  h = variance**0.5 * number**(-1.0 / 6)
68
68
  result = 0.0
69
- @series.each { |val| result += (heaviside(x - val + h) - heaviside(x - val - h)) / (2 * h) }
69
+ @series.each { |val| result += (Mathpack::Functions.heaviside(x - val + h) - Mathpack::Functions.heaviside(x - val - h)) / (2 * h) }
70
70
  result / number
71
71
  end
72
72
 
73
- def print_empirical_pdf_to_csv(filename)
73
+ def print_empirical_pdf(filename)
74
74
  step = 0.5 * (max - min) / number
75
75
  nodes = Mathpack::Approximation.generate_nodes(from: min - 10 * step, to: max + 10 * step, step: step)
76
76
  values = nodes.map { |x| empirical_pdf(x) }
@@ -85,10 +85,6 @@ module Mathpack
85
85
 
86
86
  private
87
87
 
88
- def heaviside(x)
89
- x <= 0 ? 0 : 1
90
- end
91
-
92
88
  def parse_series(series)
93
89
  data_set = []
94
90
  frequency = []
@@ -1,3 +1,3 @@
1
1
  module Mathpack
2
- VERSION = '0.4.4'
2
+ VERSION = '0.4.5'
3
3
  end
@@ -1,43 +1,51 @@
1
1
  describe 'Approximation' do
2
2
  require 'mathpack/approximation'
3
3
 
4
- context '#mnk' do
4
+ context 'mnk' do
5
5
  let(:x_start) { 0.0 }
6
6
  let(:x_end) { 10.0 }
7
7
  let(:step) { 0.25 }
8
8
  let(:nodes) { Mathpack::Approximation.generate_nodes(from: x_start, to: x_end, step: step) }
9
9
  let(:values) { Mathpack::Approximation.fill_f(nodes){ |val| val**2 } }
10
10
 
11
- it 'should generate nodes' do
12
- expect(nodes.length).to eq(41)
13
- expect(nodes.first).to eq(x_start)
14
- expect(nodes.last).to eq(x_end)
15
- end
11
+ describe '#generate_nodes' do
12
+ it 'generates nodes' do
13
+ expect(nodes.length).to eq(41)
14
+ expect(nodes.first).to eq(x_start)
15
+ expect(nodes.last).to eq(x_end)
16
+ end
16
17
 
17
- it 'should generate correct nodes' do
18
- nodes = Mathpack::Approximation.generate_nodes(from: 0, to: 1, step: 0.001)
19
- expect(nodes.last).to eq(1.0)
18
+ it 'generates last node equal to right border of interval' do
19
+ nodes = Mathpack::Approximation.generate_nodes(from: 0, to: 1, step: 0.001)
20
+ expect(nodes.last).to eq(1.0)
21
+ end
20
22
  end
21
23
 
22
- it 'should fill function table' do
23
- expect(values.length).to eq(nodes.length)
24
- expect(values.last).to eq(nodes.last**2)
24
+ describe '#fill_f' do
25
+ it 'fills function values in table' do
26
+ expect(values.length).to eq(nodes.length)
27
+ expect(values.last).to eq(nodes.last**2)
28
+ end
25
29
  end
26
30
 
27
- it 'should print polynoms' do
28
- expect(Mathpack::Approximation.print_polynom([5])).to eq('5')
29
- expect(Mathpack::Approximation.print_polynom([2, 3])).to eq('2*x + 3')
30
- expect(Mathpack::Approximation.print_polynom([1, -1, 1])).to eq('x^2 - x + 1')
31
- expect(Mathpack::Approximation.print_polynom([1, 3, 5])).to eq('x^2 + 3*x + 5')
32
- expect(Mathpack::Approximation.print_polynom([1, -2, 3, -4])).to eq('x^3 - 2*x^2 + 3*x - 4')
33
- expect(Mathpack::Approximation.print_polynom([1, 0, 1])).to eq('x^2 + 1')
31
+ describe '#print_polynoms' do
32
+ it 'prints formatted polynoms' do
33
+ expect(Mathpack::Approximation.print_polynom([5])).to eq('5')
34
+ expect(Mathpack::Approximation.print_polynom([2, 3])).to eq('2*x + 3')
35
+ expect(Mathpack::Approximation.print_polynom([1, -1, 1])).to eq('x^2 - x + 1')
36
+ expect(Mathpack::Approximation.print_polynom([1, 3, 5])).to eq('x^2 + 3*x + 5')
37
+ expect(Mathpack::Approximation.print_polynom([1, -2, 3, -4])).to eq('x^3 - 2*x^2 + 3*x - 4')
38
+ expect(Mathpack::Approximation.print_polynom([1, 0, 1])).to eq('x^2 + 1')
39
+ end
34
40
  end
35
41
 
36
- it 'should approximate by polynom' do
37
- coefficients = Mathpack::Approximation.approximate_by_polynom(x: nodes, f: values, polynom_power: 2)
38
- expect(coefficients).to eq([1.0, 0.0, 0.0])
39
- coefficients = Mathpack::Approximation.approximate_by_polynom(x: nodes, f: values, polynom_power: 0)
40
- expect(coefficients).to eq([33.75])
42
+ describe '#approximate_by_polynom' do
43
+ it 'approximates function by polynom of some power' do
44
+ coefficients = Mathpack::Approximation.approximate_by_polynom(x: nodes, f: values, polynom_power: 2)
45
+ expect(coefficients).to eq([1.0, 0.0, 0.0])
46
+ coefficients = Mathpack::Approximation.approximate_by_polynom(x: nodes, f: values, polynom_power: 0)
47
+ expect(coefficients).to eq([33.75])
48
+ end
41
49
  end
42
50
  end
43
51
  end
@@ -0,0 +1,9 @@
1
+ describe 'Functional' do
2
+ require 'mathpack/functional'
3
+
4
+ describe '#derivative' do
5
+ it 'calculates nth derivative' do
6
+ expect(Mathpack::Functional.derivative(2) { |x| x**3 }.(1)).to eq(6.0)
7
+ end
8
+ end
9
+ end
@@ -2,7 +2,7 @@ describe 'Functions' do
2
2
  require 'mathpack/functions'
3
3
 
4
4
  describe '#gamma' do
5
- it 'should calculate gamma function' do
5
+ it 'calculates gamma function' do
6
6
  expect(Mathpack::Functions.gamma(1.5)).to be_between(0.886225, 0.886229)
7
7
  expect(Mathpack::Functions.gamma(1.8)).to be_between(0.9313835, 0.9313844)
8
8
  expect(Mathpack::Functions.gamma(5.8)).to be_between(85.62165, 85.62174)
@@ -12,7 +12,7 @@ describe 'Functions' do
12
12
  end
13
13
 
14
14
  describe '#erf' do
15
- it 'should calculate erf function' do
15
+ it 'calculates erf function' do
16
16
  expect((Mathpack::Functions.erf(0.0) - 0.5).abs < 1e-7).to eq(true)
17
17
  expect((Mathpack::Functions.erf(1.73) - 0.9582).abs < 1e-4).to eq(true)
18
18
  expect((Mathpack::Functions.erf(3.49) - 0.9998).abs < 1e-4).to eq(true)
@@ -20,20 +20,20 @@ describe 'Functions' do
20
20
  end
21
21
 
22
22
  describe '#beta' do
23
- it 'should calculate beta function' do
23
+ it 'calculates beta function' do
24
24
  expect(Mathpack::Functions.beta(3.5, 2.2)).to be_between(0.0504866, 0.05048665)
25
25
  end
26
26
  end
27
27
 
28
28
  describe '#dawson_plus' do
29
- it 'should calculate dawson_plus integral' do
29
+ it 'calculates dawson_plus integral' do
30
30
  expect(Mathpack::Functions.dawson_plus(0.924138873)).to be_between(0.5410442, 0.54104425)
31
31
  expect(Mathpack::Functions.dawson_plus(1.5019752683)).to be_between(0.427686616, 0.4276866164)
32
32
  end
33
33
  end
34
34
 
35
35
  describe '#dawson_minus' do
36
- it 'should calculate dawson_minus integral' do
36
+ it 'calculates dawson_minus integral' do
37
37
  expect(Mathpack::Functions.dawson_minus(0.924138873) + Mathpack::Functions.dawson_minus(-0.924138873) < 1e-5).to eq(true)
38
38
  end
39
39
  end
@@ -1,7 +1,7 @@
1
1
  describe 'Integration' do
2
2
  require 'mathpack/integration'
3
3
 
4
- context '#a-b integrals' do
4
+ context 'a-b integrals' do
5
5
  it 'should integrate e^(-x^2)' do
6
6
  expect(Mathpack::Integration.integrate(from: 0, to: 10){ |x| Math.exp(-x**2) }).to be_between(0.8862269254525, 0.8862269254534)
7
7
  end
@@ -20,7 +20,7 @@ describe 'Integration' do
20
20
  end
21
21
  end
22
22
 
23
- context '#ni-1 integrals' do
23
+ context 'ni-1 integrals' do
24
24
  it 'should integrate e^(-x)/(x+1)' do
25
25
  expect(Mathpack::Integration.integrate(from: 0, to: Float::INFINITY){ |x| Math.exp(-x) / (x + 1) }).to be_between(0.596346, 0.596348)
26
26
  end
@@ -34,7 +34,7 @@ describe 'Integration' do
34
34
  end
35
35
  end
36
36
 
37
- context '#ni-2 integrals' do
37
+ context 'ni-2 integrals' do
38
38
  it 'should integrate e^(-x^2)*cos(x)' do
39
39
  expect(Mathpack::Integration.integrate(from: -Float::INFINITY, to: Float::INFINITY){ |x| Math.exp(-x**2) * Math.cos(x) }).to be_between(1.3803, 1.3804)
40
40
  end
@@ -0,0 +1,23 @@
1
+ describe 'Equation' do
2
+ require 'mathpack/nonlinear_equations'
3
+
4
+ describe '#solve' do
5
+ let(:eps) { 0.00001 }
6
+
7
+ it 'solves nonlinear equations correctly' do
8
+ expect(Mathpack::NonlinearEquations.solve(start: 0, eps: eps) { |x| x**2 - Math.sin(x + 1) }).to be_between(-0.613763 - eps, -0.613763 + eps)
9
+ expect(Mathpack::NonlinearEquations.solve(start: 0.01, eps: eps) { |x| 1 / x - Math.log(x) }).to be_between(1.76322 - eps, 1.76322 + eps)
10
+ expect(Mathpack::NonlinearEquations.solve(start: 0.01, eps: eps) { |x| x**2 - 2 * x + 1 }).to be_between(1.0 - eps, 1.0 + eps)
11
+ expect(Mathpack::NonlinearEquations.solve(start: 0.01, eps: eps) { |x| Math.exp(x - 2) - Math.sin(x) }).to be_between(0.159396 - eps, 0.159396 + eps)
12
+ end
13
+ end
14
+
15
+ describe '#solve_system' do
16
+ it 'solves system of nonlinear equations correctly' do
17
+ f = -> x, y { [x + y - 3.0, x**2 + y**2 - 9.0] }
18
+ w = -> x, y { [[1, 1], [2 * x, 2 * y]] }
19
+ solution = Mathpack::NonlinearEquations.solve_system(start: [1, 5], eps: 1e-4, f: f, w_matrix: w)
20
+ expect(Mathpack::IO.count_diff(solution, [0, 3]) <= 1e-4).to eq(true)
21
+ end
22
+ end
23
+ end
@@ -1,22 +1,22 @@
1
1
  describe 'SLE' do
2
2
  require 'mathpack/sle'
3
3
 
4
- context '#solve systems of linear equations' do
4
+ describe '#solve' do
5
5
  let(:a) { [[1, 2, 3], [4, 5, 6], [3, 5, 2]] }
6
6
  let(:unsolved) { [[1, 2, 3], [1, 2, 3], [3, 5, 2]] }
7
7
  let(:b) { [15, 30, 15] }
8
8
  let(:matrix_a) { Matrix[[1, 2, 3], [4, 5, 6], [3, 5, 2]] }
9
9
  let(:vector_b) { Matrix.row_vector([15, 30, 15]) }
10
10
 
11
- it 'should give correct answer' do
11
+ it 'solves SLE correctly' do
12
12
  expect(Mathpack::SLE.solve(matrix: a, f: b)).to eq([-1.0, 2.0, 4.0])
13
13
  end
14
14
 
15
- it 'should raise error when matrix is singular' do
15
+ it 'raises error when matrix is singular' do
16
16
  expect { Mathpack::SLE.solve(matrix: unsolved, f: b) }.to raise_error
17
17
  end
18
18
 
19
- it 'should raise error when matrix has incorrect size' do
19
+ it 'raises error when matrix has incorrect size' do
20
20
  b << 1
21
21
  expect { Mathpack::SLE.solve(matrix: a, f: b) }.to raise_error
22
22
  b.pop
@@ -24,7 +24,7 @@ describe 'SLE' do
24
24
  expect { Mathpack::SLE.solve(matrix: a, f: b) }.to raise_error
25
25
  end
26
26
 
27
- it 'should return vector if matrix class is given' do
27
+ it 'returns vector if matrix class is given' do
28
28
  expect(Mathpack::SLE.solve(matrix: matrix_a, f: vector_b)).to eq(Matrix.row_vector [-1.0, 2.0, 4.0])
29
29
  end
30
30
 
@@ -1,8 +1,7 @@
1
1
  describe 'Statistics' do
2
2
  require 'mathpack/statistics'
3
3
 
4
- describe '#calculate statistics functions' do
5
-
4
+ context 'calculate statistic parameters' do
6
5
  let(:data) do
7
6
  array = []
8
7
  array << [0]*50
@@ -14,62 +13,86 @@ describe 'Statistics' do
14
13
  end
15
14
  let(:stat) { Mathpack::Statistics.new(data) }
16
15
 
17
- it 'should calculate number of elements' do
18
- expect(stat.number).to eq(100)
16
+ describe '#number' do
17
+ it 'calculates number of elements' do
18
+ expect(stat.number).to eq(100)
19
+ end
19
20
  end
20
21
 
21
- it 'should calculate mean' do
22
- expect(stat.mean).to eq(0.71)
22
+ describe '#mean' do
23
+ it 'calculates mean' do
24
+ expect(stat.mean).to eq(0.71)
25
+ end
23
26
  end
24
27
 
25
- it 'should calculate variance' do
26
- expect(stat.variance).to eq(0.7659)
28
+ describe '#varince' do
29
+ it 'calculates variance' do
30
+ expect(stat.variance).to eq(0.7659)
31
+ end
27
32
  end
28
33
 
29
- it 'should calculate skewness' do
30
- expect(stat.skewness).to eq(1.3139557526940238)
34
+ describe '#skewness' do
35
+ it 'calculates skewness' do
36
+ expect(stat.skewness).to eq(1.3139557526940238)
37
+ end
31
38
  end
32
39
 
33
- it 'should calculate kurtosis' do
34
- expect(stat.kurtosis).to eq(1.5654257435282322)
40
+ describe '#kurtosis' do
41
+ it 'calculates kurtosis' do
42
+ expect(stat.kurtosis).to eq(1.5654257435282322)
43
+ end
35
44
  end
36
45
 
37
- it 'should calculate the minimal element' do
38
- expect(stat.min).to eq(0)
46
+ describe '#min' do
47
+ it 'finds the minimal element' do
48
+ expect(stat.min).to eq(0)
49
+ end
39
50
  end
40
51
 
41
- it 'should calculate the maximal element' do
42
- expect(stat.max).to eq(4)
52
+ describe '#max' do
53
+ it 'finds the maximal element' do
54
+ expect(stat.max).to eq(4)
55
+ end
43
56
  end
44
57
 
45
- it 'should calculate first raw moment equal to mean' do
46
- expect(stat.raw_moment(1)).to eq(stat.mean)
47
- end
58
+ describe '#raw_moment' do
59
+ it 'calculates first raw moment equal to mean' do
60
+ expect(stat.raw_moment(1)).to eq(stat.mean)
61
+ end
48
62
 
49
- it 'should calculate second central moment equal to variance' do
50
- expect(stat.central_moment(2)).to eq(stat.variance)
63
+ it 'calculates nth raw moment correctly' do
64
+ expect(stat.raw_moment(3)).to eq(2.87)
65
+ end
51
66
  end
52
67
 
53
- it 'should calculate raw moments' do
54
- expect(stat.raw_moment(3)).to eq(2.87)
55
- end
68
+ describe '#central_moment' do
69
+ it 'calculates second central moment equal to variance' do
70
+ expect(stat.central_moment(2)).to eq(stat.variance)
71
+ end
56
72
 
57
- it 'should calculate central moments' do
58
- expect(stat.central_moment(5)).to eq(6.641392040400001)
73
+ it 'calculates nth central moment correctly' do
74
+ expect(stat.central_moment(5)).to eq(6.641392040400001)
75
+ end
59
76
  end
60
77
 
61
- it 'should calculate empirical cdf values in points' do
62
- expect(stat.empirical_cdf(stat.min - 0.1)).to eq(0.0)
63
- expect(stat.empirical_cdf(stat.max + 0.1)).to eq(1.0)
64
- expect(stat.empirical_cdf(stat.mean)).to eq(0.5)
78
+ describe '#empirical_cdf' do
79
+ it 'calculates empirical cdf values in points' do
80
+ expect(stat.empirical_cdf(stat.min - 0.1)).to eq(0.0)
81
+ expect(stat.empirical_cdf(stat.max + 0.1)).to eq(1.0)
82
+ expect(stat.empirical_cdf(stat.mean)).to eq(0.5)
83
+ end
65
84
  end
66
85
 
67
- it 'should calculate empirical pdf values in points' do
68
- expect(stat.empirical_pdf(stat.mean)).to eq( 0.4308095750697591)
86
+ describe '#empirical_pdf' do
87
+ it 'calculates empirical pdf values in points' do
88
+ expect(stat.empirical_pdf(stat.mean)).to eq( 0.4308095750697591)
89
+ end
69
90
  end
70
91
 
71
- it 'should find trend' do
72
- expect(stat.trend(polynom_power: 2)).to eq('0.00042531864230840915*x^2 - 0.016860573212183233*x + 0.12239332096475111')
92
+ describe '#trend' do
93
+ it 'returns formatted trend' do
94
+ expect(stat.trend(polynom_power: 2)).to eq('0.00042531864230840915*x^2 - 0.016860573212183233*x + 0.12239332096475111')
95
+ end
73
96
  end
74
97
  end
75
98
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mathpack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - maxmilan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-20 00:00:00.000000000 Z
11
+ date: 2015-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,19 +53,21 @@ files:
53
53
  - Rakefile
54
54
  - lib/mathpack.rb
55
55
  - lib/mathpack/approximation.rb
56
- - lib/mathpack/equation.rb
56
+ - lib/mathpack/functional.rb
57
57
  - lib/mathpack/functions.rb
58
58
  - lib/mathpack/integration.rb
59
59
  - lib/mathpack/io.rb
60
+ - lib/mathpack/nonlinear_equations.rb
60
61
  - lib/mathpack/sle.rb
61
62
  - lib/mathpack/statistics.rb
62
63
  - lib/mathpack/version.rb
63
64
  - mathpack.gemspec
64
65
  - spec/approximation_spec.rb
65
- - spec/equation_spec.rb
66
+ - spec/functional_spec.rb
66
67
  - spec/functions_spec.rb
67
68
  - spec/integration_spec.rb
68
69
  - spec/io_spec.rb
70
+ - spec/nonlinear_equations_spec.rb
69
71
  - spec/sle_spec.rb
70
72
  - spec/statistics_spec.rb
71
73
  homepage: ''
@@ -88,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
90
  version: '0'
89
91
  requirements: []
90
92
  rubyforge_project:
91
- rubygems_version: 2.2.2
93
+ rubygems_version: 2.4.6
92
94
  signing_key:
93
95
  specification_version: 4
94
96
  summary: Summary
@@ -1,18 +0,0 @@
1
- module Mathpack
2
- module Equation
3
- def self.solve(params = {}, &function)
4
- xk1 = params[:start]
5
- loop do
6
- xk = xk1
7
- xk1 = xk - function.call(xk) / derivative(xk, &function)
8
- break if (xk1 - xk).abs < params[:eps]
9
- end
10
- xk1
11
- end
12
-
13
- def self.derivative(xk, &function)
14
- eps = 1e-5
15
- (function.call(xk + eps) - function.call(xk - eps)) / (2 * eps)
16
- end
17
- end
18
- end
@@ -1,14 +0,0 @@
1
- describe 'Equations' do
2
- require 'mathpack/equation'
3
-
4
- context '#solve nonlinear equations' do
5
- let(:eps) { 0.00001 }
6
-
7
- it 'should give correct results' do
8
- expect(Mathpack::Equation.solve(start: 0, eps: eps) { |x| x**2 - Math.sin(x + 1) }).to be_between(-0.613763 - eps, -0.613763 + eps)
9
- expect(Mathpack::Equation.solve(start: 0.01, eps: eps) { |x| 1 / x - Math.log(x) }).to be_between(1.76322 - eps, 1.76322 + eps)
10
- expect(Mathpack::Equation.solve(start: 0.01, eps: eps) { |x| x**2 - 2 * x + 1 }).to be_between(1.0 - eps, 1.0 + eps)
11
- expect(Mathpack::Equation.solve(start: 0.01, eps: eps) { |x| Math.exp(x - 2) - Math.sin(x) }).to be_between(0.159396 - eps, 0.159396 + eps)
12
- end
13
- end
14
- end