carray-gsl 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c8b74785542cb1662a05431117c483ed7a56e487
4
+ data.tar.gz: 20c52d8cf11146d6109400b8fcb382e90d8a4b68
5
+ SHA512:
6
+ metadata.gz: 18f6da917bde79bc5eced98db907d046e99341f009835c739a56f5d97d9d92abcd2a84d7dfc9f9f8c058960bbd0e194456e5168bffd18ee76a1b3e3253695880
7
+ data.tar.gz: b9798ba5a9feb0a873e38eaaebf110378346e09af57f0e69b5a9d13ca14f135a86fc70f0be58b5dcedd945939b9f4d7f6ea16fb1359185147b94d45a774fced4
data/README.md ADDED
@@ -0,0 +1,10 @@
1
+ carray-gsl
2
+ ==========
3
+
4
+ This directory contains the plugin library used as the interface to GSL
5
+ and Ruby/GSL library from Ruby/CArray.
6
+
7
+ Author
8
+ ------
9
+
10
+ Hiroki Motoyoshi
@@ -0,0 +1,23 @@
1
+
2
+ Gem::Specification::new do |s|
3
+ version = "1.0.0"
4
+
5
+ files = Dir.glob("**/*") - [
6
+ Dir.glob("carray*.gem"),
7
+ ].flatten
8
+
9
+ s.platform = Gem::Platform::RUBY
10
+ s.name = "carray-gsl"
11
+ s.summary = "Extension for accessing Ruby/GSL with CArray"
12
+ s.description = <<-HERE
13
+ Extension for accessing Ruby/GSL with CArray
14
+ HERE
15
+ s.version = version
16
+ s.author = "Hiroki Motoyoshi"
17
+ s.email = ""
18
+ s.homepage = 'https://github.com/himotoyoshi/carray-gsl'
19
+ s.files = files
20
+ s.extensions = [ "extconf.rb" ]
21
+ s.has_rdoc = false
22
+ s.required_ruby_version = ">= 1.8.1"
23
+ end
data/carray_gsl.c ADDED
@@ -0,0 +1,501 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ carray/carray_gsl.c
4
+
5
+ This file is part of Ruby/CArray extension library.
6
+ You can redistribute it and/or modify it under the terms of
7
+ the GNU General Public License (GPL).
8
+
9
+ Copyright (C) 2005-2008 Hiroki Motoyoshi
10
+
11
+ ---------------------------------------------------------------------------- */
12
+
13
+ #include "carray.h"
14
+ #include <gsl/gsl_vector.h>
15
+ #include <gsl/gsl_matrix.h>
16
+
17
+ static VALUE rb_mGSL;
18
+ static VALUE rb_cVector, rb_cVectorInt, rb_cVectorComplex;
19
+ static VALUE rb_cVectorCol, rb_cVectorIntCol, rb_cVectorComplexCol;
20
+ static VALUE rb_cMatrix, rb_cMatrixInt, rb_cMatrixComplex;
21
+ static VALUE rb_cCAMatrix, rb_cCAVector;
22
+
23
+ static VALUE
24
+ rb_gsl_vector_ca (VALUE self)
25
+ {
26
+ volatile VALUE obj, block;
27
+ gsl_vector *v;
28
+ int data_type;
29
+ int32_t dim[2], dim0;
30
+
31
+ Data_Get_Struct(self, gsl_vector, v);
32
+
33
+ if ( rb_obj_is_kind_of(self, rb_cVectorComplex) ) {
34
+ data_type = CA_CMPLX128;
35
+ }
36
+ else if ( rb_obj_is_kind_of(self, rb_cVectorInt) ) {
37
+ data_type = CA_INT32;
38
+ }
39
+ else if ( rb_obj_is_kind_of(self, rb_cVector) ) {
40
+ data_type = CA_FLOAT64;
41
+ }
42
+ else {
43
+ rb_raise(rb_eRuntimeError, "can't create CArray from GSL::Vector");
44
+ }
45
+
46
+ if ( v->stride > 1 ) {
47
+ int32_t start0, step0, count0;
48
+ if ( rb_obj_is_kind_of(self, rb_cVectorCol) ||
49
+ rb_obj_is_kind_of(self, rb_cVectorIntCol) ||
50
+ rb_obj_is_kind_of(self, rb_cVectorComplexCol) ) {
51
+ dim0 = dim[0] = v->size / ca_sizeof[data_type];
52
+ dim[1] = 1;
53
+ block = rb_carray_wrap_ptr(data_type, 2, dim, 0, NULL,
54
+ (char *) v->data, self);
55
+ }
56
+ else {
57
+ dim0 = dim[0] = v->size / ca_sizeof[data_type];
58
+ block = rb_carray_wrap_ptr(data_type, 1, dim, 0, NULL,
59
+ (char *) v->data, self);
60
+ }
61
+ start0 = 0;
62
+ step0 = v->stride;
63
+ count0 = v->size;
64
+ obj = rb_ca_block_new(block, 1, &dim0, &start0, &step0, &count0, 0);
65
+ }
66
+ else {
67
+ if ( rb_obj_is_kind_of(self, rb_cVectorCol) ||
68
+ rb_obj_is_kind_of(self, rb_cVectorIntCol) ||
69
+ rb_obj_is_kind_of(self, rb_cVectorComplexCol) ) {
70
+ dim[0] = v->size;
71
+ dim[1] = 1;
72
+ obj = rb_carray_wrap_ptr(data_type, 2, dim, 0, NULL,
73
+ (char *) v->data, self);
74
+ }
75
+ else {
76
+ dim[0] = v->size;
77
+ obj = rb_carray_wrap_ptr(data_type, 1, dim, 0, NULL,
78
+ (char *) v->data, self);
79
+ }
80
+ }
81
+
82
+ return obj;
83
+ }
84
+
85
+ static VALUE
86
+ rb_ca_gv_i (VALUE self)
87
+ {
88
+ volatile VALUE klass, obj;
89
+ CArray *ca;
90
+
91
+ Data_Get_Struct(self, CArray, ca);
92
+
93
+ if ( ! ca_is_attached(ca) ) {
94
+ rb_raise(rb_eRuntimeError,
95
+ "can't create GSL vector refers detached array");
96
+ }
97
+
98
+ switch ( ca->data_type ) {
99
+ case CA_INT32: {
100
+ gsl_vector_int *v;
101
+ if ( ( ca->rank == 2 ) && ( ca->dim[1] == 1 ) ) {
102
+ klass = rb_cVectorIntCol;
103
+ }
104
+ else {
105
+ klass = rb_cVectorInt;
106
+ }
107
+ v = ALLOC(gsl_vector_int);
108
+ v->data = (int *) ca_ptr_at_addr(ca, 0);
109
+ v->size = ca->elements;
110
+ v->stride = 1;
111
+ v->block = NULL;
112
+ v->owner = 0;
113
+ obj = Data_Wrap_Struct(klass, 0, gsl_vector_int_free, v);
114
+ break;
115
+ }
116
+ case CA_FLOAT64: {
117
+ gsl_vector *v;
118
+ if ( ( ca->rank == 2 ) && ( ca->dim[1] == 1 ) ) {
119
+ klass = rb_cVectorCol;
120
+ }
121
+ else {
122
+ klass = rb_cVector;
123
+ }
124
+ v = ALLOC(gsl_vector);
125
+ v->data = (double*) ca_ptr_at_addr(ca, 0);
126
+ v->size = ca->elements;
127
+ v->stride = 1;
128
+ v->block = NULL;
129
+ v->owner = 0;
130
+ obj = Data_Wrap_Struct(klass, 0, gsl_vector_free, v);
131
+ break;
132
+ }
133
+ case CA_CMPLX128: {
134
+ gsl_vector_complex *v;
135
+ if ( ( ca->rank == 2 ) && ( ca->dim[1] == 1 ) ) {
136
+ klass = rb_cVectorComplexCol;
137
+ }
138
+ else {
139
+ klass = rb_cVectorComplex;
140
+ }
141
+ v = ALLOC(gsl_vector_complex);
142
+ v->data = (double *) ca_ptr_at_addr(ca, 0);
143
+ v->size = 2*ca->elements;
144
+ v->stride = 1;
145
+ v->block = NULL;
146
+ v->owner = 0;
147
+ obj = Data_Wrap_Struct(klass, 0, gsl_vector_complex_free, v);
148
+ break;
149
+ }
150
+ default:
151
+ rb_raise(rb_eRuntimeError, "invalid data_type");
152
+ }
153
+
154
+ rb_ivar_set(obj, rb_intern("referred_object"), self);
155
+
156
+ return obj;
157
+ }
158
+
159
+ static VALUE
160
+ rb_ca_gv (VALUE self)
161
+ {
162
+ return rb_ca_gv_i(self);
163
+ }
164
+
165
+ static VALUE
166
+ rb_gsl_matrix_ca (VALUE self)
167
+ {
168
+ volatile VALUE obj, block;
169
+ gsl_matrix *v;
170
+ int data_type;
171
+ int32_t dim[2];
172
+
173
+ Data_Get_Struct(self, gsl_matrix, v);
174
+
175
+ if ( rb_obj_is_kind_of(self, rb_cMatrixComplex) ) {
176
+ data_type = CA_CMPLX128;
177
+ }
178
+ else if ( rb_obj_is_kind_of(self, rb_cMatrix) ) {
179
+ data_type = CA_FLOAT64;
180
+ }
181
+ else if ( rb_obj_is_kind_of(self, rb_cMatrixInt) ) {
182
+ data_type = CA_INT32;
183
+ }
184
+ else {
185
+ rb_raise(rb_eRuntimeError, "can't create CArray from GSL::Matrix");
186
+ }
187
+
188
+ if ( v->tda != v->size2 ) {
189
+ int32_t start[2], step[2], count[2];
190
+ dim[0] = v->size1;
191
+ dim[1] = v->tda;
192
+ block = rb_carray_wrap_ptr(data_type, 2, dim, 0, NULL,
193
+ (char *) v->data, self);
194
+ start[0] = 0;
195
+ start[1] = 0;
196
+ step[0] = 1;
197
+ step[1] = 1;
198
+ count[0] = v->size1;
199
+ count[1] = v->size2;
200
+ obj = rb_ca_block_new(block, 2, dim, start, step, count, 0);
201
+ }
202
+ else {
203
+ dim[0] = v->size1;
204
+ dim[1] = v->size2;
205
+ obj = rb_carray_wrap_ptr(data_type, 2, dim, 0, NULL,
206
+ (char *) v->data, self);
207
+ }
208
+
209
+ return obj;
210
+ }
211
+
212
+ static VALUE
213
+ rb_ca_gm_i (VALUE self)
214
+ {
215
+ volatile VALUE klass, obj;
216
+ CArray *ca;
217
+
218
+ Data_Get_Struct(self, CArray, ca);
219
+
220
+ if ( ! ca_is_attached(ca) ) {
221
+ rb_raise(rb_eRuntimeError,
222
+ "can't create GSL matrix for detached array");
223
+ }
224
+
225
+ if ( ca->rank < 2 && ca->dim[0] == 0 ) {
226
+ rb_raise(rb_eRuntimeError, "invalid rank or dim to convert GSL::Matrix");
227
+ }
228
+
229
+ switch ( ca->data_type ) {
230
+ case CA_INT32: {
231
+ gsl_matrix_int *v;
232
+ klass = rb_cMatrixInt;
233
+ v = ALLOC(gsl_matrix_int);
234
+ v->data = (int *) ca_ptr_at_addr(ca, 0);
235
+ v->size1 = ca->dim[0];
236
+ v->size2 = ca->elements/ca->dim[0];
237
+ v->tda = v->size2;
238
+ v->block = NULL;
239
+ v->owner = 0;
240
+ obj = Data_Wrap_Struct(klass, 0, gsl_matrix_int_free, v);
241
+ break;
242
+ }
243
+ case CA_FLOAT64: {
244
+ gsl_matrix *v;
245
+ klass = rb_cMatrix;
246
+ v = ALLOC(gsl_matrix);
247
+ v->data = (double *) ca_ptr_at_addr(ca, 0);
248
+ v->size1 = ca->dim[0];
249
+ v->size2 = ca->elements/ca->dim[0];
250
+ v->tda = v->size2;
251
+ v->block = NULL;
252
+ v->owner = 0;
253
+ obj = Data_Wrap_Struct(klass, 0, gsl_matrix_free, v);
254
+ break;
255
+ }
256
+ case CA_CMPLX128: {
257
+ gsl_matrix_complex *v;
258
+ klass = rb_cMatrixComplex;
259
+ v = ALLOC(gsl_matrix_complex);
260
+ v->data = (double *) ca_ptr_at_addr(ca, 0);
261
+ v->size1 = ca->dim[0];
262
+ v->size2 = 2*ca->elements/ca->dim[0];
263
+ v->tda = v->size2;
264
+ v->block = NULL;
265
+ v->owner = 0;
266
+ obj = Data_Wrap_Struct(klass, 0, gsl_matrix_complex_free, v);
267
+ break;
268
+ }
269
+ default:
270
+ rb_raise(rb_eRuntimeError, "invalid data_type");
271
+ }
272
+
273
+ rb_ivar_set(obj, rb_intern("referred_object"), self);
274
+
275
+ return obj;
276
+ }
277
+
278
+ static VALUE
279
+ rb_ca_gm (VALUE self)
280
+ {
281
+ return rb_ca_gm_i(self);
282
+ }
283
+
284
+ static VALUE
285
+ rb_ca_to_gv (VALUE self)
286
+ {
287
+ volatile VALUE klass, obj;
288
+ CArray *ca;
289
+
290
+ Data_Get_Struct(self, CArray, ca);
291
+
292
+ ca_attach(ca);
293
+
294
+ switch ( ca->data_type ) {
295
+ case CA_INT32: {
296
+ gsl_vector_int *v;
297
+ if ( ( ca->rank == 2 ) && ( ca->dim[1] == 1 ) ) {
298
+ klass = rb_cVectorIntCol;
299
+ }
300
+ else {
301
+ klass = rb_cVectorInt;
302
+ }
303
+ v = gsl_vector_int_alloc(ca->elements);
304
+ memcpy(v->data, ca->ptr, v->size*sizeof(int));
305
+ obj = Data_Wrap_Struct(klass, 0, gsl_vector_int_free, v);
306
+ break;
307
+ }
308
+ case CA_FLOAT64: {
309
+ gsl_vector *v;
310
+ if ( ( ca->rank == 2 ) && ( ca->dim[1] == 1 ) ) {
311
+ klass = rb_cVectorCol;
312
+ }
313
+ else {
314
+ klass = rb_cVector;
315
+ }
316
+ v = gsl_vector_alloc(ca->elements);
317
+ memcpy(v->data, ca->ptr, v->size*sizeof(double));
318
+ obj = Data_Wrap_Struct(klass, 0, gsl_vector_free, v);
319
+ break;
320
+ }
321
+ case CA_CMPLX128: {
322
+ gsl_vector_complex *v;
323
+ if ( ( ca->rank == 2 ) && ( ca->dim[1] == 1 ) ) {
324
+ klass = rb_cVectorComplexCol;
325
+ }
326
+ else {
327
+ klass = rb_cVectorComplex;
328
+ }
329
+ v = gsl_vector_complex_alloc(ca->elements);
330
+ memcpy(v->data, ca->ptr, v->size*sizeof(gsl_complex));
331
+ obj = Data_Wrap_Struct(klass, 0, gsl_vector_complex_free, v);
332
+ break;
333
+ }
334
+ default:
335
+ rb_raise(rb_eRuntimeError, "invalid data_type");
336
+ }
337
+
338
+ ca_detach(ca);
339
+
340
+ return obj;
341
+ }
342
+
343
+ static VALUE
344
+ rb_ca_to_gm (VALUE self)
345
+ {
346
+ volatile VALUE klass, obj;
347
+ CArray *ca;
348
+
349
+ Data_Get_Struct(self, CArray, ca);
350
+
351
+ if ( ca->rank < 2 && ca->dim[0] == 0 ) {
352
+ rb_raise(rb_eRuntimeError, "invalid rank or dim to convert GSL::Matrix");
353
+ }
354
+
355
+ ca_attach(ca);
356
+
357
+ switch ( ca->data_type ) {
358
+ case CA_INT32: {
359
+ gsl_matrix_int *m;
360
+ klass = rb_cMatrixInt;
361
+ m = gsl_matrix_int_alloc(ca->dim[0], ca->elements/ca->dim[0]);
362
+ memcpy(m->data, ca->ptr, m->size1*m->size2*sizeof(int));
363
+ obj = Data_Wrap_Struct(klass, 0, gsl_matrix_int_free, m);
364
+ break;
365
+ }
366
+ case CA_FLOAT64: {
367
+ gsl_matrix *m;
368
+ klass = rb_cMatrix;
369
+ m = gsl_matrix_alloc(ca->dim[0], ca->elements/ca->dim[0]);
370
+ memcpy(m->data, ca->ptr, m->size1*m->size2*sizeof(double));
371
+ obj = Data_Wrap_Struct(klass, 0, gsl_matrix_free, m);
372
+ break;
373
+ }
374
+ case CA_CMPLX128: {
375
+ gsl_matrix_complex *m;
376
+ klass = rb_cMatrixComplex;
377
+ m = gsl_matrix_complex_alloc(ca->dim[0], ca->elements/ca->dim[0]);
378
+ memcpy(m->data, ca->ptr, m->size1*m->size2*sizeof(gsl_complex));
379
+ obj = Data_Wrap_Struct(klass, 0, gsl_matrix_complex_free, m);
380
+ break;
381
+ }
382
+ default:
383
+ rb_raise(rb_eRuntimeError, "invalid data_type");
384
+ }
385
+
386
+ ca_detach(ca);
387
+
388
+ return obj;
389
+ }
390
+
391
+ static VALUE
392
+ rb_ca_m (VALUE self)
393
+ {
394
+ volatile VALUE obj;
395
+ CArray *ca;
396
+ Data_Get_Struct(self, CArray, ca);
397
+ if ( rb_obj_is_kind_of(self, rb_cCAMatrix) ) {
398
+ return self;
399
+ }
400
+ if ( ca->data_type == CA_FIXLEN ) {
401
+ rb_raise(rb_eRuntimeError, "can't create fixlen type CAMatrix");
402
+ }
403
+ if ( ca->rank != 2 ) {
404
+ rb_raise(rb_eRuntimeError, "rank should be 2 for CAMatrix");
405
+ }
406
+ /* super advanced technique
407
+ to fake other array including virtual array as CAWrap object.
408
+ When attach, detach ... are called, the routins for the
409
+ original array are executed.
410
+ For these, CAMatrix should be a subclass of CAWrap. */
411
+ obj = Data_Wrap_Struct(rb_cCAMatrix, NULL, NULL, ca);
412
+ rb_ivar_set(obj, rb_intern("referred_object"), self);
413
+ return obj;
414
+ }
415
+
416
+ static VALUE
417
+ rb_ca_v (VALUE self)
418
+ {
419
+ volatile VALUE obj;
420
+ CArray *ca;
421
+ Data_Get_Struct(self, CArray, ca);
422
+ if ( rb_obj_is_kind_of(self, rb_cCAVector) ) {
423
+ return self;
424
+ }
425
+ if ( ca->data_type == CA_FIXLEN ) {
426
+ rb_raise(rb_eRuntimeError, "can't create fixlen type CAMatrix");
427
+ }
428
+ /* super advanced technique
429
+ to fake other array including virtual array as CAWrap object.
430
+ When attach, detach ... are called, the routins for the
431
+ original array are executed.
432
+ For these, CAVector should be a subclass of CAWrap. */
433
+ if ( ca->rank == 1 ) {
434
+ obj = Data_Wrap_Struct(rb_cCAVector, NULL, NULL, ca);
435
+ }
436
+ else if ( ca->rank == 2 && ( ca->dim[0] == 1 || ca->dim[1] == 1 ) ) {
437
+ obj = Data_Wrap_Struct(rb_cCAVector, NULL, NULL, ca);
438
+ }
439
+ else {
440
+ rb_raise(rb_eRuntimeError, "rank should be 1 for CAVector");
441
+ }
442
+ rb_ivar_set(obj, rb_intern("referred_object"), self);
443
+ return obj;
444
+ }
445
+
446
+ static VALUE
447
+ rb_ca_a (VALUE self)
448
+ {
449
+ if ( rb_obj_is_kind_of(self, rb_cCAMatrix) ||
450
+ rb_obj_is_kind_of(self, rb_cCAVector) ) {
451
+ return rb_ivar_get(self, rb_intern("referred_object"));
452
+ }
453
+ else {
454
+ return self;
455
+ }
456
+ }
457
+
458
+ void Init_carray_mathfunc_gsl ();
459
+
460
+ void
461
+ Init_carray_gsl ()
462
+ {
463
+ rb_mGSL = rb_const_get(rb_cObject, rb_intern("GSL"));
464
+ rb_cVector = rb_const_get(rb_mGSL, rb_intern("Vector"));
465
+ rb_cVectorInt = rb_const_get(rb_cVector, rb_intern("Int"));
466
+ rb_cVectorComplex = rb_const_get(rb_cVector, rb_intern("Complex"));
467
+ rb_cVectorCol = rb_const_get(rb_cVector, rb_intern("Col"));
468
+ rb_cVectorIntCol = rb_const_get(rb_cVectorInt, rb_intern("Col"));
469
+ rb_cVectorComplexCol = rb_const_get(rb_cVectorComplex, rb_intern("Col"));
470
+ rb_cMatrix = rb_const_get(rb_mGSL, rb_intern("Matrix"));
471
+ rb_cMatrixInt = rb_const_get(rb_cMatrix, rb_intern("Int"));
472
+ rb_cMatrixComplex = rb_const_get(rb_cMatrix, rb_intern("Complex"));
473
+
474
+ rb_define_method(rb_cVector, "ca", rb_gsl_vector_ca, 0);
475
+ rb_define_method(rb_cVectorInt, "ca", rb_gsl_vector_ca, 0);
476
+ rb_define_method(rb_cVectorComplex, "ca", rb_gsl_vector_ca, 0);
477
+ rb_define_method(rb_cVectorCol, "ca", rb_gsl_vector_ca, 0);
478
+ rb_define_method(rb_cVectorIntCol, "ca", rb_gsl_vector_ca, 0);
479
+ rb_define_method(rb_cVectorComplexCol, "ca", rb_gsl_vector_ca, 0);
480
+
481
+ rb_define_method(rb_cMatrix, "ca", rb_gsl_matrix_ca, 0);
482
+ rb_define_method(rb_cMatrixInt, "ca", rb_gsl_matrix_ca, 0);
483
+ rb_define_method(rb_cMatrixComplex, "ca", rb_gsl_matrix_ca, 0);
484
+
485
+ rb_define_method(rb_cCArray, "gv", rb_ca_gv, 0);
486
+ rb_define_method(rb_cCArray, "to_gv", rb_ca_to_gv, 0);
487
+
488
+ rb_define_method(rb_cCArray, "gm", rb_ca_gm, 0);
489
+ rb_define_method(rb_cCArray, "to_gm", rb_ca_to_gm, 0);
490
+
491
+ rb_cCAMatrix = rb_define_class("CAMatrix", rb_cCAWrap); /* see rb_ca_m() */
492
+ rb_cCAVector = rb_define_class("CAVector", rb_cCAWrap); /* see rb_ca_v() */
493
+ rb_define_method(rb_cCArray, "m", rb_ca_m, 0);
494
+ rb_define_method(rb_cCArray, "v", rb_ca_v, 0);
495
+ rb_define_method(rb_cCArray, "a", rb_ca_a, 0);
496
+
497
+ Init_carray_mathfunc_gsl();
498
+
499
+ rb_define_const(rb_cCArray, "HAVE_GSL", Qtrue);
500
+ }
501
+