#ifndef F77_MATRIX_H
#define F77_MATRIX_H
#include <assert.h>
#include <sys/types.h>
/*
class FMATRIX
=============
A minimal class used when passing multi-dimensional array
arguments from C++ to FORTRAN 77 (received as FORTRAN arrays),
and subsequently returned back to C++ as properly aranged
C++ arrays.
Problem : FORTRAN organises data in a "column-first" order,
while C++ organises data in a "row-first" order.
Solution:
(1) The FMATRIX class can take a C++ array as a constructor
parameter. A FORTRAN compatible copy of the array is
then made. The destructor will then copy the result back
to the original c++ array.
(2) The FMATRIX class provides "subscript operators" allowing
the programmer to read and write from the array, using
FORTRAN-like syntax and indexing semantics.
Author: Carsten A. Arnholm, 04-MAR-1996
*/
template <class T>
class FMATRIX {
public:
FMATRIX(size_t dim1, size_t dim2);
FMATRIX(T* cpparr, size_t dim1, size_t dim2);
operator T*();
T& operator()(size_t index1, size_t index2);
~FMATRIX();
public:
const size_t ndim; // number of array dimensions
size_t dim[7]; // size of each dimension
T* cpprep; // original c++ array
T* f77rep; // array used by FORTRAN
};
template <class T>
FMATRIX<T>::FMATRIX(size_t dim1, size_t dim2)
: cpprep(NULL),f77rep(new T[dim1*dim2]),ndim(2)
{
dim[0]=dim1;
dim[1]=dim2;
dim[2]=0;
dim[3]=0;
dim[4]=0;
dim[5]=0;
dim[6]=0;
}
template <class T>
FMATRIX<T>::FMATRIX(T* cpparr, size_t dim1, size_t dim2)
: cpprep(cpparr),f77rep(new T[dim1*dim2]),ndim(2)
{
dim[0]=dim1;
dim[1]=dim2;
dim[2]=0;
dim[3]=0;
dim[4]=0;
dim[5]=0;
dim[6]=0;
// make a FORTRAN-compatible copy of the array
size_t index_cpp=0;
size_t index_f77;
for(size_t i=0;i<dim[0];i++) {
for(size_t j=0;j<dim[1];j++) {
index_f77 = j*dim[0] + i;
f77rep[index_f77] = cpprep[index_cpp++];
}
}
}
template <class T>
FMATRIX<T>::operator T*()
{
// Pass the FORTRAN representation when calling a function
return f77rep;
}
template <class T>
T& FMATRIX<T>::operator()(size_t index1, size_t index2)
{
assert(ndim==2); // only 2d arrays supported (so far)
// indexing according to F77 conventions
size_t index_f77 = index2*dim[0] + index1;
// return a reference to the array element
return *(f77rep+index_f77);
}
template <class T>
FMATRIX<T>::~FMATRIX()
{
if(cpprep) {
assert(ndim==2); // only 2d arrays supported (so far)
// copy back from FORTRAN to C++ array
size_t index_cpp;
size_t index_f77=0;
for(size_t j=0;j<dim[1];j++) {
for(size_t i=0;i<dim[0];i++) {
index_cpp = i*dim[1] + j;
cpprep[index_cpp] = f77rep[index_f77++];
}
}
}
// delete the FORTRAN copy of the arry
delete[] f77rep;
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1