fast_matrix 0.1.66 → 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/.dockerignore +0 -1
- data/.travis.yml +2 -1
- data/README.md +3 -8
- data/ext/fast_matrix/{c_array_opeartions.c → Helper/c_array_opeartions.c} +39 -1
- data/ext/fast_matrix/{c_array_operations.h → Helper/c_array_operations.h} +6 -1
- data/ext/fast_matrix/{errors.c → Helper/errors.c} +8 -2
- data/ext/fast_matrix/{errors.h → Helper/errors.h} +3 -1
- data/ext/fast_matrix/Matrix/c_matrix.c +606 -0
- data/ext/fast_matrix/Matrix/c_matrix.h +49 -0
- data/ext/fast_matrix/Matrix/errors.h +28 -0
- data/ext/fast_matrix/Matrix/helper.h +27 -0
- data/ext/fast_matrix/Matrix/matrix.c +633 -0
- data/ext/fast_matrix/Matrix/matrix.h +11 -0
- data/ext/fast_matrix/Vector/c_vector.c +97 -0
- data/ext/fast_matrix/Vector/c_vector.h +24 -0
- data/ext/fast_matrix/Vector/errors.h +14 -0
- data/ext/fast_matrix/Vector/helper.h +26 -0
- data/ext/fast_matrix/Vector/vector.c +476 -0
- data/ext/fast_matrix/{vector.h → Vector/vector.h} +0 -10
- data/ext/fast_matrix/c_include.c +8 -0
- data/ext/fast_matrix/fast_matrix.h +3 -3
- data/fast_matrix.gemspec +1 -1
- data/lib/fast_matrix/version.rb +1 -1
- data/lib/matrix/constructors.rb +0 -63
- data/lib/matrix/matrix.rb +105 -4
- data/lib/vector/constructors.rb +5 -4
- data/lib/vector/vector.rb +29 -0
- metadata +21 -12
- data/ext/fast_matrix/matrix.c +0 -678
- data/ext/fast_matrix/matrix.h +0 -28
- data/ext/fast_matrix/vector.c +0 -277
@@ -0,0 +1,97 @@
|
|
1
|
+
#include "Vector/c_vector.h"
|
2
|
+
#include "Matrix/c_matrix.h"
|
3
|
+
|
4
|
+
double c_vector_magnitude(int n, const double* A)
|
5
|
+
{
|
6
|
+
double sum = 0;
|
7
|
+
for(int i = 0; i < n; ++i)
|
8
|
+
sum += A[i] * A[i];
|
9
|
+
return sqrt(sum);
|
10
|
+
}
|
11
|
+
|
12
|
+
void c_vector_normalize(int n, const double* A, double* B)
|
13
|
+
{
|
14
|
+
double m = c_vector_magnitude(n, A);
|
15
|
+
for(int i = 0; i < n; ++i)
|
16
|
+
B[i] = A[i] / m;
|
17
|
+
}
|
18
|
+
|
19
|
+
void c_vector_normalize_self(int n, double* A)
|
20
|
+
{
|
21
|
+
double m = c_vector_magnitude(n, A);
|
22
|
+
for(int i = 0; i < n; ++i)
|
23
|
+
A[i] = A[i] / m;
|
24
|
+
}
|
25
|
+
|
26
|
+
void c_vector_hstack(int m, int n, struct vector** vcts, double* C)
|
27
|
+
{
|
28
|
+
for(int i = 0; i < n; ++i)
|
29
|
+
{
|
30
|
+
struct vector* V = vcts[i];
|
31
|
+
copy_d_array(m, V->data, C);
|
32
|
+
C += n;
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
bool c_vector_equal_by_size(int argc, struct vector** vcts, int size)
|
37
|
+
{
|
38
|
+
for(int i = 0; i < argc; ++i)
|
39
|
+
if(size != vcts[i]->n)
|
40
|
+
return false;
|
41
|
+
return true;
|
42
|
+
}
|
43
|
+
|
44
|
+
double c_vector_inner_product(int n, double* A, double* B)
|
45
|
+
{
|
46
|
+
double sum = 0;
|
47
|
+
for(int i = 0; i < n; ++i)
|
48
|
+
sum += A[i] * B[i];
|
49
|
+
return sum;
|
50
|
+
}
|
51
|
+
|
52
|
+
void c_vector_cross_product(int argc, struct vector** vcts, double* R)
|
53
|
+
{
|
54
|
+
int n = argc + 1;
|
55
|
+
double* rows = malloc(argc * n * sizeof(double));
|
56
|
+
double* M = malloc(argc * argc * sizeof(double));
|
57
|
+
|
58
|
+
for(int i = 0; i < argc; ++i)
|
59
|
+
for(int j = 0; j < n; ++j)
|
60
|
+
rows[i + j * argc] = vcts[i]->data[j];
|
61
|
+
|
62
|
+
copy_d_array(argc * argc, rows + argc, M);
|
63
|
+
|
64
|
+
double* colM = M;
|
65
|
+
double* colR = rows;
|
66
|
+
int sign = (argc % 2 == 0) ? 1 : -1;
|
67
|
+
for(int i = 0; ; ++i)
|
68
|
+
{
|
69
|
+
R[i] = c_matrix_determinant(argc, M) * sign;
|
70
|
+
sign = - sign;
|
71
|
+
if(i == n - 1)
|
72
|
+
break;
|
73
|
+
copy_d_array(argc, colR, colM);
|
74
|
+
colM += argc;
|
75
|
+
colR += argc;
|
76
|
+
}
|
77
|
+
|
78
|
+
free(rows);
|
79
|
+
free(M);
|
80
|
+
}
|
81
|
+
|
82
|
+
// V - vector n
|
83
|
+
// M - matrix m x 1
|
84
|
+
// R - matrix m x n
|
85
|
+
void c_vector_matrix_multiply(int n, int m, const double* V, const double* M, double* R)
|
86
|
+
{
|
87
|
+
fill_d_array(m * n, R, 0);
|
88
|
+
|
89
|
+
for(int j = 0; j < n; ++j)
|
90
|
+
{
|
91
|
+
double* p_r = R + m * j;
|
92
|
+
double d_v = V[j];
|
93
|
+
|
94
|
+
for(int i = 0; i < m; ++i)
|
95
|
+
p_r[i] += d_v * M[i];
|
96
|
+
}
|
97
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#ifndef FAST_MATRIX_VECTOR_C_VECTOR_H
|
2
|
+
#define FAST_MATRIX_VECTOR_C_VECTOR_H 1
|
3
|
+
|
4
|
+
#include <stdbool.h>
|
5
|
+
|
6
|
+
// vector
|
7
|
+
struct vector
|
8
|
+
{
|
9
|
+
int n;
|
10
|
+
double* data;
|
11
|
+
};
|
12
|
+
|
13
|
+
double c_vector_magnitude(int n, const double* A);
|
14
|
+
double c_vector_inner_product(int n, double* A, double* B);
|
15
|
+
|
16
|
+
void c_vector_matrix_multiply(int n, int m, const double* V, const double* M, double* R);
|
17
|
+
void c_vector_normalize(int n, const double* A, double* B);
|
18
|
+
void c_vector_normalize_self(int n, double* A);
|
19
|
+
void c_vector_hstack(int m, int n, struct vector** vcts, double* C);
|
20
|
+
void c_vector_cross_product(int argc, struct vector** vcts, double* R);
|
21
|
+
|
22
|
+
bool c_vector_equal_by_size(int argc, struct vector** vcts, int size);
|
23
|
+
|
24
|
+
#endif /* FAST_MATRIX_VECTOR_C_VECTOR_H */
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#ifndef FAST_MATRIX_VECTOR_ERRORS_H
|
2
|
+
#define FAST_MATRIX_VECTOR_ERRORS_H 1
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
#include "Vector/vector.h"
|
6
|
+
|
7
|
+
// check if the vectors is of equal size and raise an error if not
|
8
|
+
inline void raise_check_equal_size_vectors(struct vector* A, struct vector* B)
|
9
|
+
{
|
10
|
+
if(A->n != B->n)
|
11
|
+
rb_raise(fm_eIndexError, "Different sizes vectors");
|
12
|
+
}
|
13
|
+
|
14
|
+
#endif /* FAST_MATRIX_VECTOR_ERRORS_H */
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#ifndef FAST_MATRIX_VECTOR_HELPER_H
|
2
|
+
#define FAST_MATRIX_VECTOR_HELPER_H 1
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
#include "Vector/c_vector.h"
|
6
|
+
|
7
|
+
inline struct vector* get_vector_from_rb_value(VALUE m)
|
8
|
+
{
|
9
|
+
struct vector* data;
|
10
|
+
TypedData_Get_Struct(m, struct vector, &vector_type, data);
|
11
|
+
return data;
|
12
|
+
}
|
13
|
+
|
14
|
+
inline void c_vector_init(struct vector* vect, int n)
|
15
|
+
{
|
16
|
+
vect->n = n;
|
17
|
+
vect->data = malloc(n * sizeof(double));
|
18
|
+
}
|
19
|
+
|
20
|
+
#define MAKE_VECTOR_AND_RB_VALUE(vector_name, rb_value_name, n)\
|
21
|
+
struct vector* vector_name; \
|
22
|
+
VALUE rb_value_name = TypedData_Make_Struct( \
|
23
|
+
cVector, struct vector, &vector_type, vector_name); \
|
24
|
+
c_vector_init(vector_name, n)
|
25
|
+
|
26
|
+
#endif /* FAST_MATRIX_VECTOR_HELPER_H */
|
@@ -0,0 +1,476 @@
|
|
1
|
+
#include "Vector/vector.h"
|
2
|
+
#include "Vector/errors.h"
|
3
|
+
#include "Vector/helper.h"
|
4
|
+
#include "Vector/c_vector.h"
|
5
|
+
|
6
|
+
#include "Helper/c_array_operations.h"
|
7
|
+
#include "Helper/errors.h"
|
8
|
+
#include "Matrix/c_matrix.h"
|
9
|
+
#include "Matrix/helper.h"
|
10
|
+
|
11
|
+
VALUE cVector;
|
12
|
+
|
13
|
+
void vector_free(void* data);
|
14
|
+
size_t vector_size(const void* data);
|
15
|
+
|
16
|
+
const rb_data_type_t vector_type =
|
17
|
+
{
|
18
|
+
.wrap_struct_name = "vector",
|
19
|
+
.function =
|
20
|
+
{
|
21
|
+
.dmark = NULL,
|
22
|
+
.dfree = vector_free,
|
23
|
+
.dsize = vector_size,
|
24
|
+
},
|
25
|
+
.data = NULL,
|
26
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
27
|
+
};
|
28
|
+
|
29
|
+
void vector_free(void* data)
|
30
|
+
{
|
31
|
+
free(((*(struct vector*)data)).data);
|
32
|
+
free(data);
|
33
|
+
}
|
34
|
+
|
35
|
+
size_t vector_size(const void* data)
|
36
|
+
{
|
37
|
+
return sizeof(struct vector);
|
38
|
+
}
|
39
|
+
|
40
|
+
VALUE vector_alloc(VALUE self)
|
41
|
+
{
|
42
|
+
struct vector* vct = malloc(sizeof(struct vector));
|
43
|
+
vct->data = NULL;
|
44
|
+
return TypedData_Wrap_Struct(self, &vector_type, vct);
|
45
|
+
}
|
46
|
+
|
47
|
+
VALUE vector_initialize(VALUE self, VALUE size)
|
48
|
+
{
|
49
|
+
int n = raise_rb_value_to_int(size);
|
50
|
+
|
51
|
+
if(n <= 0)
|
52
|
+
rb_raise(fm_eIndexError, "Size cannot be negative or zero");
|
53
|
+
|
54
|
+
struct vector* data = get_vector_from_rb_value(self);
|
55
|
+
c_vector_init(data, n);
|
56
|
+
|
57
|
+
return self;
|
58
|
+
}
|
59
|
+
|
60
|
+
// []=
|
61
|
+
VALUE vector_set(VALUE self, VALUE idx, VALUE v)
|
62
|
+
{
|
63
|
+
int i = raise_rb_value_to_int(idx);
|
64
|
+
double x = raise_rb_value_to_double(v);
|
65
|
+
struct vector* data = get_vector_from_rb_value(self);
|
66
|
+
|
67
|
+
i = (i < 0) ? data->n + i : i;
|
68
|
+
raise_check_range(i, 0, data->n);
|
69
|
+
|
70
|
+
data->data[i] = x;
|
71
|
+
return v;
|
72
|
+
}
|
73
|
+
|
74
|
+
// []
|
75
|
+
VALUE vector_get(VALUE self, VALUE idx)
|
76
|
+
{
|
77
|
+
int i = raise_rb_value_to_int(idx);
|
78
|
+
struct vector* data = get_vector_from_rb_value(self);
|
79
|
+
|
80
|
+
i = (i < 0) ? data->n + i : i;
|
81
|
+
|
82
|
+
if(i < 0 || i >= data->n)
|
83
|
+
return Qnil;
|
84
|
+
|
85
|
+
return DBL2NUM(data->data[i]);
|
86
|
+
}
|
87
|
+
|
88
|
+
VALUE vector_length(VALUE self)
|
89
|
+
{
|
90
|
+
struct vector* data = get_vector_from_rb_value(self);
|
91
|
+
return INT2NUM(data->n);
|
92
|
+
}
|
93
|
+
|
94
|
+
|
95
|
+
VALUE vector_add_with(VALUE self, VALUE other)
|
96
|
+
{
|
97
|
+
raise_check_rbasic(other, cVector, "vector");
|
98
|
+
struct vector* A = get_vector_from_rb_value(self);
|
99
|
+
struct vector* B = get_vector_from_rb_value(other);
|
100
|
+
raise_check_equal_size_vectors(A, B);
|
101
|
+
|
102
|
+
int n = A->n;
|
103
|
+
|
104
|
+
struct vector* C;
|
105
|
+
VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, C);
|
106
|
+
|
107
|
+
c_vector_init(C, n);
|
108
|
+
add_d_arrays_to_result(n, A->data, B->data, C->data);
|
109
|
+
|
110
|
+
return result;
|
111
|
+
}
|
112
|
+
|
113
|
+
|
114
|
+
VALUE vector_add_from(VALUE self, VALUE other)
|
115
|
+
{
|
116
|
+
raise_check_rbasic(other, cVector, "vector");
|
117
|
+
struct vector* A = get_vector_from_rb_value(self);
|
118
|
+
struct vector* B = get_vector_from_rb_value(other);
|
119
|
+
raise_check_equal_size_vectors(A, B);
|
120
|
+
|
121
|
+
int n = A->n;
|
122
|
+
|
123
|
+
add_d_arrays_to_first(n, A->data, B->data);
|
124
|
+
|
125
|
+
return self;
|
126
|
+
}
|
127
|
+
|
128
|
+
VALUE vector_sub_with(VALUE self, VALUE other)
|
129
|
+
{
|
130
|
+
raise_check_rbasic(other, cVector, "vector");
|
131
|
+
struct vector* A = get_vector_from_rb_value(self);
|
132
|
+
struct vector* B = get_vector_from_rb_value(other);
|
133
|
+
raise_check_equal_size_vectors(A, B);
|
134
|
+
|
135
|
+
int n = A->n;
|
136
|
+
|
137
|
+
struct vector* C;
|
138
|
+
VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, C);
|
139
|
+
|
140
|
+
c_vector_init(C, n);
|
141
|
+
sub_d_arrays_to_result(n, A->data, B->data, C->data);
|
142
|
+
|
143
|
+
return result;
|
144
|
+
}
|
145
|
+
|
146
|
+
|
147
|
+
VALUE vector_sub_from(VALUE self, VALUE other)
|
148
|
+
{
|
149
|
+
raise_check_rbasic(other, cVector, "vector");
|
150
|
+
struct vector* A = get_vector_from_rb_value(self);
|
151
|
+
struct vector* B = get_vector_from_rb_value(other);
|
152
|
+
raise_check_equal_size_vectors(A, B);
|
153
|
+
|
154
|
+
int n = A->n;
|
155
|
+
|
156
|
+
sub_d_arrays_to_first(n, A->data, B->data);
|
157
|
+
|
158
|
+
return self;
|
159
|
+
}
|
160
|
+
|
161
|
+
VALUE vector_equal(VALUE self, VALUE other)
|
162
|
+
{
|
163
|
+
if(RBASIC_CLASS(other) != cVector)
|
164
|
+
return Qfalse;
|
165
|
+
struct vector* A = get_vector_from_rb_value(self);
|
166
|
+
struct vector* B = get_vector_from_rb_value(other);
|
167
|
+
|
168
|
+
if(A->n != B->n)
|
169
|
+
return Qfalse;
|
170
|
+
|
171
|
+
int n = A->n;
|
172
|
+
|
173
|
+
if(equal_d_arrays(n, A->data, B->data))
|
174
|
+
return Qtrue;
|
175
|
+
return Qfalse;
|
176
|
+
}
|
177
|
+
|
178
|
+
VALUE vector_copy(VALUE self)
|
179
|
+
{
|
180
|
+
struct vector* V = get_vector_from_rb_value(self);
|
181
|
+
|
182
|
+
struct vector* R;
|
183
|
+
VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, R);
|
184
|
+
|
185
|
+
c_vector_init(R, V->n);
|
186
|
+
copy_d_array(R->n, V->data, R->data);
|
187
|
+
|
188
|
+
return result;
|
189
|
+
}
|
190
|
+
|
191
|
+
VALUE vector_multiply_vm(VALUE self, VALUE other)
|
192
|
+
{
|
193
|
+
struct vector* V = get_vector_from_rb_value(self);
|
194
|
+
struct matrix* M = get_matrix_from_rb_value(other);
|
195
|
+
|
196
|
+
if(M->n != 1)
|
197
|
+
rb_raise(fm_eIndexError, "Number of rows must be 1");
|
198
|
+
|
199
|
+
int m = M->m;
|
200
|
+
int n = V->n;
|
201
|
+
|
202
|
+
struct matrix* R;
|
203
|
+
VALUE result = TypedData_Make_Struct(cMatrix, struct matrix, &matrix_type, R);
|
204
|
+
|
205
|
+
c_matrix_init(R, m, n);
|
206
|
+
c_vector_matrix_multiply(n, m, V->data, M->data, R->data);
|
207
|
+
|
208
|
+
return result;
|
209
|
+
}
|
210
|
+
|
211
|
+
VALUE vector_multiply_vn(VALUE self, VALUE value)
|
212
|
+
{
|
213
|
+
struct vector* A = get_vector_from_rb_value(self);
|
214
|
+
double d = NUM2DBL(value);
|
215
|
+
|
216
|
+
struct vector* R;
|
217
|
+
VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, R);
|
218
|
+
|
219
|
+
c_vector_init(R, A->n);
|
220
|
+
copy_d_array(R->n, A->data, R->data);
|
221
|
+
multiply_d_array(R->n, R->data, d);
|
222
|
+
|
223
|
+
return result;
|
224
|
+
}
|
225
|
+
|
226
|
+
VALUE vector_multiply_vv(VALUE self, VALUE other)
|
227
|
+
{
|
228
|
+
struct vector* A = get_vector_from_rb_value(self);
|
229
|
+
struct vector* B = get_vector_from_rb_value(other);
|
230
|
+
|
231
|
+
if(B->n != 1)
|
232
|
+
rb_raise(fm_eIndexError, "Length of vector must be equal to 1");
|
233
|
+
|
234
|
+
struct vector* R;
|
235
|
+
VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, R);
|
236
|
+
|
237
|
+
c_vector_init(R, A->n);
|
238
|
+
copy_d_array(A->n, A->data, R->data);
|
239
|
+
multiply_d_array(R->n, R->data, B->data[0]);
|
240
|
+
|
241
|
+
return result;
|
242
|
+
}
|
243
|
+
|
244
|
+
VALUE vector_multiply(VALUE self, VALUE v)
|
245
|
+
{
|
246
|
+
if(RB_FLOAT_TYPE_P(v) || FIXNUM_P(v)
|
247
|
+
|| RB_TYPE_P(v, T_BIGNUM))
|
248
|
+
return vector_multiply_vn(self, v);
|
249
|
+
if(RBASIC_CLASS(v) == cMatrix)
|
250
|
+
return vector_multiply_vm(self, v);
|
251
|
+
if(RBASIC_CLASS(v) == cVector)
|
252
|
+
return vector_multiply_vv(self, v);
|
253
|
+
rb_raise(fm_eTypeError, "Invalid klass for multiply");
|
254
|
+
}
|
255
|
+
|
256
|
+
VALUE vector_magnitude(VALUE self)
|
257
|
+
{
|
258
|
+
struct vector* A = get_vector_from_rb_value(self);
|
259
|
+
return DBL2NUM(c_vector_magnitude(A->n, A->data));
|
260
|
+
}
|
261
|
+
|
262
|
+
|
263
|
+
VALUE vector_normalize(VALUE self)
|
264
|
+
{
|
265
|
+
struct vector* A = get_vector_from_rb_value(self);
|
266
|
+
|
267
|
+
struct vector* R;
|
268
|
+
VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, R);
|
269
|
+
c_vector_init(R, A->n);
|
270
|
+
c_vector_normalize(A->n, A->data, R->data);
|
271
|
+
|
272
|
+
return result;
|
273
|
+
}
|
274
|
+
|
275
|
+
VALUE vector_normalize_self(VALUE self)
|
276
|
+
{
|
277
|
+
struct vector* A = get_vector_from_rb_value(self);
|
278
|
+
c_vector_normalize_self(A->n, A->data);
|
279
|
+
return self;
|
280
|
+
}
|
281
|
+
|
282
|
+
VALUE vector_minus(VALUE self)
|
283
|
+
{
|
284
|
+
struct vector* A = get_vector_from_rb_value(self);
|
285
|
+
|
286
|
+
struct vector* R;
|
287
|
+
VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, R);
|
288
|
+
c_vector_init(R, A->n);
|
289
|
+
|
290
|
+
multiply_d_array_to_result(A->n, A->data, -1, R->data);
|
291
|
+
|
292
|
+
return result;
|
293
|
+
}
|
294
|
+
|
295
|
+
VALUE vector_plus(VALUE self)
|
296
|
+
{
|
297
|
+
return self;
|
298
|
+
}
|
299
|
+
|
300
|
+
struct vector** convert_vector_array(int argc, VALUE *argv, struct vector*** vcts)
|
301
|
+
{
|
302
|
+
for(int i = 0; i < argc; ++i)
|
303
|
+
raise_check_rbasic(argv[i], cVector, "vector");
|
304
|
+
|
305
|
+
*vcts = (struct vector**)malloc(argc * sizeof(struct vector*));
|
306
|
+
|
307
|
+
for(int i = 0; i < argc; ++i)
|
308
|
+
TypedData_Get_Struct(argv[i], struct vector, &vector_type, (*vcts)[i]);
|
309
|
+
}
|
310
|
+
|
311
|
+
|
312
|
+
VALUE vector_independent(int argc, VALUE* argv, VALUE obj)
|
313
|
+
{
|
314
|
+
if(argc == 0)
|
315
|
+
return Qtrue;
|
316
|
+
|
317
|
+
struct vector** vcts;
|
318
|
+
convert_vector_array(argc, argv, &vcts);
|
319
|
+
|
320
|
+
int n = vcts[0]->n;
|
321
|
+
|
322
|
+
if(!c_vector_equal_by_size(argc, vcts, n))
|
323
|
+
{
|
324
|
+
free(vcts);
|
325
|
+
rb_raise(fm_eIndexError, "Rows of different size");
|
326
|
+
}
|
327
|
+
|
328
|
+
double* C = malloc(sizeof(double) * argc * n);
|
329
|
+
c_vector_hstack(n, argc, vcts, C);
|
330
|
+
int result = c_matrix_rank(n, argc, C);
|
331
|
+
|
332
|
+
free(vcts);
|
333
|
+
free(C);
|
334
|
+
if(result == argc)
|
335
|
+
return Qtrue;
|
336
|
+
return Qfalse;
|
337
|
+
}
|
338
|
+
|
339
|
+
VALUE vector_to_matrix(VALUE self)
|
340
|
+
{
|
341
|
+
struct vector* A = get_vector_from_rb_value(self);
|
342
|
+
|
343
|
+
struct matrix* C;
|
344
|
+
VALUE result = TypedData_Make_Struct(cMatrix, struct matrix, &matrix_type, C);
|
345
|
+
c_matrix_init(C, 1, A->n);
|
346
|
+
copy_d_array(A->n, A->data, C->data);
|
347
|
+
return result;
|
348
|
+
}
|
349
|
+
VALUE vector_covector(VALUE self)
|
350
|
+
{
|
351
|
+
struct vector* A = get_vector_from_rb_value(self);
|
352
|
+
|
353
|
+
struct matrix* C;
|
354
|
+
VALUE result = TypedData_Make_Struct(cMatrix, struct matrix, &matrix_type, C);
|
355
|
+
c_matrix_init(C, A->n, 1);
|
356
|
+
copy_d_array(A->n, A->data, C->data);
|
357
|
+
return result;
|
358
|
+
}
|
359
|
+
|
360
|
+
VALUE vector_zero(VALUE self)
|
361
|
+
{
|
362
|
+
struct vector* A = get_vector_from_rb_value(self);
|
363
|
+
if(zero_d_array(A->n, A->data))
|
364
|
+
return Qtrue;
|
365
|
+
return Qfalse;
|
366
|
+
}
|
367
|
+
|
368
|
+
VALUE vector_fill(VALUE self, VALUE value)
|
369
|
+
{
|
370
|
+
double d = raise_rb_value_to_double(value);
|
371
|
+
struct vector* A = get_vector_from_rb_value(self);
|
372
|
+
fill_d_array(A->n, A->data, d);
|
373
|
+
return self;
|
374
|
+
}
|
375
|
+
|
376
|
+
VALUE vector_round(int argc, VALUE *argv, VALUE self)
|
377
|
+
{
|
378
|
+
if(argc > 1)
|
379
|
+
rb_raise(fm_eTypeError, "Wrong number of arguments");
|
380
|
+
int d;
|
381
|
+
if(argc == 1)
|
382
|
+
d = raise_rb_value_to_int(argv[0]);
|
383
|
+
else
|
384
|
+
d = 0;
|
385
|
+
|
386
|
+
struct vector* A = get_vector_from_rb_value(self);
|
387
|
+
|
388
|
+
struct vector* R;
|
389
|
+
VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, R);
|
390
|
+
c_vector_init(R, A->n);
|
391
|
+
|
392
|
+
round_d_array(A->n, A->data, R->data, d);
|
393
|
+
|
394
|
+
return result;
|
395
|
+
}
|
396
|
+
|
397
|
+
VALUE vector_inner_product(VALUE self, VALUE other)
|
398
|
+
{
|
399
|
+
raise_check_rbasic(other, cVector, "vector");
|
400
|
+
struct vector* A = get_vector_from_rb_value(self);
|
401
|
+
struct vector* B = get_vector_from_rb_value(other);
|
402
|
+
raise_check_equal_size_vectors(A, B);
|
403
|
+
|
404
|
+
double result = c_vector_inner_product(A->n, A->data, B->data);
|
405
|
+
return DBL2NUM(result);
|
406
|
+
}
|
407
|
+
|
408
|
+
VALUE vector_angle_with(VALUE self, VALUE other)
|
409
|
+
{
|
410
|
+
raise_check_rbasic(other, cVector, "vector");
|
411
|
+
struct vector* A = get_vector_from_rb_value(self);
|
412
|
+
struct vector* B = get_vector_from_rb_value(other);
|
413
|
+
raise_check_equal_size_vectors(A, B);
|
414
|
+
|
415
|
+
double a = c_vector_magnitude(A->n, A->data);
|
416
|
+
double b = c_vector_magnitude(B->n, B->data);
|
417
|
+
double d = c_vector_inner_product(A->n, A->data, B->data);
|
418
|
+
|
419
|
+
return DBL2NUM(acos(d / (a * b)));
|
420
|
+
}
|
421
|
+
|
422
|
+
VALUE vector_cross_product(int argc, VALUE* argv, VALUE obj)
|
423
|
+
{
|
424
|
+
struct vector** vcts;
|
425
|
+
convert_vector_array(argc, argv, &vcts);
|
426
|
+
|
427
|
+
int n = argc + 1;
|
428
|
+
|
429
|
+
if(!c_vector_equal_by_size(argc, vcts, n))
|
430
|
+
{
|
431
|
+
free(vcts);
|
432
|
+
rb_raise(fm_eIndexError, "Rows of different size");
|
433
|
+
}
|
434
|
+
|
435
|
+
struct vector* R;
|
436
|
+
VALUE result = TypedData_Make_Struct(cVector, struct vector, &vector_type, R);
|
437
|
+
c_vector_init(R, n);
|
438
|
+
|
439
|
+
c_vector_cross_product(argc, vcts, R->data);
|
440
|
+
|
441
|
+
return result;
|
442
|
+
}
|
443
|
+
|
444
|
+
void init_fm_vector()
|
445
|
+
{
|
446
|
+
VALUE mod = rb_define_module("FastMatrix");
|
447
|
+
cVector = rb_define_class_under(mod, "Vector", rb_cData);
|
448
|
+
|
449
|
+
rb_define_alloc_func(cVector, vector_alloc);
|
450
|
+
|
451
|
+
rb_define_method(cVector, "initialize", vector_initialize, 1);
|
452
|
+
rb_define_method(cVector, "[]", vector_get, 1);
|
453
|
+
rb_define_method(cVector, "[]=", vector_set, 2);
|
454
|
+
rb_define_method(cVector, "size", vector_length, 0);
|
455
|
+
rb_define_method(cVector, "+", vector_add_with, 1);
|
456
|
+
rb_define_method(cVector, "+=", vector_add_from, 1);
|
457
|
+
rb_define_method(cVector, "-", vector_sub_with, 1);
|
458
|
+
rb_define_method(cVector, "-=", vector_sub_from, 1);
|
459
|
+
rb_define_method(cVector, "eql?", vector_equal, 1);
|
460
|
+
rb_define_method(cVector, "clone", vector_copy, 0);
|
461
|
+
rb_define_method(cVector, "magnitude", vector_magnitude, 0);
|
462
|
+
rb_define_method(cVector, "normalize", vector_normalize, 0);
|
463
|
+
rb_define_method(cVector, "normalize!", vector_normalize_self, 0);
|
464
|
+
rb_define_method(cVector, "-@", vector_minus, 0);
|
465
|
+
rb_define_method(cVector, "+@", vector_plus, 0);
|
466
|
+
rb_define_method(cVector, "*", vector_multiply, 1);
|
467
|
+
rb_define_method(cVector, "to_matrix", vector_to_matrix, 0);
|
468
|
+
rb_define_method(cVector, "covector", vector_covector, 0);
|
469
|
+
rb_define_method(cVector, "zero?", vector_zero, 0);
|
470
|
+
rb_define_method(cVector, "fill!", vector_fill, 1);
|
471
|
+
rb_define_method(cVector, "round", vector_round, -1);
|
472
|
+
rb_define_method(cVector, "inner_product", vector_inner_product, 1);
|
473
|
+
rb_define_method(cVector, "angle_with", vector_angle_with, 1);
|
474
|
+
rb_define_module_function(cVector, "independent?", vector_independent, -1);
|
475
|
+
rb_define_module_function(cVector, "cross_product", vector_cross_product, -1);
|
476
|
+
}
|