2010-01-16 149 views
14

在C,如果我想創建一個矩陣結構,我會用:C++矩陣

struct matrix { 
    int col, row; 
    double data[1]; // I want the matrix entries stored 
        // right after this struct 
} 

然後,我可以用

matrix* allocate_matrix(int row, int col) { 
    matrix* m = malloc(sizeof(matrix) + sizeof(double) * (row * col - 1)); 
    m->row = row; m->col = col; 
    return m; 
} 

分配它現在做我做的當量在C++ ?

編輯:

我想知道實現C++矩陣類cannonical方式。

+1

你應該填寫'...'來清除一些答案中的混淆。 – GManNickG 2010-01-16 08:07:51

+0

好通話;這足夠嗎? – anon 2010-01-16 08:19:08

回答

-2

在C++中,你可以使用這樣的:

matrix *p = new matrix; 

之後,

delete p; 
+0

OP在問題的原始語句中並不明確,但意圖顯然是'struct'的最後一個成員,它是一個變量/不確定大小的數組,因此只需使用'new'而不是'malloc'即可沒有工作。 – jamesdlin 2010-01-16 08:26:06

12

C++主要是C的超集,你可以繼續做你在做什麼。

也就是說,在C++中,你應該做的是定義一個適當的Matrix類來管理它自己的內存。例如,它可以由內部的std::vector提供支持,並且您可以覆蓋operator[]operator()以從C++ FAQ中適當地將索引編入索引(例如,請參閱:How do I create a subscript operator for a Matrix class?)。

爲了讓你開始:

class Matrix 
{ 
public: 
    Matrix(size_t rows, size_t cols); 
    double& operator()(size_t i, size_t j); 
    double operator()(size_t i, size_t j) const; 

private: 
    size_t mRows; 
    size_t mCols; 
    std::vector<double> mData; 
}; 

Matrix::Matrix(size_t rows, size_t cols) 
: mRows(rows), 
    mCols(cols), 
    mData(rows * cols) 
{ 
} 

double& Matrix::operator()(size_t i, size_t j) 
{ 
    return mData[i * mCols + j]; 
} 

double Matrix::operator()(size_t i, size_t j) const 
{ 
    return mData[i * mCols + j]; 
} 

(請注意,上面並沒有做任何邊界檢查的,我把它作爲一個練習模板,以便它適用於比double其他的東西。 )

3

可能這樣做。唯一的區別是你需要從malloc投下結果。

相反,您可以使用vector作爲具有計算索引的一維數組或嵌入向量。 (前者匹配你的代碼更好。)

例如:

template <typename T> // often, they are templates 
struct matrix 
{ 
    // should probably be hidden away, and the class would 
    // provide `at` and `operator()` for access 
    int col, row; 
    std::vector<T> data; 

    matrix(int columns, int rows) : 
    col(columns), row(rows), 
    data(col * row) 
    {} 

} 

matrix m(4, 4); 
m.data[1 + 1 * 4] = /* ... */; 

或者:

template <typename T> 
struct matrix 
{ 
    int col, row; 
    std::vector<std::vector<T> > data; 

    matrix(int columns, int rows) : 
    col(columns), row(rows), 
    data(col, std::vector(row)) 
    {} 
} 

matrix m(4, 4); 
m.data[1][1] = /* ... */; 

但這些僅是例子。你想成爲一個完整的班級;如果你想要更多的建議,編輯你的問題,並澄清你想知道實現矩陣類的規範方式。

有預先存在的矩陣類。我最喜歡的是從提升,UBLAS

+0

你的意思是'data [1] [1]',而不是'data [1,1]'。 (從技術上講,'m.data [1] [1]'。) – jamesdlin 2010-01-16 08:23:12

+0

哎呀,完全清除了那個。 – GManNickG 2010-01-16 08:36:07

+0

我不認爲vector的vector會成爲一個非常有效的實現。 – bobobobo 2010-08-02 18:54:22

4

建立一個高效和高質量的矩陣類有很多微妙之處,幸運的是有幾個好的實現浮出水面。

想想你是想要一個固定大小的矩陣類還是可變大小的矩陣類。 即你可以這樣做:

// These tend to be fast and allocated on the stack. 
matrix<3,3> M; 

或者你需要能夠做到這一點

// These are slower but more flexible and partially allocated on the heap 
matrix M(3,3); 

有支持兩種風格很好的圖書館,以及一些支持。 他們有不同的分配模式和不同的表現。

如果您想自己編寫代碼,那麼模板版本需要一些模板知識(duh)。如果在緊密循環中使用,那麼動態的需要一些黑客來解決大量的小分配問題。

1

你可以用模板做,如果矩陣大小在編譯時已知:

template <int width, int height> 
class Matrix{ 
    double data[height][width]; 
    //...member functions 
}; 
30

諾塔好處。

此答案現在有20個upvotes,但它不是,不打算作爲std::valarray的代言。

根據我的經驗,安裝和學習使用全面的數學庫(如Eigen)花費的時間會更多。 Valarray的功能比競爭對手少,但效率並不高,或者特別容易使用。

如果你只需要一點線性代數,並且你已經死定了反對向你的工具鏈添加任何東西,那麼可能valarray將適合。但是,被卡住無法表達數學上正確的解決方案是一個非常糟糕的位置。數學是無情的,無情的。使用正確的工具來完成這項工作。


標準庫提供std::valarray<double>。這裏有一些其他人提出的std::vector<>,意圖作爲對象的通用容器。 valarray,鮮爲人知的,因爲它是更特化的(不使用「專門」作爲C++術語),具有幾個優點:

  • 它不分配額外的空間。當分配時,A vector將達到最接近的2的冪,所以您可以調整它的大小而不必每次重新分配。 (您仍然可以調整valarray的大小;它仍然與realloc()一樣昂貴。)
  • 您可以將其切片以輕鬆訪問行和列。
  • 算術運算符按照您的預期工作。

當然,使用C的優勢在於您無需管理內存。維度可以位於堆棧中,也可以位於切片對象中。

std::valarray<double> matrix(row * col); // no more, no less, than a matrix 
matrix[ std::slice(2, col, row) ] = pi; // set third column to pi 
matrix[ std::slice(3*row, row, 1) ] = e; // set fourth row to e 
+2

+1將我指向stl – Shep 2012-04-14 08:36:50

+0

@Shep不得不承認我從來沒有真正使用過'valarray' ......我嘗試了幾次,切片類是一種痛苦。這可能值得一看,並且比其他答案在這裏提出的建議更好,但是有更好的庫。 (好吧,至少看起來是這樣,我還沒有真正使用過,Boost BLAS應該不錯。) – Potatoswatter 2012-04-14 10:19:01

+2

Yikes,這是朝着10個upvotes前進的。 'std :: valarray'很難使用,只支持基本的成員代數,並且它不是很流行。試試[Eigen Library](http://eigen.tuxfamily.org/),它非常易於使用,功能強大且頗受歡迎。 – Potatoswatter 2013-01-07 03:58:06

2

你可以使用一個模板:

#include <iostream> 
using std::cerr; 
using std::endl; 

//qt4type 
typedef unsigned int quint32; 

template <typename T> 
void deletep(T &) {} 
template <typename T> 
void deletep(T* & ptr) { 
    delete ptr; 
    ptr = 0; 
} 
template<typename T> 
class Matrix { 
    public: 
     typedef T value_type; 
     Matrix() : _cols(0), _rows(0), _data(new T[0]), auto_delete(true) {}; 
     Matrix(quint32 rows, quint32 cols, bool auto_del = true); 

     bool exists(quint32 row, quint32 col) const; 
     T & operator()(quint32 row, quint32 col); 
     T operator()(quint32 row, quint32 col) const; 
     virtual ~Matrix(); 

     int size() const { return _rows * _cols; } 
     int rows() const { return _rows; } 
     int cols() const { return _cols; } 
    private: 
     Matrix(const Matrix &); 
     quint32 _rows, _cols; 
     mutable T * _data; 
     const bool auto_delete; 
}; 
template<typename T> 
Matrix<T>::Matrix(quint32 rows, quint32 cols, bool auto_del) : _rows(rows), _cols(cols), auto_delete(auto_del) { 
    _data = new T[rows * cols]; 
} 
template<typename T> 
inline T & Matrix<T>::operator()(quint32 row, quint32 col) { 
    return _data[_cols * row + col]; 
} 
template<typename T> 
inline T Matrix<T>::operator()(quint32 row, quint32 col) const { 
    return _data[_cols * row + col]; 
} 

template<typename T> 
bool Matrix<T>::exists(quint32 row, quint32 col) const { 
    return (row < _rows && col < _cols); 
} 

template<typename T> 
Matrix<T>::~Matrix() { 
    if(auto_delete){ 
     for(int i = 0, c = size(); i < c; ++i){ 
      //will do nothing if T isn't a pointer 
      deletep(_data[i]); 
     } 
    } 
    delete [] _data; 
} 

int main() { 
    Matrix<int> m(10,10); 
    quint32 i = 0; 
    for(int x = 0; x < 10; ++x) { 
     for(int y = 0; y < 10; ++y, ++i) { 
      m(x, y) = i; 
     } 
    } 
    for(int x = 0; x < 10; ++x) { 
     for(int y = 0; y < 10; ++y) { 
      cerr << "@(" << x << ", " << y << ") : " << m(x,y) << endl; 
     } 
    } 
} 

*編輯,固定一個錯字。

2

對於矩陣類,您希望遠離過載運算符[]
C++ FAQ 13.10

此外,在網絡上搜索一些免費軟件矩陣類。最壞的情況下,他們可以給你指導。最好的情況下,你必須編寫更少的軟件和調試

3

發佈幾年之後,C++ 11授予了我們一些新的可能性。

這裏是一個的包括在我做飯了,應該給其他人誰在這個跌倒的現代化起點的OpenGL庫的早期草案:

(注 - 這還有待檢驗或審覈)

/*(KILLGPL: Incompatible with Libraries Linked to the GPL) 
============================================================================ 

"Free software" should be just that - free. Extreme copy-left licenses 
such as the GPL, GPL2, GPL3, etc, and their users have twisted the 
term "free" to meet their own anti-business, anti-closed source agendas by 
forcing licensees to relicense their software under the same "viral" terms 
and by forcing licensees to distribute sources with binary distributions. 
This license stands in protest of such licenses in an attempt to protect 
the freedoms that extreme copy-left licenses have been taking away from 
software developers for far too long. 

Permission is hereby granted, free of charge, to any person obtaining 
a copy of this software and associated documentation files (the 
"Software"), to deal in the Software with only one restriction: no part of 
it may be included in software projects that are distributed under "viral" 
licensing schemes like those found in the GPL, GPL2, GPL3, etc. 

There are no further usage restrictions. Licensees are encouraged to use 
this software in both open and closed source applications, so long as no 
part of the combined work is licensed under extreme copy-left licenses. 

The above copyright notice and this permission notice shall be included 
in all copies or substantial portions of the Software. Note - this notice 
does not have to appear in YOUR code, but must remain intact in the parts 
licensed under the KILLGPL. 

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ 

#ifndef MATRIX_HPP 
#define MATRIX_HPP 

#include <array> 
#include <cstdint> 
#include <iterator> 
#include <initializer_list> 
#include <iosfwd> 

/// Forward Declarations Required for free-function friends 
template<typename T, std::size_t X, std::size_t Y> 
class Matrix; 

/** 
* Performs a component-wise comparison between the two provided matrices 
* 
* @param lhs the first matrix to compare 
* 
* @param rhs the second matrix to compare 
* 
* @return true if the two matrices are equal, otherwise false 
* 
*/ 
template<typename T, std::size_t X, std::size_t Y> 
bool operator==(const Matrix<T, X, Y>& lhs, const Matrix<T, X, Y>& rhs) noexcept; 

/** 
* Performs a component-wise comparison between the two provided matrices 
* 
* @param lhs the first matrix to compare 
* 
* @param rhs the second matrix to compare 
* 
* @return true if the two matrices are not equal, otherwise false 
* 
*/ 
template<typename T, std::size_t X, std::size_t Y> 
bool operator!=(const Matrix<T, X, Y>& lhs, const Matrix<T, X, Y>& rhs) noexcept; 

/** 
* Inserts the provided Matrix into the provided output stream 
* 
* @param stream the stream to insert the provided Matrix into 
* 
* @param matrix the Matrix to insert into the provided stream 
* 
* @return the provided stream 
* 
*/ 
template<typename T, std::size_t X, std::size_t Y> 
std::ostream& operator<<(std::ostream& stream, const Matrix<T, X, Y>& matrix); 

/** 
* Extracts a Matrix from the provided input stream 
* 
* @param stream the stream to extract from 
* 
* @param matrix the Matrix to extract into 
* 
* @return the provided input stream 
* 
*/ 
template<typename T, std::size_t X, std::size_t Y> 
std::istream& operator>>(std::istream& stream, Matrix<T, X, Y>& matrix); 

/** 
* A modern general-purpose object-oriented matrix class without any legacy hacks from C 
* 
* Several common matrix types are also defined in the following format: 
* 
* Matrix {number of rows} x {number of columns} {type abbreviation} 
* 
* where the predefined type abbreviations are: 
* type  - abbreviation 
* -------------------------- 
* double - D 
* float  - F 
* int64_t - L 
* uint64_t - UL 
* int32_t - I 
* uint32_t - UI 
* int16_t - S 
* uint16_t - US 
* int8_t - C 
* uint8_t - UC 
* 
* example: Matrix3x3F - A tuple that holds 3x3 float elements 
* 
* User-defined matrix types are expected to follow the aforementioned format. 
* 
* @tparam T the type of data stored in this matrix 
* 
* @tparam Rows the number of rows in this matrix 
* 
* @tparam Columns the number of columns in this matrix 
*/ 
template<typename T, std::size_t Rows, std::size_t Columns> 
class Matrix 
{ 
    static_assert(Rows > 0, "The number of rows in a Matrix must be greater than zero"); 
    static_assert(Columns > 0, "The number of columns in a Matrix must be greater than zero"); 

    /// Privileged free-functions 
    friend std::ostream& operator<<<>(std::ostream&, const Matrix<T, Rows, Columns>&); 
    friend std::istream& operator>><>(std::istream&, const Matrix<T, Rows, Columns>&); 
    friend bool operator!=<>(const Matrix<T, Rows, Columns>&, const Matrix<T, Rows, Columns>&); 
    friend bool operator==<>(const Matrix<T, Rows, Columns>&, const Matrix<T, Rows, Columns>&); 

    /// The actual container that holds the elements of this Matrix 
    std::array<T, Rows * Columns> values; 

    public: 

    /// A convenience field that provides the total number of elements in this Matrix 
    static constexpr std::size_t Length = Rows * Columns; 

    /** 
    * Retrieves the identity-matrix 
    * 
    * @return the identity-matrix 
    * 
    */ 
    static constexpr Matrix IDENTITY() noexcept; 

    /** 
    * Retrieves the zero-matrix 
    * 
    * @return the zero-matrix 
    * 
    */ 
    static constexpr Matrix ZERO() noexcept; 

    /** 
    * Constructs a Matrix with each element initialized to zero 
    * 
    */ 
    constexpr Matrix() noexcept; 

    /** 
    * Constructs a Matrix whose elements are initialized to the provided array 
    * 
    * @param elements the array to initialize this Matrix with 
    * 
    */ 
    explicit constexpr Matrix(const std::array<T, Rows * Columns>& elements) noexcept; 

    /** 
    * Constructs a Matrix whose elements are initialized to the provided array 
    * 
    * @param elements the array to initialize this Matrix with 
    * 
    */ 
    explicit constexpr Matrix(std::array<T, Rows * Columns>&& elements) noexcept; 

    /** 
    * Constructs a Matrix whose elements are initialized with the provided values 
    * 
    * @param element the first value 
    * 
    * @param elements all subsequent values 
    * 
    * <pre>Matrix<int, 3, 3> matrix(1, 2, 3, 1, 2, 3, 1,2 ,3);</pre> 
    * 
    */ 
    template<typename ...E> 
    explicit constexpr Matrix(T element, E&&... elements) noexcept; 

    /** 
    * Retrieves a const reference to the element at the provided row and column 
    * 
    * @param row the row to access 
    * 
    * @param column the column to access 
    * 
    * @return the element at the provided row and column 
    * 
    */ 
    /*constexpr*/const T& operator()(std::size_t row, std::size_t column) const noexcept; 

    /** 
    * Retrieves a reference to the element at the provided row and column 
    * 
    * @param row the row to access 
    * 
    * @param column the column to access 
    * 
    * @return the element at the provided row and column 
    * 
    */ 
    /*constexpr*/T& operator()(std::size_t row, std::size_t column) noexcept; 

    // TODO: Global Free Functions for performing transformations 
}; 

namespace detail 
{ 
    // thanks be to Cubbi @ cplusplus.com for enlightenment 
    template<int ...> struct sequence 
    { 

    }; 

    template<int N, int ...S> struct sequence_generator : sequence_generator<N - 1, N - 1, S...> 
    { 

    }; 

    template<int ...S> struct sequence_generator < 0, S...> 
    { 
     using type = sequence<S...>; 
    }; 

    template<std::size_t X, std::size_t Y> 
    constexpr int get_element(std::size_t pos) 
    { 
     return pos % Y == pos/Y; 
    } 

    template <typename T, std::size_t Rows, std::size_t Columns, int ...S> 
    constexpr std::array<T, Rows * Columns> get_identity_array(sequence<S...>) 
    { 
     return std::array<T, Rows * Columns> {{ get_element<Rows, Columns>(S)... }}; 
    } 
} 

template<typename T, std::size_t Rows, std::size_t Columns> 
bool operator==(const Matrix<T, Rows, Columns>& lhs, const Matrix<T, Rows, Columns>& rhs) noexcept 
{ 
    for(int i = 0; i < Matrix<T, Rows, Columns>::Length; ++i) 
    { 
     if(lhs[i] == rhs[i]) 
     { 
      return true; 
     } 
    } 
    return false; 
} 

template<typename T, std::size_t Rows, std::size_t Columns> 
bool operator!=(const Matrix<T, Rows, Columns>& lhs, const Matrix<T, Rows, Columns>& rhs) noexcept 
{ 
    for(int i = 0; i < Matrix<T, Rows, Columns>::Length; ++i) 
    { 
     if(lhs[i] != rhs[i]) 
     { 
      return true; 
     } 
    } 
    return false; 
} 

template<typename T, std::size_t Rows, std::size_t Columns> 
Matrix<T, Rows, Columns> operator-(const Matrix<T, Rows, Columns>& source) noexcept 
{ 
    Matrix<T, Rows, Columns> rv(source); 
    for(int i = 0; i < Matrix<T, Rows, Columns>::Length; ++i) 
    { 
     rv[i] *= -1; 
    } 
    return rv; 
} 

template<typename T, std::size_t Rows, std::size_t Columns> 
constexpr Matrix<T, Rows, Columns> Matrix<T, Rows, Columns>::IDENTITY() noexcept 
{ 
    return Matrix{detail::get_identity_array<T, Rows, Columns>(typename detail::sequence_generator<Rows * Columns>::type())}; 
} 

template<typename T, std::size_t Rows, std::size_t Columns> 
constexpr Matrix<T, Rows, Columns> Matrix<T, Rows, Columns>::ZERO() noexcept 
{ 
    return Matrix{}; 
} 

template<typename T, std::size_t Rows, std::size_t Columns> 
constexpr Matrix<T, Rows, Columns>::Matrix() noexcept 
{ 

} 

template<typename T, std::size_t Rows, std::size_t Columns> 
constexpr Matrix<T, Rows, Columns>::Matrix(const std::array<T, Rows * Columns>& values) noexcept : values(values) 
{ 

} 

template<typename T, std::size_t Rows, std::size_t Columns> 
constexpr Matrix<T, Rows, Columns>::Matrix(std::array<T, Rows * Columns>&& array) noexcept : values(array) 
{ 

} 

template<typename T, std::size_t Rows, std::size_t Columns> 
template<typename ...E> 
constexpr Matrix<T, Rows, Columns>::Matrix(T first, E&&... elements) noexcept : values {{ first, std::forward<T>(static_cast<T>(elements))... }} 
{ 

} 

template<typename T, std::size_t Rows, std::size_t Columns> 
/*constexpr*/const T& Matrix<T, Rows, Columns>::operator()(std::size_t row, std::size_t column) const noexcept 
{ 
    dynamic_assert(row >= 0 && row < Rows, "access violation (row index " << row << " out of range [" << Rows << "])"); 
    dynamic_assert(column >= 0 && column < Columns, "access violation (column " << column << " out of range [" << Columns << "])"); 
    return values[column * Rows + row]; 
} 

template<typename T, std::size_t Rows, std::size_t Columns> 
/*constexpr*/T& Matrix<T, Rows, Columns>::operator()(std::size_t row, std::size_t column) noexcept 
{ 
    dynamic_assert(row >= 0 && row < Rows, "access violation (row index " << row << " out of range [" << Rows << "])"); 
    dynamic_assert(column >= 0 && column < Columns, "access violation (column " << column << " out of range [" << Columns << "])"); 
    return values[column * Rows + row]; 
} 


/// Built-in library matrix types 
typedef Matrix<uint8_t, 2, 2> Matrix2x2UC; 
typedef Matrix<uint8_t, 3, 3> Matrix3x3UC; 
typedef Matrix<uint8_t, 4, 4> Matrix4x4UC; 

typedef Matrix<int8_t, 2, 2> Matrix2x2C; 
typedef Matrix<int8_t, 3, 3> Matrix3x3C; 
typedef Matrix<int8_t, 4, 4> Matrix4x4C; 

typedef Matrix<uint16_t, 2, 2> Matrix2x2US; 
typedef Matrix<uint16_t, 3, 3> Matrix3x3US; 
typedef Matrix<uint16_t, 4, 4> Matrix4x4US; 

typedef Matrix<int16_t, 2, 2> Matrix2x2S; 
typedef Matrix<int16_t, 3, 3> Matrix3x3S; 
typedef Matrix<int16_t, 4, 4> Matrix4x4S; 

typedef Matrix<uint32_t, 2, 2> Matrix2x2UI; 
typedef Matrix<uint32_t, 3, 3> Matrix3x3UI; 
typedef Matrix<uint32_t, 4, 4> Matrix4x4UI; 

typedef Matrix<int32_t, 2, 2> Matrix2x2I; 
typedef Matrix<int32_t, 3, 3> Matrix3x3I; 
typedef Matrix<int32_t, 4, 4> Matrix4x4I; 

typedef Matrix<uint64_t, 2, 2> Matrix2x2UL; 
typedef Matrix<uint64_t, 3, 3> Matrix3x3UL; 
typedef Matrix<uint64_t, 4, 4> Matrix4x4UL; 

typedef Matrix<int64_t, 2, 2> Matrix2x2L; 
typedef Matrix<int64_t, 3, 3> Matrix3x3L; 
typedef Matrix<int64_t, 4, 4> Matrix4x4L; 

typedef Matrix<float, 2, 2> Matrix2x2F; 
typedef Matrix<float, 3, 3> Matrix3x3F; 
typedef Matrix<float, 4, 4> Matrix4x4F; 

typedef Matrix<double, 2, 2> Matrix2x2D; 
typedef Matrix<double, 3, 3> Matrix3x3D; 
typedef Matrix<double, 4, 4> Matrix4x4D; 
#endif 
+0

非常好的例子。 – Vincent 2014-10-03 22:36:16

0

Github Link

// 
// iBS_Matrix.h 
// 
// 
// Created by nash on 11/29/15. 
// Copyright 2015 iBean Software. 
// All rights reserved. 
// current copy on Github: 
// 
#ifndef iBS_Matrix_h 
#define iBS_Matrix_h 

const int Matrix_MAJOR_VERSION = 1; 
const int Matrix_MINOR_VERSION = 0; 

#include <iostream> 
#include <vector> 
namespace iBS 
{ 
struct Matrix 
{ 
    std::vector<std::vector<int> > a; 

    Matrix& operator =(Matrix& o) 
    { 
     a.resize(o.a.size()); 
     for(int i=0;i<a.size();i++) 
      a[i].resize(o.a[i].size()); 
     for(int i=0;i<a.size();i++) 
      for(int j=0;j<a[i].size();j++) 
      { 
       a[i][j] = o.a[i][j]; 
      } 
     return *this; 
    } 

    Matrix& operator +(Matrix& o) 
    { 
     for(int i=0;i<a.size();i++) 
      for(int j=0;j<a[i].size();j++) 
      { 
       a[i][j] = a[i][j] + o.a[i][j]; 
      } 
     return *this; 
    } 
    Matrix& operator -(Matrix& o) 
    { 
     for(int i=0;i<a.size();i++) 
      for(int j=0;j<a[i].size();j++) 
      { 
       a[i][j] = a[i][j] - o.a[i][j]; 
      } 
     return *this; 
    } 
    Matrix& operator *(Matrix& o) 
    { 
     if(a[0].size() != o.a.size()) return *this; 

     Matrix tm; 
     tm.a.resize(a.size()); 
     for(int i=0;i<tm.a.size();i++) 
      tm.a[i].resize(o.a[0].size()); 

     for(int i=0;i<tm.a.size();i++) 
      for(int j=0;j<tm.a[i].size();j++) 
      { 
       tm.a[i][j] = 0; 
       for (int c=0; c<a[i].size(); c++) 
       { 
        tm.a[i][j] += a[i][c] * o.a[c][j]; 
       } 

      } 
     *this = tm; 
     return *this; 
    } 
    Matrix& operator ^(int power) 
    { 
     Matrix tM2; 
     tM2 = *this; 

    // not <= below \/ because first time counts as 2 
     for(int i=1; i<power; ++i) 
      *this = (*this) * (tM2); 

     return *this; 
    } 

    void print() 
    { 
     for(int i=0;i<a.size();i++) 
     { 
      for(int j=0;j<a[i].size();j++) 
      { 
       std::cout << a[i][j] << ' '; 
      } 
      std::cout << std::endl; 
     } 
     std::cout << std::endl; 
    } 
}; 

}; // end of namespace iBS 

#endif // iBS_Matrix_h 
0

沒有 「規範」 的方式做在C++中,STL不提供類,如「馬特里矩陣X」。但是有一些第三方庫可以。鼓勵您使用它們或編寫您自己的實現。