2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2011 - Scilab Enterprises - Adeline CARNIS
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
13 #include "eigs_dependencies.h"
15 // dgemm performs one of the matrix-matrix operations
16 extern int C2F(dgemm)(char* transa, char* transb, int* m, int* n, int* k, double* alpha, double* A, int* lda, double* B, int* ldb, double* beta, double* C, int* ldc);
18 // dgetrf computes an LU factorization of a general M by N matrix A (double) using partial pivoting with row interchanges
19 extern int C2F(dgetrf)(int* m, int* n, double* A, int* lda, int* ipiv, int* info);
21 // dgetri computes the inverse of a matrix using the LU factorization computed by dgetrf
22 extern int C2F(dgetri)(int* n, double* A, int* lda, int* ipiv, double* work, int* lworkl, int* info);
24 // zgemm performs one of the matrix-matrix operations
25 extern int C2F(zgemm)(char* transa, char* transb, int* m, int* n, int* k, doublecomplex* alpha, doublecomplex* A, int* lda,
26 doublecomplex* B, int* ldb, doublecomplex* beta, doublecomplex* C, int* ldc);
28 // zgetrd computes an LU factorization of a general M by N matrix A (complex*16) using partial pivoting with row interchanges
29 extern int C2F(zgetrf)(int* m, int* n, doublecomplex* A, int* lda, int* ipiv, int* info);
31 // zgetri computes the inverse of a matrix using the LU factorization computed by zgetrf
32 extern int C2F(zgetri)(int* n, doublecomplex* A, int* lda, int* ipiv, doublecomplex* work, int* lworkl, int* info);
34 static double alpha = 1.;
35 static double beta = 0.;
37 static doublecomplex alphac = {1.,0.};
38 static doublecomplex betac = {0.,0.};
40 void RtimesRprime(double* result, double* R, double* Rprime, int N)
42 C2F(dgemm)("n", "n", &N, &N, &N, &alpha, R, &N, Rprime, &N, &beta, result, &N);
45 void invR_times_A_times_invRprime(double* result, double* R, double* A, double* Rprime, int N)
47 double* invRxA = NULL;
51 double* invRprime = NULL;
54 invRxA = (double*)malloc(N * N * sizeof(double));
55 invR = (double*)malloc(N * N * sizeof(double));
56 invRprime = (double*)malloc(N * N * sizeof(double));
57 work = (double*)malloc(N * N * sizeof(double));
60 IPVT = (int*) malloc(N * sizeof(int));
61 memset(IPVT, 0, N * sizeof(int));
64 memcpy(invR, R, N * N * sizeof(double)); // copy R to invR
65 C2F(dgetrf)(&N, &N, invR ,&N, IPVT, &INFO_LU); // LU decomposition
67 memset(work, 0, N * N * sizeof(double));
68 C2F(dgetri)(&N, invR, &N, IPVT, work, &N, &INFO_LU); // Obtain inverse matrix R
71 memset(IPVT, 0, N * sizeof(int));
72 memcpy(invRprime, Rprime, N * N * sizeof(double));
73 C2F(dgetrf)(&N, &N, invRprime, &N, IPVT, &INFO_LU); // LU decomposition
75 memset(work, 0, N * N * sizeof(double));
76 C2F(dgetri)(&N, invRprime, &N, IPVT, work, &N,&INFO_LU); // Obtain inverse matrix Rprime
78 C2F(dgemm)("n", "n", &N, &N, &N, &alpha, invR, &N, A, &N, &beta, invRxA, &N);
80 C2F(dgemm)("n", "n", &N, &N, &N, &alpha, invRxA, &N, invRprime, &N, &beta, result, &N);
89 void invU_times_invL_times_E(double* result, double* U, double* L, double* E, int N)
91 double* invUxinvL = NULL;
98 invUxinvL = (double*)malloc(N * N * sizeof(double));
99 invU = (double*)malloc(N * N * sizeof(double));
100 invL = (double*)malloc(N * N* sizeof(double));
101 work = (double*)malloc(N * N * sizeof(double));
103 IPVT = (int*) malloc(N * sizeof(int));
104 memset(IPVT, 0, N * sizeof(int));
106 // inv L -> L obtained with LU decomposition
107 memcpy(invL, L, N * N * sizeof(double));
108 C2F(dgetrf)(&N, &N, invL, &N, IPVT, &INFO_LU); // LU decomposition
110 memset(work, 0, N * N * sizeof(double));
111 C2F(dgetri)(&N, invL, &N, IPVT, work, &N, &INFO_LU); // inv(L)
113 // inv U -> U obtained with LU decomposition
114 memcpy(invU, U, N * N * sizeof(double));
115 memset(IPVT, 0, N*sizeof(int));
116 C2F(dgetrf)(&N, &N, invU, &N, IPVT, &INFO_LU); // LU decomposition
118 memset(work, 0, N * N * sizeof(double));
119 C2F(dgetri)(&N, invU, &N, IPVT, work, &N, &INFO_LU); // inv(U)
121 C2F(dgemm)("n", "n", &N, &N, &N, &alpha, invU, &N, invL, &N, &beta, invUxinvL, &N);
123 C2F(dgemm)("n", "n", &N, &N, &N, &alpha, invUxinvL, &N, E, &N, &beta, result, &N);
133 void RCtimesRCprime(doublecomplex* result, doublecomplex* R, doublecomplex* Rprime, int N)
135 C2F(zgemm)("n", "n", &N, &N, &N, &alphac, R, &N, Rprime, &N, &betac, result, &N);
138 void invRC_times_AC_times_invRCprime(doublecomplex* result, doublecomplex* R, doublecomplex* A, doublecomplex* Rprime, int N)
140 doublecomplex* invRxA = NULL;
142 doublecomplex* work = NULL;
143 doublecomplex* invR = NULL;
144 doublecomplex* invRprime = NULL;
147 invRxA = (doublecomplex*)malloc(N * N * sizeof(doublecomplex));
148 invR = (doublecomplex*)malloc(N * N * sizeof(doublecomplex));
149 invRprime = (doublecomplex*)malloc(N * N * sizeof(doublecomplex));
150 work = (doublecomplex*)malloc(N * N * sizeof(doublecomplex));
153 IPVT = (int*) malloc(N * sizeof(int));
154 memset(IPVT, 0, N * sizeof(int));
157 memcpy(invR, R, N * N * sizeof(doublecomplex)); // copy R to invR
158 C2F(zgetrf)(&N, &N, invR ,&N, IPVT, &INFO_LU); // LU decomposition
160 memset(work, 0, N * N * sizeof(doublecomplex));
161 C2F(zgetri)(&N, invR, &N, IPVT, work, &N, &INFO_LU); // Obtain inverse matrix R
164 memset(IPVT, 0, N * sizeof(int));
165 memcpy(invRprime, Rprime, N * N * sizeof(doublecomplex));
166 C2F(zgetrf)(&N, &N, invRprime, &N, IPVT, &INFO_LU); // LU decomposition
168 memset(work, 0, N * N * sizeof(doublecomplex));
169 C2F(zgetri)(&N, invRprime, &N, IPVT, work, &N,&INFO_LU); // Obtain inverse matrix Rprime
171 C2F(zgemm)("n", "n", &N, &N, &N, &alphac, invR, &N, A, &N, &betac, invRxA, &N);
173 C2F(zgemm)("n", "n", &N, &N, &N, &alphac, invRxA, &N, invRprime, &N, &betac, result, &N);
183 void invUC_times_invLC_times_EC(doublecomplex* result, doublecomplex* U, doublecomplex* L, doublecomplex* E, int N)
185 doublecomplex* invUxinvL = NULL;
187 doublecomplex* work = NULL;
188 doublecomplex* invU = NULL;
189 doublecomplex* invL = NULL;
192 invUxinvL = (doublecomplex*)malloc(N * N * sizeof(doublecomplex));
193 invU = (doublecomplex*)malloc(N * N * sizeof(doublecomplex));
194 invL = (doublecomplex*)malloc(N * N* sizeof(doublecomplex));
195 work = (doublecomplex*)malloc(N * N * sizeof(doublecomplex));
197 IPVT = (int*) malloc(N * sizeof(int));
198 memset(IPVT, 0, N * sizeof(int));
200 // inv L -> L obtained with LU decomposition
201 memcpy(invL, L, N * N * sizeof(doublecomplex));
202 C2F(zgetrf)(&N, &N, invL, &N, IPVT, &INFO_LU); // LU decomposition
204 memset(work, 0, N * N * sizeof(doublecomplex));
205 C2F(zgetri)(&N, invL, &N, IPVT, work, &N, &INFO_LU); // inv(L)
207 // inv U -> U obtained with LU decomposition
208 memcpy(invU, U, N * N * sizeof(doublecomplex));
209 memset(IPVT, 0, N*sizeof(int));
210 C2F(zgetrf)(&N, &N, invU, &N, IPVT, &INFO_LU); // LU decomposition
212 memset(work, 0, N * N * sizeof(doublecomplex));
213 C2F(zgetri)(&N, invU, &N, IPVT, work, &N, &INFO_LU); // inv(U)
215 C2F(zgemm)("n", "n", &N, &N, &N, &alphac, invU, &N, invL, &N, &betac, invUxinvL, &N);
217 C2F(zgemm)("n", "n", &N, &N, &N, &alphac, invUxinvL, &N, E, &N, &betac, result, &N);