-
January 4th, 2012, 12:32 PM
#1
template error...
Hello everyone!
I'm trying to compile an old library that could be useful for my graphics project.
The code has been written by third-party years ago, and uses templates. Unfortunately I have never worked with templates, I just know that there are ... and I get many errors at compile time.
I try to post the code clearly.
[code
Can anyone help me?
Thanks in advance!
-
January 4th, 2012, 12:36 PM
#2
Re: template error...
uops...
here is the code
Code:
// File knot_par.cpp
#include <iostream.h>
#include <stdlib.h>
#include "knot_par.h"
/* Constructor parameters:
* pt=partition type
* ct=more knots type
*/
knot_partition::knot_partition(int degree,int kn,int pt,int ct)
{
int i;
double h;
m=degree;
knot_number=kn;
if (knot_number<2*m) {
cerr << "\nNot enough knots: program aborted...\n";
exit(1);
}
k.change_dimension(kn);
if (ct==COINCIDENT) {
more_knots_type=COINCIDENT;
for (i=0; i<=m-1; i++)
k(i)=AA;
for (i=knot_number-1; i>=knot_number-m; i--)
k(i)=BB;
}
else {
/* Find this space with C++ code to support new disposition of knots */
}
if (pt==UNIFORM) {
partition_type=UNIFORM;
h=(BB-AA)/(knot_number-2*m+1);
for (i=m; i<knot_number-m; i++)
k(i)=((i-m+1)*h);
}
else {
/* Find this space with C++ code to support new partition types */
}
range_number=rn();
first_k=0;
}
knot_partition::knot_partition(int degree,vector<double>& data)
{
int l;
m=degree;
knot_number=data.get_dim();
k.change_dimension(knot_number);
k=data;
range_number=rn();
l=0;
while (k(l)!=0.0)
++l;
first_k=l;
}
knot_partition::~knot_partition()
{
}
/* Number of range nodes*/
/* WARNING: variable u is in [0,1] */
int knot_partition::rn()
{
int i;
int sum=0;
i=0;
while (k(i)!=AA)
++i;
while (k(i)!=BB) {
if (k(i)!=k(i+1))
++sum;
++i;
}
return sum;
}
int knot_partition::get_degree()
{
return m;
}
int knot_partition::get_knot_number()
{
return knot_number;
}
double knot_partition::get_knot_value(int knot_index)
{
return k(knot_index);
}
int knot_partition::get_knot_molt(double u)
{
int molt;
register int i,j;
molt=0;
for (i=0; i<knot_number && u!=k(i); i++)
;
j=i;
while (u==k(j++))
molt++;
return molt;
}
void knot_partition::range(double u,double *r)
{
int i,found;
i=found=0;
while (i<knot_number-1 && !found) {
if (u>=k(i) && u<k(i+1))
++found;
else
++i;
}
if (!found && u==k(knot_number-1)) { /* It controls the last node: a special situation */
i=knot_number-2;
while (k(knot_number-1)==k(i))
i--;
}
r[0]=k(i);
r[1]=k(i+1);
}
double knot_partition::BSpline(int n,double u)
{
if (u<k(n+m) && u>=k(n))
return Recursive_BSpline(n,m,u);
else if (u==BB && n+m==knot_number-1)
return Recursive_BSpline(n,m,u);
else
return 0.0;
}
double knot_partition::Recursive_BSpline(int n,int d,double u)
{
double divisor1,divisor2;
if (d==1) {
if (u>=k(n) && u<k(n+1))
return 1.0;
else if (n==knot_number-m-1 && u==BB)
return 1.0;
else
return 0.0;
}
else {
if (k(n)<k(n+d)) {
divisor1=k(n+d-1)-k(n);
divisor2=k(n+d)-k(n+1);
if (divisor1!=0.0 && divisor2!=0.0)
return ((u-k(n))/divisor1)*Recursive_BSpline(n,d-1,u)+
((k(n+d)-u)/divisor2)*Recursive_BSpline(n+1,d-1,u);
else if (divisor1!=0.0 && divisor2==0.0)
return ((u-k(n))/divisor1)*Recursive_BSpline(n,d-1,u);
else if (divisor1==0.0 && divisor2!=0.0)
return ((k(n+d)-u)/divisor2)*Recursive_BSpline(n+1,d-1,u);
else
return 0.0;
}
else
return 0.0;
}
}
double knot_partition::derived_BSpline(int n,int d,double u)
{
double d1,d2;
d1=k(n+d-1)-k(n);
d2=k(d+n)-k(n+1);
if (d1==0.0) {
if (d2==0.0)
return 0.0;
else
return -(d-1)*Recursive_BSpline(n+1,d-1,u)/d2;
}
else if (d2==0.0)
return (d-1)*Recursive_BSpline(n,d-1,u)/d1;
else
return (d-1)*(Recursive_BSpline(n,d-1,u)/d1-
Recursive_BSpline(n+1,d-1,u)/d2);
}
double knot_partition::derived2_BSpline(int n,int d,double u)
{
double d1,d2;
d1=k(n+d-1)-k(n);
d2=k(d+n)-k(n+1);
if (d1==0.0) {
if (d2==0.0)
return 0.0;
else
return -(d-1)*derived_BSpline(n+1,d-1,u)/d2;
}
else if (d2==0.0)
return (m-1)*derived_BSpline(n,d-1,u)/d1;
else
return (m-1)*(derived_BSpline(n,d-1,u)/d1-
derived_BSpline(n+1,d-1,u)/d2);
}
Code:
// File knot_par.h
#ifndef NOINCLUDE
#include "spltype.h"
#include "err.h"
#include "tem/pair.tem"
#include "tem/list.tem"
#include "tem/matvec.tem"
#endif
class knot_partition {
protected:
int m; /* Spline degree */
int knot_number;
int partition_type,more_knots_type;
int range_number;
int first_k; /* First k zero value */
vector<double> k; /* List of knots */
public:
knot_partition(int,int,int,int);
knot_partition(int,vector<double>&);
~knot_partition();
int rn();
void range(double,double *); /* Restituisce l'intervallo nodale di appartenenza */
/* void knot_insertion(double);
void knot_removal(double); */
int get_degree();
int get_knot_number();
double get_knot_value(int);
int get_knot_molt(double); /* It return the knot molteplicity */
double BSpline(int,double);
double derived_BSpline(int,int,double);
double derived2_BSpline(int,int,double);
private:
double Recursive_BSpline(int,int,double);
};
#define AA (double) 0.0
#define BB (double) 1.0
Code:
//pair.tem
// Template per gestire le molteplicita' dei nodi o dei c.p.
#include <ostream>
using namespace std;
template <class T,class D> class pair {
T fir;
D sec;
public:
pair();
pair(T,D);
~pair();
T get_first_data();
D get_second_data();
void set_first_data(T);
void set_second_data(D);
friend ostream& operator<< <>(ostream&,pair<T,D>);
friend ostream& operator<< <>(ostream&,pair<T,D>*);
friend istream& operator>> <>(istream&,pair<T,D>&);
pair<T,D>& operator=(pair<T,D>&);
//pair<T,D>& operator=(pair<T,D>);
bool operator==(pair<T,D>&);
bool operator!=(const pair<T,D>&);
//bool operator==(pair<T,D>);
//bool operator!=(pair<T,D>);
bool operator>(const pair<T,D>&); // Gli operatori di confronto
bool operator<(const pair<T,D>&); // sono stati inseriti per
bool operator>=(const pair<T,D>&); // ragioni di esportabilita'
bool operator<=(const pair<T,D>&); // del codice
pair<T,D>& operator=(const int);
};
// Template implementation
template <class T,class D> pair<T,D>::pair()
{
fir=0;
sec=0;
}
template <class T,class D> pair<T,D>::pair(T d,D oc)
{
fir=d;
sec=oc;
}
template <class T,class D> pair<T,D>::~pair()
{
}
template <class T,class D> T pair<T,D>::get_first_data()
{
return fir;
}
template <class T,class D> D pair<T,D>::get_second_data()
{
return sec;
}
template <class T,class D> void pair<T,D>::set_first_data(T oc)
{
fir=oc;
}
template <class T,class D> void pair<T,D>::set_second_data(D d)
{
sec=d;
}
template <class T,class D> ostream& operator<<(ostream &stream,pair<T,D> p)
{
stream << p.get_first_data() << "\t" << p.get_second_data() <<" ";
return stream;
}
template <class T,class D> ostream& operator<<(ostream &stream,pair<T,D> *p)
{
stream << p.get_first_data() << "\t" << p.get_second_data() << " ";
return stream;
}
template <class T,class D> istream& operator>>(istream &stream,pair<T,D> &p)
{
stream >> p.fir;
stream >> p.las;
return stream;
}
template <class T,class D> pair<T,D>& pair<T,D>::operator=(const int d)
{
fir=0;
sec=0;
return *this;
}
template <class T,class D> bool pair<T,D>::operator==(pair<T,D>& p)
{
if (fir==p.get_first_data() && sec==p.get_second_data())
return true;
else
return false;
}
template <class T,class D> bool pair<T,D>::operator!=(const pair<T,D>& p)
{
return !(this==p);
}
/*template <class T,class D> bool pair<T,D>::operator==(pair<T,D> p)
{
if (fir==p.get_first_data() && sec==p.get_second_data())
return true;
else
return false;
}
template <class T,class D> bool pair<T,D>::operator!=(pair<T,D> p)
{
return !(this==p);
}*/
template <class T,class D> pair<T,D>& pair<T,D>::operator=(pair<T,D>& p)
{
fir=p.get_first_data();
sec=p.get_second_data();
return *this;
}
/*template <class T,class D> pair<T,D>& pair<T,D>::operator=(pair<T,D> p)
{
fir=p.get_first_data();
sec=p.get_second_data();
return *this;
}*/
template <class T,class D> bool pair<T,D>::operator<(const pair<T,D>& p)
{
return true;
}
template <class T,class D> bool pair<T,D>::operator>(const pair<T,D>& p)
{
return true;
}
template <class T,class D> bool pair<T,D>::operator<=(const pair<T,D>& p)
{
return true;
}
template <class T,class D> bool pair<T,D>::operator>=(const pair<T,D>& p)
{
return true;
}
-
January 4th, 2012, 12:41 PM
#3
Re: template error...
and these are the errors
Someone help me? thanks!
g++ -c -Wno-deprecated knot_par.cpp
In file included from knot_par.h:6,
from knot_par.cpp:6:
tem/pair.tem:37: error: expected constructor, destructor, or type conversion before ‘<’ token
tem/pair.tem:43: error: expected constructor, destructor, or type conversion before ‘<’ token
tem/pair.tem:49: error: expected constructor, destructor, or type conversion before ‘<’ token
tem/pair.tem:53: error: expected initializer before ‘<’ token
tem/pair.tem:58: error: expected initializer before ‘<’ token
tem/pair.tem:64: error: expected initializer before ‘<’ token
tem/pair.tem:69: error: expected initializer before ‘<’ token
tem/pair.tem:74: error: reference to ‘pair’ is ambiguous
tem/pair.tem:7: error: candidates are: template<class T, class D> class pair
/usr/include/c++/4.4/bits/stl_pair.h:67: error: template<class _T1, class _T2> struct std::pair
tem/pair.tem:74: error: ‘pair’ has not been declared
tem/pair.tem:74: error: expected ‘,’ or ‘...’ before ‘<’ token
tem/pair.tem: In function ‘std::ostream& operator<<(std::ostream&, int)’:
tem/pair.tem:76: error: ‘p’ was not declared in this scope
tem/pair.tem: At global scope:
tem/pair.tem:80: error: reference to ‘pair’ is ambiguous
tem/pair.tem:7: error: candidates are: template<class T, class D> class pair
/usr/include/c++/4.4/bits/stl_pair.h:67: error: template<class _T1, class _T2> struct std::pair
tem/pair.tem:80: error: ‘pair’ has not been declared
tem/pair.tem:80: error: expected ‘,’ or ‘...’ before ‘<’ token
tem/pair.tem:80: error: redefinition of ‘template<class T, class D> std::ostream& operator<<(std::ostream&, int)’
tem/pair.tem:74: error: ‘template<class T, class D> std::ostream& operator<<(std::ostream&, int)’ previously declared here
tem/pair.tem: In function ‘std::ostream& operator<<(std::ostream&, int)’:
tem/pair.tem:82: error: ‘p’ was not declared in this scope
tem/pair.tem: At global scope:
tem/pair.tem:86: error: reference to ‘pair’ is ambiguous
tem/pair.tem:7: error: candidates are: template<class T, class D> class pair
/usr/include/c++/4.4/bits/stl_pair.h:67: error: template<class _T1, class _T2> struct std::pair
tem/pair.tem:86: error: ‘pair’ has not been declared
tem/pair.tem:86: error: expected ‘,’ or ‘...’ before ‘<’ token
tem/pair.tem: In function ‘std::istream& operator>>(std::istream&, int)’:
tem/pair.tem:88: error: ‘p’ was not declared in this scope
tem/pair.tem: At global scope:
tem/pair.tem:93: error: expected constructor, destructor, or type conversion before ‘<’ token
tem/pair.tem:100: error: expected initializer before ‘<’ token
tem/pair.tem:108: error: expected initializer before ‘<’ token
tem/pair.tem:126: error: expected constructor, destructor, or type conversion before ‘<’ token
tem/pair.tem:140: error: expected initializer before ‘<’ token
tem/pair.tem:145: error: expected initializer before ‘<’ token
tem/pair.tem:150: error: expected initializer before ‘<’ token
tem/pair.tem:155: error: expected initializer before ‘<’ token
-
January 4th, 2012, 01:17 PM
#4
Re: template error...
Originally Posted by mnty7
uops...
here is the code
Code:
template <class T,class D> class pair {
T fir;
D sec;
There is already a std::pair class in standard C++.
1) You are reinventing the wheel -- use the std::pair class.
2) Don't use names of types that already exist, such as "pair".
Regards,
Paul McKenzie
-
January 4th, 2012, 01:20 PM
#5
Re: template error...
Also, the std::pair is declared in the <map> header file.
My advice is to remove that old "pair" class altogether and use std::pair. Then fix the compiler errors when they occur, which shouldn't be difficult. The code will be smaller, shorter, and any competent C++ programmer will understand the code, instead of having to learn what this old, home-made "pair" class does.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; January 4th, 2012 at 01:24 PM.
-
January 4th, 2012, 01:30 PM
#6
Re: template error...
Also:
Code:
#include <iostream.h>
There is no such header file is <iostream.h>. The proper header is <iostream>, not <iostream.h>
Some advice: If you want to take old C++ code and use newer compilers on that code, be prepared to make wholesale changes. Things such as using the proper header files, using the standard classes instead of home-made ones, etc. requires that you know what you're doing without needing help.
Also, a lot of template code that compiled years ago on non-standard C++ compilers will no longer compile on standard compilers without having to make changes.
Regards,
Paul McKenzie
-
January 4th, 2012, 01:33 PM
#7
Re: template error...
Originally Posted by Paul McKenzie
Also, the std: air is declared in the <map> header file.
<utility>, actually, although that's always included by <map>.
-
January 4th, 2012, 04:59 PM
#8
Re: template error...
Originally Posted by Lindley
<utility>, actually, although that's always included by <map>.
Technically, you don't know if <map> includes the actual entire <utility> header, or just other sub headers, the strict necessary needed to find "std::map".
----
I'd add even more than that, you don't know if <map> even declares std::pair. Maybe it just forward declares it: even if it uses pair by value, since it's a template, that's good enough for a simple compilation, but if you want to use the actual methods that use pair (like insert) then you have to insert <utility> yourself.
The only thing I'm unsure of: Does the standard garantee that inlcuding a header is sufficient to compile everything in that header?
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
January 5th, 2012, 04:35 AM
#9
Re: template error...
Originally Posted by mnty7
Hello everyone!
I'm trying to compile an old library that could be useful for my graphics project.
I'd suggest to completely rewrite the code if you do want to use it. There are many many things wrong in what you posted:
- no include guards in header files
- "using namespace" in a header file
- including non-standard headers
- no const-correctness
- there's no way to tell from the header file what functions do, as they don't even have named arguments
- exit is called upon a normal error
- unneeded use of macros
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
-
January 5th, 2012, 05:38 PM
#10
Re: template error...
Thanks to everyone for the anwers!
I removed the "pair" template and adjusted the code to use std:air...it seems ok now.
But now i have to use the matrix template, but i have many many errors...
I totally agree with D_Drmmr, the best way would be rewrite the code...but I do not have the time or knowledge to rewrite a matrix class template...
It's possibile to correct this one?
Code:
// MatVec.tem
#include <math.h>
#include <iostream>
#include <vector>
template <class DataV> void swap(DataV& one,DataV& two)
{
DataV three;
three=one;
one=two;
two=three;
}
#define NODIMCHECK
template <class DataV> class matrix;
template <class DataV> class matrix {
private:
int rows,columns;
DataV *p;
public:
matrix();
matrix(int,int);
matrix(const matrix<DataV>&);
~matrix();
int get_rows() const;
int get_columns() const;
void change_dimension(int,int);
void zero_matrix();
void make_id_matrix();
void make_zero_row(int);
void exchange_rows(int,int);
void exchange_columns(int,int);
void ins_head_column(const vector<DataV>&);
void ins_tail_column(const vector<DataV>&);
DataV& operator()(int,int);
DataV elem(int,int) const;
matrix<DataV>& operator=(const matrix<DataV>&);
bool operator==(const matrix<DataV>&);
bool operator!=(const matrix<DataV>&);
bool is_zero_matrix();
bool is_zero_row(int);
bool is_zero_columns(int);
// Serve per costruire una matrice di matrici e/o vettori
matrix<DataV>& operator=(const int);
matrix<DataV> operator+(const matrix<DataV>&);
matrix<DataV> operator-(const matrix<DataV>&);
matrix<DataV> operator*(const DataV);
matrix<DataV> operator*(const matrix<DataV>&);
vector<DataV> operator*(const vector<DataV>&);
double inf_norm();
friend vector<DataV> (::operator* <>) (vector<DataV>&,matrix<DataV>&);
// friend matrix<DataV> operator* <>(const DataV,matrix<DataV>&);
friend matrix<DataV> operator* <>(const DataV,matrix<DataV>);
friend matrix<DataV> decomp <>(matrix<DataV>,vector<int>&);
friend void LU <>(matrix<DataV>,vector<DataV>&,matrix<DataV>&,matrix<DataV>&,dllist<pair<int,int> >&);
friend matrix<DataV> transpose <>(const matrix<DataV>&);
friend matrix<DataV> inverse <>(const matrix<DataV>&);
friend vector<DataV> solve_linear_system <>(matrix<DataV>,vector<DataV>&);
friend vector<DataV> xc_solve <>(matrix<DataV>,vector<DataV>,vector<int>);
friend void coniugate_gradient <>(matrix<DataV>,vector<DataV>,vector<DataV>&,int,double);
friend ostream& operator<< <>(ostream&,const matrix<DataV>&);
friend void asub <>(DataV *,DataV *,DataV *,int);
friend void atsub <>(DataV *,DataV *,DataV *,int);
private:
friend vector<DataV> simply_solve <>(matrix<DataV>,vector<DataV>);
//PATCH
friend void make_null_pointer <>(matrix<DataV>&);
};
// Template implementation
// Matrix templates
template <class DataV> matrix<DataV>::matrix()
{
p=NULL;
rows=columns=0;
}
template <class DataV> matrix<DataV>::matrix(int r,int c)
{
if (r>0 && c>0) {
if ((p=new DataV[r*c])==NULL) {
error_code(OUT_OF_MEMORY);
}
rows=r;
columns=c;
zero_matrix();
}
else {
rows=columns=0;
p=NULL;
}
}
template <class DataV> matrix<DataV>::matrix(const matrix<DataV>& a)
{
if ((p=new DataV [a.rows*a.columns])==NULL) {
error_code(OUT_OF_MEMORY);
}
rows=a.get_rows();
columns=a.get_columns();
for (register int i=0; i<rows; i++)
for (register int j=0; j<columns; j++)
p[i*columns+j]=a.elem(i,j);
}
template <class DataV> matrix<DataV>::~matrix()
{
delete [] p;
}
template <class DataV> int matrix<DataV>::get_rows() const
{
return rows;
}
template <class DataV> int matrix<DataV>::get_columns() const
{
return columns;
}
template <class DataV> DataV matrix<DataV>::elem(int r,int c) const
{
return p[r*columns+c];
}
template <class DataV> void matrix<DataV>::change_dimension(int r,int c)
{
if (p!=NULL)
delete [] p;
if (r==0 || c==0)
p=NULL;
else
if ((p=new DataV [r*c])==NULL)
error_code(OUT_OF_MEMORY);
rows=r;
columns=c;
zero_matrix();
}
template <class DataV> void matrix<DataV>::zero_matrix()
{
register int i,j;
for (i=0; i<rows; i++)
for (j=0; j<columns; j++)
p[i*columns+j]=0;
}
template <class DataV> void matrix<DataV>::make_zero_row(int r)
{
register int j;
// if (r<0 || r>=rows);
// error_code(OUT_OF_BOUNDARY);
for (j=0; j<columns; j++)
p[r*columns+j]=0;
}
template <class DataV> void matrix<DataV>::make_id_matrix()
{
if (rows!=columns) {
error_code(NOT_SQUARE_MATRIX);
}
zero_matrix();
for (register int i=0; i<rows; i++)
p[i*columns+i]=1;
}
template <class DataV> void matrix<DataV>::exchange_rows(int r1,int r2)
{
vector<DataV> dummy(columns);
register int j;
for (j=0; j<columns; j++)
dummy(j)=p[r1*columns+j];
for (j=0; j<columns; j++)
p[r1*columns+j]=p[r2*columns+j];
for (j=0; j<columns; j++)
p[r2*columns+j]=dummy(j);
}
template <class DataV> void matrix<DataV>::exchange_columns(int c1,int c2)
{
vector<DataV> dummy(rows);
register int i;
for (i=0; i<rows; i++)
dummy(i)=p[i*columns+c1];
for (i=0; i<rows; i++)
p[i*columns+c1]=p[i*columns+c2];
for (i=0; i<rows; i++)
p[i*columns+c2]=dummy(i);
}
template <class DataV> void matrix<DataV>::ins_head_column(const vector<DataV> &a) // N.B: E' da controllare !
{
register int i,j;
DataV *np;
if ((np=new DataV[rows*(columns+1)])==NULL) {
error_code(OUT_OF_MEMORY);
}
for (i=0; i<rows; i++)
np[i*(columns+1)]=a.elem(i);
for (i=0; i<rows; i++)
for (j=0; j<columns; j++)
np[i*(columns+1)+(j+1)]=p[i*columns+j];
delete [] p;
p=np;
columns++;
}
template <class DataV> void matrix<DataV>::ins_tail_column(const vector<DataV>& a)
{
register int i,j;
DataV *np;
if ((np=new DataV[rows*(columns+1)])==NULL) {
error_code(OUT_OF_MEMORY);
}
for (i=0; i<rows; i++)
for (j=0; j<columns; j++)
np[i*(columns+1)+j]=p[i*columns+j];
for (i=0; i<rows; i++)
np[i*(columns+1)+columns]=a.elem(i);
delete [] p;
p=np;
columns++;
}
template <class DataV> DataV& matrix<DataV>::operator()(int r,int c)
{
if (r<0 || r>=rows || c<0 || c>=columns)
error_code(OUT_OF_BOUNDARY);
return p[r*columns+c];
}
template <class DataV> matrix<DataV>& matrix<DataV>::operator=(const matrix<DataV>& a)
{
register int i,j;
if (rows!=a.get_rows() || columns!=a.get_columns()) {
error_code(BAD_MATRIX_DIMENSIONS);
}
for (i=0; i<rows; i++)
for (j=0; j<columns; j++)
p[i*columns+j]=a.elem(i,j);
return *this;
}
template <class DataV> bool matrix<DataV>::operator==(const matrix<DataV>& a)
{
register int i,j;
if (rows!=a.get_rows() || columns!=a.get_columns())
return false;
else {
for (i=0; i<rows; i++)
for (j=0; j<columns; j++)
if (p[i*columns+j]!=a.elem(i,j))
return false;
}
return true;
}
template <class DataV> bool matrix<DataV>::operator!=(const matrix<DataV>& a)
{
return !(this==a);
}
template <class DataV> bool matrix<DataV>::is_zero_matrix()
{
register int i,j;
for (i=0; i<rows; i++)
for (j=0; j<columns; j++)
if (p[i*columns+j]!=0)
return false;
return true;
}
template <class DataV> bool matrix<DataV>::is_zero_row(int r)
{
register int j;
if (r<0 || r>=rows)
error_code(OUT_OF_BOUNDARY);
for (j=0; j<columns; j++)
if (p[r*columns+j]!=0)
return false;
return true;
}
template <class DataV> bool matrix<DataV>::is_zero_columns(int c)
{
register int i;
if (c<0 || c>=rcolumns)
error_code(OUT_OF_BOUNDARY);
for (i=0; i<columns; i++)
if (p[i*columns+c]!=0)
return false;
return true;
}
template <class DataV> matrix<DataV>& matrix<DataV>::operator=(const int d)
{
change_dimension(d,d);
return *this;
}
template <class DataV> matrix<DataV> matrix<DataV>::operator+(const matrix<DataV>& a)
{
register int i,j;
if (rows!=a.get_rows() || columns!=a.get_columns()) {
error_code(BAD_MATRIX_DIMENSIONS);
}
matrix<DataV> result(rows,columns);
for (i=0; i<rows; i++)
for (j=0; j<columns; j++)
result(i,j)=p[i*columns+j]+a.elem(i,j);
return result;
}
template <class DataV> matrix<DataV> matrix<DataV>::operator-(const matrix<DataV>& a)
{
register int i,j;
if (rows!=a.get_rows() || columns!=a.get_columns()) {
error_code(BAD_MATRIX_DIMENSIONS);
}
matrix<DataV> result(rows,columns);
for (i=0; i<rows; i++)
for (j=0; j<columns; j++)
result(i,j)=p[i*columns+j]-a.elem(i,j);
return result;
}
template <class DataV> matrix<DataV> matrix<DataV>::operator*(const DataV d)
{
register int i,j;
matrix<DataV> result(rows,columns);
for (i=0; i<rows; i++)
for (j=0; j<columns; j++)
result(i,j)=p[i*columns+j]*d;
return result;
}
/*template <class DataV> matrix<DataV> operator*(const DataV d,matrix<DataV>& a)
{
register int i,j;
matrix<DataV> result(a.get_rows(),a.get_columns());
for (i=0; i<a.get_rows(); i++)
for (j=0; j<a.get_columns(); j++)
result(i,j)=a(i,j)*d;
return result;
}*/
template <class DataV> matrix<DataV> operator*(const DataV d,matrix<DataV> a)
{
register int i,j;
matrix<DataV> result(a.get_rows(),a.get_columns());
for (i=0; i<a.get_rows(); i++)
for (j=0; j<a.get_columns(); j++)
result(i,j)=a(i,j)*d;
return result;
}
template <class DataV> matrix<DataV> matrix<DataV>::operator*(const matrix<DataV>& a)
{
register int i,k,l;
DataV tmp;
if (columns!=a.get_rows()) {
error_code(BAD_MATRIX_DIMENSIONS);
}
matrix<DataV> result(rows,a.get_columns());
for (i=0; i<rows; i++) {
for (k=0; k<a.get_columns(); k++) {
tmp=0;
for (l=0; l<a.get_rows(); l++) {
tmp+=p[i*columns+l]*a.elem(l,k);
}
result(i,k)=tmp;
}
}
return result;
}
template <class DataV> vector<DataV> matrix<DataV>::operator*(const vector<DataV>& a)
{
register int i,j;
DataV temp;
if (columns != a.get_dim()) {
error_code(BAD_VECTOR_DIMENSIONS);
}
vector<DataV> result(rows);
for (i=0; i<rows; i++) {
temp=0.0;
for (j=0; j<columns; j++)
temp=temp+p[i*columns+j]*a.elem(j);
result(i)=temp;
}
return result;
}
template <class DataV> double matrix<DataV>::inf_norm()
{
register int i,j;
double sum,tmpsum;
sum=0.0;
for (i=0; i<rows; i++) {
tmpsum=0.0;
for (j=0; j<columns; j++)
tmpsum+=fabs(elem(i,j));
if (tmpsum>sum)
sum=tmpsum;
}
return sum;
}
template <class DataV> matrix<DataV> transpose(const matrix<DataV>& a)
{
register int i,j;
matrix<DataV> result(a.get_columns(),a.get_rows());
for (i=0; i<a.get_rows(); i++)
for (j=0; j<a.get_columns(); j++)
result(j,i)=a.elem(i,j);
return result;
}
template <class DataV> matrix<DataV> inverse(const matrix<DataV>& a)
{
matrix<DataV> tmpm,result,L,U;
vector<DataV> tmpv,r;
dllist<pair<int,int> > ll;
dblinkob<pair<int,int> > *objp;
pair<int,int> obj;
int i,k,j;
DataV parsum;
vector<int> p;
result.change_dimension(a.get_rows(),a.get_columns());
r.change_dimension(a.get_rows());
tmpv.change_dimension(a.get_rows());
tmpm.change_dimension(a.get_rows(),a.get_columns());
p.change_dimension(a.get_rows());
tmpm=decomp(a,p);
for (i=0; i<a.get_columns(); i++) {
r.make_zero_vector();
r(i)=1;
tmpv=xc_solve(tmpm,r,p);
for (j=0; j<a.get_rows(); j++)
result(j,i)=tmpv(j);
}
/*
for (i=0; i<a.get_rows(); i++) {
tmpm.change_dimension(a.get_rows(),a.get_columns());
tmpm=a;
tmpv.make_zero_vector();
tmpv(i)=1;
tmpm.ins_tail_column(tmpv);
LU(tmpm,L,U,ll);
r(a.get_rows()-1)=U(U.get_rows()-1,U.get_columns()-1)/U(U.get_rows()-1,U.get_columns()-2);
for (k=a.get_rows()-2; k>=0; k--) {
parsum=0;
for (j=k+1; j<a.get_rows(); j++) {
parsum+=U(k,j)*r(j);
}
r(k)=(1/U(k,k))*(U(k,U.get_columns()-1)-parsum);
}
objp=ll.get_start();
while (objp!=NULL) {
objp->getinfo(obj);
r.exchange_elem(obj.get_first_data(),obj.get_second_data());
objp=objp->getnext();
}
for (k=0; k<a.get_rows(); k++)
result(k,i)=r(k);
}
*/
return result;
}
template <class DataV> vector<DataV> operator*(vector<DataV>& a,matrix<DataV>& m)
{
register int i,j;
DataV ttp;
if (a.get_dim()!=m.get_rows()) {
error_code(BAD_MATRIX_DIMENSIONS);
}
vector<DataV> temp(a.get_dim());
for (i=0; i<m.columns; i++) {
ttp=0.0;
for (j=0; j<a.get_dim(); j++)
ttp=ttp+a(j)*m(j,i);
temp(i)=ttp;
}
return temp;
}
template <class DataV> matrix<DataV> decomp(matrix<DataV> a,vector<int>& p)
{
int i,j,kk,mm,n;
bool sing;
sing=false;
n=a.get_rows();
p(n-1)=1;
kk=0;
while (!sing && kk<n-1) {
mm=kk;
for(i=kk+1; i<n; i++)
if(fabs(a(i,kk))>fabs(a(mm,kk)))
mm=i;
p(kk)=mm;
if(mm!=kk)
p(n-1)=-p(n-1);
swap(a(mm,kk),a(kk,kk));
if(a(kk,kk)!=0) {
for(i=kk+1; i<n; i++)
a(i,kk)=-a(i,kk)/a(kk,kk);
for(j=kk+1; j<n; j++) {
swap(a(mm,j),a(kk,j));
if(a(kk,j)!=0)
for(i=kk+1; i<n; i++)
a(i,j)=a(i,j)+a(i,kk)*a(kk,j);
}
}
else
sing=true;
kk++;
}
if(a(n-1,n-1)==0)
sing=true;
if (sing)
error_code(SINGULAR_MATRIX);
return a;
}
template <class DataV> void LU(matrix<DataV> a,vector<DataV>& b,matrix<DataV>& L,matrix<DataV>& U,
dllist<pair<int,int> >& el)
{
register int i,j,k;
bool found;
DataV m;
pair<int,int> trace;
L.change_dimension(a.get_rows(),a.get_rows());
U.change_dimension(a.get_rows(),a.get_columns());
for (i=0; i<a.get_rows(); i++) {
if (i==a.get_rows()-1 && a(i,i)==0) {
k=i;
while (k<a.get_columns() && a(i,k)==0)
++k;
if (k==a.get_columns())
--k;
if (a(i,k)==0)
error_code(NO_PIVOT);
trace.set_first_data(i);
trace.set_second_data(k);
el.store_tail(trace);
a.exchange_columns(i,k);
}
else {
for (j=i+1; j<a.get_rows(); j++) {
if (a(i,i)==0) {
found=false;
k=i+1;
while (k<a.get_rows() && !found) {
if (a(k,i)!=0)
found=true;
else
++k;
}
if (!found) {
k=i+1;
while (k<a.get_columns() && !found) {
if (a(i,k)!=0)
found=true;
else
++k;
}
if (!found)
error_code(NO_PIVOT);
trace.set_first_data(i);
trace.set_second_data(k);
el.store_tail(trace);
a.exchange_columns(i,k);
}
else {
a.exchange_rows(i,k);
b.exchange_elem(i,k);
}
}
m=a(j,i)/a(i,i);
L(j,i)=m;
for (k=0; k<a.get_columns(); k++)
a(j,k)=a(j,k)+a(i,k)*(-m);
}
}
}
U=a;
for (i=0; i<L.get_rows(); i++)
L(i,i)=1;
}
template <class DataV> vector<DataV> xc_solve(matrix<DataV> a,vector<DataV>
b ,vector<int> p)
{
int i,kk,mm,n;
vector<DataV> x;
x.change_dimension(b.get_dim());
x=b;
n=a.get_rows()-1;
for(kk=0; kk<n; kk++) {
mm = p(kk);
swap(x(mm), x(kk));
for(i=kk+1; i<=n; i++)
x(i) = x(i) + a(i,kk) * x(kk);
}
for(kk=n; kk>=1; kk--) {
x(kk) = x(kk) / a(kk,kk);
for(i=0; i<=kk-1; i++)
x(i) = x(i) - a(i,kk) * x(kk);
}
x(0) = x(0)/a(0,0);
return x;
}
template <class DataV> vector<DataV> solve_linear_system(matrix<DataV> a,vector<DataV>& b)
{
register int i,j;
double diff;
dllist<pair<int,int> > ll;
dblinkob<pair<int,int> > *objp;
pair<int,int> obj;
matrix<DataV> L,U,LI;
vector<DataV> x;
if (a.get_rows()!=a.get_columns() || a.get_rows()!=b.get_dim()) {
cout << "\n\nOnly for square linear systems\n";
exit(9);
}
x.change_dimension(b.get_dim());
LU(a,L,U,ll);
LI.change_dimension(L.get_rows(),L.get_columns());
LI=inverse(L);
x=simply_solve(U,LI*b);
objp=ll.get_start();
while (objp!=NULL) {
objp->getinfo(obj);
x.exchange_elem(obj.get_first_data(),obj.get_second_data());
objp=objp->getnext();
}
return x;
}
template <class DataV> ostream& operator<<(ostream& left,const matrix<DataV>& m)
{
register int l,b;
left << "\n";
for (l=0; l<m.get_rows(); l++) {
left << "Row n." << l << ":\n";
for (b=0; b<m.get_columns(); b++)
left << m.elem(l,b) << "\t";
left << "\n";
}
return left;
}
template <class DataV> void coniugate_gradient(matrix<DataV> q,vector<DataV> cc,vector<DataV>& ll,int maxiter,double eps)
{
double eps2,aden,anum,bsq,dgg,gam,gg,rp,rsq;
DataV *xi,*xj;
DataV *g,*h;
int i,j,numiter;
int raggiunta_approssimazione;
DataV *a,*b,*xx;
int n;
a=q.p;
b=cc.v;
xx=ll.v;
n=cc.dim;
g=new DataV [n];
h=new DataV [n];
xi=new DataV [n];
xj=new DataV [n];
eps2=eps*eps;
raggiunta_approssimazione=0;
for (i=0; i<n; i++)
xx[i]=0.0;
asub(a,xx,xi,n);
rp=0.0; bsq=0.0;
for (j=0; j<n; j++) {
bsq=bsq+b[j]*b[j];
xi[j]=xi[j]-b[j];
rp=rp+xi[j]*xi[j];
}
atsub(a,xi,g,n);
for (j=0; j<n; j++) {
h[j]=-g[j];
g[j]=-g[j];
}
numiter=0;
do {
numiter=numiter+1;
asub(a,h,xi,n);
anum=0.0; aden=0.0;
for (j=0; j<n; j++) {
anum=anum+g[j]*h[j];
aden=aden+xi[j]*xi[j];
}
if (aden == 0.0) {
cerr << "\nVery singular matrix...\n";
exit(10);
}
else
anum=anum/aden;
for (j=0; j<n; j++) {
xi[j]=xx[j];
xx[j]=xx[j]+anum*h[j];
}
asub(a,xx,xj,n);
rsq=0.0;
for (j=0; j<n; j++) {
xj[j]=xj[j]-b[j];
rsq=rsq+xj[j]*xj[j];
}
if (rsq<=bsq*eps2)
raggiunta_approssimazione=1;
rp=rsq;
atsub(a,xj,xi,n);
gg=0.0; dgg=0.0;
for (j=0; j<n; j++ ){
gg=gg+g[j]*g[j];
dgg=dgg+(xi[j]+g[j])*xi[j];
}
if (gg == 0.0) {
cerr << "\nError !\n";
exit(11);
}
else
gam=dgg/gg;
for (j=0; j<n; j++) {
g[j]=-xi[j];
h[j]=g[j]+gam*h[j];
}
} while (!(numiter>=maxiter || raggiunta_approssimazione));
delete [] xj;
delete [] xi;
delete [] h;
delete [] g;
}
template <class DataV> void asub(DataV *a,DataV *x,DataV *v,int n)
{
register int i,j;
for (i=0; i<n; i++) {
v[i]=0.0;
for (j=0; j<n; j++)
v[i]=v[i]+a[i*n+j]*x[j];
}
}
template <class DataV> void atsub(DataV *a,DataV *x,DataV *v,int n)
{
register int i,j;
for (i=0; i<n; i++) {
v[i]=0.0;
for (j=0; j<n; j++)
v[i]=v[i]+a[j*n+i]*x[j];
}
}
template <class DataV> vector<DataV> simply_solve(matrix<DataV> a,vector<DataV> b)
{
register int i,j;
DataV parsum;
vector<DataV> result(b.get_dim());
result(b.get_dim()-1)=b(b.get_dim()-1)/a(a.get_rows()-1,a.get_columns()-1);
for (i=b.get_dim()-2; i>=0; i--) {
parsum=0;
for (j=i+1; j<b.get_dim(); j++) {
parsum+=a(i,j)*result(j);
}
result(i)=(1/a(i,i))*(b(i)-parsum);
}
return result;
}
//PATCH
template <class DataV> void make_null_pointer(matrix<DataV>& a)
{
a.p=NULL;
a.rows=a.columns=0;
}
-
January 5th, 2012, 05:40 PM
#11
Re: template error...
i obtain this...
Code:
h/../t/matvec.tem:57: error: expected ‘)’ before ‘<’ token
h/../t/matvec.tem:59: error: declaration of ‘operator*’ as non-function
h/../t/matvec.tem:59: error: expected ‘;’ before ‘<’ token
h/../t/matvec.tem:60: error: ‘decomp’ is neither function nor member function; cannot be declared friend
h/../t/matvec.tem:60: error: expected ‘;’ before ‘<’ token
h/../t/matvec.tem:61: error: variable or field ‘LU’ declared void
h/../t/matvec.tem:61: error: expected ‘;’ before ‘<’ token
h/../t/matvec.tem:62: error: ‘transpose’ is neither function nor member function; cannot be declared friend
h/../t/matvec.tem:62: error: expected ‘;’ before ‘<’ token
h/../t/matvec.tem:63: error: ‘inverse’ is neither function nor member function; cannot be declared friend
h/../t/matvec.tem:63: error: expected ‘;’ before ‘<’ token
h/../t/matvec.tem:64: error: ‘solve_linear_system’ is neither function nor member function; cannot be declared friend
h/../t/matvec.tem:64: error: expected ‘;’ before ‘<’ token
h/../t/matvec.tem:65: error: ‘xc_solve’ is neither function nor member function; cannot be declared friend
h/../t/matvec.tem:65: error: expected ‘;’ before ‘<’ token
h/../t/matvec.tem:66: error: variable or field ‘coniugate_gradient’ declared void
h/../t/matvec.tem:66: error: expected ‘;’ before ‘<’ token
h/../t/matvec.tem:68: error: variable or field ‘asub’ declared void
h/../t/matvec.tem:68: error: expected ‘;’ before ‘<’ token
h/../t/matvec.tem:69: error: variable or field ‘atsub’ declared void
h/../t/matvec.tem:69: error: expected ‘;’ before ‘<’ token
h/../t/matvec.tem:71: error: ‘simply_solve’ is neither function nor member function; cannot be declared friend
h/../t/matvec.tem:71: error: expected ‘;’ before ‘<’ token
h/../t/matvec.tem:73: error: variable or field ‘make_null_pointer’ declared void
h/../t/matvec.tem:73: error: expected ‘;’ before ‘<’ token
h/../t/matvec.tem: In member function ‘bool matrix<DataV>::is_zero_columns(int)’:
h/../t/matvec.tem:307: error: ‘rcolumns’ was not declared in this scope
h/../t/matvec.tem: In function ‘matrix<DataV> inverse(const matrix<DataV>&)’:
h/../t/matvec.tem:464: error: ‘class std::vector<int, std::allocator<int> >’ has no member named ‘change_dimension’
h/../t/matvec.tem: In function ‘matrix<DataV> decomp(matrix<DataV>, std::vector<int, std::allocator<int> >&)’:
h/../t/matvec.tem:528: error: no match for call to ‘(std::vector<int, std::allocator<int> >) (int&)’
h/../t/matvec.tem:535: error: no match for call to ‘(std::vector<int, std::allocator<int> >) (int&)’
h/../t/matvec.tem:537: error: no match for call to ‘(std::vector<int, std::allocator<int> >) (int&)’
h/../t/matvec.tem:537: error: no match for call to ‘(std::vector<int, std::allocator<int> >) (int&)’
h/../t/matvec.tem: In function ‘void LU(matrix<DataV>, std::vector<DataV, std::allocator<_CharT> >&, matrix<DataV>&, matrix<DataV>&, dllist<std::pair<int, int> >&)’:
h/../t/matvec.tem:579: error: ‘struct std::pair<int, int>’ has no member named ‘set_first_data’
h/../t/matvec.tem:580: error: ‘struct std::pair<int, int>’ has no member named ‘set_second_data’
In file included from h/../t/list.tem:2,
from h/nurbscur2d.h:5,
from nurbscur2d.cpp:5:
h/../t/dblinkob.tem: At global scope:
h/../t/dblinkob.tem: In instantiation of ‘dblinkob<std::pair<int, int> >’:
h/../t/list.tem:7: instantiated from ‘dllist<std::pair<int, int> >’
h/../t/matvec.tem:581: instantiated from here
h/../t/dblinkob.tem:19: error: template-id ‘operator<< <>’ for ‘std::ostream& operator<<(std::ostream&, dblinkob<std::pair<int, int> >)’ does not match any template declaration
h/../t/dblinkob.tem:20: error: template-id ‘operator<< <>’ for ‘std::ostream& operator<<(std::ostream&, dblinkob<std::pair<int, int> >*)’ does not match any template declaration
h/../t/dblinkob.tem:21: error: template-id ‘operator>><>’ for ‘std::istream& operator>>(std::istream&, dblinkob<std::pair<int, int> >&)’ does not match any template declaration
In file included from h/nurbscur2d.h:7,
from nurbscur2d.cpp:5:
h/../t/matvec.tem: In function ‘void LU(matrix<DataV>, std::vector<DataV, std::allocator<_CharT> >&, matrix<DataV>&, matrix<DataV>&, dllist<std::pair<int, int> >&)’:
h/../t/matvec.tem:605: error: ‘struct std::pair<int, int>’ has no member named ‘set_first_data’
h/../t/matvec.tem:606: error: ‘struct std::pair<int, int>’ has no member named ‘set_second_data’
h/../t/matvec.tem: In function ‘std::vector<DataV, std::allocator<_CharT> > xc_solve(matrix<DataV>, std::vector<DataV, std::allocator<_CharT> >, std::vector<int, std::allocator<int> >)’:
h/../t/matvec.tem:637: error: no match for call to ‘(std::vector<int, std::allocator<int> >) (int&)’
h/../t/matvec.tem: In function ‘std::vector<DataV, std::allocator<_CharT> > solve_linear_system(matrix<DataV>, std::vector<DataV, std::allocator<_CharT> >&)’:
h/../t/matvec.tem:674: error: ‘struct std::pair<int, int>’ has no member named ‘get_first_data’
h/../t/matvec.tem:674: error: ‘struct std::pair<int, int>’ has no member named ‘get_second_data’
Thank you in advance!
-
January 5th, 2012, 09:18 PM
#12
Re: template error...
Originally Posted by mnty7
Thanks to everyone for the anwers!
I removed the "pair" template and adjusted the code to use std: air...it seems ok now.
But now i have to use the matrix template, but i have many many errors...
I totally agree with D_Drmmr, the best way would be rewrite the code...but I do not have the time or knowledge to rewrite a matrix class template...
Get a C++ matrix library that is already written. Something such as Blitz++, or many of the others that already exist.
It's possibile to correct this one?
Anything is possible, but why try to fix a buggy piece of code when you have well-established C++ template-based matrix libraries. All you need to do is install them, read the instructions, and start right away writing programs.
So is your goal to do matrix-based arithmetic, or spend (more likely, waste) time trying to get this to work (let alone compile)? If it's the former, get a library.
Seriously, it makes absolutely no sense to try and fix or rewite buggy C++ code you're not prepared to handle or understand. You have matrix libraries that already do what you want that are template-based, well-written, and relatively easy to use. If you need to look at how these libraries work, you have the source code available. So you're killing two birds with one stone -- a stable library that works, plus you get the source code to look at if you're interested.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; January 5th, 2012 at 09:24 PM.
-
January 6th, 2012, 09:38 AM
#13
Re: template error...
I recommend Eigen for matrix work.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|