static complex complex_sin(complex a) { /* sin(z) = -i * (e^(i * z) - e^(-i * z)) / 2 */ /* cos(z) = (e^(i * z) - e^(-i * z)) / 2 */ complex c, d, i; c = a; d = a; i.real = 0; i.imag = 1; /* inefficient but I just want to see the picture */ mult(&c, i); i.imag = -i.imag; mult(&d, i); complex_exp(&c); complex_exp(&d); d.real = -d.real; d.imag = -d.imag; add(&c, d); c.real = c.real / 2; c.imag = c.imag / 2; mult(&c, i); return c; }
static void renumber_one_part( ComplexWithLog edge_parameters[3]) { ComplexWithLog temp; int i; /* * Swap the indices on edges 1 and 2. */ temp = edge_parameters[1]; edge_parameters[1] = edge_parameters[2]; edge_parameters[2] = temp; /* * Invert the modulus of each edge parameter, but leave * the angles the same. */ for (i = 0; i < 3; i++) { edge_parameters[i].log.real = - edge_parameters[i].log.real; edge_parameters[i].rect = complex_exp(edge_parameters[i].log); } }
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); } }
static complex complex_pow(complex a, complex b) { /* a^z = e^(z * ln(a)) */ complex c, d; c = a; d = b; cln(&c); mult(&d, c); complex_exp(&d); return d; }
int32_t main ( int32_t argc, char * argv[] ) { complex_t x,y,z; complex_init(x,1.0,0.0); complex_init(y,0.0,1.0); complex_mul(z,y,y); complex_exp(z,y,10); dbg_print("exp of"); dbg_complex_print(y); dbg_print("is"); dbg_complex_print(z); return 0; }
static void add_complex_with_log( ComplexWithLog *cwl0, Orientation eo0, ComplexWithLog *cwl1, Orientation eo1, ComplexWithLog *cwl2, Orientation eo2) { /* * First compute the sum of the logs, then recover * the rectangular form. * * We do all computations relative to the Orientation * of the EdgeClass. So if a particular edge is seen * as left_handed by the EdgeClass, we must negate the * real part of the log of its complex angle. (Recall * that all all TetShapes are stored relative to the * right_handed Orientation of the Tetrahedron.) */ Complex summand0, summand1, sum; summand0 = cwl0->log; if (eo0 == left_handed) summand0.real = - summand0.real; summand1 = cwl1->log; if (eo1 == left_handed) summand1.real = - summand1.real; sum = complex_plus(summand0, summand1); if (eo2 == left_handed) sum.real = - sum.real; normalize_angle(&sum.imag); cwl2->log = sum; cwl2->rect = complex_exp(sum); }