从头编写矩阵运算库 Numcpp

opencv 的 Mat 不支持不连续的 indexing, slicing,也不支持 broadcasting,且其对高维矩阵的支持也十分不完善。在网上并未找到十分满意的线性代数库,于是打算自己从头写一个,并希望能与 opencv 的 Mat 完全兼容。

Python 的 Numpy 包对矩阵运算的支持十分优秀,使用起来也很便捷,打算参考 Numpy 写一个 C++ 版的 Numcpp,基本的对象是 Array 类型。

快速原型

不考虑复杂功能,也不考虑性能优化,先快速实现一个具有基本功能的 Array。基本功能包括:矩阵的构造与删除,和加减乘除基本运算。

我们先来看看需求,再逐步实现。

Array 初始化

希望用户可以以简单的方式初始化一个矩阵,比如:

1
Array a(2, 2, NP_FLOAT)

这种方式很简洁。但是,当定义高维矩阵(三维、四维……)时,这种初始化方式不容易实现。所以我们参考 numpy,把尺寸打包到一个 Tuple 对象里传入给 Array:

1
2
3
Array a(Tuple(2, 2))
Array b(Tuple(10))
Array c(Tuple(3, 4, 5))

或者更简单地缩写为:

1
Array a(_t(2, 2))

定义预定义的矩阵:

1
Array a = zeros(_t(2, 3, 4))

这里假设基本数据类型默认为 float 类型。

Array 基本运算

参考 numpy,我们定义的矩阵之间的 +, -, *, / 运算均为点对点运算(element-to-element),比如:

1
d = (a * b - c) / c

为了判断运算是否合法,我们需要判断两个矩阵的形状是否一致:

1
2
3
4
5
if (a.shape != b.shape) {
cout << "error: the shape of a and b is not consistent!" << endl;
} else {
c = a * b;
}

Array 定义(Array.h)

参考以上需求,我们定义 Tuple 与 Array 类的结构如下:

1
2
3
4
5
6
7
8
9
class Tuple {
}
class Array {
public:
Array();
Array(int rows, int cols, )
};