Skip to content

Instantly share code, notes, and snippets.

@dgodfrey206
Created November 19, 2014 01:47
Show Gist options
  • Save dgodfrey206/7bfa2b9d39909857c8f3 to your computer and use it in GitHub Desktop.
Save dgodfrey206/7bfa2b9d39909857c8f3 to your computer and use it in GitHub Desktop.
Matrix class with multiplication
#include <stdexcept>
template <class T>
class Array
{
public:
Array();
Array(unsigned int, unsigned int = 0);
Array(Array const&);
~Array();
T const& operator[](unsigned int) const;
T & operator[](unsigned int);
T const* Data() const;
unsigned int Base() const;
unsigned int Length() const;
void SetBase(unsigned int);
void SetLength(unsigned int);
protected:
T* data;
unsigned int base;
unsigned int length;
};
template <class T>
Array<T>::Array()
: data(0)
, base(0)
, length(0)
{ }
template <class T>
Array<T>::Array(unsigned int n, unsigned int m)
: data(new T[n])
, base(m)
, length(n)
{ }
template <class T>
Array<T>::Array(Array<T> const& other)
: data(new T[other.length])
, base(other.base)
, length(other.length)
{
for (unsigned int i = 0; i < other.length; ++i)
data[i] = other.data[i];
}
template <class T>
Array<T>::~Array()
{ delete[] data; }
template <class T>
T const* Array<T>::Data() const
{ return data; }
template <class T>
unsigned int Array<T>::Base() const
{ return base; }
template <class T>
unsigned int Array<T>::Length() const
{ return length; }
template <class T>
T const& Array<T>::operator[](unsigned int position) const
{
unsigned int offset = position - base;
if (offset >= length)
throw std::out_of_range("Position out of range.");
return data[offset];
}
template <class T>
T& Array<T>::operator[](unsigned int position)
{
unsigned int offset = position - base;
if (offset >= length)
throw std::out_of_range("Position out of range.");
return data[offset];
}
template <class T>
void Array<T>::SetBase(unsigned int newBase)
{ base = newBase; }
template <class T>
void Array<T>::SetLength(unsigned int newLength)
{
T const* newData = new T[newLength];
unsigned int min = length < newLength ? length : newLength;
for (unsigned int i = 0; i < length; ++i)
newData[i] = data[i];
delete[] data;
data = newData;
length = newLength;
}
template <class T>
class Array2D
{
protected:
unsigned int numberOfRows, numberOfColumns;
Array<T> array;
public:
class Row
{
Array2D& array2D;
unsigned int const row;
public:
Row(Array2D& _array2D, unsigned int _row)
: array2D(_array2D)
, row(_row)
{ }
T& operator[](unsigned int column) const
{ return array2D.Select(row, column); }
};
Array2D(unsigned int, unsigned in);
T& Select(unsigned int, unsigned int);
Row operator[](unsigned int);
};
template <class T>
Array2D<T>::Array2D(unsigned int n, unsigned int m)
: numberOfRows(n)
, numberOfColumns(m)
, array(n * m)
{ }
template <class T>
T& Array2D<T>::Select(unsigned int i, unsigned int j)
{
if (i >= numberOfRows)
throw std::out_of_range("invalid row");
if (i >= numberOfColumns)
throw std::out_of_range("invalid column");
return array[i * numberOfColumns + j];
}
template <class T>
typename Array2D<T>::Row Array2D<T>::operator[](unsigned int row)
{ return Row(*this, row); }
template <class T>
class Matrix : Array2D<T>
{
Matrix(unsigned int, unsigned int);
Matrix operator*(Matrix const&) const;
Matrix operator+(Matrix const&) const;
};
template <class T>
Matrix<T> Matrix<T>::operator*(Matrix<T> const& other) const
{
if (numberOfColumns != other.numberOfRows)
throw std::invalid_argument("incompatible matrices");
Matrix<T> result(numberOfRows, other.numberOfColumns);
for (unsigned int i = 0; i < numberOfRows; ++i)
{
for (unsigned int j = 0; j < other.numberOfColumns; ++j)
{
T sum = 0;
for (unsigned int k = 0; k < numberOfColumns; ++k)
sum += (*this)[i][k] * other[k][j];
result[i][j] = sum;
}
}
return result;
}
int main()
{
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment