36 #define MIN(a,b) ((a < b) ? (a) : (b))
37 #define MAX(a,b) ((a > b) ? (a) : (b))
39 double get_max_error(complex
double *expected, complex
double *actual,
int n);
44 int main(
int argc,
char **argv)
46 so3_parameters_t parameters = {};
48 complex
double *flmn_orig, *flmn_syn_direct, *flmn_syn_ssht;
49 complex
double *f_direct, *f_ssht;
50 double *f_real_direct, *f_real_ssht;
52 clock_t time_start, time_end, time_start_ssht, time_end_ssht, time_start_direct, time_end_direct;
53 int i, sampling_scheme, n_order, storage_mode, n_mode, real, routine, steerable;
56 const char *n_order_str[SO3_N_ORDER_SIZE];
57 const char *storage_mode_str[SO3_STORAGE_SIZE];
58 const char *n_mode_str[SO3_N_MODE_SIZE];
59 const char *reality_str[2];
61 const char *sampling_str[2];
62 const char *steerable_str[2];
64 n_order_str[SO3_N_ORDER_ZERO_FIRST] =
"n = 0 first";
65 n_order_str[SO3_N_ORDER_NEGATIVE_FIRST] =
"n = -N+1 first";
67 storage_mode_str[SO3_STORAGE_PADDED] =
"PADDED storage";
68 storage_mode_str[SO3_STORAGE_COMPACT] =
"COMPACT storage";
70 n_mode_str[SO3_N_MODE_ALL] =
"ALL n";
71 n_mode_str[SO3_N_MODE_EVEN] =
"only EVEN n";
72 n_mode_str[SO3_N_MODE_ODD] =
"only ODD n";
73 n_mode_str[SO3_N_MODE_MAXIMUM] =
"only |n| = N-1";
74 n_mode_str[SO3_N_MODE_L] =
"only |n| = el";
76 reality_str[0] =
"COMPLEX";
77 reality_str[1] =
"REAL";
82 sampling_str[0] =
"MW";
83 sampling_str[1] =
"MWSS";
85 steerable_str[0] =
"NOT STEERABLE";
86 steerable_str[1] =
"STEERABLE";
93 double errors[2][SO3_SAMPLING_SIZE][SO3_N_MODE_SIZE][SO3_STORAGE_SIZE][SO3_N_MODE_SIZE][2];
94 double durations_forward[2][SO3_SAMPLING_SIZE][SO3_N_MODE_SIZE][SO3_STORAGE_SIZE][SO3_N_MODE_SIZE][2];
95 double durations_inverse[2][SO3_SAMPLING_SIZE][SO3_N_MODE_SIZE][SO3_STORAGE_SIZE][SO3_N_MODE_SIZE][2];
120 seed = atoi(argv[4]);
125 parameters.verbosity = 0;
129 flmn_orig = malloc((2*N-1)*L*L *
sizeof *flmn_orig);
130 SO3_ERROR_MEM_ALLOC_CHECK(flmn_orig);
131 flmn_syn_direct = malloc((2*N-1)*L*L *
sizeof *flmn_syn_direct);
132 SO3_ERROR_MEM_ALLOC_CHECK(flmn_syn_direct);
133 flmn_syn_ssht = malloc((2*N-1)*L*L *
sizeof *flmn_syn_ssht);
134 SO3_ERROR_MEM_ALLOC_CHECK(flmn_syn_ssht);
138 f_direct = malloc((2*L)*(L+1)*(2*N-1) *
sizeof *f_direct);
139 SO3_ERROR_MEM_ALLOC_CHECK(f_direct);
140 f_real_direct = malloc((2*L)*(L+1)*(2*N-1) *
sizeof *f_real_direct);
141 SO3_ERROR_MEM_ALLOC_CHECK(f_real_direct);
142 f_ssht = malloc((2*L)*(L+1)*(2*N-1) *
sizeof *f_ssht);
143 SO3_ERROR_MEM_ALLOC_CHECK(f_ssht);
144 f_real_ssht = malloc((2*L)*(L+1)*(2*N-1) *
sizeof *f_real_ssht);
145 SO3_ERROR_MEM_ALLOC_CHECK(f_real_ssht);
149 printf(
"SO3 test program (C implementation)\n");
150 printf(
"================================================================\n");
155 for (n_mode = 0; n_mode < 2; ++ n_mode)
157 parameters.n_mode = n_mode;
159 for (real = 0; real < 1; ++real)
161 parameters.reality = real;
164 for (sampling_scheme = 0; sampling_scheme < 1; ++sampling_scheme)
166 parameters.sampling_scheme = sampling_scheme;
171 for (n_order = 0; n_order < 1; ++n_order)
173 parameters.n_order = n_order;
176 for (storage_mode = 0; storage_mode < 1; ++storage_mode)
178 parameters.storage = storage_mode;
180 for (steerable = 0; steerable < 2; ++steerable)
182 parameters.steerable = steerable;
184 durations_inverse[steerable][sampling_scheme][n_order][storage_mode][n_mode][real] = 0.0;
185 durations_forward[steerable][sampling_scheme][n_order][storage_mode][n_mode][real] = 0.0;
186 errors[steerable][sampling_scheme][n_order][storage_mode][n_mode][real] = 0.0;
189 printf(
"Testing a %s signal with %s with %s sampling using %s with %s. N-Mode: %s. Running %d times: ",
191 steerable_str[steerable],
192 sampling_str[sampling_scheme],
193 storage_mode_str[storage_mode],
194 n_order_str[n_order],
200 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
201 printf(
"Tot Variation:");
203 printf(
" Inv Variation:");
205 printf(
" Direct Error: ");
207 printf(
" SSHT Error:");
209 printf(
" Inv T Direct:");
211 printf(
" For T Direct:");
213 printf(
" Inv T SSHT:");
215 printf(
" For T SSHT:\n");
216 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
221 double duration, tot, tot_inverse, error_direct, error_ssht;
222 double inverse_duration_ssht, forward_duration_ssht;
223 double inverse_duration_direct, forward_duration_direct;
228 for (j = 0; j < (2*N-1)*L*L; ++j)
230 flmn_syn_direct[j] = 0.0;
231 flmn_syn_ssht[j] = 0.0;
245 time_start = clock();
247 time_start_direct = clock();
250 time_end_direct = clock();
252 inverse_duration_direct = (time_end_direct - time_start_direct)/ (
double)CLOCKS_PER_SEC;
254 time_start_ssht = clock();
257 time_end_ssht = clock();
259 inverse_duration_ssht = (time_end_ssht - time_start_ssht)/ (
double)CLOCKS_PER_SEC;
263 duration = (time_end - time_start) / (
double)CLOCKS_PER_SEC;
264 if (!i || duration < durations_inverse[steerable][sampling_scheme][n_order][storage_mode][n_mode][real])
265 durations_inverse[steerable][sampling_scheme][n_order][storage_mode][n_mode][real] = duration;
269 time_start = clock();
271 time_start_direct = clock();
274 time_end_direct = clock();
276 forward_duration_direct = (time_end_direct - time_start_direct)/ (
double)CLOCKS_PER_SEC;
278 time_start_ssht = clock();
281 time_end_ssht = clock();
283 forward_duration_ssht = (time_end_ssht - time_start_ssht)/ (
double)CLOCKS_PER_SEC;
287 duration = (time_end - time_start) / (
double)CLOCKS_PER_SEC;
288 if (!i || duration < durations_forward[steerable][sampling_scheme][n_order][storage_mode][n_mode][real])
289 durations_forward[steerable][sampling_scheme][n_order][storage_mode][n_mode][real] = duration;
292 errors[steerable][sampling_scheme][n_order][storage_mode][n_mode][real] +=
get_max_error(flmn_orig, flmn_syn_ssht, flmn_size)/
NREPEAT;
307 tot =
get_max_error(flmn_syn_direct, flmn_syn_ssht, flmn_size);
309 if (real) tot_inverse =
get_max_error(f_real_direct, f_real_ssht, flmn_size);
310 else tot_inverse =
get_max_error(f_direct, f_ssht, flmn_size);
312 error_direct =
get_max_error(flmn_orig, flmn_syn_direct, flmn_size);
313 error_ssht =
get_max_error(flmn_orig, flmn_syn_ssht, flmn_size);
317 printf(
"%.7e", tot_inverse);
319 printf(
"%.7e", error_direct);
321 printf(
"%.7e", error_ssht);
323 printf(
"%.7e", inverse_duration_direct);
325 printf(
"%.7e", forward_duration_direct);
327 printf(
"%.7e", inverse_duration_ssht);
329 printf(
"%.7e\n", forward_duration_ssht);
339 if (show_arrays == 1)
345 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
347 printf(
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SSHT flmn real component ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
348 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
349 for (
int k = 0; k < (2*N-1)*L*L; ++k)
353 printf(
"|| %d ||",k);
355 if (k > 9 && k < 100)
357 printf(
"|| %d ||",k);
361 printf(
"|| %d ||",k);
364 if (creal(flmn_syn_ssht[k]) >= 0.0)
366 if (creal(flmn_syn_ssht[k]) == 0.0) printf(
" --------- ");
367 else printf(
" %.3e ", creal(flmn_syn_ssht[k]));
371 printf(
"%.3e ", creal(flmn_syn_ssht[k]));
383 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
385 printf(
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DIRECT flmn real component ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
386 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
387 for (
int h = 0; h < (2*N-1)*L*L; ++h)
391 printf(
"|| %d ||",h);
393 if (h > 9 && h < 100)
395 printf(
"|| %d ||",h);
399 printf(
"|| %d ||",h);
402 if (creal(flmn_syn_direct[h]) >= 0.0)
404 if (creal(flmn_syn_direct[h]) == 0.0) printf(
" --------- ");
405 else printf(
" %.3e ", creal(flmn_syn_direct[h]));
409 printf(
"%.3e ", creal(flmn_syn_direct[h]));
422 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
424 printf(
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TRUE flmn real component~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
425 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
426 for (
int r = 0; r < (2*N-1)*L*L; ++r)
430 printf(
"|| %d ||",r);
432 if (r > 9 && r < 100)
434 printf(
"|| %d ||",r);
438 printf(
"|| %d ||",r);
441 if (creal(flmn_orig[r]) >= 0.0)
443 if (creal(flmn_orig[r]) == 0.0) printf(
" --------- ");
444 else printf(
" %.3e ", creal(flmn_orig[r]));
448 printf(
"%.3e ", creal(flmn_orig[r]));
460 if (show_arrays == 2)
466 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
468 printf(
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SSHT real part of f ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
469 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
470 for (
int k = 0; k < (2*N-1)*L*L; ++k)
474 printf(
"|| %d ||",k);
476 if (k > 9 && k < 100)
478 printf(
"|| %d ||",k);
482 printf(
"|| %d ||",k);
485 if (creal(f_ssht[k]) >= 0.0)
487 if (creal(f_ssht[k]) == 0.0) printf(
" --------- ");
488 else printf(
" %.3e ", creal(f_ssht[k]));
492 printf(
"%.3e ", creal(f_ssht[k]));
504 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
506 printf(
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DIRECT real part of f ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
507 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
508 for (
int h = 0; h < (2*N-1)*L*L; ++h)
512 printf(
"|| %d ||",h);
514 if (h > 9 && h < 100)
516 printf(
"|| %d ||",h);
520 printf(
"|| %d ||",h);
523 if (creal(f_direct[h]) >= 0.0)
525 if (creal(f_direct[h]) == 0.0) printf(
" --------- ");
526 else printf(
" %.3e ", creal(f_direct[h]));
530 printf(
"%.3e ", creal(f_direct[h]));
543 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
545 printf(
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Difference between real part of f's ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
546 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
547 for (
int r = 0; r < (2*N-1)*L*L; ++r)
551 printf(
"|| %d ||",r);
553 if (r > 9 && r < 100)
555 printf(
"|| %d ||",r);
559 printf(
"|| %d ||",r);
562 if (creal(f_direct[r] - f_ssht[r]) >= 0.0)
564 if ((creal(f_direct[r]) - creal(f_ssht[r])) <= 0.0000000000001) printf(
" --------- ");
565 else printf(
" %.3e ", (creal(f_direct[r]) - creal(f_ssht[r])));
569 if ((creal(f_direct[r]) - creal(f_ssht[r])) >= -0.0000000000001) printf(
" --------- ");
570 else printf(
"%.3e ", (creal(f_direct[r]) - creal(f_ssht[r])));
585 printf(
"----------------------------------------------------------------------------------------------------------------------------------------------------------\n");
596 free(flmn_syn_direct);
605 printf(
"================================================================\n");
606 printf(
"Summary\n\n");
607 printf(
"Runs = %40d\n",
NREPEAT);
608 printf(
"L0 = %40d\n", L0);
609 printf(
"L = %40d\n", L);
610 printf(
"N = %40d\n\n", N);
612 for (steerable = 1; steerable < 2; ++steerable)
615 printf(
"Results for %s...\n", steerable_str[steerable]);
619 for (real = 0; real < 2; ++real)
624 for (sampling_scheme = 0; sampling_scheme < 1; ++sampling_scheme)
629 for (storage_mode = 0; storage_mode < 1; ++storage_mode)
635 for (n_order = 0; n_order < SO3_N_ORDER_SIZE - real; ++n_order)
639 for (n_mode = 0; n_mode < SO3_N_MODE_SIZE; ++ n_mode)
657 double get_max_error(complex
double *expected, complex
double *actual,
int n)
660 double error, maxError = 0;
662 for (i = 0; i < n; ++i)
664 error = cabs(expected[i] - actual[i]);
665 maxError =
MAX(error, maxError);
688 complex
double *flmn,
689 const so3_parameters_t *parameters,
693 int i, el, m, n, n_start, n_stop, n_inc, ind;
699 for (i = 0; i < (2*N-1)*L*L; ++i)
702 switch (parameters->n_mode)
710 case SO3_N_MODE_EVEN:
711 n_start = ((N-1) % 2 == 0) ? -N+1 : -N+2;
712 n_stop = ((N-1) % 2 == 0) ? N-1 : N-2;
716 n_start = ((N-1) % 2 != 0) ? -N+1 : -N+2;
717 n_stop = ((N-1) % 2 != 0) ? N-1 : N-2;
720 case SO3_N_MODE_MAXIMUM:
729 SO3_ERROR_GENERIC(
"Invalid n-mode.");
732 for (n = n_start; n <= n_stop; n += n_inc)
734 for (el =
MAX(L0, abs(n)); el < L; ++el)
736 if (parameters->n_mode == SO3_N_MODE_L && el != abs(n))
739 for (m = -el; m <= el; ++m)
742 flmn[ind] = (2.0*
ran2_dp(seed) - 1.0) + I * (2.0*
ran2_dp(seed) - 1.0);
768 complex
double *flmn,
769 const so3_parameters_t *parameters,
773 int i, el, m, n, n_start, n_stop, n_inc, ind;
780 for (i = 0; i < (2*N-1)*L*L; ++i)
783 switch (parameters->n_mode)
791 case SO3_N_MODE_EVEN:
793 n_stop = ((N-1) % 2 == 0) ? N-1 : N-2;
798 n_stop = ((N-1) % 2 != 0) ? N-1 : N-2;
801 case SO3_N_MODE_MAXIMUM:
807 SO3_ERROR_GENERIC(
"Invalid n-mode.");
810 for (n = n_start; n <= n_stop; n += n_inc)
815 for (el = L0; el < L; ++el)
817 if (parameters->n_mode == SO3_N_MODE_L && el != 0)
821 flmn[ind] = (2.0*
ran2_dp(seed) - 1.0);
826 for (el = L0; el < L; ++el)
828 if (parameters->n_mode == SO3_N_MODE_L && el != 0)
831 for (m = 1; m <= el; ++m)
833 real = (2.0*
ran2_dp(seed) - 1.0);
834 imag = (2.0*
ran2_dp(seed) - 1.0);
836 flmn[ind] = real + imag * I;
838 flmn[ind] = real - imag * I;
840 flmn[ind] = - real + imag * I;
842 flmn[ind] = real - imag * I;
848 for (el =
MAX(L0, n); el < L; ++el)
850 if (parameters->n_mode == SO3_N_MODE_L && el != n)
853 for (m = -el; m <= el; ++m)
857 flmn[ind] = (2.0*
ran2_dp(seed) - 1.0) + I * (2.0*
ran2_dp(seed) - 1.0);
879 int IM1=2147483563,IM2=2147483399,IMM1=IM1-1,
880 IA1=40014,IA2=40692,IQ1=53668,IQ2=52774,IR1=12211,IR2=3791,
881 NTAB=32,NDIV=1+IMM1/NTAB;
883 double AM=1./IM1,EPS=1.2e-7,RNMX=1.-EPS;
885 static int iv[32],iy,idum2 = 123456789;
889 idum= (-idum>1 ? -idum : 1);
891 for(j=NTAB+8;j>=1;j--) {
893 idum=IA1*(idum-k*IQ1)-k*IR1;
894 if (idum < 0) idum=idum+IM1;
895 if (j < NTAB) iv[j-1]=idum;
900 idum=IA1*(idum-k*IQ1)-k*IR1;
901 if (idum < 0) idum=idum+IM1;
903 idum2=IA2*(idum2-k*IQ2)-k*IR2;
904 if (idum2 < 0) idum2=idum2+IM2;
908 if(iy < 1)iy=iy+IMM1;
909 return (AM*iy < RNMX ? AM*iy : RNMX);