00001
00004
00005
00006
00007 #include "cscmatrix.h"
00008
00009 #ifdef HAVE_SUPERLU3_INCLUDES
00010 # include <superlu/slu_ddefs.h>
00011 # include <superlu/supermatrix.h>
00012 # include <superlu/slu_util.h>
00013 #else
00014 # include "superlu/util.h"
00015 # include "superlu/dsp_defs.h"
00016 #endif
00017
00018 #if TBCI_NUMLIB_VERSION >= 20600
00019 # define COLPERM_T_DECLARED
00020 # include "solver/superlu.h"
00021 #endif
00022
00023 #ifdef HAVE_UNISTD_H
00024 #include "unistd.h"
00025 #endif
00026
00027 NAMESPACE_TBCI
00028
00029 int lu_solve(CSCMatrix<double>& M,
00030 Vector<double>& x,
00031 const Vector<double>& rhs,
00032 colperm_t permc_spec,
00033 bool verbose, bool symm)
00034 {
00035 int nrhs = 1;
00036 int m = M.rows();
00037 int n = M.columns();
00038 int nnz = M.size();
00039 double *a= M.dataPointer();
00040 unsigned int *asub= M.rowIndexPointer();
00041 unsigned int *xa = M.columnPointer();
00042
00043 int *perm_r;
00044 int *perm_c;
00045 SuperMatrix A;
00046 SuperMatrix B;
00047 SuperMatrix L;
00048 SuperMatrix U;
00049 int info;
00050
00051 #ifdef HAVE_SUPERLU3_INCLUDES
00052 superlu_options_t slu_opt;
00053 SuperLUStat_t slu_stat;
00054 set_default_options(&slu_opt);
00055 slu_opt.ColPerm = permc_spec;
00056 slu_opt.SymmetricMode = (yes_no_t)symm;
00057 if (symm)
00058 slu_opt.DiagPivotThresh = 0.1;
00059 slu_opt.PrintStat = (yes_no_t)verbose;
00060 StatInit(&slu_stat);
00061 #elif defined(HAVE_UNISTD_H)
00062 int savedstdout = 0;
00063 #endif
00064
00065
00066 x = rhs;
00067 dCreate_CompCol_Matrix(&A, m, n, nnz, a, (int*)asub, (int*)xa, SLU_NC, SLU_D, SLU_GE);
00068 dCreate_Dense_Matrix(&B, m, nrhs, x.get_fortran_vector(), m, SLU_DN, SLU_D, SLU_GE);
00069 if ( !(perm_r = intMalloc(m)) )
00070 ABORT("Malloc fails for perm_r[].");
00071 if ( !(perm_c = intMalloc(n)) )
00072 ABORT("Malloc fails for perm_c[].");
00073
00074 #if defined(HAVE_UNISTD_H) && !defined(HAVE_SUPERLU3_INCLUDES)
00075
00076 if (!verbose) {
00077 savedstdout = dup(STDOUT_FILENO); close(STDOUT_FILENO);
00078 }
00079 #endif
00080 #ifndef HAVE_SUPERLU3_INCLUDES
00081
00082 get_perm_c(permc_spec, &A, perm_c);
00083 #endif
00084
00085
00086 #ifdef HAVE_SUPERLU3_INCLUDES
00087 dgssv(&slu_opt, &A, perm_c, perm_r, &L, &U, &B, &slu_stat, &info);
00088 if (verbose)
00089 StatPrint(&slu_stat);
00090 #else
00091 dgssv(&A, perm_c, perm_r, &L, &U, &B, &info);
00092 #endif
00093 #if defined(HAVE_UNISTD_H) && !defined(HAVE_SUPERLU3_INCLUDES)
00094
00095 if (!verbose) {
00096 dup(savedstdout); close(savedstdout);
00097 }
00098 #endif
00099
00100 if (info != 0) {
00101 fprintf(stderr, "SuperLU: dgssv() error returns INFO= %d\n", info);
00102 if (info > n) {
00103
00104 mem_usage_t mem_usage;
00105 #ifdef HAVE_SUPERLU3_INCLUDES
00106 dQuerySpace(&L, &U, &mem_usage);
00107 #else
00108 int panel_size = sp_ienv(1);
00109 dQuerySpace(&L, &U, panel_size, &mem_usage);
00110 #endif
00111 fprintf(stderr, "SuperLU: Memory allocation of %i bytes failed!\n",
00112 info - n);
00113 fprintf(stderr, " L\\U MB %.3f\ttotal MB needed %.3f\texpansions %d\n",
00114 mem_usage.for_lu/1e6, mem_usage.total_needed/1e6,
00115 mem_usage.expansions);
00116 } else
00117 fprintf(stderr, "SuperLU: Singular factor U(%i,%i) found!\n", info, info);
00118 }
00119
00120 SUPERLU_FREE(perm_r);
00121 SUPERLU_FREE(perm_c);
00122 Destroy_SuperNode_Matrix(&L);
00123 Destroy_CompCol_Matrix(&U);
00124
00125 Destroy_SuperMatrix_Store(&B);
00126 Destroy_SuperMatrix_Store(&A);
00127 #ifdef HAVE_SUPERLU3_INCLUDES
00128 StatFree(&slu_stat);
00129 #endif
00130
00131 return info;
00132 }
00133
00134 #if TBCI_NUMLIB_VERSION < 20600
00135
00138 WEAK(
00139 TVector<double> lu_solve(CSCMatrix<double>& M,
00140 const Vector<double>& rhs,
00141 colperm_t permc_spec,
00142 bool verbose, bool symm)
00143 )
00144 {
00145 TVector<double> x(rhs.size());
00146 const int info = lu_solve(M, (Vector<double>&)x, rhs, permc_spec, verbose, symm);
00147 return x;
00148 }
00149 #endif
00150
00151 NAMESPACE_END