// This may look like C code, but it is really -*- C++ -*-

/*
 *  Copyright (c) University of Aizu
 */

#include <stdarg.h>

#include "Cvector.h"

#ifdef __GNUG__
#pragma implementation
#endif

Cvector::Cvector(int size, int pos, const complex& val)
{
  v = new complex[sz = size];
  for (int i = 0; i < size; i++) v[i] = 0;
  v[pos] = val;
}

Cvector::Cvector(int size, const complex& initial)
{
  v = new complex[sz = size];
  for (int i = 0; i < size; i++) v[i] = initial;
}

Cvector::Cvector(const Cvector& source)
{
  v = new complex[sz = source.sz];
  for (int i = 0; i < sz; i++) v[i] = source.v[i];
}

Cvector::~Cvector()
{
  delete [] v;
}

complex& Cvector::operator [](int i) const
{
  return v[i];
}

complex& Cvector::elem(int i) const
{
  return v[i];
}

int Cvector::len() const
{
  return sz;
}

Cvector& Cvector::operator =  (const Cvector& y)
{
  for (int i = 0; i < sz; i++) v[i] = y.v[i];
  return *this;
}

Cvector& Cvector::operator =  (const complex& y)
{
  for (int i = 0; i < sz; i++) v[i] = y;
  return *this;
}


Cvector& Cvector::operator -  ()
{
  for (int i = 0; i < sz; i++) v[i] *= -1;
  return *this;
}

Cvector& Cvector::operator +  ()
{
  return *this;
}

Cvector& Cvector::operator += (const Cvector& y)
{
  for (int i = 0; i < sz; i++) v[i] += y.v[i];
  return *this;
}

Cvector& Cvector::operator -= (const Cvector& y)
{
  for (int i = 0; i < sz; i++) v[i] -= y.v[i];
  return *this;
}

Cvector& Cvector::operator *= (const complex& z)
{
  for (int i = 0; i < sz; i++) v[i] *= z;
  return *this;
}

Cvector& Cvector::operator /= (const complex& z) 
{
  for (int i = 0; i < sz; i++) v[i] /= z;
  return *this;
}

void Cvector::set(double initial ...) 
{
  va_list ap;
  double value;

  va_start(ap, initial);
  v[0] = complex(initial);
  for (int index = 1; value = va_arg(ap, double); index++)
    if (index == sz)
      break;
    else
      v[index] = complex(value);
  va_end(ap);
}

void Cvector::set(int initial ...) 
{
  va_list ap;
  int value;


  va_start(ap, initial);
  v[0] = complex(double(initial));
  for (int index = 1; value = va_arg(ap, int); index++)
    if (index == sz)
      break;
    else
      v[index] = complex(double(value));
  va_end(ap);
}

void Cvector::set(float initial ...) 
{
  va_list ap;
  float value;

  va_start(ap, initial);
  v[0] = complex(double(initial));
  for (int index = 1; value = va_arg(ap, double); index++)
    if (index == sz)
      break;
    else
      v[index] = complex(double(value));
  va_end(ap);
}

Cvector operator  * (const complex& z, const Cvector& x)
{
  Cvector result(x.sz);
  for (int i = 0; i < x.sz; i++) result.v[i] = x.v[i] * z;
  return result;
}

Cvector operator  * (const Cvector& x, const complex& z)
{
  Cvector result(x.sz);
  for (int i = 0; i < x.sz; i++) result.v[i] = x.v[i] * z;
  return result;
}

Cvector operator  / (const Cvector& x, const complex& z)
{
  Cvector result(x.sz);
  for (int i = 0; i < x.sz; i++) result.v[i] = x.v[i] / z;
  return result;
}

complex operator  * (const Cvector& x, const Cvector& y)
{
  complex result(0);
  for (int i = 0; i < x.sz; i++) result += x.v[i] * y.v[i];
  return result;
}

Cvector operator  + (const Cvector& x, const Cvector& y)
{
  Cvector result(x.sz);
  for (int i = 0; i < x.sz; i++) result.v[i] = x.v[i] + y.v[i];
  return result;
}

Cvector operator  - (const Cvector& x, const Cvector& y)
{
  Cvector result(x.sz);
  for (int i = 0; i < x.sz; i++) result.v[i] = x.v[i] - y.v[i];
  return result;
}


int operator == (const Cvector& x, const Cvector& y)
{
  int result = 0;
  for (int i = 0; i < x.sz; i++) if (!(result = (x.v[i] == y.v[i]))) break;
  return result;
}

double norm(const Cvector& x)
{
  double result = 0;
  double abs_value;
  for (int i = 0; i < x.sz; i++) {
    abs_value = abs(x.v[i]);
    if (abs_value > result) result = abs_value;
  }
  return result;
}

complex max(const Cvector& x)
{
  complex result;
  double maximum = 0;
  double abs_value;
  for (int i = 0; i < x.sz; i++) {
    abs_value = abs(x.v[i]);
    if (abs_value > maximum) {
      maximum = abs_value;
      result  = x.v[i];
    }
  }
  return result;
}

int operator != (const Cvector& x, const Cvector& y)
{
  return !(x == y);
}

istream&  operator >> (istream& s, Cvector& x)
{
  for (int i = 0; i < x.sz; i++)
    s >> x.v[i];
  return s;
}

ostream&  operator << (ostream& s, const Cvector& x)
{
  s << "[ ";
  for (int i = 0; i < x.sz; i++)
    s << x.v[i];
  s << " ]" << endl;
  return s;
}





