mathpack 0.1.0 → 0.2.0
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/.gitignore +1 -0
- data/.travis.yml +1 -0
- data/Gemfile +1 -1
- data/README.md +31 -7
- data/Rakefile +1 -2
- data/lib/mathpack/equation.rb +10 -6
- data/lib/mathpack/sle.rb +75 -0
- data/lib/mathpack/statistics.rb +11 -11
- data/lib/mathpack/version.rb +1 -1
- data/lib/mathpack.rb +2 -1
- data/mathpack.gemspec +5 -5
- data/spec/equation_spec.rb +7 -7
- data/spec/sle_spec.rb +23 -0
- data/spec/statistics_spec.rb +15 -15
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c14dffa0f11862781796118a019139c018cb2eb
|
4
|
+
data.tar.gz: b2be5e7d8b8bfdac4d40003a72109b6b0b9ea366
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4dcfdfcd380f2f3e23587210cfb594e533c0cc341b6a5862ec4e7891b8d72d72c8e6f09f7c7156f03bf74d87c204ee54f4baa16f76895ac55e3b62a5e964d01
|
7
|
+
data.tar.gz: edd6fce95f19953b01d6fc92a89b645fa52a855579c4136306e8b2e7ba33480a622d6b07abf3bb92f6772c5287f9e8d86a30ee6e0aebd8d1363f4fb4611ca7fe
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -18,8 +18,8 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
$ gem install mathpack
|
20
20
|
## Information
|
21
|
-
Gem `mathpack` allows to count statistical functions through `Statistics` class,
|
22
|
-
`solve` method
|
21
|
+
Gem `mathpack` allows to count statistical functions through `Statistics` class, solve nonlinear equations through `Equation` module
|
22
|
+
`solve` method, solve systems of linear equations through `SLE` module `solve` method.
|
23
23
|
## Statistics
|
24
24
|
`Statistics` class have following methods
|
25
25
|
- **number** - returns a number of elements in series
|
@@ -62,11 +62,10 @@ stat.print_empirical_pdf_to_csv('pdf.csv') #=> nil
|
|
62
62
|
Now you have no problems solving **nonlinear equations**. If you want, for example, to solve equation 
|
63
63
|
|
64
64
|
You need to complete the following steps:
|
65
|
-
|
66
|
-

|
65
|
+
- Equation should look like 
|
66
|
+
- For our equation 
|
67
|
+
- Choose the calculations accurracy. For example 
|
68
|
+
- Choose some point near the expected root of equation. For example 
|
70
69
|
|
71
70
|
Then to solve equation you should call
|
72
71
|
```ruby
|
@@ -80,6 +79,31 @@ Mathpack::Equation.solve(start: 0.01, eps: 0.00001){|x| x**2 - 2*x + 1})
|
|
80
79
|
Mathpack::Equation.solve(start: 0.01, eps: 0.00001){|x| Math.exp(x-2) - Math.sin(x)})
|
81
80
|
```
|
82
81
|
|
82
|
+
## SLE
|
83
|
+
`SLE` module has only one method
|
84
|
+
- **solve** - method, which allows to solve *system of linear equations*. Neccessary params are `matrix` representing system matrix and `f`. Params can be **Array** or **Matrix** class. If the system can't be solved, method raise exception
|
85
|
+
|
86
|
+
## Usage
|
87
|
+
Let's solve some system of linear equations. It can be written as
|
88
|
+
|
89
|
+

|
90
|
+
|
91
|
+
where A is n*n matrix, X - vector of unknown, B - vector
|
92
|
+
|
93
|
+
If you want to solve this system you should call
|
94
|
+
```ruby
|
95
|
+
Mathpack::SLE.solve(matrix: A, f: B)
|
96
|
+
```
|
97
|
+
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.
|
98
|
+
```ruby
|
99
|
+
a = [[1, 2, 3], [4, 5, 6],[3, 5, 2]]
|
100
|
+
b = [15, 30, 15]
|
101
|
+
Mathpack::SLE.solve(matrix: a, f: b) #=> [-1.0, 2.0, 4.0]
|
102
|
+
a = Matrix[[1, 2, 3], [4, 5, 6],[3, 5, 2]]
|
103
|
+
b = Matrix.row_vector [15, 30, 15]
|
104
|
+
Mathpack::SLE.solve(matrix: a, f: b) #=> Matrix[[-1.0, 2.0, 4.0]]
|
105
|
+
```
|
106
|
+
|
83
107
|
## Contributing
|
84
108
|
|
85
109
|
1. Fork it ( https://github.com/[my-github-username]/mathpack/fork )
|
data/Rakefile
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
require
|
2
|
-
|
1
|
+
require 'bundler/gem_tasks'
|
data/lib/mathpack/equation.rb
CHANGED
@@ -1,14 +1,18 @@
|
|
1
1
|
module Mathpack
|
2
2
|
module Equation
|
3
|
-
def self.solve(
|
4
|
-
|
5
|
-
xk1 = param[:start]
|
3
|
+
def self.solve(params = {}, &function)
|
4
|
+
xk1 = params[:start]
|
6
5
|
loop do
|
7
6
|
xk = xk1
|
8
|
-
xk1 = xk - function.call(xk)/(
|
9
|
-
break if (xk1 - xk).abs <
|
7
|
+
xk1 = xk - function.call(xk) / derivative(xk, &function)
|
8
|
+
break if (xk1 - xk).abs < params[:eps]
|
10
9
|
end
|
11
|
-
|
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)
|
12
16
|
end
|
13
17
|
end
|
14
18
|
end
|
data/lib/mathpack/sle.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'matrix'
|
2
|
+
|
3
|
+
module Mathpack
|
4
|
+
module SLE
|
5
|
+
EPS = 1e-14
|
6
|
+
|
7
|
+
def self.solve(params)
|
8
|
+
type = params[:f].class
|
9
|
+
@matrix = params[:matrix].to_a
|
10
|
+
@f = params[:f].to_a.flatten
|
11
|
+
@number = @f.length
|
12
|
+
@x = Array.new(@number) { |i| i + 1 }
|
13
|
+
fail 'SLE can\'t be solved' unless solve_direct
|
14
|
+
type == Matrix ? Matrix.row_vector(solve_reverse) : solve_reverse
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.swap_lines(first_line, second_line)
|
18
|
+
0.upto(@number - 1) do |j|
|
19
|
+
@matrix[first_line][j], @matrix[second_line][j] = @matrix[second_line][j], @matrix[first_line][j]
|
20
|
+
end
|
21
|
+
@f[first_line], @f[second_line] = @f[second_line], @f[first_line]
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.swap_columns(first_column, second_column)
|
25
|
+
0.upto(@number - 1) do |i|
|
26
|
+
@matrix[i][first_column], @matrix[i][second_column] = @matrix[i][second_column], @matrix[i][first_column]
|
27
|
+
end
|
28
|
+
@x[first_column], @x[second_column] = @x[second_column], @x[first_column]
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.make_null_column(step)
|
32
|
+
(step + 1).upto(@number - 1) do |i|
|
33
|
+
alpha = -@matrix[i][step] / @matrix[step][step].to_f
|
34
|
+
step.upto(@number - 1) do |j|
|
35
|
+
@matrix[i][j] += @matrix[step][j] * alpha
|
36
|
+
end
|
37
|
+
@f[i] += @f[step] * alpha
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.solve_direct
|
42
|
+
0.upto(@number - 1) do |i|
|
43
|
+
maximum = 0.0
|
44
|
+
max_line = i
|
45
|
+
max_column = i
|
46
|
+
i.upto(@number - 1) do |line|
|
47
|
+
i.upto(@number - 1) do |column|
|
48
|
+
maximum, max_line, max_column = @matrix[line][column].abs, line, column if @matrix[line][column].abs > maximum
|
49
|
+
end
|
50
|
+
end
|
51
|
+
return false if maximum < EPS
|
52
|
+
swap_lines(i, max_line) if (max_line != i)
|
53
|
+
swap_columns(i, max_column) if (max_column != i)
|
54
|
+
make_null_column(i)
|
55
|
+
end
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.solve_reverse
|
60
|
+
result_vector = Array.new(@number)
|
61
|
+
(@number - 1).downto(0) do |i|
|
62
|
+
if i == (@number - 1)
|
63
|
+
result_vector[@x[i] - 1] = @f[i] / @matrix[i][i]
|
64
|
+
else
|
65
|
+
sum = 0.0
|
66
|
+
(i + 1).upto(@number - 1) do |j|
|
67
|
+
sum += @matrix[i][j] * result_vector[@x[j] - 1]
|
68
|
+
end
|
69
|
+
result_vector[@x[i] - 1] = (@f[i] - sum) / @matrix[i][i]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
result_vector
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/mathpack/statistics.rb
CHANGED
@@ -34,28 +34,28 @@ module Mathpack
|
|
34
34
|
|
35
35
|
def raw_moment(power)
|
36
36
|
raw_moment = 0.0
|
37
|
-
@series.each{ |x| raw_moment += x**power }
|
37
|
+
@series.each { |x| raw_moment += x**power }
|
38
38
|
raw_moment / number
|
39
39
|
end
|
40
40
|
|
41
41
|
def central_moment(power)
|
42
42
|
central_moment = 0.0
|
43
43
|
m = mean
|
44
|
-
@series.each{ |x| central_moment += (x - m)**power }
|
44
|
+
@series.each { |x| central_moment += (x - m)**power }
|
45
45
|
central_moment / number
|
46
46
|
end
|
47
47
|
|
48
48
|
def empirical_cdf(x)
|
49
49
|
result = 0.0
|
50
|
-
@series.each{ |val| result +=
|
50
|
+
@series.each { |val| result += heaviside(x - val) }
|
51
51
|
result / number
|
52
52
|
end
|
53
53
|
|
54
54
|
def print_empirical_cdf_to_csv(filename)
|
55
|
-
step = 0.
|
55
|
+
step = 0.5 * (max - min) / number
|
56
56
|
val = min - step
|
57
57
|
File.open(filename, 'w+') do |file|
|
58
|
-
while val <= max + step
|
58
|
+
while val <= max + step
|
59
59
|
file.write("#{val};")
|
60
60
|
file.write("#{empirical_cdf(val)}\n")
|
61
61
|
val += step
|
@@ -64,17 +64,17 @@ module Mathpack
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def empirical_pdf(x)
|
67
|
-
h = variance**0.5 * number**(-1.0/6)
|
67
|
+
h = variance**0.5 * number**(-1.0 / 6)
|
68
68
|
result = 0.0
|
69
|
-
@series.each{ |val| result += (
|
69
|
+
@series.each { |val| result += (heaviside(x - val + h) - heaviside(x - val - h)) / (2 * h) }
|
70
70
|
result / number
|
71
71
|
end
|
72
72
|
|
73
73
|
def print_empirical_pdf_to_csv(filename)
|
74
|
-
step = 0.
|
75
|
-
val = min -
|
74
|
+
step = 0.5 * (max - min) / number
|
75
|
+
val = min - 10 * step
|
76
76
|
File.open(filename, 'w+') do |file|
|
77
|
-
while val <= max +
|
77
|
+
while val <= max + 10 * step
|
78
78
|
file.write("#{val};")
|
79
79
|
file.write("#{empirical_pdf(val)}\n")
|
80
80
|
val += step
|
@@ -84,7 +84,7 @@ module Mathpack
|
|
84
84
|
|
85
85
|
private
|
86
86
|
|
87
|
-
def
|
87
|
+
def heaviside(x)
|
88
88
|
x <= 0 ? 0 : 1
|
89
89
|
end
|
90
90
|
end
|
data/lib/mathpack/version.rb
CHANGED
data/lib/mathpack.rb
CHANGED
data/mathpack.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require "mathpack/version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "mathpack"
|
@@ -9,13 +9,13 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["maxmilan"]
|
10
10
|
spec.email = ["max231194@gmail.com"]
|
11
11
|
spec.summary = "Summary"
|
12
|
-
spec.description ="Includes collection of mathematical methods"
|
12
|
+
spec.description = "Includes collection of mathematical methods"
|
13
13
|
spec.homepage = ""
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0")
|
17
|
-
spec.executables = spec.files.grep(%r{^bin
|
18
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/$}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/$})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.6"
|
data/spec/equation_spec.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
describe 'Equations' do
|
2
2
|
require 'mathpack/equation'
|
3
3
|
|
4
|
-
context '
|
4
|
+
context '#solve nonlinear equations' do
|
5
|
+
let(:eps) { 0.00001 }
|
5
6
|
|
6
|
-
it 'should
|
7
|
-
eps
|
8
|
-
expect(Mathpack::Equation.solve(start: 0, eps: eps){|x| x
|
9
|
-
expect(Mathpack::Equation.solve(start: 0.01, eps: eps){|x|
|
10
|
-
expect(Mathpack::Equation.solve(start: 0.01, eps: eps){|x| x
|
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)
|
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
12
|
end
|
13
13
|
end
|
14
14
|
end
|
data/spec/sle_spec.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
describe 'SLE' do
|
2
|
+
require 'mathpack/sle'
|
3
|
+
|
4
|
+
context '#solve systems of linear equations' do
|
5
|
+
let(:a) { [[1, 2, 3], [4, 5, 6], [3, 5, 2]] }
|
6
|
+
let(:unsolved) { [[1, 2, 3], [1, 2, 3], [3, 5, 2]] }
|
7
|
+
let(:b) { [15, 30, 15] }
|
8
|
+
let(:matrix_a) { Matrix[[1, 2, 3], [4, 5, 6], [3, 5, 2]] }
|
9
|
+
let(:vector_b) { Matrix.row_vector([15, 30, 15]) }
|
10
|
+
|
11
|
+
it 'should give correct answer' do
|
12
|
+
expect(Mathpack::SLE.solve(matrix: a, f: b)).to eql([-1.0, 2.0, 4.0])
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should raise error' do
|
16
|
+
expect { Mathpack::SLE.solve(matrix: unsolved, f: b) }.to raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should return vector if matrix class is given' do
|
20
|
+
expect(Mathpack::SLE.solve(matrix: matrix_a, f: vector_b)).to eql(Matrix.row_vector [-1.0, 2.0, 4.0])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/spec/statistics_spec.rb
CHANGED
@@ -1,62 +1,62 @@
|
|
1
1
|
describe 'Statistics' do
|
2
2
|
require 'mathpack/statistics'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe '#calculate statistics functions' do
|
5
5
|
|
6
|
-
let(:data) { [1,5,4,2,3,4,5,7,2,7] }
|
6
|
+
let(:data) { [1, 5, 4, 2, 3, 4, 5, 7, 2, 7] }
|
7
7
|
let(:stat) { Mathpack::Statistics.new(data) }
|
8
8
|
|
9
|
-
it
|
9
|
+
it 'should calculate number of elements' do
|
10
10
|
expect(stat.number).to eql(10)
|
11
11
|
end
|
12
12
|
|
13
|
-
it
|
13
|
+
it 'should calculate mean' do
|
14
14
|
expect(stat.mean).to eql(4.0)
|
15
15
|
end
|
16
16
|
|
17
|
-
it
|
17
|
+
it 'should calculate variance' do
|
18
18
|
expect(stat.variance).to eql(3.8)
|
19
19
|
end
|
20
20
|
|
21
|
-
it
|
21
|
+
it 'should calculate skewness' do
|
22
22
|
expect(stat.skewness).to eql(0.16199658190818222)
|
23
23
|
end
|
24
24
|
|
25
|
-
it
|
25
|
+
it 'should calculate kurtosis' do
|
26
26
|
expect(stat.kurtosis).to eql(1.925207756232687)
|
27
27
|
end
|
28
28
|
|
29
|
-
it
|
29
|
+
it 'should calculate the minimal element' do
|
30
30
|
expect(stat.min).to eql(1)
|
31
31
|
end
|
32
32
|
|
33
|
-
it
|
33
|
+
it 'should calculate the maximal element' do
|
34
34
|
expect(stat.max).to eql(7)
|
35
35
|
end
|
36
36
|
|
37
|
-
it
|
37
|
+
it 'should calculate first raw moment equal to mean' do
|
38
38
|
expect(stat.raw_moment(1)).to eql(stat.mean)
|
39
39
|
end
|
40
40
|
|
41
|
-
it
|
41
|
+
it 'should calculate second central moment equal to variance' do
|
42
42
|
expect(stat.central_moment(2)).to eql(stat.variance)
|
43
43
|
end
|
44
44
|
|
45
|
-
it
|
45
|
+
it 'should calculate raw moments' do
|
46
46
|
expect(stat.raw_moment(3)).to eql(110.8)
|
47
47
|
end
|
48
48
|
|
49
|
-
it
|
49
|
+
it 'should calculate central moments' do
|
50
50
|
expect(stat.central_moment(5)).to eql(18.0)
|
51
51
|
end
|
52
52
|
|
53
|
-
it
|
53
|
+
it 'should calculate empirical cdf values in points' do
|
54
54
|
expect(stat.empirical_cdf(stat.min - 0.1)).to eql(0.0)
|
55
55
|
expect(stat.empirical_cdf(stat.max + 0.1)).to eql(1.0)
|
56
56
|
expect(stat.empirical_cdf(stat.mean)).to eql(0.4)
|
57
57
|
end
|
58
58
|
|
59
|
-
it
|
59
|
+
it 'should calculate empirical pdf values in points' do
|
60
60
|
expect(stat.empirical_pdf(stat.mean)).to eql(0.1882412842233359)
|
61
61
|
end
|
62
62
|
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
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- maxmilan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -53,10 +53,12 @@ files:
|
|
53
53
|
- Rakefile
|
54
54
|
- lib/mathpack.rb
|
55
55
|
- lib/mathpack/equation.rb
|
56
|
+
- lib/mathpack/sle.rb
|
56
57
|
- lib/mathpack/statistics.rb
|
57
58
|
- lib/mathpack/version.rb
|
58
59
|
- mathpack.gemspec
|
59
60
|
- spec/equation_spec.rb
|
61
|
+
- spec/sle_spec.rb
|
60
62
|
- spec/statistics_spec.rb
|
61
63
|
homepage: ''
|
62
64
|
licenses:
|
@@ -82,6 +84,4 @@ rubygems_version: 2.2.2
|
|
82
84
|
signing_key:
|
83
85
|
specification_version: 4
|
84
86
|
summary: Summary
|
85
|
-
test_files:
|
86
|
-
- spec/equation_spec.rb
|
87
|
-
- spec/statistics_spec.rb
|
87
|
+
test_files: []
|