numerix 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +5 -0
- data/.yardopts +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +66 -0
- data/Rakefile +18 -0
- data/TODO.txt +25 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/numerix/common.h +107 -0
- data/ext/numerix/extconf.rb +3 -0
- data/ext/numerix/matrix3x2.c +638 -0
- data/ext/numerix/matrix3x2.h +52 -0
- data/ext/numerix/matrix4x4.c +1807 -0
- data/ext/numerix/matrix4x4.h +90 -0
- data/ext/numerix/matrix_base.c +307 -0
- data/ext/numerix/matrix_base.h +70 -0
- data/ext/numerix/numerix.c +33 -0
- data/ext/numerix/numerix.h +19 -0
- data/ext/numerix/plane.c +311 -0
- data/ext/numerix/plane.h +34 -0
- data/ext/numerix/quaternion.c +712 -0
- data/ext/numerix/quaternion.h +53 -0
- data/ext/numerix/structure.c +154 -0
- data/ext/numerix/structure.h +24 -0
- data/ext/numerix/vector.c +326 -0
- data/ext/numerix/vector.h +57 -0
- data/ext/numerix/vector2.c +641 -0
- data/ext/numerix/vector2.h +64 -0
- data/ext/numerix/vector3.c +805 -0
- data/ext/numerix/vector3.h +68 -0
- data/ext/numerix/vector4.c +727 -0
- data/ext/numerix/vector4.h +63 -0
- data/ext/numerix/vector_base.c +94 -0
- data/ext/numerix/vector_base.h +30 -0
- data/extra/numerix128.png +0 -0
- data/extra/numerix24.png +0 -0
- data/extra/numerix32.png +0 -0
- data/extra/numerix320.png +0 -0
- data/extra/numerix48.png +0 -0
- data/extra/numerix96.png +0 -0
- data/lib/numerix/error.rb +36 -0
- data/lib/numerix/matrix3x2.rb +420 -0
- data/lib/numerix/matrix4x4.rb +676 -0
- data/lib/numerix/matrix_base.rb +14 -0
- data/lib/numerix/plane.rb +154 -0
- data/lib/numerix/quaternion.rb +355 -0
- data/lib/numerix/structure.rb +124 -0
- data/lib/numerix/vector.rb +13 -0
- data/lib/numerix/vector2.rb +534 -0
- data/lib/numerix/vector3.rb +572 -0
- data/lib/numerix/vector4.rb +551 -0
- data/lib/numerix/vector_base.rb +14 -0
- data/lib/numerix/version.rb +6 -0
- data/lib/numerix.rb +10 -0
- data/numerix.gemspec +30 -0
- metadata +167 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
#ifndef NUMERIX_QUATERNION_H
|
2
|
+
#define NUMERIX_QUATERNION_H 1
|
3
|
+
|
4
|
+
#include "common.h"
|
5
|
+
#include "vector_base.h"
|
6
|
+
|
7
|
+
#define QUATERNION() \
|
8
|
+
Quaternion *q; \
|
9
|
+
Data_Get_Struct(self, Quaternion, q);
|
10
|
+
|
11
|
+
void Init_quaternion(VALUE outer);
|
12
|
+
VALUE rb_quaternion_alloc(VALUE klass);
|
13
|
+
VALUE rb_quaternion_initialize(int argc, VALUE *argv, VALUE self);
|
14
|
+
|
15
|
+
// Instance
|
16
|
+
VALUE rb_quaternion_identity_p(VALUE self);
|
17
|
+
VALUE rb_quaternion_length(VALUE self);
|
18
|
+
VALUE rb_quaternion_length_squared(VALUE self);
|
19
|
+
VALUE rb_quaternion_negate(VALUE self);
|
20
|
+
VALUE rb_quaternion_add(VALUE self, VALUE other);
|
21
|
+
VALUE rb_quaternion_subtract(VALUE self, VALUE other);
|
22
|
+
VALUE rb_quaternion_multiply(VALUE self, VALUE other);
|
23
|
+
VALUE rb_quaternion_divide(VALUE self, VALUE other);
|
24
|
+
VALUE rb_quaternion_equal(VALUE self, VALUE other);
|
25
|
+
VALUE rb_quaternion_normalize(VALUE self);
|
26
|
+
VALUE rb_quaternion_normalize_bang(VALUE self);
|
27
|
+
VALUE rb_quaternion_conjugate(VALUE self);
|
28
|
+
VALUE rb_quaternion_conjugate_bang(VALUE self);
|
29
|
+
VALUE rb_quaternion_inverse(VALUE self);
|
30
|
+
VALUE rb_quaternion_dot(VALUE self, VALUE other);
|
31
|
+
VALUE rb_quaternion_concatenate(VALUE self, VALUE other);
|
32
|
+
VALUE rb_quaternion_concatenate_bang(VALUE self, VALUE other);
|
33
|
+
VALUE rb_quaternion_lerp(VALUE self, VALUE other, VALUE amount);
|
34
|
+
VALUE rb_quaternion_lerp_bang(VALUE self, VALUE other, VALUE amount);
|
35
|
+
VALUE rb_quaternion_slerp(VALUE self, VALUE other, VALUE amount);
|
36
|
+
VALUE rb_quaternion_slerp_bang(VALUE self, VALUE other, VALUE amount);
|
37
|
+
|
38
|
+
// Conversion
|
39
|
+
VALUE rb_quaternion_to_s(VALUE self);
|
40
|
+
VALUE rb_quaternion_to_a(VALUE self);
|
41
|
+
VALUE rb_quaternion_to_h(VALUE self);
|
42
|
+
VALUE rb_quaternion_to_vec4(VALUE self);
|
43
|
+
|
44
|
+
// Class
|
45
|
+
VALUE rb_quaternion_identity(VALUE klass);
|
46
|
+
VALUE rb_quaternion_from_axis_angle(VALUE klass, VALUE vec3, VALUE angle);
|
47
|
+
VALUE rb_quaternion_from_yaw_pitch_roll(VALUE klass, VALUE yaw, VALUE pitch, VALUE roll);
|
48
|
+
VALUE rb_quaternion_from_rotation_matrix(VALUE klass, VALUE matrix);
|
49
|
+
|
50
|
+
static inline VALUE rb_quaternion_slerp_s(VALUE klass, VALUE quaternion1, VALUE quaternion2, VALUE amount);
|
51
|
+
static inline VALUE rb_quaternion_lerp_s(VALUE klass, VALUE quaternion1, VALUE quaternion2, VALUE amount);
|
52
|
+
|
53
|
+
#endif /* NUMERIX_QUATERNION_H */
|
@@ -0,0 +1,154 @@
|
|
1
|
+
|
2
|
+
#include "structure.h"
|
3
|
+
|
4
|
+
VALUE rb_cNumerixStruct;
|
5
|
+
|
6
|
+
#if RUBY_API_VERSION_MAJOR >= 2
|
7
|
+
VALUE rb_numerix_cFiddlePointer;
|
8
|
+
#endif
|
9
|
+
|
10
|
+
void Init_numerix_structure(VALUE outer) {
|
11
|
+
rb_cNumerixStruct = rb_define_class_under(outer, "Structure", rb_cObject);
|
12
|
+
rb_define_method(rb_cNumerixStruct, "initialize", rb_numerix_abstract_initialize, 0);
|
13
|
+
|
14
|
+
rb_define_method(rb_cNumerixStruct, "dup", rb_numerix_dup, 0);
|
15
|
+
rb_define_method(rb_cNumerixStruct, "address", rb_numerix_address, 0);
|
16
|
+
rb_define_method(rb_cNumerixStruct, "_dump", rb_numerix_dump, -1);
|
17
|
+
rb_define_method(rb_cNumerixStruct, "[]", rb_numerix_aref, 1);
|
18
|
+
rb_define_method(rb_cNumerixStruct, "[]=", rb_numerix_aset, 2);
|
19
|
+
rb_define_method(rb_cNumerixStruct, "each", rb_numerix_each, 0);
|
20
|
+
|
21
|
+
rb_define_singleton_method(rb_cNumerixStruct, "size", rb_numerix_size, 0);
|
22
|
+
rb_define_singleton_method(rb_cNumerixStruct, "_load", rb_numerix_load, 1);
|
23
|
+
rb_define_singleton_method(rb_cNumerixStruct, "unpack", rb_numerix_load, 1);
|
24
|
+
|
25
|
+
rb_define_alias(rb_cNumerixStruct, "pack", "_dump");
|
26
|
+
|
27
|
+
#if RUBY_API_VERSION_MAJOR >= 2
|
28
|
+
rb_require("fiddle");
|
29
|
+
VALUE fiddle = rb_const_get(rb_cObject, rb_intern("Fiddle"));
|
30
|
+
rb_numerix_cFiddlePointer = rb_const_get(fiddle, rb_intern("Pointer"));
|
31
|
+
rb_define_method(rb_cNumerixStruct, "ptr", rb_numerix_fiddle_ptr, 0);
|
32
|
+
#endif
|
33
|
+
}
|
34
|
+
|
35
|
+
#if RUBY_API_VERSION_MAJOR >= 2
|
36
|
+
|
37
|
+
VALUE rb_numerix_fiddle_ptr(VALUE self) {
|
38
|
+
// Get basic data about the struct
|
39
|
+
struct RData *rdata = RDATA(self);
|
40
|
+
VALUE *args = xmalloc(sizeof(VALUE) * 2);
|
41
|
+
// Set the platform pointer-size address
|
42
|
+
#if SIZEOF_INTPTR_T == 4
|
43
|
+
args[0] = LONG2NUM((long)rdata->data);
|
44
|
+
#elif SIZEOF_INTPTR_T == 8
|
45
|
+
args[0] = LL2NUM((long long)rdata->data);
|
46
|
+
#else
|
47
|
+
args[0] = INT2NUM(0);
|
48
|
+
#endif
|
49
|
+
// Get size of structure
|
50
|
+
int size = rb_numerix_isize(rdata->basic.klass);
|
51
|
+
args[1] = INT2NUM(size);
|
52
|
+
VALUE ptr = rb_class_new_instance(2, args, rb_numerix_cFiddlePointer);
|
53
|
+
xfree(args);
|
54
|
+
return ptr;
|
55
|
+
}
|
56
|
+
|
57
|
+
#endif
|
58
|
+
|
59
|
+
VALUE rb_numerix_each(VALUE self) {
|
60
|
+
struct RData *rdata = RDATA(self);
|
61
|
+
int count = rb_numerix_isize(rdata->basic.klass) / sizeof(float);
|
62
|
+
|
63
|
+
volatile VALUE str = self;
|
64
|
+
|
65
|
+
RETURN_SIZED_ENUMERATOR(str, 0, 0, count);
|
66
|
+
|
67
|
+
float *flt = (float *)rdata->data;
|
68
|
+
for (int i = 0; i < count; i++)
|
69
|
+
rb_yield(DBL2NUM(flt[i]));
|
70
|
+
|
71
|
+
return str;
|
72
|
+
}
|
73
|
+
|
74
|
+
VALUE rb_numerix_aref(VALUE self, VALUE index) {
|
75
|
+
struct RData *rdata = RDATA(self);
|
76
|
+
int max = rb_numerix_isize(rdata->basic.klass) / sizeof(float);
|
77
|
+
int i = NUM2INT(index);
|
78
|
+
|
79
|
+
if (i < 0 || i >= max)
|
80
|
+
return Qnil;
|
81
|
+
|
82
|
+
float *flt = (float *)rdata->data;
|
83
|
+
return DBL2NUM(flt[i]);
|
84
|
+
}
|
85
|
+
|
86
|
+
VALUE rb_numerix_aset(VALUE self, VALUE index, VALUE value) {
|
87
|
+
struct RData *rdata = RDATA(self);
|
88
|
+
int max = rb_numerix_isize(rdata->basic.klass) / sizeof(float);
|
89
|
+
int i = NUM2INT(index);
|
90
|
+
|
91
|
+
if (i >= 0 || i < max) {
|
92
|
+
float *flt = (float *)rdata->data;
|
93
|
+
flt[i] = NUM2FLT(value);
|
94
|
+
}
|
95
|
+
|
96
|
+
return value;
|
97
|
+
}
|
98
|
+
|
99
|
+
VALUE rb_numerix_dup(VALUE self) {
|
100
|
+
struct RData *rdata = RDATA(self);
|
101
|
+
int size = rb_numerix_isize(rdata->basic.klass);
|
102
|
+
void *data = ruby_xmalloc(size);
|
103
|
+
memcpy(data, rdata->data, size);
|
104
|
+
return NUMERIX_WRAP(rdata->basic.klass, data);
|
105
|
+
}
|
106
|
+
|
107
|
+
VALUE rb_numerix_address(VALUE self) {
|
108
|
+
void *address = RDATA(self)->data;
|
109
|
+
#if SIZEOF_INTPTR_T == 4
|
110
|
+
return LONG2NUM((long)address);
|
111
|
+
#elif SIZEOF_INTPTR_T == 8
|
112
|
+
return LL2NUM((long long)address);
|
113
|
+
#else
|
114
|
+
return INT2NUM(0);
|
115
|
+
#endif
|
116
|
+
}
|
117
|
+
|
118
|
+
static inline int rb_numerix_isize(VALUE klass) {
|
119
|
+
if (NUMERIX_INHERIT_P(klass, rb_cVector2))
|
120
|
+
return sizeof(Vector2);
|
121
|
+
if (NUMERIX_INHERIT_P(klass, rb_cVector3))
|
122
|
+
return sizeof(Vector3);
|
123
|
+
if (NUMERIX_INHERIT_P(klass, rb_cVector4))
|
124
|
+
return sizeof(Vector4);
|
125
|
+
if (NUMERIX_INHERIT_P(klass, rb_cMatrix3x2))
|
126
|
+
return sizeof(Matrix3x2);
|
127
|
+
if (NUMERIX_INHERIT_P(klass, rb_cMatrix4x4))
|
128
|
+
return sizeof(Matrix4x4);
|
129
|
+
if (NUMERIX_INHERIT_P(klass, rb_cPlane))
|
130
|
+
return sizeof(Plane);
|
131
|
+
if (NUMERIX_INHERIT_P(klass, rb_cQuaternion))
|
132
|
+
return sizeof(Quaternion);
|
133
|
+
return 0;
|
134
|
+
}
|
135
|
+
|
136
|
+
VALUE rb_numerix_size(VALUE klass) {
|
137
|
+
int size = rb_numerix_isize(klass);
|
138
|
+
return INT2NUM(size);
|
139
|
+
}
|
140
|
+
|
141
|
+
VALUE rb_numerix_dump(int arc, VALUE *argv, VALUE self) {
|
142
|
+
int size = rb_numerix_isize(CLASS_OF(self));
|
143
|
+
VALUE str = rb_str_new(NULL, size);
|
144
|
+
void *data = RDATA(self)->data;
|
145
|
+
memcpy(RSTRING_PTR(str), data, size);
|
146
|
+
return str;
|
147
|
+
}
|
148
|
+
|
149
|
+
VALUE rb_numerix_load(VALUE klass, VALUE str) {
|
150
|
+
int size = rb_numerix_isize(klass);
|
151
|
+
void *data = ruby_xmalloc(size);
|
152
|
+
memcpy(data, RSTRING_PTR(str), size);
|
153
|
+
return NUMERIX_WRAP(klass, data);
|
154
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#ifndef NUMERIX_STRUCTURE_H
|
2
|
+
#define NUMERIX_STRUCTURE_H 1
|
3
|
+
|
4
|
+
#include "common.h"
|
5
|
+
#include "ruby/version.h"
|
6
|
+
|
7
|
+
void Init_numerix_structure(VALUE outer);
|
8
|
+
|
9
|
+
VALUE rb_numerix_address(VALUE self);
|
10
|
+
VALUE rb_numerix_dump(int arc, VALUE *argv, VALUE self);
|
11
|
+
VALUE rb_numerix_dup(VALUE self);
|
12
|
+
VALUE rb_numerix_aref(VALUE self, VALUE index);
|
13
|
+
VALUE rb_numerix_aset(VALUE self, VALUE index, VALUE value);
|
14
|
+
VALUE rb_numerix_each(VALUE self);
|
15
|
+
|
16
|
+
#if RUBY_API_VERSION_MAJOR >= 2
|
17
|
+
VALUE rb_numerix_fiddle_ptr(VALUE self);
|
18
|
+
#endif
|
19
|
+
|
20
|
+
static inline int rb_numerix_isize(VALUE klass);
|
21
|
+
VALUE rb_numerix_size(VALUE klass);
|
22
|
+
VALUE rb_numerix_load(VALUE klass, VALUE str);
|
23
|
+
|
24
|
+
#endif /* NUMERIX_STRUCTURE_H */
|
@@ -0,0 +1,326 @@
|
|
1
|
+
|
2
|
+
#include "vector.h"
|
3
|
+
|
4
|
+
VALUE rb_cBasicVector;
|
5
|
+
|
6
|
+
void Init_basic_vector(VALUE outer) {
|
7
|
+
rb_cBasicVector = rb_define_class_under(outer, "Vector", rb_cObject);
|
8
|
+
rb_define_alloc_func(rb_cBasicVector, rb_basic_vector_alloc);
|
9
|
+
rb_define_method(rb_cBasicVector, "initialize", rb_basic_vector_initialize, -1);
|
10
|
+
|
11
|
+
// Instance
|
12
|
+
rb_define_method(rb_cBasicVector, "size", rb_basic_vector_size, 0);
|
13
|
+
rb_define_method(rb_cBasicVector, "address", rb_basic_vector_address, 0);
|
14
|
+
rb_define_method(rb_cBasicVector, "count", rb_basic_vector_count, 0);
|
15
|
+
rb_define_method(rb_cBasicVector, "length", rb_basic_vector_length, 0);
|
16
|
+
rb_define_method(rb_cBasicVector, "length_squared", rb_basic_vector_length_squared, 0);
|
17
|
+
rb_define_method(rb_cBasicVector, "normalize", rb_basic_vector_normalize, 0);
|
18
|
+
rb_define_method(rb_cBasicVector, "normalize!", rb_basic_vector_normalize_bang, 0);
|
19
|
+
rb_define_method(rb_cBasicVector, "each", rb_basic_vector_each, 0);
|
20
|
+
rb_define_method(rb_cBasicVector, "dot", rb_basic_vector_dot, 1);
|
21
|
+
|
22
|
+
// Operators
|
23
|
+
rb_define_method(rb_cBasicVector, "+", rb_basic_vector_add, 1);
|
24
|
+
rb_define_method(rb_cBasicVector, "-", rb_basic_vector_subtract, 1);
|
25
|
+
rb_define_method(rb_cBasicVector, "*", rb_basic_vector_multiply, 1);
|
26
|
+
rb_define_method(rb_cBasicVector, "/", rb_basic_vector_divide, 1);
|
27
|
+
rb_define_method(rb_cBasicVector, "-@", rb_basic_vector_negate, 0);
|
28
|
+
rb_define_method(rb_cBasicVector, "==", rb_basic_vector_equal, 1);
|
29
|
+
rb_define_method(rb_cBasicVector, "[]", rb_basic_vector_aref, 1);
|
30
|
+
rb_define_method(rb_cBasicVector, "[]=", rb_basic_vector_aset, 2);
|
31
|
+
rb_define_method(rb_cBasicVector, "**", rb_basic_vector_pow, 1);
|
32
|
+
|
33
|
+
rb_define_method(rb_cBasicVector, "to_s", rb_basic_vector_to_s, 0);
|
34
|
+
|
35
|
+
// Alias
|
36
|
+
rb_define_alias(rb_cBasicVector, "magnitude", "length");
|
37
|
+
|
38
|
+
// Class
|
39
|
+
rb_define_singleton_method(rb_cBasicVector, "[]", rb_basic_vector_create, -1);
|
40
|
+
|
41
|
+
// Include
|
42
|
+
rb_include_module(rb_cBasicVector, rb_mEnumerable);
|
43
|
+
}
|
44
|
+
|
45
|
+
VALUE rb_basic_vector_alloc(VALUE klass) {
|
46
|
+
BasicVector *v = ALLOC(BasicVector);
|
47
|
+
v->count = 0;
|
48
|
+
v->values = NULL;
|
49
|
+
return NUMERIX_WRAP(klass, v);
|
50
|
+
}
|
51
|
+
|
52
|
+
VALUE rb_basic_vector_initialize(int argc, VALUE *argv, VALUE self) {
|
53
|
+
BASIC_VECTOR();
|
54
|
+
if (argc == 1) {
|
55
|
+
int count = NUM2INT(argv[0]);
|
56
|
+
if (count < 2) {
|
57
|
+
rb_raise(rb_eNumerixError, "vector size must be 2 or greater");
|
58
|
+
return Qnil;
|
59
|
+
}
|
60
|
+
v->count = count;
|
61
|
+
v->values = (float *)ruby_xmalloc(sizeof(float) * count);
|
62
|
+
memset(v->values, 0, count * sizeof(float));
|
63
|
+
} else if (argc > 1) {
|
64
|
+
v->count = argc;
|
65
|
+
v->values = (float *)ruby_xmalloc(sizeof(float) * argc);
|
66
|
+
for (int i = 0; i < argc; i++)
|
67
|
+
v->values[i] = NUM2FLT(argv[i]);
|
68
|
+
} else
|
69
|
+
rb_raise(rb_eArgError, "no arguments given");
|
70
|
+
|
71
|
+
return Qnil;
|
72
|
+
}
|
73
|
+
|
74
|
+
VALUE rb_basic_vector_create(int argc, VALUE *argv, VALUE klass) {
|
75
|
+
if (argc < 2)
|
76
|
+
rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 2 or more)", argc);
|
77
|
+
|
78
|
+
BasicVector *v = ALLOC(BasicVector);
|
79
|
+
v->count = argc;
|
80
|
+
v->values = ruby_xmalloc(sizeof(float) * argc);
|
81
|
+
for (int i = 0; i < argc; i++)
|
82
|
+
v->values[i] = NUM2FLT(argv[i]);
|
83
|
+
rb_basic_vector_create;
|
84
|
+
|
85
|
+
return NUMERIX_WRAP(klass, v);
|
86
|
+
}
|
87
|
+
|
88
|
+
VALUE rb_basic_vector_length(VALUE self) {
|
89
|
+
BASIC_VECTOR();
|
90
|
+
int c = v->count;
|
91
|
+
float length = 0.0f;
|
92
|
+
for (int i = 0; i < c; i++)
|
93
|
+
length += v->values[i] * v->values[i];
|
94
|
+
|
95
|
+
return DBL2NUM(sqrtf(length));
|
96
|
+
}
|
97
|
+
|
98
|
+
VALUE rb_basic_vector_length_squared(VALUE self) {
|
99
|
+
BASIC_VECTOR();
|
100
|
+
int c = v->count;
|
101
|
+
float length = 0.0f;
|
102
|
+
for (int i = 0; i < c; i++)
|
103
|
+
length += v->values[i] * v->values[i];
|
104
|
+
|
105
|
+
return DBL2NUM(length);
|
106
|
+
}
|
107
|
+
|
108
|
+
VALUE rb_basic_vector_normalize(VALUE self) {
|
109
|
+
BASIC_VECTOR_RESULT();
|
110
|
+
|
111
|
+
int c = v->count;
|
112
|
+
float length = 0.0f;
|
113
|
+
for (int i = 0; i < c; i++)
|
114
|
+
length += v->values[i] * v->values[i];
|
115
|
+
|
116
|
+
float inverse = 1.0f / sqrtf(length);
|
117
|
+
for (int i = 0; i < c; i++)
|
118
|
+
result->values[i] = v->values[i] * inverse;
|
119
|
+
|
120
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
121
|
+
}
|
122
|
+
|
123
|
+
VALUE rb_basic_vector_normalize_bang(VALUE self) {
|
124
|
+
BASIC_VECTOR();
|
125
|
+
|
126
|
+
int c = v->count;
|
127
|
+
float length = 0.0f;
|
128
|
+
for (int i = 0; i < c; i++)
|
129
|
+
length += v->values[i] * v->values[i];
|
130
|
+
|
131
|
+
float inverse = 1.0f / sqrtf(length);
|
132
|
+
for (int i = 0; i < c; i++)
|
133
|
+
v->values[i] *= inverse;
|
134
|
+
|
135
|
+
return self;
|
136
|
+
}
|
137
|
+
|
138
|
+
VALUE rb_basic_vector_add(VALUE self, VALUE other) {
|
139
|
+
BASIC_VECTOR_OTHER_RESULT();
|
140
|
+
for (int i = 0; i < count; i++)
|
141
|
+
result->values[i] = v1->values[i] + v2->values[i];
|
142
|
+
|
143
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
144
|
+
}
|
145
|
+
|
146
|
+
VALUE rb_basic_vector_subtract(VALUE self, VALUE other) {
|
147
|
+
BASIC_VECTOR_OTHER_RESULT();
|
148
|
+
for (int i = 0; i < count; i++)
|
149
|
+
result->values[i] = v1->values[i] - v2->values[i];
|
150
|
+
|
151
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
152
|
+
}
|
153
|
+
|
154
|
+
VALUE rb_basic_vector_multiply(VALUE self, VALUE other) {
|
155
|
+
BASIC_VECTOR_RESULT();
|
156
|
+
int count = v->count;
|
157
|
+
if (NUMERIX_TYPE_P(other, rb_cBasicVector)) {
|
158
|
+
BasicVector *v2;
|
159
|
+
Data_Get_Struct(other, BasicVector, v2);
|
160
|
+
if (count != v2->count)
|
161
|
+
rb_raise(rb_eNumerixError, "unequal length vectors");
|
162
|
+
for (int i = 0; i < count; i++)
|
163
|
+
result->values[i] = v->values[i] * v2->values[i];
|
164
|
+
} else {
|
165
|
+
float scalar = NUM2FLT(other);
|
166
|
+
for (int i = 0; i < count; i++)
|
167
|
+
result->values[i] = v->values[i] * scalar;
|
168
|
+
}
|
169
|
+
|
170
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
171
|
+
}
|
172
|
+
|
173
|
+
VALUE rb_basic_vector_divide(VALUE self, VALUE other) {
|
174
|
+
BASIC_VECTOR_RESULT();
|
175
|
+
int count = v->count;
|
176
|
+
if (NUMERIX_TYPE_P(other, rb_cBasicVector)) {
|
177
|
+
BasicVector *v2;
|
178
|
+
Data_Get_Struct(other, BasicVector, v2);
|
179
|
+
if (count != v2->count)
|
180
|
+
rb_raise(rb_eNumerixError, "unequal length vectors");
|
181
|
+
for (int i = 0; i < count; i++)
|
182
|
+
result->values[i] = v->values[i] / v2->values[i];
|
183
|
+
} else {
|
184
|
+
float scalar = 1.0f / NUM2FLT(other);
|
185
|
+
for (int i = 0; i < count; i++)
|
186
|
+
result->values[i] = v->values[i] * scalar;
|
187
|
+
}
|
188
|
+
|
189
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
190
|
+
}
|
191
|
+
|
192
|
+
VALUE rb_basic_vector_negate(VALUE self, VALUE other) {
|
193
|
+
BASIC_VECTOR_RESULT();
|
194
|
+
|
195
|
+
int c = v->count;
|
196
|
+
for (int i = 0; i < c; i++)
|
197
|
+
result->values[i] = -v->values[i];
|
198
|
+
|
199
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
200
|
+
}
|
201
|
+
|
202
|
+
VALUE rb_basic_vector_equal(VALUE self, VALUE other) {
|
203
|
+
if (CLASS_OF(self) != CLASS_OF(other))
|
204
|
+
return Qfalse;
|
205
|
+
|
206
|
+
BasicVector *v1, *v2;
|
207
|
+
Data_Get_Struct(self, BasicVector, v1);
|
208
|
+
Data_Get_Struct(other, BasicVector, v2);
|
209
|
+
|
210
|
+
int count = v1->count;
|
211
|
+
|
212
|
+
if (count != v2->count)
|
213
|
+
return Qfalse;
|
214
|
+
|
215
|
+
for (int i = 0; i < count; i++) {
|
216
|
+
if (!FLT_EQUAL(v1->values[i], v2->values[i]))
|
217
|
+
return Qfalse;
|
218
|
+
}
|
219
|
+
|
220
|
+
return Qtrue;
|
221
|
+
}
|
222
|
+
|
223
|
+
VALUE rb_basic_vector_size(VALUE self) {
|
224
|
+
BASIC_VECTOR();
|
225
|
+
return INT2NUM(v->count * sizeof(float));
|
226
|
+
}
|
227
|
+
|
228
|
+
VALUE rb_basic_vector_address(VALUE self) {
|
229
|
+
BASIC_VECTOR();
|
230
|
+
#if (SIZEOF_INTPTR_T == 4)
|
231
|
+
return LONG2NUM((long)v->values);
|
232
|
+
#elif (SIZEOF_INTPTR_T == 8)
|
233
|
+
return LL2NUM((long long)v->values)
|
234
|
+
#else
|
235
|
+
return INT2NUM(0);
|
236
|
+
#endif
|
237
|
+
}
|
238
|
+
|
239
|
+
VALUE rb_basic_vector_count(VALUE self) {
|
240
|
+
BASIC_VECTOR();
|
241
|
+
return INT2NUM(v->count);
|
242
|
+
}
|
243
|
+
|
244
|
+
VALUE rb_basic_vector_aref(VALUE self, VALUE index) {
|
245
|
+
BASIC_VECTOR();
|
246
|
+
int i = NUM2INT(index);
|
247
|
+
|
248
|
+
if (i < 0 || i >= v->count)
|
249
|
+
return Qnil;
|
250
|
+
return DBL2NUM(v->values[i]);
|
251
|
+
}
|
252
|
+
|
253
|
+
VALUE rb_basic_vector_aset(VALUE self, VALUE index, VALUE value) {
|
254
|
+
BASIC_VECTOR();
|
255
|
+
int i = NUM2INT(index);
|
256
|
+
|
257
|
+
if (i >= 0 && i < v->count)
|
258
|
+
v->values[i] = NUM2FLT(value);
|
259
|
+
|
260
|
+
return value;
|
261
|
+
}
|
262
|
+
|
263
|
+
VALUE rb_basic_vector_each(VALUE self) {
|
264
|
+
BASIC_VECTOR();
|
265
|
+
int count = v->count;
|
266
|
+
|
267
|
+
volatile VALUE vector = self;
|
268
|
+
RETURN_SIZED_ENUMERATOR(vector, 0, 0, count);
|
269
|
+
|
270
|
+
for (int i = 0; i < count; i++)
|
271
|
+
rb_yield(DBL2NUM(v->values[i]));
|
272
|
+
|
273
|
+
return vector;
|
274
|
+
}
|
275
|
+
|
276
|
+
VALUE rb_basic_vector_dot(VALUE self, VALUE other) {
|
277
|
+
BasicVector *v1, *v2;
|
278
|
+
Data_Get_Struct(self, BasicVector, v1);
|
279
|
+
Data_Get_Struct(self, BasicVector, v1);
|
280
|
+
int count = v1->count;
|
281
|
+
if (count != v2->count)
|
282
|
+
rb_raise(rb_eNumerixError, "unequal length vectors");
|
283
|
+
|
284
|
+
float dot = 0;
|
285
|
+
for (int i = 0; i < count; i++)
|
286
|
+
dot += v1->values[i] * v2->values[i];
|
287
|
+
|
288
|
+
return DBL2NUM(dot);
|
289
|
+
}
|
290
|
+
|
291
|
+
VALUE rb_basic_vector_to_s(VALUE self) {
|
292
|
+
VALUE ary = rb_funcall(self, rb_intern("to_a"), 0);
|
293
|
+
VALUE str = rb_ary_join(ary, rb_str_new_cstr(", "));
|
294
|
+
return rb_sprintf("<%" PRIsVALUE ">", str);
|
295
|
+
}
|
296
|
+
|
297
|
+
VALUE rb_basic_vector_abs(VALUE self) {
|
298
|
+
BASIC_VECTOR_RESULT();
|
299
|
+
|
300
|
+
int count = v->count;
|
301
|
+
for (int i = 0; i < count; i++)
|
302
|
+
result->values[i] = fabsf(v->values[i]);
|
303
|
+
|
304
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
305
|
+
}
|
306
|
+
|
307
|
+
VALUE rb_basic_vector_sqrt(VALUE self) {
|
308
|
+
BASIC_VECTOR_RESULT();
|
309
|
+
|
310
|
+
int count = v->count;
|
311
|
+
for (int i = 0; i < count; i++)
|
312
|
+
result->values[i] = sqrtf(v->values[i]);
|
313
|
+
|
314
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
315
|
+
}
|
316
|
+
|
317
|
+
VALUE rb_basic_vector_pow(VALUE self, VALUE exponent) {
|
318
|
+
BASIC_VECTOR_RESULT();
|
319
|
+
|
320
|
+
float e = fabsf(NUM2FLT(exponent));
|
321
|
+
int count = v->count;
|
322
|
+
for (int i = 0; i < count; i++)
|
323
|
+
result->values[i] = powf(v->values[i], e);
|
324
|
+
|
325
|
+
return NUMERIX_WRAP(CLASS_OF(self), result);
|
326
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#ifndef NUMERIX_BASIC_VECTOR_H
|
2
|
+
#define NUMERIX_BASIC_VECTOR_H 1
|
3
|
+
|
4
|
+
#include "common.h"
|
5
|
+
|
6
|
+
#define BASIC_VECTOR() \
|
7
|
+
BasicVector *v; \
|
8
|
+
Data_Get_Struct(self, BasicVector, v)
|
9
|
+
|
10
|
+
#define BASIC_VECTOR_RESULT() \
|
11
|
+
BASIC_VECTOR(); \
|
12
|
+
BasicVector *result = ALLOC(BasicVector); \
|
13
|
+
result->count = v->count; \
|
14
|
+
result->values = ruby_xmalloc(sizeof(float) * v->count)
|
15
|
+
|
16
|
+
#define BASIC_VECTOR_OTHER_RESULT() \
|
17
|
+
BasicVector *v1, *v2, *result; \
|
18
|
+
Data_Get_Struct(self, BasicVector, v1); \
|
19
|
+
Data_Get_Struct(other, BasicVector, v2); \
|
20
|
+
result = ALLOC(BasicVector); \
|
21
|
+
int count = v1->count; \
|
22
|
+
if (count != v2->count) \
|
23
|
+
rb_raise(rb_eNumerixError, "unequal length vectors"); \
|
24
|
+
result->count = count; \
|
25
|
+
result->values = ruby_xmalloc(sizeof(float) * count)
|
26
|
+
|
27
|
+
void Init_basic_vector(VALUE outer);
|
28
|
+
VALUE rb_basic_vector_alloc(VALUE klass);
|
29
|
+
VALUE rb_basic_vector_initialize(int argc, VALUE *argv, VALUE self);
|
30
|
+
|
31
|
+
// Instance
|
32
|
+
VALUE rb_basic_vector_length(VALUE self);
|
33
|
+
VALUE rb_basic_vector_length_squared(VALUE self);
|
34
|
+
VALUE rb_basic_vector_normalize(VALUE self);
|
35
|
+
VALUE rb_basic_vector_normalize_bang(VALUE self);
|
36
|
+
VALUE rb_basic_vector_add(VALUE self, VALUE other);
|
37
|
+
VALUE rb_basic_vector_subtract(VALUE self, VALUE other);
|
38
|
+
VALUE rb_basic_vector_multiply(VALUE self, VALUE other);
|
39
|
+
VALUE rb_basic_vector_divide(VALUE self, VALUE other);
|
40
|
+
VALUE rb_basic_vector_negate(VALUE self, VALUE other);
|
41
|
+
VALUE rb_basic_vector_equal(VALUE self, VALUE other);
|
42
|
+
VALUE rb_basic_vector_size(VALUE self);
|
43
|
+
VALUE rb_basic_vector_address(VALUE self);
|
44
|
+
VALUE rb_basic_vector_count(VALUE self);
|
45
|
+
VALUE rb_basic_vector_each(VALUE self);
|
46
|
+
VALUE rb_basic_vector_aref(VALUE self, VALUE index);
|
47
|
+
VALUE rb_basic_vector_aset(VALUE self, VALUE index, VALUE value);
|
48
|
+
VALUE rb_basic_vector_dot(VALUE self, VALUE other);
|
49
|
+
VALUE rb_basic_vector_to_s(VALUE self);
|
50
|
+
VALUE rb_basic_vector_abs(VALUE self);
|
51
|
+
VALUE rb_basic_vector_sqrt(VALUE self);
|
52
|
+
VALUE rb_basic_vector_pow(VALUE self, VALUE exponent);
|
53
|
+
|
54
|
+
// Class
|
55
|
+
VALUE rb_basic_vector_create(int argc, VALUE *argv, VALUE klass);
|
56
|
+
|
57
|
+
#endif
|