/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/Vector.h,v 1.1.1.1 2004/06/04 13:01:13 kamenik Exp $ */

/* Tag $Name:  $ */

#ifndef VECTOR_H
#define VECTOR_H

/* NOTE! Vector and ConstVector have not common super class in order
 * to avoid running virtual method invokation mechanism. Some
 * members, and methods are thus duplicated */ 

#include <cstdio>

class GeneralMatrix;
class ConstVector;

class Vector {
protected:
	int len;
	int s;
	double* data;
	bool destroy;
public:
	Vector() : len(0), s(1), data(0), destroy(false) {}
	Vector(int l) : len(l), s(1), data(new double[l]), destroy(true) {}
	Vector(Vector& v) : len(v.length()), s(v.skip()), data(v.base()), destroy(false) {}
	Vector(const Vector& v);
	Vector(const ConstVector& v);
	Vector(const double* d, int l)
		: len(l), s(1), data(new double[len]), destroy(true)
		{copy(d, 1);}
	Vector(double* d, int l)
		: len(l), s(1), data(d), destroy(false) {}
	Vector(double* d, int skip, int l)
		: len(l), s(skip), data(d), destroy(false) {}
	Vector(Vector& v, int off, int l);
	Vector(const Vector& v, int off, int l);
	Vector(GeneralMatrix& m, int col);
	Vector(int row, GeneralMatrix& m);
	const Vector& operator=(const Vector& v);
	const Vector& operator=(const ConstVector& v);
	double& operator[](int i)
		{return data[s*i];}
	const double& operator[](int i) const
		{return data[s*i];}
	const double* base() const
		{return data;}
	double* base()
		{return data;}
	int length() const
		{return len;}
	int skip() const
		{return s;}

	/** Exact equality. */
	bool operator==(const Vector& y) const;
	bool operator!=(const Vector& y) const;
	/** Lexicographic ordering. */
	bool operator<(const Vector& y) const;
	bool operator<=(const Vector& y) const;
	bool operator>(const Vector& y) const;
	bool operator>=(const Vector& y) const;

	virtual ~Vector();
	void zeros();
	void nans();
	void infs();
	bool toBeDestroyed() const {return destroy;}
	void rotatePair(double alpha, double beta1, double beta2, int i);
	void add(double r, const Vector& v);
	void add(double r, const ConstVector& v);
	void add(const double* z, const Vector& v);
	void add(const double* z, const ConstVector& v);
	void mult(double r);
	double getNorm() const;
	double getMax() const;
	double getNorm1() const;
	double dot(const Vector& y) const;
	bool isFinite() const;
	void print() const;

	/* multiplies | alpha -beta1|           |b1|   |x1|
                  |             |\otimes I .|  | = |  |
                  | -beta2 alpha|           |b2|   |x2|
	*/
	static void mult2(double alpha, double beta1, double beta2,
					  Vector& x1, Vector& x2,
					  const Vector& b1, const Vector& b2);
	/* same, but adds instead of set */
	static void mult2a(double alpha, double beta1, double beta2,
					   Vector& x1, Vector& x2,
					   const Vector& b1, const Vector& b2);
	/* same, but subtracts instead of add */
	static void mult2s(double alpha, double beta1, double beta2,
					   Vector& x1, Vector& x2,
					   const Vector& b1, const Vector& b2)
		{mult2a(-alpha, -beta1, -beta2, x1, x2, b1, b2);}
private:
	void copy(const double* d, int inc);
	const Vector& operator=(int); // must not be used (not implemented)
	const Vector& operator=(double); // must not be used (not implemented)
};


class BaseConstVector {
protected:
	int len;
	int s;
	const double* data;
public:
	BaseConstVector(int l, int si, const double* d) : len(l), s(si), data(d) {}
	BaseConstVector(const BaseConstVector& v) : len(v.len), s(v.s), data(v.data) {}
	const BaseConstVector& operator=(const BaseConstVector& v)
		{len = v.len; s = v.s; data = v.data; return *this;}
	const double& operator[](int i) const
		{return data[s*i];}
	const double* base() const
		{return data;}
	int length() const
		{return len;}
	int skip() const
		{return s;}
};

class ConstGeneralMatrix;

class ConstVector : public BaseConstVector {
public:
	ConstVector(const Vector& v) : BaseConstVector(v.length(), v.skip(), v.base()) {}
	ConstVector(const ConstVector& v) : BaseConstVector(v) {}
	ConstVector(const double* d, int l) : BaseConstVector(l, 1, d) {}
	ConstVector(const Vector& v, int off, int l);
	ConstVector(const ConstVector& v, int off, int l);
	ConstVector(const double* d, int skip, int l);
	ConstVector(const ConstGeneralMatrix& m, int col);
	ConstVector(int row, const ConstGeneralMatrix& m);
	
	virtual ~ConstVector() {}
	/** Exact equality. */
	bool operator==(const ConstVector& y) const;
	bool operator!=(const ConstVector& y) const
		{return ! operator==(y);}
	/** Lexicographic ordering. */
	bool operator<(const ConstVector& y) const;
	bool operator<=(const ConstVector& y) const
		{return operator<(y) || operator==(y);}
	bool operator>(const ConstVector& y) const
		{return ! operator<=(y);}
	bool operator>=(const ConstVector& y) const
		{return ! operator<(y);}

	double getNorm() const;
	double getMax() const;
	double getNorm1() const;
	double dot(const ConstVector& y) const;
	bool isFinite() const;
	void print() const;
};

class ZeroPad {
public:
	static const int length = 16;
private:
	double pad[16];
public:
	ZeroPad();
	const double* getBase() const {return pad;} 
};

#endif /* VECTOR_H */


// Local Variables:
// mode:C++
// End:
