nmatrix 0.2.1 → 0.2.3

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/ext/nmatrix/data/data.cpp +9 -9
  3. data/ext/nmatrix/data/data.h +7 -8
  4. data/ext/nmatrix/data/ruby_object.h +1 -4
  5. data/ext/nmatrix/extconf.rb +9 -127
  6. data/ext/nmatrix/math.cpp +25 -25
  7. data/ext/nmatrix/math/asum.h +10 -31
  8. data/ext/nmatrix/math/cblas_templates_core.h +10 -10
  9. data/ext/nmatrix/math/getrf.h +2 -2
  10. data/ext/nmatrix/math/imax.h +12 -9
  11. data/ext/nmatrix/math/laswp.h +3 -3
  12. data/ext/nmatrix/math/long_dtype.h +16 -3
  13. data/ext/nmatrix/math/magnitude.h +54 -0
  14. data/ext/nmatrix/math/nrm2.h +19 -14
  15. data/ext/nmatrix/math/trsm.h +40 -36
  16. data/ext/nmatrix/math/util.h +14 -0
  17. data/ext/nmatrix/nmatrix.h +39 -1
  18. data/ext/nmatrix/ruby_nmatrix.c +45 -83
  19. data/ext/nmatrix/storage/common.h +9 -3
  20. data/ext/nmatrix/storage/dense/dense.cpp +4 -4
  21. data/ext/nmatrix/storage/list/list.cpp +2 -2
  22. data/ext/nmatrix/storage/yale/class.h +1 -1
  23. data/lib/nmatrix/blas.rb +103 -34
  24. data/lib/nmatrix/io/fortran_format.rb +8 -5
  25. data/lib/nmatrix/io/harwell_boeing.rb +11 -10
  26. data/lib/nmatrix/io/market.rb +9 -6
  27. data/lib/nmatrix/io/mat5_reader.rb +54 -29
  28. data/lib/nmatrix/io/mat_reader.rb +26 -14
  29. data/lib/nmatrix/io/point_cloud.rb +19 -11
  30. data/lib/nmatrix/math.rb +224 -5
  31. data/lib/nmatrix/mkmf.rb +103 -0
  32. data/lib/nmatrix/nmatrix.rb +20 -6
  33. data/lib/nmatrix/shortcuts.rb +415 -0
  34. data/lib/nmatrix/version.rb +1 -1
  35. data/spec/00_nmatrix_spec.rb +50 -1
  36. data/spec/02_slice_spec.rb +21 -21
  37. data/spec/blas_spec.rb +25 -3
  38. data/spec/math_spec.rb +233 -5
  39. data/spec/shortcuts_spec.rb +145 -5
  40. data/spec/spec_helper.rb +24 -1
  41. metadata +20 -4
@@ -9,8 +9,8 @@
9
9
  #
10
10
  # == Copyright Information
11
11
  #
12
- # SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
13
- # NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
12
+ # SciRuby is Copyright (c) 2010 - 2016, Ruby Science Foundation
13
+ # NMatrix is Copyright (c) 2012 - 2016, John Woods and the Ruby Science Foundation
14
14
  #
15
15
  # Please see LICENSE.txt for additional copyright notices.
16
16
  #
@@ -43,22 +43,33 @@ module NMatrix::IO::Matlab
43
43
  :miUINT16 => [Integer, {:signed => false, :bytes => 2}],
44
44
  :miINT32 => [Integer, {:signed => true, :bytes => 4}],
45
45
  :miUINT32 => [Integer, {:signed => false, :bytes => 4}],
46
- :miSINGLE => [Float, {:precision => :single, :bytes => 4, :endian => :native}],
47
- :miDOUBLE => [Float, {:precision => :double, :bytes => 4, :endian => :native}],
46
+ :miSINGLE => [Float, {:precision => :single,
47
+ :bytes => 4, :endian => :native}],
48
+ :miDOUBLE => [Float, {:precision => :double,
49
+ :bytes => 4, :endian => :native}],
48
50
  :miINT64 => [Integer, {:signed => true, :bytes => 8}],
49
51
  :miUINT64 => [Integer, {:signed => false, :bytes => 8}]
50
52
  }
51
53
 
52
54
  DTYPE_PACK_ARGS = {
53
- :byte => [Integer, {:signed => false, :bytes => 1}],
54
- :int8 => [Integer, {:signed => true, :bytes => 1}],
55
- :int16 => [Integer, {:signed => true, :bytes => 2}],
56
- :int32 => [Integer, {:signed => true, :bytes => 4}],
57
- :int64 => [Integer, {:signed => true, :bytes => 8}],
58
- :float32 => [Float, {:precision => :single, :bytes => 4, :endian => :native}],
59
- :float64 => [Float, {:precision => :double, :bytes => 8, :endian => :native}],
60
- :complex64 => [Float, {:precision => :single, :bytes => 4, :endian => :native}], #2x
61
- :complex128 => [Float, {:precision => :double, :bytes => 8, :endian => :native}]
55
+ :byte => [Integer, {:signed => false,
56
+ :bytes => 1}],
57
+ :int8 => [Integer, {:signed => true,
58
+ :bytes => 1}],
59
+ :int16 => [Integer, {:signed => true,
60
+ :bytes => 2}],
61
+ :int32 => [Integer, {:signed => true,
62
+ :bytes => 4}],
63
+ :int64 => [Integer, {:signed => true,
64
+ :bytes => 8}],
65
+ :float32 => [Float, {:precision => :single,
66
+ :bytes => 4, :endian => :native}],
67
+ :float64 => [Float, {:precision => :double,
68
+ :bytes => 8, :endian => :native}],
69
+ :complex64 => [Float, {:precision => :single,
70
+ :bytes => 4, :endian => :native}], #2x
71
+ :complex128 => [Float, {:precision => :double,
72
+ :bytes => 8, :endian => :native}]
62
73
  }
63
74
 
64
75
  ITYPE_PACK_ARGS = {
@@ -68,7 +79,8 @@ module NMatrix::IO::Matlab
68
79
  :uint64 => [Integer, {:signed => false, :bytes => 8}],
69
80
  }
70
81
 
71
- NO_REPACK = [:miINT8, :miUINT8, :miINT16, :miINT32, :miSINGLE, :miDOUBLE, :miINT64]
82
+ NO_REPACK = [:miINT8, :miUINT8, :miINT16,
83
+ :miINT32, :miSINGLE, :miDOUBLE, :miINT64]
72
84
 
73
85
  # Convert from MATLAB dtype to NMatrix dtype.
74
86
  MDTYPE_TO_DTYPE = {
@@ -9,8 +9,8 @@
9
9
  #
10
10
  # == Copyright Information
11
11
  #
12
- # SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
13
- # NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
12
+ # SciRuby is Copyright (c) 2010 - 2016, Ruby Science Foundation
13
+ # NMatrix is Copyright (c) 2012 - 2016, John Woods and the Ruby Science Foundation
14
14
  #
15
15
  # Please see LICENSE.txt for additional copyright notices.
16
16
  #
@@ -55,15 +55,21 @@ module NMatrix::IO::PointCloud
55
55
  end
56
56
 
57
57
  class MetaReader #:nodoc:
58
- ENTRIES = [:version, :fields, :size, :type, :count, :width, :height, :viewpoint, :points, :data]
59
- ASSIGNS = [:version=, :fields=, :size=, :type=, :count=, :width=, :height=, :viewpoint=, :points=, :data=]
60
- CONVERT = [:to_s, :downcase_to_sym, :to_i, :downcase_to_sym, :to_i, :to_i, :to_i, :to_f, :to_i, :downcase_to_sym]
58
+ ENTRIES = [:version, :fields, :size, :type,
59
+ :count, :width, :height, :viewpoint, :points, :data]
60
+ ASSIGNS = [:version=, :fields=, :size=, :type=,
61
+ :count=, :width=, :height=, :viewpoint=, :points=, :data=]
62
+ CONVERT = [:to_s, :downcase_to_sym, :to_i, :downcase_to_sym,
63
+ :to_i, :to_i, :to_i, :to_f, :to_i, :downcase_to_sym]
61
64
 
62
- DTYPE_CONVERT = {:byte => :to_i, :int8 => :to_i, :int16 => :to_i, :int32 => :to_i, :float32 => :to_f, :float64 => :to_f}
65
+ DTYPE_CONVERT = {:byte => :to_i, :int8 => :to_i, :int16 => :to_i,
66
+ :int32 => :to_i, :float32 => :to_f, :float64 => :to_f}
63
67
 
64
68
  # For UINT, just add 1 to the index.
65
- INT_DTYPE_BY_SIZE = {1 => :int8, 2 => :int16, 4 => :int32, 8 => :int64, 16 => :int64}
66
- FLOAT_DTYPE_BY_SIZE = {1 => :float32, 2 => :float32, 4 => :float32, 8 => :float64,16 => :float64}
69
+ INT_DTYPE_BY_SIZE = {1 => :int8, 2 => :int16, 4 => :int32,
70
+ 8 => :int64, 16 => :int64}
71
+ FLOAT_DTYPE_BY_SIZE = {1 => :float32, 2 => :float32, 4 => :float32,
72
+ 8 => :float64,16 => :float64}
67
73
 
68
74
  class << self
69
75
 
@@ -101,7 +107,8 @@ module NMatrix::IO::PointCloud
101
107
  read_entry(f, entry, ASSIGNS[i], CONVERT[i])
102
108
  end
103
109
 
104
- raise(NotImplementedError, "only ASCII supported currently") unless self.data.first == :ascii
110
+ raise(NotImplementedError, "only ASCII supported currently") \
111
+ unless self.data.first == :ascii
105
112
 
106
113
  @matrix = NMatrix.new(self.shape, dtype: self.dtype)
107
114
 
@@ -150,8 +157,9 @@ module NMatrix::IO::PointCloud
150
157
  end
151
158
 
152
159
 
153
- # Determine the dtype for a matrix based on the types and sizes given in the PCD.
154
- # Call this only after read_entry has been called.
160
+ # Determine the dtype for a matrix based on the types and
161
+ # sizes given in the PCD.
162
+ # Call this only after read_entry has been called.
155
163
  def dtype
156
164
  @dtype ||= begin
157
165
  dtypes = self.type.map.with_index do |t,k|
@@ -112,6 +112,55 @@ class NMatrix
112
112
  end
113
113
  alias :inverse :invert
114
114
 
115
+ #
116
+ # call-seq:
117
+ # adjugate! -> NMatrix
118
+ #
119
+ # Calculate the adjugate of the matrix (in-place).
120
+ # Only works on dense matrices.
121
+ #
122
+ # * *Raises* :
123
+ # - +StorageTypeError+ -> only implemented on dense matrices.
124
+ # - +ShapeError+ -> matrix must be square.
125
+ # - +DataTypeError+ -> cannot calculate adjugate of an integer matrix in-place.
126
+ #
127
+ def adjugate!
128
+ raise(StorageTypeError, "adjugate only works on dense matrices currently") unless self.dense?
129
+ raise(ShapeError, "Cannot calculate adjugate of a non-square matrix") unless self.dim == 2 && self.shape[0] == self.shape[1]
130
+ raise(DataTypeError, "Cannot calculate adjugate of an integer matrix in-place") if self.integer_dtype?
131
+ d = self.det
132
+ self.invert!
133
+ self.map! { |e| e * d }
134
+ self
135
+ end
136
+ alias :adjoint! :adjugate!
137
+
138
+ #
139
+ # call-seq:
140
+ # adjugate -> NMatrix
141
+ #
142
+ # Make a copy of the matrix and calculate the adjugate of the matrix.
143
+ # Only works on dense matrices.
144
+ #
145
+ # * *Returns* :
146
+ # - A dense NMatrix. Will be the same type as the input NMatrix,
147
+ # except if the input is an integral dtype, in which case it will be a
148
+ # :float64 NMatrix.
149
+ #
150
+ # * *Raises* :
151
+ # - +StorageTypeError+ -> only implemented on dense matrices.
152
+ # - +ShapeError+ -> matrix must be square.
153
+ #
154
+ def adjugate
155
+ raise(StorageTypeError, "adjugate only works on dense matrices currently") unless self.dense?
156
+ raise(ShapeError, "Cannot calculate adjugate of a non-square matrix") unless self.dim == 2 && self.shape[0] == self.shape[1]
157
+ d = self.det
158
+ mat = self.invert
159
+ mat.map! { |e| e * d }
160
+ mat
161
+ end
162
+ alias :adjoint :adjugate
163
+
115
164
  #
116
165
  # call-seq:
117
166
  # getrf! -> Array
@@ -153,6 +202,104 @@ class NMatrix
153
202
  return ipiv
154
203
  end
155
204
 
205
+ #
206
+ # call-seq:
207
+ # geqrf! -> shape.min x 1 NMatrix
208
+ #
209
+ # QR factorization of a general M-by-N matrix +A+.
210
+ #
211
+ # The QR factorization is A = QR, where Q is orthogonal and R is Upper Triangular
212
+ # +A+ is overwritten with the elements of R and Q with Q being represented by the
213
+ # elements below A's diagonal and an array of scalar factors in the output NMatrix.
214
+ #
215
+ # The matrix Q is represented as a product of elementary reflectors
216
+ # Q = H(1) H(2) . . . H(k), where k = min(m,n).
217
+ #
218
+ # Each H(i) has the form
219
+ #
220
+ # H(i) = I - tau * v * v'
221
+ #
222
+ # http://www.netlib.org/lapack/explore-html/d3/d69/dgeqrf_8f.html
223
+ #
224
+ # Only works for dense matrices.
225
+ #
226
+ # * *Returns* :
227
+ # - Vector TAU. Q and R are stored in A. Q is represented by TAU and A
228
+ # * *Raises* :
229
+ # - +StorageTypeError+ -> LAPACK functions only work on dense matrices.
230
+ #
231
+ def geqrf!
232
+ # The real implementation is in lib/nmatrix/lapacke.rb
233
+ raise(NotImplementedError, "geqrf! requires the nmatrix-lapacke gem")
234
+ end
235
+
236
+ #
237
+ # call-seq:
238
+ # ormqr(tau) -> NMatrix
239
+ # ormqr(tau, side, transpose, c) -> NMatrix
240
+ #
241
+ # Returns the product Q * c or c * Q after a call to geqrf! used in QR factorization.
242
+ # +c+ is overwritten with the elements of the result NMatrix if supplied. Q is the orthogonal matrix
243
+ # represented by tau and the calling NMatrix
244
+ #
245
+ # Only works on float types, use unmqr for complex types.
246
+ #
247
+ # == Arguments
248
+ #
249
+ # * +tau+ - vector containing scalar factors of elementary reflectors
250
+ # * +side+ - direction of multiplication [:left, :right]
251
+ # * +transpose+ - apply Q with or without transpose [false, :transpose]
252
+ # * +c+ - NMatrix multplication argument that is overwritten, no argument assumes c = identity
253
+ #
254
+ # * *Returns* :
255
+ #
256
+ # - Q * c or c * Q Where Q may be transposed before multiplication.
257
+ #
258
+ #
259
+ # * *Raises* :
260
+ # - +StorageTypeError+ -> LAPACK functions only work on dense matrices.
261
+ # - +TypeError+ -> Works only on floating point matrices, use unmqr for complex types
262
+ # - +TypeError+ -> c must have the same dtype as the calling NMatrix
263
+ #
264
+ def ormqr(tau, side=:left, transpose=false, c=nil)
265
+ # The real implementation is in lib/nmatrix/lapacke.rb
266
+ raise(NotImplementedError, "ormqr requires the nmatrix-lapacke gem")
267
+
268
+ end
269
+
270
+ #
271
+ # call-seq:
272
+ # unmqr(tau) -> NMatrix
273
+ # unmqr(tau, side, transpose, c) -> NMatrix
274
+ #
275
+ # Returns the product Q * c or c * Q after a call to geqrf! used in QR factorization.
276
+ # +c+ is overwritten with the elements of the result NMatrix if it is supplied. Q is the orthogonal matrix
277
+ # represented by tau and the calling NMatrix
278
+ #
279
+ # Only works on complex types, use ormqr for float types.
280
+ #
281
+ # == Arguments
282
+ #
283
+ # * +tau+ - vector containing scalar factors of elementary reflectors
284
+ # * +side+ - direction of multiplication [:left, :right]
285
+ # * +transpose+ - apply Q as Q or its complex conjugate [false, :complex_conjugate]
286
+ # * +c+ - NMatrix multplication argument that is overwritten, no argument assumes c = identity
287
+ #
288
+ # * *Returns* :
289
+ #
290
+ # - Q * c or c * Q Where Q may be transformed to its complex conjugate before multiplication.
291
+ #
292
+ #
293
+ # * *Raises* :
294
+ # - +StorageTypeError+ -> LAPACK functions only work on dense matrices.
295
+ # - +TypeError+ -> Works only on floating point matrices, use unmqr for complex types
296
+ # - +TypeError+ -> c must have the same dtype as the calling NMatrix
297
+ #
298
+ def unmqr(tau, side=:left, transpose=false, c=nil)
299
+ # The real implementation is in lib/nmatrix/lapacke.rb
300
+ raise(NotImplementedError, "unmqr requires the nmatrix-lapacke gem")
301
+ end
302
+
156
303
  #
157
304
  # call-seq:
158
305
  # potrf!(upper_or_lower) -> NMatrix
@@ -232,6 +379,46 @@ class NMatrix
232
379
  [t, FactorizeLUMethods.permutation_matrix_from(pivot)]
233
380
  end
234
381
 
382
+ #
383
+ # call-seq:
384
+ # factorize_qr -> [Q,R]
385
+ #
386
+ # QR factorization of a matrix without column pivoting.
387
+ # Q is orthogonal and R is upper triangular if input is square or upper trapezoidal if
388
+ # input is rectangular.
389
+ #
390
+ # Only works for dense matrices.
391
+ #
392
+ # * *Returns* :
393
+ # - Array containing Q and R matrices
394
+ #
395
+ # * *Raises* :
396
+ # - +StorageTypeError+ -> only implemented for desnse storage.
397
+ # - +ShapeError+ -> Input must be a 2-dimensional matrix to have a QR decomposition.
398
+ #
399
+ def factorize_qr
400
+ raise(NotImplementedError, "only implemented for dense storage") unless self.stype == :dense
401
+ raise(ShapeError, "Input must be a 2-dimensional matrix to have a QR decomposition") unless self.dim == 2
402
+
403
+ rows, columns = self.shape
404
+ r = self.clone
405
+ tau = r.geqrf!
406
+
407
+ #Obtain Q
408
+ q = self.complex_dtype? ? r.unmqr(tau) : r.ormqr(tau)
409
+
410
+ #Obtain R
411
+ if rows <= columns
412
+ r.upper_triangle!
413
+ #Need to account for upper trapezoidal structure if R is a tall rectangle (rows > columns)
414
+ else
415
+ r[0...columns, 0...columns].upper_triangle!
416
+ r[columns...rows, 0...columns] = 0
417
+ end
418
+
419
+ [q,r]
420
+ end
421
+
235
422
  # Reduce self to upper hessenberg form using householder transforms.
236
423
  #
237
424
  # == References
@@ -333,10 +520,8 @@ class NMatrix
333
520
  when :lower_tri, :lower_triangular
334
521
  raise(ArgumentError, "lower triangular solver does not work with complex dtypes") if
335
522
  complex_dtype? or b.complex_dtype?
336
- # this is a workaround; see https://github.com/SciRuby/nmatrix/issues/422
337
- x = x.transpose
338
- NMatrix::BLAS::cblas_trsm(:row, :right, :lower, :transpose, :nounit, nrhs, n, 1.0, self, n, x, n)
339
- x.transpose
523
+ NMatrix::BLAS::cblas_trsm(:row, :left, :lower, false, :nounit, n, nrhs, 1.0, self, n, x, nrhs)
524
+ x
340
525
  when :pos_def, :positive_definite
341
526
  u, l = self.factorize_cholesky
342
527
  z = l.solve(b, form: :lower_tri)
@@ -848,7 +1033,6 @@ class NMatrix
848
1033
  end.cast(self.stype, abs_dtype)
849
1034
  end
850
1035
 
851
-
852
1036
  #
853
1037
  # call-seq:
854
1038
  # absolute_sum -> Numeric
@@ -883,6 +1067,41 @@ class NMatrix
883
1067
  end
884
1068
  alias :norm2 :nrm2
885
1069
 
1070
+ #
1071
+ # call-seq:
1072
+ # scale! -> NMatrix
1073
+ #
1074
+ # == Arguments
1075
+ # - +alpha+ -> Scalar value used in the operation.
1076
+ # - +inc+ -> Increment used in the scaling function. Should generally be 1.
1077
+ # - +n+ -> Number of elements of +vector+.
1078
+ #
1079
+ # This is a destructive method, modifying the source NMatrix. See also #scale.
1080
+ # Return the scaling result of the matrix. BLAS scal will be invoked if provided.
1081
+
1082
+ def scale!(alpha, incx=1, n=nil)
1083
+ raise(DataTypeError, "Incompatible data type for the scaling factor") unless
1084
+ NMatrix::upcast(self.dtype, NMatrix::min_dtype(alpha)) == self.dtype
1085
+ return NMatrix::BLAS::scal(alpha, self, incx, self.size / incx) if NMatrix::BLAS.method_defined? :scal
1086
+ self.each_stored_with_indices do |e, *i|
1087
+ self[*i] = e*alpha
1088
+ end
1089
+ end
1090
+
1091
+ #
1092
+ # call-seq:
1093
+ # scale -> NMatrix
1094
+ #
1095
+ # == Arguments
1096
+ # - +alpha+ -> Scalar value used in the operation.
1097
+ # - +inc+ -> Increment used in the scaling function. Should generally be 1.
1098
+ # - +n+ -> Number of elements of +vector+.
1099
+ #
1100
+ # Return the scaling result of the matrix. BLAS scal will be invoked if provided.
1101
+
1102
+ def scale(alpha, incx=1, n=nil)
1103
+ return self.clone.scale!(alpha, incx, n)
1104
+ end
886
1105
 
887
1106
  alias :permute_columns :laswp
888
1107
  alias :permute_columns! :laswp!
@@ -0,0 +1,103 @@
1
+ require "mkmf"
2
+
3
+ if RUBY_VERSION < '1.9'
4
+ raise NotImplementedError, "Sorry, you need at least Ruby 1.9!"
5
+ end
6
+
7
+ # Function derived from NArray's extconf.rb.
8
+ def create_conf_h(file) #:nodoc:
9
+ print "creating #{file}\n"
10
+ File.open(file, 'w') do |hfile|
11
+ header_guard = file.upcase.sub(/\s|\./, '_')
12
+
13
+ hfile.puts "#ifndef #{header_guard}"
14
+ hfile.puts "#define #{header_guard}"
15
+ hfile.puts
16
+
17
+ # FIXME: Find a better way to do this:
18
+ hfile.puts "#define RUBY_2 1" if RUBY_VERSION >= '2.0'
19
+
20
+ for line in $defs
21
+ line =~ /^-D(.*)/
22
+ hfile.printf "#define %s 1\n", $1
23
+ end
24
+
25
+ hfile.puts
26
+ hfile.puts "#endif"
27
+ end
28
+ end
29
+
30
+ def find_newer_gplusplus #:nodoc:
31
+ print "checking for apparent GNU g++ binary with C++0x/C++11 support... "
32
+ [9,8,7,6,5,4,3].each do |minor|
33
+ ver = "4.#{minor}"
34
+ gpp = "g++-#{ver}"
35
+ result = `which #{gpp}`
36
+ next if result.empty?
37
+ CONFIG['CXX'] = gpp
38
+ puts ver
39
+ return CONFIG['CXX']
40
+ end
41
+ false
42
+ end
43
+
44
+ def gplusplus_version
45
+ cxxvar = proc { |n| `#{CONFIG['CXX']} -E -dM - <#{File::NULL} | grep #{n}`.chomp.split(' ')[2] }
46
+ major = cxxvar.call('__GNUC__')
47
+ minor = cxxvar.call('__GNUC_MINOR__')
48
+ patch = cxxvar.call('__GNUC_PATCHLEVEL__')
49
+
50
+ raise("unable to determine g++ version (match to get version was nil)") if major.nil? || minor.nil? || patch.nil?
51
+
52
+ "#{major}.#{minor}.#{patch}"
53
+ end
54
+
55
+
56
+ if /cygwin|mingw/ =~ RUBY_PLATFORM
57
+ CONFIG["DLDFLAGS"] << " --output-lib libnmatrix.a"
58
+ end
59
+
60
+ # Fix compiler pairing
61
+ if CONFIG['CC'] == 'clang' && CONFIG['CXX'] != 'clang++'
62
+ puts "WARNING: CONFIG['CXX'] is not 'clang++' even though CONFIG['CC'] is 'clang'.",
63
+ "WARNING: Force to use clang++ together with clang."
64
+
65
+ CONFIG['CXX'] = 'clang++'
66
+ end
67
+
68
+ if CONFIG['CXX'] == 'clang++'
69
+ $CXX_STANDARD = 'c++11'
70
+ else
71
+ version = gplusplus_version
72
+ if version < '4.3.0' && CONFIG['CXX'] == 'g++' # see if we can find a newer G++, unless it's been overridden by user
73
+ if !find_newer_gplusplus
74
+ raise("You need a version of g++ which supports -std=c++0x or -std=c++11. If you're on a Mac and using Homebrew, we recommend using mac-brew-gcc.sh to install a more recent g++.")
75
+ end
76
+ version = gplusplus_version
77
+ end
78
+
79
+ if version < '4.7.0'
80
+ $CXX_STANDARD = 'c++0x'
81
+ else
82
+ $CXX_STANDARD = 'c++11'
83
+ end
84
+ puts "using C++ standard... #{$CXX_STANDARD}"
85
+ puts "g++ reports version... " + `#{CONFIG['CXX']} --version|head -n 1|cut -f 3 -d " "`
86
+ end
87
+
88
+ # For release, these next two should both be changed to -O3.
89
+ $CFLAGS += " -O3 "
90
+ #$CFLAGS += " -static -O0 -g "
91
+ $CXXFLAGS += " -O3 -std=#{$CXX_STANDARD} " #-fmax-errors=10 -save-temps
92
+ #$CXXFLAGS += " -static -O0 -g -std=#{$CXX_STANDARD} "
93
+
94
+ CONFIG['warnflags'].gsub!('-Wshorten-64-to-32', '') # doesn't work except in Mac-patched gcc (4.2)
95
+ CONFIG['warnflags'].gsub!('-Wdeclaration-after-statement', '')
96
+ CONFIG['warnflags'].gsub!('-Wimplicit-function-declaration', '')
97
+
98
+ have_func("rb_array_const_ptr", "ruby.h")
99
+ have_macro("FIX_CONST_VALUE_PTR", "ruby.h")
100
+ have_macro("RARRAY_CONST_PTR", "ruby.h")
101
+ have_macro("RARRAY_AREF", "ruby.h")
102
+
103
+