complex_float complex_cot(complex_float c1){ // this is 1/tan = 1/(sin/cos) = cos/sin complex_float cpx_sin = complex_sin(c1); complex_float cpx_cos = complex_cos(c1); complex_float r = complex_div(cpx_cos,cpx_sin); return r; }
void complex_gamma (complex_t *dst, complex_t const *src) { if (complex_real_p (src)) { complex_init (dst, gnm_gamma (src->re), 0); } else if (src->re < 0) { /* Gamma(z) = pi / (sin(pi*z) * Gamma(-z+1)) */ complex_t a, b, mz; complex_init (&mz, -src->re, -src->im); complex_fact (&a, &mz); complex_init (&b, M_PIgnum * gnm_fmod (src->re, 2), M_PIgnum * src->im); /* Hmm... sin overflows when b.im is large. */ complex_sin (&b, &b); complex_mul (&a, &a, &b); complex_init (&b, M_PIgnum, 0); complex_div (dst, &b, &a); } else { complex_t zmh, zmhd2, zmhpg, f, f2, p, q, pq; int i; i = G_N_ELEMENTS(lanczos_num) - 1; complex_init (&p, lanczos_num[i], 0); complex_init (&q, lanczos_denom[i], 0); while (--i >= 0) { complex_mul (&p, &p, src); p.re += lanczos_num[i]; complex_mul (&q, &q, src); q.re += lanczos_denom[i]; } complex_div (&pq, &p, &q); complex_init (&zmh, src->re - 0.5, src->im); complex_init (&zmhpg, zmh.re + lanczos_g, zmh.im); complex_init (&zmhd2, zmh.re * 0.5, zmh.im * 0.5); complex_pow (&f, &zmhpg, &zmhd2); zmh.re = -zmh.re; zmh.im = -zmh.im; complex_exp (&f2, &zmh); complex_mul (&f2, &f, &f2); complex_mul (&f2, &f2, &f); complex_mul (dst, &f2, &pq); } }
void sinc(double x, double y) { if (x == 0.0 && y == 0.0) { resultR = 1.0; resultI = 0; } else { if (x != 0.0 || y != 0.0) { complex_sin(M_PI*x, M_PI*y); division(resultR, resultI, M_PI*x, M_PI*y); } else { if (rasf > 0.0) { printf("\nError in function domain.\n\n ==> For normalized sinc function the valid domain is [-INF, INF].\n\n"); printf(" ==> Your function argument: "); complexNumber(x, y); } } } }
/* do the iterations * if binary is true, check halfplane of last iteration. * if demrange is non zero, estimate lower bound of dist(c, M) * * DEM - Distance Estimator Method * Based on Peitgen & Saupe's "The Science of Fractal Images" * * ALPHA - level sets of closest return. * INDEX - index of ALPHA. * Based on Peitgen & Richter's "The Beauty of Fractals" (Fig 33,34) * * LYAPUNOV - lyapunov exponent estimate * Based on an idea by Jan Thor * */ static int reps(complex c, double p, int r, Bool binary, interior_t interior, double demrange, Bool zpow, Bool zsin) { int rep; int escaped = 0; complex t; int escape = (int) ((demrange == 0) ? ESCAPE : ESCAPE*ESCAPE*ESCAPE*ESCAPE); /* 2 more iterations */ complex t1; complex dt; double L = 0.0; double l2; double dl2 = 1.0; double alpha2 = ESCAPE; int index = 0; #if defined(USE_LOG) double log_top = log((double) r); #endif t = c; dt.real = 1; dt.imag = 0; for (rep = 0; rep < r; rep++) { t1 = t; ipow(&t, (int) p); add(&t, c); if (zpow) add(&t, complex_pow(t1, t1)); if (zsin) add(&t, complex_sin(t1)); l2 = t.real * t.real + t.imag * t.imag; if (l2 <= alpha2) { alpha2 = l2; index = rep; } if (l2 >= escape) { escaped = 1; break; } else if (interior == LYAPUNOV) { /* Crude estimate of Lyapunov exponent. The stronger the attractor, the more negative the exponent will be. */ /* n=N L = lim 1/N * Sum log(abs(dx(n+1)/dx(n)))/ln(2) N->inf n=1 */ L += log(sqrt(l2)); } if (demrange){ /* compute dt/dc * p-1 * dt = p * t * dt + 1 * k+1 k k */ /* Note this is incorrect for zpow or zsin, but a correct implementation is too slow to be useful. */ dt.real *= p; dt.imag *= p; if(p > 2) ipow(&t1, (int) (p - 1)); mult(&dt, t1); dt.real += 1; dl2 = dt.real * dt.real + dt.imag * dt.imag; if (dl2 >= 1e300) { escaped = 2; break; } } } if (escaped) { if(demrange) { double mt = sqrt(t1.real * t1.real + t1.imag * t1.imag); /* distance estimate */ double dist = 0.5 * mt * log(mt) / sqrt(dl2); /* scale for viewing. Allow black when showing interior. */ rep = (int) (((interior > NONE)?0:1) + 10*r*dist/demrange); if(rep > r-1) rep = r-1; /* chop into color range */ } if(binary && t.imag > 0) rep = (r + rep / 2) % r; /* binary decomp */ #ifdef USE_LOG if ( rep > 0 ) rep = (int) (r * log((double) rep)/log_top); /* Log Scale */ #endif return rep; } else if (interior == LYAPUNOV) { return -(int)(L/M_LN2) % r; } else if (interior == INDEX) { return 1 + index; } else if (interior == ALPHA) { return (int) (r * sqrt(alpha2)); } else return r; }
complex_float complex_tan(complex_float c1){ complex_float cpx_sin = complex_sin(c1); complex_float cpx_cos = complex_cos(c1); complex_float r = complex_div( cpx_sin, cpx_cos ); return r; }
complex_float complex_csc(complex_float c1){ // this is 1/sin complex_float cpx_sin = complex_sin(c1); complex_float r = complex_div(complex_make(1.0f),cpx_sin); return r; }