2022-03-12 04:31:50 +00:00
|
|
|
|
/*
|
|
|
|
|
* @Author: iR
|
|
|
|
|
* @Date: 2022-03-11 16:44:46
|
|
|
|
|
* @LastEditors: iR
|
2022-03-12 06:49:02 +00:00
|
|
|
|
* @LastEditTime: 2022-03-12 14:45:22
|
2022-03-12 04:31:50 +00:00
|
|
|
|
* @FilePath: \Code\inc\matrix.hpp
|
|
|
|
|
* @Description:
|
|
|
|
|
*
|
|
|
|
|
* Copyright (c) 2022 by iR, All Rights Reserved.
|
|
|
|
|
*/
|
2022-03-11 12:27:54 +00:00
|
|
|
|
#ifndef _MATRIX_HPP_
|
|
|
|
|
#define _MATRIX_HPP_
|
|
|
|
|
|
2022-03-12 04:31:50 +00:00
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
2022-03-11 12:27:54 +00:00
|
|
|
|
#include "../inc/vector.hpp"
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
class Matrix
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
int _height;
|
|
|
|
|
int _width;
|
|
|
|
|
Vector<T> *_mat;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
public:
|
2022-03-12 06:49:02 +00:00
|
|
|
|
~Matrix()
|
|
|
|
|
{
|
|
|
|
|
delete[] _mat;
|
|
|
|
|
}
|
2022-03-12 04:31:50 +00:00
|
|
|
|
/**
|
|
|
|
|
* @description: 极度缺省初始化, 大小为2*2, 初值为0
|
|
|
|
|
* @param {int} w
|
|
|
|
|
* @param {int} h
|
|
|
|
|
*/
|
|
|
|
|
Matrix();
|
|
|
|
|
/**
|
|
|
|
|
* @description: 缺省初始化,初值为0
|
|
|
|
|
* @param {int} w
|
|
|
|
|
* @param {int} h
|
|
|
|
|
*/
|
2022-03-11 12:27:54 +00:00
|
|
|
|
Matrix(int w, int h);
|
2022-03-12 04:31:50 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @description: 以相同值初始化矩阵元素
|
|
|
|
|
* @param {int} w
|
|
|
|
|
* @param {int} h
|
|
|
|
|
* @param {T} init_value
|
|
|
|
|
*/
|
2022-03-11 12:27:54 +00:00
|
|
|
|
Matrix(int w, int h, T init_value);
|
2022-03-12 04:31:50 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @description: 以顺序访问数组的值初始化矩阵元素
|
2022-03-12 06:49:02 +00:00
|
|
|
|
* 必须给出正确的数组,因为在函数内无法判定数组是否正确
|
2022-03-12 04:31:50 +00:00
|
|
|
|
* @param {int} w
|
|
|
|
|
* @param {int} h
|
|
|
|
|
* @param {const T} elements[]
|
|
|
|
|
*/
|
|
|
|
|
Matrix(int w, int h, const T elements[]);
|
|
|
|
|
|
2022-03-12 06:49:02 +00:00
|
|
|
|
/**
|
|
|
|
|
* @description: 以顺序访问指针的值初始化矩阵元素
|
|
|
|
|
* @note: 必须给出正确的数组,因为在函数内无法判定数组是否正确
|
|
|
|
|
* @param {int} w
|
|
|
|
|
* @param {int} h
|
|
|
|
|
* @param {T*} data
|
|
|
|
|
*/
|
|
|
|
|
Matrix(int w, int h, T *data);
|
|
|
|
|
|
2022-03-12 04:31:50 +00:00
|
|
|
|
/**
|
|
|
|
|
* @description: 以另一个矩阵初始化当前矩阵的元素,实际是元素拷贝
|
|
|
|
|
* @param {Matrix} &another
|
|
|
|
|
*/
|
2022-03-11 12:27:54 +00:00
|
|
|
|
Matrix(const Matrix &another);
|
2022-03-12 04:31:50 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @description: 只读访问内容
|
|
|
|
|
* @param {int} w
|
|
|
|
|
* @param {int} h
|
|
|
|
|
* @return {*}
|
|
|
|
|
*/
|
2022-03-11 12:27:54 +00:00
|
|
|
|
const T get(int w, int h) const;
|
2022-03-12 04:31:50 +00:00
|
|
|
|
|
|
|
|
|
/**
|
2022-03-12 06:14:15 +00:00
|
|
|
|
* @description: []运算符重载
|
2022-03-12 04:31:50 +00:00
|
|
|
|
*/
|
|
|
|
|
const T operator[](int i) const { return _mat->get(i); }
|
|
|
|
|
|
|
|
|
|
/**
|
2022-03-12 06:14:15 +00:00
|
|
|
|
* @description: =运算符重载
|
2022-03-12 04:31:50 +00:00
|
|
|
|
*/
|
|
|
|
|
T operator=(const Matrix &b);
|
|
|
|
|
|
2022-03-12 06:14:15 +00:00
|
|
|
|
/**
|
|
|
|
|
* @description: +=运算符重载
|
|
|
|
|
* @note: 即 a += b,其中*this即为a
|
|
|
|
|
* @param {*}
|
|
|
|
|
* @return None
|
|
|
|
|
*/
|
|
|
|
|
void operator+=(const Matrix &b);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @description: +=运算符重载
|
|
|
|
|
* @note:即 c = a + b,其中*this即为a,返回值即为c
|
|
|
|
|
* @param {*}
|
|
|
|
|
* @return None
|
|
|
|
|
*/
|
|
|
|
|
Matrix operator+(const Matrix &b) const;
|
|
|
|
|
|
2022-03-12 04:31:50 +00:00
|
|
|
|
/**
|
|
|
|
|
* @description: 可读可写访问
|
|
|
|
|
* @param {int} w
|
|
|
|
|
* @param {int} h
|
|
|
|
|
* @return {*}
|
|
|
|
|
*/
|
2022-03-12 04:50:04 +00:00
|
|
|
|
T &at(int w, int h)
|
|
|
|
|
{
|
|
|
|
|
double &ref = _mat->get(h * _width + w);
|
|
|
|
|
return ref;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @description: 只读引用访问
|
|
|
|
|
* @param {int} w
|
|
|
|
|
* @param {int} h
|
|
|
|
|
* @return {*}
|
|
|
|
|
*/
|
|
|
|
|
const T &at(int w, int h) const
|
|
|
|
|
{
|
|
|
|
|
double &ref = _mat->get(h * _width + w);
|
|
|
|
|
return ref;
|
|
|
|
|
}
|
2022-03-12 04:31:50 +00:00
|
|
|
|
|
|
|
|
|
const int getWidth() const { return _width; }
|
|
|
|
|
const int getHeight() const { return _height; }
|
2022-03-11 12:27:54 +00:00
|
|
|
|
};
|
|
|
|
|
|
2022-03-12 04:31:50 +00:00
|
|
|
|
template <class T>
|
|
|
|
|
Matrix<T>::Matrix()
|
|
|
|
|
{
|
|
|
|
|
_width = 2;
|
|
|
|
|
_height = 2;
|
|
|
|
|
_mat = new Vector<T>(2 * 2, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-11 12:27:54 +00:00
|
|
|
|
template <class T>
|
|
|
|
|
Matrix<T>::Matrix(int w, int h)
|
|
|
|
|
{
|
|
|
|
|
_width = w;
|
|
|
|
|
_height = h;
|
2022-03-12 04:31:50 +00:00
|
|
|
|
_mat = new Vector<T>(w * h, 0);
|
2022-03-11 12:27:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
Matrix<T>::Matrix(int w, int h, T init_value)
|
|
|
|
|
{
|
|
|
|
|
_width = w;
|
|
|
|
|
_height = h;
|
|
|
|
|
_mat = new Vector<T>(w * h, init_value);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-12 04:31:50 +00:00
|
|
|
|
template <class T>
|
|
|
|
|
Matrix<T>::Matrix(int w, int h, const T elements[])
|
|
|
|
|
{
|
|
|
|
|
int size = w * h;
|
|
|
|
|
try
|
|
|
|
|
{
|
2022-03-12 06:14:15 +00:00
|
|
|
|
//实际上似乎并不能在这里判断数组是否合法
|
2022-03-12 04:31:50 +00:00
|
|
|
|
// if (w * h > size)
|
|
|
|
|
// throw "Error: The number of array elements is less than the matrix elements.\n";
|
|
|
|
|
// if (w * h < size)
|
|
|
|
|
// throw "Error: The number of array elements is greater than the matrix elements.\n";
|
|
|
|
|
|
|
|
|
|
_width = w;
|
|
|
|
|
_height = h;
|
|
|
|
|
_mat = new Vector<T>;
|
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
|
_mat->put(i, elements[i]);
|
|
|
|
|
}
|
|
|
|
|
catch (const char *msg)
|
|
|
|
|
{
|
|
|
|
|
std::cout << msg << "SIZE:" << size << std::endl;
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-12 06:49:02 +00:00
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
Matrix<T>::Matrix(int w, int h, T *data)
|
|
|
|
|
{
|
|
|
|
|
int size = w * h;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//实际上似乎并不能在这里判断数组是否合法
|
|
|
|
|
// if (w * h > size)
|
|
|
|
|
// throw "Error: The number of array elements is less than the matrix elements.\n";
|
|
|
|
|
// if (w * h < size)
|
|
|
|
|
// throw "Error: The number of array elements is greater than the matrix elements.\n";
|
|
|
|
|
if (data == NULL)
|
|
|
|
|
throw 1;
|
|
|
|
|
_width = w;
|
|
|
|
|
_height = h;
|
|
|
|
|
T temp;
|
|
|
|
|
_mat = new Vector<T>;
|
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
|
_mat->put(i, *(data+sizeof(temp)*i));
|
|
|
|
|
}
|
|
|
|
|
catch (const int a)
|
|
|
|
|
{
|
|
|
|
|
if (a == 1)
|
|
|
|
|
{
|
|
|
|
|
std::cout << "Error: Empty array. Set elements to 0." << std::endl;
|
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
|
_mat->put(i, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-12 04:31:50 +00:00
|
|
|
|
template <class T>
|
|
|
|
|
Matrix<T>::Matrix(const Matrix &another)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
_width = another.getWidth();
|
|
|
|
|
_height = another.getHeight();
|
|
|
|
|
_mat = new Vector<T>;
|
|
|
|
|
for (int i = 0; i < _width * _height; i++)
|
|
|
|
|
_mat->put(i, another[i]);
|
|
|
|
|
}
|
|
|
|
|
catch (const char *msg)
|
|
|
|
|
{
|
|
|
|
|
std::cout << msg;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
T Matrix<T>::operator=(const Matrix &another)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
_width = another.getWidth();
|
|
|
|
|
_height = another.getHeight();
|
|
|
|
|
_mat = new Vector<T>;
|
|
|
|
|
for (int i = 0; i < _width * _height; i++)
|
|
|
|
|
_mat->put(i, another[i]);
|
|
|
|
|
}
|
|
|
|
|
catch (const char *msg)
|
|
|
|
|
{
|
|
|
|
|
std::cout << msg;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-11 12:27:54 +00:00
|
|
|
|
template <class T>
|
|
|
|
|
const T Matrix<T>::get(int w, int h) const
|
|
|
|
|
{
|
2022-03-12 06:14:15 +00:00
|
|
|
|
return _mat->get(h * _width + w);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
void Matrix<T>::operator+=(const Matrix &b)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (this->_height == b.getHeight() && this->_width == b.getWidth())
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < _width * _height; i++)
|
|
|
|
|
this->_mat->put(i, (*this)[i] + b[i]);
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
throw "Error: Different size.";
|
|
|
|
|
}
|
|
|
|
|
catch (const char *msg)
|
|
|
|
|
{
|
|
|
|
|
std::cout << msg;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @description: +=运算符重载
|
|
|
|
|
* @note:即 c = a + b,其中*this即为a,返回值即为c
|
|
|
|
|
* @param {*}
|
|
|
|
|
* @return None
|
|
|
|
|
*/
|
|
|
|
|
template <class T>
|
|
|
|
|
Matrix<T> Matrix<T>::operator+(const Matrix &b) const
|
|
|
|
|
{
|
|
|
|
|
int h = this->_height;
|
|
|
|
|
int w = this->_width;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (h == b.getHeight() && w == b.getWidth())
|
|
|
|
|
{
|
|
|
|
|
Matrix<T> temp(w, h, T(0));
|
|
|
|
|
temp += *this;
|
|
|
|
|
temp += b;
|
|
|
|
|
return temp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw "Error: Different size.";
|
|
|
|
|
}
|
|
|
|
|
catch (const char *msg)
|
|
|
|
|
{
|
|
|
|
|
std::cout << msg;
|
|
|
|
|
Matrix<T> temp(w, h, T(0));
|
|
|
|
|
return temp;
|
|
|
|
|
}
|
2022-03-11 12:27:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|