/** @(#) matrixdouble/vectordouble.h */
#ifndef VECTORDOUBLE_H
#define VECTORDOUBLE_H
//----------------------------------------------------------------------------
#include "../utilpos/interfacepos.h"
#include "../mathpos/mathpos.h"	// MACHEPS
#include <fstream>	// read2ColumnsFromFile()
#include <sstream>	// toString()
#include <iomanip>
#include <iostream>
#include <string>
#include <stdexcept>	// runtime_error
using namespace std;

/**
* Representacion de un vector.
* Caso: Logica uno.
* 	La primera fila y columna si se usan.
* 	La memoria solicitada es de (nr x nc).
* @author Omar Posada Villarreal
* @version 1.3, 12/03/2002 actualizar <<, print
* @version 1.2, 04/03/2002 Actualizar con RectangularDouble
* @version 1.1, 03/03/2002 operator*
* @version 1.0, 02/03/2002
*/
class VectorDouble {
	friend class RectangularMatrix;
	friend class SquaredMatrix;
        
	friend ostream & operator<<(
        	ostream &outStr, const VectorDouble &theVector);
        friend istream & operator>>(istream &inpStr, VectorDouble &theVector);
public:
	// Se necesita un constructor sin parametros theSize = 1
	VectorDouble(int theSize = 1, int theLogic = 0, bool clean = true);
	VectorDouble(VectorDouble &source);

	// Para funciones fuera de clases, usar deleteArray
	~VectorDouble();

        // Se elimino rebuild, no usar valores por omision
        void resize(int theSize, int theLogic, bool cleanMe);
	void copyFrom(VectorDouble &source);


	void multiply(double escalar, VectorDouble &product)
        		throw (invalid_argument);
	VectorDouble operator*(double right);
	double operator*(VectorDouble &right) throw(invalid_argument);
	double & operator()(int index)
		throw (invalid_argument);
	const double & operator()(int index) const
		throw (invalid_argument);
	VectorDouble operator+(VectorDouble &right);
	VectorDouble operator-(VectorDouble &right);
	const VectorDouble & operator=(const VectorDouble &right);

	void readElements();
	bool hasAlmostZeros();
        void fill(double value);
        // Uso con cuidado
	void deleteArray();
	void print(int digits);
	string toString(int digits = 6, char separator = '\t');

        // Logica result = left.operation(right);
	VectorDouble inverse();
	// ver operator * double innerProduct(VectorDouble &right);
	VectorDouble diagonalProduct(VectorDouble &right);
	double infinityNorm();
	double norm1();
	double norm2();
	double generalNorm(double p);

	static void read2ColumnsFromFile(string pathFile,
		VectorDouble &v1, VectorDouble &v2)
                throw (runtime_error);


        /** Limpia el vector con 0.0. */
        void clean() {
        	fill(0.0);
        }
        /** @return Logica del vector. */
        int getLogic() const {
        	return logic;
        }
        /** @param theLogic Nueva logica del vector. */
        void setLogic(int theLogic) {
        	logic = (theLogic ? 1 : 0);
        }
	/** @return El taman~o del vector. */
        int getSize() const {
        	return size;
        }
	/** Poder usar Numerical Recipes. ADVERTENCIA: Puede ser mal usado. */
	/*double *getArray() { // const {?
		return v;
	}*/

        /**
        * No hay necesidad se sobrecargar operator=
        * @param index Indice del elemento a obtener.
        * @return El elemento del indice.
        */
        double & operator[](int index) {
		return v[index - logic];
        }
        /** @version const Sino error por rvalue. */
        const double & operator[](int index) const {
		return v[index - logic];
        }

private:
        /** Taman~o del vector. */
        int size;
	/** Logica del arreglo, solo es valido logica 0 y 1.
	* Es el numero donde se encuentra el primer elemento: A[0] o A[1]. */
	int logic;
       	/** Almacenar elementos. */
	double *v;
};
//----------------------------------------------------------------------------
#endif
// Fin------------------------------------------------------------------------