nmatrix 0.1.0.rc3 → 0.1.0.rc4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +22 -21
  3. data/History.txt +13 -0
  4. data/Manifest.txt +1 -2
  5. data/README.rdoc +8 -8
  6. data/ext/nmatrix/binary_format.txt +1 -1
  7. data/ext/nmatrix/data/complex.h +21 -21
  8. data/ext/nmatrix/data/data.cpp +9 -2
  9. data/ext/nmatrix/data/data.h +4 -2
  10. data/ext/nmatrix/math.cpp +69 -31
  11. data/ext/nmatrix/math/getf2.h +2 -2
  12. data/ext/nmatrix/math/getrf.h +2 -2
  13. data/ext/nmatrix/math/imax.h +101 -0
  14. data/ext/nmatrix/math/scal.h +30 -10
  15. data/ext/nmatrix/math/swap.h +1 -22
  16. data/ext/nmatrix/nm_memory.h +1 -1
  17. data/ext/nmatrix/nmatrix.h +2 -2
  18. data/ext/nmatrix/ruby_constants.cpp +1 -2
  19. data/ext/nmatrix/ruby_constants.h +6 -7
  20. data/ext/nmatrix/ruby_nmatrix.c +23 -18
  21. data/ext/nmatrix/storage/list/list.cpp +48 -47
  22. data/ext/nmatrix/util/io.cpp +2 -2
  23. data/lib/nmatrix.rb +0 -1
  24. data/lib/nmatrix/enumerate.rb +1 -1
  25. data/lib/nmatrix/io/market.rb +1 -1
  26. data/lib/nmatrix/io/mat_reader.rb +41 -41
  27. data/lib/nmatrix/lapack.rb +0 -1
  28. data/lib/nmatrix/math.rb +43 -0
  29. data/lib/nmatrix/nmatrix.rb +5 -1
  30. data/lib/nmatrix/version.rb +1 -1
  31. data/nmatrix.gemspec +3 -4
  32. data/spec/00_nmatrix_spec.rb +13 -6
  33. data/spec/01_enum_spec.rb +17 -25
  34. data/spec/02_slice_spec.rb +74 -82
  35. data/spec/blas_spec.rb +21 -6
  36. data/spec/elementwise_spec.rb +1 -6
  37. data/spec/io_spec.rb +15 -22
  38. data/spec/lapack_spec.rb +1 -6
  39. data/spec/leakcheck.rb +1 -1
  40. data/spec/math_spec.rb +43 -4
  41. data/spec/nmatrix_yale_spec.rb +1 -4
  42. data/spec/rspec_spec.rb +1 -1
  43. data/spec/shortcuts_spec.rb +1 -6
  44. data/spec/slice_set_spec.rb +1 -5
  45. data/spec/stat_spec.rb +46 -51
  46. metadata +32 -22
  47. data/Guardfile +0 -6
  48. data/ext/nmatrix/math/idamax.h +0 -86
  49. data/lib/nmatrix/nvector.rb +0 -184
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9bccc178bd2c4a0ee318f3a0808e7f3c52cfbc3f
4
- data.tar.gz: eec9ec0890b8ab958c123452f98064883de0ea33
3
+ metadata.gz: 7aab05ad51eae5a3ccba6312f79d75b624ccb6a2
4
+ data.tar.gz: d8a2d31cdf2290857458256724102588c4ef8da6
5
5
  SHA512:
6
- metadata.gz: ab789cf265f5461e75e0425ce126c45e52ff627b69bfa0a5a94018260254708ec11c9e0e67a9f94e7dab0696fe1171c56d8043304b59848bfede52761e33924f
7
- data.tar.gz: b8f8cfe0c81c7ce46306afcd9b5e469e84856aae990b6e42e52ca299234fe03801bd7f0c4ba585f14786909f1dbe88b10e5b12b3ef16c37935b8efa06e58b7ed
6
+ metadata.gz: b242f8f8603d5ff19c525c4f1ced681bf7766bff43d273e61de7497dc724867d74613da98fabe444dda4360d05bc4973d296422af62fe6013c75feec0f3c8f3c
7
+ data.tar.gz: ca9c9ac8ef252a35fcff3c3e9a405090711c47ecbc3ffe387e3e18861e6f1ddbf85654350e2c09616c11356705e8a2c234dd512fc9fb9780c60acb9dd08dd317
data/CONTRIBUTING.md CHANGED
@@ -1,5 +1,5 @@
1
1
  NMatrix is part of SciRuby, a collaborative effort to bring scientific computation to Ruby. If you want to help, please
2
- do so!
2
+ do so!
3
3
 
4
4
  This guide covers ways in which you can contribute to the development of SciRuby and, more specifically, NMatrix.
5
5
 
@@ -8,25 +8,25 @@ This guide covers ways in which you can contribute to the development of SciRuby
8
8
  There are various ways to help NMatrix: bug reports, coding and documentation. All of them are important.
9
9
 
10
10
  First, you can help implement new features or bug fixes. To do that, visit our
11
- [roadmap](https://github.com/SciRuby/nmatrix/wiki/Roadmap) or our [issue tracker][2]. If you find something that you
12
- want to work on, post it in the issue or on our [mailing list][1].
11
+ [roadmap](https://github.com/SciRuby/nmatrix/wiki/Roadmap) or our [issue tracker][2]. If you find something that you
12
+ want to work on, post it in the issue or on our [mailing list][1].
13
13
 
14
14
  You need to send tests together with your code. No exceptions. You can ask for our opinion, but we won't accept patches
15
- without good spec coverage.
15
+ without good spec coverage.
16
16
 
17
17
  We use RSpec for testing. If you aren't familiar with it, there's a good
18
- [guide to better specs with RSpec](http://betterspecs.org/) that shows a bit of the syntax and how to use it properly.
19
- However, the best resource is probably the specs that already exist -- so just read them.
18
+ [guide to better specs with RSpec](http://betterspecs.org/) that shows a bit of the syntax and how to use it properly.
19
+ However, the best resource is probably the specs that already exist -- so just read them.
20
20
 
21
21
  And don't forget to write documentation (we use RDoc). It's necessary to allow others to know what's available in the
22
- library. There's a section on it later in this guide.
22
+ library. There's a section on it later in this guide.
23
23
 
24
24
  We only accept bug reports and pull requests in GitHub. You'll need to create a new (free) account if you don't have one
25
- already. To learn how to create a pull request, please see
26
- [this guide on collaborating](https://help.github.com/categories/63/articles).
25
+ already. To learn how to create a pull request, please see
26
+ [this guide on collaborating](https://help.github.com/categories/63/articles).
27
27
 
28
28
  If you have a question about how to use NMatrix or SciRuby in general or a feature/change in mind, please ask the
29
- [sciruby-dev mailing list][1].
29
+ [sciruby-dev mailing list][1].
30
30
 
31
31
  Thanks!
32
32
 
@@ -42,21 +42,22 @@ To start helping with the code, you need to have all the dependencies in place:
42
42
 
43
43
  Now, you need to clone the git repository:
44
44
 
45
- git clone git://github.com/SciRuby/nmatrix.git
46
- cd nmatrix
47
- bundle install
48
- rake compile
49
- rake spec
45
+ ```bash
46
+ $ git clone git://github.com/SciRuby/nmatrix.git
47
+ $ cd nmatrix
48
+ $ bundle install
49
+ $ rake compile
50
+ $ rake spec
51
+ ```
50
52
 
51
- This will install all dependencies, compile the extension and run the specs.
52
-
53
- As of now (12/31/2012), there should be 25 specs failing, in elementwise\_spec, lapack\_spec and math\_spec. If you see
54
- more than 25 or from different specs, please report on the [mailing list][1] or on the [issue tracker][2].
53
+ This will install all dependencies, compile the extension and run the specs.
55
54
 
56
55
  If everything's fine until now, you can create a new branch to work on your feature:
57
56
 
58
- git branch new-feature
59
- git checkout new-feature
57
+ ```bash
58
+ $ git branch new-feature
59
+ $ git checkout new-feature
60
+ ```
60
61
 
61
62
  Before commiting any code, please read our
62
63
  [Contributor Agreement](http://github.com/SciRuby/sciruby/wiki/Contributor-Agreement).
data/History.txt CHANGED
@@ -599,3 +599,16 @@
599
599
  * Fixed critical bug with transposing a matrix reference slice (by
600
600
  @rajatkapoor)
601
601
 
602
+ === 0.1.0.rc4 / 2014-07-24
603
+
604
+ * No major enhancements.
605
+
606
+ * 1 minor enhancements:
607
+
608
+ * NMatrix#floor and #ceil implemented (by @v0dro)
609
+
610
+ * 2 bug fixes:
611
+
612
+ * Disallowed out-of-bounds rank calls (by @andrewcsmith)
613
+
614
+ * Fixed rspec 3.0 conflict with rspec-longrun 1.0.1
data/Manifest.txt CHANGED
@@ -20,7 +20,6 @@ lib/nmatrix/lapack.rb
20
20
  lib/nmatrix/math.rb
21
21
  lib/nmatrix/monkeys.rb
22
22
  lib/nmatrix/nmatrix.rb
23
- lib/nmatrix/nvector.rb
24
23
  lib/nmatrix/rspec.rb
25
24
  lib/nmatrix/shortcuts.rb
26
25
  lib/nmatrix/version.rb
@@ -66,7 +65,7 @@ ext/nmatrix/math/getf2.h
66
65
  ext/nmatrix/math/getrf.h
67
66
  ext/nmatrix/math/getri.h
68
67
  ext/nmatrix/math/getrs.h
69
- ext/nmatrix/math/idamax.h
68
+ ext/nmatrix/math/imax.h
70
69
  ext/nmatrix/math/inc.h
71
70
  ext/nmatrix/math/laswp.h
72
71
  ext/nmatrix/math/long_dtype.h
data/README.rdoc CHANGED
@@ -4,11 +4,14 @@ Fast Numerical Linear Algebra Library for Ruby
4
4
 
5
5
  * {sciruby.com}[http://sciruby.com]
6
6
  * {Google+}[https://plus.google.com/109304769076178160953/posts]
7
+ * {Google Group - Mailing List}[https://groups.google.com/forum/#!forum/sciruby-dev]
7
8
  * {NMatrix Installation wiki}[https://github.com/SciRuby/nmatrix/wiki/Installation]
8
9
  * {SciRuby Installation guide}[http://sciruby.com/docs#installation]
9
10
 
10
11
  {<img src=https://travis-ci.org/SciRuby/nmatrix.png>}[https://travis-ci.org/SciRuby/nmatrix]
11
12
 
13
+ {<img src="https://codeclimate.com/github/SciRuby/nmatrix.png" />}[https://codeclimate.com/github/SciRuby/nmatrix]
14
+
12
15
  == Description
13
16
 
14
17
  NMatrix is a fast numerical linear algebra library for Ruby, with dense and sparse matrices, written mostly in C and
@@ -38,7 +41,7 @@ If you want to obtain the latest (development) code, you should generally do:
38
41
  bundle install
39
42
  bundle exec rake compile
40
43
  bundle exec rake repackage
41
- gem install pkg/nmatrix-0.1.0.rc3.gem
44
+ gem install pkg/nmatrix-0.1.0.rc4.gem
42
45
 
43
46
  Detailed instructions are available for {Mac}[https://github.com/SciRuby/nmatrix/wiki/Installation#mac-os-x] and {Linux}[https://github.com/SciRuby/nmatrix/wiki/Installation#linux].
44
47
  We are currently working on Mavericks (Mac OS X) installation instructions, but in general, you'll need Homebrew and should
@@ -46,16 +49,13 @@ probably use +brew install gcc48+ instead of using the install script.
46
49
 
47
50
  == Documentation
48
51
 
49
- Carlos Agarie (@agarie) is currently working to improve the documentation. The best way to get help is by posting
50
- {issues}[https://github.com/SciRuby/nmatrix/issues] or sending e-mails to our
51
- {mailing list}[https://groups.google.com/forum/?fromgroups#!forum/sciruby-dev]. You may also email @agarie, or look for
52
- `agarie` on #sciruby at chat.freenode.net if you want to ask questions or offer suggestions.
52
+ If you have a suggestion or want to add documentation for any class or method in NMatrix, please open an issue or send a pull request with the changes.
53
53
 
54
54
  You can find the complete API documentation {on our website}[http://sciruby.com/nmatrix/docs/].
55
55
 
56
56
  == Examples
57
57
 
58
- Create a new NMatrix from a ruby Array:
58
+ Create a new NMatrix from a ruby Array:
59
59
 
60
60
  >> require 'nmatrix'
61
61
  >> NMatrix.new([2, 3], [0, 1, 2, 3, 4, 5], dtype: :int64)
@@ -107,7 +107,7 @@ The following features exist in the current version of NMatrix (0.1.0.rc1):
107
107
  * Point Cloud Library PCD file input
108
108
  * C and C++ API
109
109
  * BLAS internal implementations (no library) and ATLAS (with library) access:
110
- * Level 1: xROT, xROTG (BLAS dtypes only), xASUM, xNRM2
110
+ * Level 1: xROT, xROTG (BLAS dtypes only), xASUM, xNRM2, IxAMAX
111
111
  * Level 2: xGEMV
112
112
  * Level 3: xGEMM, xTRSM
113
113
  * LAPACK ATLAS access:
@@ -125,7 +125,7 @@ The following features exist in the current version of NMatrix (0.1.0.rc1):
125
125
  * Matrix inversions (requires LAPACK; BLAS dtypes only)
126
126
  * Determinant calculation for BLAS dtypes
127
127
  * Vector 2-norms
128
- * Ruby/GSL interoperability (requires {SciRuby's fork of rb-gsl}(http://github.com/SciRuby/rb-gsl))
128
+ * Ruby/GSL interoperability (requires {SciRuby's fork of rb-gsl}[http://github.com/SciRuby/rb-gsl])
129
129
  * slice assignments, e.g.,
130
130
  x[1..3,0..4] = some_other_matrix
131
131
 
@@ -50,4 +50,4 @@ The latter will serve as the capacity when we read a Yale matrix.
50
50
 
51
51
  Then we store the a array, again padding with zeros so it's a multiple of 8 bytes.
52
52
 
53
- Then we store the ija array, padding with zeros so it's a multiple of 8 bytes.
53
+ Then we store the ija array, padding with zeros so it's a multiple of 8 bytes.
@@ -61,7 +61,7 @@ typedef Complex<float64_t> Complex128;
61
61
  /*
62
62
  * Data
63
63
  */
64
-
64
+
65
65
  /*
66
66
  * Classes and Functions
67
67
  */
@@ -72,12 +72,12 @@ class Complex {
72
72
  // The real and immaginary parts of the complex number.
73
73
  Type r;
74
74
  Type i;
75
-
75
+
76
76
  /*
77
77
  * Default constructor.
78
78
  */
79
79
  inline Complex(Type real = 0, Type imaginary = 0) : r(real), i(imaginary) {}
80
-
80
+
81
81
  /*
82
82
  * Copy constructors.
83
83
  */
@@ -112,11 +112,11 @@ class Complex {
112
112
  /*
113
113
  * Binary operator definitions for various types.
114
114
  */
115
-
115
+
116
116
  ////////////////////////////////
117
117
  // Complex-Complex Operations //
118
118
  ////////////////////////////////
119
-
119
+
120
120
  template <typename OtherType>
121
121
  inline Complex<Type> operator+(const Complex<OtherType>& other) const {
122
122
  return Complex<Type>(this->r + other.r, this->i + other.i);
@@ -133,7 +133,7 @@ class Complex {
133
133
  inline Complex<Type> operator-(const Complex<OtherType>& other) const {
134
134
  return Complex<Type>(this->r - other.r, this->i - other.i);
135
135
  }
136
-
136
+
137
137
  template <typename OtherType>
138
138
  inline Complex<Type> operator*(const Complex<OtherType>& other) const {
139
139
  return Complex<Type>(this->r * other.r - this->i * other.i, this->r * other.i + this->i * other.r);
@@ -150,43 +150,43 @@ class Complex {
150
150
  inline Complex<Type> operator/(const Complex<OtherType>& other) const {
151
151
  Type new_r, new_i;
152
152
  Type denom = other.i * other.i + other.r * other.r;
153
-
153
+
154
154
  new_r = (this->r * other.r + this->i * other.i) / denom;
155
155
  new_i = (this->i * other.r - this->r * other.i) / denom;
156
-
156
+
157
157
  return Complex<Type>(new_r, new_i);
158
158
  }
159
-
159
+
160
160
  template <typename OtherType>
161
161
  inline bool operator<(const Complex<OtherType>& other) const {
162
162
  return (this->r < other.r) || ((this->r <= other.r) && (this->i < other.i));
163
163
  }
164
-
164
+
165
165
  template <typename OtherType>
166
166
  inline bool operator>(const Complex<OtherType>& other) const {
167
167
  return (this->r > other.r) || ((this->r >= other.r) && (this->i > other.i));
168
168
  }
169
-
169
+
170
170
  template <typename OtherType>
171
171
  inline bool operator==(const Complex<OtherType>& other) const {
172
172
  return FP_EQUAL(this->r, other.r) && FP_EQUAL(this->i, other.i);
173
173
  }
174
-
174
+
175
175
  template <typename OtherType>
176
176
  inline bool operator!=(const Complex<OtherType>& other) const {
177
177
  return !(*this == other);
178
178
  }
179
-
179
+
180
180
  template <typename OtherType>
181
181
  inline bool operator<=(const Complex<OtherType>& other) const {
182
182
  return (*this < other) || (*this == other);
183
183
  }
184
-
184
+
185
185
  template <typename OtherType>
186
186
  inline bool operator>=(const Complex<OtherType>& other) const {
187
187
  return (*this > other) || (*this == other);
188
188
  }
189
-
189
+
190
190
  template <typename OtherType>
191
191
  inline operator Complex<OtherType> () const {
192
192
  return Complex<OtherType>((OtherType)this->r, (OtherType)this->i);
@@ -195,27 +195,27 @@ class Complex {
195
195
  /////////////////////////////////
196
196
  // Complex-Rational Operations //
197
197
  /////////////////////////////////
198
-
198
+
199
199
  template <typename RationalType>
200
200
  inline Complex<Type> operator+(const Rational<RationalType>& other) const {
201
201
  return *this + Complex<Type>(other);
202
202
  }
203
-
203
+
204
204
  template <typename RationalType>
205
205
  inline Complex<Type> operator-(const Rational<RationalType>& other) const {
206
206
  return *this - Complex<Type>(other);
207
207
  }
208
-
208
+
209
209
  template <typename RationalType>
210
210
  inline Complex<Type> operator*(const Rational<RationalType>& other) const {
211
211
  return *this * Complex<Type>(other);
212
212
  }
213
-
213
+
214
214
  template <typename RationalType>
215
215
  inline Complex<Type> operator/(const Rational<RationalType>& other) const {
216
216
  return *this / Complex<Type>(other);
217
217
  }
218
-
218
+
219
219
  template <typename RationalType, typename = typename std::enable_if<std::is_integral<RationalType>::value>::type>
220
220
  inline bool operator!=(const Rational<RationalType>& other) const {
221
221
  return *this != Complex<Type>(other);
@@ -229,7 +229,7 @@ class Complex {
229
229
  ///////////////////////////////
230
230
  // Complex-Native Operations //
231
231
  ///////////////////////////////
232
-
232
+
233
233
  template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
234
234
  inline Complex<Type> operator+(const NativeType& other) const {
235
235
  return *this + Complex<Type>(other);
@@ -30,6 +30,7 @@
30
30
  */
31
31
 
32
32
  #include <ruby.h>
33
+ #include <stdexcept>
33
34
 
34
35
  /*
35
36
  * Project Includes
@@ -87,7 +88,7 @@ namespace nm {
87
88
  "exp", "log2",
88
89
  "log10", "sqrt", "erf",
89
90
  "erfc", "cbrt", "gamma",
90
- "negate"
91
+ "negate", "floor", "ceil"
91
92
  };
92
93
 
93
94
  } // end of namespace nm
@@ -262,7 +263,13 @@ nm::RubyObject rubyobj_from_cval(void* val, nm::dtype_t dtype) {
262
263
  return RubyObject(*reinterpret_cast<Rational128*>(val));
263
264
 
264
265
  default:
265
- throw;
266
+ try {
267
+ throw std::logic_error("Cannot create ruby object");
268
+ }
269
+ catch (std::logic_error err) {
270
+ printf("%s\n", err.what());
271
+ }
272
+
266
273
  rb_raise(nm_eDataTypeError, "Conversion to RubyObject requested from unknown/invalid data type (did you try to convert from a VALUE?)");
267
274
  }
268
275
  return Qnil;
@@ -55,7 +55,7 @@ namespace nm {
55
55
  const int NUM_DTYPES = 13;
56
56
  const int NUM_ITYPES = 4;
57
57
  const int NUM_EWOPS = 12;
58
- const int NUM_UNARYOPS = 22;
58
+ const int NUM_UNARYOPS = 24;
59
59
  const int NUM_NONCOM_EWOPS = 3;
60
60
 
61
61
  enum ewop_t {
@@ -100,7 +100,9 @@ namespace nm {
100
100
  UNARY_ERFC,
101
101
  UNARY_CBRT,
102
102
  UNARY_GAMMA,
103
- UNARY_NEGATE
103
+ UNARY_NEGATE,
104
+ UNARY_FLOOR,
105
+ UNARY_CEIL
104
106
  };
105
107
 
106
108
  // element-wise and scalar operators
data/ext/nmatrix/math.cpp CHANGED
@@ -122,7 +122,7 @@
122
122
  #include "math/gesvd.h"
123
123
  #include "math/geev.h"
124
124
  #include "math/swap.h"
125
- #include "math/idamax.h"
125
+ #include "math/imax.h"
126
126
  #include "math/scal.h"
127
127
  #include "math/ger.h"
128
128
  #include "math/getf2.h"
@@ -156,11 +156,16 @@ extern "C" {
156
156
  #include <atlas/clapack.h>
157
157
  #endif
158
158
 
159
+ /* BLAS Level 1. */
160
+ static VALUE nm_cblas_scal(VALUE self, VALUE n, VALUE scale, VALUE vector, VALUE incx);
159
161
  static VALUE nm_cblas_nrm2(VALUE self, VALUE n, VALUE x, VALUE incx);
160
162
  static VALUE nm_cblas_asum(VALUE self, VALUE n, VALUE x, VALUE incx);
161
163
  static VALUE nm_cblas_rot(VALUE self, VALUE n, VALUE x, VALUE incx, VALUE y, VALUE incy, VALUE c, VALUE s);
162
164
  static VALUE nm_cblas_rotg(VALUE self, VALUE ab);
165
+ static VALUE nm_cblas_imax(VALUE self, VALUE n, VALUE x, VALUE incx);
163
166
 
167
+ /* BLAS Level 2. */
168
+ /* BLAS Level 3. */
164
169
  static VALUE nm_cblas_gemm(VALUE self, VALUE order, VALUE trans_a, VALUE trans_b, VALUE m, VALUE n, VALUE k, VALUE vAlpha,
165
170
  VALUE a, VALUE lda, VALUE b, VALUE ldb, VALUE vBeta, VALUE c, VALUE ldc);
166
171
  static VALUE nm_cblas_gemv(VALUE self, VALUE trans_a, VALUE m, VALUE n, VALUE vAlpha, VALUE a, VALUE lda,
@@ -174,6 +179,7 @@ extern "C" {
174
179
  static VALUE nm_cblas_syrk(VALUE self, VALUE order, VALUE uplo, VALUE trans, VALUE n, VALUE k, VALUE alpha, VALUE a,
175
180
  VALUE lda, VALUE beta, VALUE c, VALUE ldc);
176
181
 
182
+ /* LAPACK. */
177
183
  static VALUE nm_has_clapack(VALUE self);
178
184
  static VALUE nm_clapack_getrf(VALUE self, VALUE order, VALUE m, VALUE n, VALUE a, VALUE lda);
179
185
  static VALUE nm_clapack_potrf(VALUE self, VALUE order, VALUE uplo, VALUE n, VALUE a, VALUE lda);
@@ -182,7 +188,6 @@ extern "C" {
182
188
  static VALUE nm_clapack_getri(VALUE self, VALUE order, VALUE n, VALUE a, VALUE lda, VALUE ipiv);
183
189
  static VALUE nm_clapack_potri(VALUE self, VALUE order, VALUE uplo, VALUE n, VALUE a, VALUE lda);
184
190
  static VALUE nm_clapack_laswp(VALUE self, VALUE n, VALUE a, VALUE lda, VALUE k1, VALUE k2, VALUE ipiv, VALUE incx);
185
- static VALUE nm_clapack_scal(VALUE self, VALUE n, VALUE scale, VALUE vector, VALUE incx);
186
191
  static VALUE nm_clapack_lauum(VALUE self, VALUE order, VALUE uplo, VALUE n, VALUE a, VALUE lda);
187
192
 
188
193
  static VALUE nm_lapack_gesvd(VALUE self, VALUE jobu, VALUE jobvt, VALUE m, VALUE n, VALUE a, VALUE lda, VALUE s, VALUE u, VALUE ldu, VALUE vt, VALUE ldvt, VALUE lworkspace_size);
@@ -394,7 +399,6 @@ void nm_math_init_blas() {
394
399
  rb_define_singleton_method(cNMatrix_LAPACK, "clapack_getri", (METHOD)nm_clapack_getri, 5);
395
400
  rb_define_singleton_method(cNMatrix_LAPACK, "clapack_potri", (METHOD)nm_clapack_potri, 5);
396
401
  rb_define_singleton_method(cNMatrix_LAPACK, "clapack_laswp", (METHOD)nm_clapack_laswp, 7);
397
- rb_define_singleton_method(cNMatrix_LAPACK, "clapack_scal", (METHOD)nm_clapack_scal, 4);
398
402
  rb_define_singleton_method(cNMatrix_LAPACK, "clapack_lauum", (METHOD)nm_clapack_lauum, 5);
399
403
 
400
404
  /* Non-ATLAS regular LAPACK Functions called via Fortran interface */
@@ -404,10 +408,12 @@ void nm_math_init_blas() {
404
408
 
405
409
  cNMatrix_BLAS = rb_define_module_under(cNMatrix, "BLAS");
406
410
 
411
+ rb_define_singleton_method(cNMatrix_BLAS, "cblas_scal", (METHOD)nm_cblas_scal, 4);
407
412
  rb_define_singleton_method(cNMatrix_BLAS, "cblas_nrm2", (METHOD)nm_cblas_nrm2, 3);
408
413
  rb_define_singleton_method(cNMatrix_BLAS, "cblas_asum", (METHOD)nm_cblas_asum, 3);
409
414
  rb_define_singleton_method(cNMatrix_BLAS, "cblas_rot", (METHOD)nm_cblas_rot, 7);
410
415
  rb_define_singleton_method(cNMatrix_BLAS, "cblas_rotg", (METHOD)nm_cblas_rotg, 1);
416
+ rb_define_singleton_method(cNMatrix_BLAS, "cblas_imax", (METHOD)nm_cblas_imax, 3);
411
417
 
412
418
  rb_define_singleton_method(cNMatrix_BLAS, "cblas_gemm", (METHOD)nm_cblas_gemm, 14);
413
419
  rb_define_singleton_method(cNMatrix_BLAS, "cblas_gemv", (METHOD)nm_cblas_gemv, 11);
@@ -457,6 +463,35 @@ static inline enum CBLAS_TRANSPOSE blas_transpose_sym(VALUE op) {
457
463
  return CblasNoTrans;
458
464
  }
459
465
 
466
+ /*
467
+ * call-seq:
468
+ * NMatrix::BLAS.cblas_scal(n, alpha, vector, inc) -> NMatrix
469
+ *
470
+ * BLAS level 1 function +scal+. Works with all dtypes.
471
+ *
472
+ * Scale +vector+ in-place by +alpha+ and also return it. The operation is as
473
+ * follows:
474
+ * x <- alpha * x
475
+ *
476
+ * - +n+ -> Number of elements of +vector+.
477
+ * - +alpha+ -> Scalar value used in the operation.
478
+ * - +vector+ -> NMatrix of shape [n,1] or [1,n]. Modified in-place.
479
+ * - +inc+ -> Increment used in the scaling function. Should generally be 1.
480
+ */
481
+ static VALUE nm_cblas_scal(VALUE self, VALUE n, VALUE alpha, VALUE vector, VALUE incx) {
482
+ nm::dtype_t dtype = NM_DTYPE(vector);
483
+
484
+ void* scalar = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]);
485
+ rubyval_to_cval(alpha, dtype, scalar);
486
+
487
+ NAMED_DTYPE_TEMPLATE_TABLE(ttable, nm::math::cblas_scal, void, const int n,
488
+ const void* scalar, void* x, const int incx);
489
+
490
+ ttable[dtype](FIX2INT(n), scalar, NM_STORAGE_DENSE(vector)->elements,
491
+ FIX2INT(incx));
492
+
493
+ return vector;
494
+ }
460
495
 
461
496
  /*
462
497
  * Interprets cblas argument which could be :left or :right
@@ -519,14 +554,17 @@ static inline enum CBLAS_ORDER blas_order_sym(VALUE op) {
519
554
  *
520
555
  * The Givens plane rotation can be used to introduce zero elements into a matrix selectively.
521
556
  *
522
- * This function differs from most of the other raw BLAS accessors. Instead of providing a, b, c, s as arguments, you
523
- * should only provide a and b (the inputs), and you should provide them as a single NVector (or the first two elements
524
- * of any dense NMatrix or NVector type, specifically).
557
+ * This function differs from most of the other raw BLAS accessors. Instead of
558
+ * providing a, b, c, s as arguments, you should only provide a and b (the
559
+ * inputs), and you should provide them as the first two elements of any dense
560
+ * NMatrix type.
525
561
  *
526
- * The outputs [c,s] will be returned in a Ruby Array at the end; the input NVector will also be modified in-place.
562
+ * The outputs [c,s] will be returned in a Ruby Array at the end; the input
563
+ * NMatrix will also be modified in-place.
527
564
  *
528
- * If you provide rationals, be aware that there's a high probability of an error, since rotg includes a square root --
529
- * and most rationals' square roots are irrational. You're better off converting to Float first.
565
+ * If you provide rationals, be aware that there's a high probability of an
566
+ * error, since rotg includes a square root -- and most rationals' square roots
567
+ * are irrational. You're better off converting to Float first.
530
568
  *
531
569
  * This function, like the other cblas_ functions, does minimal type-checking.
532
570
  */
@@ -753,7 +791,29 @@ static VALUE nm_cblas_asum(VALUE self, VALUE n, VALUE x, VALUE incx) {
753
791
  return rubyobj_from_cval(Result, rdtype).rval;
754
792
  }
755
793
 
794
+ /*
795
+ * call-seq:
796
+ * NMatrix::BLAS.cblas_imax(n, vector, inc) -> Fixnum
797
+ *
798
+ * BLAS level 1 routine.
799
+ *
800
+ * Return the index of the largest element of +vector+.
801
+ *
802
+ * - +n+ -> Vector's size. Generally, you can use NMatrix#rows or NMatrix#cols.
803
+ * - +vector+ -> A NMatrix of shape [n,1] or [1,n] with any dtype.
804
+ * - +inc+ -> It's the increment used when searching. Use 1 except if you know
805
+ * what you're doing.
806
+ */
807
+ static VALUE nm_cblas_imax(VALUE self, VALUE n, VALUE x, VALUE incx) {
808
+ NAMED_DTYPE_TEMPLATE_TABLE(ttable, nm::math::cblas_imax, int, const int n, const void* x, const int incx);
756
809
 
810
+ nm::dtype_t dtype = NM_DTYPE(x);
811
+
812
+ int index = ttable[dtype](FIX2INT(n), NM_STORAGE_DENSE(x)->elements, FIX2INT(incx));
813
+
814
+ // Convert to Ruby's Int value.
815
+ return INT2FIX(index);
816
+ }
757
817
 
758
818
 
759
819
  /* Call any of the cblas_xgemm functions as directly as possible.
@@ -1198,25 +1258,6 @@ static VALUE nm_lapack_geev(VALUE self, VALUE compute_left, VALUE compute_right,
1198
1258
  }
1199
1259
 
1200
1260
 
1201
- /*
1202
- * Based on LAPACK's dscal function, but for any dtype.
1203
- *
1204
- * In-place modification; returns the modified vector as well.
1205
- */
1206
- static VALUE nm_clapack_scal(VALUE self, VALUE n, VALUE scale, VALUE vector, VALUE incx) {
1207
- nm::dtype_t dtype = NM_DTYPE(vector);
1208
-
1209
- void* da = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]);
1210
- rubyval_to_cval(scale, dtype, da);
1211
-
1212
- NAMED_DTYPE_TEMPLATE_TABLE(ttable, nm::math::clapack_scal, void, const int n, const void* da, void* dx, const int incx);
1213
-
1214
- ttable[dtype](FIX2INT(n), da, NM_STORAGE_DENSE(vector)->elements, FIX2INT(incx));
1215
-
1216
- return vector;
1217
- }
1218
-
1219
-
1220
1261
  static VALUE nm_clapack_lauum(VALUE self, VALUE order, VALUE uplo, VALUE n, VALUE a, VALUE lda) {
1221
1262
  static int (*ttable[nm::NUM_DTYPES])(const enum CBLAS_ORDER, const enum CBLAS_UPLO, const int n, void* a, const int lda) = {
1222
1263
  /*nm::math::clapack_lauum<uint8_t, false>,
@@ -1386,7 +1427,6 @@ static VALUE nm_clapack_getrs(VALUE self, VALUE order, VALUE trans, VALUE n, VAL
1386
1427
  };
1387
1428
 
1388
1429
  // Allocate the C version of the pivot index array
1389
- // TODO: Allow for an NVector here also, maybe?
1390
1430
  int* ipiv_;
1391
1431
  if (TYPE(ipiv) != T_ARRAY) {
1392
1432
  rb_raise(rb_eArgError, "ipiv must be of type Array");
@@ -1493,7 +1533,6 @@ static VALUE nm_clapack_getri(VALUE self, VALUE order, VALUE n, VALUE a, VALUE l
1493
1533
  };
1494
1534
 
1495
1535
  // Allocate the C version of the pivot index array
1496
- // TODO: Allow for an NVector here also, maybe?
1497
1536
  int* ipiv_;
1498
1537
  if (TYPE(ipiv) != T_ARRAY) {
1499
1538
  rb_raise(rb_eArgError, "ipiv must be of type Array");
@@ -1590,7 +1629,6 @@ static VALUE nm_clapack_laswp(VALUE self, VALUE n, VALUE a, VALUE lda, VALUE k1,
1590
1629
  };
1591
1630
 
1592
1631
  // Allocate the C version of the pivot index array
1593
- // TODO: Allow for an NVector here also, maybe?
1594
1632
  int* ipiv_;
1595
1633
  if (TYPE(ipiv) != T_ARRAY) {
1596
1634
  rb_raise(rb_eArgError, "ipiv must be of type Array");