2017-05-23 8 views
0

을 사용하는 경우 MKL 스파 스 매트릭스 벡터 곱셈 루틴을 사용하는 간단한 C++ 코드 예제가 있습니까? 복잡한 벡터와 함께 복잡한 대칭 행렬 (아래 삼각형에 저장 됨)을 곱하기 위해 "mkl_zcsrsymv"를 사용해야하지만, 이것에 대한 단 하나의 시범적인 예는 찾을 수 없습니다. 복잡한 경우에 대한 코드를 컴파일 할 수 없습니다.MKL 스파 스 매트릭스 벡터 곱하기

답변

2

mkl_zcsrsymv에 대한 설명서를 Intel's homepage에서 읽으십시오. 여기서 대칭은 문자 그대로 취해진 것입니다! (허미 시안을 의미하지는 않습니다)

최대 편의를 위해 icpc -mkl test.c으로 컴파일하십시오.

#include <stdio.h> 
#include "mkl_spblas.h" 

int main() 
{ 
    /* Matrix in CRS format 
    * 
    * { { 0, 0, i } 
    * { 0, -1, 2 } 
    * { i, 2, 0 } } 
    */ 
    int m = 3; 
    MKL_Complex16 a[] = { {0,1}, {-1,0}, {2,0}, {0,1}, {2,0} }; 
    int ia[] = { 0, 1, 3, 5 }; 
    int ja[] = { 2, 1, 2, 0, 1 }; 

    MKL_Complex16 x[] = { {1,0}, {2,0}, {3,0} }; 
    MKL_Complex16 y[] = { {0,0}, {0,0}, {0,0} }; 

    char uplo = 'L'; 
    // Use MKL to compute 
    // y = A*x 
    mkl_cspblas_zcsrsymv(&uplo, &m, a, ia, ja, x, y); 

    printf("y = { (%g,%g), (%g,%g), (%g,%g) }\n", 
     y[0].real, y[0].imag, 
     y[1].real, y[1].imag, 
     y[2].real, y[2].imag 
    ); 
} 

출력은 y = { (0,3), (4,0), (4,1) }입니다. WolframAlpha에서 확인하십시오.


여기는 mkl_dcsrmv의 예이기도합니다.

#include <stdio.h> 
#include "mkl_spblas.h" 

int main() 
{ 
    /* Matrix in CRS format 
    * 
    * { { 0, 0, 1 } 
    * { 0, -1, 2 } 
    * { 1, 0, 0 } } 
    */ 
    int m = 3; 
    int k = 3; 
    double val[] = { 1, -1, 2, 1 }; 
    int indx[] = { 2, 1, 2, 0 }; 
    int pntrb[] = { 0, 1, 3 }; 
    int pntre[] = { 1, 3, 4 }; 

    double x[] = { 1, 2, 3 }; 
    double y[] = { 0, 0, 0 }; 

    double alpha = 1; 
    double beta = 0; 
    char transa = 'N'; 
    char matdescra[] = { 
    'G', // type of matrix 
    ' ', // triangular indicator (ignored in multiplication) 
    ' ', // diagonal indicator (ignored in multiplication) 
    'C' // type of indexing 
    }; 

    // Use MKL to compute 
    // y = alpha*A*x + beta*y 
    mkl_dcsrmv(&transa, &m, &k, &alpha, matdescra, val, indx, pntrb, pntre, x, &beta, y); 

    printf("y = { %g, %g, %g }\n", y[0], y[1], y[2]); 
} 

출력은 y = { 3, 4, 1 }입니다. WolframAlpha에서 확인하십시오.


이걸 가지고 노는 동안 이것은 Armadillo과 직접 호환된다는 것을 알았습니다. 이것은 C++에서 사용하는 것이 매우 편리합니다. 여기서는 먼저 Armadillo로 랜덤 대칭 행렬을 생성하고이를 희소하게 변환합니다. 이것은 임의의 벡터로 곱합니다. 마지막으로, 결과를 Armadillo의 희소 매트릭스 - 벡터 제품과 비교합니다. 정밀도는 상당히 다릅니다.

#include <iostream> 
#include <armadillo> 
#define MKL_Complex16 arma::cx_double 
#include "mkl_spblas.h" 

int main() 
{ 
    /* Matrix in CRS format 
    * 
    * { { 0, 0, i } 
    * { 0, -1, 2 } 
    * { i, 2, 0 } } 
    */ 
    int dim = 1000; 
    arma::sp_cx_mat a(arma::randu<arma::cx_mat>(dim,dim)); 
    a += a.st(); 
    arma::cx_vec x = arma::randu<arma::cx_vec>(dim); 
    arma::cx_vec y(dim); 

    char uplo = 'L'; 
    // Use MKL to compute 
    // y = A*x 
    mkl_cspblas_zcsrsymv(&uplo, &dim, 
         a.values, (int*)a.col_ptrs, (int*)a.row_indices, 
         x.memptr(), y.memptr()); 

    std::cout << std::boolalpha 
      << arma::approx_equal(y, a*x, "absdiff", 1e-10) 
      << '\n'; 
} 
+0

첫 번째 구현을 찾고있었습니다. 훌륭한 답장을 보내 주셔서 대단히 감사합니다. –

+0

@APrec 내 대답이 도움이 되었다면, upvoting을 고려하여 허용 된 대답으로 표시하십시오. –

관련 문제