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 +4 -4
- data/README.md +52 -16
- data/lib/mathpack.rb +2 -1
- data/lib/mathpack/functional.rb +46 -0
- data/lib/mathpack/functions.rb +4 -0
- data/lib/mathpack/integration.rb +1 -0
- data/lib/mathpack/io.rb +14 -2
- data/lib/mathpack/nonlinear_equations.rb +39 -0
- data/lib/mathpack/statistics.rb +4 -8
- data/lib/mathpack/version.rb +1 -1
- data/spec/approximation_spec.rb +32 -24
- data/spec/functional_spec.rb +9 -0
- data/spec/functions_spec.rb +5 -5
- data/spec/integration_spec.rb +3 -3
- data/spec/nonlinear_equations_spec.rb +23 -0
- data/spec/sle_spec.rb +5 -5
- data/spec/statistics_spec.rb +57 -34
- metadata +7 -5
- data/lib/mathpack/equation.rb +0 -18
- data/spec/equation_spec.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8ce50434e6550fb905aa1cb215106fc208af310
|
4
|
+
data.tar.gz: 2bce06f9c4b43424bf26923d0ecf7c91789253d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
- **
|
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
|
-
####
|
55
|
-
allows to print empirical_cdf table function to **filename
|
56
|
-
####
|
57
|
-
allows to print empirical_pdf table function to **filename
|
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.
|
76
|
-
stat.
|
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
|

|
92
94
|
|
93
|
-
##
|
95
|
+
## NonlinearEquations
|
94
96
|
#### solve(params = {})
|
95
97
|
returns solution of nonlinear equation.
|
96
98
|
##### Parameters
|
97
|
-
- *start* - point to start
|
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::
|
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::
|
116
|
-
Mathpack::
|
117
|
-
Mathpack::
|
118
|
-
Mathpack::
|
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 
|
132
|
+
|
133
|
+

|
134
|
+
|
135
|
+

|
136
|
+
|
137
|
+
For example, if you have system
|
138
|
+
|
139
|
+

|
140
|
+
|
141
|
+
W matrix and f vector is equal
|
142
|
+
|
143
|
+

|
144
|
+
|
145
|
+

|
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
|
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
|
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
|
data/lib/mathpack.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'mathpack/version'
|
2
2
|
require 'mathpack/statistics'
|
3
|
-
require 'mathpack/
|
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
|
data/lib/mathpack/functions.rb
CHANGED
data/lib/mathpack/integration.rb
CHANGED
data/lib/mathpack/io.rb
CHANGED
@@ -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]
|
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
|
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
|
data/lib/mathpack/statistics.rb
CHANGED
@@ -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
|
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
|
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 = []
|
data/lib/mathpack/version.rb
CHANGED
data/spec/approximation_spec.rb
CHANGED
@@ -1,43 +1,51 @@
|
|
1
1
|
describe 'Approximation' do
|
2
2
|
require 'mathpack/approximation'
|
3
3
|
|
4
|
-
context '
|
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
data/spec/functions_spec.rb
CHANGED
@@ -2,7 +2,7 @@ describe 'Functions' do
|
|
2
2
|
require 'mathpack/functions'
|
3
3
|
|
4
4
|
describe '#gamma' do
|
5
|
-
it '
|
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 '
|
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 '
|
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 '
|
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 '
|
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
|
data/spec/integration_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
describe 'Integration' do
|
2
2
|
require 'mathpack/integration'
|
3
3
|
|
4
|
-
context '
|
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 '
|
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 '
|
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
|
data/spec/sle_spec.rb
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
describe 'SLE' do
|
2
2
|
require 'mathpack/sle'
|
3
3
|
|
4
|
-
|
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 '
|
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 '
|
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 '
|
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 '
|
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
|
|
data/spec/statistics_spec.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
describe 'Statistics' do
|
2
2
|
require 'mathpack/statistics'
|
3
3
|
|
4
|
-
|
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
|
-
|
18
|
-
|
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
|
-
|
22
|
-
|
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
|
-
|
26
|
-
|
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
|
-
|
30
|
-
|
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
|
-
|
34
|
-
|
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
|
-
|
38
|
-
|
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
|
-
|
42
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
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
|
-
|
50
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
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
|
-
|
58
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
68
|
-
|
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
|
-
|
72
|
-
|
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
|
+
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-
|
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/
|
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/
|
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.
|
93
|
+
rubygems_version: 2.4.6
|
92
94
|
signing_key:
|
93
95
|
specification_version: 4
|
94
96
|
summary: Summary
|
data/lib/mathpack/equation.rb
DELETED
@@ -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
|
data/spec/equation_spec.rb
DELETED
@@ -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
|