This repository has been archived on 2024-01-06. You can view files and clone it, but cannot push or open issues or pull requests.
justhomework/SoftwareDesign/Lab1/inc/matrix.hpp

322 lines
7.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @Author: iR
* @Date: 2022-03-11 16:44:46
* @LastEditors: iR
* @LastEditTime: 2022-03-15 17:02:42
* @FilePath: \Code\inc\matrix.hpp
* @Description:
*
* Copyright (c) 2022 by iR, All Rights Reserved.
*/
#ifndef _MATRIX_HPP_
#define _MATRIX_HPP_
#include <iostream>
#include <stdio.h>
#include "../inc/vector.hpp"
template <class T>
class MatBase
{ // 定义基类,其中包含了矩阵元素读取的纯虚函数
public:
virtual T &at(int y, int x) = 0; // 定义纯虚函数
virtual const T &at(int y, int x) const = 0; // 定义纯虚函数
};
template <class T>
class Matrix : public MatBase<T>
{
private:
int _height;
int _width;
Vector<T> *_mat;
protected:
public:
~Matrix()
{
delete _mat;
}
/**
* @description: 极度缺省初始化, 大小为2*2, 初值为0
* @param {int} w
* @param {int} h
*/
Matrix();
/**
* @description: 缺省初始化初值为0
* @param {int} w
* @param {int} h
*/
Matrix(int w, int h);
/**
* @description: 以相同值初始化矩阵元素
* @param {int} w
* @param {int} h
* @param {T} init_value
*/
Matrix(int w, int h, T init_value);
/**
* @description: 以顺序访问数组的值初始化矩阵元素
* 必须给出正确的数组,因为在函数内无法判定数组是否正确
* @param {int} w
* @param {int} h
* @param {const T} elements[]
*/
Matrix(int w, int h, const T elements[]);
// /**
// * @description: 以顺序访问指针的值初始化矩阵元素
// * @note: 必须给出正确的数组,因为在函数内无法判定数组是否正确
// * @param {int} w
// * @param {int} h
// * @param {T*} data
// */
// Matrix(int w, int h, T *data);
/**
* @description: 以另一个矩阵初始化当前矩阵的元素,实际是元素拷贝
* @param {Matrix} &another
*/
Matrix(const Matrix &another);
/**
* @description: 只读访问内容
* @param {int} w
* @param {int} h
* @return {*}
*/
const T get(int w, int h) const;
/**
* @description: []运算符重载
*/
const T operator[](int i) const { return _mat->get(i); }
/**
* @description: =运算符重载
*/
void operator=(const Matrix &b);
/**
* @description: +=运算符重载
* @note: 即 a += b其中*this即为a
* @param {*}
* @return None
*/
void operator+=(const Matrix &b);
void operator+=(T &a)
{
for (int i = 0; i < _width * _height;i++)
{
_mat[i] = a;
}
}
/**
* @description: +=运算符重载
* @note:即 c = a + b其中*this即为a返回值即为c
* @param {*}
* @return None
*/
Matrix operator+(const Matrix &b) const;
/**
* @description: 可读可写访问
* @param {int} w
* @param {int} h
* @return {*}
*/
T &at(int w, int h)
{
T &ref = _mat->get(h * _width + w);
return ref;
}
/**
* @description: 只读引用访问
* @param {int} w
* @param {int} h
* @return {*}
*/
const T &at(int w, int h) const
{
T &ref = _mat->get(h * _width + w);
return ref;
}
const int getWidth() const { return _width; }
const int getHeight() const { return _height; }
};
template <class T>
Matrix<T>::Matrix()
{
_width = 2;
_height = 2;
_mat = new Vector<T>(2 * 2, 0);
}
template <class T>
Matrix<T>::Matrix(int w, int h)
{
_width = w;
_height = h;
_mat = new Vector<T>(w * h, 0);
}
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);
}
template <class T>
Matrix<T>::Matrix(int w, int h, const T elements[])
{
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";
_width = w;
_height = h;
_mat = new Vector<T>(w * h);
for (int i = 0; i < size; i++)
_mat->put(i, elements[i]);
}
catch (const char *msg)
{
std::cout << msg << "SIZE:" << size << std::endl;
;
}
}
//这个方法似乎有问题
// 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;
// _mat = new Vector<T>;
// for (int i = 0; i < size; i++)
// _mat->put(i, *(data+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);
// }
// }
// }
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>
void 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;
}
}
template <class T>
const T Matrix<T>::get(int w, int h) const
{
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;
}
}
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;
}
}
#endif