failure

template vector (unsuccessful)

    A. First Edition

    This is just for fun. My memory is so bad that I forget what I write one month ago. And this is actually a

    similar approach compared with my previous one. (I discovered the previous "workspace" accidentally.)

    B.The problem

I am learning linear algebra and want to describe this topic in c++. But it is not so easy..

C.The idea of program

¡¡

There is several failed points.

First the "..." operator is not reliable when the data type of template is double. I cannot figure out how c++

passes parameter when the type is double.

Second, I originally want to reduce the basis to an echelon format and then use it to test if a vector is inside

the space. But it is not right? I am confused about the algorithm.

Third the division of double and integer is always a painful issue. During reduction procedure of echelon

format, I want to avoid integer division and use multiplication instead of division. Then the integer is quickly

busted.

How to describe a linear operator F: V--->U where U, V are vector space?

    D.The major functions

    ¡¡

    E.Further improvement

    ¡¡

    F.File listing

    1. vector.h

    2. main.cpp

    ¡¡

    file name: vector.h

    #include <iostream>
    #include <cmath>
    #include <iomanip>

    using namespace std;

    const double Limit=1000;

    template<class T, int size>
    class Vector
    {
    protected:
    	T array[size];//the number of tuple
    public:
    	Vector(T elem, ...);
    	Vector();
    	Vector(const Vector& other);//copy constructor
    	Vector& operator=(const Vector& other);
    	bool operator==(const Vector& other);
    	bool operator!=(const Vector& other){return !this->operator==(other);}
    	Vector& operator+(const Vector& other);
    	Vector& operator-(const Vector& other);
    	Vector& operator*(T scalar);
    	Vector& operator/(T scalar);
    	T operator[](int index);
    	void display() const;
    	void display();
    	void shrink();
    };

    template<class T, int size>
    ostream& operator<<(ostream& out, const Vector<T, size>& vector);

    template<class T, int size, int dimension>
    class VectorArray
    {
    protected:
    	//the two size have different meaning in math
    	//since the maximum dimension of Vector is size
    	//and I cannot use object array because Vector is not instanciated
    	//pointer array is the only choice
    	Vector<T, size>* array[dimension];
    public:
    	//I must pass value instead of reference, otherwise the pointer won't be right
    	VectorArray(Vector<T, size> vector1, ...);
    	VectorArray();
    	VectorArray& operator=(const VectorArray& other);
    	Vector<T, size>& operator[](int index);
    	VectorArray(VectorArray& other);
    	~VectorArray();
    	void display()const;
    	void display();

    };

    template<class T, int size, int dimension>
    class Space
    {
    protected:
    	VectorArray<T, size, dimension> basis;
    	VectorArray<T, size, dimension> echelon;
    public:
    	//must pass by value
    	void simplify();
    	Space(Vector<T, size> vector1, ...);
    	void display();
    	bool belong(Vector<T, size>& vector);
    };

    template<class T, int size, int dimension>
    ostream& operator<<(ostream& out, const VectorArray<T, size, dimension>& dummy);

    template<class T, int size, int dimension>
    void Space<T, size, dimension>::display()
    {
    	printf("the original basis:\n");
    	basis.display();
    	printf("the echelon basis:\n");
    	echelon.display();
    }

    template<class T, int size, int dimension>
    bool Space<T, size, dimension>::belong(Vector<T, size>& vector)
    {
    	double var[size];
    	for (int i=size-1; i>=0; i--)
    	{
    		var[i]=vector[i];
    		for (int j=i+1; j<size; j++)
    		{
    			var[i]-=var[j]*echelon[i][j];
    		}
    		if (echelon[i][i]!=0)
    		{
    			var[i]/=echelon[i][i];
    		}
    	}
    	return var[0]==vector[0];
    }

    template<class T, int size, int dimension>
    void Space<T, size, dimension>::simplify()
    {
    	Vector<T, size> temp;
    	T top, bottom;
    	echelon=basis;
    	for (int c=0; c<size; c++)
    	{
    		if (c>=dimension)
    		{
    			break;
    		}
    		//swap for non-zero vector
    		if (echelon[c][c]==0)
    		{
    			for (int i=c; i<dimension; i++)
    			{
    				if (echelon[i][c]!=0)
    				{
    					temp=echelon[c];
    					echelon[c]=echelon[i];
    					echelon[i]=temp;
    					break;
    				}
    			}
    		}
    		/*
    		if (echelon[c][c]>Limit)
    		{
    			echelon[c]/echelon[c][c];
    		}
    		*/
    		for (int r=c+1; r<dimension; r++)
    		{
    			//display();
    			echelon[c].shrink();
    			echelon[r].shrink();
    			temp=echelon[c];//the top vector
    			top=echelon[r][c];//
    			/*
    			if (top>Limit)
    			{
    				echelon[r]/top;
    				top=1;
    			}
    			*/
    			bottom=echelon[c][c];
    			temp*top;//scale
    			echelon[r]*bottom;
    			echelon[r]-temp;
    		}
    	}
    }

    template<class T, int size, int dimension>
    Space<T, size, dimension>::Space<T, size, dimension>(Vector<T, size> vector1, ...)
    {
    	Vector<T, size>* ptr=&vector1;
    	for (int i=0; i<dimension; i++)
    	{
    		//reference, not pointer here by overloading []
    		basis[i]=*ptr;
    		ptr++;
    	}
    }

    template<class T, int size, int dimension>
    VectorArray<T, size, dimension>::VectorArray<T, size, dimension>
    (VectorArray<T, size, dimension>& other)
    {
    	for (int i=0; i<dimension; i++)
    	{
    		array[i]=new Vector<T, size>;
    		*array[i]=*other.array[i];
    	}
    }

    template<class T, int size, int dimension>
    VectorArray<T, size, dimension>& VectorArray<T, size, dimension>::operator=
    	(const VectorArray<T, size, dimension>& other)
    {
    	for (int i=0; i<dimension; i++)
    	{
    		*array[i]=*other.array[i];
    	}
    	return *this;
    }

    template<class T, int size, int dimension>
    Vector<T, size>& VectorArray<T, size, dimension>::operator [](int index)
    {
    	if (index<dimension&&index>=0)
    	{
    		return *array[index];
    	}
    	else
    	{
    		//printf("index exceeds size\n");
    		throw "index exceeds size";
    	}
    }

    template<class T, int size, int dimension>
    VectorArray<T, size, dimension>::VectorArray<T, size, dimension>()
    {
    	for (int i=0; i<dimension; i++)
    	{
    		array[i]=new Vector<T, size>;
    	}
    }

    template<class T, int size, int dimension>
    VectorArray<T, size, dimension>::~VectorArray<T, size, dimension>()
    {
    	for (int i=0; i<dimension; i++)
    	{
    		delete array[i];
    	}
    }

    template<class T, int size, int dimension>
    VectorArray<T, size, dimension>::VectorArray<T, size, dimension>(Vector<T, size> vector1, ...)
    {
    	Vector<T, size>* ptr=&vector1;
    	for (int i=0; i<dimension; i++)
    	{
    		array[i]=new Vector<T, size>;
    		*array[i]=*ptr;
    		ptr++;
    	}
    }

    template<class T, int size, int dimension>
    ostream& operator<<(ostream& out, const VectorArray<T, size, dimension>& dummy)
    {
    	dummy.display();
    	return out;
    }

    template<class T, int size, int dimension>
    void VectorArray<T, size, dimension>::display() const
    {
    	for (int i=0; i<dimension; i++)
    	{
    		array[i]->display();
    	}
    }

    template<class T, int size, int dimension>
    void VectorArray<T, size, dimension>::display()
    {
    	for (int i=0; i<dimension; i++)
    	{
    		array[i]->display();
    	}
    }

    template<class T, int size>
    ostream& operator <<(ostream& out, const Vector<T, size>& vector)
    {
    	vector.display();
    	return out;
    }

    template<class T, int size>
    T Vector<T, size>::operator [](int index)
    {
    	if (index<size&&index>=0)
    	{
    		return array[index];
    	}
    	else
    	{
    		throw "index exceeds size";
    	}
    }

    template<class T, int size>
    Vector<T, size>::Vector<T, size>(const Vector<T, size>& other)
    {
    	for (int i=0; i<size; i++)
    	{
    		array[i]=other.array[i];
    	}
    }

    template<class T, int size>
    Vector<T, size>& Vector<T, size>::operator- (const Vector<T, size>& other)
    {
    	//I have to write like this, otherwise, I need to create a
    	//temp variable of "other" since my "+", "*" is changed
    	for (int i=0; i<size; i++)
    	{
    		array[i]-=other.array[i];
    	}
    	return *this;
    }

    //I changed my mind since this has too benefit: efficiency, and
    //easy in echelon operation
    template<class T, int size>
    Vector<T, size>& Vector<T, size>::operator*(T scalar)
    {
    	//Vector<T, size> result;
    	for (int i=0; i<size; i++)
    	{
    		array[i]=array[i]*scalar;
    	}
    	return *this;
    }

    template<class T, int size>
    Vector<T, size>& Vector<T, size>::operator+(const Vector<T, size>& other)
    {
    	//Vector<T, size> result;
    	for (int i=0; i<size; i++)
    	{
    		array[i]=array[i]+other.array[i];
    	}
    	return *this;
    }

    template<class T, int size>
    bool Vector<T, size>::operator ==(const Vector<T, size>& other)
    {
    	//here we don't even have to check the size of both vector
    	//because the operator overloading require same "size"
    	for (int i=0; i<size; i++)
    	{
    		if (array[i]!=other.array[i])
    		{
    			return false;
    		}
    	}
    	return true;
    }

    template<class T, int size>
    Vector<T, size>& Vector<T, size>::operator =(const Vector<T, size>& other)
    {
    	for (int i=0; i<size; i++)
    	{
    		array[i]=other.array[i];
    	}
    	return *this;
    }

    template<class T, int size>
    Vector<T, size>::Vector()
    {
    	for (int i=0; i<size; i++)
    	{
    		array[i]=0;
    	}
    }

    template<class T, int size>
    Vector<T, size>::Vector<T, size>(T elem, ...)
    {
    	T* ptr=&elem;
    	for (int i=0; i<size; i++)
    	{
    		array[i]=*ptr;
    		ptr++;
    	}
    }

    template<class T, int size>
    Vector<T, size>& Vector<T, size>::operator /(T scalar)
    {
    	if (scalar!=0)
    	{
    		for (int i=0; i<size; i++)
    		{
    			array[i]/=scalar;
    		}
    	}
    	return *this;
    }

    template<class T, int size>
    void Vector<T, size>::display()const
    {
    	cout.setf(ios_base::fixed||ios_base::left);
    	//cout.width(2);
    	//cout.precision(2);
    	for (int i=0; i<size; i++)
    	{
    		cout<<array[i]<<", ";
    	}
    	cout.setf(ios_base::fixed);
    	//cout.width(2);
    	//cout.precision(2);
    	cout<<endl;
    }

    template<class T, int size>
    void Vector<T, size>::display()
    {
    	//int previous=cout.precision(2);
    	for (int i=0; i<size; i++)
    	{
    		cout<<array[i]<<", ";
    	}
    	//cout.precision(previous);
    	cout<<endl;
    }

    template<class T, int size>
    void Vector<T, size>::shrink()
    {
    	T small=0, big=0;
    	for (int i=0; i<size; i++)
    	{
    		if (small==0)
    		{
    			small=array[i];
    		}
    		if (abs(array[i])>big)
    		{
    			big=abs(array[i]);
    		}
    		if (array[i]!=0&&abs(array[i])<abs(small))
    		{
    			small=array[i];
    		}
    	}
    	if (small!=0&&big>Limit)
    	{
    		this->operator/(small);
    	}
    }

    file name: main.cpp

    #include "vector.h"

    int main()
    {
    	Vector<int, 5> V(11, 23, 2, 14, 5);
    	Vector<int, 5> W(2, 5, 7, 11, 23), U(3,12, 2, 22, 19);
    	Vector<int, 5> X(6, 23, 22, 4, 9), Y(1,2,3,4,4), P(2,2,2,2,5);
    	V.display();

    	X.display();
    	W.display();
    	//VectorArray<double, 5, 4> vArray(U*4, V*6, X*9, W);
    	//vArray.display();
    	Space<int, 5, 5> S(X, W, U, V, Y);
    	S.display();
    	S.simplify();
    	S.display();
    	if (S.belong(V))
    	{
    		printf("ok\n");
    	}

    	return 0;
    }

    ¡¡

    ¡¡

    How to run?

    11, 23, 2, 14, 5,
    6, 23, 22, 4, 9,
    2, 5, 7, 11, 23,
    the original basis:
    6, 23, 22, 4, 9,
    2, 5, 7, 11, 23,
    3, 12, 2, 22, 19,
    11, 23, 2, 14, 5,
    1, 2, 3, 4, 4,
    the echelon basis:
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0,
    the original basis:
    6, 23, 22, 4, 9,
    2, 5, 7, 11, 23,
    3, 12, 2, 22, 19,
    11, 23, 2, 14, 5,
    1, 2, 3, 4, 4,
    the echelon basis:
    6, 23, 22, 4, 9,
    0, -16, -2, 58, 120,
    0, 0, 1, -2, -2,
    0, 0, 0, 3, 6,
    0, 0, 0, 0, 27,
    Press any key to continue

    ¡¡