Cubli library

Matrix/Matrix.cpp

Committer:
fbob
Date:
2019-02-13
Revision:
1:085840a3d767
Parent:
0:431ee55036ca
Child:
2:dc7840a67f77

File content as of revision 1:085840a3d767:

#include "Matrix.h"

Matrix::Matrix() : _rows(1), _cols(1)
{
    // Allocate memory
    _data = (float **)malloc(sizeof(float *));
    _data[0] = (float *)malloc(sizeof(float));
    // Initialize values
    _data[0][0] = 0.0;
}

Matrix::Matrix(int rows, int cols) : _rows(rows), _cols(cols)
{

    // Allocate memory
    _data = (float **)malloc(_rows * sizeof(float *)); // = new float*[_rows];
    for (int i = 1; i <= _rows; i++) {
        _data[i-1] = (float *)malloc(_cols * sizeof(float)); // = new float[_cols];
    }
    // Initialize values
    for (int i = 1; i <= _rows; i++) {
        for (int j = 1; j <= _cols; j++) {
            _data[i-1][j-1] = 0.0;
        }
    }
}

Matrix::~Matrix()
{
    // Free memory
    for (int i = 1; i <= _rows; i++) {
        free(_data[i-1]);
    }
    free(_data);
}

Matrix& Matrix::operator=(const Matrix& m)
{
    for (int i = 1; i <= _rows; i++) {
        for (int j = 1; j <= _cols; j++) {
            _data[i-1][j-1] = m._data[i-1][j-1];
        }
    }
    return *this;
}

float& Matrix::operator()(int row, int col)
{
    // Return cell data
    return _data[row-1][col-1];
}

Matrix operator+(const Matrix& A, const Matrix& B)
{
    /*// Auxiliary matrix where C = A+B
    Matrix C(A._rows,A._cols);
    for (int i = 1; i <= A._rows; i++)
    {
      for (int j = 1; j <= A._cols; j++)
      {
          C._data[i-1][j-1] += A._data[i-1][j-1]+B._data[i-1][j-1];
      }
    }
    return C;
    */
    
    /*Matrix temp(m1);
    return (temp += m2);
    */
    
    //Matrix A(m1);
    //Matrix B(m2);
    Matrix C(A._rows,A._cols);
    for (int i = 1; i <= A._rows; i++)
    {
      for (int j = 1; j <= A._cols; j++)
      {
          C._data[i-1][j-1] += A._data[i-1][j-1]+B._data[i-1][j-1];
      }
    }
    return C;
}

Matrix operator-(const Matrix& A, const Matrix& B)
{
    // Auxiliary matrix where C = A-B
    Matrix C(A._rows,A._cols);
    for (int i = 1; i <= A._rows; i++) {
        for (int j = 1; j <= A._cols; j++) {
            C._data[i-1][j-1] += A._data[i-1][j-1]-B._data[i-1][j-1];
        }
    }
    return C;
}

Matrix operator*(const Matrix& A, const Matrix& B)
{
    // Auxiliary matrix where C = A*B
    Matrix C(A._rows,B._cols);
    for (int i = 1; i <= A._rows; i++) {
        for (int j = 1; j <= B._cols; j++) {
            for (int k = 1; k <= A._cols; k++) {
                C._data[i-1][j-1] += A._data[i-1][k-1]*B._data[k-1][j-1];
            }
        }
    }
    return C;
}

Matrix operator*(float scalar, const Matrix& A)
{
    // Auxiliary matrix where C = scalar*A
    Matrix C(A._rows,A._cols);
    for (int i = 1; i <= A._rows; i++) {
        for (int j = 1; j <= A._cols; j++) {
            C._data[i-1][j-1] += scalar*A._data[i-1][j-1];
        }
    }
    return C;
}

Matrix operator*(const Matrix& A, float scalar)
{
    // Auxiliary matrix where C = scalar*A
    Matrix C(A._rows,A._cols);
    for (int i = 1; i <= A._rows; i++) {
        for (int j = 1; j <= A._cols; j++) {
            C._data[i-1][j-1] += A._data[i-1][j-1]*scalar;
        }
    }
    return C;
}

Matrix operator/(const Matrix& A, float scalar)
{
    // Auxiliary matrix where C = scalar*A
    Matrix C(A._rows,A._cols);
    for (int i = 1; i <= A._rows; i++) {
        for (int j = 1; j <= A._cols; j++) {
            C._data[i-1][j-1] += A._data[i-1][j-1]/scalar;
        }
    }
    return C;
}

Matrix transpose(const Matrix& A)
{
    // Auxiliary matrix where C = A'
    Matrix C(A._cols, A._rows);
    for (int i = 1; i <= C._rows; i++) {
        for (int j = 1; j <= C._cols; j++) {
            C._data[i-1][j-1] = A._data[j-1][i-1];
        }
    }
    return C;
}

Matrix inverse(const Matrix& A)
{
    // Apply A = LDL' factorization where L is a lower triangular matrix and D
    // is a block diagonal matrix
    Matrix L(A._cols, A._rows);
    Matrix D(A._cols, A._rows);
    float L_sum;
    float D_sum;
    for (int i = 1; i <= A._rows; i++) {
        for (int j = 1; j <= A._rows; j++) {
            if (i >= j) {
                if (i == j) {
                    L._data[i-1][j-1] = 1.0;
                    D_sum = 0.0;
                    for (int k = 1; k <= (i-1); k++) {
                        D_sum += L._data[i-1][k-1]*L._data[i-1][k-1]*D._data[k-1][k-1];
                    }
                    D._data[i-1][j-1] = A._data[i-1][j-1] - D_sum;
                } else {
                    L_sum = 0.0;
                    for (int k = 1; k <= (j-1); k++) {
                        L_sum += L._data[i-1][k-1]*L._data[j-1][k-1]*D._data[k-1][k-1];
                    }
                    L._data[i-1][j-1] = (1.0/D._data[j-1][j-1])*(A._data[i-1][j-1]-L_sum);
                }
            }
        }
    }
    // Compute the inverse of L and D matrices
    Matrix L_inv(A._cols, A._rows);
    Matrix D_inv(A._cols, A._rows);
    float L_inv_sum;
    for (int i = 1; i <= A._rows; i++) {
        for (int j = 1; j <= A._rows; j++) {
            if (i >= j) {
                if (i == j) {
                    L_inv._data[i-1][j-1] = 1.0/L._data[i-1][j-1];
                    D_inv._data[i-1][j-1] = 1.0/D._data[i-1][j-1];
                } else {
                    L_inv_sum = 0.0;
                    for (int k = j; k <= (i-1); k++) {
                        L_inv_sum += L._data[i-1][k-1]*L_inv._data[k-1][j-1];
                    }
                    L_inv._data[i-1][j-1] = -L_inv_sum;
                }
            }
        }
    }
    // Compute the inverse of A matrix in terms of the inverse of L and D
    // matrices
    return transpose(L_inv)*D_inv*L_inv;
}

float norm(const Matrix& A)
{
    // Auxiliary matrix where C = A'
    float n;
    n = 0.0;
    for (int i = 1; i <= A._rows; i++) {
        n += A._data[i-1][0]*A._data[i-1][0];
        }
    return sqrt(n);
}