Mojo example class

R

Ryan Mitchley

Hi

I have a rather complicated class for performing matrix operations using
complex arithmetic.

I have written two classes, CComplexMatrix and CComplexMatrixTemp, and have
been attempting to remove unnecessary object copies by converting to the
temp class for intermediate operations. The temp class reuses allocated
space as is necessary.

While ironing out some bugs and attempting to improve the performance of
certain operations, I have been tempted to try and convert the entire class
to use the Mojo conventions outlined by Andrei Alexandrescu
(http://www.cuj.com/documents/s=8246/cujcexp2102alexandr/).

I was wondering if anyone has a complete example of a class that has been
"Mojo-fied", that I could use for comparison and inspiration (e.g. a
complete String class). There are a couple of things that I am hazy about,
and I think I could learn a lot from a complete example - as opposed to
posting about specific issues. The article provides all of the bones, but I
am interested in a little bit of meat!

I can email the source code of my matrix class to anyone interested.

Ryan
 
R

Ryan Mitchley

Thanks, Pavel!

I had a look through some of the code, and may have been looking in the
wrong places - but I didn't find too many examples of some of the techniques
outlined in Andrei's article. I saw several constructors taking mojo
temporary parameters, but that was about it. What about mojo::fnresult? Does
mojo::constant ever get used?

For the record, the header file for the class that I would like to convert
to using the MoJo conventions is attached below. It has a couple of issues
that I know are frowned upon by C++ gurus, but hopefully not too many. I am
not really sure how many of these functions should stay, and how many should
go. Which assignment operators do I need? Should *everything* that returns a
matrix return a mojo::fnresult<>? I would guess that everything that
currently takes a CComplexMatrixTemp as a parameter would now take a
mojo::temporary<> parameter? I think I need a couple of more clues to be
able to use this technique . . . I am probably going to go ahead and try it,
anyway, but I don't rate my chances too highly at the moment!

Thanks for any help!

Ryan

-----------------------------------

// ComplexMatrix.h: interface for the CComplexMatrix class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(__COMPLEXARRAY_H)
#define __COMPLEXARRAY_H

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CComplexMatrixTemp;
//class CComplexMatrix;

#include "MathCore/include/Matrix.h"
#include <complex>

using namespace std;

#define COMPLEX_WIDTH 8
#define COMPLEX_PRECISION 4

class CComplexMatrix : public CMatrix
{
public:
static registerInFactory<CBase, CComplexMatrix> regClass;
// Data generation
CComplexMatrix & FillWithNoise(NOISE_DISTRIB Distribution, NOISE_SPECT
Spectrum,
FTYPE fMean, FTYPE fVariance, size_t nM=0, size_t nN=0);
operator complex<FTYPE>*() const { return m_cfArray; }
CComplexMatrix & operator=(CComplexMatrixTemp another);
CComplexMatrix operator=(const CComplexMatrix &another);
// Element-wise array operators
CComplexMatrixTemp operator+(const CComplexMatrix &another);
CComplexMatrixTemp operator+(CComplexMatrixTemp another);
CComplexMatrixTemp operator-(const CComplexMatrix &another);
CComplexMatrixTemp operator-(CComplexMatrixTemp another);
CComplexMatrixTemp operator%(const CComplexMatrix &another);
CComplexMatrixTemp operator*(const CComplexMatrix &another);
CComplexMatrixTemp operator*(CComplexMatrixTemp x);
CComplexMatrixTemp operator%(CComplexMatrixTemp another);
CComplexMatrixTemp operator/(const CComplexMatrix &another);
CComplexMatrixTemp operator/(CComplexMatrixTemp another);
CComplexMatrix & operator+=(CComplexMatrixTemp another);
CComplexMatrix & operator+=(const CComplexMatrix &another);
CComplexMatrix & operator-=(CComplexMatrixTemp another);
CComplexMatrix & operator-=(const CComplexMatrix &another);
CComplexMatrix & operator%=(CComplexMatrixTemp another);
CComplexMatrix & operator%=(const CComplexMatrix &another);
CComplexMatrix & operator/=(CComplexMatrixTemp another);
CComplexMatrix & operator/=(const CComplexMatrix &another);
// Operators with scalar arguments
CComplexMatrixTemp operator+(const FTYPE fScalar);
CComplexMatrixTemp operator-(const FTYPE fScalar);
CComplexMatrixTemp operator*(const FTYPE fScalar);
CComplexMatrixTemp operator/(const FTYPE fScalar);
CComplexMatrixTemp operator+(const complex<FTYPE> fScalar);
CComplexMatrixTemp operator-(const complex<FTYPE> fScalar);
CComplexMatrixTemp operator*(const complex<FTYPE> fScalar);
CComplexMatrixTemp operator/(const complex<FTYPE> fScalar);
CComplexMatrix operator+=(const FTYPE fScalar);
CComplexMatrix operator-=(const FTYPE fScalar);
CComplexMatrix operator*=(const FTYPE fScalar);
CComplexMatrix operator/=(const FTYPE fScalar);
CComplexMatrixTemp operator~() const;
complex<FTYPE> operator[](const size_t n) { return m_cfArray[n]; }
// N.B. The () (matrix subscript) operators assume that the first
// element row or column is referenced as item 1, not item 0 as
// is conventional when programming in C. This is to preserve
// easy compatibility with MATLAB syntax.
complex<FTYPE> operator()(const size_t nM, const size_t nN) const;
complex<FTYPE>& operator()(const size_t nM, const size_t nN);
CComplexMatrixTemp operator()(const size_t nM, const cColonType
ColonParam);
CComplexMatrixTemp operator()(const cColonType ColonParam, const size_t
nN);
CComplexMatrixTemp operator()(const size_t nM);

complex<FTYPE> Min();
complex<FTYPE> Min(size_t &nMinIndex);
complex<FTYPE> Max();
complex<FTYPE> Max(size_t &nMaxIndex);
CComplexMatrix & Swap(CComplexMatrix &another);
CComplexMatrix & ScalarMult(const FTYPE fScalar);
FTYPE Norm();
complex<FTYPE> CComplexMatrix::DotConj(const CComplexMatrix &another);
complex<FTYPE> Dot(const CComplexMatrix &another);
CComplexMatrix & AddArray(const complex<FTYPE> fScaleCoef, const
CComplexMatrix &another);
virtual FTYPE MagSum() const;
void Clear();
CComplexMatrix& SetRef(complex<FTYPE> *cfArray, const size_t nM, const
size_t nN,
int nTranspose);
int SetRow(const size_t nRow, const CComplexMatrix &RowVector);
// int SetRow(const size_t nRow, const complex<FTYPE> & z1, ...);
int SetColumn(const size_t nColumn, const CComplexMatrix &ColumnVector);
CComplexMatrix& Set(const complex<FTYPE> * cfArray, const size_t nM, const
size_t nN,
int nTranspose);
CComplexMatrix& Set(const FTYPE * fArray, const size_t nM, const size_t nN,
int nTranspose);
CComplexMatrix& Set(const FTYPE *fRealMatrix, const FTYPE *fImagArray,
const size_t nM, const size_t nN, int nTranspose);
CComplexMatrix& Set(const complex<FTYPE> fX, const complex<FTYPE> fY,
const complex<FTYPE> fZ);
CComplexMatrix& Set(const complex<FTYPE> fX, const complex<FTYPE> fY);
CComplexMatrix& Set(const complex<FTYPE> fX);
CComplexMatrix& Set(const FTYPE fX, const FTYPE fY, const FTYPE fZ);
CComplexMatrix& Set(const FTYPE fX, const FTYPE fY);
CComplexMatrix& Set(const FTYPE fX);
CComplexMatrix& Create(const size_t nM, const size_t nN);
CComplexMatrix(const complex<FTYPE> *cfArray, const size_t nM, const size_t
nN,
int nTranspose);
CComplexMatrix(size_t NumRows, size_t NumColumns);
CComplexMatrix(const CComplexMatrix &another); // copy constructor
CComplexMatrix();
virtual ~CComplexMatrix();
// Serialization
virtual void XML_WriteHead(ostream &os) const;
virtual void XML_WriteTail(ostream &os) const;
virtual int XML_ReadHead(list<string> &is, list<string>::const_iterator&
i);
virtual int XML_ReadTail(list<string> &is, list<string>::const_iterator&
i);
virtual void XML_SchemaWriteHead(ostream &out) const;
virtual void XML_SchemaWriteTail(ostream &out) const;
virtual string ArrayType() const { return "complex"; }

// friend functions
// friend CComplexMatrixTemp::CComplexMatrixTemp(const CComplexMatrix
&another);

friend CComplexMatrixTemp conj(const CComplexMatrix &z);
friend CComplexMatrixTemp ctranspose(const CComplexMatrix &z);
friend CComplexMatrixTemp herm(const CComplexMatrix &z);
friend CComplexMatrixTemp transpose(const CComplexMatrix &z);
friend CComplexMatrixTemp tanh(const CComplexMatrix &z);
friend CComplexMatrixTemp sinh(const CComplexMatrix &z);
friend CComplexMatrixTemp cosh(const CComplexMatrix &z);
friend CComplexMatrixTemp atan(const CComplexMatrix &z);
friend CComplexMatrixTemp asin(const CComplexMatrix &z);
friend CComplexMatrixTemp acos(const CComplexMatrix &z);
friend CComplexMatrixTemp tan(const CComplexMatrix &z);
friend CComplexMatrixTemp sin(const CComplexMatrix &z);
friend CComplexMatrixTemp cos(const CComplexMatrix &z);
friend CComplexMatrixTemp log10(const CComplexMatrix &z);
friend CComplexMatrixTemp ln(const CComplexMatrix &z);
friend CComplexMatrixTemp exp(const CComplexMatrix &z);
friend CComplexMatrixTemp invcbrt(const CComplexMatrix &z);
friend CComplexMatrixTemp cbrt(const CComplexMatrix &z);
friend CComplexMatrixTemp invsqrt(const CComplexMatrix &z);
friend CComplexMatrixTemp sqrt(const CComplexMatrix &z);
friend CComplexMatrixTemp inv(const CComplexMatrix &z);
friend CComplexMatrixTemp pow(const CComplexMatrix &mantissas, const
CComplexMatrix &exponents);
friend CComplexMatrixTemp pow(const CComplexMatrix &mantissas,
CComplexMatrixTemp exponents);
friend CComplexMatrixTemp pow(CComplexMatrixTemp mantissas, const
CComplexMatrix &exponents);

friend complex<FTYPE> mean(const CComplexMatrix &x);
friend FTYPE var(const CComplexMatrix &x);
friend FTYPE norm(const CComplexMatrix &x);
friend CComplexMatrixTemp chol(const CComplexMatrix &z);

// friend operators
friend CComplexMatrixTemp operator+(CComplexMatrixTemp lhs, const
CComplexMatrix & another);
friend CComplexMatrixTemp operator-(CComplexMatrixTemp lhs, const
CComplexMatrix & another);
friend CComplexMatrixTemp operator%(CComplexMatrixTemp lhs, const
CComplexMatrix & another);
friend CComplexMatrixTemp operator/(CComplexMatrixTemp lhs, const
CComplexMatrix & another);
friend CComplexMatrixTemp operator+(FTYPE fScalar, const CComplexMatrix &
realArray);
friend CComplexMatrixTemp operator-(FTYPE fScalar, const CComplexMatrix &
realArray);
friend CComplexMatrixTemp operator*(FTYPE fScalar, const CComplexMatrix &
realArray);
friend CComplexMatrixTemp operator/(FTYPE fScalar, const CComplexMatrix &
realArray);
friend CComplexMatrixTemp operator+(complex<FTYPE> cfScalar, const
CComplexMatrix & realArray);
friend CComplexMatrixTemp operator-(complex<FTYPE> cfScalar, const
CComplexMatrix & realArray);
friend CComplexMatrixTemp operator*(complex<FTYPE> cfScalar, const
CComplexMatrix & realArray);
friend CComplexMatrixTemp operator/(complex<FTYPE> cfScalar, const
CComplexMatrix & realArray);
friend CComplexMatrixTemp & pow(CComplexMatrixTemp &mantissas,
CComplexMatrix &exponents);

// Stream I/O
virtual void printOn(std::eek:stream& os) const;

protected:
complex<FTYPE> * m_cfArray;
};

#endif // !defined(__COMPLEXARRAY_H)
 
P

Pavel Vozenilek

Ryan Mitchley said:
I had a look through some of the code, and may have been looking in the
wrong places - but I didn't find too many examples of some of the techniques
outlined in Andrei's article. I saw several constructors taking mojo
temporary parameters, but that was about it. What about mojo::fnresult? Does
mojo::constant ever get used?
I don't know details - its the only place Mojo is used I know.

You may also consider some exiting matrix library: daixtrose, ublas (I
am not expert here and cannot compare).

/Pavel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,146
Messages
2,570,832
Members
47,374
Latest member
anuragag27

Latest Threads

Top