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;
}
Exemple #2
0
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);
	}
}
Exemple #3
0
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;
}
Exemple #5
0
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;
}
Exemple #6
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);
}