模板矩阵类中的矩阵行列式实现

时间:2018-11-18 21:54:44

标签: c++ c++11 templates matrix determinants

我正在做一个项目,需要我编写自己的矩阵类实现。我决定将矩阵类实现为模板,以通过以下方式提供编译时错误检查:

template<size_t N, size_t M> // N × M matrix
class Matrix
{
    // implementation...
};

我设法实现了基本操作,例如加/减,转置和乘法。但是,我在实现行列式时遇到了麻烦。我正在考虑使用Laplace expansion递归实现它,因此我必须首先实现一种计算矩阵的i,j minor的方法。问题是,N×N矩阵的次要矩阵是(N-1)×(N-1)矩阵。以下内容无法编译:(错误消息为Error C2059 syntax error: '<',指向函数的第一行)

template<size_t N>
Matrix<N-1, N-1> Minor(const Matrix<N, N>& mat, size_t i, size_t j)
{
    Matrix<N-1, N-1> minor;
    // calculate i,j minor
    return minor
}

在保留类的模板形式的同时,如何解决这个问题并计算未成年人?

编辑:我被要求提供一个可行的例子。这是我代码的相关部分,我试图将其保持在最小限度。我的Matrix类使用Vector类,我也自己写过。我删除了所有无关的代码,并将所有错误检查都更改为asserts,因为实际的代码抛出了异常类,该异常类也是由我编写的。

这是Vector.h文件:

#pragma once
#include <vector>
#include <cassert>

template<size_t S>
class Vector
{
public:
    Vector(double fInitialValue = 0.0);
    Vector(std::initializer_list<double> il);
    // indexing range is 0...S-1
    double operator[](size_t i) const;
    double& operator[](size_t i);

private:
    std::vector<double> m_vec;
};

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

template<size_t S>
Vector<S>::Vector(double fInitialValue) : m_vec(S, fInitialValue)
{
}

template<size_t S>
Vector<S>::Vector(std::initializer_list<double> il) : m_vec(il)
{
    assert(il.size() == S);
}

template<size_t S>
double Vector<S>::operator[](size_t i) const
{
    return m_vec[i];
}

template<size_t S>
double& Vector<S>::operator[](size_t i)
{
    return m_vec[i];
}

这是Matrix.h文件:

#pragma once
#include "Vector.h"

template<size_t N, size_t M>
class Matrix
{
public:
    Matrix(double fInitialValue = 0.0);
    Matrix(std::initializer_list<Vector<M>> il);
    // indexing range is 0...N-1, 0...M-1
    Vector<M> operator[](int i) const;
    Vector<M>& operator[](int i);
    double Determinant() const;

private:
    std::vector<Vector<M>> m_mat; // a collection of row vectors
    template <size_t N>
    friend Matrix<N - 1, N - 1> Minor(const Matrix<N, N>& mat, size_t i, size_t j);
};

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

template<size_t N, size_t M>
Matrix<N, M>::Matrix(double fInitialValue)
: m_mat(N, Vector<M>(fInitialValue)) {}

template<size_t N, size_t M>
Matrix<N, M>::Matrix(std::initializer_list<Vector<M>> il) : m_mat(il)
{
    assert(il.size() == N);
}

template<size_t N, size_t M>
Vector<M> Matrix<N, M>::operator[](int i) const
{
    return m_mat[i];
}

template<size_t N, size_t M>
Vector<M>& Matrix<N, M>::operator[](int i)
{
    return m_mat[i];
}

template<size_t N, size_t M>
double Matrix<N, M>::Determinant() const
{
    assert(N == M);
    if (N == 2) {
        return m_mat[0][0] * m_mat[1][1] - m_mat[0][1] * m_mat[1][0];
    }
    double det = 0;
    for (size_t j = 0; j < N; j++) {
        if (j % 2) {
            det += m_mat[0][j] * Minor((*this), 0, j).Determinant();
        }
        else {
            det -= m_mat[0][j] * Minor((*this), 0, j).Determinant();
        }
    }
    return det;
}

template <size_t N>
Matrix<N - 1, N - 1> Minor(const Matrix<N, N>& mat, size_t i, size_t j)
{
    Matrix<N - 1, N - 1> minor;
    for (size_t n = 0; n < i; n++) {
        for (size_t m = 0; m < j; m++) {
            minor[n][m] = mat[n][m];
        }
    }
    for (size_t n = i + 1; n < N; n++) {
        for (size_t m = 0; m < j; m++) {
            minor[n - 1][m] = mat[n][m];
        }
    }
    for (size_t n = 0; n < i; n++) {
        for (size_t m = j + 1; m < N; m++) {
            minor[n][m - 1] = mat[n][m];
        }
    }
    for (size_t n = i + 1; n < N; n++) {
        for (size_t m = j + 1; m < N; m++) {
            minor[n - 1][m - 1] = mat[n][m];
        }
    }
    return minor;
}

将它们与简单的main.cpp文件一起编译:

#include "Matrix.h"
#include <iostream>

int main() {
    Matrix<3, 3> mat = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
    std::cout << mat.Determinant();
}

产生-Error C2760 syntax error: unexpected token '<', expected 'declaration' ...\matrix.h 67

EDIT2:显然,我在Minor函数的实现中将模板参数写为<N - 1><N - 1>而不是<N -1, N-1>。更改该错误可修复错误,但引入了一个新错误-编译挂起,大约一分钟后,我得到Error C1060 compiler is out of heap space ...\matrix.h 65

0 个答案:

没有答案