multiarray 0.11.3 → 0.11.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +61 -0
- data/Rakefile +1 -1
- data/lib/multiarray.rb +28 -0
- data/lib/multiarray/complex.rb +310 -13
- data/lib/multiarray/composite.rb +7 -0
- data/lib/multiarray/diagonal.rb +18 -3
- data/lib/multiarray/elementwise.rb +7 -2
- data/lib/multiarray/float.rb +43 -3
- data/lib/multiarray/gcccache.rb +4 -1
- data/lib/multiarray/gcccontext.rb +119 -21
- data/lib/multiarray/gccfunction.rb +92 -3
- data/lib/multiarray/gcctype.rb +26 -0
- data/lib/multiarray/gccvalue.rb +204 -2
- data/lib/multiarray/histogram.rb +65 -1
- data/lib/multiarray/index.rb +11 -0
- data/lib/multiarray/inject.rb +18 -1
- data/lib/multiarray/int.rb +49 -18
- data/lib/multiarray/integral.rb +65 -1
- data/lib/multiarray/lambda.rb +19 -5
- data/lib/multiarray/list.rb +8 -0
- data/lib/multiarray/lookup.rb +8 -1
- data/lib/multiarray/lut.rb +96 -2
- data/lib/multiarray/methods.rb +13 -3
- data/lib/multiarray/multiarray.rb +11 -0
- data/lib/multiarray/node.rb +52 -9
- data/lib/multiarray/operations.rb +118 -15
- data/lib/multiarray/pointer.rb +35 -1
- data/lib/multiarray/rgb.rb +139 -14
- data/lib/multiarray/sequence.rb +140 -2
- data/lib/multiarray/shortcuts.rb +76 -30
- data/lib/multiarray/store.rb +54 -0
- data/lib/multiarray/variable.rb +19 -0
- data/test/tc_lazy.rb +9 -0
- metadata +3 -3
data/README.md
CHANGED
@@ -1,3 +1,64 @@
|
|
1
1
|
multiarray
|
2
2
|
==========
|
3
|
+
|
4
|
+
**Author**: Jan Wedekind
|
5
|
+
**Copyright**: 2010
|
6
|
+
**License**: GPL
|
7
|
+
|
8
|
+
Synopsis
|
9
|
+
--------
|
10
|
+
|
3
11
|
This Ruby-extension defines the class {Hornetseye::MultiArray} and other native datatypes. {Hornetseye::MultiArray} provides multi-dimensional Ruby arrays with elements of same type. The extension is designed to be mostly compatible with Masahiro Tanaka's NArray. However it allows the definition of custom element types and operations on them. This work was also inspired by Ronald Garcia's boost::multi_array and by Todd Veldhuizen's Blitz++.
|
12
|
+
|
13
|
+
Installation
|
14
|
+
------------
|
15
|
+
|
16
|
+
To install this Ruby extension, use the following command:
|
17
|
+
|
18
|
+
$ sudo gem install multiarray
|
19
|
+
|
20
|
+
Alternatively you can install the Ruby extension from source as follows:
|
21
|
+
|
22
|
+
$ sudo rake install
|
23
|
+
|
24
|
+
Usage
|
25
|
+
-----
|
26
|
+
|
27
|
+
Simply run Interactive Ruby:
|
28
|
+
|
29
|
+
$ irb
|
30
|
+
|
31
|
+
You can load the Ruby extension as shown below. The example shows a few array operations and their results.
|
32
|
+
|
33
|
+
require 'rubygems'
|
34
|
+
require 'multiarray'
|
35
|
+
include Hornetseye
|
36
|
+
m = MultiArray[ [ 2, 3 ], [ 4, 5 ] ]
|
37
|
+
# MultiArray(UBYTE,2,2):
|
38
|
+
# [ [ 2, 3 ],
|
39
|
+
# [ 4, 5 ] ]
|
40
|
+
m[ 1, 0 ]
|
41
|
+
# 3
|
42
|
+
m[ 0 ][ 1 ]
|
43
|
+
# 3
|
44
|
+
m + 1
|
45
|
+
# MultiArray(UBYTE,2,2):
|
46
|
+
# [ [ 3, 4 ],
|
47
|
+
# [ 5, 6 ] ]
|
48
|
+
1.0 / m
|
49
|
+
# MultiArray(DFLOAT,2,2):
|
50
|
+
# [ [ 0.5, 0.3333333333333333 ],
|
51
|
+
# [ 0.25, 0.2 ] ]
|
52
|
+
m[ 1 ]
|
53
|
+
# Sequence(UBYTE,2):
|
54
|
+
# [ 4, 5 ]
|
55
|
+
sum { |i,j| m[i,j] }
|
56
|
+
# 14
|
57
|
+
sum { |j| m[j] }
|
58
|
+
# Sequence(UBYTE,2):
|
59
|
+
# [ 6, 8 ]
|
60
|
+
-m.to_byte
|
61
|
+
# MultiArray(BYTE,2,2):
|
62
|
+
# [ [ -2, -3 ],
|
63
|
+
# [ -4, -5 ] ]
|
64
|
+
|
data/Rakefile
CHANGED
data/lib/multiarray.rb
CHANGED
@@ -75,6 +75,10 @@ class Object
|
|
75
75
|
|
76
76
|
# Object#instance_exec is defined if it does not exist already
|
77
77
|
#
|
78
|
+
# @param [Array<Object>] arguments The arguments to pass to the block.
|
79
|
+
# @param [Proc] block The block to be executed in the object's environment.
|
80
|
+
# @return [Object] The result of executing the block.
|
81
|
+
#
|
78
82
|
# @private
|
79
83
|
def instance_exec( *arguments, &block )
|
80
84
|
block.bind( self )[ *arguments ]
|
@@ -310,6 +314,9 @@ class Fixnum
|
|
310
314
|
|
311
315
|
# +&+ is modified to work with this library
|
312
316
|
#
|
317
|
+
# @param [Object] other Second operand for binary +and+ operation.
|
318
|
+
# @return [Object] Result of binary operation.
|
319
|
+
#
|
313
320
|
# @private
|
314
321
|
def intand_with_hornetseye( other )
|
315
322
|
if other.is_a? Integer
|
@@ -324,6 +331,9 @@ class Fixnum
|
|
324
331
|
|
325
332
|
# +|+ is modified to work with this library
|
326
333
|
#
|
334
|
+
# @param [Object] other Second operand for binary +or+ operation.
|
335
|
+
# @return [Object] Result of binary operation.
|
336
|
+
#
|
327
337
|
# @private
|
328
338
|
def intor_with_hornetseye( other )
|
329
339
|
if other.is_a? Integer
|
@@ -338,6 +348,9 @@ class Fixnum
|
|
338
348
|
|
339
349
|
# +^+ is modified to work with this library
|
340
350
|
#
|
351
|
+
# @param [Object] other Second operand for binary +xor+ operation.
|
352
|
+
# @return [Object] Result of binary operation.
|
353
|
+
#
|
341
354
|
# @private
|
342
355
|
def intxor_with_hornetseye( other )
|
343
356
|
if other.is_a? Integer
|
@@ -352,6 +365,9 @@ class Fixnum
|
|
352
365
|
|
353
366
|
# +<<+ is modified to work with this library
|
354
367
|
#
|
368
|
+
# @param [Object] other Second operand for binary +shl+ operation.
|
369
|
+
# @return [Object] Result of binary operation.
|
370
|
+
#
|
355
371
|
# @private
|
356
372
|
def shl_with_hornetseye( other )
|
357
373
|
if other.is_a? Integer
|
@@ -366,6 +382,9 @@ class Fixnum
|
|
366
382
|
|
367
383
|
# +>>+ is modified to work with this library
|
368
384
|
#
|
385
|
+
# @param [Object] other Second operand for binary +shr+ operation.
|
386
|
+
# @return [Object] Result of binary operation.
|
387
|
+
#
|
369
388
|
# @private
|
370
389
|
def shr_with_hornetseye( other )
|
371
390
|
if other.is_a? Integer
|
@@ -380,6 +399,12 @@ class Fixnum
|
|
380
399
|
|
381
400
|
if method_defined? :rpower
|
382
401
|
|
402
|
+
# +**+ is modified to work with this library
|
403
|
+
#
|
404
|
+
# @param [Object] other Second operand for binary operation.
|
405
|
+
# @return [Object] Result of binary operation.
|
406
|
+
#
|
407
|
+
# @private
|
383
408
|
def power_with_hornetseye( other )
|
384
409
|
if other.is_a? Hornetseye::Node
|
385
410
|
x, y = other.coerce self
|
@@ -437,6 +462,7 @@ class Range
|
|
437
462
|
|
438
463
|
end
|
439
464
|
|
465
|
+
# The +Numeric+ class is extended with a few methods
|
440
466
|
class Numeric
|
441
467
|
|
442
468
|
# Compute complex conjugate
|
@@ -497,6 +523,7 @@ class Numeric
|
|
497
523
|
|
498
524
|
end
|
499
525
|
|
526
|
+
# The +Array+ class is extended
|
500
527
|
class Array
|
501
528
|
|
502
529
|
# Element-wise operation based on element and its index
|
@@ -516,6 +543,7 @@ require 'complex'
|
|
516
543
|
require 'malloc'
|
517
544
|
require 'rbconfig'
|
518
545
|
require 'set'
|
546
|
+
require 'thread'
|
519
547
|
require 'tmpdir'
|
520
548
|
require 'multiarray/malloc'
|
521
549
|
require 'multiarray/list'
|
data/lib/multiarray/complex.rb
CHANGED
@@ -17,11 +17,14 @@
|
|
17
17
|
# Namespace of Hornetseye computer vision library
|
18
18
|
module Hornetseye
|
19
19
|
|
20
|
+
# When compiling operations this class replaces +Complex+
|
21
|
+
#
|
22
|
+
# @private
|
20
23
|
class InternalComplex
|
21
24
|
|
22
25
|
class << self
|
23
26
|
|
24
|
-
# Check compatibility of other type
|
27
|
+
# Check compatibility of other type
|
25
28
|
#
|
26
29
|
# This method checks whether binary operations with the other Ruby object can
|
27
30
|
# be performed without requiring coercion.
|
@@ -30,30 +33,58 @@ module Hornetseye
|
|
30
33
|
#
|
31
34
|
# @return [Boolean] Returns +false+ if Ruby object requires
|
32
35
|
# coercion.
|
36
|
+
#
|
37
|
+
# @private
|
33
38
|
def generic?( value )
|
34
39
|
value.is_a?( Numeric ) or value.is_a?( GCCValue )
|
35
40
|
end
|
36
41
|
|
42
|
+
# Construct complex number using polar coordinates
|
43
|
+
#
|
44
|
+
# @param [GCCValue,Numeric] r Radius or complex modulus.
|
45
|
+
# @param [GCCValue,Numeric] theta Angle or complex argument.
|
46
|
+
#
|
47
|
+
# @return [InternalComplex] The specified complex number.
|
48
|
+
#
|
49
|
+
# @private
|
37
50
|
def polar( r, theta )
|
38
51
|
new r * Math.cos( theta ), r * Math.sin( theta )
|
39
52
|
end
|
40
53
|
|
41
54
|
end
|
42
55
|
|
43
|
-
|
56
|
+
# Get real component of complex number
|
57
|
+
#
|
58
|
+
# @return [GCCValue,Numeric] The real component.
|
59
|
+
#
|
60
|
+
# @private
|
61
|
+
attr_accessor :real
|
44
62
|
|
63
|
+
# Get imaginary component of complex number
|
64
|
+
#
|
65
|
+
# @return [GCCValue,Numeric] The imaginary component.
|
66
|
+
#
|
67
|
+
# @private
|
68
|
+
attr_accessor :imag
|
69
|
+
|
70
|
+
# Constructor for complex number
|
71
|
+
#
|
72
|
+
# @param [GCCValue,Numeric] real The real component.
|
73
|
+
# @param [GCCValue,Numeric] imag The imaginary component.
|
74
|
+
#
|
75
|
+
# @return [InternalComplex] The complex number.
|
45
76
|
def initialize( real, imag )
|
46
77
|
@real, @imag = real, imag
|
47
78
|
end
|
48
79
|
|
49
|
-
# Return string with information about this object
|
80
|
+
# Return string with information about this object
|
50
81
|
#
|
51
82
|
# @return [String] Returns a string (e.g. "InternalComplex(1,2)").
|
52
83
|
def inspect
|
53
84
|
"InternalComplex(#{@real.inspect},#{@imag.inspect})"
|
54
85
|
end
|
55
86
|
|
56
|
-
# Return string with information about this object
|
87
|
+
# Return string with information about this object
|
57
88
|
#
|
58
89
|
# @return [String] Returns a string (e.g. "InternalComplex(1,2)").
|
59
90
|
def to_s
|
@@ -71,6 +102,13 @@ module Hornetseye
|
|
71
102
|
@real, @imag = value.real, value.imag
|
72
103
|
end
|
73
104
|
|
105
|
+
# Coerce with other object
|
106
|
+
#
|
107
|
+
# @param [InternalComplex,Object] other Other object.
|
108
|
+
#
|
109
|
+
# @return [Array<InternalComplex>] Result of coercion.
|
110
|
+
#
|
111
|
+
# @private
|
74
112
|
def coerce( other )
|
75
113
|
if other.is_a? InternalComplex
|
76
114
|
return other, self
|
@@ -81,30 +119,67 @@ module Hornetseye
|
|
81
119
|
end
|
82
120
|
end
|
83
121
|
|
122
|
+
# Compute complex conjugate
|
123
|
+
#
|
124
|
+
# @return [InternalComplex] The result.
|
125
|
+
#
|
126
|
+
# @private
|
84
127
|
def conj
|
85
128
|
InternalComplex.new @real, -@imag
|
86
129
|
end
|
87
130
|
|
131
|
+
# Compute complex modulus
|
132
|
+
#
|
133
|
+
# @return [InternalComplex] The result.
|
134
|
+
#
|
135
|
+
# @private
|
88
136
|
def abs
|
89
137
|
Math.hypot @real, @imag
|
90
138
|
end
|
91
139
|
|
140
|
+
# Compute complex argument
|
141
|
+
#
|
142
|
+
# @return [InternalComplex] The result.
|
143
|
+
#
|
144
|
+
# @private
|
92
145
|
def arg
|
93
146
|
Math.atan2 @imag, @real
|
94
147
|
end
|
95
148
|
|
149
|
+
# Compute polar coordinates
|
150
|
+
#
|
151
|
+
# @return [Array<Object>] Returns complex modulus and argument.
|
152
|
+
#
|
153
|
+
# @private
|
96
154
|
def polar
|
97
155
|
return abs, arg
|
98
156
|
end
|
99
157
|
|
158
|
+
# This operation has no effect
|
159
|
+
#
|
160
|
+
# @return [InternalComplex] Returns +self+.
|
161
|
+
#
|
162
|
+
# @private
|
100
163
|
def +@
|
101
164
|
self
|
102
165
|
end
|
103
166
|
|
167
|
+
# Negate complex value
|
168
|
+
#
|
169
|
+
# @return [InternalComplex] The result
|
170
|
+
#
|
171
|
+
# @private
|
104
172
|
def -@
|
105
173
|
InternalComplex.new -@real, -@imag
|
106
174
|
end
|
107
175
|
|
176
|
+
# Add complex values
|
177
|
+
#
|
178
|
+
# @param [Object] Second operand for binary operation.
|
179
|
+
#
|
180
|
+
# @return [InternalComplex] The result
|
181
|
+
#
|
182
|
+
# @private
|
108
183
|
def +( other )
|
109
184
|
if other.is_a?( InternalComplex ) or other.is_a?( Complex )
|
110
185
|
InternalComplex.new @real + other.real, @imag + other.imag
|
@@ -116,6 +191,13 @@ module Hornetseye
|
|
116
191
|
end
|
117
192
|
end
|
118
193
|
|
194
|
+
# Subtract complex values
|
195
|
+
#
|
196
|
+
# @param [Object] Second operand for binary operation.
|
197
|
+
#
|
198
|
+
# @return [InternalComplex] The result
|
199
|
+
#
|
200
|
+
# @private
|
119
201
|
def -( other )
|
120
202
|
if other.is_a?( InternalComplex ) or other.is_a?( Complex )
|
121
203
|
InternalComplex.new @real - other.real, @imag - other.imag
|
@@ -127,6 +209,13 @@ module Hornetseye
|
|
127
209
|
end
|
128
210
|
end
|
129
211
|
|
212
|
+
# Multiply complex values
|
213
|
+
#
|
214
|
+
# @param [Object] Second operand for binary operation.
|
215
|
+
#
|
216
|
+
# @return [InternalComplex] The result
|
217
|
+
#
|
218
|
+
# @private
|
130
219
|
def *( other )
|
131
220
|
if other.is_a?( InternalComplex ) or other.is_a?( Complex )
|
132
221
|
InternalComplex.new @real * other.real - @imag * other.imag,
|
@@ -139,6 +228,13 @@ module Hornetseye
|
|
139
228
|
end
|
140
229
|
end
|
141
230
|
|
231
|
+
# Divide complex values
|
232
|
+
#
|
233
|
+
# @param [Object] Second operand for binary operation.
|
234
|
+
#
|
235
|
+
# @return [InternalComplex] The result
|
236
|
+
#
|
237
|
+
# @private
|
142
238
|
def /( other )
|
143
239
|
if other.is_a?( InternalComplex ) or other.is_a?( Complex )
|
144
240
|
self * other.conj / other.abs2
|
@@ -150,6 +246,14 @@ module Hornetseye
|
|
150
246
|
end
|
151
247
|
end
|
152
248
|
|
249
|
+
|
250
|
+
# Complex exponentiation
|
251
|
+
#
|
252
|
+
# @param [Object] Second operand for binary operation.
|
253
|
+
#
|
254
|
+
# @return [InternalComplex] The result
|
255
|
+
#
|
256
|
+
# @private
|
153
257
|
def **( other )
|
154
258
|
if other.is_a?( InternalComplex ) or other.is_a?( Complex )
|
155
259
|
r, theta = polar
|
@@ -167,14 +271,29 @@ module Hornetseye
|
|
167
271
|
end
|
168
272
|
end
|
169
273
|
|
274
|
+
# Check whether value is equal to zero
|
275
|
+
#
|
276
|
+
# @return [Boolean,GCCValue] The result.
|
277
|
+
#
|
278
|
+
# @private
|
170
279
|
def zero?
|
171
280
|
@real.zero?.and @imag.zero?
|
172
281
|
end
|
173
282
|
|
283
|
+
# Check whether value is not equal to zero
|
284
|
+
#
|
285
|
+
# @return [Boolean,GCCValue] The result.
|
286
|
+
#
|
287
|
+
# @private
|
174
288
|
def nonzero?
|
175
289
|
@real.nonzero?.or @imag.nonzero?
|
176
290
|
end
|
177
291
|
|
292
|
+
# Compute square of complex modulus
|
293
|
+
#
|
294
|
+
# @return [Numeric,GCCValue] The result.
|
295
|
+
#
|
296
|
+
# @private
|
178
297
|
def abs2
|
179
298
|
@real * @real + @imag * @imag
|
180
299
|
end
|
@@ -185,6 +304,8 @@ module Hornetseye
|
|
185
304
|
#
|
186
305
|
# @return [Boolean] Returns boolean indicating whether objects are
|
187
306
|
# equal or not.
|
307
|
+
#
|
308
|
+
# @private
|
188
309
|
def ==( other )
|
189
310
|
if other.is_a?( InternalComplex ) or other.is_a?( Complex )
|
190
311
|
@real.eq( other.real ).and( @imag.eq( other.imag ) )
|
@@ -197,10 +318,11 @@ module Hornetseye
|
|
197
318
|
|
198
319
|
# Decompose complex number
|
199
320
|
#
|
200
|
-
# This method decomposes the complex number
|
321
|
+
# This method decomposes the complex number.
|
201
322
|
#
|
202
|
-
# @return [
|
203
|
-
#
|
323
|
+
# @return [Numeric,GCCValue] Returns the requested component.
|
324
|
+
#
|
325
|
+
# @private
|
204
326
|
def decompose( i )
|
205
327
|
[ @real, @imag ][ i ]
|
206
328
|
end
|
@@ -209,8 +331,16 @@ module Hornetseye
|
|
209
331
|
|
210
332
|
end
|
211
333
|
|
334
|
+
# The +Math+ module is extended with a few methods
|
212
335
|
module Math
|
213
336
|
|
337
|
+
# Square root for internal complex numbers
|
338
|
+
#
|
339
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
340
|
+
#
|
341
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
342
|
+
#
|
343
|
+
# @private
|
214
344
|
def sqrt_with_internalcomplex( z )
|
215
345
|
if z.is_a? Hornetseye::InternalComplex
|
216
346
|
real = sqrt( ( z.abs + z.real ) / 2 )
|
@@ -226,6 +356,13 @@ module Math
|
|
226
356
|
module_function :sqrt_without_internalcomplex
|
227
357
|
module_function :sqrt
|
228
358
|
|
359
|
+
# Exponent for internal complex numbers
|
360
|
+
#
|
361
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
362
|
+
#
|
363
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
364
|
+
#
|
365
|
+
# @private
|
229
366
|
def exp_with_internalcomplex( z )
|
230
367
|
if z.is_a? Hornetseye::InternalComplex
|
231
368
|
real = exp( z.real ) * cos( z.imag )
|
@@ -240,6 +377,13 @@ module Math
|
|
240
377
|
module_function :exp_without_internalcomplex
|
241
378
|
module_function :exp
|
242
379
|
|
380
|
+
# Cosinus for internal complex numbers
|
381
|
+
#
|
382
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
383
|
+
#
|
384
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
385
|
+
#
|
386
|
+
# @private
|
243
387
|
def cos_with_internalcomplex( z )
|
244
388
|
if z.is_a? Hornetseye::InternalComplex
|
245
389
|
real = cos( z.real ) * cosh( z.imag )
|
@@ -254,6 +398,13 @@ module Math
|
|
254
398
|
module_function :cos_without_internalcomplex
|
255
399
|
module_function :cos
|
256
400
|
|
401
|
+
# Sinus for internal complex numbers
|
402
|
+
#
|
403
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
404
|
+
#
|
405
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
406
|
+
#
|
407
|
+
# @private
|
257
408
|
def sin_with_internalcomplex( z )
|
258
409
|
if z.is_a? Hornetseye::InternalComplex
|
259
410
|
real = sin( z.real ) * cosh( z.imag )
|
@@ -268,6 +419,13 @@ module Math
|
|
268
419
|
module_function :sin_without_internalcomplex
|
269
420
|
module_function :sin
|
270
421
|
|
422
|
+
# Tangens for internal complex numbers
|
423
|
+
#
|
424
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
425
|
+
#
|
426
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
427
|
+
#
|
428
|
+
# @private
|
271
429
|
def tan_with_internalcomplex( z )
|
272
430
|
if z.is_a? Hornetseye::InternalComplex
|
273
431
|
sin( z ) / cos( z )
|
@@ -280,6 +438,13 @@ module Math
|
|
280
438
|
module_function :tan_without_internalcomplex
|
281
439
|
module_function :tan
|
282
440
|
|
441
|
+
# Cosinus hyperbolicus for internal complex numbers
|
442
|
+
#
|
443
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
444
|
+
#
|
445
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
446
|
+
#
|
447
|
+
# @private
|
283
448
|
def cosh_with_internalcomplex( z )
|
284
449
|
if z.is_a? Hornetseye::InternalComplex
|
285
450
|
real = cosh( z.real ) * cos( z.imag )
|
@@ -294,6 +459,13 @@ module Math
|
|
294
459
|
module_function :cosh_without_internalcomplex
|
295
460
|
module_function :cosh
|
296
461
|
|
462
|
+
# Sinus hyperbolicus for internal complex numbers
|
463
|
+
#
|
464
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
465
|
+
#
|
466
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
467
|
+
#
|
468
|
+
# @private
|
297
469
|
def sinh_with_internalcomplex( z )
|
298
470
|
if z.is_a? Hornetseye::InternalComplex
|
299
471
|
real = sinh( z.real ) * cos( z.imag )
|
@@ -308,6 +480,13 @@ module Math
|
|
308
480
|
module_function :sinh_without_internalcomplex
|
309
481
|
module_function :sinh
|
310
482
|
|
483
|
+
# Tangens hyperbolicus for internal complex numbers
|
484
|
+
#
|
485
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
486
|
+
#
|
487
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
488
|
+
#
|
489
|
+
# @private
|
311
490
|
def tanh_with_internalcomplex( z )
|
312
491
|
if z.is_a? Hornetseye::InternalComplex
|
313
492
|
sinh( z ) / cosh( z )
|
@@ -320,6 +499,13 @@ module Math
|
|
320
499
|
module_function :tanh_without_internalcomplex
|
321
500
|
module_function :tanh
|
322
501
|
|
502
|
+
# Logarithm for internal complex numbers
|
503
|
+
#
|
504
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
505
|
+
#
|
506
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
507
|
+
#
|
508
|
+
# @private
|
323
509
|
def log_with_internalcomplex( z )
|
324
510
|
if z.is_a? Hornetseye::InternalComplex
|
325
511
|
r, theta = z.polar
|
@@ -333,6 +519,13 @@ module Math
|
|
333
519
|
module_function :log_without_internalcomplex
|
334
520
|
module_function :log
|
335
521
|
|
522
|
+
# Base-10 logarithm for internal complex numbers
|
523
|
+
#
|
524
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
525
|
+
#
|
526
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
527
|
+
#
|
528
|
+
# @private
|
336
529
|
def log10_with_internalcomplex( z )
|
337
530
|
if z.is_a? Hornetseye::InternalComplex
|
338
531
|
log( z ) / log( 10 )
|
@@ -345,6 +538,13 @@ module Math
|
|
345
538
|
module_function :log10_without_internalcomplex
|
346
539
|
module_function :log10
|
347
540
|
|
541
|
+
# Arcus cosinus for internal complex numbers
|
542
|
+
#
|
543
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
544
|
+
#
|
545
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
546
|
+
#
|
547
|
+
# @private
|
348
548
|
def acos_with_internalcomplex( z )
|
349
549
|
if z.is_a? Hornetseye::InternalComplex
|
350
550
|
-1.0.im * log( z + 1.0.im * sqrt( 1.0 - z * z ) )
|
@@ -357,6 +557,13 @@ module Math
|
|
357
557
|
module_function :acos_without_internalcomplex
|
358
558
|
module_function :acos
|
359
559
|
|
560
|
+
# Arcus sinus for internal complex numbers
|
561
|
+
#
|
562
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
563
|
+
#
|
564
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
565
|
+
#
|
566
|
+
# @private
|
360
567
|
def asin_with_internalcomplex( z )
|
361
568
|
if z.is_a? Hornetseye::InternalComplex
|
362
569
|
-1.0.im * log( 1.0.im * z + sqrt( 1.0 - z * z ) )
|
@@ -369,6 +576,13 @@ module Math
|
|
369
576
|
module_function :asin_without_internalcomplex
|
370
577
|
module_function :asin
|
371
578
|
|
579
|
+
# Arcus tangens for internal complex numbers
|
580
|
+
#
|
581
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
582
|
+
#
|
583
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
584
|
+
#
|
585
|
+
# @private
|
372
586
|
def atan_with_internalcomplex( z )
|
373
587
|
if z.is_a? Hornetseye::InternalComplex
|
374
588
|
1.0.im * log( ( 1.0.im + z ) / ( 1.0.im - z ) ) / 2.0
|
@@ -381,6 +595,13 @@ module Math
|
|
381
595
|
module_function :atan_without_internalcomplex
|
382
596
|
module_function :atan
|
383
597
|
|
598
|
+
# Arcus cosinus hyperbolicus for internal complex numbers
|
599
|
+
#
|
600
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
601
|
+
#
|
602
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
603
|
+
#
|
604
|
+
# @private
|
384
605
|
def acosh_with_internalcomplex( z )
|
385
606
|
if z.is_a? Hornetseye::InternalComplex
|
386
607
|
log( z + sqrt( z * z - 1.0 ) )
|
@@ -393,6 +614,13 @@ module Math
|
|
393
614
|
module_function :acosh_without_internalcomplex
|
394
615
|
module_function :acosh
|
395
616
|
|
617
|
+
# Arcus sinus hyperbolicus for internal complex numbers
|
618
|
+
#
|
619
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
620
|
+
#
|
621
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
622
|
+
#
|
623
|
+
# @private
|
396
624
|
def asinh_with_internalcomplex( z )
|
397
625
|
if z.is_a? Hornetseye::InternalComplex
|
398
626
|
log( z + sqrt( 1.0 + z * z ) )
|
@@ -405,6 +633,13 @@ module Math
|
|
405
633
|
module_function :asinh_without_internalcomplex
|
406
634
|
module_function :asinh
|
407
635
|
|
636
|
+
# Arcus tangens hyperbolicus for internal complex numbers
|
637
|
+
#
|
638
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
639
|
+
#
|
640
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
641
|
+
#
|
642
|
+
# @private
|
408
643
|
def atanh_with_internalcomplex( z )
|
409
644
|
if z.is_a? Hornetseye::InternalComplex
|
410
645
|
log( ( 1.0 + z ) / ( 1.0 - z ) ) / 2.0
|
@@ -417,6 +652,13 @@ module Math
|
|
417
652
|
module_function :atanh_without_internalcomplex
|
418
653
|
module_function :atanh
|
419
654
|
|
655
|
+
# Arcus tangens of two internal complex numbers
|
656
|
+
#
|
657
|
+
# @param [Object,Hornetseye::InternalComplex] z Parameter for unary method.
|
658
|
+
#
|
659
|
+
# @return [Object,Hornetseye::InternalComplex] Result of method call.
|
660
|
+
#
|
661
|
+
# @private
|
420
662
|
def atan2_with_internalcomplex( y, x )
|
421
663
|
if [ x, y ].any? { |v| v.is_a? Hornetseye::InternalComplex }
|
422
664
|
-1.0.im * log( ( x + 1.0.im * y ) / sqrt( x * x + y * y ) )
|
@@ -433,6 +675,7 @@ end
|
|
433
675
|
|
434
676
|
module Hornetseye
|
435
677
|
|
678
|
+
# Class for representing native complex values
|
436
679
|
class COMPLEX_ < Composite
|
437
680
|
|
438
681
|
class << self
|
@@ -440,6 +683,12 @@ module Hornetseye
|
|
440
683
|
# Set base class attribute
|
441
684
|
#
|
442
685
|
# Sets number of elements to two.
|
686
|
+
#
|
687
|
+
# @param [Class] subclass The class inheriting from +COMPLEX_+.
|
688
|
+
#
|
689
|
+
# @return The return value should be ignored.
|
690
|
+
#
|
691
|
+
# @private
|
443
692
|
def inherited( subclass )
|
444
693
|
subclass.num_elements = 2
|
445
694
|
end
|
@@ -474,15 +723,23 @@ module Hornetseye
|
|
474
723
|
end
|
475
724
|
end
|
476
725
|
|
726
|
+
# Identifier array used internally
|
727
|
+
#
|
728
|
+
# @private
|
729
|
+
IDENTIFIER = { SFLOAT => 'SCOMPLEX',
|
730
|
+
DFLOAT => 'DCOMPLEX' }
|
731
|
+
|
477
732
|
# Display information about this class
|
478
733
|
#
|
479
734
|
# @return [String] Returns string with information about this class (e.g.
|
480
735
|
# "SCOMPLEX").
|
481
736
|
def inspect
|
482
737
|
unless element_type.nil?
|
483
|
-
|
484
|
-
|
485
|
-
|
738
|
+
retval = IDENTIFIER[ element_type ] || "COMPLEX(#{element_type.inspect})"
|
739
|
+
( class << self; self; end ).instance_eval do
|
740
|
+
define_method( :inspect ) { retval }
|
741
|
+
end
|
742
|
+
retval
|
486
743
|
else
|
487
744
|
super
|
488
745
|
end
|
@@ -550,7 +807,7 @@ module Hornetseye
|
|
550
807
|
element_type == other.element_type
|
551
808
|
end
|
552
809
|
|
553
|
-
# Compute hash value for this class
|
810
|
+
# Compute hash value for this class
|
554
811
|
#
|
555
812
|
# @return [Fixnum] Hash value
|
556
813
|
#
|
@@ -572,6 +829,9 @@ module Hornetseye
|
|
572
829
|
|
573
830
|
end
|
574
831
|
|
832
|
+
# Constructor for native complex number
|
833
|
+
#
|
834
|
+
# @param [Complex,InternalComplex] value Complex number.
|
575
835
|
def initialize( value = self.class.default )
|
576
836
|
if Thread.current[ :function ].nil? or
|
577
837
|
[ value.real, value.imag ].all? { |c| c.is_a? GCCValue }
|
@@ -630,6 +890,11 @@ module Hornetseye
|
|
630
890
|
[ @value.real, @value.imag ]
|
631
891
|
end
|
632
892
|
|
893
|
+
# Namespace containing method for matching elements of type COMPLEX_
|
894
|
+
#
|
895
|
+
# @see COMPLEX_
|
896
|
+
#
|
897
|
+
# @private
|
633
898
|
module Match
|
634
899
|
|
635
900
|
# Method for matching elements of type COMPLEX_
|
@@ -674,6 +939,8 @@ module Hornetseye
|
|
674
939
|
#
|
675
940
|
# @param [Class] context Other type to align with.
|
676
941
|
#
|
942
|
+
# @return [Class] Result of type alignment.
|
943
|
+
#
|
677
944
|
# @private
|
678
945
|
def align( context )
|
679
946
|
if self < COMPLEX_
|
@@ -689,11 +956,15 @@ module Hornetseye
|
|
689
956
|
|
690
957
|
end
|
691
958
|
|
959
|
+
# Module providing the operations to manipulate array expressions
|
692
960
|
module Operations
|
693
961
|
|
694
962
|
define_unary_op :real, :scalar
|
695
963
|
define_unary_op :imag, :scalar
|
696
964
|
|
965
|
+
# Fast extraction for real values of complex array
|
966
|
+
#
|
967
|
+
# @return [Node] Array with real values.
|
697
968
|
def real_with_decompose
|
698
969
|
if typecode == OBJECT or is_a?( Variable )
|
699
970
|
real_without_decompose
|
@@ -706,6 +977,11 @@ module Hornetseye
|
|
706
977
|
|
707
978
|
alias_method_chain :real, :decompose
|
708
979
|
|
980
|
+
# Assignment for real values of complex array
|
981
|
+
#
|
982
|
+
# @param [Object] Value or array of values to assign to real components.
|
983
|
+
#
|
984
|
+
# @return [Object] Returns +value+.
|
709
985
|
def real=( value )
|
710
986
|
if typecode < COMPLEX_
|
711
987
|
decompose( 0 )[] = value
|
@@ -718,6 +994,9 @@ module Hornetseye
|
|
718
994
|
end
|
719
995
|
end
|
720
996
|
|
997
|
+
# Fast extraction of imaginary values of complex array
|
998
|
+
#
|
999
|
+
# @return [Node] Array with imaginary values.
|
721
1000
|
def imag_with_decompose
|
722
1001
|
if typecode == OBJECT or is_a?( Variable )
|
723
1002
|
imag_without_decompose
|
@@ -730,6 +1009,11 @@ module Hornetseye
|
|
730
1009
|
|
731
1010
|
alias_method_chain :imag, :decompose
|
732
1011
|
|
1012
|
+
# Assignment for imaginary values of complex array
|
1013
|
+
#
|
1014
|
+
# @param [Object] Value or array of values to assign to imaginary components.
|
1015
|
+
#
|
1016
|
+
# @return [Object] Returns +value+.
|
733
1017
|
def imag=( value )
|
734
1018
|
if typecode < COMPLEX_
|
735
1019
|
decompose( 1 )[] = value
|
@@ -744,16 +1028,29 @@ module Hornetseye
|
|
744
1028
|
|
745
1029
|
end
|
746
1030
|
|
747
|
-
|
1031
|
+
# Create a class deriving from +COMPLEX_+
|
1032
|
+
#
|
1033
|
+
# Create a class deriving from +COMPLEX_+. The parameter +element_type+ is assigned
|
1034
|
+
# to the corresponding attribute of the resulting class.
|
1035
|
+
#
|
1036
|
+
# @param [Class] element_type The native type of the complex components.
|
1037
|
+
#
|
1038
|
+
# @return [Class] A class deriving from +COMPLEX_+.
|
1039
|
+
#
|
1040
|
+
# @see COMPLEX_
|
1041
|
+
# @see COMPLEX_.element_type
|
1042
|
+
def COMPLEX( element_type )
|
748
1043
|
retval = Class.new COMPLEX_
|
749
|
-
retval.element_type =
|
1044
|
+
retval.element_type = element_type
|
750
1045
|
retval
|
751
1046
|
end
|
752
1047
|
|
753
1048
|
module_function :COMPLEX
|
754
1049
|
|
1050
|
+
# Convenience shortcut for single-precision floating-point complex numbers
|
755
1051
|
SCOMPLEX = COMPLEX SFLOAT
|
756
1052
|
|
1053
|
+
# Convenience shortcut for double-precision floating-point complex numbers
|
757
1054
|
DCOMPLEX = COMPLEX DFLOAT
|
758
1055
|
|
759
1056
|
# Shortcut for constructor
|