FNFT
Loading...
Searching...
No Matches
fnft__misc.h
Go to the documentation of this file.
1/*
2* This file is part of FNFT.
3*
4* FNFT is free software; you can redistribute it and/or
5* modify it under the terms of the version 2 of the GNU General
6* Public License as published by the Free Software Foundation.
7*
8* FNFT is distributed in the hope that it will be useful,
9* but WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program. If not, see <http://www.gnu.org/licenses/>.
15*
16* Contributors:
17* Sander Wahls (TU Delft) 2017-2018, 2023.
18* Shrinivas Chimmalgi (TU Delft) 2019-2020.
19* Peter J. Prins (TU Delft) 2021.
20*/
21
28#ifndef FNFT__MISC_H
29#define FNFT__MISC_H
30
31#include "fnft.h"
32#include <string.h>
33
43void fnft__misc_print_buf(const FNFT_UINT len, FNFT_COMPLEX const * const buf,
44 char const * const varname);
45
58 FNFT_COMPLEX const * const vec_numer, FNFT_COMPLEX const * const vec_exact);
59
72 FNFT_COMPLEX const * const vecA, const FNFT_UINT lenB,
73 FNFT_COMPLEX const * const vecB);
74
84
98 const FNFT_REAL a, const FNFT_REAL b);
99
124 FNFT_COMPLEX * const rearrange_as_well,
125 FNFT_REAL const * const bounding_box);
126
127
141 const FNFT_REAL tol_im);
142
160 FNFT_COMPLEX * const rearrange_as_well,
161 FNFT_REAL const * const bounding_box);
162
176 FNFT_REAL tol);
177
200 FNFT_UINT * const Dsub_ptr, FNFT_COMPLEX ** qsub_ptr,
201 FNFT_UINT * const first_last_index);
202
214{
215 const FNFT_REAL sinc_th=1.0E-8;
216
217 if (FNFT_CABS(x)>=sinc_th)
218 return FNFT_CSIN(x)/x;
219 else
220 return FNFT_CCOS(x/FNFT_CSQRT(3));
221}
222
240{
241 const FNFT_REAL sinc_derivative_th=1.0;
242 FNFT_COMPLEX returnvalue;
243
244 if (FNFT_CABS(x)>=sinc_derivative_th)
245 returnvalue = (FNFT_CCOS(x)-fnft__misc_CSINC(x))/x;
246 else {
247 returnvalue = 0.0;
248 FNFT_COMPLEX x2 = x * x;
249 for (FNFT_UINT n=9; n-->0; )
250 returnvalue = (( n%2 ? 1.0 : -1.0) + x2/(2*n+2) * returnvalue ) / (2*n+3);
251 returnvalue *= x;
252 }
253 return returnvalue;
254}
255
264
285FNFT_INT fnft__misc_resample(const FNFT_UINT D, const FNFT_REAL eps_t, FNFT_COMPLEX const * const q,
286 const FNFT_REAL delta, FNFT_COMPLEX *const q_new);
287
306static inline void fnft__misc_matrix_mult(const FNFT_UINT n,
307 const FNFT_UINT m,
308 const FNFT_UINT p,
309 FNFT_COMPLEX const * const A,
310 FNFT_COMPLEX const * const B,
311 FNFT_COMPLEX * const C){
312 for (FNFT_UINT cn = 0; cn < n; cn++) {
313 for (FNFT_UINT cp = 0; cp < p; cp++) {
314 C[ cn*p + cp] = 0.0;
315 for (FNFT_UINT cm = 0; cm < m; cm++)
316 C[ cn*p + cp ] += A[ cn*m + cm ] * B[ cm*p + cp ];
317 }
318 }
319
320 return;
321}
322
334static inline void fnft__misc_mat_mult_2x2(FNFT_COMPLEX * const U,
335 FNFT_COMPLEX *const T){
336
337 FNFT_COMPLEX TM[4] = { 0 };
338 fnft__misc_matrix_mult(2, 2, 2, U, T, &TM[0]);
339 memcpy(T,TM,4*sizeof(FNFT_COMPLEX));
340
341 return;
342}
343
355static inline void fnft__misc_mat_mult_4x4(FNFT_COMPLEX * const U,
356 FNFT_COMPLEX *const T){
357
358 FNFT_COMPLEX TM[16] = { 0 };
359 fnft__misc_matrix_mult(4, 4, 4, U, T, &TM[0]);
360 memcpy(T,TM,16*sizeof(FNFT_COMPLEX));
361
362 return;
363}
364
377 FNFT_UINT i;
378 FNFT_REAL P, P_1, P_2;
379 if (n == 0)
380 P = 1;
381 else if (n == 1)
382 P = x;
383 else{
384 P_1 = x;
385 P_2 = 1;
386 for (i = 2; i <= n; i++) {
387 P = (2.0*i-1)*x*P_1/i -(i-1.0)*P_2/i;
388 P_2 = P_1;
389 P_1 = P;
390 }
391 }
392 return P;
393}
394
408{
409 // Find max of absolute values of coefficients
410 FNFT_REAL max_abs = 0.0;
411 for (FNFT_UINT i=0; i<len; i++) {
412 const FNFT_REAL cur_abs = FNFT_CABS( v[i] );
413 if (cur_abs > max_abs)
414 max_abs = cur_abs;
415 }
416
417 // Return if polynomial is identical to zero
418 if (max_abs == 0.0)
419 return 0;
420
421 // Otherwise, rescale
422 const FNFT_REAL a = FNFT_FLOOR( FNFT_LOG2(max_abs) );
423 const FNFT_REAL scl = FNFT_POW( 2, -a );
424 for (FNFT_UINT i=0; i<len; i++)
425 v[i] *= scl;
426
427 return (FNFT_INT) a;
428}
429
430#ifdef FNFT_ENABLE_SHORT_NAMES
431#define misc_print_buf(...) fnft__misc_print_buf(__VA_ARGS__)
432#define misc_rel_err(...) fnft__misc_rel_err(__VA_ARGS__)
433#define misc_hausdorff_dist(...) fnft__misc_hausdorff_dist(__VA_ARGS__)
434#define misc_sech(...) fnft__misc_sech(__VA_ARGS__)
435#define misc_l2norm2(...) fnft__misc_l2norm2(__VA_ARGS__)
436#define misc_filter(...) fnft__misc_filter(__VA_ARGS__)
437#define misc_filter_inv(...) fnft__misc_filter_inv(__VA_ARGS__)
438#define misc_filter_nonreal(...) fnft__misc_filter_nonreal(__VA_ARGS__)
439#define misc_merge(...) fnft__misc_merge(__VA_ARGS__)
440#define misc_downsample(...) fnft__misc_downsample(__VA_ARGS__)
441#define misc_CSINC(...) fnft__misc_CSINC(__VA_ARGS__)
442#define misc_CSINC_derivative(...) fnft__misc_CSINC_derivative(__VA_ARGS__)
443#define misc_nextpowerof2(...) fnft__misc_nextpowerof2(__VA_ARGS__)
444#define misc_resample(...) fnft__misc_resample(__VA_ARGS__)
445#define misc_matrix_mult(...) fnft__misc_matrix_mult(__VA_ARGS__)
446#define misc_mat_mult_2x2(...) fnft__misc_mat_mult_2x2(__VA_ARGS__)
447#define misc_mat_mult_4x4(...) fnft__misc_mat_mult_4x4(__VA_ARGS__)
448#define misc_legendre_poly(...) fnft__misc_legendre_poly(__VA_ARGS__)
449#define misc_normalize_vector(...) fnft__misc_normalize_vector(__VA_ARGS__)
450#endif
451
452#endif
FNFT_REAL fnft__misc_rel_err(const FNFT_UINT len, FNFT_COMPLEX const *const vec_numer, FNFT_COMPLEX const *const vec_exact)
Relative l1 error between two vectors.
FNFT_INT fnft__misc_filter_nonreal(FNFT_UINT *N_ptr, FNFT_COMPLEX *const vals, const FNFT_REAL tol_im)
Filter array based on specified tolerance.
FNFT_INT fnft__misc_merge(FNFT_UINT *N_ptr, FNFT_COMPLEX *const vals, FNFT_REAL tol)
Merges elements in an array with distance lower than tol.
void fnft__misc_print_buf(const FNFT_UINT len, FNFT_COMPLEX const *const buf, char const *const varname)
Helper function for debugging. Prints an array in MATLAB style.
static FNFT_INT fnft__misc_normalize_vector(const FNFT_UINT len, FNFT_COMPLEX *const v)
Normalizes a complex vector so that the maximum absolute value is >=1 and <2.
Definition fnft__misc.h:407
FNFT_REAL fnft__misc_l2norm2(const FNFT_UINT N, FNFT_COMPLEX const *const Z, const FNFT_REAL a, const FNFT_REAL b)
Squared l2 norm.
static void fnft__misc_matrix_mult(const FNFT_UINT n, const FNFT_UINT m, const FNFT_UINT p, FNFT_COMPLEX const *const A, FNFT_COMPLEX const *const B, FNFT_COMPLEX *const C)
Multiples two complex valued matrices of any compatible size.
Definition fnft__misc.h:306
static void fnft__misc_mat_mult_2x2(FNFT_COMPLEX *const U, FNFT_COMPLEX *const T)
Multiples two square matrices of size 2.
Definition fnft__misc.h:334
FNFT_UINT fnft__misc_nextpowerof2(const FNFT_UINT number)
Closest larger or equal number that is a power of two.
FNFT_INT fnft__misc_resample(const FNFT_UINT D, const FNFT_REAL eps_t, FNFT_COMPLEX const *const q, const FNFT_REAL delta, FNFT_COMPLEX *const q_new)
Resamples an array.
FNFT_COMPLEX fnft__misc_sech(FNFT_COMPLEX Z)
Hyperbolic secant.
static FNFT_COMPLEX fnft__misc_CSINC(FNFT_COMPLEX x)
Sinc function for complex arguments.
Definition fnft__misc.h:213
FNFT_INT fnft__misc_filter(FNFT_UINT *const N, FNFT_COMPLEX *const vals, FNFT_COMPLEX *const rearrange_as_well, FNFT_REAL const *const bounding_box)
Filters array by retaining elements inside a bounding box.
static FNFT_REAL fnft__misc_legendre_poly(const FNFT_UINT n, const FNFT_REAL x)
This routine returns the nth degree Legendre polynomial at x.
Definition fnft__misc.h:376
FNFT_INT fnft__misc_downsample(const FNFT_UINT D, FNFT_COMPLEX const *const q, FNFT_UINT *const Dsub_ptr, FNFT_COMPLEX **qsub_ptr, FNFT_UINT *const first_last_index)
Downsamples an array.
static void fnft__misc_mat_mult_4x4(FNFT_COMPLEX *const U, FNFT_COMPLEX *const T)
Multiples two square matrices of size 4.
Definition fnft__misc.h:355
static FNFT_COMPLEX fnft__misc_CSINC_derivative(FNFT_COMPLEX x)
Derivative of sinc function for complex arguments.
Definition fnft__misc.h:239
FNFT_INT fnft__misc_filter_inv(FNFT_UINT *const N_ptr, FNFT_COMPLEX *const vals, FNFT_COMPLEX *const rearrange_as_well, FNFT_REAL const *const bounding_box)
Filters array by retaining elements outside a bounding box.
FNFT_REAL fnft__misc_hausdorff_dist(const FNFT_UINT lenA, FNFT_COMPLEX const *const vecA, const FNFT_UINT lenB, FNFT_COMPLEX const *const vecB)
Hausdorff distance between two vectors.
#define FNFT_CCOS(X)
Definition fnft_numtypes.h:264
#define FNFT_CSQRT(X)
Definition fnft_numtypes.h:240
size_t FNFT_UINT
Definition fnft_numtypes.h:62
#define FNFT_FLOOR(X)
Definition fnft_numtypes.h:166
double complex FNFT_COMPLEX
Definition fnft_numtypes.h:47
#define FNFT_CABS(X)
Definition fnft_numtypes.h:204
#define FNFT_POW(X, Y)
Definition fnft_numtypes.h:146
#define FNFT_LOG2(X)
Definition fnft_numtypes.h:140
int32_t FNFT_INT
Definition fnft_numtypes.h:56
#define FNFT_CSIN(X)
Definition fnft_numtypes.h:258
double FNFT_REAL
Definition fnft_numtypes.h:40