Files
vb01/matrix.cpp
T
2021-10-19 19:06:41 +03:00

201 lines
4.3 KiB
C++

#include"matrix.h"
#include<iostream>
using namespace std;
namespace vb01{
Matrix::Matrix(float **matrix,int rows,int columns){
this->dim[0]=rows;
this->dim[1]=columns;
this->matrix=new float*[rows];
for(int i=0;i<dim[0];i++){
this->matrix[i]=new float[columns];
for(int j=0;j<dim[1];j++)
this->matrix[i][j]=matrix[i][j];
}
}
Matrix::Matrix(Vector3 v1,Vector3 v2,Vector3 v3){
dim[0]=3;
dim[1]=3;
matrix=new float*[3];
matrix[0]=new float[3];
matrix[0][0]=v1.x;
matrix[0][1]=v1.y;
matrix[0][2]=v1.z;
matrix[1]=new float[3];
matrix[1][0]=v2.x;
matrix[1][1]=v2.y;
matrix[1][2]=v2.z;
matrix[2]=new float[3];
matrix[2][0]=v3.x;
matrix[2][1]=v3.y;
matrix[2][2]=v3.z;
}
Matrix& Matrix::operator+(Matrix &m){
if(dim[0]==m.dim[0]&&dim[1]==m.dim[1]){
for(int i=0;i<dim[0];i++)
for(int j=0;j<dim[1];j++)
matrix[i][j]+=m.matrix[i][j];
return *this;
}
else{
cout<<"Incompatible matrix dimensions for addition.\n";
exit(-1);
}
}
Matrix& Matrix::operator-(Matrix &m){
if(dim[0]==m.dim[0]&&dim[1]==m.dim[1]){
for(int i=0;i<dim[0];i++)
for(int j=0;j<dim[1];j++)
matrix[i][j]-=m.matrix[i][j];
return *this;
}
else{
cout<<"Incompatible matrix dimensions for subtraction.\n";
exit(-1);
}
}
Matrix Matrix::operator*(Matrix &m){
if(dim[1]==m.dim[0]){
float **matrix=new float*[dim[0]];
for(int i=0;i<dim[0];i++){
matrix[i]=new float[m.dim[1]];
for(int j=0;j<m.dim[1];j++)
matrix[i][j]=0.;
}
for(int i=0;i<dim[0];i++)
for(int j=0;j<dim[1];j++)
for(int k=0;k<dim[0];k++)
matrix[i][j]+=this->matrix[i][k]*m.matrix[k][j];
return Matrix(matrix,dim[0],dim[1]);
}
else{
cout<<"Incompatible matrix dimensions for multiplication.\n";
exit(-1);
}
}
Vector3 Matrix::operator* (Vector3 v){
float **matrix=new float*[3];
matrix[0]=new float[1];
matrix[0][0]=v.x;
matrix[1]=new float[1];
matrix[1][0]=v.y;
matrix[2]=new float[1];
matrix[2][0]=v.z;
Matrix vMat(matrix,3,1);
vMat=(*this)*vMat;
return Vector3(vMat[0][0],vMat[1][0],vMat[2][0]);
}
template<typename T> Matrix& Matrix::operator+(T s){
for(int i=0;i<dim[0];i++)
for(int j=0;j<dim[1];j++)
matrix[i][j]+=s;
return *this;
}
template<typename T> Matrix& Matrix::operator-(T s){
for(int i=0;i<dim[0];i++)
for(int j=0;j<dim[1];j++)
matrix[i][j]-=s;
return *this;
}
template<typename T> Matrix& Matrix::operator*(T s){
for(int i=0;i<dim[0];i++)
for(int j=0;j<dim[1];j++)
matrix[i][j]*=s;
return *this;
}
template<typename T> Matrix& Matrix::operator/(T s){
for(int i=0;i<dim[0];i++)
for(int j=0;j<dim[1];j++)
matrix[i][j]/=s;
return *this;
}
void Matrix::transpose(){
float **matrix=new float*[dim[1]];
for(int i=0;i<dim[1];i++)
matrix[i]=new float[dim[0]];
for(int i=0;i<dim[0];i++)
for(int j=0;j<dim[1];j++)
matrix[i][j]=this->matrix[j][i];
this->matrix=matrix;
}
Matrix Matrix::getSubMatrix(int row,int column){
int newRows=dim[0]-1,newColumns=dim[1]-1;
float **matrix=new float*[dim[0]];
bool offsetRows=false,offsetColumns=false;
for(int i=0;i<dim[1];i++){
matrix[i]=new float[dim[1]];
for(int j=0;j<dim[1];j++)
if(i!=row&&j!=column){
int a=offsetRows&&i!=0?i-1:i,b=offsetColumns&&j!=0?j-1:j;
matrix[a][b]=this->matrix[i][j];
}
else if(i==row) offsetRows=true;
else if(j==column) offsetColumns=true;
}
return Matrix(matrix,newRows,newColumns);
}
void Matrix::invert(){
transpose();
float **matrix=new float*[dim[0]];
for(int i=0;i<dim[0];i++){
matrix[i]=new float[dim[1]];
for(int j=0;j<dim[1];j++)
matrix[i][j]=getCofactor(i,j);
}
for(int i=0;i<dim[0];i++)
delete this->matrix[i];
delete[] this->matrix;
this->matrix=matrix;
*this/getDeterminant();
}
float Matrix::getMinor(int row,int column){
return getSubMatrix(row,column).getDeterminant();
}
float Matrix::getCofactor(int row,int column){
return ((row+column+2)%2==0?1:-1)*getMinor(row,column);
}
float Matrix::getDeterminant(){
if(dim[0]!=dim[1]){
cout<<"Matrix not square.\n";
exit(-1);
}
if(dim[0]==1)
return matrix[0][0];
else if(dim[0]==2)
return matrix[0][0]*matrix[1][1]-matrix[1][0]*matrix[0][1];
else{
float det=0;
for(int i=0;i<dim[0];i++)
det+=matrix[i][0]*getCofactor(i,0);
return det;
}
}
}