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.)
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?
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