Esempio n. 1
0
complex_list *compute_subtrahend (complex_node *mnode,complex_list *arow)
{
	int decision;
	double real,imag;

	complex_node *num,*den,*anode,*snode;
	complex_list *subtr;
		
	subtr = (complex_list *) malloc (sizeof(complex_list)); 
	complex_list_init (subtr,"Subtrahend");
	
	anode = arow->head;

	while (anode != NULL) {
		//printf ("\nM: (%d , %d)\tA: (%d , %d)",mnode->row,mnode->col,anode->row,anode->col);
		
		if (anode->col >= mnode->row) {
			snode = (complex_node *) malloc (sizeof(complex_node));
			snode = complex_mult (mnode,anode);
			complex_list_append (subtr,snode);
		} 
		anode=anode->next;
	}
	return subtr;
}
Esempio n. 2
0
// input: pointer to an array of complex input samples
// ouptut: pointer to an array where the result can be placed.
// n : the number of samples.
// step: what level are we currently at in the fft
// preconditions:
//		input and output are valid pointers
//		input and output are of size n
// 	n must be a power of 2.
// DFT is defined as X(n) = sum( x[n] * e^(-2jnk*pi/N ) for n = 0 to N-1
static int _fft_run(complex_t* input, complex_t* output, int n, int step, int offset){
	if( n == 1){
		output[0] = input[0];
		return 1;
	}

	complex_t even_output[n/2];
	complex_t odd_output[n/2];
	_fft_run(input, even_output, n/2, 2*step,offset);
	_fft_run(input+step, odd_output, n/2, 2*step, offset+1);

	int i = 0;
	complex_t Y_k,Z_k,W;
	for( i = 0;i < n/2; ++i){
		Y_k = even_output[i];
		Z_k = odd_output[i];	

		W = twiddle(n, i);
		complex_t temp;
		complex_mult(&W,&Z_k,&temp);

		output[i].re = Y_k.re + temp.re;
		output[i].im = Y_k.im + temp.im;

		output[i + n/2].re = Y_k.re - temp.re;
		output[i + n/2].im = Y_k.im - temp.im;
	}
	return 1;
}
Esempio n. 3
0
static void calc_powers(complex_t x, int max_power, complex_t* dst) {
    int i;
    dst[0] = complex_from_real(1.0);
    if (max_power >= 1)
        dst[1] = x;
    for (i = 2; i <= max_power; ++i)
        dst[i] = complex_mult(x, dst[i - 1]);
}
// The evaluation of the derivative happens here in
// the same way as the funtion bove.
_complex df(_complex z, int grad, double poly[]){
    int i;
    _complex df;
    df=complex_init(grad*poly[grad],0);
    for(i=grad-1;i>0;i--){
        df=complex_sum(complex_mult(df,z),complex_init(i*poly[i],0));
    }
    return df;
}
// Here the polynomial function is evaluated at a point Z
// in the complex plane.
_complex f(_complex z, int grad, double poly[]){
    int i;
    _complex f;
    f=complex_init(poly[grad],0);
    for(i=grad-1;i>=0;i--){
        f=complex_sum(complex_mult(f,z),complex_init(poly[i],0));
    }
    return f;
}
Esempio n. 6
0
static inline void butterfly(osk_complex_t* r, const osk_complex_t* tf, int idx_a, int idx_b)
{
	osk_complex_t up = r[idx_a];
	osk_complex_t dn = r[idx_b];

	//r[idx_a] = up + tf * dn;
	//r[idx_b] = up - tf * dn;
	osk_complex_t dntf = complex_mult(&dn, tf);
	r[idx_a] = complex_add(&up, &dntf);
	r[idx_b] = complex_sub(&up, &dntf);
}
Esempio n. 7
0
/* Based on http://en.wikipedia.org/wiki/Quartic_function#Quick_and_memorable_solution_from_first_principles */
static int solve_depressed_quartic(const complex_t* poly, complex_t* results) {
    complex_t helper_cubic[4];
    complex_t helper_results[3];
    complex_t quadratic_factor[3];
	complex_t p, c_plus_p_sqr, d_div_p;
    const complex_t e = poly[0];
    const complex_t d = poly[1];
    const complex_t c = poly[2];
	int num_results;
    if (complex_eq(d, complex_from_real(0.0))) {
		int i, num_quad_results;
        complex_t quadratic[3];
        complex_t quadratic_results[2];
        quadratic[0] = e;
        quadratic[1] = c;
        quadratic[2] = complex_from_real(1.0);
        num_quad_results = solve_poly(2, quadratic, quadratic_results);
        for (i = 0; i < num_quad_results; ++i) {
            const complex_t s = complex_sqrt(quadratic_results[i]);
            results[2*i] = complex_negate(s);
            results[2*i + 1] = s;
        }
        return 2 * num_quad_results;
    }
    helper_cubic[0] = complex_negate(complex_mult(d, d));
    helper_cubic[1] = complex_add(complex_mult(c, c), complex_mult_real(-4.0, e));
    helper_cubic[2] = complex_mult_real(2.0, c);
    helper_cubic[3] = complex_from_real(1.0);
    if (solve_poly(3, helper_cubic, helper_results) < 1)
        return 0;
    p = complex_sqrt(helper_results[0]);
    c_plus_p_sqr = complex_add(c, complex_mult(p, p));
    d_div_p = complex_div(d, p);
    quadratic_factor[0] = complex_add(c_plus_p_sqr, complex_negate(d_div_p));
    quadratic_factor[1] = complex_mult_real(2.0, p);
    quadratic_factor[2] = complex_from_real(2.0);
    num_results = solve_poly(2, quadratic_factor, results);
    quadratic_factor[0] = complex_add(c_plus_p_sqr, d_div_p);
    quadratic_factor[1] = complex_negate(quadratic_factor[1]);
    return num_results + solve_poly(2, quadratic_factor, results + num_results);
}
Esempio n. 8
0
/* Based on http://en.wikipedia.org/wiki/Cubic_equation#Cardano.27s_method */
static int solve_depressed_cubic(const complex_t* poly, complex_t* results) {
    const complex_t q = poly[0];
    const complex_t p = poly[1];
    complex_t t, u, cubic_root_of_unity;
    int i;
    if (complex_eq(p, complex_from_real(0.0))) {
        results[0] = complex_pow_real(complex_negate(q), 1.0/3.0);
        return 1;
    }
    t = complex_add(
        complex_mult_real(0.25, complex_mult(q, q)),
        complex_mult_real(1.0/27.0, complex_mult(p, complex_mult(p, p))));
    cubic_root_of_unity.real = -0.5;
    cubic_root_of_unity.imag = 0.5 * sqrt(3.0);
    for (i = 0; i < 3; ++i) {
        if (i == 0)
            u = complex_pow_real(complex_add(complex_mult_real(-0.5, q), complex_sqrt(t)), 1.0/3.0);
        else
            u = complex_mult(u, cubic_root_of_unity);
        results[i] = complex_add(u, complex_div(p, complex_mult_real(-3.0, u)));
    }
    return 3;
}
Esempio n. 9
0
int main(unsigned long long speid, unsigned long long argp, unsigned long long envp)
{

    printf("Hello World! from Cell (0x%llx) with argp (0x%llx) \n", speid, argp); // TODO use argp

    float a[M] __attribute__ ((aligned(16))) = {10, 20, 0, 0, 0, 0, 0, 0};

    float b[M] __attribute__ ((aligned(16))) = {1, 2, 0, 0, 0, 0, 0, 0};


    float c[M] __attribute__ ((aligned(16)));
    printf("%f\n", dot_product(a, b, M));
    complex_mult (in1, in2, out, N);

    return 0;
}
Esempio n. 10
0
int _fft(complex_t* input, complex_t* output, unsigned n){
	jig_input(input,output,n);

	int level = 0;
	int num_levels = bit_len(n);
	int block_size = 2;
	for( level = num_levels-1; level != 0 ; --level){

		int num_blocks = n / block_size;
		int segment = 0;		

		complex_t Y_k,Z_k,W;
		complex_t* out;
		for(segment = 0; segment < num_blocks; ++segment){		
			out = output + segment*block_size;

			int i = 0;
			for( i = 0; i< block_size/2; ++i){				
				Y_k = out[i];
				Z_k = out[i +block_size/2];	

				W = twiddle(block_size, i);
				complex_t temp;
				complex_mult(&W,&Z_k,&temp);

				out[i].re = Y_k.re + temp.re;
				out[i].im = Y_k.im + temp.im;

				out[i + block_size/2].re = Y_k.re - temp.re;
				out[i + block_size/2].im = Y_k.im - temp.im;
			}
		}
		block_size *= 2;
	}
	return 1;
}
Esempio n. 11
0
static void calc_shifted_coefs(complex_t shift, int degree, const complex_t* src, complex_t* dst) {
    double binomials[MAX_DEGREE + 1][MAX_DEGREE + 1];
    complex_t shift_powers[MAX_DEGREE + 1];
    int dst_i, src_i;
    for (dst_i = 0; dst_i <= degree; ++dst_i)
        dst[dst_i] = complex_from_real(0.0);
    calc_binomials(degree+1, sizeof(binomials[0]) / sizeof(binomials[0][0]), binomials[0]);
    calc_powers(shift, degree, shift_powers);
    for (src_i = 0; src_i <= degree; ++src_i)
        for (dst_i = 0; dst_i <= src_i; ++dst_i)
            dst[dst_i] = complex_add(dst[dst_i], complex_mult_real(binomials[src_i][dst_i], complex_mult(src[src_i], shift_powers[src_i - dst_i])));
}
Esempio n. 12
0
static complex_t complex_div(complex_t a, complex_t b) {
    return complex_mult(a, complex_inverse(b));
}
Esempio n. 13
0
static void compute_translation(
    PositionedTet   *initial_ptet,
    PeripheralCurve which_curve,
    TraceDirection  which_direction,
    Complex         translation[2], /* returns translations based on ultimate   */
                                    /* and penultimate shapes                   */
    FillingStatus   which_structure)
{
    PositionedTet   ptet;
    int             i,
                    initial_strand,
                    strand,
                    *this_vertex,
                    near_strands,
                    left_strands;
    Complex         left_endpoint[2],   /*  left_endpoint[ultimate/penultimate]     */
                    right_endpoint[2],  /*  right_endpoint[ultimate/penultimate]    */
                    old_diff,
                    new_diff,
                    rotation;

    /*
     *  Place the near edge of the top vertex of the initial_ptet in the
     *  complex plane with its left endpoint at zero and its right endpoint at one.
     *  Trace the curve which_curve in the direction which_direction, using the
     *  shapes of the ideal tetrahedra to compute the position of endpoints of
     *  each edge we cross.  When we return to our starting point in the manifold,
     *  the position of the left endpoint (or the position of the right endpoint
     *  minus one) will tell us the translation.
     *
     *  Note that we are working in the orientation double cover of the cusp.
     *
     *  Here's how we keep track of where we are.  At each step, we are always
     *  at the near edge of the top vertex (i.e. the truncated vertex opposite
     *  the bottom face) of the PositionedTet ptet.  The curve (i.e. the
     *  meridian or longitude) may cross that edge several times.  The variable
     *  "strand" keeps track of which intersection we are at;  0 means we're at
     *  the strand on the far left, 1 means we're at the next strand, etc.
     */

    ptet            = *initial_ptet;
    initial_strand  = 0;
    strand          = initial_strand;
    for (i = 0; i < 2; i++)     /* i = ultimate, penultimate */
    {
        left_endpoint[i]    = Zero;
        right_endpoint[i]   = One;
    }

    do
    {
        /*
         *  Note the curve's intersection numbers with the near side and left side.
         */
        this_vertex =   ptet.tet->curve[which_curve][ptet.orientation][ptet.bottom_face];
        near_strands = this_vertex[ptet.near_face];
        left_strands = this_vertex[ptet.left_face];

        /*
         *  If we are tracing the curve backwards, negate the intersection numbers
         *  so the rest of compute_translation() can enjoy the illusion that we
         *  are tracing the curve forwards.
         */
        if (which_direction == trace_backwards)
        {
            near_strands = - near_strands;
            left_strands = - left_strands;
        }

        /*
         *  Does the current strand bend to the left or to the right?
         */

        if (strand < FLOW(near_strands, left_strands))
        {
            /*
             *  The current strand bends to the left.
             */

            /*
             *  The left_endpoint remains fixed.
             *  Update the right_endpoint.
             *
             *  The plan is to compute the vector old_diff which runs
             *  from left_endpoint to right_endpoint, multiply it by the
             *  complex edge parameter to get the vector new_diff which
             *  runs from left_endpoint to the new value of right_endpoint,
             *  and then add new_diff to left_endpoint to get the new
             *  value of right_endpoint itself.
             *
             *  Note that the complex edge parameters are always expressed
             *  relative to the right_handed Orientation, so if we are
             *  viewing this Tetrahedron relative to the left_handed
             *  Orientation, we must take the conjugate-inverse of the
             *  edge parameter.
             */
            for (i = 0; i < 2; i++)     /* i = ultimate, penultimate */
            {
                old_diff = complex_minus(right_endpoint[i], left_endpoint[i]);
                rotation = ptet.tet->shape[which_structure]->cwl[i][edge3_between_faces[ptet.near_face][ptet.left_face]].rect;
                if (ptet.orientation == left_handed)
                {
                    rotation        = complex_div(One, rotation);   /* invert . . .         */
                    rotation.imag   = - rotation.imag;              /* . . . and conjugate  */
                }
                new_diff = complex_mult(old_diff, rotation);
                right_endpoint[i] = complex_plus(left_endpoint[i], new_diff);
            }

            /*
             *  strand remains unchanged.
             */

            /*
             *  Move the PositionedTet onward, following the curve.
             */
            veer_left(&ptet);

        }
        else
        {
            /*
             *  The current strand bends to the right.
             *
             *  Proceed as above, but note that
             *
             *  (1) We now divide by the complex edge parameter
             *      instead of multiplying by it.
             *
             *  (2) We must adjust the variable "strand".  Some of the strands
             *      from the near edge may be peeling off to the left (in which
             *      case left_strands is negative), or some strands from the left
             *      edge may be joining those from the near edge in passing to
             *      the right edge (in which case left_strands is positive).
             *      Either way, the code "strand += left_strands" is correct.
             */

            for (i = 0; i < 2; i++)     /* i = ultimate, penultimate */
            {
                old_diff = complex_minus(left_endpoint[i], right_endpoint[i]);
                rotation = ptet.tet->shape[which_structure]->cwl[i][edge3_between_faces[ptet.near_face][ptet.right_face]].rect;
                if (ptet.orientation == left_handed)
                {
                    rotation        = complex_div(One, rotation);
                    rotation.imag   = - rotation.imag;
                }
                new_diff = complex_div(old_diff, rotation);
                left_endpoint[i] = complex_plus(right_endpoint[i], new_diff);
            }

            strand += left_strands;

            veer_right(&ptet);

        }
    }
    while ( ! same_positioned_tet(&ptet, initial_ptet) || strand != initial_strand);

    /*
     *  Write the computed translations, and return.
     */

    for (i = 0; i < 2; i++)     /* i = ultimate, penultimate */
        translation[i] = left_endpoint[i];
}
Esempio n. 14
0
void compute_fourth_corner(
	Complex			corner[4],
	VertexIndex		missing_corner,
	Orientation		orientation,
	ComplexWithLog	cwl[3])
{
	int			i;
	VertexIndex	v[4];
	Complex		z[4],
				cross_ratio,
				diff20,
				diff21,
				numerator,
				denominator;

	/*
	 *	Given the locations on the sphere at infinity in
	 *	the upper half space model of three of a Tetrahedron's
	 *	four ideal vertices, compute_fourth_corner() computes
	 *	the location of the remaining corner.
	 *
	 *	corner[4]		is the array which contains the three known
	 *					corners, and into which the fourth will be
	 *					written.
	 *
	 *	missing_corner	is the index of the unknown corner.
	 *
	 *	orientation		is the Orientation with which the Tetrahedron
	 *					is currently being viewed.
	 *
	 *	cwl[3]			describes the shape of the Tetrahedron.
	 */

	/*
	 *	Set up an indexing scheme v[] for the vertices.
	 *
	 *	If some vertex (!= missing_corner) is positioned at infinity, let its
	 *	index be v0.  Otherwise choose v0 arbitrarily.  Then choose
	 *	v2 and v3 so that the Tetrahedron looks right_handed relative
	 *	to the v[].
	 */

	v[3] = missing_corner;

	v[0] = ! missing_corner;
	for (i = 0; i < 4; i++)
		if (i != missing_corner && complex_infinite(corner[i]))
			v[0] = i;

	if (orientation == right_handed)
	{
		v[1] = remaining_face[v[3]][v[0]];
		v[2] = remaining_face[v[0]][v[3]];
	}
	else
	{
		v[1] = remaining_face[v[0]][v[3]];
		v[2] = remaining_face[v[3]][v[0]];
	}

	/*
	 *	Let z[i] be the location of v[i].
	 *	The z[i] are known for i < 3, unknown for i == 3.
	 */

	for (i = 0; i < 3; i++)
		z[i] = corner[v[i]];

	/*
	 *	Note the cross_ratio at the edge connecting v0 to v1.
	 */

	cross_ratio = cwl[edge3_between_faces[v[0]][v[1]]].rect;
	if (orientation == left_handed)
		cross_ratio = complex_conjugate(complex_div(One, cross_ratio));

	/*
	 *	The cross ratio is defined as
	 *
	 *						(z3 - z1) (z2 - z0)
	 *		cross_ratio = -----------------------
	 *						(z2 - z1) (z3 - z0)
	 *
	 *	Solve for z3.
	 *
	 *				z1*(z2 - z0) - cross_ratio*z0*(z2 - z1)
	 *		  z3 = -----------------------------------------
	 *				   (z2 - z0) - cross_ratio*(z2 - z1)
	 *
	 *	If z0 is infinite, this reduces to
	 *
	 *		z3 = z1  +  cross_ratio * (z2 - z1)
	 *
	 *	which makes sense geometrically.
	 */

	if (complex_infinite(z[0]) == TRUE)

		z[3] =	complex_plus(
					z[1],
					complex_mult(
						cross_ratio,
						complex_minus(z[2], z[1])
					)
				);
	else
	{
		diff20 = complex_minus(z[2], z[0]);
		diff21 = complex_minus(z[2], z[1]);

		numerator	  =	complex_minus(
							complex_mult(z[1], diff20),
							complex_mult(
								cross_ratio,
								complex_mult(z[0], diff21)
							)
						);
		denominator	  = complex_minus(
							diff20,
							complex_mult(cross_ratio, diff21)
						);

		z[3] = complex_div(numerator, denominator);   /* will handle division by Zero correctly */
	}

	corner[missing_corner] = z[3];
}