carray-gsl 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+