besion d'aide - C++ - Programmation
Marsh Posté le 13-04-2010 à 11:42:30
tu as du mettre ta fonction tempalte dans un .cpp alors qu'elle devrait vivre dans un .hpp
Marsh Posté le 13-04-2010 à 11:48:26
Joel F a écrit : tu as du mettre ta fonction tempalte dans un .cpp alors qu'elle devrait vivre dans un .hpp |
Ce sont les codes pour definir a tmat.h
// friends
friend tmat<T> operator + (tmat<T> a, tmat<T> b);
friend tmat<T> operator - (tmat<T> a, tmat<T> b);
friend tmat<T> operator * (tmat<T> a, tmat<T> b);
friend tmat<T> operator * (tmat<T> a, double b);
ca marche bien sur VC++6.0.Mais dans le VC 2005 ,il y a le probleme .
Marsh Posté le 13-04-2010 à 11:52:17
Aucune idee de ce qui a ete fixe dans VC2005 depuis VC6.0 (ou alors, tu n'essaies quand meme pas de linker des fichiers compiles avec les deux compilateurs?), mais passer par valeur les arguments d'operateurs binaires sur des matrices, ca me semble pas vraiment l'ideal pour les perfs.
Marsh Posté le 13-04-2010 à 11:56:29
Un Programmeur a écrit : Aucune idee de ce qui a ete fixe dans VC2005 depuis VC6.0 (ou alors, tu n'essaies quand meme pas de linker des fichiers compiles avec les deux compilateurs?), mais passer par valeur les arguments d'operateurs binaires sur des matrices, ca me semble pas vraiment l'ideal pour les perfs. |
c'est le programme:
///////////////////////////////////
// tmat.h - basend on STL
#pragma warning (disable: 4786)
#ifndef _TMAT_
#define _TMAT_
#include <complex>
#include <string>
#include <deque>
#include <vector>
#include <iostream>
#include <fstream>
using namespace std;
#include <crtdbg.h>
#ifndef _TVEC_
#include "tvec.h"
#endif
//////////////////////////////////////////////////////////////////////
// tmat class
template <class T>
class tmat : public tvec<T>
{
protected:
// Attributes
long m_nrows; // number of rows
long m_ncols; // number of columns
tvec<T> m_vec; // base vector container
public:
// constructors and destructors
tmat()
{
m_nrows = 0;
m_ncols = 0;
m_vec.resize(0);
}
tmat(long row, long col)
{
m_nrows = row;
m_ncols = col;
m_vec.resize(row * col);
}
tmat(long row, long col, const tvec<T> &sv)
{
m_nrows = row;
m_ncols = col;
m_vec = sv;
}
tmat(long row, long col, T x)
{
m_nrows = row;
m_ncols = col;
tvec<T> nv(row*col, x);
m_vec = nv;
}
tmat(long row, long col, T *x)
{
m_nrows = row;
m_ncols = col;
tvec<T> nv(row*col, x);
m_vec = nv;
}
tmat(const tmat<T> &a) // copy
{
m_nrows = a.m_nrows;
m_ncols = a.m_ncols;
m_vec = a.m_vec;
}
tmat &operator = (const tmat<T> &a) // assignment
{
m_nrows = a.m_nrows;
m_ncols = a.m_ncols;
m_vec = a.m_vec;
return *this;
}
virtual ~tmat()
{
m_nrows = 0;
m_ncols = 0;
m_vec.resize(0);
}
// Implementation
long nrows() { return m_nrows; }
long ncols() { return m_ncols; }
void resize(long rows, long cols)
{
m_nrows = rows;
m_ncols = cols;
m_vec.resize(rows * cols);
}
void show()
{
long i,j,k; k = 1;
cout << m_nrows << " "<< m_ncols << endl;
for(i=1; i<=m_nrows; i++) {
for(j=1; j<=m_ncols; j++ ) {
cout << m_vec(k) << " "; k++;
}cout << endl;
}cout << endl;
}
// error output
void cerror(char *text)
{
printf("%s\n", text);
}
// indexing operators
T &operator() (long i) // 1d indexing
{
if ( i < 1 || i > m_nrows * m_ncols )
cerror("operator(): index out of range" );
return m_vec(i);
}
T &operator() (long i, long j) // 2d indexing
{
if (i < 1 || i > m_nrows || j < 1 || j > m_ncols)
cerror("operator(): index out of range" );
long li = i-1;
long lj = j-1;
long lc = m_ncols;
return m_vec(li *lc + lj + 1);
}
// output
friend ostream &operator << (ostream &s, tmat<T> &m)
{
s << m.nrows() << " " << m.ncols() << endl;
for(int i=1;i<=m.nrows();i++) {
for(int j=1;j<=m.ncols();j++) {
s << m(i,j) << " ";
} s << endl;
}s << endl;
return s;
}
// friends
friend tmat<T> operator + (tmat<T> a, tmat<T> b);
friend tmat<T> operator - (tmat<T> a, tmat<T> b);
friend tmat<T> operator * (tmat<T> a, tmat<T> b);
friend tmat<T> operator * (tmat<T> a, double b);
};
template <class T>
tmat<T> ini_row(tmat<T> a,int b, tvec<T> c)
{
if(a.ncols()!=c.nsize()||b>a.nrows())
{ a.cerror("dimension do not conform\n" );
return a;
}
else
{
for(int i=1;i<=a.ncols();i++)
{
a(b,i)=c(i);
}
return a;
}
}
template <class T>
tmat<T> ini_col(tmat<T> a,int b, tvec<T> c)
{
if(a.nrows()!=c.nsize()||b>a.ncols())
{ a.cerror("dimension do not conform\n" );
return a;
}
else
{
for(int i=1;i<=a.nrows();i++)
{
a(i,b)=c(i);
}
return a;
}
}
template<class T>
tmat<T> operator + (tmat<T> a, tmat<T> b)
{
if (a.nrows() != b.nrows() || a.ncols() != b.ncols()) {
a.cerror("matrices do not conform in addition\n" );
return a;
}
tmat<T> c(a.nrows(), a.ncols());
for (long i = 1; i <= c.nrows(); i++)
for (long j = 1; j <= c.ncols(); j++)
c(i, j) = a(i, j) + b(i, j);
return c;
}
template <class T>
tmat<T> operator - (tmat<T> a, tmat<T> b)
{
if (a.nrows() != b.nrows() || a.ncols() != b.ncols()) {
a.cerror("matrices do not conform in subtraction\n" );
return a;
}
tmat<T> c(a.nrows(), a.ncols());
for (long i = 1; i <= c.nrows(); i++)
for (long j = 1; j <= c.ncols(); j++)
c(i, j) = a(i, j) - b(i, j);
return c;
}
template <class T>
tmat<T> operator * (tmat<T> a, tmat<T> b)
{
if(a.ncols() != b.nrows())
{
a.cerror("matrices do not conform for multiplication\n" );
return a;
}
T sum;
tmat<T> c(a.nrows(), b.ncols());
for(long i=1;i<=a.nrows();i++) {
for(long j=1;j<=b.ncols();j++) {
sum = 0;
for(long k=1;k<=a.ncols();k++)
sum += a(i,k) * b(k,j);
c(i,j) = sum;
}
}
return c;
}
template <class T>
tmat<T> operator * (tmat<T> a, double b)
{
for(long i=1;i<=a.nrows();i++)
{
for(long j=1;j<=a.ncols();j++)
{
a(i,j)=a(i,j)*b;
}
}
return a;
}
// construct an maxtrix from an array, with the diagonal elements set by this array
template <class T>
tmat<T> diagbyarray(tmat<T> A,double a[],int n)
{
int i;
A.resize (n,n);
for(i=1;i<=n*n;i++) A(i)=0;
for(i=1;i<=n;i++) A(i,i)=a[i-1];
return A;
}
template <class T>
tmat<T> eye(tmat<T> A,int n)
{
int i;
A.resize (n,n);
for(i=1;i<=n*n;i++) A(i)=0;
for(i=1;i<=n;i++) A(i,i)=1.0;
return A;
}
// tmat x-class functions
#include <math.h>
template <class T>
tmat<T> transpose(tmat<T> m)
{
tmat<T> c(m.ncols(), m.nrows());
for(long i=1;i<=m.ncols();i++) {
for(long j=1;j<=m.nrows();j++) {
c(i,j) = m(j,i);
}
}
return c;
}// transpose(tmat<T> m)
template <class T>
tmat<T> add(tmat<T> a, tmat<T> b)
{
if(a.ncols() != b.ncols() || a.nrows() != b.nrows()) {
cerror("matrices do not conform for addition\n" );
return a;
}
tmat<T> c(a.nrows(), a.ncols());
for(long i=1;i<=a.nrows();i++) {
for(long j=1;j<=a.ncols();j++) {
c(i,j) = a(i,j) + b(i,j);
}
}
return c;
}// add(tmat<T> a, tmat<T> b)
template <class T>
tmat<T> subtract(tmat<T> a, tmat<T> b)
{
if(a.ncols() != b.ncols() || a.nrows() != b.nrows()) {
cerror("matrices do not conform for subtraction\n" );
return a;
}
tmat<T> c(a.nrows(), a.ncols());
for(long i=1;i<=a.nrows();i++) {
for(long j=1;j<=a.ncols();j++) {
c(i,j) = a(i,j) - b(i,j);
}
}
return c;
}// subtract(tmat<T> a, tmat<T> b)
template <class T>
tmat<T> mul(tmat<T> a, tmat<T> b)
{
if(a.ncols() != b.nrows()) {
cerror("matrices do not conform for multiplication\n" );
return a;
}
T sum;
tmat<T> c(a.nrows(), b.ncols());
for(long i=1;i<=a.nrows();i++) {
for(long j=1;j<=b.ncols();j++) {
sum = 0;
for(long k=1;k<=a.ncols();k++)
sum += a(i,k) * b(k,j);
c(i,j) = sum;
}
}
return c;
}// mul(tmat<T> a, tmat<T> b)
template <class T>
tmat<T> sweep(long k1, long k2, tmat<T> &a)
{
//double eps = 1.0e-8;
T eps = 1.0e-8;
T d;
long i, j, k, n, it;
if (a.ncols() != a.nrows())
a.cerror("sweep: matrix a not square\n" );
n = a.nrows();
if (k2 < k1) { k = k1; k1 = k2; k2 = k; }
for (k = k1; k <= k2; k++) {
if ( fabs( a(k, k) ) < eps)
for (it = 1; it <= n; it++)
a(it, k) = a(k, it) = 0.0;
else {
d = 1.0 / a(k, k);
a(k, k) = d;
for (i = 1; i <= n; i++)
if (i != k)
a(i, k) *= (T) - d;
for (j = 1; j <= n; j++)
if (j != k)
a(k, j) *= (T) d;
for (i = 1; i <= n; i++) {
if (i != k) {
for (j = 1; j <= n; j++) {
if (j != k)
a(i, j) += a(i, k) *a(k, j) / d;
} // end for j
} // end for i != k
} // end for i
} // end else
} // end for k
return a;
}// sweep(long k1, long k2, tmat<T> &a)
template <class T>
tmat<T> inv(tmat<T> &a)
{
//printf("typeid(a(1,1)).name() == %s\n", typeid(a(1,1)).name());
if( strcmp(typeid(a(1,1)).name(), "double" ) != 0 &&
strcmp(typeid(a(1,1)).name(), "float" ) != 0 ) {
a.cerror("not a floating point type\n" );
return a;
}
if (a.ncols() != a.nrows())
a.cerror("INVERSE: matrix a not square\n" );
tmat<T> b = a;
sweep(1, b.nrows(), b);
return b;
} // inverse
template <class T>
tmat<T> submatrix(tmat<T> a, long lr, long r, long lc, long c)
// returns a designated submatrix, sa, of matrix a
{
long m = a.nrows(); long n = a.ncols();
if ((r > m) || (c > n))
{
a.cerror("index out of range\n" );
return a;
}
long r2 = r - lr + 1; long c2 = c - lc + 1;
tmat <T> b( r2, c2);
long lrm1 = lr - 1; long lcm1 = lc - 1;
for (long i = 1; i <= r2; i++)
for (long j = 1; j <= c2; j++)
b(i, j) = a(lrm1 + i, lcm1 + j);
return b;
}// submatrix(tmat<T> a, long lr, long r, long lc, long c)
/////////////////////////////////////////////////////////////////////
// determinant algorithms and definitions
#define VERY_SMALL 1.0e-12
#define VERY_LARGE 1.0E+12
// mine
#define zeroc complex<double>(0,0)
//#define zeroc 0.0;
//#define ZERO 1.0E-8
#define ZERO VERY_SMALL
template <class T>
void Pivot(tmat<T> &Data, long RefRow, T &Determ, bool &DetEqualsZero)
{
DetEqualsZero = true;
long NewRow = RefRow;
while (DetEqualsZero && (NewRow < Data.nrows())) {
NewRow++;
if (fabs(Data(NewRow, RefRow)) > ZERO) {
for (long i = 1; i <= Data.nrows(); i++) {
T temp = Data(NewRow, i);
Data(NewRow, i) = Data(RefRow, i);
Data(RefRow, i) = temp;
}
DetEqualsZero = false;
Determ = -Determ; // row swap adjustment to det
}
}
}// Pivot(Matrix<T> &Data, long RefRow, T &Determ, bool &DetEqualsZero)
template <class T>
T det(tmat<T> &Datain)
{
T Determ;
Determ = 1.0;
if (Datain.nrows() == Datain.ncols()) {
long Dimen = Datain.nrows();
tmat<T> Data( Dimen, Dimen);
Data = Datain;
T Coef;
long Row, RefRow = 0;
//enum bboolean DetEqualsZero = false;
bool DetEqualsZero = false;
while (!(DetEqualsZero) && (RefRow < Dimen - 1)) {
RefRow++;
if (fabs(Data(RefRow, RefRow)) < ZERO)
Pivot(Data, RefRow, Determ, DetEqualsZero);
if (!(DetEqualsZero))
for (Row = RefRow + 1; Row <= Dimen; Row++)
if (fabs(Data(Row, RefRow)) > ZERO) {
Coef = -((T) Data(Row, RefRow)) /
((T) Data(RefRow, RefRow));
for (int i = 1; i <= Dimen; i++)
Data(Row, i) = Data(Row, i) +
(T) (Coef*((T) Data(RefRow,i)));
}
Determ *= Data(RefRow, RefRow);
}
Determ = (DetEqualsZero) ? zeroc.real() : Determ * Data(Dimen, Dimen);
}
else Datain.cerror("Matrix is not square\n" );
return Determ;
}
#undef ZERO
// end determinant algorithms
/////////////////////////////////////////////////////////////////////
template<class T>
tmat<T> hconcat(tmat<T> a, tmat<T> b)
// horizontally concatenate matrix a with matrix b
{
long ar=a.nrows(); long ac=a.ncols();
long br=b.nrows(); long bc=b.ncols();
if (ar != br) {
cout << "hconcat: matrices have differing row numbers" << endl;
return a;
}
long i,j;
tmat<T> c(ar, ac+bc, (T)0);
for(i=1;i<=ar;i++) {
for(j=1;j<=ac+bc;j++) {
if(j <= ac) c(i,j) = a(i,j);
if(j > ac) c(i,j) = b(i,j-ac);
}
}
return c;
}// hconcat(tmat<T> a, tmat<T> b)
template<class T>
tmat<T> flop(tmat<T> a)
// flop matrix top to bottom
{
long i, j;
long m = a.nrows(); long n = a.ncols();
tmat<T> t1; t1 = a; tmat<T> t2(m, n);
for (i = 1; i <= m; i++) {
for (j = 1; j <= n; j++)
t2(m - i + 1, j) = t1(i, j);
}
return t2;
}// flop(tmat<T> a)
template<class T>
T diagprod(tmat<T> a)
// returns the diagonal product of matrix a
{
T dp = 1;
for (long i = 1; i <= a.nrows(); i++) // wasteful algo !!
for (long j = 1; j <= a.ncols(); j++)
if (i == j) dp *= a(i,j);
return dp;
}// diagprod(tmat<T> a)
template<class T>
void delcol(tmat<T> &a, long c)
// delete by reference a selected matrix column
{
long ar = a.nrows(); long ac = a.ncols();
if(c <= 0 || c > ac) return; // invalid col index
tmat<T> s, s1, s2;
if(c == 1) { s = submatrix(a, 1, ar, 2, ac); goto quit;}
if(c == ac) { s = submatrix(a,1, ar, 1, ac - 1); goto quit;}
s1 = submatrix(a, 1, ar, 1, c - 1);
s2 = submatrix(a, 1, ar, c + 1, ac);
s = hconcat(s1, s2);
quit: a = s;
}// delcol(tmat<T> a, long n)a
template <class T>
T perm(tmat<T> a)
// Faulty algorithm for calculating the permanent of a
// real square matrix
{
long i, n;
T prm = 0;
n = a.ncols(); // ?? rows might be better
tmat<T> s, o;
o = hconcat(a,a); // concat for n easy diagonal products
s=flop(o); // save flopped version
for(i=1;i<=n;i++)
{
prm += diagprod(o);
delcol(o, 1);
prm += diagprod(s);
delcol(s, 1);
}
return prm;
}// Perm(tmat<T> a)
#endif // _TMAT_
Marsh Posté le 13-04-2010 à 11:29:59
Le programme marche bien sur VC++6.0. Mais je utilise VC 2005, il y a le problemem comme ca:
main.obj : error LNK2019: unresolved external symbol "class tmat<double> __cdecl operator-(class tmat<double>,class tmat<double> )" (??G@YA?AV?$tmat@N@@V0@0@Z) referenced in function _main
Est-ce que il y a quelque personne peux me aider de resoudre ce probleme. Merci beaucoup!