packages feed

feldspar-compiler-0.4.0.2: Feldspar/C/feldspar_c99.c

#include "feldspar_c99.h"

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>

#if defined(WIN32)
  #include <windows.h>
#else
  #include <sys/time.h>
  #include <time.h>
#endif /* WIN32 */



/*--------------------------------------------------------------------------*
 *                 pow(), abs(), signum(), logBase()                        *
 *--------------------------------------------------------------------------*/

int8_t pow_fun_int8( int8_t a, int8_t b )
{
    int8_t r = 1;
    int i;
    if (b < 0) {
        fprintf(stderr, "Negative exponent in function pow_fun_(): %d `pow` %d", a, b);
        exit(1);
    }
    for(i = 0; i < b; ++i)
        r *= a;
    return r;
}

int16_t pow_fun_int16( int16_t a, int16_t b )
{
    int16_t r = 1;
    int i;
    if (b < 0) {
        fprintf(stderr, "Negative exponent in function pow_fun_(): %d `pow` %d", a, b);
        exit(1);
    }
    for(i = 0; i < b; ++i)
        r *= a;
    return r;
}

int32_t pow_fun_int32( int32_t a, int32_t b )
{
    int32_t r = 1;
    int i;
    if (b < 0) {
        fprintf(stderr, "Negative exponent in function pow_fun_(): %d `pow` %d", a, b);
        exit(1);
    }
    for(i = 0; i < b; ++i)
        r *= a;
    return r;
}

int64_t pow_fun_int64( int64_t a, int64_t b )
{
    int64_t r = 1;
    int i;
    if (b < 0) {
        fprintf(stderr, "Negative exponent in function pow_fun_(): %lld `pow` %lld", a, b);
        exit(1);
    }
    for(i = 0; i < b; ++i)
        r *= a;
    return r;
}

uint8_t pow_fun_uint8( uint8_t a, uint8_t b )
{
    uint8_t r = 1;
    int i;
    for(i = 0; i < b; ++i)
        r *= a;
    return r;
}

uint16_t pow_fun_uint16( uint16_t a, uint16_t b )
{
    uint16_t r = 1;
    int i;
    for(i = 0; i < b; ++i)
        r *= a;
    return r;
}

uint32_t pow_fun_uint32( uint32_t a, uint32_t b )
{
    uint32_t r = 1;
    int i;
    for(i = 0; i < b; ++i)
        r *= a;
    return r;
}

uint64_t pow_fun_uint64( uint64_t a, uint64_t b )
{
    uint64_t r = 1;
    int i;
    for(i = 0; i < b; ++i)
        r *= a;
    return r;
}



int8_t abs_fun_int8( int8_t a )
{
    // From Bit Twiddling Hacks:
    //    "Compute the integer absolute value (abs) without branching"
    int8_t mask = a >> 7;
    return (a + mask) ^ mask;
}

int16_t abs_fun_int16( int16_t a )
{
    // From Bit Twiddling Hacks:
    //    "Compute the integer absolute value (abs) without branching"
    int16_t mask = a >> 15;
    return (a + mask) ^ mask;
}

int32_t abs_fun_int32( int32_t a )
{
    // From Bit Twiddling Hacks:
    //    "Compute the integer absolute value (abs) without branching"
    int32_t mask = a >> 31;
    return (a + mask) ^ mask;
}

int64_t abs_fun_int64( int64_t a )
{
    // From Bit Twiddling Hacks:
    //    "Compute the integer absolute value (abs) without branching"
    int64_t mask = a >> 63;
    return (a + mask) ^ mask;
}



int8_t signum_fun_int8( int8_t a )
{
    // From Bit Twiddling Hacks: "Compute the sign of an integer"
    return (a != 0) | (a >> 7);
}

int16_t signum_fun_int16( int16_t a )
{
    // From Bit Twiddling Hacks: "Compute the sign of an integer"
    return (a != 0) | (a >> 15);
}

int32_t signum_fun_int32( int32_t a )
{
    // From Bit Twiddling Hacks: "Compute the sign of an integer"
    return (a != 0) | (a >> 31);
}

int64_t signum_fun_int64( int64_t a )
{
    // From Bit Twiddling Hacks: "Compute the sign of an integer"
    return (a != 0) | (a >> 63);
}

uint8_t signum_fun_uint8( uint8_t a )
{
    return (a > 0);
}

uint16_t signum_fun_uint16( uint16_t a )
{
    return (a > 0);
}

uint32_t signum_fun_uint32( uint32_t a )
{
    return (a > 0);
}

uint64_t signum_fun_uint64( uint64_t a )
{
    return (a > 0);
}

float signum_fun_float( float a )
{
    // From Bit Twiddling Hacks: "Compute the sign of an integer"
    return (a > 0) - (a < 0);
}



float logBase_fun_float( float a, float b )
{
    return logf(b) / logf(a);
}



/*--------------------------------------------------------------------------*
 *                 Bit operations                                           *
 *--------------------------------------------------------------------------*/

int8_t setBit_fun_int8( int8_t x, uint32_t i )
{
    return x | 1 << i;
}

int16_t setBit_fun_int16( int16_t x, uint32_t i )
{
    return x | 1 << i;
}

int32_t setBit_fun_int32( int32_t x, uint32_t i )
{
    return x | 1 << i;
}

int64_t setBit_fun_int64( int64_t x, uint32_t i )
{
    return x | 1 << i;
}

uint8_t setBit_fun_uint8( uint8_t x, uint32_t i )
{
    return x | 1 << i;
}

uint16_t setBit_fun_uint16( uint16_t x, uint32_t i )
{
    return x | 1 << i;
}

uint32_t setBit_fun_uint32( uint32_t x, uint32_t i )
{
    return x | 1 << i;
}

uint64_t setBit_fun_uint64( uint64_t x, uint32_t i )
{
    return x | 1 << i;
}



int8_t clearBit_fun_int8( int8_t x, uint32_t i )
{
    return x & ~(1 << i);
}

int16_t clearBit_fun_int16( int16_t x, uint32_t i )
{
    return x & ~(1 << i);
}

int32_t clearBit_fun_int32( int32_t x, uint32_t i )
{
    return x & ~(1 << i);
}

int64_t clearBit_fun_int64( int64_t x, uint32_t i )
{
    return x & ~(1 << i);
}

uint8_t clearBit_fun_uint8( uint8_t x, uint32_t i )
{
    return x & ~(1 << i);
}

uint16_t clearBit_fun_uint16( uint16_t x, uint32_t i )
{
    return x & ~(1 << i);
}

uint32_t clearBit_fun_uint32( uint32_t x, uint32_t i )
{
    return x & ~(1 << i);
}

uint64_t clearBit_fun_uint64( uint64_t x, uint32_t i )
{
    return x & ~(1 << i);
}



int8_t complementBit_fun_int8( int8_t x, uint32_t i )
{
    return x ^ 1 << i;
}

int16_t complementBit_fun_int16( int16_t x, uint32_t i )
{
    return x ^ 1 << i;
}

int32_t complementBit_fun_int32( int32_t x, uint32_t i )
{
    return x ^ 1 << i;
}

int64_t complementBit_fun_int64( int64_t x, uint32_t i )
{
    return x ^ 1 << i;
}

uint8_t complementBit_fun_uint8( uint8_t x, uint32_t i )
{
    return x ^ 1 << i;
}

uint16_t complementBit_fun_uint16( uint16_t x, uint32_t i )
{
    return x ^ 1 << i;
}

uint32_t complementBit_fun_uint32( uint32_t x, uint32_t i )
{
    return x ^ 1 << i;
}

uint64_t complementBit_fun_uint64( uint64_t x, uint32_t i )
{
    return x ^ 1 << i;
}



int testBit_fun_int8( int8_t x, uint32_t i )
{
    return (x & 1 << i) != 0;
}

int testBit_fun_int16( int16_t x, uint32_t i )
{
    return (x & 1 << i) != 0;
}

int testBit_fun_int32( int32_t x, uint32_t i )
{
    return (x & 1 << i) != 0;
}

int testBit_fun_int64( int64_t x, uint32_t i )
{
    return (x & 1 << i) != 0;
}

int testBit_fun_uint8( uint8_t x, uint32_t i )
{
    return (x & 1 << i) != 0;
}

int testBit_fun_uint16( uint16_t x, uint32_t i )
{
    return (x & 1 << i) != 0;
}

int testBit_fun_uint32( uint32_t x, uint32_t i )
{
    return (x & 1 << i) != 0;
}

int testBit_fun_uint64( uint64_t x, uint32_t i )
{
    return (x & 1 << i) != 0;
}



int8_t rotateL_fun_int8( int8_t x, int32_t i )
{
    if ((i %= 8) == 0) return x;
    return (x << i) | ((0x7f >> (7 - i)) & (x >> (8 - i)));
}

int16_t rotateL_fun_int16( int16_t x, int32_t i )
{
    if ((i %= 16) == 0) return x;
    return (x << i) | ((0x7fff >> (15 - i)) & (x >> (16 - i)));
}

int32_t rotateL_fun_int32( int32_t x, int32_t i )
{
    if ((i %= 32) == 0) return x;
    return (x << i) | ((0x7fffffff >> (31 - i)) & (x >> (32 - i)));
}

int64_t rotateL_fun_int64( int64_t x, int32_t i )
{
    if ((i %= 64) == 0) return x;
    return (x << i) | ((0x7fffffffffffffffll >> (63 - i)) & (x >> (64 - i)));
}

uint8_t rotateL_fun_uint8( uint8_t x, int32_t i )
{
    if ((i %= 8) == 0) return x;
    return (x << i) | (x >> (8 - i));
}

uint16_t rotateL_fun_uint16( uint16_t x, int32_t i )
{
    if ((i %= 16) == 0) return x;
    return (x << i) | (x >> (16 - i));
}

uint32_t rotateL_fun_uint32( uint32_t x, int32_t i )
{
    if ((i %= 32) == 0) return x;
    return (x << i) | (x >> (32 - i));
}

uint64_t rotateL_fun_uint64( uint64_t x, int32_t i )
{
    if ((i %= 64) == 0) return x;
    return (x << i) | (x >> (64 - i));
}



int8_t rotateR_fun_int8( int8_t x, int32_t i )
{
    if ((i %= 8) == 0) return x;
    return (x << (8 - i)) | ((0x7f >> (i - 1)) & (x >> i));
}

int16_t rotateR_fun_int16( int16_t x, int32_t i )
{
    if ((i %= 16) == 0) return x;
    return (x << (16 - i)) | ((0x7fff >> (i - 1)) & (x >> i));
}

int32_t rotateR_fun_int32( int32_t x, int32_t i )
{
    if ((i %= 32) == 0) return x;
    return (x << (32 - i)) | ((0x7fffffff >> (i - 1)) & (x >> i));
}

int64_t rotateR_fun_int64( int64_t x, int32_t i )
{
    if ((i %= 64) == 0) return x;
    return (x << (64 - i)) | ((0x7fffffffffffffffll >> (i - 1)) & (x >> i));
}

uint8_t rotateR_fun_uint8( uint8_t x, int32_t i )
{
    if ((i %= 8) == 0) return x;
    return (x << (8 - i)) | (x >> i);
}

uint16_t rotateR_fun_uint16( uint16_t x, int32_t i )
{
    if ((i %= 16) == 0) return x;
    return (x << (16 - i)) | (x >> i);
}

uint32_t rotateR_fun_uint32( uint32_t x, int32_t i )
{
    if ((i %= 32) == 0) return x;
    return (x << (32 - i)) | (x >> i);
}

uint64_t rotateR_fun_uint64( uint64_t x, int32_t i )
{
    if ((i %= 64) == 0) return x;
    return (x << (64 - i)) | (x >> i);
}



int8_t reverseBits_fun_int8( int8_t x )
{
    int8_t r = x;
    int i = 7;
    for (x = x >> 1 & 0x7f; x; x >>= 1)
    {
        r = (r << 1) | (x & 1);
        --i;
    }
    return r << i;
}

int16_t reverseBits_fun_int16( int16_t x )
{
    int16_t r = x;
    int i = 15;
    for (x = x >> 1 & 0x7fff; x; x >>= 1)
    {
        r = (r << 1) | (x & 1);
        --i;
    }
    return r << i;
}

int32_t reverseBits_fun_int32( int32_t x )
{
    int32_t r = x;
    int i = 31;
    for (x = x >> 1 & 0x7fffffff; x; x >>= 1)
    {
        r = (r << 1) | (x & 1);
        --i;
    }
    return r << i;
}

int64_t reverseBits_fun_int64( int64_t x )
{
    int64_t r = x;
    int i = 63;
    for (x = x >> 1 & 0x7fffffffffffffffll; x; x >>= 1)
    {
        r = (r << 1) | (x & 1);
        --i;
    }
    return r << i;
}

uint8_t reverseBits_fun_uint8( uint8_t x )
{
    uint8_t r = x;
    int i = 7;
    while (x >>= 1)
    {
        r = (r << 1) | (x & 1);
        --i;
    }
    return r << i;
}

uint16_t reverseBits_fun_uint16( uint16_t x )
{
    uint16_t r = x;
    int i = 15;
    while (x >>= 1)
    {
        r = (r << 1) | (x & 1);
        --i;
    }
    return r << i;
}

uint32_t reverseBits_fun_uint32( uint32_t x )
{
    uint32_t r = x;
    int i = 31;
    while (x >>= 1)
    {
        r = (r << 1) | (x & 1);
        --i;
    }
    return r << i;
}

uint64_t reverseBits_fun_uint64( uint64_t x )
{
    uint64_t r = x;
    int i = 63;
    while (x >>= 1)
    {
        r = (r << 1) | (x & 1);
        --i;
    }
    return r << i;
}



uint32_t bitScan_fun_int8( int8_t x )
{
    uint32_t r = 0;
    int8_t s = (x & 0x80);
    if (x == 0) return 7;
    while ((int8_t)((x <<= 1) & 0x80) == s)
        ++r;
    return r;
}

uint32_t bitScan_fun_int16( int16_t x )
{
    uint32_t r = 0;
    int16_t s = (x & 0x8000);
    if (x == 0) return 15;
    while ((int16_t)((x <<= 1) & 0x8000) == s)
        ++r;
    return r;
}

uint32_t bitScan_fun_int32( int32_t x )
{
    uint32_t r = 0;
    int32_t s = (x & 0x80000000);
    if (x == 0) return 31;
    while ((int32_t)((x <<= 1) & 0x80000000) == s)
        ++r;
    return r;
}

uint32_t bitScan_fun_int64( int64_t x )
{
    uint32_t r = 0;
    int64_t s = (x & 0x8000000000000000ll);
    if (x == 0) return 63;
    while ((int64_t)((x <<= 1) & 0x8000000000000000ll) == s)
        ++r;
    return r;
}

uint32_t bitScan_fun_uint8( uint8_t x )
{
    uint32_t r = 8;
    while (x)
    {
        --r;
        x >>= 1;
    }
    return r;
}

uint32_t bitScan_fun_uint16( uint16_t x )
{
    uint32_t r = 16;
    while (x)
    {
        --r;
        x >>= 1;
    }
    return r;
}

uint32_t bitScan_fun_uint32( uint32_t x )
{
    uint32_t r = 32;
    while (x)
    {
        --r;
        x >>= 1;
    }
    return r;
}

uint32_t bitScan_fun_uint64( uint64_t x )
{
    uint32_t r = 64;
    while (x)
    {
        --r;
        x >>= 1;
    }
    return r;
}



uint32_t bitCount_fun_int8( int8_t x )
{
    uint32_t r = x & 1;
    for (x = x >> 1 & 0x7f; x; x >>= 1)
        r += x & 1;
    return r;
}

uint32_t bitCount_fun_int16( int16_t x )
{
    uint32_t r = x & 1;
    for (x = x >> 1 & 0x7fff; x; x >>= 1)
        r += x & 1;
    return r;
}

uint32_t bitCount_fun_int32( int32_t x )
{
    uint32_t r = x & 1;
    for (x = x >> 1 & 0x7fffffff; x; x >>= 1)
        r += x & 1;
    return r;
}

uint32_t bitCount_fun_int64( int64_t x )
{
    uint32_t r = x & 1;
    for (x = x >> 1 & 0x7fffffffffffffffll; x; x >>= 1)
        r += x & 1;
    return r;
}

uint32_t bitCount_fun_uint8( uint8_t x )
{
    uint32_t r = x & 1;
    while (x >>= 1)
        r += x & 1;
    return r;
}

uint32_t bitCount_fun_uint16( uint16_t x )
{
    uint32_t r = x & 1;
    while (x >>= 1)
        r += x & 1;
    return r;
}

uint32_t bitCount_fun_uint32( uint32_t x )
{
    uint32_t r = x & 1;
    while (x >>= 1)
        r += x & 1;
    return r;
}

uint32_t bitCount_fun_uint64( uint64_t x )
{
    uint32_t r = x & 1;
    while (x >>= 1)
        r += x & 1;
    return r;
}



/*--------------------------------------------------------------------------*
 *                 Complex numbers                                          *
 *--------------------------------------------------------------------------*/

int equal_fun_complexOf_int8( complexOf_int8 a, complexOf_int8 b )
{
    return a.re == b.re && a.im == b.im;
}

int equal_fun_complexOf_int16( complexOf_int16 a, complexOf_int16 b )
{
    return a.re == b.re && a.im == b.im;
}

int equal_fun_complexOf_int32( complexOf_int32 a, complexOf_int32 b )
{
    return a.re == b.re && a.im == b.im;
}

int equal_fun_complexOf_int64( complexOf_int64 a, complexOf_int64 b )
{
    return a.re == b.re && a.im == b.im;
}

int equal_fun_complexOf_uint8( complexOf_uint8 a, complexOf_uint8 b )
{
    return a.re == b.re && a.im == b.im;
}

int equal_fun_complexOf_uint16( complexOf_uint16 a, complexOf_uint16 b )
{
    return a.re == b.re && a.im == b.im;
}

int equal_fun_complexOf_uint32( complexOf_uint32 a, complexOf_uint32 b )
{
    return a.re == b.re && a.im == b.im;
}

int equal_fun_complexOf_uint64( complexOf_uint64 a, complexOf_uint64 b )
{
    return a.re == b.re && a.im == b.im;
}



complexOf_int8 negate_fun_complexOf_int8( complexOf_int8 a )
{
    a.re = -a.re;
    a.im = -a.im;
    return a;
}

complexOf_int16 negate_fun_complexOf_int16( complexOf_int16 a )
{
    a.re = -a.re;
    a.im = -a.im;
    return a;
}

complexOf_int32 negate_fun_complexOf_int32( complexOf_int32 a )
{
    a.re = -a.re;
    a.im = -a.im;
    return a;
}

complexOf_int64 negate_fun_complexOf_int64( complexOf_int64 a )
{
    a.re = -a.re;
    a.im = -a.im;
    return a;
}

complexOf_uint8 negate_fun_complexOf_uint8( complexOf_uint8 a )
{
    a.re = -a.re;
    a.im = -a.im;
    return a;
}

complexOf_uint16 negate_fun_complexOf_uint16( complexOf_uint16 a )
{
    a.re = -a.re;
    a.im = -a.im;
    return a;
}

complexOf_uint32 negate_fun_complexOf_uint32( complexOf_uint32 a )
{
    a.re = -a.re;
    a.im = -a.im;
    return a;
}

complexOf_uint64 negate_fun_complexOf_uint64( complexOf_uint64 a )
{
    a.re = -a.re;
    a.im = -a.im;
    return a;
}



complexOf_int8 abs_fun_complexOf_int8( complexOf_int8 a )
{
    a.re = magnitude_fun_complexOf_int8(a);
    a.im = 0;
    return a;
}

complexOf_int16 abs_fun_complexOf_int16( complexOf_int16 a )
{
    a.re = magnitude_fun_complexOf_int16(a);
    a.im = 0;
    return a;
}

complexOf_int32 abs_fun_complexOf_int32( complexOf_int32 a )
{
    a.re = magnitude_fun_complexOf_int32(a);
    a.im = 0;
    return a;
}

complexOf_int64 abs_fun_complexOf_int64( complexOf_int64 a )
{
    a.re = magnitude_fun_complexOf_int64(a);
    a.im = 0;
    return a;
}

complexOf_uint8 abs_fun_complexOf_uint8( complexOf_uint8 a )
{
    a.re = magnitude_fun_complexOf_uint8(a);
    a.im = 0;
    return a;
}

complexOf_uint16 abs_fun_complexOf_uint16( complexOf_uint16 a )
{
    a.re = magnitude_fun_complexOf_uint16(a);
    a.im = 0;
    return a;
}

complexOf_uint32 abs_fun_complexOf_uint32( complexOf_uint32 a )
{
    a.re = magnitude_fun_complexOf_uint32(a);
    a.im = 0;
    return a;
}

complexOf_uint64 abs_fun_complexOf_uint64( complexOf_uint64 a )
{
    a.re = magnitude_fun_complexOf_uint64(a);
    a.im = 0;
    return a;
}



complexOf_int8 signum_fun_complexOf_int8( complexOf_int8 a )
{
    int8_t m;
    if (a.re == 0 && a.im == 0) {
        return a;
    } else {
        m = magnitude_fun_complexOf_int8(a);
        a.re = a.re / m;
        a.im = a.im / m;
        return a;
    }
}

complexOf_int16 signum_fun_complexOf_int16( complexOf_int16 a )
{
    int16_t m;
    if (a.re == 0 && a.im == 0) {
        return a;
    } else {
        m = magnitude_fun_complexOf_int16(a);
        a.re = a.re / m;
        a.im = a.im / m;
        return a;
    }
}

complexOf_int32 signum_fun_complexOf_int32( complexOf_int32 a )
{
    int32_t m;
    if (a.re == 0 && a.im == 0) {
        return a;
    } else {
        m = magnitude_fun_complexOf_int32(a);
        a.re = a.re / m;
        a.im = a.im / m;
        return a;
    }
}

complexOf_int64 signum_fun_complexOf_int64( complexOf_int64 a )
{
    int64_t m;
    if (a.re == 0 && a.im == 0) {
        return a;
    } else {
        m = magnitude_fun_complexOf_int64(a);
        a.re = a.re / m;
        a.im = a.im / m;
        return a;
    }
}

complexOf_uint8 signum_fun_complexOf_uint8( complexOf_uint8 a )
{
    uint8_t m;
    if (a.re == 0 && a.im == 0) {
        return a;
    } else {
        m = magnitude_fun_complexOf_uint8(a);
        a.re = a.re / m;
        a.im = a.im / m;
        return a;
    }
}

complexOf_uint16 signum_fun_complexOf_uint16( complexOf_uint16 a )
{
    uint16_t m;
    if (a.re == 0 && a.im == 0) {
        return a;
    } else {
        m = magnitude_fun_complexOf_uint16(a);
        a.re = a.re / m;
        a.im = a.im / m;
        return a;
    }
}

complexOf_uint32 signum_fun_complexOf_uint32( complexOf_uint32 a )
{
    uint32_t m;
    if (a.re == 0 && a.im == 0) {
        return a;
    } else {
        m = magnitude_fun_complexOf_uint32(a);
        a.re = a.re / m;
        a.im = a.im / m;
        return a;
    }
}

complexOf_uint64 signum_fun_complexOf_uint64( complexOf_uint64 a )
{
    uint64_t m;
    if (a.re == 0 && a.im == 0) {
        return a;
    } else {
        m = magnitude_fun_complexOf_uint64(a);
        a.re = a.re / m;
        a.im = a.im / m;
        return a;
    }
}

float complex signum_fun_complexOf_float( float complex a )
{
    float m;
    if (a == 0) {
        return a;
    } else {
        m = cabsf(a);
        return crealf(a) / m + cimagf(a) / m * I;
    }
}



complexOf_int8 add_fun_complexOf_int8( complexOf_int8 a, complexOf_int8 b )
{
    a.re = a.re + b.re;
    a.im = a.im + b.im;
    return a;
}

complexOf_int16 add_fun_complexOf_int16( complexOf_int16 a, complexOf_int16 b )
{
    a.re = a.re + b.re;
    a.im = a.im + b.im;
    return a;
}

complexOf_int32 add_fun_complexOf_int32( complexOf_int32 a, complexOf_int32 b )
{
    a.re = a.re + b.re;
    a.im = a.im + b.im;
    return a;
}

complexOf_int64 add_fun_complexOf_int64( complexOf_int64 a, complexOf_int64 b )
{
    a.re = a.re + b.re;
    a.im = a.im + b.im;
    return a;
}

complexOf_uint8 add_fun_complexOf_uint8( complexOf_uint8 a, complexOf_uint8 b )
{
    a.re = a.re + b.re;
    a.im = a.im + b.im;
    return a;
}

complexOf_uint16 add_fun_complexOf_uint16( complexOf_uint16 a, complexOf_uint16 b )
{
    a.re = a.re + b.re;
    a.im = a.im + b.im;
    return a;
}

complexOf_uint32 add_fun_complexOf_uint32( complexOf_uint32 a, complexOf_uint32 b )
{
    a.re = a.re + b.re;
    a.im = a.im + b.im;
    return a;
}

complexOf_uint64 add_fun_complexOf_uint64( complexOf_uint64 a, complexOf_uint64 b )
{
    a.re = a.re + b.re;
    a.im = a.im + b.im;
    return a;
}



complexOf_int8 sub_fun_complexOf_int8( complexOf_int8 a, complexOf_int8 b )
{
    a.re = a.re - b.re;
    a.im = a.im - b.im;
    return a;
}

complexOf_int16 sub_fun_complexOf_int16( complexOf_int16 a, complexOf_int16 b )
{
    a.re = a.re - b.re;
    a.im = a.im - b.im;
    return a;
}

complexOf_int32 sub_fun_complexOf_int32( complexOf_int32 a, complexOf_int32 b )
{
    a.re = a.re - b.re;
    a.im = a.im - b.im;
    return a;
}

complexOf_int64 sub_fun_complexOf_int64( complexOf_int64 a, complexOf_int64 b )
{
    a.re = a.re - b.re;
    a.im = a.im - b.im;
    return a;
}

complexOf_uint8 sub_fun_complexOf_uint8( complexOf_uint8 a, complexOf_uint8 b )
{
    a.re = a.re - b.re;
    a.im = a.im - b.im;
    return a;
}

complexOf_uint16 sub_fun_complexOf_uint16( complexOf_uint16 a, complexOf_uint16 b )
{
    a.re = a.re - b.re;
    a.im = a.im - b.im;
    return a;
}

complexOf_uint32 sub_fun_complexOf_uint32( complexOf_uint32 a, complexOf_uint32 b )
{
    a.re = a.re - b.re;
    a.im = a.im - b.im;
    return a;
}

complexOf_uint64 sub_fun_complexOf_uint64( complexOf_uint64 a, complexOf_uint64 b )
{
    a.re = a.re - b.re;
    a.im = a.im - b.im;
    return a;
}



complexOf_int8 mult_fun_complexOf_int8( complexOf_int8 a, complexOf_int8 b )
{
    complexOf_int8 r;
    r.re = a.re * b.re - a.im * b.im;
    r.im = a.im * b.re + a.re * b.im;
    return r;
}

complexOf_int16 mult_fun_complexOf_int16( complexOf_int16 a, complexOf_int16 b )
{
    complexOf_int16 r;
    r.re = a.re * b.re - a.im * b.im;
    r.im = a.im * b.re + a.re * b.im;
    return r;
}

complexOf_int32 mult_fun_complexOf_int32( complexOf_int32 a, complexOf_int32 b )
{
    complexOf_int32 r;
    r.re = a.re * b.re - a.im * b.im;
    r.im = a.im * b.re + a.re * b.im;
    return r;
}

complexOf_int64 mult_fun_complexOf_int64( complexOf_int64 a, complexOf_int64 b )
{
    complexOf_int64 r;
    r.re = a.re * b.re - a.im * b.im;
    r.im = a.im * b.re + a.re * b.im;
    return r;
}

complexOf_uint8 mult_fun_complexOf_uint8( complexOf_uint8 a, complexOf_uint8 b )
{
    complexOf_uint8 r;
    r.re = a.re * b.re - a.im * b.im;
    r.im = a.im * b.re + a.re * b.im;
    return r;
}

complexOf_uint16 mult_fun_complexOf_uint16( complexOf_uint16 a, complexOf_uint16 b )
{
    complexOf_uint16 r;
    r.re = a.re * b.re - a.im * b.im;
    r.im = a.im * b.re + a.re * b.im;
    return r;
}

complexOf_uint32 mult_fun_complexOf_uint32( complexOf_uint32 a, complexOf_uint32 b )
{
    complexOf_uint32 r;
    r.re = a.re * b.re - a.im * b.im;
    r.im = a.im * b.re + a.re * b.im;
    return r;
}

complexOf_uint64 mult_fun_complexOf_uint64( complexOf_uint64 a, complexOf_uint64 b )
{
    complexOf_uint64 r;
    r.re = a.re * b.re - a.im * b.im;
    r.im = a.im * b.re + a.re * b.im;
    return r;
}

#ifdef __FreeBSD__
float complex clogf( float complex x )
{
    return (I * atan2f(cimagf(x), crealf(x))) + logf(cabsf(x));
}
#endif


float complex logBase_fun_complexOf_float( float complex a, float complex b )
{
    return clogf(b) / clogf(a);
}



complexOf_int8 complex_fun_int8( int8_t re, int8_t im )
{
    complexOf_int8 r;
    r.re = re;
    r.im = im;
    return r;
}

complexOf_int16 complex_fun_int16( int16_t re, int16_t im )
{
    complexOf_int16 r;
    r.re = re;
    r.im = im;
    return r;
}

complexOf_int32 complex_fun_int32( int32_t re, int32_t im )
{
    complexOf_int32 r;
    r.re = re;
    r.im = im;
    return r;
}

complexOf_int64 complex_fun_int64( int64_t re, int64_t im )
{
    complexOf_int64 r;
    r.re = re;
    r.im = im;
    return r;
}

complexOf_uint8 complex_fun_uint8( uint8_t re, uint8_t im )
{
    complexOf_uint8 r;
    r.re = re;
    r.im = im;
    return r;
}

complexOf_uint16 complex_fun_uint16( uint16_t re, uint16_t im )
{
    complexOf_uint16 r;
    r.re = re;
    r.im = im;
    return r;
}

complexOf_uint32 complex_fun_uint32( uint32_t re, uint32_t im )
{
    complexOf_uint32 r;
    r.re = re;
    r.im = im;
    return r;
}

complexOf_uint64 complex_fun_uint64( uint64_t re, uint64_t im )
{
    complexOf_uint64 r;
    r.re = re;
    r.im = im;
    return r;
}

float complex complex_fun_float( float re, float im )
{
    return ( re + im * I );
}



int8_t creal_fun_complexOf_int8( complexOf_int8 a )
{
    return a.re;
}

int16_t creal_fun_complexOf_int16( complexOf_int16 a )
{
    return a.re;
}

int32_t creal_fun_complexOf_int32( complexOf_int32 a )
{
    return a.re;
}

int64_t creal_fun_complexOf_int64( complexOf_int64 a )
{
    return a.re;
}

uint8_t creal_fun_complexOf_uint8( complexOf_uint8 a )
{
    return a.re;
}

uint16_t creal_fun_complexOf_uint16( complexOf_uint16 a )
{
    return a.re;
}

uint32_t creal_fun_complexOf_uint32( complexOf_uint32 a )
{
    return a.re;
}

uint64_t creal_fun_complexOf_uint64( complexOf_uint64 a )
{
    return a.re;
}



int8_t cimag_fun_complexOf_int8( complexOf_int8 a )
{
    return a.im;
}

int16_t cimag_fun_complexOf_int16( complexOf_int16 a )
{
    return a.im;
}

int32_t cimag_fun_complexOf_int32( complexOf_int32 a )
{
    return a.im;
}

int64_t cimag_fun_complexOf_int64( complexOf_int64 a )
{
    return a.im;
}

uint8_t cimag_fun_complexOf_uint8( complexOf_uint8 a )
{
    return a.im;
}

uint16_t cimag_fun_complexOf_uint16( complexOf_uint16 a )
{
    return a.im;
}

uint32_t cimag_fun_complexOf_uint32( complexOf_uint32 a )
{
    return a.im;
}

uint64_t cimag_fun_complexOf_uint64( complexOf_uint64 a )
{
    return a.im;
}



complexOf_int8 conj_fun_complexOf_int8( complexOf_int8 a )
{
    a.im = -a.im;
    return a;
}

complexOf_int16 conj_fun_complexOf_int16( complexOf_int16 a )
{
    a.im = -a.im;
    return a;
}

complexOf_int32 conj_fun_complexOf_int32( complexOf_int32 a )
{
    a.im = -a.im;
    return a;
}

complexOf_int64 conj_fun_complexOf_int64( complexOf_int64 a )
{
    a.im = -a.im;
    return a;
}

complexOf_uint8 conj_fun_complexOf_uint8( complexOf_uint8 a )
{
    a.im = -a.im;
    return a;
}

complexOf_uint16 conj_fun_complexOf_uint16( complexOf_uint16 a )
{
    a.im = -a.im;
    return a;
}

complexOf_uint32 conj_fun_complexOf_uint32( complexOf_uint32 a )
{
    a.im = -a.im;
    return a;
}

complexOf_uint64 conj_fun_complexOf_uint64( complexOf_uint64 a )
{
    a.im = -a.im;
    return a;
}



int8_t magnitude_fun_complexOf_int8( complexOf_int8 a )
{
    return lroundf(hypotf(a.re, a.im));
}

int16_t magnitude_fun_complexOf_int16( complexOf_int16 a )
{
    return lroundf(hypotf(a.re, a.im));
}

int32_t magnitude_fun_complexOf_int32( complexOf_int32 a )
{
    return lroundf(hypotf(a.re, a.im));
}

int64_t magnitude_fun_complexOf_int64( complexOf_int64 a )
{
    return llroundf(hypotf(a.re, a.im));
}

uint8_t magnitude_fun_complexOf_uint8( complexOf_uint8 a )
{
    return lroundf(hypotf(a.re, a.im));
}

uint16_t magnitude_fun_complexOf_uint16( complexOf_uint16 a )
{
    return lroundf(hypotf(a.re, a.im));
}

uint32_t magnitude_fun_complexOf_uint32( complexOf_uint32 a )
{
    return lroundf(hypotf(a.re, a.im));
}

uint64_t magnitude_fun_complexOf_uint64( complexOf_uint64 a )
{
    return llroundf(hypotf(a.re, a.im));
}



int8_t phase_fun_complexOf_int8( complexOf_int8 a )
{
    if (a.re == 0 && a.im == 0) return 0;
    else return lroundf(atan2f(a.im, a.re));
}

int16_t phase_fun_complexOf_int16( complexOf_int16 a )
{
    if (a.re == 0 && a.im == 0) return 0;
    else return lroundf(atan2f(a.im, a.re));
}

int32_t phase_fun_complexOf_int32( complexOf_int32 a )
{
    if (a.re == 0 && a.im == 0) return 0;
    else return lroundf(atan2f(a.im, a.re));
}

int64_t phase_fun_complexOf_int64( complexOf_int64 a )
{
    if (a.re == 0 && a.im == 0) return 0;
    else return llroundf(atan2f(a.im, a.re));
}

uint8_t phase_fun_complexOf_uint8( complexOf_uint8 a )
{
    if (a.re == 0 && a.im == 0) return 0;
    else return lroundf(atan2f(a.im, a.re));
}

uint16_t phase_fun_complexOf_uint16( complexOf_uint16 a )
{
    if (a.re == 0 && a.im == 0) return 0;
    else return lroundf(atan2f(a.im, a.re));
}

uint32_t phase_fun_complexOf_uint32( complexOf_uint32 a )
{
    if (a.re == 0 && a.im == 0) return 0;
    else return lroundf(atan2f(a.im, a.re));
}

uint64_t phase_fun_complexOf_uint64( complexOf_uint64 a )
{
    if (a.re == 0 && a.im == 0) return 0;
    else return llroundf(atan2f(a.im, a.re));
}



complexOf_int8 mkPolar_fun_int8( int8_t r, int8_t t )
{
    complexOf_int8 a;
    a.re = lroundf(r * cosf(t));
    a.im = lroundf(r * sinf(t));
    return a;
}

complexOf_int16 mkPolar_fun_int16( int16_t r, int16_t t )
{
    complexOf_int16 a;
    a.re = lroundf(r * cosf(t));
    a.im = lroundf(r * sinf(t));
    return a;
}

complexOf_int32 mkPolar_fun_int32( int32_t r, int32_t t )
{
    complexOf_int32 a;
    a.re = lroundf(r * cosf(t));
    a.im = lroundf(r * sinf(t));
    return a;
}

complexOf_int64 mkPolar_fun_int64( int64_t r, int64_t t )
{
    complexOf_int64 a;
    a.re = llroundf(r * cosf(t));
    a.im = llroundf(r * sinf(t));
    return a;
}

complexOf_uint8 mkPolar_fun_uint8( uint8_t r, uint8_t t )
{
    complexOf_uint8 a;
    a.re = lroundf(r * cosf(t));
    a.im = lroundf(r * sinf(t));
    return a;
}

complexOf_uint16 mkPolar_fun_uint16( uint16_t r, uint16_t t )
{
    complexOf_uint16 a;
    a.re = lroundf(r * cosf(t));
    a.im = lroundf(r * sinf(t));
    return a;
}

complexOf_uint32 mkPolar_fun_uint32( uint32_t r, uint32_t t )
{
    complexOf_uint32 a;
    a.re = lroundf(r * cosf(t));
    a.im = lroundf(r * sinf(t));
    return a;
}

complexOf_uint64 mkPolar_fun_uint64( uint64_t r, uint64_t t )
{
    complexOf_uint64 a;
    a.re = llroundf(r * cosf(t));
    a.im = llroundf(r * sinf(t));
    return a;
}

float complex mkPolar_fun_float( float r, float t )
{
    return r * cosf(t) + r * sinf(t) * I;
}



complexOf_int8 cis_fun_int8( int8_t t )
{
    complexOf_int8 r;
    r.re = lroundf(cosf(t));
    r.im = lroundf(sinf(t));
    return r;
}

complexOf_int16 cis_fun_int16( int16_t t )
{
    complexOf_int16 r;
    r.re = lroundf(cosf(t));
    r.im = lroundf(sinf(t));
    return r;
}

complexOf_int32 cis_fun_int32( int32_t t )
{
    complexOf_int32 r;
    r.re = lroundf(cosf(t));
    r.im = lroundf(sinf(t));
    return r;
}

complexOf_int64 cis_fun_int64( int64_t t )
{
    complexOf_int64 r;
    r.re = llroundf(cosf(t));
    r.im = llroundf(sinf(t));
    return r;
}

complexOf_uint8 cis_fun_uint8( uint8_t t )
{
    complexOf_uint8 r;
    r.re = lroundf(cosf(t));
    r.im = lroundf(sinf(t));
    return r;
}

complexOf_uint16 cis_fun_uint16( uint16_t t )
{
    complexOf_uint16 r;
    r.re = lroundf(cosf(t));
    r.im = lroundf(sinf(t));
    return r;
}

complexOf_uint32 cis_fun_uint32( uint32_t t )
{
    complexOf_uint32 r;
    r.re = lroundf(cosf(t));
    r.im = lroundf(sinf(t));
    return r;
}

complexOf_uint64 cis_fun_uint64( uint64_t t )
{
    complexOf_uint64 r;
    r.re = llroundf(cosf(t));
    r.im = llroundf(sinf(t));
    return r;
}

float complex cis_fun_float( float t )
{
    return cosf(t) + sinf(t) * I;
}



/*--------------------------------------------------------------------------*
 *                 Trace functions                                          *
 *--------------------------------------------------------------------------*/

static FILE *trace_log_file;

#if defined(WIN32)

static DWORD trace_start_time;

void traceStart()
{
    SYSTEMTIME lt;
    GetLocalTime(&lt);
    char str [256];
    sprintf(str, "trace-%04d%02d%02d-%02d%02d%02d.log",
          lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond);
    trace_log_file = fopen(str, "a");
    if (trace_log_file == NULL) {
        fprintf(stderr,"Can not open trace file.\n");
        exit (8);
    }
    fprintf(trace_log_file,
          "Logging started at %02d-%02d-%04d %02d:%02d:%02d.\n",
          lt.wDay, lt.wMonth, lt.wYear, lt.wHour, lt.wMinute, lt.wSecond);
    fflush(trace_log_file);
    trace_start_time = GetTickCount();
}

void elapsedTimeString( char* str )
{
    DWORD diff_ms = GetTickCount() - trace_start_time;
    DWORD diff = diff_ms / 1000;
    diff_ms = diff_ms % 1000;
    sprintf(str, "%d.%.3d", diff, diff_ms);
}

#else

static struct timeval trace_start_time;

void traceStart()
{
    gettimeofday(&trace_start_time, NULL);
    struct tm * timeinfo = localtime(&(trace_start_time.tv_sec));
    char timestr [80];
    char str [256];
    strftime(timestr, 80, "%Y%m%d-%H%M%S", timeinfo);
    sprintf(str, "trace-%s.log", timestr);
    trace_log_file = fopen(str, "a");
    if (trace_log_file == NULL) {
        fprintf(stderr,"Can not open trace file.\n");
        exit (8);
    }
    strftime(timestr, 80, "%d-%b-%Y %H:%M:%S", timeinfo);
    fprintf(trace_log_file, "Logging started at %s.\n", timestr);
    fflush(trace_log_file);
    gettimeofday(&trace_start_time, NULL);
}

void elapsedTimeString( char* str )
{
    struct timeval tv;
    gettimeofday (&tv, NULL);
    if (trace_start_time.tv_usec <= tv.tv_usec) {
        tv.tv_sec = tv.tv_sec - trace_start_time.tv_sec;
        tv.tv_usec = tv.tv_usec - trace_start_time.tv_usec;
    } else {
        tv.tv_sec = tv.tv_sec - trace_start_time.tv_sec - 1;
        tv.tv_usec = 1000000 + tv.tv_usec - trace_start_time.tv_usec;
    }
    sprintf(str, "%ld.%06ld", tv.tv_sec, tv.tv_usec);
}

#endif /* WIN32 */

void traceEnd()
{
    fprintf(trace_log_file, "Logging finished.\n");
    fclose(trace_log_file);
}

void trace_int8( int8_t val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%d\n", id, timestr, val);
    fflush(trace_log_file);
}

void trace_int16( int16_t val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%d\n", id, timestr, val);
    fflush(trace_log_file);
}

void trace_int32( int32_t val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%d\n", id, timestr, val);
    fflush(trace_log_file);
}

void trace_int64( int64_t val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%lld\n", id, timestr, val);
    fflush(trace_log_file);
}

void trace_uint8( uint8_t val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%u\n", id, timestr, val);
    fflush(trace_log_file);
}

void trace_uint16( uint16_t val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%u\n", id, timestr, val);
    fflush(trace_log_file);
}

void trace_uint32( uint32_t val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%u\n", id, timestr, val);
    fflush(trace_log_file);
}

void trace_uint64( uint64_t val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%llu\n", id, timestr, val);
    fflush(trace_log_file);
}

void trace_float( float val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%f\n", id, timestr, val);
    fflush(trace_log_file);
}

void trace_complexOf_int8( complexOf_int8 val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%d+%d*I\n", id, timestr, val.re, val.im);
    fflush(trace_log_file);
}

void trace_complexOf_int16( complexOf_int16 val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%d+%d*I\n", id, timestr, val.re, val.im);
    fflush(trace_log_file);
}

void trace_complexOf_int32( complexOf_int32 val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%d+%d*I\n", id, timestr, val.re, val.im);
    fflush(trace_log_file);
}

void trace_complexOf_int64( complexOf_int64 val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%lld+%lld*I\n", id, timestr, val.re, val.im);
    fflush(trace_log_file);
}

void trace_complexOf_uint8( complexOf_uint8 val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%u+%u*I\n", id, timestr, val.re, val.im);
    fflush(trace_log_file);
}

void trace_complexOf_uint16( complexOf_uint16 val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%u+%u*I\n", id, timestr, val.re, val.im);
    fflush(trace_log_file);
}

void trace_complexOf_uint32( complexOf_uint32 val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%u+%u*I\n", id, timestr, val.re, val.im);
    fflush(trace_log_file);
}

void trace_complexOf_uint64( complexOf_uint64 val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%llu+%llu*I\n", id, timestr, val.re, val.im);
    fflush(trace_log_file);
}

void trace_complexOf_float( float complex val, int32_t id )
{
    char timestr [80];
    elapsedTimeString(timestr);
    fprintf(trace_log_file, "id=%d, time=%s, value=%f+%f*I\n", id, timestr, creal(val), cimag(val));
    fflush(trace_log_file);
}