C++ 在C+中实现三维矩阵+;使用嵌套的std::vector

C++ 在C+中实现三维矩阵+;使用嵌套的std::vector,c++,c++11,matrix,C++,C++11,Matrix,我有一个包含MxNxL元素的3D矩阵。M和N在编译时都是已知的。然而,L是可变的,取决于用户的输入。但它将在项目开始时提供,并且在项目生命周期内不会改变。我想在C++11中实现这个矩阵,我想让用户能够灵活地沿矩阵的第一维和第二维旋转3D矩阵 我想知道实现该矩阵的最佳和最有效的设计方案是什么 我已经看到了下面使用std::vector的解决方案。使用std::vector用户可以使用std::rotate旋转任何维度。解决方案就是从这个角度出发的。但是,提到使用嵌套向量不好,而是使其线性化。但由于

我有一个包含MxNxL元素的3D矩阵。M和N在编译时都是已知的。然而,L是可变的,取决于用户的输入。但它将在项目开始时提供,并且在项目生命周期内不会改变。我想在C++11中实现这个矩阵,我想让用户能够灵活地沿矩阵的第一维和第二维旋转3D矩阵

我想知道实现该矩阵的最佳和最有效的设计方案是什么

我已经看到了下面使用
std::vector
的解决方案。使用
std::vector
用户可以使用
std::rotate
旋转任何维度。解决方案就是从这个角度出发的。但是,提到使用嵌套向量不好,而是使其线性化。但由于我有跨维旋转的要求,使用线性阵列将使处理变得困难

#include <vector>

#define M_SIZE 360
#define N_SIZE 180 

template<typename T>
using vec = std::vector<T>;

int main()
{
    uint16_t L;
    std::cin << L;
    vec<vec<vec<double>>> v{M_SIZE, vec<vec<double>>{N_SIZE, vec<double>{L}}};
}
#包括
#定义M_尺寸360
#定义N_尺寸180
样板
使用vec=std::vector;
int main()
{
uint16_t L;

STD::CIN < P>我不知道这是否会帮助你实现你所追求的,但是这是一个我已经开始使用现代C++特性构建的矩阵类,比如<代码>变量模板。矩阵类是自包含在单个头文件中的。

#ifndef MATRIX_H
#define MATRIX_H

#include <cstddef>  // std::size_t
#include <numeric>  // std::accumulate
#include <vector>

namespace /*Your namespace name here*/ {

template<typename Type, std::size_t... Dims>
class Matrix {
public:
    static const std::size_t numDims_ = sizeof...(Dims);

private:
    std::size_t numElements_;

    std::vector<Type> elements_;
    std::vector<std::size_t> strides_;

public:
    Matrix() noexcept;

    template<typename... Args>
    Matrix(Args&&... args) noexcept;

    const Type& operator[](std::size_t idx) const;

    std::size_t numElements() const { return elements_.size(); }

    const std::vector<std::size_t>& strides() const { return strides_; }
    const std::vector<Type>& elements() const { return elements_; }
};

template<typename Type, std::size_t... Dims>
Matrix<Type, Dims...>::Matrix() noexcept :
    strides_({ Dims... }) {
    using std::begin;
    using std::end;
    auto mult = std::accumulate(begin(strides_), end(strides_), 1, std::multiplies<>());
    numElements_ = mult;
    elements_.resize(numElements_);
}

template<typename Type, std::size_t... Dims>
template<typename... Args>
Matrix<Type, Dims...>::Matrix(Args&&... args) noexcept :
    elements_({ args... }),
    strides_({ Dims... }) {
    numElements_ = elements_.size();
}

template<typename T, std::size_t... d>
const T& Matrix<T, d...>::operator[](std::size_t idx) const {
    if (idx > numElements_)
        throw std::runtime_error("Invalid index");
    return elements_[idx];
}

} // Your namespace name here
#endif MATRIX_H

该类远未完成,因为它只是任何MxNx…Zx…矩阵的任意尺寸的包含外壳。在模板参数列表中,它需要单个
类型
int
float
char
用户定义的
等。tempale参数的可变参数
类型
确定此矩阵有多少维度,以及每个维度的维度大小。示例:

Matrix<type,1> = a 1 matrix which in essence would be a scalar
Matrix<type,1,2> = a 1x2 matrix and would be considered a vector
Matrix<type,3,1> = a 3x1 matrix and would be considered a vector
Matrix<type,2,2> = a 2x2 matrix
Matrix<type,3,4> = a 3x4 matrix
Matrix<type,3,3,3> = a 3x3x3 Matrix (3D-Matrix) and has 27 elements
Matrix<type,3,4,5,3,2> = a 3x4x5x3x2 (5D - Matrix) and has 360 elements

// The number of elements will always equal the product of all of the strides.
// When creating an arbitrary matrix size; careful consideration needs to be taken
// when it comes to how many dimensions and the size of that dimension. Even lower
// dimensional matrices can explode in the amount of elements...
Matrix<type, 128, 356, 242> = a 128x356x242 (3D - Matrix) but has 11,027,456 elements

// It is the Matrix's user defined variadic constructor that the number of arguments 
// in the parameter list that has to equal the total amount of elements defined by 
// the product of all of its strides.
Matrix=本质上是标量的1矩阵
矩阵=1x2矩阵,将被视为向量
矩阵=一个3x1矩阵,将被视为一个向量
矩阵=2x2矩阵
矩阵=一个3x4矩阵
矩阵=一个3x3x3矩阵(3D矩阵),有27个元素
矩阵=一个3x4x3x2(5D-矩阵),有360个元素
//元素的数量总是等于所有跨步的乘积。
//创建任意矩阵大小时,需要仔细考虑
//当涉及到多少维度和维度的大小时,甚至更低
//维度矩阵可以在元素数量上爆炸。。。
矩阵=一个128x356x242(3D矩阵),但有11027456个元素
//参数的数量取决于矩阵的用户定义变量构造函数
//在参数列表中,必须等于定义的元素总数
//它的所有进步的产物。
当使用高维矩阵时,很难将其可视化,但是可以使用
跨步
向量轻松地管理它们。我们可以使用它们进行适当的索引


这种设计方法的挑战在于能够实现实际的算术运算。因此,如果我们有两个不同的矩阵,它们具有不同的步长,它们将被视为不同的类型……这只是简单的矩阵运算;当涉及到矩阵乘法时,事情会变得更加困难因为矩阵A和矩阵B的边必须具有相同的大小。例如:4x2*2x3将给出一个4x3矩阵。这只是一个2D矩阵问题,当进入3D、4D、…ND矩阵时,表示法更加困难。然而,这种模板方法确实允许代码更通用、可读性更强,可以像op一样自包含到单个类中假设有许多不同的矩阵类用于不同的矩阵大小…

好吧,您希望有什么,更快的执行速度,还是稍长一点的开发时间?不要使用带有3D索引的1D向量。@NathanOliver,因为此操作在程序生命周期内只会发生一次,所以可以减少一些时间。我更喜欢灵活性nd代码维护的可读性。特别是,我稍后将使用此矩阵与向量相乘。当前的设计选择是避免使用外部库,因为有很多线性代数框架可以实现我想要的功能,甚至boost库也可以实现。您可以查看
GLM
的数学库设计用于执行与
OpenGL
GLSL
着色器语言非常相似的线性代数。该库本身是一个仅包含标题的全包库。不涉及任何链接,您只需将标题包含到项目解决方案中,并使用适当的标题开始使用它。它包含所有需要的内容用于进行仿射变换、矩阵和向量计算的ed函数。您可以阅读它们的头文件,查看它们如何实现其矩阵和向量类以及函数…续…但是这可能与您的要求略有不同,因为大多数
GLM
的矩阵都是
MxN
变量但是可以作为一个很好的起点的参考。你只需要将它扩展到3D。
 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7
 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7
 Number of strides: 3
 2 2 2
Matrix<type,1> = a 1 matrix which in essence would be a scalar
Matrix<type,1,2> = a 1x2 matrix and would be considered a vector
Matrix<type,3,1> = a 3x1 matrix and would be considered a vector
Matrix<type,2,2> = a 2x2 matrix
Matrix<type,3,4> = a 3x4 matrix
Matrix<type,3,3,3> = a 3x3x3 Matrix (3D-Matrix) and has 27 elements
Matrix<type,3,4,5,3,2> = a 3x4x5x3x2 (5D - Matrix) and has 360 elements

// The number of elements will always equal the product of all of the strides.
// When creating an arbitrary matrix size; careful consideration needs to be taken
// when it comes to how many dimensions and the size of that dimension. Even lower
// dimensional matrices can explode in the amount of elements...
Matrix<type, 128, 356, 242> = a 128x356x242 (3D - Matrix) but has 11,027,456 elements

// It is the Matrix's user defined variadic constructor that the number of arguments 
// in the parameter list that has to equal the total amount of elements defined by 
// the product of all of its strides.