The goal of this project is to fill in the rest of the details of the
Matrix
and Vector
classes we wrote during the
last 2 weeks. More final versions of the header and source files are
given below. Some of the methods and operators have been implemented
some have not. Your tasks are as follows:
print()
method that prints the matrix or vector
to the screen MATLAB-style.Matrix
class works as expected.#ifndef __UNIT3_EXAMPLES_MATRIX_H__
#define __UNIT3_EXAMPLES_MATRIX_H__
#include <cstdlib>
#include "vector.h"
namespace math {
class Matrix
{
public:
// Creates an empty matrix
Matrix();
// Creates an uninitialized matrix of the given size
Matrix(size_t width, size_t height);
/* Creates a matrix of the given size with d on the diagonal and
* zero off the diagonal*/
Matrix(size_t width, size_t height, double d);
// Destructor
~Matrix();
// Copies a matrix
Matrix(const Matrix& other);
Matrix& operator=(const Matrix& other);
// Creates a matrix from a single column-vector
Matrix(const Vector& vec);
Matrix& operator=(const Vector& vec);
// Resizes a matrix. The contents of the matrix is undefined after
// this operation.
void resize(size_t width, size_t height);
// Retrieves the matrix's size;
size_t rows() const;
size_t cols() const;
// Prints the matrix to standard output
void print() const;
// Gets the element in the given row and column (parens operator)
double operator()(size_t row, size_t col) const;
double& operator()(size_t row, size_t col);
Matrix transpose() const;
// Matrix-Scalar operations
Matrix operator*(double s) const;
Matrix operator/(double s) const;
// Matrix-Vector operations
Matrix operator*(const Vector& v) const;
// Matrix-Matrix operations
Matrix operator+(const Matrix& other) const;
Matrix operator-(const Matrix& other) const;
Matrix operator*(const Matrix& other) const;
private:
double *_data;
size_t _rows, _cols;
};
// Allow scalar multiplication on the left as well as the right.
static inline Matrix
operator*(double left, const Matrix& right)
{
return right * left;
}
} // namespace math
#endif // ! defined __UNIT3_EXAMPLES_MATRIX_H__
#ifndef __UNIT3_EXAMPLES_VECTOR_H__
#define __UNIT3_EXAMPLES_VECTOR_H__
#include <cstdlib>
namespace math {
class Vector
{
public:
// Creates an empty vector
Vector();
// Creates an uninitialized vector with the given length
Vector(size_t len);
// Destructor
~Vector();
// Copies a vector
Vector(const Vector& other);
Vector& operator=(const Vector& other);
// Resizes a vector. The contents of the vector is undefined after
// this operation.
void resize(size_t len);
// Retrieves the length of the vector
size_t length() const;
// Prints the vector to standard output
void print() const;
// Gets the n'th entry of the vector (bracket operator)
double operator[](size_t n) const;
double& operator[](size_t n);
// Computes the 2-norm of the matrix
double norm() const;
// Computes the p-norm of the matrix (Infinity is allowed)
double norm(double p) const;
// Vector-Scalar operations
Vector operator*(double d) const;
Vector operator/(double d) const;
// Vector-Vector operations
Vector operator+(const Vector& other) const;
Vector operator-(const Vector& other) const;
private:
double *_data;
size_t _len;
};
// Allow scalar multiplication on the left as well as the right.
static inline Vector
operator*(double left, const Vector& right)
{
return right * left;
}
} // namespace math
#endif // ! defined __UNIT3_EXAMPLES_VECTOR_H__
#include "matrix.h"
#include <cmath>
#include <cassert>
using namespace math;
Matrix::Matrix()
{
_rows = 0;
_cols = 0;
_data = NULL;
}
Matrix::Matrix(size_t rows, size_t cols)
{
_rows = rows;
_cols = cols;
if (rows * cols == 0) {
_data = NULL;
} else {
_data = new double[rows * cols];
}
}
Matrix::~Matrix()
{
delete[] _data;
}
Matrix::Matrix(const Matrix& other)
{
_rows = other._rows;
_cols = other._cols;
if (_rows * _cols == 0) {
_data = NULL;
} else {
_data = new double[_rows * _cols];
for (size_t i = 0; i < _rows * _cols; ++i)
_data[i] = other._data[i];
}
}
Matrix&
Matrix::operator=(const Matrix& other)
{
resize(other._rows, other._cols);
for (size_t i = 0; i < _rows * _cols; ++i)
_data[i] = other._data[i];
return *this;
}
Matrix::Matrix(const Vector& vec)
{
_cols = 1;
_rows = vec.length();
if (_rows * _cols == 0) {
_data = NULL;
} else {
_data = new double[_rows];
for (size_t i = 0; i < _rows; ++i)
_data[i] = vec[i];
}
}
Matrix&
Matrix::operator=(const Vector& vec)
{
resize(vec.length(), 1);
for (size_t i = 0; i < _rows; ++i)
_data[i] = vec[i];
return *this;
}
void
Matrix::resize(size_t rows, size_t cols)
{
delete[] _data;
_rows = rows;
_cols = cols;
if (rows * cols == 0) {
_data = NULL;
} else {
_data = new double[rows * cols];
}
}
size_t
Matrix::rows() const
{
return _rows;
}
size_t
Matrix::cols() const
{
return _cols;
}
double &
Matrix::operator()(size_t r, size_t c)
{
assert(r < _rows && c < _cols);
return _data[c + r * _cols];
}
double
Matrix::operator()(size_t r, size_t c) const
{
assert(r < _rows && c < _cols);
return _data[c + r * _cols];
}
Matrix
Matrix::operator/(double s) const
{
return (*this) * (1/s);
}
Matrix
Matrix::operator*(const Matrix& B) const
{
assert(cols() == B.rows());
Matrix C(rows(), B.cols());
for (size_t i = 0; i < rows(); ++i) {
for (size_t j = 0; j < B.cols(); ++j) {
C(i, j) = 0;
}
for (size_t k = 0; k < cols(); ++k) {
for (size_t j = 0; j < B.cols(); ++j) {
C(i, j) += (*this)(i, k) * B(k, j);
}
}
}
return C;
}
#include "vector.h"
#include <cassert>
#include <cmath>
using namespace math;
Vector::Vector()
{
_len = 0;
_data = NULL;
}
Vector::Vector(size_t len)
{
_len = len;
if (len == 0) {
_data = NULL;
} else {
_data = new double[len];
}
}
Vector::~Vector()
{
delete[] _data;
}
Vector::Vector(const Vector& other)
{
_len = other._len;
if (_len == 0) {
_data = NULL;
} else {
_data = new double[_len];
for (size_t i = 0; i < _len; ++i)
_data[i] = other._data[i];
}
}
size_t
Vector::length() const
{
return _len;
}
double
Vector::norm() const
{
norm(2);
}
double
Vector::norm(double p) const
{
if (p < 1) {
return NAN;
} else if (p == 1) {
double sum = 0;
for (size_t i = 0; i < _len; ++i) {
sum += abs(_data[i]);
}
return sum;
} else if (p == 2) {
double sum = 0;
for (size_t i = 0; i < _len; ++i) {
sum += _data[i] * _data[i];
}
return sqrt(sum);
} else if (! std::isfinite(p)) {
double max = 0;
for (size_t i = 0; i < _len; ++i) {
if (abs(_data[i]) > max)
max = abs(_data[i]);
}
return max;
} else {
double sum = 0;
for (size_t i = 0; i < _len; ++i) {
sum += pow(_data[i], p);
}
return pow(sum, 1/p);
}
}
Vector
Vector::operator+(const Vector& other) const
{
assert(_len == other._len);
Vector out(_len);
for (size_t i = 0; i < _len; ++i)
out[i] = (*this)[i] + other[i];
}
Vector
Vector::operator-(const Vector& other) const
{
assert(_len == other._len);
Vector out(_len);
for (size_t i = 0; i < _len; ++i)
out[i] = (*this)[i] - other[i];
}