OS: Ubuntu 22.04.2 LTS.

Download eigen from website: https://eigen.tuxfamily.org/index.php?title=Main_Page

Small Eigen Project

Write a file main.cpp which use eigen library.

#include <iostream>
#include <Eigen/Dense>
 
using Eigen::MatrixXd;
 
int main()
{
  MatrixXd m(2,2);
  m(0,0) = 3;
  m(1,0) = 2.5;
  m(0,1) = -1;
  m(1,1) = m(1,0) + m(0,1);
  std::cout << m << std::endl;
  return 0;
}

Build and run it.

➜  useEigen g++ -I /home/stephen/Downloads/eigen-3.4.0/ main.cpp -o main 
➜  useEigen ./main 
  3  -1
2.5 1.5

Use Lapack In Eigen In C++ Project

Write test code to use lapack, build and run the project.

#include <iostream>
#include <fstream>

#include "Eigen/src/misc/lapacke.h"

using namespace std;

int main(int argc, char** argv)
{
    // check for an argument
    if (argc<2){
        cout << "Usage: " << argv[0] << " " << " filename" << endl;
        return -1;
    }

    int n,m;
    double *data;

    // read in a text file that contains a real matrix stored in column major format
    // but read it into row major format
    ifstream fin(argv[1]);
    if (!fin.is_open()){
        cout << "Failed to open " << argv[1] << endl;
        return -1;
    }
    fin >> n >> m;  // n is the number of rows, m the number of columns
    data = new double[n*m];
    for (int i=0;i<n;i++){
        for (int j=0;j<m;j++){
            fin >> data[j*n+i];
        }
    }
    if (fin.fail() || fin.eof()){
        cout << "Error while reading " << argv[1] << endl;
        return -1;
    }
    fin.close();

    // check that matrix is square
    if (n != m){
        cout << "Matrix is not square" <<endl;
        return -1;
    }

    // allocate data
    char Nchar='N';
    double *eigReal=new double[n];
    double *eigImag=new double[n];
    double *vl,*vr;
    int one=1;
    int lwork=6*n;
    double *work=new double[lwork];
    int info;

    // calculate eigenvalues using the DGEEV subroutine
    dgeev_(&Nchar,&Nchar,&n,data,&n,eigReal,eigImag,
        vl,&one,vr,&one,
        work,&lwork,&info);


    // check for errors
    if (info!=0){
        cout << "Error: dgeev returned error code " << info << endl;
        return -1;
    }

    // output eigenvalues to stdout
    cout << "--- Eigenvalues ---" << endl;
    for (int i=0;i<n;i++){
        cout << "( " << eigReal[i] << " , " << eigImag[i] << " )\n";
    }
    cout << endl;

    // deallocate
    delete [] data;
    delete [] eigReal;
    delete [] eigImag;
    delete [] work;
    return 0;
}

Create a file matrix.txt

3 3
-1.0 -8.0  0.0
-1.0  1.0 -5.0
3.0  0.0  2.0

Run the executable file by command line

g++ -I /home/stephen/Downloads/eigen-3.4.0/ test.cpp -o main -D EIGEN_USE_LAPACKE=1 -llapack
./main matrix.txt

Compute SVD By Lapack In Eigen In C++ Project

Here is a project to compute the SVD for a 3×3 matrix. The interface introduction about dgesdd can be found at https://netlib.org/lapack/explore-html/d1/d7e/group__double_g_esing_gad8e0f1c83a78d3d4858eaaa88a1c5ab1.html. You can also find dgesdd function declaration in Eigen/src/misc/lapacke.h in Eigen project.

void LAPACK_dgesdd( char* jobz, lapack_int* m, lapack_int* n, double* a,
                    lapack_int* lda, double* s, double* u, lapack_int* ldu,
                    double* vt, lapack_int* ldvt, double* work,
                    lapack_int* lwork, lapack_int* iwork, lapack_int *info );

Here is a cpp file using dgesdd to compute svd for original 3×3 matrix.

#include <stdlib.h>
#include <stdio.h>

#include "Eigen/src/misc/lapacke.h"

/* DGESDD prototype */
// extern void dgesdd( char* jobz, int* m, int* n, double* a,
//                 int* lda, double* s, double* u, int* ldu, double* vt, int* ldvt,
//                 double* work, int* lwork, int* iwork, int* info );
/* Auxiliary routines prototypes */
extern void print_matrix( char* desc, int m, int n, double* a, int lda );

/* Parameters */
#define M 3
#define N 3
#define LDA M
#define LDU M
#define LDVT N

/* Main program */
int main() {
    /* Locals */
    int m = M, n = N, lda = LDA, ldu = LDU, ldvt = LDVT, info, lwork;
    double wkopt;
    double* work;
    /* Local arrays */
    /* iwork dimension should be at least 8*min(m,n) */
    int iwork[8*N];
    double s[N], u[LDU*M], vt[LDVT*N];    
    double a[LDA*N] = {
        8915.40487296, -603.33651003, -107.43002595,
        -438.80704991,  -6950.77014448, -579.47443937,
        11.03958149,-144.92407957,1730.06287165
    };

    /* Executable statements */
    printf( " DGESDD Example Program Results\n" );
    /* Query and allocate the optimal workspace */
    lwork = -1;
    // dgesdd_( "Singular vectors", &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, &wkopt,
    //     &lwork, iwork, &info );
    dgesdd_( "S", &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, &wkopt,
    &lwork, iwork, &info );
    lwork = (int)wkopt;
    work = (double*)malloc( lwork*sizeof(double) );
    /* Compute SVD */
    // dgesdd_( "Singular vectors", &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work,
    //     &lwork, iwork, &info );
    dgesdd_( "S", &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work,
        &lwork, iwork, &info );
    /* Check for convergence */
    if( info > 0 ) {
            printf( "The algorithm computing SVD failed to converge.\n" );
            exit( 1 );
    }
    /* Print singular values */
    print_matrix( "Singular values", 1, n, s, 1 );
    /* Print left singular vectors */
    print_matrix( "Left singular vectors (stored columnwise)", m, n, u, ldu );
    /* Print right singular vectors */
    print_matrix( "Right singular vectors (stored rowwise)", n, n, vt, ldvt );
    /* Free workspace */
    free( (void*)work );
    return 0;
} /* End of DGESDD Example */

/* Auxiliary routine: printing a matrix */
void print_matrix( char* desc, int m, int n, double* a, int lda ) {
        int i, j;
        printf( "\n %s\n", desc );
        for( i = 0; i < m; i++ ) {
                for( j = 0; j < n; j++ ) printf( " %.8f", a[i+j*lda] );
                printf( "\n" );
        }
}

Build and run it.

g++ -I /home/stephen/Downloads/eigen-3.4.0/ final2.cpp -o svd -D EIGEN_USE_LAPACKE=1 -llapack
./svd
DGESDD Example Program Results

 Singular values
 8936.65538773 6988.40028468 1736.15736644

 Left singular vectors (stored columnwise)
 -0.99701678 -0.07692282 0.00635843
 0.07612665 -0.99359764 -0.08347732
 0.01273903 -0.08274424 0.99648939

 Right singular vectors (stored rowwise)
 -0.99993861 -0.01108052 0.00000001
 -0.01108052 0.99993861 -0.00000082
 0.00000000 0.00000082 1.00000000

5 2 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments

Tex To PDF
: convert the Latex file which suffix is tex to a PDF file

X
0
Would love your thoughts, please comment.x
()
x