|
AbstractLinAlgPack: C++ Interfaces For Vectors, Matrices And Related Linear Algebra Objects Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization 00005 // Copyright (2003) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 // 00029 // C declarations for MA28 functions. These declarations should not have to change 00030 // for different platforms. As long as the fortran object code uses capitalized 00031 // names for its identifers then the declarations in Teuchos_F77_wrappers.h should be 00032 // sufficent for portability. 00033 00034 #ifndef MA28_CPPDECL_H 00035 #define MA28_CPPDECL_H 00036 00037 #include "Teuchos_F77_wrappers.h" 00038 00039 namespace MA28_CppDecl { 00040 00041 // Declarations that will link to the fortran object file. 00042 // These may change for different platforms 00043 00044 using FortranTypes::f_int; // INTEGER 00045 using FortranTypes::f_real; // REAL 00046 using FortranTypes::f_dbl_prec; // DOUBLE PRECISION 00047 using FortranTypes::f_logical; // LOGICAL 00048 00049 extern "C" { 00050 00051 // analyze and factorize a matrix 00052 FORTRAN_FUNC_DECL_UL(void,MA28AD,ma28ad) (const f_int& n, const f_int& nz, f_dbl_prec a[], const f_int& licn 00053 , f_int irn[], const f_int& lirn, f_int icn[], const f_dbl_prec& u, f_int ikeep[], f_int iw[] 00054 , f_dbl_prec w[], f_int* iflag); 00055 00056 // factor using previous analyze 00057 FORTRAN_FUNC_DECL_UL(void,MA28BD,ma28bd) (const f_int& n, const f_int& nz, f_dbl_prec a[], const f_int& licn 00058 , const f_int ivect[], const f_int jvect[], const f_int icn[], const f_int ikeep[], f_int iw[] 00059 , f_dbl_prec w[], f_int* iflag); 00060 00061 // solve for rhs using internally stored factorized matrix 00062 FORTRAN_FUNC_DECL_UL(void,MA28CD,ma28cd) (const f_int& n, const f_dbl_prec a[], const f_int& licn, const f_int icn[] 00063 , const f_int ikeep[], f_dbl_prec rhs[], f_dbl_prec w[], const f_int& mtype); 00064 00065 // ///////////////////////////////////////////////////////////////////////////////////////// 00066 // Declare structs that represent the MA28 common blocks. 00067 // These are the common block variables that are ment to be accessed by the user 00068 // Some are used to set the options of MA28 and others return information 00069 // about the attempts to solve the system. 00070 // I want to provide the access functions that allow all of those common block 00071 // variables that are ment to be accessed by the user to be accessable. 00072 // For each of the common data items there will be a get operation that 00073 // returns the variable value. For those items that are ment to be 00074 // set by the user there will also be set operations. 00075 00076 // COMMON /MA28ED/ LP, MP, LBLOCK, GROW 00077 // INTEGER LP, MP 00078 // LOGICAL LBLOCK, GROW 00079 struct MA28ED_struct { 00080 f_int lp; 00081 f_int mp; 00082 f_logical lblock; 00083 f_logical grow; 00084 }; 00085 extern MA28ED_struct FORTRAN_NAME_UL(MA28ED,ma28ed); // link to fortan common block 00086 00087 // COMMON /MA28FD/ EPS, RMIN, RESID, IRNCP, ICNCP, MINIRN, MINICN, 00088 // * IRANK, ABORT1, ABORT2 00089 // INTEGER IRNCP, ICNCP, MINIRN, MINICN, IRANK 00090 // LOGICAL ABORT1, ABORT2 00091 // REAL EPS, RMIN, RESID 00092 struct MA28FD_struct { 00093 f_dbl_prec eps; 00094 f_dbl_prec rmin; 00095 f_dbl_prec resid; 00096 f_int irncp; 00097 f_int icncp; 00098 f_int minirn; 00099 f_int minicn; 00100 f_int irank; 00101 f_logical abort1; 00102 f_logical abort2; 00103 }; 00104 extern MA28FD_struct FORTRAN_NAME_UL(MA28FD,ma28fd); // link to fortan common block 00105 00106 00107 // COMMON /MA28GD/ IDISP 00108 // INTEGER IDISP 00109 struct MA28GD_struct { 00110 f_int idisp[2]; 00111 }; 00112 extern MA28GD_struct FORTRAN_NAME_UL(MA28GD,ma28gd); // link to fortan common block 00113 00114 // COMMON /MA28HD/ TOL, THEMAX, BIG, DXMAX, ERRMAX, DRES, CGCE, 00115 // * NDROP, MAXIT, NOITER, NSRCH, ISTART, LBIG 00116 // INTEGER NDROP, MAXIT, NOITER, NSRCH, ISTART 00117 // LOGICAL LBIG 00118 // REAL TOL, THEMAX, BIG, DXMAX, ERRMAX, DRES, CGCE 00119 struct MA28HD_struct { 00120 f_dbl_prec tol; 00121 f_dbl_prec themax; 00122 f_dbl_prec big; 00123 f_dbl_prec dxmax; 00124 f_dbl_prec errmax; 00125 f_dbl_prec dres; 00126 f_dbl_prec cgce; 00127 f_int ndrop; 00128 f_int maxit; 00129 f_int noiter; 00130 f_int nsrch; 00131 f_int istart; 00132 f_logical lbig; 00133 }; 00134 extern MA28HD_struct FORTRAN_NAME_UL(MA28HD,ma28hd); // link to fortan common block 00135 00136 // COMMON /MA30ED/ LP, ABORT1, ABORT2, ABORT3 00137 // INTEGER LP 00138 // LOGICAL ABORT1, ABORT2, ABORT3 00139 struct MA30ED_struct { 00140 f_int lp; 00141 f_logical abort1; 00142 f_logical abort2; 00143 f_logical abort3; 00144 }; 00145 extern MA30ED_struct FORTRAN_NAME_UL(MA30ED,ma30ed); // link to fortan common block 00146 00147 // COMMON /MA30FD/ IRNCP, ICNCP, IRANK, IRN, ICN 00148 // INTEGER IRNCP, ICNCP, IRANK, IRN, ICN 00149 struct MA30FD_struct { 00150 f_int irncp; 00151 f_int icncp; 00152 f_int irank; 00153 f_int minirn; 00154 f_int minicn; 00155 }; 00156 extern MA30FD_struct FORTRAN_NAME_UL(MA30FD,ma30fd); // link to fortan common block 00157 00158 // COMMON /MA30GD/ EPS, RMIN 00159 // DOUBLE PRECISION EPS, RMIN 00160 struct MA30GD_struct { 00161 f_dbl_prec eps; 00162 f_dbl_prec rmin; 00163 }; 00164 extern MA30GD_struct FORTRAN_NAME_UL(MA30GD,ma30gd); // link to fortan common block 00165 00166 // COMMON /MA30HD/ RESID 00167 // DOUBLE PRECISION RESID 00168 struct MA30HD_struct { 00169 f_dbl_prec resid; 00170 }; 00171 extern MA30HD_struct FORTRAN_NAME_UL(MA30HD,ma30hd); // link to fortan common block 00172 00173 // COMMON /MA30ID/ TOL, BIG, NDROP, NSRCH, LBIG 00174 // INTEGER NDROP, NSRCH 00175 // LOGICAL LBIG 00176 // DOUBLE PRECISION TOL, BIG 00177 struct MA30ID_struct { 00178 f_dbl_prec tol; 00179 f_dbl_prec big; 00180 f_int ndrop; 00181 f_int nsrch; 00182 f_logical lbig; 00183 }; 00184 extern MA30ID_struct FORTRAN_NAME_UL(MA30ID,ma30id); // link to fortan common block 00185 00186 // COMMON /MC23BD/ LP,NUMNZ,NUM,LARGE,ABORT 00187 // INTEGER LP, NUMNZ, NUM, LARGE 00188 // LOGICAL ABORT 00189 struct MC23BD_struct { 00190 f_int lp; 00191 f_int numnz; 00192 f_int num; 00193 f_int large; 00194 f_logical abort; 00195 }; 00196 extern MC23BD_struct FORTRAN_NAME_UL(MC23BD,mc23bd); // link to fortan common block 00197 00198 00199 } // end extern "C" 00200 00201 00202 /* * @name {\bf MA28 C++ Declarations}. 00203 * 00204 * These the C++ declarations for MA28 functions and common block data. 00205 * These declarations will not change for different platforms. 00206 * All of these functions are in the C++ namespace #MA28_CppDecl#. 00207 * 00208 * These functions perform the three phases that are normally associated 00209 * with solving sparse systems of linear equations; analyze (and factorize) 00210 * , factorize, and solve. The MA28 interface uses a coordinate format 00211 * (aij, i, j) for the sparse matrix. 00212 * 00213 * There are three interface routienes that perform these steps: 00214 * \begin{description} 00215 * \item[#ma28ad#] Analyzes and factorizes a sparse matrix stored in #a#, #irn# 00216 * , #icn# and returns the factorized matrix data structures in #a#, #icn# 00217 * , and #ikeep#. 00218 * \item[#ma28bd#] Factorizes a matrix with the same sparsity structure that was 00219 * previously factorized by #ma28ad#. Information about the row and column 00220 * permutations, fill-in elements etc. from the previous analyze and factorization 00221 * is passed in the arguments #icn#, and #ikeep#. The matrix to be 00222 * factorized is passed in #a#, #ivect#, and #jvect# and the non-zero 00223 * elements of the factorization are returned in #a#. 00224 * \item[#ma28cd#] Solves for a dense right hand side (rhs) given a matrix factorized 00225 * by #ma28ad# or #ma28bd#. The rhs is passed in #rhs# and the solution 00226 * is returned in #rhs#. The factorized matrix is passed in by #a#, #icn# 00227 * and #ikeep#. The transposed or the non-transposed system can be solved 00228 * for by passing in #mtype != 1# and #mtype == 1# respectively. 00229 */ 00230 00231 // @{ 00232 // begin MA28 C++ Declarations 00233 00234 /* * @name {\bf MA28 / MA30 Common Block Access}. 00235 * 00236 * These are references to structures that allow C++ users to set and retrive 00237 * values of the MA28xD and MA30xD common blocks. Some of the common block 00238 * items listed below for MA28xD are also present in MA30xD. The control 00239 * parameters (abort1, eps, etc.) for MA28xD are transfered to the equivalent 00240 * common block variables in the #ma28ad# function but not in any of the other 00241 * functions. 00242 * 00243 * The internal states for MA28, MA30, and MC23 are determined by the 00244 * values in these common block variables as there are no #SAVE# variables 00245 * in any of the functions. So to use MA28 with more than 00246 * one sparse matrix at a time you just have to keep copies of these 00247 * common block variable for each system and then set them when every 00248 * you want to work with that system agian. This is very good news. 00249 * 00250 * These common block variables are: 00251 * \begin{description} 00252 * \item[lp, mp] 00253 * Integer: Used by the subroutine as the unit numbers for its warning 00254 * and diagnostic messages. Default value for both is 6 (for line 00255 * printer output). the user can either reset them to a different 00256 * stream number or suppress the output by setting them to zero. 00257 * While #lp# directs the output of error diagnostics from the 00258 * principal subroutines and internally called subroutines, #mp# 00259 * controls only the output of a message which warns the user that he 00260 * has input two or more non-zeros a(i), . . ,a(k) with the same row 00261 * and column indices. The action taken in this case is to proceed 00262 * using a numerical value of a(i)+...+a(k). in the absence of other 00263 * errors, #iflag# will equal -14 on exit. 00264 * \item[lblock] 00265 * Logical: Controls an option of first 00266 * preordering the matrix to block lower triangular form (using 00267 * harwell subroutine mc23a). The preordering is performed if #lblock# 00268 * is equal to its default value of #true# if #lblock# is set to 00269 * #false# , the option is not invoked and the space allocated to 00270 * #ikeep# can be reduced to 4*n+1. 00271 * \item[grow] 00272 * Logical: If it is left at its default value of 00273 * #true# , then on return from ma28a/ad or ma28b/bd, w(1) will give 00274 * an estimate (an upper bound) of the increase in size of elements 00275 * encountered during the decomposition. If the matrix is well 00276 * scaled, then a high value for w(1), relative to the largest entry 00277 * in the input matrix, indicates that the LU decomposition may be 00278 * inaccurate and the user should be wary of his results and perhaps 00279 * increase u for subsequent runs. We would like to emphasise that 00280 * this value only relates to the accuracy of our LU decomposition 00281 * and gives no indication as to the singularity of the matrix or the 00282 * accuracy of the solution. This upper bound can be a significant 00283 * overestimate particularly if the matrix is badly scaled. If an 00284 * accurate value for the growth is required, #lbig# (q.v.) should be 00285 * set to #true# 00286 * \item[eps, rmin] 00287 * Double Precision: If on entry to ma28b/bd, #eps# is less 00288 * than one, then #rmin# will give the smallest ratio of the pivot to 00289 * the largest element in the corresponding row of the upper 00290 * triangular factor thus monitoring the stability of successive 00291 * factorizations. if rmin becomes very large and w(1) from 00292 * ma28b/bd is also very large, it may be advisable to perform a 00293 * new decomposition using ma28a/ad. 00294 * \item[resid] 00295 * Double Precision: On exit from ma28c/cd gives the value 00296 * of the maximum residual over all the equations unsatisfied because 00297 * of dependency (zero pivots). 00298 * \item[irncp,icncp] 00299 * Integer: Monitors the adequacy of "elbow 00300 * room" in #irn# and #a#/#icn# respectively. If either is quite large (say 00301 * greater than n/10), it will probably pay to increase the size of 00302 * the corresponding array for subsequent runs. if either is very low 00303 * or zero then one can perhaps save storage by reducing the size of 00304 * the corresponding array. 00305 * \item[minirn, minicn] 00306 * Integer: In the event of a 00307 * successful return (#iflag# >= 0 or #iflag# = -14) give the minimum size 00308 * of #irn# and #a#/#icn# respectively which would enable a successful run 00309 * on an identical matrix. On an exit with #iflag# equal to -5, #minicn# 00310 * gives the minimum value of #icn# for success on subsequent runs on 00311 * an identical matrix. in the event of failure with #iflag# = -6, -4, 00312 * -3, -2, or -1, then #minicn# and #minirn# give the minimum value of 00313 * #licn# and #lirn# respectively which would be required for a 00314 * successful decomposition up to the point at which the failure 00315 * occurred. 00316 * \item[irank] 00317 * Integer: Gives an upper bound on the rank of the matrix. 00318 * \item[abort1] 00319 * Logical: Default value #true#. If #abort1# is 00320 * set to #false# then ma28a/ad will decompose structurally singular 00321 * matrices (including rectangular ones). 00322 * \item[abort2] 00323 * Logical: Default value #true#. If #abort2# is 00324 * set to #false# then ma28a/ad will decompose numerically singular 00325 * matrices. 00326 * \item[idisp] 00327 * Integer[2]: On output from ma28a/ad, the 00328 * indices of the diagonal blocks of the factors lie in positions 00329 * idisp(1) to idisp(2) of #a#/#icn#. This array must be preserved 00330 * between a call to ma28a/ad and subsequent calls to ma28b/bd, 00331 * ma28c/cd or ma28i/id. 00332 * \item[tol] 00333 * Double Precision: If it is set to a positive value, then any 00334 * non-zero whose modulus is less than #tol# will be dropped from the 00335 * factorization. The factorization will then require less storage 00336 * but will be inaccurate. After a run of ma28a/ad with #tol# positive 00337 * it is not possible to use ma28b/bd and the user is recommended to 00338 * use ma28i/id to obtain the solution. The default value for #tol# is 00339 * 0.0. 00340 * \item[themax] 00341 * Double Precision: On exit from ma28a/ad, it will hold the 00342 * largest entry of the original matrix. 00343 * \item[big] 00344 * Double Precision: If #lbig# has been set to #true#, #big# will hold 00345 * the largest entry encountered during the factorization by ma28a/ad 00346 * or ma28b/bd. 00347 * \item[dxmax] 00348 * Double Precision: On exit from ma28i/id, #dxmax# will be set to 00349 * the largest component of the solution. 00350 * \item[errmax] 00351 * Double Precision: On exit from ma28i/id, If #maxit# is 00352 * positive, #errmax# will be set to the largest component in the 00353 * estimate of the error. 00354 * \item[dres] 00355 * Double Precision: On exit from ma28i/id, if #maxit# is positive, 00356 * #dres# will be set to the largest component of the residual. 00357 * \item[cgce] 00358 * Double Precision: It is used by ma28i/id to check the 00359 * convergence rate. if the ratio of successive corrections is 00360 * not less than #cgce# then we terminate since the convergence 00361 * rate is adjudged too slow. 00362 * \item[ndrop] 00363 * Integer: If #tol# has been set positive, on exit 00364 * from ma28a/ad, #ndrop# will hold the number of entries dropped from 00365 * the data structure. 00366 * \item[maxit] 00367 * Integer: It is the maximum number of iterations 00368 * performed by ma28i/id. It has a default value of 16. 00369 * \item[noiter] 00370 * Integer: It is set by ma28i/id to the number of 00371 * iterative refinement iterations actually used. 00372 * \item[nsrch] 00373 * Integer: If #nsrch# is set to a value less than #n#, 00374 * then a different pivot option will be employed by ma28a/ad. This 00375 * may result in different fill-in and execution time for ma28a/ad. 00376 * If #nsrch# is less than or equal to #n#, the workspace array #iw# can be 00377 * reduced in length. The default value for nsrch is 32768. 00378 * \item[istart] 00379 * Integer: If #istart# is set to a value other than 00380 * zero, then the user must supply an estimate of the solution to 00381 * ma28i/id. The default value for istart is zero. 00382 * \item[lbig] 00383 * Logical: If #lbig# is set to #true#, the value of the 00384 * largest element encountered in the factorization by ma28a/ad or 00385 * ma28b/bd is returned in #big#. setting #lbig# to #true# will 00386 * increase the time for ma28a/ad marginally and that for ma28b/bd 00387 * by about 20%. The default value for #lbig# is #false#. 00388 */ 00389 00390 // @{ 00391 // begin MA28 Common Block Access 00392 00393 // / Common block with members: #lp#, #mp#, #lblock#, #grow# 00394 static MA28ED_struct &ma28ed_cb = FORTRAN_COMMMON_BLOCK_NAME_UL(MA28ED,ma28ed); 00395 // / Common block with members: #eps#, #rmin#, #resid#, #irncp#, #icncp#, #minirc#, #minicn#, #irank#, #abort1#, #abort2# 00396 static MA28FD_struct &ma28fd_cb = FORTRAN_COMMMON_BLOCK_NAME_UL(MA28FD,ma28fd); 00397 // / Common block with members: #idisp# 00398 static MA28GD_struct &ma28gd_cb = FORTRAN_COMMMON_BLOCK_NAME_UL(MA28GD,ma28gd); 00399 // / Common block with members: #tol#, #themax#, #big#, #bxmax#, #errmax#, #dres#, #cgce#, #ndrop#, #maxit#, #noiter#, #nsrch#, #istart#, #lbig# 00400 static MA28HD_struct &ma28hd_cb = FORTRAN_COMMMON_BLOCK_NAME_UL(MA28HD,ma28hd); 00401 // / Common block with members: #lp#, #abort1#, #abort2#, #abort3# 00402 static MA30ED_struct &ma30ed_cb = FORTRAN_COMMMON_BLOCK_NAME_UL(MA30ED,ma30ed); 00403 // / Common block with members: #irncp#, #icncp#, #irank#, #irn#, #icn# 00404 static MA30FD_struct &ma30fd_cb = FORTRAN_COMMMON_BLOCK_NAME_UL(MA30FD,ma30fd); 00405 // / Common block with members: #eps#, #rmin# 00406 static MA30GD_struct &ma30gd_cb = FORTRAN_COMMMON_BLOCK_NAME_UL(MA30GD,ma30gd); 00407 // / Common block with members: #resid# 00408 static MA30HD_struct &ma30hd_cb = FORTRAN_COMMMON_BLOCK_NAME_UL(MA30HD,ma30hd); 00409 // / Common block with members: #tol#, #big#, #ndrop#, #nsrch#, #lbig# 00410 static MA30ID_struct &ma30id_cb = FORTRAN_COMMMON_BLOCK_NAME_UL(MA30ID,ma30id); 00411 // / Common block with members: #lp#, #numnz#, #num#, #large#, #abort# 00412 static MC23BD_struct &mc23bd_cb = FORTRAN_COMMMON_BLOCK_NAME_UL(MC23BD,mc23bd); 00413 00414 // The reason that these are declared static is because I need to 00415 // make sure that these references are initialized before they are 00416 // used in other global defintions. This means that every translation 00417 // unit will have their own copy of this data. To reduce this code 00418 // blot you could declair them as pointers then set then using the 00419 // trick of an initialization class (Myers). 00420 00421 // end MA28 Common Block Access 00422 // @} 00423 00424 // / 00425 /* * Analyze and factor a sparse matrix. 00426 * 00427 * This function analyzes (determines row and column pivots to minimize 00428 * fill-in and result in a better conditioned factorization) then factors 00429 * (calculates upper and lower triangular factors for the determined 00430 * row and column pivots) the permuted system. The function takes a sparse 00431 * matrix stored in coordinate form ([Aij, i, j] => [#a#, #irn#, #icn#]) and 00432 * factorizes it. On entry, the first #nz# elements of #a#, #irn#, and 00433 * #icn# hold the matrix elements. The remaining entires of #a#, #irn# 00434 * , and #icn# hold the fill-in entries after the matrix factorization is 00435 * complete. 00436 * 00437 * The amount of fill-in is influenced by #u#. A value of #u = 1.0# gives partial 00438 * pivoting where fill-in is sacrificed for the sake of numerical stability and 00439 * #u = 0.0# gives pivoting that strictly minimizes fill-in. 00440 * 00441 * The parameters #ikeep#, #iw#, and #w# are used as workspace but 00442 * #ikeep# contains important information about the factoriation 00443 * on return. 00444 * 00445 * The parameter #iflag# is used return error information about the attempt 00446 * to factorized the system. 00447 * 00448 * @param n [input] Order of the system being solved. 00449 * @param nz [input] Number of non-zeros of the input matrix (#nz >= n#). 00450 * The ratio #nz/(n*n)# equals the sparsity fraction for the matrix. 00451 * @param a [input/output] Length = #licn#. The first #nz# entries hold the 00452 * non-zero entries of the input matrix on input and 00453 * the non-zero entries of the factorized matrix on exit. 00454 * @param licn [input] length of arrays #a# and #icn#. This 00455 * is the total amount of storage advalable for the 00456 * non-zero entries of the factorization of #a#. 00457 * therefore #licn# must be greater than #nz#. How 00458 * much greater depends on the amount of fill-in. 00459 * @param irn [input/modifed] Length = #ircn#. The first #nz# entries hold 00460 * the row indices of the matrix #a# on input. 00461 * @param ircn [input] Lenght of irn. 00462 * @param icn [input/output] Length = #licn#. Holds column indices of #a# on 00463 * entry and the column indices of the reordered 00464 * #a# on exit. 00465 * @param u [input] Controls partial pivoting. 00466 * \begin{description} 00467 * \item[#* u >= 1.0#] 00468 * Uses partial pivoting for maximum numerical stability 00469 * at the expense of some extra fill-in. 00470 * \item[#* 1.0 < u < 0.0#] 00471 * Balances numerical stability and fill-in with #u# near 1.0 00472 * favoring stability and #u# near 0.0 favoring less fill-in. 00473 * \item[#* u <= 0.0#] 00474 * Determines row and column pivots to minimize fill-in 00475 * irrespective of the numerical stability of the 00476 * resulting factorization. 00477 * \end{description} 00478 * @param ikeep [output] Length = 5 * #n#. On exist contains information about 00479 * the factorization. 00480 * \begin{description} 00481 * \item[#* #ikeep(:,1)] 00482 * Holds the total length of the part of row i in 00483 * the diagonal block. 00484 * \item[#* #ikeep(:,2)] 00485 * Holds the row pivots. Row #ikeep(i,2)# of the 00486 * input matrix is the ith row of the pivoted matrix 00487 * which is factorized. 00488 * \item[#* #ikeep(:,3)] 00489 * Holds the column pivots. Column #ikeep(i,3)# of the 00490 * input matrix is the ith column of the pivoted matrix 00491 * which is factorized. 00492 * \item[#* #ikeep(:,4)] 00493 * Holds the length of the part of row i in the L 00494 * part of the L/U decomposition. 00495 * \item[#* #ikeep(:,5)] 00496 * Holds the length of the part of row i in the 00497 * off-diagonal blocks. If there is only one 00498 * diagonal block, #ikeep(i,5)# is set to -1. 00499 * \end{description} 00500 * @param iw [] Length = #8*n#. Integer workspace. 00501 * @param w [] Length = #n#. Real workspace. 00502 * @param iflag [output] Used to return error condtions. 00503 * \begin{description} 00504 * \item[#* >= 0#] Success. 00505 * \item[#* < 0#] Some error has occured. 00506 * \end{description} 00507 */ 00508 inline void ma28ad(const f_int& n, const f_int& nz, f_dbl_prec a[], const f_int& licn 00509 , f_int irn[], const f_int& lirn, f_int icn[], const f_dbl_prec& u, f_int ikeep[], f_int iw[] 00510 , f_dbl_prec w[], f_int* iflag) 00511 { FORTRAN_FUNC_CALL_UL(MA28AD,ma28ad) (n,nz,a,licn,irn,lirn,icn,u,ikeep,iw,w,iflag); } 00512 00513 // / 00514 /* * Factor a sparse matrix using previous analyze pivots. 00515 * 00516 * This function uses the pivots determined from a previous factorization 00517 * to factorize the matrix #a# again. The assumption is that the 00518 * sparsity structure of #a# has not changed but only its numerical 00519 * values. It is therefore possible that the refactorization may 00520 * become unstable. 00521 * 00522 * The matrix to be refactorized on order #n# with #nz# non-zero elements 00523 * is input in coordinate format in #a#, #ivect# and #jvect#. 00524 * 00525 * Information about the factorization is contained in the #icn# and 00526 * #ikeep# arrays returned from \Ref{ma28ad}. 00527 * 00528 * @param n [input] Order of the system being solved. 00529 * @param nz [input] Number of non-zeros of the input matrix 00530 * @param a [input/output] Length = #licn#. The first #nz# entries hold the 00531 * non-zero entries of the input matrix on input and 00532 * the non-zero entries of the factorized matrix on exit. 00533 * @param licn [input] length of arrays #a# and #icn#. This 00534 * is the total amount of storage avalable for the 00535 * non-zero entries of the factorization of #a#. 00536 * therefore #licn# must be greater than #nz#. How 00537 * much greater depends on the amount of fill-in. 00538 * @param icn [input] Length = #licn#. Same array output from #ma28ad#. 00539 * It contains information about the analyze step. 00540 * @param ikeep [input] Length = 5 * #n#. Same array output form #ma28ad#. 00541 * It contains information about the analyze step. 00542 * @param iw [] Length = #8*n#. Integer workspace. 00543 * @param w [] Length = #n#. Real workspace. 00544 * @param iflag [output] Used to return error condtions. 00545 * \begin{description} 00546 * \item[#* >= 0#] Success 00547 * \item[#* < 0#] Some error has occured. 00548 * \end{description} 00549 */ 00550 inline void ma28bd(const f_int& n, const f_int& nz, f_dbl_prec a[], const f_int& licn 00551 , const f_int ivect[], const f_int jvect[], const f_int icn[], const f_int ikeep[], f_int iw[] 00552 , f_dbl_prec w[], f_int* iflag) 00553 { FORTRAN_FUNC_CALL_UL(MA28BD,ma28bd) (n,nz,a,licn,ivect,jvect,icn,ikeep,iw,w,iflag); } 00554 00555 // / 00556 /* * Solve for a rhs using a factorized matrix. 00557 * 00558 * This function solves for a rhs given a matrix factorized by 00559 * #ma28ad# or #ma28bd#. The right hand side (rhs) is passed 00560 * in in #rhs# and the solution is return in #rhs#. The 00561 * factorized matrix is passed in in #a#, #icn#, and #ikeep# 00562 * which were set by #ma28ad# and/or #ma28bd#. The 00563 * 00564 * The matrix or its transpose can be solved for by selecting 00565 * #mtype == 1# or #mtype != 1# respectively. 00566 * 00567 * @param n [input] Order of the system being solved. 00568 * @param a [input] Length = #licn#. Contains the non-zero 00569 * elements of the factorized matrix. 00570 * @param licn [input] length of arrays #a# and #icn#. This 00571 * is the total amount of storage avalable for the 00572 * non-zero entries of the factorization of #a#. 00573 * therefore #licn# must be greater than #nz#. How 00574 * much greater depends on the amount of fill-in. 00575 * @param icn [input] Length = #licn#. Same array output from #ma28ad#. 00576 * It contains information about the analyze step. 00577 * @param ikeep [input] Length = 5 * #n#. Same array output form #ma28ad#. 00578 * It contains information about the analyze step. 00579 * @param w [] Length = #n#. Real workspace. 00580 * @param mtype [input] Instructs to solve using the matrix or its transpoze. 00581 * \begin{description} 00582 * \item[#* mtype == 1#] Solve using the non-transposed matrix. 00583 * \item[#* mtype != 1#] Solve using the transposed matrix. 00584 * \end{description} 00585 */ 00586 inline void ma28cd(const f_int& n, const f_dbl_prec a[], const f_int& licn, const f_int icn[] 00587 , const f_int ikeep[], f_dbl_prec rhs[], f_dbl_prec w[], const f_int& mtype) 00588 { FORTRAN_FUNC_CALL_UL(MA28CD,ma28cd) (n,a,licn,icn,ikeep,rhs,w,mtype); } 00589 00590 // end MA28 C++ Declarations 00591 // @} 00592 00593 } // end namespace MA28_CDecl 00594 00595 #endif // MA28_CPPDECL_H
1.7.4