nmatrix 0.0.9 → 0.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/History.txt +95 -1
  4. data/LICENSE.txt +2 -2
  5. data/README.rdoc +24 -26
  6. data/Rakefile +32 -16
  7. data/ext/nmatrix/data/complex.h +2 -2
  8. data/ext/nmatrix/data/data.cpp +27 -51
  9. data/ext/nmatrix/data/data.h +92 -4
  10. data/ext/nmatrix/data/meta.h +2 -2
  11. data/ext/nmatrix/data/rational.h +2 -2
  12. data/ext/nmatrix/data/ruby_object.h +2 -2
  13. data/ext/nmatrix/extconf.rb +87 -86
  14. data/ext/nmatrix/math.cpp +45 -40
  15. data/ext/nmatrix/math/asum.h +3 -3
  16. data/ext/nmatrix/math/geev.h +2 -2
  17. data/ext/nmatrix/math/gemm.h +6 -2
  18. data/ext/nmatrix/math/gemv.h +6 -2
  19. data/ext/nmatrix/math/ger.h +2 -2
  20. data/ext/nmatrix/math/gesdd.h +2 -2
  21. data/ext/nmatrix/math/gesvd.h +2 -2
  22. data/ext/nmatrix/math/getf2.h +2 -2
  23. data/ext/nmatrix/math/getrf.h +2 -2
  24. data/ext/nmatrix/math/getri.h +2 -2
  25. data/ext/nmatrix/math/getrs.h +7 -3
  26. data/ext/nmatrix/math/idamax.h +2 -2
  27. data/ext/nmatrix/math/inc.h +12 -6
  28. data/ext/nmatrix/math/laswp.h +2 -2
  29. data/ext/nmatrix/math/long_dtype.h +2 -2
  30. data/ext/nmatrix/math/math.h +16 -10
  31. data/ext/nmatrix/math/nrm2.h +3 -3
  32. data/ext/nmatrix/math/potrs.h +7 -3
  33. data/ext/nmatrix/math/rot.h +2 -2
  34. data/ext/nmatrix/math/rotg.h +2 -2
  35. data/ext/nmatrix/math/scal.h +2 -2
  36. data/ext/nmatrix/math/swap.h +2 -2
  37. data/ext/nmatrix/math/trsm.h +7 -3
  38. data/ext/nmatrix/nm_memory.h +60 -0
  39. data/ext/nmatrix/nmatrix.cpp +13 -47
  40. data/ext/nmatrix/nmatrix.h +37 -12
  41. data/ext/nmatrix/ruby_constants.cpp +4 -2
  42. data/ext/nmatrix/ruby_constants.h +4 -2
  43. data/ext/nmatrix/ruby_nmatrix.c +937 -170
  44. data/ext/nmatrix/storage/common.cpp +2 -2
  45. data/ext/nmatrix/storage/common.h +2 -2
  46. data/ext/nmatrix/storage/{dense.cpp → dense/dense.cpp} +253 -100
  47. data/ext/nmatrix/storage/{dense.h → dense/dense.h} +6 -5
  48. data/ext/nmatrix/storage/{list.cpp → list/list.cpp} +517 -98
  49. data/ext/nmatrix/storage/{list.h → list/list.h} +13 -6
  50. data/ext/nmatrix/storage/storage.cpp +48 -19
  51. data/ext/nmatrix/storage/storage.h +4 -4
  52. data/ext/nmatrix/storage/yale/class.h +112 -43
  53. data/ext/nmatrix/storage/yale/iterators/base.h +2 -2
  54. data/ext/nmatrix/storage/yale/iterators/iterator.h +2 -2
  55. data/ext/nmatrix/storage/yale/iterators/row.h +2 -2
  56. data/ext/nmatrix/storage/yale/iterators/row_stored.h +2 -2
  57. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +4 -3
  58. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +2 -2
  59. data/ext/nmatrix/storage/yale/math/transpose.h +2 -2
  60. data/ext/nmatrix/storage/yale/yale.cpp +343 -52
  61. data/ext/nmatrix/storage/yale/yale.h +7 -3
  62. data/ext/nmatrix/types.h +2 -2
  63. data/ext/nmatrix/util/io.cpp +5 -5
  64. data/ext/nmatrix/util/io.h +2 -2
  65. data/ext/nmatrix/util/sl_list.cpp +40 -27
  66. data/ext/nmatrix/util/sl_list.h +3 -3
  67. data/ext/nmatrix/util/util.h +2 -2
  68. data/lib/nmatrix.rb +2 -2
  69. data/lib/nmatrix/blas.rb +2 -2
  70. data/lib/nmatrix/enumerate.rb +17 -6
  71. data/lib/nmatrix/io/market.rb +2 -3
  72. data/lib/nmatrix/io/mat5_reader.rb +2 -2
  73. data/lib/nmatrix/io/mat_reader.rb +2 -2
  74. data/lib/nmatrix/lapack.rb +46 -46
  75. data/lib/nmatrix/math.rb +213 -20
  76. data/lib/nmatrix/monkeys.rb +24 -2
  77. data/lib/nmatrix/nmatrix.rb +394 -9
  78. data/lib/nmatrix/nvector.rb +2 -64
  79. data/lib/nmatrix/rspec.rb +2 -2
  80. data/lib/nmatrix/shortcuts.rb +14 -61
  81. data/lib/nmatrix/version.rb +11 -3
  82. data/lib/nmatrix/yale_functions.rb +4 -4
  83. data/nmatrix.gemspec +2 -7
  84. data/scripts/mac-brew-gcc.sh +11 -8
  85. data/scripts/mac-mavericks-brew-gcc.sh +22 -0
  86. data/spec/00_nmatrix_spec.rb +116 -7
  87. data/spec/01_enum_spec.rb +17 -3
  88. data/spec/02_slice_spec.rb +11 -3
  89. data/spec/blas_spec.rb +5 -2
  90. data/spec/elementwise_spec.rb +5 -2
  91. data/spec/io_spec.rb +27 -17
  92. data/spec/lapack_spec.rb +157 -9
  93. data/spec/math_spec.rb +95 -4
  94. data/spec/nmatrix_yale_spec.rb +21 -26
  95. data/spec/rspec_monkeys.rb +27 -0
  96. data/spec/rspec_spec.rb +2 -2
  97. data/spec/shortcuts_spec.rb +5 -10
  98. data/spec/slice_set_spec.rb +6 -2
  99. data/spec/spec_helper.rb +3 -2
  100. data/spec/stat_spec.rb +174 -158
  101. metadata +15 -15
@@ -9,8 +9,8 @@
9
9
  #
10
10
  # == Copyright Information
11
11
  #
12
- # SciRuby is Copyright (c) 2010 - 2013, Ruby Science Foundation
13
- # NMatrix is Copyright (c) 2013, Ruby Science Foundation
12
+ # SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
13
+ # NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
14
14
  #
15
15
  # Please see LICENSE.txt for additional copyright notices.
16
16
  #
@@ -159,68 +159,6 @@ class NVector < NMatrix
159
159
  min_so_far
160
160
  end
161
161
 
162
- #
163
- # call-seq:
164
- # absolute_sum -> Numeric
165
- #
166
- # == Arguments
167
- # - +incx+ -> the skip size (defaults to 1, no skip)
168
- # - +n+ -> the number of elements to include
169
- #
170
- # Return the sum of the contents of the vector. This is the BLAS asum routine.
171
- def asum incx=1, n=nil
172
- NMatrix::BLAS::asum(self, incx, self.size / incx)
173
- end
174
- alias :absolute_sum :asum
175
-
176
- #
177
- # call-seq:
178
- # norm2 -> Numeric
179
- #
180
- # == Arguments
181
- # - +incx+ -> the skip size (defaults to 1, no skip)
182
- # - +n+ -> the number of elements to include
183
- #
184
- # Return the 2-norm of the vector. This is the BLAS nrm2 routine.
185
- def nrm2 incx=1, n=nil
186
- NMatrix::BLAS::nrm2(self, incx, self.size / incx)
187
- end
188
- alias :norm2 :nrm2
189
-
190
-
191
- #
192
- # call-seq:
193
- # sorted_indices -> Array
194
- #
195
- # Returns an array of the indices ordered by value sorted.
196
- #
197
- def sorted_indices
198
- ary = self.to_a
199
- ary.each_index.sort_by { |i| ary[i] } # from: http://stackoverflow.com/a/17841159/170300
200
- end
201
-
202
- #
203
- # call-seq:
204
- # binned_sorted_indices -> Array
205
- #
206
- # Returns an array of arrays of indices ordered by value sorted. Functions basically like +sorted_indices+, but
207
- # groups indices together for those values that are the same.
208
- #
209
- def binned_sorted_indices
210
- ary = self.to_a
211
- ary2 = []
212
- last_bin = ary.each_index.sort_by { |i| [ary[i]] }.inject([]) do |result, element|
213
- if result.empty? || ary[result[-1]] == ary[element]
214
- result << element
215
- else
216
- ary2 << result
217
- [element]
218
- end
219
- end
220
- ary2 << last_bin unless last_bin.empty?
221
- ary2
222
- end
223
-
224
162
 
225
163
  # TODO: Make this actually pretty.
226
164
  def pretty_print(q = nil) #:nodoc:
data/lib/nmatrix/rspec.rb CHANGED
@@ -8,8 +8,8 @@
8
8
  #
9
9
  # == Copyright Information
10
10
  #
11
- # SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
12
- # NMatrix is Copyright (c) 2012, Ruby Science Foundation
11
+ # SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
12
+ # NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
13
13
  #
14
14
  # Please see LICENSE.txt for additional copyright notices.
15
15
  #
@@ -9,8 +9,8 @@
9
9
  #
10
10
  # == Copyright Information
11
11
  #
12
- # SciRuby is Copyright (c) 2010 - 2013, Ruby Science Foundation
13
- # NMatrix is Copyright (c) 2013, Ruby Science Foundation
12
+ # SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
13
+ # NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
14
14
  #
15
15
  # Please see LICENSE.txt for additional copyright notices.
16
16
  #
@@ -295,6 +295,14 @@ class NMatrix
295
295
  # call-seq:
296
296
  # seq(shape) -> NMatrix
297
297
  # seq(shape, options) -> NMatrix
298
+ # bindgen(shape) -> NMatrix of :byte
299
+ # indgen(shape) -> NMatrix of :int64
300
+ # findgen(shape) -> NMatrix of :float32
301
+ # dindgen(shape) -> NMatrix of :float64
302
+ # cindgen(shape) -> NMatrix of :complex64
303
+ # zindgen(shape) -> NMatrix of :complex128
304
+ # rindgen(shape) -> NMatrix of :rational128
305
+ # rbindgen(shape) -> NMatrix of :object
298
306
  #
299
307
  # Creates a matrix filled with a sequence of integers starting at zero.
300
308
  #
@@ -322,66 +330,11 @@ class NMatrix
322
330
  NMatrix.new(shape, values, {:stype => :dense}.merge(options))
323
331
  end
324
332
 
325
- #
326
- # call-seq:
327
- # indgen(size) -> NMatrix
328
- #
329
- # Returns an integer NMatrix. Equivalent to <tt>seq(n, dtype: :int32)</tt>.
330
- #
331
- # * *Arguments* :
332
- # - +shape+ -> Shape of the sequence.
333
- # * *Returns* :
334
- # - NMatrix with dtype +:int32+.
335
- #
336
- def indgen(shape)
337
- NMatrix.seq(shape, dtype: :int32)
338
- end
339
-
340
- #
341
- # call-seq:
342
- # findgen(shape) -> NMatrix
343
- #
344
- # Returns a float NMatrix. Equivalent to <tt>seq(n, dtype: :float32)</tt>.
345
- #
346
- # * *Arguments* :
347
- # - +shape+ -> Shape of the sequence.
348
- # * *Returns* :
349
- # - NMatrix with dtype +:float32+.
350
- #
351
- def findgen(shape)
352
- NMatrix.seq(shape, dtype: :float32)
333
+ {:bindgen => :byte, :indgen => :int64, :findgen => :float32, :dindgen => :float64,
334
+ :cindgen => :complex64, :zindgen => :complex128,
335
+ :rindgen => :rational128, :rbindgen => :object}.each_pair do |meth, dtype|
336
+ define_method(meth) { |shape| NMatrix.seq(shape, :dtype => dtype) }
353
337
  end
354
-
355
- #
356
- # call-seq:
357
- # bindgen(size) -> NMatrix
358
- #
359
- # Returns a byte NMatrix. Equivalent to <tt>seq(n, dtype: :byte)</tt>.
360
- #
361
- # * *Arguments* :
362
- # - +size+ -> Shape of the sequence.
363
- # * *Returns* :
364
- # - NMatrix with dtype +:byte+.
365
- #
366
- def bindgen(shape)
367
- NMatrix.seq(shape, dtype: :byte)
368
- end
369
-
370
- #
371
- # call-seq:
372
- # cindgen(shape) -> NMatrix
373
- #
374
- # Returns a complex NMatrix. Equivalent to <tt>seq(n, dtype: :complex64)</tt>.
375
- #
376
- # * *Arguments* :
377
- # - +shape+ -> Shape of the sequence.
378
- # * *Returns* :
379
- # - NMatrix with dtype +:complex64+.
380
- #
381
- def cindgen(shape)
382
- NMatrix.seq(shape, dtype: :complex64)
383
- end
384
-
385
338
  end
386
339
  end
387
340
 
@@ -9,8 +9,8 @@
9
9
  #
10
10
  # == Copyright Information
11
11
  #
12
- # SciRuby is Copyright (c) 2010 - 2013, Ruby Science Foundation
13
- # NMatrix is Copyright (c) 2013, Ruby Science Foundation
12
+ # SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
13
+ # NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
14
14
  #
15
15
  # Please see LICENSE.txt for additional copyright notices.
16
16
  #
@@ -26,6 +26,14 @@ class NMatrix
26
26
  # Note that the format of the VERSION string is needed for NMatrix
27
27
  # native IO. If you change the format, please make sure that native
28
28
  # IO can still understand NMatrix::VERSION.
29
- VERSION = "0.0.9"
29
+ #VERSION = "0.1.0"
30
+ module VERSION
31
+ MAJOR = 0
32
+ MINOR = 1
33
+ TINY = 0
34
+ PRE = "rc1"
35
+
36
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
37
+ end
30
38
  end
31
39
 
@@ -9,8 +9,8 @@
9
9
  #
10
10
  # == Copyright Information
11
11
  #
12
- # SciRuby is Copyright (c) 2010 - 2013, Ruby Science Foundation
13
- # NMatrix is Copyright (c) 2013, Ruby Science Foundation
12
+ # SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
13
+ # NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
14
14
  #
15
15
  # Please see LICENSE.txt for additional copyright notices.
16
16
  #
@@ -81,7 +81,7 @@ module NMatrix::YaleFunctions
81
81
  # Returns the diagonal and non-digonal column indices stored in a given row.
82
82
  def yale_ja_d_keys_at i
83
83
  ary = yale_nd_row(i, :keys)
84
- return ary if i >= self.shape[1] || self[i,i].nil? || self[i,i] == 0
84
+ return ary if i >= self.shape[1] || self[i,i] == self.default_value
85
85
  ary << i
86
86
  end
87
87
  alias :yale_row_as_array :yale_ja_d_keys_at
@@ -112,7 +112,7 @@ module NMatrix::YaleFunctions
112
112
  # Returns the diagonal and non-diagonal column indices and entries stored in a given row.
113
113
  def yale_row_as_hash i
114
114
  h = yale_nd_row(i, :hash)
115
- return h if i >= self.shape[1] || self[i,i].nil? || self[i,i] == 0
115
+ return h if i >= self.shape[1] || self[i,i] == self.default_value
116
116
  h[i] = self[i,i]
117
117
  end
118
118
  end
data/nmatrix.gemspec CHANGED
@@ -5,22 +5,17 @@ require 'nmatrix/version'
5
5
 
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = "nmatrix"
8
- gem.version = NMatrix::VERSION
8
+ gem.version = NMatrix::VERSION::STRING
9
9
  gem.summary = "NMatrix is an experimental linear algebra library for Ruby, written mostly in C."
10
10
  gem.description = "NMatrix is an experimental linear algebra library for Ruby, written mostly in C."
11
11
  gem.homepage = 'http://sciruby.com'
12
12
  gem.authors = ['John Woods', 'Chris Wailes', 'Aleksey Timin']
13
13
  gem.email = ['john.o.woods@gmail.com']
14
+ gem.license = 'BSD 2-clause'
14
15
  gem.post_install_message = <<-EOF
15
16
  ***********************************************************
16
17
  Welcome to SciRuby: Tools for Scientific Computing in Ruby!
17
18
 
18
- *** WARNING ***
19
- Please be aware that NMatrix is in ALPHA status. If you're
20
- thinking of using NMatrix to write mission critical code,
21
- such as for driving a car or flying a space shuttle, you
22
- may wish to choose other software (for now).
23
-
24
19
  NMatrix requires a C compiler, and has been tested only
25
20
  with GCC 4.6+. We are happy to accept contributions
26
21
  which improve the portability of this project.
@@ -1,5 +1,9 @@
1
1
  #!/bin/bash
2
- VERSION="4.7.2"
2
+
3
+ # Script will not work for GCC 4.8 or 4.9. For those, please see
4
+ # mac-mavericks-brew-gcc.sh
5
+
6
+ VERSION="4.7.2" # Script should also work with GCC 4.7.1.
3
7
  PREFIX="/usr/gcc-${VERSION}"
4
8
  LANGUAGES="c,c++,fortran"
5
9
  MAKE="make -j 4"
@@ -8,11 +12,9 @@ brew-path() { brew info $1 | head -n3 | tail -n1 | cut -d' ' -f1; }
8
12
 
9
13
  # Prerequisites
10
14
 
11
- brew install gmp
12
- brew install mpfr
13
- brew install libmpc
15
+ brew install gmp mpfr libmpc
14
16
 
15
- # Download & install the latest GCC
17
+ # Next, download & install the latest GCC:
16
18
 
17
19
  mkdir -p $PREFIX
18
20
  mkdir temp-gcc
@@ -25,11 +27,12 @@ cd gcc-$VERSION
25
27
  mkdir build
26
28
  cd build
27
29
 
30
+ # Older versions of brew need brew-path instead of brew --prefix.
28
31
  ../configure \
29
32
  --prefix=$PREFIX \
30
- --with-gmp=$(brew-path gmp) \
31
- --with-mpfr=$(brew-path mpfr) \
32
- --with-mpc=$(brew-path libmpc) \
33
+ --with-gmp=$(brew --prefix gmp) \
34
+ --with-mpfr=$(brew --prefix mpfr) \
35
+ --with-mpc=$(brew --prefix libmpc) \
33
36
  --program-suffix=-$VERSION \
34
37
  --enable-languages=$LANGUAGES \
35
38
  --with-system-zlib \
@@ -0,0 +1,22 @@
1
+ #!/bin/bash
2
+
3
+ brew-path() { brew info $1 | head -n3 | tail -n1 | cut -d' ' -f1; }
4
+
5
+ # Try using the following for GCC 4.9:
6
+ #
7
+ # brew install gmp4 mpfr2 libmpc08 isl011 cloog018
8
+ #
9
+ #
10
+
11
+ brew install gcc49 --enable-fortran
12
+ # Source for this is: http://stackoverflow.com/questions/19535422/os-x-10-9-gcc-links-to-clang
13
+
14
+
15
+ # You may wish to re-install your Ruby if you're using rbenv. To do
16
+ # so, make sure you've installed openssl, readline, and libyaml.
17
+ #
18
+ # The commands for this are:
19
+ #
20
+ # CC=gcc-4.8 RUBY_CONFIGURE_OPTS="--with-openssl-dir=`brew --prefix openssl` --with-readline-dir=`brew --prefix readline` --with-gcc=gcc-4.8 --enable-shared" rbenv install --keep 2.0.0-p247
21
+ #
22
+ #
@@ -8,8 +8,8 @@
8
8
  #
9
9
  # == Copyright Information
10
10
  #
11
- # SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
12
- # NMatrix is Copyright (c) 2012, Ruby Science Foundation
11
+ # SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
12
+ # NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
13
13
  #
14
14
  # Please see LICENSE.txt for additional copyright notices.
15
15
  #
@@ -29,6 +29,10 @@
29
29
  require File.dirname(__FILE__) + "/spec_helper.rb"
30
30
 
31
31
  describe NMatrix do
32
+ #after :each do
33
+ # GC.start
34
+ #end
35
+
32
36
  it "creates a matrix with the new constructor" do
33
37
  n = NMatrix.new([2,2], [0,1,2,3], dtype: :int64)
34
38
  end
@@ -40,17 +44,15 @@ describe NMatrix do
40
44
  end
41
45
 
42
46
  it "calculates exact determinants on small square matrices" do
43
- a = NMatrix.new(:dense, 2, [1,2,3,4], :int64)
44
- a.det_exact.should == -2
47
+ NMatrix.new(2, [1,2,3,4], stype: :dense, dtype: :int64).det_exact.should == -2
45
48
  end
46
49
 
47
50
  it "calculates determinants" do
48
- m = NMatrix.new(3, [-2,2,3,-1,1,3,2,0,-1])
49
- m.det.should == 6
51
+ NMatrix.new(3, [-2,2,3,-1,1,3,2,0,-1], stype: :dense, dtype: :int64).det.should == 6
50
52
  end
51
53
 
52
54
  it "allows casting to Ruby objects" do
53
- m = NMatrix.new(:dense, [3,3], [0,0,1,0,2,0,3,4,5], :int64)
55
+ m = NMatrix.new([3,3], [0,0,1,0,2,0,3,4,5], dtype: :int64, stype: :dense)
54
56
  n = m.cast(:dense, :object)
55
57
  n.should == m
56
58
  end
@@ -367,3 +369,110 @@ describe NMatrix do
367
369
  end
368
370
 
369
371
  end
372
+
373
+
374
+ describe "NMatrix#upper_triangle" do
375
+ it "should create a copy with the lower corner set to zero" do
376
+ n = NMatrix.seq(4)+1
377
+ n.upper_triangle.should == NMatrix.new(4, [1,2,3,4,0,6,7,8,0,0,11,12,0,0,0,16])
378
+ n.upper_triangle(2).should == NMatrix.new(4, [1,2,3,4,5,6,7,8,9,10,11,12,0,14,15,16])
379
+ end
380
+ end
381
+
382
+ describe "NMatrix#lower_triangle" do
383
+ it "should create a copy with the lower corner set to zero" do
384
+ n = NMatrix.seq(4)+1
385
+ n.lower_triangle.should == NMatrix.new(4, [1,0,0,0,5,6,0,0,9,10,11,0,13,14,15,16])
386
+ n.lower_triangle(2).should == NMatrix.new(4, [1,2,3,0,5,6,7,8,9,10,11,12,13,14,15,16])
387
+ end
388
+ end
389
+
390
+ describe "NMatrix#upper_triangle!" do
391
+ it "should create a copy with the lower corner set to zero" do
392
+ n = NMatrix.seq(4)+1
393
+ n.upper_triangle!.should == NMatrix.new(4, [1,2,3,4,0,6,7,8,0,0,11,12,0,0,0,16])
394
+ n = NMatrix.seq(4)+1
395
+ n.upper_triangle!(2).should == NMatrix.new(4, [1,2,3,4,5,6,7,8,9,10,11,12,0,14,15,16])
396
+ end
397
+ end
398
+
399
+ describe "NMatrix#lower_triangle!" do
400
+ it "should create a copy with the lower corner set to zero" do
401
+ n = NMatrix.seq(4)+1
402
+ n.lower_triangle!.should == NMatrix.new(4, [1,0,0,0,5,6,0,0,9,10,11,0,13,14,15,16])
403
+ n = NMatrix.seq(4)+1
404
+ n.lower_triangle!(2).should == NMatrix.new(4, [1,2,3,0,5,6,7,8,9,10,11,12,13,14,15,16])
405
+ end
406
+ end
407
+
408
+ describe "NMatrix#reshape" do
409
+ it "should change the shape of a matrix without the contents changing" do
410
+ n = NMatrix.seq(4)+1
411
+ n.reshape([8,2]).to_flat_array.should == n.to_flat_array
412
+ end
413
+
414
+ it "should permit a change of dimensionality" do
415
+ n = NMatrix.seq(4)+1
416
+ n.reshape([8,1,2]).to_flat_array.should == n.to_flat_array
417
+ end
418
+
419
+ it "should prevent a resize" do
420
+ n = NMatrix.seq(4)+1
421
+ expect { n.reshape([5,2]) }.to raise_error(ArgumentError)
422
+ end
423
+ end
424
+
425
+ describe "NMatrix#transpose" do
426
+ [:dense, :list, :yale].each do |stype|
427
+ context(stype) do
428
+ it "should transpose a #{stype} matrix (2-dimensional)" do
429
+ n = NMatrix.seq(4, stype: stype)
430
+ n.transpose.to_a.flatten.should == [0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15]
431
+ end
432
+ end
433
+ end
434
+
435
+ [:dense, :list].each do |stype|
436
+ context(stype) do
437
+ it "should transpose a #{stype} matrix (3-dimensional)" do
438
+ n = NMatrix.new([4,4,1], [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], stype: stype)
439
+ n.transpose([2,1,0]).to_flat_array.should == [0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15]
440
+ n.transpose([1,0,2]).to_flat_array.should == [0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15]
441
+ n.transpose([0,2,1]).to_flat_array.should == n.to_flat_array # for dense, make this reshape!
442
+ end
443
+ end
444
+ end
445
+
446
+ end
447
+
448
+ describe "NMatrix#==" do
449
+ [:dense, :list, :yale].each do |left|
450
+ [:dense, :list, :yale].each do |right|
451
+ next if left == right
452
+ context ("#{left}?#{right}") do
453
+ it "should compare two matrices of differing stypes" do
454
+ n = NMatrix.new([3,4], [0,0,1,2,0,0,3,4,0,0,0,0,5,6,7,0], stype: left)
455
+ m = NMatrix.new([3,4], [0,0,1,2,0,0,3,4,0,0,0,0,5,6,7,0], stype: right)
456
+ n.should == m
457
+ end
458
+ end
459
+ end
460
+ end
461
+ end
462
+
463
+ describe "NMatrix#concat" do
464
+ it "should default to horizontal concatenation" do
465
+ n = NMatrix.new([1,3], [1,2,3])
466
+ n.concat(n).should == NMatrix.new([1,6], [1,2,3,1,2,3])
467
+ end
468
+
469
+ it "should permit vertical concatenation" do
470
+ n = NMatrix.new([1,3], [1,2,3])
471
+ n.vconcat(n).should == NMatrix.new([2,3], [1,2,3])
472
+ end
473
+
474
+ it "should permit depth concatenation on tensors" do
475
+ n = NMatrix.new([1,3,1], [1,2,3])
476
+ n.dconcat(n).should == NMatrix.new([1,3,2], [1,1,2,2,3,3])
477
+ end
478
+ end