linalg 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +24 -0
  3. data/ext/g2c_typedefs.h +5 -0
  4. data/ext/lapack/extconf.rb +309 -0
  5. data/ext/lapack/include/BLAS.h +154 -0
  6. data/ext/lapack/include/LAPACK.h +1314 -0
  7. data/ext/lapack/main.c +49 -0
  8. data/ext/lapack/rb_lapack.h +36 -0
  9. data/ext/lapack/rb_lapack_c.c +11614 -0
  10. data/ext/lapack/rb_lapack_d.c +12663 -0
  11. data/ext/lapack/rb_lapack_s.c +12649 -0
  12. data/ext/lapack/rb_lapack_x.c +208 -0
  13. data/ext/lapack/rb_lapack_z.c +11614 -0
  14. data/ext/linalg/dcomplex.c +359 -0
  15. data/ext/linalg/dcomplex.h +40 -0
  16. data/ext/linalg/ddata.c +194 -0
  17. data/ext/linalg/extconf.rb +324 -0
  18. data/ext/linalg/linalg.c +55 -0
  19. data/ext/linalg/linalg.h +21 -0
  20. data/ext/linalg/xdata.c +21 -0
  21. data/ext/linalg/xdata.h +33 -0
  22. data/ext/linalg/xmatrix.c.tmpl +1630 -0
  23. data/ext/linalg/xmatrix.h.tmpl +77 -0
  24. data/ext/linalg/xmatrixc.c.tmpl +138 -0
  25. data/ext/linalg/xmatrixr.c.tmpl +130 -0
  26. data/lib/lapack.rb +87 -0
  27. data/lib/linalg.rb +9 -0
  28. data/lib/linalg/dcomplex.rb +17 -0
  29. data/lib/linalg/dmatrix.rb +29 -0
  30. data/lib/linalg/dmatrix/alias.rb +32 -0
  31. data/lib/linalg/dmatrix/cholesky.rb +52 -0
  32. data/lib/linalg/dmatrix/cond.rb +80 -0
  33. data/lib/linalg/dmatrix/det.rb +36 -0
  34. data/lib/linalg/dmatrix/eigen.rb +153 -0
  35. data/lib/linalg/dmatrix/fit.rb +281 -0
  36. data/lib/linalg/dmatrix/inverse.rb +78 -0
  37. data/lib/linalg/dmatrix/lu.rb +120 -0
  38. data/lib/linalg/dmatrix/main.rb +244 -0
  39. data/lib/linalg/dmatrix/norms.rb +88 -0
  40. data/lib/linalg/dmatrix/nullspace.rb +114 -0
  41. data/lib/linalg/dmatrix/qr.rb +129 -0
  42. data/lib/linalg/dmatrix/schur.rb +88 -0
  43. data/lib/linalg/dmatrix/solve.rb +78 -0
  44. data/lib/linalg/dmatrix/svd.rb +125 -0
  45. data/lib/linalg/exception.rb +32 -0
  46. data/lib/linalg/iterators.rb +221 -0
  47. data/lib/linalg/math.rb +23 -0
  48. data/lib/linalg/scomplex.rb +15 -0
  49. data/lib/linalg/version.rb +3 -0
  50. data/lib/linalg/xdata.rb +123 -0
  51. metadata +94 -0
@@ -0,0 +1,1630 @@
1
+ /*
2
+ * Copyright (c) 2004-2008 by James M. Lawrence
3
+ *
4
+ * See LICENSE
5
+ *
6
+ * Inspired by Rubikitch's +DMatrix+ class in +mathx+.
7
+ *
8
+ */
9
+
10
+ #include "CLASSLOWER.h"
11
+
12
+ /**************************************************
13
+ *
14
+ * globals
15
+ *
16
+ **************************************************/
17
+
18
+ VALUE rb_cCLASSUPPER ;
19
+
20
+ /**************************************************
21
+ *
22
+ * statics
23
+ *
24
+ **************************************************/
25
+
26
+ static integer integer_1 = 1 ;
27
+
28
+ /**************************************************
29
+ **************************************************
30
+ *
31
+ * CLASSUPPER core
32
+ *
33
+ **************************************************
34
+ **************************************************/
35
+
36
+ /**************************************************
37
+ *
38
+ * init
39
+ *
40
+ **************************************************/
41
+
42
+ void CLASSUPPER_init(CLASSUPPER* a, integer vsize, integer hsize)
43
+ {
44
+ a->vsize = vsize ;
45
+ a->hsize = hsize ;
46
+ a->data = (FORTRANTYPE*)ALLOC_N(FORTRANTYPE, vsize*hsize) ;
47
+ }
48
+
49
+ /**************************************************
50
+ *
51
+ * constructors
52
+ *
53
+ **************************************************/
54
+
55
+ CLASSUPPER* CLASSUPPER_new(integer vsize, integer hsize)
56
+ {
57
+ CLASSUPPER* a = (CLASSUPPER*)ALLOC(CLASSUPPER) ;
58
+ a->data = (FORTRANTYPE*)ALLOC_N(FORTRANTYPE, vsize*hsize) ;
59
+ a->vsize = vsize ;
60
+ a->hsize = hsize ;
61
+ return a ;
62
+ }
63
+
64
+ CLASSUPPER* CLASSUPPER_clone(CLASSUPPER* a)
65
+ {
66
+ CLASSUPPER* dup = CLASSUPPER_new(a->vsize, a->hsize) ;
67
+ integer size = a->vsize*a->hsize ;
68
+ xcopy_(&size , a->data, &integer_1, dup->data, &integer_1) ;
69
+ return dup ;
70
+ }
71
+
72
+ /**************************************************
73
+ *
74
+ * destructor
75
+ *
76
+ **************************************************/
77
+
78
+ void CLASSUPPER_free(CLASSUPPER* a)
79
+ {
80
+ free(a->data) ;
81
+ free(a) ;
82
+ }
83
+
84
+ /**************************************************
85
+ *
86
+ * assignment
87
+ *
88
+ **************************************************/
89
+
90
+ CLASSUPPER* CLASSUPPER_assign(CLASSUPPER* c, CLASSUPPER* a)
91
+ {
92
+ integer size = a->vsize*a->hsize ;
93
+
94
+ xcopy_(&size,
95
+ a->data,
96
+ &integer_1,
97
+ c->data,
98
+ &integer_1) ;
99
+
100
+ return c ;
101
+ }
102
+
103
+ CLASSUPPER* CLASSUPPER_swap(CLASSUPPER* c, CLASSUPPER* a)
104
+ {
105
+ CLASSUPPER tmp = *c ;
106
+ *c = *a ;
107
+ *a = tmp ;
108
+ return c ;
109
+ }
110
+
111
+ /**************************************************
112
+ *
113
+ * fillers
114
+ *
115
+ **************************************************/
116
+
117
+ CLASSUPPER* CLASSUPPER_fill(CLASSUPPER* a, FORTRANTYPE value)
118
+ {
119
+ FORTRANTYPE* p = a->data ;
120
+ FORTRANTYPE* end = p + a->vsize*a->hsize ;
121
+
122
+ for( ; p != end ; ++p )
123
+ {
124
+ *p = value ;
125
+ }
126
+
127
+ return a ;
128
+ }
129
+
130
+ CLASSUPPER* CLASSUPPER_scalar_diagonal(CLASSUPPER* c, FORTRANTYPE s)
131
+ {
132
+ integer i ;
133
+
134
+ CLASSUPPER_fill(c, CLASSLOWER_FORTRANTYPE_0) ;
135
+
136
+ for( i = 0 ; i != c->vsize ; ++i )
137
+ {
138
+ c->data[i + i*c->vsize] = s ;
139
+ }
140
+
141
+ return c ;
142
+ }
143
+
144
+ CLASSUPPER* CLASSUPPER_identity(CLASSUPPER* a)
145
+ {
146
+ return CLASSUPPER_scalar_diagonal(a, CLASSLOWER_FORTRANTYPE_1) ;
147
+ }
148
+
149
+ /**************************************************
150
+ *
151
+ * operations
152
+ *
153
+ **************************************************/
154
+
155
+ CLASSUPPER* CLASSUPPER_mul(CLASSUPPER* c, CLASSUPPER* a, CLASSUPPER* b)
156
+ {
157
+ xgemm_("N",
158
+ "N",
159
+ &a->vsize,
160
+ &b->hsize,
161
+ &a->hsize,
162
+ &CLASSLOWER_FORTRANTYPE_1,
163
+ a->data,
164
+ &a->vsize,
165
+ b->data,
166
+ &b->vsize,
167
+ &CLASSLOWER_FORTRANTYPE_0,
168
+ c->data,
169
+ &c->vsize) ;
170
+
171
+ return c ;
172
+ }
173
+
174
+ CLASSUPPER* CLASSUPPER_mul_scalar(CLASSUPPER* a, FORTRANTYPE s)
175
+ {
176
+ integer n = a->vsize*a->hsize ;
177
+
178
+ xscal_(&n,
179
+ &s,
180
+ a->data,
181
+ &integer_1) ;
182
+
183
+ return a ;
184
+ }
185
+
186
+ CLASSUPPER* CLASSUPPER_plus(CLASSUPPER* a, CLASSUPPER* b)
187
+ {
188
+ integer n = a->vsize*a->hsize ;
189
+
190
+ xaxpy_(&n,
191
+ &CLASSLOWER_FORTRANTYPE_1,
192
+ b->data,
193
+ &integer_1,
194
+ a->data,
195
+ &integer_1) ;
196
+
197
+ return a ;
198
+ }
199
+
200
+ CLASSUPPER* CLASSUPPER_minus(CLASSUPPER* a, CLASSUPPER* b)
201
+ {
202
+ integer n = a->vsize*a->hsize ;
203
+
204
+ xaxpy_(&n,
205
+ &CLASSLOWER_FORTRANTYPE_neg_1,
206
+ b->data,
207
+ &integer_1,
208
+ a->data,
209
+ &integer_1) ;
210
+
211
+ return a ;
212
+ }
213
+
214
+ CLASSUPPER* CLASSUPPER_transpose( CLASSUPPER* c, CLASSUPPER* a )
215
+ {
216
+ if( a->vsize > a->hsize )
217
+ {
218
+ int j ;
219
+
220
+ for( j = 0 ; j != a->hsize ; ++j )
221
+ {
222
+ xcopy_(&a->vsize,
223
+ &a->data[j*a->vsize],
224
+ &integer_1,
225
+ &c->data[j],
226
+ &c->vsize) ;
227
+ }
228
+ }
229
+ else
230
+ {
231
+ int i ;
232
+
233
+ for( i = 0 ; i != a->vsize ; ++i )
234
+ {
235
+ xcopy_(&a->hsize,
236
+ &a->data[i],
237
+ &a->vsize,
238
+ &c->data[i*c->vsize],
239
+ &integer_1) ;
240
+ }
241
+ }
242
+
243
+ return c ;
244
+ }
245
+
246
+ CLASSUPPER* CLASSUPPER_transpose_inplace( CLASSUPPER* a )
247
+ {
248
+ if( a->vsize == 1 || a->hsize == 1 )
249
+ {
250
+ integer tmp = a->vsize ;
251
+ a->vsize = a->hsize ;
252
+ a->hsize = tmp ;
253
+ }
254
+ else
255
+ {
256
+ CLASSUPPER* dup = CLASSUPPER_clone(a) ;
257
+
258
+ integer tmp = a->vsize ;
259
+ a->vsize = a->hsize ;
260
+ a->hsize = tmp ;
261
+
262
+ CLASSUPPER_transpose(a, dup) ;
263
+
264
+ CLASSUPPER_free(dup) ;
265
+ }
266
+
267
+ return a ;
268
+ }
269
+
270
+ CLASSUPPER* CLASSUPPER_minor( CLASSUPPER* c,
271
+ CLASSUPPER* a,
272
+ integer minor_i,
273
+ integer minor_j,
274
+ integer minor_vsize,
275
+ integer minor_hsize )
276
+ {
277
+ int j ;
278
+
279
+ for( j = 0 ; j != minor_hsize ; ++j )
280
+ {
281
+ xcopy_(&minor_vsize,
282
+ &a->data[minor_i + (minor_j + j)*a->vsize],
283
+ &integer_1,
284
+ &c->data[j*minor_vsize],
285
+ &integer_1) ;
286
+ }
287
+
288
+ return c ;
289
+ }
290
+
291
+ CLASSUPPER* CLASSUPPER_replace_minor( CLASSUPPER* c,
292
+ integer minor_i,
293
+ integer minor_j,
294
+ CLASSUPPER* a )
295
+ {
296
+ int j ;
297
+
298
+ for( j = 0 ; j != a->hsize ; ++j )
299
+ {
300
+ xcopy_(&a->vsize,
301
+ &a->data[j*a->vsize],
302
+ &integer_1,
303
+ &c->data[minor_i + (minor_j + j)*c->vsize],
304
+ &integer_1) ;
305
+ }
306
+
307
+ return c ;
308
+ }
309
+
310
+ /**************************************************
311
+ **************************************************
312
+ *
313
+ * ruby interface
314
+ *
315
+ **************************************************
316
+ **************************************************/
317
+
318
+ /**************************************************
319
+ *
320
+ * util
321
+ *
322
+ **************************************************/
323
+
324
+ static integer num2size(VALUE val)
325
+ {
326
+ integer n = NUM2INT(val) ;
327
+ if( n < 1 )
328
+ {
329
+ raise_dim_error() ;
330
+ }
331
+ return n ;
332
+ }
333
+
334
+ /**************************************************
335
+ *
336
+ * allocate
337
+ *
338
+ **************************************************/
339
+
340
+ VALUE rb_CLASSLOWER_allocate( VALUE klass )
341
+ {
342
+ CLASSUPPER* a ;
343
+ VALUE obj = Data_Make_Struct(klass,
344
+ CLASSUPPER,
345
+ 0,
346
+ CLASSUPPER_free,
347
+ a) ;
348
+ return obj ;
349
+ }
350
+
351
+ /**************************************************
352
+ *
353
+ * constructors
354
+ *
355
+ **************************************************/
356
+
357
+ /*
358
+ * call-seq: rows(array)
359
+ *
360
+ * Create a matrix using the elements of +array+ as rows.
361
+ *
362
+ * CLASSUPPER.rows(array)
363
+ *
364
+ * is equivalent to
365
+ *
366
+ * CLASSUPPER.new(array.size, array[0].size) { |i,j| array[i][j] }
367
+ *
368
+ * +DimensionError+ is raised if +array+ is not rectangular.
369
+ *
370
+ */
371
+ VALUE rb_CLASSLOWER_s_rows( VALUE klass, VALUE array )
372
+ {
373
+ int i ;
374
+ int j ;
375
+ int vsize ;
376
+ int hsize ;
377
+
378
+ VALUE* ptr ;
379
+ VALUE crow ;
380
+
381
+ CLASSUPPER* a = 0 ;
382
+ VALUE ra ;
383
+
384
+ if( TYPE(array) != T_ARRAY )
385
+ {
386
+ raise_bad_array() ;
387
+ }
388
+
389
+ ptr = RARRAY_PTR(array) ;
390
+ vsize = RARRAY_LEN(array) ;
391
+
392
+ if( vsize < 1 || TYPE(ptr[0]) != T_ARRAY )
393
+ {
394
+ raise_bad_array() ;
395
+ }
396
+ if( (hsize = RARRAY_LEN(ptr[0])) == 0 )
397
+ {
398
+ raise_bad_array() ;
399
+ }
400
+
401
+ a = CLASSUPPER_new(vsize, hsize) ;
402
+ ra = wrap_CLASSLOWER(a) ;
403
+
404
+ for( i = 0 ; i != vsize ; ++i )
405
+ {
406
+ crow = ptr[i] ;
407
+
408
+ if( TYPE(crow) != T_ARRAY )
409
+ {
410
+ raise_bad_array() ;
411
+ }
412
+
413
+ if( RARRAY_LEN(crow) != hsize )
414
+ {
415
+ raise_bad_array() ;
416
+ }
417
+
418
+ for( j = 0 ; j != hsize ; j++ )
419
+ {
420
+ a->data[i + j*a->vsize] = RUBY2FORTRAN(RARRAY_PTR(crow)[j]) ;
421
+ }
422
+ }
423
+
424
+ return ra ;
425
+ }
426
+
427
+ /*
428
+ * call-seq: rand(vsize, hsize)
429
+ *
430
+ * Create a matrix filled with random numbers between -1.0 and 1.0.
431
+ *
432
+ * Similar to
433
+ *
434
+ * CLASSUPPER.new(vsize, hsize) { 2*rand - 1 }
435
+ *
436
+ * except uses <tt>rand()</tt> from <tt>stdlib.h</tt>
437
+ *
438
+ */
439
+ VALUE rb_CLASSLOWER_s_rand(VALUE klass, VALUE rvsize, VALUE rhsize)
440
+ {
441
+ CLASSUPPER* a = CLASSUPPER_new(num2size(rvsize),
442
+ num2size(rhsize)) ;
443
+
444
+ static int first = 1 ;
445
+ if( first )
446
+ {
447
+ srand(time(NULL)) ;
448
+ first = 0 ;
449
+ }
450
+
451
+ CLASSUPPER_rand(a) ;
452
+ return wrap_CLASSLOWER(a) ;
453
+ }
454
+
455
+ /*
456
+ * call-seq: identity(n)
457
+ *
458
+ * Create an +n+ x +n+ identity matrix.
459
+ *
460
+ */
461
+ VALUE rb_CLASSLOWER_s_identity(VALUE klass, VALUE rsize)
462
+ {
463
+ int size = num2size(rsize) ;
464
+ CLASSUPPER* a = CLASSUPPER_new(size, size) ;
465
+ CLASSUPPER_identity(a) ;
466
+ return wrap_CLASSLOWER(a) ;
467
+ }
468
+
469
+ /*
470
+ * call-seq: clone
471
+ *
472
+ * Deep copy
473
+ *
474
+ */
475
+ VALUE rb_CLASSLOWER_clone(VALUE self)
476
+ {
477
+ CLASSUPPER* a ;
478
+ get_CLASSLOWER(a, self) ;
479
+ return wrap_CLASSLOWER(CLASSUPPER_clone(a)) ;
480
+ }
481
+
482
+ /*
483
+ * call-seq:
484
+ * diagonal(array)
485
+ * diagonal(vector)
486
+ * diagonal(n, scalar)
487
+ * diagonal(n) { |i| ... }
488
+ *
489
+ * In the first form, create a diagonal matrix with the elements of
490
+ * +array+ along the diagonal. The second form is like the first but
491
+ * using elements of the column vector +vector+. In the third form,
492
+ * create an +n+ x +n+ diagonal matrix with diagonal elements of value
493
+ * +scalar+. In the fourth form, each element <tt>m[i,i]</tt> gets
494
+ * the block result.
495
+ *
496
+ */
497
+ VALUE rb_CLASSLOWER_s_diagonal(int argc, VALUE* argv, VALUE klass)
498
+ {
499
+ CLASSUPPER* a ;
500
+ VALUE ra ;
501
+ VALUE rb ;
502
+ VALUE rscalar ;
503
+ int scan = rb_scan_args(argc, argv, "11", &rb, &rscalar) ;
504
+
505
+ if( scan == 1 )
506
+ {
507
+ if( rb_block_given_p() )
508
+ {
509
+ int i ;
510
+ int size = num2size(rb) ;
511
+ a = CLASSUPPER_new(size, size) ;
512
+ ra = wrap_CLASSLOWER(a) ;
513
+
514
+ VALUE result ;
515
+
516
+ CLASSUPPER_fill(a, CLASSLOWER_FORTRANTYPE_0) ;
517
+
518
+ for( i = 0 ; i != size ; ++i )
519
+ {
520
+ result = rb_yield(INT2FIX(i)) ;
521
+ a->data[i + i*a->vsize] = RUBY2FORTRAN(result) ;
522
+ }
523
+ }
524
+ else if( rb_obj_is_kind_of(rb, rb_cCLASSUPPER) )
525
+ {
526
+ int i ;
527
+ CLASSUPPER* b ;
528
+
529
+ get_CLASSLOWER(b, rb) ;
530
+
531
+ if( b->hsize != 1 )
532
+ {
533
+ raise_dim_error() ;
534
+ }
535
+
536
+ a = CLASSUPPER_new(b->vsize, b->vsize) ;
537
+ ra = wrap_CLASSLOWER(a) ;
538
+
539
+ CLASSUPPER_fill(a, CLASSLOWER_FORTRANTYPE_0) ;
540
+
541
+ for( i = 0 ; i != b->vsize ; ++i )
542
+ {
543
+ a->data[i + i*a->vsize] = b->data[i] ;
544
+ }
545
+ }
546
+ else if( TYPE(rb) == T_ARRAY )
547
+ {
548
+ VALUE* c_arr ;
549
+ long size ;
550
+ int i ;
551
+
552
+ c_arr = RARRAY_PTR(rb) ;
553
+ size = RARRAY_LEN(rb) ;
554
+
555
+ if( size < 1 )
556
+ {
557
+ raise_dim_error() ;
558
+ }
559
+
560
+ a = CLASSUPPER_new(size, size) ;
561
+ ra = wrap_CLASSLOWER(a) ;
562
+
563
+ CLASSUPPER_fill(a, CLASSLOWER_FORTRANTYPE_0) ;
564
+
565
+ for( i = 0 ; i != size ; ++i )
566
+ {
567
+ a->data[i + i*a->vsize] = RUBY2FORTRAN(c_arr[i]) ;
568
+ }
569
+ }
570
+ else
571
+ {
572
+ rb_raise(rb_eRuntimeError, "not a vector or array") ;
573
+ }
574
+ }
575
+ else
576
+ {
577
+ int size = num2size(rb) ;
578
+ a = CLASSUPPER_new(size, size) ;
579
+ ra = wrap_CLASSLOWER(a) ;
580
+ CLASSUPPER_scalar_diagonal(a, RUBY2FORTRAN(rscalar)) ;
581
+ }
582
+
583
+ return ra ;
584
+ }
585
+
586
+ /*
587
+ * :nodoc:
588
+ */
589
+ VALUE rb_CLASSLOWER_reserve(VALUE klass, VALUE rvsize, VALUE rhsize)/* :nodoc: */
590
+ {
591
+ integer vsize = num2size(rvsize) ;
592
+ integer hsize = num2size(rhsize) ;
593
+ return wrap_CLASSLOWER(CLASSUPPER_new(vsize, hsize)) ;
594
+ }
595
+
596
+ /**************************************************
597
+ *
598
+ * instance methods
599
+ *
600
+ **************************************************/
601
+
602
+ /*
603
+ * call-seq:
604
+ * new(vsize, hsize)
605
+ * new(vsize, hsize, scalar)
606
+ * new(vsize, hsize) { |i, j| ... }
607
+ *
608
+ * Returns a new matrix with dimensions [+vsize+, +hsize+].
609
+ *
610
+ * In the first form, the matrix is filled with zero. In the second
611
+ * form, the matrix is filled with +scalar+. In the third form, each
612
+ * index pair is passed to the block and the respective matrix element
613
+ * is assigned the block result.
614
+ *
615
+ * CLASSUPPER.new(4,4) { |i,j| i == j ? 1 : 0 }
616
+ *
617
+ * is the 4 x 4 identity matrix.
618
+ *
619
+ */
620
+ VALUE rb_CLASSLOWER_initialize(int argc, VALUE* argv, VALUE self)
621
+ {
622
+ CLASSUPPER* a ;
623
+ VALUE rvsize ;
624
+ VALUE rhsize ;
625
+ VALUE rscalar ;
626
+
627
+ int scan = rb_scan_args(argc, argv, "21", &rvsize, &rhsize, &rscalar) ;
628
+
629
+ get_CLASSLOWER(a, self) ;
630
+ CLASSUPPER_init(a, num2size(rvsize), num2size(rhsize)) ;
631
+
632
+ if( scan == 3 )
633
+ {
634
+ CLASSUPPER_fill(a, RUBY2FORTRAN(rscalar)) ;
635
+ }
636
+ else if( rb_block_given_p() == Qtrue )
637
+ {
638
+ int i ;
639
+ int j ;
640
+
641
+ for( j = 0 ; j != a->hsize ; ++j )
642
+ {
643
+ for( i = 0 ; i != a->vsize ; ++i )
644
+ {
645
+ VALUE pair = rb_assoc_new(INT2FIX(i),
646
+ INT2FIX(j)) ;
647
+ a->data[i + j*a->vsize] = RUBY2FORTRAN(rb_yield(pair)) ;
648
+ }
649
+ }
650
+ }
651
+ else
652
+ {
653
+ CLASSUPPER_fill(a, CLASSLOWER_FORTRANTYPE_0) ;
654
+ }
655
+
656
+ return self ;
657
+ }
658
+
659
+ /*
660
+ * call-seq: fill(value)
661
+ *
662
+ * Fill the matrix with +value+.
663
+ */
664
+ VALUE rb_CLASSLOWER_fill(VALUE self, VALUE rval)
665
+ {
666
+ FORTRANTYPE val = RUBY2FORTRAN(rval) ;
667
+ CLASSUPPER* a ;
668
+ get_CLASSLOWER(a, self) ;
669
+ CLASSUPPER_fill(a, val) ;
670
+ return self ;
671
+ }
672
+
673
+ /*
674
+ * call-seq: vsize
675
+ *
676
+ * Vertical size of the matrix (number of rows)
677
+ *
678
+ */
679
+ VALUE rb_CLASSLOWER_vsize(VALUE self)
680
+ {
681
+ CLASSUPPER* a ;
682
+ get_CLASSLOWER(a, self) ;
683
+ return INT2FIX(a->vsize) ;
684
+ }
685
+
686
+ /*
687
+ *
688
+ * call-seq: hsize
689
+ *
690
+ * Horizontal size of the matrix (number of columns)
691
+ *
692
+ */
693
+ VALUE rb_CLASSLOWER_hsize(VALUE self)
694
+ {
695
+ CLASSUPPER* a ;
696
+ get_CLASSLOWER(a, self) ;
697
+ return INT2FIX(a->hsize) ;
698
+ }
699
+
700
+ /*
701
+ * call-seq: dimensions
702
+ *
703
+ * Returns the pair
704
+ *
705
+ * [a.vsize, a.hsize]
706
+ *
707
+ */
708
+ VALUE rb_CLASSLOWER_dimensions(VALUE self)
709
+ {
710
+ CLASSUPPER* a ;
711
+ get_CLASSLOWER(a, self) ;
712
+ return rb_assoc_new(INT2FIX(a->vsize),
713
+ INT2FIX(a->hsize)) ;
714
+ }
715
+
716
+ /*
717
+ *
718
+ * call-seq: [](row, column)
719
+ *
720
+ * Element read. Column vectors are permitted to omit the +column+ index.
721
+ *
722
+ */
723
+ VALUE rb_CLASSLOWER_bracket_get(int argc, VALUE* argv, VALUE self)
724
+ {
725
+ VALUE ri ;
726
+ VALUE rj ;
727
+ int i = 0 ;
728
+ int j = 0 ;
729
+ CLASSUPPER* a ;
730
+ get_CLASSLOWER(a, self) ;
731
+
732
+ if( rb_scan_args(argc, argv, "11", &ri, &rj) == 1 )
733
+ {
734
+ if( a->hsize == 1 )
735
+ {
736
+ i = NUM2INT(ri) ;
737
+ j = 0 ;
738
+ }
739
+ else
740
+ {
741
+ rb_raise(rb_eArgError, "") ;
742
+ }
743
+ }
744
+ else
745
+ {
746
+ i = NUM2INT(ri) ;
747
+ j = NUM2INT(rj) ;
748
+ }
749
+
750
+ if( i < 0 || i >= a->vsize ||
751
+ j < 0 || j >= a->hsize )
752
+ {
753
+ raise_index_error() ;
754
+ }
755
+
756
+ return FORTRAN2RUBY(a->data[i + j*a->vsize]) ;
757
+ }
758
+
759
+ /*
760
+ *
761
+ * call-seq: []=(row, column)
762
+ *
763
+ * Element write. Column vectors are permitted to omit the +column+ index.
764
+ *
765
+ */
766
+ VALUE rb_CLASSLOWER_bracket_set(int argc, VALUE* argv, VALUE self)
767
+ {
768
+ CLASSUPPER* a ;
769
+ int i = 0 ;
770
+ int j = 0 ;
771
+ VALUE ri ;
772
+ VALUE rj ;
773
+ VALUE rv ;
774
+
775
+ get_CLASSLOWER(a, self) ;
776
+
777
+ if( rb_scan_args(argc, argv, "21", &ri, &rj, &rv) == 2 )
778
+ {
779
+ rv = rj ;
780
+
781
+ if( a->hsize == 1 )
782
+ {
783
+ i = NUM2INT(ri) ;
784
+ j = 0 ;
785
+ }
786
+ else
787
+ {
788
+ raise_index_error() ;
789
+ }
790
+ }
791
+ else
792
+ {
793
+ i = NUM2INT(ri) ;
794
+ j = NUM2INT(rj) ;
795
+ }
796
+
797
+ if( i < 0 || i >= a->vsize ||
798
+ j < 0 || j >= a->hsize )
799
+ {
800
+ raise_index_error() ;
801
+ }
802
+
803
+ a->data[i + j*a->vsize] = RUBY2FORTRAN(rv) ;
804
+ return rv ;
805
+ }
806
+
807
+ /*
808
+ * call-seq: *(b)
809
+ *
810
+ * Matrix multiply
811
+ *
812
+ * c = a * b
813
+ *
814
+ * +DimensionError+ is raised unless
815
+ *
816
+ * a.hsize == b.vsize
817
+ *
818
+ */
819
+ VALUE rb_CLASSLOWER_mul(VALUE self, VALUE rb)
820
+ {
821
+ CLASSUPPER* a ;
822
+ get_CLASSLOWER(a, self) ;
823
+
824
+ if( rb_obj_is_kind_of(rb, rb_cCLASSUPPER) )
825
+ {
826
+ CLASSUPPER* b ;
827
+ CLASSUPPER* c ;
828
+
829
+ get_CLASSLOWER(b, rb) ;
830
+
831
+ if( a->hsize != b->vsize )
832
+ {
833
+ raise_dim_error() ;
834
+ }
835
+
836
+ c = CLASSUPPER_new(a->vsize, b->hsize) ;
837
+ CLASSUPPER_mul(c, a, b) ;
838
+ return wrap_CLASSLOWER(c) ;
839
+ }
840
+ else
841
+ {
842
+ CLASSUPPER* c = CLASSUPPER_clone(a) ;
843
+ CLASSUPPER_mul_scalar(c, RUBY2FORTRAN(rb)) ;
844
+ return wrap_CLASSLOWER(c) ;
845
+ }
846
+ }
847
+
848
+ /*
849
+ * call-seq: postmul!(b)
850
+ *
851
+ * In-place multiply
852
+ *
853
+ * c = a * b
854
+ *
855
+ * is equivalent to
856
+ *
857
+ * c = a.postmul!(b)
858
+ *
859
+ * with
860
+ *
861
+ * a.object_id == c.object_id
862
+ *
863
+ * Note this implies +b+ must be square. +DimensionError+ is raised
864
+ * otherwise.
865
+ *
866
+ */
867
+ VALUE rb_CLASSLOWER_postmul_inplace(VALUE self, VALUE rb)
868
+ {
869
+ CLASSUPPER* a ;
870
+ get_CLASSLOWER(a, self) ;
871
+
872
+ if( rb_obj_is_kind_of(rb, rb_cCLASSUPPER) )
873
+ {
874
+ CLASSUPPER* b ;
875
+ CLASSUPPER* c ;
876
+
877
+ get_CLASSLOWER(b, rb) ;
878
+
879
+ if( a->hsize != b->vsize ||
880
+ b->vsize != b->hsize )
881
+ {
882
+ raise_dim_error() ;
883
+ }
884
+
885
+ c = CLASSUPPER_new(a->vsize, b->hsize) ;
886
+ CLASSUPPER_mul(c, a, b) ;
887
+ CLASSUPPER_swap(a, c) ;
888
+ CLASSUPPER_free(c) ;
889
+ }
890
+ else
891
+ {
892
+ CLASSUPPER_mul_scalar(a, RUBY2FORTRAN(rb)) ;
893
+ }
894
+
895
+ return self ;
896
+ }
897
+
898
+ /*
899
+ * call-seq: premul!(a)
900
+ *
901
+ * In-place multiply
902
+ *
903
+ * c = a * b
904
+ *
905
+ * is equivalent to
906
+ *
907
+ * c = b.premul!(a)
908
+ *
909
+ * with
910
+ *
911
+ * b.object_id == c.object_id
912
+ *
913
+ * Note this implies +a+ must be square. +DimensionError+ is raised
914
+ * otherwise.
915
+ *
916
+ */
917
+ VALUE rb_CLASSLOWER_premul_inplace(VALUE self, VALUE ra)
918
+ {
919
+ CLASSUPPER* b ;
920
+ get_CLASSLOWER(b, self) ;
921
+
922
+ if( rb_obj_is_kind_of(ra, rb_cCLASSUPPER) )
923
+ {
924
+ CLASSUPPER* a ;
925
+ CLASSUPPER* c ;
926
+
927
+ get_CLASSLOWER(a, ra) ;
928
+
929
+ if( a->hsize != b->vsize ||
930
+ a->vsize != a->hsize )
931
+ {
932
+ raise_dim_error() ;
933
+ }
934
+
935
+ c = CLASSUPPER_new(a->vsize, b->hsize) ;
936
+ CLASSUPPER_mul(c, a, b) ;
937
+ CLASSUPPER_swap(b, c) ;
938
+ CLASSUPPER_free(c) ;
939
+ }
940
+ else
941
+ {
942
+ CLASSUPPER_mul_scalar(b, RUBY2FORTRAN(ra)) ;
943
+ }
944
+
945
+ return self ;
946
+ }
947
+
948
+ /*
949
+ * call-seq: dot(b)
950
+ *
951
+ * Column vector dot product
952
+ *
953
+ * a.dot(b)
954
+ *
955
+ * +DimensionError+ is raised unless
956
+ *
957
+ * a.hsize == b.hsize and
958
+ * b.hsize == 1 and
959
+ * a.vsize == b.vsize
960
+ *
961
+ */
962
+ VALUE rb_CLASSLOWER_dot(VALUE self, VALUE rb)
963
+ {
964
+ CLASSUPPER* a ;
965
+ CLASSUPPER* b ;
966
+
967
+ get_CLASSLOWER(a, self) ;
968
+ get_CLASSLOWER(b, rb) ;
969
+
970
+ if( a->hsize != 1 ||
971
+ b->hsize != 1 ||
972
+ a->vsize != b->vsize )
973
+ {
974
+ raise_dim_error() ;
975
+ }
976
+
977
+ return FORTRAN2RUBY(CLASSUPPER_dot(a, b)) ;
978
+ }
979
+
980
+ /*
981
+ * call-seq: plus!(b)
982
+ *
983
+ * In-place matrix addition.
984
+ *
985
+ * a.object_id == a.plus!(b).object_id
986
+ *
987
+ */
988
+ VALUE rb_CLASSLOWER_plus_inplace(VALUE self, VALUE rb)
989
+ {
990
+ CLASSUPPER* a ;
991
+ CLASSUPPER* b ;
992
+ get_CLASSLOWER(a, self) ;
993
+ get_CLASSLOWER(b, rb) ;
994
+
995
+ if( a->vsize != b->vsize ||
996
+ a->hsize != b->hsize)
997
+ {
998
+ raise_dim_error() ;
999
+ }
1000
+
1001
+ CLASSUPPER_plus(a, b) ;
1002
+ return self ;
1003
+ }
1004
+
1005
+ /*
1006
+ * call-seq: +(b)
1007
+ *
1008
+ * Matrix addition.
1009
+ *
1010
+ * a + b
1011
+ *
1012
+ * +DimensionError+ is raised unless
1013
+ *
1014
+ * a.dimensions == b.dimensions
1015
+ *
1016
+ */
1017
+ VALUE rb_CLASSLOWER_plus(VALUE self, VALUE ra)
1018
+ {
1019
+ return rb_CLASSLOWER_plus_inplace(rb_CLASSLOWER_clone(self),ra) ;
1020
+ }
1021
+
1022
+ /*
1023
+ * call-seq: minus!(b)
1024
+ *
1025
+ * In-place matrix subtraction.
1026
+ *
1027
+ * c = a - b
1028
+ *
1029
+ * is equivalent to
1030
+ *
1031
+ * c = a.minus!(b)
1032
+ *
1033
+ * with
1034
+ *
1035
+ * a.object_id == c.object_id
1036
+ *
1037
+ */
1038
+ VALUE rb_CLASSLOWER_minus_inplace(VALUE self, VALUE rb)
1039
+ {
1040
+ CLASSUPPER* a ;
1041
+ CLASSUPPER* b ;
1042
+ get_CLASSLOWER(a, self) ;
1043
+ get_CLASSLOWER(b, rb) ;
1044
+
1045
+ if( a->vsize != b->vsize ||
1046
+ a->hsize != b->hsize)
1047
+ {
1048
+ raise_dim_error() ;
1049
+ }
1050
+
1051
+ CLASSUPPER_minus(a, b) ;
1052
+ return self ;
1053
+ }
1054
+
1055
+ /*
1056
+ * call-seq: -(b)
1057
+ *
1058
+ * Matrix subtraction
1059
+ *
1060
+ * a - b
1061
+ *
1062
+ * +DimensionError+ is raised unless
1063
+ *
1064
+ * a.dimensions == b.dimensions
1065
+ *
1066
+ */
1067
+ VALUE rb_CLASSLOWER_minus(VALUE self, VALUE rb)
1068
+ {
1069
+ return rb_CLASSLOWER_minus_inplace(rb_CLASSLOWER_clone(self),rb) ;
1070
+ }
1071
+
1072
+ /*
1073
+ * call-seq: negate!
1074
+ *
1075
+ * In-place unary minus.
1076
+ *
1077
+ */
1078
+ VALUE rb_CLASSLOWER_unary_minus_inplace(VALUE self)
1079
+ {
1080
+ CLASSUPPER* a ;
1081
+ get_CLASSLOWER(a, self) ;
1082
+ CLASSUPPER_mul_scalar(a, CLASSLOWER_FORTRANTYPE_neg_1) ;
1083
+ return self ;
1084
+ }
1085
+
1086
+ /*
1087
+ * call-seq: -@
1088
+ *
1089
+ * Unary minus
1090
+ *
1091
+ */
1092
+ VALUE rb_CLASSLOWER_unary_minus(VALUE self)
1093
+ {
1094
+ return rb_CLASSLOWER_unary_minus_inplace(rb_CLASSLOWER_clone(self)) ;
1095
+ }
1096
+
1097
+ /*
1098
+ * call-seq: +@
1099
+ *
1100
+ * Unary plus. Does nothing.
1101
+ *
1102
+ */
1103
+ VALUE rb_CLASSLOWER_unary_plus(VALUE self)
1104
+ {
1105
+ return self ;
1106
+ }
1107
+
1108
+ /*
1109
+ * call-seq: to_a
1110
+ *
1111
+ * Create an array from the matrix
1112
+ *
1113
+ * a = m.to_a
1114
+ *
1115
+ * is equivalent to
1116
+ *
1117
+ * a = Array.new(m.vsize) { Array.new(m.hsize) }
1118
+ * m.each_index { |i,j|
1119
+ * a[i][j] = m[i,j]
1120
+ * }
1121
+ *
1122
+ */
1123
+ VALUE rb_CLASSLOWER_to_a(VALUE self)
1124
+ {
1125
+ int i ;
1126
+ int j ;
1127
+ VALUE arr ;
1128
+ VALUE row ;
1129
+ CLASSUPPER* a ;
1130
+ get_CLASSLOWER(a, self) ;
1131
+
1132
+ arr = rb_ary_new2(a->vsize) ;
1133
+
1134
+ for( i = 0 ; i != a->vsize ; ++i )
1135
+ {
1136
+ row = rb_ary_new2(a->hsize) ;
1137
+
1138
+ for( j = 0 ; j != a->hsize ; ++j )
1139
+ {
1140
+ rb_ary_store(row,
1141
+ j,
1142
+ FORTRAN2RUBY(a->data[i + j*a->vsize])) ;
1143
+ }
1144
+
1145
+ rb_ary_store(arr, i, row) ;
1146
+ }
1147
+
1148
+ return arr ;
1149
+ }
1150
+
1151
+ /*
1152
+ * call-seq: transpose
1153
+ *
1154
+ * Matrix transpose
1155
+ *
1156
+ */
1157
+ VALUE rb_CLASSLOWER_transpose(VALUE self)
1158
+ {
1159
+ CLASSUPPER* a ;
1160
+ CLASSUPPER* trans ;
1161
+ get_CLASSLOWER(a, self) ;
1162
+ trans = CLASSUPPER_new(a->hsize, a->vsize) ;
1163
+ CLASSUPPER_transpose(trans, a) ;
1164
+ return wrap_CLASSLOWER(trans) ;
1165
+ }
1166
+
1167
+ /*
1168
+ * call-seq: transpose!
1169
+ *
1170
+ * In-place matrix transpose. Guaranteed O(1) trivial cost for column
1171
+ * and row vectors. Note that transpose flags are not implemented;
1172
+ * thus for non-vectors the cost is a temporary copy and assignment.
1173
+ *
1174
+ */
1175
+ VALUE rb_CLASSLOWER_transpose_inplace( VALUE self )
1176
+ {
1177
+ CLASSUPPER* a ;
1178
+ get_CLASSLOWER(a, self) ;
1179
+ CLASSUPPER_transpose_inplace(a) ;
1180
+ return self ;
1181
+ }
1182
+
1183
+ static CLASSUPPER* CLASSLOWER_minor( CLASSUPPER* a,
1184
+ integer i,
1185
+ integer j,
1186
+ integer vsize,
1187
+ integer hsize )
1188
+ {
1189
+ CLASSUPPER* c ;
1190
+
1191
+ if( i < 0 || i + vsize - 1 >= a->vsize ||
1192
+ j < 0 || j + hsize - 1 >= a->hsize )
1193
+ {
1194
+ raise_index_error() ;
1195
+ }
1196
+
1197
+ c = CLASSUPPER_new(vsize, hsize) ;
1198
+ CLASSUPPER_minor(c, a, i, j, vsize, hsize) ;
1199
+ return c ;
1200
+ }
1201
+
1202
+ static void CLASSLOWER_replace_minor( CLASSUPPER* c,
1203
+ integer i,
1204
+ integer j,
1205
+ CLASSUPPER* a )
1206
+ {
1207
+ if( i < 0 || i + a->vsize - 1 >= c->vsize ||
1208
+ j < 0 || j + a->hsize - 1 >= c->hsize )
1209
+ {
1210
+ raise_index_error() ;
1211
+ }
1212
+
1213
+ CLASSUPPER_replace_minor(c, i, j, a) ;
1214
+ }
1215
+
1216
+ /*
1217
+ * call-seq: minor(i, j, vsize, hsize)
1218
+ *
1219
+ * Return the minor with upper-left position <tt>[i, j]</tt> and
1220
+ * dimensions <tt>[vsize, hsize]</tt>.
1221
+ *
1222
+ */
1223
+ VALUE rb_CLASSLOWER_minor( VALUE self,
1224
+ VALUE ri,
1225
+ VALUE rj,
1226
+ VALUE rvsize,
1227
+ VALUE rhsize )
1228
+ {
1229
+ CLASSUPPER* a ;
1230
+ integer i = (integer)NUM2INT(ri) ;
1231
+ integer j = (integer)NUM2INT(rj) ;
1232
+ integer vsize = (integer)num2size(rvsize) ;
1233
+ integer hsize = (integer)num2size(rhsize) ;
1234
+ get_CLASSLOWER(a, self) ;
1235
+ return wrap_CLASSLOWER(CLASSLOWER_minor(a, i, j, vsize, hsize)) ;
1236
+ }
1237
+
1238
+ /*
1239
+ * call-seq: replace_minor(i, j, minor)
1240
+ *
1241
+ * Insert +minor+ into the matrix, where [+i+,+j+] is the location of
1242
+ * the upper-left corner of the minor.
1243
+ *
1244
+ */
1245
+ VALUE rb_CLASSLOWER_replace_minor( VALUE self,
1246
+ VALUE ri,
1247
+ VALUE rj,
1248
+ VALUE rminor )
1249
+ {
1250
+ CLASSUPPER* c ;
1251
+ CLASSUPPER* a ;
1252
+ integer i = (integer)NUM2INT(ri) ;
1253
+ integer j = (integer)NUM2INT(rj) ;
1254
+
1255
+ get_CLASSLOWER(c, self) ;
1256
+ get_CLASSLOWER(a, rminor) ;
1257
+
1258
+ CLASSLOWER_replace_minor(c, i, j, a) ;
1259
+ return self ;
1260
+ }
1261
+
1262
+
1263
+ /*
1264
+ * call-seq: column(j)
1265
+ *
1266
+ * Returns the +j+-th column of the matrix.
1267
+ *
1268
+ */
1269
+ VALUE rb_CLASSLOWER_column( VALUE self, VALUE rj )
1270
+ {
1271
+ CLASSUPPER* c ;
1272
+ integer j = (integer)NUM2INT(rj) ;
1273
+ get_CLASSLOWER(c, self) ;
1274
+ return wrap_CLASSLOWER(CLASSLOWER_minor(c, 0, j, c->vsize, 1)) ;
1275
+ }
1276
+
1277
+ /*
1278
+ * call-seq: row(i)
1279
+ *
1280
+ * Returns the +i+-th row of the matrix.
1281
+ *
1282
+ */
1283
+ VALUE rb_CLASSLOWER_row( VALUE self, VALUE ri )
1284
+ {
1285
+ CLASSUPPER* a ;
1286
+ integer i = (integer)NUM2INT(ri) ;
1287
+ get_CLASSLOWER(a, self) ;
1288
+ return wrap_CLASSLOWER(CLASSLOWER_minor(a, i, 0, 1, a->hsize)) ;
1289
+ }
1290
+
1291
+ /*
1292
+ * call-seq: replace_column(j, v)
1293
+ *
1294
+ * replace the +j+-th column with the column vector +v+.
1295
+ *
1296
+ */
1297
+ VALUE rb_CLASSLOWER_replace_column( VALUE self, VALUE rj, VALUE rv )
1298
+ {
1299
+ CLASSUPPER* a ;
1300
+ integer j = (integer)NUM2INT(rj) ;
1301
+ CLASSUPPER* v ;
1302
+
1303
+ get_CLASSLOWER(a, self) ;
1304
+ get_CLASSLOWER(v, rv) ;
1305
+
1306
+ if( v->hsize != 1 ||
1307
+ v->vsize != a->vsize )
1308
+ {
1309
+ raise_dim_error() ;
1310
+ }
1311
+
1312
+ CLASSLOWER_replace_minor(a, 0, j, v) ;
1313
+ return self ;
1314
+ }
1315
+
1316
+ /*
1317
+ * call-seq: replace_row(i, v)
1318
+ *
1319
+ * replace the +i+-th row with the row vector +v+.
1320
+ *
1321
+ */
1322
+ VALUE rb_CLASSLOWER_replace_row( VALUE self, VALUE ri, VALUE rv )
1323
+ {
1324
+ CLASSUPPER* a ;
1325
+ integer i = (integer)NUM2INT(ri) ;
1326
+ CLASSUPPER* v ;
1327
+
1328
+ get_CLASSLOWER(a, self) ;
1329
+ get_CLASSLOWER(v, rv) ;
1330
+
1331
+ if( v->vsize != 1 ||
1332
+ v->hsize != a->hsize )
1333
+ {
1334
+ raise_dim_error() ;
1335
+ }
1336
+
1337
+ CLASSLOWER_replace_minor(a, i, 0, v) ;
1338
+ return self ;
1339
+ }
1340
+
1341
+ /*
1342
+ * call-seq: to_FORTRANTYPE_ptr
1343
+ *
1344
+ * Actual pointer value of the matrix data. Subject to change after a
1345
+ * bang (!) operation. This is called by the +Lapack+ module.
1346
+ *
1347
+ */
1348
+ VALUE rb_CLASSLOWER_to_FORTRANTYPE_ptr(VALUE self)
1349
+ {
1350
+ CLASSUPPER* a ;
1351
+ get_CLASSLOWER(a, self) ;
1352
+ return LONG2NUM((long)a->data) ;
1353
+ }
1354
+
1355
+ /*
1356
+ * call-seq: coerce(other)
1357
+ *
1358
+ * Internal call from Numeric#coerce.
1359
+ *
1360
+ */
1361
+ VALUE rb_CLASSLOWER_coerce(VALUE self, VALUE other)
1362
+ {
1363
+ return rb_assoc_new(self, other) ;
1364
+ }
1365
+
1366
+ /*
1367
+ * call-seq:
1368
+ * symmetric!
1369
+ *
1370
+ * Force the matrix to be symmetric, reflecting the upper triangle
1371
+ * onto the lower triangle.
1372
+ *
1373
+ */
1374
+ VALUE rb_CLASSLOWER_make_symmetric( VALUE self )
1375
+ {
1376
+ CLASSUPPER* a ;
1377
+ get_CLASSLOWER(a, self) ;
1378
+
1379
+ if( a->vsize != a->hsize )
1380
+ {
1381
+ raise_dim_error() ;
1382
+ }
1383
+
1384
+ {
1385
+ int i ;
1386
+ int j ;
1387
+
1388
+ for( j = 0 ; j < a->hsize ; ++j )
1389
+ {
1390
+ for( i = j + 1 ; i < a->vsize ; ++i )
1391
+ {
1392
+ a->data[i + j*a->vsize] = a->data[j + i*a->vsize] ;
1393
+ }
1394
+ }
1395
+ }
1396
+
1397
+ return self ;
1398
+ }
1399
+
1400
+ /*
1401
+ * call-seq: _dump
1402
+ *
1403
+ * For Marshal. Uses native data format.
1404
+ *
1405
+ */
1406
+ VALUE rb_CLASSLOWER_marshal_dump(VALUE self, VALUE depth)
1407
+ {
1408
+ /*
1409
+ * format:
1410
+ * sizeof(integer) vsize
1411
+ * sizeof(integer) hsize
1412
+ * 40*sizeof(char) reserved
1413
+ * vsize*hsize*sizeof(FORTRANTYPE) data
1414
+ */
1415
+
1416
+ CLASSUPPER* a ;
1417
+ VALUE str ;
1418
+ char reserved[40] = { 0 } ;
1419
+
1420
+ get_CLASSLOWER(a, self) ;
1421
+
1422
+ str = rb_str_buf_new(1*sizeof(integer) +
1423
+ 1*sizeof(integer) +
1424
+ 40*sizeof(char) +
1425
+ a->vsize*a->hsize*sizeof(FORTRANTYPE)) ;
1426
+
1427
+ rb_str_buf_cat(str, (const char*)(&a->vsize), 1*sizeof(integer)) ;
1428
+ rb_str_buf_cat(str, (const char*)(&a->hsize), 1*sizeof(integer)) ;
1429
+ rb_str_buf_cat(str, (const char*)(reserved), 40*sizeof(char)) ;
1430
+ rb_str_buf_cat(str, (const char*)(a->data),
1431
+ a->vsize*a->hsize*sizeof(FORTRANTYPE)) ;
1432
+ return str ;
1433
+ }
1434
+
1435
+ /*
1436
+ * call-seq: _load
1437
+ *
1438
+ * For Marshal. Uses native data format.
1439
+ *
1440
+ */
1441
+ VALUE rb_CLASSLOWER_s_marshal_load(VALUE klass, VALUE str)
1442
+ {
1443
+ CLASSUPPER* a ;
1444
+ integer vsize ;
1445
+ integer hsize ;
1446
+ char* p = RSTRING_PTR(str) ;
1447
+
1448
+ vsize = *((integer*)p) ;
1449
+ p += sizeof(integer) ;
1450
+
1451
+ hsize = *((integer*)p) ;
1452
+ p += sizeof(integer) ;
1453
+
1454
+ p += 40*sizeof(char) ;
1455
+
1456
+ a = CLASSUPPER_new(vsize, hsize) ;
1457
+ memcpy((void*)a->data, (void*)p, vsize*hsize*sizeof(FORTRANTYPE)) ;
1458
+
1459
+ return wrap_CLASSLOWER(a) ;
1460
+ }
1461
+
1462
+ #if 0
1463
+ /*
1464
+ * call-seq: within(epsilon, other)
1465
+ *
1466
+ * Test if each matrix element is within +epsilon+ of the respective
1467
+ * matrix element of +other+.
1468
+ *
1469
+ */
1470
+ VALUE rb_CLASSLOWER_within( VALUE self, VALUE repsilon, VALUE other )
1471
+ {
1472
+ /* rdoc can't find this function */
1473
+ }
1474
+ #endif
1475
+
1476
+ #if 0
1477
+ /*
1478
+ * call-seq: within(epsilon, other)
1479
+ *
1480
+ * Test if each matrix element is within +epsilon+ of the respective
1481
+ * matrix element of +other+.
1482
+ *
1483
+ */
1484
+ VALUE rb_CLASSLOWER_within( VALUE self, VALUE repsilon, VALUE other )
1485
+ {
1486
+ /* rdoc can't find this function */
1487
+ }
1488
+ #endif
1489
+
1490
+ #if 0
1491
+ /*
1492
+ * call-seq: /(s)
1493
+ *
1494
+ * Division by scalar +s+.
1495
+ *
1496
+ */
1497
+ VALUE rb_CLASSLOWER_div(VALUE self, VALUE rs)
1498
+ {
1499
+ /* rdoc can't find this function */
1500
+ }
1501
+ #endif
1502
+
1503
+ #if 0
1504
+ /*
1505
+ *
1506
+ */
1507
+ VALUE rb_CLASSLOWER_symmetric_private( VALUE self, VALUE repsilon )
1508
+ {
1509
+ }
1510
+ #endif
1511
+
1512
+ void Init_CLASSLOWER()
1513
+ {
1514
+ /* Linalg */
1515
+ rb_cLinalg = rb_define_module("Linalg") ;
1516
+
1517
+ /* Linalg::Exception */
1518
+ rb_cLinalgException = rb_define_module_under(rb_cLinalg, "Exception") ;
1519
+
1520
+ /* DimensionError */
1521
+ rb_eDimensionError =
1522
+ rb_define_class_under(rb_cLinalgException,
1523
+ "DimensionError",
1524
+ rb_eRuntimeError) ;
1525
+
1526
+ /* CLASSUPPER */
1527
+ rb_cCLASSUPPER =
1528
+ rb_define_class_under(rb_cLinalg,
1529
+ "CLASSUPPER",
1530
+ rb_cObject) ;
1531
+
1532
+ /* allocate */
1533
+ rb_define_alloc_func(rb_cCLASSUPPER, rb_CLASSLOWER_allocate) ;
1534
+
1535
+ /* singleton methods */
1536
+ rb_define_singleton_method(rb_cCLASSUPPER, "rows",
1537
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_s_rows), 1) ;
1538
+ rb_define_singleton_method(rb_cCLASSUPPER, "identity",
1539
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_s_identity), 1) ;
1540
+ rb_define_singleton_method(rb_cCLASSUPPER, "diagonal",
1541
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_s_diagonal), -1) ;
1542
+ rb_define_singleton_method(rb_cCLASSUPPER, "rand",
1543
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_s_rand), 2) ;
1544
+ rb_define_singleton_method(rb_cCLASSUPPER, "reserve",
1545
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_reserve), 2) ;
1546
+ rb_define_singleton_method(rb_cCLASSUPPER, "_load",
1547
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_s_marshal_load), 1) ;
1548
+
1549
+ /* instance methods */
1550
+ rb_define_method(rb_cCLASSUPPER, "initialize",
1551
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_initialize), -1) ;
1552
+ rb_define_method(rb_cCLASSUPPER, "vsize",
1553
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_vsize), 0) ;
1554
+ rb_define_method(rb_cCLASSUPPER, "hsize",
1555
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_hsize), 0) ;
1556
+ rb_define_method(rb_cCLASSUPPER, "dimensions",
1557
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_dimensions), 0) ;
1558
+ rb_define_method(rb_cCLASSUPPER, "[]",
1559
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_bracket_get), -1) ;
1560
+ rb_define_method(rb_cCLASSUPPER, "[]=",
1561
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_bracket_set), -1) ;
1562
+
1563
+ rb_define_method(rb_cCLASSUPPER, "to_a",
1564
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_to_a), 0) ;
1565
+ rb_define_method(rb_cCLASSUPPER, "_dump",
1566
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_marshal_dump), 1) ;
1567
+ rb_define_method(rb_cCLASSUPPER, "clone",
1568
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_clone), 0) ;
1569
+ rb_define_method(rb_cCLASSUPPER, "to_FORTRANTYPE_ptr",
1570
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_to_FORTRANTYPE_ptr), 0) ;
1571
+ rb_define_method(rb_cCLASSUPPER, "coerce",
1572
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_coerce), 1) ;
1573
+
1574
+ rb_define_method(rb_cCLASSUPPER, "+",
1575
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_plus), 1) ;
1576
+ rb_define_method(rb_cCLASSUPPER, "plus!",
1577
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_plus_inplace), 1) ;
1578
+ rb_define_method(rb_cCLASSUPPER, "+@",
1579
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_unary_plus), 0) ;
1580
+
1581
+ rb_define_method(rb_cCLASSUPPER, "-",
1582
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_minus), 1) ;
1583
+ rb_define_method(rb_cCLASSUPPER, "minus!",
1584
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_minus_inplace), 1) ;
1585
+ rb_define_method(rb_cCLASSUPPER, "-@",
1586
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_unary_minus), 0) ;
1587
+ rb_define_method(rb_cCLASSUPPER, "negate!",
1588
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_unary_minus_inplace), 0) ;
1589
+
1590
+ rb_define_method(rb_cCLASSUPPER, "*",
1591
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_mul), 1) ;
1592
+ rb_define_method(rb_cCLASSUPPER, "postmul!",
1593
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_postmul_inplace), 1) ;
1594
+ rb_define_method(rb_cCLASSUPPER, "premul!",
1595
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_premul_inplace), 1) ;
1596
+
1597
+ rb_define_method(rb_cCLASSUPPER, "/",
1598
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_div), 1) ;
1599
+
1600
+ rb_define_method(rb_cCLASSUPPER, "dot",
1601
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_dot), 1) ;
1602
+ rb_define_method(rb_cCLASSUPPER, "transpose",
1603
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_transpose), 0) ;
1604
+ rb_define_method(rb_cCLASSUPPER, "transpose!",
1605
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_transpose_inplace), 0) ;
1606
+
1607
+ rb_define_method(rb_cCLASSUPPER, "within",
1608
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_within), 2) ;
1609
+
1610
+ rb_define_method(rb_cCLASSUPPER, "column",
1611
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_column), 1) ;
1612
+ rb_define_method(rb_cCLASSUPPER, "row",
1613
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_row), 1) ;
1614
+ rb_define_method(rb_cCLASSUPPER, "replace_column",
1615
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_replace_column), 2) ;
1616
+ rb_define_method(rb_cCLASSUPPER, "replace_row",
1617
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_replace_row), 2) ;
1618
+ rb_define_method(rb_cCLASSUPPER, "minor",
1619
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_minor), 4) ;
1620
+ rb_define_method(rb_cCLASSUPPER, "replace_minor",
1621
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_replace_minor), 3) ;
1622
+ rb_define_method(rb_cCLASSUPPER, "fill",
1623
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_fill), 1) ;
1624
+
1625
+ rb_define_method(rb_cCLASSUPPER, "symmetric!",
1626
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_make_symmetric), 0) ;
1627
+ rb_define_private_method(rb_cCLASSUPPER, "symmetric_private",
1628
+ RUBY_METHOD_FUNC(rb_CLASSLOWER_symmetric_private), 1) ;
1629
+ }
1630
+