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.
@@ -0,0 +1,933 @@
1
+ /* Copyright (C) 2019 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 <stdlib.h>
20
+ #include <stdio.h>
21
+ #include <string.h>
22
+ #include <math.h>
23
+ #include "libpaddlec.h"
24
+
25
+
26
+ const char* pdlc_accelerator()
27
+ {
28
+ #if defined __AVX__
29
+ #if !(defined __FMA__ || defined __FMA4__)
30
+ return "AVX";
31
+ #else
32
+ return "AVX-FMA";
33
+ #endif
34
+ #elif defined __SSE__
35
+ return "SSE";
36
+ #elif (defined __ARM_NEON) && ((__ARM_NEON_FP & 4) == 4)
37
+ #ifndef __FP_FAST_FMA
38
+ return "NEON";
39
+ #else
40
+ return "NEON-VFPv4";
41
+ #endif
42
+ #else
43
+ return "";
44
+ #endif
45
+ }
46
+
47
+
48
+ pdlc_buffer_t* pdlc_buffer_new(size_t length)
49
+ {
50
+ pdlc_buffer_t *res;
51
+
52
+ res = malloc(sizeof(pdlc_buffer_t));
53
+ res->capacity = 0;
54
+ res->length = 0;
55
+ res->data = NULL;
56
+
57
+ pdlc_buffer_resize(res, length, 1);
58
+
59
+ return res;
60
+ }
61
+
62
+
63
+ void pdlc_buffer_free(pdlc_buffer_t *buf)
64
+ {
65
+ if (buf == NULL)
66
+ return;
67
+ if (buf->data)
68
+ free(buf->data);
69
+ free(buf);
70
+ }
71
+
72
+
73
+ pdlc_buffer_t* pdlc_buffer_copy(const pdlc_buffer_t *orig)
74
+ {
75
+ pdlc_buffer_t *res = pdlc_buffer_new(orig->length);
76
+ memcpy(res->data, orig->data, orig->length*sizeof(float));
77
+ return res;
78
+ }
79
+
80
+
81
+ void pdlc_buffer_resize(pdlc_buffer_t *buf, size_t new_length, int copy_old_and_zero_excess)
82
+ {
83
+ float *new_data;
84
+ size_t new_capacity;
85
+
86
+ if (new_length <= buf->capacity) {
87
+ if (copy_old_and_zero_excess != 0 && new_length > buf->length)
88
+ memset(buf->data + buf->length, 0, (new_length - buf->length)*sizeof(float));
89
+ buf->length = new_length;
90
+ return;
91
+ }
92
+
93
+ new_capacity = new_length + (new_length >> 2);
94
+ new_data = malloc(new_capacity*sizeof(float));
95
+ if (new_data == NULL) {
96
+ fprintf(stderr, "ERROR: libpaddlec: Cannot allocate %lu bytes of buffer!\n", new_capacity*sizeof(float));
97
+ exit(EXIT_FAILURE);
98
+ }
99
+ if (buf->data != NULL) {
100
+ if (copy_old_and_zero_excess != 0 && buf->length > 0)
101
+ memcpy(new_data, buf->data, buf->length*sizeof(float));
102
+ free(buf->data);
103
+ }
104
+ if (copy_old_and_zero_excess != 0 && new_length > buf->length)
105
+ memset(new_data + buf->length, 0, (new_length - buf->length)*sizeof(float));
106
+ buf->data = new_data;
107
+ buf->capacity = new_capacity;
108
+ buf->length = new_length;
109
+ }
110
+
111
+
112
+ void pdlc_buffer_set(pdlc_buffer_t *buf, float val)
113
+ {
114
+ size_t i;
115
+
116
+ for (i = 0; i < buf->length; i++)
117
+ buf->data[i] = val;
118
+ }
119
+
120
+
121
+ pdlc_complex_buffer_t* pdlc_complex_buffer_new(size_t length)
122
+ {
123
+ pdlc_complex_buffer_t *res;
124
+
125
+ res = malloc(sizeof(pdlc_complex_buffer_t));
126
+ res->capacity = 0;
127
+ res->length = 0;
128
+ res->data = NULL;
129
+
130
+ pdlc_complex_buffer_resize(res, length, 1);
131
+
132
+ return res;
133
+ }
134
+
135
+
136
+ void pdlc_complex_buffer_free(pdlc_complex_buffer_t *buf)
137
+ {
138
+ if (buf == NULL)
139
+ return;
140
+ if (buf->data)
141
+ free(buf->data);
142
+ free(buf);
143
+ }
144
+
145
+
146
+ pdlc_complex_buffer_t* pdlc_complex_buffer_copy(const pdlc_complex_buffer_t *orig)
147
+ {
148
+ pdlc_complex_buffer_t *res = pdlc_complex_buffer_new(orig->length);
149
+ memcpy(res->data, orig->data, orig->length*sizeof(pdlc_complex_t));
150
+ return res;
151
+ }
152
+
153
+
154
+ void pdlc_complex_buffer_resize(pdlc_complex_buffer_t *buf, size_t new_length, int copy_old_and_zero_excess)
155
+ {
156
+ pdlc_complex_t *new_data;
157
+ size_t new_capacity;
158
+
159
+ if (new_length <= buf->capacity) {
160
+ if (copy_old_and_zero_excess != 0 && new_length > buf->length)
161
+ memset(buf->data + buf->length, 0, (new_length - buf->length)*sizeof(pdlc_complex_t));
162
+ buf->length = new_length;
163
+ return;
164
+ }
165
+
166
+ new_capacity = new_length + (new_length >> 2);
167
+ new_data = malloc(new_capacity*sizeof(pdlc_complex_t));
168
+ if (new_data == NULL) {
169
+ fprintf(stderr, "ERROR: libpaddlec: Cannot allocate %lu bytes of buffer!\n", new_capacity*sizeof(pdlc_complex_t));
170
+ exit(EXIT_FAILURE);
171
+ }
172
+ if (buf->data != NULL) {
173
+ if (copy_old_and_zero_excess != 0 && buf->length > 0)
174
+ memcpy(new_data, buf->data, buf->length*sizeof(pdlc_complex_t));
175
+ free(buf->data);
176
+ }
177
+ if (copy_old_and_zero_excess != 0 && new_length > buf->length)
178
+ memset(new_data + buf->length, 0, (new_length - buf->length)*sizeof(pdlc_complex_t));
179
+ buf->data = new_data;
180
+ buf->capacity = new_capacity;
181
+ buf->length = new_length;
182
+ }
183
+
184
+
185
+ void pdlc_complex_buffer_set(pdlc_complex_buffer_t *buf, pdlc_complex_t val)
186
+ {
187
+ size_t i;
188
+
189
+ for (i = 0; i < buf->length; i++)
190
+ buf->data[i] = val;
191
+ }
192
+
193
+
194
+ pdlc_buffer_t* pdlc_buffer_reverse(const pdlc_buffer_t *fbuf, pdlc_buffer_t *res)
195
+ {
196
+ const size_t len = fbuf->length;
197
+ size_t i;
198
+
199
+ if (!res)
200
+ res = pdlc_buffer_new(len);
201
+ else
202
+ pdlc_buffer_resize(res, len, 0);
203
+
204
+ for (i = 0; i < len; i++)
205
+ res->data[i] = fbuf->data[len - 1 - i];
206
+
207
+ return res;
208
+ }
209
+
210
+
211
+ pdlc_buffer_t* pdlc_buffer_reverse_inplace(pdlc_buffer_t *fbuf)
212
+ {
213
+ const size_t lenmone = fbuf->length - 1;
214
+ const size_t half_len = fbuf->length / 2;
215
+ size_t i;
216
+ float tmp;
217
+
218
+ for (i = 0; i < half_len; i++) {
219
+ tmp = fbuf->data[lenmone - i];
220
+ fbuf->data[lenmone - i] = fbuf->data[i];
221
+ fbuf->data[i] = tmp;
222
+ }
223
+
224
+ return fbuf;
225
+ }
226
+
227
+
228
+ pdlc_complex_buffer_t* pdlc_complex_buffer_reverse(const pdlc_complex_buffer_t *cbuf, pdlc_complex_buffer_t *res)
229
+ {
230
+ const size_t len = cbuf->length;
231
+ size_t i;
232
+
233
+ if (!res)
234
+ res = pdlc_complex_buffer_new(len);
235
+ else
236
+ pdlc_complex_buffer_resize(res, len, 0);
237
+
238
+ for (i = 0; i < len; i++)
239
+ res->data[i] = cbuf->data[len - 1 - i];
240
+
241
+ return res;
242
+ }
243
+
244
+
245
+ pdlc_complex_buffer_t* pdlc_complex_buffer_reverse_inplace(pdlc_complex_buffer_t *cbuf)
246
+ {
247
+ const size_t lenmone = cbuf->length - 1;
248
+ const size_t half_len = cbuf->length / 2;
249
+ size_t i;
250
+ pdlc_complex_t tmp;
251
+
252
+ for (i = 0; i < half_len; i++) {
253
+ tmp = cbuf->data[lenmone - i];
254
+ cbuf->data[lenmone - i] = cbuf->data[i];
255
+ cbuf->data[i] = tmp;
256
+ }
257
+
258
+ return cbuf;
259
+ }
260
+
261
+
262
+ float pdlc_buffer_sum(const pdlc_buffer_t *fbuf)
263
+ {
264
+ const size_t len = fbuf->length;
265
+ size_t alen = len;
266
+ size_t i, hlen;
267
+ float *copy;
268
+ float res = 0.0f;
269
+
270
+ if (len < 1)
271
+ return 0.0f;
272
+
273
+ copy = malloc(len*sizeof(float));
274
+ memcpy(copy, fbuf->data, len*sizeof(float));
275
+
276
+ while (alen > 1) {
277
+ hlen = alen / 2;
278
+ for (i = 0; i < hlen; i++)
279
+ copy[i] = copy[2*i] + copy[2*i+1];
280
+ if (alen % 2) {
281
+ copy[i] = copy[2*i];
282
+ alen = hlen + 1;
283
+ }
284
+ else
285
+ alen = hlen;
286
+ }
287
+
288
+ res = copy[0];
289
+
290
+ free(copy);
291
+
292
+ return res;
293
+ }
294
+
295
+
296
+ pdlc_complex_t pdlc_complex_buffer_sum(const pdlc_complex_buffer_t *cbuf)
297
+ {
298
+ const size_t len = cbuf->length;
299
+ size_t alen, hlen, i;
300
+ float *copy;
301
+ pdlc_complex_t res = {0.0f, 0.0f};
302
+
303
+ if (len < 1)
304
+ return res;
305
+
306
+ copy = malloc(len*sizeof(float));
307
+
308
+ alen = len;
309
+ for (i = 0; i < len; i++)
310
+ copy[i] = cbuf->data[i].real;
311
+ while (alen > 1) {
312
+ hlen = alen / 2;
313
+ for (i = 0; i < hlen; i++)
314
+ copy[i] = copy[2*i] + copy[2*i+1];
315
+ if (alen % 2) {
316
+ copy[i] = copy[2*i];
317
+ alen = hlen + 1;
318
+ }
319
+ else
320
+ alen = hlen;
321
+ }
322
+ res.real = copy[0];
323
+
324
+ alen = len;
325
+ for (i = 0; i < len; i++)
326
+ copy[i] = cbuf->data[i].imag;
327
+ while (alen > 1) {
328
+ hlen = alen / 2;
329
+ for (i = 0; i < hlen; i++)
330
+ copy[i] = copy[2*i] + copy[2*i+1];
331
+ if (alen % 2) {
332
+ copy[i] = copy[2*i];
333
+ alen = hlen + 1;
334
+ }
335
+ else
336
+ alen = hlen;
337
+ }
338
+ res.imag = copy[0];
339
+
340
+ free(copy);
341
+
342
+ return res;
343
+ }
344
+
345
+
346
+ float pdlc_buffer_mean(const pdlc_buffer_t *fbuf)
347
+ {
348
+ const float sum = pdlc_buffer_sum(fbuf);
349
+ return sum / (float)fbuf->length;
350
+ }
351
+
352
+
353
+ pdlc_complex_t pdlc_complex_buffer_mean(const pdlc_complex_buffer_t *cbuf)
354
+ {
355
+ pdlc_complex_t res = pdlc_complex_buffer_sum(cbuf);
356
+ res.real = res.real / (float)cbuf->length;
357
+ res.imag = res.imag / (float)cbuf->length;
358
+ return res;
359
+ }
360
+
361
+
362
+ float pdlc_buffer_variance(const pdlc_buffer_t *fbuf)
363
+ {
364
+ const size_t len = fbuf->length;
365
+ size_t i, hlen, alen;
366
+ float *copy;
367
+ float res = 0.0f;
368
+
369
+ if (len < 1)
370
+ return 0.0f;
371
+
372
+ copy = malloc(len*sizeof(float));
373
+
374
+ /* Compute mean */
375
+ memcpy(copy, fbuf->data, len*sizeof(float));
376
+ alen = len;
377
+ while (alen > 1) {
378
+ hlen = alen / 2;
379
+ for (i = 0; i < hlen; i++)
380
+ copy[i] = copy[2*i] + copy[2*i+1];
381
+ if (alen % 2) {
382
+ copy[i] = copy[2*i];
383
+ alen = hlen + 1;
384
+ }
385
+ else
386
+ alen = hlen;
387
+ }
388
+ res = copy[0] / (float)len;
389
+
390
+ /* Compute variance */
391
+ for (i = 0; i < len; i++)
392
+ copy[i] = fbuf->data[i] * fbuf->data[i];
393
+ alen = len;
394
+ while (alen > 1) {
395
+ hlen = alen / 2;
396
+ for (i = 0; i < hlen; i++)
397
+ copy[i] = copy[2*i] + copy[2*i+1];
398
+ if (alen % 2) {
399
+ copy[i] = copy[2*i];
400
+ alen = hlen + 1;
401
+ }
402
+ else
403
+ alen = hlen;
404
+ }
405
+ res = copy[0] / (float)len - res*res;
406
+
407
+ free(copy);
408
+
409
+ return res;
410
+ }
411
+
412
+
413
+ float pdlc_buffer_standard_deviation(const pdlc_buffer_t *fbuf)
414
+ {
415
+ return sqrtf(pdlc_buffer_variance(fbuf));
416
+ }
417
+
418
+
419
+ float pdlc_buffer_prod(const pdlc_buffer_t *fbuf)
420
+ {
421
+ const size_t len = fbuf->length;
422
+ size_t i;
423
+ float res = 1.0f;
424
+
425
+ for (i = 0; i < len; i++)
426
+ res *= fbuf->data[i];
427
+
428
+ return res;
429
+ }
430
+
431
+
432
+ pdlc_complex_t pdlc_complex_buffer_prod(const pdlc_complex_buffer_t *cbuf)
433
+ {
434
+ const size_t len = cbuf->length;
435
+ size_t i;
436
+ pdlc_complex_t tmp;
437
+ pdlc_complex_t res = {1.0f, 0.0f};
438
+
439
+ for (i = 0; i < len; i++) {
440
+ tmp.real = res.real * cbuf->data[i].real - res.imag * cbuf->data[i].imag;
441
+ tmp.imag = res.real * cbuf->data[i].imag + res.imag * cbuf->data[i].real;
442
+ res = tmp;
443
+ }
444
+
445
+ return res;
446
+ }
447
+
448
+
449
+ pdlc_complex_t pdlc_complex_buffer_eprod(const pdlc_complex_buffer_t *cbuf)
450
+ {
451
+ const size_t len = cbuf->length;
452
+ size_t i;
453
+ pdlc_complex_t res = {1.0f, 1.0f};
454
+
455
+ for (i = 0; i < len; i++) {
456
+ res.real *= cbuf->data[i].real;
457
+ res.imag *= cbuf->data[i].imag;
458
+ }
459
+
460
+ return res;
461
+ }
462
+
463
+
464
+ float pdlc_buffer_fb_fs_sad(const pdlc_buffer_t *fbuf, float other)
465
+ {
466
+ const size_t len = fbuf->length;
467
+ size_t alen = len;
468
+ size_t i, hlen;
469
+ float *copy;
470
+ float res = 0.0f;
471
+
472
+ if (len < 1)
473
+ return 0.0f;
474
+
475
+ copy = malloc(len*sizeof(float));
476
+ for (i = 0; i < len; i++)
477
+ copy[i] = fabsf(fbuf->data[i] - other);
478
+
479
+ while (alen > 1) {
480
+ hlen = alen / 2;
481
+ for (i = 0; i < hlen; i++)
482
+ copy[i] = copy[2*i] + copy[2*i+1];
483
+ if (alen % 2) {
484
+ copy[i] = copy[2*i];
485
+ alen = hlen + 1;
486
+ }
487
+ else
488
+ alen = hlen;
489
+ }
490
+
491
+ res = copy[0];
492
+
493
+ free(copy);
494
+
495
+ return res;
496
+ }
497
+
498
+
499
+ float pdlc_buffer_fb_fb_sad(const pdlc_buffer_t *fbuf, const pdlc_buffer_t *other)
500
+ {
501
+ size_t len = fbuf->length;
502
+ size_t alen = len;
503
+ size_t i, hlen;
504
+ float *copy;
505
+ float res = 0.0f;
506
+
507
+ if (len > other->length)
508
+ len = other->length;
509
+
510
+ if (len < 1)
511
+ return 0.0f;
512
+
513
+ copy = malloc(len*sizeof(float));
514
+ for (i = 0; i < len; i++)
515
+ copy[i] = fabsf(fbuf->data[i] - other->data[i]);
516
+
517
+ while (alen > 1) {
518
+ hlen = alen / 2;
519
+ for (i = 0; i < hlen; i++)
520
+ copy[i] = copy[2*i] + copy[2*i+1];
521
+ if (alen % 2) {
522
+ copy[i] = copy[2*i];
523
+ alen = hlen + 1;
524
+ }
525
+ else
526
+ alen = hlen;
527
+ }
528
+
529
+ res = copy[0];
530
+
531
+ free(copy);
532
+
533
+ return res;
534
+ }
535
+
536
+
537
+ pdlc_complex_t pdlc_complex_buffer_cb_cs_sad(const pdlc_complex_buffer_t *cbuf, pdlc_complex_t other)
538
+ {
539
+ const size_t len = cbuf->length;
540
+ size_t alen, hlen, i;
541
+ float *copy;
542
+ pdlc_complex_t res = {0.0f, 0.0f};
543
+
544
+ if (len < 1)
545
+ return res;
546
+
547
+ copy = malloc(len*sizeof(float));
548
+
549
+ alen = len;
550
+ for (i = 0; i < len; i++)
551
+ copy[i] = fabsf(cbuf->data[i].real - other.real);
552
+ while (alen > 1) {
553
+ hlen = alen / 2;
554
+ for (i = 0; i < hlen; i++)
555
+ copy[i] = copy[2*i] + copy[2*i+1];
556
+ if (alen % 2) {
557
+ copy[i] = copy[2*i];
558
+ alen = hlen + 1;
559
+ }
560
+ else
561
+ alen = hlen;
562
+ }
563
+ res.real = copy[0];
564
+
565
+ alen = len;
566
+ for (i = 0; i < len; i++)
567
+ copy[i] = fabsf(cbuf->data[i].imag - other.imag);
568
+ while (alen > 1) {
569
+ hlen = alen / 2;
570
+ for (i = 0; i < hlen; i++)
571
+ copy[i] = copy[2*i] + copy[2*i+1];
572
+ if (alen % 2) {
573
+ copy[i] = copy[2*i];
574
+ alen = hlen + 1;
575
+ }
576
+ else
577
+ alen = hlen;
578
+ }
579
+ res.imag = copy[0];
580
+
581
+ free(copy);
582
+
583
+ return res;
584
+ }
585
+
586
+
587
+ pdlc_complex_t pdlc_complex_buffer_cb_cb_sad(const pdlc_complex_buffer_t *cbuf, const pdlc_complex_buffer_t *other)
588
+ {
589
+ size_t len = cbuf->length;
590
+ size_t alen, hlen, i;
591
+ float *copy;
592
+ pdlc_complex_t res = {0.0f, 0.0f};
593
+
594
+ if (len > other->length)
595
+ len = other->length;
596
+
597
+ if (len < 1)
598
+ return res;
599
+
600
+ copy = malloc(len*sizeof(float));
601
+
602
+ alen = len;
603
+ for (i = 0; i < len; i++)
604
+ copy[i] = fabsf(cbuf->data[i].real - other->data[i].real);
605
+ while (alen > 1) {
606
+ hlen = alen / 2;
607
+ for (i = 0; i < hlen; i++)
608
+ copy[i] = copy[2*i] + copy[2*i+1];
609
+ if (alen % 2) {
610
+ copy[i] = copy[2*i];
611
+ alen = hlen + 1;
612
+ }
613
+ else
614
+ alen = hlen;
615
+ }
616
+ res.real = copy[0];
617
+
618
+ alen = len;
619
+ for (i = 0; i < len; i++)
620
+ copy[i] = fabsf(cbuf->data[i].imag - other->data[i].imag);
621
+ while (alen > 1) {
622
+ hlen = alen / 2;
623
+ for (i = 0; i < hlen; i++)
624
+ copy[i] = copy[2*i] + copy[2*i+1];
625
+ if (alen % 2) {
626
+ copy[i] = copy[2*i];
627
+ alen = hlen + 1;
628
+ }
629
+ else
630
+ alen = hlen;
631
+ }
632
+ res.imag = copy[0];
633
+
634
+ free(copy);
635
+
636
+ return res;
637
+ }
638
+
639
+
640
+ float pdlc_buffer_fb_fs_ssd(const pdlc_buffer_t *fbuf, float other)
641
+ {
642
+ const size_t len = fbuf->length;
643
+ size_t alen = len;
644
+ size_t i, hlen;
645
+ float *copy;
646
+ float res = 0.0f;
647
+
648
+ if (len < 1)
649
+ return 0.0f;
650
+
651
+ copy = malloc(len*sizeof(float));
652
+ for (i = 0; i < len; i++)
653
+ copy[i] = (fbuf->data[i] - other)*(fbuf->data[i] - other);
654
+
655
+ while (alen > 1) {
656
+ hlen = alen / 2;
657
+ for (i = 0; i < hlen; i++)
658
+ copy[i] = copy[2*i] + copy[2*i+1];
659
+ if (alen % 2) {
660
+ copy[i] = copy[2*i];
661
+ alen = hlen + 1;
662
+ }
663
+ else
664
+ alen = hlen;
665
+ }
666
+
667
+ res = copy[0];
668
+
669
+ free(copy);
670
+
671
+ return res;
672
+ }
673
+
674
+
675
+ float pdlc_buffer_fb_fb_ssd(const pdlc_buffer_t *fbuf, const pdlc_buffer_t *other)
676
+ {
677
+ size_t len = fbuf->length;
678
+ size_t alen = len;
679
+ size_t i, hlen;
680
+ float *copy;
681
+ float res = 0.0f;
682
+
683
+ if (len > other->length)
684
+ len = other->length;
685
+
686
+ if (len < 1)
687
+ return 0.0f;
688
+
689
+ copy = malloc(len*sizeof(float));
690
+ for (i = 0; i < len; i++)
691
+ copy[i] = (fbuf->data[i] - other->data[i])*(fbuf->data[i] - other->data[i]);
692
+
693
+ while (alen > 1) {
694
+ hlen = alen / 2;
695
+ for (i = 0; i < hlen; i++)
696
+ copy[i] = copy[2*i] + copy[2*i+1];
697
+ if (alen % 2) {
698
+ copy[i] = copy[2*i];
699
+ alen = hlen + 1;
700
+ }
701
+ else
702
+ alen = hlen;
703
+ }
704
+
705
+ res = copy[0];
706
+
707
+ free(copy);
708
+
709
+ return res;
710
+ }
711
+
712
+
713
+ pdlc_complex_t pdlc_complex_buffer_cb_cs_essd(const pdlc_complex_buffer_t *cbuf, pdlc_complex_t other)
714
+ {
715
+ const size_t len = cbuf->length;
716
+ size_t alen, hlen, i;
717
+ float *copy;
718
+ pdlc_complex_t res = {0.0f, 0.0f};
719
+
720
+ if (len < 1)
721
+ return res;
722
+
723
+ copy = malloc(len*sizeof(float));
724
+
725
+ alen = len;
726
+ for (i = 0; i < len; i++)
727
+ copy[i] = (cbuf->data[i].real - other.real)*(cbuf->data[i].real - other.real);
728
+ while (alen > 1) {
729
+ hlen = alen / 2;
730
+ for (i = 0; i < hlen; i++)
731
+ copy[i] = copy[2*i] + copy[2*i+1];
732
+ if (alen % 2) {
733
+ copy[i] = copy[2*i];
734
+ alen = hlen + 1;
735
+ }
736
+ else
737
+ alen = hlen;
738
+ }
739
+ res.real = copy[0];
740
+
741
+ alen = len;
742
+ for (i = 0; i < len; i++)
743
+ copy[i] = (cbuf->data[i].imag - other.imag)*(cbuf->data[i].imag - other.imag);
744
+ while (alen > 1) {
745
+ hlen = alen / 2;
746
+ for (i = 0; i < hlen; i++)
747
+ copy[i] = copy[2*i] + copy[2*i+1];
748
+ if (alen % 2) {
749
+ copy[i] = copy[2*i];
750
+ alen = hlen + 1;
751
+ }
752
+ else
753
+ alen = hlen;
754
+ }
755
+ res.imag = copy[0];
756
+
757
+ free(copy);
758
+
759
+ return res;
760
+ }
761
+
762
+
763
+ pdlc_complex_t pdlc_complex_buffer_cb_cb_essd(const pdlc_complex_buffer_t *cbuf, const pdlc_complex_buffer_t *other)
764
+ {
765
+ size_t len = cbuf->length;
766
+ size_t alen, hlen, i;
767
+ float *copy;
768
+ pdlc_complex_t res = {0.0f, 0.0f};
769
+
770
+ if (len > other->length)
771
+ len = other->length;
772
+
773
+ if (len < 1)
774
+ return res;
775
+
776
+ copy = malloc(len*sizeof(float));
777
+
778
+ alen = len;
779
+ for (i = 0; i < len; i++)
780
+ copy[i] = (cbuf->data[i].real - other->data[i].real)*(cbuf->data[i].real - other->data[i].real);
781
+ while (alen > 1) {
782
+ hlen = alen / 2;
783
+ for (i = 0; i < hlen; i++)
784
+ copy[i] = copy[2*i] + copy[2*i+1];
785
+ if (alen % 2) {
786
+ copy[i] = copy[2*i];
787
+ alen = hlen + 1;
788
+ }
789
+ else
790
+ alen = hlen;
791
+ }
792
+ res.real = copy[0];
793
+
794
+ alen = len;
795
+ for (i = 0; i < len; i++)
796
+ copy[i] = (cbuf->data[i].imag - other->data[i].imag)*(cbuf->data[i].imag - other->data[i].imag);
797
+ while (alen > 1) {
798
+ hlen = alen / 2;
799
+ for (i = 0; i < hlen; i++)
800
+ copy[i] = copy[2*i] + copy[2*i+1];
801
+ if (alen % 2) {
802
+ copy[i] = copy[2*i];
803
+ alen = hlen + 1;
804
+ }
805
+ else
806
+ alen = hlen;
807
+ }
808
+ res.imag = copy[0];
809
+
810
+ free(copy);
811
+
812
+ return res;
813
+ }
814
+
815
+
816
+ pdlc_complex_t pdlc_complex_buffer_cb_cs_ssd(const pdlc_complex_buffer_t *cbuf, pdlc_complex_t other)
817
+ {
818
+ const size_t len = cbuf->length;
819
+ size_t alen, hlen, i;
820
+ float *copy;
821
+ pdlc_complex_t tmp;
822
+ pdlc_complex_t res = {0.0f, 0.0f};
823
+
824
+ if (len < 1)
825
+ return res;
826
+
827
+ copy = malloc(len*sizeof(float));
828
+
829
+ alen = len;
830
+ for (i = 0; i < len; i++) {
831
+ tmp.real = cbuf->data[i].real - other.real;
832
+ tmp.imag = cbuf->data[i].imag - other.imag;
833
+ copy[i] = tmp.real * tmp.real - tmp.imag * tmp.imag;
834
+ }
835
+ while (alen > 1) {
836
+ hlen = alen / 2;
837
+ for (i = 0; i < hlen; i++)
838
+ copy[i] = copy[2*i] + copy[2*i+1];
839
+ if (alen % 2) {
840
+ copy[i] = copy[2*i];
841
+ alen = hlen + 1;
842
+ }
843
+ else
844
+ alen = hlen;
845
+ }
846
+ res.real = copy[0];
847
+
848
+ alen = len;
849
+ for (i = 0; i < len; i++) {
850
+ tmp.real = cbuf->data[i].real - other.real;
851
+ tmp.imag = cbuf->data[i].imag - other.imag;
852
+ copy[i] = 2.0f * tmp.real * tmp.imag;
853
+ }
854
+ while (alen > 1) {
855
+ hlen = alen / 2;
856
+ for (i = 0; i < hlen; i++)
857
+ copy[i] = copy[2*i] + copy[2*i+1];
858
+ if (alen % 2) {
859
+ copy[i] = copy[2*i];
860
+ alen = hlen + 1;
861
+ }
862
+ else
863
+ alen = hlen;
864
+ }
865
+ res.imag = copy[0];
866
+
867
+ free(copy);
868
+
869
+ return res;
870
+ }
871
+
872
+
873
+ pdlc_complex_t pdlc_complex_buffer_cb_cb_ssd(const pdlc_complex_buffer_t *cbuf, const pdlc_complex_buffer_t *other)
874
+ {
875
+ size_t len = cbuf->length;
876
+ size_t alen, hlen, i;
877
+ float *copy;
878
+ pdlc_complex_t tmp;
879
+ pdlc_complex_t res = {0.0f, 0.0f};
880
+
881
+ if (len > other->length)
882
+ len = other->length;
883
+
884
+ if (len < 1)
885
+ return res;
886
+
887
+ copy = malloc(len*sizeof(float));
888
+
889
+ alen = len;
890
+ for (i = 0; i < len; i++) {
891
+ tmp.real = cbuf->data[i].real - other->data[i].real;
892
+ tmp.imag = cbuf->data[i].imag - other->data[i].imag;
893
+ copy[i] = tmp.real * tmp.real - tmp.imag * tmp.imag;
894
+ }
895
+ while (alen > 1) {
896
+ hlen = alen / 2;
897
+ for (i = 0; i < hlen; i++)
898
+ copy[i] = copy[2*i] + copy[2*i+1];
899
+ if (alen % 2) {
900
+ copy[i] = copy[2*i];
901
+ alen = hlen + 1;
902
+ }
903
+ else
904
+ alen = hlen;
905
+ }
906
+ res.real = copy[0];
907
+
908
+ alen = len;
909
+ for (i = 0; i < len; i++)
910
+ for (i = 0; i < len; i++) {
911
+ tmp.real = cbuf->data[i].real - other->data[i].real;
912
+ tmp.imag = cbuf->data[i].imag - other->data[i].imag;
913
+ copy[i] = 2.0f * tmp.real * tmp.imag;
914
+ }
915
+ while (alen > 1) {
916
+ hlen = alen / 2;
917
+ for (i = 0; i < hlen; i++)
918
+ copy[i] = copy[2*i] + copy[2*i+1];
919
+ if (alen % 2) {
920
+ copy[i] = copy[2*i];
921
+ alen = hlen + 1;
922
+ }
923
+ else
924
+ alen = hlen;
925
+ }
926
+ res.imag = copy[0];
927
+
928
+ free(copy);
929
+
930
+ return res;
931
+ }
932
+
933
+