- FFT.f90: Replace hand-written Cooley-Tukey FFT with oneMKL DFTI - ilucg.f90: Replace manual dot product loop with BLAS DDOT - gaussj.C: Replace Gauss-Jordan elimination with LAPACK dgesv/dgetri - makefile.inc: Add MKL include paths and library linking All optimizations maintain mathematical equivalence and numerical precision.
107 lines
2.7 KiB
C
107 lines
2.7 KiB
C
|
|
#ifdef newc
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <fstream>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <cmath>
|
|
using namespace std;
|
|
#else
|
|
#include <iostream.h>
|
|
#include <iomanip.h>
|
|
#include <fstream.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#endif
|
|
|
|
// Intel oneMKL LAPACK interface
|
|
#include <mkl_lapacke.h>
|
|
/* Linear equation solution using Intel oneMKL LAPACK.
|
|
a[0..n-1][0..n-1] is the input matrix. b[0..n-1] is input
|
|
containing the right-hand side vectors. On output a is
|
|
replaced by its matrix inverse, and b is replaced by the
|
|
corresponding set of solution vectors.
|
|
|
|
Mathematical equivalence:
|
|
Solves: A * x = b => x = A^(-1) * b
|
|
Original Gauss-Jordan and LAPACK dgesv/dgetri produce identical results
|
|
within numerical precision. */
|
|
|
|
int gaussj(double *a, double *b, int n)
|
|
{
|
|
// Allocate pivot array and workspace
|
|
lapack_int *ipiv = new lapack_int[n];
|
|
lapack_int info;
|
|
|
|
// Make a copy of matrix a for solving (dgesv modifies it to LU form)
|
|
double *a_copy = new double[n * n];
|
|
for (int i = 0; i < n * n; i++) {
|
|
a_copy[i] = a[i];
|
|
}
|
|
|
|
// Step 1: Solve linear system A*x = b using LU decomposition
|
|
// LAPACKE_dgesv uses column-major by default, but we use row-major
|
|
info = LAPACKE_dgesv(LAPACK_ROW_MAJOR, n, 1, a_copy, n, ipiv, b, 1);
|
|
|
|
if (info != 0) {
|
|
cout << "gaussj: Singular Matrix (dgesv info=" << info << ")" << endl;
|
|
delete[] ipiv;
|
|
delete[] a_copy;
|
|
return 1;
|
|
}
|
|
|
|
// Step 2: Compute matrix inverse A^(-1) using LU factorization
|
|
// First do LU factorization of original matrix a
|
|
info = LAPACKE_dgetrf(LAPACK_ROW_MAJOR, n, n, a, n, ipiv);
|
|
|
|
if (info != 0) {
|
|
cout << "gaussj: Singular Matrix (dgetrf info=" << info << ")" << endl;
|
|
delete[] ipiv;
|
|
delete[] a_copy;
|
|
return 1;
|
|
}
|
|
|
|
// Then compute inverse from LU factorization
|
|
info = LAPACKE_dgetri(LAPACK_ROW_MAJOR, n, a, n, ipiv);
|
|
|
|
if (info != 0) {
|
|
cout << "gaussj: Singular Matrix (dgetri info=" << info << ")" << endl;
|
|
delete[] ipiv;
|
|
delete[] a_copy;
|
|
return 1;
|
|
}
|
|
|
|
delete[] ipiv;
|
|
delete[] a_copy;
|
|
|
|
return 0;
|
|
}
|
|
// for check usage
|
|
/*
|
|
int main()
|
|
{
|
|
double *A,*b;
|
|
A=new double[9];
|
|
b=new double[3];
|
|
|
|
A[0]=0.5; A[1]=1.0/3; A[2]=1;
|
|
A[3]=1; A[4]=5.0/3; A[5]=3;
|
|
A[6]=2; A[7]=4.0/3; A[8]=5;
|
|
|
|
b[0]=1; b[1]=3; b[2]=2;
|
|
|
|
cout<<"initial data:"<<endl;
|
|
for(int i=0;i<3;i++) cout<<A[i*3]<<" "<<A[i*3+1]<<" "<<A[i*3+2]<<" "<<b[i]<<endl;
|
|
|
|
gaussj(A, b, 3);
|
|
|
|
cout<<"final data:"<<endl;
|
|
for(int i=0;i<3;i++) cout<<A[i*3]<<" "<<A[i*3+1]<<" "<<A[i*3+2]<<" "<<b[i]<<endl;
|
|
|
|
delete[] A; delete[] b;
|
|
}
|
|
*/
|