nmatrix 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +27 -0
- data/.rspec +2 -0
- data/Gemfile +3 -5
- data/Guardfile +6 -0
- data/History.txt +33 -0
- data/Manifest.txt +41 -38
- data/README.rdoc +88 -11
- data/Rakefile +35 -53
- data/ext/nmatrix/data/complex.h +372 -0
- data/ext/nmatrix/data/data.cpp +275 -0
- data/ext/nmatrix/data/data.h +707 -0
- data/ext/nmatrix/data/rational.h +421 -0
- data/ext/nmatrix/data/ruby_object.h +446 -0
- data/ext/nmatrix/extconf.rb +101 -51
- data/ext/nmatrix/new_extconf.rb +56 -0
- data/ext/nmatrix/nmatrix.cpp +1609 -0
- data/ext/nmatrix/nmatrix.h +265 -849
- data/ext/nmatrix/ruby_constants.cpp +134 -0
- data/ext/nmatrix/ruby_constants.h +103 -0
- data/ext/nmatrix/storage/common.cpp +70 -0
- data/ext/nmatrix/storage/common.h +170 -0
- data/ext/nmatrix/storage/dense.cpp +665 -0
- data/ext/nmatrix/storage/dense.h +116 -0
- data/ext/nmatrix/storage/list.cpp +1088 -0
- data/ext/nmatrix/storage/list.h +129 -0
- data/ext/nmatrix/storage/storage.cpp +658 -0
- data/ext/nmatrix/storage/storage.h +99 -0
- data/ext/nmatrix/storage/yale.cpp +1601 -0
- data/ext/nmatrix/storage/yale.h +208 -0
- data/ext/nmatrix/ttable_helper.rb +126 -0
- data/ext/nmatrix/{yale/smmp1_header.template.c → types.h} +36 -9
- data/ext/nmatrix/util/io.cpp +295 -0
- data/ext/nmatrix/util/io.h +117 -0
- data/ext/nmatrix/util/lapack.h +1175 -0
- data/ext/nmatrix/util/math.cpp +557 -0
- data/ext/nmatrix/util/math.h +1363 -0
- data/ext/nmatrix/util/sl_list.cpp +475 -0
- data/ext/nmatrix/util/sl_list.h +255 -0
- data/ext/nmatrix/util/util.h +78 -0
- data/lib/nmatrix/blas.rb +70 -0
- data/lib/nmatrix/io/mat5_reader.rb +567 -0
- data/lib/nmatrix/io/mat_reader.rb +162 -0
- data/lib/{string.rb → nmatrix/monkeys.rb} +49 -2
- data/lib/nmatrix/nmatrix.rb +199 -0
- data/lib/nmatrix/nvector.rb +103 -0
- data/lib/nmatrix/version.rb +27 -0
- data/lib/nmatrix.rb +22 -230
- data/nmatrix.gemspec +59 -0
- data/scripts/mac-brew-gcc.sh +47 -0
- data/spec/4x4_sparse.mat +0 -0
- data/spec/4x5_dense.mat +0 -0
- data/spec/blas_spec.rb +47 -0
- data/spec/elementwise_spec.rb +164 -0
- data/spec/io_spec.rb +60 -0
- data/spec/lapack_spec.rb +52 -0
- data/spec/math_spec.rb +96 -0
- data/spec/nmatrix_spec.rb +93 -89
- data/spec/nmatrix_yale_spec.rb +52 -36
- data/spec/nvector_spec.rb +1 -1
- data/spec/slice_spec.rb +257 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/utm5940.mtx +83844 -0
- metadata +113 -71
- data/.autotest +0 -23
- data/.gemtest +0 -0
- data/ext/nmatrix/cblas.c +0 -150
- data/ext/nmatrix/dense/blas_header.template.c +0 -52
- data/ext/nmatrix/dense/elementwise.template.c +0 -107
- data/ext/nmatrix/dense/gemm.template.c +0 -159
- data/ext/nmatrix/dense/gemv.template.c +0 -130
- data/ext/nmatrix/dense/rationalmath.template.c +0 -68
- data/ext/nmatrix/dense.c +0 -307
- data/ext/nmatrix/depend +0 -18
- data/ext/nmatrix/generator/syntax_tree.rb +0 -481
- data/ext/nmatrix/generator.rb +0 -594
- data/ext/nmatrix/list.c +0 -774
- data/ext/nmatrix/nmatrix.c +0 -1977
- data/ext/nmatrix/rational.c +0 -98
- data/ext/nmatrix/yale/complexmath.template.c +0 -71
- data/ext/nmatrix/yale/elementwise.template.c +0 -46
- data/ext/nmatrix/yale/elementwise_op.template.c +0 -73
- data/ext/nmatrix/yale/numbmm.template.c +0 -94
- data/ext/nmatrix/yale/smmp1.template.c +0 -21
- data/ext/nmatrix/yale/smmp2.template.c +0 -43
- data/ext/nmatrix/yale/smmp2_header.template.c +0 -46
- data/ext/nmatrix/yale/sort_columns.template.c +0 -56
- data/ext/nmatrix/yale/symbmm.template.c +0 -54
- data/ext/nmatrix/yale/transp.template.c +0 -68
- data/ext/nmatrix/yale.c +0 -726
- data/lib/array.rb +0 -67
- data/spec/syntax_tree_spec.rb +0 -46
data/ext/nmatrix/rational.c
DELETED
@@ -1,98 +0,0 @@
|
|
1
|
-
/////////////////////////////////////////////////////////////////////
|
2
|
-
// = NMatrix
|
3
|
-
//
|
4
|
-
// A linear algebra library for scientific computation in Ruby.
|
5
|
-
// NMatrix is part of SciRuby.
|
6
|
-
//
|
7
|
-
// NMatrix was originally inspired by and derived from NArray, by
|
8
|
-
// Masahiro Tanaka: http://narray.rubyforge.org
|
9
|
-
//
|
10
|
-
// == Copyright Information
|
11
|
-
//
|
12
|
-
// SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
|
13
|
-
// NMatrix is Copyright (c) 2012, Ruby Science Foundation
|
14
|
-
//
|
15
|
-
// Please see LICENSE.txt for additional copyright notices.
|
16
|
-
//
|
17
|
-
// == Contributing
|
18
|
-
//
|
19
|
-
// By contributing source code to SciRuby, you agree to be bound by
|
20
|
-
// our Contributor Agreement:
|
21
|
-
//
|
22
|
-
// * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
|
23
|
-
//
|
24
|
-
// == rational.c
|
25
|
-
//
|
26
|
-
// This file is largely based off of Ruby 1.9.3's rational.c. It
|
27
|
-
// contains functions for dealing with rational types which are
|
28
|
-
// not Ruby VALUE-based.
|
29
|
-
|
30
|
-
#ifndef RATIONAL_C
|
31
|
-
# define RATIONAL_C
|
32
|
-
|
33
|
-
#include "nmatrix.h"
|
34
|
-
|
35
|
-
|
36
|
-
inline int64_t nmrb_gcd(int64_t x, int64_t y) {
|
37
|
-
int64_t t;
|
38
|
-
|
39
|
-
if (x < 0) x = -x;
|
40
|
-
if (y < 0) y = -y;
|
41
|
-
|
42
|
-
if (x == 0) return y;
|
43
|
-
if (y == 0) return x;
|
44
|
-
|
45
|
-
while (x > 0) {
|
46
|
-
t = x;
|
47
|
-
x = y % x;
|
48
|
-
y = t;
|
49
|
-
}
|
50
|
-
|
51
|
-
return y;
|
52
|
-
}
|
53
|
-
|
54
|
-
/*
|
55
|
-
static double f_gcd(double x, double y) {
|
56
|
-
double z;
|
57
|
-
|
58
|
-
if (x < 0.0) x = -x;
|
59
|
-
if (y < 0.0) y = -y;
|
60
|
-
if (x == 0.0) return y;
|
61
|
-
if (y == 0.0) return x;
|
62
|
-
|
63
|
-
for (;;) {
|
64
|
-
z = x;
|
65
|
-
x = y % x;
|
66
|
-
y = z;
|
67
|
-
}
|
68
|
-
// NOTREACHED
|
69
|
-
}*/
|
70
|
-
|
71
|
-
/*
|
72
|
-
inline VALUE nmrb_rational_new_no_reduce1(VALUE klass, int64_t x) {
|
73
|
-
return nurat_s_canonicalize_internal_no_reduce(klass, x, 1);
|
74
|
-
}
|
75
|
-
|
76
|
-
inline static VALUE nurat_s_canonicalize_internal_no_reduce(VALUE klass, int64_t num, int64_t den) {
|
77
|
-
if (den < 0) {
|
78
|
-
num = -num;
|
79
|
-
den = -den;
|
80
|
-
} else if (den == 0) {
|
81
|
-
rb_raise_zerodiv();
|
82
|
-
}
|
83
|
-
return nurat_s_new_internal(klass, num, den);
|
84
|
-
}*/
|
85
|
-
/*
|
86
|
-
inline VALUE nmrb_rational_new(VALUE klass, int64_t num, int64_t den) {
|
87
|
-
NEWOBJ(obj, struct RRational);
|
88
|
-
OBJSETUP(obj, klass, T_RATIONAL);
|
89
|
-
|
90
|
-
obj->num = INT2FIX(num);
|
91
|
-
obj->den = INT2FIX(den);
|
92
|
-
|
93
|
-
return (VALUE)obj;
|
94
|
-
}
|
95
|
-
*/
|
96
|
-
|
97
|
-
|
98
|
-
#endif
|
@@ -1,71 +0,0 @@
|
|
1
|
-
|
2
|
-
inline static %%TYPE%% BOOL2%%= dtype.id.to_s.upcase%%(bool expr) {
|
3
|
-
%%TYPE%% result;
|
4
|
-
result.r = expr;
|
5
|
-
result.i = 0;
|
6
|
-
return result;
|
7
|
-
}
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
inline static %%TYPE%% %%TYPE_ABBREV%%_mul(double ar, double ai, double br, double bi) {
|
12
|
-
%%TYPE%% result;
|
13
|
-
|
14
|
-
result.r = ar * br - ai * bi;
|
15
|
-
result.i = ar * bi + br * ai;
|
16
|
-
|
17
|
-
return result;
|
18
|
-
}
|
19
|
-
|
20
|
-
|
21
|
-
inline static %%TYPE%% %%TYPE_ABBREV%%_div(double ar, double ai, double br, double bi) {
|
22
|
-
%%TYPE%% result;
|
23
|
-
double denom = br * br + bi * bi;
|
24
|
-
|
25
|
-
result.r = (ar * br + ai * bi) / denom;
|
26
|
-
result.i = (ai * br - ar * bi) / denom;
|
27
|
-
|
28
|
-
return result;
|
29
|
-
}
|
30
|
-
|
31
|
-
|
32
|
-
inline static %%TYPE%% %%TYPE_ABBREV%%_add(%%= dtype.sym == :complex128 ? "double ar, double ai, double br, double bi" : "float ar, float ai, float br, float bi"%%) {
|
33
|
-
%%TYPE%% result;
|
34
|
-
|
35
|
-
result.r = ar + br;
|
36
|
-
result.i = ai + bi;
|
37
|
-
|
38
|
-
return result;
|
39
|
-
}
|
40
|
-
|
41
|
-
|
42
|
-
inline static %%TYPE%% %%TYPE_ABBREV%%_sub(%%= dtype.sym == :complex128 ? "double ar, double ai, double br, double bi" : "float ar, float ai, float br, float bi"%%) {
|
43
|
-
%%TYPE%% result;
|
44
|
-
|
45
|
-
result.r = ar - br;
|
46
|
-
result.i = ai - bi;
|
47
|
-
|
48
|
-
return result;
|
49
|
-
}
|
50
|
-
|
51
|
-
|
52
|
-
inline static %%TYPE%% %%TYPE_ABBREV%%_mod(%%= dtype.sym == :complex128 ? "double ar, double ai, double br, double bi" : "float ar, float ai, float br, float bi"%%) {
|
53
|
-
%%TYPE%% result;
|
54
|
-
rb_raise(rb_eNotImpError, "modulo arithmetic for complex numbers not yet implemented");
|
55
|
-
|
56
|
-
return result;
|
57
|
-
}
|
58
|
-
|
59
|
-
|
60
|
-
inline static %%TYPE%% %%TYPE_ABBREV%%_bang(%%= dtype.sym == :complex128 ? "double ar, double ai" : "float ar, float ai"%%) {
|
61
|
-
%%TYPE%% result = {!ar, 0};
|
62
|
-
return result;
|
63
|
-
}
|
64
|
-
|
65
|
-
inline static %%TYPE%% %%TYPE_ABBREV%%_negate(%%= dtype.sym == :complex128 ? "double ar, double ai" : "float ar, float ai"%%) {
|
66
|
-
%%TYPE%% result;
|
67
|
-
result.r = -ar;
|
68
|
-
result.i = -ai;
|
69
|
-
return result;
|
70
|
-
}
|
71
|
-
|
@@ -1,46 +0,0 @@
|
|
1
|
-
|
2
|
-
int %%INT_ABBREV%%_%%TYPE_ABBREV%%_ew(y_size_t n, y_size_t m, enum NMatrix_Ops op, const u_%%INT%%* ija, const u_%%INT%%* ijb, const u_%%INT%%* ijc, %%TYPE%%* a, %%TYPE%%* b, %%TYPE%%* c)
|
3
|
-
{
|
4
|
-
y_size_t i;
|
5
|
-
y_size_t c_jj, a_jj, b_jj;
|
6
|
-
%%TYPE%% left, right;
|
7
|
-
|
8
|
-
for (i = 0; i < n; ++i) {
|
9
|
-
// do operation on diagonals first:
|
10
|
-
if (i < m) {
|
11
|
-
if (b) %%TYPE_ABBREV%%_ew_op_binary(op, &(c[i]), a[i], b[i]);
|
12
|
-
else %%TYPE_ABBREV%%_ew_op_unary(op, &(c[i]), a[i]);
|
13
|
-
}
|
14
|
-
|
15
|
-
c_jj = ijc[i];
|
16
|
-
a_jj = ija[i];
|
17
|
-
if (ijb) b_jj = ijb[i];
|
18
|
-
|
19
|
-
//fprintf(stderr, "i16_f64_ew: n=%d, i=%d, c_jj=%d\n", (int)(n), (int)(i), (int)(c_jj));
|
20
|
-
while (c_jj < ijc[i+1]) {
|
21
|
-
// one or the other has to be the correct column (j = ijc[c_jj] ==? ija[a_jj])
|
22
|
-
if (a_jj < ija[i+1] && ija[a_jj] == ijc[c_jj]) {
|
23
|
-
%%TYPE left = a[a_jj]%%
|
24
|
-
++a_jj;
|
25
|
-
} else {
|
26
|
-
%%TYPE left = 0%%
|
27
|
-
}
|
28
|
-
|
29
|
-
if (b) { // some ops don't have a second vector
|
30
|
-
if (b_jj < ijb[i+1] && ijb[b_jj] == ijc[c_jj]) {
|
31
|
-
%%TYPE right = b[b_jj]%%
|
32
|
-
++b_jj;
|
33
|
-
} else {
|
34
|
-
%%TYPE right = 0%%
|
35
|
-
}
|
36
|
-
|
37
|
-
%%TYPE_ABBREV%%_ew_op_binary(op, &(c[c_jj]), left, right);
|
38
|
-
} else {
|
39
|
-
%%TYPE_ABBREV%%_ew_op_unary(op, &(c[c_jj]), left);
|
40
|
-
}
|
41
|
-
|
42
|
-
++c_jj;
|
43
|
-
}
|
44
|
-
}
|
45
|
-
return 0;
|
46
|
-
}
|
@@ -1,73 +0,0 @@
|
|
1
|
-
|
2
|
-
static inline void %%TYPE_ABBREV%%_ew_op_unary(enum NMatrix_Ops op, %%TYPE%%* result, %%TYPE%% left) {
|
3
|
-
switch(op) {
|
4
|
-
case '!':
|
5
|
-
%%TYPE *result = !left%%
|
6
|
-
break;
|
7
|
-
case NM_OP_NEG:
|
8
|
-
%%TYPE *result = -left%%
|
9
|
-
break;
|
10
|
-
case '~':
|
11
|
-
%%TYPE *result = ~left%%
|
12
|
-
break;
|
13
|
-
default:
|
14
|
-
rb_raise(rb_eNotImpError, "Unrecognized element-wise unary operator");
|
15
|
-
}
|
16
|
-
}
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
static inline void %%TYPE_ABBREV%%_ew_op_binary(enum NMatrix_Ops op, %%TYPE%%* result, %%TYPE%% left, %%TYPE%% right) {
|
21
|
-
switch(op) {
|
22
|
-
case '+':
|
23
|
-
%%TYPE *result = left + right%%
|
24
|
-
break;
|
25
|
-
case '-':
|
26
|
-
%%TYPE *result = left - right%%
|
27
|
-
break;
|
28
|
-
case '*':
|
29
|
-
%%TYPE *result = left * right%%
|
30
|
-
break;
|
31
|
-
case '/':
|
32
|
-
%%TYPE *result = left / right%%
|
33
|
-
break;
|
34
|
-
case '%':
|
35
|
-
%%TYPE *result = left % right%%
|
36
|
-
break;
|
37
|
-
case NM_OP_EQEQ:
|
38
|
-
%%TYPE *result = left == right%%
|
39
|
-
break;
|
40
|
-
case NM_OP_NEQ:
|
41
|
-
%%TYPE *result = left != right%%
|
42
|
-
break;
|
43
|
-
case '>':
|
44
|
-
%%TYPE *result = left > right%%
|
45
|
-
break;
|
46
|
-
case '<':
|
47
|
-
%%TYPE *result = left < right%%
|
48
|
-
break;
|
49
|
-
case NM_OP_GTE:
|
50
|
-
%%TYPE *result = left >= right%%
|
51
|
-
break;
|
52
|
-
case NM_OP_LTE:
|
53
|
-
%%TYPE *result = left <= right%%
|
54
|
-
break;
|
55
|
-
case '&':
|
56
|
-
%%TYPE *result = left & right%%
|
57
|
-
break;
|
58
|
-
case '|':
|
59
|
-
%%TYPE *result = left | right%%
|
60
|
-
break;
|
61
|
-
case '^':
|
62
|
-
%%TYPE *result = left ^ right%%
|
63
|
-
break;
|
64
|
-
case NM_OP_LSH:
|
65
|
-
%%TYPE *result = left << right%%
|
66
|
-
break;
|
67
|
-
case NM_OP_RSH:
|
68
|
-
%%TYPE *result = left >> right%%
|
69
|
-
break;
|
70
|
-
default:
|
71
|
-
rb_raise(rb_eNotImpError, "Unrecognized element-wise binary operator");
|
72
|
-
}
|
73
|
-
}
|
@@ -1,94 +0,0 @@
|
|
1
|
-
// numeric matrix multiply c=a*b
|
2
|
-
void %%INT_ABBREV%%_%%TYPE_ABBREV%%_numbmm_(y_size_t n, y_size_t m, YALE_PARAM A, YALE_PARAM B, YALE_PARAM C)
|
3
|
-
{
|
4
|
-
u_%%INT%% next[m];
|
5
|
-
%%TYPE%% sums[m];
|
6
|
-
|
7
|
-
%%TYPE%% v;
|
8
|
-
%%= if [:rational,:complex,:value].include?(dtype.type); "#{dtype.long_dtype.sizeof} temp1;"; end%%
|
9
|
-
|
10
|
-
u_%%INT%% head, length, temp, ndnz = 0;
|
11
|
-
u_%%INT%% jj_start, jj_end, kk_start, kk_end;
|
12
|
-
u_%%INT%% i, j, k, kk, jj;
|
13
|
-
u_%%INT%% minmn = SMMP_MIN(m,n);
|
14
|
-
|
15
|
-
u_%%INT%% *ia = (u_%%INT%%*)(A.ia),
|
16
|
-
*ja = (u_%%INT%%*)(A.ja),
|
17
|
-
*ib = (u_%%INT%%*)(B.ia),
|
18
|
-
*jb = (u_%%INT%%*)(B.ja),
|
19
|
-
*ic = (u_%%INT%%*)(C.ia),
|
20
|
-
*jc = (u_%%INT%%*)(C.ja);
|
21
|
-
%%TYPE%% *a = A.a,
|
22
|
-
*b = B.a,
|
23
|
-
*c = C.a;
|
24
|
-
|
25
|
-
for (i = 0; i < m; ++i) { // initialize scratch arrays
|
26
|
-
next[i] = U%%INT_MAX%%;
|
27
|
-
%%TYPE sums[i] = 0%%
|
28
|
-
}
|
29
|
-
|
30
|
-
for (i = 0; i < n; ++i) { // walk down the rows
|
31
|
-
head = U%%INT_MAX%%-1; // head gets assigned as whichever column of B's row j we last visited
|
32
|
-
length = 0;
|
33
|
-
|
34
|
-
jj_start = ia[i];
|
35
|
-
jj_end = ia[i+1];
|
36
|
-
|
37
|
-
for (jj = jj_start; jj <= jj_end; ++jj) { // walk through entries in each row
|
38
|
-
|
39
|
-
if (jj == jj_end) { // if we're in the last entry for this row:
|
40
|
-
if (!A.diag || i >= minmn) continue;
|
41
|
-
j = i; // if it's a new Yale matrix, and last entry, get the diagonal position (j) and entry (ajj)
|
42
|
-
%%TYPE v = a[i]%%
|
43
|
-
} else {
|
44
|
-
j = ja[jj]; // if it's not the last entry for this row, get the column (j) and entry (ajj)
|
45
|
-
%%TYPE v = a[jj]%%
|
46
|
-
}
|
47
|
-
|
48
|
-
kk_start = ib[j]; // Find the first entry of row j of matrix B
|
49
|
-
kk_end = ib[j+1];
|
50
|
-
for (kk = kk_start; kk <= kk_end; ++kk) {
|
51
|
-
|
52
|
-
if (kk == kk_end) { // Get the column id for that entry
|
53
|
-
if (!B.diag || j >= minmn) continue;
|
54
|
-
k = j;
|
55
|
-
%%TYPE sums[k] += v*b[k]%%
|
56
|
-
} else {
|
57
|
-
k = jb[kk];
|
58
|
-
%%TYPE sums[k] += v*b[kk]%%
|
59
|
-
}
|
60
|
-
|
61
|
-
if (next[k] == U%%INT_MAX%%) {
|
62
|
-
next[k] = head;
|
63
|
-
head = k;
|
64
|
-
++length;
|
65
|
-
}
|
66
|
-
}
|
67
|
-
}
|
68
|
-
|
69
|
-
for (jj = 0; jj < length; ++jj) {
|
70
|
-
if (%%TYPE sums[head] != 0%%) {
|
71
|
-
if (C.diag && head == i) {
|
72
|
-
%%TYPE c[head] = sums[head]%%
|
73
|
-
} else {
|
74
|
-
jc[n+1+ndnz] = head;
|
75
|
-
%%TYPE c[n+1+ndnz] = sums[head]%%
|
76
|
-
++ndnz;
|
77
|
-
}
|
78
|
-
}
|
79
|
-
|
80
|
-
temp = head;
|
81
|
-
head = next[head];
|
82
|
-
|
83
|
-
next[temp] = U%%INT_MAX%%;
|
84
|
-
%%TYPE sums[temp] = 0%%
|
85
|
-
}
|
86
|
-
|
87
|
-
ic[i+1] = n+1+ndnz;
|
88
|
-
}
|
89
|
-
} /* numbmm_ */
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
@@ -1,21 +0,0 @@
|
|
1
|
-
|
2
|
-
void %%TYPE_ABBREV%%_symbmm(y_size_t n, y_size_t m, YALE_PARAM A, YALE_PARAM B, YALE_PARAM C)
|
3
|
-
{
|
4
|
-
if (A.diag && A.ia != A.ja) {
|
5
|
-
fprintf(stderr, "A.diag=true, but ia!=ja. For new yale, ia must equal ja.");
|
6
|
-
return;
|
7
|
-
}
|
8
|
-
|
9
|
-
if (B.diag && B.ia != B.ja) {
|
10
|
-
fprintf(stderr, "B.diag=true, but ia!=ja. For new yale, ia must equal ja.");
|
11
|
-
return;
|
12
|
-
}
|
13
|
-
|
14
|
-
if (C.diag && C.ia != C.ja) {
|
15
|
-
fprintf(stderr, "C.diag=true, but ia!=ja. For new yale, ia must equal ja.");
|
16
|
-
return;
|
17
|
-
}
|
18
|
-
|
19
|
-
|
20
|
-
%%TYPE_ABBREV%%_symbmm_(n, m, A, B, C);
|
21
|
-
}
|
@@ -1,43 +0,0 @@
|
|
1
|
-
|
2
|
-
void %%INT_ABBREV%%_%%TYPE_ABBREV%%_numbmm(y_size_t n, y_size_t m, YALE_PARAM A, YALE_PARAM B, YALE_PARAM C)
|
3
|
-
{
|
4
|
-
if (A.diag && A.ia != A.ja) {
|
5
|
-
fprintf(stderr, "A.diag=true, but ia!=ja. For new yale, ia must equal ja.");
|
6
|
-
return;
|
7
|
-
}
|
8
|
-
|
9
|
-
if (B.diag && B.ia != B.ja) {
|
10
|
-
fprintf(stderr, "B.diag=true, but ia!=ja. For new yale, ia must equal ja.");
|
11
|
-
return;
|
12
|
-
}
|
13
|
-
|
14
|
-
if (C.diag && C.ia != C.ja) {
|
15
|
-
fprintf(stderr, "C.diag=true, but ia!=ja. For new yale, ia must equal ja.");
|
16
|
-
return;
|
17
|
-
}
|
18
|
-
|
19
|
-
%%INT_ABBREV%%_%%TYPE_ABBREV%%_numbmm_(n, m, A, B, C);
|
20
|
-
}
|
21
|
-
|
22
|
-
// Perform both the symbolic and numeric steps together.
|
23
|
-
void %%INT_ABBREV%%_%%TYPE_ABBREV%%_smmp(y_size_t n, y_size_t m, YALE_PARAM A, YALE_PARAM B, YALE_PARAM C)
|
24
|
-
{
|
25
|
-
if (A.diag && A.ia != A.ja) {
|
26
|
-
fprintf(stderr, "A.diag=true, but ia!=ja. For new yale, ia must equal ja.");
|
27
|
-
return;
|
28
|
-
}
|
29
|
-
|
30
|
-
if (B.diag && B.ia != B.ja) {
|
31
|
-
fprintf(stderr, "B.diag=true, but ia!=ja. For new yale, ia must equal ja.");
|
32
|
-
return;
|
33
|
-
}
|
34
|
-
|
35
|
-
if (C.diag && C.ia != C.ja) {
|
36
|
-
fprintf(stderr, "C.diag=true, but ia!=ja. For new yale, ia must equal ja.");
|
37
|
-
return;
|
38
|
-
}
|
39
|
-
|
40
|
-
%%INT_ABBREV%%_symbmm_(n, m, A, B, C);
|
41
|
-
%%INT_ABBREV%%_%%TYPE_ABBREV%%_numbmm_(n, m, A, B, C);
|
42
|
-
%%INT_ABBREV%%_%%TYPE_ABBREV%%_smmp_sort_columns_(n, C);
|
43
|
-
}
|
@@ -1,46 +0,0 @@
|
|
1
|
-
/////////////////////////////////////////////////////////////////////
|
2
|
-
// = NMatrix
|
3
|
-
//
|
4
|
-
// A linear algebra library for scientific computation in Ruby.
|
5
|
-
// NMatrix is part of SciRuby.
|
6
|
-
//
|
7
|
-
// NMatrix was originally inspired by and derived from NArray, by
|
8
|
-
// Masahiro Tanaka: http://narray.rubyforge.org
|
9
|
-
//
|
10
|
-
// == Copyright Information
|
11
|
-
//
|
12
|
-
// SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
|
13
|
-
// NMatrix is Copyright (c) 2012, Ruby Science Foundation
|
14
|
-
//
|
15
|
-
// Please see LICENSE.txt for additional copyright notices.
|
16
|
-
//
|
17
|
-
// == Contributing
|
18
|
-
//
|
19
|
-
// By contributing source code to SciRuby, you agree to be bound by
|
20
|
-
// our Contributor Agreement:
|
21
|
-
//
|
22
|
-
// * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
|
23
|
-
//
|
24
|
-
// == smmp2.c
|
25
|
-
//
|
26
|
-
/* ======================================================================= *
|
27
|
-
* Sparse Matrix Multiplication Package *
|
28
|
-
* Randolph E. Bank and Craig C. Douglas *
|
29
|
-
* na.bank@na-net.ornl.gov and na.cdouglas@na-net.ornl.gov *
|
30
|
-
* ======================================================================= */
|
31
|
-
// This was originally derived from the above paper, but the algorithm they
|
32
|
-
// give, in Fortran, uses 1-based indexing, and I simply could not make it
|
33
|
-
// work. So I went back to where I found the link to that paper -- SciPy's
|
34
|
-
// CSR type -- and looked at what they had done:
|
35
|
-
//
|
36
|
-
// https://github.com/scipy/scipy/blob/master/scipy/sparse/sparsetools/csr.h
|
37
|
-
//
|
38
|
-
// However, the SciPy version does not use the "new Yale" format, but rather
|
39
|
-
// "old Yale." Thus, some modification was necessary -- reincorporating some
|
40
|
-
// stuff from the original Bank & Douglas paper.
|
41
|
-
//
|
42
|
-
//
|
43
|
-
// DO NOT MODIFY smmp2.c DIRECTLY, as it is autogenerated by generator.rb.
|
44
|
-
|
45
|
-
#include <stdio.h>
|
46
|
-
#include "nmatrix.h"
|
@@ -1,56 +0,0 @@
|
|
1
|
-
//TODO: More efficient sorting algorithm than selection sort would be nice, probably.
|
2
|
-
// Remember, we're dealing with unique keys, which simplifies things.
|
3
|
-
// Doesn't have to be in-place, since we probably just multiplied and that wasn't in-place.
|
4
|
-
|
5
|
-
void %%INT_ABBREV%%_%%TYPE_ABBREV%%_smmp_sort_columns_(y_size_t n, YALE_PARAM A)
|
6
|
-
{
|
7
|
-
u_%%INT%% i, jj, jj_start, jj_end, min, min_jj;
|
8
|
-
%%TYPE%% temp_val;
|
9
|
-
|
10
|
-
u_%%INT%% *ia = (u_%%INT%%*)(A.ia),
|
11
|
-
*ja = (u_%%INT%%*)(A.ja);
|
12
|
-
%%TYPE%% *a = (%%TYPE%%*)(A.a);
|
13
|
-
|
14
|
-
for (i = 0; i < n; ++i) {
|
15
|
-
// No need to sort if there are 0 or 1 entries in the row
|
16
|
-
if (ia[i+1] - ia[i] < 2) continue;
|
17
|
-
|
18
|
-
jj_end = ia[i+1];
|
19
|
-
for (jj_start = ia[i]; jj_start < jj_end; ++jj_start) {
|
20
|
-
|
21
|
-
// If the previous min is just current-1, this key/value pair is already in sorted order.
|
22
|
-
// This follows from the unique condition on our column keys.
|
23
|
-
if (jj_start > ia[i] && min+1 == ja[jj_start]) {
|
24
|
-
min = ja[jj_start];
|
25
|
-
continue;
|
26
|
-
}
|
27
|
-
|
28
|
-
// find the minimum key (column index) between jj_start and jj_end
|
29
|
-
min = ja[jj_start];
|
30
|
-
min_jj = jj_start;
|
31
|
-
for (jj = jj_start+1; jj < jj_end; ++jj) {
|
32
|
-
if (ja[jj] < min) {
|
33
|
-
min_jj = jj;
|
34
|
-
min = ja[jj];
|
35
|
-
}
|
36
|
-
}
|
37
|
-
|
38
|
-
// if min is already first, skip this iteration
|
39
|
-
if (min_jj == jj_start) continue;
|
40
|
-
|
41
|
-
for (jj = jj_start; jj < jj_end; ++jj) {
|
42
|
-
// swap minimum key/value pair with key/value pair in the first position.
|
43
|
-
if (min_jj != jj) {
|
44
|
-
// min already = ja[min_jj], so use this as temp_key
|
45
|
-
%%TYPE temp_val = a[min_jj]%%
|
46
|
-
|
47
|
-
ja[min_jj] = ja[jj];
|
48
|
-
%%TYPE a[min_jj] = a[jj]%%
|
49
|
-
|
50
|
-
ja[jj] = min;
|
51
|
-
%%TYPE a[jj] = temp_val%%
|
52
|
-
}
|
53
|
-
}
|
54
|
-
}
|
55
|
-
}
|
56
|
-
}
|
@@ -1,54 +0,0 @@
|
|
1
|
-
|
2
|
-
// Symbolic matrix multiply c=a*b
|
3
|
-
void %%TYPE_ABBREV%%_symbmm_(y_size_t n, y_size_t m, YALE_PARAM A, YALE_PARAM B, YALE_PARAM C)
|
4
|
-
{
|
5
|
-
u_%%TYPE%% mask[m];
|
6
|
-
u_%%TYPE%% i, j, k, kk, jj, minmn, ndnz = n; /* Local variables */
|
7
|
-
|
8
|
-
u_%%TYPE%% *ia = (u_%%TYPE%%*)(A.ia),
|
9
|
-
*ja = (u_%%TYPE%%*)(A.ja),
|
10
|
-
*ib = (u_%%TYPE%%*)(B.ia),
|
11
|
-
*jb = (u_%%TYPE%%*)(B.ja),
|
12
|
-
*ic = (u_%%TYPE%%*)(C.ia);
|
13
|
-
|
14
|
-
for (j = 0; j < m; ++j)
|
15
|
-
mask[j] = U%%TYPE_MAX%%;
|
16
|
-
|
17
|
-
if (C.diag) ic[0] = n+1;
|
18
|
-
else ic[0] = 0;
|
19
|
-
|
20
|
-
minmn = SMMP_MIN(m,n);
|
21
|
-
|
22
|
-
for (i = 0; i < n; ++i) { // MAIN LOOP: through rows
|
23
|
-
|
24
|
-
for (jj = ia[i]; jj <= ia[i+1]; ++jj) { // merge row lists, walking through columns in each row
|
25
|
-
|
26
|
-
// j <- column index given by JA[jj], or handle diagonal.
|
27
|
-
if (jj == ia[i+1]) { // Don't really do it the last time -- just handle diagonals in a new yale matrix.
|
28
|
-
if (!A.diag || i >= minmn) continue;
|
29
|
-
j = i;
|
30
|
-
} else j = ja[jj];
|
31
|
-
|
32
|
-
for (kk = ib[j]; kk <= ib[j+1]; ++kk) { // Now walk through columns of row J in matrix B.
|
33
|
-
if (kk == ib[j+1]) {
|
34
|
-
if (!B.diag || j >= minmn) continue;
|
35
|
-
k = j;
|
36
|
-
} else k = jb[kk];
|
37
|
-
|
38
|
-
if (mask[k] != i) {
|
39
|
-
mask[k] = i;
|
40
|
-
++ndnz;
|
41
|
-
}
|
42
|
-
}
|
43
|
-
}
|
44
|
-
|
45
|
-
if (C.diag && !mask[i]) --ndnz;
|
46
|
-
|
47
|
-
ic[i+1] = ndnz;
|
48
|
-
}
|
49
|
-
} /* symbmm_ */
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
@@ -1,68 +0,0 @@
|
|
1
|
-
|
2
|
-
void %%INT_ABBREV%%_%%TYPE_ABBREV%%_transp_(y_size_t n, y_size_t m, YALE_PARAM A, YALE_PARAM B, bool move)
|
3
|
-
{
|
4
|
-
u_%%INT%% i, j, index;
|
5
|
-
|
6
|
-
u_%%INT%% *ia = (u_%%INT%%*)(A.ia),
|
7
|
-
*ja = (u_%%INT%%*)(A.ja),
|
8
|
-
*ib = (u_%%INT%%*)(B.ia),
|
9
|
-
*jb = (u_%%INT%%*)(B.ja);
|
10
|
-
%%TYPE%% *a = A.a,
|
11
|
-
*b = B.a;
|
12
|
-
|
13
|
-
// Clear B
|
14
|
-
for (i = 0; i < m+1; ++i)
|
15
|
-
ib[i] = 0;
|
16
|
-
if (move) {
|
17
|
-
for (i = 0; i < m+1; ++i) {
|
18
|
-
%%TYPE b[i] = 0%%
|
19
|
-
}
|
20
|
-
}
|
21
|
-
|
22
|
-
if (A.diag) ib[0] = m + 1;
|
23
|
-
else ib[0] = 0;
|
24
|
-
|
25
|
-
/* count indices for each column */
|
26
|
-
|
27
|
-
for (i = 0; i < n; ++i) {
|
28
|
-
for (j = ia[i]; j < ia[i+1]; ++j)
|
29
|
-
++(ib[ja[j]+1]);
|
30
|
-
}
|
31
|
-
|
32
|
-
for (i = 0; i < m; ++i)
|
33
|
-
ib[i+1] = ib[i] + ib[i+1];
|
34
|
-
|
35
|
-
/* now make jb */
|
36
|
-
|
37
|
-
for (i = 0; i < n; ++i) {
|
38
|
-
|
39
|
-
for (j = ia[i]; j < ia[i+1]; ++j) {
|
40
|
-
index = ja[j];
|
41
|
-
jb[ib[index]] = i;
|
42
|
-
|
43
|
-
if (move)
|
44
|
-
%%TYPE b[ib[index]] = a[j]%%
|
45
|
-
|
46
|
-
++(ib[index]);
|
47
|
-
}
|
48
|
-
}
|
49
|
-
|
50
|
-
/* now fixup ib */
|
51
|
-
|
52
|
-
for (i = m; i >= 1; --i)
|
53
|
-
ib[i] = ib[i-1];
|
54
|
-
|
55
|
-
|
56
|
-
if (A.diag) {
|
57
|
-
if (move) {
|
58
|
-
j = SMMP_MIN(n,m);
|
59
|
-
|
60
|
-
for (i = 0; i < j; ++i)
|
61
|
-
%%TYPE b[i] = a[i]%%
|
62
|
-
}
|
63
|
-
ib[0] = m + 1;
|
64
|
-
|
65
|
-
} else {
|
66
|
-
ib[0] = 0;
|
67
|
-
}
|
68
|
-
}
|