From: arvaniti <arv...@pi...> - 2011-06-30 15:24:56
|
Please help!!!!! After some effords i havent yet resolved the issue or handling overloading operators defined in a class properly According to the manual this should be automatic.... but i havent managed ... thks arvaniti wrote: > > Hi to everyone > > I have 2 questions maybe related to post: > > 1Q How i can pass overloading operators from a class to python? > > It seems that i get some troubles for oveloading operators > > In C++ I have the simple Mat [matrix] class with some overloading > operators and the following code: > > mat.h > > #ifndef _MAT_H > #define _MAT_H > > #include <iostream> > #include <ostream> > > using namespace std; > > class Mat { > public: > //------------------------------------------------------ > // Constructors and Destructor for class data types Mat > //------------------------------------------------------ > // > Mat(); // Constructor #1 Initial values > Mat(int m,int n); // Constructor #2 for m by n matrix > Mat(const Mat &vrhs); // Constructor #3 copy constructor > //~Mat(); // Destructor > virtual ~Mat(); // Destructor > // > //---------------------------------------------------------------- > // Overload Operators > //---------------------------------------------------------------- > // > double& operator()(int x,int y) const; // Element access > friend ostream& operator<< > (ostream& os, Mat& m); // Output operator > Mat& operator= (const Mat& vrhs); // Assignment #1 > Mat& operator= (double vValue); // Assignment #2 > Mat operator* (const Mat& vrhs); // Multiply overloading for > Mat > Mat operator+ (const Mat& vrhs); // Addition overloading > Mat operator- (Mat& vrhs); // Subtraction overloading > Mat operator/ (Mat& vrhs); // Element div overloading > // > //---------------------------------------------------------------- > // Utility functions and Operations > //---------------------------------------------------------------- > // > int nrow() const; // Return rows > int ncol() const; // Return Columns > void Print(); // Print matrix to stdout > void Print(const char *vString); // Print matrix to stdout with > string > Mat transpose(); // Transpose > bool malloc(int x, int y); // Allocate memory for x-by-y > matrix > void mfree(); // Deallocate memory > //------------------------------------------------------------------ > private: > int nrows, ncols; // private matrix dimensions > params > double *mvalues; // private matrix values Only > pointer > // // mvalues since we flattening matrices > double mNaN; // Return NaN on bad input > }; > #endif /* MAT_H_ */ > > > mat.cpp methods > > include "Mat.h" // Constructor Destructor Operators and Function defs > #include <limits> // For NaN > #define NDEBUG // disables assert at Release level > #include <stdio.h> // standard IO lib > #include <cassert> // assert header for assertion > #include <iostream> // cout, cerr, endl, and flush > #include <fstream> > #include <ostream> > > using namespace std; > > // Constructor #1 > Mat::Mat():nrows(0),ncols(0), > > mvalues(0),mNaN(std::numeric_limits<double>::quiet_NaN()) { > // TODO Auto-generated constructor stub > /* malloc(1,1); */ > } > // > // > // Constructor #2 > Mat::Mat(int m, int n):nrows(0),ncols(0),mvalues(0), > > mNaN(std::numeric_limits<double>::quiet_NaN()){ > malloc(m,n); // memory allocation and initialization > } > > // Constructor #3 Copy constructor [if not defined it is created > automatically] > Mat::Mat(const Mat &vrhs):nrows(0),ncols(0),mvalues(0), > mNaN(std::numeric_limits<double>::quiet_NaN()){ > > malloc(vrhs.nrow(),vrhs.ncol()); > for (int i=1; i<=nrows; ++i) > { > for (int j=1; j<=ncols; ++j) > { > (*this)(i,j) = vrhs(i,j); > } > } > } > // > // Destructor > Mat::~Mat() { > // TODO Auto-generated destructor stub > mfree(); // memory deallocation > } > > //- Assignment operator #1 > // > Mat& > Mat::operator= (const Mat &vrhs){ > > mfree(); > malloc(vrhs.nrow(),vrhs.ncol()); > for (int i=1; i<=nrows; ++i) > { > for (int j=1; j<=ncols; ++j) > { > (*this)(i,j) = vrhs(i,j); > } > } > return (*this); > } > // > //- Assignment operator #2 > Mat& > Mat::operator= (double vValue){ > for (int i=0; i<nrows*ncols; ++i) > { > mvalues[i] = vValue; > } > return (*this); > } > // multiplication overloading operator > Mat > Mat::operator* (const Mat &vrhs){ > assert(ncols==vrhs.nrows); // assert is used to check rows cols > assert(nrows==vrhs.ncols); > Mat vProduct(nrows,vrhs.ncol()); > for (int i=1; i<=nrows; i++) > { > for (int j=1; j<=vrhs.ncol(); j++) > { > for (int k=1;k<=ncols;k++) > { > vProduct(i,j)+=(*this)(i,k)*vrhs(k,j); > } > } > } > return vProduct; > } > > //- Element access > // > // > //-------------------------------------------------------------- > // Beware with the matrix indices!!! > // with the definition below of the () operator arrays are starting at 1 > and ending at > // now or column number rather than the usual case of starting at zero and > ending at ncol-1,nrow-1 > double& > Mat::operator()(int x, int y) const { > //- Basic range checks. > // > if (x < 1 || x > nrows){ > std::cerr << "Mat::operator(): illegal row index!" << endl; > return mvalues[0]; > } > else if (y < 1 || y > ncols ){ > std::cerr << "Mat::operator(): illegal column index!" << endl; > return mvalues[0]; > } > // for R > //- Offset is ((y-1)*mNumRows)+(x-1) > // rather than ((x-1)*mNumCols)+(y-1) > // because we want to organize memory the same > // way as it is in an R matrix. R is column-major. > // Reference: > // http://en.wikipedia.org/wiki/Row-major_order#Column-major_order > //---------------------------------------------------------------- > // General transformation of d dim arrays to 1D array > //--------------------------------------------------------------- > // for a d-dim array there is a general formula for transforming to 1 > dim array > // sum_{k=1,d}(product_{l=k+1,d}N_{l})n_{k} > // d=2 array offset=N_y*X+Y > // d=3 array offset=N_y*(N_z*Z +X)+Y > // etc > else return mvalues[((x-1)*ncols)+(y-1)]; > } > /*double& > Mat::operator()(int x, int y) const > { > //- Basic range checks. > // > if ( ( x < 1 ) || ( x > nrows ) > || ( y < 1 ) || ( y > ncols ) ) > { > cerr << "Mat::operator(): range error!" << endl; > return (double &) mNaN; > } > > //- Offset is ((y-1)*mNumRows)+(x-1) > // rather than ((x-1)*mNumCols)+(y-1) > // because we want to organize memory the same > // way as it is in an R matrix. R is column-major. > // Reference: > // http://en.wikipedia.org/wiki/Row-major_order#Column-major_order > // > return mvalues[((x-1)*ncols)+(y-1)]; > } > */ > // > // output of the matrix on screen > > ostream& > operator<<(ostream& os, Mat &m){ > int mval=m.nrow(); > int nval=m.ncol(); > for(int i=1; i<=mval; ++i){ > for(int j=1; j<=nval; ++j) > os<<m(i,j)<<" "; > os<<endl; > } > return os; > } > // > //overloading operator To compute the summation > Mat > Mat::operator+(const Mat& a){ > Mat sum(nrows, ncols); > for (int i=1; i<=nrows; i++){ > for(int j=1; j<=ncols; j++){ > sum(i,j) = (*this)(i,j) + a(i,j); > } > } > return sum; > } > // > //overloading operator To compute the subtraction > Mat > Mat::operator-(Mat& a){ > Mat difference(nrows, ncols); > for (int i=1; i<=nrows; i++) > for(int j=1; j<=ncols; j++) > difference(i,j) = (*this)(i,j) - a(i,j); > return difference; > } > // > //Overloading operator To compute the division > //element by element > Mat Mat::operator/(Mat& a){ > Mat divide(nrows, ncols); > for (int i=1; i<=nrows; i++) > for(int j=1; j<=ncols; j++) > divide(i,j) = (*this)(i,j) / a(i,j); > return divide; > } > // > // > //-------------------------------------------------------- > // Definition of Operations > //-------------------------------------------------------- > //- Transpose > // > Mat > Mat::transpose() > { > Mat vTranspose(ncols,nrows); > for (int i=1; i<=nrows; i++) > { > for (int j=1; j<=ncols; j++) > { > vTranspose(j,i) = (*this)(i,j); > } > } > return vTranspose; > } > // > //- Print #1 > // > void > Mat::Print() > { > for (int i=1; i<=nrows; i++) > { > for (int j=1; j<=ncols; j++) > { > std::cout << (*this)(i,j) << " "; > } > std::cout << endl; > } > } > // > //- Print #2 > // > void > Mat::Print(const char *vString) > { > std::cout << vString; > Print(); > } > // > //- Get number of rows > // > int > Mat::nrow() const > { > return nrows; > } > // > //- Get number of columns > // > int > Mat::ncol() const > { > return ncols; > } > // > // > //---------------------------------------------------------- > // Dynamic Memory Allocation and deallocation operations > //---------------------------------------------------------- > // Allocate memory > // Initialize all entries to 0. > // > bool > Mat::malloc(int x, int y) > { > mfree(); > try { > mvalues = new double [x*y]; > } > catch (...) { > std::cerr << "Mat::AllocateMemory(): unable to allocate memory for > " > << x << " by " << y << " matrix!" << endl; > return false; > } > > nrows = x; > ncols = y; > for (int i=1; i<=nrows; i++) > { > for (int j=1; j<=ncols; j++) > { > (*this)(i,j) = 0.0; > } > } > return true; > } > // > //- Deallocate memory > // > void > Mat::mfree() > { > if ( mvalues != 0 ) > { > delete [] mvalues; > mvalues = 0; > } > } > > and interface file > > mat.i > > /* File : matrix.i */ > %module matrix > > %{ > /* The #define SWIG_FILE_WITH_INIT line inserts a macro that */ > /* specifies that the resulting C file should be built as a */ > /* python extension, inserting the module init code */ > #define SWIG_FILE_WITH_INIT > #include "Mat.h" > %} > > /* Let's just grab the original header file here */ > /* instead below one should include all the */ > /* function prototypes or classes */ > > %include "Mat.h" > > /* use the rename directive to wrap overloading operators */ > /* the rename should be used only for friend operators */ > /* the overloading operators members of the class dont need to be renamed > */ > > // %ignore ostream& operator<<(ostream& os, Mat& m); > > > I build the project and produce a matrix.pyd module which I import to > python > > it seems that i cannot get any of the overloading operators defined in the > class > > in particular the () operator is not there!!! > > so when i try > > for i in range(r): > for j in range(c): > c[i][j]=in1[i][j] > > I am a syntax error > > TypeError: 'Mat' object does not support indexing > > or > > for i in range(r): > for j in range(c): > c(i,j)=in1(i,j) > > SyntaxError: can't assign to function call > > > 2Q > > I would like to use SWIG-PYTHON building a project with matrix operations > using boost matrix classes > > can anyone guide me through how i can write properly the interface file > especially with TEMPLATES > > I would appreciate if one could provide me a simple example using boost > libs > > Thanks in advance > > Christos Arvanitis > > > > -- View this message in context: http://old.nabble.com/SWIG-PYTHON-OVERLOADING-OPERATORS-FOR-A-CLASS---BOOST-2-tp31952147p31964162.html Sent from the swig-user mailing list archive at Nabble.com. |