#include "c4.h"

C4Complex c4_complex_create(double r,
                            double i)
{
  C4Complex c;

  if(!(c = (C4Complex)
       malloc(sizeof(struct Complex)))) {
    fprintf(stderr,
            "c4_complex_create: memory exhausted\n");
    return(NULL);
  }

  c->r = r;
  c->i = i;

  return(c);
}

void c4_complex_destroy(C4Complex c)
{
  free(c);
}

C4Complex c4_complex_set(C4Complex c,
                         double r,
                         double i)
{
  if(!c)
    c = c4_complex_create(r,i);
  else {
    c->r = r;
    c->i = i;
  }

  return(c);
}

C4Complex c4_complex_copy(C4Complex c_dest,
                          C4Complex c_src)
{
  if(!c_dest)
    c_dest = c4_complex_create(c_src->r,c_src->i);
  else {
    c_dest->r = c_src->r;
    c_dest->i = c_src->i;
  }

  return(c_dest);
}

C4Complex c4_complex_add(C4Complex c1,
                         C4Complex c2,
                         C4Complex c3)
{
  if(!c3)
    c3 = c4_complex_create(0,0);

  c3->r = c1->r + c2->r;
  c3->i = c1->i + c2->i;

  return(c3);
}

C4Complex c4_complex_mul(C4Complex c1,
                         C4Complex c2,
                         C4Complex c3)
{
  if(!c3)
    c3 = c4_complex_create(0,0);

  c3->r = (c1->r * c1->r) - (c1->i * c1->i);
  c3->i = (c1->r * c2->i) + (c1->i * c1->r);

  return(c3);
}

double c4_complex_size(C4Complex c)
{
  /* return((c->r * c->r) + (c->i * c->i)); */

  /* This bogus size metric gives some nice
   * results; let's use it instead */

  return((c->r * c->r) - (c->i * c->i));
}
