paddlec 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+