sciruby / nmatrix Goto Github PK
View Code? Open in Web Editor NEWThis project forked from translunar/nmatrix
Dense and sparse linear algebra library for Ruby via SciRuby
License: Other
This project forked from translunar/nmatrix
Dense and sparse linear algebra library for Ruby via SciRuby
License: Other
Depends upon: Issue #3: Improve SyntaxTree / C / math expression parser
The problem is described in this email thread:
Let's say you have the following matrix operation:
a = (x == y)
where x is a float64 NMatrix, y is an int8 NMatrix. This will currently cause y to be copy-casted to float64, and after the operation a will be a float64 NMatrix as well.(Note that this is distinct from x.eql?(y) which will return simply true or false.)
The alternative -- which is not implemented but could be done somewhat easily -- is to have a be an NMatrix of chars (dtype = :byte), which would then be 0 or 1.
The reason that I have it this way currently is that I figure if you're doing operations at some precision (e.g., float64), you want as few copy-casts as possible. If you're using something like a = x == y to make a an indicator variable, you don't want to have to copy-cast it to a float64 to use it later in your float64 operations.
But it's also a major space suck. Eight bytes versus one!
The problem doesn't only concern booleans. Let's say you want to take the elementwise square root of an int64 matrix. You should be able to choose the return type: who knows, maybe every value in your matrix is already a square number. It makes sense that you should be able to optionally provide a dtype.
For example, == could be shorthand for the following operation:
a.elementwise(:'==', b, :byte)
which would upcast a or b to the correct type, as always, but then return a :byte NMatrix instead of a :float64. But then the coder could still choose to get back a float64:
a.elementwise(:'==', b, :float64)
and even redefine == to always return the upcasted type.
Why does this depend on issue #3? Well, currently, the dense elementwise template looks kind of like this:
int nm_d_%%TYPE_ABBREV%%_elementwise(const %%TYPE%%* A, const %%TYPE%%* B, %%TYPE%%* C, size_t n, enum NMatrix_Ops op) {
size_t i;
switch(op) {
// ...
case NM_OP_EQEQ: // ==
for (i = 0; i < n; ++i) {
%%TYPE C[i] = A[i] == B[i]%%
}
break;
// ...
}
}
But the parser can only handle operations where A[i]
, B[i]
, and C[i]
are all the same type. Go look at blas.c
to see the output for Ruby objects, for example:
C[i] = rb_funcall(A[i], rb_intern("=="), 1, B[i]);
Well, actually, that's partially broken, I just realized. The above is what you should get, but instead the output looks like what you'd actually want if you were returning a byte matrix:
C[i] = rb_funcall(A[i], rb_intern("=="), 1, B[i]) == Qtrue;
In conclusion, SyntaxTree needs to be aware of the template types in the function header.
It may be that RDoc includes a C parser up to the job. That's one place to look. If not, we may need to write one from scratch. It's also possible that SyntaxTree could be improved.
But ultimately, we need to give more control to the user.
As BLAS defines an interface we should be able to let the user select which implementation to use at install time.
It would be sweet to have functionality in NMatrix to create a Covariance matrix and then perform Eigenvalue decomposition on such a matrix (to get back Eigenvectors and Eigenvalues).
For example, from Matlab notation:
[V,D] = eig(A)
the above creates matrices of eigenvectors V, eigenvalues D from covariance matrix A
Further processing could then diagonalize D assuming a square matrix, for example:
eigenvalues = diag(D)
where a function diag() puts D on the main diagonal
Right now when we write a generic function for some kind of dtype or itype data, the inputs and outputs must be stored in void*
.
We should at some point switch to opaque structs. This gives us some degree of type safety, may help prevent future bugs.
Originally posted here: SciRuby/sciruby#23 by @tdy.
Hi, I tried loading some of my mat data like this:
require "nmatrix"
NMatrix::IO::Matlab::load_mat("r03_12_1.mat")
I was getting some strange values back, so I used some dummy data just for testing purposes. It seems that everything is fine as long as the original data only have integers, but as soon as any doubles are introduced, I get weird results.
For example, #load_mat
is showing -1.5423487136706484e-180
, but in MATLAB it's 1.1
. Not sure if something is buggy or if I'm just missing something obvious.
Original data were from:
Trying to parse the data on:
Thanks!
Update:
I had previously only tried dense matrices, but I just tried some sparse matrices. I only attached the simple test cases here because the real data are patient protected. I can throw together some fake data that are closer in form to what I’ll actually be using if it would help.
In MATLAB:
x = [1 2;3 4]; % saved as x.mat (attached)
y = [1.1 2;3 4]; % saved as y.mat (attached)
x_sparse = sparse(x); % saved as x_sparse.mat (attached)
y_sparse = sparse(y); % saved as y_sparse.mat (attached)
In MRI:
pry(main)> NMatrix::IO::Matlab::load_mat(“x.mat”)
=> [1, 2] [3, 4]pry(main)> NMatrix::IO::Matlab::load_mat(“y.mat”)
=> [-1.5423487136706484e-180, 3.16e-322] [1.0435e-320, 2.0553e-320]pry(main)> NMatrix::IO::Matlab::load_mat(“x_sparse.mat”)
indices: Requesting itype :uint8
No repack
=> [1.0, 3.0] [2.0, 4.0]pry(main)> NMatrix::IO::Matlab::load_mat(“y_sparse.mat”)
indices: Requesting itype :uint8
No repack
=> [1.1, 3.0] [2.0, 4.0]
This method does not seem to actually be present anywhere in the source code - in any case it's not working:
http://sciruby.com/nmatrix/docs/NMatrix.html#method-i-each_stored_with_indices
irb(main):048:0> NMatrix.new(:yale, 10, :byte).each_stored_with_indices
NoMethodError: undefined method `each_stored_with_indices' for #<NMatrix:0x007fcca296f3b8>
from (irb):48
from /Users/alex/.rbenv/versions/1.9.3-p392/bin/irb:12:in `<main>'
There was a discussion in the mailing list about installation of NMatrix 0.0.3.
I think we should add dir_config
calls so an user can configure the installation from the command line with --with-lib-dir, --with-lib-include and --with-lib-lib. There's a simple explanation and example of it in this blog post about C extensions. And the Ruby OpenCV wrapper uses it the same way.
It's a simple change, but I need to test it locally before sending a PR. If I'm doing a mistake here, please correct me.
If you guys can think about other ways to improve the installation process (not just explain how to do it), please post here.
This may require some design and discussion.
What dtype is returned by matrix inversion of an int? Something rational or some type of float matrix? Or should inversion simply be disallowed on int matrices? It doesn't make sense to return an integer, as it'll nearly always be all zeroes, and probably confuse the coder/user.
Regardless, we need matrix inversion pretty desperately. It's a pretty basic matrix operation.
It'd be nice if exponents could also be implemented, since the syntax will likely be similar. Is the return type similar?
I can't seem to get NMatrix to compile. I've got ATLAS/LAPACK and Green Shoes installed. I've been able to get SciRuby installed. But for some reason, I can't get NMatrix to compile.
I'm using g++ 4.2 on Mac OSX 10.7.
I've also tried following this post: http://blog.kc2vjw.com/tag/nmatrix/
Making identifier out of C[i]
Making identifier out of A[i]
Making identifier out of B[i]
compiling nmatrix.c
In file included from nmatrix.c:31:
nmatrix.h:32:19: error: cblas.h: No such file or directory
In file included from nmatrix.c:31:
nmatrix.h:697: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:697: warning: its scope is only this definition or declaration, which is probably not what you want
nmatrix.h:698: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:699: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:700: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:701: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:702: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:703: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:704: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:705: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:706: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:707: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:708: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:709: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:710: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:711: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:712: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:713: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:768: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:768: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:769: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:769: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:770: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:770: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:771: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:771: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:772: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:772: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:773: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:773: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:774: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:774: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:775: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:775: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:776: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:776: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:777: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:777: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:778: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:778: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:779: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:779: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:780: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:780: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:781: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:781: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:782: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:782: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:783: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:783: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:784: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:784: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:785: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:785: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:786: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:786: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:787: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:787: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:788: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:788: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:789: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:789: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:790: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:790: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:791: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:791: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.h:792: warning: ‘enum CBLAS_TRANSPOSE’ declared inside parameter list
nmatrix.h:792: warning: ‘enum CBLAS_ORDER’ declared inside parameter list
nmatrix.c: In function ‘cblas_params_for_multiply’:
nmatrix.c:192: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:193: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:196: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:201: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:202: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:204: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:205: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:216: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:217: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:218: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:219: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c: In function ‘multiply_matrix_dense_casted’:
nmatrix.c:290: error: ‘CblasRowMajor’ undeclared (first use in this function)
nmatrix.c:290: error: (Each undeclared identifier is reported only once
nmatrix.c:290: error: for each function it appears in.)
nmatrix.c:290: error: ‘CblasNoTrans’ undeclared (first use in this function)
nmatrix.c: At top level:
nmatrix.c:336: warning: initialization from incompatible pointer type
nmatrix.c:339: warning: initialization from incompatible pointer type
nmatrix.c:358: warning: excess elements in array initializer
nmatrix.c:358: warning: (near initialization for ‘DenseElementwiseFuncs’)
nmatrix.c:366: warning: initialization from incompatible pointer type
nmatrix.c:366: warning: initialization from incompatible pointer type
nmatrix.c:366: warning: initialization from incompatible pointer type
nmatrix.c:366: warning: initialization from incompatible pointer type
nmatrix.c:366: warning: initialization from incompatible pointer type
nmatrix.c:366: warning: initialization from incompatible pointer type
nmatrix.c:367: warning: initialization from incompatible pointer type
nmatrix.c:367: warning: initialization from incompatible pointer type
nmatrix.c:367: warning: initialization from incompatible pointer type
nmatrix.c:367: warning: initialization from incompatible pointer type
nmatrix.c:367: warning: initialization from incompatible pointer type
nmatrix.c:367: warning: initialization from incompatible pointer type
nmatrix.c:368: warning: initialization from incompatible pointer type
nmatrix.c:368: warning: initialization from incompatible pointer type
nmatrix.c:369: warning: initialization from incompatible pointer type
nmatrix.c:369: warning: initialization from incompatible pointer type
nmatrix.c:370: warning: initialization from incompatible pointer type
nmatrix.c:370: warning: initialization from incompatible pointer type
nmatrix.c:371: warning: initialization from incompatible pointer type
nmatrix.c:371: warning: initialization from incompatible pointer type
nmatrix.c:372: warning: initialization from incompatible pointer type
nmatrix.c:372: warning: initialization from incompatible pointer type
nmatrix.c:373: warning: initialization from incompatible pointer type
nmatrix.c:373: warning: initialization from incompatible pointer type
nmatrix.c:374: warning: initialization from incompatible pointer type
nmatrix.c:374: warning: initialization from incompatible pointer type
nmatrix.c:375: warning: initialization from incompatible pointer type
nmatrix.c:375: warning: initialization from incompatible pointer type
nmatrix.c:376: warning: initialization from incompatible pointer type
nmatrix.c:376: warning: initialization from incompatible pointer type
nmatrix.c:377: warning: initialization from incompatible pointer type
nmatrix.c:377: warning: initialization from incompatible pointer type
nmatrix.c:378: warning: initialization from incompatible pointer type
nmatrix.c:378: warning: initialization from incompatible pointer type
nmatrix.c:379: warning: initialization from incompatible pointer type
nmatrix.c:379: warning: initialization from incompatible pointer type
nmatrix.c:428: warning: initialization from incompatible pointer type
nmatrix.c:429: warning: initialization from incompatible pointer type
nmatrix.c:431: warning: initialization from incompatible pointer type
nmatrix.c:479: warning: initialization from incompatible pointer type
nmatrix.c:480: warning: initialization from incompatible pointer type
nmatrix.c:482: warning: initialization from incompatible pointer type
nmatrix.c:486: warning: initialization from incompatible pointer type
nmatrix.c:487: warning: initialization from incompatible pointer type
nmatrix.c:489: warning: initialization from incompatible pointer type
nmatrix.c:494: warning: initialization from incompatible pointer type
nmatrix.c:494: warning: initialization from incompatible pointer type
nmatrix.c:494: warning: initialization from incompatible pointer type
nmatrix.c:495: warning: initialization from incompatible pointer type
nmatrix.c:495: warning: initialization from incompatible pointer type
nmatrix.c:495: warning: initialization from incompatible pointer type
nmatrix.c:496: warning: initialization from incompatible pointer type
nmatrix.c:496: warning: initialization from incompatible pointer type
nmatrix.c:496: warning: initialization from incompatible pointer type
nmatrix.c:501: warning: initialization from incompatible pointer type
nmatrix.c:502: warning: initialization from incompatible pointer type
nmatrix.c:504: warning: initialization from incompatible pointer type
nmatrix.c: In function ‘gemm_op_sym’:
nmatrix.c:1412: error: ‘CblasNoTrans’ undeclared (first use in this function)
nmatrix.c:1413: error: ‘CblasTrans’ undeclared (first use in this function)
nmatrix.c:1414: error: ‘CblasConjTrans’ undeclared (first use in this function)
nmatrix.c:1417: warning: control reaches end of non-void function
nmatrix.c: In function ‘nm_cblas_gemm’:
nmatrix.c:1467: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:1468: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:1469: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:1470: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:1527: error: ‘CblasRowMajor’ undeclared (first use in this function)
nmatrix.c: In function ‘nm_cblas_gemv’:
nmatrix.c:1580: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:1581: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:1582: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:1583: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:1596: error: ‘CblasRowMajor’ undeclared (first use in this function)
nmatrix.c: In function ‘nm_transpose_new’:
nmatrix.c:1830: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:1830: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:1830: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:1830: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:1854: warning: implicit conversion shortens 64-bit value into a 32-bit value
nmatrix.c:1854: warning: implicit conversion shortens 64-bit value into a 32-bit value
make: *** [nmatrix.o] Error 1
Right now, only xgemm, xgemv, xgetrf, laswp, idamax, and a few others are implemented.
It'd be great if we could expose all of the CBLAS and ATLAS-CLAPACK functions.
Usually this means writing a templated version of the function in math.h which works for rational types (and possibly integers too). You override the templates for float, double, Complex64, and Complex128 and have those call clapack_xxxxx
or cblas_xxxxx
.
I usually just derive my templated version from whatever is in ATLAS' source (using the most recent version).
If I can't do that, e.g. with xgemm, I look at LAPACK or I use f2c
to convert the original DGEMM.F
(for example) to a C file, then I go through and rewrite it in a C++ style and make it maintainable.
There are some much faster algorithms for generic matrix multiplication than the trivial one from Netlib. ATLAS implements one using a lot of #define statements. It'd be good if we could do the same thing in our gemm.template.c
generic version, so that we have fast multiplication for rational, integer, and Ruby obj matrices.
This particular ticket involves some research. A good place to start would be Strassen's algorithm.
I'd like to be able to, for example, divide a vector by its norm to normalize the vector, e.g.:
require 'nmatrix'
matrix = NMatrix.new([1,5], [1,2,3,4,5], :float64)
norm = Math.sqrt(matrix.dot(matrix.transpose)[0,0])
matrix = matrix / norm
Right now the last step has to be:
(0...matrix.shape[1]).each do |j|
matrix[0,j] /= norm
end
I assume this is less efficient to do in Ruby-land.
I found this problem:
[3] pry(main)> m = NMatrix.new([3,3], (0..9).to_a).cast(:yale, :int32)
=> [0, 1, 2] [3, 4, 5] [6, 7, 8]
[4] pry(main)> m.cast(:list, :int32)
=> [0, 1, 2] [0, 0, 0] [0, 0, 0]
There are many java matrix libraries available. Why not simply build on top of one of those?
Yes, now you must use JRuby instead of C Ruby. However, you can build the library more quickly, gain critical mass for later building the CRuby version, etc.
Elementwise operations on list matrices are currently broken (and disabled in v0.0.2).
The following operation gives an incorrect result:
n = NMatrix.new(:list, 3, 0, :int64)
m = NMatrix.new(:list, 3, 0, :int64)
n[0,0] = 2
m[1,1] = 20
r = n + m
The current result is [0, 0, 0], [0, 20, 0], [0, 0, 0]
. If instead m[0,0] is set, the output will be correct. Basically, it seems to only be calculating a row if both matrices contain such a row, which is incorrect.
Right now all elementwise operations use a single function that looks like this:
C = OP(A,B)
where A, B, and C must all have the same type.
That includes the unary operations, boolean-style comparisons, and modulus.
If you try to do, for example, A*B, where A and B are different types, they will be upcast to a common type, and that type will be returned.
These operations need to be split up. It doesn't make sense to do x % y where both x and y are complex, for example. We need to allow for operations where the types cannot simply be upcast.
It also maybe doesn't make sense for the operation z = x == y, where z, x, and y are all rational128. Instead, z should contain bytes or maybe Ruby objects. Or if this is to be kept the same, a convincing argument should be made for leaving it as-is.
Here's the output. The problem seems to be duplicate symbols in the linking shared-object nmatrix.bundle
step. Any ideas?
rake/gempackagetask is deprecated. Use rubygems/package_task instead
mkdir -p tmp/x86_64-darwin11.4.0/nmatrix/1.9.3
cd tmp/x86_64-darwin11.4.0/nmatrix/1.9.3
/Users/james/.rvm/rubies/ruby-1.9.3-p194/bin/ruby -I. ../../../../ext/nmatrix/extconf.rb
checking for clapack_dgetrf() in -llapack... no
checking for clapack.h... no
checking for cblas_dgemm() in -lcblas... yes
checking for ATL_dgemmNN() in -latlas... no
checking for cblas.h... yes
creating nmatrix_config.h
creating Makefile
cd -
cd tmp/x86_64-darwin11.4.0/nmatrix/1.9.3
make
compiling ../../../../ext/nmatrix/nmatrix.cpp
In file included from ../../../../ext/nmatrix/storage/storage.h:50:0,
from ../../../../ext/nmatrix/util/io.h:38,
from ../../../../ext/nmatrix/nmatrix.cpp:49:
../../../../ext/nmatrix/storage/yale.h:104:18: warning: inline function 'size_t nm_yale_storage_get_size(const YALE_STORAGE*)' used but never defined [enabled by default]
../../../../ext/nmatrix/nmatrix.cpp:152:16: warning: 'dtype_t dtype_guess(VALUE)' declared 'static' but never defined [-Wunused-function]
compiling ../../../../ext/nmatrix/ruby_constants.cpp
compiling ../../../../ext/nmatrix/data/data.cpp
compiling ../../../../ext/nmatrix/util/io.cpp
../../../../ext/nmatrix/util/io.cpp: In function 'VALUE nm_rbstring_merge(VALUE, VALUE, VALUE, VALUE)':
../../../../ext/nmatrix/util/io.cpp:270:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
compiling ../../../../ext/nmatrix/util/math.cpp
compiling ../../../../ext/nmatrix/util/sl_list.cpp
compiling ../../../../ext/nmatrix/storage/common.cpp
compiling ../../../../ext/nmatrix/storage/storage.cpp
compiling ../../../../ext/nmatrix/storage/dense.cpp
../../../../ext/nmatrix/storage/dense.cpp: In instantiation of 'bool nm::dense_storage::is_hermitian(const DENSE_STORAGE*, int) [with DType = nm::Complex<float>]':
../../../../ext/nmatrix/storage/dense.cpp:285:65: required from here
../../../../ext/nmatrix/storage/dense.cpp:547:17: warning: address requested for 'complex_conj', which is declared 'register' [-Wextra]
../../../../ext/nmatrix/storage/dense.cpp: In instantiation of 'bool nm::dense_storage::is_hermitian(const DENSE_STORAGE*, int) [with DType = nm::Complex<double>]':
../../../../ext/nmatrix/storage/dense.cpp:288:66: required from here
../../../../ext/nmatrix/storage/dense.cpp:547:17: warning: address requested for 'complex_conj', which is declared 'register' [-Wextra]
compiling ../../../../ext/nmatrix/storage/yale.cpp
../../../../ext/nmatrix/storage/yale.cpp: In function 'void* nm_yale_storage_get(STORAGE*, SLICE*)':
../../../../ext/nmatrix/storage/yale.cpp:1196:17: warning: unused variable 's' [-Wunused-variable]
../../../../ext/nmatrix/storage/yale.cpp: At global scope:
../../../../ext/nmatrix/storage/yale.cpp:1250:22: warning: 'YALE_STORAGE* nm_copy_alloc_struct(const YALE_STORAGE*, dtype_t, size_t, size_t)' defined but not used [-Wunused-function]
compiling ../../../../ext/nmatrix/storage/list.cpp
linking shared-object nmatrix.bundle
duplicate symbol nm::operator-(nm::RubyObject const&) in:
nmatrix.o
data/data.o
duplicate symbol nm::operator-(nm::RubyObject const&) in:
nmatrix.o
util/io.o
duplicate symbol nm::operator-(nm::RubyObject const&) in:
nmatrix.o
util/math.o
duplicate symbol nm::operator-(nm::RubyObject const&) in:
nmatrix.o
util/sl_list.o
duplicate symbol nm::operator-(nm::RubyObject const&) in:
nmatrix.o
storage/common.o
duplicate symbol nm::operator-(nm::RubyObject const&) in:
nmatrix.o
storage/dense.o
duplicate symbol nm::operator-(nm::RubyObject const&) in:
nmatrix.o
storage/storage.o
duplicate symbol nm::operator-(nm::RubyObject const&) in:
nmatrix.o
storage/yale.o
duplicate symbol nm::operator-(nm::RubyObject const&) in:
nmatrix.o
storage/list.o
ld: 9 duplicate symbols for architecture x86_64
collect2: error: ld returned 1 exit status
make: *** [nmatrix.bundle] Error 1
rake aborted!
Command failed with status (2): [make...]
Tasks: TOP => compile => compile:x86_64-darwin11.4.0 => compile:nmatrix:x86_64-darwin11.4.0 => copy:nmatrix:x86_64-darwin11.4.0:1.9.3 => tmp/x86_64-darwin11.4.0/nmatrix/1.9.3/nmatrix.bundle
(See full trace by running task with --trace)
m = NMatrix.new([3,3], [0,1,2,3,4,5,6,7,8], :float64)
m[0...3,0].pp
yields:
[0.0]
[3.0]
[6.0]
but:
m[0...3,0].transpose.pp
yields
[0.0, 1.0, 2.0]
I would expect it to yield:
[0.0, 3.0, 6.0]
I occasionally see this error when performing matrix operations on yale matrices:
malloc: *** error for object 0x7f95dd830ca8: incorrect checksum for freed object - object was probably modified after being freed.
It's intermittent, and I can't reliable reproduce it.
Hello , i am using nmatrix for a project i am working on because it is really important to use sparse vectors. The project required that i had two categories of vectors : category A with about 4500 vectors and category B with 3500 vectors . The dimensions of the vectors are [1,8000] and [8000,1] . At some point i had to calculate the dot of every vector of category B with every vector of the category A... I designed my code and run it .. I noticed a memory consumption about 800mb . I thought i was doing something wrong until i isolated the dot operation of 2 yale vectors on a single irb session.
1.9.3-p194 :002 > require 'nmatrix'
=> true
1.9.3-p194 :003 > y = NMatrix.new(:yale , [80,1] ,:float32)
=> #<NMatrix:0x007f8f830631e0shape:[80,1] dtype:float32 stype:yale capacity:161>
1.9.3-p194 :004 > x = NMatrix.new(:yale , [1,80] ,:float32)
=> #<NMatrix:0x007f8f83052318shape:[1,80] dtype:float32 stype:yale capacity:3>
1.9.3-p194 :005 > 15000000.times do
1.9.3-p194 :006 > x.dot(y)
1.9.3-p194 :007?> end
at the point i created the matrices (they are completely empty on the test ) the ruby process consumes about 10mb of memory. When the code execution finished , the memory consumption was 245 mb. Am i doing something that forces this behaviour , or is it caused by something else ?
Matz himself said that autoload will be removed from the language and he "strongly discourages the use of autoload in any standard library". That said, what do you think?
I thought about removing it, but preferred to talk about it here first. It's used in lib/nmatrix.rb and lib/nmatrix/nmatrix.rb.
Of course it isn't an urgent issue.
LAPACK is already highly optimized and using it would allow us to support a lot of LA operations quickly.
Sorry to keep bothering you, hopefully I can solve this one myself too. FYI I am spending a long time trying to figure these issues out myself before opening issues here, it's just that I seem to solve them just after opening an issue.
Anyway, matrix multiplication with NMatrix seems to be behaving completely differently in NMatrix than pure ruby Matrix or scipy matrix:
require 'matrix'
m = Matrix[[1, 2], [3, 4]]
n = Matrix[[5, 6], [7, 8]]
result = m * n
result.each_with_index do |v, i, j|
puts "(#{i}, #{j}) #{v}" if v > 0
end
# result:
# (0, 0) 19
# (0, 1) 22
# (1, 0) 43
# (1, 1) 50
from scipy import matrix
m = matrix([[1, 2], [3, 4]])
n = matrix([[5, 6], [7, 8]])
print m * n
# [[19 22]
# [43 50]]
require 'nmatrix'
puts "nmatrix\n"
m = N[[1, 2], [3, 4]]
n = N[[5, 6], [7, 8]]
result = n * m
result.each_stored_with_indices do |v, i, j|
puts "(#{i}, #{j}) #{v}" if v > 0
end
# result:
# (0, 0) 5
# (0, 1) 12
# (1, 0) 21
# (1, 1) 32
I'm sure I'm just doing something stupid, do you have any idea what might cause this? I think it might be useful to have a wiki page detailing differences from SciPy or pure ruby matrices, which I'd be happy to write if it doesn't exist, or link to if the information is in the docs somewhere but I've missed it
What does this error mean?
StorageTypeError: conversion failed; capacity of 14 requested, max allowable is 6
Here's the code:
m = NMatrix.new(:list, [3, 5], :float64)
m.slice(0, 0...m.shape[1]).cast(:yale, :float64) # no error
c = 0
(1...m.shape[0]).each do |i|
(0...m.shape[1]).each do |j|
m[i, j] = (c+=1)
end
end
m.slice(0, 0...m.shape[1]).cast(:yale, :float64) # raises error
If a matrix is too dense, does casting it to :yale raise an error?
In this code, the slice that is being cast is actually all zeroes! I find it odd that if I take a slice of a dense matrix, then I get an error, even if the slice is sparse...
>> a = NMatrix.random(3)
=> #<NMatrix:0x007f850c97a408shape:[3,3] dtype:float64 stype:dense>
>> x = NVector.random(3)
=> #<NVector:0x007f850c96d028shape:[3,1] dtype:float64 stype:dense orientation:column>
>> NMatrix::BLAS.gemv(a, x)
/Users/carlosagarie/.rvm/gems/ruby-1.9.3-p194@nmatrix/gems/nmatrix-0.0.2/lib/nmatrix/blas.rb:64: [BUG] Segmentation fault
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.4.0]
# frame information and much more
I remember that BLAS was a bit dangerous to use (right?), but why isn't it working this way?
I have exposed clapack_xgetri
and clapack_xpotri
for float, double, complex, and double complex.
I've also converted the ATLAS version of the GETRI algorithm to C++ templates (in util/math
). Unfortunately, I could not expose that version for the other dtypes because it uses macros (NB
, MulByNB
, DivByNB
) which are set by ATLAS during compilation as part of its optimization. I have not tried to convert POTRI, but it appears to have similar dependencies to GETRI.
The LAPACK dgetri.f
and dpotri.f
algorithms won't work for our purposes since they're column-major.
So someone needs to write a row-major GETRI/POTRI, or find some way to work around the aforementioned macro issues.
A consequence of the status quo: GETRI and POTRI will work on machines which have CLAPACK as part of ATLAS. That means no luck for most Mac users at the moment.
You can't currently have both NArray and NMatrix installed. This is a problem, since people may need to use both on the same system.
When I try to fill a sparse matrix with floats, I get segmentation faults. I printed out the i
and j
variables to see if it was trying to write outside the dimensions of the matrix, but it's not the case. I print out the value that I was trying to assign to the matrix cell, but it is 0.0
, so not outside the float range.
My code looks like:
matrix = NMatrix.new(:list, [row_size, column_size], :float64)
rows.each_with_index do |x,i|
columns.each_with_index do |y,j|
matrix[i, j] = some_method(x, y)
end
end
With :list
I get:
irb(77457,0x7fff7c400960) malloc: *** error for object 0x7fff5fe83440: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
With :yale
I get:
(irb):14: [BUG] Segmentation fault
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.4.0]
-- Control frame information -----------------------------------------------
c:0037 p:---- s:0123 b:0123 l:000122 d:000122 CFUNC :[]=
c:0036 p:0073 s:0117 b:0116 l:000618 d:000115 BLOCK (irb):14
c:0035 p:---- s:0111 b:0111 l:000110 d:000110 FINISH
c:0034 p:---- s:0109 b:0109 l:000098 d:000108 IFUNC
c:0033 p:---- s:0107 b:0107 l:000102 d:000106 IFUNC
c:0032 p:---- s:0105 b:0105 l:000104 d:000104 CFUNC :each
c:0031 p:---- s:0103 b:0103 l:000102 d:000102 CFUNC :each_with_index
c:0030 p:---- s:0101 b:0101 l:000100 d:000100 CFUNC :each
c:0029 p:---- s:0099 b:0099 l:000098 d:000098 CFUNC :map
c:0028 p:0040 s:0096 b:0096 l:000618 d:000095 BLOCK (irb):11
c:0027 p:---- s:0091 b:0091 l:000090 d:000090 FINISH
c:0026 p:---- s:0089 b:0089 l:000084 d:000088 IFUNC
c:0025 p:---- s:0087 b:0087 l:000086 d:000086 CFUNC :each
c:0024 p:---- s:0085 b:0085 l:000084 d:000084 CFUNC :each_with_index
c:0023 p:0017 s:0082 b:0082 l:000618 d:000081 EVAL (irb):9
c:0022 p:---- s:0080 b:0080 l:000079 d:000079 FINISH
c:0021 p:---- s:0078 b:0078 l:000077 d:000077 CFUNC :eval
c:0020 p:0028 s:0071 b:0071 l:000070 d:000070 METHOD /Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb/workspace.rb:80
c:0019 p:0033 s:0064 b:0063 l:000062 d:000062 METHOD /Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb/context.rb:254
c:0018 p:0031 s:0058 b:0058 l:001e68 d:000057 BLOCK /Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb.rb:159
c:0017 p:0042 s:0050 b:0050 l:000049 d:000049 METHOD /Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb.rb:273
c:0016 p:0011 s:0045 b:0045 l:001e68 d:000044 BLOCK /Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb.rb:156
c:0015 p:0144 s:0041 b:0041 l:000024 d:000040 BLOCK /Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb/ruby-lex.rb:243
c:0014 p:---- s:0038 b:0038 l:000037 d:000037 FINISH
c:0013 p:---- s:0036 b:0036 l:000035 d:000035 CFUNC :loop
c:0012 p:0009 s:0033 b:0033 l:000024 d:000032 BLOCK /Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb/ruby-lex.rb:229
c:0011 p:---- s:0031 b:0031 l:000030 d:000030 FINISH
c:0010 p:---- s:0029 b:0029 l:000028 d:000028 CFUNC :catch
c:0009 p:0023 s:0025 b:0025 l:000024 d:000024 METHOD /Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb/ruby-lex.rb:228
c:0008 p:0046 s:0022 b:0022 l:001e68 d:001e68 METHOD /Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb.rb:155
c:0007 p:0011 s:0019 b:0019 l:0011d8 d:000018 BLOCK /Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb.rb:70
c:0006 p:---- s:0017 b:0017 l:000016 d:000016 FINISH
c:0005 p:---- s:0015 b:0015 l:000014 d:000014 CFUNC :catch
c:0004 p:0183 s:0011 b:0011 l:0011d8 d:0011d8 METHOD /Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb.rb:69
c:0003 p:0142 s:0006 b:0006 l:0023e8 d:001458 EVAL /Users/james/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:0023e8 d:0023e8 TOP
-- Ruby level backtrace information ----------------------------------------
/Users/james/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb.rb:69:in `start'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb.rb:69:in `catch'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb.rb:70:in `block in start'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb.rb:155:in `eval_input'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `each_top_level_statement'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `catch'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `block in each_top_level_statement'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `loop'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb/ruby-lex.rb:243:in `block (2 levels) in each_top_level_statement'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb.rb:156:in `block in eval_input'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb.rb:273:in `signal_status'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb.rb:159:in `block (2 levels) in eval_input'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb/context.rb:254:in `evaluate'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb/workspace.rb:80:in `evaluate'
/Users/james/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/irb/workspace.rb:80:in `eval'
(irb):9:in `irb_binding'
(irb):9:in `each_with_index'
(irb):9:in `each'
(irb):11:in `block in irb_binding'
(irb):11:in `map'
(irb):11:in `each'
(irb):11:in `each_with_index'
(irb):11:in `each'
(irb):14:in `block (2 levels) in irb_binding'
(irb):14:in `[]='
-- C level backtrace information -------------------------------------------
See Crash Report log file under ~/Library/Logs/CrashReporter or
/Library/Logs/CrashReporter, for the more detail of.
-- Other runtime information -----------------------------------------------
I'm fairly certain gemm
is properly exposed, but the tests are failing. If I remember correctly, it's just that the tests are wrong. It'd be great if someone who actually uses complex matrix multiplication could write some good specs to make sure it's working properly.
I cannot get this working on OS X.
First I tried "gem install nmatrix". This resulted in the error about gcc not being up to date. I then used the script to install a later version of gcc. After a lot of fiddling I managed to get the gem install command to use that compiler. This gave the following error:
util/math.h:72:21: fatal error: cblas.h: No such file or directory
So then in #34 I found a reference to some environment variables:
export C_INCLUDE_PATH=/System/Library/Frameworks/Accelerate.framework/Versions/Current/Frameworks/vecLib.framework/Versions/Current/Headers/
export CPLUS_INCLUDE_PATH=/System/Library/Frameworks/Accelerate.framework/Versions/Current/Frameworks/vecLib.framework/Versions/Current/Headers/
Then I get these results:
compiling nmatrix.cpp
In file included from nmatrix.cpp:49:0:
util/math.h: In function ‘int nm::math::potrf(CBLAS_ORDER, CBLAS_UPLO, int, DType*, int) [with DType = float]’:
util/math.h:1568:47: error: ‘clapack_spotrf’ was not declared in this scope
util/math.h: In function ‘int nm::math::potrf(CBLAS_ORDER, CBLAS_UPLO, int, DType*, int) [with DType = double]’:
util/math.h:1573:47: error: ‘clapack_dpotrf’ was not declared in this scope
util/math.h: In function ‘int nm::math::potrf(CBLAS_ORDER, CBLAS_UPLO, int, DType*, int) [with DType = nm::Complex<float>]’:
util/math.h:1578:72: error: ‘clapack_cpotrf’ was not declared in this scope
util/math.h: In function ‘int nm::math::potrf(CBLAS_ORDER, CBLAS_UPLO, int, DType*, int) [with DType = nm::Complex<double>]’:
util/math.h:1583:72: error: ‘clapack_zpotrf’ was not declared in this scope
util/math.h: In function ‘void nm::math::lauum(CBLAS_ORDER, CBLAS_UPLO, int, float*, int)’:
util/math.h:2093:40: error: there are no arguments to ‘clapack_slauum’ that depend on a template parameter, so a declaration of ‘clapack_slauum’ must be available [-fpermissive]
util/math.h:2093:40: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
util/math.h: In function ‘void nm::math::lauum(CBLAS_ORDER, CBLAS_UPLO, int, double*, int)’:
util/math.h:2098:40: error: there are no arguments to ‘clapack_dlauum’ that depend on a template parameter, so a declaration of ‘clapack_dlauum’ must be available [-fpermissive]
util/math.h: In function ‘void nm::math::lauum(CBLAS_ORDER, CBLAS_UPLO, int, nm::Complex64*, int)’:
util/math.h:2103:40: error: there are no arguments to ‘clapack_clauum’ that depend on a template parameter, so a declaration of ‘clapack_clauum’ must be available [-fpermissive]
util/math.h: In function ‘void nm::math::lauum(CBLAS_ORDER, CBLAS_UPLO, int, nm::Complex128*, int)’:
util/math.h:2108:40: error: there are no arguments to ‘clapack_zlauum’ that depend on a template parameter, so a declaration of ‘clapack_zlauum’ must be available [-fpermissive]
util/math.h: In function ‘int nm::math::getri(CBLAS_ORDER, int, DType*, int, const int*) [with DType = float]’:
util/math.h:2220:47: error: ‘clapack_sgetri’ was not declared in this scope
util/math.h: In function ‘int nm::math::getri(CBLAS_ORDER, int, DType*, int, const int*) [with DType = double]’:
util/math.h:2225:47: error: ‘clapack_dgetri’ was not declared in this scope
util/math.h: In function ‘int nm::math::getri(CBLAS_ORDER, int, DType*, int, const int*) [with DType = nm::Complex<float>]’:
util/math.h:2230:72: error: ‘clapack_cgetri’ was not declared in this scope
util/math.h: In function ‘int nm::math::getri(CBLAS_ORDER, int, DType*, int, const int*) [with DType = nm::Complex<double>]’:
util/math.h:2235:72: error: ‘clapack_zgetri’ was not declared in this scope
util/math.h: In function ‘int nm::math::potri(CBLAS_ORDER, CBLAS_UPLO, int, DType*, int) [with DType = float]’:
util/math.h:2250:47: error: ‘clapack_spotri’ was not declared in this scope
util/math.h: In function ‘int nm::math::potri(CBLAS_ORDER, CBLAS_UPLO, int, DType*, int) [with DType = double]’:
util/math.h:2255:47: error: ‘clapack_dpotri’ was not declared in this scope
util/math.h: In function ‘int nm::math::potri(CBLAS_ORDER, CBLAS_UPLO, int, DType*, int) [with DType = nm::Complex<float>]’:
util/math.h:2260:72: error: ‘clapack_cpotri’ was not declared in this scope
util/math.h: In function ‘int nm::math::potri(CBLAS_ORDER, CBLAS_UPLO, int, DType*, int) [with DType = nm::Complex<double>]’:
util/math.h:2265:72: error: ‘clapack_zpotri’ was not declared in this scope
nmatrix.cpp: In function ‘VALUE nm_factorize_lu(VALUE)’:
nmatrix.cpp:1555:7: error: ‘clapack_cgetrf’ was not declared in this scope
nmatrix.cpp:1555:23: error: ‘clapack_zgetrf’ was not declared in this scope
make: *** [nmatrix.o] Error 1
How do I get the gem installed?
Installing from git:
Using nmatrix (0.0.2) from https://github.com/SciRuby/nmatrix.git (at master) with native extensions
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.
/Users/james/.rvm/rubies/ruby-1.9.3-p194/bin/ruby extconf.rb
checking for clapack_dgetrf() in -llapack... no
checking for clapack.h... yes
checking for cblas_dgemm() in -lcblas... yes
checking for ATL_dgemmNN() in -latlas... no
checking for cblas.h... yes
creating nmatrix_config.h
creating Makefile
make
compiling nmatrix.cpp
cc1plus: error: unrecognized command line option "-std=c++0x"
make: *** [nmatrix.o] Error 1
Gem files will remain installed in /Users/james/.rvm/gems/ruby-1.9.3-p194/bundler/gems/nmatrix-506812677faa for inspection.
Results logged to /Users/james/.rvm/gems/ruby-1.9.3-p194/bundler/gems/nmatrix-506812677faa/ext/nmatrix/gem_make.out
Downloading the git repository and running rake compile
(with or without bundle exec
) gives a similar error:
rake/gempackagetask is deprecated. Use rubygems/package_task instead
mkdir -p tmp/x86_64-darwin11.4.0/nmatrix/1.9.3
cd tmp/x86_64-darwin11.4.0/nmatrix/1.9.3
/Users/james/.rvm/rubies/ruby-1.9.3-p194/bin/ruby -I. ../../../../ext/nmatrix/extconf.rb
checking for clapack_dgetrf() in -llapack... no
checking for clapack.h... yes
checking for cblas_dgemm() in -lcblas... yes
checking for ATL_dgemmNN() in -latlas... no
checking for cblas.h... yes
creating nmatrix_config.h
creating Makefile
cd -
cd tmp/x86_64-darwin11.4.0/nmatrix/1.9.3
make
compiling ../../../../ext/nmatrix/nmatrix.cpp
cc1plus: error: unrecognized command line option "-std=c++0x"
make: *** [nmatrix.o] Error 1
rake aborted!
Command failed with status (2): [make...]
Tasks: TOP => compile => compile:x86_64-darwin11.4.0 => compile:nmatrix:x86_64-darwin11.4.0 => copy:nmatrix:x86_64-darwin11.4.0:1.9.3 => tmp/x86_64-darwin11.4.0/nmatrix/1.9.3/nmatrix.bundle
The specs for getrf
(a LAPACK function) currently fail. getrf
is used by the LU factorization routine, which works correctly. How is this possible, you might ask?
Well, actually, LU factorization is kind of broken, too. It gives a correct result, but it's slow. The reason is that in order for LU factorization to work as expected, it first has to copy-transpose the matrix; then call getrf
; then copy-transpose the result. This is all somewhat unfortunate, as getrf
works mostly in-place.
I opened a support request on the ATLAS tracker. Unfortunately, no reply as of yet. It might help if someone else could ask about this problem.
Need to rewrite yale_storage::create_from_list_storage
method.
SciRuby has code for reading v5 of Matlab matrix files. This code needs to be moved to NMatrix.
Apparently NMatrix segfaults when you don't provide any arguments. @killapl
When I try to build HEAD on Mac OS X (using rake repackage
and then gem install
on the .gem
file it creates), I get the following:
compiling storage/list.cpp
linking shared-object nmatrix.bundle
0 0x102cb6098 __assert_rtn + 144
1 0x102cdc8af archive::File<x86_64>::makeObjectFileForMember(archive::File<x86_64>::Entry const*) const + 1149
2 0x102cdc261 archive::File<x86_64>::justInTimeforEachAtom(char const*, ld::File::AtomHandler&) const + 139
3 0x102cecb06 ld::tool::InputFiles::searchLibraries(char const*, bool, bool, bool, ld::File::AtomHandler&) const + 210
4 0x102cf3978 ld::tool::Resolver::resolveUndefines() + 200
5 0x102cf58a3 ld::tool::Resolver::resolve() + 75
6 0x102cb6380 main + 370
7 0x102ca7cd4 start + 52
A linker snapshot was created at:
/tmp/nmatrix.bundle-2013-02-30-135555.ld-snapshot
ld: Assertion failed: (memberIndex != 0), function makeObjectFileForMember, file /SourceCache/ld64/ld64-136/src/ld/parsers/archive_file.cpp, line 354.
collect2: error: ld returned 1 exit status
make: *** [nmatrix.bundle] Error 1
I'm not really sure what's causing it. I imagine it's a problem with the gcc version being used to link, since I have multiple gcc and clang versions installed. But not good enough with Mac to figure out how to control those things.
This resembles an error @agarie noted on the listserv, but he didn't indicate which part of his solution actually solved that problem. He recommended reinstalling ATLAS, which isn't an option on MacBook Air, since there's no way to disable processor throttling.
Since we're writing our own generic versions of all of the CBLAS API (e.g., gemm, which generates i8gemm, i16gemm, i32gemm, i64gemm, r32gemm, etc.), it should be really simple to have it also generate dgemm, sgemm, cgemm, and zgemm whenever extconf.rb/configure can't find LAPACK or ATLAS.
Probably some environment variable needs to be set that ext/nmatrix/generator.rb
can read, indicating whether cblas_dgemm() was found in -lcblas, and if not, also generate gemm functions for the extra dtypes.
The same will eventually need to be done for all of the BLAS functions.
Downside: much slower than ATLAS.
Upside: works even when we don't have ATLAS, which is probably a huge barrier to adoption.
We need slicing.
It'd be nice if slices didn't require any copying -- if they were just references, that could be used with gemv, for example, and with elementwise operations.
Hi!
I have installed all the dependencies and get this error when I try to install nmatrix with gem:
Building native extensions. This could take a while...
ERROR: Error installing nmatrix:
ERROR: Failed to build gem native extension.
/usr/bin/ruby1.9.1 extconf.rb
checking for clapack_dgetrf() in -llapack... no
checking for clapack.h in /usr/local/atlas/include... no
checking for clapack.h... no
checking for cblas_dgemm() in -lcblas... no
checking for ATL_dgemmNN() in -latlas... no
checking for cblas.h in /usr/local/atlas/include... yes
checking for cblas.h... yes
creating nmatrix_config.h
creating Makefile
make
compiling nmatrix.cpp
In file included from nmatrix.cpp:49:0:
util/math.h: In function ‘void nm::math::rotg(DType*, DType*, DType*, DType*) [with DType = nm::Complex<float>]’:
util/math.h:1972:125: error: ‘cblas_crotg’ was not declared in this scope
util/math.h: In function ‘void nm::math::rotg(DType*, DType*, DType*, DType*) [with DType = nm::Complex<double>]’:
util/math.h:1977:125: error: ‘cblas_zrotg’ was not declared in this scope
util/math.h: In function ‘void nm::math::rot(int, DType*, int, DType*, int, CSDType, CSDType) [with DType = nm::Complex<float>, CSDType = float]’:
util/math.h:2017:40: error: ‘cblas_csrot’ was not declared in this scope
util/math.h: In function ‘void nm::math::rot(int, DType*, int, DType*, int, CSDType, CSDType) [with DType = nm::Complex<double>, CSDType = double]’:
util/math.h:2022:40: error: ‘cblas_zdrot’ was not declared in this scope
make: *** [nmatrix.o] Error 1
Any idea?
operator >> was found (12); parsing 'C[i] = A[i]' and 'B[i]'
operator = was found (5); parsing 'C[i]' and 'A[i]'
Making identifier out of C[i]
Making identifier out of A[i]
Making identifier out of B[i]
compiling nmatrix.c
In file included from nmatrix.c:31:0:
nmatrix.h:32:19: fatal error: cblas.h: No such file or directory
compilation terminated.
make: *** [nmatrix.o] Error 1
Can you put what libraries are needed for windows to compile this or show how it can be done.
thanks.
Aleksey mentioned that Yale slicing could be messy, and it prompted the following series of thoughts:
These questions need to be answered prior to the implementation of Yale slicing.
The BLAS algorithm will not work proplery for Rationals or Integers (due to sqrt
call). It's enabled for Rational currently, but will likely throw a Ruby exception (ArgumentError
).
cblas_rotg
also doesn't have any matrix arguments, so there needs to be some way for the user to specify the correct dtype (:float32
instead of the default :float64
, :complex64
instead of the default complex128
).
This should set the standard for any other BLAS functions which don't have NMatrix/NVector arguments from which to infer dtype.
Currently, dense transpose works only for two dimensions. It should be rewritten to be generic for n dimensions.
Matrix determinants!
It'd be nice to have two varieties: exact and fast. For 2x2 and 3x3, only exact will be used, unless the user requests an exact determinant of some larger matrix (which should thus be available, unless sufficient accuracy can be achieved with a faster algorithm).
As the matrices increase in size, there will eventually be a crossover point where we go from the exact method to the fast approximation.
Determinant is a fairly important calculation, so it'd be great if it were implemented for dense and yale. Dense is obviously priority 1.
It is not so important but I think that infrastructure of project can be improved.
I offer a using Bundler with classic rubygems specification. We can define a development dependency. It relieve a development process managment and publish gems.
Also I offer to use pry
for console and guard
for autotesting.
I used those tools in all my projects and I never felt pain with it=)
Thanks
P.S. If you agree I will do that.
I wrote a Ruby module which takes templated C files (e.g., ext/nmatrix/dense/gemm.template.c
) and writes it into a regular C source file to be compiled.
The goal is to be able to write one generic function and have it work for all of the dtypes.
The templater I've written is not very flexible, however, and is probably insufficient for the task of implementing all of the other necessary generic functions. There are some things that the SyntaxTree just won't be able to parse, and it'd be good to have better conditional support.
ERB may have a lot of this stuff. Investigate it to see if it would be a viable replacement. If not, suggest another.
Finally, one that's been researched, you could replace the current templater (ext/nmatrix/generator.rb
) with the new one.
I'm trying to come up with some examples of how to use NMatrix and, obviously, #pretty_print
/#pp
is used lots of times.
I wanted to throw this discussion to see how you guys think NMatrix
/NVector
should be printed. Any ideas? I'll try to come up with something and implement it, but I don't want to make this kind of change without listening to others.
SyntaxTree (ext/nmatrix/generator/syntax_tree.rb
) supports only very simple mathematical expressions. I'd like it if it could handle more complicated stuff.
That probably means finding a library with few or no dependencies which can parse C. It's possible you could derive your own from SyntaxTree, though this doesn't really even support parentheses.
It'd also be nice if it understood things like absolute value functions -- or really anything else you might find in NETLIB's BLAS subroutines.
1.9 added the no block format for all the enumerable methods such that they return an Enumerator
. See Array#each for example. External enumerators are useful when iterating over two collections simultaneously.
For example, it would be nice if the following worked (not a real world example):
a = NMatrix.new([2, 2], 1)
b = NMatrix.new([2, 2], [-1, 0, 1, 0])
enums = [a.each, b.each]
begin
atans = []
atans << Math.atan2(*enums.map(&:next)
rescue StopIteration
end
c = NMatrix.new([2, 2], atans)
Hey everyone,
I'd like to implement a norm method for NMatrix
and would like to ask for your assistance.
How do you see the function? At the moment, here's what I think:
mat = NMatrix.new(4, 4)
mat.norm # norm with p = 2
mat.norm 3 # norm with p = 3
mat.norm :inf # infinity norm
mat.norm :fro # Frobenius norm
What do you think?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.