regression 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 German Antsiferov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,32 @@
1
+ require 'lib/regression/version'
2
+ require 'rake/extensiontask'
3
+
4
+ spec = Gem::Specification.new 'regression', Regression::VERSION do |s|
5
+ s.authors = ["German Antsiferov"]
6
+ s.email = ["dxdy@bk.ru"]
7
+ s.summary = %q{This project implements a simple least-squares polynomial fit}
8
+ s.license = "MIT"
9
+
10
+ s.extensions = %w[ext/regression/extconf.rb]
11
+
12
+ s.files = %w[
13
+ LICENSE.txt
14
+ Rakefile
15
+ lib/regression.rb
16
+ lib/regression/version.rb
17
+ ext/regression/extconf.rb
18
+ ext/regression/regression.c
19
+ ]
20
+
21
+ s.add_development_dependency "rake-compiler", "~> 0.8"
22
+ s.add_development_dependency "rspec", "~> 3.3"
23
+ end
24
+
25
+ Gem::PackageTask.new(spec) do |pkg|
26
+ end
27
+
28
+ Rake::ExtensionTask.new('regression', spec) do |ext|
29
+ ext.lib_dir = "lib/regression"
30
+ end
31
+
32
+ task :default => [:compile]
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile("regression/regression")
@@ -0,0 +1,211 @@
1
+ #include <stdlib.h>
2
+ #include <stdio.h>
3
+ #include <string.h>
4
+ #include <ctype.h>
5
+ #include <assert.h>
6
+ #include <ruby.h>
7
+
8
+ //----------------------------------------------------
9
+ //
10
+ // METHOD: polyfit
11
+ //
12
+ // INPUTS: dependentValues[0..(countOfElements-1)]
13
+ // independentValues[0...(countOfElements-1)]
14
+ // countOfElements
15
+ // order - Order of the polynomial fitting
16
+ //
17
+ // OUTPUTS: coefficients[0..order] - indexed by term
18
+ // (the (coef*x^3) is coefficients[3])
19
+ //
20
+ // HOMEPAGE: https://github.com/natedomin/polyfit.git
21
+ //
22
+ //----------------------------------------------------
23
+ int polyfit(const double* const dependentValues,
24
+ const double* const independentValues,
25
+ unsigned int countOfElements,
26
+ unsigned int order,
27
+ double* coefficients)
28
+ {
29
+ // Declarations...
30
+ // ----------------------------------
31
+ const unsigned int maxNoOfElements = 50; // Arbitrary
32
+ enum {maxOrder = 5};
33
+
34
+ double B[maxOrder+1] = {0.0f};
35
+ double P[((maxOrder+1) * 2)+1] = {0.0f};
36
+ double A[(maxOrder + 1)*2*(maxOrder + 1)] = {0.0f};
37
+
38
+ double x, y, powx;
39
+
40
+ unsigned int ii, jj, kk;
41
+
42
+ // Verify initial conditions....
43
+ // ----------------------------------
44
+
45
+ // This method requires that the countOfElements >
46
+ // (order+1)
47
+ if (countOfElements <= order)
48
+ return -1;
49
+
50
+ // This method has imposed an arbitrary bound of
51
+ // order <= maxOrder. Increase maxOrder if necessary.
52
+ if (order > maxOrder)
53
+ return -1;
54
+
55
+ // This method has imposed an arbitrary bound of
56
+ // countOfElements <= maxNoOfElements
57
+ if (countOfElements > maxNoOfElements)
58
+ return -1;
59
+
60
+ // Begin Code...
61
+ // ----------------------------------
62
+
63
+ // Identify the column vector
64
+ for (ii = 0; ii < countOfElements; ii++)
65
+ {
66
+ x = dependentValues[ii];
67
+ y = independentValues[ii];
68
+ powx = 1;
69
+
70
+ for (jj = 0; jj < (order + 1); jj++)
71
+ {
72
+ B[jj] = B[jj] + (y * powx);
73
+ powx = powx * x;
74
+ }
75
+ }
76
+
77
+ // Initialize the PowX array
78
+ P[0] = countOfElements;
79
+
80
+ // Compute the sum of the Powers of X
81
+ for (ii = 0; ii < countOfElements; ii++)
82
+ {
83
+ x = dependentValues[ii];
84
+ powx = dependentValues[ii];
85
+
86
+ for (jj = 1; jj < ((2 * (order + 1)) + 1); jj++)
87
+ {
88
+ P[jj] = P[jj] + powx;
89
+ powx = powx * x;
90
+ }
91
+ }
92
+
93
+ // Initialize the reduction matrix
94
+ //
95
+ for (ii = 0; ii < (order + 1); ii++)
96
+ {
97
+ for (jj = 0; jj < (order + 1); jj++)
98
+ {
99
+ A[(ii * (2 * (order + 1))) + jj] = P[ii+jj];
100
+ }
101
+
102
+ A[(ii*(2 * (order + 1))) + (ii + (order + 1))] = 1;
103
+ }
104
+
105
+ // Move the Identity matrix portion of the redux matrix
106
+ // to the left side (find the inverse of the left side
107
+ // of the redux matrix
108
+ for (ii = 0; ii < (order + 1); ii++)
109
+ {
110
+ x = A[(ii * (2 * (order + 1))) + ii];
111
+ if (x != 0)
112
+ {
113
+ for (kk = 0; kk < (2 * (order + 1)); kk++)
114
+ {
115
+ A[(ii * (2 * (order + 1))) + kk] =
116
+ A[(ii * (2 * (order + 1))) + kk] / x;
117
+ }
118
+
119
+ for (jj = 0; jj < (order + 1); jj++)
120
+ {
121
+ if ((jj - ii) != 0)
122
+ {
123
+ y = A[(jj * (2 * (order + 1))) + ii];
124
+ for (kk = 0; kk < (2 * (order + 1)); kk++)
125
+ {
126
+ A[(jj * (2 * (order + 1))) + kk] =
127
+ A[(jj * (2 * (order + 1))) + kk] -
128
+ y * A[(ii * (2 * (order + 1))) + kk];
129
+ }
130
+ }
131
+ }
132
+ }
133
+ else
134
+ {
135
+ // Cannot work with singular matrices
136
+ return -1;
137
+ }
138
+ }
139
+
140
+ // Calculate and Identify the coefficients
141
+ for (ii = 0; ii < (order + 1); ii++)
142
+ {
143
+ for (jj = 0; jj < (order + 1); jj++)
144
+ {
145
+ x = 0;
146
+ for (kk = 0; kk < (order + 1); kk++)
147
+ {
148
+ x = x + (A[(ii * (2 * (order + 1))) + (kk + (order + 1))] *
149
+ B[kk]);
150
+ }
151
+ coefficients[ii] = x;
152
+ }
153
+ }
154
+
155
+ return 0;
156
+ }
157
+
158
+ static VALUE
159
+ rb_polyfit(VALUE rb_self, VALUE rb_x_array, VALUE rb_y_array, VALUE rb_order)
160
+ {
161
+ VALUE rb_c_array;
162
+
163
+ char status;
164
+ unsigned int i, order, length, order_length;
165
+ double *x_array, *y_array, *c_array;
166
+
167
+ Check_Type(rb_x_array, T_ARRAY);
168
+ Check_Type(rb_y_array, T_ARRAY);
169
+
170
+ order = NUM2INT(rb_order);
171
+ order_length = order + 1;
172
+ length = (unsigned int)RARRAY_LEN(rb_x_array);
173
+
174
+ rb_c_array = rb_ary_new2(order_length);
175
+
176
+ if (!length)
177
+ return rb_c_array;
178
+
179
+ c_array = malloc(order_length * sizeof(double));
180
+ x_array = malloc(length * sizeof(double));
181
+ y_array = malloc(length * sizeof(double));
182
+
183
+ for(i = 0; i < length; ++i)
184
+ {
185
+ x_array[i] = NUM2DBL( rb_ary_entry(rb_x_array, i) );
186
+ y_array[i] = NUM2DBL( rb_ary_entry(rb_y_array, i) );
187
+ }
188
+
189
+ status = polyfit(x_array, y_array, length, order, c_array);
190
+
191
+ free(x_array);
192
+ free(y_array);
193
+
194
+ if (!status)
195
+ {
196
+ for(i = 0; i < order_length; ++i)
197
+ {
198
+ rb_ary_store(rb_c_array, i, rb_float_new(c_array[i]));
199
+ }
200
+ }
201
+
202
+ return rb_c_array;
203
+ }
204
+
205
+ void Init_regression(void)
206
+ {
207
+ VALUE rb_mRegression;
208
+
209
+ rb_mRegression = rb_const_get(rb_cObject, rb_intern("Regression"));
210
+ rb_define_module_function(rb_mRegression, "polyfit", rb_polyfit, 3);
211
+ }
@@ -0,0 +1,6 @@
1
+ require 'regression/version'
2
+
3
+ module Regression
4
+ end
5
+
6
+ require "regression/regression"
@@ -0,0 +1,3 @@
1
+ module Regression
2
+ VERSION = '0.0.1'
3
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: regression
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - German Antsiferov
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2015-10-22 00:00:00 +03:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rake-compiler
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 27
30
+ segments:
31
+ - 0
32
+ - 8
33
+ version: "0.8"
34
+ type: :development
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 1
45
+ segments:
46
+ - 3
47
+ - 3
48
+ version: "3.3"
49
+ type: :development
50
+ version_requirements: *id002
51
+ description:
52
+ email:
53
+ - dxdy@bk.ru
54
+ executables: []
55
+
56
+ extensions:
57
+ - ext/regression/extconf.rb
58
+ extra_rdoc_files: []
59
+
60
+ files:
61
+ - LICENSE.txt
62
+ - Rakefile
63
+ - lib/regression.rb
64
+ - lib/regression/version.rb
65
+ - ext/regression/extconf.rb
66
+ - ext/regression/regression.c
67
+ has_rdoc: true
68
+ homepage:
69
+ licenses:
70
+ - MIT
71
+ post_install_message:
72
+ rdoc_options: []
73
+
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ hash: 3
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ hash: 3
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ requirements: []
95
+
96
+ rubyforge_project:
97
+ rubygems_version: 1.6.2
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: This project implements a simple least-squares polynomial fit
101
+ test_files: []
102
+