linalg 1.0.2
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 +7 -0
- data/LICENSE +24 -0
- data/ext/g2c_typedefs.h +5 -0
- data/ext/lapack/extconf.rb +309 -0
- data/ext/lapack/include/BLAS.h +154 -0
- data/ext/lapack/include/LAPACK.h +1314 -0
- data/ext/lapack/main.c +49 -0
- data/ext/lapack/rb_lapack.h +36 -0
- data/ext/lapack/rb_lapack_c.c +11614 -0
- data/ext/lapack/rb_lapack_d.c +12663 -0
- data/ext/lapack/rb_lapack_s.c +12649 -0
- data/ext/lapack/rb_lapack_x.c +208 -0
- data/ext/lapack/rb_lapack_z.c +11614 -0
- data/ext/linalg/dcomplex.c +359 -0
- data/ext/linalg/dcomplex.h +40 -0
- data/ext/linalg/ddata.c +194 -0
- data/ext/linalg/extconf.rb +324 -0
- data/ext/linalg/linalg.c +55 -0
- data/ext/linalg/linalg.h +21 -0
- data/ext/linalg/xdata.c +21 -0
- data/ext/linalg/xdata.h +33 -0
- data/ext/linalg/xmatrix.c.tmpl +1630 -0
- data/ext/linalg/xmatrix.h.tmpl +77 -0
- data/ext/linalg/xmatrixc.c.tmpl +138 -0
- data/ext/linalg/xmatrixr.c.tmpl +130 -0
- data/lib/lapack.rb +87 -0
- data/lib/linalg.rb +9 -0
- data/lib/linalg/dcomplex.rb +17 -0
- data/lib/linalg/dmatrix.rb +29 -0
- data/lib/linalg/dmatrix/alias.rb +32 -0
- data/lib/linalg/dmatrix/cholesky.rb +52 -0
- data/lib/linalg/dmatrix/cond.rb +80 -0
- data/lib/linalg/dmatrix/det.rb +36 -0
- data/lib/linalg/dmatrix/eigen.rb +153 -0
- data/lib/linalg/dmatrix/fit.rb +281 -0
- data/lib/linalg/dmatrix/inverse.rb +78 -0
- data/lib/linalg/dmatrix/lu.rb +120 -0
- data/lib/linalg/dmatrix/main.rb +244 -0
- data/lib/linalg/dmatrix/norms.rb +88 -0
- data/lib/linalg/dmatrix/nullspace.rb +114 -0
- data/lib/linalg/dmatrix/qr.rb +129 -0
- data/lib/linalg/dmatrix/schur.rb +88 -0
- data/lib/linalg/dmatrix/solve.rb +78 -0
- data/lib/linalg/dmatrix/svd.rb +125 -0
- data/lib/linalg/exception.rb +32 -0
- data/lib/linalg/iterators.rb +221 -0
- data/lib/linalg/math.rb +23 -0
- data/lib/linalg/scomplex.rb +15 -0
- data/lib/linalg/version.rb +3 -0
- data/lib/linalg/xdata.rb +123 -0
- metadata +94 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2004-2008 by James M. Lawrence
|
3
|
+
*
|
4
|
+
* See LICENSE
|
5
|
+
*
|
6
|
+
*/
|
7
|
+
|
8
|
+
#ifndef CLASSUPPER_H
|
9
|
+
#define CLASSUPPER_H
|
10
|
+
|
11
|
+
#include <stdlib.h>
|
12
|
+
#include <math.h>
|
13
|
+
#include <time.h>
|
14
|
+
|
15
|
+
#include <f2c.h>
|
16
|
+
|
17
|
+
#include "BLAS.h"
|
18
|
+
#include "LAPACK.h"
|
19
|
+
|
20
|
+
#include "ruby.h"
|
21
|
+
|
22
|
+
#include "dcomplex.h"
|
23
|
+
#include "scomplex.h"
|
24
|
+
|
25
|
+
#include "linalg.h"
|
26
|
+
|
27
|
+
/**************************************************
|
28
|
+
*
|
29
|
+
* CLASSUPPER
|
30
|
+
*
|
31
|
+
**************************************************/
|
32
|
+
|
33
|
+
struct CLASSUPPER_
|
34
|
+
{
|
35
|
+
integer vsize ;
|
36
|
+
integer hsize ;
|
37
|
+
FORTRANTYPE* data ;
|
38
|
+
} ;
|
39
|
+
|
40
|
+
typedef struct CLASSUPPER_ CLASSUPPER ;
|
41
|
+
|
42
|
+
/**************************************************
|
43
|
+
*
|
44
|
+
* globals
|
45
|
+
*
|
46
|
+
**************************************************/
|
47
|
+
|
48
|
+
extern FORTRANTYPE CLASSLOWER_FORTRANTYPE_1 ;
|
49
|
+
extern FORTRANTYPE CLASSLOWER_FORTRANTYPE_neg_1 ;
|
50
|
+
extern FORTRANTYPE CLASSLOWER_FORTRANTYPE_0 ;
|
51
|
+
extern VALUE rb_cCLASSUPPER ;
|
52
|
+
|
53
|
+
/**************************************************
|
54
|
+
*
|
55
|
+
* utils
|
56
|
+
*
|
57
|
+
**************************************************/
|
58
|
+
|
59
|
+
#define get_CLASSLOWER(ptr, obj) Data_Get_Struct(obj, CLASSUPPER, ptr)
|
60
|
+
#define wrap_CLASSLOWER(obj) Data_Wrap_Struct(rb_cCLASSUPPER, 0, CLASSUPPER_free, obj)
|
61
|
+
|
62
|
+
/**************************************************
|
63
|
+
*
|
64
|
+
* cross-defs
|
65
|
+
*
|
66
|
+
**************************************************/
|
67
|
+
|
68
|
+
FORTRANTYPE CLASSUPPER_dot(CLASSUPPER* a, CLASSUPPER* b) ;
|
69
|
+
CLASSUPPER* CLASSUPPER_rand(CLASSUPPER* a) ;
|
70
|
+
VALUE rb_CLASSLOWER_within( VALUE self, VALUE repsilon, VALUE other ) ;
|
71
|
+
VALUE rb_CLASSLOWER_symmetric_private( VALUE self, VALUE repsilon ) ;
|
72
|
+
VALUE rb_CLASSLOWER_div(VALUE self, VALUE rb) ;
|
73
|
+
CLASSUPPER* CLASSUPPER_mul_scalar(CLASSUPPER* a, FORTRANTYPE s) ;
|
74
|
+
CLASSUPPER* CLASSUPPER_clone(CLASSUPPER* m) ;
|
75
|
+
void CLASSUPPER_free(CLASSUPPER* m) ;
|
76
|
+
|
77
|
+
#endif
|
@@ -0,0 +1,138 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2004-2008 by James M. Lawrence
|
3
|
+
*
|
4
|
+
* See LICENSE
|
5
|
+
*
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include "CLASSLOWER.h"
|
9
|
+
|
10
|
+
FORTRANTYPE CLASSLOWER_FORTRANTYPE_1 = { 1.0, 0.0 } ;
|
11
|
+
FORTRANTYPE CLASSLOWER_FORTRANTYPE_neg_1 = { -1.0, 0.0 } ;
|
12
|
+
FORTRANTYPE CLASSLOWER_FORTRANTYPE_0 = { 0.0, 0.0 } ;
|
13
|
+
|
14
|
+
static integer integer_1 = 1 ;
|
15
|
+
|
16
|
+
FORTRANTYPE CLASSUPPER_dot(CLASSUPPER* a, CLASSUPPER* b)
|
17
|
+
{
|
18
|
+
FORTRANTYPE ret ;
|
19
|
+
xdotc_(&ret,
|
20
|
+
&a->vsize,
|
21
|
+
a->data,
|
22
|
+
&integer_1,
|
23
|
+
b->data,
|
24
|
+
&integer_1) ;
|
25
|
+
return ret ;
|
26
|
+
}
|
27
|
+
|
28
|
+
|
29
|
+
CLASSUPPER* CLASSUPPER_rand(CLASSUPPER* a)
|
30
|
+
{
|
31
|
+
integer i ;
|
32
|
+
integer size = a->vsize*a->hsize ;
|
33
|
+
|
34
|
+
for( i = 0 ; i != size ; ++i )
|
35
|
+
{
|
36
|
+
(a->data[i]).r =
|
37
|
+
2.0*(((double)rand())/(RAND_MAX)) - 1.0 ;
|
38
|
+
(a->data[i]).i =
|
39
|
+
2.0*(((double)rand())/(RAND_MAX)) - 1.0 ;
|
40
|
+
}
|
41
|
+
|
42
|
+
return a ;
|
43
|
+
}
|
44
|
+
|
45
|
+
|
46
|
+
VALUE rb_CLASSLOWER_within( VALUE self, VALUE repsilon, VALUE other )
|
47
|
+
{
|
48
|
+
CLASSUPPER* a ;
|
49
|
+
CLASSUPPER* b ;
|
50
|
+
FORTRANTYPE* pa ;
|
51
|
+
FORTRANTYPE* pb ;
|
52
|
+
FORTRANTYPE* aend ;
|
53
|
+
double epsilon ;
|
54
|
+
get_CLASSLOWER(a, self) ;
|
55
|
+
get_CLASSLOWER(b, other) ;
|
56
|
+
|
57
|
+
if( a->vsize != b->vsize ||
|
58
|
+
a->hsize != b->hsize )
|
59
|
+
{
|
60
|
+
raise_dim_error() ;
|
61
|
+
}
|
62
|
+
|
63
|
+
epsilon = NUM2DBL(repsilon) ;
|
64
|
+
|
65
|
+
pa = a->data ;
|
66
|
+
pb = b->data ;
|
67
|
+
aend = pa + a->vsize*a->hsize ;
|
68
|
+
|
69
|
+
for( ; pa != aend ; ++pa, ++pb )
|
70
|
+
{
|
71
|
+
if( fabs(pa->r - pb->r) > epsilon ||
|
72
|
+
fabs(pa->i - pb->i) > epsilon )
|
73
|
+
{
|
74
|
+
return Qfalse ;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
return Qtrue ;
|
79
|
+
}
|
80
|
+
|
81
|
+
VALUE rb_CLASSLOWER_symmetric_private( VALUE self, VALUE repsilon )
|
82
|
+
{
|
83
|
+
CLASSUPPER* a ;
|
84
|
+
double epsilon ;
|
85
|
+
|
86
|
+
get_CLASSLOWER(a, self) ;
|
87
|
+
|
88
|
+
if( a->vsize != a->hsize )
|
89
|
+
{
|
90
|
+
return Qfalse ;
|
91
|
+
}
|
92
|
+
|
93
|
+
epsilon = NUM2DBL(repsilon) ;
|
94
|
+
|
95
|
+
{
|
96
|
+
int i ;
|
97
|
+
int j ;
|
98
|
+
|
99
|
+
for( j = 0 ; j < a->hsize ; ++j )
|
100
|
+
{
|
101
|
+
for( i = j + 1 ; i < a->vsize ; ++i )
|
102
|
+
{
|
103
|
+
if( fabs(a->data[i + j*a->vsize].r -
|
104
|
+
a->data[j + i*a->vsize].r) > epsilon ||
|
105
|
+
fabs(a->data[i + j*a->vsize].i -
|
106
|
+
a->data[j + i*a->vsize].i) > epsilon )
|
107
|
+
{
|
108
|
+
return Qfalse ;
|
109
|
+
}
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
return Qtrue ;
|
115
|
+
}
|
116
|
+
|
117
|
+
VALUE rb_CLASSLOWER_div(VALUE self, VALUE rb)
|
118
|
+
{
|
119
|
+
CLASSUPPER* a ;
|
120
|
+
CLASSUPPER* c ;
|
121
|
+
FORTRANTYPE b ;
|
122
|
+
FORTRANTYPE s ;
|
123
|
+
doublereal bottom ;
|
124
|
+
VALUE rc ;
|
125
|
+
|
126
|
+
b = RUBY2FORTRAN(rb) ;
|
127
|
+
|
128
|
+
get_CLASSLOWER(a, self) ;
|
129
|
+
c = CLASSUPPER_clone(a) ;
|
130
|
+
rc = wrap_CLASSLOWER(c) ;
|
131
|
+
|
132
|
+
bottom = b.r*b.r + b.i*b.i ;
|
133
|
+
s.r = b.r/bottom ;
|
134
|
+
s.i = -b.i/bottom ;
|
135
|
+
|
136
|
+
CLASSUPPER_mul_scalar(c, s) ;
|
137
|
+
return rc ;
|
138
|
+
}
|
@@ -0,0 +1,130 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2004-2008 by James M. Lawrence
|
3
|
+
*
|
4
|
+
* See LICENSE
|
5
|
+
*
|
6
|
+
*/
|
7
|
+
|
8
|
+
#include "CLASSLOWER.h"
|
9
|
+
|
10
|
+
FORTRANTYPE CLASSLOWER_FORTRANTYPE_1 = 1.0 ;
|
11
|
+
FORTRANTYPE CLASSLOWER_FORTRANTYPE_neg_1 = -1.0 ;
|
12
|
+
FORTRANTYPE CLASSLOWER_FORTRANTYPE_0 = 0.0 ;
|
13
|
+
|
14
|
+
static integer integer_1 = 1 ;
|
15
|
+
|
16
|
+
FORTRANTYPE CLASSUPPER_dot(CLASSUPPER* a, CLASSUPPER* b)
|
17
|
+
{
|
18
|
+
return xdot_(&a->vsize,
|
19
|
+
a->data,
|
20
|
+
&integer_1,
|
21
|
+
b->data,
|
22
|
+
&integer_1) ;
|
23
|
+
}
|
24
|
+
|
25
|
+
|
26
|
+
CLASSUPPER* CLASSUPPER_rand(CLASSUPPER* a)
|
27
|
+
{
|
28
|
+
integer i ;
|
29
|
+
integer size = a->vsize*a->hsize ;
|
30
|
+
|
31
|
+
for( i = 0 ; i != size ; ++i )
|
32
|
+
{
|
33
|
+
a->data[i] =
|
34
|
+
2.0*(((double)rand())/(RAND_MAX)) - CLASSLOWER_FORTRANTYPE_1 ;
|
35
|
+
}
|
36
|
+
|
37
|
+
return a ;
|
38
|
+
}
|
39
|
+
|
40
|
+
|
41
|
+
/*
|
42
|
+
* call-seq: within(epsilon, other)
|
43
|
+
*
|
44
|
+
* Test if each matrix element is within +epsilon+ of the respective
|
45
|
+
* matrix element of +other+.
|
46
|
+
*
|
47
|
+
*/
|
48
|
+
VALUE rb_CLASSLOWER_within( VALUE self, VALUE repsilon, VALUE other )
|
49
|
+
{
|
50
|
+
CLASSUPPER* a ;
|
51
|
+
CLASSUPPER* b ;
|
52
|
+
FORTRANTYPE* pa ;
|
53
|
+
FORTRANTYPE* pb ;
|
54
|
+
FORTRANTYPE* aend ;
|
55
|
+
double epsilon ;
|
56
|
+
get_CLASSLOWER(a, self) ;
|
57
|
+
get_CLASSLOWER(b, other) ;
|
58
|
+
|
59
|
+
if( a->vsize != b->vsize ||
|
60
|
+
a->hsize != b->hsize )
|
61
|
+
{
|
62
|
+
raise_dim_error() ;
|
63
|
+
}
|
64
|
+
|
65
|
+
epsilon = NUM2DBL(repsilon) ;
|
66
|
+
|
67
|
+
pa = a->data ;
|
68
|
+
pb = b->data ;
|
69
|
+
aend = pa + a->vsize*a->hsize ;
|
70
|
+
|
71
|
+
for( ; pa != aend ; ++pa, ++pb )
|
72
|
+
{
|
73
|
+
if( fabs((*pa) - (*pb)) > epsilon )
|
74
|
+
{
|
75
|
+
return Qfalse ;
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
return Qtrue ;
|
80
|
+
}
|
81
|
+
|
82
|
+
|
83
|
+
VALUE rb_CLASSLOWER_symmetric_private( VALUE self, VALUE repsilon )
|
84
|
+
{
|
85
|
+
CLASSUPPER* a ;
|
86
|
+
double epsilon ;
|
87
|
+
|
88
|
+
get_CLASSLOWER(a, self) ;
|
89
|
+
|
90
|
+
if( a->vsize != a->hsize )
|
91
|
+
{
|
92
|
+
return Qfalse ;
|
93
|
+
}
|
94
|
+
|
95
|
+
epsilon = NUM2DBL(repsilon) ;
|
96
|
+
|
97
|
+
{
|
98
|
+
int i ;
|
99
|
+
int j ;
|
100
|
+
|
101
|
+
for( j = 0 ; j < a->hsize ; ++j )
|
102
|
+
{
|
103
|
+
for( i = j + 1 ; i < a->vsize ; ++i )
|
104
|
+
{
|
105
|
+
if( fabs(a->data[i + j*a->vsize] -
|
106
|
+
a->data[j + i*a->vsize]) > epsilon )
|
107
|
+
{
|
108
|
+
return Qfalse ;
|
109
|
+
}
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
return Qtrue ;
|
115
|
+
}
|
116
|
+
|
117
|
+
VALUE rb_CLASSLOWER_div(VALUE self, VALUE rb)
|
118
|
+
{
|
119
|
+
CLASSUPPER* a ;
|
120
|
+
CLASSUPPER* c ;
|
121
|
+
VALUE rc ;
|
122
|
+
double b = NUM2DBL(rb) ;
|
123
|
+
|
124
|
+
get_CLASSLOWER(a, self) ;
|
125
|
+
c = CLASSUPPER_clone(a) ;
|
126
|
+
rc = wrap_CLASSLOWER(c) ;
|
127
|
+
CLASSUPPER_mul_scalar(c, 1.0/b) ;
|
128
|
+
return rc ;
|
129
|
+
}
|
130
|
+
|
data/lib/lapack.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2004-2008 by James M. Lawrence
|
3
|
+
#
|
4
|
+
# See LICENSE
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'rbconfig'
|
8
|
+
|
9
|
+
require "lapack.#{Config::CONFIG['DLEXT']}"
|
10
|
+
|
11
|
+
#
|
12
|
+
# Simple, strongly-typed bindings to LAPACK.
|
13
|
+
#
|
14
|
+
# Every LAPACK subroutine is accessible from the +Lapack+ module
|
15
|
+
#
|
16
|
+
# Lapack.methods.size # => 1498
|
17
|
+
#
|
18
|
+
# and each subroutine corresponds to a +Lapack+ module method
|
19
|
+
# of the same name
|
20
|
+
#
|
21
|
+
# Lapack.methods.include? "dgemm" # => true
|
22
|
+
#
|
23
|
+
# The +Lapack+ module knows the type signature of each LAPACK
|
24
|
+
# subroutine. With this signature it calls the appropriate method:
|
25
|
+
#
|
26
|
+
# to_real_ptr
|
27
|
+
# to_doublereal_ptr
|
28
|
+
# to_complex_ptr
|
29
|
+
# to_doublecomplex_ptr
|
30
|
+
# to_integer_ptr
|
31
|
+
# to_logical_ptr
|
32
|
+
# to_L_fp_ptr
|
33
|
+
# to_char_ptr
|
34
|
+
#
|
35
|
+
# on each parameter passed. For example,
|
36
|
+
#
|
37
|
+
# Lapack.dgemm(transa, # calls transa.to_integer_ptr
|
38
|
+
# transb, # calls transb.to_integer_ptr
|
39
|
+
# m, # calls m.to_integer_ptr
|
40
|
+
# n, # calls n.to_integer_ptr
|
41
|
+
# k, # calls k.to_integer_ptr
|
42
|
+
# alpha, # calls alpha.to_doublereal_ptr
|
43
|
+
# a, # calls a.to_doublereal_ptr
|
44
|
+
# lda, # calls lda.to_integer_ptr
|
45
|
+
# b, # calls b.to_doublereal_ptr
|
46
|
+
# ldb, # calls b.to_integer_ptr
|
47
|
+
# beta, # calls beta.to_doublereal_ptr
|
48
|
+
# c, # calls c.to_doublereal_ptr
|
49
|
+
# ldc) # calls ldc.to_integer_ptr
|
50
|
+
#
|
51
|
+
# The type names are taken directly from g2c.h.
|
52
|
+
#
|
53
|
+
# real
|
54
|
+
# doublereal
|
55
|
+
# complex
|
56
|
+
# doublecomplex
|
57
|
+
# integer
|
58
|
+
# logical
|
59
|
+
# L_fp
|
60
|
+
# char
|
61
|
+
#
|
62
|
+
# Each <tt>to_FORTRANTYPE_ptr</tt> method returns the actual pointer
|
63
|
+
# value of some data.
|
64
|
+
#
|
65
|
+
# Where do you find classes which so promiscuously expose pointer
|
66
|
+
# values? Well, you make them from your own extension classes, or you
|
67
|
+
# may use some generic classes which are provided. See Linalg::XData
|
68
|
+
# for some very simple data classes.
|
69
|
+
#
|
70
|
+
# It should be emphasized that there is no preferred class or data
|
71
|
+
# structure for interacting with the +Lapack+ module. All +Lapack+
|
72
|
+
# requires is that the appropriate to_FORTRANTYPE_ptr be implemented
|
73
|
+
# on each parameter passed. From this perspective it is questionable
|
74
|
+
# whether +Lapack+ should even be bundled with the +linalg+ package.
|
75
|
+
#
|
76
|
+
# +DMatrix+, for example, is just a class which implements
|
77
|
+
# the <tt>to_doublereal_ptr</tt> method, and the entirety of its
|
78
|
+
# communication from ruby to +Lapack+ goes through that method.
|
79
|
+
#
|
80
|
+
# For C extension writers: While C's +double+, for example, is almost
|
81
|
+
# surely the same as +doublereal+, to ensure portability it is
|
82
|
+
# generally good practice to use the aforementioned types found in the
|
83
|
+
# g2c.h header on your system.
|
84
|
+
#
|
85
|
+
#
|
86
|
+
module Lapack
|
87
|
+
end
|
data/lib/linalg.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require "linalg.#{RbConfig::CONFIG['DLEXT']}"
|
2
|
+
require "lapack.#{RbConfig::CONFIG['DLEXT']}"
|
3
|
+
require "linalg/dcomplex"
|
4
|
+
require "linalg/dmatrix"
|
5
|
+
require "linalg/exception"
|
6
|
+
require "linalg/iterators"
|
7
|
+
require "linalg/math"
|
8
|
+
require "linalg/scomplex"
|
9
|
+
require "linalg/xdata"
|