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.
- checksums.yaml +4 -4
- data/ext/nmatrix/data/data.cpp +9 -9
- data/ext/nmatrix/data/data.h +7 -8
- data/ext/nmatrix/data/ruby_object.h +1 -4
- data/ext/nmatrix/extconf.rb +9 -127
- data/ext/nmatrix/math.cpp +25 -25
- data/ext/nmatrix/math/asum.h +10 -31
- data/ext/nmatrix/math/cblas_templates_core.h +10 -10
- data/ext/nmatrix/math/getrf.h +2 -2
- data/ext/nmatrix/math/imax.h +12 -9
- data/ext/nmatrix/math/laswp.h +3 -3
- data/ext/nmatrix/math/long_dtype.h +16 -3
- data/ext/nmatrix/math/magnitude.h +54 -0
- data/ext/nmatrix/math/nrm2.h +19 -14
- data/ext/nmatrix/math/trsm.h +40 -36
- data/ext/nmatrix/math/util.h +14 -0
- data/ext/nmatrix/nmatrix.h +39 -1
- data/ext/nmatrix/ruby_nmatrix.c +45 -83
- data/ext/nmatrix/storage/common.h +9 -3
- data/ext/nmatrix/storage/dense/dense.cpp +4 -4
- data/ext/nmatrix/storage/list/list.cpp +2 -2
- data/ext/nmatrix/storage/yale/class.h +1 -1
- data/lib/nmatrix/blas.rb +103 -34
- data/lib/nmatrix/io/fortran_format.rb +8 -5
- data/lib/nmatrix/io/harwell_boeing.rb +11 -10
- data/lib/nmatrix/io/market.rb +9 -6
- data/lib/nmatrix/io/mat5_reader.rb +54 -29
- data/lib/nmatrix/io/mat_reader.rb +26 -14
- data/lib/nmatrix/io/point_cloud.rb +19 -11
- data/lib/nmatrix/math.rb +224 -5
- data/lib/nmatrix/mkmf.rb +103 -0
- data/lib/nmatrix/nmatrix.rb +20 -6
- data/lib/nmatrix/shortcuts.rb +415 -0
- data/lib/nmatrix/version.rb +1 -1
- data/spec/00_nmatrix_spec.rb +50 -1
- data/spec/02_slice_spec.rb +21 -21
- data/spec/blas_spec.rb +25 -3
- data/spec/math_spec.rb +233 -5
- data/spec/shortcuts_spec.rb +145 -5
- data/spec/spec_helper.rb +24 -1
- metadata +20 -4
@@ -9,8 +9,8 @@
|
|
9
9
|
#
|
10
10
|
# == Copyright Information
|
11
11
|
#
|
12
|
-
# SciRuby is Copyright (c) 2010 -
|
13
|
-
# NMatrix is Copyright (c) 2012 -
|
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,
|
47
|
-
|
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,
|
54
|
-
|
55
|
-
:
|
56
|
-
|
57
|
-
:
|
58
|
-
|
59
|
-
:
|
60
|
-
|
61
|
-
:
|
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,
|
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 -
|
13
|
-
# NMatrix is Copyright (c) 2012 -
|
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,
|
59
|
-
|
60
|
-
|
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,
|
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,
|
66
|
-
|
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")
|
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
|
154
|
-
#
|
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|
|
data/lib/nmatrix/math.rb
CHANGED
@@ -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
|
-
|
337
|
-
x
|
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!
|
data/lib/nmatrix/mkmf.rb
ADDED
@@ -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
|
+
|