2012-04-07 7 views
-1

저는 새로운 C++ 사용자이고 또한 수학에서 전공을하고 있으므로 간단한 계산기를 구현하려고합니다. 인터넷에서 코드를 얻었으니 이제는 2 행렬 또는 벡터 요소를 곱하는 데 도움이 필요합니다.2 행렬 또는 벡터 곱셈을위한 기본 C++ 코드 (C++ 초보자)

Matrixf multiply(Matrixf const& left, Matrixf const& right) { 

    // error check 
    if (left.ncols() != right.nrows()) { 
     throw std::runtime_error("Unable to multiply: matrix dimensions not agree."); 
    } 

    /* I have all the other part of the code for matrix*/ 

    /** Now I am not sure how to implement multiplication of vector or matrix.**/ 


    Matrixf ret(1, 1); 

    return ret; 
} 
+0

아래 의견에서 "코딩 지식"을 향상시키고 싶지만 동시에 인터넷에서 코드를 얻었다고 말했습니까? 아마도 처음부터 Matrix 클래스를 구현해야 할 것입니다. –

+0

네, 먼저 쉬운 방법을 통해 지식을 쌓으려고 노력하고 있습니다. 그래서 나는 수학 이해 수준을 뛰어 넘는 행렬 소스 코드를 가져갔습니다. 위와 같은 간단한 방법을 시도하고 있습니다. – Ice

+0

@Ice : 전혀 이해하지 못하는 코드를 사용해도 지식은 향상되지 않으며 "쉬운"방법이 아닙니다. 배우고 싶다면 자신 만의 행렬 클래스를 처음부터 구현하고 자신의 곱셈 루틴을 작성하십시오. 이것은 훨씬 더 좋은 운동이 될 것입니다. – SigTerm

답변

0

나는 당신이 도서관 등 Eigen (매우 빠르게) 또는를 사용하는 것이 좋습니다 것 boost uBLAS matrix (그렇게 빨리, 상대적으로 말하기는 어렵습니다) 수업. 아직도, 당신이 이것을하는 방법을 배우려고한다면, 자신의 수업을 만드는 데 아무런 해가 없습니다. 이 작업을 수행하는 표준 방법은 유형에 대한 템플리트를 사용하는 것입니다. 더 많은 조사를 통해 크기에 대한 템플릿을 사용할 수도 있습니다 (독자의 연습 문제로 남음).

template <typename T> class matrix 
{ 
private: 
    T *_m; 
    std::size_t _rows; 
    std::size_t _cols; 

public: 
    matrix(std::size_t rows, std::size_t cols) 
     : _m(new T[rows*cols]), _rows(rows), _cols(cols) {} 

    matrix(matrix<T>&& src) 
     : _m(src._m), _rows(src._rows), _cols(src._cols) 
    { 
     src._m = NULL; 
     src._rows = 0; 
     src._cols = 0; 
    } 

    matrix<T>& operator=(matrix<T>&& src) 
    { 
     delete[] this->_m; 
     this->_m = src._m; 
     this->_rows = src._rows; 
     this->_cols = src._cols; 
     src._m = NULL; 
     src._rows = 0; 
     src._cols = 0; 

     return *this; 
    } 

    virtual ~matrix() 
    { 
     delete[] this->_m; 
    } 

    inline float& operator()(std::size_t r, std::size_t c) 
    { 
     assert(r < this->_rows && c < this->_cols); 
     return this->_m[r*this->_cols + c]; 
    } 

    inline std::size_t rows() { return this->_rows; } 
    inline std::size_t cols() { return this->_cols; } 
}; 

template <typename T> 
matrix<T> operator*(const matrix<T>& l, const matrix<T>& r) 
{ 
    assert(l.cols() == r.rows()); 
    matrix<T> rv(l.rows(), r.cols()); 

    for (std::size_t r = 0; r < rv.rows(); ++r) 
     for (std::size_t c = 0; c < rv.cols(); ++c); 
     { 
      rv(r, c) = (T) 0; 
      for (std::size_t i = 0; i < l.cols(); ++i) 
       rv(r, c) += l(r, i) * r(i, c); 
     } 

    return rv; 
} 

여기에는 몇 가지 C++ 11 측면 즉 이동 생성자와 할당 연산자가 있습니다. C++ 11을 아직 사용하지 않는 경우 기존의 복사 및 대입 연산자로 각각 대체하십시오. 또한 이것은 일종의 순진한 배율입니다. 대신에 반복자 스타일 구조로 대체하여 많은 행렬 요소 조회를 제거하는 데 사용할 수있는 몇 가지 효율성이 있습니다.

+0

그게 최고로 지금까지 =) – Ice

+0

경고, 방금 입력 한; 나는 그것을 컴파일하려고하지 않았다. – andand

0

우리가 어떻게 클래스 Matrixf 일을 알 필요가 있기 때문에 당신이 코드는, (아웃 사이더로) 해제 작업하기 어렵습니다. 나는 어쨌든 올바른 방향으로 당신을 가리킬 수있는 방법을 설명합니다. 당신은 C/C의 행렬을 나타낼 수있는 가장 간단한 방법은 ++ 단순히 때문에 같은 부동 포인트의 2 차원 배열 : 나는 당신이 필요로하는 모든 코딩 측면에서 몇 가지 지침 생각,

float matrix[3][3]; // 3x3 Matrix 

은 이미 수학을 알고 고려할 것 너는 필요해. 이 행렬의 두 가지 요소를 곱하면 간단하게이 작업을 수행 :

matrixC[0][1] = matrixA[0][0] * matrixB[0][0]; 

matrixA의 왼쪽 요소와 matrixC의 상단 중간 요소에 matrixB의 왼쪽 상단 요소를 곱한 결과를 저장합니다. 본질적으로 첫 번째 대괄호는 을 나타내며 두 ​​번째 대괄호는 을 나타냅니다. 그러나 일관성을 유지하는 한 행과 열이 원하는 순서대로 전적으로 사용자에게 달려 있습니다.

벡터는 유사하게 표현 될 수있다 : 물론

float vector[3]; // 3d vector 

, 우리는 C의 ++를 사용하고 있기 때문에,이 작업을 수행하는 더 좋은 방법이 있습니다. 이 작업을 수행하는 클래스 중심 방법을 설명하는 리소스가있는 것 같습니다. 클래스 기반 방법의 좋은 점은 당신이 할 수있는이 같은 깔끔한 방식으로 추상적 인 곱셈 연산 :이 라인을 따라

Matrix3x3f matrix(1.0f, 0.0f, 0.0f, 
        0.0f, 1.0f, 0.0f, 
        0.0f, 0.0f, 1.0f); 

Vector3f vector(0.2f, 1.4f, -3.1f); 

matrix.multVec(vector); 

... 또는 뭔가.

은 (또한 효율적으로 이미 이런 종류의 물건을 거기 라이브러리,도 있다는 것을 언급 할 가치가있다.)

0

Armadillo C++ 매트릭스 라이브러리의 출처를 살펴 보는 것이 좋습니다. 큰 반면, 그것은 아주 가독성이 있습니다.

특히, 행렬/행렬 곱셈을 구현하는 "gemm.hpp"파일과 행렬/벡터 곱셈을 구현하는 "gemv.hpp"를 살펴보십시오. "Mat_bones.hpp"및 "Mat_meat.hpp"파일은 루트 매트릭스 클래스를 제공합니다.