Original Post
I'm working on a physics engine and I'm writing up a nice Matrix library to tag along with it. I'd like some feedback on it though. Before writing the bulk of my physics code, I'd like this to be a solid as possible because the more efficient this is, the easier it will be down the road. I've tested it out more or less and it seems to be working math wise, but if anyone sees an error, please point it out. Thanks! matrix.h matrix.cpp [Edited by - tendifo on July 9, 2006 10:29:42 PM]
#ifndef matrix_h
#define matrix_h
class Matrix {
public:
// constructors
Matrix(int r, int c);
Matrix();
// create the element array
void initElements(int r, int c);
// manipulate the matrix
double getElement(int r, int c);
double get(); // gets the first element in the matrix
void setElement(int r, int c, double e);
// retrieve information about the matrix
int getRows();
int getColumns();
bool fetchError(); // returns if there's an error from last calculation or whatever
// clearing functions
void blank(); // create a blank matrix (all 0's)
void identity(); // create an identity matrix
// matrix math functions
void add(Matrix a, Matrix b);
void subt(Matrix a, Matrix b);
void mult(Matrix a, Matrix b);
void scale(double s);
private:
int rows, columns; // number of rows and columns in the matrix
double *elements; // the element array
bool error; // contains information about errors
};
#endif
#include "matrix.h"
Matrix::Matrix(int r, int c) {
initElements(r, c);
}
Matrix::Matrix() {
Matrix(1, 1);
}
void Matrix::initElements(int r, int c) {
rows = r;
columns = c;
elements = (double*)malloc(sizeof(double) * rows * columns);
blank(); // set everything to 0
}
double Matrix::getElement(int r, int c) {
int elementId = r * columns + c;
return elements[elementId];
}
double Matrix::get() {
return getElement(0, 0):
}
void Matrix::setElement(int r, int c, double e) {
int elementId = r * columns + c;
elements[elementId] = e;
}
int Matrix::getRows() {
return rows;
}
int Matrix::getColumns() {
return columns;
}
bool Matrix::fetchError() {
return error;
}
void Matrix::blank() {
for (int i = 0; i < getRows(); i += 1)
for (int j = 0; j < getColumns(); j += 1)
setElement(i, j, 0);
}
void Matrix::identity() {
if (getRows() == getColumns()) {
blank();
for (int i = 0; i < getRows(); i += 1)
setElement(i, i, 1);
error = false;
} else {
error = true;
}
}
void Matrix::add(Matrix a, Matrix b) {
// is subtraction legal?
if (a.getRows() == b.getRows() && a.getColumns() == b.getRows()) {
// recreate the matrix
initElements(a.getRows(), a.getColumns());
for (int i = 0; i < a.getRows(); i += 1)
for (int j = 0; j < a.getColumns(); j += 1)
setElement(i, j, a.getElement(i, j) + b.getElement(i, j));
error = false;
} else {
error = true;
}
}
void Matrix::subt(Matrix a, Matrix b) {
// is subtraction legal?
if (a.getRows() == b.getRows() && a.getColumns() == b.getRows()) {
// recreate the matrix
initElements(a.getRows(), a.getColumns());
for (int i = 0; i < a.getRows(); i += 1)
for (int j = 0; j < a.getColumns(); j += 1)
setElement(i, j, a.getElement(i, j) - b.getElement(i, j));
error = false;
} else {
error = true;
}
}
void Matrix::mult(Matrix a, Matrix b) {
// first check to see if multiplication is even legal
if (a.getColumns() == b.getRows()) {
// recreate the matrix
initElements(a.getRows(), b.getColumns());
for (int i = 0; i < a.getRows(); i += 1)
for (int j = 0; j < b.getColumns(); j += 1) {
double sum = 0;
for (int k = 0; k < a.getColumns(); k += 1)
sum += a.getElement(i, k) * b.getElement(k, j);
setElement(i, j, sum);
}
error = false;
} else {
// however, if we're dealing with vector matrices, then we can multiply
if (a.getColumns() == 1 && b.getColumns() == 1 && a.getRows() == b.getRows()) {
// create a 1x1 matrix to store the result
initElements(1, 1);
double sum = 0;
for (int i = 0; i < a.getRows(); i += 1)
sum += a.getElement(i, 0) * b.getElement(i, 0);
setElement(0, 0, sum);
error = false;
} else {
error = true;
}
}
}
void Matrix::scale(double s) {
for (int i = 0; i < getRows(); i += 1)
for (int j = 0; j < getColumns(); j += 1)
setElement(i, j, getElement(i, j) * s);
}