static int record_samples(complex * cSamples, int nSamples) { // Record the samples to a WAV file, two float samples I/Q static FILE * fp = NULL; // TODO: correct for big-endian byte order static unsigned int samples=0, remain=0; int j; float samp; // must be 4 bytes unsigned int u; // must be 4 bytes unsigned short s; // must be 2 bytes switch (nSamples) { case -1: // Open the file fp = fopen(file_name_samples, "wb"); if ( ! fp) return 0; if (fwrite("RIFF", 1, 4, fp) != 4) { fclose(fp); fp = NULL; return 0; } // IEEE float data, two channels u = 50; fwrite(&u, 4, 1, fp); fwrite("WAVE", 1, 4, fp); fwrite("fmt ", 1, 4, fp); u = 18; fwrite(&u, 4, 1, fp); s = 3; // wave_format_ieee_float fwrite(&s, 2, 1, fp); s = 2; // number of channels fwrite(&s, 2, 1, fp); u = quisk_sound_state.sample_rate; // sample rate fwrite(&u, 4, 1, fp); u *= 8; fwrite(&u, 4, 1, fp); s = 8; fwrite(&s, 2, 1, fp); s = 32; fwrite(&s, 2, 1, fp); s = 0; fwrite(&s, 2, 1, fp); fwrite("fact", 1, 4, fp); u = 4; fwrite(&u, 4, 1, fp); u = 0; fwrite(&u, 4, 1, fp); fwrite("data", 1, 4, fp); u = 0; fwrite(&u, 4, 1, fp); samples = 0; remain = 536870000; break; case -2: // close the file if (fp) fclose(fp); fp = NULL; remain = 0; break; default: // write the sound data to the file u = (unsigned int)nSamples; if (u >= remain) return 0; samples += u; remain -= u; fseek(fp, 54, SEEK_SET); // seek from the beginning u = 8 * samples; fwrite(&u, 4, 1, fp); fseek(fp, 4, SEEK_SET); // seek from the beginning u += 50 ; fwrite(&u, 4, 1, fp); fseek(fp, 46, SEEK_SET); // seek from the beginning u = samples * 2; fwrite(&u, 4, 1, fp); fseek(fp, 0, SEEK_END); // seek to the end for (j = 0; j < nSamples; j++) { samp = creal(cSamples[j]) / CLIP32; fwrite(&samp, 4, 1, fp); samp = cimag(cSamples[j]) / CLIP32; fwrite(&samp, 4, 1, fp); } break; } return 1; }
void printcomp(double complex integ) { printf("abs %.2f %+.2fi\n", creal(integ), cimag(integ)); while(!getch()); }
void testBesselComplex(){ double complex z; double complex Jn; double complex Yn; double complex In; double complex Kn; int n, nmin, nmax, nsize; double complex *Jnarray; double complex *Ynarray; double complex *Inarray; double complex *Knarray; n = 2; nmin = n; nmax = n + 4; nsize = nmax - nmin + 1; Jnarray = (double complex *) calloc(nsize, sizeof(double complex)); Ynarray = (double complex *) calloc(nsize, sizeof(double complex)); Inarray = (double complex *) calloc(nsize, sizeof(double complex)); Knarray = (double complex *) calloc(nsize, sizeof(double complex)); z = 2.4 + 1.1*I; printf("n = %d\n",n); printf("z = %.4f + %.4fi\n",creal(z), cimag(z)); Jn = besselJ(n, z); printf("Jn = %.4f + %.4fi\n",creal(Jn), cimag(Jn)); Yn = besselY(n, z); printf("Yn = %.4f + %.4fi\n",creal(Yn), cimag(Yn)); In = besselI(n, z); printf("In = %.4f + %.4fi\n",creal(In), cimag(In)); Kn = besselK(n, z); printf("Kn = %.4f + %.4fi\n",creal(Kn), cimag(Kn)); besselJArray(nmin, nmax, z, Jnarray); besselYArray(nmin, nmax, z, Ynarray); besselIArray(nmin, nmax, z, Inarray); besselKArray(nmin, nmax, z, Knarray); printf("\n"); printf("z = %.4f + %.4fi\n",creal(z), cimag(z)); printf("n Jn Yn In Kn\n"); for (int i = 0; i < nsize; i++){ printf("%d", nmin + i); printf(" "); printf("%.4f + %.4fi",creal(Jnarray[i]), cimag(Jnarray[i])); printf(" "); printf("%.4f + %.4fi",creal(Ynarray[i]), cimag(Ynarray[i])); printf(" "); printf("%.4f + %.4fi",creal(Inarray[i]), cimag(Inarray[i])); printf(" "); printf("%.4f + %.4fi",creal(Knarray[i]), cimag(Knarray[i])); printf("\n"); // // printf("Jn = %.4f + %.4fi\n",creal(Jnarray[i]), cimag(Jnarray[i])); // printf("Yn = %.4f + %.4fi\n",creal(Ynarray[i]), cimag(Ynarray[i])); // printf("In = %.4f + %.4fi\n",creal(Inarray[i]), cimag(Inarray[i])); // printf("Kn = %.4f + %.4fi\n",creal(Knarray[i]), cimag(Knarray[i])); } free(Jnarray); free(Ynarray); free(Inarray); free(Knarray); }
int main(void) { QLA_ColorMatrix O, iQ, tmp, matI; QLA_M_eq_zero(&matI); for(int i=0; i<QLA_Nc; i++) { QLA_c_eq_r_plus_ir(QLA_elem_M(matI,i,i), 1.0, 0.0); } printm(&matI); QLA_Complex tr; QLA_Real half = 0.5; for(int i=0; i<QLA_Nc; i++) { for(int j=0; j<QLA_Nc; j++) { QLA_c_eq_r_plus_ir(QLA_elem_M(O,i,j), i+1, QLA_Nc*(j+1)); } QLA_c_eq_r_plus_ir(QLA_elem_M(O,i,i), 2+1, 1); } #if QDP_Colors == 3 QLA_Complex ci; QLA_c_eq_r_plus_ir(ci, 0, 1); //use my own implementation QLA_ColorMatrix expiQ; QLA_ColorMatrix QQ; QLA_ColorMatrix QQQ; QLA_M_eq_M_times_M(&QQ, &iQ, &iQ); //-Q^2 QLA_M_eq_M_times_M(&QQQ, &QQ, &iQ); //-iQ^3 QLA_M_eq_c_times_M(&QQQ, &ci, &QQQ); //Q^3 QLA_Complex c0, c1; QLA_C_eq_trace_M(&c0, &QQQ); QLA_c_eq_r_times_c(c0, 0.3333333, c0); QLA_C_eq_trace_M(&c1, &QQ); QLA_c_eq_r_times_c(c1, -0.5, c1); double _Complex tf0, tf1, tf2; getfs(&tf0, &tf1, &tf2, QLA_real(c0), QLA_real(c1)); QLA_Complex f0, f1, f2; f0 = tf0; f1 = tf1; f2 = tf2; printm(&O); printf("iQ = \n"); printm(&iQ); printf("QLA: exp(iQ) = \n"); printm(&qla_exp); printf("Q^3 = \n"); printm(&QQQ); printf("c0 = "); printc(&c0); printf("c1 = "); printc(&c1); #endif #if QDP_Colors == 2 QLA_ColorMatrix expO; QLA_Complex Tr, det; QLA_c_eq_c_times_c(det, QLA_elem_M(O,0,0),QLA_elem_M(O,1,1)); QLA_c_meq_c_times_c(det, QLA_elem_M(O,0,1), QLA_elem_M(O,1,0)); QLA_C_eq_trace_M(&Tr, &O); QLA_Complex s, t; QLA_c_eq_r_times_c(s, 0.5, Tr); // s=TrA/2 QLA_Complex s2; QLA_c_eq_c_times_c(s2, s, s); //s2 = s^2 QLA_c_meq_c(s2, det); //s2 = s^2 - detA double _Complex dc_t = QLA_real(s2) + QLA_imag(s2) * _Complex_I; dc_t = csqrt(dc_t); // sqrt(s^2 - det A) QLA_c_eq_r_plus_ir(t, creal(dc_t), cimag(dc_t)); // t = sqrt(s^2 - det A) printf(" Matrix O = \n"); printm(&O); printf("TrO = "); printc(&Tr); printf("detO = "); printc(&det); printf("s = "); printc(&s); printf("t^2 = "); printc(&s2); printf("t = "); printc(&t); //use the QLA exp function QLA_ColorMatrix qla_exp; QLA_M_eq_exp_M(&qla_exp, &O); //exp(O) double _Complex cosht, sinht, sinht_t; if(QLA_real(t) == 0 && QLA_imag(t) == 0) { cosht = 1; sinht = 0; sinht_t = 1; } else { cosht = ccosh(dc_t); sinht = csinh(dc_t); sinht_t = sinht/dc_t; } double _Complex dc_s = QLA_real(s) + QLA_imag(s) * _Complex_I; double _Complex dc_f0, dc_f1; dc_f0 = cexp(dc_s) * (cosht - dc_s * sinht_t); dc_f1 = cexp(dc_s) * sinht_t; QLA_Complex f0, f1; QLA_c_eq_r_plus_ir(f0, creal(dc_f0), cimag(dc_f0)); QLA_c_eq_r_plus_ir(f1, creal(dc_f1), cimag(dc_f1)); QLA_M_eq_c_times_M(&expO, &f1, &O); QLA_M_peq_c(&expO, &f0); printf("QLA exp = \n"); printm(&qla_exp); printf("my expO = \n"); printm(&expO); #endif return 0; }
/* * Save fftwf-complex matrix to PNG files via gd * spectrum = 1 -> save complex spectrum to <basename>-spectrum.png * phase_angle = 1 -> save complex phase angle to <basename>-phaseang.png * power_spectrum = 1 -> save complex phase angle to <basename>-powspect.png * * return -1 on error, 0 otherwise */ int fftwf_result_save( fftwf_complex *data, int spectrum, int phase_angle, int power_spectrum, uint32_t w, uint32_t h, char *basename ) { FILE *f_s, *f_pa, *f_ps; gdImage *image_s, *image_pa, *image_ps; uint32_t i, j, g, color; fftwf_complex *dat; float d, max_s, max_pa, max_ps, power; char fn_s[256],fn_pa[256],fn_ps[256]; if( !spectrum && !phase_angle && !power_spectrum ) { WARN("nothing to do"); return(0); } if( spectrum ) { snprintf( fn_s, 255, "%s-spectrum.png", basename); f_s = fopen(fn_s,"wb"); if(!f_s) { ERROR("Error opening file for output: %s", fn_s); ERROR("fopen: %s", strerror(errno)); return(-1); } image_s = gdImageCreateTrueColor(w,h); if(!image_s) { ERROR("Cannot create image"); fclose(f_s); return(-1); } } if( phase_angle ) { snprintf( fn_pa, 255, "%s-phaseang.png", basename); f_pa = fopen(fn_pa,"wb"); if(!f_pa) { ERROR("Error opening file for output: %s", fn_pa); ERROR("fopen: %s", strerror(errno)); return(-1); } image_pa = gdImageCreateTrueColor(w,h); if(!image_pa) { ERROR("Cannot create image"); fclose(f_pa); return(-1); } } if( phase_angle ) { snprintf( fn_ps, 255, "%s-powspect.png", basename); f_ps = fopen(fn_ps,"wb"); if(!f_ps) { ERROR("Error opening file for output: %s", fn_ps); ERROR("fopen: %s", strerror(errno)); return(-1); } image_ps = gdImageCreateTrueColor(w,h); if(!image_ps) { ERROR("Cannot create image"); fclose(f_ps); return(-1); } } max_s = max_pa = max_ps =0; dat = data; for(j=0;j<h;j++) for(i=0;i<w;i++,dat++) { if( spectrum || power_spectrum ) power = powf(creal(*dat),2) + powf(cimag(*dat),2); if( spectrum ) { d = sqrtf(power); if( d> max_s ) max_s = d; } if( phase_angle ) { d = atan2(cimag(*dat), creal(*dat)); if( d> max_pa ) max_pa = d; } if( power_spectrum ) { d = power; if( d> max_ps ) max_ps = d; } } dat = data; for(j=0; j<h; j++){ for(i=0; i<w; i++) { if( spectrum || power_spectrum ) power = powf(creal(*dat),2) + powf(cimag(*dat),2); if( spectrum ){ d = sqrtf(power); g = round(255.0 * d/max_s); color = g + (g<<8) + (g<<16); color &= 0xffffff; gdImageSetPixel(image_s,i,j,color); } if( phase_angle ){ d = atan2(cimag(*dat), creal(*dat)); g = round(255.0 * d/max_pa); color = g + (g<<8) + (g<<16); color &= 0xffffff; gdImageSetPixel(image_pa,i,j,color); } if( power_spectrum ){ d = power; g = round(255.0 * d/max_ps); color = g + (g<<8) + (g<<16); color &= 0xffffff; gdImageSetPixel(image_ps,i,j,color); } dat++; } } if( spectrum ){ gdImagePng(image_s, f_s); fclose( f_s ); gdImageDestroy(image_s); } if( phase_angle ){ gdImagePng(image_pa, f_pa); fclose( f_pa ); gdImageDestroy(image_pa); } if( power_spectrum ){ gdImagePng(image_ps, f_ps); fclose( f_ps ); gdImageDestroy(image_ps); } return(0); }
static int cfpequal_tol(long double complex x, long double complex y, long double tol) { return (fpequal_tol(creal(x), creal(y), tol) && fpequal_tol(cimag(x), cimag(y), tol)); }
int main(int argc, char **argv) { /* SDL SEtup */ if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Could not initialize SDL: %s\n", SDL_GetError()); exit(1); } atexit(SDL_Quit); SDL_Surface *surface; surface = SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_HWSURFACE); if ( surface == NULL ) { fprintf(stderr, "Could not setup screen to resolution %dx%d : %s\n", WIDTH, HEIGHT, SDL_GetError()); exit(1); } /* Initialize variables */ double complex center = START_POS; double zoom = START_ZOOM; sdl_draw_mandelbrot(surface, center, zoom); SDL_Event event; while(1) { SDL_PollEvent(&event); switch (event.type) { case SDL_QUIT: exit(0); break; case SDL_KEYDOWN: if (event.key.keysym.sym == ' ') { center = START_POS; zoom = START_ZOOM; sdl_draw_mandelbrot(surface, center, zoom); } else if (event.key.keysym.sym == SDLK_ESCAPE) { exit(0); } break; case SDL_MOUSEBUTTONDOWN: center = creal(center) + ((event.button.x - (WIDTH/2))/zoom) + ((cimag(center) + ((event.button.y - (HEIGHT/2))/zoom)) *_Complex_I); if (event.button.button == 1) zoom *= ZOOM_FACTOR; else if (event.button.button == 3) zoom /= ZOOM_FACTOR; sdl_draw_mandelbrot(surface, center, zoom); break; } } return 0; }
int main(int argc, char *argv[]) { static const int ntests = sizeof(tests) / sizeof(tests[0]) / 2; complex float in; complex long double expected; int i; printf("1..%d\n", ntests * 3); for (i = 0; i < ntests; i++) { __real__ expected = __real__ in = tests[2 * i]; __imag__ in = tests[2 * i + 1]; __imag__ expected = -cimag(in); assert(fpequal(libcrealf(in), __real__ in)); assert(fpequal(libcreal(in), __real__ in)); assert(fpequal(libcreall(in), __real__ in)); assert(fpequal(libcimagf(in), __imag__ in)); assert(fpequal(libcimag(in), __imag__ in)); assert(fpequal(libcimagl(in), __imag__ in)); feclearexcept(FE_ALL_EXCEPT); if (!cfpequal(libconjf(in), expected)) { printf("not ok %d\t# conjf(%#.2g + %#.2gI): " "wrong value\n", 3 * i + 1, creal(in), cimag(in)); } else if (fetestexcept(FE_ALL_EXCEPT)) { printf("not ok %d\t# conjf(%#.2g + %#.2gI): " "threw an exception\n", 3 * i + 1, creal(in), cimag(in)); } else { printf("ok %d\t\t# conjf(%#.2g + %#.2gI)\n", 3 * i + 1, creal(in), cimag(in)); } feclearexcept(FE_ALL_EXCEPT); if (!cfpequal(libconj(in), expected)) { printf("not ok %d\t# conj(%#.2g + %#.2gI): " "wrong value\n", 3 * i + 2, creal(in), cimag(in)); } else if (fetestexcept(FE_ALL_EXCEPT)) { printf("not ok %d\t# conj(%#.2g + %#.2gI): " "threw an exception\n", 3 * i + 2, creal(in), cimag(in)); } else { printf("ok %d\t\t# conj(%#.2g + %#.2gI)\n", 3 * i + 2, creal(in), cimag(in)); } feclearexcept(FE_ALL_EXCEPT); if (!cfpequal(libconjl(in), expected)) { printf("not ok %d\t# conjl(%#.2g + %#.2gI): " "wrong value\n", 3 * i + 3, creal(in), cimag(in)); } else if (fetestexcept(FE_ALL_EXCEPT)) { printf("not ok %d\t# conjl(%#.2g + %#.2gI): " "threw an exception\n", 3 * i + 3, creal(in), cimag(in)); } else { printf("ok %d\t\t# conjl(%#.2g + %#.2gI)\n", 3 * i + 3, creal(in), cimag(in)); } } return (0); }
int main(){ unsigned int iX,iY, /* indices of 2D virtual array (image) = integer coordinate */ i, /* index of 1D array */ iLength = iXmax*iYmax;/* length of array in bytes = number of bytes = number of pixels of image * number of bytes of color */ /* world ( double) coordinate = parameter plane*/ const double ZxMin=-2.0; const double ZxMax=2.0; const double ZyMin=-1.0; const double ZyMax=1.0; double PixelWidth=(ZxMax-ZxMin)/iXmax; double PixelHeight=(ZyMax-ZyMin)/iYmax; /* */ double Zx, Zy; /* Z=Zx+Zy*i */ /* */ int eLastIteration, iLastIteration; /* sobel filter */ unsigned char G, Gh, Gv; /* dynamic 1D arrays for colors ( shades of gray ) */ unsigned char *data, *edge; data = malloc( iLength * sizeof(unsigned char) ); edge = malloc( iLength * sizeof(unsigned char) ); if (data == NULL || edge==NULL) { fprintf(stderr," Could not allocate memory"); getchar(); return 1; } else printf(" memory is OK\n"); ER2=EscapeRadius*EscapeRadius; denominator = iPeriodChild; InternalAngle = 1.0/((double) denominator); c = GiveC(InternalAngle, 1.0, iPeriodParent) ; // internal radius= 1.0 gives root point = parabolic parameter Cx=creal(c); Cy=cimag(c); ZA = GiveAlfaFixedPoint( c); ZAx=creal(ZA); ZAy = cimag(ZA); printf(" fill the data array \n"); for(iY=0;iY<iYmax;++iY){ Zy=ZyMin + iY*PixelHeight; /* */ if (fabs(Zy)<PixelHeight/2) Zy=0.0; /* */ printf(" row %u from %u \n",iY, iYmax); for(iX=0;iX<iXmax;++iX){ Zx=ZxMin + iX*PixelWidth; i= f(iX,iY); /* compute index of 1D array from indices of 2D array */ color = GiveColor(Zx, Zy); data[i]= color; /* exterior */ /* if (Zx>0 && Zy>0) data[i]=255-data[i]; check the orientation of Z-plane by marking first quadrant */ } } printf(" find boundaries in data array using Sobel filter\n"); for(iY=1;iY<iYmax-1;++iY){ for(iX=1;iX<iXmax-1;++iX){ Gv= data[f(iX-1,iY+1)] + 2*data[f(iX,iY+1)] + data[f(iX-1,iY+1)] - data[f(iX-1,iY-1)] - 2*data[f(iX-1,iY)] - data[f(iX+1,iY-1)]; Gh= data[f(iX+1,iY+1)] + 2*data[f(iX+1,iY)] + data[f(iX-1,iY-1)] - data[f(iX+1,iY-1)] - 2*data[f(iX-1,iY)] - data[f(iX-1,iY-1)]; G = sqrt(Gh*Gh + Gv*Gv); i= f(iX,iY); /* compute index of 1D array from indices of 2D array */ if (G==0) {edge[i]=255;} /* background */ else {edge[i]=0;} /* boundary */ } } printf(" copy boundaries from edge to data array \n"); for(iY=1;iY<iYmax-1;++iY){ for(iX=1;iX<iXmax-1;++iX) {i= f(iX,iY); /* compute index of 1D array from indices of 2D array */ if (edge[i]==0) data[i]=0;}} /* ---------- file -------------------------------------*/ printf(" save data array to the file \n"); FILE * fp; char name [100]; /* name of file */ i = sprintf(name,"B%2.9f",AR); /* result (is saved in i) but is not used */ char *filename =strcat(name,".pgm"); char *comment="# C=0.2";/* comment should start with # */ /* save image to the pgm file */ fp= fopen(filename,"wb"); /*create new file,give it a name and open it in binary mode */ fprintf(fp,"P5\n %s\n %u\n %u\n %u\n",comment,iXmax,iYmax,MaxColorComponentValue); /*write header to the file*/ fwrite(data,iLength,1,fp); /*write image data bytes to the file in one step */ printf("File %s saved. \n", filename); fclose(fp); /* --------------free memory ---------------------*/ free(data); free(edge); printf("parameter c = ( %f ; %f ) \n", Cx, Cy); printf("alfa fixed point z = ( %f ; %f ) \n", creal(ZA), cimag(ZA)); return 0; }
double complex csinh(double complex z) { double x, y, h; int32_t hx, hy, ix, iy, lx, ly; x = creal(z); y = cimag(z); EXTRACT_WORDS(hx, lx, x); EXTRACT_WORDS(hy, ly, y); ix = 0x7fffffff & hx; iy = 0x7fffffff & hy; /* Handle the nearly-non-exceptional cases where x and y are finite. */ if (ix < 0x7ff00000 && iy < 0x7ff00000) { if ((iy | ly) == 0) return CMPLX(sinh(x), y); if (ix < 0x40360000) /* small x: normal case */ return CMPLX(sinh(x) * cos(y), cosh(x) * sin(y)); /* |x| >= 22, so cosh(x) ~= exp(|x|) */ if (ix < 0x40862e42) { /* x < 710: exp(|x|) won't overflow */ h = exp(fabs(x)) * 0.5; return CMPLX(copysign(h, x) * cos(y), h * sin(y)); } else if (ix < 0x4096bbaa) { /* x < 1455: scale to avoid overflow */ z = __ldexp_cexp(CMPLX(fabs(x), y), -1); return CMPLX(creal(z) * copysign(1, x), cimag(z)); } else { /* x >= 1455: the result always overflows */ h = huge * x; return CMPLX(h * cos(y), h * h * sin(y)); } } /* * sinh(+-0 +- I Inf) = sign(d(+-0, dNaN))0 + I dNaN. * The sign of 0 in the result is unspecified. Choice = normally * the same as dNaN. Raise the invalid floating-point exception. * * sinh(+-0 +- I NaN) = sign(d(+-0, NaN))0 + I d(NaN). * The sign of 0 in the result is unspecified. Choice = normally * the same as d(NaN). */ if ((ix | lx) == 0 && iy >= 0x7ff00000) return CMPLX(copysign(0, x * (y - y)), y - y); /* * sinh(+-Inf +- I 0) = +-Inf + I +-0. * * sinh(NaN +- I 0) = d(NaN) + I +-0. */ if ((iy | ly) == 0 && ix >= 0x7ff00000) { if (((hx & 0xfffff) | lx) == 0) return CMPLX(x, y); return CMPLX(x, copysign(0, y)); } /* * sinh(x +- I Inf) = dNaN + I dNaN. * Raise the invalid floating-point exception for finite nonzero x. * * sinh(x + I NaN) = d(NaN) + I d(NaN). * Optionally raises the invalid floating-point exception for finite * nonzero x. Choice = don't raise (except for signaling NaNs). */ if (ix < 0x7ff00000 && iy >= 0x7ff00000) return CMPLX(y - y, x * (y - y)); /* * sinh(+-Inf + I NaN) = +-Inf + I d(NaN). * The sign of Inf in the result is unspecified. Choice = normally * the same as d(NaN). * * sinh(+-Inf +- I Inf) = +Inf + I dNaN. * The sign of Inf in the result is unspecified. Choice = always +. * Raise the invalid floating-point exception. * * sinh(+-Inf + I y) = +-Inf cos(y) + I Inf sin(y) */ if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) { if (iy >= 0x7ff00000) return CMPLX(x * x, x * (y - y)); return CMPLX(x * cos(y), INFINITY * sin(y)); } /* * sinh(NaN + I NaN) = d(NaN) + I d(NaN). * * sinh(NaN +- I Inf) = d(NaN) + I d(NaN). * Optionally raises the invalid floating-point exception. * Choice = raise. * * sinh(NaN + I y) = d(NaN) + I d(NaN). * Optionally raises the invalid floating-point exception for finite * nonzero y. Choice = don't raise (except for signaling NaNs). */ return CMPLX((x * x) * (y - y), (x + x) * (y - y)); }
void z_sin(doublecomplex *r, doublecomplex *z) { double _Complex ret_val = csin(z->r + I*z->i); r->r = creal(ret_val); r->i = cimag(ret_val); }
static MagickBooleanType ForwardFourierTransform(FourierInfo *fourier_info, const Image *image,double *magnitude,double *phase,ExceptionInfo *exception) { CacheView *image_view; double n, *source; fftw_complex *fourier; fftw_plan fftw_r2c_plan; long y; register const IndexPacket *indexes; register const PixelPacket *p; register long i, x; /* Generate the forward Fourier transform. */ source=(double *) AcquireQuantumMemory((size_t) fourier_info->height, fourier_info->width*sizeof(*source)); if (source == (double *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); return(MagickFalse); } ResetMagickMemory(source,0,fourier_info->width*fourier_info->height* sizeof(*source)); i=0L; image_view=AcquireCacheView(image); for (y=0L; y < (long) fourier_info->height; y++) { p=GetCacheViewVirtualPixels(image_view,0L,y,fourier_info->width,1UL, exception); if (p == (const PixelPacket *) NULL) break; indexes=GetCacheViewVirtualIndexQueue(image_view); for (x=0L; x < (long) fourier_info->width; x++) { switch (fourier_info->channel) { case RedChannel: default: { source[i]=QuantumScale*GetRedPixelComponent(p); break; } case GreenChannel: { source[i]=QuantumScale*GetGreenPixelComponent(p); break; } case BlueChannel: { source[i]=QuantumScale*GetBluePixelComponent(p); break; } case OpacityChannel: { source[i]=QuantumScale*GetOpacityPixelComponent(p); break; } case IndexChannel: { source[i]=QuantumScale*indexes[x]; break; } case GrayChannels: { source[i]=QuantumScale*GetRedPixelComponent(p); break; } } i++; p++; } } image_view=DestroyCacheView(image_view); fourier=(fftw_complex *) AcquireAlignedMemory((size_t) fourier_info->height, fourier_info->center*sizeof(*fourier)); if (fourier == (fftw_complex *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); source=(double *) RelinquishMagickMemory(source); return(MagickFalse); } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_ForwardFourierTransform) #endif fftw_r2c_plan=fftw_plan_dft_r2c_2d(fourier_info->width,fourier_info->width, source,fourier,FFTW_ESTIMATE); fftw_execute(fftw_r2c_plan); fftw_destroy_plan(fftw_r2c_plan); source=(double *) RelinquishMagickMemory(source); /* Normalize Fourier transform. */ n=(double) fourier_info->width*(double) fourier_info->width; i=0L; for (y=0L; y < (long) fourier_info->height; y++) for (x=0L; x < (long) fourier_info->center; x++) { #if defined(MAGICKCORE_HAVE_COMPLEX_H) fourier[i]/=n; #else fourier[i][0]/=n; fourier[i][1]/=n; #endif i++; } /* Generate magnitude and phase (or real and imaginary). */ i=0L; if (fourier_info->modulus != MagickFalse) for (y=0L; y < (long) fourier_info->height; y++) for (x=0L; x < (long) fourier_info->center; x++) { magnitude[i]=cabs(fourier[i]); phase[i]=carg(fourier[i]); i++; } else for (y=0L; y < (long) fourier_info->height; y++) for (x=0L; x < (long) fourier_info->center; x++) { magnitude[i]=creal(fourier[i]); phase[i]=cimag(fourier[i]); i++; } fourier=(fftw_complex *) RelinquishAlignedMemory(fourier); return(MagickTrue); }
f = cabsf(f); ld = cabsl(ld); TEST_TRACE(C99 7.3.8.2) d = cpow(d, d); f = cpowf(f, f); ld = cpowl(ld, ld); TEST_TRACE(C99 7.3.8.3) d = csqrt(d); f = csqrtf(f); ld = csqrtl(ld); TEST_TRACE(C99 7.3.9.1) d = carg(d); f = cargf(f); ld = cargl(ld); TEST_TRACE(C99 7.3.9.2) d = cimag(d); f = cimagf(f); ld = cimagl(ld); TEST_TRACE(C99 7.3.9.3) d = conj(d); f = conjf(f); ld = conjl(ld); TEST_TRACE(C99 7.3.9.4) d = cproj(d); f = cprojf(f); ld = cprojl(ld); } TEST_TRACE(C99 7.3.9.5) double rd = creal(d); float rf = crealf(f); long double rld = creall(ld);
int main(int argc, char *argv[]) { int i, j, Nx, Ny, Nr, Nb; int seedn=54; double sigma; double a; double mse; double snr; double snr_out; double gamma=0.001; double aux1, aux2, aux3, aux4; complex double alpha; purify_image img, img_copy; purify_visibility_filetype filetype_vis; purify_image_filetype filetype_img; complex double *xinc; complex double *y0; complex double *y; complex double *noise; double *xout; double *w; double *error; complex double *xoutc; double *wdx; double *wdy; double *dummyr; complex double *dummyc; //parameters for the continuos Fourier Transform double *deconv; purify_sparsemat_row gmat; purify_visibility vis_test; purify_measurement_cparam param_m1; purify_measurement_cparam param_m2; complex double *fft_temp1; complex double *fft_temp2; void *datafwd[5]; void *dataadj[5]; fftw_plan planfwd; fftw_plan planadj; //Structures for sparsity operator sopt_wavelet_type *dict_types; sopt_wavelet_type *dict_types1; sopt_wavelet_type *dict_types2; sopt_sara_param param1; sopt_sara_param param2; sopt_sara_param param3; void *datas[1]; void *datas1[1]; void *datas2[1]; //Structures for the opmization problems sopt_l1_sdmmparam param4; sopt_l1_rwparam param5; sopt_prox_tvparam param6; sopt_tv_sdmmparam param7; sopt_tv_rwparam param8; clock_t start, stop; double t = 0.0; double start1, stop1; int dimy, dimx; //Image dimension of the zero padded image //Dimensions should be power of 2 dimx = 256; dimy = 256; //Define parameters filetype_vis = PURIFY_VISIBILITY_FILETYPE_PROFILE_VIS; filetype_img = PURIFY_IMAGE_FILETYPE_FITS; //Read coverage purify_visibility_readfile(&vis_test, "./data/images/Coverages/cont_sim4.vis", filetype_vis); printf("Number of visibilities: %i \n\n", vis_test.nmeas); // Input image. img.fov_x = 1.0 / 180.0 * PURIFY_PI; img.fov_y = 1.0 / 180.0 * PURIFY_PI; img.nx = 4; img.ny = 4; //Read input image purify_image_readfile(&img, "data/images/Einstein.fits", 1); printf("Image dimension: %i, %i \n\n", img.nx, img.ny); // purify_image_writefile(&img, "data/test/Einstein_double.fits", filetype_img); param_m1.nmeas = vis_test.nmeas; param_m1.ny1 = dimy; param_m1.nx1 = dimx; param_m1.ofy = 2; param_m1.ofx = 2; param_m1.ky = 2; param_m1.kx = 2; param_m2.nmeas = vis_test.nmeas; param_m2.ny1 = dimy; param_m2.nx1 = dimx; param_m2.ofy = 2; param_m2.ofx = 2; param_m2.ky = 2; param_m2.kx = 2; Nb = 9; Nx=param_m2.ny1*param_m2.nx1; Nr=Nb*Nx; Ny=param_m2.nmeas; //Memory allocation for the different variables deconv = (double*)malloc((Nx) * sizeof(double)); PURIFY_ERROR_MEM_ALLOC_CHECK(deconv); xinc = (complex double*)malloc((Nx) * sizeof(complex double)); PURIFY_ERROR_MEM_ALLOC_CHECK(xinc); xout = (double*)malloc((Nx) * sizeof(double)); PURIFY_ERROR_MEM_ALLOC_CHECK(xout); y = (complex double*)malloc((vis_test.nmeas) * sizeof(complex double)); PURIFY_ERROR_MEM_ALLOC_CHECK(y); y0 = (complex double*)malloc((vis_test.nmeas) * sizeof(complex double)); PURIFY_ERROR_MEM_ALLOC_CHECK(y0); noise = (complex double*)malloc((vis_test.nmeas) * sizeof(complex double)); PURIFY_ERROR_MEM_ALLOC_CHECK(noise); w = (double*)malloc((Nr) * sizeof(double)); PURIFY_ERROR_MEM_ALLOC_CHECK(w); error = (double*)malloc((Nx) * sizeof(double)); PURIFY_ERROR_MEM_ALLOC_CHECK(error); xoutc = (complex double*)malloc((Nx) * sizeof(complex double)); PURIFY_ERROR_MEM_ALLOC_CHECK(xoutc); wdx = (double*)malloc((Nx) * sizeof(double)); PURIFY_ERROR_MEM_ALLOC_CHECK(wdx); wdy = (double*)malloc((Nx) * sizeof(double)); PURIFY_ERROR_MEM_ALLOC_CHECK(wdy); dummyr = malloc(Nr * sizeof(double)); PURIFY_ERROR_MEM_ALLOC_CHECK(dummyr); dummyc = malloc(Nr * sizeof(complex double)); PURIFY_ERROR_MEM_ALLOC_CHECK(dummyc); for (i=0; i < Nx; i++){ xinc[i] = 0.0 + 0.0*I; } for (i=0; i < img.nx; i++){ for (j=0; j < img.ny; j++){ xinc[i+j*param_m1.nx1] = img.pix[i+j*img.nx] + 0.0*I; } } //Initialize griding matrix assert((start = clock())!=-1); purify_measurement_init_cft(&gmat, deconv, vis_test.u, vis_test.v, ¶m_m1); stop = clock(); t = (double) (stop-start)/CLOCKS_PER_SEC; printf("Time initalization: %f \n\n", t); for(i = 0; i < img.nx * img.ny; ++i){ deconv[i] = 1.0; } //Memory allocation for the fft i = Nx*param_m1.ofy*param_m1.ofx; fft_temp1 = (complex double*)malloc((i) * sizeof(complex double)); PURIFY_ERROR_MEM_ALLOC_CHECK(fft_temp1); fft_temp2 = (complex double*)malloc((i) * sizeof(complex double)); PURIFY_ERROR_MEM_ALLOC_CHECK(fft_temp2); //FFT plan planfwd = fftw_plan_dft_2d(param_m1.nx1*param_m1.ofx, param_m1.ny1*param_m1.ofy, fft_temp1, fft_temp1, FFTW_FORWARD, FFTW_MEASURE); planadj = fftw_plan_dft_2d(param_m1.nx1*param_m1.ofx, param_m1.ny1*param_m1.ofy, fft_temp2, fft_temp2, FFTW_BACKWARD, FFTW_MEASURE); datafwd[0] = (void*)¶m_m1; datafwd[1] = (void*)deconv; datafwd[2] = (void*)&gmat; datafwd[3] = (void*)&planfwd; datafwd[4] = (void*)fft_temp1; dataadj[0] = (void*)¶m_m2; dataadj[1] = (void*)deconv; dataadj[2] = (void*)&gmat; dataadj[3] = (void*)&planadj; dataadj[4] = (void*)fft_temp2; printf("FFT plan done \n\n"); assert((start = clock())!=-1); purify_measurement_cftfwd((void*)y0, (void*)xinc, datafwd); stop = clock(); t = (double) (stop-start)/CLOCKS_PER_SEC; printf("Time forward operator: %f \n\n", t); //Noise realization //Input snr snr = 30.0; a = cblas_dznrm2(Ny, (void*)y0, 1); sigma = a*pow(10.0,-(snr/20.0))/sqrt(Ny); FILE *fout = fopen("ein.uv", "w"); for (i=0; i < Ny; i++) { // noise[i] = (sopt_ran_gasdev2(seedn) + sopt_ran_gasdev2(seedn)*I)*(sigma/sqrt(2)); noise[i] = 0; y[i] = y0[i] + noise[i]; fprintf(fout, "%14.5e%14.5e%14.5e%14.5e%14.5e%14.5e\n", vis_test.u[i], vis_test.v[i], vis_test.w[i], creal(y[i]), cimag(y[i]), 1.0); } fclose(fout); //Rescaling the measurements aux4 = (double)Ny/(double)Nx; for (i=0; i < Ny; i++) { y[i] = y[i]/sqrt(aux4); } for (i=0; i < Nx; i++) { deconv[i] = deconv[i]/sqrt(aux4); } // Output image. img_copy.fov_x = 1.0 / 180.0 * PURIFY_PI; img_copy.fov_y = 1.0 / 180.0 * PURIFY_PI; img_copy.nx = param_m1.nx1; img_copy.ny = param_m1.ny1; for (i=0; i < Nx; i++){ xoutc[i] = 0.0 + 0.0*I; } //Dirty image purify_measurement_cftadj((void*)xoutc, (void*)y, dataadj); for (i=0; i < Nx; i++) { xout[i] = creal(xoutc[i]); } aux1 = purify_utils_maxarray(xout, Nx); img_copy.pix = (double*)malloc((Nx) * sizeof(double)); PURIFY_ERROR_MEM_ALLOC_CHECK(img_copy.pix); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xoutc[i]); } purify_image_writefile(&img_copy, "eindirty.fits", filetype_img); return 0; //SARA structure initialization param1.ndict = Nb; param1.real = 0; dict_types = malloc(param1.ndict * sizeof(sopt_wavelet_type)); PURIFY_ERROR_MEM_ALLOC_CHECK(dict_types); dict_types[0] = SOPT_WAVELET_DB1; dict_types[1] = SOPT_WAVELET_DB2; dict_types[2] = SOPT_WAVELET_DB3; dict_types[3] = SOPT_WAVELET_DB4; dict_types[4] = SOPT_WAVELET_DB5; dict_types[5] = SOPT_WAVELET_DB6; dict_types[6] = SOPT_WAVELET_DB7; dict_types[7] = SOPT_WAVELET_DB8; dict_types[8] = SOPT_WAVELET_Dirac; sopt_sara_initop(¶m1, param_m1.ny1, param_m1.nx1, 4, dict_types); datas[0] = (void*)¶m1; //Db8 structure initialization param2.ndict = 1; param2.real = 0; dict_types1 = malloc(param2.ndict * sizeof(sopt_wavelet_type)); PURIFY_ERROR_MEM_ALLOC_CHECK(dict_types1); dict_types1[0] = SOPT_WAVELET_DB8; sopt_sara_initop(¶m2, param_m1.ny1, param_m1.nx1, 4, dict_types1); datas1[0] = (void*)¶m2; //Dirac structure initialization param3.ndict = 1; param3.real = 0; dict_types2 = malloc(param3.ndict * sizeof(sopt_wavelet_type)); PURIFY_ERROR_MEM_ALLOC_CHECK(dict_types2); dict_types2[0] = SOPT_WAVELET_Dirac; sopt_sara_initop(¶m3, param_m1.ny1, param_m1.nx1, 4, dict_types2); datas2[0] = (void*)¶m3; //Scaling constants in the diferent representation domains sopt_sara_analysisop((void*)dummyc, (void*)xoutc, datas); for (i=0; i < Nr; i++) { dummyr[i] = creal(dummyc[i]); } aux2 = purify_utils_maxarray(dummyr, Nr); sopt_sara_analysisop((void*)dummyc, (void*)xoutc, datas1); for (i=0; i < Nr; i++) { dummyr[i] = creal(dummyc[i]); } aux3 = purify_utils_maxarray(dummyr, Nx); // Output image. img_copy.fov_x = 1.0 / 180.0 * PURIFY_PI; img_copy.fov_y = 1.0 / 180.0 * PURIFY_PI; img_copy.nx = param_m1.nx1; img_copy.ny = param_m1.ny1; //Initial solution and weights for (i=0; i < Nx; i++) { xoutc[i] = 0.0 + 0.0*I; wdx[i] = 1.0; wdy[i] = 1.0; } for (i=0; i < Nr; i++){ w[i] = 1.0; } //Copy true image in xout for (i=0; i < Nx; i++) { xout[i] = creal(xinc[i]); } printf("**********************\n"); printf("BPSA reconstruction\n"); printf("**********************\n"); //Structure for the L1 solver param4.verbose = 2; param4.max_iter = 300; param4.gamma = gamma*aux2; param4.rel_obj = 0.001; param4.epsilon = sqrt(Ny + 2*sqrt(Ny))*sigma/sqrt(aux4); param4.epsilon_tol = 0.01; param4.real_data = 0; param4.cg_max_iter = 100; param4.cg_tol = 0.000001; //Initial solution for (i=0; i < Nx; i++) { xoutc[i] = 0.0 + 0.0*I; } #ifdef _OPENMP start1 = omp_get_wtime(); #else assert((start = clock())!=-1); #endif sopt_l1_sdmm((void*)xoutc, Nx, &purify_measurement_cftfwd, datafwd, &purify_measurement_cftadj, dataadj, &sopt_sara_synthesisop, datas, &sopt_sara_analysisop, datas, Nr, (void*)y, Ny, w, param4); #ifdef _OPENMP stop1 = omp_get_wtime(); t = stop1 - start1; #else stop = clock(); t = (double) (stop-start)/CLOCKS_PER_SEC; #endif printf("Time BPSA: %f \n\n", t); //SNR for (i=0; i < Nx; i++) { error[i] = creal(xoutc[i])-xout[i]; } mse = cblas_dnrm2(Nx, error, 1); a = cblas_dnrm2(Nx, xout, 1); snr_out = 20.0*log10(a/mse); printf("SNR: %f dB\n\n", snr_out); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xoutc[i]); } purify_image_writefile(&img_copy, "./data/test/einbpsa.fits", filetype_img); //Residual image purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd); alpha = -1.0 +0.0*I; cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1); purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xinc[i]); } purify_image_writefile(&img_copy, "data/test/einbpsares.fits", filetype_img); //Error image for (i=0; i < Nx; i++){ img_copy.pix[i] = error[i]; } purify_image_writefile(&img_copy, "data/test/einbpsaerror.fits", filetype_img); printf("**********************\n"); printf("SARA reconstruction\n"); printf("**********************\n"); //Structure for the RWL1 solver param5.verbose = 2; param5.max_iter = 5; param5.rel_var = 0.001; param5.sigma = sigma*sqrt((double)Ny/(double)Nr); param5.init_sol = 1; #ifdef _OPENMP start1 = omp_get_wtime(); #else assert((start = clock())!=-1); #endif sopt_l1_rwsdmm((void*)xoutc, Nx, &purify_measurement_cftfwd, datafwd, &purify_measurement_cftadj, dataadj, &sopt_sara_synthesisop, datas, &sopt_sara_analysisop, datas, Nr, (void*)y, Ny, param4, param5); #ifdef _OPENMP stop1 = omp_get_wtime(); t = stop1 - start1; #else stop = clock(); t = (double) (stop-start)/CLOCKS_PER_SEC; #endif printf("Time SARA: %f \n\n", t); //SNR for (i=0; i < Nx; i++) { error[i] = creal(xoutc[i])-xout[i]; } mse = cblas_dnrm2(Nx, error, 1); a = cblas_dnrm2(Nx, xout, 1); snr_out = 20.0*log10(a/mse); printf("SNR: %f dB\n\n", snr_out); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xoutc[i]); } purify_image_writefile(&img_copy, "data/test/einsara.fits", filetype_img); //Residual image purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd); alpha = -1.0 +0.0*I; cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1); purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xinc[i]); } purify_image_writefile(&img_copy, "data/test/einsarares.fits", filetype_img); //Error image for (i=0; i < Nx; i++){ img_copy.pix[i] = error[i]; } purify_image_writefile(&img_copy, "data/test/einsaraerror.fits", filetype_img); printf("**********************\n"); printf("TV reconstruction\n"); printf("**********************\n"); //Structure for the TV prox param6.verbose = 1; param6.max_iter = 50; param6.rel_obj = 0.0001; //Structure for the TV solver param7.verbose = 2; param7.max_iter = 300; param7.gamma = gamma*aux1; param7.rel_obj = 0.001; param7.epsilon = sqrt(Ny + 2*sqrt(Ny))*sigma/sqrt(aux4); param7.epsilon_tol = 0.01; param7.real_data = 0; param7.cg_max_iter = 100; param7.cg_tol = 0.000001; param7.paramtv = param6; //Initial solution and weights for (i=0; i < Nx; i++) { xoutc[i] = 0.0 + 0.0*I; wdx[i] = 1.0; wdy[i] = 1.0; } assert((start = clock())!=-1); sopt_tv_sdmm((void*)xoutc, dimx, dimy, &purify_measurement_cftfwd, datafwd, &purify_measurement_cftadj, dataadj, (void*)y, Ny, wdx, wdy, param7); stop = clock(); t = (double) (stop-start)/CLOCKS_PER_SEC; printf("Time TV: %f \n\n", t); //SNR for (i=0; i < Nx; i++) { error[i] = creal(xoutc[i])-xout[i]; } mse = cblas_dnrm2(Nx, error, 1); a = cblas_dnrm2(Nx, xout, 1); snr_out = 20.0*log10(a/mse); printf("SNR: %f dB\n\n", snr_out); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xoutc[i]); } purify_image_writefile(&img_copy, "data/test/eintv.fits", filetype_img); //Residual image purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd); alpha = -1.0 +0.0*I; cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1); purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xinc[i]); } purify_image_writefile(&img_copy, "data/test/eintvres.fits", filetype_img); //Error image for (i=0; i < Nx; i++){ img_copy.pix[i] = error[i]; } purify_image_writefile(&img_copy, "data/test/eintverror.fits", filetype_img); printf("**********************\n"); printf("RWTV reconstruction\n"); printf("**********************\n"); //Structure for the RWTV solver param8.verbose = 2; param8.max_iter = 5; param8.rel_var = 0.001; param8.sigma = sigma*sqrt(Ny/(2*Nx)); param8.init_sol = 1; assert((start = clock())!=-1); sopt_tv_rwsdmm((void*)xoutc, dimx, dimy, &purify_measurement_cftfwd, datafwd, &purify_measurement_cftadj, dataadj, (void*)y, Ny, param7, param8); stop = clock(); t = (double) (stop-start)/CLOCKS_PER_SEC; printf("Time RWTV: %f \n\n", t); //SNR for (i=0; i < Nx; i++) { error[i] = creal(xoutc[i])-xout[i]; } mse = cblas_dnrm2(Nx, error, 1); a = cblas_dnrm2(Nx, xout, 1); snr_out = 20.0*log10(a/mse); printf("SNR: %f dB\n\n", snr_out); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xoutc[i]); } purify_image_writefile(&img_copy, "data/test/einrwtv.fits", filetype_img); //Residual image purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd); alpha = -1.0 +0.0*I; cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1); purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xinc[i]); } purify_image_writefile(&img_copy, "data/test/einrwtvres.fits", filetype_img); //Error image for (i=0; i < Nx; i++){ img_copy.pix[i] = error[i]; } purify_image_writefile(&img_copy, "data/test/einrwtverror.fits", filetype_img); printf("**********************\n"); printf("Db8 reconstruction\n"); printf("**********************\n"); //Initial solution for (i=0; i < Nx; i++) { xoutc[i] = 0.0 + 0.0*I; } param4.gamma = gamma*aux3; assert((start = clock())!=-1); sopt_l1_sdmm((void*)xoutc, Nx, &purify_measurement_cftfwd, datafwd, &purify_measurement_cftadj, dataadj, &sopt_sara_synthesisop, datas1, &sopt_sara_analysisop, datas1, Nx, (void*)y, Ny, w, param4); stop = clock(); t = (double) (stop-start)/CLOCKS_PER_SEC; printf("Time BPDb8: %f \n\n", t); //SNR for (i=0; i < Nx; i++) { error[i] = creal(xoutc[i])-xout[i]; } mse = cblas_dnrm2(Nx, error, 1); a = cblas_dnrm2(Nx, xout, 1); snr_out = 20.0*log10(a/mse); printf("SNR: %f dB\n\n", snr_out); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xoutc[i]); } purify_image_writefile(&img_copy, "data/test/eindb8.fits", filetype_img); //Residual image purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd); alpha = -1.0 +0.0*I; cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1); purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xinc[i]); } purify_image_writefile(&img_copy, "data/test/eindb8res.fits", filetype_img); //Error image for (i=0; i < Nx; i++){ img_copy.pix[i] = error[i]; } purify_image_writefile(&img_copy, "data/test/eindb8error.fits", filetype_img); printf("**********************\n"); printf("RWBPDb8 reconstruction\n"); printf("**********************\n"); //Structure for the RWL1 solver param5.verbose = 2; param5.max_iter = 5; param5.rel_var = 0.001; param5.sigma = sigma*sqrt((double)Ny/(double)Nx); param5.init_sol = 1; assert((start = clock())!=-1); sopt_l1_rwsdmm((void*)xoutc, Nx, &purify_measurement_cftfwd, datafwd, &purify_measurement_cftadj, dataadj, &sopt_sara_synthesisop, datas1, &sopt_sara_analysisop, datas1, Nx, (void*)y, Ny, param4, param5); stop = clock(); t = (double) (stop-start)/CLOCKS_PER_SEC; printf("Time RWBPDb8: %f \n\n", t); //SNR for (i=0; i < Nx; i++) { error[i] = creal(xoutc[i])-xout[i]; } mse = cblas_dnrm2(Nx, error, 1); a = cblas_dnrm2(Nx, xout, 1); snr_out = 20.0*log10(a/mse); printf("SNR: %f dB\n\n", snr_out); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xoutc[i]); } purify_image_writefile(&img_copy, "data/test/einrwdb8.fits", filetype_img); //Residual image purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd); alpha = -1.0 +0.0*I; cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1); purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xinc[i]); } purify_image_writefile(&img_copy, "data/test/einrwdb8res.fits", filetype_img); //Error image for (i=0; i < Nx; i++){ img_copy.pix[i] = error[i]; } purify_image_writefile(&img_copy, "data/test/einrwdb8error.fits", filetype_img); printf("**********************\n"); printf("BP reconstruction\n"); printf("**********************\n"); param4.gamma = gamma*aux1; //Initial solution for (i=0; i < Nx; i++) { xoutc[i] = 0.0 + 0.0*I; } assert((start = clock())!=-1); sopt_l1_sdmm((void*)xoutc, Nx, &purify_measurement_cftfwd, datafwd, &purify_measurement_cftadj, dataadj, &sopt_sara_synthesisop, datas2, &sopt_sara_analysisop, datas2, Nx, (void*)y, Ny, w, param4); stop = clock(); t = (double) (stop-start)/CLOCKS_PER_SEC; printf("Time BP: %f \n\n", t); //SNR for (i=0; i < Nx; i++) { error[i] = creal(xoutc[i])-xout[i]; } mse = cblas_dnrm2(Nx, error, 1); a = cblas_dnrm2(Nx, xout, 1); snr_out = 20.0*log10(a/mse); printf("SNR: %f dB\n\n", snr_out); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xoutc[i]); } purify_image_writefile(&img_copy, "data/test/einbp.fits", filetype_img); //Residual image purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd); alpha = -1.0 +0.0*I; cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1); purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xinc[i]); } purify_image_writefile(&img_copy, "data/test/einbpres.fits", filetype_img); //Error image for (i=0; i < Nx; i++){ img_copy.pix[i] = error[i]; } purify_image_writefile(&img_copy, "data/test/einbperror.fits", filetype_img); printf("**********************\n"); printf("RWBP reconstruction\n"); printf("**********************\n"); //Structure for the RWL1 solver param5.verbose = 2; param5.max_iter = 5; param5.rel_var = 0.001; param5.sigma = sigma*sqrt((double)Ny/(double)Nx); param5.init_sol = 1; assert((start = clock())!=-1); sopt_l1_rwsdmm((void*)xoutc, Nx, &purify_measurement_cftfwd, datafwd, &purify_measurement_cftadj, dataadj, &sopt_sara_synthesisop, datas2, &sopt_sara_analysisop, datas2, Nx, (void*)y, Ny, param4, param5); stop = clock(); t = (double) (stop-start)/CLOCKS_PER_SEC; printf("Time RWBP: %f \n\n", t); //SNR for (i=0; i < Nx; i++) { error[i] = creal(xoutc[i])-xout[i]; } mse = cblas_dnrm2(Nx, error, 1); a = cblas_dnrm2(Nx, xout, 1); snr_out = 20.0*log10(a/mse); printf("SNR: %f dB\n\n", snr_out); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xoutc[i]); } purify_image_writefile(&img_copy, "data/test/einrwbp.fits", filetype_img); //Residual image purify_measurement_cftfwd((void*)y0, (void*)xoutc, datafwd); alpha = -1.0 +0.0*I; cblas_zaxpy(Ny, (void*)&alpha, y, 1, y0, 1); purify_measurement_cftadj((void*)xinc, (void*)y0, dataadj); for (i=0; i < Nx; i++){ img_copy.pix[i] = creal(xinc[i]); } purify_image_writefile(&img_copy, "data/test/einrwbpres.fits", filetype_img); //Error image for (i=0; i < Nx; i++){ img_copy.pix[i] = error[i]; } purify_image_writefile(&img_copy, "data/test/einrwbperror.fits", filetype_img); //Free all memory purify_image_free(&img); purify_image_free(&img_copy); free(deconv); purify_visibility_free(&vis_test); free(y); free(xinc); free(xout); free(w); free(noise); free(y0); free(error); free(xoutc); free(wdx); free(wdy); sopt_sara_free(¶m1); sopt_sara_free(¶m2); sopt_sara_free(¶m3); free(dict_types); free(dict_types1); free(dict_types2); free(fft_temp1); free(fft_temp2); fftw_destroy_plan(planfwd); fftw_destroy_plan(planadj); purify_sparsemat_freer(&gmat); free(dummyr); free(dummyc); return 0; }
double carg(double complex z) { return (atan2(cimag(z), creal(z))); }
double complex casin(double complex z) { double complex w; static double complex ca, ct, zz, z2; double x, y; x = creal (z); y = cimag (z); if (y == 0.0) { if (fabs(x) > 1.0) { w = M_PI_2 + 0.0 * I; /*mtherr ("casin", DOMAIN);*/ } else { w = asin (x) + 0.0 * I; } return (w); } /* Power series expansion */ /* b = cabs(z); if( b < 0.125 ) { z2.r = (x - y) * (x + y); z2.i = 2.0 * x * y; cn = 1.0; n = 1.0; ca.r = x; ca.i = y; sum.r = x; sum.i = y; do { ct.r = z2.r * ca.r - z2.i * ca.i; ct.i = z2.r * ca.i + z2.i * ca.r; ca.r = ct.r; ca.i = ct.i; cn *= n; n += 1.0; cn /= n; n += 1.0; b = cn/n; ct.r *= b; ct.i *= b; sum.r += ct.r; sum.i += ct.i; b = fabs(ct.r) + fabs(ct.i); } while( b > MACHEP ); w->r = sum.r; w->i = sum.i; return; } */ ca = x + y * I; ct = ca * I; /* sqrt( 1 - z*z) */ /* cmul( &ca, &ca, &zz ) */ /*x * x - y * y */ zz = (x - y) * (x + y) + (2.0 * x * y) * I; zz = 1.0 - creal(zz) - cimag(zz) * I; z2 = csqrt (zz); zz = ct + z2; zz = clog (zz); /* multiply by 1/i = -i */ w = zz * (-1.0 * I); return (w); }
static int cfpequal(long double complex x, long double complex y, int checksign) { return (fpequal(creal(x), creal(y), checksign) && fpequal(cimag(x), cimag(y), checksign)); }
double complex catanh(double complex z) { z = catan(CMPLX(-cimag(z), creal(z))); return CMPLX(cimag(z), -creal(z)); }
double complex firstPart(const double Tolerance, const int l, const int m, const double *dVec, const double gamma, const double Lamda, const double qSqur, const int verbose, int *const rstatus) { double complex firstTerms = 0 + I * 0, pmodeSum = 0 + I * 0, firstPartSum = 0 + I * 0; int npmode[2] = {40, 72}; int i_npmode = 1; double error = 1.0; int pmodeSqur; int n0, n1, n2; double dModSqur = dVec[0] * dVec[0] + dVec[1] * dVec[1] + dVec[2] * dVec[2]; int *degnrtDOF = NULL; int *arrayPmode = NULL; int niter = 0; int genReturn; get_npmode(npmode, i_npmode); genReturn = gen_points_array(°nrtDOF, &arrayPmode, npmode[0], npmode[1]); if (genReturn != 0) { Rprintf("Generated the points wrongly in firstPart!"); *rstatus = 1000; return (firstPartSum); } if (verbose && 0) { for (int i = 0; i < npmode[0]; i++) { if (degnrtDOF[i] == 0) Rprintf("pmodeSqur=%d has no corresponding points.\n", i); else Rprintf("pmodeSqur=%d have %d degenaration DOF.\n", i, degnrtDOF[i]); } } pmodeSqur = 0; while (error > Tolerance) { if (pmodeSqur >= npmode[0]) { i_npmode++; get_npmode(npmode, i_npmode); genReturn = gen_points_array(°nrtDOF, &arrayPmode, npmode[0], npmode[1]); if (verbose) REprintf("increased i_npmode to %d in firstPart %d %d\n", i_npmode, npmode[0], npmode[1]); if (genReturn != 0) { Rprintf("Generated the points wrongly in firstPart!"); *rstatus = 1000; return (firstPartSum); } if (i_npmode > 4) { if (verbose) REprintf( "NPmode and DimMax need to be larger than available in firstPart! " "Aborting...!\n"); *rstatus = 2000; return (firstPartSum); } } pmodeSum = 0 + I * 0; // These pmodes has no contribution to the points sets. if (degnrtDOF[pmodeSqur] == 0) { pmodeSqur += 1; continue; } for (int i = 0; i < degnrtDOF[pmodeSqur]; i++) { n0 = arrayPmode[pmodeSqur * npmode[1] * 3 + i * 3 + 0]; n1 = arrayPmode[pmodeSqur * npmode[1] * 3 + i * 3 + 1]; n2 = arrayPmode[pmodeSqur * npmode[1] * 3 + i * 3 + 2]; double r[3], rpar[3], rort[3]; if (fabs(dModSqur) < DBL_EPSILON) { r[0] = n0 / gamma; r[1] = n1 / gamma; r[2] = n2 / gamma; } else { double nDotd = n0 * dVec[0] + n1 * dVec[1] + n2 * dVec[2]; // we split the vector first into a parallel and orthogonal part w.r.t. dVec rpar[0] = nDotd / dModSqur * dVec[0]; rpar[1] = nDotd / dModSqur * dVec[1]; rpar[2] = nDotd / dModSqur * dVec[2]; rort[0] = n0 - rpar[0]; rort[1] = n1 - rpar[1]; rort[2] = n2 - rpar[2]; r[0] = (rpar[0] - 0.5 * dVec[0]) / gamma + rort[0]; r[1] = (rpar[1] - 0.5 * dVec[1]) / gamma + rort[1]; r[2] = (rpar[2] - 0.5 * dVec[2]) / gamma + rort[2]; } // now we determine the spherical coordinates appropriate for // usage with GSL spherical harmonics double u, v, w, xy; xy = r[0] * r[0] + r[1] * r[1]; u = sqrt(xy + r[2] * r[2]); v = atan2(sqrt(xy), r[2]); w = atan2(r[1], r[0]) * 180 / M_PI; r[0] = u; r[1] = cos(v); r[2] = w; firstTerms = exp(-Lamda * (pow(r[0], 2.0) - qSqur)) * pow(r[0], l) * spheHarm(l, m, r[1], r[2], rstatus) / (pow(r[0], 2.0) - qSqur); if (*rstatus != 0) { REprintf("spheHarm produced error code \"%s\"\n", gsl_strerror(*rstatus)); return (firstPartSum); } // Add every term within the same pmode into pmodeSum pmodeSum += firstTerms; } // end of pmode loop firstPartSum += pmodeSum; // Both pmodeSum and firstPartSum are complex numbers, // cabs take the modulus of these variables. // only calculate new error if firstPartSum != 0. if (cabs(firstPartSum) > DBL_EPSILON) error = cabs(pmodeSum) / cabs(firstPartSum); if (verbose) Rprintf("first term: pmode %d error: %.16f result (%e, %e)\n", pmodeSqur, error, creal(firstPartSum), cimag(firstPartSum)); // if the result is still zero after 4 iterations it is assumed to stay zero if (cabs(firstPartSum) < DBL_EPSILON && niter > 4) break; pmodeSqur += 1; ++niter; } // end of while. if (verbose) { Rprintf("First term = (%e, %e)\n", creal(firstPartSum), cimag(firstPartSum)); } return firstPartSum; }
int main( int argc, char *argv[] ) { static LALStatus status; RealFFTPlan *fwd = NULL; RealFFTPlan *rev = NULL; REAL4Vector *dat = NULL; REAL4Vector *rfft = NULL; REAL4Vector *ans = NULL; COMPLEX8Vector *dft = NULL; COMPLEX8Vector *fft = NULL; #if LAL_CUDA_ENABLED /* The test itself should pass at 1e-4, but it might fail at * some rare cases where accuracy is bad for some numbers. */ REAL8 eps = 3e-4; #else /* very conservative floating point precision */ REAL8 eps = 1e-6; #endif REAL8 lbn; REAL8 ssq; REAL8 var; REAL8 tol; UINT4 nmax; UINT4 m; UINT4 n; UINT4 i; UINT4 j; UINT4 k; UINT4 s = 0; FILE *fp; ParseOptions( argc, argv ); m = m_; n = n_; fp = verbose ? stdout : NULL ; if ( n == 0 ) { nmax = 65536; } else { nmax = n--; } while ( n < nmax ) { if ( n < 128 ) { ++n; } else { n *= 2; } LALSCreateVector( &status, &dat, n ); TestStatus( &status, CODES( 0 ), 1 ); LALSCreateVector( &status, &rfft, n ); TestStatus( &status, CODES( 0 ), 1 ); LALSCreateVector( &status, &ans, n ); TestStatus( &status, CODES( 0 ), 1 ); LALCCreateVector( &status, &dft, n / 2 + 1 ); TestStatus( &status, CODES( 0 ), 1 ); LALCCreateVector( &status, &fft, n / 2 + 1 ); TestStatus( &status, CODES( 0 ), 1 ); LALCreateForwardRealFFTPlan( &status, &fwd, n, 0 ); TestStatus( &status, CODES( 0 ), 1 ); LALCreateReverseRealFFTPlan( &status, &rev, n, 0 ); TestStatus( &status, CODES( 0 ), 1 ); /* * * Do m trials of random data. * */ for ( i = 0; i < m; ++i ) { srand( s++ ); /* seed the random number generator */ /* * * Create data and compute error tolerance. * * Reference: Kaneko and Liu, * "Accumulation of round-off error in fast fourier tranforms" * J. Asssoc. Comp. Mach, Vol 17 (No 4) 637-654, October 1970. * */ srand( i ); /* seed the random number generator */ ssq = 0; for ( j = 0; j < n; ++j ) { dat->data[j] = 20.0 * rand() / (REAL4)( RAND_MAX + 1.0 ) - 10.0; ssq += dat->data[j] * dat->data[j]; fp ? fprintf( fp, "%e\n", dat->data[j] ) : 0; } lbn = log( n ) / log( 2 ); var = 2.5 * lbn * eps * eps * ssq / n; tol = 5 * sqrt( var ); /* up to 5 sigma excursions */ fp ? fprintf( fp, "\neps = %e \ntol = %e\n", eps, tol ) : 0; /* * * Perform forward FFT and DFT (only if n < 100). * */ LALForwardRealFFT( &status, fft, dat, fwd ); TestStatus( &status, CODES( 0 ), 1 ); LALREAL4VectorFFT( &status, rfft, dat, fwd ); TestStatus( &status, CODES( 0 ), 1 ); LALREAL4VectorFFT( &status, ans, rfft, rev ); TestStatus( &status, CODES( 0 ), 1 ); fp ? fprintf( fp, "rfft()\t\trfft(rfft())\trfft(rfft())\n\n" ) : 0; for ( j = 0; j < n; ++j ) { fp ? fprintf( fp, "%e\t%e\t%e\n", rfft->data[j], ans->data[j], ans->data[j] / n ) : 0; } if ( n < 128 ) { LALForwardRealDFT( &status, dft, dat ); TestStatus( &status, CODES( 0 ), 1 ); /* * * Check accuracy of FFT vs DFT. * */ fp ? fprintf( fp, "\nfftre\t\tfftim\t\t" ) : 0; fp ? fprintf( fp, "dtfre\t\tdftim\n" ) : 0; for ( k = 0; k <= n / 2; ++k ) { REAL8 fftre = creal(fft->data[k]); REAL8 fftim = cimag(fft->data[k]); REAL8 dftre = creal(dft->data[k]); REAL8 dftim = cimag(dft->data[k]); REAL8 errre = fabs( dftre - fftre ); REAL8 errim = fabs( dftim - fftim ); REAL8 avere = fabs( dftre + fftre ) / 2 + eps; REAL8 aveim = fabs( dftim + fftim ) / 2 + eps; REAL8 ferre = errre / avere; REAL8 ferim = errim / aveim; fp ? fprintf( fp, "%e\t%e\t", fftre, fftim ) : 0; fp ? fprintf( fp, "%e\t%e\n", dftre, dftim ) : 0; /* fp ? fprintf( fp, "%e\t%e\t", errre, errim ) : 0; */ /* fp ? fprintf( fp, "%e\t%e\n", ferre, ferim ) : 0; */ if ( ferre > eps && errre > tol ) { fputs( "FAIL: Incorrect result from forward transform\n", stderr ); fprintf( stderr, "\tdifference = %e\n", errre ); fprintf( stderr, "\ttolerance = %e\n", tol ); fprintf( stderr, "\tfrac error = %e\n", ferre ); fprintf( stderr, "\tprecision = %e\n", eps ); return 1; } if ( ferim > eps && errim > tol ) { fputs( "FAIL: Incorrect result from forward transform\n", stderr ); fprintf( stderr, "\tdifference = %e\n", errim ); fprintf( stderr, "\ttolerance = %e\n", tol ); fprintf( stderr, "\tfrac error = %e\n", ferim ); fprintf( stderr, "\tprecision = %e\n", eps ); return 1; } } } /* * * Perform reverse FFT and check accuracy vs original data. * */ LALReverseRealFFT( &status, ans, fft, rev ); TestStatus( &status, CODES( 0 ), 1 ); fp ? fprintf( fp, "\ndat->data[j]\tans->data[j] / n\n" ) : 0; for ( j = 0; j < n; ++j ) { REAL8 err = fabs( dat->data[j] - ans->data[j] / n ); REAL8 ave = fabs( dat->data[j] + ans->data[j] / n ) / 2 + eps; REAL8 fer = err / ave; fp ? fprintf( fp, "%e\t%e\n", dat->data[j], ans->data[j] / n ) : 0; /* fp ? fprintf( fp, "%e\t%e\n", err, fer ) : 0; */ if ( fer > eps && err > tol ) { fputs( "FAIL: Incorrect result after reverse transform\n", stderr ); fprintf( stderr, "\tdifference = %e\n", err ); fprintf( stderr, "\ttolerance = %e\n", tol ); fprintf( stderr, "\tfrac error = %e\n", fer ); fprintf( stderr, "\tprecision = %e\n", eps ); return 1; } } } LALSDestroyVector( &status, &dat ); TestStatus( &status, CODES( 0 ), 1 ); LALSDestroyVector( &status, &rfft ); TestStatus( &status, CODES( 0 ), 1 ); LALSDestroyVector( &status, &ans ); TestStatus( &status, CODES( 0 ), 1 ); LALCDestroyVector( &status, &dft ); TestStatus( &status, CODES( 0 ), 1 ); LALCDestroyVector( &status, &fft ); TestStatus( &status, CODES( 0 ), 1 ); LALDestroyRealFFTPlan( &status, &fwd ); TestStatus( &status, CODES( 0 ), 1 ); LALDestroyRealFFTPlan( &status, &rev ); TestStatus( &status, CODES( 0 ), 1 ); } LALCheckMemoryLeaks(); return 0; }
double complex ccosh(double complex z) { double x, y; int32_t hx, hy, ix, iy, lx, ly; x = creal(z); y = cimag(z); EXTRACT_WORDS(hx, lx, x); EXTRACT_WORDS(hy, ly, y); ix = 0x7fffffff & hx; iy = 0x7fffffff & hy; /* Handle the nearly-non-exceptional cases where x and y are finite. */ if (ix < 0x7ff00000 && iy < 0x7ff00000) { if ((iy | ly) == 0) return (cpack(cosh(x), x * y)); /* XXX We don't handle |x| > DBL_MAX ln(2) yet. */ return (cpack(cosh(x) * cos(y), sinh(x) * sin(y))); } /* * cosh(+-0 +- I Inf) = dNaN + I sign(d(+-0, dNaN))0. * The sign of 0 in the result is unspecified. Choice = normally * the same as dNaN. Raise the invalid floating-point exception. * * cosh(+-0 +- I NaN) = d(NaN) + I sign(d(+-0, NaN))0. * The sign of 0 in the result is unspecified. Choice = normally * the same as d(NaN). */ if ((ix | lx) == 0 && iy >= 0x7ff00000) return (cpack(y - y, copysign(0, x * (y - y)))); /* * cosh(+-Inf +- I 0) = +Inf + I (+-)(+-)0. * * cosh(NaN +- I 0) = d(NaN) + I sign(d(NaN, +-0))0. * The sign of 0 in the result is unspecified. */ if ((iy | ly) == 0 && ix >= 0x7ff00000) { if (((hx & 0xfffff) | lx) == 0) return (cpack(x * x, copysign(0, x) * y)); return (cpack(x * x, copysign(0, (x + x) * y))); } /* * cosh(x +- I Inf) = dNaN + I dNaN. * Raise the invalid floating-point exception for finite nonzero x. * * cosh(x + I NaN) = d(NaN) + I d(NaN). * Optionally raises the invalid floating-point exception for finite * nonzero x. Choice = don't raise (except for signaling NaNs). */ if (ix < 0x7ff00000 && iy >= 0x7ff00000) return (cpack(y - y, x * (y - y))); /* * cosh(+-Inf + I NaN) = +Inf + I d(NaN). * * cosh(+-Inf +- I Inf) = +Inf + I dNaN. * The sign of Inf in the result is unspecified. Choice = always +. * Raise the invalid floating-point exception. * * cosh(+-Inf + I y) = +Inf cos(y) +- I Inf sin(y) */ if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) { if (iy >= 0x7ff00000) return (cpack(x * x, x * (y - y))); return (cpack((x * x) * cos(y), x * sin(y))); } /* * cosh(NaN + I NaN) = d(NaN) + I d(NaN). * * cosh(NaN +- I Inf) = d(NaN) + I d(NaN). * Optionally raises the invalid floating-point exception. * Choice = raise. * * cosh(NaN + I y) = d(NaN) + I d(NaN). * Optionally raises the invalid floating-point exception for finite * nonzero y. Choice = don't raise (except for signaling NaNs). */ return (cpack((x * x) * (y - y), (x + x) * (y - y))); }
void Calculate_HF(int *tlist,double *vlist,int nfac,int nvert,double *angles,double *Eo,double *E0o,double *up,double TIME,double dist,double Gamma,double A,double Hdist,int N,double WL,double *freqx,double *freqy,int nfreq,double *offset,double *Fr,double *Fi) { double complex *F=calloc(nfreq,sizeof(double complex)); double complex *F0; F0=(double complex*)calloc(nfreq,sizeof(double complex)); double *Flux,*Fldx,*Fldy,*Fldz,*FldA; Flux=(double*)calloc(nfac,sizeof(double)); double M[3][3],dMb[3][3],dMo[3][3],dMl[3][3],Mt[3][3]; double R[3][3],Rdb[3][3],Rdl[3][3],Rdo[3][3],RT[3][3]; double E[3],E0[3]; double normalr[3],side1[3],side2[3]; double dechdx[3],dechdy[3],dechdz[3],dechdA[3]; double n[3],*nb,*cent; double *vb1,*vb2,*vb3; double vr1[3],vr2[3],vr3[3]; double *v1,*v2,*v3; double scale; double complex tscale,FTC; double dp; double B,TB=0; double norm; int t1,t2,t3,blocker,sign; int j1,j2,j3; double mu,mu0,area,mub,ech,rexp; double *normal,*centroid; int *visible; int tb1,tb2,tb3; //Indices to the vertices of possible blocker facet int blocked=0; //Distance km->arcsec dp=1/(dist*149597871.0)*180.0/PI*3600.0; visible=calloc(nfac,sizeof(int)); //Allocate for memory // normal=(double*)malloc(3*nfac*sizeof(double)); // centroid=(double*)mxCalloc(3*nfac,sizeof(double)); // IndexofBlocks=(int*)mxCalloc(nfac,sizeof(int)); // NumofBlocks=(int*)mxCalloc(nfac,sizeof(int)); //Calculate frame change matrix Calculate_Frame_Matrix(Eo,up,R); //FacetsOverHorizon(tlist,vlist,nfac,nvert,normal,centroid,NumofBlocks,IndexofBlocks); rotate(angles[0],angles[1],angles[2],0.0,TIME,M,dMb,dMl,dMo); //Construct asteroid->Camera frame matrix, which is //asteroid->world frame->camera frame transpose(M,Mt); //Transpose, since we rotate the model, not view directions mult_mat(R,Mt,RT); mult_vector(M,Eo,E); mult_vector(M,E0o,E0); /*For each facet, * 1)Check if facet is visible * 2) Calculate echo * 3) Convert triangle to range-Doppler frame * 4) Calculate FT */ //Find actual blockers FindActualBlockers(tlist,vlist,nfac,nvert,E,E,1,visible); Calculate_Radiance(tlist,vlist,nfac,nvert,angles,Eo,E0o,TIME,Gamma, A,Hdist,WL,N,Flux,Fldx,Fldy,Fldz,FldA,0); //for(int i=27;i<nfac;i++) // mexPrintf("fl%d: %.10e\n",i+1, Flux[i]); //visible is nfac vector, visible[j]=1 if facet (j+1)th facet is visible //NOTE INDEXING //mexPrintf("%f %f %f\n",vlist[0],vlist[1],vlist[2]); for(int j=0;j<nfac;j++) { if(visible[j]==0) continue; //Calculate normal from facet vertices //Vertex indices of the current facet //Note that C indices from 0, matlab from 1 j1=tlist[j*3]-1; j2=tlist[j*3+1]-1; j3=tlist[j*3+2]-1; //Current vertices v1=vlist+j1*3; v2=vlist+j2*3; v3=vlist+j3*3; //Calculate normals and centroids for(int i=0;i<3;i++) { side1[i]=dp*(v2[i]-v1[i]); //Convert km->arcsec side2[i]=dp*(v3[i]-v1[i]); } cross(side1,side2,n); norm=NORM(n); n[0]=n[0]/norm; n[1]=n[1]/norm; n[2]=n[2]/norm; mu=DOT(E,n); mu0=DOT(E0,n); //Convert to camera frame mult_vector(RT,v1,vr1); mult_vector(RT,v2,vr2); mult_vector(RT,v3,vr3); for(int i=0;i<3;i++) { vr1[i]=dp*vr1[i]; vr2[i]=dp*vr2[i]; vr3[i]=dp*vr3[i]; } //Now we should convert to frequency domain, ie calculate the contribution of each facet Calc_FTC(freqx,freqy,nfreq,vr1[0],vr1[1],vr2[0],vr2[1],vr3[0],vr3[1],F0); // printf("Fdd: %f %f\n",creal(FTdd[0]),cimag(FTdd[0])); //Note that we sum to F at each round, does not work, we need to multiply with the echo //Derivatives wrt angles area=0.5*norm; //if(j==0) //{ // mexPrintf("area: %f mu: %f F0: %f\n",area,mu,F0[0]); //} //mexPrintf("area: %f normal: %f %f %f mu: %f mu0: %f\n",area,n[0],n[1],n[2],mu,mu0); B=Flux[j]; for(int jf=0;jf<nfreq;jf++) { //This should be taken outside of the loop // mexPrintf("scale:%f offset: %f %f\n",scale,creal(cexp(2*PI*I*(offset[0]*freqx[jf]+offset[1]*freqy[jf]))),cimag(cexp(2*PI*I*(offset[0]*freqx[jf]+offset[1]*freqy[jf])))); //FTC=tscale*F0[jf]; F[jf]+=B*F0[jf]; } TB=TB+B*area*mu; // printf("Flux: %f area: %f mu: %f\n",B,area,mu); } //printf("Total brightness: %f\n",TB); //Normalize with total brightness double complex temp; for(int j=0;j<nfreq;j++) { temp=cexp(2.0*PI*I*(offset[0]*freqx[j]+offset[1]*freqy[j]))*F[j]/TB; Fr[j]=creal(temp); Fi[j]=cimag(temp); } free(visible); free(Flux); free(F0); free(F); }
/* * Save complex matrix to JPEG via gd * if magnitude is set, brightness of output pixels is abs(complex), otherwise it's atan(re/im) * * return -1 on error, 0 otherwise */ uint32_t y_complex_save( fftwf_complex *data, uint32_t magnitude, uint32_t w, uint32_t h, char *name ) { FILE *f; gdImage *image; uint32_t i, j, g, color; fftwf_complex *dat; float d, max, re, im; if(!name) return(-1); f = fopen(name, "wb"); if(!f) { ERROR("Error opening file for output: %s", name); ERROR("fopen: %s", strerror(errno)); return(-1); } image = gdImageCreateTrueColor(w,h); if(!image) { ERROR("Cannot create image"); fclose(f); return(-1); } max=0; dat=data; for(j=0;j<h;j++) for(i=0;i<w;i++) { if(magnitude) { re = creal(*dat); im = cimag(*dat); d = sqrtf(powf(re,2)+powf(im,2)); } else { re = creal(*dat); im = cimag(*dat); d = atan2(im, re); } dat++; if(d>max) max=d; } dat = data; for(j=0; j<h; j++){ for(i=0; i<w; i++) { if(magnitude) { re = creal(*dat); im = cimag(*dat); d = sqrtf(re*re+im*im); } else { re = creal(*dat); im = cimag(*dat); d = atan2(im, re); } dat++; g = round(255.0 * d/max); color = g + (g<<8) + (g<<16); color &= 0xffffff; gdImageSetPixel(image,i,j,color); } } gdImageJpeg(image, f, 255); gdImageDestroy(image); return(0); }
void Calculate_HF_deriv(int *tlist,double *vlist,int nfac,int nvert,double *angles,double *Eo,double *E0o,double *up,double TIME,double dist,double Gamma,double A,double Hdist,int N,double WL,double *freqx,double *freqy,int nfreq,double *offset,double *Fr,double *Fi,double *dFdxr,double *dFdxi,double *dFdyr,double *dFdyi,double *dFdzr,double *dFdzi,double *dFdAr,double *dFdAi,double *dFdoffr,double *dFdoffi) { double complex *F=calloc(nfreq,sizeof(double complex)); double complex *F0,*FTda,*FTdb,*FTdc,*FTdd,*FTdh,*FTdg,*FTdx,*FTdy,*FTdz,*FTdA; FTdx=calloc(nfreq*nvert,sizeof(double complex)); FTdy=calloc(nfreq*nvert,sizeof(double complex)); FTdz=calloc(nfreq*nvert,sizeof(double complex)); FTdA=calloc(nfreq*3,sizeof(double complex)); F0=calloc(nfreq,sizeof(double complex)); FTda=malloc(nfreq*sizeof(double complex)); FTdb=malloc(nfreq*sizeof(double complex)); FTdc=malloc(nfreq*sizeof(double complex)); FTdd=malloc(nfreq*sizeof(double complex)); FTdh=malloc(nfreq*sizeof(double complex)); FTdg=malloc(nfreq*sizeof(double complex)); double M[3][3],dMb[3][3],dMo[3][3],dMl[3][3],Mt[3][3],dMbT[3][3],dMoT[3][3],dMlT[3][3]; //Rotation matrices and their derivatives and transposes double R[3][3],Rdb[3][3],Rdl[3][3],Rdo[3][3],RT[3][3]; //Projection matrix, and derivatives of combined projection+rotation matrix double dEdb[3],dEdl[3],dEdo[3],dE0db[3],dE0dl[3],dE0do[3]; double dndx1[3],dndx2[3],dndx3[3],dndy1[3],dndy2[3],dndy3[3],dndz1[3],dndz2[3],dndz3[3]; //Derivatives of the facet normal vector double dBdx1,dBdy1,dBdz1,dBdx2,dBdy2,dBdz2,dBdx3,dBdy3,dBdz3,dBdb,dBdl,dBdo; //Derivatives of facet brightness double *dTBdx,*dTBdy,*dTBdz; //Derivatives of total brightness, allocating memory double *Flux,*Fldx,*Fldy,*Fldz,*FldA; Flux=calloc(nfac,sizeof(double)); Fldx=calloc(nfac*nvert,sizeof(double)); Fldy=calloc(nfac*nvert,sizeof(double)); Fldz=calloc(nfac*nvert,sizeof(double)); FldA=calloc(nfac*3,sizeof(double)); double dTBdA[3]={0}; dTBdx=calloc(nvert,sizeof(double)); dTBdy=calloc(nvert,sizeof(double)); dTBdz=calloc(nvert,sizeof(double)); double dmudx1,dmudy1,dmudz1,dmudx2,dmudy2,dmudz2,dmudx3,dmudy3,dmudz3; double dmu0dx1,dmu0dy1,dmu0dz1,dmu0dx2,dmu0dy2,dmu0dz2,dmu0dx3,dmu0dy3,dmu0dz3; double dmudl,dmudb,dmudo,dmu0dl,dmu0db,dmu0do; //Derivatives of mu and mu0 double dAdx[3],dAdy[3],dAdz[3]; //Facet area derivatives double dadx,dady,dadz,dbdx,dbdy,dbdz; //Derivatives of projected vertices double E[3],E0[3]; //Earth and Sun direction, rotated double side1[3],side2[3]; double n[3]; double v1db[3],v2db[3],v3db[3],v1dl[3],v2dl[3],v3dl[3],v1do[3],v2do[3],v3do[3]; //Derivatives of 2d vertices wrt angles double vr1[3],vr2[3],vr3[3]; double v1[3],v2[3],v3[3]; double complex scale; double dp; double B,TB=0.0; double norm; double mut,mu0t; int t1,t2,t3; int j1,j2,j3; double mu,mu0,area; double *normal; int *visible; int tb1,tb2,tb3; //Indices to the vertices of possible blocker facet int blocked=0; //Distance km->arcsec dp=1/(dist*149597871.0)*180.0/PI*3600.0; visible=calloc(nfac,sizeof(int)); //Calculate_Frame_Matrix_Derivatives(Eo,angles,TIME,rfreq,R,Rdb,Rdl,Rdo); Calculate_Frame_Matrix(Eo,up,R); //Calculate frame change matrix //FacetsOverHorizon(tlist,vlist,nfac,nvert,normal,centroid,NumofBlocks,IndexofBlocks); rotate(angles[0],angles[1],angles[2],0.0,TIME,M,dMb,dMl,dMo); //Construct asteroid->Camera frame matrix, which is //asteroid->world frame->camera frame transpose(M,Mt); //Transpose, since we rotate the model, not view directions transpose(dMb,dMbT); transpose(dMl,dMlT); transpose(dMo,dMoT); mult_mat(R,Mt,RT); mult_vector(M,Eo,E); mult_vector(M,E0o,E0); mult_mat(R,dMbT,Rdb); mult_mat(R,dMlT,Rdl); mult_mat(R,dMoT,Rdo); //Derivatives of E,E0 wrt beta,lambda,omega mult_vector(dMb,Eo,dEdb); mult_vector(dMl,Eo,dEdl); mult_vector(dMo,Eo,dEdo); mult_vector(dMb,E0o,dE0db); mult_vector(dMl,E0o,dE0dl); mult_vector(dMo,E0o,dE0do); dadx=RT[0][0]; dady=RT[0][1]; dadz=RT[0][2]; dbdx=RT[1][0]; dbdy=RT[1][1]; dbdz=RT[1][2]; /*For each facet, * 1)Check if facet is visible * 2) Calculate echo * 3) Convert triangle to range-Doppler frame * 4) Calculate FT */ //Find actual blockers FindActualBlockers(tlist,vlist,nfac,nvert,E,E,1,visible); //visible is nfac vector, visible[j]=1 if facet (j+1)th facet is visible //NOTE INDEXING Calculate_Radiance(tlist,vlist,nfac,nvert,angles,Eo,E0o,TIME,Gamma, A,Hdist,WL,N,Flux,Fldx,Fldy,Fldz,FldA,1); //for(int j=0;j<nfac;j++) for(int j=0;j<nfac;j++) { if(visible[j]==0) continue; //Calculate normal from facet vertices //Vertex indices of the current facet //Note that C indices from 0, matlab from 1 j1=tlist[j*3]-1; j2=tlist[j*3+1]-1; j3=tlist[j*3+2]-1; //Current vertices for(int i=0;i<3;i++) { v1[i]=*(vlist+j1*3+i)*dp; //convert km->arcsec v2[i]=*(vlist+j2*3+i)*dp; v3[i]=*(vlist+j3*3+i)*dp; } //Calculate Normal derivatives (in the original frame) Calculate_Area_and_Normal_Derivative(v1,v2,v3,n,dndx1,dndx2,dndx3,dndy1,dndy2,dndy3,dndz1,dndz2,dndz3,&area,dAdx,dAdy,dAdz); //Calculate normals and centroids mu=DOT(E,n); //Convert to camera frame mult_vector(RT,v1,vr1); mult_vector(RT,v2,vr2); mult_vector(RT,v3,vr3); //Now we should convert to frequency domain, ie calculate the contribution of each facet // Calc_FTC(freqx,freqy,nfreq,vr1[0],vr1[1],vr2[0],vr2[1],vr3[0],vr3[1],F0); Calc_FTC_deriv(freqx,freqy,nfreq,vr1[0],vr1[1],vr2[0],vr2[1],vr3[0],vr3[1],F0,FTda,FTdb,FTdc,FTdd,FTdg,FTdh); //Derivatives wrt angles mult_vector(Rdb,v1,v1db); mult_vector(Rdb,v2,v2db); mult_vector(Rdb,v3,v3db); mult_vector(Rdl,v1,v1dl); mult_vector(Rdl,v2,v2dl); mult_vector(Rdl,v3,v3dl); mult_vector(Rdo,v1,v1do); mult_vector(Rdo,v2,v2do); mult_vector(Rdo,v3,v3do); //Derivatives of mu,mu0 dmudx1=DOT(E,dndx1); dmudx2=DOT(E,dndx2); dmudx3=DOT(E,dndx3); dmudy1=DOT(E,dndy1); dmudy2=DOT(E,dndy2); dmudy3=DOT(E,dndy3); dmudz1=DOT(E,dndz1); dmudz2=DOT(E,dndz2); dmudz3=DOT(E,dndz3); dmudb=DOT(dEdb,n); dmudl=DOT(dEdl,n); dmudo=DOT(dEdo,n); B=Flux[j]; //Derivatives of B dBdx1=Fldx[j*nvert+j1]/dp; dBdx2=Fldx[j*nvert+j2]/dp; dBdx3=Fldx[j*nvert+j3]/dp; dBdy1=Fldy[j*nvert+j1]/dp; dBdy2=Fldy[j*nvert+j2]/dp; dBdy3=Fldy[j*nvert+j3]/dp; dBdz1=Fldz[j*nvert+j1]/dp; dBdz2=Fldz[j*nvert+j2]/dp; dBdz3=Fldz[j*nvert+j3]/dp; dBdb=FldA[3*j]; dBdl=FldA[3*j+1]; dBdo=FldA[3*j+2]; //Derivative of total brightness dTBdx[j1]+=dBdx1*area*mu+B*dAdx[0]*mu+B*area*dmudx1; dTBdx[j2]+=dBdx2*area*mu+B*dAdx[1]*mu+B*area*dmudx2; dTBdx[j3]+=dBdx3*area*mu+B*dAdx[2]*mu+B*area*dmudx3; dTBdy[j1]+=dBdy1*area*mu+B*dAdy[0]*mu+B*area*dmudy1; dTBdy[j2]+=dBdy2*area*mu+B*dAdy[1]*mu+B*area*dmudy2; dTBdy[j3]+=dBdy3*area*mu+B*dAdy[2]*mu+B*area*dmudy3; dTBdz[j1]+=dBdz1*area*mu+B*dAdz[0]*mu+B*area*dmudz1; dTBdz[j2]+=dBdz2*area*mu+B*dAdz[1]*mu+B*area*dmudz2; dTBdz[j3]+=dBdz3*area*mu+B*dAdz[2]*mu+B*area*dmudz3; dTBdA[0]+=dBdb*area*mu+B*area*dmudb; dTBdA[1]+=dBdl*area*mu+B*area*dmudl; dTBdA[2]+=dBdo*area*mu+B*area*dmudo; for(int jf=0;jf<nfreq;jf++) { F[jf]+=B*F0[jf]; FTdx[jf*nvert+j1]+=dBdx1*F0[jf]+B*(FTda[jf]*dadx+FTdb[jf]*dbdx); FTdx[jf*nvert+j2]+=dBdx2*F0[jf]+B*(FTdc[jf]*dadx+FTdd[jf]*dbdx); FTdx[jf*nvert+j3]+=dBdx3*F0[jf]+B*(FTdg[jf]*dadx+FTdh[jf]*dbdx); FTdy[jf*nvert+j1]+=dBdy1*F0[jf]+B*(FTda[jf]*dady+FTdb[jf]*dbdy); FTdy[jf*nvert+j2]+=dBdy2*F0[jf]+B*(FTdc[jf]*dady+FTdd[jf]*dbdy); FTdy[jf*nvert+j3]+=dBdy3*F0[jf]+B*(FTdg[jf]*dady+FTdh[jf]*dbdy); FTdz[jf*nvert+j1]+=dBdz1*F0[jf]+B*(FTda[jf]*dadz+FTdb[jf]*dbdz); FTdz[jf*nvert+j2]+=dBdz2*F0[jf]+B*(FTdc[jf]*dadz+FTdd[jf]*dbdz); FTdz[jf*nvert+j3]+=dBdz3*F0[jf]+B*(FTdg[jf]*dadz+FTdh[jf]*dbdz); //angle derivatives FTdA[jf*3+0]+=dBdb*F0[jf]+B*(FTda[jf]*v1db[0]+FTdb[jf]*v1db[1]+FTdc[jf]*v2db[0]+FTdd[jf]*v2db[1]+FTdg[jf]*v3db[0]+FTdh[jf]*v3db[1]); FTdA[jf*3+1]+=dBdl*F0[jf]+B*(FTda[jf]*v1dl[0]+FTdb[jf]*v1dl[1]+FTdc[jf]*v2dl[0]+FTdd[jf]*v2dl[1]+FTdg[jf]*v3dl[0]+FTdh[jf]*v3dl[1]); FTdA[jf*3+2]+=dBdo*F0[jf]+B*(FTda[jf]*v1do[0]+FTdb[jf]*v1do[1]+FTdc[jf]*v2do[0]+FTdd[jf]*v2do[1]+FTdg[jf]*v3do[0]+FTdh[jf]*v3do[1]); } TB=TB+B*area*mu; } //Normalize with total brightness double complex temp; for(int j=0;j<nfreq;j++) { scale=cexp(2.0*PI*I*(offset[0]*freqx[j]+offset[1]*freqy[j])); for(int k=0;k<nvert;k++) { temp=dp*scale*(FTdx[j*nvert+k]*TB-F[j]*dTBdx[k])/pow(TB,2); dFdxr[j*nvert+k]=creal(temp); dFdxi[j*nvert+k]=cimag(temp); temp=dp*scale*(FTdy[j*nvert+k]*TB-F[j]*dTBdy[k])/pow(TB,2); dFdyr[j*nvert+k]=creal(temp); dFdyi[j*nvert+k]=cimag(temp); temp=dp*scale*(FTdz[j*nvert+k]*TB-F[j]*dTBdz[k])/pow(TB,2); dFdzr[j*nvert+k]=creal(temp); dFdzi[j*nvert+k]=cimag(temp); } temp=scale*(FTdA[j*3+0]*TB-F[j]*dTBdA[0])/pow(TB,2); dFdAr[j*3+0]=creal(temp); dFdAi[j*3+0]=cimag(temp); temp=scale*(FTdA[j*3+1]*TB-F[j]*dTBdA[1])/pow(TB,2); dFdAr[j*3+1]=creal(temp); dFdAi[j*3+1]=cimag(temp); temp=scale*(FTdA[j*3+2]*TB-F[j]*dTBdA[2])/pow(TB,2); dFdAr[j*3+2]=creal(temp); dFdAi[j*3+2]=cimag(temp); temp=cexp(2.0*PI*I*(offset[0]*freqx[j]+offset[1]*freqy[j]))*F[j]/TB; Fr[j]=creal(temp); Fi[j]=cimag(temp); temp=2.0*PI*I*freqx[j]*F[j]; dFdoffr[j*2+0]=creal(temp); dFdoffi[j*2+0]=cimag(temp); temp=2.0*PI*I*freqy[j]*F[j]; dFdoffr[j*2+1]=creal(temp); dFdoffi[j*2+1]=cimag(temp); } free(FTdx); free(FTdy); free(FTdz); free(FTdA); free(dTBdx); free(dTBdy); free(dTBdz); free(FTda); free(FTdb); free(FTdc); free(FTdd); free(FTdg); free(FTdh); free(F0); free(visible); free(Flux); free(Fldx); free(Fldy); free(Fldz); free(FldA); free(F); }
double complex cacos(double complex z) { z = casin(z); return CMPLX(M_PI_2 - creal(z), -cimag(z)); }
void cdprintf(double _Complex * in,unsigned N) { putchar('\n'); for(unsigned i=0;i<N;i++) printf("%lf%+lf*I%c",creal(in[i]),cimag(in[i]),i%5==4?'\n':'\t' ); }
void VecSetComplex(Vec vR, Vec vI, int i, int ir, dcomp val, InsertMode addv){ VecSetValue(vR, i, ir? cimag(val) : creal(val), addv ); VecSetValue(vI, i, ir? creal(val) : -cimag(val), addv ); }
VrArrayPtrCF64 BlasComplexDouble::scal_minus(VrArrayPtrCF64 A, double complex scal) { // scal[0]=-scal[0]; //scal[1]=-scal[1]; scal = -creal(scal)-(cimag(scal)*I); return scal_add(VR_GET_NDIMS_CF64(A) , A,scal); }
/** * The main workhorse function for performing the ringdown attachment for EOB * models EOBNRv2 and SEOBNRv1. This is the function which gets called by the * code generating the full IMR waveform once generation of the inspiral part * has been completed. * The ringdown is attached using the hybrid comb matching detailed in * The method is describe in Sec. II C of Pan et al. PRD 84, 124052 (2011), * specifically Eqs. 30 - 32.. Further details of the * implementation of the found in the DCC document T1100433. * In SEOBNRv1, the last physical overtone is replace by a pseudoQNM. See * Taracchini et al. PRD 86, 024011 (2012) for details. * STEP 1) Get mass and spin of the final black hole and the complex ringdown frequencies * STEP 2) Based on least-damped-mode decay time, allocate memory for rigndown waveform * STEP 3) Get values and derivatives of inspiral waveforms at matching comb points * STEP 4) Solve QNM coefficients and generate ringdown waveforms * STEP 5) Stitch inspiral and ringdown waveoforms */ static INT4 XLALSimIMREOBHybridAttachRingdown( REAL8Vector *signal1, /**<< OUTPUT, Real of inspiral waveform to which we attach ringdown */ REAL8Vector *signal2, /**<< OUTPUT, Imag of inspiral waveform to which we attach ringdown */ const INT4 l, /**<< Current mode l */ const INT4 m, /**<< Current mode m */ const REAL8 dt, /**<< Sample time step (in seconds) */ const REAL8 mass1, /**<< First component mass (in Solar masses) */ const REAL8 mass2, /**<< Second component mass (in Solar masses) */ const REAL8 spin1x, /**<<The spin of the first object; only needed for spin waveforms */ const REAL8 spin1y, /**<<The spin of the first object; only needed for spin waveforms */ const REAL8 spin1z, /**<<The spin of the first object; only needed for spin waveforms */ const REAL8 spin2x, /**<<The spin of the second object; only needed for spin waveforms */ const REAL8 spin2y, /**<<The spin of the second object; only needed for spin waveforms */ const REAL8 spin2z, /**<<The spin of the second object; only needed for spin waveforms */ REAL8Vector *timeVec, /**<< Vector containing the time values */ REAL8Vector *matchrange, /**<< Time values chosen as points for performing comb matching */ Approximant approximant /**<<The waveform approximant being used */ ) { COMPLEX16Vector *modefreqs; UINT4 Nrdwave; UINT4 j; UINT4 nmodes; REAL8Vector *rdwave1; REAL8Vector *rdwave2; REAL8Vector *rinspwave; REAL8Vector *dinspwave; REAL8Vector *ddinspwave; REAL8VectorSequence *inspwaves1; REAL8VectorSequence *inspwaves2; REAL8 eta, a, NRPeakOmega22; /* To generate pQNM frequency */ REAL8 mTot; /* In geometric units */ REAL8 spin1[3] = { spin1x, spin1y, spin1z }; REAL8 spin2[3] = { spin2x, spin2y, spin2z }; REAL8 finalMass, finalSpin; mTot = (mass1 + mass2) * LAL_MTSUN_SI; eta = mass1 * mass2 / ( (mass1 + mass2) * (mass1 + mass2) ); /* * STEP 1) Get mass and spin of the final black hole and the complex ringdown frequencies */ /* Create memory for the QNM frequencies */ nmodes = 8; modefreqs = XLALCreateCOMPLEX16Vector( nmodes ); if ( !modefreqs ) { XLAL_ERROR( XLAL_ENOMEM ); } if ( XLALSimIMREOBGenerateQNMFreqV2( modefreqs, mass1, mass2, spin1, spin2, l, m, nmodes, approximant ) == XLAL_FAILURE ) { XLALDestroyCOMPLEX16Vector( modefreqs ); XLAL_ERROR( XLAL_EFUNC ); } /* Call XLALSimIMREOBFinalMassSpin() to get mass and spin of the final black hole */ if ( XLALSimIMREOBFinalMassSpin(&finalMass, &finalSpin, mass1, mass2, spin1, spin2, approximant) == XLAL_FAILURE ) { XLAL_ERROR( XLAL_EFUNC ); } if ( approximant == SEOBNRv1 ) { /* Replace the last QNM with pQNM */ /* We assume aligned/antialigned spins here */ a = (spin1[2] + spin2[2]) / 2. * (1.0 - 2.0 * eta) + (spin1[2] - spin2[2]) / 2. * (mass1 - mass2) / (mass1 + mass2); NRPeakOmega22 = GetNRSpinPeakOmega( l, m, eta, a ) / mTot; /*printf("a and NRomega in QNM freq: %.16e %.16e %.16e %.16e %.16e\n",spin1[2],spin2[2], mTot/LAL_MTSUN_SI,a,NRPeakOmega22*mTot);*/ modefreqs->data[7] = (NRPeakOmega22/finalMass + creal(modefreqs->data[0])) / 2.; modefreqs->data[7] += I * 10./3. * cimag(modefreqs->data[0]); } /*for (j = 0; j < nmodes; j++) { printf("QNM frequencies: %d %d %d %e %e\n",l,m,j,modefreqs->data[j].re*mTot,1./modefreqs->data[j].im/mTot); }*/ /* Ringdown signal length: 10 times the decay time of the n=0 mode */ Nrdwave = (INT4) (EOB_RD_EFOLDS / cimag(modefreqs->data[0]) / dt); /* Check the value of attpos, to prevent memory access problems later */ if ( matchrange->data[0] * mTot / dt < 5 || matchrange->data[1]*mTot/dt > matchrange->data[2] *mTot/dt - 2 ) { XLALPrintError( "More inspiral points needed for ringdown matching.\n" ); //printf("%.16e,%.16e,%.16e\n",matchrange->data[0] * mTot / dt, matchrange->data[1]*mTot/dt, matchrange->data[2] *mTot/dt - 2); XLALDestroyCOMPLEX16Vector( modefreqs ); XLAL_ERROR( XLAL_EFAILED ); } /* * STEP 2) Based on least-damped-mode decay time, allocate memory for rigndown waveform */ /* Create memory for the ring-down and full waveforms, and derivatives of inspirals */ rdwave1 = XLALCreateREAL8Vector( Nrdwave ); rdwave2 = XLALCreateREAL8Vector( Nrdwave ); rinspwave = XLALCreateREAL8Vector( 6 ); dinspwave = XLALCreateREAL8Vector( 6 ); ddinspwave = XLALCreateREAL8Vector( 6 ); inspwaves1 = XLALCreateREAL8VectorSequence( 3, 6 ); inspwaves2 = XLALCreateREAL8VectorSequence( 3, 6 ); /* Check memory was allocated */ if ( !rdwave1 || !rdwave2 || !rinspwave || !dinspwave || !ddinspwave || !inspwaves1 || !inspwaves2 ) { XLALDestroyCOMPLEX16Vector( modefreqs ); if (rdwave1) XLALDestroyREAL8Vector( rdwave1 ); if (rdwave2) XLALDestroyREAL8Vector( rdwave2 ); if (rinspwave) XLALDestroyREAL8Vector( rinspwave ); if (dinspwave) XLALDestroyREAL8Vector( dinspwave ); if (ddinspwave) XLALDestroyREAL8Vector( ddinspwave ); if (inspwaves1) XLALDestroyREAL8VectorSequence( inspwaves1 ); if (inspwaves2) XLALDestroyREAL8VectorSequence( inspwaves2 ); XLAL_ERROR( XLAL_ENOMEM ); } memset( rdwave1->data, 0, rdwave1->length * sizeof( REAL8 ) ); memset( rdwave2->data, 0, rdwave2->length * sizeof( REAL8 ) ); /* * STEP 3) Get values and derivatives of inspiral waveforms at matching comb points */ /* Generate derivatives of the last part of inspiral waves */ /* Get derivatives of signal1 */ if ( XLALGenerateHybridWaveDerivatives( rinspwave, dinspwave, ddinspwave, timeVec, signal1, matchrange, dt, mass1, mass2 ) == XLAL_FAILURE ) { XLALDestroyCOMPLEX16Vector( modefreqs ); XLALDestroyREAL8Vector( rdwave1 ); XLALDestroyREAL8Vector( rdwave2 ); XLALDestroyREAL8Vector( rinspwave ); XLALDestroyREAL8Vector( dinspwave ); XLALDestroyREAL8Vector( ddinspwave ); XLALDestroyREAL8VectorSequence( inspwaves1 ); XLALDestroyREAL8VectorSequence( inspwaves2 ); XLAL_ERROR( XLAL_EFUNC ); } for (j = 0; j < 6; j++) { inspwaves1->data[j] = rinspwave->data[j]; inspwaves1->data[j + 6] = dinspwave->data[j]; inspwaves1->data[j + 12] = ddinspwave->data[j]; } /* Get derivatives of signal2 */ if ( XLALGenerateHybridWaveDerivatives( rinspwave, dinspwave, ddinspwave, timeVec, signal2, matchrange, dt, mass1, mass2 ) == XLAL_FAILURE ) { XLALDestroyCOMPLEX16Vector( modefreqs ); XLALDestroyREAL8Vector( rdwave1 ); XLALDestroyREAL8Vector( rdwave2 ); XLALDestroyREAL8Vector( rinspwave ); XLALDestroyREAL8Vector( dinspwave ); XLALDestroyREAL8Vector( ddinspwave ); XLALDestroyREAL8VectorSequence( inspwaves1 ); XLALDestroyREAL8VectorSequence( inspwaves2 ); XLAL_ERROR( XLAL_EFUNC ); } for (j = 0; j < 6; j++) { inspwaves2->data[j] = rinspwave->data[j]; inspwaves2->data[j + 6] = dinspwave->data[j]; inspwaves2->data[j + 12] = ddinspwave->data[j]; } /* * STEP 4) Solve QNM coefficients and generate ringdown waveforms */ /* Generate ring-down waveforms */ if ( XLALSimIMREOBHybridRingdownWave( rdwave1, rdwave2, dt, mass1, mass2, inspwaves1, inspwaves2, modefreqs, matchrange ) == XLAL_FAILURE ) { XLALDestroyCOMPLEX16Vector( modefreqs ); XLALDestroyREAL8Vector( rdwave1 ); XLALDestroyREAL8Vector( rdwave2 ); XLALDestroyREAL8Vector( rinspwave ); XLALDestroyREAL8Vector( dinspwave ); XLALDestroyREAL8Vector( ddinspwave ); XLALDestroyREAL8VectorSequence( inspwaves1 ); XLALDestroyREAL8VectorSequence( inspwaves2 ); XLAL_ERROR( XLAL_EFUNC ); } /* * STEP 5) Stitch inspiral and ringdown waveoforms */ /* Generate full waveforms, by stitching inspiral and ring-down waveforms */ UINT4 attachIdx = matchrange->data[1] * mTot / dt; for (j = 1; j < Nrdwave; ++j) { signal1->data[j + attachIdx] = rdwave1->data[j]; signal2->data[j + attachIdx] = rdwave2->data[j]; } memset( signal1->data+Nrdwave+attachIdx, 0, (signal1->length - Nrdwave - attachIdx)*sizeof(REAL8) ); memset( signal2->data+Nrdwave+attachIdx, 0, (signal2->length - Nrdwave - attachIdx)*sizeof(REAL8) ); /* Free memory */ XLALDestroyCOMPLEX16Vector( modefreqs ); XLALDestroyREAL8Vector( rdwave1 ); XLALDestroyREAL8Vector( rdwave2 ); XLALDestroyREAL8Vector( rinspwave ); XLALDestroyREAL8Vector( dinspwave ); XLALDestroyREAL8Vector( ddinspwave ); XLALDestroyREAL8VectorSequence( inspwaves1 ); XLALDestroyREAL8VectorSequence( inspwaves2 ); return XLAL_SUCCESS; }
/* * catanh(z) = log((1+z)/(1-z)) / 2 * = log1p(4*x / |z-1|^2) / 4 * + I * atan2(2*y, (1-x)*(1+x)-y*y) / 2 * * catanh(z) = z + O(z^3) as z -> 0 * * catanh(z) = 1/z + sign(y)*I*PI/2 + O(1/z^3) as z -> infinity * The above formula works for the real part as well, because * Re(catanh(z)) = x/|z|^2 + O(x/z^4) * as z -> infinity, uniformly in x */ double complex catanh(double complex z) { double x, y, ax, ay, rx, ry; x = creal(z); y = cimag(z); ax = fabs(x); ay = fabs(y); /* This helps handle many cases. */ if (y == 0 && ax <= 1) return (CMPLX(atanh(x), y)); /* To ensure the same accuracy as atan(), and to filter out z = 0. */ if (x == 0) return (CMPLX(x, atan(y))); if (isnan(x) || isnan(y)) { /* catanh(+-Inf + I*NaN) = +-0 + I*NaN */ if (isinf(x)) return (CMPLX(copysign(0, x), y + y)); /* catanh(NaN + I*+-Inf) = sign(NaN)0 + I*+-PI/2 */ if (isinf(y)) return (CMPLX(copysign(0, x), copysign(pio2_hi + pio2_lo, y))); /* * All other cases involving NaN return NaN + I*NaN. * C99 leaves it optional whether to raise invalid if one of * the arguments is not NaN, so we opt not to raise it. */ return (CMPLX(x + 0.0L + (y + 0), x + 0.0L + (y + 0))); } if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) return (CMPLX(real_part_reciprocal(x, y), copysign(pio2_hi + pio2_lo, y))); if (ax < SQRT_3_EPSILON / 2 && ay < SQRT_3_EPSILON / 2) { /* * z = 0 was filtered out above. All other cases must raise * inexact, but this is the only only that needs to do it * explicitly. */ raise_inexact(); return (z); } if (ax == 1 && ay < DBL_EPSILON) rx = (m_ln2 - log(ay)) / 2; else rx = log1p(4 * ax / sum_squares(ax - 1, ay)) / 4; if (ax == 1) ry = atan2(2, -ay) / 2; else if (ay < DBL_EPSILON) ry = atan2(2 * ay, (1 - ax) * (1 + ax)) / 2; else ry = atan2(2 * ay, (1 - ax) * (1 + ax) - ay * ay) / 2; return (CMPLX(copysign(rx, x), copysign(ry, y))); }