paddlec 0.0.1
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 +7 -0
- data/LICENSE +674 -0
- data/README.md +56 -0
- data/ext/libpaddlec/arithmetic.c +2486 -0
- data/ext/libpaddlec/comparison.c +683 -0
- data/ext/libpaddlec/complex.c +349 -0
- data/ext/libpaddlec/delay.c +240 -0
- data/ext/libpaddlec/fir_filter.c +724 -0
- data/ext/libpaddlec/fir_filter_avx.c +2645 -0
- data/ext/libpaddlec/fir_filter_neon.c +1767 -0
- data/ext/libpaddlec/fir_filter_sse.c +1677 -0
- data/ext/libpaddlec/libpaddlec.c +933 -0
- data/ext/libpaddlec/libpaddlec.h +473 -0
- data/ext/libpaddlec/math.c +563 -0
- data/ext/libpaddlec/no_fast_math.c +955 -0
- data/ext/libpaddlec/rounding.c +503 -0
- data/ext/paddlec/complex_buffer.c +3555 -0
- data/ext/paddlec/complex_buffer.h +28 -0
- data/ext/paddlec/delay.c +214 -0
- data/ext/paddlec/delay.h +29 -0
- data/ext/paddlec/extconf.rb +106 -0
- data/ext/paddlec/fir_filter.c +892 -0
- data/ext/paddlec/fir_filter.h +28 -0
- data/ext/paddlec/float_buffer.c +4770 -0
- data/ext/paddlec/float_buffer.h +28 -0
- data/ext/paddlec/paddlec.c +788 -0
- data/ext/paddlec/paddlec.h +76 -0
- data/ext/paddlec/pulseaudio.c +6767 -0
- data/ext/paddlec/pulseaudio.h +30 -0
- data/lib/paddlec.rb +26 -0
- data/lib/paddlec/version.rb +3 -0
- data/paddlec.gemspec +55 -0
- data/samples/fmdemod.rb +121 -0
- data/samples/fmdemod_chunk.rb +120 -0
- data/samples/fmdemod_chunk_buffer.rb +144 -0
- data/samples/stereo_chunk.rb +161 -0
- metadata +99 -0
@@ -0,0 +1,3555 @@
|
|
1
|
+
/* Copyright (C) 2019-2020 Théotime Bollengier <theotime.bollengier@gmail.com>
|
2
|
+
*
|
3
|
+
* This file is part of PaddleC
|
4
|
+
*
|
5
|
+
* PaddleC is free software: you can redistribute it and/or modify
|
6
|
+
* it under the terms of the GNU General Public License as published by
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or
|
8
|
+
* (at your option) any later version.
|
9
|
+
*
|
10
|
+
* PaddleC is distributed in the hope that it will be useful,
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
* GNU General Public License for more details.
|
14
|
+
*
|
15
|
+
* You should have received a copy of the GNU General Public License
|
16
|
+
* along with PaddleC. If not, see <https://www.gnu.org/licenses/>.
|
17
|
+
*/
|
18
|
+
|
19
|
+
#include <ruby.h>
|
20
|
+
#include "libpaddlec.h"
|
21
|
+
#include "paddlec.h"
|
22
|
+
#include "complex_buffer.h"
|
23
|
+
#include "float_buffer.h"
|
24
|
+
|
25
|
+
|
26
|
+
/* Document-class: PaddleC::ComplexBuffer
|
27
|
+
*
|
28
|
+
* A a Ruby object that wraps a native array of complex numbers, as pairs of single floats.
|
29
|
+
*/
|
30
|
+
|
31
|
+
|
32
|
+
VALUE c_ComplexBuffer;
|
33
|
+
|
34
|
+
|
35
|
+
static void paddlec_complex_buffer_free(void *p)
|
36
|
+
{
|
37
|
+
pdlc_complex_buffer_t *cbuf = (pdlc_complex_buffer_t*)p;
|
38
|
+
pdlc_complex_buffer_free(cbuf);
|
39
|
+
}
|
40
|
+
|
41
|
+
|
42
|
+
static size_t paddlec_complex_buffer_size(const void* data)
|
43
|
+
{
|
44
|
+
pdlc_complex_buffer_t *cbuf = (pdlc_complex_buffer_t*)data;
|
45
|
+
return sizeof(pdlc_complex_buffer_t) + cbuf->capacity*sizeof(pdlc_complex_t);
|
46
|
+
}
|
47
|
+
|
48
|
+
|
49
|
+
static const rb_data_type_t paddlec_complex_buffer_type = {
|
50
|
+
.wrap_struct_name = "paddlec_complex_buffer_struct",
|
51
|
+
.function = {
|
52
|
+
.dmark = NULL,
|
53
|
+
.dfree = paddlec_complex_buffer_free,
|
54
|
+
.dsize = paddlec_complex_buffer_size,
|
55
|
+
},
|
56
|
+
.data = NULL,
|
57
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
58
|
+
};
|
59
|
+
|
60
|
+
|
61
|
+
static VALUE paddlec_complex_buffer_alloc(VALUE klass)
|
62
|
+
{
|
63
|
+
VALUE obj;
|
64
|
+
pdlc_complex_buffer_t *cbuf;
|
65
|
+
|
66
|
+
cbuf = pdlc_complex_buffer_new(0);
|
67
|
+
obj = TypedData_Wrap_Struct(klass, &paddlec_complex_buffer_type, cbuf);
|
68
|
+
|
69
|
+
return obj;
|
70
|
+
}
|
71
|
+
|
72
|
+
|
73
|
+
pdlc_complex_buffer_t* paddlec_complex_buffer_get_struct(VALUE obj)
|
74
|
+
{
|
75
|
+
pdlc_complex_buffer_t *cbuf;
|
76
|
+
TypedData_Get_Struct(obj, pdlc_complex_buffer_t, &paddlec_complex_buffer_type, cbuf);
|
77
|
+
return cbuf;
|
78
|
+
}
|
79
|
+
|
80
|
+
|
81
|
+
static inline VALUE paddlec2COMPLEX(pdlc_complex_t c)
|
82
|
+
{
|
83
|
+
return rb_complex_new(DBL2NUM((double)c.real), DBL2NUM((double)c.imag));
|
84
|
+
}
|
85
|
+
|
86
|
+
|
87
|
+
static inline pdlc_complex_t COMPLEX2paddlec(VALUE c)
|
88
|
+
{
|
89
|
+
pdlc_complex_t res;
|
90
|
+
res.real = (float)NUM2DBL(rb_funcallv(c, id_real, 0, NULL));
|
91
|
+
res.imag = (float)NUM2DBL(rb_funcallv(c, id_imag, 0, NULL));
|
92
|
+
return res;
|
93
|
+
}
|
94
|
+
|
95
|
+
|
96
|
+
/* @return [PaddleC::ComplexBuffer]
|
97
|
+
* @overload initialize(length = 0, value = 0.0)
|
98
|
+
* @param length [Integer] the length of the buffer
|
99
|
+
* @param value [Numeric] the value which is set to all elements of the buffer
|
100
|
+
* @return [PaddleC::ComplexBuffer]
|
101
|
+
* @overload initialize(a)
|
102
|
+
* @param a [Array<Numeric>, PaddleC::ComplexBuffer, PaddleC::FloatBuffer] an array of complex numbers, a ComplexBuffer or a FloatBuffer
|
103
|
+
* @return [PaddleC::ComplexBuffer]
|
104
|
+
* @overload initialize(fbreal, fbimag)
|
105
|
+
* @param fbreal [PaddleC::FloatBuffer] a FloatBuffer for the real part
|
106
|
+
* @param fbimag [PaddleC::FloatBuffer] a FloatBuffer for the imaginary part
|
107
|
+
* @return [PaddleC::ComplexBuffer]
|
108
|
+
* @overload initialize(str)
|
109
|
+
* @param str [String] a binary string
|
110
|
+
* @return [PaddleC::ComplexBuffer]
|
111
|
+
*/
|
112
|
+
static VALUE paddlec_complex_buffer_initialize(int argc, VALUE *argv, VALUE self)
|
113
|
+
{
|
114
|
+
pdlc_complex_buffer_t *cbuf;
|
115
|
+
VALUE rblength, rbvalue;
|
116
|
+
VALUE elem;
|
117
|
+
long length = 0, length2;
|
118
|
+
pdlc_complex_t value = {0.0f, 0.0f};
|
119
|
+
size_t i;
|
120
|
+
const pdlc_complex_buffer_t *ocbuf;
|
121
|
+
const pdlc_buffer_t *ofbuf, *ofbuf2;
|
122
|
+
|
123
|
+
cbuf = paddlec_complex_buffer_get_struct(self);
|
124
|
+
|
125
|
+
rb_scan_args(argc, argv, "02", &rblength, &rbvalue);
|
126
|
+
|
127
|
+
if (rb_class_of(rblength) == rb_cArray) {
|
128
|
+
if (rbvalue != Qnil)
|
129
|
+
rb_raise(rb_eArgError, "Not expecting another argument along with the array");
|
130
|
+
length = rb_array_len(rblength);
|
131
|
+
pdlc_complex_buffer_resize(cbuf, (size_t)length, 0);
|
132
|
+
for (i = 0; i < (size_t)length; i++) {
|
133
|
+
elem = rb_ary_entry(rblength, i);
|
134
|
+
value.real = (float)NUM2DBL(rb_funcallv(elem, id_real, 0, NULL));
|
135
|
+
value.imag = (float)NUM2DBL(rb_funcallv(elem, id_imag, 0, NULL));
|
136
|
+
cbuf->data[i] = value;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
else if (rb_class_of(rblength) == c_ComplexBuffer) {
|
140
|
+
if (rbvalue != Qnil)
|
141
|
+
rb_raise(rb_eArgError, "Not expecting another argument along with the ComplexBuffer");
|
142
|
+
ocbuf = paddlec_complex_buffer_get_struct(rblength);
|
143
|
+
length = (long)ocbuf->length;
|
144
|
+
pdlc_complex_buffer_resize(cbuf, (size_t)length, 0);
|
145
|
+
memcpy(cbuf->data, ocbuf->data, length*sizeof(pdlc_complex_t));
|
146
|
+
}
|
147
|
+
else if (rb_class_of(rblength) == c_FloatBuffer) {
|
148
|
+
ofbuf = paddlec_float_buffer_get_struct(rblength);
|
149
|
+
length = (long)ofbuf->length;
|
150
|
+
if (rb_class_of(rbvalue) == c_FloatBuffer) {
|
151
|
+
ofbuf2 = paddlec_float_buffer_get_struct(rbvalue);
|
152
|
+
length2 = (long)ofbuf->length;
|
153
|
+
if (length2 == length) {
|
154
|
+
pdlc_complex_buffer_resize(cbuf, (size_t)length, 0);
|
155
|
+
for (i = 0; i < (size_t)length; i++) {
|
156
|
+
cbuf->data[i].real = ofbuf->data[i];
|
157
|
+
cbuf->data[i].imag = ofbuf2->data[i];
|
158
|
+
}
|
159
|
+
}
|
160
|
+
else {
|
161
|
+
pdlc_complex_buffer_resize(cbuf, (size_t)((length > length2) ? length : length2), 1);
|
162
|
+
for (i = 0; i < (size_t)length; i++)
|
163
|
+
cbuf->data[i].real = ofbuf->data[i];
|
164
|
+
for (i = 0; i < (size_t)length2; i++)
|
165
|
+
cbuf->data[i].imag = ofbuf2->data[i];
|
166
|
+
}
|
167
|
+
}
|
168
|
+
else if (rbvalue != Qnil) {
|
169
|
+
rb_raise(rb_eArgError, "Not expecting another argument along with the FloatBuffer");
|
170
|
+
}
|
171
|
+
else {
|
172
|
+
pdlc_complex_buffer_resize(cbuf, (size_t)length, 0);
|
173
|
+
for (i = 0; i < (size_t)length; i++) {
|
174
|
+
cbuf->data[i].real = ofbuf->data[i];
|
175
|
+
cbuf->data[i].imag = 0.0f;
|
176
|
+
}
|
177
|
+
}
|
178
|
+
}
|
179
|
+
else if (rb_class_of(rblength) == rb_cString) {
|
180
|
+
length = (long)RSTRING_LEN(rblength) / sizeof(pdlc_complex_t);
|
181
|
+
pdlc_complex_buffer_resize(cbuf, (size_t)length, 0);
|
182
|
+
memcpy(cbuf->data, StringValuePtr(rblength), length*sizeof(pdlc_complex_t));
|
183
|
+
}
|
184
|
+
else {
|
185
|
+
if (rblength != Qnil)
|
186
|
+
length = NUM2LONG(rblength);
|
187
|
+
if (rbvalue != Qnil) {
|
188
|
+
value.real = (float)NUM2DBL(rb_funcallv(rbvalue, id_real, 0, NULL));
|
189
|
+
value.imag = (float)NUM2DBL(rb_funcallv(rbvalue, id_imag, 0, NULL));
|
190
|
+
}
|
191
|
+
if (length < 0)
|
192
|
+
rb_raise(rb_eArgError, "negative buffer size");
|
193
|
+
|
194
|
+
if (length > 0) {
|
195
|
+
if (value.real != 0.0f || value.imag != 0.0f) {
|
196
|
+
pdlc_complex_buffer_resize(cbuf, (size_t)length, 0);
|
197
|
+
pdlc_complex_buffer_set(cbuf, value);
|
198
|
+
}
|
199
|
+
else
|
200
|
+
pdlc_complex_buffer_resize(cbuf, (size_t)length, 1);
|
201
|
+
}
|
202
|
+
}
|
203
|
+
|
204
|
+
return self;
|
205
|
+
}
|
206
|
+
|
207
|
+
|
208
|
+
/* Change the length of the buffer
|
209
|
+
* @param new_length [Integer] the new length of the buffer, as a positive integer
|
210
|
+
* @return [self] +self+
|
211
|
+
*/
|
212
|
+
static VALUE paddlec_complex_buffer_resize(VALUE self, VALUE new_length)
|
213
|
+
{
|
214
|
+
pdlc_complex_buffer_t *cbuf;
|
215
|
+
long length;
|
216
|
+
|
217
|
+
length = NUM2LONG(new_length);
|
218
|
+
if (length < 0)
|
219
|
+
rb_raise(rb_eArgError, "New length cannot be less than 0");
|
220
|
+
|
221
|
+
cbuf = paddlec_complex_buffer_get_struct(self);
|
222
|
+
|
223
|
+
pdlc_complex_buffer_resize(cbuf, (size_t)length, 1);
|
224
|
+
|
225
|
+
return self;
|
226
|
+
}
|
227
|
+
|
228
|
+
|
229
|
+
/* @return [Array<Float>]
|
230
|
+
*/
|
231
|
+
static VALUE paddlec_complex_buffer_to_a(VALUE self)
|
232
|
+
{
|
233
|
+
size_t i;
|
234
|
+
pdlc_complex_buffer_t *cbuf;
|
235
|
+
VALUE ar;
|
236
|
+
|
237
|
+
cbuf = paddlec_complex_buffer_get_struct(self);
|
238
|
+
ar = rb_ary_new_capa(cbuf->length);
|
239
|
+
for (i = 0; i < cbuf->length; i++)
|
240
|
+
rb_ary_store(ar, i, rb_complex_raw(DBL2NUM((double)cbuf->data[i].real), DBL2NUM((double)cbuf->data[i].imag)));
|
241
|
+
|
242
|
+
return ar;
|
243
|
+
}
|
244
|
+
|
245
|
+
|
246
|
+
/* @return [Integer] the length of the buffer
|
247
|
+
*/
|
248
|
+
static VALUE paddlec_complex_buffer_length(VALUE self)
|
249
|
+
{
|
250
|
+
pdlc_complex_buffer_t *cbuf = paddlec_complex_buffer_get_struct(self);
|
251
|
+
return ULONG2NUM(cbuf->length);
|
252
|
+
}
|
253
|
+
|
254
|
+
|
255
|
+
/* @return [Boolean] true if length < 1
|
256
|
+
*/
|
257
|
+
static VALUE paddlec_complex_buffer_isempty(VALUE self)
|
258
|
+
{
|
259
|
+
pdlc_complex_buffer_t *cbuf = paddlec_complex_buffer_get_struct(self);
|
260
|
+
return ((cbuf->length < 1) ? Qtrue : Qfalse);
|
261
|
+
}
|
262
|
+
|
263
|
+
|
264
|
+
static VALUE paddlec_complex_buffer_to_enum_get_size_block(VALUE block_arg, VALUE data, int argc, VALUE* argv)
|
265
|
+
{
|
266
|
+
/* block_arg will be the first yielded value */
|
267
|
+
/* data will be the last argument you passed to rb_block_call */
|
268
|
+
/* if multiple values are yielded, use argc/argv to access them */
|
269
|
+
(void)block_arg;
|
270
|
+
(void)argc;
|
271
|
+
(void)argv;
|
272
|
+
return rb_funcallv(data, id_length, 0, NULL);
|
273
|
+
}
|
274
|
+
|
275
|
+
|
276
|
+
/* Calls the given block once for each element in +self+,
|
277
|
+
* passing that element as a parameter.
|
278
|
+
* Returns the array itself, or, if no block is given, an Enumerator is returned.
|
279
|
+
* @return [Object, Enumerator]
|
280
|
+
* @overload each{|item| block}
|
281
|
+
* @return [Array<Float>] self
|
282
|
+
* @overload each
|
283
|
+
* @return [Enumerator]
|
284
|
+
*/
|
285
|
+
static VALUE paddlec_complex_buffer_each(VALUE self)
|
286
|
+
{
|
287
|
+
size_t i;
|
288
|
+
pdlc_complex_buffer_t *cbuf;
|
289
|
+
VALUE res;
|
290
|
+
VALUE each_sym;
|
291
|
+
|
292
|
+
cbuf = paddlec_complex_buffer_get_struct(self);
|
293
|
+
|
294
|
+
if (rb_block_given_p()) {
|
295
|
+
for (i = 0; i < cbuf->length; i++)
|
296
|
+
rb_yield(rb_complex_raw(DBL2NUM((double)cbuf->data[i].real), DBL2NUM((double)cbuf->data[i].imag)));
|
297
|
+
res = self;
|
298
|
+
}
|
299
|
+
else {
|
300
|
+
each_sym = ID2SYM(id_each);
|
301
|
+
res = rb_block_call(self, id_to_enum, 1, &each_sym, paddlec_complex_buffer_to_enum_get_size_block, self);
|
302
|
+
}
|
303
|
+
|
304
|
+
return res;
|
305
|
+
}
|
306
|
+
|
307
|
+
|
308
|
+
/* Invokes the given block once for each element of self,
|
309
|
+
* replacing the element with the value returned by the block.
|
310
|
+
* If no block is given, an Enumerator is returned instead.
|
311
|
+
* @overload collect!{|value| block}
|
312
|
+
* @return [self]
|
313
|
+
* @overload collect!
|
314
|
+
* @return [Enumerator]
|
315
|
+
*/
|
316
|
+
static VALUE paddlec_complex_buffer_collect_inp(VALUE self)
|
317
|
+
{
|
318
|
+
pdlc_complex_buffer_t *cbuf;
|
319
|
+
size_t i;
|
320
|
+
VALUE res, elem;
|
321
|
+
VALUE collectI_sym;
|
322
|
+
|
323
|
+
cbuf = paddlec_complex_buffer_get_struct(self);
|
324
|
+
|
325
|
+
if (rb_block_given_p()) {
|
326
|
+
for (i = 0; i < cbuf->length; i++) {
|
327
|
+
elem = rb_yield(rb_complex_raw(DBL2NUM((double)cbuf->data[i].real), DBL2NUM((double)cbuf->data[i].imag)));
|
328
|
+
cbuf->data[i].real = (float)NUM2DBL(rb_funcallv(elem, id_real, 0, NULL));
|
329
|
+
cbuf->data[i].imag = (float)NUM2DBL(rb_funcallv(elem, id_imag, 0, NULL));
|
330
|
+
}
|
331
|
+
res = self;
|
332
|
+
}
|
333
|
+
else {
|
334
|
+
collectI_sym = ID2SYM(id_collectI);
|
335
|
+
res = rb_block_call(self, id_to_enum, 1, &collectI_sym, paddlec_complex_buffer_to_enum_get_size_block, self);
|
336
|
+
}
|
337
|
+
|
338
|
+
return res;
|
339
|
+
}
|
340
|
+
|
341
|
+
|
342
|
+
/* Returns a new ComplexBuffer with the same content as +self+.
|
343
|
+
* @return [PaddleC::ComplexBuffer]
|
344
|
+
*/
|
345
|
+
static VALUE paddlec_complex_buffer_clone(VALUE self)
|
346
|
+
{
|
347
|
+
const pdlc_complex_buffer_t *cbuf;
|
348
|
+
pdlc_complex_buffer_t *newcbuf;
|
349
|
+
VALUE newComplexBuffer;
|
350
|
+
VALUE len;
|
351
|
+
|
352
|
+
cbuf = paddlec_complex_buffer_get_struct(self);
|
353
|
+
len = rb_funcallv(self, id_length, 0, NULL);
|
354
|
+
|
355
|
+
newComplexBuffer = rb_class_new_instance(1, &len, c_ComplexBuffer);
|
356
|
+
newcbuf = paddlec_complex_buffer_get_struct(newComplexBuffer);
|
357
|
+
memcpy(newcbuf->data, cbuf->data, cbuf->length*sizeof(pdlc_complex_t));
|
358
|
+
|
359
|
+
return newComplexBuffer;
|
360
|
+
}
|
361
|
+
|
362
|
+
|
363
|
+
/* Element Reference -- Returns the element at index,
|
364
|
+
* or returns a sub-buffer starting at the start index and continuing for length elements,
|
365
|
+
* or returns a sub-buffer specified by range of indices.
|
366
|
+
*
|
367
|
+
* Negative indices count backward from the end of the buffer (-1 is the last element).
|
368
|
+
* Returns nil if the index (or starting index) are out of range.
|
369
|
+
*
|
370
|
+
* @overload [](index)
|
371
|
+
* @param index [Integer] the index of the element
|
372
|
+
* @return [Complex, nil] the element at +index+, or +nil+ if index out of bound
|
373
|
+
* @overload [](start, length)
|
374
|
+
* @param start [Integer] the start index of the sub-buffer
|
375
|
+
* @param length [Integer] the length of the sub-buffer
|
376
|
+
* @return [PaddleC::ComplexBuffer, nil] a new ComplexBuffer, or +nil+ if indexes are out of bound
|
377
|
+
* @overload [](range)
|
378
|
+
* @param range [Range] the range of indexes of the sub-buffer
|
379
|
+
* @return [PaddleC::ComplexBuffer, nil] a new ComplexBuffer, or +nil+ if indexes are out of bound
|
380
|
+
*/
|
381
|
+
static VALUE paddlec_complex_buffer_get(int argc, VALUE *argv, VALUE self)
|
382
|
+
{
|
383
|
+
const pdlc_complex_buffer_t *cbuf;
|
384
|
+
pdlc_complex_buffer_t *ncbuf;
|
385
|
+
VALUE rbind_start_range;
|
386
|
+
VALUE rblength;
|
387
|
+
long ind_start;
|
388
|
+
long ind_end;
|
389
|
+
long length;
|
390
|
+
VALUE res = Qnil;
|
391
|
+
VALUE beg, end;
|
392
|
+
int exc;
|
393
|
+
|
394
|
+
cbuf = paddlec_complex_buffer_get_struct(self);
|
395
|
+
|
396
|
+
rb_scan_args(argc, argv, "11", &rbind_start_range, &rblength);
|
397
|
+
|
398
|
+
if (rblength == Qnil && rb_range_values(rbind_start_range, &beg, &end, &exc)) {
|
399
|
+
ind_start = NUM2LONG(beg);
|
400
|
+
if (ind_start < 0)
|
401
|
+
ind_start = (long)cbuf->length + ind_start;
|
402
|
+
if (ind_start < 0 || ind_start >= (long)cbuf->length)
|
403
|
+
return Qnil;
|
404
|
+
ind_end = NUM2LONG(end);
|
405
|
+
if (ind_end < 0)
|
406
|
+
ind_end = (long)cbuf->length + ind_end;
|
407
|
+
if (exc)
|
408
|
+
ind_end -= 1;
|
409
|
+
length = ind_end + 1 - ind_start;
|
410
|
+
if (length < 0)
|
411
|
+
length = 0;
|
412
|
+
}
|
413
|
+
else {
|
414
|
+
ind_start = NUM2LONG(rbind_start_range);
|
415
|
+
if (ind_start < 0)
|
416
|
+
ind_start = (long)cbuf->length + ind_start;
|
417
|
+
if (ind_start < 0 || ind_start >= (long)cbuf->length)
|
418
|
+
return Qnil;
|
419
|
+
if (rblength == Qnil)
|
420
|
+
return rb_complex_raw(DBL2NUM((double)cbuf->data[ind_start].real), DBL2NUM((double)cbuf->data[ind_start].imag));
|
421
|
+
length = NUM2LONG(rblength);
|
422
|
+
if (length < 0)
|
423
|
+
return Qnil;
|
424
|
+
}
|
425
|
+
|
426
|
+
if ((ind_start + length) > (long)cbuf->length)
|
427
|
+
length = (long)cbuf->length - ind_start;
|
428
|
+
rblength = LONG2NUM(length);
|
429
|
+
|
430
|
+
res = rb_class_new_instance(1, &rblength, c_ComplexBuffer);
|
431
|
+
|
432
|
+
ncbuf = paddlec_complex_buffer_get_struct(res);
|
433
|
+
memcpy(ncbuf->data, cbuf->data + ind_start, length*sizeof(pdlc_complex_t));
|
434
|
+
|
435
|
+
return res;
|
436
|
+
}
|
437
|
+
|
438
|
+
|
439
|
+
/* Element Assignment -- Sets the element at index,
|
440
|
+
* or replaces a subarray from the start index for length elements,
|
441
|
+
* or replaces a subarray specified by the range of indices.
|
442
|
+
*
|
443
|
+
* Negative indices count backward from the end of the buffer (-1 is the last element).
|
444
|
+
* An exception is raised if indexes are out of bounds.
|
445
|
+
*
|
446
|
+
* @overload []=(index, value)
|
447
|
+
* @param index [Integer] the index of the element
|
448
|
+
* @param value [Numeric] the element to set at +index+
|
449
|
+
* @overload []=(start, length, vaule)
|
450
|
+
* @param start [Integer] the start index of the sub-buffer
|
451
|
+
* @param length [Integer] the length of the sub-buffer
|
452
|
+
* @param value [Numeric, Array<Numeric>, ComplexBuffer, FloatBuffer] the element to set at +index+
|
453
|
+
* @overload []=(range, value)
|
454
|
+
* @param range [Range] the range of indexes of the sub-buffer
|
455
|
+
* @param value [Numeric, Array<Numeric>, ComplexBuffer, FloatBuffer] the element to set at +index+
|
456
|
+
*/
|
457
|
+
static VALUE paddlec_complex_buffer_set(int argc, VALUE *argv, VALUE self)
|
458
|
+
{
|
459
|
+
pdlc_complex_buffer_t *cbuf;
|
460
|
+
const pdlc_complex_buffer_t *ocbuf;
|
461
|
+
const pdlc_buffer_t *ofbuf;
|
462
|
+
VALUE rbind_start_range;
|
463
|
+
VALUE rblength;
|
464
|
+
VALUE rbvalue;
|
465
|
+
VALUE elem;
|
466
|
+
long ind_start, length, i, j, ind_end;
|
467
|
+
VALUE beg, end;
|
468
|
+
int exc;
|
469
|
+
pdlc_complex_t value;
|
470
|
+
|
471
|
+
cbuf = paddlec_complex_buffer_get_struct(self);
|
472
|
+
|
473
|
+
rb_scan_args(argc, argv, "111", &rbind_start_range, &rblength, &rbvalue);
|
474
|
+
|
475
|
+
if (rblength == Qnil && rb_range_values(rbind_start_range, &beg, &end, &exc)) {
|
476
|
+
ind_start = NUM2LONG(beg);
|
477
|
+
if (ind_start < 0)
|
478
|
+
ind_start = (long)cbuf->length + ind_start;
|
479
|
+
if (ind_start < 0 || ind_start >= (long)cbuf->length)
|
480
|
+
rb_raise(rb_eIndexError, "index out of bounds");
|
481
|
+
ind_end = NUM2LONG(end);
|
482
|
+
if (ind_end < 0)
|
483
|
+
ind_end = (long)cbuf->length + ind_end;
|
484
|
+
if (exc)
|
485
|
+
ind_end -= 1;
|
486
|
+
length = ind_end + 1 - ind_start;
|
487
|
+
}
|
488
|
+
else {
|
489
|
+
ind_start = NUM2LONG(rbind_start_range);
|
490
|
+
if (ind_start < 0)
|
491
|
+
ind_start = (long)cbuf->length + ind_start;
|
492
|
+
if (ind_start < 0 || ind_start >= (long)cbuf->length)
|
493
|
+
rb_raise(rb_eIndexError, "index out of bounds");
|
494
|
+
if (rblength == Qnil)
|
495
|
+
length = 1;
|
496
|
+
else
|
497
|
+
length = NUM2LONG(rblength);
|
498
|
+
}
|
499
|
+
if (length < 1)
|
500
|
+
rb_raise(rb_eIndexError, "index range maps to %ld..%ld which does not have a strictly positive length", ind_start, ind_start + length - 1);
|
501
|
+
if ((ind_start + length) > (long)cbuf->length)
|
502
|
+
rb_raise(rb_eIndexError, "index range maps to %ld..%ld which exceeds the buffer length [0..%lu]", ind_start, ind_start + length - 1, cbuf->length - 1);
|
503
|
+
|
504
|
+
if (rb_class_of(rbvalue) == rb_cArray) {
|
505
|
+
if (length != rb_array_len(rbvalue))
|
506
|
+
rb_raise(rb_eArgError, "trying to assign a %ld long array to a %ld long sub-buffer", rb_array_len(rbvalue), length);
|
507
|
+
for (j = 0, i = ind_start; j < length; i++, j++) {
|
508
|
+
elem = rb_ary_entry(rbvalue, j);
|
509
|
+
cbuf->data[i].real = (float)NUM2DBL(rb_funcallv(elem, id_real, 0, NULL));
|
510
|
+
cbuf->data[i].imag = (float)NUM2DBL(rb_funcallv(elem, id_imag, 0, NULL));
|
511
|
+
}
|
512
|
+
}
|
513
|
+
else if (rb_class_of(rbvalue) == c_ComplexBuffer) {
|
514
|
+
ocbuf = paddlec_complex_buffer_get_struct(rbvalue);
|
515
|
+
if (length != (long)ocbuf->length)
|
516
|
+
rb_raise(rb_eArgError, "trying to assign a %lu long %"PRIsVALUE" to a %ld long sub-buffer", ocbuf->length, rb_class_name(rb_class_of(rbvalue)), length);
|
517
|
+
for (j = 0, i = ind_start; j < length; i++, j++)
|
518
|
+
cbuf->data[i] = ocbuf->data[j];
|
519
|
+
}
|
520
|
+
else if (rb_class_of(rbvalue) == c_FloatBuffer) {
|
521
|
+
ofbuf = paddlec_float_buffer_get_struct(rbvalue);
|
522
|
+
if (length != (long)ofbuf->length)
|
523
|
+
rb_raise(rb_eArgError, "trying to assign a %lu long %"PRIsVALUE" to a %ld long sub-buffer", ofbuf->length, rb_class_name(rb_class_of(rbvalue)), length);
|
524
|
+
for (j = 0, i = ind_start; j < length; i++, j++) {
|
525
|
+
cbuf->data[i].real = ofbuf->data[j];
|
526
|
+
cbuf->data[i].imag = 0.0f;
|
527
|
+
}
|
528
|
+
}
|
529
|
+
else {
|
530
|
+
value.real = (float)NUM2DBL(rb_funcallv(rbvalue, id_real, 0, NULL));
|
531
|
+
value.imag = (float)NUM2DBL(rb_funcallv(rbvalue, id_imag, 0, NULL));
|
532
|
+
ind_end = ind_start + length;
|
533
|
+
for (i = ind_start; i < ind_end; i++)
|
534
|
+
cbuf->data[i] = value;
|
535
|
+
}
|
536
|
+
|
537
|
+
return rbvalue;
|
538
|
+
}
|
539
|
+
|
540
|
+
|
541
|
+
#define PADDLEC_COMPLEX_BUFFER_MAX_TO_S_ELEMS 512
|
542
|
+
/* @return [String]
|
543
|
+
*/
|
544
|
+
static VALUE paddlec_complex_buffer_to_s(VALUE self)
|
545
|
+
{
|
546
|
+
const pdlc_complex_buffer_t *cbuf;
|
547
|
+
size_t nb_elm_to_print;
|
548
|
+
char *cstr, *p;
|
549
|
+
size_t i;
|
550
|
+
size_t avail;
|
551
|
+
VALUE str;
|
552
|
+
|
553
|
+
cbuf = paddlec_complex_buffer_get_struct(self);
|
554
|
+
|
555
|
+
nb_elm_to_print = cbuf->length;
|
556
|
+
if (nb_elm_to_print > PADDLEC_COMPLEX_BUFFER_MAX_TO_S_ELEMS)
|
557
|
+
nb_elm_to_print = PADDLEC_COMPLEX_BUFFER_MAX_TO_S_ELEMS;
|
558
|
+
|
559
|
+
avail = 32*nb_elm_to_print;
|
560
|
+
cstr = malloc(avail+64);
|
561
|
+
p = cstr;
|
562
|
+
sprintf(p, "["); p += strlen(p);
|
563
|
+
if (nb_elm_to_print > 0) {
|
564
|
+
switch (fpclassify(cbuf->data[0].real)) {
|
565
|
+
case FP_NORMAL:
|
566
|
+
case FP_SUBNORMAL:
|
567
|
+
case FP_ZERO:
|
568
|
+
sprintf(p, "(%.7g", cbuf->data[0].real);
|
569
|
+
break;
|
570
|
+
case FP_INFINITE:
|
571
|
+
sprintf(p, "(%sInfinity", (cbuf->data[0].real < 0.0f) ? "-" : "");
|
572
|
+
break;
|
573
|
+
default:
|
574
|
+
sprintf(p, "(NaN");
|
575
|
+
}
|
576
|
+
p += strlen(p);
|
577
|
+
switch (fpclassify(cbuf->data[0].imag)) {
|
578
|
+
case FP_NORMAL:
|
579
|
+
case FP_SUBNORMAL:
|
580
|
+
case FP_ZERO:
|
581
|
+
sprintf(p, "%+.7gi)", cbuf->data[0].imag);
|
582
|
+
break;
|
583
|
+
case FP_INFINITE:
|
584
|
+
sprintf(p, "%sInfinity*i)", (cbuf->data[0].imag < 0.0f) ? "-" : "+");
|
585
|
+
break;
|
586
|
+
default:
|
587
|
+
sprintf(p, "+NaN*i)");
|
588
|
+
}
|
589
|
+
p += strlen(p);
|
590
|
+
}
|
591
|
+
i = 1;
|
592
|
+
while ((size_t)(p - cstr) < avail && i < cbuf->length) {
|
593
|
+
switch (fpclassify(cbuf->data[i].real)) {
|
594
|
+
case FP_NORMAL:
|
595
|
+
case FP_SUBNORMAL:
|
596
|
+
case FP_ZERO:
|
597
|
+
sprintf(p, ", (%.7g", cbuf->data[i].real);
|
598
|
+
break;
|
599
|
+
case FP_INFINITE:
|
600
|
+
sprintf(p, ", (%sInfinity", (cbuf->data[i].real < 0.0f) ? "-" : "");
|
601
|
+
break;
|
602
|
+
default:
|
603
|
+
sprintf(p, ", (NaN");
|
604
|
+
}
|
605
|
+
p += strlen(p);
|
606
|
+
switch (fpclassify(cbuf->data[i].imag)) {
|
607
|
+
case FP_NORMAL:
|
608
|
+
case FP_SUBNORMAL:
|
609
|
+
case FP_ZERO:
|
610
|
+
sprintf(p, "%+.7gi)", cbuf->data[i].imag);
|
611
|
+
break;
|
612
|
+
case FP_INFINITE:
|
613
|
+
sprintf(p, "%sInfinity*i)", (cbuf->data[i].imag < 0.0f) ? "-" : "+");
|
614
|
+
break;
|
615
|
+
default:
|
616
|
+
sprintf(p, "+NaN*i)");
|
617
|
+
}
|
618
|
+
p += strlen(p);
|
619
|
+
i++;
|
620
|
+
}
|
621
|
+
if (i < cbuf->length) {
|
622
|
+
sprintf(p, ", ...(+%lu)", cbuf->length - i);
|
623
|
+
p += strlen(p);
|
624
|
+
}
|
625
|
+
sprintf(p, "]");
|
626
|
+
p += 1;
|
627
|
+
|
628
|
+
str = rb_str_new(cstr, (long)(p - cstr));
|
629
|
+
|
630
|
+
free(cstr);
|
631
|
+
|
632
|
+
return str;
|
633
|
+
}
|
634
|
+
|
635
|
+
|
636
|
+
/* Packs the contents of the buffer into a binary string, according to +format+.
|
637
|
+
* If the optional +outbuf+ is present, it must reference a String, which will receive the data.
|
638
|
+
* In this case, +outbuf will be resized accordingly.
|
639
|
+
* @return [String] the content of the buffer as a binary string
|
640
|
+
* @overload pack(format, outbuf = nil)
|
641
|
+
* @param format [Symbol] either +:u8+, +:s8+, +:u16+, +:s16+, +:u32+, +:s328+ or +:f32+
|
642
|
+
* @param outbuf [String, nil]
|
643
|
+
*/
|
644
|
+
static VALUE paddlec_complex_buffer_pack(int argc, VALUE *argv, VALUE self)
|
645
|
+
{
|
646
|
+
const pdlc_complex_buffer_t *cbuf;
|
647
|
+
VALUE str, format;
|
648
|
+
size_t i, len, slen;
|
649
|
+
ID fmt;
|
650
|
+
uint8_t *u8;
|
651
|
+
int8_t *s8;
|
652
|
+
uint16_t *u16;
|
653
|
+
int16_t *s16;
|
654
|
+
uint32_t *u32;
|
655
|
+
int32_t *s32;
|
656
|
+
float *f32;
|
657
|
+
|
658
|
+
rb_scan_args(argc, argv, "11", &format, &str);
|
659
|
+
|
660
|
+
cbuf = paddlec_complex_buffer_get_struct(self);
|
661
|
+
len = cbuf->length;
|
662
|
+
|
663
|
+
if (rb_class_of(format) != rb_cSymbol)
|
664
|
+
rb_raise(rb_eTypeError, "format must be a symbol, not a %"PRIsVALUE, rb_class_name(rb_class_of(format)));
|
665
|
+
fmt = SYM2ID(format);
|
666
|
+
if (fmt == id_u8 || fmt == id_s8)
|
667
|
+
slen = len * 2;
|
668
|
+
else if (fmt == id_u16 || fmt == id_s16)
|
669
|
+
slen = len * 4;
|
670
|
+
else if (fmt == id_u32 || fmt == id_s32 || fmt == id_f32)
|
671
|
+
slen = len * 8;
|
672
|
+
else
|
673
|
+
rb_raise(rb_eTypeError, "format must be either :u8, :s8, :u16, :s16, :u32, :s32 or :f32, not %"PRIsVALUE, format);
|
674
|
+
|
675
|
+
if (str == Qnil)
|
676
|
+
str = rb_usascii_str_new_cstr("");
|
677
|
+
else if (!rb_obj_is_kind_of(str, rb_cString))
|
678
|
+
rb_raise(rb_eTypeError, "expecting a string, not a %"PRIsVALUE, rb_class_name(rb_class_of(str)));
|
679
|
+
str = rb_str_resize(str, slen);
|
680
|
+
|
681
|
+
if (fmt == id_u8) {
|
682
|
+
u8 = (uint8_t*)rb_string_value_ptr(&str);
|
683
|
+
for (i = 0; i < len; i++) {
|
684
|
+
u8[i*2+0] = (uint8_t)fminf(255.0f, fmaxf(0.0f, (cbuf->data[i].real * 128.0f) + 128.0f));
|
685
|
+
u8[i*2+1] = (uint8_t)fminf(255.0f, fmaxf(0.0f, (cbuf->data[i].imag * 128.0f) + 128.0f));
|
686
|
+
}
|
687
|
+
}
|
688
|
+
else if (fmt == id_s8) {
|
689
|
+
s8 = (int8_t*)rb_string_value_ptr(&str);
|
690
|
+
for (i = 0; i < len; i++) {
|
691
|
+
s8[i*2+0] = (int8_t)fminf(127.0f, fmaxf(-128.0f, cbuf->data[i].real * 128.0f));
|
692
|
+
s8[i*2+1] = (int8_t)fminf(127.0f, fmaxf(-128.0f, cbuf->data[i].imag * 128.0f));
|
693
|
+
}
|
694
|
+
}
|
695
|
+
else if (fmt == id_u16) {
|
696
|
+
u16 = (uint16_t*)rb_string_value_ptr(&str);
|
697
|
+
for (i = 0; i < len; i++) {
|
698
|
+
u16[i*2+0] = (uint16_t)fminf(65535.0f, fmaxf(0.0f, (cbuf->data[i].real * 32768.0f) + 32768.0f));
|
699
|
+
u16[i*2+1] = (uint16_t)fminf(65535.0f, fmaxf(0.0f, (cbuf->data[i].imag * 32768.0f) + 32768.0f));
|
700
|
+
}
|
701
|
+
}
|
702
|
+
else if (fmt == id_s16) {
|
703
|
+
s16 = (int16_t*)rb_string_value_ptr(&str);
|
704
|
+
for (i = 0; i < len; i++) {
|
705
|
+
s16[i*2+0] = (uint16_t)fminf(32767.0f, fmaxf(-32768.0f, cbuf->data[i].real * 32768.0f));
|
706
|
+
s16[i*2+1] = (uint16_t)fminf(32767.0f, fmaxf(-32768.0f, cbuf->data[i].imag * 32768.0f));
|
707
|
+
}
|
708
|
+
}
|
709
|
+
else if (fmt == id_u32) {
|
710
|
+
u32 = (uint32_t*)rb_string_value_ptr(&str);
|
711
|
+
for (i = 0; i < len; i++) {
|
712
|
+
u32[i*2+0] = (uint32_t)fminf(4294967295.0f, fmaxf(0.0f, (cbuf->data[i].real * 2147483648.0f) + 2147483648.0f));
|
713
|
+
u32[i*2+1] = (uint32_t)fminf(4294967295.0f, fmaxf(0.0f, (cbuf->data[i].imag * 2147483648.0f) + 2147483648.0f));
|
714
|
+
}
|
715
|
+
}
|
716
|
+
else if (fmt == id_s32) {
|
717
|
+
s32 = (int32_t*)rb_string_value_ptr(&str);
|
718
|
+
for (i = 0; i < len; i++) {
|
719
|
+
s32[i*2+0] = (int32_t)fminf(2147483647.0f, fmaxf(-2147483648.0f, cbuf->data[i].real * 2147483648.0f));
|
720
|
+
s32[i*2+1] = (int32_t)fminf(2147483647.0f, fmaxf(-2147483648.0f, cbuf->data[i].imag * 2147483648.0f));
|
721
|
+
}
|
722
|
+
}
|
723
|
+
else if (fmt == id_f32) {
|
724
|
+
f32 = (float*)rb_string_value_ptr(&str);
|
725
|
+
memcpy(f32, cbuf->data, len*8);
|
726
|
+
}
|
727
|
+
|
728
|
+
return str;
|
729
|
+
}
|
730
|
+
|
731
|
+
|
732
|
+
/* Unpack the string +str+ into +self+ according to +format+.
|
733
|
+
* The complex buffer is resized accordingly.
|
734
|
+
* Real and imaginary parts of elements of +self+ will be in the range [-1, 1[;
|
735
|
+
* @param str [String]
|
736
|
+
* @param format [Symbol] either +:u8+, +:s8+, +:u16+, +:s16+, +:u32+, +:s328+ or +:f32+
|
737
|
+
* @return [self]
|
738
|
+
*/
|
739
|
+
static VALUE paddlec_complex_buffer_unpack(VALUE self, VALUE str, VALUE format)
|
740
|
+
{
|
741
|
+
pdlc_complex_buffer_t *cbuf;
|
742
|
+
ID fmt;
|
743
|
+
const void *ptr;
|
744
|
+
const uint8_t *u8;
|
745
|
+
const int8_t *s8;
|
746
|
+
const uint16_t *u16;
|
747
|
+
const int16_t *s16;
|
748
|
+
const uint32_t *u32;
|
749
|
+
const int32_t *s32;
|
750
|
+
const float *f32;
|
751
|
+
size_t i, len;
|
752
|
+
|
753
|
+
if (!rb_obj_is_kind_of(str, rb_cString))
|
754
|
+
rb_raise(rb_eTypeError, "expecting a string, not a %"PRIsVALUE, rb_class_name(rb_class_of(str)));
|
755
|
+
if (rb_class_of(format) != rb_cSymbol)
|
756
|
+
rb_raise(rb_eTypeError, "format must be a symbol, not a %"PRIsVALUE, rb_class_name(rb_class_of(format)));
|
757
|
+
fmt = SYM2ID(format);
|
758
|
+
ptr = rb_string_value_ptr(&str);
|
759
|
+
len = (size_t)RSTRING_LEN(str);
|
760
|
+
|
761
|
+
cbuf = paddlec_complex_buffer_get_struct(self);
|
762
|
+
|
763
|
+
if (fmt == id_u8) {
|
764
|
+
u8 = ptr;
|
765
|
+
len /= 2;
|
766
|
+
pdlc_complex_buffer_resize(cbuf, len, 0);
|
767
|
+
for (i = 0; i < len; i++) {
|
768
|
+
cbuf->data[i].real = ((float)u8[i*2+0] - 128.0f) / 128.0f;
|
769
|
+
cbuf->data[i].imag = ((float)u8[i*2+1] - 128.0f) / 128.0f;
|
770
|
+
}
|
771
|
+
}
|
772
|
+
else if (fmt == id_s8) {
|
773
|
+
s8 = ptr;
|
774
|
+
len /= 2;
|
775
|
+
pdlc_complex_buffer_resize(cbuf, len, 0);
|
776
|
+
for (i = 0; i < len; i++) {
|
777
|
+
cbuf->data[i].real = (float)s8[i*2+0] / 128.0f;
|
778
|
+
cbuf->data[i].imag = (float)s8[i*2+1] / 128.0f;
|
779
|
+
}
|
780
|
+
}
|
781
|
+
else if (fmt == id_u16) {
|
782
|
+
u16 = ptr;
|
783
|
+
len /= 4;
|
784
|
+
pdlc_complex_buffer_resize(cbuf, len, 0);
|
785
|
+
for (i = 0; i < len; i++) {
|
786
|
+
cbuf->data[i].real = ((float)u16[i*2+0] - 32768.0f) / 32768.0f;
|
787
|
+
cbuf->data[i].imag = ((float)u16[i*2+1] - 32768.0f) / 32768.0f;
|
788
|
+
}
|
789
|
+
}
|
790
|
+
else if (fmt == id_s16) {
|
791
|
+
s16 = ptr;
|
792
|
+
len /= 4;
|
793
|
+
pdlc_complex_buffer_resize(cbuf, len, 0);
|
794
|
+
for (i = 0; i < len; i++) {
|
795
|
+
cbuf->data[i].real = (float)s16[i*2+0] / 32768.0f;
|
796
|
+
cbuf->data[i].imag = (float)s16[i*2+1] / 32768.0f;
|
797
|
+
}
|
798
|
+
}
|
799
|
+
else if (fmt == id_u32) {
|
800
|
+
u32 = ptr;
|
801
|
+
len /= 8;
|
802
|
+
pdlc_complex_buffer_resize(cbuf, len, 0);
|
803
|
+
for (i = 0; i < len; i++) {
|
804
|
+
cbuf->data[i].real = ((float)u32[i*2+0] - 2147483648.0f) / 2147483648.0f;
|
805
|
+
cbuf->data[i].imag = ((float)u32[i*2+1] - 2147483648.0f) / 2147483648.0f;
|
806
|
+
}
|
807
|
+
}
|
808
|
+
else if (fmt == id_s32) {
|
809
|
+
s32 = ptr;
|
810
|
+
len /= 8;
|
811
|
+
pdlc_complex_buffer_resize(cbuf, len, 0);
|
812
|
+
for (i = 0; i < len; i++) {
|
813
|
+
cbuf->data[i].real = (float)s32[i*2+0] / 2147483648.0f;
|
814
|
+
cbuf->data[i].imag = (float)s32[i*2+1] / 2147483648.0f;
|
815
|
+
}
|
816
|
+
}
|
817
|
+
else if (fmt == id_f32) {
|
818
|
+
f32 = ptr;
|
819
|
+
len /= 8;
|
820
|
+
pdlc_complex_buffer_resize(cbuf, len, 0);
|
821
|
+
memcpy(cbuf->data, f32, len*8);
|
822
|
+
}
|
823
|
+
else
|
824
|
+
rb_raise(rb_eTypeError, "format must be either :u8, :s8, :u16, :s16, :u32, :s32 or :f32, not %"PRIsVALUE, format);
|
825
|
+
|
826
|
+
return self;
|
827
|
+
}
|
828
|
+
|
829
|
+
|
830
|
+
/* Unpack the string +str+ into a new {PaddleC::ComplexBuffer} according to +format+.
|
831
|
+
* The float buffer is resized accordingly.
|
832
|
+
* Elements of +self+ will be in the range [-1, 1[;
|
833
|
+
* @param str [String]
|
834
|
+
* @param format [Symbol] either +:u8+, +:s8+, +:u16+, +:s16+, +:u32+, +:s328+ or +:f32+
|
835
|
+
* @return [PaddleC::ComplexBuffer] a new {PaddleC::ComplexBuffer} filled with values from +str+
|
836
|
+
*/
|
837
|
+
static VALUE paddlec_complex_buffer_classunpack(VALUE self, VALUE str, VALUE format)
|
838
|
+
{
|
839
|
+
VALUE res = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
840
|
+
paddlec_complex_buffer_unpack(res, str, format);
|
841
|
+
return res;
|
842
|
+
}
|
843
|
+
|
844
|
+
|
845
|
+
/* Returns the native pointer pointing to the array of floats as an integer
|
846
|
+
* @return [Integer] native pointer to the data
|
847
|
+
*/
|
848
|
+
static VALUE paddlec_complex_buffer_native_ptr(VALUE self)
|
849
|
+
{
|
850
|
+
const pdlc_complex_buffer_t *cbuf;
|
851
|
+
void *ptr;
|
852
|
+
VALUE res;
|
853
|
+
|
854
|
+
cbuf = paddlec_complex_buffer_get_struct(self);
|
855
|
+
|
856
|
+
ptr = cbuf->data;
|
857
|
+
res = ULL2NUM( (sizeof(ptr) == 4) ? (unsigned long long int)(unsigned long int)ptr : (unsigned long long int)ptr );
|
858
|
+
|
859
|
+
return res;
|
860
|
+
}
|
861
|
+
|
862
|
+
|
863
|
+
/* Returns a FFI::Pointer pointing to the native array of floats.
|
864
|
+
* +FFI+ must be requiered +paddlec+ for this method to be defined.
|
865
|
+
* @return [FFI::Pointer] FFI::Pointer pointing to the native array of floats
|
866
|
+
*/
|
867
|
+
static VALUE paddlec_complex_buffer_ffi_pointer(VALUE self)
|
868
|
+
{
|
869
|
+
const pdlc_complex_buffer_t *cbuf;
|
870
|
+
VALUE type_and_addr[2];
|
871
|
+
VALUE res;
|
872
|
+
|
873
|
+
cbuf = paddlec_complex_buffer_get_struct(self);
|
874
|
+
|
875
|
+
type_and_addr[0] = o_FFI_Type_FLOAT;
|
876
|
+
type_and_addr[1] = paddlec_complex_buffer_native_ptr(self);
|
877
|
+
res = rb_class_new_instance(2, type_and_addr, c_FFI_Pointer);
|
878
|
+
res = rb_funcall(res, rb_intern("slice"), 2, LONG2NUM(0), ULONG2NUM(cbuf->length*sizeof(pdlc_complex_t)));
|
879
|
+
|
880
|
+
return res;
|
881
|
+
}
|
882
|
+
|
883
|
+
|
884
|
+
/* @return [self]
|
885
|
+
*/
|
886
|
+
static VALUE paddlec_complex_buffer_to_complex_buffer(VALUE self)
|
887
|
+
{
|
888
|
+
return self;
|
889
|
+
}
|
890
|
+
|
891
|
+
|
892
|
+
/* @return [PaddleC::ComplexBuffer]
|
893
|
+
*/
|
894
|
+
static VALUE paddlec_array_to_complex_buffer(VALUE self)
|
895
|
+
{
|
896
|
+
return rb_class_new_instance(1, &self, c_ComplexBuffer);
|
897
|
+
}
|
898
|
+
|
899
|
+
|
900
|
+
// /* Returns the real part.
|
901
|
+
// * @return [PaddleC::FloatBuffer] the real part of the buffer
|
902
|
+
// * @overload real(buffer = nil)
|
903
|
+
// * @param buffer [nil, PaddleC::FloatBuffer] if a {FloatBuffer} is provided, it is filled with the output
|
904
|
+
// */
|
905
|
+
// static VALUE paddlec_complex_buffer_real(int argc, VALUE *argv, VALUE self)
|
906
|
+
// {
|
907
|
+
// const pdlc_complex_buffer_t *cbuf;
|
908
|
+
// pdlc_buffer_t *ofbuf;
|
909
|
+
// VALUE buffer;
|
910
|
+
//
|
911
|
+
// rb_scan_args(argc, argv, "01", &buffer);
|
912
|
+
//
|
913
|
+
// if (buffer == Qnil)
|
914
|
+
// buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
915
|
+
// else if (rb_class_of(buffer) != c_FloatBuffer)
|
916
|
+
// rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected nil or %"PRIsVALUE")", rb_class_name(rb_class_of(buffer)), rb_class_name(c_FloatBuffer));
|
917
|
+
// ofbuf = paddlec_float_buffer_get_struct(buffer);
|
918
|
+
// cbuf = paddlec_complex_buffer_get_struct(self);
|
919
|
+
//
|
920
|
+
// pdlc_complex_buffer_real(cbuf, ofbuf);
|
921
|
+
//
|
922
|
+
// return buffer;
|
923
|
+
// }
|
924
|
+
//
|
925
|
+
//
|
926
|
+
// /* Returns the imaginary part.
|
927
|
+
// * @return [PaddleC::FloatBuffer] the real imaginary of the buffer
|
928
|
+
// * @overload imaginary(buffer = nil)
|
929
|
+
// * @overload imag(buffer = nil)
|
930
|
+
// * @param buffer [nil, PaddleC::FloatBuffer] if a {FloatBuffer} is provided, it is filled with the output
|
931
|
+
// */
|
932
|
+
// static VALUE paddlec_complex_buffer_imag(int argc, VALUE *argv, VALUE self)
|
933
|
+
// {
|
934
|
+
// const pdlc_complex_buffer_t *cbuf;
|
935
|
+
// pdlc_buffer_t *ofbuf;
|
936
|
+
// VALUE buffer;
|
937
|
+
//
|
938
|
+
// rb_scan_args(argc, argv, "01", &buffer);
|
939
|
+
//
|
940
|
+
// if (buffer == Qnil)
|
941
|
+
// buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
942
|
+
// else if (rb_class_of(buffer) != c_FloatBuffer)
|
943
|
+
// rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected nil or %"PRIsVALUE")", rb_class_name(rb_class_of(buffer)), rb_class_name(c_FloatBuffer));
|
944
|
+
// ofbuf = paddlec_float_buffer_get_struct(buffer);
|
945
|
+
// cbuf = paddlec_complex_buffer_get_struct(self);
|
946
|
+
//
|
947
|
+
// pdlc_complex_buffer_imag(cbuf, ofbuf);
|
948
|
+
//
|
949
|
+
// return buffer;
|
950
|
+
// }
|
951
|
+
//
|
952
|
+
//
|
953
|
+
// // /* Returns the absolute part of its polar form.
|
954
|
+
// // * @return [PaddleC::FloatBuffer] the absolute value
|
955
|
+
// // * @overload magnitude(buffer = nil)
|
956
|
+
// // * @overload abs(buffer = nil)
|
957
|
+
// // * @param buffer [nil, PaddleC::FloatBuffer] if a {FloatBuffer} is provided, it is filled with the output
|
958
|
+
// // */
|
959
|
+
// // static VALUE paddlec_complex_buffer_abs(int argc, VALUE *argv, VALUE self)
|
960
|
+
// // {
|
961
|
+
// // const pdlc_complex_buffer_t *cbuf;
|
962
|
+
// // pdlc_buffer_t *ofbuf;
|
963
|
+
// // VALUE buffer;
|
964
|
+
// //
|
965
|
+
// // rb_scan_args(argc, argv, "01", &buffer);
|
966
|
+
// //
|
967
|
+
// // if (buffer == Qnil)
|
968
|
+
// // buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
969
|
+
// // else if (rb_class_of(buffer) != c_FloatBuffer)
|
970
|
+
// // rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected nil or %"PRIsVALUE")", rb_class_name(rb_class_of(buffer)), rb_class_name(c_FloatBuffer));
|
971
|
+
// // ofbuf = paddlec_float_buffer_get_struct(buffer);
|
972
|
+
// // cbuf = paddlec_complex_buffer_get_struct(self);
|
973
|
+
// //
|
974
|
+
// // pdlc_complex_buffer_abs(cbuf, ofbuf);
|
975
|
+
// //
|
976
|
+
// // return buffer;
|
977
|
+
// // }
|
978
|
+
// //
|
979
|
+
// //
|
980
|
+
// // /* Returns the square of the absolute value.
|
981
|
+
// // * @return [PaddleC::FloatBuffer] the square of the absolute value
|
982
|
+
// // * @overload abs2(buffer = nil)
|
983
|
+
// // * @param buffer [nil, PaddleC::FloatBuffer] if a {FloatBuffer} is provided, it is filled with the output
|
984
|
+
// // */
|
985
|
+
// // static VALUE paddlec_complex_buffer_abs2(int argc, VALUE *argv, VALUE self)
|
986
|
+
// // {
|
987
|
+
// // const pdlc_complex_buffer_t *cbuf;
|
988
|
+
// // pdlc_buffer_t *ofbuf;
|
989
|
+
// // VALUE buffer;
|
990
|
+
// //
|
991
|
+
// // rb_scan_args(argc, argv, "01", &buffer);
|
992
|
+
// //
|
993
|
+
// // if (buffer == Qnil)
|
994
|
+
// // buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
995
|
+
// // else if (rb_class_of(buffer) != c_FloatBuffer)
|
996
|
+
// // rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected nil or %"PRIsVALUE")", rb_class_name(rb_class_of(buffer)), rb_class_name(c_FloatBuffer));
|
997
|
+
// // ofbuf = paddlec_float_buffer_get_struct(buffer);
|
998
|
+
// // cbuf = paddlec_complex_buffer_get_struct(self);
|
999
|
+
// //
|
1000
|
+
// // pdlc_complex_buffer_abs2(cbuf, ofbuf);
|
1001
|
+
// //
|
1002
|
+
// // return buffer;
|
1003
|
+
// // }
|
1004
|
+
//
|
1005
|
+
//
|
1006
|
+
// /* Returns the angle part of its polar form.
|
1007
|
+
// * @return [PaddleC::FloatBuffer] the angle in radians
|
1008
|
+
// * @overload arg(buffer = nil)
|
1009
|
+
// * @overload angle(buffer = nil)
|
1010
|
+
// * @overload phase(buffer = nil)
|
1011
|
+
// * @param buffer [nil, PaddleC::FloatBuffer] if a {FloatBuffer} is provided, it is filled with the output
|
1012
|
+
// */
|
1013
|
+
// static VALUE paddlec_complex_buffer_angle(int argc, VALUE *argv, VALUE self)
|
1014
|
+
// {
|
1015
|
+
// const pdlc_complex_buffer_t *cbuf;
|
1016
|
+
// pdlc_buffer_t *ofbuf;
|
1017
|
+
// VALUE buffer;
|
1018
|
+
//
|
1019
|
+
// rb_scan_args(argc, argv, "01", &buffer);
|
1020
|
+
//
|
1021
|
+
// if (buffer == Qnil)
|
1022
|
+
// buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
1023
|
+
// else if (rb_class_of(buffer) != c_FloatBuffer)
|
1024
|
+
// rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected nil or %"PRIsVALUE")", rb_class_name(rb_class_of(buffer)), rb_class_name(c_FloatBuffer));
|
1025
|
+
// ofbuf = paddlec_float_buffer_get_struct(buffer);
|
1026
|
+
// cbuf = paddlec_complex_buffer_get_struct(self);
|
1027
|
+
//
|
1028
|
+
// pdlc_complex_buffer_angle(cbuf, ofbuf);
|
1029
|
+
//
|
1030
|
+
// return buffer;
|
1031
|
+
// }
|
1032
|
+
//
|
1033
|
+
//
|
1034
|
+
// /* Returns the complex conjugate.
|
1035
|
+
// * @return [PaddleC::FloatBuffer] the complex conjugate
|
1036
|
+
// * @overload conjugate(buffer = nil)
|
1037
|
+
// * @overload conj(buffer = nil)
|
1038
|
+
// * @param buffer [nil, PaddleC::FloatBuffer] if a {FloatBuffer} is provided, it is filled with the output
|
1039
|
+
// */
|
1040
|
+
// static VALUE paddlec_complex_buffer_conj(int argc, VALUE *argv, VALUE self)
|
1041
|
+
// {
|
1042
|
+
// const pdlc_complex_buffer_t *cbuf;
|
1043
|
+
// pdlc_complex_buffer_t *ocbuf;
|
1044
|
+
// VALUE buffer;
|
1045
|
+
//
|
1046
|
+
// rb_scan_args(argc, argv, "01", &buffer);
|
1047
|
+
//
|
1048
|
+
// if (buffer == Qnil)
|
1049
|
+
// buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
1050
|
+
// else if (rb_class_of(buffer) != c_ComplexBuffer)
|
1051
|
+
// rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected nil or %"PRIsVALUE")", rb_class_name(rb_class_of(buffer)), rb_class_name(c_ComplexBuffer));
|
1052
|
+
// ocbuf = paddlec_complex_buffer_get_struct(buffer);
|
1053
|
+
// cbuf = paddlec_complex_buffer_get_struct(self);
|
1054
|
+
//
|
1055
|
+
// pdlc_complex_buffer_conj(cbuf, ocbuf);
|
1056
|
+
//
|
1057
|
+
// return buffer;
|
1058
|
+
// }
|
1059
|
+
|
1060
|
+
|
1061
|
+
/* @see Array#zip
|
1062
|
+
* @return [Array]
|
1063
|
+
*/
|
1064
|
+
static VALUE paddlec_complex_buffer_zip(int argc, VALUE *argv, VALUE self)
|
1065
|
+
{
|
1066
|
+
VALUE a, res;
|
1067
|
+
|
1068
|
+
a = paddlec_complex_buffer_to_a(self);
|
1069
|
+
res = rb_funcallv(a, id_zip, argc, argv);
|
1070
|
+
|
1071
|
+
return res;
|
1072
|
+
}
|
1073
|
+
|
1074
|
+
|
1075
|
+
/* If +numeric+ is a +Complex+, returns an array +[PaddleC::ComplexBuffer, self]+.
|
1076
|
+
* Otherwise, returns an array +[PaddleC::FloatBuffer, self]+.
|
1077
|
+
*
|
1078
|
+
* The coercion mechanism is used by Ruby to handle mixed-type numeric operations:
|
1079
|
+
* it is intended to find a compatible common type between the two operands of the operator.
|
1080
|
+
*
|
1081
|
+
* @param numeric [Numeric]
|
1082
|
+
* @return [Array<PaddleC::FloatBuffer, PaddleC::ComplexBuffer>]
|
1083
|
+
*/
|
1084
|
+
static VALUE paddlec_complex_buffer_coerce(VALUE self, VALUE numeric)
|
1085
|
+
{
|
1086
|
+
VALUE other_coerced;
|
1087
|
+
VALUE len_val[2];
|
1088
|
+
|
1089
|
+
len_val[0] = rb_funcallv(self, id_length, 0, NULL);
|
1090
|
+
len_val[1] = numeric;
|
1091
|
+
if (rb_class_of(numeric) == rb_cComplex)
|
1092
|
+
other_coerced = rb_class_new_instance(2, len_val, c_ComplexBuffer);
|
1093
|
+
else
|
1094
|
+
other_coerced = rb_class_new_instance(2, len_val, c_FloatBuffer);
|
1095
|
+
|
1096
|
+
return rb_assoc_new(other_coerced, self);
|
1097
|
+
}
|
1098
|
+
|
1099
|
+
|
1100
|
+
/* Unary plus, returns the receiver.
|
1101
|
+
* @return [self]
|
1102
|
+
*/
|
1103
|
+
static VALUE paddlec_complex_buffer_unaryplus(VALUE self)
|
1104
|
+
{
|
1105
|
+
return self;
|
1106
|
+
}
|
1107
|
+
|
1108
|
+
|
1109
|
+
static pdlc_buffer_t* pdlc_complex_buffer_finite(const pdlc_complex_buffer_t *cbuf, pdlc_buffer_t *ofbuf)
|
1110
|
+
{
|
1111
|
+
size_t i;
|
1112
|
+
|
1113
|
+
if (!ofbuf)
|
1114
|
+
ofbuf = pdlc_buffer_new(cbuf->length);
|
1115
|
+
else
|
1116
|
+
pdlc_buffer_resize(ofbuf, cbuf->length, 0);
|
1117
|
+
|
1118
|
+
for (i = 0; i < cbuf->length; i++)
|
1119
|
+
ofbuf->data[i] = ((isfinite(cbuf->data[i].real) && isfinite(cbuf->data[i].imag)) ? 1.0f : 0.0f);
|
1120
|
+
|
1121
|
+
return ofbuf;
|
1122
|
+
}
|
1123
|
+
|
1124
|
+
|
1125
|
+
static pdlc_buffer_t* pdlc_complex_buffer_infinite(const pdlc_complex_buffer_t *cbuf, pdlc_buffer_t *ofbuf)
|
1126
|
+
{
|
1127
|
+
size_t i;
|
1128
|
+
|
1129
|
+
if (!ofbuf)
|
1130
|
+
ofbuf = pdlc_buffer_new(cbuf->length);
|
1131
|
+
else
|
1132
|
+
pdlc_buffer_resize(ofbuf, cbuf->length, 0);
|
1133
|
+
|
1134
|
+
for (i = 0; i < cbuf->length; i++)
|
1135
|
+
ofbuf->data[i] = ((isinf(cbuf->data[i].real) || isinf(cbuf->data[i].imag)) ? 1.0f : 0.0f);
|
1136
|
+
|
1137
|
+
return ofbuf;
|
1138
|
+
}
|
1139
|
+
|
1140
|
+
|
1141
|
+
static pdlc_buffer_t* pdlc_complex_buffer_nan(const pdlc_complex_buffer_t *cbuf, pdlc_buffer_t *ofbuf)
|
1142
|
+
{
|
1143
|
+
size_t i;
|
1144
|
+
|
1145
|
+
if (!ofbuf)
|
1146
|
+
ofbuf = pdlc_buffer_new(cbuf->length);
|
1147
|
+
else
|
1148
|
+
pdlc_buffer_resize(ofbuf, cbuf->length, 0);
|
1149
|
+
|
1150
|
+
for (i = 0; i < cbuf->length; i++)
|
1151
|
+
ofbuf->data[i] = ((isnan(cbuf->data[i].real) || isnan(cbuf->data[i].imag)) ? 1.0f : 0.0f);
|
1152
|
+
|
1153
|
+
return ofbuf;
|
1154
|
+
}
|
1155
|
+
|
1156
|
+
|
1157
|
+
static pdlc_buffer_t* pdlc_complex_buffer_integer(const pdlc_complex_buffer_t *cbuf, pdlc_buffer_t *ofbuf)
|
1158
|
+
{
|
1159
|
+
size_t i;
|
1160
|
+
|
1161
|
+
if (!ofbuf)
|
1162
|
+
ofbuf = pdlc_buffer_new(cbuf->length);
|
1163
|
+
else
|
1164
|
+
pdlc_buffer_resize(ofbuf, cbuf->length, 0);
|
1165
|
+
|
1166
|
+
for (i = 0; i < cbuf->length; i++)
|
1167
|
+
ofbuf->data[i] = ((isfinite(cbuf->data[i].real) && isfinite(cbuf->data[i].imag) && (cbuf->data[i].real == truncf(cbuf->data[i].real)) && (cbuf->data[i].imag == truncf(cbuf->data[i].imag))) ? 1.0f : 0.0f);
|
1168
|
+
|
1169
|
+
return ofbuf;
|
1170
|
+
}
|
1171
|
+
|
1172
|
+
|
1173
|
+
static pdlc_buffer_t* pdlc_complex_buffer_nonzero(const pdlc_complex_buffer_t *cbuf, pdlc_buffer_t *ofbuf)
|
1174
|
+
{
|
1175
|
+
size_t i;
|
1176
|
+
|
1177
|
+
if (!ofbuf)
|
1178
|
+
ofbuf = pdlc_buffer_new(cbuf->length);
|
1179
|
+
else
|
1180
|
+
pdlc_buffer_resize(ofbuf, cbuf->length, 0);
|
1181
|
+
|
1182
|
+
for (i = 0; i < cbuf->length; i++)
|
1183
|
+
ofbuf->data[i] = ((cbuf->data[i].real == 0.0f && cbuf->data[i].imag == 0.0f) ? 0.0f : 1.0f);
|
1184
|
+
|
1185
|
+
return ofbuf;
|
1186
|
+
}
|
1187
|
+
|
1188
|
+
|
1189
|
+
static pdlc_buffer_t* pdlc_complex_buffer_zero(const pdlc_complex_buffer_t *cbuf, pdlc_buffer_t *ofbuf)
|
1190
|
+
{
|
1191
|
+
size_t i;
|
1192
|
+
|
1193
|
+
if (!ofbuf)
|
1194
|
+
ofbuf = pdlc_buffer_new(cbuf->length);
|
1195
|
+
else
|
1196
|
+
pdlc_buffer_resize(ofbuf, cbuf->length, 0);
|
1197
|
+
|
1198
|
+
for (i = 0; i < cbuf->length; i++)
|
1199
|
+
ofbuf->data[i] = ((cbuf->data[i].real == 0.0f && cbuf->data[i].imag == 0.0f) ? 1.0f : 0.0f);
|
1200
|
+
|
1201
|
+
return ofbuf;
|
1202
|
+
}
|
1203
|
+
|
1204
|
+
|
1205
|
+
/* Returns a {PaddleC::FloatBuffer}. 1.0 for values which are valid IEEE floating point number, i.e. which are not infinite or NaN, 0.0 otherwize.
|
1206
|
+
* @return [PaddleC::FloatBuffer]
|
1207
|
+
*/
|
1208
|
+
static VALUE paddlec_complex_buffer_finite(VALUE self)
|
1209
|
+
{
|
1210
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1211
|
+
pdlc_buffer_t *rfbuf;
|
1212
|
+
VALUE buffer;
|
1213
|
+
|
1214
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1215
|
+
buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
1216
|
+
rfbuf = paddlec_float_buffer_get_struct(buffer);
|
1217
|
+
pdlc_complex_buffer_finite(mcbuf, rfbuf);
|
1218
|
+
|
1219
|
+
return buffer;
|
1220
|
+
}
|
1221
|
+
|
1222
|
+
|
1223
|
+
/* Returns a {PaddleC::FloatBuffer}. 1.0 for values which are positive or negative infinity, 0.0 otherwize.
|
1224
|
+
* @return [PaddleC::FloatBuffer]
|
1225
|
+
*/
|
1226
|
+
static VALUE paddlec_complex_buffer_infinite(VALUE self)
|
1227
|
+
{
|
1228
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1229
|
+
pdlc_buffer_t *rfbuf;
|
1230
|
+
VALUE buffer;
|
1231
|
+
|
1232
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1233
|
+
buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
1234
|
+
rfbuf = paddlec_float_buffer_get_struct(buffer);
|
1235
|
+
pdlc_complex_buffer_infinite(mcbuf, rfbuf);
|
1236
|
+
|
1237
|
+
return buffer;
|
1238
|
+
}
|
1239
|
+
|
1240
|
+
|
1241
|
+
/* Returns a {PaddleC::FloatBuffer}. 1.0 for values which are NaN, 0.0 otherwize.
|
1242
|
+
* @return [PaddleC::FloatBuffer]
|
1243
|
+
*/
|
1244
|
+
static VALUE paddlec_complex_buffer_nan(VALUE self)
|
1245
|
+
{
|
1246
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1247
|
+
pdlc_buffer_t *rfbuf;
|
1248
|
+
VALUE buffer;
|
1249
|
+
|
1250
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1251
|
+
buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
1252
|
+
rfbuf = paddlec_float_buffer_get_struct(buffer);
|
1253
|
+
pdlc_complex_buffer_nan(mcbuf, rfbuf);
|
1254
|
+
|
1255
|
+
return buffer;
|
1256
|
+
}
|
1257
|
+
|
1258
|
+
|
1259
|
+
/* Returns a {PaddleC::FloatBuffer}. 1.0 if +value == value.truncate+, 0.0 otherwise.
|
1260
|
+
* @return [PaddleC::FloatBuffer]
|
1261
|
+
*/
|
1262
|
+
static VALUE paddlec_complex_buffer_integer(VALUE self)
|
1263
|
+
{
|
1264
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1265
|
+
pdlc_buffer_t *rfbuf;
|
1266
|
+
VALUE buffer;
|
1267
|
+
|
1268
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1269
|
+
buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
1270
|
+
rfbuf = paddlec_float_buffer_get_struct(buffer);
|
1271
|
+
pdlc_complex_buffer_integer(mcbuf, rfbuf);
|
1272
|
+
|
1273
|
+
return buffer;
|
1274
|
+
}
|
1275
|
+
|
1276
|
+
|
1277
|
+
/* Returns a {PaddleC::FloatBuffer}. 1.0 if +value != 0+, 0.0 otherwise.
|
1278
|
+
* @return [PaddleC::FloatBuffer]
|
1279
|
+
*/
|
1280
|
+
static VALUE paddlec_complex_buffer_nonzero(VALUE self)
|
1281
|
+
{
|
1282
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1283
|
+
pdlc_buffer_t *rfbuf;
|
1284
|
+
VALUE buffer;
|
1285
|
+
|
1286
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1287
|
+
buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
1288
|
+
rfbuf = paddlec_float_buffer_get_struct(buffer);
|
1289
|
+
pdlc_complex_buffer_nonzero(mcbuf, rfbuf);
|
1290
|
+
|
1291
|
+
return buffer;
|
1292
|
+
}
|
1293
|
+
|
1294
|
+
|
1295
|
+
/* Returns a {PaddleC::FloatBuffer}. 1.0 if +value == 0+, 0.0 otherwise.
|
1296
|
+
* @return [PaddleC::FloatBuffer]
|
1297
|
+
*/
|
1298
|
+
static VALUE paddlec_complex_buffer_zero(VALUE self)
|
1299
|
+
{
|
1300
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1301
|
+
pdlc_buffer_t *rfbuf;
|
1302
|
+
VALUE buffer;
|
1303
|
+
|
1304
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1305
|
+
buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
1306
|
+
rfbuf = paddlec_float_buffer_get_struct(buffer);
|
1307
|
+
pdlc_complex_buffer_zero(mcbuf, rfbuf);
|
1308
|
+
|
1309
|
+
return buffer;
|
1310
|
+
}
|
1311
|
+
|
1312
|
+
|
1313
|
+
/* Returns a {PaddleC::FloatBuffer}. 1.0 for true, 0.0 for false.
|
1314
|
+
* @param other [PaddleC::ComplexBuffer, Complex, PaddleC::FloatBuffer, Numeric]
|
1315
|
+
* @return [PaddleC::FloatBuffer]
|
1316
|
+
*/
|
1317
|
+
static VALUE paddlec_complex_buffer_equ(VALUE self, VALUE other)
|
1318
|
+
{
|
1319
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1320
|
+
pdlc_buffer_t *rfbuf;
|
1321
|
+
const pdlc_complex_buffer_t *ocbuf;
|
1322
|
+
pdlc_complex_t oc;
|
1323
|
+
const pdlc_buffer_t *ofbuf;
|
1324
|
+
float of;
|
1325
|
+
VALUE buffer;
|
1326
|
+
|
1327
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1328
|
+
|
1329
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer) || rb_obj_is_kind_of(other, rb_cComplex) || rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
1330
|
+
buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
1331
|
+
rfbuf = paddlec_float_buffer_get_struct(buffer);
|
1332
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
1333
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
1334
|
+
pdlc_cb_cb_equ(mcbuf, ocbuf, rfbuf);
|
1335
|
+
}
|
1336
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
1337
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
1338
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
1339
|
+
pdlc_cb_cs_equ(mcbuf, oc, rfbuf);
|
1340
|
+
}
|
1341
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
1342
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
1343
|
+
pdlc_cb_fb_equ(mcbuf, ofbuf, rfbuf);
|
1344
|
+
}
|
1345
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
1346
|
+
of = (float)NUM2DBL(other);
|
1347
|
+
pdlc_cb_fs_equ(mcbuf, of, rfbuf);
|
1348
|
+
}
|
1349
|
+
}
|
1350
|
+
else
|
1351
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
1352
|
+
|
1353
|
+
return buffer;
|
1354
|
+
}
|
1355
|
+
|
1356
|
+
|
1357
|
+
/* Returns a {PaddleC::FloatBuffer}. 1.0 for true, 0.0 for false.
|
1358
|
+
* @param other [PaddleC::ComplexBuffer, Complex, PaddleC::FloatBuffer, Numeric]
|
1359
|
+
* @return [PaddleC::FloatBuffer]
|
1360
|
+
*/
|
1361
|
+
static VALUE paddlec_complex_buffer_different(VALUE self, VALUE other)
|
1362
|
+
{
|
1363
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1364
|
+
pdlc_buffer_t *rfbuf;
|
1365
|
+
const pdlc_complex_buffer_t *ocbuf;
|
1366
|
+
pdlc_complex_t oc;
|
1367
|
+
const pdlc_buffer_t *ofbuf;
|
1368
|
+
float of;
|
1369
|
+
VALUE buffer;
|
1370
|
+
|
1371
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1372
|
+
|
1373
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer) || rb_obj_is_kind_of(other, rb_cComplex) || rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
1374
|
+
buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
1375
|
+
rfbuf = paddlec_float_buffer_get_struct(buffer);
|
1376
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
1377
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
1378
|
+
pdlc_cb_cb_different(mcbuf, ocbuf, rfbuf);
|
1379
|
+
}
|
1380
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
1381
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
1382
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
1383
|
+
pdlc_cb_cs_different(mcbuf, oc, rfbuf);
|
1384
|
+
}
|
1385
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
1386
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
1387
|
+
pdlc_cb_fb_different(mcbuf, ofbuf, rfbuf);
|
1388
|
+
}
|
1389
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
1390
|
+
of = (float)NUM2DBL(other);
|
1391
|
+
pdlc_cb_fs_different(mcbuf, of, rfbuf);
|
1392
|
+
}
|
1393
|
+
}
|
1394
|
+
else
|
1395
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
1396
|
+
|
1397
|
+
return buffer;
|
1398
|
+
}
|
1399
|
+
|
1400
|
+
|
1401
|
+
/* Returns the smallest numbers greater than or equal to values of +self+, with a precision of +ndigits+ decimal digits (default: 0).
|
1402
|
+
* @overload ceil(ndigits = 0, buffer = nil)
|
1403
|
+
* @param ndigits [Integer] precision
|
1404
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if provided, the result is written into +buffer+.
|
1405
|
+
* @return [PaddleC::ComplexBuffer]
|
1406
|
+
*/
|
1407
|
+
static VALUE paddlec_complex_buffer_ceil(int argc, VALUE *argv, VALUE self)
|
1408
|
+
{
|
1409
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1410
|
+
pdlc_complex_buffer_t *rcbuf;
|
1411
|
+
VALUE digits, buffer, tmp;
|
1412
|
+
int d;
|
1413
|
+
|
1414
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1415
|
+
|
1416
|
+
rb_scan_args(argc, argv, "02", &digits, &buffer);
|
1417
|
+
if (NIL_P(buffer) && rb_obj_is_kind_of(digits, c_ComplexBuffer)) {
|
1418
|
+
buffer = digits;
|
1419
|
+
digits = Qnil;
|
1420
|
+
}
|
1421
|
+
else if (rb_obj_is_kind_of(buffer, rb_cNumeric) && rb_obj_is_kind_of(digits, c_ComplexBuffer)) {
|
1422
|
+
tmp = buffer;
|
1423
|
+
buffer = digits;
|
1424
|
+
digits = tmp;
|
1425
|
+
}
|
1426
|
+
|
1427
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
1428
|
+
rb_warn("expecting a %"PRIsVALUE" as buffer, not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
1429
|
+
buffer = Qnil;
|
1430
|
+
}
|
1431
|
+
if (buffer == Qnil)
|
1432
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
1433
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
1434
|
+
|
1435
|
+
if (digits == Qnil)
|
1436
|
+
pdlc_complex_buffer_ceil(mcbuf, rcbuf);
|
1437
|
+
else {
|
1438
|
+
d = NUM2INT(digits);
|
1439
|
+
pdlc_complex_buffer_ceil_digits(mcbuf, d, rcbuf);
|
1440
|
+
}
|
1441
|
+
|
1442
|
+
return buffer;
|
1443
|
+
}
|
1444
|
+
|
1445
|
+
|
1446
|
+
/* Returns the smallest integral values that are not less than values of +self+, with a precision of +ndigits+ decimal digits (default: 0).
|
1447
|
+
* @overload ceil!(ndigits = 0)
|
1448
|
+
* @param ndigits [Integer] precision
|
1449
|
+
* @return [self]
|
1450
|
+
*/
|
1451
|
+
static VALUE paddlec_complex_buffer_ceil_inplace(int argc, VALUE *argv, VALUE self)
|
1452
|
+
{
|
1453
|
+
pdlc_complex_buffer_t *mcbuf;
|
1454
|
+
VALUE digits;
|
1455
|
+
int d;
|
1456
|
+
|
1457
|
+
rb_scan_args(argc, argv, "01", &digits);
|
1458
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1459
|
+
|
1460
|
+
if (digits == Qnil)
|
1461
|
+
pdlc_complex_buffer_ceil_inplace(mcbuf);
|
1462
|
+
else {
|
1463
|
+
d = NUM2INT(digits);
|
1464
|
+
pdlc_complex_buffer_ceil_digits_inplace(mcbuf, d);
|
1465
|
+
}
|
1466
|
+
|
1467
|
+
return self;
|
1468
|
+
}
|
1469
|
+
|
1470
|
+
|
1471
|
+
/* Returns the largest integral values that are not greater than values of +self+, with a precision of +ndigits+ decimal digits (default: 0).
|
1472
|
+
* @overload floor(ndigits = 0, buffer = nil)
|
1473
|
+
* @param ndigits [Integer] precision
|
1474
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if provided, the result is written into +buffer+.
|
1475
|
+
* @return [PaddleC::ComplexBuffer]
|
1476
|
+
*/
|
1477
|
+
static VALUE paddlec_complex_buffer_floor(int argc, VALUE *argv, VALUE self)
|
1478
|
+
{
|
1479
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1480
|
+
pdlc_complex_buffer_t *rcbuf;
|
1481
|
+
VALUE digits, buffer, tmp;
|
1482
|
+
int d;
|
1483
|
+
|
1484
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1485
|
+
|
1486
|
+
rb_scan_args(argc, argv, "02", &digits, &buffer);
|
1487
|
+
if (NIL_P(buffer) && rb_obj_is_kind_of(digits, c_ComplexBuffer)) {
|
1488
|
+
buffer = digits;
|
1489
|
+
digits = Qnil;
|
1490
|
+
}
|
1491
|
+
else if (rb_obj_is_kind_of(buffer, rb_cNumeric) && rb_obj_is_kind_of(digits, c_ComplexBuffer)) {
|
1492
|
+
tmp = buffer;
|
1493
|
+
buffer = digits;
|
1494
|
+
digits = tmp;
|
1495
|
+
}
|
1496
|
+
|
1497
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
1498
|
+
rb_warn("expecting a %"PRIsVALUE" as buffer, not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
1499
|
+
buffer = Qnil;
|
1500
|
+
}
|
1501
|
+
if (buffer == Qnil)
|
1502
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
1503
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
1504
|
+
|
1505
|
+
if (digits == Qnil)
|
1506
|
+
pdlc_complex_buffer_floor(mcbuf, rcbuf);
|
1507
|
+
else {
|
1508
|
+
d = NUM2INT(digits);
|
1509
|
+
pdlc_complex_buffer_floor_digits(mcbuf, d, rcbuf);
|
1510
|
+
}
|
1511
|
+
|
1512
|
+
return buffer;
|
1513
|
+
}
|
1514
|
+
|
1515
|
+
|
1516
|
+
/* Returns the largest integral values that are not greater than values of +self+, with a precision of +ndigits+ decimal digits (default: 0).
|
1517
|
+
* @overload floor!(ndigits = 0)
|
1518
|
+
* @param ndigits [Integer] precision
|
1519
|
+
* @return [self]
|
1520
|
+
*/
|
1521
|
+
static VALUE paddlec_complex_buffer_floor_inplace(int argc, VALUE *argv, VALUE self)
|
1522
|
+
{
|
1523
|
+
pdlc_complex_buffer_t *mcbuf;
|
1524
|
+
VALUE digits;
|
1525
|
+
int d;
|
1526
|
+
|
1527
|
+
rb_scan_args(argc, argv, "01", &digits);
|
1528
|
+
|
1529
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1530
|
+
|
1531
|
+
if (digits == Qnil)
|
1532
|
+
pdlc_complex_buffer_floor_inplace(mcbuf);
|
1533
|
+
else {
|
1534
|
+
d = NUM2INT(digits);
|
1535
|
+
pdlc_complex_buffer_floor_digits_inplace(mcbuf, d);
|
1536
|
+
}
|
1537
|
+
|
1538
|
+
return self;
|
1539
|
+
}
|
1540
|
+
|
1541
|
+
|
1542
|
+
/* Truncates values of +self+ to the nearest integers not larger in absolute value, with a precision of +ndigits+ decimal digits (default: 0).
|
1543
|
+
* @overload truncate(ndigits = 0, buffer = nil)
|
1544
|
+
* @param ndigits [Integer] precision
|
1545
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if provided, the result is written into +buffer+.
|
1546
|
+
* @return [PaddleC::ComplexBuffer]
|
1547
|
+
*/
|
1548
|
+
static VALUE paddlec_complex_buffer_truncate(int argc, VALUE *argv, VALUE self)
|
1549
|
+
{
|
1550
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1551
|
+
pdlc_complex_buffer_t *rcbuf;
|
1552
|
+
VALUE digits, buffer, tmp;
|
1553
|
+
int d;
|
1554
|
+
|
1555
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1556
|
+
|
1557
|
+
rb_scan_args(argc, argv, "02", &digits, &buffer);
|
1558
|
+
if (NIL_P(buffer) && rb_obj_is_kind_of(digits, c_ComplexBuffer)) {
|
1559
|
+
buffer = digits;
|
1560
|
+
digits = Qnil;
|
1561
|
+
}
|
1562
|
+
else if (rb_obj_is_kind_of(buffer, rb_cNumeric) && rb_obj_is_kind_of(digits, c_ComplexBuffer)) {
|
1563
|
+
tmp = buffer;
|
1564
|
+
buffer = digits;
|
1565
|
+
digits = tmp;
|
1566
|
+
}
|
1567
|
+
|
1568
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
1569
|
+
rb_warn("expecting a %"PRIsVALUE" as buffer, not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
1570
|
+
buffer = Qnil;
|
1571
|
+
}
|
1572
|
+
if (buffer == Qnil)
|
1573
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
1574
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
1575
|
+
|
1576
|
+
if (digits == Qnil)
|
1577
|
+
pdlc_complex_buffer_truncate(mcbuf, rcbuf);
|
1578
|
+
else {
|
1579
|
+
d = NUM2INT(digits);
|
1580
|
+
pdlc_complex_buffer_truncate_digits(mcbuf, d, rcbuf);
|
1581
|
+
}
|
1582
|
+
|
1583
|
+
return buffer;
|
1584
|
+
}
|
1585
|
+
|
1586
|
+
|
1587
|
+
/* Truncates values of +self+ to the nearest integers not larger in absolute value, with a precision of +ndigits+ decimal digits (default: 0).
|
1588
|
+
* @overload truncate!(ndigits = 0)
|
1589
|
+
* @param ndigits [Integer] precision
|
1590
|
+
* @return [self]
|
1591
|
+
*/
|
1592
|
+
static VALUE paddlec_complex_buffer_truncate_inplace(int argc, VALUE *argv, VALUE self)
|
1593
|
+
{
|
1594
|
+
pdlc_complex_buffer_t *mcbuf;
|
1595
|
+
VALUE digits;
|
1596
|
+
int d;
|
1597
|
+
|
1598
|
+
rb_scan_args(argc, argv, "01", &digits);
|
1599
|
+
|
1600
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1601
|
+
|
1602
|
+
if (digits == Qnil)
|
1603
|
+
pdlc_complex_buffer_truncate_inplace(mcbuf);
|
1604
|
+
else {
|
1605
|
+
d = NUM2INT(digits);
|
1606
|
+
pdlc_complex_buffer_truncate_digits_inplace(mcbuf, d);
|
1607
|
+
}
|
1608
|
+
|
1609
|
+
return self;
|
1610
|
+
}
|
1611
|
+
|
1612
|
+
|
1613
|
+
/* Rounds values of +self+ to the nearest integers, but round halfway cases away from zero, with a precision of +ndigits+ decimal digits (default: 0).
|
1614
|
+
* @overload round(ndigits = 0, buffer = nil)
|
1615
|
+
* @param ndigits [Integer] precision
|
1616
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if provided, the result is written into +buffer+.
|
1617
|
+
* @return [PaddleC::ComplexBuffer]
|
1618
|
+
*/
|
1619
|
+
static VALUE paddlec_complex_buffer_round(int argc, VALUE *argv, VALUE self)
|
1620
|
+
{
|
1621
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1622
|
+
pdlc_complex_buffer_t *rcbuf;
|
1623
|
+
VALUE digits, buffer, tmp;
|
1624
|
+
int d;
|
1625
|
+
|
1626
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1627
|
+
|
1628
|
+
rb_scan_args(argc, argv, "02", &digits, &buffer);
|
1629
|
+
if (NIL_P(buffer) && rb_obj_is_kind_of(digits, c_ComplexBuffer)) {
|
1630
|
+
buffer = digits;
|
1631
|
+
digits = Qnil;
|
1632
|
+
}
|
1633
|
+
else if (rb_obj_is_kind_of(buffer, rb_cNumeric) && rb_obj_is_kind_of(digits, c_ComplexBuffer)) {
|
1634
|
+
tmp = buffer;
|
1635
|
+
buffer = digits;
|
1636
|
+
digits = tmp;
|
1637
|
+
}
|
1638
|
+
|
1639
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
1640
|
+
rb_warn("expecting a %"PRIsVALUE" as buffer, not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
1641
|
+
buffer = Qnil;
|
1642
|
+
}
|
1643
|
+
if (buffer == Qnil)
|
1644
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
1645
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
1646
|
+
|
1647
|
+
if (digits == Qnil)
|
1648
|
+
pdlc_complex_buffer_round(mcbuf, rcbuf);
|
1649
|
+
else {
|
1650
|
+
d = NUM2INT(digits);
|
1651
|
+
pdlc_complex_buffer_round_digits(mcbuf, d, rcbuf);
|
1652
|
+
}
|
1653
|
+
|
1654
|
+
return buffer;
|
1655
|
+
}
|
1656
|
+
|
1657
|
+
|
1658
|
+
/* Rounds values of +self+ to the nearest integers, but round halfway cases away from zero, with a precision of +ndigits+ decimal digits (default: 0).
|
1659
|
+
* @overload round!(ndigits = 0)
|
1660
|
+
* @param ndigits [Integer] precision
|
1661
|
+
* @return [self]
|
1662
|
+
*/
|
1663
|
+
static VALUE paddlec_complex_buffer_round_inplace(int argc, VALUE *argv, VALUE self)
|
1664
|
+
{
|
1665
|
+
pdlc_complex_buffer_t *mcbuf;
|
1666
|
+
VALUE digits;
|
1667
|
+
int d;
|
1668
|
+
|
1669
|
+
rb_scan_args(argc, argv, "01", &digits);
|
1670
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1671
|
+
|
1672
|
+
if (digits == Qnil)
|
1673
|
+
pdlc_complex_buffer_round_inplace(mcbuf);
|
1674
|
+
else {
|
1675
|
+
d = NUM2INT(digits);
|
1676
|
+
pdlc_complex_buffer_round_digits_inplace(mcbuf, d);
|
1677
|
+
}
|
1678
|
+
|
1679
|
+
return self;
|
1680
|
+
}
|
1681
|
+
|
1682
|
+
|
1683
|
+
/* Returns the absolute value / the absolute part of its polar form.
|
1684
|
+
* @overload abs(buffer = nil)
|
1685
|
+
* @param buffer [nil, PaddleC::FloatBuffer] if provided, the result is written into +buffer+.
|
1686
|
+
* @return [PaddleC::FloatBuffer]
|
1687
|
+
*/
|
1688
|
+
static VALUE paddlec_complex_buffer_abs(int argc, VALUE *argv, VALUE self)
|
1689
|
+
{
|
1690
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1691
|
+
pdlc_buffer_t *rfbuf;
|
1692
|
+
VALUE buffer;
|
1693
|
+
|
1694
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1695
|
+
|
1696
|
+
rb_scan_args(argc, argv, "01", &buffer);
|
1697
|
+
|
1698
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_FloatBuffer)) {
|
1699
|
+
rb_warn("expecting a %"PRIsVALUE" as buffer, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(buffer)));
|
1700
|
+
buffer = Qnil;
|
1701
|
+
}
|
1702
|
+
if (buffer == Qnil)
|
1703
|
+
buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
1704
|
+
rfbuf = paddlec_float_buffer_get_struct(buffer);
|
1705
|
+
|
1706
|
+
pdlc_complex_buffer_abs(mcbuf, rfbuf);
|
1707
|
+
|
1708
|
+
return buffer;
|
1709
|
+
}
|
1710
|
+
|
1711
|
+
|
1712
|
+
/* Returns the square of the absolute value / the square of the absolute part of its polar form.
|
1713
|
+
* @overload abs2(buffer = nil)
|
1714
|
+
* @param buffer [nil, PaddleC::FloatBuffer] if provided, the result is written into +buffer+.
|
1715
|
+
* @return [PaddleC::FloatBuffer]
|
1716
|
+
*/
|
1717
|
+
static VALUE paddlec_complex_buffer_abs2(int argc, VALUE *argv, VALUE self)
|
1718
|
+
{
|
1719
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1720
|
+
pdlc_buffer_t *rfbuf;
|
1721
|
+
VALUE buffer;
|
1722
|
+
|
1723
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1724
|
+
|
1725
|
+
rb_scan_args(argc, argv, "01", &buffer);
|
1726
|
+
|
1727
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_FloatBuffer)) {
|
1728
|
+
rb_warn("expecting a %"PRIsVALUE" as buffer, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(buffer)));
|
1729
|
+
buffer = Qnil;
|
1730
|
+
}
|
1731
|
+
if (buffer == Qnil)
|
1732
|
+
buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
1733
|
+
rfbuf = paddlec_float_buffer_get_struct(buffer);
|
1734
|
+
|
1735
|
+
pdlc_complex_buffer_abs2(mcbuf, rfbuf);
|
1736
|
+
|
1737
|
+
return buffer;
|
1738
|
+
}
|
1739
|
+
|
1740
|
+
|
1741
|
+
/* Returns the angle part of its polar form.
|
1742
|
+
* @overload arg(buffer = nil)
|
1743
|
+
* @param buffer [nil, PaddleC::FloatBuffer] if provided, the result is written into +buffer+.
|
1744
|
+
* @return [PaddleC::FloatBuffer]
|
1745
|
+
*/
|
1746
|
+
static VALUE paddlec_complex_buffer_arg(int argc, VALUE *argv, VALUE self)
|
1747
|
+
{
|
1748
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1749
|
+
pdlc_buffer_t *rfbuf;
|
1750
|
+
VALUE buffer;
|
1751
|
+
|
1752
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1753
|
+
|
1754
|
+
rb_scan_args(argc, argv, "01", &buffer);
|
1755
|
+
|
1756
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_FloatBuffer)) {
|
1757
|
+
rb_warn("expecting a %"PRIsVALUE" as buffer, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(buffer)));
|
1758
|
+
buffer = Qnil;
|
1759
|
+
}
|
1760
|
+
if (buffer == Qnil)
|
1761
|
+
buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
1762
|
+
rfbuf = paddlec_float_buffer_get_struct(buffer);
|
1763
|
+
|
1764
|
+
pdlc_complex_buffer_arg(mcbuf, rfbuf);
|
1765
|
+
|
1766
|
+
return buffer;
|
1767
|
+
}
|
1768
|
+
|
1769
|
+
|
1770
|
+
/* Returns the complex conjugate.
|
1771
|
+
* @overload conjugate(buffer = nil)
|
1772
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if provided, the result is written into +buffer+.
|
1773
|
+
* @return [PaddleC::ComplexBuffer]
|
1774
|
+
*/
|
1775
|
+
static VALUE paddlec_complex_buffer_conjugate(int argc, VALUE *argv, VALUE self)
|
1776
|
+
{
|
1777
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1778
|
+
pdlc_complex_buffer_t *rcbuf;
|
1779
|
+
VALUE buffer;
|
1780
|
+
|
1781
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1782
|
+
|
1783
|
+
rb_scan_args(argc, argv, "01", &buffer);
|
1784
|
+
|
1785
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
1786
|
+
rb_warn("expecting a %"PRIsVALUE" as buffer, not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
1787
|
+
buffer = Qnil;
|
1788
|
+
}
|
1789
|
+
if (buffer == Qnil)
|
1790
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
1791
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
1792
|
+
|
1793
|
+
pdlc_complex_buffer_conjugate(mcbuf, rcbuf);
|
1794
|
+
|
1795
|
+
return buffer;
|
1796
|
+
}
|
1797
|
+
|
1798
|
+
|
1799
|
+
/* Returns the complex conjugate.
|
1800
|
+
* @return [self]
|
1801
|
+
*/
|
1802
|
+
static VALUE paddlec_complex_buffer_conjugate_inplace(VALUE self)
|
1803
|
+
{
|
1804
|
+
pdlc_complex_buffer_t *mcbuf;
|
1805
|
+
|
1806
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1807
|
+
|
1808
|
+
pdlc_complex_buffer_conjugate_inplace(mcbuf);
|
1809
|
+
|
1810
|
+
return self;
|
1811
|
+
}
|
1812
|
+
|
1813
|
+
|
1814
|
+
/* Returns the imaginary part.
|
1815
|
+
* @overload imaginary(buffer = nil)
|
1816
|
+
* @param buffer [nil, PaddleC::FloatBuffer] if provided, the result is written into +buffer+.
|
1817
|
+
* @return [PaddleC::FloatBuffer]
|
1818
|
+
*/
|
1819
|
+
static VALUE paddlec_complex_buffer_imag(int argc, VALUE *argv, VALUE self)
|
1820
|
+
{
|
1821
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1822
|
+
pdlc_buffer_t *rfbuf;
|
1823
|
+
VALUE buffer;
|
1824
|
+
|
1825
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1826
|
+
|
1827
|
+
rb_scan_args(argc, argv, "01", &buffer);
|
1828
|
+
|
1829
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_FloatBuffer)) {
|
1830
|
+
rb_warn("expecting a %"PRIsVALUE" as buffer, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(buffer)));
|
1831
|
+
buffer = Qnil;
|
1832
|
+
}
|
1833
|
+
if (buffer == Qnil)
|
1834
|
+
buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
1835
|
+
rfbuf = paddlec_float_buffer_get_struct(buffer);
|
1836
|
+
|
1837
|
+
pdlc_complex_buffer_imag(mcbuf, rfbuf);
|
1838
|
+
|
1839
|
+
return buffer;
|
1840
|
+
}
|
1841
|
+
|
1842
|
+
|
1843
|
+
/* Returns the real part.
|
1844
|
+
* @overload real(buffer = nil)
|
1845
|
+
* @param buffer [nil, PaddleC::FloatBuffer] if provided, the result is written into +buffer+.
|
1846
|
+
* @return [PaddleC::FloatBuffer]
|
1847
|
+
*/
|
1848
|
+
static VALUE paddlec_complex_buffer_real(int argc, VALUE *argv, VALUE self)
|
1849
|
+
{
|
1850
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1851
|
+
pdlc_buffer_t *rfbuf;
|
1852
|
+
VALUE buffer;
|
1853
|
+
|
1854
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1855
|
+
|
1856
|
+
rb_scan_args(argc, argv, "01", &buffer);
|
1857
|
+
|
1858
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_FloatBuffer)) {
|
1859
|
+
rb_warn("expecting a %"PRIsVALUE" as buffer, not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_class_of(buffer)));
|
1860
|
+
buffer = Qnil;
|
1861
|
+
}
|
1862
|
+
if (buffer == Qnil)
|
1863
|
+
buffer = rb_class_new_instance(0, NULL, c_FloatBuffer);
|
1864
|
+
rfbuf = paddlec_float_buffer_get_struct(buffer);
|
1865
|
+
|
1866
|
+
pdlc_complex_buffer_real(mcbuf, rfbuf);
|
1867
|
+
|
1868
|
+
return buffer;
|
1869
|
+
}
|
1870
|
+
|
1871
|
+
|
1872
|
+
/* Swap the real and imaginary parts.
|
1873
|
+
* @overload swapIQ(buffer = nil)
|
1874
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if provided, the result is written into +buffer+.
|
1875
|
+
* @return [PaddleC::ComplexBuffer]
|
1876
|
+
*/
|
1877
|
+
static VALUE paddlec_complex_buffer_swapIQ(int argc, VALUE *argv, VALUE self)
|
1878
|
+
{
|
1879
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1880
|
+
pdlc_complex_buffer_t *rcbuf;
|
1881
|
+
VALUE buffer;
|
1882
|
+
|
1883
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1884
|
+
|
1885
|
+
rb_scan_args(argc, argv, "01", &buffer);
|
1886
|
+
|
1887
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
1888
|
+
rb_warn("expecting a %"PRIsVALUE" as buffer, not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
1889
|
+
buffer = Qnil;
|
1890
|
+
}
|
1891
|
+
if (buffer == Qnil)
|
1892
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
1893
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
1894
|
+
|
1895
|
+
pdlc_complex_buffer_swapIQ(mcbuf, rcbuf);
|
1896
|
+
|
1897
|
+
return buffer;
|
1898
|
+
}
|
1899
|
+
|
1900
|
+
|
1901
|
+
/* Swap the real and imaginary parts.
|
1902
|
+
* @return [self]
|
1903
|
+
*/
|
1904
|
+
static VALUE paddlec_complex_buffer_swapIQ_inplace(VALUE self)
|
1905
|
+
{
|
1906
|
+
pdlc_complex_buffer_t *mcbuf;
|
1907
|
+
|
1908
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1909
|
+
|
1910
|
+
pdlc_complex_buffer_swapIQ_inplace(mcbuf);
|
1911
|
+
|
1912
|
+
return self;
|
1913
|
+
}
|
1914
|
+
|
1915
|
+
|
1916
|
+
/* Unary minus, returns the receiver, negated.
|
1917
|
+
* @overload -@(buffer = nil)
|
1918
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if provided, the result is written into +buffer+.
|
1919
|
+
* @return [PaddleC::ComplexBuffer]
|
1920
|
+
*/
|
1921
|
+
static VALUE paddlec_complex_buffer_unaryminus(int argc, VALUE *argv, VALUE self)
|
1922
|
+
{
|
1923
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1924
|
+
pdlc_complex_buffer_t *rcbuf;
|
1925
|
+
VALUE buffer;
|
1926
|
+
|
1927
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1928
|
+
|
1929
|
+
rb_scan_args(argc, argv, "01", &buffer);
|
1930
|
+
|
1931
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
1932
|
+
rb_warn("expecting a %"PRIsVALUE" as buffer, not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
1933
|
+
buffer = Qnil;
|
1934
|
+
}
|
1935
|
+
if (buffer == Qnil)
|
1936
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
1937
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
1938
|
+
|
1939
|
+
pdlc_complex_buffer_unaryminus(mcbuf, rcbuf);
|
1940
|
+
|
1941
|
+
return buffer;
|
1942
|
+
}
|
1943
|
+
|
1944
|
+
|
1945
|
+
/* Unary minus, returns the receiver, negated.
|
1946
|
+
* @return [self]
|
1947
|
+
*/
|
1948
|
+
static VALUE paddlec_complex_buffer_unaryminus_inplace(VALUE self)
|
1949
|
+
{
|
1950
|
+
pdlc_complex_buffer_t *mcbuf;
|
1951
|
+
|
1952
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1953
|
+
|
1954
|
+
pdlc_complex_buffer_unaryminus_inplace(mcbuf);
|
1955
|
+
|
1956
|
+
return self;
|
1957
|
+
}
|
1958
|
+
|
1959
|
+
|
1960
|
+
/* @return [PaddleC::ComplexBuffer]
|
1961
|
+
* @overload -(other, buffer = nil)
|
1962
|
+
* @param other [PaddleC::ComplexBuffer, Complex, PaddleC::FloatBuffer, Numeric]
|
1963
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if a {ComplexBuffer} is provided, it is filled with the output
|
1964
|
+
* @return [PaddleC::ComplexBuffer]
|
1965
|
+
*/
|
1966
|
+
static VALUE paddlec_complex_buffer_sub(int argc, VALUE *argv, VALUE self)
|
1967
|
+
{
|
1968
|
+
const pdlc_complex_buffer_t *mcbuf;
|
1969
|
+
pdlc_complex_buffer_t *rcbuf;
|
1970
|
+
const pdlc_complex_buffer_t *ocbuf;
|
1971
|
+
pdlc_complex_t oc;
|
1972
|
+
const pdlc_buffer_t *ofbuf;
|
1973
|
+
float of;
|
1974
|
+
VALUE other, buffer;
|
1975
|
+
|
1976
|
+
rb_scan_args(argc, argv, "11", &other, &buffer);
|
1977
|
+
|
1978
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
1979
|
+
|
1980
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer) || rb_obj_is_kind_of(other, rb_cComplex) || rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
1981
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
1982
|
+
rb_warn("second argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
1983
|
+
buffer = Qnil;
|
1984
|
+
}
|
1985
|
+
if (buffer == Qnil)
|
1986
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
1987
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
1988
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
1989
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
1990
|
+
pdlc_cb_cb_sub(mcbuf, ocbuf, rcbuf);
|
1991
|
+
}
|
1992
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
1993
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
1994
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
1995
|
+
pdlc_cb_cs_sub(mcbuf, oc, rcbuf);
|
1996
|
+
}
|
1997
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
1998
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
1999
|
+
pdlc_cb_fb_sub(mcbuf, ofbuf, rcbuf);
|
2000
|
+
}
|
2001
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2002
|
+
of = (float)NUM2DBL(other);
|
2003
|
+
pdlc_cb_fs_sub(mcbuf, of, rcbuf);
|
2004
|
+
}
|
2005
|
+
}
|
2006
|
+
else
|
2007
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2008
|
+
|
2009
|
+
return buffer;
|
2010
|
+
}
|
2011
|
+
|
2012
|
+
|
2013
|
+
/* @param other [c_ComplexBuffer, rb_cComplex, c_FloatBuffer, rb_cNumeric]
|
2014
|
+
* @return [self]
|
2015
|
+
*/
|
2016
|
+
static VALUE paddlec_complex_buffer_sub_inplace(VALUE self, VALUE other)
|
2017
|
+
{
|
2018
|
+
pdlc_complex_buffer_t *mcbuf;
|
2019
|
+
const pdlc_buffer_t *ofbuf;
|
2020
|
+
float of;
|
2021
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2022
|
+
pdlc_complex_t oc;
|
2023
|
+
|
2024
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2025
|
+
|
2026
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2027
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2028
|
+
pdlc_cb_cb_sub_inplace(mcbuf, ocbuf);
|
2029
|
+
}
|
2030
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2031
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2032
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2033
|
+
pdlc_cb_cs_sub_inplace(mcbuf, oc);
|
2034
|
+
}
|
2035
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2036
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2037
|
+
pdlc_cb_fb_sub_inplace(mcbuf, ofbuf);
|
2038
|
+
}
|
2039
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2040
|
+
of = (float)NUM2DBL(other);
|
2041
|
+
pdlc_cb_fs_sub_inplace(mcbuf, of);
|
2042
|
+
}
|
2043
|
+
else
|
2044
|
+
rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2045
|
+
|
2046
|
+
return self;
|
2047
|
+
}
|
2048
|
+
|
2049
|
+
|
2050
|
+
/* Element by element soustraction.
|
2051
|
+
* @return [PaddleC::ComplexBuffer]
|
2052
|
+
* @overload esub(other, buffer = nil)
|
2053
|
+
* @param other [PaddleC::ComplexBuffer, Complex, PaddleC::FloatBuffer, Numeric]
|
2054
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if a {ComplexBuffer} is provided, it is filled with the output
|
2055
|
+
* @return [PaddleC::ComplexBuffer]
|
2056
|
+
*/
|
2057
|
+
static VALUE paddlec_complex_buffer_esub(int argc, VALUE *argv, VALUE self)
|
2058
|
+
{
|
2059
|
+
const pdlc_complex_buffer_t *mcbuf;
|
2060
|
+
pdlc_complex_buffer_t *rcbuf;
|
2061
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2062
|
+
pdlc_complex_t oc;
|
2063
|
+
const pdlc_buffer_t *ofbuf;
|
2064
|
+
float of;
|
2065
|
+
VALUE other, buffer;
|
2066
|
+
|
2067
|
+
rb_scan_args(argc, argv, "11", &other, &buffer);
|
2068
|
+
|
2069
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2070
|
+
|
2071
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer) || rb_obj_is_kind_of(other, rb_cComplex) || rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2072
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
2073
|
+
rb_warn("second argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
2074
|
+
buffer = Qnil;
|
2075
|
+
}
|
2076
|
+
if (buffer == Qnil)
|
2077
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
2078
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
2079
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2080
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2081
|
+
pdlc_cb_cb_esub(mcbuf, ocbuf, rcbuf);
|
2082
|
+
}
|
2083
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2084
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2085
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2086
|
+
pdlc_cb_cs_esub(mcbuf, oc, rcbuf);
|
2087
|
+
}
|
2088
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2089
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2090
|
+
pdlc_cb_fb_esub(mcbuf, ofbuf, rcbuf);
|
2091
|
+
}
|
2092
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2093
|
+
of = (float)NUM2DBL(other);
|
2094
|
+
pdlc_cb_fs_esub(mcbuf, of, rcbuf);
|
2095
|
+
}
|
2096
|
+
}
|
2097
|
+
else
|
2098
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2099
|
+
|
2100
|
+
return buffer;
|
2101
|
+
}
|
2102
|
+
|
2103
|
+
|
2104
|
+
/* Element by element soustraction.
|
2105
|
+
* @param other [c_ComplexBuffer, rb_cComplex, c_FloatBuffer, rb_cNumeric]
|
2106
|
+
* @return [self]
|
2107
|
+
*/
|
2108
|
+
static VALUE paddlec_complex_buffer_esub_inplace(VALUE self, VALUE other)
|
2109
|
+
{
|
2110
|
+
pdlc_complex_buffer_t *mcbuf;
|
2111
|
+
const pdlc_buffer_t *ofbuf;
|
2112
|
+
float of;
|
2113
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2114
|
+
pdlc_complex_t oc;
|
2115
|
+
|
2116
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2117
|
+
|
2118
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2119
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2120
|
+
pdlc_cb_cb_esub_inplace(mcbuf, ocbuf);
|
2121
|
+
}
|
2122
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2123
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2124
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2125
|
+
pdlc_cb_cs_esub_inplace(mcbuf, oc);
|
2126
|
+
}
|
2127
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2128
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2129
|
+
pdlc_cb_fb_esub_inplace(mcbuf, ofbuf);
|
2130
|
+
}
|
2131
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2132
|
+
of = (float)NUM2DBL(other);
|
2133
|
+
pdlc_cb_fs_esub_inplace(mcbuf, of);
|
2134
|
+
}
|
2135
|
+
else
|
2136
|
+
rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2137
|
+
|
2138
|
+
return self;
|
2139
|
+
}
|
2140
|
+
|
2141
|
+
|
2142
|
+
/* @return [PaddleC::ComplexBuffer]
|
2143
|
+
* @overload +(other, buffer = nil)
|
2144
|
+
* @param other [PaddleC::ComplexBuffer, Complex, PaddleC::FloatBuffer, Numeric]
|
2145
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if a {ComplexBuffer} is provided, it is filled with the output
|
2146
|
+
* @return [PaddleC::ComplexBuffer]
|
2147
|
+
*/
|
2148
|
+
static VALUE paddlec_complex_buffer_add(int argc, VALUE *argv, VALUE self)
|
2149
|
+
{
|
2150
|
+
const pdlc_complex_buffer_t *mcbuf;
|
2151
|
+
pdlc_complex_buffer_t *rcbuf;
|
2152
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2153
|
+
pdlc_complex_t oc;
|
2154
|
+
const pdlc_buffer_t *ofbuf;
|
2155
|
+
float of;
|
2156
|
+
VALUE other, buffer;
|
2157
|
+
|
2158
|
+
rb_scan_args(argc, argv, "11", &other, &buffer);
|
2159
|
+
|
2160
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2161
|
+
|
2162
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer) || rb_obj_is_kind_of(other, rb_cComplex) || rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2163
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
2164
|
+
rb_warn("second argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
2165
|
+
buffer = Qnil;
|
2166
|
+
}
|
2167
|
+
if (buffer == Qnil)
|
2168
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
2169
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
2170
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2171
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2172
|
+
pdlc_cb_cb_add(mcbuf, ocbuf, rcbuf);
|
2173
|
+
}
|
2174
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2175
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2176
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2177
|
+
pdlc_cb_cs_add(mcbuf, oc, rcbuf);
|
2178
|
+
}
|
2179
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2180
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2181
|
+
pdlc_cb_fb_add(mcbuf, ofbuf, rcbuf);
|
2182
|
+
}
|
2183
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2184
|
+
of = (float)NUM2DBL(other);
|
2185
|
+
pdlc_cb_fs_add(mcbuf, of, rcbuf);
|
2186
|
+
}
|
2187
|
+
}
|
2188
|
+
else
|
2189
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2190
|
+
|
2191
|
+
return buffer;
|
2192
|
+
}
|
2193
|
+
|
2194
|
+
|
2195
|
+
/* @param other [c_ComplexBuffer, rb_cComplex, c_FloatBuffer, rb_cNumeric]
|
2196
|
+
* @return [self]
|
2197
|
+
*/
|
2198
|
+
static VALUE paddlec_complex_buffer_add_inplace(VALUE self, VALUE other)
|
2199
|
+
{
|
2200
|
+
pdlc_complex_buffer_t *mcbuf;
|
2201
|
+
const pdlc_buffer_t *ofbuf;
|
2202
|
+
float of;
|
2203
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2204
|
+
pdlc_complex_t oc;
|
2205
|
+
|
2206
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2207
|
+
|
2208
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2209
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2210
|
+
pdlc_cb_cb_add_inplace(mcbuf, ocbuf);
|
2211
|
+
}
|
2212
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2213
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2214
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2215
|
+
pdlc_cb_cs_add_inplace(mcbuf, oc);
|
2216
|
+
}
|
2217
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2218
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2219
|
+
pdlc_cb_fb_add_inplace(mcbuf, ofbuf);
|
2220
|
+
}
|
2221
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2222
|
+
of = (float)NUM2DBL(other);
|
2223
|
+
pdlc_cb_fs_add_inplace(mcbuf, of);
|
2224
|
+
}
|
2225
|
+
else
|
2226
|
+
rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2227
|
+
|
2228
|
+
return self;
|
2229
|
+
}
|
2230
|
+
|
2231
|
+
|
2232
|
+
/* Element by element addition.
|
2233
|
+
* @return [PaddleC::ComplexBuffer]
|
2234
|
+
* @overload eadd(other, buffer = nil)
|
2235
|
+
* @param other [PaddleC::ComplexBuffer, Complex, PaddleC::FloatBuffer, Numeric]
|
2236
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if a {ComplexBuffer} is provided, it is filled with the output
|
2237
|
+
* @return [PaddleC::ComplexBuffer]
|
2238
|
+
*/
|
2239
|
+
static VALUE paddlec_complex_buffer_eadd(int argc, VALUE *argv, VALUE self)
|
2240
|
+
{
|
2241
|
+
const pdlc_complex_buffer_t *mcbuf;
|
2242
|
+
pdlc_complex_buffer_t *rcbuf;
|
2243
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2244
|
+
pdlc_complex_t oc;
|
2245
|
+
const pdlc_buffer_t *ofbuf;
|
2246
|
+
float of;
|
2247
|
+
VALUE other, buffer;
|
2248
|
+
|
2249
|
+
rb_scan_args(argc, argv, "11", &other, &buffer);
|
2250
|
+
|
2251
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2252
|
+
|
2253
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer) || rb_obj_is_kind_of(other, rb_cComplex) || rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2254
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
2255
|
+
rb_warn("second argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
2256
|
+
buffer = Qnil;
|
2257
|
+
}
|
2258
|
+
if (buffer == Qnil)
|
2259
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
2260
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
2261
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2262
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2263
|
+
pdlc_cb_cb_eadd(mcbuf, ocbuf, rcbuf);
|
2264
|
+
}
|
2265
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2266
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2267
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2268
|
+
pdlc_cb_cs_eadd(mcbuf, oc, rcbuf);
|
2269
|
+
}
|
2270
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2271
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2272
|
+
pdlc_cb_fb_eadd(mcbuf, ofbuf, rcbuf);
|
2273
|
+
}
|
2274
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2275
|
+
of = (float)NUM2DBL(other);
|
2276
|
+
pdlc_cb_fs_eadd(mcbuf, of, rcbuf);
|
2277
|
+
}
|
2278
|
+
}
|
2279
|
+
else
|
2280
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2281
|
+
|
2282
|
+
return buffer;
|
2283
|
+
}
|
2284
|
+
|
2285
|
+
|
2286
|
+
/* Element by element addition.
|
2287
|
+
* @param other [c_ComplexBuffer, rb_cComplex, c_FloatBuffer, rb_cNumeric]
|
2288
|
+
* @return [self]
|
2289
|
+
*/
|
2290
|
+
static VALUE paddlec_complex_buffer_eadd_inplace(VALUE self, VALUE other)
|
2291
|
+
{
|
2292
|
+
pdlc_complex_buffer_t *mcbuf;
|
2293
|
+
const pdlc_buffer_t *ofbuf;
|
2294
|
+
float of;
|
2295
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2296
|
+
pdlc_complex_t oc;
|
2297
|
+
|
2298
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2299
|
+
|
2300
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2301
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2302
|
+
pdlc_cb_cb_eadd_inplace(mcbuf, ocbuf);
|
2303
|
+
}
|
2304
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2305
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2306
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2307
|
+
pdlc_cb_cs_eadd_inplace(mcbuf, oc);
|
2308
|
+
}
|
2309
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2310
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2311
|
+
pdlc_cb_fb_eadd_inplace(mcbuf, ofbuf);
|
2312
|
+
}
|
2313
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2314
|
+
of = (float)NUM2DBL(other);
|
2315
|
+
pdlc_cb_fs_eadd_inplace(mcbuf, of);
|
2316
|
+
}
|
2317
|
+
else
|
2318
|
+
rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2319
|
+
|
2320
|
+
return self;
|
2321
|
+
}
|
2322
|
+
|
2323
|
+
|
2324
|
+
/* Performs multiplication.
|
2325
|
+
* @return [PaddleC::ComplexBuffer]
|
2326
|
+
* @overload *(other, buffer = nil)
|
2327
|
+
* @param other [PaddleC::ComplexBuffer, Complex, PaddleC::FloatBuffer, Numeric]
|
2328
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if a {ComplexBuffer} is provided, it is filled with the output
|
2329
|
+
* @return [PaddleC::ComplexBuffer]
|
2330
|
+
*/
|
2331
|
+
static VALUE paddlec_complex_buffer_mult(int argc, VALUE *argv, VALUE self)
|
2332
|
+
{
|
2333
|
+
const pdlc_complex_buffer_t *mcbuf;
|
2334
|
+
pdlc_complex_buffer_t *rcbuf;
|
2335
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2336
|
+
pdlc_complex_t oc;
|
2337
|
+
const pdlc_buffer_t *ofbuf;
|
2338
|
+
float of;
|
2339
|
+
VALUE other, buffer;
|
2340
|
+
|
2341
|
+
rb_scan_args(argc, argv, "11", &other, &buffer);
|
2342
|
+
|
2343
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2344
|
+
|
2345
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer) || rb_obj_is_kind_of(other, rb_cComplex) || rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2346
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
2347
|
+
rb_warn("second argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
2348
|
+
buffer = Qnil;
|
2349
|
+
}
|
2350
|
+
if (buffer == Qnil)
|
2351
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
2352
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
2353
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2354
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2355
|
+
pdlc_cb_cb_mult(mcbuf, ocbuf, rcbuf);
|
2356
|
+
}
|
2357
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2358
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2359
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2360
|
+
pdlc_cb_cs_mult(mcbuf, oc, rcbuf);
|
2361
|
+
}
|
2362
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2363
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2364
|
+
pdlc_cb_fb_mult(mcbuf, ofbuf, rcbuf);
|
2365
|
+
}
|
2366
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2367
|
+
of = (float)NUM2DBL(other);
|
2368
|
+
pdlc_cb_fs_mult(mcbuf, of, rcbuf);
|
2369
|
+
}
|
2370
|
+
}
|
2371
|
+
else
|
2372
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2373
|
+
|
2374
|
+
return buffer;
|
2375
|
+
}
|
2376
|
+
|
2377
|
+
|
2378
|
+
/* Performs multiplication.
|
2379
|
+
* @param other [c_ComplexBuffer, rb_cComplex, c_FloatBuffer, rb_cNumeric]
|
2380
|
+
* @return [self]
|
2381
|
+
*/
|
2382
|
+
static VALUE paddlec_complex_buffer_mult_inplace(VALUE self, VALUE other)
|
2383
|
+
{
|
2384
|
+
pdlc_complex_buffer_t *mcbuf;
|
2385
|
+
const pdlc_buffer_t *ofbuf;
|
2386
|
+
float of;
|
2387
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2388
|
+
pdlc_complex_t oc;
|
2389
|
+
|
2390
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2391
|
+
|
2392
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2393
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2394
|
+
pdlc_cb_cb_mult_inplace(mcbuf, ocbuf);
|
2395
|
+
}
|
2396
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2397
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2398
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2399
|
+
pdlc_cb_cs_mult_inplace(mcbuf, oc);
|
2400
|
+
}
|
2401
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2402
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2403
|
+
pdlc_cb_fb_mult_inplace(mcbuf, ofbuf);
|
2404
|
+
}
|
2405
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2406
|
+
of = (float)NUM2DBL(other);
|
2407
|
+
pdlc_cb_fs_mult_inplace(mcbuf, of);
|
2408
|
+
}
|
2409
|
+
else
|
2410
|
+
rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2411
|
+
|
2412
|
+
return self;
|
2413
|
+
}
|
2414
|
+
|
2415
|
+
|
2416
|
+
/* Element by element multiplication.
|
2417
|
+
* @return [PaddleC::ComplexBuffer]
|
2418
|
+
* @overload emult(other, buffer = nil)
|
2419
|
+
* @param other [PaddleC::ComplexBuffer, Complex, PaddleC::FloatBuffer, Numeric]
|
2420
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if a {ComplexBuffer} is provided, it is filled with the output
|
2421
|
+
* @return [PaddleC::ComplexBuffer]
|
2422
|
+
*/
|
2423
|
+
static VALUE paddlec_complex_buffer_emult(int argc, VALUE *argv, VALUE self)
|
2424
|
+
{
|
2425
|
+
const pdlc_complex_buffer_t *mcbuf;
|
2426
|
+
pdlc_complex_buffer_t *rcbuf;
|
2427
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2428
|
+
pdlc_complex_t oc;
|
2429
|
+
const pdlc_buffer_t *ofbuf;
|
2430
|
+
float of;
|
2431
|
+
VALUE other, buffer;
|
2432
|
+
|
2433
|
+
rb_scan_args(argc, argv, "11", &other, &buffer);
|
2434
|
+
|
2435
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2436
|
+
|
2437
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer) || rb_obj_is_kind_of(other, rb_cComplex) || rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2438
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
2439
|
+
rb_warn("second argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
2440
|
+
buffer = Qnil;
|
2441
|
+
}
|
2442
|
+
if (buffer == Qnil)
|
2443
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
2444
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
2445
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2446
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2447
|
+
pdlc_cb_cb_emult(mcbuf, ocbuf, rcbuf);
|
2448
|
+
}
|
2449
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2450
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2451
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2452
|
+
pdlc_cb_cs_emult(mcbuf, oc, rcbuf);
|
2453
|
+
}
|
2454
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2455
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2456
|
+
pdlc_cb_fb_emult(mcbuf, ofbuf, rcbuf);
|
2457
|
+
}
|
2458
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2459
|
+
of = (float)NUM2DBL(other);
|
2460
|
+
pdlc_cb_fs_emult(mcbuf, of, rcbuf);
|
2461
|
+
}
|
2462
|
+
}
|
2463
|
+
else
|
2464
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2465
|
+
|
2466
|
+
return buffer;
|
2467
|
+
}
|
2468
|
+
|
2469
|
+
|
2470
|
+
/* Element by element multiplication.
|
2471
|
+
* @param other [c_ComplexBuffer, rb_cComplex, c_FloatBuffer, rb_cNumeric]
|
2472
|
+
* @return [self]
|
2473
|
+
*/
|
2474
|
+
static VALUE paddlec_complex_buffer_emult_inplace(VALUE self, VALUE other)
|
2475
|
+
{
|
2476
|
+
pdlc_complex_buffer_t *mcbuf;
|
2477
|
+
const pdlc_buffer_t *ofbuf;
|
2478
|
+
float of;
|
2479
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2480
|
+
pdlc_complex_t oc;
|
2481
|
+
|
2482
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2483
|
+
|
2484
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2485
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2486
|
+
pdlc_cb_cb_emult_inplace(mcbuf, ocbuf);
|
2487
|
+
}
|
2488
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2489
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2490
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2491
|
+
pdlc_cb_cs_emult_inplace(mcbuf, oc);
|
2492
|
+
}
|
2493
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2494
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2495
|
+
pdlc_cb_fb_emult_inplace(mcbuf, ofbuf);
|
2496
|
+
}
|
2497
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2498
|
+
of = (float)NUM2DBL(other);
|
2499
|
+
pdlc_cb_fs_emult_inplace(mcbuf, of);
|
2500
|
+
}
|
2501
|
+
else
|
2502
|
+
rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2503
|
+
|
2504
|
+
return self;
|
2505
|
+
}
|
2506
|
+
|
2507
|
+
|
2508
|
+
/* Performs division.
|
2509
|
+
* @return [PaddleC::ComplexBuffer]
|
2510
|
+
* @overload /(other, buffer = nil)
|
2511
|
+
* @param other [PaddleC::ComplexBuffer, Complex, PaddleC::FloatBuffer, Numeric]
|
2512
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if a {ComplexBuffer} is provided, it is filled with the output
|
2513
|
+
* @return [PaddleC::ComplexBuffer]
|
2514
|
+
*/
|
2515
|
+
static VALUE paddlec_complex_buffer_div(int argc, VALUE *argv, VALUE self)
|
2516
|
+
{
|
2517
|
+
const pdlc_complex_buffer_t *mcbuf;
|
2518
|
+
pdlc_complex_buffer_t *rcbuf;
|
2519
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2520
|
+
pdlc_complex_t oc;
|
2521
|
+
const pdlc_buffer_t *ofbuf;
|
2522
|
+
float of;
|
2523
|
+
VALUE other, buffer;
|
2524
|
+
|
2525
|
+
rb_scan_args(argc, argv, "11", &other, &buffer);
|
2526
|
+
|
2527
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2528
|
+
|
2529
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer) || rb_obj_is_kind_of(other, rb_cComplex) || rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2530
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
2531
|
+
rb_warn("second argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
2532
|
+
buffer = Qnil;
|
2533
|
+
}
|
2534
|
+
if (buffer == Qnil)
|
2535
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
2536
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
2537
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2538
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2539
|
+
pdlc_cb_cb_div(mcbuf, ocbuf, rcbuf);
|
2540
|
+
}
|
2541
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2542
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2543
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2544
|
+
pdlc_cb_cs_div(mcbuf, oc, rcbuf);
|
2545
|
+
}
|
2546
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2547
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2548
|
+
pdlc_cb_fb_div(mcbuf, ofbuf, rcbuf);
|
2549
|
+
}
|
2550
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2551
|
+
of = (float)NUM2DBL(other);
|
2552
|
+
pdlc_cb_fs_div(mcbuf, of, rcbuf);
|
2553
|
+
}
|
2554
|
+
}
|
2555
|
+
else
|
2556
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2557
|
+
|
2558
|
+
return buffer;
|
2559
|
+
}
|
2560
|
+
|
2561
|
+
|
2562
|
+
/* Performs division.
|
2563
|
+
* @param other [c_ComplexBuffer, rb_cComplex, c_FloatBuffer, rb_cNumeric]
|
2564
|
+
* @return [self]
|
2565
|
+
*/
|
2566
|
+
static VALUE paddlec_complex_buffer_div_inplace(VALUE self, VALUE other)
|
2567
|
+
{
|
2568
|
+
pdlc_complex_buffer_t *mcbuf;
|
2569
|
+
const pdlc_buffer_t *ofbuf;
|
2570
|
+
float of;
|
2571
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2572
|
+
pdlc_complex_t oc;
|
2573
|
+
|
2574
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2575
|
+
|
2576
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2577
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2578
|
+
pdlc_cb_cb_div_inplace(mcbuf, ocbuf);
|
2579
|
+
}
|
2580
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2581
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2582
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2583
|
+
pdlc_cb_cs_div_inplace(mcbuf, oc);
|
2584
|
+
}
|
2585
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2586
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2587
|
+
pdlc_cb_fb_div_inplace(mcbuf, ofbuf);
|
2588
|
+
}
|
2589
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2590
|
+
of = (float)NUM2DBL(other);
|
2591
|
+
pdlc_cb_fs_div_inplace(mcbuf, of);
|
2592
|
+
}
|
2593
|
+
else
|
2594
|
+
rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2595
|
+
|
2596
|
+
return self;
|
2597
|
+
}
|
2598
|
+
|
2599
|
+
|
2600
|
+
/* Element by element division.
|
2601
|
+
* @return [PaddleC::ComplexBuffer]
|
2602
|
+
* @overload ediv(other, buffer = nil)
|
2603
|
+
* @param other [PaddleC::ComplexBuffer, Complex, PaddleC::FloatBuffer, Numeric]
|
2604
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if a {ComplexBuffer} is provided, it is filled with the output
|
2605
|
+
* @return [PaddleC::ComplexBuffer]
|
2606
|
+
*/
|
2607
|
+
static VALUE paddlec_complex_buffer_ediv(int argc, VALUE *argv, VALUE self)
|
2608
|
+
{
|
2609
|
+
const pdlc_complex_buffer_t *mcbuf;
|
2610
|
+
pdlc_complex_buffer_t *rcbuf;
|
2611
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2612
|
+
pdlc_complex_t oc;
|
2613
|
+
const pdlc_buffer_t *ofbuf;
|
2614
|
+
float of;
|
2615
|
+
VALUE other, buffer;
|
2616
|
+
|
2617
|
+
rb_scan_args(argc, argv, "11", &other, &buffer);
|
2618
|
+
|
2619
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2620
|
+
|
2621
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer) || rb_obj_is_kind_of(other, rb_cComplex) || rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2622
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
2623
|
+
rb_warn("second argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
2624
|
+
buffer = Qnil;
|
2625
|
+
}
|
2626
|
+
if (buffer == Qnil)
|
2627
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
2628
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
2629
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2630
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2631
|
+
pdlc_cb_cb_ediv(mcbuf, ocbuf, rcbuf);
|
2632
|
+
}
|
2633
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2634
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2635
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2636
|
+
pdlc_cb_cs_ediv(mcbuf, oc, rcbuf);
|
2637
|
+
}
|
2638
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2639
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2640
|
+
pdlc_cb_fb_ediv(mcbuf, ofbuf, rcbuf);
|
2641
|
+
}
|
2642
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2643
|
+
of = (float)NUM2DBL(other);
|
2644
|
+
pdlc_cb_fs_ediv(mcbuf, of, rcbuf);
|
2645
|
+
}
|
2646
|
+
}
|
2647
|
+
else
|
2648
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2649
|
+
|
2650
|
+
return buffer;
|
2651
|
+
}
|
2652
|
+
|
2653
|
+
|
2654
|
+
/* Element by element division.
|
2655
|
+
* @param other [c_ComplexBuffer, rb_cComplex, c_FloatBuffer, rb_cNumeric]
|
2656
|
+
* @return [self]
|
2657
|
+
*/
|
2658
|
+
static VALUE paddlec_complex_buffer_ediv_inplace(VALUE self, VALUE other)
|
2659
|
+
{
|
2660
|
+
pdlc_complex_buffer_t *mcbuf;
|
2661
|
+
const pdlc_buffer_t *ofbuf;
|
2662
|
+
float of;
|
2663
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2664
|
+
pdlc_complex_t oc;
|
2665
|
+
|
2666
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2667
|
+
|
2668
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2669
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2670
|
+
pdlc_cb_cb_ediv_inplace(mcbuf, ocbuf);
|
2671
|
+
}
|
2672
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2673
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2674
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2675
|
+
pdlc_cb_cs_ediv_inplace(mcbuf, oc);
|
2676
|
+
}
|
2677
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2678
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2679
|
+
pdlc_cb_fb_ediv_inplace(mcbuf, ofbuf);
|
2680
|
+
}
|
2681
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2682
|
+
of = (float)NUM2DBL(other);
|
2683
|
+
pdlc_cb_fs_ediv_inplace(mcbuf, of);
|
2684
|
+
}
|
2685
|
+
else
|
2686
|
+
rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2687
|
+
|
2688
|
+
return self;
|
2689
|
+
}
|
2690
|
+
|
2691
|
+
|
2692
|
+
/* Performs exponentiation. Raises +self+ to the power of +rhs+.
|
2693
|
+
* @return [PaddleC::ComplexBuffer]
|
2694
|
+
* @overload **(other, buffer = nil)
|
2695
|
+
* @param other [PaddleC::FloatBuffer, Numeric]
|
2696
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if a {ComplexBuffer} is provided, it is filled with the output
|
2697
|
+
* @return [PaddleC::ComplexBuffer]
|
2698
|
+
*/
|
2699
|
+
static VALUE paddlec_complex_buffer_pow(int argc, VALUE *argv, VALUE self)
|
2700
|
+
{
|
2701
|
+
const pdlc_complex_buffer_t *mcbuf;
|
2702
|
+
pdlc_complex_buffer_t *rcbuf;
|
2703
|
+
const pdlc_buffer_t *ofbuf;
|
2704
|
+
float of;
|
2705
|
+
VALUE other, buffer;
|
2706
|
+
|
2707
|
+
rb_scan_args(argc, argv, "11", &other, &buffer);
|
2708
|
+
|
2709
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2710
|
+
|
2711
|
+
if (rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2712
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
2713
|
+
rb_warn("second argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
2714
|
+
buffer = Qnil;
|
2715
|
+
}
|
2716
|
+
if (buffer == Qnil)
|
2717
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
2718
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
2719
|
+
if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2720
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2721
|
+
pdlc_cb_fb_pow(mcbuf, ofbuf, rcbuf);
|
2722
|
+
}
|
2723
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2724
|
+
of = (float)NUM2DBL(other);
|
2725
|
+
pdlc_cb_fs_pow(mcbuf, of, rcbuf);
|
2726
|
+
}
|
2727
|
+
}
|
2728
|
+
else
|
2729
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2730
|
+
|
2731
|
+
return buffer;
|
2732
|
+
}
|
2733
|
+
|
2734
|
+
|
2735
|
+
/* Performs exponentiation. Raises +self+ to the power of +rhs+.
|
2736
|
+
* @param other [c_FloatBuffer, rb_cNumeric]
|
2737
|
+
* @return [self]
|
2738
|
+
*/
|
2739
|
+
static VALUE paddlec_complex_buffer_pow_inplace(VALUE self, VALUE other)
|
2740
|
+
{
|
2741
|
+
pdlc_complex_buffer_t *mcbuf;
|
2742
|
+
const pdlc_buffer_t *ofbuf;
|
2743
|
+
float of;
|
2744
|
+
|
2745
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2746
|
+
|
2747
|
+
if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2748
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2749
|
+
pdlc_cb_fb_pow_inplace(mcbuf, ofbuf);
|
2750
|
+
}
|
2751
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2752
|
+
of = (float)NUM2DBL(other);
|
2753
|
+
pdlc_cb_fs_pow_inplace(mcbuf, of);
|
2754
|
+
}
|
2755
|
+
else
|
2756
|
+
rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2757
|
+
|
2758
|
+
return self;
|
2759
|
+
}
|
2760
|
+
|
2761
|
+
|
2762
|
+
/* Element by element modulo.
|
2763
|
+
* @return [PaddleC::ComplexBuffer]
|
2764
|
+
* @overload emod(other, buffer = nil)
|
2765
|
+
* @param other [PaddleC::ComplexBuffer, Complex, PaddleC::FloatBuffer, Numeric]
|
2766
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if a {ComplexBuffer} is provided, it is filled with the output
|
2767
|
+
* @return [PaddleC::ComplexBuffer]
|
2768
|
+
*/
|
2769
|
+
static VALUE paddlec_complex_buffer_emod(int argc, VALUE *argv, VALUE self)
|
2770
|
+
{
|
2771
|
+
const pdlc_complex_buffer_t *mcbuf;
|
2772
|
+
pdlc_complex_buffer_t *rcbuf;
|
2773
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2774
|
+
pdlc_complex_t oc;
|
2775
|
+
const pdlc_buffer_t *ofbuf;
|
2776
|
+
float of;
|
2777
|
+
VALUE other, buffer;
|
2778
|
+
|
2779
|
+
rb_scan_args(argc, argv, "11", &other, &buffer);
|
2780
|
+
|
2781
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2782
|
+
|
2783
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer) || rb_obj_is_kind_of(other, rb_cComplex) || rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2784
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
2785
|
+
rb_warn("second argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
2786
|
+
buffer = Qnil;
|
2787
|
+
}
|
2788
|
+
if (buffer == Qnil)
|
2789
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
2790
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
2791
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2792
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2793
|
+
pdlc_cb_cb_emod(mcbuf, ocbuf, rcbuf);
|
2794
|
+
}
|
2795
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2796
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2797
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2798
|
+
pdlc_cb_cs_emod(mcbuf, oc, rcbuf);
|
2799
|
+
}
|
2800
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2801
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2802
|
+
pdlc_cb_fb_emod(mcbuf, ofbuf, rcbuf);
|
2803
|
+
}
|
2804
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2805
|
+
of = (float)NUM2DBL(other);
|
2806
|
+
pdlc_cb_fs_emod(mcbuf, of, rcbuf);
|
2807
|
+
}
|
2808
|
+
}
|
2809
|
+
else
|
2810
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2811
|
+
|
2812
|
+
return buffer;
|
2813
|
+
}
|
2814
|
+
|
2815
|
+
|
2816
|
+
/* Element by element modulo.
|
2817
|
+
* @param other [c_ComplexBuffer, rb_cComplex, c_FloatBuffer, rb_cNumeric]
|
2818
|
+
* @return [self]
|
2819
|
+
*/
|
2820
|
+
static VALUE paddlec_complex_buffer_emod_inplace(VALUE self, VALUE other)
|
2821
|
+
{
|
2822
|
+
pdlc_complex_buffer_t *mcbuf;
|
2823
|
+
const pdlc_buffer_t *ofbuf;
|
2824
|
+
float of;
|
2825
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2826
|
+
pdlc_complex_t oc;
|
2827
|
+
|
2828
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2829
|
+
|
2830
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2831
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2832
|
+
pdlc_cb_cb_emod_inplace(mcbuf, ocbuf);
|
2833
|
+
}
|
2834
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2835
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2836
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2837
|
+
pdlc_cb_cs_emod_inplace(mcbuf, oc);
|
2838
|
+
}
|
2839
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2840
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2841
|
+
pdlc_cb_fb_emod_inplace(mcbuf, ofbuf);
|
2842
|
+
}
|
2843
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2844
|
+
of = (float)NUM2DBL(other);
|
2845
|
+
pdlc_cb_fs_emod_inplace(mcbuf, of);
|
2846
|
+
}
|
2847
|
+
else
|
2848
|
+
rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2849
|
+
|
2850
|
+
return self;
|
2851
|
+
}
|
2852
|
+
|
2853
|
+
|
2854
|
+
/* Element by element exponentiation.
|
2855
|
+
* @return [PaddleC::ComplexBuffer]
|
2856
|
+
* @overload epow(other, buffer = nil)
|
2857
|
+
* @param other [PaddleC::ComplexBuffer, Complex, PaddleC::FloatBuffer, Numeric]
|
2858
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if a {ComplexBuffer} is provided, it is filled with the output
|
2859
|
+
* @return [PaddleC::ComplexBuffer]
|
2860
|
+
*/
|
2861
|
+
static VALUE paddlec_complex_buffer_epow(int argc, VALUE *argv, VALUE self)
|
2862
|
+
{
|
2863
|
+
const pdlc_complex_buffer_t *mcbuf;
|
2864
|
+
pdlc_complex_buffer_t *rcbuf;
|
2865
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2866
|
+
pdlc_complex_t oc;
|
2867
|
+
const pdlc_buffer_t *ofbuf;
|
2868
|
+
float of;
|
2869
|
+
VALUE other, buffer;
|
2870
|
+
|
2871
|
+
rb_scan_args(argc, argv, "11", &other, &buffer);
|
2872
|
+
|
2873
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2874
|
+
|
2875
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer) || rb_obj_is_kind_of(other, rb_cComplex) || rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2876
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
2877
|
+
rb_warn("second argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
2878
|
+
buffer = Qnil;
|
2879
|
+
}
|
2880
|
+
if (buffer == Qnil)
|
2881
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
2882
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
2883
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2884
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2885
|
+
pdlc_cb_cb_epow(mcbuf, ocbuf, rcbuf);
|
2886
|
+
}
|
2887
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2888
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2889
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2890
|
+
pdlc_cb_cs_epow(mcbuf, oc, rcbuf);
|
2891
|
+
}
|
2892
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2893
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2894
|
+
pdlc_cb_fb_epow(mcbuf, ofbuf, rcbuf);
|
2895
|
+
}
|
2896
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2897
|
+
of = (float)NUM2DBL(other);
|
2898
|
+
pdlc_cb_fs_epow(mcbuf, of, rcbuf);
|
2899
|
+
}
|
2900
|
+
}
|
2901
|
+
else
|
2902
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2903
|
+
|
2904
|
+
return buffer;
|
2905
|
+
}
|
2906
|
+
|
2907
|
+
|
2908
|
+
/* Element by element exponentiation.
|
2909
|
+
* @param other [c_ComplexBuffer, rb_cComplex, c_FloatBuffer, rb_cNumeric]
|
2910
|
+
* @return [self]
|
2911
|
+
*/
|
2912
|
+
static VALUE paddlec_complex_buffer_epow_inplace(VALUE self, VALUE other)
|
2913
|
+
{
|
2914
|
+
pdlc_complex_buffer_t *mcbuf;
|
2915
|
+
const pdlc_buffer_t *ofbuf;
|
2916
|
+
float of;
|
2917
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2918
|
+
pdlc_complex_t oc;
|
2919
|
+
|
2920
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2921
|
+
|
2922
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
2923
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
2924
|
+
pdlc_cb_cb_epow_inplace(mcbuf, ocbuf);
|
2925
|
+
}
|
2926
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
2927
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
2928
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
2929
|
+
pdlc_cb_cs_epow_inplace(mcbuf, oc);
|
2930
|
+
}
|
2931
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
2932
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
2933
|
+
pdlc_cb_fb_epow_inplace(mcbuf, ofbuf);
|
2934
|
+
}
|
2935
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
2936
|
+
of = (float)NUM2DBL(other);
|
2937
|
+
pdlc_cb_fs_epow_inplace(mcbuf, of);
|
2938
|
+
}
|
2939
|
+
else
|
2940
|
+
rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
2941
|
+
|
2942
|
+
return self;
|
2943
|
+
}
|
2944
|
+
|
2945
|
+
|
2946
|
+
/* Return the lesser and greater values of +self+.
|
2947
|
+
* Returns nil if empty.
|
2948
|
+
* @return [Array<Complex>, nil] a two element array containint the lesser and greater values from +self+.
|
2949
|
+
*/
|
2950
|
+
static VALUE paddlec_complex_buffer_minmax(VALUE self)
|
2951
|
+
{
|
2952
|
+
const pdlc_complex_buffer_t *mcbuf;
|
2953
|
+
pdlc_complex_t mi, ma;
|
2954
|
+
|
2955
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2956
|
+
|
2957
|
+
if (mcbuf->length < 1)
|
2958
|
+
return Qnil;
|
2959
|
+
|
2960
|
+
pdlc_complex_buffer_minmax_of_self(mcbuf, &mi, &ma);
|
2961
|
+
|
2962
|
+
return rb_assoc_new(paddlec2COMPLEX(mi), paddlec2COMPLEX(ma));
|
2963
|
+
}
|
2964
|
+
|
2965
|
+
|
2966
|
+
/* @return [nil, Complex, PaddleC::ComplexBuffer]
|
2967
|
+
* Without any parameter, returns the lesser value stored in +self+ (or +nil+ if empty).
|
2968
|
+
* If a {PaddleC::FloatBuffer}, a {PaddleC::FloatBuffer], a Float or a Complex is provided as +other+,
|
2969
|
+
* returns a new buffer for which each element is the lesser value of the corresponding element of +self+ and +other+.
|
2970
|
+
* @overload min()
|
2971
|
+
* @return [Complex, nil]
|
2972
|
+
* @overload min(other, buffer = nil)
|
2973
|
+
* @param other [PaddleC::ComplexBuffer, Complex, PaddleC::FloatBuffer, Numeric]
|
2974
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if a {ComplexBuffer} is provided, it is filled with the output
|
2975
|
+
* @return [PaddleC::ComplexBuffer]
|
2976
|
+
*/
|
2977
|
+
static VALUE paddlec_complex_buffer_min(int argc, VALUE *argv, VALUE self)
|
2978
|
+
{
|
2979
|
+
const pdlc_complex_buffer_t *mcbuf;
|
2980
|
+
pdlc_complex_buffer_t *rcbuf;
|
2981
|
+
const pdlc_complex_buffer_t *ocbuf;
|
2982
|
+
pdlc_complex_t oc;
|
2983
|
+
const pdlc_buffer_t *ofbuf;
|
2984
|
+
float of;
|
2985
|
+
VALUE other, buffer;
|
2986
|
+
|
2987
|
+
rb_scan_args(argc, argv, "02", &other, &buffer);
|
2988
|
+
|
2989
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
2990
|
+
|
2991
|
+
if (other == Qnil) {
|
2992
|
+
if (mcbuf->length < 1)
|
2993
|
+
buffer = Qnil;
|
2994
|
+
else {
|
2995
|
+
oc = pdlc_complex_buffer_min_of_self(mcbuf);
|
2996
|
+
buffer = paddlec2COMPLEX(oc);
|
2997
|
+
}
|
2998
|
+
}
|
2999
|
+
else if (rb_obj_is_kind_of(other, c_ComplexBuffer) || rb_obj_is_kind_of(other, rb_cComplex) || rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
3000
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
3001
|
+
rb_warn("second argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
3002
|
+
buffer = Qnil;
|
3003
|
+
}
|
3004
|
+
if (buffer == Qnil)
|
3005
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
3006
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
3007
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
3008
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
3009
|
+
pdlc_cb_cb_min(mcbuf, ocbuf, rcbuf);
|
3010
|
+
}
|
3011
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
3012
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
3013
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
3014
|
+
pdlc_cb_cs_min(mcbuf, oc, rcbuf);
|
3015
|
+
}
|
3016
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
3017
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
3018
|
+
pdlc_cb_fb_min(mcbuf, ofbuf, rcbuf);
|
3019
|
+
}
|
3020
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
3021
|
+
of = (float)NUM2DBL(other);
|
3022
|
+
pdlc_cb_fs_min(mcbuf, of, rcbuf);
|
3023
|
+
}
|
3024
|
+
}
|
3025
|
+
else
|
3026
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
3027
|
+
|
3028
|
+
return buffer;
|
3029
|
+
}
|
3030
|
+
|
3031
|
+
|
3032
|
+
/* @param other [c_ComplexBuffer, rb_cComplex, c_FloatBuffer, rb_cNumeric]
|
3033
|
+
* @return [self]
|
3034
|
+
*/
|
3035
|
+
static VALUE paddlec_complex_buffer_min_inplace(VALUE self, VALUE other)
|
3036
|
+
{
|
3037
|
+
pdlc_complex_buffer_t *mcbuf;
|
3038
|
+
const pdlc_buffer_t *ofbuf;
|
3039
|
+
float of;
|
3040
|
+
const pdlc_complex_buffer_t *ocbuf;
|
3041
|
+
pdlc_complex_t oc;
|
3042
|
+
|
3043
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
3044
|
+
|
3045
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
3046
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
3047
|
+
pdlc_cb_cb_min_inplace(mcbuf, ocbuf);
|
3048
|
+
}
|
3049
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
3050
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
3051
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
3052
|
+
pdlc_cb_cs_min_inplace(mcbuf, oc);
|
3053
|
+
}
|
3054
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
3055
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
3056
|
+
pdlc_cb_fb_min_inplace(mcbuf, ofbuf);
|
3057
|
+
}
|
3058
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
3059
|
+
of = (float)NUM2DBL(other);
|
3060
|
+
pdlc_cb_fs_min_inplace(mcbuf, of);
|
3061
|
+
}
|
3062
|
+
else
|
3063
|
+
rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
3064
|
+
|
3065
|
+
return self;
|
3066
|
+
}
|
3067
|
+
|
3068
|
+
|
3069
|
+
/* @return [nil, Complex, PaddleC::ComplexBuffer]
|
3070
|
+
* Without any parameter, returns the greater value stored in +self+ (or +nil+ if empty).
|
3071
|
+
* If a {PaddleC::FloatBuffer}, a {PaddleC::FloatBuffer], a Float or a Complex is provided as +other+,
|
3072
|
+
* returns a new buffer for which each element is the lesser value of the corresponding element of +self+ and +other+.
|
3073
|
+
* @overload max()
|
3074
|
+
* @return [Complex, nil]
|
3075
|
+
* @overload max(other, buffer = nil)
|
3076
|
+
* @param other [PaddleC::ComplexBuffer, Complex, PaddleC::FloatBuffer, Numeric]
|
3077
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if a {ComplexBuffer} is provided, it is filled with the output
|
3078
|
+
* @return [PaddleC::ComplexBuffer]
|
3079
|
+
*/
|
3080
|
+
static VALUE paddlec_complex_buffer_max(int argc, VALUE *argv, VALUE self)
|
3081
|
+
{
|
3082
|
+
const pdlc_complex_buffer_t *mcbuf;
|
3083
|
+
pdlc_complex_buffer_t *rcbuf;
|
3084
|
+
const pdlc_complex_buffer_t *ocbuf;
|
3085
|
+
pdlc_complex_t oc;
|
3086
|
+
const pdlc_buffer_t *ofbuf;
|
3087
|
+
float of;
|
3088
|
+
VALUE other, buffer;
|
3089
|
+
|
3090
|
+
rb_scan_args(argc, argv, "02", &other, &buffer);
|
3091
|
+
|
3092
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
3093
|
+
|
3094
|
+
if (other == Qnil) {
|
3095
|
+
if (mcbuf->length < 1)
|
3096
|
+
buffer = Qnil;
|
3097
|
+
else {
|
3098
|
+
oc = pdlc_complex_buffer_max_of_self(mcbuf);
|
3099
|
+
buffer = paddlec2COMPLEX(oc);
|
3100
|
+
}
|
3101
|
+
}
|
3102
|
+
else if (rb_obj_is_kind_of(other, c_ComplexBuffer) || rb_obj_is_kind_of(other, rb_cComplex) || rb_obj_is_kind_of(other, c_FloatBuffer) || rb_obj_is_kind_of(other, rb_cNumeric)) {
|
3103
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
3104
|
+
rb_warn("second argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
3105
|
+
buffer = Qnil;
|
3106
|
+
}
|
3107
|
+
if (buffer == Qnil)
|
3108
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
3109
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
3110
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
3111
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
3112
|
+
pdlc_cb_cb_max(mcbuf, ocbuf, rcbuf);
|
3113
|
+
}
|
3114
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
3115
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
3116
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
3117
|
+
pdlc_cb_cs_max(mcbuf, oc, rcbuf);
|
3118
|
+
}
|
3119
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
3120
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
3121
|
+
pdlc_cb_fb_max(mcbuf, ofbuf, rcbuf);
|
3122
|
+
}
|
3123
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
3124
|
+
of = (float)NUM2DBL(other);
|
3125
|
+
pdlc_cb_fs_max(mcbuf, of, rcbuf);
|
3126
|
+
}
|
3127
|
+
}
|
3128
|
+
else
|
3129
|
+
rb_raise(rb_eTypeError, "First argument is expected to be a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
3130
|
+
|
3131
|
+
return buffer;
|
3132
|
+
}
|
3133
|
+
|
3134
|
+
|
3135
|
+
/* @param other [c_ComplexBuffer, rb_cComplex, c_FloatBuffer, rb_cNumeric]
|
3136
|
+
* @return [self]
|
3137
|
+
*/
|
3138
|
+
static VALUE paddlec_complex_buffer_max_inplace(VALUE self, VALUE other)
|
3139
|
+
{
|
3140
|
+
pdlc_complex_buffer_t *mcbuf;
|
3141
|
+
const pdlc_buffer_t *ofbuf;
|
3142
|
+
float of;
|
3143
|
+
const pdlc_complex_buffer_t *ocbuf;
|
3144
|
+
pdlc_complex_t oc;
|
3145
|
+
|
3146
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
3147
|
+
|
3148
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
3149
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
3150
|
+
pdlc_cb_cb_max_inplace(mcbuf, ocbuf);
|
3151
|
+
}
|
3152
|
+
else if (rb_obj_is_kind_of(other, rb_cComplex)) {
|
3153
|
+
oc.real = (float)NUM2DBL(rb_funcallv(other, id_real, 0, NULL));
|
3154
|
+
oc.imag = (float)NUM2DBL(rb_funcallv(other, id_imag, 0, NULL));
|
3155
|
+
pdlc_cb_cs_max_inplace(mcbuf, oc);
|
3156
|
+
}
|
3157
|
+
else if (rb_obj_is_kind_of(other, c_FloatBuffer)) {
|
3158
|
+
ofbuf = paddlec_float_buffer_get_struct(other);
|
3159
|
+
pdlc_cb_fb_max_inplace(mcbuf, ofbuf);
|
3160
|
+
}
|
3161
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
3162
|
+
of = (float)NUM2DBL(other);
|
3163
|
+
pdlc_cb_fs_max_inplace(mcbuf, of);
|
3164
|
+
}
|
3165
|
+
else
|
3166
|
+
rb_raise(rb_eTypeError, "expecting a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE" or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_cComplex), rb_class_name(c_FloatBuffer), rb_class_name(rb_cNumeric), rb_class_name(rb_class_of(other)));
|
3167
|
+
|
3168
|
+
return self;
|
3169
|
+
}
|
3170
|
+
|
3171
|
+
|
3172
|
+
/* Clipp the real and imaginary parts of the signal so that the output has no values whose real and imaginary part are greater than +max+ nor lesser than +min+.
|
3173
|
+
* @overload clipp(max = 1.0, min = -max, buffer = nil)
|
3174
|
+
* @param max [Float] the maximum value allowed
|
3175
|
+
* @param min [Float] the minimum value allowed
|
3176
|
+
* @param buffer [nil, PaddleC::ComplexBuffer] if provided, the result is written into +buffer+.
|
3177
|
+
* @return [PaddleC::ComplexBuffer]
|
3178
|
+
*/
|
3179
|
+
static VALUE paddlec_complex_buffer_clipp(int argc, VALUE *argv, VALUE self)
|
3180
|
+
{
|
3181
|
+
const pdlc_complex_buffer_t *mcbuf;
|
3182
|
+
pdlc_complex_buffer_t *rcbuf;
|
3183
|
+
float mi, ma;
|
3184
|
+
VALUE buffer, rbmin, rbmax;
|
3185
|
+
|
3186
|
+
rb_scan_args(argc, argv, "3", &rbmax, &rbmin, &buffer);
|
3187
|
+
|
3188
|
+
if (rbmax == Qnil)
|
3189
|
+
ma = 1.0f;
|
3190
|
+
else
|
3191
|
+
ma = (float)NUM2DBL(rbmax);
|
3192
|
+
|
3193
|
+
if (rbmin == Qnil)
|
3194
|
+
mi = -ma;
|
3195
|
+
else
|
3196
|
+
mi = (float)NUM2DBL(rbmin);
|
3197
|
+
|
3198
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
3199
|
+
rb_warn("second argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
3200
|
+
buffer = Qnil;
|
3201
|
+
}
|
3202
|
+
|
3203
|
+
if (buffer == Qnil)
|
3204
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
3205
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
3206
|
+
|
3207
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
3208
|
+
|
3209
|
+
pdlc_complex_buffer_clipp(mcbuf, mi, ma, rcbuf);
|
3210
|
+
|
3211
|
+
return buffer;
|
3212
|
+
}
|
3213
|
+
|
3214
|
+
|
3215
|
+
/* Clipp the real and imaginary parts of the signal so that the output has no values whose real and imaginary part are greater than +max+ nor lesser than +min+.
|
3216
|
+
* @overload clipp!(max = 1.0, min = -max)
|
3217
|
+
* @param max [Float] the maximum value allowed
|
3218
|
+
* @param min [Float] the minimum value allowed
|
3219
|
+
* @return [self]
|
3220
|
+
*/
|
3221
|
+
static VALUE paddlec_complex_buffer_clipp_inplace(int argc, VALUE *argv, VALUE self)
|
3222
|
+
{
|
3223
|
+
pdlc_complex_buffer_t *mcbuf;
|
3224
|
+
float mi, ma;
|
3225
|
+
VALUE rbmin, rbmax;
|
3226
|
+
|
3227
|
+
rb_scan_args(argc, argv, "2", &rbmax, &rbmin);
|
3228
|
+
|
3229
|
+
if (rbmax == Qnil)
|
3230
|
+
ma = 1.0f;
|
3231
|
+
else
|
3232
|
+
ma = (float)NUM2DBL(rbmax);
|
3233
|
+
|
3234
|
+
if (rbmin == Qnil)
|
3235
|
+
mi = -ma;
|
3236
|
+
else
|
3237
|
+
mi = (float)NUM2DBL(rbmin);
|
3238
|
+
|
3239
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
3240
|
+
|
3241
|
+
pdlc_complex_buffer_clipp_inplace(mcbuf, mi, ma);
|
3242
|
+
|
3243
|
+
return self;
|
3244
|
+
}
|
3245
|
+
|
3246
|
+
|
3247
|
+
/* Returns a new {PaddleC::ComplexBuffer} containing +self+'s elements in reverse order.
|
3248
|
+
* @overload reverse(buffer = nil)
|
3249
|
+
* @param buffer [PaddleC::ComplexBuffer] if provided, the result is written into +buffer+.
|
3250
|
+
* @return [PaddleC::ComplexBuffer]
|
3251
|
+
*/
|
3252
|
+
static VALUE paddlec_complex_buffer_reverse(int argc, VALUE *argv, VALUE self)
|
3253
|
+
{
|
3254
|
+
const pdlc_complex_buffer_t *mcbuf;
|
3255
|
+
pdlc_complex_buffer_t *rcbuf;
|
3256
|
+
VALUE buffer;
|
3257
|
+
|
3258
|
+
rb_scan_args(argc, argv, "01", &buffer);
|
3259
|
+
|
3260
|
+
if (buffer != Qnil && !rb_obj_is_kind_of(buffer, c_ComplexBuffer)) {
|
3261
|
+
rb_warn("argument (buffer) is expected to be a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(buffer)));
|
3262
|
+
buffer = Qnil;
|
3263
|
+
}
|
3264
|
+
|
3265
|
+
if (buffer == Qnil)
|
3266
|
+
buffer = rb_class_new_instance(0, NULL, c_ComplexBuffer);
|
3267
|
+
rcbuf = paddlec_complex_buffer_get_struct(buffer);
|
3268
|
+
|
3269
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
3270
|
+
|
3271
|
+
pdlc_complex_buffer_reverse(mcbuf, rcbuf);
|
3272
|
+
|
3273
|
+
return buffer;
|
3274
|
+
}
|
3275
|
+
|
3276
|
+
|
3277
|
+
/* Reverse +self+ in place.
|
3278
|
+
* @return [self]
|
3279
|
+
*/
|
3280
|
+
static VALUE paddlec_complex_buffer_reverse_inplace(VALUE self)
|
3281
|
+
{
|
3282
|
+
pdlc_complex_buffer_t *mcbuf;
|
3283
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
3284
|
+
pdlc_complex_buffer_reverse_inplace(mcbuf);
|
3285
|
+
return self;
|
3286
|
+
}
|
3287
|
+
|
3288
|
+
|
3289
|
+
/* Returns the sum of all values in +self+, or +nil+ if empty.
|
3290
|
+
* @return [Complex, nil]
|
3291
|
+
*/
|
3292
|
+
static VALUE paddlec_complex_buffer_sum(VALUE self)
|
3293
|
+
{
|
3294
|
+
const pdlc_complex_buffer_t *mcbuf;
|
3295
|
+
pdlc_complex_t res;
|
3296
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
3297
|
+
if (mcbuf->length < 1)
|
3298
|
+
return Qnil;
|
3299
|
+
res = pdlc_complex_buffer_sum(mcbuf);
|
3300
|
+
return paddlec2COMPLEX(res);
|
3301
|
+
}
|
3302
|
+
|
3303
|
+
|
3304
|
+
/* Returns the mean of all values in +self+, or +nil+ if empty.
|
3305
|
+
* @return [Complex, nil]
|
3306
|
+
*/
|
3307
|
+
static VALUE paddlec_complex_buffer_mean(VALUE self)
|
3308
|
+
{
|
3309
|
+
const pdlc_complex_buffer_t *mcbuf;
|
3310
|
+
pdlc_complex_t res;
|
3311
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
3312
|
+
if (mcbuf->length < 1)
|
3313
|
+
return Qnil;
|
3314
|
+
res = pdlc_complex_buffer_mean(mcbuf);
|
3315
|
+
return paddlec2COMPLEX(res);
|
3316
|
+
}
|
3317
|
+
|
3318
|
+
|
3319
|
+
/* Returns the product of all values in +self+, or +nil+ if empty.
|
3320
|
+
* @return [Complex, nil]
|
3321
|
+
*/
|
3322
|
+
static VALUE paddlec_complex_buffer_prod(VALUE self)
|
3323
|
+
{
|
3324
|
+
const pdlc_complex_buffer_t *mcbuf;
|
3325
|
+
pdlc_complex_t res;
|
3326
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
3327
|
+
if (mcbuf->length < 1)
|
3328
|
+
return Qnil;
|
3329
|
+
res = pdlc_complex_buffer_prod(mcbuf);
|
3330
|
+
return paddlec2COMPLEX(res);
|
3331
|
+
}
|
3332
|
+
|
3333
|
+
|
3334
|
+
/* Returns the product of all values in +self+, processing separately the real part and the imaginary part.
|
3335
|
+
* Returns +nil+ if empty.
|
3336
|
+
* @return [Complex, nil]
|
3337
|
+
*/
|
3338
|
+
static VALUE paddlec_complex_buffer_eprod(VALUE self)
|
3339
|
+
{
|
3340
|
+
const pdlc_complex_buffer_t *mcbuf;
|
3341
|
+
pdlc_complex_t res;
|
3342
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
3343
|
+
if (mcbuf->length < 1)
|
3344
|
+
return Qnil;
|
3345
|
+
res = pdlc_complex_buffer_eprod(mcbuf);
|
3346
|
+
return paddlec2COMPLEX(res);
|
3347
|
+
}
|
3348
|
+
|
3349
|
+
|
3350
|
+
/* Returns the sum of absolute differences of values of +self+ with +other+, or +nil+ if empty.
|
3351
|
+
* @return [Complex, nil]
|
3352
|
+
* @param other [Complex, PaddleC::ComplexBuffer]
|
3353
|
+
*/
|
3354
|
+
static VALUE paddlec_complex_buffer_sad(VALUE self, VALUE other)
|
3355
|
+
{
|
3356
|
+
const pdlc_complex_buffer_t *mcbuf;
|
3357
|
+
const pdlc_complex_buffer_t *ocbuf;
|
3358
|
+
pdlc_complex_t oc, rc;
|
3359
|
+
|
3360
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
3361
|
+
if (mcbuf->length < 1)
|
3362
|
+
return Qnil;
|
3363
|
+
|
3364
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
3365
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
3366
|
+
if (ocbuf->length < 1)
|
3367
|
+
return Qnil;
|
3368
|
+
rc = pdlc_complex_buffer_cb_cb_sad(mcbuf, ocbuf);
|
3369
|
+
}
|
3370
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
3371
|
+
oc = COMPLEX2paddlec(other);
|
3372
|
+
rc = pdlc_complex_buffer_cb_cs_sad(mcbuf, oc);
|
3373
|
+
}
|
3374
|
+
else
|
3375
|
+
rb_raise(rb_eArgError, "expecting a Complex or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(other)));
|
3376
|
+
|
3377
|
+
return paddlec2COMPLEX(rc);
|
3378
|
+
}
|
3379
|
+
|
3380
|
+
|
3381
|
+
/* Returns the sum of square differences of values of +self+ with +other+, or +nil+ if empty.
|
3382
|
+
* @return [Complex, nil]
|
3383
|
+
* @param other [Complex, PaddleC::ComplexBuffer]
|
3384
|
+
*/
|
3385
|
+
static VALUE paddlec_complex_buffer_ssd(VALUE self, VALUE other)
|
3386
|
+
{
|
3387
|
+
const pdlc_complex_buffer_t *mcbuf;
|
3388
|
+
const pdlc_complex_buffer_t *ocbuf;
|
3389
|
+
pdlc_complex_t oc, rc;
|
3390
|
+
|
3391
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
3392
|
+
if (mcbuf->length < 1)
|
3393
|
+
return Qnil;
|
3394
|
+
|
3395
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
3396
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
3397
|
+
if (ocbuf->length < 1)
|
3398
|
+
return Qnil;
|
3399
|
+
rc = pdlc_complex_buffer_cb_cb_ssd(mcbuf, ocbuf);
|
3400
|
+
}
|
3401
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
3402
|
+
oc = COMPLEX2paddlec(other);
|
3403
|
+
rc = pdlc_complex_buffer_cb_cs_ssd(mcbuf, oc);
|
3404
|
+
}
|
3405
|
+
else
|
3406
|
+
rb_raise(rb_eArgError, "expecting a Complex or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(other)));
|
3407
|
+
|
3408
|
+
return paddlec2COMPLEX(rc);
|
3409
|
+
}
|
3410
|
+
|
3411
|
+
|
3412
|
+
/* Returns the sum of square differences of values of +self+ with +other+, processing the real part and the imaginary part independantly.
|
3413
|
+
* Returns +nil+ if empty.
|
3414
|
+
* @return [Complex, nil]
|
3415
|
+
* @param other [Complex, PaddleC::ComplexBuffer]
|
3416
|
+
*/
|
3417
|
+
static VALUE paddlec_complex_buffer_essd(VALUE self, VALUE other)
|
3418
|
+
{
|
3419
|
+
const pdlc_complex_buffer_t *mcbuf;
|
3420
|
+
const pdlc_complex_buffer_t *ocbuf;
|
3421
|
+
pdlc_complex_t oc, rc;
|
3422
|
+
|
3423
|
+
mcbuf = paddlec_complex_buffer_get_struct(self);
|
3424
|
+
if (mcbuf->length < 1)
|
3425
|
+
return Qnil;
|
3426
|
+
|
3427
|
+
if (rb_obj_is_kind_of(other, c_ComplexBuffer)) {
|
3428
|
+
ocbuf = paddlec_complex_buffer_get_struct(other);
|
3429
|
+
if (ocbuf->length < 1)
|
3430
|
+
return Qnil;
|
3431
|
+
rc = pdlc_complex_buffer_cb_cb_essd(mcbuf, ocbuf);
|
3432
|
+
}
|
3433
|
+
else if (rb_obj_is_kind_of(other, rb_cNumeric)) {
|
3434
|
+
oc = COMPLEX2paddlec(other);
|
3435
|
+
rc = pdlc_complex_buffer_cb_cs_essd(mcbuf, oc);
|
3436
|
+
}
|
3437
|
+
else
|
3438
|
+
rb_raise(rb_eArgError, "expecting a Complex or a %"PRIsVALUE", not a %"PRIsVALUE, rb_class_name(c_ComplexBuffer), rb_class_name(rb_class_of(other)));
|
3439
|
+
|
3440
|
+
return paddlec2COMPLEX(rc);
|
3441
|
+
}
|
3442
|
+
|
3443
|
+
|
3444
|
+
|
3445
|
+
void Init_paddlec_complex_buffer()
|
3446
|
+
{
|
3447
|
+
c_ComplexBuffer = rb_define_class_under(m_PaddleC, "ComplexBuffer", rb_cObject);
|
3448
|
+
rb_define_module_function(c_ComplexBuffer, "unpack", paddlec_complex_buffer_classunpack, 2);
|
3449
|
+
|
3450
|
+
rb_define_alloc_func(c_ComplexBuffer, paddlec_complex_buffer_alloc);
|
3451
|
+
rb_include_module(c_ComplexBuffer, rb_mEnumerable);
|
3452
|
+
rb_define_method(c_ComplexBuffer, "initialize", paddlec_complex_buffer_initialize, -1);
|
3453
|
+
rb_define_method(c_ComplexBuffer, "to_complex_buffer", paddlec_complex_buffer_to_complex_buffer, 0);
|
3454
|
+
rb_define_method(c_ComplexBuffer, "each", paddlec_complex_buffer_each, 0);
|
3455
|
+
rb_define_method(c_ComplexBuffer, "collect!", paddlec_complex_buffer_collect_inp, 0);
|
3456
|
+
rb_define_method(c_ComplexBuffer, "length", paddlec_complex_buffer_length, 0);
|
3457
|
+
rb_define_method(c_ComplexBuffer, "empty?", paddlec_complex_buffer_isempty, 0);
|
3458
|
+
rb_define_method(c_ComplexBuffer, "to_a", paddlec_complex_buffer_to_a, 0);
|
3459
|
+
rb_define_method(c_ComplexBuffer, "to_s", paddlec_complex_buffer_to_s, 0);
|
3460
|
+
rb_define_method(c_ComplexBuffer, "inspect", paddlec_complex_buffer_to_s, 0);
|
3461
|
+
rb_define_method(c_ComplexBuffer, "zip", paddlec_complex_buffer_zip, -1);
|
3462
|
+
rb_define_method(c_ComplexBuffer, "clone", paddlec_complex_buffer_clone, 0);
|
3463
|
+
rb_define_method(c_ComplexBuffer, "[]", paddlec_complex_buffer_get, -1);
|
3464
|
+
rb_define_method(c_ComplexBuffer, "slice", paddlec_complex_buffer_get, -1);
|
3465
|
+
rb_define_method(c_ComplexBuffer, "[]=", paddlec_complex_buffer_set, -1);
|
3466
|
+
rb_define_method(c_ComplexBuffer, "pack", paddlec_complex_buffer_pack, -1);
|
3467
|
+
rb_define_method(c_ComplexBuffer, "unpack", paddlec_complex_buffer_unpack, 2);
|
3468
|
+
rb_define_method(c_ComplexBuffer, "resize", paddlec_complex_buffer_resize, 1);
|
3469
|
+
rb_define_method(c_ComplexBuffer, "pointer", paddlec_complex_buffer_native_ptr, 0);
|
3470
|
+
rb_define_method(c_ComplexBuffer, "coerce", paddlec_complex_buffer_coerce, 1);
|
3471
|
+
if (c_FFI_Pointer != Qundef)
|
3472
|
+
rb_define_method(c_ComplexBuffer, "to_ptr", paddlec_complex_buffer_ffi_pointer, 0);
|
3473
|
+
|
3474
|
+
rb_define_method(rb_cArray, "to_complex_buffer", paddlec_array_to_complex_buffer, 0);
|
3475
|
+
|
3476
|
+
rb_define_method(c_ComplexBuffer, "finite?", paddlec_complex_buffer_finite, 0);
|
3477
|
+
rb_define_method(c_ComplexBuffer, "infinite?", paddlec_complex_buffer_infinite, 0);
|
3478
|
+
rb_define_method(c_ComplexBuffer, "nan?", paddlec_complex_buffer_nan, 0);
|
3479
|
+
rb_define_method(c_ComplexBuffer, "integer?", paddlec_complex_buffer_integer, 0);
|
3480
|
+
rb_define_method(c_ComplexBuffer, "nonzero?", paddlec_complex_buffer_nonzero, 0);
|
3481
|
+
rb_define_method(c_ComplexBuffer, "zero?", paddlec_complex_buffer_zero, 0);
|
3482
|
+
rb_define_method(c_ComplexBuffer, "==", paddlec_complex_buffer_equ, 1);
|
3483
|
+
rb_define_method(c_ComplexBuffer, "!=", paddlec_complex_buffer_different, 1);
|
3484
|
+
rb_define_method(c_ComplexBuffer, "ceil", paddlec_complex_buffer_ceil, -1);
|
3485
|
+
rb_define_method(c_ComplexBuffer, "ceil!", paddlec_complex_buffer_ceil_inplace, -1);
|
3486
|
+
rb_define_method(c_ComplexBuffer, "floor", paddlec_complex_buffer_floor, -1);
|
3487
|
+
rb_define_method(c_ComplexBuffer, "floor!", paddlec_complex_buffer_floor_inplace, -1);
|
3488
|
+
rb_define_method(c_ComplexBuffer, "truncate", paddlec_complex_buffer_truncate, -1);
|
3489
|
+
rb_define_method(c_ComplexBuffer, "truncate!", paddlec_complex_buffer_truncate_inplace, -1);
|
3490
|
+
rb_define_method(c_ComplexBuffer, "round", paddlec_complex_buffer_round, -1);
|
3491
|
+
rb_define_method(c_ComplexBuffer, "round!", paddlec_complex_buffer_round_inplace, -1);
|
3492
|
+
rb_define_method(c_ComplexBuffer, "abs", paddlec_complex_buffer_abs, -1);
|
3493
|
+
rb_define_alias(c_ComplexBuffer, "magnitude", "abs");
|
3494
|
+
rb_define_method(c_ComplexBuffer, "abs2", paddlec_complex_buffer_abs2, -1);
|
3495
|
+
rb_define_method(c_ComplexBuffer, "arg", paddlec_complex_buffer_arg, -1);
|
3496
|
+
rb_define_alias(c_ComplexBuffer, "angle", "arg");
|
3497
|
+
rb_define_alias(c_ComplexBuffer, "phase", "arg");
|
3498
|
+
rb_define_method(c_ComplexBuffer, "conjugate", paddlec_complex_buffer_conjugate, -1);
|
3499
|
+
rb_define_alias(c_ComplexBuffer, "conj", "conjugate");
|
3500
|
+
rb_define_method(c_ComplexBuffer, "conjugate!", paddlec_complex_buffer_conjugate_inplace, 0);
|
3501
|
+
rb_define_method(c_ComplexBuffer, "imaginary", paddlec_complex_buffer_imag, -1);
|
3502
|
+
rb_define_alias(c_ComplexBuffer, "imag", "imaginary");
|
3503
|
+
rb_define_method(c_ComplexBuffer, "real", paddlec_complex_buffer_real, -1);
|
3504
|
+
rb_define_method(c_ComplexBuffer, "swapIQ", paddlec_complex_buffer_swapIQ, -1);
|
3505
|
+
rb_define_alias(c_ComplexBuffer, "swapRI", "swapIQ");
|
3506
|
+
rb_define_method(c_ComplexBuffer, "swapIQ!", paddlec_complex_buffer_swapIQ_inplace, 0);
|
3507
|
+
rb_define_alias(c_ComplexBuffer, "swapRI!", "swapIQ!");
|
3508
|
+
rb_define_method(c_ComplexBuffer, "+@", paddlec_complex_buffer_unaryplus, 0);
|
3509
|
+
rb_define_method(c_ComplexBuffer, "-@", paddlec_complex_buffer_unaryminus, -1);
|
3510
|
+
rb_define_method(c_ComplexBuffer, "negate!", paddlec_complex_buffer_unaryminus_inplace,0);
|
3511
|
+
rb_define_method(c_ComplexBuffer, "-", paddlec_complex_buffer_sub, -1);
|
3512
|
+
rb_define_alias(c_ComplexBuffer, "sub", "-");
|
3513
|
+
rb_define_method(c_ComplexBuffer, "sub!", paddlec_complex_buffer_sub_inplace, 1);
|
3514
|
+
rb_define_method(c_ComplexBuffer, "esub", paddlec_complex_buffer_esub, -1);
|
3515
|
+
rb_define_method(c_ComplexBuffer, "esub!", paddlec_complex_buffer_esub_inplace, 1);
|
3516
|
+
rb_define_method(c_ComplexBuffer, "+", paddlec_complex_buffer_add, -1);
|
3517
|
+
rb_define_alias(c_ComplexBuffer, "add", "+");
|
3518
|
+
rb_define_method(c_ComplexBuffer, "add!", paddlec_complex_buffer_add_inplace, 1);
|
3519
|
+
rb_define_method(c_ComplexBuffer, "eadd", paddlec_complex_buffer_eadd, -1);
|
3520
|
+
rb_define_method(c_ComplexBuffer, "eadd!", paddlec_complex_buffer_eadd_inplace, 1);
|
3521
|
+
rb_define_method(c_ComplexBuffer, "*", paddlec_complex_buffer_mult, -1);
|
3522
|
+
rb_define_alias(c_ComplexBuffer, "mult", "*");
|
3523
|
+
rb_define_method(c_ComplexBuffer, "mult!", paddlec_complex_buffer_mult_inplace, 1);
|
3524
|
+
rb_define_method(c_ComplexBuffer, "emult", paddlec_complex_buffer_emult, -1);
|
3525
|
+
rb_define_method(c_ComplexBuffer, "emul!", paddlec_complex_buffer_emult_inplace, 1);
|
3526
|
+
rb_define_method(c_ComplexBuffer, "/", paddlec_complex_buffer_div, -1);
|
3527
|
+
rb_define_alias(c_ComplexBuffer, "div", "/");
|
3528
|
+
rb_define_method(c_ComplexBuffer, "div!", paddlec_complex_buffer_div_inplace, 1);
|
3529
|
+
rb_define_method(c_ComplexBuffer, "ediv", paddlec_complex_buffer_ediv, -1);
|
3530
|
+
rb_define_method(c_ComplexBuffer, "ediv!", paddlec_complex_buffer_ediv_inplace, 1);
|
3531
|
+
rb_define_method(c_ComplexBuffer, "**", paddlec_complex_buffer_pow, -1);
|
3532
|
+
rb_define_alias(c_ComplexBuffer, "pow", "**");
|
3533
|
+
rb_define_method(c_ComplexBuffer, "pow!", paddlec_complex_buffer_pow_inplace, 1);
|
3534
|
+
rb_define_method(c_ComplexBuffer, "emod", paddlec_complex_buffer_emod, -1);
|
3535
|
+
rb_define_method(c_ComplexBuffer, "emod!", paddlec_complex_buffer_emod_inplace, 1);
|
3536
|
+
rb_define_method(c_ComplexBuffer, "epow", paddlec_complex_buffer_epow, -1);
|
3537
|
+
rb_define_method(c_ComplexBuffer, "epow!", paddlec_complex_buffer_epow_inplace, 1);
|
3538
|
+
rb_define_method(c_ComplexBuffer, "min", paddlec_complex_buffer_min, -1);
|
3539
|
+
rb_define_method(c_ComplexBuffer, "min!", paddlec_complex_buffer_min_inplace, 1);
|
3540
|
+
rb_define_method(c_ComplexBuffer, "max", paddlec_complex_buffer_max, -1);
|
3541
|
+
rb_define_method(c_ComplexBuffer, "max!", paddlec_complex_buffer_max_inplace, 1);
|
3542
|
+
rb_define_method(c_ComplexBuffer, "minmax", paddlec_complex_buffer_minmax, 0);
|
3543
|
+
rb_define_method(c_ComplexBuffer, "clipp", paddlec_complex_buffer_clipp, -1);
|
3544
|
+
rb_define_method(c_ComplexBuffer, "clipp!", paddlec_complex_buffer_clipp_inplace, -1);
|
3545
|
+
rb_define_method(c_ComplexBuffer, "reverse", paddlec_complex_buffer_reverse, -1);
|
3546
|
+
rb_define_method(c_ComplexBuffer, "reverse!", paddlec_complex_buffer_reverse_inplace, 0);
|
3547
|
+
rb_define_method(c_ComplexBuffer, "sum", paddlec_complex_buffer_sum, 0);
|
3548
|
+
rb_define_method(c_ComplexBuffer, "mean", paddlec_complex_buffer_mean, 0);
|
3549
|
+
rb_define_method(c_ComplexBuffer, "prod", paddlec_complex_buffer_prod, 0);
|
3550
|
+
rb_define_method(c_ComplexBuffer, "eprod", paddlec_complex_buffer_eprod, 0);
|
3551
|
+
rb_define_method(c_ComplexBuffer, "sad", paddlec_complex_buffer_sad, 1);
|
3552
|
+
rb_define_method(c_ComplexBuffer, "ssd", paddlec_complex_buffer_ssd, 1);
|
3553
|
+
rb_define_method(c_ComplexBuffer, "essd", paddlec_complex_buffer_essd, 1);
|
3554
|
+
}
|
3555
|
+
|