>source

4x4 행렬의 pinv를 계산하기 위해 아래 code를 사용하고 있습니다. 예상 출력이 해결되지 않습니다. code 출처 https://fractalytics.io/moore-penrose-matrix-optimization-cuda-c. 나는 내가 받아야 할 답을 찾기 위해 matlab을 사용했다. code를 실행하는 데 도움을 주시면 대단히 감사하겠습니다.

code:

#include <iostream>#include <cstdlib>#include <time.h>using namespace std;
//C++ program to find Moore-Penrose inverse  matrix
#define N 7
void Trans_2D_1D(float matrix_2D[N][N], float *matrix)
{
    for (int i= 0; i < N; i++)
    {
        for (int j= 0; j < N; j++)
        {
            matrix[i * N + j]= matrix_2D[i][j];
        }
        cout << endl;
    }
    return;
}
void Transpose(float *matrix, float *t_matrix)
{
    for (int i= 0; i < N; i++)
    {
        for (int j= 0; j < N; j++)
        {
            t_matrix[j * N + i]= matrix[i * N + j];
        }
        cout << endl;
    }
    return;
}
void MatrixMult(float *matrix_1, float *matrix_2, float *matrix_product)
{
    int k;
    for (int i= 0; i < N; i++)
    {
        for (int j= 0; j < N; j++)
        { //not j<M
            matrix_product[i * N + j]= 0;
            for (k= 0; k < N; k++)
            {
                matrix_product[i * N + j] += matrix_1[i * N + k] * matrix_2[k * N + j];
            }
        }
    }
    return;
}
//Function to get cofactor
void getCofactor(float *A, float *temp, int p, int q, int n)
{
    int i= 0, j= 0;
    //Looping for each element of the matrix
    for (int row= 0; row < n; row++)
    {
        for (int col= 0; col < n; col++)
        {
            //Copying into temporary matrix only those element
            //which are not in given row and column
            if (row != p &amp;
&amp;
 col != q)
            {
                temp[i * N + j++]= A[row * N + col];
                //Row is filled, so increase row index and
                //reset col index
                if (j== n -1)
                {
                    j= 0;
                    i++;
                }
            }
        }
    }
}
//Recursive function for finding determinant of matrix.
int determinant(float *A, int n)
{
    int D= 0; //Initialize result
    //Base case : if matrix contains single element
    if (n== 1)
        return A[0];
    float temp[N * N]; //To store cofactors
    int sign= 1; //To store sign multiplier
    //Iterate for each element of first row
    for (int f= 0; f < n; f++)
    {
        //Getting Cofactor of A[0][f]
        getCofactor(A, temp, 0, f, n);
        D += sign * A[0 * N + f] * determinant(temp, n -1);
        //terms are to be added with alternate sign
        sign= -sign;
    }
    return D;
}
//Function to get adjoint
void adjoint(float *A, float *adj)
{
    if (N== 1)
    {
        adj[0]= 1;
        return;
    }
    //temp is used to store cofactors
    int sign= 1;
    float temp[N * N];
    for (int i= 0; i < N; i++)
    {
        for (int j= 0; j < N; j++)
        {
            //Get cofactor
            getCofactor(A, temp, i, j, N);
            //sign of adj positive if sum of row
            //and column indexes is even.
            sign= ((i + j) % 2== 0) ? 1 : -1;
            //Interchanging rows and columns to get the
            //transpose of the cofactor matrix
            adj[j * N + i]= (sign) * (determinant(temp, N -1));
        }
    }
}
//Function to calculate and store inverse, returns false if
//matrix is singular
bool inverse(float *A, float *inverse)
{
    //Find determinant of A[][]
    int det= determinant(A, N);
    if (det== 0)
    {
        cout << "Singular matrix, can't find its inverse";
        return false;
    }
    //Find adjoint
    float adj[N * N];
    adjoint(A, adj);
    //Find Inverse using formula "inverse(A)= adj(A)/det(A)"
    for (int i= 0; i < N; i++)
        for (int j= 0; j < N; j++)
            inverse[i * N + j]= adj[i * N + j] /float(det);
    return true;
}
//Generic function to display the matrix. We use it to display
//both adjoin and inverse. adjoin is integer matrix and inverse
//is a float.
template <class T>void display(T *A)
{
    for (int i= 0; i < N; i++)
    {
        for (int j= 0; j < N; j++)
            cout << A[i * N + j] << " ";
        cout << endl;
    }
}
//Driver program
int main()
{
    float A[N][N]= {{
                         0,
                         0,
                         0,
                         0,
                     },
                     {0, 2, 1, 2},
                     {2, 1, 0, 1},
                     {2, 0, 1, 4}};
    ;
    float *matrix= new float[N * N];
    float *t_matrix= new float[N * N];
    float *matrix_mult= new float[N * N];
    float *pseudoinverse= new float[N * N];
    float *adj= new float[N * N]; //To store adjoint
    float *inv= new float[N * N]; //To store inverse
    Transpose(matrix, t_matrix);
    cout << "\nThe Transpose is :\n";
    display(t_matrix);
    cout << "The product of the matrix is: " << endl;
    MatrixMult(t_matrix, matrix, matrix_mult);
    display(matrix_mult);
    cout << "\nThe Inverse is :\n";
    if (inverse(matrix_mult, inv))
        display(inv);
    MatrixMult(inv, t_matrix, pseudoinverse);
    cout << "\nThe Monroe-penrose inverse is :\n";
    display(pseudoinverse);
    return 0;
}

출력:

The Transpose is :
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
The product of the matrix is:
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
The Inverse is :
Singular matrix, can't find its inverse
The Monroe-penrose inverse is :
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

예상되는 pinv 결과:

-0.000000 -0.217949 0.461539 0.012820
-0.000000 0.358974 0.269231 -0.256410
0.000000 0.128205 -0.153846 0.051282
0.000000 0.076923 -0.192308 0.230769

편집 1: 실제 출력:

The Transpose is :
2.33793e-37 0 0 0
0 0 0 0
1.60717e-38 0 0 0
0 0 0 0
The product of the matrix is:
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
The Inverse is :
Singular matrix, can't find its inverse
The Monroe-penrose inverse is :
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

나는 원래 code에서 #define N을 변경하지 않았다는 것을 깨달았습니다. 편집에서 업데이트했습니다.

CodingCurry2021-09-22 07:36:12

A는 어디에 사용됩니까?

Frank2021-09-22 07:36:12

A를 초기화했지만 사용하지 않고 대신 초기화되지 않은 다른 행렬을 사용합니다.

463035818_is_not_a_number2021-09-22 07:36:12

블로그 게시물과 동일한 문제입니다. 다른 이유로 code가 가장 좋지 않다는 점에 유의하십시오. 조옮김과 2d->1d는 하나의 단계로 쉽게 수행할 수 있기 때문에 두 개의 별도 단계로 만든 예시용일 뿐이라고 생각합니다. 그리고 약간의 인덱스 저글링으로 2d->1d를 수행하고 한 단계로 역변환 및 계산을 수행할 수 있습니다.

463035818_is_not_a_number2021-09-22 07:36:12
  • 이전 Android에서 모바일 시스템 시간과 날짜를 설정하는 방법은 무엇입니까?
  • 다음 Windows에서 Python 3.9에서 가상 env를 만들 수 없습니다