GithubHelp home page GithubHelp logo

sciruby / nmatrix Goto Github PK

View Code? Open in Web Editor NEW

This project forked from translunar/nmatrix

469.0 469.0 133.0 7.89 MB

Dense and sparse linear algebra library for Ruby via SciRuby

License: Other

Ruby 19.42% C++ 60.33% C 19.81% Shell 0.11% Java 0.34%

nmatrix's Introduction

SciRuby meta gem Build Status

Tools for Scientific Computing in Ruby

Description

This gem acts as a meta gem which collects and provides multiple scientific gems, including numeric and visualization libraries.

Getting started

Installation:

gem install sciruby
gem install sciruby-full

If you want to have a full-blown installation, install sciruby-full.

Start a notebook server:

iruby notebook

Enter commands:

require 'sciruby'
# Scientific gems are auto loaded, you can use them directly!
plot = Nyaplot::Plot.new
sc = plot.add(:scatter, [0,1,2,3,4], [-1,2,-3,4,-5])

Take a look at gems.yml or the list of gems for interesting gems which are included in sciruby-full.

License

Copyright (c) 2010 onward, The Ruby Science Foundation.

All rights reserved.

SciRuby is licensed under the BSD 3-clause license. See LICENSE for details.

Donations

Support a SciRuby Fellow via Pledgie.

nmatrix's People

Contributors

agarie avatar agisga avatar alno avatar andrewcsmith avatar atimin avatar blackwinter avatar chriswailes avatar cjfuller avatar duggiefresh avatar erik avatar firemind avatar gtamba avatar ktns avatar lokeshh avatar masaomi avatar mrkn avatar npriyadarshi avatar prasunanand avatar preetpals avatar rajatkapoor avatar rve avatar ryanmt avatar sheerun avatar takkanm avatar terrencekhng avatar translunar avatar v0dro avatar wlevine avatar yoongkang avatar yui-knk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nmatrix's Issues

Linking problem on Mac OS X

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.

Elementwise operation improvements: return types

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.

NMatrix::IO::MATLAB loads dense double matrix incorrectly

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:

  • 64-bit Win7
  • MATLAB R2012a

Trying to parse the data on:

  • 64-bit Arch Linux
  • ruby 1.9.3-p286 rev 37165
  • nmatrix 0.0.2

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]

malloc errors

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.

Cannot install on OS X

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?

memory leak when using dot with yale vectors ( matrix with one dimension set to 1)

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 ?

Implement slicing

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.

Elementwise list operations broken

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.

Exposure of remaining CBLAS and CLAPACK functions

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.

`each` should return an `Enumerator` when no block is passed

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)

Why not build on top of Java?

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.

Improve SyntaxTree / C / math expression parser

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.

Investigate replacing custom code generator with ERB (or other lib)

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.

Need native GETRI, POTRI, ROTG implementation (or ATLAS macros)

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.

Yale slicing

Aleksey mentioned that Yale slicing could be messy, and it prompted the following series of thoughts:

  • What would a row slice for a Yale matrix look like? This would be inefficient storage if the slice itself were stored as Yale, unless we stored it as a column-major yale matrix (?).
  • Should certain copy-slice shapes return dense matrices instead, as these are nearly always more efficient for certain (small) shapes?
  • Does slicing-by-reference make sense for Yale at all?
  • Would it be more efficient to return an "old" Yale for a reference-slice instead of a "new" Yale, since we're much less likely to care so much about the diagonal? (New Yale, diagonal access is O(1), but old Yale saves some space.)

These questions need to be answered prior to the implementation of Yale slicing.

Casting from yale to list doesn't work.

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]

Issues compiling on OS X

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)

Fail to compile nmatrix.cpp - Ubuntu 12.04.1 LTS

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?

gem installation on windows

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.

NMatrix::BLAS::cblas_rotg needs a rational-safe algorithm, dtype specifier

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.

Segfault when using NMatrix::BLAS#gemv

>> 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?

ATLAS xGETRF gives a result which is apparently incorrect

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.

Norm method format

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?

Segmentation faults when using sparse matrices

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 -----------------------------------------------

Can't install HEAD

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

Improve speed of gemm for non-ATLAS types

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.

Write workaround for missing ATLAS/LAPACK/BLAS

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.

Bundler instead of isolite and hoe

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.

Matrix inversion and matrix exponents

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?

Mac Install Issues

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

Split elementwise operations to allow different return types

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.

Implement scalar operations [yale still needed]

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.

StorageTypeError: conversion failed; capacity of 14 requested, max allowable is 6

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...

Covariance Matrices and Eigenvalue decomposition (LAPACK xGEEV)

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

Determinants

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.

Tests need to be checked for :complex64/:complex128 gemm exposure

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.

Improve the installation process

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.

Make #pretty_print actually pretty

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.

Matrix multiplication is not what I expect

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:

Pure Ruby

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

SciPy

from scipy import matrix

m = matrix([[1, 2], [3, 4]])
n = matrix([[5, 6], [7, 8]])

print m * n

# [[19 22]
#  [43 50]]

NMatrix

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.