diff --git a/Makefile b/Makefile index a161d1ce..8f4a371b 100644 --- a/Makefile +++ b/Makefile @@ -218,10 +218,15 @@ info_init: .PHONY: lib lib: rm -f ${BIL_LIB_FILE} + touch ${BIL_LIB_FILE} ; @if [ ${SLU_USE} = "YES" ] ; then \ - echo "#define SLU_DIR ${SLU_DIR}" > ${BIL_LIB_FILE} ; \ - else \ - touch ${BIL_LIB_FILE} ; \ + echo "#define SUPERLULIB ${SLU_DIR}" >> ${BIL_LIB_FILE} ; \ + fi + @if [ ${BLAS_USE} = "YES" ] ; then \ + echo "#define BLASLIB ${BLAS_DIR}" >> ${BIL_LIB_FILE} ; \ + fi + @if [ ${LAPACK_USE} = "YES" ] ; then \ + echo "#define LAPACKLIB ${LAPACK_DIR}" >> ${BIL_LIB_FILE} ; \ fi @@ -230,7 +235,7 @@ lib: .PHONY: doc doc: - ( cd doc && ${MAKE} ) + ( ${MAKE} -C doc ) #======================================================================= @@ -238,7 +243,7 @@ doc: .PHONY: base base: - ( cd base && ${MAKE} ) + ( ${MAKE} -C base ) #======================================================================= diff --git a/README b/README index ada67650..8bdbe832 100644 --- a/README +++ b/README @@ -7,7 +7,7 @@ Bil is distributed under the terms of the GNU General Public License (GnuGPL). Bil can be downloaded from the URL - http://perso.lcpc.fr/dangla.patrick/bil + https://github.com/ifsttar/bil Building requirements @@ -30,7 +30,6 @@ List of folders ./bin binaries ./doc documentations ./examples examples of input data files - ./hsl sources from the HSL library ./src sources ./lib libraries diff --git a/base/Sulfaco/Sat b/base/Sulfaco/Sat index 2634d4f7..d7d7a95e 100644 --- a/base/Sulfaco/Sat +++ b/base/Sulfaco/Sat @@ -1,1002 +1,2002 @@ # Models: X-axis(1) Expressions(2) # Labels: r(1) S_r(2) -1.000000e-08 1.141796e-01 -1.007638e-08 1.148560e-01 -1.015333e-08 1.155362e-01 -1.023088e-08 1.162206e-01 -1.030902e-08 1.169088e-01 -1.038775e-08 1.176011e-01 -1.046709e-08 1.182974e-01 -1.054703e-08 1.189978e-01 -1.062759e-08 1.197022e-01 -1.070876e-08 1.204108e-01 -1.079054e-08 1.211233e-01 -1.087296e-08 1.218402e-01 -1.095600e-08 1.225611e-01 -1.103968e-08 1.232862e-01 -1.112399e-08 1.240155e-01 -1.120895e-08 1.247491e-01 -1.129456e-08 1.254869e-01 -1.138082e-08 1.262290e-01 -1.146774e-08 1.269753e-01 -1.155533e-08 1.277261e-01 -1.164358e-08 1.284811e-01 -1.173251e-08 1.292405e-01 -1.182212e-08 1.300043e-01 -1.191241e-08 1.307725e-01 -1.200339e-08 1.315452e-01 -1.209507e-08 1.323223e-01 -1.218745e-08 1.331039e-01 -1.228053e-08 1.338900e-01 -1.237432e-08 1.346806e-01 -1.246883e-08 1.354759e-01 -1.256406e-08 1.362756e-01 -1.266002e-08 1.370800e-01 -1.275671e-08 1.378890e-01 -1.285414e-08 1.387027e-01 -1.295231e-08 1.395210e-01 -1.305124e-08 1.403441e-01 -1.315092e-08 1.411719e-01 -1.325136e-08 1.420044e-01 -1.335257e-08 1.428417e-01 -1.345455e-08 1.436838e-01 -1.355731e-08 1.445308e-01 -1.366085e-08 1.453825e-01 -1.376518e-08 1.462391e-01 -1.387032e-08 1.471007e-01 -1.397625e-08 1.479672e-01 -1.408300e-08 1.488387e-01 -1.419055e-08 1.497150e-01 -1.429894e-08 1.505965e-01 -1.440814e-08 1.514829e-01 -1.451819e-08 1.523744e-01 -1.462907e-08 1.532710e-01 -1.474080e-08 1.541727e-01 -1.485338e-08 1.550795e-01 -1.496683e-08 1.559915e-01 -1.508114e-08 1.569086e-01 -1.519632e-08 1.578310e-01 -1.531238e-08 1.587585e-01 -1.542933e-08 1.596914e-01 -1.554717e-08 1.606295e-01 -1.566591e-08 1.615730e-01 -1.578556e-08 1.625218e-01 -1.590613e-08 1.634760e-01 -1.602761e-08 1.644355e-01 -1.615002e-08 1.654004e-01 -1.627337e-08 1.663709e-01 -1.639765e-08 1.673467e-01 -1.652289e-08 1.683281e-01 -1.664909e-08 1.693150e-01 -1.677624e-08 1.703074e-01 -1.690437e-08 1.713055e-01 -1.703348e-08 1.723091e-01 -1.716357e-08 1.733183e-01 -1.729466e-08 1.743333e-01 -1.742675e-08 1.753539e-01 -1.755985e-08 1.763802e-01 -1.769396e-08 1.774123e-01 -1.782910e-08 1.784501e-01 -1.796527e-08 1.794937e-01 -1.810248e-08 1.805431e-01 -1.824074e-08 1.815984e-01 -1.838005e-08 1.826595e-01 -1.852043e-08 1.837266e-01 -1.866188e-08 1.847995e-01 -1.880441e-08 1.858785e-01 -1.894803e-08 1.869634e-01 -1.909275e-08 1.880543e-01 -1.923857e-08 1.891512e-01 -1.938550e-08 1.902542e-01 -1.953356e-08 1.913633e-01 -1.968275e-08 1.924786e-01 -1.983308e-08 1.935999e-01 -1.998455e-08 1.947274e-01 -2.013718e-08 1.958611e-01 -2.029098e-08 1.970011e-01 -2.044596e-08 1.981473e-01 -2.060211e-08 1.992997e-01 -2.075946e-08 2.004585e-01 -2.091801e-08 2.016236e-01 -2.107778e-08 2.027951e-01 -2.123876e-08 2.039729e-01 -2.140097e-08 2.051572e-01 -2.156442e-08 2.063479e-01 -2.172912e-08 2.075450e-01 -2.189507e-08 2.087486e-01 -2.206230e-08 2.099588e-01 -2.223080e-08 2.111755e-01 -2.240059e-08 2.123988e-01 -2.257167e-08 2.136287e-01 -2.274407e-08 2.148652e-01 -2.291777e-08 2.161083e-01 -2.309281e-08 2.173582e-01 -2.326918e-08 2.186147e-01 -2.344690e-08 2.198779e-01 -2.362598e-08 2.211480e-01 -2.380642e-08 2.224247e-01 -2.398824e-08 2.237083e-01 -2.417145e-08 2.249987e-01 -2.435606e-08 2.262959e-01 -2.454208e-08 2.276001e-01 -2.472953e-08 2.289112e-01 -2.491840e-08 2.302292e-01 -2.510871e-08 2.315541e-01 -2.530048e-08 2.328860e-01 -2.549371e-08 2.342249e-01 -2.568842e-08 2.355708e-01 -2.588462e-08 2.369238e-01 -2.608231e-08 2.382839e-01 -2.628152e-08 2.396511e-01 -2.648224e-08 2.410254e-01 -2.668450e-08 2.424068e-01 -2.688831e-08 2.437955e-01 -2.709367e-08 2.451913e-01 -2.730060e-08 2.465943e-01 -2.750911e-08 2.480046e-01 -2.771921e-08 2.494221e-01 -2.793091e-08 2.508468e-01 -2.814424e-08 2.522790e-01 -2.835919e-08 2.537184e-01 -2.857578e-08 2.551652e-01 -2.879403e-08 2.566194e-01 -2.901395e-08 2.580809e-01 -2.923554e-08 2.595499e-01 -2.945883e-08 2.610263e-01 -2.968382e-08 2.625101e-01 -2.991053e-08 2.640014e-01 -3.013897e-08 2.655002e-01 -3.036916e-08 2.670066e-01 -3.060111e-08 2.685205e-01 -3.083482e-08 2.700418e-01 -3.107033e-08 2.715708e-01 -3.130763e-08 2.731074e-01 -3.154674e-08 2.746515e-01 -3.178768e-08 2.762033e-01 -3.203046e-08 2.777628e-01 -3.227509e-08 2.793298e-01 -3.252159e-08 2.809045e-01 -3.276998e-08 2.824870e-01 -3.302026e-08 2.840771e-01 -3.327245e-08 2.856750e-01 -3.352657e-08 2.872805e-01 -3.378263e-08 2.888939e-01 -3.404065e-08 2.905150e-01 -3.430064e-08 2.921438e-01 -3.456261e-08 2.937805e-01 -3.482658e-08 2.954249e-01 -3.509257e-08 2.970771e-01 -3.536059e-08 2.987372e-01 -3.563066e-08 3.004051e-01 -3.590279e-08 3.020808e-01 -3.617700e-08 3.037644e-01 -3.645330e-08 3.054559e-01 -3.673171e-08 3.071552e-01 -3.701225e-08 3.088624e-01 -3.729493e-08 3.105774e-01 -3.757977e-08 3.123004e-01 -3.786679e-08 3.140313e-01 -3.815600e-08 3.157701e-01 -3.844742e-08 3.175168e-01 -3.874106e-08 3.192714e-01 -3.903695e-08 3.210339e-01 -3.933509e-08 3.228043e-01 -3.963552e-08 3.245827e-01 -3.993823e-08 3.263690e-01 -4.024326e-08 3.281632e-01 -4.055062e-08 3.299654e-01 -4.086033e-08 3.317755e-01 -4.117240e-08 3.335935e-01 -4.148686e-08 3.354194e-01 -4.180371e-08 3.372533e-01 -4.212299e-08 3.390951e-01 -4.244471e-08 3.409448e-01 -4.276888e-08 3.428024e-01 -4.309553e-08 3.446679e-01 -4.342467e-08 3.465413e-01 -4.375633e-08 3.484227e-01 -4.409052e-08 3.503119e-01 -4.442726e-08 3.522090e-01 -4.476657e-08 3.541139e-01 -4.510848e-08 3.560268e-01 -4.545300e-08 3.579474e-01 -4.580015e-08 3.598760e-01 -4.614995e-08 3.618123e-01 -4.650242e-08 3.637565e-01 -4.685758e-08 3.657084e-01 -4.721546e-08 3.676681e-01 -4.757607e-08 3.696356e-01 -4.793943e-08 3.716108e-01 -4.830557e-08 3.735938e-01 -4.867450e-08 3.755845e-01 -4.904626e-08 3.775829e-01 -4.942085e-08 3.795889e-01 -4.979830e-08 3.816026e-01 -5.017864e-08 3.836239e-01 -5.056188e-08 3.856528e-01 -5.094805e-08 3.876893e-01 -5.133716e-08 3.897332e-01 -5.172925e-08 3.917848e-01 -5.212434e-08 3.938438e-01 -5.252244e-08 3.959103e-01 -5.292358e-08 3.979842e-01 -5.332779e-08 4.000655e-01 -5.373508e-08 4.021542e-01 -5.414548e-08 4.042502e-01 -5.455902e-08 4.063535e-01 -5.497572e-08 4.084640e-01 -5.539559e-08 4.105817e-01 -5.581868e-08 4.127067e-01 -5.624500e-08 4.148388e-01 -5.667457e-08 4.169779e-01 -5.710742e-08 4.191241e-01 -5.754358e-08 4.212774e-01 -5.798307e-08 4.234376e-01 -5.842592e-08 4.256047e-01 -5.887215e-08 4.277787e-01 -5.932179e-08 4.299595e-01 -5.977486e-08 4.321470e-01 -6.023139e-08 4.343413e-01 -6.069141e-08 4.365423e-01 -6.115494e-08 4.387498e-01 -6.162202e-08 4.409640e-01 -6.209266e-08 4.431846e-01 -6.256689e-08 4.454116e-01 -6.304475e-08 4.476451e-01 -6.352625e-08 4.498848e-01 -6.401144e-08 4.521309e-01 -6.450033e-08 4.543831e-01 -6.499295e-08 4.566414e-01 -6.548933e-08 4.589058e-01 -6.598951e-08 4.611762e-01 -6.649351e-08 4.634525e-01 -6.700135e-08 4.657346e-01 -6.751308e-08 4.680226e-01 -6.802871e-08 4.703162e-01 -6.854828e-08 4.726155e-01 -6.907182e-08 4.749204e-01 -6.959936e-08 4.772307e-01 -7.013093e-08 4.795464e-01 -7.066656e-08 4.818675e-01 -7.120627e-08 4.841937e-01 -7.175011e-08 4.865252e-01 -7.229811e-08 4.888617e-01 -7.285029e-08 4.912032e-01 -7.340668e-08 4.935496e-01 -7.396733e-08 4.959008e-01 -7.453226e-08 4.982567e-01 -7.510150e-08 5.006172e-01 -7.567509e-08 5.029823e-01 -7.625306e-08 5.053518e-01 -7.683544e-08 5.077256e-01 -7.742228e-08 5.101038e-01 -7.801359e-08 5.124860e-01 -7.860942e-08 5.148723e-01 -7.920980e-08 5.172625e-01 -7.981477e-08 5.196566e-01 -8.042436e-08 5.220544e-01 -8.103860e-08 5.244559e-01 -8.165754e-08 5.268609e-01 -8.228120e-08 5.292693e-01 -8.290962e-08 5.316810e-01 -8.354285e-08 5.340959e-01 -8.418091e-08 5.365139e-01 -8.482384e-08 5.389348e-01 -8.547169e-08 5.413587e-01 -8.612448e-08 5.437852e-01 -8.678226e-08 5.462145e-01 -8.744506e-08 5.486462e-01 -8.811293e-08 5.510803e-01 -8.878589e-08 5.535166e-01 -8.946399e-08 5.559551e-01 -9.014728e-08 5.583957e-01 -9.083578e-08 5.608381e-01 -9.152954e-08 5.632824e-01 -9.222860e-08 5.657283e-01 -9.293300e-08 5.681757e-01 -9.364278e-08 5.706245e-01 -9.435798e-08 5.730745e-01 -9.507864e-08 5.755257e-01 -9.580481e-08 5.779780e-01 -9.653652e-08 5.804310e-01 -9.727382e-08 5.828849e-01 -9.801675e-08 5.853393e-01 -9.876536e-08 5.877942e-01 -9.951968e-08 5.902495e-01 -1.002798e-07 5.927050e-01 -1.010457e-07 5.951606e-01 -1.018174e-07 5.976159e-01 -1.025950e-07 6.000710e-01 -1.033786e-07 6.025260e-01 -1.041682e-07 6.049805e-01 -1.049637e-07 6.074340e-01 -1.057654e-07 6.098871e-01 -1.065732e-07 6.123393e-01 -1.073871e-07 6.147901e-01 -1.082073e-07 6.172401e-01 -1.090338e-07 6.196887e-01 -1.098665e-07 6.221356e-01 -1.107056e-07 6.245810e-01 -1.115511e-07 6.270245e-01 -1.124031e-07 6.294663e-01 -1.132616e-07 6.319060e-01 -1.141266e-07 6.343433e-01 -1.149983e-07 6.367786e-01 -1.158766e-07 6.392111e-01 -1.167616e-07 6.416411e-01 -1.176534e-07 6.440683e-01 -1.185519e-07 6.464923e-01 -1.194574e-07 6.489136e-01 -1.203697e-07 6.513314e-01 -1.212891e-07 6.537462e-01 -1.222154e-07 6.561571e-01 -1.231488e-07 6.585645e-01 -1.240894e-07 6.609682e-01 -1.250371e-07 6.633677e-01 -1.259921e-07 6.657634e-01 -1.269544e-07 6.681548e-01 -1.279240e-07 6.705417e-01 -1.289010e-07 6.729240e-01 -1.298855e-07 6.753018e-01 -1.308775e-07 6.776748e-01 -1.318771e-07 6.800428e-01 -1.328843e-07 6.824057e-01 -1.338992e-07 6.847634e-01 -1.349219e-07 6.871158e-01 -1.359523e-07 6.894624e-01 -1.369907e-07 6.918037e-01 -1.380369e-07 6.941389e-01 -1.390912e-07 6.964684e-01 -1.401535e-07 6.987918e-01 -1.412239e-07 7.011089e-01 -1.423025e-07 7.034198e-01 -1.433894e-07 7.057243e-01 -1.444845e-07 7.080220e-01 -1.455880e-07 7.103131e-01 -1.467000e-07 7.125974e-01 -1.478204e-07 7.148746e-01 -1.489494e-07 7.171448e-01 -1.500870e-07 7.194076e-01 -1.512333e-07 7.216631e-01 -1.523883e-07 7.239111e-01 -1.535522e-07 7.261515e-01 -1.547250e-07 7.283843e-01 -1.559067e-07 7.306091e-01 -1.570974e-07 7.328258e-01 -1.582972e-07 7.350345e-01 -1.595062e-07 7.372351e-01 -1.607245e-07 7.394274e-01 -1.619520e-07 7.416111e-01 -1.631889e-07 7.437863e-01 -1.644353e-07 7.459530e-01 -1.656912e-07 7.481108e-01 -1.669566e-07 7.502597e-01 -1.682318e-07 7.523998e-01 -1.695167e-07 7.545307e-01 -1.708113e-07 7.566523e-01 -1.721159e-07 7.587648e-01 -1.734305e-07 7.608679e-01 -1.747550e-07 7.629614e-01 -1.760897e-07 7.650454e-01 -1.774346e-07 7.671198e-01 -1.787898e-07 7.691844e-01 -1.801553e-07 7.712392e-01 -1.815312e-07 7.732840e-01 -1.829177e-07 7.753189e-01 -1.843147e-07 7.773436e-01 -1.857224e-07 7.793581e-01 -1.871409e-07 7.813625e-01 -1.885702e-07 7.833565e-01 -1.900104e-07 7.853400e-01 -1.914616e-07 7.873131e-01 -1.929239e-07 7.892756e-01 -1.943974e-07 7.912276e-01 -1.958821e-07 7.931688e-01 -1.973781e-07 7.950992e-01 -1.988856e-07 7.970189e-01 -2.004046e-07 7.989277e-01 -2.019352e-07 8.008255e-01 -2.034775e-07 8.027124e-01 -2.050316e-07 8.045882e-01 -2.065975e-07 8.064529e-01 -2.081754e-07 8.083065e-01 -2.097653e-07 8.101487e-01 -2.113674e-07 8.119799e-01 -2.129818e-07 8.137998e-01 -2.146084e-07 8.156082e-01 -2.162475e-07 8.174053e-01 -2.178991e-07 8.191910e-01 -2.195633e-07 8.209652e-01 -2.212402e-07 8.227279e-01 -2.229299e-07 8.244791e-01 -2.246326e-07 8.262189e-01 -2.263482e-07 8.279470e-01 -2.280770e-07 8.296635e-01 -2.298189e-07 8.313684e-01 -2.315741e-07 8.330615e-01 -2.333428e-07 8.347432e-01 -2.351250e-07 8.364131e-01 -2.369207e-07 8.380712e-01 -2.387302e-07 8.397176e-01 -2.405535e-07 8.413523e-01 -2.423908e-07 8.429754e-01 -2.442420e-07 8.445865e-01 -2.461074e-07 8.461860e-01 -2.479871e-07 8.477737e-01 -2.498811e-07 8.493496e-01 -2.517896e-07 8.509138e-01 -2.537126e-07 8.524662e-01 -2.556504e-07 8.540068e-01 -2.576029e-07 8.555357e-01 -2.595704e-07 8.570528e-01 -2.615528e-07 8.585581e-01 -2.635504e-07 8.600517e-01 -2.655633e-07 8.615336e-01 -2.675916e-07 8.630038e-01 -2.696353e-07 8.644622e-01 -2.716947e-07 8.659090e-01 -2.737697e-07 8.673441e-01 -2.758607e-07 8.687675e-01 -2.779676e-07 8.701793e-01 -2.800905e-07 8.715795e-01 -2.822297e-07 8.729681e-01 -2.843853e-07 8.743451e-01 -2.865573e-07 8.757106e-01 -2.887459e-07 8.770646e-01 -2.909512e-07 8.784071e-01 -2.931733e-07 8.797381e-01 -2.954124e-07 8.810577e-01 -2.976687e-07 8.823660e-01 -2.999421e-07 8.836629e-01 -3.022329e-07 8.849484e-01 -3.045412e-07 8.862227e-01 -3.068672e-07 8.874858e-01 -3.092109e-07 8.887376e-01 -3.115725e-07 8.899782e-01 -3.139521e-07 8.912078e-01 -3.163500e-07 8.924263e-01 -3.187661e-07 8.936337e-01 -3.212007e-07 8.948301e-01 -3.236539e-07 8.960156e-01 -3.261258e-07 8.971901e-01 -3.286166e-07 8.983539e-01 -3.311264e-07 8.995068e-01 -3.336554e-07 9.006489e-01 -3.362037e-07 9.017804e-01 -3.387714e-07 9.029011e-01 -3.413588e-07 9.040113e-01 -3.439660e-07 9.051110e-01 -3.465930e-07 9.062001e-01 -3.492401e-07 9.072788e-01 -3.519075e-07 9.083471e-01 -3.545952e-07 9.094051e-01 -3.573034e-07 9.104527e-01 -3.600323e-07 9.114902e-01 -3.627821e-07 9.125175e-01 -3.655528e-07 9.135347e-01 -3.683447e-07 9.145419e-01 -3.711580e-07 9.155391e-01 -3.739927e-07 9.165263e-01 -3.768491e-07 9.175037e-01 -3.797273e-07 9.184713e-01 -3.826275e-07 9.194291e-01 -3.855498e-07 9.203772e-01 -3.884944e-07 9.213158e-01 -3.914616e-07 9.222448e-01 -3.944514e-07 9.231642e-01 -3.974640e-07 9.240743e-01 -4.004997e-07 9.249750e-01 -4.035585e-07 9.258664e-01 -4.066407e-07 9.267485e-01 -4.097464e-07 9.276215e-01 -4.128759e-07 9.284854e-01 -4.160292e-07 9.293402e-01 -4.192066e-07 9.301860e-01 -4.224083e-07 9.310229e-01 -4.256345e-07 9.318510e-01 -4.288853e-07 9.326704e-01 -4.321609e-07 9.334810e-01 -4.354616e-07 9.342829e-01 -4.387874e-07 9.350763e-01 -4.421387e-07 9.358611e-01 -4.455155e-07 9.366375e-01 -4.489182e-07 9.374056e-01 -4.523468e-07 9.381653e-01 -4.558016e-07 9.389167e-01 -4.592828e-07 9.396600e-01 -4.627906e-07 9.403952e-01 -4.663251e-07 9.411223e-01 -4.698867e-07 9.418414e-01 -4.734755e-07 9.425526e-01 -4.770917e-07 9.432560e-01 -4.807355e-07 9.439516e-01 -4.844071e-07 9.446395e-01 -4.881068e-07 9.453197e-01 -4.918347e-07 9.459923e-01 -4.955911e-07 9.466574e-01 -4.993762e-07 9.473151e-01 -5.031902e-07 9.479654e-01 -5.070333e-07 9.486083e-01 -5.109058e-07 9.492440e-01 -5.148079e-07 9.498726e-01 -5.187397e-07 9.504940e-01 -5.227016e-07 9.511083e-01 -5.266938e-07 9.517156e-01 -5.307164e-07 9.523160e-01 -5.347698e-07 9.529096e-01 -5.388541e-07 9.534963e-01 -5.429696e-07 9.540763e-01 -5.471166e-07 9.546496e-01 -5.512952e-07 9.552164e-01 -5.555057e-07 9.557765e-01 -5.597484e-07 9.563302e-01 -5.640235e-07 9.568774e-01 -5.683312e-07 9.574183e-01 -5.726719e-07 9.579529e-01 -5.770457e-07 9.584813e-01 -5.814529e-07 9.590035e-01 -5.858938e-07 9.595195e-01 -5.903685e-07 9.600295e-01 -5.948775e-07 9.605335e-01 -5.994209e-07 9.610316e-01 -6.039990e-07 9.615238e-01 -6.086120e-07 9.620102e-01 -6.132603e-07 9.624908e-01 -6.179441e-07 9.629657e-01 -6.226637e-07 9.634350e-01 -6.274193e-07 9.638987e-01 -6.322112e-07 9.643569e-01 -6.370398e-07 9.648096e-01 -6.419052e-07 9.652568e-01 -6.468077e-07 9.656988e-01 -6.517478e-07 9.661354e-01 -6.567255e-07 9.665668e-01 -6.617413e-07 9.669930e-01 -6.667953e-07 9.674140e-01 -6.718880e-07 9.678300e-01 -6.770196e-07 9.682410e-01 -6.821903e-07 9.686470e-01 -6.874006e-07 9.690480e-01 -6.926506e-07 9.694442e-01 -6.979408e-07 9.698356e-01 -7.032713e-07 9.702222e-01 -7.086425e-07 9.706041e-01 -7.140548e-07 9.709814e-01 -7.195084e-07 9.713540e-01 -7.250037e-07 9.717221e-01 -7.305409e-07 9.720857e-01 -7.361205e-07 9.724448e-01 -7.417426e-07 9.727995e-01 -7.474077e-07 9.731498e-01 -7.531160e-07 9.734959e-01 -7.588680e-07 9.738376e-01 -7.646639e-07 9.741752e-01 -7.705040e-07 9.745086e-01 -7.763888e-07 9.748378e-01 -7.823184e-07 9.751630e-01 -7.882934e-07 9.754842e-01 -7.943140e-07 9.758013e-01 -8.003806e-07 9.761146e-01 -8.064936e-07 9.764239e-01 -8.126532e-07 9.767294e-01 -8.188598e-07 9.770311e-01 -8.251139e-07 9.773290e-01 -8.314157e-07 9.776232e-01 -8.377657e-07 9.779137e-01 -8.441642e-07 9.782006e-01 -8.506115e-07 9.784839e-01 -8.571081e-07 9.787636e-01 -8.636543e-07 9.790399e-01 -8.702504e-07 9.793126e-01 -8.768970e-07 9.795820e-01 -8.835943e-07 9.798479e-01 -8.903428e-07 9.801105e-01 -8.971428e-07 9.803698e-01 -9.039948e-07 9.806258e-01 -9.108991e-07 9.808786e-01 -9.178561e-07 9.811282e-01 -9.248662e-07 9.813746e-01 -9.319299e-07 9.816179e-01 -9.390476e-07 9.818582e-01 -9.462196e-07 9.820953e-01 -9.534464e-07 9.823295e-01 -9.607283e-07 9.825607e-01 -9.680659e-07 9.827890e-01 -9.754596e-07 9.830143e-01 -9.829097e-07 9.832368e-01 -9.904167e-07 9.834565e-01 -9.979810e-07 9.836733e-01 -1.005603e-06 9.838874e-01 -1.013283e-06 9.840988e-01 -1.021022e-06 9.843074e-01 -1.028820e-06 9.845134e-01 -1.036678e-06 9.847168e-01 -1.044596e-06 9.849175e-01 -1.052574e-06 9.851157e-01 -1.060613e-06 9.853113e-01 -1.068713e-06 9.855045e-01 -1.076876e-06 9.856951e-01 -1.085100e-06 9.858833e-01 -1.093388e-06 9.860691e-01 -1.101739e-06 9.862525e-01 -1.110153e-06 9.864335e-01 -1.118632e-06 9.866122e-01 -1.127176e-06 9.867886e-01 -1.135785e-06 9.869627e-01 -1.144459e-06 9.871346e-01 -1.153200e-06 9.873043e-01 -1.162008e-06 9.874718e-01 -1.170882e-06 9.876370e-01 -1.179825e-06 9.878002e-01 -1.188836e-06 9.879613e-01 -1.197916e-06 9.881203e-01 -1.207065e-06 9.882772e-01 -1.216284e-06 9.884320e-01 -1.225573e-06 9.885849e-01 -1.234934e-06 9.887358e-01 -1.244366e-06 9.888848e-01 -1.253869e-06 9.890317e-01 -1.263446e-06 9.891768e-01 -1.273095e-06 9.893200e-01 -1.282819e-06 9.894614e-01 -1.292616e-06 9.896009e-01 -1.302489e-06 9.897386e-01 -1.312437e-06 9.898745e-01 -1.322460e-06 9.900086e-01 -1.332561e-06 9.901410e-01 -1.342738e-06 9.902716e-01 -1.352993e-06 9.904006e-01 -1.363327e-06 9.905279e-01 -1.373739e-06 9.906535e-01 -1.384231e-06 9.907774e-01 -1.394803e-06 9.908998e-01 -1.405456e-06 9.910205e-01 -1.416190e-06 9.911397e-01 -1.427007e-06 9.912573e-01 -1.437905e-06 9.913734e-01 -1.448887e-06 9.914879e-01 -1.459953e-06 9.916010e-01 -1.471104e-06 9.917125e-01 -1.482339e-06 9.918226e-01 -1.493661e-06 9.919313e-01 -1.505069e-06 9.920386e-01 -1.516564e-06 9.921444e-01 -1.528147e-06 9.922488e-01 -1.539818e-06 9.923519e-01 -1.551578e-06 9.924536e-01 -1.563428e-06 9.925540e-01 -1.575369e-06 9.926531e-01 -1.587401e-06 9.927508e-01 -1.599525e-06 9.928473e-01 -1.611741e-06 9.929425e-01 -1.624051e-06 9.930365e-01 -1.636455e-06 9.931292e-01 -1.648953e-06 9.932207e-01 -1.661547e-06 9.933110e-01 -1.674237e-06 9.934001e-01 -1.687024e-06 9.934880e-01 -1.699909e-06 9.935748e-01 -1.712892e-06 9.936604e-01 -1.725974e-06 9.937449e-01 -1.739157e-06 9.938283e-01 -1.752439e-06 9.939106e-01 -1.765824e-06 9.939918e-01 -1.779310e-06 9.940719e-01 -1.792900e-06 9.941510e-01 -1.806593e-06 9.942290e-01 -1.820391e-06 9.943060e-01 -1.834294e-06 9.943819e-01 -1.848304e-06 9.944569e-01 -1.862420e-06 9.945309e-01 -1.876645e-06 9.946039e-01 -1.890977e-06 9.946759e-01 -1.905420e-06 9.947470e-01 -1.919973e-06 9.948171e-01 -1.934636e-06 9.948863e-01 -1.949412e-06 9.949546e-01 -1.964301e-06 9.950220e-01 -1.979303e-06 9.950885e-01 -1.994420e-06 9.951541e-01 -2.009653e-06 9.952189e-01 -2.025002e-06 9.952828e-01 -2.040468e-06 9.953458e-01 -2.056052e-06 9.954080e-01 -2.071755e-06 9.954694e-01 -2.087578e-06 9.955299e-01 -2.103522e-06 9.955897e-01 -2.119588e-06 9.956487e-01 -2.135776e-06 9.957068e-01 -2.152088e-06 9.957643e-01 -2.168525e-06 9.958209e-01 -2.185087e-06 9.958768e-01 -2.201776e-06 9.959320e-01 -2.218592e-06 9.959864e-01 -2.235536e-06 9.960401e-01 -2.252610e-06 9.960931e-01 -2.269815e-06 9.961453e-01 -2.287150e-06 9.961969e-01 -2.304619e-06 9.962478e-01 -2.322220e-06 9.962980e-01 -2.339956e-06 9.963476e-01 -2.357828e-06 9.963965e-01 -2.375836e-06 9.964447e-01 -2.393981e-06 9.964923e-01 -2.412265e-06 9.965393e-01 -2.430689e-06 9.965856e-01 -2.449253e-06 9.966314e-01 -2.467960e-06 9.966765e-01 -2.486809e-06 9.967210e-01 -2.505802e-06 9.967649e-01 -2.524940e-06 9.968083e-01 -2.544224e-06 9.968510e-01 -2.563656e-06 9.968932e-01 -2.583236e-06 9.969348e-01 -2.602965e-06 9.969759e-01 -2.622846e-06 9.970164e-01 -2.642878e-06 9.970564e-01 -2.663063e-06 9.970959e-01 -2.683402e-06 9.971348e-01 -2.703897e-06 9.971732e-01 -2.724548e-06 9.972111e-01 -2.745356e-06 9.972485e-01 -2.766324e-06 9.972854e-01 -2.787452e-06 9.973217e-01 -2.808741e-06 9.973577e-01 -2.830193e-06 9.973931e-01 -2.851809e-06 9.974280e-01 -2.873590e-06 9.974625e-01 -2.895537e-06 9.974966e-01 -2.917651e-06 9.975301e-01 -2.939935e-06 9.975633e-01 -2.962389e-06 9.975959e-01 -2.985014e-06 9.976282e-01 -3.007812e-06 9.976600e-01 -3.030785e-06 9.976914e-01 -3.053932e-06 9.977224e-01 -3.077257e-06 9.977529e-01 -3.100760e-06 9.977831e-01 -3.124442e-06 9.978128e-01 -3.148305e-06 9.978422e-01 -3.172350e-06 9.978711e-01 -3.196579e-06 9.978997e-01 -3.220993e-06 9.979279e-01 -3.245593e-06 9.979557e-01 -3.270382e-06 9.979831e-01 -3.295359e-06 9.980102e-01 -3.320528e-06 9.980369e-01 -3.345888e-06 9.980633e-01 -3.371443e-06 9.980893e-01 -3.397192e-06 9.981149e-01 -3.423138e-06 9.981402e-01 -3.449283e-06 9.981652e-01 -3.475626e-06 9.981898e-01 -3.502172e-06 9.982141e-01 -3.528920e-06 9.982381e-01 -3.555872e-06 9.982618e-01 -3.583030e-06 9.982851e-01 -3.610395e-06 9.983081e-01 -3.637970e-06 9.983309e-01 -3.665755e-06 9.983533e-01 -3.693752e-06 9.983754e-01 -3.721963e-06 9.983972e-01 -3.750390e-06 9.984187e-01 -3.779034e-06 9.984400e-01 -3.807896e-06 9.984609e-01 -3.836979e-06 9.984816e-01 -3.866284e-06 9.985020e-01 -3.895813e-06 9.985221e-01 -3.925567e-06 9.985420e-01 -3.955549e-06 9.985616e-01 -3.985760e-06 9.985809e-01 -4.016201e-06 9.986000e-01 -4.046875e-06 9.986188e-01 -4.077783e-06 9.986373e-01 -4.108927e-06 9.986556e-01 -4.140309e-06 9.986737e-01 -4.171931e-06 9.986915e-01 -4.203794e-06 9.987091e-01 -4.235901e-06 9.987265e-01 -4.268253e-06 9.987436e-01 -4.300852e-06 9.987605e-01 -4.333700e-06 9.987771e-01 -4.366798e-06 9.987935e-01 -4.400150e-06 9.988098e-01 -4.433756e-06 9.988258e-01 -4.467619e-06 9.988415e-01 -4.501741e-06 9.988571e-01 -4.536123e-06 9.988725e-01 -4.570768e-06 9.988876e-01 -4.605677e-06 9.989026e-01 -4.640853e-06 9.989173e-01 -4.676298e-06 9.989319e-01 -4.712013e-06 9.989462e-01 -4.748001e-06 9.989604e-01 -4.784264e-06 9.989744e-01 -4.820804e-06 9.989882e-01 -4.857623e-06 9.990018e-01 -4.894723e-06 9.990152e-01 -4.932107e-06 9.990284e-01 -4.969776e-06 9.990415e-01 -5.007733e-06 9.990544e-01 -5.045980e-06 9.990671e-01 -5.084518e-06 9.990796e-01 -5.123351e-06 9.990920e-01 -5.162481e-06 9.991042e-01 -5.201910e-06 9.991163e-01 -5.241640e-06 9.991282e-01 -5.281673e-06 9.991399e-01 -5.322012e-06 9.991514e-01 -5.362659e-06 9.991629e-01 -5.403616e-06 9.991741e-01 -5.444886e-06 9.991852e-01 -5.486472e-06 9.991962e-01 -5.528375e-06 9.992070e-01 -5.570598e-06 9.992177e-01 -5.613144e-06 9.992282e-01 -5.656014e-06 9.992386e-01 -5.699212e-06 9.992488e-01 -5.742740e-06 9.992589e-01 -5.786600e-06 9.992689e-01 -5.830796e-06 9.992787e-01 -5.875329e-06 9.992884e-01 -5.920202e-06 9.992980e-01 -5.965417e-06 9.993074e-01 -6.010978e-06 9.993167e-01 -6.056887e-06 9.993259e-01 -6.103147e-06 9.993350e-01 -6.149760e-06 9.993439e-01 -6.196729e-06 9.993528e-01 -6.244057e-06 9.993615e-01 -6.291746e-06 9.993701e-01 -6.339799e-06 9.993785e-01 -6.388220e-06 9.993869e-01 -6.437010e-06 9.993951e-01 -6.486173e-06 9.994033e-01 -6.535711e-06 9.994113e-01 -6.585628e-06 9.994192e-01 -6.635926e-06 9.994270e-01 -6.686608e-06 9.994347e-01 -6.737677e-06 9.994424e-01 -6.789136e-06 9.994499e-01 -6.840988e-06 9.994573e-01 -6.893237e-06 9.994646e-01 -6.945884e-06 9.994718e-01 -6.998933e-06 9.994789e-01 -7.052388e-06 9.994859e-01 -7.106251e-06 9.994928e-01 -7.160525e-06 9.994996e-01 -7.215214e-06 9.995064e-01 -7.270320e-06 9.995130e-01 -7.325847e-06 9.995196e-01 -7.381799e-06 9.995260e-01 -7.438177e-06 9.995324e-01 -7.494987e-06 9.995387e-01 -7.552230e-06 9.995449e-01 -7.609910e-06 9.995510e-01 -7.668031e-06 9.995571e-01 -7.726596e-06 9.995630e-01 -7.785608e-06 9.995689e-01 -7.845071e-06 9.995747e-01 -7.904988e-06 9.995804e-01 -7.965362e-06 9.995861e-01 -8.026198e-06 9.995916e-01 -8.087498e-06 9.995971e-01 -8.149267e-06 9.996026e-01 -8.211507e-06 9.996079e-01 -8.274223e-06 9.996132e-01 -8.337417e-06 9.996184e-01 -8.401095e-06 9.996235e-01 -8.465258e-06 9.996286e-01 -8.529912e-06 9.996336e-01 -8.595059e-06 9.996385e-01 -8.660704e-06 9.996434e-01 -8.726851e-06 9.996482e-01 -8.793502e-06 9.996529e-01 -8.860663e-06 9.996576e-01 -8.928337e-06 9.996622e-01 -8.996527e-06 9.996667e-01 -9.065238e-06 9.996712e-01 -9.134474e-06 9.996757e-01 -9.204239e-06 9.996800e-01 -9.274537e-06 9.996843e-01 -9.345371e-06 9.996886e-01 -9.416747e-06 9.996928e-01 -9.488668e-06 9.996969e-01 -9.561138e-06 9.997010e-01 -9.634161e-06 9.997050e-01 -9.707742e-06 9.997090e-01 -9.781885e-06 9.997129e-01 -9.856595e-06 9.997168e-01 -9.931875e-06 9.997206e-01 -1.000773e-05 9.997243e-01 -1.008416e-05 9.997280e-01 -1.016118e-05 9.997317e-01 -1.023879e-05 9.997353e-01 -1.031699e-05 9.997389e-01 -1.039578e-05 9.997424e-01 -1.047518e-05 9.997459e-01 -1.055519e-05 9.997493e-01 -1.063580e-05 9.997527e-01 -1.071703e-05 9.997560e-01 -1.079888e-05 9.997593e-01 -1.088136e-05 9.997625e-01 -1.096447e-05 9.997657e-01 -1.104821e-05 9.997689e-01 -1.113259e-05 9.997720e-01 -1.121762e-05 9.997750e-01 -1.130329e-05 9.997781e-01 -1.138962e-05 9.997811e-01 -1.147661e-05 9.997840e-01 -1.156426e-05 9.997869e-01 -1.165258e-05 9.997898e-01 -1.174158e-05 9.997926e-01 -1.183126e-05 9.997954e-01 -1.192162e-05 9.997982e-01 -1.201267e-05 9.998009e-01 -1.210442e-05 9.998036e-01 -1.219687e-05 9.998062e-01 -1.229002e-05 9.998088e-01 -1.238389e-05 9.998114e-01 -1.247847e-05 9.998139e-01 -1.257377e-05 9.998164e-01 -1.266981e-05 9.998189e-01 -1.276657e-05 9.998213e-01 -1.286408e-05 9.998237e-01 -1.296233e-05 9.998261e-01 -1.306133e-05 9.998285e-01 -1.316108e-05 9.998308e-01 -1.326160e-05 9.998330e-01 -1.336289e-05 9.998353e-01 -1.346495e-05 9.998375e-01 -1.356778e-05 9.998397e-01 -1.367141e-05 9.998419e-01 -1.377582e-05 9.998440e-01 -1.388104e-05 9.998461e-01 -1.398705e-05 9.998482e-01 -1.409388e-05 9.998502e-01 -1.420152e-05 9.998522e-01 -1.430999e-05 9.998542e-01 -1.441928e-05 9.998562e-01 -1.452941e-05 9.998581e-01 -1.464038e-05 9.998600e-01 -1.475219e-05 9.998619e-01 -1.486486e-05 9.998638e-01 -1.497840e-05 9.998656e-01 -1.509279e-05 9.998674e-01 -1.520806e-05 9.998692e-01 -1.532422e-05 9.998709e-01 -1.544126e-05 9.998727e-01 -1.555919e-05 9.998744e-01 -1.567802e-05 9.998761e-01 -1.579776e-05 9.998778e-01 -1.591842e-05 9.998794e-01 -1.604000e-05 9.998810e-01 -1.616250e-05 9.998826e-01 -1.628595e-05 9.998842e-01 -1.641033e-05 9.998858e-01 -1.653566e-05 9.998873e-01 -1.666196e-05 9.998888e-01 -1.678921e-05 9.998903e-01 -1.691744e-05 9.998918e-01 -1.704665e-05 9.998933e-01 -1.717684e-05 9.998947e-01 -1.730803e-05 9.998961e-01 -1.744022e-05 9.998975e-01 -1.757342e-05 9.998989e-01 -1.770764e-05 9.999003e-01 -1.784288e-05 9.999016e-01 -1.797916e-05 9.999029e-01 -1.811647e-05 9.999042e-01 -1.825484e-05 9.999055e-01 -1.839426e-05 9.999068e-01 -1.853475e-05 9.999080e-01 -1.867631e-05 9.999093e-01 -1.881895e-05 9.999105e-01 -1.896268e-05 9.999117e-01 -1.910751e-05 9.999129e-01 -1.925344e-05 9.999141e-01 -1.940049e-05 9.999152e-01 -1.954866e-05 9.999164e-01 -1.969796e-05 9.999175e-01 -1.984841e-05 9.999186e-01 -2.000000e-05 9.999197e-01 +1.000000e-08 1.831248e-01 +1.006935e-08 1.835502e-01 +1.013918e-08 1.839767e-01 +1.020950e-08 1.844041e-01 +1.028031e-08 1.848326e-01 +1.035160e-08 1.852620e-01 +1.042339e-08 1.856924e-01 +1.049568e-08 1.861238e-01 +1.056847e-08 1.865562e-01 +1.064176e-08 1.869896e-01 +1.071556e-08 1.874240e-01 +1.078988e-08 1.878594e-01 +1.086471e-08 1.882959e-01 +1.094006e-08 1.887333e-01 +1.101593e-08 1.891717e-01 +1.109232e-08 1.896111e-01 +1.116925e-08 1.900516e-01 +1.124671e-08 1.904931e-01 +1.132471e-08 1.909356e-01 +1.140325e-08 1.913791e-01 +1.148233e-08 1.918237e-01 +1.156196e-08 1.922692e-01 +1.164215e-08 1.927159e-01 +1.172289e-08 1.931635e-01 +1.180419e-08 1.936122e-01 +1.188605e-08 1.940619e-01 +1.196848e-08 1.945126e-01 +1.205148e-08 1.949644e-01 +1.213506e-08 1.954172e-01 +1.221922e-08 1.958711e-01 +1.230396e-08 1.963260e-01 +1.238929e-08 1.967820e-01 +1.247521e-08 1.972390e-01 +1.256173e-08 1.976971e-01 +1.264885e-08 1.981562e-01 +1.273657e-08 1.986164e-01 +1.282490e-08 1.990777e-01 +1.291384e-08 1.995400e-01 +1.300340e-08 2.000033e-01 +1.309358e-08 2.004678e-01 +1.318439e-08 2.009333e-01 +1.327583e-08 2.014000e-01 +1.336790e-08 2.018676e-01 +1.346060e-08 2.023364e-01 +1.355395e-08 2.028062e-01 +1.364795e-08 2.032771e-01 +1.374260e-08 2.037491e-01 +1.383791e-08 2.042222e-01 +1.393388e-08 2.046964e-01 +1.403051e-08 2.051717e-01 +1.412782e-08 2.056481e-01 +1.422579e-08 2.061255e-01 +1.432445e-08 2.066041e-01 +1.442379e-08 2.070838e-01 +1.452383e-08 2.075646e-01 +1.462455e-08 2.080464e-01 +1.472597e-08 2.085294e-01 +1.482810e-08 2.090135e-01 +1.493094e-08 2.094988e-01 +1.503448e-08 2.099851e-01 +1.513875e-08 2.104726e-01 +1.524374e-08 2.109612e-01 +1.534946e-08 2.114509e-01 +1.545591e-08 2.119417e-01 +1.556310e-08 2.124337e-01 +1.567103e-08 2.129268e-01 +1.577971e-08 2.134210e-01 +1.588915e-08 2.139164e-01 +1.599934e-08 2.144129e-01 +1.611030e-08 2.149105e-01 +1.622202e-08 2.154093e-01 +1.633453e-08 2.159093e-01 +1.644781e-08 2.164104e-01 +1.656188e-08 2.169126e-01 +1.667674e-08 2.174160e-01 +1.679239e-08 2.179206e-01 +1.690885e-08 2.184263e-01 +1.702611e-08 2.189331e-01 +1.714419e-08 2.194412e-01 +1.726309e-08 2.199504e-01 +1.738281e-08 2.204608e-01 +1.750337e-08 2.209724e-01 +1.762475e-08 2.214851e-01 +1.774698e-08 2.219990e-01 +1.787006e-08 2.225141e-01 +1.799399e-08 2.230303e-01 +1.811878e-08 2.235478e-01 +1.824444e-08 2.240665e-01 +1.837097e-08 2.245863e-01 +1.849837e-08 2.251073e-01 +1.862666e-08 2.256295e-01 +1.875584e-08 2.261530e-01 +1.888592e-08 2.266776e-01 +1.901689e-08 2.272034e-01 +1.914878e-08 2.277305e-01 +1.928158e-08 2.282587e-01 +1.941530e-08 2.287882e-01 +1.954995e-08 2.293189e-01 +1.968553e-08 2.298507e-01 +1.982205e-08 2.303838e-01 +1.995952e-08 2.309182e-01 +2.009794e-08 2.314537e-01 +2.023732e-08 2.319905e-01 +2.037767e-08 2.325285e-01 +2.051899e-08 2.330677e-01 +2.066130e-08 2.336083e-01 +2.080459e-08 2.341500e-01 +2.094887e-08 2.346929e-01 +2.109415e-08 2.352371e-01 +2.124044e-08 2.357825e-01 +2.138775e-08 2.363293e-01 +2.153608e-08 2.368772e-01 +2.168543e-08 2.374264e-01 +2.183582e-08 2.379768e-01 +2.198726e-08 2.385286e-01 +2.213974e-08 2.390815e-01 +2.229329e-08 2.396358e-01 +2.244789e-08 2.401913e-01 +2.260357e-08 2.407481e-01 +2.276033e-08 2.413061e-01 +2.291818e-08 2.418655e-01 +2.307712e-08 2.424261e-01 +2.323716e-08 2.429879e-01 +2.339832e-08 2.435511e-01 +2.356059e-08 2.441156e-01 +2.372398e-08 2.446813e-01 +2.388851e-08 2.452483e-01 +2.405418e-08 2.458167e-01 +2.422100e-08 2.463863e-01 +2.438898e-08 2.469572e-01 +2.455812e-08 2.475295e-01 +2.472843e-08 2.481030e-01 +2.489993e-08 2.486778e-01 +2.507261e-08 2.492540e-01 +2.524650e-08 2.498315e-01 +2.542158e-08 2.504102e-01 +2.559789e-08 2.509904e-01 +2.577541e-08 2.515718e-01 +2.595417e-08 2.521545e-01 +2.613416e-08 2.527386e-01 +2.631541e-08 2.533240e-01 +2.649791e-08 2.539107e-01 +2.668168e-08 2.544988e-01 +2.686672e-08 2.550882e-01 +2.705304e-08 2.556790e-01 +2.724066e-08 2.562711e-01 +2.742958e-08 2.568645e-01 +2.761981e-08 2.574593e-01 +2.781135e-08 2.580555e-01 +2.800423e-08 2.586530e-01 +2.819844e-08 2.592518e-01 +2.839400e-08 2.598520e-01 +2.859092e-08 2.604536e-01 +2.878920e-08 2.610566e-01 +2.898886e-08 2.616609e-01 +2.918990e-08 2.622666e-01 +2.939234e-08 2.628737e-01 +2.959618e-08 2.634821e-01 +2.980143e-08 2.640919e-01 +3.000811e-08 2.647031e-01 +3.021622e-08 2.653157e-01 +3.042577e-08 2.659297e-01 +3.063678e-08 2.665451e-01 +3.084925e-08 2.671618e-01 +3.106320e-08 2.677800e-01 +3.127862e-08 2.683996e-01 +3.149554e-08 2.690205e-01 +3.171397e-08 2.696429e-01 +3.193391e-08 2.702667e-01 +3.215538e-08 2.708919e-01 +3.237838e-08 2.715185e-01 +3.260293e-08 2.721465e-01 +3.282904e-08 2.727759e-01 +3.305671e-08 2.734068e-01 +3.328596e-08 2.740391e-01 +3.351681e-08 2.746728e-01 +3.374925e-08 2.753079e-01 +3.398331e-08 2.759445e-01 +3.421899e-08 2.765826e-01 +3.445630e-08 2.772220e-01 +3.469526e-08 2.778629e-01 +3.493588e-08 2.785053e-01 +3.517816e-08 2.791490e-01 +3.542213e-08 2.797943e-01 +3.566778e-08 2.804410e-01 +3.591515e-08 2.810891e-01 +3.616422e-08 2.817387e-01 +3.641503e-08 2.823898e-01 +3.666757e-08 2.830424e-01 +3.692187e-08 2.836964e-01 +3.717792e-08 2.843518e-01 +3.743576e-08 2.850088e-01 +3.769538e-08 2.856672e-01 +3.795680e-08 2.863271e-01 +3.822004e-08 2.869885e-01 +3.848510e-08 2.876514e-01 +3.875200e-08 2.883157e-01 +3.902075e-08 2.889816e-01 +3.929137e-08 2.896490e-01 +3.956386e-08 2.903178e-01 +3.983824e-08 2.909881e-01 +4.011452e-08 2.916600e-01 +4.039272e-08 2.923333e-01 +4.067285e-08 2.930082e-01 +4.095493e-08 2.936845e-01 +4.123896e-08 2.943624e-01 +4.152495e-08 2.950418e-01 +4.181294e-08 2.957227e-01 +4.210291e-08 2.964051e-01 +4.239490e-08 2.970891e-01 +4.268892e-08 2.977746e-01 +4.298497e-08 2.984616e-01 +4.328308e-08 2.991502e-01 +4.358325e-08 2.998402e-01 +4.388551e-08 3.005319e-01 +4.418986e-08 3.012250e-01 +4.449633e-08 3.019198e-01 +4.480492e-08 3.026160e-01 +4.511564e-08 3.033138e-01 +4.542853e-08 3.040132e-01 +4.574358e-08 3.047141e-01 +4.606082e-08 3.054166e-01 +4.638026e-08 3.061206e-01 +4.670191e-08 3.068262e-01 +4.702580e-08 3.075334e-01 +4.735193e-08 3.082421e-01 +4.768032e-08 3.089524e-01 +4.801099e-08 3.096643e-01 +4.834395e-08 3.103777e-01 +4.867923e-08 3.110928e-01 +4.901682e-08 3.118094e-01 +4.935676e-08 3.125276e-01 +4.969906e-08 3.132474e-01 +5.004373e-08 3.139688e-01 +5.039079e-08 3.146918e-01 +5.074026e-08 3.154164e-01 +5.109215e-08 3.161425e-01 +5.144648e-08 3.168703e-01 +5.180327e-08 3.175997e-01 +5.216253e-08 3.183307e-01 +5.252429e-08 3.190633e-01 +5.288855e-08 3.197975e-01 +5.325534e-08 3.205334e-01 +5.362468e-08 3.212708e-01 +5.399657e-08 3.220099e-01 +5.437105e-08 3.227506e-01 +5.474812e-08 3.234930e-01 +5.512780e-08 3.242369e-01 +5.551012e-08 3.249825e-01 +5.589509e-08 3.257297e-01 +5.628273e-08 3.264786e-01 +5.667306e-08 3.272291e-01 +5.706610e-08 3.279813e-01 +5.746186e-08 3.287350e-01 +5.786037e-08 3.294905e-01 +5.826164e-08 3.302476e-01 +5.866569e-08 3.310063e-01 +5.907255e-08 3.317667e-01 +5.948222e-08 3.325288e-01 +5.989474e-08 3.332925e-01 +6.031012e-08 3.340579e-01 +6.072838e-08 3.348250e-01 +6.114954e-08 3.355937e-01 +6.157362e-08 3.363641e-01 +6.200064e-08 3.371362e-01 +6.243063e-08 3.379099e-01 +6.286359e-08 3.386854e-01 +6.329956e-08 3.394625e-01 +6.373855e-08 3.402413e-01 +6.418059e-08 3.410218e-01 +6.462569e-08 3.418039e-01 +6.507388e-08 3.425878e-01 +6.552518e-08 3.433734e-01 +6.597960e-08 3.441606e-01 +6.643718e-08 3.449496e-01 +6.689793e-08 3.457402e-01 +6.736188e-08 3.465326e-01 +6.782905e-08 3.473267e-01 +6.829945e-08 3.481225e-01 +6.877312e-08 3.489200e-01 +6.925007e-08 3.497192e-01 +6.973033e-08 3.505201e-01 +7.021392e-08 3.513227e-01 +7.070086e-08 3.521271e-01 +7.119118e-08 3.529332e-01 +7.168490e-08 3.537410e-01 +7.218205e-08 3.545506e-01 +7.268264e-08 3.553618e-01 +7.318671e-08 3.561748e-01 +7.369427e-08 3.569896e-01 +7.420535e-08 3.578061e-01 +7.471998e-08 3.586243e-01 +7.523817e-08 3.594443e-01 +7.575996e-08 3.602660e-01 +7.628536e-08 3.610894e-01 +7.681441e-08 3.619146e-01 +7.734713e-08 3.627416e-01 +7.788355e-08 3.635703e-01 +7.842368e-08 3.644008e-01 +7.896756e-08 3.652330e-01 +7.951521e-08 3.660670e-01 +8.006666e-08 3.669027e-01 +8.062194e-08 3.677402e-01 +8.118106e-08 3.685795e-01 +8.174406e-08 3.694205e-01 +8.231097e-08 3.702634e-01 +8.288181e-08 3.711080e-01 +8.345661e-08 3.719543e-01 +8.403539e-08 3.728025e-01 +8.461819e-08 3.736524e-01 +8.520503e-08 3.745041e-01 +8.579594e-08 3.753575e-01 +8.639095e-08 3.762128e-01 +8.699008e-08 3.770699e-01 +8.759337e-08 3.779287e-01 +8.820084e-08 3.787893e-01 +8.881253e-08 3.796517e-01 +8.942846e-08 3.805160e-01 +9.004866e-08 3.813820e-01 +9.067316e-08 3.822498e-01 +9.130199e-08 3.831194e-01 +9.193518e-08 3.839908e-01 +9.257277e-08 3.848640e-01 +9.321477e-08 3.857390e-01 +9.386123e-08 3.866158e-01 +9.451217e-08 3.874944e-01 +9.516763e-08 3.883749e-01 +9.582763e-08 3.892571e-01 +9.649221e-08 3.901411e-01 +9.716140e-08 3.910270e-01 +9.783522e-08 3.919147e-01 +9.851373e-08 3.928042e-01 +9.919693e-08 3.936955e-01 +9.988488e-08 3.945886e-01 +1.005776e-07 3.954836e-01 +1.012751e-07 3.963803e-01 +1.019775e-07 3.972790e-01 +1.026847e-07 3.981794e-01 +1.033968e-07 3.990816e-01 +1.041139e-07 3.999857e-01 +1.048360e-07 4.008917e-01 +1.055630e-07 4.017994e-01 +1.062951e-07 4.027089e-01 +1.070323e-07 4.036204e-01 +1.077746e-07 4.045336e-01 +1.085220e-07 4.054486e-01 +1.092746e-07 4.063655e-01 +1.100324e-07 4.072842e-01 +1.107955e-07 4.082048e-01 +1.115639e-07 4.091273e-01 +1.123376e-07 4.100515e-01 +1.131167e-07 4.109776e-01 +1.139012e-07 4.119056e-01 +1.146911e-07 4.128353e-01 +1.154865e-07 4.137670e-01 +1.162874e-07 4.147004e-01 +1.170939e-07 4.156357e-01 +1.179060e-07 4.165729e-01 +1.187237e-07 4.175120e-01 +1.195470e-07 4.184527e-01 +1.203761e-07 4.193954e-01 +1.212109e-07 4.203400e-01 +1.220515e-07 4.212863e-01 +1.228980e-07 4.222346e-01 +1.237503e-07 4.231847e-01 +1.246085e-07 4.241366e-01 +1.254727e-07 4.250904e-01 +1.263429e-07 4.260461e-01 +1.272191e-07 4.270036e-01 +1.281014e-07 4.279629e-01 +1.289898e-07 4.289241e-01 +1.298843e-07 4.298871e-01 +1.307851e-07 4.308520e-01 +1.316921e-07 4.318187e-01 +1.326054e-07 4.327873e-01 +1.335251e-07 4.337578e-01 +1.344511e-07 4.347301e-01 +1.353835e-07 4.357042e-01 +1.363224e-07 4.366802e-01 +1.372678e-07 4.376580e-01 +1.382198e-07 4.386377e-01 +1.391784e-07 4.396193e-01 +1.401436e-07 4.406027e-01 +1.411155e-07 4.415879e-01 +1.420942e-07 4.425750e-01 +1.430796e-07 4.435639e-01 +1.440719e-07 4.445547e-01 +1.450711e-07 4.455474e-01 +1.460772e-07 4.465419e-01 +1.470902e-07 4.475382e-01 +1.481103e-07 4.485364e-01 +1.491375e-07 4.495364e-01 +1.501718e-07 4.505383e-01 +1.512132e-07 4.515419e-01 +1.522619e-07 4.525475e-01 +1.533179e-07 4.535549e-01 +1.543812e-07 4.545642e-01 +1.554518e-07 4.555752e-01 +1.565299e-07 4.565881e-01 +1.576155e-07 4.576029e-01 +1.587085e-07 4.586193e-01 +1.598092e-07 4.596378e-01 +1.609175e-07 4.606580e-01 +1.620335e-07 4.616801e-01 +1.631572e-07 4.627040e-01 +1.642887e-07 4.637297e-01 +1.654281e-07 4.647573e-01 +1.665754e-07 4.657867e-01 +1.677306e-07 4.668178e-01 +1.688938e-07 4.678508e-01 +1.700651e-07 4.688857e-01 +1.712446e-07 4.699224e-01 +1.724322e-07 4.709608e-01 +1.736280e-07 4.720011e-01 +1.748322e-07 4.730432e-01 +1.760446e-07 4.740870e-01 +1.772655e-07 4.751327e-01 +1.784949e-07 4.761803e-01 +1.797328e-07 4.772296e-01 +1.809793e-07 4.782807e-01 +1.822344e-07 4.793336e-01 +1.834982e-07 4.803883e-01 +1.847708e-07 4.814448e-01 +1.860522e-07 4.825031e-01 +1.873425e-07 4.835631e-01 +1.886418e-07 4.846250e-01 +1.899500e-07 4.856886e-01 +1.912673e-07 4.867539e-01 +1.925938e-07 4.878211e-01 +1.939295e-07 4.888901e-01 +1.952744e-07 4.899608e-01 +1.966287e-07 4.910333e-01 +1.979923e-07 4.921075e-01 +1.993654e-07 4.931835e-01 +2.007480e-07 4.942612e-01 +2.021403e-07 4.953407e-01 +2.035421e-07 4.964219e-01 +2.049537e-07 4.975049e-01 +2.063751e-07 4.985896e-01 +2.078064e-07 4.996761e-01 +2.092475e-07 5.007642e-01 +2.106987e-07 5.018541e-01 +2.121599e-07 5.029457e-01 +2.136313e-07 5.040391e-01 +2.151128e-07 5.051340e-01 +2.166047e-07 5.062308e-01 +2.181069e-07 5.073293e-01 +2.196195e-07 5.084294e-01 +2.211426e-07 5.095313e-01 +2.226762e-07 5.106348e-01 +2.242205e-07 5.117400e-01 +2.257755e-07 5.128469e-01 +2.273413e-07 5.139555e-01 +2.289179e-07 5.150657e-01 +2.305055e-07 5.161776e-01 +2.321041e-07 5.172911e-01 +2.337138e-07 5.184064e-01 +2.353346e-07 5.195232e-01 +2.369667e-07 5.206417e-01 +2.386101e-07 5.217618e-01 +2.402649e-07 5.228835e-01 +2.419312e-07 5.240069e-01 +2.436090e-07 5.251319e-01 +2.452985e-07 5.262585e-01 +2.469997e-07 5.273867e-01 +2.487126e-07 5.285165e-01 +2.504375e-07 5.296479e-01 +2.521743e-07 5.307809e-01 +2.539232e-07 5.319154e-01 +2.556842e-07 5.330516e-01 +2.574574e-07 5.341892e-01 +2.592429e-07 5.353285e-01 +2.610408e-07 5.364693e-01 +2.628511e-07 5.376116e-01 +2.646740e-07 5.387554e-01 +2.665096e-07 5.399009e-01 +2.683579e-07 5.410478e-01 +2.702190e-07 5.421962e-01 +2.720930e-07 5.433461e-01 +2.739800e-07 5.444976e-01 +2.758801e-07 5.456505e-01 +2.777934e-07 5.468049e-01 +2.797199e-07 5.479607e-01 +2.816598e-07 5.491181e-01 +2.836131e-07 5.502768e-01 +2.855800e-07 5.514370e-01 +2.875606e-07 5.525988e-01 +2.895549e-07 5.537619e-01 +2.915630e-07 5.549264e-01 +2.935850e-07 5.560923e-01 +2.956211e-07 5.572596e-01 +2.976712e-07 5.584283e-01 +2.997356e-07 5.595984e-01 +3.018143e-07 5.607699e-01 +3.039075e-07 5.619428e-01 +3.060151e-07 5.631170e-01 +3.081374e-07 5.642925e-01 +3.102743e-07 5.654694e-01 +3.124261e-07 5.666476e-01 +3.145929e-07 5.678271e-01 +3.167746e-07 5.690079e-01 +3.189715e-07 5.701900e-01 +3.211836e-07 5.713734e-01 +3.234111e-07 5.725581e-01 +3.256540e-07 5.737440e-01 +3.279124e-07 5.749312e-01 +3.301866e-07 5.761196e-01 +3.324764e-07 5.773092e-01 +3.347822e-07 5.785001e-01 +3.371040e-07 5.796922e-01 +3.394418e-07 5.808854e-01 +3.417959e-07 5.820798e-01 +3.441663e-07 5.832754e-01 +3.465532e-07 5.844722e-01 +3.489566e-07 5.856701e-01 +3.513766e-07 5.868691e-01 +3.538135e-07 5.880693e-01 +3.562672e-07 5.892705e-01 +3.587380e-07 5.904729e-01 +3.612259e-07 5.916764e-01 +3.637311e-07 5.928809e-01 +3.662536e-07 5.940864e-01 +3.687936e-07 5.952930e-01 +3.713513e-07 5.965007e-01 +3.739266e-07 5.977093e-01 +3.765199e-07 5.989190e-01 +3.791311e-07 6.001296e-01 +3.817604e-07 6.013412e-01 +3.844080e-07 6.025538e-01 +3.870739e-07 6.037674e-01 +3.897583e-07 6.049818e-01 +3.924614e-07 6.061972e-01 +3.951831e-07 6.074134e-01 +3.979238e-07 6.086306e-01 +4.006834e-07 6.098486e-01 +4.034622e-07 6.110675e-01 +4.062603e-07 6.122873e-01 +4.090778e-07 6.135079e-01 +4.119148e-07 6.147293e-01 +4.147715e-07 6.159514e-01 +4.176480e-07 6.171744e-01 +4.205445e-07 6.183981e-01 +4.234610e-07 6.196226e-01 +4.263978e-07 6.208478e-01 +4.293549e-07 6.220737e-01 +4.323325e-07 6.233003e-01 +4.353308e-07 6.245277e-01 +4.383499e-07 6.257556e-01 +4.413899e-07 6.269843e-01 +4.444510e-07 6.282135e-01 +4.475334e-07 6.294434e-01 +4.506371e-07 6.306739e-01 +4.537623e-07 6.319050e-01 +4.569092e-07 6.331366e-01 +4.600779e-07 6.343687e-01 +4.632687e-07 6.356015e-01 +4.664815e-07 6.368347e-01 +4.697166e-07 6.380684e-01 +4.729742e-07 6.393026e-01 +4.762543e-07 6.405372e-01 +4.795572e-07 6.417723e-01 +4.828830e-07 6.430078e-01 +4.862319e-07 6.442437e-01 +4.896040e-07 6.454800e-01 +4.929994e-07 6.467167e-01 +4.964185e-07 6.479537e-01 +4.998612e-07 6.491910e-01 +5.033278e-07 6.504286e-01 +5.068185e-07 6.516666e-01 +5.103333e-07 6.529047e-01 +5.138726e-07 6.541432e-01 +5.174363e-07 6.553818e-01 +5.210248e-07 6.566207e-01 +5.246382e-07 6.578597e-01 +5.282767e-07 6.590990e-01 +5.319403e-07 6.603383e-01 +5.356294e-07 6.615778e-01 +5.393441e-07 6.628175e-01 +5.430845e-07 6.640571e-01 +5.468509e-07 6.652969e-01 +5.506434e-07 6.665367e-01 +5.544622e-07 6.677765e-01 +5.583075e-07 6.690164e-01 +5.621794e-07 6.702562e-01 +5.660782e-07 6.714959e-01 +5.700040e-07 6.727356e-01 +5.739571e-07 6.739753e-01 +5.779376e-07 6.752148e-01 +5.819457e-07 6.764542e-01 +5.859815e-07 6.776934e-01 +5.900454e-07 6.789325e-01 +5.941375e-07 6.801713e-01 +5.982579e-07 6.814100e-01 +6.024069e-07 6.826484e-01 +6.065847e-07 6.838866e-01 +6.107914e-07 6.851244e-01 +6.150274e-07 6.863620e-01 +6.192927e-07 6.875992e-01 +6.235876e-07 6.888361e-01 +6.279122e-07 6.900726e-01 +6.322669e-07 6.913087e-01 +6.366518e-07 6.925444e-01 +6.410670e-07 6.937796e-01 +6.455129e-07 6.950144e-01 +6.499897e-07 6.962487e-01 +6.544974e-07 6.974824e-01 +6.590365e-07 6.987157e-01 +6.636070e-07 6.999483e-01 +6.682092e-07 7.011804e-01 +6.728433e-07 7.024119e-01 +6.775096e-07 7.036427e-01 +6.822082e-07 7.048729e-01 +6.869395e-07 7.061024e-01 +6.917035e-07 7.073311e-01 +6.965005e-07 7.085592e-01 +7.013309e-07 7.097865e-01 +7.061947e-07 7.110130e-01 +7.110923e-07 7.122387e-01 +7.160238e-07 7.134636e-01 +7.209895e-07 7.146876e-01 +7.259897e-07 7.159107e-01 +7.310246e-07 7.171330e-01 +7.360943e-07 7.183543e-01 +7.411992e-07 7.195747e-01 +7.463396e-07 7.207941e-01 +7.515155e-07 7.220124e-01 +7.567274e-07 7.232298e-01 +7.619754e-07 7.244461e-01 +7.672598e-07 7.256613e-01 +7.725809e-07 7.268755e-01 +7.779389e-07 7.280885e-01 +7.833340e-07 7.293003e-01 +7.887665e-07 7.305110e-01 +7.942367e-07 7.317204e-01 +7.997449e-07 7.329287e-01 +8.052912e-07 7.341356e-01 +8.108761e-07 7.353413e-01 +8.164996e-07 7.365457e-01 +8.221621e-07 7.377488e-01 +8.278640e-07 7.389505e-01 +8.336053e-07 7.401508e-01 +8.393865e-07 7.413498e-01 +8.452078e-07 7.425473e-01 +8.510694e-07 7.437433e-01 +8.569717e-07 7.449378e-01 +8.629149e-07 7.461309e-01 +8.688994e-07 7.473224e-01 +8.749253e-07 7.485123e-01 +8.809931e-07 7.497007e-01 +8.871029e-07 7.508875e-01 +8.932551e-07 7.520726e-01 +8.994499e-07 7.532561e-01 +9.056877e-07 7.544379e-01 +9.119688e-07 7.556179e-01 +9.182935e-07 7.567963e-01 +9.246620e-07 7.579729e-01 +9.310746e-07 7.591477e-01 +9.375318e-07 7.603207e-01 +9.440337e-07 7.614918e-01 +9.505807e-07 7.626611e-01 +9.571731e-07 7.638285e-01 +9.638113e-07 7.649940e-01 +9.704954e-07 7.661575e-01 +9.772260e-07 7.673191e-01 +9.840032e-07 7.684788e-01 +9.908274e-07 7.696364e-01 +9.976989e-07 7.707919e-01 +1.004618e-06 7.719454e-01 +1.011585e-06 7.730968e-01 +1.018601e-06 7.742462e-01 +1.025665e-06 7.753934e-01 +1.032778e-06 7.765384e-01 +1.039941e-06 7.776813e-01 +1.047153e-06 7.788219e-01 +1.054415e-06 7.799603e-01 +1.061727e-06 7.810964e-01 +1.069091e-06 7.822304e-01 +1.076505e-06 7.833619e-01 +1.083971e-06 7.844912e-01 +1.091488e-06 7.856181e-01 +1.099058e-06 7.867426e-01 +1.106680e-06 7.878648e-01 +1.114355e-06 7.889845e-01 +1.122083e-06 7.901017e-01 +1.129865e-06 7.912166e-01 +1.137701e-06 7.923290e-01 +1.145591e-06 7.934388e-01 +1.153536e-06 7.945461e-01 +1.161536e-06 7.956508e-01 +1.169591e-06 7.967529e-01 +1.177702e-06 7.978524e-01 +1.185870e-06 7.989494e-01 +1.194094e-06 8.000437e-01 +1.202375e-06 8.011353e-01 +1.210714e-06 8.022243e-01 +1.219110e-06 8.033105e-01 +1.227565e-06 8.043940e-01 +1.236078e-06 8.054747e-01 +1.244651e-06 8.065528e-01 +1.253283e-06 8.076280e-01 +1.261974e-06 8.087003e-01 +1.270726e-06 8.097698e-01 +1.279539e-06 8.108365e-01 +1.288413e-06 8.119004e-01 +1.297348e-06 8.129612e-01 +1.306345e-06 8.140192e-01 +1.315405e-06 8.150743e-01 +1.324528e-06 8.161265e-01 +1.333713e-06 8.171755e-01 +1.342963e-06 8.182217e-01 +1.352277e-06 8.192649e-01 +1.361655e-06 8.203049e-01 +1.371098e-06 8.213420e-01 +1.380607e-06 8.223760e-01 +1.390182e-06 8.234069e-01 +1.399823e-06 8.244347e-01 +1.409531e-06 8.254593e-01 +1.419306e-06 8.264808e-01 +1.429149e-06 8.274992e-01 +1.439060e-06 8.285143e-01 +1.449041e-06 8.295264e-01 +1.459090e-06 8.305352e-01 +1.469209e-06 8.315408e-01 +1.479398e-06 8.325431e-01 +1.489658e-06 8.335421e-01 +1.499989e-06 8.345379e-01 +1.510392e-06 8.355305e-01 +1.520866e-06 8.365196e-01 +1.531414e-06 8.375055e-01 +1.542034e-06 8.384880e-01 +1.552729e-06 8.394673e-01 +1.563497e-06 8.404431e-01 +1.574340e-06 8.414155e-01 +1.585258e-06 8.423846e-01 +1.596252e-06 8.433502e-01 +1.607323e-06 8.443125e-01 +1.618470e-06 8.452713e-01 +1.629694e-06 8.462266e-01 +1.640996e-06 8.471785e-01 +1.652377e-06 8.481270e-01 +1.663836e-06 8.490719e-01 +1.675375e-06 8.500133e-01 +1.686994e-06 8.509512e-01 +1.698694e-06 8.518857e-01 +1.710474e-06 8.528165e-01 +1.722337e-06 8.537438e-01 +1.734281e-06 8.546676e-01 +1.746309e-06 8.555878e-01 +1.758420e-06 8.565044e-01 +1.770615e-06 8.574175e-01 +1.782894e-06 8.583269e-01 +1.795259e-06 8.592327e-01 +1.807709e-06 8.601349e-01 +1.820246e-06 8.610335e-01 +1.832870e-06 8.619285e-01 +1.845581e-06 8.628198e-01 +1.858380e-06 8.637074e-01 +1.871268e-06 8.645914e-01 +1.884246e-06 8.654718e-01 +1.897313e-06 8.663484e-01 +1.910472e-06 8.672214e-01 +1.923721e-06 8.680907e-01 +1.937062e-06 8.689562e-01 +1.950496e-06 8.698181e-01 +1.964023e-06 8.706763e-01 +1.977644e-06 8.715307e-01 +1.991359e-06 8.723814e-01 +2.005169e-06 8.732284e-01 +2.019076e-06 8.740717e-01 +2.033078e-06 8.749112e-01 +2.047178e-06 8.757470e-01 +2.061375e-06 8.765789e-01 +2.075671e-06 8.774072e-01 +2.090066e-06 8.782317e-01 +2.104561e-06 8.790524e-01 +2.119157e-06 8.798694e-01 +2.133853e-06 8.806826e-01 +2.148652e-06 8.814921e-01 +2.163553e-06 8.822977e-01 +2.178558e-06 8.830996e-01 +2.193666e-06 8.838976e-01 +2.208880e-06 8.846920e-01 +2.224199e-06 8.854825e-01 +2.239624e-06 8.862692e-01 +2.255156e-06 8.870521e-01 +2.270796e-06 8.878313e-01 +2.286544e-06 8.886066e-01 +2.302402e-06 8.893782e-01 +2.318369e-06 8.901459e-01 +2.334447e-06 8.909099e-01 +2.350637e-06 8.916701e-01 +2.366939e-06 8.924264e-01 +2.383354e-06 8.931790e-01 +2.399883e-06 8.939278e-01 +2.416527e-06 8.946728e-01 +2.433286e-06 8.954140e-01 +2.450161e-06 8.961514e-01 +2.467153e-06 8.968850e-01 +2.484263e-06 8.976149e-01 +2.501492e-06 8.983409e-01 +2.518840e-06 8.990632e-01 +2.536309e-06 8.997817e-01 +2.553898e-06 9.004964e-01 +2.571610e-06 9.012073e-01 +2.589444e-06 9.019145e-01 +2.607403e-06 9.026179e-01 +2.625485e-06 9.033175e-01 +2.643694e-06 9.040134e-01 +2.662028e-06 9.047055e-01 +2.680489e-06 9.053938e-01 +2.699079e-06 9.060784e-01 +2.717798e-06 9.067593e-01 +2.736646e-06 9.074364e-01 +2.755625e-06 9.081098e-01 +2.774736e-06 9.087794e-01 +2.793979e-06 9.094453e-01 +2.813355e-06 9.101075e-01 +2.832867e-06 9.107660e-01 +2.852513e-06 9.114208e-01 +2.872295e-06 9.120718e-01 +2.892215e-06 9.127192e-01 +2.912273e-06 9.133629e-01 +2.932470e-06 9.140029e-01 +2.952807e-06 9.146392e-01 +2.973286e-06 9.152719e-01 +2.993906e-06 9.159009e-01 +3.014669e-06 9.165263e-01 +3.035576e-06 9.171479e-01 +3.056628e-06 9.177660e-01 +3.077826e-06 9.183804e-01 +3.099172e-06 9.189912e-01 +3.120665e-06 9.195984e-01 +3.142307e-06 9.202020e-01 +3.164099e-06 9.208019e-01 +3.186043e-06 9.213983e-01 +3.208139e-06 9.219911e-01 +3.230388e-06 9.225803e-01 +3.252791e-06 9.231660e-01 +3.275349e-06 9.237481e-01 +3.298064e-06 9.243266e-01 +3.320937e-06 9.249017e-01 +3.343968e-06 9.254732e-01 +3.367159e-06 9.260412e-01 +3.390511e-06 9.266056e-01 +3.414024e-06 9.271666e-01 +3.437701e-06 9.277241e-01 +3.461542e-06 9.282781e-01 +3.485549e-06 9.288287e-01 +3.509721e-06 9.293758e-01 +3.534062e-06 9.299194e-01 +3.558571e-06 9.304596e-01 +3.583250e-06 9.309964e-01 +3.608101e-06 9.315298e-01 +3.633123e-06 9.320598e-01 +3.658320e-06 9.325864e-01 +3.683691e-06 9.331096e-01 +3.709238e-06 9.336295e-01 +3.734962e-06 9.341460e-01 +3.760864e-06 9.346591e-01 +3.786946e-06 9.351689e-01 +3.813209e-06 9.356754e-01 +3.839654e-06 9.361786e-01 +3.866283e-06 9.366785e-01 +3.893096e-06 9.371751e-01 +3.920096e-06 9.376685e-01 +3.947282e-06 9.381586e-01 +3.974657e-06 9.386454e-01 +4.002222e-06 9.391290e-01 +4.029978e-06 9.396094e-01 +4.057926e-06 9.400866e-01 +4.086069e-06 9.405606e-01 +4.114406e-06 9.410314e-01 +4.142940e-06 9.414990e-01 +4.171672e-06 9.419635e-01 +4.200603e-06 9.424249e-01 +4.229735e-06 9.428831e-01 +4.259069e-06 9.433382e-01 +4.288606e-06 9.437901e-01 +4.318348e-06 9.442390e-01 +4.348297e-06 9.446849e-01 +4.378453e-06 9.451276e-01 +4.408818e-06 9.455673e-01 +4.439394e-06 9.460040e-01 +4.470182e-06 9.464377e-01 +4.501183e-06 9.468683e-01 +4.532399e-06 9.472959e-01 +4.563832e-06 9.477206e-01 +4.595483e-06 9.481423e-01 +4.627353e-06 9.485610e-01 +4.659445e-06 9.489768e-01 +4.691759e-06 9.493897e-01 +4.724297e-06 9.497997e-01 +4.757060e-06 9.502067e-01 +4.790051e-06 9.506109e-01 +4.823271e-06 9.510122e-01 +4.856721e-06 9.514107e-01 +4.890403e-06 9.518063e-01 +4.924319e-06 9.521990e-01 +4.958470e-06 9.525890e-01 +4.992858e-06 9.529762e-01 +5.027484e-06 9.533606e-01 +5.062350e-06 9.537422e-01 +5.097458e-06 9.541210e-01 +5.132810e-06 9.544971e-01 +5.168407e-06 9.548705e-01 +5.204250e-06 9.552412e-01 +5.240343e-06 9.556091e-01 +5.276685e-06 9.559744e-01 +5.313280e-06 9.563370e-01 +5.350128e-06 9.566970e-01 +5.387232e-06 9.570543e-01 +5.424593e-06 9.574090e-01 +5.462214e-06 9.577610e-01 +5.500095e-06 9.581105e-01 +5.538239e-06 9.584574e-01 +5.576647e-06 9.588017e-01 +5.615322e-06 9.591434e-01 +5.654265e-06 9.594826e-01 +5.693479e-06 9.598193e-01 +5.732964e-06 9.601535e-01 +5.772723e-06 9.604852e-01 +5.812757e-06 9.608143e-01 +5.853070e-06 9.611410e-01 +5.893662e-06 9.614653e-01 +5.934535e-06 9.617871e-01 +5.975692e-06 9.621065e-01 +6.017134e-06 9.624234e-01 +6.058864e-06 9.627380e-01 +6.100883e-06 9.630502e-01 +6.143194e-06 9.633600e-01 +6.185797e-06 9.636674e-01 +6.228697e-06 9.639725e-01 +6.271894e-06 9.642753e-01 +6.315390e-06 9.645757e-01 +6.359189e-06 9.648739e-01 +6.403290e-06 9.651698e-01 +6.447698e-06 9.654634e-01 +6.492414e-06 9.657547e-01 +6.537440e-06 9.660438e-01 +6.582778e-06 9.663306e-01 +6.628430e-06 9.666153e-01 +6.674400e-06 9.668977e-01 +6.720688e-06 9.671779e-01 +6.767297e-06 9.674560e-01 +6.814229e-06 9.677319e-01 +6.861486e-06 9.680056e-01 +6.909072e-06 9.682773e-01 +6.956987e-06 9.685467e-01 +7.005235e-06 9.688141e-01 +7.053817e-06 9.690794e-01 +7.102737e-06 9.693426e-01 +7.151995e-06 9.696038e-01 +7.201595e-06 9.698628e-01 +7.251539e-06 9.701199e-01 +7.301830e-06 9.703749e-01 +7.352469e-06 9.706279e-01 +7.403460e-06 9.708789e-01 +7.454804e-06 9.711279e-01 +7.506504e-06 9.713749e-01 +7.558563e-06 9.716200e-01 +7.610982e-06 9.718631e-01 +7.663766e-06 9.721043e-01 +7.716915e-06 9.723436e-01 +7.770433e-06 9.725809e-01 +7.824322e-06 9.728164e-01 +7.878585e-06 9.730499e-01 +7.933224e-06 9.732816e-01 +7.988242e-06 9.735115e-01 +8.043642e-06 9.737395e-01 +8.099426e-06 9.739656e-01 +8.155596e-06 9.741900e-01 +8.212157e-06 9.744125e-01 +8.269109e-06 9.746332e-01 +8.326457e-06 9.748522e-01 +8.384202e-06 9.750694e-01 +8.442348e-06 9.752848e-01 +8.500897e-06 9.754984e-01 +8.559852e-06 9.757104e-01 +8.619215e-06 9.759206e-01 +8.678991e-06 9.761291e-01 +8.739181e-06 9.763359e-01 +8.799789e-06 9.765411e-01 +8.860816e-06 9.767445e-01 +8.922267e-06 9.769463e-01 +8.984145e-06 9.771464e-01 +9.046451e-06 9.773449e-01 +9.109190e-06 9.775418e-01 +9.172363e-06 9.777371e-01 +9.235975e-06 9.779307e-01 +9.300028e-06 9.781228e-01 +9.364525e-06 9.783133e-01 +9.429469e-06 9.785022e-01 +9.494864e-06 9.786895e-01 +9.560712e-06 9.788753e-01 +9.627017e-06 9.790596e-01 +9.693782e-06 9.792424e-01 +9.761010e-06 9.794236e-01 +9.828704e-06 9.796033e-01 +9.896867e-06 9.797816e-01 +9.965504e-06 9.799584e-01 +1.003462e-05 9.801337e-01 +1.010421e-05 9.803075e-01 +1.017428e-05 9.804799e-01 +1.024484e-05 9.806509e-01 +1.031589e-05 9.808204e-01 +1.038743e-05 9.809885e-01 +1.045947e-05 9.811552e-01 +1.053201e-05 9.813206e-01 +1.060505e-05 9.814845e-01 +1.067860e-05 9.816471e-01 +1.075266e-05 9.818083e-01 +1.082723e-05 9.819681e-01 +1.090232e-05 9.821267e-01 +1.097793e-05 9.822838e-01 +1.105406e-05 9.824397e-01 +1.113072e-05 9.825942e-01 +1.120791e-05 9.827475e-01 +1.128564e-05 9.828994e-01 +1.136391e-05 9.830501e-01 +1.144272e-05 9.831995e-01 +1.152208e-05 9.833477e-01 +1.160198e-05 9.834945e-01 +1.168245e-05 9.836402e-01 +1.176347e-05 9.837846e-01 +1.184505e-05 9.839278e-01 +1.192719e-05 9.840698e-01 +1.200991e-05 9.842105e-01 +1.209320e-05 9.843501e-01 +1.217707e-05 9.844885e-01 +1.226152e-05 9.846257e-01 +1.234655e-05 9.847618e-01 +1.243218e-05 9.848967e-01 +1.251840e-05 9.850304e-01 +1.260522e-05 9.851630e-01 +1.269263e-05 9.852945e-01 +1.278066e-05 9.854248e-01 +1.286930e-05 9.855541e-01 +1.295855e-05 9.856822e-01 +1.304842e-05 9.858092e-01 +1.313891e-05 9.859351e-01 +1.323003e-05 9.860600e-01 +1.332178e-05 9.861838e-01 +1.341417e-05 9.863065e-01 +1.350720e-05 9.864282e-01 +1.360087e-05 9.865489e-01 +1.369520e-05 9.866685e-01 +1.379018e-05 9.867870e-01 +1.388581e-05 9.869046e-01 +1.398211e-05 9.870211e-01 +1.407908e-05 9.871367e-01 +1.417672e-05 9.872512e-01 +1.427504e-05 9.873647e-01 +1.437404e-05 9.874773e-01 +1.447372e-05 9.875889e-01 +1.457410e-05 9.876996e-01 +1.467518e-05 9.878092e-01 +1.477695e-05 9.879180e-01 +1.487943e-05 9.880258e-01 +1.498262e-05 9.881326e-01 +1.508653e-05 9.882385e-01 +1.519116e-05 9.883436e-01 +1.529651e-05 9.884477e-01 +1.540259e-05 9.885509e-01 +1.550941e-05 9.886532e-01 +1.561697e-05 9.887546e-01 +1.572528e-05 9.888551e-01 +1.583433e-05 9.889548e-01 +1.594415e-05 9.890536e-01 +1.605472e-05 9.891515e-01 +1.616606e-05 9.892486e-01 +1.627818e-05 9.893448e-01 +1.639107e-05 9.894402e-01 +1.650474e-05 9.895348e-01 +1.661921e-05 9.896285e-01 +1.673446e-05 9.897215e-01 +1.685052e-05 9.898136e-01 +1.696738e-05 9.899049e-01 +1.708505e-05 9.899954e-01 +1.720354e-05 9.900851e-01 +1.732285e-05 9.901740e-01 +1.744299e-05 9.902622e-01 +1.756395e-05 9.903496e-01 +1.768576e-05 9.904362e-01 +1.780842e-05 9.905221e-01 +1.793192e-05 9.906072e-01 +1.805628e-05 9.906915e-01 +1.818150e-05 9.907751e-01 +1.830760e-05 9.908580e-01 +1.843456e-05 9.909402e-01 +1.856241e-05 9.910216e-01 +1.869114e-05 9.911023e-01 +1.882077e-05 9.911824e-01 +1.895129e-05 9.912617e-01 +1.908272e-05 9.913403e-01 +1.921506e-05 9.914182e-01 +1.934832e-05 9.914954e-01 +1.948251e-05 9.915720e-01 +1.961762e-05 9.916478e-01 +1.975367e-05 9.917230e-01 +1.989067e-05 9.917976e-01 +2.002861e-05 9.918715e-01 +2.016751e-05 9.919447e-01 +2.030738e-05 9.920173e-01 +2.044821e-05 9.920892e-01 +2.059002e-05 9.921606e-01 +2.073282e-05 9.922312e-01 +2.087660e-05 9.923013e-01 +2.102139e-05 9.923707e-01 +2.116717e-05 9.924395e-01 +2.131397e-05 9.925078e-01 +2.146178e-05 9.925754e-01 +2.161063e-05 9.926424e-01 +2.176050e-05 9.927088e-01 +2.191141e-05 9.927746e-01 +2.206337e-05 9.928399e-01 +2.221638e-05 9.929045e-01 +2.237046e-05 9.929686e-01 +2.252560e-05 9.930321e-01 +2.268182e-05 9.930951e-01 +2.283912e-05 9.931575e-01 +2.299751e-05 9.932193e-01 +2.315700e-05 9.932806e-01 +2.331760e-05 9.933414e-01 +2.347931e-05 9.934016e-01 +2.364214e-05 9.934613e-01 +2.380610e-05 9.935204e-01 +2.397120e-05 9.935790e-01 +2.413745e-05 9.936371e-01 +2.430484e-05 9.936947e-01 +2.447340e-05 9.937517e-01 +2.464313e-05 9.938083e-01 +2.481403e-05 9.938644e-01 +2.498612e-05 9.939199e-01 +2.515940e-05 9.939750e-01 +2.533389e-05 9.940295e-01 +2.550958e-05 9.940836e-01 +2.568650e-05 9.941372e-01 +2.586463e-05 9.941903e-01 +2.604401e-05 9.942430e-01 +2.622463e-05 9.942951e-01 +2.640650e-05 9.943468e-01 +2.658963e-05 9.943981e-01 +2.677404e-05 9.944489e-01 +2.695972e-05 9.944992e-01 +2.714669e-05 9.945491e-01 +2.733495e-05 9.945985e-01 +2.752453e-05 9.946475e-01 +2.771541e-05 9.946961e-01 +2.790762e-05 9.947442e-01 +2.810117e-05 9.947919e-01 +2.829605e-05 9.948391e-01 +2.849229e-05 9.948860e-01 +2.868989e-05 9.949324e-01 +2.888886e-05 9.949784e-01 +2.908921e-05 9.950240e-01 +2.929094e-05 9.950692e-01 +2.949408e-05 9.951140e-01 +2.969863e-05 9.951583e-01 +2.990459e-05 9.952023e-01 +3.011198e-05 9.952459e-01 +3.032081e-05 9.952891e-01 +3.053109e-05 9.953319e-01 +3.074283e-05 9.953743e-01 +3.095604e-05 9.954163e-01 +3.117072e-05 9.954580e-01 +3.138690e-05 9.954993e-01 +3.160457e-05 9.955402e-01 +3.182375e-05 9.955807e-01 +3.204445e-05 9.956209e-01 +3.226669e-05 9.956607e-01 +3.249046e-05 9.957002e-01 +3.271579e-05 9.957393e-01 +3.294268e-05 9.957781e-01 +3.317114e-05 9.958165e-01 +3.340119e-05 9.958545e-01 +3.363283e-05 9.958923e-01 +3.386608e-05 9.959296e-01 +3.410094e-05 9.959667e-01 +3.433744e-05 9.960034e-01 +3.457557e-05 9.960398e-01 +3.481536e-05 9.960758e-01 +3.505681e-05 9.961115e-01 +3.529993e-05 9.961469e-01 +3.554474e-05 9.961820e-01 +3.579125e-05 9.962168e-01 +3.603947e-05 9.962512e-01 +3.628941e-05 9.962854e-01 +3.654108e-05 9.963192e-01 +3.679450e-05 9.963527e-01 +3.704967e-05 9.963860e-01 +3.730662e-05 9.964189e-01 +3.756535e-05 9.964515e-01 +3.782587e-05 9.964839e-01 +3.808820e-05 9.965159e-01 +3.835234e-05 9.965477e-01 +3.861832e-05 9.965791e-01 +3.888615e-05 9.966103e-01 +3.915583e-05 9.966412e-01 +3.942738e-05 9.966718e-01 +3.970081e-05 9.967022e-01 +3.997614e-05 9.967322e-01 +4.025338e-05 9.967620e-01 +4.053255e-05 9.967916e-01 +4.081365e-05 9.968208e-01 +4.109670e-05 9.968498e-01 +4.138171e-05 9.968785e-01 +4.166870e-05 9.969070e-01 +4.195767e-05 9.969352e-01 +4.224866e-05 9.969632e-01 +4.254166e-05 9.969909e-01 +4.283669e-05 9.970184e-01 +4.313377e-05 9.970456e-01 +4.343291e-05 9.970725e-01 +4.373412e-05 9.970992e-01 +4.403742e-05 9.971257e-01 +4.434283e-05 9.971519e-01 +4.465035e-05 9.971779e-01 +4.496001e-05 9.972037e-01 +4.527182e-05 9.972292e-01 +4.558578e-05 9.972545e-01 +4.590193e-05 9.972796e-01 +4.622026e-05 9.973044e-01 +4.654081e-05 9.973290e-01 +4.686358e-05 9.973534e-01 +4.718858e-05 9.973776e-01 +4.751584e-05 9.974016e-01 +4.784537e-05 9.974253e-01 +4.817719e-05 9.974488e-01 +4.851130e-05 9.974721e-01 +4.884773e-05 9.974952e-01 +4.918650e-05 9.975181e-01 +4.952762e-05 9.975408e-01 +4.987110e-05 9.975632e-01 +5.021696e-05 9.975855e-01 +5.056522e-05 9.976076e-01 +5.091590e-05 9.976294e-01 +5.126901e-05 9.976511e-01 +5.162457e-05 9.976725e-01 +5.198259e-05 9.976938e-01 +5.234310e-05 9.977149e-01 +5.270611e-05 9.977358e-01 +5.307163e-05 9.977565e-01 +5.343969e-05 9.977770e-01 +5.381030e-05 9.977973e-01 +5.418348e-05 9.978174e-01 +5.455926e-05 9.978374e-01 +5.493763e-05 9.978572e-01 +5.531863e-05 9.978768e-01 +5.570228e-05 9.978962e-01 +5.608858e-05 9.979154e-01 +5.647756e-05 9.979345e-01 +5.686924e-05 9.979534e-01 +5.726364e-05 9.979721e-01 +5.766077e-05 9.979906e-01 +5.806066e-05 9.980090e-01 +5.846332e-05 9.980272e-01 +5.886877e-05 9.980453e-01 +5.927703e-05 9.980632e-01 +5.968813e-05 9.980809e-01 +6.010207e-05 9.980984e-01 +6.051889e-05 9.981158e-01 +6.093860e-05 9.981331e-01 +6.136121e-05 9.981502e-01 +6.178676e-05 9.981671e-01 +6.221526e-05 9.981839e-01 +6.264674e-05 9.982005e-01 +6.308120e-05 9.982169e-01 +6.351868e-05 9.982333e-01 +6.395919e-05 9.982494e-01 +6.440276e-05 9.982655e-01 +6.484940e-05 9.982813e-01 +6.529914e-05 9.982971e-01 +6.575200e-05 9.983127e-01 +6.620800e-05 9.983281e-01 +6.666716e-05 9.983434e-01 +6.712951e-05 9.983586e-01 +6.759506e-05 9.983736e-01 +6.806384e-05 9.983885e-01 +6.853587e-05 9.984032e-01 +6.901118e-05 9.984179e-01 +6.948978e-05 9.984323e-01 +6.997171e-05 9.984467e-01 +7.045697e-05 9.984609e-01 +7.094560e-05 9.984750e-01 +7.143762e-05 9.984890e-01 +7.193305e-05 9.985028e-01 +7.243191e-05 9.985165e-01 +7.293424e-05 9.985301e-01 +7.344005e-05 9.985436e-01 +7.394937e-05 9.985569e-01 +7.446222e-05 9.985701e-01 +7.497862e-05 9.985832e-01 +7.549861e-05 9.985962e-01 +7.602221e-05 9.986091e-01 +7.654943e-05 9.986218e-01 +7.708031e-05 9.986344e-01 +7.761488e-05 9.986470e-01 +7.815315e-05 9.986593e-01 +7.869515e-05 9.986716e-01 +7.924091e-05 9.986838e-01 +7.979046e-05 9.986959e-01 +8.034382e-05 9.987078e-01 +8.090102e-05 9.987196e-01 +8.146208e-05 9.987314e-01 +8.202703e-05 9.987430e-01 +8.259590e-05 9.987545e-01 +8.316871e-05 9.987659e-01 +8.374550e-05 9.987772e-01 +8.432629e-05 9.987885e-01 +8.491110e-05 9.987996e-01 +8.549997e-05 9.988106e-01 +8.609293e-05 9.988215e-01 +8.669000e-05 9.988323e-01 +8.729120e-05 9.988430e-01 +8.789658e-05 9.988536e-01 +8.850616e-05 9.988641e-01 +8.911996e-05 9.988745e-01 +8.973802e-05 9.988848e-01 +9.036037e-05 9.988950e-01 +9.098703e-05 9.989052e-01 +9.161804e-05 9.989152e-01 +9.225342e-05 9.989251e-01 +9.289321e-05 9.989350e-01 +9.353744e-05 9.989448e-01 +9.418614e-05 9.989544e-01 +9.483933e-05 9.989640e-01 +9.549706e-05 9.989735e-01 +9.615934e-05 9.989829e-01 +9.682622e-05 9.989923e-01 +9.749773e-05 9.990015e-01 +9.817389e-05 9.990107e-01 +9.885474e-05 9.990197e-01 +9.954031e-05 9.990287e-01 +1.002306e-04 9.990376e-01 +1.009258e-04 9.990464e-01 +1.016257e-04 9.990552e-01 +1.023305e-04 9.990639e-01 +1.030402e-04 9.990724e-01 +1.037548e-04 9.990809e-01 +1.044743e-04 9.990894e-01 +1.051989e-04 9.990977e-01 +1.059284e-04 9.991060e-01 +1.066631e-04 9.991142e-01 +1.074028e-04 9.991223e-01 +1.081476e-04 9.991304e-01 +1.088977e-04 9.991384e-01 +1.096529e-04 9.991463e-01 +1.104133e-04 9.991541e-01 +1.111791e-04 9.991619e-01 +1.119501e-04 9.991695e-01 +1.127265e-04 9.991772e-01 +1.135083e-04 9.991847e-01 +1.142955e-04 9.991922e-01 +1.150881e-04 9.991996e-01 +1.158863e-04 9.992069e-01 +1.166900e-04 9.992142e-01 +1.174992e-04 9.992214e-01 +1.183141e-04 9.992286e-01 +1.191346e-04 9.992356e-01 +1.199608e-04 9.992427e-01 +1.207928e-04 9.992496e-01 +1.216305e-04 9.992565e-01 +1.224740e-04 9.992633e-01 +1.233234e-04 9.992701e-01 +1.241787e-04 9.992768e-01 +1.250399e-04 9.992834e-01 +1.259070e-04 9.992900e-01 +1.267802e-04 9.992965e-01 +1.276595e-04 9.993030e-01 +1.285448e-04 9.993093e-01 +1.294363e-04 9.993157e-01 +1.303339e-04 9.993220e-01 +1.312378e-04 9.993282e-01 +1.321480e-04 9.993344e-01 +1.330644e-04 9.993405e-01 +1.339873e-04 9.993465e-01 +1.349165e-04 9.993525e-01 +1.358522e-04 9.993585e-01 +1.367943e-04 9.993643e-01 +1.377430e-04 9.993702e-01 +1.386983e-04 9.993760e-01 +1.396602e-04 9.993817e-01 +1.406287e-04 9.993874e-01 +1.416040e-04 9.993930e-01 +1.425861e-04 9.993986e-01 +1.435749e-04 9.994041e-01 +1.445706e-04 9.994095e-01 +1.455732e-04 9.994150e-01 +1.465828e-04 9.994203e-01 +1.475994e-04 9.994257e-01 +1.486230e-04 9.994309e-01 +1.496537e-04 9.994361e-01 +1.506916e-04 9.994413e-01 +1.517367e-04 9.994465e-01 +1.527890e-04 9.994515e-01 +1.538486e-04 9.994566e-01 +1.549156e-04 9.994616e-01 +1.559899e-04 9.994665e-01 +1.570717e-04 9.994714e-01 +1.581611e-04 9.994763e-01 +1.592579e-04 9.994811e-01 +1.603624e-04 9.994858e-01 +1.614745e-04 9.994905e-01 +1.625944e-04 9.994952e-01 +1.637220e-04 9.994999e-01 +1.648574e-04 9.995044e-01 +1.660008e-04 9.995090e-01 +1.671520e-04 9.995135e-01 +1.683112e-04 9.995180e-01 +1.694785e-04 9.995224e-01 +1.706538e-04 9.995268e-01 +1.718373e-04 9.995311e-01 +1.730291e-04 9.995354e-01 +1.742290e-04 9.995397e-01 +1.754374e-04 9.995439e-01 +1.766540e-04 9.995481e-01 +1.778792e-04 9.995523e-01 +1.791128e-04 9.995564e-01 +1.803549e-04 9.995604e-01 +1.816057e-04 9.995645e-01 +1.828652e-04 9.995685e-01 +1.841334e-04 9.995724e-01 +1.854104e-04 9.995764e-01 +1.866962e-04 9.995803e-01 +1.879910e-04 9.995841e-01 +1.892948e-04 9.995879e-01 +1.906075e-04 9.995917e-01 +1.919294e-04 9.995955e-01 +1.932605e-04 9.995992e-01 +1.946008e-04 9.996029e-01 +1.959504e-04 9.996065e-01 +1.973093e-04 9.996101e-01 +1.986777e-04 9.996137e-01 +2.000555e-04 9.996172e-01 +2.014430e-04 9.996208e-01 +2.028400e-04 9.996242e-01 +2.042467e-04 9.996277e-01 +2.056632e-04 9.996311e-01 +2.070895e-04 9.996345e-01 +2.085257e-04 9.996379e-01 +2.099719e-04 9.996412e-01 +2.114280e-04 9.996445e-01 +2.128943e-04 9.996477e-01 +2.143708e-04 9.996510e-01 +2.158575e-04 9.996542e-01 +2.173545e-04 9.996574e-01 +2.188619e-04 9.996605e-01 +2.203797e-04 9.996636e-01 +2.219081e-04 9.996667e-01 +2.234470e-04 9.996698e-01 +2.249967e-04 9.996728e-01 +2.265571e-04 9.996758e-01 +2.281283e-04 9.996788e-01 +2.297104e-04 9.996817e-01 +2.313034e-04 9.996847e-01 +2.329076e-04 9.996876e-01 +2.345228e-04 9.996904e-01 +2.361493e-04 9.996933e-01 +2.377870e-04 9.996961e-01 +2.394361e-04 9.996989e-01 +2.410966e-04 9.997017e-01 +2.427686e-04 9.997044e-01 +2.444523e-04 9.997071e-01 +2.461476e-04 9.997098e-01 +2.478547e-04 9.997125e-01 +2.495736e-04 9.997151e-01 +2.513044e-04 9.997177e-01 +2.530472e-04 9.997203e-01 +2.548022e-04 9.997229e-01 +2.565692e-04 9.997254e-01 +2.583486e-04 9.997280e-01 +2.601403e-04 9.997305e-01 +2.619444e-04 9.997329e-01 +2.637610e-04 9.997354e-01 +2.655902e-04 9.997378e-01 +2.674321e-04 9.997402e-01 +2.692868e-04 9.997426e-01 +2.711544e-04 9.997450e-01 +2.730349e-04 9.997473e-01 +2.749284e-04 9.997496e-01 +2.768351e-04 9.997519e-01 +2.787550e-04 9.997542e-01 +2.806882e-04 9.997565e-01 +2.826348e-04 9.997587e-01 +2.845949e-04 9.997609e-01 +2.865686e-04 9.997631e-01 +2.885560e-04 9.997653e-01 +2.905572e-04 9.997675e-01 +2.925722e-04 9.997696e-01 +2.946013e-04 9.997717e-01 +2.966444e-04 9.997738e-01 +2.987016e-04 9.997759e-01 +3.007732e-04 9.997779e-01 +3.028591e-04 9.997800e-01 +3.049595e-04 9.997820e-01 +3.070744e-04 9.997840e-01 +3.092040e-04 9.997860e-01 +3.113484e-04 9.997880e-01 +3.135076e-04 9.997899e-01 +3.156819e-04 9.997918e-01 +3.178712e-04 9.997937e-01 +3.200756e-04 9.997956e-01 +3.222954e-04 9.997975e-01 +3.245306e-04 9.997994e-01 +3.267812e-04 9.998012e-01 +3.290475e-04 9.998030e-01 +3.313295e-04 9.998049e-01 +3.336273e-04 9.998067e-01 +3.359411e-04 9.998084e-01 +3.382709e-04 9.998102e-01 +3.406169e-04 9.998119e-01 +3.429791e-04 9.998137e-01 +3.453577e-04 9.998154e-01 +3.477528e-04 9.998171e-01 +3.501645e-04 9.998187e-01 +3.525930e-04 9.998204e-01 +3.550382e-04 9.998221e-01 +3.575005e-04 9.998237e-01 +3.599798e-04 9.998253e-01 +3.624763e-04 9.998269e-01 +3.649901e-04 9.998285e-01 +3.675214e-04 9.998301e-01 +3.700702e-04 9.998317e-01 +3.726367e-04 9.998332e-01 +3.752210e-04 9.998347e-01 +3.778232e-04 9.998362e-01 +3.804435e-04 9.998378e-01 +3.830819e-04 9.998392e-01 +3.857386e-04 9.998407e-01 +3.884138e-04 9.998422e-01 +3.911075e-04 9.998436e-01 +3.938199e-04 9.998451e-01 +3.965511e-04 9.998465e-01 +3.993012e-04 9.998479e-01 +4.020704e-04 9.998493e-01 +4.048589e-04 9.998507e-01 +4.076666e-04 9.998521e-01 +4.104938e-04 9.998534e-01 +4.133407e-04 9.998548e-01 +4.162073e-04 9.998561e-01 +4.190937e-04 9.998574e-01 +4.220002e-04 9.998587e-01 +4.249268e-04 9.998600e-01 +4.278738e-04 9.998613e-01 +4.308411e-04 9.998626e-01 +4.338291e-04 9.998639e-01 +4.368377e-04 9.998651e-01 +4.398673e-04 9.998663e-01 +4.429178e-04 9.998676e-01 +4.459895e-04 9.998688e-01 +4.490825e-04 9.998700e-01 +4.521970e-04 9.998712e-01 +4.553330e-04 9.998724e-01 +4.584908e-04 9.998735e-01 +4.616705e-04 9.998747e-01 +4.648723e-04 9.998759e-01 +4.680963e-04 9.998770e-01 +4.713426e-04 9.998781e-01 +4.746114e-04 9.998793e-01 +4.779029e-04 9.998804e-01 +4.812172e-04 9.998815e-01 +4.845545e-04 9.998826e-01 +4.879150e-04 9.998836e-01 +4.912988e-04 9.998847e-01 +4.947060e-04 9.998858e-01 +4.981369e-04 9.998868e-01 +5.015915e-04 9.998878e-01 +5.050701e-04 9.998889e-01 +5.085729e-04 9.998899e-01 +5.120999e-04 9.998909e-01 +5.156514e-04 9.998919e-01 +5.192275e-04 9.998929e-01 +5.228284e-04 9.998939e-01 +5.264543e-04 9.998949e-01 +5.301053e-04 9.998958e-01 +5.337817e-04 9.998968e-01 +5.374836e-04 9.998977e-01 +5.412111e-04 9.998987e-01 +5.449645e-04 9.998996e-01 +5.487439e-04 9.999005e-01 +5.525495e-04 9.999014e-01 +5.563815e-04 9.999024e-01 +5.602401e-04 9.999032e-01 +5.641254e-04 9.999041e-01 +5.680377e-04 9.999050e-01 +5.719772e-04 9.999059e-01 +5.759439e-04 9.999068e-01 +5.799382e-04 9.999076e-01 +5.839601e-04 9.999085e-01 +5.880100e-04 9.999093e-01 +5.920879e-04 9.999101e-01 +5.961941e-04 9.999110e-01 +6.003288e-04 9.999118e-01 +6.044922e-04 9.999126e-01 +6.086844e-04 9.999134e-01 +6.129058e-04 9.999142e-01 +6.171563e-04 9.999150e-01 +6.214364e-04 9.999158e-01 +6.257462e-04 9.999165e-01 +6.300858e-04 9.999173e-01 +6.344555e-04 9.999181e-01 +6.388556e-04 9.999188e-01 +6.432862e-04 9.999196e-01 +6.477474e-04 9.999203e-01 +6.522397e-04 9.999210e-01 +6.567630e-04 9.999218e-01 +6.613178e-04 9.999225e-01 +6.659041e-04 9.999232e-01 +6.705223e-04 9.999239e-01 +6.751724e-04 9.999246e-01 +6.798549e-04 9.999253e-01 +6.845698e-04 9.999260e-01 +6.893173e-04 9.999267e-01 +6.940979e-04 9.999273e-01 +6.989115e-04 9.999280e-01 +7.037586e-04 9.999287e-01 +7.086393e-04 9.999293e-01 +7.135538e-04 9.999300e-01 +7.185024e-04 9.999306e-01 +7.234853e-04 9.999312e-01 +7.285028e-04 9.999319e-01 +7.335551e-04 9.999325e-01 +7.386424e-04 9.999331e-01 +7.437650e-04 9.999337e-01 +7.489231e-04 9.999343e-01 +7.541170e-04 9.999350e-01 +7.593469e-04 9.999355e-01 +7.646131e-04 9.999361e-01 +7.699158e-04 9.999367e-01 +7.752553e-04 9.999373e-01 +7.806318e-04 9.999379e-01 +7.860456e-04 9.999385e-01 +7.914969e-04 9.999390e-01 +7.969861e-04 9.999396e-01 +8.025133e-04 9.999401e-01 +8.080788e-04 9.999407e-01 +8.136830e-04 9.999412e-01 +8.193260e-04 9.999418e-01 +8.250081e-04 9.999423e-01 +8.307297e-04 9.999428e-01 +8.364909e-04 9.999434e-01 +8.422921e-04 9.999439e-01 +8.481335e-04 9.999444e-01 +8.540155e-04 9.999449e-01 +8.599382e-04 9.999454e-01 +8.659020e-04 9.999459e-01 +8.719071e-04 9.999464e-01 +8.779539e-04 9.999469e-01 +8.840427e-04 9.999474e-01 +8.901737e-04 9.999479e-01 +8.963471e-04 9.999484e-01 +9.025634e-04 9.999488e-01 +9.088229e-04 9.999493e-01 +9.151257e-04 9.999498e-01 +9.214722e-04 9.999502e-01 +9.278628e-04 9.999507e-01 +9.342976e-04 9.999511e-01 +9.407771e-04 9.999516e-01 +9.473015e-04 9.999520e-01 +9.538712e-04 9.999525e-01 +9.604865e-04 9.999529e-01 +9.671476e-04 9.999533e-01 +9.738549e-04 9.999538e-01 +9.806087e-04 9.999542e-01 +9.874094e-04 9.999546e-01 +9.942572e-04 9.999550e-01 +1.001153e-03 9.999555e-01 +1.008096e-03 9.999559e-01 +1.015087e-03 9.999563e-01 +1.022127e-03 9.999567e-01 +1.029215e-03 9.999571e-01 +1.036353e-03 9.999575e-01 +1.043540e-03 9.999579e-01 +1.050777e-03 9.999582e-01 +1.058065e-03 9.999586e-01 +1.065403e-03 9.999590e-01 +1.072791e-03 9.999594e-01 +1.080231e-03 9.999598e-01 +1.087723e-03 9.999601e-01 +1.095266e-03 9.999605e-01 +1.102862e-03 9.999609e-01 +1.110511e-03 9.999612e-01 +1.118212e-03 9.999616e-01 +1.125967e-03 9.999619e-01 +1.133776e-03 9.999623e-01 +1.141639e-03 9.999626e-01 +1.149556e-03 9.999630e-01 +1.157529e-03 9.999633e-01 +1.165556e-03 9.999636e-01 +1.173640e-03 9.999640e-01 +1.181779e-03 9.999643e-01 +1.189975e-03 9.999646e-01 +1.198227e-03 9.999650e-01 +1.206537e-03 9.999653e-01 +1.214905e-03 9.999656e-01 +1.223330e-03 9.999659e-01 +1.231814e-03 9.999662e-01 +1.240357e-03 9.999665e-01 +1.248959e-03 9.999668e-01 +1.257621e-03 9.999672e-01 +1.266343e-03 9.999675e-01 +1.275125e-03 9.999678e-01 +1.283968e-03 9.999681e-01 +1.292873e-03 9.999683e-01 +1.301839e-03 9.999686e-01 +1.310867e-03 9.999689e-01 +1.319959e-03 9.999692e-01 +1.329113e-03 9.999695e-01 +1.338330e-03 9.999698e-01 +1.347612e-03 9.999701e-01 +1.356958e-03 9.999703e-01 +1.366368e-03 9.999706e-01 +1.375844e-03 9.999709e-01 +1.385386e-03 9.999711e-01 +1.394994e-03 9.999714e-01 +1.404668e-03 9.999717e-01 +1.414410e-03 9.999719e-01 +1.424219e-03 9.999722e-01 +1.434096e-03 9.999724e-01 +1.444042e-03 9.999727e-01 +1.454057e-03 9.999729e-01 +1.464141e-03 9.999732e-01 +1.474295e-03 9.999734e-01 +1.484519e-03 9.999737e-01 +1.494814e-03 9.999739e-01 +1.505181e-03 9.999742e-01 +1.515620e-03 9.999744e-01 +1.526131e-03 9.999746e-01 +1.536715e-03 9.999749e-01 +1.547372e-03 9.999751e-01 +1.558103e-03 9.999753e-01 +1.568909e-03 9.999756e-01 +1.579790e-03 9.999758e-01 +1.590746e-03 9.999760e-01 +1.601778e-03 9.999762e-01 +1.612886e-03 9.999764e-01 +1.624072e-03 9.999767e-01 +1.635335e-03 9.999769e-01 +1.646677e-03 9.999771e-01 +1.658097e-03 9.999773e-01 +1.669596e-03 9.999775e-01 +1.681175e-03 9.999777e-01 +1.692834e-03 9.999779e-01 +1.704574e-03 9.999781e-01 +1.716395e-03 9.999783e-01 +1.728299e-03 9.999785e-01 +1.740285e-03 9.999787e-01 +1.752354e-03 9.999789e-01 +1.764507e-03 9.999791e-01 +1.776744e-03 9.999793e-01 +1.789066e-03 9.999795e-01 +1.801473e-03 9.999797e-01 +1.813967e-03 9.999799e-01 +1.826547e-03 9.999801e-01 +1.839214e-03 9.999802e-01 +1.851969e-03 9.999804e-01 +1.864813e-03 9.999806e-01 +1.877746e-03 9.999808e-01 +1.890768e-03 9.999810e-01 +1.903881e-03 9.999811e-01 +1.917085e-03 9.999813e-01 +1.930380e-03 9.999815e-01 +1.943768e-03 9.999816e-01 +1.957248e-03 9.999818e-01 +1.970822e-03 9.999820e-01 +1.984490e-03 9.999821e-01 +1.998252e-03 9.999823e-01 +2.012110e-03 9.999825e-01 +2.026065e-03 9.999826e-01 +2.040116e-03 9.999828e-01 +2.054264e-03 9.999829e-01 +2.068511e-03 9.999831e-01 +2.082856e-03 9.999833e-01 +2.097301e-03 9.999834e-01 +2.111846e-03 9.999836e-01 +2.126492e-03 9.999837e-01 +2.141240e-03 9.999839e-01 +2.156090e-03 9.999840e-01 +2.171043e-03 9.999842e-01 +2.186099e-03 9.999843e-01 +2.201260e-03 9.999845e-01 +2.216526e-03 9.999846e-01 +2.231898e-03 9.999847e-01 +2.247377e-03 9.999849e-01 +2.262962e-03 9.999850e-01 +2.278656e-03 9.999852e-01 +2.294459e-03 9.999853e-01 +2.310372e-03 9.999854e-01 +2.326394e-03 9.999856e-01 +2.342528e-03 9.999857e-01 +2.358774e-03 9.999858e-01 +2.375133e-03 9.999860e-01 +2.391604e-03 9.999861e-01 +2.408191e-03 9.999862e-01 +2.424892e-03 9.999863e-01 +2.441709e-03 9.999865e-01 +2.458642e-03 9.999866e-01 +2.475693e-03 9.999867e-01 +2.492863e-03 9.999868e-01 +2.510151e-03 9.999870e-01 +2.527559e-03 9.999871e-01 +2.545088e-03 9.999872e-01 +2.562739e-03 9.999873e-01 +2.580512e-03 9.999874e-01 +2.598408e-03 9.999875e-01 +2.616428e-03 9.999877e-01 +2.634574e-03 9.999878e-01 +2.652845e-03 9.999879e-01 +2.671243e-03 9.999880e-01 +2.689768e-03 9.999881e-01 +2.708422e-03 9.999882e-01 +2.727205e-03 9.999883e-01 +2.746119e-03 9.999884e-01 +2.765164e-03 9.999885e-01 +2.784341e-03 9.999886e-01 +2.803650e-03 9.999887e-01 +2.823094e-03 9.999888e-01 +2.842673e-03 9.999890e-01 +2.862387e-03 9.999891e-01 +2.882238e-03 9.999892e-01 +2.902227e-03 9.999893e-01 +2.922354e-03 9.999894e-01 +2.942621e-03 9.999895e-01 +2.963029e-03 9.999895e-01 +2.983578e-03 9.999896e-01 +3.004269e-03 9.999897e-01 +3.025104e-03 9.999898e-01 +3.046084e-03 9.999899e-01 +3.067209e-03 9.999900e-01 +3.088481e-03 9.999901e-01 +3.109900e-03 9.999902e-01 +3.131467e-03 9.999903e-01 +3.153184e-03 9.999904e-01 +3.175052e-03 9.999905e-01 +3.197072e-03 9.999906e-01 +3.219244e-03 9.999906e-01 +3.241570e-03 9.999907e-01 +3.264051e-03 9.999908e-01 +3.286687e-03 9.999909e-01 +3.309481e-03 9.999910e-01 +3.332433e-03 9.999911e-01 +3.355544e-03 9.999911e-01 +3.378815e-03 9.999912e-01 +3.402247e-03 9.999913e-01 +3.425842e-03 9.999914e-01 +3.449601e-03 9.999915e-01 +3.473525e-03 9.999915e-01 +3.497614e-03 9.999916e-01 +3.521871e-03 9.999917e-01 +3.546295e-03 9.999918e-01 +3.570889e-03 9.999919e-01 +3.595654e-03 9.999919e-01 +3.620590e-03 9.999920e-01 +3.645700e-03 9.999921e-01 +3.670983e-03 9.999921e-01 +3.696442e-03 9.999922e-01 +3.722077e-03 9.999923e-01 +3.747890e-03 9.999924e-01 +3.773883e-03 9.999924e-01 +3.800055e-03 9.999925e-01 +3.826409e-03 9.999926e-01 +3.852946e-03 9.999926e-01 +3.879667e-03 9.999927e-01 +3.906573e-03 9.999928e-01 +3.933665e-03 9.999928e-01 +3.960946e-03 9.999929e-01 +3.988416e-03 9.999930e-01 +4.016076e-03 9.999930e-01 +4.043928e-03 9.999931e-01 +4.071973e-03 9.999932e-01 +4.100213e-03 9.999932e-01 +4.128648e-03 9.999933e-01 +4.157281e-03 9.999934e-01 +4.186113e-03 9.999934e-01 +4.215144e-03 9.999935e-01 +4.244377e-03 9.999935e-01 +4.273812e-03 9.999936e-01 +4.303451e-03 9.999937e-01 +4.333297e-03 9.999937e-01 +4.363349e-03 9.999938e-01 +4.393609e-03 9.999938e-01 +4.424079e-03 9.999939e-01 +4.454761e-03 9.999939e-01 +4.485655e-03 9.999940e-01 +4.516764e-03 9.999940e-01 +4.548089e-03 9.999941e-01 +4.579630e-03 9.999942e-01 +4.611391e-03 9.999942e-01 +4.643371e-03 9.999943e-01 +4.675574e-03 9.999943e-01 +4.708000e-03 9.999944e-01 +4.740650e-03 9.999944e-01 +4.773527e-03 9.999945e-01 +4.806633e-03 9.999945e-01 +4.839967e-03 9.999946e-01 +4.873533e-03 9.999946e-01 +4.907332e-03 9.999947e-01 +4.941365e-03 9.999947e-01 +4.975634e-03 9.999948e-01 +5.010141e-03 9.999948e-01 +5.044887e-03 9.999949e-01 +5.079874e-03 9.999949e-01 +5.115104e-03 9.999950e-01 +5.150578e-03 9.999950e-01 +5.186298e-03 9.999951e-01 +5.222265e-03 9.999951e-01 +5.258482e-03 9.999951e-01 +5.294951e-03 9.999952e-01 +5.331672e-03 9.999952e-01 +5.368648e-03 9.999953e-01 +5.405880e-03 9.999953e-01 +5.443371e-03 9.999954e-01 +5.481122e-03 9.999954e-01 +5.519134e-03 9.999954e-01 +5.557410e-03 9.999955e-01 +5.595951e-03 9.999955e-01 +5.634760e-03 9.999956e-01 +5.673838e-03 9.999956e-01 +5.713187e-03 9.999957e-01 +5.752809e-03 9.999957e-01 +5.792705e-03 9.999957e-01 +5.832879e-03 9.999958e-01 +5.873331e-03 9.999958e-01 +5.914063e-03 9.999958e-01 +5.955078e-03 9.999959e-01 +5.996377e-03 9.999959e-01 +6.037963e-03 9.999960e-01 +6.079837e-03 9.999960e-01 +6.122002e-03 9.999960e-01 +6.164459e-03 9.999961e-01 +6.207210e-03 9.999961e-01 +6.250258e-03 9.999961e-01 +6.293605e-03 9.999962e-01 +6.337252e-03 9.999962e-01 +6.381201e-03 9.999962e-01 +6.425456e-03 9.999963e-01 +6.470017e-03 9.999963e-01 +6.514888e-03 9.999964e-01 +6.560070e-03 9.999964e-01 +6.605565e-03 9.999964e-01 +6.651375e-03 9.999965e-01 +6.697504e-03 9.999965e-01 +6.743952e-03 9.999965e-01 +6.790722e-03 9.999965e-01 +6.837817e-03 9.999966e-01 +6.885238e-03 9.999966e-01 +6.932988e-03 9.999966e-01 +6.981069e-03 9.999967e-01 +7.029484e-03 9.999967e-01 +7.078235e-03 9.999967e-01 +7.127323e-03 9.999968e-01 +7.176752e-03 9.999968e-01 +7.226524e-03 9.999968e-01 +7.276641e-03 9.999969e-01 +7.327106e-03 9.999969e-01 +7.377920e-03 9.999969e-01 +7.429087e-03 9.999969e-01 +7.480609e-03 9.999970e-01 +7.532488e-03 9.999970e-01 +7.584727e-03 9.999970e-01 +7.637328e-03 9.999971e-01 +7.690295e-03 9.999971e-01 +7.743628e-03 9.999971e-01 +7.797331e-03 9.999971e-01 +7.851407e-03 9.999972e-01 +7.905857e-03 9.999972e-01 +7.960686e-03 9.999972e-01 +8.015894e-03 9.999972e-01 +8.071486e-03 9.999973e-01 +8.127463e-03 9.999973e-01 +8.183828e-03 9.999973e-01 +8.240584e-03 9.999973e-01 +8.297733e-03 9.999974e-01 +8.355279e-03 9.999974e-01 +8.413225e-03 9.999974e-01 +8.471572e-03 9.999974e-01 +8.530323e-03 9.999975e-01 +8.589482e-03 9.999975e-01 +8.649052e-03 9.999975e-01 +8.709034e-03 9.999975e-01 +8.769432e-03 9.999975e-01 +8.830250e-03 9.999976e-01 +8.891489e-03 9.999976e-01 +8.953153e-03 9.999976e-01 +9.015244e-03 9.999976e-01 +9.077766e-03 9.999977e-01 +9.140722e-03 9.999977e-01 +9.204114e-03 9.999977e-01 +9.267946e-03 9.999977e-01 +9.332221e-03 9.999977e-01 +9.396941e-03 9.999978e-01 +9.462110e-03 9.999978e-01 +9.527731e-03 9.999978e-01 +9.593807e-03 9.999978e-01 +9.660342e-03 9.999978e-01 +9.727338e-03 9.999979e-01 +9.794798e-03 9.999979e-01 +9.862727e-03 9.999979e-01 +9.931126e-03 9.999979e-01 +1.000000e-02 9.999979e-01 diff --git a/base/Sulfaco/Sulfaco b/base/Sulfaco/Sulfaco index f0c43c6e..ed5bd207 100644 --- a/base/Sulfaco/Sulfaco +++ b/base/Sulfaco/Sulfaco @@ -1,103 +1,90 @@ +# Time(1) ph(2) c_oh(3) c_h(4) c_ca(5) c_caoh(6) c_h2sio4(7) c_h3sio4(8) c_h4sio4(9) c_cah2sio4(10) c_cah3sio4(11) c_h2so4(12) c_hso4(13) c_so4(14) c_caso4aq(15) c_cahso4(16) c_k(17) c_koh(18) zn_ca_s(19) zn_si_s(20) s_ch(21) s_csh2(22) n_ch(23) n_csh2(24) n_csh(25) porosite(26) potentiel_electrique(27) charge(28) V_CSH(29) C/S(30) W_Si(31) W_Ca(32) W_S(33) P_CSH2(34) Damage(35) c_al(36) c_alo4h4(37) zn_al_s(38) s_ah3(39) s_afm(40) s_aft(41) s_c3ah6(42) n_ah3(43) n_afm(44) n_aft(45) n_c3ah6(46) W_Al(47) W_q(48) N_Ca(49) N_Si(50) N_S(51) N_Al(52) N_K(53) N_Cl(54) Saturation degree of crystal(55) Pore entry radius(56) Equilibrium saturation index of AFt(57) Crystallization pressure(58) Strain(59) + Units Length = decimeter Time = second Mass = hectogram - Geometry Dimension = 1 axis - Mesh 4 -0. 0. 1 1 +0. 0. 1. 1. 1. 1 1 1 1 1 1 - Material -Model = Sulfaco +Model = Sulfaco porosity = 0.2 -N_CH = 1.9637 -N_CSH = 1.279 -N_AH3 = 0 -N_CSH2 = 1.e-5 -N_AFm = 2 +N_CH = 1.53 +N_CSH = 1.393 +N_AH3 = 1.e-6 +N_CSH2 = 0 +N_AFm = 0 N_AFt = 0 -N_C3AH6 = 0 +N_C3AH6 = 0.114 R_CSH2 = 0 -R_AFm = 1.e-6 -R_AFt = 1.e-7 -R_C3AH6 = 0 -Curves_log = Sat r = Range{r1 = 1.e-8 , r2 = 2.e-5 , n = 1000} S_r = Expressions(1){r0=15.979e-8; m = 0.4388 ; S_r = (1 + (r0/r)**(1/(1-m)))**(-m)} -#Curves_log = Sat r = Range{r1 = 1.e-8 , r2 = 1.e-5 , n = 1000} S_r = Expressions(1){a = 5.72 ; m = 0.438 ; V_w = 18.e-3 ; Gamma_lg = 0.072 ; RT = 2436.e2 ; r0 = a*V_w/RT*2*Gamma_lg ; S_r = (1 + (r0/r)**(1/(1-m)))**(-m)} -a_AFt = 9e-8 +R_AFm = 0 +R_C3AH6 = 1.e-7 +Curves_log = Sat r = Range{r1 = 1.e-8 , r2 = 1.e-2 , n = 2000} S_r = Expressions(1){r0=155.82e-8; m = 0.2516 ; S_r = (1 + (r0/r)**(1/(1-m)))**(-m)} +A_i = 9e-9 K_bulk = 20.e9 -Strain0 = 1e-5 -Strainf = 3.9e-4 -A_p = 3e-10 -AlphaCoef = 0 #2.55 -BetaCoef = 15.87 - +Strain0 = 6e-4 +Strainf = 3.9e-3 +A_p = 1.1e-9 Fields 1 -Value = 1 Gradient = 0 0 0 Point = 0 0 0 - +Value = 1 Gradient = 0 0 0 Point = 0 0 0 Initialization 5 -Region = 2 Unknown = logc_h2so4 Field = 1 Function = 1 -Region = 2 Unknown = psi Field = 0 Function = 0 -Region = 2 Unknown = z_ca Field = 1 Function = 4 -Region = 2 Unknown = z_al Field = 1 Function = 3 -Region = 2 Unknown = logc_k Field = 1 Function = 2 -#Region = 2 Unknown = logc_oh Field = 1 Function = 5 - +Region = 2 Unknown = logc_h2so4 Field = 1 Function = 1 +Region = 2 Unknown = psi Field = 0 Function = 0 +Region = 2 Unknown = z_ca Field = 1 Function = 4 +Region = 2 Unknown = z_al Field = 1 Function = 3 +Region = 2 Unknown = logc_k Field = 1 Function = 2 +#Region = 2 Unknown = logc_oh Field = 1 Function = 5 Functions 5 -N = 2 F(0) = -29.6 F(86400) = -29.6 -N = 2 F(0) = -0.9 F(86400) = -0.9 -N = 2 F(0) = -8 F(86400) = -8 -N = 2 F(0) = 0 F(86400) = 0 -N = 2 F(0) = -0.94 F(86400) = -0.94 - +N = 2 F(0) = -35 F(86400) = -29.6 +N = 2 F(0) = -90 F(86400) = -0.12 +N = 2 F(0) = -6.32 F(86400) = -6.32 +N = 2 F(0) = 1 F(86400) = 1 +N = 2 F(0) = 0 F(86400) = -7.2 Boundary Conditions -1 -#Region = 2 Unknown = logc_h2so4 Field = 2 Function = 0 -Region = 2 Unknown = psi Field = 0 Function = 0 +3 +Region = 2 Unknown = logc_h2so4 Field = 1 Function = 1 +Region = 2 Unknown = psi Field = 0 Function = 0 #Region = 2 Unknown = z_ca Field = 1 Function = 4 -#Region = 2 Unknown = z_al Field = 1 Function = 3 -#Region = 2 Unknown = logc_k Field = 1 Function = 2 -#Region = 2 Unknown = logc_oh Field = 1 Function = 5 - +#Region = 2 Unknown = z_al Field = 1 Function = 3 +Region = 2 Unknown = logc_k Field = 1 Function = 2 +#Region = 2 Unknown = logc_oh Field = 1 Function = 5 Loads 0 - Points 1 0.5 - Dates 2 -0 3.1536e7 - +0. 1.38e7 #1.15e4 1.156e4 1.1564e4 1.1566e4 1.15663e4 1.156664e4 2.78e4 9.05e4 6e5 1.0e6 2.62e6 4.29e6 5.2e6 7.68e6 8.17e6 9.3e6 9.62e6 9.83e6 1.0e7 1.03e7 1.05e7 1.08e7 1.1e7 1.21e7 1.24e7 1.38e7 Objective Variations @@ -109,14 +96,12 @@ z_al = 1.e-1 logc_oh = 1.e-1 - Iterative Process Iter = 40 Tol = 1.e-4 -Repetition = 2 - +Repetition = 0 Time Steps -Dtini = 1. -Dtmax = 1.e9 +Dtini = 1.e-5 +Dtmax = 1.e4 diff --git a/base/Sulfaco/Sulfaco.gp b/base/Sulfaco/Sulfaco.gp index 47cc33c5..f2a8266c 100644 --- a/base/Sulfaco/Sulfaco.gp +++ b/base/Sulfaco/Sulfaco.gp @@ -47,18 +47,12 @@ set linetype cycle 15 # Input files -file1 = 'RVE1' -file2 = 'RVE2' -file3 = 'RVE3' +file1 = 'Sulfaco' # Files file1p1 = file1.'.p1' -file2p1 = file2.'.p1' -file3p1 = file3.'.p1' fileI = file1p1 -fileII = file2p1 -fileIII = file3p1 @@ -93,7 +87,7 @@ set ylabel "Strain (-)" font ",24" y0 = 0 y1 = 5 set yrange [y0:y1] noreverse nowriteback -set ytics nomirror +set ytics 0.001 nomirror set tics in set autoscale y #set y2label "Gipsum content (mol/L)" font ",24" @@ -115,8 +109,7 @@ set origin 0,0 plot \ fileI us ($1/day):($59) w l lt 1 title '1' \ - ,fileII us ($1/day):($59) w l lt 2 title '2' \ - ,fileIII us ($1/day):($59) w l lt 3 title '3' \ + reset @@ -167,7 +160,6 @@ set origin 0,0 plot \ fileI us ($1/day):($41) w l lt 1 title '1' \ - ,fileII us ($1/day):($41) w l lt 2 title '2' \ reset @@ -218,7 +210,6 @@ set origin 0,0 plot \ fileI us ($1/day):($45) w l lt 1 title '1' \ - ,fileII us ($1/day):($45) w l lt 2 title '2' \ reset @@ -269,8 +260,6 @@ set origin 0,0 plot \ fileI us ($1/day):($58) w l lt 1 title '1' \ - ,fileII us ($1/day):($58) w l lt 2 title '2' \ - ,fileIII us ($1/day):($58) w l lt 3 title '3' \ reset @@ -299,7 +288,7 @@ set ylabel "pH (-)" font ",24" y0 = 0 y1 = 14 set yrange [y0:y1] noreverse nowriteback -set ytics 1 nomirror +set ytics 0.05 nomirror set tics in set autoscale y #set y2label "Gipsum content (mol/L)" font ",24" @@ -321,8 +310,6 @@ set origin 0,0 plot \ fileI us ($1/day):($2) w l lt 1 title '1' \ - ,fileII us ($1/day):($2) w l lt 2 title '2' \ - ,fileIII us ($1/day):($2) w l lt 3 title '3' \ reset @@ -374,18 +361,7 @@ set origin 0,0 plot \ fileI us ($1/day):($41/$57) w l lt 1 title '1: supersat AFt' \ ,fileI us ($1/day):($22) w l lt 2 title '1: CSH_2' \ - ,fileII us ($1/day):($41/$57) w l lt 3 title '2: supersat AFt' \ - ,fileII us ($1/day):($22) w l lt 4 title '2: CSH_2' \ - ,fileIII us ($1/day):($41/$57) w l lt 5 title '3: supersat AFt' \ - ,fileIII us ($1/day):($22) w l lt 6 title '3: CSH_2' \ -# fileI us ($1/day):($41) w l lt 1 title '1: AFt' \ -# ,fileII us ($1/day):($41) w l lt 3 title '2: AFt' \ -# ,fileIII us ($1/day):($41) w l lt 5 title '3: AFt' \ -# ,fileI us ($1/day):($42) w l lt 2 title '1: C_3AH_6' \ -# ,fileII us ($1/day):($42) w l lt 5 title '2: C_3AH_6' \ -# ,fileI us ($1/day):($41/$57) w l lt 3 title '1: supersat AFt' \ -# ,fileII us ($1/day):($41/$57) w l lt 6 title '2: supersat AFt' \ reset @@ -439,12 +415,6 @@ plot \ fileI us ($1/day):($23) w l lt 7 title '1: CH' \ ,fileI us ($1/day):($45) w l lt 1 title '1: AFt' \ ,fileI us ($1/day):($46) w l lt 3 title '1: C_3AH_6' \ - ,fileII us ($1/day):($23) w l lt 8 title '2: CH' \ - ,fileII us ($1/day):($45) w l lt 4 title '2: AFt' \ - ,fileII us ($1/day):($46) w l lt 5 title '2: C_3AH_6' \ - ,fileIII us ($1/day):($23) w l lt 2 title '3: CH' \ - ,fileIII us ($1/day):($45) w l lt 6 title '3: AFt' \ - ,fileIII us ($1/day):($46) w l lt 9 title '3: C_3AH_6' \ reset @@ -496,8 +466,6 @@ set origin 0,0 plot \ fileI us ($1/day):(10**$14) w l lt 1 title '1: SO@_4^{-2}' \ - ,fileII us ($1/day):(10**$14) w l lt 2 title '2: SO@_4^{-2}' \ - ,fileIII us ($1/day):(10**$14) w l lt 3 title '3: SO@_4^{-2}' \ reset @@ -538,7 +506,6 @@ set origin 0,0 plot \ fileI us ($59):($55*$58) w l lt 1 title '1' \ - ,fileII us ($59):($55*$58) w l lt 2 title '2' \ @@ -582,7 +549,6 @@ set origin 0,0 plot \ fileI us ($1/day):($28) w l lt 1 title '1' \ - ,fileII us ($1/day):($28) w l lt 2 title '2' \ diff --git a/base/Sulfaco/Sulfaco.msh b/base/Sulfaco/Sulfaco.msh new file mode 100644 index 00000000..0b8ccbe4 --- /dev/null +++ b/base/Sulfaco/Sulfaco.msh @@ -0,0 +1,13 @@ +$NOD +4 +1 0.000000e+00 0 0 +2 0.000000e+00 0 0 +3 1.000000e+00 0 0 +4 1.000000e+00 0 0 +$ENDNOD +$ELM +3 +1 15 1 1 1 2 +2 1 1 2 2 2 3 +3 15 1 3 1 3 +$ENDELM diff --git a/base/Sulfaco/Sulfaco.p1 b/base/Sulfaco/Sulfaco.p1 new file mode 100644 index 00000000..c66ed810 --- /dev/null +++ b/base/Sulfaco/Sulfaco.p1 @@ -0,0 +1,80 @@ +# Version 2.6, Fri Aug 24 08:20:53 2018 +# Point = 5.000000e-01 0 0 +# Model = Sulfaco +# Number of views = 58 +# Numbers of components per view = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +# Time(1) ph(2) c_oh(3) c_h(4) c_ca(5) c_caoh(6) c_h2sio4(7) c_h3sio4(8) c_h4sio4(9) c_cah2sio4(10) c_cah3sio4(11) c_h2so4(12) c_hso4(13) c_so4(14) c_caso4aq(15) c_cahso4(16) c_k(17) c_koh(18) zn_ca_s(19) zn_si_s(20) s_ch(21) s_csh2(22) n_ch(23) n_csh2(24) n_csh(25) porosite(26) potentiel_electrique(27) charge(28) V_CSH(29) C/S(30) W_Si(31) W_Ca(32) W_S(33) P_CSH2(34) Damage(35) c_al(36) c_alo4h4(37) zn_al_s(38) s_ah3(39) s_afm(40) s_aft(41) s_c3ah6(42) n_ah3(43) n_afm(44) n_aft(45) n_c3ah6(46) W_Al(47) W_q(48) N_Ca(49) N_Si(50) N_S(51) N_Al(52) N_K(53) N_Cl(54) Saturation degree of crystal(55) Pore entry radius(56) Equilibrium saturation index of AFt(57) Crystallization pressure(58) Strain(59) + 0.000000e+00 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203517e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924977e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -6.148822e-18 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243450e+01 -5.614166e+00 -6.320000e+00 4.786301e-07 3.508909e-02 1.879832e-01 8.536541e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695232e-06 2.280017e-01 2.018440e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 0.000000e+00 0.000000e+00 + 1.000000e-05 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203517e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924977e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 4.453389e-16 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243450e+01 -5.614165e+00 -6.319999e+00 4.786307e-07 3.508914e-02 1.879834e-01 8.536551e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695232e-06 2.280017e-01 2.018440e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -4.524586e+02 -4.750815e-14 + 2.500000e-05 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203517e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924977e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 2.230688e-16 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243450e+01 -5.614165e+00 -6.319999e+00 4.786310e-07 3.508916e-02 1.879835e-01 8.536557e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695232e-06 2.280017e-01 2.018440e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.130980e+03 -1.187529e-13 + 4.750000e-05 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203517e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924977e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 7.772050e-16 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243450e+01 -5.614165e+00 -6.319998e+00 4.786320e-07 3.508923e-02 1.879839e-01 8.536575e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695232e-06 2.280017e-01 2.018440e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -2.148390e+03 -2.255809e-13 + 8.125000e-05 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203517e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924977e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 7.282870e-16 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243450e+01 -5.614164e+00 -6.319997e+00 4.786329e-07 3.508930e-02 1.879843e-01 8.536591e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695232e-06 2.280017e-01 2.018441e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -3.673664e+03 -3.857348e-13 + 1.318750e-04 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203517e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924977e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.531179e-15 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243450e+01 -5.614164e+00 -6.319996e+00 4.786349e-07 3.508944e-02 1.879851e-01 8.536627e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695232e-06 2.280017e-01 2.018441e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.959693e+03 -6.257678e-13 + 2.078125e-04 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203517e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924978e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.856197e-15 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243450e+01 -5.614162e+00 -6.319993e+00 4.786373e-07 3.508962e-02 1.879860e-01 8.536669e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695232e-06 2.280017e-01 2.018441e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -9.384502e+03 -9.853727e-13 + 3.217188e-04 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203517e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924978e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 3.220575e-15 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243450e+01 -5.614161e+00 -6.319990e+00 4.786414e-07 3.508993e-02 1.879877e-01 8.536744e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695232e-06 2.280017e-01 2.018442e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.451222e+04 -1.523784e-12 + 4.925781e-04 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203517e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924978e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 4.393239e-15 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243450e+01 -5.614158e+00 -6.319985e+00 4.786471e-07 3.509034e-02 1.879899e-01 8.536845e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695232e-06 2.280017e-01 2.018443e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -2.218254e+04 -2.329167e-12 + 7.488672e-04 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203516e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924978e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 7.020377e-15 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243449e+01 -5.614154e+00 -6.319976e+00 4.786562e-07 3.509101e-02 1.879935e-01 8.537007e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695233e-06 2.280017e-01 2.018444e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -3.364052e+04 -3.532255e-12 + 1.133301e-03 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203516e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924978e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -3.899853e-18 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243449e+01 -5.614148e+00 -6.319964e+00 4.786693e-07 3.509197e-02 1.879987e-01 8.537240e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695233e-06 2.280017e-01 2.018446e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.072112e+04 -5.325718e-12 + 1.709951e-03 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203516e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924979e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -9.162458e-18 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243447e+01 -5.614133e+00 -6.319934e+00 4.787025e-07 3.509441e-02 1.880118e-01 8.537832e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695233e-06 2.280017e-01 2.018448e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -7.610634e+04 -7.991165e-12 + 2.574927e-03 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203516e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924980e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -1.872510e-17 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243445e+01 -5.614110e+00 -6.319889e+00 4.787522e-07 3.509806e-02 1.880314e-01 8.538719e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695233e-06 2.280017e-01 2.018453e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.136659e+05 -1.193492e-11 + 3.872390e-03 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203516e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924981e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -2.525836e-17 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243441e+01 -5.614076e+00 -6.319822e+00 4.788268e-07 3.510353e-02 1.880608e-01 8.540049e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695233e-06 2.280017e-01 2.018459e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.688776e+05 -1.773215e-11 + 5.818585e-03 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554000e+00 -1.729953e+01 -8.999999e+01 -9.203516e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924983e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -3.735825e-17 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243436e+01 -5.614026e+00 -6.319720e+00 4.789385e-07 3.511173e-02 1.881048e-01 8.542041e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695233e-06 2.280017e-01 2.018468e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -2.492802e+05 -2.617442e-11 + 8.737878e-03 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554000e+00 -1.729953e+01 -8.999999e+01 -9.203516e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924986e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -5.241927e-17 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243429e+01 -5.613950e+00 -6.319569e+00 4.791057e-07 3.512401e-02 1.881707e-01 8.545025e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695234e-06 2.280017e-01 2.018482e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -3.648241e+05 -3.830653e-11 + 1.311682e-02 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741268e+00 -5.554000e+00 -1.729953e+01 -8.999999e+01 -9.203515e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924990e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -8.073918e-17 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243417e+01 -5.613837e+00 -6.319342e+00 4.793559e-07 3.514237e-02 1.882693e-01 8.549486e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695234e-06 2.280017e-01 2.018504e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.278547e+05 -5.542474e-11 + 1.968523e-02 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741268e+00 -5.554000e+00 -1.729953e+01 -8.999998e+01 -9.203515e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924997e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -1.300647e-16 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243400e+01 -5.613667e+00 -6.319004e+00 4.797296e-07 3.516980e-02 1.884166e-01 8.556151e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695235e-06 2.280017e-01 2.018535e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -7.523188e+05 -7.899347e-11 + 2.953784e-02 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741267e+00 -5.553999e+00 -1.729953e+01 -8.999997e+01 -9.203513e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.925007e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -2.025236e-16 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243375e+01 -5.613416e+00 -6.318500e+00 4.802865e-07 3.521068e-02 1.886362e-01 8.566084e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695236e-06 2.280017e-01 2.018583e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.051765e+06 -1.104353e-10 + 4.431676e-02 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741266e+00 -5.553998e+00 -1.729952e+01 -8.999995e+01 -9.203512e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.925021e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -3.347822e-16 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243338e+01 -5.613042e+00 -6.317752e+00 4.811139e-07 3.527141e-02 1.889623e-01 8.580841e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695238e-06 2.280017e-01 2.018654e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.435987e+06 -1.507786e-10 + 6.648513e-02 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998312e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741265e+00 -5.553997e+00 -1.729952e+01 -8.999993e+01 -9.203510e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.925044e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -5.787669e-16 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243283e+01 -5.612490e+00 -6.316649e+00 4.823374e-07 3.536122e-02 1.894447e-01 8.602663e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695241e-06 2.280017e-01 2.018762e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.906805e+06 -2.002145e-10 + 9.973770e-02 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998312e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.499999e+01 -1.640706e+01 -5.741263e+00 -5.553995e+00 -1.729952e+01 -8.999990e+01 -9.203506e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.925077e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -1.008746e-15 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243202e+01 -5.611683e+00 -6.315035e+00 4.841337e-07 3.549308e-02 1.901529e-01 8.634699e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695246e-06 2.280017e-01 2.018922e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -2.454125e+06 -2.576832e-10 + 1.496166e-01 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998312e+00 -2.185367e+00 -7.257166e+00 -6.352001e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.499999e+01 -1.640706e+01 -5.741260e+00 -5.553991e+00 -1.729952e+01 -8.999984e+01 -9.203501e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.925126e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -1.813901e-15 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243085e+01 -5.610516e+00 -6.312701e+00 4.867427e-07 3.568461e-02 1.911818e-01 8.681232e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695252e-06 2.280017e-01 2.019164e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -3.053576e+06 -3.206255e-10 + 2.244348e-01 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998312e+00 -2.185367e+00 -7.257166e+00 -6.352001e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.499999e+01 -1.640705e+01 -5.741255e+00 -5.553987e+00 -1.729951e+01 -8.999977e+01 -9.203493e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.925201e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -3.318258e-15 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.242920e+01 -5.608859e+00 -6.309386e+00 4.904720e-07 3.595840e-02 1.926528e-01 8.747746e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695262e-06 2.280017e-01 2.019526e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -3.666545e+06 -3.849872e-10 + 3.366622e-01 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998312e+00 -2.185367e+00 -7.257167e+00 -6.352001e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.499998e+01 -1.640704e+01 -5.741249e+00 -5.553980e+00 -1.729951e+01 -8.999965e+01 -9.203482e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.925313e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -7.635319e-20 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.242690e+01 -5.606566e+00 -6.304801e+00 4.956773e-07 3.634061e-02 1.947068e-01 8.840584e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695277e-06 2.280017e-01 2.020069e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -4.243115e+06 -4.455271e-10 + 5.050034e-01 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998312e+00 -2.185367e+00 -7.257167e+00 -6.352001e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.499997e+01 -1.640703e+01 -5.741238e+00 -5.553969e+00 -1.729950e+01 -8.999947e+01 -9.203464e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.925481e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 2.718938e-18 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.242386e+01 -5.603520e+00 -6.298708e+00 5.026800e-07 3.685491e-02 1.974719e-01 8.965480e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695299e-06 2.280017e-01 2.020883e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -4.728892e+06 -4.965336e-10 + 7.575150e-01 1.259293e+01 -1.575166e+00 -1.259293e+01 -1.998312e+00 -2.185367e+00 -7.257167e+00 -6.352001e+00 -8.966835e+00 -4.655479e+00 -7.150312e+00 -3.499995e+01 -1.640702e+01 -5.741223e+00 -5.553953e+00 -1.729948e+01 -8.999921e+01 -9.203438e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.925732e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -1.261725e-18 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.242002e+01 -5.599687e+00 -6.291041e+00 5.116334e-07 3.751270e-02 2.010110e-01 9.125166e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695332e-06 2.280017e-01 2.022106e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.077652e+06 -5.331535e-10 + 1.136283e+00 1.259293e+01 -1.575166e+00 -1.259293e+01 -1.998311e+00 -2.185366e+00 -7.257167e+00 -6.352001e+00 -8.966835e+00 -4.655479e+00 -7.150312e+00 -3.499993e+01 -1.640699e+01 -5.741199e+00 -5.553930e+00 -1.729946e+01 -8.999882e+01 -9.203398e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.926110e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -3.652781e-18 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.241556e+01 -5.595225e+00 -6.282117e+00 5.222560e-07 3.829363e-02 2.052180e-01 9.314624e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695382e-06 2.280017e-01 2.023941e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.269453e+06 -5.532926e-10 + 1.704434e+00 1.259293e+01 -1.575166e+00 -1.259293e+01 -1.998311e+00 -2.185366e+00 -7.257168e+00 -6.352001e+00 -8.966835e+00 -4.655479e+00 -7.150312e+00 -3.499989e+01 -1.640696e+01 -5.741164e+00 -5.553894e+00 -1.729942e+01 -8.999823e+01 -9.203339e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.926676e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -1.099122e-17 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.241089e+01 -5.590557e+00 -6.272781e+00 5.336034e-07 3.912887e-02 2.097284e-01 9.517010e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695457e-06 2.280017e-01 2.026698e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.324953e+06 -5.591201e-10 + 2.556661e+00 1.259293e+01 -1.575167e+00 -1.259293e+01 -1.998311e+00 -2.185366e+00 -7.257168e+00 -6.352001e+00 -8.966835e+00 -4.655479e+00 -7.150312e+00 -3.499984e+01 -1.640691e+01 -5.741111e+00 -5.553841e+00 -1.729937e+01 -8.999734e+01 -9.203251e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.927526e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -7.909399e-18 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240665e+01 -5.586319e+00 -6.264304e+00 5.441211e-07 3.990502e-02 2.139410e-01 9.704597e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695570e-06 2.280017e-01 2.030839e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.298686e+06 -5.563620e-10 + 3.835001e+00 1.259293e+01 -1.575167e+00 -1.259293e+01 -1.998310e+00 -2.185366e+00 -7.257168e+00 -6.352001e+00 -8.966835e+00 -4.655479e+00 -7.150312e+00 -3.499976e+01 -1.640683e+01 -5.741032e+00 -5.553761e+00 -1.729929e+01 -8.999601e+01 -9.203118e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.928800e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -8.736946e-18 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240344e+01 -5.583104e+00 -6.257875e+00 5.522366e-07 4.050765e-02 2.172518e-01 9.849340e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695739e-06 2.280017e-01 2.037067e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.248731e+06 -5.511167e-10 + 5.752512e+00 1.259293e+01 -1.575167e+00 -1.259293e+01 -1.998310e+00 -2.185366e+00 -7.257168e+00 -6.352002e+00 -8.966835e+00 -4.655479e+00 -7.150312e+00 -3.499964e+01 -1.640671e+01 -5.740912e+00 -5.553641e+00 -1.729917e+01 -8.999402e+01 -9.202918e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.930713e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -5.233054e-18 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240148e+01 -5.581147e+00 -6.253961e+00 5.572356e-07 4.088561e-02 2.193999e-01 9.938499e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695994e-06 2.280017e-01 2.046445e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.208965e+06 -5.469413e-10 + 8.628778e+00 1.259293e+01 -1.575167e+00 -1.259293e+01 -1.998310e+00 -2.185366e+00 -7.257168e+00 -6.352002e+00 -8.966835e+00 -4.655479e+00 -7.150312e+00 -3.499946e+01 -1.640653e+01 -5.740732e+00 -5.553462e+00 -1.729899e+01 -8.999102e+01 -9.202619e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.933582e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -2.129384e-15 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240056e+01 -5.580228e+00 -6.252122e+00 5.596001e-07 4.107610e-02 2.206047e-01 9.980671e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.696375e-06 2.280017e-01 2.060593e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.185993e+06 -5.445292e-10 + 1.294318e+01 1.259293e+01 -1.575167e+00 -1.259293e+01 -1.998310e+00 -2.185366e+00 -7.257169e+00 -6.352002e+00 -8.966835e+00 -4.655479e+00 -7.150312e+00 -3.499919e+01 -1.640626e+01 -5.740463e+00 -5.553192e+00 -1.729872e+01 -8.998654e+01 -9.202170e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.937888e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -6.130227e-16 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240024e+01 -5.579906e+00 -6.251478e+00 5.604310e-07 4.116264e-02 2.213441e-01 9.995489e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.696948e-06 2.280017e-01 2.081998e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.172907e+06 -5.431553e-10 + 1.941477e+01 1.259293e+01 -1.575167e+00 -1.259293e+01 -1.998310e+00 -2.185366e+00 -7.257169e+00 -6.352002e+00 -8.966835e+00 -4.655479e+00 -7.150312e+00 -3.499879e+01 -1.640585e+01 -5.740058e+00 -5.552787e+00 -1.729831e+01 -8.997980e+01 -9.201497e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.944353e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -6.034531e-16 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240016e+01 -5.579824e+00 -6.251315e+00 5.606411e-07 4.121644e-02 2.220466e-01 9.999237e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.697808e-06 2.280017e-01 2.114524e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.161617e+06 -5.419698e-10 + 2.912217e+01 1.259293e+01 -1.575167e+00 -1.259293e+01 -1.998310e+00 -2.185366e+00 -7.257169e+00 -6.352002e+00 -8.966835e+00 -4.655479e+00 -7.150312e+00 -3.499818e+01 -1.640525e+01 -5.739451e+00 -5.552181e+00 -1.729771e+01 -8.996970e+01 -9.200487e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.954061e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -9.021646e-16 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240014e+01 -5.579810e+00 -6.251286e+00 5.606787e-07 4.127683e-02 2.229942e-01 9.999909e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.699100e-06 2.280017e-01 2.164268e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.146936e+06 -5.404283e-10 + 4.368327e+01 1.259293e+01 -1.575167e+00 -1.259293e+01 -1.998310e+00 -2.185366e+00 -7.257169e+00 -6.352002e+00 -8.966835e+00 -4.655479e+00 -7.150312e+00 -3.499727e+01 -1.640434e+01 -5.738542e+00 -5.551271e+00 -1.729680e+01 -8.995456e+01 -9.198972e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.968649e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.447507e-12 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240014e+01 -5.579808e+00 -6.251282e+00 5.606834e-07 4.136377e-02 2.244023e-01 9.999992e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.701041e-06 2.280017e-01 2.241086e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.125366e+06 -5.381634e-10 + 6.552491e+01 1.259293e+01 -1.575167e+00 -1.259293e+01 -1.998310e+00 -2.185366e+00 -7.257169e+00 -6.352002e+00 -8.966835e+00 -4.655479e+00 -7.150312e+00 -3.499590e+01 -1.640297e+01 -5.737177e+00 -5.549906e+00 -1.729543e+01 -8.993184e+01 -9.196700e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.990587e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 2.170699e-12 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240014e+01 -5.579808e+00 -6.251282e+00 5.606836e-07 4.149400e-02 2.265285e-01 9.999995e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.703960e-06 2.280017e-01 2.361457e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.092997e+06 -5.347647e-10 + 9.828738e+01 1.259293e+01 -1.575167e+00 -1.259293e+01 -1.998310e+00 -2.185366e+00 -7.257169e+00 -6.352002e+00 -8.966835e+00 -4.655479e+00 -7.150311e+00 -3.499386e+01 -1.640092e+01 -5.735129e+00 -5.547858e+00 -1.729338e+01 -8.989775e+01 -9.193292e+01 1.000000e+00 1.000000e+00 1.000000e+00 7.023625e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 3.269020e-12 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240014e+01 -5.579808e+00 -6.251282e+00 5.606839e-07 4.169012e-02 2.297555e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.708355e-06 2.280017e-01 2.554242e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.044486e+06 -5.296710e-10 + 1.474311e+02 1.259293e+01 -1.575167e+00 -1.259293e+01 -1.998309e+00 -2.185365e+00 -7.257169e+00 -6.352002e+00 -8.966835e+00 -4.655479e+00 -7.150311e+00 -3.499079e+01 -1.639785e+01 -5.732058e+00 -5.544786e+00 -1.729031e+01 -8.984663e+01 -9.188180e+01 1.000000e+00 1.000000e+00 1.000000e+00 7.073475e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 4.932491e-12 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240014e+01 -5.579808e+00 -6.251282e+00 5.606839e-07 4.198601e-02 2.346823e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.714988e-06 2.280017e-01 2.873328e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -4.971719e+06 -5.220305e-10 + 2.211466e+02 1.259293e+01 -1.575168e+00 -1.259293e+01 -1.998309e+00 -2.185365e+00 -7.257170e+00 -6.352002e+00 -8.966835e+00 -4.655479e+00 -7.150311e+00 -3.498618e+01 -1.639324e+01 -5.727451e+00 -5.540179e+00 -1.728570e+01 -8.976995e+01 -9.180511e+01 1.000000e+00 1.000000e+00 1.000000e+00 7.148913e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 7.465030e-12 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240014e+01 -5.579809e+00 -6.251282e+00 5.606839e-07 4.243380e-02 2.422714e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.725025e-06 2.280017e-01 3.428229e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -4.862571e+06 -5.105699e-10 + 3.172748e+02 1.259293e+01 -1.575168e+00 -1.259293e+01 -1.998308e+00 -2.185365e+00 -7.257170e+00 -6.352003e+00 -8.966835e+00 -4.655479e+00 -7.150311e+00 -3.498017e+01 -1.638724e+01 -5.721444e+00 -5.534171e+00 -1.727970e+01 -8.966995e+01 -9.170511e+01 1.000000e+00 1.000000e+00 1.000000e+00 7.248498e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 9.854231e-12 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240014e+01 -5.579809e+00 -6.251282e+00 5.606839e-07 4.302490e-02 2.525376e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.738274e-06 2.280017e-01 4.315884e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -4.720237e+06 -4.956249e-10 + 4.134030e+02 1.259293e+01 -1.575168e+00 -1.259293e+01 -1.998308e+00 -2.185365e+00 -7.257171e+00 -6.352003e+00 -8.966835e+00 -4.655479e+00 -7.150310e+00 -3.497416e+01 -1.638123e+01 -5.715436e+00 -5.528163e+00 -1.727369e+01 -8.956995e+01 -9.160511e+01 1.000000e+00 1.000000e+00 1.000000e+00 7.349470e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 9.989338e-12 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240014e+01 -5.579809e+00 -6.251282e+00 5.606839e-07 4.362424e-02 2.632390e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.751708e-06 2.280017e-01 5.433376e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -4.577904e+06 -4.806799e-10 + 5.095311e+02 1.259293e+01 -1.575169e+00 -1.259293e+01 -1.998307e+00 -2.185364e+00 -7.257172e+00 -6.352003e+00 -8.966835e+00 -4.655479e+00 -7.150310e+00 -3.496815e+01 -1.637522e+01 -5.709429e+00 -5.522155e+00 -1.726768e+01 -8.946995e+01 -9.150511e+01 1.000000e+00 1.000000e+00 1.000000e+00 7.451849e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.012849e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240014e+01 -5.579809e+00 -6.251282e+00 5.606839e-07 4.423193e-02 2.743937e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.765329e-06 2.280017e-01 6.840215e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -4.435570e+06 -4.657349e-10 + 6.056593e+02 1.259293e+01 -1.575169e+00 -1.259293e+01 -1.998306e+00 -2.185364e+00 -7.257172e+00 -6.352004e+00 -8.966835e+00 -4.655479e+00 -7.150310e+00 -3.496215e+01 -1.636921e+01 -5.703422e+00 -5.516147e+00 -1.726167e+01 -8.936995e+01 -9.140511e+01 1.000000e+00 1.000000e+00 1.000000e+00 7.555654e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.026958e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240013e+01 -5.579810e+00 -6.251282e+00 5.606839e-07 4.484809e-02 2.860212e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.779140e-06 2.280017e-01 8.611321e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -4.293237e+06 -4.507899e-10 + 7.017875e+02 1.259293e+01 -1.575169e+00 -1.259293e+01 -1.998306e+00 -2.185364e+00 -7.257173e+00 -6.352004e+00 -8.966835e+00 -4.655479e+00 -7.150309e+00 -3.495614e+01 -1.636321e+01 -5.697414e+00 -5.510139e+00 -1.725566e+01 -8.926995e+01 -9.130512e+01 1.000000e+00 1.000000e+00 1.000000e+00 7.660905e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.041263e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240013e+01 -5.579810e+00 -6.251282e+00 5.606839e-07 4.547283e-02 2.981414e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.793143e-06 2.280017e-01 1.084101e-90 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -4.150904e+06 -4.358449e-10 + 7.979157e+02 1.259293e+01 -1.575169e+00 -1.259293e+01 -1.998305e+00 -2.185363e+00 -7.257174e+00 -6.352004e+00 -8.966835e+00 -4.655479e+00 -7.150309e+00 -3.495013e+01 -1.635720e+01 -5.691407e+00 -5.504131e+00 -1.724965e+01 -8.916995e+01 -9.120512e+01 1.000000e+00 1.000000e+00 1.000000e+00 7.767622e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.055767e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240013e+01 -5.579810e+00 -6.251282e+00 5.606839e-07 4.610627e-02 3.107752e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.807342e-06 2.280017e-01 1.364802e-90 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -4.008570e+06 -4.208999e-10 + 8.940438e+02 1.259293e+01 -1.575170e+00 -1.259293e+01 -1.998304e+00 -2.185363e+00 -7.257174e+00 -6.352005e+00 -8.966835e+00 -4.655479e+00 -7.150309e+00 -3.494412e+01 -1.635119e+01 -5.685400e+00 -5.498123e+00 -1.724365e+01 -8.906995e+01 -9.110512e+01 1.000000e+00 1.000000e+00 1.000000e+00 7.875826e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.070474e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240013e+01 -5.579811e+00 -6.251282e+00 5.606839e-07 4.674853e-02 3.239443e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.821738e-06 2.280017e-01 1.718184e-90 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -3.866237e+06 -4.059549e-10 + 9.901720e+02 1.259293e+01 -1.575170e+00 -1.259293e+01 -1.998304e+00 -2.185363e+00 -7.257175e+00 -6.352005e+00 -8.966835e+00 -4.655479e+00 -7.150308e+00 -3.493811e+01 -1.634518e+01 -5.679392e+00 -5.492115e+00 -1.723764e+01 -8.896995e+01 -9.100512e+01 1.000000e+00 1.000000e+00 1.000000e+00 7.985537e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.085385e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240013e+01 -5.579811e+00 -6.251282e+00 5.606839e-07 4.739974e-02 3.376715e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.836334e-06 2.280017e-01 2.163066e-90 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -3.723903e+06 -3.910098e-10 + 1.086300e+03 1.259293e+01 -1.575171e+00 -1.259293e+01 -1.998303e+00 -2.185362e+00 -7.257176e+00 -6.352005e+00 -8.966835e+00 -4.655479e+00 -7.150308e+00 -3.493211e+01 -1.633918e+01 -5.673385e+00 -5.486107e+00 -1.723163e+01 -8.886995e+01 -9.090512e+01 1.000000e+00 1.000000e+00 1.000000e+00 8.096776e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.100504e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240013e+01 -5.579811e+00 -6.251282e+00 5.606839e-07 4.806002e-02 3.519803e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.851134e-06 2.280017e-01 2.723139e-90 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -3.581570e+06 -3.760648e-10 + 1.182428e+03 1.259293e+01 -1.575171e+00 -1.259293e+01 -1.998302e+00 -2.185362e+00 -7.257176e+00 -6.352006e+00 -8.966835e+00 -4.655479e+00 -7.150308e+00 -3.492610e+01 -1.633317e+01 -5.667378e+00 -5.480099e+00 -1.722562e+01 -8.876995e+01 -9.080512e+01 1.000000e+00 1.000000e+00 1.000000e+00 8.209565e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.115834e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240013e+01 -5.579812e+00 -6.251282e+00 5.606839e-07 4.872950e-02 3.668955e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.866140e-06 2.280017e-01 3.428229e-90 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -3.439236e+06 -3.611198e-10 + 1.278557e+03 1.259293e+01 -1.575171e+00 -1.259293e+01 -1.998302e+00 -2.185362e+00 -7.257177e+00 -6.352006e+00 -8.966835e+00 -4.655479e+00 -7.150307e+00 -3.492009e+01 -1.632716e+01 -5.661370e+00 -5.474091e+00 -1.721961e+01 -8.866995e+01 -9.070512e+01 1.000000e+00 1.000000e+00 1.000000e+00 8.323925e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.131377e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240013e+01 -5.579812e+00 -6.251282e+00 5.606839e-07 4.940831e-02 3.824428e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.881355e-06 2.280017e-01 4.315884e-90 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -3.296903e+06 -3.461748e-10 + 1.374685e+03 1.259293e+01 -1.575172e+00 -1.259293e+01 -1.998301e+00 -2.185361e+00 -7.257178e+00 -6.352006e+00 -8.966835e+00 -4.655479e+00 -7.150307e+00 -3.491408e+01 -1.632115e+01 -5.655363e+00 -5.468083e+00 -1.721360e+01 -8.856995e+01 -9.060512e+01 9.999999e-01 1.000000e+00 1.000000e+00 8.439878e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.147137e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240013e+01 -5.579813e+00 -6.251282e+00 5.606839e-07 5.009657e-02 3.986488e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.896782e-06 2.280017e-01 5.433376e-90 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -3.154570e+06 -3.312298e-10 + 1.470813e+03 1.259293e+01 -1.575172e+00 -1.259293e+01 -1.998300e+00 -2.185361e+00 -7.257179e+00 -6.352007e+00 -8.966835e+00 -4.655479e+00 -7.150307e+00 -3.490807e+01 -1.631514e+01 -5.649356e+00 -5.462075e+00 -1.720760e+01 -8.846995e+01 -9.050512e+01 9.999999e-01 1.000000e+00 1.000000e+00 8.557446e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.163116e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240013e+01 -5.579813e+00 -6.251282e+00 5.606839e-07 5.079442e-02 4.155416e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.912424e-06 2.280017e-01 6.840215e-90 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -3.012236e+06 -3.162848e-10 + 1.566941e+03 1.259293e+01 -1.575172e+00 -1.259293e+01 -1.998299e+00 -2.185360e+00 -7.257179e+00 -6.352007e+00 -8.966835e+00 -4.655479e+00 -7.150306e+00 -3.490207e+01 -1.630914e+01 -5.643349e+00 -5.456067e+00 -1.720159e+01 -8.836995e+01 -9.040512e+01 9.999999e-01 1.000000e+00 1.000000e+00 8.676652e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.179318e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240012e+01 -5.579813e+00 -6.251282e+00 5.606839e-07 5.150199e-02 4.331502e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.928284e-06 2.280017e-01 8.611320e-90 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -2.869903e+06 -3.013398e-10 + 1.663069e+03 1.259293e+01 -1.575173e+00 -1.259293e+01 -1.998299e+00 -2.185360e+00 -7.257180e+00 -6.352007e+00 -8.966835e+00 -4.655479e+00 -7.150306e+00 -3.489606e+01 -1.630313e+01 -5.637341e+00 -5.450059e+00 -1.719558e+01 -8.826995e+01 -9.030512e+01 9.999999e-01 1.000000e+00 1.000000e+00 8.797518e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.195745e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240012e+01 -5.579814e+00 -6.251282e+00 5.606839e-07 5.221942e-02 4.515050e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.944364e-06 2.280017e-01 1.084101e-89 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -2.727569e+06 -2.863948e-10 + 1.759197e+03 1.259293e+01 -1.575173e+00 -1.259293e+01 -1.998298e+00 -2.185360e+00 -7.257181e+00 -6.352008e+00 -8.966835e+00 -4.655479e+00 -7.150306e+00 -3.489005e+01 -1.629712e+01 -5.631334e+00 -5.444051e+00 -1.718957e+01 -8.816995e+01 -9.020512e+01 9.999999e-01 1.000000e+00 1.000000e+00 8.920069e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.212402e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240012e+01 -5.579814e+00 -6.251282e+00 5.606839e-07 5.294684e-02 4.706376e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.960669e-06 2.280017e-01 1.364802e-89 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -2.585236e+06 -2.714498e-10 + 1.855326e+03 1.259293e+01 -1.575173e+00 -1.259293e+01 -1.998297e+00 -2.185359e+00 -7.257182e+00 -6.352008e+00 -8.966835e+00 -4.655479e+00 -7.150305e+00 -3.488404e+01 -1.629111e+01 -5.625327e+00 -5.438043e+00 -1.718356e+01 -8.806995e+01 -9.010512e+01 9.999999e-01 1.000000e+00 1.000000e+00 9.044326e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.229290e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240012e+01 -5.579814e+00 -6.251282e+00 5.606839e-07 5.368440e-02 4.905809e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.977200e-06 2.280017e-01 1.718184e-89 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -2.442902e+06 -2.565048e-10 + 1.951454e+03 1.259293e+01 -1.575174e+00 -1.259293e+01 -1.998296e+00 -2.185359e+00 -7.257182e+00 -6.352009e+00 -8.966835e+00 -4.655479e+00 -7.150305e+00 -3.487803e+01 -1.628511e+01 -5.619320e+00 -5.432035e+00 -1.717755e+01 -8.796995e+01 -9.000512e+01 9.999999e-01 1.000000e+00 1.000000e+00 9.170314e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.246414e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240012e+01 -5.579815e+00 -6.251282e+00 5.606839e-07 5.443222e-02 5.113693e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.993962e-06 2.280017e-01 2.163066e-89 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -2.300569e+06 -2.415597e-10 + 2.047582e+03 1.259293e+01 -1.575174e+00 -1.259293e+01 -1.998295e+00 -2.185359e+00 -7.257183e+00 -6.352009e+00 -8.966835e+00 -4.655479e+00 -7.150304e+00 -3.487203e+01 -1.627910e+01 -5.613312e+00 -5.426027e+00 -1.717154e+01 -8.786995e+01 -8.990512e+01 9.999999e-01 1.000000e+00 1.000000e+00 9.298057e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.263776e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240012e+01 -5.579815e+00 -6.251282e+00 5.606839e-07 5.519047e-02 5.330387e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.010958e-06 2.280017e-01 2.723139e-89 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -2.158236e+06 -2.266147e-10 + 2.143710e+03 1.259293e+01 -1.575175e+00 -1.259293e+01 -1.998295e+00 -2.185358e+00 -7.257184e+00 -6.352009e+00 -8.966835e+00 -4.655479e+00 -7.150304e+00 -3.486602e+01 -1.627309e+01 -5.607305e+00 -5.420019e+00 -1.716554e+01 -8.776995e+01 -8.980512e+01 9.999999e-01 1.000000e+00 1.000000e+00 9.427580e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.281380e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240012e+01 -5.579816e+00 -6.251282e+00 5.606839e-07 5.595928e-02 5.556262e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.028190e-06 2.280017e-01 3.428228e-89 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -2.015902e+06 -2.116697e-10 + 2.239838e+03 1.259293e+01 -1.575175e+00 -1.259293e+01 -1.998294e+00 -2.185358e+00 -7.257185e+00 -6.352010e+00 -8.966835e+00 -4.655479e+00 -7.150304e+00 -3.486001e+01 -1.626708e+01 -5.601298e+00 -5.414011e+00 -1.715953e+01 -8.766995e+01 -8.970512e+01 9.999999e-01 1.000000e+00 1.000000e+00 9.558907e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.299229e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240012e+01 -5.579816e+00 -6.251282e+00 5.606839e-07 5.673880e-02 5.791710e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.045662e-06 2.280017e-01 4.315884e-89 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.873569e+06 -1.967247e-10 + 2.335966e+03 1.259293e+01 -1.575175e+00 -1.259293e+01 -1.998293e+00 -2.185357e+00 -7.257186e+00 -6.352010e+00 -8.966835e+00 -4.655479e+00 -7.150303e+00 -3.485400e+01 -1.626108e+01 -5.595291e+00 -5.408003e+00 -1.715352e+01 -8.756995e+01 -8.960512e+01 9.999999e-01 1.000000e+00 1.000000e+00 9.692064e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.317326e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240011e+01 -5.579816e+00 -6.251282e+00 5.606839e-07 5.752917e-02 6.037134e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.063378e-06 2.280017e-01 5.433376e-89 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.731235e+06 -1.817797e-10 + 2.432095e+03 1.259293e+01 -1.575176e+00 -1.259293e+01 -1.998292e+00 -2.185357e+00 -7.257186e+00 -6.352011e+00 -8.966835e+00 -4.655479e+00 -7.150303e+00 -3.484799e+01 -1.625507e+01 -5.589284e+00 -5.401995e+00 -1.714751e+01 -8.746995e+01 -8.950512e+01 9.999999e-01 1.000000e+00 1.000000e+00 9.827075e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.335676e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240011e+01 -5.579817e+00 -6.251282e+00 5.606839e-07 5.833056e-02 6.292958e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.081340e-06 2.280017e-01 6.840215e-89 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.588902e+06 -1.668347e-10 + 2.528223e+03 1.259292e+01 -1.575176e+00 -1.259292e+01 -1.998291e+00 -2.185356e+00 -7.257187e+00 -6.352011e+00 -8.966835e+00 -4.655479e+00 -7.150302e+00 -3.484199e+01 -1.624906e+01 -5.583276e+00 -5.395987e+00 -1.714150e+01 -8.736995e+01 -8.940512e+01 9.999999e-01 1.000000e+00 1.000000e+00 9.963967e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.354282e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240011e+01 -5.579817e+00 -6.251282e+00 5.606839e-07 5.914311e-02 6.559623e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.099552e-06 2.280017e-01 8.611320e-89 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.446568e+06 -1.518897e-10 + 2.624351e+03 1.259292e+01 -1.575177e+00 -1.259292e+01 -1.998290e+00 -2.185356e+00 -7.257188e+00 -6.352011e+00 -8.966835e+00 -4.655479e+00 -7.150302e+00 -3.483598e+01 -1.624305e+01 -5.577269e+00 -5.389979e+00 -1.713549e+01 -8.726995e+01 -8.930512e+01 9.999999e-01 1.000000e+00 1.000000e+00 1.010277e-03 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.373147e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240011e+01 -5.579818e+00 -6.251282e+00 5.606839e-07 5.996698e-02 6.837588e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.118019e-06 2.280017e-01 1.084101e-88 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.304235e+06 -1.369447e-10 + 2.720479e+03 1.259292e+01 -1.575177e+00 -1.259292e+01 -1.998290e+00 -2.185356e+00 -7.257189e+00 -6.352012e+00 -8.966835e+00 -4.655479e+00 -7.150301e+00 -3.482997e+01 -1.623705e+01 -5.571262e+00 -5.383971e+00 -1.712949e+01 -8.716995e+01 -8.920512e+01 9.999999e-01 1.000000e+00 1.000000e+00 1.024350e-03 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.392274e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240011e+01 -5.579818e+00 -6.251282e+00 5.606839e-07 6.080232e-02 7.127331e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.136742e-06 2.280017e-01 1.364802e-88 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.161902e+06 -1.219997e-10 + 2.816607e+03 1.259292e+01 -1.575178e+00 -1.259292e+01 -1.998289e+00 -2.185355e+00 -7.257190e+00 -6.352012e+00 -8.966835e+00 -4.655479e+00 -7.150301e+00 -3.482396e+01 -1.623104e+01 -5.565255e+00 -5.377963e+00 -1.712348e+01 -8.706995e+01 -8.910512e+01 9.999998e-01 1.000000e+00 1.000000e+00 1.038619e-03 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.411668e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240011e+01 -5.579819e+00 -6.251282e+00 5.606839e-07 6.164930e-02 7.429353e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.155726e-06 2.280017e-01 1.718184e-88 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.019568e+06 -1.070547e-10 + 2.912735e+03 1.259292e+01 -1.575178e+00 -1.259292e+01 -1.998288e+00 -2.185355e+00 -7.257191e+00 -6.352013e+00 -8.966835e+00 -4.655479e+00 -7.150301e+00 -3.481795e+01 -1.622503e+01 -5.559248e+00 -5.371955e+00 -1.711747e+01 -8.696995e+01 -8.900512e+01 9.999998e-01 1.000000e+00 1.000000e+00 1.053087e-03 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.431331e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240011e+01 -5.579819e+00 -6.251282e+00 5.606839e-07 6.250808e-02 7.744172e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.174975e-06 2.280017e-01 2.163066e-88 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -8.772347e+05 -9.210964e-11 + 3.008864e+03 1.259292e+01 -1.575179e+00 -1.259292e+01 -1.998287e+00 -2.185354e+00 -7.257192e+00 -6.352013e+00 -8.966835e+00 -4.655479e+00 -7.150300e+00 -3.481195e+01 -1.621902e+01 -5.553241e+00 -5.365947e+00 -1.711146e+01 -8.686995e+01 -8.890512e+01 9.999998e-01 1.000000e+00 1.000000e+00 1.067757e-03 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.451269e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240011e+01 -5.579819e+00 -6.251282e+00 5.606839e-07 6.337883e-02 8.072332e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.194491e-06 2.280017e-01 2.723138e-88 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -7.349013e+05 -7.716463e-11 + 3.104992e+03 1.259292e+01 -1.575179e+00 -1.259292e+01 -1.998286e+00 -2.185354e+00 -7.257193e+00 -6.352014e+00 -8.966835e+00 -4.655479e+00 -7.150300e+00 -3.480594e+01 -1.621302e+01 -5.547234e+00 -5.359939e+00 -1.710545e+01 -8.676995e+01 -8.880513e+01 9.999998e-01 1.000000e+00 1.000000e+00 1.082631e-03 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.471485e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240010e+01 -5.579820e+00 -6.251282e+00 5.606839e-07 6.426170e-02 8.414398e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.214280e-06 2.280017e-01 3.428228e-88 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -5.925678e+05 -6.221962e-11 + 3.201120e+03 1.259292e+01 -1.575179e+00 -1.259292e+01 -1.998285e+00 -2.185353e+00 -7.257194e+00 -6.352014e+00 -8.966835e+00 -4.655479e+00 -7.150299e+00 -3.479993e+01 -1.620701e+01 -5.541227e+00 -5.353931e+00 -1.709944e+01 -8.666995e+01 -8.870513e+01 9.999998e-01 1.000000e+00 1.000000e+00 1.097712e-03 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.491982e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240010e+01 -5.579820e+00 -6.251282e+00 5.606839e-07 6.515687e-02 8.770959e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.234344e-06 2.280017e-01 4.315883e-88 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -4.502344e+05 -4.727461e-11 + 3.297248e+03 1.259292e+01 -1.575180e+00 -1.259292e+01 -1.998284e+00 -2.185353e+00 -7.257195e+00 -6.352015e+00 -8.966835e+00 -4.655479e+00 -7.150299e+00 -3.479392e+01 -1.620100e+01 -5.535220e+00 -5.347923e+00 -1.709343e+01 -8.656995e+01 -8.860513e+01 9.999998e-01 1.000000e+00 1.000000e+00 1.113003e-03 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.512765e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240010e+01 -5.579821e+00 -6.251282e+00 5.606839e-07 6.606451e-02 9.142630e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.254687e-06 2.280017e-01 5.433375e-88 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -3.079010e+05 -3.232960e-11 + 3.393376e+03 1.259292e+01 -1.575180e+00 -1.259292e+01 -1.998283e+00 -2.185352e+00 -7.257196e+00 -6.352015e+00 -8.966835e+00 -4.655479e+00 -7.150298e+00 -3.478791e+01 -1.619499e+01 -5.529212e+00 -5.341915e+00 -1.708743e+01 -8.646995e+01 -8.850513e+01 9.999998e-01 1.000000e+00 1.000000e+00 1.128507e-03 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.533837e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240010e+01 -5.579821e+00 -6.251282e+00 5.606839e-07 6.698480e-02 9.530050e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.275314e-06 2.280017e-01 6.840214e-88 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.655675e+05 -1.738459e-11 diff --git a/base/Sulfaco/Sulfaco.sto b/base/Sulfaco/Sulfaco.sto new file mode 100644 index 00000000..75a7721c --- /dev/null +++ b/base/Sulfaco/Sulfaco.sto @@ -0,0 +1,12 @@ +3.393376e+03 +-3.478791398338e+01 0.000000000000e+00 9.999998036030e-01 -8.646994607891e+01 -6.251281913856e+00 -1.575180402688e+00 +-3.478791398338e+01 0.000000000000e+00 9.999998036030e-01 -8.646994607891e+01 -6.251281913856e+00 -1.575180402688e+00 +3.275314390302e-06 -1.623262929194e-08 4.373665790241e+00 6.840214092310e-88 1.393004535655e+00 2.280016687964e-01 1.999995924944e-100 1.529999711561e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 5.912828020673e-07 1.139999799806e-01 1.999995924944e-01 1.999995924944e-01 0.000000000000e+00 1.000000000000e-02 9.528702673129e-01 -1.738459120277e-11 6.000000000000e-04 +3.275314390302e-06 -0.000000000000e+00 0.000000000000e+00 3.275314390302e-06 -1.623262929194e-08 0.000000000000e+00 -0.000000000000e+00 -1.623262929194e-08 4.373665790241e+00 -0.000000000000e+00 0.000000000000e+00 4.373665790241e+00 6.840214092310e-88 -0.000000000000e+00 0.000000000000e+00 6.840214092310e-88 1.393004535655e+00 -0.000000000000e+00 0.000000000000e+00 1.393004535655e+00 2.280016687964e-01 -0.000000000000e+00 0.000000000000e+00 2.280016687964e-01 1.999995924944e-100 -0.000000000000e+00 0.000000000000e+00 1.999995924944e-100 1.529999711561e+00 1.529999711561e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 5.912828020673e-07 5.912828020673e-07 1.139999799806e-01 1.139999799806e-01 1.999995924944e-01 1.999995924944e-01 1.999995924944e-01 1.999995924944e-01 0.000000000000e+00 0.000000000000e+00 1.000000000000e-02 1.000000000000e-02 9.528702673129e-01 9.528702673129e-01 -1.738459120277e-11 -1.738459120277e-11 6.000000000000e-04 6.000000000000e-04 +3.275314390302e-06 -1.623262929194e-08 4.373665790241e+00 6.840214092310e-88 1.393004535655e+00 2.280016687964e-01 1.999995924944e-100 1.529999711561e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 5.912828020673e-07 1.139999799806e-01 1.999995924944e-01 1.999995924944e-01 0.000000000000e+00 1.000000000000e-02 9.528702673129e-01 -1.738459120277e-11 6.000000000000e-04 +0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 +2.121496197455e-03 2.121496197455e-03 5.557066522886e+01 2.553167205239e-13 2.659620043982e-02 1.003961065629e-02 6.526008174802e-03 7.101597688124e-06 5.531010463677e-08 4.446157906930e-07 1.079357430044e-09 2.210656934748e-05 7.074597782632e-08 1.000000000000e-99 1.757193537249e-101 3.388862289323e-87 3.125169077109e-89 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 1.629618763932e-35 6.382734200046e-17 2.956565479526e-06 8.176616521838e-18 4.550773183292e-06 1.000000000000e-99 3.980157436996e-33 2.631350134900e-06 5.557066522886e+01 2.553167205239e-13 2.659620043982e-02 1.003961065629e-02 6.526008174802e-03 7.101597688124e-06 5.531010463677e-08 4.446157906930e-07 1.079357430044e-09 2.210656934748e-05 7.074597782632e-08 1.000000000000e-99 1.757193537249e-101 3.388862289323e-87 3.125169077109e-89 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 1.629618763932e-35 6.382734200046e-17 2.956565479526e-06 8.176616521838e-18 4.550773183292e-06 1.000000000000e-99 3.980157436996e-33 2.631350134900e-06 +0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 +1.788707476412e-01 0.000000000000e+00 +1.788707476412e-01 1.788707476412e-01 +1.788707476412e-01 0.000000000000e+00 diff --git a/base/Sulfaco/Sulfaco.t0 b/base/Sulfaco/Sulfaco.t0 new file mode 100644 index 00000000..9f23eb0b --- /dev/null +++ b/base/Sulfaco/Sulfaco.t0 @@ -0,0 +1,8 @@ +# Version 2.6, Fri Aug 24 08:20:53 2018 +# Time = 0.000000e+00 +# Model = Sulfaco +# Number of views = 58 +# Numbers of components per view = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +# Coordinates(1) ph(4) c_oh(5) c_h(6) c_ca(7) c_caoh(8) c_h2sio4(9) c_h3sio4(10) c_h4sio4(11) c_cah2sio4(12) c_cah3sio4(13) c_h2so4(14) c_hso4(15) c_so4(16) c_caso4aq(17) c_cahso4(18) c_k(19) c_koh(20) zn_ca_s(21) zn_si_s(22) s_ch(23) s_csh2(24) n_ch(25) n_csh2(26) n_csh(27) porosite(28) potentiel_electrique(29) charge(30) V_CSH(31) C/S(32) W_Si(33) W_Ca(34) W_S(35) P_CSH2(36) Damage(37) c_al(38) c_alo4h4(39) zn_al_s(40) s_ah3(41) s_afm(42) s_aft(43) s_c3ah6(44) n_ah3(45) n_afm(46) n_aft(47) n_c3ah6(48) W_Al(49) W_q(50) N_Ca(51) N_Si(52) N_S(53) N_Al(54) N_K(55) N_Cl(56) Saturation degree of crystal(57) Pore entry radius(58) Equilibrium saturation index of AFt(59) Crystallization pressure(60) Strain(61) + 0.000000e+00 0.000000e+00 0.000000e+00 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203517e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924977e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -6.148822e-18 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243450e+01 -5.614166e+00 -6.320000e+00 4.786301e-07 3.508909e-02 1.879832e-01 8.536541e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695232e-06 2.280017e-01 2.018440e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 0.000000e+00 0.000000e+00 + 1.000000e+00 0.000000e+00 0.000000e+00 1.259294e+01 -1.575166e+00 -1.259294e+01 -1.998313e+00 -2.185367e+00 -7.257166e+00 -6.352000e+00 -8.966835e+00 -4.655479e+00 -7.150313e+00 -3.500000e+01 -1.640706e+01 -5.741269e+00 -5.554001e+00 -1.729953e+01 -9.000000e+01 -9.203517e+01 1.000000e+00 1.000000e+00 1.000000e+00 6.924977e-04 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 -6.148822e-18 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.243450e+01 -5.614166e+00 -6.320000e+00 4.786301e-07 3.508909e-02 1.879832e-01 8.536541e-01 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 2.695232e-06 2.280017e-01 2.018440e-91 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 0.000000e+00 0.000000e+00 diff --git a/base/Sulfaco/Sulfaco.t1 b/base/Sulfaco/Sulfaco.t1 new file mode 100644 index 00000000..43dbac32 --- /dev/null +++ b/base/Sulfaco/Sulfaco.t1 @@ -0,0 +1,8 @@ +# Version 2.6, Fri Aug 24 08:20:53 2018 +# Time = 3.393376e+03 +# Model = Sulfaco +# Number of views = 58 +# Numbers of components per view = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +# Coordinates(1) ph(4) c_oh(5) c_h(6) c_ca(7) c_caoh(8) c_h2sio4(9) c_h3sio4(10) c_h4sio4(11) c_cah2sio4(12) c_cah3sio4(13) c_h2so4(14) c_hso4(15) c_so4(16) c_caso4aq(17) c_cahso4(18) c_k(19) c_koh(20) zn_ca_s(21) zn_si_s(22) s_ch(23) s_csh2(24) n_ch(25) n_csh2(26) n_csh(27) porosite(28) potentiel_electrique(29) charge(30) V_CSH(31) C/S(32) W_Si(33) W_Ca(34) W_S(35) P_CSH2(36) Damage(37) c_al(38) c_alo4h4(39) zn_al_s(40) s_ah3(41) s_afm(42) s_aft(43) s_c3ah6(44) n_ah3(45) n_afm(46) n_aft(47) n_c3ah6(48) W_Al(49) W_q(50) N_Ca(51) N_Si(52) N_S(53) N_Al(54) N_K(55) N_Cl(56) Saturation degree of crystal(57) Pore entry radius(58) Equilibrium saturation index of AFt(59) Crystallization pressure(60) Strain(61) + 0.000000e+00 0.000000e+00 0.000000e+00 1.259292e+01 -1.575180e+00 -1.259292e+01 -1.998283e+00 -2.185352e+00 -7.257196e+00 -6.352015e+00 -8.966835e+00 -4.655479e+00 -7.150298e+00 -3.478791e+01 -1.619499e+01 -5.529212e+00 -5.341915e+00 -1.708743e+01 -8.646995e+01 -8.850513e+01 9.999998e-01 1.000000e+00 1.000000e+00 1.128507e-03 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.533837e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240010e+01 -5.579821e+00 -6.251282e+00 5.606839e-07 6.698480e-02 9.530050e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.275314e-06 2.280017e-01 6.840214e-88 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.655675e+05 -1.738459e-11 + 1.000000e+00 0.000000e+00 0.000000e+00 1.259292e+01 -1.575180e+00 -1.259292e+01 -1.998283e+00 -2.185352e+00 -7.257196e+00 -6.352015e+00 -8.966835e+00 -4.655479e+00 -7.150298e+00 -3.478791e+01 -1.619499e+01 -5.529212e+00 -5.341915e+00 -1.708743e+01 -8.646995e+01 -8.850513e+01 9.999998e-01 1.000000e+00 1.000000e+00 1.128507e-03 1.530000e+00 0.000000e+00 1.393000e+00 1.999996e-01 0.000000e+00 1.533837e-11 7.992496e-02 1.793498e+00 -0.000000e+00 -0.000000e+00 -0.000000e+00 0.000000e+00 0.000000e+00 -3.240010e+01 -5.579821e+00 -6.251282e+00 5.606839e-07 6.698480e-02 9.530050e-01 1.000000e+00 0.000000e+00 0.000000e+00 5.912828e-07 1.140000e-01 -0.000000e+00 0.000000e+00 4.373666e+00 1.393005e+00 3.275314e-06 2.280017e-01 6.840214e-88 1.999996e-100 2.100000e-06 1.000000e-02 1.000058e+00 -1.655675e+05 -1.738459e-11 diff --git a/make.extralibs b/make.extralibs index 52f8e0df..d3e658b3 100644 --- a/make.extralibs +++ b/make.extralibs @@ -1,17 +1,21 @@ # SHELL = /bin/sh -# Do you use libraries BLAS and SuperLU (YES/NO) ? -BLAS_USE := NO -SLU_USE := NO +# Do you use these libraries: BLAS, LAPACK, SuperLU or others (YES/NO) ? +BLAS_USE := YES +SLU_USE := YES +LAPACK_USE := YES # if YES, where are these libraries ? # Change if needed (${HOME} is root when sudo so I removed it) -#SLU_DIR := ${HOME}/Documents/Softwares/superLU/SuperLU_3.0 -SLU_DIR := /home/dangla/Documents/Softwares/superLU/SuperLU_3.0 -SLU_LIB := ${SLU_DIR}/superlu_linux.a -BLAS_DIR := ${SLU_DIR} -BLAS_LIB := ${BLAS_DIR}/blas_linux.a +#SLU_DIR := ${HOME}/Documents/Softwares/superLU/SuperLU_3.0 +#SLU_DIR := /home/dangla/Documents/Softwares/superLU/SuperLU_3.0 +SLU_DIR := /usr/lib/x86_64-linux-gnu +SLU_LIB := ${SLU_DIR}/libsuperlu.so.5 +BLAS_DIR := /usr/lib +BLAS_LIB := ${BLAS_DIR}/libblas.so.3 +LAPACK_DIR := /usr/lib +LAPACK_LIB := ${LAPACK_DIR}/liblapack.so.3 BIL_EXTRALIBS := @@ -23,6 +27,10 @@ ifeq (${BLAS_USE},YES) BIL_EXTRALIBS += ${BLAS_LIB} endif +ifeq (${LAPACK_USE},YES) + BIL_EXTRALIBS += ${LAPACK_LIB} +endif + # Library UEL BIL_EXTRALIBS += /home/dangla/Documents/Softwares/bil/Projects/IoannisStefanou/libUEL_64.so diff --git a/make.inc b/make.inc index 88a8732a..813c811d 100644 --- a/make.inc +++ b/make.inc @@ -5,8 +5,8 @@ UNAME = Linux # Compilers (C++11 for variadic macros) #---------- -CC := gcc -x c++ -std=c++11 -CPP := g++ +CC := gcc -x c -std=c11 +CPP := gcc -x c++ -std=c++11 F77 := gfortran @@ -27,10 +27,10 @@ DFLAGS = -iquote${BIL_PATH} # Preprocessor flags #------------------- -IFLAGS = -iprefix ${BIL_PATH}/src/ -iwithprefix . -iwithprefix DataSet -iwithprefix Outputs -iwithprefix Solver -iwithprefix Tools -iwithprefix Models -iwithprefix Modules -iwithprefix Help -iwithprefix Common -iwithprefix Main -iwithprefix Macros +IFLAGS = -iprefix ${BIL_PATH}/src/ -iwithprefix . -iwithprefix Common -iwithprefix DataSet -iwithprefix Help -iwithprefix Libraries -iwithprefix Macros -iwithprefix Main -iwithprefix Models -iwithprefix Modules -iwithprefix Outputs -iwithprefix Solver -iwithprefix Tools # Additional flags for models -IFLAGS-MODELS = -iprefix ${BIL_PATH}/src/Models/ -iwithprefix . -iwithprefix Methods -iwithprefix Libraries -iwithprefix DataBases +IFLAGS-MODELS = -iprefix ${BIL_PATH}/src/Models/ -iwithprefix . -iwithprefix DataBases -iwithprefix Libraries -iwithprefix Methods # Additional flags for modules IFLAGS-MODULES = -iprefix ${BIL_PATH}/src/Modules/ -iwithprefix . diff --git a/src/Common/GenericData.c b/src/Common/GenericData.c index 00a6a91f..de7362d7 100644 --- a/src/Common/GenericData.c +++ b/src/Common/GenericData.c @@ -5,7 +5,7 @@ #include "Message.h" #include "TypeId.h" #include "GenericData.h" -#include "GenericObject.h" +//#include "GenericObject.h" #include "Tools/Math.h" diff --git a/src/Common/GenericObject.c b/src/Common/GenericObject.c index 4c37e33b..5272ccf9 100644 --- a/src/Common/GenericObject.c +++ b/src/Common/GenericObject.c @@ -1,3 +1,5 @@ +#if 0 + #include #include #include @@ -5,7 +7,6 @@ #include "Class.h" #include "GenericObject.h" -#if 0 diff --git a/src/Common/GenericObject.h b/src/Common/GenericObject.h index 1893787a..4d8cfc3f 100644 --- a/src/Common/GenericObject.h +++ b/src/Common/GenericObject.h @@ -20,6 +20,16 @@ typedef void (GenericObject_Delete_t)(void*) ; /* GenericObject_t * ---------------*/ + + +/* OBJ stands for a pointer to an object. + * (OBJ)->delete should point to a function which is expected + * to free the space allocated for the creation of OBJ. */ +#define GenericObject_Delete(OBJ) \ + (*(OBJ))->Delete(OBJ) + +#endif +#if 0 template extern void* GenericObject_New_(const int = 1) ; template inline void* GenericObject_New_(const int n) @@ -34,13 +44,6 @@ template inline void* GenericObject_New_(const int n) GenericObject_New_(__VA_ARGS__) -/* OBJ stands for a pointer to an object. - * (OBJ)->delete should point to a function which is expected - * to free the space allocated for the creation of OBJ. */ -#define GenericObject_Delete(OBJ) \ - (*(OBJ))->Delete(OBJ) - - #endif #if 0 diff --git a/src/Common/Options.h b/src/Common/Options.h index f92f1140..75d6355d 100644 --- a/src/Common/Options.h +++ b/src/Common/Options.h @@ -29,11 +29,31 @@ extern void (Options_Delete)(void*) ; #define Options_GetDebug(OPT) \ Options_GetPrintData(OPT) + + +#include + +#define Options_IsToPrintOutAtEachIteration(OPT) \ + (!strcmp(Options_GetPrintLevel(OPT),"2")) + + +#define Options_GetFillFactor(OPT) \ + (((!strcmp(((char**) Context_GetSolver(Options_GetContext(OPT)))[2],"-ff")) && atof(((char**) Context_GetSolver(Options_GetContext(OPT)))[3])) ? \ + atof(((char**) Context_GetSolver(Options_GetContext(OPT)))[3]) : Options_DefaultFillFactor) + + +#define Options_DefaultFillFactor (2) + struct Options_s { /* options */ char* debug ; /* data to be printed */ char* method ; /* resolution method */ + /* Print level + * 0: minimal, + * 1: normal at each step , + * 2: normal at each iteration, + * 3-: not used) */ char* level ; /* print level */ char* module ; /* module */ char* graph ; /* Graph method */ diff --git a/src/DataSet/CoorSys.h b/src/DataSet/CoorSys.h new file mode 100644 index 00000000..404beff0 --- /dev/null +++ b/src/DataSet/CoorSys.h @@ -0,0 +1,42 @@ +#ifndef COORSYS_H +#define COORSYS_H + +enum CoorSys_e { /* coordinate system */ + COORSYS_CARTESIAN, + COORSYS_CYLINDRICAL, + COORSYS_SPHERICAL, + CARTESIAN = COORSYS_CARTESIAN /* Should be eliminated */ +} ; + + +/* vacuous declarations and typedef names */ + +/* 1. CoorSys_t attributes */ +typedef enum CoorSys_e CoorSys_t ; + + + +/* Test the coordinate system */ +#define CoorSys_IsCartesian(COO) \ + (COO == COORSYS_CARTESIAN) + +#define CoorSys_IsCylindrical(COO) \ + (COO == COORSYS_CYLINDRICAL) + +#define CoorSys_IsSpherical(COO) \ + (COO == COORSYS_SPHERICAL) + + + +/* Set the coordinate system */ +#define CoorSys_SetCartesian(COO) \ + (COO = COORSYS_CARTESIAN) + +#define CoorSys_SetCylindrical(COO) \ + (COO = COORSYS_CYLINDRICAL) + +#define CoorSys_SetSpherical(COO) \ + (COO = COORSYS_SPHERICAL) + + +#endif diff --git a/src/DataSet/DataSet.c b/src/DataSet/DataSet.c index 282b803d..5a6bc2e1 100644 --- a/src/DataSet/DataSet.c +++ b/src/DataSet/DataSet.c @@ -189,7 +189,7 @@ void DataSet_PrintData(DataSet_t* jdd,char* mot) } else if(Symmetry_IsSpherical(SYMMETRY)) { fprintf(stdout,"Spherical\n") ; - } else if(SYMMETRY == PLAN) { + } else if(Symmetry_IsPlane(SYMMETRY)) { fprintf(stdout,"Plane\n") ; } else { diff --git a/src/DataSet/Element.c b/src/DataSet/Element.c index e3a4e5a6..b6180540 100644 --- a/src/DataSet/Element.c +++ b/src/DataSet/Element.c @@ -60,7 +60,7 @@ Element_AllocateGenericData(Element_t* el,int n,void* gdat,TypeId_t typeid) -double** Element_ComputePointerToNodalCoordinates(Element_t* element) +double** (Element_ComputePointerToNodalCoordinates)(Element_t* element) /** Compute the nodal coordinates */ { int nn = Element_GetNbOfNodes(element) ; @@ -77,7 +77,7 @@ double** Element_ComputePointerToNodalCoordinates(Element_t* element) -double* Element_ComputeNodalCoordinates(Element_t* element) +double* (Element_ComputeNodalCoordinates)(Element_t* element) /** Compute the nodal coordinates */ { int nn = Element_GetNbOfNodes(element) ; @@ -100,7 +100,7 @@ double* Element_ComputeNodalCoordinates(Element_t* element) -double** Element_ComputePointerToCurrentNodalUnknowns(Element_t* element) +double** (Element_ComputePointerToCurrentNodalUnknowns)(Element_t* element) /** Compute a pointer to the nodal unknowns at the current time */ { int nn = Element_GetNbOfNodes(element) ; @@ -117,7 +117,7 @@ double** Element_ComputePointerToCurrentNodalUnknowns(Element_t* element) -double** Element_ComputePointerToPreviousNodalUnknowns(Element_t* element) +double** (Element_ComputePointerToPreviousNodalUnknowns)(Element_t* element) /** Compute a pointer to the nodal unknowns at the current time */ { int nn = Element_GetNbOfNodes(element) ; @@ -134,7 +134,7 @@ double** Element_ComputePointerToPreviousNodalUnknowns(Element_t* element) -double* Element_ComputeDeepNodalUnknowns(Element_t* element,unsigned int depth) +double* (Element_ComputeDeepNodalUnknowns)(Element_t* element,unsigned int depth) /** Compute the nodal unknowns at the some depth */ { int nn = Element_GetNbOfNodes(element) ; @@ -163,7 +163,7 @@ double* Element_ComputeDeepNodalUnknowns(Element_t* element,unsigned int depth) -double* Element_ComputeCurrentNodalUnknowns(Element_t* element) +double* (Element_ComputeCurrentNodalUnknowns)(Element_t* element) /** Compute the nodal unknowns at the current time */ { int nn = Element_GetNbOfNodes(element) ; @@ -192,7 +192,7 @@ double* Element_ComputeCurrentNodalUnknowns(Element_t* element) -double* Element_ComputePreviousNodalUnknowns(Element_t* element) +double* (Element_ComputePreviousNodalUnknowns)(Element_t* element) /** Compute the nodal unknowns at the previous time */ { int nn = Element_GetNbOfNodes(element) ; @@ -221,7 +221,7 @@ double* Element_ComputePreviousNodalUnknowns(Element_t* element) -double* Element_ComputeIncrementalNodalUnknowns(Element_t* element) +double* (Element_ComputeIncrementalNodalUnknowns)(Element_t* element) /** Compute the incremental values of nodal unknowns */ { int nn = Element_GetNbOfNodes(element) ; @@ -251,7 +251,7 @@ double* Element_ComputeIncrementalNodalUnknowns(Element_t* element) -double* Element_ComputeIncrementalImplicitTerms(Element_t* element) +double* (Element_ComputeIncrementalImplicitTerms)(Element_t* element) { int n = Element_GetNbOfImplicitTerms(element) ; double* vi1 = Element_GetCurrentImplicitTerm(element) ; @@ -267,7 +267,7 @@ double* Element_ComputeIncrementalImplicitTerms(Element_t* element) -int Element_FindUnknownPositionIndex(Element_t* element,char* s) +int (Element_FindUnknownPositionIndex)(Element_t* element,char* s) /** Find the unknown position index whose name is pointed to by s */ { int n = Element_GetNbOfEquations(element) ; @@ -287,7 +287,7 @@ int Element_FindUnknownPositionIndex(Element_t* element,char* s) -int Element_FindEquationPositionIndex(Element_t* element,char* s) +int (Element_FindEquationPositionIndex)(Element_t* element,char* s) /** Find the equation position index whose name is pointed to by s */ { int n = Element_GetNbOfEquations(element) ; @@ -308,7 +308,7 @@ int Element_FindEquationPositionIndex(Element_t* element,char* s) -double* Element_ComputeNormalVector(Element_t* element,double* dh,int nn) +double* (Element_ComputeNormalVector)(Element_t* element,double* dh,int nn) /** Compute the unit outward normal vector to a submanifold element * of dimension dim-1 */ { @@ -382,7 +382,7 @@ double* Element_ComputeNormalVector(Element_t* element,double* dh,int nn) -double* Element_ComputeCoordinateInReferenceFrame(Element_t* el,double* x) +double* (Element_ComputeCoordinateInReferenceFrame)(Element_t* el,double* x) /** Compute the local coordinates in the reference element which maps * into coordinates "x" in the actual space */ { @@ -512,7 +512,7 @@ double* Element_ComputeCoordinateInReferenceFrame(Element_t* el,double* x) -int Element_ComputeNbOfSolutions(Element_t* el) +int (Element_ComputeNbOfSolutions)(Element_t* el) { ElementSol_t* elementsol = Element_GetElementSol(el) ; int n = 0 ; @@ -526,3 +526,32 @@ int Element_ComputeNbOfSolutions(Element_t* el) return(n) ; } + + + +int* (Element_ComputeMatrixRowAndColumnIndices)(Element_t* el) +{ + int nn = Element_GetNbOfNodes(el) ; + int neq = Element_GetNbOfEquations(el) ; + + size_t SizeNeeded = 2*nn*neq*sizeof(int) ; + int* rowind = (int*) Element_AllocateInBuffer(el,SizeNeeded) ; + int* colind = rowind + nn*neq ; + int i ; + + for(i = 0 ; i < nn ; i++) { + Node_t* node_i = Element_GetNode(el,i) ; + int j ; + + for(j = 0 ; j < neq ; j++) { + int ij = i*neq + j ; + int jj_col = Element_GetUnknownPosition(el)[ij] ; + int jj_row = Element_GetEquationPosition(el)[ij] ; + + colind[ij] = (jj_col >= 0) ? Node_GetMatrixColumnIndex(node_i)[jj_col] : -1 ; + rowind[ij] = (jj_row >= 0) ? Node_GetMatrixRowIndex(node_i)[jj_row] : -1 ; + } + } + + return(rowind) ; +} diff --git a/src/DataSet/Element.h b/src/DataSet/Element.h index d5a382ac..edd04df7 100644 --- a/src/DataSet/Element.h +++ b/src/DataSet/Element.h @@ -9,20 +9,21 @@ struct Element_s ; typedef struct Element_s Element_t ; -extern double** (Element_ComputePointerToCurrentNodalUnknowns)(Element_t*) ; -extern double** (Element_ComputePointerToPreviousNodalUnknowns)(Element_t*) ; -extern double* (Element_ComputeCurrentNodalUnknowns)(Element_t*) ; -extern double* (Element_ComputePreviousNodalUnknowns)(Element_t*) ; -extern double* (Element_ComputeIncrementalNodalUnknowns)(Element_t*) ; -extern double* (Element_ComputeDeepNodalUnknowns)(Element_t*,unsigned int) ; -extern double** (Element_ComputePointerToNodalCoordinates)(Element_t*) ; -extern double* (Element_ComputeNodalCoordinates)(Element_t*) ; -extern int (Element_FindUnknownPositionIndex)(Element_t*,char*) ; -extern int (Element_FindEquationPositionIndex)(Element_t*,char*) ; -extern double* (Element_ComputeIncrementalImplicitTerms)(Element_t*) ; -extern double* (Element_ComputeNormalVector)(Element_t*,double*,int) ; -extern double* (Element_ComputeCoordinateInReferenceFrame)(Element_t*,double*) ; -extern int (Element_ComputeNbOfSolutions)(Element_t*) ; +extern double** (Element_ComputePointerToCurrentNodalUnknowns) (Element_t*) ; +extern double** (Element_ComputePointerToPreviousNodalUnknowns) (Element_t*) ; +extern double* (Element_ComputeCurrentNodalUnknowns) (Element_t*) ; +extern double* (Element_ComputePreviousNodalUnknowns) (Element_t*) ; +extern double* (Element_ComputeIncrementalNodalUnknowns) (Element_t*) ; +extern double* (Element_ComputeDeepNodalUnknowns) (Element_t*,unsigned int) ; +extern double** (Element_ComputePointerToNodalCoordinates) (Element_t*) ; +extern double* (Element_ComputeNodalCoordinates) (Element_t*) ; +extern int (Element_FindUnknownPositionIndex) (Element_t*,char*) ; +extern int (Element_FindEquationPositionIndex) (Element_t*,char*) ; +extern double* (Element_ComputeIncrementalImplicitTerms) (Element_t*) ; +extern double* (Element_ComputeNormalVector) (Element_t*,double*,int) ; +extern double* (Element_ComputeCoordinateInReferenceFrame) (Element_t*,double*) ; +extern int (Element_ComputeNbOfSolutions) (Element_t*) ; +extern int* (Element_ComputeMatrixRowAndColumnIndices) (Element_t*) ; /* Synonyms */ diff --git a/src/DataSet/Elements.c b/src/DataSet/Elements.c index 89de2ac8..d76dd5ac 100644 --- a/src/DataSet/Elements.c +++ b/src/DataSet/Elements.c @@ -15,9 +15,10 @@ #include "Curves.h" -static double Elements_ComputeMaximumSizeOfElements(Elements_t*) ; -static double Elements_ComputeMinimumSizeOfElements(Elements_t*) ; +static double (Elements_ComputeMaximumSizeOfElements)(Elements_t*) ; +static double (Elements_ComputeMinimumSizeOfElements)(Elements_t*) ; static double (Element_ComputeSize)(Element_t*) ; +static int (Element_ComputeNbOfMatrixEntries)(Element_t*) ; void Elements_CreateMore(Elements_t* elements,Materials_t* materials) @@ -276,3 +277,59 @@ double Element_ComputeSize(Element_t* element) return(h) ; } + + + + +int Elements_ComputeNbOfMatrixEntries(Elements_t* elements) +{ + int nel = Elements_GetNbOfElements(elements) ; + Element_t* el = Elements_GetElement(elements) ; + int len = 0 ; + + { + int ie ; + + for(ie = 0 ; ie < nel ; ie++) { + Element_FreeBuffer(el + ie) ; + len += Element_ComputeNbOfMatrixEntries(el + ie) ; + } + } + + return(len) ; +} + + + + +int Element_ComputeNbOfMatrixEntries(Element_t* element) +{ + int ndof = Element_GetNbOfDOF(element) ; + int* row = Element_ComputeMatrixRowAndColumnIndices(element) ; + int* col = row + ndof ; + int len = 0 ; + + { + int jdof ; + + for(jdof = 0 ; jdof < ndof ; jdof++) { + int jcol = col[jdof] ; + + if(jcol < 0) continue ; + + { + int idof ; + + for(idof = 0 ; idof < ndof ; idof++) { + int irow = row[idof] ; + + if(irow < 0) continue ; + + len++ ; + } + } + } + } + + return(len) ; +} diff --git a/src/DataSet/Elements.h b/src/DataSet/Elements.h index 20d1c8bb..94f45629 100644 --- a/src/DataSet/Elements.h +++ b/src/DataSet/Elements.h @@ -12,6 +12,7 @@ struct Elements_s ; typedef struct Elements_s Elements_t ; extern void (Elements_CreateMore)(Elements_t*,Materials_t*) ; extern void (Elements_DefineProperties)(Elements_t*) ; +extern int (Elements_ComputeNbOfMatrixEntries)(Elements_t*) ; diff --git a/src/DataSet/Geometry.h b/src/DataSet/Geometry.h index c3783d7e..f0799ec5 100644 --- a/src/DataSet/Geometry.h +++ b/src/DataSet/Geometry.h @@ -1,37 +1,12 @@ #ifndef GEOMETRY_H #define GEOMETRY_H -enum Symmetry_e { /* symmetry of the problem */ - NO, - PLAN, - AXIS, - SPHE -} ; - -enum CoorSys_e { /* coordinate system */ - CARTESIAN, - CYLINDRICAL, - SPHERICAL -} ; - /* vacuous declarations and typedef names */ /* class-like structure */ struct Geometry_s ; typedef struct Geometry_s Geometry_t ; -/* 1. Geometry_t attributes */ -typedef enum CoorSys_e CoorSys_t ; -typedef enum Symmetry_e Symmetry_t ; - - - -/* Test the symmetry */ -#define Symmetry_IsCylindrical(SYM) (SYM == AXIS) -#define Symmetry_IsSpherical(SYM) (SYM == SPHE) -#define Symmetry_IsPlane(SYM) (SYM == PLAN) - - /* 1. Geometry_t * -------------*/ @@ -61,40 +36,39 @@ extern Geometry_t* Geometry_Create(DataFile_t*) ; /* Set the symmetry */ #define Geometry_SetNoSymmetry(GEO) \ do { \ - Geometry_GetSymmetry(GEO) = NO ; \ - Geometry_GetCoordinateSystem(GEO) = CARTESIAN ; \ + Symmetry_SetNoSymmetry(Geometry_GetSymmetry(GEO)) ; \ + CoorSys_SetCartesian(Geometry_GetCoordinateSystem(GEO)) ; \ } while(0) #define Geometry_SetPlaneSymmetry(GEO) \ do { \ - Geometry_GetSymmetry(GEO) = PLAN ; \ - Geometry_GetCoordinateSystem(GEO) = CARTESIAN ; \ + Symmetry_SetPlaneSymmetry(Geometry_GetSymmetry(GEO)) ; \ + CoorSys_SetCartesian(Geometry_GetCoordinateSystem(GEO)) ; \ } while(0) #define Geometry_SetCylindricalSymmetry(GEO) \ do { \ - Geometry_GetSymmetry(GEO) = AXIS ; \ - Geometry_GetCoordinateSystem(GEO) = CYLINDRICAL ; \ + Symmetry_SetCylindricalSymmetry(Geometry_GetSymmetry(GEO)) ; \ + CoorSys_SetCylindrical(Geometry_GetCoordinateSystem(GEO)) ; \ } while(0) #define Geometry_SetSphericalSymmetry(GEO) \ do { \ - Geometry_GetSymmetry(GEO) = SPHE ; \ - Geometry_GetCoordinateSystem(GEO) = SPHERICAL ; \ + Symmetry_SetSphericalSymmetry(Geometry_GetSymmetry(GEO)) ; \ + CoorSys_SetSpherical(Geometry_GetCoordinateSystem(GEO)) ; \ } while(0) +#include "Symmetry.h" +#include "CoorSys.h" #include "Periodicities.h" struct Geometry_s { - unsigned short int dim ; /* dimension (1,2,3) */ - Symmetry_t symmetry ; /* symmetry (PLAN,AXIS,SPHE) */ - CoorSys_t coorsys ; /* coordinate system (CARTESIAN,CYLINDRICAL,SPHERICAL) */ + unsigned short int dim ; /* Dimension (1,2,3) */ + Symmetry_t symmetry ; /* Symmetry */ + CoorSys_t coorsys ; /* Coordinate system */ Periodicities_t* periodicities ; } ; -/* Old notations which I try to eliminate little by little */ -#define geom_t Symmetry_t - #endif diff --git a/src/DataSet/Mesh.h b/src/DataSet/Mesh.h index a2aec9e0..b7b2931e 100644 --- a/src/DataSet/Mesh.h +++ b/src/DataSet/Mesh.h @@ -80,6 +80,13 @@ extern void (Mesh_UpdateCurrentUnknowns)(Mesh_t*,Solver_t*) ; +/* Compute the nb of matrix entries */ +#define Mesh_ComputeNbOfMatrixEntries(MSH) \ + Elements_ComputeNbOfMatrixEntries(Mesh_GetElements(MSH)) + + + + /* Periodicities */ #define Mesh_GetPeriodicities(MSH) \ Geometry_GetPeriodicities(Mesh_GetGeometry(MSH)) diff --git a/src/DataSet/Symmetry.h b/src/DataSet/Symmetry.h new file mode 100644 index 00000000..8fd5700e --- /dev/null +++ b/src/DataSet/Symmetry.h @@ -0,0 +1,51 @@ +#ifndef SYMMETRY_H +#define SYMMETRY_H + +enum Symmetry_e { /* symmetry of the problem */ + SYMMETRY_NO, + SYMMETRY_PLAN, + SYMMETRY_AXIS, + SYMMETRY_SPHE, + AXIS = SYMMETRY_AXIS, /* Should be eliminated */ + SPHE = SYMMETRY_SPHE, +} ; + + +/* vacuous declarations and typedef names */ + +/* 1. Symmetry_t attributes */ +typedef enum Symmetry_e Symmetry_t ; + + + +/* Test the symmetry */ +#define Symmetry_IsCylindrical(SYM) \ + (SYM == SYMMETRY_AXIS) + +#define Symmetry_IsSpherical(SYM) \ + (SYM == SYMMETRY_SPHE) + +#define Symmetry_IsPlane(SYM) \ + (SYM == SYMMETRY_PLAN) + + + +/* Set the symmetry */ +#define Symmetry_SetNoSymmetry(SYM) \ + (SYM = SYMMETRY_NO) + +#define Symmetry_SetPlaneSymmetry(SYM) \ + (SYM = SYMMETRY_PLAN) + +#define Symmetry_SetCylindricalSymmetry(SYM) \ + (SYM = SYMMETRY_AXIS) + +#define Symmetry_SetSphericalSymmetry(SYM) \ + (SYM = SYMMETRY_SPHE) + + + +/* Old notations which I try to eliminate little by little */ +#define geom_t Symmetry_t + +#endif diff --git a/src/Libraries/hsl/fd15-1.0.0/doc/fd15_Fortran.pdf b/src/Libraries/hsl/fd15-1.0.0/doc/fd15_Fortran.pdf new file mode 100644 index 00000000..9ee32ef2 Binary files /dev/null and b/src/Libraries/hsl/fd15-1.0.0/doc/fd15_Fortran.pdf differ diff --git a/src/Libraries/hsl/fd15-1.0.0/src/fd15d.f b/src/Libraries/hsl/fd15-1.0.0/src/fd15d.f new file mode 100644 index 00000000..3c421ff2 --- /dev/null +++ b/src/Libraries/hsl/fd15-1.0.0/src/fd15d.f @@ -0,0 +1,39 @@ +* COPYRIGHT (c) 1988 AEA Technology +* Original date 17 Feb 2005 + +C 17th February 2005 Version 1.0.0. Replacement for FD05. + + DOUBLE PRECISION FUNCTION FD15AD(T) +C---------------------------------------------------------------- +C Fortran 77 implementation of the Fortran 90 intrinsic +C functions: EPSILON, TINY, HUGE and RADIX. Note that +C the RADIX result is returned as DOUBLE PRECISION. +C +C The CHARACTER argument specifies the type of result: +C +C 'E' smallest positive real number: 1.0 + DC(1) > 1.0, i.e. +C EPSILON(DOUBLE PRECISION) +C 'T' smallest full precision positive real number, i.e. +C TINY(DOUBLE PRECISION) +C 'H' largest finite positive real number, i.e. +C HUGE(DOUBLE PRECISION) +C 'R' the base of the floating point arithematic, i.e. +C RADIX(DOUBLE PRECISION) +C +C any other value gives a result of zero. +C---------------------------------------------------------------- + CHARACTER T + + IF ( T.EQ.'E' ) THEN + FD15AD = EPSILON(1.0D0) + ELSE IF ( T.EQ.'T' ) THEN + FD15AD = TINY(1.0D0) + ELSE IF ( T.EQ.'H' ) THEN + FD15AD = HUGE(1.0D0) + ELSE IF ( T.EQ.'R' ) THEN + FD15AD = DBLE(RADIX(1.0D0)) + ELSE + FD15AD = 0.0D0 + ENDIF + RETURN + END diff --git a/src/Libraries/hsl/hsl.f b/src/Libraries/hsl/hsl.f new file mode 100644 index 00000000..2b55952d --- /dev/null +++ b/src/Libraries/hsl/hsl.f @@ -0,0 +1,8 @@ +INCLUDE "./fd15-1.0.0/src/fd15d.f" +INCLUDE "./mc13-1.0.0/src/mc13d.f" +INCLUDE "./mc21-1.0.0/src/mc21d.f" +INCLUDE "./mc40-1.0.0/src/mc40d.f" +INCLUDE "./mc43-1.0.0/src/mc43d.f" +INCLUDE "./ma38-1.1.0/src/ma38d.f" +INCLUDE "./mc34-1.0.0/src/mc34d.f" +INCLUDE "./mc49-1.0.0/src/mc49d.f" diff --git a/src/Libraries/hsl/ma38-1.1.0/doc/ma38_Fortran.pdf b/src/Libraries/hsl/ma38-1.1.0/doc/ma38_Fortran.pdf new file mode 100644 index 00000000..ff49c109 Binary files /dev/null and b/src/Libraries/hsl/ma38-1.1.0/doc/ma38_Fortran.pdf differ diff --git a/src/Libraries/hsl/ma38-1.1.0/src/ma38d.f b/src/Libraries/hsl/ma38-1.1.0/src/ma38d.f new file mode 100644 index 00000000..e082f706 --- /dev/null +++ b/src/Libraries/hsl/ma38-1.1.0/src/ma38d.f @@ -0,0 +1,14427 @@ +C COPYRIGHT (c) 1995 Timothy A. Davis and +C Council for the Central Laboratory of the Research Councils +C Original date 30 November 1995 +C## Initialization of XOUT and IOUT added to subroutine MA38DD. 20/1/98 +C## In cases where MA38ED is not called this avoids a possibly wrong +C## decision on storage requirements after label 9000 in MA38DD. +C## Initialization of XRMAX moved to top of subroutine MA38DD. 14/1/99 +C## Small modifications to commenst on iout/xout in MA38DD and MA38ED. +C####################################################################### +C## MA38: double precision version +C## user-callable routines are listed first +C####################################################################### + +C 12th July 2004 Version 1.0.0. Version numbering added. +C 21st February 2005 Version 1.1.0. FD05 dependence changed to FD15. +C Calls to SGEMV with N=0 avoided to prevent subscript errors. + + SUBROUTINE MA38ID (KEEP, CNTL, ICNTL) + INTEGER KEEP(20) + DOUBLE PRECISION CNTL(10) + INTEGER ICNTL(20) + +C=== MA38ID ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Initialize user-controllable parameters to default values, and +C non-user controllable parameters. This routine is normally +C called once prior to any call to MA38AD. +C +C This routine sets the default control parameters. We recommend +C changing these defaults under certain circumstances: +C +C (1) If you know that your matrix has nearly symmetric nonzero +C pattern, then we recommend setting Icntl (6) to 1 so that +C diagonal pivoting is preferred. This can have a significant +C impact on the performance for matrices that are essentially +C symmetric in pattern. +C +C (2) If you know that your matrix is not reducible to block +C triangular form, then we recommend setting Icntl (4) to 0 +C so that MA38 does not try to permute the matrix to block +C triangular form (it will not do any useful work and will +C leave the matrix in its irreducible form). The work saved +C is typically small, however. +C +C The other control parameters typically have less effect on overall +C performance. + +C======================================================================= +C INSTALLATION NOTE: +C======================================================================= +C +C This routine can be modified on installation to reflect the computer +C or environment in which this package is installed (printing control, +C maximum integer, block size, and machine epsilon in particular). If +C you, the installer, modify this routine, please comment out the +C original code, and add comments (with date) to describe the +C installation. Do not delete any original code. + +C======================================================================= +C ARGUMENTS: +C======================================================================= + +C -------------------------------------------------------- +C Icntl: An integer array of size 20. Need not be set by +C caller on input. On output, it contains default +C integer control parameters. +C +C Icntl (1): Fortran output unit for error messages. +C Default: 6 +C +C Icntl (2): Fortran output unit for diagnostic messages. +C Default: 6 +C +C Icntl (3): printing-level. +C 0 or less: no output +C 1: error messages only +C 2: error messages and terse diagnostics +C 3: as 2, and print first few entries of all input and +C output arguments. Invalid and duplicate entries +C are printed. +C 4: as 2, and print all entries of all input and +C output arguments. Invalid and duplicate entries +C are printed. The entire input matrix and its +C factors are printed. +C 5: as 4, and print out information on the data +C structures used to represent the LU factors, +C the assembly DAG, etc. +C Default: 2 +C +C Icntl (4): whether or not to attempt a permutation to block +C triangular form. If equal to one, then attempt the +C permutation. If you know the matrix is not reducible +C to block triangular form, then setting Icntl (4) to +C zero can save a small amount of computing time. +C Default: 1 (attempt the permutation) +C +C Icntl (5): the number of columns to examine during the global +C pivot search. A value less than one is treated as one. +C Default: 4 +C +C Icntl (6): if not equal to zero, then pivots from the diagonal +C of A (or the diagonal of the block-triangular form) are +C preferred. If the nonzero pattern of the matrix is +C basically symmetric, we recommend that you change this +C default value to 1 so that pivots on the diagonal +C are preferred. +C Default: 0 (do not prefer the diagonal) +C +C Icntl (7): block size for the BLAS, controlling the tradeoff +C between the Level-2 and Level-3 BLAS. Values less than +C one are treated as one. +C Default: 16, which is suitable for the CRAY YMP. +C +C Icntl (8): number of steps of iterative refinement to perform. +C Values less than zero are treated as zero. The matrix +C must be preserved for iterative refinement to be done +C (job=1 in MA38AD or MA38BD). +C Default: 0 (no iterative refinement) +C +C Icntl (9 ... 20): set to zero. Reserved for future releases. + +C -------------------------------------------------------- +C Cntl: A double precision array of size 10. +C Need not be set by caller on input. On output, contains +C default double precision control parameters. +C +C Cntl (1): pivoting tradeoff between sparsity-preservation +C and numerical stability. An entry A(k,k) is numerically +C acceptable if: +C abs (A(k,k)) >= Cntl (1) * max (abs (A(*,k))) +C Values less than zero are treated as zero (no numerical +C constraints). Values greater than one are treated as +C one (partial pivoting with row interchanges). +C Default: 0.1 +C +C Cntl (2): amalgamation parameter. If the first pivot in a +C frontal matrix has row degree r and column degree c, +C then a working array of size +C (Cntl (2) * c) - by - (Cntl (2) * r) +C is allocated for the frontal matrix. Subsequent pivots +C within the same frontal matrix must fit within this +C working array, or they are not selected for this frontal +C matrix. Values less than one are treated as one (no +C fill-in due to amalgamation). Some fill-in due to +C amalgamation is necessary for efficient use of the BLAS +C and to reduce the assembly operations required. +C Default: 2.0 +C +C Cntl (3): Normally not modified by the user. +C Defines the smallest positive number, +C epsilon = Cntl (3), such that fl (1.0 + epsilon) +C is greater than 1.0 (fl (x) is the floating-point +C representation of x). If the floating-point mantissa +C is binary, then Cntl (3) is 2 ** (-b+1), where b +C is the number of bits in the mantissa (including the +C implied bit, if applicable). +C +C Cntl (3) is only +C used in MA38JD to compute the sparse backward error +C estimates, Rinfo (7) and Rinfo (8), when +C Icntl (8) > 0 (the default is Icntl (8) = 0, +C so by default, Cntl (3) is not used). +C +C Cntl (4 ... 10): set to zero. Reserved for future releases. + +C -------------------------------------------------------- +C Keep: An integer array of size 20. +C Need not be set by the caller. On output, contains +C integer control parameters that are (normally) non-user +C controllable (but can of course be modified by the +C "expert" user or library installer). +C +C Keep (1 ... 5): unmodified (see MA38AD or MA38BD for a description). +C +C Keep (6): Formerly, this held the largest representable positive +C integer. MA38 no longer needs this, and it is set to +C zero by MA38ID and ignored elsewhere. +C +C Keep (7) and Keep (8): A column is treated as "dense" if +C it has more than +C max (0, Keep(7), Keep(8)*int(sqrt(float(n)))) +C original entries. "Dense" columns are treated +C differently that "sparse" rows and columns. Dense +C columns are transformed into a priori contribution +C blocks of dimension cdeg-by-1, where cdeg is the number +C of original entries in the column. Modifying these two +C parameters can change the pivot order. +C Default: Keep (7) = 64 +C Default: Keep (8) = 1 +C +C Keep (9 ... 20): set to zero. Reserved for future releases. + +C## End of user documentation for MA38ID ############################### + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: user routine + +C functions called: FD15AD + DOUBLE PRECISION FD15AD + EXTERNAL FD15AD + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER I + DOUBLE PRECISION ZERO, TENTH, TWO + PARAMETER (TENTH = 0.1D0, TWO = 2.0D0, ZERO = 0.0D0) + +C i: loop index + +C======================================================================= +C EXECUTABLE STATMENTS: +C======================================================================= + +C ---------------------------------------------------------------- +C integer control parameters: +C ---------------------------------------------------------------- + + ICNTL (1) = 6 + ICNTL (2) = 6 + ICNTL (3) = 2 + ICNTL (4) = 1 + ICNTL (5) = 4 + ICNTL (6) = 0 + ICNTL (7) = 16 + ICNTL (8) = 0 + +C Icntl (9 ... 20) is reserved for future releases: + DO 10 I = 9, 20 + ICNTL (I) = 0 +10 CONTINUE + +C ---------------------------------------------------------------- +C double precision control parameters: +C ---------------------------------------------------------------- + + CNTL (1) = TENTH + CNTL (2) = TWO + +C Set machine epsilon by call to FD15. + CNTL (3) = FD15AD('E') + +C Cntl (4 ... 10) is reserved for future releases: + DO 30 I = 4, 10 + CNTL (I) = ZERO +30 CONTINUE + +C ---------------------------------------------------------------- +C integer control parameters in Keep: +C ---------------------------------------------------------------- + +C Keep(6) once held largest integer, now not used. + KEEP (6) = 0 + KEEP (7) = 64 + KEEP (8) = 1 + +C Keep (9 ... 20) is reserved for future releases: + DO 20 I = 9, 20 + KEEP (I) = 0 +20 CONTINUE + + RETURN + END + + SUBROUTINE MA38AD (N, NE, JOB, TRANSA, LVALUE, LINDEX, VALUE, + * INDEX, KEEP, CNTL, ICNTL, INFO, RINFO) + INTEGER N, NE, JOB + LOGICAL TRANSA + INTEGER LVALUE, LINDEX + DOUBLE PRECISION VALUE(LVALUE) + INTEGER INDEX(LINDEX), KEEP(20) + DOUBLE PRECISION CNTL(10) + INTEGER ICNTL(20), INFO(40) + DOUBLE PRECISION RINFO(20) + +C=== MA38AD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Given a sparse matrix A, find a sparsity-preserving and numerically- +C acceptable pivot order and compute the LU factors, PAQ = LU. The +C matrix is optionally preordered into a block upper triangular form +C (BTF). Pivoting is performed within each diagonal block to maintain +C sparsity and numerical stability. The method used to factorize the +C matrix is an unsymmetric-pattern variant of the multifrontal method. +C Most of the floating-point work is done in the Level-3 BLAS (dense +C matrix multiply). In addition, approximate degrees are used in the +C Markowitz-style pivot search to reduce the symbolic overhead. For +C best performance, be sure to use an optimized BLAS library. +C +C This routine is normally preceded by a call to MA38ID, to +C initialize the default control parameters. MA38ID need only be +C called once. A call to MA38AD can be followed by any number of +C calls to MA38CD, which solves a linear system using the LU factors +C computed by this routine. A call to MA38AD can also be followed by +C any number of calls to MA38BD, which factorizes another matrix with +C the same nonzero pattern as the matrix factorized by MA38AD (but with +C different numerical values). +C +C For more information, see T. A. Davis and I. S. Duff, "An +C unsymmetric-pattern multifrontal method for sparse LU factorization", +C SIAM J. Matrix Analysis and Applications (to appear), also +C technical report TR-94-038, CISE Dept., Univ. of Florida, +C P.O. Box 116120, Gainesville, FL 32611-6120, USA. The method used +C here is a modification of that method, described in T. A. Davis, +C "A combined unifrontal/multifrontal method for unsymmetric sparse +C matrices," TR-94-005. (Technical reports are available via WWW at +C http://www.cis.ufl.edu/). The appoximate degree update algorithm +C used here has been incorporated into an approximate minimum degree +C ordering algorithm, desribed in P. Amestoy, T. A. Davis, and I. S. +C Duff, "An approximate minimum degree ordering algorithm", SIAM J. +C Matrix Analysis and Applications (to appear, also TR-94-039). The +C approximate minimum degree ordering algorithm is implemented as MC47 +C in the Harwell Subroutine Library (MC47 is not called by +C MA38). + +C======================================================================= +C INSTALLATION NOTE: +C======================================================================= +C +C Requires the BLAS (Basic Linear Algebra Subprograms). Ideally, you +C should use vendor-optimized BLAS for your computer. If you do not +C have them, you may obtain the Fortran BLAS from NETLIB. Send email +C to netlib@ornl.gov with the two-line message: +C send index from blas +C send blas.shar from blas +C +C To permamently disable any diagnostic and/or error printing, see +C the "INSTALLATION NOTE:" comments in MA38YD and MA38ZD. +C +C To change the default control parameters, see the +C "INSTALLATION NOTE:" comments in MA38ID. + +C======================================================================= +C ARGUMENTS: +C======================================================================= + +C ------------------------------------------------------------ +C n: An integer variable. +C Must be set by caller on input (not modified). +C Order of the matrix. + +C ------------------------------------------------------------ +C ne: An integer variable. +C Must be set by caller on input (not modified). +C Number of entries in input matrix. Restriction: ne => 1. + +C ------------------------------------------------------------ +C job: An integer variable. +C Must be set by caller on input (not modified). +C If job=1, then a column-oriented form of the input matrix +C is preserved, otherwise, the input matrix is overwritten +C with its LU factors. If iterative refinement is to done +C in MA38CD, (Icntl (8) > 0), then job must be set to 1. + +C ------------------------------------------------------------ +C transa: A logical variable. +C Must be set by caller on input (not modified). +C If false then A is factorized: PAQ = LU. Otherwise, A +C transpose is factorized: PA'Q = LU. + +C ------------------------------------------------------------ +C lvalue: An integer variable. +C Must be set by caller on input (not modified). +C Size of the Value array. Restriction: lvalue >= 2*ne +C is required to convert the input form of the matrix into +C the internal represenation. lvalue >= ne + axcopy is +C required to start the factorization, where axcopy = ne if +C job = 1, or axcopy = 0 otherwise. During factorization, +C additional memory is required to hold the frontal matrices. +C The internal representation of the matrix is overwritten +C with the LU factors, of size (Keep (2) - Keep (1) + 1 +C + axcopy), on output. + +C ------------------------------------------------------------ +C lindex: An integer variable. +C Must be set by caller on input (not modified). +C Size of the Index array. Restriction: lindex >= 3*ne+2*n+1, +C is required to convert the input form of the matrix into +C its internal representation. lindex >= wlen + alen + acopy +C is required to start the factorization, where +C wlen <= 11*n + 3*dn + 8 is the size of the workspaces, +C dn <= n is the number of columns with more than d +C entries (d = max (64, sqrt (n)) is the default), +C alen <= 2*ne + 11*n + 11*dn + dne is the size of the +C internal representation of the matrix, dne <= ne is the +C number of entries in such columns with more than d entries, +C and acopy = ne+n+1 if job = 1, or acopy = 0 otherwize. +C During factorization, the internal representation of size +C alen is overwritten with the LU factors, of size +C luilen = (Keep (5) - Keep (3) + 1 - acopy) on output. +C Additional memory is also required to hold the unsymmetric +C quotient graph, but this also overwrites the input matrix. +C Usually about 7*n additional space is adequate for this +C purpose. Just prior to the end of factorization, +C lindex >= wlen + luilen + acopy is required. + +C ------------------------------------------------------------ +C Value: A double precision array of size lvalue. +C Must be set by caller on input. Modified on output. On +C input, Value (1..ne) holds the original matrix in triplet +C form. On output, Value holds the LU factors, and +C (optionally) a column-oriented form of the original matrix +C - otherwise the input matrix is overwritten with the LU +C factors. + +C ------------------------------------------------------------ +C Index: An integer array of size lindex. +C Must be set by caller on input. Modified on output. On +C input, Index (1..2*ne) holds the original matrix in triplet +C form. On output, Index holds the LU factors, and +C (optionally) a column-oriented form of the original matrix +C - otherwise the input matrix is overwritten with the LU +C factors. +C +C On input the kth triplet (for k = 1...ne) is stored as: +C A (row,col) = Value (k) +C row = Index (k) +C col = Index (k+ne) +C If there is more than one entry for a particular position, +C the values are accumulated, and the number of such duplicate +C entries is returned in Info (2), and a warning flag is +C set. However, applications such as finite element methods +C naturally generate duplicate entries which are then +C assembled (added) together. If this is the case, then +C ignore the warning message. +C +C On output, the LU factors and the column-oriented form +C of A (if preserved) are stored in: +C Value (Keep (1)...Keep (2)) +C Index (Keep (3)...Keep (5)) +C where Keep (2) = lvalue, and Keep (5) = lindex. + +C ------------------------------------------------------------ +C Keep: An integer array of size 20. +C +C Keep (1 ... 5): Need not be set by caller on input. +C Modified on output. +C Keep (1): LU factors start here in Value +C Keep (2) = lvalue: LU factors end here in Value +C Keep (3): LU factors start here in Index +C Keep (4): LU factors needed for MA38BD start here +C in Index +C Keep (5) = lindex: LU factors end here in Index +C +C Keep (6 ... 8): Must be set by caller on input (not +C modified). +C integer control arguments not normally modified by the +C user. See MA38ID for details, which sets the defaults. +C Keep (6) was the largest representable positive +C integer but is set to zero and is no longer used. +C Keep (7) and Keep (8) determine the +C size of d, where columns with more than d original +C entries are treated as a priori frontal matrices. +C +C Keep (9 ... 20): Unused. Reserved for future releases. + +C ------------------------------------------------------------ +C Cntl: A double precision array of size 10. +C Must be set by caller on input (not modified). +C real control arguments, see MA38ID for a description, +C which sets the defaults. MA38AD uses Cntl (1) and Cntl (2). + +C ------------------------------------------------------------ +C Icntl: An integer array of size 20. +C Must be set by caller on input (not modified). +C Integer control arguments, see MA38ID for a description, +C which sets the defaults. MA38AD uses Icntl (1..7). + +C ------------------------------------------------------------ +C Info: An integer array of size 40. +C Need not be set by caller on input. Modified on output. +C It contains information about the execution of MA38AD. +C +C Info (1): zero if no error occurred, negative if +C an error occurred and the factorization was not +C completed, positive if a warning occurred (the +C factorization was completed). +C +C These errors cause the factorization to terminate: +C +C Error Description +C -1 n < 1 or n > maximum value +C -2 ne < 1 or ne > maximum value +C -3 lindex too small +C -4 lvalue too small +C -5 both lindex and lvalue are too small +C +C With these warnings the factorization was able to +C complete: +C +C Error Description +C 1 invalid entries +C 2 duplicate entries +C 3 invalid and duplicate entries +C 4 singular matrix +C 5 invalid entries, singular matrix +C 6 duplicate entries, singular matrix +C 7 invalid and duplicate entries, singular matrix +C +C Subsequent calls to MA38BD and MA38CD can only be made +C if Info (1) is zero or positive. If Info (1) +C is negative, then some or all of the remaining +C Info and Rinfo arrays may not be valid. +C +C Info (2): duplicate entries in A. A warning is set +C if Info (2) > 0. However, the duplicate entries +C are summed and the factorization continues. Duplicate +C entries are sometimes intentional - for finite element +C codes, for example. +C +C Info (3): invalid entries in A, indices not in 1..n. +C These entries are ignored and a warning is set +C in Info (1). +C +C Info (4): zero. Used by MA38BD only. +C +C Info (5): entries in A after adding duplicates and +C removing invalid entries. +C +C Info (6): entries in diagonal blocks of A. +C +C Info (7): entries in off-diagonal blocks of A. Zero +C if Info (9) = 1. +C +C Info (8): 1-by-1 diagonal blocks. +C +C Info (9): blocks in block-triangular form. +C +C Info (10): entries below diagonal in L. +C +C Info (11): entries below diagonal in U. +C +C Info (12): entries in L+U+offdiagonal part. +C +C Info (13): frontal matrices. +C +C Info (14): garbage collections performed on Index, when +C memory is exhausted. Garbage collections are performed +C to remove external fragmentation. If Info (14) is +C excessively high, performance can be degraded. Try +C increasing lindex if that occurs. Note that external +C fragmentation in *both* Index and Value is removed when +C either is exhausted. +C +C Info (15): garbage collections performed on Value. +C +C Info (16): diagonal pivots chosen. +C +C Info (17): numerically acceptable pivots found in A. +C If less than n, then A is singular (or nearly so). +C The factorization still proceeds, and MA38CD can still +C be called. The zero-rank active submatrix of order +C n - Info (17) is replaced with the identity matrix +C (assuming BTF is not in use). If BTF is in use, then +C one or more of the diagonal blocks are singular. +C +C Info (18): memory used in Index. +C +C Info (19): minimum memory needed in Index +C (or minimum recommended). If lindex is set to +C Info (19) on a subsequent call, then a moderate +C number of garbage collections (Info (14)) will +C occur. +C +C Info (20): memory used in Value. +C +C Info (21): minimum memory needed in Value +C (or minimum recommended). If lvalue is set to +C Info (21) on a subsequent call, then a moderate +C number of garbage collections (Info (15)) will +C occur. +C +C Info (22): memory needed in Index for the next call to +C MA38BD. +C +C Info (23): memory needed in Value for the next call to +C MA38BD. +C +C Info (24): zero. Used by MA38CD only. +C +C Info (25 ... 40): reserved for future releases + +C ------------------------------------------------------------ +C Rinfo: A double precision array of size 20. +C Need not be set by caller on input. Modified on output. +C It contains information about the execution of MA38AD. +C +C Rinfo (1): total flop count in the BLAS +C +C Rinfo (2): total assembly flop count +C +C Rinfo (3): total flops during pivot search +C +C Rinfo (4): Level-1 BLAS flops +C +C Rinfo (5): Level-2 BLAS flops +C +C Rinfo (6): Level-3 BLAS flops +C +C Rinfo (7): zero. Used by MA38CD only. +C +C Rinfo (8): zero. Used by MA38CD only. +C +C Rinfo (9 ... 20): reserved for future releases + +C======================================================================= +C TO BE PRESERVED BETWEEN CALLS TO MA38AD, MA38BD, MA38CD: +C======================================================================= +C +C When calling MA38CD to solve a linear system using the factors +C computed by MA38AD or MA38BD, the following must be preserved: +C +C n +C Value (Keep (1)...Keep (2)) +C Index (Keep (3)...Keep (5)) +C Keep (1 ... 20) +C +C When calling MA38BD to factorize a subsequent matrix with a pattern +C similar to that factorized by MA38AD, the following must be +C preserved: +C +C n +C Index (Keep (4)...Keep (5)) +C Keep (4 ... 20) +C +C Note that the user may move the LU factors to a different position +C in Value and/or Index, as long as Keep (1 ... 5) are modified +C correspondingly. + +C## End of user documentation for MA38AD ############################### + +C======================================================================= +C CODING CONVENTIONS: +C======================================================================= +C +C This package is written in ANSI Fortran 77. To make the code more +C understandable, the following coding conventions are followed for all +C routines in this package: +C +C 1) Large code blocks are delimited with [...] comments. +C +C 2) GOTO usage: +C a) Goto's used to return if an error condition is found are +C written as "GO TO 9000" or "GO TO 9010". +C b) Goto's used to exit loops prematurely are written as "GO TO", +C and have a target label of 2000 or less. +C c) Goto's used to jump to the next iteration of a do loop or +C while loop (or to implement a while loop) are written as +C "GOTO". +C No other goto's are used in this package. +C +C This package uses the following CRAY compiler directives to help +C in the vectorization of loops. Each of them operate on the +C do-loop immediately following the directive. Other compilers +C normally treat these directives as ordinary comments. +C +C CFPP$ NODEPCHK L disables data dependency check, and +C asserts that no recursion exists. +C CFPP$ NOLSTVAL L disables the saving of last values of +C transformed scalars (indexes or promoted +C scalars, especially those in array +C subscripts). Asserts that values do not +C need to be the same as in the scalar +C version (for later use of the scalars). +C CDIR$ SHORTLOOP asserts that the loop count is always +C 64 or less. + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: user routine +C subroutines called: MA38ND, MA38YD, MA38KD, MA38DD +C functions called: MAX, MIN + INTRINSIC MAX, MIN + EXTERNAL MA38DD, MA38KD, MA38ND, MA38YD + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER I, NZ, LUX1, LUI1, IUSE, XUSE, LUIR1, NZOFF, NBLKS + LOGICAL PRESRV + DOUBLE PRECISION + $ ZERO + PARAMETER (ZERO = 0.0D0) + +C Location of LU factors: +C ----------------------- +C lux1: real part of LU factors placed in Value (lux1 ... lvalue) +C lui1: integer part of LU factors placed in Index (lui1 ... lindex) +C luir1: Index (luir1 ... lindex) must be preserved for MA38BD +C +C Memory usage: +C ------------- +C iuse: current memory usage in Index +C xuse: current memory usage in Value +C +C Matrix to factorize: +C -------------------- +C nblks: number of diagonal blocks (1 if BTF not used) +C nzoff: entries in off-diagonal part (0 if BTF not used) +C nz: entries in matrix after removing invalid/duplicate entries +C +C Other: +C ------ +C nmax: largest permissible value of n +C i: general loop index +C presrv: true if original matrix to be preserved + +C======================================================================= +C EXECUTABLE STATEMENTS: +C======================================================================= + +C----------------------------------------------------------------------- +C clear informational output, and Keep array (except Keep (6..8)): +C----------------------------------------------------------------------- + + DO 10 I = 1, 40 + INFO (I) = 0 +10 CONTINUE + DO 20 I = 1, 20 + RINFO (I) = ZERO +20 CONTINUE + KEEP (1) = 0 + KEEP (2) = 0 + KEEP (3) = 0 + KEEP (4) = 0 + KEEP (5) = 0 + +C----------------------------------------------------------------------- +C print input arguments if requested +C----------------------------------------------------------------------- + + CALL MA38YD (1, 1, + $ N, NE, JOB, TRANSA, LVALUE, LINDEX, VALUE, + $ INDEX, KEEP, CNTL, ICNTL, INFO, RINFO, + $ RINFO(1), RINFO(1), 1, RINFO(1), 1) + +C----------------------------------------------------------------------- +C initialize and check inputs +C----------------------------------------------------------------------- + + IUSE = 0 + XUSE = 0 + INFO (5) = NE + INFO (6) = NE + IF (N .LT. 1) THEN +C n is too small + CALL MA38ND (1, ICNTL, INFO, -1, -1) + GO TO 9000 + ENDIF + IF (NE .LT. 1) THEN +C ne is too small + CALL MA38ND (1, ICNTL, INFO, -2, -1) + GO TO 9000 + ENDIF + +C----------------------------------------------------------------------- +C get memory for conversion to column form +C----------------------------------------------------------------------- + + NZ = NE + IUSE = 2*N+1 + MAX (2*NZ, N+1) + NZ + XUSE = 2*NZ + INFO (18) = IUSE + INFO (20) = XUSE + INFO (19) = IUSE + INFO (21) = XUSE + IF (LINDEX .LT. IUSE) THEN +C set error flag if out of integer memory: + CALL MA38ND (1, ICNTL, INFO, -3, IUSE) + ENDIF + IF (LVALUE .LT. XUSE) THEN +C set error flag if out of real memory: + CALL MA38ND (1, ICNTL, INFO, -4, XUSE) + ENDIF + IF (INFO (1) .LT. 0) THEN +C error return, if not enough integer and/or real memory: + GO TO 9000 + ENDIF + +C----------------------------------------------------------------------- +C convert to column-oriented form and remove duplicates +C----------------------------------------------------------------------- + + CALL MA38KD (N, NZ, TRANSA, VALUE, LVALUE, INFO, ICNTL, + $ INDEX, LINDEX-(2*N+1), INDEX(LINDEX-2*N), INDEX(LINDEX-N), 1) + IF (INFO (1) .LT. 0) THEN +C error return, if all entries invalid (nz is now 0): + GO TO 9000 + ENDIF + +C----------------------------------------------------------------------- +C current memory usage: +C----------------------------------------------------------------------- + +C Index (1..n+1): column pointers. input matrix is now in +C Index (1..nz+n+1) and Value (1..nz) +C col pattern: Index (n+1+ Index (col) ... n+1+ Index (col+1)) +C col values: Value ( Index (col) ... Index (col+1)) +C at this point, nz <= ne (nz = ne if there are no invalid or +C duplicate entries; nz < ne otherwise). + + IUSE = NZ + (N+1) + XUSE = NZ + +C----------------------------------------------------------------------- +C factorize +C----------------------------------------------------------------------- + + PRESRV = JOB .EQ. 1 + IF (PRESRV) THEN + +C ------------------------------------------------------------- +C keep a copy of the original matrix in column-oriented form +C ------------------------------------------------------------- + +C copy column pointers (Cp (1..n+1) = Ap (1..n+1)) + IUSE = IUSE + (N+1) +CFPP$ NODEPCHK L + DO 30 I = 1, N+1 + INDEX (NZ+N+1+I) = INDEX (I) +30 CONTINUE + + CALL MA38DD (N, NZ, INDEX (NZ+N+2), + $ VALUE (NZ+1), LVALUE-NZ, + $ INDEX (NZ+2*N+3), LINDEX-(NZ+2*N+2), + $ LUX1, LUI1, IUSE, XUSE, NZOFF, NBLKS, + $ ICNTL, CNTL, INFO, RINFO, + $ PRESRV, INDEX, INDEX (N+2), VALUE, N, NZ, KEEP, NE) + IF (INFO (1) .LT. 0) THEN +C error return, if MA38DD fails + GO TO 9000 + ENDIF +C adjust pointers to reflect Index/Value, not II/XX: + LUX1 = LUX1 + NZ + LUI1 = LUI1 + (NZ+2*N+2) + +C move preserved copy of A to permanent place + LUX1 = LUX1 - NZ + LUI1 = LUI1 - (NZ+N+1) + DO 40 I = NZ+N+1, 1, -1 + INDEX (LUI1+I-1) = INDEX (I) +40 CONTINUE + DO 50 I = NZ, 1, -1 + VALUE (LUX1+I-1) = VALUE (I) +50 CONTINUE + + ELSE + +C ------------------------------------------------------------- +C do not preserve the original matrix +C ------------------------------------------------------------- + + CALL MA38DD (N, NZ, INDEX, + $ VALUE, LVALUE, + $ INDEX (N+2), LINDEX-(N+1), + $ LUX1, LUI1, IUSE, XUSE, NZOFF, NBLKS, + $ ICNTL, CNTL, INFO, RINFO, + $ PRESRV, INDEX, INDEX, VALUE, 0, 1, KEEP, NE) + IF (INFO (1) .LT. 0) THEN +C error return, if MA38DD fails + GO TO 9000 + ENDIF +C adjust pointers to reflect Index/Value, not II/XX: + LUI1 = LUI1 + (N+1) + ENDIF + +C----------------------------------------------------------------------- +C wrap-up +C----------------------------------------------------------------------- + + IF (TRANSA) THEN + INDEX (LINDEX-6) = 1 + ELSE + INDEX (LINDEX-6) = 0 + ENDIF + INDEX (LINDEX-5) = NZOFF + INDEX (LINDEX-4) = NBLKS + IF (PRESRV) THEN + INDEX (LINDEX-3) = 1 + ELSE + INDEX (LINDEX-3) = 0 + ENDIF + INDEX (LINDEX-2) = NZ + INDEX (LINDEX-1) = N + INDEX (LINDEX) = NE + +C do not need preserved matrix (n+1+nz), or off-diagonal entries +C (nzoff) for MA38BD: + LUIR1 = LUI1 + IF (PRESRV) THEN +C do not need preserved matrix for MA38BD + LUIR1 = LUIR1 + N+1 + NZ + ENDIF + IF (NBLKS .GT. 1) THEN +C do not need off-diagonal part for MA38BD + LUIR1 = LUIR1 + NZOFF + ENDIF + +C save location of LU factors + KEEP (1) = LUX1 + KEEP (2) = LVALUE + KEEP (3) = LUI1 + KEEP (4) = LUIR1 + KEEP (5) = LINDEX + +C update memory usage information + IUSE = LINDEX - LUI1 + 1 + XUSE = LVALUE - LUX1 + 1 + INFO (22) = INFO (22) + (LINDEX - LUIR1 + 1) + +C----------------------------------------------------------------------- +C print the output arguments if requested, and return +C----------------------------------------------------------------------- + +C error return label: +9000 CONTINUE + IF (INFO (1) .LT. 0) THEN + KEEP (1) = 0 + KEEP (2) = 0 + KEEP (3) = 0 + KEEP (4) = 0 + KEEP (5) = 0 + ENDIF + + INFO (18) = MIN (LINDEX, MAX (INFO (18), IUSE)) + INFO (20) = MIN (LVALUE, MAX (INFO (20), XUSE)) + + CALL MA38YD (1, 2, + $ N, NE, JOB, TRANSA, LVALUE, LINDEX, VALUE, + $ INDEX, KEEP, CNTL, ICNTL, INFO, RINFO, + $ RINFO(1), RINFO(1), 1, RINFO(1), 1) + RETURN + END + + SUBROUTINE MA38BD (N, NE, JOB, TRANSA, LVALUE, LINDEX, VALUE, + * INDEX, KEEP, CNTL, ICNTL, INFO, RINFO) + INTEGER N, NE, JOB + LOGICAL TRANSA + INTEGER LVALUE, LINDEX + DOUBLE PRECISION VALUE(LVALUE) + INTEGER INDEX(LINDEX), KEEP(20) + DOUBLE PRECISION CNTL(10) + INTEGER ICNTL(20), INFO(40) + DOUBLE PRECISION RINFO(20) + +C=== MA38BD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Given a sparse matrix A, and a sparsity-preserving and numerically- +C acceptable pivot order and symbolic factorization, compute the LU +C factors, PAQ = LU. Uses the sparsity pattern and permutations from +C a prior factorization by MA38AD or MA38BD. The matrix A should have +C the same nonzero pattern as the matrix factorized by MA38AD or +C MA38BD. The matrix can have different numerical values. No +C variations are made in the pivot order computed by MA38AD. If a +C zero pivot is encountered, an error flag is set and the +C factorization terminates. +C +C This routine can actually handle any matrix A such that (PAQ)_ij can +C be nonzero only if (LU)_ij is be nonzero, where L and U are the LU +C factors of the matrix factorized by MA38AD. If BTF (block triangular +C form) is used, entries above the diagonal blocks of (PAQ)_ij can have +C an arbitrary sparsity pattern. Entries for which (LU)_ij is not +C present, or those below the diagonal blocks are invalid and ignored +C (a warning flag is set and the factorization proceeds without the +C invalid entries). A listing of the invalid entries can be printed. +C +C This routine must be preceded by a call to MA38AD or MA38BD. +C A call to MA38BD can be followed by any number of calls to MA38CD, +C which solves a linear system using the LU factors computed by this +C routine or by MA38AD. A call to MA38BD can also be followed by any +C number of calls to MA38BD. + +C======================================================================= +C ARGUMENTS: +C======================================================================= + +C ------------------------------------------------------------ +C n: An integer variable. +C Must be set by caller on input (not modified). +C Order of the matrix. Must be identical to the value of n +C in the last call to MA38AD. + +C ------------------------------------------------------------ +C ne: An integer variable. +C Must be set by caller on input (not modified). +C Number of entries in input matrix. Normally not modified +C since the last call to MA38AD. +C Restriction: 1 <= ne < (Keep (4)) / 2 + +C ------------------------------------------------------------ +C job: An integer variable. +C Must be set by caller on input (not modified). +C If job=1, then a column-oriented form of the input matrix +C is preserved, otherwise, the input matrix is overwritten +C with its LU factors. If iterative refinement is to done +C (Icntl (8) > 0), then job must be set to 1. Can be +C the same, or different, as the last call to MA38AD. + +C ------------------------------------------------------------ +C transa: A logical variable. +C Must be set by caller on input (not modified). +C If false then A is factorized: PAQ = LU. Otherwise, A +C transpose is factorized: PA'Q = LU. Normally the same as +C the last call to MA38AD. + +C ------------------------------------------------------------ +C lvalue: An integer variable. +C Must be set by caller on input (not modified). +C Size of the Value array. Restriction: lvalue >= 2*ne, +C although a larger will typically be required to complete +C the factorization. The exact value required is computed +C by the last call to MA38AD or MA38BD (Info (23)). +C This value assumes that the ne, job, and transa parameters +C are the same as the last call. Some garbage collection may +C occur if lvalue is set to Info (23), but usually not +C much. We recommend lvalue => 1.2 * Info (23). The +C lvalue parameter is usually the same as in the last call to +C MA38AD, however. + +C ------------------------------------------------------------ +C lindex: An integer variable. +C Must be set by caller on input (not modified). +C Size of the Index array. Restriction: +C lindex >= 3*ne+2*n+1 + (Keep (5) - Keep (4) + 1), +C although a larger will typically be required to complete +C the factorization. The exact value required is computed +C by the last call to MA38AD or MA38BD (Info (22)). +C This value assumes that the ne, job, and transa parameters +C are the same as the last call. No garbage collection ever +C occurs in the Index array, since MA38BD does not create +C external fragmentation in Index. The lindex parameter is +C usually the same as in the last call to MA38AD, however. +C Note that lindex >= Keep (5) is also required, since +C the pattern of the prior LU factors reside in +C Index (Keep (4) ... Keep (5)). + +C ------------------------------------------------------------ +C Value: A double precision array of size lvalue. +C Must be set by caller on input (normally from the last call +C to MA38AD or MA38BD). Modified on output. On input, +C Value (1..ne) holds the original matrix in triplet form. +C On output, Value holds the LU factors, and (optionally) a +C column-oriented form of the original matrix - otherwise +C the input matrix is overwritten with the LU factors. + +C ------------------------------------------------------------ +C Index: An integer array of size lindex. +C Must be set by caller on input (normally from the last call +C to MA38AD or MA38BD). Modified on output. On input, +C Index (1..2*ne) holds the original matrix in triplet form, +C and Index (Keep (4) ... Keep (5)) holds the pattern +C of the prior LU factors. On output, Index holds the LU +C factors, and (optionally) a column-oriented form of the +C original matrix - otherwise the input matrix is overwritten +C with the LU factors. +C +C On input the kth triplet (for k = 1...ne) is stored as: +C A (row,col) = Value (k) +C row = Index (k) +C col = Index (k+ne) +C If there is more than one entry for a particular position, +C the values are accumulated, and the number of such duplicate +C entries is returned in Info (2), and a warning flag is +C set. However, applications such as finite element methods +C naturally generate duplicate entries which are then +C assembled (added) together. If this is the case, then +C ignore the warning message. +C +C On input, and the pattern of the prior LU factors is in +C Index (Keep (4) ... Keep (5)) +C +C On output, the LU factors and the column-oriented form +C of A (if preserved) are stored in: +C Value (Keep (1)...Keep (2)) +C Index (Keep (3)...Keep (5)) +C where Keep (2) = lvalue, and Keep (5) = lindex. + +C ------------------------------------------------------------ +C Keep: An integer array of size 20. +C +C Keep (1 ... 3): Need not be set by caller on input. +C Modified on output. +C Keep (1): new LU factors start here in Value +C Keep (2) = lvalue: new LU factors end here in Value +C Keep (3): new LU factors start here in Index +C +C Keep (4 ... 5): Must be set by caller on input (normally +C from the last call to MA38AD or MA38BD). Modified on +C output. +C Keep (4): On input, the prior LU factors start here +C in Index, not including the prior (optionally) preserved +C input matrix, nor the off-diagonal pattern (if BTF was +C used in the last call to MA38AD). On output, the new +C LU factors needed for MA38BD start here in Index. +C Keep (5): On input, the prior LU factors end here in +C Index. On output, Keep (5) is set to lindex, which +C is where the new LU factors end in Index +C +C Keep (6 ... 8): Unused. These are used by MA38AD only. +C Future releases may make use of them, however. +C +C Keep (9 ... 20): Unused. Reserved for future releases. + +C ------------------------------------------------------------ +C Cntl: A double precision array of size 10. +C Must be set by caller on input (not modified). +C double precision control arguments, see MA38ID for a +C description, which sets the default values. The current +C version of MA38BD does not actually use Cntl. It is +C included to make the argument list of MA38BD the same as +C MA38AD. MA38BD may use Cntl in future releases. + +C ------------------------------------------------------------ +C Icntl: An integer array of size 20. +C Must be set by caller on input (not modified). +C Integer control arguments, see MA38ID for a description, +C which sets the default values. MA38BD uses Icntl (1), +C Icntl (2), Icntl (3), and Icntl (7). + +C ------------------------------------------------------------ +C Info: An integer array of size 40. +C Need not be set by caller on input. Modified on output. +C It contains information about the execution of MA38BD. +C +C Info (1): zero if no error occurred, negative if +C an error occurred and the factorization was not +C completed, positive if a warning occurred (the +C factorization was completed). +C +C These errors cause the factorization to terminate: +C +C Error Description +C -1 n < 1 or n > maximum value +C -2 ne < 1 or ne > maximum value +C -3 lindex too small +C -4 lvalue too small +C -5 both lindex and lvalue are too small +C -6 prior pivot ordering no longer acceptable +C -7 LU factors are uncomputed, or are corrupted +C +C With these warnings the factorization was able to +C complete: +C +C Error Description +C 1 invalid entries +C 2 duplicate entries +C 3 invalid and duplicate entries +C 4 singular matrix +C 5 invalid entries, singular matrix +C 6 duplicate entries, singular matrix +C 7 invalid and duplicate entries, singular matrix +C +C Subsequent calls to MA38BD and MA38CD can only be made +C if Info (1) is zero or positive. If Info (1) +C is negative, then some or all of the remaining +C Info and Rinfo arrays may not be valid. +C +C Info (2): duplicate entries in A. A warning is set +C if Info (2) > 0. However, the duplicate entries +C are summed and the factorization continues. Duplicate +C entries are sometimes intentional - for finite element +C codes, for example. +C +C Info (3): invalid entries in A, indices not in 1..n. +C These entries are ignored and a warning is set in +C Info (1). +C +C Info (4): invalid entries in A, not in prior LU +C factors. These entries are ignored and a warning is +C set in Info (1). +C +C Info (5): entries in A after adding duplicates and +C removing invalid entries. +C +C Info (6): entries in diagonal blocks of A. +C +C Info (7): entries in off-diagonal blocks of A. Zero +C if Info (9) = 1. +C +C Info (8): 1-by-1 diagonal blocks. +C +C Info (9): blocks in block-triangular form. +C +C Info (10): entries below diagonal in L. +C +C Info (11): entries below diagonal in U. +C +C Info (12): entries in L+U+offdiagonal part. +C +C Info (13): frontal matrices. +C +C Info (14): zero. Used by MA38AD only. +C +C Info (15): garbage collections performed on Value. +C +C Info (16): diagonal pivots chosen. +C +C Info (17): numerically acceptable pivots found in A. +C If less than n, then A is singular (or nearly so). +C The factorization still proceeds, and MA38CD can still +C be called. The zero-rank active submatrix of order +C n - Info (17) is replaced with the identity matrix +C (assuming BTF is not in use). If BTF is in use, then +C one or more of the diagonal blocks are singular. +C MA38BD can be called if the value of Info (17) +C returned by MA38AD was less than n, but the order +C (n - Info (17)) active submatrix is still replaced +C with the identity matrix. Entries residing in this +C submatrix are ignored, their number is included in +C Info (4), and a warning is set in Info (1). +C +C Info (18): memory used in Index. +C +C Info (19): memory needed in Index (same as Info (18)). +C +C Info (20): memory used in Value. +C +C Info (21): minimum memory needed in Value +C (or minimum recommended). If lvalue is set to +C Info (21) on a subsequent call, then a moderate +C number of garbage collections (Info (15)) will +C occur. +C +C Info (22): memory needed in Index for the next call to +C MA38BD. +C +C Info (23): memory needed in Value for the next call to +C MA38BD. +C +C Info (24): zero. Used by MA38CD only. +C +C Info (25 ... 40): reserved for future releases + +C ------------------------------------------------------------ +C Rinfo: A double precision array of size 20. +C Need not be set by caller on input. Modified on output. +C It contains information about the execution of MA38BD. +C +C Rinfo (1): total flop count in the BLAS +C +C Rinfo (2): total assembly flop count +C +C Rinfo (3): zero. Used by MA38AD only. +C +C Rinfo (4): Level-1 BLAS flops +C +C Rinfo (5): Level-2 BLAS flops +C +C Rinfo (6): Level-3 BLAS flops +C +C Rinfo (7): zero. Used by MA38CD only. +C +C Rinfo (8): zero. Used by MA38CD only. +C +C Rinfo (9 ... 20): reserved for future releases + +C======================================================================= +C TO BE PRESERVED BETWEEN CALLS TO MA38AD, MA38BD, MA38CD: +C======================================================================= +C +C When calling MA38CD to solve a linear system using the factors +C computed by MA38AD or MA38BD, the following must be preserved: +C +C n +C Value (Keep (1)...Keep (2)) +C Index (Keep (3)...Keep (5)) +C Keep (1 ... 20) +C +C When calling MA38BD to factorize a subsequent matrix with a pattern +C similar to that factorized by MA38AD, the following must be +C preserved: +C +C n +C Index (Keep (4)...Keep (5)) +C Keep (4 ... 20) +C +C Note that the user may move the LU factors to a different position +C in Value and/or Index, as long as Keep (1 ... 5) are modified +C correspondingly. + +C## End of user documentation for MA38BD ############################### + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: user routine +C subroutines called: MA38ND, MA38YD, MA38KD, MA38PD +C functions called: MAX, MIN + INTRINSIC MAX, MIN + EXTERNAL MA38KD, MA38ND, MA38PD, MA38YD + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER I, NZ, LUX1, LUI1, IUSE, XUSE, N1, NZ1, NBLKS, + $ LIND2, LUIR1, LUSIZ, LUI2, RPERMP, CPERMP, + $ OFFPP, LUBLPP, BLKPP, ON, NZOFF, IP2, IO, PRL + LOGICAL PRESRV, BADLU + DOUBLE PRECISION + $ ZERO + PARAMETER (ZERO = 0.0D0) + +C Printing control: +C ----------------- +C io: I/O unit for diagnostic messages +C prl: printing level +C +C Matrix to factorize: +C -------------------- +C nz: number of entries, after removing invalid/duplicate entries +C presrv: true if original matrix to be preserved +C +C Memory usage: +C ------------- +C iuse: current memory usage in Index +C xuse: current memory usage in Value +C lind2: allocatable part of Index is (1..lind2) +C +C Location and status of LU factors: +C ---------------------------------- +C lui1: integer part of LU factors start in Index (lui1...) +C luir1: Index (luir1 ... lui2) is needed for this call to MA38BD +C lusiz: size of Index (luir1..lui2), needed from prior LU factors +C lui2: integer part of LU factors end in Index (..lui2) +C lux1: real part of LU factors in Value (lux1...lvalue) +C ip2: pointer into trailing part of LU factors in Index +C badlu: if true, then LU factors are corrupted or not computed +C +C Arrays and scalars allocated in LU factors (in order): +C ------------------------------------------------------ +C ... LU factors of each diagonal block located here +C lublpp: LUblkp (1..nblks) array in Index (lublpp..lublpp+nblks-1) +C blkpp: Blkp (1..nblks+1) array loc. in Index (blkpp...blkpp+nblks) +C offpp: Offp (1..n+1) array located in Index (offpp...offpp+n) +C on: size of Offp array +C cpermp: Cperm (1..n) array located in Index (cpermp...cpermp+n-1) +C rpermp: Rperm (1..n) array located in Index (rpermp...rpermp+n-1) +C nblks: number of diagonal blocks +C nz1: number of entries when prior matrix factorize +C n1: N argument in MA38AD or MA38BD when prior matrix factorized +C +C Other: +C ------ +C i: loop index + +C======================================================================= +C EXECUTABLE STATEMENTS: +C======================================================================= + + IO = ICNTL (2) + PRL = ICNTL (3) + +C----------------------------------------------------------------------- +C clear informational output, and the unneeded part of the Keep array +C----------------------------------------------------------------------- + + DO 10 I = 1, 40 + INFO (I) = 0 +10 CONTINUE + DO 20 I = 1, 20 + RINFO (I) = ZERO +20 CONTINUE + KEEP (1) = 0 + KEEP (2) = 0 + KEEP (3) = 0 + +C----------------------------------------------------------------------- +C print input arguments if requested +C----------------------------------------------------------------------- + + CALL MA38YD (2, 1, + $ N, NE, JOB, TRANSA, LVALUE, LINDEX, VALUE, + $ INDEX, KEEP, CNTL, ICNTL, INFO, RINFO, + $ RINFO(1), RINFO(1), 1, RINFO(1), 1) + +C----------------------------------------------------------------------- +C check input arguments +C----------------------------------------------------------------------- + + IUSE = 0 + XUSE = 0 + INFO (5) = NE + INFO (6) = NE + IF (N .LT. 1) THEN +C n is too small + CALL MA38ND (2, ICNTL, INFO, -1, -1) + GO TO 9000 + ENDIF + IF (NE .LT. 1) THEN +C ne is too small + CALL MA38ND (2, ICNTL, INFO, -2, -1) + GO TO 9000 + ENDIF + +C----------------------------------------------------------------------- +C get pointers to integer part of prior LU factors +C----------------------------------------------------------------------- + + LUIR1 = KEEP (4) + LUI2 = KEEP (5) + LUSIZ = LUI2 - LUIR1 + 1 + + BADLU = LUIR1 .LE. 0 .OR. LUI2-6 .LT. LUIR1 .OR. LUI2.GT.LINDEX + IF (BADLU) THEN + CALL MA38ND (2, ICNTL, INFO, -7, 0) +C error return, LU factors are corrupted: + GO TO 9000 + ENDIF + IF (2*NE .GT. LUIR1) THEN + CALL MA38ND (2, ICNTL, INFO, -2, LUIR1/2) +C error return, ne is too large: + GO TO 9000 + ENDIF + +C----------------------------------------------------------------------- +C shift the prior LU factors down to the end of Index. If Keep and +C lindex are unmodified from the prior call to MA38AD, then +C Keep (5) = lindex, and this shift is not performed. +C----------------------------------------------------------------------- + + IF (LUI2 .LT. LINDEX) THEN + DO 30 I = LINDEX, LINDEX - LUSIZ + 1, -1 + INDEX (I) = INDEX (I - LINDEX + LUI2) +30 CONTINUE + LUIR1 = LINDEX - LUSIZ + 1 + KEEP (5) = LINDEX + KEEP (4) = LUIR1 + ENDIF + +C----------------------------------------------------------------------- +C get seven scalars (transa, nzoff, nblks, presrv, nz, n, ne) from LU +C----------------------------------------------------------------------- + +C ne1 = Index (lindex), not required for MA38BD + N1 = INDEX (LINDEX-1) + NZ1 = INDEX (LINDEX-2) +C presr1 = Index (lindex-3) .ne. 0, not required for MA38BD + NBLKS = INDEX (LINDEX-4) +C nzoff1 = Index (lindex-5), not required for MA38BD +C trans1 = Index (lindex-6) .ne. 0, not required for MA38BD + +C----------------------------------------------------------------------- +C get pointers to permutation vectors +C----------------------------------------------------------------------- + + RPERMP = (LINDEX-6) - N + CPERMP = RPERMP - N + IP2 = CPERMP - 1 + +C----------------------------------------------------------------------- +C get pointers to block-triangular information, if BTF was used +C----------------------------------------------------------------------- + + IF (NBLKS .GT. 1) THEN + +C ------------------------------------------------------------- +C get pointers to BTF arrays +C ------------------------------------------------------------- + + OFFPP = CPERMP - (N+1) + BLKPP = OFFPP - (NBLKS+1) + LUBLPP = BLKPP - (NBLKS) + IP2 = LUBLPP - 1 + ON = N + + ELSE + +C ------------------------------------------------------------- +C matrix was factorized as a single block, pass dummy arg. +C ------------------------------------------------------------- + + OFFPP = 1 + BLKPP = 1 + LUBLPP = 1 + ON = 0 + + ENDIF + + BADLU = N .NE. N1 .OR. NZ1 .LE. 0 .OR. LUIR1 .GT. IP2 .OR. + $ NBLKS .LE. 0 .OR. NBLKS .GT. N + IF (BADLU) THEN + CALL MA38ND (2, ICNTL, INFO, -7, 0) +C error return, LU factors are corrupted: + GO TO 9000 + ENDIF + +C----------------------------------------------------------------------- +C get memory for conversion to column form +C----------------------------------------------------------------------- + + NZ = NE + IUSE = 2*N+1 + MAX (2*NZ,N+1) + NZ + LUSIZ + XUSE = 2*NZ + INFO (18) = IUSE + INFO (20) = XUSE + INFO (19) = IUSE + INFO (21) = XUSE + INFO (23) = XUSE + LIND2 = LUIR1 - 1 + IF (LINDEX .LT. IUSE) THEN +C set error flag if out of integer memory + CALL MA38ND (2, ICNTL, INFO, -3, IUSE) + ENDIF + IF (LVALUE .LT. XUSE) THEN +C set error flag if out of real memory + CALL MA38ND (2, ICNTL, INFO, -4, XUSE) + ENDIF + IF (INFO (1) .LT. 0) THEN +C error return, if not enough integer and/or real memory + GO TO 9000 + ENDIF + +C----------------------------------------------------------------------- +C convert to column-oriented form and remove duplicates +C----------------------------------------------------------------------- + + CALL MA38KD (N, NZ, TRANSA, VALUE, LVALUE, INFO, ICNTL, + $ INDEX, LIND2-(2*N+1), INDEX (LIND2-2*N), INDEX (LIND2-N), 2) + IF (INFO (1) .LT. 0) THEN +C error return, if all entries are invalid (nz is now 0) + GO TO 9000 + ENDIF + +C----------------------------------------------------------------------- +C current memory usage: +C----------------------------------------------------------------------- + +C Index (1..n+1): column pointers. input matrix is now in +C Index (1..nz+n+1) and Value (1..nz) +C col pattern: Index (n+1+ Index (col) ... n+1+ Index (col+1)) +C col values: Value ( Index (col) ... Index (col+1)) +C at this point, nz <= ne (nz = ne if there are no invalid or +C duplicate entries; nz < ne otherwise). +C Pattern of prior LU factors and BTF arrays are in +C Index (Keep (4) ... Keep (5)) + + IUSE = NZ + (N+1) + LUSIZ + XUSE = NZ + +C----------------------------------------------------------------------- +C refactorize +C----------------------------------------------------------------------- + + PRESRV = JOB .EQ. 1 + IF (PRESRV) THEN + +C ------------------------------------------------------------- +C keep a copy of the original matrix in column-oriented form +C ------------------------------------------------------------- + +C copy column pointers (Cp (1..n+1) = Ap (1..n+1)) + IUSE = IUSE + (N+1) +CFPP$ NODEPCHK L + DO 40 I = 1, N+1 + INDEX (NZ+N+1+I) = INDEX (I) +40 CONTINUE + + CALL MA38PD (N, NZ, INDEX (NZ+N+2), + $ VALUE (NZ+1), LVALUE-NZ, + $ INDEX (NZ+2*N+3), LIND2-(NZ+2*N+2), + $ LUX1, LUI1, IUSE, XUSE, NZOFF, NBLKS, + $ ICNTL, INFO, RINFO, + $ PRESRV, INDEX, INDEX (N+2), VALUE, N, NZ, + $ INDEX (LUIR1), IP2 - LUIR1 + 1, + $ INDEX (LUBLPP), INDEX (BLKPP), INDEX (OFFPP), ON, + $ INDEX (CPERMP), INDEX (RPERMP), NE) + IF (INFO (1) .LT. 0) THEN +C error return, if MA38PD fails + GO TO 9000 + ENDIF +C adjust pointers to reflect Index/Value, not II/XX: + LUX1 = LUX1 + NZ + LUI1 = LUI1 + (NZ+2*N+2) + +C move preserved copy of A to permanent place + LUX1 = LUX1 - (NZ) + LUI1 = LUI1 - (NZ+N+1) + DO 50 I = NZ+N+1, 1, -1 + INDEX (LUI1+I-1) = INDEX (I) +50 CONTINUE + DO 60 I = NZ, 1, -1 + VALUE (LUX1+I-1) = VALUE (I) +60 CONTINUE + + ELSE + +C ------------------------------------------------------------- +C do not preserve the original matrix +C ------------------------------------------------------------- + + CALL MA38PD (N, NZ, INDEX, + $ VALUE, LVALUE, + $ INDEX (N+2), LIND2-(N+1), + $ LUX1, LUI1, IUSE, XUSE, NZOFF, NBLKS, + $ ICNTL, INFO, RINFO, + $ PRESRV, INDEX, INDEX, VALUE, 0, 1, + $ INDEX (LUIR1), IP2 - LUIR1 + 1, + $ INDEX (LUBLPP), INDEX (BLKPP), INDEX (OFFPP), ON, + $ INDEX (CPERMP), INDEX (RPERMP), NE) + IF (INFO (1) .LT. 0) THEN +C error return, if MA38PD fails + GO TO 9000 + ENDIF +C adjust pointers to reflect Index/Value, not II/XX: + LUI1 = LUI1 + (N+1) + + ENDIF + +C----------------------------------------------------------------------- +C wrap-up +C----------------------------------------------------------------------- + + IF (TRANSA) THEN + INDEX (LINDEX-6) = 1 + ELSE + INDEX (LINDEX-6) = 0 + ENDIF + INDEX (LINDEX-5) = NZOFF + INDEX (LINDEX-4) = NBLKS + IF (PRESRV) THEN + INDEX (LINDEX-3) = 1 + ELSE + INDEX (LINDEX-3) = 0 + ENDIF + INDEX (LINDEX-2) = NZ + INDEX (LINDEX-1) = N + INDEX (LINDEX) = NE + +C save location of LU factors + KEEP (1) = LUX1 + KEEP (2) = LVALUE + KEEP (3) = LUI1 + KEEP (4) = LUIR1 + KEEP (5) = LINDEX + +C update memory usage information + IUSE = LINDEX - LUI1 + 1 + XUSE = LVALUE - LUX1 + 1 + +C----------------------------------------------------------------------- +C print the output arguments if requested, and return +C----------------------------------------------------------------------- + +C error return label: +9000 CONTINUE + IF (INFO (1) .LT. 0) THEN + KEEP (1) = 0 + KEEP (2) = 0 + KEEP (3) = 0 + KEEP (4) = 0 + KEEP (5) = 0 + ENDIF + + INFO (18) = MIN (LINDEX, MAX (INFO (18), IUSE)) + INFO (19) = INFO (18) + INFO (22) = INFO (19) + INFO (20) = MIN (LVALUE, MAX (INFO (20), XUSE)) + + CALL MA38YD (2, 2, + $ N, NE, JOB, TRANSA, LVALUE, LINDEX, VALUE, + $ INDEX, KEEP, CNTL, ICNTL, INFO, RINFO, + $ RINFO(1), RINFO(1), 1, RINFO(1), 1) + RETURN + END + + SUBROUTINE MA38CD (N, JOB, TRANSC, LVALUE, LINDEX, VALUE, INDEX, + * KEEP, B, X, W, CNTL, ICNTL, INFO, RINFO) + INTEGER N, JOB + LOGICAL TRANSC + INTEGER LVALUE, LINDEX + DOUBLE PRECISION VALUE(LVALUE) + INTEGER INDEX(LINDEX), KEEP(20) + DOUBLE PRECISION B(N), X(N), W(*), CNTL(10) + INTEGER ICNTL(20), INFO(40) + DOUBLE PRECISION RINFO(20) + +C=== MA38CD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Given LU factors computed by MA38AD or MA38BD, and the +C right-hand-side, B, solve a linear system for the solution X. +C +C This routine handles all permutations, so that B and X are in terms +C of the original order of the matrix, A, and not in terms of the +C permuted matrix. +C +C If iterative refinement is done, then the residual is returned in W, +C and the sparse backward error estimates are returned in +C Rinfo (7) and Rinfo (8). The computed solution X is the +C exact solution of the equation (A + dA)x = (b + db), where +C dA (i,j) <= max (Rinfo (7), Rinfo (8)) * abs (A(i,j)) +C and +C db (i) <= max (Rinfo (7) * abs (b (i)), +C Rinfo (8) * maxnorm (A) * maxnorm (x computed)) +C Note that dA has the same sparsity pattern as A. +C The method used to compute the sparse backward error estimate is +C described in M. Arioli, J. W. Demmel, and I. S. Duff, "Solving +C sparse linear systems with sparse backward error," SIAM J. Matrix +C Analysis and Applications, vol 10, 1989, pp. 165-190. + +C======================================================================= +C ARGUMENTS: +C======================================================================= + +C ------------------------------------------------------------ +C n: An integer variable. +C Must be set by caller on input (not modified). +C Must be the same as passed to MA38AD or MA38BD. + +C ------------------------------------------------------------ +C job: An integer variable. +C Must be set by caller on input (not modified). +C What system to solve (see the transc argument below). +C Iterative refinement is only performed if job = 0, +C Icntl (8) > 0, and only if the original matrix was +C preserved (job = 1 in MA38AD or MA38BD). + +C ------------------------------------------------------------ +C transc: A logical variable. +C Must be set by caller on input (not modified). +C solve with L and U factors or with L' and U', where +C transa was passed to MA38AD or MA38BD. +C +C If transa = false, then PAQ = LU was performed, +C and the following systems are solved: +C +C transc = false transc = true +C ---------------- ---------------- +C job = 0 solve Ax = b solve A'x = b +C job = 1 solve P'Lx = b solve L'Px = b +C job = 2 solve UQ'x = b solve QU'x = b +C +C If transa = true, then A was transformed prior to LU +C factorization, and P(A')Q = LU +C +C transc = false transc = true +C ---------------- ---------------- +C job = 0 solve A'x = b solve Ax = b +C job = 1 solve P'Lx = b solve L'Px = b +C job = 2 solve UQ'x = b solve QU'x = b +C +C Other values of job are treated as zero. Iterative +C refinement can be done only when solving Ax=b or A'x=b. +C +C The comments below use Matlab notation, where +C x = L \ b means x = (L^(-1)) * b, premultiplication by +C the inverse of L. + +C ------------------------------------------------------------ +C lvalue: An integer variable. +C Must be set by caller on input (not modified). +C The size of Value. + +C ------------------------------------------------------------ +C lindex: An integer variable. +C Must be set by caller on input (not modified). +C The size of Index. + +C ------------------------------------------------------------ +C Value: A double precision array of size lvalue. +C Must be set by caller on input (normally from last call to +C MA38AD or MA38BD) (not modified). +C The LU factors, in Value (Keep (1) ... Keep (2)). +C The entries in Value (1 ... Keep (1) - 1) and in +C Value (Keep (2) + 1 ... lvalue) are not accessed. + +C ------------------------------------------------------------ +C Index: An integer array of size lindex. +C Must be set by caller on input (normally from last call to +C MA38AD or MA38BD) (not modified). +C The LU factors, in Index (Keep (3) ... Keep (5)). +C The entries in Index (1 ... Keep (3) - 1) and in +C Index (Keep (5) + 1 ... lindex) are not accessed. + +C ------------------------------------------------------------ +C Keep: An integer array of size 20. +C +C Keep (1..5): Must be set by caller on input (normally from +C last call to MA38AD or MA38BD) (not modified). +C Layout of the LU factors in Value and Index + +C ------------------------------------------------------------ +C B: A double precision array of size n. +C Must be set by caller on input (not modified). +C The right hand side, b, of the system to solve. + +C ------------------------------------------------------------ +C W: A double precision array of size 2*n or 4*n. +C Need not be set by caller on input. Modified on output. +C Workspace of size W (1..2*n) if Icntl (8) = 0, which +C is the default value. If iterative refinement is +C performed, and W must be of size W (1..4*n) and the +C residual b-Ax (or b-A'x) is returned in W (1..n). + +C ------------------------------------------------------------ +C X: A double precision array of size n. +C Need not be set by caller on input. Modified on output. +C The solution, x, of the system that was solved. Valid only +C if Info (1) is greater than or equal to 0. + +C ------------------------------------------------------------ +C Cntl: A double precision array of size 10. +C Must be set by caller on input (not modified). +C real control parameters, see MA38ID for a description, +C which sets the defaults. + +C ------------------------------------------------------------ +C Icntl: An integer array of size 20. +C Must be set by caller on input (not modified). +C Integer control parameters, see MA38ID for a description, +C which sets the defaults. In particular, Icntl (8) is +C the maximum number of steps of iterative refinement to be +C performed. + +C ------------------------------------------------------------ +C Info: An integer array of size 40. +C Need not be set by caller on input. Modified on output. +C It contains information about the execution of MA38CD. +C +C Info (1) is the error flag. If Info (1) is -7, then +C the LU factors are uncomputed, or have been corrupted since +C the last call to MA38AD or MA38BD. No system is solved, +C and X (1..n) is not valid on output. If Info (1) is 8, +C then iterative refinement was requested but cannot be done. +C To perform iterative refinement, the original matrix must be +C preserved (job = 1 in MA38AD or MA38BD) and Ax=b or A'x=b +C must be solved (job = 0 in MA38CD). Info (24) is the +C steps of iterative refinement actually taken. + +C ------------------------------------------------------------ +C Rinfo: A double precision array of size 20. +C Need not be set by caller on input. Modified on output. +C It contains information about the execution of MA38CD. +C +C If iterative refinement was performed then +C Rinfo (7) is the sparse error estimate, omega1, and +C Rinfo (8) is the sparse error estimate, omega2. + +C======================================================================= +C TO BE PRESERVED BETWEEN CALLS TO MA38AD, MA38BD, MA38CD: +C======================================================================= +C +C The following must be unchanged since the call to MA38AD or MA38BD +C that computed the LU factors: +C +C n +C Value (Keep (1) ... Keep (2)) +C Index (Keep (3) ... Keep (5)) +C Keep (1 ... 20) + +C## End of user documentation for MA38CD ############################### + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: user routine +C subroutines called: MA38ND, MA38YD, MA38JD +C functions called: MAX + INTRINSIC MAX + EXTERNAL MA38JD, MA38ND, MA38YD + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER NBLKS, OFFIP, OFFXP, N1, NZ, NE, OFFPP, BLKPP, LUBLPP, + $ APP, AN, ANZ, ON, LUI1, LUI2, LUX1, LUX2, AIP, AXP, + $ CPERMP, RPERMP, NZOFF, IRSTEP, YP, LY, LW, SP, IP1, IP2, + $ XP1, LUIR1, IO, PRL + LOGICAL PRESRV, BADLU + DOUBLE PRECISION + $ ZERO + PARAMETER (ZERO = 0.0D0) + +C Printing control: +C ----------------- +C io: I/O unit for diagnostic messages +C prl: printing level +C +C Location and status of LU factors: +C ---------------------------------- +C lui1: integer part of LU factors start in Index (lui1...) +C luir1: Index (luir1 ... lui2) is needed for a call to MA38BD +C lui2: integer part of LU factors end in Index (..lui2) +C lux1: real part of LU factors start in Value (lux1...) +C lux2: real part of LU factors end in Value (...lux1) +C ip1: pointer into leading part of LU factors in Index +C ip2: pointer into trailing part of LU factors in Index +C xp1: pointer into leading part of LU factors in Value +C badlu: if true, then LU factors are corrupted or not computed +C +C Arrays and scalars allocated in LU factors (in order): +C ------------------------------------------------------ +C app: Ap (1..n+1) array located in Index (app...app+n) +C axp: Ax (1..nz) array located in Value (axp...axp+nz-1) +C aip: Ai (1..nz) array located in Index (aip...aip+nz-1) +C an: n if A is preserved, 1 otherwise +C anz: nz if A is preserved, 1 otherwise +C offip: Offi (1..nzoff) array loc. in Index (offip...offip+nzoff-1) +C offxp: Offx (1..nzoff) array loc. in Value (offxp...offxp+nzoff-1) +C ... LU factors of each diagonal block located here +C lublpp: LUblkp (1..nblks) array in Index (lublpp..lublpp+nblks-1) +C blkpp: Blkp (1..nblks+1) array loc. in Index (blkpp...blkpp+nblks) +C offpp: Offp (1..n+1) array located in Index (offpp...offpp+n) +C on: size of Offp (1..n+1): n if nblks > 1, 1 otherwise +C cpermp: Cperm (1..n) array located in Index (cpermp...cpermp+n-1) +C rpermp: Rperm (1..n) array located in Index (rpermp...rpermp+n-1) +C ... seven scalars in Index (lui2-6...lui2): +C nzoff: number of entries in off-diagonal part +C nblks: number of diagonal blocks +C presrv: true if original matrix was preserved when factorized +C nz: entries in A +C n1: N argument in MA38AD or MA38BD when matrix factorized +C ne: NE argument in MA38AD or MA38BD when matrix factorized +C +C Arrays allocated from W work array: +C ----------------------------------- +C lw: size of W +C yp: Y (1..n) located in W (yp...yp+n-1) +C sp: S (1..n) located in W (sp...sp+n-1) +C ly: size of Y and S +C +C Other: +C ------ +C irstep: maximum number of iterative refinement steps to take + +C======================================================================= +C EXECUTABLE STATEMENTS: +C======================================================================= + + IO = ICNTL (2) + PRL = ICNTL (3) + +C----------------------------------------------------------------------- +C clear informational output +C----------------------------------------------------------------------- + + INFO (1) = 0 + INFO (24) = 0 + RINFO (7) = ZERO + RINFO (8) = ZERO + +C----------------------------------------------------------------------- +C print input arguments if requested +C----------------------------------------------------------------------- + + IRSTEP = MAX (0, ICNTL (8)) + IF (IRSTEP .EQ. 0) THEN + LW = 2*N + ELSE + LW = 4*N + ENDIF + CALL MA38YD (3, 1, + $ N, NE, JOB, TRANSC, LVALUE, LINDEX, VALUE, + $ INDEX, KEEP, CNTL, ICNTL, INFO, RINFO, + $ B, X, N, W, LW) + +C----------------------------------------------------------------------- +C get pointers to LU factors +C----------------------------------------------------------------------- + + LUX1 = KEEP (1) + LUX2 = KEEP (2) + LUI1 = KEEP (3) + LUIR1 = KEEP (4) + LUI2 = KEEP (5) + BADLU = LUIR1 .LE. 0 .OR. LUI2-6 .LT. LUIR1 + $ .OR. LUI2 .GT. LINDEX + $ .OR. LUX1 .LE. 0 .OR. LUX1 .GT. LUX2 .OR. LUX2 .GT. LVALUE + $ .OR. LUI1 .LE. 0 .OR. LUIR1 .LT. LUI1 .OR. LUIR1 .GT. LUI2 + IF (BADLU) THEN + CALL MA38ND (3, ICNTL, INFO, -7, 0) +C error return, LU factors are corrupted: + GO TO 9000 + ENDIF + +C----------------------------------------------------------------------- +C get seven scalars (transa, nzoff, nblks, presrv, nz, n, ne) from LU +C----------------------------------------------------------------------- + + NE = INDEX (LUI2) + N1 = INDEX (LUI2-1) + NZ = INDEX (LUI2-2) + PRESRV = INDEX (LUI2-3) .NE. 0 + NBLKS = INDEX (LUI2-4) + NZOFF = INDEX (LUI2-5) +C transa = Index (lui2-6) .ne. 0, we don't actually need this here + +C----------------------------------------------------------------------- +C get pointers to permutation vectors +C----------------------------------------------------------------------- + + RPERMP = (LUI2-6) - N + CPERMP = RPERMP - N + IP2 = CPERMP - 1 + XP1 = LUX1 + IP1 = LUI1 + +C----------------------------------------------------------------------- +C get pointers to preserved column-oriented copy of input matrix +C----------------------------------------------------------------------- + + IF (PRESRV) THEN + +C ------------------------------------------------------------- +C original matrix preserved in Index (lui1..lui1+nz+n) and +C Value (lux1..lux1+nz-1) +C ------------------------------------------------------------- + + APP = IP1 + AIP = APP + N+1 + IP1 = AIP + NZ + AXP = XP1 + XP1 = AXP + NZ + AN = N + ANZ = NZ + + ELSE + +C ------------------------------------------------------------- +C original matrix not preserved, pass dummy argument to MA38JD +C ------------------------------------------------------------- + + APP = 1 + AIP = 1 + AXP = 1 + AN = 1 + ANZ = 1 + + ENDIF + +C----------------------------------------------------------------------- +C get pointers to block-triangular information, if BTF was used +C----------------------------------------------------------------------- + + IF (NBLKS .GT. 1) THEN + +C ------------------------------------------------------------- +C get pointers to off-diagonal nonzeros, and BTF arrays +C ------------------------------------------------------------- + + OFFIP = IP1 + IP1 = IP1 + NZOFF + OFFXP = XP1 + XP1 = XP1 + NZOFF + OFFPP = CPERMP - (N+1) + BLKPP = OFFPP - (NBLKS+1) + LUBLPP = BLKPP - (NBLKS) + IP2 = LUBLPP - 1 + ON = N + + ELSE + +C ------------------------------------------------------------- +C matrix was factorized as a single block, pass dummy arg. +C ------------------------------------------------------------- + + OFFIP = 1 + OFFXP = 1 + OFFPP = 1 + BLKPP = 1 + LUBLPP = 1 + ON = 1 + + ENDIF + + BADLU = N .NE. N1 .OR. NZ .LE. 0 .OR. LUIR1 .GT. IP2 .OR. + $ NBLKS .LE. 0 .OR. NBLKS .GT. N .OR. + $ XP1 .GT. LUX2 .OR. NZOFF .LT. 0 .OR. IP1 .NE. LUIR1 + IF (BADLU) THEN + CALL MA38ND (3, ICNTL, INFO, -7, 0) +C error return, LU factors are corrupted: + GO TO 9000 + ENDIF + +C----------------------------------------------------------------------- +C get the number of steps of iterative refinement +C----------------------------------------------------------------------- + + IF (IRSTEP .GT. 0 .AND. .NOT. PRESRV) THEN +C original matrix not preserved (MA38AD/MA38BD job .ne. 1) + CALL MA38ND (3, ICNTL, INFO, 8, 0) + IRSTEP = 0 + ENDIF + IF (IRSTEP .GT. 0 .AND. (JOB .EQ. 1 .OR. JOB .EQ. 2)) THEN +C iterative refinement for Ax=b and A'x=b only (job = 0) + CALL MA38ND (3, ICNTL, INFO, 8, 1) + IRSTEP = 0 + ENDIF + IF (IRSTEP .EQ. 0) THEN +C pass a dummy argument as Y, which is not accessed in MA38JD + YP = 1 + LY = 1 + SP = 1 + LW = 2*N + ELSE +C pass W (yp ... yp+n-1) as Y (1..n) to MA38JD + YP = 2*N+1 + LY = N + SP = 3*N+1 + LW = 4*N + ENDIF + +C----------------------------------------------------------------------- +C solve; optional iterative refinement and sparse backward error +C----------------------------------------------------------------------- + + CALL MA38JD (N, JOB, TRANSC, LUX2-XP1+1, VALUE (XP1), + $ IP2-LUIR1+1, INDEX (LUIR1), B, X, + $ W, W (N+1), LY, W (YP), W (SP), + $ CNTL, INFO, RINFO, INDEX (CPERMP), INDEX (RPERMP), + $ AN, ANZ, INDEX (APP), INDEX (AIP), VALUE (AXP), + $ ON, MAX (1, NZOFF), INDEX (OFFPP), INDEX (OFFIP), + $ VALUE (OFFXP), NBLKS, INDEX (LUBLPP), INDEX (BLKPP), IRSTEP) + +C----------------------------------------------------------------------- +C print output arguments if requested +C----------------------------------------------------------------------- + +C error return label: +9000 CONTINUE + CALL MA38YD (3, 2, + $ N, NE, JOB, TRANSC, LVALUE, LINDEX, VALUE, + $ INDEX, KEEP, CNTL, ICNTL, INFO, RINFO, + $ B, X, N, W, LW) + RETURN + END + + +C####################################################################### +C## non-user-callable routines: +C####################################################################### + + + SUBROUTINE MA38DD (N, NZ, CP, XX, XSIZE, II, ISIZE, XTAIL, + * ITAIL, IUSE, XUSE, NZOFF, NBLKS, ICNTL, CNTL, INFO, + * RINFO, PRESRV, AP, AI, AX, AN, ANZ, KEEP, NE) + INTEGER N, NZ, ISIZE, II(ISIZE), ICNTL(20), INFO(40), + * CP(N+1), XSIZE, XTAIL, ITAIL, IUSE, XUSE, AN, ANZ, + * AP(AN+1), AI(ANZ), KEEP(20), NZOFF, NBLKS, NE + LOGICAL PRESRV + DOUBLE PRECISION XX(XSIZE), CNTL(10), RINFO(20), AX(ANZ) + +C=== MA38DD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Factorize an unsymmetric sparse matrix in column-form, optionally +C permuting the matrix to upper block triangular form and factorizing +C each diagonal block. + +C======================================================================= +C INPUT: +C======================================================================= +C +C n: order of matrix +C nz: entries in matrix, after removing duplicates +C and invalid entries. +C ne: number of triplets, unchanged from MA38AD +C Cp (1..n+1): column pointers of input matrix +C presrv: if true then preserve original matrix +C xsize: size of XX +C isize: size of II +C iuse: memory usage in Index on input +C xuse: memory usage in Value on input +C Icntl: integer control parameters, see MA38ID +C Cntl: real control parameters, see MA38ID +C Keep (6..8): integer control parameters, see MA38ID +C +C if presrv is true: +C an: = n, order of preserved matrix +C anz: = anz, order of preserved matrix +C Ap (1..an+1): column pointers of preserved matrix +C Ai (1..nz): row indices of preserved matrix +C Ax (1..nz): values of preserved matrix +C II: unused on input +C XX: unused on input +C else +C an: 1 +C anz: 1 +C Ap: unused +C Ai: unused +C Ax: unused +C II (1..nz): row indices of input matrix +C XX (1..nz): values of input matrix + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C XX (xtail ... xsize), xtail: +C +C LU factors are located in XX (xtail ... xsize), +C including values in off-diagonal part if matrix +C was permuted to block triangular form. +C +C II (itail ... isize), itail: +C +C LU factors are located in II (itail ... isize), +C including pattern, row and column permutations, +C block triangular information, etc. See umf2fa +C for more information. +C +C Info: integer informational output, see MA38AD +C Rinfo: real informational output, see MA38AD +C +C iuse: memory usage in Index on output +C xuse: memory usage in Value on output +C +C nzoff: entries in off-diagonal part (0 if BTF not used) +C nblks: number of diagonal blocks (1 if BTF not used) + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38AD +C subroutines called: MA38ND, MA38HD, MA38ED, MA38MD +C functions called: MAX + INTRINSIC MAX + EXTERNAL MA38ED, MA38HD, MA38MD, MA38ND + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER KN, NZDIA, BLKPP, LUBLPP, P, OFFIP, XHEAD, ROW, + $ OFFXP, OFFPP, IHEAD, K1, K2, BLK, PRP, P2, CPERMP, + $ RPERMP, NSGLTN, NPIV, MNZ, NSYM, K, COL, RMAX, CMAX, + $ TOTNLU, XRMAX, XRUSE + LOGICAL TRYBTF, IOUT, XOUT + DOUBLE PRECISION + $ ZERO, ONE, A + PARAMETER (ZERO = 0.0D0, ONE = 1.0D0) + +C Allocated array pointers: +C ------------------------- +C blkpp: Blkp (1..nblks+1) array located in II (blkpp..blkp+nblks) +C lublpp: LUblkp (1..nblks) array loc. in II (lublpp..lublpp+nblks-1) +C offip: Offi (1..nzoff) array located in II (offip..offip+nzoff-1) +C offxp: Offx (1..nzoff) array located in XX (offxp..offxp+nzoff-1) +C offpp: Offp (1..n+1) array located in II (offpp..offpp+n) +C cpermp: Cperm (1..n) array located in II (cpermp..cpermp+n-1) +C rpermp: Rperm (1..n) array located in II (rpermp..rpermp+n-1) +C prp: Pr (1..n) work array located in II (prp..prp+n-1) +C +C BTF information: +C ---------------- +C k1: starting index of diagonal block being factorized +C k2: ending index of diagonal block being factorized +C kn: the order of the diagonal block being factorized +C blk: block number of diagonal block being factorized +C trybtf: true if BTF is to be attempted (= Icntl (4) .eq. 1) +C nzdia: number of entries in diagonal blocks (= nz if BTF not used) +C nsgltn: number of 1-by-1 diagonal blocks ("singletons") +C npiv: number of numerically valid singletons +C a: numerical value of a singleton +C mnz: nzoff +C +C Memory usage: +C ------------- +C xhead: XX (1..xhead-1) is in use, XX (xhead..xtail-1) is free +C ihead: II (1..ihead-1) is in use, II (ihead..itail-1) is free +C iout: true if MA38ED ran out of integer memory, but did not +C set error flag +C xout: true if MA38FD ran out of real memory, but did not +C set error flag +C +C Estimated memory for MA38BD: +C ---------------------------- +C rmax: largest contribution block is cmax-by-rmax +C cmax: " " " " " " " +C totnlu: total number of LU arrowheads in all diagonal blocks +C xrmax: estimated maximum real memory usage for MA38BD +C xruse: estimated current real memory usage for MA38BD +C +C Other: +C ------ +C k: loop index (kth pivot) +C row: row index +C col: column index +C p: pointer +C p2: pointer +C nsym: number of symmetric pivots chosen + +C======================================================================= +C EXECUTABLE STATEMENTS: +C======================================================================= + +C----------------------------------------------------------------------- +C get input parameters and initialize +C----------------------------------------------------------------------- + + NBLKS = 1 + NZOFF = 0 + NZDIA = NZ + NSGLTN = 0 + NPIV = 0 + RMAX = 1 + CMAX = 1 + TOTNLU = 0 + XOUT = .FALSE. + IOUT = .FALSE. + XRMAX = 2*NE + IF (PRESRV) THEN +C original matrix is not in Cp/II/XX, but in Ap/Ai/Ax: + IHEAD = 1 + XHEAD = 1 + ELSE + IHEAD = NZ + 1 + XHEAD = NZ + 1 + ENDIF + ITAIL = ISIZE + 1 + XTAIL = XSIZE + 1 + +C----------------------------------------------------------------------- +C allocate permutation arrays: Cperm (1..n) and Rperm (1..n), and +C seven scalars: transa, nzoff, nblks, presrv, nz, n, ne +C (in that order) at tail of II (in LU factors) +C----------------------------------------------------------------------- + + ITAIL = ITAIL - (2*N+7) + IUSE = IUSE + (2*N+7) + INFO (18) = MAX (INFO (18), IUSE) + INFO (19) = INFO (18) + CPERMP = ITAIL + RPERMP = CPERMP + N + IF (IHEAD .GT. ITAIL) THEN +C error return, if not enough integer memory: + GO TO 9000 + ENDIF + +C----------------------------------------------------------------------- +C Find permutations to block upper triangular form, if requested. +C----------------------------------------------------------------------- + + TRYBTF = ICNTL (4) .EQ. 1 + IF (TRYBTF) THEN + +C ------------------------------------------------------------- +C get workspace at tail of II of size 6n+2 +C ------------------------------------------------------------- + + ITAIL = ITAIL - (N+1) + OFFPP = ITAIL + ITAIL = ITAIL - (5*N+1) + P = ITAIL + IUSE = IUSE + (6*N+2) + INFO (18) = MAX (INFO (18), IUSE) + INFO (19) = INFO (18) + +C ------------------------------------------------------------- + IF (PRESRV) THEN +C find permutation, but do not convert to BTF form +C ------------------------------------------------------------- + + IF (IHEAD .GT. ITAIL) THEN +C error return, if not enough integer memory: + GO TO 9000 + ENDIF + CALL MA38HD (AX, ANZ, AI, ANZ, N, NZ, NZDIA, NZOFF, + $ NBLKS, CP, II (CPERMP), II (RPERMP), II(P), II(P+N), + $ II (P+2*N), II (P+3*N), II (P+4*N), II (OFFPP), + $ PRESRV) + +C ------------------------------------------------------------- + ELSE +C find permutation, convert to BTF form, and discard original +C ------------------------------------------------------------- + +C use additional size nz temporary workspace in II and XX + IHEAD = IHEAD + NZ + XHEAD = XHEAD + NZ + IUSE = IUSE + NZ + XUSE = XUSE + NZ + INFO (18) = MAX (INFO (18), IUSE) + INFO (20) = MAX (INFO (20), XUSE) + INFO (19) = INFO (18) + INFO (21) = INFO (20) + IF (IHEAD .GT. ITAIL .OR. XHEAD .GT. XTAIL) THEN +C error return, if not enough integer and/or real memory: + GO TO 9000 + ENDIF + CALL MA38HD (XX, 2*NZ, II, 2*NZ, N, NZ, NZDIA, NZOFF, + $ NBLKS, CP, II (CPERMP), II (RPERMP), II(P), II(P+N), + $ II (P+2*N), II (P+3*N), II (P+4*N), II (OFFPP), + $ PRESRV) +C deallocate extra workspace in II and XX + IHEAD = IHEAD - NZ + XHEAD = XHEAD - NZ + IUSE = IUSE - NZ + XUSE = XUSE - NZ + ENDIF + +C ------------------------------------------------------------- +C deallocate workspace, and allocate BTF arrays if required +C ------------------------------------------------------------- + + IF (NBLKS .GT. 1) THEN +C replace (6*n+2) workspace at tail of II with +C Blkp (1..nblks+1) and LUblkp (1..nblks), Offp (1..n+1) + BLKPP = OFFPP - (NBLKS+1) + LUBLPP = BLKPP - (NBLKS) + ITAIL = LUBLPP + IUSE = IUSE - (6*N+2) + (2*NBLKS+N+2) + ELSE +C The matrix is irreducible. There is only one block. +C Remove everything at tail of II, except +C for the 2*n permutation vectors and the 7 scalars. +C (transa, nzoff, nblks, presrv, nz, n, ne). + ITAIL = (ISIZE + 1) - (2*N+7) + IUSE = IUSE - (6*N+2) + ENDIF + + ENDIF + +C----------------------------------------------------------------------- +C current memory usage: +C----------------------------------------------------------------------- + +C if .not. presrv then +C input matrix is now in II (1..nz) and XX (1..nz) +C off-diagonal part: in II/XX (1..nzoff) +C col pattern: II (Offp (col) ... Offp (col+1)) +C col values: XX (Offp (col) ... Offp (col+1)) +C diagonal blocks: in II/XX (nzoff+1..nz) +C col pattern: II (Cp (col) ... Cp (col+1)) +C col values: XX (Cp (col) ... Cp (col+1)) +C total: nz+n+1 integers, nz reals +C else +C input matrix is now in Ai (1..nz) and Ax (1..nz), +C in original (non-BTF) order: +C col pattern: Ai (Ap (col) ... Ap (col+1)) +C col values: Ax (Ap (col) ... Ap (col+1)) +C Cp is a size n+1 integer workspace +C total: nz+2*(n+1) integers, nz reals +C +C if (nblks > 1) then +C at tail of II (in order): 2*nblks+n+2 +C LUblkp (1..nblks) +C Blkp (1..nblks+1) +C Offp (1..n+1) +C total: (2*nblks+n+2) integers +C +C remainder at tail of II: +C Cperm (1..n) +C Rperm (1..n) +C seven scalars: transa, nzoff, nblks, presrv, nz, n, ne +C +C Grand total current memory usage (including II,XX,Cp,Ai,Ap,Ax): +C +C presrv nblks>1 integers, iuse = +C F F nz+ (n+1)+(2*n+7) +C F T nz+ (n+1)+(2*n+7)+(2*nblks+n+2) +C T F nz+2*(n+1)+(2*n+7) +C T T nz+2*(n+1)+(2*n+7)+(2*nblks+n+2) +C +C real usage is xuse = nz + +C ---------------------------------------------------------------- +C get memory usage for next call to MA38BD +C ---------------------------------------------------------------- + + XRUSE = NZ + +C----------------------------------------------------------------------- +C factorization +C----------------------------------------------------------------------- + + IF (NBLKS .EQ. 1) THEN + +C ------------------------------------------------------------- +C factorize the matrix as a single block +C ------------------------------------------------------------- + + CALL MA38ED (CP, N, II (CPERMP), II (RPERMP), NZOFF, + $ ITAIL, XTAIL, XX, XSIZE, XUSE, II, ITAIL-1, IUSE, + $ ICNTL, CNTL, INFO, RINFO, NBLKS, + $ AP, AI, AX, PRESRV, 1, AN, ANZ, II, KEEP, + $ RMAX, CMAX, TOTNLU, XRMAX, XRUSE, IOUT, XOUT) + IF (IOUT .OR. XOUT) THEN +C error return, if not enough integer and/or real memory: + GO TO 9000 + ENDIF + IF (INFO (1) .LT. 0) THEN +C error return, if error in MA38FD: + GO TO 9010 + ENDIF +C original matrix has been deallocated + IHEAD = 1 + XHEAD = 1 + +C ------------------------------------------------------------- +C make the index of the block relative to start of LU factors +C ------------------------------------------------------------- + + II (ITAIL) = 1 + + ELSE + +C ------------------------------------------------------------- +C factorize the block-upper-triangular form of the matrix +C ------------------------------------------------------------- + + PRP = OFFPP + IF (PRESRV) THEN +C count the off-diagonal entries during factorization + NZOFF = 0 +C compute temp inverse permutation in II (prp..prp+n-1) +CFPP$ NODEPCHK L + DO 10 K = 1, N + II (PRP + II (RPERMP+K-1) - 1) = K +10 CONTINUE + ENDIF + + DO 30 BLK = NBLKS, 1, -1 + +C ---------------------------------------------------------- +C factorize the kn-by-kn block, A (k1..k2, k1..k2) +C ---------------------------------------------------------- + +C get k1 and k2, the start and end of this block + K1 = II (BLKPP+BLK-1) + K2 = II (BLKPP+BLK) - 1 + KN = K2-K1+1 + IF (.NOT. PRESRV) THEN + P = CP (K1) + CP (K2+1) = IHEAD + ENDIF + + IF (KN .GT. 1) THEN + +C ------------------------------------------------------- +C factor the block (the block is not a singleton) +C ------------------------------------------------------- + + CALL MA38ED (CP (K1), KN, + $ II (CPERMP+K1-1), II (RPERMP+K1-1), NZOFF, + $ ITAIL, XTAIL, XX, XTAIL-1, XUSE, II, ITAIL-1, + $ IUSE, ICNTL, CNTL, INFO, RINFO, NBLKS, + $ AP, AI, AX, PRESRV, K1, AN, ANZ, II (PRP), KEEP, + $ RMAX, CMAX, TOTNLU, XRMAX, XRUSE, IOUT, XOUT) + IF (IOUT .OR. XOUT) THEN +C error return, if not enough int. and/or real memory: + GO TO 9000 + ENDIF + IF (INFO (1) .LT. 0) THEN +C error return, if error in MA38FD: + GO TO 9010 + ENDIF + IF (PRESRV) THEN + IHEAD = 1 + XHEAD = 1 + ELSE + IHEAD = P + XHEAD = P + ENDIF + +C ------------------------------------------------------- +C save the location of the LU factors in LUbkp (blk) +C ------------------------------------------------------- + + II (LUBLPP+BLK-1) = ITAIL + + ELSE + +C ------------------------------------------------------- +C get the value of singleton at A (k1,k1), if it exists +C ------------------------------------------------------- + + A = ZERO + IF (PRESRV) THEN +C find the diagonal entry in the unpermuted matrix + COL = II (CPERMP + K1 - 1) + DO 20 P2 = AP (COL), AP (COL + 1) - 1 + ROW = II (PRP + AI (P2) - 1) + IF (ROW .LT. K1) THEN +C entry in off-diagonal blocks + NZOFF = NZOFF + 1 + ELSE + A = AX (P2) + ENDIF +20 CONTINUE + IHEAD = 1 + XHEAD = 1 + ELSE IF (P .NE. IHEAD) THEN + A = XX (P) + IHEAD = P + XHEAD = P + IUSE = IUSE - 1 + XUSE = XUSE - 1 + XRUSE = XRUSE - 1 + ENDIF + +C ------------------------------------------------------- +C store the 1-by-1 LU factors of a singleton +C ------------------------------------------------------- + + NSGLTN = NSGLTN + 1 + IF (A .EQ. ZERO) THEN +C the diagonal entry is either not present, or present +C but numerically zero. This is a singular matrix, +C replace with 1-by-1 identity matrix. + A = ONE + ELSE +C increment pivot count + NPIV = NPIV + 1 + ENDIF + XTAIL = XTAIL - 1 +C note: if the matrix is not preserved and nonsingular +C then we will not run out of memory at this point. + XUSE = XUSE + 1 + XRUSE = XRUSE + 1 + XRMAX = MAX (XRMAX, XRUSE) + INFO (20) = MAX (INFO (20), XUSE) + INFO (21) = MAX (INFO (21), XUSE) +C error return, if not enough real memory: + IF (XHEAD .GT. XTAIL) THEN + GO TO 9000 + ENDIF + II (LUBLPP+BLK-1) = -XTAIL + XX (XTAIL) = A + + ENDIF + +30 CONTINUE + +C ------------------------------------------------------------- +C make the index of each block relative to start of LU factors +C ------------------------------------------------------------- + +CFPP$ NODEPCHK L + DO 40 P = LUBLPP, LUBLPP + NBLKS - 1 + IF (II (P) .GT. 0) THEN + II (II (P)) = II (II (P)) - XTAIL + 1 + II (P) = II (P) - ITAIL + 1 + ELSE +C this is a singleton + II (P) = (-II (P)) - XTAIL + 1 + ENDIF +40 CONTINUE + +C ------------------------------------------------------------- +C allocate temporary workspace for Pr (1..n) at head of II +C ------------------------------------------------------------- + + PRP = IHEAD + IHEAD = IHEAD + N + IUSE = IUSE + N + +C ------------------------------------------------------------- +C allocate a single entry in case the LU factors are empty +C ------------------------------------------------------------- + + IF (NBLKS .EQ. N) THEN +C otherwise, arrays in MA38BD and MA38CD would have +C zero size, which can cause an address fault later on + ITAIL = ITAIL - 1 + IUSE = IUSE + 1 + P2 = ITAIL + ENDIF + +C ------------------------------------------------------------- +C allocate permanent copy of off-diagonal blocks +C ------------------------------------------------------------- + + ITAIL = ITAIL - NZOFF + OFFIP = ITAIL + XTAIL = XTAIL - NZOFF + OFFXP = XTAIL + IUSE = IUSE + NZOFF + XUSE = XUSE + NZOFF + XRUSE = XRUSE + NZOFF + XRMAX = MAX (XRMAX, XRUSE) + INFO (18) = MAX (INFO (18), IUSE) + INFO (19) = MAX (INFO (19), IUSE) + INFO (20) = MAX (INFO (20), XUSE) + INFO (21) = MAX (INFO (21), XUSE) + IF (IHEAD .GT. ITAIL .OR. XHEAD .GT. XTAIL) THEN +C error return, if not enough integer and/or real memory: + GO TO 9000 + ENDIF + +C ------------------------------------------------------------- +C re-order the off-diagonal blocks according to pivot perm +C ------------------------------------------------------------- + +C use Cp as temporary work array: + MNZ = NZOFF + IF (PRESRV) THEN + CALL MA38MD (CP, N, II (RPERMP), II (CPERMP), NZOFF, + $ II (OFFPP), II (OFFIP), XX (OFFXP), II (PRP), + $ ICNTL, AP, AI, AX, AN, ANZ, PRESRV, NBLKS, II (BLKPP), + $ MNZ, 1, P) + ELSE + CALL MA38MD (CP, N, II (RPERMP), II (CPERMP), NZOFF, + $ II (OFFPP), II (OFFIP), XX (OFFXP), II (PRP), + $ ICNTL, AP, II, XX, 0, MNZ, PRESRV, 0, II(BLKPP), + $ MNZ, 1, P) + ENDIF + IF (NBLKS .EQ. N) THEN +C zero the only entry in the integer part of the LU factors + II (P2) = 0 + ENDIF + +C ------------------------------------------------------------- +C deallocate Pr (1..n), and II/XX (1..nzoff) if present +C ------------------------------------------------------------- + + IHEAD = 1 + XHEAD = 1 + IUSE = IUSE - N + IF (.NOT. PRESRV) THEN + IUSE = IUSE - NZOFF + XUSE = XUSE - NZOFF + ENDIF + + ENDIF + +C----------------------------------------------------------------------- +C normal and error return +C----------------------------------------------------------------------- + +C error return label: +9000 CONTINUE + IF (IOUT .OR. IHEAD .GT. ITAIL) THEN +C set error flag if not enough integer memory + CALL MA38ND (1, ICNTL, INFO, -3, INFO (19)) + ENDIF + IF (XOUT .OR. XHEAD .GT. XTAIL) THEN +C set error flag if not enough real memory + CALL MA38ND (1, ICNTL, INFO, -4, INFO (21)) + ENDIF + +C error return label, for error from MA38FD: +9010 CONTINUE + + INFO (4) = 0 + NZDIA = NZ - NZOFF + INFO (5) = NZ + INFO (6) = NZDIA + INFO (7) = NZOFF + INFO (8) = NSGLTN + INFO (9) = NBLKS + INFO (12) = INFO (10) + INFO (11) + N + INFO (7) + +C Count the number of symmetric pivots chosen. Note that some of +C these may have been numerically unacceptable. + NSYM = 0 + IF (INFO (1) .GE. 0) THEN + DO 50 K = 1, N + IF (II (CPERMP+K-1) .EQ. II (RPERMP+K-1)) THEN +C this kth pivot came from the diagonal of A + NSYM = NSYM + 1 + ENDIF +50 CONTINUE + ENDIF + INFO (16) = NSYM + + INFO (17) = INFO (17) + NPIV + RINFO (1) = RINFO (4) + RINFO (5) + RINFO (6) + + IF (INFO (1) .GE. 0 .AND. INFO (17) .LT. N) THEN +C set warning flag if matrix is singular + CALL MA38ND (1, ICNTL, INFO, 4, INFO (17)) + ENDIF + +C ---------------------------------------------------------------- +C Determine an upper bound on the amount of integer memory needed +C (LINDEX) for a subsequent call to MA38BD. If block-upper- +C triangular-form is not in use (Info (9) is 1), then +C this bound is exact. If NE is higher in the call to MA38BD +C than in the call to MA38AD, then add 3 integers for each +C additional entry (including the 2 integers required for the +C row and column indices of the additional triplet itself). +C This estimate assumes that JOB and TRANSA are the same in +C MA38AD and MA38BD. +C ---------------------------------------------------------------- + +C (Keep (5) - Keep (4) + 1), is added to Info (22) +C in MA38AD, to complete the computation of the estimate. + + IF (PRESRV) THEN + INFO (22) = MAX (3*NE+2*N+1, NE+3*N+2, + $ 2*NZ+4*N+10+RMAX+3*CMAX+4*TOTNLU) + ELSE + INFO (22) = MAX (3*NE+2*N+1, NE+3*N+2, 2*NZ+3*N+2, + $ NZ+3*N+ 9+RMAX+3*CMAX+4*TOTNLU) + ENDIF + +C ---------------------------------------------------------------- +C Approximate the amount of real memory needed (LVALUE) for a +C subsequent call to MA38BD. The approximation is an upper bound +C on the bare minimum amount needed. Some garbage collection may +C occur, but MA38BD is guaranteed to finish if given an LVALUE of +C size Info (23) and if the pattern is the same. If NE is +C higher in the call to MA38BD than in the call to MA38AD, then +C add 2 reals for each additional entry (including the 1 real +C required for the value of the additional triplet itself). +C This estimate assumes that JOB and TRANSA are the same in +C MA38AD and MA38BD. +C ---------------------------------------------------------------- + + INFO (23) = XRMAX + RETURN + END + + SUBROUTINE MA38ED (CP, N, CPERM, RPERM, NZOFF, + * ITAIL, XTAIL, XX, XSIZE, XUSE, II, ISIZE, IUSE, + * ICNTL, CNTL, INFO, RINFO, NBLKS, + * AP, AI, AX, PRESRV, K1, AN, ANZ, PR, KEEP, + * RMAX, CMAX, TOTNLU, XRMAX, XRUSE, IOUT, XOUT) + INTEGER XSIZE, ISIZE, N, ICNTL(20), INFO(40), XUSE, IUSE, + * ITAIL, XTAIL, II(ISIZE), CP(N+1), CPERM(N), NZOFF, + * AN, ANZ, RPERM(N), AI(ANZ), AP(AN+1), K1, PR(AN), + * NBLKS, KEEP(20), RMAX, CMAX, TOTNLU, XRMAX, XRUSE + LOGICAL PRESRV, IOUT, XOUT + DOUBLE PRECISION XX(XSIZE), CNTL(10), RINFO(20), AX(ANZ) + +C=== MA38ED ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C MA38ED factorizes the n-by-n column-form matrix at the head of II/XX +C or in Ap/Ai/Ax, and places its LU factors at the tail of II/XX. The +C input matrix overwritten if it is located in II/XX on input. If +C block-triangular-form (BTF) is in use, this routine factorizes a +C single diagonal block. + +C======================================================================= +C INPUT: +C======================================================================= +C +C n: order of matrix (or order of diagonal block +C if BTF is in use). +C Cp (1..n+1): column pointers for input matrix +C nblks: number of diagonal blocks in BTF form +C isize: size of II +C xsize: size of XX +C k1: first index of this matrix (1 if BTF not used) +C Icntl: integer control parameters, see MA38ID +C Cntl: real control parameters, see MA38ID +C Keep (6..8): integer control parameters, see MA38ID +C iuse: memory usage in Index +C xuse: memory usage in Value +C rmax: maximum ludegr seen so far (see MA38FD for info) +C cmax: maximum ludegc seen so far (see MA38FD for info) +C totnlu: total number of LU arrowheads constructed so far +C +C if nblks>1 then: +C Cperm (1..n): col permutation to BTF +C Rperm (1..n): row permutation to BTF +C else +C Cperm (1..n): undefined on input +C Rperm (1..n): undefined on input +C +C +C presrv: if true then input matrix is preserved +C +C if presrv is true then: +C an: order of preserved matrix (all blocks) +C anz: entries in preserved matrix +C Ap (1..an+1): column pointers for preserved matrix +C Ai (1..anz): row indices of preserved matrix +C Ax (1..anz): values of preserved matrix +C The preserved matrix is not in BTF form; +C it is in the orginal order. +C if nblks > 1: +C Pr (1..n): inverse row permutations to BTF form +C nzoff entries in off-diagonal blocks +C seen so far +C else +C Pr (1..n): undefined on input +C +C II (1..isize): undefined on input +C XX (1..xsize): undefined on input +C Cp (1..n+1): undefined on input +C +C else, if presrv is false: +C an: 1 +C anz: 1 +C II (1..Cp (1) - 1): unused +C II (Cp (1) ... Cp (n+1)-1): row indices of matrix to factor, +C will be overwritten on output +C II (Cp (n+1) ... isize): unused on input +C +C XX (1..Cp (1) - 1): unused +C XX (Cp (1) ... Cp (n+1)-1): values of matrix to factorize, +C will be overwritten on output +C XX (Cp (n+1) ... xsize): unused on input +C If BTF is in use, then II and XX contain a +C single diagonal block. + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C XX (xtail ... xsize), xtail, II (itail ... isize), itail: +C +C The LU factors of a single diagonal block. +C See MA38FD for a description. +C +C II (cp1 ... itail-1): undefined on output +C XX (cp1 ... xtail-1): undefined on output, +C where cp1 is equal to the value of Cp (1) +C if presrv is false, or cp1 = 1 if presrv is +C true. +C +C Info: integer informational output, see MA38AD +C Rinfo: real informational output, see MA38AD +C Cperm (1..n): the final col permutations, including BTF +C Rperm (1..n): the final row permutations, including BTF +C +C iuse: memory usage in Index +C xuse: memory usage in Value +C rmax: maximum ludegr seen so far (see MA38FD for info) +C cmax: maximum ludegc seen so far (see MA38FD for info) +C totnlu: total number of LU arrowheads constructed so far +C +C if nblks>1 and presrv: +C nzoff entries in off-diagonal blocks seen so far +C +C iout: true if ran out of integer memory in MA38ED, +C and if the corresponding error status has not +C yet been set (the error status is set in the caller, +C MA38DD) +C xout: true if ran out of real memory in MA38ED, +C and if the corresponding error status has not +C yet been set (the error status is set in the caller, +C MA38DD) + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38DD +C subroutines called: MA38FD +C functions called: MAX, SQRT + INTRINSIC MAX, SQRT + EXTERNAL MA38FD + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER CP1, PC, PEND, PCOL, CDEG, COL, CSIZ, NZ, XP, IP, IS, P, + $ DN, DSIZ, WRKSIZ, I, CLEN, D1, D2, N2, ROW, CSCAL + PARAMETER (CSCAL = 9) + DOUBLE PRECISION XN + +C Original and expanded column-form: +C ---------------------------------- +C cp1: = value of Cp (1) on input +C pc: pointer to integer part of expanded column-form matrix +C pend: column col ends here in the input column-form matrix +C pcol: column col starts here in the input column-form matrix +C cdeg: degree (number of entries) in a column +C clen: number of original entries in a column (= degree, here, +C but decreases in MA38FD) +C csiz: size of the integer part of an expanded column (cdeg+cscal) +C cscal: = 9, the number of scalars in column data structure +C nz: number of entries in the diagonal block being factorized +C xp: pointer to real part of the expanded column +C ip: pointer to integer part of the expanded column +C +C Memory usage: +C ------------- +C wrksiz: size of integer workspace needed by MA38FD +C +C "Dense" columns: (converted to a prior, or artificial, frontal mat.): +C ---------------- +C d1: = Keep (7), dense column control +C d2: = Keep (8), dense column control +C dn: number of "dense" columns +C dsiz: a column is "dense" if it has more than dsiz entries +C xn: = sqrt (real (n)) +C n2: = int (sqrt (real (n))) +C +C Other: +C ------ +C row: row index +C col: a column index +C i: loop index +C p: pointer + +C======================================================================= +C EXECUTABLE STATEMENTS: +C======================================================================= + + IOUT = .FALSE. + XOUT = .FALSE. + +C----------------------------------------------------------------------- +C count "dense" columns (they are treated as a priori frontal matrices) +C----------------------------------------------------------------------- + +C a column is "dense" if it has more than dsiz entries + D1 = KEEP (7) + D2 = KEEP (8) + XN = N + XN = SQRT (XN) + N2 = XN + DSIZ = MAX (0, D1, D2 * N2) + DN = 0 + IF (PRESRV) THEN + IF (NBLKS .EQ. 1) THEN + DO 10 COL = 1, N + IF (AP (COL+1) - AP (COL) .GT. DSIZ) THEN +C this is a "dense" column + DN = DN + 1 + ENDIF +10 CONTINUE + ELSE + DO 40 COL = 1, N +C if col might be dense, check more carefully: + CDEG = AP (CPERM (COL) + 1)- AP (CPERM (COL)) + IF (CDEG .GT. DSIZ) THEN + CDEG = 0 + DO 20 P = AP (CPERM (COL)), AP (CPERM (COL) + 1) -1 + ROW = PR (AI (P)) + IF (ROW .GE. K1) THEN + CDEG = CDEG + 1 + IF (CDEG .GT. DSIZ) THEN +C this is a "dense" column, exit out of loop + DN = DN + 1 + GO TO 30 + ENDIF + ENDIF +20 CONTINUE +C loop exit label: +30 CONTINUE + ENDIF +40 CONTINUE + ENDIF + ELSE + DO 50 COL = 1, N + IF (CP (COL+1) - CP (COL) .GT. DSIZ) THEN +C this is a "dense" column + DN = DN + 1 + ENDIF +50 CONTINUE + ENDIF + +C----------------------------------------------------------------------- +C get size of workspaces to allocate from II +C----------------------------------------------------------------------- + +C workspaces: WiR (n), WiC (n), WpR (n), WpC (n), +C Wm (n), Head (n), Rp (n+dn), Wc (n+dn), Wr (n+dn), Wj (n) + IF (NBLKS .EQ. 1) THEN +C Rperm (1..n) is used as WiR (1..n), and +C Cperm (1..n) is used as WiC (1..n) in MA38FD + WRKSIZ = 8*N + 3*DN + ELSE + WRKSIZ = 10*N + 3*DN + ENDIF + +C----------------------------------------------------------------------- +C construct the expanded column-form of the matrix or the diag. block +C----------------------------------------------------------------------- + + IF (PRESRV) THEN + +C ------------------------------------------------------------- +C allocate space for wrksiz workspace and nz+cscal*n +C integers and nz reals for the expanded column-form matrix. +C ------------------------------------------------------------- + + CP1 = 1 + XP = 1 + IP = 1 + WRKSIZ + IF (NBLKS .EQ. 1) THEN + +C ---------------------------------------------------------- +C construct copy of entire matrix +C ---------------------------------------------------------- + + NZ = ANZ + IS = NZ + WRKSIZ + CSCAL*N + IUSE = IUSE + IS + XUSE = XUSE + NZ + INFO (18) = MAX (INFO (18), IUSE) + INFO (19) = MAX (INFO (19), IUSE) + INFO (20) = MAX (INFO (20), XUSE) + INFO (21) = MAX (INFO (21), XUSE) + IOUT = IS .GT. ISIZE + XOUT = NZ .GT. XSIZE + IF (IOUT .OR. XOUT) THEN +C error return, if not enough integer and/or real memory: + GO TO 9000 + ENDIF + + PC = IP + DO 70 COL = 1, N + CP (COL) = PC - WRKSIZ + CDEG = AP (COL+1) - AP (COL) + CLEN = CDEG + CSIZ = CDEG + CSCAL + II (PC) = CSIZ + II (PC+1) = CDEG + II (PC+5) = 0 + II (PC+6) = CLEN + II (PC+7) = 0 + II (PC+8) = 0 + II (PC+2) = XP + XP = XP + CDEG + PC = PC + CSCAL + P = AP (COL) + DO 60 I = 0, CDEG - 1 + II (PC + I) = AI (P + I) +60 CONTINUE + PC = PC + CDEG +70 CONTINUE + DO 80 P = 1, NZ + XX (P) = AX (P) +80 CONTINUE + + ELSE + +C ---------------------------------------------------------- +C construct copy of a single block in BTF form +C ---------------------------------------------------------- + +C check for memory usage during construction of block + DO 100 COL = 1, N + PC = IP + CP (COL) = PC - WRKSIZ + IP = IP + CSCAL + IOUT = IP .GT. ISIZE + IF (IOUT) THEN +C error return, if not enough integer memory: + GO TO 9000 + ENDIF + II (PC+2) = XP + CDEG = IP + DO 90 P = AP (CPERM (COL)), AP (CPERM (COL)+1)-1 + ROW = PR (AI (P)) + IF (ROW .GE. K1) THEN + IOUT = IP .GT. ISIZE + XOUT = XP .GT. XSIZE + IF (IOUT .OR. XOUT) THEN +C error return, if not enough memory + GO TO 9000 + ENDIF + II (IP) = ROW - K1 + 1 + XX (XP) = AX (P) + IP = IP + 1 + XP = XP + 1 + ELSE +C entry in off-diagonal part + NZOFF = NZOFF + 1 + ENDIF +90 CONTINUE + CDEG = IP - CDEG + CLEN = CDEG + CSIZ = CDEG + CSCAL + II (PC) = CSIZ + II (PC+1) = CDEG + II (PC+5) = 0 + II (PC+6) = CLEN + II (PC+7) = 0 + II (PC+8) = 0 +100 CONTINUE + + NZ = XP - 1 + IS = NZ + WRKSIZ + CSCAL*N + IUSE = IUSE + IS + XUSE = XUSE + NZ + INFO (18) = MAX (INFO (18), IUSE) + INFO (19) = MAX (INFO (19), IUSE) + INFO (20) = MAX (INFO (20), XUSE) + INFO (21) = MAX (INFO (21), XUSE) + + ENDIF + +C ------------------------------------------------------------- +C get memory usage for next call to MA38BD +C ------------------------------------------------------------- + + XRUSE = XRUSE + NZ + XRMAX = MAX (XRMAX, XRUSE) + + ELSE + +C ------------------------------------------------------------- +C allocate space for wrksiz workspace and additional cscal*n +C space for the expanded column-form of the matrix. +C ------------------------------------------------------------- + + CP1 = CP (1) + NZ = CP (N+1) - CP1 + PC = CP1 + WRKSIZ + (NZ+CSCAL*N) + IUSE = IUSE + WRKSIZ + CSCAL*N + INFO (18) = MAX (INFO (18), IUSE) + INFO (19) = MAX (INFO (19), IUSE) + IOUT = PC .GT. ISIZE+1 + IF (IOUT) THEN +C error return, if not enough integer memory: + GO TO 9000 + ENDIF + +C ------------------------------------------------------------- +C expand the column form in place and make space for workspace +C ------------------------------------------------------------- + + XP = NZ + 1 + IP = NZ + CSCAL*N + 1 + PEND = CP (N+1) + DO 120 COL = N, 1, -1 + PCOL = CP (COL) + DO 110 P = PEND-1, PCOL, -1 + PC = PC - 1 + II (PC) = II (P) +110 CONTINUE + PC = PC - CSCAL + CDEG = PEND - PCOL + CLEN = CDEG + PEND = PCOL + CSIZ = CDEG + CSCAL + IP = IP - CSIZ + CP (COL) = IP + II (PC) = CSIZ + II (PC+1) = CDEG + II (PC+5) = 0 + II (PC+6) = CLEN + II (PC+7) = 0 + II (PC+8) = 0 + XP = XP - CDEG + II (PC+2) = XP +120 CONTINUE + ENDIF + +C----------------------------------------------------------------------- +C factorize the expanded column-form, with allocated workspaces +C----------------------------------------------------------------------- + + XP = CP1 + IP = CP1 + WRKSIZ + + IF (NBLKS .EQ. 1) THEN + +C pass Rperm and Cperm as the WiR and WiC arrays in MA38FD: + CALL MA38FD (CP, NZ, N, 1, CPERM, RPERM, ITAIL, XTAIL, + $ XX (XP), XSIZE-XP+1, II (IP), ISIZE-IP+1, ICNTL, CNTL, + $ INFO, RINFO, .FALSE., IUSE, XUSE, + $ RPERM, CPERM, II (CP1), II (CP1+N), + $ II (CP1+2*N), II (CP1+3*N), II (CP1+4*N), II (CP1+5*N), + $ II (CP1+6*N+DN), II (CP1+7*N+2*DN), + $ DN, DSIZ, RMAX, CMAX, TOTNLU, XRMAX, XRUSE) + + ELSE + +C pass Cperm, Rperm, WiC and WiR as separate arrays, and +C change Cperm and Rperm from the BTF permutations to the +C final permutations (including BTF and numerical pivoting). + CALL MA38FD (CP, NZ, N, N, CPERM, RPERM, ITAIL, XTAIL, + $ XX (XP), XSIZE-XP+1, II (IP), ISIZE-IP+1, ICNTL, CNTL, + $ INFO, RINFO, .TRUE., IUSE, XUSE, + $ II (CP1), II (CP1+N), II (CP1+2*N), II (CP1+3*N), + $ II (CP1+4*N), II (CP1+5*N), II (CP1+6*N), II (CP1+7*N), + $ II (CP1+8*N+DN), II (CP1+9*N+2*DN), + $ DN, DSIZ, RMAX, CMAX, TOTNLU, XRMAX, XRUSE) + + ENDIF + + IF (INFO (1) .LT. 0) THEN +C error return, if error occured in MA38FD: + RETURN + ENDIF + +C----------------------------------------------------------------------- +C adjust tail pointers, and save pointer to numerical part of LU +C----------------------------------------------------------------------- + +C head = cp1 + IUSE = IUSE - WRKSIZ + ITAIL = ITAIL + IP - 1 + XTAIL = XTAIL + XP - 1 + II (ITAIL) = XTAIL + RETURN + +C======================================================================= +C Error return +C======================================================================= + +C error return label: +9000 CONTINUE + RETURN + END + + SUBROUTINE MA38FD (CP, NZ, N, PN, CPERM, RPERM, ITAIL, XTAIL, + * XX, XSIZE, II, ISIZE, ICNTL, CNTL, INFO, RINFO, PGIVEN, + * IUSE, XUSE, WIR, WIC, WPR, WPC, WM, HEAD, + * WJ, RP, WC, WR, DN, DSIZ, + * RMAX, CMAX, TOTNLU, XRMAX, XRUSE) + INTEGER XSIZE, ISIZE, ICNTL(20), INFO(40), PN, + * ITAIL, XTAIL, NZ, N, II(ISIZE), CP(N+1), DN, DSIZ, + * RPERM(PN), CPERM(PN), WIR(N), WIC(N), WPR(N), + * WPC(N), WM(N), HEAD(N), RP(N+DN), WC(N+DN), + * WR(N+DN), IUSE, XUSE, WJ(N), + * RMAX, CMAX, TOTNLU, XRMAX, XRUSE + LOGICAL PGIVEN + DOUBLE PRECISION XX(XSIZE), CNTL(10), RINFO(20) + +C=== MA38FD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C MA38FD factorizes the n-by-n input matrix at the head of II/XX +C (in expanded column-form) and places its LU factors at the tail of +C II/XX. The input matrix is overwritten. No BTF information is +C used in this routine, except that the BTF permutation arrays are +C modified to include the final permutations. + +C======================================================================= +C INPUT: +C======================================================================= +C +C Cp (1..n+1): column pointers of expanded column-form, +C undefined on output +C n: order of input matrix +C nz: entries in input matrix +C isize: size of II +C xsize: size of XX +C iuse: memory usage in Index +C xuse: memory usage in Value +C Icntl: integer control parameters, see MA38ID +C Cntl: real control parameters, see MA38ID +C Keep (6) integer control parameter, see MA38ID +C dn: number of dense columns +C dsiz: entries required for col to be treated as dense +C rmax: maximum ludegr seen so far (see below) +C cmax: maximum ludegc seen so far (see below) +C totnlu: total number of LU arrowheads constructed so far +C xrmax: maximum real memory usage for MA38BD +C xruse: current real memory usage for MA38BD +C +C pgiven: true if Cperm and Rperm are defined on input +C if pgiven then: +C Cperm (1..pn): col permutation to BTF, n = pn +C Rperm (1..pn): row permutation to BTF +C else +C Cperm (1..pn): unaccessed pn = 1 +C Rperm (1..pn): unaccessed +C +C II (1..nz+cscal*n): expanded column-form, see below +C II (nz+cscal*n+1..isize): undefined on input +C XX (1..nz): expanded column-form, see below +C XX (nz+1..xsize): undefined on input + +C======================================================================= +C WORKSPACE: +C======================================================================= +C +C WiR (1..n) +C WiC (1..n) +C WpR (1..n) +C WpC (1..n) +C Wm (1..n) +C Head (n) +C Rp (1..n+dn) +C Wr (1..n+dn) +C Wc (1..n+dn) + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C II (1..itail-1): undefined on output +C II (itail..isize): LU factors of this matrix, see below +C XX (1..xtail-1): undefined on output +C XX (xtail..xsize): LU factors of this matrix, see below +C +C Info: integer informational output, see MA38AD +C Rinfo: real informational output, see MA38AD +C if pgiven: +C Cperm (1..n): the final col permutations, including BTF +C Rperm (1..n): the final row permutations, including BTF +C +C WiC (1..n): row permutations, not including BTF +C WiR (1..n): column permutations, not including BTF +C +C iuse: memory usage in Index +C xuse: memory usage in Value +C rmax: maximum ludegr seen so far (see below) +C cmax: maximum ludegc seen so far (see below) +C totnlu: total number of LU arrowheads constructed so far +C xrmax: maximum real memory usage for MA38BD +C xruse: current real memory usage for MA38BD + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38ED +C subroutines called: MA38ND, MA38GD, DGEMV, DGEMM +C functions called: IDAMAX, ABS, MAX, MIN + INTEGER IDAMAX + INTRINSIC ABS, MAX, MIN + EXTERNAL MA38GD, MA38ND, DGEMM, DGEMV, IDAMAX + +C======================================================================= +C DESCRIPTION OF DATA STRUCTURES: +C======================================================================= + +C----------------------------------------------------------------------- +C Column/element/arrowhead pointers: +C----------------------------------------------------------------------- +C +C The Cp (1..n) array contains information about non-pivotal columns +C +C p = Cp (j) +C if (p = 0) then j is a pivotal column +C else i is a non-pivotal column +C +C The Rp (1..n) array contains information about non-pivotal rows, +C unassembled frontal matrices (elements), and the LU arrowheads +C +C p = Rp (i) +C if (i > n) then +C i is an artificial frontal matrix (a dense column) +C if (p = 0) then i is assembled, else unassembled +C else if (p = 0) then i is pivotal but not element/arrowhead +C else if (Wc (i) >= 0 and Wc (i) <= n) then +C i is a non-pivotal row +C else if (Wc (i) = -(n+dn+2)) then +C i is a pivotal row, an assembled element, and an LU arrowhead +C else i an unassembled element + +C----------------------------------------------------------------------- +C Matrix being factorized: +C----------------------------------------------------------------------- +C +C Each column is stored in II and XX: +C ----------------------------------- +C +C if j is a non-pivotal column, pc = Cp (j): +C +C csiz = II (pc) size of the integer data structure for col j, +C including the cscal scalars +C cdeg = II (pc+1) degree of column j +C cxp = II (pc+2) pointer into XX for numerical values +C next = II (pc+3) pointer to next block of memory in XX +C prev = II (pc+4) pointer to previous block of memory in XX +C celn = II (pc+5) number of elements in column j element list +C clen = II (pc+6) number of original entries in column j +C cnxt = II (pc+7) next column with same degree as col j +C cprv = II (pc+8) previous column with same degree as col j +C cep = (pc+9) pointer to start of the element list +C II (cep ... cep + 2*celn - 1) +C element list (e,f) for the column +C II (cep + 2*celn ... pc + csiz - clen - 1) +C empty +C II (pc + csiz - clen ... pc + csiz - 1) +C row indices of original nonzeros in the column +C XX (xp ... xp + clen - 1) +C numerical values of original nonzeros in the col +C +C if cdeg = II (pc+1) = -(n+2), then this is a singular column +C if cdeg = -1, then this column is deallocated +C +C Each row is stored in II only: +C ------------------------------ +C +C if i is a non-pivotal row, pr = Rp (i) +C +C rsiz = II (pr) size of the integer data structure for row i, +C including the rscal scalars +C rdeg = II (pr+1) degree of row i +C reln = Wr (i) number of elements in row i element list +C rlen = Wc (i) number of original entries in row i +C rep = (pr+2) pointer to start of the element list +C II (rep ... rep + 2*reln - 1) +C element list (e,f) for the row +C II (rep + 2*reln ... pr + rsiz - rlen - 1) +C empty +C II (pr + rsiz - rlen ... pr + rsiz - 1) +C column indices of original nonzeros in the row +C +C if rdeg = -1, then this row is deallocated + +C----------------------------------------------------------------------- +C Frontal matrices +C----------------------------------------------------------------------- +C +C Each unassembled frontal matrix (element) is stored as follows: +C total size: fscal integers, (fdimr*fdimc) reals +C +C if e is an unassembled element, ep = Rp (e), and e is also +C the first pivot row in the frontal matrix. +C +C fluip = II (ep) pointer to LU arrowhead in II +C fdimc = II (ep+1) column dimension of contribution block +C fxp = II (ep+2) pointer to contribution block in XX +C next = II (ep+3) pointer to next block in XX +C prev = II (ep+4) pointer to previous block in XX +C fleftr = II (ep+5) number of unassembled rows +C fleftc = II (ep+6) number of unassembled columns +C fextr = Wr (e) - w0 external row degree of the frontal mtx +C fextc = Wc (e) - w0 external col degree of the frontal mtx +C XX (fxp ... ) +C a 2-dimensional array, C (1..fdimc, 1..fdimr). +C note that fdimr is not kept (it is not needed, +C except for the current frontal). If this is not the +C current frontal matrix, then luip points to the +C corresponding LU arrowhead, and the contribution block +C is stored in C (1..ludegc, 1..ludegr) in the +C C (1..fdimc, ...) array. +C +C If memory is limited, garbage collection will occur. +C In this case, the C (1..fdimc, 1..fdimr) array is +C compressed to be just large enough to hold the +C unassembled contribution block, +C C (1..ludegc, 1..ludegr). + +C----------------------------------------------------------------------- +C Artificial frontal matrices +C----------------------------------------------------------------------- +C +C An artificial frontal matrix is an original column that is treated +C as a c-by-1 frontal matrix, where c is the number of original +C nonzeros in the column. Dense columns (c > dsiz) are treated this +C way. An artificial frontal matrix is just the same as a frontal +C matrix created by the elimination of one or more pivots, except +C that there is no corresponding LU arrowhead. The row and column +C patterns are stored in: +C +C ep = Rp (e), where e = n+1 .. n+dn, where there are dn +C artificial frontal matrices. +C +C lucp = (ep+9) pointer to row pattern (just one column index) +C lurp = (ep+8) pointer to column pattern (fdimc row indices) + +C----------------------------------------------------------------------- +C Current frontal matrix +C----------------------------------------------------------------------- +C +C ffxp points to current frontal matrix (contribution block and LU +C factors). For example, if fflefc = 4, fflefr = 6, k = 3, and +C gro = 2.0, then "x" is a term in the contribution block, "l" in L1, +C "u" in U1, "L" in L2, "U" in U2, and "." is unused. XX (fxp) is "X". +C The first 3 pivot values (diagonal entries in U1) are 1,2, and 3. +C For this frontal matrix, ffdimr = 12 (the number of columns), and +C ffdimc = 8 (the number of rows). The frontal matrix is +C ffdimc-by-ffdimr +C +C |----------- col 1 of L1 and L2, etc. +C V +C X x x x x x . . . L L L +C x x x x x x . . . L L L +C x x x x x x . . . L L L +C x x x x x x . . . L L L +C . . . . . . . . . . . . +C U U U U U U . . . 3 l l <- row 3 of U1 and U2 +C U U U U U U . . . u 2 l <- row 2 of U1 and U2 +C U U U U U U . . . u u 1 <- row 1 of U1 and U2 + +C----------------------------------------------------------------------- +C LU factors +C----------------------------------------------------------------------- +C +C The LU factors are placed at the tail of II and XX. If this routine +C is factorizing a single block, then this decription is for the +C factors of the single block: +C +C II (itail): xtail = start of LU factors in XX +C II (itail+1): nlu = number of LU arrowheads +C II (itail+2): npiv = number of pivots +C II (itail+3): maximum number of rows in any +C contribution block (max ludegc) +C II (itail+4): maximum number of columns in any +C contribution block (max ludegr) +C II (itail+5..itail+nlu+4): LUp (1..nlu) array, pointers to each +C LU arrowhead, in order of their +C factorization +C II (itail+nlu+5...isize):integer info. for LU factors +C XX (xtail..xsize): real values in LU factors +C +C Each LU arrowhead is stored as follows: +C --------------------------------------- +C +C total size: (7 + ludegc + ludegr + nsons) integers, +C (luk**2 + ludegc*luk + luk*ludegc) reals +C +C If e is an LU arrowhead, then luip = Rp (e), and luip >= itail. +C When MA38FD returns, then luip is given by luip = +C II (itail+s+1), where s = 1..nlu is the position of the LU +C arrowhead in the LU factors (s=1,2,.. refers to the first, +C second,.. LU arrowhead) +C +C luxp = II (luip) pointer to numerical LU arrowhead +C luk = II (luip+1) number of pivots in LU arrowhead +C ludegr = II (luip+2) degree of last row of U (excl. diag) +C ludegc = II (luip+3) degree of last col of L (excl. diag) +C nsons = II (luip+4) number of children in assembly DAG +C ludimr = II (luip+5) +C ludimc = II (luip+5) max front size is ludimr-by-ludimc, +C or zero if this LU arrowhead factorized within +C the frontal matrix of a prior LU arrowhead. +C lucp = (luip + 7) +C pointer to pattern of column of L +C lurp = lucp + ludegc +C pointer to patter of row of U +C lusonp = lurp + ludegr +C pointer to list of sons in the assembly DAG +C II (lucp ... lucp + ludegc - 1) +C row indices of column of L +C II (lurp ... lurp + ludegr - 1) +C column indices of row of U +C II (lusonp ... lusonp + nsons - 1) +C list of sons +C XX (luxp...luxp + luk**2 + ludegc*luk + luk*ludegr - 1) +C pivot block (luk-by-luk) and the L block +C (ludegc-by-luk) in a single (luk+ludegc)-by-luk +C array, followed by the U block in a +C luk-by-ludegr array. +C +C Pivot column/row pattern (also columns/rows in contribution block): +C If the column/row index is negated, the column/row has been +C assembled out of the frontal matrix into a subsequent frontal +C matrix. After factorization, the negative flags are removed, +C and the row/col indices are replaced with their corresponding +C index in the permuted LU factors. +C +C List of sons: +C 1 <= son <= n: son an LUson +C n+1 <= son <= 2n: son-n is an Uson +C 2n+n <= son <= 3n: son-2n is a Lson +C during factorzation, a son is referred to by its first +C pivot column. After factorization, they are numbered according +C to their order in the LU factors. + +C----------------------------------------------------------------------- +C Workspaces: +C----------------------------------------------------------------------- +C +C WiR (e): link list of sons of the current element +C WiR (e) = -1 means that e is not in the list. +C WiR (e) = next+n+2 means that "next" is the element after e. +C The end of the list is marked with WiR (e) = -(n+2). +C sonlst points to the first element in the list, or 0 if +C the sonlst is empty. +C +C WiR (row), WiC (col): used for pivot row/col offsets: +C +C If WiR (row) >= 0 then the row is in the current +C column pattern. Similarly for WiC (col). +C +C If WiR (row) is set to "empty" (<= -1), then +C the row is not in the current pivot column pattern. +C +C Similarly, if WiC (col) is set to -2, then the column is +C not in the current pivot row pattern. +C +C If WiC (col) = -1 then col is pivotal +C +C After factorization, WiR/C holds the pivot permutations. +C +C WpR/C (1..n): the first part is used for the current frontal +C matrix pattern. During factorization, the last part holds +C a stack of the row and column permutations (WpR/C (n-k+1) +C is the k-th pivot row/column). +C +C Head (1..n): degree lists for columns. Head (d) is the +C first column in list d with degree d. +C The cnxt and cprv pointers are stored in the +C column data structure itself. +C mindeg is the least non-empty list +C +C Wm (1..n): various uses +C Wj (1..degc) or Wj (1..fdegc): offset in pattern of a son + +C----------------------------------------------------------------------- +C Memory allocation in II and XX: +C----------------------------------------------------------------------- +C +C II (1..ihead): rows and columns of active submatrix, and +C integer information for frontal matrices. +C XX (1..xhead): values of original entries in columns of +C matrix, values of contribution blocks, followed +C by the current frontal matrix. +C +C mhead: a pointer to the first block in the head of +C XX. Each block (a column or frontal matrix) +C contains a next and prev pointer for this list. +C If the list is traversed starting at mhead, +C then the pointers to the reals (cxp or fxp) +C will appear in strictly increasing order. +C Note that the next, prev, and real pointers +C are in II. next and prev point to the next +C and previous block in II, and the real pointer +C points to the real part in XX. +C +C mtail: the end of the memory list. + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER SWPCOL, SWPROW, FDIMC, K0, COLPOS, ROWPOS, ROW2, RDEG2, + $ P, I, J, FFROW, PIVROW, PIVCOL, LUDEGR, LUDEGC, E1, + $ FXP, LURP, LUCP, IP, NEXT, FFLEFR, PC, MNEXT, MPREV, + $ FFLEFC, FEDEGR, FEDEGC, K, XUDP, XDP, XSP, XLP, S, COL2, + $ BESTCO, COL, E, ROW, COST, SRCHED, PR, F1, RSCAN, REP, + $ KLEFT1, FFSIZE, FFXP, W0, FFDIMR, FFDIMC, KLEFT, XLDP, + $ EP, SCAN1, SCAN2, SCAN3, SCAN4, NZL, NZU, DEGC, CEP + INTEGER MINDEG, NSRCH, NPIV, ESON, LUIP1, DNZ, IWORST, WXP, + $ NB, LUPP, NLU, NSONS, INEED, XNEED, LDIMC, LXP, RLEN2, + $ RSIZ, LSONS, SONLST, XHEAD, IHEAD, DELN, DLEN, + $ SLIST, XP, LUIP, RDEG, CDEG1, PFREE, XFREE, CDEG2, + $ F, CDEG, MTAIL, MHEAD, RSIZ2, CSIZ2, IP2, MAXDR, MAXDC, + $ XS, IS, LUXP, FSP, FLP, FDP, JJ, USONS, NDN, P2, + $ CSIZ, CELN, CLEN, RELN, RLEN, UXP, PC2, PR2 + INTEGER CNXT, CPRV, CXP, FLUIP, LUSONP, FLEFTR, FLEFTC, + $ FMAXR, FMAXC, SLOTS, LIMIT, RSCAL, CSCAL, FSCAL, EXTRA, + $ FMAX, MINMEM, DUMMY1, DUMMY2, DUMMY3, DUMMY4, W1 + LOGICAL SYMSRC, PFOUND, MOVELU, OKCOL, OKROW, BETTER + DOUBLE PRECISION + $ TOLER, MAXVAL, RELPT, GRO, ONE, ZERO, X + PARAMETER (ONE = 1.0D0, ZERO = 0.0D0, + $ RSCAL = 2, CSCAL = 9, FSCAL = 7, + $ MINMEM = 24) + INTEGER INTZER + +C Current element and working array, C: +C ------------------------------------- +C ffxp: current working array is in XX (ffxp ... ffxp+ffsize-1) +C ffsize: size of current working array in XX +C ffdimr: row degree (number of columns) of current working array +C ffdimc: column degree (number of rows) of current working array +C fflefr: row degree (number of columns) of current contribution block +C fflefc: column degree (number of rows) of current contribution block +C fmaxr: max row degree (maximum front size is fmaxr-by-fmaxc) +C fmaxc: max col degree (maximum front size is fmaxr-by-fmaxc) +C fedegr: extended row degree +C fedegc: extended column degree +C ffrow: current element being factorized (a pivot row index) +C pivrow: current pivot row index +C pivcol: current pivot column index +C e1: first pivot row in the frontal matrix +C gro: frontal matrix amalgamation growth factor +C usons: pointer to a link list of Usons, in Wc, assembled this SCAN3 +C lsons: pointer to a link list of Lsons, in Wr, assembled this SCAN4 +C sonlst: pointer to a link list of sons, in WiR, of current element +C swpcol: the non-pivotal column to be swapped with pivot column +C swprow: the non-pivotal row to be swapped with pivot row +C colpos: position in WpR of the pivot column +C rowpos: position in WpC of the pivot row +C k: current pivot is kth pivot of current element +C k0: contribution block, C, has been updated with pivots 1..k0 +C +C LU arrowhead (a factorized element): +C ------------------------------------ +C movelu: true if a new LU arrowhead is to be created +C luip: current element is in II (luip ...) +C luip1: first element from current frontal matrix in II (luip1...) +C ludegc: degree of pivot column (excluding pivots themselves) +C ludegr: degree of pivot row (excluding pivots themselves) +C lucp: pattern of col(s) of current element in II (lucp...) +C lurp: pattern of row(s) of current element in II (lurp...) +C lusonp: list of sons of current element is in II (lusonp...) +C nsons: number of sons of current element +C ldimc: column dimension (number of rows) of [L1\U1 L2] block +C luxp: numerical values of LU arrowhead stored in XX (luxp ...) +C lxp: L2 block is stored in XX (lxp ...) when computed +C uxp: U2 block is stored in XX (uxp ...) when computed +C nzu: nonzeros above diagonal in U in current LU arrowhead +C nzl: nonzeros below diagonal in L in current LU arrowhead +C +C Son, or element other than current element: +C ------------------------------------------- +C e: an element +C eson: an element +C s: a renumbered element (1..nlu) for MA38CD and MA38BD +C ep: frontal matrix integer data struct. in II (ep...ep+fscal-1) +C fscal: = 7, size of frontal matrix data structure +C fluip: LU arrowhead of e is in II (fluip ...) +C fxp: contribution block of son is in XX (fxp ...) +C fdimc: leading dimension of contribution block of e +C lucp: pattern of col(s) of e in II (lucp...) +C lurp: pattern of row(s) of e in II (lurp...) +C ludegr: row degree of contribution block of e +C ludegr: column degree of contribution block of e +C maxdr: maximum ludegr for any LU arrowhead, for MA38BD +C maxdc: maximum ludegc for any LU arrowhead, for MA38BD +C degc: compressed column offset vector of son is in Wj/Wm (1..degc) +C fleftr: remaining row degree (number of columns) of a contrib. block +C fleftc: remaining column degree (number of rows) of a contrib. block +C xudp: pointer to a column of a prior contribution block +C xldp: pointer to a row of a prior contribution block +C +C Memory allocation: +C ------------------ +C mhead: head pointer for link list of blocks in XX +C mtail: tail pointer for link list of blocks in XX +C mprev: previous block, II (p+4), of the block located at p +C mnext: next block, II (p+3), of the block located at p +C pfree: II (pfree+2) is the largest known free block in XX +C xfree: size of largest known free block in XX +C xhead: XX (1..xhead-1) is in use, XX (xhead ..xtail-1) is free +C xtail: XX (xtail..xsize) is in use, XX (xhead ..xtail-1) is free +C xneed: bare minimum memory currently needed in XX +C ihead: II (1..ihead-1) is in use, II (ihead ..itail-1) is free +C itail: II (itail..isize) is in use, II (ihead ..itail-1) is free +C ineed: bare minimum memory currently needed in II +C iworst: worst possible current integer memory required +C xs: size of a block of memory in XX +C is: size of a block of memory in II +C wxp: pointer to a temporary workspace in XX (wxp ... ) +C slots: number of slots added to element lists during garbage coll. +C minmem: smallest isize allowed +C +C Wr and Wc flag arrays: +C ---------------------- +C w0: marker value for Wr (1..n) and Wc (1..n) arrays +C w1: used to test for possible integer overflow in flags +C fmax: largest row/col degree of an element seen so far +C +C A column: +C --------- +C pc: pointer to a column, in II (pc...) +C pc2: pointer to a column, in II (pc2...) +C csiz: size of integer data structure of a column +C csiz2: size of integer data structure of a column +C cscal: = 9, number of scalars in data structure of a column +C cdeg: degree of a column +C cdeg1: degree of a column +C cdeg2: degree of a column +C celn: number of elements in the element list of a column +C clen: number of original entries that remain in a column +C cnxt: next column with same degree as this column +C cprv: previous column with same degree as this column +C cep: pointer to the element list of a column +C cxp: pointer to the numerical values in a column +C limit: maximum size for row/col data structure (excl. scalars) +C +C Dense columns: +C -------------- +C dnz: number of original entries that reside in "dense" columns +C dn: number of "dense" columns +C ndn: n + dn +C extra: number of extra slots to add to reconstructed "dense" cols +C +C A row: +C ------ +C pr: pointer to a row, in II (pr...) +C pr2: pointer to a row, in II (pr2...) +C rsiz: size of integer data structure of a row +C rsiz2: size of integer data structure of a row +C rscal: = 2, number of scalars in data structure of a row +C rdeg: degree of a row +C rdeg2: degree of a row +C reln: number of elements in the element list of a row +C rlen: number of original entries that remain in a row +C rlen2: number of original entries that remain in a row +C rep: pointer to the element list of a row +C +C Pivot search: +C ------------- +C cost: approximate Markowitz-cost of the current candidate pivot +C bestco: best approximate Markowitz-cost seen so far +C srched: number of non-singular candidates searched so far +C mindeg: minimum degree of columns in active submatrix +C nsrch: maximum number of columns to search +C slist: pointer to a link list of searched columns, in II +C symsrc: true if attempting to preserve symmetry +C pfound: true if pivot found during local search +C okcol: true if candidate pivot column is acceptable, so far +C okrow: true if candidate pivot row is acceptable, so far +C toler: pivot tolerance; abs(pivot) must be >= toler +C maxval: maximum absolute value in a candidate pivot column +C relpt: relative pivot tolerance (Cntl (1)) +C npiv: number of pivots factorized so far, incl. current element +C kleft: number of rows/columns remaining in active submatrix +C kleft1: kleft - 1 +C better: if true, then candidate is better than the prior candidate +C +C Assembly: +C --------- +C f1: degree prior to assembly next item +C f: offset into an element +C rscan: skip row assembly if more than rscan original entries +C scan1: start SCAN1 at WpC (scan1 ... fflefc) +C scan2: start SCAN2 at WpR (scan2 ... fflefr) +C scan3: start SCAN3 at WpR (scan3 ... fflefr) +C scan4: start SCAN4 at WpC (scan4 ... fflefc) +C deln: number of (e,f) tuples to delete from an element list +C dlen: number of original entries to delete from a row/col +C +C Allocated arrays: +C ----------------- +C lupp: LUp (1..nlu) array located in II (lupp...lupp+nlu-1) +C nlu: number of LU arrowheads +C +C Other: +C ------ +C xdp: destination pointer, into XX +C xsp: source pointer, into XX +C xlp: pointer into XX of location of last row/col in C +C xp: pointer into XX +C ip: pointer into II +C ip2: pointer into II +C p2: pointer into II +C fsp: source pointer, into XX +C fsp: destination pointer, into XX +C flp: last row/column in current contribution is in XX (flp...) +C col,col2: a column index +C row,row2: a row index +C nb: block size for tradeoff between Level-2 and Level-3 BLAS +C p, i, j, k, x: various uses +C jj: loop index +C next: next pointer, for a link list +C dummy1: dummy loop index for main factorization loop +C dummy2: dummy loop index for global pivot search loop +C dummy3: dummy loop index for outer frontal matrix factorization loop +C dummy4: dummy loop index for inner frontal matrix factorization loop + +C======================================================================= +C EXECUTABLE STATEMENTS: +C======================================================================= + +C ---------------------------------------------------------------- +C get control parameters and initialize various scalars +C ---------------------------------------------------------------- + + NSRCH = MAX (1, ICNTL (5)) + SYMSRC = ICNTL (6) .NE. 0 + NB = MAX (1, ICNTL (7)) + RELPT = MAX (ZERO, MIN (CNTL (1), ONE)) + GRO = MAX (ONE, CNTL (2)) + NDN = N + DN + W0 = NDN + 2 +C currently: w0 = n+dn+2 < 2n+2 + KLEFT = N + NPIV = 0 + NLU = 0 + MINDEG = 1 + FMAX = 1 + IHEAD = NZ + CSCAL*N + 1 + XHEAD = NZ + 1 + ITAIL = ISIZE + 1 + XTAIL = XSIZE + 1 +C Cp (1) must equal 1, the first block + XFREE = -1 + PFREE = 0 +C make sure integer space is at least of size minmem (simplifies +C link list management and memory management) + INFO (19) = MAX (INFO (19), IUSE+MINMEM) + IF (IHEAD.GT.ITAIL.OR.ISIZE.LT.MINMEM.OR.XHEAD.GT.XTAIL) THEN +C error return, if not enough integer and/or real memory: + GO TO 9000 + ENDIF + BESTCO = 0 + LIMIT = N + 2*NDN + LSONS = NDN + 1 + USONS = NDN + 1 + +C ---------------------------------------------------------------- +C initialize workspaces +C ---------------------------------------------------------------- + + DO 10 I = 1, N + WIR (I) = -1 + WIC (I) = -2 + HEAD (I) = 0 + WC (I) = 0 + WR (I) = 0 +10 CONTINUE + +C ---------------------------------------------------------------- +C initialize the link list for keeping track of real memory usage +C ---------------------------------------------------------------- + + MHEAD = 0 + MTAIL = 0 + DO 20 COL = 1, N + PC = CP (COL) + CLEN = II (PC+6) + IF (CLEN .GT. 0) THEN +C place the column in the link list of blocks in XX + IF (MHEAD .EQ. 0) MHEAD = PC + II (PC+4) = MTAIL + II (PC+3) = 0 + IF (MTAIL .NE. 0) II (MTAIL+3) = PC + MTAIL = PC + ELSE + II (PC+2) = 0 + II (PC+4) = 0 + II (PC+3) = 0 + ENDIF +20 CONTINUE + +C ---------------------------------------------------------------- +C convert dense columns to a-priori contribution blocks and +C get the count of nonzeros in each row +C ---------------------------------------------------------------- + + E = N + DNZ = 0 + DO 50 COL = 1, N + PC = CP (COL) + CLEN = II (PC+6) + CEP = (PC+9) + IF (CLEN .GT. DSIZ) THEN +C this is a dense column - add to element list length + DNZ = DNZ + CLEN + DO 30 IP = CEP, CEP + CLEN - 1 + ROW = II (IP) + WR (ROW) = WR (ROW) + 1 +30 CONTINUE +C convert dense column (in place) into a frontal matrix + E = E + 1 + EP = PC + RP (E) = EP + FDIMC = CLEN + FLEFTC = CLEN + FLEFTR = 1 + II (EP+1) = FDIMC + II (EP+5) = FLEFTR + II (EP+6) = FLEFTC + WR (E) = W0-1 + WC (E) = W0-1 + LURP = (EP+8) + II (LURP) = COL + FMAX = MAX (FMAX, FLEFTC) + ELSE +C this is a sparse column - add to orig entry length + DO 40 IP = CEP, CEP + CLEN - 1 + ROW = II (IP) + WC (ROW) = WC (ROW) + 1 +40 CONTINUE + ENDIF +50 CONTINUE + +C ---------------------------------------------------------------- +C get memory for row-oriented form, and dense column element lists +C ---------------------------------------------------------------- + + PR = IHEAD + CSIZ = CSCAL + 2 + IS = (NZ + RSCAL*N + DNZ) + (DN * CSIZ) + IHEAD = IHEAD + IS + IUSE = IUSE + IS + INEED = IUSE + XNEED = XUSE + INFO (18) = MAX (INFO (18), IUSE) + INFO (19) = MAX (INFO (19), INEED) + IF (IHEAD .GT. ITAIL) THEN +C error return, if not enough integer memory: + GO TO 9000 + ENDIF + +C ---------------------------------------------------------------- +C if memory is available, add up to dsiz+6 extra slots in the +C reconstructed dense columns to allow for element list growth +C ---------------------------------------------------------------- + + IF (DN .GT. 0) THEN + EXTRA = MIN ((ITAIL - IHEAD) / DN, DSIZ + 6) + CSIZ = CSIZ + EXTRA + IS = DN * EXTRA + IHEAD = IHEAD + IS + IUSE = IUSE + IS + INFO (18) = MAX (INFO (18), IUSE) + ENDIF + +C ---------------------------------------------------------------- +C construct row pointers +C ---------------------------------------------------------------- + + DO 60 ROW = 1, N + RP (ROW) = PR + REP = (PR+2) + RELN = WR (ROW) + RLEN = WC (ROW) + RSIZ = 2*RELN + RLEN + RSCAL + II (PR) = RSIZ + RDEG = RELN + RLEN + II (PR+1) = RDEG + WM (ROW) = REP + PR = PR + RSIZ +60 CONTINUE + +C ---------------------------------------------------------------- +C construct row element lists for dense columns +C ---------------------------------------------------------------- + + PC = PR + DO 80 E = N+1, N+DN + EP = RP (E) + LUCP = (EP+9) + FDIMC = II (EP+1) +CFPP$ NODEPCHK L + DO 70 F = 0, FDIMC - 1 + ROW = II (LUCP+F) + II (WM (ROW) ) = E + II (WM (ROW) + 1) = F + WM (ROW) = WM (ROW) + 2 +70 CONTINUE +C re-construct dense columns as just an element list, +C containing a single element tuple (e,f), where f = 0 + LURP = (EP+8) + COL = II (LURP) + CP (COL) = PC + II (PC) = CSIZ + CDEG = FDIMC + II (PC+1) = CDEG + II (PC+2) = 0 + II (PC+4) = 0 + II (PC+3) = 0 + II (PC+5) = 1 + II (PC+6) = 0 + II (PC+7) = 0 + II (PC+8) = 0 +C store the (e,0) tuple: + CEP = (PC+9) + II (CEP ) = E + II (CEP+1) = 0 + PC = PC + CSIZ +80 CONTINUE + +C ---------------------------------------------------------------- +C construct the nonzero pattern of the row-oriented form +C ---------------------------------------------------------------- + + DO 100 COL = 1, N + PC = CP (COL) + CEP = (PC+9) + CLEN = II (PC+6) +CFPP$ NODEPCHK L + DO 90 P = CEP, CEP + CLEN - 1 + ROW = II (P) + II (WM (ROW)) = COL + WM (ROW) = WM (ROW) + 1 +90 CONTINUE +100 CONTINUE + +C count the numerical assembly of the original matrix + RINFO (2) = RINFO (2) + NZ + +C ---------------------------------------------------------------- +C initialize the degree lists +C ---------------------------------------------------------------- + +C do so in reverse order to try to improve pivot tie-breaking + DO 110 COL = N, 1, -1 + PC = CP (COL) + CDEG = II (PC+1) + IF (CDEG .LE. 0) THEN +C empty column - remove from pivot search + CDEG = -(N+2) + II (PC+1) = CDEG + ELSE + CNXT = HEAD (CDEG) + II (PC+7) = CNXT + II (PC+8) = 0 + IF (CNXT .NE. 0) II (CP (CNXT)+8) = COL + HEAD (CDEG) = COL + ENDIF +110 CONTINUE + +C======================================================================= +C======================================================================= +C MAIN FACTORIZATION LOOP [ +C======================================================================= +C======================================================================= + + DO 1540 DUMMY1 = 1, N +C (this loop is not indented due to its length) + +C ---------------------------------------------------------------- +C factorization is done if N pivots have been found +C ---------------------------------------------------------------- + + IF (NPIV .GE. N) THEN + GO TO 2000 + ENDIF + +C======================================================================= +C Global pivot search, and initialization of a new frontal matrix [ +C======================================================================= + + IF (MTAIL .NE. 0 .AND. II (MTAIL+6) .EQ. 0) THEN +C tail block is free, delete it + XP = II (MTAIL+2) + XUSE = XUSE - (XHEAD - XP) + XHEAD = XP + IF (MTAIL .EQ. PFREE) THEN + PFREE = 0 + XFREE = -1 + ENDIF + MTAIL = II (MTAIL+4) + IF (MTAIL .NE. 0) THEN + II (MTAIL+3) = 0 + ELSE +C singular matrix. No columns or contribution blocks left. + MHEAD = 0 + ENDIF + ENDIF + +C======================================================================= +C Global pivot search: find pivot row and column +C======================================================================= + + NSONS = 0 + SONLST = 0 + SRCHED = 0 + PIVCOL = 0 + SLIST = 0 + + DO 255 DUMMY2 = 1, N + +C ------------------------------------------------------------- +C get col from column upper-bound degree list +C ------------------------------------------------------------- + + COL = 0 + DO 140 CDEG = MINDEG, N + COL = HEAD (CDEG) + IF (COL .NE. 0) THEN +C exit out of loop if column found: + GO TO 150 + ENDIF +140 CONTINUE + IF (COL .EQ. 0) THEN +C exit out of loop if column not found (singular matrix): + GO TO 260 + ENDIF +C loop exit label: +150 CONTINUE + PC = CP (COL) + CNXT = II (PC+7) + IF (CNXT .NE. 0) THEN + II (CP (CNXT)+8) = 0 + ENDIF + HEAD (CDEG) = CNXT + MINDEG = CDEG + +C ------------------------------------------------------------- +C construct candidate column in Wm and XX (wxp..wxp+cdeg-1) +C ------------------------------------------------------------- + + XS = CDEG +C use Wm (1..cdeg) for pattern [ +C use XX (wxp..wxp+xs-1) as workspace for values [ + + IF (XS .GT. XTAIL-XHEAD) THEN + + INFO (15) = INFO (15) + 1 + INTZER = 0 + CALL MA38GD (XX, XSIZE, XHEAD, XUSE, + $ II, ISIZE, IHEAD, IUSE, + $ CP, RP, DN, N, WIR, WIC, WR, WC, + $ INTZER, INTZER, INTZER, INTZER, .FALSE., + $ PFREE, XFREE, MHEAD, MTAIL, SLOTS) +C at this point, iuse = ineed and xuse = xneed + PC = CP (COL) + ENDIF + + WXP = XHEAD + XHEAD = XHEAD + XS + XUSE = XUSE + XS + XNEED = XNEED + XS + INFO (20) = MAX (INFO (20), XUSE) + INFO (21) = MAX (INFO (21), XNEED) + IF (XHEAD .GT. XTAIL) THEN +C error return, if not enough real memory: + GO TO 9000 + ENDIF + +C ------------------------------------------------------------- +C assemble the elements in the element list +C ------------------------------------------------------------- + + CDEG = 0 + CEP = (PC+9) + CELN = II (PC+5) + DO 190 IP = CEP, CEP + 2*CELN - 2, 2 + E = II (IP) + F = II (IP+1) + EP = RP (E) + FDIMC = II (EP+1) + FXP = II (EP+2) + IF (E .LE. N) THEN + FLUIP = II (EP) + LUDEGC = II (FLUIP+3) + LUCP = (FLUIP + 7) + ELSE + LUDEGC = FDIMC + LUCP = (EP+9) + ENDIF + XP = FXP + F * FDIMC +C split into 3 loops so that they all vectorize on a CRAY + CDEG1 = CDEG + DO 160 P = LUCP, LUCP + LUDEGC - 1 + ROW = II (P) + IF (ROW .GT. 0) THEN + IF (WIR (ROW) .LE. 0) THEN + CDEG = CDEG + 1 + WM (CDEG) = ROW + ENDIF + ENDIF +160 CONTINUE + DO 170 I = CDEG1+1, CDEG + ROW = WM (I) + WIR (ROW) = I + XX (WXP+I-1) = ZERO +170 CONTINUE +CFPP$ NODEPCHK L + DO 180 J = 0, LUDEGC - 1 + ROW = II (LUCP+J) + IF (ROW .GT. 0) THEN + XX (WXP + WIR (ROW) - 1) = + $ XX (WXP + WIR (ROW) - 1) + XX (XP+J) + ENDIF +180 CONTINUE +190 CONTINUE + +C ------------------------------------------------------------- +C assemble the original entries in the column +C ------------------------------------------------------------- + + CDEG1 = CDEG + CLEN = II (PC+6) + CSIZ = II (PC) + IP = PC + CSIZ - CLEN + CXP = II (PC+2) +CFPP$ NODEPCHK L + DO 200 I = 0, CLEN - 1 + ROW = II (IP+I) + WM (CDEG+1+I) = ROW + XX (WXP+CDEG+I) = XX (CXP+I) +200 CONTINUE + CDEG = CDEG + CLEN + +C ------------------------------------------------------------- +C update the degree of this column (exact, not upper bound) +C ------------------------------------------------------------- + + II (PC+1) = CDEG + +C Wm (1..cdeg) holds the pattern of col being searched. +C XX (wxp..wxp+cdeg-1) holds the numerical values of col being +C searched. WiR (Wm (1..cdeg1)) is 1..cdeg1. + +C ------------------------------------------------------------- +C find the maximum absolute value in the column +C ------------------------------------------------------------- + + MAXVAL = ABS (XX (WXP - 1 + IDAMAX (CDEG, XX (WXP), 1))) + RINFO (3) = RINFO (3) + CDEG + TOLER = RELPT * MAXVAL + RDEG = N+1 + +C ------------------------------------------------------------- +C look for the best possible pivot row in this column +C ------------------------------------------------------------- + + IF (CDEG .NE. 0 .AND. MAXVAL .GT. ZERO) THEN + IF (SYMSRC) THEN +C prefer symmetric pivots, if numerically acceptable + ROW = COL + ROWPOS = WIR (ROW) + IF (ROWPOS .LE. 0) THEN +C diagonal may be in original entries + DO 210 I = CDEG1 + 1, CDEG1 + CLEN + IF (WM (I) .EQ. ROW) THEN + ROWPOS = I +C exit out of loop if symmetric pivot found: + GO TO 220 + ENDIF +210 CONTINUE +C loop exit label: +220 CONTINUE + ENDIF + IF (ROWPOS .GT. 0) THEN +C diagonal entry exists in the column pattern + X = ABS (XX (WXP-1+ROWPOS)) + IF (X .GE. TOLER .AND. X .GT. ZERO) THEN +C diagonal entry is numerically acceptable + PR = RP (ROW) + RDEG = II (PR+1) + ENDIF + ENDIF + ENDIF + IF (RDEG .EQ. N+1) THEN +C Continue searching - no diagonal found or sought for. +C Minimize row degree subject to abs(value) constraints. + ROW = N+1 + DO 230 I = 1, CDEG + ROW2 = WM (I) + PR = RP (ROW2) + RDEG2 = II (PR+1) +C among those numerically acceptable rows of least +C (upper bound) degree, select the row with the +C lowest row index + BETTER = RDEG2 .LT. RDEG .OR. + $ (RDEG2 .EQ. RDEG .AND. ROW2 .LT. ROW) + IF (BETTER) THEN + X = ABS (XX (WXP-1+I)) + IF (X.GE.TOLER .AND. X.GT.ZERO) THEN + ROW = ROW2 + RDEG = RDEG2 + ROWPOS = I + ENDIF + ENDIF +230 CONTINUE + ENDIF + ENDIF + +C ------------------------------------------------------------- +C deallocate workspace +C ------------------------------------------------------------- + + XHEAD = XHEAD - XS + XUSE = XUSE - XS + XNEED = XNEED - XS +C done using XX (wxp...wxp+xs-1) ] + +C ------------------------------------------------------------- +C reset work vector +C ------------------------------------------------------------- + + DO 240 I = 1, CDEG1 + WIR (WM (I)) = -1 +240 CONTINUE + +C ------------------------------------------------------------- +C check to see if a pivot column was found +C ------------------------------------------------------------- + + IF (RDEG .EQ. N+1) THEN + +C ---------------------------------------------------------- +C no pivot found, column is zero +C ---------------------------------------------------------- + +C remove this singular column from any further pivot search + CDEG = -(N+2) + II (PC+1) = CDEG + + ELSE + +C ---------------------------------------------------------- +C save a list of the columns searched (with nonzero degrees) +C ---------------------------------------------------------- + + SRCHED = SRCHED + 1 + II (PC+7) = SLIST + SLIST = COL + +C ---------------------------------------------------------- +C check if this is the best pivot seen so far +C ---------------------------------------------------------- + +C compute the true Markowitz cost without scanning the row +C Wm (1..cdeg) holds pivot column, including pivot row index +C Wm (rowpos) contains the candidate pivot row index + COST = (CDEG - 1) * (RDEG - 1) + IF (PIVCOL .EQ. 0 .OR. COST .LT. BESTCO) THEN + FFLEFC = CDEG + DO 250 I = 1, FFLEFC-1 + WPC (I) = WM (I) +250 CONTINUE +C remove the pivot row index from pivot column pattern + WPC (ROWPOS) = WM (FFLEFC) + PIVCOL = COL + PIVROW = ROW + BESTCO = COST + ENDIF + ENDIF + +C done using Wm (1..cdeg) for pattern ] +C WpC (1..fflefc-1) holds pivot column (excl. pivot row index) + +C ------------------------------------------------------------- +C exit global pivot search if nsrch pivots have been searched +C ------------------------------------------------------------- + + IF (SRCHED .GE. NSRCH) THEN + GO TO 260 + ENDIF + +255 CONTINUE +C exit label for loop 255: +260 CONTINUE + +C======================================================================= +C Quit early if no pivot found (singular matrix detected) +C======================================================================= + + IF (PIVCOL .EQ. 0) THEN +C complete the column permutation vector in +C WpC (n-npiv+1 ... n) in reverse order + K = N - NPIV + 1 + DO 270 COL = 1, N + IF (CP (COL) .NE. 0) THEN +C this is a non-pivotal column + K = K - 1 + WPC (K) = COL + CP (COL) = 0 + ENDIF +270 CONTINUE +C complete the row permutation vector in +C WpR (n-npiv+1 ... n) in reverse order + K = N - NPIV + 1 + DO 280 ROW = 1, NDN + IF (ROW .GT. N) THEN +C this is an artificial frontal matrix + E = ROW + RP (E) = 0 + ELSE IF (RP (ROW) .NE. 0) THEN + RLEN = WC (ROW) + IF (RLEN .GE. 0 .AND. RLEN .LE. N) THEN +C this is a non-pivotal row + K = K - 1 + WPR (K) = ROW + RP (ROW) = 0 + ELSE IF (RLEN .NE. -(NDN+2)) THEN +C this is an unassembled element: convert to LU + E = ROW + EP = RP (ROW) + WR (E) = -(NDN+2) + WC (E) = -(NDN+2) + FLUIP = II (EP) + RP (E) = FLUIP + ENDIF + ENDIF +280 CONTINUE +C factorization is done, exit the main factorization loop: + GO TO 2000 + ENDIF + +C======================================================================= +C Place the non-pivotal columns searched back in degree lists +C======================================================================= + + DO 300 I = 1, SRCHED + COL = SLIST + PC = CP (COL) + SLIST = II (PC+7) + IF (COL .NE. PIVCOL) THEN + CDEG = II (PC+1) + CNXT = HEAD (CDEG) + II (PC+7) = CNXT + II (PC+8) = 0 + IF (CNXT .NE. 0) THEN + II (CP (CNXT)+8) = COL + ENDIF + HEAD (CDEG) = COL + MINDEG = MIN (MINDEG, CDEG) + ENDIF +300 CONTINUE + +C======================================================================= +C Construct pivot row pattern +C======================================================================= + +C At this point, WiR (1..n) = -1 and WiC (1..n) is -2 for +C nonpivotal columns and -1 for pivotal columns. +C WiC (WpR (1..fflefr+1)) is set to zero in the code below. It +C will be set to the proper offsets in do 775, once ffdimc is +C known (offsets are dependent on ffdimc, which is dependent on +C fflefr calculated below, and the memory allocation). + +C ---------------------------------------------------------------- +C assemble the elements in the element list +C ---------------------------------------------------------------- + + PR = RP (PIVROW) + FFLEFR = 0 + REP = (PR+2) + RELN = WR (PIVROW) + DO 330 IP = REP, REP + 2*RELN - 2, 2 + E = II (IP) + EP = RP (E) + IF (E .LE. N) THEN + FLUIP = II (EP) + LUCP = (FLUIP + 7) + LUDEGR = II (FLUIP+2) + LUDEGC = II (FLUIP+3) + LURP = LUCP + LUDEGC +C split into two loops so that they both vectorize on a CRAY + F1 = FFLEFR + DO 310 P = LURP, LURP + LUDEGR - 1 + COL = II (P) + IF (COL .GT. 0) THEN + IF (WIC (COL) .EQ. -2) THEN + FFLEFR = FFLEFR + 1 + WPR (FFLEFR) = COL + ENDIF + ENDIF +310 CONTINUE + DO 320 I = F1+1, FFLEFR + WIC (WPR (I)) = 0 +320 CONTINUE + ELSE +C this is an artifical element (a dense column) + LURP = (EP+8) + COL = II (LURP) + IF (WIC (COL) .EQ. -2) THEN + FFLEFR = FFLEFR + 1 + WPR (FFLEFR) = COL + WIC (COL) = 0 + ENDIF + ENDIF +330 CONTINUE + +C ---------------------------------------------------------------- +C assemble the original entries in the pivot row +C ---------------------------------------------------------------- + + RSIZ = II (PR) + RLEN = WC (PIVROW) + DO 340 P = PR + RSIZ - RLEN, PR + RSIZ - 1 + COL = II (P) + IF (WIC (COL) .EQ. -2) THEN + FFLEFR = FFLEFR + 1 + WPR (FFLEFR) = COL + ENDIF +340 CONTINUE +C the exact degree of the pivot row is fflefr + +C======================================================================= +C Initialize the new frontal matrix +C======================================================================= + +C ffrow is the name of current frontal matrix + FFROW = PIVROW + E1 = PIVROW + K = 1 + K0 = 0 + FFDIMR = MIN (KLEFT, INT (GRO * FFLEFR)) + FFDIMC = MIN (KLEFT, INT (GRO * FFLEFC)) + FMAXR = FFLEFR + FMAXC = FFLEFC + FFSIZE = FFDIMC * FFDIMR + RSCAN = MAX (DSIZ, FFDIMR) + +C ---------------------------------------------------------------- +C compute the offsets for rows in the pivot column +C and the offsets for columns in the pivot row +C ---------------------------------------------------------------- + + DO 350 I = 1, FFLEFC - 1 + WIR (WPC (I)) = I - 1 +350 CONTINUE + DO 360 I = 1, FFLEFR + WIC (WPR (I)) = (I - 1) * FFDIMC +360 CONTINUE + +C ---------------------------------------------------------------- +C remove the pivot column index from the pivot row pattern +C ---------------------------------------------------------------- + + COL = WPR (FFLEFR) + COLPOS = (WIC (PIVCOL)/FFDIMC)+1 + WPR (COLPOS) = COL + WIC (COL) = WIC (PIVCOL) + WIC (PIVCOL) = (FFDIMR - 1) * FFDIMC + WIR (PIVROW) = FFDIMC - 1 + +C ---------------------------------------------------------------- +C remove the pivot row/col from the nonzero count +C ---------------------------------------------------------------- + + FFLEFR = FFLEFR - 1 + FFLEFC = FFLEFC - 1 + +C ---------------------------------------------------------------- +C allocate the working array, doing garbage collection if needed +C also allocate space for a work vector of size ffdimc +C ---------------------------------------------------------------- + + IF (FFSIZE + FFDIMC .GT. XTAIL-XHEAD) THEN + INFO (15) = INFO (15) + 1 + INTZER = 0 + CALL MA38GD (XX, XSIZE, XHEAD, XUSE, + $ II, ISIZE, IHEAD, IUSE, + $ CP, RP, DN, N, WIR, WIC, WR, WC, + $ INTZER, INTZER, INTZER, INTZER, .FALSE., + $ PFREE, XFREE, MHEAD, MTAIL, SLOTS) +C at this point, iuse = ineed and xuse = xneed + ENDIF + + FFXP = XHEAD + XHEAD = XHEAD + FFSIZE + WXP = XHEAD + XHEAD = XHEAD + FFDIMC + XUSE = XUSE + FFSIZE + FFDIMC + XNEED = XNEED + FFSIZE + FFDIMC + INFO (20) = MAX (INFO (20), XUSE) + INFO (21) = MAX (INFO (21), XNEED) + IF (XHEAD .GT. XTAIL) THEN +C error return, if not enough real memory: + GO TO 9000 + ENDIF + +C ---------------------------------------------------------------- +C get memory usage for next call to MA38BD +C ---------------------------------------------------------------- + + XRUSE = XRUSE + FFSIZE + XRMAX = MAX (XRMAX, XRUSE) + +C ---------------------------------------------------------------- +C zero the working array +C ---------------------------------------------------------------- + +C zero the contribution block: + DO 380 J = 0, FFLEFR - 1 + DO 370 I = 0, FFLEFC - 1 + XX (FFXP + J*FFDIMC + I) = ZERO +370 CONTINUE +380 CONTINUE + +C zero the pivot row: + DO 390 J = 0, FFLEFR - 1 + XX (FFXP + J*FFDIMC + FFDIMC-1) = ZERO +390 CONTINUE + +C zero the pivot column: + DO 400 I = 0, FFLEFC - 1 + XX (FFXP + (FFDIMR-1)*FFDIMC + I) = ZERO +400 CONTINUE + +C zero the pivot entry itself: + XX (FFXP + (FFDIMR-1)*FFDIMC + FFDIMC-1) = ZERO + +C ---------------------------------------------------------------- +C current workspace usage: +C ---------------------------------------------------------------- + +C WpC (1..fflefc): holds the pivot column pattern +C (excluding the pivot row index) +C WpC (fflefc+1 .. n-npiv): unused +C WpC (n-npiv+1 .. n): pivot columns in reverse order +C +C WpR (1..fflefr): holds the pivot row pattern +C (excluding the pivot column index) +C WpR (fflefr+1 .. n-npiv): unused +C WpR (n-npiv+1 .. n): pivot rows in reverse order +C +C C (1..ffdimr, 1..ffdimc): space for the new frontal matrix. +C +C C (i,j) is located at XX (ffxp+((i)-1)+((j)-1)*ffdimc) +C +C WiR (row) >= 0 for each row in pivot column pattern. +C offset into pattern is given by: +C WiR (row) == offset - 1 +C Also, WiR (pivrow) is ffdimc-1, the offset in C of +C the pivot row itself. +C Otherwise, WiR (1..n) is -1 +C +C WiC (col) >= 0 for each col in pivot row pattern. +C WiC (col) == (offset - 1) * ffdimc +C Also, WiC (pivcol) is (ffdimr-1)*ffdimc, +C the offset in C of the pivot column itself. +C Otherwise, WiC (1..n) is -2 for nonpivotal columns, +C and -1 for pivotal columns + +C ---------------------------------------------------------------- +C remove the columns affected by this element from degree lists +C ---------------------------------------------------------------- + + DO 410 J = 1, FFLEFR + PC = CP (WPR (J)) + CDEG = II (PC+1) + IF (CDEG .GT. 0) THEN + CNXT = II (PC+7) + CPRV = II (PC+8) + IF (CNXT .NE. 0) THEN + II (CP (CNXT)+8) = CPRV + ENDIF + IF (CPRV .NE. 0) THEN + II (CP (CPRV)+7) = CNXT + ELSE + HEAD (CDEG) = CNXT + ENDIF + ENDIF +410 CONTINUE + +C======================================================================= +C Initialization of new frontal matrix is complete ] +C======================================================================= + +C======================================================================= +C Assemble and factorize the current frontal matrix [ +C======================================================================= + +C for first pivot in frontal matrix, do all scans + SCAN1 = 0 + SCAN2 = 0 + SCAN3 = 0 + SCAN4 = 0 + + DO 1395 DUMMY3 = 1, N +C (this loop is not indented due to its length) + +C======================================================================= +C Degree update and numerical assembly [ +C======================================================================= + + KLEFT1 = KLEFT - 1 + +C ---------------------------------------------------------------- +C SCAN1: scan the element lists of each row in the pivot col +C and compute the external column degree for each frontal +C ---------------------------------------------------------------- + + ROW = PIVROW + DO 440 J = SCAN1, FFLEFC + IF (J .NE. 0) THEN +C Get a row; otherwise, scan the pivot row if j is zero. + ROW = WPC (J) + ENDIF + PR = RP (ROW) + REP = (PR+2) + RELN = WR (ROW) +CFPP$ NODEPCHK L + DO 430 P = REP, REP + 2*RELN - 2, 2 + E = II (P) + IF (WC (E) .LT. W0) THEN +C this is the first time seen in either scan 1 or 2: + EP = RP (E) + FLEFTR = II (EP+5) + FLEFTC = II (EP+6) + WR (E) = FLEFTR + W0 + WC (E) = FLEFTC + W0 + ENDIF + WC (E) = WC (E) - 1 +430 CONTINUE +440 CONTINUE + +C ---------------------------------------------------------------- +C SCAN2: scan the element lists of each col in the pivot row +C and compute the external row degree for each frontal +C ---------------------------------------------------------------- + + COL = PIVCOL + DO 460 J = SCAN2, FFLEFR + IF (J .NE. 0) THEN +C Get a col; otherwise, scan the pivot col if j is zero. + COL = WPR (J) + ENDIF + PC = CP (COL) + CELN = II (PC+5) + CEP = (PC+9) +CFPP$ NODEPCHK L + DO 450 P = CEP, CEP + 2*CELN - 2, 2 + E = II (P) + IF (WR (E) .LT. W0) THEN +C this is the first time seen in either scan 1 or 2: + EP = RP (E) + FLEFTR = II (EP+5) + FLEFTC = II (EP+6) + WR (E) = FLEFTR + W0 + WC (E) = FLEFTC + W0 + ENDIF + WR (E) = WR (E) - 1 +450 CONTINUE +460 CONTINUE + +C ---------------------------------------------------------------- +C SCAN3: scan the element lists of each column in pivot row +C do degree update for the columns +C assemble effective Usons and LU-sons +C ---------------------------------------------------------------- + +C flag Usons in Wc (e) as scanned (all now unflagged) [ +C uses Wc (e) for the link list. Wc (e) <= 0 +C means that e is in the list, the external column +C degree is zero, and -(Wc (e)) is the next element in +C the Uson list. + + COL = PIVCOL + DO 700 JJ = SCAN3, FFLEFR + +C ------------------------------------------------------------- +C assemble and update the degree of a column +C ------------------------------------------------------------- + + IF (JJ .NE. 0) THEN +C Get a col; otherwise, scan the pivot col if jj is zero + COL = WPR (JJ) + ENDIF + +C ------------------------------------------------------------- +C compute the degree, and partition the element list into +C two parts. The first part are not LUsons or Usons, and +C are not assembled. The second part is assembled. +C ------------------------------------------------------------- + + CDEG = 0 + DELN = 0 + PC = CP (COL) + CEP = (PC+9) + CELN = II (PC+5) + IP2 = CEP + 2*CELN - 2 + XUDP = FFXP + WIC (COL) +CFPP$ NODEPCHK L + DO 470 IP = CEP, IP2, 2 + E = II (IP) + IF (WC (E) .GT. W0) THEN +C this element cannot be assembled + CDEG = CDEG + (WC (E) - W0) + ELSE +C delete this tuple from the element list + DELN = DELN + 1 + WM (DELN) = IP + ENDIF +470 CONTINUE + + IF (DELN .NE. 0) THEN + +C ---------------------------------------------------------- +C move the deleted tuples to the end of the element list +C ---------------------------------------------------------- + + P2 = IP2 + DO 480 I = DELN, 1, -1 + E = II (WM (I) ) + F = II (WM (I)+1) + II (WM (I) ) = II (P2 ) + II (WM (I)+1) = II (P2+1) + II (P2 ) = E + II (P2+1) = F + P2 = P2 - 2 +480 CONTINUE + +C ---------------------------------------------------------- +C assemble from LUsons and Usons (the deleted tuples) +C ---------------------------------------------------------- + + DO 670 IP = P2 + 2, IP2, 2 + +C ------------------------------------------------------- +C this is an LUson or Uson. If fextc < 0 then this has +C already been assembled. +C ------------------------------------------------------- + + E = II (IP) + IF (WC (E) .LT. W0) THEN +C go to next iteration if already assembled + GOTO 670 + ENDIF + +C ------------------------------------------------------- +C get scalar info, add son to list if not already there +C ------------------------------------------------------- + + EP = RP (E) + FDIMC = II (EP+1) + FXP = II (EP+2) + FLEFTR = II (EP+5) + FLEFTC = II (EP+6) + IF (E .LE. N) THEN + FLUIP = II (EP) + LUDEGR = II (FLUIP+2) + LUDEGC = II (FLUIP+3) + LUCP = (FLUIP + 7) + LURP = LUCP + LUDEGC + IF (WIR (E) .EQ. -1) THEN + WIR (E) = SONLST - N - 2 + SONLST = E + NSONS = NSONS + 1 + ENDIF + ELSE +C an artificial frontal matrix + LUDEGR = 1 + LUDEGC = FDIMC + LUCP = (EP+9) + LURP = (EP+8) + ENDIF + +C ------------------------------------------------------- + IF (WR (E) .EQ. W0) THEN +C this is an LUson - assemble an entire frontal matrix +C ------------------------------------------------------- + +C ---------------------------------------------------- + IF (LUDEGC .EQ. FLEFTC) THEN +C no rows assembled out of this frontal yet +C ---------------------------------------------------- + +C compute the compressed column offset vector +C use Wm (1..ludegc for offsets) [ + DO 490 I = 0, LUDEGC-1 + ROW2 = II (LUCP+I) + WM (I+1) = WIR (ROW2) +490 CONTINUE + +C ------------------------------------------------- + IF (LUDEGR .EQ. FLEFTR) THEN +C no rows or cols assembled out of frontal yet +C ------------------------------------------------- + + DO 510 J = 0, LUDEGR-1 + COL2 = II (LURP+J) + XDP = FFXP + WIC (COL2) +CFPP$ NODEPCHK L + DO 500 I = 0, LUDEGC-1 + XX (XDP + WM (I+1)) = + $ XX (XDP + WM (I+1)) + + $ XX (FXP + J*FDIMC + I) +500 CONTINUE +510 CONTINUE + +C ------------------------------------------------- + ELSE +C only cols have been assembled out of frontal +C ------------------------------------------------- + + DO 530 J = 0, LUDEGR-1 + COL2 = II (LURP+J) + IF (COL2 .GT. 0) THEN + XDP = FFXP + WIC (COL2) +CFPP$ NODEPCHK L + DO 520 I = 0, LUDEGC-1 + XX (XDP + WM (I+1)) = + $ XX (XDP + WM (I+1)) + + $ XX (FXP + J*FDIMC + I) +520 CONTINUE + ENDIF +530 CONTINUE + ENDIF +C done using Wm (1..ludegc for offsets) ] + +C ---------------------------------------------------- + ELSE +C some rows have been assembled out of this frontal +C ---------------------------------------------------- + +C compute the compressed column offset vector +C use Wm (1..ludegc for offsets) [ + DEGC = 0 + DO 540 I = 0, LUDEGC-1 + ROW2 = II (LUCP+I) + IF (ROW2 .GT. 0) THEN + DEGC = DEGC + 1 + WJ (DEGC) = I + WM (DEGC) = WIR (ROW2) + ENDIF +540 CONTINUE + +C ------------------------------------------------- + IF (LUDEGR .EQ. FLEFTR) THEN +C only rows assembled out of this frontal +C ------------------------------------------------- + + DO 560 J = 0, LUDEGR-1 + COL2 = II (LURP+J) + XDP = FFXP + WIC (COL2) +CFPP$ NODEPCHK L + DO 550 I = 1, DEGC + XX (XDP + WM (I)) = + $ XX (XDP + WM (I)) + + $ XX (FXP + J*FDIMC + WJ (I)) +550 CONTINUE +560 CONTINUE + +C ------------------------------------------------- + ELSE +C both rows and columns assembled out of frontal +C ------------------------------------------------- + + DO 580 J = 0, LUDEGR-1 + COL2 = II (LURP+J) + IF (COL2 .GT. 0) THEN + XDP = FFXP + WIC (COL2) +CFPP$ NODEPCHK L + DO 570 I = 1, DEGC + XX (XDP + WM (I)) = + $ XX (XDP + WM (I)) + + $ XX (FXP + J*FDIMC + WJ (I)) +570 CONTINUE + ENDIF +580 CONTINUE + ENDIF +C done using Wm (1..ludegc for offsets) ] + ENDIF + +C ---------------------------------------------------- +C deallocate the LUson frontal matrix +C ---------------------------------------------------- + + WR (E) = -(NDN+2) + WC (E) = -(NDN+2) + IF (E .LE. N) THEN + RP (E) = FLUIP + II (EP) = FSCAL + INEED = INEED - FSCAL + ELSE + RP (E) = 0 + II (EP) = FDIMC + CSCAL + INEED = INEED - (FDIMC + CSCAL) + ENDIF + II (EP+1) = -1 + II (EP+6) = 0 + MPREV = II (EP+4) + MNEXT = II (EP+3) + XNEED = XNEED - LUDEGR*LUDEGC + IF (MNEXT .NE. 0 .AND. II (MNEXT+6) .EQ. 0) THEN +C next block is free - delete it + MNEXT = II (MNEXT+3) + II (EP+3) = MNEXT + IF (MNEXT .NE. 0) THEN + II (MNEXT+4) = EP + ELSE + MTAIL = EP + ENDIF + ENDIF + IF (MPREV .NE. 0 .AND. II (MPREV+6) .EQ. 0) THEN +C previous block is free - delete it + II (EP+2) = II (MPREV+2) + MPREV = II (MPREV+4) + II (EP+4) = MPREV + IF (MPREV .NE. 0) THEN + II (MPREV+3) = EP + ELSE + MHEAD = EP + ENDIF + ENDIF +C get the size of the freed block + IF (MNEXT .NE. 0) THEN + XS = II (MNEXT+2) - II (EP+2) + ELSE + XS = FFXP - II (EP+2) + ENDIF + IF (XS .GT. XFREE) THEN +C keep track of the largest free block + XFREE = XS + PFREE = EP + ENDIF + +C ---------------------------------------------------- +C get memory usage for next call to MA38BD +C ---------------------------------------------------- + + XRUSE = XRUSE - LUDEGR*LUDEGC + +C ------------------------------------------------------- + ELSE IF (WR (E) - W0 .LE. FLEFTR/2) THEN +C this is a Uson - assemble all possible columns +C ------------------------------------------------------- + +C ---------------------------------------------------- +C add to Uson list - to be cleared just after scan 3 +C ---------------------------------------------------- + + WC (E) = -USONS + USONS = E + +C ---------------------------------------------------- + IF (LUDEGC .EQ. FLEFTC) THEN +C no rows assembled out of this Uson frontal yet +C ---------------------------------------------------- + +C compute the compressed column offset vector +C use Wm (1..ludegc for offsets) + DO 590 I = 0, LUDEGC-1 + ROW2 = II (LUCP+I) + WM (I+1) = WIR (ROW2) +590 CONTINUE + + DO 610 J = 0, LUDEGR-1 + COL2 = II (LURP+J) + IF (COL2 .GT. 0) THEN + IF (WIC (COL2) .GE. 0) THEN + XDP = FFXP + WIC (COL2) +CFPP$ NODEPCHK L + DO 600 I = 0, LUDEGC-1 + XX (XDP + WM (I+1)) = + $ XX (XDP + WM (I+1)) + + $ XX (FXP + J*FDIMC + I) +600 CONTINUE +C flag this column as assembled from Uson + II (LURP+J) = -COL2 + ENDIF + ENDIF +610 CONTINUE + +C ---------------------------------------------------- + ELSE +C some rows already assembled out of this Uson frontal +C ---------------------------------------------------- + +C compute the compressed column offset vector +C use Wm (1..ludegc for offsets) + DEGC = 0 + DO 620 I = 0, LUDEGC-1 + ROW2 = II (LUCP+I) + IF (ROW2 .GT. 0) THEN + DEGC = DEGC + 1 + WJ (DEGC) = I + WM (DEGC) = WIR (ROW2) + ENDIF +620 CONTINUE + + DO 640 J = 0, LUDEGR-1 + COL2 = II (LURP+J) + IF (COL2 .GT. 0) THEN + IF (WIC (COL2) .GE. 0) THEN + XDP = FFXP + WIC (COL2) +CFPP$ NODEPCHK L + DO 630 I = 1, DEGC + XX (XDP + WM (I)) = + $ XX (XDP + WM (I)) + + $ XX (FXP + J*FDIMC + WJ (I)) +630 CONTINUE +C flag this column as assembled from Uson + II (LURP+J) = -COL2 + ENDIF + ENDIF +640 CONTINUE + + ENDIF + + FLEFTR = WR (E) - W0 + II (EP+5) = FLEFTR + +C ------------------------------------------------------- + ELSE +C this is a Uson - assemble just one column +C ------------------------------------------------------- + +C get the offset, f, from the (e,f) tuple + F = II (IP+1) + +C ---------------------------------------------------- + IF (LUDEGC .EQ. FLEFTC) THEN +C no rows assembled out of this Uson yet +C ---------------------------------------------------- + +CFPP$ NODEPCHK L + DO 650 I = 0, LUDEGC-1 + ROW2 = II (LUCP+I) + XX (XUDP + WIR (ROW2)) = + $ XX (XUDP + WIR (ROW2)) + + $ XX (FXP + F*FDIMC + I) +650 CONTINUE + +C ---------------------------------------------------- + ELSE +C some rows already assembled out of this Uson +C ---------------------------------------------------- + +CFPP$ NODEPCHK L + DO 660 I = 0, LUDEGC-1 + ROW2 = II (LUCP+I) + IF (ROW2 .GT. 0) THEN + XX (XUDP + WIR (ROW2)) = + $ XX (XUDP + WIR (ROW2)) + + $ XX (FXP + F*FDIMC + I) + ENDIF +660 CONTINUE + ENDIF + +C ---------------------------------------------------- +C decrement count of unassembled cols in frontal +C ---------------------------------------------------- + + II (EP+5) = FLEFTR - 1 +C flag the column as assembled from the Uson + II (LURP+F) = -COL + ENDIF + +670 CONTINUE + +C ---------------------------------------------------------- +C update the count of (e,f) tuples in the element list +C ---------------------------------------------------------- + + II (PC+5) = II (PC+5) - DELN + INEED = INEED - 2*DELN + ENDIF + +C ------------------------------------------------------------- +C assemble the original column and update count of entries +C ------------------------------------------------------------- + + CLEN = II (PC+6) + IF (CLEN .GT. 0) THEN + CSIZ = II (PC) + IP = PC + CSIZ - CLEN + DLEN = 0 +CFPP$ NODEPCHK L + DO 680 I = 0, CLEN - 1 + ROW = II (IP+I) + IF (WIR (ROW) .GE. 0) THEN +C this entry can be assembled and deleted + DLEN = DLEN + 1 + WM (DLEN) = I + ENDIF +680 CONTINUE + IF (DLEN .NE. 0) THEN + CXP = II (PC+2) + DO 690 J = 1, DLEN + I = WM (J) + ROW = II (IP+I) +C assemble the entry + XX (XUDP + WIR (ROW)) = + $ XX (XUDP + WIR (ROW)) + XX (CXP+I) +C and delete the entry + II (IP +I) = II (IP +J-1) + XX (CXP+I) = XX (CXP+J-1) +690 CONTINUE + CLEN = CLEN - DLEN + CXP = CXP + DLEN + INEED = INEED - DLEN + XNEED = XNEED - DLEN + II (PC+6) = CLEN + IF (CLEN .NE. 0) THEN + II (PC+2) = CXP + ELSE +C deallocate the real portion of the column: + MPREV = II (PC+4) + MNEXT = II (PC+3) + IF (MNEXT .NE. 0 .AND. II (MNEXT+6) .EQ. 0) THEN +C next block is free - delete it + MNEXT = II (MNEXT+3) + II (PC+3) = MNEXT + IF (MNEXT .NE. 0) THEN + II (MNEXT+4) = PC + ELSE + MTAIL = PC + ENDIF + ENDIF + IF (MPREV .NE. 0 .AND. II (MPREV+6) .EQ. 0) THEN +C previous block is free - delete it + II (PC+2) = II (MPREV+2) + MPREV = II (MPREV+4) + II (PC+4) = MPREV + IF (MPREV .NE. 0) THEN + II (MPREV+3) = PC + ELSE + MHEAD = PC + ENDIF + ENDIF + IF (PC .EQ. MHEAD) THEN +C adjust the start of the block if this is head + II (PC+2) = 1 + ENDIF +C get the size of the freed block + IF (MNEXT .NE. 0) THEN + XS = II (MNEXT+2) - II (PC+2) + ELSE + XS = FFXP - II (PC+2) + ENDIF + IF (XS .GT. XFREE) THEN +C keep track of the largest free block + XFREE = XS + PFREE = PC + ENDIF + ENDIF + ENDIF + CDEG = CDEG + CLEN + ENDIF + +C ------------------------------------------------------------- +C compute the upper bound degree - excluding current front +C ------------------------------------------------------------- + + CDEG2 = II (PC+1) + CDEG = MIN (KLEFT1 - FFLEFC, CDEG2, CDEG) + II (PC+1) = CDEG + +700 CONTINUE + +C ---------------------------------------------------------------- +C SCAN-3 wrap-up: remove flags from assembled Usons +C ---------------------------------------------------------------- + +C while (usons .ne. ndn+1) do +710 CONTINUE + IF (USONS .NE. NDN+1) THEN + NEXT = -WC (USONS) + WC (USONS) = W0 + USONS = NEXT +C end while: + GOTO 710 + ENDIF +C done un-flagging usons, all now unflagged in Wc (e) ] + +C ---------------------------------------------------------------- +C SCAN4: scan element lists of each row in the pivot column +C do degree update for the rows +C assemble effective Lsons +C ---------------------------------------------------------------- + +C flag Lsons in Wr (e) (all are now unflagged) [ +C uses Wr (e) for the link list. Wr (e) <= 0 means +C that e is in the list, the external row degree is zero, and +C -(Wr (e)) is the next element in the Lson list. + + ROW = PIVROW + DO 840 JJ = SCAN4, FFLEFC + +C ------------------------------------------------------------- +C assemble and update the degree of a row +C ------------------------------------------------------------- + + IF (JJ .NE. 0) THEN +C Get a row; otherwise, scan the pivot row if jj is zero + ROW = WPC (JJ) + ENDIF + +C ------------------------------------------------------------- +C compute the degree, and partition the element list into +C two parts. The first part are not LUsons or Lsons, and +C are not assembled. The second part is assembled. +C ------------------------------------------------------------- + + RDEG = 0 + DELN = 0 + PR = RP (ROW) + REP = (PR+2) + RELN = WR (ROW) + IP2 = REP + 2*RELN - 2 +CFPP$ NODEPCHK L + DO 720 IP = REP, IP2, 2 + E = II (IP) + IF (WR (E) .GT. W0) THEN + RDEG = RDEG + (WR (E) - W0) + ELSE + DELN = DELN + 1 + WM (DELN) = IP + ENDIF +720 CONTINUE + + IF (DELN .NE. 0) THEN + +C ---------------------------------------------------------- +C move the deleted tuples to the end of the element list +C ---------------------------------------------------------- + + P2 = IP2 + DO 730 I = DELN, 1, -1 + E = II (WM (I) ) + F = II (WM (I)+1) + II (WM (I) ) = II (P2 ) + II (WM (I)+1) = II (P2+1) + II (P2 ) = E + II (P2+1) = F + P2 = P2 - 2 +730 CONTINUE + +C ---------------------------------------------------------- +C assemble from Lsons (the deleted tuples) +C ---------------------------------------------------------- + + DO 810 IP = P2 + 2, IP2, 2 + +C ------------------------------------------------------- +C this is an LUson or Lson. If fextr < 0 then this has +C already been assembled. All LUsons have already been +C assembled (in SCAN3, above). +C ------------------------------------------------------- + + E = II (IP) + IF (WR (E) .LT. W0) THEN +C go to next iteration if already assembled + GOTO 810 + ENDIF + +C ------------------------------------------------------- +C get scalar info, add to son list if not already there +C ------------------------------------------------------- + + EP = RP (E) + FDIMC = II (EP+1) + FXP = II (EP+2) + FLEFTR = II (EP+5) + FLEFTC = II (EP+6) + IF (E .LE. N) THEN + FLUIP = II (EP) + LUDEGR = II (FLUIP+2) + LUDEGC = II (FLUIP+3) + LUCP = (FLUIP + 7) + LURP = LUCP + LUDEGC + IF (WIR (E) .EQ. -1) THEN + WIR (E) = SONLST - N - 2 + SONLST = E + NSONS = NSONS + 1 + ENDIF + ELSE +C an artificial frontal matrix + LUDEGR = 1 + LUDEGC = FDIMC + LUCP = (EP+9) + LURP = (EP+8) + ENDIF + +C ------------------------------------------------------- + IF (WC (E) - W0 .LE. FLEFTC/2) THEN +C this is an Lson - assemble all possible rows +C ------------------------------------------------------- + +C ---------------------------------------------------- +C add to Lson list - to be cleared just after scan 4 +C ---------------------------------------------------- + + WR (E) = -LSONS + LSONS = E + +C compute the compressed column offset vector +C use Wm (1..ludegc for offsets) [ + DEGC = 0 + DO 740 I = 0, LUDEGC-1 + ROW2 = II (LUCP+I) + IF (ROW2 .GT. 0) THEN + IF (WIR (ROW2) .GE. 0) THEN +C this row will be assembled in loop below + DEGC = DEGC + 1 + WJ (DEGC) = I + WM (DEGC) = WIR (ROW2) +C flag the row as assembled from the Lson + II (LUCP+I) = -ROW2 + ENDIF + ENDIF +740 CONTINUE + +C ---------------------------------------------------- + IF (LUDEGR .EQ. FLEFTR) THEN +C no columns assembled out this Lson yet +C ---------------------------------------------------- + + DO 760 J = 0, LUDEGR-1 + COL2 = II (LURP+J) + XDP = FFXP + WIC (COL2) +CFPP$ NODEPCHK L + DO 750 I = 1, DEGC + XX (XDP + WM (I)) = + $ XX (XDP + WM (I)) + + $ XX (FXP + J*FDIMC + WJ (I)) +750 CONTINUE +760 CONTINUE + +C ---------------------------------------------------- + ELSE +C some columns already assembled out of this Lson +C ---------------------------------------------------- + + DO 780 J = 0, LUDEGR-1 + COL2 = II (LURP+J) + IF (COL2 .GT. 0) THEN + XDP = FFXP + WIC (COL2) +CFPP$ NODEPCHK L + DO 770 I = 1, DEGC + XX (XDP + WM (I)) = + $ XX (XDP + WM (I)) + + $ XX (FXP + J*FDIMC + WJ (I)) +770 CONTINUE + ENDIF +780 CONTINUE + ENDIF + +C done using Wm (1..ludegc for offsets) ] + FLEFTC = WC (E) - W0 + II (EP+6) = FLEFTC + +C ------------------------------------------------------- + ELSE +C this is an Lson - assemble just one row +C ------------------------------------------------------- + + XLDP = FFXP + WIR (ROW) +C get the offset, f, from the (e,f) tuple + F = II (IP+1) + +C ---------------------------------------------------- + IF (LUDEGR .EQ. FLEFTR) THEN +C no columns assembled out this Lson yet +C ---------------------------------------------------- + +CFPP$ NODEPCHK L + DO 790 J = 0, LUDEGR-1 + COL2 = II (LURP+J) + XX (XLDP + WIC (COL2)) = + $ XX (XLDP + WIC (COL2)) + + $ XX (FXP + J*FDIMC + F) +790 CONTINUE + +C ---------------------------------------------------- + ELSE +C some columns already assembled out of this Lson +C ---------------------------------------------------- + +CFPP$ NODEPCHK L + DO 800 J = 0, LUDEGR-1 + COL2 = II (LURP+J) + IF (COL2 .GT. 0) THEN + XX (XLDP + WIC (COL2)) = + $ XX (XLDP + WIC (COL2)) + + $ XX (FXP + J*FDIMC + F) + ENDIF +800 CONTINUE + ENDIF + + II (EP+6) = FLEFTC - 1 +C flag the row as assembled from the Lson + II (LUCP+F) = -ROW + ENDIF + +810 CONTINUE + +C ---------------------------------------------------------- +C update the count of (e,f) tuples in the element list +C ---------------------------------------------------------- + + WR (ROW) = WR (ROW) - DELN + INEED = INEED - 2*DELN + ENDIF + +C ------------------------------------------------------------- +C assemble the original row and update count of entries +C ------------------------------------------------------------- + + RLEN = WC (ROW) + IF (RLEN .GT. 0) THEN +C do not scan a very long row: + IF (RLEN .LE. RSCAN) THEN + RSIZ = II (PR) + IP = PR + RSIZ - RLEN + DLEN = 0 +CFPP$ NODEPCHK L + DO 820 P = IP, IP + RLEN - 1 + COL = II (P) + IF (WIC (COL) .NE. -2) THEN +C this entry can be assembled and deleted +C if WiC (col) = -1, it is an older pivot col, +C otherwise (>=0) it is in the current element + DLEN = DLEN + 1 + WM (DLEN) = P + ENDIF +820 CONTINUE + IF (DLEN .NE. 0) THEN + DO 830 J = 1, DLEN +C delete the entry + II (WM (J)) = II (IP+J-1) +830 CONTINUE + RLEN = RLEN - DLEN + INEED = INEED - DLEN + WC (ROW) = RLEN + ENDIF + ENDIF + RDEG = RDEG + RLEN + ENDIF + +C ------------------------------------------------------------- +C compute the upper bound degree - excluding current front +C ------------------------------------------------------------- + + RDEG2 = II (PR+1) + RDEG = MIN (KLEFT1 - FFLEFR, RDEG2, RDEG) + II (PR+1) = RDEG + +840 CONTINUE + +C ---------------------------------------------------------------- +C SCAN-4 wrap-up: remove flags from assembled Lsons +C ---------------------------------------------------------------- + +C while (lsons .ne. ndn+1) do +850 CONTINUE + IF (LSONS .NE. NDN+1) THEN + NEXT = -WR (LSONS) + WR (LSONS) = W0 + LSONS = NEXT +C end while: + GOTO 850 + ENDIF +C done un-flagging Lsons, all now unflagged in Wr (e) ] + +C======================================================================= +C Degree update and numerical assemble is complete ] +C======================================================================= + +C======================================================================= +C Factorize frontal matrix until next pivot extends it [ +C======================================================================= + + DO 1324 DUMMY4 = 1, N +C (this loop is not indented due to its length) + +C ---------------------------------------------------------------- +C Wc (e) = fextc+w0, where fextc is the external column +C degree for each element (ep = Rp (e)) appearing in +C the element lists for each row in the pivot column. +C if Wc (e) < w0, then fextc is defined as II (ep+6) +C +C Wr (e) = fextr+w0, where fextr is the external row +C degree for each element (ep = Rp (e)) appearing in +C the element lists for each column in the pivot row +C if Wr (e) < w0, then fextr is defined as II (ep+5) +C +C WiR (row) >= 0 for each row in pivot column pattern. +C offset into pattern is given by: +C WiR (row) == offset - 1 +C WiR (pivrow) is the offset of the latest pivot row +C +C WiC (col) >= 0 for each col in pivot row pattern. +C WiC (col) == (offset - 1) * ffdimc +C WiC (pivcol) is the offset of the latest pivot column +C +C WpR (1..fflefr) is the pivot row pattern (excl pivot cols) +C WpC (1..fflefc) is the pivot col pattern (excl pivot rows) +C ---------------------------------------------------------------- + +C======================================================================= +C Divide pivot column by pivot +C======================================================================= + +C k-th pivot in frontal matrix located in C(ffdimc-k+1,ffdimr-k+1) + XDP = FFXP + (FFDIMR - K) * FFDIMC + X = XX (XDP + FFDIMC - K) + +C divide C(1:fflefc,ffdimr-k+1) by pivot value + X = ONE / X + DO 870 P = XDP, XDP + FFLEFC-1 + XX (P) = XX (P) * X +870 CONTINUE +C count this as a call to the Level-1 BLAS: + RINFO (4) = RINFO (4) + FFLEFC + +C======================================================================= +C A pivot step is complete +C======================================================================= + + KLEFT = KLEFT - 1 + NPIV = NPIV + 1 + INFO (17) = INFO (17) + 1 + +C ---------------------------------------------------------------- +C the pivot column is fully assembled and scaled, and is now the +C (npiv)-th column of L. The pivot row is the (npiv)-th row of U. +C ---------------------------------------------------------------- + + WPR (N-NPIV+1) = PIVROW + WPC (N-NPIV+1) = PIVCOL + WIR (PIVROW) = -1 + WIC (PIVCOL) = -1 + +C ---------------------------------------------------------------- +C deallocate the pivot row and pivot column +C ---------------------------------------------------------------- + + RLEN = WC (PIVROW) + INEED = INEED - CSCAL - RSCAL - RLEN + PR = RP (PIVROW) + PC = CP (PIVCOL) + II (PR+1) = -1 + II (PC+1) = -1 + RP (PIVROW) = 0 + CP (PIVCOL) = 0 + +C======================================================================= +C Local search for next pivot within current frontal matrix [ +C======================================================================= + + FEDEGC = FFLEFC + FEDEGR = FFLEFR + PFOUND = .FALSE. + OKCOL = FFLEFC .GT. 0 + OKROW = .FALSE. + +C ---------------------------------------------------------------- +C find column of minimum degree in current frontal row pattern +C ---------------------------------------------------------------- + +C among those columns of least (upper bound) degree, select the +C column with the lowest column index + IF (OKCOL) THEN + COLPOS = 0 + PIVCOL = N+1 + CDEG = N+1 +C can this be vectorized? This is the most intensive +C non-vector loop. + DO 880 J = 1, FFLEFR + COL = WPR (J) + PC = CP (COL) + CDEG2 = II (PC+1) + BETTER = CDEG2 .GE. 0 .AND. + $ (CDEG2 .LT. CDEG .OR. + $ (CDEG2 .EQ. CDEG .AND. COL .LT. PIVCOL)) + IF (BETTER) THEN + CDEG = CDEG2 + COLPOS = J + PIVCOL = COL + ENDIF +880 CONTINUE + OKCOL = COLPOS .NE. 0 + ENDIF + +C======================================================================= +C Assemble candidate pivot column in temporary workspace +C======================================================================= + + IF (OKCOL) THEN + PC = CP (PIVCOL) + CLEN = II (PC+6) + OKCOL = FEDEGC + CLEN .LE. FFDIMC + ENDIF + + IF (OKCOL) THEN + +C ------------------------------------------------------------- +C copy candidate column from current frontal matrix into +C work vector XX (wxp ... wxp+ffdimc-1) [ +C ------------------------------------------------------------- + + P = FFXP + (COLPOS - 1) * FFDIMC - 1 +CFPP$ NODEPCHK L + DO 890 I = 1, FFLEFC + XX (WXP-1+I) = XX (P+I) +890 CONTINUE + +C ------------------------------------------------------------- +C update candidate column with previous pivots in this front +C ------------------------------------------------------------- + + IF (K-K0 .GT. 0 .AND. FFLEFC .NE. 0) THEN + CALL DGEMV ('N', FFLEFC, K-K0, + $ -ONE, XX (FFXP + (FFDIMR - K) * FFDIMC) ,FFDIMC, + $ XX (FFXP + (COLPOS - 1) * FFDIMC + FFDIMC - K), 1, + $ ONE, XX (WXP) , 1) + RINFO (3) = RINFO (3) + 2*FFLEFC*(K-K0) + ENDIF + +C ------------------------------------------------------------- +C Compute extended pivot column in XX (wxp..wxp-1+fedegc). +C Pattern of pivot column is placed in WpC (1..fedegc) +C ------------------------------------------------------------- + +C assemble the elements in the element list + CEP = (PC+9) + CELN = II (PC+5) + DO 930 IP = CEP, CEP + 2*CELN - 2, 2 + E = II (IP) + F = II (IP+1) + EP = RP (E) + FLEFTC = II (EP+6) + FDIMC = II (EP+1) + FXP = II (EP+2) + IF (E .LE. N) THEN + FLUIP = II (EP) + LUCP = (FLUIP + 7) + LUDEGC = II (FLUIP+3) + ELSE + LUCP = (EP+9) + LUDEGC = FDIMC + ENDIF + XP = FXP + F * FDIMC +C split into 3 loops so that they all vectorize on a CRAY + F1 = FEDEGC + DO 900 P = LUCP, LUCP + LUDEGC - 1 + ROW = II (P) + IF (ROW .GT. 0) THEN + IF (WIR (ROW) .LT. 0) THEN + F1 = F1 + 1 + WPC (F1) = ROW + ENDIF + ENDIF +900 CONTINUE + OKCOL = F1 + CLEN .LE. FFDIMC + IF (.NOT. OKCOL) THEN +C exit out of loop if column too long: + GO TO 940 + ENDIF + DO 910 I = FEDEGC+1, F1 + ROW = WPC (I) + WIR (ROW) = I - 1 + XX (WXP-1+I) = ZERO +910 CONTINUE + FEDEGC = F1 +CFPP$ NODEPCHK L + DO 920 J = 0, LUDEGC - 1 + ROW = II (LUCP+J) + IF (ROW .GT. 0) THEN + XX (WXP + WIR (ROW)) = + $ XX (WXP + WIR (ROW)) + XX (XP+J) + ENDIF +920 CONTINUE +930 CONTINUE +C loop exit label: +940 CONTINUE + ENDIF + +C======================================================================= +C Find candidate pivot row - unless candidate pivot column is too long +C======================================================================= + + IF (OKCOL) THEN + +C ------------------------------------------------------------- +C assemble the original entries in the column +C ------------------------------------------------------------- + + CSIZ = II (PC) + IP = PC + CSIZ - CLEN + CXP = II (PC+2) +CFPP$ NODEPCHK L + DO 950 I = 0, CLEN - 1 + ROW = II (IP+I) + WIR (ROW) = FEDEGC + I + WPC (FEDEGC+1+I) = ROW + XX (WXP+FEDEGC+I) = XX (CXP+I) +950 CONTINUE + FEDEGC = FEDEGC + CLEN + +C ------------------------------------------------------------- +C update degree of candidate column - excluding current front +C ------------------------------------------------------------- + + CDEG = FEDEGC - FFLEFC + II (PC+1) = CDEG + +C ------------------------------------------------------------- +C find the maximum absolute value in the column +C ------------------------------------------------------------- + + MAXVAL = ABS (XX (WXP-1 + IDAMAX (FEDEGC, XX (WXP), 1))) + RINFO (3) = RINFO (3) + FEDEGC + TOLER = RELPT * MAXVAL + RDEG = N+1 + +C ------------------------------------------------------------- +C look for the best possible pivot row in this column +C ------------------------------------------------------------- + + IF (MAXVAL .GT. ZERO) THEN + IF (SYMSRC) THEN +C prefer symmetric pivots, if numerically acceptable + PIVROW = PIVCOL + ROWPOS = WIR (PIVROW) + 1 + IF (ROWPOS .GT. 0 .AND. ROWPOS .LE. FFLEFC) THEN +C diagonal entry exists in the column pattern +C also within the current frontal matrix + X = ABS (XX (WXP-1+ROWPOS)) + IF (X.GE.TOLER .AND. X.GT.ZERO) THEN +C diagonal entry is numerically acceptable + PR = RP (PIVROW) + RDEG = II (PR+1) + ENDIF + ENDIF + ENDIF + IF (RDEG .EQ. N+1) THEN +C Continue searching - no diagonal found or sought for. +C Minimize row degree subject to abs(value) constraints. + PIVROW = N+1 + DO 960 I = 1, FFLEFC + ROW2 = WPC (I) + PR = RP (ROW2) + RDEG2 = II (PR+1) +C among those numerically acceptable rows of least +C (upper bound) degree, select the row with the +C lowest row index + BETTER = RDEG2 .LT. RDEG .OR. + $ (RDEG2 .EQ. RDEG .AND. ROW2 .LT. PIVROW) + IF (BETTER) THEN + X = ABS (XX (WXP-1+I)) + IF (X.GE.TOLER .AND. X.GT.ZERO) THEN + PIVROW = ROW2 + RDEG = RDEG2 + ROWPOS = I + ENDIF + ENDIF +960 CONTINUE + ENDIF + ELSE +C remove this column from any further pivot search + CDEG = -(N+2) + II (PC+1) = CDEG + ENDIF + OKROW = RDEG .NE. N+1 + ENDIF + +C done using XX (wxp...wxp+ffdimc-1) ] + +C======================================================================= +C If found, construct candidate pivot row pattern +C======================================================================= + + IF (OKROW) THEN + +C ------------------------------------------------------------- +C assemble the elements in the element list +C ------------------------------------------------------------- + + PR = RP (PIVROW) + REP = (PR+2) + RELN = WR (PIVROW) + DO 990 IP = REP, REP + 2*RELN - 2, 2 + E = II (IP) + EP = RP (E) + IF (E .LE. N) THEN + FLUIP = II (EP) + LUCP = (FLUIP + 7) + LUDEGR = II (FLUIP+2) + LUDEGC = II (FLUIP+3) + LURP = LUCP + LUDEGC + FLEFTR = II (EP+5) + OKROW = FLEFTR .LE. FFDIMR + IF (.NOT. OKROW) THEN +C exit out of loop if row too long: + GO TO 1000 + ENDIF +C split into two loops so that both vectorize on a CRAY + F1 = FEDEGR + DO 970 P = LURP, LURP + LUDEGR - 1 + COL = II (P) + IF (COL .GT. 0) THEN + IF (WIC (COL) .EQ. -2) THEN + F1 = F1 + 1 + WPR (F1) = COL + ENDIF + ENDIF +970 CONTINUE + OKROW = F1 .LE. FFDIMR + IF (.NOT. OKROW) THEN +C exit out of loop if row too long: + GO TO 1000 + ENDIF + DO 980 I = FEDEGR+1, F1 + WIC (WPR (I)) = (I - 1) * FFDIMC +980 CONTINUE + FEDEGR = F1 + ELSE +C this is an artificial element (a dense column) + LURP = (EP+8) + COL = II (LURP) + IF (WIC (COL) .EQ. -2) THEN + WIC (COL) = FEDEGR * FFDIMC + FEDEGR = FEDEGR + 1 + WPR (FEDEGR) = COL + OKROW = FEDEGR .LE. FFDIMR + IF (.NOT. OKROW) THEN +C exit out of loop if row too long: + GO TO 1000 + ENDIF + ENDIF + ENDIF +990 CONTINUE +C loop exit label: +1000 CONTINUE + ENDIF + + IF (OKROW) THEN + +C ------------------------------------------------------------- +C assemble the original entries in the row +C ------------------------------------------------------------- + + RLEN = WC (PIVROW) + IF (RLEN .GT. 0) THEN + F1 = FEDEGR + RSIZ = II (PR) + P2 = PR + RSIZ +C split into two loops so that they both vectorize on a CRAY + DO 1010 P = P2 - RLEN, P2 - 1 + COL = II (P) + IF (WIC (COL) .EQ. -2) THEN +C this entry cannot be assembled, do not delete + F1 = F1 + 1 + WPR (F1) = COL + ENDIF +1010 CONTINUE + RLEN2 = F1 - FEDEGR + IF (RLEN2 .LT. RLEN) THEN +C delete one or more entries in the row + DO 1020 I = FEDEGR+1, F1 + II (P2 - F1 + I - 1) = WPR (I) +1020 CONTINUE + INEED = INEED - (RLEN - RLEN2) + WC (PIVROW) = RLEN2 + ENDIF + +C ---------------------------------------------------------- +C update the candidate row degree - excluding current front +C ---------------------------------------------------------- + + RDEG = F1 - FFLEFR + II (PR+1) = RDEG + +C ---------------------------------------------------------- +C pivot is found if candidate pivot row is not too long +C ---------------------------------------------------------- + + OKROW = F1 .LE. FFDIMR + IF (OKROW) THEN + DO 1030 I = FEDEGR+1, F1 + WIC (WPR (I)) = (I - 1) * FFDIMC +1030 CONTINUE + FEDEGR = F1 + ENDIF + + ELSE + +C ---------------------------------------------------------- +C update the candidate row degree - excluding current front +C ---------------------------------------------------------- + + RDEG = FEDEGR - FFLEFR + II (PR+1) = RDEG + ENDIF + ENDIF + +C ---------------------------------------------------------------- +C if pivot not found: clear WiR and WiC +C ---------------------------------------------------------------- + + PFOUND = OKROW .AND. OKCOL + IF (.NOT. PFOUND) THEN + MOVELU = K .GT. 0 + DO 1040 I = FFLEFR+1, FEDEGR + WIC (WPR (I)) = -2 +1040 CONTINUE + FEDEGR = FFLEFR + DO 1050 I = FFLEFC+1, FEDEGC + WIR (WPC (I)) = -1 +1050 CONTINUE + FEDEGC = FFLEFC + ELSE + MOVELU = FEDEGC .GT. FFDIMC - K .OR. FEDEGR .GT. FFDIMR - K + ENDIF + +C ---------------------------------------------------------------- +C WpR (1..fflefr) unextended pivot row pattern +C WpR (fflefr+1 .. fedegr) extended pattern, if pfound +C WpR (fedegr+1 .. n-npiv) empty space +C WpR (n-npiv+1 .. n) pivot row order +C +C WpC (1..fflefc) unextended pivot column pattern +C WpC (fflefc+1 .. fedegc) extended pattern, if pfound +C WpC (fedegc+1 .. n-npiv) empty space +C WpC (n-npiv+1 .. n) pivot column order +C ---------------------------------------------------------------- + +C======================================================================= +C Local pivot search complete ] +C======================================================================= + +C======================================================================= +C Update contribution block: rank-nb, or if LU arrowhead to be moved +C======================================================================= + + IF (K-K0 .GE. NB .OR. MOVELU) THEN + CALL DGEMM ('N', 'N', FFLEFC, FFLEFR, K-K0, + $ -ONE, XX (FFXP + (FFDIMR - K) * FFDIMC), FFDIMC, + $ XX (FFXP + FFDIMC - K) , FFDIMC, + $ ONE, XX (FFXP) , FFDIMC) + RINFO (6) = RINFO (6) + 2*FFLEFC*FFLEFR*(K-K0) + K0 = K + ENDIF + +C======================================================================= +C Move the LU arrowhead if no pivot found, or pivot needs room +C======================================================================= + + IF (MOVELU) THEN + +C allocate permanent space for the LU arrowhead + LUDEGR = FFLEFR + LUDEGC = FFLEFC + XS = K*LUDEGC + K*LUDEGR + K*K + IS = 7 + LUDEGC + LUDEGR + NSONS + IF (IS .GT. ITAIL-IHEAD .OR. XS .GT. XTAIL-XHEAD) THEN + IF (IS .GT. ITAIL-IHEAD) THEN +C garbage collection because we ran out of integer mem + INFO (14) = INFO (14) + 1 + ENDIF + IF (XS .GT. XTAIL-XHEAD) THEN +C garbage collection because we ran out of real mem + INFO (15) = INFO (15) + 1 + ENDIF + CALL MA38GD (XX, XSIZE, XHEAD, XUSE, + $ II, ISIZE, IHEAD, IUSE, + $ CP, RP, DN, N, WIR, WIC, WR, WC, + $ FFXP, FFSIZE, WXP, FFDIMC, .FALSE., + $ PFREE, XFREE, MHEAD, MTAIL, SLOTS) +C at this point, iuse = ineed and xuse = xneed + ENDIF + + ITAIL = ITAIL - IS + LUIP = ITAIL + IUSE = IUSE + IS + INEED = INEED + IS + XTAIL = XTAIL - XS + LUXP = XTAIL + XUSE = XUSE + XS + XNEED = XNEED + XS + INFO (18) = MAX (INFO (18), IUSE) + INFO (19) = MAX (INFO (19), INEED) + INFO (20) = MAX (INFO (20), XUSE) + INFO (21) = MAX (INFO (21), XNEED) + IF (IHEAD .GT. ITAIL .OR. XHEAD .GT. XTAIL) THEN +C error return, if not enough integer and/or real memory: + GO TO 9000 + ENDIF + +C ------------------------------------------------------------- +C get memory usage for next call to MA38BD +C ------------------------------------------------------------- + + XRUSE = XRUSE + XS + XRMAX = MAX (XRMAX, XRUSE) + +C ------------------------------------------------------------- +C save the new LU arrowhead +C ------------------------------------------------------------- + +C save the scalar data of the LU arrowhead + II (LUIP) = LUXP + II (LUIP+1) = K + II (LUIP+2) = LUDEGR + II (LUIP+3) = LUDEGC + II (LUIP+4) = NSONS + II (LUIP+5) = 0 + II (LUIP+6) = 0 + E = FFROW + IF (E .EQ. E1) THEN +C this is the first LU arrowhead from this global pivot + LUIP1 = LUIP + ENDIF + WR (E) = -(NDN+2) + WC (E) = -(NDN+2) + +C save column pattern + LUCP = (LUIP + 7) + DO 1060 I = 0, LUDEGC-1 + II (LUCP+I) = WPC (I+1) +1060 CONTINUE + +C save row pattern + LURP = LUCP + LUDEGC + DO 1070 I = 0, LUDEGR-1 + II (LURP+I) = WPR (I+1) +1070 CONTINUE + +C add list of sons after the end of the frontal matrix pattern +C this list of sons is for the refactorization (MA38BD) only. + LUSONP = LURP + LUDEGR + IP = LUSONP + E = SONLST +C while (e > 0) do +1080 CONTINUE + IF (E .GT. 0) THEN + EP = RP (E) + IF (WC (E) .EQ. -(NDN+2)) THEN +C LUson + II (IP) = E + ELSE IF (WC (E) .EQ. W0) THEN +C Uson + II (IP) = E + N + ELSE IF (WR (E) .EQ. W0) THEN +C Lson + II (IP) = E + 2*N + ENDIF + NEXT = WIR (E) + N + 2 + WIR (E) = -1 + E = NEXT + IP = IP + 1 +C end while: + GOTO 1080 + ENDIF + NSONS = 0 + SONLST = 0 + +C move the L1,U1 matrix, compressing the dimension from +C ffdimc to ldimc. The LU arrowhead grows on top of stack. + LDIMC = K + LUDEGC + XP = FFXP + (FFDIMR-1)*FFDIMC + FFDIMC-1 + DO 1100 J = 0, K-1 +CFPP$ NODEPCHK L + DO 1090 I = 0, K-1 + XX (LUXP + J*LDIMC + I) = XX (XP - J*FFDIMC - I) +1090 CONTINUE +1100 CONTINUE + +C move L2 matrix, compressing dimension from ffdimc to ludegc+k + IF (LUDEGC .NE. 0) THEN + LXP = LUXP + K + XP = FFXP + (FFDIMR-1)*FFDIMC + DO 1120 J = 0, K-1 +CFPP$ NODEPCHK L + DO 1110 I = 0, LUDEGC-1 + XX (LXP + J*LDIMC + I) = XX (XP - J*FFDIMC + I) +1110 CONTINUE +1120 CONTINUE + ENDIF + +C move the U2 block. + IF (LUDEGR .NE. 0) THEN + UXP = LUXP + K * LDIMC + XP = FFXP + FFDIMC-1 + DO 1140 J = 0, LUDEGR-1 +CFPP$ NODEPCHK L + DO 1130 I = 0, K-1 + XX (UXP + J*K + I) = XX (XP + J*FFDIMC - I) +1130 CONTINUE +1140 CONTINUE + ENDIF + +C one more LU arrowhead has been created + NLU = NLU + 1 + NZU = (K*(K-1)/2) + K*LUDEGC + NZL = (K*(K-1)/2) + K*LUDEGR + INFO (10) = INFO (10) + NZL + INFO (11) = INFO (11) + NZU + +C no more rows of U or columns of L in current frontal array + K = 0 + K0 = 0 + + IF (PFOUND) THEN + +C ---------------------------------------------------------- +C Place the old frontal matrix as the only item in the son +C list, since the next "implied" frontal matrix will have +C this as its son. +C ---------------------------------------------------------- + + NSONS = 1 + E = FFROW + WIR (E) = - N - 2 + SONLST = E + +C ---------------------------------------------------------- +C The contribution block of the old frontal matrix is still +C stored in the current frontal matrix, and continues (in a +C unifrontal sense) as a "new" frontal matrix (same array +C but with a new name, and the LU arrowhead is removed and +C placed in the LU factors). Old name is "ffrow", new name +C is "pivrow". +C ---------------------------------------------------------- + + RP (E) = LUIP + FFROW = PIVROW + ENDIF + ENDIF + +C======================================================================= +C Stop the factorization of this frontal matrix if no pivot found +C======================================================================= + +C (this is the only way out of loop 1395) + IF (.NOT. PFOUND) THEN +C exit out of loop 1395 if pivot not found: + GO TO 1400 + ENDIF + +C======================================================================= +C Update the pivot column, and move into position as (k+1)-st col of L +C======================================================================= + + XSP = (COLPOS - 1) * FFDIMC + XDP = (FFDIMR - K - 1) * FFDIMC + FSP = FFXP + XSP + FDP = FFXP + XDP + + IF (K-K0 .GT. 0 .AND. FFLEFC .NE. 0) THEN + CALL DGEMV ('N', FFLEFC, K-K0, + $ -ONE, XX (FDP + FFDIMC ), FFDIMC, + $ XX (FSP + FFDIMC - K), 1, + $ ONE, XX (FSP ), 1) + RINFO (5) = RINFO (5) + 2*FFLEFC*(K-K0) + ENDIF + + IF (FFLEFR .LT. FFDIMR - K) THEN + + XLP = (FFLEFR - 1) * FFDIMC + IF (FFLEFR .EQ. COLPOS) THEN + +C ---------------------------------------------------------- +C move C(:,colpos) => C(:,ffdimr-k) +C ---------------------------------------------------------- + +C copy only what needs to be copied +C column of the contribution block: +CFPP$ NODEPCHK L + DO 1160 I = 0, FFLEFC - 1 + XX (FDP+I) = XX (FSP+I) +1160 CONTINUE +C column of the U2 block +CFPP$ NODEPCHK L + DO 1170 I = FFDIMC - K, FFDIMC - 1 + XX (FDP+I) = XX (FSP+I) +1170 CONTINUE + + ELSE + +C ---------------------------------------------------------- +C move C(:,colpos) => C(:,ffdimr-k) +C move C(:,fflefr) => C(:,colpos) +C ---------------------------------------------------------- + + FLP = FFXP + XLP + +C copy only what needs to be copied +C columns of the contribution block: +CFPP$ NODEPCHK L + DO 1190 I = 0, FFLEFC - 1 + XX (FDP+I) = XX (FSP+I) + XX (FSP+I) = XX (FLP+I) +1190 CONTINUE +C columns of the U2 block: +CFPP$ NODEPCHK L + DO 1200 I = FFDIMC - K, FFDIMC - 1 + XX (FDP+I) = XX (FSP+I) + XX (FSP+I) = XX (FLP+I) +1200 CONTINUE + + SWPCOL = WPR (FFLEFR) + WPR (COLPOS) = SWPCOL + WIC (SWPCOL) = XSP + ENDIF + + IF (FEDEGR .NE. FFLEFR) THEN +C move column fedegr to column fflefr (pattern only) + SWPCOL = WPR (FEDEGR) + WPR (FFLEFR) = SWPCOL + WIC (SWPCOL) = XLP + ENDIF + + ELSE IF (COLPOS .NE. FFDIMR - K) THEN + +C ------------------------------------------------------------- +C swap C(:,colpos) <=> C (:,ffdimr-k) +C ------------------------------------------------------------- + +C swap only what needs to be swapped +C columns of the contribution block: +CFPP$ NODEPCHK L +CFPP$ NOLSTVAL L + DO 1220 I = 0, FFLEFC - 1 + X = XX (FDP+I) + XX (FDP+I) = XX (FSP+I) + XX (FSP+I) = X +1220 CONTINUE +C columns of the U2 block: +CFPP$ NODEPCHK L +CFPP$ NOLSTVAL L + DO 1230 I = FFDIMC - K, FFDIMC - 1 + X = XX (FDP+I) + XX (FDP+I) = XX (FSP+I) + XX (FSP+I) = X +1230 CONTINUE + SWPCOL = WPR (FFDIMR - K) + WPR (COLPOS) = SWPCOL + WIC (SWPCOL) = XSP + ENDIF + + WIC (PIVCOL) = XDP + FEDEGR = FEDEGR - 1 + SCAN2 = FFLEFR + FFLEFR = FFLEFR - 1 + +C======================================================================= +C Move pivot row into position as (k+1)-st row of U, and update +C======================================================================= + + XSP = ROWPOS - 1 + XDP = FFDIMC - K - 1 + FSP = FFXP + XSP + FDP = FFXP + XDP + + IF (FFLEFC .LT. FFDIMC - K) THEN + + XLP = FFLEFC - 1 + IF (FFLEFC .EQ. ROWPOS) THEN + +C ---------------------------------------------------------- +C move C(rowpos,:) => C(ffdimc-k,:) +C ---------------------------------------------------------- + +C copy only what needs to be copied +C row of the contribution block: +CFPP$ NODEPCHK L + DO 1250 J = 0, (FFLEFR - 1) * FFDIMC, FFDIMC + XX (FDP+J) = XX (FSP+J) +1250 CONTINUE +C row of the L2 block: +CFPP$ NODEPCHK L + DO 1260 J = (FFDIMR - K - 1) * FFDIMC, + $ (FFDIMR - 1) * FFDIMC, FFDIMC + XX (FDP+J) = XX (FSP+J) +1260 CONTINUE + + ELSE + +C ---------------------------------------------------------- +C move C(rowpos,:) => C(ffdimc-k,:) +C move C(fflefc,:) => C(rowpos,:) +C ---------------------------------------------------------- + + FLP = FFXP + XLP +C copy only what needs to be copied +C rows of the contribution block: +CFPP$ NODEPCHK L + DO 1280 J = 0, (FFLEFR - 1) * FFDIMC, FFDIMC + XX (FDP+J) = XX (FSP+J) + XX (FSP+J) = XX (FLP+J) +1280 CONTINUE +C rows of the L2 block: +CFPP$ NODEPCHK L + DO 1290 J = (FFDIMR - K - 1) * FFDIMC, + $ (FFDIMR - 1) * FFDIMC, FFDIMC + XX (FDP+J) = XX (FSP+J) + XX (FSP+J) = XX (FLP+J) +1290 CONTINUE + SWPROW = WPC (FFLEFC) + WPC (ROWPOS) = SWPROW + WIR (SWPROW) = XSP + ENDIF + + IF (FEDEGC .NE. FFLEFC) THEN +C move row fedegc to row fflefc (pattern only) + SWPROW = WPC (FEDEGC) + WPC (FFLEFC) = SWPROW + WIR (SWPROW) = XLP + ENDIF + + ELSE IF (ROWPOS .NE. FFDIMC - K) THEN + +C ------------------------------------------------------------- +C swap C(rowpos,:) <=> C (ffdimc-k,:) +C ------------------------------------------------------------- + +C swap only what needs to be swapped +C rows of the contribution block: +CFPP$ NODEPCHK L +CFPP$ NOLSTVAL L + DO 1310 J = 0, (FFLEFR - 1) * FFDIMC, FFDIMC + X = XX (FDP+J) + XX (FDP+J) = XX (FSP+J) + XX (FSP+J) = X +1310 CONTINUE +C rows of the L2 block: +CFPP$ NODEPCHK L +CFPP$ NOLSTVAL L + DO 1320 J = (FFDIMR - K - 1) * FFDIMC, + $ (FFDIMR - 1) * FFDIMC, FFDIMC + X = XX (FDP+J) + XX (FDP+J) = XX (FSP+J) + XX (FSP+J) = X + +1320 CONTINUE + SWPROW = WPC (FFDIMC - K) + WPC (ROWPOS) = SWPROW + WIR (SWPROW) = XSP + ENDIF + + WIR (PIVROW) = XDP + FEDEGC = FEDEGC - 1 + SCAN1 = FFLEFC + FFLEFC = FFLEFC - 1 + + IF (K-K0 .GT. 0 .AND. FFLEFR .GT. 0) THEN + CALL DGEMV ('T', K-K0, FFLEFR, + $ -ONE, XX (FDP + 1) , FFDIMC, + $ XX (FDP + (FFDIMR - K) * FFDIMC), FFDIMC, + $ ONE, XX (FDP) , FFDIMC) + RINFO (5) = RINFO (5) + 2*(K-K0)*FFLEFR + ENDIF + +C======================================================================= +C Prepare for degree update and next local pivot search +C======================================================================= + +C ---------------------------------------------------------------- +C if only column pattern has been extended: +C scan1: new rows only +C scan2: no columns scanned +C scan3: all columns +C scan4: new rows only +C +C if only row pattern has been extended: +C scan1: no rows scanned +C scan2: new columns only +C scan3: new columns only +C scan4: all rows +C +C if both row and column pattern have been extended: +C scan1: new rows only +C scan2: new columns only +C scan3: all columns +C scan4: all rows +C +C if no patterns have been extended: +C scan1-4: none +C ---------------------------------------------------------------- + + IF (FEDEGC .EQ. FFLEFC) THEN +C column pattern has not been extended + SCAN3 = FFLEFR + 1 + ELSE +C column pattern has been extended. + SCAN3 = 0 + ENDIF + + IF (FEDEGR .EQ. FFLEFR) THEN +C row pattern has not been extended + SCAN4 = FFLEFC + 1 + ELSE +C row pattern has been extended + SCAN4 = 0 + ENDIF + +C======================================================================= +C Finished with step k (except for assembly and scaling of pivot col) +C======================================================================= + + K = K + 1 + +C ---------------------------------------------------------------- +C exit loop if frontal matrix has been extended +C ---------------------------------------------------------------- + + IF (FEDEGR .NE. FFLEFR .OR. FEDEGC .NE. FFLEFC) THEN + GO TO 1325 + ENDIF + +1324 CONTINUE +C exit label for loop 1324: +1325 CONTINUE + +C======================================================================= +C Finished factorizing while frontal matrix is not extended ] +C======================================================================= + +C======================================================================= +C Extend the frontal matrix [ +C======================================================================= + +C ---------------------------------------------------------------- +C Zero the newly extended frontal matrix +C ---------------------------------------------------------------- + +C fill-in due to amalgamation caused by this step is +C k*(fedegr-fflefr+fedegc-fflefc) + + DO 1350 J = FFLEFR, FEDEGR - 1 +C zero the new columns in the contribution block: + DO 1330 I = 0, FEDEGC - 1 + XX (FFXP + J*FFDIMC + I) = ZERO +1330 CONTINUE +C zero the new columns in U block: + DO 1340 I = FFDIMC - K, FFDIMC - 1 + XX (FFXP + J*FFDIMC + I) = ZERO +1340 CONTINUE +1350 CONTINUE + +CFPP$ NODEPCHK L + DO 1380 I = FFLEFC, FEDEGC - 1 +C zero the new rows in the contribution block: +CFPP$ NODEPCHK L + DO 1360 J = 0, FFLEFR - 1 + XX (FFXP + J*FFDIMC + I) = ZERO +1360 CONTINUE +C zero the new rows in L block: +CFPP$ NODEPCHK L + DO 1370 J = FFDIMR - K, FFDIMR - 1 + XX (FFXP + J*FFDIMC + I) = ZERO +1370 CONTINUE +1380 CONTINUE + +C ---------------------------------------------------------------- +C remove the new columns from the degree lists +C ---------------------------------------------------------------- + + DO 1390 J = FFLEFR+1, FEDEGR + PC = CP (WPR (J)) + CDEG = II (PC+1) + IF (CDEG .GT. 0) THEN + CNXT = II (PC+7) + CPRV = II (PC+8) + IF (CNXT .NE. 0) THEN + II (CP (CNXT)+8) = CPRV + ENDIF + IF (CPRV .NE. 0) THEN + II (CP (CPRV)+7) = CNXT + ELSE + HEAD (CDEG) = CNXT + ENDIF + ENDIF +1390 CONTINUE + +C ---------------------------------------------------------------- +C finalize extended row and column pattern of the frontal matrix +C ---------------------------------------------------------------- + + FFLEFC = FEDEGC + FFLEFR = FEDEGR + FMAXR = MAX (FMAXR, FFLEFR + K) + FMAXC = MAX (FMAXC, FFLEFC + K) + +C======================================================================= +C Done extending the current frontal matrix ] +C======================================================================= + +1395 CONTINUE +C exit label for loop 1395: +1400 CONTINUE + +C======================================================================= +C Done assembling and factorizing the current frontal matrix ] +C======================================================================= + +C======================================================================= +C Wrap-up: complete the current frontal matrix [ +C======================================================================= + +C ---------------------------------------------------------------- +C store the maximum front size in the first LU arrowhead +C ---------------------------------------------------------------- + + II (LUIP1+5) = FMAXR + II (LUIP1+6) = FMAXC + +C one more frontal matrix is finished + INFO (13) = INFO (13) + 1 + +C ---------------------------------------------------------------- +C add the current frontal matrix to the degrees of each column, +C and place the modified columns back in the degree lists +C ---------------------------------------------------------------- + +C do so in reverse order to try to improve pivot tie-breaking + DO 1410 J = FFLEFR, 1, -1 + COL = WPR (J) + PC = CP (COL) +C add the current frontal matrix to the degree + CDEG = II (PC+1) + CDEG = MIN (KLEFT, CDEG + FFLEFC) + IF (CDEG .GT. 0) THEN + II (PC+1) = CDEG + CNXT = HEAD (CDEG) + II (PC+7) = CNXT + II (PC+8) = 0 + IF (CNXT .NE. 0) THEN + II (CP (CNXT)+8) = COL + ENDIF + HEAD (CDEG) = COL + MINDEG = MIN (MINDEG, CDEG) + ENDIF +1410 CONTINUE + +C ---------------------------------------------------------------- +C add the current frontal matrix to the degrees of each row +C ---------------------------------------------------------------- + +CFPP$ NODEPCHK L + DO 1420 I = 1, FFLEFC + ROW = WPC (I) + PR = RP (ROW) + RDEG = II (PR+1) + RDEG = MIN (KLEFT, RDEG + FFLEFR) + II (PR+1) = RDEG +1420 CONTINUE + +C ---------------------------------------------------------------- +C Reset w0 so that Wr (1..n) < w0 and Wc (1..n) < w0. +C Also ensure that w0 + n would not cause integer overflow +C ---------------------------------------------------------------- + + W1 = W0 + FMAX + 1 + IF (W1 .LE. W0) THEN + W0 = NDN+2 + DO 1430 E = 1, N+DN + IF (WR (E) .GT. NDN) THEN +C this is a frontal matrix + WR (E) = W0-1 + WC (E) = W0-1 + ENDIF +1430 CONTINUE + ELSE + W0 = W1 + ENDIF + +C ---------------------------------------------------------------- +C deallocate work vector +C ---------------------------------------------------------------- + + XUSE = XUSE - FFDIMC + XNEED = XNEED - FFDIMC + XHEAD = XHEAD - FFDIMC + +C ---------------------------------------------------------------- +C get the name of this new frontal matrix, and size of +C contribution block +C ---------------------------------------------------------------- + + E = FFROW + XS = FFLEFR * FFLEFC + FMAX = MAX (FMAX, FFLEFR, FFLEFC) + +C ---------------------------------------------------------------- +C get memory usage for next call to MA38BD +C ---------------------------------------------------------------- + + XRUSE = XRUSE - FFSIZE + XS + +C ---------------------------------------------------------------- +C if contribution block empty, deallocate and continue next step +C ---------------------------------------------------------------- + + IF (FFLEFR .LE. 0 .OR. FFLEFC .LE. 0) THEN + RP (E) = LUIP + XUSE = XUSE - FFSIZE + XNEED = XNEED - FFSIZE + XHEAD = FFXP + DO 1440 I = 1, FFLEFR + WIC (WPR (I)) = -2 +1440 CONTINUE + DO 1450 I = 1, FFLEFC + WIR (WPC (I)) = -1 +1450 CONTINUE +C next iteration of main factorization loop 1540: + GOTO 1540 + ENDIF + +C ---------------------------------------------------------------- +C prepare the contribution block for later assembly +C ---------------------------------------------------------------- + + IF (FSCAL .GT. ITAIL-IHEAD) THEN + INFO (14) = INFO (14) + 1 + INTZER = 0 + CALL MA38GD (XX, XSIZE, XHEAD, XUSE, + $ II, ISIZE, IHEAD, IUSE, + $ CP, RP, DN, N, WIR, WIC, WR, WC, + $ FFXP, FFSIZE, INTZER, INTZER, .FALSE., + $ PFREE, XFREE, MHEAD, MTAIL, SLOTS) +C at this point, iuse = ineed and xuse = xneed + ENDIF + + EP = IHEAD + IHEAD = IHEAD + FSCAL + IUSE = IUSE + FSCAL + INEED = INEED + FSCAL + INFO (18) = MAX (INFO (18), IUSE) + INFO (19) = MAX (INFO (19), INEED) + IF (IHEAD .GT. ITAIL) THEN +C error return, if not enough integer memory: +C (highly unlikely to run out of memory at this point) + GO TO 9000 + ENDIF + + RP (E) = EP + II (EP) = LUIP + II (EP+5) = FFLEFR + II (EP+6) = FFLEFC + WR (E) = W0-1 + WC (E) = W0-1 + +C count the numerical assembly + RINFO (2) = RINFO (2) + XS + + IF (XS .LE. XFREE) THEN + +C ------------------------------------------------------------- +C compress and store the contribution block in a freed block +C ------------------------------------------------------------- + +C place the new block in the list in front of the free block + XDP = II (PFREE+2) + II (PFREE+2) = II (PFREE+2) + XS + XFREE = XFREE - XS + MPREV = II (PFREE+4) + IF (XFREE .EQ. 0) THEN +C delete the free block if its size is zero + MNEXT = II (PFREE+3) + PFREE = 0 + XFREE = -1 + ELSE + MNEXT = PFREE + ENDIF + IF (MNEXT .NE. 0) THEN + II (MNEXT+4) = EP + ELSE + MTAIL = EP + ENDIF + IF (MPREV .NE. 0) THEN + II (MPREV+3) = EP + ELSE + MHEAD = EP + ENDIF + DO 1470 J = 0, FFLEFR - 1 +CFPP$ NODEPCHK L + DO 1460 I = 0, FFLEFC - 1 + XX (XDP + J*FFLEFC + I) = XX (FFXP + J*FFDIMC + I) +1460 CONTINUE +1470 CONTINUE + XHEAD = FFXP + XUSE = XUSE - FFSIZE + XNEED = XNEED - FFSIZE + XS + FFDIMC = FFLEFC + II (EP+1) = FFDIMC + II (EP+2) = XDP + II (EP+3) = MNEXT + II (EP+4) = MPREV + + ELSE + +C ------------------------------------------------------------- +C deallocate part of the unused portion of the frontal matrix +C ------------------------------------------------------------- + +C leave the contribution block C (1..fflefc, 1..fflefr) at the +C head of XX, with column dimension of ffdimc and in space +C of size (fflefr-1)*ffdimc for the first fflefr columns, and +C fflefc for the last column. + XNEED = XNEED - FFSIZE + XS + XS = FFSIZE - (FFLEFC + (FFLEFR-1)*FFDIMC) + XHEAD = XHEAD - XS + XUSE = XUSE - XS + II (EP+1) = FFDIMC + II (EP+2) = FFXP + II (EP+3) = 0 + II (EP+4) = MTAIL + IF (MTAIL .EQ. 0) THEN + MHEAD = EP + ELSE + II (MTAIL+3) = EP + ENDIF + MTAIL = EP + ENDIF + +C ---------------------------------------------------------------- +C add tuples to the amount of integer space needed - and add +C limit+cscal to maximum need to account for worst-case possible +C reallocation of rows/columns. Required integer memory usage +C is guaranteed not to exceed iworst during the placement of (e,f) +C tuples in the two loops below. +C ---------------------------------------------------------------- + + INEED = INEED + 2*(FFLEFR+FFLEFC) + IWORST = INEED + LIMIT + CSCAL + INFO (19) = MAX (INFO (19), IWORST) + INFO (18) = MAX (INFO (18), IWORST) + +C ---------------------------------------------------------------- +C place (e,f) in the element list of each column +C ---------------------------------------------------------------- + + DO 1500 I = 1, FFLEFR + COL = WPR (I) + PC = CP (COL) + CELN = II (PC+5) + CSIZ = II (PC) + CLEN = II (PC+6) +C clear the column offset + WIC (COL) = -2 + +C ------------------------------------------------------------- +C make sure an empty slot exists - if not, create one +C ------------------------------------------------------------- + + IF (2*(CELN+1) + CLEN + CSCAL .GT. CSIZ) THEN + +C ---------------------------------------------------------- +C no room exists - reallocate elsewhere +C ---------------------------------------------------------- + +C at least this much space is needed: + IS = 2 * (CELN + 1) + CLEN +C add some slots for growth: at least 8 tuples, +C or double the size - whichever is larger (but with a total +C size not larger than limit+cscal) + IS = MIN (IS + MAX (16, IS), LIMIT) + CSIZ2 = IS + CSCAL + +C ---------------------------------------------------------- +C make sure enough room exists: garbage collection if needed +C ---------------------------------------------------------- + + IF (CSIZ2 .GT. ITAIL-IHEAD) THEN +C garbage collection: + INFO (14) = INFO (14) + 1 + INTZER = 0 + CALL MA38GD (XX, XSIZE, XHEAD, XUSE, + $ II, ISIZE, IHEAD, IUSE, + $ CP, RP, DN, N, WIR, WIC, WR, WC, + $ INTZER, INTZER, INTZER, INTZER, .TRUE., + $ PFREE, XFREE, MHEAD, MTAIL, SLOTS) +C at this point, iuse+csiz2 <= iworst and xuse = xneed + PC = CP (COL) + CSIZ = II (PC) + ENDIF + +C ---------------------------------------------------------- +C get space for the new copy +C ---------------------------------------------------------- + + PC2 = IHEAD + IHEAD = IHEAD + CSIZ2 + IUSE = IUSE + CSIZ2 + INFO (18) = MAX (INFO (18), IUSE) + IF (IHEAD .GT. ITAIL) THEN +C error return, if not enough integer memory: + GO TO 9000 + ENDIF + +C ---------------------------------------------------------- +C make the copy, leaving hole in middle for element list +C ---------------------------------------------------------- + +C copy the cscal scalars, and the element list +CFPP$ NODEPCHK L + DO 1480 J = 0, CSCAL + 2*CELN - 1 + II (PC2+J) = II (PC+J) +1480 CONTINUE + +C copy column indices of original entries (XX is unchanged) +CFPP$ NODEPCHK L + DO 1490 J = 0, CLEN - 1 + II (PC2+CSIZ2-CLEN+J) = II (PC+CSIZ-CLEN+J) +1490 CONTINUE + + IF (CLEN .GT. 0) THEN +C place the new block in the memory-list + MNEXT = II (PC2+3) + MPREV = II (PC2+4) + IF (MNEXT .NE. 0) THEN + II (MNEXT+4) = PC2 + ELSE + MTAIL = PC2 + ENDIF + IF (MPREV .NE. 0) THEN + II (MPREV+3) = PC2 + ELSE + MHEAD = PC2 + ENDIF + ENDIF + + CP (COL) = PC2 + II (PC2) = CSIZ2 + +C ---------------------------------------------------------- +C deallocate the old copy of the column in II (not in XX) +C ---------------------------------------------------------- + + II (PC+1) = -1 + II (PC+6) = 0 + PC = PC2 + ENDIF + +C ------------------------------------------------------------- +C place the new (e,f) tuple in the element list of the column +C ------------------------------------------------------------- + + CEP = (PC+9) + II (CEP + 2*CELN ) = E + II (CEP + 2*CELN+1) = I - 1 + II (PC+5) = CELN + 1 +1500 CONTINUE + +C ---------------------------------------------------------------- +C place (e,f) in the element list of each row +C ---------------------------------------------------------------- + + DO 1530 I = 1, FFLEFC + ROW = WPC (I) + PR = RP (ROW) + RSIZ = II (PR) + RELN = WR (ROW) + RLEN = WC (ROW) +C clear the row offset + WIR (ROW) = -1 + +C ------------------------------------------------------------- +C make sure an empty slot exists - if not, create one +C ------------------------------------------------------------- + + IF (2*(RELN+1) + RLEN + RSCAL .GT. RSIZ) THEN + +C ---------------------------------------------------------- +C no room exists - reallocate elsewhere +C ---------------------------------------------------------- + +C at least this much space is needed: + IS = 2 * (RELN + 1) + RLEN +C add some extra slots for growth - for at least 8 +C tuples, or double the size (but with a total size not +C larger than limit+rscal) + IS = MIN (IS + MAX (16, IS), LIMIT) + RSIZ2 = IS + RSCAL + +C ---------------------------------------------------------- +C make sure enough room exists: garbage collection if needed +C ---------------------------------------------------------- + + IF (RSIZ2 .GT. ITAIL-IHEAD) THEN +C garbage collection: + INFO (14) = INFO (14) + 1 + INTZER = 0 + CALL MA38GD (XX, XSIZE, XHEAD, XUSE, + $ II, ISIZE, IHEAD, IUSE, + $ CP, RP, DN, N, WIR, WIC, WR, WC, + $ INTZER, INTZER, INTZER, INTZER, .TRUE., + $ PFREE, XFREE, MHEAD, MTAIL, SLOTS) +C at this point, iuse+rsiz2 <= iworst and xuse = xneed + PR = RP (ROW) + RSIZ = II (PR) + ENDIF + +C ---------------------------------------------------------- +C get space for the new copy +C ---------------------------------------------------------- + + PR2 = IHEAD + IHEAD = IHEAD + RSIZ2 + IUSE = IUSE + RSIZ2 + INFO (18) = MAX (INFO (18), IUSE) + IF (IHEAD .GT. ITAIL) THEN +C error return, if not enough integer memory: + GO TO 9000 + ENDIF + +C ---------------------------------------------------------- +C make the copy, leaving hole in middle for element list +C ---------------------------------------------------------- + +C copy the rscal scalars, and the element list +CFPP$ NODEPCHK L + DO 1510 J = 0, RSCAL + 2*RELN - 1 + II (PR2+J) = II (PR+J) +1510 CONTINUE + +C copy the original entries +CFPP$ NODEPCHK L + DO 1520 J = 0, RLEN - 1 + II (PR2+RSIZ2-RLEN+J) = II (PR+RSIZ-RLEN+J) +1520 CONTINUE + + RP (ROW) = PR2 + II (PR2) = RSIZ2 + +C ---------------------------------------------------------- +C deallocate the old copy of the row +C ---------------------------------------------------------- + + II (PR+1) = -1 + PR = PR2 + ENDIF + +C ------------------------------------------------------------- +C place the new (e,f) tuple in the element list of the row +C ------------------------------------------------------------- + + REP = (PR+2) + II (REP + 2*RELN ) = E + II (REP + 2*RELN+1) = I - 1 + WR (ROW) = RELN + 1 +1530 CONTINUE + +C======================================================================= +C Wrap-up of factorized frontal matrix is complete ] +C======================================================================= + +1540 CONTINUE +C exit label for loop 1540: +2000 CONTINUE + +C======================================================================= +C======================================================================= +C END OF MAIN FACTORIZATION LOOP ] +C======================================================================= +C======================================================================= + +C======================================================================= +C Wrap-up: store LU factors in their final form [ +C======================================================================= + +C ---------------------------------------------------------------- +C deallocate all remaining columns, rows, and frontal matrices +C ---------------------------------------------------------------- + + IUSE = IUSE - (IHEAD - 1) + XUSE = XUSE - (XHEAD - 1) + INEED = IUSE + XNEED = XUSE + IHEAD = 1 + XHEAD = 1 + + IF (NLU .EQ. 0) THEN +C LU factors are completely empty (A = 0). +C Add one integer and one real, to simplify rest of code. +C Otherwise, some arrays in MA38BD or MA38CD would have +C zero size, which can cause an address fault. + ITAIL = ISIZE + XTAIL = XSIZE + IUSE = IUSE + 1 + XUSE = XUSE + 1 + INEED = IUSE + XNEED = XUSE + IP = ITAIL + XP = XTAIL + ENDIF + +C ---------------------------------------------------------------- +C compute permutation and inverse permutation vectors. +C use WiR/C for the row/col permutation, and WpR/C for the +C inverse row/col permutation. +C ---------------------------------------------------------------- + + DO 2010 K = 1, N +C the kth pivot row and column: + ROW = WPR (N-K+1) + COL = WPC (N-K+1) + WIR (K) = ROW + WIC (K) = COL +2010 CONTINUE +C replace WpR/C with the inversion permutations: + DO 2020 K = 1, N + ROW = WIR (K) + COL = WIC (K) + WPR (ROW) = K + WPC (COL) = K +2020 CONTINUE + + IF (PGIVEN) THEN +C the input matrix had been permuted from the original ordering +C according to Rperm and Cperm. Combine the initial +C permutations (now in Rperm and Cperm) and the pivoting +C permutations, and place them back into Rperm and Cperm. + DO 2030 ROW = 1, N + WM (WPR (ROW)) = RPERM (ROW) +2030 CONTINUE + DO 2040 ROW = 1, N + RPERM (ROW) = WM (ROW) +2040 CONTINUE + DO 2050 COL = 1, N + WM (WPC (COL)) = CPERM (COL) +2050 CONTINUE + DO 2060 COL = 1, N + CPERM (COL) = WM (COL) +2060 CONTINUE +C else +C the input matrix was not permuted on input. Rperm and Cperm +C in MA38ED have been passed to this routine as WiR and WiC, +C which now contain the row and column permutations. Rperm and +C Cperm in this routine (MA38FD) are not defined. + ENDIF + +C ---------------------------------------------------------------- +C allocate nlu+3 integers for xtail, nlu, npiv and LUp (1..nlu) +C ---------------------------------------------------------------- + + IS = NLU + 5 + LUIP1 = ITAIL + ITAIL = ITAIL - IS + IUSE = IUSE + IS + INEED = IUSE + INFO (18) = MAX (INFO (18), IUSE) + INFO (19) = MAX (INFO (19), INEED) + IF (IHEAD .LE. ITAIL) THEN + +C ------------------------------------------------------------- +C sufficient memory exist to finish the factorization +C ------------------------------------------------------------- + + II (ITAIL+1) = NLU + II (ITAIL+2) = NPIV + LUPP = ITAIL+5 + IF (NLU .EQ. 0) THEN +C zero the dummy entries, if LU factors are empty + II (IP) = 0 + XX (XP) = ZERO + ENDIF + +C ------------------------------------------------------------- +C convert the LU factors into the new pivot order +C ------------------------------------------------------------- + + S = 0 + MAXDR = 1 + MAXDC = 1 + DO 2100 K = 1, N + E = WIR (K) + LUIP = RP (E) + IF (LUIP .GT. 0) THEN +C this is an LU arrowhead - save a pointer in LUp: + S = S + 1 +C update pointers to LU arrowhead relative to start of LU + II (LUPP+S-1) = LUIP - LUIP1 + 1 + LUXP = II (LUIP) + II (LUIP) = LUXP - XTAIL + 1 +C convert the row and column indices to their final order +C pattern of a column of L: + P = (LUIP + 7) + LUDEGC = II (LUIP+3) + MAXDC = MAX (MAXDC, LUDEGC) + DO 2070 J = 1, LUDEGC + II (P) = WPR (ABS (II (P))) + P = P + 1 +2070 CONTINUE +C pattern of a row of U: + LUDEGR = II (LUIP+2) + MAXDR = MAX (MAXDR, LUDEGR) + DO 2080 J = 1, LUDEGR + II (P) = WPC (ABS (II (P))) + P = P + 1 +2080 CONTINUE +C convert the LUsons, Usons, and Lsons: + NSONS = II (LUIP+4) + DO 2090 J = 1, NSONS + ESON = II (P) + IF (ESON .LE. N) THEN +C an LUson + II (P) = WM (ESON) + ELSE IF (ESON .LE. 2*N) THEN +C a Uson + II (P) = WM (ESON-N) + N + ELSE +C an Lson + II (P) = WM (ESON-2*N) + 2*N + ENDIF + P = P + 1 +2090 CONTINUE +C renumber this LU arrowhead + WM (E) = S + ENDIF +2100 CONTINUE + + CMAX = MAX (CMAX, MAXDC) + RMAX = MAX (RMAX, MAXDR) + TOTNLU = TOTNLU + NLU + + II (ITAIL+3) = MAXDC + II (ITAIL+4) = MAXDR + +C ------------------------------------------------------------- +C get memory usage for next call to MA38BD +C ------------------------------------------------------------- + + XRUSE = XRUSE - NZ + RETURN + ENDIF + +C======================================================================= +C LU factors are now stored in their final form ] +C======================================================================= + +C======================================================================= +C Error conditions +C======================================================================= + +C error return label: +9000 CONTINUE + IF (IHEAD .GT. ITAIL .OR. ISIZE .LT. MINMEM) THEN +C error return if out of integer memory + CALL MA38ND (1, ICNTL, INFO, -3, INFO (19)) + ENDIF + IF (XHEAD .GT. XTAIL) THEN +C error return if out of real memory + CALL MA38ND (1, ICNTL, INFO, -4, INFO (21)) + ENDIF + RETURN + END + + SUBROUTINE MA38GD (XX, XSIZE, XHEAD, XUSE, + * II, ISIZE, IHEAD, IUSE, + * CP, RP, DN, N, WIR, WIC, WR, WC, + * FFXP, FFSIZE, WXP, FFDIMC, DOSLOT, + * PFREE, XFREE, MHEAD, MTAIL, SLOTS) + INTEGER N, DN, ISIZE, II(ISIZE), IHEAD, RP(N+DN), + * CP(N+1), WIR(N), WIC(N), XSIZE, XUSE, + * IUSE, XHEAD, FFXP, FFSIZE, WXP, + * FFDIMC, WR(N+DN), WC(N+DN), PFREE, XFREE, MHEAD, + * MTAIL, SLOTS + LOGICAL DOSLOT + DOUBLE PRECISION XX (XSIZE) + +C=== MA38GD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Garbage collection for MA38FD. + +C======================================================================= +C INPUT: +C======================================================================= +C +C II/XX: integer/real workspace, containing matrix being +C factorized and partially-computed LU factors +C isize: size of II +C xsize: size of XX +C xhead: XX (1..xhead) is in use (matrix, frontal mtc's) +C xtail: XX (xtail..xsize) is in use (LU factors) +C xuse: memory usage in Value +C ihead: II (1..ihead) is in use (matrix, frontal mtc's) +C itail: II (itail..isize) is in use (LU factors) +C iuse: memory usage in Index +C Cp (1..n+1): pointers to columns +C Rp (1..n+dn): pointers to rows, frontal matrices, and LU +C arrowheads +C dn: number of dense columns +C n: order of matrix +C Icntl: integer control parameters, see MA38ID +C Wr (1..n): see MA38FD +C Wc (1..n): see MA38FD +C ffxp: pointer to current contribution block +C ffsize: size of current contribution block +C mhead: pointer to first block in memory list +C mtail: pointer to last block in memory list +C doslot: true if adding slots +C if doslot: +C WiR (1..n) if WiR (row) >= 0 then add (or keep) an extra +C slot in the row's element list +C WiC (1..n) if WiR (col) >= 0 then add (or keep) an extra +C slot in the col's element list + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C II/XX: external fragmentation is removed at head +C xhead: XX (1..xhead) is in use, reduced in size +C xuse: memory usage in Value, reduced +C ihead: II (1..ihead) is in use, reduced in size +C iuse: memory usage in Index, reduced +C pfree: pointer to free block in memory list, set to 0 +C xfree: size of free block in XX, set to -1 +C mhead: pointer to first block in memory list +C mtail: pointer to last block in memory list +C ffxp current working array has been shifted +C wxp current work vector has been shifted + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38FD + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER WHAT, FSIZ, ROW, COL, P, IDP, XDP, I, E, EP, FDIMC, + $ LUDEGR, LUDEGC, J, PC, CELN, CLEN, RELN, RLEN, + $ CSIZ1, CSIZ2, RSIZ1, RSIZ2, FLUIP, CXP, FXP, RDEG, + $ CDEG, CSCAL, RSCAL, FSCAL + PARAMETER (CSCAL = 9, RSCAL = 2, FSCAL = 7) + LOGICAL SLOT + +C Compression: +C ------------ +C what: what this block of memory is (a row, column, etc.) +C idp: int. destination pointer, current block moved to II (idp...) +C xdp: real destination pointer, current block moved to XX (xdp...) +C slot: true if adding, or keeping, a size-2 hole in an element list +C +C Columns: +C -------- +C cscal: = 9, the number of scalars in column data structure +C celn: number of (e,f) tuples in element list of a column +C clen: number of unassembled original entries in a column +C cdeg: degree of a column (number of entries, including fill-in) +C cxp: a column is in XX (cxp...) prior to compression +C pc: column is in II (pc ...) prior to compression +C csiz1: size of a column in II, prior to compression +C csiz2: size of a column in II, after compression +C col: column index +C +C Rows: +C ----- +C rscal: = 2, the number of scalars in row data structure +C reln: number of (e,f) tuples in element list of a row +C rlen: number of unassembled original entries in a row +C rsiz1: size of a row in II, prior to compression +C rsiz2: size of a row in II, after compression +C rdeg: degree of a row (number of entries, including fill-in) +C row: row index +C +C Frontal matrices: +C ----------------- +C fscal: = 7, the number of scalars in element data structure +C fluip: element is in II (fluip...) prior to compression +C fxp: a frontal matrix is in XX (fxp...) prior to compression +C e: an element +C fdimc: column dimension (number of rows) of a frontal matrix +C ludegr: row degree (number of columns) of a contribution block +C ludegc: column degree (number of rows) of a contribution block +C fsiz: size of an artificial frontal matrix +C ep: an artificial frontal matrix is in II (ep ...) prior to comp +C +C Other: +C ------ +C p: pointer +C i: general loop index +C j: general loop index + +C======================================================================= +C EXECUTABLE STATMENTS: +C======================================================================= + + SLOTS = 0 + +C----------------------------------------------------------------------- +C prepare the non-pivotal rows/cols and unassembled elements +C----------------------------------------------------------------------- + +C place the size of each block of memory at the beginning, +C and mark the 2nd entry in each block with what it is + +C ---------------------------------------------------------------- +C mark the columns +C ---------------------------------------------------------------- + +CFPP$ NODEPCHK L + DO 10 COL = 1, N + PC = CP (COL) + IF (PC .NE. 0) THEN +C this is a non-pivotal, non-null column + CDEG = II (PC+1) + CP (COL) = CDEG + II (PC+1) = COL+N + ENDIF +10 CONTINUE + +C ---------------------------------------------------------------- +C mark the rows and frontal matrices +C ---------------------------------------------------------------- + +CFPP$ NODEPCHK L + DO 20 ROW = 1, N + P = RP (ROW) + RLEN = WC (ROW) + IF (P .EQ. 0) THEN +C a pivotal row + CONTINUE + ELSE IF (RLEN .GE. 0 .AND. RLEN .LE. N) THEN +C this is a non-pivotal, non-null row + RDEG = II (P+1) + RP (ROW) = RDEG + II (P+1) = ROW+2*N + ELSE IF (WR (ROW) .EQ. -(N+DN+2)) THEN +C a pivotal row, and an assembled element + CONTINUE + ELSE +C this is an unassembled frontal matrix +C the size is implicitly fscal + FDIMC = II (P+1) + RP (ROW) = FDIMC + II (P+1) = ROW + ENDIF +20 CONTINUE + +C ---------------------------------------------------------------- +C mark the artificial frontal matrices +C ---------------------------------------------------------------- + +CFPP$ NODEPCHK L + DO 30 E = N+1, N+DN + EP = RP (E) + IF (EP .NE. 0) THEN +C this is an unassembled artificial frontal matrix +C the size is II (ep+1) + cscal + FDIMC = II (EP+1) + RP (E) = FDIMC + II (EP+1) = E+2*N + ENDIF +30 CONTINUE + +C----------------------------------------------------------------------- +C scan the link list and compress the reals +C----------------------------------------------------------------------- + + XDP = 1 + P = MHEAD +C while (p .ne. 0) do +40 CONTINUE + IF (P .NE. 0) THEN + + WHAT = II (P+1) + +C ------------------------------------------------------------- + IF (WHAT .GT. 3*N) THEN +C ------------------------------------------------------------- + +C this is an unassembled artificial frontal matrix + E = WHAT - 2*N + FXP = II (P+2) + II (P+2) = XDP +CFPP$ NODEPCHK L + DO 50 J = 0, RP (E) - 1 + XX (XDP+J) = XX (FXP+J) +50 CONTINUE + XDP = XDP + RP (E) + +C ------------------------------------------------------------- + ELSE IF (WHAT .EQ. -1 .OR. II (P+6) .EQ. 0) THEN +C ------------------------------------------------------------- + +C this is a real hole - delete it from the link list + IF (II (P+4) .NE. 0) THEN + II (II (P+4)+3) = II (P+3) + ELSE + MHEAD = II (P+3) + ENDIF + IF (II (P+3) .NE. 0) THEN + II (II (P+3)+4) = II (P+4) + ELSE + MTAIL = II (P+4) + ENDIF + +C ------------------------------------------------------------- + ELSE IF (WHAT .LE. N) THEN +C ------------------------------------------------------------- + +C this is an unassembled frontal matrix + E = WHAT + FXP = II (P+2) + II (P+2) = XDP + FLUIP = II (P) + LUDEGR = II (FLUIP+2) + LUDEGC = II (FLUIP+3) + FDIMC = RP (E) + IF (FDIMC .EQ. LUDEGC) THEN +C contribution block is already compressed +CFPP$ NODEPCHK L + DO 60 I = 0, (LUDEGR * LUDEGC) - 1 + XX (XDP+I) = XX (FXP+I) +60 CONTINUE + ELSE +C contribution block is not compressed +C compress XX (fxp..) to XX (xdp..xdp+(ludegr*ludegc)-1) + DO 80 J = 0, LUDEGR - 1 +CFPP$ NODEPCHK L + DO 70 I = 0, LUDEGC - 1 + XX (XDP + J*LUDEGC + I) = XX (FXP + J*FDIMC + I) +70 CONTINUE +80 CONTINUE + RP (E) = LUDEGC + ENDIF + XDP = XDP + LUDEGR*LUDEGC + +C ------------------------------------------------------------- + ELSE IF (WHAT .LE. 2*N) THEN +C ------------------------------------------------------------- + +C this is a column + CXP = II (P+2) + II (P+2) = XDP + CLEN = II (P+6) +CFPP$ NODEPCHK L + DO 90 J = 0, CLEN - 1 + XX (XDP+J) = XX (CXP+J) +90 CONTINUE + XDP = XDP + CLEN + +C ------------------------------------------------------------- + ENDIF +C ------------------------------------------------------------- + +C ------------------------------------------------------------- +C get the next item in the link list +C ------------------------------------------------------------- + + P = II (P+3) + +C end while: + GOTO 40 + ENDIF + + PFREE = 0 + XFREE = -1 + +C ---------------------------------------------------------------- +C shift the current working array (if it exists) +C ---------------------------------------------------------------- + + IF (FFXP .NE. 0) THEN +CFPP$ NODEPCHK L + DO 100 I = 0, FFSIZE - 1 + XX (XDP+I) = XX (FFXP+I) +100 CONTINUE + FFXP = XDP + XDP = XDP + FFSIZE + ENDIF + +C ---------------------------------------------------------------- +C shift the current work vector (if it exists) +C ---------------------------------------------------------------- + + IF (WXP .NE. 0) THEN + WXP = XDP + XDP = XDP + FFDIMC + ENDIF + +C----------------------------------------------------------------------- +C scan from the top of integer memory (1) to bottom (ihead) and +C compress the integers +C----------------------------------------------------------------------- + + P = 1 + IDP = P +C while (p .lt. ihead) do: +110 CONTINUE + IF (P .LT. IHEAD) THEN + + WHAT = II (P+1) + +C ------------------------------------------------------------- + IF (WHAT .GT. 3*N) THEN +C ------------------------------------------------------------- + +C this is an unassembled artificial frontal matrix + E = WHAT - 2*N + FSIZ = RP (E) + CSCAL + II (P+1) = RP (E) + RP (E) = IDP +CFPP$ NODEPCHK L + DO 120 I = 0, FSIZ - 1 + II (IDP+I) = II (P+I) +120 CONTINUE +C shift pointers in the link list + IF (II (IDP+4) .NE. 0) THEN + II (II (IDP+4)+3) = IDP + ELSE + MHEAD = IDP + ENDIF + IF (II (IDP+3) .NE. 0) THEN + II (II (IDP+3)+4) = IDP + ELSE + MTAIL = IDP + ENDIF + P = P + FSIZ + IDP = IDP + FSIZ + +C ------------------------------------------------------------- + ELSE IF (WHAT .EQ. -1) THEN +C ------------------------------------------------------------- + +C this is a integer hole + P = P + II (P) + +C ------------------------------------------------------------- + ELSE IF (WHAT .GE. 1 .AND. WHAT .LE. N) THEN +C ------------------------------------------------------------- + +C this is an unassembled frontal matrix (fscal integers) + E = WHAT + FDIMC = RP (E) + II (P+1) = FDIMC + RP (E) = IDP +CFPP$ NODEPCHK L + DO 130 I = 0, FSCAL - 1 + II (IDP+I) = II (P+I) +130 CONTINUE +C shift pointers in the link list + IF (II (IDP+4) .NE. 0) THEN + II (II (IDP+4)+3) = IDP + ELSE + MHEAD = IDP + ENDIF + IF (II (IDP+3) .NE. 0) THEN + II (II (IDP+3)+4) = IDP + ELSE + MTAIL = IDP + ENDIF + P = P + FSCAL + IDP = IDP + FSCAL + +C ------------------------------------------------------------- + ELSE IF (WHAT .LE. 2*N) THEN +C ------------------------------------------------------------- + +C this is a non-pivotal column + CSIZ1 = II (P) + COL = WHAT - N + CELN = II (P+5) + CLEN = II (P+6) + CSIZ2 = 2*CELN + CLEN + CSCAL + SLOT = DOSLOT .AND. WIC (COL) .GE. 0 .AND. P .GE. IDP+2 + IF (SLOT) THEN +C keep (or make) one extra slot for element list growth + CSIZ2 = CSIZ2 + 2 + SLOTS = SLOTS + 2 + ENDIF + CDEG = CP (COL) + II (P+1) = CDEG + CP (COL) = IDP + II (P) = CSIZ2 +C copy the cscal scalars and the celn (e,f) tuples +CFPP$ NODEPCHK L + DO 140 I = 0, CSCAL + 2*CELN - 1 + II (IDP+I) = II (P+I) +140 CONTINUE + IF (CLEN .GT. 0) THEN +C shift pointers in the link list + IF (II (IDP+4) .NE. 0) THEN + II (II (IDP+4)+3) = IDP + ELSE + MHEAD = IDP + ENDIF + IF (II (IDP+3) .NE. 0) THEN + II (II (IDP+3)+4) = IDP + ELSE + MTAIL = IDP + ENDIF + ENDIF + P = P + CSIZ1 - CLEN + IDP = IDP + CSCAL + 2*CELN + IF (SLOT) THEN +C skip past the slot + IDP = IDP + 2 + ENDIF +C copy the clen original row indices +CFPP$ NODEPCHK L + DO 150 I = 0, CLEN - 1 + II (IDP+I) = II (P+I) +150 CONTINUE + P = P + CLEN + IDP = IDP + CLEN + +C ------------------------------------------------------------- + ELSE +C ------------------------------------------------------------- + +C this is a non-pivotal row + RSIZ1 = II (P) + ROW = WHAT - 2*N + RELN = WR (ROW) + RLEN = WC (ROW) + RSIZ2 = 2*RELN + RLEN + RSCAL + SLOT = DOSLOT .AND. WIR (ROW) .GE. 0 .AND. P .GE. IDP+2 + IF (SLOT) THEN +C keep (or make) one extra slot for element list growth + RSIZ2 = RSIZ2 + 2 + SLOTS = SLOTS + 2 + ENDIF + RDEG = RP (ROW) + II (P+1) = RDEG + RP (ROW) = IDP + II (P) = RSIZ2 +C copy the rscal scalars, and the reln (e,f) tuples +CFPP$ NODEPCHK L + DO 160 I = 0, RSCAL + 2*RELN - 1 + II (IDP+I) = II (P+I) +160 CONTINUE + P = P + RSIZ1 - RLEN + IDP = IDP + RSCAL + 2*RELN + IF (SLOT) THEN +C skip past the slot + IDP = IDP + 2 + ENDIF +C copy the rlen original column indices +CFPP$ NODEPCHK L + DO 170 I = 0, RLEN - 1 + II (IDP+I) = II (P+I) +170 CONTINUE + P = P + RLEN + IDP = IDP + RLEN + +C ------------------------------------------------------------- + ENDIF +C ------------------------------------------------------------- + +C ------------------------------------------------------------- +C move to the next block +C ------------------------------------------------------------- + +C end while: + GOTO 110 + ENDIF + +C----------------------------------------------------------------------- +C deallocate the unused space +C----------------------------------------------------------------------- + + IUSE = IUSE - (IHEAD - IDP) + IHEAD = IDP + XUSE = XUSE - (XHEAD - XDP) + XHEAD = XDP + RETURN + END + + SUBROUTINE MA38HD (XX, XSIZE, II, ISIZE, N, NZ, NZDIA, NZOFF, + * NBLKS, CP, CPERM, RPERM, PR, PC, + * W, ZPERM, BP, OFFP, + * PRESRV) + INTEGER N, NZ, ISIZE, II(ISIZE), NZDIA, NZOFF, NBLKS, CP(N+1), + * CPERM(N), RPERM(N), PR(N), PC(N), W(N), ZPERM(N), + * BP(N+1), OFFP(N+1), XSIZE + LOGICAL PRESRV + DOUBLE PRECISION XX (XSIZE) + +C=== MA38HD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Find permutations to block triangular form: +C 1) permute the matrix so that it has a zero-free diagonal. +C 2) find strongly-connected components of the corresponding +C graph. Each diagonal block corresponds to exactly one +C strongly-connected component. +C 3) convert the matrix to block triangular form, unless it is +C to be preserved in its original form. + +C======================================================================= +C INPUT: +C======================================================================= +C +C presrv: true if original matrix is to be preserved +C n: order of matrix +C nz: entries in matrix +C isize: size of II +C xsize: size of XX +C Cp (1..n+1): column pointers +C XX (1..nz): values +C II (1..nz): row indices +C Icntl: integer control arguments +C +C input matrix in column form is in: +C XX (1..nz), II (1..nz), n, nz, Cp (1..n+1), where +C II (Cp(col) ... Cp(col+1)-1): row indices +C XX (Cp(col) ... Cp(col+1)-1): values +C if presrv is false then xsize and isize must be >= 2*nz +C otherwise, xsize and isize must be >= nz + +C======================================================================= +C WORKSPACE: +C======================================================================= +C +C Pr (1..n), Pc (1..n), W (1..n), Zperm (1..n) + +C====================================================================== +C OUTPUT: +C======================================================================= +C +C nblks: number of blocks +C if (nblks > 1): +C +C Cperm (1..n), Rperm (1..n): permutation to block form: +C Rperm (newrow) = oldrow +C Cperm (newcol) = oldcol +C +C Bp (n-nblks+1...n+1) holds the start/end of blocks 1..nblks +C +C if (presrv is false) then +C +C input matrix is converted to block-upper-tri. form, +C using II/XX (nz+1..2*nz) as workspace. +C nzdia: nonzeros in diagonal blocks +C nzoff: nonzeros in off-diagonal blocks +C (nz = nzdia + nzoff) +C +C off-diagonal column-oriented form in XX/II (1..nzoff) +C col is located in +C XX/II (Offp (col) ... Offp (col+1)-1) +C +C diagonal blocks now in XX/II (nzoff+1 .. nzoff+nzdia) +C col is located in +C XX/II (Cp (col) ... Cp (col+1)-1) +C +C else, nblks=1: and no other output is generated. + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38DD +C subroutines called: MC21BD, MC13ED + EXTERNAL MC21BD, MC13ED + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER COL, NDIAG, I, PO, PB, BLK, P, ROW, K1, K + +C ndiag: number of entries on the diagonal +C po: pointer into off-diagonal part +C pb: pointer into diagonal blocks +C blk: block number for current diagonal block +C k1: column col is in diagonal block A (k1.., k1...) +C k: kth row/col in BTF form is Rperm(k)/Cperm(k) in input matrix +C p: pointer +C row: row index +C col: column index +C i: general loop index + + +C======================================================================= +C EXECUTABLE STATEMENTS: +C======================================================================= + + NZDIA = NZ + NZOFF = 0 + +C----------------------------------------------------------------------- +C compute the length of each column +C----------------------------------------------------------------------- + + DO 10 COL = 1, N + W (COL) = CP (COL+1) - CP (COL) +10 CONTINUE + +C----------------------------------------------------------------------- +C find a column permutation for a zero-free diagonal +C----------------------------------------------------------------------- + + CALL MC21BD(N, II, NZ, CP, W, ZPERM, NDIAG, OFFP, CPERM, PR, PC) +C MC21BD calling interface: +C input: n, II (1..nz), nz, Cp (n), W (n): +C n-by-n matrix, col is of length W (col), +C and its pattern is located in +C II (Cp (col) ... Cp (col)+W(col)-1) +C output: Zperm (n), the permutation, such that +C colold = Zperm (col), and ndiag (number of +C structural nonzeros on the diagonal. +C matrix is structurally singular if ndiag < n +C workspace: Offp, Cperm, Pr, Pc + +C----------------------------------------------------------------------- +C permute the columns of the temporary matrix to get zero-free diagonal +C----------------------------------------------------------------------- + + DO 20 COL = 1, N + OFFP (COL) = CP (ZPERM (COL)) + W (COL) = CP (ZPERM (COL)+1) - CP (ZPERM (COL)) +20 CONTINUE + +C----------------------------------------------------------------------- +C find a symmetric permutation into upper block triangular form +C (that is, find the strongly-connected components in the graph). +C----------------------------------------------------------------------- + + CALL MC13ED(N, II, NZ, OFFP, W, RPERM, BP, NBLKS, CPERM, PR, PC) +C MC13ED calling interface: +C input: n, II (1..nz), nz, Offp (n), W (n) +C n-by-n matrix, col of length W(col), +C in II (Offp(col) ... Offp(col)+W(col)-1), where +C this permuted matrix has a zero-free diagonal +C (unless the matrix is structurally singular). +C output: Rperm (n), Bp (n+1), nblks +C old = Rperm (new) is the symmetric permutation, +C there are nblks diagonal blocks, Bp (i) is +C the position in new order of the ith block. +C workspace: Cperm, Pr, Pc + +C----------------------------------------------------------------------- +C if more than one block, get permutations and block pointers, +C and convert to block-upper-triangular form (unless matrix preserved) +C----------------------------------------------------------------------- + + IF (NBLKS .NE. 1) THEN + +C ------------------------------------------------------------- +C find the composite column permutation vector (Cperm): +C ------------------------------------------------------------- + + DO 30 COL = 1, N + CPERM (COL) = ZPERM (RPERM (COL)) +30 CONTINUE + +C ------------------------------------------------------------- +C convert to block-upper-triangular form, if not preserved +C ------------------------------------------------------------- + + IF (.NOT. PRESRV) THEN + +C ---------------------------------------------------------- +C find the inverse permutation vectors, Pr and Pc +C ---------------------------------------------------------- + + DO 40 K = 1, N + PC (CPERM (K)) = K + PR (RPERM (K)) = K +40 CONTINUE + +C ---------------------------------------------------------- +C construct flag array to determine if entry in block or not +C ---------------------------------------------------------- + + BP (NBLKS+1) = N+1 + DO 60 BLK = 1, NBLKS + DO 50 I = BP (BLK), BP (BLK+1)-1 + W (I) = BP (BLK) +50 CONTINUE +60 CONTINUE + +C ---------------------------------------------------------- +C construct block-diagonal form in XX/II (nz+1..nz+nzdia) +C ---------------------------------------------------------- + +C These blocks are in a permuted order (according to Rperm +C and Cperm). The row indices in each block range from 1 +C to the size of the block. + + PB = NZ + 1 + DO 80 COL = 1, N + ZPERM (COL) = PB + K1 = W (COL) +CFPP$ NODEPCHK L + DO 70 P = CP (CPERM (COL)), CP (CPERM (COL)+1)-1 + ROW = PR (II (P)) + IF (W (ROW) .EQ. K1) THEN +C entry is in the diagonal block: + II (PB) = ROW - K1 + 1 + XX (PB) = XX (P) + PB = PB + 1 + ENDIF +70 CONTINUE +80 CONTINUE +C Zperm (n+1) == pb ( but Zperm (n+1) does not exist ) + NZDIA = PB - (NZ + 1) + NZOFF = NZ - NZDIA + +C diagonal blocks now in XX/II (nz+1..nz+nzdia) +C col is located in XX/II (Zperm (col) ... Zperm (col+1)-1) + +C ---------------------------------------------------------- +C compress original matrix to off-diagonal part, in place +C ---------------------------------------------------------- + +C The rows/cols of off-diagonal form correspond to rows/cols +C in the original, unpermuted matrix. They are permuted to +C the final pivot order and stored in a row-oriented form, +C after the factorization is complete (by MA38MD). + + PO = 1 + DO 100 COL = 1, N + OFFP (COL) = PO + K1 = W (PC (COL)) +CFPP$ NODEPCHK L + DO 90 P = CP (COL), CP (COL+1)-1 + ROW = PR (II (P)) + IF (W (ROW) .NE. K1) THEN +C offdiagonal entry + II (PO) = II (P) + XX (PO) = XX (P) + PO = PO + 1 + ENDIF +90 CONTINUE +100 CONTINUE + OFFP (N+1) = PO + +C off-diagonal form now in XX/II (1..nzoff) +C col is located in XX/II(Offp(col)..Offp(col+1)-1) + +C ---------------------------------------------------------- +C move block-diagonal part into place +C ---------------------------------------------------------- + + PB = NZ + 1 +CFPP$ NODEPCHK L + DO 110 I = 0, NZDIA - 1 + II (PO+I) = II (PB+I) + XX (PO+I) = XX (PB+I) +110 CONTINUE + DO 120 COL = 1, N + CP (COL) = ZPERM (COL) - NZDIA +120 CONTINUE +C Cp (n+1) == nz+1 ( this is unchanged ) + +C diagonal blocks now in XX/II (nzoff+1 .. nzoff+nzdia) +C col is located in XX/II (Cp (col) ... Cp (col+1)-1) + + ENDIF + +C ------------------------------------------------------------- +C shift Bp (1 .. nblks+1) down to Bp (1+n-nblks .. n+1), which +C then becomes the Blkp (1 .. nblks+1) array. +C ------------------------------------------------------------- + + BP (NBLKS+1) = N+1 +CFPP$ NODEPCHK L + DO 130 BLK = NBLKS + 1, 1, -1 + BP (BLK + (N-NBLKS)) = BP (BLK) +130 CONTINUE + ENDIF + + RETURN + END + + SUBROUTINE MA38JD (N, JOB, TRANSC, LUXSIZ, LUX, + * LUISIZ, LUI, B, X, R, Z, LY, Y, S, CNTL, INFO, + * RINFO, CPERM, RPERM, AN, ANZ, AP, AI, AX, ON, + * NZOFF, OFFP, OFFI, OFFX, NBLKS, LUBLKP, BLKP, IRSTEP) + INTEGER N, JOB, LUXSIZ, LUISIZ, LUI(LUISIZ), LY, IRSTEP, + * INFO(40), CPERM(N), RPERM(N), AN, + * ANZ, AP(AN+1), AI(ANZ), ON, NZOFF, OFFP(ON+1), + * OFFI(NZOFF), NBLKS, LUBLKP(NBLKS), BLKP(NBLKS+1) + LOGICAL TRANSC + DOUBLE PRECISION LUX(LUXSIZ), B(N), X(N), R(N), Z(N), Y(LY), + * S(LY), CNTL(10), RINFO(20), AX(ANZ), + * OFFX(NZOFF) + +C=== MA38JD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Solve a system, given LU factors, permutation arrays, original +C matrix (if preserved), and off-diagonal blocks (if BTF was used). + +C======================================================================= +C INPUT: +C======================================================================= +C +C n: order of matrix +C job: 0: solve Ax=b, 1: solve Lx=b, 2: solve Ux=b +C transc: if true, solve with transposed factors instead +C LUxsiz: size of LUx +C LUx (1..LUxsiz) real values in LU factors for each block +C LUisiz: size of LUi +C LUi (1..LUisiz) integers in LU factors for each block +C B (1..n): right-hand-side +C ly: size of Y and S, ly=n if Y and S are used +C Cntl: real control parameters, see MA38ID +C Icntl: integer control parameters, see MA38ID +C Cperm (1..n): Q, column permutation array +C Rperm (1..n): P, row permutation array +C presrv: if true, then original matrix was preserved +C nblks: number of diagonoal blocks (1 if no BTF) +C irstep: maximum number of steps of iterative refinement +C +C if presrv then +C an: order of preserved matrix, n +C anz: number of entries in preserved matrix +C Ap (1..an+1): column pointers of preserved matrix +C Ai (1..anz): row indices of preserved matrix +C Ax (1..anz): values of preserved matrix +C an, anz, Ap, Ai, Ax: not accessed +C +C if nblks > 1 then +C on: n +C nzoff: number of off-diagonoal entries +C Offp (1..n+1) row pointers for off-diagonal part +C Offi (1..nzoff): column indices for off-diagonal part +C Offx (1..nzoff): values of off-diagonal part +C LUBlkp (1..nblks): pointers to LU factors of each block +C Blkp (1..nblks+1): index range of each block +C else +C on, nzoff, Offp, Offi, Offx, LUBlkp, Blkp: not accessed + +C======================================================================= +C WORKSPACE: +C======================================================================= +C +C R (1..n), Z (1..n) +C Y (1..ly), S (1..ly): unaccessed if no iterative refinement + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C X (1..n): solution +C Info: integer informational output, see MA38ID +C Rinfo: real informational output, see MA38ID +C +C if irsteps > 0 and presrv is true then +C W (1..n): residual +C Rinfo (7): sparse error estimate, omega1 +C Rinfo (8): sparse error estimate, omega2 + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38CD +C subroutines called: MA38ND, MA38LD, MA38TD, MA38UD, MA38SD +C functions called: IDAMAX, ABS, MAX + INTRINSIC ABS, MAX + INTEGER IDAMAX + EXTERNAL MA38LD, MA38ND, MA38SD, MA38TD, MA38UD + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER NLU, I, BLK, K1, K2, KN, P, STEP, NPIV, J + DOUBLE PRECISION + $ ZERO, ONE, XNORM, TAU, NCTAU, OMEGA1, OMEGA2, D1, + $ D2, OMEGA, OMLAST, OM1LST, OM2LST, TWO, EPS, MAXEPS, + $ THOSND, A, AXX, R2, X2, Y2, Z2 + PARAMETER (ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0, + $ MAXEPS = TWO ** (-15), THOSND = 1000.0D0) + +C LU factors: +C ----------- +C blk: current diagonal block +C k1,k2: current diagonal block is A (k1..k2, k1..k2) +C kn: size of diagonal block (= k2-k1+1) +C nlu: number of elements in the LU factors of a single diag block +C npiv: number of pivots in the LU factors of a single diag block +C +C Iterative refinement and sparse backward error: +C ----------------------------------------------- +C step: number of steps of iterative refinement taken +C xnorm: ||x|| maxnorm of solution vector, x +C tau: threshold for selecting which estimate to use (1 or 2) +C nctau: 1000*n*eps +C eps: largest positive value such that fl (1.0 + eps) = 1.0 +C omega1: current sparse backward error estimate 1 +C omega2: current sparse backward error estimate 2 +C d1: divisor for omega1 +C d2: divisor for omega2 +C omega: omega1 + omega2 +C omlast: value of omega from previous step +C om1lst: value of omega1 from previous step +C om2lst: value of omega2 from previous step +C maxeps: maximum value that eps is allowed to be +C a: value of an entry in A, A_ij +C axx: A_ij * x_j +C +C Other: +C ------ +C i,j: loop indices +C p: pointer +C r2: R (i) +C x2: X (i) +C y2: Y (i) +C z2: Z (i) + +C======================================================================= +C EXECUTABLE STATEMENTS: +C======================================================================= + +C----------------------------------------------------------------------- +C initializations for sparse backward error +C----------------------------------------------------------------------- + + OMEGA = ZERO + OMEGA1 = ZERO + OMEGA2 = ZERO + EPS = CNTL (3) + IF (EPS .LE. ZERO .OR. EPS .GT. MAXEPS) THEN +C eps is too small or too big: set to a large default value + EPS = MAXEPS + ENDIF + NCTAU = THOSND * N * EPS + +C----------------------------------------------------------------------- +C get information on LU factorization if BTF was not used +C----------------------------------------------------------------------- + + IF (NBLKS .EQ. 1) THEN +C p is 1, and LUi (p) is 1 + NLU = LUI (2) + NPIV = LUI (3) + ENDIF + +C----------------------------------------------------------------------- + IF (JOB .EQ. 1) THEN +C----------------------------------------------------------------------- + +C ------------------------------------------------------------- + IF (.NOT. TRANSC) THEN +C ------------------------------------------------------------- + +C ---------------------------------------------------------- +C Solve P'Lx=b: x = L \ Pb +C ---------------------------------------------------------- + + DO 10 I = 1, N + X (I) = B (RPERM (I)) +10 CONTINUE + IF (NBLKS .EQ. 1) THEN + CALL MA38LD (NLU, N, LUI(6), LUI(6+NLU), LUX,X,Z) + ELSE + DO 20 BLK = 1, NBLKS + K1 = BLKP (BLK) + K2 = BLKP (BLK+1) - 1 + KN = K2-K1+1 + IF (KN .GT. 1) THEN + P = LUBLKP (BLK) + NLU = LUI (P+1) + NPIV = LUI (P+2) + CALL MA38LD (NLU, KN, LUI (P+5), + $ LUI (P+5+NLU), LUX (LUI (P)), X (K1), Z) + ENDIF +20 CONTINUE + ENDIF + +C ------------------------------------------------------------- + ELSE +C ------------------------------------------------------------- + +C ---------------------------------------------------------- +C Solve L'Px=b: x = P' (L' \ b) +C ---------------------------------------------------------- + + DO 30 I = 1, N + R (I) = B (I) +30 CONTINUE + IF (NBLKS .EQ. 1) THEN + CALL MA38TD (NLU, NPIV, N, LUI(6), LUI(6+NLU), LUX,R,Z) + ELSE + DO 40 BLK = 1, NBLKS + K1 = BLKP (BLK) + K2 = BLKP (BLK+1) - 1 + KN = K2-K1+1 + IF (KN .GT. 1) THEN + P = LUBLKP (BLK) + NLU = LUI (P+1) + NPIV = LUI (P+2) + CALL MA38TD (NLU, NPIV, KN, LUI (P+5), + $ LUI (P+5+NLU), LUX (LUI (P)), R (K1), Z) + ENDIF +40 CONTINUE + ENDIF + DO 50 I = 1, N + X (RPERM (I)) = R (I) +50 CONTINUE + +C ------------------------------------------------------------- + ENDIF +C ------------------------------------------------------------- + +C----------------------------------------------------------------------- + ELSE IF (JOB .EQ. 2) THEN +C----------------------------------------------------------------------- + +C ------------------------------------------------------------- + IF (TRANSC) THEN +C ------------------------------------------------------------- + +C ---------------------------------------------------------- +C Solve QU'x=b: x = U' \ Q'b +C ---------------------------------------------------------- + + DO 60 I = 1, N + X (I) = B (CPERM (I)) +60 CONTINUE + IF (NBLKS .EQ. 1) THEN + CALL MA38SD (NLU, N, LUI(6), LUI(6+NLU), LUX,X,Z) + ELSE + DO 100 BLK = 1, NBLKS + K1 = BLKP (BLK) + K2 = BLKP (BLK+1) - 1 + KN = K2-K1+1 + IF (KN .EQ. 1) THEN + X (K1) = X (K1) / LUX (LUBLKP (BLK)) + R (K1) = X (K1) + ELSE + P = LUBLKP (BLK) + NLU = LUI (P+1) + NPIV = LUI (P+2) + CALL MA38SD (NLU, KN, LUI (P+5), + $ LUI (P+5+NLU), LUX (LUI (P)), X (K1), Z) + DO 70 I = K1, K2 + R (I) = X (I) +70 CONTINUE + CALL MA38TD (NLU, NPIV, KN, LUI (P+5), + $ LUI (P+5+NLU), LUX (LUI (P)), R (K1), Z) + ENDIF + DO 90 I = K1, K2 + R2 = R (I) + DO 80 P = OFFP (I), OFFP (I+1)-1 + X (OFFI (P)) = X (OFFI (P)) - OFFX (P) * R2 +80 CONTINUE +90 CONTINUE +100 CONTINUE + ENDIF + +C ------------------------------------------------------------- + ELSE +C ------------------------------------------------------------- + +C ---------------------------------------------------------- +C Solve UQ'x=b: x = Q (U \ b) +C ---------------------------------------------------------- + + IF (NBLKS .EQ. 1) THEN + DO 110 I = 1, N + R (I) = B (I) +110 CONTINUE + CALL MA38UD (NLU, NPIV, N, LUI(6), LUI(6+NLU), LUX,R,Z) + ELSE + DO 150 BLK = NBLKS, 1, -1 + K1 = BLKP (BLK) + K2 = BLKP (BLK+1) - 1 + KN = K2-K1+1 + DO 130 I = K1, K2 + X2 = ZERO + DO 120 P = OFFP (I), OFFP (I+1)-1 + X2 = X2 + OFFX (P) * R (OFFI (P)) +120 CONTINUE + X (I) = X2 +130 CONTINUE + IF (KN .EQ. 1) THEN + R (K1) = (B (K1) - X (K1)) / LUX (LUBLKP (BLK)) + ELSE + P = LUBLKP (BLK) + NLU = LUI (P+1) + NPIV = LUI (P+2) + CALL MA38LD (NLU, KN, LUI (P+5), + $ LUI (P+5+NLU), LUX (LUI (P)), X (K1), Z) + DO 140 I = K1, K2 + R (I) = B (I) - X (I) +140 CONTINUE + CALL MA38UD (NLU, NPIV, KN, LUI (P+5), + $ LUI (P+5+NLU), LUX (LUI (P)), R (K1), Z) + ENDIF +150 CONTINUE + ENDIF + DO 160 I = 1, N + X (CPERM (I)) = R (I) +160 CONTINUE + +C ------------------------------------------------------------- + ENDIF +C ------------------------------------------------------------- + +C----------------------------------------------------------------------- + ELSE +C----------------------------------------------------------------------- + + DO 450 STEP = 0, IRSTEP + +C ---------------------------------------------------------- +C If transa was true in MA38AD or MA38BD, then C = A'. +C Otherwise C = A. In both cases, the factorization is +C PCQ = LU, and C is stored in column-form in Ai,Ax,Ap if +C it is preserved. +C ---------------------------------------------------------- + +C ---------------------------------------------------------- + IF (.NOT. TRANSC) THEN +C ---------------------------------------------------------- + +C ------------------------------------------------------- +C Solve Cx=b (step 0): +C x = Q (U \ L \ Pb) +C and then perform iterative refinement (step > 0): +C x = x + Q (U \ L \ P (b-Cx)) +C ------------------------------------------------------- + + IF (STEP .EQ. 0) THEN + DO 170 I = 1, N + R (I) = B (RPERM (I)) +170 CONTINUE + ELSE + DO 180 I = 1, N + Z (I) = B (I) +180 CONTINUE + DO 200 I = 1, N + X2 = X (I) + DO 190 P = AP (I), AP (I+1) - 1 + Z (AI (P)) = Z (AI (P)) - AX (P) * X2 +190 CONTINUE +200 CONTINUE + DO 210 I = 1, N + R (I) = Z (RPERM (I)) +210 CONTINUE + ENDIF + IF (NBLKS .EQ. 1) THEN + CALL MA38LD (NLU, N,LUI(6),LUI(6+NLU),LUX,R,Z) + CALL MA38UD (NLU, NPIV, N,LUI(6),LUI(6+NLU),LUX,R,Z) + ELSE + DO 240 BLK = NBLKS, 1, -1 + K1 = BLKP (BLK) + K2 = BLKP (BLK+1) - 1 + KN = K2-K1+1 + DO 230 I = K1, K2 + R2 = R (I) + DO 220 P = OFFP (I), OFFP (I+1)-1 + R2 = R2 - OFFX (P) * R (OFFI (P)) +220 CONTINUE + R (I) = R2 +230 CONTINUE + IF (KN .EQ. 1) THEN + R (K1) = R (K1) / LUX (LUBLKP (BLK)) + ELSE + P = LUBLKP (BLK) + NLU = LUI (P+1) + NPIV = LUI (P+2) + CALL MA38LD (NLU, KN, LUI (P+5), + $ LUI (P+5+NLU), LUX (LUI (P)), R (K1), Z) + CALL MA38UD (NLU, NPIV, KN, LUI (P+5), + $ LUI (P+5+NLU), LUX (LUI (P)), R (K1), Z) + ENDIF +240 CONTINUE + ENDIF + IF (STEP .EQ. 0) THEN + DO 250 I = 1, N + X (CPERM (I)) = R (I) +250 CONTINUE + ELSE + DO 260 I = 1, N + X (CPERM (I)) = X (CPERM (I)) + R (I) +260 CONTINUE + ENDIF + +C ---------------------------------------------------------- + ELSE +C ---------------------------------------------------------- + +C ------------------------------------------------------- +C Solve C'x=b (step 0): +C x = P' (L' \ U' \ Q'b) +C and then perform iterative refinement (step > 0): +C x = x + P' (L' \ U' \ Q' (b-C'x)) +C ------------------------------------------------------- + + IF (STEP .EQ. 0) THEN + DO 270 I = 1, N + R (I) = B (CPERM (I)) +270 CONTINUE + ELSE + DO 280 I = 1, N + Z (I) = B (I) +280 CONTINUE + DO 300 I = 1, N + Z2 = Z (I) + DO 290 P = AP (I), AP (I+1) - 1 + Z2 = Z2 - AX (P) * X (AI (P)) +290 CONTINUE + Z (I) = Z2 +300 CONTINUE + DO 310 I = 1, N + R (I) = Z (CPERM (I)) +310 CONTINUE + ENDIF + IF (NBLKS .EQ. 1) THEN + CALL MA38SD (NLU, N,LUI(6),LUI(6+NLU),LUX,R,Z) + CALL MA38TD (NLU, NPIV, N,LUI(6),LUI(6+NLU),LUX,R,Z) + ELSE + DO 340 BLK = 1, NBLKS + K1 = BLKP (BLK) + K2 = BLKP (BLK+1) - 1 + KN = K2-K1+1 + IF (KN .EQ. 1) THEN + R (K1) = R (K1) / LUX (LUBLKP (BLK)) + ELSE + P = LUBLKP (BLK) + NLU = LUI (P+1) + NPIV = LUI (P+2) + CALL MA38SD (NLU, KN, LUI (P+5), + $ LUI (P+5+NLU), LUX (LUI (P)), R (K1), Z) + CALL MA38TD (NLU, NPIV, KN, LUI (P+5), + $ LUI (P+5+NLU), LUX (LUI (P)), R (K1), Z) + ENDIF + DO 330 I = K1, K2 + R2 = R (I) + DO 320 P = OFFP (I), OFFP (I+1)-1 + R (OFFI (P)) = R (OFFI (P)) - OFFX (P) * R2 +320 CONTINUE +330 CONTINUE +340 CONTINUE + ENDIF + IF (STEP .EQ. 0) THEN + DO 350 I = 1, N + X (RPERM (I)) = R (I) +350 CONTINUE + ELSE + DO 360 I = 1, N + X (RPERM (I)) = X (RPERM (I)) + R (I) +360 CONTINUE + ENDIF + +C ---------------------------------------------------------- + ENDIF +C ---------------------------------------------------------- + +C ---------------------------------------------------------- +C sparse backward error estimate +C ---------------------------------------------------------- + + IF (IRSTEP .GT. 0) THEN + +C xnorm = ||x|| maxnorm + XNORM = ABS (X (IDAMAX (N, X, 1))) + +C r (i) = (b-Ax)_i, residual (or A') +C z (i) = (|A||x|)_i +C y (i) = ||A_i||, maxnorm of row i of A (or A') + DO 370 I = 1, N + R (I) = B (I) + Z (I) = ZERO + Y (I) = ZERO +370 CONTINUE + + IF (.NOT. TRANSC) THEN + +C ---------------------------------------------------- +C sparse backward error for Cx=b, C stored by column +C ---------------------------------------------------- + + DO 390 J = 1, N + X2 = X (J) +CFPP$ NODEPCHK L + DO 380 P = AP (J), AP (J+1) - 1 + I = AI (P) + A = AX (P) + AXX = A * X2 + R (I) = R (I) - (AXX) + Z (I) = Z (I) + ABS (AXX) + Y (I) = Y (I) + ABS (A) +380 CONTINUE +390 CONTINUE + + ELSE + +C ---------------------------------------------------- +C sparse backward error for C'x=b, C' stored by row +C ---------------------------------------------------- + + DO 410 I = 1, N + R2 = R (I) + Z2 = Z (I) + Y2 = Y (I) +CFPP$ NODEPCHK L + DO 400 P = AP (I), AP (I+1) - 1 + J = AI (P) + A = AX (P) + AXX = A * X (J) + R2 = R2 - (AXX) + Z2 = Z2 + ABS (AXX) + Y2 = Y2 + ABS (A) +400 CONTINUE + R (I) = R2 + Z (I) = Z2 + Y (I) = Y2 +410 CONTINUE + + ENDIF + +C ------------------------------------------------------- +C save the last iteration in case we need to reinstate it +C ------------------------------------------------------- + + OMLAST = OMEGA + OM1LST = OMEGA1 + OM2LST = OMEGA2 + +C ------------------------------------------------------- +C compute sparse backward errors: omega1 and omega2 +C ------------------------------------------------------- + + OMEGA1 = ZERO + OMEGA2 = ZERO + DO 420 I = 1, N + TAU = (Y (I) * XNORM + ABS (B (I))) * NCTAU + D1 = Z (I) + ABS (B (I)) + IF (D1 .GT. TAU) THEN + OMEGA1 = MAX (OMEGA1, ABS (R (I)) / D1) + ELSE IF (TAU .GT. ZERO) THEN + D2 = Z (I) + Y (I) * XNORM + OMEGA2 = MAX (OMEGA2, ABS (R (I)) / D2) + ENDIF +420 CONTINUE + OMEGA = OMEGA1 + OMEGA2 + RINFO (7) = OMEGA1 + RINFO (8) = OMEGA2 + +C ------------------------------------------------------- +C stop the iterations if the backward error is small +C ------------------------------------------------------- + + INFO (24) = STEP + IF (ONE + OMEGA .LE. ONE) THEN +C further iterative refinement will no longer improve +C the solution + RETURN + ENDIF + +C ------------------------------------------------------- +C stop if insufficient decrease in omega +C ------------------------------------------------------- + + IF (STEP .GT. 0 .AND. OMEGA .GT. OMLAST / TWO) THEN + IF (OMEGA .GT. OMLAST) THEN +C last iteration better than this one, reinstate it + DO 430 I = 1, N + X (I) = S (I) + RINFO (7) = OM1LST + RINFO (8) = OM2LST +430 CONTINUE + ENDIF + INFO (24) = STEP - 1 + RETURN + ENDIF + +C ------------------------------------------------------- +C save current solution in case we need to reinstate +C ------------------------------------------------------- + + DO 440 I = 1, N + S (I) = X (I) +440 CONTINUE + + ENDIF + +450 CONTINUE + +C----------------------------------------------------------------------- + ENDIF +C----------------------------------------------------------------------- + + RETURN + END + + SUBROUTINE MA38KD (N, NZ, TRANSA, XX, XSIZE, INFO, ICNTL, + * II, ISIZE, W, WP, WHO) + INTEGER ISIZE, II(ISIZE), N, NZ, W(N), WP(N+1), INFO(40), + * ICNTL(20), XSIZE,WHO + DOUBLE PRECISION XX (XSIZE) + LOGICAL TRANSA + +C=== MA38KD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Convert input matrix (II,XX,n,nz) into from triplet form to column- +C oriented form. Remove invalid entries and duplicate entries. + +C======================================================================= +C INPUT: +C======================================================================= +C +C n: size of the matrix +C nz: number of nonzeros in the input matrix +C transa: if true then transpose input matrix +C XX (1..nz): values of triplet form +C xsize: size of XX, must be >= 2*nz +C II (1..2*nz): row and col indices of triplet form +C isize: size of II, must be >= max (2*nz,n+1) + nz +C Icntl: integer control parameters +C who: who called MA38KD, 1: MA38AD, 2: MA38BD +C +C II must be at least of size (nz + max (2*nz, n+1)) +C XX must be at least of size (nz + max ( nz, n+1)) +C +C input triplet matrix: +C if (transa) is false: +C II (p) row index, for p = 1..nz +C II (nz+p) col index +C XX (p) value +C if (transa) is true: +C II (p) col index, for p = 1..nz +C II (nz+p) row index +C XX (p) value + +C======================================================================= +C WORKSPACE: +C======================================================================= +C +C W (1..n) + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C nz: number of nonzeros in the output matrix, +C after removing invalid entries, and summing up +C duplicate entries +C II (n+2..nz+n+1): row indices in column-form +C XX (1..nz): values in column-form. +C Info (1): error flag +C Info (3): invalid entries +C Info (2): duplicate entries +C Info (5): remaining valid entries +C Info (6): remaining valid entries +C Info (7): 0 +C Wp (1..n+1) column pointers for column form +C II (1..n+1) column pointers for column form + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutines: MA38AD, MA38BD +C subroutines called: MA38ND, MA38ZD +C functions called: MAX + INTRINSIC MAX + EXTERNAL MA38ND, MA38ZD + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER ROW, COL, PDEST, P, NZ1, PCOL, IP, XP, IO, PRL, NINVLD, + $ NDUPL, I + LOGICAL PR3 + +C row: row index +C col: column index +C pdest: location of an entry in the column-form, for dupl. removal +C p: pointer +C nz1: number of entries after removing invalid or duplic. entries +C pcol: column col starts here after duplicates removed +C ip: column-form copy of matrix placed in II (ip...ip+nz-1) +C xp: column-form copy of matrix placed in XX (xp...xp+nz-1) +C ninvld: number of invalid entries +C ndupl: number of duplicate entries +C i: a row index if transa is true, a column index otherwise +C io: I/O unit for warning messages (for invalid or dupl. entries) +C prl: printing level +C pr3: true if printing invalid and duplicate entries + +C======================================================================= +C EXECUTABLE STATEMENTS: +C======================================================================= + +C----------------------------------------------------------------------- +C get arguments and check memory sizes +C----------------------------------------------------------------------- + + IO = ICNTL (2) + PRL = ICNTL (3) + PR3 = PRL .GE. 3 .AND. IO .GE. 0 + +C----------------------------------------------------------------------- +C count nonzeros in columns and check for invalid entries +C----------------------------------------------------------------------- + + NINVLD = 0 + NDUPL = 0 + DO 10 COL = 1, N + W (COL) = 0 +10 CONTINUE + NZ1 = NZ + DO 20 P = NZ, 1, -1 + ROW = II (P) + COL = II (NZ+P) + IF (ROW.LT.1.OR.ROW.GT.N.OR.COL.LT.1.OR.COL.GT.N) THEN +C this entry is invalid - delete it + IF (PR3) THEN +C print the offending entry on the diagnostic I/O unit + CALL MA38ZD (WHO, 99, ROW, COL, XX(P), IO) + ENDIF + II (P) = II (NZ1) + II (NZ+P) = II (NZ+NZ1) + XX (P) = XX (NZ1) + NZ1 = NZ1 - 1 + ELSE + IF (TRANSA) THEN +C factorizing A transpose + W (ROW) = W (ROW) + 1 + ELSE +C factorizing A + W (COL) = W (COL) + 1 + ENDIF + ENDIF +20 CONTINUE + NINVLD = NZ - NZ1 + IF (NINVLD .NE. 0) THEN +C invalid entries found - set warning flag and continue + CALL MA38ND (WHO, ICNTL, INFO, 1, NINVLD) + ENDIF + +C----------------------------------------------------------------------- +C convert triplet form to column-form +C----------------------------------------------------------------------- + + WP (1) = 1 + DO 30 I = 1, N + WP (I+1) = WP (I) + W (I) +30 CONTINUE + DO 40 I = 1, N + W (I) = WP (I) +40 CONTINUE + +C ---------------------------------------------------------------- +C construct column-form in II (2*nz+1..3*nz) and XX (nz+1..2*nz) +C ---------------------------------------------------------------- + + IP = MAX (2*NZ, N+1) + XP = NZ + IF (TRANSA) THEN + DO 50 P = 1, NZ1 + ROW = II (P) + COL = II (NZ+P) + II (IP + W (ROW)) = COL + XX (XP + W (ROW)) = XX (P) + W (ROW) = W (ROW) + 1 +50 CONTINUE + ELSE + DO 60 P = 1, NZ1 + ROW = II (P) + COL = II (NZ+P) + II (IP + W (COL)) = ROW + XX (XP + W (COL)) = XX (P) + W (COL) = W (COL) + 1 +60 CONTINUE + ENDIF + +C ---------------------------------------------------------------- +C shift the matrix back to II (n+2..nz+n+1) and XX (n+2..nz+n+1) +C ---------------------------------------------------------------- + + NZ = NZ1 +CFPP$ NODEPCHK L + DO 70 P = 1, NZ + II (N+1+P) = II (IP+P) + XX (P) = XX (XP+P) +70 CONTINUE + +C----------------------------------------------------------------------- +C remove duplicate entries by adding them up +C----------------------------------------------------------------------- + + DO 80 ROW = 1, N + W (ROW) = 0 +80 CONTINUE + PDEST = 1 + DO 100 COL = 1, N + PCOL = PDEST + DO 90 P = WP (COL), WP (COL+1)-1 + ROW = II (N+1+P) + IF (W (ROW) .GE. PCOL) THEN +C this is a duplicate entry + XX (W (ROW)) = XX (W (ROW)) + XX (P) + IF (PR3) THEN +C print the duplicate entry on the diagnostic I/O +C unit. The row and column indices printed reflect +C the input matrix. + IF (TRANSA) THEN + CALL MA38ZD (WHO, 98, COL, ROW, XX (P), IO) + ELSE + CALL MA38ZD (WHO, 98, ROW, COL, XX (P), IO) + ENDIF + ENDIF + ELSE +C this is a new entry, store and record where it is + W (ROW) = PDEST + IF (PDEST .NE. P) THEN + II (N+1+PDEST) = ROW + XX (PDEST) = XX (P) + ENDIF + PDEST = PDEST + 1 + ENDIF +90 CONTINUE + WP (COL) = PCOL +100 CONTINUE + WP (N+1) = PDEST + NZ1 = PDEST - 1 + NDUPL = NZ - NZ1 + IF (NDUPL .NE. 0) THEN +C duplicate entries found - set warning flag and continue + CALL MA38ND (WHO, ICNTL, INFO, 2, NDUPL) + ENDIF + NZ = NZ1 + +C----------------------------------------------------------------------- +C save column pointers in II (1..n+1) +C----------------------------------------------------------------------- + + DO 110 COL = 1, N+1 + II (COL) = WP (COL) +110 CONTINUE + + INFO (2) = NDUPL + INFO (3) = NINVLD + INFO (5) = NZ + INFO (6) = NZ + INFO (7) = 0 + IF (NZ .EQ. 0) THEN +C set error flag if all entries are invalid + CALL MA38ND (WHO, ICNTL, INFO, -2, -1) + ENDIF + RETURN + END + + SUBROUTINE MA38LD (NLU, N, LUP, LUI, LUX, X, W) + INTEGER NLU, N, LUP(NLU), LUI(*) + DOUBLE PRECISION LUX(*), X(N), W(N) + +C=== MA38LD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C solves Lx = b, where L is the lower triangular factor of a matrix +C (if BTF not used) or a single diagonal block (if BTF is used). +C B is overwritten with the solution X. + +C======================================================================= +C INPUT: +C======================================================================= +C +C nlu: number of LU arrowheads in the LU factors +C npiv: number of pivots found (normally n) +C n: order of matrix +C LUp (1..nlu): pointer to LU arrowheads in LUi +C LUi ( ... ): integer values of LU arrowheads +C LUx ( ... ): real values of LU arroheads +C X (1..n): the right-hand-side + +C======================================================================= +C WORKSPACE: +C======================================================================= +C +C W (1..n) + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C X (1..n): the solution to Lx=b + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38JD +C subroutines called: DTRSV, DGEMV + EXTERNAL DTRSV, DGEMV + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER I, K, S, LUIP, LUXP, LUK, LUDEGC, LUCP, LXP, ROW + DOUBLE PRECISION + $ ONE + PARAMETER (ONE = 1.0D0) + +C s: an element, or LU arrowhead +C k: kth pivot +C i: ith row in L2 array in element s +C luip: integer part of s is in LUi (luip...) +C luxp: real part of s is in LUx (luxp...) +C luk: number of pivots in s +C ludegc: column degree of non-pivotal part of s +C lucp: pattern of column of s in LUi (lucp...lucp+ludegc-1) +C lxp: the ludegc-by-luk L2 block of s is in LUx (lxp...) +C row: row index + +C======================================================================= +C EXECUTABLE STATMENTS: +C======================================================================= + + K = 0 + DO 40 S = 1, NLU + +C ------------------------------------------------------------- +C get the s-th LU arrowhead (s = 1..nlu, in pivotal order) +C ------------------------------------------------------------- + + LUIP = LUP (S) + LUXP = LUI (LUIP) + LUK = LUI (LUIP+1) + LUDEGC = LUI (LUIP+3) + LUCP = (LUIP + 7) + LXP = LUXP + LUK + + IF (LUK .EQ. 1) THEN + +C ---------------------------------------------------------- +C only one pivot, stride-1 sparse saxpy +C ---------------------------------------------------------- + + K = K + 1 +C L (k,k) is one +CFPP$ NODEPCHK L + DO 10 I = 1, LUDEGC + ROW = LUI (LUCP+I-1) +C col: k, L (row,col): LUx (lxp+i-1) + X (ROW) = X (ROW) - LUX (LXP+I-1) * X (K) +10 CONTINUE + + ELSE + +C ---------------------------------------------------------- +C more than one pivot +C ---------------------------------------------------------- + + CALL DTRSV ('L', 'N', 'U', LUK, + $ LUX (LUXP), LUDEGC + LUK, X (K+1), 1) + DO 20 I = 1, LUDEGC + ROW = LUI (LUCP+I-1) + W (I) = X (ROW) +20 CONTINUE + CALL DGEMV ('N', LUDEGC, LUK, -ONE, + $ LUX (LXP), LUDEGC + LUK, X (K+1), 1, ONE, W, 1) + DO 30 I = 1, LUDEGC + ROW = LUI (LUCP+I-1) + X (ROW) = W (I) +30 CONTINUE + K = K + LUK + ENDIF +40 CONTINUE + RETURN + END + + SUBROUTINE MA38MD (W, N, RPERM, CPERM, NZOFF, + * OFFP, OFFI, OFFX, PR, + * ICNTL, MP, MI, MX, MN, MNZ, PRESRV, NBLKS, BLKP, + * ONZ, WHO, NBELOW) + INTEGER N, NZOFF, W(N+1), RPERM(N), CPERM(N), ONZ, + * OFFP(N+1), OFFI(ONZ), PR(N), ICNTL(20), MN, MNZ, + * MP(MN+1), MI(MNZ), NBLKS, BLKP(NBLKS+1), WHO, NBELOW + LOGICAL PRESRV + DOUBLE PRECISION OFFX(ONZ), MX(MNZ) + +C=== MA38MD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Permute the off-diagonal blocks according to final pivot permutation. +C This routine is called only if the block-triangular-form (BTF) is +C used. + +C======================================================================= +C INPUT: +C======================================================================= +C +C n: order of matrix +C Rperm (1..n): the final row permutations, including BTF +C If i is the k-th pivot row, then Rperm (k) = i +C Cperm (1..n): the final column permutations, including BTF +C If j is the k-th pivot col, then Cperm (k) = j +C Icntl: integer control parameters, see MA38ID +C Info: integer informational parameters +C who: who called (1: MA38AD, 2: MA38BD) +C +C if presrv is true then +C mn: order of preserved matrix +C mnz: number of entries in preserved matrix +C Mp (1..mn+1): column pointers of preserved matrix +C Mi (1..mnz): row indices of preserved matrix +C Mx (1..mnz): values of preserved matrix +C Blkp (1..nblks+1): the index range of the blocks +C nblks: the number of diagonal blocks +C else +C mn: 0 +C mnz: nzoff +C Mp: unaccessed +C Offp (1..n+1): column pointers for off-diagonal entries +C in original order +C Mi (1..mnz): the row indices of off-diagonal entries, +C in original order +C Mx (1..mnz): the values of off-diagonal entries, +C in original order +C nblks: 0 +C Blkp (1..nblks+1): unaccessed +C nzoff: number of entries in off-diagonal blocks + +C======================================================================= +C WORKSPACE: +C======================================================================= +C +C W (1..n) + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C Offp (1..n+1): row pointers for off-diagonal part +C Offi (1..nzoff): column indices in off-diagonal part +C Offx (1..nzoff): values in off-diagonal part +C nzoff: number of entries in off-diagonal blocks +C Pr (1..n): inverse row permutation +C nbelow: entries that are below the diagonal +C blocks (can only occur if who = 2) + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38DD, MA38QD, MA38PD +C subroutines called: MA38ZD + EXTERNAL MA38ZD + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER ROW, COL, P, BLK, K, K1, K2, IO, PRL + LOGICAL PR3 + +C row: row index +C col: column index +C p: pointer +C blk: current diagonal block +C k: kth pivot +C k1,k2: current diaogonal block is A (k1..k2, k1..k2) +C io: I/O unit for diagnostic messages +C prl: printing level +C pr3: true if printing entries below diagonal blocks (MA38BD) + +C======================================================================= +C EXECUTABLE STATMENTS: +C======================================================================= + + IO = ICNTL (2) + PRL = ICNTL (3) + PR3 = PRL .GE. 3 .AND. IO .GE. 0 + +C----------------------------------------------------------------------- +C compute inverse row permutation +C----------------------------------------------------------------------- + +C if original row i is the kth pivot row, then +C Rperm (k) = i +C Pr (i) = k +C if original col j is the kth pivot col, then +C Cperm (k) = j +CFPP$ NODEPCHK L + DO 10 K = 1, N + PR (RPERM (K)) = K +10 CONTINUE + +C----------------------------------------------------------------------- +C construct row-oriented pointers for permuted row-form +C----------------------------------------------------------------------- + + W (1) = 1 + DO 20 ROW = 2, N + W (ROW) = 0 +20 CONTINUE + NBELOW = 0 + IF (PRESRV) THEN + DO 50 BLK = 1, NBLKS + K1 = BLKP (BLK) + K2 = BLKP (BLK+1) - 1 + DO 40 COL = K1, K2 +CFPP$ NODEPCHK L + DO 30 P = MP (CPERM (COL)), MP (CPERM (COL)+1)-1 + ROW = PR (MI (P)) + IF (ROW .LT. K1) THEN +C offdiagonal entry + W (ROW) = W (ROW) + 1 + ELSE IF (ROW .GT. K2 .AND. WHO .EQ. 2) THEN +C This entry is below the diagonal block - invalid. +C This can only occur if who = 2 (MA38BD). + IF (PR3) THEN +C print the original row and column indices: + CALL MA38ZD (2, 96, MI (P), COL, MX (P), IO) + ENDIF + NBELOW = NBELOW + 1 + ENDIF +30 CONTINUE +40 CONTINUE +50 CONTINUE + ELSE + DO 70 COL = 1, N +CFPP$ NODEPCHK L + DO 60 P = OFFP (COL), OFFP (COL+1) - 1 + ROW = PR (MI (P)) + W (ROW) = W (ROW) + 1 +60 CONTINUE +70 CONTINUE + ENDIF + DO 80 ROW = 2, N + W (ROW) = W (ROW) + W (ROW-1) +80 CONTINUE + W (N+1) = W (N) +C W (row) now points just past end of row in Offi/x + +C----------------------------------------------------------------------- +C construct the row-oriented form of the off-diagonal values, +C in the final pivot order. The column indices in each row +C are placed in ascending order (the access of Offi/Offx later on +C does not require this, but it makes access more efficient). +C----------------------------------------------------------------------- + + IF (PRESRV) THEN + DO 110 BLK = NBLKS, 1, -1 + K1 = BLKP (BLK) + K2 = BLKP (BLK+1) - 1 + DO 100 COL = K2, K1, - 1 +CFPP$ NODEPCHK L + DO 90 P = MP (CPERM (COL)), MP (CPERM (COL)+1)-1 + ROW = PR (MI (P)) + IF (ROW .LT. K1) THEN +C offdiagonal entry + W (ROW) = W (ROW) - 1 + OFFI (W (ROW)) = COL + OFFX (W (ROW)) = MX (P) + ENDIF +90 CONTINUE +100 CONTINUE +110 CONTINUE + ELSE + DO 130 COL = N, 1, -1 +CFPP$ NODEPCHK L + DO 120 P = OFFP (CPERM (COL)), OFFP (CPERM (COL) + 1) - 1 + ROW = PR (MI (P)) + W (ROW) = W (ROW) - 1 + OFFI (W (ROW)) = COL + OFFX (W (ROW)) = MX (P) +120 CONTINUE +130 CONTINUE + ENDIF + +C----------------------------------------------------------------------- +C save the new row pointers +C----------------------------------------------------------------------- + + DO 140 ROW = 1, N+1 + OFFP (ROW) = W (ROW) +140 CONTINUE + + NZOFF = OFFP (N+1) - 1 + + RETURN + END + + SUBROUTINE MA38ND (WHO, ICNTL, INFO, ERROR, S) + INTEGER WHO, ICNTL(20), INFO(40), ERROR, S + +C=== MA38ND ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Print error and warning messages, and set error flags. + +C======================================================================= +C INPUT: +C======================================================================= +C +C who which user-callable routine called: +C 1: MA38AD, 2: MA38BD, 3: MA38CD +C Icntl (1): I/O unit for error and warning messages +C Icntl (3): printing level +C Info (1): the error/warning status +C error: the applicable error (<0) or warning (>0). +C See MA38ZD for a description. +C s: the relevant offending value + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C Info (1): the error/warning status + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutines: MA38KD, MA38AD, MA38DD, MA38ED, MA38FD, +C MA38BD, MA38PD, MA38RD, MA38CD, MA38JD +C subroutines called: MA38ZD +C functions called: MOD + INTRINSIC MOD + EXTERNAL MA38ZD + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + LOGICAL BOTH + DOUBLE PRECISION + $ ZERO + PARAMETER (ZERO = 0.0D0) + INTEGER IOERR, PRL + +C ioerr: I/O unit for error and warning messages +C prl: printing level +C both: if true, then combine errors -3 and -4 into error -5 + +C======================================================================= +C EXECUTABLE STATEMENTS: +C======================================================================= + + IOERR = ICNTL (1) + PRL = ICNTL (3) + IF (ERROR .LT. 0) THEN +C this is an error message + BOTH = (INFO (1) .EQ. -3 .AND. ERROR .EQ. -4) .OR. + $ (INFO (1) .EQ. -4 .AND. ERROR .EQ. -3) + IF (BOTH) THEN +C combine error -3 (out of integer memory) and error -4 +C (out of real memory) + INFO (1) = -5 + ELSE + INFO (1) = ERROR + ENDIF + IF (PRL .GE. 1) THEN + CALL MA38ZD (WHO, ERROR, S, 0, ZERO, IOERR) + ENDIF + ELSE IF (ERROR .GT. 0) THEN +C this is a warning message + IF (INFO (1) .GE. 0) THEN +C do not override a prior error setting, sum up warnings + IF (MOD (INFO (1) / ERROR, 2) .EQ. 0) THEN + INFO (1) = INFO (1) + ERROR + ENDIF + ENDIF + IF (PRL .GE. 2) THEN + CALL MA38ZD (WHO, ERROR, S, 0, ZERO, IOERR) + ENDIF + ENDIF + RETURN + END + + SUBROUTINE MA38OD (XX, XSIZE, XHEAD, XUSE, + * LUI, FRDIMC, FRXP, FRNEXT, FRPREV, NLU, LUP, + * FFXP, FFSIZE, PFREE, XFREE) + INTEGER LUI(*), NLU, FRDIMC(NLU+2), FRXP(NLU+2), + * FRNEXT(NLU+2), FRPREV(NLU+2), LUP(NLU), + * XSIZE, XUSE, XHEAD, FFXP, FFSIZE, + * PFREE, XFREE + DOUBLE PRECISION XX(XSIZE) + +C=== MA38OD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Garbage collection for MA38RD. + +C======================================================================= +C INPUT: +C======================================================================= +C +C XX: real workspace, containing matrix being +C factorized and partially-computed LU factors +C xsize: size of XX +C xhead: XX (1..xhead) is in use (matrix, frontal mtc's) +C xtail: XX (xtail..xsize) is in use (LU factors) +C xuse: memory usage in Value +C Icntl: integer control parameters, see MA38ID +C ffxp: pointer to current contribution block +C ffsize: size of current contribution block +C nlu: number of LU arrowheads +C +C FRdimc (1..nlu+2) leading dimension of frontal matrices +C FRxp (1..nlu+2) pointer to frontal matrices in XX +C FRnext (1..nlu+2) pointer to next block in XX +C FRprev (1..nlu+2) pointer to previous block in XX +C LUp (1..nlu) pointer to LU arrowhead patters in LUi +C LUi (*) pattern of LU factors + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C XX: external fragmentation is removed at head +C xhead: XX (1..xhead) is in use, reduced in size +C xuse: memory usage in Value, reduced +C pfree: pointer to free block in memory list, set to 0 +C xfree: size of free block in XX, set to -1 +C FRdimc arrays for frontal matrices are compressed +C FRxp frontal matrices have been shifted +C ffxp current working array has been shifted + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38RD +C functions called: ABS + INTRINSIC ABS + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER XDP, I, E, FDIMC, LUDEGR, LUDEGC, J, FLUIP, FXP, + $ MHEAD, MTAIL + +C xdp: real destination pointer, current block moved to XX (xdp...) +C e: an element +C fdimc: column dimension (number of rows) of a frontal matrix +C ludegr: row degree (number of columns) of a contribution block +C ludegc: column degree (number of rows) of a contribution block +C fluip: element is in LUi (fluip...) +C fxp: element is in XX (fxp...) prior to compression +C mhead: nlu+1, head pointer for contribution block link list +C mtail: nlu+2, tail pointer for contribution block link list +C i: general loop index +C j: general loop index + +C======================================================================= +C EXECUTABLE STATMENTS: +C======================================================================= + +C----------------------------------------------------------------------- +C scan the link list and compress the reals +C----------------------------------------------------------------------- + + MHEAD = NLU+1 + MTAIL = NLU+2 + XDP = FRXP (MHEAD) + E = FRNEXT (MHEAD) + +C while (e .ne. mtail) do +10 CONTINUE + IF (E .NE. MTAIL) THEN + + FDIMC = FRDIMC (E) + +C ------------------------------------------------------------- + IF (FDIMC .EQ. 0) THEN +C ------------------------------------------------------------- + +C this is a real hole - delete it from the link list + + FRNEXT (FRPREV (E)) = FRNEXT (E) + FRPREV (FRNEXT (E)) = FRPREV (E) + +C ------------------------------------------------------------- + ELSE +C ------------------------------------------------------------- + +C this is an unassembled frontal matrix + FXP = FRXP (E) + FRXP (E) = XDP + FLUIP = LUP (E) + LUDEGR = ABS (LUI (FLUIP+2)) + LUDEGC = ABS (LUI (FLUIP+3)) + IF (FDIMC .EQ. LUDEGC) THEN +C contribution block is already compressed +CFPP$ NODEPCHK L + DO 20 I = 0, (LUDEGR * LUDEGC) - 1 + XX (XDP+I) = XX (FXP+I) +20 CONTINUE + ELSE +C contribution block is not compressed +C compress XX (fxp..) to XX (xdp..xdp+(ludegr*ludegc)-1) + DO 40 J = 0, LUDEGR - 1 +CFPP$ NODEPCHK L + DO 30 I = 0, LUDEGC - 1 + XX (XDP + J*LUDEGC + I) = XX (FXP + J*FDIMC + I) +30 CONTINUE +40 CONTINUE + FRDIMC (E) = LUDEGC + ENDIF + XDP = XDP + LUDEGR*LUDEGC + + ENDIF + +C ------------------------------------------------------------- +C get the next item in the link list +C ------------------------------------------------------------- + + E = FRNEXT (E) + +C end while: + GOTO 10 + ENDIF + + FRXP (MTAIL) = XDP + PFREE = 0 + XFREE = -1 + +C ---------------------------------------------------------------- +C shift the current working array (if it exists) +C ---------------------------------------------------------------- + + IF (FFXP .NE. 0) THEN +CFPP$ NODEPCHK L + DO 50 I = 0, FFSIZE - 1 + XX (XDP+I) = XX (FFXP+I) +50 CONTINUE + FFXP = XDP + XDP = XDP + FFSIZE + ENDIF + +C----------------------------------------------------------------------- +C deallocate the unused space +C----------------------------------------------------------------------- + + XUSE = XUSE - (XHEAD - XDP) + XHEAD = XDP + RETURN + END + + SUBROUTINE MA38PD (N, NZ, CP, XX, XSIZE, II, ISIZE, XTAIL, + * ITAIL, IUSE, XUSE, NZOFF, NBLKS, ICNTL, INFO, + * RINFO, PRESRV, AP, AI, AX, AN, ANZ, LUI, LUISIZ, + * LUBLKP, BLKP, OFFP, ON, CPERM, RPERM, NE) + INTEGER N, NZ, ISIZE, II(ISIZE), ICNTL(20), INFO(40), + * CP(N+1), XSIZE, XTAIL, ITAIL, IUSE, XUSE, AN, ANZ, + * AP(AN+1), AI(ANZ), LUISIZ, LUI(LUISIZ), NBLKS, + * LUBLKP(NBLKS), BLKP(NBLKS+1), ON, OFFP(ON+1), + * CPERM(N), RPERM(N), NZOFF, NE + LOGICAL PRESRV + DOUBLE PRECISION XX(XSIZE), RINFO(20), AX(ANZ) + +C=== MA38PD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Refactorize an unsymmetric sparse matrix in column-form, optionally +C permuting the matrix to upper block triangular form and factorizing +C each diagonal block. + +C======================================================================= +C INPUT: +C======================================================================= +C +C n: order of matrix +C nz: entries in matrix +C Cp (1..n+1): column pointers of input matrix +C presrv: if true then preserve original matrix +C xsize: size of XX +C isize: size of II +C iuse: memory usage in Index on input +C xuse: memory usage in Value on input +C Icntl: integer control parameters, see MA38ID +C Cntl: real control parameters, see MA38ID +C +C if presrv is true: +C an: = n, order of preserved matrix +C anz: = anz, order of preserved matrix +C Ap (1..an+1): column pointers of preserved matrix +C Ai (1..nz): row indices of preserved matrix +C Ax (1..nz): values of preserved matrix +C II: unused on input +C XX: unused on input +C else +C an: 0 +C anz: 1 +C Ap: unused +C Ai: unused +C Ax: unused +C II (1..nz): row indices of input matrix +C XX (1..nz): values of input matrix +C +C Information from prior LU factorization: +C +C LUisiz: size of LUi +C LUi (1..LUisiz): patterns of LU factors, excluding +C prior preserved matrix (if it existed) +C and prior off-diagonal part (if it +C existed) +C Cperm (1..n): column permutations +C Rperm (1..n): row permutations +C nblks: number of diagonal blocks for BTF +C if nblks > 1: +C LUblkp (1..nblks): pointers to each diagonal LU factors +C Blkp (1..nblks+1): index range of diagonal blocks + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C XX (xtail ... xsize), xtail: +C +C LU factors are located in XX (xtail ... xsize), +C including values in off-diagonal part if matrix +C was permuted to block triangular form. +C +C II (itail ... isize), itail: +C +C the off-diagonal nonzeros, if nblks > 1 +C +C Offp (1..n+1): row pointers for off-diagonal part, if nblks > 1 +C Info: integer informational output, see MA38AD +C Rinfo: real informational output, see MA38AD + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38BD +C subroutines called: MA38ND, MA38RD, MA38QD, MA38MD +C functions called: MAX + INTRINSIC MAX + EXTERNAL MA38MD, MA38ND, MA38QD, MA38RD + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER I, NZDIA, P, IHEAD, NSGLTN, NSYM, WP, ARIP, ARXP, NPIV, + $ WRKSIZ, NLU, PRP, MC, MR, DUMMY1, DUMMY2, NZ2, K, BLK, + $ K1, K2, KN, NZBLK, COL, ROW, PRL, IO, LUIP, MNZ, ARNZ, + $ XHEAD, OFFIP, OFFXP, NOUTSD, NBELOW, NZORIG, XRMAX + DOUBLE PRECISION + $ ZERO, ONE, A + PARAMETER (ZERO = 0.0D0, ONE = 1.0D0) + +C Printing control: +C ----------------- +C io: I/O unit for diagnostic messages +C prl: printing level +C +C Allocated array pointers: +C ------------------------- +C wp: W (1..n+1), or W (1..kn+1), work array located in II (wp...) +C prp: Pr (1..n) work array located in II (prp..prp+n-1) +C arip: Ari (1..nz) array located in II (arip..arip+nz-1) +C arxp: Arx (1..nz) array located in XX (arxp..arxp+nz-1) +C offip: Offi (1..nzoff) array located in II (offip..offip+nzoff-1) +C offxp: Offx (1..nzoff) array located in XX (offxp..offip+nzoff-1) +C +C Arrowhead-form matrix: +C ---------------------- +C nz2: number of entries in arrowhead matrix +C nzblk: number of entries in arrowhead matrix of a single block +C arnz: arrowhead form of blocks located in II/XX (1..arnz) +C +C BTF information: +C ---------------- +C k1: starting index of diagonal block being factorized +C k2: ending index of diagonal block being factorized +C kn: the order of the diagonal block being factorized +C blk: block number of diagonal block being factorized +C nsgltn: number of 1-by-1 diagonal blocks ("singletons") +C a: numerical value of a singleton +C mnz: nzoff +C noutsd: entries in diagonal blocks, but not in LU (invalid) +C nbelow: entries below diagonal blocks (invalid) +C nzoff: entries above diagonal blocks (valid) +C nzdia: entries in diagonal blocks (valid) +C nzorig: total number of original entries +C +C Memory usage: +C ------------- +C xhead: XX (1..xhead-1) is in use, XX (xhead..xtail-1) is free +C ihead: II (1..ihead-1) is in use, II (ihead..itail-1) is free +C wrksiz: total size of work arrays need in II for call to MA38RD +C xrmax: memory needed in Value for next call to MA38BD +C +C Symbolic information and pattern of prior LU factors: +C ----------------------------------------------------- +C nlu: number of elements in a diagonal block +C luip: integer part of LU factors located in LUi (luip...) +C mr,mc: largest frontal matrix for this diagonal block is mc-by-mr +C +C Other: +C ------ +C k: loop index (kth pivot) +C i: loop index +C row: row index +C col: column index +C p: pointer +C nsym: number of symmetric pivots chosen +C dummy1: argument returned by MA38QD, but not needed +C dummy2: argument returned by MA38QD, but not needed + +C======================================================================= +C EXECUTABLE STATEMENTS: +C======================================================================= + + IO = ICNTL (2) + PRL = ICNTL (3) + NZORIG = NZ + + IF (PRESRV) THEN +C original matrix is not in Cp/II/XX, but in Ap/Ai/Ax: + IHEAD = 1 + XHEAD = 1 + ELSE + IHEAD = NZ + 1 + XHEAD = NZ + 1 + ENDIF + + NZOFF = 0 + NZDIA = NZ + NSGLTN = 0 + NPIV = 0 + NOUTSD = 0 + NBELOW = 0 + ITAIL = ISIZE + 1 + XTAIL = XSIZE + 1 + +C----------------------------------------------------------------------- +C current memory usage: +C----------------------------------------------------------------------- + +C if .not. presrv then +C input matrix is now in II (1..nz) and XX (1..nz) +C col pattern: II (Cp (col) ... Cp (col+1)) +C col values: XX (Cp (col) ... Cp (col+1)) +C total: nz+n+1 integers, nz reals +C else +C input matrix is now in Ai (1..nz) and Ax (1..nz) +C col pattern: Ai (Ap (col) ... Ap (col+1)) +C col values: Ax (Ap (col) ... Ap (col+1)) +C Cp is a size n+1 integer workspace +C total: nz+2*(n+1) integers, nz reals +C +C if (nblks > 1) then +C LUblkp (1..nblks) +C Blkp (1..nblks+1) +C Offp (1..n+1) +C total: (2*nblks+n+2) integers +C +C Cperm (1..n) and Rperm (1..n) +C total: 2*n integers +C +C Grand total current memory usage (including II,XX,Cp,Ai,Ap,Ax +C and LUi): +C +C presrv nblks>1 integers, iuse = +C F F LUisiz + nz+ (n+1)+(2*n+7) +C F T LUisiz + nz+ (n+1)+(2*n+7)+(2*nblks+n+2) +C T F LUisiz + nz+2*(n+1)+(2*n+7) +C T T LUisiz + nz+2*(n+1)+(2*n+7)+(2*nblks+n+2) +C +C real usage is xuse = nz + +C----------------------------------------------------------------------- +C get memory usage estimate for next call to MA38BD +C----------------------------------------------------------------------- + + XRMAX = 2*NE + +C----------------------------------------------------------------------- +C convert matrix into arrowhead format (unless BTF and preserved) +C----------------------------------------------------------------------- + + IF (NBLKS .GT. 1 .AND. PRESRV) THEN + +C ------------------------------------------------------------- +C BTF is to be used, and original matrix is to be preserved. +C It is converted and factorized on a block-by-block basis, +C using the inverse row permutation (computed and stored in +C Offp (1..n) +C ------------------------------------------------------------- + + DO 10 K = 1, N + OFFP (RPERM (K)) = K +10 CONTINUE + + ELSE + +C ------------------------------------------------------------- +C convert the entire input matrix to arrowhead form +C ------------------------------------------------------------- + +C ------------------------------------------------------------- +C allocate workspace: W (n+1), Pr (n), Ari (nz), Arx (nz) +C ------------------------------------------------------------- + + ITAIL = ITAIL - (2*N+1) + IUSE = IUSE + 2*N+1 + PRP = ITAIL + WP = PRP + N + IUSE = IUSE + NZ + XUSE = XUSE + NZ + ARXP = XHEAD + ARIP = IHEAD + IHEAD = IHEAD + NZ + XHEAD = XHEAD + NZ + INFO (18) = MAX (INFO (18), IUSE) + INFO (20) = MAX (INFO (20), XUSE) + INFO (21) = MAX (INFO (21), XUSE) + IF (IHEAD .GT. ITAIL .OR. XHEAD .GT. XTAIL) THEN +C error return, if not enough integer and/or real memory: + GO TO 9000 + ENDIF + +C ------------------------------------------------------------- +C convert +C ------------------------------------------------------------- + + IF (NBLKS .EQ. 1) THEN + IF (PRESRV) THEN + CALL MA38QD (PRESRV, N, NZ, CPERM, RPERM, II (PRP), + $ II (WP), NBLKS, XX (ARXP), II (ARIP), NZOFF, NZDIA, + $ ICNTL, AP, BLKP, AI, AX, OFFP, ON, NZ, + $ 0, N, NZ2, I) + ELSE + CALL MA38QD (PRESRV, N, NZ, CPERM, RPERM, II (PRP), + $ II (WP), NBLKS, XX (ARXP), II (ARIP), NZOFF, NZDIA, + $ ICNTL, CP, BLKP, II, XX, OFFP, ON, NZ, + $ 0, N, NZ2, I) + ENDIF + ELSE +C note that presrv is false in this case + CALL MA38QD (PRESRV, N, NZ, CPERM, RPERM, II (PRP), + $ II (WP), NBLKS, XX (ARXP), II (ARIP), NZOFF, NZDIA, + $ ICNTL, CP, BLKP, II, XX, OFFP, ON, NZ, + $ 0, N, NZ2, NBELOW) + ENDIF + +C ------------------------------------------------------------- +C copy the arrowhead pointers from W (1..n+1) to Cp (1..n+1) +C ------------------------------------------------------------- + + DO 20 I = 1, N+1 + CP (I) = II (WP+I-1) +20 CONTINUE + +C ------------------------------------------------------------- +C deallocate W and Pr. If not presrv deallocate Ari and Arx +C ------------------------------------------------------------- + + IUSE = IUSE - (2*N+1) + IF (.NOT. PRESRV) THEN +C Ari and Arx have been deallocated. + XUSE = XUSE - NZ + IUSE = IUSE - NZ + ENDIF + ITAIL = ISIZE + 1 + XTAIL = XSIZE + 1 + NZ = NZ2 + IHEAD = NZ + 1 + XHEAD = NZ + 1 + + ENDIF + + INFO (5) = NZ + INFO (6) = NZDIA + INFO (7) = NZOFF + INFO (4) = NBELOW + +C----------------------------------------------------------------------- +C refactorization +C----------------------------------------------------------------------- + +C ---------------------------------------------------------------- +C if nblks=1 +C arrowhead form is now stored in II (1..nz) and XX (1..nz) +C in reverse pivotal order (arrowhead n, n-1, ..., 2, 1). +C The arrowhead form will be overwritten. +C else if not presrv +C off-diagonal part is in II (1..nzoff), XX (1..nzoff), +C (with row pointers Offp (1..n+1)) followed by each diagonal +C block (block 1, 2, ... nblks) in II/XX (nzoff+1...nz). +C Each diagonal block is in arrowhead form, and in +C reverse pivotal order (arrowhead k2, k2-1, ..., k1-1, k1). +C The arrowhead form will be overwritten. +C else (nblks > 1 and presrv) +C II and XX are still empty. Original matrix is in Ap, Ai, +C and Ax. Inverse row permutation (Pr) is in Offp (1..n). +C The arrowhead form is not yet computed. +C ---------------------------------------------------------------- + + IF (NBLKS .EQ. 1) THEN + +C ------------------------------------------------------------- +C refactorize the matrix as a single block +C ------------------------------------------------------------- + + NLU = LUI (2) + MC = LUI (4) + MR = LUI (5) + WRKSIZ = 2*N + MR + 3*MC + 4*(NLU+2) + ITAIL = ITAIL - WRKSIZ + IUSE = IUSE + WRKSIZ + P = ITAIL + INFO (18) = MAX (INFO (18), IUSE) + IF (IHEAD .GT. ITAIL) THEN +C error return, if not enough integer memory: + GO TO 9000 + ENDIF + + CALL MA38RD (CP, NZ, N, XTAIL, + $ XX, XSIZE, XUSE, II, CPERM, RPERM, + $ ICNTL, INFO, RINFO, MC, MR, + $ II (P), II (P+N), II (P+2*N), II (P+2*N+MR), + $ II (P+2*N+MR+MC), II (P+2*N+MR+2*MC), + $ II (P+2*N+MR+3*MC), II (P+2*N+MR+3*MC+(NLU+2)), + $ II (P+2*N+MR+3*MC+2*(NLU+2)), + $ II (P+2*N+MR+3*MC+3*(NLU+2)), + $ NLU, LUI (6), LUI (NLU+6), NOUTSD, + $ XRMAX) + + IF (INFO (1) .LT. 0) THEN +C error return, if not enough real memory or bad pivot found + GO TO 9010 + ENDIF + +C ------------------------------------------------------------- +C deallocate workspace and original matrix (reals already done) +C ------------------------------------------------------------- + + IUSE = IUSE - WRKSIZ - NZ + ITAIL = ITAIL + WRKSIZ + LUI (1) = 1 + IHEAD = 1 + XHEAD = 1 + + ELSE + +C ------------------------------------------------------------- +C refactorize the block-upper-triangular form of the matrix +C ------------------------------------------------------------- + + IF (PRESRV) THEN +C count the entries in off-diagonal part + NZOFF = 0 + ENDIF + + DO 70 BLK = NBLKS, 1, -1 + +C ---------------------------------------------------------- +C factorize the kn-by-kn block, A (k1..k2, k1..k2) +C ---------------------------------------------------------- + +C get k1 and k2, the start and end of this block + K1 = BLKP (BLK) + K2 = BLKP (BLK+1) - 1 + KN = K2-K1+1 + A = ZERO + +C ---------------------------------------------------------- +C get pointers to, or place the block in, arrowhead form +C ---------------------------------------------------------- + + IF (PRESRV) THEN + + IF (KN .GT. 1) THEN + +C ---------------------------------------------------- +C convert a single block to arrowhead format, using +C the inverse row permutation stored in Offp +C ---------------------------------------------------- + +C ---------------------------------------------------- +C compute nzblk, allocate II/XX (1..nzblk), W(1..kn+1) +C ---------------------------------------------------- + + NZBLK = 0 + DO 40 K = K1, K2 + COL = CPERM (K) +CFPP$ NODEPCHK L + DO 30 P = AP (COL), AP (COL+1) - 1 + ROW = OFFP (AI (P)) + IF (ROW .LT. K1) THEN +C entry in off-diagonal part + NZOFF = NZOFF + 1 + ELSE IF (ROW .LE. K2) THEN +C entry in diagonal block + NZBLK = NZBLK + 1 + ENDIF +30 CONTINUE +40 CONTINUE + + ITAIL = ITAIL - (KN+1) + WP = ITAIL + IHEAD = NZBLK + 1 + XHEAD = NZBLK + 1 + IUSE = IUSE + NZBLK + KN+1 + XUSE = XUSE + NZBLK + XRMAX = MAX (XRMAX, XUSE) + INFO (18) = MAX (INFO (18), IUSE) + INFO (20) = MAX (INFO (20), XUSE) + INFO (21) = MAX (INFO (21), XUSE) + IF (IHEAD .GT. ITAIL .OR. XHEAD .GT. XTAIL) THEN +C error return, if not enough integer +C and/or real memory: + GO TO 9000 + ENDIF + +C ---------------------------------------------------- +C convert blk from column-form in Ai/Ax to arrowhead +C form in II/XX (1..nzblk) +C ---------------------------------------------------- + + CALL MA38QD (PRESRV, N, NZ, CPERM, RPERM, OFFP, + $ II (WP), NBLKS, XX, II, DUMMY1, DUMMY2, + $ ICNTL, AP, BLKP, AI, AX, OFFP, 0, NZBLK, + $ BLK, KN, NZ2, I) + +C ---------------------------------------------------- +C copy the arrowhead pointers from W (1..kn+1) +C to Cp (k1 ... k2+1) +C ---------------------------------------------------- + + DO 50 I = 0, KN + CP (K1+I) = II (WP+I) +50 CONTINUE + +C Cp (k1) is nzblk + 1 and Cp (k2+1) is 1 + +C ---------------------------------------------------- +C deallocate W (1..kn+1) +C ---------------------------------------------------- + + IUSE = IUSE - (KN+1) + ITAIL = ITAIL + (KN+1) + + ELSE + +C ---------------------------------------------------- +C get the value of singleton at A (k1,k1) if it exists +C ---------------------------------------------------- + +C find the diagonal entry in the unpermuted matrix, +C and count the entries in the diagonal and +C off-diagonal blocks. + COL = CPERM (K1) + DO 60 P = AP (COL), AP (COL + 1) - 1 +C inverse row permutation is stored in Offp + ROW = OFFP (AI (P)) + IF (ROW .LT. K1) THEN + NZOFF = NZOFF + 1 + ELSE IF (ROW .EQ. K1) THEN + A = AX (P) +C else +C this is an invalid entry, below the diagonal +C block. It will be detected (and optionally +C printed) in the call to MA38MD below. + ENDIF +60 CONTINUE + + IHEAD = 1 + XHEAD = 1 + ENDIF + + ELSE + +C ------------------------------------------------------- +C the block is located in II/XX (Cp (k2+1) ... Cp (k1)-1) +C and has already been converted to arrowhead form +C ------------------------------------------------------- + + IF (BLK .EQ. 1) THEN +C this is the last block to factorize + CP (K2+1) = NZOFF + 1 + ELSE + CP (K2+1) = CP (BLKP (BLK-1)) + ENDIF + + IHEAD = CP (K1) + XHEAD = IHEAD + + IF (KN .EQ. 1) THEN +C singleton block in II/XX (Cp (k1+1) ... Cp (k1)-1) + IF (CP (K1) .GT. CP (K1+1)) THEN + A = XX (CP (K1) - 1) + IHEAD = IHEAD - 1 + XHEAD = XHEAD - 1 + IUSE = IUSE - 1 + XUSE = XUSE - 1 + ENDIF + ENDIF + + ENDIF + +C ---------------------------------------------------------- +C factor the block +C ---------------------------------------------------------- + + IF (KN .GT. 1) THEN + +C ------------------------------------------------------- +C The A (k1..k2, k1..k2) block is not a singleton. +C block is now in II/XX (Cp (k2+1) ... Cp (k1)-1), in +C arrowhead form, and is to be overwritten with LU +C ------------------------------------------------------- + + ARNZ = CP (K1) - 1 + +C if (presrv) then +C II/XX (1..arnz) holds just the current block, blk +C else +C II/XX (1..arnz) holds the off-diagonal part, and +C blocks 1..blk, in that order. +C endif + + LUIP = LUBLKP (BLK) +C luxp = LUi (luip), not needed for refactorization + NLU = LUI (LUIP+1) +C npiv = LUi (luip+2), not needed for refactorization + MC = LUI (LUIP+3) + MR = LUI (LUIP+4) + WRKSIZ = 2*KN + MR + 3*MC + 4*(NLU+2) + ITAIL = ITAIL - WRKSIZ + IUSE = IUSE + WRKSIZ + P = ITAIL + INFO (18) = MAX (INFO (18), IUSE) + IF (IHEAD .GT. ITAIL) THEN +C error return, if not enough integer memory: + GO TO 9000 + ENDIF + + CALL MA38RD (CP (K1), ARNZ, KN, XTAIL, + $ XX, XTAIL-1, XUSE, II, CPERM (K1), RPERM (K1), + $ ICNTL, INFO, RINFO, MC, MR, + $ II (P), II (P+KN), II (P+2*KN), II (P+2*KN+MR), + $ II (P+2*KN+MR+MC), II (P+2*KN+MR+2*MC), + $ II (P+2*KN+MR+3*MC), II (P+2*KN+MR+3*MC+(NLU+2)), + $ II (P+2*KN+MR+3*MC+2*(NLU+2)), + $ II (P+2*KN+MR+3*MC+3*(NLU+2)), + $ NLU, LUI (LUIP+5), LUI (LUIP+NLU+5), NOUTSD, + $ XRMAX) + + IF (INFO (1) .LT. 0) THEN +C error return, if not enough real memory or bad pivot + GO TO 9010 + ENDIF + +C ------------------------------------------------------- +C deallocate workspace and original matrix (reals +C already deallocated in MA38RD) +C ------------------------------------------------------- + + IUSE = IUSE - WRKSIZ + ITAIL = ITAIL + WRKSIZ + LUI (LUIP) = XTAIL + IUSE = IUSE - (IHEAD - CP (K2+1)) + IHEAD = CP (K2+1) + XHEAD = IHEAD + + ELSE + +C ------------------------------------------------------- +C factor the singleton A (k1,k1) block, in a +C ------------------------------------------------------- + + NSGLTN = NSGLTN + 1 + IF (A .EQ. ZERO) THEN +C this is a singular matrix, replace with 1-by-1 +C identity matrix. + A = ONE + ELSE +C increment pivot count + NPIV = NPIV + 1 + ENDIF + XTAIL = XTAIL - 1 + XUSE = XUSE + 1 + XRMAX = MAX (XRMAX, XUSE) + INFO (20) = MAX (INFO (20), XUSE) + INFO (21) = MAX (INFO (21), XUSE) +C note: if the matrix is not preserved and nonsingular +C then we will not run out of memory + IF (XHEAD .GT. XTAIL) THEN +C error return, if not enough real memory: + GO TO 9000 + ENDIF + +C ------------------------------------------------------- +C store the 1-by-1 LU factors +C ------------------------------------------------------- + + XX (XTAIL) = A + LUBLKP (BLK) = -XTAIL + + ENDIF +70 CONTINUE + +C ------------------------------------------------------------- +C make the index of each block relative to start of LU factors +C ------------------------------------------------------------- +CFPP$ NODEPCHK L + DO 80 BLK = 1, NBLKS + IF (LUBLKP (BLK) .GT. 0) THEN + LUI (LUBLKP (BLK)) = LUI (LUBLKP (BLK)) - XTAIL + 1 + ELSE +C this is a singleton + LUBLKP (BLK) = (-LUBLKP (BLK)) - XTAIL + 1 + ENDIF +80 CONTINUE + +C ------------------------------------------------------------- +C store the off-diagonal blocks +C ------------------------------------------------------------- + + IF (PRESRV) THEN + +C ---------------------------------------------------------- +C allocate temporary workspace for Pr (1..n) at head of II +C ---------------------------------------------------------- + + PRP = IHEAD + IHEAD = IHEAD + N + IUSE = IUSE + N + +C ---------------------------------------------------------- +C allocate permanent copy of off-diagonal blocks +C ---------------------------------------------------------- + + ITAIL = ITAIL - NZOFF + OFFIP = ITAIL + XTAIL = XTAIL - NZOFF + OFFXP = XTAIL + IUSE = IUSE + NZOFF + XUSE = XUSE + NZOFF + XRMAX = MAX (XRMAX, XUSE) + INFO (18) = MAX (INFO (18), IUSE) + INFO (20) = MAX (INFO (20), XUSE) + INFO (21) = MAX (INFO (21), XUSE) + IF (IHEAD .GT. ITAIL .OR. XHEAD .GT. XTAIL) THEN +C error return, if not enough integer and/or real memory: + GO TO 9000 + ENDIF + +C ---------------------------------------------------------- +C re-order the off-diagonal blocks according to pivot perm +C ---------------------------------------------------------- + +C use Cp as temporary work array: + MNZ = NZOFF + IF (NZOFF .EQ. 0) THEN +C Offi and Offx are not accessed in MA38MD. Set offip +C and offxp to 1 (since offip = itail = isize+1, which +C can generate an address fault, otherwise). + OFFIP = 1 + OFFXP = 1 + ENDIF + CALL MA38MD (CP, N, RPERM, CPERM, NZOFF, + $ OFFP, II (OFFIP), XX (OFFXP), II (PRP), + $ ICNTL, AP, AI, AX, AN, ANZ, PRESRV, NBLKS, BLKP, + $ MNZ, 2, NBELOW) + +C ---------------------------------------------------------- +C deallocate Pr (1..n) +C ---------------------------------------------------------- + + IHEAD = 1 + XHEAD = 1 + IUSE = IUSE - N + + ELSE + +C off-diagonal entries are in II/XX (1..nzoff); shift down +C to II/XX ( ... itail/xtail). No extra memory needed. + DO 90 I = NZOFF, 1, -1 + II (ITAIL+I-NZOFF-1) = II (I) + XX (XTAIL+I-NZOFF-1) = XX (I) +90 CONTINUE + IHEAD = 1 + XHEAD = 1 + ITAIL = ITAIL - NZOFF + XTAIL = XTAIL - NZOFF + ENDIF + + ENDIF + +C ---------------------------------------------------------------- +C clear the flags (negated row/col indices, and negated ludegr/c) +C ---------------------------------------------------------------- + + DO 100 I = 1, LUISIZ + LUI (I) = ABS (LUI (I)) +100 CONTINUE + +C----------------------------------------------------------------------- +C normal and error return +C----------------------------------------------------------------------- + +C error return label: +9000 CONTINUE + IF (IHEAD .GT. ITAIL) THEN +C set error flag if not enough integer memory + CALL MA38ND (2, ICNTL, INFO, -3, INFO (18)) + ENDIF + IF (XHEAD .GT. XTAIL) THEN +C set error flag if not enough real memory + CALL MA38ND (2, ICNTL, INFO, -4, INFO (21)) + ENDIF + +C error return label, for error return from MA38RD: +9010 CONTINUE + +C Cp can now be deallocated in MA38BD: + IUSE = IUSE - (N+1) + + INFO (4) = NOUTSD + NBELOW + NZDIA = NZORIG - NZOFF - NOUTSD - NBELOW + INFO (5) = NZOFF + NZDIA + INFO (6) = NZDIA + INFO (7) = NZOFF + INFO (8) = NSGLTN + INFO (9) = NBLKS + INFO (12) = INFO (10) + INFO (11) + N + INFO (7) + +C Count the number of symmetric pivots chosen. Note that some +C of these may have been numerically unacceptable. + NSYM = 0 + DO 110 K = 1, N + IF (CPERM (K) .EQ. RPERM (K)) THEN +C this kth pivot came from the diagonal of A + NSYM = NSYM + 1 + ENDIF +110 CONTINUE + INFO (16) = NSYM + + INFO (17) = INFO (17) + NPIV + RINFO (1) = RINFO (4) + RINFO (5) + RINFO (6) + +C set warning flag if entries outside prior pattern are present + IF (INFO (4) .GT. 0) THEN + CALL MA38ND (2, ICNTL, INFO, 1, -INFO (4)) + ENDIF + +C set warning flag if matrix is singular + IF (INFO (1) .GE. 0 .AND. INFO (17) .LT. N) THEN + CALL MA38ND (2, ICNTL, INFO, 4, INFO (17)) + ENDIF + +C ---------------------------------------------------------------- +C return memory usage estimate for next call to MA38BD +C ---------------------------------------------------------------- + + INFO (23) = XRMAX + + RETURN + END + + SUBROUTINE MA38QD (PRESRV, N, NZ, CPERM, RPERM, PR, + * W, NBLKS, ARX, ARI, NZOFF, NZDIA, + * ICNTL, MP, BLKP, MI, MX, OFFP, ON, NZBLK, + * CBLK, KN, NZ2, NBELOW) + INTEGER N, NZ, CPERM(N), RPERM(N), PR(N), KN, W(KN+1), + * NBLKS, NZBLK, ARI(NZBLK), NZOFF, NZDIA, MP(N+1), + * MI(NZ), ON, ICNTL(20), BLKP(NBLKS+1), NZ2, + * OFFP(ON+1), CBLK, NBELOW + LOGICAL PRESRV + DOUBLE PRECISION ARX(NZBLK), MX(NZ) + +C=== MA38QD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Convert a column-oriented matrix into an arrowhead format. + +C======================================================================= +C INPUT: +C======================================================================= +C +C n size of entire matrix +C Mi (1..nz): row indices of column form of entire matrix +C Mx (1..nz): values of column form of entire matrix +C Mp (1..n+1) column pointers for entire matrix +C Cperm (1..n): column permutations +C Rperm (1..n): row permutations +C +C if nblks > 1 and presrv +C cblk: the block to convert +C kn: the size of the block to convert +C else +C cblk: 0 +C kn n, size of input matrix + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C if nblks = 1 and not presrv +C +C nzoff 0 +C nzdia nz - (entries below in diagonal blocks) +C nz2 nzdia +C +C Mi (1..nz2) arrowheads for the diagonal block +C Mx (1..nz2) +C Ari, Arx used as workspace +C W (1..n+1) pointer to each arrowhead in Mi/Mx +C +C Offp not accessed +C +C if nblks = 1 and presrv +C +C nzoff 0 +C nzdia nz - (entries below in diagonal blocks) +C nz2 nzdia +C +C Mi, Mx not modified +C Ari (1..nz2) arrowheads for the diagonal block +C Arx (1..nz2) +C W (1..n+1) pointer to each arrowhead in Ari/Arx +C +C Offp not accessed +C +C else if nblks > 1 and not presrv +C +C nzoff number of entries in off-diagonal part +C nzdia number of entries in diagonal blocks +C (nz = nzoff + nzdia + entries below +C diagonal blocks) +C nz2 nzoff + nzdia +C +C Mi (nzoff+1..nz2) arrowheads for each diagonal block +C Mx (nzoff+1..nz2) +C Ari, Arx used as workspace +C W (1..n+1) pointer to each arrowhead in Mi/Mx +C +C Offp (1..n+1) row pointers for off-diagonal part +C Mi (1..nzoff) col indices for off-diagonal part +C Mx (1..nzoff) values for off-diagonal part +C +C else (nblks > 1 and presrv) +C +C nzoff 0 +C nzdia nonzeros in the diagonal block, cblk +C nz2 nzdia +C +C Mi, Mx not modified +C Ari (1..nz2) arrowheads for the diagonal block, cblk +C Arx (1..nz2) +C W (1..kn+1) pointer to each arrowhead in Ari/Arx +C +C Offp not accessed + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38PD +C subroutines called: MA38MD +C functions called: MIN + INTRINSIC MIN + EXTERNAL MA38MD + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER I, P, ROW, COL, BLK, BASE, K1, K2, K, B1, B2, K0 + +C i: loop index, arrowhead index +C p: pointer into column-form input matrix +C row: row index +C col: column index +C blk: current diagonal block +C base: where to start the construction of the arrowhead form +C k1,k2: current diagonal block is A (k1..k2, k1..k2) +C k: loop index, kth pivot +C b1,b2: convert blocks b1...b2 from column-form to arrowhead form +C k0: convert A (k0+1..., k0+1...) to arrowhead form + +C======================================================================= +C EXECUTABLE STATEMENTS: +C======================================================================= + +C----------------------------------------------------------------------- +C if entire matrix is to be converted, then create the off-diagonal +C part in row-oriented form in Ari (1..nzoff) and Arx (1..nzoff) and +C compute inverse row permutation. Otherwise, the inverse row +C permutation has already been computed. +C----------------------------------------------------------------------- + + NZOFF = 0 + NBELOW = 0 + IF (NBLKS .EQ. 1) THEN + DO 10 K = 1, N + PR (RPERM (K)) = K +10 CONTINUE + ELSE IF (NBLKS .GT. 1 .AND. .NOT. PRESRV) THEN + CALL MA38MD (W, N, RPERM, CPERM, NZOFF, + $ OFFP, ARI, ARX, PR, + $ ICNTL, MP, MI, MX, N, NZ, .TRUE., NBLKS, BLKP, + $ NZ, 2, NBELOW) + ENDIF + +C----------------------------------------------------------------------- +C construct the arrowhead form for the diagonal block(s) +C----------------------------------------------------------------------- + + DO 20 I = 1, KN+1 + W (I) = 0 +20 CONTINUE + + BASE = NZOFF + 1 + + IF (CBLK .NE. 0) THEN +C convert just cblk + K0 = BLKP (CBLK) - 1 + B1 = CBLK + B2 = CBLK + ELSE +C convert all the block(s) + K0 = 0 + B1 = 1 + B2 = NBLKS + ENDIF + + DO 80 BLK = B1, B2 + +C ------------------------------------------------------------- +C get the starting and ending indices of this diagonal block +C ------------------------------------------------------------- + + IF (NBLKS .GT. 1) THEN + K1 = BLKP (BLK) + K2 = BLKP (BLK+1) - 1 + ELSE + K1 = 1 + K2 = N + ENDIF + +C ------------------------------------------------------------- +C count the number of entries in each arrowhead +C ------------------------------------------------------------- + + DO 40 COL = K1, K2 + DO 30 P = MP (CPERM (COL)), MP (CPERM (COL) + 1) - 1 + ROW = PR (MI (P)) + IF (ROW .GE. K1 .AND. ROW .LE. K2) THEN +C this is in a diagonal block, arrowhead i + I = MIN (ROW, COL) - K0 + W (I) = W (I) + 1 + ENDIF +30 CONTINUE +40 CONTINUE + +C ------------------------------------------------------------- +C set pointers to point just past end of each arrowhead +C ------------------------------------------------------------- + + W (K2-K0+1) = W (K2-K0) + BASE + DO 50 I = K2-K0, K1-K0+1, -1 + W (I) = W (I+1) + W (I-1) +50 CONTINUE + W (K1-K0) = W (K1-K0+1) +C W (i+1-k0) points just past end of arrowhead i in Ari/Arx + +C ------------------------------------------------------------- +C construct arrowhead form, leaving pointers in final state +C ------------------------------------------------------------- + + DO 70 COL = K1, K2 + DO 60 P = MP (CPERM (COL)), MP (CPERM (COL) + 1) - 1 + ROW = PR (MI (P)) + IF (ROW .GE. K1 .AND. ROW .LE. K2) THEN + IF (ROW .GE. COL) THEN +C diagonal, or lower triangular part + I = COL - K0 + 1 + W (I) = W (I) - 1 + ARI (W (I)) = ROW - K1 + 1 + ARX (W (I)) = MX (P) + ELSE +C upper triangular part, flag by negating col + I = ROW - K0 + 1 + W (I) = W (I) - 1 + ARI (W (I)) = -(COL - K1 + 1) + ARX (W (I)) = MX (P) + ENDIF + ENDIF +60 CONTINUE +70 CONTINUE + + BASE = W (K1-K0) + W (K2-K0+1) = 0 +80 CONTINUE + + W (KN+1) = NZOFF + 1 + NZDIA = BASE - NZOFF - 1 + NZ2 = NZOFF + NZDIA + +C ---------------------------------------------------------------- +C if cblk = 0, the entire matrix has been converted: +C +C W (i) now points just past end of arrowhead i in Ari/Arx +C arrowhead i is located in Ari/Arx (W (i+1) ... W (i)-1), +C except for the k2-th arrowhead in each block. Those are +C located in Ari/Arx (base ... W (k2) - 1), where base is +C W (Blkp (blk-1)) if blk>1 or W (n+1) = nzoff + 1 otherwise. +C +C otherwise, just one block has been converted: +C +C W (i) now points just past end of arrowhead i in Ari/Arx, +C where i = 1 is the first arrowhead of this block (not the +C first arrowhead of the entire matrix). Arrowhead i is +C located in Ari/Arx (W (i+1) ... W (i)-1). +C This option is used only if nblks>1 and presrv is true. +C ---------------------------------------------------------------- + +C----------------------------------------------------------------------- +C if not preserved, overwrite column-form with arrowhead form +C----------------------------------------------------------------------- + + IF (.NOT. PRESRV) THEN + DO 90 I = 1, NZ + MI (I) = ARI (I) + MX (I) = ARX (I) +90 CONTINUE + ENDIF + + RETURN + END + + SUBROUTINE MA38RD (CP, NZ, N, XTAIL, XX, XSIZE, XUSE, ARI, + * CPERM, RPERM, ICNTL, INFO, RINFO, MC, MR, + * WIR, WIC, WPR, WPC, WM, WJ, FRDIMC, FRXP, FRNEXT, + * FRPREV, NLU, LUP, LUI, NOUTSD, XRMAX) + INTEGER XSIZE, ICNTL(20), INFO(40), N, CPERM(N), RPERM(N), + * XTAIL, NZ, ARI(NZ), CP(N+1), MR, MC, NOUTSD, + * WIR(N), WIC(N), WPR(MR), XRMAX, WPC(MC), WM(MC), + * NLU, FRDIMC(NLU+2), FRXP(NLU+2), XUSE, WJ(MC), + * FRNEXT(NLU+2), FRPREV(NLU+2), LUP(NLU), LUI(*) + DOUBLE PRECISION XX(XSIZE), RINFO(20) + +C=== MA38RD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C MA38RD refactorizes the n-by-n input matrix at the head of XX +C (in arrowhead form) and places its LU factors at the tail of +C XX. The input matrix is overwritten. No BTF information is +C used in this routine. + +C======================================================================= +C INPUT: +C======================================================================= +C +C Cp (1..n+1): column pointers of arrowhead form +C n: order of input matrix +C nz: entries in input matrix +C xsize: size of XX +C Icntl: integer control parameters, see MA38ID +C Cntl: real control parameters, see MA38ID +C +C Ari (1..nz): arrowhead format of A +C XX (1..nz): arrowhead format of A, see below +C XX (nz+1..xsize): undefined on input, used as workspace +C +C nlu: number of LU arrowheads +C LUp (1..nlu): pointers to LU arrowheads in LUi +C LUi (1.. ): LU arrowheads +C +C xuse: memory usage in Value +C +C noutsd: entries not in prior LU pattern +C +C Cperm (1..n): column permutation +C Rperm (1..n): row permutation + +C======================================================================= +C WORKSPACE: +C======================================================================= +C +C WiR (1..n) +C WiC (1..n) +C +C WpR (1.. max ludegr) +C WpC (1.. max ludegc) +C Wm (1.. max ludegc) +C Wj (1.. max ludegc) +C +C FRdimc (1..nlu+2) +C FRxp (1..nlu+2) +C FRnext (1..nlu+2) +C FRprev (1..nlu+2) + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C LUi (1..): LU arrowheads, modified luxp pointers +C XX (1..xtail-1): undefined on output +C XX (xtail..xsize): LU factors of this matrix, see below +C +C Info: integer informational output, see MA38AD +C Rinfo: real informational output, see MA38AD +C +C xuse: memory usage in Value +C +C noutsd: entries not in prior LU pattern, incremented + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38PD +C subroutines called: MA38ND, MA38ZD, MA38OD, DGEMV, +C DGEMM, DTRSV, DTRSM +C functions called: ABS, MAX + INTRINSIC ABS, MAX + EXTERNAL MA38ND, MA38OD, MA38ZD, DGEMV, DGEMM, DTRSV, DTRSM + +C======================================================================= +C DESCRIPTION OF DATA STRUCTURES: +C======================================================================= + +C----------------------------------------------------------------------- +C Matrix being factorized: +C----------------------------------------------------------------------- +C +C The input matrix is held in an arrowhead format. For the kth pivot, +C the nonzeros in the pivot row (A (k, k...n)) and pivot column +C (A (k...n, k)) are stored in the kth arrowhead. The kth arrowhead +C is located in: +C Ari (Cp (k+1) ... Cp (k)-1): pattern +C XX (Cp (k+1) ... Cp (k)-1): values +C +C Suppose p is in the range Cp (k+1) to Cp (k)-1. If Ari (p) is +C greater than zero, then the entry is in row Ari (p), column k, +C with value XX (p). If Ari (p) is less than zero, then the entry is +C in row k, column -Ari (p), with value XX (p). The arrowheads are +C stored in reverse order (arrowhead n, n-1, ... 2, 1) in Ari and XX. +C Note that Cp (n+1) = 1 unless BTF is in use and the original matrix +C is not preserved. In all cases, the real part of the arrowhead +C format (XX (Cp (n+1) ... Cp (1)-1)) is overwritten with the LU +C factors. The integer part (Ari (Cp (n+1) ... Cp (1)-1)) is not +C overwritten, since MA38RD does not require dynamic allocation of +C integer memory. + +C----------------------------------------------------------------------- +C Frontal matrices +C----------------------------------------------------------------------- +C +C Each unassembled frontal matrix (element) is stored as follows: +C total size: fscal integers, (fdimr*fdimc) reals +C +C if e is an unassembled element, and not the current frontal +C matrix: +C +C fluip = LUp (e) pointer to LU arrowhead in II +C fdimc = FRdimc (e) column dimension of contribution block +C fxp = FRxp (e) pointer to contribution block in XX +C next = FRnext (e) pointer to next block in XX +C prev = FRprev (e) pointer to previous block in XX +C fdegr = abs (LUi (fluip+2)) +C fdegc = abs (LUi (fluip+2)) +C XX (fxp ... ) +C a 2-dimensional array, C (1..fdimc, 1..fdimr), where +C fdimr = fdegr if the contribution block is compressed, +C or fdimr = LUi (fluip+5) if not. Note, however, that +C fdimr is not needed. The contribution block is stored +C in C (1..fdegc, 1..fdegr) in the C (1..fdimc,...) array. +C +C If memory is limited, garbage collection will occur. +C In this case, the C (1..fdimc, 1..fdimr) array is +C compressed to be just large enough to hold the +C unassembled contribution block, +C C (1..fdegc, 1..fdegr). + +C----------------------------------------------------------------------- +C Current frontal matrix +C----------------------------------------------------------------------- +C +C ffxp points to current frontal matrix (contribution block and LU +C factors). For example, if fflefc = 4, fflefr = 6, luk = 3, +C ffdimc = 8, ffdimr = 12, then "x" is a term in the contribution +C block, "l" in L1, "u" in U1, "L" in L2, "U" in U2, and "." is unused. +C XX (fxp) is "X". The first 3 pivot values (diagonal entries in U1) +C are labelled 1, 2, and 3. The frontal matrix is ffdimc-by-ffdimr. +C +C |----------- col 1 of L1 and L2, etc. +C V +C X x x x x x L L L . . . +C x x x x x x L L L . . . +C x x x x x x L L L . . . +C x x x x x x L L L . . . +C U U U U U U 3 l l . . . <- row 3 of U1 and U2 +C U U U U U U u 2 l . . . <- row 2 of U1 and U2 +C U U U U U U u u 1 . . . <- row 1 of U1 and U2 +C . . . . . . . . . . . . + +C----------------------------------------------------------------------- +C LU factors +C----------------------------------------------------------------------- +C +C The LU factors are placed at the tail of XX. If this routine +C is factorizing a single block, then this description is for the +C factors of the single block: +C +C LUi (1..): integer info. for LU factors +C XX (xtail..xsize): real values in LU factors +C +C Each LU arrowhead (or factorized element) is stored as follows: +C --------------------------------------------------------------- +C +C total size: (7 + ludegc + ludegr + lunson) integers, +C (luk**2 + ludegc*luk + luk*ludegc) reals +C +C If e is an LU arrowhead, then luip = LUp (e). +C +C luxp = LUi (luip) pointer to numerical LU arrowhead +C luk = LUi (luip+1) number of pivots in LU arrowhead +C ludegr = LUi (luip+2) degree of last row of U (excl. diag) +C ludegc = LUi (luip+3) degree of last col of L (excl. diag) +C lunson = LUi (luip+4) number of children in assembly DAG +C ffdimr = LUi (luip+5) +C ffdimc = LUi (luip+6) +C max front size for this LU arrowhead is +C ffdimr-by-ffdimc, or zero if this LU arrowhead +C factorized within the frontal matrix of a prior +C LU arrowhead. +C lucp = (luip + 7) +C pointer to pattern of column of L +C lurp = lucp + ludegc +C pointer to patter of row of U +C lusonp = lurp + ludegr +C pointer to list of sons in the assembly DAG +C LUi (lucp ... lucp + ludegc - 1) +C row indices of column of L +C LUi (lurp ... lurp + ludegr - 1) +C column indices of row of U +C LUi (lusonp ... lusonp + lunson - 1) +C list of sons +C XX (luxp...luxp + luk**2 + ludegc*luk + luk*ludegr - 1) +C pivot block (luk-by-luk) and the L block +C (ludegc-by-luk) in a single (luk+ludegc)-by-luk +C array, followed by the U block in a +C luk-by-ludegr array. +C +C Pivot column/row pattern (also columns/rows in contribution block): +C If the column/row index is negated, the column/row has been +C assembled out of the frontal matrix into a subsequent frontal +C matrix. After factorization, the negative flags are removed. +C +C List of sons: +C 1 <= son <= n: son an LUson +C n+1 <= son <= 2n: son-n is an Uson +C 2n+n <= son <= 3n: son-2n is a Lson + +C----------------------------------------------------------------------- +C Workspaces: +C----------------------------------------------------------------------- +C +C WpC (1..ludegr): holds the pivot column pattern +C (excluding the pivot row indices) +C +C WpR (1..ludegr): holds the pivot row pattern +C (excluding the pivot column indices) +C +C WiR (row) >= 0 for each row in pivot column pattern. +C offset into pattern is given by: +C WiR (row) == offset - 1 +C Otherwise, WiR (1..n) is < 0 +C +C WiC (col) >= 0 for each col in pivot row pattern. +C WiC (col) == (offset - 1) * ffdimc +C Otherwise, WiC (1..n) is < 0 +C +C Wm (1..degc) or Wm (1..fdegc): a gathered copy of WiR +C Wj (1..degc) or Wj (1..fdegc): offset in pattern of a son + +C----------------------------------------------------------------------- +C Memory allocation in XX: +C----------------------------------------------------------------------- +C +C XX (1..xhead): values of original entries in arrowheads of +C matrix, values of contribution blocks, followed +C by the current frontal matrix. +C +C mtail = nlu+2 +C mhead = nlu+1: FRnext (mhead) points to the first contribution +C block in the head of XX. The FRnext and FRprev +C arrays form a doubly-linked list. Traversing +C the list from mhead to mtail gives the +C contribution blocks in ascending ordering of +C address (FRxp). A block is free if FRdimc <= 0. +C The largest known free block in XX is pfree, +C located in +C XX (FRxp (pfree) ... FRxp (pfree) + xfree -1), +C unless pfree = 0, in which case no largest free +C block is known. + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER SWPCOL, SWPROW, FDIMC, K0, COLPOS, ROWPOS, PIVOT, FFPP, + $ P, I, J, LUDEGR, LUDEGC, KPOS, SP, FFRP, FFCP, TYPE, + $ FXP, LURP, LUCP, NEXT, FFLEFR, PREV, XHEAD, FDEGR, + $ FFLEFC, K, XCDP, XDP, XSP, S, FDEGC, FLURP, FLUCP, + $ COL, E, ROW, MHEAD, MTAIL, UXP, LUK, IO, FLUIP, LUSONP, + $ FFSIZE, FFXP, FFDIMR, FFDIMC, XRDP, NPIV, NB, LUNSON, + $ XNEED, LDIMR, LDIMC, LXP, PRL, XP, LUIP, PFREE, XFREE, + $ XS, LUXP, FSP, FLP, FDP, DEGC, NZU, NZL, XRUSE + LOGICAL PR3, ALLCOL, ALLROW + DOUBLE PRECISION + $ ONE, ZERO, X + PARAMETER (ONE = 1.0D0, ZERO = 0.0D0) + +C Printing control: +C ----------------- +C prl: invalid entries printed if prl >= 3 +C io: I/O unit for warning messages (printing invalid entries) +C pr3: true if invalid entries are to be printed when found +C +C Current working array: +C ---------------------- +C ffxp: current working array is in XX (ffxp ... ffxp+ffsize-1) +C ffsize: size of current working array in XX +C ffdimr: row degree (number of columns) of current working array +C ffdimc: column degree (number of rows) of current working array +C fflefr: row degree (number of columns) of current contribution block +C fflefc: column degree (number of rows) of current contribution block +C ffrp: U2 block is in XX (ffrp ...) +C ffcp: L2 block is in XX (ffcp ...) +C ffpp: location in XX of the current pivot value +C +C Current element: +C ---------------- +C s: current element being factorized +C luip: current element is in LUi (luip ...) +C luk: number of pivots in current element +C ludegc: degree of pivot column (excluding pivots themselves) +C ludegr: degree of pivot row (excluding pivots themselves) +C ldimr: row degree (number of columns) of current element +C ldimc: column degree (number of row) of current element +C lucp: pattern of col(s) of current element in LUi (lucp...) +C lurp: pattern of row(s) of current element in LUi (lurp...) +C lusonp: list of sons of current element is in LUi (lusonp...) +C lunson: number of sons of current element +C sp: pointer into list of sons of current element +C luxp: numerical values of LU arrowhead stored in XX (luxp ...) +C lxp: L2 block is stored in XX (lxp ...) when computed +C uxp: U2 block is stored in XX (uxp ...) when computed +C nzu: nonzeros above diagonal in U in current LU arrowhead +C nzl: nonzeros below diagonal in L in current LU arrowhead +C swpcol: the non-pivotal column to be swapped with pivot column +C swprow: the non-pivotal row to be swapped with pivot row +C colpos: position in WpR of the pivot column +C rowpos: position in WpC of the pivot row +C kpos: position in C to place pivot row/column +C k: current pivot is kth pivot of current element, k=1..luk +C k0: contribution block, C, has been updated with pivots 1..k0 +C npiv: number of pivots factorized so far, excl. current element +C pivot: current pivot entry is A (pivot, pivot) +C xcdp: current pivot column is in XX (xcdp ...) +C xrdp: current pivot row is in XX (xrdp ...) +C +C Son, or element other than current element: +C ------------------------------------------- +C e: an element other than s (a son of s, for example) +C fluip: LU arrowhead of e is in LUi (fluip ...) +C fxp: contribution block of son is in XX (fxp ...) +C fdimc: leading dimension of contribution block of a son +C fdegr: row degree of contribution block of son (number of columns) +C fdegc: column degree of contribution block of son (number of rows) +C allcol: true if all columns are present in son +C allrow: true if all rows are present in son +C flucp: pattern of col(s) of son in LUi (flucp...) +C flurp: pattern of row(s) of son in LUi (flurp...) +C type: an LUson (type = 1), Uson (type = 2) or Lson (type = 3) +C degc: compressed column offset vector of son is in Wj/Wm (1..degc) +C +C Memory allocation: +C ------------------ +C mhead: nlu+1, head pointer for contribution block link list +C mtail: nlu+2, tail pointer for contribution block link list +C prev: FRprev (e) of the element e +C next: FRnext (e) of the element e +C pfree: FRxp (pfree) is the largest known free block in XX +C xfree: size of largest known free block in XX +C xneed: bare minimum memory currently needed in XX +C xhead: XX (1..xhead-1) is in use, XX (xhead ..) is free +C xruse: estimated memory needed in XX for next call to MA38BD, +C assuming a modest number of garbage collections +C xs: size of a block of memory in XX +C +C Other: +C ------ +C xdp: destination pointer, into XX +C xsp: source pointer, into XX +C xp: a pointer into XX +C fsp: source pointer, into XX +C fsp: destination pointer, into XX +C flp: last row/column in current contribution is in XX (flp...) +C col: a column index +C row: a row index +C nb: block size for tradeoff between Level-2 and Level-3 BLAS +C p, i, j, x: various uses + +C======================================================================= +C EXECUTABLE STATEMENTS: +C======================================================================= + +C ---------------------------------------------------------------- +C get control parameters and initialize various scalars +C ---------------------------------------------------------------- + + IO = ICNTL (2) + PRL = ICNTL (3) + NB = MAX (1, ICNTL (7)) + NPIV = 0 + XHEAD = CP (1) + XTAIL = XSIZE + 1 + XNEED = XUSE + XRUSE = XUSE + XRMAX = MAX (XRMAX, XRUSE) + MHEAD = NLU+1 + MTAIL = NLU+2 + XFREE = -1 + PFREE = 0 + PR3 = PRL .GE. 3 .AND. IO .GE. 0 + +C ---------------------------------------------------------------- +C initialize workspaces +C ---------------------------------------------------------------- + + DO 10 I = 1, N + WIR (I) = -1 + WIC (I) = -1 +10 CONTINUE + + DO 20 E = 1, NLU+2 + FRDIMC (E) = 0 + FRXP (E) = 0 + FRNEXT (E) = 0 + FRPREV (E) = 0 +20 CONTINUE + FRNEXT (MHEAD) = MTAIL + FRPREV (MTAIL) = MHEAD + FRXP (MHEAD) = XHEAD + FRXP (MTAIL) = XHEAD + +C count the numerical assembly of the original matrix + RINFO (2) = RINFO (2) + NZ + +C current working array is empty: + FFLEFR = 0 + FFLEFC = 0 + FFSIZE = 0 + FFXP = XHEAD + +C======================================================================= +C Factorization [ +C======================================================================= + + DO 600 S = 1, NLU + +C======================================================================= +C Get the next element to factorize +C======================================================================= + + LUIP = LUP (S) + LUK = LUI (LUIP+1) + LUDEGC = LUI (LUIP+3) + LUDEGR = LUI (LUIP+2) + LUNSON = LUI (LUIP+4) + LUCP = (LUIP + 7) + LURP = LUCP + LUDEGC + LUSONP = LURP + LUDEGR + LDIMC = LUK + LUDEGC + LDIMR = LUK + LUDEGR + +C======================================================================= +C Start new frontal matrix or merge with prior contribution block [ +C======================================================================= + +C ============================================================= + IF (LUI (LUIP+6) .NE. 0) THEN +C start new contribution block +C ============================================================= + +C ---------------------------------------------------------- +C clear the prior offsets +C ---------------------------------------------------------- + + DO 30 I = 1, FFLEFR + WIC (WPR (I)) = -1 +30 CONTINUE + DO 40 I = 1, FFLEFC + WIR (WPC (I)) = -1 +40 CONTINUE + +C ---------------------------------------------------------- +C save prior contribution block (s-1), if it exists +C ---------------------------------------------------------- + + XS = FFLEFR * FFLEFC + IF (FFSIZE .NE. 0) THEN +C one more frontal matrix is finished + XNEED = XNEED - (FFSIZE - XS) + XRUSE = XRUSE - (FFSIZE - XS) + INFO (13) = INFO (13) + 1 +C else +C prior contribution block does not exist + ENDIF + + IF (FFLEFR .LE. 0 .OR. FFLEFC .LE. 0) THEN + +C ------------------------------------------------------- +C if prior contribution block nonexistent or empty +C ------------------------------------------------------- + + XUSE = XUSE - (XHEAD - FRXP (MTAIL)) + XHEAD = FRXP (MTAIL) + + ELSE + +C ------------------------------------------------------- +C prepare the prior contribution block for later assembly +C ------------------------------------------------------- + + E = S - 1 + +C count the numerical assembly + RINFO (2) = RINFO (2) + XS + + IF (XS .LE. XFREE) THEN + +C ---------------------------------------------------- +C compress and store in a freed block +C ---------------------------------------------------- + +C place the new block in the list + XFREE = XFREE - XS + IF (PFREE .EQ. MTAIL) THEN +C place the new block at start of tail block + PREV = FRPREV (MTAIL) + NEXT = MTAIL + XDP = FRXP (MTAIL) + FRXP (MTAIL) = XDP + XS + ELSE +C place the new block at end of block + PREV = PFREE + NEXT = FRNEXT (PFREE) + XDP = FRXP (NEXT) - XS + IF (XFREE .EQ. 0 .AND. PFREE .NE. MHEAD) THEN +C delete the free block if its size is zero + PREV = FRPREV (PREV) + PFREE = 0 + XFREE = -1 + ENDIF + ENDIF + DO 60 J = 0, FFLEFR - 1 +CFPP$ NODEPCHK L + DO 50 I = 0, FFLEFC - 1 + XX (XDP+J*FFLEFC+I) = XX (FFXP+J*FFDIMC+I) +50 CONTINUE +60 CONTINUE + XUSE = XUSE - (XHEAD - FRXP (MTAIL)) + XHEAD = FRXP (MTAIL) + FRXP (E) = XDP + FRDIMC (E) = FFLEFC + + ELSE + +C ---------------------------------------------------- +C deallocate part of unused portion of frontal matrix +C ---------------------------------------------------- + +C leave the contribution block C (1:fflefc, 1:fflefr) +C at head of XX, with column dimension of ffdimc and +C space of size (fflefr-1)*ffdimc for the first +C fflefr columns, and fflefc for the last column. + XS = FFSIZE - (FFLEFC + (FFLEFR-1)*FFDIMC) + XHEAD = XHEAD - XS + XUSE = XUSE - XS + PREV = FRPREV (MTAIL) + NEXT = MTAIL + FRXP (MTAIL) = XHEAD + FRXP (E) = FFXP + FRDIMC (E) = FFDIMC + ENDIF + + FRNEXT (PREV) = E + FRPREV (NEXT) = E + FRNEXT (E) = NEXT + FRPREV (E) = PREV + + ENDIF + + IF (PFREE .EQ. MTAIL) THEN + PFREE = 0 + XFREE = -1 + ENDIF + +C ---------------------------------------------------------- +C allocate a new ffdimr-by-ffdimc frontal matrix +C ---------------------------------------------------------- + + FFDIMC = LUI (LUIP+6) + FFDIMR = LUI (LUIP+5) + FFSIZE = FFDIMR * FFDIMC + FFXP = 0 + +C ---------------------------------------------------------- +C allocate and zero the space, garbage collection if needed +C ---------------------------------------------------------- + + IF (FFSIZE .GT. XTAIL-XHEAD) THEN + INFO (15) = INFO (15) + 1 + CALL MA38OD (XX, XSIZE, XHEAD, XUSE, + $ LUI, FRDIMC, FRXP, FRNEXT, FRPREV, NLU, LUP, + $ FFXP, FFSIZE, PFREE, XFREE) + ENDIF + + FFXP = XHEAD + XHEAD = XHEAD + FFSIZE + XUSE = XUSE + FFSIZE + XNEED = XNEED + FFSIZE + XRUSE = XRUSE + FFSIZE + XRMAX = MAX (XRMAX, XRUSE) + INFO (20) = MAX (INFO (20), XUSE) + INFO (21) = MAX (INFO (21), XNEED) + IF (XHEAD .GT. XTAIL) THEN +C error return, if not enough real memory: + GO TO 9000 + ENDIF + +C ---------------------------------------------------------- +C zero the frontal matrix +C ---------------------------------------------------------- + + DO 70 P = FFXP, FFXP + FFSIZE - 1 + XX (P) = ZERO +70 CONTINUE + +C ---------------------------------------------------------- +C place pivot rows and columns in correct position +C ---------------------------------------------------------- + + DO 80 K = 1, LUK + WIC (NPIV + K) = (LDIMR - K) * FFDIMC + WIR (NPIV + K) = LDIMC - K +80 CONTINUE + +C ---------------------------------------------------------- +C get the pivot row pattern of the new LU arrowhead +C ---------------------------------------------------------- + + DO 90 I = 0, LUDEGR - 1 + COL = LUI (LURP+I) + WIC (COL) = I * FFDIMC + WPR (I+1) = COL +90 CONTINUE + +C ---------------------------------------------------------- +C get the pivot column pattern of the new LU arrowhead +C ---------------------------------------------------------- + + DO 100 I = 0, LUDEGC - 1 + ROW = LUI (LUCP+I) + WIR (ROW) = I + WPC (I+1) = ROW +100 CONTINUE + +C ============================================================= + ELSE +C merge with prior contribution block +C ============================================================= + +C ---------------------------------------------------------- +C prior block is located at XX (ffxp ... ffxp + ffsize - 1). +C It holds a working array C (1..ffdimc, 1..ffdimr), with a +C prior contribution block in C (1..fflefc, 1..fflefr). +C The last pivot column pattern is WpC (1..fflefc), and +C the last pivot row pattern is WpR (1..fflefr). The +C offsets WiR and WiC are: +C WiR (WpC (i)) = i-1, for i = 1..fflefc, and -1 otherwise. +C WiC (WpR (i)) = (i-1)*ffdimc, for i = 1..fflefr, else -1. +C The prior LU arrowhead is an implicit LUson of the current +C element (and is implicitly assembled into the same +C frontal matrix). +C ---------------------------------------------------------- + +C ---------------------------------------------------------- +C zero the newly extended frontal matrix +C ---------------------------------------------------------- + +C zero the new columns in the contribution and LU blocks +C C (1..ldimc, fflefr+1..ldimr) = 0 + DO 120 J = FFLEFR, LDIMR - 1 + DO 110 I = 0, LDIMC - 1 + XX (FFXP + J*FFDIMC + I) = ZERO +110 CONTINUE +120 CONTINUE + +C C (fflefc+1..ldimc, 1..fflefr) = 0 +C zero the new rows in the contribution and U blocks + DO 140 I = FFLEFC, LDIMC - 1 +CFPP$ NODEPCHK L + DO 130 J = 0, FFLEFR - 1 + XX (FFXP + J*FFDIMC + I) = ZERO +130 CONTINUE +140 CONTINUE + +C ---------------------------------------------------------- +C move pivot rows and columns into correct position +C ---------------------------------------------------------- + + DO 220 K = 1, LUK + +C ------------------------------------------------------- +C kth pivot of frontal matrix, (npiv+k)th pivot of LU +C ------------------------------------------------------- + + PIVOT = NPIV + K + +C ------------------------------------------------------- +C move the kth pivot column into position +C ------------------------------------------------------- + + XSP = WIC (PIVOT) + KPOS = LDIMR - K + 1 + XDP = (KPOS - 1) * FFDIMC + WIC (PIVOT) = XDP + + IF (XSP .GE. 0) THEN +C pivot column is already in current frontal matrix, +C shift into proper position + COLPOS = (XSP / FFDIMC) + 1 + FSP = FFXP + XSP + FDP = FFXP + XDP + + IF (FFLEFR .LT. KPOS) THEN + + IF (FFLEFR .EQ. COLPOS) THEN + +C ---------------------------------------------- +C move C(:,colpos) => C (:,kpos) +C C (:,colpos) = 0 +C ---------------------------------------------- +CFPP$ NODEPCHK L + DO 150 I = 0, LDIMC - 1 + XX (FDP+I) = XX (FSP+I) + XX (FSP+I) = ZERO +150 CONTINUE + + ELSE + +C ---------------------------------------------- +C move C(:,colpos) => C (:,kpos) +C move C(:,fflefr) => C (:,colpos) +C C (:,fflefr) = 0 +C ---------------------------------------------- + + FLP = FFXP + (FFLEFR - 1) * FFDIMC +CFPP$ NODEPCHK L + DO 160 I = 0, LDIMC - 1 + XX (FDP+I) = XX (FSP+I) + XX (FSP+I) = XX (FLP+I) + XX (FLP+I) = ZERO +160 CONTINUE + + SWPCOL = WPR (FFLEFR) + WPR (COLPOS) = SWPCOL + WIC (SWPCOL) = XSP + ENDIF + + ELSE IF (COLPOS .NE. KPOS) THEN + +C ------------------------------------------------- +C swap C (:,colpos) <=> C (:,kpos) +C ------------------------------------------------- +CFPP$ NODEPCHK L + DO 180 I = 0, LDIMC - 1 + X = XX (FDP+I) + XX (FDP+I) = XX (FSP+I) + XX (FSP+I) = X +180 CONTINUE + + SWPCOL = WPR (KPOS) + WPR (COLPOS) = SWPCOL + WIC (SWPCOL) = XSP + ENDIF + + FFLEFR = FFLEFR - 1 + ENDIF + +C ------------------------------------------------------- +C move the kth pivot row into position +C ------------------------------------------------------- + + XSP = WIR (PIVOT) + KPOS = LDIMC - K + 1 + XDP = (KPOS - 1) + WIR (PIVOT) = XDP + + IF (XSP .GE. 0) THEN +C pivot row is already in current frontal matrix, +C shift into proper position + ROWPOS = XSP + 1 + FSP = FFXP + XSP + FDP = FFXP + XDP + + IF (FFLEFC .LT. KPOS) THEN + + IF (FFLEFC .EQ. ROWPOS) THEN + +C ---------------------------------------------- +C move C(rowpos,:) => C (kpos,:) +C C (rowpos,:) = 0 +C ---------------------------------------------- +CFPP$ NODEPCHK L + DO 190 J = 0, (LDIMR - 1) * FFDIMC, FFDIMC + XX (FDP+J) = XX (FSP+J) + XX (FSP+J) = ZERO +190 CONTINUE + + ELSE + +C ---------------------------------------------- +C move C(rowpos,:) => C (kpos,:) +C move C(fflefc,:) => C (rowpos,:) +C C (fflefc,:) = 0 +C ---------------------------------------------- + + FLP = FFXP + (FFLEFC - 1) +CFPP$ NODEPCHK L + DO 200 J = 0, (LDIMR - 1) * FFDIMC, FFDIMC + XX (FDP+J) = XX (FSP+J) + XX (FSP+J) = XX (FLP+J) + XX (FLP+J) = ZERO +200 CONTINUE + + SWPROW = WPC (FFLEFC) + WPC (ROWPOS) = SWPROW + WIR (SWPROW) = XSP + ENDIF + + ELSE IF (ROWPOS .NE. KPOS) THEN + +C ------------------------------------------------- +C swap C (rowpos,:) <=> C (kpos,:) +C ------------------------------------------------- +CFPP$ NODEPCHK L + DO 210 J = 0, (LDIMR - 1) * FFDIMC, FFDIMC + X = XX (FDP+J) + XX (FDP+J) = XX (FSP+J) + XX (FSP+J) = X +210 CONTINUE + + SWPROW = WPC (KPOS) + WPC (ROWPOS) = SWPROW + WIR (SWPROW) = XSP + ENDIF + + FFLEFC = FFLEFC - 1 + ENDIF + +220 CONTINUE + +C ---------------------------------------------------------- +C merge with pivot row pattern of new LU arrowhead +C ---------------------------------------------------------- + + I = FFLEFR + DO 230 P = LURP, LURP + LUDEGR - 1 + COL = LUI (P) + IF (WIC (COL) .LT. 0) THEN + WIC (COL) = I * FFDIMC + I = I + 1 + WPR (I) = COL + ENDIF +230 CONTINUE + +C ---------------------------------------------------------- +C merge with pivot column pattern of new LU arrowhead +C ---------------------------------------------------------- + + I = FFLEFC + DO 240 P = LUCP, LUCP + LUDEGC - 1 + ROW = LUI (P) + IF (WIR (ROW) .LT. 0) THEN + WIR (ROW) = I + I = I + 1 + WPC (I) = ROW + ENDIF +240 CONTINUE + + ENDIF + +C======================================================================= +C Done initializing frontal matrix ] +C======================================================================= + +C======================================================================= +C Assemble original arrowheads into the frontal matrix, and deallocate +C======================================================================= + +C ------------------------------------------------------------- +C current workspace usage: +C ------------------------------------------------------------- + +C WpC (1..ludegr): holds the pivot column pattern +C (excluding the pivot row indices) +C +C WpR (1..ludegr): holds the pivot row pattern +C (excluding the pivot column indices) +C +C C (1..ffdimr, 1..ffdimc): space for the frontal matrix, +C in XX (ffxp ... ffxp + ffsize - 1) +C +C C (i,j) is located at XX (ffxp+((i)-1)+((j)-1)*ffdimc) +C +C C (1..ludegc, 1..ludegr): contribution block +C C (ludegc+1..ludegc+luk, 1..ludegr): U2 block +C C (1..ludegc, ludegr+1..ludegr+luk): L2 block +C C (ludegc+1..ludegc+luk, ludegr+1..ludegr+luk): L1\U1 block +C +C WiR (row) >= 0 for each row in pivot column pattern. +C offset into pattern is given by: +C WiR (row) == offset - 1 +C Also, WiR (npiv+1 ... npiv+luk) is +C ludegc+luk-1 ... ludegc, the offsets of the pivot rows. +C +C Otherwise, WiR (1..n) is < 0 +C +C WiC (col) >= 0 for each col in pivot row pattern. +C WiC (col) == (offset - 1) * ffdimc +C Also, WiC (npiv+1 ... npiv+luk) is +C ludegr+luk-1 ... ludegr, the offsets of the pivot rows. +C +C Otherwise, WiC (1..n) is < 0 + + DO 260 K = 1, LUK + I = NPIV + K + XCDP = FFXP + WIC (I) + XRDP = FFXP + WIR (I) + DO 250 P = CP (I+1), CP (I) - 1 + J = ARI (P) + IF (J .GT. 0) THEN +C a diagonal entry, or lower triangular entry +C row = j, col = i + XP = XCDP + WIR (J) + IF (XP .LT. XCDP) THEN +C invalid entry - not in prior LU pattern + NOUTSD = NOUTSD + 1 + IF (PR3) THEN +C get original row and column index and print it + ROW = RPERM (J) + COL = CPERM (I) + CALL MA38ZD (2, 97, ROW, COL, XX (P), IO) + ENDIF + ELSE + XX (XP) = XX (XP) + XX (P) + ENDIF + ELSE +C an upper triangular entry +C row = i, col = -j + XP = XRDP + WIC (-J) + IF (XP .LT. XRDP) THEN +C invalid entry - not in prior LU pattern + NOUTSD = NOUTSD + 1 + IF (PR3) THEN +C get original row and column index and print it + ROW = RPERM (I) + COL = CPERM (-J) + CALL MA38ZD (2, 97, ROW, COL, XX (P), IO) + ENDIF + ELSE + XX (XP) = XX (XP) + XX (P) + ENDIF + ENDIF +250 CONTINUE +260 CONTINUE + +C deallocate the original arrowheads + P = CP (NPIV + LUK + 1) + XS = CP (NPIV + 1) - P + FRXP (MHEAD) = P + XNEED = XNEED - XS + IF (XS .GT. XFREE) THEN + XFREE = XS + PFREE = MHEAD + ENDIF + +C======================================================================= +C Assemble LUsons, Usons, and Lsons into the frontal matrix [ +C======================================================================= + + DO 480 SP = LUSONP, LUSONP + LUNSON - 1 + +C ---------------------------------------------------------- +C get the son and determine its type (LUson, Uson, or Lson) +C ---------------------------------------------------------- + + E = LUI (SP) + IF (E .LE. N) THEN +C LUson + TYPE = 1 + ELSE IF (E .LE. 2*N) THEN +C Uson + E = E - N + TYPE = 2 + ELSE +C Lson + E = E - 2*N + TYPE = 3 + ENDIF + +C ---------------------------------------------------------- +C if fdimc=0 this is the implicit LUson (already assembled) +C ---------------------------------------------------------- + + FDIMC = FRDIMC (E) + IF (FDIMC .NE. 0) THEN + +C ------------------------------------------------------- +C get scalar info of the son (it needs assembling) +C ------------------------------------------------------- + + FXP = FRXP (E) + FLUIP = LUP (E) + FDEGR = LUI (FLUIP+2) + FDEGC = LUI (FLUIP+3) + ALLCOL = FDEGR .GT. 0 + ALLROW = FDEGC .GT. 0 + FDEGR = ABS (FDEGR) + FDEGC = ABS (FDEGC) + FLUCP = (FLUIP + 7) + FLURP = FLUCP + FDEGC + +C use Wm (1..fdegc) for offsets: + +C ------------------------------------------------------- + IF (TYPE .EQ. 1) THEN +C this is an LUson - assemble an entire frontal matrix +C ------------------------------------------------------- + +C ---------------------------------------------------- + IF (ALLROW) THEN +C no rows assembled out of this LUson yet +C ---------------------------------------------------- + +C compute the compressed column offset vector + DO 270 I = 0, FDEGC-1 + ROW = LUI (FLUCP+I) + WM (I+1) = WIR (ROW) +270 CONTINUE + +C ------------------------------------------------- + IF (ALLCOL) THEN +C no rows or cols assembled out of LUson yet +C ------------------------------------------------- + + DO 290 J = 0, FDEGR-1 + COL = LUI (FLURP+J) + XDP = FFXP + WIC (COL) +CFPP$ NODEPCHK L + DO 280 I = 0, FDEGC-1 + XX (XDP + WM (I+1)) = + $ XX (XDP + WM (I+1)) + + $ XX (FXP + J*FDIMC + I) +280 CONTINUE +290 CONTINUE + +C ------------------------------------------------- + ELSE +C some columns already assembled out of LUson +C ------------------------------------------------- + + DO 310 J = 0, FDEGR-1 + COL = LUI (FLURP+J) + IF (COL .GT. 0) THEN + XDP = FFXP + WIC (COL) +CFPP$ NODEPCHK L + DO 300 I = 0, FDEGC-1 + XX (XDP + WM (I+1)) = + $ XX (XDP + WM (I+1)) + + $ XX (FXP + J*FDIMC + I) +300 CONTINUE + ENDIF +310 CONTINUE + + ENDIF + +C ---------------------------------------------------- + ELSE +C some rows already assembled out of LUson +C ---------------------------------------------------- + +C compute the compressed column offset vector + DEGC = 0 + DO 320 I = 0, FDEGC-1 + ROW = LUI (FLUCP+I) + IF (ROW .GT. 0) THEN + DEGC = DEGC + 1 + WJ (DEGC) = I + WM (DEGC) = WIR (ROW) + ENDIF +320 CONTINUE + +C ------------------------------------------------- + IF (ALLCOL) THEN +C some rows already assembled out of LUson +C ------------------------------------------------- + + DO 340 J = 0, FDEGR-1 + COL = LUI (FLURP+J) + XDP = FFXP + WIC (COL) +CFPP$ NODEPCHK L + DO 330 I = 1, DEGC + XX (XDP + WM (I)) = + $ XX (XDP + WM (I)) + + $ XX (FXP + J*FDIMC + WJ (I)) +330 CONTINUE +340 CONTINUE + +C ------------------------------------------------- + ELSE +C rows and columns already assembled out of LUson +C ------------------------------------------------- + + DO 360 J = 0, FDEGR-1 + COL = LUI (FLURP+J) + IF (COL .GT. 0) THEN + XDP = FFXP + WIC (COL) +CFPP$ NODEPCHK L + DO 350 I = 1, DEGC + XX (XDP + WM (I)) = + $ XX (XDP + WM (I)) + + $ XX (FXP + J*FDIMC + WJ (I)) +350 CONTINUE + ENDIF +360 CONTINUE + + ENDIF + ENDIF + +C ---------------------------------------------------- +C deallocate the LUson frontal matrix +C ---------------------------------------------------- + + FRDIMC (E) = 0 + PREV = FRPREV (E) + NEXT = FRNEXT (E) + XNEED = XNEED - FDEGR*FDEGC + XRUSE = XRUSE - FDEGR*FDEGC + + IF (FRDIMC (PREV) .LE. 0) THEN +C previous block is free - delete this block + FRNEXT (PREV) = NEXT + FRPREV (NEXT) = PREV + E = PREV + PREV = FRPREV (E) + ENDIF + + IF (FRDIMC (NEXT) .LE. 0) THEN +C next block is free - delete this block + FRXP (NEXT) = FRXP (E) + IF (E .LE. NLU) THEN + FRNEXT (PREV) = NEXT + FRPREV (NEXT) = PREV + ENDIF + E = NEXT + NEXT = FRNEXT (E) + IF (FRNEXT (MHEAD) .EQ. MTAIL) THEN +C no blocks left except mhead and mtail + FRXP (MTAIL) = FRXP (MHEAD) + ENDIF + ENDIF + +C get the size of the freed block + IF (NEXT .EQ. 0) THEN +C this is the mtail block + XS = FFXP - FRXP (E) + ELSE + XS = FRXP (NEXT) - FRXP (E) + ENDIF + IF (XS .GT. XFREE) THEN +C keep track of the largest free block + XFREE = XS + PFREE = E + ENDIF + +C ------------------------------------------------------- + ELSE IF (TYPE .EQ. 2) THEN +C Uson: assemble all possible columns +C ------------------------------------------------------- + +C ---------------------------------------------------- + IF (ALLROW) THEN +C no rows assembled out of this Uson yet +C ---------------------------------------------------- + +C compute the compressed column offset vector + DO 370 I = 0, FDEGC-1 + ROW = LUI (FLUCP+I) + WM (I+1) = WIR (ROW) +370 CONTINUE + + DO 390 J = 0, FDEGR-1 + COL = LUI (FLURP+J) + IF (COL .GT. 0) THEN + IF (WIC (COL) .GE. 0) THEN + XDP = FFXP + WIC (COL) +CFPP$ NODEPCHK L + DO 380 I = 0, FDEGC-1 + XX (XDP + WM (I+1)) = + $ XX (XDP + WM (I+1)) + + $ XX (FXP + J*FDIMC + I) +380 CONTINUE +C flag this column as assembled + LUI (FLURP+J) = -COL + ENDIF + ENDIF +390 CONTINUE + +C ---------------------------------------------------- + ELSE +C some rows already assembled out of this Uson +C ---------------------------------------------------- + +C compute the compressed column offset vector + DEGC = 0 + DO 400 I = 0, FDEGC-1 + ROW = LUI (FLUCP+I) + IF (ROW .GT. 0) THEN + DEGC = DEGC + 1 + WJ (DEGC) = I + WM (DEGC) = WIR (ROW) + ENDIF +400 CONTINUE + + DO 420 J = 0, FDEGR-1 + COL = LUI (FLURP+J) + IF (COL .GT. 0) THEN + IF (WIC (COL) .GE. 0) THEN + XDP = FFXP + WIC (COL) +CFPP$ NODEPCHK L + DO 410 I = 1, DEGC + XX (XDP + WM (I)) = + $ XX (XDP + WM (I)) + + $ XX (FXP + J*FDIMC + WJ (I)) +410 CONTINUE +C flag this column as assembled + LUI (FLURP+J) = -COL + ENDIF + ENDIF +420 CONTINUE + + ENDIF + +C flag this element as missing some columns + LUI (FLUIP+2) = -FDEGR + +C ------------------------------------------------------- + ELSE +C Lson: assemble all possible rows +C ------------------------------------------------------- + +C compute the compressed column offset vector + DEGC = 0 + DO 430 I = 0, FDEGC-1 + ROW = LUI (FLUCP+I) + IF (ROW .GT. 0) THEN + IF (WIR (ROW) .GE. 0) THEN +C this row will be assembled in loop below + DEGC = DEGC + 1 + WJ (DEGC) = I + WM (DEGC) = WIR (ROW) +C flag this row as assembled + LUI (FLUCP+I) = -ROW + ENDIF + ENDIF +430 CONTINUE + +C ---------------------------------------------------- + IF (ALLCOL) THEN +C no columns assembled out of this Lson yet +C ---------------------------------------------------- + + DO 450 J = 0, FDEGR-1 + COL = LUI (FLURP+J) + XDP = FFXP + WIC (COL) +CFPP$ NODEPCHK L + DO 440 I = 1, DEGC + XX (XDP + WM (I)) = + $ XX (XDP + WM (I)) + + $ XX (FXP + J*FDIMC + WJ (I)) +440 CONTINUE +450 CONTINUE + +C ---------------------------------------------------- + ELSE +C some columns already assembled out of this Lson +C ---------------------------------------------------- + + DO 470 J = 0, FDEGR-1 + COL = LUI (FLURP+J) + IF (COL .GT. 0) THEN + XDP = FFXP + WIC (COL) +CFPP$ NODEPCHK L + DO 460 I = 1, DEGC + XX (XDP + WM (I)) = + $ XX (XDP + WM (I)) + + $ XX (FXP + J*FDIMC + WJ (I)) +460 CONTINUE + ENDIF +470 CONTINUE + + ENDIF + +C flag this element as missing some rows + LUI (FLUIP+3) = -FDEGC + + ENDIF + + ENDIF + +480 CONTINUE + +C======================================================================= +C Done assemblying sons into the frontal matrix ] +C======================================================================= + +C======================================================================= +C Factorize the frontal matrix [ +C======================================================================= + + K0 = 0 + FFLEFR = LDIMR + FFLEFC = LDIMC + FFCP = FFXP + FFLEFR * FFDIMC + FFRP = FFXP + FFLEFC + FFPP = FFXP + FFLEFC + FFLEFR * FFDIMC + + DO 500 K = 1, LUK + +C ---------------------------------------------------------- +C compute kth column of U1, and update pivot column +C ---------------------------------------------------------- + + IF (K-K0-2 .GT. 0) THEN +C u1 = L1 \ u1. Note that L1 transpose is stored, and +C that u1 is stored with rows in reverse order. + CALL DTRSV ('U', 'N', 'U', K-K0-1, + $ XX (FFPP ), FFDIMC, + $ XX (FFPP - FFDIMC), 1) + RINFO (5) = RINFO (5) + (K-K0-2)*(K-K0-1) + ENDIF + IF (K-K0-1 .GT. 0) THEN +C l1 = l1 - L2*u1 + CALL DGEMV ('N', FFLEFC, K-K0-1, + $ -ONE, XX (FFCP ), FFDIMC, + $ XX (FFPP - FFDIMC), 1, + $ ONE, XX (FFCP - FFDIMC), 1) + RINFO (5) = RINFO (5) + 2*FFLEFC*(K-K0-1) + ENDIF + + FFCP = FFCP - FFDIMC + FFRP = FFRP - 1 + FFPP = FFPP - FFDIMC - 1 + FFLEFR = FFLEFR - 1 + FFLEFC = FFLEFC - 1 + +C ---------------------------------------------------------- +C divide pivot column by pivot +C ---------------------------------------------------------- + +C k-th pivot in frontal matrix located in XX (ffpp) + X = XX (FFPP) + IF (ABS (X) .EQ. ZERO) THEN +C error return, if pivot order from MA38AD not acceptable + GO TO 9010 + ENDIF + X = ONE / X + DO 490 P = FFCP, FFCP + FFLEFC - 1 + XX (P) = XX (P) * X +490 CONTINUE +C count this as a call to the Level-1 BLAS: + RINFO (4) = RINFO (4) + FFLEFC + INFO (17) = INFO (17) + 1 + +C ---------------------------------------------------------- +C compute U1 (k0+1..k, k..ldimc) and +C update contribution block: rank-nb, or if last pivot +C ---------------------------------------------------------- + + IF (K-K0 .GE. NB .OR. K .EQ. LUK) THEN + CALL DTRSM ('L', 'U', 'N', 'U', K-K0, FFLEFR, ONE, + $ XX (FFPP), FFDIMC, + $ XX (FFRP), FFDIMC) + CALL DGEMM ('N', 'N', FFLEFC, FFLEFR, K-K0, + $ -ONE, XX (FFCP ), FFDIMC, + $ XX (FFRP ), FFDIMC, + $ ONE, XX (FFXP), FFDIMC) + RINFO (6) = RINFO (6) + FFLEFR*(K-K0-1)*(K-K0) + $ + 2*FFLEFC*FFLEFR*(K-K0) + K0 = K + ENDIF + +500 CONTINUE + +C======================================================================= +C Done factorizing the frontal matrix ] +C======================================================================= + +C======================================================================= +C Save the new LU arrowhead [ +C======================================================================= + +C allocate permanent space for the LU arrowhead + XS = LUK*LUDEGC + LUK*LUDEGR + LUK*LUK + + IF (XS .GT. XTAIL-XHEAD) THEN + INFO (15) = INFO (15) + 1 + CALL MA38OD (XX, XSIZE, XHEAD, XUSE, + $ LUI, FRDIMC, FRXP, FRNEXT, FRPREV, NLU, LUP, + $ FFXP, FFSIZE, PFREE, XFREE) + ENDIF + + XTAIL = XTAIL - XS + LUXP = XTAIL + XUSE = XUSE + XS + XNEED = XNEED + XS + XRUSE = XRUSE + XS + XRMAX = MAX (XRMAX, XRUSE) + INFO (20) = MAX (INFO (20), XUSE) + INFO (21) = MAX (INFO (21), XNEED) + IF (XHEAD .GT. XTAIL) THEN +C error return, if not enough real memory: + GO TO 9000 + ENDIF + +C save the scalar data of the LU arrowhead + LUI (LUIP) = LUXP + +C save column pattern (it may have been rearranged) + DO 510 I = 0, LUDEGC-1 + LUI (LUCP+I) = WPC (I+1) +510 CONTINUE + +C save row pattern (it may have been rearranged) + DO 520 I = 0, LUDEGR-1 + LUI (LURP+I) = WPR (I+1) +520 CONTINUE + +C move the L1,U1 matrix, compressing the dimension from +C ffdimc to ldimc. The LU arrowhead grows on top of stack. + XP = FFXP + (LDIMR-1)*FFDIMC + LDIMC-1 + DO 540 J = 0, LUK-1 +CFPP$ NODEPCHK L + DO 530 I = 0, LUK-1 + XX (LUXP + J*LDIMC + I) = XX (XP - J*FFDIMC - I) +530 CONTINUE +540 CONTINUE + +C move L2 matrix, compressing dimension from ffdimc to ldimc + IF (LUDEGC .NE. 0) THEN + LXP = LUXP + LUK + XP = FFXP + (LDIMR-1)*FFDIMC + DO 560 J = 0, LUK-1 +CFPP$ NODEPCHK L + DO 550 I = 0, LUDEGC-1 + XX (LXP + J*LDIMC + I) = XX (XP - J*FFDIMC + I) +550 CONTINUE +560 CONTINUE + ENDIF + +C move the U2 block. + IF (LUDEGR .NE. 0) THEN + UXP = LUXP + LUK * LDIMC + XP = FFXP + LDIMC-1 + DO 580 J = 0, LUDEGR-1 +CFPP$ NODEPCHK L + DO 570 I = 0, LUK-1 + XX (UXP + J*LUK + I) = XX (XP + J*FFDIMC - I) +570 CONTINUE +580 CONTINUE + ENDIF + +C one more LU arrowhead has been refactorized + NZU = (LUK*(LUK-1)/2) + LUK*LUDEGC + NZL = (LUK*(LUK-1)/2) + LUK*LUDEGR + INFO (10) = INFO (10) + NZL + INFO (11) = INFO (11) + NZU + +C ------------------------------------------------------------- +C clear the pivot row and column offsets +C ------------------------------------------------------------- + + DO 590 PIVOT = NPIV + 1, NPIV + LUK + WIR (PIVOT) = -1 + WIC (PIVOT) = -1 +590 CONTINUE + NPIV = NPIV + LUK + +C======================================================================= +C Done saving the new LU arrowhead ] +C======================================================================= + +600 CONTINUE + +C======================================================================= +C Factorization complete ] +C======================================================================= + +C======================================================================= +C Wrap-up: store LU factors in their final form +C======================================================================= + +C ---------------------------------------------------------------- +C Flag remaining arrowheads as invalid entries, if prior matrix +C was singular. Print them if requested. +C ---------------------------------------------------------------- + + IF (NPIV .LT. N) THEN + IF (PR3) THEN + DO 620 I = NPIV+1, N + DO 610 P = CP (I+1), CP (I) - 1 + J = ARI (P) + IF (J .GT. 0) THEN +C a diagonal entry, or lower triangular entry +C get original row and column index + ROW = RPERM (J) + COL = CPERM (I) + ELSE +C an upper triangular entry +C get original row and column index + ROW = RPERM (I) + COL = CPERM (-J) + ENDIF + CALL MA38ZD (2, 95, ROW, COL, XX(P), IO) +610 CONTINUE +620 CONTINUE + ENDIF + NOUTSD = NOUTSD + (CP (NPIV+1) - CP (N+1)) + ENDIF + +C ---------------------------------------------------------------- +C deallocate all remaining input arrowheads and frontal matrices +C ---------------------------------------------------------------- + + IF (FFSIZE .NE. 0) THEN + INFO (13) = INFO (13) + 1 + ENDIF + XUSE = XUSE - (XHEAD - CP (N+1)) + XNEED = XUSE + XHEAD = CP (N+1) + + IF (NLU .EQ. 0) THEN +C LU factors are completely empty (A = 0). +C Add one real, to simplify rest of code. +C Otherwise, some arrays in MA38BD or MA38CD would have +C zero size, which can cause an address fault. + XTAIL = XSIZE + XUSE = XUSE + 1 + XRUSE = XUSE + XNEED = XUSE + INFO (20) = MAX (INFO (20), XUSE) + INFO (21) = MAX (INFO (21), XNEED) + ENDIF + + IF (XHEAD .LE. XTAIL) THEN + +C ------------------------------------------------------------- +C sufficient memory to complete the factorization +C ------------------------------------------------------------- + + IF (NLU .EQ. 0) THEN +C zero the dummy entry, although it won't be accessed: + XX (XTAIL) = ZERO + ENDIF + +C ------------------------------------------------------------- +C update pointers in LU factors +C ------------------------------------------------------------- + + DO 630 S = 1, NLU + LUIP = LUP (S) + LUXP = LUI (LUIP) + LUI (LUIP) = LUXP - XTAIL + 1 +630 CONTINUE + +C ------------------------------------------------------------- +C get memory usage estimate for next call to MA38BD +C ------------------------------------------------------------- + + XRUSE = XUSE + XRMAX = MAX (XRMAX, XRUSE) + RETURN + + ENDIF + +C======================================================================= +C Error conditions +C======================================================================= + +C error return label: +9000 CONTINUE +C out of real memory + CALL MA38ND (2, ICNTL, INFO, -4, INFO (21)) + RETURN + +C error return label: +9010 CONTINUE +C original pivot order computed by MA38AD is no longer acceptable + CALL MA38ND (2, ICNTL, INFO, -6, 0) + RETURN + END + + SUBROUTINE MA38SD (NLU, N, LUP, LUI, LUX, X, W) + INTEGER NLU, N, LUP(NLU), LUI(*) + DOUBLE PRECISION LUX(*), X(N), W(N) + +C=== MA38SD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C solves U'x = b, where U is the upper triangular factor of a matrix +C (if BTF not used) or a single diagonal block (if BTF is used). +C B is overwritten with the solution X. + +C======================================================================= +C INPUT: +C======================================================================= +C +C nlu: number of LU arrowheads in the LU factors +C npiv: number of pivots found (normally n) +C n: order of matrix +C LUp (1..nlu): pointer to LU arrowheads in LUi +C LUi ( ... ): integer values of LU arrowheads +C LUx ( ... ): real values of LU arroheads +C X (1..n): the right-hand-side + +C======================================================================= +C WORKSPACE: +C======================================================================= +C +C W (1..n) + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C X (1..n): the solution to U'x=b + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38JD +C subroutines called: DTRSV, DGEMV + EXTERNAL DTRSV, DGEMV + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER I, K, S, LUIP, LUXP, LUK, LUDEGR, LUDEGC, LURP, UXP, + $ LUCP, ROW + DOUBLE PRECISION + $ ONE + PARAMETER (ONE = 1.0D0) + +C s: an element, or LU arrowhead +C k: kth pivot +C i: ith column in U2' array in element s +C luip: s is in LUi (luip...) +C luxp: real part of s is in LUx (luxp...) +C luk: number of pivots in s +C ludegc: column degree of non-pivotal part of s +C ludegr: row degree of non-pivotal part of s +C lucp: pattern of column of s in LUi (lucp...lucp+ludegc-1) +C lurp: pattern of row of s in LUi (lurp...lurp+ludegr-1) +C uxp: the luk-by-ludegr U2 block of s is in LUx (uxp...) +C row: row index + +C======================================================================= +C EXECUTABLE STATMENTS: +C======================================================================= + + K = 0 + DO 40 S = 1, NLU + +C ------------------------------------------------------------- +C get s-th LU arrowhead (s = 1..nlu, in pivotal order) +C ------------------------------------------------------------- + + LUIP = LUP (S) + LUXP = LUI (LUIP) + LUK = LUI (LUIP+1) + LUDEGR = LUI (LUIP+2) + LUDEGC = LUI (LUIP+3) + LUCP = (LUIP + 7) + LURP = LUCP + LUDEGC + + IF (LUK .EQ. 1) THEN + +C ---------------------------------------------------------- +C only one pivot, stride-1 sparse saxpy +C ---------------------------------------------------------- + + K = K + 1 +C divide by pivot, U (k,k): LUx (luxp) + X (K) = X (K) / LUX (LUXP) + UXP = LUXP + LUDEGC + 1 +CFPP$ NODEPCHK L + DO 10 I = 1, LUDEGR + ROW = LUI (LURP+I-1) +C col: k, U (row,col): LUx (uxp+i-1) + X (ROW) = X (ROW) - LUX (UXP+I-1) * X (K) +10 CONTINUE + + ELSE + +C ---------------------------------------------------------- +C more than one pivot +C ---------------------------------------------------------- + + UXP = LUXP + LUK * (LUDEGC + LUK) + CALL DTRSV ('U', 'T', 'N', LUK, + $ LUX (LUXP), LUDEGC + LUK, X (K+1), 1) + DO 20 I = 1, LUDEGR + ROW = LUI (LURP+I-1) + W (I) = X (ROW) +20 CONTINUE + IF(LUDEGR.GT.0)CALL DGEMV ('T', LUK, LUDEGR, -ONE, + $ LUX (UXP), LUK, X (K+1), 1, ONE, W, 1) + DO 30 I = 1, LUDEGR + ROW = LUI (LURP+I-1) + X (ROW) = W (I) +30 CONTINUE + K = K + LUK + + ENDIF + +40 CONTINUE + RETURN + END + + SUBROUTINE MA38TD (NLU, NPIV, N, LUP, LUI, LUX, X, W) + INTEGER NLU, NPIV, N, LUP(NLU), LUI(*) + DOUBLE PRECISION LUX(*), X(N), W(N) + +C=== MA38TD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C solves L'x = b, where L is the lower triangular factor of a matrix +C (if BTF not used) or a single diagonal block (if BTF is used). +C B is overwritten with the solution X. + +C======================================================================= +C INPUT: +C======================================================================= +C +C nlu: number of LU arrowheads in the LU factors +C npiv: number of pivots found (normally n) +C n: order of matrix +C LUp (1..nlu): pointer to LU arrowheads in LUi +C LUi ( ... ): integer values of LU arrowheads +C LUx ( ... ): real values of LU arroheads +C X (1..n): the right-hand-side + +C======================================================================= +C WORKSPACE: +C======================================================================= +C +C W (1..n): + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C X (1..n): the solution to L'x=b + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38JD +C subroutines called: DTRSV, DGEMV + EXTERNAL DTRSV, DGEMV + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER J, K, S, LUIP, LUXP, LUK, LUDEGC, LUCP, LXP, COL + DOUBLE PRECISION + $ ONE + PARAMETER (ONE = 1.0D0) + +C s: an element, or LU arrowhead +C k: kth pivot +C j: jth column in L2' array in element s +C luip: s is in LUi (luip...) +C luxp: real part of s is in LUx (luxp...) +C luk: number of pivots in s +C ludegc: column degree of non-pivotal part of s +C lucp: pattern of column of s in LUi (lucp...lucp+ludegc-1) +C lxp: the ludegc-by-luk L2 block of s is in LUx (lxp...) +C col: column index + +C======================================================================= +C EXECUTABLE STATMENTS: +C======================================================================= + + K = NPIV + DO 30 S = NLU, 1, -1 + +C ------------------------------------------------------------- +C get s-th LU arrowhead (s = nlu..1, in reverse pivotal order) +C ------------------------------------------------------------- + + LUIP = LUP (S) + LUXP = LUI (LUIP) + LUK = LUI (LUIP+1) + LUDEGC = LUI (LUIP+3) + LUCP = (LUIP + 7) + LXP = LUXP + LUK + + IF (LUK .EQ. 1) THEN + +C ---------------------------------------------------------- +C only one pivot, stride-1 sparse dot product +C ---------------------------------------------------------- + +CFPP$ NODEPCHK L + DO 10 J = 1, LUDEGC + COL = LUI (LUCP+J-1) +C row: k, U (row,col): LUx (lxp+j-1) + X (K) = X (K) - LUX (LXP+J-1) * X (COL) +10 CONTINUE +C L (k,k) is one + K = K - 1 + + ELSE + +C ---------------------------------------------------------- +C more than one pivot +C ---------------------------------------------------------- + + K = K - LUK + DO 20 J = 1, LUDEGC + COL = LUI (LUCP+J-1) + W (J) = X (COL) +20 CONTINUE + CALL DGEMV ('T', LUDEGC, LUK, -ONE, + $ LUX (LXP), LUDEGC + LUK, W, 1, ONE, X (K+1), 1) + CALL DTRSV ('L', 'T', 'U', LUK, + $ LUX (LUXP), LUDEGC + LUK, X (K+1), 1) + + ENDIF + +30 CONTINUE + RETURN + END + + SUBROUTINE MA38UD (NLU, NPIV, N, LUP, LUI, LUX, X, W) + INTEGER NLU, NPIV, N, LUP(NLU), LUI(*) + DOUBLE PRECISION LUX(*), X(N), W(N) + +C=== MA38UD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C solves Ux = b, where U is the upper triangular factor of a matrix +C (if BTF not used) or a single diagonal block (if BTF is used). +C B is overwritten with the solution X. + +C======================================================================= +C INPUT: +C======================================================================= +C +C nlu: number of LU arrowheads in the LU factors +C npiv: number of pivots found (normally n) +C n: order of matrix +C LUp (1..nlu): pointer to LU arrowheads in LUi +C LUi ( ... ): integer values of LU arrowheads +C LUx ( ... ): real values of LU arroheads +C X (1..n): the right-hand-side + +C======================================================================= +C WORKSPACE: +C======================================================================= +C +C W (1..n) + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C X (1..n): the solution to Ux=b + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutine: MA38JD +C subroutines called: DTRSV, DGEMV + EXTERNAL DTRSV, DGEMV + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + INTEGER J, K, S, LUIP, LUXP, LUK, LUDEGR, LUDEGC, LURP, UXP, + $ LUCP, COL + DOUBLE PRECISION + $ ONE + PARAMETER (ONE = 1.0D0) + +C s: an element, or LU arrowhead +C k: kth pivot +C j: jth column in U2 array in element s +C luip: s is in LUi (luip...) +C luxp: real part of s is in LUx (luxp...) +C luk: number of pivots in s +C ludegc: column degree of non-pivotal part of s +C ludegr: row degree of non-pivotal part of s +C lucp: pattern of column of s in LUi (lucp...lucp+ludegc-1) +C lurp: pattern of row of s in LUi (lurp...lurp+ludegr-1) +C uxp: the luk-by-ludegr U2 block of s is in LUx (uxp...) +C col: column index + +C======================================================================= +C EXECUTABLE STATMENTS: +C======================================================================= + + K = NPIV + DO 30 S = NLU, 1, -1 + +C ------------------------------------------------------------- +C get s-th LU arrowhead (s = nlu..1, in reverse pivotal order) +C ------------------------------------------------------------- + + LUIP = LUP (S) + LUXP = LUI (LUIP) + LUK = LUI (LUIP+1) + LUDEGR = LUI (LUIP+2) + LUDEGC = LUI (LUIP+3) + LUCP = (LUIP + 7) + LURP = LUCP + LUDEGC + UXP = LUXP + LUK * (LUDEGC + LUK) + + IF (LUK .EQ. 1) THEN + +C ---------------------------------------------------------- +C only one pivot, stride-1 sparse dot product +C ---------------------------------------------------------- + +CFPP$ NODEPCHK L + DO 10 J = 1, LUDEGR + COL = LUI (LURP+J-1) +C row: k, U (row,col): LUx (uxp+j-1) + X (K) = X (K) - LUX (UXP+J-1) * X (COL) +10 CONTINUE +C divide by pivot, U (k,k): LUx (luxp) + X (K) = X (K) / LUX (LUXP) + K = K - 1 + + ELSE + +C ---------------------------------------------------------- +C more than one pivot +C ---------------------------------------------------------- + + K = K - LUK + DO 20 J = 1, LUDEGR + COL = LUI (LURP+J-1) + W (J) = X (COL) +20 CONTINUE + IF(LUDEGR.GT.0) CALL DGEMV ('N', LUK, LUDEGR, -ONE, + $ LUX (UXP), LUK, W, 1, ONE, X (K+1), 1) + CALL DTRSV ('U', 'N', 'N', LUK, + $ LUX (LUXP), LUDEGC + LUK, X (K+1), 1) + + ENDIF + +30 CONTINUE + RETURN + END + + SUBROUTINE MA38YD (WHO, WHERE, + * N, NE, JOB, TRANS, LVALUE, LINDEX, VALUE, + * INDEX, KEEP, CNTL, ICNTL, INFO, RINFO, + * B, X, LX, W, LW) + INTEGER WHO, WHERE, N, NE, JOB, LVALUE, LINDEX, INDEX(LINDEX), + * KEEP(20), ICNTL(20), INFO(40), LX, LW + DOUBLE PRECISION VALUE(LVALUE), CNTL(10), RINFO(20), B(LX), + * X(LX), W(LW) + LOGICAL TRANS + +C=== MA38YD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE. + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C print input/output arguments for MA38AD, MA38BD, and MA38CD + +C======================================================================= +C INSTALLATION NOTE: +C======================================================================= +C +C This routine can be deleted on installation (replaced with a dummy +C routine that just returns without printing) in order to completely +C disable the printing of all input/output parameters. To completely +C disable all I/O, you can also replace the MA38ZD routine with a +C dummy subroutine. If you make this modification, please do +C not delete any original code - just comment it out instead. Add a +C comment and date to your modifications. + +C======================================================================= +C INPUT: +C======================================================================= +C +C who: what routine called MA38YD: +C 1: MA38AD, 2: MA38BD, 3: MA38CD +C where: called from where: +C 1: entry of routine, else exit of routine +C Icntl (3): if < 3 then print nothing, if 3 then print +C terse output, if 4 print info and matrix +C values. If 5, print everything. +C Icntl (2): I/O unit on which to print. No printing +C occurs if < 0. +C +C Parameters to print, see MA38AD, MA38BD, or MA38CD for +C descriptions: +C +C n, ne, job, trans, lvalue, lindex, Value, Index, Keep, +C Icntl, Info, Rinfo, B, X, lx, W, lw + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C on Icntl (2) I/O unit only + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutines: MA38AD, MA38BD, MA38CD +C functions called: MIN + INTRINSIC MIN + +C======================================================================= +C LOCAL SCALARS: +C======================================================================= + + LOGICAL TRANSA, TRANSC, PRLU, BADLU, SGLTON, PRESRV, SYMBOL + INTEGER IO, PRL, PRN, K, LUI1, LUI2, LUX1, LUX2, ROW, COL, + $ FACNE, FACN, NZ, FACJOB, NBLKS, NZOFF, FACTRA, CPERMP, + $ RPERMP, APP, AXP, AIP, OFFIP, OFFXP, LUBLPP, OFFPP, + $ BLKPP, P1, P2, P, BLK, K1, K2, KN, LUIIP, LUXXP, NPIV, + $ NLU, E, LUK, LUPP, LUIP, LUXP, LUDEGR, LUDEGC, LUNSON, + $ LUSONP, LUCP, LURP, I, J, NZCOL, NZROW, UXP, SON, + $ PRMAX, LUDIMR, LUDIMC, MAXDR, MAXDC, LUIR1, IP1, IP2, + $ XP1 + DOUBLE PRECISION + $ ONE + PARAMETER (PRMAX = 10, ONE = 1.0D0) + +C Printing control: +C ----------------- +C io: I/O unit for diagnostic messages +C prl: printing level +C prn: number of entries printed so far +C prmax: maximum number of entries to print if prl = 3 +C prlu: true if printing LU factors +C +C Location and status of LU factors: +C ---------------------------------- +C transc: TRANSC argument in MA38CD +C transa: TRANSA argument in MA38AD or MA38BD when matrix factorized +C badlu: true if LU factors uncomputed or corrupted +C presrv: true if original matrix was preserved when factorized +C symbol: true if only symbolic part of LU factors needed on input +C lui1: integer part of LU factors start in Index (lui1...) +C luir1: Index (luir1 ... lui2) is needed for a call to MA38BD +C lui2: integer part of LU factors end in Index (..lui2) +C lux1: real part of LU factors start in Value (lux1...) +C lux2: real part of LU factors end in Value (...lux1) +C ip1: pointer into leading part of LU factors in Index +C ip2: pointer into trailing part of LU factors in Index +C xp1: pointer into leading part of LU factors in Value +C +C Arrays and scalars allocated in LU factors (in order): +C ------------------------------------------------------ +C app: Ap (1..n+1) array located in Index (app...app+n) +C axp: Ax (1..nz) array located in Value (axp...axp+nz-1) +C aip: Ai (1..nz) array located in Index (aip...aip+nz-1) +C offip: Offi (1..nzoff) array loc. in Index (offip...offip+nzoff-1) +C offxp: Offx (1..nzoff) array loc. in Value (offxp...offxp+nzoff-1) +C ... LU factors of each diagonal block located here +C lublpp: LUblkp (1..nblks) array in Index (lublpp..lublpp+nblks-1) +C blkpp: Blkp (1..nblks+1) array loc. in Index (blkpp...blkpp+nblks) +C offpp: Offp (1..n+1) array located in Index (offpp...offpp+n) +C cpermp: Cperm (1..n) array located in Index (cpermp...cpermp+n-1) +C rpermp: Rperm (1..n) array located in Index (rpermp...rpermp+n-1) +C ... seven scalars in Index (lui2-6...lui2): +C factra: 0/1 if TRANSA argument was false/true in MA38AD or MA38BD +C nzoff: number of entries in off-diagonal part +C nblks: number of diagonal blocks +C facjob: JOB argument in MA38AD or MA38BD when matrix factorized +C nz: entries in A +C facn: N argument in MA38AD or MA38BD when matrix factorized +C facne: NE argument in MA38AD or MA38BD when matrix factorized +C +C A single diagonal block and its LU factors: +C ------------------------------------------- +C blk: current diagonal block +C k1,k2: current diagonal is A (k1..k2, k1..k2) +C kn: order of current diagonal block (= k2-k1+1) +C sglton: true if current diagonal block is 1-by-1 (a singleton) +C luiip: LU factors of a diagonal block start in Index (luiip...) +C luxxp: LU factors of a diagonal block start in Value (luxxp...) +C npiv: number of pivots in a diagonal block (0 <= npiv <= kn) +C nlu: number of elements in a diagonal block +C lupp: LUp (1..nlu) array located in Index (lupp...lupp+nlu-1) +C +C An element in the LU factors of a single diagonal block: +C -------------------------------------------------------- +C e: element +C luk: number of pivots in element e +C luip: integer part of element is in Index (luip...) +C luxp: real part of element e is in Value (luxp...) +C ludegr: row degree (number of columns) of U2 block in element e +C ludegc: column degree (number of rows) of L2 block in element e +C lunson: number of sons of element e in the assembly DAG +C lusonp: list of sons of element e in Index(lusonp...lusonp+lunson-1) +C lucp: column pattern (row indices) of L2 block in Index (lucp..) +C lurp: row pattern (column indices) of U2 block in Index (lurp..) +C nzcol: entries in a column of L, including unit diagonal +C nzrow: entries in a row of U, including non-unit diagonal +C uxp: a row of the U2 block located in Value (uxp...) +C son: a son of the element e +C ludimr: row dimension (number of columns) in frontal matrix +C ludimc: column dimension (number of rows) in frontal matrix +C maxdr: largest ludimr for this block +C maxdc: largest ludimc for this block +C +C Other: +C ------ +C row: row index +C col: column index +C k: kth pivot, and general loop index +C i, j: loop indices +C p: pointer +C p1: column of A starts Ai/Ax (p1...), or row Offi/x (p1...) +C p2: column of A ends in Ai/Ax (...p2), or row Offi/x (...p2) + +C======================================================================= +C EXECUTABLE STATEMENTS: +C if (printing disabled on installation) return +C======================================================================= + +C----------------------------------------------------------------------- +C get printing control parameters +C----------------------------------------------------------------------- + + IO = ICNTL(2) + PRL = ICNTL(3) + IF (PRL .LT. 3 .OR. IO .LT. 0) THEN +C printing has not been requested + RETURN + ENDIF + +C----------------------------------------------------------------------- +C who is this, and where. Determine if LU factors are to be printed +C----------------------------------------------------------------------- + + IF (WHO .EQ. 1) THEN + IF (WHERE .EQ. 1) THEN + WRITE (IO, 6) 'MA38AD input:' + PRLU = .FALSE. + ELSE + WRITE (IO, 6) 'MA38AD output:' + PRLU = .TRUE. + ENDIF + ELSE IF (WHO .EQ. 2) THEN + IF (WHERE .EQ. 1) THEN + WRITE (IO, 6) 'MA38BD input:' + PRLU = .TRUE. + ELSE + WRITE (IO, 6) 'MA38BD output:' + PRLU = .TRUE. + ENDIF + ELSE IF (WHO .EQ. 3) THEN + IF (WHERE .EQ. 1) THEN + WRITE (IO, 6) 'MA38CD input:' + PRLU = .TRUE. + ELSE + WRITE (IO, 6) 'MA38CD output:' + PRLU = .FALSE. + ENDIF + ENDIF + +C----------------------------------------------------------------------- +C print scalar input arguments: n, ne, job, trans, lvalue, lindex +C----------------------------------------------------------------------- + + IF (WHERE .EQ. 1) THEN + WRITE (IO, 1) 'Scalar arguments:' + WRITE (IO, 1) ' N: ', N, ' : order of matrix A' + IF (WHO .EQ. 3) THEN +C MA38CD: +C was A or A^T factorized? + LUI2 = KEEP (5) + TRANSA = .FALSE. + IF (LUI2-6 .GE. 1 .AND. LUI2-6 .LE. LINDEX) THEN + TRANSA = INDEX (LUI2-6) .NE. 0 + ENDIF + TRANSC = TRANS + IF (.NOT. TRANSC) THEN + IF (JOB .EQ. 1) THEN + WRITE (IO, 1) ' JOB: ', JOB, + $ ' : solve P''Lx=b' + ELSE IF (JOB .EQ. 2) THEN + WRITE (IO, 1) ' JOB: ', JOB, + $ ' : solve UQ''x=b' + ELSE IF (.NOT. TRANSA) THEN + WRITE (IO, 1) ' JOB: ', JOB, + $ ' : solve Ax=b (PAQ=LU was factorized)' + ELSE + WRITE (IO, 1) ' JOB: ', JOB, + $ ' : solve A''x=b (PA''Q=LU was factorized)' + ENDIF + ELSE + IF (JOB .EQ. 1) THEN + WRITE (IO, 1) ' JOB: ', JOB, + $ ' : solve L''Px=b' + ELSE IF (JOB .EQ. 2) THEN + WRITE (IO, 1) ' JOB: ', JOB, + $ ' : solve QU''x=b' + ELSE IF (.NOT. TRANSA) THEN + WRITE (IO, 1) ' JOB: ', JOB, + $ ' : solve A''x=b (PAQ=LU was factorized)' + ELSE + WRITE (IO, 1) ' JOB: ', JOB, + $ ' : solve Ax=b (PA''Q=LU was factorized)' + ENDIF + ENDIF + IF (TRANSC) THEN + WRITE (IO, 1) + $ ' TRANSC: .true. : see JOB above ' + ELSE + WRITE (IO, 1) + $ ' TRANSC: .false. : see JOB above ' + ENDIF + ELSE +C MA38AD or MA38BD: + WRITE (IO, 1) ' NE: ', NE, + $ ' : entries in matrix A' + IF (JOB .EQ. 1) THEN + WRITE (IO, 1) ' JOB: ', JOB, + $ ' : matrix A preserved' + ELSE + WRITE (IO, 1) ' JOB: ', JOB, + $ ' : matrix A not preserved' + ENDIF + TRANSA = TRANS + IF (TRANSA) THEN + WRITE (IO, 1) + $ ' TRANSA: .true. : factorize A transpose' + ELSE + WRITE (IO, 1) + $ ' TRANSA: .false. : factorize A' + ENDIF + ENDIF + WRITE (IO, 1) ' LVALUE: ',LVALUE, + $ ' : size of VALUE array' + WRITE (IO, 1) ' LINDEX: ',LINDEX, + $ ' : size of INDEX array' + ENDIF + +C----------------------------------------------------------------------- +C print control parameters: Icntl, Cntl, and Keep (6..8) +C----------------------------------------------------------------------- + + IF (WHERE .EQ. 1) THEN + WRITE (IO, 1) + $ 'Control parameters, normally initialized by MA38ID:' + WRITE (IO, 1) ' ICNTL (1): ', ICNTL (1), + $ ' : I/O unit for error and warning messages' + WRITE (IO, 1) ' ICNTL (2): ', IO, + $ ' : I/O unit for diagnostics' + WRITE (IO, 1) ' ICNTL (3): ', PRL, + $ ' : printing control' + IF (WHO .EQ. 1) THEN + IF (ICNTL (4) .EQ. 1) THEN + WRITE (IO, 1) ' ICNTL (4): ', ICNTL (4), + $ ' : use block triangular form (BTF)' + ELSE + WRITE (IO, 1) ' ICNTL (4): ', ICNTL (4), + $ ' : do not permute to block triangular form (BTF)' + ENDIF + WRITE (IO, 1) ' ICNTL (5): ', ICNTL (5), + $ ' : columns examined during pivot search' + IF (ICNTL (6) .NE. 0) THEN + WRITE (IO, 1) ' ICNTL (6): ', ICNTL (6), + $ ' : preserve symmetry' + ELSE + WRITE (IO, 1) ' ICNTL (6): ', ICNTL (6), + $ ' : do not preserve symmetry' + ENDIF + ENDIF + IF (WHO .NE. 3) THEN + WRITE (IO, 1) ' ICNTL (7): ', ICNTL (7), + $ ' : block size for dense matrix multiply' + ELSE + WRITE (IO, 1) ' ICNTL (8): ', ICNTL (8), + $ ' : maximum number of iterative refinement steps' + ENDIF + IF (WHO .EQ. 1) THEN + WRITE (IO, 3) ' CNTL (1): ',CNTL (1), + $ ' : relative pivot tolerance' + WRITE (IO, 3) ' CNTL (2): ',CNTL (2), + $ ' : frontal matrix growth factor' + WRITE (IO, 1) ' KEEP (7): ',KEEP(7), + $ ' : dense row/col control, d1' + WRITE (IO, 1) ' KEEP (8): ',KEEP(8), + $ ' : dense row/col control, d2' + ELSE IF (WHO .EQ. 3) THEN + WRITE (IO, 3) ' CNTL (3): ',CNTL(3), + $ ' : machine epsilon' + ENDIF + ENDIF + +C----------------------------------------------------------------------- +C print the informational output +C----------------------------------------------------------------------- + + IF (WHERE .NE. 1) THEN + WRITE (IO, 1) 'Output information:' + IF (INFO (1) .LT. 0) THEN + WRITE (IO, 1) ' INFO (1): ', INFO (1), + $ ' : error occurred.' + ELSE IF (INFO (1) .GT. 0) THEN + WRITE (IO, 1) ' INFO (1): ', INFO (1), + $ ' : warning occurred' + ELSE + WRITE (IO, 1) ' INFO (1): ', INFO (1), + $ ' : no error or warning occurred' + ENDIF + IF (WHO .NE. 3) THEN + WRITE (IO, 1) ' INFO (2): ', INFO (2), + $ ' : duplicate entries in A' + WRITE (IO, 1) ' INFO (3): ', INFO (3), + $ ' : invalid entries in A (indices not in 1..N)' + WRITE (IO, 1) ' INFO (4): ', INFO (4), + $ ' : invalid entries in A (not in prior pattern)' + WRITE (IO, 1) ' INFO (5): ', INFO (5), + $ ' : entries in A after summing duplicates' + WRITE (IO, 1) + $ ' and removing invalid entries' + WRITE (IO, 1) ' INFO (6): ', INFO (6), + $ ' : entries in diagonal blocks of A' + WRITE (IO, 1) ' INFO (7): ', INFO (7), + $ ' : entries in off-diagonal blocks of A' + WRITE (IO, 1) ' INFO (8): ', INFO (8), + $ ' : 1-by-1 diagonal blocks in A' + WRITE (IO, 1) ' INFO (9): ', INFO (9), + $ ' : diagonal blocks in A (>1 only if BTF used)' + WRITE (IO, 1) ' INFO (10): ', INFO (10), + $ ' : entries below diagonal in L' + WRITE (IO, 1) ' INFO (11): ', INFO (11), + $ ' : entries above diagonal in U' + WRITE (IO, 1) ' INFO (12): ', INFO (12), + $ ' : entries in L + U + offdiagonal blocks of A' + WRITE (IO, 1) ' INFO (13): ', INFO (13), + $ ' : frontal matrices' + WRITE (IO, 1) ' INFO (14): ', INFO (14), + $ ' : integer garbage collections' + WRITE (IO, 1) ' INFO (15): ', INFO (15), + $ ' : real garbage collections' + WRITE (IO, 1) ' INFO (16): ', INFO (16), + $ ' : diagonal pivots chosen' + WRITE (IO, 1) ' INFO (17): ', INFO (17), + $ ' : numerically valid pivots found in A' + WRITE (IO, 1) ' INFO (18): ', INFO (18), + $ ' : memory used in INDEX' + WRITE (IO, 1) ' INFO (19): ', INFO (19), + $ ' : minimum memory needed in INDEX' + WRITE (IO, 1) ' INFO (20): ', INFO (20), + $ ' : memory used in VALUE' + WRITE (IO, 1) ' INFO (21): ', INFO (21), + $ ' : minimum memory needed in VALUE' + WRITE (IO, 1) ' INFO (22): ', INFO (22), + $ ' : memory needed in INDEX for next call to MA38BD' + WRITE (IO, 1) ' INFO (23): ', INFO (23), + $ ' : memory needed in VALUE for next call to MA38BD' + ELSE + WRITE (IO, 1) ' INFO (24): ', INFO (24), + $ ' : steps of iterative refinement taken' + ENDIF + IF (WHO .NE. 3) THEN + WRITE (IO, 3) ' RINFO (1):', RINFO (1), + $ ' : total BLAS flop count' + WRITE (IO, 3) ' RINFO (2):', RINFO (2), + $ ' : assembly flop count' + WRITE (IO, 3) ' RINFO (3):', RINFO (3), + $ ' : pivot search flop count' + WRITE (IO, 3) ' RINFO (4):', RINFO (4), + $ ' : Level-1 BLAS flop count' + WRITE (IO, 3) ' RINFO (5):', RINFO (5), + $ ' : Level-2 BLAS flop count' + WRITE (IO, 3) ' RINFO (6):', RINFO (6), + $ ' : Level-3 BLAS flop count' + ELSE IF (LW .EQ. 4*N) THEN + WRITE (IO, 3) ' RINFO (7):', RINFO (7), + $ ' : sparse error estimate omega1' + WRITE (IO, 3) ' RINFO (8):', RINFO (8), + $ ' : sparse error estimate omega2' + ENDIF + ENDIF + +C----------------------------------------------------------------------- +C print input matrix A, in triplet form, for MA38AD and MA38BD +C----------------------------------------------------------------------- + + IF (WHERE .EQ. 1 .AND. WHO .NE. 3) THEN + + IF (TRANSA) THEN + IF (PRL .GE. 5) THEN + WRITE (IO, 1) 'The input matrix A transpose:' + WRITE (IO, 1) ' VALUE (1 ... ',NE, + $ ' ): numerical values' + WRITE (IO, 1) ' INDEX (1 ... ',NE, + $ ' ): column indices' + WRITE (IO, 1) ' INDEX (',NE+1,' ... ',2*NE, + $ ' ): row indices' + ENDIF + WRITE (IO, 1) + $ 'Input matrix A transpose (entry: row, column, value):' + ELSE + IF (PRL .GE. 5) THEN + WRITE (IO, 1) 'The input matrix A:' + WRITE (IO, 1) ' VALUE (1 ... ',NE, + $ ' ): numerical values' + WRITE (IO, 1) ' INDEX (1 ... ',NE, + $ ' ): row indices' + WRITE (IO, 1) ' INDEX (',NE+1,' ... ',2*NE, + $ ' ): column indices' + ENDIF + WRITE (IO, 1) + $ 'Input matrix A (entry: row, column, value):' + ENDIF + + PRN = MIN (PRMAX, NE) + IF (PRL .GE. 4) THEN + PRN = NE + ENDIF + DO 20 K = 1, PRN + IF (TRANSA) THEN + ROW = INDEX (K+NE) + COL = INDEX (K) + ELSE + ROW = INDEX (K) + COL = INDEX (K+NE) + ENDIF + WRITE (IO, 2) K, ROW, COL, VALUE (K) +20 CONTINUE + IF (PRN .LT. NE) THEN + WRITE (IO, 7) + ENDIF + ENDIF + +C----------------------------------------------------------------------- +C print the LU factors: MA38AD output, MA38BD input/output, +C and MA38CD input +C----------------------------------------------------------------------- + + IF (PRLU .AND. INFO (1) .LT. 0) THEN + WRITE (IO, 1) + $ 'LU factors not printed because of error flag, INFO (1) =' + $ , INFO (1) + PRLU = .FALSE. + ENDIF + + IF (PRLU) THEN + +C ------------------------------------------------------------- +C description of what must be preserved between calls +C ------------------------------------------------------------- + + LUX1 = KEEP (1) + LUX2 = KEEP (2) + LUI1 = KEEP (3) + LUIR1 = KEEP (4) + LUI2 = KEEP (5) + + XP1 = LUX1 + IP1 = LUI1 + IP2 = LUI2 + +C ------------------------------------------------------------- +C on input to MA38BD, only the symbol information is used +C ------------------------------------------------------------- + + SYMBOL = WHO .EQ. 2 .AND. WHERE .EQ. 1 + + IF (PRL .GE. 5) THEN + IF (SYMBOL) THEN + WRITE (IO, 1) + $ 'KEEP (4...5) gives the location of LU factors' + WRITE (IO, 1) + $ ' which must be preserved for calls to MA38BD: ' + ELSE + WRITE (IO, 1) + $ 'KEEP (1...5) gives the location of LU factors' + WRITE (IO, 1) + $ ' which must be preserved for calls to MA38CD: ' + WRITE (IO, 1) ' VALUE ( KEEP (1): ', LUX1, + $ ' ... KEEP (2): ', LUX2,' )' + WRITE (IO, 1) ' INDEX ( KEEP (3): ', LUI1, + $ ' ... KEEP (5): ', LUI2,' )' + WRITE (IO, 1) ' and for calls to MA38BD: ' + ENDIF + WRITE (IO, 1) ' INDEX ( KEEP (4): ',LUIR1, + $ ' ... KEEP (5): ', LUI2,' )' + ENDIF + + BADLU = LUIR1 .LE. 0 .OR. LUI2-6 .LT. LUIR1 .OR. + $ LUI2 .GT. LINDEX + IF (.NOT. SYMBOL) THEN + BADLU = BADLU .OR. LUX1 .LE. 0 .OR. + $ LUX1 .GT. LUX2 .OR. LUX2 .GT. LVALUE .OR. LUI1 .LE. 0 .OR. + $ LUIR1 .LT. LUI1 .OR. LUIR1 .GT. LUI2 + ENDIF + +C ------------------------------------------------------------- +C get the 7 scalars, and location of permutation vectors +C ------------------------------------------------------------- + + IF (BADLU) THEN +C pointers are bad, so these values cannot be obtained + FACNE = 0 + FACN = 0 + NZ = 0 + FACJOB = 0 + NBLKS = 0 + NZOFF = 0 + FACTRA = 0 + ELSE + FACNE = INDEX (LUI2) + FACN = INDEX (LUI2-1) + NZ = INDEX (LUI2-2) + FACJOB = INDEX (LUI2-3) + NBLKS = INDEX (LUI2-4) + NZOFF = INDEX (LUI2-5) + FACTRA = INDEX (LUI2-6) + ENDIF + + PRESRV = FACJOB .NE. 0 + TRANSA = FACTRA .NE. 0 + RPERMP = (LUI2-6) - (FACN) + CPERMP = RPERMP - (FACN) + IP2 = CPERMP - 1 + + IF (PRL .GE. 5) THEN + IF (SYMBOL) THEN + WRITE (IO, 1) 'Layout of LU factors in INDEX:' + ELSE + WRITE (IO, 1) + $ 'Layout of LU factors in VALUE and INDEX:' + ENDIF + ENDIF + +C ------------------------------------------------------------- +C get location of preserved input matrix +C ------------------------------------------------------------- + + IF (PRESRV) THEN +C preserved column-form of original matrix + APP = IP1 + AIP = APP + (FACN+1) + IP1 = AIP + (NZ) + AXP = XP1 + XP1 = XP1 + (NZ) + IF (PRL .GE. 5 .AND. .NOT. SYMBOL) THEN + WRITE (IO, 1)' preserved copy of original matrix:' + WRITE (IO, 1)' INDEX ( ',APP,' ... ', AIP-1, + $ ' ): column pointers' + WRITE (IO, 1)' INDEX ( ',AIP,' ... ', IP1-1, + $ ' ): row indices' + WRITE (IO, 1)' VALUE ( ',AXP,' ... ', XP1-1, + $ ' ): numerical values' + ENDIF + ELSE + IF (PRL .GE. 5 .AND. .NOT. SYMBOL) THEN + WRITE (IO, 1) ' original matrix not preserved.' + ENDIF + ENDIF + + BADLU = BADLU .OR. + $ N .NE. FACN .OR. NZ .LE. 0 .OR. LUIR1 .GT. IP2 .OR. + $ NBLKS .LE. 0 .OR. NBLKS .GT. N + IF (.NOT. SYMBOL) THEN + BADLU = BADLU .OR. XP1 .GT. LUX2 .OR. NZOFF .LT. 0 + ENDIF + IF (BADLU) THEN + NBLKS = 0 + ENDIF + + IF (NBLKS .LE. 1) THEN + +C ---------------------------------------------------------- +C single block (or block triangular form not used), +C or LU factors are corrupted +C ---------------------------------------------------------- + + IF (PRL .GE. 5) THEN + WRITE (IO, 1) + $ ' collection of elements in LU factors:' + WRITE (IO, 1) ' INDEX ( ',LUIR1,' ... ', IP2, + $ ' ): integer data' + IF (.NOT. SYMBOL) THEN + WRITE (IO, 1) ' VALUE ( ',XP1,' ... ', LUX2, + $ ' ): numerical values' + ENDIF + ENDIF + + ELSE + +C ---------------------------------------------------------- +C block triangular form with more than one block +C ---------------------------------------------------------- + + OFFIP = IP1 + IP1 = IP1 + (NZOFF) + OFFXP = XP1 + XP1 = XP1 + (NZOFF) + OFFPP = CPERMP - (N+1) + BLKPP = OFFPP - (NBLKS+1) + LUBLPP = BLKPP - (NBLKS) + IP2 = LUBLPP - 1 + BADLU = BADLU .OR. LUIR1 .GT. IP2 + IF (.NOT. SYMBOL) THEN + BADLU = BADLU .OR. IP1 .GT. IP2 .OR. + $ XP1 .GT. LUX2 .OR. LUIR1 .NE. IP1 + ENDIF + + IF (PRL .GE. 5) THEN + WRITE (IO, 1) + $ ' matrix permuted to upper block triangular form.' + IF (NZOFF .NE. 0 .AND. .NOT. SYMBOL) THEN + WRITE (IO, 1)' entries not in diagonal blocks:' + WRITE (IO, 1)' INDEX ( ',OFFIP,' ... ', + $ LUIR1-1, ' ): row indices' + WRITE (IO, 1)' VALUE ( ',OFFXP,' ... ', + $ XP1-1, ' ): numerical values' + ENDIF + WRITE (IO, 1) + $ ' collection of elements in LU factors of diagonal blocks:' + IF (LUIR1 .LE. LUBLPP-1) THEN + WRITE (IO, 1) ' INDEX ( ',LUIR1,' ... ', + $ IP2, ' ): integer data' + ENDIF + IF (XP1 .LE. LUX2 .AND. .NOT. SYMBOL) THEN + WRITE (IO, 1) ' VALUE ( ',XP1,' ... ', LUX2, + $ ' ): numerical values' + ENDIF + WRITE (IO, 1) ' other block triangular data:' + WRITE (IO, 1) ' INDEX ( ',LUBLPP,' ... ', + $ BLKPP-1, ' ): pointers to block factors' + WRITE (IO, 1) ' INDEX ( ', BLKPP,' ... ', + $ OFFPP-1, ' ): index range of blocks' + IF (.NOT. SYMBOL) THEN + WRITE (IO, 1) ' INDEX ( ', OFFPP,' ... ', + $ LUI2-7,' ): off-diagonal row pointers' + ENDIF + ENDIF + + ENDIF + +C ------------------------------------------------------------- +C print location of permutation vectors and 7 scalars at tail +C ------------------------------------------------------------- + + IF (PRL .GE. 5) THEN + WRITE (IO, 1) + $ ' permutation vectors (start at KEEP(4)-2*N-6):' + WRITE (IO, 1) ' INDEX ( ',CPERMP,' ... ',RPERMP-1, + $ ' ): column permutations' + WRITE (IO, 1) ' INDEX ( ',RPERMP,' ... ',LUI2-7, + $ ' ): row permutations' + WRITE (IO, 1) ' other data in INDEX: ' + WRITE (IO, 1) ' INDEX ( ',LUI2-6,' ): ', FACTRA, + $ ' : TRANSA MA38AD/MA38BD argument' + WRITE (IO, 1) ' INDEX ( ',LUI2-5,' ): ', NZOFF, + $ ' : entries in off-diagonal part' + WRITE (IO, 1) ' INDEX ( ',LUI2-4,' ): ', NBLKS, + $ ' : number of diagonal blocks' + WRITE (IO, 1) ' INDEX ( ',LUI2-3,' ): ', FACJOB, + $ ' : JOB MA38AD/MA38BD argument' + WRITE (IO, 1) ' INDEX ( ',LUI2-2,' ): ', NZ, + $ ' : entries in original matrix' + WRITE (IO, 1) ' INDEX ( ',LUI2-1,' ): ', FACN, + $ ' : N MA38AD/MA38BD argument' + WRITE (IO, 1) ' INDEX ( ',LUI2 ,' ): ', FACNE, + $ ' : NE MA38AD/MA38BD argument' + ENDIF + + IF (.NOT. SYMBOL) THEN + BADLU = BADLU .OR. IP1 .NE. LUIR1 + ENDIF + IP1 = LUIR1 + IF (BADLU) THEN + WRITE (IO, 1) 'LU factors uncomputed or corrupted.' + PRESRV = .FALSE. + NBLKS = 0 + ENDIF + +C ------------------------------------------------------------- +C copy of original matrix in column-oriented form +C ------------------------------------------------------------- + + IF (PRESRV .AND. .NOT. SYMBOL) THEN + WRITE (IO, 8) + WRITE (IO, 1) + $ 'Preserved copy of original matrix (stored by column),' + WRITE (IO, 1) 'one entry per line (row index, value):' + DO 40 COL = 1, N + P1 = INDEX (APP-1 + COL) + P2 = INDEX (APP-1 + COL+1) - 1 + WRITE (IO, 1) ' col: ', COL + IF (PRL .EQ. 3) THEN + P2 = MIN (PRMAX, P2) + ENDIF + DO 30 P = P1, P2 + WRITE (IO, 5) INDEX (AIP-1 + P), VALUE (AXP-1 + P) +30 CONTINUE + IF (PRL .EQ. 3 .AND. P2 .GE. PRMAX) THEN +C exit out of loop if done printing: + WRITE (IO, 7) + GO TO 50 + ENDIF +40 CONTINUE +C loop exit label: +50 CONTINUE + ENDIF + +C ------------------------------------------------------------- +C entries in off-diagonal blocks, in row-oriented form +C ------------------------------------------------------------- + + IF (NBLKS .GT. 1 .AND. .NOT. SYMBOL) THEN + WRITE (IO, 8) + WRITE (IO, 1) + $ 'Entries not in diagonal blocks (stored by row):' + WRITE (IO, 1) 'one entry per line (column index, value):' + IF (NZOFF .EQ. 0) THEN + WRITE (IO, 1) ' (none)' + ENDIF + DO 70 ROW = 1, N + P1 = INDEX (OFFPP-1 + ROW) + P2 = INDEX (OFFPP-1 + ROW+1) - 1 + IF (P2 .GE. P1) THEN + WRITE (IO, 1) ' row: ', ROW + IF (PRL .EQ. 3) THEN + P2 = MIN (PRMAX, P2) + ENDIF + DO 60 P = P1, P2 + WRITE (IO, 5) + $ INDEX (OFFIP-1 + P), VALUE (OFFXP-1 + P) +60 CONTINUE + ENDIF + IF (PRL .EQ. 3 .AND. P2 .GE. PRMAX) THEN +C exit out of loop if done printing: + WRITE (IO, 7) + GO TO 80 + ENDIF +70 CONTINUE +C loop exit label: +80 CONTINUE + ENDIF + +C ------------------------------------------------------------- +C LU factors of each diagonal block +C ------------------------------------------------------------- + + WRITE (IO, 8) + IF (NBLKS .GT. 0) THEN + IF (SYMBOL) THEN + WRITE (IO, 1) 'Nonzero pattern of prior LU factors:' + ELSE + WRITE (IO, 1) 'LU factors:' + ENDIF + ENDIF + PRN = 0 + DO 200 BLK = 1, NBLKS + +C ---------------------------------------------------------- +C print the factors of a single diagonal block +C ---------------------------------------------------------- + + IF (NBLKS .GT. 1) THEN + K1 = INDEX (BLKPP-1 + BLK) + K2 = INDEX (BLKPP-1 + BLK+1) - 1 + KN = K2-K1+1 + SGLTON = KN .EQ. 1 + IF (SGLTON) THEN +C this is a singleton + LUXXP = XP1-1 + INDEX (LUBLPP-1 + BLK) + ELSE + LUIIP = IP1-1 + INDEX (LUBLPP-1 + BLK) + ENDIF + IF (BLK .GT. 1) THEN + WRITE (IO, 9) + ENDIF + ELSE + SGLTON = .FALSE. + K1 = 1 + K2 = N + KN = N + LUIIP = IP1 + ENDIF + + IF (SGLTON) THEN + +C ------------------------------------------------------- +C this is a singleton +C ------------------------------------------------------- + + IF (PRL .EQ. 3 .AND. PRN .GE. PRMAX) THEN +C exit out of loop if done printing: + WRITE (IO, 7) + GO TO 210 + ENDIF + PRN = PRN + 1 + IF (SYMBOL) THEN + WRITE (IO, 1) 'Block: ', BLK, + $ ' (singleton) at index : ', K1 + ELSE + WRITE (IO, 4) 'Block: ', BLK, + $ ' (singleton) at index : ', K1,' value: ', + $ VALUE (LUXXP) + ENDIF + IF (PRL .GE. 5) THEN + WRITE (IO, 1) 'located in VALUE ( ', LUXXP,' )' + ENDIF + + ELSE + +C ------------------------------------------------------- +C this block is larger than 1-by-1 +C ------------------------------------------------------- + + LUXXP = XP1-1 + INDEX (LUIIP) + NLU = INDEX (LUIIP+1) + NPIV = INDEX (LUIIP+2) + MAXDC = INDEX (LUIIP+3) + MAXDR = INDEX (LUIIP+4) + LUPP = LUIIP+5 + IF (NBLKS .GT. 1) THEN + WRITE (IO, 1) 'Block: ',BLK,' first index: ',K1, + $ ' last index: ',K2 + ENDIF + IF (PRL .GE. 5) THEN + WRITE (IO, 1) 'elements: ', NLU, ' pivots: ', NPIV + WRITE (IO, 1) 'largest contribution block: ', + $ MAXDC, ' by ', MAXDR + WRITE (IO, 1)'located in INDEX ( ',LUIIP,' ... )' + IF (.NOT. SYMBOL) THEN + WRITE (IO, 1) 'and in VALUE ( ',LUXXP,' ... )' + ENDIF + ENDIF + LUIIP = LUPP + NLU + +C Note: the indices of the LU factors of the block range +C from 1 to kn, even though the kn-by-kn block resides in +C A (k1 ... k2, k1 ... k2). + K = 0 + + DO 190 E = 1, NLU + +C ---------------------------------------------------- +C print a single element +C ---------------------------------------------------- + + LUIP = LUIIP-1 + INDEX (LUPP-1 + E) + LUXP = LUXXP-1 + INDEX (LUIP) + LUK = INDEX (LUIP+1) + LUDEGR = INDEX (LUIP+2) + LUDEGC = INDEX (LUIP+3) + LUNSON = INDEX (LUIP+4) + LUDIMR = INDEX (LUIP+5) + LUDIMC = INDEX (LUIP+6) + LUCP = LUIP + 7 + LURP = LUCP + LUDEGC + LUSONP = LURP + LUDEGR + IF (PRL .GE. 5) THEN + WRITE (IO, 1) ' e: ', E, ' pivots: ', LUK + WRITE (IO, 1) ' children in dag: ', LUNSON, + $ ' frontal matrix: ', LUDIMR, ' by ', LUDIMC + ENDIF + +C ---------------------------------------------------- +C print the columns of L +C ---------------------------------------------------- + + P = LUXP + DO 140 J = 1, LUK + COL = K+J + NZCOL = LUK-J+1+LUDEGC + WRITE (IO, 1) ' L, col: ', COL + PRN = PRN + 1 + ROW = COL + IF (SYMBOL) THEN + WRITE (IO, 5) ROW + ELSE +C L is unit diagonal: + WRITE (IO, 5) ROW, ONE + ENDIF + P = P + 1 +C pivot block + DO 120 I = J+1, LUK + IF (PRL .EQ. 3 .AND. PRN .GE. PRMAX) THEN +C exit out of loop if done printing: + WRITE (IO, 7) + GO TO 210 + ENDIF + PRN = PRN + 1 + ROW = K+I + IF (SYMBOL) THEN + WRITE (IO, 5) ROW + ELSE + WRITE (IO, 5) ROW, VALUE (P) + ENDIF + P = P + 1 +120 CONTINUE +C L block + DO 130 I = 1, LUDEGC + IF (PRL .EQ. 3 .AND. PRN .GE. PRMAX) THEN +C exit out of loop if done printing: + WRITE (IO, 7) + GO TO 210 + ENDIF + PRN = PRN + 1 + ROW = INDEX (LUCP-1+I) + IF (SYMBOL) THEN + WRITE (IO, 5) ROW + ELSE + WRITE (IO, 5) ROW, VALUE (P) + ENDIF + P = P + 1 +130 CONTINUE + P = P + J +140 CONTINUE + +C ---------------------------------------------------- +C print the rows of U +C ---------------------------------------------------- + + UXP = LUXP + LUK*(LUDEGC+LUK) + DO 170 I = 1, LUK + ROW = K+I + NZROW = LUK-I+1+LUDEGR + WRITE (IO, 1) ' U, row: ', ROW + P = LUXP + (I-1) + (I-1) * (LUDEGC+LUK) +C pivot block + DO 150 J = I, LUK + IF (PRL .EQ. 3 .AND. PRN .GE. PRMAX) THEN +C exit out of loop if done printing: + WRITE (IO, 7) + GO TO 210 + ENDIF + PRN = PRN + 1 + COL = K+J + IF (SYMBOL) THEN + WRITE (IO, 5) COL + ELSE + WRITE (IO, 5) COL, VALUE (P) + ENDIF + P = P + (LUDEGC+LUK) +150 CONTINUE + P = UXP +C U block + DO 160 J = 1, LUDEGR + IF (PRL .EQ. 3 .AND. PRN .GE. PRMAX) THEN +C exit out of loop if done printing: + WRITE (IO, 7) + GO TO 210 + ENDIF + PRN = PRN + 1 + COL = INDEX (LURP-1+J) + IF (SYMBOL) THEN + WRITE (IO, 5) COL + ELSE + WRITE (IO, 5) COL, VALUE (P) + ENDIF + P = P + LUK +160 CONTINUE + UXP = UXP + 1 +170 CONTINUE + +C ---------------------------------------------------- +C print the sons of the element in the assembly DAG +C ---------------------------------------------------- + + IF (PRL .GE. 5) THEN + DO 180 I = 1, LUNSON + PRN = PRN + 1 + SON = INDEX (LUSONP-1+I) + IF (SON .LE. KN) THEN +C an LUson + WRITE (IO, 1) ' LUson: ', SON + ELSE IF (SON .LE. 2*KN) THEN +C a Uson + WRITE (IO, 1) ' Uson: ', SON-KN + ELSE +C an Lson + WRITE (IO, 1) ' Lson: ', SON-2*KN + ENDIF +180 CONTINUE + ENDIF + +C ---------------------------------------------------- +C increment count of pivots within this block +C ---------------------------------------------------- + + K = K + LUK +190 CONTINUE + ENDIF +200 CONTINUE +C loop exit label: +210 CONTINUE + +C ------------------------------------------------------------- +C row and column permutations +C ------------------------------------------------------------- + + IF (.NOT. BADLU) THEN + PRN = MIN (PRMAX, N) + IF (PRL .GE. 4) THEN +C print all of Cperm and Rperm + PRN = N + ENDIF + WRITE (IO, 8) + WRITE (IO, 1) 'Column permutations' + DO 220 I = 1, PRN + WRITE (IO, 5) INDEX (CPERMP+I-1) +220 CONTINUE + IF (PRN .LT. N) THEN + WRITE (IO, 7) + ENDIF + WRITE (IO, 8) + WRITE (IO, 1) 'Row permutations' + DO 230 I = 1, PRN + WRITE (IO, 5) INDEX (RPERMP+I-1) +230 CONTINUE + IF (PRN .LT. N) THEN + WRITE (IO, 7) + ENDIF + ENDIF + + ENDIF + +C----------------------------------------------------------------------- +C print B (on input) or W and X (on output) for MA38CD +C----------------------------------------------------------------------- + + IF (WHO .EQ. 3) THEN + WRITE (IO, 8) + PRN = MIN (PRMAX, N) + IF (PRL .GE. 4) THEN +C print all of B, or W and X + PRN = N + ENDIF + IF (WHERE .EQ. 1) THEN + WRITE (IO, 1) 'W (1 ... ',LW, + $ ' ), work vector: not printed' + WRITE (IO, 1) 'B (1 ... ',N,' ), right-hand side: ' + DO 240 I = 1, PRN + WRITE (IO, 5) I, B (I) +240 CONTINUE + IF (PRN .LT. N) THEN + WRITE (IO, 7) + ENDIF + ELSE + IF (INFO (1) .LT. 0) THEN + WRITE (IO, 1) 'W (1 ... ',LW,' ), work vector, and' + WRITE (IO, 1) 'X (1 ... ',N, ' ), solution,' + WRITE (IO, 1) + $ ' not printed because of error flag, INFO (1) = ', + $ INFO (1) + ELSE + IF (LW .EQ. 4*N) THEN +C MA38CD did iterative refinement + WRITE (IO, 1) 'W (1 ... ',N,' ), residual: ' + DO 250 I = 1, PRN + WRITE (IO, 5) I, W (I) +250 CONTINUE + IF (PRN .LT. N) THEN + WRITE (IO, 7) + ENDIF + WRITE (IO, 1) 'W (',N+1,' ... ',LW, + $ ' ), work vector: not printed' + ELSE +C no iterative refinement + WRITE (IO, 1) 'W (1 ... ',LW, + $ ' ), work vector: not printed' + ENDIF + WRITE (IO, 1) 'X (1 ... ',N,' ), solution: ' + DO 260 I = 1, PRN + WRITE (IO, 5) I, X (I) +260 CONTINUE + IF (PRN .LT. N) THEN + WRITE (IO, 7) + ENDIF + ENDIF + ENDIF + ENDIF + +C----------------------------------------------------------------------- +C who is this, and where: +C----------------------------------------------------------------------- + + IF (WHO .EQ. 1) THEN + IF (WHERE .EQ. 1) THEN + WRITE (IO, 6) 'end of MA38AD input ' + ELSE + WRITE (IO, 6) 'end of MA38AD output' + ENDIF + ELSE IF (WHO .EQ. 2) THEN + IF (WHERE .EQ. 1) THEN + WRITE (IO, 6) 'end of MA38BD input ' + ELSE + WRITE (IO, 6) 'end of MA38BD output' + ENDIF + ELSE IF (WHO .EQ. 3) THEN + IF (WHERE .EQ. 1) THEN + WRITE (IO, 6) 'end of MA38CD input ' + ELSE + WRITE (IO, 6) 'end of MA38CD output' + ENDIF + ENDIF + + RETURN + +C======================================================================= +C FORMAT STATMENTS +C======================================================================= + +1 FORMAT (' ', A, :, I12, :, A, :, I12, :, + $ A, :, I12, :, A, :, I12, :, A, :, I12) +2 FORMAT (' ', I12, ': ', I12, ' ', I12, ' ', D11.4) +3 FORMAT (' ', A, D13.4, A) +4 FORMAT (' ', A, I12, A, I12, A, D11.4) +5 FORMAT (' ', I12, :, ': ', D11.4) +6 FORMAT (' ', 59('='), A) +7 FORMAT (' ...') +8 FORMAT (' ', 79 ('-')) +9 FORMAT (' ', 79 ('.')) + END + + SUBROUTINE MA38ZD (WHO, ERROR, I, J, X, IO) + INTEGER WHO, ERROR, I, J, IO + DOUBLE PRECISION X + +C=== MA38ZD ============================================================ +C +C Unsymmetric-pattern multifrontal package (MA38). Double-precision. +C Copyright (C) 1995, Timothy A. Davis, University of Florida, USA. +C Joint work with Iain S. Duff, Rutherford Appleton Laboratory, UK. +C October 1995. Work supported by the National Science Foundation +C (DMS-9223088 and DMS-9504974) and the State of Florida; and by CRAY +C Research Inc. through the allocation of supercomputing resources. + +C======================================================================= +C NOT USER-CALLABLE + +C======================================================================= +C DESCRIPTION: +C======================================================================= +C +C Print error and warning messages for for MA38AD, MA38BD, and MA38CD. + +C======================================================================= +C INSTALLATION NOTE: +C======================================================================= +C +C This routine can be deleted on installation (replaced with a dummy +C routine that just returns without printing) in order to completely +C disable the printing of all error and warning messages. The error +C and warning return flag (Info (1)) will not be affected. To +C completely disable all I/O, you can also replace the MA38YD routine +C with a dummy subroutine. If you make this modification, please do +C not delete any original code - just comment it out instead. Add a +C comment and date to your modifications. + +C======================================================================= +C INPUT: +C======================================================================= +C +C who: what user-callable routine called MA38ZD: +C 1: MA38AD, 2: MA38BD, 3: MA38CD +C i, j, x: the relevant offending value(s) +C io: I/O unit on which to print. No printing +C occurs if < 0. +C error: the applicable error (<0) or warning (>0) +C Errors (<0) cause the factorization/solve to +C be terminated. If an error occurs, a prior +C warning status is overwritten with the error +C status. +C +C The following error codes are returned in Info (1) by MA38ND. +C These errors cause the factorization or solve to terminate: +C +C Where** Error Description +C +C FA RF - -1 N < 1 or N > maximum value +C FA RF - -2 NE < 1 or NE > maximum value +C FA RF - -3 LINDEX too small +C FA RF - -4 LVALUE too small +C FA RF - -5 both LINDEX and LVALUE are too small +C - RF - -6 prior pivot ordering no longer acceptable +C - RF SO -7 LU factors are uncomputed, or are corrupted +C +C The following warning codes are returned in Info (1) by MA38ND. +C The factorization or solve was able to complete: +C +C FA RF - 1 invalid entries +C FA RF - 2 duplicate entries +C FA RF - 3 invalid and duplicate entries +C FA RF - 4 singular matrix +C FA RF - 5 invalid entries, singular matrix +C FA RF - 6 duplicate entries, singular matrix +C FA RF - 7 invalid and duplicate entries, singular matrix +C - - SO 8 iterative refinement cannot be done +C +C The following are internal error codes (not returned in Info (1)) +C for printing specific invalid or duplicate entries. These codes are +C for MA38KD, MA38MD, and MA38RD. Invalid entries are ignored, and +C duplicate entries are added together (and the factorization +C continues). Warning levels (1..7) will be set later by MA38ND, +C above. +C +C FA RF - 99 invalid entry, out of range 1..N +C FA RF - 98 duplicate entry +C - RF - 97 invalid entry: within a diagonal block, but not +C in the pattern of the LU factors of that block. +C - RF - 96 invalid entry: below the diagonal blocks. Can +C only occur if the matrix has been ordered into +C block-upper-triangular form. +C - RF - 95 invalid entry: matrix is singular. The +C remaining rank 0 submatrix yet to be factorized +C is replaced with the identity matrix in the LU +C factors. Any entry that remains is ignored. + +C ** FA: MA38AD, RF: MA38BD, SO: MA38CD + +C======================================================================= +C OUTPUT: +C======================================================================= +C +C Error or warning message printed on I/O unit + +C======================================================================= +C SUBROUTINES AND FUNCTIONS CALLED / CALLED BY: +C======================================================================= +C +C called by subroutines: MA38ND, MA38KD, MA38PD, MA38RD + +C======================================================================= +C EXECUTABLE STATEMENTS: +C if (printing disabled on installation) return +C======================================================================= + + IF (IO .LT. 0) THEN +C printing of error / warning messages has not been requested + RETURN + ENDIF + + IF (WHO .EQ. 1) THEN + +C ------------------------------------------------------------- +C MA38AD error messages +C ------------------------------------------------------------- + + IF (ERROR .EQ. -1) THEN + WRITE (IO, 1) 'MA38AD: N less than one.' + ELSE IF (ERROR .EQ. -2) THEN + WRITE (IO, 1) 'MA38AD: NE less than one.' + ELSE IF (ERROR .EQ. -3) THEN + WRITE (IO, 1) + $ 'MA38AD: LINDEX too small. Must be greater than ', I + ELSE IF (ERROR .EQ. -4) THEN + WRITE (IO, 1) + $ 'MA38AD: LVALUE too small. Must be greater than ', I + +C ------------------------------------------------------------- +C MA38AD cumulative warning messages +C ------------------------------------------------------------- + + ELSE IF (ERROR .EQ. 1) THEN + WRITE (IO, 1) 'MA38AD: ', I, + $ ' invalid entries ignored (out of range 1..N).' + ELSE IF (ERROR .EQ. 2) THEN + WRITE (IO, 1) 'MA38AD: ', I,' duplicate entries summed.' + ELSE IF (ERROR .EQ. 4) THEN + WRITE (IO, 1) + $ 'MA38AD: matrix is singular. Only ', I, ' pivots found.' + +C ------------------------------------------------------------- +C MA38AD non-cumulative warning messages (internal error codes) +C ------------------------------------------------------------- + + ELSE IF (ERROR .EQ. 99) THEN + WRITE (IO, 2) + $ 'MA38AD: invalid entry (out of range 1..N):', I, J, X + ELSE IF (ERROR .EQ. 98) THEN + WRITE (IO, 2) + $ 'MA38AD: duplicate entry summed:', I, J, X + ENDIF + + ELSE IF (WHO .EQ. 2) THEN + +C ------------------------------------------------------------- +C MA38BD error messages +C ------------------------------------------------------------- + + IF (ERROR .EQ. -1) THEN + WRITE (IO, 1) 'MA38BD: N less than one.' + ELSE IF (ERROR .EQ. -2) THEN + IF (I .LT. 0) THEN + WRITE (IO, 1) 'MA38BD: NE less than one.' + ELSE + WRITE (IO, 1) + $ 'MA38BD: NE too large. Must be less than ', I + ENDIF + ELSE IF (ERROR .EQ. -3) THEN + WRITE (IO, 1) + $ 'MA38BD: LINDEX too small. Must be greater than ', I + ELSE IF (ERROR .EQ. -4) THEN + WRITE (IO, 1) + $ 'MA38BD: LVALUE too small. Must be greater than ', I + ELSE IF (ERROR .EQ. -6) THEN + WRITE (IO, 1) 'MA38BD: pivot order from MA38AD failed.' + ELSE IF (ERROR .EQ. -7) THEN + WRITE (IO, 1) + $ 'MA38BD: LU factors uncomputed or corrupted.' + +C ------------------------------------------------------------- +C MA38BD cumulative warning messages +C ------------------------------------------------------------- + + ELSE IF (ERROR .EQ. 1) THEN + IF (I .GT. 0) THEN + WRITE (IO, 1) 'MA38BD: ', I, + $ ' invalid entries ignored (out of range 1..N).' + ELSE + WRITE (IO, 1) 'MA38BD: ',-I, + $ ' invalid entries ignored (not in prior pattern).' + ENDIF + ELSE IF (ERROR .EQ. 2) THEN + WRITE (IO, 1) 'MA38BD: ', I,' duplicate entries summed.' + ELSE IF (ERROR .EQ. 4) THEN + WRITE (IO, 1) 'MA38BD: matrix is singular. Only ', I, + $ ' pivots found.' + +C ------------------------------------------------------------- +C MA38BD non-cumulative warning messages (internal error codes) +C ------------------------------------------------------------- + + ELSE IF (ERROR .EQ. 99) THEN + WRITE (IO, 2) + $ 'MA38BD: invalid entry (out of range 1..N):', I, J, X + ELSE IF (ERROR .EQ. 98) THEN + WRITE (IO, 2) + $ 'MA38BD: duplicate entry summed:', I, J, X + ELSE IF (ERROR .EQ. 97) THEN + WRITE (IO, 2) + $ 'MA38BD: invalid entry (not in pattern of prior factors)', + $ I, J, X + ELSE IF (ERROR .EQ. 96) THEN + WRITE (IO, 2) + $ 'MA38BD: invalid entry (below diagonal blocks):', I, J, X + ELSE IF (ERROR .EQ. 95) THEN + WRITE (IO, 2) + $ 'MA38BD: invalid entry (prior matrix singular):', I, J, X + ENDIF + + ELSE IF (WHO .EQ. 3) THEN + +C ------------------------------------------------------------- +C MA38CD error messages +C ------------------------------------------------------------- + + IF (ERROR .EQ. -7) THEN + WRITE (IO, 1) + $ 'MA38CD: LU factors uncomputed or corrupted.' + +C ------------------------------------------------------------- +C MA38CD non-cumulative warning messages +C ------------------------------------------------------------- + + ELSE IF (ERROR .EQ. 8) THEN + IF (I .EQ. 0) THEN + WRITE (IO, 1) + $ 'MA38CD: no iterative refinement: original matrix not preserved' + ELSE + WRITE (IO, 1) + $ 'MA38CD: no iterative refinement: only for Ax=b or A''x=b' + ENDIF + ENDIF + + ENDIF + + RETURN + +C======================================================================= +C FORMAT STATMENTS +C======================================================================= + +1 FORMAT (' ', A, :, I12, :, A) +2 FORMAT (' ', A, /, + $ ' row: ', I12, ' col: ', I12,' value: ', D11.4) + END + + diff --git a/src/Libraries/hsl/mc13-1.0.0/doc/mc13_Fortran.pdf b/src/Libraries/hsl/mc13-1.0.0/doc/mc13_Fortran.pdf new file mode 100644 index 00000000..ccd7e919 Binary files /dev/null and b/src/Libraries/hsl/mc13-1.0.0/doc/mc13_Fortran.pdf differ diff --git a/src/Libraries/hsl/mc13-1.0.0/src/mc13d.f b/src/Libraries/hsl/mc13-1.0.0/src/mc13d.f new file mode 100644 index 00000000..1db9ea2d --- /dev/null +++ b/src/Libraries/hsl/mc13-1.0.0/src/mc13d.f @@ -0,0 +1,155 @@ +* COPYRIGHT (c) 1976 AEA Technology +* Original date 21 Jan 1993 +C Toolpack tool decs employed. +C Double version of MC13D (name change only) +C 10 August 2001 DOs terminated with CONTINUE +C 13/3/02 Cosmetic changes applied to reduce single/double differences +C +C 12th July 2004 Version 1.0.0. Version numbering added. + + SUBROUTINE MC13DD(N,ICN,LICN,IP,LENR,IOR,IB,NUM,IW) +C .. Scalar Arguments .. + INTEGER LICN,N,NUM +C .. +C .. Array Arguments .. + INTEGER IB(N),ICN(LICN),IOR(N),IP(N),IW(N,3),LENR(N) +C .. +C .. External Subroutines .. + EXTERNAL MC13ED +C .. +C .. Executable Statements .. + CALL MC13ED(N,ICN,LICN,IP,LENR,IOR,IB,NUM,IW(1,1),IW(1,2),IW(1,3)) + RETURN + + END + SUBROUTINE MC13ED(N,ICN,LICN,IP,LENR,ARP,IB,NUM,LOWL,NUMB,PREV) +C +C ARP(I) IS ONE LESS THAN THE NUMBER OF UNSEARCHED EDGES LEAVING +C NODE I. AT THE END OF THE ALGORITHM IT IS SET TO A +C PERMUTATION WHICH PUTS THE MATRIX IN BLOCK LOWER +C TRIANGULAR FORM. +C IB(I) IS THE POSITION IN THE ORDERING OF THE START OF THE ITH +C BLOCK. IB(N+1-I) HOLDS THE NODE NUMBER OF THE ITH NODE +C ON THE STACK. +C LOWL(I) IS THE SMALLEST STACK POSITION OF ANY NODE TO WHICH A PATH +C FROM NODE I HAS BEEN FOUND. IT IS SET TO N+1 WHEN NODE I +C IS REMOVED FROM THE STACK. +C NUMB(I) IS THE POSITION OF NODE I IN THE STACK IF IT IS ON +C IT, IS THE PERMUTED ORDER OF NODE I FOR THOSE NODES +C WHOSE FINAL POSITION HAS BEEN FOUND AND IS OTHERWISE ZERO. +C PREV(I) IS THE NODE AT THE END OF THE PATH WHEN NODE I WAS +C PLACED ON THE STACK. +C +C +C ICNT IS THE NUMBER OF NODES WHOSE POSITIONS IN FINAL ORDERING HAVE +C BEEN FOUND. +C .. Scalar Arguments .. + INTEGER LICN,N,NUM +C .. +C .. Array Arguments .. + INTEGER ARP(N),IB(N),ICN(LICN),IP(N),LENR(N),LOWL(N),NUMB(N), + + PREV(N) +C .. +C .. Local Scalars .. + INTEGER DUMMY,I,I1,I2,ICNT,II,ISN,IST,IST1,IV,IW,J,K,LCNT,NNM1,STP +C .. +C .. Intrinsic Functions .. + INTRINSIC MIN +C .. +C .. Executable Statements .. + ICNT = 0 +C NUM IS THE NUMBER OF BLOCKS THAT HAVE BEEN FOUND. + NUM = 0 + NNM1 = N + N - 1 +C +C INITIALIZATION OF ARRAYS. + DO 20 J = 1,N + NUMB(J) = 0 + ARP(J) = LENR(J) - 1 + 20 CONTINUE +C +C + DO 120 ISN = 1,N +C LOOK FOR A STARTING NODE + IF (NUMB(ISN).NE.0) GO TO 120 + IV = ISN +C IST IS THE NUMBER OF NODES ON THE STACK ... IT IS THE STACK POINTER. + IST = 1 +C PUT NODE IV AT BEGINNING OF STACK. + LOWL(IV) = 1 + NUMB(IV) = 1 + IB(N) = IV +C +C THE BODY OF THIS LOOP PUTS A NEW NODE ON THE STACK OR BACKTRACKS. + DO 110 DUMMY = 1,NNM1 + I1 = ARP(IV) +C HAVE ALL EDGES LEAVING NODE IV BEEN SEARCHED. + IF (I1.LT.0) GO TO 60 + I2 = IP(IV) + LENR(IV) - 1 + I1 = I2 - I1 +C +C LOOK AT EDGES LEAVING NODE IV UNTIL ONE ENTERS A NEW NODE OR +C ALL EDGES ARE EXHAUSTED. + DO 50 II = I1,I2 + IW = ICN(II) +C HAS NODE IW BEEN ON STACK ALREADY. + IF (NUMB(IW).EQ.0) GO TO 100 +C UPDATE VALUE OF LOWL(IV) IF NECESSARY. + LOWL(IV) = MIN(LOWL(IV),LOWL(IW)) + 50 CONTINUE +C +C THERE ARE NO MORE EDGES LEAVING NODE IV. + ARP(IV) = -1 +C IS NODE IV THE ROOT OF A BLOCK. + 60 IF (LOWL(IV).LT.NUMB(IV)) GO TO 90 +C +C ORDER NODES IN A BLOCK. + NUM = NUM + 1 + IST1 = N + 1 - IST + LCNT = ICNT + 1 +C PEEL BLOCK OFF THE TOP OF THE STACK STARTING AT THE TOP AND +C WORKING DOWN TO THE ROOT OF THE BLOCK. + DO 70 STP = IST1,N + IW = IB(STP) + LOWL(IW) = N + 1 + ICNT = ICNT + 1 + NUMB(IW) = ICNT + IF (IW.EQ.IV) GO TO 80 + 70 CONTINUE + 80 IST = N - STP + IB(NUM) = LCNT +C ARE THERE ANY NODES LEFT ON THE STACK. + IF (IST.NE.0) GO TO 90 +C HAVE ALL THE NODES BEEN ORDERED. + IF (ICNT.LT.N) GO TO 120 + GO TO 130 +C +C BACKTRACK TO PREVIOUS NODE ON PATH. + 90 IW = IV + IV = PREV(IV) +C UPDATE VALUE OF LOWL(IV) IF NECESSARY. + LOWL(IV) = MIN(LOWL(IV),LOWL(IW)) + GO TO 110 +C +C PUT NEW NODE ON THE STACK. + 100 ARP(IV) = I2 - II - 1 + PREV(IW) = IV + IV = IW + IST = IST + 1 + LOWL(IV) = IST + NUMB(IV) = IST + K = N + 1 - IST + IB(K) = IV + 110 CONTINUE +C + 120 CONTINUE +C +C +C PUT PERMUTATION IN THE REQUIRED FORM. + 130 DO 140 I = 1,N + II = NUMB(I) + ARP(II) = I + 140 CONTINUE + RETURN + + END diff --git a/src/Libraries/hsl/mc21-1.0.0/doc/mc21_Fortran.pdf b/src/Libraries/hsl/mc21-1.0.0/doc/mc21_Fortran.pdf new file mode 100644 index 00000000..416c168e Binary files /dev/null and b/src/Libraries/hsl/mc21-1.0.0/doc/mc21_Fortran.pdf differ diff --git a/src/Libraries/hsl/mc21-1.0.0/src/mc21d.f b/src/Libraries/hsl/mc21-1.0.0/src/mc21d.f new file mode 100644 index 00000000..20e1ec19 --- /dev/null +++ b/src/Libraries/hsl/mc21-1.0.0/src/mc21d.f @@ -0,0 +1,147 @@ +* COPYRIGHT (c) 1977 AEA Technology +* Original date 8 Oct 1992 +C######8/10/92 Toolpack tool decs employed. +C######8/10/92 D version created by name change only. +C 13/3/02 Cosmetic changes applied to reduce single/double differences +C +C 12th July 2004 Version 1.0.0. Version numbering added. + + SUBROUTINE MC21AD(N,ICN,LICN,IP,LENR,IPERM,NUMNZ,IW) +C .. Scalar Arguments .. + INTEGER LICN,N,NUMNZ +C .. +C .. Array Arguments .. + INTEGER ICN(LICN),IP(N),IPERM(N),IW(N,4),LENR(N) +C .. +C .. External Subroutines .. + EXTERNAL MC21BD +C .. +C .. Executable Statements .. + CALL MC21BD(N,ICN,LICN,IP,LENR,IPERM,NUMNZ,IW(1,1),IW(1,2), + + IW(1,3),IW(1,4)) + RETURN +C + END + SUBROUTINE MC21BD(N,ICN,LICN,IP,LENR,IPERM,NUMNZ,PR,ARP,CV,OUT) +C PR(I) IS THE PREVIOUS ROW TO I IN THE DEPTH FIRST SEARCH. +C IT IS USED AS A WORK ARRAY IN THE SORTING ALGORITHM. +C ELEMENTS (IPERM(I),I) I=1, ... N ARE NON-ZERO AT THE END OF THE +C ALGORITHM UNLESS N ASSIGNMENTS HAVE NOT BEEN MADE. IN WHICH CASE +C (IPERM(I),I) WILL BE ZERO FOR N-NUMNZ ENTRIES. +C CV(I) IS THE MOST RECENT ROW EXTENSION AT WHICH COLUMN I +C WAS VISITED. +C ARP(I) IS ONE LESS THAN THE NUMBER OF NON-ZEROS IN ROW I +C WHICH HAVE NOT BEEN SCANNED WHEN LOOKING FOR A CHEAP ASSIGNMENT. +C OUT(I) IS ONE LESS THAN THE NUMBER OF NON-ZEROS IN ROW I +C WHICH HAVE NOT BEEN SCANNED DURING ONE PASS THROUGH THE MAIN LOOP. +C +C INITIALIZATION OF ARRAYS. +C .. Scalar Arguments .. + INTEGER LICN,N,NUMNZ +C .. +C .. Array Arguments .. + INTEGER ARP(N),CV(N),ICN(LICN),IP(N),IPERM(N),LENR(N),OUT(N),PR(N) +C .. +C .. Local Scalars .. + INTEGER I,II,IN1,IN2,IOUTK,J,J1,JORD,K,KK +C .. +C .. Executable Statements .. + DO 10 I = 1,N + ARP(I) = LENR(I) - 1 + CV(I) = 0 + IPERM(I) = 0 + 10 CONTINUE + NUMNZ = 0 +C +C +C MAIN LOOP. +C EACH PASS ROUND THIS LOOP EITHER RESULTS IN A NEW ASSIGNMENT +C OR GIVES A ROW WITH NO ASSIGNMENT. + DO 100 JORD = 1,N + J = JORD + PR(J) = -1 + DO 70 K = 1,JORD +C LOOK FOR A CHEAP ASSIGNMENT + IN1 = ARP(J) + IF (IN1.LT.0) GO TO 30 + IN2 = IP(J) + LENR(J) - 1 + IN1 = IN2 - IN1 + DO 20 II = IN1,IN2 + I = ICN(II) + IF (IPERM(I).EQ.0) GO TO 80 + 20 CONTINUE +C NO CHEAP ASSIGNMENT IN ROW. + ARP(J) = -1 +C BEGIN LOOKING FOR ASSIGNMENT CHAIN STARTING WITH ROW J. + 30 CONTINUE + OUT(J) = LENR(J) - 1 +C INNER LOOP. EXTENDS CHAIN BY ONE OR BACKTRACKS. + DO 60 KK = 1,JORD + IN1 = OUT(J) + IF (IN1.LT.0) GO TO 50 + IN2 = IP(J) + LENR(J) - 1 + IN1 = IN2 - IN1 +C FORWARD SCAN. + DO 40 II = IN1,IN2 + I = ICN(II) + IF (CV(I).EQ.JORD) GO TO 40 +C COLUMN I HAS NOT YET BEEN ACCESSED DURING THIS PASS. + J1 = J + J = IPERM(I) + CV(I) = JORD + PR(J) = J1 + OUT(J1) = IN2 - II - 1 + GO TO 70 +C + 40 CONTINUE +C +C BACKTRACKING STEP. + 50 CONTINUE + J = PR(J) + IF (J.EQ.-1) GO TO 100 + 60 CONTINUE +C + 70 CONTINUE +C +C NEW ASSIGNMENT IS MADE. + 80 CONTINUE + IPERM(I) = J + ARP(J) = IN2 - II - 1 + NUMNZ = NUMNZ + 1 + DO 90 K = 1,JORD + J = PR(J) + IF (J.EQ.-1) GO TO 100 + II = IP(J) + LENR(J) - OUT(J) - 2 + I = ICN(II) + IPERM(I) = J + 90 CONTINUE +C + 100 CONTINUE +C +C IF MATRIX IS STRUCTURALLY SINGULAR, WE NOW COMPLETE THE +C PERMUTATION IPERM. + IF (NUMNZ.EQ.N) RETURN + DO 110 I = 1,N + ARP(I) = 0 + 110 CONTINUE + K = 0 + DO 130 I = 1,N + IF (IPERM(I).NE.0) GO TO 120 + K = K + 1 + OUT(K) = I + GO TO 130 +C + 120 CONTINUE + J = IPERM(I) + ARP(J) = I + 130 CONTINUE + K = 0 + DO 140 I = 1,N + IF (ARP(I).NE.0) GO TO 140 + K = K + 1 + IOUTK = OUT(K) + IPERM(IOUTK) = I + 140 CONTINUE + RETURN +C + END diff --git a/src/Libraries/hsl/mc34-1.0.0/doc/mc34_Fortran.pdf b/src/Libraries/hsl/mc34-1.0.0/doc/mc34_Fortran.pdf new file mode 100644 index 00000000..3e0c6c2a Binary files /dev/null and b/src/Libraries/hsl/mc34-1.0.0/doc/mc34_Fortran.pdf differ diff --git a/src/Libraries/hsl/mc34ad.f b/src/Libraries/hsl/mc34-1.0.0/src/mc34d.f similarity index 62% rename from src/Libraries/hsl/mc34ad.f rename to src/Libraries/hsl/mc34-1.0.0/src/mc34d.f index 6522c563..12012259 100644 --- a/src/Libraries/hsl/mc34ad.f +++ b/src/Libraries/hsl/mc34-1.0.0/src/mc34d.f @@ -1,7 +1,10 @@ -* COPYRIGHT (c) 1993 AEA Technology -*######DATE 10 Feb 1993 +* COPYRIGHT (c) 1987 AEA Technology +* Original date 10 Feb 1993 C Toolpack tool decs employed. -C +C 20/2/02 Cosmetic changes applied to reduce single/double differences + +C 12th July 2004 Version 1.0.0. Version numbering added. + SUBROUTINE MC34AD(N,IRN,JCOLST,YESA,A,IW) C THIS SUBROUTINE ACCEPTS AS INPUT THE STANDARD DATA STRUCTURE FOR C A SYMMETRIC MATRIX STORED AS A LOWER TRIANGLE AND PRODUCES @@ -146,96 +149,3 @@ SUBROUTINE MC34AD(N,IRN,JCOLST,YESA,A,IW) RETURN END -* ******************************************************************* -* COPYRIGHT (c) 1967 Hyprotech UK -* All rights reserved. -* -* None of the comments in this Copyright notice between the lines -* of asterisks shall be removed or altered in any way. -* -* This Package is intended for compilation without modification, -* so most of the embedded comments have been removed. -* -* ALL USE IS SUBJECT TO LICENCE. For full details of an HSL ARCHIVE -* Licence, see http://hsl.rl.ac.uk/archive/cou.html -* -* Please note that for an HSL ARCHIVE Licence: -* -* 1. The Package must not be copied for use by any other person. -* Supply of any part of the library by the Licensee to a third party -* shall be subject to prior written agreement between AEA -* Hyprotech UK Limited and the Licensee on suitable terms and -* conditions, which will include financial conditions. -* 2. All information on the Package is provided to the Licensee on the -* understanding that the details thereof are confidential. -* 3. All publications issued by the Licensee that include results obtained -* with the help of one or more of the Packages shall acknowledge the -* use of the Packages. The Licensee will notify the Numerical Analysis -* Group at Rutherford Appleton Laboratory of any such publication. -* 4. The Packages may be modified by or on behalf of the Licensee -* for such use in research applications but at no time shall such -* Packages or modifications thereof become the property of the -* Licensee. The Licensee shall make available free of charge to the -* copyright holder for any purpose all information relating to -* any modification. -* 5. Neither CCLRC nor Hyprotech UK Limited shall be liable for any -* direct or consequential loss or damage whatsoever arising out of -* the use of Packages by the Licensee. -* ******************************************************************* -* -*######DATE 4 Oct 1992 -C Toolpack tool decs employed. -C SAVE statement for COMMON FA01ED added. -C EAT 21/6/93 EXTERNAL statement put in for block data on VAXs. -C -C - DOUBLE PRECISION FUNCTION FA01AD(I) - INTEGER I - DOUBLE PRECISION R,S - INTRINSIC DINT,MOD - COMMON /FA01ED/GL,GR - DOUBLE PRECISION GL,GR - EXTERNAL FA01FD - SAVE /FA01ED/ - R = GR*9228907D0/65536D0 - S = DINT(R) - GL = MOD(S+GL*9228907D0,65536D0) - GR = R - S - IF (I.GE.0) FA01AD = (GL+GR)/65536D0 - IF (I.LT.0) FA01AD = (GL+GR)/32768D0 - 1.D0 - GR = GR*65536D0 - RETURN - END - SUBROUTINE FA01BD(MAX,NRAND) - INTEGER MAX,NRAND - DOUBLE PRECISION FA01AD - EXTERNAL FA01AD - INTRINSIC DBLE,INT - NRAND = INT(FA01AD(1)*DBLE(MAX)) + 1 - RETURN - END - SUBROUTINE FA01CD(IL,IR) - INTEGER IL,IR - COMMON /FA01ED/GL,GR - DOUBLE PRECISION GL,GR - SAVE /FA01ED/ - IL = GL - IR = GR - RETURN - END - SUBROUTINE FA01DD(IL,IR) - INTEGER IL,IR - COMMON /FA01ED/GL,GR - DOUBLE PRECISION GL,GR - SAVE /FA01ED/ - GL = IL - GR = IR - RETURN - END - BLOCK DATA FA01FD - COMMON /FA01ED/GL,GR - DOUBLE PRECISION GL,GR - SAVE /FA01ED/ - DATA GL/21845D0/ - DATA GR/21845D0/ - END diff --git a/src/Libraries/hsl/mc40-1.0.0/doc/mc40_Fortran.pdf b/src/Libraries/hsl/mc40-1.0.0/doc/mc40_Fortran.pdf new file mode 100644 index 00000000..dbc9a6ec Binary files /dev/null and b/src/Libraries/hsl/mc40-1.0.0/doc/mc40_Fortran.pdf differ diff --git a/src/Libraries/hsl/mc40-1.0.0/src/mc40d.f b/src/Libraries/hsl/mc40-1.0.0/src/mc40d.f new file mode 100755 index 00000000..9f548b02 --- /dev/null +++ b/src/Libraries/hsl/mc40-1.0.0/src/mc40d.f @@ -0,0 +1,1028 @@ +* COPYRIGHT (c) 1988 AEA Technology +*######DATE 21 Sept 1994 +C +C + SUBROUTINE MC40AD(ITYPE,N,NNZ,IRN,JCN,ICPTR,IPERM,IW,IPROF,IFLAG) +C +C ALGORITHM TO REDUCE THE PROFILE OF A SPARSE SQUARE MATRIX WITH A +C SYMMETRIC SPARSITY PATTERN. +C THE USER MUST SUPPLY THE PATTERN OF THE ENTRIES IN THE STRICTLY +C LOWER TRIANGULAR PART OF THE MATRIX. +C +C ITYPE - ON ENTRY, IF ITYPE=1, THE USER HAS SUPPLIED +C THE STRICT LOWER TRIANGLE OF THE MATRIX IN +C COORDINATE FORMAT +C IF ITYPE=0, THE USER HAS INPUT THE STRICT LOWER +C TRIANGLE OF THE MATRIX IN SPARSE COLUMN-WISE +C FORMAT. Unchanged on exit. +C +C N - ORDER OF THE MATRIX +C - RESTRICTION: N.GE.1. Unchanged on exit. +C +C NNZ - NNZ IS THE NUMBER OF ENTRIES IN THE STRICT +C LOWER TRIANGLE OF THE MATRIX +C - RESTRICTION: NNZ.GE.0. Unchanged on exit. +C +C IRN - INTEGER ARRAY OF LENGTH 2*NNZ +C - ON ENTRY CONTAINS THE ROW INDICES OF THE +C ENTRIES IN THE STRICT LOWER TRIANGLE OF THE +C MATRIX. ON EXIT HOLDS +C ADJACENCY LIST FOR ALL NODES IN THE MATRIX +C +C JCN - INTEGER ARRAY +C - IF ITYPE=1, LENGTH OF ARRAY NNZ +C - IF ITYPE=1, JCN CONTAINS THE COLUMN INDICES OF THE +C ENTRIES IN THE STRICT LOWER TRIANGLE PART OF +C THE MATRIX. DESTROTED BY ROUTINE. +C - IF ITYPE=0, JCN IS NOT ACCESSED +C +C ICPTR - INTEGER ARRAY OF LENGTH N+1 +C - IF ITYPE=1, ICPTR IS NOT SET ON ENTRY; IF ITYPE=0 +C ICPTR IS AN ARRAY SET SO THAT ICPTR(J) IS THE +C POSITION IN THE ARRAY IRN OF THE FIRST ENTRY IN +C COLUMN J (J=1,...,N) +C - ON EXIT HOLDS LIST OF POINTERS TO IRN +C - NODES ADJACENT TO NODE I ARE FOUND IN IRN(J), WHERE +C J = ICPTR(I), ICPTR(I)+1, ...,ICPTR(I+1)-1 +C - DEGREE OF NODE I GIVEN BY ICPTR(I+1)-ICPTR(I) +C +C IPERM - INTEGER ARRAY OF LENGTH N +C - NOT SET ON ENTRY +C - ON EXIT HOLDS LIST OF THE NEW NODE NUMBERS +C - NEW NODE NUMBER FOR NODE I GIVEN BY IPERM(I) +C +C IW - INTEGER ARRAY DEFINING WORKSPACE FOR RENUMBERING +C - LENGTH 3*N+2 +C +C IPROF - INTEGER ARRAY OF LENGTH 2. NOT SET ON ENTRY +C ON EXIT IPROF(1) - PROFILE FOR THE ORIGINAL ORDERING +C IPROF(2) - PROFILE FOR THE NEW ORDERING +C +C IFLAG - INTEGER VARIABLE, NOT SET ON ENTRY. ERROR FLAG. +C - IF IFLAG GT 0 A WARNING IS ISSUED BUT PROGRAM CONTINUES +C - IF IFLAG LT 0 THE PROGRAM IS TERMINATED +C +C .. Scalar Arguments .. + INTEGER IFLAG,ITYPE,N,NNZ +C .. +C .. Array Arguments .. + INTEGER ICPTR(N+1),IPERM(N),IPROF(2),IRN(2*NNZ),IW(3*N+2),JCN(*) +C .. +C .. Scalars in Common .. + INTEGER LP,MP +C .. +C .. Local Scalars .. + INTEGER I,IOUT,J,J1,JFLAG,KZ,L,NDIAG,OFDIAG + LOGICAL YESA +C .. +C .. Local Arrays .. + DOUBLE PRECISION A(1) +C .. +C .. External Subroutines .. + EXTERNAL MC34AD,MC49AD,MC40BD +C .. +C .. Data block external statement + EXTERNAL MC40KD +C .. +C .. Common blocks .. + COMMON /MC40ID/LP,MP +C .. +C .. Save statement .. + SAVE /MC40ID/ +C .. + YESA = .FALSE. + IFLAG = 0 +C +C CHECK INPUT PARAMETERS +C + IF (N.LT.1) THEN + IFLAG = -1 + IF (LP.GT.0) WRITE (LP,FMT=9000) IFLAG + RETURN + + END IF + + IF (NNZ.LT.0) THEN + IFLAG = -2 + IF (LP.GT.0) WRITE (LP,FMT=9000) IFLAG + RETURN + + END IF +C + IF (ITYPE.NE.0 .AND. ITYPE.NE.1) THEN + IFLAG = -3 + IF (LP.GT.0) WRITE (LP,FMT=9000) IFLAG + RETURN + + END IF +C +C CHECK WHETHER THE MATRIX IS OF ORDER 1 +C + IF (N.EQ.1) THEN + IPROF(1) = 1 + IPROF(2) = 1 + IPERM(1) = 1 + RETURN + + END IF +C +C CHECK WHETHER THE MATRIX IS DIAGONAL. IF IT IS RETURN WITH +C THE PROFILE EQUAL TO THE ORDER OF THE MATRIX +C + IF (NNZ.EQ.0) THEN + IPROF(1) = N + IPROF(2) = N + RETURN + + END IF +C +C INITIALISE +C + DO 10 I = 1,3*N + 2 + IW(I) = 0 + 10 CONTINUE +C +C CHECK THAT THE USER DID NOT SUPPLY SOME ENTRIES ON THE +C DIAGONAL OR IN THE UPPER TRIANGLE OF THE MATRIX. IF THE +C USER DID SUPPLY ENTRIES NOT IN THE LOWER TRIANGLE THEY ARE +C IGNORED AND THE USER IS ISSUED WITH A WARNING MESSAGE. +C +C ALSO CHECK THAT THE USER DID NOT SUPPLY ROW OR COLUMN INDICES +C OUT OF RANGE (AGAIN, ANY SUCH ENTRIES ARE IGNORED). +C + KZ = 0 + IOUT = 0 + NDIAG = 0 + OFDIAG = 0 + IF (ITYPE.EQ.0) THEN + J1 = ICPTR(1) + ICPTR(1) = 1 + DO 30 L = 1,N + DO 20 J = J1,ICPTR(L+1) - 1 + I = IRN(J) + IF (I.GT.N .OR. I.LT.1) IOUT = IOUT + 1 + IF (I.EQ.L) NDIAG = NDIAG + 1 + IF (I.LT.L) OFDIAG = OFDIAG + 1 + IF (I.GT.L .AND. I.LE.N) THEN + KZ = KZ + 1 + IRN(KZ) = I + END IF + + 20 CONTINUE + J1 = ICPTR(L+1) + ICPTR(L+1) = KZ + 1 + 30 CONTINUE + + ELSE + DO 40 L = 1,NNZ + I = IRN(L) + J = JCN(L) + IF (I.GT.N .OR. I.LT.1) IOUT = IOUT + 1 + IF (J.GT.N .OR. J.LT.1) IOUT = IOUT + 1 + IF (I.EQ.J) NDIAG = NDIAG + 1 + IF (I.LT.J) OFDIAG = OFDIAG + 1 + IF (J.GE.1 .AND. I.GT.J .AND. I.LE.N) THEN + KZ = KZ + 1 + IRN(KZ) = I + JCN(KZ) = J + END IF + + 40 CONTINUE + END IF +C + IF (IOUT.GT.0) THEN + IFLAG = 3 + + ELSE IF (OFDIAG.GT.0) THEN + IFLAG = 2 + + ELSE IF (NDIAG.GT.0) THEN + IFLAG = 1 + END IF + + IF (IFLAG.GT.0 .AND. MP.GT.0) WRITE (MP,FMT=9010) IFLAG +C +C IF ITYPE=1 SORT THE ENTRIES TO AN ORDERING BY COLUMNS +C + IF (ITYPE.EQ.1) THEN + CALL MC49AD(-1,N,N,KZ,IRN,JCN,YESA,1,A,N+1,ICPTR,N+1, + + IW,JFLAG) + DO 50 I = 1,N + IW(I) = 0 + 50 CONTINUE + END IF +C +C EXPAND MATRIX STRUCTURE +C + CALL MC34AD(N,IRN,ICPTR,YESA,A,IW) + DO 60 I = 1,N + IW(I) = 0 + 60 CONTINUE +C +C CALL THE RENUMBERING ALGORITHM +C + CALL MC40BD(N,NNZ,IRN,ICPTR,IPERM,IW,IPROF) +C + RETURN + + 9000 FORMAT (/,3X,'ERROR MESSAGE: IFLAG = ',I2) + 9010 FORMAT (/,3X,'WARNING MESSAGE : IFLAG =',I2) + + END +C + SUBROUTINE MC40BD(N,NNZ,IRN,ICPTR,IPERM,IW,IPROF) +C +C RENUMBER A GRAPH FOR SMALL WAVEFRONT AND PROFILE +C +C N,NNZ - SEE MC40AD +C IRN - ADJACENCY LIST FOR ALL NODES IN GRAPH +C - LIST OF LENGTH 2*NNZ. UNCHANGED ON EXIT. +C ICPTR - LIST OF LENGTH N+1 OF POINTERS TO IRN. SEE MC40AD. +C IPERM - INTEGER ARRAY OF LENGTH N. NOT SET ON ENTRY +C - ON EXIT, NEW NUMBERS CONTAINED IN IPERM(I) FOR I=1 TO N +C - NEW NUMBER FOR NODE I GIVEN BY IPERM(I) +C - IPERM CONTAINS ORIGINAL NODE NUMBERS IF THEY GIVE +C A SMALLER PROFILE +C IW - INTEGER ARRAY DEFINING WORKSPACE FOR RENUMBERING +C - LENGTH 3*N+2 +C IPROF - NOT SET ON ENTRY +C - ON EXIT IPROF(1) - PROFILE USING ORIGINAL NODE ORDERING +C IPROF(2) - PROFILE FOR NEW NODE ORDERING +C IF ORIGINAL NODE NUMBERS GIVE A SMALLER PROFILE, +C THE BOTH ENTRIES IN IPROF ARE SET TO THE +C ORIGINAL PROFILE +C +C .. Scalar Arguments .. + INTEGER N,NNZ +C .. +C .. Array Arguments .. + INTEGER ICPTR(N+1),IPERM(N),IPROF(2),IRN(2*NNZ),IW(3*N+2) +C .. +C .. Local Scalars .. + INTEGER DEGREE,I,LSTNUM,N1,N2,N3,NODES,NSTOP,NSTRT +C .. +C .. External Subroutines .. + EXTERNAL MC40CD,MC40DD,MC40ED,MC40FD +C .. +C SET ALL NEW NODE NUMBERS = 1 +C THIS IS USED TO DENOTE ALL VISIBLE NODES +C + DO 10 I = 1,N + IPERM(I) = 1 + 10 CONTINUE +C +C SET LAST NEW NODE NUMBER +C + LSTNUM = 0 +C +C RENUMBER ALL NODES OF DEGREE ZERO +C STORE -VE OF NEW NODE NUMBER +C + DO 20 I = 1,N + DEGREE = ICPTR(I+1) - ICPTR(I) + IF (DEGREE.EQ.0) THEN + LSTNUM = LSTNUM + 1 + IPERM(I) = -LSTNUM + END IF + + 20 CONTINUE +C +C LOOP WHILE SOME NODES REMAIN UNNUMBERED +C + 30 IF (LSTNUM.LT.N) THEN +C +C FIND END POINTS OF P-DIAMETER FOR NODES IN THIS COMPONENT +C + N1 = 1 + N2 = N1 + N - LSTNUM + N3 = N2 + N + 1 + CALL MC40CD(N,NNZ,IRN,ICPTR,IPERM,IW(N1),IW(N2),IW(N2),IW(N3), + + NSTRT,NSTOP,NODES) +C +C COMPUTE DISTANCES FROM END NODE AND ASSEMBLE LIST OF NODES +C THAT ARE IN THIS COMPONENT +C + N2 = N1 + NODES + N3 = N2 + NODES + 1 + CALL MC40DD(N,NNZ,NSTOP,NODES,IRN,ICPTR,IPERM,IW(N1),IW(N2)) +C +C RENUMBER NODES IN THIS COMPONENT +C + N3 = N2 + N + CALL MC40ED(N,NNZ,NODES,NSTRT,LSTNUM,IRN,ICPTR,IPERM,IW(N1), + + IW(N1),IW(N2)) + GO TO 30 + + END IF +C +C SET NEW NODE NUMBERS TO +VE VALUES +C + DO 40 I = 1,N + IPERM(I) = -IPERM(I) + 40 CONTINUE +C +C COMPUTE PROFILES FOR OLD AND NEW NODE NUMBERS +C + CALL MC40FD(N,NNZ,IPERM,IRN,ICPTR,IPROF) +C +C USE ORIGINAL NUMBERING IF NEW NUMBERING GIVES GREATER PROFILE +C + IF (IPROF(2).GE.IPROF(1)) THEN + DO 50 I = 1,N + IPERM(I) = I + 50 CONTINUE + IPROF(2) = IPROF(1) + END IF +C + RETURN + + END +C + SUBROUTINE MC40CD(N,NNZ,IRN,ICPTR,MASK,LS,XLS,DEG,LIST,NSTRT, + + NSTOP,NODES) +C +C FIND NODES WHICH DEFINE A PSUEDO-DIAMETER OF A GRAPH +C +C N - THE TOTAL NUMBER OF NODES IN THE GRAPH +C IRN - ADJACENCY LIST FOR ALL NODES IN THE GRAPH +C ICPTR - LIST OF LENGTH N+1 OF POINTERS TO IRN +C MASK - MASKING VECTOR OF LENGTH N FOR GRAPH +C - VISIBLE NODES HAVE MASK = 1. NODE IS INVISIBLE OTHERWISE. +C LS - LIST OF LENGTH N CONTAINING A ROOTED LEVEL STRUCTURE +C - NOT SET ON ENTRY +C XLS - LIST OF LENGTH N+1 POINTERS TO LS +C - NODES IN LEVEL I ARE FOUND IN LS(J), WHERE +C J = XLS(I), XLS(I)+1, ..., XLS(I+1)-1 +C - THE WIDTH OF LEVEL I IS GIVEN BY XLS(I+1)-XLS(I) +C - NOT SET ON ENTRY +C DEG - LIST OF LENGTH N DEGREES OF NODES ON BOTTOM +C LEVEL OF ROOTED STRUCTURE +C - NOT SET ON ENTRY +C LIST - LIST OF LENGTH N OF NODES ON BOTTOM LEVEL OF +C ROOTED LEVEL STRUCTURE +C - NOT SET ON ENTRY +C NSTRT - NOT SET ON ENTRY. ON EXIT STARTING NODE FOR RENUMBERING. +C NSTOP - NOT SET ON ENTRY. ON EXIT END NODE FOR RENUMBERING +C NODES - NOT SET ON ENTRY. ON EXIT NUMBER OF NODES IN THIS +C COMPONENT OF GRAPH +C +C NOTES: +C ------ +C - DEG AND XLS MAY OCCUPY SAME SPACE +C - NSTRT AND NSTOP DEFINE A PSUEDO-DIAMETER OF THIS COMPONENT +C OF THE GRAPH +C +C .. Scalar Arguments .. + INTEGER N,NNZ,NODES,NSTOP,NSTRT +C .. +C .. Array Arguments .. + INTEGER DEG(N),ICPTR(N+1),IRN(2*NNZ),LIST(N),LS(N),MASK(N), + + XLS(N+1) +C .. +C .. Local Scalars .. + INTEGER DEGREE,I,ID1,ID2,ISTOP,ISTRT,LSIZE,LWIDTH,MAXDEP,MINDEG, + + MINWID,NLSIZE,NLVL,NODE +C .. +C .. External Subroutines .. + EXTERNAL MC40GD,MC40HD +C .. +C CHOOSE FIRST GUESS FOR STARTING NODE BY MIN DEGREE +C IGNORE NODES THAT ARE INVISIBLE (MASK NE 1) +C + MINDEG = N + DO 10 I = 1,N + IF (MASK(I).EQ.1) THEN + DEGREE = ICPTR(I+1) - ICPTR(I) + IF (DEGREE.LT.MINDEG) THEN + NSTRT = I + MINDEG = DEGREE + END IF + + END IF + + 10 CONTINUE +C +C GENERATE LEVEL STRUCTURE FOR NODE WITH MIN DEGREE +C + CALL MC40GD(NSTRT,N,N,NNZ,IRN,ICPTR,MASK,LS,XLS,MAXDEP,LWIDTH) +C +C STORE NUMBER OF NODES IN THIS COMPONENT +C + NODES = XLS(MAXDEP+1) - 1 +C +C ITERATE TO FIND START AND END NODES +C + 20 CONTINUE +C +C STORE DEGREES OF NODES THAT ARE AT MAX DISTANCE FROM STARTING NODE +C + ISTRT = XLS(MAXDEP) + ISTOP = XLS(MAXDEP+1) - 1 + DO 30 I = ISTRT,ISTOP + NODE = LS(I) + DEG(NODE) = ICPTR(NODE+1) - ICPTR(NODE) + 30 CONTINUE +C +C SORT LIST OF NODES IN ASCENDING SEQUENCE OF THEIR DEGREE +C USE INSERTION SORT ALGORITHM (HOULSBY AND SLOAN) +C + LSIZE = ISTOP - ISTRT + 1 + IF (LSIZE.GT.1) CALL MC40HD(N,LSIZE,LS(ISTRT),DEG) +C******* +C STORE THE SORTED LIST +C + ISTRT = ISTRT - 1 +C LSIZE=(LSIZE/2)+1 + DO 40 I = 1,LSIZE + LIST(I) = LS(ISTRT+I) + 40 CONTINUE +C******* + ID1 = DEG(LIST(1)) + NLSIZE = 1 + DO 50 I = 2,LSIZE + ID2 = DEG(LIST(I)) + IF (ID2.NE.ID1) THEN + NLSIZE = NLSIZE + 1 + LIST(NLSIZE) = LIST(I) + END IF + + ID1 = ID2 + 50 CONTINUE +C********** +C +C LOOP OVER NODES IN LIST +C + MINWID = NODES + DO 60 I = 1,NLSIZE + NODE = LIST(I) +C +C FORM ROOTED LEVEL STRUCTURES FOR EACH NODE IN LIST +C + CALL MC40GD(NODE,MINWID,N,NNZ,IRN,ICPTR,MASK,LS,XLS,NLVL, + + LWIDTH) + IF (NLVL.GT.MAXDEP .AND. LWIDTH.LT.MINWID) THEN +C +C LEVEL STRUCTURE OF GREATER DEPTH FOUND +C STORE ROOT NODE AS STARTING NODE, NEW MAX DEPTH, AND BEGIN +C A NEW ITERATION +C + NSTRT = NODE + MAXDEP = NLVL + GO TO 20 + + ELSE IF (LWIDTH.LT.MINWID) THEN +C +C LEVEL STRUCTURE WIDTH FOR THIS END NODE IS SMALLEST +C ENCOUNTERED SO FAR +C STORE END NODE AND NEW MIN WIDTH +C + NSTOP = NODE + MINWID = LWIDTH + END IF + + 60 CONTINUE +C + RETURN + + END +C + SUBROUTINE MC40DD(N,NNZ,ROOT,NODES,IRN,ICPTR,MASK,LS,XLS) +C +C ASSEMBLE LIST OF NODES IN SAME COMPONENT AS ROOT NODE +C COMPUTE DISTANCES OF THESE NODES FROM ROOT NODE +C +C N,NNZ - SEE MC40AD. +C ROOT - THE ROOT NODE +C NODES - THE NUMBER OF NODES IN SAME COMPONENT AS ROOT +C IRN - ADJACENCY LIST FOR ALL NODES IN GRAPH +C ICPTR - LIST OF POINTERS TO IRN +C MASK - MASKING VECTOR OF LENGTH N FOR GRAPH +C - VISIBLE NODES HAVE MASK = 1 +C - ON EXIT HOLDS DISTANCES OF NODES IN THIS COMPONENT FROM ROOT. +C - THE DISTANCE OF NODE I IS GIVEN BY MASK(I) +C LS - LENGTH NODES. NOT SET ON ENTRY. +C ON EXIT HOLDS ROOTED LEVEL STRUCTURE, +C (I.E. A LIST OF NODES IN THE SAME COMPONENT AS ROOT) +C XLS - LENGTH NODES+1. NOT SET ON ENTRY. ON EXIT HOLDS +C LIST OF POINTERS TO LS +C - NODES IN LEVEL I ARE FOUND IN LS(J), WHERE +C J = XLS(I), XLS(I)+1, ..., XLS(I+1)-1 +C +C .. Scalar Arguments .. + INTEGER N,NNZ,NODES,ROOT +C .. +C .. Array Arguments .. + INTEGER ICPTR(N+1),IRN(2*NNZ),LS(NODES),MASK(N),XLS(NODES+1) +C .. +C .. Local Scalars .. + INTEGER I,J,JSTOP,JSTRT,LWIDTH,NLVL +C .. +C .. External Subroutines .. + EXTERNAL MC40GD +C .. +C GENERATE LEVEL STRUCTURE FOR ROOT NODE + CALL MC40GD(ROOT,NODES,N,NNZ,IRN,ICPTR,MASK,LS,XLS,NLVL,LWIDTH) +C +C STORE DISTANCES OF EACH NODE FROM ROOT NODE +C + DO 20 I = 1,NLVL + JSTRT = XLS(I) + JSTOP = XLS(I+1) - 1 + DO 10 J = JSTRT,JSTOP + MASK(LS(J)) = I - 1 + 10 CONTINUE + 20 CONTINUE +C + RETURN + + END +C + SUBROUTINE MC40ED(N,NNZ,NODES,NSTRT,LSTNUM,IRN,ICPTR,STATUS,NLIST, + + QUEUE,PRIOR) +C +C RENUMBER NODES IN COMPONENT OF GRAPH FOR SMALL WAVEFRONT AND +C PROFILE +C +C INPUT: +C ------ +C +C NODES - NUMBER OF NODES IN COMPONENT OF GRAPH +C NSTRT - NUMBER OF NODE FOR STARTING RENUMBERING +C LSTNUM - NUMBER OF NODES WHICH HAVE ALREADY BEEN RENUMBERED +C IRN - ADJACENCY LIST FOR ALL NODES IN GRAPH +C ICPTR - LIST OF POINTERS TO IRN +C STATUS - LIST GIVING THE DISTANCE OF EACH NODE IN THIS +C COMPONENT FROM THE END NODE +C - IF NODE I IS IN THIS COMPONENT, THE DISTANCE OF +C NODE I FROM THE END NODE IS GIVEN BY STATUS(I) +C - IF NODE I IS IN A COMPONENT WHICH HAS ALREADY BEEN +C RENUMBERED, THEN THE NEW NODE NUMBER FOR NODE I IS +C GIVEN BY -STATUS(I) +C - IF NODE I IS NOT IN THIS COMPONENT, AND THE COMPONENT +C IS YET TO BE RENUMBERED, THEN STATUS(I)=1 +C - LIST OF LENGTH N WHERE N IS THE TOTAL NUMBER +C OF NODES IN THE GRAPH +C NLIST - LIST OF NODES WHICH ARE IN THIS COMPONENT +C - LIST OF LENGTH NODES +C QUEUE - QUEUE OF NODES WHICH ARE CURRENTLY ACTIVE OR PREACTIVE +C - LIST OF MAX LENGTH NODES-1 +C - NOT DEFINED WHEN CALLING ROUTINE +C PRIOR - LIST OF PRIORITIES FOR EACH NODE +C - FOR NODE I WHICH IS CURRENTLY IN QUEUE, THE +C PRIORITY OF NODE I IS GIVEN BY PRIOR(I) +C - LIST OF LENGTH N, WHERE N IS THE TOTAL NUMBER +C OF NODES IN THE GRAPH +C - NOT DEFINED WHEN CALLING ROUTINE +C +C OUTPUT: +C ------- +C +C NODES - UNCHANGED +C NSTRT - UNCHANGED +C LSTNUM - NUMBER OF NODES WHICH HAVE BEEN RENUMBERED +C (INPUT VALUE INCREMENTED BY NODES) +C IRN - UNCHANGED +C ICPTR - UNCHANGED +C STATUS - LIST GIVING THE NEW NODE NUMBERS FOR NODES WHICH +C HAVE BEEN RENUMBERED +C - NEW NUMBER FOR NODE I IS -STATUS(I) +C NLIST - NOT USED +C QUEUE - NOT USED +C PRIOR - NOT USED +C NOTES: +C ------ +C +C - NLIST AND QUEUE MAY OCCUPY SAME SPACE +C - STATUS ALSO SERVES AS A LIST GIVING THE STATUS OF THE NODES +C DURING THE RENUMBERING PROCESS: +C STATUS(I) LT 0 INDICATES NODE I IS POSTACTIVE +C STATUS(I) = 0 INDICATES NODE I IS CURRENTLY ACTIVE +C STATUS(I) = 1 INDICATES NODE I IS PREACTIVE +C STATUS(I) = 2 INDICATES NODE I IS INACTIVE +C +C .. Parameters .. + INTEGER W1,W2 + PARAMETER (W1=2,W2=1) +C .. +C .. Scalar Arguments .. + INTEGER LSTNUM,N,NNZ,NODES,NSTRT +C .. +C .. Array Arguments .. + INTEGER ICPTR(N+1),IRN(2*NNZ),NLIST(NODES),PRIOR(N),QUEUE(NODES), + + STATUS(N) +C .. +C .. Local Scalars .. + INTEGER ADDRES,DEGREE,I,ISTOP,ISTRT,J,JSTOP,JSTRT,MAXDEG,MAXPRT, + + NABOR,NBR,NEXT,NODE,NQ,PRTY,STANAB +C .. +C MAX CURRENT DEGREE FOR ANY GRAPH WITH N NODES IS N + MAXDEG = NODES +C +C INITIALISE PRIORITIES AND STATUS FOR EACH NODE IN THIS COMPONENT +C INITIAL PRIORITY = W1*(MAXDEG-DEGREE) + W2*DIST +C WHERE: +C W1 = A POSITIVE WEIGHT +C W2 = A POSITIVE WEIGHT +C MAXDEG = MAX CURRENT DEGREE FOR ANY NODE IN GRAPH +C DEGREE = INITIAL CURRENT DEGREE FOR NODE +C DIST = DISTANCE OF NODE FROM END NODE +C INITIAL STATUS FOR ALL NODES IN THIS COMPONENT = 2 +C + DO 10 I = 1,NODES + NODE = NLIST(I) + DEGREE = ICPTR(NODE+1) - ICPTR(NODE) + 1 + PRIOR(NODE) = W1* (MAXDEG-DEGREE) + W2*STATUS(NODE) + STATUS(NODE) = 2 + 10 CONTINUE +C +C INSERT STARTING NODE IN QUEUE +C ASSIGN IT A PREACTIVE STATUS +C NQ IS THE SIZE OF QUEUE +C + NQ = 1 + QUEUE(NQ) = NSTRT + STATUS(NSTRT) = 1 +C +C LOOP WHILE QUEUE IS NOT EMPTY +C + 20 IF (NQ.GT.0) THEN +C +C LOOP OVER EACH NODE IN QUEUE +C PICK NODE WITH MAX PRIORITY +C + MAXPRT = -1 + DO 30 I = 1,NQ + PRTY = PRIOR(QUEUE(I)) + IF (PRTY.GT.MAXPRT) THEN + ADDRES = I + MAXPRT = PRTY + END IF + + 30 CONTINUE +C +C NEXT IS THE NEXT NODE TO BE RENUMBERED +C + NEXT = QUEUE(ADDRES) +C +C DELETE NODE NEXT FROM QUEUE +C + QUEUE(ADDRES) = QUEUE(NQ) + NQ = NQ - 1 + ISTRT = ICPTR(NEXT) + ISTOP = ICPTR(NEXT+1) - 1 + IF (STATUS(NEXT).EQ.1) THEN +C +C NODE NEXT IS PREACTIVE +C EXAMINE NEIGHBOURS OF NEXT +C + DO 40 I = ISTRT,ISTOP +C +C DECREASE CURRENT DEGREE OF NEIGHBOUR BY -1 +C + NBR = IRN(I) + PRIOR(NBR) = PRIOR(NBR) + W1 +C +C ADD NEIGHBOUR TO QUEUE IF IT IS INACTIVE +C ASSIGN IT A PREACTIVE STATUS +C + IF (STATUS(NBR).EQ.2) THEN + NQ = NQ + 1 + QUEUE(NQ) = NBR + STATUS(NBR) = 1 + END IF + + 40 CONTINUE + END IF +C +C STORE -VE OF NEW NODE NUMBER FOR NODE NEXT +C STATUS FOR NEXT IS NOW -LSTNUM +C + LSTNUM = LSTNUM + 1 + STATUS(NEXT) = -LSTNUM +C +C EXAMINE NEIGHBOURS OF NEXT +C + DO 60 I = ISTRT,ISTOP + NBR = IRN(I) +C +C SKIP TO NEXT NEIGHBOUR IF NBR IS NOT PREACTIVE +C + IF (STATUS(NBR).EQ.1) THEN +C +C NEIGHBOUR IS CURRENTLY PREACTIVE +C DECREASE ITS CURRENT DEGREE BY -1 +C ASSIGN IT AN ACTIVE STATUS +C + PRIOR(NBR) = PRIOR(NBR) + W1 + STATUS(NBR) = 0 +C +C LOOP OVER NODES ADJACENT TO NBR +C + JSTRT = ICPTR(NBR) + JSTOP = ICPTR(NBR+1) - 1 + DO 50 J = JSTRT,JSTOP + NABOR = IRN(J) + STANAB = STATUS(NABOR) + IF (STANAB.GE.0) THEN +C +C NABOR IS NOT POSTACTIVE +C DECREASE ITS CURRENT DEGREE BY -1 +C + PRIOR(NABOR) = PRIOR(NABOR) + W1 + IF (STANAB.EQ.2) THEN +C +C NABOR IS CURRENTLY INACTIVE, BUT THIS NODE IS NOW +C ADJACENT TO A NEWLY ACTIVATED NODE +C INSERT NABOR IN QUEUE AND ASSIGN IT A PREACTIVE +C STATUS +C + NQ = NQ + 1 + QUEUE(NQ) = NABOR + STATUS(NABOR) = 1 + END IF + + END IF + + 50 CONTINUE + END IF + + 60 CONTINUE + GO TO 20 + + END IF +C + RETURN + + END +C + SUBROUTINE MC40FD(N,NNZ,IPERM,IRN,ICPTR,IPROF) +C +C COMPUTE THE PROFILES USING BOTH ORIGINAL AND NEW NODE NUMBERS +C +C INPUT: +C ------ +C N,NNZ - SEE MC40AD +C IPERM - LIST OF NEW NODE NUMBERS FOR GRAPH +C - NEW NODE NUMBER FOR NODE I IS GIVEN BY IPERM(I) +C - LIST OF LENGTH N +C IRN - ADJACENCY LIST FOR ALL NODES IN GRAPH +C ICPTR - LIST OF POINTERS TO IRN +C IPROF - NOT SET ON ENTRY +C +C OUTPUT: +C ------- +C N,NNZ - UNCHANGED +C IPERM - UNCHANGED +C IRN - UNCHANGED +C ICPTR - UNCHANGED +C IPROF(1) - PROFILE OF MATRIX FOR ORIGINAL ORDERING +C IPROF(2) - PROFILE OF MATRIX FOR NEW ORDERING +C +C NOTES: +C ------ +C - COMPUTED PROFILES INCLUDE DIAGONAL TERMS +C +C .. Scalar Arguments .. + INTEGER N,NNZ +C .. +C .. Array Arguments .. + INTEGER ICPTR(N+1),IPERM(N),IPROF(2),IRN(2*NNZ) +C .. +C .. Local Scalars .. + INTEGER I,J,JSTOP,JSTRT,K1,NEWMIN,OLDMIN +C .. +C .. Intrinsic Functions .. + INTRINSIC DIM,MIN +C .. +C INITIALISE PROFILES TO ZERO + DO 10 I = 1,2 + IPROF(I) = 0 + 10 CONTINUE +C +C LOOP OVER NODES IN GRAPH +C + DO 30 I = 1,N + JSTRT = ICPTR(I) + JSTOP = ICPTR(I+1) - 1 + OLDMIN = I + NEWMIN = IPERM(I) +C +C FIND LOWEST NUMBERED NEIGHBOUR OF NODE I +C (USING BOTH OLD AND NEW NODE NUMBERS) +C + DO 20 J = JSTRT,JSTOP + K1 = IRN(J) + OLDMIN = MIN(OLDMIN,K1) + NEWMIN = MIN(NEWMIN,IPERM(K1)) + 20 CONTINUE +C +C CONTRIBUTION TO PROFILE IS POSITIVE DIFFERENCE BETWEEN +C NODE NUMBER FOR NODE I AND LOWEST NUMBERED NEIGHBOUR +C + IPROF(1) = IPROF(1) + DIM(I,OLDMIN) + IPROF(2) = IPROF(2) + DIM(IPERM(I),NEWMIN) + 30 CONTINUE +C +C ADD DIAGONAL TERMS TO PROFILES +C + DO 40 I = 1,2 + IPROF(I) = IPROF(I) + N + 40 CONTINUE +C + RETURN + + END +C + SUBROUTINE MC40GD(ROOT,MAXWID,N,NNZ,IRN,ICPTR,MASK,LS,XLS,NLVL, + + LWIDTH) +C +C GENERATE ROOTED LEVEL STRUCTURE USING A FORTRAN 77 IMPLEMENTATION +C OF THE ALGORITHM GIVEN BY GEORGE AND LUI +C +C INPUT: +C ------ +C ROOT - ROOT NODE FOR LEVEL STRUCTURE +C MAXWID - MAX PERMISSIBLE WIDTH OF ROOTED LEVEL STRUCTURE +C - ASSEMBLY OF LEVEL STRUCTURE ABORTED IF ANY LEVEL HAS +C WIDTH WHICH IS GE THIS VALUE +C - ASSEMBLY ENSURED BY SETTING MAXWID = NODES, WHERE +C NODES IS THE NUMBER OF NODES IN COMPONENT +C IRN - ADJACENCY LIST FOR ALL NODES IN GRAPH +C ICPTR - LIST OF POINTERS TO IRN +C MASK - MASKING VECTOR FOR GRAPH +C - VISIBLE NODES HAVE MASK = 1 +C - LIST OF LENGTH N, WHERE N IS THE TOTAL +C NUMBER OF NODES IN THE GRAPH +C LS - NOT SET +C XLS - NOT SET +C NLVL - NOT SET +C LWIDTH - NOT SET +C +C OUTPUT: +C ------- +C ROOT - UNCHANGED +C MAXWID - UNCHANGED +C IRN - UNCHANGED +C ICPTR - UNCHANGED +C MASK - UNCHANGED +C LS - LIST CONTAINING A ROOTED LEVEL STRUCTURE +C - LIST OF LENGTH NODES +C XLS - LIST OF POINTERS TO LS +C - NODES IN LEVEL I ARE FOUND IN LS(J), WHERE +C J = XLS(I), XLS(I)+1, ..., XLS(I+1)-1 +C - LIST OF MAX LENGTH NODES+1 +C NLVL - NUMBER OF LEVELS IN ROOTED LEVEL STRUCTURE +C LWIDTH - WIDTH OF ROOTED LEVEL STRUCTURE +C +C .. Scalar Arguments .. + INTEGER LWIDTH,MAXWID,N,NLVL,NNZ,ROOT +C .. +C .. Array Arguments .. + INTEGER ICPTR(N+1),IRN(2*NNZ),LS(N),MASK(N),XLS(N+1) +C .. +C .. Local Scalars .. + INTEGER I,J,JSTOP,JSTRT,LBEGIN,LNBR,LVLEND,LVSIZE,NBR,NODE +C .. +C .. Intrinsic Functions .. + INTRINSIC MAX +C .. +C INITIALISATION +C + MASK(ROOT) = 0 + LS(1) = ROOT + NLVL = 0 + LVLEND = 0 + LNBR = 1 + LWIDTH = 1 + LVSIZE = 1 + 10 IF (LVSIZE.GT.0) THEN + LWIDTH = MAX(LVSIZE,LWIDTH) +C +C ABORT CONSTRUCTION IF LEVEL STRUCTURE HAS WIDTH GE MAXWID +C + IF (LWIDTH.GE.MAXWID) THEN + GO TO 40 + + END IF +C +C LBEGIN POINTS TO BEGINNING OF PRESENT LEVEL +C LVLEND POINTS TO END OF PRESENT LEVEL +C + LBEGIN = LVLEND + 1 + LVLEND = LNBR + NLVL = NLVL + 1 + XLS(NLVL) = LBEGIN +C +C GENERATE NEXT LEVEL BY FINDING ALL UNMASKED NEIGHBOURS +C OF NODES IN PRESENT LEVEL +C + DO 30 I = LBEGIN,LVLEND + NODE = LS(I) + JSTRT = ICPTR(NODE) + JSTOP = ICPTR(NODE+1) - 1 + DO 20 J = JSTRT,JSTOP + NBR = IRN(J) + IF (MASK(NBR).EQ.1) THEN + LNBR = LNBR + 1 + LS(LNBR) = NBR + MASK(NBR) = 0 + END IF + + 20 CONTINUE + 30 CONTINUE + LVSIZE = LNBR - LVLEND + GO TO 10 + + END IF + + XLS(NLVL+1) = LVLEND + 1 +C +C RESET MASK=1 FOR NODES IN THE LEVEL STRUCTURE +C + 40 CONTINUE + DO 50 I = 1,LNBR + MASK(LS(I)) = 1 + 50 CONTINUE +C + RETURN + + END +C + SUBROUTINE MC40HD(N,NL,LIST,KEY) +C +C ORDER A LIST OF INTEGERS IN ASCENDING SEQUENCE OF THEIR KEYS +C +C INPUT: +C ------ +C N,NL - INTEGERS GIVING LENGTH OF KEY AND LIST +C LIST - A LIST OF LENGTH NL OF INTEGERS +C KEY - A LIST OF LENGTH N OF INTEGER KEYS +C +C OUTPUT: +C ------- +C N,NL - UNCHANGED +C LIST - A LIST INTEGERS SORTED IN ASCENDING +C SEQUENCE OF THEIR INTEGER KEYS +C KEY - UNCHANGED +C +C NOTES: +C ------ +C +C - USES INSERTION SORT +C - EFFICIENT ONLY FOR N VALUES LESS THAN ABOUT 12 (ALTHOUGH +C MAY BE SYSTEM DEPENDENT) AS DISCUSSED IN HOULSBY AND SLOAN + +C .. Scalar Arguments .. + INTEGER N,NL +C .. +C .. Array Arguments .. + INTEGER KEY(N),LIST(NL) +C .. +C .. Local Scalars .. + INTEGER I,J,K,VALUE +C .. +C FIND INTEGER WITH SMALLEST KEY AND PUT IT AT HEAD OF LIST + J = 1 + K = LIST(1) + VALUE = KEY(K) + DO 10 I = 2,NL + IF (KEY(LIST(I)).LT.VALUE) THEN + J = I + VALUE = KEY(LIST(I)) + END IF + + 10 CONTINUE + LIST(1) = LIST(J) + LIST(J) = K +C +C CARRY OUT INSERTION SORT +C + DO 30 I = 2,NL + J = I + K = LIST(I) + VALUE = KEY(K) + 20 IF (VALUE.LT.KEY(LIST(J-1))) THEN + LIST(J) = LIST(J-1) + J = J - 1 + GO TO 20 + + END IF + + LIST(J) = K + 30 CONTINUE + END +C + BLOCK DATA MC40KD +C .. Scalars in Common .. + INTEGER LP,MP +C .. +C .. Common blocks .. + COMMON /MC40ID/LP,MP +C .. +C .. Save statement .. + SAVE /MC40ID/ +C .. +C .. Data statements .. + DATA LP/6/,MP/6/ +C .. + END diff --git a/src/Libraries/hsl/mc40ad.f b/src/Libraries/hsl/mc40ad.f deleted file mode 100644 index 2500e4fa..00000000 --- a/src/Libraries/hsl/mc40ad.f +++ /dev/null @@ -1,436 +0,0 @@ -* ******************************************************************* -* COPYRIGHT (c) 1988 Hyprotech UK -* All rights reserved. -* -* None of the comments in this Copyright notice between the lines -* of asterisks shall be removed or altered in any way. -* -* This Package is intended for compilation without modification, -* so most of the embedded comments have been removed. -* -* ALL USE IS SUBJECT TO LICENCE. For full details of an HSL ARCHIVE -* Licence, see http://hsl.rl.ac.uk/archive/cou.html -* -* Please note that for an HSL ARCHIVE Licence: -* -* 1. The Package must not be copied for use by any other person. -* Supply of any part of the library by the Licensee to a third party -* shall be subject to prior written agreement between AEA -* Hyprotech UK Limited and the Licensee on suitable terms and -* conditions, which will include financial conditions. -* 2. All information on the Package is provided to the Licensee on the -* understanding that the details thereof are confidential. -* 3. All publications issued by the Licensee that include results obtained -* with the help of one or more of the Packages shall acknowledge the -* use of the Packages. The Licensee will notify the Numerical Analysis -* Group at Rutherford Appleton Laboratory of any such publication. -* 4. The Packages may be modified by or on behalf of the Licensee -* for such use in research applications but at no time shall such -* Packages or modifications thereof become the property of the -* Licensee. The Licensee shall make available free of charge to the -* copyright holder for any purpose all information relating to -* any modification. -* 5. Neither CCLRC nor Hyprotech UK Limited shall be liable for any -* direct or consequential loss or damage whatsoever arising out of -* the use of Packages by the Licensee. -* ******************************************************************* -* -*######DATE 21 Sept 1994 -C -C - SUBROUTINE MC40AD(ITYPE,N,NNZ,IRN,JCN,ICPTR,IPERM,IW,IPROF,IFLAG) - INTEGER IFLAG,ITYPE,N,NNZ - INTEGER ICPTR(N+1),IPERM(N),IPROF(2),IRN(2*NNZ),IW(3*N+2),JCN(*) - INTEGER LP,MP - INTEGER I,IOUT,J,J1,JFLAG,KZ,L,NDIAG,OFDIAG - LOGICAL YESA - DOUBLE PRECISION A(1) - EXTERNAL MC34AD,MC49AD,MC40BD - EXTERNAL MC40KD - COMMON /MC40ID/LP,MP - SAVE /MC40ID/ - YESA = .FALSE. - IFLAG = 0 - IF (N.LT.1) THEN - IFLAG = -1 - IF (LP.GT.0) WRITE (LP,FMT=9000) IFLAG - RETURN - END IF - IF (NNZ.LT.0) THEN - IFLAG = -2 - IF (LP.GT.0) WRITE (LP,FMT=9000) IFLAG - RETURN - END IF - IF (ITYPE.NE.0 .AND. ITYPE.NE.1) THEN - IFLAG = -3 - IF (LP.GT.0) WRITE (LP,FMT=9000) IFLAG - RETURN - END IF - IF (N.EQ.1) THEN - IPROF(1) = 1 - IPROF(2) = 1 - IPERM(1) = 1 - RETURN - END IF - IF (NNZ.EQ.0) THEN - IPROF(1) = N - IPROF(2) = N - RETURN - END IF - DO 10 I = 1,3*N + 2 - IW(I) = 0 - 10 CONTINUE - KZ = 0 - IOUT = 0 - NDIAG = 0 - OFDIAG = 0 - IF (ITYPE.EQ.0) THEN - J1 = ICPTR(1) - ICPTR(1) = 1 - DO 30 L = 1,N - DO 20 J = J1,ICPTR(L+1) - 1 - I = IRN(J) - IF (I.GT.N .OR. I.LT.1) IOUT = IOUT + 1 - IF (I.EQ.L) NDIAG = NDIAG + 1 - IF (I.LT.L) OFDIAG = OFDIAG + 1 - IF (I.GT.L .AND. I.LE.N) THEN - KZ = KZ + 1 - IRN(KZ) = I - END IF - 20 CONTINUE - J1 = ICPTR(L+1) - ICPTR(L+1) = KZ + 1 - 30 CONTINUE - ELSE - DO 40 L = 1,NNZ - I = IRN(L) - J = JCN(L) - IF (I.GT.N .OR. I.LT.1) IOUT = IOUT + 1 - IF (J.GT.N .OR. J.LT.1) IOUT = IOUT + 1 - IF (I.EQ.J) NDIAG = NDIAG + 1 - IF (I.LT.J) OFDIAG = OFDIAG + 1 - IF (J.GE.1 .AND. I.GT.J .AND. I.LE.N) THEN - KZ = KZ + 1 - IRN(KZ) = I - JCN(KZ) = J - END IF - 40 CONTINUE - END IF - IF (IOUT.GT.0) THEN - IFLAG = 3 - ELSE IF (OFDIAG.GT.0) THEN - IFLAG = 2 - ELSE IF (NDIAG.GT.0) THEN - IFLAG = 1 - END IF - IF (IFLAG.GT.0 .AND. MP.GT.0) WRITE (MP,FMT=9010) IFLAG - IF (ITYPE.EQ.1) THEN - CALL MC49AD(-1,N,N,KZ,IRN,JCN,YESA,1,A,N+1,ICPTR,N+1, - + IW,JFLAG) - DO 50 I = 1,N - IW(I) = 0 - 50 CONTINUE - END IF - CALL MC34AD(N,IRN,ICPTR,YESA,A,IW) - DO 60 I = 1,N - IW(I) = 0 - 60 CONTINUE - CALL MC40BD(N,NNZ,IRN,ICPTR,IPERM,IW,IPROF) - RETURN - 9000 FORMAT (/,3X,'ERROR MESSAGE: IFLAG = ',I2) - 9010 FORMAT (/,3X,'WARNING MESSAGE : IFLAG =',I2) - END - SUBROUTINE MC40BD(N,NNZ,IRN,ICPTR,IPERM,IW,IPROF) - INTEGER N,NNZ - INTEGER ICPTR(N+1),IPERM(N),IPROF(2),IRN(2*NNZ),IW(3*N+2) - INTEGER DEGREE,I,LSTNUM,N1,N2,N3,NODES,NSTOP,NSTRT - EXTERNAL MC40CD,MC40DD,MC40ED,MC40FD - DO 10 I = 1,N - IPERM(I) = 1 - 10 CONTINUE - LSTNUM = 0 - DO 20 I = 1,N - DEGREE = ICPTR(I+1) - ICPTR(I) - IF (DEGREE.EQ.0) THEN - LSTNUM = LSTNUM + 1 - IPERM(I) = -LSTNUM - END IF - 20 CONTINUE - 30 IF (LSTNUM.LT.N) THEN - N1 = 1 - N2 = N1 + N - LSTNUM - N3 = N2 + N + 1 - CALL MC40CD(N,NNZ,IRN,ICPTR,IPERM,IW(N1),IW(N2),IW(N2),IW(N3), - + NSTRT,NSTOP,NODES) - N2 = N1 + NODES - N3 = N2 + NODES + 1 - CALL MC40DD(N,NNZ,NSTOP,NODES,IRN,ICPTR,IPERM,IW(N1),IW(N2)) - N3 = N2 + N - CALL MC40ED(N,NNZ,NODES,NSTRT,LSTNUM,IRN,ICPTR,IPERM,IW(N1), - + IW(N1),IW(N2)) - GO TO 30 - END IF - DO 40 I = 1,N - IPERM(I) = -IPERM(I) - 40 CONTINUE - CALL MC40FD(N,NNZ,IPERM,IRN,ICPTR,IPROF) - IF (IPROF(2).GE.IPROF(1)) THEN - DO 50 I = 1,N - IPERM(I) = I - 50 CONTINUE - IPROF(2) = IPROF(1) - END IF - RETURN - END - SUBROUTINE MC40CD(N,NNZ,IRN,ICPTR,MASK,LS,XLS,DEG,LIST,NSTRT, - + NSTOP,NODES) - INTEGER N,NNZ,NODES,NSTOP,NSTRT - INTEGER DEG(N),ICPTR(N+1),IRN(2*NNZ),LIST(N),LS(N),MASK(N), - + XLS(N+1) - INTEGER DEGREE,I,ID1,ID2,ISTOP,ISTRT,LSIZE,LWIDTH,MAXDEP,MINDEG, - + MINWID,NLSIZE,NLVL,NODE - EXTERNAL MC40GD,MC40HD - MINDEG = N - DO 10 I = 1,N - IF (MASK(I).EQ.1) THEN - DEGREE = ICPTR(I+1) - ICPTR(I) - IF (DEGREE.LT.MINDEG) THEN - NSTRT = I - MINDEG = DEGREE - END IF - END IF - 10 CONTINUE - CALL MC40GD(NSTRT,N,N,NNZ,IRN,ICPTR,MASK,LS,XLS,MAXDEP,LWIDTH) - NODES = XLS(MAXDEP+1) - 1 - 20 CONTINUE - ISTRT = XLS(MAXDEP) - ISTOP = XLS(MAXDEP+1) - 1 - DO 30 I = ISTRT,ISTOP - NODE = LS(I) - DEG(NODE) = ICPTR(NODE+1) - ICPTR(NODE) - 30 CONTINUE - LSIZE = ISTOP - ISTRT + 1 - IF (LSIZE.GT.1) CALL MC40HD(N,LSIZE,LS(ISTRT),DEG) -C******* - ISTRT = ISTRT - 1 - DO 40 I = 1,LSIZE - LIST(I) = LS(ISTRT+I) - 40 CONTINUE -C******* - ID1 = DEG(LIST(1)) - NLSIZE = 1 - DO 50 I = 2,LSIZE - ID2 = DEG(LIST(I)) - IF (ID2.NE.ID1) THEN - NLSIZE = NLSIZE + 1 - LIST(NLSIZE) = LIST(I) - END IF - ID1 = ID2 - 50 CONTINUE -C********** - MINWID = NODES - DO 60 I = 1,NLSIZE - NODE = LIST(I) - CALL MC40GD(NODE,MINWID,N,NNZ,IRN,ICPTR,MASK,LS,XLS,NLVL, - + LWIDTH) - IF (NLVL.GT.MAXDEP .AND. LWIDTH.LT.MINWID) THEN - NSTRT = NODE - MAXDEP = NLVL - GO TO 20 - ELSE IF (LWIDTH.LT.MINWID) THEN - NSTOP = NODE - MINWID = LWIDTH - END IF - 60 CONTINUE - RETURN - END - SUBROUTINE MC40DD(N,NNZ,ROOT,NODES,IRN,ICPTR,MASK,LS,XLS) - INTEGER N,NNZ,NODES,ROOT - INTEGER ICPTR(N+1),IRN(2*NNZ),LS(NODES),MASK(N),XLS(NODES+1) - INTEGER I,J,JSTOP,JSTRT,LWIDTH,NLVL - EXTERNAL MC40GD - CALL MC40GD(ROOT,NODES,N,NNZ,IRN,ICPTR,MASK,LS,XLS,NLVL,LWIDTH) - DO 20 I = 1,NLVL - JSTRT = XLS(I) - JSTOP = XLS(I+1) - 1 - DO 10 J = JSTRT,JSTOP - MASK(LS(J)) = I - 1 - 10 CONTINUE - 20 CONTINUE - RETURN - END - SUBROUTINE MC40ED(N,NNZ,NODES,NSTRT,LSTNUM,IRN,ICPTR,STATUS,NLIST, - + QUEUE,PRIOR) - INTEGER W1,W2 - PARAMETER (W1=2,W2=1) - INTEGER LSTNUM,N,NNZ,NODES,NSTRT - INTEGER ICPTR(N+1),IRN(2*NNZ),NLIST(NODES),PRIOR(N),QUEUE(NODES), - + STATUS(N) - INTEGER ADDRES,DEGREE,I,ISTOP,ISTRT,J,JSTOP,JSTRT,MAXDEG,MAXPRT, - + NABOR,NBR,NEXT,NODE,NQ,PRTY,STANAB - MAXDEG = NODES - DO 10 I = 1,NODES - NODE = NLIST(I) - DEGREE = ICPTR(NODE+1) - ICPTR(NODE) + 1 - PRIOR(NODE) = W1* (MAXDEG-DEGREE) + W2*STATUS(NODE) - STATUS(NODE) = 2 - 10 CONTINUE - NQ = 1 - QUEUE(NQ) = NSTRT - STATUS(NSTRT) = 1 - 20 IF (NQ.GT.0) THEN - MAXPRT = -1 - DO 30 I = 1,NQ - PRTY = PRIOR(QUEUE(I)) - IF (PRTY.GT.MAXPRT) THEN - ADDRES = I - MAXPRT = PRTY - END IF - 30 CONTINUE - NEXT = QUEUE(ADDRES) - QUEUE(ADDRES) = QUEUE(NQ) - NQ = NQ - 1 - ISTRT = ICPTR(NEXT) - ISTOP = ICPTR(NEXT+1) - 1 - IF (STATUS(NEXT).EQ.1) THEN - DO 40 I = ISTRT,ISTOP - NBR = IRN(I) - PRIOR(NBR) = PRIOR(NBR) + W1 - IF (STATUS(NBR).EQ.2) THEN - NQ = NQ + 1 - QUEUE(NQ) = NBR - STATUS(NBR) = 1 - END IF - 40 CONTINUE - END IF - LSTNUM = LSTNUM + 1 - STATUS(NEXT) = -LSTNUM - DO 60 I = ISTRT,ISTOP - NBR = IRN(I) - IF (STATUS(NBR).EQ.1) THEN - PRIOR(NBR) = PRIOR(NBR) + W1 - STATUS(NBR) = 0 - JSTRT = ICPTR(NBR) - JSTOP = ICPTR(NBR+1) - 1 - DO 50 J = JSTRT,JSTOP - NABOR = IRN(J) - STANAB = STATUS(NABOR) - IF (STANAB.GE.0) THEN - PRIOR(NABOR) = PRIOR(NABOR) + W1 - IF (STANAB.EQ.2) THEN - NQ = NQ + 1 - QUEUE(NQ) = NABOR - STATUS(NABOR) = 1 - END IF - END IF - 50 CONTINUE - END IF - 60 CONTINUE - GO TO 20 - END IF - RETURN - END - SUBROUTINE MC40FD(N,NNZ,IPERM,IRN,ICPTR,IPROF) - INTEGER N,NNZ - INTEGER ICPTR(N+1),IPERM(N),IPROF(2),IRN(2*NNZ) - INTEGER I,J,JSTOP,JSTRT,K1,NEWMIN,OLDMIN - INTRINSIC DIM,MIN - DO 10 I = 1,2 - IPROF(I) = 0 - 10 CONTINUE - DO 30 I = 1,N - JSTRT = ICPTR(I) - JSTOP = ICPTR(I+1) - 1 - OLDMIN = I - NEWMIN = IPERM(I) - DO 20 J = JSTRT,JSTOP - K1 = IRN(J) - OLDMIN = MIN(OLDMIN,K1) - NEWMIN = MIN(NEWMIN,IPERM(K1)) - 20 CONTINUE - IPROF(1) = IPROF(1) + DIM(I,OLDMIN) - IPROF(2) = IPROF(2) + DIM(IPERM(I),NEWMIN) - 30 CONTINUE - DO 40 I = 1,2 - IPROF(I) = IPROF(I) + N - 40 CONTINUE - RETURN - END - SUBROUTINE MC40GD(ROOT,MAXWID,N,NNZ,IRN,ICPTR,MASK,LS,XLS,NLVL, - + LWIDTH) - INTEGER LWIDTH,MAXWID,N,NLVL,NNZ,ROOT - INTEGER ICPTR(N+1),IRN(2*NNZ),LS(N),MASK(N),XLS(N+1) - INTEGER I,J,JSTOP,JSTRT,LBEGIN,LNBR,LVLEND,LVSIZE,NBR,NODE - INTRINSIC MAX - MASK(ROOT) = 0 - LS(1) = ROOT - NLVL = 0 - LVLEND = 0 - LNBR = 1 - LWIDTH = 1 - LVSIZE = 1 - 10 IF (LVSIZE.GT.0) THEN - LWIDTH = MAX(LVSIZE,LWIDTH) - IF (LWIDTH.GE.MAXWID) THEN - GO TO 40 - END IF - LBEGIN = LVLEND + 1 - LVLEND = LNBR - NLVL = NLVL + 1 - XLS(NLVL) = LBEGIN - DO 30 I = LBEGIN,LVLEND - NODE = LS(I) - JSTRT = ICPTR(NODE) - JSTOP = ICPTR(NODE+1) - 1 - DO 20 J = JSTRT,JSTOP - NBR = IRN(J) - IF (MASK(NBR).EQ.1) THEN - LNBR = LNBR + 1 - LS(LNBR) = NBR - MASK(NBR) = 0 - END IF - 20 CONTINUE - 30 CONTINUE - LVSIZE = LNBR - LVLEND - GO TO 10 - END IF - XLS(NLVL+1) = LVLEND + 1 - 40 CONTINUE - DO 50 I = 1,LNBR - MASK(LS(I)) = 1 - 50 CONTINUE - RETURN - END - SUBROUTINE MC40HD(N,NL,LIST,KEY) - INTEGER N,NL - INTEGER KEY(N),LIST(NL) - INTEGER I,J,K,VALUE - J = 1 - K = LIST(1) - VALUE = KEY(K) - DO 10 I = 2,NL - IF (KEY(LIST(I)).LT.VALUE) THEN - J = I - VALUE = KEY(LIST(I)) - END IF - 10 CONTINUE - LIST(1) = LIST(J) - LIST(J) = K - DO 30 I = 2,NL - J = I - K = LIST(I) - VALUE = KEY(K) - 20 IF (VALUE.LT.KEY(LIST(J-1))) THEN - LIST(J) = LIST(J-1) - J = J - 1 - GO TO 20 - END IF - LIST(J) = K - 30 CONTINUE - END - BLOCK DATA MC40KD - INTEGER LP,MP - COMMON /MC40ID/LP,MP - SAVE /MC40ID/ - DATA LP/6/,MP/6/ - END diff --git a/src/Libraries/hsl/mc43-1.0.0/doc/mc43_Fortran.pdf b/src/Libraries/hsl/mc43-1.0.0/doc/mc43_Fortran.pdf new file mode 100644 index 00000000..36161239 Binary files /dev/null and b/src/Libraries/hsl/mc43-1.0.0/doc/mc43_Fortran.pdf differ diff --git a/src/Libraries/hsl/mc43d.f b/src/Libraries/hsl/mc43-1.0.0/src/mc43d.f similarity index 100% rename from src/Libraries/hsl/mc43d.f rename to src/Libraries/hsl/mc43-1.0.0/src/mc43d.f diff --git a/src/Libraries/hsl/mc49-1.0.0/doc/mc49_Fortran.pdf b/src/Libraries/hsl/mc49-1.0.0/doc/mc49_Fortran.pdf new file mode 100644 index 00000000..e4d6d59c Binary files /dev/null and b/src/Libraries/hsl/mc49-1.0.0/doc/mc49_Fortran.pdf differ diff --git a/src/Libraries/hsl/mc49ad.f b/src/Libraries/hsl/mc49-1.0.0/src/mc49d.f similarity index 54% rename from src/Libraries/hsl/mc49ad.f rename to src/Libraries/hsl/mc49-1.0.0/src/mc49d.f index f9693481..9ecab282 100644 --- a/src/Libraries/hsl/mc49ad.f +++ b/src/Libraries/hsl/mc49-1.0.0/src/mc49d.f @@ -1,41 +1,5 @@ -* ******************************************************************* * COPYRIGHT (c) 1993 Council for the Central Laboratory * of the Research Councils -* All rights reserved. -* -* None of the comments in this Copyright notice between the lines -* of asterisks shall be removed or altered in any way. -* -* This Package is intended for compilation without modification, -* so most of the embedded comments have been removed. -* -* ALL USE IS SUBJECT TO LICENCE. For full details of an HSL ARCHIVE -* Licence, see http://hsl.rl.ac.uk/archive/cou.html -* -* Please note that for an HSL ARCHIVE Licence: -* -* 1. The Package must not be copied for use by any other person. -* Supply of any part of the library by the Licensee to a third party -* shall be subject to prior written agreement between AEA -* Hyprotech UK Limited and the Licensee on suitable terms and -* conditions, which will include financial conditions. -* 2. All information on the Package is provided to the Licensee on the -* understanding that the details thereof are confidential. -* 3. All publications issued by the Licensee that include results obtained -* with the help of one or more of the Packages shall acknowledge the -* use of the Packages. The Licensee will notify the Numerical Analysis -* Group at Rutherford Appleton Laboratory of any such publication. -* 4. The Packages may be modified by or on behalf of the Licensee -* for such use in research applications but at no time shall such -* Packages or modifications thereof become the property of the -* Licensee. The Licensee shall make available free of charge to the -* copyright holder for any purpose all information relating to -* any modification. -* 5. Neither CCLRC nor Hyprotech UK Limited shall be liable for any -* direct or consequential loss or damage whatsoever arising out of -* the use of Packages by the Licensee. -* ******************************************************************* -* *######DATE 21 Dec 1992 C Toolpack tool decs employed. C @@ -46,30 +10,111 @@ C SUBROUTINE MC49AD(IND,NC,NR,NNZ,IRN,JCN,YESA,LA,A,LIP,IP,LIW,IW, + IFLAG) +C +C TO SORT THE PATTERN OF A SPARSE MATRIX FROM ARBITARY ORDER TO +C COLUMN ORDER. AN OPTION EXISTS FOR ORDERING BY ROWS WITHIN EACH +C COLUMN. +C +C Argument list. * indicates changed on exit. +C IND - INTEGER VARIABLE +C - MUST BE SET TO -1,-2, 2, OR 1 ON ENTRY +C - IF IND=1 or -1 THE ORDERING WITHIN EACH COLUMN WILL BE +C ARBITRARY +C - IF IND=2 or -2 THE ORDERING WITHIN EACH COLUMN WILL BE BY ROWS +C - IF IND = 1 0R 2 THE USER-SUPPLIED DATA IS CHECKED. +C NC - INTEGER VARIABLE +C - MUST BE SET TO THE NUMBER OF COLUMNS IN THE MATRIX +C - RESTRICTION: NC.GE.1 +C NR - INTEGER VARIABLE +C - MUST BE SET TO THE NUMBER OF ROWS IN THE MATRIX +C - RESTRICTION: NR.GE.1 +C NNZ - INTEGER VARIABLE +C - MUST BE SET TO THE NUMBER OF NONZEROS IN THE MATRIX +C - RESTRICTION: NNZ.GE.1 +C *IRN - INTEGER ARRAY OF LENGTH NNZ +C - ON ENTRY SET TO CONTAIN THE ROW INDICES OF THE NONZEROS +C IN ARBITARY ORDER. +C - ON EXIT, IRN IS REORDERED SO THAT THE ROW INDICES +C FOR COLUMN 1 PRECEDE THOSE FOR COLUMN 2 AND SO ON. +C - IF IND=0 THE ORDER WITHIN COLUMNS IS ARBITRARY. +C - IF IND=1 THE ORDER WITHIN COLUMNS IS BY ROWS. +C *JCN - INTEGER ARRAY OF LENGTH NNZ +C - ON ENTRY SET TO CONTAIN THE COLUMN INDICES OF THE NONZEROS +C - JCN(K) MUST BE THE COLUMN INDEX OF +C THE ENTRY IN IRN(K) +C YESA - LOGICAL VARIABLE +C - IF YESA IS SET TO .FALSE., THE ARRAY A IS NOT ACCESSED. +C LA - INTEGER VARIABLE WHICH MUST BE SET TO THE LENGTH OF THE +C ARRAY A. IF YESA=.TRUE. LA MUST BE AT LEAST NNZ, AND +C IF YESA=.FALSE. LA MUST BE AT LEAST 1. +C *A - REAL (DOUBLE PRECISION) ARRAY OF LENGTH LA +C - IF YESA IS .TRUE., A(K) +C MUST BE SET TO THE VALUE OF THE ENTRY IN (IRN(K),JCN(K)) +C AND ON EXIT, THE ARRAY WILL HAVE BEEN PERMUTED IN THE SAME +C WAY AS IRN +C - IF YESA IS .FALSE. THE ARRAY IS NOT ACCESSED +C LIP - INTEGER VARIABLE WHICH DEFINES THE LENGTH OF THE ARRAY IP. +C - IF IND=1 OR -1 LIP MUST BE AT LEAST NC+1 +C - IF IND=2 OR -2 LIP MUST BE AT LEAST MAX(NR,NC)+1 +C *IP - INTEGER ARRAY OF LENGTH LIP +C - NOT SET ON ENTRY +C - ON EXIT, IP(J) CONTAINS THE POSITION IN IRN (AND A) OF THE +C FIRST ENTRY IN COLUMN J (J=1,...,NC) +C AND IP(NC+1) IS SET TO NNZ+1 +C LIW - INTEGER VARIABLE WHICH DEFINES THE LENGTH OF THE ARRAY IW +C - IF IND=1 OR -1 LIW MUST BE AT LEAST MAX(NR,NC)+1 +C - IF IND=2 OR -2 LIW MUST BE AT LEAST NR+1 +C *IW - INTEGER ARRAY OF LENGTH LIW +C - THE ARRAY IS USED AS WORKSPACE +C *IFLAG - INTEGER VARIABLE. NOT SET ON ENTRY. +C IF IND = 1 OR 2 ON SUCCESSFUL EXIT +C IFLAG=0 AND OTHER VALUES OF IFLAG INDICATE AN ERROR. +C +C .. Scalar Arguments .. INTEGER IFLAG,IND,LA,LIP,LIW,NC,NNZ,NR LOGICAL YESA +C .. +C .. Array Arguments .. DOUBLE PRECISION A(LA) INTEGER IP(LIP),IRN(NNZ),IW(LIW),JCN(NNZ) +C .. +C .. Local Scalars .. INTEGER I,J,K,KSTART,KSTOP,NZJ +C .. +C .. External Subroutines .. EXTERNAL MC49BD,MC49CD +C .. +C .. Data block external statement EXTERNAL MC49DD +C .. +C .. Intrinsic Functions .. INTRINSIC ABS,MAX +C .. +C .. Common blocks .. COMMON /MC49ED/LP,MP,IOUT,JOUT,IDUP,NZOUT INTEGER IDUP,IOUT,JOUT,LP,MP,NZOUT +C .. +C .. Save statement .. SAVE /MC49ED/ +C .. +C .. Executable Statements .. IFLAG = 0 NZOUT = 0 IOUT = 0 JOUT = 0 IDUP = 0 +C CHECK THE INPUT DATA IF (IND.GT.2 .OR. IND.LT.-2 .OR. IND.EQ.0) THEN IFLAG = -1 IF (LP.GT.0) THEN WRITE (LP,FMT=9000) IFLAG WRITE (LP,FMT=9010) IND END IF + GO TO 70 + END IF + IF (NC.LT.1 .OR. NR.LT.1 .OR. NNZ.LT.1) THEN IFLAG = -2 IF (LP.GT.0) THEN @@ -77,8 +122,11 @@ SUBROUTINE MC49AD(IND,NC,NR,NNZ,IRN,JCN,YESA,LA,A,LIP,IP,LIW,IW, WRITE (LP,FMT=9020) WRITE (LP,FMT=9030) NC,NR,NNZ END IF + GO TO 70 + END IF + IF (YESA) THEN IF (LA.LT.NNZ) THEN IFLAG = -3 @@ -86,8 +134,11 @@ SUBROUTINE MC49AD(IND,NC,NR,NNZ,IRN,JCN,YESA,LA,A,LIP,IP,LIW,IW, WRITE (LP,FMT=9000) IFLAG WRITE (LP,FMT=9040) LA,NNZ END IF + GO TO 70 + END IF + ELSE IF (LA.LT.1) THEN IFLAG = -3 @@ -95,56 +146,75 @@ SUBROUTINE MC49AD(IND,NC,NR,NNZ,IRN,JCN,YESA,LA,A,LIP,IP,LIW,IW, WRITE (LP,FMT=9000) IFLAG WRITE (LP,FMT=9050) LA END IF + GO TO 70 + END IF + END IF + IF (ABS(IND).EQ.1 .AND. LIW.LT.MAX(NR,NC)+1) THEN IFLAG = -4 IF (LP.GT.0) THEN WRITE (LP,FMT=9000) IFLAG WRITE (LP,FMT=9060) LIW,MAX(NR,NC) + 1 END IF + GO TO 70 + ELSE IF (ABS(IND).EQ.2 .AND. LIW.LT.NR+1) THEN IFLAG = -4 IF (LP.GT.0) THEN WRITE (LP,FMT=9000) IFLAG WRITE (LP,FMT=9060) LIW,NR + 1 END IF + GO TO 70 + END IF + IF (ABS(IND).EQ.1 .AND. LIP.LT.NC+1) THEN IFLAG = -5 IF (LP.GT.0) THEN WRITE (LP,FMT=9000) IFLAG WRITE (LP,FMT=9070) LIP,NC + 1 END IF + GO TO 70 + ELSE IF (ABS(IND).EQ.2 .AND. LIP.LT.MAX(NR,NC)+1) THEN IFLAG = -5 IF (LP.GT.0) THEN WRITE (LP,FMT=9000) IFLAG WRITE (LP,FMT=9070) LIP,MAX(NR,NC) + 1 END IF + GO TO 70 + END IF + IF (IND.LT.0) THEN NZOUT = NNZ GO TO 20 + END IF + DO 10 K = 1,NNZ I = IRN(K) J = JCN(K) IF (I.GT.NR .OR. I.LT.1) THEN IOUT = IOUT + 1 + ELSE IF (J.GT.NC .OR. J.LT.1) THEN JOUT = JOUT + 1 + ELSE NZOUT = NZOUT + 1 IRN(NZOUT) = I JCN(NZOUT) = J IF (YESA) A(NZOUT) = A(K) END IF + 10 CONTINUE IF (IOUT.GT.0) THEN IFLAG = 2 @@ -152,26 +222,44 @@ SUBROUTINE MC49AD(IND,NC,NR,NNZ,IRN,JCN,YESA,LA,A,LIP,IP,LIW,IW, WRITE (MP,FMT=9080) IFLAG WRITE (MP,FMT=9090) IOUT END IF + END IF + IF (JOUT.GT.0) THEN IFLAG = 3 IF (MP.GT.0) THEN WRITE (MP,FMT=9080) IFLAG WRITE (MP,FMT=9110) JOUT END IF + END IF + IF (IOUT+JOUT.EQ.NNZ) THEN NZOUT = 0 GO TO 70 + END IF + 20 CONTINUE +C +C NZOUT IS NOW THE NUMBER OF NONZERO ENTRIES +C IF ABS(IND)=1 ORDER DIRECTLY BY COLUMNS IF (ABS(IND).EQ.1) THEN CALL MC49BD(NC,NZOUT,IRN,JCN,YESA,LA,A,IP,IW) + ELSE +C +C IF ABS(IND)=2 ORDER FIRST ORDER BY ROWS +C CALL MC49BD(NR,NZOUT,JCN,IRN,YESA,LA,A,IW,IP) +C +C NOW ORDER BY COLUMNS AND BY ROWS WITHIN EACH COLUMN +C CALL MC49CD(NC,NR,NZOUT,IRN,JCN,YESA,LA,A,IP,IW) END IF + IF (IND.GT.0) THEN +C CHECK FOR DUPLICATES NZOUT = 0 KSTART = 1 NZJ = 0 @@ -189,10 +277,13 @@ SUBROUTINE MC49AD(IND,NC,NR,NNZ,IRN,JCN,YESA,LA,A,LIP,IP,LIW,IW, IF (YESA) A(NZOUT) = A(K) IP(J+1) = IP(J+1) + 1 IW(I) = NZOUT + ELSE +C WE HAVE A DUPLICATE IN COLUMN J IDUP = IDUP + 1 IF (YESA) A(IW(I)) = A(IW(I)) + A(K) END IF + 40 CONTINUE KSTART = KSTOP + 1 NZJ = NZOUT @@ -203,9 +294,13 @@ SUBROUTINE MC49AD(IND,NC,NR,NNZ,IRN,JCN,YESA,LA,A,LIP,IP,LIW,IW, WRITE (MP,FMT=9080) IFLAG WRITE (MP,FMT=9100) IDUP END IF + END IF + END IF + 70 RETURN + 9000 FORMAT (/,' *** ERROR RETURN FROM MC49A/AD *** IFLAG = ',I2) 9010 FORMAT (1X,'IND=',I2,' IS OUT OF RANGE') 9020 FORMAT (1X,'NC, NR, OR, NNZ IS OUT OF RANGE') @@ -220,15 +315,62 @@ SUBROUTINE MC49AD(IND,NC,NR,NNZ,IRN,JCN,YESA,LA,A,LIP,IP,LIW,IW, 9100 FORMAT (1X,I6,' DUPLICATE ENTRIES WERE SUPPLIED BY THE USER') 9110 FORMAT (1X,I6,' ENTRIES IN JCN SUPPLIED BY THE USER WERE OUT OF ', + /,' RANGE AND WERE IGNORED BY THE ROUTINE') + END C*********************************************************************** SUBROUTINE MC49BD(NC,NNZ,IRN,JCN,YESA,LA,A,IP,IW) +C +C TO SORT THE PATTERN OF A SPARSE MATRIX FROM ARBITARY ORDER TO +C COLUMN ORDER, UNORDERED WITHIN EACH COLUMN. +C +C Argument list. * indicates changed on exit. +C +C NC - INTEGER VARIABLE +C - ON ENTRY MUST BE SET TO THE NUMBER OF COLUMNS IN THE MATRIX +C NNZ - INTEGER VARIABLE +C - ON ENTRY, MUST BE SET TO THE NUMBER OF NONZEROS IN THE MATRIX +C *IRN - INTEGER ARRAY OF LENGTH NNZ +C - ON ENTRY SET TO CONTAIN THE ROW INDICES OF THE NONZEROS +C IN ARBITARY ORDER. +C - ON EXIT, THE ENTRIES IN IRN ARE REORDERED SO THAT THE ROW +C INDICES FOR COLUMN 1 PRECEDE THOSE FOR COLUMN 2 AND SO ON, +C BUT THE ORDER WITHIN COLUMNS IS ARBITRARY. +C *JCN - INTEGER ARRAY OF LENGTH NNZ +C - ON ENTRY SET TO CONTAIN THE COLUMN INDICES OF THE NONZEROS +C - JCN(K) MUST BE THE COLUMN INDEX OF +C THE ENTRY IN IRN(K) +C - ON EXIT, JCN(K) IS THE COLUMN INDEX FOR THE ENTRY WITH +C ROW INDEX IRN(K) (K=1,...,NNZ). +C YESA - LOGICAL VARIABLE +C - IF YESA IS SET TO .FALSE., THE ARRAY A IS NOT ACCESSED. +C LA - INTEGER VARIABLE WHICH DEFINES THE LENGTH OF THE ARRAY A +C *A - REAL (DOUBLE PRECISION) ARRAY OF LENGTH LA +C - IF YESA IS .TRUE., THE ARRAY MUST BE OF LENGTH NNZ, AND A(K) +C MUST BE SET TO THE VALUE OF THE ENTRY IN (IRN(K), JCN(K)); +C ON EXIT A IS REORDERED IN THE SAME WAY AS IRN +C - IF YESA IS .FALSE. THE ARRAY IS NOT ACCESSED +C *IP - INTEGER ARRAY OF LENGTH NC+1 +C - NOT SET ON ENTRY +C - ON EXIT, IP(J) CONTAINS THE POSITION IN IRN (AND A) OF THE +C FIRST ENTRY IN COLUMN J (J=1,...,NC) +C - IP(NC+1) IS SET TO NNZ+1 +C *IW - INTEGER ARRAY OF LENGTH NC+1 +C - THE ARRAY IS USED AS WORKSPACE +C - ON EXIT IW(I)=IP(I) (SO IW(I) POINTS TO THE BEGINNING +C OF COLUMN I). +C .. Scalar Arguments .. INTEGER LA,NC,NNZ LOGICAL YESA +C .. +C .. Array Arguments .. DOUBLE PRECISION A(LA) INTEGER IP(NC+1),IRN(NNZ),IW(NC+1),JCN(NNZ) +C .. +C .. Local Scalars .. DOUBLE PRECISION ACE,ACEP INTEGER ICE,ICEP,J,JCE,JCEP,K,L,LOC +C .. +C .. Executable Statements .. DO 10 J = 1,NC + 1 IW(J) = 0 10 CONTINUE @@ -237,13 +379,20 @@ SUBROUTINE MC49BD(NC,NNZ,IRN,JCN,YESA,LA,A,IP,IW) J = JCN(K) IW(J) = IW(J) + 1 20 CONTINUE +C C** PUT INTO IP AND IW THE POSITIONS WHERE EACH COLUMN +C WOULD BEGIN IN A COMPRESSED COLLECTION WITH THE COLUMNS +C IN NATURAL ORDER. +C IP(1) = 1 DO 30 J = 2,NC + 1 IP(J) = IW(J-1) + IP(J-1) IW(J-1) = IP(J-1) 30 CONTINUE C****** REORDER THE ELEMENTS INTO COLUMN ORDER. +C FILL IN EACH COLUMN FROM THE FRONT, AND AS A NEW ENTRY IS PLACED +C IN COLUMN K INCREASE THE POINTER IW(K) BY ONE. +C IF (YESA) GO TO 80 DO 70 L = 1,NC DO 60 K = IW(L),IP(L+1) - 1 @@ -265,6 +414,7 @@ SUBROUTINE MC49BD(NC,NNZ,IRN,JCN,YESA,LA,A,IP,IW) 60 CONTINUE 70 CONTINUE GO TO 130 + 80 CONTINUE DO 120 L = 1,NC DO 110 K = IW(L),IP(L+1) - 1 @@ -292,29 +442,84 @@ SUBROUTINE MC49BD(NC,NNZ,IRN,JCN,YESA,LA,A,IP,IW) 120 CONTINUE 130 CONTINUE RETURN + END +C C********************************************************** SUBROUTINE MC49CD(NC,NR,NNZ,IRN,JCN,YESA,LA,A,IP,IW) +C +C TO SORT THE ENTRIES OF A SPARSE MATRIX STORED BY ROWS, +C UNORDERED WITHIN EACH ROW, TO ORDERING BY COLUMNS ,WITH +C ORDERING BY ROWS WITHIN EACH COLUMN. +C +C Argument list. * indicates changed on exit. +C +C NC - INTEGER VARIABLE +C - ON ENTRY MUST BE SET TO THE NUMBER OF COLUMNS IN THE MATRIX +C NR - INTEGER VARIABLE +C - ON ENTRY MUST BE SET TO THE NUMBER OF ROWS IN THE MATRIX +C NNZ - INTEGER VARIABLE +C - ON ENTRY MUST BE SET TO THE NUMBER OF NONZEROS IN THE MATRIX +C *IRN - INTEGER ARRAY OF LENGTH NNZ +C - NOT SET ON ENTRY. +C - ON EXIT IRN(K) CONTAINS THE ROW INDEX OF THE K TH ENTRY. +C - THE ENTRIES ARE ORDERED SO THAT THE ENTRIES IN COLUMN 1 +C PRECEDE THOSE IN COLUMN 2,... AND THE ORDER WITHIN COLUMNS +C IS BY ROWS. +C *JCN - INTEGER ARRAY OF LENGTH NNZ +C - ON ENTRY SET TO CONTAIN THE COLUMN INDICES OF THE NONZEROS +C ORDERED BY ROWS. +C - THE CONTENTS OF THIS ARRAY ARE DESTROYED +C YESA - LOGICAL VARIABLE +C - IF YESA IS SET TO .FALSE., THE ARRAY A IS NOT ACCESSED. +C LA - INTEGER VARIABLE WHICH DEFINES THE LENGTH OF THE ARRAY A +C *A - REAL (DOUBLE PRECISION) ARRAY OF LENGTH LA +C - IF YESA IS .TRUE., THE ARRAY MUST BE OF LENGTH NNZ, AND ON +C ENTRY A(K) MUST CONTAIN THE VALUE OF THE ENTRY IN JCN(K). +C - ON EXIT, A IS REORDERED IN THE SAME WAY AS IRN +C *IP - INTEGER ARRAY OF LENGTH NC+1 +C - NOT SET ON ENTRY. +C - ON EXIT IP(I) POINTS TO THE FIRST ENTRY IN COLUMN I(I=1,...,NC) +C AND IP(NC+1) IS SET TO NNZ+1 +C IW - INTEGER ARRAY OF LENGTH NR+1 +C - ON ENTRY, MUST BE SET ON ENTRY SO THAT IW(J) POINTS TO THE +C POSITION IN JCN OF THE FIRST ENTRY IN ROW J ,J=1,..NR, AND +C IW(NR+1) MUST BE SET TO NNZ+1 +C +C .. Scalar Arguments .. INTEGER LA,NC,NNZ,NR LOGICAL YESA +C .. +C .. Array Arguments .. DOUBLE PRECISION A(LA) INTEGER IP(NC+1),IRN(NNZ),IW(NR+1),JCN(NNZ) +C .. +C .. Local Scalars .. DOUBLE PRECISION ACE,ACEP INTEGER I,ICE,ICEP,J,K,L,LOC,LOCP +C .. +C .. Executable Statements .. DO 10 J = 1,NC IP(J) = 0 10 CONTINUE IF (.NOT.YESA) GO TO 80 +C +C COUNT THE NUMBER OF ENTRIES IN EACH COLUMN +C DO 20 K = 1,NNZ I = JCN(K) IP(I) = IP(I) + 1 IRN(K) = JCN(K) 20 CONTINUE IP(NC+1) = NNZ + 1 +C +C SET IP SO THE IP(I) POINTS TO THE FIRST ENTRY IN COLUMN I+1 +C IP(1) = IP(1) + 1 DO 30 J = 2,NC IP(J) = IP(J) + IP(J-1) 30 CONTINUE +C DO 50 I = NR,1,-1 DO 40 J = IW(I),IW(I+1) - 1 K = IRN(J) @@ -345,16 +550,24 @@ SUBROUTINE MC49CD(NC,NR,NNZ,IRN,JCN,YESA,LA,A,IP,IW) 60 CONTINUE 70 CONTINUE GO TO 130 + 80 CONTINUE +C +C COUNT THE NUMBER OF ENTRIES IN EACH COLUMN +C DO 90 K = 1,NNZ I = JCN(K) IP(I) = IP(I) + 1 90 CONTINUE IP(NC+1) = NNZ + 1 +C +C SET IP SO THE IP(I) POINTS TO THE FIRST ENTRY IN COLUMN I+1 +C IP(1) = IP(1) + 1 DO 100 J = 2,NC IP(J) = IP(J) + IP(J-1) 100 CONTINUE +C DO 120 I = NR,1,-1 DO 110 J = IW(I),IW(I+1) - 1 K = JCN(J) @@ -364,11 +577,19 @@ SUBROUTINE MC49CD(NC,NR,NNZ,IRN,JCN,YESA,LA,A,IP,IW) 110 CONTINUE 120 CONTINUE 130 RETURN + END C********************************************************************** BLOCK DATA MC49DD +C .. Common blocks .. COMMON /MC49ED/LP,MP,IOUT,JOUT,IDUP,NZOUT INTEGER IDUP,IOUT,JOUT,LP,MP,NZOUT +C .. +C .. Save statement .. SAVE /MC49ED/ +C .. +C .. Data statements .. DATA LP/6/,MP/6/ +C .. +C .. Executable Statements .. END diff --git a/src/Libraries/superlu-5.2.1/DOC/ug.pdf b/src/Libraries/superlu-5.2.1/DOC/ug.pdf new file mode 100644 index 00000000..f8544055 Binary files /dev/null and b/src/Libraries/superlu-5.2.1/DOC/ug.pdf differ diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/.dropbox.attr b/src/Libraries/superlu-5.2.1/EXAMPLE/.dropbox.attr new file mode 100755 index 00000000..9e26dfee --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/.dropbox.attr @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/.gitignore b/src/Libraries/superlu-5.2.1/EXAMPLE/.gitignore new file mode 100644 index 00000000..d60e48c2 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/.gitignore @@ -0,0 +1,34 @@ +/*.o +/superlu +/citersol +/citersol1 +/clinsol +/clinsol1 +/clinsolx +/clinsolx1 +/clinsolx2 +/clinsolx3 +/ditersol +/ditersol1 +/dlinsol +/dlinsol1 +/dlinsolx +/dlinsolx1 +/dlinsolx2 +/dlinsolx3 +/sitersol +/sitersol1 +/slinsol +/slinsol1 +/slinsolx +/slinsolx1 +/slinsolx2 +/slinsolx3 +/zitersol +/zitersol1 +/zlinsol +/zlinsol1 +/zlinsolx +/zlinsolx1 +/zlinsolx2 +/zlinsolx3 diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/Makefile b/src/Libraries/superlu-5.2.1/EXAMPLE/Makefile new file mode 100644 index 00000000..7ab70b45 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/Makefile @@ -0,0 +1,197 @@ +include ../make.inc + +####################################################################### +# This makefile creates the example programs for the linear equation +# routines in SuperLU. The files are grouped as follows: +# +# SLINEXM -- Single precision real example routines +# DLINEXM -- Double precision real example routines +# CLINEXM -- Double precision complex example routines +# ZLINEXM -- Double precision complex example routines +# +# Example programs can be generated for all or some of the four different +# precisions. Enter make followed by one or more of the data types +# desired. Some examples: +# make single +# make single double +# Alternatively, the command +# make +# without any arguments creates all four example programs. +# The executable files are called +# slinsol slinsolx +# dlinsol dlinsolx +# clinsol clinsolx +# zlinsol zlinsolx +# +# To remove the object files after the executable files have been +# created, enter +# make clean +# On some systems, you can force the source files to be recompiled by +# entering (for example) +# make single FRC=FRC +# +####################################################################### + +HEADER = ../SRC + +SLINEXM = slinsol.o +SLINEXM1 = slinsol1.o +SLINXEXM = slinsolx.o +SLINXEXM1 = slinsolx1.o +SLINXEXM2 = slinsolx2.o +SLINXEXM3 = slinsolx3.o +SITSOL = sitersol.o sfgmr.o +SITSOL1 = sitersol1.o sfgmr.o + +DLINEXM = dlinsol.o +DLINEXM1 = dlinsol1.o +DLINXEXM = dlinsolx.o +DLINXEXM1 = dlinsolx1.o +DLINXEXM2 = dlinsolx2.o +DLINXEXM3 = dlinsolx3.o +SUPERLUEXM = superlu.o sp_ienv.o +DITSOL = ditersol.o dfgmr.o +DITSOL1 = ditersol1.o dfgmr.o + +CLINEXM = clinsol.o +CLINEXM1 = clinsol1.o +CLINXEXM = clinsolx.o +CLINXEXM1 = clinsolx1.o +CLINXEXM2 = clinsolx2.o +CLINXEXM3 = clinsolx3.o +CITSOL = citersol.o cfgmr.o +CITSOL1 = citersol1.o cfgmr.o + +ZLINEXM = zlinsol.o +ZLINEXM1 = zlinsol1.o +ZLINXEXM = zlinsolx.o +ZLINXEXM1 = zlinsolx1.o +ZLINXEXM2 = zlinsolx2.o +ZLINXEXM3 = zlinsolx3.o +ZITSOL = zitersol.o zfgmr.o +ZITSOL1 = zitersol1.o zfgmr.o + + +all: single double complex complex16 + +single: slinsol slinsol1 slinsolx slinsolx1 slinsolx2 slinsolx3 \ + sitersol sitersol1 +double: dlinsol dlinsol1 dlinsolx dlinsolx1 dlinsolx2 dlinsolx3 \ + superlu ditersol ditersol1 +complex: clinsol clinsol1 clinsolx clinsolx1 clinsolx2 clinsolx3 \ + citersol citersol1 +complex16: zlinsol zlinsol1 zlinsolx zlinsolx1 zlinsolx2 zlinsolx3 \ + zitersol zitersol1 + +slinsol: $(SLINEXM) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(SLINEXM) $(LIBS) -lm -o $@ + +slinsol1: $(SLINEXM1) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(SLINEXM1) $(LIBS) -lm -o $@ + +slinsolx: $(SLINXEXM) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(SLINXEXM) $(LIBS) -lm -o $@ + +slinsolx1: $(SLINXEXM1) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(SLINXEXM1) $(LIBS) -lm -o $@ + +slinsolx2: $(SLINXEXM2) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(SLINXEXM2) $(LIBS) -lm -o $@ + +slinsolx3: $(SLINXEXM3) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(SLINXEXM3) $(LIBS) -lm -o $@ + +sitersol: $(SITSOL) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(SITSOL) $(LIBS) -lm -o $@ + +sitersol1: $(SITSOL1) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(SITSOL1) $(LIBS) -lm -o $@ + +dlinsol: $(DLINEXM) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(DLINEXM) $(LIBS) -lm -o $@ + +dlinsol1: $(DLINEXM1) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(DLINEXM1) $(LIBS) -lm -o $@ + +dlinsolx: $(DLINXEXM) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(DLINXEXM) $(LIBS) -lm -o $@ + +dlinsolx1: $(DLINXEXM1) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(DLINXEXM1) $(LIBS) -lm -o $@ + +dlinsolx2: $(DLINXEXM2) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(DLINXEXM2) $(LIBS) -lm -o $@ + +dlinsolx3: $(DLINXEXM3) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(DLINXEXM3) $(LIBS) -lm -o $@ + +superlu: $(SUPERLUEXM) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(SUPERLUEXM) $(LIBS) -lm -o $@ + +ditersol: $(DITSOL) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(DITSOL) $(LIBS) -lm -o $@ + +ditersol1: $(DITSOL1) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(DITSOL1) $(LIBS) -lm -o $@ + +clinsol: $(CLINEXM) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(CLINEXM) $(LIBS) -lm -o $@ + +clinsol1: $(CLINEXM1) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(CLINEXM1) $(LIBS) -lm -o $@ + +clinsolx: $(CLINXEXM) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(CLINXEXM) $(LIBS) -lm -o $@ + +clinsolx1: $(CLINXEXM1) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(CLINXEXM1) $(LIBS) -lm -o $@ + +clinsolx2: $(CLINXEXM2) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(CLINXEXM2) $(LIBS) -lm -o $@ + +clinsolx3: $(CLINXEXM3) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(CLINXEXM3) $(LIBS) -lm -o $@ + +citersol: $(CITSOL) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(CITSOL) $(LIBS) -lm -o $@ + +citersol1: $(CITSOL1) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(CITSOL1) $(LIBS) -lm -o $@ + +zlinsol: $(ZLINEXM) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(ZLINEXM) $(LIBS) -lm -o $@ + +zlinsol1: $(ZLINEXM1) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(ZLINEXM1) $(LIBS) -lm -o $@ + +zlinsolx: $(ZLINXEXM) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(ZLINXEXM) $(LIBS) -lm -o $@ + +zlinsolx1: $(ZLINXEXM1) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(ZLINXEXM1) $(LIBS) -lm -o $@ + +zlinsolx2: $(ZLINXEXM2) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(ZLINXEXM2) $(LIBS) -lm -o $@ + +zlinsolx3: $(ZLINXEXM3) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(ZLINXEXM3) $(LIBS) -lm -o $@ + +zitersol: $(ZITSOL) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(ZITSOL) $(LIBS) -lm -o $@ + +zitersol1: $(ZITSOL1) $(SUPERLULIB) + $(LOADER) $(LOADOPTS) $(ZITSOL1) $(LIBS) -lm -o $@ + +.c.o: + $(CC) $(CFLAGS) $(CDEFS) -I$(HEADER) -c $< $(VERBOSE) + +.f.o: + $(FORTRAN) $(FFLAGS) -c $< $(VERBOSE) + +clean: + rm -f *.o *linsol *linsol1 *linsolx *linsolx1 *linsolx2 *linsolx3 \ + superlu *itersol *itersol1 + + + + diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/README b/src/Libraries/superlu-5.2.1/EXAMPLE/README new file mode 100644 index 00000000..8330d0ef --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/README @@ -0,0 +1,55 @@ + SuperLU EXAMPLES + +This directory contains sample programs to illustrate how to use +various functions provded in SuperLU. You can modify these +examples to suit your applications. + +Here are the descriptions of the double precision examples: + + dlinsol : use simple driver DGSSV to solve a linear system one time. + dlinsol1: use simple driver DGSSV in the symmetric mode. + dlinsolx: use DGSSVX with the full (default) options to solve a + linear system. + dlinsolx1: use DGSSVX to factorize A first, then solve the system later. + dlinsolx2: use DGSSVX to solve systems repeatedly with the same sparsity + pattern of matrix A. + dlinsolx3: use DGSSVX to solve systems repeatedly with the same sparsity + pattern and similar numerical values as matrix A. + + superlu : the small 5x5 sample program in Section 2 of the Users' Guide. + + ditersol: use GMRES with ILU preconditioner to solve a linear system. + ILU is computed from the equilibrated matrix, and the + preconditioned GMRES is applied to the equilibrated system. + ( The ILU is computed by the routine SRC/dgsitrf.c, the driver + routine is SRC/dgsisx.c. ) + ditersol1: use GMRES with ILU preconditioner to solve a linear system. + ILU is computed from the equilibrated matrix, but the + preconditioned GMRES is applied to the original system. + + +To compile all the examples, type: + % make + +To run the small 5x5 sample program in Section 1 of the Users' Guide, type: + % superlu + +To run the real version examples, type: + % dlinsol < g20.rua (or, % slinsol < g20.rua) + % dlinsolx < g20.rua (or, % slinsolx < g20.rua) + % dlinsolx1 < g20.rua (or, % slinsolx1 < g20.rua) + % dlinsolx2 < g20.rua (or, % slinsolx2 < g20.rua) + % dlinsolx3 < g20.rua (or, % slinsolx3 < g20.rua) + +To run the complex version examples, type: + % zlinsol < cg20.cua (or, % clinsol < cg20.cua) + % zlinsolx < cg20.cua (or, % clinsolx < cg20.cua) + % zlinsolx1 < cg20.cua (or, % clinsolx1 < cg20.cua) + % zlinsolx2 < cg20.cua (or, % clinsolx2 < cg20.cua) + % zlinsolx3 < cg20.cua (or, % clinsolx3 < cg20.cua) + +To run the ILU preconditioner example, type: + % ditersol -h < g20.rua + % ditersol1 -h < g20.rua + % zitersol -h < cg20.cua + % zitersol1 -h < cg20.cua diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/cfgmr.c b/src/Libraries/superlu-5.2.1/EXAMPLE/cfgmr.c new file mode 100644 index 00000000..cb96f260 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/cfgmr.c @@ -0,0 +1,344 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cfgmr.c + * \brief flexible GMRES from ITSOL developed by Yousef Saad. + */ + +/* ITSOL COPYRIGHT + +Copyright (C) 2006, the University of Minnesota + +ITSOL is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation [version 2 of the License, or any later version] +For details, see + +http://www.gnu.org/copyleft/gpl.html + +A copy of the GNU licencing agreement is attached to the ITSOL package +in the file GNU. For additional information contact the Free Software +Foundation Inc., 65 Mass Ave, Cambridge, MA 02139, USA. + +DISCLAIMER +---------- + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +For information on ITSOL contact saad@cs.umn.edu +*/ + +#include "slu_cdefs.h" + +#define epsmac 1.0e-16 + +extern void cdotc_(complex *, int *, complex [], int *, complex [], int *); +extern float scnrm2_(int *, complex [], int *); + + +int cfgmr(int n, + void (*cmatvec) (complex, complex[], complex, complex[]), + void (*cpsolve) (int, complex[], complex[]), + complex *rhs, complex *sol, double tol, int im, int *itmax, FILE * fits) +{ +/*---------------------------------------------------------------------- +| *** Preconditioned FGMRES *** ++----------------------------------------------------------------------- +| This is a simple version of the ARMS preconditioned FGMRES algorithm. ++----------------------------------------------------------------------- +| Y. S. Dec. 2000. -- Apr. 2008 ++----------------------------------------------------------------------- +| on entry: +|---------- +| +| rhs = real vector of length n containing the right hand side. +| sol = real vector of length n containing an initial guess to the +| solution on input. +| tol = tolerance for stopping iteration +| im = Krylov subspace dimension +| (itmax) = max number of iterations allowed. +| fits = NULL: no output +| != NULL: file handle to output " resid vs time and its" +| +| on return: +|---------- +| fgmr int = 0 --> successful return. +| int = 1 --> convergence not achieved in itmax iterations. +| sol = contains an approximate solution (upon successful return). +| itmax = has changed. It now contains the number of steps required +| to converge -- ++----------------------------------------------------------------------- +| internal work arrays: +|---------- +| vv = work array of length [im+1][n] (used to store the Arnoldi +| basis) +| hh = work array of length [im][im+1] (Householder matrix) +| z = work array of length [im][n] to store preconditioned vectors ++----------------------------------------------------------------------- +| subroutines called : +| matvec - matrix-vector multiplication operation +| psolve - (right) preconditionning operation +| psolve can be a NULL pointer (GMRES without preconditioner) ++---------------------------------------------------------------------*/ + + int maxits = *itmax; + int i, i1, ii, j, k, k1, its, retval, i_1 = 1, i_2 = 2; + float beta, eps1 = 0.0, t, t0, gam; + complex **hh, *c, *s, *rs; + complex **vv, **z, tt; + complex zero = {0.0, 0.0}; + complex one = {1.0, 0.0}; + complex tt1, tt2; + + its = 0; + vv = (complex **)SUPERLU_MALLOC((im + 1) * sizeof(complex *)); + for (i = 0; i <= im; i++) vv[i] = complexMalloc(n); + z = (complex **)SUPERLU_MALLOC(im * sizeof(complex *)); + hh = (complex **)SUPERLU_MALLOC(im * sizeof(complex *)); + for (i = 0; i < im; i++) + { + hh[i] = complexMalloc(i + 2); + z[i] = complexMalloc(n); + } + c = complexMalloc(im); + s = complexMalloc(im); + rs = complexMalloc(im + 1); + + /*---- outer loop starts here ----*/ + do + { + /*---- compute initial residual vector ----*/ + cmatvec(one, sol, zero, vv[0]); + for (j = 0; j < n; j++) + c_sub(&vv[0][j], &rhs[j], &vv[0][j]); /* vv[0]= initial residual */ + beta = scnrm2_(&n, vv[0], &i_1); + + /*---- print info if fits != null ----*/ + if (fits != NULL && its == 0) + fprintf(fits, "%8d %10.2e\n", its, beta); + /*if ( beta <= tol * dnrm2_(&n, rhs, &i_1) )*/ + if ( !(beta > tol * scnrm2_(&n, rhs, &i_1)) ) + break; + t = 1.0 / beta; + + /*---- normalize: vv[0] = vv[0] / beta ----*/ + for (j = 0; j < n; j++) + cs_mult(&vv[0][j], &vv[0][j], t); + if (its == 0) + eps1 = tol * beta; + + /*---- initialize 1-st term of rhs of hessenberg system ----*/ + rs[0].r = beta; + rs[0].i = 0.0; + for (i = 0; i < im; i++) + { + its++; + i1 = i + 1; + + /*------------------------------------------------------------ + | (Right) Preconditioning Operation z_{j} = M^{-1} v_{j} + +-----------------------------------------------------------*/ + if (cpsolve) + cpsolve(n, z[i], vv[i]); + else + ccopy_(&n, vv[i], &i_1, z[i], &i_1); + + /*---- matvec operation w = A z_{j} = A M^{-1} v_{j} ----*/ + cmatvec(one, z[i], zero, vv[i1]); + + /*------------------------------------------------------------ + | modified gram - schmidt... + | h_{i,j} = (w,v_{i}) + | w = w - h_{i,j} v_{i} + +------------------------------------------------------------*/ + t0 = scnrm2_(&n, vv[i1], &i_1); + for (j = 0; j <= i; j++) + { + complex negt; +#if 0 + cdotc_(&tt, &n, vv[j], &i_1, vv[i1], &i_1); +#else + tt = zero; + for (k = 0; k < n; ++k) { + cc_conj(&tt1, &vv[j][k]); + cc_mult(&tt2, &tt1, &vv[i1][k]); + c_add(&tt, &tt, &tt2); + } +#endif + hh[i][j] = tt; + negt.r = -tt.r; + negt.i = -tt.i; + caxpy_(&n, &negt, vv[j], &i_1, vv[i1], &i_1); + } + + /*---- h_{j+1,j} = ||w||_{2} ----*/ + t = scnrm2_(&n, vv[i1], &i_1); + while (t < 0.5 * t0) + { + t0 = t; + for (j = 0; j <= i; j++) + { + complex negt; +#if 0 + cdotc_(&tt, &n, vv[j], &i_1, vv[i1], &i_1); +#else + tt = zero; + for (k = 0; k < n; ++k) { + cc_conj(&tt1, &vv[j][k]); + cc_mult(&tt2, &tt1, &vv[i1][k]); + c_add(&tt, &tt, &tt2); + } +#endif + c_add(&hh[i][j], &hh[i][j], &tt); + negt.r = -tt.r; + negt.i = -tt.i; + caxpy_(&n, &negt, vv[j], &i_1, vv[i1], &i_1); + } + t = scnrm2_(&n, vv[i1], &i_1); + } + + hh[i][i1].r = t; + hh[i][i1].i = 0.0; + + if (t != 0.0) + { + /*---- v_{j+1} = w / h_{j+1,j} ----*/ + t = 1.0 / t; + for (k = 0; k < n; k++) + cs_mult(&vv[i1][k], &vv[i1][k], t); + } + /*--------------------------------------------------- + | done with modified gram schimdt and arnoldi step + | now update factorization of hh + +--------------------------------------------------*/ + + /*-------------------------------------------------------- + | perform previous transformations on i-th column of h + +-------------------------------------------------------*/ + for (k = 1; k <= i; k++) + { + k1 = k - 1; + tt = hh[i][k1]; + cc_mult(&tt1, &c[k1], &tt); + cc_mult(&tt2, &s[k1], &hh[i][k]); + c_add(&hh[i][k1], &tt1, &tt2); + + cc_mult(&tt1, &s[k1], &tt); + cc_mult(&tt2, &c[k1], &hh[i][k]); + c_sub(&hh[i][k], &tt2, &tt1); + } + + gam = scnrm2_(&i_2, &hh[i][i], &i_1); + + /*--------------------------------------------------- + | if gamma is zero then any small value will do + | affect only residual estimate + +--------------------------------------------------*/ + /* if (gam == 0.0) gam = epsmac; */ + + /*---- get next plane rotation ---*/ + if (gam == 0.0) + { + c[i] = one; + s[i] = zero; + } + else + { + gam = 1.0 / gam; + cs_mult(&c[i], &hh[i][i], gam); + cs_mult(&s[i], &hh[i][i1], gam); + } + + cc_mult(&rs[i1], &s[i], &rs[i]); + rs[i1].r = -rs[i1].r; rs[i1].i = -rs[i1].i; + cc_mult(&rs[i], &c[i], &rs[i]); + + /*---------------------------------------------------- + | determine residual norm and test for convergence + +---------------------------------------------------*/ + cc_mult(&tt1, &c[i], &hh[i][i]); + cc_mult(&tt2, &s[i], &hh[i][i1]); + c_add(&hh[i][i], &tt1, &tt2); + beta = c_abs1(&rs[i1]); + if (fits != NULL) + fprintf(fits, "%8d %10.2e\n", its, beta); + if (beta <= eps1 || its >= maxits) + break; + } + + if (i == im) i--; + + /*---- now compute solution. 1st, solve upper triangular system ----*/ + c_div(&rs[i], &rs[i], &hh[i][i]); + + for (ii = 1; ii <= i; ii++) + { + k = i - ii; + k1 = k + 1; + tt = rs[k]; + for (j = k1; j <= i; j++) { + cc_mult(&tt1, &hh[j][k], &rs[j]); + c_sub(&tt, &tt, &tt1); + } + c_div(&rs[k], &tt, &hh[k][k]); + } + + /*---- linear combination of v[i]'s to get sol. ----*/ + for (j = 0; j <= i; j++) + { + tt = rs[j]; + for (k = 0; k < n; k++) { + cc_mult(&tt1, &tt, &z[j][k]); + c_add(&sol[k], &sol[k], &tt1); + } + } + + /* calculate the residual and output */ + cmatvec(one, sol, zero, vv[0]); + for (j = 0; j < n; j++) + c_sub(&vv[0][j], &rhs[j], &vv[0][j]);/* vv[0]= initial residual */ + + /*---- print info if fits != null ----*/ + beta = scnrm2_(&n, vv[0], &i_1); + + /*---- restart outer loop if needed ----*/ + /*if (beta >= eps1 / tol)*/ + if ( !(beta < eps1 / tol) ) + { + its = maxits + 10; + break; + } + if (beta <= eps1) + break; + } while(its < maxits); + + retval = (its >= maxits); + for (i = 0; i <= im; i++) + SUPERLU_FREE(vv[i]); + SUPERLU_FREE(vv); + for (i = 0; i < im; i++) + { + SUPERLU_FREE(hh[i]); + SUPERLU_FREE(z[i]); + } + SUPERLU_FREE(hh); + SUPERLU_FREE(z); + SUPERLU_FREE(c); + SUPERLU_FREE(s); + SUPERLU_FREE(rs); + + *itmax = its; + + return retval; +} /*----end of fgmr ----*/ diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/cg20.cua b/src/Libraries/superlu-5.2.1/EXAMPLE/cg20.cua new file mode 100755 index 00000000..ea07dbad --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/cg20.cua @@ -0,0 +1,918 @@ +complex g20, symm. permuted by SYMMMD sym + 914 26 120 768 0 +CUA 400 400 1920 0 +(16I5) (16I5) (5E15.8) (5E15.8) + 1 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 + 81 86 91 96 101 106 111 116 121 126 131 136 141 146 151 156 + 161 166 171 176 181 186 191 196 201 206 210 214 218 223 228 231 + 235 239 243 248 253 257 262 266 271 276 281 286 291 295 300 304 + 309 313 318 323 328 332 337 342 347 352 357 362 367 372 377 382 + 387 392 397 402 407 412 417 422 427 432 437 442 447 452 457 462 + 467 472 477 482 487 492 497 501 505 510 514 519 524 529 534 539 + 544 549 554 559 564 568 572 576 580 583 588 593 597 601 606 610 + 614 619 624 629 634 639 644 649 654 659 664 669 674 678 682 686 + 691 696 701 706 710 714 718 723 728 732 737 742 747 752 757 762 + 767 772 777 781 786 791 796 800 805 810 815 820 825 830 835 839 + 844 849 854 859 864 869 874 879 884 889 894 899 904 909 914 919 + 923 928 932 937 941 946 951 956 961 966 971 976 981 986 991 996 + 1001 1006 1011 1015 1020 1024 1029 1033 1038 1043 1048 1053 1058 1063 1068 1073 + 1078 1083 1088 1093 1098 1103 1108 1113 1117 1122 1126 1130 1133 1138 1142 1147 + 1152 1156 1161 1165 1170 1174 1179 1183 1188 1193 1198 1203 1208 1212 1217 1221 + 1226 1230 1235 1240 1245 1249 1254 1259 1264 1269 1274 1279 1284 1288 1293 1298 + 1303 1308 1313 1317 1322 1327 1332 1337 1342 1347 1352 1357 1362 1367 1372 1377 + 1382 1387 1392 1397 1402 1407 1412 1417 1422 1427 1432 1437 1442 1446 1451 1455 + 1459 1464 1468 1472 1477 1482 1487 1492 1497 1501 1506 1510 1515 1519 1522 1526 + 1530 1535 1539 1544 1549 1554 1559 1563 1568 1573 1578 1583 1587 1592 1596 1601 + 1605 1610 1615 1620 1625 1630 1635 1640 1645 1650 1655 1660 1665 1670 1674 1679 + 1684 1689 1694 1699 1704 1709 1714 1719 1724 1729 1734 1738 1743 1748 1753 1758 + 1763 1768 1773 1778 1783 1788 1792 1797 1802 1807 1811 1816 1821 1826 1831 1836 + 1841 1846 1851 1856 1861 1866 1871 1876 1881 1886 1891 1896 1901 1906 1911 1916 + 1921 + 1 9 32 391 395 2 9 392 395 400 3 8 389 393 394 4 + 8 9 392 394 5 7 8 381 389 6 7 8 9 32 5 6 + 7 33 382 3 4 5 6 8 1 2 4 6 9 10 31 396 + 398 399 11 18 29 30 31 12 18 31 397 399 13 17 386 387 + 388 14 17 18 30 387 15 17 383 388 390 16 17 18 390 397 + 13 14 15 16 17 11 12 14 16 18 19 28 33 380 382 20 + 22 28 29 33 21 22 29 31 398 20 21 22 32 391 23 27 + 379 384 385 24 27 28 379 380 25 27 30 385 387 26 27 28 + 29 30 23 24 25 26 27 19 20 24 26 28 11 20 21 26 + 29 11 14 25 26 30 10 11 12 21 31 1 6 22 32 33 + 7 19 20 32 33 34 74 92 370 372 35 40 70 174 176 36 + 40 91 174 177 37 39 40 70 71 38 39 40 90 91 37 38 + 39 74 92 35 36 37 38 40 41 56 70 71 73 42 44 55 + 56 43 44 175 176 42 43 44 45 44 45 56 70 176 46 54 + 55 56 73 47 49 53 48 49 54 55 47 48 49 52 50 51 + 53 69 50 51 52 68 72 49 51 52 53 54 47 50 52 53 + 46 48 52 54 72 42 46 48 55 41 42 45 46 56 57 59 + 67 68 72 58 59 67 74 372 57 58 59 71 73 60 66 67 + 372 373 61 62 65 69 61 62 66 67 68 63 64 65 374 63 + 64 66 371 373 61 63 65 66 60 62 64 65 66 57 58 60 + 62 67 51 57 62 68 69 50 61 68 69 35 37 41 45 70 + 37 41 59 71 74 51 54 57 72 73 41 46 59 72 73 34 + 39 58 71 74 75 89 369 381 389 76 78 92 370 375 77 78 + 89 369 375 76 77 78 88 90 79 87 91 177 178 80 87 88 + 90 91 81 86 87 173 178 82 86 173 379 380 83 85 86 87 + 88 84 85 86 380 382 83 84 85 89 381 81 82 83 84 86 + 79 80 81 83 87 78 80 83 88 89 75 77 85 88 89 38 + 78 80 90 92 36 38 79 80 91 34 39 76 90 92 93 172 + 385 386 387 94 98 168 169 170 95 98 169 172 386 96 98 109 + 170 171 97 98 109 386 388 94 95 96 97 98 99 108 377 383 + 390 100 108 376 377 378 101 107 109 167 171 102 107 109 383 388 + 103 106 107 167 104 106 108 378 105 106 107 108 383 103 104 105 + 106 101 102 103 105 107 99 100 104 105 108 96 97 101 102 109 + 110 166 173 379 384 111 132 138 162 164 112 132 138 168 169 113 + 131 132 163 164 114 130 131 132 168 115 129 130 168 170 116 123 + 128 129 130 117 121 123 128 118 120 131 163 119 120 121 123 118 + 119 120 122 117 119 121 120 122 123 130 131 116 117 119 122 123 + 124 127 128 129 125 127 167 171 126 127 129 170 171 124 125 126 + 127 116 117 124 128 115 116 124 126 129 114 115 116 122 130 113 + 114 118 122 131 111 112 113 114 132 133 137 138 162 165 134 137 + 165 166 384 135 137 138 169 172 136 137 172 384 385 133 134 135 + 136 137 111 112 133 135 138 139 145 174 175 176 140 145 161 174 + 177 141 143 145 175 142 143 153 160 141 142 143 144 143 144 145 + 160 161 139 140 141 144 145 146 152 153 159 160 147 152 159 162 + 165 148 150 152 153 149 150 163 164 148 149 150 151 150 151 152 + 162 164 146 147 148 151 152 142 146 148 153 154 158 159 160 161 + 155 158 161 177 178 156 158 159 165 166 157 158 166 173 178 154 + 155 156 157 158 146 147 154 156 159 142 144 146 154 160 140 144 + 154 155 161 111 133 147 151 162 113 118 149 163 111 113 149 151 + 164 133 134 147 156 165 110 134 156 157 166 101 103 125 167 94 + 112 114 115 168 94 95 112 135 169 94 96 115 126 170 96 101 + 125 126 171 93 95 135 136 172 81 82 110 157 173 35 36 139 + 140 174 43 139 141 175 35 43 45 139 176 36 79 140 155 177 + 79 81 155 157 178 179 183 201 369 375 180 183 200 201 274 181 + 183 369 389 393 182 183 272 274 393 179 180 181 182 183 184 188 + 370 372 373 185 188 199 371 373 186 188 201 370 375 187 188 199 + 200 201 184 185 186 187 188 189 198 200 274 277 190 198 273 276 + 277 191 197 198 199 200 192 193 196 374 192 193 197 199 371 194 + 195 196 275 194 195 197 198 276 192 194 196 197 191 193 195 196 + 197 189 190 191 195 198 185 187 191 193 199 180 187 189 191 200 + 179 180 186 187 201 202 271 272 393 394 203 207 272 274 277 204 + 207 218 273 277 205 207 267 271 272 206 207 218 266 267 203 204 + 205 206 207 208 217 218 266 268 209 217 265 268 270 210 216 217 + 218 273 211 212 215 275 211 212 216 273 276 213 214 215 269 213 + 214 216 217 270 211 213 215 216 210 212 214 215 216 208 209 210 + 214 217 204 206 208 210 218 219 223 271 392 394 220 223 229 267 + 271 221 223 365 392 400 222 223 229 365 366 219 220 221 222 223 + 224 228 229 266 267 225 228 263 266 268 226 228 229 264 366 227 + 228 262 263 264 224 225 226 227 228 220 222 224 226 229 230 249 + 263 265 268 231 239 248 249 265 232 233 238 269 232 233 239 265 + 270 234 236 237 238 235 236 237 247 234 235 236 234 235 237 239 + 248 232 234 238 239 231 233 237 238 239 240 246 249 262 263 241 + 242 245 247 241 242 246 248 249 243 244 245 261 243 244 246 260 + 262 241 243 245 246 240 242 244 245 246 235 241 247 248 231 237 + 242 247 248 230 231 240 242 249 250 259 264 364 366 251 259 260 + 262 264 252 258 259 364 367 253 254 257 261 253 254 258 259 260 + 255 256 257 363 255 256 258 367 368 253 255 257 258 252 254 256 + 257 258 250 251 252 254 259 244 251 254 260 261 243 253 260 261 + 227 240 244 251 262 225 227 230 240 263 226 227 250 251 264 209 + 230 231 233 265 206 208 224 225 266 205 206 220 224 267 208 209 + 225 230 268 213 232 269 270 209 214 233 269 270 202 205 219 220 + 271 182 202 203 205 272 190 204 210 212 273 180 182 189 203 274 + 194 211 275 276 190 195 212 275 276 189 190 203 204 277 278 283 + 289 395 400 279 283 289 361 362 280 282 283 391 395 281 282 283 + 359 361 280 281 282 396 398 278 279 280 281 283 284 288 289 365 + 400 285 288 364 365 366 286 288 289 360 362 287 288 360 364 367 + 284 285 286 287 288 278 279 284 286 289 290 292 298 396 399 291 + 292 298 355 357 290 291 292 358 359 293 297 377 390 397 294 297 + 298 397 399 295 297 356 376 377 296 297 298 355 356 293 294 295 + 296 297 290 291 294 296 298 299 328 351 355 357 300 308 328 355 + 356 301 307 326 327 302 307 308 326 328 303 306 376 378 304 306 + 307 308 305 306 308 356 376 303 304 305 306 301 302 304 307 300 + 302 304 305 308 309 311 326 328 351 310 311 324 326 327 309 310 + 311 325 353 312 323 325 352 353 313 314 322 350 313 314 323 352 + 354 315 316 320 322 315 316 321 323 325 317 319 324 327 318 319 + 320 317 318 319 321 315 318 320 321 316 319 320 321 324 313 315 + 322 323 312 314 316 322 323 310 317 321 324 325 311 312 316 324 + 325 301 302 309 310 326 301 310 317 327 299 300 302 309 328 329 + 338 349 360 362 330 338 360 367 368 331 337 338 348 349 332 333 + 336 363 332 333 337 338 368 334 335 336 350 334 335 337 348 354 + 332 334 336 337 331 333 335 336 337 329 330 331 333 338 339 347 + 358 359 361 340 347 349 361 362 341 346 347 348 349 342 346 348 + 352 354 343 345 346 347 358 344 345 346 352 353 343 344 345 351 + 357 341 342 343 344 346 339 340 341 343 347 331 335 341 342 348 + 329 331 340 341 349 313 334 350 354 299 309 345 351 353 312 314 + 342 344 352 311 312 344 351 353 314 335 342 350 354 291 296 299 + 300 355 295 296 300 305 356 291 299 345 357 358 292 339 343 357 + 358 281 292 339 359 396 286 287 329 330 360 279 281 339 340 361 + 279 286 329 340 362 255 332 363 368 250 252 285 287 364 221 222 + 284 285 365 222 226 250 285 366 252 256 287 330 367 256 330 333 + 363 368 75 77 179 181 369 34 76 184 186 370 64 185 193 371 + 374 34 58 60 184 372 60 64 184 185 373 63 192 371 374 76 + 77 179 186 375 100 295 303 305 376 99 100 293 295 377 100 104 + 303 378 23 24 82 110 379 19 24 82 84 380 5 75 85 381 + 382 7 19 84 381 382 15 99 102 105 383 23 110 134 136 384 + 23 25 93 136 385 13 93 95 97 386 13 14 25 93 387 13 + 15 97 102 388 3 5 75 181 389 15 16 99 293 390 1 22 + 280 391 398 2 4 219 221 392 3 181 182 202 393 3 4 202 + 219 394 1 2 278 280 395 10 282 290 359 396 12 16 293 294 + 397 10 21 282 391 398 10 12 290 294 399 2 221 278 284 400 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 + 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00 4.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 +-1.00000000E+00 1.00000000E+00-1.00000000E+00 1.00000000E+00-1.00000000E+00 + 1.00000000E+00-1.00000000E+00 1.00000000E+00 4.00000000E+00 1.00000000E+00 diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/citersol.c b/src/Libraries/superlu-5.2.1/EXAMPLE/citersol.c new file mode 100644 index 00000000..5384e985 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/citersol.c @@ -0,0 +1,386 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file citersol.c + * \brief Example #1 showing how to use ILU to precondition GMRES + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Lawrence Berkeley National Laboratory
+ * November, 2010
+ * August, 2011
+ *
+ * This example shows that ILU is computed from the equilibrated matrix,
+ * and the preconditioned GMRES is applied to the equilibrated system.
+ * The driver routine CGSISX is called twice to perform factorization
+ * and apply preconditioner separately.
+ * 
+ * Note that CGSISX performs the following factorization:
+ *     Pr*Dr*A*Dc*Pc^T ~= LU
+ * with Pr being obtained from MC64 statically then partial pivoting
+ * dynamically. On return, A is overwritten as A1 = Dr*A*Dc.
+ *
+ * We can solve the transformed system, A1*y = Dr*B, using FGMRES.
+ * B is first overwritten as Dr*B.
+ * Then GMRES step requires requires 2 procedures:
+ *   1) Apply preconditioner M^{-1} = Pc^T*U^{-1}*L^{-1}*Pr
+ *   2) Matrix-vector multiplication: w = A1*v
+ * 
+ * 
+ */ + +#include "slu_cdefs.h" + +superlu_options_t *GLOBAL_OPTIONS; +float *GLOBAL_R, *GLOBAL_C; +int *GLOBAL_PERM_C, *GLOBAL_PERM_R; +SuperMatrix *GLOBAL_A, *GLOBAL_L, *GLOBAL_U; +SuperLUStat_t *GLOBAL_STAT; +mem_usage_t *GLOBAL_MEM_USAGE; + +void cpsolve(int n, + complex x[], /* solution */ + complex y[] /* right-hand side */ +) +{ + SuperMatrix *A = GLOBAL_A, *L = GLOBAL_L, *U = GLOBAL_U; + SuperLUStat_t *stat = GLOBAL_STAT; + int *perm_c = GLOBAL_PERM_C, *perm_r = GLOBAL_PERM_R; + char equed[1] = {'N'}; + float *R = GLOBAL_R, *C = GLOBAL_C; + superlu_options_t *options = GLOBAL_OPTIONS; + mem_usage_t *mem_usage = GLOBAL_MEM_USAGE; + int info; + static DNformat X, Y; + static SuperMatrix XX = {SLU_DN, SLU_C, SLU_GE, 1, 1, &X}; + static SuperMatrix YY = {SLU_DN, SLU_C, SLU_GE, 1, 1, &Y}; + float rpg, rcond; + + XX.nrow = YY.nrow = n; + X.lda = Y.lda = n; + X.nzval = x; + Y.nzval = y; + +#if 0 + dcopy_(&n, y, &i_1, x, &i_1); + cgstrs(NOTRANS, L, U, perm_c, perm_r, &XX, stat, &info); +#else + cgsisx(options, A, perm_c, perm_r, NULL, equed, R, C, + L, U, NULL, 0, &YY, &XX, &rpg, &rcond, NULL, + mem_usage, stat, &info); +#endif +} + +void cmatvec_mult(complex alpha, complex x[], complex beta, complex y[]) +{ + SuperMatrix *A = GLOBAL_A; + + sp_cgemv("N", alpha, A, x, 1, beta, y, 1); +} + +int main(int argc, char *argv[]) +{ + void cmatvec_mult(complex alpha, complex x[], complex beta, complex y[]); + void cpsolve(int n, complex x[], complex y[]); + extern int cfgmr( int n, + void (*matvec_mult)(complex, complex [], complex, complex []), + void (*psolve)(int n, complex [], complex[]), + complex *rhs, complex *sol, double tol, int restrt, int *itmax, + FILE *fits); + extern int cfill_diag(int n, NCformat *Astore); + + char equed[1] = {'B'}; + yes_no_t equil; + trans_t trans; + SuperMatrix A, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + complex *a; + int *asub, *xa; + int *etree; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + int nrhs, ldx, lwork, info, m, n, nnz; + complex *rhsb, *rhsx, *xact; + complex *work = NULL; + float *R, *C; + float u, rpg, rcond; + complex zero = {0.0, 0.0}; + complex one = {1.0, 0.0}; + complex none = {-1.0, 0.0}; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + int restrt, iter, maxit, i; + double resid; + complex *x, *b; + +#ifdef DEBUG + extern int num_drop_L, num_drop_U; +#endif + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 0.1; //different from complete LU + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + options.RowPerm = LargeDiag; + options.ILU_DropTol = 1e-4; + options.ILU_FillTol = 1e-2; + options.ILU_FillFactor = 10.0; + options.ILU_DropRule = DROP_BASIC | DROP_AREA; + options.ILU_Norm = INF_NORM; + options.ILU_MILU = SILU; + */ + ilu_set_default_options(&options); + + /* Modify the defaults. */ + options.PivotGrowth = YES; /* Compute reciprocal pivot growth */ + options.ConditionNumber = YES;/* Compute reciprocal condition number */ + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) ABORT("Malloc fails for work[]."); + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + if (argc < 2) + { + printf("Usage:\n%s [OPTION] < [INPUT] > [OUTPUT]\nOPTION:\n" + "-h -hb:\n\t[INPUT] is a Harwell-Boeing format matrix.\n" + "-r -rb:\n\t[INPUT] is a Rutherford-Boeing format matrix.\n" + "-t -triplet:\n\t[INPUT] is a triplet format matrix.\n", + argv[0]); + return 0; + } + else + { + switch (argv[1][1]) + { + case 'H': + case 'h': + printf("Input a Harwell-Boeing format matrix:\n"); + creadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + break; + case 'R': + case 'r': + printf("Input a Rutherford-Boeing format matrix:\n"); + creadrb(&m, &n, &nnz, &a, &asub, &xa); + break; + case 'T': + case 't': + printf("Input a triplet format matrix:\n"); + creadtriple(&m, &n, &nnz, &a, &asub, &xa); + break; + default: + printf("Unrecognized format.\n"); + return 0; + } + } + + cCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, + SLU_NC, SLU_C, SLU_GE); + Astore = A.Store; + cfill_diag(n, Astore); + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + fflush(stdout); + + /* Generate the right-hand side */ + if ( !(rhsb = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + cCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_C, SLU_GE); + cCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_C, SLU_GE); + xact = complexMalloc(n * nrhs); + ldx = n; + cGenXtrue(n, nrhs, xact, ldx); + cFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (float *) SUPERLU_MALLOC(A.nrow * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (float *) SUPERLU_MALLOC(A.ncol * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + + info = 0; +#ifdef DEBUG + num_drop_L = 0; + num_drop_U = 0; +#endif + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* Compute the incomplete factorization and compute the condition number + and pivot growth using dgsisx. */ + B.ncol = 0; /* not to perform triangular solution */ + cgsisx(&options, &A, perm_c, perm_r, etree, equed, R, C, &L, &U, work, + lwork, &B, &X, &rpg, &rcond, &Glu, &mem_usage, &stat, &info); + + /* Set RHS for GMRES. */ + if (!(b = complexMalloc(m))) ABORT("Malloc fails for b[]."); + if (*equed == 'R' || *equed == 'B') { + for (i = 0; i < n; ++i) cs_mult(&b[i], &rhsb[i], R[i]); + } else { + for (i = 0; i < m; i++) b[i] = rhsb[i]; + } + + printf("cgsisx(): info %d, equed %c\n", info, equed[0]); + if (info > 0 || rcond < 1e-8 || rpg > 1e8) + printf("WARNING: This preconditioner might be unstable.\n"); + + if ( info == 0 || info == n+1 ) { + if ( options.PivotGrowth == YES ) + printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber == YES ) + printf("Recip. condition number = %e\n", rcond); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("n(A) = %d, nnz(A) = %d\n", n, Astore->nnz); + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("Fill ratio: nnz(F)/nnz(A) = %.3f\n", + ((double)(Lstore->nnz) + (double)(Ustore->nnz) - (double)n) + / (double)Astore->nnz); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + fflush(stdout); + + /* Set the global variables. */ + GLOBAL_A = &A; + GLOBAL_L = &L; + GLOBAL_U = &U; + GLOBAL_STAT = &stat; + GLOBAL_PERM_C = perm_c; + GLOBAL_PERM_R = perm_r; + GLOBAL_OPTIONS = &options; + GLOBAL_R = R; + GLOBAL_C = C; + GLOBAL_MEM_USAGE = &mem_usage; + + /* Set the options to do solve-only. */ + options.Fact = FACTORED; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + + /* Set the variables used by GMRES. */ + restrt = SUPERLU_MIN(n / 3 + 1, 50); + maxit = 1000; + iter = maxit; + resid = 1e-4; + if (!(x = complexMalloc(n))) ABORT("Malloc fails for x[]."); + + if (info <= n + 1) + { + int i_1 = 1; + double maxferr = 0.0, nrmA, nrmB, res, t; + complex temp; + extern float scnrm2_(int *, complex [], int *); + extern void caxpy_(int *, complex *, complex [], int *, complex [], int *); + + /* Initial guess */ + for (i = 0; i < n; i++) x[i] = zero; + + t = SuperLU_timer_(); + + /* Call GMRES */ + cfgmr(n, cmatvec_mult, cpsolve, b, x, resid, restrt, &iter, stdout); + + t = SuperLU_timer_() - t; + + /* Output the result. */ + nrmA = scnrm2_(&(Astore->nnz), (complex *)((DNformat *)A.Store)->nzval, + &i_1); + nrmB = scnrm2_(&m, b, &i_1); + sp_cgemv("N", none, &A, x, 1, one, b, 1); + res = scnrm2_(&m, b, &i_1); + resid = res / nrmB; + printf("||A||_F = %.1e, ||B||_2 = %.1e, ||B-A*X||_2 = %.1e, " + "relres = %.1e\n", nrmA, nrmB, res, resid); + + if (iter >= maxit) + { + if (resid >= 1.0) iter = -180; + else if (resid > 1e-8) iter = -111; + } + printf("iteration: %d\nresidual: %.1e\nGMRES time: %.2f seconds.\n", + iter, resid, t); + + /* Scale the solution back if equilibration was performed. */ + if (*equed == 'C' || *equed == 'B') + for (i = 0; i < n; i++) cs_mult(&x[i], &x[i], C[i]); + + for (i = 0; i < m; i++) { + c_sub(&temp, &x[i], &xact[i]); + maxferr = SUPERLU_MAX(maxferr, c_abs1(&temp)); + } + printf("||X-X_true||_oo = %.1e\n", maxferr); + } +#ifdef DEBUG + printf("%d entries in L and %d entries in U dropped.\n", + num_drop_L, num_drop_U); +#endif + fflush(stdout); + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork >= 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } + SUPERLU_FREE(b); + SUPERLU_FREE(x); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/citersol1.c b/src/Libraries/superlu-5.2.1/EXAMPLE/citersol1.c new file mode 100644 index 00000000..5eb1cdc7 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/citersol1.c @@ -0,0 +1,395 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file citersol1.c + * \brief Example #2 showing how to use ILU to precondition GMRES + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Lawrence Berkeley National Laboratory
+ * November, 2010
+ * August, 2011
+ *
+ * This example shows that ILU is computed from the equilibrated matrix,
+ * but the preconditioned GMRES is applied to the original system.
+ * The driver routine CGSISX is called twice to perform factorization
+ * and apply preconditioner separately.
+ * 
+ * Note that CGSISX performs the following factorization:
+ *     Pr*Dr*A*Dc*Pc^T ~= LU
+ * with Pr being obtained from MC64 statically then partial pivoting
+ * dynamically. On return, A is overwritten as A1 = Dr*A*Dc.
+ *
+ * We need to save a copy of the original matrix A, then solve
+ * the original system, A*x = B, using FGMRES.
+ * Each GMRES step requires requires 2 procedures:
+ *   1) Apply preconditioner M^{-1} = Dc*Pc^T*U^{-1}*L^{-1}*Pr*Dr
+ *   2) Matrix-vector multiplication: w = A*v
+ *
+ * 
+ */ + +#include "slu_cdefs.h" + +char *GLOBAL_EQUED; +superlu_options_t *GLOBAL_OPTIONS; +float *GLOBAL_R, *GLOBAL_C; +int *GLOBAL_PERM_C, *GLOBAL_PERM_R; +SuperMatrix *GLOBAL_A, *GLOBAL_A_ORIG, *GLOBAL_L, *GLOBAL_U; +SuperLUStat_t *GLOBAL_STAT; +mem_usage_t *GLOBAL_MEM_USAGE; + +void cpsolve(int n, + complex x[], /* solution */ + complex y[] /* right-hand side */ +) +{ + SuperMatrix *A = GLOBAL_A, *L = GLOBAL_L, *U = GLOBAL_U; + SuperLUStat_t *stat = GLOBAL_STAT; + int *perm_c = GLOBAL_PERM_C, *perm_r = GLOBAL_PERM_R; + char *equed = GLOBAL_EQUED; + float *R = GLOBAL_R, *C = GLOBAL_C; + superlu_options_t *options = GLOBAL_OPTIONS; + mem_usage_t *mem_usage = GLOBAL_MEM_USAGE; + int info; + static DNformat X, Y; + static SuperMatrix XX = {SLU_DN, SLU_C, SLU_GE, 1, 1, &X}; + static SuperMatrix YY = {SLU_DN, SLU_C, SLU_GE, 1, 1, &Y}; + float rpg, rcond; + + XX.nrow = YY.nrow = n; + X.lda = Y.lda = n; + X.nzval = x; + Y.nzval = y; + +#if 0 + ccopy_(&n, y, &i_1, x, &i_1); + cgstrs(NOTRANS, L, U, perm_c, perm_r, &XX, stat, &info); +#else + cgsisx(options, A, perm_c, perm_r, NULL, equed, R, C, + L, U, NULL, 0, &YY, &XX, &rpg, &rcond, NULL, + mem_usage, stat, &info); +#endif +} + +void cmatvec_mult(complex alpha, complex x[], complex beta, complex y[]) +{ + SuperMatrix *A = GLOBAL_A_ORIG; + + sp_cgemv("N", alpha, A, x, 1, beta, y, 1); +} + +int main(int argc, char *argv[]) +{ + void cmatvec_mult(complex alpha, complex x[], complex beta, complex y[]); + void cpsolve(int n, complex x[], complex y[]); + extern int cfgmr( int n, + void (*matvec_mult)(complex, complex [], complex, complex []), + void (*psolve)(int n, complex [], complex[]), + complex *rhs, complex *sol, double tol, int restrt, int *itmax, + FILE *fits); + extern int cfill_diag(int n, NCformat *Astore); + + char equed[1] = {'B'}; + yes_no_t equil; + trans_t trans; + SuperMatrix A, AA, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + complex *a, *a_orig; + int *asub, *xa, *asub_orig, *xa_orig; + int *etree; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + int nrhs, ldx, lwork, info, m, n, nnz; + complex *rhsb, *rhsx, *xact; + complex *work = NULL; + float *R, *C; + float u, rpg, rcond; + complex zero = {0.0, 0.0}; + complex one = {1.0, 0.0}; + complex none = {-1.0, 0.0}; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + int restrt, iter, maxit, i; + double resid; + complex *x, *b; + +#ifdef DEBUG + extern int num_drop_L, num_drop_U; +#endif + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 0.1; //different from complete LU + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + options.RowPerm = LargeDiag; + options.ILU_DropTol = 1e-4; + options.ILU_FillTol = 1e-2; + options.ILU_FillFactor = 10.0; + options.ILU_DropRule = DROP_BASIC | DROP_AREA; + options.ILU_Norm = INF_NORM; + options.ILU_MILU = SILU; + */ + ilu_set_default_options(&options); + + /* Modify the defaults. */ + options.PivotGrowth = YES; /* Compute reciprocal pivot growth */ + options.ConditionNumber = YES;/* Compute reciprocal condition number */ + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) ABORT("Malloc fails for work[]."); + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + if (argc < 2) + { + printf("Usage:\n%s [OPTION] < [INPUT] > [OUTPUT]\nOPTION:\n" + "-h -hb:\n\t[INPUT] is a Harwell-Boeing format matrix.\n" + "-r -rb:\n\t[INPUT] is a Rutherford-Boeing format matrix.\n" + "-t -triplet:\n\t[INPUT] is a triplet format matrix.\n", + argv[0]); + return 0; + } + else + { + switch (argv[1][1]) + { + case 'H': + case 'h': + printf("Input a Harwell-Boeing format matrix:\n"); + creadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + break; + case 'R': + case 'r': + printf("Input a Rutherford-Boeing format matrix:\n"); + creadrb(&m, &n, &nnz, &a, &asub, &xa); + break; + case 'T': + case 't': + printf("Input a triplet format matrix:\n"); + creadtriple(&m, &n, &nnz, &a, &asub, &xa); + break; + default: + printf("Unrecognized format.\n"); + return 0; + } + } + + cCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, + SLU_NC, SLU_C, SLU_GE); + Astore = A.Store; + cfill_diag(n, Astore); + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + fflush(stdout); + + /* Make a copy of the original matrix. */ + nnz = Astore->nnz; + a_orig = complexMalloc(nnz); + asub_orig = intMalloc(nnz); + xa_orig = intMalloc(n+1); + for (i = 0; i < nnz; ++i) { + a_orig[i] = ((complex *)Astore->nzval)[i]; + asub_orig[i] = Astore->rowind[i]; + } + for (i = 0; i <= n; ++i) xa_orig[i] = Astore->colptr[i]; + cCreate_CompCol_Matrix(&AA, m, n, nnz, a_orig, asub_orig, xa_orig, + SLU_NC, SLU_C, SLU_GE); + + /* Generate the right-hand side */ + if ( !(rhsb = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + cCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_C, SLU_GE); + cCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_C, SLU_GE); + xact = complexMalloc(n * nrhs); + ldx = n; + cGenXtrue(n, nrhs, xact, ldx); + cFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (float *) SUPERLU_MALLOC(A.nrow * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (float *) SUPERLU_MALLOC(A.ncol * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + + info = 0; +#ifdef DEBUG + num_drop_L = 0; + num_drop_U = 0; +#endif + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* Compute the incomplete factorization and compute the condition number + and pivot growth using dgsisx. */ + B.ncol = 0; /* not to perform triangular solution */ + cgsisx(&options, &A, perm_c, perm_r, etree, equed, R, C, &L, &U, work, + lwork, &B, &X, &rpg, &rcond, &Glu, &mem_usage, &stat, &info); + + /* Set RHS for GMRES. */ + if (!(b = complexMalloc(m))) ABORT("Malloc fails for b[]."); + for (i = 0; i < m; i++) b[i] = rhsb[i]; + + printf("cgsisx(): info %d, equed %c\n", info, equed[0]); + if (info > 0 || rcond < 1e-8 || rpg > 1e8) + printf("WARNING: This preconditioner might be unstable.\n"); + + if ( info == 0 || info == n+1 ) { + if ( options.PivotGrowth == YES ) + printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber == YES ) + printf("Recip. condition number = %e\n", rcond); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("n(A) = %d, nnz(A) = %d\n", n, Astore->nnz); + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("Fill ratio: nnz(F)/nnz(A) = %.3f\n", + ((double)(Lstore->nnz) + (double)(Ustore->nnz) - (double)n) + / (double)Astore->nnz); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + fflush(stdout); + + /* Set the global variables. */ + GLOBAL_A = &A; + GLOBAL_A_ORIG = &AA; + GLOBAL_L = &L; + GLOBAL_U = &U; + GLOBAL_STAT = &stat; + GLOBAL_PERM_C = perm_c; + GLOBAL_PERM_R = perm_r; + GLOBAL_OPTIONS = &options; + GLOBAL_EQUED = equed; + GLOBAL_R = R; + GLOBAL_C = C; + GLOBAL_MEM_USAGE = &mem_usage; + + /* Set the options to do solve-only. */ + options.Fact = FACTORED; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + + /* Set the variables used by GMRES. */ + restrt = SUPERLU_MIN(n / 3 + 1, 50); + maxit = 1000; + iter = maxit; + resid = 1e-8; + if (!(x = complexMalloc(n))) ABORT("Malloc fails for x[]."); + + if (info <= n + 1) + { + int i_1 = 1; + double maxferr = 0.0, nrmA, nrmB, res, t; + complex temp; + extern float scnrm2_(int *, complex [], int *); + extern void caxpy_(int *, complex *, complex [], int *, complex [], int *); + + /* Initial guess */ + for (i = 0; i < n; i++) x[i] = zero; + + t = SuperLU_timer_(); + + /* Call GMRES */ + cfgmr(n, cmatvec_mult, cpsolve, b, x, resid, restrt, &iter, stdout); + + t = SuperLU_timer_() - t; + + /* Output the result. */ + nrmA = scnrm2_(&(Astore->nnz), (complex *)((DNformat *)A.Store)->nzval, + &i_1); + nrmB = scnrm2_(&m, b, &i_1); + sp_cgemv("N", none, &AA, x, 1, one, b, 1); /* Original matrix */ + res = scnrm2_(&m, b, &i_1); + resid = res / nrmB; + printf("||A||_F = %.1e, ||B||_2 = %.1e, ||B-A*X||_2 = %.1e, " + "relres = %.1e\n", nrmA, nrmB, res, resid); + + if (iter >= maxit) + { + if (resid >= 1.0) iter = -180; + else if (resid > 1e-8) iter = -111; + } + printf("iteration: %d\nresidual: %.1e\nGMRES time: %.2f seconds.\n", + iter, resid, t); + + for (i = 0; i < m; i++) { + c_sub(&temp, &x[i], &xact[i]); + maxferr = SUPERLU_MAX(maxferr, c_abs1(&temp)); + } + printf("||X-X_true||_oo = %.1e\n", maxferr); + } +#ifdef DEBUG + printf("%d entries in L and %d entries in U dropped.\n", + num_drop_L, num_drop_U); +#endif + fflush(stdout); + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + Destroy_CompCol_Matrix(&A); + Destroy_CompCol_Matrix(&AA); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork >= 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } + SUPERLU_FREE(b); + SUPERLU_FREE(x); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/clinsol.c b/src/Libraries/superlu-5.2.1/EXAMPLE/clinsol.c new file mode 100644 index 00000000..fd6e69d7 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/clinsol.c @@ -0,0 +1,126 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 3.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + */ +#include "slu_cdefs.h" + +int main(int argc, char *argv[]) +{ + SuperMatrix A; + NCformat *Astore; + complex *a; + int *asub, *xa; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + SuperMatrix L; /* factor L */ + SCformat *Lstore; + SuperMatrix U; /* factor U */ + NCformat *Ustore; + SuperMatrix B; + int nrhs, ldx, info, m, n, nnz; + complex *xact, *rhs; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Read the matrix in Harwell-Boeing format. */ + creadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + cCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_C, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + nrhs = 1; + if ( !(rhs = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhs[]."); + cCreate_Dense_Matrix(&B, m, nrhs, rhs, m, SLU_DN, SLU_C, SLU_GE); + xact = complexMalloc(n * nrhs); + ldx = n; + cGenXtrue(n, nrhs, xact, ldx); + cFillRHS(options.Trans, nrhs, xact, ldx, &A, &B); + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + cgssv(&options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info); + + if ( info == 0 ) { + + /* This is how you could access the solution matrix. */ + complex *sol = (complex*) ((DNformat*) B.Store)->nzval; + + /* Compute the infinity norm of the error. */ + cinf_norm_error(nrhs, &B, xact); + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + cQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + + } else { + printf("cgssv() error returns INFO= %d\n", info); + if ( info <= n ) { /* factorization completes */ + cQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + } + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhs); + SUPERLU_FREE (xact); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/clinsol1.c b/src/Libraries/superlu-5.2.1/EXAMPLE/clinsol1.c new file mode 100644 index 00000000..db236197 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/clinsol1.c @@ -0,0 +1,131 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 3.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + */ +#include "slu_cdefs.h" + +int main(int argc, char *argv[]) +{ + SuperMatrix A; + NCformat *Astore; + complex *a; + int *asub, *xa; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + SuperMatrix L; /* factor L */ + SCformat *Lstore; + SuperMatrix U; /* factor U */ + NCformat *Ustore; + SuperMatrix B; + int nrhs, ldx, info, m, n, nnz; + complex *xact, *rhs; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Now we modify the default options to use the symmetric mode. */ + options.SymmetricMode = YES; + options.ColPerm = MMD_AT_PLUS_A; + options.DiagPivotThresh = 0.001; + + /* Read the matrix in Harwell-Boeing format. */ + creadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + cCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_C, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + nrhs = 1; + if ( !(rhs = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhs[]."); + cCreate_Dense_Matrix(&B, m, nrhs, rhs, m, SLU_DN, SLU_C, SLU_GE); + xact = complexMalloc(n * nrhs); + ldx = n; + cGenXtrue(n, nrhs, xact, ldx); + cFillRHS(options.Trans, nrhs, xact, ldx, &A, &B); + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + cgssv(&options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info); + + if ( info == 0 ) { + + /* This is how you could access the solution matrix. */ + complex *sol = (complex*) ((DNformat*) B.Store)->nzval; + + /* Compute the infinity norm of the error. */ + cinf_norm_error(nrhs, &B, xact); + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + cQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + + } else { + printf("cgssv() error returns INFO= %d\n", info); + if ( info <= n ) { /* factorization completes */ + cQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + } + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhs); + SUPERLU_FREE (xact); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/clinsolx.c b/src/Libraries/superlu-5.2.1/EXAMPLE/clinsolx.c new file mode 100644 index 00000000..ba682bba --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/clinsolx.c @@ -0,0 +1,226 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 3.1) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * August 1, 2008 + * + */ +#include "slu_cdefs.h" + +int main(int argc, char *argv[]) +{ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + complex *a; + int *asub, *xa; + int *perm_r; /* row permutations from partial pivoting */ + int *perm_c; /* column permutation vector */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, m, n, nnz; + complex *rhsb, *rhsx, *xact; + float *R, *C; + float *ferr, *berr; + float u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + /* Add more functionalities that the defaults. */ + options.PivotGrowth = YES; /* Compute reciprocal pivot growth */ + options.ConditionNumber = YES;/* Compute reciprocal condition number */ + options.IterRefine = SLU_SINGLE; /* Perform single-precision refinement */ + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("CLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + creadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + cCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_C, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + cCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_C, SLU_GE); + cCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_C, SLU_GE); + xact = complexMalloc(n * nrhs); + ldx = n; + cGenXtrue(n, nrhs, xact, ldx); + cFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (float *) SUPERLU_MALLOC(A.nrow * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (float *) SUPERLU_MALLOC(A.ncol * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* Solve the system and compute the condition number + and error bounds using dgssvx. */ + + cgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("cgssvx(): info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + complex *sol = (complex*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth == YES ) + printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber == YES ) + printf("Recip. condition number = %e\n", rcond); + if ( options.IterRefine != NOREFINE ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork == 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + + +/* + * Parse command line inputs. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + float *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:w:r:u:f:t:p:e:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/clinsolx1.c b/src/Libraries/superlu-5.2.1/EXAMPLE/clinsolx1.c new file mode 100644 index 00000000..477aaf44 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/clinsolx1.c @@ -0,0 +1,257 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 5.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + * Last update: July 10, 2015 + * + */ +#include "slu_cdefs.h" + +int main(int argc, char *argv[]) +{ +/* + * Purpose + * ======= + * + * The driver program CLINSOLX1. + * + * This example illustrates how to use CGSSVX to solve systems with the same + * A but different right-hand side. + * In this case, we factorize A only once in the first call to DGSSVX, + * and reuse the following data structures in the subsequent call to CGSSVX: + * perm_c, perm_r, R, C, L, U. + * + */ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + complex *a; + int *asub, *xa; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, m, n, nnz; + complex *rhsb, *rhsx, *xact; + float *R, *C; + float *ferr, *berr; + float u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default values for options argument: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("CLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + creadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + cCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_C, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + cCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_C, SLU_GE); + cCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_C, SLU_GE); + xact = complexMalloc(n * nrhs); + ldx = n; + cGenXtrue(n, nrhs, xact, ldx); + cFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (float *) SUPERLU_MALLOC(A.nrow * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (float *) SUPERLU_MALLOC(A.ncol * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* ONLY PERFORM THE LU DECOMPOSITION */ + B.ncol = 0; /* Indicate not to solve the system */ + cgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("LU factorization: cgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + /* ------------------------------------------------------------ + NOW WE SOLVE THE LINEAR SYSTEM USING THE FACTORED FORM OF A. + ------------------------------------------------------------*/ + options.Fact = FACTORED; /* Indicate the factored form of A is supplied. */ + B.ncol = nrhs; /* Set the number of right-hand side */ + + /* Initialize the statistics variables. */ + StatInit(&stat); + + cgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("Triangular solve: cgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + complex *sol = (complex*) ((DNformat*) X.Store)->nzval; + + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork == 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + +/* + * Parse command line options to get relaxed snode size, panel size, etc. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + float *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:u:e:t:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/clinsolx2.c b/src/Libraries/superlu-5.2.1/EXAMPLE/clinsolx2.c new file mode 100644 index 00000000..812a938c --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/clinsolx2.c @@ -0,0 +1,293 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 5.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + * Last update: July 10, 2015 + * + */ +#include "slu_cdefs.h" + +int main(int argc, char *argv[]) +{ +/* + * Purpose + * ======= + * + * The driver program CLINSOLX2. + * + * This example illustrates how to use CGSSVX to solve systems repeatedly + * with the same sparsity pattern of matrix A. + * In this case, the column permutation vector perm_c is computed once. + * The following data structures will be reused in the subsequent call to + * CGSSVX: perm_c, etree + * + */ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, A1, L, U; + SuperMatrix B, B1, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + complex *a, *a1; + int *asub, *xa, *asub1, *xa1; + int *perm_r; /* row permutations from partial pivoting */ + int *perm_c; /* column permutation vector */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, j, m, n, nnz; + complex *rhsb, *rhsb1, *rhsx, *xact; + float *R, *C; + float *ferr, *berr; + float u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("DLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + creadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + if ( !(a1 = complexMalloc(nnz)) ) ABORT("Malloc fails for a1[]."); + if ( !(asub1 = intMalloc(nnz)) ) ABORT("Malloc fails for asub1[]."); + if ( !(xa1 = intMalloc(n+1)) ) ABORT("Malloc fails for xa1[]."); + for (i = 0; i < nnz; ++i) { + a1[i] = a[i]; + asub1[i] = asub[i]; + } + for (i = 0; i < n+1; ++i) xa1[i] = xa[i]; + + cCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_C, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsb1 = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb1[]."); + if ( !(rhsx = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + cCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_C, SLU_GE); + cCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_C, SLU_GE); + xact = complexMalloc(n * nrhs); + ldx = n; + cGenXtrue(n, nrhs, xact, ldx); + cFillRHS(trans, nrhs, xact, ldx, &A, &B); + for (j = 0; j < nrhs; ++j) + for (i = 0; i < m; ++i) rhsb1[i+j*m] = rhsb[i+j*m]; + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(R = (float *) SUPERLU_MALLOC(A.nrow * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (float *) SUPERLU_MALLOC(A.ncol * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* ------------------------------------------------------------ + WE SOLVE THE LINEAR SYSTEM FOR THE FIRST TIME: AX = B + ------------------------------------------------------------*/ + cgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("First system: cgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + complex *sol = (complex*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + Destroy_CompCol_Matrix(&A); + Destroy_Dense_Matrix(&B); + if ( lwork >= 0 ) { /* Deallocate storage associated with L and U. */ + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } + + /* ------------------------------------------------------------ + NOW WE SOLVE ANOTHER LINEAR SYSTEM: A1*X = B1 + ONLY THE SPARSITY PATTERN OF A1 IS THE SAME AS THAT OF A. + ------------------------------------------------------------*/ + options.Fact = SamePattern; + StatInit(&stat); /* Initialize the statistics variables. */ + + cCreate_CompCol_Matrix(&A1, m, n, nnz, a1, asub1, xa1, + SLU_NC, SLU_C, SLU_GE); + cCreate_Dense_Matrix(&B1, m, nrhs, rhsb1, m, SLU_DN, SLU_C, SLU_GE); + + cgssvx(&options, &A1, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B1, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("\nSecond system: cgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + complex *sol = (complex*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A1); + Destroy_Dense_Matrix(&B1); + Destroy_Dense_Matrix(&X); + if ( lwork == 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + +/* + * Parse command line options to get relaxed snode size, panel size, etc. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + double *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:u:e:t:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/clinsolx3.c b/src/Libraries/superlu-5.2.1/EXAMPLE/clinsolx3.c new file mode 100644 index 00000000..ead6f3f3 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/clinsolx3.c @@ -0,0 +1,288 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 5.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + * Last update: July 10, 2015 + * + */ +#include "slu_cdefs.h" + +int main(int argc, char *argv[]) +{ +/* + * Purpose + * ======= + * + * The driver program CLINSOLX2. + * + * This example illustrates how to use CGSSVX to solve systems repeatedly + * with the same sparsity pattern and similar values of matrix A. + * In this case, the permutation vectors perm_r and perm_c are computed once. + * The following data structures will be reused in the subsequent call to + * CGSSVX: perm_r, perm_c, etree, L, U. + * + */ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, A1, L, U; + SuperMatrix B, B1, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; + complex *a, *a1; + int *asub, *xa, *asub1, *xa1; + int *perm_r; /* row permutations from partial pivoting */ + int *perm_c; /* column permutation vector */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, j, m, n, nnz; + complex *rhsb, *rhsb1, *rhsx, *xact; + float *R, *C; + float *ferr, *berr; + float u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("DLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + creadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + if ( !(a1 = complexMalloc(nnz)) ) ABORT("Malloc fails for a1[]."); + if ( !(asub1 = intMalloc(nnz)) ) ABORT("Malloc fails for asub1[]."); + if ( !(xa1 = intMalloc(n+1)) ) ABORT("Malloc fails for xa1[]."); + for (i = 0; i < nnz; ++i) { + a1[i] = a[i]; + asub1[i] = asub[i]; + } + for (i = 0; i < n+1; ++i) xa1[i] = xa[i]; + + cCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_C, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsb1 = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb1[]."); + if ( !(rhsx = complexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + cCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_C, SLU_GE); + cCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_C, SLU_GE); + xact = complexMalloc(n * nrhs); + ldx = n; + cGenXtrue(n, nrhs, xact, ldx); + cFillRHS(trans, nrhs, xact, ldx, &A, &B); + for (j = 0; j < nrhs; ++j) + for (i = 0; i < m; ++i) rhsb1[i+j*m] = rhsb[i+j*m]; + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(R = (float *) SUPERLU_MALLOC(A.nrow * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (float *) SUPERLU_MALLOC(A.ncol * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* ------------------------------------------------------------ + WE SOLVE THE LINEAR SYSTEM FOR THE FIRST TIME: AX = B + ------------------------------------------------------------*/ + cgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("First system: cgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + complex *sol = (complex*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + Destroy_CompCol_Matrix(&A); + Destroy_Dense_Matrix(&B); + + /* ------------------------------------------------------------ + NOW WE SOLVE ANOTHER LINEAR SYSTEM: A1*X = B1 + ONLY THE SPARSITY PATTERN OF A1 IS THE SAME AS THAT OF A. + ------------------------------------------------------------*/ + options.Fact = SamePattern_SameRowPerm; + StatInit(&stat); /* Initialize the statistics variables. */ + + cCreate_CompCol_Matrix(&A1, m, n, nnz, a1, asub1, xa1, + SLU_NC, SLU_C, SLU_GE); + cCreate_Dense_Matrix(&B1, m, nrhs, rhsb1, m, SLU_DN, SLU_C, SLU_GE); + + cgssvx(&options, &A1, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B1, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("\nSecond system: cgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + complex *sol = (complex*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A1); + Destroy_Dense_Matrix(&B1); + Destroy_Dense_Matrix(&X); + if ( lwork == 0 ) { /* Deallocate storage associated with L and U. */ + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + +/* + * Parse command line options to get relaxed snode size, panel size, etc. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + double *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:u:e:t:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/cmat.cua b/src/Libraries/superlu-5.2.1/EXAMPLE/cmat.cua new file mode 100644 index 00000000..cad51d02 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/cmat.cua @@ -0,0 +1,10968 @@ +Complex key + 10964 99 1753 9112 0 +CUA 1280 1280 22778 0 +(13I6) (13I6) (5E15.8) (5E15.8) + 1 2 3 4 5 6 7 8 9 10 11 12 13 + 14 15 19 23 29 35 41 47 53 59 65 71 77 + 83 89 95 101 107 113 119 125 131 137 143 149 155 + 161 167 173 179 185 191 197 203 209 215 221 227 233 + 239 243 247 253 259 265 271 277 283 289 295 301 307 + 313 319 325 331 337 343 349 355 361 367 373 379 385 + 391 397 403 409 415 421 427 433 439 445 451 457 463 + 469 475 481 487 491 495 501 507 513 519 525 531 537 + 543 549 555 561 567 573 579 585 591 597 603 609 615 + 621 627 633 639 645 651 657 663 669 675 681 687 693 + 699 705 711 715 719 725 731 737 743 749 755 761 767 + 773 779 785 791 797 803 809 815 821 827 833 839 845 + 851 857 863 869 875 881 887 893 899 905 911 917 923 + 929 935 941 947 953 959 965 971 977 983 989 999 1009 + 1015 1021 1031 1041 1047 1053 1063 1073 1079 1085 1095 1105 1111 + 1117 1127 1137 1143 1149 1159 1169 1175 1181 1191 1201 1207 1217 + 1223 1229 1239 1245 1255 1265 1271 1281 1291 1297 1303 1313 1319 + 1325 1335 1341 1351 1361 1367 1377 1387 1393 1399 1409 1415 1421 + 1431 1437 1447 1457 1463 1473 1483 1489 1495 1505 1511 1517 1527 + 1533 1543 1553 1559 1565 1571 1577 1583 1593 1599 1609 1615 1621 + 1631 1641 1647 1653 1663 1673 1679 1685 1695 1705 1711 1717 1727 + 1737 1743 1749 1759 1769 1775 1781 1791 1801 1807 1817 1823 1829 + 1839 1845 1855 1865 1871 1881 1891 1897 1903 1913 1919 1925 1935 + 1941 1951 1961 1967 1977 1987 1993 1999 2009 2015 2021 2031 2037 + 2047 2057 2063 2073 2083 2089 2095 2105 2111 2117 2127 2133 2143 + 2153 2159 2169 2179 2189 2199 2205 2211 2217 2223 2229 2235 2241 + 2251 2261 2267 2273 2283 2293 2299 2305 2315 2325 2331 2337 2347 + 2357 2363 2369 2379 2389 2395 2401 2411 2421 2427 2433 2443 2453 + 2459 2469 2475 2481 2491 2497 2507 2517 2523 2533 2543 2549 2555 + 2565 2571 2577 2587 2593 2603 2613 2619 2629 2639 2645 2651 2661 + 2667 2673 2683 2689 2699 2709 2715 2725 2735 2741 2747 2757 2763 + 2769 2779 2785 2795 2805 2811 2817 2823 2829 2835 2845 2851 2861 + 2867 2873 2883 2893 2899 2905 2915 2925 2931 2937 2947 2957 2963 + 2969 2979 2989 2995 3001 3011 3021 3027 3033 3043 3053 3059 3069 + 3075 3081 3091 3097 3107 3117 3123 3133 3143 3149 3155 3165 3171 + 3177 3187 3193 3203 3213 3219 3229 3239 3245 3251 3261 3267 3273 + 3283 3289 3299 3309 3315 3325 3335 3341 3347 3357 3363 3369 3379 + 3385 3395 3405 3411 3421 3431 3441 3451 3457 3463 3475 3487 3499 + 3511 3523 3535 3549 3569 3589 3609 3629 3649 3669 3683 3697 3719 + 3741 3763 3785 3807 3829 3843 3857 3879 3901 3923 3945 3967 3989 + 4003 4017 4039 4061 4083 4105 4127 4149 4163 4177 4199 4221 4243 + 4265 4287 4309 4323 4337 4359 4381 4403 4425 4447 4469 4483 4497 + 4519 4541 4563 4585 4607 4629 4643 4657 4679 4701 4723 4745 4767 + 4789 4803 4817 4839 4861 4883 4905 4927 4949 4963 4977 4999 5021 + 5043 5065 5087 5109 5123 5137 5159 5181 5203 5225 5247 5269 5283 + 5297 5319 5341 5363 5385 5407 5429 5443 5465 5487 5509 5531 5553 + 5575 5589 5603 5625 5639 5653 5675 5697 5719 5741 5763 5777 5799 + 5821 5843 5865 5887 5909 5923 5945 5967 5989 6011 6033 6055 6069 + 6083 6105 6119 6133 6155 6177 6199 6221 6243 6257 6279 6301 6323 + 6345 6367 6389 6403 6417 6431 6445 6459 6473 6487 6501 6515 6537 + 6551 6573 6587 6609 6631 6653 6675 6689 6711 6733 6755 6777 6799 + 6821 6835 6849 6871 6893 6915 6937 6959 6981 6995 7009 7031 7053 + 7075 7097 7119 7141 7155 7169 7191 7213 7235 7257 7279 7301 7315 + 7329 7351 7373 7395 7417 7439 7461 7475 7489 7511 7533 7555 7577 + 7599 7621 7635 7649 7671 7693 7715 7737 7759 7781 7795 7809 7831 + 7853 7875 7897 7919 7941 7955 7969 7991 8013 8035 8057 8079 8101 + 8115 8129 8151 8173 8195 8217 8239 8261 8275 8289 8311 8333 8355 + 8377 8399 8421 8435 8457 8479 8501 8523 8545 8567 8581 8595 8617 + 8631 8645 8667 8689 8711 8733 8755 8769 8791 8813 8835 8857 8879 + 8901 8915 8937 8959 8981 9003 9025 9047 9061 9075 9097 9111 9125 + 9147 9169 9191 9213 9235 9249 9271 9293 9315 9337 9359 9381 9395 + 9417 9439 9461 9483 9505 9527 9549 9571 9593 9615 9637 9659 9673 + 9687 9705 9723 9741 9759 9777 9795 9813 9831 9849 9867 9887 9917 + 9947 9977 10007 10037 10067 10097 10127 10147 10167 10187 10207 10239 10271 + 10303 10335 10367 10399 10431 10463 10483 10503 10523 10543 10575 10607 10639 + 10671 10703 10735 10767 10799 10819 10839 10859 10879 10911 10943 10975 11007 + 11039 11071 11103 11135 11155 11175 11195 11215 11247 11279 11311 11343 11375 + 11407 11439 11471 11491 11511 11531 11551 11583 11615 11647 11679 11711 11743 + 11775 11807 11827 11847 11867 11887 11919 11951 11983 12015 12047 12079 12111 + 12143 12163 12183 12203 12223 12255 12287 12319 12351 12383 12415 12447 12479 + 12499 12519 12539 12559 12591 12623 12655 12687 12719 12751 12783 12815 12835 + 12855 12875 12895 12927 12959 12991 13023 13055 13087 13119 13151 13171 13191 + 13211 13231 13263 13295 13327 13359 13391 13423 13455 13487 13507 13527 13547 + 13567 13587 13607 13627 13659 13691 13723 13755 13787 13819 13851 13883 13903 + 13923 13943 13975 14007 14039 14071 14103 14135 14167 14199 14219 14239 14259 + 14291 14323 14355 14387 14419 14451 14483 14515 14535 14555 14575 14607 14639 + 14671 14703 14735 14767 14799 14831 14851 14871 14891 14923 14955 14987 15019 + 15051 15083 15115 15147 15167 15187 15207 15227 15247 15267 15287 15307 15327 + 15359 15391 15423 15455 15487 15519 15551 15583 15615 15647 15679 15711 15743 + 15775 15807 15839 15859 15879 15899 15919 15939 15959 15979 15999 16019 16039 + 16059 16079 16099 16119 16139 16171 16203 16235 16267 16299 16319 16351 16371 + 16403 16423 16455 16475 16495 16527 16559 16591 16623 16655 16687 16719 16751 + 16771 16791 16811 16831 16863 16895 16927 16959 16991 17023 17055 17087 17107 + 17127 17147 17167 17199 17231 17263 17295 17327 17359 17391 17423 17443 17463 + 17483 17503 17535 17567 17599 17631 17663 17695 17727 17759 17779 17799 17819 + 17839 17871 17903 17935 17967 17999 18031 18063 18095 18115 18135 18155 18175 + 18207 18239 18271 18303 18335 18367 18399 18431 18451 18471 18491 18511 18543 + 18575 18607 18639 18671 18703 18735 18767 18787 18807 18827 18847 18879 18911 + 18943 18975 19007 19039 19071 19103 19123 19143 19163 19183 19215 19247 19279 + 19311 19343 19375 19407 19439 19459 19479 19499 19519 19551 19583 19615 19647 + 19679 19711 19743 19775 19795 19815 19835 19855 19887 19919 19951 19983 20015 + 20047 20079 20111 20131 20151 20171 20191 20223 20255 20287 20319 20351 20383 + 20415 20447 20467 20487 20507 20527 20559 20591 20623 20655 20687 20719 20751 + 20783 20803 20823 20843 20863 20895 20927 20959 20991 21023 21055 21087 21119 + 21139 21159 21179 21211 21243 21275 21307 21339 21371 21403 21435 21455 21475 + 21495 21515 21547 21567 21587 21607 21627 21659 21691 21723 21755 21787 21819 + 21851 21871 21903 21935 21967 21999 22031 22063 22095 22127 22147 22167 22187 + 22219 22251 22283 22315 22347 22379 22411 22443 22475 22507 22539 22571 22603 + 22635 22667 22699 22719 22739 22759 22779 + 1 3 5 7 9 11 13 15 17 19 21 23 25 + 27 29 30 61 62 29 30 61 62 29 30 61 62 + 93 94 29 30 61 62 93 94 61 62 93 94 125 + 126 61 62 93 94 125 126 93 94 125 126 157 158 + 93 94 125 126 157 158 125 126 157 158 189 190 125 + 126 157 158 189 190 157 158 189 190 221 222 157 158 + 189 190 221 222 189 190 221 222 253 254 189 190 221 + 222 253 254 221 222 253 254 285 286 221 222 253 254 + 285 286 253 254 285 286 317 318 253 254 285 286 317 + 318 285 286 317 318 349 350 285 286 317 318 349 350 + 317 318 349 350 381 382 317 318 349 350 381 382 349 + 350 381 382 413 414 349 350 381 382 413 414 381 382 + 413 414 445 446 381 382 413 414 445 446 413 414 445 + 446 477 478 413 414 445 446 477 478 445 446 477 478 + 509 510 445 446 477 478 509 510 477 478 509 510 541 + 542 477 478 509 510 541 542 509 510 541 542 573 574 + 509 510 541 542 573 574 541 542 573 574 605 606 541 + 542 573 574 605 606 573 574 605 606 637 638 573 574 + 605 606 637 638 1245 1246 1277 1278 1245 1246 1277 1278 1213 + 1214 1245 1246 1277 1278 1213 1214 1245 1246 1277 1278 1181 1182 + 1213 1214 1245 1246 1181 1182 1213 1214 1245 1246 1149 1150 1181 + 1182 1213 1214 1149 1150 1181 1182 1213 1214 1117 1118 1149 1150 + 1181 1182 1117 1118 1149 1150 1181 1182 1085 1086 1117 1118 1149 + 1150 1085 1086 1117 1118 1149 1150 1053 1054 1085 1086 1117 1118 + 1053 1054 1085 1086 1117 1118 1021 1022 1053 1054 1085 1086 1021 + 1022 1053 1054 1085 1086 989 990 1021 1022 1053 1054 989 990 + 1021 1022 1053 1054 957 958 989 990 1021 1022 957 958 989 + 990 1021 1022 925 926 957 958 989 990 925 926 957 958 + 989 990 893 894 925 926 957 958 893 894 925 926 957 + 958 861 862 893 894 925 926 861 862 893 894 925 926 + 829 830 861 862 893 894 829 830 861 862 893 894 797 + 798 829 830 861 862 797 798 829 830 861 862 765 766 + 797 798 829 830 765 766 797 798 829 830 733 734 765 + 766 797 798 733 734 765 766 797 798 701 702 733 734 + 765 766 701 702 733 734 765 766 669 670 701 702 733 + 734 669 670 701 702 733 734 637 638 669 670 701 702 + 605 606 637 638 669 670 605 606 637 638 669 670 637 + 638 669 670 701 702 31 32 63 64 31 32 63 64 + 31 32 63 64 95 96 31 32 63 64 95 96 63 + 64 95 96 127 128 63 64 95 96 127 128 95 96 + 127 128 159 160 95 96 127 128 159 160 127 128 159 + 160 191 192 127 128 159 160 191 192 159 160 191 192 + 223 224 159 160 191 192 223 224 191 192 223 224 255 + 256 191 192 223 224 255 256 223 224 255 256 287 288 + 223 224 255 256 287 288 255 256 287 288 319 320 255 + 256 287 288 319 320 287 288 319 320 351 352 287 288 + 319 320 351 352 319 320 351 352 383 384 319 320 351 + 352 383 384 351 352 383 384 415 416 351 352 383 384 + 415 416 383 384 415 416 447 448 383 384 415 416 447 + 448 415 416 447 448 479 480 415 416 447 448 479 480 + 447 448 479 480 511 512 447 448 479 480 511 512 479 + 480 511 512 543 544 479 480 511 512 543 544 511 512 + 543 544 575 576 511 512 543 544 575 576 543 544 575 + 576 607 608 543 544 575 576 607 608 575 576 607 608 + 639 640 575 576 607 608 639 640 1247 1248 1279 1280 1247 + 1248 1279 1280 1215 1216 1247 1248 1279 1280 1215 1216 1247 1248 + 1279 1280 1183 1184 1215 1216 1247 1248 1183 1184 1215 1216 1247 + 1248 1151 1152 1183 1184 1215 1216 1151 1152 1183 1184 1215 1216 + 1119 1120 1151 1152 1183 1184 1119 1120 1151 1152 1183 1184 1087 + 1088 1119 1120 1151 1152 1087 1088 1119 1120 1151 1152 1055 1056 + 1087 1088 1119 1120 1055 1056 1087 1088 1119 1120 1023 1024 1055 + 1056 1087 1088 1023 1024 1055 1056 1087 1088 991 992 1023 1024 + 1055 1056 991 992 1023 1024 1055 1056 959 960 991 992 1023 + 1024 959 960 991 992 1023 1024 927 928 959 960 991 992 + 927 928 959 960 991 992 895 896 927 928 959 960 895 + 896 927 928 959 960 863 864 895 896 927 928 863 864 + 895 896 927 928 831 832 863 864 895 896 831 832 863 + 864 895 896 799 800 831 832 863 864 799 800 831 832 + 863 864 767 768 799 800 831 832 767 768 799 800 831 + 832 735 736 767 768 799 800 735 736 767 768 799 800 + 703 704 735 736 767 768 703 704 735 736 767 768 671 + 672 703 704 735 736 671 672 703 704 735 736 639 640 + 671 672 703 704 607 608 639 640 671 672 607 608 639 + 640 671 672 639 640 671 672 703 704 2 4 33 34 + 35 36 2 4 33 34 35 36 2 4 33 34 35 + 36 2 4 33 34 35 36 34 36 65 66 67 68 + 2 4 33 34 35 36 65 66 67 68 2 4 33 + 34 35 36 65 66 67 68 34 36 65 66 67 68 + 66 68 97 98 99 100 34 36 65 66 67 68 97 + 98 99 100 34 36 65 66 67 68 97 98 99 100 + 66 68 97 98 99 100 98 100 129 130 131 132 66 + 68 97 98 99 100 129 130 131 132 66 68 97 98 + 99 100 129 130 131 132 98 100 129 130 131 132 130 + 132 161 162 163 164 98 100 129 130 131 132 161 162 + 163 164 98 100 129 130 131 132 161 162 163 164 130 + 132 161 162 163 164 162 164 193 194 195 196 130 132 + 161 162 163 164 193 194 195 196 130 132 161 162 163 + 164 193 194 195 196 162 164 193 194 195 196 194 196 + 225 226 227 228 162 164 193 194 195 196 225 226 227 + 228 162 164 193 194 195 196 225 226 227 228 194 196 + 225 226 227 228 226 228 257 258 259 260 194 196 225 + 226 227 228 257 258 259 260 194 196 225 226 227 228 + 257 258 259 260 226 228 257 258 259 260 226 228 257 + 258 259 260 289 290 291 292 258 260 289 290 291 292 + 258 260 289 290 291 292 226 228 257 258 259 260 289 + 290 291 292 290 292 321 322 323 324 258 260 289 290 + 291 292 321 322 323 324 258 260 289 290 291 292 321 + 322 323 324 290 292 321 322 323 324 290 292 321 322 + 323 324 353 354 355 356 290 292 321 322 323 324 353 + 354 355 356 322 324 353 354 355 356 322 324 353 354 + 355 356 322 324 353 354 355 356 385 386 387 388 354 + 356 385 386 387 388 354 356 385 386 387 388 322 324 + 353 354 355 356 385 386 387 388 386 388 417 418 419 + 420 354 356 385 386 387 388 417 418 419 420 354 356 + 385 386 387 388 417 418 419 420 386 388 417 418 419 + 420 386 388 417 418 419 420 449 450 451 452 386 388 + 417 418 419 420 449 450 451 452 418 420 449 450 451 + 452 418 420 449 450 451 452 418 420 449 450 451 452 + 481 482 483 484 450 452 481 482 483 484 450 452 481 + 482 483 484 418 420 449 450 451 452 481 482 483 484 + 482 484 513 514 515 516 450 452 481 482 483 484 513 + 514 515 516 450 452 481 482 483 484 513 514 515 516 + 482 484 513 514 515 516 482 484 513 514 515 516 545 + 546 547 548 482 484 513 514 515 516 545 546 547 548 + 514 516 545 546 547 548 514 516 545 546 547 548 514 + 516 545 546 547 548 577 578 579 580 546 548 577 578 + 579 580 546 548 577 578 579 580 514 516 545 546 547 + 548 577 578 579 580 578 580 609 610 611 612 546 548 + 577 578 579 580 609 610 611 612 546 548 577 578 579 + 580 609 610 611 612 578 580 609 610 611 612 1218 1220 + 1249 1250 1251 1252 1218 1220 1249 1250 1251 1252 1218 1220 1249 + 1250 1251 1252 1218 1220 1249 1250 1251 1252 1186 1188 1217 1218 + 1219 1220 1249 1250 1251 1252 1186 1188 1217 1218 1219 1220 1186 + 1188 1217 1218 1219 1220 1249 1250 1251 1252 1186 1188 1217 1218 + 1219 1220 1154 1156 1185 1186 1187 1188 1154 1156 1185 1186 1187 + 1188 1217 1218 1219 1220 1154 1156 1185 1186 1187 1188 1217 1218 + 1219 1220 1154 1156 1185 1186 1187 1188 1122 1124 1153 1154 1155 + 1156 1122 1124 1153 1154 1155 1156 1185 1186 1187 1188 1122 1124 + 1153 1154 1155 1156 1185 1186 1187 1188 1122 1124 1153 1154 1155 + 1156 1090 1092 1121 1122 1123 1124 1090 1092 1121 1122 1123 1124 + 1153 1154 1155 1156 1090 1092 1121 1122 1123 1124 1153 1154 1155 + 1156 1090 1092 1121 1122 1123 1124 1058 1060 1089 1090 1091 1092 + 1058 1060 1089 1090 1091 1092 1121 1122 1123 1124 1058 1060 1089 + 1090 1091 1092 1121 1122 1123 1124 1058 1060 1089 1090 1091 1092 + 1026 1028 1057 1058 1059 1060 1026 1028 1057 1058 1059 1060 1089 + 1090 1091 1092 1026 1028 1057 1058 1059 1060 1089 1090 1091 1092 + 1026 1028 1057 1058 1059 1060 994 996 1025 1026 1027 1028 994 + 996 1025 1026 1027 1028 1057 1058 1059 1060 994 996 1025 1026 + 1027 1028 1057 1058 1059 1060 994 996 1025 1026 1027 1028 962 + 964 993 994 995 996 1025 1026 1027 1028 962 964 993 994 + 995 996 962 964 993 994 995 996 962 964 993 994 995 + 996 1025 1026 1027 1028 930 932 961 962 963 964 930 932 + 961 962 963 964 993 994 995 996 930 932 961 962 963 + 964 993 994 995 996 930 932 961 962 963 964 898 900 + 929 930 931 932 961 962 963 964 898 900 929 930 931 + 932 961 962 963 964 898 900 929 930 931 932 898 900 + 929 930 931 932 866 868 897 898 899 900 929 930 931 + 932 866 868 897 898 899 900 866 868 897 898 899 900 + 866 868 897 898 899 900 929 930 931 932 834 836 865 + 866 867 868 834 836 865 866 867 868 897 898 899 900 + 834 836 865 866 867 868 897 898 899 900 834 836 865 + 866 867 868 802 804 833 834 835 836 865 866 867 868 + 802 804 833 834 835 836 865 866 867 868 802 804 833 + 834 835 836 802 804 833 834 835 836 770 772 801 802 + 803 804 833 834 835 836 770 772 801 802 803 804 770 + 772 801 802 803 804 770 772 801 802 803 804 833 834 + 835 836 738 740 769 770 771 772 738 740 769 770 771 + 772 801 802 803 804 738 740 769 770 771 772 801 802 + 803 804 738 740 769 770 771 772 706 708 737 738 739 + 740 769 770 771 772 706 708 737 738 739 740 769 770 + 771 772 706 708 737 738 739 740 706 708 737 738 739 + 740 674 676 705 706 707 708 737 738 739 740 674 676 + 705 706 707 708 674 676 705 706 707 708 674 676 705 + 706 707 708 737 738 739 740 642 644 673 674 675 676 + 642 644 673 674 675 676 705 706 707 708 642 644 673 + 674 675 676 705 706 707 708 642 644 673 674 675 676 + 578 580 609 610 611 612 641 642 643 644 578 580 609 + 610 611 612 641 642 643 644 610 612 641 642 643 644 + 673 674 675 676 610 612 641 642 643 644 673 674 675 + 676 610 612 641 642 643 644 610 612 641 642 643 644 + 18 20 49 50 51 52 18 20 49 50 51 52 18 + 20 49 50 51 52 18 20 49 50 51 52 50 52 + 81 82 83 84 18 20 49 50 51 52 81 82 83 + 84 18 20 49 50 51 52 81 82 83 84 50 52 + 81 82 83 84 82 84 113 114 115 116 50 52 81 + 82 83 84 113 114 115 116 50 52 81 82 83 84 + 113 114 115 116 82 84 113 114 115 116 114 116 145 + 146 147 148 82 84 113 114 115 116 145 146 147 148 + 82 84 113 114 115 116 145 146 147 148 114 116 145 + 146 147 148 146 148 177 178 179 180 114 116 145 146 + 147 148 177 178 179 180 114 116 145 146 147 148 177 + 178 179 180 146 148 177 178 179 180 178 180 209 210 + 211 212 146 148 177 178 179 180 209 210 211 212 146 + 148 177 178 179 180 209 210 211 212 178 180 209 210 + 211 212 210 212 241 242 243 244 178 180 209 210 211 + 212 241 242 243 244 178 180 209 210 211 212 241 242 + 243 244 210 212 241 242 243 244 242 244 273 274 275 + 276 210 212 241 242 243 244 273 274 275 276 210 212 + 241 242 243 244 273 274 275 276 242 244 273 274 275 + 276 242 244 273 274 275 276 305 306 307 308 274 276 + 305 306 307 308 274 276 305 306 307 308 242 244 273 + 274 275 276 305 306 307 308 306 308 337 338 339 340 + 274 276 305 306 307 308 337 338 339 340 274 276 305 + 306 307 308 337 338 339 340 306 308 337 338 339 340 + 306 308 337 338 339 340 369 370 371 372 306 308 337 + 338 339 340 369 370 371 372 338 340 369 370 371 372 + 338 340 369 370 371 372 338 340 369 370 371 372 401 + 402 403 404 370 372 401 402 403 404 370 372 401 402 + 403 404 338 340 369 370 371 372 401 402 403 404 402 + 404 433 434 435 436 370 372 401 402 403 404 433 434 + 435 436 370 372 401 402 403 404 433 434 435 436 402 + 404 433 434 435 436 402 404 433 434 435 436 465 466 + 467 468 402 404 433 434 435 436 465 466 467 468 434 + 436 465 466 467 468 434 436 465 466 467 468 434 436 + 465 466 467 468 497 498 499 500 466 468 497 498 499 + 500 466 468 497 498 499 500 434 436 465 466 467 468 + 497 498 499 500 498 500 529 530 531 532 466 468 497 + 498 499 500 529 530 531 532 466 468 497 498 499 500 + 529 530 531 532 498 500 529 530 531 532 498 500 529 + 530 531 532 561 562 563 564 498 500 529 530 531 532 + 561 562 563 564 530 532 561 562 563 564 530 532 561 + 562 563 564 530 532 561 562 563 564 593 594 595 596 + 562 564 593 594 595 596 562 564 593 594 595 596 530 + 532 561 562 563 564 593 594 595 596 594 596 625 626 + 627 628 562 564 593 594 595 596 625 626 627 628 562 + 564 593 594 595 596 625 626 627 628 594 596 625 626 + 627 628 1234 1236 1265 1266 1267 1268 1234 1236 1265 1266 1267 + 1268 1234 1236 1265 1266 1267 1268 1234 1236 1265 1266 1267 1268 + 1202 1204 1233 1234 1235 1236 1265 1266 1267 1268 1202 1204 1233 + 1234 1235 1236 1202 1204 1233 1234 1235 1236 1265 1266 1267 1268 + 1202 1204 1233 1234 1235 1236 1170 1172 1201 1202 1203 1204 1170 + 1172 1201 1202 1203 1204 1233 1234 1235 1236 1170 1172 1201 1202 + 1203 1204 1233 1234 1235 1236 1170 1172 1201 1202 1203 1204 1138 + 1140 1169 1170 1171 1172 1138 1140 1169 1170 1171 1172 1201 1202 + 1203 1204 1138 1140 1169 1170 1171 1172 1201 1202 1203 1204 1138 + 1140 1169 1170 1171 1172 1106 1108 1137 1138 1139 1140 1106 1108 + 1137 1138 1139 1140 1169 1170 1171 1172 1106 1108 1137 1138 1139 + 1140 1169 1170 1171 1172 1106 1108 1137 1138 1139 1140 1074 1076 + 1105 1106 1107 1108 1074 1076 1105 1106 1107 1108 1137 1138 1139 + 1140 1074 1076 1105 1106 1107 1108 1137 1138 1139 1140 1074 1076 + 1105 1106 1107 1108 1042 1044 1073 1074 1075 1076 1042 1044 1073 + 1074 1075 1076 1105 1106 1107 1108 1042 1044 1073 1074 1075 1076 + 1105 1106 1107 1108 1042 1044 1073 1074 1075 1076 1010 1012 1041 + 1042 1043 1044 1010 1012 1041 1042 1043 1044 1073 1074 1075 1076 + 1010 1012 1041 1042 1043 1044 1073 1074 1075 1076 1010 1012 1041 + 1042 1043 1044 978 980 1009 1010 1011 1012 1041 1042 1043 1044 + 978 980 1009 1010 1011 1012 978 980 1009 1010 1011 1012 978 + 980 1009 1010 1011 1012 1041 1042 1043 1044 946 948 977 978 + 979 980 946 948 977 978 979 980 1009 1010 1011 1012 946 + 948 977 978 979 980 1009 1010 1011 1012 946 948 977 978 + 979 980 914 916 945 946 947 948 977 978 979 980 914 + 916 945 946 947 948 977 978 979 980 914 916 945 946 + 947 948 914 916 945 946 947 948 882 884 913 914 915 + 916 945 946 947 948 882 884 913 914 915 916 882 884 + 913 914 915 916 882 884 913 914 915 916 945 946 947 + 948 850 852 881 882 883 884 850 852 881 882 883 884 + 913 914 915 916 850 852 881 882 883 884 913 914 915 + 916 850 852 881 882 883 884 818 820 849 850 851 852 + 881 882 883 884 818 820 849 850 851 852 881 882 883 + 884 818 820 849 850 851 852 818 820 849 850 851 852 + 786 788 817 818 819 820 849 850 851 852 786 788 817 + 818 819 820 786 788 817 818 819 820 786 788 817 818 + 819 820 849 850 851 852 754 756 785 786 787 788 754 + 756 785 786 787 788 817 818 819 820 754 756 785 786 + 787 788 817 818 819 820 754 756 785 786 787 788 722 + 724 753 754 755 756 785 786 787 788 722 724 753 754 + 755 756 785 786 787 788 722 724 753 754 755 756 722 + 724 753 754 755 756 690 692 721 722 723 724 753 754 + 755 756 690 692 721 722 723 724 690 692 721 722 723 + 724 690 692 721 722 723 724 753 754 755 756 658 660 + 689 690 691 692 658 660 689 690 691 692 721 722 723 + 724 658 660 689 690 691 692 721 722 723 724 658 660 + 689 690 691 692 594 596 625 626 627 628 657 658 659 + 660 594 596 625 626 627 628 657 658 659 660 626 628 + 657 658 659 660 689 690 691 692 626 628 657 658 659 + 660 689 690 691 692 626 628 657 658 659 660 626 628 + 657 658 659 660 22 24 26 28 53 54 55 56 57 + 58 59 60 22 24 26 28 53 54 55 56 57 58 + 59 60 22 24 26 28 53 54 55 56 57 58 59 + 60 22 24 26 28 53 54 55 56 57 58 59 60 + 22 24 26 28 53 54 55 56 57 58 59 60 22 + 24 26 28 53 54 55 56 57 58 59 60 54 56 + 57 58 59 60 85 86 87 88 89 90 91 92 22 + 24 26 28 53 54 55 56 57 58 59 60 85 86 + 87 88 89 90 91 92 22 24 26 28 53 54 55 + 56 57 58 59 60 85 86 87 88 89 90 91 92 + 22 24 26 28 53 54 55 56 57 58 59 60 85 + 86 87 88 89 90 91 92 22 24 26 28 53 54 + 55 56 57 58 59 60 85 86 87 88 89 90 91 + 92 22 24 26 28 53 54 55 56 57 58 59 60 + 85 86 87 88 89 90 91 92 22 24 26 28 53 + 54 55 56 57 58 59 60 85 86 87 88 89 90 + 91 92 54 56 57 58 59 60 85 86 87 88 89 + 90 91 92 86 88 89 90 91 92 117 118 119 120 + 121 122 123 124 54 56 57 58 59 60 85 86 87 + 88 89 90 91 92 117 118 119 120 121 122 123 124 + 54 56 57 58 59 60 85 86 87 88 89 90 91 + 92 117 118 119 120 121 122 123 124 54 56 57 58 + 59 60 85 86 87 88 89 90 91 92 117 118 119 + 120 121 122 123 124 54 56 57 58 59 60 85 86 + 87 88 89 90 91 92 117 118 119 120 121 122 123 + 124 54 56 57 58 59 60 85 86 87 88 89 90 + 91 92 117 118 119 120 121 122 123 124 54 56 57 + 58 59 60 85 86 87 88 89 90 91 92 117 118 + 119 120 121 122 123 124 86 88 89 90 91 92 117 + 118 119 120 121 122 123 124 118 120 121 122 123 124 + 149 150 151 152 153 154 155 156 86 88 89 90 91 + 92 117 118 119 120 121 122 123 124 149 150 151 152 + 153 154 155 156 86 88 89 90 91 92 117 118 119 + 120 121 122 123 124 149 150 151 152 153 154 155 156 + 86 88 89 90 91 92 117 118 119 120 121 122 123 + 124 149 150 151 152 153 154 155 156 86 88 89 90 + 91 92 117 118 119 120 121 122 123 124 149 150 151 + 152 153 154 155 156 86 88 89 90 91 92 117 118 + 119 120 121 122 123 124 149 150 151 152 153 154 155 + 156 86 88 89 90 91 92 117 118 119 120 121 122 + 123 124 149 150 151 152 153 154 155 156 118 120 121 + 122 123 124 149 150 151 152 153 154 155 156 150 152 + 153 154 155 156 181 182 183 184 185 186 187 188 118 + 120 121 122 123 124 149 150 151 152 153 154 155 156 + 181 182 183 184 185 186 187 188 118 120 121 122 123 + 124 149 150 151 152 153 154 155 156 181 182 183 184 + 185 186 187 188 118 120 121 122 123 124 149 150 151 + 152 153 154 155 156 181 182 183 184 185 186 187 188 + 118 120 121 122 123 124 149 150 151 152 153 154 155 + 156 181 182 183 184 185 186 187 188 118 120 121 122 + 123 124 149 150 151 152 153 154 155 156 181 182 183 + 184 185 186 187 188 118 120 121 122 123 124 149 150 + 151 152 153 154 155 156 181 182 183 184 185 186 187 + 188 150 152 153 154 155 156 181 182 183 184 185 186 + 187 188 182 184 185 186 187 188 213 214 215 216 217 + 218 219 220 150 152 153 154 155 156 181 182 183 184 + 185 186 187 188 213 214 215 216 217 218 219 220 150 + 152 153 154 155 156 181 182 183 184 185 186 187 188 + 213 214 215 216 217 218 219 220 150 152 153 154 155 + 156 181 182 183 184 185 186 187 188 213 214 215 216 + 217 218 219 220 150 152 153 154 155 156 181 182 183 + 184 185 186 187 188 213 214 215 216 217 218 219 220 + 150 152 153 154 155 156 181 182 183 184 185 186 187 + 188 213 214 215 216 217 218 219 220 150 152 153 154 + 155 156 181 182 183 184 185 186 187 188 213 214 215 + 216 217 218 219 220 182 184 185 186 187 188 213 214 + 215 216 217 218 219 220 214 216 217 218 219 220 245 + 246 247 248 249 250 251 252 182 184 185 186 187 188 + 213 214 215 216 217 218 219 220 245 246 247 248 249 + 250 251 252 182 184 185 186 187 188 213 214 215 216 + 217 218 219 220 245 246 247 248 249 250 251 252 182 + 184 185 186 187 188 213 214 215 216 217 218 219 220 + 245 246 247 248 249 250 251 252 182 184 185 186 187 + 188 213 214 215 216 217 218 219 220 245 246 247 248 + 249 250 251 252 182 184 185 186 187 188 213 214 215 + 216 217 218 219 220 245 246 247 248 249 250 251 252 + 182 184 185 186 187 188 213 214 215 216 217 218 219 + 220 245 246 247 248 249 250 251 252 214 216 217 218 + 219 220 245 246 247 248 249 250 251 252 246 248 249 + 250 251 252 277 278 279 280 281 282 283 284 214 216 + 217 218 219 220 245 246 247 248 249 250 251 252 277 + 278 279 280 281 282 283 284 214 216 217 218 219 220 + 245 246 247 248 249 250 251 252 277 278 279 280 281 + 282 283 284 214 216 217 218 219 220 245 246 247 248 + 249 250 251 252 277 278 279 280 281 282 283 284 214 + 216 217 218 219 220 245 246 247 248 249 250 251 252 + 277 278 279 280 281 282 283 284 214 216 217 218 219 + 220 245 246 247 248 249 250 251 252 277 278 279 280 + 281 282 283 284 214 216 217 218 219 220 245 246 247 + 248 249 250 251 252 277 278 279 280 281 282 283 284 + 246 248 249 250 251 252 277 278 279 280 281 282 283 + 284 278 280 281 282 283 284 309 310 311 312 313 314 + 315 316 246 248 249 250 251 252 277 278 279 280 281 + 282 283 284 309 310 311 312 313 314 315 316 246 248 + 249 250 251 252 277 278 279 280 281 282 283 284 309 + 310 311 312 313 314 315 316 246 248 249 250 251 252 + 277 278 279 280 281 282 283 284 309 310 311 312 313 + 314 315 316 246 248 249 250 251 252 277 278 279 280 + 281 282 283 284 309 310 311 312 313 314 315 316 246 + 248 249 250 251 252 277 278 279 280 281 282 283 284 + 309 310 311 312 313 314 315 316 246 248 249 250 251 + 252 277 278 279 280 281 282 283 284 309 310 311 312 + 313 314 315 316 278 280 281 282 283 284 309 310 311 + 312 313 314 315 316 310 312 313 314 315 316 341 342 + 343 344 345 346 347 348 278 280 281 282 283 284 309 + 310 311 312 313 314 315 316 341 342 343 344 345 346 + 347 348 278 280 281 282 283 284 309 310 311 312 313 + 314 315 316 341 342 343 344 345 346 347 348 278 280 + 281 282 283 284 309 310 311 312 313 314 315 316 341 + 342 343 344 345 346 347 348 278 280 281 282 283 284 + 309 310 311 312 313 314 315 316 341 342 343 344 345 + 346 347 348 278 280 281 282 283 284 309 310 311 312 + 313 314 315 316 341 342 343 344 345 346 347 348 278 + 280 281 282 283 284 309 310 311 312 313 314 315 316 + 341 342 343 344 345 346 347 348 310 312 313 314 315 + 316 341 342 343 344 345 346 347 348 342 344 345 346 + 347 348 373 374 375 376 377 378 379 380 310 312 313 + 314 315 316 341 342 343 344 345 346 347 348 373 374 + 375 376 377 378 379 380 310 312 313 314 315 316 341 + 342 343 344 345 346 347 348 373 374 375 376 377 378 + 379 380 310 312 313 314 315 316 341 342 343 344 345 + 346 347 348 373 374 375 376 377 378 379 380 310 312 + 313 314 315 316 341 342 343 344 345 346 347 348 373 + 374 375 376 377 378 379 380 310 312 313 314 315 316 + 341 342 343 344 345 346 347 348 373 374 375 376 377 + 378 379 380 310 312 313 314 315 316 341 342 343 344 + 345 346 347 348 373 374 375 376 377 378 379 380 342 + 344 345 346 347 348 373 374 375 376 377 378 379 380 + 374 376 377 378 379 380 405 406 407 408 409 410 411 + 412 342 344 345 346 347 348 373 374 375 376 377 378 + 379 380 405 406 407 408 409 410 411 412 342 344 345 + 346 347 348 373 374 375 376 377 378 379 380 405 406 + 407 408 409 410 411 412 342 344 345 346 347 348 373 + 374 375 376 377 378 379 380 405 406 407 408 409 410 + 411 412 342 344 345 346 347 348 373 374 375 376 377 + 378 379 380 405 406 407 408 409 410 411 412 342 344 + 345 346 347 348 373 374 375 376 377 378 379 380 405 + 406 407 408 409 410 411 412 342 344 345 346 347 348 + 373 374 375 376 377 378 379 380 405 406 407 408 409 + 410 411 412 374 376 377 378 379 380 405 406 407 408 + 409 410 411 412 406 408 409 410 411 412 437 438 439 + 440 441 442 443 444 374 376 377 378 379 380 405 406 + 407 408 409 410 411 412 437 438 439 440 441 442 443 + 444 374 376 377 378 379 380 405 406 407 408 409 410 + 411 412 437 438 439 440 441 442 443 444 374 376 377 + 378 379 380 405 406 407 408 409 410 411 412 437 438 + 439 440 441 442 443 444 374 376 377 378 379 380 405 + 406 407 408 409 410 411 412 437 438 439 440 441 442 + 443 444 374 376 377 378 379 380 405 406 407 408 409 + 410 411 412 437 438 439 440 441 442 443 444 374 376 + 377 378 379 380 405 406 407 408 409 410 411 412 437 + 438 439 440 441 442 443 444 406 408 409 410 411 412 + 437 438 439 440 441 442 443 444 406 408 409 410 411 + 412 437 438 439 440 441 442 443 444 469 470 471 472 + 473 474 475 476 406 408 409 410 411 412 437 438 439 + 440 441 442 443 444 469 470 471 472 473 474 475 476 + 406 408 409 410 411 412 437 438 439 440 441 442 443 + 444 469 470 471 472 473 474 475 476 406 408 409 410 + 411 412 437 438 439 440 441 442 443 444 469 470 471 + 472 473 474 475 476 406 408 409 410 411 412 437 438 + 439 440 441 442 443 444 469 470 471 472 473 474 475 + 476 406 408 409 410 411 412 437 438 439 440 441 442 + 443 444 469 470 471 472 473 474 475 476 438 440 441 + 442 443 444 469 470 471 472 473 474 475 476 438 440 + 441 442 443 444 469 470 471 472 473 474 475 476 438 + 440 441 442 443 444 469 470 471 472 473 474 475 476 + 501 502 503 504 505 506 507 508 470 472 473 474 475 + 476 501 502 503 504 505 506 507 508 470 472 473 474 + 475 476 501 502 503 504 505 506 507 508 438 440 441 + 442 443 444 469 470 471 472 473 474 475 476 501 502 + 503 504 505 506 507 508 438 440 441 442 443 444 469 + 470 471 472 473 474 475 476 501 502 503 504 505 506 + 507 508 438 440 441 442 443 444 469 470 471 472 473 + 474 475 476 501 502 503 504 505 506 507 508 438 440 + 441 442 443 444 469 470 471 472 473 474 475 476 501 + 502 503 504 505 506 507 508 438 440 441 442 443 444 + 469 470 471 472 473 474 475 476 501 502 503 504 505 + 506 507 508 502 504 505 506 507 508 533 534 535 536 + 537 538 539 540 470 472 473 474 475 476 501 502 503 + 504 505 506 507 508 533 534 535 536 537 538 539 540 + 470 472 473 474 475 476 501 502 503 504 505 506 507 + 508 533 534 535 536 537 538 539 540 470 472 473 474 + 475 476 501 502 503 504 505 506 507 508 533 534 535 + 536 537 538 539 540 470 472 473 474 475 476 501 502 + 503 504 505 506 507 508 533 534 535 536 537 538 539 + 540 470 472 473 474 475 476 501 502 503 504 505 506 + 507 508 533 534 535 536 537 538 539 540 470 472 473 + 474 475 476 501 502 503 504 505 506 507 508 533 534 + 535 536 537 538 539 540 502 504 505 506 507 508 533 + 534 535 536 537 538 539 540 502 504 505 506 507 508 + 533 534 535 536 537 538 539 540 565 566 567 568 569 + 570 571 572 502 504 505 506 507 508 533 534 535 536 + 537 538 539 540 565 566 567 568 569 570 571 572 502 + 504 505 506 507 508 533 534 535 536 537 538 539 540 + 565 566 567 568 569 570 571 572 502 504 505 506 507 + 508 533 534 535 536 537 538 539 540 565 566 567 568 + 569 570 571 572 502 504 505 506 507 508 533 534 535 + 536 537 538 539 540 565 566 567 568 569 570 571 572 + 502 504 505 506 507 508 533 534 535 536 537 538 539 + 540 565 566 567 568 569 570 571 572 534 536 537 538 + 539 540 565 566 567 568 569 570 571 572 534 536 537 + 538 539 540 565 566 567 568 569 570 571 572 534 536 + 537 538 539 540 565 566 567 568 569 570 571 572 597 + 598 599 600 601 602 603 604 566 568 569 570 571 572 + 597 598 599 600 601 602 603 604 566 568 569 570 571 + 572 597 598 599 600 601 602 603 604 534 536 537 538 + 539 540 565 566 567 568 569 570 571 572 597 598 599 + 600 601 602 603 604 534 536 537 538 539 540 565 566 + 567 568 569 570 571 572 597 598 599 600 601 602 603 + 604 534 536 537 538 539 540 565 566 567 568 569 570 + 571 572 597 598 599 600 601 602 603 604 534 536 537 + 538 539 540 565 566 567 568 569 570 571 572 597 598 + 599 600 601 602 603 604 534 536 537 538 539 540 565 + 566 567 568 569 570 571 572 597 598 599 600 601 602 + 603 604 598 600 601 602 603 604 629 630 631 632 633 + 634 635 636 566 568 569 570 571 572 597 598 599 600 + 601 602 603 604 629 630 631 632 633 634 635 636 566 + 568 569 570 571 572 597 598 599 600 601 602 603 604 + 629 630 631 632 633 634 635 636 566 568 569 570 571 + 572 597 598 599 600 601 602 603 604 629 630 631 632 + 633 634 635 636 566 568 569 570 571 572 597 598 599 + 600 601 602 603 604 629 630 631 632 633 634 635 636 + 566 568 569 570 571 572 597 598 599 600 601 602 603 + 604 629 630 631 632 633 634 635 636 566 568 569 570 + 571 572 597 598 599 600 601 602 603 604 629 630 631 + 632 633 634 635 636 598 600 601 602 603 604 629 630 + 631 632 633 634 635 636 1238 1240 1241 1242 1243 1244 1269 + 1270 1271 1272 1273 1274 1275 1276 1238 1240 1241 1242 1243 1244 + 1269 1270 1271 1272 1273 1274 1275 1276 1238 1240 1241 1242 1243 + 1244 1269 1270 1271 1272 1273 1274 1275 1276 1238 1240 1241 1242 + 1243 1244 1269 1270 1271 1272 1273 1274 1275 1276 1238 1240 1241 + 1242 1243 1244 1269 1270 1271 1272 1273 1274 1275 1276 1238 1240 + 1241 1242 1243 1244 1269 1270 1271 1272 1273 1274 1275 1276 1238 + 1240 1241 1242 1243 1244 1269 1270 1271 1272 1273 1274 1275 1276 + 1238 1240 1241 1242 1243 1244 1269 1270 1271 1272 1273 1274 1275 + 1276 1206 1208 1209 1210 1211 1212 1237 1238 1239 1240 1241 1242 + 1243 1244 1269 1270 1271 1272 1273 1274 1275 1276 1206 1208 1209 + 1210 1211 1212 1237 1238 1239 1240 1241 1242 1243 1244 1206 1208 + 1209 1210 1211 1212 1237 1238 1239 1240 1241 1242 1243 1244 1269 + 1270 1271 1272 1273 1274 1275 1276 1206 1208 1209 1210 1211 1212 + 1237 1238 1239 1240 1241 1242 1243 1244 1206 1208 1209 1210 1211 + 1212 1237 1238 1239 1240 1241 1242 1243 1244 1269 1270 1271 1272 + 1273 1274 1275 1276 1206 1208 1209 1210 1211 1212 1237 1238 1239 + 1240 1241 1242 1243 1244 1269 1270 1271 1272 1273 1274 1275 1276 + 1206 1208 1209 1210 1211 1212 1237 1238 1239 1240 1241 1242 1243 + 1244 1269 1270 1271 1272 1273 1274 1275 1276 1206 1208 1209 1210 + 1211 1212 1237 1238 1239 1240 1241 1242 1243 1244 1269 1270 1271 + 1272 1273 1274 1275 1276 1174 1176 1177 1178 1179 1180 1205 1206 + 1207 1208 1209 1210 1211 1212 1174 1176 1177 1178 1179 1180 1205 + 1206 1207 1208 1209 1210 1211 1212 1237 1238 1239 1240 1241 1242 + 1243 1244 1174 1176 1177 1178 1179 1180 1205 1206 1207 1208 1209 + 1210 1211 1212 1237 1238 1239 1240 1241 1242 1243 1244 1174 1176 + 1177 1178 1179 1180 1205 1206 1207 1208 1209 1210 1211 1212 1237 + 1238 1239 1240 1241 1242 1243 1244 1174 1176 1177 1178 1179 1180 + 1205 1206 1207 1208 1209 1210 1211 1212 1237 1238 1239 1240 1241 + 1242 1243 1244 1174 1176 1177 1178 1179 1180 1205 1206 1207 1208 + 1209 1210 1211 1212 1237 1238 1239 1240 1241 1242 1243 1244 1174 + 1176 1177 1178 1179 1180 1205 1206 1207 1208 1209 1210 1211 1212 + 1237 1238 1239 1240 1241 1242 1243 1244 1174 1176 1177 1178 1179 + 1180 1205 1206 1207 1208 1209 1210 1211 1212 1142 1144 1145 1146 + 1147 1148 1173 1174 1175 1176 1177 1178 1179 1180 1142 1144 1145 + 1146 1147 1148 1173 1174 1175 1176 1177 1178 1179 1180 1205 1206 + 1207 1208 1209 1210 1211 1212 1142 1144 1145 1146 1147 1148 1173 + 1174 1175 1176 1177 1178 1179 1180 1205 1206 1207 1208 1209 1210 + 1211 1212 1142 1144 1145 1146 1147 1148 1173 1174 1175 1176 1177 + 1178 1179 1180 1205 1206 1207 1208 1209 1210 1211 1212 1142 1144 + 1145 1146 1147 1148 1173 1174 1175 1176 1177 1178 1179 1180 1205 + 1206 1207 1208 1209 1210 1211 1212 1142 1144 1145 1146 1147 1148 + 1173 1174 1175 1176 1177 1178 1179 1180 1205 1206 1207 1208 1209 + 1210 1211 1212 1142 1144 1145 1146 1147 1148 1173 1174 1175 1176 + 1177 1178 1179 1180 1205 1206 1207 1208 1209 1210 1211 1212 1142 + 1144 1145 1146 1147 1148 1173 1174 1175 1176 1177 1178 1179 1180 + 1110 1112 1113 1114 1115 1116 1141 1142 1143 1144 1145 1146 1147 + 1148 1110 1112 1113 1114 1115 1116 1141 1142 1143 1144 1145 1146 + 1147 1148 1173 1174 1175 1176 1177 1178 1179 1180 1110 1112 1113 + 1114 1115 1116 1141 1142 1143 1144 1145 1146 1147 1148 1173 1174 + 1175 1176 1177 1178 1179 1180 1110 1112 1113 1114 1115 1116 1141 + 1142 1143 1144 1145 1146 1147 1148 1173 1174 1175 1176 1177 1178 + 1179 1180 1110 1112 1113 1114 1115 1116 1141 1142 1143 1144 1145 + 1146 1147 1148 1173 1174 1175 1176 1177 1178 1179 1180 1110 1112 + 1113 1114 1115 1116 1141 1142 1143 1144 1145 1146 1147 1148 1173 + 1174 1175 1176 1177 1178 1179 1180 1110 1112 1113 1114 1115 1116 + 1141 1142 1143 1144 1145 1146 1147 1148 1173 1174 1175 1176 1177 + 1178 1179 1180 1110 1112 1113 1114 1115 1116 1141 1142 1143 1144 + 1145 1146 1147 1148 1078 1080 1081 1082 1083 1084 1109 1110 1111 + 1112 1113 1114 1115 1116 1078 1080 1081 1082 1083 1084 1109 1110 + 1111 1112 1113 1114 1115 1116 1141 1142 1143 1144 1145 1146 1147 + 1148 1078 1080 1081 1082 1083 1084 1109 1110 1111 1112 1113 1114 + 1115 1116 1141 1142 1143 1144 1145 1146 1147 1148 1078 1080 1081 + 1082 1083 1084 1109 1110 1111 1112 1113 1114 1115 1116 1141 1142 + 1143 1144 1145 1146 1147 1148 1078 1080 1081 1082 1083 1084 1109 + 1110 1111 1112 1113 1114 1115 1116 1141 1142 1143 1144 1145 1146 + 1147 1148 1078 1080 1081 1082 1083 1084 1109 1110 1111 1112 1113 + 1114 1115 1116 1141 1142 1143 1144 1145 1146 1147 1148 1078 1080 + 1081 1082 1083 1084 1109 1110 1111 1112 1113 1114 1115 1116 1141 + 1142 1143 1144 1145 1146 1147 1148 1078 1080 1081 1082 1083 1084 + 1109 1110 1111 1112 1113 1114 1115 1116 1046 1048 1049 1050 1051 + 1052 1077 1078 1079 1080 1081 1082 1083 1084 1046 1048 1049 1050 + 1051 1052 1077 1078 1079 1080 1081 1082 1083 1084 1109 1110 1111 + 1112 1113 1114 1115 1116 1046 1048 1049 1050 1051 1052 1077 1078 + 1079 1080 1081 1082 1083 1084 1109 1110 1111 1112 1113 1114 1115 + 1116 1046 1048 1049 1050 1051 1052 1077 1078 1079 1080 1081 1082 + 1083 1084 1109 1110 1111 1112 1113 1114 1115 1116 1046 1048 1049 + 1050 1051 1052 1077 1078 1079 1080 1081 1082 1083 1084 1109 1110 + 1111 1112 1113 1114 1115 1116 1046 1048 1049 1050 1051 1052 1077 + 1078 1079 1080 1081 1082 1083 1084 1109 1110 1111 1112 1113 1114 + 1115 1116 1046 1048 1049 1050 1051 1052 1077 1078 1079 1080 1081 + 1082 1083 1084 1109 1110 1111 1112 1113 1114 1115 1116 1046 1048 + 1049 1050 1051 1052 1077 1078 1079 1080 1081 1082 1083 1084 1014 + 1016 1017 1018 1019 1020 1045 1046 1047 1048 1049 1050 1051 1052 + 1014 1016 1017 1018 1019 1020 1045 1046 1047 1048 1049 1050 1051 + 1052 1077 1078 1079 1080 1081 1082 1083 1084 1014 1016 1017 1018 + 1019 1020 1045 1046 1047 1048 1049 1050 1051 1052 1077 1078 1079 + 1080 1081 1082 1083 1084 1014 1016 1017 1018 1019 1020 1045 1046 + 1047 1048 1049 1050 1051 1052 1077 1078 1079 1080 1081 1082 1083 + 1084 1014 1016 1017 1018 1019 1020 1045 1046 1047 1048 1049 1050 + 1051 1052 1077 1078 1079 1080 1081 1082 1083 1084 1014 1016 1017 + 1018 1019 1020 1045 1046 1047 1048 1049 1050 1051 1052 1077 1078 + 1079 1080 1081 1082 1083 1084 1014 1016 1017 1018 1019 1020 1045 + 1046 1047 1048 1049 1050 1051 1052 1077 1078 1079 1080 1081 1082 + 1083 1084 1014 1016 1017 1018 1019 1020 1045 1046 1047 1048 1049 + 1050 1051 1052 982 984 985 986 987 988 1013 1014 1015 1016 + 1017 1018 1019 1020 982 984 985 986 987 988 1013 1014 1015 + 1016 1017 1018 1019 1020 1045 1046 1047 1048 1049 1050 1051 1052 + 982 984 985 986 987 988 1013 1014 1015 1016 1017 1018 1019 + 1020 1045 1046 1047 1048 1049 1050 1051 1052 982 984 985 986 + 987 988 1013 1014 1015 1016 1017 1018 1019 1020 1045 1046 1047 + 1048 1049 1050 1051 1052 982 984 985 986 987 988 1013 1014 + 1015 1016 1017 1018 1019 1020 1045 1046 1047 1048 1049 1050 1051 + 1052 982 984 985 986 987 988 1013 1014 1015 1016 1017 1018 + 1019 1020 1045 1046 1047 1048 1049 1050 1051 1052 982 984 985 + 986 987 988 1013 1014 1015 1016 1017 1018 1019 1020 1045 1046 + 1047 1048 1049 1050 1051 1052 982 984 985 986 987 988 1013 + 1014 1015 1016 1017 1018 1019 1020 950 952 953 954 955 956 + 981 982 983 984 985 986 987 988 950 952 953 954 955 + 956 981 982 983 984 985 986 987 988 1013 1014 1015 1016 + 1017 1018 1019 1020 950 952 953 954 955 956 981 982 983 + 984 985 986 987 988 1013 1014 1015 1016 1017 1018 1019 1020 + 950 952 953 954 955 956 981 982 983 984 985 986 987 + 988 1013 1014 1015 1016 1017 1018 1019 1020 950 952 953 954 + 955 956 981 982 983 984 985 986 987 988 1013 1014 1015 + 1016 1017 1018 1019 1020 950 952 953 954 955 956 981 982 + 983 984 985 986 987 988 1013 1014 1015 1016 1017 1018 1019 + 1020 950 952 953 954 955 956 981 982 983 984 985 986 + 987 988 1013 1014 1015 1016 1017 1018 1019 1020 950 952 953 + 954 955 956 981 982 983 984 985 986 987 988 918 920 + 921 922 923 924 949 950 951 952 953 954 955 956 918 + 920 921 922 923 924 949 950 951 952 953 954 955 956 + 981 982 983 984 985 986 987 988 918 920 921 922 923 + 924 949 950 951 952 953 954 955 956 981 982 983 984 + 985 986 987 988 918 920 921 922 923 924 949 950 951 + 952 953 954 955 956 981 982 983 984 985 986 987 988 + 918 920 921 922 923 924 949 950 951 952 953 954 955 + 956 981 982 983 984 985 986 987 988 918 920 921 922 + 923 924 949 950 951 952 953 954 955 956 981 982 983 + 984 985 986 987 988 918 920 921 922 923 924 949 950 + 951 952 953 954 955 956 981 982 983 984 985 986 987 + 988 918 920 921 922 923 924 949 950 951 952 953 954 + 955 956 886 888 889 890 891 892 917 918 919 920 921 + 922 923 924 886 888 889 890 891 892 917 918 919 920 + 921 922 923 924 949 950 951 952 953 954 955 956 886 + 888 889 890 891 892 917 918 919 920 921 922 923 924 + 949 950 951 952 953 954 955 956 886 888 889 890 891 + 892 917 918 919 920 921 922 923 924 949 950 951 952 + 953 954 955 956 886 888 889 890 891 892 917 918 919 + 920 921 922 923 924 949 950 951 952 953 954 955 956 + 886 888 889 890 891 892 917 918 919 920 921 922 923 + 924 949 950 951 952 953 954 955 956 886 888 889 890 + 891 892 917 918 919 920 921 922 923 924 949 950 951 + 952 953 954 955 956 886 888 889 890 891 892 917 918 + 919 920 921 922 923 924 854 856 857 858 859 860 885 + 886 887 888 889 890 891 892 854 856 857 858 859 860 + 885 886 887 888 889 890 891 892 917 918 919 920 921 + 922 923 924 854 856 857 858 859 860 885 886 887 888 + 889 890 891 892 917 918 919 920 921 922 923 924 854 + 856 857 858 859 860 885 886 887 888 889 890 891 892 + 917 918 919 920 921 922 923 924 854 856 857 858 859 + 860 885 886 887 888 889 890 891 892 917 918 919 920 + 921 922 923 924 854 856 857 858 859 860 885 886 887 + 888 889 890 891 892 917 918 919 920 921 922 923 924 + 854 856 857 858 859 860 885 886 887 888 889 890 891 + 892 917 918 919 920 921 922 923 924 854 856 857 858 + 859 860 885 886 887 888 889 890 891 892 822 824 825 + 826 827 828 853 854 855 856 857 858 859 860 885 886 + 887 888 889 890 891 892 822 824 825 826 827 828 853 + 854 855 856 857 858 859 860 885 886 887 888 889 890 + 891 892 822 824 825 826 827 828 853 854 855 856 857 + 858 859 860 885 886 887 888 889 890 891 892 822 824 + 825 826 827 828 853 854 855 856 857 858 859 860 885 + 886 887 888 889 890 891 892 822 824 825 826 827 828 + 853 854 855 856 857 858 859 860 885 886 887 888 889 + 890 891 892 822 824 825 826 827 828 853 854 855 856 + 857 858 859 860 885 886 887 888 889 890 891 892 822 + 824 825 826 827 828 853 854 855 856 857 858 859 860 + 822 824 825 826 827 828 853 854 855 856 857 858 859 + 860 790 792 793 794 795 796 821 822 823 824 825 826 + 827 828 853 854 855 856 857 858 859 860 790 792 793 + 794 795 796 821 822 823 824 825 826 827 828 790 792 + 793 794 795 796 821 822 823 824 825 826 827 828 790 + 792 793 794 795 796 821 822 823 824 825 826 827 828 + 853 854 855 856 857 858 859 860 790 792 793 794 795 + 796 821 822 823 824 825 826 827 828 853 854 855 856 + 857 858 859 860 790 792 793 794 795 796 821 822 823 + 824 825 826 827 828 853 854 855 856 857 858 859 860 + 790 792 793 794 795 796 821 822 823 824 825 826 827 + 828 853 854 855 856 857 858 859 860 790 792 793 794 + 795 796 821 822 823 824 825 826 827 828 853 854 855 + 856 857 858 859 860 758 760 761 762 763 764 789 790 + 791 792 793 794 795 796 758 760 761 762 763 764 789 + 790 791 792 793 794 795 796 821 822 823 824 825 826 + 827 828 758 760 761 762 763 764 789 790 791 792 793 + 794 795 796 821 822 823 824 825 826 827 828 758 760 + 761 762 763 764 789 790 791 792 793 794 795 796 821 + 822 823 824 825 826 827 828 758 760 761 762 763 764 + 789 790 791 792 793 794 795 796 821 822 823 824 825 + 826 827 828 758 760 761 762 763 764 789 790 791 792 + 793 794 795 796 821 822 823 824 825 826 827 828 758 + 760 761 762 763 764 789 790 791 792 793 794 795 796 + 821 822 823 824 825 826 827 828 758 760 761 762 763 + 764 789 790 791 792 793 794 795 796 726 728 729 730 + 731 732 757 758 759 760 761 762 763 764 789 790 791 + 792 793 794 795 796 726 728 729 730 731 732 757 758 + 759 760 761 762 763 764 789 790 791 792 793 794 795 + 796 726 728 729 730 731 732 757 758 759 760 761 762 + 763 764 789 790 791 792 793 794 795 796 726 728 729 + 730 731 732 757 758 759 760 761 762 763 764 789 790 + 791 792 793 794 795 796 726 728 729 730 731 732 757 + 758 759 760 761 762 763 764 789 790 791 792 793 794 + 795 796 726 728 729 730 731 732 757 758 759 760 761 + 762 763 764 789 790 791 792 793 794 795 796 726 728 + 729 730 731 732 757 758 759 760 761 762 763 764 726 + 728 729 730 731 732 757 758 759 760 761 762 763 764 + 694 696 697 698 699 700 725 726 727 728 729 730 731 + 732 757 758 759 760 761 762 763 764 694 696 697 698 + 699 700 725 726 727 728 729 730 731 732 694 696 697 + 698 699 700 725 726 727 728 729 730 731 732 694 696 + 697 698 699 700 725 726 727 728 729 730 731 732 757 + 758 759 760 761 762 763 764 694 696 697 698 699 700 + 725 726 727 728 729 730 731 732 757 758 759 760 761 + 762 763 764 694 696 697 698 699 700 725 726 727 728 + 729 730 731 732 757 758 759 760 761 762 763 764 694 + 696 697 698 699 700 725 726 727 728 729 730 731 732 + 757 758 759 760 761 762 763 764 694 696 697 698 699 + 700 725 726 727 728 729 730 731 732 757 758 759 760 + 761 762 763 764 662 664 665 666 667 668 693 694 695 + 696 697 698 699 700 662 664 665 666 667 668 693 694 + 695 696 697 698 699 700 725 726 727 728 729 730 731 + 732 662 664 665 666 667 668 693 694 695 696 697 698 + 699 700 725 726 727 728 729 730 731 732 662 664 665 + 666 667 668 693 694 695 696 697 698 699 700 725 726 + 727 728 729 730 731 732 662 664 665 666 667 668 693 + 694 695 696 697 698 699 700 725 726 727 728 729 730 + 731 732 662 664 665 666 667 668 693 694 695 696 697 + 698 699 700 725 726 727 728 729 730 731 732 662 664 + 665 666 667 668 693 694 695 696 697 698 699 700 725 + 726 727 728 729 730 731 732 662 664 665 666 667 668 + 693 694 695 696 697 698 699 700 598 600 601 602 603 + 604 629 630 631 632 633 634 635 636 661 662 663 664 + 665 666 667 668 598 600 601 602 603 604 629 630 631 + 632 633 634 635 636 661 662 663 664 665 666 667 668 + 598 600 601 602 603 604 629 630 631 632 633 634 635 + 636 661 662 663 664 665 666 667 668 598 600 601 602 + 603 604 629 630 631 632 633 634 635 636 661 662 663 + 664 665 666 667 668 598 600 601 602 603 604 629 630 + 631 632 633 634 635 636 661 662 663 664 665 666 667 + 668 598 600 601 602 603 604 629 630 631 632 633 634 + 635 636 661 662 663 664 665 666 667 668 630 632 633 + 634 635 636 661 662 663 664 665 666 667 668 693 694 + 695 696 697 698 699 700 630 632 633 634 635 636 661 + 662 663 664 665 666 667 668 693 694 695 696 697 698 + 699 700 630 632 633 634 635 636 661 662 663 664 665 + 666 667 668 693 694 695 696 697 698 699 700 630 632 + 633 634 635 636 661 662 663 664 665 666 667 668 693 + 694 695 696 697 698 699 700 630 632 633 634 635 636 + 661 662 663 664 665 666 667 668 693 694 695 696 697 + 698 699 700 630 632 633 634 635 636 661 662 663 664 + 665 666 667 668 693 694 695 696 697 698 699 700 630 + 632 633 634 635 636 661 662 663 664 665 666 667 668 + 630 632 633 634 635 636 661 662 663 664 665 666 667 + 668 6 8 10 12 14 16 37 38 39 40 41 42 + 43 44 45 46 47 48 6 8 10 12 14 16 37 + 38 39 40 41 42 43 44 45 46 47 48 6 8 + 10 12 14 16 37 38 39 40 41 42 43 44 45 + 46 47 48 6 8 10 12 14 16 37 38 39 40 + 41 42 43 44 45 46 47 48 6 8 10 12 14 + 16 37 38 39 40 41 42 43 44 45 46 47 48 + 6 8 10 12 14 16 37 38 39 40 41 42 43 + 44 45 46 47 48 6 8 10 12 14 16 37 38 + 39 40 41 42 43 44 45 46 47 48 6 8 10 + 12 14 16 37 38 39 40 41 42 43 44 45 46 + 47 48 6 8 10 12 14 16 37 38 39 40 41 + 42 43 44 45 46 47 48 6 8 10 12 14 16 + 37 38 39 40 41 42 43 44 45 46 47 48 37 + 38 39 40 42 44 46 48 69 70 71 72 73 74 + 75 76 77 78 79 80 6 8 10 12 14 16 37 + 38 39 40 41 42 43 44 45 46 47 48 69 70 + 71 72 73 74 75 76 77 78 79 80 6 8 10 + 12 14 16 37 38 39 40 41 42 43 44 45 46 + 47 48 69 70 71 72 73 74 75 76 77 78 79 + 80 6 8 10 12 14 16 37 38 39 40 41 42 + 43 44 45 46 47 48 69 70 71 72 73 74 75 + 76 77 78 79 80 6 8 10 12 14 16 37 38 + 39 40 41 42 43 44 45 46 47 48 69 70 71 + 72 73 74 75 76 77 78 79 80 6 8 10 12 + 14 16 37 38 39 40 41 42 43 44 45 46 47 + 48 69 70 71 72 73 74 75 76 77 78 79 80 + 6 8 10 12 14 16 37 38 39 40 41 42 43 + 44 45 46 47 48 69 70 71 72 73 74 75 76 + 77 78 79 80 6 8 10 12 14 16 37 38 39 + 40 41 42 43 44 45 46 47 48 69 70 71 72 + 73 74 75 76 77 78 79 80 6 8 10 12 14 + 16 37 38 39 40 41 42 43 44 45 46 47 48 + 69 70 71 72 73 74 75 76 77 78 79 80 37 + 38 39 40 42 44 46 48 69 70 71 72 73 74 + 75 76 77 78 79 80 37 38 39 40 42 44 46 + 48 69 70 71 72 73 74 75 76 77 78 79 80 + 37 38 39 40 42 44 46 48 69 70 71 72 73 + 74 75 76 77 78 79 80 69 70 71 72 74 76 + 78 80 101 102 103 104 105 106 107 108 109 110 111 + 112 37 38 39 40 42 44 46 48 69 70 71 72 + 73 74 75 76 77 78 79 80 101 102 103 104 105 + 106 107 108 109 110 111 112 37 38 39 40 42 44 + 46 48 69 70 71 72 73 74 75 76 77 78 79 + 80 101 102 103 104 105 106 107 108 109 110 111 112 + 37 38 39 40 42 44 46 48 69 70 71 72 73 + 74 75 76 77 78 79 80 101 102 103 104 105 106 + 107 108 109 110 111 112 37 38 39 40 42 44 46 + 48 69 70 71 72 73 74 75 76 77 78 79 80 + 101 102 103 104 105 106 107 108 109 110 111 112 37 + 38 39 40 42 44 46 48 69 70 71 72 73 74 + 75 76 77 78 79 80 101 102 103 104 105 106 107 + 108 109 110 111 112 37 38 39 40 42 44 46 48 + 69 70 71 72 73 74 75 76 77 78 79 80 101 + 102 103 104 105 106 107 108 109 110 111 112 37 38 + 39 40 42 44 46 48 69 70 71 72 73 74 75 + 76 77 78 79 80 101 102 103 104 105 106 107 108 + 109 110 111 112 37 38 39 40 42 44 46 48 69 + 70 71 72 73 74 75 76 77 78 79 80 101 102 + 103 104 105 106 107 108 109 110 111 112 69 70 71 + 72 74 76 78 80 101 102 103 104 105 106 107 108 + 109 110 111 112 69 70 71 72 74 76 78 80 101 + 102 103 104 105 106 107 108 109 110 111 112 69 70 + 71 72 74 76 78 80 101 102 103 104 105 106 107 + 108 109 110 111 112 101 102 103 104 106 108 110 112 + 133 134 135 136 137 138 139 140 141 142 143 144 69 + 70 71 72 74 76 78 80 101 102 103 104 105 106 + 107 108 109 110 111 112 133 134 135 136 137 138 139 + 140 141 142 143 144 69 70 71 72 74 76 78 80 + 101 102 103 104 105 106 107 108 109 110 111 112 133 + 134 135 136 137 138 139 140 141 142 143 144 69 70 + 71 72 74 76 78 80 101 102 103 104 105 106 107 + 108 109 110 111 112 133 134 135 136 137 138 139 140 + 141 142 143 144 69 70 71 72 74 76 78 80 101 + 102 103 104 105 106 107 108 109 110 111 112 133 134 + 135 136 137 138 139 140 141 142 143 144 69 70 71 + 72 74 76 78 80 101 102 103 104 105 106 107 108 + 109 110 111 112 133 134 135 136 137 138 139 140 141 + 142 143 144 69 70 71 72 74 76 78 80 101 102 + 103 104 105 106 107 108 109 110 111 112 133 134 135 + 136 137 138 139 140 141 142 143 144 69 70 71 72 + 74 76 78 80 101 102 103 104 105 106 107 108 109 + 110 111 112 133 134 135 136 137 138 139 140 141 142 + 143 144 69 70 71 72 74 76 78 80 101 102 103 + 104 105 106 107 108 109 110 111 112 133 134 135 136 + 137 138 139 140 141 142 143 144 101 102 103 104 106 + 108 110 112 133 134 135 136 137 138 139 140 141 142 + 143 144 101 102 103 104 106 108 110 112 133 134 135 + 136 137 138 139 140 141 142 143 144 101 102 103 104 + 106 108 110 112 133 134 135 136 137 138 139 140 141 + 142 143 144 133 134 135 136 138 140 142 144 165 166 + 167 168 169 170 171 172 173 174 175 176 101 102 103 + 104 106 108 110 112 133 134 135 136 137 138 139 140 + 141 142 143 144 165 166 167 168 169 170 171 172 173 + 174 175 176 101 102 103 104 106 108 110 112 133 134 + 135 136 137 138 139 140 141 142 143 144 165 166 167 + 168 169 170 171 172 173 174 175 176 101 102 103 104 + 106 108 110 112 133 134 135 136 137 138 139 140 141 + 142 143 144 165 166 167 168 169 170 171 172 173 174 + 175 176 101 102 103 104 106 108 110 112 133 134 135 + 136 137 138 139 140 141 142 143 144 165 166 167 168 + 169 170 171 172 173 174 175 176 101 102 103 104 106 + 108 110 112 133 134 135 136 137 138 139 140 141 142 + 143 144 165 166 167 168 169 170 171 172 173 174 175 + 176 101 102 103 104 106 108 110 112 133 134 135 136 + 137 138 139 140 141 142 143 144 165 166 167 168 169 + 170 171 172 173 174 175 176 101 102 103 104 106 108 + 110 112 133 134 135 136 137 138 139 140 141 142 143 + 144 165 166 167 168 169 170 171 172 173 174 175 176 + 101 102 103 104 106 108 110 112 133 134 135 136 137 + 138 139 140 141 142 143 144 165 166 167 168 169 170 + 171 172 173 174 175 176 133 134 135 136 138 140 142 + 144 165 166 167 168 169 170 171 172 173 174 175 176 + 133 134 135 136 138 140 142 144 165 166 167 168 169 + 170 171 172 173 174 175 176 133 134 135 136 138 140 + 142 144 165 166 167 168 169 170 171 172 173 174 175 + 176 165 166 167 168 170 172 174 176 197 198 199 200 + 201 202 203 204 205 206 207 208 133 134 135 136 138 + 140 142 144 165 166 167 168 169 170 171 172 173 174 + 175 176 197 198 199 200 201 202 203 204 205 206 207 + 208 133 134 135 136 138 140 142 144 165 166 167 168 + 169 170 171 172 173 174 175 176 197 198 199 200 201 + 202 203 204 205 206 207 208 133 134 135 136 138 140 + 142 144 165 166 167 168 169 170 171 172 173 174 175 + 176 197 198 199 200 201 202 203 204 205 206 207 208 + 133 134 135 136 138 140 142 144 165 166 167 168 169 + 170 171 172 173 174 175 176 197 198 199 200 201 202 + 203 204 205 206 207 208 133 134 135 136 138 140 142 + 144 165 166 167 168 169 170 171 172 173 174 175 176 + 197 198 199 200 201 202 203 204 205 206 207 208 133 + 134 135 136 138 140 142 144 165 166 167 168 169 170 + 171 172 173 174 175 176 197 198 199 200 201 202 203 + 204 205 206 207 208 133 134 135 136 138 140 142 144 + 165 166 167 168 169 170 171 172 173 174 175 176 197 + 198 199 200 201 202 203 204 205 206 207 208 133 134 + 135 136 138 140 142 144 165 166 167 168 169 170 171 + 172 173 174 175 176 197 198 199 200 201 202 203 204 + 205 206 207 208 165 166 167 168 170 172 174 176 197 + 198 199 200 201 202 203 204 205 206 207 208 165 166 + 167 168 170 172 174 176 197 198 199 200 201 202 203 + 204 205 206 207 208 165 166 167 168 170 172 174 176 + 197 198 199 200 201 202 203 204 205 206 207 208 197 + 198 199 200 202 204 206 208 229 230 231 232 233 234 + 235 236 237 238 239 240 165 166 167 168 170 172 174 + 176 197 198 199 200 201 202 203 204 205 206 207 208 + 229 230 231 232 233 234 235 236 237 238 239 240 165 + 166 167 168 170 172 174 176 197 198 199 200 201 202 + 203 204 205 206 207 208 229 230 231 232 233 234 235 + 236 237 238 239 240 165 166 167 168 170 172 174 176 + 197 198 199 200 201 202 203 204 205 206 207 208 229 + 230 231 232 233 234 235 236 237 238 239 240 165 166 + 167 168 170 172 174 176 197 198 199 200 201 202 203 + 204 205 206 207 208 229 230 231 232 233 234 235 236 + 237 238 239 240 165 166 167 168 170 172 174 176 197 + 198 199 200 201 202 203 204 205 206 207 208 229 230 + 231 232 233 234 235 236 237 238 239 240 165 166 167 + 168 170 172 174 176 197 198 199 200 201 202 203 204 + 205 206 207 208 229 230 231 232 233 234 235 236 237 + 238 239 240 165 166 167 168 170 172 174 176 197 198 + 199 200 201 202 203 204 205 206 207 208 229 230 231 + 232 233 234 235 236 237 238 239 240 165 166 167 168 + 170 172 174 176 197 198 199 200 201 202 203 204 205 + 206 207 208 229 230 231 232 233 234 235 236 237 238 + 239 240 197 198 199 200 202 204 206 208 229 230 231 + 232 233 234 235 236 237 238 239 240 197 198 199 200 + 202 204 206 208 229 230 231 232 233 234 235 236 237 + 238 239 240 197 198 199 200 202 204 206 208 229 230 + 231 232 233 234 235 236 237 238 239 240 229 230 231 + 232 234 236 238 240 261 262 263 264 265 266 267 268 + 269 270 271 272 197 198 199 200 202 204 206 208 229 + 230 231 232 233 234 235 236 237 238 239 240 261 262 + 263 264 265 266 267 268 269 270 271 272 197 198 199 + 200 202 204 206 208 229 230 231 232 233 234 235 236 + 237 238 239 240 261 262 263 264 265 266 267 268 269 + 270 271 272 197 198 199 200 202 204 206 208 229 230 + 231 232 233 234 235 236 237 238 239 240 261 262 263 + 264 265 266 267 268 269 270 271 272 197 198 199 200 + 202 204 206 208 229 230 231 232 233 234 235 236 237 + 238 239 240 261 262 263 264 265 266 267 268 269 270 + 271 272 197 198 199 200 202 204 206 208 229 230 231 + 232 233 234 235 236 237 238 239 240 261 262 263 264 + 265 266 267 268 269 270 271 272 197 198 199 200 202 + 204 206 208 229 230 231 232 233 234 235 236 237 238 + 239 240 261 262 263 264 265 266 267 268 269 270 271 + 272 197 198 199 200 202 204 206 208 229 230 231 232 + 233 234 235 236 237 238 239 240 261 262 263 264 265 + 266 267 268 269 270 271 272 197 198 199 200 202 204 + 206 208 229 230 231 232 233 234 235 236 237 238 239 + 240 261 262 263 264 265 266 267 268 269 270 271 272 + 229 230 231 232 234 236 238 240 261 262 263 264 265 + 266 267 268 269 270 271 272 229 230 231 232 234 236 + 238 240 261 262 263 264 265 266 267 268 269 270 271 + 272 229 230 231 232 234 236 238 240 261 262 263 264 + 265 266 267 268 269 270 271 272 261 262 263 264 266 + 268 270 272 293 294 295 296 297 298 299 300 301 302 + 303 304 229 230 231 232 234 236 238 240 261 262 263 + 264 265 266 267 268 269 270 271 272 293 294 295 296 + 297 298 299 300 301 302 303 304 229 230 231 232 234 + 236 238 240 261 262 263 264 265 266 267 268 269 270 + 271 272 293 294 295 296 297 298 299 300 301 302 303 + 304 229 230 231 232 234 236 238 240 261 262 263 264 + 265 266 267 268 269 270 271 272 293 294 295 296 297 + 298 299 300 301 302 303 304 229 230 231 232 234 236 + 238 240 261 262 263 264 265 266 267 268 269 270 271 + 272 293 294 295 296 297 298 299 300 301 302 303 304 + 229 230 231 232 234 236 238 240 261 262 263 264 265 + 266 267 268 269 270 271 272 293 294 295 296 297 298 + 299 300 301 302 303 304 229 230 231 232 234 236 238 + 240 261 262 263 264 265 266 267 268 269 270 271 272 + 293 294 295 296 297 298 299 300 301 302 303 304 229 + 230 231 232 234 236 238 240 261 262 263 264 265 266 + 267 268 269 270 271 272 293 294 295 296 297 298 299 + 300 301 302 303 304 229 230 231 232 234 236 238 240 + 261 262 263 264 265 266 267 268 269 270 271 272 293 + 294 295 296 297 298 299 300 301 302 303 304 261 262 + 263 264 266 268 270 272 293 294 295 296 297 298 299 + 300 301 302 303 304 261 262 263 264 266 268 270 272 + 293 294 295 296 297 298 299 300 301 302 303 304 261 + 262 263 264 266 268 270 272 293 294 295 296 297 298 + 299 300 301 302 303 304 293 294 295 296 298 300 302 + 304 325 326 327 328 329 330 331 332 333 334 335 336 + 261 262 263 264 266 268 270 272 293 294 295 296 297 + 298 299 300 301 302 303 304 325 326 327 328 329 330 + 331 332 333 334 335 336 261 262 263 264 266 268 270 + 272 293 294 295 296 297 298 299 300 301 302 303 304 + 325 326 327 328 329 330 331 332 333 334 335 336 261 + 262 263 264 266 268 270 272 293 294 295 296 297 298 + 299 300 301 302 303 304 325 326 327 328 329 330 331 + 332 333 334 335 336 261 262 263 264 266 268 270 272 + 293 294 295 296 297 298 299 300 301 302 303 304 325 + 326 327 328 329 330 331 332 333 334 335 336 261 262 + 263 264 266 268 270 272 293 294 295 296 297 298 299 + 300 301 302 303 304 325 326 327 328 329 330 331 332 + 333 334 335 336 261 262 263 264 266 268 270 272 293 + 294 295 296 297 298 299 300 301 302 303 304 325 326 + 327 328 329 330 331 332 333 334 335 336 261 262 263 + 264 266 268 270 272 293 294 295 296 297 298 299 300 + 301 302 303 304 325 326 327 328 329 330 331 332 333 + 334 335 336 261 262 263 264 266 268 270 272 293 294 + 295 296 297 298 299 300 301 302 303 304 325 326 327 + 328 329 330 331 332 333 334 335 336 293 294 295 296 + 298 300 302 304 325 326 327 328 329 330 331 332 333 + 334 335 336 293 294 295 296 298 300 302 304 325 326 + 327 328 329 330 331 332 333 334 335 336 293 294 295 + 296 298 300 302 304 325 326 327 328 329 330 331 332 + 333 334 335 336 325 326 327 328 330 332 334 336 357 + 358 359 360 361 362 363 364 365 366 367 368 293 294 + 295 296 298 300 302 304 325 326 327 328 329 330 331 + 332 333 334 335 336 357 358 359 360 361 362 363 364 + 365 366 367 368 293 294 295 296 298 300 302 304 325 + 326 327 328 329 330 331 332 333 334 335 336 357 358 + 359 360 361 362 363 364 365 366 367 368 293 294 295 + 296 298 300 302 304 325 326 327 328 329 330 331 332 + 333 334 335 336 357 358 359 360 361 362 363 364 365 + 366 367 368 293 294 295 296 298 300 302 304 325 326 + 327 328 329 330 331 332 333 334 335 336 357 358 359 + 360 361 362 363 364 365 366 367 368 293 294 295 296 + 298 300 302 304 325 326 327 328 329 330 331 332 333 + 334 335 336 357 358 359 360 361 362 363 364 365 366 + 367 368 293 294 295 296 298 300 302 304 325 326 327 + 328 329 330 331 332 333 334 335 336 357 358 359 360 + 361 362 363 364 365 366 367 368 293 294 295 296 298 + 300 302 304 325 326 327 328 329 330 331 332 333 334 + 335 336 357 358 359 360 361 362 363 364 365 366 367 + 368 293 294 295 296 298 300 302 304 325 326 327 328 + 329 330 331 332 333 334 335 336 357 358 359 360 361 + 362 363 364 365 366 367 368 325 326 327 328 330 332 + 334 336 357 358 359 360 361 362 363 364 365 366 367 + 368 325 326 327 328 330 332 334 336 357 358 359 360 + 361 362 363 364 365 366 367 368 325 326 327 328 330 + 332 334 336 357 358 359 360 361 362 363 364 365 366 + 367 368 357 358 359 360 362 364 366 368 389 390 391 + 392 393 394 395 396 397 398 399 400 325 326 327 328 + 330 332 334 336 357 358 359 360 361 362 363 364 365 + 366 367 368 389 390 391 392 393 394 395 396 397 398 + 399 400 325 326 327 328 330 332 334 336 357 358 359 + 360 361 362 363 364 365 366 367 368 389 390 391 392 + 393 394 395 396 397 398 399 400 325 326 327 328 330 + 332 334 336 357 358 359 360 361 362 363 364 365 366 + 367 368 389 390 391 392 393 394 395 396 397 398 399 + 400 325 326 327 328 330 332 334 336 357 358 359 360 + 361 362 363 364 365 366 367 368 389 390 391 392 393 + 394 395 396 397 398 399 400 325 326 327 328 330 332 + 334 336 357 358 359 360 361 362 363 364 365 366 367 + 368 389 390 391 392 393 394 395 396 397 398 399 400 + 325 326 327 328 330 332 334 336 357 358 359 360 361 + 362 363 364 365 366 367 368 389 390 391 392 393 394 + 395 396 397 398 399 400 325 326 327 328 330 332 334 + 336 357 358 359 360 361 362 363 364 365 366 367 368 + 389 390 391 392 393 394 395 396 397 398 399 400 325 + 326 327 328 330 332 334 336 357 358 359 360 361 362 + 363 364 365 366 367 368 389 390 391 392 393 394 395 + 396 397 398 399 400 357 358 359 360 362 364 366 368 + 389 390 391 392 393 394 395 396 397 398 399 400 357 + 358 359 360 362 364 366 368 389 390 391 392 393 394 + 395 396 397 398 399 400 357 358 359 360 362 364 366 + 368 389 390 391 392 393 394 395 396 397 398 399 400 + 485 486 487 488 490 492 494 496 517 518 519 520 521 + 522 523 524 525 526 527 528 453 454 455 456 458 460 + 462 464 485 486 487 488 489 490 491 492 493 494 495 + 496 421 422 423 424 426 428 430 432 453 454 455 456 + 457 458 459 460 461 462 463 464 389 390 391 392 394 + 396 398 400 421 422 423 424 425 426 427 428 429 430 + 431 432 357 358 359 360 362 364 366 368 389 390 391 + 392 393 394 395 396 397 398 399 400 421 422 423 424 + 425 426 427 428 429 430 431 432 357 358 359 360 362 + 364 366 368 389 390 391 392 393 394 395 396 397 398 + 399 400 421 422 423 424 425 426 427 428 429 430 431 + 432 357 358 359 360 362 364 366 368 389 390 391 392 + 393 394 395 396 397 398 399 400 421 422 423 424 425 + 426 427 428 429 430 431 432 357 358 359 360 362 364 + 366 368 389 390 391 392 393 394 395 396 397 398 399 + 400 421 422 423 424 425 426 427 428 429 430 431 432 + 357 358 359 360 362 364 366 368 389 390 391 392 393 + 394 395 396 397 398 399 400 421 422 423 424 425 426 + 427 428 429 430 431 432 357 358 359 360 362 364 366 + 368 389 390 391 392 393 394 395 396 397 398 399 400 + 421 422 423 424 425 426 427 428 429 430 431 432 357 + 358 359 360 362 364 366 368 389 390 391 392 393 394 + 395 396 397 398 399 400 421 422 423 424 425 426 427 + 428 429 430 431 432 357 358 359 360 362 364 366 368 + 389 390 391 392 393 394 395 396 397 398 399 400 421 + 422 423 424 425 426 427 428 429 430 431 432 389 390 + 391 392 394 396 398 400 421 422 423 424 425 426 427 + 428 429 430 431 432 389 390 391 392 394 396 398 400 + 421 422 423 424 425 426 427 428 429 430 431 432 389 + 390 391 392 394 396 398 400 421 422 423 424 425 426 + 427 428 429 430 431 432 389 390 391 392 394 396 398 + 400 421 422 423 424 425 426 427 428 429 430 431 432 + 453 454 455 456 457 458 459 460 461 462 463 464 389 + 390 391 392 394 396 398 400 421 422 423 424 425 426 + 427 428 429 430 431 432 453 454 455 456 457 458 459 + 460 461 462 463 464 389 390 391 392 394 396 398 400 + 421 422 423 424 425 426 427 428 429 430 431 432 453 + 454 455 456 457 458 459 460 461 462 463 464 389 390 + 391 392 394 396 398 400 421 422 423 424 425 426 427 + 428 429 430 431 432 453 454 455 456 457 458 459 460 + 461 462 463 464 389 390 391 392 394 396 398 400 421 + 422 423 424 425 426 427 428 429 430 431 432 453 454 + 455 456 457 458 459 460 461 462 463 464 389 390 391 + 392 394 396 398 400 421 422 423 424 425 426 427 428 + 429 430 431 432 453 454 455 456 457 458 459 460 461 + 462 463 464 389 390 391 392 394 396 398 400 421 422 + 423 424 425 426 427 428 429 430 431 432 453 454 455 + 456 457 458 459 460 461 462 463 464 389 390 391 392 + 394 396 398 400 421 422 423 424 425 426 427 428 429 + 430 431 432 453 454 455 456 457 458 459 460 461 462 + 463 464 421 422 423 424 426 428 430 432 453 454 455 + 456 457 458 459 460 461 462 463 464 421 422 423 424 + 426 428 430 432 453 454 455 456 457 458 459 460 461 + 462 463 464 421 422 423 424 426 428 430 432 453 454 + 455 456 457 458 459 460 461 462 463 464 421 422 423 + 424 426 428 430 432 453 454 455 456 457 458 459 460 + 461 462 463 464 485 486 487 488 489 490 491 492 493 + 494 495 496 421 422 423 424 426 428 430 432 453 454 + 455 456 457 458 459 460 461 462 463 464 485 486 487 + 488 489 490 491 492 493 494 495 496 421 422 423 424 + 426 428 430 432 453 454 455 456 457 458 459 460 461 + 462 463 464 485 486 487 488 489 490 491 492 493 494 + 495 496 421 422 423 424 426 428 430 432 453 454 455 + 456 457 458 459 460 461 462 463 464 485 486 487 488 + 489 490 491 492 493 494 495 496 421 422 423 424 426 + 428 430 432 453 454 455 456 457 458 459 460 461 462 + 463 464 485 486 487 488 489 490 491 492 493 494 495 + 496 421 422 423 424 426 428 430 432 453 454 455 456 + 457 458 459 460 461 462 463 464 485 486 487 488 489 + 490 491 492 493 494 495 496 421 422 423 424 426 428 + 430 432 453 454 455 456 457 458 459 460 461 462 463 + 464 485 486 487 488 489 490 491 492 493 494 495 496 + 421 422 423 424 426 428 430 432 453 454 455 456 457 + 458 459 460 461 462 463 464 485 486 487 488 489 490 + 491 492 493 494 495 496 453 454 455 456 458 460 462 + 464 485 486 487 488 489 490 491 492 493 494 495 496 + 453 454 455 456 458 460 462 464 485 486 487 488 489 + 490 491 492 493 494 495 496 453 454 455 456 458 460 + 462 464 485 486 487 488 489 490 491 492 493 494 495 + 496 453 454 455 456 458 460 462 464 485 486 487 488 + 489 490 491 492 493 494 495 496 517 518 519 520 521 + 522 523 524 525 526 527 528 453 454 455 456 458 460 + 462 464 485 486 487 488 489 490 491 492 493 494 495 + 496 517 518 519 520 521 522 523 524 525 526 527 528 + 453 454 455 456 458 460 462 464 485 486 487 488 489 + 490 491 492 493 494 495 496 517 518 519 520 521 522 + 523 524 525 526 527 528 453 454 455 456 458 460 462 + 464 485 486 487 488 489 490 491 492 493 494 495 496 + 517 518 519 520 521 522 523 524 525 526 527 528 453 + 454 455 456 458 460 462 464 485 486 487 488 489 490 + 491 492 493 494 495 496 517 518 519 520 521 522 523 + 524 525 526 527 528 453 454 455 456 458 460 462 464 + 485 486 487 488 489 490 491 492 493 494 495 496 517 + 518 519 520 521 522 523 524 525 526 527 528 453 454 + 455 456 458 460 462 464 485 486 487 488 489 490 491 + 492 493 494 495 496 517 518 519 520 521 522 523 524 + 525 526 527 528 453 454 455 456 458 460 462 464 485 + 486 487 488 489 490 491 492 493 494 495 496 517 518 + 519 520 521 522 523 524 525 526 527 528 485 486 487 + 488 490 492 494 496 517 518 519 520 521 522 523 524 + 525 526 527 528 485 486 487 488 490 492 494 496 517 + 518 519 520 521 522 523 524 525 526 527 528 485 486 + 487 488 490 492 494 496 517 518 519 520 521 522 523 + 524 525 526 527 528 485 486 487 488 490 492 494 496 + 517 518 519 520 521 522 523 524 525 526 527 528 549 + 550 551 552 553 554 555 556 557 558 559 560 485 486 + 487 488 490 492 494 496 517 518 519 520 521 522 523 + 524 525 526 527 528 549 550 551 552 553 554 555 556 + 557 558 559 560 485 486 487 488 490 492 494 496 517 + 518 519 520 521 522 523 524 525 526 527 528 549 550 + 551 552 553 554 555 556 557 558 559 560 485 486 487 + 488 490 492 494 496 517 518 519 520 521 522 523 524 + 525 526 527 528 549 550 551 552 553 554 555 556 557 + 558 559 560 485 486 487 488 490 492 494 496 517 518 + 519 520 521 522 523 524 525 526 527 528 549 550 551 + 552 553 554 555 556 557 558 559 560 485 486 487 488 + 490 492 494 496 517 518 519 520 521 522 523 524 525 + 526 527 528 549 550 551 552 553 554 555 556 557 558 + 559 560 485 486 487 488 490 492 494 496 517 518 519 + 520 521 522 523 524 525 526 527 528 549 550 551 552 + 553 554 555 556 557 558 559 560 485 486 487 488 490 + 492 494 496 517 518 519 520 521 522 523 524 525 526 + 527 528 549 550 551 552 553 554 555 556 557 558 559 + 560 517 518 519 520 522 524 526 528 549 550 551 552 + 553 554 555 556 557 558 559 560 517 518 519 520 522 + 524 526 528 549 550 551 552 553 554 555 556 557 558 + 559 560 517 518 519 520 522 524 526 528 549 550 551 + 552 553 554 555 556 557 558 559 560 517 518 519 520 + 522 524 526 528 549 550 551 552 553 554 555 556 557 + 558 559 560 581 582 583 584 586 588 590 592 613 614 + 615 616 617 618 619 620 621 622 623 624 549 550 551 + 552 554 556 558 560 581 582 583 584 585 586 587 588 + 589 590 591 592 549 550 551 552 554 556 558 560 581 + 582 583 584 585 586 587 588 589 590 591 592 549 550 + 551 552 554 556 558 560 581 582 583 584 585 586 587 + 588 589 590 591 592 549 550 551 552 554 556 558 560 + 581 582 583 584 585 586 587 588 589 590 591 592 517 + 518 519 520 522 524 526 528 549 550 551 552 553 554 + 555 556 557 558 559 560 581 582 583 584 585 586 587 + 588 589 590 591 592 517 518 519 520 522 524 526 528 + 549 550 551 552 553 554 555 556 557 558 559 560 581 + 582 583 584 585 586 587 588 589 590 591 592 517 518 + 519 520 522 524 526 528 549 550 551 552 553 554 555 + 556 557 558 559 560 581 582 583 584 585 586 587 588 + 589 590 591 592 517 518 519 520 522 524 526 528 549 + 550 551 552 553 554 555 556 557 558 559 560 581 582 + 583 584 585 586 587 588 589 590 591 592 517 518 519 + 520 522 524 526 528 549 550 551 552 553 554 555 556 + 557 558 559 560 581 582 583 584 585 586 587 588 589 + 590 591 592 517 518 519 520 522 524 526 528 549 550 + 551 552 553 554 555 556 557 558 559 560 581 582 583 + 584 585 586 587 588 589 590 591 592 517 518 519 520 + 522 524 526 528 549 550 551 552 553 554 555 556 557 + 558 559 560 581 582 583 584 585 586 587 588 589 590 + 591 592 517 518 519 520 522 524 526 528 549 550 551 + 552 553 554 555 556 557 558 559 560 581 582 583 584 + 585 586 587 588 589 590 591 592 549 550 551 552 554 + 556 558 560 581 582 583 584 585 586 587 588 589 590 + 591 592 613 614 615 616 617 618 619 620 621 622 623 + 624 549 550 551 552 554 556 558 560 581 582 583 584 + 585 586 587 588 589 590 591 592 613 614 615 616 617 + 618 619 620 621 622 623 624 549 550 551 552 554 556 + 558 560 581 582 583 584 585 586 587 588 589 590 591 + 592 613 614 615 616 617 618 619 620 621 622 623 624 + 549 550 551 552 554 556 558 560 581 582 583 584 585 + 586 587 588 589 590 591 592 613 614 615 616 617 618 + 619 620 621 622 623 624 549 550 551 552 554 556 558 + 560 581 582 583 584 585 586 587 588 589 590 591 592 + 613 614 615 616 617 618 619 620 621 622 623 624 549 + 550 551 552 554 556 558 560 581 582 583 584 585 586 + 587 588 589 590 591 592 613 614 615 616 617 618 619 + 620 621 622 623 624 549 550 551 552 554 556 558 560 + 581 582 583 584 585 586 587 588 589 590 591 592 613 + 614 615 616 617 618 619 620 621 622 623 624 549 550 + 551 552 554 556 558 560 581 582 583 584 585 586 587 + 588 589 590 591 592 613 614 615 616 617 618 619 620 + 621 622 623 624 581 582 583 584 586 588 590 592 613 + 614 615 616 617 618 619 620 621 622 623 624 581 582 + 583 584 586 588 590 592 613 614 615 616 617 618 619 + 620 621 622 623 624 581 582 583 584 586 588 590 592 + 613 614 615 616 617 618 619 620 621 622 623 624 1221 + 1222 1223 1224 1226 1228 1230 1232 1253 1254 1255 1256 1257 1258 + 1259 1260 1261 1262 1263 1264 1221 1222 1223 1224 1226 1228 1230 + 1232 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 + 1221 1222 1223 1224 1226 1228 1230 1232 1253 1254 1255 1256 1257 + 1258 1259 1260 1261 1262 1263 1264 1221 1222 1223 1224 1226 1228 + 1230 1232 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 + 1264 1221 1222 1223 1224 1226 1228 1230 1232 1253 1254 1255 1256 + 1257 1258 1259 1260 1261 1262 1263 1264 1221 1222 1223 1224 1226 + 1228 1230 1232 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 + 1263 1264 1221 1222 1223 1224 1226 1228 1230 1232 1253 1254 1255 + 1256 1257 1258 1259 1260 1261 1262 1263 1264 1221 1222 1223 1224 + 1226 1228 1230 1232 1253 1254 1255 1256 1257 1258 1259 1260 1261 + 1262 1263 1264 1221 1222 1223 1224 1226 1228 1230 1232 1253 1254 + 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1221 1222 1223 + 1224 1226 1228 1230 1232 1253 1254 1255 1256 1257 1258 1259 1260 + 1261 1262 1263 1264 1221 1222 1223 1224 1226 1228 1230 1232 1253 + 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1221 1222 + 1223 1224 1226 1228 1230 1232 1253 1254 1255 1256 1257 1258 1259 + 1260 1261 1262 1263 1264 1189 1190 1191 1192 1194 1196 1198 1200 + 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1253 + 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1189 1190 + 1191 1192 1194 1196 1198 1200 1221 1222 1223 1224 1225 1226 1227 + 1228 1229 1230 1231 1232 1253 1254 1255 1256 1257 1258 1259 1260 + 1261 1262 1263 1264 1189 1190 1191 1192 1194 1196 1198 1200 1221 + 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1253 1254 + 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1189 1190 1191 + 1192 1194 1196 1198 1200 1221 1222 1223 1224 1225 1226 1227 1228 + 1229 1230 1231 1232 1253 1254 1255 1256 1257 1258 1259 1260 1261 + 1262 1263 1264 1189 1190 1191 1192 1194 1196 1198 1200 1221 1222 + 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1253 1254 1255 + 1256 1257 1258 1259 1260 1261 1262 1263 1264 1189 1190 1191 1192 + 1194 1196 1198 1200 1221 1222 1223 1224 1225 1226 1227 1228 1229 + 1230 1231 1232 1189 1190 1191 1192 1194 1196 1198 1200 1221 1222 + 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1253 1254 1255 + 1256 1257 1258 1259 1260 1261 1262 1263 1264 1189 1190 1191 1192 + 1194 1196 1198 1200 1221 1222 1223 1224 1225 1226 1227 1228 1229 + 1230 1231 1232 1189 1190 1191 1192 1194 1196 1198 1200 1221 1222 + 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1253 1254 1255 + 1256 1257 1258 1259 1260 1261 1262 1263 1264 1189 1190 1191 1192 + 1194 1196 1198 1200 1221 1222 1223 1224 1225 1226 1227 1228 1229 + 1230 1231 1232 1189 1190 1191 1192 1194 1196 1198 1200 1221 1222 + 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1253 1254 1255 + 1256 1257 1258 1259 1260 1261 1262 1263 1264 1189 1190 1191 1192 + 1194 1196 1198 1200 1221 1222 1223 1224 1225 1226 1227 1228 1229 + 1230 1231 1232 1157 1158 1159 1160 1162 1164 1166 1168 1189 1190 + 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1157 1158 1159 + 1160 1162 1164 1166 1168 1189 1190 1191 1192 1193 1194 1195 1196 + 1197 1198 1199 1200 1221 1222 1223 1224 1225 1226 1227 1228 1229 + 1230 1231 1232 1157 1158 1159 1160 1162 1164 1166 1168 1189 1190 + 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1221 1222 1223 + 1224 1225 1226 1227 1228 1229 1230 1231 1232 1157 1158 1159 1160 + 1162 1164 1166 1168 1189 1190 1191 1192 1193 1194 1195 1196 1197 + 1198 1199 1200 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 + 1231 1232 1157 1158 1159 1160 1162 1164 1166 1168 1189 1190 1191 + 1192 1193 1194 1195 1196 1197 1198 1199 1200 1221 1222 1223 1224 + 1225 1226 1227 1228 1229 1230 1231 1232 1157 1158 1159 1160 1162 + 1164 1166 1168 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 + 1199 1200 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 + 1232 1157 1158 1159 1160 1162 1164 1166 1168 1189 1190 1191 1192 + 1193 1194 1195 1196 1197 1198 1199 1200 1221 1222 1223 1224 1225 + 1226 1227 1228 1229 1230 1231 1232 1157 1158 1159 1160 1162 1164 + 1166 1168 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 + 1200 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 + 1157 1158 1159 1160 1162 1164 1166 1168 1189 1190 1191 1192 1193 + 1194 1195 1196 1197 1198 1199 1200 1221 1222 1223 1224 1225 1226 + 1227 1228 1229 1230 1231 1232 1157 1158 1159 1160 1162 1164 1166 + 1168 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 + 1157 1158 1159 1160 1162 1164 1166 1168 1189 1190 1191 1192 1193 + 1194 1195 1196 1197 1198 1199 1200 1157 1158 1159 1160 1162 1164 + 1166 1168 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 + 1200 1125 1126 1127 1128 1130 1132 1134 1136 1157 1158 1159 1160 + 1161 1162 1163 1164 1165 1166 1167 1168 1125 1126 1127 1128 1130 + 1132 1134 1136 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 + 1167 1168 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 + 1200 1125 1126 1127 1128 1130 1132 1134 1136 1157 1158 1159 1160 + 1161 1162 1163 1164 1165 1166 1167 1168 1189 1190 1191 1192 1193 + 1194 1195 1196 1197 1198 1199 1200 1125 1126 1127 1128 1130 1132 + 1134 1136 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 + 1168 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 + 1125 1126 1127 1128 1130 1132 1134 1136 1157 1158 1159 1160 1161 + 1162 1163 1164 1165 1166 1167 1168 1189 1190 1191 1192 1193 1194 + 1195 1196 1197 1198 1199 1200 1125 1126 1127 1128 1130 1132 1134 + 1136 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 + 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1125 + 1126 1127 1128 1130 1132 1134 1136 1157 1158 1159 1160 1161 1162 + 1163 1164 1165 1166 1167 1168 1189 1190 1191 1192 1193 1194 1195 + 1196 1197 1198 1199 1200 1125 1126 1127 1128 1130 1132 1134 1136 + 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1189 + 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1125 1126 + 1127 1128 1130 1132 1134 1136 1157 1158 1159 1160 1161 1162 1163 + 1164 1165 1166 1167 1168 1189 1190 1191 1192 1193 1194 1195 1196 + 1197 1198 1199 1200 1125 1126 1127 1128 1130 1132 1134 1136 1157 + 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1125 1126 + 1127 1128 1130 1132 1134 1136 1157 1158 1159 1160 1161 1162 1163 + 1164 1165 1166 1167 1168 1125 1126 1127 1128 1130 1132 1134 1136 + 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1093 + 1094 1095 1096 1098 1100 1102 1104 1125 1126 1127 1128 1129 1130 + 1131 1132 1133 1134 1135 1136 1093 1094 1095 1096 1098 1100 1102 + 1104 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 + 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1093 + 1094 1095 1096 1098 1100 1102 1104 1125 1126 1127 1128 1129 1130 + 1131 1132 1133 1134 1135 1136 1157 1158 1159 1160 1161 1162 1163 + 1164 1165 1166 1167 1168 1093 1094 1095 1096 1098 1100 1102 1104 + 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1157 + 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1093 1094 + 1095 1096 1098 1100 1102 1104 1125 1126 1127 1128 1129 1130 1131 + 1132 1133 1134 1135 1136 1157 1158 1159 1160 1161 1162 1163 1164 + 1165 1166 1167 1168 1093 1094 1095 1096 1098 1100 1102 1104 1125 + 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1157 1158 + 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1093 1094 1095 + 1096 1098 1100 1102 1104 1125 1126 1127 1128 1129 1130 1131 1132 + 1133 1134 1135 1136 1157 1158 1159 1160 1161 1162 1163 1164 1165 + 1166 1167 1168 1093 1094 1095 1096 1098 1100 1102 1104 1125 1126 + 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1157 1158 1159 + 1160 1161 1162 1163 1164 1165 1166 1167 1168 1093 1094 1095 1096 + 1098 1100 1102 1104 1125 1126 1127 1128 1129 1130 1131 1132 1133 + 1134 1135 1136 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 + 1167 1168 1093 1094 1095 1096 1098 1100 1102 1104 1125 1126 1127 + 1128 1129 1130 1131 1132 1133 1134 1135 1136 1093 1094 1095 1096 + 1098 1100 1102 1104 1125 1126 1127 1128 1129 1130 1131 1132 1133 + 1134 1135 1136 1093 1094 1095 1096 1098 1100 1102 1104 1125 1126 + 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1061 1062 1063 + 1064 1066 1068 1070 1072 1093 1094 1095 1096 1097 1098 1099 1100 + 1101 1102 1103 1104 1061 1062 1063 1064 1066 1068 1070 1072 1093 + 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1125 1126 + 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1061 1062 1063 + 1064 1066 1068 1070 1072 1093 1094 1095 1096 1097 1098 1099 1100 + 1101 1102 1103 1104 1125 1126 1127 1128 1129 1130 1131 1132 1133 + 1134 1135 1136 1061 1062 1063 1064 1066 1068 1070 1072 1093 1094 + 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1125 1126 1127 + 1128 1129 1130 1131 1132 1133 1134 1135 1136 1061 1062 1063 1064 + 1066 1068 1070 1072 1093 1094 1095 1096 1097 1098 1099 1100 1101 + 1102 1103 1104 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 + 1135 1136 1061 1062 1063 1064 1066 1068 1070 1072 1093 1094 1095 + 1096 1097 1098 1099 1100 1101 1102 1103 1104 1125 1126 1127 1128 + 1129 1130 1131 1132 1133 1134 1135 1136 1061 1062 1063 1064 1066 + 1068 1070 1072 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 + 1103 1104 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 + 1136 1061 1062 1063 1064 1066 1068 1070 1072 1093 1094 1095 1096 + 1097 1098 1099 1100 1101 1102 1103 1104 1125 1126 1127 1128 1129 + 1130 1131 1132 1133 1134 1135 1136 1061 1062 1063 1064 1066 1068 + 1070 1072 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 + 1104 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 + 1061 1062 1063 1064 1066 1068 1070 1072 1093 1094 1095 1096 1097 + 1098 1099 1100 1101 1102 1103 1104 1061 1062 1063 1064 1066 1068 + 1070 1072 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 + 1104 1061 1062 1063 1064 1066 1068 1070 1072 1093 1094 1095 1096 + 1097 1098 1099 1100 1101 1102 1103 1104 1029 1030 1031 1032 1034 + 1036 1038 1040 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 + 1071 1072 1029 1030 1031 1032 1034 1036 1038 1040 1061 1062 1063 + 1064 1065 1066 1067 1068 1069 1070 1071 1072 1093 1094 1095 1096 + 1097 1098 1099 1100 1101 1102 1103 1104 1029 1030 1031 1032 1034 + 1036 1038 1040 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 + 1071 1072 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 + 1104 1029 1030 1031 1032 1034 1036 1038 1040 1061 1062 1063 1064 + 1065 1066 1067 1068 1069 1070 1071 1072 1093 1094 1095 1096 1097 + 1098 1099 1100 1101 1102 1103 1104 1029 1030 1031 1032 1034 1036 + 1038 1040 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 + 1072 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 + 1029 1030 1031 1032 1034 1036 1038 1040 1061 1062 1063 1064 1065 + 1066 1067 1068 1069 1070 1071 1072 1093 1094 1095 1096 1097 1098 + 1099 1100 1101 1102 1103 1104 1029 1030 1031 1032 1034 1036 1038 + 1040 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 + 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1029 + 1030 1031 1032 1034 1036 1038 1040 1061 1062 1063 1064 1065 1066 + 1067 1068 1069 1070 1071 1072 1093 1094 1095 1096 1097 1098 1099 + 1100 1101 1102 1103 1104 1029 1030 1031 1032 1034 1036 1038 1040 + 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1093 + 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1029 1030 + 1031 1032 1034 1036 1038 1040 1061 1062 1063 1064 1065 1066 1067 + 1068 1069 1070 1071 1072 1029 1030 1031 1032 1034 1036 1038 1040 + 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1029 + 1030 1031 1032 1034 1036 1038 1040 1061 1062 1063 1064 1065 1066 + 1067 1068 1069 1070 1071 1072 997 998 999 1000 1002 1004 1006 + 1008 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 + 997 998 999 1000 1002 1004 1006 1008 1029 1030 1031 1032 1033 + 1034 1035 1036 1037 1038 1039 1040 1061 1062 1063 1064 1065 1066 + 1067 1068 1069 1070 1071 1072 997 998 999 1000 1002 1004 1006 + 1008 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 + 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 997 + 998 999 1000 1002 1004 1006 1008 1029 1030 1031 1032 1033 1034 + 1035 1036 1037 1038 1039 1040 1061 1062 1063 1064 1065 1066 1067 + 1068 1069 1070 1071 1072 997 998 999 1000 1002 1004 1006 1008 + 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1061 + 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 997 998 + 999 1000 1002 1004 1006 1008 1029 1030 1031 1032 1033 1034 1035 + 1036 1037 1038 1039 1040 1061 1062 1063 1064 1065 1066 1067 1068 + 1069 1070 1071 1072 997 998 999 1000 1002 1004 1006 1008 1029 + 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1061 1062 + 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 997 998 999 + 1000 1002 1004 1006 1008 1029 1030 1031 1032 1033 1034 1035 1036 + 1037 1038 1039 1040 1061 1062 1063 1064 1065 1066 1067 1068 1069 + 1070 1071 1072 997 998 999 1000 1002 1004 1006 1008 1029 1030 + 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1061 1062 1063 + 1064 1065 1066 1067 1068 1069 1070 1071 1072 997 998 999 1000 + 1002 1004 1006 1008 1029 1030 1031 1032 1033 1034 1035 1036 1037 + 1038 1039 1040 997 998 999 1000 1002 1004 1006 1008 1029 1030 + 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 997 998 999 + 1000 1002 1004 1006 1008 1029 1030 1031 1032 1033 1034 1035 1036 + 1037 1038 1039 1040 965 966 967 968 970 972 974 976 997 + 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 965 966 + 967 968 970 972 974 976 997 998 999 1000 1001 1002 1003 + 1004 1005 1006 1007 1008 1029 1030 1031 1032 1033 1034 1035 1036 + 1037 1038 1039 1040 965 966 967 968 970 972 974 976 997 + 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1029 1030 + 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 965 966 967 + 968 970 972 974 976 997 998 999 1000 1001 1002 1003 1004 + 1005 1006 1007 1008 1029 1030 1031 1032 1033 1034 1035 1036 1037 + 1038 1039 1040 965 966 967 968 970 972 974 976 997 998 + 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1029 1030 1031 + 1032 1033 1034 1035 1036 1037 1038 1039 1040 965 966 967 968 + 970 972 974 976 997 998 999 1000 1001 1002 1003 1004 1005 + 1006 1007 1008 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 + 1039 1040 965 966 967 968 970 972 974 976 997 998 999 + 1000 1001 1002 1003 1004 1005 1006 1007 1008 1029 1030 1031 1032 + 1033 1034 1035 1036 1037 1038 1039 1040 965 966 967 968 970 + 972 974 976 997 998 999 1000 1001 1002 1003 1004 1005 1006 + 1007 1008 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 + 1040 965 966 967 968 970 972 974 976 997 998 999 1000 + 1001 1002 1003 1004 1005 1006 1007 1008 1029 1030 1031 1032 1033 + 1034 1035 1036 1037 1038 1039 1040 965 966 967 968 970 972 + 974 976 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 + 1008 965 966 967 968 970 972 974 976 997 998 999 1000 + 1001 1002 1003 1004 1005 1006 1007 1008 965 966 967 968 970 + 972 974 976 997 998 999 1000 1001 1002 1003 1004 1005 1006 + 1007 1008 933 934 935 936 938 940 942 944 965 966 967 + 968 969 970 971 972 973 974 975 976 933 934 935 936 + 938 940 942 944 965 966 967 968 969 970 971 972 973 + 974 975 976 997 998 999 1000 1001 1002 1003 1004 1005 1006 + 1007 1008 933 934 935 936 938 940 942 944 965 966 967 + 968 969 970 971 972 973 974 975 976 997 998 999 1000 + 1001 1002 1003 1004 1005 1006 1007 1008 933 934 935 936 938 + 940 942 944 965 966 967 968 969 970 971 972 973 974 + 975 976 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 + 1008 933 934 935 936 938 940 942 944 965 966 967 968 + 969 970 971 972 973 974 975 976 997 998 999 1000 1001 + 1002 1003 1004 1005 1006 1007 1008 933 934 935 936 938 940 + 942 944 965 966 967 968 969 970 971 972 973 974 975 + 976 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 + 933 934 935 936 938 940 942 944 965 966 967 968 969 + 970 971 972 973 974 975 976 997 998 999 1000 1001 1002 + 1003 1004 1005 1006 1007 1008 933 934 935 936 938 940 942 + 944 965 966 967 968 969 970 971 972 973 974 975 976 + 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 933 + 934 935 936 938 940 942 944 965 966 967 968 969 970 + 971 972 973 974 975 976 997 998 999 1000 1001 1002 1003 + 1004 1005 1006 1007 1008 933 934 935 936 938 940 942 944 + 965 966 967 968 969 970 971 972 973 974 975 976 933 + 934 935 936 938 940 942 944 965 966 967 968 969 970 + 971 972 973 974 975 976 933 934 935 936 938 940 942 + 944 965 966 967 968 969 970 971 972 973 974 975 976 + 901 902 903 904 906 908 910 912 933 934 935 936 937 + 938 939 940 941 942 943 944 901 902 903 904 906 908 + 910 912 933 934 935 936 937 938 939 940 941 942 943 + 944 965 966 967 968 969 970 971 972 973 974 975 976 + 901 902 903 904 906 908 910 912 933 934 935 936 937 + 938 939 940 941 942 943 944 965 966 967 968 969 970 + 971 972 973 974 975 976 901 902 903 904 906 908 910 + 912 933 934 935 936 937 938 939 940 941 942 943 944 + 965 966 967 968 969 970 971 972 973 974 975 976 901 + 902 903 904 906 908 910 912 933 934 935 936 937 938 + 939 940 941 942 943 944 965 966 967 968 969 970 971 + 972 973 974 975 976 901 902 903 904 906 908 910 912 + 933 934 935 936 937 938 939 940 941 942 943 944 965 + 966 967 968 969 970 971 972 973 974 975 976 901 902 + 903 904 906 908 910 912 933 934 935 936 937 938 939 + 940 941 942 943 944 965 966 967 968 969 970 971 972 + 973 974 975 976 901 902 903 904 906 908 910 912 933 + 934 935 936 937 938 939 940 941 942 943 944 965 966 + 967 968 969 970 971 972 973 974 975 976 901 902 903 + 904 906 908 910 912 933 934 935 936 937 938 939 940 + 941 942 943 944 965 966 967 968 969 970 971 972 973 + 974 975 976 901 902 903 904 906 908 910 912 933 934 + 935 936 937 938 939 940 941 942 943 944 901 902 903 + 904 906 908 910 912 933 934 935 936 937 938 939 940 + 941 942 943 944 901 902 903 904 906 908 910 912 933 + 934 935 936 937 938 939 940 941 942 943 944 869 870 + 871 872 874 876 878 880 901 902 903 904 905 906 907 + 908 909 910 911 912 869 870 871 872 874 876 878 880 + 901 902 903 904 905 906 907 908 909 910 911 912 933 + 934 935 936 937 938 939 940 941 942 943 944 869 870 + 871 872 874 876 878 880 901 902 903 904 905 906 907 + 908 909 910 911 912 933 934 935 936 937 938 939 940 + 941 942 943 944 869 870 871 872 874 876 878 880 901 + 902 903 904 905 906 907 908 909 910 911 912 933 934 + 935 936 937 938 939 940 941 942 943 944 869 870 871 + 872 874 876 878 880 901 902 903 904 905 906 907 908 + 909 910 911 912 933 934 935 936 937 938 939 940 941 + 942 943 944 869 870 871 872 874 876 878 880 901 902 + 903 904 905 906 907 908 909 910 911 912 933 934 935 + 936 937 938 939 940 941 942 943 944 869 870 871 872 + 874 876 878 880 901 902 903 904 905 906 907 908 909 + 910 911 912 933 934 935 936 937 938 939 940 941 942 + 943 944 869 870 871 872 874 876 878 880 901 902 903 + 904 905 906 907 908 909 910 911 912 933 934 935 936 + 937 938 939 940 941 942 943 944 869 870 871 872 874 + 876 878 880 901 902 903 904 905 906 907 908 909 910 + 911 912 933 934 935 936 937 938 939 940 941 942 943 + 944 869 870 871 872 874 876 878 880 901 902 903 904 + 905 906 907 908 909 910 911 912 869 870 871 872 874 + 876 878 880 901 902 903 904 905 906 907 908 909 910 + 911 912 869 870 871 872 874 876 878 880 901 902 903 + 904 905 906 907 908 909 910 911 912 837 838 839 840 + 842 844 846 848 869 870 871 872 873 874 875 876 877 + 878 879 880 837 838 839 840 842 844 846 848 869 870 + 871 872 873 874 875 876 877 878 879 880 901 902 903 + 904 905 906 907 908 909 910 911 912 837 838 839 840 + 842 844 846 848 869 870 871 872 873 874 875 876 877 + 878 879 880 901 902 903 904 905 906 907 908 909 910 + 911 912 837 838 839 840 842 844 846 848 869 870 871 + 872 873 874 875 876 877 878 879 880 901 902 903 904 + 905 906 907 908 909 910 911 912 837 838 839 840 842 + 844 846 848 869 870 871 872 873 874 875 876 877 878 + 879 880 901 902 903 904 905 906 907 908 909 910 911 + 912 837 838 839 840 842 844 846 848 869 870 871 872 + 873 874 875 876 877 878 879 880 901 902 903 904 905 + 906 907 908 909 910 911 912 837 838 839 840 842 844 + 846 848 869 870 871 872 873 874 875 876 877 878 879 + 880 901 902 903 904 905 906 907 908 909 910 911 912 + 837 838 839 840 842 844 846 848 869 870 871 872 873 + 874 875 876 877 878 879 880 901 902 903 904 905 906 + 907 908 909 910 911 912 837 838 839 840 842 844 846 + 848 869 870 871 872 873 874 875 876 877 878 879 880 + 901 902 903 904 905 906 907 908 909 910 911 912 837 + 838 839 840 842 844 846 848 869 870 871 872 873 874 + 875 876 877 878 879 880 837 838 839 840 842 844 846 + 848 869 870 871 872 873 874 875 876 877 878 879 880 + 837 838 839 840 842 844 846 848 869 870 871 872 873 + 874 875 876 877 878 879 880 805 806 807 808 810 812 + 814 816 837 838 839 840 841 842 843 844 845 846 847 + 848 805 806 807 808 810 812 814 816 837 838 839 840 + 841 842 843 844 845 846 847 848 869 870 871 872 873 + 874 875 876 877 878 879 880 805 806 807 808 810 812 + 814 816 837 838 839 840 841 842 843 844 845 846 847 + 848 869 870 871 872 873 874 875 876 877 878 879 880 + 805 806 807 808 810 812 814 816 837 838 839 840 841 + 842 843 844 845 846 847 848 869 870 871 872 873 874 + 875 876 877 878 879 880 805 806 807 808 810 812 814 + 816 837 838 839 840 841 842 843 844 845 846 847 848 + 869 870 871 872 873 874 875 876 877 878 879 880 805 + 806 807 808 810 812 814 816 837 838 839 840 841 842 + 843 844 845 846 847 848 869 870 871 872 873 874 875 + 876 877 878 879 880 805 806 807 808 810 812 814 816 + 837 838 839 840 841 842 843 844 845 846 847 848 869 + 870 871 872 873 874 875 876 877 878 879 880 805 806 + 807 808 810 812 814 816 837 838 839 840 841 842 843 + 844 845 846 847 848 869 870 871 872 873 874 875 876 + 877 878 879 880 805 806 807 808 810 812 814 816 837 + 838 839 840 841 842 843 844 845 846 847 848 869 870 + 871 872 873 874 875 876 877 878 879 880 805 806 807 + 808 810 812 814 816 837 838 839 840 841 842 843 844 + 845 846 847 848 805 806 807 808 810 812 814 816 837 + 838 839 840 841 842 843 844 845 846 847 848 805 806 + 807 808 810 812 814 816 837 838 839 840 841 842 843 + 844 845 846 847 848 773 774 775 776 778 780 782 784 + 805 806 807 808 809 810 811 812 813 814 815 816 773 + 774 775 776 778 780 782 784 805 806 807 808 809 810 + 811 812 813 814 815 816 837 838 839 840 841 842 843 + 844 845 846 847 848 773 774 775 776 778 780 782 784 + 805 806 807 808 809 810 811 812 813 814 815 816 837 + 838 839 840 841 842 843 844 845 846 847 848 773 774 + 775 776 778 780 782 784 805 806 807 808 809 810 811 + 812 813 814 815 816 837 838 839 840 841 842 843 844 + 845 846 847 848 773 774 775 776 778 780 782 784 805 + 806 807 808 809 810 811 812 813 814 815 816 837 838 + 839 840 841 842 843 844 845 846 847 848 773 774 775 + 776 778 780 782 784 805 806 807 808 809 810 811 812 + 813 814 815 816 837 838 839 840 841 842 843 844 845 + 846 847 848 773 774 775 776 778 780 782 784 805 806 + 807 808 809 810 811 812 813 814 815 816 837 838 839 + 840 841 842 843 844 845 846 847 848 773 774 775 776 + 778 780 782 784 805 806 807 808 809 810 811 812 813 + 814 815 816 837 838 839 840 841 842 843 844 845 846 + 847 848 773 774 775 776 778 780 782 784 805 806 807 + 808 809 810 811 812 813 814 815 816 837 838 839 840 + 841 842 843 844 845 846 847 848 773 774 775 776 778 + 780 782 784 805 806 807 808 809 810 811 812 813 814 + 815 816 773 774 775 776 778 780 782 784 805 806 807 + 808 809 810 811 812 813 814 815 816 773 774 775 776 + 778 780 782 784 805 806 807 808 809 810 811 812 813 + 814 815 816 741 742 743 744 746 748 750 752 773 774 + 775 776 777 778 779 780 781 782 783 784 741 742 743 + 744 746 748 750 752 773 774 775 776 777 778 779 780 + 781 782 783 784 805 806 807 808 809 810 811 812 813 + 814 815 816 741 742 743 744 746 748 750 752 773 774 + 775 776 777 778 779 780 781 782 783 784 805 806 807 + 808 809 810 811 812 813 814 815 816 741 742 743 744 + 746 748 750 752 773 774 775 776 777 778 779 780 781 + 782 783 784 805 806 807 808 809 810 811 812 813 814 + 815 816 741 742 743 744 746 748 750 752 773 774 775 + 776 777 778 779 780 781 782 783 784 805 806 807 808 + 809 810 811 812 813 814 815 816 741 742 743 744 746 + 748 750 752 773 774 775 776 777 778 779 780 781 782 + 783 784 805 806 807 808 809 810 811 812 813 814 815 + 816 741 742 743 744 746 748 750 752 773 774 775 776 + 777 778 779 780 781 782 783 784 805 806 807 808 809 + 810 811 812 813 814 815 816 741 742 743 744 746 748 + 750 752 773 774 775 776 777 778 779 780 781 782 783 + 784 805 806 807 808 809 810 811 812 813 814 815 816 + 741 742 743 744 746 748 750 752 773 774 775 776 777 + 778 779 780 781 782 783 784 805 806 807 808 809 810 + 811 812 813 814 815 816 741 742 743 744 746 748 750 + 752 773 774 775 776 777 778 779 780 781 782 783 784 + 741 742 743 744 746 748 750 752 773 774 775 776 777 + 778 779 780 781 782 783 784 741 742 743 744 746 748 + 750 752 773 774 775 776 777 778 779 780 781 782 783 + 784 709 710 711 712 714 716 718 720 741 742 743 744 + 745 746 747 748 749 750 751 752 773 774 775 776 777 + 778 779 780 781 782 783 784 709 710 711 712 714 716 + 718 720 741 742 743 744 745 746 747 748 749 750 751 + 752 773 774 775 776 777 778 779 780 781 782 783 784 + 709 710 711 712 714 716 718 720 741 742 743 744 745 + 746 747 748 749 750 751 752 773 774 775 776 777 778 + 779 780 781 782 783 784 709 710 711 712 714 716 718 + 720 741 742 743 744 745 746 747 748 749 750 751 752 + 773 774 775 776 777 778 779 780 781 782 783 784 709 + 710 711 712 714 716 718 720 741 742 743 744 745 746 + 747 748 749 750 751 752 773 774 775 776 777 778 779 + 780 781 782 783 784 709 710 711 712 714 716 718 720 + 741 742 743 744 745 746 747 748 749 750 751 752 773 + 774 775 776 777 778 779 780 781 782 783 784 709 710 + 711 712 714 716 718 720 741 742 743 744 745 746 747 + 748 749 750 751 752 773 774 775 776 777 778 779 780 + 781 782 783 784 709 710 711 712 714 716 718 720 741 + 742 743 744 745 746 747 748 749 750 751 752 773 774 + 775 776 777 778 779 780 781 782 783 784 709 710 711 + 712 714 716 718 720 741 742 743 744 745 746 747 748 + 749 750 751 752 709 710 711 712 714 716 718 720 741 + 742 743 744 745 746 747 748 749 750 751 752 709 710 + 711 712 714 716 718 720 741 742 743 744 745 746 747 + 748 749 750 751 752 709 710 711 712 714 716 718 720 + 741 742 743 744 745 746 747 748 749 750 751 752 677 + 678 679 680 682 684 686 688 709 710 711 712 713 714 + 715 716 717 718 719 720 741 742 743 744 745 746 747 + 748 749 750 751 752 677 678 679 680 682 684 686 688 + 709 710 711 712 713 714 715 716 717 718 719 720 677 + 678 679 680 682 684 686 688 709 710 711 712 713 714 + 715 716 717 718 719 720 677 678 679 680 682 684 686 + 688 709 710 711 712 713 714 715 716 717 718 719 720 + 677 678 679 680 682 684 686 688 709 710 711 712 713 + 714 715 716 717 718 719 720 677 678 679 680 682 684 + 686 688 709 710 711 712 713 714 715 716 717 718 719 + 720 741 742 743 744 745 746 747 748 749 750 751 752 + 677 678 679 680 682 684 686 688 709 710 711 712 713 + 714 715 716 717 718 719 720 741 742 743 744 745 746 + 747 748 749 750 751 752 677 678 679 680 682 684 686 + 688 709 710 711 712 713 714 715 716 717 718 719 720 + 741 742 743 744 745 746 747 748 749 750 751 752 677 + 678 679 680 682 684 686 688 709 710 711 712 713 714 + 715 716 717 718 719 720 741 742 743 744 745 746 747 + 748 749 750 751 752 677 678 679 680 682 684 686 688 + 709 710 711 712 713 714 715 716 717 718 719 720 741 + 742 743 744 745 746 747 748 749 750 751 752 677 678 + 679 680 682 684 686 688 709 710 711 712 713 714 715 + 716 717 718 719 720 741 742 743 744 745 746 747 748 + 749 750 751 752 677 678 679 680 682 684 686 688 709 + 710 711 712 713 714 715 716 717 718 719 720 741 742 + 743 744 745 746 747 748 749 750 751 752 645 646 647 + 648 650 652 654 656 677 678 679 680 681 682 683 684 + 685 686 687 688 645 646 647 648 650 652 654 656 677 + 678 679 680 681 682 683 684 685 686 687 688 709 710 + 711 712 713 714 715 716 717 718 719 720 645 646 647 + 648 650 652 654 656 677 678 679 680 681 682 683 684 + 685 686 687 688 709 710 711 712 713 714 715 716 717 + 718 719 720 645 646 647 648 650 652 654 656 677 678 + 679 680 681 682 683 684 685 686 687 688 709 710 711 + 712 713 714 715 716 717 718 719 720 645 646 647 648 + 650 652 654 656 677 678 679 680 681 682 683 684 685 + 686 687 688 709 710 711 712 713 714 715 716 717 718 + 719 720 645 646 647 648 650 652 654 656 677 678 679 + 680 681 682 683 684 685 686 687 688 709 710 711 712 + 713 714 715 716 717 718 719 720 645 646 647 648 650 + 652 654 656 677 678 679 680 681 682 683 684 685 686 + 687 688 709 710 711 712 713 714 715 716 717 718 719 + 720 645 646 647 648 650 652 654 656 677 678 679 680 + 681 682 683 684 685 686 687 688 709 710 711 712 713 + 714 715 716 717 718 719 720 645 646 647 648 650 652 + 654 656 677 678 679 680 681 682 683 684 685 686 687 + 688 709 710 711 712 713 714 715 716 717 718 719 720 + 645 646 647 648 650 652 654 656 677 678 679 680 681 + 682 683 684 685 686 687 688 645 646 647 648 650 652 + 654 656 677 678 679 680 681 682 683 684 685 686 687 + 688 645 646 647 648 650 652 654 656 677 678 679 680 + 681 682 683 684 685 686 687 688 581 582 583 584 586 + 588 590 592 613 614 615 616 617 618 619 620 621 622 + 623 624 645 646 647 648 649 650 651 652 653 654 655 + 656 581 582 583 584 586 588 590 592 613 614 615 616 + 617 618 619 620 621 622 623 624 645 646 647 648 649 + 650 651 652 653 654 655 656 581 582 583 584 586 588 + 590 592 613 614 615 616 617 618 619 620 621 622 623 + 624 645 646 647 648 649 650 651 652 653 654 655 656 + 581 582 583 584 586 588 590 592 613 614 615 616 617 + 618 619 620 621 622 623 624 645 646 647 648 649 650 + 651 652 653 654 655 656 581 582 583 584 586 588 590 + 592 613 614 615 616 617 618 619 620 621 622 623 624 + 645 646 647 648 649 650 651 652 653 654 655 656 581 + 582 583 584 586 588 590 592 613 614 615 616 617 618 + 619 620 621 622 623 624 645 646 647 648 649 650 651 + 652 653 654 655 656 581 582 583 584 586 588 590 592 + 613 614 615 616 617 618 619 620 621 622 623 624 645 + 646 647 648 649 650 651 652 653 654 655 656 581 582 + 583 584 586 588 590 592 613 614 615 616 617 618 619 + 620 621 622 623 624 645 646 647 648 649 650 651 652 + 653 654 655 656 613 614 615 616 618 620 622 624 645 + 646 647 648 649 650 651 652 653 654 655 656 677 678 + 679 680 681 682 683 684 685 686 687 688 613 614 615 + 616 618 620 622 624 645 646 647 648 649 650 651 652 + 653 654 655 656 677 678 679 680 681 682 683 684 685 + 686 687 688 613 614 615 616 618 620 622 624 645 646 + 647 648 649 650 651 652 653 654 655 656 677 678 679 + 680 681 682 683 684 685 686 687 688 613 614 615 616 + 618 620 622 624 645 646 647 648 649 650 651 652 653 + 654 655 656 677 678 679 680 681 682 683 684 685 686 + 687 688 613 614 615 616 618 620 622 624 645 646 647 + 648 649 650 651 652 653 654 655 656 677 678 679 680 + 681 682 683 684 685 686 687 688 613 614 615 616 618 + 620 622 624 645 646 647 648 649 650 651 652 653 654 + 655 656 677 678 679 680 681 682 683 684 685 686 687 + 688 613 614 615 616 618 620 622 624 645 646 647 648 + 649 650 651 652 653 654 655 656 677 678 679 680 681 + 682 683 684 685 686 687 688 613 614 615 616 618 620 + 622 624 645 646 647 648 649 650 651 652 653 654 655 + 656 677 678 679 680 681 682 683 684 685 686 687 688 + 613 614 615 616 618 620 622 624 645 646 647 648 649 + 650 651 652 653 654 655 656 613 614 615 616 618 620 + 622 624 645 646 647 648 649 650 651 652 653 654 655 + 656 613 614 615 616 618 620 622 624 645 646 647 648 + 649 650 651 652 653 654 655 656 613 614 615 616 618 + 620 622 624 645 646 647 648 649 650 651 652 653 654 + 655 656 + 2.00000000E+00 0.00000000E+00 2.00000000E+00 0.00000000E+00 2.00000000E+00 + 0.00000000E+00 2.00000000E+00 0.00000000E+00 2.00000000E+00 0.00000000E+00 + 2.00000000E+00 0.00000000E+00 2.00000000E+00 0.00000000E+00 2.00000000E+00 + 0.00000000E+00 2.00000000E+00 0.00000000E+00 2.00000000E+00 0.00000000E+00 + 2.00000000E+00 0.00000000E+00 2.00000000E+00 0.00000000E+00 2.00000000E+00 + 0.00000000E+00 2.00000000E+00 0.00000000E+00 8.75942750E-06 0.00000000E+00 + 4.42350460E-08 0.00000000E+00 6.56981094E-06 0.00000000E+00-3.79165823E-08 + 0.00000000E+00 4.42350460E-08 0.00000000E+00 2.46180794E-10 0.00000000E+00 + 4.42365575E-08 0.00000000E+00-2.46186068E-10 0.00000000E+00-3.79165823E-08 + 0.00000000E+00-2.46186068E-10 0.00000000E+00 8.85162345E-08 0.00000000E+00 + 1.31325328E-09 0.00000000E+00 1.26437061E-07 0.00000000E+00-7.38818378E-10 + 0.00000000E+00 6.56981094E-06 0.00000000E+00 4.42365575E-08 0.00000000E+00 + 7.59294901E-05 0.00000000E+00 8.85162345E-08 0.00000000E+00 1.97164994E-05 + 0.00000000E+00-1.20109968E-07 0.00000000E+00 1.97164994E-05 0.00000000E+00 + 1.26437061E-07 0.00000000E+00 1.51945060E-04 0.00000000E+00 8.86702205E-08 + 0.00000000E+00 3.28860902E-05 0.00000000E+00-2.02442283E-07 0.00000000E+00 +-1.20109968E-07 0.00000000E+00-7.38818378E-10 0.00000000E+00 8.86702205E-08 + 0.00000000E+00 2.62798441E-09 0.00000000E+00 2.08784061E-07 0.00000000E+00 +-1.23230320E-09 0.00000000E+00 3.28860902E-05 0.00000000E+00 2.08784061E-07 + 0.00000000E+00 2.28136664E-04 0.00000000E+00 8.89239278E-08 0.00000000E+00 + 4.60935066E-05 0.00000000E+00-2.85007067E-07 0.00000000E+00-2.02442283E-07 + 0.00000000E+00-1.23230320E-09 0.00000000E+00 8.89239278E-08 0.00000000E+00 + 3.94574029E-09 0.00000000E+00 2.91370606E-07 0.00000000E+00-1.72719953E-09 + 0.00000000E+00 4.60935066E-05 0.00000000E+00 2.91370606E-07 0.00000000E+00 + 3.04590319E-04 0.00000000E+00 8.92807049E-08 0.00000000E+00 5.93540390E-05 + 0.00000000E+00-3.67899663E-07 0.00000000E+00-2.85007067E-07 0.00000000E+00 +-1.72719953E-09 0.00000000E+00 8.92807049E-08 0.00000000E+00 5.26801771E-09 + 0.00000000E+00 3.74292548E-07 0.00000000E+00-2.22408031E-09 0.00000000E+00 + 5.93540390E-05 0.00000000E+00 3.74292548E-07 0.00000000E+00 3.81396330E-04 + 0.00000000E+00 8.97431430E-08 0.00000000E+00 7.26833869E-05 0.00000000E+00 +-4.51218253E-07 0.00000000E+00-3.67899663E-07 0.00000000E+00-2.22408031E-09 + 0.00000000E+00 8.97431430E-08 0.00000000E+00 6.59637223E-09 0.00000000E+00 + 4.57648013E-07 0.00000000E+00-2.72353380E-09 0.00000000E+00 7.26833869E-05 + 0.00000000E+00 4.57648013E-07 0.00000000E+00 4.58645576E-04 0.00000000E+00 + 9.03126171E-08 0.00000000E+00 8.60974364E-05 0.00000000E+00-5.35062060E-07 + 0.00000000E+00-4.51218253E-07 0.00000000E+00-2.72353380E-09 0.00000000E+00 + 9.03126171E-08 0.00000000E+00 7.93237847E-09 0.00000000E+00 5.41536420E-07 + 0.00000000E+00-3.22615523E-09 0.00000000E+00 8.60974364E-05 0.00000000E+00 + 5.41536420E-07 0.00000000E+00 5.36430732E-04 0.00000000E+00 9.09908348E-08 + 0.00000000E+00 9.96123693E-05 0.00000000E+00-6.19532152E-07 0.00000000E+00 +-5.35062060E-07 0.00000000E+00-3.22615523E-09 0.00000000E+00 9.09908348E-08 + 0.00000000E+00 9.27763861E-09 0.00000000E+00 6.26059028E-07 0.00000000E+00 +-3.73255084E-09 0.00000000E+00 9.96123693E-05 0.00000000E+00 6.26059028E-07 + 0.00000000E+00 6.14847001E-04 0.00000000E+00 9.17823250E-08 0.00000000E+00 + 1.13244965E-04 0.00000000E+00-7.04733340E-07 0.00000000E+00-6.19532152E-07 + 0.00000000E+00-3.73255084E-09 0.00000000E+00 9.17823250E-08 0.00000000E+00 + 1.06337992E-08 0.00000000E+00 7.11320841E-07 0.00000000E+00-4.24334937E-09 + 0.00000000E+00 1.13244965E-04 0.00000000E+00 7.11320841E-07 0.00000000E+00 + 6.93991813E-04 0.00000000E+00 9.26876732E-08 0.00000000E+00 1.27012198E-04 + 0.00000000E+00-7.90771604E-07 0.00000000E+00-7.04733340E-07 0.00000000E+00 +-4.24334937E-09 0.00000000E+00 9.26876732E-08 0.00000000E+00 1.20025454E-08 + 0.00000000E+00 7.97428108E-07 0.00000000E+00-4.75918668E-09 0.00000000E+00 + 1.27012198E-04 0.00000000E+00 7.97428108E-07 0.00000000E+00 7.73965837E-04 + 0.00000000E+00 9.37138501E-08 0.00000000E+00 1.40931959E-04 0.00000000E+00 +-8.77758640E-07 0.00000000E+00-7.90771604E-07 0.00000000E+00-4.75918668E-09 + 0.00000000E+00 9.37138501E-08 0.00000000E+00 1.33856185E-08 0.00000000E+00 + 8.84492832E-07 0.00000000E+00-5.28073311E-09 0.00000000E+00 1.40931959E-04 + 0.00000000E+00 8.84492832E-07 0.00000000E+00 8.54873478E-04 0.00000000E+00 + 9.48625731E-08 0.00000000E+00 1.55022496E-04 0.00000000E+00-9.65808378E-07 + 0.00000000E+00-8.77758640E-07 0.00000000E+00-5.28073311E-09 0.00000000E+00 + 9.48625731E-08 0.00000000E+00 1.47848237E-08 0.00000000E+00 9.72629243E-07 + 0.00000000E+00-5.80867227E-09 0.00000000E+00 1.55022496E-04 0.00000000E+00 + 9.72629243E-07 0.00000000E+00 9.36822740E-04 0.00000000E+00 9.61406592E-08 + 0.00000000E+00 1.69303005E-04 0.00000000E+00-1.05504060E-06 0.00000000E+00 +-9.65808378E-07 0.00000000E+00-5.80867227E-09 0.00000000E+00 9.61406592E-08 + 0.00000000E+00 1.62020298E-08 0.00000000E+00 1.06195757E-06 0.00000000E+00 +-6.34372335E-09 0.00000000E+00 1.69303005E-04 0.00000000E+00 1.06195757E-06 + 0.00000000E+00 1.01992683E-03 0.00000000E+00 9.75530157E-08 0.00000000E+00 + 1.83793438E-04 0.00000000E+00-1.14557987E-06 0.00000000E+00-1.05504060E-06 + 0.00000000E+00-6.34372335E-09 0.00000000E+00 9.75530157E-08 0.00000000E+00 + 1.76391933E-08 0.00000000E+00 1.15260272E-06 0.00000000E+00-6.88663377E-09 + 0.00000000E+00 1.83793438E-04 0.00000000E+00 1.15260272E-06 0.00000000E+00 + 1.10430351E-03 0.00000000E+00 9.91060520E-08 0.00000000E+00 1.98514700E-04 + 0.00000000E+00-1.23755658E-06 0.00000000E+00-1.14557987E-06 0.00000000E+00 +-6.88663377E-09 0.00000000E+00 9.91060520E-08 0.00000000E+00 1.90983523E-08 + 0.00000000E+00 1.24469566E-06 0.00000000E+00-7.43818669E-09 0.00000000E+00 + 1.98514700E-04 0.00000000E+00 1.24469566E-06 0.00000000E+00 1.19007687E-03 + 0.00000000E+00 1.00807231E-07 0.00000000E+00 2.13488794E-04 0.00000000E+00 +-1.33110805E-06 0.00000000E+00-1.23755658E-06 0.00000000E+00-7.43818669E-09 + 0.00000000E+00 1.00807231E-07 0.00000000E+00 2.05816515E-08 0.00000000E+00 + 1.33837418E-06 0.00000000E+00-7.99920639E-09 0.00000000E+00 2.13488794E-04 + 0.00000000E+00 1.33837418E-06 0.00000000E+00 1.27737718E-03 0.00000000E+00 + 1.02664521E-07 0.00000000E+00 2.28738915E-04 0.00000000E+00-1.42637894E-06 + 0.00000000E+00-1.33110805E-06 0.00000000E+00-7.99920639E-09 0.00000000E+00 + 1.02664521E-07 0.00000000E+00 2.20913454E-08 0.00000000E+00 1.43378361E-06 + 0.00000000E+00-8.57056173E-09 0.00000000E+00 2.28738915E-04 0.00000000E+00 + 1.43378361E-06 0.00000000E+00 1.36634235E-03 0.00000000E+00 1.04686480E-07 + 0.00000000E+00 2.44289530E-04 0.00000000E+00-1.52352193E-06 0.00000000E+00 +-1.42637894E-06 0.00000000E+00-8.57056173E-09 0.00000000E+00 1.04686480E-07 + 0.00000000E+00 2.36298168E-08 0.00000000E+00 1.53107720E-06 0.00000000E+00 +-9.15316936E-09 0.00000000E+00 2.44289530E-04 0.00000000E+00 1.53107720E-06 + 0.00000000E+00 1.45711769E-03 0.00000000E+00 1.06883448E-07 0.00000000E+00 + 2.60166638E-04 0.00000000E+00-1.62269909E-06 0.00000000E+00-1.52352193E-06 + 0.00000000E+00-9.15316936E-09 0.00000000E+00 1.06883448E-07 0.00000000E+00 + 2.51995815E-08 0.00000000E+00 1.63041791E-06 0.00000000E+00-9.74800311E-09 + 0.00000000E+00 5.25986919E-04 0.00000000E+00 2.48000500E-06 0.00000000E+00 + 1.53411731E-03 0.00000000E+00-4.21835721E-06 0.00000000E+00-2.47322832E-06 + 0.00000000E+00-1.11781679E-08 0.00000000E+00-4.21835721E-06 0.00000000E+00 + 1.49705588E-08 0.00000000E+00-2.38685945E-06 0.00000000E+00-1.07877440E-08 + 0.00000000E+00 9.31961136E-08 0.00000000E+00 2.92854760E-08 0.00000000E+00 + 2.48000500E-06 0.00000000E+00-1.11781679E-08 0.00000000E+00 5.07616093E-04 + 0.00000000E+00 2.39337383E-06 0.00000000E+00 2.98553404E-03 0.00000000E+00 + 9.31961136E-08 0.00000000E+00 5.25986919E-04 0.00000000E+00-2.47322832E-06 + 0.00000000E+00 6.46857518E-04 0.00000000E+00 4.05120307E-06 0.00000000E+00 + 3.34490810E-03 0.00000000E+00-2.88314555E-06 0.00000000E+00 5.07616093E-04 + 0.00000000E+00-2.38685945E-06 0.00000000E+00-4.03665185E-06 0.00000000E+00 +-2.42340321E-08 0.00000000E+00-2.88314555E-06 0.00000000E+00 4.68213371E-08 + 0.00000000E+00 2.39337383E-06 0.00000000E+00-1.07877440E-08 0.00000000E+00 + 6.17333390E-04 0.00000000E+00 3.86628975E-06 0.00000000E+00 3.65124957E-03 + 0.00000000E+00 1.98736593E-07 0.00000000E+00 6.46857518E-04 0.00000000E+00 +-4.03665185E-06 0.00000000E+00-3.85243896E-06 0.00000000E+00-2.31280701E-08 + 0.00000000E+00 1.98736593E-07 0.00000000E+00 6.31409811E-08 0.00000000E+00 + 4.05120307E-06 0.00000000E+00-2.42340321E-08 0.00000000E+00 5.89216910E-04 + 0.00000000E+00 3.69020238E-06 0.00000000E+00 3.48479812E-03 0.00000000E+00 + 1.89244595E-07 0.00000000E+00 6.17333390E-04 0.00000000E+00-3.85243896E-06 + 0.00000000E+00-3.67699874E-06 0.00000000E+00-2.20748365E-08 0.00000000E+00 + 1.89244595E-07 0.00000000E+00 6.02627017E-08 0.00000000E+00 3.86628975E-06 + 0.00000000E+00-2.31280701E-08 0.00000000E+00 5.62384798E-04 0.00000000E+00 + 3.52217151E-06 0.00000000E+00 3.32612634E-03 0.00000000E+00 1.80606167E-07 + 0.00000000E+00 5.89216910E-04 0.00000000E+00-3.67699874E-06 0.00000000E+00 +-3.50955873E-06 0.00000000E+00-2.10697072E-08 0.00000000E+00 1.80606167E-07 + 0.00000000E+00 5.75188985E-08 0.00000000E+00 3.69020238E-06 0.00000000E+00 +-2.20748365E-08 0.00000000E+00 5.36730100E-04 0.00000000E+00 3.36152493E-06 + 0.00000000E+00 3.17455768E-03 0.00000000E+00 1.72681764E-07 0.00000000E+00 + 5.62384798E-04 0.00000000E+00-3.50955873E-06 0.00000000E+00-3.34945414E-06 + 0.00000000E+00-2.01086777E-08 0.00000000E+00 1.72681764E-07 0.00000000E+00 + 5.48979462E-08 0.00000000E+00 3.52217151E-06 0.00000000E+00-2.10697072E-08 + 0.00000000E+00 5.12155628E-04 0.00000000E+00 3.20765279E-06 0.00000000E+00 + 3.02950525E-03 0.00000000E+00 1.65412563E-07 0.00000000E+00 5.36730100E-04 + 0.00000000E+00-3.34945414E-06 0.00000000E+00-3.19607976E-06 0.00000000E+00 +-1.91881074E-08 0.00000000E+00 1.65412563E-07 0.00000000E+00 5.23896820E-08 + 0.00000000E+00 3.36152493E-06 0.00000000E+00-2.01086777E-08 0.00000000E+00 + 4.88573983E-04 0.00000000E+00 3.06000664E-06 0.00000000E+00 2.89043658E-03 + 0.00000000E+00 1.58731235E-07 0.00000000E+00 5.12155628E-04 0.00000000E+00 +-3.19607976E-06 0.00000000E+00-3.04889136E-06 0.00000000E+00-1.83047226E-08 + 0.00000000E+00 1.58731235E-07 0.00000000E+00 4.99848936E-08 0.00000000E+00 + 3.20765279E-06 0.00000000E+00-1.91881074E-08 0.00000000E+00 4.65906066E-04 + 0.00000000E+00 2.91809008E-06 0.00000000E+00 2.75687088E-03 0.00000000E+00 + 1.52582271E-07 0.00000000E+00 4.88573983E-04 0.00000000E+00-3.04889136E-06 + 0.00000000E+00-2.90739645E-06 0.00000000E+00-1.74555605E-08 0.00000000E+00 + 1.52582271E-07 0.00000000E+00 4.76752684E-08 0.00000000E+00 3.06000664E-06 + 0.00000000E+00-1.83047226E-08 0.00000000E+00 4.44080279E-04 0.00000000E+00 + 2.78145392E-06 0.00000000E+00 2.62837373E-03 0.00000000E+00 1.46915036E-07 + 0.00000000E+00 4.65906066E-04 0.00000000E+00-2.90739645E-06 0.00000000E+00 +-2.77114908E-06 0.00000000E+00-1.66379394E-08 0.00000000E+00 1.46915036E-07 + 0.00000000E+00 4.54532890E-08 0.00000000E+00 2.91809008E-06 0.00000000E+00 +-1.74555605E-08 0.00000000E+00 4.23031340E-04 0.00000000E+00 2.64968863E-06 + 0.00000000E+00 2.50455006E-03 0.00000000E+00 1.41687169E-07 0.00000000E+00 + 4.44080279E-04 0.00000000E+00-2.77114908E-06 0.00000000E+00-2.63974262E-06 + 0.00000000E+00-1.58494138E-08 0.00000000E+00 1.41687169E-07 0.00000000E+00 + 4.33121231E-08 0.00000000E+00 2.78145392E-06 0.00000000E+00-1.66379394E-08 + 0.00000000E+00 4.02699720E-04 0.00000000E+00 2.52242079E-06 0.00000000E+00 + 2.38503969E-03 0.00000000E+00 1.36859869E-07 0.00000000E+00 4.23031340E-04 + 0.00000000E+00-2.63974262E-06 0.00000000E+00-2.51280625E-06 0.00000000E+00 +-1.50877542E-08 0.00000000E+00 1.36859869E-07 0.00000000E+00 4.12455409E-08 + 0.00000000E+00 2.64968863E-06 0.00000000E+00-1.58494138E-08 0.00000000E+00 + 3.83030945E-04 0.00000000E+00 2.39930873E-06 0.00000000E+00 2.26951365E-03 + 0.00000000E+00 1.32399218E-07 0.00000000E+00 4.02699720E-04 0.00000000E+00 +-2.51280625E-06 0.00000000E+00-2.39000060E-06 0.00000000E+00-1.43509199E-08 + 0.00000000E+00 1.32399218E-07 0.00000000E+00 3.92478526E-08 0.00000000E+00 + 2.52242079E-06 0.00000000E+00-1.50877542E-08 0.00000000E+00 3.63975113E-04 + 0.00000000E+00 2.28003948E-06 0.00000000E+00 2.15767072E-03 0.00000000E+00 + 1.28274305E-07 0.00000000E+00 3.83030945E-04 0.00000000E+00-2.39000060E-06 + 0.00000000E+00-2.27101475E-06 0.00000000E+00-1.36370418E-08 0.00000000E+00 + 1.28274305E-07 0.00000000E+00 3.73138482E-08 0.00000000E+00 2.39930873E-06 + 0.00000000E+00-1.43509199E-08 0.00000000E+00 3.45486210E-04 0.00000000E+00 + 2.16432452E-06 0.00000000E+00 2.04923414E-03 0.00000000E+00 1.24459165E-07 + 0.00000000E+00 3.63975113E-04 0.00000000E+00-2.27101475E-06 0.00000000E+00 +-2.15556195E-06 0.00000000E+00-1.29443962E-08 0.00000000E+00 1.24459165E-07 + 0.00000000E+00 3.54387407E-08 0.00000000E+00 2.28003948E-06 0.00000000E+00 +-1.36370418E-08 0.00000000E+00 3.27521854E-04 0.00000000E+00 2.05189807E-06 + 0.00000000E+00 1.94394868E-03 0.00000000E+00 1.20929194E-07 0.00000000E+00 + 3.45486210E-04 0.00000000E+00-2.15556195E-06 0.00000000E+00-2.04337809E-06 + 0.00000000E+00-1.22713958E-08 0.00000000E+00 1.20929194E-07 0.00000000E+00 + 3.36181166E-08 0.00000000E+00 2.16432452E-06 0.00000000E+00-1.29443962E-08 + 0.00000000E+00 3.10042837E-04 0.00000000E+00 1.94251433E-06 0.00000000E+00 + 1.84157892E-03 0.00000000E+00 1.17663128E-07 0.00000000E+00 3.27521854E-04 + 0.00000000E+00-2.04337809E-06 0.00000000E+00-1.93421879E-06 0.00000000E+00 +-1.16165717E-08 0.00000000E+00 1.17663128E-07 0.00000000E+00 3.18479038E-08 + 0.00000000E+00 2.05189807E-06 0.00000000E+00-1.22713958E-08 0.00000000E+00 + 2.93012800E-04 0.00000000E+00 1.83594536E-06 0.00000000E+00 1.74190672E-03 + 0.00000000E+00 1.14641757E-07 0.00000000E+00 3.10042837E-04 0.00000000E+00 +-1.93421879E-06 0.00000000E+00-1.82785741E-06 0.00000000E+00-1.09785621E-08 + 0.00000000E+00 1.14641757E-07 0.00000000E+00 3.01243298E-08 0.00000000E+00 + 1.94251433E-06 0.00000000E+00-1.16165717E-08 0.00000000E+00 2.76397912E-04 + 0.00000000E+00 1.73197911E-06 0.00000000E+00 1.64472947E-03 0.00000000E+00 + 1.11848087E-07 0.00000000E+00 2.93012800E-04 0.00000000E+00-1.82785741E-06 + 0.00000000E+00 2.60166638E-04 0.00000000E+00 1.63041791E-06 0.00000000E+00 + 1.54985850E-03 0.00000000E+00 1.09266675E-07 0.00000000E+00 2.76397912E-04 + 0.00000000E+00-1.72408305E-06 0.00000000E+00-1.62269909E-06 0.00000000E+00 +-9.74800311E-09 0.00000000E+00 1.09266675E-07 0.00000000E+00 2.68033229E-08 + 0.00000000E+00 1.73197911E-06 0.00000000E+00-1.03560997E-08 0.00000000E+00 +-1.72408305E-06 0.00000000E+00-1.03560997E-08 0.00000000E+00 1.11848087E-07 + 0.00000000E+00 2.84438906E-08 0.00000000E+00 1.83594536E-06 0.00000000E+00 +-1.09785621E-08 0.00000000E+00 8.75942750E-06 0.00000000E+00 4.42350460E-08 + 0.00000000E+00 6.56981094E-06 0.00000000E+00-3.79165823E-08 0.00000000E+00 + 4.42350460E-08 0.00000000E+00 2.46180794E-10 0.00000000E+00 4.42365575E-08 + 0.00000000E+00-2.46186068E-10 0.00000000E+00-3.79165823E-08 0.00000000E+00 +-2.46186068E-10 0.00000000E+00 8.85162345E-08 0.00000000E+00 1.31325328E-09 + 0.00000000E+00 1.26437061E-07 0.00000000E+00-7.38818378E-10 0.00000000E+00 + 6.56981094E-06 0.00000000E+00 4.42365575E-08 0.00000000E+00 7.59294901E-05 + 0.00000000E+00 8.85162345E-08 0.00000000E+00 1.97164994E-05 0.00000000E+00 +-1.20109968E-07 0.00000000E+00 1.97164994E-05 0.00000000E+00 1.26437061E-07 + 0.00000000E+00 1.51945060E-04 0.00000000E+00 8.86702205E-08 0.00000000E+00 + 3.28860902E-05 0.00000000E+00-2.02442283E-07 0.00000000E+00-1.20109968E-07 + 0.00000000E+00-7.38818378E-10 0.00000000E+00 8.86702205E-08 0.00000000E+00 + 2.62798441E-09 0.00000000E+00 2.08784061E-07 0.00000000E+00-1.23230320E-09 + 0.00000000E+00 3.28860902E-05 0.00000000E+00 2.08784061E-07 0.00000000E+00 + 2.28136664E-04 0.00000000E+00 8.89239278E-08 0.00000000E+00 4.60935066E-05 + 0.00000000E+00-2.85007067E-07 0.00000000E+00-2.02442283E-07 0.00000000E+00 +-1.23230320E-09 0.00000000E+00 8.89239278E-08 0.00000000E+00 3.94574029E-09 + 0.00000000E+00 2.91370606E-07 0.00000000E+00-1.72719953E-09 0.00000000E+00 + 4.60935066E-05 0.00000000E+00 2.91370606E-07 0.00000000E+00 3.04590319E-04 + 0.00000000E+00 8.92807049E-08 0.00000000E+00 5.93540390E-05 0.00000000E+00 +-3.67899663E-07 0.00000000E+00-2.85007067E-07 0.00000000E+00-1.72719953E-09 + 0.00000000E+00 8.92807049E-08 0.00000000E+00 5.26801771E-09 0.00000000E+00 + 3.74292548E-07 0.00000000E+00-2.22408031E-09 0.00000000E+00 5.93540390E-05 + 0.00000000E+00 3.74292548E-07 0.00000000E+00 3.81396330E-04 0.00000000E+00 + 8.97431430E-08 0.00000000E+00 7.26833869E-05 0.00000000E+00-4.51218253E-07 + 0.00000000E+00-3.67899663E-07 0.00000000E+00-2.22408031E-09 0.00000000E+00 + 8.97431430E-08 0.00000000E+00 6.59637223E-09 0.00000000E+00 4.57648013E-07 + 0.00000000E+00-2.72353380E-09 0.00000000E+00 7.26833869E-05 0.00000000E+00 + 4.57648013E-07 0.00000000E+00 4.58645576E-04 0.00000000E+00 9.03126171E-08 + 0.00000000E+00 8.60974364E-05 0.00000000E+00-5.35062060E-07 0.00000000E+00 +-4.51218253E-07 0.00000000E+00-2.72353380E-09 0.00000000E+00 9.03126171E-08 + 0.00000000E+00 7.93237847E-09 0.00000000E+00 5.41536420E-07 0.00000000E+00 +-3.22615523E-09 0.00000000E+00 8.60974364E-05 0.00000000E+00 5.41536420E-07 + 0.00000000E+00 5.36430732E-04 0.00000000E+00 9.09908348E-08 0.00000000E+00 + 9.96123693E-05 0.00000000E+00-6.19532152E-07 0.00000000E+00-5.35062060E-07 + 0.00000000E+00-3.22615523E-09 0.00000000E+00 9.09908348E-08 0.00000000E+00 + 9.27763861E-09 0.00000000E+00 6.26059028E-07 0.00000000E+00-3.73255084E-09 + 0.00000000E+00 9.96123693E-05 0.00000000E+00 6.26059028E-07 0.00000000E+00 + 6.14847001E-04 0.00000000E+00 9.17823250E-08 0.00000000E+00 1.13244965E-04 + 0.00000000E+00-7.04733340E-07 0.00000000E+00-6.19532152E-07 0.00000000E+00 +-3.73255084E-09 0.00000000E+00 9.17823250E-08 0.00000000E+00 1.06337992E-08 + 0.00000000E+00 7.11320841E-07 0.00000000E+00-4.24334937E-09 0.00000000E+00 + 1.13244965E-04 0.00000000E+00 7.11320841E-07 0.00000000E+00 6.93991813E-04 + 0.00000000E+00 9.26876732E-08 0.00000000E+00 1.27012198E-04 0.00000000E+00 +-7.90771604E-07 0.00000000E+00-7.04733340E-07 0.00000000E+00-4.24334937E-09 + 0.00000000E+00 9.26876732E-08 0.00000000E+00 1.20025454E-08 0.00000000E+00 + 7.97428108E-07 0.00000000E+00-4.75918668E-09 0.00000000E+00 1.27012198E-04 + 0.00000000E+00 7.97428108E-07 0.00000000E+00 7.73965837E-04 0.00000000E+00 + 9.37138501E-08 0.00000000E+00 1.40931959E-04 0.00000000E+00-8.77758640E-07 + 0.00000000E+00-7.90771604E-07 0.00000000E+00-4.75918668E-09 0.00000000E+00 + 9.37138501E-08 0.00000000E+00 1.33856185E-08 0.00000000E+00 8.84492832E-07 + 0.00000000E+00-5.28073311E-09 0.00000000E+00 1.40931959E-04 0.00000000E+00 + 8.84492832E-07 0.00000000E+00 8.54873478E-04 0.00000000E+00 9.48625731E-08 + 0.00000000E+00 1.55022496E-04 0.00000000E+00-9.65808378E-07 0.00000000E+00 +-8.77758640E-07 0.00000000E+00-5.28073311E-09 0.00000000E+00 9.48625731E-08 + 0.00000000E+00 1.47848237E-08 0.00000000E+00 9.72629243E-07 0.00000000E+00 +-5.80867227E-09 0.00000000E+00 1.55022496E-04 0.00000000E+00 9.72629243E-07 + 0.00000000E+00 9.36822740E-04 0.00000000E+00 9.61406592E-08 0.00000000E+00 + 1.69303005E-04 0.00000000E+00-1.05504060E-06 0.00000000E+00-9.65808378E-07 + 0.00000000E+00-5.80867227E-09 0.00000000E+00 9.61406592E-08 0.00000000E+00 + 1.62020298E-08 0.00000000E+00 1.06195757E-06 0.00000000E+00-6.34372335E-09 + 0.00000000E+00 1.69303005E-04 0.00000000E+00 1.06195757E-06 0.00000000E+00 + 1.01992683E-03 0.00000000E+00 9.75530157E-08 0.00000000E+00 1.83793438E-04 + 0.00000000E+00-1.14557987E-06 0.00000000E+00-1.05504060E-06 0.00000000E+00 +-6.34372335E-09 0.00000000E+00 9.75530157E-08 0.00000000E+00 1.76391933E-08 + 0.00000000E+00 1.15260272E-06 0.00000000E+00-6.88663377E-09 0.00000000E+00 + 1.83793438E-04 0.00000000E+00 1.15260272E-06 0.00000000E+00 1.10430351E-03 + 0.00000000E+00 9.91060520E-08 0.00000000E+00 1.98514700E-04 0.00000000E+00 +-1.23755658E-06 0.00000000E+00-1.14557987E-06 0.00000000E+00-6.88663377E-09 + 0.00000000E+00 9.91060520E-08 0.00000000E+00 1.90983523E-08 0.00000000E+00 + 1.24469566E-06 0.00000000E+00-7.43818669E-09 0.00000000E+00 1.98514700E-04 + 0.00000000E+00 1.24469566E-06 0.00000000E+00 1.19007687E-03 0.00000000E+00 + 1.00807231E-07 0.00000000E+00 2.13488794E-04 0.00000000E+00-1.33110805E-06 + 0.00000000E+00-1.23755658E-06 0.00000000E+00-7.43818669E-09 0.00000000E+00 + 1.00807231E-07 0.00000000E+00 2.05816515E-08 0.00000000E+00 1.33837418E-06 + 0.00000000E+00-7.99920639E-09 0.00000000E+00 2.13488794E-04 0.00000000E+00 + 1.33837418E-06 0.00000000E+00 1.27737718E-03 0.00000000E+00 1.02664521E-07 + 0.00000000E+00 2.28738915E-04 0.00000000E+00-1.42637894E-06 0.00000000E+00 +-1.33110805E-06 0.00000000E+00-7.99920639E-09 0.00000000E+00 1.02664521E-07 + 0.00000000E+00 2.20913454E-08 0.00000000E+00 1.43378361E-06 0.00000000E+00 +-8.57056173E-09 0.00000000E+00 2.28738915E-04 0.00000000E+00 1.43378361E-06 + 0.00000000E+00 1.36634235E-03 0.00000000E+00 1.04686480E-07 0.00000000E+00 + 2.44289530E-04 0.00000000E+00-1.52352193E-06 0.00000000E+00-1.42637894E-06 + 0.00000000E+00-8.57056173E-09 0.00000000E+00 1.04686480E-07 0.00000000E+00 + 2.36298168E-08 0.00000000E+00 1.53107720E-06 0.00000000E+00-9.15316936E-09 + 0.00000000E+00 2.44289530E-04 0.00000000E+00 1.53107720E-06 0.00000000E+00 + 1.45711769E-03 0.00000000E+00 1.06883448E-07 0.00000000E+00 2.60166638E-04 + 0.00000000E+00-1.62269909E-06 0.00000000E+00-1.52352193E-06 0.00000000E+00 +-9.15316936E-09 0.00000000E+00 1.06883448E-07 0.00000000E+00 2.51995815E-08 + 0.00000000E+00 1.63041791E-06 0.00000000E+00-9.74800311E-09 0.00000000E+00 + 5.25986919E-04 0.00000000E+00 2.48000500E-06 0.00000000E+00 1.53411731E-03 + 0.00000000E+00-4.21835721E-06 0.00000000E+00-2.47322832E-06 0.00000000E+00 +-1.11781679E-08 0.00000000E+00-4.21835721E-06 0.00000000E+00 1.49705588E-08 + 0.00000000E+00-2.38685945E-06 0.00000000E+00-1.07877440E-08 0.00000000E+00 + 9.31961136E-08 0.00000000E+00 2.92854760E-08 0.00000000E+00 2.48000500E-06 + 0.00000000E+00-1.11781679E-08 0.00000000E+00 5.07616093E-04 0.00000000E+00 + 2.39337383E-06 0.00000000E+00 2.98553404E-03 0.00000000E+00 9.31961136E-08 + 0.00000000E+00 5.25986919E-04 0.00000000E+00-2.47322832E-06 0.00000000E+00 + 6.46857518E-04 0.00000000E+00 4.05120307E-06 0.00000000E+00 3.34490810E-03 + 0.00000000E+00-2.88314555E-06 0.00000000E+00 5.07616093E-04 0.00000000E+00 +-2.38685945E-06 0.00000000E+00-4.03665185E-06 0.00000000E+00-2.42340321E-08 + 0.00000000E+00-2.88314555E-06 0.00000000E+00 4.68213371E-08 0.00000000E+00 + 2.39337383E-06 0.00000000E+00-1.07877440E-08 0.00000000E+00 6.17333390E-04 + 0.00000000E+00 3.86628975E-06 0.00000000E+00 3.65124957E-03 0.00000000E+00 + 1.98736593E-07 0.00000000E+00 6.46857518E-04 0.00000000E+00-4.03665185E-06 + 0.00000000E+00-3.85243896E-06 0.00000000E+00-2.31280701E-08 0.00000000E+00 + 1.98736593E-07 0.00000000E+00 6.31409811E-08 0.00000000E+00 4.05120307E-06 + 0.00000000E+00-2.42340321E-08 0.00000000E+00 5.89216910E-04 0.00000000E+00 + 3.69020238E-06 0.00000000E+00 3.48479812E-03 0.00000000E+00 1.89244595E-07 + 0.00000000E+00 6.17333390E-04 0.00000000E+00-3.85243896E-06 0.00000000E+00 +-3.67699874E-06 0.00000000E+00-2.20748365E-08 0.00000000E+00 1.89244595E-07 + 0.00000000E+00 6.02627017E-08 0.00000000E+00 3.86628975E-06 0.00000000E+00 +-2.31280701E-08 0.00000000E+00 5.62384798E-04 0.00000000E+00 3.52217151E-06 + 0.00000000E+00 3.32612634E-03 0.00000000E+00 1.80606167E-07 0.00000000E+00 + 5.89216910E-04 0.00000000E+00-3.67699874E-06 0.00000000E+00-3.50955873E-06 + 0.00000000E+00-2.10697072E-08 0.00000000E+00 1.80606167E-07 0.00000000E+00 + 5.75188985E-08 0.00000000E+00 3.69020238E-06 0.00000000E+00-2.20748365E-08 + 0.00000000E+00 5.36730100E-04 0.00000000E+00 3.36152493E-06 0.00000000E+00 + 3.17455768E-03 0.00000000E+00 1.72681764E-07 0.00000000E+00 5.62384798E-04 + 0.00000000E+00-3.50955873E-06 0.00000000E+00-3.34945414E-06 0.00000000E+00 +-2.01086777E-08 0.00000000E+00 1.72681764E-07 0.00000000E+00 5.48979462E-08 + 0.00000000E+00 3.52217151E-06 0.00000000E+00-2.10697072E-08 0.00000000E+00 + 5.12155628E-04 0.00000000E+00 3.20765279E-06 0.00000000E+00 3.02950525E-03 + 0.00000000E+00 1.65412563E-07 0.00000000E+00 5.36730100E-04 0.00000000E+00 +-3.34945414E-06 0.00000000E+00-3.19607976E-06 0.00000000E+00-1.91881074E-08 + 0.00000000E+00 1.65412563E-07 0.00000000E+00 5.23896820E-08 0.00000000E+00 + 3.36152493E-06 0.00000000E+00-2.01086777E-08 0.00000000E+00 4.88573983E-04 + 0.00000000E+00 3.06000664E-06 0.00000000E+00 2.89043658E-03 0.00000000E+00 + 1.58731235E-07 0.00000000E+00 5.12155628E-04 0.00000000E+00-3.19607976E-06 + 0.00000000E+00-3.04889136E-06 0.00000000E+00-1.83047226E-08 0.00000000E+00 + 1.58731235E-07 0.00000000E+00 4.99848936E-08 0.00000000E+00 3.20765279E-06 + 0.00000000E+00-1.91881074E-08 0.00000000E+00 4.65906066E-04 0.00000000E+00 + 2.91809008E-06 0.00000000E+00 2.75687088E-03 0.00000000E+00 1.52582271E-07 + 0.00000000E+00 4.88573983E-04 0.00000000E+00-3.04889136E-06 0.00000000E+00 +-2.90739645E-06 0.00000000E+00-1.74555605E-08 0.00000000E+00 1.52582271E-07 + 0.00000000E+00 4.76752684E-08 0.00000000E+00 3.06000664E-06 0.00000000E+00 +-1.83047226E-08 0.00000000E+00 4.44080279E-04 0.00000000E+00 2.78145392E-06 + 0.00000000E+00 2.62837373E-03 0.00000000E+00 1.46915036E-07 0.00000000E+00 + 4.65906066E-04 0.00000000E+00-2.90739645E-06 0.00000000E+00-2.77114908E-06 + 0.00000000E+00-1.66379394E-08 0.00000000E+00 1.46915036E-07 0.00000000E+00 + 4.54532890E-08 0.00000000E+00 2.91809008E-06 0.00000000E+00-1.74555605E-08 + 0.00000000E+00 4.23031340E-04 0.00000000E+00 2.64968863E-06 0.00000000E+00 + 2.50455006E-03 0.00000000E+00 1.41687169E-07 0.00000000E+00 4.44080279E-04 + 0.00000000E+00-2.77114908E-06 0.00000000E+00-2.63974262E-06 0.00000000E+00 +-1.58494138E-08 0.00000000E+00 1.41687169E-07 0.00000000E+00 4.33121231E-08 + 0.00000000E+00 2.78145392E-06 0.00000000E+00-1.66379394E-08 0.00000000E+00 + 4.02699720E-04 0.00000000E+00 2.52242079E-06 0.00000000E+00 2.38503969E-03 + 0.00000000E+00 1.36859869E-07 0.00000000E+00 4.23031340E-04 0.00000000E+00 +-2.63974262E-06 0.00000000E+00-2.51280625E-06 0.00000000E+00-1.50877542E-08 + 0.00000000E+00 1.36859869E-07 0.00000000E+00 4.12455409E-08 0.00000000E+00 + 2.64968863E-06 0.00000000E+00-1.58494138E-08 0.00000000E+00 3.83030945E-04 + 0.00000000E+00 2.39930873E-06 0.00000000E+00 2.26951365E-03 0.00000000E+00 + 1.32399218E-07 0.00000000E+00 4.02699720E-04 0.00000000E+00-2.51280625E-06 + 0.00000000E+00-2.39000060E-06 0.00000000E+00-1.43509199E-08 0.00000000E+00 + 1.32399218E-07 0.00000000E+00 3.92478526E-08 0.00000000E+00 2.52242079E-06 + 0.00000000E+00-1.50877542E-08 0.00000000E+00 3.63975113E-04 0.00000000E+00 + 2.28003948E-06 0.00000000E+00 2.15767072E-03 0.00000000E+00 1.28274305E-07 + 0.00000000E+00 3.83030945E-04 0.00000000E+00-2.39000060E-06 0.00000000E+00 +-2.27101475E-06 0.00000000E+00-1.36370418E-08 0.00000000E+00 1.28274305E-07 + 0.00000000E+00 3.73138482E-08 0.00000000E+00 2.39930873E-06 0.00000000E+00 +-1.43509199E-08 0.00000000E+00 3.45486210E-04 0.00000000E+00 2.16432452E-06 + 0.00000000E+00 2.04923414E-03 0.00000000E+00 1.24459165E-07 0.00000000E+00 + 3.63975113E-04 0.00000000E+00-2.27101475E-06 0.00000000E+00-2.15556195E-06 + 0.00000000E+00-1.29443962E-08 0.00000000E+00 1.24459165E-07 0.00000000E+00 + 3.54387407E-08 0.00000000E+00 2.28003948E-06 0.00000000E+00-1.36370418E-08 + 0.00000000E+00 3.27521854E-04 0.00000000E+00 2.05189807E-06 0.00000000E+00 + 1.94394868E-03 0.00000000E+00 1.20929194E-07 0.00000000E+00 3.45486210E-04 + 0.00000000E+00-2.15556195E-06 0.00000000E+00-2.04337809E-06 0.00000000E+00 +-1.22713958E-08 0.00000000E+00 1.20929194E-07 0.00000000E+00 3.36181166E-08 + 0.00000000E+00 2.16432452E-06 0.00000000E+00-1.29443962E-08 0.00000000E+00 + 3.10042837E-04 0.00000000E+00 1.94251433E-06 0.00000000E+00 1.84157892E-03 + 0.00000000E+00 1.17663128E-07 0.00000000E+00 3.27521854E-04 0.00000000E+00 +-2.04337809E-06 0.00000000E+00-1.93421879E-06 0.00000000E+00-1.16165717E-08 + 0.00000000E+00 1.17663128E-07 0.00000000E+00 3.18479038E-08 0.00000000E+00 + 2.05189807E-06 0.00000000E+00-1.22713958E-08 0.00000000E+00 2.93012800E-04 + 0.00000000E+00 1.83594536E-06 0.00000000E+00 1.74190672E-03 0.00000000E+00 + 1.14641757E-07 0.00000000E+00 3.10042837E-04 0.00000000E+00-1.93421879E-06 + 0.00000000E+00-1.82785741E-06 0.00000000E+00-1.09785621E-08 0.00000000E+00 + 1.14641757E-07 0.00000000E+00 3.01243298E-08 0.00000000E+00 1.94251433E-06 + 0.00000000E+00-1.16165717E-08 0.00000000E+00 2.76397912E-04 0.00000000E+00 + 1.73197911E-06 0.00000000E+00 1.64472947E-03 0.00000000E+00 1.11848087E-07 + 0.00000000E+00 2.93012800E-04 0.00000000E+00-1.82785741E-06 0.00000000E+00 + 2.60166638E-04 0.00000000E+00 1.63041791E-06 0.00000000E+00 1.54985850E-03 + 0.00000000E+00 1.09266675E-07 0.00000000E+00 2.76397912E-04 0.00000000E+00 +-1.72408305E-06 0.00000000E+00-1.62269909E-06 0.00000000E+00-9.74800311E-09 + 0.00000000E+00 1.09266675E-07 0.00000000E+00 2.68033229E-08 0.00000000E+00 + 1.73197911E-06 0.00000000E+00-1.03560997E-08 0.00000000E+00-1.72408305E-06 + 0.00000000E+00-1.03560997E-08 0.00000000E+00 1.11848087E-07 0.00000000E+00 + 2.84438906E-08 0.00000000E+00 1.83594536E-06 0.00000000E+00-1.09785621E-08 + 0.00000000E+00 2.52505826E-01 0.00000000E+00 1.44380768E-04-1.11464849E-18 + 1.01002561E-01 0.00000000E+00-2.52507036E-02 0.00000000E+00 7.21908598E-05 +-6.04225745E-19-3.60938437E-05 2.08311261E-19 7.21908598E-05 6.04225745E-19 + 1.01002561E-01 0.00000000E+00 5.77496419E-04 3.33299100E-18 7.21845152E-05 + 2.29019301E-19 2.02007605E-01 0.00000000E+00 2.53673071E-07 0.00000000E+00 + 1.01002561E-01 0.00000000E+00 7.21908598E-05-6.04225745E-19 2.02007605E-01 + 0.00000000E+00 2.53673071E-07 0.00000000E+00 5.77496419E-04-3.33299100E-18 + 7.21845152E-05-2.29019301E-19 1.44380768E-04 1.11464849E-18 2.52505826E-01 + 0.00000000E+00 7.21908598E-05 6.04225745E-19-3.60938437E-05-2.08311261E-19 + 1.01002561E-01 0.00000000E+00-2.52507036E-02 0.00000000E+00 7.21848291E-05 + 1.92005693E-19 9.43971392E-03 0.00000000E+00 5.77535624E-04 8.14182850E-19 + 7.21999873E-05 5.51035468E-20 5.47526269E-02 0.00000000E+00 4.72042869E-03 + 0.00000000E+00-2.52507036E-02 0.00000000E+00-3.60938437E-05 2.08311261E-19 + 2.53673071E-07 0.00000000E+00 4.34227697E-02 0.00000000E+00 7.21845152E-05 +-2.29019301E-19 2.88746182E-04-9.30265833E-19 9.43971392E-03 0.00000000E+00 +-3.54003565E-03 0.00000000E+00 7.21848291E-05-1.92005693E-19-3.60962041E-05 + 6.17773099E-20-3.60938437E-05-2.08311261E-19-2.52507036E-02 0.00000000E+00 + 7.21845152E-05 2.29019301E-19 2.88746182E-04 9.30265833E-19 2.53673071E-07 + 0.00000000E+00 4.34227697E-02 0.00000000E+00 7.21848291E-05 1.92005693E-19 +-3.60962041E-05-6.17773099E-20 9.43971392E-03 0.00000000E+00-3.54003565E-03 + 0.00000000E+00 9.43971392E-03 0.00000000E+00 7.21848291E-05-1.92005693E-19 + 5.47526269E-02 0.00000000E+00 4.72042869E-03 0.00000000E+00 5.77535624E-04 +-8.14182850E-19 7.21999873E-05-5.51035468E-20 7.21998374E-05 1.10659477E-19 + 4.93416001E-03 0.00000000E+00 5.77693717E-04 1.64036732E-18 7.22242578E-05 + 2.79151031E-19 3.25146790E-02 0.00000000E+00 3.29011431E-03 0.00000000E+00 +-3.54003565E-03 0.00000000E+00-3.60962041E-05 6.17773099E-20 4.72042869E-03 + 0.00000000E+00 2.04000208E-02 0.00000000E+00 7.21999873E-05-5.51035468E-20 + 2.88802971E-04-4.37747071E-19 4.93416001E-03 0.00000000E+00-2.05606858E-03 + 0.00000000E+00 7.21998374E-05-1.10659477E-19-3.61060238E-05 9.74526269E-20 +-3.60962041E-05-6.17773099E-20-3.54003565E-03 0.00000000E+00 7.21999873E-05 + 5.51035468E-20 2.88802971E-04 4.37747071E-19 4.72042869E-03 0.00000000E+00 + 2.04000208E-02 0.00000000E+00 7.21998374E-05 1.10659477E-19-3.61060238E-05 +-9.74526269E-20 4.93416001E-03 0.00000000E+00-2.05606858E-03 0.00000000E+00 + 4.93416001E-03 0.00000000E+00 7.21998374E-05-1.10659477E-19 3.25146790E-02 + 0.00000000E+00 3.29011431E-03 0.00000000E+00 5.77693717E-04-1.64036732E-18 + 7.22242578E-05-2.79151031E-19 7.22240354E-05 2.52104109E-19 3.32839305E-03 + 0.00000000E+00 5.77925427E-04 1.71412575E-18 7.22580148E-05 1.81266360E-19 + 2.31644755E-02 0.00000000E+00 2.49697619E-03 0.00000000E+00-2.05606858E-03 + 0.00000000E+00-3.61060238E-05 9.74526269E-20 3.29011431E-03 0.00000000E+00 + 1.35268909E-02 0.00000000E+00 7.22242578E-05-2.79151031E-19 2.88900003E-04 +-9.77664255E-19 3.32839305E-03 0.00000000E+00-1.45634231E-03 0.00000000E+00 + 7.22240354E-05-2.52104109E-19-3.61205126E-05 1.08342617E-19-3.61060238E-05 +-9.74526269E-20-2.05606858E-03 0.00000000E+00 7.22242578E-05 2.79151031E-19 + 2.88900003E-04 9.77664255E-19 3.29011431E-03 0.00000000E+00 1.35268909E-02 + 0.00000000E+00 7.22240354E-05 2.52104109E-19-3.61205126E-05-1.08342617E-19 + 3.32839305E-03 0.00000000E+00-1.45634231E-03 0.00000000E+00 3.32839305E-03 + 0.00000000E+00 7.22240354E-05-2.52104109E-19 2.31644755E-02 0.00000000E+00 + 2.49697619E-03 0.00000000E+00 5.77925427E-04-1.71412575E-18 7.22580148E-05 +-1.81266360E-19 7.22577994E-05 1.92214225E-19 2.50870136E-03 0.00000000E+00 + 5.78234767E-04 1.55462165E-18 7.23015919E-05 1.93065849E-19 1.80014525E-02 + 0.00000000E+00 2.00766466E-03 0.00000000E+00-1.45634231E-03 0.00000000E+00 +-3.61205126E-05 1.08342617E-19 2.49697619E-03 0.00000000E+00 1.01293045E-02 + 0.00000000E+00 7.22580148E-05-1.81266360E-19 2.89035132E-04-7.72819711E-19 + 2.50870136E-03 0.00000000E+00-1.12909150E-03 0.00000000E+00 7.22577994E-05 +-1.92214225E-19-3.61398478E-05 9.63200184E-20-3.61205126E-05-1.08342617E-19 +-1.45634231E-03 0.00000000E+00 7.22580148E-05 1.81266360E-19 2.89035132E-04 + 7.72819711E-19 2.49697619E-03 0.00000000E+00 1.01293045E-02 0.00000000E+00 + 7.22577994E-05 1.92214225E-19-3.61398478E-05-9.63200184E-20 2.50870136E-03 + 0.00000000E+00-1.12909150E-03 0.00000000E+00 2.50870136E-03 0.00000000E+00 + 7.22577994E-05-1.92214225E-19 1.80014525E-02 0.00000000E+00 2.00766466E-03 + 0.00000000E+00 5.78234767E-04-1.55462165E-18 7.23015919E-05-1.93065849E-19 + 7.23013690E-05 1.80471453E-19 2.01239456E-03 0.00000000E+00 5.78622637E-04 + 1.49071301E-18 7.23549998E-05 2.01852945E-19 1.47254906E-02 0.00000000E+00 + 1.67771234E-03 0.00000000E+00-1.12909150E-03 0.00000000E+00-3.61398478E-05 + 9.63200184E-20 2.00766466E-03 0.00000000E+00 8.09952173E-03 0.00000000E+00 + 7.23015919E-05-1.93065849E-19 2.89209436E-04-7.54041549E-19 2.01239456E-03 + 0.00000000E+00-9.22526724E-04 0.00000000E+00 7.23013690E-05-1.80471453E-19 +-3.61640922E-05 9.55810994E-20-3.61398478E-05-9.63200184E-20-1.12909150E-03 + 0.00000000E+00 7.23015919E-05 1.93065849E-19 2.89209436E-04 7.54041549E-19 + 2.00766466E-03 0.00000000E+00 8.09952173E-03 0.00000000E+00 7.23013690E-05 + 1.80471453E-19-3.61640922E-05-9.55810994E-20 2.01239456E-03 0.00000000E+00 +-9.22526724E-04 0.00000000E+00 2.01239456E-03 0.00000000E+00 7.23013690E-05 +-1.80471453E-19 1.47254906E-02 0.00000000E+00 1.67771234E-03 0.00000000E+00 + 5.78622637E-04-1.49071301E-18 7.23549998E-05-2.01852945E-19 7.23547916E-05 + 2.15314754E-19 1.67997372E-03 0.00000000E+00 5.79089697E-04 2.01231867E-18 + 7.24183382E-05 2.83129479E-19 1.24615926E-02 0.00000000E+00 1.44070505E-03 + 0.00000000E+00-9.22526724E-04 0.00000000E+00-3.61640922E-05 9.55810994E-20 + 1.67771234E-03 0.00000000E+00 6.74944581E-03 0.00000000E+00 7.23549998E-05 +-2.01852945E-19 2.89423124E-04-8.51336740E-19 1.67997372E-03 0.00000000E+00 +-7.80169692E-04 0.00000000E+00 7.23547916E-05-2.15314754E-19-3.61932824E-05 + 1.24611058E-19-3.61640922E-05-9.55810994E-20-9.22526724E-04 0.00000000E+00 + 7.23549998E-05 2.01852945E-19 2.89423124E-04 8.51336740E-19 1.67771234E-03 + 0.00000000E+00 6.74944581E-03 0.00000000E+00 7.23547916E-05 2.15314754E-19 +-3.61932824E-05-1.24611058E-19 1.67997372E-03 0.00000000E+00-7.80169692E-04 + 0.00000000E+00 1.67997372E-03 0.00000000E+00 7.23547916E-05-2.15314754E-19 + 1.24615926E-02 0.00000000E+00 1.44070505E-03 0.00000000E+00 5.79089697E-04 +-2.01231867E-18 7.24183382E-05-2.83129479E-19 7.24181029E-05 2.71573524E-19 + 1.44191797E-03 0.00000000E+00 5.79636262E-04 2.49541719E-18 7.24916925E-05 + 3.56645168E-19 1.08035988E-02 0.00000000E+00 1.26241515E-03 0.00000000E+00 +-7.80169692E-04 0.00000000E+00-3.61932824E-05 1.24611058E-19 1.44070505E-03 + 0.00000000E+00 5.78659005E-03 0.00000000E+00 7.24183382E-05-2.83129479E-19 + 2.89676469E-04-1.11602926E-18 1.44191797E-03 0.00000000E+00-6.76083280E-04 + 0.00000000E+00 7.24181029E-05-2.71573524E-19-3.62274489E-05 1.57054673E-19 +-3.61932824E-05-1.24611058E-19-7.80169692E-04 0.00000000E+00 7.24183382E-05 + 2.83129479E-19 2.89676469E-04 1.11602926E-18 1.44070505E-03 0.00000000E+00 + 5.78659005E-03 0.00000000E+00 7.24181029E-05 2.71573524E-19-3.62274489E-05 +-1.57054673E-19 1.44191797E-03 0.00000000E+00-6.76083280E-04 0.00000000E+00 + 1.44191797E-03 0.00000000E+00 7.24181029E-05-2.71573524E-19 1.08035988E-02 + 0.00000000E+00 1.26241515E-03 0.00000000E+00 5.79636262E-04-2.49541719E-18 + 7.24916925E-05-3.56645168E-19-6.76083280E-04 0.00000000E+00-3.62274489E-05 + 1.57054673E-19 1.26241515E-03 0.00000000E+00 5.06532646E-03 0.00000000E+00 + 7.24916925E-05-3.56645168E-19 2.89969984E-04-1.40162493E-18 1.26312319E-03 + 0.00000000E+00-5.96661025E-04 0.00000000E+00 7.24914920E-05-3.91478435E-19 +-3.62666740E-05 1.51602465E-19 7.24914920E-05 3.91478435E-19 1.26312319E-03 + 0.00000000E+00 5.80263915E-04 2.54809016E-18 7.25752041E-05 2.14931424E-19 + 9.53715082E-03 0.00000000E+00 1.12352091E-03 0.00000000E+00 1.26312319E-03 + 0.00000000E+00 7.24914920E-05-3.91478435E-19 9.53715082E-03 0.00000000E+00 + 1.12352091E-03 0.00000000E+00 5.80263915E-04-2.54809016E-18 7.25752041E-05 +-2.14931424E-19-3.62274489E-05-1.57054673E-19-6.76083280E-04 0.00000000E+00 + 7.24916925E-05 3.56645168E-19 2.89969984E-04 1.40162493E-18 1.26241515E-03 + 0.00000000E+00 5.06532646E-03 0.00000000E+00 7.24914920E-05 3.91478435E-19 +-3.62666740E-05-1.51602465E-19 1.26312319E-03 0.00000000E+00-5.96661025E-04 + 0.00000000E+00 7.25749664E-05 1.57829273E-19 1.12396061E-03 0.00000000E+00 + 5.80972596E-04 9.27277926E-19 7.26689274E-05 1.08985416E-19 8.53835985E-03 + 0.00000000E+00 1.01231648E-03 0.00000000E+00-5.96661025E-04 0.00000000E+00 +-3.62666740E-05 1.51602465E-19 1.12352091E-03 0.00000000E+00 4.50494786E-03 + 0.00000000E+00 7.25752041E-05-2.14931424E-19 2.90304001E-04-7.91257512E-19 + 1.12396061E-03 0.00000000E+00-5.34069271E-04 0.00000000E+00 7.25749664E-05 +-1.57829273E-19-3.63109735E-05 6.67036722E-20-3.62666740E-05-1.51602465E-19 +-5.96661025E-04 0.00000000E+00 7.25752041E-05 2.14931424E-19 2.90304001E-04 + 7.91257512E-19 1.12352091E-03 0.00000000E+00 4.50494786E-03 0.00000000E+00 + 7.25749664E-05 1.57829273E-19-3.63109735E-05-6.67036722E-20 1.12396061E-03 + 0.00000000E+00-5.34069271E-04 0.00000000E+00 1.12396061E-03 0.00000000E+00 + 7.25749664E-05-1.57829273E-19 8.53835985E-03 0.00000000E+00 1.01231648E-03 + 0.00000000E+00 5.80972596E-04-9.27277926E-19 7.26689274E-05-1.08985416E-19 +-5.34069271E-04 0.00000000E+00-3.63109735E-05 6.67036722E-20 1.01231648E-03 + 0.00000000E+00 4.05710802E-03 0.00000000E+00 7.26689274E-05-1.08985416E-19 + 2.90679001E-04-5.58320476E-19 1.01260399E-03 0.00000000E+00-4.83478011E-04 + 0.00000000E+00 7.26687164E-05-1.44702286E-19-3.63604477E-05 9.51964654E-20 +-3.63109735E-05-6.67036722E-20-5.34069271E-04 0.00000000E+00 7.26689274E-05 + 1.08985416E-19 2.90679001E-04 5.58320476E-19 1.01231648E-03 0.00000000E+00 + 4.05710802E-03 0.00000000E+00 7.26687164E-05 1.44702286E-19-3.63604477E-05 +-9.51964654E-20 1.01260399E-03 0.00000000E+00-4.83478011E-04 0.00000000E+00 + 7.26687164E-05 1.44702286E-19 1.01260399E-03 0.00000000E+00 5.81764191E-04 + 1.56241573E-18 7.27730743E-05 2.36083575E-19 7.73065242E-03 0.00000000E+00 + 9.21308052E-04 0.00000000E+00 1.01260399E-03 0.00000000E+00 7.26687164E-05 +-1.44702286E-19 7.73065242E-03 0.00000000E+00 9.21308052E-04 0.00000000E+00 + 5.81764191E-04-1.56241573E-18 7.27730743E-05-2.36083575E-19-4.83478011E-04 + 0.00000000E+00-3.63604477E-05 9.51964654E-20 9.21308052E-04 0.00000000E+00 + 3.69107618E-03 0.00000000E+00 7.27730743E-05-2.36083575E-19 2.91095602E-04 +-8.89589313E-19 9.21503391E-04 0.00000000E+00-4.41745080E-04 0.00000000E+00 + 7.27728463E-05-2.32139380E-19-3.64151453E-05 1.06368428E-19 7.27728463E-05 + 2.32139380E-19 9.21503391E-04 0.00000000E+00 5.82639281E-04 1.70368713E-18 + 7.28877347E-05 1.93334334E-19 7.06411950E-03 0.00000000E+00 8.45476931E-04 + 0.00000000E+00 9.21503391E-04 0.00000000E+00 7.27728463E-05-2.32139380E-19 + 7.06411950E-03 0.00000000E+00 8.45476931E-04 0.00000000E+00 5.82639281E-04 +-1.70368713E-18 7.28877347E-05-1.93334334E-19-3.63604477E-05-9.51964654E-20 +-4.83478011E-04 0.00000000E+00 7.27730743E-05 2.36083575E-19 2.91095602E-04 + 8.89589313E-19 9.21308052E-04 0.00000000E+00 3.69107618E-03 0.00000000E+00 + 7.27728463E-05 2.32139380E-19-3.64151453E-05-1.06368428E-19 9.21503391E-04 + 0.00000000E+00-4.41745080E-04 0.00000000E+00 7.28875110E-05 1.84190981E-19 + 8.45614190E-04 0.00000000E+00 5.83599508E-04 2.03664784E-18 7.30131388E-05 + 3.28617652E-19 6.50485425E-03 0.00000000E+00 7.81339357E-04 0.00000000E+00 +-4.41745080E-04 0.00000000E+00-3.64151453E-05 1.06368428E-19 8.45476931E-04 + 0.00000000E+00 3.38637919E-03 0.00000000E+00 7.28877347E-05-1.93334334E-19 + 2.91554327E-04-8.19125309E-19 8.45614190E-04 0.00000000E+00-4.06738387E-04 + 0.00000000E+00 7.28875110E-05-1.84190981E-19-3.64751625E-05 1.28202158E-19 +-3.64151453E-05-1.06368428E-19-4.41745080E-04 0.00000000E+00 7.28877347E-05 + 1.93334334E-19 2.91554327E-04 8.19125309E-19 8.45476931E-04 0.00000000E+00 + 3.38637919E-03 0.00000000E+00 7.28875110E-05 1.84190981E-19-3.64751625E-05 +-1.28202158E-19 8.45614190E-04 0.00000000E+00-4.06738387E-04 0.00000000E+00 + 8.45614190E-04 0.00000000E+00 7.28875110E-05-1.84190981E-19 6.50485425E-03 + 0.00000000E+00 7.81339357E-04 0.00000000E+00 5.83599508E-04-2.03664784E-18 + 7.30131388E-05-3.28617652E-19-4.06738387E-04 0.00000000E+00-3.64751625E-05 + 1.28202158E-19 7.81339357E-04 0.00000000E+00 3.12885444E-03 0.00000000E+00 + 7.30131388E-05-3.28617652E-19 2.92055999E-04-1.24460224E-18 7.81438457E-04 + 0.00000000E+00-3.76959722E-04 0.00000000E+00 7.30129146E-05-3.46541010E-19 +-3.65405886E-05 1.32785705E-19-3.64751625E-05-1.28202158E-19-4.06738387E-04 + 0.00000000E+00 7.30131388E-05 3.28617652E-19 2.92055999E-04 1.24460224E-18 + 7.81339357E-04 0.00000000E+00 3.12885444E-03 0.00000000E+00 7.30129146E-05 + 3.46541010E-19-3.65405886E-05-1.32785705E-19 7.81438457E-04 0.00000000E+00 +-3.76959722E-04 0.00000000E+00 7.30129146E-05 3.46541010E-19 7.81438457E-04 + 0.00000000E+00 5.84646274E-04 2.18002859E-18 7.31494398E-05 1.84601809E-19 + 6.02900608E-03 0.00000000E+00 7.26400430E-04 0.00000000E+00 7.81438457E-04 + 0.00000000E+00 7.30129146E-05-3.46541010E-19 6.02900608E-03 0.00000000E+00 + 7.26400430E-04 0.00000000E+00 5.84646274E-04-2.18002859E-18 7.31494398E-05 +-1.84601809E-19-3.76959722E-04 0.00000000E+00-3.65405886E-05 1.32785705E-19 + 7.26400430E-04 0.00000000E+00 2.90838824E-03 0.00000000E+00 7.31494398E-05 +-1.84601809E-19 2.92601278E-04-7.63089717E-19 7.26473614E-04 0.00000000E+00 +-3.51325435E-04 0.00000000E+00 7.31492119E-05-1.63856052E-19-3.66115196E-05 + 9.06397343E-20 7.31492119E-05 1.63856052E-19 7.26473614E-04 0.00000000E+00 + 5.85781103E-04 1.39773764E-18 7.32968666E-05 1.98702885E-19 5.61931079E-03 + 0.00000000E+00 6.78828125E-04 0.00000000E+00 7.26473614E-04 0.00000000E+00 + 7.31492119E-05-1.63856052E-19 5.61931079E-03 0.00000000E+00 6.78828125E-04 + 0.00000000E+00 5.85781103E-04-1.39773764E-18 7.32968666E-05-1.98702885E-19 +-3.65405886E-05-1.32785705E-19-3.76959722E-04 0.00000000E+00 7.31494398E-05 + 1.84601809E-19 2.92601278E-04 7.63089717E-19 7.26400430E-04 0.00000000E+00 + 2.90838824E-03 0.00000000E+00 7.31492119E-05 1.63856052E-19-3.66115196E-05 +-9.06397343E-20 7.26473614E-04 0.00000000E+00-3.51325435E-04 0.00000000E+00 + 7.32966382E-05 2.06550202E-19 6.78883259E-04 0.00000000E+00 5.87005832E-04 + 1.72765771E-18 7.34556401E-05 2.26930845E-19 5.26296537E-03 0.00000000E+00 + 6.37246200E-04 0.00000000E+00-3.51325435E-04 0.00000000E+00-3.66115196E-05 + 9.06397343E-20 6.78828125E-04 0.00000000E+00 2.71756861E-03 0.00000000E+00 + 7.32968666E-05-1.98702885E-19 2.93191063E-04-8.08022071E-19 6.78883259E-04 + 0.00000000E+00-3.29032365E-04 0.00000000E+00 7.32966382E-05-2.06550202E-19 +-3.66880696E-05 1.08370262E-19-3.66115196E-05-9.06397343E-20-3.51325435E-04 + 0.00000000E+00 7.32968666E-05 1.98702885E-19 2.93191063E-04 8.08022071E-19 + 6.78828125E-04 0.00000000E+00 2.71756861E-03 0.00000000E+00 7.32966382E-05 + 2.06550202E-19-3.66880696E-05-1.08370262E-19 6.78883259E-04 0.00000000E+00 +-3.29032365E-04 0.00000000E+00 6.78883259E-04 0.00000000E+00 7.32966382E-05 +-2.06550202E-19 5.26296537E-03 0.00000000E+00 6.37246200E-04 0.00000000E+00 + 5.87005832E-04-1.72765771E-18 7.34556401E-05-2.26930845E-19-3.29032365E-04 + 0.00000000E+00-3.66880696E-05 1.08370262E-19 6.37246200E-04 0.00000000E+00 + 2.55083722E-03 0.00000000E+00 7.34556401E-05-2.26930845E-19 2.93826253E-04 +-9.39821608E-19 6.37288447E-04 0.00000000E+00-3.09472527E-04 0.00000000E+00 + 7.34554112E-05-2.36090296E-19-3.67703614E-05 1.34558776E-19-3.66880696E-05 +-1.08370262E-19-3.29032365E-04 0.00000000E+00 7.34556401E-05 2.26930845E-19 + 2.93826253E-04 9.39821608E-19 6.37246200E-04 0.00000000E+00 2.55083722E-03 + 0.00000000E+00 7.34554112E-05 2.36090296E-19-3.67703614E-05-1.34558776E-19 + 6.37288447E-04 0.00000000E+00-3.09472527E-04 0.00000000E+00 7.34554112E-05 + 2.36090296E-19 6.37288447E-04 0.00000000E+00 5.88322431E-04 2.19400249E-18 + 7.36260344E-05 3.02144806E-19 4.95027334E-03 0.00000000E+00 6.00601663E-04 + 0.00000000E+00 6.37288447E-04 0.00000000E+00 7.34554112E-05-2.36090296E-19 + 4.95027334E-03 0.00000000E+00 6.00601663E-04 0.00000000E+00 5.88322431E-04 +-2.19400249E-18 7.36260344E-05-3.02144806E-19-3.09472527E-04 0.00000000E+00 +-3.67703614E-05 1.34558776E-19 6.00601663E-04 0.00000000E+00 2.40394604E-03 + 0.00000000E+00 7.36260344E-05-3.02144806E-19 2.94507909E-04-1.11868878E-18 + 6.00634481E-04 0.00000000E+00-2.92177181E-04 0.00000000E+00 7.36258017E-05 +-2.99382734E-19-3.68585216E-05 1.05757241E-19 7.36258017E-05 2.99382734E-19 + 6.00634481E-04 0.00000000E+00 5.89732908E-04 1.73149361E-18 7.38082848E-05 + 1.23646230E-19 4.67375581E-03 0.00000000E+00 5.68074243E-04 0.00000000E+00 + 6.00634481E-04 0.00000000E+00 7.36258017E-05-2.99382734E-19 4.67375581E-03 + 0.00000000E+00 5.68074243E-04 0.00000000E+00 5.89732908E-04-1.73149361E-18 + 7.38082848E-05-1.23646230E-19-3.67703614E-05-1.34558776E-19-3.09472527E-04 + 0.00000000E+00 7.36260344E-05 3.02144806E-19 2.94507909E-04 1.11868878E-18 + 6.00601663E-04 0.00000000E+00 2.40394604E-03 0.00000000E+00 7.36258017E-05 + 2.99382734E-19-3.68585216E-05-1.05757241E-19 6.00634481E-04 0.00000000E+00 +-2.92177181E-04 0.00000000E+00 7.38080520E-05 1.00957605E-19 5.68100086E-04 + 0.00000000E+00 5.91239613E-04 3.46836424E-19 7.40027329E-05 8.82205679E-21 + 4.42755351E-03 0.00000000E+00 5.39016708E-04 0.00000000E+00-2.92177181E-04 + 0.00000000E+00-3.68585216E-05 1.05757241E-19 5.68074243E-04 0.00000000E+00 + 2.27359037E-03 0.00000000E+00 7.38082848E-05-1.23646230E-19 2.95237030E-04 +-4.79358099E-19 5.68100086E-04 0.00000000E+00-2.76779198E-04 0.00000000E+00 + 7.38080520E-05-1.00957605E-19-3.69526962E-05 2.74449154E-20-3.68585216E-05 +-1.05757241E-19-2.92177181E-04 0.00000000E+00 7.38082848E-05 1.23646230E-19 + 2.95237030E-04 4.79358099E-19 5.68074243E-04 0.00000000E+00 2.27359037E-03 + 0.00000000E+00 7.38080520E-05 1.00957605E-19-3.69526962E-05-2.74449154E-20 + 5.68100086E-04 0.00000000E+00-2.76779198E-04 0.00000000E+00 5.68100086E-04 + 0.00000000E+00 7.38080520E-05-1.00957605E-19 4.42755351E-03 0.00000000E+00 + 5.39016708E-04 0.00000000E+00 5.91239613E-04-3.46836424E-19 7.40027329E-05 +-8.82205679E-21 2.14691448E-04 0.00000000E+00 6.06593275E-05-2.11915552E-19 + 1.70326147E-03 0.00000000E+00 2.11129320E-04 0.00000000E+00 4.86530401E-04 +-1.45145463E-18 6.09723509E-05-1.44803072E-19-3.04079196E-05-8.91796561E-20 +-1.06455192E-04 0.00000000E+00 6.09723509E-05 1.44803072E-19 1.21865303E-04 + 3.01782260E-19 2.11129320E-04 0.00000000E+00 4.23151561E-04 0.00000000E+00 + 6.06593275E-05 2.11915552E-19 2.14691448E-04 0.00000000E+00 4.86530401E-04 + 1.45145463E-18 6.09723509E-05 1.44803072E-19 1.70326147E-03 0.00000000E+00 + 2.11129320E-04 0.00000000E+00-1.06455192E-04 0.00000000E+00-3.04079196E-05 + 8.91796561E-20 2.11129320E-04 0.00000000E+00 4.23151561E-04 0.00000000E+00 + 6.09723509E-05-1.44803072E-19 1.21865303E-04-3.01782260E-19-3.02528068E-05 +-1.02223430E-19-1.08272646E-04 0.00000000E+00 6.06574152E-05 2.10888680E-19 + 2.42636849E-04 8.17041259E-19 2.14684023E-04 0.00000000E+00 8.58808235E-04 + 0.00000000E+00 6.06593275E-05 2.11915552E-19-3.04079196E-05-8.91796561E-20 + 2.14691448E-04 0.00000000E+00-1.06455192E-04 0.00000000E+00 2.18406560E-04 + 0.00000000E+00 6.03538119E-05-1.98005039E-19 1.73230242E-03 0.00000000E+00 + 2.14684023E-04 0.00000000E+00 4.84038793E-04-1.65072057E-18 6.06574152E-05 +-2.10888680E-19-1.08272646E-04 0.00000000E+00-3.02528068E-05 1.02223430E-19 + 2.14684023E-04 0.00000000E+00 8.58808235E-04 0.00000000E+00 6.06574152E-05 +-2.10888680E-19 2.42636849E-04-8.17041259E-19 2.14691448E-04 0.00000000E+00 +-1.06455192E-04 0.00000000E+00 6.06593275E-05-2.11915552E-19-3.04079196E-05 + 8.91796561E-20 6.03538119E-05 1.98005039E-19 2.18406560E-04 0.00000000E+00 + 4.84038793E-04 1.65072057E-18 6.06574152E-05 2.10888680E-19 1.73230242E-03 + 0.00000000E+00 2.14684023E-04 0.00000000E+00 7.96272581E-05 2.59421630E-19 + 2.96926596E-04 0.00000000E+00 6.39039784E-04 2.00885375E-18 8.01341282E-05 + 2.50716854E-19 2.34749116E-03 0.00000000E+00 2.89975775E-04 0.00000000E+00 +-1.46725593E-04 0.00000000E+00-3.99403466E-05 1.27534621E-19 2.89975775E-04 + 0.00000000E+00 1.01760462E-03 0.00000000E+00 8.01341282E-05-2.50716854E-19 + 2.80927199E-04-9.08863458E-19 2.18406560E-04 0.00000000E+00-1.08272646E-04 + 0.00000000E+00 6.03538119E-05-1.98005039E-19-3.02528068E-05 1.02223430E-19 +-3.99403466E-05-1.27534621E-19-1.46725593E-04 0.00000000E+00 8.01341282E-05 + 2.50716854E-19 2.80927199E-04 9.08863458E-19 2.89975775E-04 0.00000000E+00 + 1.01760462E-03 0.00000000E+00 6.03538119E-05 1.98005039E-19-3.02528068E-05 +-1.02223430E-19 2.18406560E-04 0.00000000E+00-1.08272646E-04 0.00000000E+00 + 2.96926596E-04 0.00000000E+00 7.96272581E-05-2.59421630E-19 2.34749116E-03 + 0.00000000E+00 2.89975775E-04 0.00000000E+00 6.39039784E-04-2.00885375E-18 + 8.01341282E-05-2.50716854E-19 7.91435571E-05 2.54346782E-19 3.04320363E-04 + 0.00000000E+00 6.35075183E-04 2.13773822E-18 7.96270880E-05 2.73159155E-19 + 2.40484179E-03 0.00000000E+00 2.96924047E-04 0.00000000E+00-1.50311103E-04 + 0.00000000E+00-3.96926613E-05 1.31876484E-19 2.96924047E-04 0.00000000E+00 + 1.18786032E-03 0.00000000E+00 7.96270880E-05-2.73159155E-19 3.18517009E-04 +-1.05524314E-18 2.96926596E-04 0.00000000E+00-1.46725593E-04 0.00000000E+00 + 7.96272581E-05-2.59421630E-19-3.99403466E-05 1.27534621E-19-3.96926613E-05 +-1.31876484E-19-1.50311103E-04 0.00000000E+00 7.96270880E-05 2.73159155E-19 + 3.18517009E-04 1.05524314E-18 2.96924047E-04 0.00000000E+00 1.18786032E-03 + 0.00000000E+00 7.96272581E-05 2.59421630E-19-3.99403466E-05-1.27534621E-19 + 2.96926596E-04 0.00000000E+00-1.46725593E-04 0.00000000E+00 3.04320363E-04 + 0.00000000E+00 7.91435571E-05-2.54346782E-19 2.40484179E-03 0.00000000E+00 + 2.96924047E-04 0.00000000E+00 6.35075183E-04-2.13773822E-18 7.96270880E-05 +-2.73159155E-19 7.86844880E-05 2.51702607E-19 3.12206384E-04 0.00000000E+00 + 6.31307374E-04 1.94264770E-18 7.91439743E-05 2.42481483E-19 2.46596012E-03 + 0.00000000E+00 3.04319873E-04 0.00000000E+00-1.54131564E-04 0.00000000E+00 +-3.94571156E-05 1.23546023E-19 3.04319873E-04 0.00000000E+00 1.21745555E-03 + 0.00000000E+00 7.91439743E-05-2.42481483E-19 3.16583654E-04-1.00349649E-18 + 3.04320363E-04 0.00000000E+00-1.50311103E-04 0.00000000E+00 7.91435571E-05 +-2.54346782E-19-3.96926613E-05 1.31876484E-19-3.94571156E-05-1.23546023E-19 +-1.54131564E-04 0.00000000E+00 7.91439743E-05 2.42481483E-19 3.16583654E-04 + 1.00349649E-18 3.04319873E-04 0.00000000E+00 1.21745555E-03 0.00000000E+00 + 7.91435571E-05 2.54346782E-19-3.96926613E-05-1.31876484E-19 3.04320363E-04 + 0.00000000E+00-1.50311103E-04 0.00000000E+00 3.12206384E-04 0.00000000E+00 + 7.86844880E-05-2.51702607E-19 2.46596012E-03 0.00000000E+00 3.04319873E-04 + 0.00000000E+00 6.31307374E-04-1.94264770E-18 7.91439743E-05-2.42481483E-19 + 7.82476655E-05 3.58714096E-19 3.20621826E-04 0.00000000E+00 6.27723377E-04 + 2.48099194E-18 7.86847495E-05 2.57655201E-19 2.53114956E-03 0.00000000E+00 + 3.12205094E-04 0.00000000E+00-1.58206730E-04 0.00000000E+00-3.92331038E-05 + 1.54092324E-19 3.12205094E-04 0.00000000E+00 1.24901231E-03 0.00000000E+00 + 7.86847495E-05-2.57655201E-19 3.14746475E-04-1.05101002E-18 3.12206384E-04 + 0.00000000E+00-1.54131564E-04 0.00000000E+00 7.86844880E-05-2.51702607E-19 +-3.94571156E-05 1.23546023E-19-3.92331038E-05-1.54092324E-19-1.58206730E-04 + 0.00000000E+00 7.86847495E-05 2.57655201E-19 3.14746475E-04 1.05101002E-18 + 3.12205094E-04 0.00000000E+00 1.24901231E-03 0.00000000E+00 7.86844880E-05 + 2.51702607E-19-3.94571156E-05-1.23546023E-19 3.12206384E-04 0.00000000E+00 +-1.54131564E-04 0.00000000E+00 3.20621826E-04 0.00000000E+00 7.82476655E-05 +-3.58714096E-19 2.53114956E-03 0.00000000E+00 3.12205094E-04 0.00000000E+00 + 6.27723377E-04-2.48099194E-18 7.86847495E-05-2.57655201E-19 7.78322240E-05 + 2.08933904E-19 3.29614774E-04 0.00000000E+00 6.24314774E-04 2.38290838E-18 + 7.82479558E-05 3.70549476E-19 2.60076848E-03 0.00000000E+00 3.20620423E-04 + 0.00000000E+00-1.62558799E-04 0.00000000E+00-3.90200449E-05 1.44870845E-19 + 3.20620423E-04 0.00000000E+00 1.28269079E-03 0.00000000E+00 7.82479558E-05 +-3.70549476E-19 3.12998870E-04-1.36681858E-18 3.20621826E-04 0.00000000E+00 +-1.58206730E-04 0.00000000E+00 7.82476655E-05-3.58714096E-19-3.92331038E-05 + 1.54092324E-19-3.90200449E-05-1.44870845E-19-1.62558799E-04 0.00000000E+00 + 7.82479558E-05 3.70549476E-19 3.12998870E-04 1.36681858E-18 3.20620423E-04 + 0.00000000E+00 1.28269079E-03 0.00000000E+00 7.82476655E-05 3.58714096E-19 +-3.92331038E-05-1.54092324E-19 3.20621826E-04 0.00000000E+00-1.58206730E-04 + 0.00000000E+00 3.29614774E-04 0.00000000E+00 7.78322240E-05-2.08933904E-19 + 2.60076848E-03 0.00000000E+00 3.20620423E-04 0.00000000E+00 6.24314774E-04 +-2.38290838E-18 7.82479558E-05-3.70549476E-19 7.74370958E-05 1.12123942E-19 + 3.39238444E-04 0.00000000E+00 6.21072714E-04 1.02612150E-18 7.78325003E-05 + 1.76745171E-19 2.67521734E-03 0.00000000E+00 3.29613039E-04 0.00000000E+00 +-1.67212871E-04 0.00000000E+00-3.88173990E-05 7.22172781E-20 3.29613039E-04 + 0.00000000E+00 1.31868100E-03 0.00000000E+00 7.78325003E-05-1.76745171E-19 + 3.11336709E-04-8.06254492E-19 3.29614774E-04 0.00000000E+00-1.62558799E-04 + 0.00000000E+00 7.78322240E-05-2.08933904E-19-3.90200449E-05 1.44870845E-19 +-3.88173990E-05-7.22172781E-20-1.67212871E-04 0.00000000E+00 7.78325003E-05 + 1.76745171E-19 3.11336709E-04 8.06254492E-19 3.29613039E-04 0.00000000E+00 + 1.31868100E-03 0.00000000E+00 7.78322240E-05 2.08933904E-19-3.90200449E-05 +-1.44870845E-19 3.29614774E-04 0.00000000E+00-1.62558799E-04 0.00000000E+00 + 3.39238444E-04 0.00000000E+00 7.74370958E-05-1.12123942E-19 2.67521734E-03 + 0.00000000E+00 3.29613039E-04 0.00000000E+00 6.21072714E-04-1.02612150E-18 + 7.78325003E-05-1.76745171E-19-1.72197455E-04 0.00000000E+00-3.86246740E-05 + 1.55625796E-19 3.39236367E-04 0.00000000E+00 1.35719665E-03 0.00000000E+00 + 7.74373684E-05-1.51479002E-19 3.09755846E-04-6.56074923E-19 3.39238444E-04 + 0.00000000E+00-1.67212871E-04 0.00000000E+00 7.74370958E-05-1.12123942E-19 +-3.88173990E-05 7.22172781E-20 7.70613276E-05 4.71024180E-19 3.49553453E-04 + 0.00000000E+00 6.17989374E-04 2.60308139E-18 7.74373684E-05 1.51479002E-19 + 2.75495220E-03 0.00000000E+00 3.39236367E-04 0.00000000E+00 3.49553453E-04 + 0.00000000E+00 7.70613276E-05-4.71024180E-19 2.75495220E-03 0.00000000E+00 + 3.39236367E-04 0.00000000E+00 6.17989374E-04-2.60308139E-18 7.74373684E-05 +-1.51479002E-19-3.86246740E-05-1.55625796E-19-1.72197455E-04 0.00000000E+00 + 7.74373684E-05 1.51479002E-19 3.09755846E-04 6.56074923E-19 3.39236367E-04 + 0.00000000E+00 1.35719665E-03 0.00000000E+00 7.74370958E-05 1.12123942E-19 +-3.88173990E-05-7.22172781E-20 3.39238444E-04 0.00000000E+00-1.67212871E-04 + 0.00000000E+00 7.67040762E-05 5.80547583E-20 3.60629146E-04 0.00000000E+00 + 6.15057503E-04 1.89609337E-18 7.70615940E-05 4.33841430E-19 2.84049214E-03 + 0.00000000E+00 3.49550957E-04 0.00000000E+00-1.77545026E-04 0.00000000E+00 +-3.84414176E-05 1.22974047E-19 3.49550957E-04 0.00000000E+00 1.39848064E-03 + 0.00000000E+00 7.70615940E-05-4.33841430E-19 3.08252460E-04-1.57547897E-18 + 3.49553453E-04 0.00000000E+00-1.72197455E-04 0.00000000E+00 7.70613276E-05 +-4.71024180E-19-3.86246740E-05 1.55625796E-19-3.84414176E-05-1.22974047E-19 +-1.77545026E-04 0.00000000E+00 7.70615940E-05 4.33841430E-19 3.08252460E-04 + 1.57547897E-18 3.49550957E-04 0.00000000E+00 1.39848064E-03 0.00000000E+00 + 7.70613276E-05 4.71024180E-19-3.86246740E-05-1.55625796E-19 3.49553453E-04 + 0.00000000E+00-1.72197455E-04 0.00000000E+00 3.60629146E-04 0.00000000E+00 + 7.67040762E-05-5.80547583E-20 2.84049214E-03 0.00000000E+00 3.49550957E-04 + 0.00000000E+00 6.15057503E-04-1.89609337E-18 7.70615940E-05-4.33841430E-19 +-1.83292753E-04 0.00000000E+00-3.82672213E-05 1.27081310E-19 3.60626165E-04 + 0.00000000E+00 1.44281079E-03 0.00000000E+00 7.67043391E-05-8.48884992E-20 + 3.06823162E-04-5.29741474E-19 3.60629146E-04 0.00000000E+00-1.77545026E-04 + 0.00000000E+00 7.67040762E-05-5.80547583E-20-3.84414176E-05 1.22974047E-19 +-3.82672213E-05-1.27081310E-19-1.83292753E-04 0.00000000E+00 7.67043391E-05 + 8.48884992E-20 3.06823162E-04 5.29741474E-19 3.60626165E-04 0.00000000E+00 + 1.44281079E-03 0.00000000E+00 7.67040762E-05 5.80547583E-20-3.84414176E-05 +-1.22974047E-19 3.60629146E-04 0.00000000E+00-1.77545026E-04 0.00000000E+00 + 7.63645460E-05 4.23436741E-19 3.72544847E-04 0.00000000E+00 6.12270583E-04 + 2.03875790E-18 7.67043391E-05 8.48884992E-20 2.93243150E-03 0.00000000E+00 + 3.60626165E-04 0.00000000E+00 3.72544847E-04 0.00000000E+00 7.63645460E-05 +-4.23436741E-19 2.93243150E-03 0.00000000E+00 3.60626165E-04 0.00000000E+00 + 6.12270583E-04-2.03875790E-18 7.67043391E-05-8.48884992E-20-1.89483264E-04 + 0.00000000E+00-3.81017018E-05 1.74314816E-19 3.72541280E-04 0.00000000E+00 + 1.49050504E-03 0.00000000E+00 7.63648045E-05-4.26180520E-19 3.05464770E-04 +-1.52681598E-18 3.72544847E-04 0.00000000E+00-1.83292753E-04 0.00000000E+00 + 7.63645460E-05-4.23436741E-19-3.82672213E-05 1.27081310E-19 7.60420025E-05 + 2.71078746E-19 3.85391775E-04 0.00000000E+00 6.09622471E-04 2.88074516E-18 + 7.63648045E-05 4.26180520E-19 3.03145166E-03 0.00000000E+00 3.72541280E-04 + 0.00000000E+00 3.85391775E-04 0.00000000E+00 7.60420025E-05-2.71078746E-19 + 3.03145166E-03 0.00000000E+00 3.72541280E-04 0.00000000E+00 6.09622471E-04 +-2.88074516E-18 7.63648045E-05-4.26180520E-19-3.81017018E-05-1.74314816E-19 +-1.89483264E-04 0.00000000E+00 7.63648045E-05 4.26180520E-19 3.05464770E-04 + 1.52681598E-18 3.72541280E-04 0.00000000E+00 1.49050504E-03 0.00000000E+00 + 7.63645460E-05 4.23436741E-19-3.82672213E-05-1.27081310E-19 3.72544847E-04 + 0.00000000E+00-1.83292753E-04 0.00000000E+00 7.57357700E-05 1.27061470E-19 + 3.99275362E-04 0.00000000E+00 6.07107544E-04 1.36244647E-18 7.60422581E-05 + 2.39031309E-19 3.13833852E-03 0.00000000E+00 3.85387511E-04 0.00000000E+00 +-1.96165718E-04 0.00000000E+00-3.79445070E-05 9.15231948E-20 3.85387511E-04 + 0.00000000E+00 1.54192905E-03 0.00000000E+00 7.60422581E-05-2.39031309E-19 + 3.04174348E-04-1.03595016E-18 3.85391775E-04 0.00000000E+00-1.89483264E-04 + 0.00000000E+00 7.60420025E-05-2.71078746E-19-3.81017018E-05 1.74314816E-19 +-3.79445070E-05-9.15231948E-20-1.96165718E-04 0.00000000E+00 7.60422581E-05 + 2.39031309E-19 3.04174348E-04 1.03595016E-18 3.85387511E-04 0.00000000E+00 + 1.54192905E-03 0.00000000E+00 7.60420025E-05 2.71078746E-19-3.81017018E-05 +-1.74314816E-19 3.85391775E-04 0.00000000E+00-1.89483264E-04 0.00000000E+00 + 3.99275362E-04 0.00000000E+00 7.57357700E-05-1.27061470E-19 3.13833852E-03 + 0.00000000E+00 3.85387511E-04 0.00000000E+00 6.07107544E-04-1.36244647E-18 + 7.60422581E-05-2.39031309E-19-2.03397069E-04 0.00000000E+00-3.77953126E-05 + 9.16564431E-20 3.99270242E-04 0.00000000E+00 1.59750546E-03 0.00000000E+00 + 7.57360200E-05-1.66253623E-19 3.02949187E-04-6.38816820E-19 3.99275362E-04 + 0.00000000E+00-1.96165718E-04 0.00000000E+00 7.57357700E-05-1.27061470E-19 +-3.79445070E-05 9.15231948E-20-3.77953126E-05-9.16564431E-20-2.03397069E-04 + 0.00000000E+00 7.57360200E-05 1.66253623E-19 3.02949187E-04 6.38816820E-19 + 3.99270242E-04 0.00000000E+00 1.59750546E-03 0.00000000E+00 7.57357700E-05 + 1.27061470E-19-3.79445070E-05-9.15231948E-20 3.99275362E-04 0.00000000E+00 +-1.96165718E-04 0.00000000E+00 7.54452306E-05 2.00372150E-19 4.14318035E-04 + 0.00000000E+00 6.04720596E-04 1.54474102E-18 7.57360200E-05 1.66253623E-19 + 3.25400233E-03 0.00000000E+00 3.99270242E-04 0.00000000E+00 4.14318035E-04 + 0.00000000E+00 7.54452306E-05-2.00372150E-19 3.25400233E-03 0.00000000E+00 + 3.99270242E-04 0.00000000E+00 6.04720596E-04-1.54474102E-18 7.57360200E-05 +-1.66253623E-19-2.11243682E-04 0.00000000E+00-3.76538272E-05 6.20176414E-20 + 4.14311898E-04 0.00000000E+00 1.65772526E-03 0.00000000E+00 7.54454813E-05 +-1.65756107E-19 3.01786829E-04-6.89024582E-19 4.14318035E-04 0.00000000E+00 +-2.03397069E-04 0.00000000E+00 7.54452306E-05-2.00372150E-19-3.77953126E-05 + 9.16564431E-20 7.51698276E-05 8.23144585E-20 4.30662828E-04 0.00000000E+00 + 6.02456994E-04 9.23474648E-19 7.54454813E-05 1.65756107E-19 3.37950392E-03 + 0.00000000E+00 4.14311898E-04 0.00000000E+00 4.30662828E-04 0.00000000E+00 + 7.51698276E-05-8.23144585E-20 3.37950392E-03 0.00000000E+00 4.14311898E-04 + 0.00000000E+00 6.02456994E-04-9.23474648E-19 7.54454813E-05-1.65756107E-19 +-3.76538272E-05-6.20176414E-20-2.11243682E-04 0.00000000E+00 7.54454813E-05 + 1.65756107E-19 3.01786829E-04 6.89024582E-19 4.14311898E-04 0.00000000E+00 + 1.65772526E-03 0.00000000E+00 7.54452306E-05 2.00372150E-19-3.77953126E-05 +-9.16564431E-20 4.14318035E-04 0.00000000E+00-2.03397069E-04 0.00000000E+00 + 7.49090109E-05 2.82564308E-19 4.48477606E-04 0.00000000E+00 6.00312236E-04 + 1.43597767E-18 7.51700730E-05 8.76795328E-20 3.51608496E-03 0.00000000E+00 + 4.30655417E-04 0.00000000E+00-2.19783256E-04 0.00000000E+00-3.75197710E-05 + 9.25609601E-20 4.30655417E-04 0.00000000E+00 1.72316193E-03 0.00000000E+00 + 7.51700730E-05-8.76795328E-20 3.00685012E-04-4.41861034E-19 4.30662828E-04 + 0.00000000E+00-2.11243682E-04 0.00000000E+00 7.51698276E-05-8.23144585E-20 +-3.76538272E-05 6.20176414E-20-3.75197710E-05-9.25609601E-20-2.19783256E-04 + 0.00000000E+00 7.51700730E-05 8.76795328E-20 3.00685012E-04 4.41861034E-19 + 4.30655417E-04 0.00000000E+00 1.72316193E-03 0.00000000E+00 7.51698276E-05 + 8.23144585E-20-3.76538272E-05-6.20176414E-20 4.30662828E-04 0.00000000E+00 +-2.11243682E-04 0.00000000E+00 4.48477606E-04 0.00000000E+00 7.49090109E-05 +-2.82564308E-19 3.51608496E-03 0.00000000E+00 4.30655417E-04 0.00000000E+00 + 6.00312236E-04-1.43597767E-18 7.51700730E-05-8.76795328E-20-2.29107412E-04 + 0.00000000E+00-3.73928893E-05 1.33711675E-19 4.48468635E-04 0.00000000E+00 + 1.79448896E-03 0.00000000E+00 7.49092552E-05-3.36018317E-19 2.99641571E-04 +-1.11531980E-18 4.48477606E-04 0.00000000E+00-2.19783256E-04 0.00000000E+00 + 7.49090109E-05-2.82564308E-19-3.75197710E-05 9.25609601E-20-3.73928893E-05 +-1.33711675E-19-2.29107412E-04 0.00000000E+00 7.49092552E-05 3.36018317E-19 + 2.99641571E-04 1.11531980E-18 4.48468635E-04 0.00000000E+00 1.79448896E-03 + 0.00000000E+00 7.49090109E-05 2.82564308E-19-3.75197710E-05-9.25609601E-20 + 4.48477606E-04 0.00000000E+00-2.19783256E-04 0.00000000E+00 7.46623019E-05 + 1.98828385E-19 4.67961014E-04 0.00000000E+00 5.98282265E-04 2.32506205E-18 + 7.49092552E-05 3.36018317E-19 3.66520960E-03 0.00000000E+00 4.48468635E-04 + 0.00000000E+00 4.67961014E-04 0.00000000E+00 7.46623019E-05-1.98828385E-19 + 3.66520960E-03 0.00000000E+00 4.48468635E-04 0.00000000E+00 5.98282265E-04 +-2.32506205E-18 7.49092552E-05-3.36018317E-19-2.39324912E-04 0.00000000E+00 +-3.72729483E-05 6.73834721E-20 4.67950087E-04 0.00000000E+00 1.87250329E-03 + 0.00000000E+00 7.46625429E-05-1.02779359E-19 2.98654568E-04-6.77568961E-19 + 4.67961014E-04 0.00000000E+00-2.29107412E-04 0.00000000E+00 7.46623019E-05 +-1.98828385E-19-3.73928893E-05 1.33711675E-19 7.44292501E-05 1.66754529E-19 + 4.89349560E-04 0.00000000E+00 5.96363329E-04 8.45589705E-19 7.46625429E-05 + 1.02779359E-19 3.82861564E-03 0.00000000E+00 4.67950087E-04 0.00000000E+00 + 4.89349560E-04 0.00000000E+00 7.44292501E-05-1.66754529E-19 3.82861564E-03 + 0.00000000E+00 4.67950087E-04 0.00000000E+00 5.96363329E-04-8.45589705E-19 + 7.46625429E-05-1.02779359E-19-3.72729483E-05-6.73834721E-20-2.39324912E-04 + 0.00000000E+00 7.46625429E-05 1.02779359E-19 2.98654568E-04 6.77568961E-19 + 4.67950087E-04 0.00000000E+00 1.87250329E-03 0.00000000E+00 7.46623019E-05 + 1.98828385E-19-3.73928893E-05-1.33711675E-19 4.67961014E-04 0.00000000E+00 +-2.29107412E-04 0.00000000E+00 7.42094428E-05 2.85146593E-19 5.12927099E-04 + 0.00000000E+00 5.94552003E-04 2.36379438E-18 7.44294899E-05 2.58606043E-19 + 4.00838103E-03 0.00000000E+00 4.89336176E-04 0.00000000E+00-2.50565819E-04 + 0.00000000E+00-3.71597332E-05 1.35938159E-19 4.89336176E-04 0.00000000E+00 + 1.95815412E-03 0.00000000E+00 7.44294899E-05-2.58606043E-19 2.97722210E-04 +-8.36905908E-19 4.89349560E-04 0.00000000E+00-2.39324912E-04 0.00000000E+00 + 7.44292501E-05-1.66754529E-19-3.72729483E-05 6.73834721E-20-3.71597332E-05 +-1.35938159E-19-2.50565819E-04 0.00000000E+00 7.44294899E-05 2.58606043E-19 + 2.97722210E-04 8.36905908E-19 4.89336176E-04 0.00000000E+00 1.95815412E-03 + 0.00000000E+00 7.44292501E-05 1.66754529E-19-3.72729483E-05-6.73834721E-20 + 4.89349560E-04 0.00000000E+00-2.39324912E-04 0.00000000E+00 5.12927099E-04 + 0.00000000E+00 7.42094428E-05-2.85146593E-19 4.00838103E-03 0.00000000E+00 + 4.89336176E-04 0.00000000E+00 5.94552003E-04-2.36379438E-18 7.44294899E-05 +-2.58606043E-19-2.76779198E-04 0.00000000E+00-3.69526962E-05 2.74449154E-20 + 5.39016708E-04 0.00000000E+00 2.15716390E-03 0.00000000E+00 7.40027329E-05 +-8.82205679E-21 2.96014925E-04-1.70626753E-19 5.39037271E-04 0.00000000E+00 +-2.62986962E-04 0.00000000E+00 7.40024971E-05-2.08657907E-20-3.70530442E-05 + 6.54360816E-20-3.69526962E-05-2.74449154E-20-2.76779198E-04 0.00000000E+00 + 7.40027329E-05 8.82205679E-21 2.96014925E-04 1.70626753E-19 5.39016708E-04 + 0.00000000E+00 2.15716390E-03 0.00000000E+00 7.40024971E-05 2.08657907E-20 +-3.70530442E-05-6.54360816E-20 5.39037271E-04 0.00000000E+00-2.62986962E-04 + 0.00000000E+00-2.62986962E-04 0.00000000E+00-3.70530442E-05 6.54360816E-20 + 5.12910576E-04 0.00000000E+00 2.05258097E-03 0.00000000E+00 7.42096798E-05 +-2.40878536E-19 2.96842840E-04-9.63050978E-19 5.12927099E-04 0.00000000E+00 +-2.50565819E-04 0.00000000E+00 7.42094428E-05-2.85146593E-19-3.71597332E-05 + 1.35938159E-19-3.70530442E-05-6.54360816E-20-2.62986962E-04 0.00000000E+00 + 7.42096798E-05 2.40878536E-19 2.96842840E-04 9.63050978E-19 5.12910576E-04 + 0.00000000E+00 2.05258097E-03 0.00000000E+00 7.42094428E-05 2.85146593E-19 +-3.71597332E-05-1.35938159E-19 5.12927099E-04 0.00000000E+00-2.50565819E-04 + 0.00000000E+00 7.40024971E-05 2.08657907E-20 5.39037271E-04 0.00000000E+00 + 5.92845084E-04 1.00559325E-18 7.42096798E-05 2.40878536E-19 4.20701092E-03 + 0.00000000E+00 5.12910576E-04 0.00000000E+00 5.39037271E-04 0.00000000E+00 + 7.40024971E-05-2.08657907E-20 4.20701092E-03 0.00000000E+00 5.12910576E-04 + 0.00000000E+00 5.92845084E-04-1.00559325E-18 7.42096798E-05-2.40878536E-19 + 2.52505826E-01 0.00000000E+00 1.44380768E-04-1.11464849E-18 1.01002561E-01 + 0.00000000E+00-2.52507036E-02 0.00000000E+00 7.21908598E-05-6.04225745E-19 +-3.60938437E-05 2.08311261E-19 7.21908598E-05 6.04225745E-19 1.01002561E-01 + 0.00000000E+00 5.77496419E-04 3.33299100E-18 7.21845152E-05 2.29019301E-19 + 2.02007605E-01 0.00000000E+00 2.53673071E-07 0.00000000E+00 1.01002561E-01 + 0.00000000E+00 7.21908598E-05-6.04225745E-19 2.02007605E-01 0.00000000E+00 + 2.53673071E-07 0.00000000E+00 5.77496419E-04-3.33299100E-18 7.21845152E-05 +-2.29019301E-19 1.44380768E-04 1.11464849E-18 2.52505826E-01 0.00000000E+00 + 7.21908598E-05 6.04225745E-19-3.60938437E-05-2.08311261E-19 1.01002561E-01 + 0.00000000E+00-2.52507036E-02 0.00000000E+00 7.21848291E-05 1.92005693E-19 + 9.43971392E-03 0.00000000E+00 5.77535624E-04 8.14182850E-19 7.21999873E-05 + 5.51035468E-20 5.47526269E-02 0.00000000E+00 4.72042869E-03 0.00000000E+00 +-2.52507036E-02 0.00000000E+00-3.60938437E-05 2.08311261E-19 2.53673071E-07 + 0.00000000E+00 4.34227697E-02 0.00000000E+00 7.21845152E-05-2.29019301E-19 + 2.88746182E-04-9.30265833E-19 9.43971392E-03 0.00000000E+00-3.54003565E-03 + 0.00000000E+00 7.21848291E-05-1.92005693E-19-3.60962041E-05 6.17773099E-20 +-3.60938437E-05-2.08311261E-19-2.52507036E-02 0.00000000E+00 7.21845152E-05 + 2.29019301E-19 2.88746182E-04 9.30265833E-19 2.53673071E-07 0.00000000E+00 + 4.34227697E-02 0.00000000E+00 7.21848291E-05 1.92005693E-19-3.60962041E-05 +-6.17773099E-20 9.43971392E-03 0.00000000E+00-3.54003565E-03 0.00000000E+00 + 9.43971392E-03 0.00000000E+00 7.21848291E-05-1.92005693E-19 5.47526269E-02 + 0.00000000E+00 4.72042869E-03 0.00000000E+00 5.77535624E-04-8.14182850E-19 + 7.21999873E-05-5.51035468E-20 7.21998374E-05 1.10659477E-19 4.93416001E-03 + 0.00000000E+00 5.77693717E-04 1.64036732E-18 7.22242578E-05 2.79151031E-19 + 3.25146790E-02 0.00000000E+00 3.29011431E-03 0.00000000E+00-3.54003565E-03 + 0.00000000E+00-3.60962041E-05 6.17773099E-20 4.72042869E-03 0.00000000E+00 + 2.04000208E-02 0.00000000E+00 7.21999873E-05-5.51035468E-20 2.88802971E-04 +-4.37747071E-19 4.93416001E-03 0.00000000E+00-2.05606858E-03 0.00000000E+00 + 7.21998374E-05-1.10659477E-19-3.61060238E-05 9.74526269E-20-3.60962041E-05 +-6.17773099E-20-3.54003565E-03 0.00000000E+00 7.21999873E-05 5.51035468E-20 + 2.88802971E-04 4.37747071E-19 4.72042869E-03 0.00000000E+00 2.04000208E-02 + 0.00000000E+00 7.21998374E-05 1.10659477E-19-3.61060238E-05-9.74526269E-20 + 4.93416001E-03 0.00000000E+00-2.05606858E-03 0.00000000E+00 4.93416001E-03 + 0.00000000E+00 7.21998374E-05-1.10659477E-19 3.25146790E-02 0.00000000E+00 + 3.29011431E-03 0.00000000E+00 5.77693717E-04-1.64036732E-18 7.22242578E-05 +-2.79151031E-19 7.22240354E-05 2.52104109E-19 3.32839305E-03 0.00000000E+00 + 5.77925427E-04 1.71412575E-18 7.22580148E-05 1.81266360E-19 2.31644755E-02 + 0.00000000E+00 2.49697619E-03 0.00000000E+00-2.05606858E-03 0.00000000E+00 +-3.61060238E-05 9.74526269E-20 3.29011431E-03 0.00000000E+00 1.35268909E-02 + 0.00000000E+00 7.22242578E-05-2.79151031E-19 2.88900003E-04-9.77664255E-19 + 3.32839305E-03 0.00000000E+00-1.45634231E-03 0.00000000E+00 7.22240354E-05 +-2.52104109E-19-3.61205126E-05 1.08342617E-19-3.61060238E-05-9.74526269E-20 +-2.05606858E-03 0.00000000E+00 7.22242578E-05 2.79151031E-19 2.88900003E-04 + 9.77664255E-19 3.29011431E-03 0.00000000E+00 1.35268909E-02 0.00000000E+00 + 7.22240354E-05 2.52104109E-19-3.61205126E-05-1.08342617E-19 3.32839305E-03 + 0.00000000E+00-1.45634231E-03 0.00000000E+00 3.32839305E-03 0.00000000E+00 + 7.22240354E-05-2.52104109E-19 2.31644755E-02 0.00000000E+00 2.49697619E-03 + 0.00000000E+00 5.77925427E-04-1.71412575E-18 7.22580148E-05-1.81266360E-19 + 7.22577994E-05 1.92214225E-19 2.50870136E-03 0.00000000E+00 5.78234767E-04 + 1.55462165E-18 7.23015919E-05 1.93065849E-19 1.80014525E-02 0.00000000E+00 + 2.00766466E-03 0.00000000E+00-1.45634231E-03 0.00000000E+00-3.61205126E-05 + 1.08342617E-19 2.49697619E-03 0.00000000E+00 1.01293045E-02 0.00000000E+00 + 7.22580148E-05-1.81266360E-19 2.89035132E-04-7.72819711E-19 2.50870136E-03 + 0.00000000E+00-1.12909150E-03 0.00000000E+00 7.22577994E-05-1.92214225E-19 +-3.61398478E-05 9.63200184E-20-3.61205126E-05-1.08342617E-19-1.45634231E-03 + 0.00000000E+00 7.22580148E-05 1.81266360E-19 2.89035132E-04 7.72819711E-19 + 2.49697619E-03 0.00000000E+00 1.01293045E-02 0.00000000E+00 7.22577994E-05 + 1.92214225E-19-3.61398478E-05-9.63200184E-20 2.50870136E-03 0.00000000E+00 +-1.12909150E-03 0.00000000E+00 2.50870136E-03 0.00000000E+00 7.22577994E-05 +-1.92214225E-19 1.80014525E-02 0.00000000E+00 2.00766466E-03 0.00000000E+00 + 5.78234767E-04-1.55462165E-18 7.23015919E-05-1.93065849E-19 7.23013690E-05 + 1.80471453E-19 2.01239456E-03 0.00000000E+00 5.78622637E-04 1.49071301E-18 + 7.23549998E-05 2.01852945E-19 1.47254906E-02 0.00000000E+00 1.67771234E-03 + 0.00000000E+00-1.12909150E-03 0.00000000E+00-3.61398478E-05 9.63200184E-20 + 2.00766466E-03 0.00000000E+00 8.09952173E-03 0.00000000E+00 7.23015919E-05 +-1.93065849E-19 2.89209436E-04-7.54041549E-19 2.01239456E-03 0.00000000E+00 +-9.22526724E-04 0.00000000E+00 7.23013690E-05-1.80471453E-19-3.61640922E-05 + 9.55810994E-20-3.61398478E-05-9.63200184E-20-1.12909150E-03 0.00000000E+00 + 7.23015919E-05 1.93065849E-19 2.89209436E-04 7.54041549E-19 2.00766466E-03 + 0.00000000E+00 8.09952173E-03 0.00000000E+00 7.23013690E-05 1.80471453E-19 +-3.61640922E-05-9.55810994E-20 2.01239456E-03 0.00000000E+00-9.22526724E-04 + 0.00000000E+00 2.01239456E-03 0.00000000E+00 7.23013690E-05-1.80471453E-19 + 1.47254906E-02 0.00000000E+00 1.67771234E-03 0.00000000E+00 5.78622637E-04 +-1.49071301E-18 7.23549998E-05-2.01852945E-19 7.23547916E-05 2.15314754E-19 + 1.67997372E-03 0.00000000E+00 5.79089697E-04 2.01231867E-18 7.24183382E-05 + 2.83129479E-19 1.24615926E-02 0.00000000E+00 1.44070505E-03 0.00000000E+00 +-9.22526724E-04 0.00000000E+00-3.61640922E-05 9.55810994E-20 1.67771234E-03 + 0.00000000E+00 6.74944581E-03 0.00000000E+00 7.23549998E-05-2.01852945E-19 + 2.89423124E-04-8.51336740E-19 1.67997372E-03 0.00000000E+00-7.80169692E-04 + 0.00000000E+00 7.23547916E-05-2.15314754E-19-3.61932824E-05 1.24611058E-19 +-3.61640922E-05-9.55810994E-20-9.22526724E-04 0.00000000E+00 7.23549998E-05 + 2.01852945E-19 2.89423124E-04 8.51336740E-19 1.67771234E-03 0.00000000E+00 + 6.74944581E-03 0.00000000E+00 7.23547916E-05 2.15314754E-19-3.61932824E-05 +-1.24611058E-19 1.67997372E-03 0.00000000E+00-7.80169692E-04 0.00000000E+00 + 1.67997372E-03 0.00000000E+00 7.23547916E-05-2.15314754E-19 1.24615926E-02 + 0.00000000E+00 1.44070505E-03 0.00000000E+00 5.79089697E-04-2.01231867E-18 + 7.24183382E-05-2.83129479E-19 7.24181029E-05 2.71573524E-19 1.44191797E-03 + 0.00000000E+00 5.79636262E-04 2.49541719E-18 7.24916925E-05 3.56645168E-19 + 1.08035988E-02 0.00000000E+00 1.26241515E-03 0.00000000E+00-7.80169692E-04 + 0.00000000E+00-3.61932824E-05 1.24611058E-19 1.44070505E-03 0.00000000E+00 + 5.78659005E-03 0.00000000E+00 7.24183382E-05-2.83129479E-19 2.89676469E-04 +-1.11602926E-18 1.44191797E-03 0.00000000E+00-6.76083280E-04 0.00000000E+00 + 7.24181029E-05-2.71573524E-19-3.62274489E-05 1.57054673E-19-3.61932824E-05 +-1.24611058E-19-7.80169692E-04 0.00000000E+00 7.24183382E-05 2.83129479E-19 + 2.89676469E-04 1.11602926E-18 1.44070505E-03 0.00000000E+00 5.78659005E-03 + 0.00000000E+00 7.24181029E-05 2.71573524E-19-3.62274489E-05-1.57054673E-19 + 1.44191797E-03 0.00000000E+00-6.76083280E-04 0.00000000E+00 1.44191797E-03 + 0.00000000E+00 7.24181029E-05-2.71573524E-19 1.08035988E-02 0.00000000E+00 + 1.26241515E-03 0.00000000E+00 5.79636262E-04-2.49541719E-18 7.24916925E-05 +-3.56645168E-19-6.76083280E-04 0.00000000E+00-3.62274489E-05 1.57054673E-19 + 1.26241515E-03 0.00000000E+00 5.06532646E-03 0.00000000E+00 7.24916925E-05 +-3.56645168E-19 2.89969984E-04-1.40162493E-18 1.26312319E-03 0.00000000E+00 +-5.96661025E-04 0.00000000E+00 7.24914920E-05-3.91478435E-19-3.62666740E-05 + 1.51602465E-19 7.24914920E-05 3.91478435E-19 1.26312319E-03 0.00000000E+00 + 5.80263915E-04 2.54809016E-18 7.25752041E-05 2.14931424E-19 9.53715082E-03 + 0.00000000E+00 1.12352091E-03 0.00000000E+00 1.26312319E-03 0.00000000E+00 + 7.24914920E-05-3.91478435E-19 9.53715082E-03 0.00000000E+00 1.12352091E-03 + 0.00000000E+00 5.80263915E-04-2.54809016E-18 7.25752041E-05-2.14931424E-19 +-3.62274489E-05-1.57054673E-19-6.76083280E-04 0.00000000E+00 7.24916925E-05 + 3.56645168E-19 2.89969984E-04 1.40162493E-18 1.26241515E-03 0.00000000E+00 + 5.06532646E-03 0.00000000E+00 7.24914920E-05 3.91478435E-19-3.62666740E-05 +-1.51602465E-19 1.26312319E-03 0.00000000E+00-5.96661025E-04 0.00000000E+00 + 7.25749664E-05 1.57829273E-19 1.12396061E-03 0.00000000E+00 5.80972596E-04 + 9.27277926E-19 7.26689274E-05 1.08985416E-19 8.53835985E-03 0.00000000E+00 + 1.01231648E-03 0.00000000E+00-5.96661025E-04 0.00000000E+00-3.62666740E-05 + 1.51602465E-19 1.12352091E-03 0.00000000E+00 4.50494786E-03 0.00000000E+00 + 7.25752041E-05-2.14931424E-19 2.90304001E-04-7.91257512E-19 1.12396061E-03 + 0.00000000E+00-5.34069271E-04 0.00000000E+00 7.25749664E-05-1.57829273E-19 +-3.63109735E-05 6.67036722E-20-3.62666740E-05-1.51602465E-19-5.96661025E-04 + 0.00000000E+00 7.25752041E-05 2.14931424E-19 2.90304001E-04 7.91257512E-19 + 1.12352091E-03 0.00000000E+00 4.50494786E-03 0.00000000E+00 7.25749664E-05 + 1.57829273E-19-3.63109735E-05-6.67036722E-20 1.12396061E-03 0.00000000E+00 +-5.34069271E-04 0.00000000E+00 1.12396061E-03 0.00000000E+00 7.25749664E-05 +-1.57829273E-19 8.53835985E-03 0.00000000E+00 1.01231648E-03 0.00000000E+00 + 5.80972596E-04-9.27277926E-19 7.26689274E-05-1.08985416E-19-5.34069271E-04 + 0.00000000E+00-3.63109735E-05 6.67036722E-20 1.01231648E-03 0.00000000E+00 + 4.05710802E-03 0.00000000E+00 7.26689274E-05-1.08985416E-19 2.90679001E-04 +-5.58320476E-19 1.01260399E-03 0.00000000E+00-4.83478011E-04 0.00000000E+00 + 7.26687164E-05-1.44702286E-19-3.63604477E-05 9.51964654E-20-3.63109735E-05 +-6.67036722E-20-5.34069271E-04 0.00000000E+00 7.26689274E-05 1.08985416E-19 + 2.90679001E-04 5.58320476E-19 1.01231648E-03 0.00000000E+00 4.05710802E-03 + 0.00000000E+00 7.26687164E-05 1.44702286E-19-3.63604477E-05-9.51964654E-20 + 1.01260399E-03 0.00000000E+00-4.83478011E-04 0.00000000E+00 7.26687164E-05 + 1.44702286E-19 1.01260399E-03 0.00000000E+00 5.81764191E-04 1.56241573E-18 + 7.27730743E-05 2.36083575E-19 7.73065242E-03 0.00000000E+00 9.21308052E-04 + 0.00000000E+00 1.01260399E-03 0.00000000E+00 7.26687164E-05-1.44702286E-19 + 7.73065242E-03 0.00000000E+00 9.21308052E-04 0.00000000E+00 5.81764191E-04 +-1.56241573E-18 7.27730743E-05-2.36083575E-19-4.83478011E-04 0.00000000E+00 +-3.63604477E-05 9.51964654E-20 9.21308052E-04 0.00000000E+00 3.69107618E-03 + 0.00000000E+00 7.27730743E-05-2.36083575E-19 2.91095602E-04-8.89589313E-19 + 9.21503391E-04 0.00000000E+00-4.41745080E-04 0.00000000E+00 7.27728463E-05 +-2.32139380E-19-3.64151453E-05 1.06368428E-19 7.27728463E-05 2.32139380E-19 + 9.21503391E-04 0.00000000E+00 5.82639281E-04 1.70368713E-18 7.28877347E-05 + 1.93334334E-19 7.06411950E-03 0.00000000E+00 8.45476931E-04 0.00000000E+00 + 9.21503391E-04 0.00000000E+00 7.27728463E-05-2.32139380E-19 7.06411950E-03 + 0.00000000E+00 8.45476931E-04 0.00000000E+00 5.82639281E-04-1.70368713E-18 + 7.28877347E-05-1.93334334E-19-3.63604477E-05-9.51964654E-20-4.83478011E-04 + 0.00000000E+00 7.27730743E-05 2.36083575E-19 2.91095602E-04 8.89589313E-19 + 9.21308052E-04 0.00000000E+00 3.69107618E-03 0.00000000E+00 7.27728463E-05 + 2.32139380E-19-3.64151453E-05-1.06368428E-19 9.21503391E-04 0.00000000E+00 +-4.41745080E-04 0.00000000E+00 7.28875110E-05 1.84190981E-19 8.45614190E-04 + 0.00000000E+00 5.83599508E-04 2.03664784E-18 7.30131388E-05 3.28617652E-19 + 6.50485425E-03 0.00000000E+00 7.81339357E-04 0.00000000E+00-4.41745080E-04 + 0.00000000E+00-3.64151453E-05 1.06368428E-19 8.45476931E-04 0.00000000E+00 + 3.38637919E-03 0.00000000E+00 7.28877347E-05-1.93334334E-19 2.91554327E-04 +-8.19125309E-19 8.45614190E-04 0.00000000E+00-4.06738387E-04 0.00000000E+00 + 7.28875110E-05-1.84190981E-19-3.64751625E-05 1.28202158E-19-3.64151453E-05 +-1.06368428E-19-4.41745080E-04 0.00000000E+00 7.28877347E-05 1.93334334E-19 + 2.91554327E-04 8.19125309E-19 8.45476931E-04 0.00000000E+00 3.38637919E-03 + 0.00000000E+00 7.28875110E-05 1.84190981E-19-3.64751625E-05-1.28202158E-19 + 8.45614190E-04 0.00000000E+00-4.06738387E-04 0.00000000E+00 8.45614190E-04 + 0.00000000E+00 7.28875110E-05-1.84190981E-19 6.50485425E-03 0.00000000E+00 + 7.81339357E-04 0.00000000E+00 5.83599508E-04-2.03664784E-18 7.30131388E-05 +-3.28617652E-19-4.06738387E-04 0.00000000E+00-3.64751625E-05 1.28202158E-19 + 7.81339357E-04 0.00000000E+00 3.12885444E-03 0.00000000E+00 7.30131388E-05 +-3.28617652E-19 2.92055999E-04-1.24460224E-18 7.81438457E-04 0.00000000E+00 +-3.76959722E-04 0.00000000E+00 7.30129146E-05-3.46541010E-19-3.65405886E-05 + 1.32785705E-19-3.64751625E-05-1.28202158E-19-4.06738387E-04 0.00000000E+00 + 7.30131388E-05 3.28617652E-19 2.92055999E-04 1.24460224E-18 7.81339357E-04 + 0.00000000E+00 3.12885444E-03 0.00000000E+00 7.30129146E-05 3.46541010E-19 +-3.65405886E-05-1.32785705E-19 7.81438457E-04 0.00000000E+00-3.76959722E-04 + 0.00000000E+00 7.30129146E-05 3.46541010E-19 7.81438457E-04 0.00000000E+00 + 5.84646274E-04 2.18002859E-18 7.31494398E-05 1.84601809E-19 6.02900608E-03 + 0.00000000E+00 7.26400430E-04 0.00000000E+00 7.81438457E-04 0.00000000E+00 + 7.30129146E-05-3.46541010E-19 6.02900608E-03 0.00000000E+00 7.26400430E-04 + 0.00000000E+00 5.84646274E-04-2.18002859E-18 7.31494398E-05-1.84601809E-19 +-3.76959722E-04 0.00000000E+00-3.65405886E-05 1.32785705E-19 7.26400430E-04 + 0.00000000E+00 2.90838824E-03 0.00000000E+00 7.31494398E-05-1.84601809E-19 + 2.92601278E-04-7.63089717E-19 7.26473614E-04 0.00000000E+00-3.51325435E-04 + 0.00000000E+00 7.31492119E-05-1.63856052E-19-3.66115196E-05 9.06397343E-20 + 7.31492119E-05 1.63856052E-19 7.26473614E-04 0.00000000E+00 5.85781103E-04 + 1.39773764E-18 7.32968666E-05 1.98702885E-19 5.61931079E-03 0.00000000E+00 + 6.78828125E-04 0.00000000E+00 7.26473614E-04 0.00000000E+00 7.31492119E-05 +-1.63856052E-19 5.61931079E-03 0.00000000E+00 6.78828125E-04 0.00000000E+00 + 5.85781103E-04-1.39773764E-18 7.32968666E-05-1.98702885E-19-3.65405886E-05 +-1.32785705E-19-3.76959722E-04 0.00000000E+00 7.31494398E-05 1.84601809E-19 + 2.92601278E-04 7.63089717E-19 7.26400430E-04 0.00000000E+00 2.90838824E-03 + 0.00000000E+00 7.31492119E-05 1.63856052E-19-3.66115196E-05-9.06397343E-20 + 7.26473614E-04 0.00000000E+00-3.51325435E-04 0.00000000E+00 7.32966382E-05 + 2.06550202E-19 6.78883259E-04 0.00000000E+00 5.87005832E-04 1.72765771E-18 + 7.34556401E-05 2.26930845E-19 5.26296537E-03 0.00000000E+00 6.37246200E-04 + 0.00000000E+00-3.51325435E-04 0.00000000E+00-3.66115196E-05 9.06397343E-20 + 6.78828125E-04 0.00000000E+00 2.71756861E-03 0.00000000E+00 7.32968666E-05 +-1.98702885E-19 2.93191063E-04-8.08022071E-19 6.78883259E-04 0.00000000E+00 +-3.29032365E-04 0.00000000E+00 7.32966382E-05-2.06550202E-19-3.66880696E-05 + 1.08370262E-19-3.66115196E-05-9.06397343E-20-3.51325435E-04 0.00000000E+00 + 7.32968666E-05 1.98702885E-19 2.93191063E-04 8.08022071E-19 6.78828125E-04 + 0.00000000E+00 2.71756861E-03 0.00000000E+00 7.32966382E-05 2.06550202E-19 +-3.66880696E-05-1.08370262E-19 6.78883259E-04 0.00000000E+00-3.29032365E-04 + 0.00000000E+00 6.78883259E-04 0.00000000E+00 7.32966382E-05-2.06550202E-19 + 5.26296537E-03 0.00000000E+00 6.37246200E-04 0.00000000E+00 5.87005832E-04 +-1.72765771E-18 7.34556401E-05-2.26930845E-19-3.29032365E-04 0.00000000E+00 +-3.66880696E-05 1.08370262E-19 6.37246200E-04 0.00000000E+00 2.55083722E-03 + 0.00000000E+00 7.34556401E-05-2.26930845E-19 2.93826253E-04-9.39821608E-19 + 6.37288447E-04 0.00000000E+00-3.09472527E-04 0.00000000E+00 7.34554112E-05 +-2.36090296E-19-3.67703614E-05 1.34558776E-19-3.66880696E-05-1.08370262E-19 +-3.29032365E-04 0.00000000E+00 7.34556401E-05 2.26930845E-19 2.93826253E-04 + 9.39821608E-19 6.37246200E-04 0.00000000E+00 2.55083722E-03 0.00000000E+00 + 7.34554112E-05 2.36090296E-19-3.67703614E-05-1.34558776E-19 6.37288447E-04 + 0.00000000E+00-3.09472527E-04 0.00000000E+00 7.34554112E-05 2.36090296E-19 + 6.37288447E-04 0.00000000E+00 5.88322431E-04 2.19400249E-18 7.36260344E-05 + 3.02144806E-19 4.95027334E-03 0.00000000E+00 6.00601663E-04 0.00000000E+00 + 6.37288447E-04 0.00000000E+00 7.34554112E-05-2.36090296E-19 4.95027334E-03 + 0.00000000E+00 6.00601663E-04 0.00000000E+00 5.88322431E-04-2.19400249E-18 + 7.36260344E-05-3.02144806E-19-3.09472527E-04 0.00000000E+00-3.67703614E-05 + 1.34558776E-19 6.00601663E-04 0.00000000E+00 2.40394604E-03 0.00000000E+00 + 7.36260344E-05-3.02144806E-19 2.94507909E-04-1.11868878E-18 6.00634481E-04 + 0.00000000E+00-2.92177181E-04 0.00000000E+00 7.36258017E-05-2.99382734E-19 +-3.68585216E-05 1.05757241E-19 7.36258017E-05 2.99382734E-19 6.00634481E-04 + 0.00000000E+00 5.89732908E-04 1.73149361E-18 7.38082848E-05 1.23646230E-19 + 4.67375581E-03 0.00000000E+00 5.68074243E-04 0.00000000E+00 6.00634481E-04 + 0.00000000E+00 7.36258017E-05-2.99382734E-19 4.67375581E-03 0.00000000E+00 + 5.68074243E-04 0.00000000E+00 5.89732908E-04-1.73149361E-18 7.38082848E-05 +-1.23646230E-19-3.67703614E-05-1.34558776E-19-3.09472527E-04 0.00000000E+00 + 7.36260344E-05 3.02144806E-19 2.94507909E-04 1.11868878E-18 6.00601663E-04 + 0.00000000E+00 2.40394604E-03 0.00000000E+00 7.36258017E-05 2.99382734E-19 +-3.68585216E-05-1.05757241E-19 6.00634481E-04 0.00000000E+00-2.92177181E-04 + 0.00000000E+00 7.38080520E-05 1.00957605E-19 5.68100086E-04 0.00000000E+00 + 5.91239613E-04 3.46836424E-19 7.40027329E-05 8.82205679E-21 4.42755351E-03 + 0.00000000E+00 5.39016708E-04 0.00000000E+00-2.92177181E-04 0.00000000E+00 +-3.68585216E-05 1.05757241E-19 5.68074243E-04 0.00000000E+00 2.27359037E-03 + 0.00000000E+00 7.38082848E-05-1.23646230E-19 2.95237030E-04-4.79358099E-19 + 5.68100086E-04 0.00000000E+00-2.76779198E-04 0.00000000E+00 7.38080520E-05 +-1.00957605E-19-3.69526962E-05 2.74449154E-20-3.68585216E-05-1.05757241E-19 +-2.92177181E-04 0.00000000E+00 7.38082848E-05 1.23646230E-19 2.95237030E-04 + 4.79358099E-19 5.68074243E-04 0.00000000E+00 2.27359037E-03 0.00000000E+00 + 7.38080520E-05 1.00957605E-19-3.69526962E-05-2.74449154E-20 5.68100086E-04 + 0.00000000E+00-2.76779198E-04 0.00000000E+00 5.68100086E-04 0.00000000E+00 + 7.38080520E-05-1.00957605E-19 4.42755351E-03 0.00000000E+00 5.39016708E-04 + 0.00000000E+00 5.91239613E-04-3.46836424E-19 7.40027329E-05-8.82205679E-21 + 2.14691448E-04 0.00000000E+00 6.06593275E-05-2.11915552E-19 1.70326147E-03 + 0.00000000E+00 2.11129320E-04 0.00000000E+00 4.86530401E-04-1.45145463E-18 + 6.09723509E-05-1.44803072E-19-3.04079196E-05-8.91796561E-20-1.06455192E-04 + 0.00000000E+00 6.09723509E-05 1.44803072E-19 1.21865303E-04 3.01782260E-19 + 2.11129320E-04 0.00000000E+00 4.23151561E-04 0.00000000E+00 6.06593275E-05 + 2.11915552E-19 2.14691448E-04 0.00000000E+00 4.86530401E-04 1.45145463E-18 + 6.09723509E-05 1.44803072E-19 1.70326147E-03 0.00000000E+00 2.11129320E-04 + 0.00000000E+00-1.06455192E-04 0.00000000E+00-3.04079196E-05 8.91796561E-20 + 2.11129320E-04 0.00000000E+00 4.23151561E-04 0.00000000E+00 6.09723509E-05 +-1.44803072E-19 1.21865303E-04-3.01782260E-19-3.02528068E-05-1.02223430E-19 +-1.08272646E-04 0.00000000E+00 6.06574152E-05 2.10888680E-19 2.42636849E-04 + 8.17041259E-19 2.14684023E-04 0.00000000E+00 8.58808235E-04 0.00000000E+00 + 6.06593275E-05 2.11915552E-19-3.04079196E-05-8.91796561E-20 2.14691448E-04 + 0.00000000E+00-1.06455192E-04 0.00000000E+00 2.18406560E-04 0.00000000E+00 + 6.03538119E-05-1.98005039E-19 1.73230242E-03 0.00000000E+00 2.14684023E-04 + 0.00000000E+00 4.84038793E-04-1.65072057E-18 6.06574152E-05-2.10888680E-19 +-1.08272646E-04 0.00000000E+00-3.02528068E-05 1.02223430E-19 2.14684023E-04 + 0.00000000E+00 8.58808235E-04 0.00000000E+00 6.06574152E-05-2.10888680E-19 + 2.42636849E-04-8.17041259E-19 2.14691448E-04 0.00000000E+00-1.06455192E-04 + 0.00000000E+00 6.06593275E-05-2.11915552E-19-3.04079196E-05 8.91796561E-20 + 6.03538119E-05 1.98005039E-19 2.18406560E-04 0.00000000E+00 4.84038793E-04 + 1.65072057E-18 6.06574152E-05 2.10888680E-19 1.73230242E-03 0.00000000E+00 + 2.14684023E-04 0.00000000E+00 7.96272581E-05 2.59421630E-19 2.96926596E-04 + 0.00000000E+00 6.39039784E-04 2.00885375E-18 8.01341282E-05 2.50716854E-19 + 2.34749116E-03 0.00000000E+00 2.89975775E-04 0.00000000E+00-1.46725593E-04 + 0.00000000E+00-3.99403466E-05 1.27534621E-19 2.89975775E-04 0.00000000E+00 + 1.01760462E-03 0.00000000E+00 8.01341282E-05-2.50716854E-19 2.80927199E-04 +-9.08863458E-19 2.18406560E-04 0.00000000E+00-1.08272646E-04 0.00000000E+00 + 6.03538119E-05-1.98005039E-19-3.02528068E-05 1.02223430E-19-3.99403466E-05 +-1.27534621E-19-1.46725593E-04 0.00000000E+00 8.01341282E-05 2.50716854E-19 + 2.80927199E-04 9.08863458E-19 2.89975775E-04 0.00000000E+00 1.01760462E-03 + 0.00000000E+00 6.03538119E-05 1.98005039E-19-3.02528068E-05-1.02223430E-19 + 2.18406560E-04 0.00000000E+00-1.08272646E-04 0.00000000E+00 2.96926596E-04 + 0.00000000E+00 7.96272581E-05-2.59421630E-19 2.34749116E-03 0.00000000E+00 + 2.89975775E-04 0.00000000E+00 6.39039784E-04-2.00885375E-18 8.01341282E-05 +-2.50716854E-19 7.91435571E-05 2.54346782E-19 3.04320363E-04 0.00000000E+00 + 6.35075183E-04 2.13773822E-18 7.96270880E-05 2.73159155E-19 2.40484179E-03 + 0.00000000E+00 2.96924047E-04 0.00000000E+00-1.50311103E-04 0.00000000E+00 +-3.96926613E-05 1.31876484E-19 2.96924047E-04 0.00000000E+00 1.18786032E-03 + 0.00000000E+00 7.96270880E-05-2.73159155E-19 3.18517009E-04-1.05524314E-18 + 2.96926596E-04 0.00000000E+00-1.46725593E-04 0.00000000E+00 7.96272581E-05 +-2.59421630E-19-3.99403466E-05 1.27534621E-19-3.96926613E-05-1.31876484E-19 +-1.50311103E-04 0.00000000E+00 7.96270880E-05 2.73159155E-19 3.18517009E-04 + 1.05524314E-18 2.96924047E-04 0.00000000E+00 1.18786032E-03 0.00000000E+00 + 7.96272581E-05 2.59421630E-19-3.99403466E-05-1.27534621E-19 2.96926596E-04 + 0.00000000E+00-1.46725593E-04 0.00000000E+00 3.04320363E-04 0.00000000E+00 + 7.91435571E-05-2.54346782E-19 2.40484179E-03 0.00000000E+00 2.96924047E-04 + 0.00000000E+00 6.35075183E-04-2.13773822E-18 7.96270880E-05-2.73159155E-19 + 7.86844880E-05 2.51702607E-19 3.12206384E-04 0.00000000E+00 6.31307374E-04 + 1.94264770E-18 7.91439743E-05 2.42481483E-19 2.46596012E-03 0.00000000E+00 + 3.04319873E-04 0.00000000E+00-1.54131564E-04 0.00000000E+00-3.94571156E-05 + 1.23546023E-19 3.04319873E-04 0.00000000E+00 1.21745555E-03 0.00000000E+00 + 7.91439743E-05-2.42481483E-19 3.16583654E-04-1.00349649E-18 3.04320363E-04 + 0.00000000E+00-1.50311103E-04 0.00000000E+00 7.91435571E-05-2.54346782E-19 +-3.96926613E-05 1.31876484E-19-3.94571156E-05-1.23546023E-19-1.54131564E-04 + 0.00000000E+00 7.91439743E-05 2.42481483E-19 3.16583654E-04 1.00349649E-18 + 3.04319873E-04 0.00000000E+00 1.21745555E-03 0.00000000E+00 7.91435571E-05 + 2.54346782E-19-3.96926613E-05-1.31876484E-19 3.04320363E-04 0.00000000E+00 +-1.50311103E-04 0.00000000E+00 3.12206384E-04 0.00000000E+00 7.86844880E-05 +-2.51702607E-19 2.46596012E-03 0.00000000E+00 3.04319873E-04 0.00000000E+00 + 6.31307374E-04-1.94264770E-18 7.91439743E-05-2.42481483E-19 7.82476655E-05 + 3.58714096E-19 3.20621826E-04 0.00000000E+00 6.27723377E-04 2.48099194E-18 + 7.86847495E-05 2.57655201E-19 2.53114956E-03 0.00000000E+00 3.12205094E-04 + 0.00000000E+00-1.58206730E-04 0.00000000E+00-3.92331038E-05 1.54092324E-19 + 3.12205094E-04 0.00000000E+00 1.24901231E-03 0.00000000E+00 7.86847495E-05 +-2.57655201E-19 3.14746475E-04-1.05101002E-18 3.12206384E-04 0.00000000E+00 +-1.54131564E-04 0.00000000E+00 7.86844880E-05-2.51702607E-19-3.94571156E-05 + 1.23546023E-19-3.92331038E-05-1.54092324E-19-1.58206730E-04 0.00000000E+00 + 7.86847495E-05 2.57655201E-19 3.14746475E-04 1.05101002E-18 3.12205094E-04 + 0.00000000E+00 1.24901231E-03 0.00000000E+00 7.86844880E-05 2.51702607E-19 +-3.94571156E-05-1.23546023E-19 3.12206384E-04 0.00000000E+00-1.54131564E-04 + 0.00000000E+00 3.20621826E-04 0.00000000E+00 7.82476655E-05-3.58714096E-19 + 2.53114956E-03 0.00000000E+00 3.12205094E-04 0.00000000E+00 6.27723377E-04 +-2.48099194E-18 7.86847495E-05-2.57655201E-19 7.78322240E-05 2.08933904E-19 + 3.29614774E-04 0.00000000E+00 6.24314774E-04 2.38290838E-18 7.82479558E-05 + 3.70549476E-19 2.60076848E-03 0.00000000E+00 3.20620423E-04 0.00000000E+00 +-1.62558799E-04 0.00000000E+00-3.90200449E-05 1.44870845E-19 3.20620423E-04 + 0.00000000E+00 1.28269079E-03 0.00000000E+00 7.82479558E-05-3.70549476E-19 + 3.12998870E-04-1.36681858E-18 3.20621826E-04 0.00000000E+00-1.58206730E-04 + 0.00000000E+00 7.82476655E-05-3.58714096E-19-3.92331038E-05 1.54092324E-19 +-3.90200449E-05-1.44870845E-19-1.62558799E-04 0.00000000E+00 7.82479558E-05 + 3.70549476E-19 3.12998870E-04 1.36681858E-18 3.20620423E-04 0.00000000E+00 + 1.28269079E-03 0.00000000E+00 7.82476655E-05 3.58714096E-19-3.92331038E-05 +-1.54092324E-19 3.20621826E-04 0.00000000E+00-1.58206730E-04 0.00000000E+00 + 3.29614774E-04 0.00000000E+00 7.78322240E-05-2.08933904E-19 2.60076848E-03 + 0.00000000E+00 3.20620423E-04 0.00000000E+00 6.24314774E-04-2.38290838E-18 + 7.82479558E-05-3.70549476E-19 7.74370958E-05 1.12123942E-19 3.39238444E-04 + 0.00000000E+00 6.21072714E-04 1.02612150E-18 7.78325003E-05 1.76745171E-19 + 2.67521734E-03 0.00000000E+00 3.29613039E-04 0.00000000E+00-1.67212871E-04 + 0.00000000E+00-3.88173990E-05 7.22172781E-20 3.29613039E-04 0.00000000E+00 + 1.31868100E-03 0.00000000E+00 7.78325003E-05-1.76745171E-19 3.11336709E-04 +-8.06254492E-19 3.29614774E-04 0.00000000E+00-1.62558799E-04 0.00000000E+00 + 7.78322240E-05-2.08933904E-19-3.90200449E-05 1.44870845E-19-3.88173990E-05 +-7.22172781E-20-1.67212871E-04 0.00000000E+00 7.78325003E-05 1.76745171E-19 + 3.11336709E-04 8.06254492E-19 3.29613039E-04 0.00000000E+00 1.31868100E-03 + 0.00000000E+00 7.78322240E-05 2.08933904E-19-3.90200449E-05-1.44870845E-19 + 3.29614774E-04 0.00000000E+00-1.62558799E-04 0.00000000E+00 3.39238444E-04 + 0.00000000E+00 7.74370958E-05-1.12123942E-19 2.67521734E-03 0.00000000E+00 + 3.29613039E-04 0.00000000E+00 6.21072714E-04-1.02612150E-18 7.78325003E-05 +-1.76745171E-19-1.72197455E-04 0.00000000E+00-3.86246740E-05 1.55625796E-19 + 3.39236367E-04 0.00000000E+00 1.35719665E-03 0.00000000E+00 7.74373684E-05 +-1.51479002E-19 3.09755846E-04-6.56074923E-19 3.39238444E-04 0.00000000E+00 +-1.67212871E-04 0.00000000E+00 7.74370958E-05-1.12123942E-19-3.88173990E-05 + 7.22172781E-20 7.70613276E-05 4.71024180E-19 3.49553453E-04 0.00000000E+00 + 6.17989374E-04 2.60308139E-18 7.74373684E-05 1.51479002E-19 2.75495220E-03 + 0.00000000E+00 3.39236367E-04 0.00000000E+00 3.49553453E-04 0.00000000E+00 + 7.70613276E-05-4.71024180E-19 2.75495220E-03 0.00000000E+00 3.39236367E-04 + 0.00000000E+00 6.17989374E-04-2.60308139E-18 7.74373684E-05-1.51479002E-19 +-3.86246740E-05-1.55625796E-19-1.72197455E-04 0.00000000E+00 7.74373684E-05 + 1.51479002E-19 3.09755846E-04 6.56074923E-19 3.39236367E-04 0.00000000E+00 + 1.35719665E-03 0.00000000E+00 7.74370958E-05 1.12123942E-19-3.88173990E-05 +-7.22172781E-20 3.39238444E-04 0.00000000E+00-1.67212871E-04 0.00000000E+00 + 7.67040762E-05 5.80547583E-20 3.60629146E-04 0.00000000E+00 6.15057503E-04 + 1.89609337E-18 7.70615940E-05 4.33841430E-19 2.84049214E-03 0.00000000E+00 + 3.49550957E-04 0.00000000E+00-1.77545026E-04 0.00000000E+00-3.84414176E-05 + 1.22974047E-19 3.49550957E-04 0.00000000E+00 1.39848064E-03 0.00000000E+00 + 7.70615940E-05-4.33841430E-19 3.08252460E-04-1.57547897E-18 3.49553453E-04 + 0.00000000E+00-1.72197455E-04 0.00000000E+00 7.70613276E-05-4.71024180E-19 +-3.86246740E-05 1.55625796E-19-3.84414176E-05-1.22974047E-19-1.77545026E-04 + 0.00000000E+00 7.70615940E-05 4.33841430E-19 3.08252460E-04 1.57547897E-18 + 3.49550957E-04 0.00000000E+00 1.39848064E-03 0.00000000E+00 7.70613276E-05 + 4.71024180E-19-3.86246740E-05-1.55625796E-19 3.49553453E-04 0.00000000E+00 +-1.72197455E-04 0.00000000E+00 3.60629146E-04 0.00000000E+00 7.67040762E-05 +-5.80547583E-20 2.84049214E-03 0.00000000E+00 3.49550957E-04 0.00000000E+00 + 6.15057503E-04-1.89609337E-18 7.70615940E-05-4.33841430E-19-1.83292753E-04 + 0.00000000E+00-3.82672213E-05 1.27081310E-19 3.60626165E-04 0.00000000E+00 + 1.44281079E-03 0.00000000E+00 7.67043391E-05-8.48884992E-20 3.06823162E-04 +-5.29741474E-19 3.60629146E-04 0.00000000E+00-1.77545026E-04 0.00000000E+00 + 7.67040762E-05-5.80547583E-20-3.84414176E-05 1.22974047E-19-3.82672213E-05 +-1.27081310E-19-1.83292753E-04 0.00000000E+00 7.67043391E-05 8.48884992E-20 + 3.06823162E-04 5.29741474E-19 3.60626165E-04 0.00000000E+00 1.44281079E-03 + 0.00000000E+00 7.67040762E-05 5.80547583E-20-3.84414176E-05-1.22974047E-19 + 3.60629146E-04 0.00000000E+00-1.77545026E-04 0.00000000E+00 7.63645460E-05 + 4.23436741E-19 3.72544847E-04 0.00000000E+00 6.12270583E-04 2.03875790E-18 + 7.67043391E-05 8.48884992E-20 2.93243150E-03 0.00000000E+00 3.60626165E-04 + 0.00000000E+00 3.72544847E-04 0.00000000E+00 7.63645460E-05-4.23436741E-19 + 2.93243150E-03 0.00000000E+00 3.60626165E-04 0.00000000E+00 6.12270583E-04 +-2.03875790E-18 7.67043391E-05-8.48884992E-20-1.89483264E-04 0.00000000E+00 +-3.81017018E-05 1.74314816E-19 3.72541280E-04 0.00000000E+00 1.49050504E-03 + 0.00000000E+00 7.63648045E-05-4.26180520E-19 3.05464770E-04-1.52681598E-18 + 3.72544847E-04 0.00000000E+00-1.83292753E-04 0.00000000E+00 7.63645460E-05 +-4.23436741E-19-3.82672213E-05 1.27081310E-19 7.60420025E-05 2.71078746E-19 + 3.85391775E-04 0.00000000E+00 6.09622471E-04 2.88074516E-18 7.63648045E-05 + 4.26180520E-19 3.03145166E-03 0.00000000E+00 3.72541280E-04 0.00000000E+00 + 3.85391775E-04 0.00000000E+00 7.60420025E-05-2.71078746E-19 3.03145166E-03 + 0.00000000E+00 3.72541280E-04 0.00000000E+00 6.09622471E-04-2.88074516E-18 + 7.63648045E-05-4.26180520E-19-3.81017018E-05-1.74314816E-19-1.89483264E-04 + 0.00000000E+00 7.63648045E-05 4.26180520E-19 3.05464770E-04 1.52681598E-18 + 3.72541280E-04 0.00000000E+00 1.49050504E-03 0.00000000E+00 7.63645460E-05 + 4.23436741E-19-3.82672213E-05-1.27081310E-19 3.72544847E-04 0.00000000E+00 +-1.83292753E-04 0.00000000E+00 7.57357700E-05 1.27061470E-19 3.99275362E-04 + 0.00000000E+00 6.07107544E-04 1.36244647E-18 7.60422581E-05 2.39031309E-19 + 3.13833852E-03 0.00000000E+00 3.85387511E-04 0.00000000E+00-1.96165718E-04 + 0.00000000E+00-3.79445070E-05 9.15231948E-20 3.85387511E-04 0.00000000E+00 + 1.54192905E-03 0.00000000E+00 7.60422581E-05-2.39031309E-19 3.04174348E-04 +-1.03595016E-18 3.85391775E-04 0.00000000E+00-1.89483264E-04 0.00000000E+00 + 7.60420025E-05-2.71078746E-19-3.81017018E-05 1.74314816E-19-3.79445070E-05 +-9.15231948E-20-1.96165718E-04 0.00000000E+00 7.60422581E-05 2.39031309E-19 + 3.04174348E-04 1.03595016E-18 3.85387511E-04 0.00000000E+00 1.54192905E-03 + 0.00000000E+00 7.60420025E-05 2.71078746E-19-3.81017018E-05-1.74314816E-19 + 3.85391775E-04 0.00000000E+00-1.89483264E-04 0.00000000E+00 3.99275362E-04 + 0.00000000E+00 7.57357700E-05-1.27061470E-19 3.13833852E-03 0.00000000E+00 + 3.85387511E-04 0.00000000E+00 6.07107544E-04-1.36244647E-18 7.60422581E-05 +-2.39031309E-19-2.03397069E-04 0.00000000E+00-3.77953126E-05 9.16564431E-20 + 3.99270242E-04 0.00000000E+00 1.59750546E-03 0.00000000E+00 7.57360200E-05 +-1.66253623E-19 3.02949187E-04-6.38816820E-19 3.99275362E-04 0.00000000E+00 +-1.96165718E-04 0.00000000E+00 7.57357700E-05-1.27061470E-19-3.79445070E-05 + 9.15231948E-20-3.77953126E-05-9.16564431E-20-2.03397069E-04 0.00000000E+00 + 7.57360200E-05 1.66253623E-19 3.02949187E-04 6.38816820E-19 3.99270242E-04 + 0.00000000E+00 1.59750546E-03 0.00000000E+00 7.57357700E-05 1.27061470E-19 +-3.79445070E-05-9.15231948E-20 3.99275362E-04 0.00000000E+00-1.96165718E-04 + 0.00000000E+00 7.54452306E-05 2.00372150E-19 4.14318035E-04 0.00000000E+00 + 6.04720596E-04 1.54474102E-18 7.57360200E-05 1.66253623E-19 3.25400233E-03 + 0.00000000E+00 3.99270242E-04 0.00000000E+00 4.14318035E-04 0.00000000E+00 + 7.54452306E-05-2.00372150E-19 3.25400233E-03 0.00000000E+00 3.99270242E-04 + 0.00000000E+00 6.04720596E-04-1.54474102E-18 7.57360200E-05-1.66253623E-19 +-2.11243682E-04 0.00000000E+00-3.76538272E-05 6.20176414E-20 4.14311898E-04 + 0.00000000E+00 1.65772526E-03 0.00000000E+00 7.54454813E-05-1.65756107E-19 + 3.01786829E-04-6.89024582E-19 4.14318035E-04 0.00000000E+00-2.03397069E-04 + 0.00000000E+00 7.54452306E-05-2.00372150E-19-3.77953126E-05 9.16564431E-20 + 7.51698276E-05 8.23144585E-20 4.30662828E-04 0.00000000E+00 6.02456994E-04 + 9.23474648E-19 7.54454813E-05 1.65756107E-19 3.37950392E-03 0.00000000E+00 + 4.14311898E-04 0.00000000E+00 4.30662828E-04 0.00000000E+00 7.51698276E-05 +-8.23144585E-20 3.37950392E-03 0.00000000E+00 4.14311898E-04 0.00000000E+00 + 6.02456994E-04-9.23474648E-19 7.54454813E-05-1.65756107E-19-3.76538272E-05 +-6.20176414E-20-2.11243682E-04 0.00000000E+00 7.54454813E-05 1.65756107E-19 + 3.01786829E-04 6.89024582E-19 4.14311898E-04 0.00000000E+00 1.65772526E-03 + 0.00000000E+00 7.54452306E-05 2.00372150E-19-3.77953126E-05-9.16564431E-20 + 4.14318035E-04 0.00000000E+00-2.03397069E-04 0.00000000E+00 7.49090109E-05 + 2.82564308E-19 4.48477606E-04 0.00000000E+00 6.00312236E-04 1.43597767E-18 + 7.51700730E-05 8.76795328E-20 3.51608496E-03 0.00000000E+00 4.30655417E-04 + 0.00000000E+00-2.19783256E-04 0.00000000E+00-3.75197710E-05 9.25609601E-20 + 4.30655417E-04 0.00000000E+00 1.72316193E-03 0.00000000E+00 7.51700730E-05 +-8.76795328E-20 3.00685012E-04-4.41861034E-19 4.30662828E-04 0.00000000E+00 +-2.11243682E-04 0.00000000E+00 7.51698276E-05-8.23144585E-20-3.76538272E-05 + 6.20176414E-20-3.75197710E-05-9.25609601E-20-2.19783256E-04 0.00000000E+00 + 7.51700730E-05 8.76795328E-20 3.00685012E-04 4.41861034E-19 4.30655417E-04 + 0.00000000E+00 1.72316193E-03 0.00000000E+00 7.51698276E-05 8.23144585E-20 +-3.76538272E-05-6.20176414E-20 4.30662828E-04 0.00000000E+00-2.11243682E-04 + 0.00000000E+00 4.48477606E-04 0.00000000E+00 7.49090109E-05-2.82564308E-19 + 3.51608496E-03 0.00000000E+00 4.30655417E-04 0.00000000E+00 6.00312236E-04 +-1.43597767E-18 7.51700730E-05-8.76795328E-20-2.29107412E-04 0.00000000E+00 +-3.73928893E-05 1.33711675E-19 4.48468635E-04 0.00000000E+00 1.79448896E-03 + 0.00000000E+00 7.49092552E-05-3.36018317E-19 2.99641571E-04-1.11531980E-18 + 4.48477606E-04 0.00000000E+00-2.19783256E-04 0.00000000E+00 7.49090109E-05 +-2.82564308E-19-3.75197710E-05 9.25609601E-20-3.73928893E-05-1.33711675E-19 +-2.29107412E-04 0.00000000E+00 7.49092552E-05 3.36018317E-19 2.99641571E-04 + 1.11531980E-18 4.48468635E-04 0.00000000E+00 1.79448896E-03 0.00000000E+00 + 7.49090109E-05 2.82564308E-19-3.75197710E-05-9.25609601E-20 4.48477606E-04 + 0.00000000E+00-2.19783256E-04 0.00000000E+00 7.46623019E-05 1.98828385E-19 + 4.67961014E-04 0.00000000E+00 5.98282265E-04 2.32506205E-18 7.49092552E-05 + 3.36018317E-19 3.66520960E-03 0.00000000E+00 4.48468635E-04 0.00000000E+00 + 4.67961014E-04 0.00000000E+00 7.46623019E-05-1.98828385E-19 3.66520960E-03 + 0.00000000E+00 4.48468635E-04 0.00000000E+00 5.98282265E-04-2.32506205E-18 + 7.49092552E-05-3.36018317E-19-2.39324912E-04 0.00000000E+00-3.72729483E-05 + 6.73834721E-20 4.67950087E-04 0.00000000E+00 1.87250329E-03 0.00000000E+00 + 7.46625429E-05-1.02779359E-19 2.98654568E-04-6.77568961E-19 4.67961014E-04 + 0.00000000E+00-2.29107412E-04 0.00000000E+00 7.46623019E-05-1.98828385E-19 +-3.73928893E-05 1.33711675E-19 7.44292501E-05 1.66754529E-19 4.89349560E-04 + 0.00000000E+00 5.96363329E-04 8.45589705E-19 7.46625429E-05 1.02779359E-19 + 3.82861564E-03 0.00000000E+00 4.67950087E-04 0.00000000E+00 4.89349560E-04 + 0.00000000E+00 7.44292501E-05-1.66754529E-19 3.82861564E-03 0.00000000E+00 + 4.67950087E-04 0.00000000E+00 5.96363329E-04-8.45589705E-19 7.46625429E-05 +-1.02779359E-19-3.72729483E-05-6.73834721E-20-2.39324912E-04 0.00000000E+00 + 7.46625429E-05 1.02779359E-19 2.98654568E-04 6.77568961E-19 4.67950087E-04 + 0.00000000E+00 1.87250329E-03 0.00000000E+00 7.46623019E-05 1.98828385E-19 +-3.73928893E-05-1.33711675E-19 4.67961014E-04 0.00000000E+00-2.29107412E-04 + 0.00000000E+00 7.42094428E-05 2.85146593E-19 5.12927099E-04 0.00000000E+00 + 5.94552003E-04 2.36379438E-18 7.44294899E-05 2.58606043E-19 4.00838103E-03 + 0.00000000E+00 4.89336176E-04 0.00000000E+00-2.50565819E-04 0.00000000E+00 +-3.71597332E-05 1.35938159E-19 4.89336176E-04 0.00000000E+00 1.95815412E-03 + 0.00000000E+00 7.44294899E-05-2.58606043E-19 2.97722210E-04-8.36905908E-19 + 4.89349560E-04 0.00000000E+00-2.39324912E-04 0.00000000E+00 7.44292501E-05 +-1.66754529E-19-3.72729483E-05 6.73834721E-20-3.71597332E-05-1.35938159E-19 +-2.50565819E-04 0.00000000E+00 7.44294899E-05 2.58606043E-19 2.97722210E-04 + 8.36905908E-19 4.89336176E-04 0.00000000E+00 1.95815412E-03 0.00000000E+00 + 7.44292501E-05 1.66754529E-19-3.72729483E-05-6.73834721E-20 4.89349560E-04 + 0.00000000E+00-2.39324912E-04 0.00000000E+00 5.12927099E-04 0.00000000E+00 + 7.42094428E-05-2.85146593E-19 4.00838103E-03 0.00000000E+00 4.89336176E-04 + 0.00000000E+00 5.94552003E-04-2.36379438E-18 7.44294899E-05-2.58606043E-19 +-2.76779198E-04 0.00000000E+00-3.69526962E-05 2.74449154E-20 5.39016708E-04 + 0.00000000E+00 2.15716390E-03 0.00000000E+00 7.40027329E-05-8.82205679E-21 + 2.96014925E-04-1.70626753E-19 5.39037271E-04 0.00000000E+00-2.62986962E-04 + 0.00000000E+00 7.40024971E-05-2.08657907E-20-3.70530442E-05 6.54360816E-20 +-3.69526962E-05-2.74449154E-20-2.76779198E-04 0.00000000E+00 7.40027329E-05 + 8.82205679E-21 2.96014925E-04 1.70626753E-19 5.39016708E-04 0.00000000E+00 + 2.15716390E-03 0.00000000E+00 7.40024971E-05 2.08657907E-20-3.70530442E-05 +-6.54360816E-20 5.39037271E-04 0.00000000E+00-2.62986962E-04 0.00000000E+00 +-2.62986962E-04 0.00000000E+00-3.70530442E-05 6.54360816E-20 5.12910576E-04 + 0.00000000E+00 2.05258097E-03 0.00000000E+00 7.42096798E-05-2.40878536E-19 + 2.96842840E-04-9.63050978E-19 5.12927099E-04 0.00000000E+00-2.50565819E-04 + 0.00000000E+00 7.42094428E-05-2.85146593E-19-3.71597332E-05 1.35938159E-19 +-3.70530442E-05-6.54360816E-20-2.62986962E-04 0.00000000E+00 7.42096798E-05 + 2.40878536E-19 2.96842840E-04 9.63050978E-19 5.12910576E-04 0.00000000E+00 + 2.05258097E-03 0.00000000E+00 7.42094428E-05 2.85146593E-19-3.71597332E-05 +-1.35938159E-19 5.12927099E-04 0.00000000E+00-2.50565819E-04 0.00000000E+00 + 7.40024971E-05 2.08657907E-20 5.39037271E-04 0.00000000E+00 5.92845084E-04 + 1.00559325E-18 7.42096798E-05 2.40878536E-19 4.20701092E-03 0.00000000E+00 + 5.12910576E-04 0.00000000E+00 5.39037271E-04 0.00000000E+00 7.40024971E-05 +-2.08657907E-20 4.20701092E-03 0.00000000E+00 5.12910576E-04 0.00000000E+00 + 5.92845084E-04-1.00559325E-18 7.42096798E-05-2.40878536E-19 2.25394106E-05 + 0.00000000E+00-2.67589582E-06-4.89750120E-21 0.00000000E+00-1.37940565E-11 + 4.11689936E-08-1.31006298E-10 3.18864756E-08 0.00000000E+00-2.24899751E-05 + 0.00000000E+00-1.73927334E-06-2.10582022E-21 6.70278439E-08 1.73870336E-21 + 0.00000000E+00 5.77058951E-10 0.00000000E+00-1.49100624E-13-1.39177137E-05 + 1.92615125E-09 4.00360879E-08 1.01227467E-11-1.73927334E-06 2.10582022E-21 + 3.18864756E-08 0.00000000E+00-4.84969212E-07-4.38176119E-10 0.00000000E+00 +-5.65788654E-11-1.07277955E-06 2.78187155E-20 1.47116196E-06 4.84899322E-21 + 3.59826817E-04 0.00000000E+00 8.99280138E-05 0.00000000E+00-1.36530480E-04 +-7.36320070E-08 6.45113563E-07 3.97685132E-10 0.00000000E+00-1.10452945E-08 + 0.00000000E+00 5.71752679E-11 3.18864756E-08 0.00000000E+00-1.73927334E-06 +-2.10582022E-21 0.00000000E+00-5.65788654E-11 4.84969212E-07-4.38176119E-10 + 3.59826817E-04 0.00000000E+00 8.99280138E-05 0.00000000E+00-1.07277955E-06 +-2.78187155E-20 1.47116196E-06-4.84899322E-21 0.00000000E+00-1.10452945E-08 + 0.00000000E+00 5.71752679E-11 1.36530480E-04-7.36320070E-08-6.45113563E-07 + 3.97685132E-10 4.11689936E-08 1.31006298E-10 0.00000000E+00 1.37940565E-11 +-1.15557012E-07-7.81475425E-22 4.49393384E-05 0.00000000E+00 4.84969212E-07 + 4.38176119E-10 4.00360879E-08-1.01227467E-11 0.00000000E+00 5.65788654E-11 + 0.00000000E+00 1.49100624E-13-1.44067264E-05-8.14286976E-20 8.63877587E-08 + 5.10993374E-22 3.46175643E-03 0.00000000E+00-2.24751703E-05 0.00000000E+00 + 0.00000000E+00 1.37940565E-11-4.11689936E-08 1.31006298E-10 4.49393384E-05 + 0.00000000E+00-1.15557012E-07 7.81475425E-22 0.00000000E+00 5.65788654E-11 + 0.00000000E+00 1.49100624E-13-4.84969212E-07 4.38176119E-10-4.00360879E-08 +-1.01227467E-11 3.46175643E-03 0.00000000E+00-2.24751703E-05 0.00000000E+00 +-1.44067264E-05 8.14286976E-20 8.63877587E-08-5.10993374E-22-2.67589582E-06 + 4.89750120E-21 2.25394106E-05 0.00000000E+00-4.11689936E-08-1.31006298E-10 + 0.00000000E+00-1.37940565E-11-1.73927334E-06 2.10582022E-21 6.70278439E-08 +-1.73870336E-21 3.18864756E-08 0.00000000E+00-2.24899751E-05 0.00000000E+00 + 1.39177137E-05 1.92615125E-09-4.00360879E-08 1.01227467E-11 0.00000000E+00 + 5.77058951E-10 0.00000000E+00-1.49100624E-13 1.30904404E-06 3.02914454E-21 + 8.99321598E-05 0.00000000E+00-2.96877452E-04-4.28416442E-08-1.60613057E-06 +-2.13146761E-10 0.00000000E+00-1.12549393E-08 0.00000000E+00-5.84557828E-11 + 2.67330275E-05 7.35272761E-20 5.56528379E-06 1.74938089E-20 1.07918818E-03 + 0.00000000E+00 1.79864261E-04 0.00000000E+00-3.52400914E-04-3.55563601E-08 + 1.76635315E-06 1.92123858E-10 0.00000000E+00-1.12390890E-08 0.00000000E+00 + 5.84037915E-11-2.24899751E-05 0.00000000E+00 6.70278439E-08 1.73870336E-21 + 0.00000000E+00-1.49100624E-13 4.00360879E-08 1.01227467E-11 8.99280138E-05 + 0.00000000E+00 3.59732256E-04 0.00000000E+00 1.47116196E-06-4.84899322E-21 + 5.94746735E-06-2.00955888E-20 0.00000000E+00-1.23457263E-08 0.00000000E+00 +-8.04509373E-14 2.38364603E-04-6.17741630E-08 8.00779516E-08 1.53780889E-11 + 8.99321598E-05 0.00000000E+00-6.74491053E-05 0.00000000E+00 1.30904404E-06 +-3.02914454E-21-1.71858196E-06 5.13073835E-21 0.00000000E+00 5.59473200E-10 + 0.00000000E+00 1.29978248E-14-2.47149660E-05 8.84389392E-10 4.00556460E-08 + 5.25572555E-12 6.70278439E-08-1.73870336E-21-2.24899751E-05 0.00000000E+00 +-4.00360879E-08 1.01227467E-11 0.00000000E+00-1.49100624E-13 1.47116196E-06 + 4.84899322E-21 5.94746735E-06 2.00955888E-20 8.99280138E-05 0.00000000E+00 + 3.59732256E-04 0.00000000E+00-2.38364603E-04-6.17741630E-08-8.00779516E-08 + 1.53780889E-11 0.00000000E+00-1.23457263E-08 0.00000000E+00-8.04509373E-14 + 1.30904404E-06 3.02914454E-21-1.71858196E-06-5.13073835E-21 8.99321598E-05 + 0.00000000E+00-6.74491053E-05 0.00000000E+00 2.47149660E-05 8.84389392E-10 +-4.00556460E-08 5.25572555E-12 0.00000000E+00 5.59473200E-10 0.00000000E+00 + 1.29978248E-14 0.00000000E+00-5.77058951E-10 1.39177137E-05-1.92615125E-09 + 3.46175643E-03 0.00000000E+00-1.44067264E-05 8.14286976E-20 0.00000000E+00 + 1.10452945E-08 0.00000000E+00 1.23457263E-08-1.36530480E-04 7.36320070E-08 +-2.38364603E-04 6.17741630E-08 1.64791001E+00 0.00000000E+00-2.23105181E-03 + 0.00000000E+00-1.32736728E-02 3.53051191E-17 5.94060576E-08-9.25859891E-20 + 0.00000000E+00 1.12549393E-08 0.00000000E+00-5.64436733E-10-2.96877452E-04 + 4.28416442E-08 7.74947050E-06-3.11044660E-09 1.74331755E-01 0.00000000E+00 +-1.11767146E-03 0.00000000E+00-2.29416912E-03 1.06347697E-18 1.43448783E-05 +-7.24079001E-21 0.00000000E+00 1.49100624E-13-4.00360879E-08-1.01227467E-11 +-2.24751703E-05 0.00000000E+00 8.63877587E-08-5.10993374E-22 0.00000000E+00 +-5.71752679E-11 0.00000000E+00 8.04509373E-14 6.45113563E-07-3.97685132E-10 +-8.00779516E-08-1.53780889E-11-2.23105181E-03 0.00000000E+00 3.19448666E-05 + 0.00000000E+00 5.94060576E-08-9.25859891E-20-2.29647159E-07 6.57272771E-22 + 0.00000000E+00 5.84557828E-11 0.00000000E+00-1.29978248E-14-1.60613057E-06 + 2.13146761E-10-4.00556460E-08-5.25572555E-12 1.06108141E-03 0.00000000E+00 +-6.52091892E-06 0.00000000E+00-1.43428033E-05 5.81959875E-21 8.59673429E-08 +-3.75330692E-23-1.39177137E-05-1.92615125E-09 0.00000000E+00-5.77058951E-10 +-1.44067264E-05-8.14286976E-20 3.46175643E-03 0.00000000E+00 1.36530480E-04 + 7.36320070E-08 2.38364603E-04 6.17741630E-08 0.00000000E+00 1.10452945E-08 + 0.00000000E+00 1.23457263E-08-1.32736728E-02-3.53051191E-17 5.94060576E-08 + 9.25859891E-20 1.64791001E+00 0.00000000E+00-2.23105181E-03 0.00000000E+00 + 2.96877452E-04 4.28416442E-08-7.74947050E-06-3.11044660E-09 0.00000000E+00 + 1.12549393E-08 0.00000000E+00-5.64436733E-10-2.29416912E-03-1.06347697E-18 + 1.43448783E-05 7.24079001E-21 1.74331755E-01 0.00000000E+00-1.11767146E-03 + 0.00000000E+00 4.00360879E-08-1.01227467E-11 0.00000000E+00 1.49100624E-13 + 8.63877587E-08 5.10993374E-22-2.24751703E-05 0.00000000E+00-6.45113563E-07 +-3.97685132E-10 8.00779516E-08-1.53780889E-11 0.00000000E+00-5.71752679E-11 + 0.00000000E+00 8.04509373E-14 5.94060576E-08 9.25859891E-20-2.29647159E-07 +-6.57272771E-22-2.23105181E-03 0.00000000E+00 3.19448666E-05 0.00000000E+00 + 1.60613057E-06 2.13146761E-10 4.00556460E-08-5.25572555E-12 0.00000000E+00 + 5.84557828E-11 0.00000000E+00-1.29978248E-14-1.43428033E-05-5.81959875E-21 + 8.59673429E-08 3.75330692E-23 1.06108141E-03 0.00000000E+00-6.52091892E-06 + 0.00000000E+00 8.99321598E-05 0.00000000E+00 1.30904404E-06-3.02914454E-21 + 0.00000000E+00-1.12549393E-08 0.00000000E+00-5.84557828E-11 2.96877452E-04 +-4.28416442E-08 1.60613057E-06-2.13146761E-10 1.07918818E-03 0.00000000E+00 + 1.79864261E-04 0.00000000E+00 2.67330275E-05-7.35272761E-20 5.56528379E-06 +-1.74938089E-20 0.00000000E+00-1.12390890E-08 0.00000000E+00 5.84037915E-11 + 3.52400914E-04-3.55563601E-08-1.76635315E-06 1.92123858E-10 5.56565485E-06 + 2.29650515E-20 1.79863913E-04 0.00000000E+00-5.12877382E-04-2.34839158E-08 +-2.72813795E-06-1.19277363E-10 0.00000000E+00-1.12045574E-08 0.00000000E+00 +-5.82021977E-11 7.26660368E-05 2.44747131E-19 1.28088842E-05 3.38942009E-20 + 1.79859350E-03 0.00000000E+00 2.69783831E-04 0.00000000E+00-5.68458816E-04 +-2.14969501E-08 2.88852736E-06 1.13653296E-10 0.00000000E+00-1.12099721E-08 + 0.00000000E+00 5.82194154E-11-6.74491053E-05 0.00000000E+00-1.71858196E-06 + 5.13073835E-21 0.00000000E+00 5.64436733E-10 0.00000000E+00 1.29978248E-14 +-7.74947050E-06 3.11044660E-09 4.00556460E-08 5.25572555E-12 1.79864261E-04 + 0.00000000E+00 7.19451870E-04 0.00000000E+00 5.56528379E-06-1.74938089E-20 + 2.33281703E-05-7.93754566E-20 0.00000000E+00-1.23308054E-08 0.00000000E+00 + 2.28271294E-14 4.75883551E-04-3.05923725E-08 8.01437247E-08 5.53767826E-12 + 1.79863913E-04 0.00000000E+00-1.12411936E-04 0.00000000E+00 5.56565485E-06 +-2.29650515E-20-4.59363476E-06 1.42148131E-20 0.00000000E+00 5.61285266E-10 + 0.00000000E+00-4.30441273E-15-3.55254014E-05 8.35669366E-10 4.00973523E-08 + 1.40601695E-12 4.00556460E-08-5.25572555E-12 0.00000000E+00-1.29978248E-14 + 1.43448783E-05 7.24079001E-21 8.59673429E-08 3.75330692E-23-1.11767146E-03 + 0.00000000E+00-6.52091892E-06 0.00000000E+00-1.76635315E-06-1.92123858E-10 + 8.01437247E-08-5.53767826E-12 0.00000000E+00-5.84037915E-11 0.00000000E+00 +-2.28271294E-14 2.87743409E-08-7.20469794E-20-2.29031915E-07-4.59228377E-22 +-4.54185892E-04 0.00000000E+00 1.34401670E-05 0.00000000E+00 2.72813795E-06 + 1.19277363E-10 4.00973523E-08-1.40601695E-12 0.00000000E+00 5.82021977E-11 + 0.00000000E+00 4.30441273E-15-1.43150613E-05-5.94791759E-20 8.58024019E-08 + 3.49521727E-22 6.38464092E-04 0.00000000E+00-3.88461866E-06 0.00000000E+00 +-2.47149660E-05-8.84389392E-10 0.00000000E+00-5.59473200E-10-2.29416912E-03 +-1.06347697E-18-1.43428033E-05-5.81959875E-21 1.74331755E-01 0.00000000E+00 + 1.06108141E-03 0.00000000E+00 3.52400914E-04 3.55563601E-08 4.75883551E-04 + 3.05923725E-08 0.00000000E+00 1.12390890E-08 0.00000000E+00 1.23308054E-08 +-1.32430655E-02-2.34874761E-17 2.87743409E-08-7.20469794E-20 7.60152437E-01 + 0.00000000E+00-4.54185892E-04 0.00000000E+00 5.12877382E-04 2.34839158E-08 +-1.85421922E-05-1.44068655E-09 0.00000000E+00 1.12045574E-08 0.00000000E+00 +-5.59600115E-10-2.28977138E-03-9.25994732E-18 1.43175806E-05 5.65726722E-20 + 1.03730500E-01 0.00000000E+00-6.58398978E-04 0.00000000E+00 0.00000000E+00 +-1.29978248E-14-4.00556460E-08-5.25572555E-12-1.11767146E-03 0.00000000E+00 +-6.52091892E-06 0.00000000E+00 1.43448783E-05-7.24079001E-21 8.59673429E-08 +-3.75330692E-23 0.00000000E+00-5.84037915E-11 0.00000000E+00-2.28271294E-14 + 1.76635315E-06-1.92123858E-10-8.01437247E-08-5.53767826E-12-4.54185892E-04 + 0.00000000E+00 1.34401670E-05 0.00000000E+00 2.87743409E-08 7.20469794E-20 +-2.29031915E-07 4.59228377E-22 0.00000000E+00 5.82021977E-11 0.00000000E+00 + 4.30441273E-15-2.72813795E-06 1.19277363E-10-4.00973523E-08-1.40601695E-12 + 6.38464092E-04 0.00000000E+00-3.88461866E-06 0.00000000E+00-1.43150613E-05 + 5.94791759E-20 8.58024019E-08-3.49521727E-22 0.00000000E+00-5.59473200E-10 + 2.47149660E-05-8.84389392E-10 1.74331755E-01 0.00000000E+00 1.06108141E-03 + 0.00000000E+00-2.29416912E-03 1.06347697E-18-1.43428033E-05 5.81959875E-21 + 0.00000000E+00 1.12390890E-08 0.00000000E+00 1.23308054E-08-3.52400914E-04 + 3.55563601E-08-4.75883551E-04 3.05923725E-08 7.60152437E-01 0.00000000E+00 +-4.54185892E-04 0.00000000E+00-1.32430655E-02 2.34874761E-17 2.87743409E-08 + 7.20469794E-20 0.00000000E+00 1.12045574E-08 0.00000000E+00-5.59600115E-10 +-5.12877382E-04 2.34839158E-08 1.85421922E-05-1.44068655E-09 1.03730500E-01 + 0.00000000E+00-6.58398978E-04 0.00000000E+00-2.28977138E-03 9.25994732E-18 + 1.43175806E-05-5.65726722E-20-1.71858196E-06-5.13073835E-21-6.74491053E-05 + 0.00000000E+00 7.74947050E-06 3.11044660E-09-4.00556460E-08 5.25572555E-12 + 0.00000000E+00 5.64436733E-10 0.00000000E+00 1.29978248E-14 5.56528379E-06 + 1.74938089E-20 2.33281703E-05 7.93754566E-20 1.79864261E-04 0.00000000E+00 + 7.19451870E-04 0.00000000E+00-4.75883551E-04-3.05923725E-08-8.01437247E-08 + 5.53767826E-12 0.00000000E+00-1.23308054E-08 0.00000000E+00 2.28271294E-14 + 5.56565485E-06 2.29650515E-20-4.59363476E-06-1.42148131E-20 1.79863913E-04 + 0.00000000E+00-1.12411936E-04 0.00000000E+00 3.55254014E-05 8.35669366E-10 +-4.00973523E-08 1.40601695E-12 0.00000000E+00 5.61285266E-10 0.00000000E+00 +-4.30441273E-15 1.79863913E-04 0.00000000E+00 5.56565485E-06-2.29650515E-20 + 0.00000000E+00-1.12045574E-08 0.00000000E+00-5.82021977E-11 5.12877382E-04 +-2.34839158E-08 2.72813795E-06-1.19277363E-10 1.79859350E-03 0.00000000E+00 + 2.69783831E-04 0.00000000E+00 7.26660368E-05-2.44747131E-19 1.28088842E-05 +-3.38942009E-20 0.00000000E+00-1.12099721E-08 0.00000000E+00 5.82194154E-11 + 5.68458816E-04-2.14969501E-08-2.88852736E-06 1.13653296E-10 1.28085178E-05 + 2.73625613E-20 2.69783796E-04 0.00000000E+00-7.29077597E-04-1.73982443E-08 +-3.85112643E-06-8.89642472E-11 0.00000000E+00-1.12192998E-08 0.00000000E+00 +-5.82738132E-11 1.42103194E-04 1.39044929E-19 2.29234356E-05 1.03804859E-20 + 2.51791576E-03 0.00000000E+00 3.59694243E-04 0.00000000E+00-7.84639382E-04 +-1.62527509E-08 4.01146490E-06 8.56509434E-11 0.00000000E+00-1.12169175E-08 + 0.00000000E+00 5.82667048E-11-1.12411936E-04 0.00000000E+00-4.59363476E-06 + 1.42148131E-20 0.00000000E+00 5.59600115E-10 0.00000000E+00-4.30441273E-15 +-1.85421922E-05 1.44068655E-09 4.00973523E-08 1.40601695E-12 2.69783831E-04 + 0.00000000E+00 1.07913188E-03 0.00000000E+00 1.28088842E-05-3.38942009E-20 + 5.22604536E-05-1.12664940E-19 0.00000000E+00-1.23399491E-08 0.00000000E+00 +-5.94873314E-15 7.13647459E-04-2.11857251E-08 8.02462213E-08 1.92320131E-12 + 2.69783796E-04 0.00000000E+00-1.57369510E-04 0.00000000E+00 1.28085178E-05 +-2.73625613E-20-8.93298836E-06 9.43576181E-21 0.00000000E+00 5.60491634E-10 + 0.00000000E+00 1.77710210E-15-4.63305669E-05 6.69554903E-10 4.00846181E-08 + 8.28325962E-13 4.00973523E-08-1.40601695E-12 0.00000000E+00 4.30441273E-15 + 1.43175806E-05 5.65726722E-20 8.58024019E-08 3.49521727E-22-6.58398978E-04 + 0.00000000E+00-3.88461866E-06 0.00000000E+00-2.88852736E-06-1.13653296E-10 + 8.02462213E-08-1.92320131E-12 0.00000000E+00-5.82194154E-11 0.00000000E+00 + 5.94873314E-15 4.63975999E-08 7.54135274E-20-2.28481579E-07-5.94446546E-22 +-1.95715777E-04 0.00000000E+00 8.76228911E-06 0.00000000E+00 3.85112643E-06 + 8.89642472E-11 4.00846181E-08-8.28325962E-13 0.00000000E+00 5.82738132E-11 + 0.00000000E+00-1.77710210E-15-1.42715375E-05-4.04650056E-21 8.55455758E-08 + 3.29828935E-23 4.58192075E-04 0.00000000E+00-2.77573680E-06 0.00000000E+00 +-3.55254014E-05-8.35669366E-10 0.00000000E+00-5.61285266E-10-2.28977138E-03 +-9.25994732E-18-1.43150613E-05-5.94791759E-20 1.03730500E-01 0.00000000E+00 + 6.38464092E-04 0.00000000E+00 5.68458816E-04 2.14969501E-08 7.13647459E-04 + 2.11857251E-08 0.00000000E+00 1.12099721E-08 0.00000000E+00 1.23399491E-08 +-1.32118254E-02-3.86618193E-17 4.63975999E-08 7.54135274E-20 5.01879160E-01 + 0.00000000E+00-1.95715777E-04 0.00000000E+00 7.29077597E-04 1.73982443E-08 +-2.93532413E-05-1.01971688E-09 0.00000000E+00 1.12192998E-08 0.00000000E+00 +-5.61224041E-10-2.28293252E-03-9.53435983E-19 1.42754972E-05 7.59402659E-21 + 7.40981060E-02 0.00000000E+00-4.68283605E-04 0.00000000E+00 0.00000000E+00 + 4.30441273E-15-4.00973523E-08-1.40601695E-12-6.58398978E-04 0.00000000E+00 +-3.88461866E-06 0.00000000E+00 1.43175806E-05-5.65726722E-20 8.58024019E-08 +-3.49521727E-22 0.00000000E+00-5.82194154E-11 0.00000000E+00 5.94873314E-15 + 2.88852736E-06-1.13653296E-10-8.02462213E-08-1.92320131E-12-1.95715777E-04 + 0.00000000E+00 8.76228911E-06 0.00000000E+00 4.63975999E-08-7.54135274E-20 +-2.28481579E-07 5.94446546E-22 0.00000000E+00 5.82738132E-11 0.00000000E+00 +-1.77710210E-15-3.85112643E-06 8.89642472E-11-4.00846181E-08-8.28325962E-13 + 4.58192075E-04 0.00000000E+00-2.77573680E-06 0.00000000E+00-1.42715375E-05 + 4.04650056E-21 8.55455758E-08-3.29828935E-23 0.00000000E+00-5.61285266E-10 + 3.55254014E-05-8.35669366E-10 1.03730500E-01 0.00000000E+00 6.38464092E-04 + 0.00000000E+00-2.28977138E-03 9.25994732E-18-1.43150613E-05 5.94791759E-20 + 0.00000000E+00 1.12099721E-08 0.00000000E+00 1.23399491E-08-5.68458816E-04 + 2.14969501E-08-7.13647459E-04 2.11857251E-08 5.01879160E-01 0.00000000E+00 +-1.95715777E-04 0.00000000E+00-1.32118254E-02 3.86618193E-17 4.63975999E-08 +-7.54135274E-20 0.00000000E+00 1.12192998E-08 0.00000000E+00-5.61224041E-10 +-7.29077597E-04 1.73982443E-08 2.93532413E-05-1.01971688E-09 7.40981060E-02 + 0.00000000E+00-4.68283605E-04 0.00000000E+00-2.28293252E-03 9.53435983E-19 + 1.42754972E-05-7.59402659E-21-4.59363476E-06-1.42148131E-20-1.12411936E-04 + 0.00000000E+00 1.85421922E-05 1.44068655E-09-4.00973523E-08 1.40601695E-12 + 0.00000000E+00 5.59600115E-10 0.00000000E+00-4.30441273E-15 1.28088842E-05 + 3.38942009E-20 5.22604536E-05 1.12664940E-19 2.69783831E-04 0.00000000E+00 + 1.07913188E-03 0.00000000E+00-7.13647459E-04-2.11857251E-08-8.02462213E-08 + 1.92320131E-12 0.00000000E+00-1.23399491E-08 0.00000000E+00-5.94873314E-15 + 1.28085178E-05 2.73625613E-20-8.93298836E-06-9.43576181E-21 2.69783796E-04 + 0.00000000E+00-1.57369510E-04 0.00000000E+00 4.63305669E-05 6.69554903E-10 +-4.00846181E-08 8.28325962E-13 0.00000000E+00 5.60491634E-10 0.00000000E+00 + 1.77710210E-15 2.69783796E-04 0.00000000E+00 1.28085178E-05-2.73625613E-20 + 0.00000000E+00-1.12192998E-08 0.00000000E+00-5.82738132E-11 7.29077597E-04 +-1.73982443E-08 3.85112643E-06-8.89642472E-11 2.51791576E-03 0.00000000E+00 + 3.59694243E-04 0.00000000E+00 1.42103194E-04-1.39044929E-19 2.29234356E-05 +-1.03804859E-20 0.00000000E+00-1.12169175E-08 0.00000000E+00 5.82667048E-11 + 7.84639382E-04-1.62527509E-08-4.01146490E-06 8.56509434E-11 2.29238722E-05 + 9.87779310E-21 3.59693602E-04 0.00000000E+00-9.44815294E-04-1.38354753E-08 +-4.97144205E-06-7.11176290E-11 0.00000000E+00-1.12096143E-08 0.00000000E+00 +-5.82271351E-11 2.34586808E-04 2.47024411E-19 3.59289123E-05 5.64661482E-20 + 3.23713832E-03 0.00000000E+00 4.49589946E-04 0.00000000E+00-1.00015628E-03 +-1.32291835E-08 5.13113463E-06 6.93769384E-11 0.00000000E+00-1.12148576E-08 + 0.00000000E+00 5.82418876E-11-1.57369510E-04 0.00000000E+00-8.93298836E-06 + 9.43576181E-21 0.00000000E+00 5.61224041E-10 0.00000000E+00 1.77710210E-15 +-2.93532413E-05 1.01971688E-09 4.00846181E-08 8.28325962E-13 3.59694243E-04 + 0.00000000E+00 1.43877075E-03 0.00000000E+00 2.29234356E-05-1.03804859E-20 + 9.27268509E-05-6.32930871E-20 0.00000000E+00-1.23322150E-08 0.00000000E+00 + 8.06359294E-15 9.51279658E-04-1.63560626E-08 7.99854936E-08 1.16169643E-12 + 3.59693602E-04 0.00000000E+00-2.02320887E-04 0.00000000E+00 2.29238722E-05 +-9.87779310E-21-1.47131961E-05 1.65859853E-20 0.00000000E+00 5.61556897E-10 + 0.00000000E+00-3.68814693E-15-5.70782032E-05 5.85692579E-10 3.99231467E-08 + 4.35172656E-13 4.00846181E-08-8.28325962E-13 0.00000000E+00-1.77710210E-15 + 1.42754972E-05 7.59402659E-21 8.55455758E-08 3.29828935E-23-4.68283605E-04 + 0.00000000E+00-2.77573680E-06 0.00000000E+00-4.01146490E-06-8.56509434E-11 + 7.99854936E-08-1.16169643E-12 0.00000000E+00-5.82667048E-11 0.00000000E+00 +-8.06359294E-15 6.25922200E-08-7.84850769E-20-2.27669122E-07-4.27734956E-22 +-1.08700169E-04 0.00000000E+00 6.53879903E-06 0.00000000E+00 4.97144205E-06 + 7.11176290E-11 3.99231467E-08-4.35172656E-13 0.00000000E+00 5.82271351E-11 + 0.00000000E+00 3.68814693E-15-1.42128733E-05-6.35609445E-20 8.51968569E-08 + 3.68100247E-22 3.58206885E-04 0.00000000E+00-2.16474619E-06 0.00000000E+00 +-4.63305669E-05-6.69554903E-10 0.00000000E+00-5.60491634E-10-2.28293252E-03 +-9.53435983E-19-1.42715375E-05-4.04650056E-21 7.40981060E-02 0.00000000E+00 + 4.58192075E-04 0.00000000E+00 7.84639382E-04 1.62527509E-08 9.51279658E-04 + 1.63560626E-08 0.00000000E+00 1.12169175E-08 0.00000000E+00 1.23322150E-08 +-1.31646922E-02-1.97281930E-17 6.25922200E-08-7.84850769E-20 3.76105923E-01 + 0.00000000E+00-1.08700169E-04 0.00000000E+00 9.44815294E-04 1.38354753E-08 +-4.01685043E-05-7.70777887E-10 0.00000000E+00 1.12096143E-08 0.00000000E+00 +-5.59962054E-10-2.27363948E-03-9.76309193E-18 1.42178734E-05 5.87539710E-20 + 5.77810279E-02 0.00000000E+00-3.64275454E-04 0.00000000E+00 0.00000000E+00 +-1.77710210E-15-4.00846181E-08-8.28325962E-13-4.68283605E-04 0.00000000E+00 +-2.77573680E-06 0.00000000E+00 1.42754972E-05-7.59402659E-21 8.55455758E-08 +-3.29828935E-23 0.00000000E+00-5.82667048E-11 0.00000000E+00-8.06359294E-15 + 4.01146490E-06-8.56509434E-11-7.99854936E-08-1.16169643E-12-1.08700169E-04 + 0.00000000E+00 6.53879903E-06 0.00000000E+00 6.25922200E-08 7.84850769E-20 +-2.27669122E-07 4.27734956E-22 0.00000000E+00 5.82271351E-11 0.00000000E+00 + 3.68814693E-15-4.97144205E-06 7.11176290E-11-3.99231467E-08-4.35172656E-13 + 3.58206885E-04 0.00000000E+00-2.16474619E-06 0.00000000E+00-1.42128733E-05 + 6.35609445E-20 8.51968569E-08-3.68100247E-22 0.00000000E+00-5.60491634E-10 + 4.63305669E-05-6.69554903E-10 7.40981060E-02 0.00000000E+00 4.58192075E-04 + 0.00000000E+00-2.28293252E-03 9.53435983E-19-1.42715375E-05 4.04650056E-21 + 0.00000000E+00 1.12169175E-08 0.00000000E+00 1.23322150E-08-7.84639382E-04 + 1.62527509E-08-9.51279658E-04 1.63560626E-08 3.76105923E-01 0.00000000E+00 +-1.08700169E-04 0.00000000E+00-1.31646922E-02 1.97281930E-17 6.25922200E-08 + 7.84850769E-20 0.00000000E+00 1.12096143E-08 0.00000000E+00-5.59962054E-10 +-9.44815294E-04 1.38354753E-08 4.01685043E-05-7.70777887E-10 5.77810279E-02 + 0.00000000E+00-3.64275454E-04 0.00000000E+00-2.27363948E-03 9.76309193E-18 + 1.42178734E-05-5.87539710E-20-8.93298836E-06-9.43576181E-21-1.57369510E-04 + 0.00000000E+00 2.93532413E-05 1.01971688E-09-4.00846181E-08 8.28325962E-13 + 0.00000000E+00 5.61224041E-10 0.00000000E+00 1.77710210E-15 2.29234356E-05 + 1.03804859E-20 9.27268509E-05 6.32930871E-20 3.59694243E-04 0.00000000E+00 + 1.43877075E-03 0.00000000E+00-9.51279658E-04-1.63560626E-08-7.99854936E-08 + 1.16169643E-12 0.00000000E+00-1.23322150E-08 0.00000000E+00 8.06359294E-15 + 2.29238722E-05 9.87779310E-21-1.47131961E-05-1.65859853E-20 3.59693602E-04 + 0.00000000E+00-2.02320887E-04 0.00000000E+00 5.70782032E-05 5.85692579E-10 +-3.99231467E-08 4.35172656E-13 0.00000000E+00 5.61556897E-10 0.00000000E+00 +-3.68814693E-15 3.59693602E-04 0.00000000E+00 2.29238722E-05-9.87779310E-21 + 0.00000000E+00-1.12096143E-08 0.00000000E+00-5.82271351E-11 9.44815294E-04 +-1.38354753E-08 4.97144205E-06-7.11176290E-11 3.23713832E-03 0.00000000E+00 + 4.49589946E-04 0.00000000E+00 2.34586808E-04-2.47024411E-19 3.59289123E-05 +-5.64661482E-20 0.00000000E+00-1.12148576E-08 0.00000000E+00 5.82418876E-11 + 1.00015628E-03-1.32291835E-08-5.13113463E-06 6.93769384E-11 3.59289115E-05 + 5.94731204E-20 4.49589088E-04 0.00000000E+00-1.15981939E-03-1.18047173E-08 +-6.08802784E-06-6.08490869E-11 0.00000000E+00-1.12333206E-08 0.00000000E+00 +-5.83340138E-11 3.50159574E-04 8.14902151E-19 5.18169310E-05 1.45366357E-19 + 3.95623235E-03 0.00000000E+00 5.39467669E-04 0.00000000E+00-1.21502239E-03 +-1.14356413E-08 6.24732475E-06 5.97827293E-11 0.00000000E+00-1.12082093E-08 + 0.00000000E+00 5.82634973E-11-2.02320887E-04 0.00000000E+00-1.47131961E-05 + 1.65859853E-20 0.00000000E+00 5.59962054E-10 0.00000000E+00-3.68814693E-15 +-4.01685043E-05 7.70777887E-10 3.99231467E-08 4.35172656E-13 4.49589946E-04 + 0.00000000E+00 1.79835190E-03 0.00000000E+00 3.59289123E-05-5.64661482E-20 + 1.44745330E-04-2.45879363E-19 0.00000000E+00-1.23554119E-08 0.00000000E+00 +-2.75330935E-14 1.18803225E-03-1.36932881E-08 7.97327741E-08 7.21038593E-13 + 4.49589088E-04 0.00000000E+00-2.47264189E-04 0.00000000E+00 3.59289115E-05 +-5.94731204E-20-2.19364606E-05 5.12098693E-20 0.00000000E+00 5.56593668E-10 + 0.00000000E+00 1.76291254E-14-6.78040978E-05 5.26195525E-10 3.98242299E-08 + 2.66589418E-13 3.99231467E-08-4.35172656E-13 0.00000000E+00 3.68814693E-15 + 1.42178734E-05 5.87539710E-20 8.51968569E-08 3.68100247E-22-3.64275454E-04 + 0.00000000E+00-2.16474619E-06 0.00000000E+00-5.13113463E-06-6.93769384E-11 + 7.97327741E-08-7.21038593E-13 0.00000000E+00-5.82418876E-11 0.00000000E+00 + 2.75330935E-14 7.83112096E-08 4.05489964E-20-2.26624779E-07-8.82760381E-22 +-6.89716507E-05 0.00000000E+00 5.23308808E-06 0.00000000E+00 6.08802784E-06 + 6.08490869E-11 3.98242299E-08-2.66589418E-13 0.00000000E+00 5.83340138E-11 + 0.00000000E+00-1.76291254E-14-1.41396712E-05-3.47038974E-20 8.47613096E-08 + 2.17106647E-22 2.94748908E-04 0.00000000E+00-1.77846133E-06 0.00000000E+00 +-5.70782032E-05-5.85692579E-10 0.00000000E+00-5.61556897E-10-2.27363948E-03 +-9.76309193E-18-1.42128733E-05-6.35609445E-20 5.77810279E-02 0.00000000E+00 + 3.58206885E-04 0.00000000E+00 1.00015628E-03 1.32291835E-08 1.18803225E-03 + 1.36932881E-08 0.00000000E+00 1.12148576E-08 0.00000000E+00 1.23554119E-08 +-1.31044475E-02-5.55521453E-17 7.83112096E-08 4.05489964E-20 3.01582648E-01 + 0.00000000E+00-6.89716507E-05 0.00000000E+00 1.15981939E-03 1.18047173E-08 +-5.09365019E-05-6.38994441E-10 0.00000000E+00 1.12333206E-08 0.00000000E+00 +-5.64229096E-10-2.26202967E-03-5.82661399E-18 1.41458160E-05 3.80291090E-20 + 4.74677487E-02 0.00000000E+00-2.98787710E-04 0.00000000E+00 0.00000000E+00 + 3.68814693E-15-3.99231467E-08-4.35172656E-13-3.64275454E-04 0.00000000E+00 +-2.16474619E-06 0.00000000E+00 1.42178734E-05-5.87539710E-20 8.51968569E-08 +-3.68100247E-22 0.00000000E+00-5.82418876E-11 0.00000000E+00 2.75330935E-14 + 5.13113463E-06-6.93769384E-11-7.97327741E-08-7.21038593E-13-6.89716507E-05 + 0.00000000E+00 5.23308808E-06 0.00000000E+00 7.83112096E-08-4.05489964E-20 +-2.26624779E-07 8.82760381E-22 0.00000000E+00 5.83340138E-11 0.00000000E+00 +-1.76291254E-14-6.08802784E-06 6.08490869E-11-3.98242299E-08-2.66589418E-13 + 2.94748908E-04 0.00000000E+00-1.77846133E-06 0.00000000E+00-1.41396712E-05 + 3.47038974E-20 8.47613096E-08-2.17106647E-22 0.00000000E+00-5.61556897E-10 + 5.70782032E-05-5.85692579E-10 5.77810279E-02 0.00000000E+00 3.58206885E-04 + 0.00000000E+00-2.27363948E-03 9.76309193E-18-1.42128733E-05 6.35609445E-20 + 0.00000000E+00 1.12148576E-08 0.00000000E+00 1.23554119E-08-1.00015628E-03 + 1.32291835E-08-1.18803225E-03 1.36932881E-08 3.01582648E-01 0.00000000E+00 +-6.89716507E-05 0.00000000E+00-1.31044475E-02 5.55521453E-17 7.83112096E-08 +-4.05489964E-20 0.00000000E+00 1.12333206E-08 0.00000000E+00-5.64229096E-10 +-1.15981939E-03 1.18047173E-08 5.09365019E-05-6.38994441E-10 4.74677487E-02 + 0.00000000E+00-2.98787710E-04 0.00000000E+00-2.26202967E-03 5.82661399E-18 + 1.41458160E-05-3.80291090E-20-1.47131961E-05-1.65859853E-20-2.02320887E-04 + 0.00000000E+00 4.01685043E-05 7.70777887E-10-3.99231467E-08 4.35172656E-13 + 0.00000000E+00 5.59962054E-10 0.00000000E+00-3.68814693E-15 3.59289123E-05 + 5.64661482E-20 1.44745330E-04 2.45879363E-19 4.49589946E-04 0.00000000E+00 + 1.79835190E-03 0.00000000E+00-1.18803225E-03-1.36932881E-08-7.97327741E-08 + 7.21038593E-13 0.00000000E+00-1.23554119E-08 0.00000000E+00-2.75330935E-14 + 3.59289115E-05 5.94731204E-20-2.19364606E-05-5.12098693E-20 4.49589088E-04 + 0.00000000E+00-2.47264189E-04 0.00000000E+00 6.78040978E-05 5.26195525E-10 +-3.98242299E-08 2.66589418E-13 0.00000000E+00 5.56593668E-10 0.00000000E+00 + 1.76291254E-14 4.49589088E-04 0.00000000E+00 3.59289115E-05-5.94731204E-20 + 0.00000000E+00-1.12333206E-08 0.00000000E+00-5.83340138E-11 1.15981939E-03 +-1.18047173E-08 6.08802784E-06-6.08490869E-11 3.95623235E-03 0.00000000E+00 + 5.39467669E-04 0.00000000E+00 3.50159574E-04-8.14902151E-19 5.18169310E-05 +-1.45366357E-19 0.00000000E+00-1.12082093E-08 0.00000000E+00 5.82634973E-11 + 1.21502239E-03-1.14356413E-08-6.24732475E-06 5.97827293E-11 5.18171855E-05 + 1.38518998E-19 5.39466318E-04 0.00000000E+00-1.37423943E-03-1.07303302E-08 +-7.20151326E-06-5.55260596E-11 0.00000000E+00-1.09977496E-08 0.00000000E+00 +-5.70231916E-11 4.88787193E-04 1.69393974E-18 7.05851338E-05 2.91841201E-19 + 4.67516665E-03 0.00000000E+00 6.29323843E-04 0.00000000E+00-1.42922544E-03 +-1.05590888E-08 7.36018397E-06 5.50352531E-11 0.00000000E+00-1.09138770E-08 + 0.00000000E+00 5.67788812E-11-2.47264189E-04 0.00000000E+00-2.19364606E-05 + 5.12098693E-20 0.00000000E+00 5.64229096E-10 0.00000000E+00 1.76291254E-14 +-5.09365019E-05 6.38994441E-10 3.98242299E-08 2.66589418E-13 5.39467669E-04 + 0.00000000E+00 2.15786065E-03 0.00000000E+00 5.18169310E-05-1.45366357E-19 + 2.08296867E-04-5.92292709E-19 0.00000000E+00-1.22350029E-08 0.00000000E+00 + 1.26358035E-13 1.42416705E-03-1.21222211E-08 7.95339982E-08 3.22912241E-13 + 5.39466318E-04 0.00000000E+00-2.92197540E-04 0.00000000E+00 5.18171855E-05 +-1.38518998E-19-3.06005798E-05 1.07590050E-19 0.00000000E+00 5.35149983E-10 + 0.00000000E+00 6.10776156E-14-7.84855684E-05 5.06472648E-10 3.96676761E-08 + 1.22701640E-13 3.98242299E-08-2.66589418E-13 0.00000000E+00-1.76291254E-14 + 1.41458160E-05 3.80291090E-20 8.47613096E-08 2.17106647E-22-2.98787710E-04 + 0.00000000E+00-1.77846133E-06 0.00000000E+00-6.24732475E-06-5.97827293E-11 + 7.95339982E-08-3.22912241E-13 0.00000000E+00-5.82634973E-11 0.00000000E+00 +-1.26358035E-13 9.39403809E-08-1.09797825E-20-2.25346559E-07-5.52379779E-22 +-4.75331521E-05 0.00000000E+00 4.37419872E-06 0.00000000E+00 7.20151326E-06 + 5.55260596E-11 3.96676761E-08-1.22701640E-13 0.00000000E+00 5.70231916E-11 + 0.00000000E+00-6.10776156E-14-1.40518696E-05-3.97817735E-20 8.42382641E-08 + 2.36371326E-22 2.50989215E-04 0.00000000E+00-1.51275971E-06 0.00000000E+00 +-6.78040978E-05-5.26195525E-10 0.00000000E+00-5.56593668E-10-2.26202967E-03 +-5.82661399E-18-1.41396712E-05-3.47038974E-20 4.74677487E-02 0.00000000E+00 + 2.94748908E-04 0.00000000E+00 1.21502239E-03 1.14356413E-08 1.42416705E-03 + 1.21222211E-08 0.00000000E+00 1.12082093E-08 0.00000000E+00 1.22350029E-08 +-1.30306099E-02-2.97077759E-17 9.39403809E-08-1.09797825E-20 2.52347067E-01 + 0.00000000E+00-4.75331521E-05 0.00000000E+00 1.37423943E-03 1.07303302E-08 +-6.16842667E-05-5.58732199E-10 0.00000000E+00 1.09977496E-08 0.00000000E+00 +-5.60821695E-10-2.24808402E-03-6.29091561E-18 1.40591529E-05 3.89486588E-20 + 4.03749001E-02 0.00000000E+00-2.53862408E-04 0.00000000E+00 0.00000000E+00 +-1.76291254E-14-3.98242299E-08-2.66589418E-13-2.98787710E-04 0.00000000E+00 +-1.77846133E-06 0.00000000E+00 1.41458160E-05-3.80291090E-20 8.47613096E-08 +-2.17106647E-22 0.00000000E+00-5.82634973E-11 0.00000000E+00-1.26358035E-13 + 6.24732475E-06-5.97827293E-11-7.95339982E-08-3.22912241E-13-4.75331521E-05 + 0.00000000E+00 4.37419872E-06 0.00000000E+00 9.39403809E-08 1.09797825E-20 +-2.25346559E-07 5.52379779E-22 0.00000000E+00 5.70231916E-11 0.00000000E+00 +-6.10776156E-14-7.20151326E-06 5.55260596E-11-3.96676761E-08-1.22701640E-13 + 2.50989215E-04 0.00000000E+00-1.51275971E-06 0.00000000E+00-1.40518696E-05 + 3.97817735E-20 8.42382641E-08-2.36371326E-22 0.00000000E+00-5.56593668E-10 + 6.78040978E-05-5.26195525E-10 4.74677487E-02 0.00000000E+00 2.94748908E-04 + 0.00000000E+00-2.26202967E-03 5.82661399E-18-1.41396712E-05 3.47038974E-20 + 0.00000000E+00 1.12082093E-08 0.00000000E+00 1.22350029E-08-1.21502239E-03 + 1.14356413E-08-1.42416705E-03 1.21222211E-08 2.52347067E-01 0.00000000E+00 +-4.75331521E-05 0.00000000E+00-1.30306099E-02 2.97077759E-17 9.39403809E-08 + 1.09797825E-20 0.00000000E+00 1.09977496E-08 0.00000000E+00-5.60821695E-10 +-1.37423943E-03 1.07303302E-08 6.16842667E-05-5.58732199E-10 4.03749001E-02 + 0.00000000E+00-2.53862408E-04 0.00000000E+00-2.24808402E-03 6.29091561E-18 + 1.40591529E-05-3.89486588E-20-2.19364606E-05-5.12098693E-20-2.47264189E-04 + 0.00000000E+00 5.09365019E-05 6.38994441E-10-3.98242299E-08 2.66589418E-13 + 0.00000000E+00 5.64229096E-10 0.00000000E+00 1.76291254E-14 5.18169310E-05 + 1.45366357E-19 2.08296867E-04 5.92292709E-19 5.39467669E-04 0.00000000E+00 + 2.15786065E-03 0.00000000E+00-1.42416705E-03-1.21222211E-08-7.95339982E-08 + 3.22912241E-13 0.00000000E+00-1.22350029E-08 0.00000000E+00 1.26358035E-13 + 5.18171855E-05 1.38518998E-19-3.06005798E-05-1.07590050E-19 5.39466318E-04 + 0.00000000E+00-2.92197540E-04 0.00000000E+00 7.84855684E-05 5.06472648E-10 +-3.96676761E-08 1.22701640E-13 0.00000000E+00 5.35149983E-10 0.00000000E+00 + 6.10776156E-14 5.39466318E-04 0.00000000E+00 5.18171855E-05-1.38518998E-19 + 0.00000000E+00-1.09977496E-08 0.00000000E+00-5.70231916E-11 1.37423943E-03 +-1.07303302E-08 7.20151326E-06-5.55260596E-11 4.67516665E-03 0.00000000E+00 + 6.29323843E-04 0.00000000E+00 4.88787193E-04-1.69393974E-18 7.05851338E-05 +-2.91841201E-19 0.00000000E+00-1.09138770E-08 0.00000000E+00 5.67788812E-11 + 1.42922544E-03-1.05590888E-08-7.36018397E-06 5.50352531E-11 7.05849759E-05 + 3.22722810E-19 6.29322294E-04 0.00000000E+00-1.58768672E-03-1.01239387E-08 +-8.30989046E-06-5.24283125E-11 0.00000000E+00-1.07387569E-08 0.00000000E+00 +-5.57250230E-11 6.50433448E-04 2.61101692E-18 9.22287781E-05 3.04254129E-19 + 5.39391548E-03 0.00000000E+00 7.19154735E-04 0.00000000E+00-1.64245854E-03 +-9.99364037E-09 8.46794212E-06 5.20523041E-11 0.00000000E+00-1.06954896E-08 + 0.00000000E+00 5.56005869E-11-2.92197540E-04 0.00000000E+00-3.06005798E-05 + 1.07590050E-19 0.00000000E+00 5.60821695E-10 0.00000000E+00 6.10776156E-14 +-6.16842667E-05 5.58732199E-10 3.96676761E-08 1.22701640E-13 6.29323843E-04 + 0.00000000E+00 2.51728352E-03 0.00000000E+00 7.05851338E-05-2.91841201E-19 + 2.83367407E-04-1.16713368E-18 0.00000000E+00-1.18942909E-08 0.00000000E+00 + 8.33477327E-14 1.65937482E-03-1.13628938E-08 7.91019805E-08 2.18546195E-13 + 6.29322294E-04 0.00000000E+00-3.37119257E-04 0.00000000E+00 7.05849759E-05 +-3.22722810E-19-4.07034385E-05 1.56744235E-19 0.00000000E+00 5.29378675E-10 + 0.00000000E+00 3.11090361E-14-8.91209231E-05 4.83277874E-10 3.95129141E-08 + 9.40020973E-14 3.96676761E-08-1.22701640E-13 0.00000000E+00-6.10776156E-14 + 1.40591529E-05 3.89486588E-20 8.42382641E-08 2.36371326E-22-2.53862408E-04 + 0.00000000E+00-1.51275971E-06 0.00000000E+00-7.36018397E-06-5.50352531E-11 + 7.91019805E-08-2.18546195E-13 0.00000000E+00-5.67788812E-11 0.00000000E+00 +-8.33477327E-14 1.10319765E-07 1.60677554E-20-2.23831083E-07-5.62827558E-22 +-3.46546145E-05 0.00000000E+00 3.76720226E-06 0.00000000E+00 8.30989046E-06 + 5.24283125E-11 3.95129141E-08-9.40020973E-14 0.00000000E+00 5.57250230E-11 + 0.00000000E+00-3.11090361E-14-1.39489516E-05-2.73577586E-20 8.36246298E-08 + 1.67163500E-22 2.19065940E-04 0.00000000E+00-1.31927361E-06 0.00000000E+00 +-7.84855684E-05-5.06472648E-10 0.00000000E+00-5.35149983E-10-2.24808402E-03 +-6.29091561E-18-1.40518696E-05-3.97817735E-20 4.03749001E-02 0.00000000E+00 + 2.50989215E-04 0.00000000E+00 1.42922544E-03 1.05590888E-08 1.65937482E-03 + 1.13628938E-08 0.00000000E+00 1.09138770E-08 0.00000000E+00 1.18942909E-08 +-1.29430620E-02-3.35708455E-17 1.10319765E-07 1.60677554E-20 2.17465647E-01 + 0.00000000E+00-3.46546145E-05 0.00000000E+00 1.58768672E-03 1.01239387E-08 +-7.23850777E-05-5.23091554E-10 0.00000000E+00 1.07387569E-08 0.00000000E+00 +-5.42591202E-10-2.23172135E-03-4.47014193E-18 1.39573812E-05 2.85040958E-20 + 3.52102764E-02 0.00000000E+00-2.21208399E-04 0.00000000E+00 0.00000000E+00 +-6.10776156E-14-3.96676761E-08-1.22701640E-13-2.53862408E-04 0.00000000E+00 +-1.51275971E-06 0.00000000E+00 1.40591529E-05-3.89486588E-20 8.42382641E-08 +-2.36371326E-22 0.00000000E+00-5.67788812E-11 0.00000000E+00-8.33477327E-14 + 7.36018397E-06-5.50352531E-11-7.91019805E-08-2.18546195E-13-3.46546145E-05 + 0.00000000E+00 3.76720226E-06 0.00000000E+00 1.10319765E-07-1.60677554E-20 +-2.23831083E-07 5.62827558E-22 0.00000000E+00 5.57250230E-11 0.00000000E+00 +-3.11090361E-14-8.30989046E-06 5.24283125E-11-3.95129141E-08-9.40020973E-14 + 2.19065940E-04 0.00000000E+00-1.31927361E-06 0.00000000E+00-1.39489516E-05 + 2.73577586E-20 8.36246298E-08-1.67163500E-22 0.00000000E+00-5.35149983E-10 + 7.84855684E-05-5.06472648E-10 4.03749001E-02 0.00000000E+00 2.50989215E-04 + 0.00000000E+00-2.24808402E-03 6.29091561E-18-1.40518696E-05 3.97817735E-20 + 0.00000000E+00 1.09138770E-08 0.00000000E+00 1.18942909E-08-1.42922544E-03 + 1.05590888E-08-1.65937482E-03 1.13628938E-08 2.17465647E-01 0.00000000E+00 +-3.46546145E-05 0.00000000E+00-1.29430620E-02 3.35708455E-17 1.10319765E-07 +-1.60677554E-20 0.00000000E+00 1.07387569E-08 0.00000000E+00-5.42591202E-10 +-1.58768672E-03 1.01239387E-08 7.23850777E-05-5.23091554E-10 3.52102764E-02 + 0.00000000E+00-2.21208399E-04 0.00000000E+00-2.23172135E-03 4.47014193E-18 + 1.39573812E-05-2.85040958E-20-3.06005798E-05-1.07590050E-19-2.92197540E-04 + 0.00000000E+00 6.16842667E-05 5.58732199E-10-3.96676761E-08 1.22701640E-13 + 0.00000000E+00 5.60821695E-10 0.00000000E+00 6.10776156E-14 7.05851338E-05 + 2.91841201E-19 2.83367407E-04 1.16713368E-18 6.29323843E-04 0.00000000E+00 + 2.51728352E-03 0.00000000E+00-1.65937482E-03-1.13628938E-08-7.91019805E-08 + 2.18546195E-13 0.00000000E+00-1.18942909E-08 0.00000000E+00 8.33477327E-14 + 7.05849759E-05 3.22722810E-19-4.07034385E-05-1.56744235E-19 6.29322294E-04 + 0.00000000E+00-3.37119257E-04 0.00000000E+00 8.91209231E-05 4.83277874E-10 +-3.95129141E-08 9.40020973E-14 0.00000000E+00 5.29378675E-10 0.00000000E+00 + 3.11090361E-14 6.29322294E-04 0.00000000E+00 7.05849759E-05-3.22722810E-19 + 0.00000000E+00-1.07387569E-08 0.00000000E+00-5.57250230E-11 1.58768672E-03 +-1.01239387E-08 8.30989046E-06-5.24283125E-11 5.39391548E-03 0.00000000E+00 + 7.19154735E-04 0.00000000E+00 6.50433448E-04-2.61101692E-18 9.22287781E-05 +-3.04254129E-19 0.00000000E+00-1.06954896E-08 0.00000000E+00 5.56005869E-11 + 1.64245854E-03-9.99364037E-09-8.46794212E-06 5.20523041E-11 9.22290010E-05 + 2.53488314E-19 7.19152638E-04 0.00000000E+00-1.80040865E-03-9.67532032E-09 +-9.41450778E-06-5.01420571E-11 0.00000000E+00-1.05994649E-08 0.00000000E+00 +-5.50250179E-11 8.35068003E-04 2.20286844E-18 1.16742730E-04 3.26361940E-19 + 6.11244832E-03 0.00000000E+00 8.08957464E-04 0.00000000E+00-1.85491828E-03 +-9.58106815E-09 9.57180160E-06 4.98702758E-11 0.00000000E+00-1.05760609E-08 + 0.00000000E+00 5.49575509E-11-3.37119257E-04 0.00000000E+00-4.07034385E-05 + 1.56744235E-19 0.00000000E+00 5.42591202E-10 0.00000000E+00 3.11090361E-14 +-7.23850777E-05 5.23091554E-10 3.95129141E-08 9.40020973E-14 7.19154735E-04 + 0.00000000E+00 2.87660506E-03 0.00000000E+00 9.22287781E-05-3.04254129E-19 + 3.69940628E-04-1.14839446E-18 0.00000000E+00-1.17055903E-08 0.00000000E+00 + 4.80909626E-14 1.89366622E-03-1.08056564E-08 7.89167855E-08 1.56684172E-13 + 7.19152638E-04 0.00000000E+00-3.82027525E-04 0.00000000E+00 9.22290010E-05 +-2.53488314E-19-5.22429328E-05 1.44962563E-19 0.00000000E+00 5.25920526E-10 + 0.00000000E+00 1.68667327E-14-9.97087932E-05 4.67158044E-10 3.93234551E-08 + 6.79453344E-14 3.95129141E-08-9.40020973E-14 0.00000000E+00-3.11090361E-14 + 1.39573812E-05 2.85040958E-20 8.36246298E-08 1.67163500E-22-2.21208399E-04 + 0.00000000E+00-1.31927361E-06 0.00000000E+00-8.46794212E-06-5.20523041E-11 + 7.89167855E-08-1.56684172E-13 0.00000000E+00-5.56005869E-11 0.00000000E+00 +-4.80909626E-14 1.26123730E-07-7.54976031E-21-2.22076958E-07-4.60580010E-22 +-2.63112791E-05 0.00000000E+00 3.31642837E-06 0.00000000E+00 9.41450778E-06 + 5.01420571E-11 3.93234551E-08-6.79453344E-14 0.00000000E+00 5.50250179E-11 + 0.00000000E+00-1.68667327E-14-1.38312398E-05-3.66250536E-20 8.29224330E-08 + 2.11806284E-22 1.94814101E-04 0.00000000E+00-1.17247910E-06 0.00000000E+00 +-8.91209231E-05-4.83277874E-10 0.00000000E+00-5.29378675E-10-2.23172135E-03 +-4.47014193E-18-1.39489516E-05-2.73577586E-20 3.52102764E-02 0.00000000E+00 + 2.19065940E-04 0.00000000E+00 1.64245854E-03 9.99364037E-09 1.89366622E-03 + 1.08056564E-08 0.00000000E+00 1.06954896E-08 0.00000000E+00 1.17055903E-08 +-1.28417244E-02-2.47487160E-17 1.26123730E-07-7.54976031E-21 1.91522291E-01 + 0.00000000E+00-2.63112791E-05 0.00000000E+00 1.80040865E-03 9.67532032E-09 +-8.30530777E-05-4.95953572E-10 0.00000000E+00 1.05994649E-08 0.00000000E+00 +-5.33070430E-10-2.21299418E-03-5.66376025E-18 1.38408410E-05 3.41536581E-20 + 3.12921828E-02 0.00000000E+00-1.96468447E-04 0.00000000E+00 0.00000000E+00 +-3.11090361E-14-3.95129141E-08-9.40020973E-14-2.21208399E-04 0.00000000E+00 +-1.31927361E-06 0.00000000E+00 1.39573812E-05-2.85040958E-20 8.36246298E-08 +-1.67163500E-22 0.00000000E+00-5.56005869E-11 0.00000000E+00-4.80909626E-14 + 8.46794212E-06-5.20523041E-11-7.89167855E-08-1.56684172E-13-2.63112791E-05 + 0.00000000E+00 3.31642837E-06 0.00000000E+00 1.26123730E-07 7.54976031E-21 +-2.22076958E-07 4.60580010E-22 0.00000000E+00 5.50250179E-11 0.00000000E+00 +-1.68667327E-14-9.41450778E-06 5.01420571E-11-3.93234551E-08-6.79453344E-14 + 1.94814101E-04 0.00000000E+00-1.17247910E-06 0.00000000E+00-1.38312398E-05 + 3.66250536E-20 8.29224330E-08-2.11806284E-22 0.00000000E+00-5.29378675E-10 + 8.91209231E-05-4.83277874E-10 3.52102764E-02 0.00000000E+00 2.19065940E-04 + 0.00000000E+00-2.23172135E-03 4.47014193E-18-1.39489516E-05 2.73577586E-20 + 0.00000000E+00 1.06954896E-08 0.00000000E+00 1.17055903E-08-1.64245854E-03 + 9.99364037E-09-1.89366622E-03 1.08056564E-08 1.91522291E-01 0.00000000E+00 +-2.63112791E-05 0.00000000E+00-1.28417244E-02 2.47487160E-17 1.26123730E-07 + 7.54976031E-21 0.00000000E+00 1.05994649E-08 0.00000000E+00-5.33070430E-10 +-1.80040865E-03 9.67532032E-09 8.30530777E-05-4.95953572E-10 3.12921828E-02 + 0.00000000E+00-1.96468447E-04 0.00000000E+00-2.21299418E-03 5.66376025E-18 + 1.38408410E-05-3.41536581E-20-4.07034385E-05-1.56744235E-19-3.37119257E-04 + 0.00000000E+00 7.23850777E-05 5.23091554E-10-3.95129141E-08 9.40020973E-14 + 0.00000000E+00 5.42591202E-10 0.00000000E+00 3.11090361E-14 9.22287781E-05 + 3.04254129E-19 3.69940628E-04 1.14839446E-18 7.19154735E-04 0.00000000E+00 + 2.87660506E-03 0.00000000E+00-1.89366622E-03-1.08056564E-08-7.89167855E-08 + 1.56684172E-13 0.00000000E+00-1.17055903E-08 0.00000000E+00 4.80909626E-14 + 9.22290010E-05 2.53488314E-19-5.22429328E-05-1.44962563E-19 7.19152638E-04 + 0.00000000E+00-3.82027525E-04 0.00000000E+00 9.97087932E-05 4.67158044E-10 +-3.93234551E-08 6.79453344E-14 0.00000000E+00 5.25920526E-10 0.00000000E+00 + 1.68667327E-14 7.19152638E-04 0.00000000E+00 9.22290010E-05-2.53488314E-19 + 0.00000000E+00-1.05994649E-08 0.00000000E+00-5.50250179E-11 1.80040865E-03 +-9.67532032E-09 9.41450778E-06-5.01420571E-11 6.11244832E-03 0.00000000E+00 + 8.08957464E-04 0.00000000E+00 8.35068003E-04-2.20286844E-18 1.16742730E-04 +-3.26361940E-19 0.00000000E+00-1.05760609E-08 0.00000000E+00 5.49575509E-11 + 1.85491828E-03-9.58106815E-09-9.57180160E-06 4.98702758E-11 1.16742327E-04 + 3.75170392E-19 8.08955306E-04 0.00000000E+00-2.01187888E-03-9.34333618E-09 +-1.05125011E-05-4.84448591E-11 0.00000000E+00-1.05335818E-08 0.00000000E+00 +-5.47020377E-11 1.04263597E-03 3.17149003E-18 1.44121250E-04 3.95152686E-19 + 6.83074175E-03 0.00000000E+00 8.98727729E-04 0.00000000E+00-2.06608612E-03 +-9.27193379E-09 1.06689231E-05 4.82389129E-11 0.00000000E+00-1.05261431E-08 + 0.00000000E+00 5.46806378E-11-3.82027525E-04 0.00000000E+00-5.22429328E-05 + 1.44962563E-19 0.00000000E+00 5.33070430E-10 0.00000000E+00 1.68667327E-14 +-8.30530777E-05 4.95953572E-10 3.93234551E-08 6.79453344E-14 8.08957464E-04 + 0.00000000E+00 3.23581412E-03 0.00000000E+00 1.16742730E-04-3.26361940E-19 + 4.67993491E-04-1.38390168E-18 0.00000000E+00-1.16048996E-08 0.00000000E+00 + 2.04908555E-14 2.12684011E-03-1.04007028E-08 7.83513749E-08 1.18272066E-13 + 8.08955306E-04 0.00000000E+00-4.26920759E-04 0.00000000E+00 1.16742327E-04 +-3.75170392E-19-6.52158945E-05 1.92580770E-19 0.00000000E+00 5.25427782E-10 + 0.00000000E+00 5.34997497E-15-1.10229596E-04 4.54585986E-10 3.91055027E-08 + 5.14865491E-14 3.93234551E-08-6.79453344E-14 0.00000000E+00-1.68667327E-14 + 1.38408410E-05 3.41536581E-20 8.29224330E-08 2.11806284E-22-1.96468447E-04 + 0.00000000E+00-1.17247910E-06 0.00000000E+00-9.57180160E-06-4.98702758E-11 + 7.83513749E-08-1.18272066E-13 0.00000000E+00-5.49575509E-11 0.00000000E+00 +-2.04908555E-14 1.42842101E-07-3.35904507E-20-2.20080999E-07-8.14042281E-22 +-2.06010052E-05 0.00000000E+00 2.96930051E-06 0.00000000E+00 1.05125011E-05 + 4.84448591E-11 3.91055027E-08-5.14865491E-14 0.00000000E+00 5.47020377E-11 + 0.00000000E+00-5.34997497E-15-1.36981196E-05-6.29501823E-20 8.21278255E-08 + 3.77233944E-22 1.75816339E-04 0.00000000E+00-1.05760423E-06 0.00000000E+00 +-9.97087932E-05-4.67158044E-10 0.00000000E+00-5.25920526E-10-2.21299418E-03 +-5.66376025E-18-1.38312398E-05-3.66250536E-20 3.12921828E-02 0.00000000E+00 + 1.94814101E-04 0.00000000E+00 1.85491828E-03 9.58106815E-09 2.12684011E-03 + 1.04007028E-08 0.00000000E+00 1.05760609E-08 0.00000000E+00 1.16048996E-08 +-1.27263759E-02-4.83475195E-17 1.42842101E-07-3.35904507E-20 1.71523888E-01 + 0.00000000E+00-2.06010052E-05 0.00000000E+00 2.01187888E-03 9.34333618E-09 +-9.36662523E-05-4.76401587E-10 0.00000000E+00 1.05335818E-08 0.00000000E+00 +-5.27699454E-10-2.19180136E-03-1.00473980E-17 1.37088762E-05 6.27630862E-20 + 2.82261773E-02 0.00000000E+00-1.77128442E-04 0.00000000E+00 0.00000000E+00 +-1.68667327E-14-3.93234551E-08-6.79453344E-14-1.96468447E-04 0.00000000E+00 +-1.17247910E-06 0.00000000E+00 1.38408410E-05-3.41536581E-20 8.29224330E-08 +-2.11806284E-22 0.00000000E+00-5.49575509E-11 0.00000000E+00-2.04908555E-14 + 9.57180160E-06-4.98702758E-11-7.83513749E-08-1.18272066E-13-2.06010052E-05 + 0.00000000E+00 2.96930051E-06 0.00000000E+00 1.42842101E-07 3.35904507E-20 +-2.20080999E-07 8.14042281E-22 0.00000000E+00 5.47020377E-11 0.00000000E+00 +-5.34997497E-15-1.05125011E-05 4.84448591E-11-3.91055027E-08-5.14865491E-14 + 1.75816339E-04 0.00000000E+00-1.05760423E-06 0.00000000E+00-1.36981196E-05 + 6.29501823E-20 8.21278255E-08-3.77233944E-22 0.00000000E+00-5.25920526E-10 + 9.97087932E-05-4.67158044E-10 3.12921828E-02 0.00000000E+00 1.94814101E-04 + 0.00000000E+00-2.21299418E-03 5.66376025E-18-1.38312398E-05 3.66250536E-20 + 0.00000000E+00 1.05760609E-08 0.00000000E+00 1.16048996E-08-1.85491828E-03 + 9.58106815E-09-2.12684011E-03 1.04007028E-08 1.71523888E-01 0.00000000E+00 +-2.06010052E-05 0.00000000E+00-1.27263759E-02 4.83475195E-17 1.42842101E-07 + 3.35904507E-20 0.00000000E+00 1.05335818E-08 0.00000000E+00-5.27699454E-10 +-2.01187888E-03 9.34333618E-09 9.36662523E-05-4.76401587E-10 2.82261773E-02 + 0.00000000E+00-1.77128442E-04 0.00000000E+00-2.19180136E-03 1.00473980E-17 + 1.37088762E-05-6.27630862E-20-5.22429328E-05-1.44962563E-19-3.82027525E-04 + 0.00000000E+00 8.30530777E-05 4.95953572E-10-3.93234551E-08 6.79453344E-14 + 0.00000000E+00 5.33070430E-10 0.00000000E+00 1.68667327E-14 1.16742730E-04 + 3.26361940E-19 4.67993491E-04 1.38390168E-18 8.08957464E-04 0.00000000E+00 + 3.23581412E-03 0.00000000E+00-2.12684011E-03-1.04007028E-08-7.83513749E-08 + 1.18272066E-13 0.00000000E+00-1.16048996E-08 0.00000000E+00 2.04908555E-14 + 1.16742327E-04 3.75170392E-19-6.52158945E-05-1.92580770E-19 8.08955306E-04 + 0.00000000E+00-4.26920759E-04 0.00000000E+00 1.10229596E-04 4.54585986E-10 +-3.91055027E-08 5.14865491E-14 0.00000000E+00 5.25427782E-10 0.00000000E+00 + 5.34997497E-15 8.08955306E-04 0.00000000E+00 1.16742327E-04-3.75170392E-19 + 0.00000000E+00-1.05335818E-08 0.00000000E+00-5.47020377E-11 2.01187888E-03 +-9.34333618E-09 1.05125011E-05-4.84448591E-11 6.83074175E-03 0.00000000E+00 + 8.98727729E-04 0.00000000E+00 1.04263597E-03-3.17149003E-18 1.44121250E-04 +-3.95152686E-19 0.00000000E+00-1.05261431E-08 0.00000000E+00 5.46806378E-11 + 2.06608612E-03-9.27193379E-09-1.06689231E-05 4.82389129E-11 1.44121311E-04 + 3.53718367E-19 8.98725002E-04 0.00000000E+00-2.22231051E-03-9.09217712E-09 +-1.16051590E-05-4.71608639E-11 0.00000000E+00-1.05215126E-08 0.00000000E+00 +-5.46524568E-11 1.27310104E-03 3.32315708E-18 1.74357754E-04 4.98168046E-19 + 7.54876006E-03 0.00000000E+00 9.88462489E-04 0.00000000E+00-2.27623001E-03 +-9.03798505E-09 1.17607515E-05 4.70045485E-11 0.00000000E+00-1.05251886E-08 + 0.00000000E+00 5.46631073E-11-4.26920759E-04 0.00000000E+00-6.52158945E-05 + 1.92580770E-19 0.00000000E+00 5.27699454E-10 0.00000000E+00 5.34997497E-15 +-9.36662523E-05 4.76401587E-10 3.91055027E-08 5.14865491E-14 8.98727729E-04 + 0.00000000E+00 3.59489310E-03 0.00000000E+00 1.44121250E-04-3.95152686E-19 + 5.77505733E-04-1.54245182E-18 0.00000000E+00-1.15724497E-08 0.00000000E+00 + 2.08563453E-15 2.35871550E-03-1.00944428E-08 7.80279764E-08 8.92185019E-14 + 8.98725002E-04 0.00000000E+00-4.71796873E-04 0.00000000E+00 1.44121311E-04 +-3.53718367E-19-7.96197663E-05 2.12971603E-19 0.00000000E+00 5.26783522E-10 + 0.00000000E+00-2.66262492E-15-1.20699194E-04 4.45056190E-10 3.88981382E-08 + 3.90788414E-14 3.91055027E-08-5.14865491E-14 0.00000000E+00-5.34997497E-15 + 1.37088762E-05 6.27630862E-20 8.21278255E-08 3.77233944E-22-1.77128442E-04 + 0.00000000E+00-1.05760423E-06 0.00000000E+00-1.06689231E-05-4.82389129E-11 + 7.80279764E-08-8.92185019E-14 0.00000000E+00-5.46806378E-11 0.00000000E+00 +-2.08563453E-15 1.58941907E-07 2.00601055E-20-2.17842403E-07-8.97741197E-22 +-1.65166094E-05 0.00000000E+00 2.69450317E-06 0.00000000E+00 1.16051590E-05 + 4.71608639E-11 3.88981382E-08-3.90788414E-14 0.00000000E+00 5.46524568E-11 + 0.00000000E+00 2.66262492E-15-1.35499186E-05-4.60997033E-20 8.12430114E-08 + 2.80743211E-22 1.60578300E-04 0.00000000E+00-9.65537362E-07 0.00000000E+00 +-1.10229596E-04-4.54585986E-10 0.00000000E+00-5.25427782E-10-2.19180136E-03 +-1.00473980E-17-1.36981196E-05-6.29501823E-20 2.82261773E-02 0.00000000E+00 + 1.75816339E-04 0.00000000E+00 2.06608612E-03 9.27193379E-09 2.35871550E-03 + 1.00944428E-08 0.00000000E+00 1.05261431E-08 0.00000000E+00 1.15724497E-08 +-1.25970372E-02-5.27023606E-17 1.58941907E-07 2.00601055E-20 1.55681424E-01 + 0.00000000E+00-1.65166094E-05 0.00000000E+00 2.22231051E-03 9.09217712E-09 +-1.04223746E-04-4.61613695E-10 0.00000000E+00 1.05215126E-08 0.00000000E+00 +-5.25659460E-10-2.16820004E-03-7.49665203E-18 1.35618804E-05 4.76243466E-20 + 2.57689837E-02 0.00000000E+00-1.61641114E-04 0.00000000E+00 0.00000000E+00 +-5.34997497E-15-3.91055027E-08-5.14865491E-14-1.77128442E-04 0.00000000E+00 +-1.05760423E-06 0.00000000E+00 1.37088762E-05-6.27630862E-20 8.21278255E-08 +-3.77233944E-22 0.00000000E+00-5.46806378E-11 0.00000000E+00-2.08563453E-15 + 1.06689231E-05-4.82389129E-11-7.80279764E-08-8.92185019E-14-1.65166094E-05 + 0.00000000E+00 2.69450317E-06 0.00000000E+00 1.58941907E-07-2.00601055E-20 +-2.17842403E-07 8.97741197E-22 0.00000000E+00 5.46524568E-11 0.00000000E+00 + 2.66262492E-15-1.16051590E-05 4.71608639E-11-3.88981382E-08-3.90788414E-14 + 1.60578300E-04 0.00000000E+00-9.65537362E-07 0.00000000E+00-1.35499186E-05 + 4.60997033E-20 8.12430114E-08-2.80743211E-22 0.00000000E+00-5.25427782E-10 + 1.10229596E-04-4.54585986E-10 2.82261773E-02 0.00000000E+00 1.75816339E-04 + 0.00000000E+00-2.19180136E-03 1.00473980E-17-1.36981196E-05 6.29501823E-20 + 0.00000000E+00 1.05261431E-08 0.00000000E+00 1.15724497E-08-2.06608612E-03 + 9.27193379E-09-2.35871550E-03 1.00944428E-08 1.55681424E-01 0.00000000E+00 +-1.65166094E-05 0.00000000E+00-1.25970372E-02 5.27023606E-17 1.58941907E-07 +-2.00601055E-20 0.00000000E+00 1.05215126E-08 0.00000000E+00-5.25659460E-10 +-2.22231051E-03 9.09217712E-09 1.04223746E-04-4.61613695E-10 2.57689837E-02 + 0.00000000E+00-1.61641114E-04 0.00000000E+00-2.16820004E-03 7.49665203E-18 + 1.35618804E-05-4.76243466E-20-6.52158945E-05-1.92580770E-19-4.26920759E-04 + 0.00000000E+00 9.36662523E-05 4.76401587E-10-3.91055027E-08 5.14865491E-14 + 0.00000000E+00 5.27699454E-10 0.00000000E+00 5.34997497E-15 1.44121250E-04 + 3.95152686E-19 5.77505733E-04 1.54245182E-18 8.98727729E-04 0.00000000E+00 + 3.59489310E-03 0.00000000E+00-2.35871550E-03-1.00944428E-08-7.80279764E-08 + 8.92185019E-14 0.00000000E+00-1.15724497E-08 0.00000000E+00 2.08563453E-15 + 1.44121311E-04 3.53718367E-19-7.96197663E-05-2.12971603E-19 8.98725002E-04 + 0.00000000E+00-4.71796873E-04 0.00000000E+00 1.20699194E-04 4.45056190E-10 +-3.88981382E-08 3.90788414E-14 0.00000000E+00 5.26783522E-10 0.00000000E+00 +-2.66262492E-15 8.98725002E-04 0.00000000E+00 1.44121311E-04-3.53718367E-19 + 0.00000000E+00-1.05215126E-08 0.00000000E+00-5.46524568E-11 2.22231051E-03 +-9.09217712E-09 1.16051590E-05-4.71608639E-11 7.54876006E-03 0.00000000E+00 + 9.88462489E-04 0.00000000E+00 1.27310104E-03-3.32315708E-18 1.74357754E-04 +-4.98168046E-19 0.00000000E+00-1.05251886E-08 0.00000000E+00 5.46631073E-11 + 2.27623001E-03-9.03798505E-09-1.17607515E-05 4.70045485E-11 1.74357292E-04 + 5.33289100E-19 9.88459711E-04 0.00000000E+00-2.43140207E-03-8.90087637E-09 +-1.26906830E-05-4.61823663E-11 0.00000000E+00-1.05486642E-08 0.00000000E+00 +-5.48034007E-11 1.52639589E-03 4.40285609E-18 2.07445141E-04 5.49795614E-19 + 8.26648274E-03 0.00000000E+00 1.07815807E-03 0.00000000E+00-2.48489748E-03 +-8.85948883E-09 1.28450467E-05 4.60629828E-11 0.00000000E+00-1.05607609E-08 + 0.00000000E+00 5.48383353E-11-4.71796873E-04 0.00000000E+00-7.96197663E-05 + 2.12971603E-19 0.00000000E+00 5.25659460E-10 0.00000000E+00-2.66262492E-15 +-1.04223746E-04 4.61613695E-10 3.88981382E-08 3.90788414E-14 9.88462489E-04 + 0.00000000E+00 3.95383050E-03 0.00000000E+00 1.74357754E-04-4.98168046E-19 + 6.98448486E-04-2.01771928E-18 0.00000000E+00-1.15877727E-08 0.00000000E+00 +-1.19214851E-14 2.58934381E-03-9.86204168E-09 7.74929629E-08 6.81815024E-14 + 9.88459711E-04 0.00000000E+00-5.16654445E-04 0.00000000E+00 1.74357292E-04 +-5.33289100E-19-9.54506083E-05 2.70771179E-19 0.00000000E+00 5.29624432E-10 + 0.00000000E+00-8.73363976E-15-1.31077976E-04 4.37748736E-10 3.85909170E-08 + 2.98458794E-14 3.88981382E-08-3.90788414E-14 0.00000000E+00 2.66262492E-15 + 1.35618804E-05 4.76243466E-20 8.12430114E-08 2.80743211E-22-1.61641114E-04 + 0.00000000E+00-9.65537362E-07 0.00000000E+00-1.17607515E-05-4.70045485E-11 + 7.74929629E-08-6.81815024E-14 0.00000000E+00-5.46631073E-11 0.00000000E+00 + 1.19214851E-14 1.76129163E-07 1.13672879E-20-2.15355953E-07-6.46635408E-22 +-1.34968321E-05 0.00000000E+00 2.47221609E-06 0.00000000E+00 1.26906830E-05 + 4.61823663E-11 3.85909170E-08-2.98458794E-14 0.00000000E+00 5.48034007E-11 + 0.00000000E+00 8.73363976E-15-1.33858377E-05-3.60725331E-20 8.02630135E-08 + 2.16769351E-22 1.48121630E-04 0.00000000E+00-8.90324199E-07 0.00000000E+00 +-1.20699194E-04-4.45056190E-10 0.00000000E+00-5.26783522E-10-2.16820004E-03 +-7.49665203E-18-1.35499186E-05-4.60997033E-20 2.57689837E-02 0.00000000E+00 + 1.60578300E-04 0.00000000E+00 2.27623001E-03 9.03798505E-09 2.58934381E-03 + 9.86204168E-09 0.00000000E+00 1.05251886E-08 0.00000000E+00 1.15877727E-08 +-1.24533302E-02-3.66379816E-17 1.76129163E-07 1.13672879E-20 1.42859835E-01 + 0.00000000E+00-1.34968321E-05 0.00000000E+00 2.43140207E-03 8.90087637E-09 +-1.14732200E-04-4.50394079E-10 0.00000000E+00 1.05486642E-08 0.00000000E+00 +-5.25927667E-10-2.14205882E-03-5.78556398E-18 1.33990042E-05 3.62699786E-20 + 2.37616465E-02 0.00000000E+00-1.48997355E-04 0.00000000E+00 0.00000000E+00 + 2.66262492E-15-3.88981382E-08-3.90788414E-14-1.61641114E-04 0.00000000E+00 +-9.65537362E-07 0.00000000E+00 1.35618804E-05-4.76243466E-20 8.12430114E-08 +-2.80743211E-22 0.00000000E+00-5.46631073E-11 0.00000000E+00 1.19214851E-14 + 1.17607515E-05-4.70045485E-11-7.74929629E-08-6.81815024E-14-1.34968321E-05 + 0.00000000E+00 2.47221609E-06 0.00000000E+00 1.76129163E-07-1.13672879E-20 +-2.15355953E-07 6.46635408E-22 0.00000000E+00 5.48034007E-11 0.00000000E+00 + 8.73363976E-15-1.26906830E-05 4.61823663E-11-3.85909170E-08-2.98458794E-14 + 1.48121630E-04 0.00000000E+00-8.90324199E-07 0.00000000E+00-1.33858377E-05 + 3.60725331E-20 8.02630135E-08-2.16769351E-22 0.00000000E+00-5.26783522E-10 + 1.20699194E-04-4.45056190E-10 2.57689837E-02 0.00000000E+00 1.60578300E-04 + 0.00000000E+00-2.16820004E-03 7.49665203E-18-1.35499186E-05 4.60997033E-20 + 0.00000000E+00 1.05251886E-08 0.00000000E+00 1.15877727E-08-2.27623001E-03 + 9.03798505E-09-2.58934381E-03 9.86204168E-09 1.42859835E-01 0.00000000E+00 +-1.34968321E-05 0.00000000E+00-1.24533302E-02 3.66379816E-17 1.76129163E-07 +-1.13672879E-20 0.00000000E+00 1.05486642E-08 0.00000000E+00-5.25927667E-10 +-2.43140207E-03 8.90087637E-09 1.14732200E-04-4.50394079E-10 2.37616465E-02 + 0.00000000E+00-1.48997355E-04 0.00000000E+00-2.14205882E-03 5.78556398E-18 + 1.33990042E-05-3.62699786E-20-7.96197663E-05-2.12971603E-19-4.71796873E-04 + 0.00000000E+00 1.04223746E-04 4.61613695E-10-3.88981382E-08 3.90788414E-14 + 0.00000000E+00 5.25659460E-10 0.00000000E+00-2.66262492E-15 1.74357754E-04 + 4.98168046E-19 6.98448486E-04 2.01771928E-18 9.88462489E-04 0.00000000E+00 + 3.95383050E-03 0.00000000E+00-2.58934381E-03-9.86204168E-09-7.74929629E-08 + 6.81815024E-14 0.00000000E+00-1.15877727E-08 0.00000000E+00-1.19214851E-14 + 1.74357292E-04 5.33289100E-19-9.54506083E-05-2.70771179E-19 9.88459711E-04 + 0.00000000E+00-5.16654445E-04 0.00000000E+00 1.31077976E-04 4.37748736E-10 +-3.85909170E-08 2.98458794E-14 0.00000000E+00 5.29624432E-10 0.00000000E+00 +-8.73363976E-15 9.88459711E-04 0.00000000E+00 1.74357292E-04-5.33289100E-19 + 0.00000000E+00-1.05486642E-08 0.00000000E+00-5.48034007E-11 2.43140207E-03 +-8.90087637E-09 1.26906830E-05-4.61823663E-11 8.26648274E-03 0.00000000E+00 + 1.07815807E-03 0.00000000E+00 1.52639589E-03-4.40285609E-18 2.07445141E-04 +-5.49795614E-19 0.00000000E+00-1.05607609E-08 0.00000000E+00 5.48383353E-11 + 2.48489748E-03-8.85948883E-09-1.28450467E-05 4.60629828E-11 2.07444959E-04 + 5.24763247E-19 1.07815489E-03 0.00000000E+00-2.63887208E-03-8.75492317E-09 +-1.37678163E-05-4.54359254E-11 0.00000000E+00-1.06054411E-08 0.00000000E+00 +-5.51058036E-11 1.80246920E-03 4.58484225E-18 2.43375017E-04 6.32968876E-19 + 8.98387553E-03 0.00000000E+00 1.16781088E-03 0.00000000E+00-2.69199655E-03 +-8.72342846E-09 1.39211144E-05 4.53450760E-11 0.00000000E+00-1.06239722E-08 + 0.00000000E+00 5.51592978E-11-5.16654445E-04 0.00000000E+00-9.54506083E-05 + 2.70771179E-19 0.00000000E+00 5.25927667E-10 0.00000000E+00-8.73363976E-15 +-1.14732200E-04 4.50394079E-10 3.85909170E-08 2.98458794E-14 1.07815807E-03 + 0.00000000E+00 4.31261082E-03 0.00000000E+00 2.07445141E-04-5.49795614E-19 + 8.30795284E-04-2.18054789E-18 0.00000000E+00-1.16392346E-08 0.00000000E+00 +-2.24186273E-14 2.81819565E-03-9.68458170E-09 7.68732925E-08 5.20124808E-14 + 1.07815489E-03 0.00000000E+00-5.61491442E-04 0.00000000E+00 2.07444959E-04 +-5.24763247E-19-1.12704994E-04 2.89433031E-19 0.00000000E+00 5.33598173E-10 + 0.00000000E+00-1.33735708E-14-1.41385926E-04 4.32195831E-10 3.83245204E-08 + 2.27123608E-14 3.85909170E-08-2.98458794E-14 0.00000000E+00 8.73363976E-15 + 1.33990042E-05 3.62699786E-20 8.02630135E-08 2.16769351E-22-1.48997355E-04 + 0.00000000E+00-8.90324199E-07 0.00000000E+00-1.28450467E-05-4.60629828E-11 + 7.68732925E-08-5.20124808E-14 0.00000000E+00-5.48383353E-11 0.00000000E+00 + 2.24186273E-14 1.93037599E-07 1.42475808E-20-2.12617232E-07-4.92732594E-22 +-1.11997836E-05 0.00000000E+00 2.28925203E-06 0.00000000E+00 1.37678163E-05 + 4.54359254E-11 3.83245204E-08-2.27123608E-14 0.00000000E+00 5.51058036E-11 + 0.00000000E+00 1.33735708E-14-1.32059932E-05-2.10928737E-20 7.91886548E-08 + 1.33139682E-22 1.37781809E-04 0.00000000E+00-8.27925013E-07 0.00000000E+00 +-1.31077976E-04-4.37748736E-10 0.00000000E+00-5.29624432E-10-2.14205882E-03 +-5.78556398E-18-1.33858377E-05-3.60725331E-20 2.37616465E-02 0.00000000E+00 + 1.48121630E-04 0.00000000E+00 2.48489748E-03 8.85948883E-09 2.81819565E-03 + 9.68458170E-09 0.00000000E+00 1.05607609E-08 0.00000000E+00 1.16392346E-08 +-1.22950604E-02-2.97808459E-17 1.93037599E-07 1.42475808E-20 1.32302292E-01 + 0.00000000E+00-1.11997836E-05 0.00000000E+00 2.63887208E-03 8.75492317E-09 +-1.25153396E-04-4.41818615E-10 0.00000000E+00 1.06054411E-08 0.00000000E+00 +-5.27935488E-10-2.11339860E-03-3.55127505E-18 1.32203969E-05 2.33206372E-20 + 2.20963261E-02 0.00000000E+00-1.38513321E-04 0.00000000E+00 0.00000000E+00 + 8.73363976E-15-3.85909170E-08-2.98458794E-14-1.48997355E-04 0.00000000E+00 +-8.90324199E-07 0.00000000E+00 1.33990042E-05-3.62699786E-20 8.02630135E-08 +-2.16769351E-22 0.00000000E+00-5.48383353E-11 0.00000000E+00 2.24186273E-14 + 1.28450467E-05-4.60629828E-11-7.68732925E-08-5.20124808E-14-1.11997836E-05 + 0.00000000E+00 2.28925203E-06 0.00000000E+00 1.93037599E-07-1.42475808E-20 +-2.12617232E-07 4.92732594E-22 0.00000000E+00 5.51058036E-11 0.00000000E+00 + 1.33735708E-14-1.37678163E-05 4.54359254E-11-3.83245204E-08-2.27123608E-14 + 1.37781809E-04 0.00000000E+00-8.27925013E-07 0.00000000E+00-1.32059932E-05 + 2.10928737E-20 7.91886548E-08-1.33139682E-22 0.00000000E+00-5.29624432E-10 + 1.31077976E-04-4.37748736E-10 2.37616465E-02 0.00000000E+00 1.48121630E-04 + 0.00000000E+00-2.14205882E-03 5.78556398E-18-1.33858377E-05 3.60725331E-20 + 0.00000000E+00 1.05607609E-08 0.00000000E+00 1.16392346E-08-2.48489748E-03 + 8.85948883E-09-2.81819565E-03 9.68458170E-09 1.32302292E-01 0.00000000E+00 +-1.11997836E-05 0.00000000E+00-1.22950604E-02 2.97808459E-17 1.93037599E-07 +-1.42475808E-20 0.00000000E+00 1.06054411E-08 0.00000000E+00-5.27935488E-10 +-2.63887208E-03 8.75492317E-09 1.25153396E-04-4.41818615E-10 2.20963261E-02 + 0.00000000E+00-1.38513321E-04 0.00000000E+00-2.11339860E-03 3.55127505E-18 + 1.32203969E-05-2.33206372E-20-9.54506083E-05-2.70771179E-19-5.16654445E-04 + 0.00000000E+00 1.14732200E-04 4.50394079E-10-3.85909170E-08 2.98458794E-14 + 0.00000000E+00 5.25927667E-10 0.00000000E+00-8.73363976E-15 2.07445141E-04 + 5.49795614E-19 8.30795284E-04 2.18054789E-18 1.07815807E-03 0.00000000E+00 + 4.31261082E-03 0.00000000E+00-2.81819565E-03-9.68458170E-09-7.68732925E-08 + 5.20124808E-14 0.00000000E+00-1.16392346E-08 0.00000000E+00-2.24186273E-14 + 2.07444959E-04 5.24763247E-19-1.12704994E-04-2.89433031E-19 1.07815489E-03 + 0.00000000E+00-5.61491442E-04 0.00000000E+00 1.41385926E-04 4.32195831E-10 +-3.83245204E-08 2.27123608E-14 0.00000000E+00 5.33598173E-10 0.00000000E+00 +-1.33735708E-14 1.07815489E-03 0.00000000E+00 2.07444959E-04-5.24763247E-19 + 0.00000000E+00-1.06054411E-08 0.00000000E+00-5.51058036E-11 2.63887208E-03 +-8.75492317E-09 1.37678163E-05-4.54359254E-11 8.98387553E-03 0.00000000E+00 + 1.16781088E-03 0.00000000E+00 1.80246920E-03-4.58484225E-18 2.43375017E-04 +-6.32968876E-19 0.00000000E+00-1.06239722E-08 0.00000000E+00 5.51592978E-11 + 2.69199655E-03-8.72342846E-09-1.39211144E-05 4.53450760E-11-5.61491442E-04 + 0.00000000E+00-1.12704994E-04 2.89433031E-19 0.00000000E+00 5.27935488E-10 + 0.00000000E+00-1.33735708E-14-1.25153396E-04 4.41818615E-10 3.83245204E-08 + 2.27123608E-14 1.16781088E-03 0.00000000E+00 4.67122038E-03 0.00000000E+00 + 2.43375017E-04-6.32968876E-19 9.74511282E-04-2.54444613E-18 0.00000000E+00 +-1.17182876E-08 0.00000000E+00-3.05899079E-14 3.04541913E-03-9.54955325E-09 + 7.63349838E-08 3.94445105E-14 1.16780757E-03 0.00000000E+00-6.06306212E-04 + 0.00000000E+00 2.43374580E-04-6.31921622E-19-1.31378292E-04 3.51002738E-19 + 0.00000000E+00 5.38469503E-10 0.00000000E+00-1.70042983E-14-1.51605077E-04 + 4.28032469E-10 3.80024474E-08 1.70995149E-14 3.83245204E-08-2.27123608E-14 + 0.00000000E+00 1.33735708E-14 1.32203969E-05 2.33206372E-20 7.91886548E-08 + 1.33139682E-22-1.38513321E-04 0.00000000E+00-8.27925013E-07 0.00000000E+00 +-1.39211144E-05-4.53450760E-11 7.63349838E-08-3.94445105E-14 0.00000000E+00 +-5.51592978E-11 0.00000000E+00 3.05899079E-14 2.10387203E-07 1.26251229E-20 +-2.09623588E-07-2.28855655E-22-9.41028879E-06 0.00000000E+00 2.13653128E-06 + 0.00000000E+00 1.48371365E-05 4.48698372E-11 3.80024474E-08-1.70995149E-14 + 0.00000000E+00 5.55253802E-11 0.00000000E+00 1.70042983E-14-1.30100634E-05 +-1.31984306E-20 7.80178745E-08 7.40888381E-23 1.29091637E-04 0.00000000E+00 +-7.75504011E-07 0.00000000E+00-1.41385926E-04-4.32195831E-10 0.00000000E+00 +-5.33598173E-10-2.11339860E-03-3.55127505E-18-1.32059932E-05-2.10928737E-20 + 2.20963261E-02 0.00000000E+00 1.37781809E-04 0.00000000E+00 2.69199655E-03 + 8.72342846E-09 3.04541913E-03 9.54955325E-09 0.00000000E+00 1.06239722E-08 + 0.00000000E+00 1.17182876E-08-1.21220171E-02-1.10124393E-17 2.10387203E-07 + 1.26251229E-20 1.23487430E-01 0.00000000E+00-9.41028879E-06 0.00000000E+00 + 2.84485003E-03 8.64418136E-09-1.35508610E-04-4.35277222E-10 0.00000000E+00 + 1.06851002E-08 0.00000000E+00-5.31268476E-10-2.08216485E-03-1.99250507E-18 + 1.30256966E-05 1.16577281E-20 2.06973251E-02 0.00000000E+00-1.29709718E-04 + 0.00000000E+00 0.00000000E+00 1.33735708E-14-3.83245204E-08-2.27123608E-14 +-1.38513321E-04 0.00000000E+00-8.27925013E-07 0.00000000E+00 1.32203969E-05 +-2.33206372E-20 7.91886548E-08-1.33139682E-22 0.00000000E+00-5.51592978E-11 + 0.00000000E+00 3.05899079E-14 1.39211144E-05-4.53450760E-11-7.63349838E-08 +-3.94445105E-14-9.41028879E-06 0.00000000E+00 2.13653128E-06 0.00000000E+00 + 2.10387203E-07-1.26251229E-20-2.09623588E-07 2.28855655E-22 0.00000000E+00 + 5.55253802E-11 0.00000000E+00 1.70042983E-14-1.48371365E-05 4.48698372E-11 +-3.80024474E-08-1.70995149E-14 1.29091637E-04 0.00000000E+00-7.75504011E-07 + 0.00000000E+00-1.30100634E-05 1.31984306E-20 7.80178745E-08-7.40888381E-23 + 0.00000000E+00-5.33598173E-10 1.41385926E-04-4.32195831E-10 2.20963261E-02 + 0.00000000E+00 1.37781809E-04 0.00000000E+00-2.11339860E-03 3.55127505E-18 +-1.32059932E-05 2.10928737E-20 0.00000000E+00 1.06239722E-08 0.00000000E+00 + 1.17182876E-08-2.69199655E-03 8.72342846E-09-3.04541913E-03 9.54955325E-09 + 1.23487430E-01 0.00000000E+00-9.41028879E-06 0.00000000E+00-1.21220171E-02 + 1.10124393E-17 2.10387203E-07-1.26251229E-20 0.00000000E+00 1.06851002E-08 + 0.00000000E+00-5.31268476E-10-2.84485003E-03 8.64418136E-09 1.35508610E-04 +-4.35277222E-10 2.06973251E-02 0.00000000E+00-1.29709718E-04 0.00000000E+00 +-2.08216485E-03 1.99250507E-18 1.30256966E-05-1.16577281E-20-1.12704994E-04 +-2.89433031E-19-5.61491442E-04 0.00000000E+00 1.25153396E-04 4.41818615E-10 +-3.83245204E-08 2.27123608E-14 0.00000000E+00 5.27935488E-10 0.00000000E+00 +-1.33735708E-14 2.43375017E-04 6.32968876E-19 9.74511282E-04 2.54444613E-18 + 1.16781088E-03 0.00000000E+00 4.67122038E-03 0.00000000E+00-3.04541913E-03 +-9.54955325E-09-7.63349838E-08 3.94445105E-14 0.00000000E+00-1.17182876E-08 + 0.00000000E+00-3.05899079E-14 2.43374580E-04 6.31921622E-19-1.31378292E-04 +-3.51002738E-19 1.16780757E-03 0.00000000E+00-6.06306212E-04 0.00000000E+00 + 1.51605077E-04 4.28032469E-10-3.80024474E-08 1.70995149E-14 0.00000000E+00 + 5.38469503E-10 0.00000000E+00-1.70042983E-14 2.43374580E-04 6.31921622E-19 + 1.16780757E-03 0.00000000E+00-2.84485003E-03-8.64418136E-09-1.48371365E-05 +-4.48698372E-11 0.00000000E+00-1.06851002E-08 0.00000000E+00-5.55253802E-11 + 2.10124433E-03 5.53047307E-18 2.82138588E-04 7.72089328E-19 9.70091323E-03 + 0.00000000E+00 1.25741728E-03 0.00000000E+00-2.89752942E-03-8.62046978E-09 + 1.49891463E-05 4.48014391E-11 0.00000000E+00-1.07086662E-08 0.00000000E+00 + 5.55933974E-11 1.16780757E-03 0.00000000E+00 2.43374580E-04-6.31921622E-19 + 0.00000000E+00-1.06851002E-08 0.00000000E+00-5.55253802E-11 2.84485003E-03 +-8.64418136E-09 1.48371365E-05-4.48698372E-11 9.70091323E-03 0.00000000E+00 + 1.25741728E-03 0.00000000E+00 2.10124433E-03-5.53047307E-18 2.82138588E-04 +-7.72089328E-19 0.00000000E+00-1.07086662E-08 0.00000000E+00 5.55933974E-11 + 2.89752942E-03-8.62046978E-09-1.49891463E-05 4.48014391E-11-6.06306212E-04 + 0.00000000E+00-1.31378292E-04 3.51002738E-19 0.00000000E+00 5.31268476E-10 + 0.00000000E+00-1.70042983E-14-1.35508610E-04 4.35277222E-10 3.80024474E-08 + 1.70995149E-14 1.25741728E-03 0.00000000E+00 5.02964385E-03 0.00000000E+00 + 2.82138588E-04-7.72089328E-19 1.12956210E-03-3.28844099E-18 0.00000000E+00 +-1.18189280E-08 0.00000000E+00-3.70281006E-14 3.27076562E-03-9.44788919E-09 + 7.56466487E-08 2.94407191E-14 1.25741363E-03 0.00000000E+00-6.51096662E-04 + 0.00000000E+00 2.82138175E-04-8.11303685E-19-1.51466120E-04 5.34741855E-19 + 0.00000000E+00 5.44058945E-10 0.00000000E+00-1.98911406E-14-1.61730357E-04 + 4.24993099E-10 3.76634793E-08 1.25978857E-14 2.82138175E-04 8.11303685E-19 + 1.25741363E-03 0.00000000E+00-3.04903069E-03-8.56134845E-09-1.58970706E-05 +-4.44468673E-11 0.00000000E+00-1.07827550E-08 0.00000000E+00-5.60371871E-11 + 2.42265246E-03 8.75789359E-18 3.23726305E-04 1.32766374E-18 1.04175612E-02 + 0.00000000E+00 1.34697302E-03 0.00000000E+00-3.10123950E-03-8.54387892E-09 + 1.60477245E-05 4.43964758E-11 0.00000000E+00-1.08103240E-08 0.00000000E+00 + 5.61167517E-11 1.25741363E-03 0.00000000E+00 2.82138175E-04-8.11303685E-19 + 0.00000000E+00-1.07827550E-08 0.00000000E+00-5.60371871E-11 3.04903069E-03 +-8.56134845E-09 1.58970706E-05-4.44468673E-11 1.04175612E-02 0.00000000E+00 + 1.34697302E-03 0.00000000E+00 2.42265246E-03-8.75789359E-18 3.23726305E-04 +-1.32766374E-18 0.00000000E+00-1.08103240E-08 0.00000000E+00 5.61167517E-11 + 3.10123950E-03-8.54387892E-09-1.60477245E-05 4.43964758E-11 3.80024474E-08 +-1.70995149E-14 0.00000000E+00 1.70042983E-14 1.30256966E-05 1.16577281E-20 + 7.80178745E-08 7.40888381E-23-1.29709718E-04 0.00000000E+00-7.75504011E-07 + 0.00000000E+00-1.49891463E-05-4.48014391E-11 7.56466487E-08-2.94407191E-14 + 0.00000000E+00-5.55933974E-11 0.00000000E+00 3.70281006E-14 2.28020220E-07 +-3.43926934E-20-2.06371427E-07-4.29616696E-22-7.98964483E-06 0.00000000E+00 + 2.00757411E-06 0.00000000E+00 1.58970706E-05 4.44468673E-11 3.76634793E-08 +-1.25978857E-14 0.00000000E+00 5.60371871E-11 0.00000000E+00 1.98911406E-14 +-1.27977089E-05-4.29202180E-20 7.67488761E-08 2.51698641E-22 1.21711757E-04 + 0.00000000E+00-7.31002786E-07 0.00000000E+00-1.51605077E-04-4.28032469E-10 + 0.00000000E+00-5.38469503E-10-2.08216485E-03-1.99250507E-18-1.30100634E-05 +-1.31984306E-20 2.06973251E-02 0.00000000E+00 1.29091637E-04 0.00000000E+00 + 2.89752942E-03 8.62046978E-09 3.27076562E-03 9.44788919E-09 0.00000000E+00 + 1.07086662E-08 0.00000000E+00 1.18189280E-08-1.19340750E-02-2.46532340E-17 + 2.28020220E-07-3.43926934E-20 1.16042443E-01 0.00000000E+00-7.98964483E-06 + 0.00000000E+00 3.04903069E-03 8.56134845E-09-1.45777630E-04-4.30330663E-10 + 0.00000000E+00 1.07827550E-08 0.00000000E+00-5.35634828E-10-2.04830933E-03 +-6.70620426E-18 1.28146407E-05 4.09783729E-20 1.95097008E-02 0.00000000E+00 +-1.22238909E-04 0.00000000E+00 0.00000000E+00 1.70042983E-14-3.80024474E-08 +-1.70995149E-14-1.29709718E-04 0.00000000E+00-7.75504011E-07 0.00000000E+00 + 1.30256966E-05-1.16577281E-20 7.80178745E-08-7.40888381E-23 0.00000000E+00 +-5.55933974E-11 0.00000000E+00 3.70281006E-14 1.49891463E-05-4.48014391E-11 +-7.56466487E-08-2.94407191E-14-7.98964483E-06 0.00000000E+00 2.00757411E-06 + 0.00000000E+00 2.28020220E-07 3.43926934E-20-2.06371427E-07 4.29616696E-22 + 0.00000000E+00 5.60371871E-11 0.00000000E+00 1.98911406E-14-1.58970706E-05 + 4.44468673E-11-3.76634793E-08-1.25978857E-14 1.21711757E-04 0.00000000E+00 +-7.31002786E-07 0.00000000E+00-1.27977089E-05 4.29202180E-20 7.67488761E-08 +-2.51698641E-22 0.00000000E+00-5.38469503E-10 1.51605077E-04-4.28032469E-10 + 2.06973251E-02 0.00000000E+00 1.29091637E-04 0.00000000E+00-2.08216485E-03 + 1.99250507E-18-1.30100634E-05 1.31984306E-20 0.00000000E+00 1.07086662E-08 + 0.00000000E+00 1.18189280E-08-2.89752942E-03 8.62046978E-09-3.27076562E-03 + 9.44788919E-09 1.16042443E-01 0.00000000E+00-7.98964483E-06 0.00000000E+00 +-1.19340750E-02 2.46532340E-17 2.28020220E-07 3.43926934E-20 0.00000000E+00 + 1.07827550E-08 0.00000000E+00-5.35634828E-10-3.04903069E-03 8.56134845E-09 + 1.45777630E-04-4.30330663E-10 1.95097008E-02 0.00000000E+00-1.22238909E-04 + 0.00000000E+00-2.04830933E-03 6.70620426E-18 1.28146407E-05-4.09783729E-20 +-1.31378292E-04-3.51002738E-19-6.06306212E-04 0.00000000E+00 1.35508610E-04 + 4.35277222E-10-3.80024474E-08 1.70995149E-14 0.00000000E+00 5.31268476E-10 + 0.00000000E+00-1.70042983E-14 2.82138588E-04 7.72089328E-19 1.12956210E-03 + 3.28844099E-18 1.25741728E-03 0.00000000E+00 5.02964385E-03 0.00000000E+00 +-3.27076562E-03-9.44788919E-09-7.56466487E-08 2.94407191E-14 0.00000000E+00 +-1.18189280E-08 0.00000000E+00-3.70281006E-14 2.82138175E-04 8.11303685E-19 +-1.51466120E-04-5.34741855E-19 1.25741363E-03 0.00000000E+00-6.51096662E-04 + 0.00000000E+00 1.61730357E-04 4.24993099E-10-3.76634793E-08 1.25978857E-14 + 0.00000000E+00 5.44058945E-10 0.00000000E+00-1.98911406E-14 3.23725834E-04 + 1.26781654E-18 1.34696922E-03 0.00000000E+00-3.25129741E-03-8.50102492E-09 +-1.69469912E-05-4.41394323E-11 0.00000000E+00-1.08947944E-08 0.00000000E+00 +-5.66227794E-11 2.76661534E-03 7.12396288E-18 3.68128609E-04 5.55190955E-19 + 1.11337972E-02 0.00000000E+00 1.43647611E-03 0.00000000E+00-3.30297491E-03 +-8.48864151E-09 1.70961088E-05 4.41037132E-11 0.00000000E+00-1.09255909E-08 + 0.00000000E+00 5.67116540E-11-6.51096662E-04 0.00000000E+00-1.51466120E-04 + 5.34741855E-19 0.00000000E+00 5.35634828E-10 0.00000000E+00-1.98911406E-14 +-1.45777630E-04 4.30330663E-10 3.76634793E-08 1.25978857E-14 1.34697302E-03 + 0.00000000E+00 5.38786570E-03 0.00000000E+00 3.23726305E-04-1.32766374E-18 + 1.29590944E-03-4.78018708E-18 0.00000000E+00-1.19367238E-08 0.00000000E+00 +-4.21896101E-14 3.49407780E-03-9.37297692E-09 7.49263645E-08 2.13507344E-14 + 1.34696922E-03 0.00000000E+00-6.95861334E-04 0.00000000E+00 3.23725834E-04 +-1.26781654E-18-1.72963611E-04 4.55751874E-19 0.00000000E+00 5.50230901E-10 + 0.00000000E+00-2.22186487E-14-1.71749043E-04 4.22875503E-10 3.72793919E-08 + 8.92976643E-15 3.76634793E-08-1.25978857E-14 0.00000000E+00 1.98911406E-14 + 1.28146407E-05 4.09783729E-20 7.67488761E-08 2.51698641E-22-1.22238909E-04 + 0.00000000E+00-7.31002786E-07 0.00000000E+00-1.60477245E-05-4.43964758E-11 + 7.49263645E-08-2.13507344E-14 0.00000000E+00-5.61167517E-11 0.00000000E+00 + 4.21896101E-14 2.46097715E-07 2.32231158E-21-2.02853091E-07-7.06928642E-22 +-6.84203184E-06 0.00000000E+00 1.89763750E-06 0.00000000E+00 1.69469912E-05 + 4.41394323E-11 3.72793919E-08-8.92976643E-15 0.00000000E+00 5.66227794E-11 + 0.00000000E+00 2.22186487E-14-1.25685853E-05-3.95345132E-20 7.53793275E-08 + 2.42638388E-22 1.15390673E-04 0.00000000E+00-6.92897588E-07 0.00000000E+00 +-1.61730357E-04-4.24993099E-10 0.00000000E+00-5.44058945E-10-2.04830933E-03 +-6.70620426E-18-1.27977089E-05-4.29202180E-20 1.95097008E-02 0.00000000E+00 + 1.21711757E-04 0.00000000E+00 3.10123950E-03 8.54387892E-09 3.49407780E-03 + 9.37297692E-09 0.00000000E+00 1.08103240E-08 0.00000000E+00 1.19367238E-08 +-1.17306786E-02-4.31229726E-17 2.46097715E-07 2.32231158E-21 1.09694486E-01 + 0.00000000E+00-6.84203184E-06 0.00000000E+00 3.25129741E-03 8.50102492E-09 +-1.55958714E-04-4.26659052E-10 0.00000000E+00 1.08947944E-08 0.00000000E+00 +-5.40820677E-10-2.01176991E-03-6.47188920E-18 1.25867966E-05 4.14052631E-20 + 1.84927822E-02 0.00000000E+00-1.15843841E-04 0.00000000E+00 0.00000000E+00 + 1.98911406E-14-3.76634793E-08-1.25978857E-14-1.22238909E-04 0.00000000E+00 +-7.31002786E-07 0.00000000E+00 1.28146407E-05-4.09783729E-20 7.67488761E-08 +-2.51698641E-22 0.00000000E+00-5.61167517E-11 0.00000000E+00 4.21896101E-14 + 1.60477245E-05-4.43964758E-11-7.49263645E-08-2.13507344E-14-6.84203184E-06 + 0.00000000E+00 1.89763750E-06 0.00000000E+00 2.46097715E-07-2.32231158E-21 +-2.02853091E-07 7.06928642E-22 0.00000000E+00 5.66227794E-11 0.00000000E+00 + 2.22186487E-14-1.69469912E-05 4.41394323E-11-3.72793919E-08-8.92976643E-15 + 1.15390673E-04 0.00000000E+00-6.92897588E-07 0.00000000E+00-1.25685853E-05 + 3.95345132E-20 7.53793275E-08-2.42638388E-22 0.00000000E+00-5.44058945E-10 + 1.61730357E-04-4.24993099E-10 1.95097008E-02 0.00000000E+00 1.21711757E-04 + 0.00000000E+00-2.04830933E-03 6.70620426E-18-1.27977089E-05 4.29202180E-20 + 0.00000000E+00 1.08103240E-08 0.00000000E+00 1.19367238E-08-3.10123950E-03 + 8.54387892E-09-3.49407780E-03 9.37297692E-09 1.09694486E-01 0.00000000E+00 +-6.84203184E-06 0.00000000E+00-1.17306786E-02 4.31229726E-17 2.46097715E-07 +-2.32231158E-21 0.00000000E+00 1.08947944E-08 0.00000000E+00-5.40820677E-10 +-3.25129741E-03 8.50102492E-09 1.55958714E-04-4.26659052E-10 1.84927822E-02 + 0.00000000E+00-1.15843841E-04 0.00000000E+00-2.01176991E-03 6.47188920E-18 + 1.25867966E-05-4.14052631E-20-1.51466120E-04-5.34741855E-19-6.51096662E-04 + 0.00000000E+00 1.45777630E-04 4.30330663E-10-3.76634793E-08 1.25978857E-14 + 0.00000000E+00 5.35634828E-10 0.00000000E+00-1.98911406E-14 3.23726305E-04 + 1.32766374E-18 1.29590944E-03 4.78018708E-18 1.34697302E-03 0.00000000E+00 + 5.38786570E-03 0.00000000E+00-3.49407780E-03-9.37297692E-09-7.49263645E-08 + 2.13507344E-14 0.00000000E+00-1.19367238E-08 0.00000000E+00-4.21896101E-14 + 3.23725834E-04 1.26781654E-18-1.72963611E-04-4.55751874E-19 1.34696922E-03 + 0.00000000E+00-6.95861334E-04 0.00000000E+00 1.71749043E-04 4.22875503E-10 +-3.72793919E-08 8.92976643E-15 0.00000000E+00 5.50230901E-10 0.00000000E+00 +-2.22186487E-14 1.34696922E-03 0.00000000E+00 3.23725834E-04-1.26781654E-18 + 0.00000000E+00-1.08947944E-08 0.00000000E+00-5.66227794E-11 3.25129741E-03 +-8.50102492E-09 1.69469912E-05-4.41394323E-11 1.11337972E-02 0.00000000E+00 + 1.43647611E-03 0.00000000E+00 2.76661534E-03-7.12396288E-18 3.68128609E-04 +-5.55190955E-19 0.00000000E+00-1.09255909E-08 0.00000000E+00 5.67116540E-11 + 3.30297491E-03-8.48864151E-09-1.70961088E-05 4.41037132E-11-6.95861334E-04 + 0.00000000E+00-1.72963611E-04 4.55751874E-19 0.00000000E+00 5.40820677E-10 + 0.00000000E+00-2.22186487E-14-1.55958714E-04 4.26659052E-10 3.72793919E-08 + 8.92976643E-15 1.43647611E-03 0.00000000E+00 5.74587562E-03 0.00000000E+00 + 3.68128609E-04-5.55190955E-19 1.47351440E-03-2.88704980E-18 0.00000000E+00 +-1.20683487E-08 0.00000000E+00-4.63769796E-14 3.71514080E-03-9.31985677E-09 + 7.41636163E-08 1.47074318E-14 1.43647205E-03 0.00000000E+00-7.40598244E-04 + 0.00000000E+00 3.68128129E-04-5.80810553E-19-1.95865443E-04 5.64275917E-19 + 0.00000000E+00 5.56880224E-10 0.00000000E+00-2.41170424E-14-1.81665586E-04 + 4.21524028E-10 3.68997951E-08 5.89839909E-15 3.72793919E-08-8.92976643E-15 + 0.00000000E+00 2.22186487E-14 1.25867966E-05 4.14052631E-20 7.53793275E-08 + 2.42638388E-22-1.15843841E-04 0.00000000E+00-6.92897588E-07 0.00000000E+00 +-1.70961088E-05-4.41037132E-11 7.41636163E-08-1.47074318E-14 0.00000000E+00 +-5.67116540E-11 0.00000000E+00 4.63769796E-14 2.64495715E-07 1.79145733E-20 +-1.99065335E-07-4.98100924E-22-5.90087459E-06 0.00000000E+00 1.80317145E-06 + 0.00000000E+00 1.79862208E-05 4.39267051E-11 3.68997951E-08-5.89839909E-15 + 0.00000000E+00 5.72681494E-11 0.00000000E+00 2.41170424E-14-1.23223407E-05 +-2.37876803E-20 7.39073918E-08 1.44172742E-22 1.09938252E-04 0.00000000E+00 +-6.60036696E-07 0.00000000E+00-1.71749043E-04-4.22875503E-10 0.00000000E+00 +-5.50230901E-10-2.01176991E-03-6.47188920E-18-1.25685853E-05-3.95345132E-20 + 1.84927822E-02 0.00000000E+00 1.15390673E-04 0.00000000E+00 3.30297491E-03 + 8.48864151E-09 3.71514080E-03 9.31985677E-09 0.00000000E+00 1.09255909E-08 + 0.00000000E+00 1.20683487E-08-1.15117617E-02-2.78217796E-17 2.64495715E-07 + 1.79145733E-20 1.04238974E-01 0.00000000E+00-5.90087459E-06 0.00000000E+00 + 3.45150634E-03 8.45913781E-09-1.66036261E-04-4.24023350E-10 0.00000000E+00 + 1.10184801E-08 0.00000000E+00-5.46665712E-10-1.97249744E-03-3.84820126E-18 + 1.23419019E-05 2.43289212E-20 1.76158288E-02 0.00000000E+00-1.10330270E-04 + 0.00000000E+00 0.00000000E+00 2.22186487E-14-3.72793919E-08-8.92976643E-15 +-1.15843841E-04 0.00000000E+00-6.92897588E-07 0.00000000E+00 1.25867966E-05 +-4.14052631E-20 7.53793275E-08-2.42638388E-22 0.00000000E+00-5.67116540E-11 + 0.00000000E+00 4.63769796E-14 1.70961088E-05-4.41037132E-11-7.41636163E-08 +-1.47074318E-14-5.90087459E-06 0.00000000E+00 1.80317145E-06 0.00000000E+00 + 2.64495715E-07-1.79145733E-20-1.99065335E-07 4.98100924E-22 0.00000000E+00 + 5.72681494E-11 0.00000000E+00 2.41170424E-14-1.79862208E-05 4.39267051E-11 +-3.68997951E-08-5.89839909E-15 1.09938252E-04 0.00000000E+00-6.60036696E-07 + 0.00000000E+00-1.23223407E-05 2.37876803E-20 7.39073918E-08-1.44172742E-22 + 0.00000000E+00-5.50230901E-10 1.71749043E-04-4.22875503E-10 1.84927822E-02 + 0.00000000E+00 1.15390673E-04 0.00000000E+00-2.01176991E-03 6.47188920E-18 +-1.25685853E-05 3.95345132E-20 0.00000000E+00 1.09255909E-08 0.00000000E+00 + 1.20683487E-08-3.30297491E-03 8.48864151E-09-3.71514080E-03 9.31985677E-09 + 1.04238974E-01 0.00000000E+00-5.90087459E-06 0.00000000E+00-1.15117617E-02 + 2.78217796E-17 2.64495715E-07-1.79145733E-20 0.00000000E+00 1.10184801E-08 + 0.00000000E+00-5.46665712E-10-3.45150634E-03 8.45913781E-09 1.66036261E-04 +-4.24023350E-10 1.76158288E-02 0.00000000E+00-1.10330270E-04 0.00000000E+00 +-1.97249744E-03 3.84820126E-18 1.23419019E-05-2.43289212E-20-1.72963611E-04 +-4.55751874E-19-6.95861334E-04 0.00000000E+00 1.55958714E-04 4.26659052E-10 +-3.72793919E-08 8.92976643E-15 0.00000000E+00 5.40820677E-10 0.00000000E+00 +-2.22186487E-14 3.68128609E-04 5.55190955E-19 1.47351440E-03 2.88704980E-18 + 1.43647611E-03 0.00000000E+00 5.74587562E-03 0.00000000E+00-3.71514080E-03 +-9.31985677E-09-7.41636163E-08 1.47074318E-14 0.00000000E+00-1.20683487E-08 + 0.00000000E+00-4.63769796E-14 3.68128129E-04 5.80810553E-19-1.95865443E-04 +-5.64275917E-19 1.43647205E-03 0.00000000E+00-7.40598244E-04 0.00000000E+00 + 1.81665586E-04 4.21524028E-10-3.68997951E-08 5.89839909E-15 0.00000000E+00 + 5.56880224E-10 0.00000000E+00-2.41170424E-14 3.68128129E-04 5.80810553E-19 + 1.43647205E-03 0.00000000E+00-3.45150634E-03-8.45913781E-09-1.79862208E-05 +-4.39267051E-11 0.00000000E+00-1.10184801E-08 0.00000000E+00-5.72681494E-11 + 3.13304813E-03 8.92048627E-18 4.15333644E-04 1.67629312E-18 1.18495888E-02 + 0.00000000E+00 1.52592093E-03 0.00000000E+00-3.50265672E-03-8.45095751E-09 + 1.81338199E-05 4.39031115E-11 0.00000000E+00-1.10519090E-08 0.00000000E+00 + 5.73646176E-11 1.43647205E-03 0.00000000E+00 3.68128129E-04-5.80810553E-19 + 0.00000000E+00-1.10184801E-08 0.00000000E+00-5.72681494E-11 3.45150634E-03 +-8.45913781E-09 1.79862208E-05-4.39267051E-11 1.18495888E-02 0.00000000E+00 + 1.52592093E-03 0.00000000E+00 3.13304813E-03-8.92048627E-18 4.15333644E-04 +-1.67629312E-18 0.00000000E+00-1.10519090E-08 0.00000000E+00 5.73646176E-11 + 3.50265672E-03-8.45095751E-09-1.81338199E-05 4.39031115E-11-7.40598244E-04 + 0.00000000E+00-1.95865443E-04 5.64275917E-19 0.00000000E+00 5.46665712E-10 + 0.00000000E+00-2.41170424E-14-1.66036261E-04 4.24023350E-10 3.68997951E-08 + 5.89839909E-15 1.52592093E-03 0.00000000E+00 6.10365349E-03 0.00000000E+00 + 4.15333644E-04-1.67629312E-18 1.66233002E-03-6.43442002E-18 0.00000000E+00 +-1.22112503E-08 0.00000000E+00-4.98096972E-14 3.93392151E-03-9.28474198E-09 + 7.33441126E-08 9.18088977E-15 1.52591665E-03 0.00000000E+00-7.85305380E-04 + 0.00000000E+00 4.15333043E-04-1.76402520E-18-2.20165578E-04 8.35961293E-19 + 0.00000000E+00 5.63923989E-10 0.00000000E+00-2.56797500E-14-1.91459882E-04 + 4.20816698E-10 3.64622149E-08 3.36201191E-15 4.15333043E-04 1.76402520E-18 + 1.52591665E-03 0.00000000E+00-3.64955124E-03-8.43255509E-09-1.90141172E-05 +-4.37926529E-11 0.00000000E+00-1.11516971E-08 0.00000000E+00-5.79624676E-11 + 3.52185359E-03 1.38755457E-17 4.65329269E-04 1.57981997E-18 1.25649040E-02 + 0.00000000E+00 1.61530488E-03 0.00000000E+00-3.70009598E-03-8.42789154E-09 + 1.91599660E-05 4.37792048E-11 0.00000000E+00-1.11872928E-08 0.00000000E+00 + 5.80651866E-11 1.52591665E-03 0.00000000E+00 4.15333043E-04-1.76402520E-18 + 0.00000000E+00-1.11516971E-08 0.00000000E+00-5.79624676E-11 3.64955124E-03 +-8.43255509E-09 1.90141172E-05-4.37926529E-11 1.25649040E-02 0.00000000E+00 + 1.61530488E-03 0.00000000E+00 3.52185359E-03-1.38755457E-17 4.65329269E-04 +-1.57981997E-18 0.00000000E+00-1.11872928E-08 0.00000000E+00 5.80651866E-11 + 3.70009598E-03-8.42789154E-09-1.91599660E-05 4.37792048E-11 3.68997951E-08 +-5.89839909E-15 0.00000000E+00 2.41170424E-14 1.23419019E-05 2.43289212E-20 + 7.39073918E-08 1.44172742E-22-1.10330270E-04 0.00000000E+00-6.60036696E-07 + 0.00000000E+00-1.81338199E-05-4.39031115E-11 7.33441126E-08-9.18088977E-15 + 0.00000000E+00-5.73646176E-11 0.00000000E+00 4.98096972E-14 2.83345973E-07 + 1.26415898E-20-1.95000192E-07-3.01744738E-22-5.11907894E-06 0.00000000E+00 + 1.72147256E-06 0.00000000E+00 1.90141172E-05 4.37926529E-11 3.64622149E-08 +-3.36201191E-15 0.00000000E+00 5.79624676E-11 0.00000000E+00 2.56797500E-14 +-1.20585864E-05-1.33545378E-20 7.23305194E-08 8.13119891E-23 1.05207588E-04 + 0.00000000E+00-6.31531561E-07 0.00000000E+00-1.81665586E-04-4.21524028E-10 + 0.00000000E+00-5.56880224E-10-1.97249744E-03-3.84820126E-18-1.23223407E-05 +-2.37876803E-20 1.76158288E-02 0.00000000E+00 1.09938252E-04 0.00000000E+00 + 3.50265672E-03 8.45095751E-09 3.93392151E-03 9.28474198E-09 0.00000000E+00 + 1.10519090E-08 0.00000000E+00 1.22112503E-08-1.12767511E-02-1.77022987E-17 + 2.83345973E-07 1.26415898E-20 9.95203325E-02 0.00000000E+00-5.11907894E-06 + 0.00000000E+00 3.64955124E-03 8.43255509E-09-1.76015660E-04-4.22241502E-10 + 0.00000000E+00 1.11516971E-08 0.00000000E+00-5.53047405E-10-1.93042383E-03 +-2.18145898E-18 1.20794945E-05 1.38789059E-20 1.68551253E-02 0.00000000E+00 +-1.05548562E-04 0.00000000E+00 0.00000000E+00 2.41170424E-14-3.68997951E-08 +-5.89839909E-15-1.10330270E-04 0.00000000E+00-6.60036696E-07 0.00000000E+00 + 1.23419019E-05-2.43289212E-20 7.39073918E-08-1.44172742E-22 0.00000000E+00 +-5.73646176E-11 0.00000000E+00 4.98096972E-14 1.81338199E-05-4.39031115E-11 +-7.33441126E-08-9.18088977E-15-5.11907894E-06 0.00000000E+00 1.72147256E-06 + 0.00000000E+00 2.83345973E-07-1.26415898E-20-1.95000192E-07 3.01744738E-22 + 0.00000000E+00 5.79624676E-11 0.00000000E+00 2.56797500E-14-1.90141172E-05 + 4.37926529E-11-3.64622149E-08-3.36201191E-15 1.05207588E-04 0.00000000E+00 +-6.31531561E-07 0.00000000E+00-1.20585864E-05 1.33545378E-20 7.23305194E-08 +-8.13119891E-23 0.00000000E+00-5.56880224E-10 1.81665586E-04-4.21524028E-10 + 1.76158288E-02 0.00000000E+00 1.09938252E-04 0.00000000E+00-1.97249744E-03 + 3.84820126E-18-1.23223407E-05 2.37876803E-20 0.00000000E+00 1.10519090E-08 + 0.00000000E+00 1.22112503E-08-3.50265672E-03 8.45095751E-09-3.93392151E-03 + 9.28474198E-09 9.95203325E-02 0.00000000E+00-5.11907894E-06 0.00000000E+00 +-1.12767511E-02 1.77022987E-17 2.83345973E-07-1.26415898E-20 0.00000000E+00 + 1.11516971E-08 0.00000000E+00-5.53047405E-10-3.64955124E-03 8.43255509E-09 + 1.76015660E-04-4.22241502E-10 1.68551253E-02 0.00000000E+00-1.05548562E-04 + 0.00000000E+00-1.93042383E-03 2.18145898E-18 1.20794945E-05-1.38789059E-20 +-1.95865443E-04-5.64275917E-19-7.40598244E-04 0.00000000E+00 1.66036261E-04 + 4.24023350E-10-3.68997951E-08 5.89839909E-15 0.00000000E+00 5.46665712E-10 + 0.00000000E+00-2.41170424E-14 4.15333644E-04 1.67629312E-18 1.66233002E-03 + 6.43442002E-18 1.52592093E-03 0.00000000E+00 6.10365349E-03 0.00000000E+00 +-3.93392151E-03-9.28474198E-09-7.33441126E-08 9.18088977E-15 0.00000000E+00 +-1.22112503E-08 0.00000000E+00-4.98096972E-14 4.15333043E-04 1.76402520E-18 +-2.20165578E-04-8.35961293E-19 1.52591665E-03 0.00000000E+00-7.85305380E-04 + 0.00000000E+00 1.91459882E-04 4.20816698E-10-3.64622149E-08 3.36201191E-15 + 0.00000000E+00 5.63923989E-10 0.00000000E+00-2.56797500E-14 4.65328646E-04 + 1.33246043E-18 1.61530033E-03 0.00000000E+00-3.84521018E-03-8.41883253E-09 +-2.00295875E-05-4.37247553E-11 0.00000000E+00-1.12927844E-08 0.00000000E+00 +-5.86972220E-11 3.93293580E-03 8.91777861E-18 5.18103266E-04 1.10082855E-18 + 1.32797144E-02 0.00000000E+00 1.70462352E-03 0.00000000E+00-3.89512752E-03 +-8.41714598E-09 2.01736269E-05 4.37198958E-11 0.00000000E+00-1.13301786E-08 + 0.00000000E+00 5.88051293E-11-7.85305380E-04 0.00000000E+00-2.20165578E-04 + 8.35961293E-19 0.00000000E+00 5.53047405E-10 0.00000000E+00-2.56797500E-14 +-1.76015660E-04 4.22241502E-10 3.64622149E-08 3.36201191E-15 1.61530488E-03 + 0.00000000E+00 6.46118722E-03 0.00000000E+00 4.65329269E-04-1.57981997E-18 + 1.86230810E-03-5.81810205E-18 0.00000000E+00-1.23634338E-08 0.00000000E+00 +-5.26484579E-14 4.15013013E-03-9.26469057E-09 7.24546433E-08 4.52753388E-15 + 1.61530033E-03 0.00000000E+00-8.29980962E-04 0.00000000E+00 4.65328646E-04 +-1.33246043E-18-2.45857978E-04 6.08322244E-19 0.00000000E+00 5.71296242E-10 + 0.00000000E+00-2.69768252E-14-2.01131067E-04 4.20657123E-10 3.60098416E-08 + 1.21486113E-15 3.64622149E-08-3.36201191E-15 0.00000000E+00 2.56797500E-14 + 1.20794945E-05 1.38789059E-20 7.23305194E-08 8.13119891E-23-1.05548562E-04 + 0.00000000E+00-6.31531561E-07 0.00000000E+00-1.91599660E-05-4.37792048E-11 + 7.24546433E-08-4.52753388E-15 0.00000000E+00-5.80651866E-11 0.00000000E+00 + 5.26484579E-14 3.02635863E-07-1.80826479E-20-1.90652855E-07-3.03340164E-22 +-4.46217208E-06 0.00000000E+00 1.65043337E-06 0.00000000E+00 2.00295875E-05 + 4.37247553E-11 3.60098416E-08-1.21486113E-15 0.00000000E+00 5.86972220E-11 + 0.00000000E+00 2.69768252E-14-1.17768914E-05-2.87671283E-20 7.06463208E-08 + 1.67578564E-22 1.01083591E-04 0.00000000E+00-6.06685783E-07 0.00000000E+00 +-1.91459882E-04-4.20816698E-10 0.00000000E+00-5.63923989E-10-1.93042383E-03 +-2.18145898E-18-1.20585864E-05-1.33545378E-20 1.68551253E-02 0.00000000E+00 + 1.05207588E-04 0.00000000E+00 3.70009598E-03 8.42789154E-09 4.15013013E-03 + 9.26469057E-09 0.00000000E+00 1.11872928E-08 0.00000000E+00 1.23634338E-08 +-1.10254615E-02-1.61178246E-17 3.02635863E-07-1.80826479E-20 9.54169155E-02 + 0.00000000E+00-4.46217208E-06 0.00000000E+00 3.84521018E-03 8.41883253E-09 +-1.85878524E-04-4.21172319E-10 0.00000000E+00 1.12927844E-08 0.00000000E+00 +-5.59870131E-10-1.88548525E-03-4.46330207E-18 1.17992074E-05 2.70774355E-20 + 1.61920851E-02 0.00000000E+00-1.01381395E-04 0.00000000E+00 0.00000000E+00 + 2.56797500E-14-3.64622149E-08-3.36201191E-15-1.05548562E-04 0.00000000E+00 +-6.31531561E-07 0.00000000E+00 1.20794945E-05-1.38789059E-20 7.23305194E-08 +-8.13119891E-23 0.00000000E+00-5.80651866E-11 0.00000000E+00 5.26484579E-14 + 1.91599660E-05-4.37792048E-11-7.24546433E-08-4.52753388E-15-4.46217208E-06 + 0.00000000E+00 1.65043337E-06 0.00000000E+00 3.02635863E-07 1.80826479E-20 +-1.90652855E-07 3.03340164E-22 0.00000000E+00 5.86972220E-11 0.00000000E+00 + 2.69768252E-14-2.00295875E-05 4.37247553E-11-3.60098416E-08-1.21486113E-15 + 1.01083591E-04 0.00000000E+00-6.06685783E-07 0.00000000E+00-1.17768914E-05 + 2.87671283E-20 7.06463208E-08-1.67578564E-22 0.00000000E+00-5.63923989E-10 + 1.91459882E-04-4.20816698E-10 1.68551253E-02 0.00000000E+00 1.05207588E-04 + 0.00000000E+00-1.93042383E-03 2.18145898E-18-1.20585864E-05 1.33545378E-20 + 0.00000000E+00 1.11872928E-08 0.00000000E+00 1.23634338E-08-3.70009598E-03 + 8.42789154E-09-4.15013013E-03 9.26469057E-09 9.54169155E-02 0.00000000E+00 +-4.46217208E-06 0.00000000E+00-1.10254615E-02 1.61178246E-17 3.02635863E-07 + 1.80826479E-20 0.00000000E+00 1.12927844E-08 0.00000000E+00-5.59870131E-10 +-3.84521018E-03 8.41883253E-09 1.85878524E-04-4.21172319E-10 1.61920851E-02 + 0.00000000E+00-1.01381395E-04 0.00000000E+00-1.88548525E-03 4.46330207E-18 + 1.17992074E-05-2.70774355E-20-2.20165578E-04-8.35961293E-19-7.85305380E-04 + 0.00000000E+00 1.76015660E-04 4.22241502E-10-3.64622149E-08 3.36201191E-15 + 0.00000000E+00 5.53047405E-10 0.00000000E+00-2.56797500E-14 4.65329269E-04 + 1.57981997E-18 1.86230810E-03 5.81810205E-18 1.61530488E-03 0.00000000E+00 + 6.46118722E-03 0.00000000E+00-4.15013013E-03-9.26469057E-09-7.24546433E-08 + 4.52753388E-15 0.00000000E+00-1.23634338E-08 0.00000000E+00-5.26484579E-14 + 4.65328646E-04 1.33246043E-18-2.45857978E-04-6.08322244E-19 1.61530033E-03 + 0.00000000E+00-8.29980962E-04 0.00000000E+00 2.01131067E-04 4.20657123E-10 +-3.60098416E-08 1.21486113E-15 0.00000000E+00 5.71296242E-10 0.00000000E+00 +-2.69768252E-14 1.61530033E-03 0.00000000E+00 4.65328646E-04-1.33246043E-18 + 0.00000000E+00-1.12927844E-08 0.00000000E+00-5.86972220E-11 3.84521018E-03 +-8.41883253E-09 2.00295875E-05-4.37247553E-11 1.32797144E-02 0.00000000E+00 + 1.70462352E-03 0.00000000E+00 3.93293580E-03-8.91777861E-18 5.18103266E-04 +-1.10082855E-18 0.00000000E+00-1.13301786E-08 0.00000000E+00 5.88051293E-11 + 3.89512752E-03-8.41714598E-09-2.01736269E-05 4.37198958E-11 2.53244666E-03 + 0.00000000E+00 1.50545947E-03-5.94667244E-18 0.00000000E+00-5.84038099E-09 + 0.00000000E+00-2.11816861E-11 5.21746461E-03-3.36586209E-09 2.04222387E-05 +-1.21835907E-11 2.04575987E-02 0.00000000E+00 2.58187679E-03 0.00000000E+00 + 1.22774934E-02-3.72822596E-17 1.56394277E-03-3.00650445E-18 0.00000000E+00 +-3.71809035E-09 0.00000000E+00 1.65705663E-11 5.23240712E-03-2.12750718E-09 +-2.04547256E-05 9.49294435E-12 8.12171887E-09-6.72661587E-13 0.00000000E+00 +-1.15277996E-12 9.33365335E-07 6.10268395E-21 4.15220418E-09 2.40507893E-23 +-4.28146000E-05 0.00000000E+00-1.93248788E-07 0.00000000E+00-2.04547256E-05 +-9.49294435E-12-5.12972217E-06-9.09743173E-13 0.00000000E+00-1.65705663E-11 + 0.00000000E+00-1.60945799E-12 1.44930552E-06 1.68956076E-21-5.27357790E-09 +-1.52774623E-23-7.24686450E-05 0.00000000E+00 2.57690883E-07 0.00000000E+00 +-2.63522233E-04 5.66630481E-11 0.00000000E+00 9.45310880E-11-1.95377825E-04 +-1.11875379E-18-9.06523131E-07-4.47018117E-21 9.09328764E-03 0.00000000E+00 + 4.28171506E-05 0.00000000E+00 5.23240712E-03 2.12750718E-09 2.88580788E-03 + 4.06561330E-10 0.00000000E+00 3.71809035E-09 0.00000000E+00 7.17366281E-10 +-5.06648427E-04 9.31171062E-19 1.44930552E-06 1.68956076E-21 2.62757109E-02 + 0.00000000E+00-7.24686450E-05 0.00000000E+00 0.00000000E+00-1.15277996E-12 +-8.12171887E-09-6.72661587E-13-4.28146000E-05 0.00000000E+00-1.93248788E-07 + 0.00000000E+00 9.33365335E-07-6.10268395E-21 4.15220418E-09-2.40507893E-23 + 0.00000000E+00-1.65705663E-11 0.00000000E+00-1.60945799E-12 2.04547256E-05 +-9.49294435E-12 5.12972217E-06-9.09743173E-13-7.24686450E-05 0.00000000E+00 + 2.57690883E-07 0.00000000E+00 1.44930552E-06-1.68956076E-21-5.27357790E-09 + 1.52774623E-23 0.00000000E+00 9.45310880E-11 2.63522233E-04 5.66630481E-11 + 9.09328764E-03 0.00000000E+00 4.28171506E-05 0.00000000E+00-1.95377825E-04 + 1.11875379E-18-9.06523131E-07 4.47018117E-21 0.00000000E+00 3.71809035E-09 + 0.00000000E+00 7.17366281E-10-5.23240712E-03 2.12750718E-09-2.88580788E-03 + 4.06561330E-10 2.62757109E-02 0.00000000E+00-7.24686450E-05 0.00000000E+00 +-5.06648427E-04-9.31171062E-19 1.44930552E-06-1.68956076E-21-7.67350560E-04 +-2.23829422E-18-1.27858086E-03 0.00000000E+00 2.58956100E-04 3.21710422E-10 +-8.12171887E-09 6.72661587E-13 0.00000000E+00 5.53922053E-10 0.00000000E+00 + 1.15277996E-12 1.56394277E-03 3.00650445E-18 3.11327565E-03 6.47297658E-18 + 2.58187679E-03 0.00000000E+00 5.15132050E-03 0.00000000E+00-2.88580788E-03 +-4.06561330E-10 5.12972217E-06 9.09743173E-13 0.00000000E+00-7.17366281E-10 + 0.00000000E+00 1.60945799E-12 1.50545947E-03 5.94667244E-18 2.53244666E-03 + 0.00000000E+00-5.21746461E-03-3.36586209E-09-2.04222387E-05-1.21835907E-11 + 0.00000000E+00-5.84038099E-09 0.00000000E+00-2.11816861E-11 1.22774934E-02 + 3.72822596E-17 1.56394277E-03 3.00650445E-18 2.04575987E-02 0.00000000E+00 + 2.58187679E-03 0.00000000E+00-5.23240712E-03-2.12750718E-09 2.04547256E-05 + 9.49294435E-12 0.00000000E+00-3.71809035E-09 0.00000000E+00 1.65705663E-11 +-1.27858086E-03 0.00000000E+00-7.67350560E-04 2.23829422E-18 0.00000000E+00 + 5.53922053E-10 0.00000000E+00 1.15277996E-12-2.58956100E-04 3.21710422E-10 + 8.12171887E-09 6.72661587E-13 2.58187679E-03 0.00000000E+00 5.15132050E-03 + 0.00000000E+00 1.56394277E-03-3.00650445E-18 3.11327565E-03-6.47297658E-18 + 0.00000000E+00-7.17366281E-10 0.00000000E+00 1.60945799E-12 2.88580788E-03 +-4.06561330E-10-5.12972217E-06 9.09743173E-13 8.57706455E-09-2.27572885E-13 + 0.00000000E+00-2.99442738E-13 1.27607912E-06 9.59471387E-21 5.70129362E-09 + 4.53083483E-23-4.27984831E-05 0.00000000E+00-1.93170824E-07 0.00000000E+00 +-2.02207834E-05-2.28084495E-11 1.68692553E-08-8.73750502E-13 0.00000000E+00 +-3.82282879E-11 0.00000000E+00-1.39576856E-12 3.69850681E-07 4.92049717E-21 +-1.31470150E-08-1.15147815E-22 1.83369704E-08 0.00000000E+00 5.15204913E-07 + 0.00000000E+00 2.04222387E-05 1.21835907E-11 8.12171887E-09-6.72661587E-13 + 0.00000000E+00 2.11816861E-11 0.00000000E+00-1.15277996E-12-9.06523131E-07 +-4.47018117E-21 4.15220418E-09 2.40507893E-23 4.28171506E-05 0.00000000E+00 +-1.93248788E-07 0.00000000E+00 2.48277020E-03 0.00000000E+00 1.44785021E-03 +-4.14698508E-18 0.00000000E+00-1.01708663E-08 0.00000000E+00-3.94260588E-11 + 5.15702535E-03-6.13982855E-09 2.01864751E-05-2.37187410E-11 2.00604744E-02 + 0.00000000E+00 2.53237051E-03 0.00000000E+00 1.18127277E-02-4.07588957E-17 + 1.50541651E-03-5.86428285E-18 0.00000000E+00-9.61212509E-09 0.00000000E+00 + 3.82282879E-11 5.17281393E-03-5.71750187E-09-2.02207834E-05 2.28084495E-11 +-1.25378518E-03 0.00000000E+00-7.38316681E-04 2.50281698E-18 0.00000000E+00 + 5.72840446E-10 0.00000000E+00 2.99442738E-13-2.55830745E-04 3.57153258E-10 + 8.57706455E-09 2.27572885E-13 2.53237051E-03 0.00000000E+00 1.01295735E-02 + 0.00000000E+00 1.50541651E-03-5.86428285E-18 6.02207935E-03-2.19587557E-17 + 0.00000000E+00-9.04020808E-09 0.00000000E+00 1.39576856E-12 5.71492723E-03 +-5.27756332E-09 1.68692553E-08 8.73750502E-13 2.53244666E-03 0.00000000E+00 +-1.27858086E-03 0.00000000E+00 1.50545947E-03-5.94667244E-18-7.67350560E-04 + 2.23829422E-18 0.00000000E+00-9.45310880E-11 0.00000000E+00 1.15277996E-12 +-2.63522233E-04-5.66630481E-11 8.12171887E-09 6.72661587E-13 1.44785021E-03 + 4.14698508E-18 2.48277020E-03 0.00000000E+00-5.15702535E-03-6.13982855E-09 +-2.01864751E-05-2.37187410E-11 0.00000000E+00-1.01708663E-08 0.00000000E+00 +-3.94260588E-11 1.18127277E-02 4.07588957E-17 1.50541651E-03 5.86428285E-18 + 2.00604744E-02 0.00000000E+00 2.53237051E-03 0.00000000E+00-5.17281393E-03 +-5.71750187E-09 2.02207834E-05 2.28084495E-11 0.00000000E+00-9.61212509E-09 + 0.00000000E+00 3.82282879E-11-7.38316681E-04-2.50281698E-18-1.25378518E-03 + 0.00000000E+00 2.55830745E-04 3.57153258E-10-8.57706455E-09 2.27572885E-13 + 0.00000000E+00 5.72840446E-10 0.00000000E+00 2.99442738E-13 1.50541651E-03 + 5.86428285E-18 6.02207935E-03 2.19587557E-17 2.53237051E-03 0.00000000E+00 + 1.01295735E-02 0.00000000E+00-5.71492723E-03-5.27756332E-09-1.68692553E-08 + 8.73750502E-13 0.00000000E+00-9.04020808E-09 0.00000000E+00 1.39576856E-12 + 1.50545947E-03 5.94667244E-18-7.67350560E-04-2.23829422E-18 2.53244666E-03 + 0.00000000E+00-1.27858086E-03 0.00000000E+00 2.63522233E-04-5.66630481E-11 +-8.12171887E-09 6.72661587E-13 0.00000000E+00-9.45310880E-11 0.00000000E+00 + 1.15277996E-12 0.00000000E+00-4.02534851E-10 2.60654961E-04-2.28300536E-10 + 9.08961599E-03 0.00000000E+00 4.27987004E-05 0.00000000E+00-2.68267062E-04 + 2.12296664E-18-1.25021777E-06 1.04234299E-20 0.00000000E+00 9.61212509E-09 + 0.00000000E+00 9.04020808E-09-5.17281393E-03 5.71750187E-09-5.71492723E-03 + 5.27756332E-09 5.25246164E-02 0.00000000E+00 1.83369704E-08 0.00000000E+00 +-1.34103359E-03 1.34302731E-17 3.69850681E-07-4.92049717E-21 0.00000000E+00 + 5.84038099E-09 0.00000000E+00-5.53922053E-10-5.21746461E-03 3.36586209E-09 + 2.58956100E-04-3.21710422E-10 9.09328764E-03 0.00000000E+00-4.28146000E-05 + 0.00000000E+00-1.95377825E-04 1.11875379E-18 9.33365335E-07-6.10268395E-21 + 0.00000000E+00-2.99442738E-13-8.57706455E-09-2.27572885E-13-4.27984831E-05 + 0.00000000E+00-1.93170824E-07 0.00000000E+00 1.27607912E-06-9.59471387E-21 + 5.70129362E-09-4.53083483E-23 0.00000000E+00-3.82282879E-11 0.00000000E+00 +-1.39576856E-12 2.02207834E-05-2.28084495E-11-1.68692553E-08-8.73750502E-13 + 1.83369704E-08 0.00000000E+00 5.15204913E-07 0.00000000E+00 3.69850681E-07 +-4.92049717E-21-1.31470150E-08 1.15147815E-22 0.00000000E+00 2.11816861E-11 + 0.00000000E+00-1.15277996E-12-2.04222387E-05 1.21835907E-11-8.12171887E-09 +-6.72661587E-13 4.28171506E-05 0.00000000E+00-1.93248788E-07 0.00000000E+00 +-9.06523131E-07 4.47018117E-21 4.15220418E-09-2.40507893E-23-2.60654961E-04 +-2.28300536E-10 0.00000000E+00-4.02534851E-10-2.68267062E-04-2.12296664E-18 +-1.25021777E-06-1.04234299E-20 9.08961599E-03 0.00000000E+00 4.27987004E-05 + 0.00000000E+00 5.17281393E-03 5.71750187E-09 5.71492723E-03 5.27756332E-09 + 0.00000000E+00 9.61212509E-09 0.00000000E+00 9.04020808E-09-1.34103359E-03 +-1.34302731E-17 3.69850681E-07 4.92049717E-21 5.25246164E-02 0.00000000E+00 + 1.83369704E-08 0.00000000E+00 5.21746461E-03 3.36586209E-09-2.58956100E-04 +-3.21710422E-10 0.00000000E+00 5.84038099E-09 0.00000000E+00-5.53922053E-10 +-1.95377825E-04-1.11875379E-18 9.33365335E-07 6.10268395E-21 9.09328764E-03 + 0.00000000E+00-4.28146000E-05 0.00000000E+00 1.82295904E-03 7.24889606E-18 + 3.20912514E-03 0.00000000E+00-6.74566114E-03-8.98432156E-09-3.50689559E-05 +-4.65722786E-11 0.00000000E+00-1.40648797E-08 0.00000000E+00-7.30226675E-11 + 1.49804424E-02 4.35358217E-17 1.92230985E-03 4.44104428E-18 2.60226235E-02 + 0.00000000E+00 3.29650467E-03 0.00000000E+00-6.77497508E-03-8.88962710E-09 + 3.51535396E-05 4.63057584E-11 0.00000000E+00-1.40560025E-08 0.00000000E+00 + 7.30041627E-11-1.62640745E-03 0.00000000E+00-9.36317224E-04 2.92248508E-18 + 0.00000000E+00 7.04775916E-10 0.00000000E+00 4.62620284E-15-3.33526689E-04 + 4.60358755E-10 2.11459169E-08 6.66300434E-14 3.29650467E-03 0.00000000E+00 + 1.15490978E-02 0.00000000E+00 1.92230985E-03-4.44104428E-18 6.73005358E-03 +-1.90863465E-17 0.00000000E+00-1.35133106E-08 0.00000000E+00 7.94337397E-12 + 6.56970556E-03-8.36124373E-09-3.80094314E-06 5.10401111E-12 2.48277020E-03 + 0.00000000E+00-1.25378518E-03 0.00000000E+00 1.44785021E-03-4.14698508E-18 +-7.38316681E-04 2.50281698E-18 0.00000000E+00 4.02534851E-10 0.00000000E+00 + 2.99442738E-13-2.60654961E-04 2.28300536E-10 8.57706455E-09 2.27572885E-13 + 2.11459169E-08-6.66300434E-14 0.00000000E+00-4.62620284E-15 2.92909728E-06 +-1.06210928E-20 1.73802205E-08-6.01002596E-23-7.54809124E-05 0.00000000E+00 +-4.52317855E-07 0.00000000E+00-3.51535396E-05-4.63057584E-11-3.80094314E-06 +-5.10401111E-12 0.00000000E+00-7.30041627E-11 0.00000000E+00-7.94337397E-12 + 2.43510657E-06-2.33054196E-20-3.02757466E-08 8.89397484E-24-5.52834532E-05 + 0.00000000E+00 8.60579746E-07 0.00000000E+00 2.01864751E-05 2.37187410E-11 + 8.57706455E-09-2.27572885E-13 0.00000000E+00 3.94260588E-11 0.00000000E+00 +-2.99442738E-13-1.25021777E-06-1.04234299E-20 5.70129362E-09 4.53083483E-23 + 4.27987004E-05 0.00000000E+00-1.93170824E-07 0.00000000E+00-3.42483761E-04 +-4.31553521E-10 0.00000000E+00-7.02200321E-10-4.63902310E-04 1.58583048E-18 +-2.87126149E-06 9.27770632E-21 1.20732961E-02 0.00000000E+00 7.54752441E-05 + 0.00000000E+00 6.77497508E-03 8.88962710E-09 6.56970556E-03 8.36124373E-09 + 0.00000000E+00 1.40560025E-08 0.00000000E+00 1.35133106E-08-2.07631619E-03 +-2.50050963E-18 2.43510657E-06-2.33054196E-20 6.11296785E-02 0.00000000E+00 +-5.52834532E-05 0.00000000E+00 5.15702535E-03 6.13982855E-09-2.55830745E-04 +-3.57153258E-10 0.00000000E+00 1.01708663E-08 0.00000000E+00-5.72840446E-10 +-2.68267062E-04-2.12296664E-18 1.27607912E-06 9.59471387E-21 9.08961599E-03 + 0.00000000E+00-4.27984831E-05 0.00000000E+00 0.00000000E+00-4.62620284E-15 +-2.11459169E-08-6.66300434E-14-7.54809124E-05 0.00000000E+00-4.52317855E-07 + 0.00000000E+00 2.92909728E-06 1.06210928E-20 1.73802205E-08 6.01002596E-23 + 0.00000000E+00-7.30041627E-11 0.00000000E+00-7.94337397E-12 3.51535396E-05 +-4.63057584E-11 3.80094314E-06-5.10401111E-12-5.52834532E-05 0.00000000E+00 + 8.60579746E-07 0.00000000E+00 2.43510657E-06 2.33054196E-20-3.02757466E-08 +-8.89397484E-24 0.00000000E+00 3.94260588E-11 0.00000000E+00-2.99442738E-13 +-2.01864751E-05 2.37187410E-11-8.57706455E-09-2.27572885E-13 4.27987004E-05 + 0.00000000E+00-1.93170824E-07 0.00000000E+00-1.25021777E-06 1.04234299E-20 + 5.70129362E-09-4.53083483E-23 0.00000000E+00-7.02200321E-10 3.42483761E-04 +-4.31553521E-10 1.20732961E-02 0.00000000E+00 7.54752441E-05 0.00000000E+00 +-4.63902310E-04-1.58583048E-18-2.87126149E-06-9.27770632E-21 0.00000000E+00 + 1.40560025E-08 0.00000000E+00 1.35133106E-08-6.77497508E-03 8.88962710E-09 +-6.56970556E-03 8.36124373E-09 6.11296785E-02 0.00000000E+00-5.52834532E-05 + 0.00000000E+00-2.07631619E-03 2.50050963E-18 2.43510657E-06 2.33054196E-20 + 0.00000000E+00 1.01708663E-08 0.00000000E+00-5.72840446E-10-5.15702535E-03 + 6.13982855E-09 2.55830745E-04-3.57153258E-10 9.08961599E-03 0.00000000E+00 +-4.27984831E-05 0.00000000E+00-2.68267062E-04 2.12296664E-18 1.27607912E-06 +-9.59471387E-21-9.36317224E-04-2.92248508E-18-1.62640745E-03 0.00000000E+00 + 3.33526689E-04 4.60358755E-10-2.11459169E-08 6.66300434E-14 0.00000000E+00 + 7.04775916E-10 0.00000000E+00 4.62620284E-15 1.92230985E-03 4.44104428E-18 + 6.73005358E-03 1.90863465E-17 3.29650467E-03 0.00000000E+00 1.15490978E-02 + 0.00000000E+00-6.56970556E-03-8.36124373E-09 3.80094314E-06 5.10401111E-12 + 0.00000000E+00-1.35133106E-08 0.00000000E+00 7.94337397E-12 1.44785021E-03 + 4.14698508E-18-7.38316681E-04-2.50281698E-18 2.48277020E-03 0.00000000E+00 +-1.25378518E-03 0.00000000E+00 2.60654961E-04 2.28300536E-10-8.57706455E-09 + 2.27572885E-13 0.00000000E+00 4.02534851E-10 0.00000000E+00 2.99442738E-13 + 3.20912514E-03 0.00000000E+00 1.82295904E-03-7.24889606E-18 0.00000000E+00 +-1.40648797E-08 0.00000000E+00-7.30226675E-11 6.74566114E-03-8.98432156E-09 + 3.50689559E-05-4.65722786E-11 2.60226235E-02 0.00000000E+00 3.29650467E-03 + 0.00000000E+00 1.49804424E-02-4.35358217E-17 1.92230985E-03-4.44104428E-18 + 0.00000000E+00-1.40560025E-08 0.00000000E+00 7.30041627E-11 6.77497508E-03 +-8.88962710E-09-3.51535396E-05 4.63057584E-11 1.72592117E-03 7.41636422E-18 + 3.12152539E-03 0.00000000E+00-6.62723914E-03-9.11358167E-09-3.44560273E-05 +-4.73355395E-11 0.00000000E+00-1.41557028E-08 0.00000000E+00-7.35481224E-11 + 1.41948084E-02 6.79646214E-17 1.82295272E-03 8.74718329E-18 2.53225911E-02 + 0.00000000E+00 3.20911636E-03 0.00000000E+00-6.65833347E-03-9.10886358E-09 + 3.45457478E-05 4.73232534E-11 0.00000000E+00-1.41645235E-08 0.00000000E+00 + 7.35761614E-11-1.58266044E-03 0.00000000E+00-8.87218472E-04 4.04088688E-18 + 0.00000000E+00 7.05911464E-10 0.00000000E+00-7.00976204E-15-3.27379601E-04 + 4.55944707E-10 2.24301381E-08 3.07153397E-15 3.20911636E-03 0.00000000E+00 + 1.28364068E-02 0.00000000E+00 1.82295272E-03-8.74718329E-18 7.29265151E-03 +-3.04968293E-17 0.00000000E+00-1.55335158E-08 0.00000000E+00 9.36762409E-14 + 7.37279920E-03-9.98062522E-09 4.36046621E-08 5.77403711E-14 3.20912514E-03 + 0.00000000E+00-1.62640745E-03 0.00000000E+00 1.82295904E-03-7.24889606E-18 +-9.36317224E-04 2.92248508E-18 0.00000000E+00 7.02200321E-10 0.00000000E+00 + 4.62620284E-15-3.42483761E-04 4.31553521E-10 2.11459169E-08 6.66300434E-14 + 2.24301381E-08-3.07153397E-15 0.00000000E+00 7.00976204E-15 3.66178309E-06 + 3.81270902E-22 2.17793253E-08-4.25009555E-24-7.56073105E-05 0.00000000E+00 +-4.53054228E-07 0.00000000E+00-3.45457478E-05-4.73232534E-11 4.36046621E-08 +-5.77403711E-14 0.00000000E+00-7.35761614E-11 0.00000000E+00-9.36762409E-14 + 7.90584215E-07 1.14685947E-20-5.22461391E-08 1.28798343E-22-1.32331142E-07 + 0.00000000E+00 1.20707212E-06 0.00000000E+00 3.50689559E-05 4.65722786E-11 + 2.11459169E-08-6.66300434E-14 0.00000000E+00 7.30226675E-11 0.00000000E+00 +-4.62620284E-15-2.87126149E-06 9.27770632E-21 1.73802205E-08-6.01002596E-23 + 7.54752441E-05 0.00000000E+00-4.52317855E-07 0.00000000E+00-3.36880670E-04 +-4.54528627E-10 0.00000000E+00-7.08656493E-10-5.81319633E-04 1.10333713E-19 +-3.60670389E-06 1.77277405E-21 1.20928805E-02 0.00000000E+00 7.55941605E-05 + 0.00000000E+00 6.65833347E-03 9.10886358E-09 7.37279920E-03 9.98062522E-09 + 0.00000000E+00 1.41645235E-08 0.00000000E+00 1.55335158E-08-3.02290583E-03 + 9.26259032E-18 7.90584215E-07 1.14685947E-20 6.98042457E-02 0.00000000E+00 +-1.32331142E-07 0.00000000E+00 6.74566114E-03 8.98432156E-09-3.33526689E-04 +-4.60358755E-10 0.00000000E+00 1.40648797E-08 0.00000000E+00-7.04775916E-10 +-4.63902310E-04 1.58583048E-18 2.92909728E-06-1.06210928E-20 1.20732961E-02 + 0.00000000E+00-7.54809124E-05 0.00000000E+00 0.00000000E+00 7.00976204E-15 +-2.24301381E-08-3.07153397E-15-7.56073105E-05 0.00000000E+00-4.53054228E-07 + 0.00000000E+00 3.66178309E-06-3.81270902E-22 2.17793253E-08 4.25009555E-24 + 0.00000000E+00-7.35761614E-11 0.00000000E+00-9.36762409E-14 3.45457478E-05 +-4.73232534E-11-4.36046621E-08-5.77403711E-14-1.32331142E-07 0.00000000E+00 + 1.20707212E-06 0.00000000E+00 7.90584215E-07-1.14685947E-20-5.22461391E-08 +-1.28798343E-22 0.00000000E+00 7.30226675E-11 0.00000000E+00-4.62620284E-15 +-3.50689559E-05 4.65722786E-11-2.11459169E-08-6.66300434E-14 7.54752441E-05 + 0.00000000E+00-4.52317855E-07 0.00000000E+00-2.87126149E-06-9.27770632E-21 + 1.73802205E-08 6.01002596E-23 0.00000000E+00-7.08656493E-10 3.36880670E-04 +-4.54528627E-10 1.20928805E-02 0.00000000E+00 7.55941605E-05 0.00000000E+00 +-5.81319633E-04-1.10333713E-19-3.60670389E-06-1.77277405E-21 0.00000000E+00 + 1.41645235E-08 0.00000000E+00 1.55335158E-08-6.65833347E-03 9.10886358E-09 +-7.37279920E-03 9.98062522E-09 6.98042457E-02 0.00000000E+00-1.32331142E-07 + 0.00000000E+00-3.02290583E-03-9.26259032E-18 7.90584215E-07-1.14685947E-20 + 0.00000000E+00 1.40648797E-08 0.00000000E+00-7.04775916E-10-6.74566114E-03 + 8.98432156E-09 3.33526689E-04-4.60358755E-10 1.20732961E-02 0.00000000E+00 +-7.54809124E-05 0.00000000E+00-4.63902310E-04-1.58583048E-18 2.92909728E-06 + 1.06210928E-20-8.87218472E-04-4.04088688E-18-1.58266044E-03 0.00000000E+00 + 3.27379601E-04 4.55944707E-10-2.24301381E-08 3.07153397E-15 0.00000000E+00 + 7.05911464E-10 0.00000000E+00-7.00976204E-15 1.82295272E-03 8.74718329E-18 + 7.29265151E-03 3.04968293E-17 3.20911636E-03 0.00000000E+00 1.28364068E-02 + 0.00000000E+00-7.37279920E-03-9.98062522E-09-4.36046621E-08 5.77403711E-14 + 0.00000000E+00-1.55335158E-08 0.00000000E+00 9.36762409E-14 1.82295904E-03 + 7.24889606E-18-9.36317224E-04-2.92248508E-18 3.20912514E-03 0.00000000E+00 +-1.62640745E-03 0.00000000E+00 3.42483761E-04 4.31553521E-10-2.11459169E-08 + 6.66300434E-14 0.00000000E+00 7.02200321E-10 0.00000000E+00 4.62620284E-15 + 3.12152539E-03 0.00000000E+00 1.72592117E-03-7.41636422E-18 0.00000000E+00 +-1.41557028E-08 0.00000000E+00-7.35481224E-11 6.62723914E-03-9.11358167E-09 + 3.44560273E-05-4.73355395E-11 2.53225911E-02 0.00000000E+00 3.20911636E-03 + 0.00000000E+00 1.41948084E-02-6.79646214E-17 1.82295272E-03-8.74718329E-18 + 0.00000000E+00-1.41645235E-08 0.00000000E+00 7.35761614E-11 6.65833347E-03 +-9.10886358E-09-3.45457478E-05 4.73232534E-11 1.63129399E-03 6.16819952E-18 + 3.03382383E-03 0.00000000E+00-6.50234390E-03-9.06290611E-09-3.38093335E-05 +-4.70878330E-11 0.00000000E+00-1.39822288E-08 0.00000000E+00-7.26695199E-11 + 1.34281969E-02 4.82505706E-17 1.72592680E-03 6.29999365E-18 2.46214920E-02 + 0.00000000E+00 3.12153859E-03 0.00000000E+00-6.53506718E-03-9.07848927E-09 + 3.39037536E-05 4.71327101E-11 0.00000000E+00-1.40275432E-08 0.00000000E+00 + 7.27996859E-11-1.53884060E-03 0.00000000E+00-8.39305197E-04 3.11704829E-18 + 0.00000000E+00 6.93435087E-10 0.00000000E+00-3.25415012E-14-3.20926922E-04 + 4.51168972E-10 2.36050327E-08-1.12192646E-14 3.12153859E-03 0.00000000E+00 + 1.24860839E-02 0.00000000E+00 1.72592680E-03-6.29999365E-18 6.90455279E-03 +-2.78429095E-17 0.00000000E+00-1.55110146E-08 0.00000000E+00-8.33230934E-14 + 7.23982023E-03-1.00117109E-08 4.59928977E-08-2.48205636E-14 3.12152539E-03 + 0.00000000E+00-1.58266044E-03 0.00000000E+00 1.72592117E-03-7.41636422E-18 +-8.87218472E-04 4.04088688E-18 0.00000000E+00 7.08656493E-10 0.00000000E+00 +-7.00976204E-15-3.36880670E-04 4.54528627E-10 2.24301381E-08 3.07153397E-15 + 2.36050327E-08 1.12192646E-14 0.00000000E+00 3.25415012E-14 4.35898862E-06 + 1.34944113E-20 2.59655309E-08 8.35548641E-23-7.58327448E-05 0.00000000E+00 +-4.54383193E-07 0.00000000E+00-3.39037536E-05-4.71327101E-11 4.59928977E-08 + 2.48205636E-14 0.00000000E+00-7.27996859E-11 0.00000000E+00 8.33230934E-14 + 7.52208460E-07 1.80345273E-20-6.36920809E-08-1.42995236E-22-2.38705506E-07 + 0.00000000E+00 1.20982229E-06 0.00000000E+00 3.44560273E-05 4.73355395E-11 + 2.24301381E-08-3.07153397E-15 0.00000000E+00 7.35481224E-11 0.00000000E+00 + 7.00976204E-15-3.60670389E-06 1.77277405E-21 2.17793253E-08-4.25009555E-24 + 7.55941605E-05 0.00000000E+00-4.53054228E-07 0.00000000E+00-3.30925711E-04 +-4.55928827E-10 0.00000000E+00-7.07269893E-10-6.93053799E-04-2.21819581E-18 +-4.30657316E-06-1.42868206E-20 1.21282828E-02 0.00000000E+00 7.58118165E-05 + 0.00000000E+00 6.53506718E-03 9.07848927E-09 7.23982023E-03 1.00117109E-08 + 0.00000000E+00 1.40275432E-08 0.00000000E+00 1.55110146E-08-3.68478165E-03 +-9.97911823E-18 7.52208460E-07 1.80345273E-20 6.99627293E-02 0.00000000E+00 +-2.38705506E-07 0.00000000E+00 6.62723914E-03 9.11358167E-09-3.27379601E-04 +-4.55944707E-10 0.00000000E+00 1.41557028E-08 0.00000000E+00-7.05911464E-10 +-5.81319633E-04 1.10333713E-19 3.66178309E-06 3.81270902E-22 1.20928805E-02 + 0.00000000E+00-7.56073105E-05 0.00000000E+00 0.00000000E+00 3.25415012E-14 +-2.36050327E-08 1.12192646E-14-7.58327448E-05 0.00000000E+00-4.54383193E-07 + 0.00000000E+00 4.35898862E-06-1.34944113E-20 2.59655309E-08-8.35548641E-23 + 0.00000000E+00-7.27996859E-11 0.00000000E+00 8.33230934E-14 3.39037536E-05 +-4.71327101E-11-4.59928977E-08 2.48205636E-14-2.38705506E-07 0.00000000E+00 + 1.20982229E-06 0.00000000E+00 7.52208460E-07-1.80345273E-20-6.36920809E-08 + 1.42995236E-22 0.00000000E+00 7.35481224E-11 0.00000000E+00 7.00976204E-15 +-3.44560273E-05 4.73355395E-11-2.24301381E-08-3.07153397E-15 7.55941605E-05 + 0.00000000E+00-4.53054228E-07 0.00000000E+00-3.60670389E-06-1.77277405E-21 + 2.17793253E-08 4.25009555E-24 0.00000000E+00-7.07269893E-10 3.30925711E-04 +-4.55928827E-10 1.21282828E-02 0.00000000E+00 7.58118165E-05 0.00000000E+00 +-6.93053799E-04 2.21819581E-18-4.30657316E-06 1.42868206E-20 0.00000000E+00 + 1.40275432E-08 0.00000000E+00 1.55110146E-08-6.53506718E-03 9.07848927E-09 +-7.23982023E-03 1.00117109E-08 6.99627293E-02 0.00000000E+00-2.38705506E-07 + 0.00000000E+00-3.68478165E-03 9.97911823E-18 7.52208460E-07-1.80345273E-20 + 0.00000000E+00 1.41557028E-08 0.00000000E+00-7.05911464E-10-6.62723914E-03 + 9.11358167E-09 3.27379601E-04-4.55944707E-10 1.20928805E-02 0.00000000E+00 +-7.56073105E-05 0.00000000E+00-5.81319633E-04-1.10333713E-19 3.66178309E-06 +-3.81270902E-22-8.39305197E-04-3.11704829E-18-1.53884060E-03 0.00000000E+00 + 3.20926922E-04 4.51168972E-10-2.36050327E-08-1.12192646E-14 0.00000000E+00 + 6.93435087E-10 0.00000000E+00-3.25415012E-14 1.72592680E-03 6.29999365E-18 + 6.90455279E-03 2.78429095E-17 3.12153859E-03 0.00000000E+00 1.24860839E-02 + 0.00000000E+00-7.23982023E-03-1.00117109E-08-4.59928977E-08-2.48205636E-14 + 0.00000000E+00-1.55110146E-08 0.00000000E+00-8.33230934E-14 1.72592117E-03 + 7.41636422E-18-8.87218472E-04-4.04088688E-18 3.12152539E-03 0.00000000E+00 +-1.58266044E-03 0.00000000E+00 3.36880670E-04 4.54528627E-10-2.24301381E-08 + 3.07153397E-15 0.00000000E+00 7.08656493E-10 0.00000000E+00-7.00976204E-15 + 3.03382383E-03 0.00000000E+00 1.63129399E-03-6.16819952E-18 0.00000000E+00 +-1.39822288E-08 0.00000000E+00-7.26695199E-11 6.50234390E-03-9.06290611E-09 + 3.38093335E-05-4.70878330E-11 2.46214920E-02 0.00000000E+00 3.12153859E-03 + 0.00000000E+00 1.34281969E-02-4.82505706E-17 1.72592680E-03-6.29999365E-18 + 0.00000000E+00-1.40275432E-08 0.00000000E+00 7.27996859E-11 6.53506718E-03 +-9.07848927E-09-3.39037536E-05 4.71327101E-11 1.53908661E-03 3.42184946E-18 + 2.94597858E-03 0.00000000E+00-6.37119951E-03-9.00212274E-09-3.31301257E-05 +-4.67737158E-11 0.00000000E+00-1.38178847E-08 0.00000000E+00-7.18181846E-11 + 1.26808358E-02 4.16644468E-17 1.63129677E-03 6.78898222E-18 2.39192793E-02 + 0.00000000E+00 3.03383191E-03 0.00000000E+00-6.40551228E-03-9.01845077E-09 + 3.32291354E-05 4.68208928E-11 0.00000000E+00-1.38619857E-08 0.00000000E+00 + 7.19456528E-11-1.49495262E-03 0.00000000E+00-7.92595845E-04 2.55270792E-18 + 0.00000000E+00 6.85218430E-10 0.00000000E+00-3.18670495E-14-3.14167032E-04 + 4.48008083E-10 2.47524450E-08-1.17942481E-14 3.03383191E-03 0.00000000E+00 + 1.21352620E-02 0.00000000E+00 1.63129677E-03-6.78898222E-18 6.52604676E-03 +-2.48104001E-17 0.00000000E+00-1.53145127E-08 0.00000000E+00-5.65026755E-14 + 7.09986164E-03-9.94512495E-09 4.83239656E-08-2.14972127E-14 3.03382383E-03 + 0.00000000E+00-1.53884060E-03 0.00000000E+00 1.63129399E-03-6.16819952E-18 +-8.39305197E-04 3.11704829E-18 0.00000000E+00 7.07269893E-10 0.00000000E+00 +-3.25415012E-14-3.30925711E-04 4.55928827E-10 2.36050327E-08-1.12192646E-14 + 2.47524450E-08 1.17942481E-14 0.00000000E+00 3.18670495E-14 5.02268388E-06 + 8.92090491E-21 2.99505119E-08 4.97089588E-23-7.61617838E-05 0.00000000E+00 +-4.56331991E-07 0.00000000E+00-3.32291354E-05-4.68208928E-11 4.83239656E-08 + 2.14972127E-14 0.00000000E+00-7.19456528E-11 0.00000000E+00 5.65026755E-14 + 7.16079430E-07-9.09801030E-21-7.45852280E-08-1.52447776E-22-3.50105169E-07 + 0.00000000E+00 1.21418842E-06 0.00000000E+00 3.38093335E-05 4.70878330E-11 + 2.36050327E-08 1.12192646E-14 0.00000000E+00 7.26695199E-11 0.00000000E+00 + 3.25415012E-14-4.30657316E-06-1.42868206E-20 2.59655309E-08 8.35548641E-23 + 7.58118165E-05 0.00000000E+00-4.54383193E-07 0.00000000E+00-3.24651558E-04 +-4.52998434E-10 0.00000000E+00-6.98697958E-10-7.99415342E-04-1.33864769E-18 +-4.97278595E-06-7.77123193E-21 1.21802290E-02 0.00000000E+00 7.61327258E-05 + 0.00000000E+00 6.40551228E-03 9.01845077E-09 7.09986164E-03 9.94512495E-09 + 0.00000000E+00 1.38619857E-08 0.00000000E+00 1.53145127E-08-4.31465781E-03 +-7.54190157E-18 7.16079430E-07-9.09801030E-21 7.02146484E-02 0.00000000E+00 +-3.50105169E-07 0.00000000E+00 6.50234390E-03 9.06290611E-09-3.20926922E-04 +-4.51168972E-10 0.00000000E+00 1.39822288E-08 0.00000000E+00-6.93435087E-10 +-6.93053799E-04-2.21819581E-18 4.35898862E-06 1.34944113E-20 1.21282828E-02 + 0.00000000E+00-7.58327448E-05 0.00000000E+00 0.00000000E+00 3.18670495E-14 +-2.47524450E-08 1.17942481E-14-7.61617838E-05 0.00000000E+00-4.56331991E-07 + 0.00000000E+00 5.02268388E-06-8.92090491E-21 2.99505119E-08-4.97089588E-23 + 0.00000000E+00-7.19456528E-11 0.00000000E+00 5.65026755E-14 3.32291354E-05 +-4.68208928E-11-4.83239656E-08 2.14972127E-14-3.50105169E-07 0.00000000E+00 + 1.21418842E-06 0.00000000E+00 7.16079430E-07 9.09801030E-21-7.45852280E-08 + 1.52447776E-22 0.00000000E+00 7.26695199E-11 0.00000000E+00 3.25415012E-14 +-3.38093335E-05 4.70878330E-11-2.36050327E-08 1.12192646E-14 7.58118165E-05 + 0.00000000E+00-4.54383193E-07 0.00000000E+00-4.30657316E-06 1.42868206E-20 + 2.59655309E-08-8.35548641E-23 0.00000000E+00-6.98697958E-10 3.24651558E-04 +-4.52998434E-10 1.21802290E-02 0.00000000E+00 7.61327258E-05 0.00000000E+00 +-7.99415342E-04 1.33864769E-18-4.97278595E-06 7.77123193E-21 0.00000000E+00 + 1.38619857E-08 0.00000000E+00 1.53145127E-08-6.40551228E-03 9.01845077E-09 +-7.09986164E-03 9.94512495E-09 7.02146484E-02 0.00000000E+00-3.50105169E-07 + 0.00000000E+00-4.31465781E-03 7.54190157E-18 7.16079430E-07 9.09801030E-21 + 0.00000000E+00 1.39822288E-08 0.00000000E+00-6.93435087E-10-6.50234390E-03 + 9.06290611E-09 3.20926922E-04-4.51168972E-10 1.21282828E-02 0.00000000E+00 +-7.58327448E-05 0.00000000E+00-6.93053799E-04 2.21819581E-18 4.35898862E-06 +-1.34944113E-20-7.92595845E-04-2.55270792E-18-1.49495262E-03 0.00000000E+00 + 3.14167032E-04 4.48008083E-10-2.47524450E-08-1.17942481E-14 0.00000000E+00 + 6.85218430E-10 0.00000000E+00-3.18670495E-14 1.63129677E-03 6.78898222E-18 + 6.52604676E-03 2.48104001E-17 3.03383191E-03 0.00000000E+00 1.21352620E-02 + 0.00000000E+00-7.09986164E-03-9.94512495E-09-4.83239656E-08-2.14972127E-14 + 0.00000000E+00-1.53145127E-08 0.00000000E+00-5.65026755E-14 1.63129399E-03 + 6.16819952E-18-8.39305197E-04-3.11704829E-18 3.03382383E-03 0.00000000E+00 +-1.53884060E-03 0.00000000E+00 3.30925711E-04 4.55928827E-10-2.36050327E-08 +-1.12192646E-14 0.00000000E+00 7.07269893E-10 0.00000000E+00-3.25415012E-14 + 2.94597858E-03 0.00000000E+00 1.53908661E-03-3.42184946E-18 0.00000000E+00 +-1.38178847E-08 0.00000000E+00-7.18181846E-11 6.37119951E-03-9.00212274E-09 + 3.31301257E-05-4.67737158E-11 2.39192793E-02 0.00000000E+00 3.03383191E-03 + 0.00000000E+00 1.26808358E-02-4.16644468E-17 1.63129677E-03-6.78898222E-18 + 0.00000000E+00-1.38619857E-08 0.00000000E+00 7.19456528E-11 6.40551228E-03 +-9.01845077E-09-3.32291354E-05 4.68208928E-11 1.44933666E-03 5.68013166E-18 + 2.85800537E-03 0.00000000E+00-6.23420865E-03-8.93708917E-09-3.24203814E-05 +-4.64361192E-11 0.00000000E+00-1.36405842E-08 0.00000000E+00-7.08981444E-11 + 1.19529990E-02 3.34799311E-17 1.53908965E-03 2.94385131E-18 2.32160061E-02 + 0.00000000E+00 2.94598711E-03 0.00000000E+00-6.26996722E-03-8.95373540E-09 + 3.25235591E-05 4.64841505E-11 0.00000000E+00-1.36860666E-08 0.00000000E+00 + 7.10293376E-11-1.45099812E-03 0.00000000E+00-7.47106578E-04 2.15599574E-18 + 0.00000000E+00 6.76222674E-10 0.00000000E+00-3.27983074E-14-3.07133445E-04 + 4.44730465E-10 2.57944293E-08-1.20078163E-14 2.94598711E-03 0.00000000E+00 + 1.17838856E-02 0.00000000E+00 1.53908965E-03-2.94385131E-18 6.15723009E-03 +-1.48108090E-17 0.00000000E+00-1.51274396E-08 0.00000000E+00-6.66750274E-14 + 6.95312870E-03-9.87578072E-09 5.05298214E-08-2.44013526E-14 2.94597858E-03 + 0.00000000E+00-1.49495262E-03 0.00000000E+00 1.53908661E-03-3.42184946E-18 +-7.92595845E-04 2.55270792E-18 0.00000000E+00 6.98697958E-10 0.00000000E+00 +-3.18670495E-14-3.24651558E-04 4.52998434E-10 2.47524450E-08-1.17942481E-14 + 2.57944293E-08 1.20078163E-14 0.00000000E+00 3.27983074E-14 5.65436039E-06 + 2.50465941E-20 3.37433385E-08 1.49288089E-22-7.66002865E-05 0.00000000E+00 +-4.58935065E-07 0.00000000E+00-3.25235591E-05-4.64841505E-11 5.05298214E-08 + 2.44013526E-14 0.00000000E+00-7.10293376E-11 0.00000000E+00 6.66750274E-14 + 6.81551076E-07 2.03409289E-20-8.49544419E-08-2.75458367E-22-4.67596085E-07 + 0.00000000E+00 1.22025061E-06 0.00000000E+00 3.31301257E-05 4.67737158E-11 + 2.47524450E-08 1.17942481E-14 0.00000000E+00 7.18181846E-11 0.00000000E+00 + 3.18670495E-14-4.97278595E-06-7.77123193E-21 2.99505119E-08 4.97089588E-23 + 7.61327258E-05 0.00000000E+00-4.56331991E-07 0.00000000E+00-3.18059662E-04 +-4.49816813E-10 0.00000000E+00-6.90119262E-10-9.00646732E-04-3.97306525E-18 +-5.60688079E-06-2.46752675E-20 1.22496388E-02 0.00000000E+00 7.65625281E-05 + 0.00000000E+00 6.26996722E-03 8.95373540E-09 6.95312870E-03 9.87578072E-09 + 0.00000000E+00 1.36860666E-08 0.00000000E+00 1.51274396E-08-4.91425057E-03 +-1.64588205E-17 6.81551076E-07 2.03409289E-20 7.05645206E-02 0.00000000E+00 +-4.67596085E-07 0.00000000E+00 6.37119951E-03 9.00212274E-09-3.14167032E-04 +-4.48008083E-10 0.00000000E+00 1.38178847E-08 0.00000000E+00-6.85218430E-10 +-7.99415342E-04-1.33864769E-18 5.02268388E-06 8.92090491E-21 1.21802290E-02 + 0.00000000E+00-7.61617838E-05 0.00000000E+00 0.00000000E+00 3.27983074E-14 +-2.57944293E-08 1.20078163E-14-7.66002865E-05 0.00000000E+00-4.58935065E-07 + 0.00000000E+00 5.65436039E-06-2.50465941E-20 3.37433385E-08-1.49288089E-22 + 0.00000000E+00-7.10293376E-11 0.00000000E+00 6.66750274E-14 3.25235591E-05 +-4.64841505E-11-5.05298214E-08 2.44013526E-14-4.67596085E-07 0.00000000E+00 + 1.22025061E-06 0.00000000E+00 6.81551076E-07-2.03409289E-20-8.49544419E-08 + 2.75458367E-22 0.00000000E+00 7.18181846E-11 0.00000000E+00 3.18670495E-14 +-3.31301257E-05 4.67737158E-11-2.47524450E-08 1.17942481E-14 7.61327258E-05 + 0.00000000E+00-4.56331991E-07 0.00000000E+00-4.97278595E-06 7.77123193E-21 + 2.99505119E-08-4.97089588E-23 0.00000000E+00-6.90119262E-10 3.18059662E-04 +-4.49816813E-10 1.22496388E-02 0.00000000E+00 7.65625281E-05 0.00000000E+00 +-9.00646732E-04 3.97306525E-18-5.60688079E-06 2.46752675E-20 0.00000000E+00 + 1.36860666E-08 0.00000000E+00 1.51274396E-08-6.26996722E-03 8.95373540E-09 +-6.95312870E-03 9.87578072E-09 7.05645206E-02 0.00000000E+00-4.67596085E-07 + 0.00000000E+00-4.91425057E-03 1.64588205E-17 6.81551076E-07-2.03409289E-20 + 0.00000000E+00 1.38178847E-08 0.00000000E+00-6.85218430E-10-6.37119951E-03 + 9.00212274E-09 3.14167032E-04-4.48008083E-10 1.21802290E-02 0.00000000E+00 +-7.61617838E-05 0.00000000E+00-7.99415342E-04 1.33864769E-18 5.02268388E-06 +-8.92090491E-21-7.47106578E-04-2.15599574E-18-1.45099812E-03 0.00000000E+00 + 3.07133445E-04 4.44730465E-10-2.57944293E-08-1.20078163E-14 0.00000000E+00 + 6.76222674E-10 0.00000000E+00-3.27983074E-14 1.53908965E-03 2.94385131E-18 + 6.15723009E-03 1.48108090E-17 2.94598711E-03 0.00000000E+00 1.17838856E-02 + 0.00000000E+00-6.95312870E-03-9.87578072E-09-5.05298214E-08-2.44013526E-14 + 0.00000000E+00-1.51274396E-08 0.00000000E+00-6.66750274E-14 1.53908661E-03 + 3.42184946E-18-7.92595845E-04-2.55270792E-18 2.94597858E-03 0.00000000E+00 +-1.49495262E-03 0.00000000E+00 3.24651558E-04 4.52998434E-10-2.47524450E-08 +-1.17942481E-14 0.00000000E+00 6.98697958E-10 0.00000000E+00-3.18670495E-14 + 2.85800537E-03 0.00000000E+00 1.44933666E-03-5.68013166E-18 0.00000000E+00 +-1.36405842E-08 0.00000000E+00-7.08981444E-11 6.23420865E-03-8.93708917E-09 + 3.24203814E-05-4.64361192E-11 2.32160061E-02 0.00000000E+00 2.94598711E-03 + 0.00000000E+00 1.19529990E-02-3.34799311E-17 1.53908965E-03-2.94385131E-18 + 0.00000000E+00-1.36860666E-08 0.00000000E+00 7.10293376E-11 6.26996722E-03 +-8.95373540E-09-3.25235591E-05 4.64841505E-11 1.36207245E-03 3.04008775E-18 + 2.76990525E-03 0.00000000E+00-6.09169854E-03-8.87374277E-09-3.16819438E-05 +-4.61065763E-11 0.00000000E+00-1.34638988E-08 0.00000000E+00-6.99809030E-11 + 1.12449333E-02 3.76020280E-17 1.44933953E-03 6.11107317E-18 2.25117111E-02 + 0.00000000E+00 2.85801370E-03 0.00000000E+00-6.12887334E-03-8.88981987E-09 + 3.17892105E-05 4.61529696E-11 0.00000000E+00-1.35094556E-08 0.00000000E+00 + 7.01123692E-11-1.40697974E-03 0.00000000E+00-7.02852994E-04 2.28779023E-18 + 0.00000000E+00 6.67372409E-10 0.00000000E+00-3.28665539E-14-2.99827075E-04 + 4.41636413E-10 2.68166749E-08-1.15983180E-14 2.85801370E-03 0.00000000E+00 + 1.14319930E-02 0.00000000E+00 1.44933953E-03-6.11107317E-18 5.79824020E-03 +-2.16372021E-17 0.00000000E+00-1.49325951E-08 0.00000000E+00-6.52765307E-14 + 6.80017701E-03-9.80461063E-09 5.25677114E-08-2.35606900E-14 2.85800537E-03 + 0.00000000E+00-1.45099812E-03 0.00000000E+00 1.44933666E-03-5.68013166E-18 +-7.47106578E-04 2.15599574E-18 0.00000000E+00 6.90119262E-10 0.00000000E+00 +-3.27983074E-14-3.18059662E-04 4.49816813E-10 2.57944293E-08-1.20078163E-14 + 2.68166749E-08 1.15983180E-14 0.00000000E+00 3.28665539E-14 6.25539432E-06 + 1.04679558E-20 3.73521979E-08 6.77853265E-23-7.71553849E-05 0.00000000E+00 +-4.62235445E-07 0.00000000E+00-3.17892105E-05-4.61529696E-11 5.25677114E-08 + 2.35606900E-14 0.00000000E+00-7.01123692E-11 0.00000000E+00 6.52765307E-14 + 6.48478920E-07-1.62302013E-20-9.48219322E-08-3.16523927E-22-5.92939934E-07 + 0.00000000E+00 1.22811606E-06 0.00000000E+00 3.24203814E-05 4.64361192E-11 + 2.57944293E-08 1.20078163E-14 0.00000000E+00 7.08981444E-11 0.00000000E+00 + 3.27983074E-14-5.60688079E-06-2.46752675E-20 3.37433385E-08 1.49288089E-22 + 7.65625281E-05 0.00000000E+00-4.58935065E-07 0.00000000E+00-3.11186075E-04 +-4.46548937E-10 0.00000000E+00-6.81292836E-10-9.96966728E-04-1.81676061E-18 +-6.21021561E-06-1.22191074E-20 1.23376595E-02 0.00000000E+00 7.71084415E-05 + 0.00000000E+00 6.12887334E-03 8.88981987E-09 6.80017701E-03 9.80461063E-09 + 0.00000000E+00 1.35094556E-08 0.00000000E+00 1.49325951E-08-5.48481058E-03 +-1.96428880E-17 6.48478920E-07-1.62302013E-20 7.10187395E-02 0.00000000E+00 +-5.92939934E-07 0.00000000E+00 6.23420865E-03 8.93708917E-09-3.07133445E-04 +-4.44730465E-10 0.00000000E+00 1.36405842E-08 0.00000000E+00-6.76222674E-10 +-9.00646732E-04-3.97306525E-18 5.65436039E-06 2.50465941E-20 1.22496388E-02 + 0.00000000E+00-7.66002865E-05 0.00000000E+00 0.00000000E+00 3.28665539E-14 +-2.68166749E-08 1.15983180E-14-7.71553849E-05 0.00000000E+00-4.62235445E-07 + 0.00000000E+00 6.25539432E-06-1.04679558E-20 3.73521979E-08-6.77853265E-23 + 0.00000000E+00-7.01123692E-11 0.00000000E+00 6.52765307E-14 3.17892105E-05 +-4.61529696E-11-5.25677114E-08 2.35606900E-14-5.92939934E-07 0.00000000E+00 + 1.22811606E-06 0.00000000E+00 6.48478920E-07 1.62302013E-20-9.48219322E-08 + 3.16523927E-22 0.00000000E+00 7.08981444E-11 0.00000000E+00 3.27983074E-14 +-3.24203814E-05 4.64361192E-11-2.57944293E-08 1.20078163E-14 7.65625281E-05 + 0.00000000E+00-4.58935065E-07 0.00000000E+00-5.60688079E-06 2.46752675E-20 + 3.37433385E-08-1.49288089E-22 0.00000000E+00-6.81292836E-10 3.11186075E-04 +-4.46548937E-10 1.23376595E-02 0.00000000E+00 7.71084415E-05 0.00000000E+00 +-9.96966728E-04 1.81676061E-18-6.21021561E-06 1.22191074E-20 0.00000000E+00 + 1.35094556E-08 0.00000000E+00 1.49325951E-08-6.12887334E-03 8.88981987E-09 +-6.80017701E-03 9.80461063E-09 7.10187395E-02 0.00000000E+00-5.92939934E-07 + 0.00000000E+00-5.48481058E-03 1.96428880E-17 6.48478920E-07 1.62302013E-20 + 0.00000000E+00 1.36405842E-08 0.00000000E+00-6.76222674E-10-6.23420865E-03 + 8.93708917E-09 3.07133445E-04-4.44730465E-10 1.22496388E-02 0.00000000E+00 +-7.66002865E-05 0.00000000E+00-9.00646732E-04 3.97306525E-18 5.65436039E-06 +-2.50465941E-20-7.02852994E-04-2.28779023E-18-1.40697974E-03 0.00000000E+00 + 2.99827075E-04 4.41636413E-10-2.68166749E-08-1.15983180E-14 0.00000000E+00 + 6.67372409E-10 0.00000000E+00-3.28665539E-14 1.44933953E-03 6.11107317E-18 + 5.79824020E-03 2.16372021E-17 2.85801370E-03 0.00000000E+00 1.14319930E-02 + 0.00000000E+00-6.80017701E-03-9.80461063E-09-5.25677114E-08-2.35606900E-14 + 0.00000000E+00-1.49325951E-08 0.00000000E+00-6.52765307E-14 1.44933666E-03 + 5.68013166E-18-7.47106578E-04-2.15599574E-18 2.85800537E-03 0.00000000E+00 +-1.45099812E-03 0.00000000E+00 3.18059662E-04 4.49816813E-10-2.57944293E-08 +-1.20078163E-14 0.00000000E+00 6.90119262E-10 0.00000000E+00-3.27983074E-14 + 2.76990525E-03 0.00000000E+00 1.36207245E-03-3.04008775E-18 0.00000000E+00 +-1.34638988E-08 0.00000000E+00-6.99809030E-11 6.09169854E-03-8.87374277E-09 + 3.16819438E-05-4.61065763E-11 2.25117111E-02 0.00000000E+00 2.85801370E-03 + 0.00000000E+00 1.12449333E-02-3.76020280E-17 1.44933953E-03-6.11107317E-18 + 0.00000000E+00-1.35094556E-08 0.00000000E+00 7.01123692E-11 6.12887334E-03 +-8.88981987E-09-3.17892105E-05 4.61529696E-11 1.27732442E-03 3.05731501E-18 + 2.68168461E-03 0.00000000E+00-5.94383606E-03-8.81301972E-09-3.09156127E-05 +-4.57904585E-11 0.00000000E+00-1.32869055E-08 0.00000000E+00-6.90616785E-11 + 1.05568748E-02 2.31423721E-17 1.36207505E-03 2.80774801E-18 2.18064239E-02 + 0.00000000E+00 2.76991309E-03 0.00000000E+00-5.98235557E-03-8.82835597E-09 + 3.10267592E-05 4.58347104E-11 0.00000000E+00-1.33323599E-08 0.00000000E+00 + 6.91928317E-11-1.36289942E-03 0.00000000E+00-6.59849867E-04 1.46626575E-18 + 0.00000000E+00 6.58538240E-10 0.00000000E+00-3.27883037E-14-2.92262604E-04 + 4.38695692E-10 2.77866368E-08-1.10629697E-14 2.76991309E-03 0.00000000E+00 + 1.10795939E-02 0.00000000E+00 1.36207505E-03-2.80774801E-18 5.44919369E-03 +-1.27738326E-17 0.00000000E+00-1.47378923E-08 0.00000000E+00-6.56496329E-14 + 6.64118516E-03-9.73590007E-09 5.45772996E-08-2.26249349E-14 2.76990525E-03 + 0.00000000E+00-1.40697974E-03 0.00000000E+00 1.36207245E-03-3.04008775E-18 +-7.02852994E-04 2.28779023E-18 0.00000000E+00 6.81292836E-10 0.00000000E+00 +-3.28665539E-14-3.11186075E-04 4.46548937E-10 2.68166749E-08-1.15983180E-14 + 2.77866368E-08 1.10629697E-14 0.00000000E+00 3.27883037E-14 6.82743009E-06 + 2.23292373E-20 4.07869254E-08 1.24638917E-22-7.78341907E-05 0.00000000E+00 +-4.66275246E-07 0.00000000E+00-3.10267592E-05-4.58347104E-11 5.45772996E-08 + 2.26249349E-14 0.00000000E+00-6.91928317E-11 0.00000000E+00 6.56496329E-14 + 6.17196715E-07 1.05720579E-20-1.04211851E-07-1.95429406E-22-7.25735013E-07 + 0.00000000E+00 1.23789513E-06 0.00000000E+00 3.16819438E-05 4.61065763E-11 + 2.68166749E-08 1.15983180E-14 0.00000000E+00 6.99809030E-11 0.00000000E+00 + 3.28665539E-14-6.21021561E-06-1.22191074E-20 3.73521979E-08 6.77853265E-23 + 7.71084415E-05 0.00000000E+00-4.62235445E-07 0.00000000E+00-3.04032476E-04 +-4.43381770E-10 0.00000000E+00-6.72427060E-10-1.08863769E-03-3.32907175E-18 +-6.78442686E-06-1.92869892E-20 1.24454158E-02 0.00000000E+00 7.77774171E-05 + 0.00000000E+00 5.98235557E-03 8.82835597E-09 6.64118516E-03 9.73590007E-09 + 0.00000000E+00 1.33323599E-08 0.00000000E+00 1.47378923E-08-6.02773961E-03 +-8.26850198E-18 6.17196715E-07 1.05720579E-20 7.15835232E-02 0.00000000E+00 +-7.25735013E-07 0.00000000E+00 6.09169854E-03 8.87374277E-09-2.99827075E-04 +-4.41636413E-10 0.00000000E+00 1.34638988E-08 0.00000000E+00-6.67372409E-10 +-9.96966728E-04-1.81676061E-18 6.25539432E-06 1.04679558E-20 1.23376595E-02 + 0.00000000E+00-7.71553849E-05 0.00000000E+00 0.00000000E+00 3.27883037E-14 +-2.77866368E-08 1.10629697E-14-7.78341907E-05 0.00000000E+00-4.66275246E-07 + 0.00000000E+00 6.82743009E-06-2.23292373E-20 4.07869254E-08-1.24638917E-22 + 0.00000000E+00-6.91928317E-11 0.00000000E+00 6.56496329E-14 3.10267592E-05 +-4.58347104E-11-5.45772996E-08 2.26249349E-14-7.25735013E-07 0.00000000E+00 + 1.23789513E-06 0.00000000E+00 6.17196715E-07-1.05720579E-20-1.04211851E-07 + 1.95429406E-22 0.00000000E+00 6.99809030E-11 0.00000000E+00 3.28665539E-14 +-3.16819438E-05 4.61065763E-11-2.68166749E-08 1.15983180E-14 7.71084415E-05 + 0.00000000E+00-4.62235445E-07 0.00000000E+00-6.21021561E-06 1.22191074E-20 + 3.73521979E-08-6.77853265E-23 0.00000000E+00-6.72427060E-10 3.04032476E-04 +-4.43381770E-10 1.24454158E-02 0.00000000E+00 7.77774171E-05 0.00000000E+00 +-1.08863769E-03 3.32907175E-18-6.78442686E-06 1.92869892E-20 0.00000000E+00 + 1.33323599E-08 0.00000000E+00 1.47378923E-08-5.98235557E-03 8.82835597E-09 +-6.64118516E-03 9.73590007E-09 7.15835232E-02 0.00000000E+00-7.25735013E-07 + 0.00000000E+00-6.02773961E-03 8.26850198E-18 6.17196715E-07-1.05720579E-20 + 0.00000000E+00 1.34638988E-08 0.00000000E+00-6.67372409E-10-6.09169854E-03 + 8.87374277E-09 2.99827075E-04-4.41636413E-10 1.23376595E-02 0.00000000E+00 +-7.71553849E-05 0.00000000E+00-9.96966728E-04 1.81676061E-18 6.25539432E-06 +-1.04679558E-20-6.59849867E-04-1.46626575E-18-1.36289942E-03 0.00000000E+00 + 2.92262604E-04 4.38695692E-10-2.77866368E-08-1.10629697E-14 0.00000000E+00 + 6.58538240E-10 0.00000000E+00-3.27883037E-14 1.36207505E-03 2.80774801E-18 + 5.44919369E-03 1.27738326E-17 2.76991309E-03 0.00000000E+00 1.10795939E-02 + 0.00000000E+00-6.64118516E-03-9.73590007E-09-5.45772996E-08-2.26249349E-14 + 0.00000000E+00-1.47378923E-08 0.00000000E+00-6.56496329E-14 1.36207245E-03 + 3.04008775E-18-7.02852994E-04-2.28779023E-18 2.76990525E-03 0.00000000E+00 +-1.40697974E-03 0.00000000E+00 3.11186075E-04 4.46548937E-10-2.68166749E-08 +-1.15983180E-14 0.00000000E+00 6.81292836E-10 0.00000000E+00-3.28665539E-14 + 2.68168461E-03 0.00000000E+00 1.27732442E-03-3.05731501E-18 0.00000000E+00 +-1.32869055E-08 0.00000000E+00-6.90616785E-11 5.94383606E-03-8.81301972E-09 + 3.09156127E-05-4.57904585E-11 2.18064239E-02 0.00000000E+00 2.76991309E-03 + 0.00000000E+00 1.05568748E-02-2.31423721E-17 1.36207505E-03-2.80774801E-18 + 0.00000000E+00-1.33323599E-08 0.00000000E+00 6.91928317E-11 5.98235557E-03 +-8.82835597E-09-3.10267592E-05 4.58347104E-11 1.19512061E-03 1.39689861E-18 + 2.59334972E-03 0.00000000E+00-5.79093911E-03-8.75533657E-09-3.01230336E-05 +-4.54900757E-11 0.00000000E+00-1.31105409E-08 0.00000000E+00-6.81457088E-11 + 9.88905961E-03 1.67633618E-17 1.27732697E-03 2.96168489E-18 2.11002006E-02 + 0.00000000E+00 2.68169239E-03 0.00000000E+00-5.83072227E-03-8.76987770E-09 + 3.02378273E-05 4.55320343E-11 0.00000000E+00-1.31558467E-08 0.00000000E+00 + 6.82764381E-11-1.31876053E-03 0.00000000E+00-6.18111893E-04 1.08964588E-18 + 0.00000000E+00 6.49738915E-10 0.00000000E+00-3.26823163E-14-2.84456802E-04 + 4.35913344E-10 2.86984316E-08-1.04896388E-14 2.68169239E-03 0.00000000E+00 + 1.07267133E-02 0.00000000E+00 1.27732697E-03-2.96168489E-18 5.11021141E-03 +-1.14705075E-17 0.00000000E+00-1.45434672E-08 0.00000000E+00-6.53693113E-14 + 6.47643601E-03-9.67032487E-09 5.64626436E-08-2.14950107E-14 2.68168461E-03 + 0.00000000E+00-1.36289942E-03 0.00000000E+00 1.27732442E-03-3.05731501E-18 +-6.59849867E-04 1.46626575E-18 0.00000000E+00 6.72427060E-10 0.00000000E+00 +-3.27883037E-14-3.04032476E-04 4.43381770E-10 2.77866368E-08-1.10629697E-14 + 2.86984316E-08 1.04896388E-14 0.00000000E+00 3.26823163E-14 7.37170432E-06 + 3.84375963E-20 4.40550936E-08 2.31667469E-22-7.86461491E-05 0.00000000E+00 +-4.71110662E-07 0.00000000E+00-3.02378273E-05-4.55320343E-11 5.64626436E-08 + 2.14950107E-14 0.00000000E+00-6.82764381E-11 0.00000000E+00 6.53693113E-14 + 5.87272147E-07 1.94493728E-20-1.13148204E-07-5.19989384E-22-8.68653192E-07 + 0.00000000E+00 1.24971923E-06 0.00000000E+00 3.09156127E-05 4.57904585E-11 + 2.77866368E-08 1.10629697E-14 0.00000000E+00 6.90616785E-11 0.00000000E+00 + 3.27883037E-14-6.78442686E-06-1.92869892E-20 4.07869254E-08 1.24638917E-22 + 7.77774171E-05 0.00000000E+00-4.66275246E-07 0.00000000E+00-2.96612801E-04 +-4.40356487E-10 0.00000000E+00-6.63582414E-10-1.17586187E-03-6.18093388E-18 +-7.33080602E-06-3.88557215E-20 1.25744071E-02 0.00000000E+00 7.85787590E-05 + 0.00000000E+00 5.83072227E-03 8.76987770E-09 6.47643601E-03 9.67032487E-09 + 0.00000000E+00 1.31558467E-08 0.00000000E+00 1.45434672E-08-6.54446452E-03 +-3.24184989E-17 5.87272147E-07 1.94493728E-20 7.22665010E-02 0.00000000E+00 +-8.68653192E-07 0.00000000E+00 5.94383606E-03 8.81301972E-09-2.92262604E-04 +-4.38695692E-10 0.00000000E+00 1.32869055E-08 0.00000000E+00-6.58538240E-10 +-1.08863769E-03-3.32907175E-18 6.82743009E-06 2.23292373E-20 1.24454158E-02 + 0.00000000E+00-7.78341907E-05 0.00000000E+00 0.00000000E+00 3.26823163E-14 +-2.86984316E-08 1.04896388E-14-7.86461491E-05 0.00000000E+00-4.71110662E-07 + 0.00000000E+00 7.37170432E-06-3.84375963E-20 4.40550936E-08-2.31667469E-22 + 0.00000000E+00-6.82764381E-11 0.00000000E+00 6.53693113E-14 3.02378273E-05 +-4.55320343E-11-5.64626436E-08 2.14950107E-14-8.68653192E-07 0.00000000E+00 + 1.24971923E-06 0.00000000E+00 5.87272147E-07-1.94493728E-20-1.13148204E-07 + 5.19989384E-22 0.00000000E+00 6.90616785E-11 0.00000000E+00 3.27883037E-14 +-3.09156127E-05 4.57904585E-11-2.77866368E-08 1.10629697E-14 7.77774171E-05 + 0.00000000E+00-4.66275246E-07 0.00000000E+00-6.78442686E-06 1.92869892E-20 + 4.07869254E-08-1.24638917E-22 0.00000000E+00-6.63582414E-10 2.96612801E-04 +-4.40356487E-10 1.25744071E-02 0.00000000E+00 7.85787590E-05 0.00000000E+00 +-1.17586187E-03 6.18093388E-18-7.33080602E-06 3.88557215E-20 0.00000000E+00 + 1.31558467E-08 0.00000000E+00 1.45434672E-08-5.83072227E-03 8.76987770E-09 +-6.47643601E-03 9.67032487E-09 7.22665010E-02 0.00000000E+00-8.68653192E-07 + 0.00000000E+00-6.54446452E-03 3.24184989E-17 5.87272147E-07-1.94493728E-20 + 0.00000000E+00 1.32869055E-08 0.00000000E+00-6.58538240E-10-5.94383606E-03 + 8.81301972E-09 2.92262604E-04-4.38695692E-10 1.24454158E-02 0.00000000E+00 +-7.78341907E-05 0.00000000E+00-1.08863769E-03 3.32907175E-18 6.82743009E-06 +-2.23292373E-20-6.18111893E-04-1.08964588E-18-1.31876053E-03 0.00000000E+00 + 2.84456802E-04 4.35913344E-10-2.86984316E-08-1.04896388E-14 0.00000000E+00 + 6.49738915E-10 0.00000000E+00-3.26823163E-14 1.27732697E-03 2.96168489E-18 + 5.11021141E-03 1.14705075E-17 2.68169239E-03 0.00000000E+00 1.07267133E-02 + 0.00000000E+00-6.47643601E-03-9.67032487E-09-5.64626436E-08-2.14950107E-14 + 0.00000000E+00-1.45434672E-08 0.00000000E+00-6.53693113E-14 1.27732442E-03 + 3.05731501E-18-6.59849867E-04-1.46626575E-18 2.68168461E-03 0.00000000E+00 +-1.36289942E-03 0.00000000E+00 3.04032476E-04 4.43381770E-10-2.77866368E-08 +-1.10629697E-14 0.00000000E+00 6.72427060E-10 0.00000000E+00-3.27883037E-14 + 2.59334972E-03 0.00000000E+00 1.19512061E-03-1.39689861E-18 0.00000000E+00 +-1.31105409E-08 0.00000000E+00-6.81457088E-11 5.79093911E-03-8.75533657E-09 + 3.01230336E-05-4.54900757E-11 2.11002006E-02 0.00000000E+00 2.68169239E-03 + 0.00000000E+00 9.88905961E-03-1.67633618E-17 1.27732697E-03-2.96168489E-18 + 0.00000000E+00-1.31558467E-08 0.00000000E+00 6.82764381E-11 5.83072227E-03 +-8.76987770E-09-3.02378273E-05 4.55320343E-11 1.11548686E-03 3.96637713E-18 + 2.50490315E-03 0.00000000E+00-5.63334961E-03-8.70087613E-09-2.93059884E-05 +-4.52063619E-11 0.00000000E+00-1.29349039E-08 0.00000000E+00-6.72334225E-11 + 9.24170138E-03 2.28171192E-17 1.19512299E-03 1.64733560E-18 2.03930721E-02 + 0.00000000E+00 2.59335717E-03 0.00000000E+00-5.67431196E-03-8.71456610E-09 + 2.94241833E-05 4.52458645E-11 0.00000000E+00-1.29799909E-08 0.00000000E+00 + 6.73635194E-11-1.27456508E-03 0.00000000E+00-5.77652463E-04 1.40342818E-18 + 0.00000000E+00 6.40985460E-10 0.00000000E+00-3.25242441E-14-2.76426913E-04 + 4.33299426E-10 2.95487065E-08-9.87566971E-15 2.59335717E-03 0.00000000E+00 + 1.03733741E-02 0.00000000E+00 1.19512299E-03-1.64733560E-18 4.78140513E-03 +-7.41271617E-18 0.00000000E+00-1.43497176E-08 0.00000000E+00-6.51236672E-14 + 6.30628644E-03-9.60815808E-09 5.82123872E-08-2.03132190E-14 2.59334972E-03 + 0.00000000E+00-1.31876053E-03 0.00000000E+00 1.19512061E-03-1.39689861E-18 +-6.18111893E-04 1.08964588E-18 0.00000000E+00 6.63582414E-10 0.00000000E+00 +-3.26823163E-14-2.96612801E-04 4.40356487E-10 2.86984316E-08-1.04896388E-14 + 2.95487065E-08 9.87566971E-15 0.00000000E+00 3.25242441E-14 7.88921304E-06 + 4.16923935E-20 4.71626151E-08 2.49651837E-22-7.96025705E-05 0.00000000E+00 +-4.76809066E-07 0.00000000E+00-2.94241833E-05-4.52458645E-11 5.82123872E-08 + 2.03132190E-14 0.00000000E+00-6.73635194E-11 0.00000000E+00 6.51236672E-14 + 5.58395968E-07 4.93133083E-21-1.21648058E-07-6.31739241E-22-1.02371274E-06 + 0.00000000E+00 1.26375306E-06 0.00000000E+00 3.01230336E-05 4.54900757E-11 + 2.86984316E-08 1.04896388E-14 0.00000000E+00 6.81457088E-11 0.00000000E+00 + 3.26823163E-14-7.33080602E-06-3.88557215E-20 4.40550936E-08 2.31667469E-22 + 7.85787590E-05 0.00000000E+00-4.71110662E-07 0.00000000E+00-2.88943188E-04 +-4.37482490E-10 0.00000000E+00-6.54762054E-10-1.25879730E-03-6.64815447E-18 +-7.85033210E-06-4.14921855E-20 1.27264309E-02 0.00000000E+00 7.95236358E-05 + 0.00000000E+00 5.67431196E-03 8.71456610E-09 6.30628644E-03 9.60815808E-09 + 0.00000000E+00 1.29799909E-08 0.00000000E+00 1.43497176E-08-7.03592853E-03 +-3.57263373E-17 5.58395968E-07 4.93133083E-21 7.30771816E-02 0.00000000E+00 +-1.02371274E-06 0.00000000E+00 5.79093911E-03 8.75533657E-09-2.84456802E-04 +-4.35913344E-10 0.00000000E+00 1.31105409E-08 0.00000000E+00-6.49738915E-10 +-1.17586187E-03-6.18093388E-18 7.37170432E-06 3.84375963E-20 1.25744071E-02 + 0.00000000E+00-7.86461491E-05 0.00000000E+00 0.00000000E+00 3.25242441E-14 +-2.95487065E-08 9.87566971E-15-7.96025705E-05 0.00000000E+00-4.76809066E-07 + 0.00000000E+00 7.88921304E-06-4.16923935E-20 4.71626151E-08-2.49651837E-22 + 0.00000000E+00-6.73635194E-11 0.00000000E+00 6.51236672E-14 2.94241833E-05 +-4.52458645E-11-5.82123872E-08 2.03132190E-14-1.02371274E-06 0.00000000E+00 + 1.26375306E-06 0.00000000E+00 5.58395968E-07-4.93133083E-21-1.21648058E-07 + 6.31739241E-22 0.00000000E+00 6.81457088E-11 0.00000000E+00 3.26823163E-14 +-3.01230336E-05 4.54900757E-11-2.86984316E-08 1.04896388E-14 7.85787590E-05 + 0.00000000E+00-4.71110662E-07 0.00000000E+00-7.33080602E-06 3.88557215E-20 + 4.40550936E-08-2.31667469E-22 0.00000000E+00-6.54762054E-10 2.88943188E-04 +-4.37482490E-10 1.27264309E-02 0.00000000E+00 7.95236358E-05 0.00000000E+00 +-1.25879730E-03 6.64815447E-18-7.85033210E-06 4.14921855E-20 0.00000000E+00 + 1.29799909E-08 0.00000000E+00 1.43497176E-08-5.67431196E-03 8.71456610E-09 +-6.30628644E-03 9.60815808E-09 7.30771816E-02 0.00000000E+00-1.02371274E-06 + 0.00000000E+00-7.03592853E-03 3.57263373E-17 5.58395968E-07-4.93133083E-21 + 0.00000000E+00 1.31105409E-08 0.00000000E+00-6.49738915E-10-5.79093911E-03 + 8.75533657E-09 2.84456802E-04-4.35913344E-10 1.25744071E-02 0.00000000E+00 +-7.86461491E-05 0.00000000E+00-1.17586187E-03 6.18093388E-18 7.37170432E-06 +-3.84375963E-20-5.77652463E-04-1.40342818E-18-1.27456508E-03 0.00000000E+00 + 2.76426913E-04 4.33299426E-10-2.95487065E-08-9.87566971E-15 0.00000000E+00 + 6.40985460E-10 0.00000000E+00-3.25242441E-14 1.19512299E-03 1.64733560E-18 + 4.78140513E-03 7.41271617E-18 2.59335717E-03 0.00000000E+00 1.03733741E-02 + 0.00000000E+00-6.30628644E-03-9.60815808E-09-5.82123872E-08-2.03132190E-14 + 0.00000000E+00-1.43497176E-08 0.00000000E+00-6.51236672E-14 1.19512061E-03 + 1.39689861E-18-6.18111893E-04-1.08964588E-18 2.59334972E-03 0.00000000E+00 +-1.31876053E-03 0.00000000E+00 2.96612801E-04 4.40356487E-10-2.86984316E-08 +-1.04896388E-14 0.00000000E+00 6.63582414E-10 0.00000000E+00-3.26823163E-14 + 2.50490315E-03 0.00000000E+00 1.11548686E-03-3.96637713E-18 0.00000000E+00 +-1.29349039E-08 0.00000000E+00-6.72334225E-11 5.63334961E-03-8.70087613E-09 + 2.93059884E-05-4.52063619E-11 2.03930721E-02 0.00000000E+00 2.59335717E-03 + 0.00000000E+00 9.24170138E-03-2.28171192E-17 1.19512299E-03-1.64733560E-18 + 0.00000000E+00-1.29799909E-08 0.00000000E+00 6.73635194E-11 5.67431196E-03 +-8.71456610E-09-2.94241833E-05 4.52458645E-11 1.03844794E-03 2.74371749E-18 + 2.41635056E-03 0.00000000E+00-5.47124959E-03-8.64988315E-09-2.84654675E-05 +-4.49405780E-11 0.00000000E+00-1.27602698E-08 0.00000000E+00-6.63262686E-11 + 8.61500364E-03 2.66218944E-17 1.11548915E-03 3.85561092E-18 1.96850731E-02 + 0.00000000E+00 2.50491035E-03 0.00000000E+00-5.51335675E-03-8.66265612E-09 + 2.85869674E-05 4.49774351E-11 0.00000000E+00-1.28050760E-08 0.00000000E+00 + 6.64555563E-11-1.23031523E-03 0.00000000E+00-5.38484275E-04 1.64983210E-18 + 0.00000000E+00 6.32290000E-10 0.00000000E+00-3.23219183E-14-2.68175973E-04 + 4.30867348E-10 3.03749630E-08-9.21427741E-15 2.50491035E-03 0.00000000E+00 + 1.00195893E-02 0.00000000E+00 1.11548915E-03-3.85561092E-18 4.46287880E-03 +-1.44481902E-17 0.00000000E+00-1.41568942E-08 0.00000000E+00-6.47642424E-14 + 6.13107750E-03-9.54963219E-09 5.98980597E-08-1.90411647E-14 2.50490315E-03 + 0.00000000E+00-1.27456508E-03 0.00000000E+00 1.11548686E-03-3.96637713E-18 +-5.77652463E-04 1.40342818E-18 0.00000000E+00 6.54762054E-10 0.00000000E+00 +-3.25242441E-14-2.88943188E-04 4.37482490E-10 2.95487065E-08-9.87566971E-15 + 3.03749630E-08 9.21427741E-15 0.00000000E+00 3.23219183E-14 8.38111041E-06 + 1.67129568E-20 5.01164202E-08 1.04250059E-22-8.07158229E-05 0.00000000E+00 +-4.83444372E-07 0.00000000E+00-2.85869674E-05-4.49774351E-11 5.98980597E-08 + 1.90411647E-14 0.00000000E+00-6.64555563E-11 0.00000000E+00 6.47642424E-14 + 5.30780368E-07-3.16951190E-20-1.29728807E-07-4.97648537E-22-1.19199185E-06 + 0.00000000E+00 1.28018598E-06 0.00000000E+00 2.93059884E-05 4.52063619E-11 + 2.95487065E-08 9.87566971E-15 0.00000000E+00 6.72334225E-11 0.00000000E+00 + 3.25242441E-14-7.85033210E-06-4.14921855E-20 4.71626151E-08 2.49651837E-22 + 7.95236358E-05 0.00000000E+00-4.76809066E-07 0.00000000E+00-2.81042075E-04 +-4.34770226E-10 0.00000000E+00-6.45980816E-10-1.33762888E-03-2.81435786E-18 +-8.34416290E-06-1.83542046E-20 1.29034602E-02 0.00000000E+00 8.06243489E-05 + 0.00000000E+00 5.51335675E-03 8.66265612E-09 6.13107750E-03 9.54963219E-09 + 0.00000000E+00 1.28050760E-08 0.00000000E+00 1.41568942E-08-7.50315214E-03 +-3.03371737E-17 5.30780368E-07-3.16951190E-20 7.40265694E-02 0.00000000E+00 +-1.19199185E-06 0.00000000E+00 5.63334961E-03 8.70087613E-09-2.76426913E-04 +-4.33299426E-10 0.00000000E+00 1.29349039E-08 0.00000000E+00-6.40985460E-10 +-1.25879730E-03-6.64815447E-18 7.88921304E-06 4.16923935E-20 1.27264309E-02 + 0.00000000E+00-7.96025705E-05 0.00000000E+00 0.00000000E+00 3.23219183E-14 +-3.03749630E-08 9.21427741E-15-8.07158229E-05 0.00000000E+00-4.83444372E-07 + 0.00000000E+00 8.38111041E-06-1.67129568E-20 5.01164202E-08-1.04250059E-22 + 0.00000000E+00-6.64555563E-11 0.00000000E+00 6.47642424E-14 2.85869674E-05 +-4.49774351E-11-5.98980597E-08 1.90411647E-14-1.19199185E-06 0.00000000E+00 + 1.28018598E-06 0.00000000E+00 5.30780368E-07 3.16951190E-20-1.29728807E-07 + 4.97648537E-22 0.00000000E+00 6.72334225E-11 0.00000000E+00 3.25242441E-14 +-2.93059884E-05 4.52063619E-11-2.95487065E-08 9.87566971E-15 7.95236358E-05 + 0.00000000E+00-4.76809066E-07 0.00000000E+00-7.85033210E-06 4.14921855E-20 + 4.71626151E-08-2.49651837E-22 0.00000000E+00-6.45980816E-10 2.81042075E-04 +-4.34770226E-10 1.29034602E-02 0.00000000E+00 8.06243489E-05 0.00000000E+00 +-1.33762888E-03 2.81435786E-18-8.34416290E-06 1.83542046E-20 0.00000000E+00 + 1.28050760E-08 0.00000000E+00 1.41568942E-08-5.51335675E-03 8.66265612E-09 +-6.13107750E-03 9.54963219E-09 7.40265694E-02 0.00000000E+00-1.19199185E-06 + 0.00000000E+00-7.50315214E-03 3.03371737E-17 5.30780368E-07 3.16951190E-20 + 0.00000000E+00 1.29349039E-08 0.00000000E+00-6.40985460E-10-5.63334961E-03 + 8.70087613E-09 2.76426913E-04-4.33299426E-10 1.27264309E-02 0.00000000E+00 +-7.96025705E-05 0.00000000E+00-1.25879730E-03 6.64815447E-18 7.88921304E-06 +-4.16923935E-20-5.38484275E-04-1.64983210E-18-1.23031523E-03 0.00000000E+00 + 2.68175973E-04 4.30867348E-10-3.03749630E-08-9.21427741E-15 0.00000000E+00 + 6.32290000E-10 0.00000000E+00-3.23219183E-14 1.11548915E-03 3.85561092E-18 + 4.46287880E-03 1.44481902E-17 2.50491035E-03 0.00000000E+00 1.00195893E-02 + 0.00000000E+00-6.13107750E-03-9.54963219E-09-5.98980597E-08-1.90411647E-14 + 0.00000000E+00-1.41568942E-08 0.00000000E+00-6.47642424E-14 1.11548686E-03 + 3.96637713E-18-5.77652463E-04-1.40342818E-18 2.50490315E-03 0.00000000E+00 +-1.27456508E-03 0.00000000E+00 2.88943188E-04 4.37482490E-10-2.95487065E-08 +-9.87566971E-15 0.00000000E+00 6.54762054E-10 0.00000000E+00-3.25242441E-14 + 2.41635056E-03 0.00000000E+00 1.03844794E-03-2.74371749E-18 0.00000000E+00 +-1.27602698E-08 0.00000000E+00-6.63262686E-11 5.47124959E-03-8.64988315E-09 + 2.84654675E-05-4.49405780E-11 1.96850731E-02 0.00000000E+00 2.50491035E-03 + 0.00000000E+00 8.61500364E-03-2.66218944E-17 1.11548915E-03-3.85561092E-18 + 0.00000000E+00-1.28050760E-08 0.00000000E+00 6.64555563E-11 5.51335675E-03 +-8.66265612E-09-2.85869674E-05 4.49774351E-11 9.64026674E-04 2.60236754E-18 + 2.32769606E-03 0.00000000E+00-5.30486915E-03-8.60264674E-09-2.76026374E-05 +-4.46942102E-11 0.00000000E+00-1.25869062E-08 0.00000000E+00-6.54256218E-11 + 8.00915517E-03 2.08450139E-17 1.03845000E-03 2.69087132E-18 1.89762427E-02 + 0.00000000E+00 2.41635754E-03 0.00000000E+00-5.34805454E-03-8.61442331E-09 + 2.77272478E-05 4.47281925E-11 0.00000000E+00-1.26313576E-08 0.00000000E+00 + 6.55538857E-11-1.18601340E-03 0.00000000E+00-5.00619168E-04 1.32330972E-18 + 0.00000000E+00 6.23667596E-10 0.00000000E+00-3.20659859E-14-2.59719415E-04 + 4.28633317E-10 3.11526041E-08-8.49557253E-15 2.41635754E-03 0.00000000E+00 + 9.66537993E-03 0.00000000E+00 1.03845000E-03-2.69087132E-18 4.15473090E-03 +-1.12329059E-17 0.00000000E+00-1.39652748E-08 0.00000000E+00-6.43088885E-14 + 5.95098212E-03-9.49503098E-09 6.14944277E-08-1.76643049E-14 2.41635056E-03 + 0.00000000E+00-1.23031523E-03 0.00000000E+00 1.03844794E-03-2.74371749E-18 +-5.38484275E-04 1.64983210E-18 0.00000000E+00 6.45980816E-10 0.00000000E+00 +-3.23219183E-14-2.81042075E-04 4.34770226E-10 3.03749630E-08-9.21427741E-15 + 3.11526041E-08 8.49557253E-15 0.00000000E+00 3.20659859E-14 8.84836065E-06 + 4.91079882E-20 5.29223146E-08 2.87945345E-22-8.20006067E-05 0.00000000E+00 +-4.91103965E-07 0.00000000E+00-2.77272478E-05-4.47281925E-11 6.14944277E-08 + 1.76643049E-14 0.00000000E+00-6.55538857E-11 0.00000000E+00 6.43088885E-14 + 5.04189481E-07 4.24739456E-20-1.37407529E-07-4.67883815E-22-1.37600480E-06 + 0.00000000E+00 1.29923084E-06 0.00000000E+00 2.84654675E-05 4.49405780E-11 + 3.03749630E-08 9.21427741E-15 0.00000000E+00 6.63262686E-11 0.00000000E+00 + 3.23219183E-14-8.34416290E-06-1.83542046E-20 5.01164202E-08 1.04250059E-22 + 8.06243489E-05 0.00000000E+00-4.83444372E-07 0.00000000E+00-2.72914959E-04 +-4.32231740E-10 0.00000000E+00-6.37249963E-10-1.41251182E-03-7.64186785E-18 +-8.81327365E-06-4.66109572E-20 1.31078266E-02 0.00000000E+00 8.18953569E-05 + 0.00000000E+00 5.34805454E-03 8.61442331E-09 5.95098212E-03 9.49503098E-09 + 0.00000000E+00 1.26313576E-08 0.00000000E+00 1.39652748E-08-7.94712825E-03 +-2.41655800E-17 5.04189481E-07 4.24739456E-20 7.51268615E-02 0.00000000E+00 +-1.37600480E-06 0.00000000E+00 5.47124959E-03 8.64988315E-09-2.68175973E-04 +-4.30867348E-10 0.00000000E+00 1.27602698E-08 0.00000000E+00-6.32290000E-10 +-1.33762888E-03-2.81435786E-18 8.38111041E-06 1.67129568E-20 1.29034602E-02 + 0.00000000E+00-8.07158229E-05 0.00000000E+00 0.00000000E+00 3.20659859E-14 +-3.11526041E-08 8.49557253E-15-8.20006067E-05 0.00000000E+00-4.91103965E-07 + 0.00000000E+00 8.84836065E-06-4.91079882E-20 5.29223146E-08-2.87945345E-22 + 0.00000000E+00-6.55538857E-11 0.00000000E+00 6.43088885E-14 2.77272478E-05 +-4.47281925E-11-6.14944277E-08 1.76643049E-14-1.37600480E-06 0.00000000E+00 + 1.29923084E-06 0.00000000E+00 5.04189481E-07-4.24739456E-20-1.37407529E-07 + 4.67883815E-22 0.00000000E+00 6.63262686E-11 0.00000000E+00 3.23219183E-14 +-2.84654675E-05 4.49405780E-11-3.03749630E-08 9.21427741E-15 8.06243489E-05 + 0.00000000E+00-4.83444372E-07 0.00000000E+00-8.34416290E-06 1.83542046E-20 + 5.01164202E-08-1.04250059E-22 0.00000000E+00-6.37249963E-10 2.72914959E-04 +-4.32231740E-10 1.31078266E-02 0.00000000E+00 8.18953569E-05 0.00000000E+00 +-1.41251182E-03 7.64186785E-18-8.81327365E-06 4.66109572E-20 0.00000000E+00 + 1.26313576E-08 0.00000000E+00 1.39652748E-08-5.34805454E-03 8.61442331E-09 +-5.95098212E-03 9.49503098E-09 7.51268615E-02 0.00000000E+00-1.37600480E-06 + 0.00000000E+00-7.94712825E-03 2.41655800E-17 5.04189481E-07-4.24739456E-20 + 0.00000000E+00 1.27602698E-08 0.00000000E+00-6.32290000E-10-5.47124959E-03 + 8.64988315E-09 2.68175973E-04-4.30867348E-10 1.29034602E-02 0.00000000E+00 +-8.07158229E-05 0.00000000E+00-1.33762888E-03 2.81435786E-18 8.38111041E-06 +-1.67129568E-20-5.00619168E-04-1.32330972E-18-1.18601340E-03 0.00000000E+00 + 2.59719415E-04 4.28633317E-10-3.11526041E-08-8.49557253E-15 0.00000000E+00 + 6.23667596E-10 0.00000000E+00-3.20659859E-14 1.03845000E-03 2.69087132E-18 + 4.15473090E-03 1.12329059E-17 2.41635754E-03 0.00000000E+00 9.66537993E-03 + 0.00000000E+00-5.95098212E-03-9.49503098E-09-6.14944277E-08-1.76643049E-14 + 0.00000000E+00-1.39652748E-08 0.00000000E+00-6.43088885E-14 1.03844794E-03 + 2.74371749E-18-5.38484275E-04-1.64983210E-18 2.41635056E-03 0.00000000E+00 +-1.23031523E-03 0.00000000E+00 2.81042075E-04 4.34770226E-10-3.03749630E-08 +-9.21427741E-15 0.00000000E+00 6.45980816E-10 0.00000000E+00-3.23219183E-14 + 2.32769606E-03 0.00000000E+00 9.64026674E-04-2.60236754E-18 0.00000000E+00 +-1.25869062E-08 0.00000000E+00-6.54256218E-11 5.30486915E-03-8.60264674E-09 + 2.76026374E-05-4.46942102E-11 1.89762427E-02 0.00000000E+00 2.41635754E-03 + 0.00000000E+00 8.00915517E-03-2.08450139E-17 1.03845000E-03-2.69087132E-18 + 0.00000000E+00-1.26313576E-08 0.00000000E+00 6.55538857E-11 5.34805454E-03 +-8.61442331E-09-2.77272478E-05 4.47281925E-11-1.14166164E-03 0.00000000E+00 +-4.64068653E-04 1.34638817E-18 0.00000000E+00 6.15134126E-10 0.00000000E+00 +-3.17522453E-14-2.51065172E-04 4.26616148E-10 3.18946474E-08-7.70969791E-15 + 2.32770277E-03 0.00000000E+00 9.31076291E-03 0.00000000E+00 9.64028625E-04 +-2.74068541E-18 3.85705378E-03-1.06809089E-17 0.00000000E+00-1.37751734E-08 + 0.00000000E+00-6.37432871E-14 5.76626625E-03-9.44469362E-09 6.30282266E-08 +-1.61644781E-14 2.32769606E-03 0.00000000E+00-1.18601340E-03 0.00000000E+00 + 9.64026674E-04-2.60236754E-18-5.00619168E-04 1.32330972E-18 0.00000000E+00 + 6.37249963E-10 0.00000000E+00-3.20659859E-14-2.72914959E-04 4.32231740E-10 + 3.11526041E-08-8.49557253E-15 3.18946474E-08 7.70969791E-15 0.00000000E+00 + 3.17522453E-14 9.29203452E-06 5.64696845E-21 5.55866977E-08 4.62362673E-23 +-8.34741005E-05 0.00000000E+00-4.99890238E-07 0.00000000E+00-2.68460972E-05 +-4.44998502E-11 6.30282266E-08 1.61644781E-14 0.00000000E+00-6.46600521E-11 + 0.00000000E+00 6.37432871E-14 4.78775999E-07-5.40337409E-20-1.44700252E-07 +-5.34512247E-22-1.57834559E-06 0.00000000E+00 1.32114146E-06 0.00000000E+00 + 2.76026374E-05 4.46942102E-11 3.11526041E-08 8.49557253E-15 0.00000000E+00 + 6.54256218E-11 0.00000000E+00 3.20659859E-14-8.81327365E-06-4.66109572E-20 + 5.29223146E-08 2.87945345E-22 8.18953569E-05 0.00000000E+00-4.91103965E-07 + 0.00000000E+00-2.64574906E-04-4.29881653E-10 0.00000000E+00-6.28583539E-10 +-1.48361675E-03-1.26828986E-18-9.25872775E-06-1.00796796E-20 1.33422631E-02 + 0.00000000E+00 8.33536544E-05 0.00000000E+00 5.17861683E-03 8.57019458E-09 + 5.76626625E-03 9.44469362E-09 0.00000000E+00 1.24591315E-08 0.00000000E+00 + 1.37751734E-08-8.36877132E-03-3.51097855E-17 4.78775999E-07-5.40337409E-20 + 7.63927802E-02 0.00000000E+00-1.57834559E-06 0.00000000E+00 5.30486915E-03 + 8.60264674E-09-2.59719415E-04-4.28633317E-10 0.00000000E+00 1.25869062E-08 + 0.00000000E+00-6.23667596E-10-1.41251182E-03-7.64186785E-18 8.84836065E-06 + 4.91079882E-20 1.31078266E-02 0.00000000E+00-8.20006067E-05 0.00000000E+00 + 0.00000000E+00 3.17522453E-14-3.18946474E-08 7.70969791E-15-8.34741005E-05 + 0.00000000E+00-4.99890238E-07 0.00000000E+00 9.29203452E-06-5.64696845E-21 + 5.55866977E-08-4.62362673E-23 0.00000000E+00-6.46600521E-11 0.00000000E+00 + 6.37432871E-14 2.68460972E-05-4.44998502E-11-6.30282266E-08 1.61644781E-14 +-1.57834559E-06 0.00000000E+00 1.32114146E-06 0.00000000E+00 4.78775999E-07 + 5.40337409E-20-1.44700252E-07 5.34512247E-22 0.00000000E+00 6.54256218E-11 + 0.00000000E+00 3.20659859E-14-2.76026374E-05 4.46942102E-11-3.11526041E-08 + 8.49557253E-15 8.18953569E-05 0.00000000E+00-4.91103965E-07 0.00000000E+00 +-8.81327365E-06 4.66109572E-20 5.29223146E-08-2.87945345E-22 0.00000000E+00 +-6.28583539E-10 2.64574906E-04-4.29881653E-10 1.33422631E-02 0.00000000E+00 + 8.33536544E-05 0.00000000E+00-1.48361675E-03 1.26828986E-18-9.25872775E-06 + 1.00796796E-20 0.00000000E+00 1.24591315E-08 0.00000000E+00 1.37751734E-08 +-5.17861683E-03 8.57019458E-09-5.76626625E-03 9.44469362E-09 7.63927802E-02 + 0.00000000E+00-1.57834559E-06 0.00000000E+00-8.36877132E-03 3.51097855E-17 + 4.78775999E-07 5.40337409E-20 0.00000000E+00 1.25869062E-08 0.00000000E+00 +-6.23667596E-10-5.30486915E-03 8.60264674E-09 2.59719415E-04-4.28633317E-10 + 1.31078266E-02 0.00000000E+00-8.20006067E-05 0.00000000E+00-1.41251182E-03 + 7.64186785E-18 8.84836065E-06-4.91079882E-20-4.64068653E-04-1.34638817E-18 +-1.14166164E-03 0.00000000E+00 2.51065172E-04 4.26616148E-10-3.18946474E-08 +-7.70969791E-15 0.00000000E+00 6.15134126E-10 0.00000000E+00-3.17522453E-14 + 9.64028625E-04 2.74068541E-18 3.85705378E-03 1.06809089E-17 2.32770277E-03 + 0.00000000E+00 9.31076291E-03 0.00000000E+00-5.76626625E-03-9.44469362E-09 +-6.30282266E-08-1.61644781E-14 0.00000000E+00-1.37751734E-08 0.00000000E+00 +-6.37432871E-14 9.64026674E-04 2.60236754E-18-5.00619168E-04-1.32330972E-18 + 2.32769606E-03 0.00000000E+00-1.18601340E-03 0.00000000E+00 2.72914959E-04 + 4.32231740E-10-3.11526041E-08-8.49557253E-15 0.00000000E+00 6.37249963E-10 + 0.00000000E+00-3.20659859E-14 8.92245988E-04 2.64486728E-18 2.23894378E-03 + 0.00000000E+00-5.13440324E-03-8.55950758E-09-2.67185186E-05-4.44690114E-11 + 0.00000000E+00-1.24151153E-08 0.00000000E+00-6.45330432E-11 7.42434076E-03 + 2.19332035E-17 9.64028625E-04 2.74068541E-18 1.82666133E-02 0.00000000E+00 + 2.32770277E-03 0.00000000E+00-5.17861683E-03-8.57019458E-09 2.68460972E-05 + 4.44998502E-11 0.00000000E+00-1.24591315E-08 0.00000000E+00 6.46600521E-11 + 2.23894378E-03 0.00000000E+00 8.92245988E-04-2.64486728E-18 0.00000000E+00 +-1.24151153E-08 0.00000000E+00-6.45330432E-11 5.13440324E-03-8.55950758E-09 + 2.67185186E-05-4.44690114E-11 1.82666133E-02 0.00000000E+00 2.32770277E-03 + 0.00000000E+00 7.42434076E-03-2.19332035E-17 9.64028625E-04-2.74068541E-18 + 0.00000000E+00-1.24591315E-08 0.00000000E+00 6.46600521E-11 5.17861683E-03 +-8.57019458E-09-2.68460972E-05 4.44998502E-11-1.09726207E-03 0.00000000E+00 +-4.28843512E-04 1.16940036E-18 0.00000000E+00 6.06708075E-10 0.00000000E+00 +-3.13723869E-14-2.42230261E-04 4.24838612E-10 3.25816368E-08-6.84323783E-15 + 2.23895021E-03 0.00000000E+00 8.95575477E-03 0.00000000E+00 8.92247759E-04 +-2.44011470E-18 3.56993802E-03-1.01306976E-17 0.00000000E+00-1.35869347E-08 + 0.00000000E+00-6.30531016E-14 5.57715865E-03-9.39901980E-09 6.44499972E-08 +-1.45165056E-14 2.23894378E-03 0.00000000E+00-1.14166164E-03 0.00000000E+00 + 8.92245988E-04-2.64486728E-18-4.64068653E-04 1.34638817E-18 0.00000000E+00 + 6.28583539E-10 0.00000000E+00-3.17522453E-14-2.64574906E-04 4.29881653E-10 + 3.18946474E-08-7.70969791E-15 8.23126291E-04 2.23748674E-18 2.15009806E-03 + 0.00000000E+00-4.96013274E-03-8.52087362E-09-2.58145508E-05-4.42670791E-11 + 0.00000000E+00-1.22452374E-08 0.00000000E+00-6.36502883E-11 6.86073275E-03 + 1.81848843E-17 8.92247759E-04 2.44011470E-18 1.75562188E-02 0.00000000E+00 + 2.23895021E-03 0.00000000E+00-5.00529878E-03-8.53035934E-09 2.59448774E-05 + 4.42944520E-11 0.00000000E+00-1.22887268E-08 0.00000000E+00 6.37757779E-11 + 2.15009806E-03 0.00000000E+00 8.23126291E-04-2.23748674E-18 0.00000000E+00 +-1.22452374E-08 0.00000000E+00-6.36502883E-11 4.96013274E-03-8.52087362E-09 + 2.58145508E-05-4.42670791E-11 1.75562188E-02 0.00000000E+00 2.23895021E-03 + 0.00000000E+00 6.86073275E-03-1.81848843E-17 8.92247759E-04-2.44011470E-18 + 0.00000000E+00-1.22887268E-08 0.00000000E+00 6.37757779E-11 5.00529878E-03 +-8.53035934E-09-2.59448774E-05 4.42944520E-11 3.25816368E-08 6.84323783E-15 + 0.00000000E+00 3.13723869E-14 9.71289579E-06 1.56589631E-20 5.81142382E-08 + 8.54113169E-23-8.51570274E-05 0.00000000E+00-5.09926482E-07 0.00000000E+00 +-2.59448774E-05-4.42944520E-11 6.44499972E-08 1.45165056E-14 0.00000000E+00 +-6.37757779E-11 0.00000000E+00 6.30531016E-14 4.54180716E-07 1.35644802E-20 +-1.51622241E-07-8.38077942E-23-1.80288328E-06 0.00000000E+00 1.34621721E-06 + 0.00000000E+00 2.67185186E-05 4.44690114E-11 3.18946474E-08 7.70969791E-15 + 0.00000000E+00 6.45330432E-11 0.00000000E+00 3.17522453E-14-9.25872775E-06 +-1.00796796E-20 5.55866977E-08 4.62362673E-23 8.33536544E-05 0.00000000E+00 +-4.99890238E-07 0.00000000E+00-2.56031009E-04-4.27737067E-10 0.00000000E+00 +-6.19996533E-10-1.55106850E-03-2.27307376E-18-9.68132126E-06-1.27882614E-20 + 1.36100596E-02 0.00000000E+00 8.50196577E-05 0.00000000E+00 5.00529878E-03 + 8.53035934E-09 5.57715865E-03 9.39901980E-09 0.00000000E+00 1.22887268E-08 + 0.00000000E+00 1.35869347E-08-8.76898833E-03-7.93120732E-19 4.54180716E-07 + 1.35644802E-20 7.78415606E-02 0.00000000E+00-1.80288328E-06 0.00000000E+00 + 5.13440324E-03 8.55950758E-09-2.51065172E-04-4.26616148E-10 0.00000000E+00 + 1.24151153E-08 0.00000000E+00-6.15134126E-10-1.48361675E-03-1.26828986E-18 + 9.29203452E-06 5.64696845E-21 1.33422631E-02 0.00000000E+00-8.34741005E-05 + 0.00000000E+00 0.00000000E+00 3.13723869E-14-3.25816368E-08 6.84323783E-15 +-8.51570274E-05 0.00000000E+00-5.09926482E-07 0.00000000E+00 9.71289579E-06 +-1.56589631E-20 5.81142382E-08-8.54113169E-23 0.00000000E+00-6.37757779E-11 + 0.00000000E+00 6.30531016E-14 2.59448774E-05-4.42944520E-11-6.44499972E-08 + 1.45165056E-14-1.80288328E-06 0.00000000E+00 1.34621721E-06 0.00000000E+00 + 4.54180716E-07-1.35644802E-20-1.51622241E-07 8.38077942E-23 0.00000000E+00 + 6.45330432E-11 0.00000000E+00 3.17522453E-14-2.67185186E-05 4.44690114E-11 +-3.18946474E-08 7.70969791E-15 8.33536544E-05 0.00000000E+00-4.99890238E-07 + 0.00000000E+00-9.25872775E-06 1.00796796E-20 5.55866977E-08-4.62362673E-23 + 0.00000000E+00-6.19996533E-10 2.56031009E-04-4.27737067E-10 1.36100596E-02 + 0.00000000E+00 8.50196577E-05 0.00000000E+00-1.55106850E-03 2.27307376E-18 +-9.68132126E-06 1.27882614E-20 0.00000000E+00 1.22887268E-08 0.00000000E+00 + 1.35869347E-08-5.00529878E-03 8.53035934E-09-5.57715865E-03 9.39901980E-09 + 7.78415606E-02 0.00000000E+00-1.80288328E-06 0.00000000E+00-8.76898833E-03 + 7.93120732E-19 4.54180716E-07-1.35644802E-20 0.00000000E+00 1.24151153E-08 + 0.00000000E+00-6.15134126E-10-5.13440324E-03 8.55950758E-09 2.51065172E-04 +-4.26616148E-10 1.33422631E-02 0.00000000E+00-8.34741005E-05 0.00000000E+00 +-1.48361675E-03 1.26828986E-18 9.29203452E-06-5.64696845E-21-4.28843512E-04 +-1.16940036E-18-1.09726207E-03 0.00000000E+00 2.42230261E-04 4.24838612E-10 +-3.25816368E-08-6.84323783E-15 0.00000000E+00 6.06708075E-10 0.00000000E+00 +-3.13723869E-14 8.92247759E-04 2.44011470E-18 3.56993802E-03 1.01306976E-17 + 2.23895021E-03 0.00000000E+00 8.95575477E-03 0.00000000E+00-5.57715865E-03 +-9.39901980E-09-6.44499972E-08-1.45165056E-14 0.00000000E+00-1.35869347E-08 + 0.00000000E+00-6.30531016E-14 8.92245988E-04 2.64486728E-18-4.64068653E-04 +-1.34638817E-18 2.23894378E-03 0.00000000E+00-1.14166164E-03 0.00000000E+00 + 2.64574906E-04 4.29881653E-10-3.18946474E-08-7.70969791E-15 0.00000000E+00 + 6.28583539E-10 0.00000000E+00-3.17522453E-14 7.56687796E-04 2.85531603E-18 + 2.06116398E-03 0.00000000E+00-4.78226796E-03-8.48722739E-09-2.48918625E-05 +-4.40908949E-11 0.00000000E+00-1.20776565E-08 0.00000000E+00-6.27793363E-11 + 6.31849298E-03 2.15351735E-17 8.23127777E-04 2.43766165E-18 1.68450968E-02 + 0.00000000E+00 2.15010416E-03 0.00000000E+00-4.82834366E-03-8.49537957E-09 + 2.50248143E-05 4.41144205E-11 0.00000000E+00-1.21205154E-08 0.00000000E+00 + 6.29030074E-11-1.05281704E-03 0.00000000E+00-3.94953893E-04 1.32324442E-18 + 0.00000000E+00 5.98410203E-10 0.00000000E+00-3.09177743E-14-2.33220986E-04 + 4.23327499E-10 3.32379449E-08-5.88139767E-15 2.15010416E-03 0.00000000E+00 + 8.60037310E-03 0.00000000E+00 8.23127777E-04-2.43766165E-18 3.29346594E-03 +-9.57792739E-18 0.00000000E+00-1.34009505E-08 0.00000000E+00-6.22236823E-14 + 5.38397031E-03-9.35848745E-09 6.57900283E-08-1.26943546E-14 2.15009806E-03 + 0.00000000E+00-1.09726207E-03 0.00000000E+00 8.23126291E-04-2.23748674E-18 +-4.28843512E-04 1.16940036E-18 0.00000000E+00 6.19996533E-10 0.00000000E+00 +-3.13723869E-14-2.56031009E-04 4.27737067E-10 3.25816368E-08-6.84323783E-15 + 3.32379449E-08 5.88139767E-15 0.00000000E+00 3.09177743E-14 1.01116728E-05 + 3.56149283E-20 6.05092510E-08 2.09854745E-22-8.70735147E-05 0.00000000E+00 +-5.21356531E-07 0.00000000E+00-2.50248143E-05-4.41144205E-11 6.57900283E-08 + 1.26943546E-14 0.00000000E+00-6.29030074E-11 0.00000000E+00 6.22236823E-14 + 4.30358850E-07 2.01354232E-20-1.58184868E-07-4.15474433E-22-2.05322726E-06 + 0.00000000E+00 1.37481494E-06 0.00000000E+00 2.58145508E-05 4.42670791E-11 + 3.25816368E-08 6.84323783E-15 0.00000000E+00 6.36502883E-11 0.00000000E+00 + 3.13723869E-14-9.68132126E-06-1.27882614E-20 5.81142382E-08 8.54113169E-23 + 8.50196577E-05 0.00000000E+00-5.09926482E-07 0.00000000E+00-2.47299688E-04 +-4.25818492E-10 0.00000000E+00-6.11506032E-10-1.61498236E-03-5.60447141E-18 +-1.00817666E-05-3.44489470E-20 1.39150548E-02 0.00000000E+00 8.69172405E-05 + 0.00000000E+00 4.82834366E-03 8.49537957E-09 5.38397031E-03 9.35848745E-09 + 0.00000000E+00 1.21205154E-08 0.00000000E+00 1.34009505E-08-9.14841052E-03 +-2.49957438E-17 4.30358850E-07 2.01354232E-20 7.94938701E-02 0.00000000E+00 +-2.05322726E-06 0.00000000E+00 4.96013274E-03 8.52087362E-09-2.42230261E-04 +-4.24838612E-10 0.00000000E+00 1.22452374E-08 0.00000000E+00-6.06708075E-10 +-1.55106850E-03-2.27307376E-18 9.71289579E-06 1.56589631E-20 1.36100596E-02 + 0.00000000E+00-8.51570274E-05 0.00000000E+00 0.00000000E+00 3.09177743E-14 +-3.32379449E-08 5.88139767E-15-8.70735147E-05 0.00000000E+00-5.21356531E-07 + 0.00000000E+00 1.01116728E-05-3.56149283E-20 6.05092510E-08-2.09854745E-22 + 0.00000000E+00-6.29030074E-11 0.00000000E+00 6.22236823E-14 2.50248143E-05 +-4.41144205E-11-6.57900283E-08 1.26943546E-14-2.05322726E-06 0.00000000E+00 + 1.37481494E-06 0.00000000E+00 4.30358850E-07-2.01354232E-20-1.58184868E-07 + 4.15474433E-22 0.00000000E+00 6.36502883E-11 0.00000000E+00 3.13723869E-14 +-2.58145508E-05 4.42670791E-11-3.25816368E-08 6.84323783E-15 8.50196577E-05 + 0.00000000E+00-5.09926482E-07 0.00000000E+00-9.68132126E-06 1.27882614E-20 + 5.81142382E-08-8.54113169E-23 0.00000000E+00-6.11506032E-10 2.47299688E-04 +-4.25818492E-10 1.39150548E-02 0.00000000E+00 8.69172405E-05 0.00000000E+00 +-1.61498236E-03 5.60447141E-18-1.00817666E-05 3.44489470E-20 0.00000000E+00 + 1.21205154E-08 0.00000000E+00 1.34009505E-08-4.82834366E-03 8.49537957E-09 +-5.38397031E-03 9.35848745E-09 7.94938701E-02 0.00000000E+00-2.05322726E-06 + 0.00000000E+00-9.14841052E-03 2.49957438E-17 4.30358850E-07-2.01354232E-20 + 0.00000000E+00 1.22452374E-08 0.00000000E+00-6.06708075E-10-4.96013274E-03 + 8.52087362E-09 2.42230261E-04-4.24838612E-10 1.36100596E-02 0.00000000E+00 +-8.51570274E-05 0.00000000E+00-1.55106850E-03 2.27307376E-18 9.71289579E-06 +-1.56589631E-20-3.94953893E-04-1.32324442E-18-1.05281704E-03 0.00000000E+00 + 2.33220986E-04 4.23327499E-10-3.32379449E-08-5.88139767E-15 0.00000000E+00 + 5.98410203E-10 0.00000000E+00-3.09177743E-14 8.23127777E-04 2.43766165E-18 + 3.29346594E-03 9.57792739E-18 2.15010416E-03 0.00000000E+00 8.60037310E-03 + 0.00000000E+00-5.38397031E-03-9.35848745E-09-6.57900283E-08-1.26943546E-14 + 0.00000000E+00-1.34009505E-08 0.00000000E+00-6.22236823E-14 8.23126291E-04 + 2.23748674E-18-4.28843512E-04-1.16940036E-18 2.15009806E-03 0.00000000E+00 +-1.09726207E-03 0.00000000E+00 2.56031009E-04 4.27737067E-10-3.25816368E-08 +-6.84323783E-15 0.00000000E+00 6.19996533E-10 0.00000000E+00-3.13723869E-14 + 2.06116398E-03 0.00000000E+00 7.56687796E-04-2.85531603E-18 0.00000000E+00 +-1.20776565E-08 0.00000000E+00-6.27793363E-11 4.78226796E-03-8.48722739E-09 + 2.48918625E-05-4.40908949E-11 1.68450968E-02 0.00000000E+00 2.15010416E-03 + 0.00000000E+00 6.31849298E-03-2.15351735E-17 8.23127777E-04-2.43766165E-18 + 0.00000000E+00-1.21205154E-08 0.00000000E+00 6.29030074E-11 4.82834366E-03 +-8.49537957E-09-2.50248143E-05 4.41144205E-11-1.00832880E-03 0.00000000E+00 +-3.62409648E-04 1.18332408E-18 0.00000000E+00 5.90264941E-10 0.00000000E+00 +-3.03760354E-14-2.24045631E-04 4.22115251E-10 3.38624739E-08-4.80468230E-15 + 2.06117003E-03 0.00000000E+00 8.24463786E-03 0.00000000E+00 7.56689263E-04 +-2.82315525E-18 3.02771855E-03-1.08735200E-17 0.00000000E+00-1.32176652E-08 + 0.00000000E+00-6.12326492E-14 5.18689021E-03-9.32366349E-09 6.70776005E-08 +-1.06626800E-14 2.06116398E-03 0.00000000E+00-1.05281704E-03 0.00000000E+00 + 7.56687796E-04-2.85531603E-18-3.94953893E-04 1.32324442E-18 0.00000000E+00 + 6.11506032E-10 0.00000000E+00-3.09177743E-14-2.47299688E-04 4.25818492E-10 + 3.32379449E-08-5.88139767E-15 3.38624739E-08 4.80468230E-15 0.00000000E+00 + 3.03760354E-14 1.04891953E-05 5.13806641E-20 6.27767326E-08 3.06420004E-22 +-8.92519229E-05 0.00000000E+00-5.34349172E-07 0.00000000E+00-2.40867169E-05 +-4.39626553E-11 6.70776005E-08 1.06626800E-14 0.00000000E+00-6.20439804E-11 + 0.00000000E+00 6.12326492E-14 4.07452874E-07 1.91757363E-20-1.64400838E-07 +-6.95299146E-22-2.33384847E-06 0.00000000E+00 1.40734976E-06 0.00000000E+00 + 2.48918625E-05 4.40908949E-11 3.32379449E-08 5.88139767E-15 0.00000000E+00 + 6.27793363E-11 0.00000000E+00 3.09177743E-14-1.00817666E-05-3.44489470E-20 + 6.05092510E-08 2.09854745E-22 8.69172405E-05 0.00000000E+00-5.21356531E-07 + 0.00000000E+00-2.38388806E-04-4.24150119E-10 0.00000000E+00-6.03131233E-10 +-1.67549157E-03-8.16900795E-18-1.04609005E-05-5.07989653E-20 1.42617534E-02 + 0.00000000E+00 8.90743704E-05 0.00000000E+00 4.64790805E-03 8.46580760E-09 + 5.18689021E-03 9.32366349E-09 0.00000000E+00 1.19549247E-08 0.00000000E+00 + 1.32176652E-08-9.50778521E-03-4.04829373E-17 4.07452874E-07 1.91757363E-20 + 8.13736377E-02 0.00000000E+00-2.33384847E-06 0.00000000E+00 4.78226796E-03 + 8.48722739E-09-2.33220986E-04-4.23327499E-10 0.00000000E+00 1.20776565E-08 + 0.00000000E+00-5.98410203E-10-1.61498236E-03-5.60447141E-18 1.01116728E-05 + 3.56149283E-20 1.39150548E-02 0.00000000E+00-8.70735147E-05 0.00000000E+00 + 0.00000000E+00 3.03760354E-14-3.38624739E-08 4.80468230E-15-8.92519229E-05 + 0.00000000E+00-5.34349172E-07 0.00000000E+00 1.04891953E-05-5.13806641E-20 + 6.27767326E-08-3.06420004E-22 0.00000000E+00-6.20439804E-11 0.00000000E+00 + 6.12326492E-14 2.40867169E-05-4.39626553E-11-6.70776005E-08 1.06626800E-14 +-2.33384847E-06 0.00000000E+00 1.40734976E-06 0.00000000E+00 4.07452874E-07 +-1.91757363E-20-1.64400838E-07 6.95299146E-22 0.00000000E+00 6.27793363E-11 + 0.00000000E+00 3.09177743E-14-2.48918625E-05 4.40908949E-11-3.32379449E-08 + 5.88139767E-15 8.69172405E-05 0.00000000E+00-5.21356531E-07 0.00000000E+00 +-1.00817666E-05 3.44489470E-20 6.05092510E-08-2.09854745E-22 0.00000000E+00 +-6.03131233E-10 2.38388806E-04-4.24150119E-10 1.42617534E-02 0.00000000E+00 + 8.90743704E-05 0.00000000E+00-1.67549157E-03 8.16900795E-18-1.04609005E-05 + 5.07989653E-20 0.00000000E+00 1.19549247E-08 0.00000000E+00 1.32176652E-08 +-4.64790805E-03 8.46580760E-09-5.18689021E-03 9.32366349E-09 8.13736377E-02 + 0.00000000E+00-2.33384847E-06 0.00000000E+00-9.50778521E-03 4.04829373E-17 + 4.07452874E-07-1.91757363E-20 0.00000000E+00 1.20776565E-08 0.00000000E+00 +-5.98410203E-10-4.78226796E-03 8.48722739E-09 2.33220986E-04-4.23327499E-10 + 1.39150548E-02 0.00000000E+00-8.70735147E-05 0.00000000E+00-1.61498236E-03 + 5.60447141E-18 1.01116728E-05-3.56149283E-20-3.62409648E-04-1.18332408E-18 +-1.00832880E-03 0.00000000E+00 2.24045631E-04 4.22115251E-10-3.38624739E-08 +-4.80468230E-15 0.00000000E+00 5.90264941E-10 0.00000000E+00-3.03760354E-14 + 7.56689263E-04 2.82315525E-18 3.02771855E-03 1.08735200E-17 2.06117003E-03 + 0.00000000E+00 8.24463786E-03 0.00000000E+00-5.18689021E-03-9.32366349E-09 +-6.70776005E-08-1.06626800E-14 0.00000000E+00-1.32176652E-08 0.00000000E+00 +-6.12326492E-14 7.56687796E-04 2.85531603E-18-3.94953893E-04-1.32324442E-18 + 2.06116398E-03 0.00000000E+00-1.05281704E-03 0.00000000E+00 2.47299688E-04 + 4.25818492E-10-3.32379449E-08-5.88139767E-15 0.00000000E+00 6.11506032E-10 + 0.00000000E+00-3.09177743E-14 6.92949330E-04 1.91014108E-18 1.97214516E-03 + 0.00000000E+00-4.60096680E-03-8.45914823E-09-2.39512670E-05-4.39434366E-11 + 0.00000000E+00-1.19128170E-08 0.00000000E+00-6.19224762E-11 5.79778032E-03 + 1.91904908E-17 7.56689263E-04 2.82315525E-18 1.61332845E-02 0.00000000E+00 + 2.06117003E-03 0.00000000E+00-4.64790805E-03-8.46580760E-09 2.40867169E-05 + 4.39626553E-11 0.00000000E+00-1.19549247E-08 0.00000000E+00 6.20439804E-11 + 1.97214516E-03 0.00000000E+00 6.92949330E-04-1.91014108E-18 0.00000000E+00 +-1.19128170E-08 0.00000000E+00-6.19224762E-11 4.60096680E-03-8.45914823E-09 + 2.39512670E-05-4.39434366E-11 1.61332845E-02 0.00000000E+00 2.06117003E-03 + 0.00000000E+00 5.79778032E-03-1.91904908E-17 7.56689263E-04-2.82315525E-18 + 0.00000000E+00-1.19549247E-08 0.00000000E+00 6.20439804E-11 4.64790805E-03 +-8.46580760E-09-2.40867169E-05 4.39626553E-11-9.63798883E-04 0.00000000E+00 +-3.31219573E-04 6.83613562E-19 0.00000000E+00 5.82300815E-10 0.00000000E+00 +-2.97325027E-14-2.14715689E-04 4.21240841E-10 3.44472673E-08-3.58982636E-15 + 1.97215066E-03 0.00000000E+00 7.88856283E-03 0.00000000E+00 6.92950459E-04 +-1.81572764E-18 2.77277016E-03-7.45569888E-18 0.00000000E+00-1.30375959E-08 + 0.00000000E+00-6.00539814E-14 4.98610870E-03-9.29522999E-09 6.82876256E-08 +-8.37966851E-15 1.97214516E-03 0.00000000E+00-1.00832880E-03 0.00000000E+00 + 6.92949330E-04-1.91014108E-18-3.62409648E-04 1.18332408E-18 0.00000000E+00 + 6.03131233E-10 0.00000000E+00-3.03760354E-14-2.38388806E-04 4.24150119E-10 + 3.38624739E-08-4.80468230E-15 6.31927834E-04 9.18726606E-19 1.88304487E-03 + 0.00000000E+00-4.41643418E-03-8.43733237E-09-2.29938196E-05-4.38282820E-11 + 0.00000000E+00-1.17512370E-08 0.00000000E+00-6.10823742E-11 5.29873401E-03 + 1.06263130E-17 6.92950459E-04 1.81572764E-18 1.54208042E-02 0.00000000E+00 + 1.97215066E-03 0.00000000E+00-4.46418613E-03-8.44230739E-09 2.31316087E-05 + 4.38426413E-11 0.00000000E+00-1.17924524E-08 0.00000000E+00 6.12013042E-11 + 1.88304487E-03 0.00000000E+00 6.31927834E-04-9.18726606E-19 0.00000000E+00 +-1.17512370E-08 0.00000000E+00-6.10823742E-11 4.41643418E-03-8.43733237E-09 + 2.29938196E-05-4.38282820E-11 1.54208042E-02 0.00000000E+00 1.97215066E-03 + 0.00000000E+00 5.29873401E-03-1.06263130E-17 6.92950459E-04-1.81572764E-18 + 0.00000000E+00-1.17924524E-08 0.00000000E+00 6.12013042E-11 4.46418613E-03 +-8.44230739E-09-2.31316087E-05 4.38426413E-11 3.44472673E-08 3.58982636E-15 + 0.00000000E+00 2.97325027E-14 1.08460741E-05 4.86152281E-20 6.49203760E-08 + 2.92339699E-22-9.17264639E-05 0.00000000E+00-5.49107993E-07 0.00000000E+00 +-2.31316087E-05-4.38426413E-11 6.82876256E-08 8.37966851E-15 0.00000000E+00 +-6.12013042E-11 0.00000000E+00 6.00539814E-14 3.85194724E-07-4.02078146E-21 +-1.70281800E-07-8.09470583E-22-2.65103916E-06 0.00000000E+00 1.44431708E-06 + 0.00000000E+00 2.39512670E-05 4.39434366E-11 3.38624739E-08 4.80468230E-15 + 0.00000000E+00 6.19224762E-11 0.00000000E+00 3.03760354E-14-1.04609005E-05 +-5.07989653E-20 6.27767326E-08 3.06420004E-22 8.90743704E-05 0.00000000E+00 +-5.34349172E-07 0.00000000E+00-2.29306570E-04-4.22761062E-10 0.00000000E+00 +-5.94894445E-10-1.73269490E-03-7.80388727E-18-1.08193461E-05-4.89580150E-20 + 1.46555885E-02 0.00000000E+00 9.15247750E-05 0.00000000E+00 4.46418613E-03 + 8.44230739E-09 4.98610870E-03 9.29522999E-09 0.00000000E+00 1.17924524E-08 + 0.00000000E+00 1.30375959E-08-9.84778933E-03-4.72643165E-17 3.85194724E-07 +-4.02078146E-21 8.35094611E-02 0.00000000E+00-2.65103916E-06 0.00000000E+00 + 4.60096680E-03 8.45914823E-09-2.24045631E-04-4.22115251E-10 0.00000000E+00 + 1.19128170E-08 0.00000000E+00-5.90264941E-10-1.67549157E-03-8.16900795E-18 + 1.04891953E-05 5.13806641E-20 1.42617534E-02 0.00000000E+00-8.92519229E-05 + 0.00000000E+00 0.00000000E+00 2.97325027E-14-3.44472673E-08 3.58982636E-15 +-9.17264639E-05 0.00000000E+00-5.49107993E-07 0.00000000E+00 1.08460741E-05 +-4.86152281E-20 6.49203760E-08-2.92339699E-22 0.00000000E+00-6.12013042E-11 + 0.00000000E+00 6.00539814E-14 2.31316087E-05-4.38426413E-11-6.82876256E-08 + 8.37966851E-15-2.65103916E-06 0.00000000E+00 1.44431708E-06 0.00000000E+00 + 3.85194724E-07 4.02078146E-21-1.70281800E-07 8.09470583E-22 0.00000000E+00 + 6.19224762E-11 0.00000000E+00 3.03760354E-14-2.39512670E-05 4.39434366E-11 +-3.38624739E-08 4.80468230E-15 8.90743704E-05 0.00000000E+00-5.34349172E-07 + 0.00000000E+00-1.04609005E-05 5.07989653E-20 6.27767326E-08-3.06420004E-22 + 0.00000000E+00-5.94894445E-10 2.29306570E-04-4.22761062E-10 1.46555885E-02 + 0.00000000E+00 9.15247750E-05 0.00000000E+00-1.73269490E-03 7.80388727E-18 +-1.08193461E-05 4.89580150E-20 0.00000000E+00 1.17924524E-08 0.00000000E+00 + 1.30375959E-08-4.46418613E-03 8.44230739E-09-4.98610870E-03 9.29522999E-09 + 8.35094611E-02 0.00000000E+00-2.65103916E-06 0.00000000E+00-9.84778933E-03 + 4.72643165E-17 3.85194724E-07 4.02078146E-21 0.00000000E+00 1.19128170E-08 + 0.00000000E+00-5.90264941E-10-4.60096680E-03 8.45914823E-09 2.24045631E-04 +-4.22115251E-10 1.42617534E-02 0.00000000E+00-8.92519229E-05 0.00000000E+00 +-1.67549157E-03 8.16900795E-18 1.04891953E-05-5.13806641E-20-3.31219573E-04 +-6.83613562E-19-9.63798883E-04 0.00000000E+00 2.14715689E-04 4.21240841E-10 +-3.44472673E-08-3.58982636E-15 0.00000000E+00 5.82300815E-10 0.00000000E+00 +-2.97325027E-14 6.92950459E-04 1.81572764E-18 2.77277016E-03 7.45569888E-18 + 1.97215066E-03 0.00000000E+00 7.88856283E-03 0.00000000E+00-4.98610870E-03 +-9.29522999E-09-6.82876256E-08-8.37966851E-15 0.00000000E+00-1.30375959E-08 + 0.00000000E+00-6.00539814E-14 6.92949330E-04 1.91014108E-18-3.62409648E-04 +-1.18332408E-18 1.97214516E-03 0.00000000E+00-1.00832880E-03 0.00000000E+00 + 2.38388806E-04 4.24150119E-10-3.38624739E-08-4.80468230E-15 0.00000000E+00 + 6.03131233E-10 0.00000000E+00-3.03760354E-14 5.73640413E-04 2.08163394E-18 + 1.79386818E-03 0.00000000E+00-4.22883581E-03-8.42262095E-09-2.20204079E-05 +-4.37497524E-11 0.00000000E+00-1.15935277E-08 0.00000000E+00-6.02621737E-11 + 4.82149350E-03 1.11678109E-17 6.31928867E-04 8.32497204E-19 1.47076948E-02 + 0.00000000E+00 1.88305024E-03 0.00000000E+00-4.27736602E-03-8.42567965E-09 + 2.21604441E-05 4.37585831E-11 0.00000000E+00-1.16336834E-08 0.00000000E+00 + 6.03780467E-11-9.19229605E-04 0.00000000E+00-3.01392320E-04 7.28532786E-19 + 0.00000000E+00 5.74551770E-10 0.00000000E+00-2.89682638E-14-2.05236483E-04 + 4.20751546E-10 3.50090628E-08-2.20766034E-15 1.88305024E-03 0.00000000E+00 + 7.53216307E-03 0.00000000E+00 6.31928867E-04-8.32497204E-19 2.52868999E-03 +-4.28146998E-18 0.00000000E+00-1.28613473E-08 0.00000000E+00-5.86542196E-14 + 4.78185437E-03-9.27400750E-09 6.94278216E-08-5.79325256E-15 1.88304487E-03 + 0.00000000E+00-9.63798883E-04 0.00000000E+00 6.31927834E-04-9.18726606E-19 +-3.31219573E-04 6.83613562E-19 0.00000000E+00 5.94894445E-10 0.00000000E+00 +-2.97325027E-14-2.29306570E-04 4.22761062E-10 3.44472673E-08-3.58982636E-15 + 3.50090628E-08 2.20766034E-15 0.00000000E+00 2.89682638E-14 1.11829399E-05 + 4.03821258E-20 6.69439419E-08 2.45943852E-22-9.45380076E-05 0.00000000E+00 +-5.65876297E-07 0.00000000E+00-2.21604441E-05-4.37585831E-11 6.94278216E-08 + 5.79325256E-15 0.00000000E+00-6.03780467E-11 0.00000000E+00 5.86542196E-14 + 3.63615436E-07-7.24026372E-21-1.75837461E-07-7.29427549E-22-3.01191215E-06 + 0.00000000E+00 1.48631201E-06 0.00000000E+00 2.29938196E-05 4.38282820E-11 + 3.44472673E-08 3.58982636E-15 0.00000000E+00 6.10823742E-11 0.00000000E+00 + 2.97325027E-14-1.08193461E-05-4.89580150E-20 6.49203760E-08 2.92339699E-22 + 9.15247750E-05 0.00000000E+00-5.49107993E-07 0.00000000E+00-2.20065188E-04 +-4.21686240E-10 0.00000000E+00-5.86821604E-10-1.78669275E-03-6.55947521E-18 +-1.11577279E-05-4.16548012E-20 1.51030534E-02 0.00000000E+00 9.43087786E-05 + 0.00000000E+00 4.27736602E-03 8.42567965E-09 4.78185437E-03 9.27400750E-09 + 0.00000000E+00 1.16336834E-08 0.00000000E+00 1.28613473E-08-1.01689748E-02 +-4.27002821E-17 3.63615436E-07-7.24026372E-21 8.59357221E-02 0.00000000E+00 +-3.01191215E-06 0.00000000E+00 4.41643418E-03 8.43733237E-09-2.14715689E-04 +-4.21240841E-10 0.00000000E+00 1.17512370E-08 0.00000000E+00-5.82300815E-10 +-1.73269490E-03-7.80388727E-18 1.08460741E-05 4.86152281E-20 1.46555885E-02 + 0.00000000E+00-9.17264639E-05 0.00000000E+00 0.00000000E+00 2.89682638E-14 +-3.50090628E-08 2.20766034E-15-9.45380076E-05 0.00000000E+00-5.65876297E-07 + 0.00000000E+00 1.11829399E-05-4.03821258E-20 6.69439419E-08-2.45943852E-22 + 0.00000000E+00-6.03780467E-11 0.00000000E+00 5.86542196E-14 2.21604441E-05 +-4.37585831E-11-6.94278216E-08 5.79325256E-15-3.01191215E-06 0.00000000E+00 + 1.48631201E-06 0.00000000E+00 3.63615436E-07 7.24026372E-21-1.75837461E-07 + 7.29427549E-22 0.00000000E+00 6.10823742E-11 0.00000000E+00 2.97325027E-14 +-2.29938196E-05 4.38282820E-11-3.44472673E-08 3.58982636E-15 9.15247750E-05 + 0.00000000E+00-5.49107993E-07 0.00000000E+00-1.08193461E-05 4.89580150E-20 + 6.49203760E-08-2.92339699E-22 0.00000000E+00-5.86821604E-10 2.20065188E-04 +-4.21686240E-10 1.51030534E-02 0.00000000E+00 9.43087786E-05 0.00000000E+00 +-1.78669275E-03 6.55947521E-18-1.11577279E-05 4.16548012E-20 0.00000000E+00 + 1.16336834E-08 0.00000000E+00 1.28613473E-08-4.27736602E-03 8.42567965E-09 +-4.78185437E-03 9.27400750E-09 8.59357221E-02 0.00000000E+00-3.01191215E-06 + 0.00000000E+00-1.01689748E-02 4.27002821E-17 3.63615436E-07 7.24026372E-21 + 0.00000000E+00 1.17512370E-08 0.00000000E+00-5.82300815E-10-4.41643418E-03 + 8.43733237E-09 2.14715689E-04-4.21240841E-10 1.46555885E-02 0.00000000E+00 +-9.17264639E-05 0.00000000E+00-1.73269490E-03 7.80388727E-18 1.08460741E-05 +-4.86152281E-20-3.01392320E-04-7.28532786E-19-9.19229605E-04 0.00000000E+00 + 2.05236483E-04 4.20751546E-10-3.50090628E-08-2.20766034E-15 0.00000000E+00 + 5.74551770E-10 0.00000000E+00-2.89682638E-14 6.31928867E-04 8.32497204E-19 + 2.52868999E-03 4.28146998E-18 1.88305024E-03 0.00000000E+00 7.53216307E-03 + 0.00000000E+00-4.78185437E-03-9.27400750E-09-6.94278216E-08-5.79325256E-15 + 0.00000000E+00-1.28613473E-08 0.00000000E+00-5.86542196E-14 6.31927834E-04 + 9.18726606E-19-3.31219573E-04-6.83613562E-19 1.88304487E-03 0.00000000E+00 +-9.63798883E-04 0.00000000E+00 2.29306570E-04 4.22761062E-10-3.44472673E-08 +-3.58982636E-15 0.00000000E+00 5.94894445E-10 0.00000000E+00-2.97325027E-14 + 1.79386818E-03 0.00000000E+00 5.73640413E-04-2.08163394E-18 0.00000000E+00 +-1.15935277E-08 0.00000000E+00-6.02621737E-11 4.22883581E-03-8.42262095E-09 + 2.20204079E-05-4.37497524E-11 1.47076948E-02 0.00000000E+00 1.88305024E-03 + 0.00000000E+00 4.82149350E-03-1.11678109E-17 6.31928867E-04-8.32497204E-19 + 0.00000000E+00-1.16336834E-08 0.00000000E+00 6.03780467E-11 4.27736602E-03 +-8.42567965E-09-2.21604441E-05 4.37585831E-11-8.29980962E-04 0.00000000E+00 +-2.45857978E-04 6.08322244E-19 0.00000000E+00 5.59870131E-10 0.00000000E+00 +-2.69768252E-14-1.85878524E-04 4.21172319E-10 3.60098416E-08 1.21486113E-15 + 1.70462352E-03 0.00000000E+00 6.81845998E-03 0.00000000E+00 5.18103266E-04 +-1.10082855E-18 2.07339878E-03-5.57313482E-18 0.00000000E+00-1.25233199E-08 + 0.00000000E+00-5.50120678E-14 4.36364350E-03-9.25738862E-09 7.15065350E-08 + 5.66949575E-16 1.70461871E-03 0.00000000E+00-8.74622985E-04 0.00000000E+00 + 5.18102512E-04-1.48072214E-18-2.72935947E-04 9.77117126E-19 0.00000000E+00 + 5.78943361E-10 0.00000000E+00-2.80596544E-14-2.10668162E-04 4.20967826E-10 + 3.55229696E-08-6.21489896E-16 3.60098416E-08-1.21486113E-15 0.00000000E+00 + 2.69768252E-14 1.17992074E-05 2.70774355E-20 7.06463208E-08 1.67578564E-22 +-1.01381395E-04 0.00000000E+00-6.06685783E-07 0.00000000E+00-2.01736269E-05 +-4.37198958E-11 7.15065350E-08-5.66949575E-16 0.00000000E+00-5.88051293E-11 + 0.00000000E+00 5.50120678E-14 3.22528899E-07 8.67018607E-23-1.86014372E-07 +-4.91131315E-22-3.90417123E-06 0.00000000E+00 1.58839896E-06 0.00000000E+00 + 2.10319270E-05 4.37131012E-11 3.55229696E-08 6.21489896E-16 0.00000000E+00 + 5.94656219E-11 0.00000000E+00 2.80596544E-14-1.14767161E-05-3.00295975E-20 + 6.88514485E-08 1.80862254E-22 9.74750636E-05 0.00000000E+00-5.84948203E-07 + 0.00000000E+00-2.01131067E-04-4.20657123E-10 0.00000000E+00-5.71296242E-10 +-1.88548525E-03-4.46330207E-18-1.17768914E-05-2.87671283E-20 1.61920851E-02 + 0.00000000E+00 1.01083591E-04 0.00000000E+00 3.89512752E-03 8.41714598E-09 + 4.36364350E-03 9.25738862E-09 0.00000000E+00 1.13301786E-08 0.00000000E+00 + 1.25233199E-08-1.07573092E-02-2.97010531E-17 3.22528899E-07 8.67018607E-23 + 9.18334052E-02 0.00000000E+00-3.90417123E-06 0.00000000E+00 4.03835293E-03 + 8.41603701E-09-1.95621714E-04-4.20705082E-10 0.00000000E+00 1.14404180E-08 + 0.00000000E+00-5.67058483E-10-1.83759241E-03-4.83493929E-18 1.15004636E-05 + 3.03960274E-20 1.56119980E-02 0.00000000E+00-9.77360296E-05 0.00000000E+00 + 0.00000000E+00 2.69768252E-14-3.60098416E-08-1.21486113E-15-1.01381395E-04 + 0.00000000E+00-6.06685783E-07 0.00000000E+00 1.17992074E-05-2.70774355E-20 + 7.06463208E-08-1.67578564E-22 0.00000000E+00-5.88051293E-11 0.00000000E+00 + 5.50120678E-14 2.01736269E-05-4.37198958E-11-7.15065350E-08-5.66949575E-16 +-3.90417123E-06 0.00000000E+00 1.58839896E-06 0.00000000E+00 3.22528899E-07 +-8.67018607E-23-1.86014372E-07 4.91131315E-22 0.00000000E+00 5.94656219E-11 + 0.00000000E+00 2.80596544E-14-2.10319270E-05 4.37131012E-11-3.55229696E-08 + 6.21489896E-16 9.74750636E-05 0.00000000E+00-5.84948203E-07 0.00000000E+00 +-1.14767161E-05 3.00295975E-20 6.88514485E-08-1.80862254E-22 0.00000000E+00 +-5.71296242E-10 2.01131067E-04-4.20657123E-10 1.61920851E-02 0.00000000E+00 + 1.01083591E-04 0.00000000E+00-1.88548525E-03 4.46330207E-18-1.17768914E-05 + 2.87671283E-20 0.00000000E+00 1.13301786E-08 0.00000000E+00 1.25233199E-08 +-3.89512752E-03 8.41714598E-09-4.36364350E-03 9.25738862E-09 9.18334052E-02 + 0.00000000E+00-3.90417123E-06 0.00000000E+00-1.07573092E-02 2.97010531E-17 + 3.22528899E-07-8.67018607E-23 0.00000000E+00 1.14404180E-08 0.00000000E+00 +-5.67058483E-10-4.03835293E-03 8.41603701E-09 1.95621714E-04-4.20705082E-10 + 1.56119980E-02 0.00000000E+00-9.77360296E-05 0.00000000E+00-1.83759241E-03 + 4.83493929E-18 1.15004636E-05-3.03960274E-20-2.45857978E-04-6.08322244E-19 +-8.29980962E-04 0.00000000E+00 1.85878524E-04 4.21172319E-10-3.60098416E-08 + 1.21486113E-15 0.00000000E+00 5.59870131E-10 0.00000000E+00-2.69768252E-14 + 5.18103266E-04 1.10082855E-18 2.07339878E-03 5.57313482E-18 1.70462352E-03 + 0.00000000E+00 6.81845998E-03 0.00000000E+00-4.36364350E-03-9.25738862E-09 +-7.15065350E-08 5.66949575E-16 0.00000000E+00-1.25233199E-08 0.00000000E+00 +-5.50120678E-14 5.18102512E-04 1.48072214E-18-2.72935947E-04-9.77117126E-19 + 1.70461871E-03 0.00000000E+00-8.74622985E-04 0.00000000E+00 2.10668162E-04 + 4.20967826E-10-3.55229696E-08-6.21489896E-16 0.00000000E+00 5.78943361E-10 + 0.00000000E+00-2.80596544E-14-8.74622985E-04 0.00000000E+00-2.72935947E-04 + 9.77117126E-19 0.00000000E+00 5.67058483E-10 0.00000000E+00-2.80596544E-14 +-1.95621714E-04 4.20705082E-10 3.55229696E-08-6.21489896E-16 1.79387323E-03 + 0.00000000E+00 7.17545701E-03 0.00000000E+00 5.73641275E-04-2.42774637E-18 + 2.29554547E-03-8.22964374E-18 0.00000000E+00-1.26896362E-08 0.00000000E+00 +-5.69911476E-14 4.57427828E-03-9.26098984E-09 7.05210748E-08-2.83837889E-15 + 1.79386818E-03 0.00000000E+00-9.19229605E-04 0.00000000E+00 5.73640413E-04 +-2.08163394E-18-3.01392320E-04 7.28532786E-19 0.00000000E+00 5.86821604E-10 + 0.00000000E+00-2.89682638E-14-2.20065188E-04 4.21686240E-10 3.50090628E-08 +-2.20766034E-15 3.55229696E-08 6.21489896E-16 0.00000000E+00 2.80596544E-14 + 1.15004636E-05 3.03960274E-20 6.88514485E-08 1.80862254E-22-9.77360296E-05 + 0.00000000E+00-5.84948203E-07 0.00000000E+00-2.11740189E-05-4.37155872E-11 + 7.05210748E-08 2.83837889E-15 0.00000000E+00-5.95778605E-11 0.00000000E+00 + 5.69911476E-14 3.42760098E-07-1.36359826E-20-1.81078267E-07-5.48152478E-22 +-3.42551312E-06 0.00000000E+00 1.53404809E-06 0.00000000E+00 2.20204079E-05 + 4.37497524E-11 3.50090628E-08 2.20766034E-15 0.00000000E+00 6.02621737E-11 + 0.00000000E+00 2.89682638E-14-1.11577279E-05-4.16548012E-20 6.69439419E-08 + 2.45943852E-22 9.43087786E-05 0.00000000E+00-5.65876297E-07 0.00000000E+00 +-2.10668162E-04-4.20967826E-10 0.00000000E+00-5.78943361E-10-1.83759241E-03 +-4.83493929E-18-1.14767161E-05-3.00295975E-20 1.56119980E-02 0.00000000E+00 + 9.74750636E-05 0.00000000E+00 4.08759583E-03 8.41689654E-09 4.57427828E-03 + 9.26098984E-09 0.00000000E+00 1.14793137E-08 0.00000000E+00 1.26896362E-08 +-1.04719489E-02-3.07265899E-17 3.42760098E-07-1.36359826E-20 8.86935480E-02 + 0.00000000E+00-3.42551312E-06 0.00000000E+00 4.22883581E-03 8.42262095E-09 +-2.05236483E-04-4.20751546E-10 0.00000000E+00 1.15935277E-08 0.00000000E+00 +-5.74551770E-10-1.78669275E-03-6.55947521E-18 1.11829399E-05 4.03821258E-20 + 1.51030534E-02 0.00000000E+00-9.45380076E-05 0.00000000E+00 0.00000000E+00 + 2.80596544E-14-3.55229696E-08 6.21489896E-16-9.77360296E-05 0.00000000E+00 +-5.84948203E-07 0.00000000E+00 1.15004636E-05-3.03960274E-20 6.88514485E-08 +-1.80862254E-22 0.00000000E+00-5.95778605E-11 0.00000000E+00 5.69911476E-14 + 2.11740189E-05-4.37155872E-11-7.05210748E-08 2.83837889E-15-3.42551312E-06 + 0.00000000E+00 1.53404809E-06 0.00000000E+00 3.42760098E-07 1.36359826E-20 +-1.81078267E-07 5.48152478E-22 0.00000000E+00 6.02621737E-11 0.00000000E+00 + 2.89682638E-14-2.20204079E-05 4.37497524E-11-3.50090628E-08 2.20766034E-15 + 9.43087786E-05 0.00000000E+00-5.65876297E-07 0.00000000E+00-1.11577279E-05 + 4.16548012E-20 6.69439419E-08-2.45943852E-22 0.00000000E+00-5.78943361E-10 + 2.10668162E-04-4.20967826E-10 1.56119980E-02 0.00000000E+00 9.74750636E-05 + 0.00000000E+00-1.83759241E-03 4.83493929E-18-1.14767161E-05 3.00295975E-20 + 0.00000000E+00 1.14793137E-08 0.00000000E+00 1.26896362E-08-4.08759583E-03 + 8.41689654E-09-4.57427828E-03 9.26098984E-09 8.86935480E-02 0.00000000E+00 +-3.42551312E-06 0.00000000E+00-1.04719489E-02 3.07265899E-17 3.42760098E-07 + 1.36359826E-20 0.00000000E+00 1.15935277E-08 0.00000000E+00-5.74551770E-10 +-4.22883581E-03 8.42262095E-09 2.05236483E-04-4.20751546E-10 1.51030534E-02 + 0.00000000E+00-9.45380076E-05 0.00000000E+00-1.78669275E-03 6.55947521E-18 + 1.11829399E-05-4.03821258E-20-2.72935947E-04-9.77117126E-19-8.74622985E-04 + 0.00000000E+00 1.95621714E-04 4.20705082E-10-3.55229696E-08-6.21489896E-16 + 0.00000000E+00 5.67058483E-10 0.00000000E+00-2.80596544E-14 5.73641275E-04 + 2.42774637E-18 2.29554547E-03 8.22964374E-18 1.79387323E-03 0.00000000E+00 + 7.17545701E-03 0.00000000E+00-4.57427828E-03-9.26098984E-09-7.05210748E-08 +-2.83837889E-15 0.00000000E+00-1.26896362E-08 0.00000000E+00-5.69911476E-14 + 5.73640413E-04 2.08163394E-18-3.01392320E-04-7.28532786E-19 1.79386818E-03 + 0.00000000E+00-9.19229605E-04 0.00000000E+00 2.20065188E-04 4.21686240E-10 +-3.50090628E-08-2.20766034E-15 0.00000000E+00 5.86821604E-10 0.00000000E+00 +-2.89682638E-14 5.18102512E-04 1.48072214E-18 1.70461871E-03 0.00000000E+00 +-4.03835293E-03-8.41603701E-09-2.10319270E-05-4.37131012E-11 0.00000000E+00 +-1.14404180E-08 0.00000000E+00-5.94656219E-11 4.36618727E-03 1.65812449E-17 + 5.73641275E-04 2.42774637E-18 1.39939877E-02 0.00000000E+00 1.79387323E-03 + 0.00000000E+00-4.08759583E-03-8.41689654E-09 2.11740189E-05 4.37155872E-11 + 0.00000000E+00-1.14793137E-08 0.00000000E+00 5.95778605E-11 1.70461871E-03 + 0.00000000E+00 5.18102512E-04-1.48072214E-18 0.00000000E+00-1.14404180E-08 + 0.00000000E+00-5.94656219E-11 4.03835293E-03-8.41603701E-09 2.10319270E-05 +-4.37131012E-11 1.39939877E-02 0.00000000E+00 1.79387323E-03 0.00000000E+00 + 4.36618727E-03-1.65812449E-17 5.73641275E-04-2.42774637E-18 0.00000000E+00 +-1.14793137E-08 0.00000000E+00 5.95778605E-11 4.08759583E-03-8.41689654E-09 +-2.11740189E-05 4.37155872E-11 4.49509255E-05 0.00000000E+00-2.40909084E-08 +-4.20804442E-23 0.00000000E+00-1.40466514E-11 4.11751495E-08-1.31036026E-10 + 0.00000000E+00-1.40466514E-11 4.11751495E-08-1.31036026E-10 3.46215210E-03 + 0.00000000E+00-2.24783720E-05 0.00000000E+00-2.93440489E-06-3.63226763E-21 + 1.76503909E-08 2.42039935E-23 0.00000000E+00-5.89886133E-11 0.00000000E+00 +-2.98130723E-13 4.84988889E-07-4.38532884E-10 4.00332114E-08 1.00930141E-11 + 0.00000000E+00-5.89886133E-11 0.00000000E+00-2.98130723E-13 4.84988889E-07 +-4.38532884E-10 4.00332114E-08 1.00930141E-11 4.84988889E-07 4.38532884E-10 + 0.00000000E+00 5.89886133E-11-2.51328991E-06 4.58918167E-21 1.63168975E-08 + 0.00000000E+00 3.04454833E-02-3.86047019E-17 2.12979992E+01 0.00000000E+00 + 1.36530472E-04 7.37327475E-08-6.45121735E-07-3.98160827E-10 0.00000000E+00 + 1.16619185E-08 0.00000000E+00-6.01811362E-11-1.55414590E-06 4.27330687E-20 + 2.12487408E-06 6.09421977E-21 3.59792902E-04 0.00000000E+00 8.99351051E-05 + 0.00000000E+00 2.43548839E-01 1.57193558E-16 3.04422621E-02 7.79065537E-17 + 4.25964458E+01 0.00000000E+00 3.45529031E-05 0.00000000E+00 0.00000000E+00 + 5.89886133E-11-4.84988889E-07 4.38532884E-10 1.63168975E-08 0.00000000E+00 +-2.51328991E-06-4.58918167E-21 2.12979992E+01 0.00000000E+00 3.04454833E-02 + 3.86047019E-17 0.00000000E+00 1.16619185E-08 0.00000000E+00-6.01811362E-11 +-1.36530472E-04 7.37327475E-08 6.45121735E-07-3.98160827E-10 3.59792902E-04 + 0.00000000E+00 8.99351051E-05 0.00000000E+00-1.55414590E-06-4.27330687E-20 + 2.12487408E-06-6.09421977E-21 4.25964458E+01 0.00000000E+00 3.45529031E-05 + 0.00000000E+00 2.43548839E-01-1.57193558E-16 3.04422621E-02-7.79065537E-17 + 4.84988889E-07 4.38532884E-10 0.00000000E+00 5.89886133E-11-2.51328991E-06 + 4.58918167E-21 1.63168975E-08 0.00000000E+00-2.51328991E-06 4.58918167E-21 + 1.63168975E-08 0.00000000E+00 1.36530472E-04 7.37327475E-08-6.45121735E-07 +-3.98160827E-10 0.00000000E+00 1.16619185E-08 0.00000000E+00-6.01811362E-11 +-1.55414590E-06 4.27330687E-20 2.12487408E-06 6.09421977E-21 3.59792902E-04 + 0.00000000E+00 8.99351051E-05 0.00000000E+00-1.55414590E-06 4.27330687E-20 + 2.12487408E-06 6.09421977E-21 3.59792902E-04 0.00000000E+00 8.99351051E-05 + 0.00000000E+00 0.00000000E+00 5.89886133E-11-4.84988889E-07 4.38532884E-10 + 1.63168975E-08 0.00000000E+00-2.51328991E-06-4.58918167E-21 1.63168975E-08 + 0.00000000E+00-2.51328991E-06-4.58918167E-21 0.00000000E+00 1.16619185E-08 + 0.00000000E+00-6.01811362E-11-1.36530472E-04 7.37327475E-08 6.45121735E-07 +-3.98160827E-10 3.59792902E-04 0.00000000E+00 8.99351051E-05 0.00000000E+00 +-1.55414590E-06-4.27330687E-20 2.12487408E-06-6.09421977E-21 3.59792902E-04 + 0.00000000E+00 8.99351051E-05 0.00000000E+00-1.55414590E-06-4.27330687E-20 + 2.12487408E-06-6.09421977E-21 4.11751495E-08 1.31036026E-10 0.00000000E+00 + 1.40466514E-11-3.86697810E-06 9.55469012E-21 2.25139369E-05 0.00000000E+00 + 6.08904291E-02-4.80798488E-17 5.32448720E+01 0.00000000E+00-1.39170647E-05 +-1.93645462E-09 4.00332114E-08-1.00930141E-11 0.00000000E+00-6.32691269E-10 + 0.00000000E+00 2.98130723E-13-2.51328991E-06 4.58918167E-21 9.71039581E-08 +-2.67085036E-21 1.63168975E-08 0.00000000E+00-2.24878555E-05 0.00000000E+00 + 3.04454833E-02-3.86047019E-17-1.52219364E-02-9.82546293E-18 2.12979992E+01 + 0.00000000E+00-5.32450844E+00 0.00000000E+00 0.00000000E+00 1.40466514E-11 +-4.11751495E-08 1.31036026E-10 2.25139369E-05 0.00000000E+00-3.86697810E-06 +-9.55469012E-21 5.32448720E+01 0.00000000E+00 6.08904291E-02 4.80798488E-17 + 0.00000000E+00-6.32691269E-10 0.00000000E+00 2.98130723E-13 1.39170647E-05 +-1.93645462E-09-4.00332114E-08-1.00930141E-11 1.63168975E-08 0.00000000E+00 +-2.24878555E-05 0.00000000E+00-2.51328991E-06-4.58918167E-21 9.71039581E-08 + 2.67085036E-21 2.12979992E+01 0.00000000E+00-5.32450844E+00 0.00000000E+00 + 3.04454833E-02 3.86047019E-17-1.52219364E-02 9.82546293E-18 4.11751495E-08 + 1.31036026E-10 0.00000000E+00 1.40466514E-11-3.86697810E-06 9.55469012E-21 + 2.25139369E-05 0.00000000E+00-3.86697810E-06 9.55469012E-21 2.25139369E-05 + 0.00000000E+00-1.39170647E-05-1.93645462E-09 4.00332114E-08-1.00930141E-11 + 0.00000000E+00-6.32691269E-10 0.00000000E+00 2.98130723E-13-2.51328991E-06 + 4.58918167E-21 9.71039581E-08-2.67085036E-21 1.63168975E-08 0.00000000E+00 +-2.24878555E-05 0.00000000E+00-2.51328991E-06 4.58918167E-21 9.71039581E-08 +-2.67085036E-21 1.63168975E-08 0.00000000E+00-2.24878555E-05 0.00000000E+00 + 0.00000000E+00 1.40466514E-11-4.11751495E-08 1.31036026E-10 2.25139369E-05 + 0.00000000E+00-3.86697810E-06-9.55469012E-21 2.25139369E-05 0.00000000E+00 +-3.86697810E-06-9.55469012E-21 0.00000000E+00-6.32691269E-10 0.00000000E+00 + 2.98130723E-13 1.39170647E-05-1.93645462E-09-4.00332114E-08-1.00930141E-11 + 1.63168975E-08 0.00000000E+00-2.24878555E-05 0.00000000E+00-2.51328991E-06 +-4.58918167E-21 9.71039581E-08 2.67085036E-21 1.63168975E-08 0.00000000E+00 +-2.24878555E-05 0.00000000E+00-2.51328991E-06-4.58918167E-21 9.71039581E-08 + 2.67085036E-21-2.40909084E-08 4.20804442E-23 4.49509255E-05 0.00000000E+00 +-4.11751495E-08-1.31036026E-10 0.00000000E+00-1.40466514E-11-4.11751495E-08 +-1.31036026E-10 0.00000000E+00-1.40466514E-11-2.93440489E-06 3.63226763E-21 + 1.76503909E-08-2.42039935E-23 3.46215210E-03 0.00000000E+00-2.24783720E-05 + 0.00000000E+00-4.84988889E-07-4.38532884E-10-4.00332114E-08 1.00930141E-11 + 0.00000000E+00-5.89886133E-11 0.00000000E+00-2.98130723E-13-4.84988889E-07 +-4.38532884E-10-4.00332114E-08 1.00930141E-11 0.00000000E+00-5.89886133E-11 + 0.00000000E+00-2.98130723E-13 2.96827850E-04 4.30614799E-08 1.60584009E-06 + 2.14336226E-10 0.00000000E+00 1.20857195E-08 0.00000000E+00 6.27692959E-11 + 1.89081858E-06 3.34243744E-21 8.99355087E-05 0.00000000E+00 3.04424223E-02 + 9.43265053E-17 1.99049519E+00 0.00000000E+00 3.52318272E-04 3.58174219E-08 +-1.76596770E-06-1.93432292E-10 0.00000000E+00 1.20571371E-08 0.00000000E+00 +-6.26743089E-11 3.86152484E-05 9.06993318E-20 8.03884968E-06 2.25708054E-20 + 1.07938443E-03 0.00000000E+00 1.79914386E-04 0.00000000E+00 2.43560646E-01 + 8.75244199E-16 3.04480903E-02 1.05163947E-16 1.15452375E+01 0.00000000E+00 + 9.95339906E-01 0.00000000E+00 3.46215210E-03 0.00000000E+00-2.93440489E-06 +-3.63226763E-21 0.00000000E+00 6.32691269E-10-1.39170647E-05 1.93645462E-09 + 0.00000000E+00 6.32691269E-10-1.39170647E-05 1.93645462E-09 1.64755271E+00 + 0.00000000E+00-2.23205429E-03 0.00000000E+00-2.65585772E-03 1.26003415E-18 + 7.86061908E-08 1.16526156E-20 0.00000000E+00-1.16619185E-08 0.00000000E+00 +-1.32213241E-08 1.36530472E-04-7.37327475E-08 2.38346856E-04-6.19504734E-08 + 0.00000000E+00-1.16619185E-08 0.00000000E+00-1.32213241E-08 1.36530472E-04 +-7.37327475E-08 2.38346856E-04-6.19504734E-08 1.74219402E-01 0.00000000E+00 +-1.11698387E-03 0.00000000E+00-4.55670288E-04 1.05052103E-18 2.85016886E-06 +-6.20377319E-21 0.00000000E+00-1.20857195E-08 0.00000000E+00 6.07284573E-10 + 2.96827850E-04-4.30614799E-08-7.75099760E-06 3.11617040E-09 0.00000000E+00 +-1.20857195E-08 0.00000000E+00 6.07284573E-10 2.96827850E-04-4.30614799E-08 +-7.75099760E-06 3.11617040E-09-2.24783720E-05 0.00000000E+00 1.76503909E-08 + 2.42039935E-23 0.00000000E+00-2.98130723E-13 4.00332114E-08 1.00930141E-11 + 0.00000000E+00-2.98130723E-13 4.00332114E-08 1.00930141E-11-2.23205429E-03 + 0.00000000E+00 3.19403151E-05 0.00000000E+00 7.86061908E-08 1.16526156E-20 +-4.60565375E-08 2.11580797E-23 0.00000000E+00 6.01811362E-11 0.00000000E+00 +-1.63262927E-13-6.45121735E-07 3.98160827E-10 8.00546092E-08 1.53186028E-11 + 0.00000000E+00 6.01811362E-11 0.00000000E+00-1.63262927E-13-6.45121735E-07 + 3.98160827E-10 8.00546092E-08 1.53186028E-11 1.06036391E-03 0.00000000E+00 +-6.51670722E-06 0.00000000E+00-2.84779494E-06 6.93746626E-21 1.70747902E-08 +-3.94128332E-23 0.00000000E+00-6.27692959E-11 0.00000000E+00 2.37467613E-14 + 1.60584009E-06-2.14336226E-10 4.00319026E-08 5.22598364E-12 0.00000000E+00 +-6.27692959E-11 0.00000000E+00 2.37467613E-14 1.60584009E-06-2.14336226E-10 + 4.00319026E-08 5.22598364E-12-2.93440489E-06 3.63226763E-21 3.46215210E-03 + 0.00000000E+00 1.39170647E-05 1.93645462E-09 0.00000000E+00 6.32691269E-10 + 1.39170647E-05 1.93645462E-09 0.00000000E+00 6.32691269E-10-2.65585772E-03 +-1.26003415E-18 7.86061908E-08-1.16526156E-20 1.64755271E+00 0.00000000E+00 +-2.23205429E-03 0.00000000E+00-1.36530472E-04-7.37327475E-08-2.38346856E-04 +-6.19504734E-08 0.00000000E+00-1.16619185E-08 0.00000000E+00-1.32213241E-08 +-1.36530472E-04-7.37327475E-08-2.38346856E-04-6.19504734E-08 0.00000000E+00 +-1.16619185E-08 0.00000000E+00-1.32213241E-08-4.55670288E-04-1.05052103E-18 + 2.85016886E-06 6.20377319E-21 1.74219402E-01 0.00000000E+00-1.11698387E-03 + 0.00000000E+00-2.96827850E-04-4.30614799E-08 7.75099760E-06 3.11617040E-09 + 0.00000000E+00-1.20857195E-08 0.00000000E+00 6.07284573E-10-2.96827850E-04 +-4.30614799E-08 7.75099760E-06 3.11617040E-09 0.00000000E+00-1.20857195E-08 + 0.00000000E+00 6.07284573E-10 1.76503909E-08-2.42039935E-23-2.24783720E-05 + 0.00000000E+00-4.00332114E-08 1.00930141E-11 0.00000000E+00-2.98130723E-13 +-4.00332114E-08 1.00930141E-11 0.00000000E+00-2.98130723E-13 7.86061908E-08 +-1.16526156E-20-4.60565375E-08-2.11580797E-23-2.23205429E-03 0.00000000E+00 + 3.19403151E-05 0.00000000E+00 6.45121735E-07 3.98160827E-10-8.00546092E-08 + 1.53186028E-11 0.00000000E+00 6.01811362E-11 0.00000000E+00-1.63262927E-13 + 6.45121735E-07 3.98160827E-10-8.00546092E-08 1.53186028E-11 0.00000000E+00 + 6.01811362E-11 0.00000000E+00-1.63262927E-13-2.84779494E-06-6.93746626E-21 + 1.70747902E-08 3.94128332E-23 1.06036391E-03 0.00000000E+00-6.51670722E-06 + 0.00000000E+00-1.60584009E-06-2.14336226E-10-4.00319026E-08 5.22598364E-12 + 0.00000000E+00-6.27692959E-11 0.00000000E+00 2.37467613E-14-1.60584009E-06 +-2.14336226E-10-4.00319026E-08 5.22598364E-12 0.00000000E+00-6.27692959E-11 + 0.00000000E+00 2.37467613E-14 0.00000000E+00 2.98130723E-13-4.00332114E-08 +-1.00930141E-11-2.24878555E-05 0.00000000E+00 9.71039581E-08 2.67085036E-21 +-2.24878555E-05 0.00000000E+00 9.71039581E-08 2.67085036E-21 0.00000000E+00 + 1.32213241E-08 0.00000000E+00 1.63262927E-13-2.38346856E-04 6.19504734E-08 +-8.00546092E-08-1.53186028E-11 8.99351051E-05 0.00000000E+00 3.59762062E-04 + 0.00000000E+00 2.12487408E-06-6.09421977E-21 8.59019160E-06-2.54342703E-20 + 8.99351051E-05 0.00000000E+00 3.59762062E-04 0.00000000E+00 2.12487408E-06 +-6.09421977E-21 8.59019160E-06-2.54342703E-20 0.00000000E+00-5.98310281E-10 + 0.00000000E+00-2.37467613E-14 2.47064046E-05-9.02710109E-10-4.00319026E-08 +-5.22598364E-12 8.99355087E-05 0.00000000E+00-6.74624738E-05 0.00000000E+00 + 1.89081858E-06-3.34243744E-21-2.48241706E-06 6.47831070E-21 8.99355087E-05 + 0.00000000E+00-6.74624738E-05 0.00000000E+00 1.89081858E-06-3.34243744E-21 +-2.48241706E-06 6.47831070E-21 4.00332114E-08-1.00930141E-11 0.00000000E+00 + 2.98130723E-13 9.71039581E-08-2.67085036E-21-2.24878555E-05 0.00000000E+00 + 9.71039581E-08-2.67085036E-21-2.24878555E-05 0.00000000E+00 2.38346856E-04 + 6.19504734E-08 8.00546092E-08-1.53186028E-11 0.00000000E+00 1.32213241E-08 + 0.00000000E+00 1.63262927E-13 2.12487408E-06 6.09421977E-21 8.59019160E-06 + 2.54342703E-20 8.99351051E-05 0.00000000E+00 3.59762062E-04 0.00000000E+00 + 2.12487408E-06 6.09421977E-21 8.59019160E-06 2.54342703E-20 8.99351051E-05 + 0.00000000E+00 3.59762062E-04 0.00000000E+00-2.47064046E-05-9.02710109E-10 + 4.00319026E-08-5.22598364E-12 0.00000000E+00-5.98310281E-10 0.00000000E+00 +-2.37467613E-14 1.89081858E-06 3.34243744E-21-2.48241706E-06-6.47831070E-21 + 8.99355087E-05 0.00000000E+00-6.74624738E-05 0.00000000E+00 1.89081858E-06 + 3.34243744E-21-2.48241706E-06-6.47831070E-21 8.99355087E-05 0.00000000E+00 +-6.74624738E-05 0.00000000E+00 0.00000000E+00 2.98130723E-13-4.00332114E-08 +-1.00930141E-11-2.24878555E-05 0.00000000E+00 9.71039581E-08 2.67085036E-21 +-5.32450844E+00 0.00000000E+00-1.52219364E-02 9.82546293E-18 0.00000000E+00 + 1.32213241E-08 0.00000000E+00 1.63262927E-13-2.38346856E-04 6.19504734E-08 +-8.00546092E-08-1.53186028E-11 8.99351051E-05 0.00000000E+00 3.59762062E-04 + 0.00000000E+00 2.12487408E-06-6.09421977E-21 8.59019160E-06-2.54342703E-20 + 3.45529031E-05 0.00000000E+00 9.15630721E+00 0.00000000E+00 3.04422621E-02 +-7.79065537E-17 1.21772463E-01-3.05345911E-16 0.00000000E+00-5.98310281E-10 + 0.00000000E+00-2.37467613E-14 2.47064046E-05-9.02710109E-10-4.00319026E-08 +-5.22598364E-12 8.99355087E-05 0.00000000E+00-6.74624738E-05 0.00000000E+00 + 1.89081858E-06-3.34243744E-21-2.48241706E-06 6.47831070E-21 1.99049519E+00 + 0.00000000E+00-7.46458775E-01 0.00000000E+00 3.04424223E-02-9.43265053E-17 +-1.52226282E-02 4.98726132E-17 4.00332114E-08-1.00930141E-11 0.00000000E+00 + 2.98130723E-13 9.71039581E-08-2.67085036E-21-2.24878555E-05 0.00000000E+00 +-1.52219364E-02-9.82546293E-18-5.32450844E+00 0.00000000E+00 2.38346856E-04 + 6.19504734E-08 8.00546092E-08-1.53186028E-11 0.00000000E+00 1.32213241E-08 + 0.00000000E+00 1.63262927E-13 2.12487408E-06 6.09421977E-21 8.59019160E-06 + 2.54342703E-20 8.99351051E-05 0.00000000E+00 3.59762062E-04 0.00000000E+00 + 3.04422621E-02 7.79065537E-17 1.21772463E-01 3.05345911E-16 3.45529031E-05 + 0.00000000E+00 9.15630721E+00 0.00000000E+00-2.47064046E-05-9.02710109E-10 + 4.00319026E-08-5.22598364E-12 0.00000000E+00-5.98310281E-10 0.00000000E+00 +-2.37467613E-14 1.89081858E-06 3.34243744E-21-2.48241706E-06-6.47831070E-21 + 8.99355087E-05 0.00000000E+00-6.74624738E-05 0.00000000E+00 3.04424223E-02 + 9.43265053E-17-1.52226282E-02-4.98726132E-17 1.99049519E+00 0.00000000E+00 +-7.46458775E-01 0.00000000E+00 0.00000000E+00 1.20857195E-08 0.00000000E+00 + 6.27692959E-11-2.96827850E-04 4.30614799E-08-1.60584009E-06 2.14336226E-10 + 8.99355087E-05 0.00000000E+00 1.89081858E-06-3.34243744E-21 8.99355087E-05 + 0.00000000E+00 1.89081858E-06-3.34243744E-21 0.00000000E+00 1.20571371E-08 + 0.00000000E+00-6.26743089E-11-3.52318272E-04 3.58174219E-08 1.76596770E-06 +-1.93432292E-10 1.07938443E-03 0.00000000E+00 1.79914386E-04 0.00000000E+00 + 3.86152484E-05-9.06993318E-20 8.03884968E-06-2.25708054E-20 1.07938443E-03 + 0.00000000E+00 1.79914386E-04 0.00000000E+00 3.86152484E-05-9.06993318E-20 + 8.03884968E-06-2.25708054E-20 2.96827850E-04 4.30614799E-08 1.60584009E-06 + 2.14336226E-10 0.00000000E+00 1.20857195E-08 0.00000000E+00 6.27692959E-11 + 1.89081858E-06 3.34243744E-21 8.99355087E-05 0.00000000E+00 1.89081858E-06 + 3.34243744E-21 8.99355087E-05 0.00000000E+00 3.52318272E-04 3.58174219E-08 +-1.76596770E-06-1.93432292E-10 0.00000000E+00 1.20571371E-08 0.00000000E+00 +-6.26743089E-11 3.86152484E-05 9.06993318E-20 8.03884968E-06 2.25708054E-20 + 1.07938443E-03 0.00000000E+00 1.79914386E-04 0.00000000E+00 3.86152484E-05 + 9.06993318E-20 8.03884968E-06 2.25708054E-20 1.07938443E-03 0.00000000E+00 + 1.79914386E-04 0.00000000E+00 0.00000000E+00 1.20857195E-08 0.00000000E+00 + 6.27692959E-11-2.96827850E-04 4.30614799E-08-1.60584009E-06 2.14336226E-10 + 8.99355087E-05 0.00000000E+00 1.89081858E-06-3.34243744E-21 1.99049519E+00 + 0.00000000E+00 3.04424223E-02-9.43265053E-17 0.00000000E+00 1.20571371E-08 + 0.00000000E+00-6.26743089E-11-3.52318272E-04 3.58174219E-08 1.76596770E-06 +-1.93432292E-10 1.07938443E-03 0.00000000E+00 1.79914386E-04 0.00000000E+00 + 3.86152484E-05-9.06993318E-20 8.03884968E-06-2.25708054E-20 1.15452375E+01 + 0.00000000E+00 9.95339906E-01 0.00000000E+00 2.43560646E-01-8.75244199E-16 + 3.04480903E-02-1.05163947E-16 5.12633896E-04 2.38640242E-08 2.72678577E-06 + 1.21299299E-10 0.00000000E+00 1.20012210E-08 0.00000000E+00 6.23497348E-11 + 8.03935107E-06 2.88699829E-20 1.79911893E-04 0.00000000E+00 3.04480281E-02 + 7.33421282E-17 1.04040854E+00 0.00000000E+00 5.68131739E-04 2.19182897E-08 +-2.88693442E-06-1.15794206E-10 0.00000000E+00 1.20174288E-08 0.00000000E+00 +-6.23997595E-11 1.04956041E-04 3.56535389E-19 1.85000411E-05 5.61302147E-20 + 1.79946880E-03 0.00000000E+00 2.69962119E-04 0.00000000E+00 2.43619469E-01 + 2.11750019E-16 3.04570830E-02-2.65162758E-18 6.85586021E+00 0.00000000E+00 + 6.93716262E-01 0.00000000E+00 1.74219402E-01 0.00000000E+00 1.06036391E-03 + 0.00000000E+00-4.55670288E-04 1.05052103E-18-2.84779494E-06 6.93746626E-21 + 0.00000000E+00 5.98310281E-10-2.47064046E-05 9.02710109E-10 0.00000000E+00 + 5.98310281E-10-2.47064046E-05 9.02710109E-10 7.59315917E-01 0.00000000E+00 +-4.54643281E-04 0.00000000E+00-2.61817667E-03 9.70437203E-18 3.57548951E-08 + 7.00338996E-21 0.00000000E+00-1.20571371E-08 0.00000000E+00-1.32048739E-08 + 3.52318272E-04-3.58174219E-08 4.75721252E-04-3.09450206E-08 0.00000000E+00 +-1.20571371E-08 0.00000000E+00-1.32048739E-08 3.52318272E-04-3.58174219E-08 + 4.75721252E-04-3.09450206E-08 1.03550242E-01 0.00000000E+00-6.57289798E-04 + 0.00000000E+00-4.50221714E-04 2.04249510E-18 2.81655538E-06-1.27299719E-20 + 0.00000000E+00-1.20012210E-08 0.00000000E+00 5.98120072E-10 5.12633896E-04 +-2.38640242E-08-1.85403385E-05 1.45442440E-09 0.00000000E+00-1.20012210E-08 + 0.00000000E+00 5.98120072E-10 5.12633896E-04-2.38640242E-08-1.85403385E-05 + 1.45442440E-09-7.75099760E-06-3.11617040E-09 4.00319026E-08-5.22598364E-12 + 0.00000000E+00-6.07284573E-10 0.00000000E+00-2.37467613E-14-2.48241706E-06 +-6.47831070E-21-6.74624738E-05 0.00000000E+00-1.52226282E-02-4.98726132E-17 +-7.46458775E-01 0.00000000E+00 4.75721252E-04 3.09450206E-08 8.00661270E-08 +-5.47824535E-12 0.00000000E+00 1.32048739E-08 0.00000000E+00-3.87076439E-14 + 8.03884968E-06 2.25708054E-20 3.36959327E-05 1.05424862E-19 1.79914386E-04 + 0.00000000E+00 7.19678004E-04 0.00000000E+00 3.04480903E-02 1.05163947E-16 + 1.21793452E-01 3.27621091E-16 9.95339906E-01 0.00000000E+00 4.30151852E+00 + 0.00000000E+00-3.54980149E-05-8.62005532E-10 4.00371611E-08-1.37627343E-12 + 0.00000000E+00-6.03135107E-10 0.00000000E+00 1.25061766E-14 8.03935107E-06 + 2.88699829E-20-6.63484803E-06-2.12500494E-20 1.79911893E-04 0.00000000E+00 +-1.12468503E-04 0.00000000E+00 3.04480281E-02 7.33421282E-17-1.52262778E-02 +-1.76726252E-17 1.04040854E+00 0.00000000E+00-4.33531200E-01 0.00000000E+00 + 0.00000000E+00-6.07284573E-10 0.00000000E+00-2.37467613E-14 7.75099760E-06 +-3.11617040E-09-4.00319026E-08-5.22598364E-12-6.74624738E-05 0.00000000E+00 +-2.48241706E-06 6.47831070E-21-7.46458775E-01 0.00000000E+00-1.52226282E-02 + 4.98726132E-17 0.00000000E+00 1.32048739E-08 0.00000000E+00-3.87076439E-14 +-4.75721252E-04 3.09450206E-08-8.00661270E-08-5.47824535E-12 1.79914386E-04 + 0.00000000E+00 7.19678004E-04 0.00000000E+00 8.03884968E-06-2.25708054E-20 + 3.36959327E-05-1.05424862E-19 9.95339906E-01 0.00000000E+00 4.30151852E+00 + 0.00000000E+00 3.04480903E-02-1.05163947E-16 1.21793452E-01-3.27621091E-16 + 0.00000000E+00-6.03135107E-10 0.00000000E+00 1.25061766E-14 3.54980149E-05 +-8.62005532E-10-4.00371611E-08-1.37627343E-12 1.79911893E-04 0.00000000E+00 +-1.12468503E-04 0.00000000E+00 8.03935107E-06-2.88699829E-20-6.63484803E-06 + 2.12500494E-20 1.04040854E+00 0.00000000E+00-4.33531200E-01 0.00000000E+00 + 3.04480281E-02-7.33421282E-17-1.52262778E-02 1.76726252E-17-7.75099760E-06 +-3.11617040E-09 4.00319026E-08-5.22598364E-12 0.00000000E+00-6.07284573E-10 + 0.00000000E+00-2.37467613E-14-2.48241706E-06-6.47831070E-21-6.74624738E-05 + 0.00000000E+00-2.48241706E-06-6.47831070E-21-6.74624738E-05 0.00000000E+00 + 4.75721252E-04 3.09450206E-08 8.00661270E-08-5.47824535E-12 0.00000000E+00 + 1.32048739E-08 0.00000000E+00-3.87076439E-14 8.03884968E-06 2.25708054E-20 + 3.36959327E-05 1.05424862E-19 1.79914386E-04 0.00000000E+00 7.19678004E-04 + 0.00000000E+00 8.03884968E-06 2.25708054E-20 3.36959327E-05 1.05424862E-19 + 1.79914386E-04 0.00000000E+00 7.19678004E-04 0.00000000E+00-3.54980149E-05 +-8.62005532E-10 4.00371611E-08-1.37627343E-12 0.00000000E+00-6.03135107E-10 + 0.00000000E+00 1.25061766E-14 8.03935107E-06 2.88699829E-20-6.63484803E-06 +-2.12500494E-20 1.79911893E-04 0.00000000E+00-1.12468503E-04 0.00000000E+00 + 8.03935107E-06 2.88699829E-20-6.63484803E-06-2.12500494E-20 1.79911893E-04 + 0.00000000E+00-1.12468503E-04 0.00000000E+00 0.00000000E+00-6.07284573E-10 + 0.00000000E+00-2.37467613E-14 7.75099760E-06-3.11617040E-09-4.00319026E-08 +-5.22598364E-12-6.74624738E-05 0.00000000E+00-2.48241706E-06 6.47831070E-21 +-6.74624738E-05 0.00000000E+00-2.48241706E-06 6.47831070E-21 0.00000000E+00 + 1.32048739E-08 0.00000000E+00-3.87076439E-14-4.75721252E-04 3.09450206E-08 +-8.00661270E-08-5.47824535E-12 1.79914386E-04 0.00000000E+00 7.19678004E-04 + 0.00000000E+00 8.03884968E-06-2.25708054E-20 3.36959327E-05-1.05424862E-19 + 1.79914386E-04 0.00000000E+00 7.19678004E-04 0.00000000E+00 8.03884968E-06 +-2.25708054E-20 3.36959327E-05-1.05424862E-19 0.00000000E+00-6.03135107E-10 + 0.00000000E+00 1.25061766E-14 3.54980149E-05-8.62005532E-10-4.00371611E-08 +-1.37627343E-12 1.79911893E-04 0.00000000E+00-1.12468503E-04 0.00000000E+00 + 8.03935107E-06-2.88699829E-20-6.63484803E-06 2.12500494E-20 1.79911893E-04 + 0.00000000E+00-1.12468503E-04 0.00000000E+00 8.03935107E-06-2.88699829E-20 +-6.63484803E-06 2.12500494E-20 2.85016886E-06 6.20377319E-21 1.70747902E-08 + 3.94128332E-23-1.11698387E-03 0.00000000E+00-6.51670722E-06 0.00000000E+00 +-4.00319026E-08 5.22598364E-12 0.00000000E+00 2.37467613E-14-4.00319026E-08 + 5.22598364E-12 0.00000000E+00 2.37467613E-14 3.57548951E-08-7.00338996E-21 +-4.52721089E-08-1.62489536E-22-4.54643281E-04 0.00000000E+00 1.34256245E-05 + 0.00000000E+00 1.76596770E-06 1.93432292E-10-8.00661270E-08 5.47824535E-12 + 0.00000000E+00 6.26743089E-11 0.00000000E+00 3.87076439E-14 1.76596770E-06 + 1.93432292E-10-8.00661270E-08 5.47824535E-12 0.00000000E+00 6.26743089E-11 + 0.00000000E+00 3.87076439E-14-2.81330261E-06-1.28258817E-20 1.68709408E-08 + 7.66854568E-23 6.37319247E-04 0.00000000E+00-3.87786425E-06 0.00000000E+00 +-2.72678577E-06-1.21299299E-10-4.00371611E-08 1.37627343E-12 0.00000000E+00 +-6.23497348E-11 0.00000000E+00-1.25061766E-14-2.72678577E-06-1.21299299E-10 +-4.00371611E-08 1.37627343E-12 0.00000000E+00-6.23497348E-11 0.00000000E+00 +-1.25061766E-14-4.55670288E-04-1.05052103E-18-2.84779494E-06-6.93746626E-21 + 1.74219402E-01 0.00000000E+00 1.06036391E-03 0.00000000E+00 2.47064046E-05 + 9.02710109E-10 0.00000000E+00 5.98310281E-10 2.47064046E-05 9.02710109E-10 + 0.00000000E+00 5.98310281E-10-2.61817667E-03-9.70437203E-18 3.57548951E-08 +-7.00338996E-21 7.59315917E-01 0.00000000E+00-4.54643281E-04 0.00000000E+00 +-3.52318272E-04-3.58174219E-08-4.75721252E-04-3.09450206E-08 0.00000000E+00 +-1.20571371E-08 0.00000000E+00-1.32048739E-08-3.52318272E-04-3.58174219E-08 +-4.75721252E-04-3.09450206E-08 0.00000000E+00-1.20571371E-08 0.00000000E+00 +-1.32048739E-08-4.50221714E-04-2.04249510E-18 2.81655538E-06 1.27299719E-20 + 1.03550242E-01 0.00000000E+00-6.57289798E-04 0.00000000E+00-5.12633896E-04 +-2.38640242E-08 1.85403385E-05 1.45442440E-09 0.00000000E+00-1.20012210E-08 + 0.00000000E+00 5.98120072E-10-5.12633896E-04-2.38640242E-08 1.85403385E-05 + 1.45442440E-09 0.00000000E+00-1.20012210E-08 0.00000000E+00 5.98120072E-10 +-1.11698387E-03 0.00000000E+00-6.51670722E-06 0.00000000E+00 2.85016886E-06 +-6.20377319E-21 1.70747902E-08-3.94128332E-23 0.00000000E+00 2.37467613E-14 + 4.00319026E-08 5.22598364E-12 0.00000000E+00 2.37467613E-14 4.00319026E-08 + 5.22598364E-12-4.54643281E-04 0.00000000E+00 1.34256245E-05 0.00000000E+00 + 3.57548951E-08 7.00338996E-21-4.52721089E-08 1.62489536E-22 0.00000000E+00 + 6.26743089E-11 0.00000000E+00 3.87076439E-14-1.76596770E-06 1.93432292E-10 + 8.00661270E-08 5.47824535E-12 0.00000000E+00 6.26743089E-11 0.00000000E+00 + 3.87076439E-14-1.76596770E-06 1.93432292E-10 8.00661270E-08 5.47824535E-12 + 6.37319247E-04 0.00000000E+00-3.87786425E-06 0.00000000E+00-2.81330261E-06 + 1.28258817E-20 1.68709408E-08-7.66854568E-23 0.00000000E+00-6.23497348E-11 + 0.00000000E+00-1.25061766E-14 2.72678577E-06-1.21299299E-10 4.00371611E-08 + 1.37627343E-12 0.00000000E+00-6.23497348E-11 0.00000000E+00-1.25061766E-14 + 2.72678577E-06-1.21299299E-10 4.00371611E-08 1.37627343E-12 0.00000000E+00 + 1.20012210E-08 0.00000000E+00 6.23497348E-11-5.12633896E-04 2.38640242E-08 +-2.72678577E-06 1.21299299E-10 1.79911893E-04 0.00000000E+00 8.03935107E-06 +-2.88699829E-20 1.79911893E-04 0.00000000E+00 8.03935107E-06-2.88699829E-20 + 0.00000000E+00 1.20174288E-08 0.00000000E+00-6.23997595E-11-5.68131739E-04 + 2.19182897E-08 2.88693442E-06-1.15794206E-10 1.79946880E-03 0.00000000E+00 + 2.69962119E-04 0.00000000E+00 1.04956041E-04-3.56535389E-19 1.85000411E-05 +-5.61302147E-20 1.79946880E-03 0.00000000E+00 2.69962119E-04 0.00000000E+00 + 1.04956041E-04-3.56535389E-19 1.85000411E-05-5.61302147E-20 5.12633896E-04 + 2.38640242E-08 2.72678577E-06 1.21299299E-10 0.00000000E+00 1.20012210E-08 + 0.00000000E+00 6.23497348E-11 8.03935107E-06 2.88699829E-20 1.79911893E-04 + 0.00000000E+00 8.03935107E-06 2.88699829E-20 1.79911893E-04 0.00000000E+00 + 5.68131739E-04 2.19182897E-08-2.88693442E-06-1.15794206E-10 0.00000000E+00 + 1.20174288E-08 0.00000000E+00-6.23997595E-11 1.04956041E-04 3.56535389E-19 + 1.85000411E-05 5.61302147E-20 1.79946880E-03 0.00000000E+00 2.69962119E-04 + 0.00000000E+00 1.04956041E-04 3.56535389E-19 1.85000411E-05 5.61302147E-20 + 1.79946880E-03 0.00000000E+00 2.69962119E-04 0.00000000E+00 0.00000000E+00 + 1.20012210E-08 0.00000000E+00 6.23497348E-11-5.12633896E-04 2.38640242E-08 +-2.72678577E-06 1.21299299E-10 1.79911893E-04 0.00000000E+00 8.03935107E-06 +-2.88699829E-20 1.04040854E+00 0.00000000E+00 3.04480281E-02-7.33421282E-17 + 0.00000000E+00 1.20174288E-08 0.00000000E+00-6.23997595E-11-5.68131739E-04 + 2.19182897E-08 2.88693442E-06-1.15794206E-10 1.79946880E-03 0.00000000E+00 + 2.69962119E-04 0.00000000E+00 1.04956041E-04-3.56535389E-19 1.85000411E-05 +-5.61302147E-20 6.85586021E+00 0.00000000E+00 6.93716262E-01 0.00000000E+00 + 2.43619469E-01-2.11750019E-16 3.04570830E-02 2.65162758E-18 7.28403617E-04 + 1.79388205E-08 3.84745108E-06 9.18196769E-11 0.00000000E+00 1.20533236E-08 + 0.00000000E+00 6.26131844E-11 1.84996244E-05 4.72947059E-20 2.69959957E-04 + 0.00000000E+00 3.04569905E-02 1.48691177E-17 7.01787952E-01 0.00000000E+00 + 7.83802446E-04 1.68344745E-08-4.00731985E-06-8.86251281E-11 0.00000000E+00 + 1.20571862E-08 0.00000000E+00-6.26236510E-11 2.05232888E-04 4.20159737E-19 + 3.31061369E-05 6.34179378E-20 2.52030057E-03 0.00000000E+00 3.60124633E-04 + 0.00000000E+00 2.43705163E-01 6.40756784E-16 3.04695545E-02 1.45867592E-16 + 4.88406857E+00 0.00000000E+00 5.26451423E-01 0.00000000E+00 1.03550242E-01 + 0.00000000E+00 6.37319247E-04 0.00000000E+00-4.50221714E-04 2.04249510E-18 +-2.81330261E-06 1.28258817E-20 0.00000000E+00 6.03135107E-10-3.54980149E-05 + 8.62005532E-10 0.00000000E+00 6.03135107E-10-3.54980149E-05 8.62005532E-10 + 5.00624946E-01 0.00000000E+00-1.96208182E-04 0.00000000E+00-2.57845141E-03 + 1.07736966E-17 5.83895678E-08-4.34983776E-21 0.00000000E+00-1.20174288E-08 + 0.00000000E+00-1.32457192E-08 5.68131739E-04-2.19182897E-08 7.13123719E-04 +-2.17147902E-08 0.00000000E+00-1.20174288E-08 0.00000000E+00-1.32457192E-08 + 5.68131739E-04-2.19182897E-08 7.13123719E-04-2.17147902E-08 7.38446799E-02 + 0.00000000E+00-4.66716499E-04 0.00000000E+00-4.41589833E-04 1.53590813E-18 + 2.76342658E-06-9.70934951E-21 0.00000000E+00-1.20533236E-08 0.00000000E+00 + 6.02136996E-10 7.28403617E-04-1.79388205E-08-2.93398284E-05 1.04148447E-09 + 0.00000000E+00-1.20533236E-08 0.00000000E+00 6.02136996E-10 7.28403617E-04 +-1.79388205E-08-2.93398284E-05 1.04148447E-09-1.85403385E-05-1.45442440E-09 + 4.00371611E-08-1.37627343E-12 0.00000000E+00-5.98120072E-10 0.00000000E+00 + 1.25061766E-14-6.63484803E-06-2.12500494E-20-1.12468503E-04 0.00000000E+00 +-1.52262778E-02-1.76726252E-17-4.33531200E-01 0.00000000E+00 7.13123719E-04 + 2.17147902E-08 8.00762788E-08-1.86355687E-12 0.00000000E+00 1.32457192E-08 + 0.00000000E+00 1.94002525E-14 1.85000411E-05 5.61302147E-20 7.54800474E-05 + 2.03098584E-19 2.69962119E-04 0.00000000E+00 1.07988506E-03 0.00000000E+00 + 3.04570830E-02-2.65162758E-18 1.21829401E-01 9.80370983E-17 6.93716262E-01 + 0.00000000E+00 2.85213344E+00 0.00000000E+00-4.62673721E-05-7.03895672E-10 + 3.99671908E-08-7.98637196E-13 0.00000000E+00-6.03304141E-10 0.00000000E+00 + 2.61665674E-15 1.84996244E-05 4.72947059E-20-1.29014403E-05-2.76781609E-20 + 2.69959957E-04 0.00000000E+00-1.57521148E-04 0.00000000E+00 3.04569905E-02 + 1.48691177E-17-1.52316362E-02-4.01841774E-17 7.01787952E-01 0.00000000E+00 +-3.07059844E-01 0.00000000E+00 0.00000000E+00-5.98120072E-10 0.00000000E+00 + 1.25061766E-14 1.85403385E-05-1.45442440E-09-4.00371611E-08-1.37627343E-12 +-1.12468503E-04 0.00000000E+00-6.63484803E-06 2.12500494E-20-4.33531200E-01 + 0.00000000E+00-1.52262778E-02 1.76726252E-17 0.00000000E+00 1.32457192E-08 + 0.00000000E+00 1.94002525E-14-7.13123719E-04 2.17147902E-08-8.00762788E-08 +-1.86355687E-12 2.69962119E-04 0.00000000E+00 1.07988506E-03 0.00000000E+00 + 1.85000411E-05-5.61302147E-20 7.54800474E-05-2.03098584E-19 6.93716262E-01 + 0.00000000E+00 2.85213344E+00 0.00000000E+00 3.04570830E-02 2.65162758E-18 + 1.21829401E-01-9.80370983E-17 0.00000000E+00-6.03304141E-10 0.00000000E+00 + 2.61665674E-15 4.62673721E-05-7.03895672E-10-3.99671908E-08-7.98637196E-13 + 2.69959957E-04 0.00000000E+00-1.57521148E-04 0.00000000E+00 1.84996244E-05 +-4.72947059E-20-1.29014403E-05 2.76781609E-20 7.01787952E-01 0.00000000E+00 +-3.07059844E-01 0.00000000E+00 3.04569905E-02-1.48691177E-17-1.52316362E-02 + 4.01841774E-17-1.85403385E-05-1.45442440E-09 4.00371611E-08-1.37627343E-12 + 0.00000000E+00-5.98120072E-10 0.00000000E+00 1.25061766E-14-6.63484803E-06 +-2.12500494E-20-1.12468503E-04 0.00000000E+00-6.63484803E-06-2.12500494E-20 +-1.12468503E-04 0.00000000E+00 7.13123719E-04 2.17147902E-08 8.00762788E-08 +-1.86355687E-12 0.00000000E+00 1.32457192E-08 0.00000000E+00 1.94002525E-14 + 1.85000411E-05 5.61302147E-20 7.54800474E-05 2.03098584E-19 2.69962119E-04 + 0.00000000E+00 1.07988506E-03 0.00000000E+00 1.85000411E-05 5.61302147E-20 + 7.54800474E-05 2.03098584E-19 2.69962119E-04 0.00000000E+00 1.07988506E-03 + 0.00000000E+00-4.62673721E-05-7.03895672E-10 3.99671908E-08-7.98637196E-13 + 0.00000000E+00-6.03304141E-10 0.00000000E+00 2.61665674E-15 1.84996244E-05 + 4.72947059E-20-1.29014403E-05-2.76781609E-20 2.69959957E-04 0.00000000E+00 +-1.57521148E-04 0.00000000E+00 1.84996244E-05 4.72947059E-20-1.29014403E-05 +-2.76781609E-20 2.69959957E-04 0.00000000E+00-1.57521148E-04 0.00000000E+00 + 0.00000000E+00-5.98120072E-10 0.00000000E+00 1.25061766E-14 1.85403385E-05 +-1.45442440E-09-4.00371611E-08-1.37627343E-12-1.12468503E-04 0.00000000E+00 +-6.63484803E-06 2.12500494E-20-1.12468503E-04 0.00000000E+00-6.63484803E-06 + 2.12500494E-20 0.00000000E+00 1.32457192E-08 0.00000000E+00 1.94002525E-14 +-7.13123719E-04 2.17147902E-08-8.00762788E-08-1.86355687E-12 2.69962119E-04 + 0.00000000E+00 1.07988506E-03 0.00000000E+00 1.85000411E-05-5.61302147E-20 + 7.54800474E-05-2.03098584E-19 2.69962119E-04 0.00000000E+00 1.07988506E-03 + 0.00000000E+00 1.85000411E-05-5.61302147E-20 7.54800474E-05-2.03098584E-19 + 0.00000000E+00-6.03304141E-10 0.00000000E+00 2.61665674E-15 4.62673721E-05 +-7.03895672E-10-3.99671908E-08-7.98637196E-13 2.69959957E-04 0.00000000E+00 +-1.57521148E-04 0.00000000E+00 1.84996244E-05-4.72947059E-20-1.29014403E-05 + 2.76781609E-20 2.69959957E-04 0.00000000E+00-1.57521148E-04 0.00000000E+00 + 1.84996244E-05-4.72947059E-20-1.29014403E-05 2.76781609E-20 2.81655538E-06 + 1.27299719E-20 1.68709408E-08 7.66854568E-23-6.57289798E-04 0.00000000E+00 +-3.87786425E-06 0.00000000E+00-4.00371611E-08 1.37627343E-12 0.00000000E+00 +-1.25061766E-14-4.00371611E-08 1.37627343E-12 0.00000000E+00-1.25061766E-14 + 5.83895678E-08 4.34983776E-21-4.45784504E-08-1.82919987E-22-1.96208182E-04 + 0.00000000E+00 8.74060922E-06 0.00000000E+00 2.88693442E-06 1.15794206E-10 +-8.00762788E-08 1.86355687E-12 0.00000000E+00 6.23997595E-11 0.00000000E+00 +-1.94002525E-14 2.88693442E-06 1.15794206E-10-8.00762788E-08 1.86355687E-12 + 0.00000000E+00 6.23997595E-11 0.00000000E+00-1.94002525E-14-2.75847080E-06 +-9.48370596E-21 1.65473286E-08 5.74287815E-23 4.56590205E-04 0.00000000E+00 +-2.76624049E-06 0.00000000E+00-3.84745108E-06-9.18196769E-11-3.99671908E-08 + 7.98637196E-13 0.00000000E+00-6.26131844E-11 0.00000000E+00-2.61665674E-15 +-3.84745108E-06-9.18196769E-11-3.99671908E-08 7.98637196E-13 0.00000000E+00 +-6.26131844E-11 0.00000000E+00-2.61665674E-15-4.50221714E-04-2.04249510E-18 +-2.81330261E-06-1.28258817E-20 1.03550242E-01 0.00000000E+00 6.37319247E-04 + 0.00000000E+00 3.54980149E-05 8.62005532E-10 0.00000000E+00 6.03135107E-10 + 3.54980149E-05 8.62005532E-10 0.00000000E+00 6.03135107E-10-2.57845141E-03 +-1.07736966E-17 5.83895678E-08 4.34983776E-21 5.00624946E-01 0.00000000E+00 +-1.96208182E-04 0.00000000E+00-5.68131739E-04-2.19182897E-08-7.13123719E-04 +-2.17147902E-08 0.00000000E+00-1.20174288E-08 0.00000000E+00-1.32457192E-08 +-5.68131739E-04-2.19182897E-08-7.13123719E-04-2.17147902E-08 0.00000000E+00 +-1.20174288E-08 0.00000000E+00-1.32457192E-08-4.41589833E-04-1.53590813E-18 + 2.76342658E-06 9.70934951E-21 7.38446799E-02 0.00000000E+00-4.66716499E-04 + 0.00000000E+00-7.28403617E-04-1.79388205E-08 2.93398284E-05 1.04148447E-09 + 0.00000000E+00-1.20533236E-08 0.00000000E+00 6.02136996E-10-7.28403617E-04 +-1.79388205E-08 2.93398284E-05 1.04148447E-09 0.00000000E+00-1.20533236E-08 + 0.00000000E+00 6.02136996E-10-6.57289798E-04 0.00000000E+00-3.87786425E-06 + 0.00000000E+00 2.81655538E-06-1.27299719E-20 1.68709408E-08-7.66854568E-23 + 0.00000000E+00-1.25061766E-14 4.00371611E-08 1.37627343E-12 0.00000000E+00 +-1.25061766E-14 4.00371611E-08 1.37627343E-12-1.96208182E-04 0.00000000E+00 + 8.74060922E-06 0.00000000E+00 5.83895678E-08-4.34983776E-21-4.45784504E-08 + 1.82919987E-22 0.00000000E+00 6.23997595E-11 0.00000000E+00-1.94002525E-14 +-2.88693442E-06 1.15794206E-10 8.00762788E-08 1.86355687E-12 0.00000000E+00 + 6.23997595E-11 0.00000000E+00-1.94002525E-14-2.88693442E-06 1.15794206E-10 + 8.00762788E-08 1.86355687E-12 4.56590205E-04 0.00000000E+00-2.76624049E-06 + 0.00000000E+00-2.75847080E-06 9.48370596E-21 1.65473286E-08-5.74287815E-23 + 0.00000000E+00-6.26131844E-11 0.00000000E+00-2.61665674E-15 3.84745108E-06 +-9.18196769E-11 3.99671908E-08 7.98637196E-13 0.00000000E+00-6.26131844E-11 + 0.00000000E+00-2.61665674E-15 3.84745108E-06-9.18196769E-11 3.99671908E-08 + 7.98637196E-13 0.00000000E+00 1.20533236E-08 0.00000000E+00 6.26131844E-11 +-7.28403617E-04 1.79388205E-08-3.84745108E-06 9.18196769E-11 2.69959957E-04 + 0.00000000E+00 1.84996244E-05-4.72947059E-20 2.69959957E-04 0.00000000E+00 + 1.84996244E-05-4.72947059E-20 0.00000000E+00 1.20571862E-08 0.00000000E+00 +-6.26236510E-11-7.83802446E-04 1.68344745E-08 4.00731985E-06-8.86251281E-11 + 2.52030057E-03 0.00000000E+00 3.60124633E-04 0.00000000E+00 2.05232888E-04 +-4.20159737E-19 3.31061369E-05-6.34179378E-20 2.52030057E-03 0.00000000E+00 + 3.60124633E-04 0.00000000E+00 2.05232888E-04-4.20159737E-19 3.31061369E-05 +-6.34179378E-20 7.28403617E-04 1.79388205E-08 3.84745108E-06 9.18196769E-11 + 0.00000000E+00 1.20533236E-08 0.00000000E+00 6.26131844E-11 1.84996244E-05 + 4.72947059E-20 2.69959957E-04 0.00000000E+00 1.84996244E-05 4.72947059E-20 + 2.69959957E-04 0.00000000E+00 7.83802446E-04 1.68344745E-08-4.00731985E-06 +-8.86251281E-11 0.00000000E+00 1.20571862E-08 0.00000000E+00-6.26236510E-11 + 2.05232888E-04 4.20159737E-19 3.31061369E-05 6.34179378E-20 2.52030057E-03 + 0.00000000E+00 3.60124633E-04 0.00000000E+00 2.05232888E-04 4.20159737E-19 + 3.31061369E-05 6.34179378E-20 2.52030057E-03 0.00000000E+00 3.60124633E-04 + 0.00000000E+00 0.00000000E+00 1.20533236E-08 0.00000000E+00 6.26131844E-11 +-7.28403617E-04 1.79388205E-08-3.84745108E-06 9.18196769E-11 2.69959957E-04 + 0.00000000E+00 1.84996244E-05-4.72947059E-20 7.01787952E-01 0.00000000E+00 + 3.04569905E-02-1.48691177E-17 0.00000000E+00 1.20571862E-08 0.00000000E+00 +-6.26236510E-11-7.83802446E-04 1.68344745E-08 4.00731985E-06-8.86251281E-11 + 2.52030057E-03 0.00000000E+00 3.60124633E-04 0.00000000E+00 2.05232888E-04 +-4.20159737E-19 3.31061369E-05-6.34179378E-20 4.88406857E+00 0.00000000E+00 + 5.26451423E-01 0.00000000E+00 2.43705163E-01-6.40756784E-16 3.04695545E-02 +-1.45867592E-16 9.43357356E-04 1.45357677E-08 4.96357275E-06 7.48028240E-11 + 0.00000000E+00 1.20744098E-08 0.00000000E+00 6.27304824E-11 3.31068566E-05 + 8.21190576E-20 3.60121900E-04 0.00000000E+00 3.04694652E-02 1.59557089E-16 + 5.28923861E-01 0.00000000E+00 9.98426591E-04 1.39711211E-08-5.12248152E-06 +-7.31822643E-11 0.00000000E+00 1.20896304E-08 0.00000000E+00-6.27741751E-11 + 3.38772847E-04 6.28018266E-19 5.18836571E-05 6.00996193E-20 3.24219056E-03 + 0.00000000E+00 4.50437997E-04 0.00000000E+00 2.43819302E-01 1.27254241E-15 + 3.04856147E-02 1.39606146E-16 3.79521021E+00 0.00000000E+00 4.23253149E-01 + 0.00000000E+00 7.38446799E-02 0.00000000E+00 4.56590205E-04 0.00000000E+00 +-4.41589833E-04 1.53590813E-18-2.75847080E-06 9.48370596E-21 0.00000000E+00 + 6.03304141E-10-4.62673721E-05 7.03895672E-10 0.00000000E+00 6.03304141E-10 +-4.62673721E-05 7.03895672E-10 3.74432269E-01 0.00000000E+00-1.09189310E-04 + 0.00000000E+00-2.51934704E-03 9.12191690E-18 7.84221017E-08 2.61903684E-21 + 0.00000000E+00-1.20571862E-08 0.00000000E+00-1.32683861E-08 7.83802446E-04 +-1.68344745E-08 9.50054445E-04-1.70610481E-08 0.00000000E+00-1.20571862E-08 + 0.00000000E+00-1.32683861E-08 7.83802446E-04-1.68344745E-08 9.50054445E-04 +-1.70610481E-08 5.74549672E-02 0.00000000E+00-3.62254380E-04 0.00000000E+00 +-4.29934992E-04 1.79579035E-18 2.69121152E-06-1.11589027E-20 0.00000000E+00 +-1.20744098E-08 0.00000000E+00 6.01925375E-10 9.43357356E-04-1.45357677E-08 +-4.01296596E-05 8.00484630E-10 0.00000000E+00-1.20744098E-08 0.00000000E+00 + 6.01925375E-10 9.43357356E-04-1.45357677E-08-4.01296596E-05 8.00484630E-10 +-2.93398284E-05-1.04148447E-09 3.99671908E-08-7.98637196E-13 0.00000000E+00 +-6.02136996E-10 0.00000000E+00 2.61665674E-15-1.29014403E-05-2.76781609E-20 +-1.57521148E-04 0.00000000E+00-1.52316362E-02-4.01841774E-17-3.07059844E-01 + 0.00000000E+00 9.50054445E-04 1.70610481E-08 7.96777527E-08-1.10288433E-12 + 0.00000000E+00 1.32683861E-08 0.00000000E+00 4.76539318E-15 3.31061369E-05 + 6.34179378E-20 1.33915447E-04 2.77257248E-19 3.60124633E-04 0.00000000E+00 + 1.44054723E-03 0.00000000E+00 3.04695545E-02 1.45867592E-16 1.21879320E-01 + 5.56667658E-16 5.26451423E-01 0.00000000E+00 2.13562205E+00 0.00000000E+00 +-5.69563318E-05-6.28123444E-10 3.97271943E-08-4.05139921E-13 0.00000000E+00 +-6.06571712E-10 0.00000000E+00 1.09231881E-14 3.31068566E-05 8.21190576E-20 +-2.12476284E-05-3.55546692E-20 3.60121900E-04 0.00000000E+00-2.02639974E-04 + 0.00000000E+00 3.04694652E-02 1.59557089E-16-1.52387700E-02-7.47908089E-17 + 5.28923861E-01 0.00000000E+00-2.38044252E-01 0.00000000E+00 0.00000000E+00 +-6.02136996E-10 0.00000000E+00 2.61665674E-15 2.93398284E-05-1.04148447E-09 +-3.99671908E-08-7.98637196E-13-1.57521148E-04 0.00000000E+00-1.29014403E-05 + 2.76781609E-20-3.07059844E-01 0.00000000E+00-1.52316362E-02 4.01841774E-17 + 0.00000000E+00 1.32683861E-08 0.00000000E+00 4.76539318E-15-9.50054445E-04 + 1.70610481E-08-7.96777527E-08-1.10288433E-12 3.60124633E-04 0.00000000E+00 + 1.44054723E-03 0.00000000E+00 3.31061369E-05-6.34179378E-20 1.33915447E-04 +-2.77257248E-19 5.26451423E-01 0.00000000E+00 2.13562205E+00 0.00000000E+00 + 3.04695545E-02-1.45867592E-16 1.21879320E-01-5.56667658E-16 0.00000000E+00 +-6.06571712E-10 0.00000000E+00 1.09231881E-14 5.69563318E-05-6.28123444E-10 +-3.97271943E-08-4.05139921E-13 3.60121900E-04 0.00000000E+00-2.02639974E-04 + 0.00000000E+00 3.31068566E-05-8.21190576E-20-2.12476284E-05 3.55546692E-20 + 5.28923861E-01 0.00000000E+00-2.38044252E-01 0.00000000E+00 3.04694652E-02 +-1.59557089E-16-1.52387700E-02 7.47908089E-17-2.93398284E-05-1.04148447E-09 + 3.99671908E-08-7.98637196E-13 0.00000000E+00-6.02136996E-10 0.00000000E+00 + 2.61665674E-15-1.29014403E-05-2.76781609E-20-1.57521148E-04 0.00000000E+00 +-1.29014403E-05-2.76781609E-20-1.57521148E-04 0.00000000E+00 9.50054445E-04 + 1.70610481E-08 7.96777527E-08-1.10288433E-12 0.00000000E+00 1.32683861E-08 + 0.00000000E+00 4.76539318E-15 3.31061369E-05 6.34179378E-20 1.33915447E-04 + 2.77257248E-19 3.60124633E-04 0.00000000E+00 1.44054723E-03 0.00000000E+00 + 3.31061369E-05 6.34179378E-20 1.33915447E-04 2.77257248E-19 3.60124633E-04 + 0.00000000E+00 1.44054723E-03 0.00000000E+00-5.69563318E-05-6.28123444E-10 + 3.97271943E-08-4.05139921E-13 0.00000000E+00-6.06571712E-10 0.00000000E+00 + 1.09231881E-14 3.31068566E-05 8.21190576E-20-2.12476284E-05-3.55546692E-20 + 3.60121900E-04 0.00000000E+00-2.02639974E-04 0.00000000E+00 3.31068566E-05 + 8.21190576E-20-2.12476284E-05-3.55546692E-20 3.60121900E-04 0.00000000E+00 +-2.02639974E-04 0.00000000E+00 0.00000000E+00-6.02136996E-10 0.00000000E+00 + 2.61665674E-15 2.93398284E-05-1.04148447E-09-3.99671908E-08-7.98637196E-13 +-1.57521148E-04 0.00000000E+00-1.29014403E-05 2.76781609E-20-1.57521148E-04 + 0.00000000E+00-1.29014403E-05 2.76781609E-20 0.00000000E+00 1.32683861E-08 + 0.00000000E+00 4.76539318E-15-9.50054445E-04 1.70610481E-08-7.96777527E-08 +-1.10288433E-12 3.60124633E-04 0.00000000E+00 1.44054723E-03 0.00000000E+00 + 3.31061369E-05-6.34179378E-20 1.33915447E-04-2.77257248E-19 3.60124633E-04 + 0.00000000E+00 1.44054723E-03 0.00000000E+00 3.31061369E-05-6.34179378E-20 + 1.33915447E-04-2.77257248E-19 0.00000000E+00-6.06571712E-10 0.00000000E+00 + 1.09231881E-14 5.69563318E-05-6.28123444E-10-3.97271943E-08-4.05139921E-13 + 3.60121900E-04 0.00000000E+00-2.02639974E-04 0.00000000E+00 3.31068566E-05 +-8.21190576E-20-2.12476284E-05 3.55546692E-20 3.60121900E-04 0.00000000E+00 +-2.02639974E-04 0.00000000E+00 3.31068566E-05-8.21190576E-20-2.12476284E-05 + 3.55546692E-20 2.76342658E-06 9.70934951E-21 1.65473286E-08 5.74287815E-23 +-4.66716499E-04 0.00000000E+00-2.76624049E-06 0.00000000E+00-3.99671908E-08 + 7.98637196E-13 0.00000000E+00-2.61665674E-15-3.99671908E-08 7.98637196E-13 + 0.00000000E+00-2.61665674E-15 7.84221017E-08-2.61903684E-21-4.35597697E-08 +-1.61637492E-22-1.09189310E-04 0.00000000E+00 6.50985065E-06 0.00000000E+00 + 4.00731985E-06 8.86251281E-11-7.96777527E-08 1.10288433E-12 0.00000000E+00 + 6.26236510E-11 0.00000000E+00-4.76539318E-15 4.00731985E-06 8.86251281E-11 +-7.96777527E-08 1.10288433E-12 0.00000000E+00 6.26236510E-11 0.00000000E+00 +-4.76539318E-15-2.68493262E-06-1.13072021E-20 1.61105167E-08 6.73945958E-23 + 3.56150735E-04 0.00000000E+00-2.15252822E-06 0.00000000E+00-4.96357275E-06 +-7.48028240E-11-3.97271943E-08 4.05139921E-13 0.00000000E+00-6.27304824E-11 + 0.00000000E+00-1.09231881E-14-4.96357275E-06-7.48028240E-11-3.97271943E-08 + 4.05139921E-13 0.00000000E+00-6.27304824E-11 0.00000000E+00-1.09231881E-14 +-4.41589833E-04-1.53590813E-18-2.75847080E-06-9.48370596E-21 7.38446799E-02 + 0.00000000E+00 4.56590205E-04 0.00000000E+00 4.62673721E-05 7.03895672E-10 + 0.00000000E+00 6.03304141E-10 4.62673721E-05 7.03895672E-10 0.00000000E+00 + 6.03304141E-10-2.51934704E-03-9.12191690E-18 7.84221017E-08-2.61903684E-21 + 3.74432269E-01 0.00000000E+00-1.09189310E-04 0.00000000E+00-7.83802446E-04 +-1.68344745E-08-9.50054445E-04-1.70610481E-08 0.00000000E+00-1.20571862E-08 + 0.00000000E+00-1.32683861E-08-7.83802446E-04-1.68344745E-08-9.50054445E-04 +-1.70610481E-08 0.00000000E+00-1.20571862E-08 0.00000000E+00-1.32683861E-08 +-4.29934992E-04-1.79579035E-18 2.69121152E-06 1.11589027E-20 5.74549672E-02 + 0.00000000E+00-3.62254380E-04 0.00000000E+00-9.43357356E-04-1.45357677E-08 + 4.01296596E-05 8.00484630E-10 0.00000000E+00-1.20744098E-08 0.00000000E+00 + 6.01925375E-10-9.43357356E-04-1.45357677E-08 4.01296596E-05 8.00484630E-10 + 0.00000000E+00-1.20744098E-08 0.00000000E+00 6.01925375E-10-4.66716499E-04 + 0.00000000E+00-2.76624049E-06 0.00000000E+00 2.76342658E-06-9.70934951E-21 + 1.65473286E-08-5.74287815E-23 0.00000000E+00-2.61665674E-15 3.99671908E-08 + 7.98637196E-13 0.00000000E+00-2.61665674E-15 3.99671908E-08 7.98637196E-13 +-1.09189310E-04 0.00000000E+00 6.50985065E-06 0.00000000E+00 7.84221017E-08 + 2.61903684E-21-4.35597697E-08 1.61637492E-22 0.00000000E+00 6.26236510E-11 + 0.00000000E+00-4.76539318E-15-4.00731985E-06 8.86251281E-11 7.96777527E-08 + 1.10288433E-12 0.00000000E+00 6.26236510E-11 0.00000000E+00-4.76539318E-15 +-4.00731985E-06 8.86251281E-11 7.96777527E-08 1.10288433E-12 3.56150735E-04 + 0.00000000E+00-2.15252822E-06 0.00000000E+00-2.68493262E-06 1.13072021E-20 + 1.61105167E-08-6.73945958E-23 0.00000000E+00-6.27304824E-11 0.00000000E+00 +-1.09231881E-14 4.96357275E-06-7.48028240E-11 3.97271943E-08 4.05139921E-13 + 0.00000000E+00-6.27304824E-11 0.00000000E+00-1.09231881E-14 4.96357275E-06 +-7.48028240E-11 3.97271943E-08 4.05139921E-13 0.00000000E+00 1.20744098E-08 + 0.00000000E+00 6.27304824E-11-9.43357356E-04 1.45357677E-08-4.96357275E-06 + 7.48028240E-11 3.60121900E-04 0.00000000E+00 3.31068566E-05-8.21190576E-20 + 3.60121900E-04 0.00000000E+00 3.31068566E-05-8.21190576E-20 0.00000000E+00 + 1.20896304E-08 0.00000000E+00-6.27741751E-11-9.98426591E-04 1.39711211E-08 + 5.12248152E-06-7.31822643E-11 3.24219056E-03 0.00000000E+00 4.50437997E-04 + 0.00000000E+00 3.38772847E-04-6.28018266E-19 5.18836571E-05-6.00996193E-20 + 3.24219056E-03 0.00000000E+00 4.50437997E-04 0.00000000E+00 3.38772847E-04 +-6.28018266E-19 5.18836571E-05-6.00996193E-20 9.43357356E-04 1.45357677E-08 + 4.96357275E-06 7.48028240E-11 0.00000000E+00 1.20744098E-08 0.00000000E+00 + 6.27304824E-11 3.31068566E-05 8.21190576E-20 3.60121900E-04 0.00000000E+00 + 3.31068566E-05 8.21190576E-20 3.60121900E-04 0.00000000E+00 9.98426591E-04 + 1.39711211E-08-5.12248152E-06-7.31822643E-11 0.00000000E+00 1.20896304E-08 + 0.00000000E+00-6.27741751E-11 3.38772847E-04 6.28018266E-19 5.18836571E-05 + 6.00996193E-20 3.24219056E-03 0.00000000E+00 4.50437997E-04 0.00000000E+00 + 3.38772847E-04 6.28018266E-19 5.18836571E-05 6.00996193E-20 3.24219056E-03 + 0.00000000E+00 4.50437997E-04 0.00000000E+00 0.00000000E+00 1.20744098E-08 + 0.00000000E+00 6.27304824E-11-9.43357356E-04 1.45357677E-08-4.96357275E-06 + 7.48028240E-11 3.60121900E-04 0.00000000E+00 3.31068566E-05-8.21190576E-20 + 5.28923861E-01 0.00000000E+00 3.04694652E-02-1.59557089E-16 0.00000000E+00 + 1.20896304E-08 0.00000000E+00-6.27741751E-11-9.98426591E-04 1.39711211E-08 + 5.12248152E-06-7.31822643E-11 3.24219056E-03 0.00000000E+00 4.50437997E-04 + 0.00000000E+00 3.38772847E-04-6.28018266E-19 5.18836571E-05-6.00996193E-20 + 3.79521021E+00 0.00000000E+00 4.23253149E-01 0.00000000E+00 2.43819302E-01 +-1.27254241E-15 3.04856147E-02-1.39606146E-16 1.15712002E-03 1.26673472E-08 + 6.07356017E-06 6.53761040E-11 0.00000000E+00 1.21387422E-08 0.00000000E+00 + 6.30517225E-11 5.18838302E-05 4.96031128E-21 4.50435069E-04 0.00000000E+00 + 3.04855228E-02 1.10406303E-16 4.24250527E-01 0.00000000E+00 1.21191772E-03 + 1.23372684E-08-6.23168798E-06-6.44224616E-11 0.00000000E+00 1.21279096E-08 + 0.00000000E+00-6.30222011E-11 5.05620373E-04 5.32131861E-19 7.48181387E-05 + 1.74434762E-19 3.96544202E-03 0.00000000E+00 5.40940354E-04 0.00000000E+00 + 2.43962000E-01 5.24770833E-16 3.05052329E-02 3.59871873E-17 3.10426787E+00 + 0.00000000E+00 3.53658182E-01 0.00000000E+00 5.74549672E-02 0.00000000E+00 + 3.56150735E-04 0.00000000E+00-4.29934992E-04 1.79579035E-18-2.68493262E-06 + 1.13072021E-20 0.00000000E+00 6.06571712E-10-5.69563318E-05 6.28123444E-10 + 0.00000000E+00 6.06571712E-10-5.69563318E-05 6.28123444E-10 2.99487918E-01 + 0.00000000E+00-6.94632345E-05 0.00000000E+00-2.44378230E-03 9.86575575E-18 + 9.80058599E-08-3.07675707E-21 0.00000000E+00-1.20896304E-08 0.00000000E+00 +-1.33332525E-08 9.98426591E-04-1.39711211E-08 1.18564148E-03-1.45765685E-08 + 0.00000000E+00-1.20896304E-08 0.00000000E+00-1.33332525E-08 9.98426591E-04 +-1.39711211E-08 1.18564148E-03-1.45765685E-08 4.70686692E-02 0.00000000E+00 +-2.96310163E-04 0.00000000E+00-4.15388238E-04 1.42338342E-18 2.60096239E-06 +-9.04409808E-21 0.00000000E+00-1.21387422E-08 0.00000000E+00 6.07746368E-10 + 1.15712002E-03-1.26673472E-08-5.08524956E-05 6.77085146E-10 0.00000000E+00 +-1.21387422E-08 0.00000000E+00 6.07746368E-10 1.15712002E-03-1.26673472E-08 +-5.08524956E-05 6.77085146E-10-4.01296596E-05-8.00484630E-10 3.97271943E-08 +-4.05139921E-13 0.00000000E+00-6.01925375E-10 0.00000000E+00 1.09231881E-14 +-2.12476284E-05-3.55546692E-20-2.02639974E-04 0.00000000E+00-1.52387700E-02 +-7.47908089E-17-2.38044252E-01 0.00000000E+00 1.18564148E-03 1.45765685E-08 + 7.92514849E-08-6.59124682E-13 0.00000000E+00 1.33332525E-08 0.00000000E+00 + 4.10887169E-14 5.18836571E-05 6.00996193E-20 2.09019870E-04 1.98396506E-19 + 4.50437997E-04 0.00000000E+00 1.80181383E-03 0.00000000E+00 3.04856147E-02 + 1.39606146E-16 1.21943547E-01 4.79969868E-16 4.23253149E-01 0.00000000E+00 + 1.70753344E+00 0.00000000E+00-6.75962579E-05-5.76205544E-10 3.95319535E-08 +-2.38410603E-13 0.00000000E+00-6.04469862E-10 0.00000000E+00-7.38034003E-15 + 5.18838302E-05 4.96031128E-21-3.16754922E-05-4.48487683E-20 4.50435069E-04 + 0.00000000E+00-2.47843856E-04 0.00000000E+00 3.04855228E-02 1.10406303E-16 +-1.52476889E-02-3.65983727E-17 4.24250527E-01 0.00000000E+00-1.94477177E-01 + 0.00000000E+00 0.00000000E+00-6.01925375E-10 0.00000000E+00 1.09231881E-14 + 4.01296596E-05-8.00484630E-10-3.97271943E-08-4.05139921E-13-2.02639974E-04 + 0.00000000E+00-2.12476284E-05 3.55546692E-20-2.38044252E-01 0.00000000E+00 +-1.52387700E-02 7.47908089E-17 0.00000000E+00 1.33332525E-08 0.00000000E+00 + 4.10887169E-14-1.18564148E-03 1.45765685E-08-7.92514849E-08-6.59124682E-13 + 4.50437997E-04 0.00000000E+00 1.80181383E-03 0.00000000E+00 5.18836571E-05 +-6.00996193E-20 2.09019870E-04-1.98396506E-19 4.23253149E-01 0.00000000E+00 + 1.70753344E+00 0.00000000E+00 3.04856147E-02-1.39606146E-16 1.21943547E-01 +-4.79969868E-16 0.00000000E+00-6.04469862E-10 0.00000000E+00-7.38034003E-15 + 6.75962579E-05-5.76205544E-10-3.95319535E-08-2.38410603E-13 4.50435069E-04 + 0.00000000E+00-2.47843856E-04 0.00000000E+00 5.18838302E-05-4.96031128E-21 +-3.16754922E-05 4.48487683E-20 4.24250527E-01 0.00000000E+00-1.94477177E-01 + 0.00000000E+00 3.04855228E-02-1.10406303E-16-1.52476889E-02 3.65983727E-17 +-4.01296596E-05-8.00484630E-10 3.97271943E-08-4.05139921E-13 0.00000000E+00 +-6.01925375E-10 0.00000000E+00 1.09231881E-14-2.12476284E-05-3.55546692E-20 +-2.02639974E-04 0.00000000E+00-2.12476284E-05-3.55546692E-20-2.02639974E-04 + 0.00000000E+00 1.18564148E-03 1.45765685E-08 7.92514849E-08-6.59124682E-13 + 0.00000000E+00 1.33332525E-08 0.00000000E+00 4.10887169E-14 5.18836571E-05 + 6.00996193E-20 2.09019870E-04 1.98396506E-19 4.50437997E-04 0.00000000E+00 + 1.80181383E-03 0.00000000E+00 5.18836571E-05 6.00996193E-20 2.09019870E-04 + 1.98396506E-19 4.50437997E-04 0.00000000E+00 1.80181383E-03 0.00000000E+00 +-6.75962579E-05-5.76205544E-10 3.95319535E-08-2.38410603E-13 0.00000000E+00 +-6.04469862E-10 0.00000000E+00-7.38034003E-15 5.18838302E-05 4.96031128E-21 +-3.16754922E-05-4.48487683E-20 4.50435069E-04 0.00000000E+00-2.47843856E-04 + 0.00000000E+00 5.18838302E-05 4.96031128E-21-3.16754922E-05-4.48487683E-20 + 4.50435069E-04 0.00000000E+00-2.47843856E-04 0.00000000E+00 0.00000000E+00 +-6.01925375E-10 0.00000000E+00 1.09231881E-14 4.01296596E-05-8.00484630E-10 +-3.97271943E-08-4.05139921E-13-2.02639974E-04 0.00000000E+00-2.12476284E-05 + 3.55546692E-20-2.02639974E-04 0.00000000E+00-2.12476284E-05 3.55546692E-20 + 0.00000000E+00 1.33332525E-08 0.00000000E+00 4.10887169E-14-1.18564148E-03 + 1.45765685E-08-7.92514849E-08-6.59124682E-13 4.50437997E-04 0.00000000E+00 + 1.80181383E-03 0.00000000E+00 5.18836571E-05-6.00996193E-20 2.09019870E-04 +-1.98396506E-19 4.50437997E-04 0.00000000E+00 1.80181383E-03 0.00000000E+00 + 5.18836571E-05-6.00996193E-20 2.09019870E-04-1.98396506E-19 0.00000000E+00 +-6.04469862E-10 0.00000000E+00-7.38034003E-15 6.75962579E-05-5.76205544E-10 +-3.95319535E-08-2.38410603E-13 4.50435069E-04 0.00000000E+00-2.47843856E-04 + 0.00000000E+00 5.18838302E-05-4.96031128E-21-3.16754922E-05 4.48487683E-20 + 4.50435069E-04 0.00000000E+00-2.47843856E-04 0.00000000E+00 5.18838302E-05 +-4.96031128E-21-3.16754922E-05 4.48487683E-20 2.69121152E-06 1.11589027E-20 + 1.61105167E-08 6.73945958E-23-3.62254380E-04 0.00000000E+00-2.15252822E-06 + 0.00000000E+00-3.97271943E-08 4.05139921E-13 0.00000000E+00-1.09231881E-14 +-3.97271943E-08 4.05139921E-13 0.00000000E+00-1.09231881E-14 9.80058599E-08 + 3.07675707E-21-4.22516598E-08-1.66457424E-22-6.94632345E-05 0.00000000E+00 + 5.19686000E-06 0.00000000E+00 5.12248152E-06 7.31822643E-11-7.92514849E-08 + 6.59124682E-13 0.00000000E+00 6.27741751E-11 0.00000000E+00-4.10887169E-14 + 5.12248152E-06 7.31822643E-11-7.92514849E-08 6.59124682E-13 0.00000000E+00 + 6.27741751E-11 0.00000000E+00-4.10887169E-14-2.59326559E-06-8.75083466E-21 + 1.55653273E-08 5.32998166E-23 2.92236183E-04 0.00000000E+00-1.76350734E-06 + 0.00000000E+00-6.07356017E-06-6.53761040E-11-3.95319535E-08 2.38410603E-13 + 0.00000000E+00-6.30517225E-11 0.00000000E+00 7.38034003E-15-6.07356017E-06 +-6.53761040E-11-3.95319535E-08 2.38410603E-13 0.00000000E+00-6.30517225E-11 + 0.00000000E+00 7.38034003E-15-4.29934992E-04-1.79579035E-18-2.68493262E-06 +-1.13072021E-20 5.74549672E-02 0.00000000E+00 3.56150735E-04 0.00000000E+00 + 5.69563318E-05 6.28123444E-10 0.00000000E+00 6.06571712E-10 5.69563318E-05 + 6.28123444E-10 0.00000000E+00 6.06571712E-10-2.44378230E-03-9.86575575E-18 + 9.80058599E-08 3.07675707E-21 2.99487918E-01 0.00000000E+00-6.94632345E-05 + 0.00000000E+00-9.98426591E-04-1.39711211E-08-1.18564148E-03-1.45765685E-08 + 0.00000000E+00-1.20896304E-08 0.00000000E+00-1.33332525E-08-9.98426591E-04 +-1.39711211E-08-1.18564148E-03-1.45765685E-08 0.00000000E+00-1.20896304E-08 + 0.00000000E+00-1.33332525E-08-4.15388238E-04-1.42338342E-18 2.60096239E-06 + 9.04409808E-21 4.70686692E-02 0.00000000E+00-2.96310163E-04 0.00000000E+00 +-1.15712002E-03-1.26673472E-08 5.08524956E-05 6.77085146E-10 0.00000000E+00 +-1.21387422E-08 0.00000000E+00 6.07746368E-10-1.15712002E-03-1.26673472E-08 + 5.08524956E-05 6.77085146E-10 0.00000000E+00-1.21387422E-08 0.00000000E+00 + 6.07746368E-10-3.62254380E-04 0.00000000E+00-2.15252822E-06 0.00000000E+00 + 2.69121152E-06-1.11589027E-20 1.61105167E-08-6.73945958E-23 0.00000000E+00 +-1.09231881E-14 3.97271943E-08 4.05139921E-13 0.00000000E+00-1.09231881E-14 + 3.97271943E-08 4.05139921E-13-6.94632345E-05 0.00000000E+00 5.19686000E-06 + 0.00000000E+00 9.80058599E-08-3.07675707E-21-4.22516598E-08 1.66457424E-22 + 0.00000000E+00 6.27741751E-11 0.00000000E+00-4.10887169E-14-5.12248152E-06 + 7.31822643E-11 7.92514849E-08 6.59124682E-13 0.00000000E+00 6.27741751E-11 + 0.00000000E+00-4.10887169E-14-5.12248152E-06 7.31822643E-11 7.92514849E-08 + 6.59124682E-13 2.92236183E-04 0.00000000E+00-1.76350734E-06 0.00000000E+00 +-2.59326559E-06 8.75083466E-21 1.55653273E-08-5.32998166E-23 0.00000000E+00 +-6.30517225E-11 0.00000000E+00 7.38034003E-15 6.07356017E-06-6.53761040E-11 + 3.95319535E-08 2.38410603E-13 0.00000000E+00-6.30517225E-11 0.00000000E+00 + 7.38034003E-15 6.07356017E-06-6.53761040E-11 3.95319535E-08 2.38410603E-13 + 0.00000000E+00 1.21387422E-08 0.00000000E+00 6.30517225E-11-1.15712002E-03 + 1.26673472E-08-6.07356017E-06 6.53761040E-11 4.50435069E-04 0.00000000E+00 + 5.18838302E-05-4.96031128E-21 4.50435069E-04 0.00000000E+00 5.18838302E-05 +-4.96031128E-21 0.00000000E+00 1.21279096E-08 0.00000000E+00-6.30222011E-11 +-1.21191772E-03 1.23372684E-08 6.23168798E-06-6.44224616E-11 3.96544202E-03 + 0.00000000E+00 5.40940354E-04 0.00000000E+00 5.05620373E-04-5.32131861E-19 + 7.48181387E-05-1.74434762E-19 3.96544202E-03 0.00000000E+00 5.40940354E-04 + 0.00000000E+00 5.05620373E-04-5.32131861E-19 7.48181387E-05-1.74434762E-19 + 1.15712002E-03 1.26673472E-08 6.07356017E-06 6.53761040E-11 0.00000000E+00 + 1.21387422E-08 0.00000000E+00 6.30517225E-11 5.18838302E-05 4.96031128E-21 + 4.50435069E-04 0.00000000E+00 5.18838302E-05 4.96031128E-21 4.50435069E-04 + 0.00000000E+00 1.21191772E-03 1.23372684E-08-6.23168798E-06-6.44224616E-11 + 0.00000000E+00 1.21279096E-08 0.00000000E+00-6.30222011E-11 5.05620373E-04 + 5.32131861E-19 7.48181387E-05 1.74434762E-19 3.96544202E-03 0.00000000E+00 + 5.40940354E-04 0.00000000E+00 5.05620373E-04 5.32131861E-19 7.48181387E-05 + 1.74434762E-19 3.96544202E-03 0.00000000E+00 5.40940354E-04 0.00000000E+00 + 0.00000000E+00 1.21387422E-08 0.00000000E+00 6.30517225E-11-1.15712002E-03 + 1.26673472E-08-6.07356017E-06 6.53761040E-11 4.50435069E-04 0.00000000E+00 + 5.18838302E-05-4.96031128E-21 4.24250527E-01 0.00000000E+00 3.04855228E-02 +-1.10406303E-16 0.00000000E+00 1.21279096E-08 0.00000000E+00-6.30222011E-11 +-1.21191772E-03 1.23372684E-08 6.23168798E-06-6.44224616E-11 3.96544202E-03 + 0.00000000E+00 5.40940354E-04 0.00000000E+00 5.05620373E-04-5.32131861E-19 + 7.48181387E-05-1.74434762E-19 3.10426787E+00 0.00000000E+00 3.53658182E-01 + 0.00000000E+00 2.43962000E-01-5.24770833E-16 3.05052329E-02-3.59871873E-17 + 1.36973968E-03 1.17315123E-08 7.17751334E-06 6.07640482E-11 0.00000000E+00 + 1.19752841E-08 0.00000000E+00 6.21268488E-11 7.48185997E-05 2.80812926E-19 + 5.40936972E-04 0.00000000E+00 3.05051474E-02 5.49754151E-17 3.54135028E-01 + 0.00000000E+00 1.42416081E-03 1.15929694E-08-7.33455437E-06-6.03674136E-11 + 0.00000000E+00 1.19143481E-08 0.00000000E+00-6.19489137E-11 7.05702772E-04 + 2.60561055E-18 1.01903190E-04 3.01009373E-19 4.69035571E-03 0.00000000E+00 + 6.31669660E-04 0.00000000E+00 2.44133215E-01 5.88104593E-16 3.05284070E-02 + 8.77936662E-17 2.62673415E+00 0.00000000E+00 3.03662001E-01 0.00000000E+00 + 4.70686692E-02 0.00000000E+00 2.92236183E-04 0.00000000E+00-4.15388238E-04 + 1.42338342E-18-2.59326559E-06 8.75083466E-21 0.00000000E+00 6.04469862E-10 +-6.75962579E-05 5.76205544E-10 0.00000000E+00 6.04469862E-10-6.75962579E-05 + 5.76205544E-10 2.49829652E-01 0.00000000E+00-4.80268846E-05 0.00000000E+00 +-2.35133601E-03 7.06606508E-18 1.17447073E-07-1.80710822E-21 0.00000000E+00 +-1.21279096E-08 0.00000000E+00-1.32753821E-08 1.21191772E-03-1.23372684E-08 + 1.42003874E-03-1.31710549E-08 0.00000000E+00-1.21279096E-08 0.00000000E+00 +-1.32753821E-08 1.21191772E-03-1.23372684E-08 1.42003874E-03-1.31710549E-08 + 3.99024901E-02 0.00000000E+00-2.50926479E-04 0.00000000E+00-3.97940900E-04 + 1.13270771E-18 2.49257327E-06-7.10148688E-21 0.00000000E+00-1.19752841E-08 + 0.00000000E+00 6.06772804E-10 1.36973968E-03-1.17315123E-08-6.15305081E-05 + 6.04620057E-10 0.00000000E+00-1.19752841E-08 0.00000000E+00 6.06772804E-10 + 1.36973968E-03-1.17315123E-08-6.15305081E-05 6.04620057E-10-5.08524956E-05 +-6.77085146E-10 3.95319535E-08-2.38410603E-13 0.00000000E+00-6.07746368E-10 + 0.00000000E+00-7.38034003E-15-3.16754922E-05-4.48487683E-20-2.47843856E-04 + 0.00000000E+00-1.52476889E-02-3.65983727E-17-1.94477177E-01 0.00000000E+00 + 1.42003874E-03 1.31710549E-08 7.88394604E-08-2.74806254E-13 0.00000000E+00 + 1.32753821E-08 0.00000000E+00-9.58296347E-14 7.48181387E-05 1.74434762E-19 + 3.00755851E-04 8.58263839E-19 5.40940354E-04 0.00000000E+00 2.16383601E-03 + 0.00000000E+00 3.05052329E-02 3.59871873E-17 1.22022028E-01 2.21230207E-16 + 3.53658182E-01 0.00000000E+00 1.42277135E+00 0.00000000E+00-7.81592117E-05 +-5.62348143E-10 3.92602581E-08-9.91586589E-14 0.00000000E+00-5.88113106E-10 + 0.00000000E+00-4.44837599E-14 7.48185997E-05 2.80812926E-19-4.41804474E-05 +-1.45455575E-19 5.40936972E-04 0.00000000E+00-2.93151658E-04 0.00000000E+00 + 3.05051474E-02 5.49754151E-17-1.52583886E-02-3.56922703E-17 3.54135028E-01 + 0.00000000E+00-1.64449257E-01 0.00000000E+00 0.00000000E+00-6.07746368E-10 + 0.00000000E+00-7.38034003E-15 5.08524956E-05-6.77085146E-10-3.95319535E-08 +-2.38410603E-13-2.47843856E-04 0.00000000E+00-3.16754922E-05 4.48487683E-20 +-1.94477177E-01 0.00000000E+00-1.52476889E-02 3.65983727E-17 0.00000000E+00 + 1.32753821E-08 0.00000000E+00-9.58296347E-14-1.42003874E-03 1.31710549E-08 +-7.88394604E-08-2.74806254E-13 5.40940354E-04 0.00000000E+00 2.16383601E-03 + 0.00000000E+00 7.48181387E-05-1.74434762E-19 3.00755851E-04-8.58263839E-19 + 3.53658182E-01 0.00000000E+00 1.42277135E+00 0.00000000E+00 3.05052329E-02 +-3.59871873E-17 1.22022028E-01-2.21230207E-16 0.00000000E+00-5.88113106E-10 + 0.00000000E+00-4.44837599E-14 7.81592117E-05-5.62348143E-10-3.92602581E-08 +-9.91586589E-14 5.40936972E-04 0.00000000E+00-2.93151658E-04 0.00000000E+00 + 7.48185997E-05-2.80812926E-19-4.41804474E-05 1.45455575E-19 3.54135028E-01 + 0.00000000E+00-1.64449257E-01 0.00000000E+00 3.05051474E-02-5.49754151E-17 +-1.52583886E-02 3.56922703E-17-5.08524956E-05-6.77085146E-10 3.95319535E-08 +-2.38410603E-13 0.00000000E+00-6.07746368E-10 0.00000000E+00-7.38034003E-15 +-3.16754922E-05-4.48487683E-20-2.47843856E-04 0.00000000E+00-3.16754922E-05 +-4.48487683E-20-2.47843856E-04 0.00000000E+00 1.42003874E-03 1.31710549E-08 + 7.88394604E-08-2.74806254E-13 0.00000000E+00 1.32753821E-08 0.00000000E+00 +-9.58296347E-14 7.48181387E-05 1.74434762E-19 3.00755851E-04 8.58263839E-19 + 5.40940354E-04 0.00000000E+00 2.16383601E-03 0.00000000E+00 7.48181387E-05 + 1.74434762E-19 3.00755851E-04 8.58263839E-19 5.40940354E-04 0.00000000E+00 + 2.16383601E-03 0.00000000E+00-7.81592117E-05-5.62348143E-10 3.92602581E-08 +-9.91586589E-14 0.00000000E+00-5.88113106E-10 0.00000000E+00-4.44837599E-14 + 7.48185997E-05 2.80812926E-19-4.41804474E-05-1.45455575E-19 5.40936972E-04 + 0.00000000E+00-2.93151658E-04 0.00000000E+00 7.48185997E-05 2.80812926E-19 +-4.41804474E-05-1.45455575E-19 5.40936972E-04 0.00000000E+00-2.93151658E-04 + 0.00000000E+00 0.00000000E+00-6.07746368E-10 0.00000000E+00-7.38034003E-15 + 5.08524956E-05-6.77085146E-10-3.95319535E-08-2.38410603E-13-2.47843856E-04 + 0.00000000E+00-3.16754922E-05 4.48487683E-20-2.47843856E-04 0.00000000E+00 +-3.16754922E-05 4.48487683E-20 0.00000000E+00 1.32753821E-08 0.00000000E+00 +-9.58296347E-14-1.42003874E-03 1.31710549E-08-7.88394604E-08-2.74806254E-13 + 5.40940354E-04 0.00000000E+00 2.16383601E-03 0.00000000E+00 7.48181387E-05 +-1.74434762E-19 3.00755851E-04-8.58263839E-19 5.40940354E-04 0.00000000E+00 + 2.16383601E-03 0.00000000E+00 7.48181387E-05-1.74434762E-19 3.00755851E-04 +-8.58263839E-19 0.00000000E+00-5.88113106E-10 0.00000000E+00-4.44837599E-14 + 7.81592117E-05-5.62348143E-10-3.92602581E-08-9.91586589E-14 5.40936972E-04 + 0.00000000E+00-2.93151658E-04 0.00000000E+00 7.48185997E-05-2.80812926E-19 +-4.41804474E-05 1.45455575E-19 5.40936972E-04 0.00000000E+00-2.93151658E-04 + 0.00000000E+00 7.48185997E-05-2.80812926E-19-4.41804474E-05 1.45455575E-19 + 2.60096239E-06 9.04409808E-21 1.55653273E-08 5.32998166E-23-2.96310163E-04 + 0.00000000E+00-1.76350734E-06 0.00000000E+00-3.95319535E-08 2.38410603E-13 + 0.00000000E+00 7.38034003E-15-3.95319535E-08 2.38410603E-13 0.00000000E+00 + 7.38034003E-15 1.17447073E-07 1.80710822E-21-4.06527608E-08-1.24505897E-22 +-4.80268846E-05 0.00000000E+00 4.33066000E-06 0.00000000E+00 6.23168798E-06 + 6.44224616E-11-7.88394604E-08 2.74806254E-13 0.00000000E+00 6.30222011E-11 + 0.00000000E+00 9.58296347E-14 6.23168798E-06 6.44224616E-11-7.88394604E-08 + 2.74806254E-13 0.00000000E+00 6.30222011E-11 0.00000000E+00 9.58296347E-14 +-2.48347159E-06-7.06102302E-21 1.49114769E-08 4.24305898E-23 2.48017929E-04 + 0.00000000E+00-1.49505803E-06 0.00000000E+00-7.17751334E-06-6.07640482E-11 +-3.92602581E-08 9.91586589E-14 0.00000000E+00-6.21268488E-11 0.00000000E+00 + 4.44837599E-14-7.17751334E-06-6.07640482E-11-3.92602581E-08 9.91586589E-14 + 0.00000000E+00-6.21268488E-11 0.00000000E+00 4.44837599E-14-4.15388238E-04 +-1.42338342E-18-2.59326559E-06-8.75083466E-21 4.70686692E-02 0.00000000E+00 + 2.92236183E-04 0.00000000E+00 6.75962579E-05 5.76205544E-10 0.00000000E+00 + 6.04469862E-10 6.75962579E-05 5.76205544E-10 0.00000000E+00 6.04469862E-10 +-2.35133601E-03-7.06606508E-18 1.17447073E-07 1.80710822E-21 2.49829652E-01 + 0.00000000E+00-4.80268846E-05 0.00000000E+00-1.21191772E-03-1.23372684E-08 +-1.42003874E-03-1.31710549E-08 0.00000000E+00-1.21279096E-08 0.00000000E+00 +-1.32753821E-08-1.21191772E-03-1.23372684E-08-1.42003874E-03-1.31710549E-08 + 0.00000000E+00-1.21279096E-08 0.00000000E+00-1.32753821E-08-3.97940900E-04 +-1.13270771E-18 2.49257327E-06 7.10148688E-21 3.99024901E-02 0.00000000E+00 +-2.50926479E-04 0.00000000E+00-1.36973968E-03-1.17315123E-08 6.15305081E-05 + 6.04620057E-10 0.00000000E+00-1.19752841E-08 0.00000000E+00 6.06772804E-10 +-1.36973968E-03-1.17315123E-08 6.15305081E-05 6.04620057E-10 0.00000000E+00 +-1.19752841E-08 0.00000000E+00 6.06772804E-10-2.96310163E-04 0.00000000E+00 +-1.76350734E-06 0.00000000E+00 2.60096239E-06-9.04409808E-21 1.55653273E-08 +-5.32998166E-23 0.00000000E+00 7.38034003E-15 3.95319535E-08 2.38410603E-13 + 0.00000000E+00 7.38034003E-15 3.95319535E-08 2.38410603E-13-4.80268846E-05 + 0.00000000E+00 4.33066000E-06 0.00000000E+00 1.17447073E-07-1.80710822E-21 +-4.06527608E-08 1.24505897E-22 0.00000000E+00 6.30222011E-11 0.00000000E+00 + 9.58296347E-14-6.23168798E-06 6.44224616E-11 7.88394604E-08 2.74806254E-13 + 0.00000000E+00 6.30222011E-11 0.00000000E+00 9.58296347E-14-6.23168798E-06 + 6.44224616E-11 7.88394604E-08 2.74806254E-13 2.48017929E-04 0.00000000E+00 +-1.49505803E-06 0.00000000E+00-2.48347159E-06 7.06102302E-21 1.49114769E-08 +-4.24305898E-23 0.00000000E+00-6.21268488E-11 0.00000000E+00 4.44837599E-14 + 7.17751334E-06-6.07640482E-11 3.92602581E-08 9.91586589E-14 0.00000000E+00 +-6.21268488E-11 0.00000000E+00 4.44837599E-14 7.17751334E-06-6.07640482E-11 + 3.92602581E-08 9.91586589E-14 0.00000000E+00 1.19752841E-08 0.00000000E+00 + 6.21268488E-11-1.36973968E-03 1.17315123E-08-7.17751334E-06 6.07640482E-11 + 5.40936972E-04 0.00000000E+00 7.48185997E-05-2.80812926E-19 5.40936972E-04 + 0.00000000E+00 7.48185997E-05-2.80812926E-19 0.00000000E+00 1.19143481E-08 + 0.00000000E+00-6.19489137E-11-1.42416081E-03 1.15929694E-08 7.33455437E-06 +-6.03674136E-11 4.69035571E-03 0.00000000E+00 6.31669660E-04 0.00000000E+00 + 7.05702772E-04-2.60561055E-18 1.01903190E-04-3.01009373E-19 4.69035571E-03 + 0.00000000E+00 6.31669660E-04 0.00000000E+00 7.05702772E-04-2.60561055E-18 + 1.01903190E-04-3.01009373E-19 1.36973968E-03 1.17315123E-08 7.17751334E-06 + 6.07640482E-11 0.00000000E+00 1.19752841E-08 0.00000000E+00 6.21268488E-11 + 7.48185997E-05 2.80812926E-19 5.40936972E-04 0.00000000E+00 7.48185997E-05 + 2.80812926E-19 5.40936972E-04 0.00000000E+00 1.42416081E-03 1.15929694E-08 +-7.33455437E-06-6.03674136E-11 0.00000000E+00 1.19143481E-08 0.00000000E+00 +-6.19489137E-11 7.05702772E-04 2.60561055E-18 1.01903190E-04 3.01009373E-19 + 4.69035571E-03 0.00000000E+00 6.31669660E-04 0.00000000E+00 7.05702772E-04 + 2.60561055E-18 1.01903190E-04 3.01009373E-19 4.69035571E-03 0.00000000E+00 + 6.31669660E-04 0.00000000E+00 0.00000000E+00 1.19752841E-08 0.00000000E+00 + 6.21268488E-11-1.36973968E-03 1.17315123E-08-7.17751334E-06 6.07640482E-11 + 5.40936972E-04 0.00000000E+00 7.48185997E-05-2.80812926E-19 3.54135028E-01 + 0.00000000E+00 3.05051474E-02-5.49754151E-17 0.00000000E+00 1.19143481E-08 + 0.00000000E+00-6.19489137E-11-1.42416081E-03 1.15929694E-08 7.33455437E-06 +-6.03674136E-11 4.69035571E-03 0.00000000E+00 6.31669660E-04 0.00000000E+00 + 7.05702772E-04-2.60561055E-18 1.01903190E-04-3.01009373E-19 2.62673415E+00 + 0.00000000E+00 3.03662001E-01 0.00000000E+00 2.44133215E-01-5.88104593E-16 + 3.05284070E-02-8.77936662E-17 1.58073074E-03 1.12553575E-08 8.27292217E-06 + 5.83448714E-11 0.00000000E+00 1.18055170E-08 0.00000000E+00 6.12924984E-11 + 1.01903238E-04 1.60600024E-19 6.31666092E-04 0.00000000E+00 3.05283107E-02 + 7.86553336E-17 3.03917772E-01 0.00000000E+00 1.63475148E-03 1.11597344E-08 +-8.42880689E-06-5.80689374E-11 0.00000000E+00 1.17853813E-08 0.00000000E+00 +-6.12347958E-11 9.38944655E-04 1.55085154E-18 1.33128469E-04 3.07918278E-19 + 5.41723804E-03 0.00000000E+00 7.22663767E-04 0.00000000E+00 2.44332697E-01 + 7.09322568E-16 3.05551204E-02 1.02729575E-16 2.27696373E+00 0.00000000E+00 + 2.66047137E-01 0.00000000E+00 3.99024901E-02 0.00000000E+00 2.48017929E-04 + 0.00000000E+00-3.97940900E-04 1.13270771E-18-2.48347159E-06 7.06102302E-21 + 0.00000000E+00 5.88113106E-10-7.81592117E-05 5.62348143E-10 0.00000000E+00 + 5.88113106E-10-7.81592117E-05 5.62348143E-10 2.14523457E-01 0.00000000E+00 +-3.51509107E-05 0.00000000E+00-2.24197947E-03 6.52629251E-18 1.37473932E-07 + 4.44225708E-22 0.00000000E+00-1.19143481E-08 0.00000000E+00-1.30312694E-08 + 1.42416081E-03-1.15929694E-08 1.65282657E-03-1.25530732E-08 0.00000000E+00 +-1.19143481E-08 0.00000000E+00-1.30312694E-08 1.42416081E-03-1.15929694E-08 + 1.65282657E-03-1.25530732E-08 3.46641500E-02 0.00000000E+00-2.17811692E-04 + 0.00000000E+00-3.77532956E-04 1.22100633E-18 2.36567456E-06-7.54053726E-21 + 0.00000000E+00-1.18055170E-08 0.00000000E+00 5.92978458E-10 1.58073074E-03 +-1.12553575E-08-7.21321246E-05 5.75239178E-10 0.00000000E+00-1.18055170E-08 + 0.00000000E+00 5.92978458E-10 1.58073074E-03-1.12553575E-08-7.21321246E-05 + 5.75239178E-10-6.15305081E-05-6.04620057E-10 3.92602581E-08-9.91586589E-14 + 0.00000000E+00-6.06772804E-10 0.00000000E+00-4.44837599E-14-4.41804474E-05 +-1.45455575E-19-2.93151658E-04 0.00000000E+00-1.52583886E-02-3.56922703E-17 +-1.64449257E-01 0.00000000E+00 1.65282657E-03 1.25530732E-08 7.81608896E-08 +-1.69681079E-13 0.00000000E+00 1.30312694E-08 0.00000000E+00-5.04169718E-14 + 1.01903190E-04 3.01009373E-19 4.09091801E-04 9.67035929E-19 6.31669660E-04 + 0.00000000E+00 2.52676630E-03 0.00000000E+00 3.05284070E-02 8.77936662E-17 + 1.22114703E-01 3.29349503E-16 3.03662001E-01 0.00000000E+00 1.21966020E+00 + 0.00000000E+00-8.86384800E-05-5.46020983E-10 3.89711804E-08-6.89835202E-14 + 0.00000000E+00-5.86833604E-10 0.00000000E+00-1.44256412E-14 1.01903238E-04 + 1.60600024E-19-5.87579268E-05-1.17129576E-19 6.31666092E-04 0.00000000E+00 +-3.38582465E-04 0.00000000E+00 3.05283107E-02 7.86553336E-17-1.52708578E-02 +-4.53462273E-17 3.03917772E-01 0.00000000E+00-1.42491227E-01 0.00000000E+00 + 0.00000000E+00-6.06772804E-10 0.00000000E+00-4.44837599E-14 6.15305081E-05 +-6.04620057E-10-3.92602581E-08-9.91586589E-14-2.93151658E-04 0.00000000E+00 +-4.41804474E-05 1.45455575E-19-1.64449257E-01 0.00000000E+00-1.52583886E-02 + 3.56922703E-17 0.00000000E+00 1.30312694E-08 0.00000000E+00-5.04169718E-14 +-1.65282657E-03 1.25530732E-08-7.81608896E-08-1.69681079E-13 6.31669660E-04 + 0.00000000E+00 2.52676630E-03 0.00000000E+00 1.01903190E-04-3.01009373E-19 + 4.09091801E-04-9.67035929E-19 3.03662001E-01 0.00000000E+00 1.21966020E+00 + 0.00000000E+00 3.05284070E-02-8.77936662E-17 1.22114703E-01-3.29349503E-16 + 0.00000000E+00-5.86833604E-10 0.00000000E+00-1.44256412E-14 8.86384800E-05 +-5.46020983E-10-3.89711804E-08-6.89835202E-14 6.31666092E-04 0.00000000E+00 +-3.38582465E-04 0.00000000E+00 1.01903238E-04-1.60600024E-19-5.87579268E-05 + 1.17129576E-19 3.03917772E-01 0.00000000E+00-1.42491227E-01 0.00000000E+00 + 3.05283107E-02-7.86553336E-17-1.52708578E-02 4.53462273E-17-6.15305081E-05 +-6.04620057E-10 3.92602581E-08-9.91586589E-14 0.00000000E+00-6.06772804E-10 + 0.00000000E+00-4.44837599E-14-4.41804474E-05-1.45455575E-19-2.93151658E-04 + 0.00000000E+00-4.41804474E-05-1.45455575E-19-2.93151658E-04 0.00000000E+00 + 1.65282657E-03 1.25530732E-08 7.81608896E-08-1.69681079E-13 0.00000000E+00 + 1.30312694E-08 0.00000000E+00-5.04169718E-14 1.01903190E-04 3.01009373E-19 + 4.09091801E-04 9.67035929E-19 6.31669660E-04 0.00000000E+00 2.52676630E-03 + 0.00000000E+00 1.01903190E-04 3.01009373E-19 4.09091801E-04 9.67035929E-19 + 6.31669660E-04 0.00000000E+00 2.52676630E-03 0.00000000E+00-8.86384800E-05 +-5.46020983E-10 3.89711804E-08-6.89835202E-14 0.00000000E+00-5.86833604E-10 + 0.00000000E+00-1.44256412E-14 1.01903238E-04 1.60600024E-19-5.87579268E-05 +-1.17129576E-19 6.31666092E-04 0.00000000E+00-3.38582465E-04 0.00000000E+00 + 1.01903238E-04 1.60600024E-19-5.87579268E-05-1.17129576E-19 6.31666092E-04 + 0.00000000E+00-3.38582465E-04 0.00000000E+00 0.00000000E+00-6.06772804E-10 + 0.00000000E+00-4.44837599E-14 6.15305081E-05-6.04620057E-10-3.92602581E-08 +-9.91586589E-14-2.93151658E-04 0.00000000E+00-4.41804474E-05 1.45455575E-19 +-2.93151658E-04 0.00000000E+00-4.41804474E-05 1.45455575E-19 0.00000000E+00 + 1.30312694E-08 0.00000000E+00-5.04169718E-14-1.65282657E-03 1.25530732E-08 +-7.81608896E-08-1.69681079E-13 6.31669660E-04 0.00000000E+00 2.52676630E-03 + 0.00000000E+00 1.01903190E-04-3.01009373E-19 4.09091801E-04-9.67035929E-19 + 6.31669660E-04 0.00000000E+00 2.52676630E-03 0.00000000E+00 1.01903190E-04 +-3.01009373E-19 4.09091801E-04-9.67035929E-19 0.00000000E+00-5.86833604E-10 + 0.00000000E+00-1.44256412E-14 8.86384800E-05-5.46020983E-10-3.89711804E-08 +-6.89835202E-14 6.31666092E-04 0.00000000E+00-3.38582465E-04 0.00000000E+00 + 1.01903238E-04-1.60600024E-19-5.87579268E-05 1.17129576E-19 6.31666092E-04 + 0.00000000E+00-3.38582465E-04 0.00000000E+00 1.01903238E-04-1.60600024E-19 +-5.87579268E-05 1.17129576E-19 2.49257327E-06 7.10148688E-21 1.49114769E-08 + 4.24305898E-23-2.50926479E-04 0.00000000E+00-1.49505803E-06 0.00000000E+00 +-3.92602581E-08 9.91586589E-14 0.00000000E+00 4.44837599E-14-3.92602581E-08 + 9.91586589E-14 0.00000000E+00 4.44837599E-14 1.37473932E-07-4.44225708E-22 +-3.87612569E-08-1.14812891E-22-3.51509107E-05 0.00000000E+00 3.71631743E-06 + 0.00000000E+00 7.33455437E-06 6.03674136E-11-7.81608896E-08 1.69681079E-13 + 0.00000000E+00 6.19489137E-11 0.00000000E+00 5.04169718E-14 7.33455437E-06 + 6.03674136E-11-7.81608896E-08 1.69681079E-13 0.00000000E+00 6.19489137E-11 + 0.00000000E+00 5.04169718E-14-2.35516542E-06-7.72232491E-21 1.41466737E-08 + 4.57026718E-23 2.15633673E-04 0.00000000E+00-1.29880983E-06 0.00000000E+00 +-8.27292217E-06-5.83448714E-11-3.89711804E-08 6.89835202E-14 0.00000000E+00 +-6.12924984E-11 0.00000000E+00 1.44256412E-14-8.27292217E-06-5.83448714E-11 +-3.89711804E-08 6.89835202E-14 0.00000000E+00-6.12924984E-11 0.00000000E+00 + 1.44256412E-14-3.97940900E-04-1.13270771E-18-2.48347159E-06-7.06102302E-21 + 3.99024901E-02 0.00000000E+00 2.48017929E-04 0.00000000E+00 7.81592117E-05 + 5.62348143E-10 0.00000000E+00 5.88113106E-10 7.81592117E-05 5.62348143E-10 + 0.00000000E+00 5.88113106E-10-2.24197947E-03-6.52629251E-18 1.37473932E-07 +-4.44225708E-22 2.14523457E-01 0.00000000E+00-3.51509107E-05 0.00000000E+00 +-1.42416081E-03-1.15929694E-08-1.65282657E-03-1.25530732E-08 0.00000000E+00 +-1.19143481E-08 0.00000000E+00-1.30312694E-08-1.42416081E-03-1.15929694E-08 +-1.65282657E-03-1.25530732E-08 0.00000000E+00-1.19143481E-08 0.00000000E+00 +-1.30312694E-08-3.77532956E-04-1.22100633E-18 2.36567456E-06 7.54053726E-21 + 3.46641500E-02 0.00000000E+00-2.17811692E-04 0.00000000E+00-1.58073074E-03 +-1.12553575E-08 7.21321246E-05 5.75239178E-10 0.00000000E+00-1.18055170E-08 + 0.00000000E+00 5.92978458E-10-1.58073074E-03-1.12553575E-08 7.21321246E-05 + 5.75239178E-10 0.00000000E+00-1.18055170E-08 0.00000000E+00 5.92978458E-10 +-2.50926479E-04 0.00000000E+00-1.49505803E-06 0.00000000E+00 2.49257327E-06 +-7.10148688E-21 1.49114769E-08-4.24305898E-23 0.00000000E+00 4.44837599E-14 + 3.92602581E-08 9.91586589E-14 0.00000000E+00 4.44837599E-14 3.92602581E-08 + 9.91586589E-14-3.51509107E-05 0.00000000E+00 3.71631743E-06 0.00000000E+00 + 1.37473932E-07 4.44225708E-22-3.87612569E-08 1.14812891E-22 0.00000000E+00 + 6.19489137E-11 0.00000000E+00 5.04169718E-14-7.33455437E-06 6.03674136E-11 + 7.81608896E-08 1.69681079E-13 0.00000000E+00 6.19489137E-11 0.00000000E+00 + 5.04169718E-14-7.33455437E-06 6.03674136E-11 7.81608896E-08 1.69681079E-13 + 2.15633673E-04 0.00000000E+00-1.29880983E-06 0.00000000E+00-2.35516542E-06 + 7.72232491E-21 1.41466737E-08-4.57026718E-23 0.00000000E+00-6.12924984E-11 + 0.00000000E+00 1.44256412E-14 8.27292217E-06-5.83448714E-11 3.89711804E-08 + 6.89835202E-14 0.00000000E+00-6.12924984E-11 0.00000000E+00 1.44256412E-14 + 8.27292217E-06-5.83448714E-11 3.89711804E-08 6.89835202E-14 0.00000000E+00 + 1.18055170E-08 0.00000000E+00 6.12924984E-11-1.58073074E-03 1.12553575E-08 +-8.27292217E-06 5.83448714E-11 6.31666092E-04 0.00000000E+00 1.01903238E-04 +-1.60600024E-19 6.31666092E-04 0.00000000E+00 1.01903238E-04-1.60600024E-19 + 0.00000000E+00 1.17853813E-08 0.00000000E+00-6.12347958E-11-1.63475148E-03 + 1.11597344E-08 8.42880689E-06-5.80689374E-11 5.41723804E-03 0.00000000E+00 + 7.22663767E-04 0.00000000E+00 9.38944655E-04-1.55085154E-18 1.33128469E-04 +-3.07918278E-19 5.41723804E-03 0.00000000E+00 7.22663767E-04 0.00000000E+00 + 9.38944655E-04-1.55085154E-18 1.33128469E-04-3.07918278E-19 1.58073074E-03 + 1.12553575E-08 8.27292217E-06 5.83448714E-11 0.00000000E+00 1.18055170E-08 + 0.00000000E+00 6.12924984E-11 1.01903238E-04 1.60600024E-19 6.31666092E-04 + 0.00000000E+00 1.01903238E-04 1.60600024E-19 6.31666092E-04 0.00000000E+00 + 1.63475148E-03 1.11597344E-08-8.42880689E-06-5.80689374E-11 0.00000000E+00 + 1.17853813E-08 0.00000000E+00-6.12347958E-11 9.38944655E-04 1.55085154E-18 + 1.33128469E-04 3.07918278E-19 5.41723804E-03 0.00000000E+00 7.22663767E-04 + 0.00000000E+00 9.38944655E-04 1.55085154E-18 1.33128469E-04 3.07918278E-19 + 5.41723804E-03 0.00000000E+00 7.22663767E-04 0.00000000E+00 0.00000000E+00 + 1.18055170E-08 0.00000000E+00 6.12924984E-11-1.58073074E-03 1.12553575E-08 +-8.27292217E-06 5.83448714E-11 6.31666092E-04 0.00000000E+00 1.01903238E-04 +-1.60600024E-19 3.03917772E-01 0.00000000E+00 3.05283107E-02-7.86553336E-17 + 0.00000000E+00 1.17853813E-08 0.00000000E+00-6.12347958E-11-1.63475148E-03 + 1.11597344E-08 8.42880689E-06-5.80689374E-11 5.41723804E-03 0.00000000E+00 + 7.22663767E-04 0.00000000E+00 9.38944655E-04-1.55085154E-18 1.33128469E-04 +-3.07918278E-19 2.27696373E+00 0.00000000E+00 2.66047137E-01 0.00000000E+00 + 2.44332697E-01-7.09322568E-16 3.05551204E-02-1.02729575E-16 1.79023118E-03 + 1.09435191E-08 9.36056521E-06 5.67706657E-11 0.00000000E+00 1.17574526E-08 + 0.00000000E+00 6.10672683E-11 1.33128862E-04 4.51573668E-19 7.22659693E-04 + 0.00000000E+00 3.05550389E-02 1.12224164E-16 2.66196436E-01 0.00000000E+00 + 1.84377791E-03 1.08853685E-08-9.51508093E-06-5.66030577E-11 0.00000000E+00 + 1.17579707E-08 0.00000000E+00-6.10688336E-11 1.20526852E-03 4.16981307E-18 + 1.68482688E-04 5.18401609E-19 6.14639173E-03 0.00000000E+00 8.13961418E-04 + 0.00000000E+00 2.44560653E-01 9.26576765E-16 3.05853713E-02 1.13360392E-16 + 2.00975531E+00 0.00000000E+00 2.36739262E-01 0.00000000E+00 3.46641500E-02 + 0.00000000E+00 2.15633673E-04 0.00000000E+00-3.77532956E-04 1.22100633E-18 +-2.35516542E-06 7.72232491E-21 0.00000000E+00 5.86833604E-10-8.86384800E-05 + 5.46020983E-10 0.00000000E+00 5.86833604E-10-8.86384800E-05 5.46020983E-10 + 1.88152888E-01 0.00000000E+00-2.68106938E-05 0.00000000E+00-2.11570344E-03 + 8.60624542E-18 1.56907343E-07 4.16414062E-21 0.00000000E+00-1.17853813E-08 + 0.00000000E+00-1.29416513E-08 1.63475148E-03-1.11597344E-08 1.88390148E-03 +-1.21440386E-08 0.00000000E+00-1.17853813E-08 0.00000000E+00-1.29416513E-08 + 1.63475148E-03-1.11597344E-08 1.88390148E-03-1.21440386E-08 3.06718801E-02 + 0.00000000E+00-1.92608101E-04 0.00000000E+00-3.54223893E-04 1.80628666E-18 + 2.22064604E-06-1.11485358E-20 0.00000000E+00-1.17574526E-08 0.00000000E+00 + 5.87916297E-10 1.79023118E-03-1.09435191E-08-8.26660030E-05 5.54759589E-10 + 0.00000000E+00-1.17574526E-08 0.00000000E+00 5.87916297E-10 1.79023118E-03 +-1.09435191E-08-8.26660030E-05 5.54759589E-10-7.21321246E-05-5.75239178E-10 + 3.89711804E-08-6.89835202E-14 0.00000000E+00-5.92978458E-10 0.00000000E+00 +-1.44256412E-14-5.87579268E-05-1.17129576E-19-3.38582465E-04 0.00000000E+00 +-1.52708578E-02-4.53462273E-17-1.42491227E-01 0.00000000E+00 1.88390148E-03 + 1.21440386E-08 7.76848215E-08-1.05751896E-13 0.00000000E+00 1.29416513E-08 + 0.00000000E+00-1.40298709E-14 1.33128469E-04 3.07918278E-19 5.33989307E-04 + 1.49127065E-18 7.22663767E-04 0.00000000E+00 2.89075565E-03 0.00000000E+00 + 3.05551204E-02 1.02729575E-16 1.22221577E-01 4.21792881E-16 2.66047137E-01 + 0.00000000E+00 1.06749187E+00 0.00000000E+00-9.90275086E-05-5.36995041E-10 + 3.86289303E-08-4.19020202E-14 0.00000000E+00-5.88075960E-10 0.00000000E+00 + 3.91323208E-16 1.33128862E-04 4.51573668E-19-7.54028875E-05-2.42493819E-19 + 7.22659693E-04 0.00000000E+00-3.84155278E-04 0.00000000E+00 3.05550389E-02 + 1.12224164E-16-1.52851025E-02-5.63961389E-17 2.66196436E-01 0.00000000E+00 +-1.25733924E-01 0.00000000E+00 0.00000000E+00-5.92978458E-10 0.00000000E+00 +-1.44256412E-14 7.21321246E-05-5.75239178E-10-3.89711804E-08-6.89835202E-14 +-3.38582465E-04 0.00000000E+00-5.87579268E-05 1.17129576E-19-1.42491227E-01 + 0.00000000E+00-1.52708578E-02 4.53462273E-17 0.00000000E+00 1.29416513E-08 + 0.00000000E+00-1.40298709E-14-1.88390148E-03 1.21440386E-08-7.76848215E-08 +-1.05751896E-13 7.22663767E-04 0.00000000E+00 2.89075565E-03 0.00000000E+00 + 1.33128469E-04-3.07918278E-19 5.33989307E-04-1.49127065E-18 2.66047137E-01 + 0.00000000E+00 1.06749187E+00 0.00000000E+00 3.05551204E-02-1.02729575E-16 + 1.22221577E-01-4.21792881E-16 0.00000000E+00-5.88075960E-10 0.00000000E+00 + 3.91323208E-16 9.90275086E-05-5.36995041E-10-3.86289303E-08-4.19020202E-14 + 7.22659693E-04 0.00000000E+00-3.84155278E-04 0.00000000E+00 1.33128862E-04 +-4.51573668E-19-7.54028875E-05 2.42493819E-19 2.66196436E-01 0.00000000E+00 +-1.25733924E-01 0.00000000E+00 3.05550389E-02-1.12224164E-16-1.52851025E-02 + 5.63961389E-17-7.21321246E-05-5.75239178E-10 3.89711804E-08-6.89835202E-14 + 0.00000000E+00-5.92978458E-10 0.00000000E+00-1.44256412E-14-5.87579268E-05 +-1.17129576E-19-3.38582465E-04 0.00000000E+00-5.87579268E-05-1.17129576E-19 +-3.38582465E-04 0.00000000E+00 1.88390148E-03 1.21440386E-08 7.76848215E-08 +-1.05751896E-13 0.00000000E+00 1.29416513E-08 0.00000000E+00-1.40298709E-14 + 1.33128469E-04 3.07918278E-19 5.33989307E-04 1.49127065E-18 7.22663767E-04 + 0.00000000E+00 2.89075565E-03 0.00000000E+00 1.33128469E-04 3.07918278E-19 + 5.33989307E-04 1.49127065E-18 7.22663767E-04 0.00000000E+00 2.89075565E-03 + 0.00000000E+00-9.90275086E-05-5.36995041E-10 3.86289303E-08-4.19020202E-14 + 0.00000000E+00-5.88075960E-10 0.00000000E+00 3.91323208E-16 1.33128862E-04 + 4.51573668E-19-7.54028875E-05-2.42493819E-19 7.22659693E-04 0.00000000E+00 +-3.84155278E-04 0.00000000E+00 1.33128862E-04 4.51573668E-19-7.54028875E-05 +-2.42493819E-19 7.22659693E-04 0.00000000E+00-3.84155278E-04 0.00000000E+00 + 0.00000000E+00-5.92978458E-10 0.00000000E+00-1.44256412E-14 7.21321246E-05 +-5.75239178E-10-3.89711804E-08-6.89835202E-14-3.38582465E-04 0.00000000E+00 +-5.87579268E-05 1.17129576E-19-3.38582465E-04 0.00000000E+00-5.87579268E-05 + 1.17129576E-19 0.00000000E+00 1.29416513E-08 0.00000000E+00-1.40298709E-14 +-1.88390148E-03 1.21440386E-08-7.76848215E-08-1.05751896E-13 7.22663767E-04 + 0.00000000E+00 2.89075565E-03 0.00000000E+00 1.33128469E-04-3.07918278E-19 + 5.33989307E-04-1.49127065E-18 7.22663767E-04 0.00000000E+00 2.89075565E-03 + 0.00000000E+00 1.33128469E-04-3.07918278E-19 5.33989307E-04-1.49127065E-18 + 0.00000000E+00-5.88075960E-10 0.00000000E+00 3.91323208E-16 9.90275086E-05 +-5.36995041E-10-3.86289303E-08-4.19020202E-14 7.22659693E-04 0.00000000E+00 +-3.84155278E-04 0.00000000E+00 1.33128862E-04-4.51573668E-19-7.54028875E-05 + 2.42493819E-19 7.22659693E-04 0.00000000E+00-3.84155278E-04 0.00000000E+00 + 1.33128862E-04-4.51573668E-19-7.54028875E-05 2.42493819E-19 2.36567456E-06 + 7.54053726E-21 1.41466737E-08 4.57026718E-23-2.17811692E-04 0.00000000E+00 +-1.29880983E-06 0.00000000E+00-3.89711804E-08 6.89835202E-14 0.00000000E+00 + 1.44256412E-14-3.89711804E-08 6.89835202E-14 0.00000000E+00 1.44256412E-14 + 1.56907343E-07-4.16414062E-21-3.65770498E-08-1.49831664E-22-2.68106938E-05 + 0.00000000E+00 3.25815533E-06 0.00000000E+00 8.42880689E-06 5.80689374E-11 +-7.76848215E-08 1.05751896E-13 0.00000000E+00 6.12347958E-11 0.00000000E+00 + 1.40298709E-14 8.42880689E-06 5.80689374E-11-7.76848215E-08 1.05751896E-13 + 0.00000000E+00 6.12347958E-11 0.00000000E+00 1.40298709E-14-2.20871653E-06 +-1.14413387E-20 1.32731981E-08 6.77160463E-23 1.90917965E-04 0.00000000E+00 +-1.14923601E-06 0.00000000E+00-9.36056521E-06-5.67706657E-11-3.86289303E-08 + 4.19020202E-14 0.00000000E+00-6.10672683E-11 0.00000000E+00-3.91323208E-16 +-9.36056521E-06-5.67706657E-11-3.86289303E-08 4.19020202E-14 0.00000000E+00 +-6.10672683E-11 0.00000000E+00-3.91323208E-16-3.77532956E-04-1.22100633E-18 +-2.35516542E-06-7.72232491E-21 3.46641500E-02 0.00000000E+00 2.15633673E-04 + 0.00000000E+00 8.86384800E-05 5.46020983E-10 0.00000000E+00 5.86833604E-10 + 8.86384800E-05 5.46020983E-10 0.00000000E+00 5.86833604E-10-2.11570344E-03 +-8.60624542E-18 1.56907343E-07-4.16414062E-21 1.88152888E-01 0.00000000E+00 +-2.68106938E-05 0.00000000E+00-1.63475148E-03-1.11597344E-08-1.88390148E-03 +-1.21440386E-08 0.00000000E+00-1.17853813E-08 0.00000000E+00-1.29416513E-08 +-1.63475148E-03-1.11597344E-08-1.88390148E-03-1.21440386E-08 0.00000000E+00 +-1.17853813E-08 0.00000000E+00-1.29416513E-08-3.54223893E-04-1.80628666E-18 + 2.22064604E-06 1.11485358E-20 3.06718801E-02 0.00000000E+00-1.92608101E-04 + 0.00000000E+00-1.79023118E-03-1.09435191E-08 8.26660030E-05 5.54759589E-10 + 0.00000000E+00-1.17574526E-08 0.00000000E+00 5.87916297E-10-1.79023118E-03 +-1.09435191E-08 8.26660030E-05 5.54759589E-10 0.00000000E+00-1.17574526E-08 + 0.00000000E+00 5.87916297E-10-2.17811692E-04 0.00000000E+00-1.29880983E-06 + 0.00000000E+00 2.36567456E-06-7.54053726E-21 1.41466737E-08-4.57026718E-23 + 0.00000000E+00 1.44256412E-14 3.89711804E-08 6.89835202E-14 0.00000000E+00 + 1.44256412E-14 3.89711804E-08 6.89835202E-14-2.68106938E-05 0.00000000E+00 + 3.25815533E-06 0.00000000E+00 1.56907343E-07 4.16414062E-21-3.65770498E-08 + 1.49831664E-22 0.00000000E+00 6.12347958E-11 0.00000000E+00 1.40298709E-14 +-8.42880689E-06 5.80689374E-11 7.76848215E-08 1.05751896E-13 0.00000000E+00 + 6.12347958E-11 0.00000000E+00 1.40298709E-14-8.42880689E-06 5.80689374E-11 + 7.76848215E-08 1.05751896E-13 1.90917965E-04 0.00000000E+00-1.14923601E-06 + 0.00000000E+00-2.20871653E-06 1.14413387E-20 1.32731981E-08-6.77160463E-23 + 0.00000000E+00-6.10672683E-11 0.00000000E+00-3.91323208E-16 9.36056521E-06 +-5.67706657E-11 3.86289303E-08 4.19020202E-14 0.00000000E+00-6.10672683E-11 + 0.00000000E+00-3.91323208E-16 9.36056521E-06-5.67706657E-11 3.86289303E-08 + 4.19020202E-14 0.00000000E+00 1.17574526E-08 0.00000000E+00 6.10672683E-11 +-1.79023118E-03 1.09435191E-08-9.36056521E-06 5.67706657E-11 7.22659693E-04 + 0.00000000E+00 1.33128862E-04-4.51573668E-19 7.22659693E-04 0.00000000E+00 + 1.33128862E-04-4.51573668E-19 0.00000000E+00 1.17579707E-08 0.00000000E+00 +-6.10688336E-11-1.84377791E-03 1.08853685E-08 9.51508093E-06-5.66030577E-11 + 6.14639173E-03 0.00000000E+00 8.13961418E-04 0.00000000E+00 1.20526852E-03 +-4.16981307E-18 1.68482688E-04-5.18401609E-19 6.14639173E-03 0.00000000E+00 + 8.13961418E-04 0.00000000E+00 1.20526852E-03-4.16981307E-18 1.68482688E-04 +-5.18401609E-19 1.79023118E-03 1.09435191E-08 9.36056521E-06 5.67706657E-11 + 0.00000000E+00 1.17574526E-08 0.00000000E+00 6.10672683E-11 1.33128862E-04 + 4.51573668E-19 7.22659693E-04 0.00000000E+00 1.33128862E-04 4.51573668E-19 + 7.22659693E-04 0.00000000E+00 1.84377791E-03 1.08853685E-08-9.51508093E-06 +-5.66030577E-11 0.00000000E+00 1.17579707E-08 0.00000000E+00-6.10688336E-11 + 1.20526852E-03 4.16981307E-18 1.68482688E-04 5.18401609E-19 6.14639173E-03 + 0.00000000E+00 8.13961418E-04 0.00000000E+00 1.20526852E-03 4.16981307E-18 + 1.68482688E-04 5.18401609E-19 6.14639173E-03 0.00000000E+00 8.13961418E-04 + 0.00000000E+00 0.00000000E+00 1.17574526E-08 0.00000000E+00 6.10672683E-11 +-1.79023118E-03 1.09435191E-08-9.36056521E-06 5.67706657E-11 7.22659693E-04 + 0.00000000E+00 1.33128862E-04-4.51573668E-19 2.66196436E-01 0.00000000E+00 + 3.05550389E-02-1.12224164E-16 0.00000000E+00 1.17579707E-08 0.00000000E+00 +-6.10688336E-11-1.84377791E-03 1.08853685E-08 9.51508093E-06-5.66030577E-11 + 6.14639173E-03 0.00000000E+00 8.13961418E-04 0.00000000E+00 1.20526852E-03 +-4.16981307E-18 1.68482688E-04-5.18401609E-19 2.00975531E+00 0.00000000E+00 + 2.36739262E-01 0.00000000E+00 2.44560653E-01-9.26576765E-16 3.05853713E-02 +-1.13360392E-16 1.99762190E-03 1.07542545E-08 1.04370985E-05 5.58165913E-11 + 0.00000000E+00 1.17854488E-08 0.00000000E+00 6.12325881E-11 1.68482475E-04 + 3.95612048E-19 8.13957259E-04 0.00000000E+00 3.05852747E-02 1.05133790E-16 + 2.36831987E-01 0.00000000E+00 2.05062749E-03 1.07205402E-08-1.05900533E-05 +-5.57193983E-11 0.00000000E+00 1.18025489E-08 0.00000000E+00-6.12819975E-11 + 1.50456671E-03 3.67933153E-18 2.07952918E-04 5.85625880E-19 6.87812632E-03 + 0.00000000E+00 9.05600086E-04 0.00000000E+00 2.44816538E-01 7.96021375E-16 + 3.06191128E-02 9.72281895E-17 1.79898496E+00 0.00000000E+00 2.13269988E-01 + 0.00000000E+00 3.06718801E-02 0.00000000E+00 1.90917965E-04 0.00000000E+00 +-3.54223893E-04 1.80628666E-18-2.20871653E-06 1.14413387E-20 0.00000000E+00 + 5.88075960E-10-9.90275086E-05 5.36995041E-10 0.00000000E+00 5.88075960E-10 +-9.90275086E-05 5.36995041E-10 1.67724493E-01 0.00000000E+00-2.11038020E-05 + 0.00000000E+00-1.97241817E-03 1.13243119E-17 1.77004386E-07 2.93429209E-22 + 0.00000000E+00-1.17579707E-08 0.00000000E+00-1.29432682E-08 1.84377791E-03 +-1.08853685E-08 2.11295252E-03-1.18935352E-08 0.00000000E+00-1.17579707E-08 + 0.00000000E+00-1.29432682E-08 1.84377791E-03-1.08853685E-08 2.11295252E-03 +-1.18935352E-08 2.75311914E-02 0.00000000E+00-1.72801310E-04 0.00000000E+00 +-3.27944793E-04 1.79926192E-18 2.05703689E-06-1.14681222E-20 0.00000000E+00 +-1.17854488E-08 0.00000000E+00 5.87161023E-10 1.99762190E-03-1.07542545E-08 +-9.31055297E-05 5.42140330E-10 0.00000000E+00-1.17854488E-08 0.00000000E+00 + 5.87161023E-10 1.99762190E-03-1.07542545E-08-9.31055297E-05 5.42140330E-10 +-8.26660030E-05-5.54759589E-10 3.86289303E-08-4.19020202E-14 0.00000000E+00 +-5.87916297E-10 0.00000000E+00 3.91323208E-16-7.54028875E-05-2.42493819E-19 +-3.84155278E-04 0.00000000E+00-1.52851025E-02-5.63961389E-17-1.25733924E-01 + 0.00000000E+00 2.11295252E-03 1.18935352E-08 7.67985646E-08-6.50162542E-14 + 0.00000000E+00 1.29432682E-08 0.00000000E+00 1.44244215E-14 1.68482688E-04 + 5.18401609E-19 6.75400682E-04 1.87151266E-18 8.13961418E-04 0.00000000E+00 + 3.25595930E-03 0.00000000E+00 3.05853713E-02 1.13360392E-16 1.22342544E-01 + 4.33648282E-16 2.36739262E-01 0.00000000E+00 9.49247872E-01 0.00000000E+00 +-1.09301710E-04-5.31840527E-10 3.82387209E-08-2.42982346E-14 0.00000000E+00 +-5.92387307E-10 0.00000000E+00 1.23523320E-14 1.68482475E-04 3.95612048E-19 +-9.41088483E-05-2.45309482E-19 8.13957259E-04 0.00000000E+00-4.29889336E-04 + 0.00000000E+00 3.05852747E-02 1.05133790E-16-1.53010969E-02-5.05904948E-17 + 2.36831987E-01 0.00000000E+00-1.12525494E-01 0.00000000E+00 0.00000000E+00 +-5.87916297E-10 0.00000000E+00 3.91323208E-16 8.26660030E-05-5.54759589E-10 +-3.86289303E-08-4.19020202E-14-3.84155278E-04 0.00000000E+00-7.54028875E-05 + 2.42493819E-19-1.25733924E-01 0.00000000E+00-1.52851025E-02 5.63961389E-17 + 0.00000000E+00 1.29432682E-08 0.00000000E+00 1.44244215E-14-2.11295252E-03 + 1.18935352E-08-7.67985646E-08-6.50162542E-14 8.13961418E-04 0.00000000E+00 + 3.25595930E-03 0.00000000E+00 1.68482688E-04-5.18401609E-19 6.75400682E-04 +-1.87151266E-18 2.36739262E-01 0.00000000E+00 9.49247872E-01 0.00000000E+00 + 3.05853713E-02-1.13360392E-16 1.22342544E-01-4.33648282E-16 0.00000000E+00 +-5.92387307E-10 0.00000000E+00 1.23523320E-14 1.09301710E-04-5.31840527E-10 +-3.82387209E-08-2.42982346E-14 8.13957259E-04 0.00000000E+00-4.29889336E-04 + 0.00000000E+00 1.68482475E-04-3.95612048E-19-9.41088483E-05 2.45309482E-19 + 2.36831987E-01 0.00000000E+00-1.12525494E-01 0.00000000E+00 3.05852747E-02 +-1.05133790E-16-1.53010969E-02 5.05904948E-17-8.26660030E-05-5.54759589E-10 + 3.86289303E-08-4.19020202E-14 0.00000000E+00-5.87916297E-10 0.00000000E+00 + 3.91323208E-16-7.54028875E-05-2.42493819E-19-3.84155278E-04 0.00000000E+00 +-7.54028875E-05-2.42493819E-19-3.84155278E-04 0.00000000E+00 2.11295252E-03 + 1.18935352E-08 7.67985646E-08-6.50162542E-14 0.00000000E+00 1.29432682E-08 + 0.00000000E+00 1.44244215E-14 1.68482688E-04 5.18401609E-19 6.75400682E-04 + 1.87151266E-18 8.13961418E-04 0.00000000E+00 3.25595930E-03 0.00000000E+00 + 1.68482688E-04 5.18401609E-19 6.75400682E-04 1.87151266E-18 8.13961418E-04 + 0.00000000E+00 3.25595930E-03 0.00000000E+00-1.09301710E-04-5.31840527E-10 + 3.82387209E-08-2.42982346E-14 0.00000000E+00-5.92387307E-10 0.00000000E+00 + 1.23523320E-14 1.68482475E-04 3.95612048E-19-9.41088483E-05-2.45309482E-19 + 8.13957259E-04 0.00000000E+00-4.29889336E-04 0.00000000E+00 1.68482475E-04 + 3.95612048E-19-9.41088483E-05-2.45309482E-19 8.13957259E-04 0.00000000E+00 +-4.29889336E-04 0.00000000E+00 0.00000000E+00-5.87916297E-10 0.00000000E+00 + 3.91323208E-16 8.26660030E-05-5.54759589E-10-3.86289303E-08-4.19020202E-14 +-3.84155278E-04 0.00000000E+00-7.54028875E-05 2.42493819E-19-3.84155278E-04 + 0.00000000E+00-7.54028875E-05 2.42493819E-19 0.00000000E+00 1.29432682E-08 + 0.00000000E+00 1.44244215E-14-2.11295252E-03 1.18935352E-08-7.67985646E-08 +-6.50162542E-14 8.13961418E-04 0.00000000E+00 3.25595930E-03 0.00000000E+00 + 1.68482688E-04-5.18401609E-19 6.75400682E-04-1.87151266E-18 8.13961418E-04 + 0.00000000E+00 3.25595930E-03 0.00000000E+00 1.68482688E-04-5.18401609E-19 + 6.75400682E-04-1.87151266E-18 0.00000000E+00-5.92387307E-10 0.00000000E+00 + 1.23523320E-14 1.09301710E-04-5.31840527E-10-3.82387209E-08-2.42982346E-14 + 8.13957259E-04 0.00000000E+00-4.29889336E-04 0.00000000E+00 1.68482475E-04 +-3.95612048E-19-9.41088483E-05 2.45309482E-19 8.13957259E-04 0.00000000E+00 +-4.29889336E-04 0.00000000E+00 1.68482475E-04-3.95612048E-19-9.41088483E-05 + 2.45309482E-19 2.22064604E-06 1.11485358E-20 1.32731981E-08 6.77160463E-23 +-1.92608101E-04 0.00000000E+00-1.14923601E-06 0.00000000E+00-3.86289303E-08 + 4.19020202E-14 0.00000000E+00-3.91323208E-16-3.86289303E-08 4.19020202E-14 + 0.00000000E+00-3.91323208E-16 1.77004386E-07-2.93429209E-22-3.40990887E-08 +-1.89235579E-22-2.11038020E-05 0.00000000E+00 2.90359115E-06 0.00000000E+00 + 9.51508093E-06 5.66030577E-11-7.67985646E-08 6.50162542E-14 0.00000000E+00 + 6.10688336E-11 0.00000000E+00-1.44244215E-14 9.51508093E-06 5.66030577E-11 +-7.67985646E-08 6.50162542E-14 0.00000000E+00 6.10688336E-11 0.00000000E+00 +-1.44244215E-14-2.04370907E-06-1.10417230E-20 1.22884186E-08 6.75291416E-23 + 1.71453150E-04 0.00000000E+00-1.03156288E-06 0.00000000E+00-1.04370985E-05 +-5.58165913E-11-3.82387209E-08 2.42982346E-14 0.00000000E+00-6.12325881E-11 + 0.00000000E+00-1.23523320E-14-1.04370985E-05-5.58165913E-11-3.82387209E-08 + 2.42982346E-14 0.00000000E+00-6.12325881E-11 0.00000000E+00-1.23523320E-14 +-3.54223893E-04-1.80628666E-18-2.20871653E-06-1.14413387E-20 3.06718801E-02 + 0.00000000E+00 1.90917965E-04 0.00000000E+00 9.90275086E-05 5.36995041E-10 + 0.00000000E+00 5.88075960E-10 9.90275086E-05 5.36995041E-10 0.00000000E+00 + 5.88075960E-10-1.97241817E-03-1.13243119E-17 1.77004386E-07-2.93429209E-22 + 1.67724493E-01 0.00000000E+00-2.11038020E-05 0.00000000E+00-1.84377791E-03 +-1.08853685E-08-2.11295252E-03-1.18935352E-08 0.00000000E+00-1.17579707E-08 + 0.00000000E+00-1.29432682E-08-1.84377791E-03-1.08853685E-08-2.11295252E-03 +-1.18935352E-08 0.00000000E+00-1.17579707E-08 0.00000000E+00-1.29432682E-08 +-3.27944793E-04-1.79926192E-18 2.05703689E-06 1.14681222E-20 2.75311914E-02 + 0.00000000E+00-1.72801310E-04 0.00000000E+00-1.99762190E-03-1.07542545E-08 + 9.31055297E-05 5.42140330E-10 0.00000000E+00-1.17854488E-08 0.00000000E+00 + 5.87161023E-10-1.99762190E-03-1.07542545E-08 9.31055297E-05 5.42140330E-10 + 0.00000000E+00-1.17854488E-08 0.00000000E+00 5.87161023E-10-1.92608101E-04 + 0.00000000E+00-1.14923601E-06 0.00000000E+00 2.22064604E-06-1.11485358E-20 + 1.32731981E-08-6.77160463E-23 0.00000000E+00-3.91323208E-16 3.86289303E-08 + 4.19020202E-14 0.00000000E+00-3.91323208E-16 3.86289303E-08 4.19020202E-14 +-2.11038020E-05 0.00000000E+00 2.90359115E-06 0.00000000E+00 1.77004386E-07 + 2.93429209E-22-3.40990887E-08 1.89235579E-22 0.00000000E+00 6.10688336E-11 + 0.00000000E+00-1.44244215E-14-9.51508093E-06 5.66030577E-11 7.67985646E-08 + 6.50162542E-14 0.00000000E+00 6.10688336E-11 0.00000000E+00-1.44244215E-14 +-9.51508093E-06 5.66030577E-11 7.67985646E-08 6.50162542E-14 1.71453150E-04 + 0.00000000E+00-1.03156288E-06 0.00000000E+00-2.04370907E-06 1.10417230E-20 + 1.22884186E-08-6.75291416E-23 0.00000000E+00-6.12325881E-11 0.00000000E+00 +-1.23523320E-14 1.04370985E-05-5.58165913E-11 3.82387209E-08 2.42982346E-14 + 0.00000000E+00-6.12325881E-11 0.00000000E+00-1.23523320E-14 1.04370985E-05 +-5.58165913E-11 3.82387209E-08 2.42982346E-14 0.00000000E+00 1.17854488E-08 + 0.00000000E+00 6.12325881E-11-1.99762190E-03 1.07542545E-08-1.04370985E-05 + 5.58165913E-11 8.13957259E-04 0.00000000E+00 1.68482475E-04-3.95612048E-19 + 8.13957259E-04 0.00000000E+00 1.68482475E-04-3.95612048E-19 0.00000000E+00 + 1.18025489E-08 0.00000000E+00-6.12819975E-11-2.05062749E-03 1.07205402E-08 + 1.05900533E-05-5.57193983E-11 6.87812632E-03 0.00000000E+00 9.05600086E-04 + 0.00000000E+00 1.50456671E-03-3.67933153E-18 2.07952918E-04-5.85625880E-19 + 6.87812632E-03 0.00000000E+00 9.05600086E-04 0.00000000E+00 1.50456671E-03 +-3.67933153E-18 2.07952918E-04-5.85625880E-19 1.99762190E-03 1.07542545E-08 + 1.04370985E-05 5.58165913E-11 0.00000000E+00 1.17854488E-08 0.00000000E+00 + 6.12325881E-11 1.68482475E-04 3.95612048E-19 8.13957259E-04 0.00000000E+00 + 1.68482475E-04 3.95612048E-19 8.13957259E-04 0.00000000E+00 2.05062749E-03 + 1.07205402E-08-1.05900533E-05-5.57193983E-11 0.00000000E+00 1.18025489E-08 + 0.00000000E+00-6.12819975E-11 1.50456671E-03 3.67933153E-18 2.07952918E-04 + 5.85625880E-19 6.87812632E-03 0.00000000E+00 9.05600086E-04 0.00000000E+00 + 1.50456671E-03 3.67933153E-18 2.07952918E-04 5.85625880E-19 6.87812632E-03 + 0.00000000E+00 9.05600086E-04 0.00000000E+00 0.00000000E+00 1.17854488E-08 + 0.00000000E+00 6.12325881E-11-1.99762190E-03 1.07542545E-08-1.04370985E-05 + 5.58165913E-11 8.13957259E-04 0.00000000E+00 1.68482475E-04-3.95612048E-19 + 2.36831987E-01 0.00000000E+00 3.05852747E-02-1.05133790E-16 0.00000000E+00 + 1.18025489E-08 0.00000000E+00-6.12819975E-11-2.05062749E-03 1.07205402E-08 + 1.05900533E-05-5.57193983E-11 6.87812632E-03 0.00000000E+00 9.05600086E-04 + 0.00000000E+00 1.50456671E-03-3.67933153E-18 2.07952918E-04-5.85625880E-19 + 1.79898496E+00 0.00000000E+00 2.13269988E-01 0.00000000E+00 2.44816538E-01 +-7.96021375E-16 3.06191128E-02-9.72281895E-17 2.20300418E-03 1.06518791E-08 + 1.15032275E-05 5.53071493E-11 0.00000000E+00 1.18697647E-08 0.00000000E+00 + 6.16843841E-11 2.07953115E-04 6.72295753E-19 9.05595393E-04 0.00000000E+00 + 3.06190277E-02 1.00321671E-16 2.13330612E-01 0.00000000E+00 2.25545765E-03 + 1.06369203E-08-1.16545900E-05-5.52640458E-11 0.00000000E+00 1.18986379E-08 + 0.00000000E+00-6.17677436E-11 1.83674212E-03 6.23084662E-18 2.51524777E-04 + 8.44792984E-19 7.61274116E-03 0.00000000E+00 9.97618518E-04 0.00000000E+00 + 2.45100545E-01 8.33350026E-16 3.06563550E-02 1.08549463E-16 1.62850543E+00 + 0.00000000E+00 1.94059084E-01 0.00000000E+00 2.75311914E-02 0.00000000E+00 + 1.71453150E-04 0.00000000E+00-3.27944793E-04 1.79926192E-18-2.04370907E-06 + 1.10417230E-20 0.00000000E+00 5.92387307E-10-1.09301710E-04 5.31840527E-10 + 0.00000000E+00 5.92387307E-10-1.09301710E-04 5.31840527E-10 1.51448845E-01 + 0.00000000E+00-1.70234201E-05 0.00000000E+00-1.81223819E-03 7.35626607E-18 + 1.96468110E-07-7.08210713E-21 0.00000000E+00-1.18025489E-08 0.00000000E+00 +-1.30157885E-08 2.05062749E-03-1.07205402E-08 2.33968436E-03-1.17484887E-08 + 0.00000000E+00-1.18025489E-08 0.00000000E+00-1.30157885E-08 2.05062749E-03 +-1.07205402E-08 2.33968436E-03-1.17484887E-08 2.49987212E-02 0.00000000E+00 +-1.56843504E-04 0.00000000E+00-2.98759875E-04 8.54710123E-19 1.87528055E-06 +-5.44214385E-21 0.00000000E+00-1.18697647E-08 0.00000000E+00 5.89856018E-10 + 2.20300418E-03-1.06518791E-08-1.03444229E-04 5.34594291E-10 0.00000000E+00 +-1.18697647E-08 0.00000000E+00 5.89856018E-10 2.20300418E-03-1.06518791E-08 +-1.03444229E-04 5.34594291E-10-9.31055297E-05-5.42140330E-10 3.82387209E-08 +-2.42982346E-14 0.00000000E+00-5.87161023E-10 0.00000000E+00 1.23523320E-14 +-9.41088483E-05-2.45309482E-19-4.29889336E-04 0.00000000E+00-1.53010969E-02 +-5.05904948E-17-1.12525494E-01 0.00000000E+00 2.33968436E-03 1.17484887E-08 + 7.61083611E-08-3.37467720E-14 0.00000000E+00 1.30157885E-08 0.00000000E+00 + 3.37924825E-14 2.07952918E-04 5.85625880E-19 8.33276886E-04 2.51064878E-18 + 9.05600086E-04 0.00000000E+00 3.62252688E-03 0.00000000E+00 3.06191128E-02 + 9.72281895E-17 1.22477527E-01 4.00872785E-16 2.13269988E-01 0.00000000E+00 + 8.54733484E-01 0.00000000E+00-1.19471728E-04-5.30024738E-10 3.78406271E-08 +-1.07758787E-14 0.00000000E+00-5.98679225E-10 0.00000000E+00 2.08398851E-14 + 2.07953115E-04 6.72295753E-19-1.14869473E-04-3.79272184E-19 9.05595393E-04 + 0.00000000E+00-4.75803478E-04 0.00000000E+00 3.06190277E-02 1.00321671E-16 +-1.53188457E-02-5.22177835E-17 2.13330612E-01 0.00000000E+00-1.01847424E-01 + 0.00000000E+00 0.00000000E+00-5.87161023E-10 0.00000000E+00 1.23523320E-14 + 9.31055297E-05-5.42140330E-10-3.82387209E-08-2.42982346E-14-4.29889336E-04 + 0.00000000E+00-9.41088483E-05 2.45309482E-19-1.12525494E-01 0.00000000E+00 +-1.53010969E-02 5.05904948E-17 0.00000000E+00 1.30157885E-08 0.00000000E+00 + 3.37924825E-14-2.33968436E-03 1.17484887E-08-7.61083611E-08-3.37467720E-14 + 9.05600086E-04 0.00000000E+00 3.62252688E-03 0.00000000E+00 2.07952918E-04 +-5.85625880E-19 8.33276886E-04-2.51064878E-18 2.13269988E-01 0.00000000E+00 + 8.54733484E-01 0.00000000E+00 3.06191128E-02-9.72281895E-17 1.22477527E-01 +-4.00872785E-16 0.00000000E+00-5.98679225E-10 0.00000000E+00 2.08398851E-14 + 1.19471728E-04-5.30024738E-10-3.78406271E-08-1.07758787E-14 9.05595393E-04 + 0.00000000E+00-4.75803478E-04 0.00000000E+00 2.07953115E-04-6.72295753E-19 +-1.14869473E-04 3.79272184E-19 2.13330612E-01 0.00000000E+00-1.01847424E-01 + 0.00000000E+00 3.06190277E-02-1.00321671E-16-1.53188457E-02 5.22177835E-17 +-9.31055297E-05-5.42140330E-10 3.82387209E-08-2.42982346E-14 0.00000000E+00 +-5.87161023E-10 0.00000000E+00 1.23523320E-14-9.41088483E-05-2.45309482E-19 +-4.29889336E-04 0.00000000E+00-9.41088483E-05-2.45309482E-19-4.29889336E-04 + 0.00000000E+00 2.33968436E-03 1.17484887E-08 7.61083611E-08-3.37467720E-14 + 0.00000000E+00 1.30157885E-08 0.00000000E+00 3.37924825E-14 2.07952918E-04 + 5.85625880E-19 8.33276886E-04 2.51064878E-18 9.05600086E-04 0.00000000E+00 + 3.62252688E-03 0.00000000E+00 2.07952918E-04 5.85625880E-19 8.33276886E-04 + 2.51064878E-18 9.05600086E-04 0.00000000E+00 3.62252688E-03 0.00000000E+00 +-1.19471728E-04-5.30024738E-10 3.78406271E-08-1.07758787E-14 0.00000000E+00 +-5.98679225E-10 0.00000000E+00 2.08398851E-14 2.07953115E-04 6.72295753E-19 +-1.14869473E-04-3.79272184E-19 9.05595393E-04 0.00000000E+00-4.75803478E-04 + 0.00000000E+00 2.07953115E-04 6.72295753E-19-1.14869473E-04-3.79272184E-19 + 9.05595393E-04 0.00000000E+00-4.75803478E-04 0.00000000E+00 0.00000000E+00 +-5.87161023E-10 0.00000000E+00 1.23523320E-14 9.31055297E-05-5.42140330E-10 +-3.82387209E-08-2.42982346E-14-4.29889336E-04 0.00000000E+00-9.41088483E-05 + 2.45309482E-19-4.29889336E-04 0.00000000E+00-9.41088483E-05 2.45309482E-19 + 0.00000000E+00 1.30157885E-08 0.00000000E+00 3.37924825E-14-2.33968436E-03 + 1.17484887E-08-7.61083611E-08-3.37467720E-14 9.05600086E-04 0.00000000E+00 + 3.62252688E-03 0.00000000E+00 2.07952918E-04-5.85625880E-19 8.33276886E-04 +-2.51064878E-18 9.05600086E-04 0.00000000E+00 3.62252688E-03 0.00000000E+00 + 2.07952918E-04-5.85625880E-19 8.33276886E-04-2.51064878E-18 0.00000000E+00 +-5.98679225E-10 0.00000000E+00 2.08398851E-14 1.19471728E-04-5.30024738E-10 +-3.78406271E-08-1.07758787E-14 9.05595393E-04 0.00000000E+00-4.75803478E-04 + 0.00000000E+00 2.07953115E-04-6.72295753E-19-1.14869473E-04 3.79272184E-19 + 9.05595393E-04 0.00000000E+00-4.75803478E-04 0.00000000E+00 2.07953115E-04 +-6.72295753E-19-1.14869473E-04 3.79272184E-19 2.05703689E-06 1.14681222E-20 + 1.22884186E-08 6.75291416E-23-1.72801310E-04 0.00000000E+00-1.03156288E-06 + 0.00000000E+00-3.82387209E-08 2.42982346E-14 0.00000000E+00-1.23523320E-14 +-3.82387209E-08 2.42982346E-14 0.00000000E+00-1.23523320E-14 1.96468110E-07 + 7.08210713E-21-3.13283520E-08-1.29715557E-22-1.70234201E-05 0.00000000E+00 + 2.62130250E-06 0.00000000E+00 1.05900533E-05 5.57193983E-11-7.61083611E-08 + 3.37467720E-14 0.00000000E+00 6.12819975E-11 0.00000000E+00-3.37924825E-14 + 1.05900533E-05 5.57193983E-11-7.61083611E-08 3.37467720E-14 0.00000000E+00 + 6.12819975E-11 0.00000000E+00-3.37924825E-14-1.86051828E-06-5.23555177E-21 + 1.11947956E-08 3.19303140E-23 1.55744337E-04 0.00000000E+00-9.36675536E-07 + 0.00000000E+00-1.15032275E-05-5.53071493E-11-3.78406271E-08 1.07758787E-14 + 0.00000000E+00-6.16843841E-11 0.00000000E+00-2.08398851E-14-1.15032275E-05 +-5.53071493E-11-3.78406271E-08 1.07758787E-14 0.00000000E+00-6.16843841E-11 + 0.00000000E+00-2.08398851E-14-3.27944793E-04-1.79926192E-18-2.04370907E-06 +-1.10417230E-20 2.75311914E-02 0.00000000E+00 1.71453150E-04 0.00000000E+00 + 1.09301710E-04 5.31840527E-10 0.00000000E+00 5.92387307E-10 1.09301710E-04 + 5.31840527E-10 0.00000000E+00 5.92387307E-10-1.81223819E-03-7.35626607E-18 + 1.96468110E-07 7.08210713E-21 1.51448845E-01 0.00000000E+00-1.70234201E-05 + 0.00000000E+00-2.05062749E-03-1.07205402E-08-2.33968436E-03-1.17484887E-08 + 0.00000000E+00-1.18025489E-08 0.00000000E+00-1.30157885E-08-2.05062749E-03 +-1.07205402E-08-2.33968436E-03-1.17484887E-08 0.00000000E+00-1.18025489E-08 + 0.00000000E+00-1.30157885E-08-2.98759875E-04-8.54710123E-19 1.87528055E-06 + 5.44214385E-21 2.49987212E-02 0.00000000E+00-1.56843504E-04 0.00000000E+00 +-2.20300418E-03-1.06518791E-08 1.03444229E-04 5.34594291E-10 0.00000000E+00 +-1.18697647E-08 0.00000000E+00 5.89856018E-10-2.20300418E-03-1.06518791E-08 + 1.03444229E-04 5.34594291E-10 0.00000000E+00-1.18697647E-08 0.00000000E+00 + 5.89856018E-10-1.72801310E-04 0.00000000E+00-1.03156288E-06 0.00000000E+00 + 2.05703689E-06-1.14681222E-20 1.22884186E-08-6.75291416E-23 0.00000000E+00 +-1.23523320E-14 3.82387209E-08 2.42982346E-14 0.00000000E+00-1.23523320E-14 + 3.82387209E-08 2.42982346E-14-1.70234201E-05 0.00000000E+00 2.62130250E-06 + 0.00000000E+00 1.96468110E-07-7.08210713E-21-3.13283520E-08 1.29715557E-22 + 0.00000000E+00 6.12819975E-11 0.00000000E+00-3.37924825E-14-1.05900533E-05 + 5.57193983E-11 7.61083611E-08 3.37467720E-14 0.00000000E+00 6.12819975E-11 + 0.00000000E+00-3.37924825E-14-1.05900533E-05 5.57193983E-11 7.61083611E-08 + 3.37467720E-14 1.55744337E-04 0.00000000E+00-9.36675536E-07 0.00000000E+00 +-1.86051828E-06 5.23555177E-21 1.11947956E-08-3.19303140E-23 0.00000000E+00 +-6.16843841E-11 0.00000000E+00-2.08398851E-14 1.15032275E-05-5.53071493E-11 + 3.78406271E-08 1.07758787E-14 0.00000000E+00-6.16843841E-11 0.00000000E+00 +-2.08398851E-14 1.15032275E-05-5.53071493E-11 3.78406271E-08 1.07758787E-14 + 0.00000000E+00 1.18697647E-08 0.00000000E+00 6.16843841E-11-2.20300418E-03 + 1.06518791E-08-1.15032275E-05 5.53071493E-11 9.05595393E-04 0.00000000E+00 + 2.07953115E-04-6.72295753E-19 9.05595393E-04 0.00000000E+00 2.07953115E-04 +-6.72295753E-19 0.00000000E+00 1.18986379E-08 0.00000000E+00-6.17677436E-11 +-2.25545765E-03 1.06369203E-08 1.16545900E-05-5.52640458E-11 7.61274116E-03 + 0.00000000E+00 9.97618518E-04 0.00000000E+00 1.83674212E-03-6.23084662E-18 + 2.51524777E-04-8.44792984E-19 7.61274116E-03 0.00000000E+00 9.97618518E-04 + 0.00000000E+00 1.83674212E-03-6.23084662E-18 2.51524777E-04-8.44792984E-19 + 2.20300418E-03 1.06518791E-08 1.15032275E-05 5.53071493E-11 0.00000000E+00 + 1.18697647E-08 0.00000000E+00 6.16843841E-11 2.07953115E-04 6.72295753E-19 + 9.05595393E-04 0.00000000E+00 2.07953115E-04 6.72295753E-19 9.05595393E-04 + 0.00000000E+00 2.25545765E-03 1.06369203E-08-1.16545900E-05-5.52640458E-11 + 0.00000000E+00 1.18986379E-08 0.00000000E+00-6.17677436E-11 1.83674212E-03 + 6.23084662E-18 2.51524777E-04 8.44792984E-19 7.61274116E-03 0.00000000E+00 + 9.97618518E-04 0.00000000E+00 1.83674212E-03 6.23084662E-18 2.51524777E-04 + 8.44792984E-19 7.61274116E-03 0.00000000E+00 9.97618518E-04 0.00000000E+00 + 0.00000000E+00 1.18697647E-08 0.00000000E+00 6.16843841E-11-2.20300418E-03 + 1.06518791E-08-1.15032275E-05 5.53071493E-11 9.05595393E-04 0.00000000E+00 + 2.07953115E-04-6.72295753E-19 2.13330612E-01 0.00000000E+00 3.06190277E-02 +-1.00321671E-16 0.00000000E+00 1.18986379E-08 0.00000000E+00-6.17677436E-11 +-2.25545765E-03 1.06369203E-08 1.16545900E-05-5.52640458E-11 7.61274116E-03 + 0.00000000E+00 9.97618518E-04 0.00000000E+00 1.83674212E-03-6.23084662E-18 + 2.51524777E-04-8.44792984E-19 1.62850543E+00 0.00000000E+00 1.94059084E-01 + 0.00000000E+00 2.45100545E-01-8.33350026E-16 3.06563550E-02-1.08549463E-16 + 2.40598848E-03 1.06153884E-08 1.25567037E-05 5.51345117E-11 0.00000000E+00 + 1.19958400E-08 0.00000000E+00 6.23498753E-11 2.51524477E-04 8.08569272E-19 + 9.97613725E-04 0.00000000E+00 3.06562634E-02 1.06812293E-16 1.94100279E-01 + 0.00000000E+00 2.45773183E-03 1.06147830E-08-1.27060121E-05-5.51328090E-11 + 0.00000000E+00 1.20337861E-08 0.00000000E+00-6.24594006E-11 2.20166244E-03 + 6.30932886E-18 2.99182475E-04 7.77901837E-19 8.35055003E-03 0.00000000E+00 + 1.09005505E-03 0.00000000E+00 2.45412257E-01 1.04525901E-15 3.06970480E-02 + 1.54683961E-16 1.48779255E+00 0.00000000E+00 1.78048251E-01 0.00000000E+00 + 2.49987212E-02 0.00000000E+00 1.55744337E-04 0.00000000E+00-2.98759875E-04 + 8.54710123E-19-1.86051828E-06 5.23555177E-21 0.00000000E+00 5.98679225E-10 +-1.19471728E-04 5.30024738E-10 0.00000000E+00 5.98679225E-10-1.19471728E-04 + 5.30024738E-10 1.38190515E-01 0.00000000E+00-1.40079352E-05 0.00000000E+00 +-1.63492905E-03 4.29551783E-18 2.16730696E-07-1.03140021E-21 0.00000000E+00 +-1.18986379E-08 0.00000000E+00-1.31388955E-08 2.25545765E-03-1.06369203E-08 + 2.56403839E-03-1.16839129E-08 0.00000000E+00-1.18986379E-08 0.00000000E+00 +-1.31388955E-08 2.25545765E-03-1.06369203E-08 2.56403839E-03-1.16839129E-08 + 2.29154669E-02 0.00000000E+00-1.43725280E-04 0.00000000E+00-2.66577079E-04 + 6.36839842E-19 1.67477331E-06-4.06779359E-21 0.00000000E+00-1.19958400E-08 + 0.00000000E+00 5.94987135E-10 2.40598848E-03-1.06153884E-08-1.13683729E-04 + 5.30917205E-10 0.00000000E+00-1.19958400E-08 0.00000000E+00 5.94987135E-10 + 2.40598848E-03-1.06153884E-08-1.13683729E-04 5.30917205E-10-1.03444229E-04 +-5.34594291E-10 3.78406271E-08-1.07758787E-14 0.00000000E+00-5.89856018E-10 + 0.00000000E+00 2.08398851E-14-1.14869473E-04-3.79272184E-19-4.75803478E-04 + 0.00000000E+00-1.53188457E-02-5.22177835E-17-1.01847424E-01 0.00000000E+00 + 2.56403839E-03 1.16839129E-08 7.51776382E-08-1.04677226E-14 0.00000000E+00 + 1.31388955E-08 0.00000000E+00 4.87327602E-14 2.51524777E-04 8.44792984E-19 + 1.00755797E-03 3.23318192E-18 9.97618518E-04 0.00000000E+00 3.99061392E-03 + 0.00000000E+00 3.06563550E-02 1.08549463E-16 1.22626472E-01 4.44880074E-16 + 1.94059084E-01 0.00000000E+00 7.77468529E-01 0.00000000E+00-1.29494161E-04 +-5.30733077E-10 3.73271039E-08-4.25675456E-16 0.00000000E+00-6.06582311E-10 + 0.00000000E+00 2.73813240E-14 2.51524477E-04 8.08569272E-19-1.37676738E-04 +-3.96617777E-19 9.97613725E-04 0.00000000E+00-5.21917193E-04 0.00000000E+00 + 3.06562634E-02 1.06812293E-16-1.53383279E-02-6.53740633E-17 1.94100279E-01 + 0.00000000E+00-9.30371326E-02 0.00000000E+00 0.00000000E+00-5.89856018E-10 + 0.00000000E+00 2.08398851E-14 1.03444229E-04-5.34594291E-10-3.78406271E-08 +-1.07758787E-14-4.75803478E-04 0.00000000E+00-1.14869473E-04 3.79272184E-19 +-1.01847424E-01 0.00000000E+00-1.53188457E-02 5.22177835E-17 0.00000000E+00 + 1.31388955E-08 0.00000000E+00 4.87327602E-14-2.56403839E-03 1.16839129E-08 +-7.51776382E-08-1.04677226E-14 9.97618518E-04 0.00000000E+00 3.99061392E-03 + 0.00000000E+00 2.51524777E-04-8.44792984E-19 1.00755797E-03-3.23318192E-18 + 1.94059084E-01 0.00000000E+00 7.77468529E-01 0.00000000E+00 3.06563550E-02 +-1.08549463E-16 1.22626472E-01-4.44880074E-16 0.00000000E+00-6.06582311E-10 + 0.00000000E+00 2.73813240E-14 1.29494161E-04-5.30733077E-10-3.73271039E-08 +-4.25675456E-16 9.97613725E-04 0.00000000E+00-5.21917193E-04 0.00000000E+00 + 2.51524477E-04-8.08569272E-19-1.37676738E-04 3.96617777E-19 1.94100279E-01 + 0.00000000E+00-9.30371326E-02 0.00000000E+00 3.06562634E-02-1.06812293E-16 +-1.53383279E-02 6.53740633E-17-1.03444229E-04-5.34594291E-10 3.78406271E-08 +-1.07758787E-14 0.00000000E+00-5.89856018E-10 0.00000000E+00 2.08398851E-14 +-1.14869473E-04-3.79272184E-19-4.75803478E-04 0.00000000E+00-1.14869473E-04 +-3.79272184E-19-4.75803478E-04 0.00000000E+00 2.56403839E-03 1.16839129E-08 + 7.51776382E-08-1.04677226E-14 0.00000000E+00 1.31388955E-08 0.00000000E+00 + 4.87327602E-14 2.51524777E-04 8.44792984E-19 1.00755797E-03 3.23318192E-18 + 9.97618518E-04 0.00000000E+00 3.99061392E-03 0.00000000E+00 2.51524777E-04 + 8.44792984E-19 1.00755797E-03 3.23318192E-18 9.97618518E-04 0.00000000E+00 + 3.99061392E-03 0.00000000E+00-1.29494161E-04-5.30733077E-10 3.73271039E-08 +-4.25675456E-16 0.00000000E+00-6.06582311E-10 0.00000000E+00 2.73813240E-14 + 2.51524477E-04 8.08569272E-19-1.37676738E-04-3.96617777E-19 9.97613725E-04 + 0.00000000E+00-5.21917193E-04 0.00000000E+00 2.51524477E-04 8.08569272E-19 +-1.37676738E-04-3.96617777E-19 9.97613725E-04 0.00000000E+00-5.21917193E-04 + 0.00000000E+00 0.00000000E+00-5.89856018E-10 0.00000000E+00 2.08398851E-14 + 1.03444229E-04-5.34594291E-10-3.78406271E-08-1.07758787E-14-4.75803478E-04 + 0.00000000E+00-1.14869473E-04 3.79272184E-19-4.75803478E-04 0.00000000E+00 +-1.14869473E-04 3.79272184E-19 0.00000000E+00 1.31388955E-08 0.00000000E+00 + 4.87327602E-14-2.56403839E-03 1.16839129E-08-7.51776382E-08-1.04677226E-14 + 9.97618518E-04 0.00000000E+00 3.99061392E-03 0.00000000E+00 2.51524777E-04 +-8.44792984E-19 1.00755797E-03-3.23318192E-18 9.97618518E-04 0.00000000E+00 + 3.99061392E-03 0.00000000E+00 2.51524777E-04-8.44792984E-19 1.00755797E-03 +-3.23318192E-18 0.00000000E+00-6.06582311E-10 0.00000000E+00 2.73813240E-14 + 1.29494161E-04-5.30733077E-10-3.73271039E-08-4.25675456E-16 9.97613725E-04 + 0.00000000E+00-5.21917193E-04 0.00000000E+00 2.51524477E-04-8.08569272E-19 +-1.37676738E-04 3.96617777E-19 9.97613725E-04 0.00000000E+00-5.21917193E-04 + 0.00000000E+00 2.51524477E-04-8.08569272E-19-1.37676738E-04 3.96617777E-19 + 1.87528055E-06 5.44214385E-21 1.11947956E-08 3.19303140E-23-1.56843504E-04 + 0.00000000E+00-9.36675536E-07 0.00000000E+00-3.78406271E-08 1.07758787E-14 + 0.00000000E+00-2.08398851E-14-3.78406271E-08 1.07758787E-14 0.00000000E+00 +-2.08398851E-14 2.16730696E-07 1.03140021E-21-2.82620199E-08-7.41415186E-23 +-1.40079352E-05 0.00000000E+00 2.39146261E-06 0.00000000E+00 1.16545900E-05 + 5.52640458E-11-7.51776382E-08 1.04677226E-14 0.00000000E+00 6.17677436E-11 + 0.00000000E+00-4.87327602E-14 1.16545900E-05 5.52640458E-11-7.51776382E-08 + 1.04677226E-14 0.00000000E+00 6.17677436E-11 0.00000000E+00-4.87327602E-14 +-1.65859214E-06-3.89855590E-21 9.98883334E-09 2.38930288E-23 1.42812876E-04 + 0.00000000E+00-8.58617942E-07 0.00000000E+00-1.25567037E-05-5.51345117E-11 +-3.73271039E-08 4.25675456E-16 0.00000000E+00-6.23498753E-11 0.00000000E+00 +-2.73813240E-14-1.25567037E-05-5.51345117E-11-3.73271039E-08 4.25675456E-16 + 0.00000000E+00-6.23498753E-11 0.00000000E+00-2.73813240E-14-2.98759875E-04 +-8.54710123E-19-1.86051828E-06-5.23555177E-21 2.49987212E-02 0.00000000E+00 + 1.55744337E-04 0.00000000E+00 1.19471728E-04 5.30024738E-10 0.00000000E+00 + 5.98679225E-10 1.19471728E-04 5.30024738E-10 0.00000000E+00 5.98679225E-10 +-1.63492905E-03-4.29551783E-18 2.16730696E-07 1.03140021E-21 1.38190515E-01 + 0.00000000E+00-1.40079352E-05 0.00000000E+00-2.25545765E-03-1.06369203E-08 +-2.56403839E-03-1.16839129E-08 0.00000000E+00-1.18986379E-08 0.00000000E+00 +-1.31388955E-08-2.25545765E-03-1.06369203E-08-2.56403839E-03-1.16839129E-08 + 0.00000000E+00-1.18986379E-08 0.00000000E+00-1.31388955E-08-2.66577079E-04 +-6.36839842E-19 1.67477331E-06 4.06779359E-21 2.29154669E-02 0.00000000E+00 +-1.43725280E-04 0.00000000E+00-2.40598848E-03-1.06153884E-08 1.13683729E-04 + 5.30917205E-10 0.00000000E+00-1.19958400E-08 0.00000000E+00 5.94987135E-10 +-2.40598848E-03-1.06153884E-08 1.13683729E-04 5.30917205E-10 0.00000000E+00 +-1.19958400E-08 0.00000000E+00 5.94987135E-10-1.56843504E-04 0.00000000E+00 +-9.36675536E-07 0.00000000E+00 1.87528055E-06-5.44214385E-21 1.11947956E-08 +-3.19303140E-23 0.00000000E+00-2.08398851E-14 3.78406271E-08 1.07758787E-14 + 0.00000000E+00-2.08398851E-14 3.78406271E-08 1.07758787E-14-1.40079352E-05 + 0.00000000E+00 2.39146261E-06 0.00000000E+00 2.16730696E-07-1.03140021E-21 +-2.82620199E-08 7.41415186E-23 0.00000000E+00 6.17677436E-11 0.00000000E+00 +-4.87327602E-14-1.16545900E-05 5.52640458E-11 7.51776382E-08 1.04677226E-14 + 0.00000000E+00 6.17677436E-11 0.00000000E+00-4.87327602E-14-1.16545900E-05 + 5.52640458E-11 7.51776382E-08 1.04677226E-14 1.42812876E-04 0.00000000E+00 +-8.58617942E-07 0.00000000E+00-1.65859214E-06 3.89855590E-21 9.98883334E-09 +-2.38930288E-23 0.00000000E+00-6.23498753E-11 0.00000000E+00-2.73813240E-14 + 1.25567037E-05-5.51345117E-11 3.73271039E-08 4.25675456E-16 0.00000000E+00 +-6.23498753E-11 0.00000000E+00-2.73813240E-14 1.25567037E-05-5.51345117E-11 + 3.73271039E-08 4.25675456E-16 0.00000000E+00 1.19958400E-08 0.00000000E+00 + 6.23498753E-11-2.40598848E-03 1.06153884E-08-1.25567037E-05 5.51345117E-11 + 9.97613725E-04 0.00000000E+00 2.51524477E-04-8.08569272E-19 9.97613725E-04 + 0.00000000E+00 2.51524477E-04-8.08569272E-19 0.00000000E+00 1.20337861E-08 + 0.00000000E+00-6.24594006E-11-2.45773183E-03 1.06147830E-08 1.27060121E-05 +-5.51328090E-11 8.35055003E-03 0.00000000E+00 1.09005505E-03 0.00000000E+00 + 2.20166244E-03-6.30932886E-18 2.99182475E-04-7.77901837E-19 8.35055003E-03 + 0.00000000E+00 1.09005505E-03 0.00000000E+00 2.20166244E-03-6.30932886E-18 + 2.99182475E-04-7.77901837E-19 2.40598848E-03 1.06153884E-08 1.25567037E-05 + 5.51345117E-11 0.00000000E+00 1.19958400E-08 0.00000000E+00 6.23498753E-11 + 2.51524477E-04 8.08569272E-19 9.97613725E-04 0.00000000E+00 2.51524477E-04 + 8.08569272E-19 9.97613725E-04 0.00000000E+00 2.45773183E-03 1.06147830E-08 +-1.27060121E-05-5.51328090E-11 0.00000000E+00 1.20337861E-08 0.00000000E+00 +-6.24594006E-11 2.20166244E-03 6.30932886E-18 2.99182475E-04 7.77901837E-19 + 8.35055003E-03 0.00000000E+00 1.09005505E-03 0.00000000E+00 2.20166244E-03 + 6.30932886E-18 2.99182475E-04 7.77901837E-19 8.35055003E-03 0.00000000E+00 + 1.09005505E-03 0.00000000E+00 0.00000000E+00 1.19958400E-08 0.00000000E+00 + 6.23498753E-11-2.40598848E-03 1.06153884E-08-1.25567037E-05 5.51345117E-11 + 9.97613725E-04 0.00000000E+00 2.51524477E-04-8.08569272E-19 1.94100279E-01 + 0.00000000E+00 3.06562634E-02-1.06812293E-16 0.00000000E+00 1.20337861E-08 + 0.00000000E+00-6.24594006E-11-2.45773183E-03 1.06147830E-08 1.27060121E-05 +-5.51328090E-11 8.35055003E-03 0.00000000E+00 1.09005505E-03 0.00000000E+00 + 2.20166244E-03-6.30932886E-18 2.99182475E-04-7.77901837E-19 1.48779255E+00 + 0.00000000E+00 1.78048251E-01 0.00000000E+00 2.45412257E-01-1.04525901E-15 + 3.06970480E-02-1.54683961E-16 3.18891877E-03 1.08946909E-08 1.66194131E-05 + 5.66260921E-11 0.00000000E+00 1.27632137E-08 0.00000000E+00 6.63601531E-11 + 4.66485193E-04 1.17511322E-18 1.37025138E-03 0.00000000E+00 3.08395779E-02 + 7.11749993E-17 1.42855211E-01 0.00000000E+00 3.23744248E-03 1.09292286E-08 +-1.67594304E-05-5.67257666E-11 0.00000000E+00 1.28225002E-08 0.00000000E+00 +-6.65312373E-11 3.98598104E-03 9.23413590E-18 5.30295395E-04 1.15961660E-18 + 1.13398450E-02 0.00000000E+00 1.46475220E-03 0.00000000E+00 2.46933143E-01 + 4.43821644E-16 3.08939460E-02 4.74640937E-17 1.10730613E+00 0.00000000E+00 + 1.34053126E-01 0.00000000E+00 2.99796244E-03 1.07762798E-08 1.56286813E-05 + 5.60034495E-11 0.00000000E+00 1.25420104E-08 0.00000000E+00 6.52068237E-11 + 4.06682403E-04 6.07413155E-19 1.27633039E-03 0.00000000E+00 3.07886470E-02 + 1.20610020E-16 1.52912176E-01 0.00000000E+00 3.04740482E-03 1.08042051E-08 +-1.57713530E-05-5.60840478E-11 0.00000000E+00 1.25974050E-08 0.00000000E+00 +-6.53666808E-11 3.49152385E-03 7.09141990E-18 4.66485513E-04 1.18096522E-18 + 1.05861923E-02 0.00000000E+00 1.37025727E-03 0.00000000E+00 2.46512296E-01 + 8.20576965E-16 3.08396676E-02 7.95757101E-17 1.18262332E+00 0.00000000E+00 + 1.42843582E-01 0.00000000E+00 2.80365502E-03 1.06863279E-08 1.46204401E-05 + 5.55272328E-11 0.00000000E+00 1.23377679E-08 0.00000000E+00 6.41406598E-11 + 3.50907835E-04 9.60342103E-19 1.18294269E-03 0.00000000E+00 3.07411005E-02 + 9.48681227E-17 1.64523745E-01 0.00000000E+00 2.85392737E-03 1.07064788E-08 +-1.47655044E-05-5.55854035E-11 0.00000000E+00 1.23884980E-08 0.00000000E+00 +-6.42870612E-11 3.02920808E-03 6.31637785E-18 4.06682674E-04 6.24656760E-19 + 9.83696822E-03 0.00000000E+00 1.27633610E-03 0.00000000E+00 2.46118381E-01 + 8.15350141E-16 3.07887371E-02 1.13511434E-16 1.26918664E+00 0.00000000E+00 + 1.52896741E-01 0.00000000E+00 2.60619933E-03 1.06302561E-08 1.35957741E-05 + 5.52251380E-11 0.00000000E+00 1.21540857E-08 0.00000000E+00 6.31800472E-11 + 2.99182429E-04 7.81594890E-19 1.09004987E-03 0.00000000E+00 3.06969586E-02 + 1.61102507E-16 1.78077196E-01 0.00000000E+00 2.65725714E-03 1.06410863E-08 +-1.37431091E-05-5.52564206E-11 0.00000000E+00 1.21991225E-08 0.00000000E+00 +-6.33100259E-11 2.59920279E-03 6.98168977E-18 3.50908122E-04 9.55982233E-19 + 9.09185545E-03 0.00000000E+00 1.18294805E-03 0.00000000E+00 2.45751613E-01 + 1.07948334E-15 3.07411896E-02 1.03529338E-16 1.36969611E+00 0.00000000E+00 + 1.64502845E-01 0.00000000E+00 2.29154669E-02 0.00000000E+00 1.42812876E-04 + 0.00000000E+00-2.66577079E-04 6.36839842E-19-1.65859214E-06 3.89855590E-21 + 0.00000000E+00 6.06582311E-10-1.29494161E-04 5.30733077E-10 0.00000000E+00 + 6.06582311E-10-1.29494161E-04 5.30733077E-10 1.27192306E-01 0.00000000E+00 +-1.17157224E-05 0.00000000E+00-1.44048393E-03 2.60608195E-18 2.36564584E-07 +-2.34005575E-21 0.00000000E+00-1.20337861E-08 0.00000000E+00-1.33009306E-08 + 2.45773183E-03-1.06147830E-08 2.78539120E-03-1.16809038E-08 0.00000000E+00 +-1.20337861E-08 0.00000000E+00-1.33009306E-08 2.45773183E-03-1.06147830E-08 + 2.78539120E-03-1.16809038E-08 2.11735114E-02 0.00000000E+00-1.32762311E-04 + 0.00000000E+00-2.31441070E-04 3.22011015E-19 1.45581460E-06-2.03544583E-21 + 0.00000000E+00-1.21540857E-08 0.00000000E+00 6.01984528E-10 2.60619933E-03 +-1.06302561E-08-1.23782000E-04 5.30185649E-10 0.00000000E+00-1.21540857E-08 + 0.00000000E+00 6.01984528E-10 2.60619933E-03-1.06302561E-08-1.23782000E-04 + 5.30185649E-10-1.13683729E-04-5.30917205E-10 3.73271039E-08-4.25675456E-16 + 0.00000000E+00-5.94987135E-10 0.00000000E+00 2.73813240E-14-1.37676738E-04 +-3.96617777E-19-5.21917193E-04 0.00000000E+00-1.53383279E-02-6.53740633E-17 +-9.30371326E-02 0.00000000E+00 2.78539120E-03 1.16809038E-08 7.41262247E-08 + 7.92732036E-15 0.00000000E+00 1.33009306E-08 0.00000000E+00 6.01757089E-14 + 2.99182475E-04 7.77901837E-19 1.19818257E-03 3.19071014E-18 1.09005505E-03 + 0.00000000E+00 4.36037303E-03 0.00000000E+00 3.06970480E-02 1.54683961E-16 + 1.22789244E-01 5.94525715E-16 1.78048251E-01 0.00000000E+00 7.13135765E-01 + 0.00000000E+00-1.39383061E-04-5.33495457E-10 3.68337430E-08 7.82065732E-15 + 0.00000000E+00-6.15746173E-10 0.00000000E+00 3.24946701E-14 2.99182429E-04 + 7.81594890E-19-1.62522638E-04-4.34394281E-19 1.09004987E-03 0.00000000E+00 +-5.68249479E-04 0.00000000E+00 3.06969586E-02 1.61102507E-16-1.53595370E-02 +-6.61579614E-17 1.78077196E-01 0.00000000E+00-8.56450101E-02 0.00000000E+00 + 0.00000000E+00-5.94987135E-10 0.00000000E+00 2.73813240E-14 1.13683729E-04 +-5.30917205E-10-3.73271039E-08-4.25675456E-16-5.21917193E-04 0.00000000E+00 +-1.37676738E-04 3.96617777E-19-9.30371326E-02 0.00000000E+00-1.53383279E-02 + 6.53740633E-17 0.00000000E+00 1.33009306E-08 0.00000000E+00 6.01757089E-14 +-2.78539120E-03 1.16809038E-08-7.41262247E-08 7.92732036E-15 1.09005505E-03 + 0.00000000E+00 4.36037303E-03 0.00000000E+00 2.99182475E-04-7.77901837E-19 + 1.19818257E-03-3.19071014E-18 1.78048251E-01 0.00000000E+00 7.13135765E-01 + 0.00000000E+00 3.06970480E-02-1.54683961E-16 1.22789244E-01-5.94525715E-16 + 0.00000000E+00-6.15746173E-10 0.00000000E+00 3.24946701E-14 1.39383061E-04 +-5.33495457E-10-3.68337430E-08 7.82065732E-15 1.09004987E-03 0.00000000E+00 +-5.68249479E-04 0.00000000E+00 2.99182429E-04-7.81594890E-19-1.62522638E-04 + 4.34394281E-19 1.78077196E-01 0.00000000E+00-8.56450101E-02 0.00000000E+00 + 3.06969586E-02-1.61102507E-16-1.53595370E-02 6.61579614E-17-1.13683729E-04 +-5.30917205E-10 3.73271039E-08-4.25675456E-16 0.00000000E+00-5.94987135E-10 + 0.00000000E+00 2.73813240E-14-1.37676738E-04-3.96617777E-19-5.21917193E-04 + 0.00000000E+00-1.37676738E-04-3.96617777E-19-5.21917193E-04 0.00000000E+00 + 2.78539120E-03 1.16809038E-08 7.41262247E-08 7.92732036E-15 0.00000000E+00 + 1.33009306E-08 0.00000000E+00 6.01757089E-14 2.99182475E-04 7.77901837E-19 + 1.19818257E-03 3.19071014E-18 1.09005505E-03 0.00000000E+00 4.36037303E-03 + 0.00000000E+00 2.99182475E-04 7.77901837E-19 1.19818257E-03 3.19071014E-18 + 1.09005505E-03 0.00000000E+00 4.36037303E-03 0.00000000E+00-1.39383061E-04 +-5.33495457E-10 3.68337430E-08 7.82065732E-15 0.00000000E+00-6.15746173E-10 + 0.00000000E+00 3.24946701E-14 2.99182429E-04 7.81594890E-19-1.62522638E-04 +-4.34394281E-19 1.09004987E-03 0.00000000E+00-5.68249479E-04 0.00000000E+00 + 2.99182429E-04 7.81594890E-19-1.62522638E-04-4.34394281E-19 1.09004987E-03 + 0.00000000E+00-5.68249479E-04 0.00000000E+00 0.00000000E+00-5.94987135E-10 + 0.00000000E+00 2.73813240E-14 1.13683729E-04-5.30917205E-10-3.73271039E-08 +-4.25675456E-16-5.21917193E-04 0.00000000E+00-1.37676738E-04 3.96617777E-19 +-5.21917193E-04 0.00000000E+00-1.37676738E-04 3.96617777E-19 0.00000000E+00 + 1.33009306E-08 0.00000000E+00 6.01757089E-14-2.78539120E-03 1.16809038E-08 +-7.41262247E-08 7.92732036E-15 1.09005505E-03 0.00000000E+00 4.36037303E-03 + 0.00000000E+00 2.99182475E-04-7.77901837E-19 1.19818257E-03-3.19071014E-18 + 1.09005505E-03 0.00000000E+00 4.36037303E-03 0.00000000E+00 2.99182475E-04 +-7.77901837E-19 1.19818257E-03-3.19071014E-18 0.00000000E+00-6.15746173E-10 + 0.00000000E+00 3.24946701E-14 1.39383061E-04-5.33495457E-10-3.68337430E-08 + 7.82065732E-15 1.09004987E-03 0.00000000E+00-5.68249479E-04 0.00000000E+00 + 2.99182429E-04-7.81594890E-19-1.62522638E-04 4.34394281E-19 1.09004987E-03 + 0.00000000E+00-5.68249479E-04 0.00000000E+00 2.99182429E-04-7.81594890E-19 +-1.62522638E-04 4.34394281E-19 1.67477331E-06 4.06779359E-21 9.98883334E-09 + 2.38930288E-23-1.43725280E-04 0.00000000E+00-8.58617942E-07 0.00000000E+00 +-3.73271039E-08 4.25675456E-16 0.00000000E+00-2.73813240E-14-3.73271039E-08 + 4.25675456E-16 0.00000000E+00-2.73813240E-14 2.36564584E-07 2.34005575E-21 +-2.48988979E-08-4.63515815E-23-1.17157224E-05 0.00000000E+00 2.20087798E-06 + 0.00000000E+00 1.27060121E-05 5.51328090E-11-7.41262247E-08-7.92732036E-15 + 0.00000000E+00 6.24594006E-11 0.00000000E+00-6.01757089E-14 1.27060121E-05 + 5.51328090E-11-7.41262247E-08-7.92732036E-15 0.00000000E+00 6.24594006E-11 + 0.00000000E+00-6.01757089E-14-1.43819357E-06-1.98694881E-21 8.67224219E-09 + 1.20257612E-23 1.31993759E-04 0.00000000E+00-7.93347449E-07 0.00000000E+00 +-1.35957741E-05-5.52251380E-11-3.68337430E-08-7.82065732E-15 0.00000000E+00 +-6.31800472E-11 0.00000000E+00-3.24946701E-14-1.35957741E-05-5.52251380E-11 +-3.68337430E-08-7.82065732E-15 0.00000000E+00-6.31800472E-11 0.00000000E+00 +-3.24946701E-14-2.66577079E-04-6.36839842E-19-1.65859214E-06-3.89855590E-21 + 2.29154669E-02 0.00000000E+00 1.42812876E-04 0.00000000E+00 1.29494161E-04 + 5.30733077E-10 0.00000000E+00 6.06582311E-10 1.29494161E-04 5.30733077E-10 + 0.00000000E+00 6.06582311E-10-1.44048393E-03-2.60608195E-18 2.36564584E-07 + 2.34005575E-21 1.27192306E-01 0.00000000E+00-1.17157224E-05 0.00000000E+00 +-2.45773183E-03-1.06147830E-08-2.78539120E-03-1.16809038E-08 0.00000000E+00 +-1.20337861E-08 0.00000000E+00-1.33009306E-08-2.45773183E-03-1.06147830E-08 +-2.78539120E-03-1.16809038E-08 0.00000000E+00-1.20337861E-08 0.00000000E+00 +-1.33009306E-08-2.31441070E-04-3.22011015E-19 1.45581460E-06 2.03544583E-21 + 2.11735114E-02 0.00000000E+00-1.32762311E-04 0.00000000E+00-2.60619933E-03 +-1.06302561E-08 1.23782000E-04 5.30185649E-10 0.00000000E+00-1.21540857E-08 + 0.00000000E+00 6.01984528E-10-2.60619933E-03-1.06302561E-08 1.23782000E-04 + 5.30185649E-10 0.00000000E+00-1.21540857E-08 0.00000000E+00 6.01984528E-10 +-1.43725280E-04 0.00000000E+00-8.58617942E-07 0.00000000E+00 1.67477331E-06 +-4.06779359E-21 9.98883334E-09-2.38930288E-23 0.00000000E+00-2.73813240E-14 + 3.73271039E-08 4.25675456E-16 0.00000000E+00-2.73813240E-14 3.73271039E-08 + 4.25675456E-16-1.17157224E-05 0.00000000E+00 2.20087798E-06 0.00000000E+00 + 2.36564584E-07-2.34005575E-21-2.48988979E-08 4.63515815E-23 0.00000000E+00 + 6.24594006E-11 0.00000000E+00-6.01757089E-14-1.27060121E-05 5.51328090E-11 + 7.41262247E-08-7.92732036E-15 0.00000000E+00 6.24594006E-11 0.00000000E+00 +-6.01757089E-14-1.27060121E-05 5.51328090E-11 7.41262247E-08-7.92732036E-15 + 1.31993759E-04 0.00000000E+00-7.93347449E-07 0.00000000E+00-1.43819357E-06 + 1.98694881E-21 8.67224219E-09-1.20257612E-23 0.00000000E+00-6.31800472E-11 + 0.00000000E+00-3.24946701E-14 1.35957741E-05-5.52251380E-11 3.68337430E-08 +-7.82065732E-15 0.00000000E+00-6.31800472E-11 0.00000000E+00-3.24946701E-14 + 1.35957741E-05-5.52251380E-11 3.68337430E-08-7.82065732E-15 0.00000000E+00 + 1.21540857E-08 0.00000000E+00 6.31800472E-11-2.60619933E-03 1.06302561E-08 +-1.35957741E-05 5.52251380E-11 1.09004987E-03 0.00000000E+00 2.99182429E-04 +-7.81594890E-19 1.09004987E-03 0.00000000E+00 2.99182429E-04-7.81594890E-19 + 0.00000000E+00 1.21991225E-08 0.00000000E+00-6.33100259E-11-2.65725714E-03 + 1.06410863E-08 1.37431091E-05-5.52564206E-11 9.09185545E-03 0.00000000E+00 + 1.18294805E-03 0.00000000E+00 2.59920279E-03-6.98168977E-18 3.50908122E-04 +-9.55982233E-19 9.09185545E-03 0.00000000E+00 1.18294805E-03 0.00000000E+00 + 2.59920279E-03-6.98168977E-18 3.50908122E-04-9.55982233E-19 2.60619933E-03 + 1.06302561E-08 1.35957741E-05 5.52251380E-11 0.00000000E+00 1.21540857E-08 + 0.00000000E+00 6.31800472E-11 2.99182429E-04 7.81594890E-19 1.09004987E-03 + 0.00000000E+00 2.99182429E-04 7.81594890E-19 1.09004987E-03 0.00000000E+00 + 2.65725714E-03 1.06410863E-08-1.37431091E-05-5.52564206E-11 0.00000000E+00 + 1.21991225E-08 0.00000000E+00-6.33100259E-11 2.59920279E-03 6.98168977E-18 + 3.50908122E-04 9.55982233E-19 9.09185545E-03 0.00000000E+00 1.18294805E-03 + 0.00000000E+00 2.59920279E-03 6.98168977E-18 3.50908122E-04 9.55982233E-19 + 9.09185545E-03 0.00000000E+00 1.18294805E-03 0.00000000E+00 0.00000000E+00 + 1.21540857E-08 0.00000000E+00 6.31800472E-11-2.60619933E-03 1.06302561E-08 +-1.35957741E-05 5.52251380E-11 1.09004987E-03 0.00000000E+00 2.99182429E-04 +-7.81594890E-19 1.78077196E-01 0.00000000E+00 3.06969586E-02-1.61102507E-16 + 0.00000000E+00 1.21991225E-08 0.00000000E+00-6.33100259E-11-2.65725714E-03 + 1.06410863E-08 1.37431091E-05-5.52564206E-11 9.09185545E-03 0.00000000E+00 + 1.18294805E-03 0.00000000E+00 2.59920279E-03-6.98168977E-18 3.50908122E-04 +-9.55982233E-19 1.36969611E+00 0.00000000E+00 1.64502845E-01 0.00000000E+00 + 2.45751613E-01-1.07948334E-15 3.07411896E-02-1.03529338E-16 2.11735114E-02 + 0.00000000E+00 1.31993759E-04 0.00000000E+00-2.31441070E-04 3.22011015E-19 +-1.43819357E-06 1.98694881E-21 0.00000000E+00 6.15746173E-10-1.39383061E-04 + 5.33495457E-10 0.00000000E+00 6.15746173E-10-1.39383061E-04 5.33495457E-10 + 1.17932426E-01 0.00000000E+00-9.93154514E-06 0.00000000E+00-1.22883562E-03 + 1.98967238E-18 2.56638929E-07 8.99672587E-22 0.00000000E+00-1.21991225E-08 + 0.00000000E+00-1.34933643E-08 2.65725714E-03-1.06410863E-08 3.00377068E-03 +-1.17269246E-08 0.00000000E+00-1.21991225E-08 0.00000000E+00-1.34933643E-08 + 2.65725714E-03-1.06410863E-08 3.00377068E-03-1.17269246E-08 1.96970843E-02 + 0.00000000E+00-1.23474852E-04 0.00000000E+00-1.93327000E-04 4.36357554E-19 + 1.21822554E-06-2.67571767E-21 0.00000000E+00-1.23377679E-08 0.00000000E+00 + 6.10434553E-10 2.80365502E-03-1.06863279E-08-1.33754480E-04 5.31788420E-10 + 0.00000000E+00-1.23377679E-08 0.00000000E+00 6.10434553E-10 2.80365502E-03 +-1.06863279E-08-1.33754480E-04 5.31788420E-10-1.23782000E-04-5.30185649E-10 + 3.68337430E-08 7.82065732E-15 0.00000000E+00-6.01984528E-10 0.00000000E+00 + 3.24946701E-14-1.62522638E-04-4.34394281E-19-5.68249479E-04 0.00000000E+00 +-1.53595370E-02-6.61579614E-17-8.56450101E-02 0.00000000E+00 3.00377068E-03 + 1.17269246E-08 7.31133971E-08 2.27169273E-14 0.00000000E+00 1.34933643E-08 + 0.00000000E+00 6.92939239E-14 3.50908122E-04 9.55982233E-19 1.40507799E-03 + 3.65845871E-18 1.18294805E-03 0.00000000E+00 4.73195837E-03 0.00000000E+00 + 3.07411896E-02 1.03529338E-16 1.22965796E-01 4.22745897E-16 1.64502845E-01 + 0.00000000E+00 6.58748651E-01 0.00000000E+00-1.49115465E-04-5.37946105E-10 + 3.62660783E-08 1.45426791E-14 0.00000000E+00-6.25935734E-10 0.00000000E+00 + 3.66003485E-14 3.50907835E-04 9.60342103E-19-1.89397627E-04-3.96249716E-19 + 1.18294269E-03 0.00000000E+00-6.14819697E-04 0.00000000E+00 3.07411005E-02 + 9.48681227E-17-1.53824594E-02-5.20948891E-17 1.64523745E-01 0.00000000E+00 +-7.93551215E-02 0.00000000E+00 0.00000000E+00-6.01984528E-10 0.00000000E+00 + 3.24946701E-14 1.23782000E-04-5.30185649E-10-3.68337430E-08 7.82065732E-15 +-5.68249479E-04 0.00000000E+00-1.62522638E-04 4.34394281E-19-8.56450101E-02 + 0.00000000E+00-1.53595370E-02 6.61579614E-17 0.00000000E+00 1.34933643E-08 + 0.00000000E+00 6.92939239E-14-3.00377068E-03 1.17269246E-08-7.31133971E-08 + 2.27169273E-14 1.18294805E-03 0.00000000E+00 4.73195837E-03 0.00000000E+00 + 3.50908122E-04-9.55982233E-19 1.40507799E-03-3.65845871E-18 1.64502845E-01 + 0.00000000E+00 6.58748651E-01 0.00000000E+00 3.07411896E-02-1.03529338E-16 + 1.22965796E-01-4.22745897E-16 0.00000000E+00-6.25935734E-10 0.00000000E+00 + 3.66003485E-14 1.49115465E-04-5.37946105E-10-3.62660783E-08 1.45426791E-14 + 1.18294269E-03 0.00000000E+00-6.14819697E-04 0.00000000E+00 3.50907835E-04 +-9.60342103E-19-1.89397627E-04 3.96249716E-19 1.64523745E-01 0.00000000E+00 +-7.93551215E-02 0.00000000E+00 3.07411005E-02-9.48681227E-17-1.53824594E-02 + 5.20948891E-17-1.23782000E-04-5.30185649E-10 3.68337430E-08 7.82065732E-15 + 0.00000000E+00-6.01984528E-10 0.00000000E+00 3.24946701E-14-1.62522638E-04 +-4.34394281E-19-5.68249479E-04 0.00000000E+00-1.62522638E-04-4.34394281E-19 +-5.68249479E-04 0.00000000E+00 3.00377068E-03 1.17269246E-08 7.31133971E-08 + 2.27169273E-14 0.00000000E+00 1.34933643E-08 0.00000000E+00 6.92939239E-14 + 3.50908122E-04 9.55982233E-19 1.40507799E-03 3.65845871E-18 1.18294805E-03 + 0.00000000E+00 4.73195837E-03 0.00000000E+00 3.50908122E-04 9.55982233E-19 + 1.40507799E-03 3.65845871E-18 1.18294805E-03 0.00000000E+00 4.73195837E-03 + 0.00000000E+00-1.49115465E-04-5.37946105E-10 3.62660783E-08 1.45426791E-14 + 0.00000000E+00-6.25935734E-10 0.00000000E+00 3.66003485E-14 3.50907835E-04 + 9.60342103E-19-1.89397627E-04-3.96249716E-19 1.18294269E-03 0.00000000E+00 +-6.14819697E-04 0.00000000E+00 3.50907835E-04 9.60342103E-19-1.89397627E-04 +-3.96249716E-19 1.18294269E-03 0.00000000E+00-6.14819697E-04 0.00000000E+00 + 0.00000000E+00-6.01984528E-10 0.00000000E+00 3.24946701E-14 1.23782000E-04 +-5.30185649E-10-3.68337430E-08 7.82065732E-15-5.68249479E-04 0.00000000E+00 +-1.62522638E-04 4.34394281E-19-5.68249479E-04 0.00000000E+00-1.62522638E-04 + 4.34394281E-19 0.00000000E+00 1.34933643E-08 0.00000000E+00 6.92939239E-14 +-3.00377068E-03 1.17269246E-08-7.31133971E-08 2.27169273E-14 1.18294805E-03 + 0.00000000E+00 4.73195837E-03 0.00000000E+00 3.50908122E-04-9.55982233E-19 + 1.40507799E-03-3.65845871E-18 1.18294805E-03 0.00000000E+00 4.73195837E-03 + 0.00000000E+00 3.50908122E-04-9.55982233E-19 1.40507799E-03-3.65845871E-18 + 0.00000000E+00-6.25935734E-10 0.00000000E+00 3.66003485E-14 1.49115465E-04 +-5.37946105E-10-3.62660783E-08 1.45426791E-14 1.18294269E-03 0.00000000E+00 +-6.14819697E-04 0.00000000E+00 3.50907835E-04-9.60342103E-19-1.89397627E-04 + 3.96249716E-19 1.18294269E-03 0.00000000E+00-6.14819697E-04 0.00000000E+00 + 3.50907835E-04-9.60342103E-19-1.89397627E-04 3.96249716E-19 1.45581460E-06 + 2.03544583E-21 8.67224219E-09 1.20257612E-23-1.32762311E-04 0.00000000E+00 +-7.93347449E-07 0.00000000E+00-3.68337430E-08-7.82065732E-15 0.00000000E+00 +-3.24946701E-14-3.68337430E-08-7.82065732E-15 0.00000000E+00-3.24946701E-14 + 2.56638929E-07-8.99672587E-22-2.12388894E-08-3.59242823E-23-9.93154514E-06 + 0.00000000E+00 2.04046141E-06 0.00000000E+00 1.37431091E-05 5.52564206E-11 +-7.31133971E-08-2.27169273E-14 0.00000000E+00 6.33100259E-11 0.00000000E+00 +-6.92939239E-14 1.37431091E-05 5.52564206E-11-7.31133971E-08-2.27169273E-14 + 0.00000000E+00 6.33100259E-11 0.00000000E+00-6.92939239E-14-1.19918918E-06 +-2.78189374E-21 7.24407438E-09 1.63629852E-23 1.22819330E-04 0.00000000E+00 +-7.38025543E-07 0.00000000E+00-1.46204401E-05-5.55272328E-11-3.62660783E-08 +-1.45426791E-14 0.00000000E+00-6.41406598E-11 0.00000000E+00-3.66003485E-14 +-1.46204401E-05-5.55272328E-11-3.62660783E-08-1.45426791E-14 0.00000000E+00 +-6.41406598E-11 0.00000000E+00-3.66003485E-14-2.31441070E-04-3.22011015E-19 +-1.43819357E-06-1.98694881E-21 2.11735114E-02 0.00000000E+00 1.31993759E-04 + 0.00000000E+00 1.39383061E-04 5.33495457E-10 0.00000000E+00 6.15746173E-10 + 1.39383061E-04 5.33495457E-10 0.00000000E+00 6.15746173E-10-1.22883562E-03 +-1.98967238E-18 2.56638929E-07-8.99672587E-22 1.17932426E-01 0.00000000E+00 +-9.93154514E-06 0.00000000E+00-2.65725714E-03-1.06410863E-08-3.00377068E-03 +-1.17269246E-08 0.00000000E+00-1.21991225E-08 0.00000000E+00-1.34933643E-08 +-2.65725714E-03-1.06410863E-08-3.00377068E-03-1.17269246E-08 0.00000000E+00 +-1.21991225E-08 0.00000000E+00-1.34933643E-08-1.93327000E-04-4.36357554E-19 + 1.21822554E-06 2.67571767E-21 1.96970843E-02 0.00000000E+00-1.23474852E-04 + 0.00000000E+00-2.80365502E-03-1.06863279E-08 1.33754480E-04 5.31788420E-10 + 0.00000000E+00-1.23377679E-08 0.00000000E+00 6.10434553E-10-2.80365502E-03 +-1.06863279E-08 1.33754480E-04 5.31788420E-10 0.00000000E+00-1.23377679E-08 + 0.00000000E+00 6.10434553E-10-1.32762311E-04 0.00000000E+00-7.93347449E-07 + 0.00000000E+00 1.45581460E-06-2.03544583E-21 8.67224219E-09-1.20257612E-23 + 0.00000000E+00-3.24946701E-14 3.68337430E-08-7.82065732E-15 0.00000000E+00 +-3.24946701E-14 3.68337430E-08-7.82065732E-15-9.93154514E-06 0.00000000E+00 + 2.04046141E-06 0.00000000E+00 2.56638929E-07 8.99672587E-22-2.12388894E-08 + 3.59242823E-23 0.00000000E+00 6.33100259E-11 0.00000000E+00-6.92939239E-14 +-1.37431091E-05 5.52564206E-11 7.31133971E-08-2.27169273E-14 0.00000000E+00 + 6.33100259E-11 0.00000000E+00-6.92939239E-14-1.37431091E-05 5.52564206E-11 + 7.31133971E-08-2.27169273E-14 1.22819330E-04 0.00000000E+00-7.38025543E-07 + 0.00000000E+00-1.19918918E-06 2.78189374E-21 7.24407438E-09-1.63629852E-23 + 0.00000000E+00-6.41406598E-11 0.00000000E+00-3.66003485E-14 1.46204401E-05 +-5.55272328E-11 3.62660783E-08-1.45426791E-14 0.00000000E+00-6.41406598E-11 + 0.00000000E+00-3.66003485E-14 1.46204401E-05-5.55272328E-11 3.62660783E-08 +-1.45426791E-14 0.00000000E+00 1.23377679E-08 0.00000000E+00 6.41406598E-11 +-2.80365502E-03 1.06863279E-08-1.46204401E-05 5.55272328E-11 1.18294269E-03 + 0.00000000E+00 3.50907835E-04-9.60342103E-19 1.18294269E-03 0.00000000E+00 + 3.50907835E-04-9.60342103E-19 0.00000000E+00 1.23884980E-08 0.00000000E+00 +-6.42870612E-11-2.85392737E-03 1.07064788E-08 1.47655044E-05-5.55854035E-11 + 9.83696822E-03 0.00000000E+00 1.27633610E-03 0.00000000E+00 3.02920808E-03 +-6.31637785E-18 4.06682674E-04-6.24656760E-19 9.83696822E-03 0.00000000E+00 + 1.27633610E-03 0.00000000E+00 3.02920808E-03-6.31637785E-18 4.06682674E-04 +-6.24656760E-19 2.80365502E-03 1.06863279E-08 1.46204401E-05 5.55272328E-11 + 0.00000000E+00 1.23377679E-08 0.00000000E+00 6.41406598E-11 3.50907835E-04 + 9.60342103E-19 1.18294269E-03 0.00000000E+00 3.50907835E-04 9.60342103E-19 + 1.18294269E-03 0.00000000E+00 2.85392737E-03 1.07064788E-08-1.47655044E-05 +-5.55854035E-11 0.00000000E+00 1.23884980E-08 0.00000000E+00-6.42870612E-11 + 3.02920808E-03 6.31637785E-18 4.06682674E-04 6.24656760E-19 9.83696822E-03 + 0.00000000E+00 1.27633610E-03 0.00000000E+00 3.02920808E-03 6.31637785E-18 + 4.06682674E-04 6.24656760E-19 9.83696822E-03 0.00000000E+00 1.27633610E-03 + 0.00000000E+00 0.00000000E+00 1.23377679E-08 0.00000000E+00 6.41406598E-11 +-2.80365502E-03 1.06863279E-08-1.46204401E-05 5.55272328E-11 1.18294269E-03 + 0.00000000E+00 3.50907835E-04-9.60342103E-19 1.64523745E-01 0.00000000E+00 + 3.07411005E-02-9.48681227E-17 0.00000000E+00 1.23884980E-08 0.00000000E+00 +-6.42870612E-11-2.85392737E-03 1.07064788E-08 1.47655044E-05-5.55854035E-11 + 9.83696822E-03 0.00000000E+00 1.27633610E-03 0.00000000E+00 3.02920808E-03 +-6.31637785E-18 4.06682674E-04-6.24656760E-19 1.26918664E+00 0.00000000E+00 + 1.52896741E-01 0.00000000E+00 2.46118381E-01-8.15350141E-16 3.07887371E-02 +-1.13511434E-16 1.96970843E-02 0.00000000E+00 1.22819330E-04 0.00000000E+00 +-1.93327000E-04 4.36357554E-19-1.19918918E-06 2.78189374E-21 0.00000000E+00 + 6.25935734E-10-1.49115465E-04 5.37946105E-10 0.00000000E+00 6.25935734E-10 +-1.49115465E-04 5.37946105E-10 1.10037634E-01 0.00000000E+00-8.51669741E-06 + 0.00000000E+00-1.00005509E-03 2.75426384E-18 2.76751843E-07-2.09819154E-22 + 0.00000000E+00-1.23884980E-08 0.00000000E+00-1.37102019E-08 2.85392737E-03 +-1.07064788E-08 3.21881849E-03-1.18128872E-08 0.00000000E+00-1.23884980E-08 + 0.00000000E+00-1.37102019E-08 2.85392737E-03-1.07064788E-08 3.21881849E-03 +-1.18128872E-08 1.84311727E-02 0.00000000E+00-1.15514818E-04 0.00000000E+00 +-1.52222884E-04 4.22038138E-19 9.61969799E-07-2.67287295E-21 0.00000000E+00 +-1.25420104E-08 0.00000000E+00 6.20045796E-10 2.99796244E-03-1.07762798E-08 +-1.43575629E-04 5.35285289E-10 0.00000000E+00-1.25420104E-08 0.00000000E+00 + 6.20045796E-10 2.99796244E-03-1.07762798E-08-1.43575629E-04 5.35285289E-10 +-1.33754480E-04-5.31788420E-10 3.62660783E-08 1.45426791E-14 0.00000000E+00 +-6.10434553E-10 0.00000000E+00 3.66003485E-14-1.89397627E-04-3.96249716E-19 +-6.14819697E-04 0.00000000E+00-1.53824594E-02-5.20948891E-17-7.93551215E-02 + 0.00000000E+00 3.21881849E-03 1.18128872E-08 7.19203836E-08 3.49336857E-14 + 0.00000000E+00 1.37102019E-08 0.00000000E+00 7.66833622E-14 4.06682674E-04 + 6.24656760E-19 1.62816875E-03 2.77288010E-18 1.27633610E-03 0.00000000E+00 + 5.10552352E-03 0.00000000E+00 3.07887371E-02 1.13511434E-16 1.23155977E-01 + 4.48073193E-16 1.52896741E-01 0.00000000E+00 6.12174400E-01 0.00000000E+00 +-1.58683069E-04-5.43818346E-10 3.56679367E-08 2.01495625E-14 0.00000000E+00 +-6.36972165E-10 0.00000000E+00 3.99642700E-14 4.06682403E-04 6.07413155E-19 +-2.18291979E-04-4.47094593E-19 1.27633039E-03 0.00000000E+00-6.61646915E-04 + 0.00000000E+00 3.07886470E-02 1.20610020E-16-1.54070787E-02-5.00464325E-17 + 1.52912176E-01 0.00000000E+00-7.39389393E-02 0.00000000E+00 0.00000000E+00 +-6.10434553E-10 0.00000000E+00 3.66003485E-14 1.33754480E-04-5.31788420E-10 +-3.62660783E-08 1.45426791E-14-6.14819697E-04 0.00000000E+00-1.89397627E-04 + 3.96249716E-19-7.93551215E-02 0.00000000E+00-1.53824594E-02 5.20948891E-17 + 0.00000000E+00 1.37102019E-08 0.00000000E+00 7.66833622E-14-3.21881849E-03 + 1.18128872E-08-7.19203836E-08 3.49336857E-14 1.27633610E-03 0.00000000E+00 + 5.10552352E-03 0.00000000E+00 4.06682674E-04-6.24656760E-19 1.62816875E-03 +-2.77288010E-18 1.52896741E-01 0.00000000E+00 6.12174400E-01 0.00000000E+00 + 3.07887371E-02-1.13511434E-16 1.23155977E-01-4.48073193E-16 0.00000000E+00 +-6.36972165E-10 0.00000000E+00 3.99642700E-14 1.58683069E-04-5.43818346E-10 +-3.56679367E-08 2.01495625E-14 1.27633039E-03 0.00000000E+00-6.61646915E-04 + 0.00000000E+00 4.06682403E-04-6.07413155E-19-2.18291979E-04 4.47094593E-19 + 1.52912176E-01 0.00000000E+00-7.39389393E-02 0.00000000E+00 3.07886470E-02 +-1.20610020E-16-1.54070787E-02 5.00464325E-17-1.33754480E-04-5.31788420E-10 + 3.62660783E-08 1.45426791E-14 0.00000000E+00-6.10434553E-10 0.00000000E+00 + 3.66003485E-14-1.89397627E-04-3.96249716E-19-6.14819697E-04 0.00000000E+00 +-1.89397627E-04-3.96249716E-19-6.14819697E-04 0.00000000E+00 3.21881849E-03 + 1.18128872E-08 7.19203836E-08 3.49336857E-14 0.00000000E+00 1.37102019E-08 + 0.00000000E+00 7.66833622E-14 4.06682674E-04 6.24656760E-19 1.62816875E-03 + 2.77288010E-18 1.27633610E-03 0.00000000E+00 5.10552352E-03 0.00000000E+00 + 4.06682674E-04 6.24656760E-19 1.62816875E-03 2.77288010E-18 1.27633610E-03 + 0.00000000E+00 5.10552352E-03 0.00000000E+00-1.58683069E-04-5.43818346E-10 + 3.56679367E-08 2.01495625E-14 0.00000000E+00-6.36972165E-10 0.00000000E+00 + 3.99642700E-14 4.06682403E-04 6.07413155E-19-2.18291979E-04-4.47094593E-19 + 1.27633039E-03 0.00000000E+00-6.61646915E-04 0.00000000E+00 4.06682403E-04 + 6.07413155E-19-2.18291979E-04-4.47094593E-19 1.27633039E-03 0.00000000E+00 +-6.61646915E-04 0.00000000E+00 0.00000000E+00-6.10434553E-10 0.00000000E+00 + 3.66003485E-14 1.33754480E-04-5.31788420E-10-3.62660783E-08 1.45426791E-14 +-6.14819697E-04 0.00000000E+00-1.89397627E-04 3.96249716E-19-6.14819697E-04 + 0.00000000E+00-1.89397627E-04 3.96249716E-19 0.00000000E+00 1.37102019E-08 + 0.00000000E+00 7.66833622E-14-3.21881849E-03 1.18128872E-08-7.19203836E-08 + 3.49336857E-14 1.27633610E-03 0.00000000E+00 5.10552352E-03 0.00000000E+00 + 4.06682674E-04-6.24656760E-19 1.62816875E-03-2.77288010E-18 1.27633610E-03 + 0.00000000E+00 5.10552352E-03 0.00000000E+00 4.06682674E-04-6.24656760E-19 + 1.62816875E-03-2.77288010E-18 0.00000000E+00-6.36972165E-10 0.00000000E+00 + 3.99642700E-14 1.58683069E-04-5.43818346E-10-3.56679367E-08 2.01495625E-14 + 1.27633039E-03 0.00000000E+00-6.61646915E-04 0.00000000E+00 4.06682403E-04 +-6.07413155E-19-2.18291979E-04 4.47094593E-19 1.27633039E-03 0.00000000E+00 +-6.61646915E-04 0.00000000E+00 4.06682403E-04-6.07413155E-19-2.18291979E-04 + 4.47094593E-19 1.21822554E-06 2.67571767E-21 7.24407438E-09 1.63629852E-23 +-1.23474852E-04 0.00000000E+00-7.38025543E-07 0.00000000E+00-3.62660783E-08 +-1.45426791E-14 0.00000000E+00-3.66003485E-14-3.62660783E-08-1.45426791E-14 + 0.00000000E+00-3.66003485E-14 2.76751843E-07 2.09819154E-22-1.72817519E-08 +-4.52516541E-23-8.51669741E-06 0.00000000E+00 1.90372586E-06 0.00000000E+00 + 1.47655044E-05 5.55854035E-11-7.19203836E-08-3.49336857E-14 0.00000000E+00 + 6.42870612E-11 0.00000000E+00-7.66833622E-14 1.47655044E-05 5.55854035E-11 +-7.19203836E-08-3.49336857E-14 0.00000000E+00 6.42870612E-11 0.00000000E+00 +-7.66833622E-14-9.41466737E-07-2.60024549E-21 5.70389214E-09 1.57735176E-23 + 1.14949796E-04 0.00000000E+00-6.90591171E-07 0.00000000E+00-1.56286813E-05 +-5.60034495E-11-3.56679367E-08-2.01495625E-14 0.00000000E+00-6.52068237E-11 + 0.00000000E+00-3.99642700E-14-1.56286813E-05-5.60034495E-11-3.56679367E-08 +-2.01495625E-14 0.00000000E+00-6.52068237E-11 0.00000000E+00-3.99642700E-14 +-1.93327000E-04-4.36357554E-19-1.19918918E-06-2.78189374E-21 1.96970843E-02 + 0.00000000E+00 1.22819330E-04 0.00000000E+00 1.49115465E-04 5.37946105E-10 + 0.00000000E+00 6.25935734E-10 1.49115465E-04 5.37946105E-10 0.00000000E+00 + 6.25935734E-10-1.00005509E-03-2.75426384E-18 2.76751843E-07 2.09819154E-22 + 1.10037634E-01 0.00000000E+00-8.51669741E-06 0.00000000E+00-2.85392737E-03 +-1.07064788E-08-3.21881849E-03-1.18128872E-08 0.00000000E+00-1.23884980E-08 + 0.00000000E+00-1.37102019E-08-2.85392737E-03-1.07064788E-08-3.21881849E-03 +-1.18128872E-08 0.00000000E+00-1.23884980E-08 0.00000000E+00-1.37102019E-08 +-1.52222884E-04-4.22038138E-19 9.61969799E-07 2.67287295E-21 1.84311727E-02 + 0.00000000E+00-1.15514818E-04 0.00000000E+00-2.99796244E-03-1.07762798E-08 + 1.43575629E-04 5.35285289E-10 0.00000000E+00-1.25420104E-08 0.00000000E+00 + 6.20045796E-10-2.99796244E-03-1.07762798E-08 1.43575629E-04 5.35285289E-10 + 0.00000000E+00-1.25420104E-08 0.00000000E+00 6.20045796E-10-1.23474852E-04 + 0.00000000E+00-7.38025543E-07 0.00000000E+00 1.21822554E-06-2.67571767E-21 + 7.24407438E-09-1.63629852E-23 0.00000000E+00-3.66003485E-14 3.62660783E-08 +-1.45426791E-14 0.00000000E+00-3.66003485E-14 3.62660783E-08-1.45426791E-14 +-8.51669741E-06 0.00000000E+00 1.90372586E-06 0.00000000E+00 2.76751843E-07 +-2.09819154E-22-1.72817519E-08 4.52516541E-23 0.00000000E+00 6.42870612E-11 + 0.00000000E+00-7.66833622E-14-1.47655044E-05 5.55854035E-11 7.19203836E-08 +-3.49336857E-14 0.00000000E+00 6.42870612E-11 0.00000000E+00-7.66833622E-14 +-1.47655044E-05 5.55854035E-11 7.19203836E-08-3.49336857E-14 1.14949796E-04 + 0.00000000E+00-6.90591171E-07 0.00000000E+00-9.41466737E-07 2.60024549E-21 + 5.70389214E-09-1.57735176E-23 0.00000000E+00-6.52068237E-11 0.00000000E+00 +-3.99642700E-14 1.56286813E-05-5.60034495E-11 3.56679367E-08-2.01495625E-14 + 0.00000000E+00-6.52068237E-11 0.00000000E+00-3.99642700E-14 1.56286813E-05 +-5.60034495E-11 3.56679367E-08-2.01495625E-14 0.00000000E+00 1.25420104E-08 + 0.00000000E+00 6.52068237E-11-2.99796244E-03 1.07762798E-08-1.56286813E-05 + 5.60034495E-11 1.27633039E-03 0.00000000E+00 4.06682403E-04-6.07413155E-19 + 1.27633039E-03 0.00000000E+00 4.06682403E-04-6.07413155E-19 0.00000000E+00 + 1.25974050E-08 0.00000000E+00-6.53666808E-11-3.04740482E-03 1.08042051E-08 + 1.57713530E-05-5.60840478E-11 1.05861923E-02 0.00000000E+00 1.37025727E-03 + 0.00000000E+00 3.49152385E-03-7.09141990E-18 4.66485513E-04-1.18096522E-18 + 1.05861923E-02 0.00000000E+00 1.37025727E-03 0.00000000E+00 3.49152385E-03 +-7.09141990E-18 4.66485513E-04-1.18096522E-18 2.99796244E-03 1.07762798E-08 + 1.56286813E-05 5.60034495E-11 0.00000000E+00 1.25420104E-08 0.00000000E+00 + 6.52068237E-11 4.06682403E-04 6.07413155E-19 1.27633039E-03 0.00000000E+00 + 4.06682403E-04 6.07413155E-19 1.27633039E-03 0.00000000E+00 3.04740482E-03 + 1.08042051E-08-1.57713530E-05-5.60840478E-11 0.00000000E+00 1.25974050E-08 + 0.00000000E+00-6.53666808E-11 3.49152385E-03 7.09141990E-18 4.66485513E-04 + 1.18096522E-18 1.05861923E-02 0.00000000E+00 1.37025727E-03 0.00000000E+00 + 3.49152385E-03 7.09141990E-18 4.66485513E-04 1.18096522E-18 1.05861923E-02 + 0.00000000E+00 1.37025727E-03 0.00000000E+00 0.00000000E+00 1.25420104E-08 + 0.00000000E+00 6.52068237E-11-2.99796244E-03 1.07762798E-08-1.56286813E-05 + 5.60034495E-11 1.27633039E-03 0.00000000E+00 4.06682403E-04-6.07413155E-19 + 1.52912176E-01 0.00000000E+00 3.07886470E-02-1.20610020E-16 0.00000000E+00 + 1.25974050E-08 0.00000000E+00-6.53666808E-11-3.04740482E-03 1.08042051E-08 + 1.57713530E-05-5.60840478E-11 1.05861923E-02 0.00000000E+00 1.37025727E-03 + 0.00000000E+00 3.49152385E-03-7.09141990E-18 4.66485513E-04-1.18096522E-18 + 1.18262332E+00 0.00000000E+00 1.42843582E-01 0.00000000E+00 2.46512296E-01 +-8.20576965E-16 3.08396676E-02-7.95757101E-17 1.84311727E-02 0.00000000E+00 + 1.14949796E-04 0.00000000E+00-1.52222884E-04 4.22038138E-19-9.41466737E-07 + 2.60024549E-21 0.00000000E+00 6.36972165E-10-1.58683069E-04 5.43818346E-10 + 0.00000000E+00 6.36972165E-10-1.58683069E-04 5.43818346E-10 1.03234703E-01 + 0.00000000E+00-7.37537209E-06 0.00000000E+00-7.53806080E-04 3.05249244E-18 + 2.97032093E-07 3.30378404E-21 0.00000000E+00-1.25974050E-08 0.00000000E+00 +-1.39470238E-08 3.04740482E-03-1.08042051E-08 3.43029201E-03-1.19321554E-08 + 0.00000000E+00-1.25974050E-08 0.00000000E+00-1.39470238E-08 3.04740482E-03 +-1.08042051E-08 3.43029201E-03-1.19321554E-08 1.73350316E-02 0.00000000E+00 +-1.08624704E-04 0.00000000E+00-1.08107595E-04 8.66002379E-19 6.86869346E-07 +-5.23105304E-21 0.00000000E+00-1.27632137E-08 0.00000000E+00 6.30604955E-10 + 3.18891877E-03-1.08946909E-08-1.53240554E-04 5.40355350E-10 0.00000000E+00 +-1.27632137E-08 0.00000000E+00 6.30604955E-10 3.18891877E-03-1.08946909E-08 +-1.53240554E-04 5.40355350E-10-1.43575629E-04-5.35285289E-10 3.56679367E-08 + 2.01495625E-14 0.00000000E+00-6.20045796E-10 0.00000000E+00 3.99642700E-14 +-2.18291979E-04-4.47094593E-19-6.61646915E-04 0.00000000E+00-1.54070787E-02 +-5.00464325E-17-7.39389393E-02 0.00000000E+00 3.43029201E-03 1.19321554E-08 + 7.06622747E-08 4.52286578E-14 0.00000000E+00 1.39470238E-08 0.00000000E+00 + 8.28002445E-14 4.66485513E-04 1.18096522E-18 1.86737241E-03 4.52258903E-18 + 1.37025727E-03 0.00000000E+00 5.48122226E-03 0.00000000E+00 3.08396676E-02 + 7.95757101E-17 1.23359687E-01 3.07813966E-16 1.42843582E-01 0.00000000E+00 + 5.71849904E-01 0.00000000E+00-1.68067231E-04-5.50908790E-10 3.50043425E-08 + 2.49186357E-14 0.00000000E+00-6.48720455E-10 0.00000000E+00 4.27710347E-14 + 4.66485193E-04 1.17511322E-18-2.49195147E-04-5.83682453E-19 1.37025138E-03 + 0.00000000E+00-7.08750895E-04 0.00000000E+00 3.08395779E-02 7.11749993E-17 +-1.54333810E-02-2.96597732E-17 1.42855211E-01 0.00000000E+00-6.92270842E-02 + 0.00000000E+00 0.00000000E+00-6.20045796E-10 0.00000000E+00 3.99642700E-14 + 1.43575629E-04-5.35285289E-10-3.56679367E-08 2.01495625E-14-6.61646915E-04 + 0.00000000E+00-2.18291979E-04 4.47094593E-19-7.39389393E-02 0.00000000E+00 +-1.54070787E-02 5.00464325E-17 0.00000000E+00 1.39470238E-08 0.00000000E+00 + 8.28002445E-14-3.43029201E-03 1.19321554E-08-7.06622747E-08 4.52286578E-14 + 1.37025727E-03 0.00000000E+00 5.48122226E-03 0.00000000E+00 4.66485513E-04 +-1.18096522E-18 1.86737241E-03-4.52258903E-18 1.42843582E-01 0.00000000E+00 + 5.71849904E-01 0.00000000E+00 3.08396676E-02-7.95757101E-17 1.23359687E-01 +-3.07813966E-16 0.00000000E+00-6.48720455E-10 0.00000000E+00 4.27710347E-14 + 1.68067231E-04-5.50908790E-10-3.50043425E-08 2.49186357E-14 1.37025138E-03 + 0.00000000E+00-7.08750895E-04 0.00000000E+00 4.66485193E-04-1.17511322E-18 +-2.49195147E-04 5.83682453E-19 1.42855211E-01 0.00000000E+00-6.92270842E-02 + 0.00000000E+00 3.08395779E-02-7.11749993E-17-1.54333810E-02 2.96597732E-17 +-1.43575629E-04-5.35285289E-10 3.56679367E-08 2.01495625E-14 0.00000000E+00 +-6.20045796E-10 0.00000000E+00 3.99642700E-14-2.18291979E-04-4.47094593E-19 +-6.61646915E-04 0.00000000E+00-2.18291979E-04-4.47094593E-19-6.61646915E-04 + 0.00000000E+00 3.43029201E-03 1.19321554E-08 7.06622747E-08 4.52286578E-14 + 0.00000000E+00 1.39470238E-08 0.00000000E+00 8.28002445E-14 4.66485513E-04 + 1.18096522E-18 1.86737241E-03 4.52258903E-18 1.37025727E-03 0.00000000E+00 + 5.48122226E-03 0.00000000E+00 4.66485513E-04 1.18096522E-18 1.86737241E-03 + 4.52258903E-18 1.37025727E-03 0.00000000E+00 5.48122226E-03 0.00000000E+00 +-1.68067231E-04-5.50908790E-10 3.50043425E-08 2.49186357E-14 0.00000000E+00 +-6.48720455E-10 0.00000000E+00 4.27710347E-14 4.66485193E-04 1.17511322E-18 +-2.49195147E-04-5.83682453E-19 1.37025138E-03 0.00000000E+00-7.08750895E-04 + 0.00000000E+00 4.66485193E-04 1.17511322E-18-2.49195147E-04-5.83682453E-19 + 1.37025138E-03 0.00000000E+00-7.08750895E-04 0.00000000E+00 0.00000000E+00 +-6.20045796E-10 0.00000000E+00 3.99642700E-14 1.43575629E-04-5.35285289E-10 +-3.56679367E-08 2.01495625E-14-6.61646915E-04 0.00000000E+00-2.18291979E-04 + 4.47094593E-19-6.61646915E-04 0.00000000E+00-2.18291979E-04 4.47094593E-19 + 0.00000000E+00 1.39470238E-08 0.00000000E+00 8.28002445E-14-3.43029201E-03 + 1.19321554E-08-7.06622747E-08 4.52286578E-14 1.37025727E-03 0.00000000E+00 + 5.48122226E-03 0.00000000E+00 4.66485513E-04-1.18096522E-18 1.86737241E-03 +-4.52258903E-18 1.37025727E-03 0.00000000E+00 5.48122226E-03 0.00000000E+00 + 4.66485513E-04-1.18096522E-18 1.86737241E-03-4.52258903E-18 0.00000000E+00 +-6.48720455E-10 0.00000000E+00 4.27710347E-14 1.68067231E-04-5.50908790E-10 +-3.50043425E-08 2.49186357E-14 1.37025138E-03 0.00000000E+00-7.08750895E-04 + 0.00000000E+00 4.66485193E-04-1.17511322E-18-2.49195147E-04 5.83682453E-19 + 1.37025138E-03 0.00000000E+00-7.08750895E-04 0.00000000E+00 4.66485193E-04 +-1.17511322E-18-2.49195147E-04 5.83682453E-19 9.61969799E-07 2.67287295E-21 + 5.70389214E-09 1.57735176E-23-1.15514818E-04 0.00000000E+00-6.90591171E-07 + 0.00000000E+00-3.56679367E-08-2.01495625E-14 0.00000000E+00-3.99642700E-14 +-3.56679367E-08-2.01495625E-14 0.00000000E+00-3.99642700E-14 2.97032093E-07 +-3.30378404E-21-1.30236545E-08-5.84792283E-23-7.37537209E-06 0.00000000E+00 + 1.78592139E-06 0.00000000E+00 1.57713530E-05 5.60840478E-11-7.06622747E-08 +-4.52286578E-14 0.00000000E+00 6.53666808E-11 0.00000000E+00-8.28002445E-14 + 1.57713530E-05 5.60840478E-11-7.06622747E-08-4.52286578E-14 0.00000000E+00 + 6.53666808E-11 0.00000000E+00-8.28002445E-14-6.64939836E-07-5.60555578E-21 + 4.05090022E-09 3.25265280E-23 1.08133195E-04 0.00000000E+00-6.49517827E-07 + 0.00000000E+00-1.66194131E-05-5.66260921E-11-3.50043425E-08-2.49186357E-14 + 0.00000000E+00-6.63601531E-11 0.00000000E+00-4.27710347E-14-1.66194131E-05 +-5.66260921E-11-3.50043425E-08-2.49186357E-14 0.00000000E+00-6.63601531E-11 + 0.00000000E+00-4.27710347E-14-1.52222884E-04-4.22038138E-19-9.41466737E-07 +-2.60024549E-21 1.84311727E-02 0.00000000E+00 1.14949796E-04 0.00000000E+00 + 1.58683069E-04 5.43818346E-10 0.00000000E+00 6.36972165E-10 1.58683069E-04 + 5.43818346E-10 0.00000000E+00 6.36972165E-10-7.53806080E-04-3.05249244E-18 + 2.97032093E-07-3.30378404E-21 1.03234703E-01 0.00000000E+00-7.37537209E-06 + 0.00000000E+00-3.04740482E-03-1.08042051E-08-3.43029201E-03-1.19321554E-08 + 0.00000000E+00-1.25974050E-08 0.00000000E+00-1.39470238E-08-3.04740482E-03 +-1.08042051E-08-3.43029201E-03-1.19321554E-08 0.00000000E+00-1.25974050E-08 + 0.00000000E+00-1.39470238E-08-1.08107595E-04-8.66002379E-19 6.86869346E-07 + 5.23105304E-21 1.73350316E-02 0.00000000E+00-1.08624704E-04 0.00000000E+00 +-3.18891877E-03-1.08946909E-08 1.53240554E-04 5.40355350E-10 0.00000000E+00 +-1.27632137E-08 0.00000000E+00 6.30604955E-10-3.18891877E-03-1.08946909E-08 + 1.53240554E-04 5.40355350E-10 0.00000000E+00-1.27632137E-08 0.00000000E+00 + 6.30604955E-10-1.15514818E-04 0.00000000E+00-6.90591171E-07 0.00000000E+00 + 9.61969799E-07-2.67287295E-21 5.70389214E-09-1.57735176E-23 0.00000000E+00 +-3.99642700E-14 3.56679367E-08-2.01495625E-14 0.00000000E+00-3.99642700E-14 + 3.56679367E-08-2.01495625E-14-7.37537209E-06 0.00000000E+00 1.78592139E-06 + 0.00000000E+00 2.97032093E-07 3.30378404E-21-1.30236545E-08 5.84792283E-23 + 0.00000000E+00 6.53666808E-11 0.00000000E+00-8.28002445E-14-1.57713530E-05 + 5.60840478E-11 7.06622747E-08-4.52286578E-14 0.00000000E+00 6.53666808E-11 + 0.00000000E+00-8.28002445E-14-1.57713530E-05 5.60840478E-11 7.06622747E-08 +-4.52286578E-14 1.08133195E-04 0.00000000E+00-6.49517827E-07 0.00000000E+00 +-6.64939836E-07 5.60555578E-21 4.05090022E-09-3.25265280E-23 0.00000000E+00 +-6.63601531E-11 0.00000000E+00-4.27710347E-14 1.66194131E-05-5.66260921E-11 + 3.50043425E-08-2.49186357E-14 0.00000000E+00-6.63601531E-11 0.00000000E+00 +-4.27710347E-14 1.66194131E-05-5.66260921E-11 3.50043425E-08-2.49186357E-14 + 0.00000000E+00 1.27632137E-08 0.00000000E+00 6.63601531E-11-3.18891877E-03 + 1.08946909E-08-1.66194131E-05 5.66260921E-11 1.37025138E-03 0.00000000E+00 + 4.66485193E-04-1.17511322E-18 1.37025138E-03 0.00000000E+00 4.66485193E-04 +-1.17511322E-18 0.00000000E+00 1.28225002E-08 0.00000000E+00-6.65312373E-11 +-3.23744248E-03 1.09292286E-08 1.67594304E-05-5.67257666E-11 1.13398450E-02 + 0.00000000E+00 1.46475220E-03 0.00000000E+00 3.98598104E-03-9.23413590E-18 + 5.30295395E-04-1.15961660E-18 1.13398450E-02 0.00000000E+00 1.46475220E-03 + 0.00000000E+00 3.98598104E-03-9.23413590E-18 5.30295395E-04-1.15961660E-18 + 3.18891877E-03 1.08946909E-08 1.66194131E-05 5.66260921E-11 0.00000000E+00 + 1.27632137E-08 0.00000000E+00 6.63601531E-11 4.66485193E-04 1.17511322E-18 + 1.37025138E-03 0.00000000E+00 4.66485193E-04 1.17511322E-18 1.37025138E-03 + 0.00000000E+00 3.23744248E-03 1.09292286E-08-1.67594304E-05-5.67257666E-11 + 0.00000000E+00 1.28225002E-08 0.00000000E+00-6.65312373E-11 3.98598104E-03 + 9.23413590E-18 5.30295395E-04 1.15961660E-18 1.13398450E-02 0.00000000E+00 + 1.46475220E-03 0.00000000E+00 3.98598104E-03 9.23413590E-18 5.30295395E-04 + 1.15961660E-18 1.13398450E-02 0.00000000E+00 1.46475220E-03 0.00000000E+00 + 0.00000000E+00 1.27632137E-08 0.00000000E+00 6.63601531E-11-3.18891877E-03 + 1.08946909E-08-1.66194131E-05 5.66260921E-11 1.37025138E-03 0.00000000E+00 + 4.66485193E-04-1.17511322E-18 1.42855211E-01 0.00000000E+00 3.08395779E-02 +-7.11749993E-17 0.00000000E+00 1.28225002E-08 0.00000000E+00-6.65312373E-11 +-3.23744248E-03 1.09292286E-08 1.67594304E-05-5.67257666E-11 1.13398450E-02 + 0.00000000E+00 1.46475220E-03 0.00000000E+00 3.98598104E-03-9.23413590E-18 + 5.30295395E-04-1.15961660E-18 1.10730613E+00 0.00000000E+00 1.34053126E-01 + 0.00000000E+00 2.46933143E-01-4.43821644E-16 3.08939460E-02-4.74640937E-17 + 1.73350316E-02 0.00000000E+00 1.08133195E-04 0.00000000E+00-1.08107595E-04 + 8.66002379E-19-6.64939836E-07 5.60555578E-21 0.00000000E+00 6.48720455E-10 +-1.68067231E-04 5.50908790E-10 0.00000000E+00 6.48720455E-10-1.68067231E-04 + 5.50908790E-10 9.73185643E-02 0.00000000E+00-6.44105717E-06 0.00000000E+00 +-4.90265188E-04 5.25884635E-18 3.17368784E-07-2.91936120E-21 0.00000000E+00 +-1.28225002E-08 0.00000000E+00-1.42005171E-08 3.23744248E-03-1.09292286E-08 + 3.63786209E-03-1.20797445E-08 0.00000000E+00-1.28225002E-08 0.00000000E+00 +-1.42005171E-08 3.23744248E-03-1.09292286E-08 3.63786209E-03-1.20797445E-08 + 1.63778388E-02 0.00000000E+00-1.02609748E-04 0.00000000E+00-6.09715301E-05 + 5.02490754E-19 3.92910811E-07-3.41022484E-21 0.00000000E+00-1.29986524E-08 + 0.00000000E+00 6.41952276E-10 3.37628133E-03-1.10374652E-08-1.62727721E-04 + 5.46758413E-10 0.00000000E+00-1.29986524E-08 0.00000000E+00 6.41952276E-10 + 3.37628133E-03-1.10374652E-08-1.62727721E-04 5.46758413E-10-1.53240554E-04 +-5.40355350E-10 3.50043425E-08 2.49186357E-14 0.00000000E+00-6.30604955E-10 + 0.00000000E+00 4.27710347E-14-2.49195147E-04-5.83682453E-19-7.08750895E-04 + 0.00000000E+00-1.54333810E-02-2.96597732E-17-6.92270842E-02 0.00000000E+00 + 3.63786209E-03 1.20797445E-08 6.93257784E-08 5.40684513E-14 0.00000000E+00 + 1.42005171E-08 0.00000000E+00 8.79480904E-14 5.30295395E-04 1.15961660E-18 + 2.12260318E-03 5.04649778E-18 1.46475220E-03 0.00000000E+00 5.85921468E-03 + 0.00000000E+00 3.08939460E-02 4.74640937E-17 1.23576791E-01 2.38825112E-16 + 1.34053126E-01 0.00000000E+00 5.36602938E-01 0.00000000E+00-1.77268886E-04 +-5.59060630E-10 3.43308526E-08 2.90466746E-14 0.00000000E+00-6.61076235E-10 + 0.00000000E+00 4.51514036E-14 5.30295064E-04 1.21786742E-18-2.82095725E-04 +-8.25633236E-19 1.46474602E-03 0.00000000E+00-7.56150963E-04 0.00000000E+00 + 3.08938568E-02 5.42604561E-17-1.54613504E-02-4.69646868E-17 1.34062038E-01 + 0.00000000E+00-6.50913295E-02 0.00000000E+00 0.00000000E+00-6.30604955E-10 + 0.00000000E+00 4.27710347E-14 1.53240554E-04-5.40355350E-10-3.50043425E-08 + 2.49186357E-14-7.08750895E-04 0.00000000E+00-2.49195147E-04 5.83682453E-19 +-6.92270842E-02 0.00000000E+00-1.54333810E-02 2.96597732E-17 0.00000000E+00 + 1.42005171E-08 0.00000000E+00 8.79480904E-14-3.63786209E-03 1.20797445E-08 +-6.93257784E-08 5.40684513E-14 1.46475220E-03 0.00000000E+00 5.85921468E-03 + 0.00000000E+00 5.30295395E-04-1.15961660E-18 2.12260318E-03-5.04649778E-18 + 1.34053126E-01 0.00000000E+00 5.36602938E-01 0.00000000E+00 3.08939460E-02 +-4.74640937E-17 1.23576791E-01-2.38825112E-16 0.00000000E+00-6.61076235E-10 + 0.00000000E+00 4.51514036E-14 1.77268886E-04-5.59060630E-10-3.43308526E-08 + 2.90466746E-14 1.46474602E-03 0.00000000E+00-7.56150963E-04 0.00000000E+00 + 5.30295064E-04-1.21786742E-18-2.82095725E-04 8.25633236E-19 1.34062038E-01 + 0.00000000E+00-6.50913295E-02 0.00000000E+00 3.08938568E-02-5.42604561E-17 +-1.54613504E-02 4.69646868E-17-1.53240554E-04-5.40355350E-10 3.50043425E-08 + 2.49186357E-14 0.00000000E+00-6.30604955E-10 0.00000000E+00 4.27710347E-14 +-2.49195147E-04-5.83682453E-19-7.08750895E-04 0.00000000E+00-2.49195147E-04 +-5.83682453E-19-7.08750895E-04 0.00000000E+00 3.63786209E-03 1.20797445E-08 + 6.93257784E-08 5.40684513E-14 0.00000000E+00 1.42005171E-08 0.00000000E+00 + 8.79480904E-14 5.30295395E-04 1.15961660E-18 2.12260318E-03 5.04649778E-18 + 1.46475220E-03 0.00000000E+00 5.85921468E-03 0.00000000E+00 5.30295395E-04 + 1.15961660E-18 2.12260318E-03 5.04649778E-18 1.46475220E-03 0.00000000E+00 + 5.85921468E-03 0.00000000E+00-1.77268886E-04-5.59060630E-10 3.43308526E-08 + 2.90466746E-14 0.00000000E+00-6.61076235E-10 0.00000000E+00 4.51514036E-14 + 5.30295064E-04 1.21786742E-18-2.82095725E-04-8.25633236E-19 1.46474602E-03 + 0.00000000E+00-7.56150963E-04 0.00000000E+00 5.30295064E-04 1.21786742E-18 +-2.82095725E-04-8.25633236E-19 1.46474602E-03 0.00000000E+00-7.56150963E-04 + 0.00000000E+00 0.00000000E+00-6.30604955E-10 0.00000000E+00 4.27710347E-14 + 1.53240554E-04-5.40355350E-10-3.50043425E-08 2.49186357E-14-7.08750895E-04 + 0.00000000E+00-2.49195147E-04 5.83682453E-19-7.08750895E-04 0.00000000E+00 +-2.49195147E-04 5.83682453E-19 0.00000000E+00 1.42005171E-08 0.00000000E+00 + 8.79480904E-14-3.63786209E-03 1.20797445E-08-6.93257784E-08 5.40684513E-14 + 1.46475220E-03 0.00000000E+00 5.85921468E-03 0.00000000E+00 5.30295395E-04 +-1.15961660E-18 2.12260318E-03-5.04649778E-18 1.46475220E-03 0.00000000E+00 + 5.85921468E-03 0.00000000E+00 5.30295395E-04-1.15961660E-18 2.12260318E-03 +-5.04649778E-18 0.00000000E+00-6.61076235E-10 0.00000000E+00 4.51514036E-14 + 1.77268886E-04-5.59060630E-10-3.43308526E-08 2.90466746E-14 1.46474602E-03 + 0.00000000E+00-7.56150963E-04 0.00000000E+00 5.30295064E-04-1.21786742E-18 +-2.82095725E-04 8.25633236E-19 1.46474602E-03 0.00000000E+00-7.56150963E-04 + 0.00000000E+00 5.30295064E-04-1.21786742E-18-2.82095725E-04 8.25633236E-19 + 6.86869346E-07 5.23105304E-21 4.05090022E-09 3.25265280E-23-1.08624704E-04 + 0.00000000E+00-6.49517827E-07 0.00000000E+00-3.50043425E-08-2.49186357E-14 + 0.00000000E+00-4.27710347E-14-3.50043425E-08-2.49186357E-14 0.00000000E+00 +-4.27710347E-14 3.17368784E-07 2.91936120E-21-8.46546673E-09-8.02724933E-23 +-6.44105717E-06 0.00000000E+00 1.68348993E-06 0.00000000E+00 1.67594304E-05 + 5.67257666E-11-6.93257784E-08-5.40684513E-14 0.00000000E+00 6.65312373E-11 + 0.00000000E+00-8.79480904E-14 1.67594304E-05 5.67257666E-11-6.93257784E-08 +-5.40684513E-14 0.00000000E+00 6.65312373E-11 0.00000000E+00-8.79480904E-14 +-3.69502373E-07-2.86626192E-21 2.28474333E-09 1.87626260E-23 1.02178883E-04 + 0.00000000E+00-6.13650719E-07 0.00000000E+00-1.75914525E-05-5.73742138E-11 +-3.43308526E-08-2.90466746E-14 0.00000000E+00-6.75867093E-11 0.00000000E+00 +-4.51514036E-14-1.75914525E-05-5.73742138E-11-3.43308526E-08-2.90466746E-14 + 0.00000000E+00-6.75867093E-11 0.00000000E+00-4.51514036E-14-1.08107595E-04 +-8.66002379E-19-6.64939836E-07-5.60555578E-21 1.73350316E-02 0.00000000E+00 + 1.08133195E-04 0.00000000E+00 1.68067231E-04 5.50908790E-10 0.00000000E+00 + 6.48720455E-10 1.68067231E-04 5.50908790E-10 0.00000000E+00 6.48720455E-10 +-4.90265188E-04-5.25884635E-18 3.17368784E-07 2.91936120E-21 9.73185643E-02 + 0.00000000E+00-6.44105717E-06 0.00000000E+00-3.23744248E-03-1.09292286E-08 +-3.63786209E-03-1.20797445E-08 0.00000000E+00-1.28225002E-08 0.00000000E+00 +-1.42005171E-08-3.23744248E-03-1.09292286E-08-3.63786209E-03-1.20797445E-08 + 0.00000000E+00-1.28225002E-08 0.00000000E+00-1.42005171E-08-6.09715301E-05 +-5.02490754E-19 3.92910811E-07 3.41022484E-21 1.63778388E-02 0.00000000E+00 +-1.02609748E-04 0.00000000E+00-3.37628133E-03-1.10374652E-08 1.62727721E-04 + 5.46758413E-10 0.00000000E+00-1.29986524E-08 0.00000000E+00 6.41952276E-10 +-3.37628133E-03-1.10374652E-08 1.62727721E-04 5.46758413E-10 0.00000000E+00 +-1.29986524E-08 0.00000000E+00 6.41952276E-10-1.08624704E-04 0.00000000E+00 +-6.49517827E-07 0.00000000E+00 6.86869346E-07-5.23105304E-21 4.05090022E-09 +-3.25265280E-23 0.00000000E+00-4.27710347E-14 3.50043425E-08-2.49186357E-14 + 0.00000000E+00-4.27710347E-14 3.50043425E-08-2.49186357E-14-6.44105717E-06 + 0.00000000E+00 1.68348993E-06 0.00000000E+00 3.17368784E-07-2.91936120E-21 +-8.46546673E-09 8.02724933E-23 0.00000000E+00 6.65312373E-11 0.00000000E+00 +-8.79480904E-14-1.67594304E-05 5.67257666E-11 6.93257784E-08-5.40684513E-14 + 0.00000000E+00 6.65312373E-11 0.00000000E+00-8.79480904E-14-1.67594304E-05 + 5.67257666E-11 6.93257784E-08-5.40684513E-14 1.02178883E-04 0.00000000E+00 +-6.13650719E-07 0.00000000E+00-3.69502373E-07 2.86626192E-21 2.28474333E-09 +-1.87626260E-23 0.00000000E+00-6.75867093E-11 0.00000000E+00-4.51514036E-14 + 1.75914525E-05-5.73742138E-11 3.43308526E-08-2.90466746E-14 0.00000000E+00 +-6.75867093E-11 0.00000000E+00-4.51514036E-14 1.75914525E-05-5.73742138E-11 + 3.43308526E-08-2.90466746E-14 3.37628133E-03 1.10374652E-08 1.75914525E-05 + 5.73742138E-11 0.00000000E+00 1.29986524E-08 0.00000000E+00 6.75867093E-11 + 5.30295064E-04 1.21786742E-18 1.46474602E-03 0.00000000E+00 3.08938568E-02 + 5.42604561E-17 1.34062038E-01 0.00000000E+00 3.42387044E-03 1.10777263E-08 +-1.77287759E-05-5.74904005E-11 0.00000000E+00 1.30612394E-08 0.00000000E+00 +-6.77673149E-11 4.51239745E-03 1.33834824E-17 5.98087834E-04 2.08466552E-18 + 1.20982350E-02 0.00000000E+00 1.55985783E-03 0.00000000E+00 2.47380666E-01 + 7.57200916E-16 3.09515449E-02 1.33598291E-16 1.04119002E+00 0.00000000E+00 + 1.26303280E-01 0.00000000E+00 0.00000000E+00 1.29986524E-08 0.00000000E+00 + 6.75867093E-11-3.37628133E-03 1.10374652E-08-1.75914525E-05 5.73742138E-11 + 1.46474602E-03 0.00000000E+00 5.30295064E-04-1.21786742E-18 1.46474602E-03 + 0.00000000E+00 5.30295064E-04-1.21786742E-18 0.00000000E+00 1.30612394E-08 + 0.00000000E+00-6.77673149E-11-3.42387044E-03 1.10777263E-08 1.77287759E-05 +-5.74904005E-11 1.20982350E-02 0.00000000E+00 1.55985783E-03 0.00000000E+00 + 4.51239745E-03-1.33834824E-17 5.98087834E-04-2.08466552E-18 1.20982350E-02 + 0.00000000E+00 1.55985783E-03 0.00000000E+00 4.51239745E-03-1.33834824E-17 + 5.98087834E-04-2.08466552E-18 3.37628133E-03 1.10374652E-08 1.75914525E-05 + 5.73742138E-11 0.00000000E+00 1.29986524E-08 0.00000000E+00 6.75867093E-11 + 5.30295064E-04 1.21786742E-18 1.46474602E-03 0.00000000E+00 5.30295064E-04 + 1.21786742E-18 1.46474602E-03 0.00000000E+00 3.42387044E-03 1.10777263E-08 +-1.77287759E-05-5.74904005E-11 0.00000000E+00 1.30612394E-08 0.00000000E+00 +-6.77673149E-11 4.51239745E-03 1.33834824E-17 5.98087834E-04 2.08466552E-18 + 1.20982350E-02 0.00000000E+00 1.55985783E-03 0.00000000E+00 4.51239745E-03 + 1.33834824E-17 5.98087834E-04 2.08466552E-18 1.20982350E-02 0.00000000E+00 + 1.55985783E-03 0.00000000E+00 0.00000000E+00 1.29986524E-08 0.00000000E+00 + 6.75867093E-11-3.37628133E-03 1.10374652E-08-1.75914525E-05 5.73742138E-11 + 1.46474602E-03 0.00000000E+00 5.30295064E-04-1.21786742E-18 1.34062038E-01 + 0.00000000E+00 3.08938568E-02-5.42604561E-17 0.00000000E+00 1.30612394E-08 + 0.00000000E+00-6.77673149E-11-3.42387044E-03 1.10777263E-08 1.77287759E-05 +-5.74904005E-11 1.20982350E-02 0.00000000E+00 1.55985783E-03 0.00000000E+00 + 4.51239745E-03-1.33834824E-17 5.98087834E-04-2.08466552E-18 1.04119002E+00 + 0.00000000E+00 1.26303280E-01 0.00000000E+00 2.47380666E-01-7.57200916E-16 + 3.09515449E-02-1.33598291E-16 3.73933855E-03 1.13841572E-08 1.94746300E-05 + 5.91857201E-11 0.00000000E+00 1.35042826E-08 0.00000000E+00 7.02187729E-11 + 6.69836861E-04 2.25684001E-18 1.65560763E-03 0.00000000E+00 3.10123216E-02 + 1.06033020E-16 1.19426488E-01 0.00000000E+00 3.78481071E-03 1.14339307E-08 +-1.96058431E-05-5.93293506E-11 0.00000000E+00 1.35721818E-08 0.00000000E+00 +-7.04147030E-11 5.66029950E-03 2.01820988E-17 7.45517793E-04 2.53812162E-18 + 1.36304698E-02 0.00000000E+00 1.75206054E-03 0.00000000E+00 2.48354458E-01 + 6.41248053E-16 3.10765226E-02 5.64284492E-17 9.30592878E-01 0.00000000E+00 + 1.13269851E-01 0.00000000E+00 3.55985759E-03 1.12014449E-08 1.85437037E-05 + 5.82316456E-11 0.00000000E+00 1.32462245E-08 0.00000000E+00 6.88757290E-11 + 5.98087376E-04 1.97210373E-18 1.55985140E-03 0.00000000E+00 3.09514547E-02 + 1.35474268E-16 1.26310204E-01 0.00000000E+00 3.60640812E-03 1.12467354E-08 +-1.86780274E-05-5.83623424E-11 0.00000000E+00 1.33116495E-08 0.00000000E+00 +-6.90645216E-11 5.07057202E-03 1.54542871E-17 6.69837368E-04 1.97333379E-18 + 1.28616713E-02 0.00000000E+00 1.65561435E-03 0.00000000E+00 2.47854532E-01 + 1.01235124E-15 3.10124112E-02 1.11524575E-16 9.82697582E-01 0.00000000E+00 + 1.19421035E-01 0.00000000E+00 0.00000000E+00 1.32462245E-08 0.00000000E+00 + 6.88757290E-11-3.55985759E-03 1.12014449E-08-1.85437037E-05 5.82316456E-11 + 1.55985140E-03 0.00000000E+00 5.98087376E-04-1.97210373E-18 1.55985140E-03 + 0.00000000E+00 5.98087376E-04-1.97210373E-18 0.00000000E+00 1.33116495E-08 + 0.00000000E+00-6.90645216E-11-3.60640812E-03 1.12467354E-08 1.86780274E-05 +-5.83623424E-11 1.28616713E-02 0.00000000E+00 1.65561435E-03 0.00000000E+00 + 5.07057202E-03-1.54542871E-17 6.69837368E-04-1.97333379E-18 1.28616713E-02 + 0.00000000E+00 1.65561435E-03 0.00000000E+00 5.07057202E-03-1.54542871E-17 + 6.69837368E-04-1.97333379E-18 3.55985759E-03 1.12014449E-08 1.85437037E-05 + 5.82316456E-11 0.00000000E+00 1.32462245E-08 0.00000000E+00 6.88757290E-11 + 5.98087376E-04 1.97210373E-18 1.55985140E-03 0.00000000E+00 5.98087376E-04 + 1.97210373E-18 1.55985140E-03 0.00000000E+00 3.60640812E-03 1.12467354E-08 +-1.86780274E-05-5.83623424E-11 0.00000000E+00 1.33116495E-08 0.00000000E+00 +-6.90645216E-11 5.07057202E-03 1.54542871E-17 6.69837368E-04 1.97333379E-18 + 1.28616713E-02 0.00000000E+00 1.65561435E-03 0.00000000E+00 5.07057202E-03 + 1.54542871E-17 6.69837368E-04 1.97333379E-18 1.28616713E-02 0.00000000E+00 + 1.65561435E-03 0.00000000E+00 0.00000000E+00 1.32462245E-08 0.00000000E+00 + 6.88757290E-11-3.55985759E-03 1.12014449E-08-1.85437037E-05 5.82316456E-11 + 1.55985140E-03 0.00000000E+00 5.98087376E-04-1.97210373E-18 1.26310204E-01 + 0.00000000E+00 3.09514547E-02-1.35474268E-16 0.00000000E+00 1.33116495E-08 + 0.00000000E+00-6.90645216E-11-3.60640812E-03 1.12467354E-08 1.86780274E-05 +-5.83623424E-11 1.28616713E-02 0.00000000E+00 1.65561435E-03 0.00000000E+00 + 5.07057202E-03-1.54542871E-17 6.69837368E-04-1.97333379E-18 9.82697582E-01 + 0.00000000E+00 1.19421035E-01 0.00000000E+00 2.47854532E-01-1.01235124E-15 + 3.10124112E-02-1.11524575E-16 1.63778388E-02 0.00000000E+00 1.02178883E-04 + 0.00000000E+00-6.09715301E-05 5.02490754E-19-3.69502373E-07 2.86626192E-21 + 0.00000000E+00 6.61076235E-10-1.77268886E-04 5.59060630E-10 0.00000000E+00 + 6.61076235E-10-1.77268886E-04 5.59060630E-10 9.21332007E-02 0.00000000E+00 +-5.66664573E-06 0.00000000E+00-2.09091798E-04 1.74733010E-18 3.37839566E-07 + 1.12619249E-21 0.00000000E+00-1.30612394E-08 0.00000000E+00-1.44681447E-08 + 3.42387044E-03-1.10777263E-08 3.84140447E-03-1.22518416E-08 0.00000000E+00 +-1.30612394E-08 0.00000000E+00-1.44681447E-08 3.42387044E-03-1.10777263E-08 + 3.84140447E-03-1.22518416E-08 1.55357984E-02 0.00000000E+00-9.73198184E-05 + 0.00000000E+00-1.07934970E-05 6.25493877E-19 7.99209911E-08-3.63139980E-21 + 0.00000000E+00-1.32462245E-08 0.00000000E+00 6.53965997E-10 3.55985759E-03 +-1.12014449E-08-1.72038893E-04 5.54311349E-10 0.00000000E+00-1.32462245E-08 + 0.00000000E+00 6.53965997E-10 3.55985759E-03-1.12014449E-08-1.72038893E-04 + 5.54311349E-10-1.62727721E-04-5.46758413E-10 3.43308526E-08 2.90466746E-14 + 0.00000000E+00-6.41952276E-10 0.00000000E+00 4.51514036E-14-2.82095725E-04 +-8.25633236E-19-7.56150963E-04 0.00000000E+00-1.54613504E-02-4.69646868E-17 +-6.50913295E-02 0.00000000E+00 3.84140447E-03 1.22518416E-08 6.78993153E-08 + 6.17814029E-14 0.00000000E+00 1.44681447E-08 0.00000000E+00 9.23457622E-14 + 5.98087834E-04 2.08466552E-18 2.39376366E-03 7.82764522E-18 1.55985783E-03 + 0.00000000E+00 6.23965101E-03 0.00000000E+00 3.09515449E-02 1.33598291E-16 + 1.23807167E-01 5.02230023E-16 1.26303280E-01 0.00000000E+00 5.05537532E-01 + 0.00000000E+00-1.86262667E-04-5.68150309E-10 3.35809077E-08 3.26742122E-14 + 0.00000000E+00-6.73957080E-10 0.00000000E+00 4.71981452E-14 5.98087376E-04 + 1.97210373E-18-3.16981186E-04-9.86359380E-19 1.55985140E-03 0.00000000E+00 +-8.03866436E-04 0.00000000E+00 3.09514547E-02 1.35474268E-16-1.54909665E-02 +-6.17497107E-17 1.26310204E-01 0.00000000E+00-6.14328097E-02 0.00000000E+00 + 0.00000000E+00-6.41952276E-10 0.00000000E+00 4.51514036E-14 1.62727721E-04 +-5.46758413E-10-3.43308526E-08 2.90466746E-14-7.56150963E-04 0.00000000E+00 +-2.82095725E-04 8.25633236E-19-6.50913295E-02 0.00000000E+00-1.54613504E-02 + 4.69646868E-17 0.00000000E+00 1.44681447E-08 0.00000000E+00 9.23457622E-14 +-3.84140447E-03 1.22518416E-08-6.78993153E-08 6.17814029E-14 1.55985783E-03 + 0.00000000E+00 6.23965101E-03 0.00000000E+00 5.98087834E-04-2.08466552E-18 + 2.39376366E-03-7.82764522E-18 1.26303280E-01 0.00000000E+00 5.05537532E-01 + 0.00000000E+00 3.09515449E-02-1.33598291E-16 1.23807167E-01-5.02230023E-16 + 0.00000000E+00-6.73957080E-10 0.00000000E+00 4.71981452E-14 1.86262667E-04 +-5.68150309E-10-3.35809077E-08 3.26742122E-14 1.55985140E-03 0.00000000E+00 +-8.03866436E-04 0.00000000E+00 5.98087376E-04-1.97210373E-18-3.16981186E-04 + 9.86359380E-19 1.26310204E-01 0.00000000E+00-6.14328097E-02 0.00000000E+00 + 3.09514547E-02-1.35474268E-16-1.54909665E-02 6.17497107E-17-1.62727721E-04 +-5.46758413E-10 3.43308526E-08 2.90466746E-14 0.00000000E+00-6.41952276E-10 + 0.00000000E+00 4.51514036E-14-2.82095725E-04-8.25633236E-19-7.56150963E-04 + 0.00000000E+00-2.82095725E-04-8.25633236E-19-7.56150963E-04 0.00000000E+00 + 3.84140447E-03 1.22518416E-08 6.78993153E-08 6.17814029E-14 0.00000000E+00 + 1.44681447E-08 0.00000000E+00 9.23457622E-14 5.98087834E-04 2.08466552E-18 + 2.39376366E-03 7.82764522E-18 1.55985783E-03 0.00000000E+00 6.23965101E-03 + 0.00000000E+00 5.98087834E-04 2.08466552E-18 2.39376366E-03 7.82764522E-18 + 1.55985783E-03 0.00000000E+00 6.23965101E-03 0.00000000E+00-1.86262667E-04 +-5.68150309E-10 3.35809077E-08 3.26742122E-14 0.00000000E+00-6.73957080E-10 + 0.00000000E+00 4.71981452E-14 5.98087376E-04 1.97210373E-18-3.16981186E-04 +-9.86359380E-19 1.55985140E-03 0.00000000E+00-8.03866436E-04 0.00000000E+00 + 5.98087376E-04 1.97210373E-18-3.16981186E-04-9.86359380E-19 1.55985140E-03 + 0.00000000E+00-8.03866436E-04 0.00000000E+00 0.00000000E+00-6.41952276E-10 + 0.00000000E+00 4.51514036E-14 1.62727721E-04-5.46758413E-10-3.43308526E-08 + 2.90466746E-14-7.56150963E-04 0.00000000E+00-2.82095725E-04 8.25633236E-19 +-7.56150963E-04 0.00000000E+00-2.82095725E-04 8.25633236E-19 0.00000000E+00 + 1.44681447E-08 0.00000000E+00 9.23457622E-14-3.84140447E-03 1.22518416E-08 +-6.78993153E-08 6.17814029E-14 1.55985783E-03 0.00000000E+00 6.23965101E-03 + 0.00000000E+00 5.98087834E-04-2.08466552E-18 2.39376366E-03-7.82764522E-18 + 1.55985783E-03 0.00000000E+00 6.23965101E-03 0.00000000E+00 5.98087834E-04 +-2.08466552E-18 2.39376366E-03-7.82764522E-18 0.00000000E+00-6.73957080E-10 + 0.00000000E+00 4.71981452E-14 1.86262667E-04-5.68150309E-10-3.35809077E-08 + 3.26742122E-14 1.55985140E-03 0.00000000E+00-8.03866436E-04 0.00000000E+00 + 5.98087376E-04-1.97210373E-18-3.16981186E-04 9.86359380E-19 1.55985140E-03 + 0.00000000E+00-8.03866436E-04 0.00000000E+00 5.98087376E-04-1.97210373E-18 +-3.16981186E-04 9.86359380E-19 3.92910811E-07 3.41022484E-21 2.28474333E-09 + 1.87626260E-23-1.02609748E-04 0.00000000E+00-6.13650719E-07 0.00000000E+00 +-3.43308526E-08-2.90466746E-14 0.00000000E+00-4.51514036E-14-3.43308526E-08 +-2.90466746E-14 0.00000000E+00-4.51514036E-14 3.37839566E-07-1.12619249E-21 +-3.60338404E-09-4.21931663E-23-5.66664573E-06 0.00000000E+00 1.59372021E-06 + 0.00000000E+00 1.77287759E-05 5.74904005E-11-6.78993153E-08-6.17814029E-14 + 0.00000000E+00 6.77673149E-11 0.00000000E+00-9.23457622E-14 1.77287759E-05 + 5.74904005E-11-6.78993153E-08-6.17814029E-14 0.00000000E+00 6.77673149E-11 + 0.00000000E+00-9.23457622E-14-5.50629385E-08-4.18819921E-21 4.04629904E-10 + 2.34209122E-23 9.69394486E-05 0.00000000E+00-5.82098282E-07 0.00000000E+00 +-1.85437037E-05-5.82316456E-11-3.35809077E-08-3.26742122E-14 0.00000000E+00 +-6.88757290E-11 0.00000000E+00-4.71981452E-14-1.85437037E-05-5.82316456E-11 +-3.35809077E-08-3.26742122E-14 0.00000000E+00-6.88757290E-11 0.00000000E+00 +-4.71981452E-14-6.09715301E-05-5.02490754E-19-3.69502373E-07-2.86626192E-21 + 1.63778388E-02 0.00000000E+00 1.02178883E-04 0.00000000E+00 1.77268886E-04 + 5.59060630E-10 0.00000000E+00 6.61076235E-10 1.77268886E-04 5.59060630E-10 + 0.00000000E+00 6.61076235E-10-2.09091798E-04-1.74733010E-18 3.37839566E-07 +-1.12619249E-21 9.21332007E-02 0.00000000E+00-5.66664573E-06 0.00000000E+00 +-3.42387044E-03-1.10777263E-08-3.84140447E-03-1.22518416E-08 0.00000000E+00 +-1.30612394E-08 0.00000000E+00-1.44681447E-08-3.42387044E-03-1.10777263E-08 +-3.84140447E-03-1.22518416E-08 0.00000000E+00-1.30612394E-08 0.00000000E+00 +-1.44681447E-08-1.07934970E-05-6.25493877E-19 7.99209911E-08 3.63139980E-21 + 1.55357984E-02 0.00000000E+00-9.73198184E-05 0.00000000E+00-3.55985759E-03 +-1.12014449E-08 1.72038893E-04 5.54311349E-10 0.00000000E+00-1.32462245E-08 + 0.00000000E+00 6.53965997E-10-3.55985759E-03-1.12014449E-08 1.72038893E-04 + 5.54311349E-10 0.00000000E+00-1.32462245E-08 0.00000000E+00 6.53965997E-10 +-1.02609748E-04 0.00000000E+00-6.13650719E-07 0.00000000E+00 3.92910811E-07 +-3.41022484E-21 2.28474333E-09-1.87626260E-23 0.00000000E+00-4.51514036E-14 + 3.43308526E-08-2.90466746E-14 0.00000000E+00-4.51514036E-14 3.43308526E-08 +-2.90466746E-14-5.66664573E-06 0.00000000E+00 1.59372021E-06 0.00000000E+00 + 3.37839566E-07 1.12619249E-21-3.60338404E-09 4.21931663E-23 0.00000000E+00 + 6.77673149E-11 0.00000000E+00-9.23457622E-14-1.77287759E-05 5.74904005E-11 + 6.78993153E-08-6.17814029E-14 0.00000000E+00 6.77673149E-11 0.00000000E+00 +-9.23457622E-14-1.77287759E-05 5.74904005E-11 6.78993153E-08-6.17814029E-14 + 9.69394486E-05 0.00000000E+00-5.82098282E-07 0.00000000E+00-5.50629385E-08 + 4.18819921E-21 4.04629904E-10-2.34209122E-23 0.00000000E+00-6.88757290E-11 + 0.00000000E+00-4.71981452E-14 1.85437037E-05-5.82316456E-11 3.35809077E-08 +-3.26742122E-14 0.00000000E+00-6.88757290E-11 0.00000000E+00-4.71981452E-14 + 1.85437037E-05-5.82316456E-11 3.35809077E-08-3.26742122E-14 1.55357984E-02 + 0.00000000E+00 9.69394486E-05 0.00000000E+00-1.07934970E-05 6.25493877E-19 +-5.50629385E-08 4.18819921E-21 0.00000000E+00 6.73957080E-10-1.86262667E-04 + 5.68150309E-10 0.00000000E+00 6.73957080E-10-1.86262667E-04 5.68150309E-10 + 8.75564702E-02 0.00000000E+00-5.01768613E-06 0.00000000E+00 8.96015981E-05 + 6.05671826E-18 3.58415057E-07 3.62204566E-21 0.00000000E+00-1.33116495E-08 + 0.00000000E+00-1.47479251E-08 3.60640812E-03-1.12467354E-08 4.04052513E-03 +-1.24454730E-08 0.00000000E+00-1.33116495E-08 0.00000000E+00-1.47479251E-08 + 3.60640812E-03-1.12467354E-08 4.04052513E-03-1.24454730E-08 1.47902400E-02 + 0.00000000E+00-9.26370669E-05 0.00000000E+00 4.24401357E-05 1.09801840E-18 +-2.52151547E-07-7.01480269E-21 0.00000000E+00-1.35042826E-08 0.00000000E+00 + 6.66550967E-10 3.73933855E-03-1.13841572E-08-1.81150365E-04 5.62871447E-10 + 0.00000000E+00-1.35042826E-08 0.00000000E+00 6.66550967E-10 3.73933855E-03 +-1.13841572E-08-1.81150365E-04 5.62871447E-10-1.72038893E-04-5.54311349E-10 + 3.35809077E-08 3.26742122E-14 0.00000000E+00-6.53965997E-10 0.00000000E+00 + 4.71981452E-14-3.16981186E-04-9.86359380E-19-8.03866436E-04 0.00000000E+00 +-1.54909665E-02-6.17497107E-17-6.14328097E-02 0.00000000E+00 4.04052513E-03 + 1.24454730E-08 6.63726649E-08 6.86107824E-14 0.00000000E+00 1.47479251E-08 + 0.00000000E+00 9.61548650E-14 6.69837368E-04 1.97333379E-18 2.68075234E-03 + 8.53759535E-18 1.65561435E-03 0.00000000E+00 6.62269041E-03 0.00000000E+00 + 3.10124112E-02 1.11524575E-16 1.24050624E-01 4.25956419E-16 1.19421035E-01 + 0.00000000E+00 4.77956660E-01 0.00000000E+00-1.95044666E-04-5.78080161E-10 + 3.28032585E-08 3.59076205E-14 0.00000000E+00-6.87298010E-10 0.00000000E+00 + 4.89825262E-14 6.69836861E-04 2.25684001E-18-3.53838664E-04-1.19874041E-18 + 1.65560763E-03 0.00000000E+00-8.51917043E-04 0.00000000E+00 3.10123216E-02 + 1.06033020E-16-1.55222111E-02-4.06153673E-17 1.19426488E-01 0.00000000E+00 +-5.81740847E-02 0.00000000E+00 0.00000000E+00-6.53965997E-10 0.00000000E+00 + 4.71981452E-14 1.72038893E-04-5.54311349E-10-3.35809077E-08 3.26742122E-14 +-8.03866436E-04 0.00000000E+00-3.16981186E-04 9.86359380E-19-6.14328097E-02 + 0.00000000E+00-1.54909665E-02 6.17497107E-17 0.00000000E+00 1.47479251E-08 + 0.00000000E+00 9.61548650E-14-4.04052513E-03 1.24454730E-08-6.63726649E-08 + 6.86107824E-14 1.65561435E-03 0.00000000E+00 6.62269041E-03 0.00000000E+00 + 6.69837368E-04-1.97333379E-18 2.68075234E-03-8.53759535E-18 1.19421035E-01 + 0.00000000E+00 4.77956660E-01 0.00000000E+00 3.10124112E-02-1.11524575E-16 + 1.24050624E-01-4.25956419E-16 0.00000000E+00-6.87298010E-10 0.00000000E+00 + 4.89825262E-14 1.95044666E-04-5.78080161E-10-3.28032585E-08 3.59076205E-14 + 1.65560763E-03 0.00000000E+00-8.51917043E-04 0.00000000E+00 6.69836861E-04 +-2.25684001E-18-3.53838664E-04 1.19874041E-18 1.19426488E-01 0.00000000E+00 +-5.81740847E-02 0.00000000E+00 3.10123216E-02-1.06033020E-16-1.55222111E-02 + 4.06153673E-17-1.72038893E-04-5.54311349E-10 3.35809077E-08 3.26742122E-14 + 0.00000000E+00-6.53965997E-10 0.00000000E+00 4.71981452E-14-3.16981186E-04 +-9.86359380E-19-8.03866436E-04 0.00000000E+00-3.16981186E-04-9.86359380E-19 +-8.03866436E-04 0.00000000E+00 4.04052513E-03 1.24454730E-08 6.63726649E-08 + 6.86107824E-14 0.00000000E+00 1.47479251E-08 0.00000000E+00 9.61548650E-14 + 6.69837368E-04 1.97333379E-18 2.68075234E-03 8.53759535E-18 1.65561435E-03 + 0.00000000E+00 6.62269041E-03 0.00000000E+00 6.69837368E-04 1.97333379E-18 + 2.68075234E-03 8.53759535E-18 1.65561435E-03 0.00000000E+00 6.62269041E-03 + 0.00000000E+00-1.95044666E-04-5.78080161E-10 3.28032585E-08 3.59076205E-14 + 0.00000000E+00-6.87298010E-10 0.00000000E+00 4.89825262E-14 6.69836861E-04 + 2.25684001E-18-3.53838664E-04-1.19874041E-18 1.65560763E-03 0.00000000E+00 +-8.51917043E-04 0.00000000E+00 6.69836861E-04 2.25684001E-18-3.53838664E-04 +-1.19874041E-18 1.65560763E-03 0.00000000E+00-8.51917043E-04 0.00000000E+00 + 0.00000000E+00-6.53965997E-10 0.00000000E+00 4.71981452E-14 1.72038893E-04 +-5.54311349E-10-3.35809077E-08 3.26742122E-14-8.03866436E-04 0.00000000E+00 +-3.16981186E-04 9.86359380E-19-8.03866436E-04 0.00000000E+00-3.16981186E-04 + 9.86359380E-19 0.00000000E+00 1.47479251E-08 0.00000000E+00 9.61548650E-14 +-4.04052513E-03 1.24454730E-08-6.63726649E-08 6.86107824E-14 1.65561435E-03 + 0.00000000E+00 6.62269041E-03 0.00000000E+00 6.69837368E-04-1.97333379E-18 + 2.68075234E-03-8.53759535E-18 1.65561435E-03 0.00000000E+00 6.62269041E-03 + 0.00000000E+00 6.69837368E-04-1.97333379E-18 2.68075234E-03-8.53759535E-18 + 0.00000000E+00-6.87298010E-10 0.00000000E+00 4.89825262E-14 1.95044666E-04 +-5.78080161E-10-3.28032585E-08 3.59076205E-14 1.65560763E-03 0.00000000E+00 +-8.51917043E-04 0.00000000E+00 6.69836861E-04-2.25684001E-18-3.53838664E-04 + 1.19874041E-18 1.65560763E-03 0.00000000E+00-8.51917043E-04 0.00000000E+00 + 6.69836861E-04-2.25684001E-18-3.53838664E-04 1.19874041E-18 7.99209911E-08 + 3.63139980E-21 4.04629904E-10 2.34209122E-23-9.73198184E-05 0.00000000E+00 +-5.82098282E-07 0.00000000E+00-3.35809077E-08-3.26742122E-14 0.00000000E+00 +-4.71981452E-14-3.35809077E-08-3.26742122E-14 0.00000000E+00-4.71981452E-14 + 3.58415057E-07-3.62204566E-21 1.56239093E-09-9.67273515E-23-5.01768613E-06 + 0.00000000E+00 1.51449637E-06 0.00000000E+00 1.86780274E-05 5.83623424E-11 +-6.63726649E-08-6.86107824E-14 0.00000000E+00 6.90645216E-11 0.00000000E+00 +-9.61548650E-14 1.86780274E-05 5.83623424E-11-6.63726649E-08-6.86107824E-14 + 0.00000000E+00 6.90645216E-11 0.00000000E+00-9.61548650E-14 2.78497228E-07 +-6.73284424E-21-1.58994964E-09 4.13167003E-23 9.22992794E-05 0.00000000E+00 +-5.54160978E-07 0.00000000E+00-1.94746300E-05-5.91857201E-11-3.28032585E-08 +-3.59076205E-14 0.00000000E+00-7.02187729E-11 0.00000000E+00-4.89825262E-14 +-1.94746300E-05-5.91857201E-11-3.28032585E-08-3.59076205E-14 0.00000000E+00 +-7.02187729E-11 0.00000000E+00-4.89825262E-14-1.07934970E-05-6.25493877E-19 +-5.50629385E-08-4.18819921E-21 1.55357984E-02 0.00000000E+00 9.69394486E-05 + 0.00000000E+00 1.86262667E-04 5.68150309E-10 0.00000000E+00 6.73957080E-10 + 1.86262667E-04 5.68150309E-10 0.00000000E+00 6.73957080E-10 8.96015981E-05 +-6.05671826E-18 3.58415057E-07-3.62204566E-21 8.75564702E-02 0.00000000E+00 +-5.01768613E-06 0.00000000E+00-3.60640812E-03-1.12467354E-08-4.04052513E-03 +-1.24454730E-08 0.00000000E+00-1.33116495E-08 0.00000000E+00-1.47479251E-08 +-3.60640812E-03-1.12467354E-08-4.04052513E-03-1.24454730E-08 0.00000000E+00 +-1.33116495E-08 0.00000000E+00-1.47479251E-08 4.24401357E-05-1.09801840E-18 +-2.52151547E-07 7.01480269E-21 1.47902400E-02 0.00000000E+00-9.26370669E-05 + 0.00000000E+00-3.73933855E-03-1.13841572E-08 1.81150365E-04 5.62871447E-10 + 0.00000000E+00-1.35042826E-08 0.00000000E+00 6.66550967E-10-3.73933855E-03 +-1.13841572E-08 1.81150365E-04 5.62871447E-10 0.00000000E+00-1.35042826E-08 + 0.00000000E+00 6.66550967E-10-9.73198184E-05 0.00000000E+00-5.82098282E-07 + 0.00000000E+00 7.99209911E-08-3.63139980E-21 4.04629904E-10-2.34209122E-23 + 0.00000000E+00-4.71981452E-14 3.35809077E-08-3.26742122E-14 0.00000000E+00 +-4.71981452E-14 3.35809077E-08-3.26742122E-14-5.01768613E-06 0.00000000E+00 + 1.51449637E-06 0.00000000E+00 3.58415057E-07 3.62204566E-21 1.56239093E-09 + 9.67273515E-23 0.00000000E+00 6.90645216E-11 0.00000000E+00-9.61548650E-14 +-1.86780274E-05 5.83623424E-11 6.63726649E-08-6.86107824E-14 0.00000000E+00 + 6.90645216E-11 0.00000000E+00-9.61548650E-14-1.86780274E-05 5.83623424E-11 + 6.63726649E-08-6.86107824E-14 9.22992794E-05 0.00000000E+00-5.54160978E-07 + 0.00000000E+00 2.78497228E-07 6.73284424E-21-1.58994964E-09-4.13167003E-23 + 0.00000000E+00-7.02187729E-11 0.00000000E+00-4.89825262E-14 1.94746300E-05 +-5.91857201E-11 3.28032585E-08-3.59076205E-14 0.00000000E+00-7.02187729E-11 + 0.00000000E+00-4.89825262E-14 1.94746300E-05-5.91857201E-11 3.28032585E-08 +-3.59076205E-14 0.00000000E+00 1.35042826E-08 0.00000000E+00 7.02187729E-11 +-3.73933855E-03 1.13841572E-08-1.94746300E-05 5.91857201E-11 1.65560763E-03 + 0.00000000E+00 6.69836861E-04-2.25684001E-18 1.65560763E-03 0.00000000E+00 + 6.69836861E-04-2.25684001E-18 0.00000000E+00 1.35721818E-08 0.00000000E+00 +-7.04147030E-11-3.78481071E-03 1.14339307E-08 1.96058431E-05-5.93293506E-11 + 1.36304698E-02 0.00000000E+00 1.75206054E-03 0.00000000E+00 5.66029950E-03 +-2.01820988E-17 7.45517793E-04-2.53812162E-18 1.36304698E-02 0.00000000E+00 + 1.75206054E-03 0.00000000E+00 5.66029950E-03-2.01820988E-17 7.45517793E-04 +-2.53812162E-18 3.73933855E-03 1.13841572E-08 1.94746300E-05 5.91857201E-11 + 0.00000000E+00 1.35042826E-08 0.00000000E+00 7.02187729E-11 6.69836861E-04 + 2.25684001E-18 1.65560763E-03 0.00000000E+00 6.69836861E-04 2.25684001E-18 + 1.65560763E-03 0.00000000E+00 3.78481071E-03 1.14339307E-08-1.96058431E-05 +-5.93293506E-11 0.00000000E+00 1.35721818E-08 0.00000000E+00-7.04147030E-11 + 5.66029950E-03 2.01820988E-17 7.45517793E-04 2.53812162E-18 1.36304698E-02 + 0.00000000E+00 1.75206054E-03 0.00000000E+00 5.66029950E-03 2.01820988E-17 + 7.45517793E-04 2.53812162E-18 1.36304698E-02 0.00000000E+00 1.75206054E-03 + 0.00000000E+00 0.00000000E+00 1.35042826E-08 0.00000000E+00 7.02187729E-11 +-3.73933855E-03 1.13841572E-08-1.94746300E-05 5.91857201E-11 1.65560763E-03 + 0.00000000E+00 6.69836861E-04-2.25684001E-18 1.19426488E-01 0.00000000E+00 + 3.10123216E-02-1.06033020E-16 0.00000000E+00 1.35721818E-08 0.00000000E+00 +-7.04147030E-11-3.78481071E-03 1.14339307E-08 1.96058431E-05-5.93293506E-11 + 1.36304698E-02 0.00000000E+00 1.75206054E-03 0.00000000E+00 5.66029950E-03 +-2.01820988E-17 7.45517793E-04-2.53812162E-18 9.30592878E-01 0.00000000E+00 + 1.13269851E-01 0.00000000E+00 2.48354458E-01-6.41248053E-16 3.10765226E-02 +-5.64284492E-17 6.50928138E-03 0.00000000E+00 3.06365241E-05 0.00000000E+00 + 1.31230169E-03-4.87650804E-18 6.19138708E-06-2.29843270E-20 0.00000000E+00 +-1.24827704E-10-2.29265257E-04-1.07197462E-10 0.00000000E+00-1.24827704E-10 +-2.29265257E-04-1.07197462E-10 1.87512929E-02 0.00000000E+00-5.17679706E-05 + 0.00000000E+00 3.84441653E-03-1.41688665E-17-1.05560173E-05 3.90219168E-20 + 0.00000000E+00-4.87166607E-09 0.00000000E+00-9.38462609E-10 4.57061742E-03 +-4.14102755E-09 2.51683468E-03-7.96052301E-10 0.00000000E+00-4.87166607E-09 + 0.00000000E+00-9.38462609E-10 4.57061742E-03-4.14102755E-09 2.51683468E-03 +-7.96052301E-10-2.27488326E-04-6.20467873E-10 3.16206903E-09-1.29360787E-12 + 0.00000000E+00-7.27570100E-10 0.00000000E+00-1.51534493E-12-1.09271660E-03 +-2.48943771E-18-1.42537591E-03 0.00000000E+00-1.23717249E-02-2.51217038E-17 +-2.20383866E-02 0.00000000E+00 2.51683468E-03 7.96052301E-10-4.47458764E-06 +-1.78420705E-12 0.00000000E+00 9.38462609E-10 0.00000000E+00-2.10459794E-12 + 2.22653918E-03 4.97512614E-18 4.43253626E-03 1.00280934E-17 2.88428653E-03 + 0.00000000E+00 5.75176074E-03 0.00000000E+00 2.47761074E-02 7.13508582E-17 + 4.95351995E-02 1.33612476E-16 4.36849440E-02 0.00000000E+00 8.75662485E-02 + 0.00000000E+00 4.56480308E-03 6.52256408E-09 1.78613161E-05 2.36382481E-11 + 0.00000000E+00 7.66143530E-09 0.00000000E+00 2.77773453E-11 2.14432722E-03 + 4.98262469E-18 2.81721709E-03 0.00000000E+00 2.47107924E-02 2.91359571E-17 + 4.44686025E-02 0.00000000E+00 4.57061742E-03 4.14102755E-09-1.78739643E-05 +-1.84638166E-11 0.00000000E+00 4.87166607E-09 0.00000000E+00-2.17159656E-11 + 1.74833260E-02 3.94248488E-17 2.22653918E-03 4.97512614E-18 2.28061455E-02 + 0.00000000E+00 2.88428653E-03 0.00000000E+00 1.97950279E-01 3.94122483E-16 + 2.47761074E-02 7.13508582E-17 3.52609973E-01 0.00000000E+00 4.36849440E-02 + 0.00000000E+00 0.00000000E+00-7.27570100E-10 0.00000000E+00-1.51534493E-12 + 2.27488326E-04-6.20467873E-10-3.16206903E-09-1.29360787E-12-1.42537591E-03 + 0.00000000E+00-1.09271660E-03 2.48943771E-18-2.20383866E-02 0.00000000E+00 +-1.23717249E-02 2.51217038E-17 0.00000000E+00 9.38462609E-10 0.00000000E+00 +-2.10459794E-12-2.51683468E-03 7.96052301E-10 4.47458764E-06-1.78420705E-12 + 2.88428653E-03 0.00000000E+00 5.75176074E-03 0.00000000E+00 2.22653918E-03 +-4.97512614E-18 4.43253626E-03-1.00280934E-17 4.36849440E-02 0.00000000E+00 + 8.75662485E-02 0.00000000E+00 2.47761074E-02-7.13508582E-17 4.95351995E-02 +-1.33612476E-16 0.00000000E+00 7.66143530E-09 0.00000000E+00 2.77773453E-11 +-4.56480308E-03 6.52256408E-09-1.78613161E-05 2.36382481E-11 2.81721709E-03 + 0.00000000E+00 2.14432722E-03-4.98262469E-18 4.44686025E-02 0.00000000E+00 + 2.47107924E-02-2.91359571E-17 0.00000000E+00 4.87166607E-09 0.00000000E+00 +-2.17159656E-11-4.57061742E-03 4.14102755E-09 1.78739643E-05-1.84638166E-11 + 2.28061455E-02 0.00000000E+00 2.88428653E-03 0.00000000E+00 1.74833260E-02 +-3.94248488E-17 2.22653918E-03-4.97512614E-18 3.52609973E-01 0.00000000E+00 + 4.36849440E-02 0.00000000E+00 1.97950279E-01-3.94122483E-16 2.47761074E-02 +-7.13508582E-17-2.27488326E-04-6.20467873E-10 3.16206903E-09-1.29360787E-12 + 0.00000000E+00-7.27570100E-10 0.00000000E+00-1.51534493E-12-1.09271660E-03 +-2.48943771E-18-1.42537591E-03 0.00000000E+00-1.09271660E-03-2.48943771E-18 +-1.42537591E-03 0.00000000E+00 2.51683468E-03 7.96052301E-10-4.47458764E-06 +-1.78420705E-12 0.00000000E+00 9.38462609E-10 0.00000000E+00-2.10459794E-12 + 2.22653918E-03 4.97512614E-18 4.43253626E-03 1.00280934E-17 2.88428653E-03 + 0.00000000E+00 5.75176074E-03 0.00000000E+00 2.22653918E-03 4.97512614E-18 + 4.43253626E-03 1.00280934E-17 2.88428653E-03 0.00000000E+00 5.75176074E-03 + 0.00000000E+00 4.56480308E-03 6.52256408E-09 1.78613161E-05 2.36382481E-11 + 0.00000000E+00 7.66143530E-09 0.00000000E+00 2.77773453E-11 2.14432722E-03 + 4.98262469E-18 2.81721709E-03 0.00000000E+00 2.14432722E-03 4.98262469E-18 + 2.81721709E-03 0.00000000E+00 4.57061742E-03 4.14102755E-09-1.78739643E-05 +-1.84638166E-11 0.00000000E+00 4.87166607E-09 0.00000000E+00-2.17159656E-11 + 1.74833260E-02 3.94248488E-17 2.22653918E-03 4.97512614E-18 2.28061455E-02 + 0.00000000E+00 2.88428653E-03 0.00000000E+00 1.74833260E-02 3.94248488E-17 + 2.22653918E-03 4.97512614E-18 2.28061455E-02 0.00000000E+00 2.88428653E-03 + 0.00000000E+00 0.00000000E+00-7.27570100E-10 0.00000000E+00-1.51534493E-12 + 2.27488326E-04-6.20467873E-10-3.16206903E-09-1.29360787E-12-1.42537591E-03 + 0.00000000E+00-1.09271660E-03 2.48943771E-18-1.42537591E-03 0.00000000E+00 +-1.09271660E-03 2.48943771E-18 0.00000000E+00 9.38462609E-10 0.00000000E+00 +-2.10459794E-12-2.51683468E-03 7.96052301E-10 4.47458764E-06-1.78420705E-12 + 2.88428653E-03 0.00000000E+00 5.75176074E-03 0.00000000E+00 2.22653918E-03 +-4.97512614E-18 4.43253626E-03-1.00280934E-17 2.88428653E-03 0.00000000E+00 + 5.75176074E-03 0.00000000E+00 2.22653918E-03-4.97512614E-18 4.43253626E-03 +-1.00280934E-17 0.00000000E+00 7.66143530E-09 0.00000000E+00 2.77773453E-11 +-4.56480308E-03 6.52256408E-09-1.78613161E-05 2.36382481E-11 2.81721709E-03 + 0.00000000E+00 2.14432722E-03-4.98262469E-18 2.81721709E-03 0.00000000E+00 + 2.14432722E-03-4.98262469E-18 0.00000000E+00 4.87166607E-09 0.00000000E+00 +-2.17159656E-11-4.57061742E-03 4.14102755E-09 1.78739643E-05-1.84638166E-11 + 2.28061455E-02 0.00000000E+00 2.88428653E-03 0.00000000E+00 1.74833260E-02 +-3.94248488E-17 2.22653918E-03-4.97512614E-18 2.28061455E-02 0.00000000E+00 + 2.88428653E-03 0.00000000E+00 1.74833260E-02-3.94248488E-17 2.22653918E-03 +-4.97512614E-18-6.16659582E-06-2.29388208E-20-2.78887831E-08-1.03641438E-22 +-3.06615677E-05 0.00000000E+00-1.38334004E-07 0.00000000E+00-3.16206903E-09 + 1.29360787E-12 0.00000000E+00 1.51534493E-12-3.16206903E-09 1.29360787E-12 + 0.00000000E+00 1.51534493E-12-1.05560173E-05-3.90219168E-20 3.74276068E-08 + 1.38613576E-22-5.17679706E-05 0.00000000E+00 1.84201018E-07 0.00000000E+00 + 1.78739643E-05 1.84638166E-11 4.47458764E-06 1.78420705E-12 0.00000000E+00 + 2.17159656E-11 0.00000000E+00 2.10459794E-12 1.78739643E-05 1.84638166E-11 + 4.47458764E-06 1.78420705E-12 0.00000000E+00 2.17159656E-11 0.00000000E+00 + 2.10459794E-12 1.31230169E-03 4.87650804E-18 6.19138708E-06 2.29843270E-20 + 6.50928138E-03 0.00000000E+00 3.06365241E-05 0.00000000E+00 2.29265257E-04 +-1.07197462E-10 0.00000000E+00-1.24827704E-10 2.29265257E-04-1.07197462E-10 + 0.00000000E+00-1.24827704E-10 3.84441653E-03 1.41688665E-17-1.05560173E-05 +-3.90219168E-20 1.87512929E-02 0.00000000E+00-5.17679706E-05 0.00000000E+00 +-4.57061742E-03-4.14102755E-09-2.51683468E-03-7.96052301E-10 0.00000000E+00 +-4.87166607E-09 0.00000000E+00-9.38462609E-10-4.57061742E-03-4.14102755E-09 +-2.51683468E-03-7.96052301E-10 0.00000000E+00-4.87166607E-09 0.00000000E+00 +-9.38462609E-10-3.06615677E-05 0.00000000E+00-1.38334004E-07 0.00000000E+00 +-6.16659582E-06 2.29388208E-20-2.78887831E-08 1.03641438E-22 0.00000000E+00 + 1.51534493E-12 3.16206903E-09 1.29360787E-12 0.00000000E+00 1.51534493E-12 + 3.16206903E-09 1.29360787E-12-5.17679706E-05 0.00000000E+00 1.84201018E-07 + 0.00000000E+00-1.05560173E-05 3.90219168E-20 3.74276068E-08-1.38613576E-22 + 0.00000000E+00 2.17159656E-11 0.00000000E+00 2.10459794E-12-1.78739643E-05 + 1.84638166E-11-4.47458764E-06 1.78420705E-12 0.00000000E+00 2.17159656E-11 + 0.00000000E+00 2.10459794E-12-1.78739643E-05 1.84638166E-11-4.47458764E-06 + 1.78420705E-12-2.26075347E-04-6.59647223E-10 3.75570681E-09-3.74879498E-13 + 0.00000000E+00-7.61482664E-10 0.00000000E+00-4.13197110E-13-1.05188479E-03 +-2.79949782E-18-1.39193211E-03 0.00000000E+00-1.23386165E-02-1.09608352E-17 +-2.24375345E-02 0.00000000E+00 5.01140417E-03 1.01464726E-08 7.07039325E-09 +-1.61055597E-12 0.00000000E+00 1.18844306E-08 0.00000000E+00-1.85716606E-12 + 2.14426594E-03 5.03239378E-18 8.57762161E-03 2.04319392E-17 2.81713339E-03 + 0.00000000E+00 1.12688905E-02 0.00000000E+00 2.47100065E-02 2.90525835E-17 + 9.88415145E-02 1.26360496E-16 4.44670589E-02 0.00000000E+00 1.77882882E-01 + 0.00000000E+00-2.29265257E-04 1.07197462E-10 3.16206903E-09-1.29360787E-12 + 0.00000000E+00 1.24827704E-10 0.00000000E+00-1.51534493E-12 2.14432722E-03 + 4.98262469E-18-1.09271660E-03-2.48943771E-18 2.81721709E-03 0.00000000E+00 +-1.42537591E-03 0.00000000E+00 2.47107924E-02 2.91359571E-17-1.23717249E-02 +-2.51217038E-17 4.44686025E-02 0.00000000E+00-2.20383866E-02 0.00000000E+00 + 6.58072453E-03 0.00000000E+00 3.09721118E-05 0.00000000E+00 1.24458427E-03 +-4.66717884E-18 5.87224580E-06-2.20335315E-20 0.00000000E+00 5.26712703E-10 +-2.28187918E-04 4.46890440E-10 0.00000000E+00 5.26712703E-10-2.28187918E-04 + 4.46890440E-10 3.78129638E-02 0.00000000E+00-3.62408526E-07 0.00000000E+00 + 7.38560376E-03-2.76749755E-17 3.43510607E-07-1.04380797E-21 0.00000000E+00 +-1.26760070E-08 0.00000000E+00-1.18844306E-08 4.54618375E-03-1.08670212E-08 + 5.01140417E-03-1.01464726E-08 0.00000000E+00-1.26760070E-08 0.00000000E+00 +-1.18844306E-08 4.54618375E-03-1.08670212E-08 5.01140417E-03-1.01464726E-08 + 6.50928138E-03 0.00000000E+00-3.06615677E-05 0.00000000E+00 1.31230169E-03 +-4.87650804E-18-6.16659582E-06 2.29388208E-20 0.00000000E+00-7.66143530E-09 + 0.00000000E+00 7.27570100E-10 4.56480308E-03-6.52256408E-09-2.27488326E-04 + 6.20467873E-10 0.00000000E+00-7.66143530E-09 0.00000000E+00 7.27570100E-10 + 4.56480308E-03-6.52256408E-09-2.27488326E-04 6.20467873E-10-3.09987668E-05 + 0.00000000E+00-1.39852334E-07 0.00000000E+00-5.84803556E-06 2.19195393E-20 +-2.64496313E-08 9.92014838E-23 0.00000000E+00 4.13197110E-13 3.75570681E-09 + 3.74879498E-13 0.00000000E+00 4.13197110E-13 3.75570681E-09 3.74879498E-13 +-3.62408526E-07 0.00000000E+00 3.70900439E-07 0.00000000E+00 3.43510607E-07 +-1.04380797E-21 7.24458804E-08-2.71060893E-22 0.00000000E+00 5.04394958E-11 + 0.00000000E+00 1.85716606E-12-1.77773451E-05 4.32704077E-11 7.07039325E-09 + 1.61055597E-12 0.00000000E+00 5.04394958E-11 0.00000000E+00 1.85716606E-12 +-1.77773451E-05 4.32704077E-11 7.07039325E-09 1.61055597E-12 3.06365241E-05 + 0.00000000E+00-1.38334004E-07 0.00000000E+00 6.19138708E-06-2.29843270E-20 +-2.78887831E-08 1.03641438E-22 0.00000000E+00-2.77773453E-11 0.00000000E+00 + 1.51534493E-12 1.78613161E-05-2.36382481E-11 3.16206903E-09 1.29360787E-12 + 0.00000000E+00-2.77773453E-11 0.00000000E+00 1.51534493E-12 1.78613161E-05 +-2.36382481E-11 3.16206903E-09 1.29360787E-12 1.24458427E-03 4.66717884E-18 + 5.87224580E-06 2.20335315E-20 6.58072453E-03 0.00000000E+00 3.09721118E-05 + 0.00000000E+00 2.28187918E-04 4.46890440E-10 0.00000000E+00 5.26712703E-10 + 2.28187918E-04 4.46890440E-10 0.00000000E+00 5.26712703E-10 7.38560376E-03 + 2.76749755E-17 3.43510607E-07 1.04380797E-21 3.78129638E-02 0.00000000E+00 +-3.62408526E-07 0.00000000E+00-4.54618375E-03-1.08670212E-08-5.01140417E-03 +-1.01464726E-08 0.00000000E+00-1.26760070E-08 0.00000000E+00-1.18844306E-08 +-4.54618375E-03-1.08670212E-08-5.01140417E-03-1.01464726E-08 0.00000000E+00 +-1.26760070E-08 0.00000000E+00-1.18844306E-08 1.31230169E-03 4.87650804E-18 +-6.16659582E-06-2.29388208E-20 6.50928138E-03 0.00000000E+00-3.06615677E-05 + 0.00000000E+00-4.56480308E-03-6.52256408E-09 2.27488326E-04 6.20467873E-10 + 0.00000000E+00-7.66143530E-09 0.00000000E+00 7.27570100E-10-4.56480308E-03 +-6.52256408E-09 2.27488326E-04 6.20467873E-10 0.00000000E+00-7.66143530E-09 + 0.00000000E+00 7.27570100E-10-5.84803556E-06-2.19195393E-20-2.64496313E-08 +-9.92014838E-23-3.09987668E-05 0.00000000E+00-1.39852334E-07 0.00000000E+00 +-3.75570681E-09 3.74879498E-13 0.00000000E+00 4.13197110E-13-3.75570681E-09 + 3.74879498E-13 0.00000000E+00 4.13197110E-13 3.43510607E-07 1.04380797E-21 + 7.24458804E-08 2.71060893E-22-3.62408526E-07 0.00000000E+00 3.70900439E-07 + 0.00000000E+00 1.77773451E-05 4.32704077E-11-7.07039325E-09 1.61055597E-12 + 0.00000000E+00 5.04394958E-11 0.00000000E+00 1.85716606E-12 1.77773451E-05 + 4.32704077E-11-7.07039325E-09 1.61055597E-12 0.00000000E+00 5.04394958E-11 + 0.00000000E+00 1.85716606E-12 6.19138708E-06 2.29843270E-20-2.78887831E-08 +-1.03641438E-22 3.06365241E-05 0.00000000E+00-1.38334004E-07 0.00000000E+00 +-1.78613161E-05-2.36382481E-11-3.16206903E-09 1.29360787E-12 0.00000000E+00 +-2.77773453E-11 0.00000000E+00 1.51534493E-12-1.78613161E-05-2.36382481E-11 +-3.16206903E-09 1.29360787E-12 0.00000000E+00-2.77773453E-11 0.00000000E+00 + 1.51534493E-12 0.00000000E+00 1.34460767E-08 0.00000000E+00 5.20922842E-11 +-4.53926966E-03 1.15647113E-08-1.77623223E-05 4.47699256E-11 2.75059506E-03 + 0.00000000E+00 2.06327321E-03-6.16559751E-18 2.75059506E-03 0.00000000E+00 + 2.06327321E-03-6.16559751E-18 0.00000000E+00 1.26760070E-08 0.00000000E+00 +-5.04394958E-11-4.54618375E-03 1.08670212E-08 1.77773451E-05-4.32704077E-11 + 2.22706126E-02 0.00000000E+00 2.81713339E-03 0.00000000E+00 1.68296980E-02 +-4.48406387E-17 2.14426594E-03-5.03239378E-18 2.22706126E-02 0.00000000E+00 + 2.81713339E-03 0.00000000E+00 1.68296980E-02-4.48406387E-17 2.14426594E-03 +-5.03239378E-18 0.00000000E+00-7.61482664E-10 0.00000000E+00-4.13197110E-13 + 2.26075347E-04-6.59647223E-10-3.75570681E-09-3.74879498E-13-1.39193211E-03 + 0.00000000E+00-1.05188479E-03 2.79949782E-18-1.39193211E-03 0.00000000E+00 +-1.05188479E-03 2.79949782E-18 0.00000000E+00 1.18844306E-08 0.00000000E+00 +-1.85716606E-12-5.01140417E-03 1.01464726E-08-7.07039325E-09-1.61055597E-12 + 2.81713339E-03 0.00000000E+00 1.12688905E-02 0.00000000E+00 2.14426594E-03 +-5.03239378E-18 8.57762161E-03-2.04319392E-17 2.81713339E-03 0.00000000E+00 + 1.12688905E-02 0.00000000E+00 2.14426594E-03-5.03239378E-18 8.57762161E-03 +-2.04319392E-17 0.00000000E+00 1.24827704E-10 0.00000000E+00-1.51534493E-12 + 2.29265257E-04 1.07197462E-10-3.16206903E-09-1.29360787E-12 2.81721709E-03 + 0.00000000E+00-1.42537591E-03 0.00000000E+00 2.14432722E-03-4.98262469E-18 +-1.09271660E-03 2.48943771E-18 2.81721709E-03 0.00000000E+00-1.42537591E-03 + 0.00000000E+00 2.14432722E-03-4.98262469E-18-1.09271660E-03 2.48943771E-18 + 4.53926966E-03 1.15647113E-08 1.77623223E-05 4.47699256E-11 0.00000000E+00 + 1.34460767E-08 0.00000000E+00 5.20922842E-11 2.06327321E-03 6.16559751E-18 + 2.75059506E-03 0.00000000E+00 2.06327321E-03 6.16559751E-18 2.75059506E-03 + 0.00000000E+00 4.54618375E-03 1.08670212E-08-1.77773451E-05-4.32704077E-11 + 0.00000000E+00 1.26760070E-08 0.00000000E+00-5.04394958E-11 1.68296980E-02 + 4.48406387E-17 2.14426594E-03 5.03239378E-18 2.22706126E-02 0.00000000E+00 + 2.81713339E-03 0.00000000E+00 1.68296980E-02 4.48406387E-17 2.14426594E-03 + 5.03239378E-18 2.22706126E-02 0.00000000E+00 2.81713339E-03 0.00000000E+00 +-2.26075347E-04-6.59647223E-10 3.75570681E-09-3.74879498E-13 0.00000000E+00 +-7.61482664E-10 0.00000000E+00-4.13197110E-13-1.05188479E-03-2.79949782E-18 +-1.39193211E-03 0.00000000E+00-1.05188479E-03-2.79949782E-18-1.39193211E-03 + 0.00000000E+00 5.01140417E-03 1.01464726E-08 7.07039325E-09-1.61055597E-12 + 0.00000000E+00 1.18844306E-08 0.00000000E+00-1.85716606E-12 2.14426594E-03 + 5.03239378E-18 8.57762161E-03 2.04319392E-17 2.81713339E-03 0.00000000E+00 + 1.12688905E-02 0.00000000E+00 2.14426594E-03 5.03239378E-18 8.57762161E-03 + 2.04319392E-17 2.81713339E-03 0.00000000E+00 1.12688905E-02 0.00000000E+00 +-2.29265257E-04 1.07197462E-10 3.16206903E-09-1.29360787E-12 0.00000000E+00 + 1.24827704E-10 0.00000000E+00-1.51534493E-12 2.14432722E-03 4.98262469E-18 +-1.09271660E-03-2.48943771E-18 2.81721709E-03 0.00000000E+00-1.42537591E-03 + 0.00000000E+00 2.14432722E-03 4.98262469E-18-1.09271660E-03-2.48943771E-18 + 2.81721709E-03 0.00000000E+00-1.42537591E-03 0.00000000E+00 0.00000000E+00 + 1.34460767E-08 0.00000000E+00 5.20922842E-11-4.53926966E-03 1.15647113E-08 +-1.77623223E-05 4.47699256E-11 2.75059506E-03 0.00000000E+00 2.06327321E-03 +-6.16559751E-18 4.52830791E-02 0.00000000E+00 2.46444594E-02-1.47907573E-17 + 0.00000000E+00 1.26760070E-08 0.00000000E+00-5.04394958E-11-4.54618375E-03 + 1.08670212E-08 1.77773451E-05-4.32704077E-11 2.22706126E-02 0.00000000E+00 + 2.81713339E-03 0.00000000E+00 1.68296980E-02-4.48406387E-17 2.14426594E-03 +-5.03239378E-18 3.58988369E-01 0.00000000E+00 4.44670589E-02 0.00000000E+00 + 1.97416506E-01-1.66835622E-16 2.47100065E-02-2.90525835E-17 0.00000000E+00 +-7.61482664E-10 0.00000000E+00-4.13197110E-13 2.26075347E-04-6.59647223E-10 +-3.75570681E-09-3.74879498E-13-1.39193211E-03 0.00000000E+00-1.05188479E-03 + 2.79949782E-18-2.24375345E-02 0.00000000E+00-1.23386165E-02 1.09608352E-17 + 0.00000000E+00 1.18844306E-08 0.00000000E+00-1.85716606E-12-5.01140417E-03 + 1.01464726E-08-7.07039325E-09-1.61055597E-12 2.81713339E-03 0.00000000E+00 + 1.12688905E-02 0.00000000E+00 2.14426594E-03-5.03239378E-18 8.57762161E-03 +-2.04319392E-17 4.44670589E-02 0.00000000E+00 1.77882882E-01 0.00000000E+00 + 2.47100065E-02-2.90525835E-17 9.88415145E-02-1.26360496E-16 0.00000000E+00 + 1.24827704E-10 0.00000000E+00-1.51534493E-12 2.29265257E-04 1.07197462E-10 +-3.16206903E-09-1.29360787E-12 2.81721709E-03 0.00000000E+00-1.42537591E-03 + 0.00000000E+00 2.14432722E-03-4.98262469E-18-1.09271660E-03 2.48943771E-18 + 4.44686025E-02 0.00000000E+00-2.20383866E-02 0.00000000E+00 2.47107924E-02 +-2.91359571E-17-1.23717249E-02 2.51217038E-17 4.53926966E-03 1.15647113E-08 + 1.77623223E-05 4.47699256E-11 0.00000000E+00 1.34460767E-08 0.00000000E+00 + 5.20922842E-11 2.06327321E-03 6.16559751E-18 2.75059506E-03 0.00000000E+00 + 2.46444594E-02 1.47907573E-17 4.52830791E-02 0.00000000E+00 4.54618375E-03 + 1.08670212E-08-1.77773451E-05-4.32704077E-11 0.00000000E+00 1.26760070E-08 + 0.00000000E+00-5.04394958E-11 1.68296980E-02 4.48406387E-17 2.14426594E-03 + 5.03239378E-18 2.22706126E-02 0.00000000E+00 2.81713339E-03 0.00000000E+00 + 1.97416506E-01 1.66835622E-16 2.47100065E-02 2.90525835E-17 3.58988369E-01 + 0.00000000E+00 4.44670589E-02 0.00000000E+00 5.97945193E-03 1.62930467E-08 + 3.10721744E-05 8.45799959E-11 0.00000000E+00 1.87358990E-08 0.00000000E+00 + 9.72749140E-11 2.59949574E-03 4.27672608E-18 3.53626850E-03 0.00000000E+00 + 3.26098680E-02 5.78076322E-17 6.16393998E-02 0.00000000E+00 5.99367294E-03 + 1.62489536E-08-3.11132090E-05-8.44633404E-11 0.00000000E+00 1.87119159E-08 + 0.00000000E+00-9.72164760E-11 2.13547864E-02 5.52055320E-17 2.73941246E-03 + 8.90375909E-18 2.87529656E-02 0.00000000E+00 3.65206025E-03 0.00000000E+00 + 2.61326225E-01 2.84711866E-16 3.27216646E-02 1.70917629E-17 4.87020872E-01 + 0.00000000E+00 6.01218408E-02 0.00000000E+00 8.85519020E-03 0.00000000E+00 + 5.53261909E-05 0.00000000E+00 1.55073862E-03-5.00778496E-18 9.72220608E-06 +-3.18707215E-20 0.00000000E+00 9.32650430E-10-3.01486722E-04 8.06329969E-10 + 0.00000000E+00 9.32650430E-10-3.01486722E-04 8.06329969E-10 4.45432806E-02 + 0.00000000E+00-4.08758294E-05 0.00000000E+00 8.11293721E-03-2.92498338E-17 +-6.80657944E-06 2.04842944E-20 0.00000000E+00-1.87119159E-08 0.00000000E+00 +-1.79367425E-08 5.99367294E-03-1.62489536E-08 5.79674668E-03-1.55095688E-08 + 0.00000000E+00-1.87119159E-08 0.00000000E+00-1.79367425E-08 5.99367294E-03 +-1.62489536E-08 5.79674668E-03-1.55095688E-08 6.58072453E-03 0.00000000E+00 +-3.09987668E-05 0.00000000E+00 1.24458427E-03-4.66717884E-18-5.84803556E-06 + 2.19195393E-20 0.00000000E+00-1.34460767E-08 0.00000000E+00 7.61482664E-10 + 4.53926966E-03-1.15647113E-08-2.26075347E-04 6.59647223E-10 0.00000000E+00 +-1.34460767E-08 0.00000000E+00 7.61482664E-10 4.53926966E-03-1.15647113E-08 +-2.26075347E-04 6.59647223E-10-2.97141383E-04-8.19599366E-10 1.02586464E-08 +-2.91638816E-14 0.00000000E+00-9.39771395E-10 0.00000000E+00-1.46094951E-14 +-1.33472705E-03-3.29512129E-18-1.79708219E-03 0.00000000E+00-1.63328831E-02 +-1.87248488E-17-3.04403101E-02 0.00000000E+00 5.79674668E-03 1.55095688E-08 +-3.36540984E-06-9.24957453E-12 0.00000000E+00 1.79367425E-08 0.00000000E+00 +-1.06094646E-11 2.73941246E-03 8.90375909E-18 9.59088113E-03 2.79500114E-17 + 3.65206025E-03 0.00000000E+00 1.27931149E-02 0.00000000E+00 3.27216646E-02 + 1.70917629E-17 1.14720882E-01 8.36334492E-17 6.01218408E-02 0.00000000E+00 + 2.10991912E-01 0.00000000E+00-2.28187918E-04-4.46890440E-10 3.75570681E-09 +-3.74879498E-13 0.00000000E+00-5.26712703E-10 0.00000000E+00-4.13197110E-13 + 2.06327321E-03 6.16559751E-18-1.05188479E-03-2.79949782E-18 2.75059506E-03 + 0.00000000E+00-1.39193211E-03 0.00000000E+00 2.46444594E-02 1.47907573E-17 +-1.23386165E-02-1.09608352E-17 4.52830791E-02 0.00000000E+00-2.24375345E-02 + 0.00000000E+00 0.00000000E+00-9.39771395E-10 0.00000000E+00-1.46094951E-14 + 2.97141383E-04-8.19599366E-10-1.02586464E-08-2.91638816E-14-1.79708219E-03 + 0.00000000E+00-1.33472705E-03 3.29512129E-18-3.04403101E-02 0.00000000E+00 +-1.63328831E-02 1.87248488E-17 0.00000000E+00 1.79367425E-08 0.00000000E+00 +-1.06094646E-11-5.79674668E-03 1.55095688E-08 3.36540984E-06-9.24957453E-12 + 3.65206025E-03 0.00000000E+00 1.27931149E-02 0.00000000E+00 2.73941246E-03 +-8.90375909E-18 9.59088113E-03-2.79500114E-17 6.01218408E-02 0.00000000E+00 + 2.10991912E-01 0.00000000E+00 3.27216646E-02-1.70917629E-17 1.14720882E-01 +-8.36334492E-17 0.00000000E+00-5.26712703E-10 0.00000000E+00-4.13197110E-13 + 2.28187918E-04-4.46890440E-10-3.75570681E-09-3.74879498E-13 2.75059506E-03 + 0.00000000E+00-1.39193211E-03 0.00000000E+00 2.06327321E-03-6.16559751E-18 +-1.05188479E-03 2.79949782E-18 4.52830791E-02 0.00000000E+00-2.24375345E-02 + 0.00000000E+00 2.46444594E-02-1.47907573E-17-1.23386165E-02 1.09608352E-17 +-2.97141383E-04-8.19599366E-10 1.02586464E-08-2.91638816E-14 0.00000000E+00 +-9.39771395E-10 0.00000000E+00-1.46094951E-14-1.33472705E-03-3.29512129E-18 +-1.79708219E-03 0.00000000E+00-1.33472705E-03-3.29512129E-18-1.79708219E-03 + 0.00000000E+00 5.79674668E-03 1.55095688E-08-3.36540984E-06-9.24957453E-12 + 0.00000000E+00 1.79367425E-08 0.00000000E+00-1.06094646E-11 2.73941246E-03 + 8.90375909E-18 9.59088113E-03 2.79500114E-17 3.65206025E-03 0.00000000E+00 + 1.27931149E-02 0.00000000E+00 2.73941246E-03 8.90375909E-18 9.59088113E-03 + 2.79500114E-17 3.65206025E-03 0.00000000E+00 1.27931149E-02 0.00000000E+00 +-2.28187918E-04-4.46890440E-10 3.75570681E-09-3.74879498E-13 0.00000000E+00 +-5.26712703E-10 0.00000000E+00-4.13197110E-13 2.06327321E-03 6.16559751E-18 +-1.05188479E-03-2.79949782E-18 2.75059506E-03 0.00000000E+00-1.39193211E-03 + 0.00000000E+00 2.06327321E-03 6.16559751E-18-1.05188479E-03-2.79949782E-18 + 2.75059506E-03 0.00000000E+00-1.39193211E-03 0.00000000E+00 0.00000000E+00 +-9.39771395E-10 0.00000000E+00-1.46094951E-14 2.97141383E-04-8.19599366E-10 +-1.02586464E-08-2.91638816E-14-1.79708219E-03 0.00000000E+00-1.33472705E-03 + 3.29512129E-18-1.79708219E-03 0.00000000E+00-1.33472705E-03 3.29512129E-18 + 0.00000000E+00 1.79367425E-08 0.00000000E+00-1.06094646E-11-5.79674668E-03 + 1.55095688E-08 3.36540984E-06-9.24957453E-12 3.65206025E-03 0.00000000E+00 + 1.27931149E-02 0.00000000E+00 2.73941246E-03-8.90375909E-18 9.59088113E-03 +-2.79500114E-17 3.65206025E-03 0.00000000E+00 1.27931149E-02 0.00000000E+00 + 2.73941246E-03-8.90375909E-18 9.59088113E-03-2.79500114E-17 0.00000000E+00 +-5.26712703E-10 0.00000000E+00-4.13197110E-13 2.28187918E-04-4.46890440E-10 +-3.75570681E-09-3.74879498E-13 2.75059506E-03 0.00000000E+00-1.39193211E-03 + 0.00000000E+00 2.06327321E-03-6.16559751E-18-1.05188479E-03 2.79949782E-18 + 2.75059506E-03 0.00000000E+00-1.39193211E-03 0.00000000E+00 2.06327321E-03 +-6.16559751E-18-1.05188479E-03 2.79949782E-18-9.66714802E-06-3.07525469E-20 +-5.80972675E-08-1.87704649E-22-5.53929930E-05 0.00000000E+00-3.31753710E-07 + 0.00000000E+00-1.02586464E-08 2.91638816E-14 0.00000000E+00 1.46094951E-14 +-1.02586464E-08 2.91638816E-14 0.00000000E+00 1.46094951E-14-6.80657944E-06 +-2.04842944E-20 1.13208269E-07 3.95626511E-22-4.08758294E-05 0.00000000E+00 + 6.28204157E-07 0.00000000E+00 3.11132090E-05 8.44633404E-11 3.36540984E-06 + 9.24957453E-12 0.00000000E+00 9.72164760E-11 0.00000000E+00 1.06094646E-11 + 3.11132090E-05 8.44633404E-11 3.36540984E-06 9.24957453E-12 0.00000000E+00 + 9.72164760E-11 0.00000000E+00 1.06094646E-11 5.87224580E-06 2.20335315E-20 +-2.64496313E-08-9.92014838E-23 3.09721118E-05 0.00000000E+00-1.39852334E-07 + 0.00000000E+00-1.77623223E-05-4.47699256E-11-3.75570681E-09 3.74879498E-13 + 0.00000000E+00-5.20922842E-11 0.00000000E+00 4.13197110E-13-1.77623223E-05 +-4.47699256E-11-3.75570681E-09 3.74879498E-13 0.00000000E+00-5.20922842E-11 + 0.00000000E+00 4.13197110E-13 1.55073862E-03 5.00778496E-18 9.72220608E-06 + 3.18707215E-20 8.85519020E-03 0.00000000E+00 5.53261909E-05 0.00000000E+00 + 3.01486722E-04 8.06329969E-10 0.00000000E+00 9.32650430E-10 3.01486722E-04 + 8.06329969E-10 0.00000000E+00 9.32650430E-10 8.11293721E-03 2.92498338E-17 +-6.80657944E-06-2.04842944E-20 4.45432806E-02 0.00000000E+00-4.08758294E-05 + 0.00000000E+00-5.99367294E-03-1.62489536E-08-5.79674668E-03-1.55095688E-08 + 0.00000000E+00-1.87119159E-08 0.00000000E+00-1.79367425E-08-5.99367294E-03 +-1.62489536E-08-5.79674668E-03-1.55095688E-08 0.00000000E+00-1.87119159E-08 + 0.00000000E+00-1.79367425E-08 1.24458427E-03 4.66717884E-18-5.84803556E-06 +-2.19195393E-20 6.58072453E-03 0.00000000E+00-3.09987668E-05 0.00000000E+00 +-4.53926966E-03-1.15647113E-08 2.26075347E-04 6.59647223E-10 0.00000000E+00 +-1.34460767E-08 0.00000000E+00 7.61482664E-10-4.53926966E-03-1.15647113E-08 + 2.26075347E-04 6.59647223E-10 0.00000000E+00-1.34460767E-08 0.00000000E+00 + 7.61482664E-10-5.53929930E-05 0.00000000E+00-3.31753710E-07 0.00000000E+00 +-9.66714802E-06 3.07525469E-20-5.80972675E-08 1.87704649E-22 0.00000000E+00 + 1.46094951E-14 1.02586464E-08 2.91638816E-14 0.00000000E+00 1.46094951E-14 + 1.02586464E-08 2.91638816E-14-4.08758294E-05 0.00000000E+00 6.28204157E-07 + 0.00000000E+00-6.80657944E-06 2.04842944E-20 1.13208269E-07-3.95626511E-22 + 0.00000000E+00 9.72164760E-11 0.00000000E+00 1.06094646E-11-3.11132090E-05 + 8.44633404E-11-3.36540984E-06 9.24957453E-12 0.00000000E+00 9.72164760E-11 + 0.00000000E+00 1.06094646E-11-3.11132090E-05 8.44633404E-11-3.36540984E-06 + 9.24957453E-12 3.09721118E-05 0.00000000E+00-1.39852334E-07 0.00000000E+00 + 5.87224580E-06-2.20335315E-20-2.64496313E-08 9.92014838E-23 0.00000000E+00 +-5.20922842E-11 0.00000000E+00 4.13197110E-13 1.77623223E-05-4.47699256E-11 + 3.75570681E-09 3.74879498E-13 0.00000000E+00-5.20922842E-11 0.00000000E+00 + 4.13197110E-13 1.77623223E-05-4.47699256E-11 3.75570681E-09 3.74879498E-13 + 0.00000000E+00 1.87358990E-08 0.00000000E+00 9.72749140E-11-5.97945193E-03 + 1.62930467E-08-3.10721744E-05 8.45799959E-11 3.53626850E-03 0.00000000E+00 + 2.59949574E-03-4.27672608E-18 3.53626850E-03 0.00000000E+00 2.59949574E-03 +-4.27672608E-18 0.00000000E+00 1.87119159E-08 0.00000000E+00-9.72164760E-11 +-5.99367294E-03 1.62489536E-08 3.11132090E-05-8.44633404E-11 2.87529656E-02 + 0.00000000E+00 3.65206025E-03 0.00000000E+00 2.13547864E-02-5.52055320E-17 + 2.73941246E-03-8.90375909E-18 2.87529656E-02 0.00000000E+00 3.65206025E-03 + 0.00000000E+00 2.13547864E-02-5.52055320E-17 2.73941246E-03-8.90375909E-18 + 5.97945193E-03 1.62930467E-08 3.10721744E-05 8.45799959E-11 0.00000000E+00 + 1.87358990E-08 0.00000000E+00 9.72749140E-11 2.59949574E-03 4.27672608E-18 + 3.53626850E-03 0.00000000E+00 2.59949574E-03 4.27672608E-18 3.53626850E-03 + 0.00000000E+00 5.99367294E-03 1.62489536E-08-3.11132090E-05-8.44633404E-11 + 0.00000000E+00 1.87119159E-08 0.00000000E+00-9.72164760E-11 2.13547864E-02 + 5.52055320E-17 2.73941246E-03 8.90375909E-18 2.87529656E-02 0.00000000E+00 + 3.65206025E-03 0.00000000E+00 2.13547864E-02 5.52055320E-17 2.73941246E-03 + 8.90375909E-18 2.87529656E-02 0.00000000E+00 3.65206025E-03 0.00000000E+00 + 0.00000000E+00 1.87358990E-08 0.00000000E+00 9.72749140E-11-5.97945193E-03 + 1.62930467E-08-3.10721744E-05 8.45799959E-11 3.53626850E-03 0.00000000E+00 + 2.59949574E-03-4.27672608E-18 6.16393998E-02 0.00000000E+00 3.26098680E-02 +-5.78076322E-17 0.00000000E+00 1.87119159E-08 0.00000000E+00-9.72164760E-11 +-5.99367294E-03 1.62489536E-08 3.11132090E-05-8.44633404E-11 2.87529656E-02 + 0.00000000E+00 3.65206025E-03 0.00000000E+00 2.13547864E-02-5.52055320E-17 + 2.73941246E-03-8.90375909E-18 4.87020872E-01 0.00000000E+00 6.01218408E-02 + 0.00000000E+00 2.61326225E-01-2.84711866E-16 3.27216646E-02-1.70917629E-17 + 5.91820629E-03 1.62710031E-08 3.07569146E-05 8.45825574E-11 0.00000000E+00 + 1.87652591E-08 0.00000000E+00 9.75284361E-11 2.46268171E-03 4.00014899E-18 + 3.42183754E-03 0.00000000E+00 3.24992731E-02 6.30951619E-17 6.32474231E-02 + 0.00000000E+00 5.93483151E-03 1.63218133E-08-3.08048860E-05-8.47319133E-11 + 0.00000000E+00 1.88048132E-08 0.00000000E+00-9.76458784E-11 2.02477481E-02 + 2.40474954E-17 2.59948652E-03 2.90270919E-18 2.78319708E-02 0.00000000E+00 + 3.53626111E-03 0.00000000E+00 2.60435396E-01 5.40907831E-16 3.26097671E-02 + 6.66000030E-17 4.99517269E-01 0.00000000E+00 6.16388531E-02 0.00000000E+00 + 8.99981963E-03 0.00000000E+00 5.62277661E-05 0.00000000E+00 1.43802116E-03 +-3.83849292E-18 9.01670128E-06-2.36657650E-20 0.00000000E+00 9.44429965E-10 +-2.98853203E-04 8.21894993E-10 0.00000000E+00 9.44429965E-10-2.98853203E-04 + 8.21894993E-10 5.15743796E-02 0.00000000E+00-9.73982466E-07 0.00000000E+00 + 8.63208934E-03-2.32733225E-17 7.58863198E-07-9.58270535E-21 0.00000000E+00 +-1.88048132E-08 0.00000000E+00-2.06696984E-08 5.93483151E-03-1.63218133E-08 + 6.55366955E-03-1.79700113E-08 0.00000000E+00-1.88048132E-08 0.00000000E+00 +-2.06696984E-08 5.93483151E-03-1.63218133E-08 6.55366955E-03-1.79700113E-08 + 8.85519020E-03 0.00000000E+00-5.53929930E-05 0.00000000E+00 1.55073862E-03 +-5.00778496E-18-9.66714802E-06 3.07525469E-20 0.00000000E+00-1.87358990E-08 + 0.00000000E+00 9.39771395E-10 5.97945193E-03-1.62930467E-08-2.97141383E-04 + 8.19599366E-10 0.00000000E+00-1.87358990E-08 0.00000000E+00 9.39771395E-10 + 5.97945193E-03-1.62930467E-08-2.97141383E-04 8.19599366E-10-2.93773253E-04 +-8.06316730E-10 1.19928340E-08 3.73389913E-14 0.00000000E+00-9.32280177E-10 + 0.00000000E+00 2.93605608E-14-1.26554206E-03-1.72571455E-18-1.73952466E-03 + 0.00000000E+00-1.62772601E-02-3.24237912E-17-3.12215690E-02 0.00000000E+00 + 6.55366955E-03 1.79700113E-08 2.22782230E-08-3.51516527E-14 0.00000000E+00 + 2.06696984E-08 0.00000000E+00-7.67951082E-14 2.59948652E-03 2.90270919E-18 + 1.03990755E-02 1.64253247E-17 3.53626111E-03 0.00000000E+00 1.41455471E-02 + 0.00000000E+00 3.26097671E-02 6.66000030E-17 1.30439728E-01 2.32766576E-16 + 6.16388531E-02 0.00000000E+00 2.46588995E-01 0.00000000E+00-3.01486722E-04 +-8.06329969E-10 1.02586464E-08-2.91638816E-14 0.00000000E+00-9.32650430E-10 + 0.00000000E+00-1.46094951E-14 2.59949574E-03 4.27672608E-18-1.33472705E-03 +-3.29512129E-18 3.53626850E-03 0.00000000E+00-1.79708219E-03 0.00000000E+00 + 3.26098680E-02 5.78076322E-17-1.63328831E-02-1.87248488E-17 6.16393998E-02 + 0.00000000E+00-3.04403101E-02 0.00000000E+00 0.00000000E+00-9.32280177E-10 + 0.00000000E+00 2.93605608E-14 2.93773253E-04-8.06316730E-10-1.19928340E-08 + 3.73389913E-14-1.73952466E-03 0.00000000E+00-1.26554206E-03 1.72571455E-18 +-3.12215690E-02 0.00000000E+00-1.62772601E-02 3.24237912E-17 0.00000000E+00 + 2.06696984E-08 0.00000000E+00-7.67951082E-14-6.55366955E-03 1.79700113E-08 +-2.22782230E-08-3.51516527E-14 3.53626111E-03 0.00000000E+00 1.41455471E-02 + 0.00000000E+00 2.59948652E-03-2.90270919E-18 1.03990755E-02-1.64253247E-17 + 6.16388531E-02 0.00000000E+00 2.46588995E-01 0.00000000E+00 3.26097671E-02 +-6.66000030E-17 1.30439728E-01-2.32766576E-16 0.00000000E+00-9.32650430E-10 + 0.00000000E+00-1.46094951E-14 3.01486722E-04-8.06329969E-10-1.02586464E-08 +-2.91638816E-14 3.53626850E-03 0.00000000E+00-1.79708219E-03 0.00000000E+00 + 2.59949574E-03-4.27672608E-18-1.33472705E-03 3.29512129E-18 6.16393998E-02 + 0.00000000E+00-3.04403101E-02 0.00000000E+00 3.26098680E-02-5.78076322E-17 +-1.63328831E-02 1.87248488E-17-2.93773253E-04-8.06316730E-10 1.19928340E-08 + 3.73389913E-14 0.00000000E+00-9.32280177E-10 0.00000000E+00 2.93605608E-14 +-1.26554206E-03-1.72571455E-18-1.73952466E-03 0.00000000E+00-1.26554206E-03 +-1.72571455E-18-1.73952466E-03 0.00000000E+00 6.55366955E-03 1.79700113E-08 + 2.22782230E-08-3.51516527E-14 0.00000000E+00 2.06696984E-08 0.00000000E+00 +-7.67951082E-14 2.59948652E-03 2.90270919E-18 1.03990755E-02 1.64253247E-17 + 3.53626111E-03 0.00000000E+00 1.41455471E-02 0.00000000E+00 2.59948652E-03 + 2.90270919E-18 1.03990755E-02 1.64253247E-17 3.53626111E-03 0.00000000E+00 + 1.41455471E-02 0.00000000E+00-3.01486722E-04-8.06329969E-10 1.02586464E-08 +-2.91638816E-14 0.00000000E+00-9.32650430E-10 0.00000000E+00-1.46094951E-14 + 2.59949574E-03 4.27672608E-18-1.33472705E-03-3.29512129E-18 3.53626850E-03 + 0.00000000E+00-1.79708219E-03 0.00000000E+00 2.59949574E-03 4.27672608E-18 +-1.33472705E-03-3.29512129E-18 3.53626850E-03 0.00000000E+00-1.79708219E-03 + 0.00000000E+00 0.00000000E+00-9.32280177E-10 0.00000000E+00 2.93605608E-14 + 2.93773253E-04-8.06316730E-10-1.19928340E-08 3.73389913E-14-1.73952466E-03 + 0.00000000E+00-1.26554206E-03 1.72571455E-18-1.73952466E-03 0.00000000E+00 +-1.26554206E-03 1.72571455E-18 0.00000000E+00 2.06696984E-08 0.00000000E+00 +-7.67951082E-14-6.55366955E-03 1.79700113E-08-2.22782230E-08-3.51516527E-14 + 3.53626111E-03 0.00000000E+00 1.41455471E-02 0.00000000E+00 2.59948652E-03 +-2.90270919E-18 1.03990755E-02-1.64253247E-17 3.53626111E-03 0.00000000E+00 + 1.41455471E-02 0.00000000E+00 2.59948652E-03-2.90270919E-18 1.03990755E-02 +-1.64253247E-17 0.00000000E+00-9.32650430E-10 0.00000000E+00-1.46094951E-14 + 3.01486722E-04-8.06329969E-10-1.02586464E-08-2.91638816E-14 3.53626850E-03 + 0.00000000E+00-1.79708219E-03 0.00000000E+00 2.59949574E-03-4.27672608E-18 +-1.33472705E-03 3.29512129E-18 3.53626850E-03 0.00000000E+00-1.79708219E-03 + 0.00000000E+00 2.59949574E-03-4.27672608E-18-1.33472705E-03 3.29512129E-18 +-8.96336248E-06-2.42966068E-20-5.38746809E-08-1.43499321E-22-5.63000931E-05 + 0.00000000E+00-3.37174109E-07 0.00000000E+00-1.19928340E-08-3.73389913E-14 + 0.00000000E+00-2.93605608E-14-1.19928340E-08-3.73389913E-14 0.00000000E+00 +-2.93605608E-14 7.58863198E-07 9.58270535E-21 1.49275093E-07 4.19548066E-22 +-9.73982466E-07 0.00000000E+00 8.91836805E-07 0.00000000E+00 3.08048860E-05 + 8.47319133E-11-2.22782230E-08 3.51516527E-14 0.00000000E+00 9.76458784E-11 + 0.00000000E+00 7.67951082E-14 3.08048860E-05 8.47319133E-11-2.22782230E-08 + 3.51516527E-14 0.00000000E+00 9.76458784E-11 0.00000000E+00 7.67951082E-14 + 9.72220608E-06 3.18707215E-20-5.80972675E-08-1.87704649E-22 5.53261909E-05 + 0.00000000E+00-3.31753710E-07 0.00000000E+00-3.10721744E-05-8.45799959E-11 +-1.02586464E-08 2.91638816E-14 0.00000000E+00-9.72749140E-11 0.00000000E+00 + 1.46094951E-14-3.10721744E-05-8.45799959E-11-1.02586464E-08 2.91638816E-14 + 0.00000000E+00-9.72749140E-11 0.00000000E+00 1.46094951E-14 1.43802116E-03 + 3.83849292E-18 9.01670128E-06 2.36657650E-20 8.99981963E-03 0.00000000E+00 + 5.62277661E-05 0.00000000E+00 2.98853203E-04 8.21894993E-10 0.00000000E+00 + 9.44429965E-10 2.98853203E-04 8.21894993E-10 0.00000000E+00 9.44429965E-10 + 8.63208934E-03 2.32733225E-17 7.58863198E-07 9.58270535E-21 5.15743796E-02 + 0.00000000E+00-9.73982466E-07 0.00000000E+00-5.93483151E-03-1.63218133E-08 +-6.55366955E-03-1.79700113E-08 0.00000000E+00-1.88048132E-08 0.00000000E+00 +-2.06696984E-08-5.93483151E-03-1.63218133E-08-6.55366955E-03-1.79700113E-08 + 0.00000000E+00-1.88048132E-08 0.00000000E+00-2.06696984E-08 1.55073862E-03 + 5.00778496E-18-9.66714802E-06-3.07525469E-20 8.85519020E-03 0.00000000E+00 +-5.53929930E-05 0.00000000E+00-5.97945193E-03-1.62930467E-08 2.97141383E-04 + 8.19599366E-10 0.00000000E+00-1.87358990E-08 0.00000000E+00 9.39771395E-10 +-5.97945193E-03-1.62930467E-08 2.97141383E-04 8.19599366E-10 0.00000000E+00 +-1.87358990E-08 0.00000000E+00 9.39771395E-10-5.63000931E-05 0.00000000E+00 +-3.37174109E-07 0.00000000E+00-8.96336248E-06 2.42966068E-20-5.38746809E-08 + 1.43499321E-22 0.00000000E+00-2.93605608E-14 1.19928340E-08-3.73389913E-14 + 0.00000000E+00-2.93605608E-14 1.19928340E-08-3.73389913E-14-9.73982466E-07 + 0.00000000E+00 8.91836805E-07 0.00000000E+00 7.58863198E-07-9.58270535E-21 + 1.49275093E-07-4.19548066E-22 0.00000000E+00 9.76458784E-11 0.00000000E+00 + 7.67951082E-14-3.08048860E-05 8.47319133E-11 2.22782230E-08 3.51516527E-14 + 0.00000000E+00 9.76458784E-11 0.00000000E+00 7.67951082E-14-3.08048860E-05 + 8.47319133E-11 2.22782230E-08 3.51516527E-14 5.53261909E-05 0.00000000E+00 +-3.31753710E-07 0.00000000E+00 9.72220608E-06-3.18707215E-20-5.80972675E-08 + 1.87704649E-22 0.00000000E+00-9.72749140E-11 0.00000000E+00 1.46094951E-14 + 3.10721744E-05-8.45799959E-11 1.02586464E-08 2.91638816E-14 0.00000000E+00 +-9.72749140E-11 0.00000000E+00 1.46094951E-14 3.10721744E-05-8.45799959E-11 + 1.02586464E-08 2.91638816E-14 0.00000000E+00 1.87652591E-08 0.00000000E+00 + 9.75284361E-11-5.91820629E-03 1.62710031E-08-3.07569146E-05 8.45825574E-11 + 3.42183754E-03 0.00000000E+00 2.46268171E-03-4.00014899E-18 3.42183754E-03 + 0.00000000E+00 2.46268171E-03-4.00014899E-18 0.00000000E+00 1.88048132E-08 + 0.00000000E+00-9.76458784E-11-5.93483151E-03 1.63218133E-08 3.08048860E-05 +-8.47319133E-11 2.78319708E-02 0.00000000E+00 3.53626111E-03 0.00000000E+00 + 2.02477481E-02-2.40474954E-17 2.59948652E-03-2.90270919E-18 2.78319708E-02 + 0.00000000E+00 3.53626111E-03 0.00000000E+00 2.02477481E-02-2.40474954E-17 + 2.59948652E-03-2.90270919E-18 5.91820629E-03 1.62710031E-08 3.07569146E-05 + 8.45825574E-11 0.00000000E+00 1.87652591E-08 0.00000000E+00 9.75284361E-11 + 2.46268171E-03 4.00014899E-18 3.42183754E-03 0.00000000E+00 2.46268171E-03 + 4.00014899E-18 3.42183754E-03 0.00000000E+00 5.93483151E-03 1.63218133E-08 +-3.08048860E-05-8.47319133E-11 0.00000000E+00 1.88048132E-08 0.00000000E+00 +-9.76458784E-11 2.02477481E-02 2.40474954E-17 2.59948652E-03 2.90270919E-18 + 2.78319708E-02 0.00000000E+00 3.53626111E-03 0.00000000E+00 2.02477481E-02 + 2.40474954E-17 2.59948652E-03 2.90270919E-18 2.78319708E-02 0.00000000E+00 + 3.53626111E-03 0.00000000E+00 0.00000000E+00 1.87652591E-08 0.00000000E+00 + 9.75284361E-11-5.91820629E-03 1.62710031E-08-3.07569146E-05 8.45825574E-11 + 3.42183754E-03 0.00000000E+00 2.46268171E-03-4.00014899E-18 6.32474231E-02 + 0.00000000E+00 3.24992731E-02-6.30951619E-17 0.00000000E+00 1.88048132E-08 + 0.00000000E+00-9.76458784E-11-5.93483151E-03 1.63218133E-08 3.08048860E-05 +-8.47319133E-11 2.78319708E-02 0.00000000E+00 3.53626111E-03 0.00000000E+00 + 2.02477481E-02-2.40474954E-17 2.59948652E-03-2.90270919E-18 4.99517269E-01 + 0.00000000E+00 6.16388531E-02 0.00000000E+00 2.60435396E-01-5.40907831E-16 + 3.26097671E-02-6.66000030E-17 5.84801230E-03 1.59314416E-08 3.03950530E-05 + 8.28448836E-11 0.00000000E+00 1.84360994E-08 0.00000000E+00 9.58488182E-11 + 2.32911557E-03 6.23195571E-18 3.30884414E-03 0.00000000E+00 3.23911639E-02 + 8.02921054E-17 6.49565437E-02 0.00000000E+00 5.86690756E-03 1.60210629E-08 +-3.04495740E-05-8.31030585E-11 0.00000000E+00 1.85225266E-08 0.00000000E+00 +-9.60975538E-11 1.91662945E-02 4.71516685E-17 2.46268942E-03 5.12139935E-18 + 2.69224054E-02 0.00000000E+00 3.42185444E-03 0.00000000E+00 2.59561744E-01 + 5.19470162E-16 3.24994141E-02 5.39449728E-17 5.12785565E-01 0.00000000E+00 + 6.32473035E-02 0.00000000E+00 9.15636419E-03 0.00000000E+00 5.72036162E-05 + 0.00000000E+00 1.32891196E-03-4.56733656E-18 8.33374908E-06-2.90041387E-20 + 0.00000000E+00 9.37284300E-10-2.95747259E-04 8.12583895E-10 0.00000000E+00 + 9.37284300E-10-2.95747259E-04 8.12583895E-10 5.24438997E-02 0.00000000E+00 +-1.05413637E-06 0.00000000E+00 7.99125440E-03-2.63294231E-17 7.34503644E-07 + 7.37838736E-21 0.00000000E+00-1.85225266E-08 0.00000000E+00-2.05215764E-08 + 5.86690756E-03-1.60210629E-08 6.48258185E-03-1.77717936E-08 0.00000000E+00 +-1.85225266E-08 0.00000000E+00-2.05215764E-08 5.86690756E-03-1.60210629E-08 + 6.48258185E-03-1.77717936E-08 8.99981963E-03 0.00000000E+00-5.63000931E-05 + 0.00000000E+00 1.43802116E-03-3.83849292E-18-8.96336248E-06 2.42966068E-20 + 0.00000000E+00-1.87652591E-08 0.00000000E+00 9.32280177E-10 5.91820629E-03 +-1.62710031E-08-2.93773253E-04 8.06316730E-10 0.00000000E+00-1.87652591E-08 + 0.00000000E+00 9.32280177E-10 5.91820629E-03-1.62710031E-08-2.93773253E-04 + 8.06316730E-10-2.89973692E-04-7.85207648E-10 1.36302589E-08 6.45437313E-14 + 0.00000000E+00-9.10888339E-10 0.00000000E+00 6.21839221E-14-1.19795125E-03 +-2.83833877E-18-1.68267465E-03 0.00000000E+00-1.62226445E-02-3.35592696E-17 +-3.20509618E-02 0.00000000E+00 6.48258185E-03 1.77717936E-08 2.55845816E-08 + 1.42836868E-13 0.00000000E+00 2.05215764E-08 0.00000000E+00 1.44611847E-13 + 2.46268942E-03 5.12139935E-18 9.85189640E-03 1.82648175E-17 3.42185444E-03 + 0.00000000E+00 1.36878889E-02 0.00000000E+00 3.24994141E-02 5.39449728E-17 + 1.29998177E-01 2.44616867E-16 6.32473035E-02 0.00000000E+00 2.53025409E-01 + 0.00000000E+00-2.98853203E-04-8.21894993E-10 1.19928340E-08 3.73389913E-14 + 0.00000000E+00-9.44429965E-10 0.00000000E+00 2.93605608E-14 2.46268171E-03 + 4.00014899E-18-1.26554206E-03-1.72571455E-18 3.42183754E-03 0.00000000E+00 +-1.73952466E-03 0.00000000E+00 3.24992731E-02 6.30951619E-17-1.62772601E-02 +-3.24237912E-17 6.32474231E-02 0.00000000E+00-3.12215690E-02 0.00000000E+00 + 0.00000000E+00-9.10888339E-10 0.00000000E+00 6.21839221E-14 2.89973692E-04 +-7.85207648E-10-1.36302589E-08 6.45437313E-14-1.68267465E-03 0.00000000E+00 +-1.19795125E-03 2.83833877E-18-3.20509618E-02 0.00000000E+00-1.62226445E-02 + 3.35592696E-17 0.00000000E+00 2.05215764E-08 0.00000000E+00 1.44611847E-13 +-6.48258185E-03 1.77717936E-08-2.55845816E-08 1.42836868E-13 3.42185444E-03 + 0.00000000E+00 1.36878889E-02 0.00000000E+00 2.46268942E-03-5.12139935E-18 + 9.85189640E-03-1.82648175E-17 6.32473035E-02 0.00000000E+00 2.53025409E-01 + 0.00000000E+00 3.24994141E-02-5.39449728E-17 1.29998177E-01-2.44616867E-16 + 0.00000000E+00-9.44429965E-10 0.00000000E+00 2.93605608E-14 2.98853203E-04 +-8.21894993E-10-1.19928340E-08 3.73389913E-14 3.42183754E-03 0.00000000E+00 +-1.73952466E-03 0.00000000E+00 2.46268171E-03-4.00014899E-18-1.26554206E-03 + 1.72571455E-18 6.32474231E-02 0.00000000E+00-3.12215690E-02 0.00000000E+00 + 3.24992731E-02-6.30951619E-17-1.62772601E-02 3.24237912E-17-2.89973692E-04 +-7.85207648E-10 1.36302589E-08 6.45437313E-14 0.00000000E+00-9.10888339E-10 + 0.00000000E+00 6.21839221E-14-1.19795125E-03-2.83833877E-18-1.68267465E-03 + 0.00000000E+00-1.19795125E-03-2.83833877E-18-1.68267465E-03 0.00000000E+00 + 6.48258185E-03 1.77717936E-08 2.55845816E-08 1.42836868E-13 0.00000000E+00 + 2.05215764E-08 0.00000000E+00 1.44611847E-13 2.46268942E-03 5.12139935E-18 + 9.85189640E-03 1.82648175E-17 3.42185444E-03 0.00000000E+00 1.36878889E-02 + 0.00000000E+00 2.46268942E-03 5.12139935E-18 9.85189640E-03 1.82648175E-17 + 3.42185444E-03 0.00000000E+00 1.36878889E-02 0.00000000E+00-2.98853203E-04 +-8.21894993E-10 1.19928340E-08 3.73389913E-14 0.00000000E+00-9.44429965E-10 + 0.00000000E+00 2.93605608E-14 2.46268171E-03 4.00014899E-18-1.26554206E-03 +-1.72571455E-18 3.42183754E-03 0.00000000E+00-1.73952466E-03 0.00000000E+00 + 2.46268171E-03 4.00014899E-18-1.26554206E-03-1.72571455E-18 3.42183754E-03 + 0.00000000E+00-1.73952466E-03 0.00000000E+00 0.00000000E+00-9.10888339E-10 + 0.00000000E+00 6.21839221E-14 2.89973692E-04-7.85207648E-10-1.36302589E-08 + 6.45437313E-14-1.68267465E-03 0.00000000E+00-1.19795125E-03 2.83833877E-18 +-1.68267465E-03 0.00000000E+00-1.19795125E-03 2.83833877E-18 0.00000000E+00 + 2.05215764E-08 0.00000000E+00 1.44611847E-13-6.48258185E-03 1.77717936E-08 +-2.55845816E-08 1.42836868E-13 3.42185444E-03 0.00000000E+00 1.36878889E-02 + 0.00000000E+00 2.46268942E-03-5.12139935E-18 9.85189640E-03-1.82648175E-17 + 3.42185444E-03 0.00000000E+00 1.36878889E-02 0.00000000E+00 2.46268942E-03 +-5.12139935E-18 9.85189640E-03-1.82648175E-17 0.00000000E+00-9.44429965E-10 + 0.00000000E+00 2.93605608E-14 2.98853203E-04-8.21894993E-10-1.19928340E-08 + 3.73389913E-14 3.42183754E-03 0.00000000E+00-1.73952466E-03 0.00000000E+00 + 2.46268171E-03-4.00014899E-18-1.26554206E-03 1.72571455E-18 3.42183754E-03 + 0.00000000E+00-1.73952466E-03 0.00000000E+00 2.46268171E-03-4.00014899E-18 +-1.26554206E-03 1.72571455E-18-8.28213344E-06-2.81402042E-20-4.97872470E-08 +-1.71476289E-22-5.72819065E-05 0.00000000E+00-3.43040951E-07 0.00000000E+00 +-1.36302589E-08-6.45437313E-14 0.00000000E+00-6.21839221E-14-1.36302589E-08 +-6.45437313E-14 0.00000000E+00-6.21839221E-14 7.34503644E-07-7.37838736E-21 + 1.38195027E-07 4.39216204E-22-1.05413637E-06 0.00000000E+00 9.06881138E-07 + 0.00000000E+00 3.04495740E-05 8.31030585E-11-2.55845816E-08-1.42836868E-13 + 0.00000000E+00 9.60975538E-11 0.00000000E+00-1.44611847E-13 3.04495740E-05 + 8.31030585E-11-2.55845816E-08-1.42836868E-13 0.00000000E+00 9.60975538E-11 + 0.00000000E+00-1.44611847E-13 9.01670128E-06 2.36657650E-20-5.38746809E-08 +-1.43499321E-22 5.62277661E-05 0.00000000E+00-3.37174109E-07 0.00000000E+00 +-3.07569146E-05-8.45825574E-11-1.19928340E-08-3.73389913E-14 0.00000000E+00 +-9.75284361E-11 0.00000000E+00-2.93605608E-14-3.07569146E-05-8.45825574E-11 +-1.19928340E-08-3.73389913E-14 0.00000000E+00-9.75284361E-11 0.00000000E+00 +-2.93605608E-14 1.32891196E-03 4.56733656E-18 8.33374908E-06 2.90041387E-20 + 9.15636419E-03 0.00000000E+00 5.72036162E-05 0.00000000E+00 2.95747259E-04 + 8.12583895E-10 0.00000000E+00 9.37284300E-10 2.95747259E-04 8.12583895E-10 + 0.00000000E+00 9.37284300E-10 7.99125440E-03 2.63294231E-17 7.34503644E-07 +-7.37838736E-21 5.24438997E-02 0.00000000E+00-1.05413637E-06 0.00000000E+00 +-5.86690756E-03-1.60210629E-08-6.48258185E-03-1.77717936E-08 0.00000000E+00 +-1.85225266E-08 0.00000000E+00-2.05215764E-08-5.86690756E-03-1.60210629E-08 +-6.48258185E-03-1.77717936E-08 0.00000000E+00-1.85225266E-08 0.00000000E+00 +-2.05215764E-08 1.43802116E-03 3.83849292E-18-8.96336248E-06-2.42966068E-20 + 8.99981963E-03 0.00000000E+00-5.63000931E-05 0.00000000E+00-5.91820629E-03 +-1.62710031E-08 2.93773253E-04 8.06316730E-10 0.00000000E+00-1.87652591E-08 + 0.00000000E+00 9.32280177E-10-5.91820629E-03-1.62710031E-08 2.93773253E-04 + 8.06316730E-10 0.00000000E+00-1.87652591E-08 0.00000000E+00 9.32280177E-10 +-5.72819065E-05 0.00000000E+00-3.43040951E-07 0.00000000E+00-8.28213344E-06 + 2.81402042E-20-4.97872470E-08 1.71476289E-22 0.00000000E+00-6.21839221E-14 + 1.36302589E-08-6.45437313E-14 0.00000000E+00-6.21839221E-14 1.36302589E-08 +-6.45437313E-14-1.05413637E-06 0.00000000E+00 9.06881138E-07 0.00000000E+00 + 7.34503644E-07 7.37838736E-21 1.38195027E-07-4.39216204E-22 0.00000000E+00 + 9.60975538E-11 0.00000000E+00-1.44611847E-13-3.04495740E-05 8.31030585E-11 + 2.55845816E-08-1.42836868E-13 0.00000000E+00 9.60975538E-11 0.00000000E+00 +-1.44611847E-13-3.04495740E-05 8.31030585E-11 2.55845816E-08-1.42836868E-13 + 5.62277661E-05 0.00000000E+00-3.37174109E-07 0.00000000E+00 9.01670128E-06 +-2.36657650E-20-5.38746809E-08 1.43499321E-22 0.00000000E+00-9.75284361E-11 + 0.00000000E+00-2.93605608E-14 3.07569146E-05-8.45825574E-11 1.19928340E-08 +-3.73389913E-14 0.00000000E+00-9.75284361E-11 0.00000000E+00-2.93605608E-14 + 3.07569146E-05-8.45825574E-11 1.19928340E-08-3.73389913E-14 0.00000000E+00 + 1.84360994E-08 0.00000000E+00 9.58488182E-11-5.84801230E-03 1.59314416E-08 +-3.03950530E-05 8.28448836E-11 3.30884414E-03 0.00000000E+00 2.32911557E-03 +-6.23195571E-18 3.30884414E-03 0.00000000E+00 2.32911557E-03-6.23195571E-18 + 0.00000000E+00 1.85225266E-08 0.00000000E+00-9.60975538E-11-5.86690756E-03 + 1.60210629E-08 3.04495740E-05-8.31030585E-11 2.69224054E-02 0.00000000E+00 + 3.42185444E-03 0.00000000E+00 1.91662945E-02-4.71516685E-17 2.46268942E-03 +-5.12139935E-18 2.69224054E-02 0.00000000E+00 3.42185444E-03 0.00000000E+00 + 1.91662945E-02-4.71516685E-17 2.46268942E-03-5.12139935E-18 5.84801230E-03 + 1.59314416E-08 3.03950530E-05 8.28448836E-11 0.00000000E+00 1.84360994E-08 + 0.00000000E+00 9.58488182E-11 2.32911557E-03 6.23195571E-18 3.30884414E-03 + 0.00000000E+00 2.32911557E-03 6.23195571E-18 3.30884414E-03 0.00000000E+00 + 5.86690756E-03 1.60210629E-08-3.04495740E-05-8.31030585E-11 0.00000000E+00 + 1.85225266E-08 0.00000000E+00-9.60975538E-11 1.91662945E-02 4.71516685E-17 + 2.46268942E-03 5.12139935E-18 2.69224054E-02 0.00000000E+00 3.42185444E-03 + 0.00000000E+00 1.91662945E-02 4.71516685E-17 2.46268942E-03 5.12139935E-18 + 2.69224054E-02 0.00000000E+00 3.42185444E-03 0.00000000E+00 0.00000000E+00 + 1.84360994E-08 0.00000000E+00 9.58488182E-11-5.84801230E-03 1.59314416E-08 +-3.03950530E-05 8.28448836E-11 3.30884414E-03 0.00000000E+00 2.32911557E-03 +-6.23195571E-18 6.49565437E-02 0.00000000E+00 3.23911639E-02-8.02921054E-17 + 0.00000000E+00 1.85225266E-08 0.00000000E+00-9.60975538E-11-5.86690756E-03 + 1.60210629E-08 3.04495740E-05-8.31030585E-11 2.69224054E-02 0.00000000E+00 + 3.42185444E-03 0.00000000E+00 1.91662945E-02-4.71516685E-17 2.46268942E-03 +-5.12139935E-18 5.12785565E-01 0.00000000E+00 6.32473035E-02 0.00000000E+00 + 2.59561744E-01-5.19470162E-16 3.24994141E-02-5.39449728E-17 5.76908586E-03 + 1.55929159E-08 2.99877757E-05 8.10878574E-11 0.00000000E+00 1.81133405E-08 + 0.00000000E+00 9.41749501E-11 2.19881840E-03 6.78436473E-18 3.19719271E-03 + 0.00000000E+00 3.22851641E-02 8.26035667E-17 6.67748425E-02 0.00000000E+00 + 5.79020672E-03 1.56811786E-08-3.00487209E-05-8.13427179E-11 0.00000000E+00 + 1.81983748E-08 0.00000000E+00-9.44205640E-11 1.81108061E-02 4.89852724E-17 + 2.32911916E-03 5.70728089E-18 2.60238112E-02 0.00000000E+00 3.30885522E-03 + 0.00000000E+00 2.58704982E-01 6.93850403E-16 3.23912444E-02 8.72980460E-17 + 5.26891740E-01 0.00000000E+00 6.49562595E-02 0.00000000E+00 9.32580950E-03 + 0.00000000E+00 5.82598827E-05 0.00000000E+00 1.22334642E-03-2.56110250E-18 + 7.67296125E-06-1.61425573E-20 0.00000000E+00 9.20744546E-10-2.92197082E-04 + 7.95313638E-10 0.00000000E+00 9.20744546E-10-2.92197082E-04 7.95313638E-10 + 5.33850645E-02 0.00000000E+00-1.14100310E-06 0.00000000E+00 7.37111879E-03 +-1.97188932E-17 7.10674077E-07-1.55315058E-20 0.00000000E+00-1.81983748E-08 + 0.00000000E+00-2.01491718E-08 5.79020672E-03-1.56811786E-08 6.40177624E-03 +-1.73869493E-08 0.00000000E+00-1.81983748E-08 0.00000000E+00-2.01491718E-08 + 5.79020672E-03-1.56811786E-08 6.40177624E-03-1.73869493E-08 9.15636419E-03 + 0.00000000E+00-5.72819065E-05 0.00000000E+00 1.32891196E-03-4.56733656E-18 +-8.28213344E-06 2.81402042E-20 0.00000000E+00-1.84360994E-08 0.00000000E+00 + 9.10888339E-10 5.84801230E-03-1.59314416E-08-2.89973692E-04 7.85207648E-10 + 0.00000000E+00-1.84360994E-08 0.00000000E+00 9.10888339E-10 5.84801230E-03 +-1.59314416E-08-2.89973692E-04 7.85207648E-10-2.85743431E-04-7.68340888E-10 + 1.52363001E-08 6.37151206E-14 0.00000000E+00-8.94756941E-10 0.00000000E+00 + 6.14034667E-14-1.13198439E-03-3.12291141E-18-1.62651198E-03 0.00000000E+00 +-1.61691021E-02-4.24754032E-17-3.29327755E-02 0.00000000E+00 6.40177624E-03 + 1.73869493E-08 2.88389379E-08 1.22277221E-13 0.00000000E+00 2.01491718E-08 + 0.00000000E+00 1.14739700E-13 2.32911916E-03 5.70728089E-18 9.31763845E-03 + 2.38477269E-17 3.30885522E-03 0.00000000E+00 1.32358801E-02 0.00000000E+00 + 3.23912444E-02 8.72980460E-17 1.29565591E-01 3.24511850E-16 6.49562595E-02 + 0.00000000E+00 2.59864655E-01 0.00000000E+00-2.95747259E-04-8.12583895E-10 + 1.36302589E-08 6.45437313E-14 0.00000000E+00-9.37284300E-10 0.00000000E+00 + 6.21839221E-14 2.32911557E-03 6.23195571E-18-1.19795125E-03-2.83833877E-18 + 3.30884414E-03 0.00000000E+00-1.68267465E-03 0.00000000E+00 3.23911639E-02 + 8.02921054E-17-1.62226445E-02-3.35592696E-17 6.49565437E-02 0.00000000E+00 +-3.20509618E-02 0.00000000E+00 0.00000000E+00-8.94756941E-10 0.00000000E+00 + 6.14034667E-14 2.85743431E-04-7.68340888E-10-1.52363001E-08 6.37151206E-14 +-1.62651198E-03 0.00000000E+00-1.13198439E-03 3.12291141E-18-3.29327755E-02 + 0.00000000E+00-1.61691021E-02 4.24754032E-17 0.00000000E+00 2.01491718E-08 + 0.00000000E+00 1.14739700E-13-6.40177624E-03 1.73869493E-08-2.88389379E-08 + 1.22277221E-13 3.30885522E-03 0.00000000E+00 1.32358801E-02 0.00000000E+00 + 2.32911916E-03-5.70728089E-18 9.31763845E-03-2.38477269E-17 6.49562595E-02 + 0.00000000E+00 2.59864655E-01 0.00000000E+00 3.23912444E-02-8.72980460E-17 + 1.29565591E-01-3.24511850E-16 0.00000000E+00-9.37284300E-10 0.00000000E+00 + 6.21839221E-14 2.95747259E-04-8.12583895E-10-1.36302589E-08 6.45437313E-14 + 3.30884414E-03 0.00000000E+00-1.68267465E-03 0.00000000E+00 2.32911557E-03 +-6.23195571E-18-1.19795125E-03 2.83833877E-18 6.49565437E-02 0.00000000E+00 +-3.20509618E-02 0.00000000E+00 3.23911639E-02-8.02921054E-17-1.62226445E-02 + 3.35592696E-17-2.85743431E-04-7.68340888E-10 1.52363001E-08 6.37151206E-14 + 0.00000000E+00-8.94756941E-10 0.00000000E+00 6.14034667E-14-1.13198439E-03 +-3.12291141E-18-1.62651198E-03 0.00000000E+00-1.13198439E-03-3.12291141E-18 +-1.62651198E-03 0.00000000E+00 6.40177624E-03 1.73869493E-08 2.88389379E-08 + 1.22277221E-13 0.00000000E+00 2.01491718E-08 0.00000000E+00 1.14739700E-13 + 2.32911916E-03 5.70728089E-18 9.31763845E-03 2.38477269E-17 3.30885522E-03 + 0.00000000E+00 1.32358801E-02 0.00000000E+00 2.32911916E-03 5.70728089E-18 + 9.31763845E-03 2.38477269E-17 3.30885522E-03 0.00000000E+00 1.32358801E-02 + 0.00000000E+00-2.95747259E-04-8.12583895E-10 1.36302589E-08 6.45437313E-14 + 0.00000000E+00-9.37284300E-10 0.00000000E+00 6.21839221E-14 2.32911557E-03 + 6.23195571E-18-1.19795125E-03-2.83833877E-18 3.30884414E-03 0.00000000E+00 +-1.68267465E-03 0.00000000E+00 2.32911557E-03 6.23195571E-18-1.19795125E-03 +-2.83833877E-18 3.30884414E-03 0.00000000E+00-1.68267465E-03 0.00000000E+00 + 0.00000000E+00-8.94756941E-10 0.00000000E+00 6.14034667E-14 2.85743431E-04 +-7.68340888E-10-1.52363001E-08 6.37151206E-14-1.62651198E-03 0.00000000E+00 +-1.13198439E-03 3.12291141E-18-1.62651198E-03 0.00000000E+00-1.13198439E-03 + 3.12291141E-18 0.00000000E+00 2.01491718E-08 0.00000000E+00 1.14739700E-13 +-6.40177624E-03 1.73869493E-08-2.88389379E-08 1.22277221E-13 3.30885522E-03 + 0.00000000E+00 1.32358801E-02 0.00000000E+00 2.32911916E-03-5.70728089E-18 + 9.31763845E-03-2.38477269E-17 3.30885522E-03 0.00000000E+00 1.32358801E-02 + 0.00000000E+00 2.32911916E-03-5.70728089E-18 9.31763845E-03-2.38477269E-17 + 0.00000000E+00-9.37284300E-10 0.00000000E+00 6.21839221E-14 2.95747259E-04 +-8.12583895E-10-1.36302589E-08 6.45437313E-14 3.30884414E-03 0.00000000E+00 +-1.68267465E-03 0.00000000E+00 2.32911557E-03-6.23195571E-18-1.19795125E-03 + 2.83833877E-18 3.30884414E-03 0.00000000E+00-1.68267465E-03 0.00000000E+00 + 2.32911557E-03-6.23195571E-18-1.19795125E-03 2.83833877E-18-7.62303922E-06 +-1.58533488E-20-4.58325214E-08-9.56922938E-23-5.83446183E-05 0.00000000E+00 +-3.49391184E-07 0.00000000E+00-1.52363001E-08-6.37151206E-14 0.00000000E+00 +-6.14034667E-14-1.52363001E-08-6.37151206E-14 0.00000000E+00-6.14034667E-14 + 7.10674077E-07 1.55315058E-20 1.27472505E-07 3.48456114E-22-1.14100310E-06 + 0.00000000E+00 9.23164760E-07 0.00000000E+00 3.00487209E-05 8.13427179E-11 +-2.88389379E-08-1.22277221E-13 0.00000000E+00 9.44205640E-11 0.00000000E+00 +-1.14739700E-13 3.00487209E-05 8.13427179E-11-2.88389379E-08-1.22277221E-13 + 0.00000000E+00 9.44205640E-11 0.00000000E+00-1.14739700E-13 8.33374908E-06 + 2.90041387E-20-4.97872470E-08-1.71476289E-22 5.72036162E-05 0.00000000E+00 +-3.43040951E-07 0.00000000E+00-3.03950530E-05-8.28448836E-11-1.36302589E-08 +-6.45437313E-14 0.00000000E+00-9.58488182E-11 0.00000000E+00-6.21839221E-14 +-3.03950530E-05-8.28448836E-11-1.36302589E-08-6.45437313E-14 0.00000000E+00 +-9.58488182E-11 0.00000000E+00-6.21839221E-14 1.22334642E-03 2.56110250E-18 + 7.67296125E-06 1.61425573E-20 9.32580950E-03 0.00000000E+00 5.82598827E-05 + 0.00000000E+00 2.92197082E-04 7.95313638E-10 0.00000000E+00 9.20744546E-10 + 2.92197082E-04 7.95313638E-10 0.00000000E+00 9.20744546E-10 7.37111879E-03 + 1.97188932E-17 7.10674077E-07 1.55315058E-20 5.33850645E-02 0.00000000E+00 +-1.14100310E-06 0.00000000E+00-5.79020672E-03-1.56811786E-08-6.40177624E-03 +-1.73869493E-08 0.00000000E+00-1.81983748E-08 0.00000000E+00-2.01491718E-08 +-5.79020672E-03-1.56811786E-08-6.40177624E-03-1.73869493E-08 0.00000000E+00 +-1.81983748E-08 0.00000000E+00-2.01491718E-08 1.32891196E-03 4.56733656E-18 +-8.28213344E-06-2.81402042E-20 9.15636419E-03 0.00000000E+00-5.72819065E-05 + 0.00000000E+00-5.84801230E-03-1.59314416E-08 2.89973692E-04 7.85207648E-10 + 0.00000000E+00-1.84360994E-08 0.00000000E+00 9.10888339E-10-5.84801230E-03 +-1.59314416E-08 2.89973692E-04 7.85207648E-10 0.00000000E+00-1.84360994E-08 + 0.00000000E+00 9.10888339E-10-5.83446183E-05 0.00000000E+00-3.49391184E-07 + 0.00000000E+00-7.62303922E-06 1.58533488E-20-4.58325214E-08 9.56922938E-23 + 0.00000000E+00-6.14034667E-14 1.52363001E-08-6.37151206E-14 0.00000000E+00 +-6.14034667E-14 1.52363001E-08-6.37151206E-14-1.14100310E-06 0.00000000E+00 + 9.23164760E-07 0.00000000E+00 7.10674077E-07-1.55315058E-20 1.27472505E-07 +-3.48456114E-22 0.00000000E+00 9.44205640E-11 0.00000000E+00-1.14739700E-13 +-3.00487209E-05 8.13427179E-11 2.88389379E-08-1.22277221E-13 0.00000000E+00 + 9.44205640E-11 0.00000000E+00-1.14739700E-13-3.00487209E-05 8.13427179E-11 + 2.88389379E-08-1.22277221E-13 5.72036162E-05 0.00000000E+00-3.43040951E-07 + 0.00000000E+00 8.33374908E-06-2.90041387E-20-4.97872470E-08 1.71476289E-22 + 0.00000000E+00-9.58488182E-11 0.00000000E+00-6.21839221E-14 3.03950530E-05 +-8.28448836E-11 1.36302589E-08-6.45437313E-14 0.00000000E+00-9.58488182E-11 + 0.00000000E+00-6.21839221E-14 3.03950530E-05-8.28448836E-11 1.36302589E-08 +-6.45437313E-14 0.00000000E+00 1.81133405E-08 0.00000000E+00 9.41749501E-11 +-5.76908586E-03 1.55929159E-08-2.99877757E-05 8.10878574E-11 3.19719271E-03 + 0.00000000E+00 2.19881840E-03-6.78436473E-18 3.19719271E-03 0.00000000E+00 + 2.19881840E-03-6.78436473E-18 0.00000000E+00 1.81983748E-08 0.00000000E+00 +-9.44205640E-11-5.79020672E-03 1.56811786E-08 3.00487209E-05-8.13427179E-11 + 2.60238112E-02 0.00000000E+00 3.30885522E-03 0.00000000E+00 1.81108061E-02 +-4.89852724E-17 2.32911916E-03-5.70728089E-18 2.60238112E-02 0.00000000E+00 + 3.30885522E-03 0.00000000E+00 1.81108061E-02-4.89852724E-17 2.32911916E-03 +-5.70728089E-18 5.76908586E-03 1.55929159E-08 2.99877757E-05 8.10878574E-11 + 0.00000000E+00 1.81133405E-08 0.00000000E+00 9.41749501E-11 2.19881840E-03 + 6.78436473E-18 3.19719271E-03 0.00000000E+00 2.19881840E-03 6.78436473E-18 + 3.19719271E-03 0.00000000E+00 5.79020672E-03 1.56811786E-08-3.00487209E-05 +-8.13427179E-11 0.00000000E+00 1.81983748E-08 0.00000000E+00-9.44205640E-11 + 1.81108061E-02 4.89852724E-17 2.32911916E-03 5.70728089E-18 2.60238112E-02 + 0.00000000E+00 3.30885522E-03 0.00000000E+00 1.81108061E-02 4.89852724E-17 + 2.32911916E-03 5.70728089E-18 2.60238112E-02 0.00000000E+00 3.30885522E-03 + 0.00000000E+00 0.00000000E+00 1.81133405E-08 0.00000000E+00 9.41749501E-11 +-5.76908586E-03 1.55929159E-08-2.99877757E-05 8.10878574E-11 3.19719271E-03 + 0.00000000E+00 2.19881840E-03-6.78436473E-18 6.67748425E-02 0.00000000E+00 + 3.22851641E-02-8.26035667E-17 0.00000000E+00 1.81983748E-08 0.00000000E+00 +-9.44205640E-11-5.79020672E-03 1.56811786E-08 3.00487209E-05-8.13427179E-11 + 2.60238112E-02 0.00000000E+00 3.30885522E-03 0.00000000E+00 1.81108061E-02 +-4.89852724E-17 2.32911916E-03-5.70728089E-18 5.26891740E-01 0.00000000E+00 + 6.49562595E-02 0.00000000E+00 2.58704982E-01-6.93850403E-16 3.23912444E-02 +-8.72980460E-17 5.68180576E-03 1.52482245E-08 2.95369603E-05 7.92966569E-11 + 0.00000000E+00 1.77771835E-08 0.00000000E+00 9.24293752E-11 2.07185090E-03 + 9.58677228E-18 3.08685020E-03 0.00000000E+00 3.21814691E-02 8.97802769E-17 + 6.87126594E-02 0.00000000E+00 5.70502407E-03 1.53362154E-08-2.96039546E-05 +-7.95505221E-11 0.00000000E+00 1.78632906E-08 0.00000000E+00-9.26777854E-11 + 1.70817348E-02 6.78900744E-17 2.19882241E-03 7.09452185E-18 2.51358509E-02 + 0.00000000E+00 3.19720434E-03 0.00000000E+00 2.57866246E-01 6.62536703E-16 + 3.22852585E-02 7.79925675E-17 5.41913060E-01 0.00000000E+00 6.67745347E-02 + 0.00000000E+00 9.50931653E-03 0.00000000E+00 5.94037342E-05 0.00000000E+00 + 1.12130522E-03-2.94524948E-18 7.03420116E-06-1.82585187E-20 0.00000000E+00 + 9.04175640E-10-2.88206530E-04 7.78066934E-10 0.00000000E+00 9.04175640E-10 +-2.88206530E-04 7.78066934E-10 5.44038861E-02 0.00000000E+00-1.23561660E-06 + 0.00000000E+00 6.77136049E-03-1.51915483E-17 6.86954619E-07 3.46300968E-21 + 0.00000000E+00-1.78632906E-08 0.00000000E+00-1.97872792E-08 5.70502407E-03 +-1.53362154E-08 6.31146905E-03-1.70107669E-08 0.00000000E+00-1.78632906E-08 + 0.00000000E+00-1.97872792E-08 5.70502407E-03-1.53362154E-08 6.31146905E-03 +-1.70107669E-08 9.32580950E-03 0.00000000E+00-5.83446183E-05 0.00000000E+00 + 1.22334642E-03-2.56110250E-18-7.62303922E-06 1.58533488E-20 0.00000000E+00 +-1.81133405E-08 0.00000000E+00 8.94756941E-10 5.76908586E-03-1.55929159E-08 +-2.85743431E-04 7.68340888E-10 0.00000000E+00-1.81133405E-08 0.00000000E+00 + 8.94756941E-10 5.76908586E-03-1.55929159E-08-2.85743431E-04 7.68340888E-10 +-2.81112050E-04-7.51181301E-10 1.67485839E-08 6.34663132E-14 0.00000000E+00 +-8.77865997E-10 0.00000000E+00 6.21025524E-14-1.06766833E-03-4.17032353E-18 +-1.57101364E-03 0.00000000E+00-1.61166819E-02-4.19432111E-17-3.38717985E-02 + 0.00000000E+00 6.31146905E-03 1.70107669E-08 3.19691203E-08 1.28912140E-13 + 0.00000000E+00 1.97872792E-08 0.00000000E+00 1.25857622E-13 2.19882241E-03 + 7.09452185E-18 8.79647065E-03 2.82352026E-17 3.19720434E-03 0.00000000E+00 + 1.27892614E-02 0.00000000E+00 3.22852585E-02 7.79925675E-17 1.29141664E-01 + 3.26605840E-16 6.67745347E-02 0.00000000E+00 2.67141448E-01 0.00000000E+00 +-2.92197082E-04-7.95313638E-10 1.52363001E-08 6.37151206E-14 0.00000000E+00 +-9.20744546E-10 0.00000000E+00 6.14034667E-14 2.19881840E-03 6.78436473E-18 +-1.13198439E-03-3.12291141E-18 3.19719271E-03 0.00000000E+00-1.62651198E-03 + 0.00000000E+00 3.22851641E-02 8.26035667E-17-1.61691021E-02-4.24754032E-17 + 6.67748425E-02 0.00000000E+00-3.29327755E-02 0.00000000E+00 0.00000000E+00 +-8.77865997E-10 0.00000000E+00 6.21025524E-14 2.81112050E-04-7.51181301E-10 +-1.67485839E-08 6.34663132E-14-1.57101364E-03 0.00000000E+00-1.06766833E-03 + 4.17032353E-18-3.38717985E-02 0.00000000E+00-1.61166819E-02 4.19432111E-17 + 0.00000000E+00 1.97872792E-08 0.00000000E+00 1.25857622E-13-6.31146905E-03 + 1.70107669E-08-3.19691203E-08 1.28912140E-13 3.19720434E-03 0.00000000E+00 + 1.27892614E-02 0.00000000E+00 2.19882241E-03-7.09452185E-18 8.79647065E-03 +-2.82352026E-17 6.67745347E-02 0.00000000E+00 2.67141448E-01 0.00000000E+00 + 3.22852585E-02-7.79925675E-17 1.29141664E-01-3.26605840E-16 0.00000000E+00 +-9.20744546E-10 0.00000000E+00 6.14034667E-14 2.92197082E-04-7.95313638E-10 +-1.52363001E-08 6.37151206E-14 3.19719271E-03 0.00000000E+00-1.62651198E-03 + 0.00000000E+00 2.19881840E-03-6.78436473E-18-1.13198439E-03 3.12291141E-18 + 6.67748425E-02 0.00000000E+00-3.29327755E-02 0.00000000E+00 3.22851641E-02 +-8.26035667E-17-1.61691021E-02 4.24754032E-17-2.81112050E-04-7.51181301E-10 + 1.67485839E-08 6.34663132E-14 0.00000000E+00-8.77865997E-10 0.00000000E+00 + 6.21025524E-14-1.06766833E-03-4.17032353E-18-1.57101364E-03 0.00000000E+00 +-1.06766833E-03-4.17032353E-18-1.57101364E-03 0.00000000E+00 6.31146905E-03 + 1.70107669E-08 3.19691203E-08 1.28912140E-13 0.00000000E+00 1.97872792E-08 + 0.00000000E+00 1.25857622E-13 2.19882241E-03 7.09452185E-18 8.79647065E-03 + 2.82352026E-17 3.19720434E-03 0.00000000E+00 1.27892614E-02 0.00000000E+00 + 2.19882241E-03 7.09452185E-18 8.79647065E-03 2.82352026E-17 3.19720434E-03 + 0.00000000E+00 1.27892614E-02 0.00000000E+00-2.92197082E-04-7.95313638E-10 + 1.52363001E-08 6.37151206E-14 0.00000000E+00-9.20744546E-10 0.00000000E+00 + 6.14034667E-14 2.19881840E-03 6.78436473E-18-1.13198439E-03-3.12291141E-18 + 3.19719271E-03 0.00000000E+00-1.62651198E-03 0.00000000E+00 2.19881840E-03 + 6.78436473E-18-1.13198439E-03-3.12291141E-18 3.19719271E-03 0.00000000E+00 +-1.62651198E-03 0.00000000E+00 0.00000000E+00-8.77865997E-10 0.00000000E+00 + 6.21025524E-14 2.81112050E-04-7.51181301E-10-1.67485839E-08 6.34663132E-14 +-1.57101364E-03 0.00000000E+00-1.06766833E-03 4.17032353E-18-1.57101364E-03 + 0.00000000E+00-1.06766833E-03 4.17032353E-18 0.00000000E+00 1.97872792E-08 + 0.00000000E+00 1.25857622E-13-6.31146905E-03 1.70107669E-08-3.19691203E-08 + 1.28912140E-13 3.19720434E-03 0.00000000E+00 1.27892614E-02 0.00000000E+00 + 2.19882241E-03-7.09452185E-18 8.79647065E-03-2.82352026E-17 3.19720434E-03 + 0.00000000E+00 1.27892614E-02 0.00000000E+00 2.19882241E-03-7.09452185E-18 + 8.79647065E-03-2.82352026E-17 0.00000000E+00-9.20744546E-10 0.00000000E+00 + 6.14034667E-14 2.92197082E-04-7.95313638E-10-1.52363001E-08 6.37151206E-14 + 3.19719271E-03 0.00000000E+00-1.62651198E-03 0.00000000E+00 2.19881840E-03 +-6.78436473E-18-1.13198439E-03 3.12291141E-18 3.19719271E-03 0.00000000E+00 +-1.62651198E-03 0.00000000E+00 2.19881840E-03-6.78436473E-18-1.13198439E-03 + 3.12291141E-18-6.98597590E-06-1.85728418E-20-4.20097894E-08-1.10398524E-22 +-5.94955755E-05 0.00000000E+00-3.56268299E-07 0.00000000E+00-1.67485839E-08 +-6.34663132E-14 0.00000000E+00-6.21025524E-14-1.67485839E-08-6.34663132E-14 + 0.00000000E+00-6.21025524E-14 6.86954619E-07-3.46300968E-21 1.17102516E-07 + 2.67568472E-22-1.23561660E-06 0.00000000E+00 9.40793173E-07 0.00000000E+00 + 2.96039546E-05 7.95505221E-11-3.19691203E-08-1.28912140E-13 0.00000000E+00 + 9.26777854E-11 0.00000000E+00-1.25857622E-13 2.96039546E-05 7.95505221E-11 +-3.19691203E-08-1.28912140E-13 0.00000000E+00 9.26777854E-11 0.00000000E+00 +-1.25857622E-13 7.67296125E-06 1.61425573E-20-4.58325214E-08-9.56922938E-23 + 5.82598827E-05 0.00000000E+00-3.49391184E-07 0.00000000E+00-2.99877757E-05 +-8.10878574E-11-1.52363001E-08-6.37151206E-14 0.00000000E+00-9.41749501E-11 + 0.00000000E+00-6.14034667E-14-2.99877757E-05-8.10878574E-11-1.52363001E-08 +-6.37151206E-14 0.00000000E+00-9.41749501E-11 0.00000000E+00-6.14034667E-14 + 1.12130522E-03 2.94524948E-18 7.03420116E-06 1.82585187E-20 9.50931653E-03 + 0.00000000E+00 5.94037342E-05 0.00000000E+00 2.88206530E-04 7.78066934E-10 + 0.00000000E+00 9.04175640E-10 2.88206530E-04 7.78066934E-10 0.00000000E+00 + 9.04175640E-10 6.77136049E-03 1.51915483E-17 6.86954619E-07-3.46300968E-21 + 5.44038861E-02 0.00000000E+00-1.23561660E-06 0.00000000E+00-5.70502407E-03 +-1.53362154E-08-6.31146905E-03-1.70107669E-08 0.00000000E+00-1.78632906E-08 + 0.00000000E+00-1.97872792E-08-5.70502407E-03-1.53362154E-08-6.31146905E-03 +-1.70107669E-08 0.00000000E+00-1.78632906E-08 0.00000000E+00-1.97872792E-08 + 1.22334642E-03 2.56110250E-18-7.62303922E-06-1.58533488E-20 9.32580950E-03 + 0.00000000E+00-5.83446183E-05 0.00000000E+00-5.76908586E-03-1.55929159E-08 + 2.85743431E-04 7.68340888E-10 0.00000000E+00-1.81133405E-08 0.00000000E+00 + 8.94756941E-10-5.76908586E-03-1.55929159E-08 2.85743431E-04 7.68340888E-10 + 0.00000000E+00-1.81133405E-08 0.00000000E+00 8.94756941E-10-5.94955755E-05 + 0.00000000E+00-3.56268299E-07 0.00000000E+00-6.98597590E-06 1.85728418E-20 +-4.20097894E-08 1.10398524E-22 0.00000000E+00-6.21025524E-14 1.67485839E-08 +-6.34663132E-14 0.00000000E+00-6.21025524E-14 1.67485839E-08-6.34663132E-14 +-1.23561660E-06 0.00000000E+00 9.40793173E-07 0.00000000E+00 6.86954619E-07 + 3.46300968E-21 1.17102516E-07-2.67568472E-22 0.00000000E+00 9.26777854E-11 + 0.00000000E+00-1.25857622E-13-2.96039546E-05 7.95505221E-11 3.19691203E-08 +-1.28912140E-13 0.00000000E+00 9.26777854E-11 0.00000000E+00-1.25857622E-13 +-2.96039546E-05 7.95505221E-11 3.19691203E-08-1.28912140E-13 5.82598827E-05 + 0.00000000E+00-3.49391184E-07 0.00000000E+00 7.67296125E-06-1.61425573E-20 +-4.58325214E-08 9.56922938E-23 0.00000000E+00-9.41749501E-11 0.00000000E+00 +-6.14034667E-14 2.99877757E-05-8.10878574E-11 1.52363001E-08-6.37151206E-14 + 0.00000000E+00-9.41749501E-11 0.00000000E+00-6.14034667E-14 2.99877757E-05 +-8.10878574E-11 1.52363001E-08-6.37151206E-14 0.00000000E+00 1.77771835E-08 + 0.00000000E+00 9.24293752E-11-5.68180576E-03 1.52482245E-08-2.95369603E-05 + 7.92966569E-11 3.08685020E-03 0.00000000E+00 2.07185090E-03-9.58677228E-18 + 3.08685020E-03 0.00000000E+00 2.07185090E-03-9.58677228E-18 0.00000000E+00 + 1.78632906E-08 0.00000000E+00-9.26777854E-11-5.70502407E-03 1.53362154E-08 + 2.96039546E-05-7.95505221E-11 2.51358509E-02 0.00000000E+00 3.19720434E-03 + 0.00000000E+00 1.70817348E-02-6.78900744E-17 2.19882241E-03-7.09452185E-18 + 2.51358509E-02 0.00000000E+00 3.19720434E-03 0.00000000E+00 1.70817348E-02 +-6.78900744E-17 2.19882241E-03-7.09452185E-18 5.68180576E-03 1.52482245E-08 + 2.95369603E-05 7.92966569E-11 0.00000000E+00 1.77771835E-08 0.00000000E+00 + 9.24293752E-11 2.07185090E-03 9.58677228E-18 3.08685020E-03 0.00000000E+00 + 2.07185090E-03 9.58677228E-18 3.08685020E-03 0.00000000E+00 5.70502407E-03 + 1.53362154E-08-2.96039546E-05-7.95505221E-11 0.00000000E+00 1.78632906E-08 + 0.00000000E+00-9.26777854E-11 1.70817348E-02 6.78900744E-17 2.19882241E-03 + 7.09452185E-18 2.51358509E-02 0.00000000E+00 3.19720434E-03 0.00000000E+00 + 1.70817348E-02 6.78900744E-17 2.19882241E-03 7.09452185E-18 2.51358509E-02 + 0.00000000E+00 3.19720434E-03 0.00000000E+00 0.00000000E+00 1.77771835E-08 + 0.00000000E+00 9.24293752E-11-5.68180576E-03 1.52482245E-08-2.95369603E-05 + 7.92966569E-11 3.08685020E-03 0.00000000E+00 2.07185090E-03-9.58677228E-18 + 6.87126594E-02 0.00000000E+00 3.21814691E-02-8.97802769E-17 0.00000000E+00 + 1.78632906E-08 0.00000000E+00-9.26777854E-11-5.70502407E-03 1.53362154E-08 + 2.96039546E-05-7.95505221E-11 2.51358509E-02 0.00000000E+00 3.19720434E-03 + 0.00000000E+00 1.70817348E-02-6.78900744E-17 2.19882241E-03-7.09452185E-18 + 5.41913060E-01 0.00000000E+00 6.67745347E-02 0.00000000E+00 2.57866246E-01 +-6.62536703E-16 3.22852585E-02-7.79925675E-17 5.58649320E-03 1.49107484E-08 + 2.90443851E-05 7.75420582E-11 0.00000000E+00 1.74443163E-08 0.00000000E+00 + 9.07001864E-11 1.94826233E-03 3.72250916E-18 2.97776896E-03 0.00000000E+00 + 3.20801480E-02 1.01968760E-16 7.07814028E-02 0.00000000E+00 5.61176812E-03 + 1.49969008E-08-2.91173153E-05-7.77906571E-11 0.00000000E+00 1.75297687E-08 + 0.00000000E+00-9.09467702E-11 1.60794946E-02 5.42054407E-17 2.07185455E-03 + 9.61415372E-18 2.42581671E-02 0.00000000E+00 3.08686146E-03 0.00000000E+00 + 2.57046140E-01 7.76117064E-16 3.21815600E-02 9.16850905E-17 5.57935541E-01 + 0.00000000E+00 6.87122826E-02 0.00000000E+00 9.70823611E-03 0.00000000E+00 + 6.06436474E-05 0.00000000E+00 1.02276816E-03-2.82492979E-18 6.41735957E-06 +-1.78773838E-20 0.00000000E+00 8.87410413E-10-2.83806714E-04 7.60863639E-10 + 0.00000000E+00 8.87410413E-10-2.83806714E-04 7.60863639E-10 5.55079470E-02 + 0.00000000E+00-1.33942420E-06 0.00000000E+00 6.19194947E-03-1.76678758E-17 + 6.63351860E-07-7.99801471E-22 0.00000000E+00-1.75297687E-08 0.00000000E+00 +-1.94186533E-08 5.61176812E-03-1.49969008E-08 6.21216396E-03-1.66342274E-08 + 0.00000000E+00-1.75297687E-08 0.00000000E+00-1.94186533E-08 5.61176812E-03 +-1.49969008E-08 6.21216396E-03-1.66342274E-08 9.50931653E-03 0.00000000E+00 +-5.94955755E-05 0.00000000E+00 1.12130522E-03-2.94524948E-18-6.98597590E-06 + 1.85728418E-20 0.00000000E+00-1.77771835E-08 0.00000000E+00 8.77865997E-10 + 5.68180576E-03-1.52482245E-08-2.81112050E-04 7.51181301E-10 0.00000000E+00 +-1.77771835E-08 0.00000000E+00 8.77865997E-10 5.68180576E-03-1.52482245E-08 +-2.81112050E-04 7.51181301E-10-2.76083797E-04-7.34539045E-10 1.82325560E-08 + 6.21497268E-14 0.00000000E+00-8.61299623E-10 0.00000000E+00 6.16459487E-14 +-1.00502922E-03-3.33416572E-18-1.51615760E-03 0.00000000E+00-1.60654270E-02 +-4.84134625E-17-3.48734214E-02 0.00000000E+00 6.21216396E-03 1.66342274E-08 + 3.49446081E-08 1.25351599E-13 0.00000000E+00 1.94186533E-08 0.00000000E+00 + 1.23320926E-13 2.07185455E-03 9.61415372E-18 8.28861779E-03 3.55134924E-17 + 3.08686146E-03 0.00000000E+00 1.23478740E-02 0.00000000E+00 3.21815600E-02 + 9.16850905E-17 1.28726908E-01 3.62701750E-16 6.87122826E-02 0.00000000E+00 + 2.74896668E-01 0.00000000E+00-2.88206530E-04-7.78066934E-10 1.67485839E-08 + 6.34663132E-14 0.00000000E+00-9.04175640E-10 0.00000000E+00 6.21025524E-14 + 2.07185090E-03 9.58677228E-18-1.06766833E-03-4.17032353E-18 3.08685020E-03 + 0.00000000E+00-1.57101364E-03 0.00000000E+00 3.21814691E-02 8.97802769E-17 +-1.61166819E-02-4.19432111E-17 6.87126594E-02 0.00000000E+00-3.38717985E-02 + 0.00000000E+00 0.00000000E+00-8.61299623E-10 0.00000000E+00 6.16459487E-14 + 2.76083797E-04-7.34539045E-10-1.82325560E-08 6.21497268E-14-1.51615760E-03 + 0.00000000E+00-1.00502922E-03 3.33416572E-18-3.48734214E-02 0.00000000E+00 +-1.60654270E-02 4.84134625E-17 0.00000000E+00 1.94186533E-08 0.00000000E+00 + 1.23320926E-13-6.21216396E-03 1.66342274E-08-3.49446081E-08 1.25351599E-13 + 3.08686146E-03 0.00000000E+00 1.23478740E-02 0.00000000E+00 2.07185455E-03 +-9.61415372E-18 8.28861779E-03-3.55134924E-17 6.87122826E-02 0.00000000E+00 + 2.74896668E-01 0.00000000E+00 3.21815600E-02-9.16850905E-17 1.28726908E-01 +-3.62701750E-16 0.00000000E+00-9.04175640E-10 0.00000000E+00 6.21025524E-14 + 2.88206530E-04-7.78066934E-10-1.67485839E-08 6.34663132E-14 3.08685020E-03 + 0.00000000E+00-1.57101364E-03 0.00000000E+00 2.07185090E-03-9.58677228E-18 +-1.06766833E-03 4.17032353E-18 6.87126594E-02 0.00000000E+00-3.38717985E-02 + 0.00000000E+00 3.21814691E-02-8.97802769E-17-1.61166819E-02 4.19432111E-17 +-2.76083797E-04-7.34539045E-10 1.82325560E-08 6.21497268E-14 0.00000000E+00 +-8.61299623E-10 0.00000000E+00 6.16459487E-14-1.00502922E-03-3.33416572E-18 +-1.51615760E-03 0.00000000E+00-1.00502922E-03-3.33416572E-18-1.51615760E-03 + 0.00000000E+00 6.21216396E-03 1.66342274E-08 3.49446081E-08 1.25351599E-13 + 0.00000000E+00 1.94186533E-08 0.00000000E+00 1.23320926E-13 2.07185455E-03 + 9.61415372E-18 8.28861779E-03 3.55134924E-17 3.08686146E-03 0.00000000E+00 + 1.23478740E-02 0.00000000E+00 2.07185455E-03 9.61415372E-18 8.28861779E-03 + 3.55134924E-17 3.08686146E-03 0.00000000E+00 1.23478740E-02 0.00000000E+00 +-2.88206530E-04-7.78066934E-10 1.67485839E-08 6.34663132E-14 0.00000000E+00 +-9.04175640E-10 0.00000000E+00 6.21025524E-14 2.07185090E-03 9.58677228E-18 +-1.06766833E-03-4.17032353E-18 3.08685020E-03 0.00000000E+00-1.57101364E-03 + 0.00000000E+00 2.07185090E-03 9.58677228E-18-1.06766833E-03-4.17032353E-18 + 3.08685020E-03 0.00000000E+00-1.57101364E-03 0.00000000E+00 0.00000000E+00 +-8.61299623E-10 0.00000000E+00 6.16459487E-14 2.76083797E-04-7.34539045E-10 +-1.82325560E-08 6.21497268E-14-1.51615760E-03 0.00000000E+00-1.00502922E-03 + 3.33416572E-18-1.51615760E-03 0.00000000E+00-1.00502922E-03 3.33416572E-18 + 0.00000000E+00 1.94186533E-08 0.00000000E+00 1.23320926E-13-6.21216396E-03 + 1.66342274E-08-3.49446081E-08 1.25351599E-13 3.08686146E-03 0.00000000E+00 + 1.23478740E-02 0.00000000E+00 2.07185455E-03-9.61415372E-18 8.28861779E-03 +-3.55134924E-17 3.08686146E-03 0.00000000E+00 1.23478740E-02 0.00000000E+00 + 2.07185455E-03-9.61415372E-18 8.28861779E-03-3.55134924E-17 0.00000000E+00 +-9.04175640E-10 0.00000000E+00 6.21025524E-14 2.88206530E-04-7.78066934E-10 +-1.67485839E-08 6.34663132E-14 3.08685020E-03 0.00000000E+00-1.57101364E-03 + 0.00000000E+00 2.07185090E-03-9.58677228E-18-1.06766833E-03 4.17032353E-18 + 3.08685020E-03 0.00000000E+00-1.57101364E-03 0.00000000E+00 2.07185090E-03 +-9.58677228E-18-1.06766833E-03 4.17032353E-18-6.37080126E-06-1.74478440E-20 +-3.83183027E-08-1.05873576E-22-6.07431963E-05 0.00000000E+00-3.63722941E-07 + 0.00000000E+00-1.82325560E-08-6.21497268E-14 0.00000000E+00-6.16459487E-14 +-1.82325560E-08-6.21497268E-14 0.00000000E+00-6.16459487E-14 6.63351860E-07 + 7.99801471E-22 1.07083922E-07 2.97751428E-22-1.33942420E-06 0.00000000E+00 + 9.59894928E-07 0.00000000E+00 2.91173153E-05 7.77906571E-11-3.49446081E-08 +-1.25351599E-13 0.00000000E+00 9.09467702E-11 0.00000000E+00-1.23320926E-13 + 2.91173153E-05 7.77906571E-11-3.49446081E-08-1.25351599E-13 0.00000000E+00 + 9.09467702E-11 0.00000000E+00-1.23320926E-13 7.03420116E-06 1.82585187E-20 +-4.20097894E-08-1.10398524E-22 5.94037342E-05 0.00000000E+00-3.56268299E-07 + 0.00000000E+00-2.95369603E-05-7.92966569E-11-1.67485839E-08-6.34663132E-14 + 0.00000000E+00-9.24293752E-11 0.00000000E+00-6.21025524E-14-2.95369603E-05 +-7.92966569E-11-1.67485839E-08-6.34663132E-14 0.00000000E+00-9.24293752E-11 + 0.00000000E+00-6.21025524E-14 1.02276816E-03 2.82492979E-18 6.41735957E-06 + 1.78773838E-20 9.70823611E-03 0.00000000E+00 6.06436474E-05 0.00000000E+00 + 2.83806714E-04 7.60863639E-10 0.00000000E+00 8.87410413E-10 2.83806714E-04 + 7.60863639E-10 0.00000000E+00 8.87410413E-10 6.19194947E-03 1.76678758E-17 + 6.63351860E-07 7.99801471E-22 5.55079470E-02 0.00000000E+00-1.33942420E-06 + 0.00000000E+00-5.61176812E-03-1.49969008E-08-6.21216396E-03-1.66342274E-08 + 0.00000000E+00-1.75297687E-08 0.00000000E+00-1.94186533E-08-5.61176812E-03 +-1.49969008E-08-6.21216396E-03-1.66342274E-08 0.00000000E+00-1.75297687E-08 + 0.00000000E+00-1.94186533E-08 1.12130522E-03 2.94524948E-18-6.98597590E-06 +-1.85728418E-20 9.50931653E-03 0.00000000E+00-5.94955755E-05 0.00000000E+00 +-5.68180576E-03-1.52482245E-08 2.81112050E-04 7.51181301E-10 0.00000000E+00 +-1.77771835E-08 0.00000000E+00 8.77865997E-10-5.68180576E-03-1.52482245E-08 + 2.81112050E-04 7.51181301E-10 0.00000000E+00-1.77771835E-08 0.00000000E+00 + 8.77865997E-10-6.07431963E-05 0.00000000E+00-3.63722941E-07 0.00000000E+00 +-6.37080126E-06 1.74478440E-20-3.83183027E-08 1.05873576E-22 0.00000000E+00 +-6.16459487E-14 1.82325560E-08-6.21497268E-14 0.00000000E+00-6.16459487E-14 + 1.82325560E-08-6.21497268E-14-1.33942420E-06 0.00000000E+00 9.59894928E-07 + 0.00000000E+00 6.63351860E-07-7.99801471E-22 1.07083922E-07-2.97751428E-22 + 0.00000000E+00 9.09467702E-11 0.00000000E+00-1.23320926E-13-2.91173153E-05 + 7.77906571E-11 3.49446081E-08-1.25351599E-13 0.00000000E+00 9.09467702E-11 + 0.00000000E+00-1.23320926E-13-2.91173153E-05 7.77906571E-11 3.49446081E-08 +-1.25351599E-13 5.94037342E-05 0.00000000E+00-3.56268299E-07 0.00000000E+00 + 7.03420116E-06-1.82585187E-20-4.20097894E-08 1.10398524E-22 0.00000000E+00 +-9.24293752E-11 0.00000000E+00-6.21025524E-14 2.95369603E-05-7.92966569E-11 + 1.67485839E-08-6.34663132E-14 0.00000000E+00-9.24293752E-11 0.00000000E+00 +-6.21025524E-14 2.95369603E-05-7.92966569E-11 1.67485839E-08-6.34663132E-14 + 0.00000000E+00 1.74443163E-08 0.00000000E+00 9.07001864E-11-5.58649320E-03 + 1.49107484E-08-2.90443851E-05 7.75420582E-11 2.97776896E-03 0.00000000E+00 + 1.94826233E-03-3.72250916E-18 2.97776896E-03 0.00000000E+00 1.94826233E-03 +-3.72250916E-18 0.00000000E+00 1.75297687E-08 0.00000000E+00-9.09467702E-11 +-5.61176812E-03 1.49969008E-08 2.91173153E-05-7.77906571E-11 2.42581671E-02 + 0.00000000E+00 3.08686146E-03 0.00000000E+00 1.60794946E-02-5.42054407E-17 + 2.07185455E-03-9.61415372E-18 2.42581671E-02 0.00000000E+00 3.08686146E-03 + 0.00000000E+00 1.60794946E-02-5.42054407E-17 2.07185455E-03-9.61415372E-18 + 5.58649320E-03 1.49107484E-08 2.90443851E-05 7.75420582E-11 0.00000000E+00 + 1.74443163E-08 0.00000000E+00 9.07001864E-11 1.94826233E-03 3.72250916E-18 + 2.97776896E-03 0.00000000E+00 1.94826233E-03 3.72250916E-18 2.97776896E-03 + 0.00000000E+00 5.61176812E-03 1.49969008E-08-2.91173153E-05-7.77906571E-11 + 0.00000000E+00 1.75297687E-08 0.00000000E+00-9.09467702E-11 1.60794946E-02 + 5.42054407E-17 2.07185455E-03 9.61415372E-18 2.42581671E-02 0.00000000E+00 + 3.08686146E-03 0.00000000E+00 1.60794946E-02 5.42054407E-17 2.07185455E-03 + 9.61415372E-18 2.42581671E-02 0.00000000E+00 3.08686146E-03 0.00000000E+00 + 0.00000000E+00 1.74443163E-08 0.00000000E+00 9.07001864E-11-5.58649320E-03 + 1.49107484E-08-2.90443851E-05 7.75420582E-11 2.97776896E-03 0.00000000E+00 + 1.94826233E-03-3.72250916E-18 7.07814028E-02 0.00000000E+00 3.20801480E-02 +-1.01968760E-16 0.00000000E+00 1.75297687E-08 0.00000000E+00-9.09467702E-11 +-5.61176812E-03 1.49969008E-08 2.91173153E-05-7.77906571E-11 2.42581671E-02 + 0.00000000E+00 3.08686146E-03 0.00000000E+00 1.60794946E-02-5.42054407E-17 + 2.07185455E-03-9.61415372E-18 5.57935541E-01 0.00000000E+00 6.87122826E-02 + 0.00000000E+00 2.57046140E-01-7.76117064E-16 3.21815600E-02-9.16850905E-17 + 5.48333417E-03 1.45807591E-08 2.85109682E-05 7.58259426E-11 0.00000000E+00 + 1.71140754E-08 0.00000000E+00 8.89841868E-11 1.82810490E-03 3.30222348E-18 + 2.86990801E-03 0.00000000E+00 3.19812816E-02 1.10710122E-16 7.29940319E-02 + 0.00000000E+00 5.51059712E-03 1.46648231E-08-2.85896349E-05-7.60685020E-11 + 0.00000000E+00 1.71986476E-08 0.00000000E+00-8.92282110E-11 1.51044946E-02 + 2.40504938E-17 1.94826564E-03 3.22506667E-18 2.33904075E-02 0.00000000E+00 + 2.97777966E-03 0.00000000E+00 2.56245368E-01 8.62754447E-16 3.20802392E-02 + 1.02998118E-16 5.75056797E-01 0.00000000E+00 7.07809547E-02 0.00000000E+00 + 9.92391215E-03 0.00000000E+00 6.19879592E-05 0.00000000E+00 9.27649615E-04 +-2.38100162E-18 5.82190668E-06-1.47919452E-20 0.00000000E+00 8.70744152E-10 +-2.79002658E-04 7.43994686E-10 0.00000000E+00 8.70744152E-10-2.79002658E-04 + 7.43994686E-10 5.67047718E-02 0.00000000E+00-1.45217968E-06 0.00000000E+00 + 5.63255309E-03-1.42366960E-17 6.40353002E-07-3.42444934E-21 0.00000000E+00 +-1.71986476E-08 0.00000000E+00-1.90533146E-08 5.51059712E-03-1.46648231E-08 + 6.10407348E-03-1.62658447E-08 0.00000000E+00-1.71986476E-08 0.00000000E+00 +-1.90533146E-08 5.51059712E-03-1.46648231E-08 6.10407348E-03-1.62658447E-08 + 9.70823611E-03 0.00000000E+00-6.07431963E-05 0.00000000E+00 1.02276816E-03 +-2.82492979E-18-6.37080126E-06 1.74478440E-20 0.00000000E+00-1.74443163E-08 + 0.00000000E+00 8.61299623E-10 5.58649320E-03-1.49107484E-08-2.76083797E-04 + 7.34539045E-10 0.00000000E+00-1.74443163E-08 0.00000000E+00 8.61299623E-10 + 5.58649320E-03-1.49107484E-08-2.76083797E-04 7.34539045E-10-2.70672289E-04 +-7.18308503E-10 1.96666770E-08 6.06398415E-14 0.00000000E+00-8.44902705E-10 + 0.00000000E+00 6.10060468E-14-9.44092636E-04-1.63182254E-18-1.46192192E-03 + 0.00000000E+00-1.60153802E-02-5.34270599E-17-3.59437467E-02 0.00000000E+00 + 6.10407348E-03 1.62658447E-08 3.78768869E-08 1.22759750E-13 0.00000000E+00 + 1.90533146E-08 0.00000000E+00 1.22625861E-13 1.94826564E-03 3.22506667E-18 + 7.79428142E-03 1.59335072E-17 2.97777966E-03 0.00000000E+00 1.19115333E-02 + 0.00000000E+00 3.20802392E-02 1.02998118E-16 1.28321652E-01 4.08688011E-16 + 7.07809547E-02 0.00000000E+00 2.83176128E-01 0.00000000E+00-2.83806714E-04 +-7.60863639E-10 1.82325560E-08 6.21497268E-14 0.00000000E+00-8.87410413E-10 + 0.00000000E+00 6.16459487E-14 1.94826233E-03 3.72250916E-18-1.00502922E-03 +-3.33416572E-18 2.97776896E-03 0.00000000E+00-1.51615760E-03 0.00000000E+00 + 3.20801480E-02 1.01968760E-16-1.60654270E-02-4.84134625E-17 7.07814028E-02 + 0.00000000E+00-3.48734214E-02 0.00000000E+00 0.00000000E+00-8.44902705E-10 + 0.00000000E+00 6.10060468E-14 2.70672289E-04-7.18308503E-10-1.96666770E-08 + 6.06398415E-14-1.46192192E-03 0.00000000E+00-9.44092636E-04 1.63182254E-18 +-3.59437467E-02 0.00000000E+00-1.60153802E-02 5.34270599E-17 0.00000000E+00 + 1.90533146E-08 0.00000000E+00 1.22625861E-13-6.10407348E-03 1.62658447E-08 +-3.78768869E-08 1.22759750E-13 2.97777966E-03 0.00000000E+00 1.19115333E-02 + 0.00000000E+00 1.94826564E-03-3.22506667E-18 7.79428142E-03-1.59335072E-17 + 7.07809547E-02 0.00000000E+00 2.83176128E-01 0.00000000E+00 3.20802392E-02 +-1.02998118E-16 1.28321652E-01-4.08688011E-16 0.00000000E+00-8.87410413E-10 + 0.00000000E+00 6.16459487E-14 2.83806714E-04-7.60863639E-10-1.82325560E-08 + 6.21497268E-14 2.97776896E-03 0.00000000E+00-1.51615760E-03 0.00000000E+00 + 1.94826233E-03-3.72250916E-18-1.00502922E-03 3.33416572E-18 7.07814028E-02 + 0.00000000E+00-3.48734214E-02 0.00000000E+00 3.20801480E-02-1.01968760E-16 +-1.60654270E-02 4.84134625E-17-2.70672289E-04-7.18308503E-10 1.96666770E-08 + 6.06398415E-14 0.00000000E+00-8.44902705E-10 0.00000000E+00 6.10060468E-14 +-9.44092636E-04-1.63182254E-18-1.46192192E-03 0.00000000E+00-9.44092636E-04 +-1.63182254E-18-1.46192192E-03 0.00000000E+00 6.10407348E-03 1.62658447E-08 + 3.78768869E-08 1.22759750E-13 0.00000000E+00 1.90533146E-08 0.00000000E+00 + 1.22625861E-13 1.94826564E-03 3.22506667E-18 7.79428142E-03 1.59335072E-17 + 2.97777966E-03 0.00000000E+00 1.19115333E-02 0.00000000E+00 1.94826564E-03 + 3.22506667E-18 7.79428142E-03 1.59335072E-17 2.97777966E-03 0.00000000E+00 + 1.19115333E-02 0.00000000E+00-2.83806714E-04-7.60863639E-10 1.82325560E-08 + 6.21497268E-14 0.00000000E+00-8.87410413E-10 0.00000000E+00 6.16459487E-14 + 1.94826233E-03 3.72250916E-18-1.00502922E-03-3.33416572E-18 2.97776896E-03 + 0.00000000E+00-1.51615760E-03 0.00000000E+00 1.94826233E-03 3.72250916E-18 +-1.00502922E-03-3.33416572E-18 2.97776896E-03 0.00000000E+00-1.51615760E-03 + 0.00000000E+00 0.00000000E+00-8.44902705E-10 0.00000000E+00 6.10060468E-14 + 2.70672289E-04-7.18308503E-10-1.96666770E-08 6.06398415E-14-1.46192192E-03 + 0.00000000E+00-9.44092636E-04 1.63182254E-18-1.46192192E-03 0.00000000E+00 +-9.44092636E-04 1.63182254E-18 0.00000000E+00 1.90533146E-08 0.00000000E+00 + 1.22625861E-13-6.10407348E-03 1.62658447E-08-3.78768869E-08 1.22759750E-13 + 2.97777966E-03 0.00000000E+00 1.19115333E-02 0.00000000E+00 1.94826564E-03 +-3.22506667E-18 7.79428142E-03-1.59335072E-17 2.97777966E-03 0.00000000E+00 + 1.19115333E-02 0.00000000E+00 1.94826564E-03-3.22506667E-18 7.79428142E-03 +-1.59335072E-17 0.00000000E+00-8.87410413E-10 0.00000000E+00 6.16459487E-14 + 2.83806714E-04-7.60863639E-10-1.82325560E-08 6.21497268E-14 2.97776896E-03 + 0.00000000E+00-1.51615760E-03 0.00000000E+00 1.94826233E-03-3.72250916E-18 +-1.00502922E-03 3.33416572E-18 2.97776896E-03 0.00000000E+00-1.51615760E-03 + 0.00000000E+00 1.94826233E-03-3.72250916E-18-1.00502922E-03 3.33416572E-18 +-5.77697364E-06-1.49663496E-20-3.47548451E-08-8.90827496E-23-6.20959458E-05 + 0.00000000E+00-3.71805439E-07 0.00000000E+00-1.96666770E-08-6.06398415E-14 + 0.00000000E+00-6.10060468E-14-1.96666770E-08-6.06398415E-14 0.00000000E+00 +-6.10060468E-14 6.40353002E-07 3.42444934E-21 9.74111769E-08 2.52361273E-22 +-1.45217968E-06 0.00000000E+00 9.80602257E-07 0.00000000E+00 2.85896349E-05 + 7.60685020E-11-3.78768869E-08-1.22759750E-13 0.00000000E+00 8.92282110E-11 + 0.00000000E+00-1.22625861E-13 2.85896349E-05 7.60685020E-11-3.78768869E-08 +-1.22759750E-13 0.00000000E+00 8.92282110E-11 0.00000000E+00-1.22625861E-13 + 6.41735957E-06 1.78773838E-20-3.83183027E-08-1.05873576E-22 6.06436474E-05 + 0.00000000E+00-3.63722941E-07 0.00000000E+00-2.90443851E-05-7.75420582E-11 +-1.82325560E-08-6.21497268E-14 0.00000000E+00-9.07001864E-11 0.00000000E+00 +-6.16459487E-14-2.90443851E-05-7.75420582E-11-1.82325560E-08-6.21497268E-14 + 0.00000000E+00-9.07001864E-11 0.00000000E+00-6.16459487E-14 9.27649615E-04 + 2.38100162E-18 5.82190668E-06 1.47919452E-20 9.92391215E-03 0.00000000E+00 + 6.19879592E-05 0.00000000E+00 2.79002658E-04 7.43994686E-10 0.00000000E+00 + 8.70744152E-10 2.79002658E-04 7.43994686E-10 0.00000000E+00 8.70744152E-10 + 5.63255309E-03 1.42366960E-17 6.40353002E-07 3.42444934E-21 5.67047718E-02 + 0.00000000E+00-1.45217968E-06 0.00000000E+00-5.51059712E-03-1.46648231E-08 +-6.10407348E-03-1.62658447E-08 0.00000000E+00-1.71986476E-08 0.00000000E+00 +-1.90533146E-08-5.51059712E-03-1.46648231E-08-6.10407348E-03-1.62658447E-08 + 0.00000000E+00-1.71986476E-08 0.00000000E+00-1.90533146E-08 1.02276816E-03 + 2.82492979E-18-6.37080126E-06-1.74478440E-20 9.70823611E-03 0.00000000E+00 +-6.07431963E-05 0.00000000E+00-5.58649320E-03-1.49107484E-08 2.76083797E-04 + 7.34539045E-10 0.00000000E+00-1.74443163E-08 0.00000000E+00 8.61299623E-10 +-5.58649320E-03-1.49107484E-08 2.76083797E-04 7.34539045E-10 0.00000000E+00 +-1.74443163E-08 0.00000000E+00 8.61299623E-10-6.20959458E-05 0.00000000E+00 +-3.71805439E-07 0.00000000E+00-5.77697364E-06 1.49663496E-20-3.47548451E-08 + 8.90827496E-23 0.00000000E+00-6.10060468E-14 1.96666770E-08-6.06398415E-14 + 0.00000000E+00-6.10060468E-14 1.96666770E-08-6.06398415E-14-1.45217968E-06 + 0.00000000E+00 9.80602257E-07 0.00000000E+00 6.40353002E-07-3.42444934E-21 + 9.74111769E-08-2.52361273E-22 0.00000000E+00 8.92282110E-11 0.00000000E+00 +-1.22625861E-13-2.85896349E-05 7.60685020E-11 3.78768869E-08-1.22759750E-13 + 0.00000000E+00 8.92282110E-11 0.00000000E+00-1.22625861E-13-2.85896349E-05 + 7.60685020E-11 3.78768869E-08-1.22759750E-13 6.06436474E-05 0.00000000E+00 +-3.63722941E-07 0.00000000E+00 6.41735957E-06-1.78773838E-20-3.83183027E-08 + 1.05873576E-22 0.00000000E+00-9.07001864E-11 0.00000000E+00-6.16459487E-14 + 2.90443851E-05-7.75420582E-11 1.82325560E-08-6.21497268E-14 0.00000000E+00 +-9.07001864E-11 0.00000000E+00-6.16459487E-14 2.90443851E-05-7.75420582E-11 + 1.82325560E-08-6.21497268E-14 0.00000000E+00 1.71140754E-08 0.00000000E+00 + 8.89841868E-11-5.48333417E-03 1.45807591E-08-2.85109682E-05 7.58259426E-11 + 2.86990801E-03 0.00000000E+00 1.82810490E-03-3.30222348E-18 2.86990801E-03 + 0.00000000E+00 1.82810490E-03-3.30222348E-18 0.00000000E+00 1.71986476E-08 + 0.00000000E+00-8.92282110E-11-5.51059712E-03 1.46648231E-08 2.85896349E-05 +-7.60685020E-11 2.33904075E-02 0.00000000E+00 2.97777966E-03 0.00000000E+00 + 1.51044946E-02-2.40504938E-17 1.94826564E-03-3.22506667E-18 2.33904075E-02 + 0.00000000E+00 2.97777966E-03 0.00000000E+00 1.51044946E-02-2.40504938E-17 + 1.94826564E-03-3.22506667E-18 5.48333417E-03 1.45807591E-08 2.85109682E-05 + 7.58259426E-11 0.00000000E+00 1.71140754E-08 0.00000000E+00 8.89841868E-11 + 1.82810490E-03 3.30222348E-18 2.86990801E-03 0.00000000E+00 1.82810490E-03 + 3.30222348E-18 2.86990801E-03 0.00000000E+00 5.51059712E-03 1.46648231E-08 +-2.85896349E-05-7.60685020E-11 0.00000000E+00 1.71986476E-08 0.00000000E+00 +-8.92282110E-11 1.51044946E-02 2.40504938E-17 1.94826564E-03 3.22506667E-18 + 2.33904075E-02 0.00000000E+00 2.97777966E-03 0.00000000E+00 1.51044946E-02 + 2.40504938E-17 1.94826564E-03 3.22506667E-18 2.33904075E-02 0.00000000E+00 + 2.97777966E-03 0.00000000E+00 0.00000000E+00 1.71140754E-08 0.00000000E+00 + 8.89841868E-11-5.48333417E-03 1.45807591E-08-2.85109682E-05 7.58259426E-11 + 2.86990801E-03 0.00000000E+00 1.82810490E-03-3.30222348E-18 7.29940319E-02 + 0.00000000E+00 3.19812816E-02-1.10710122E-16 0.00000000E+00 1.71986476E-08 + 0.00000000E+00-8.92282110E-11-5.51059712E-03 1.46648231E-08 2.85896349E-05 +-7.60685020E-11 2.33904075E-02 0.00000000E+00 2.97777966E-03 0.00000000E+00 + 1.51044946E-02-2.40504938E-17 1.94826564E-03-3.22506667E-18 5.75056797E-01 + 0.00000000E+00 7.07809547E-02 0.00000000E+00 2.56245368E-01-8.62754447E-16 + 3.20802392E-02-1.02998118E-16 5.37265521E-03 1.42591460E-08 2.79383871E-05 + 7.41532836E-11 0.00000000E+00 1.67874797E-08 0.00000000E+00 8.72871233E-11 + 1.71142790E-03 5.04184382E-18 2.76322618E-03 0.00000000E+00 3.18849585E-02 + 7.86895398E-17 7.53653253E-02 0.00000000E+00 5.40181790E-03 1.43410554E-08 +-2.80225361E-05-7.43896301E-11 0.00000000E+00 1.68711356E-08 0.00000000E+00 +-8.75285091E-11 1.41571429E-02 3.86143922E-17 1.82810811E-03 4.03948329E-18 + 2.25322484E-02 0.00000000E+00 2.86991859E-03 0.00000000E+00 2.55464585E-01 + 7.54342736E-16 3.19813722E-02 1.09459049E-16 5.93387629E-01 0.00000000E+00 + 7.29934964E-02 0.00000000E+00 1.01580228E-02 0.00000000E+00 6.34470882E-05 + 0.00000000E+00 8.35913479E-04-3.18989215E-18 5.24759342E-06-1.98747951E-20 + 0.00000000E+00 8.54251359E-10-2.73806992E-04 7.27531143E-10 0.00000000E+00 + 8.54251359E-10-2.73806992E-04 7.27531143E-10 5.80030827E-02 0.00000000E+00 +-1.57625180E-06 0.00000000E+00 5.09274113E-03-1.59978595E-17 6.17593519E-07 + 6.56462951E-21 0.00000000E+00-1.68711356E-08 0.00000000E+00-1.86915598E-08 + 5.40181790E-03-1.43410554E-08 5.98747791E-03-1.59062708E-08 0.00000000E+00 +-1.68711356E-08 0.00000000E+00-1.86915598E-08 5.40181790E-03-1.43410554E-08 + 5.98747791E-03-1.59062708E-08 9.92391215E-03 0.00000000E+00-6.20959458E-05 + 0.00000000E+00 9.27649615E-04-2.38100162E-18-5.77697364E-06 1.49663496E-20 + 0.00000000E+00-1.71140754E-08 0.00000000E+00 8.44902705E-10 5.48333417E-03 +-1.45807591E-08-2.70672289E-04 7.18308503E-10 0.00000000E+00-1.71140754E-08 + 0.00000000E+00 8.44902705E-10 5.48333417E-03-1.45807591E-08-2.70672289E-04 + 7.18308503E-10-2.64896136E-04-7.02503236E-10 2.10372404E-08 5.90866267E-14 + 0.00000000E+00-8.28689812E-10 0.00000000E+00 6.03464434E-14-8.84884002E-04 +-2.27033178E-18-1.40828619E-03 0.00000000E+00-1.59665827E-02-4.70371472E-17 +-3.70897054E-02 0.00000000E+00 5.98747791E-03 1.59062708E-08 4.06859671E-08 + 1.19621791E-13 0.00000000E+00 1.86915598E-08 0.00000000E+00 1.21217679E-13 + 1.82810811E-03 4.03948329E-18 7.31366903E-03 1.49856745E-17 2.86991859E-03 + 0.00000000E+00 1.14800744E-02 0.00000000E+00 3.19813722E-02 1.09459049E-16 + 1.27926216E-01 4.27082833E-16 7.29934964E-02 0.00000000E+00 2.92031753E-01 + 0.00000000E+00-2.79002658E-04-7.43994686E-10 1.96666770E-08 6.06398415E-14 + 0.00000000E+00-8.70744152E-10 0.00000000E+00 6.10060468E-14 1.82810490E-03 + 3.30222348E-18-9.44092636E-04-1.63182254E-18 2.86990801E-03 0.00000000E+00 +-1.46192192E-03 0.00000000E+00 3.19812816E-02 1.10710122E-16-1.60153802E-02 +-5.34270599E-17 7.29940319E-02 0.00000000E+00-3.59437467E-02 0.00000000E+00 + 0.00000000E+00-8.28689812E-10 0.00000000E+00 6.03464434E-14 2.64896136E-04 +-7.02503236E-10-2.10372404E-08 5.90866267E-14-1.40828619E-03 0.00000000E+00 +-8.84884002E-04 2.27033178E-18-3.70897054E-02 0.00000000E+00-1.59665827E-02 + 4.70371472E-17 0.00000000E+00 1.86915598E-08 0.00000000E+00 1.21217679E-13 +-5.98747791E-03 1.59062708E-08-4.06859671E-08 1.19621791E-13 2.86991859E-03 + 0.00000000E+00 1.14800744E-02 0.00000000E+00 1.82810811E-03-4.03948329E-18 + 7.31366903E-03-1.49856745E-17 7.29934964E-02 0.00000000E+00 2.92031753E-01 + 0.00000000E+00 3.19813722E-02-1.09459049E-16 1.27926216E-01-4.27082833E-16 + 0.00000000E+00-8.70744152E-10 0.00000000E+00 6.10060468E-14 2.79002658E-04 +-7.43994686E-10-1.96666770E-08 6.06398415E-14 2.86990801E-03 0.00000000E+00 +-1.46192192E-03 0.00000000E+00 1.82810490E-03-3.30222348E-18-9.44092636E-04 + 1.63182254E-18 7.29940319E-02 0.00000000E+00-3.59437467E-02 0.00000000E+00 + 3.19812816E-02-1.10710122E-16-1.60153802E-02 5.34270599E-17-2.64896136E-04 +-7.02503236E-10 2.10372404E-08 5.90866267E-14 0.00000000E+00-8.28689812E-10 + 0.00000000E+00 6.03464434E-14-8.84884002E-04-2.27033178E-18-1.40828619E-03 + 0.00000000E+00-8.84884002E-04-2.27033178E-18-1.40828619E-03 0.00000000E+00 + 5.98747791E-03 1.59062708E-08 4.06859671E-08 1.19621791E-13 0.00000000E+00 + 1.86915598E-08 0.00000000E+00 1.21217679E-13 1.82810811E-03 4.03948329E-18 + 7.31366903E-03 1.49856745E-17 2.86991859E-03 0.00000000E+00 1.14800744E-02 + 0.00000000E+00 1.82810811E-03 4.03948329E-18 7.31366903E-03 1.49856745E-17 + 2.86991859E-03 0.00000000E+00 1.14800744E-02 0.00000000E+00-2.79002658E-04 +-7.43994686E-10 1.96666770E-08 6.06398415E-14 0.00000000E+00-8.70744152E-10 + 0.00000000E+00 6.10060468E-14 1.82810490E-03 3.30222348E-18-9.44092636E-04 +-1.63182254E-18 2.86990801E-03 0.00000000E+00-1.46192192E-03 0.00000000E+00 + 1.82810490E-03 3.30222348E-18-9.44092636E-04-1.63182254E-18 2.86990801E-03 + 0.00000000E+00-1.46192192E-03 0.00000000E+00 0.00000000E+00-8.28689812E-10 + 0.00000000E+00 6.03464434E-14 2.64896136E-04-7.02503236E-10-2.10372404E-08 + 5.90866267E-14-1.40828619E-03 0.00000000E+00-8.84884002E-04 2.27033178E-18 +-1.40828619E-03 0.00000000E+00-8.84884002E-04 2.27033178E-18 0.00000000E+00 + 1.86915598E-08 0.00000000E+00 1.21217679E-13-5.98747791E-03 1.59062708E-08 +-4.06859671E-08 1.19621791E-13 2.86991859E-03 0.00000000E+00 1.14800744E-02 + 0.00000000E+00 1.82810811E-03-4.03948329E-18 7.31366903E-03-1.49856745E-17 + 2.86991859E-03 0.00000000E+00 1.14800744E-02 0.00000000E+00 1.82810811E-03 +-4.03948329E-18 7.31366903E-03-1.49856745E-17 0.00000000E+00-8.70744152E-10 + 0.00000000E+00 6.10060468E-14 2.79002658E-04-7.43994686E-10-1.96666770E-08 + 6.06398415E-14 2.86990801E-03 0.00000000E+00-1.46192192E-03 0.00000000E+00 + 1.82810490E-03-3.30222348E-18-9.44092636E-04 1.63182254E-18 2.86990801E-03 + 0.00000000E+00-1.46192192E-03 0.00000000E+00 1.82810490E-03-3.30222348E-18 +-9.44092636E-04 1.63182254E-18-5.20429128E-06-2.00389632E-20-3.13180677E-08 +-1.19791821E-22-6.35643898E-05 0.00000000E+00-3.80578680E-07 0.00000000E+00 +-2.10372404E-08-5.90866267E-14 0.00000000E+00-6.03464434E-14-2.10372404E-08 +-5.90866267E-14 0.00000000E+00-6.03464434E-14 6.17593519E-07-6.56462951E-21 + 8.80774507E-08 2.78163719E-22-1.57625180E-06 0.00000000E+00 1.00306595E-06 + 0.00000000E+00 2.80225361E-05 7.43896301E-11-4.06859671E-08-1.19621791E-13 + 0.00000000E+00 8.75285091E-11 0.00000000E+00-1.21217679E-13 2.80225361E-05 + 7.43896301E-11-4.06859671E-08-1.19621791E-13 0.00000000E+00 8.75285091E-11 + 0.00000000E+00-1.21217679E-13 5.82190668E-06 1.47919452E-20-3.47548451E-08 +-8.90827496E-23 6.19879592E-05 0.00000000E+00-3.71805439E-07 0.00000000E+00 +-2.85109682E-05-7.58259426E-11-1.96666770E-08-6.06398415E-14 0.00000000E+00 +-8.89841868E-11 0.00000000E+00-6.10060468E-14-2.85109682E-05-7.58259426E-11 +-1.96666770E-08-6.06398415E-14 0.00000000E+00-8.89841868E-11 0.00000000E+00 +-6.10060468E-14 8.35913479E-04 3.18989215E-18 5.24759342E-06 1.98747951E-20 + 1.01580228E-02 0.00000000E+00 6.34470882E-05 0.00000000E+00 2.73806992E-04 + 7.27531143E-10 0.00000000E+00 8.54251359E-10 2.73806992E-04 7.27531143E-10 + 0.00000000E+00 8.54251359E-10 5.09274113E-03 1.59978595E-17 6.17593519E-07 +-6.56462951E-21 5.80030827E-02 0.00000000E+00-1.57625180E-06 0.00000000E+00 +-5.40181790E-03-1.43410554E-08-5.98747791E-03-1.59062708E-08 0.00000000E+00 +-1.68711356E-08 0.00000000E+00-1.86915598E-08-5.40181790E-03-1.43410554E-08 +-5.98747791E-03-1.59062708E-08 0.00000000E+00-1.68711356E-08 0.00000000E+00 +-1.86915598E-08 9.27649615E-04 2.38100162E-18-5.77697364E-06-1.49663496E-20 + 9.92391215E-03 0.00000000E+00-6.20959458E-05 0.00000000E+00-5.48333417E-03 +-1.45807591E-08 2.70672289E-04 7.18308503E-10 0.00000000E+00-1.71140754E-08 + 0.00000000E+00 8.44902705E-10-5.48333417E-03-1.45807591E-08 2.70672289E-04 + 7.18308503E-10 0.00000000E+00-1.71140754E-08 0.00000000E+00 8.44902705E-10 +-6.35643898E-05 0.00000000E+00-3.80578680E-07 0.00000000E+00-5.20429128E-06 + 2.00389632E-20-3.13180677E-08 1.19791821E-22 0.00000000E+00-6.03464434E-14 + 2.10372404E-08-5.90866267E-14 0.00000000E+00-6.03464434E-14 2.10372404E-08 +-5.90866267E-14-1.57625180E-06 0.00000000E+00 1.00306595E-06 0.00000000E+00 + 6.17593519E-07 6.56462951E-21 8.80774507E-08-2.78163719E-22 0.00000000E+00 + 8.75285091E-11 0.00000000E+00-1.21217679E-13-2.80225361E-05 7.43896301E-11 + 4.06859671E-08-1.19621791E-13 0.00000000E+00 8.75285091E-11 0.00000000E+00 +-1.21217679E-13-2.80225361E-05 7.43896301E-11 4.06859671E-08-1.19621791E-13 + 6.19879592E-05 0.00000000E+00-3.71805439E-07 0.00000000E+00 5.82190668E-06 +-1.47919452E-20-3.47548451E-08 8.90827496E-23 0.00000000E+00-8.89841868E-11 + 0.00000000E+00-6.10060468E-14 2.85109682E-05-7.58259426E-11 1.96666770E-08 +-6.06398415E-14 0.00000000E+00-8.89841868E-11 0.00000000E+00-6.10060468E-14 + 2.85109682E-05-7.58259426E-11 1.96666770E-08-6.06398415E-14 0.00000000E+00 + 1.67874797E-08 0.00000000E+00 8.72871233E-11-5.37265521E-03 1.42591460E-08 +-2.79383871E-05 7.41532836E-11 2.76322618E-03 0.00000000E+00 1.71142790E-03 +-5.04184382E-18 2.76322618E-03 0.00000000E+00 1.71142790E-03-5.04184382E-18 + 0.00000000E+00 1.68711356E-08 0.00000000E+00-8.75285091E-11-5.40181790E-03 + 1.43410554E-08 2.80225361E-05-7.43896301E-11 2.25322484E-02 0.00000000E+00 + 2.86991859E-03 0.00000000E+00 1.41571429E-02-3.86143922E-17 1.82810811E-03 +-4.03948329E-18 2.25322484E-02 0.00000000E+00 2.86991859E-03 0.00000000E+00 + 1.41571429E-02-3.86143922E-17 1.82810811E-03-4.03948329E-18 5.37265521E-03 + 1.42591460E-08 2.79383871E-05 7.41532836E-11 0.00000000E+00 1.67874797E-08 + 0.00000000E+00 8.72871233E-11 1.71142790E-03 5.04184382E-18 2.76322618E-03 + 0.00000000E+00 1.71142790E-03 5.04184382E-18 2.76322618E-03 0.00000000E+00 + 5.40181790E-03 1.43410554E-08-2.80225361E-05-7.43896301E-11 0.00000000E+00 + 1.68711356E-08 0.00000000E+00-8.75285091E-11 1.41571429E-02 3.86143922E-17 + 1.82810811E-03 4.03948329E-18 2.25322484E-02 0.00000000E+00 2.86991859E-03 + 0.00000000E+00 1.41571429E-02 3.86143922E-17 1.82810811E-03 4.03948329E-18 + 2.25322484E-02 0.00000000E+00 2.86991859E-03 0.00000000E+00 0.00000000E+00 + 1.67874797E-08 0.00000000E+00 8.72871233E-11-5.37265521E-03 1.42591460E-08 +-2.79383871E-05 7.41532836E-11 2.76322618E-03 0.00000000E+00 1.71142790E-03 +-5.04184382E-18 7.53653253E-02 0.00000000E+00 3.18849585E-02-7.86895398E-17 + 0.00000000E+00 1.68711356E-08 0.00000000E+00-8.75285091E-11-5.40181790E-03 + 1.43410554E-08 2.80225361E-05-7.43896301E-11 2.25322484E-02 0.00000000E+00 + 2.86991859E-03 0.00000000E+00 1.41571429E-02-3.86143922E-17 1.82810811E-03 +-4.03948329E-18 5.93387629E-01 0.00000000E+00 7.29934964E-02 0.00000000E+00 + 2.55464585E-01-7.54342736E-16 3.19813722E-02-1.09459049E-16 5.25481749E-03 + 1.39460877E-08 2.73285266E-05 7.25249473E-11 0.00000000E+00 1.64645670E-08 + 0.00000000E+00 8.56090999E-11 1.59827776E-03 3.07194056E-19 2.65767940E-03 + 0.00000000E+00 3.17912517E-02 6.24604176E-17 7.79121484E-02 0.00000000E+00 + 5.28579158E-03 1.40257631E-08-2.74179011E-05-7.27548477E-11 0.00000000E+00 + 1.65472474E-08 0.00000000E+00-8.58476706E-11 1.32378201E-02 1.31500233E-17 + 1.71143086E-03 3.89020246E-18 2.16833443E-02 0.00000000E+00 2.76323637E-03 + 0.00000000E+00 2.54704445E-01 5.66111986E-16 3.18850492E-02 7.89254561E-17 + 6.13054529E-01 0.00000000E+00 7.53646881E-02 0.00000000E+00 1.04125372E-02 + 0.00000000E+00 6.50332846E-05 0.00000000E+00 7.47559263E-04-1.13575472E-18 + 4.69442679E-06-7.83265530E-21 0.00000000E+00 8.37932657E-10-2.68237425E-04 + 7.11481538E-10 0.00000000E+00 8.37932657E-10-2.68237425E-04 7.11481538E-10 + 5.94134350E-02 0.00000000E+00-1.71361916E-06 0.00000000E+00 4.57249694E-03 +-1.48270852E-17 5.94818675E-07-1.55263934E-20 0.00000000E+00-1.65472474E-08 + 0.00000000E+00-1.83337686E-08 5.28579158E-03-1.40257631E-08 5.86275860E-03 +-1.55559426E-08 0.00000000E+00-1.65472474E-08 0.00000000E+00-1.83337686E-08 + 5.28579158E-03-1.40257631E-08 5.86275860E-03-1.55559426E-08 1.01580228E-02 + 0.00000000E+00-6.35643898E-05 0.00000000E+00 8.35913479E-04-3.18989215E-18 +-5.20429128E-06 2.00389632E-20 0.00000000E+00-1.67874797E-08 0.00000000E+00 + 8.28689812E-10 5.37265521E-03-1.42591460E-08-2.64896136E-04 7.02503236E-10 + 0.00000000E+00-1.67874797E-08 0.00000000E+00 8.28689812E-10 5.37265521E-03 +-1.42591460E-08-2.64896136E-04 7.02503236E-10-2.58773112E-04-6.87136258E-10 + 2.23436279E-08 5.74751023E-14 0.00000000E+00-8.12669184E-10 0.00000000E+00 + 5.96426813E-14-8.27427155E-04-1.04934913E-18-1.35522894E-03 0.00000000E+00 +-1.59190752E-02-3.53464684E-17-3.83192091E-02 0.00000000E+00 5.86275860E-03 + 1.55559426E-08 4.33521663E-08 1.16473308E-13 0.00000000E+00 1.83337686E-08 + 0.00000000E+00 1.19875871E-13 1.71143086E-03 3.89020246E-18 6.84697719E-03 + 1.63570976E-17 2.76323637E-03 0.00000000E+00 1.10533307E-02 0.00000000E+00 + 3.18850492E-02 7.89254561E-17 1.27540950E-01 3.19991554E-16 7.53646881E-02 + 0.00000000E+00 3.01522752E-01 0.00000000E+00-2.73806992E-04-7.27531143E-10 + 2.10372404E-08 5.90866267E-14 0.00000000E+00-8.54251359E-10 0.00000000E+00 + 6.03464434E-14 1.71142790E-03 5.04184382E-18-8.84884002E-04-2.27033178E-18 + 2.76322618E-03 0.00000000E+00-1.40828619E-03 0.00000000E+00 3.18849585E-02 + 7.86895398E-17-1.59665827E-02-4.70371472E-17 7.53653253E-02 0.00000000E+00 +-3.70897054E-02 0.00000000E+00 0.00000000E+00-8.12669184E-10 0.00000000E+00 + 5.96426813E-14 2.58773112E-04-6.87136258E-10-2.23436279E-08 5.74751023E-14 +-1.35522894E-03 0.00000000E+00-8.27427155E-04 1.04934913E-18-3.83192091E-02 + 0.00000000E+00-1.59190752E-02 3.53464684E-17 0.00000000E+00 1.83337686E-08 + 0.00000000E+00 1.19875871E-13-5.86275860E-03 1.55559426E-08-4.33521663E-08 + 1.16473308E-13 2.76323637E-03 0.00000000E+00 1.10533307E-02 0.00000000E+00 + 1.71143086E-03-3.89020246E-18 6.84697719E-03-1.63570976E-17 7.53646881E-02 + 0.00000000E+00 3.01522752E-01 0.00000000E+00 3.18850492E-02-7.89254561E-17 + 1.27540950E-01-3.19991554E-16 0.00000000E+00-8.54251359E-10 0.00000000E+00 + 6.03464434E-14 2.73806992E-04-7.27531143E-10-2.10372404E-08 5.90866267E-14 + 2.76322618E-03 0.00000000E+00-1.40828619E-03 0.00000000E+00 1.71142790E-03 +-5.04184382E-18-8.84884002E-04 2.27033178E-18 7.53653253E-02 0.00000000E+00 +-3.70897054E-02 0.00000000E+00 3.18849585E-02-7.86895398E-17-1.59665827E-02 + 4.70371472E-17-2.58773112E-04-6.87136258E-10 2.23436279E-08 5.74751023E-14 + 0.00000000E+00-8.12669184E-10 0.00000000E+00 5.96426813E-14-8.27427155E-04 +-1.04934913E-18-1.35522894E-03 0.00000000E+00-8.27427155E-04-1.04934913E-18 +-1.35522894E-03 0.00000000E+00 5.86275860E-03 1.55559426E-08 4.33521663E-08 + 1.16473308E-13 0.00000000E+00 1.83337686E-08 0.00000000E+00 1.19875871E-13 + 1.71143086E-03 3.89020246E-18 6.84697719E-03 1.63570976E-17 2.76323637E-03 + 0.00000000E+00 1.10533307E-02 0.00000000E+00 1.71143086E-03 3.89020246E-18 + 6.84697719E-03 1.63570976E-17 2.76323637E-03 0.00000000E+00 1.10533307E-02 + 0.00000000E+00-2.73806992E-04-7.27531143E-10 2.10372404E-08 5.90866267E-14 + 0.00000000E+00-8.54251359E-10 0.00000000E+00 6.03464434E-14 1.71142790E-03 + 5.04184382E-18-8.84884002E-04-2.27033178E-18 2.76322618E-03 0.00000000E+00 +-1.40828619E-03 0.00000000E+00 1.71142790E-03 5.04184382E-18-8.84884002E-04 +-2.27033178E-18 2.76322618E-03 0.00000000E+00-1.40828619E-03 0.00000000E+00 + 0.00000000E+00-8.12669184E-10 0.00000000E+00 5.96426813E-14 2.58773112E-04 +-6.87136258E-10-2.23436279E-08 5.74751023E-14-1.35522894E-03 0.00000000E+00 +-8.27427155E-04 1.04934913E-18-1.35522894E-03 0.00000000E+00-8.27427155E-04 + 1.04934913E-18 0.00000000E+00 1.83337686E-08 0.00000000E+00 1.19875871E-13 +-5.86275860E-03 1.55559426E-08-4.33521663E-08 1.16473308E-13 2.76323637E-03 + 0.00000000E+00 1.10533307E-02 0.00000000E+00 1.71143086E-03-3.89020246E-18 + 6.84697719E-03-1.63570976E-17 2.76323637E-03 0.00000000E+00 1.10533307E-02 + 0.00000000E+00 1.71143086E-03-3.89020246E-18 6.84697719E-03-1.63570976E-17 + 0.00000000E+00-8.54251359E-10 0.00000000E+00 6.03464434E-14 2.73806992E-04 +-7.27531143E-10-2.10372404E-08 5.90866267E-14 2.76322618E-03 0.00000000E+00 +-1.40828619E-03 0.00000000E+00 1.71142790E-03-5.04184382E-18-8.84884002E-04 + 2.27033178E-18 2.76322618E-03 0.00000000E+00-1.40828619E-03 0.00000000E+00 + 1.71142790E-03-5.04184382E-18-8.84884002E-04 2.27033178E-18-4.65274217E-06 +-6.34273504E-21-2.80079613E-08-4.23026181E-23-6.51609043E-05 0.00000000E+00 +-3.90116469E-07 0.00000000E+00-2.23436279E-08-5.74751023E-14 0.00000000E+00 +-5.96426813E-14-2.23436279E-08-5.74751023E-14 0.00000000E+00-5.96426813E-14 + 5.94818675E-07 1.55263934E-20 7.90817695E-08 2.37514461E-22-1.71361916E-06 + 0.00000000E+00 1.02746848E-06 0.00000000E+00 2.74179011E-05 7.27548477E-11 +-4.33521663E-08-1.16473308E-13 0.00000000E+00 8.58476706E-11 0.00000000E+00 +-1.19875871E-13 2.74179011E-05 7.27548477E-11-4.33521663E-08-1.16473308E-13 + 0.00000000E+00 8.58476706E-11 0.00000000E+00-1.19875871E-13 5.24759342E-06 + 1.98747951E-20-3.13180677E-08-1.19791821E-22 6.34470882E-05 0.00000000E+00 +-3.80578680E-07 0.00000000E+00-2.79383871E-05-7.41532836E-11-2.10372404E-08 +-5.90866267E-14 0.00000000E+00-8.72871233E-11 0.00000000E+00-6.03464434E-14 +-2.79383871E-05-7.41532836E-11-2.10372404E-08-5.90866267E-14 0.00000000E+00 +-8.72871233E-11 0.00000000E+00-6.03464434E-14 7.47559263E-04 1.13575472E-18 + 4.69442679E-06 7.83265530E-21 1.04125372E-02 0.00000000E+00 6.50332846E-05 + 0.00000000E+00 2.68237425E-04 7.11481538E-10 0.00000000E+00 8.37932657E-10 + 2.68237425E-04 7.11481538E-10 0.00000000E+00 8.37932657E-10 4.57249694E-03 + 1.48270852E-17 5.94818675E-07 1.55263934E-20 5.94134350E-02 0.00000000E+00 +-1.71361916E-06 0.00000000E+00-5.28579158E-03-1.40257631E-08-5.86275860E-03 +-1.55559426E-08 0.00000000E+00-1.65472474E-08 0.00000000E+00-1.83337686E-08 +-5.28579158E-03-1.40257631E-08-5.86275860E-03-1.55559426E-08 0.00000000E+00 +-1.65472474E-08 0.00000000E+00-1.83337686E-08 8.35913479E-04 3.18989215E-18 +-5.20429128E-06-2.00389632E-20 1.01580228E-02 0.00000000E+00-6.35643898E-05 + 0.00000000E+00-5.37265521E-03-1.42591460E-08 2.64896136E-04 7.02503236E-10 + 0.00000000E+00-1.67874797E-08 0.00000000E+00 8.28689812E-10-5.37265521E-03 +-1.42591460E-08 2.64896136E-04 7.02503236E-10 0.00000000E+00-1.67874797E-08 + 0.00000000E+00 8.28689812E-10-6.51609043E-05 0.00000000E+00-3.90116469E-07 + 0.00000000E+00-4.65274217E-06 6.34273504E-21-2.80079613E-08 4.23026181E-23 + 0.00000000E+00-5.96426813E-14 2.23436279E-08-5.74751023E-14 0.00000000E+00 +-5.96426813E-14 2.23436279E-08-5.74751023E-14-1.71361916E-06 0.00000000E+00 + 1.02746848E-06 0.00000000E+00 5.94818675E-07-1.55263934E-20 7.90817695E-08 +-2.37514461E-22 0.00000000E+00 8.58476706E-11 0.00000000E+00-1.19875871E-13 +-2.74179011E-05 7.27548477E-11 4.33521663E-08-1.16473308E-13 0.00000000E+00 + 8.58476706E-11 0.00000000E+00-1.19875871E-13-2.74179011E-05 7.27548477E-11 + 4.33521663E-08-1.16473308E-13 6.34470882E-05 0.00000000E+00-3.80578680E-07 + 0.00000000E+00 5.24759342E-06-1.98747951E-20-3.13180677E-08 1.19791821E-22 + 0.00000000E+00-8.72871233E-11 0.00000000E+00-6.03464434E-14 2.79383871E-05 +-7.41532836E-11 2.10372404E-08-5.90866267E-14 0.00000000E+00-8.72871233E-11 + 0.00000000E+00-6.03464434E-14 2.79383871E-05-7.41532836E-11 2.10372404E-08 +-5.90866267E-14 0.00000000E+00 1.64645670E-08 0.00000000E+00 8.56090999E-11 +-5.25481749E-03 1.39460877E-08-2.73285266E-05 7.25249473E-11 2.65767940E-03 + 0.00000000E+00 1.59827776E-03-3.07194056E-19 2.65767940E-03 0.00000000E+00 + 1.59827776E-03-3.07194056E-19 0.00000000E+00 1.65472474E-08 0.00000000E+00 +-8.58476706E-11-5.28579158E-03 1.40257631E-08 2.74179011E-05-7.27548477E-11 + 2.16833443E-02 0.00000000E+00 2.76323637E-03 0.00000000E+00 1.32378201E-02 +-1.31500233E-17 1.71143086E-03-3.89020246E-18 2.16833443E-02 0.00000000E+00 + 2.76323637E-03 0.00000000E+00 1.32378201E-02-1.31500233E-17 1.71143086E-03 +-3.89020246E-18 5.25481749E-03 1.39460877E-08 2.73285266E-05 7.25249473E-11 + 0.00000000E+00 1.64645670E-08 0.00000000E+00 8.56090999E-11 1.59827776E-03 + 3.07194056E-19 2.65767940E-03 0.00000000E+00 1.59827776E-03 3.07194056E-19 + 2.65767940E-03 0.00000000E+00 5.28579158E-03 1.40257631E-08-2.74179011E-05 +-7.27548477E-11 0.00000000E+00 1.65472474E-08 0.00000000E+00-8.58476706E-11 + 1.32378201E-02 1.31500233E-17 1.71143086E-03 3.89020246E-18 2.16833443E-02 + 0.00000000E+00 2.76323637E-03 0.00000000E+00 1.32378201E-02 1.31500233E-17 + 1.71143086E-03 3.89020246E-18 2.16833443E-02 0.00000000E+00 2.76323637E-03 + 0.00000000E+00 0.00000000E+00 1.64645670E-08 0.00000000E+00 8.56090999E-11 +-5.25481749E-03 1.39460877E-08-2.73285266E-05 7.25249473E-11 2.65767940E-03 + 0.00000000E+00 1.59827776E-03-3.07194056E-19 7.79121484E-02 0.00000000E+00 + 3.17912517E-02-6.24604176E-17 0.00000000E+00 1.65472474E-08 0.00000000E+00 +-8.58476706E-11-5.28579158E-03 1.40257631E-08 2.74179011E-05-7.27548477E-11 + 2.16833443E-02 0.00000000E+00 2.76323637E-03 0.00000000E+00 1.32378201E-02 +-1.31500233E-17 1.71143086E-03-3.89020246E-18 6.13054529E-01 0.00000000E+00 + 7.53646881E-02 0.00000000E+00 2.54704445E-01-5.66111986E-16 3.18850492E-02 +-7.89254561E-17 5.13004616E-03 1.36419098E-08 2.66825903E-05 7.09426319E-11 + 0.00000000E+00 1.61455713E-08 0.00000000E+00 8.39513528E-11 1.48869981E-03 + 8.51473568E-18 2.55322679E-03 0.00000000E+00 3.17002332E-02 3.72592135E-17 + 8.06538711E-02 0.00000000E+00 5.16278301E-03 1.37192714E-08-2.67770526E-05 +-7.11658572E-11 0.00000000E+00 1.62272256E-08 0.00000000E+00-8.41869640E-11 + 1.23468946E-02 4.53867764E-17 1.59828056E-03 1.91281386E-18 2.08433575E-02 + 0.00000000E+00 2.65768930E-03 0.00000000E+00 2.53965523E-01 3.93043741E-16 + 3.17913421E-02 6.16037817E-17 6.34202278E-01 0.00000000E+00 7.79113882E-02 + 0.00000000E+00 1.06895961E-02 0.00000000E+00 6.67598937E-05 0.00000000E+00 + 6.62541288E-04-1.28136632E-18 4.16212610E-06-7.32980403E-21 0.00000000E+00 + 8.21800780E-10-2.62312661E-04 6.95861800E-10 0.00000000E+00 8.21800780E-10 +-2.62312661E-04 6.95861800E-10 6.09477772E-02 0.00000000E+00-1.86534041E-06 + 0.00000000E+00 4.07167374E-03-3.21857444E-18 5.72369280E-07 1.76617854E-21 + 0.00000000E+00-1.62272256E-08 0.00000000E+00-1.79801387E-08 5.16278301E-03 +-1.37192714E-08 5.73027854E-03-1.52151638E-08 0.00000000E+00-1.62272256E-08 + 0.00000000E+00-1.79801387E-08 5.16278301E-03-1.37192714E-08 5.73027854E-03 +-1.52151638E-08 1.04125372E-02 0.00000000E+00-6.51609043E-05 0.00000000E+00 + 7.47559263E-04-1.13575472E-18-4.65274217E-06 6.34273504E-21 0.00000000E+00 +-1.64645670E-08 0.00000000E+00 8.12669184E-10 5.25481749E-03-1.39460877E-08 +-2.58773112E-04 6.87136258E-10 0.00000000E+00-1.64645670E-08 0.00000000E+00 + 8.12669184E-10 5.25481749E-03-1.39460877E-08-2.58773112E-04 6.87136258E-10 +-2.52309708E-04-6.72223487E-10 2.36155764E-08 5.58063262E-14 0.00000000E+00 +-7.96850822E-10 0.00000000E+00 5.89027984E-14-7.71745094E-04-2.60688738E-18 +-1.30272902E-03 0.00000000E+00-1.58728938E-02-2.47157488E-17-3.96413148E-02 + 0.00000000E+00 5.73027854E-03 1.52151638E-08 4.59387584E-08 1.13196834E-13 + 0.00000000E+00 1.79801387E-08 0.00000000E+00 1.18434488E-13 1.59828056E-03 + 1.91281386E-18 6.39439251E-03 7.94574565E-18 2.65768930E-03 0.00000000E+00 + 1.06311283E-02 0.00000000E+00 3.17913421E-02 6.16037817E-17 1.27166148E-01 + 2.45432362E-16 7.79113882E-02 0.00000000E+00 3.11716723E-01 0.00000000E+00 +-2.68237425E-04-7.11481538E-10 2.23436279E-08 5.74751023E-14 0.00000000E+00 +-8.37932657E-10 0.00000000E+00 5.96426813E-14 1.59827776E-03 3.07194056E-19 +-8.27427155E-04-1.04934913E-18 2.65767940E-03 0.00000000E+00-1.35522894E-03 + 0.00000000E+00 3.17912517E-02 6.24604176E-17-1.59190752E-02-3.53464684E-17 + 7.79121484E-02 0.00000000E+00-3.83192091E-02 0.00000000E+00 0.00000000E+00 +-7.96850822E-10 0.00000000E+00 5.89027984E-14 2.52309708E-04-6.72223487E-10 +-2.36155764E-08 5.58063262E-14-1.30272902E-03 0.00000000E+00-7.71745094E-04 + 2.60688738E-18-3.96413148E-02 0.00000000E+00-1.58728938E-02 2.47157488E-17 + 0.00000000E+00 1.79801387E-08 0.00000000E+00 1.18434488E-13-5.73027854E-03 + 1.52151638E-08-4.59387584E-08 1.13196834E-13 2.65768930E-03 0.00000000E+00 + 1.06311283E-02 0.00000000E+00 1.59828056E-03-1.91281386E-18 6.39439251E-03 +-7.94574565E-18 7.79113882E-02 0.00000000E+00 3.11716723E-01 0.00000000E+00 + 3.17913421E-02-6.16037817E-17 1.27166148E-01-2.45432362E-16 0.00000000E+00 +-8.37932657E-10 0.00000000E+00 5.96426813E-14 2.68237425E-04-7.11481538E-10 +-2.23436279E-08 5.74751023E-14 2.65767940E-03 0.00000000E+00-1.35522894E-03 + 0.00000000E+00 1.59827776E-03-3.07194056E-19-8.27427155E-04 1.04934913E-18 + 7.79121484E-02 0.00000000E+00-3.83192091E-02 0.00000000E+00 3.17912517E-02 +-6.24604176E-17-1.59190752E-02 3.53464684E-17-2.52309708E-04-6.72223487E-10 + 2.36155764E-08 5.58063262E-14 0.00000000E+00-7.96850822E-10 0.00000000E+00 + 5.89027984E-14-7.71745094E-04-2.60688738E-18-1.30272902E-03 0.00000000E+00 +-7.71745094E-04-2.60688738E-18-1.30272902E-03 0.00000000E+00 5.73027854E-03 + 1.52151638E-08 4.59387584E-08 1.13196834E-13 0.00000000E+00 1.79801387E-08 + 0.00000000E+00 1.18434488E-13 1.59828056E-03 1.91281386E-18 6.39439251E-03 + 7.94574565E-18 2.65768930E-03 0.00000000E+00 1.06311283E-02 0.00000000E+00 + 1.59828056E-03 1.91281386E-18 6.39439251E-03 7.94574565E-18 2.65768930E-03 + 0.00000000E+00 1.06311283E-02 0.00000000E+00-2.68237425E-04-7.11481538E-10 + 2.23436279E-08 5.74751023E-14 0.00000000E+00-8.37932657E-10 0.00000000E+00 + 5.96426813E-14 1.59827776E-03 3.07194056E-19-8.27427155E-04-1.04934913E-18 + 2.65767940E-03 0.00000000E+00-1.35522894E-03 0.00000000E+00 1.59827776E-03 + 3.07194056E-19-8.27427155E-04-1.04934913E-18 2.65767940E-03 0.00000000E+00 +-1.35522894E-03 0.00000000E+00 0.00000000E+00-7.96850822E-10 0.00000000E+00 + 5.89027984E-14 2.52309708E-04-6.72223487E-10-2.36155764E-08 5.58063262E-14 +-1.30272902E-03 0.00000000E+00-7.71745094E-04 2.60688738E-18-1.30272902E-03 + 0.00000000E+00-7.71745094E-04 2.60688738E-18 0.00000000E+00 1.79801387E-08 + 0.00000000E+00 1.18434488E-13-5.73027854E-03 1.52151638E-08-4.59387584E-08 + 1.13196834E-13 2.65768930E-03 0.00000000E+00 1.06311283E-02 0.00000000E+00 + 1.59828056E-03-1.91281386E-18 6.39439251E-03-7.94574565E-18 2.65768930E-03 + 0.00000000E+00 1.06311283E-02 0.00000000E+00 1.59828056E-03-1.91281386E-18 + 6.39439251E-03-7.94574565E-18 0.00000000E+00-8.37932657E-10 0.00000000E+00 + 5.96426813E-14 2.68237425E-04-7.11481538E-10-2.23436279E-08 5.74751023E-14 + 2.65767940E-03 0.00000000E+00-1.35522894E-03 0.00000000E+00 1.59827776E-03 +-3.07194056E-19-8.27427155E-04 1.04934913E-18 2.65767940E-03 0.00000000E+00 +-1.35522894E-03 0.00000000E+00 1.59827776E-03-3.07194056E-19-8.27427155E-04 + 1.04934913E-18-4.12203555E-06-8.67992250E-21-2.48228106E-08-4.78910259E-23 +-6.68989104E-05 0.00000000E+00-4.00499004E-07 0.00000000E+00-2.36155764E-08 +-5.58063262E-14 0.00000000E+00-5.89027984E-14-2.36155764E-08-5.58063262E-14 + 0.00000000E+00-5.89027984E-14 5.72369280E-07-1.76617854E-21 7.04217157E-08 + 8.44824150E-23-1.86534041E-06 0.00000000E+00 1.05401586E-06 0.00000000E+00 + 2.67770526E-05 7.11658572E-11-4.59387584E-08-1.13196834E-13 0.00000000E+00 + 8.41869640E-11 0.00000000E+00-1.18434488E-13 2.67770526E-05 7.11658572E-11 +-4.59387584E-08-1.13196834E-13 0.00000000E+00 8.41869640E-11 0.00000000E+00 +-1.18434488E-13 4.69442679E-06 7.83265530E-21-2.80079613E-08-4.23026181E-23 + 6.50332846E-05 0.00000000E+00-3.90116469E-07 0.00000000E+00-2.73285266E-05 +-7.25249473E-11-2.23436279E-08-5.74751023E-14 0.00000000E+00-8.56090999E-11 + 0.00000000E+00-5.96426813E-14-2.73285266E-05-7.25249473E-11-2.23436279E-08 +-5.74751023E-14 0.00000000E+00-8.56090999E-11 0.00000000E+00-5.96426813E-14 + 6.62541288E-04 1.28136632E-18 4.16212610E-06 7.32980403E-21 1.06895961E-02 + 0.00000000E+00 6.67598937E-05 0.00000000E+00 2.62312661E-04 6.95861800E-10 + 0.00000000E+00 8.21800780E-10 2.62312661E-04 6.95861800E-10 0.00000000E+00 + 8.21800780E-10 4.07167374E-03 3.21857444E-18 5.72369280E-07-1.76617854E-21 + 6.09477772E-02 0.00000000E+00-1.86534041E-06 0.00000000E+00-5.16278301E-03 +-1.37192714E-08-5.73027854E-03-1.52151638E-08 0.00000000E+00-1.62272256E-08 + 0.00000000E+00-1.79801387E-08-5.16278301E-03-1.37192714E-08-5.73027854E-03 +-1.52151638E-08 0.00000000E+00-1.62272256E-08 0.00000000E+00-1.79801387E-08 + 7.47559263E-04 1.13575472E-18-4.65274217E-06-6.34273504E-21 1.04125372E-02 + 0.00000000E+00-6.51609043E-05 0.00000000E+00-5.25481749E-03-1.39460877E-08 + 2.58773112E-04 6.87136258E-10 0.00000000E+00-1.64645670E-08 0.00000000E+00 + 8.12669184E-10-5.25481749E-03-1.39460877E-08 2.58773112E-04 6.87136258E-10 + 0.00000000E+00-1.64645670E-08 0.00000000E+00 8.12669184E-10-6.68989104E-05 + 0.00000000E+00-4.00499004E-07 0.00000000E+00-4.12203555E-06 8.67992250E-21 +-2.48228106E-08 4.78910259E-23 0.00000000E+00-5.89027984E-14 2.36155764E-08 +-5.58063262E-14 0.00000000E+00-5.89027984E-14 2.36155764E-08-5.58063262E-14 +-1.86534041E-06 0.00000000E+00 1.05401586E-06 0.00000000E+00 5.72369280E-07 + 1.76617854E-21 7.04217157E-08-8.44824150E-23 0.00000000E+00 8.41869640E-11 + 0.00000000E+00-1.18434488E-13-2.67770526E-05 7.11658572E-11 4.59387584E-08 +-1.13196834E-13 0.00000000E+00 8.41869640E-11 0.00000000E+00-1.18434488E-13 +-2.67770526E-05 7.11658572E-11 4.59387584E-08-1.13196834E-13 6.50332846E-05 + 0.00000000E+00-3.90116469E-07 0.00000000E+00 4.69442679E-06-7.83265530E-21 +-2.80079613E-08 4.23026181E-23 0.00000000E+00-8.56090999E-11 0.00000000E+00 +-5.96426813E-14 2.73285266E-05-7.25249473E-11 2.23436279E-08-5.74751023E-14 + 0.00000000E+00-8.56090999E-11 0.00000000E+00-5.96426813E-14 2.73285266E-05 +-7.25249473E-11 2.23436279E-08-5.74751023E-14 0.00000000E+00 1.61455713E-08 + 0.00000000E+00 8.39513528E-11-5.13004616E-03 1.36419098E-08-2.66825903E-05 + 7.09426319E-11 2.55322679E-03 0.00000000E+00 1.48869981E-03-8.51473568E-18 + 2.55322679E-03 0.00000000E+00 1.48869981E-03-8.51473568E-18 0.00000000E+00 + 1.62272256E-08 0.00000000E+00-8.41869640E-11-5.16278301E-03 1.37192714E-08 + 2.67770526E-05-7.11658572E-11 2.08433575E-02 0.00000000E+00 2.65768930E-03 + 0.00000000E+00 1.23468946E-02-4.53867764E-17 1.59828056E-03-1.91281386E-18 + 2.08433575E-02 0.00000000E+00 2.65768930E-03 0.00000000E+00 1.23468946E-02 +-4.53867764E-17 1.59828056E-03-1.91281386E-18 5.13004616E-03 1.36419098E-08 + 2.66825903E-05 7.09426319E-11 0.00000000E+00 1.61455713E-08 0.00000000E+00 + 8.39513528E-11 1.48869981E-03 8.51473568E-18 2.55322679E-03 0.00000000E+00 + 1.48869981E-03 8.51473568E-18 2.55322679E-03 0.00000000E+00 5.16278301E-03 + 1.37192714E-08-2.67770526E-05-7.11658572E-11 0.00000000E+00 1.62272256E-08 + 0.00000000E+00-8.41869640E-11 1.23468946E-02 4.53867764E-17 1.59828056E-03 + 1.91281386E-18 2.08433575E-02 0.00000000E+00 2.65768930E-03 0.00000000E+00 + 1.23468946E-02 4.53867764E-17 1.59828056E-03 1.91281386E-18 2.08433575E-02 + 0.00000000E+00 2.65768930E-03 0.00000000E+00 0.00000000E+00 1.61455713E-08 + 0.00000000E+00 8.39513528E-11-5.13004616E-03 1.36419098E-08-2.66825903E-05 + 7.09426319E-11 2.55322679E-03 0.00000000E+00 1.48869981E-03-8.51473568E-18 + 8.06538711E-02 0.00000000E+00 3.17002332E-02-3.72592135E-17 0.00000000E+00 + 1.62272256E-08 0.00000000E+00-8.41869640E-11-5.16278301E-03 1.37192714E-08 + 2.67770526E-05-7.11658572E-11 2.08433575E-02 0.00000000E+00 2.65768930E-03 + 0.00000000E+00 1.23468946E-02-4.53867764E-17 1.59828056E-03-1.91281386E-18 + 6.34202278E-01 0.00000000E+00 7.79113882E-02 0.00000000E+00 2.53965523E-01 +-3.93043741E-16 3.17913421E-02-6.16037817E-17 4.99861328E-03 1.33469582E-08 + 2.60019680E-05 6.94081162E-11 0.00000000E+00 1.58307203E-08 0.00000000E+00 + 8.23150473E-11 1.38273676E-03 5.45447543E-19 2.44982624E-03 0.00000000E+00 + 3.16119696E-02 7.04588741E-17 8.36128445E-02 0.00000000E+00 5.03303721E-03 + 1.34219111E-08-2.61012977E-05-6.96243919E-11 0.00000000E+00 1.59112842E-08 + 0.00000000E+00-8.25475130E-11 1.14847169E-02 2.96186639E-17 1.48870231E-03 + 7.19681856E-18 2.00119554E-02 0.00000000E+00 2.55323636E-03 0.00000000E+00 + 2.53248378E-01 3.66269987E-16 3.17003238E-02 3.05517383E-17 6.56997609E-01 + 0.00000000E+00 8.06529646E-02 0.00000000E+00 1.09916887E-02 0.00000000E+00 + 6.86423661E-05 0.00000000E+00 5.80827978E-04-3.36050674E-18 3.65048962E-06 +-2.09085556E-20 0.00000000E+00 8.05864746E-10-2.56041225E-04 6.80686546E-10 + 0.00000000E+00 8.05864746E-10-2.56041225E-04 6.80686546E-10 6.26192815E-02 + 0.00000000E+00-2.03385225E-06 0.00000000E+00 3.59002130E-03-1.48470091E-17 + 5.50113834E-07 1.50281726E-20 0.00000000E+00-1.59112842E-08 0.00000000E+00 +-1.76309011E-08 5.03303721E-03-1.34219111E-08 5.59026708E-03-1.48842853E-08 + 0.00000000E+00-1.59112842E-08 0.00000000E+00-1.76309011E-08 5.03303721E-03 +-1.34219111E-08 5.59026708E-03-1.48842853E-08 1.06895961E-02 0.00000000E+00 +-6.68989104E-05 0.00000000E+00 6.62541288E-04-1.28136632E-18-4.12203555E-06 + 8.67992250E-21 0.00000000E+00-1.61455713E-08 0.00000000E+00 7.96850822E-10 + 5.13004616E-03-1.36419098E-08-2.52309708E-04 6.72223487E-10 0.00000000E+00 +-1.61455713E-08 0.00000000E+00 7.96850822E-10 5.13004616E-03-1.36419098E-08 +-2.52309708E-04 6.72223487E-10-2.45522789E-04-6.57784243E-10 2.48324306E-08 + 5.40689114E-14 0.00000000E+00-7.81247960E-10 0.00000000E+00 5.81164074E-14 +-7.17859768E-04-1.93556653E-18-1.25076565E-03 0.00000000E+00-1.58280733E-02 +-2.52526531E-17-4.10664523E-02 0.00000000E+00 5.59026708E-03 1.48842853E-08 + 4.84201361E-08 1.09795244E-13 0.00000000E+00 1.76309011E-08 0.00000000E+00 + 1.16912045E-13 1.48870231E-03 7.19681856E-18 5.95609546E-03 2.67304467E-17 + 2.55323636E-03 0.00000000E+00 1.02133022E-02 0.00000000E+00 3.17003238E-02 + 3.05517383E-17 1.26802098E-01 1.58769458E-16 8.06529646E-02 0.00000000E+00 + 3.22691311E-01 0.00000000E+00-2.62312661E-04-6.95861800E-10 2.36155764E-08 + 5.58063262E-14 0.00000000E+00-8.21800780E-10 0.00000000E+00 5.89027984E-14 + 1.48869981E-03 8.51473568E-18-7.71745094E-04-2.60688738E-18 2.55322679E-03 + 0.00000000E+00-1.30272902E-03 0.00000000E+00 3.17002332E-02 3.72592135E-17 +-1.58728938E-02-2.47157488E-17 8.06538711E-02 0.00000000E+00-3.96413148E-02 + 0.00000000E+00 0.00000000E+00-7.81247960E-10 0.00000000E+00 5.81164074E-14 + 2.45522789E-04-6.57784243E-10-2.48324306E-08 5.40689114E-14-1.25076565E-03 + 0.00000000E+00-7.17859768E-04 1.93556653E-18-4.10664523E-02 0.00000000E+00 +-1.58280733E-02 2.52526531E-17 0.00000000E+00 1.76309011E-08 0.00000000E+00 + 1.16912045E-13-5.59026708E-03 1.48842853E-08-4.84201361E-08 1.09795244E-13 + 2.55323636E-03 0.00000000E+00 1.02133022E-02 0.00000000E+00 1.48870231E-03 +-7.19681856E-18 5.95609546E-03-2.67304467E-17 8.06529646E-02 0.00000000E+00 + 3.22691311E-01 0.00000000E+00 3.17003238E-02-3.05517383E-17 1.26802098E-01 +-1.58769458E-16 0.00000000E+00-8.21800780E-10 0.00000000E+00 5.89027984E-14 + 2.62312661E-04-6.95861800E-10-2.36155764E-08 5.58063262E-14 2.55322679E-03 + 0.00000000E+00-1.30272902E-03 0.00000000E+00 1.48869981E-03-8.51473568E-18 +-7.71745094E-04 2.60688738E-18 8.06538711E-02 0.00000000E+00-3.96413148E-02 + 0.00000000E+00 3.17002332E-02-3.72592135E-17-1.58728938E-02 2.47157488E-17 +-2.45522789E-04-6.57784243E-10 2.48324306E-08 5.40689114E-14 0.00000000E+00 +-7.81247960E-10 0.00000000E+00 5.81164074E-14-7.17859768E-04-1.93556653E-18 +-1.25076565E-03 0.00000000E+00-7.17859768E-04-1.93556653E-18-1.25076565E-03 + 0.00000000E+00 5.59026708E-03 1.48842853E-08 4.84201361E-08 1.09795244E-13 + 0.00000000E+00 1.76309011E-08 0.00000000E+00 1.16912045E-13 1.48870231E-03 + 7.19681856E-18 5.95609546E-03 2.67304467E-17 2.55323636E-03 0.00000000E+00 + 1.02133022E-02 0.00000000E+00 1.48870231E-03 7.19681856E-18 5.95609546E-03 + 2.67304467E-17 2.55323636E-03 0.00000000E+00 1.02133022E-02 0.00000000E+00 +-2.62312661E-04-6.95861800E-10 2.36155764E-08 5.58063262E-14 0.00000000E+00 +-8.21800780E-10 0.00000000E+00 5.89027984E-14 1.48869981E-03 8.51473568E-18 +-7.71745094E-04-2.60688738E-18 2.55322679E-03 0.00000000E+00-1.30272902E-03 + 0.00000000E+00 1.48869981E-03 8.51473568E-18-7.71745094E-04-2.60688738E-18 + 2.55322679E-03 0.00000000E+00-1.30272902E-03 0.00000000E+00 0.00000000E+00 +-7.81247960E-10 0.00000000E+00 5.81164074E-14 2.45522789E-04-6.57784243E-10 +-2.48324306E-08 5.40689114E-14-1.25076565E-03 0.00000000E+00-7.17859768E-04 + 1.93556653E-18-1.25076565E-03 0.00000000E+00-7.17859768E-04 1.93556653E-18 + 0.00000000E+00 1.76309011E-08 0.00000000E+00 1.16912045E-13-5.59026708E-03 + 1.48842853E-08-4.84201361E-08 1.09795244E-13 2.55323636E-03 0.00000000E+00 + 1.02133022E-02 0.00000000E+00 1.48870231E-03-7.19681856E-18 5.95609546E-03 +-2.67304467E-17 2.55323636E-03 0.00000000E+00 1.02133022E-02 0.00000000E+00 + 1.48870231E-03-7.19681856E-18 5.95609546E-03-2.67304467E-17 0.00000000E+00 +-8.21800780E-10 0.00000000E+00 5.89027984E-14 2.62312661E-04-6.95861800E-10 +-2.36155764E-08 5.58063262E-14 2.55322679E-03 0.00000000E+00-1.30272902E-03 + 0.00000000E+00 1.48869981E-03-8.51473568E-18-7.71745094E-04 2.60688738E-18 + 2.55322679E-03 0.00000000E+00-1.30272902E-03 0.00000000E+00 1.48869981E-03 +-8.51473568E-18-7.71745094E-04 2.60688738E-18-3.61197924E-06-2.11421703E-20 +-2.17614400E-08-1.26218455E-22-6.87940846E-05 0.00000000E+00-4.11819567E-07 + 0.00000000E+00-2.48324306E-08-5.40689114E-14 0.00000000E+00-5.81164074E-14 +-2.48324306E-08-5.40689114E-14 0.00000000E+00-5.81164074E-14 5.50113834E-07 +-1.50281726E-20 6.20931825E-08 2.46059960E-22-2.03385225E-06 0.00000000E+00 + 1.08293750E-06 0.00000000E+00 2.61012977E-05 6.96243919E-11-4.84201361E-08 +-1.09795244E-13 0.00000000E+00 8.25475130E-11 0.00000000E+00-1.16912045E-13 + 2.61012977E-05 6.96243919E-11-4.84201361E-08-1.09795244E-13 0.00000000E+00 + 8.25475130E-11 0.00000000E+00-1.16912045E-13 4.16212610E-06 7.32980403E-21 +-2.48228106E-08-4.78910259E-23 6.67598937E-05 0.00000000E+00-4.00499004E-07 + 0.00000000E+00-2.66825903E-05-7.09426319E-11-2.36155764E-08-5.58063262E-14 + 0.00000000E+00-8.39513528E-11 0.00000000E+00-5.89027984E-14-2.66825903E-05 +-7.09426319E-11-2.36155764E-08-5.58063262E-14 0.00000000E+00-8.39513528E-11 + 0.00000000E+00-5.89027984E-14 5.80827978E-04 3.36050674E-18 3.65048962E-06 + 2.09085556E-20 1.09916887E-02 0.00000000E+00 6.86423661E-05 0.00000000E+00 + 2.56041225E-04 6.80686546E-10 0.00000000E+00 8.05864746E-10 2.56041225E-04 + 6.80686546E-10 0.00000000E+00 8.05864746E-10 3.59002130E-03 1.48470091E-17 + 5.50113834E-07-1.50281726E-20 6.26192815E-02 0.00000000E+00-2.03385225E-06 + 0.00000000E+00-5.03303721E-03-1.34219111E-08-5.59026708E-03-1.48842853E-08 + 0.00000000E+00-1.59112842E-08 0.00000000E+00-1.76309011E-08-5.03303721E-03 +-1.34219111E-08-5.59026708E-03-1.48842853E-08 0.00000000E+00-1.59112842E-08 + 0.00000000E+00-1.76309011E-08 6.62541288E-04 1.28136632E-18-4.12203555E-06 +-8.67992250E-21 1.06895961E-02 0.00000000E+00-6.68989104E-05 0.00000000E+00 +-5.13004616E-03-1.36419098E-08 2.52309708E-04 6.72223487E-10 0.00000000E+00 +-1.61455713E-08 0.00000000E+00 7.96850822E-10-5.13004616E-03-1.36419098E-08 + 2.52309708E-04 6.72223487E-10 0.00000000E+00-1.61455713E-08 0.00000000E+00 + 7.96850822E-10-6.87940846E-05 0.00000000E+00-4.11819567E-07 0.00000000E+00 +-3.61197924E-06 2.11421703E-20-2.17614400E-08 1.26218455E-22 0.00000000E+00 +-5.81164074E-14 2.48324306E-08-5.40689114E-14 0.00000000E+00-5.81164074E-14 + 2.48324306E-08-5.40689114E-14-2.03385225E-06 0.00000000E+00 1.08293750E-06 + 0.00000000E+00 5.50113834E-07 1.50281726E-20 6.20931825E-08-2.46059960E-22 + 0.00000000E+00 8.25475130E-11 0.00000000E+00-1.16912045E-13-2.61012977E-05 + 6.96243919E-11 4.84201361E-08-1.09795244E-13 0.00000000E+00 8.25475130E-11 + 0.00000000E+00-1.16912045E-13-2.61012977E-05 6.96243919E-11 4.84201361E-08 +-1.09795244E-13 6.67598937E-05 0.00000000E+00-4.00499004E-07 0.00000000E+00 + 4.16212610E-06-7.32980403E-21-2.48228106E-08 4.78910259E-23 0.00000000E+00 +-8.39513528E-11 0.00000000E+00-5.89027984E-14 2.66825903E-05-7.09426319E-11 + 2.36155764E-08-5.58063262E-14 0.00000000E+00-8.39513528E-11 0.00000000E+00 +-5.89027984E-14 2.66825903E-05-7.09426319E-11 2.36155764E-08-5.58063262E-14 + 0.00000000E+00 1.58307203E-08 0.00000000E+00 8.23150473E-11-4.99861328E-03 + 1.33469582E-08-2.60019680E-05 6.94081162E-11 2.44982624E-03 0.00000000E+00 + 1.38273676E-03-5.45447543E-19 2.44982624E-03 0.00000000E+00 1.38273676E-03 +-5.45447543E-19 0.00000000E+00 1.59112842E-08 0.00000000E+00-8.25475130E-11 +-5.03303721E-03 1.34219111E-08 2.61012977E-05-6.96243919E-11 2.00119554E-02 + 0.00000000E+00 2.55323636E-03 0.00000000E+00 1.14847169E-02-2.96186639E-17 + 1.48870231E-03-7.19681856E-18 2.00119554E-02 0.00000000E+00 2.55323636E-03 + 0.00000000E+00 1.14847169E-02-2.96186639E-17 1.48870231E-03-7.19681856E-18 + 4.99861328E-03 1.33469582E-08 2.60019680E-05 6.94081162E-11 0.00000000E+00 + 1.58307203E-08 0.00000000E+00 8.23150473E-11 1.38273676E-03 5.45447543E-19 + 2.44982624E-03 0.00000000E+00 1.38273676E-03 5.45447543E-19 2.44982624E-03 + 0.00000000E+00 5.03303721E-03 1.34219111E-08-2.61012977E-05-6.96243919E-11 + 0.00000000E+00 1.59112842E-08 0.00000000E+00-8.25475130E-11 1.14847169E-02 + 2.96186639E-17 1.48870231E-03 7.19681856E-18 2.00119554E-02 0.00000000E+00 + 2.55323636E-03 0.00000000E+00 1.14847169E-02 2.96186639E-17 1.48870231E-03 + 7.19681856E-18 2.00119554E-02 0.00000000E+00 2.55323636E-03 0.00000000E+00 + 0.00000000E+00 1.58307203E-08 0.00000000E+00 8.23150473E-11-4.99861328E-03 + 1.33469582E-08-2.60019680E-05 6.94081162E-11 2.44982624E-03 0.00000000E+00 + 1.38273676E-03-5.45447543E-19 8.36128445E-02 0.00000000E+00 3.16119696E-02 +-7.04588741E-17 0.00000000E+00 1.59112842E-08 0.00000000E+00-8.25475130E-11 +-5.03303721E-03 1.34219111E-08 2.61012977E-05-6.96243919E-11 2.00119554E-02 + 0.00000000E+00 2.55323636E-03 0.00000000E+00 1.14847169E-02-2.96186639E-17 + 1.48870231E-03-7.19681856E-18 6.56997609E-01 0.00000000E+00 8.06529646E-02 + 0.00000000E+00 2.53248378E-01-3.66269987E-16 3.17003238E-02-3.05517383E-17 + 4.86075581E-03 1.30616280E-08 2.52878955E-05 6.79234373E-11 0.00000000E+00 + 1.55202773E-08 0.00000000E+00 8.07015437E-11 1.28043105E-03 3.40777737E-18 + 2.34743654E-03 0.00000000E+00 3.15265277E-02 1.04649952E-16 8.68149937E-02 + 0.00000000E+00 4.89680507E-03 1.31340656E-08-2.53919163E-05-6.81324562E-11 + 0.00000000E+00 1.55996802E-08 0.00000000E+00-8.09306600E-11 1.06516294E-02 + 1.57270646E-17 1.38273908E-03 8.41835607E-19 1.91888049E-02 0.00000000E+00 + 2.44983550E-03 0.00000000E+00 2.52553530E-01 8.76603235E-16 3.16120592E-02 + 9.47988447E-17 6.81633378E-01 0.00000000E+00 8.36117581E-02 0.00000000E+00 + 1.13216876E-02 0.00000000E+00 7.06985711E-05 0.00000000E+00 5.02368150E-04 +-1.97397660E-18 3.15920268E-06-1.29098602E-20 0.00000000E+00 7.90136622E-10 +-2.49437815E-04 6.65973523E-10 0.00000000E+00 7.90136622E-10-2.49437815E-04 + 6.65973523E-10 6.44435088E-02 0.00000000E+00-2.22163385E-06 0.00000000E+00 + 3.12733081E-03-1.71465606E-17 5.28230132E-07-1.04488351E-20 0.00000000E+00 +-1.55996802E-08 0.00000000E+00-1.72863270E-08 4.89680507E-03-1.31340656E-08 + 5.44303140E-03-1.45637109E-08 0.00000000E+00-1.55996802E-08 0.00000000E+00 +-1.72863270E-08 4.89680507E-03-1.31340656E-08 5.44303140E-03-1.45637109E-08 + 1.09916887E-02 0.00000000E+00-6.87940846E-05 0.00000000E+00 5.80827978E-04 +-3.36050674E-18-3.61197924E-06 2.11421703E-20 0.00000000E+00-1.58307203E-08 + 0.00000000E+00 7.81247960E-10 4.99861328E-03-1.33469582E-08-2.45522789E-04 + 6.57784243E-10 0.00000000E+00-1.58307203E-08 0.00000000E+00 7.81247960E-10 + 4.99861328E-03-1.33469582E-08-2.45522789E-04 6.57784243E-10-2.38422733E-04 +-6.43839774E-10 2.60052053E-08 5.22547100E-14 0.00000000E+00-7.65874611E-10 + 0.00000000E+00 5.72790698E-14-6.65792532E-04-1.06240324E-18-1.19931801E-03 + 0.00000000E+00-1.57846467E-02-4.98621993E-17-4.26066879E-02 0.00000000E+00 + 5.44303140E-03 1.45637109E-08 5.08236504E-08 1.06250655E-13 0.00000000E+00 + 1.72863270E-08 0.00000000E+00 1.15294289E-13 1.38273908E-03 8.41835607E-19 + 5.53225806E-03 6.10119392E-18 2.44983550E-03 0.00000000E+00 9.79968469E-03 + 0.00000000E+00 3.16120592E-02 9.47988447E-17 1.26449066E-01 3.19460499E-16 + 8.36117581E-02 0.00000000E+00 3.34536116E-01 0.00000000E+00-2.56041225E-04 +-6.80686546E-10 2.48324306E-08 5.40689114E-14 0.00000000E+00-8.05864746E-10 + 0.00000000E+00 5.81164074E-14 1.38273676E-03 5.45447543E-19-7.17859768E-04 +-1.93556653E-18 2.44982624E-03 0.00000000E+00-1.25076565E-03 0.00000000E+00 + 3.16119696E-02 7.04588741E-17-1.58280733E-02-2.52526531E-17 8.36128445E-02 + 0.00000000E+00-4.10664523E-02 0.00000000E+00 0.00000000E+00-7.65874611E-10 + 0.00000000E+00 5.72790698E-14 2.38422733E-04-6.43839774E-10-2.60052053E-08 + 5.22547100E-14-1.19931801E-03 0.00000000E+00-6.65792532E-04 1.06240324E-18 +-4.26066879E-02 0.00000000E+00-1.57846467E-02 4.98621993E-17 0.00000000E+00 + 1.72863270E-08 0.00000000E+00 1.15294289E-13-5.44303140E-03 1.45637109E-08 +-5.08236504E-08 1.06250655E-13 2.44983550E-03 0.00000000E+00 9.79968469E-03 + 0.00000000E+00 1.38273908E-03-8.41835607E-19 5.53225806E-03-6.10119392E-18 + 8.36117581E-02 0.00000000E+00 3.34536116E-01 0.00000000E+00 3.16120592E-02 +-9.47988447E-17 1.26449066E-01-3.19460499E-16 0.00000000E+00-8.05864746E-10 + 0.00000000E+00 5.81164074E-14 2.56041225E-04-6.80686546E-10-2.48324306E-08 + 5.40689114E-14 2.44982624E-03 0.00000000E+00-1.25076565E-03 0.00000000E+00 + 1.38273676E-03-5.45447543E-19-7.17859768E-04 1.93556653E-18 8.36128445E-02 + 0.00000000E+00-4.10664523E-02 0.00000000E+00 3.16119696E-02-7.04588741E-17 +-1.58280733E-02 2.52526531E-17-2.38422733E-04-6.43839774E-10 2.60052053E-08 + 5.22547100E-14 0.00000000E+00-7.65874611E-10 0.00000000E+00 5.72790698E-14 +-6.65792532E-04-1.06240324E-18-1.19931801E-03 0.00000000E+00-6.65792532E-04 +-1.06240324E-18-1.19931801E-03 0.00000000E+00 5.44303140E-03 1.45637109E-08 + 5.08236504E-08 1.06250655E-13 0.00000000E+00 1.72863270E-08 0.00000000E+00 + 1.15294289E-13 1.38273908E-03 8.41835607E-19 5.53225806E-03 6.10119392E-18 + 2.44983550E-03 0.00000000E+00 9.79968469E-03 0.00000000E+00 1.38273908E-03 + 8.41835607E-19 5.53225806E-03 6.10119392E-18 2.44983550E-03 0.00000000E+00 + 9.79968469E-03 0.00000000E+00-2.56041225E-04-6.80686546E-10 2.48324306E-08 + 5.40689114E-14 0.00000000E+00-8.05864746E-10 0.00000000E+00 5.81164074E-14 + 1.38273676E-03 5.45447543E-19-7.17859768E-04-1.93556653E-18 2.44982624E-03 + 0.00000000E+00-1.25076565E-03 0.00000000E+00 1.38273676E-03 5.45447543E-19 +-7.17859768E-04-1.93556653E-18 2.44982624E-03 0.00000000E+00-1.25076565E-03 + 0.00000000E+00 0.00000000E+00-7.65874611E-10 0.00000000E+00 5.72790698E-14 + 2.38422733E-04-6.43839774E-10-2.60052053E-08 5.22547100E-14-1.19931801E-03 + 0.00000000E+00-6.65792532E-04 1.06240324E-18-1.19931801E-03 0.00000000E+00 +-6.65792532E-04 1.06240324E-18 0.00000000E+00 1.72863270E-08 0.00000000E+00 + 1.15294289E-13-5.44303140E-03 1.45637109E-08-5.08236504E-08 1.06250655E-13 + 2.44983550E-03 0.00000000E+00 9.79968469E-03 0.00000000E+00 1.38273908E-03 +-8.41835607E-19 5.53225806E-03-6.10119392E-18 2.44983550E-03 0.00000000E+00 + 9.79968469E-03 0.00000000E+00 1.38273908E-03-8.41835607E-19 5.53225806E-03 +-6.10119392E-18 0.00000000E+00-8.05864746E-10 0.00000000E+00 5.81164074E-14 + 2.56041225E-04-6.80686546E-10-2.48324306E-08 5.40689114E-14 2.44982624E-03 + 0.00000000E+00-1.25076565E-03 0.00000000E+00 1.38273676E-03-5.45447543E-19 +-7.17859768E-04 1.93556653E-18 2.44982624E-03 0.00000000E+00-1.25076565E-03 + 0.00000000E+00 1.38273676E-03-5.45447543E-19-7.17859768E-04 1.93556653E-18 +-3.12224754E-06-1.17698368E-20-1.88219264E-08-7.39356604E-23-7.08644776E-05 + 0.00000000E+00-4.24185784E-07 0.00000000E+00-2.60052053E-08-5.22547100E-14 + 0.00000000E+00-5.72790698E-14-2.60052053E-08-5.22547100E-14 0.00000000E+00 +-5.72790698E-14 5.28230132E-07 1.04488351E-20 5.40923128E-08 2.83842594E-22 +-2.22163385E-06 0.00000000E+00 1.11450188E-06 0.00000000E+00 2.53919163E-05 + 6.81324562E-11-5.08236504E-08-1.06250655E-13 0.00000000E+00 8.09306600E-11 + 0.00000000E+00-1.15294289E-13 2.53919163E-05 6.81324562E-11-5.08236504E-08 +-1.06250655E-13 0.00000000E+00 8.09306600E-11 0.00000000E+00-1.15294289E-13 + 3.65048962E-06 2.09085556E-20-2.17614400E-08-1.26218455E-22 6.86423661E-05 + 0.00000000E+00-4.11819567E-07 0.00000000E+00-2.60019680E-05-6.94081162E-11 +-2.48324306E-08-5.40689114E-14 0.00000000E+00-8.23150473E-11 0.00000000E+00 +-5.81164074E-14-2.60019680E-05-6.94081162E-11-2.48324306E-08-5.40689114E-14 + 0.00000000E+00-8.23150473E-11 0.00000000E+00-5.81164074E-14 5.02368150E-04 + 1.97397660E-18 3.15920268E-06 1.29098602E-20 1.13216876E-02 0.00000000E+00 + 7.06985711E-05 0.00000000E+00 2.49437815E-04 6.65973523E-10 0.00000000E+00 + 7.90136622E-10 2.49437815E-04 6.65973523E-10 0.00000000E+00 7.90136622E-10 + 3.12733081E-03 1.71465606E-17 5.28230132E-07 1.04488351E-20 6.44435088E-02 + 0.00000000E+00-2.22163385E-06 0.00000000E+00-4.89680507E-03-1.31340656E-08 +-5.44303140E-03-1.45637109E-08 0.00000000E+00-1.55996802E-08 0.00000000E+00 +-1.72863270E-08-4.89680507E-03-1.31340656E-08-5.44303140E-03-1.45637109E-08 + 0.00000000E+00-1.55996802E-08 0.00000000E+00-1.72863270E-08 5.80827978E-04 + 3.36050674E-18-3.61197924E-06-2.11421703E-20 1.09916887E-02 0.00000000E+00 +-6.87940846E-05 0.00000000E+00-4.99861328E-03-1.33469582E-08 2.45522789E-04 + 6.57784243E-10 0.00000000E+00-1.58307203E-08 0.00000000E+00 7.81247960E-10 +-4.99861328E-03-1.33469582E-08 2.45522789E-04 6.57784243E-10 0.00000000E+00 +-1.58307203E-08 0.00000000E+00 7.81247960E-10-7.08644776E-05 0.00000000E+00 +-4.24185784E-07 0.00000000E+00-3.12224754E-06 1.17698368E-20-1.88219264E-08 + 7.39356604E-23 0.00000000E+00-5.72790698E-14 2.60052053E-08-5.22547100E-14 + 0.00000000E+00-5.72790698E-14 2.60052053E-08-5.22547100E-14-2.22163385E-06 + 0.00000000E+00 1.11450188E-06 0.00000000E+00 5.28230132E-07-1.04488351E-20 + 5.40923128E-08-2.83842594E-22 0.00000000E+00 8.09306600E-11 0.00000000E+00 +-1.15294289E-13-2.53919163E-05 6.81324562E-11 5.08236504E-08-1.06250655E-13 + 0.00000000E+00 8.09306600E-11 0.00000000E+00-1.15294289E-13-2.53919163E-05 + 6.81324562E-11 5.08236504E-08-1.06250655E-13 6.86423661E-05 0.00000000E+00 +-4.11819567E-07 0.00000000E+00 3.65048962E-06-2.09085556E-20-2.17614400E-08 + 1.26218455E-22 0.00000000E+00-8.23150473E-11 0.00000000E+00-5.81164074E-14 + 2.60019680E-05-6.94081162E-11 2.48324306E-08-5.40689114E-14 0.00000000E+00 +-8.23150473E-11 0.00000000E+00-5.81164074E-14 2.60019680E-05-6.94081162E-11 + 2.48324306E-08-5.40689114E-14 0.00000000E+00 1.55202773E-08 0.00000000E+00 + 8.07015437E-11-4.86075581E-03 1.30616280E-08-2.52878955E-05 6.79234373E-11 + 2.34743654E-03 0.00000000E+00 1.28043105E-03-3.40777737E-18 2.34743654E-03 + 0.00000000E+00 1.28043105E-03-3.40777737E-18 0.00000000E+00 1.55996802E-08 + 0.00000000E+00-8.09306600E-11-4.89680507E-03 1.31340656E-08 2.53919163E-05 +-6.81324562E-11 1.91888049E-02 0.00000000E+00 2.44983550E-03 0.00000000E+00 + 1.06516294E-02-1.57270646E-17 1.38273908E-03-8.41835607E-19 1.91888049E-02 + 0.00000000E+00 2.44983550E-03 0.00000000E+00 1.06516294E-02-1.57270646E-17 + 1.38273908E-03-8.41835607E-19 4.86075581E-03 1.30616280E-08 2.52878955E-05 + 6.79234373E-11 0.00000000E+00 1.55202773E-08 0.00000000E+00 8.07015437E-11 + 1.28043105E-03 3.40777737E-18 2.34743654E-03 0.00000000E+00 1.28043105E-03 + 3.40777737E-18 2.34743654E-03 0.00000000E+00 4.89680507E-03 1.31340656E-08 +-2.53919163E-05-6.81324562E-11 0.00000000E+00 1.55996802E-08 0.00000000E+00 +-8.09306600E-11 1.06516294E-02 1.57270646E-17 1.38273908E-03 8.41835607E-19 + 1.91888049E-02 0.00000000E+00 2.44983550E-03 0.00000000E+00 1.06516294E-02 + 1.57270646E-17 1.38273908E-03 8.41835607E-19 1.91888049E-02 0.00000000E+00 + 2.44983550E-03 0.00000000E+00 0.00000000E+00 1.55202773E-08 0.00000000E+00 + 8.07015437E-11-4.86075581E-03 1.30616280E-08-2.52878955E-05 6.79234373E-11 + 2.34743654E-03 0.00000000E+00 1.28043105E-03-3.40777737E-18 8.68149937E-02 + 0.00000000E+00 3.15265277E-02-1.04649952E-16 0.00000000E+00 1.55996802E-08 + 0.00000000E+00-8.09306600E-11-4.89680507E-03 1.31340656E-08 2.53919163E-05 +-6.81324562E-11 1.91888049E-02 0.00000000E+00 2.44983550E-03 0.00000000E+00 + 1.06516294E-02-1.57270646E-17 1.38273908E-03-8.41835607E-19 6.81633378E-01 + 0.00000000E+00 8.36117581E-02 0.00000000E+00 2.52553530E-01-8.76603235E-16 + 3.16120592E-02-9.47988447E-17 4.71680355E-03 1.27863801E-08 2.45420636E-05 + 6.64909702E-11 0.00000000E+00 1.52145515E-08 0.00000000E+00 7.91124323E-11 + 1.18182214E-03 4.73657903E-18 2.24601660E-03 0.00000000E+00 3.14439758E-02 + 4.53434017E-17 9.02905814E-02 0.00000000E+00 4.75438874E-03 1.28561775E-08 +-2.46505160E-05-6.66923715E-11 0.00000000E+00 1.52927095E-08 0.00000000E+00 +-7.93379576E-11 9.84795882E-03 3.68310046E-17 1.28043311E-03 3.97799735E-18 + 1.83735766E-02 0.00000000E+00 2.34744546E-03 0.00000000E+00 2.51881546E-01 + 3.43811958E-16 3.15266187E-02 6.48723134E-17 7.08334121E-01 0.00000000E+00 + 8.68136933E-02 0.00000000E+00 1.16830136E-02 0.00000000E+00 7.29497447E-05 + 0.00000000E+00 4.27146865E-04-5.19429226E-19 2.68815852E-06-3.25940067E-21 + 0.00000000E+00 7.74629514E-10-2.42513651E-04 6.51742487E-10 0.00000000E+00 + 7.74629514E-10-2.42513651E-04 6.51742487E-10 6.64384788E-02 0.00000000E+00 +-2.43248794E-06 0.00000000E+00 2.68335900E-03-5.84207165E-18 5.06425783E-07 +-1.03302718E-20 0.00000000E+00-1.52927095E-08 0.00000000E+00-1.69467210E-08 + 4.75438874E-03-1.28561775E-08 5.28884979E-03-1.42538984E-08 0.00000000E+00 +-1.52927095E-08 0.00000000E+00-1.69467210E-08 4.75438874E-03-1.28561775E-08 + 5.28884979E-03-1.42538984E-08 1.13216876E-02 0.00000000E+00-7.08644776E-05 + 0.00000000E+00 5.02368150E-04-1.97397660E-18-3.12224754E-06 1.17698368E-20 + 0.00000000E+00-1.55202773E-08 0.00000000E+00 7.65874611E-10 4.86075581E-03 +-1.30616280E-08-2.38422733E-04 6.43839774E-10 0.00000000E+00-1.55202773E-08 + 0.00000000E+00 7.65874611E-10 4.86075581E-03-1.30616280E-08-2.38422733E-04 + 6.43839774E-10-2.31029267E-04-6.30415478E-10 2.71131037E-08 5.03503294E-14 + 0.00000000E+00-7.50747861E-10 0.00000000E+00 5.63813042E-14-6.15563814E-04 +-2.17864410E-18-1.14836552E-03 0.00000000E+00-1.57426486E-02-2.75539288E-17 +-4.42760687E-02 0.00000000E+00 5.28884979E-03 1.42538984E-08 5.30981111E-08 + 1.02537318E-13 0.00000000E+00 1.69467210E-08 0.00000000E+00 1.13563152E-13 + 1.28043311E-03 3.97799735E-18 5.12304886E-03 1.41016270E-17 2.34744546E-03 + 0.00000000E+00 9.39011057E-03 0.00000000E+00 3.15266187E-02 6.48723134E-17 + 1.26107324E-01 3.28536009E-16 8.68136933E-02 0.00000000E+00 3.47355104E-01 + 0.00000000E+00-2.49437815E-04-6.65973523E-10 2.60052053E-08 5.22547100E-14 + 0.00000000E+00-7.90136622E-10 0.00000000E+00 5.72790698E-14 1.28043105E-03 + 3.40777737E-18-6.65792532E-04-1.06240324E-18 2.34743654E-03 0.00000000E+00 +-1.19931801E-03 0.00000000E+00 3.15265277E-02 1.04649952E-16-1.57846467E-02 +-4.98621993E-17 8.68149937E-02 0.00000000E+00-4.26066879E-02 0.00000000E+00 + 0.00000000E+00-7.50747861E-10 0.00000000E+00 5.63813042E-14 2.31029267E-04 +-6.30415478E-10-2.71131037E-08 5.03503294E-14-1.14836552E-03 0.00000000E+00 +-6.15563814E-04 2.17864410E-18-4.42760687E-02 0.00000000E+00-1.57426486E-02 + 2.75539288E-17 0.00000000E+00 1.69467210E-08 0.00000000E+00 1.13563152E-13 +-5.28884979E-03 1.42538984E-08-5.30981111E-08 1.02537318E-13 2.34744546E-03 + 0.00000000E+00 9.39011057E-03 0.00000000E+00 1.28043311E-03-3.97799735E-18 + 5.12304886E-03-1.41016270E-17 8.68136933E-02 0.00000000E+00 3.47355104E-01 + 0.00000000E+00 3.15266187E-02-6.48723134E-17 1.26107324E-01-3.28536009E-16 + 0.00000000E+00-7.90136622E-10 0.00000000E+00 5.72790698E-14 2.49437815E-04 +-6.65973523E-10-2.60052053E-08 5.22547100E-14 2.34743654E-03 0.00000000E+00 +-1.19931801E-03 0.00000000E+00 1.28043105E-03-3.40777737E-18-6.65792532E-04 + 1.06240324E-18 8.68149937E-02 0.00000000E+00-4.26066879E-02 0.00000000E+00 + 3.15265277E-02-1.04649952E-16-1.57846467E-02 4.98621993E-17-2.31029267E-04 +-6.30415478E-10 2.71131037E-08 5.03503294E-14 0.00000000E+00-7.50747861E-10 + 0.00000000E+00 5.63813042E-14-6.15563814E-04-2.17864410E-18-1.14836552E-03 + 0.00000000E+00-6.15563814E-04-2.17864410E-18-1.14836552E-03 0.00000000E+00 + 5.28884979E-03 1.42538984E-08 5.30981111E-08 1.02537318E-13 0.00000000E+00 + 1.69467210E-08 0.00000000E+00 1.13563152E-13 1.28043311E-03 3.97799735E-18 + 5.12304886E-03 1.41016270E-17 2.34744546E-03 0.00000000E+00 9.39011057E-03 + 0.00000000E+00 1.28043311E-03 3.97799735E-18 5.12304886E-03 1.41016270E-17 + 2.34744546E-03 0.00000000E+00 9.39011057E-03 0.00000000E+00-2.49437815E-04 +-6.65973523E-10 2.60052053E-08 5.22547100E-14 0.00000000E+00-7.90136622E-10 + 0.00000000E+00 5.72790698E-14 1.28043105E-03 3.40777737E-18-6.65792532E-04 +-1.06240324E-18 2.34743654E-03 0.00000000E+00-1.19931801E-03 0.00000000E+00 + 1.28043105E-03 3.40777737E-18-6.65792532E-04-1.06240324E-18 2.34743654E-03 + 0.00000000E+00-1.19931801E-03 0.00000000E+00 0.00000000E+00-7.50747861E-10 + 0.00000000E+00 5.63813042E-14 2.31029267E-04-6.30415478E-10-2.71131037E-08 + 5.03503294E-14-1.14836552E-03 0.00000000E+00-6.15563814E-04 2.17864410E-18 +-1.14836552E-03 0.00000000E+00-6.15563814E-04 2.17864410E-18 0.00000000E+00 + 1.69467210E-08 0.00000000E+00 1.13563152E-13-5.28884979E-03 1.42538984E-08 +-5.30981111E-08 1.02537318E-13 2.34744546E-03 0.00000000E+00 9.39011057E-03 + 0.00000000E+00 1.28043311E-03-3.97799735E-18 5.12304886E-03-1.41016270E-17 + 2.34744546E-03 0.00000000E+00 9.39011057E-03 0.00000000E+00 1.28043311E-03 +-3.97799735E-18 5.12304886E-03-1.41016270E-17 0.00000000E+00-7.90136622E-10 + 0.00000000E+00 5.72790698E-14 2.49437815E-04-6.65973523E-10-2.60052053E-08 + 5.22547100E-14 2.34743654E-03 0.00000000E+00-1.19931801E-03 0.00000000E+00 + 1.28043105E-03-3.40777737E-18-6.65792532E-04 1.06240324E-18 2.34743654E-03 + 0.00000000E+00-1.19931801E-03 0.00000000E+00 1.28043105E-03-3.40777737E-18 +-6.65792532E-04 1.06240324E-18-2.65276132E-06-3.21283219E-21-1.60037175E-08 +-1.92415306E-23-7.31316285E-05 0.00000000E+00-4.37725845E-07 0.00000000E+00 +-2.71131037E-08-5.03503294E-14 0.00000000E+00-5.63813042E-14-2.71131037E-08 +-5.03503294E-14 0.00000000E+00-5.63813042E-14 5.06425783E-07 1.03302718E-20 + 4.64153110E-08 1.10767088E-22-2.43248794E-06 0.00000000E+00 1.14902189E-06 + 0.00000000E+00 2.46505160E-05 6.66923715E-11-5.30981111E-08-1.02537318E-13 + 0.00000000E+00 7.93379576E-11 0.00000000E+00-1.13563152E-13 2.46505160E-05 + 6.66923715E-11-5.30981111E-08-1.02537318E-13 0.00000000E+00 7.93379576E-11 + 0.00000000E+00-1.13563152E-13 3.15920268E-06 1.29098602E-20-1.88219264E-08 +-7.39356604E-23 7.06985711E-05 0.00000000E+00-4.24185784E-07 0.00000000E+00 +-2.52878955E-05-6.79234373E-11-2.60052053E-08-5.22547100E-14 0.00000000E+00 +-8.07015437E-11 0.00000000E+00-5.72790698E-14-2.52878955E-05-6.79234373E-11 +-2.60052053E-08-5.22547100E-14 0.00000000E+00-8.07015437E-11 0.00000000E+00 +-5.72790698E-14 4.27146865E-04 5.19429226E-19 2.68815852E-06 3.25940067E-21 + 1.16830136E-02 0.00000000E+00 7.29497447E-05 0.00000000E+00 2.42513651E-04 + 6.51742487E-10 0.00000000E+00 7.74629514E-10 2.42513651E-04 6.51742487E-10 + 0.00000000E+00 7.74629514E-10 2.68335900E-03 5.84207165E-18 5.06425783E-07 + 1.03302718E-20 6.64384788E-02 0.00000000E+00-2.43248794E-06 0.00000000E+00 +-4.75438874E-03-1.28561775E-08-5.28884979E-03-1.42538984E-08 0.00000000E+00 +-1.52927095E-08 0.00000000E+00-1.69467210E-08-4.75438874E-03-1.28561775E-08 +-5.28884979E-03-1.42538984E-08 0.00000000E+00-1.52927095E-08 0.00000000E+00 +-1.69467210E-08 5.02368150E-04 1.97397660E-18-3.12224754E-06-1.17698368E-20 + 1.13216876E-02 0.00000000E+00-7.08644776E-05 0.00000000E+00-4.86075581E-03 +-1.30616280E-08 2.38422733E-04 6.43839774E-10 0.00000000E+00-1.55202773E-08 + 0.00000000E+00 7.65874611E-10-4.86075581E-03-1.30616280E-08 2.38422733E-04 + 6.43839774E-10 0.00000000E+00-1.55202773E-08 0.00000000E+00 7.65874611E-10 +-7.31316285E-05 0.00000000E+00-4.37725845E-07 0.00000000E+00-2.65276132E-06 + 3.21283219E-21-1.60037175E-08 1.92415306E-23 0.00000000E+00-5.63813042E-14 + 2.71131037E-08-5.03503294E-14 0.00000000E+00-5.63813042E-14 2.71131037E-08 +-5.03503294E-14-2.43248794E-06 0.00000000E+00 1.14902189E-06 0.00000000E+00 + 5.06425783E-07-1.03302718E-20 4.64153110E-08-1.10767088E-22 0.00000000E+00 + 7.93379576E-11 0.00000000E+00-1.13563152E-13-2.46505160E-05 6.66923715E-11 + 5.30981111E-08-1.02537318E-13 0.00000000E+00 7.93379576E-11 0.00000000E+00 +-1.13563152E-13-2.46505160E-05 6.66923715E-11 5.30981111E-08-1.02537318E-13 + 7.06985711E-05 0.00000000E+00-4.24185784E-07 0.00000000E+00 3.15920268E-06 +-1.29098602E-20-1.88219264E-08 7.39356604E-23 0.00000000E+00-8.07015437E-11 + 0.00000000E+00-5.72790698E-14 2.52878955E-05-6.79234373E-11 2.60052053E-08 +-5.22547100E-14 0.00000000E+00-8.07015437E-11 0.00000000E+00-5.72790698E-14 + 2.52878955E-05-6.79234373E-11 2.60052053E-08-5.22547100E-14 0.00000000E+00 + 1.52145515E-08 0.00000000E+00 7.91124323E-11-4.71680355E-03 1.27863801E-08 +-2.45420636E-05 6.64909702E-11 2.24601660E-03 0.00000000E+00 1.18182214E-03 +-4.73657903E-18 2.24601660E-03 0.00000000E+00 1.18182214E-03-4.73657903E-18 + 0.00000000E+00 1.52927095E-08 0.00000000E+00-7.93379576E-11-4.75438874E-03 + 1.28561775E-08 2.46505160E-05-6.66923715E-11 1.83735766E-02 0.00000000E+00 + 2.34744546E-03 0.00000000E+00 9.84795882E-03-3.68310046E-17 1.28043311E-03 +-3.97799735E-18 1.83735766E-02 0.00000000E+00 2.34744546E-03 0.00000000E+00 + 9.84795882E-03-3.68310046E-17 1.28043311E-03-3.97799735E-18 4.71680355E-03 + 1.27863801E-08 2.45420636E-05 6.64909702E-11 0.00000000E+00 1.52145515E-08 + 0.00000000E+00 7.91124323E-11 1.18182214E-03 4.73657903E-18 2.24601660E-03 + 0.00000000E+00 1.18182214E-03 4.73657903E-18 2.24601660E-03 0.00000000E+00 + 4.75438874E-03 1.28561775E-08-2.46505160E-05-6.66923715E-11 0.00000000E+00 + 1.52927095E-08 0.00000000E+00-7.93379576E-11 9.84795882E-03 3.68310046E-17 + 1.28043311E-03 3.97799735E-18 1.83735766E-02 0.00000000E+00 2.34744546E-03 + 0.00000000E+00 9.84795882E-03 3.68310046E-17 1.28043311E-03 3.97799735E-18 + 1.83735766E-02 0.00000000E+00 2.34744546E-03 0.00000000E+00 0.00000000E+00 + 1.52145515E-08 0.00000000E+00 7.91124323E-11-4.71680355E-03 1.27863801E-08 +-2.45420636E-05 6.64909702E-11 2.24601660E-03 0.00000000E+00 1.18182214E-03 +-4.73657903E-18 9.02905814E-02 0.00000000E+00 3.14439758E-02-4.53434017E-17 + 0.00000000E+00 1.52927095E-08 0.00000000E+00-7.93379576E-11-4.75438874E-03 + 1.28561775E-08 2.46505160E-05-6.66923715E-11 1.83735766E-02 0.00000000E+00 + 2.34744546E-03 0.00000000E+00 9.84795882E-03-3.68310046E-17 1.28043311E-03 +-3.97799735E-18 7.08334121E-01 0.00000000E+00 8.68136933E-02 0.00000000E+00 + 2.51881546E-01-3.43811958E-16 3.15266187E-02-6.48723134E-17 4.56702803E-03 + 1.25217424E-08 2.37659165E-05 6.51134331E-11 0.00000000E+00 1.49138935E-08 + 0.00000000E+00 7.75495211E-11 1.08694880E-03 1.90613701E-18 2.14552658E-03 + 0.00000000E+00 3.13643641E-02 9.02920365E-17 9.40750979E-02 0.00000000E+00 + 4.60609016E-03 1.25887561E-08-2.38786309E-05-6.53068033E-11 0.00000000E+00 + 1.49907114E-08 0.00000000E+00-7.77711804E-11 9.07401719E-03 2.34019835E-17 + 1.18182383E-03 4.14256900E-18 1.75659463E-02 0.00000000E+00 2.24602511E-03 + 0.00000000E+00 2.51232869E-01 8.54002422E-16 3.14440656E-02 9.47329908E-17 + 7.37362444E-01 0.00000000E+00 9.02890128E-02 0.00000000E+00 1.20796356E-02 + 0.00000000E+00 7.54205759E-05 0.00000000E+00 3.55149452E-04-8.91938128E-19 + 2.23727643E-06-5.74488050E-21 0.00000000E+00 7.59358956E-10-2.35287727E-04 + 6.38016603E-10 0.00000000E+00 7.59358956E-10-2.35287727E-04 6.38016603E-10 + 6.86256096E-02 0.00000000E+00-2.67003179E-06 0.00000000E+00 2.25808368E-03 +-4.37920279E-18 4.84715292E-07 4.37096832E-21 0.00000000E+00-1.49907114E-08 + 0.00000000E+00-1.66124406E-08 4.60609016E-03-1.25887561E-08 5.12809205E-03 +-1.39553818E-08 0.00000000E+00-1.49907114E-08 0.00000000E+00-1.66124406E-08 + 4.60609016E-03-1.25887561E-08 5.12809205E-03-1.39553818E-08 1.16830136E-02 + 0.00000000E+00-7.31316285E-05 0.00000000E+00 4.27146865E-04-5.19429226E-19 +-2.65276132E-06 3.21283219E-21 0.00000000E+00-1.52145515E-08 0.00000000E+00 + 7.50747861E-10 4.71680355E-03-1.27863801E-08-2.31029267E-04 6.30415478E-10 + 0.00000000E+00-1.52145515E-08 0.00000000E+00 7.50747861E-10 4.71680355E-03 +-1.27863801E-08-2.31029267E-04 6.30415478E-10-2.23352058E-04-6.17540149E-10 + 2.81786064E-08 4.83425387E-14 0.00000000E+00-7.35886779E-10 0.00000000E+00 + 5.54148281E-14-5.67193156E-04-1.51217650E-18-1.09788792E-03 0.00000000E+00 +-1.57021074E-02-4.62562568E-17-4.60910277E-02 0.00000000E+00 5.12809205E-03 + 1.39553818E-08 5.52676095E-08 9.86333132E-14 0.00000000E+00 1.66124406E-08 + 0.00000000E+00 1.11705524E-13 1.18182383E-03 4.14256900E-18 4.72862639E-03 + 1.66713089E-17 2.24602511E-03 0.00000000E+00 8.98441580E-03 0.00000000E+00 + 3.14440656E-02 9.47329908E-17 1.25777133E-01 2.85690070E-16 9.02890128E-02 + 0.00000000E+00 3.61269613E-01 0.00000000E+00-2.42513651E-04-6.51742487E-10 + 2.71131037E-08 5.03503294E-14 0.00000000E+00-7.74629514E-10 0.00000000E+00 + 5.63813042E-14 1.18182214E-03 4.73657903E-18-6.15563814E-04-2.17864410E-18 + 2.24601660E-03 0.00000000E+00-1.14836552E-03 0.00000000E+00 3.14439758E-02 + 4.53434017E-17-1.57426486E-02-2.75539288E-17 9.02905814E-02 0.00000000E+00 +-4.42760687E-02 0.00000000E+00 0.00000000E+00-7.35886779E-10 0.00000000E+00 + 5.54148281E-14 2.23352058E-04-6.17540149E-10-2.81786064E-08 4.83425387E-14 +-1.09788792E-03 0.00000000E+00-5.67193156E-04 1.51217650E-18-4.60910277E-02 + 0.00000000E+00-1.57021074E-02 4.62562568E-17 0.00000000E+00 1.66124406E-08 + 0.00000000E+00 1.11705524E-13-5.12809205E-03 1.39553818E-08-5.52676095E-08 + 9.86333132E-14 2.24602511E-03 0.00000000E+00 8.98441580E-03 0.00000000E+00 + 1.18182383E-03-4.14256900E-18 4.72862639E-03-1.66713089E-17 9.02890128E-02 + 0.00000000E+00 3.61269613E-01 0.00000000E+00 3.14440656E-02-9.47329908E-17 + 1.25777133E-01-2.85690070E-16 0.00000000E+00-7.74629514E-10 0.00000000E+00 + 5.63813042E-14 2.42513651E-04-6.51742487E-10-2.71131037E-08 5.03503294E-14 + 2.24601660E-03 0.00000000E+00-1.14836552E-03 0.00000000E+00 1.18182214E-03 +-4.73657903E-18-6.15563814E-04 2.17864410E-18 9.02905814E-02 0.00000000E+00 +-4.42760687E-02 0.00000000E+00 3.14439758E-02-4.53434017E-17-1.57426486E-02 + 2.75539288E-17-2.23352058E-04-6.17540149E-10 2.81786064E-08 4.83425387E-14 + 0.00000000E+00-7.35886779E-10 0.00000000E+00 5.54148281E-14-5.67193156E-04 +-1.51217650E-18-1.09788792E-03 0.00000000E+00-5.67193156E-04-1.51217650E-18 +-1.09788792E-03 0.00000000E+00 5.12809205E-03 1.39553818E-08 5.52676095E-08 + 9.86333132E-14 0.00000000E+00 1.66124406E-08 0.00000000E+00 1.11705524E-13 + 1.18182383E-03 4.14256900E-18 4.72862639E-03 1.66713089E-17 2.24602511E-03 + 0.00000000E+00 8.98441580E-03 0.00000000E+00 1.18182383E-03 4.14256900E-18 + 4.72862639E-03 1.66713089E-17 2.24602511E-03 0.00000000E+00 8.98441580E-03 + 0.00000000E+00-2.42513651E-04-6.51742487E-10 2.71131037E-08 5.03503294E-14 + 0.00000000E+00-7.74629514E-10 0.00000000E+00 5.63813042E-14 1.18182214E-03 + 4.73657903E-18-6.15563814E-04-2.17864410E-18 2.24601660E-03 0.00000000E+00 +-1.14836552E-03 0.00000000E+00 1.18182214E-03 4.73657903E-18-6.15563814E-04 +-2.17864410E-18 2.24601660E-03 0.00000000E+00-1.14836552E-03 0.00000000E+00 + 0.00000000E+00-7.35886779E-10 0.00000000E+00 5.54148281E-14 2.23352058E-04 +-6.17540149E-10-2.81786064E-08 4.83425387E-14-1.09788792E-03 0.00000000E+00 +-5.67193156E-04 1.51217650E-18-1.09788792E-03 0.00000000E+00-5.67193156E-04 + 1.51217650E-18 0.00000000E+00 1.66124406E-08 0.00000000E+00 1.11705524E-13 +-5.12809205E-03 1.39553818E-08-5.52676095E-08 9.86333132E-14 2.24602511E-03 + 0.00000000E+00 8.98441580E-03 0.00000000E+00 1.18182383E-03-4.14256900E-18 + 4.72862639E-03-1.66713089E-17 2.24602511E-03 0.00000000E+00 8.98441580E-03 + 0.00000000E+00 1.18182383E-03-4.14256900E-18 4.72862639E-03-1.66713089E-17 + 0.00000000E+00-7.74629514E-10 0.00000000E+00 5.63813042E-14 2.42513651E-04 +-6.51742487E-10-2.71131037E-08 5.03503294E-14 2.24601660E-03 0.00000000E+00 +-1.14836552E-03 0.00000000E+00 1.18182214E-03-4.73657903E-18-6.15563814E-04 + 2.17864410E-18 2.24601660E-03 0.00000000E+00-1.14836552E-03 0.00000000E+00 + 1.18182214E-03-4.73657903E-18-6.15563814E-04 2.17864410E-18-2.20341842E-06 +-5.43899306E-21-1.33062681E-08-3.37229159E-23-7.56204789E-05 0.00000000E+00 +-4.52588468E-07 0.00000000E+00-2.81786064E-08-4.83425387E-14 0.00000000E+00 +-5.54148281E-14-2.81786064E-08-4.83425387E-14 0.00000000E+00-5.54148281E-14 + 4.84715292E-07-4.37096832E-21 3.90613288E-08 7.37330988E-23-2.67003179E-06 + 0.00000000E+00 1.18686740E-06 0.00000000E+00 2.38786309E-05 6.53068033E-11 +-5.52676095E-08-9.86333132E-14 0.00000000E+00 7.77711804E-11 0.00000000E+00 +-1.11705524E-13 2.38786309E-05 6.53068033E-11-5.52676095E-08-9.86333132E-14 + 0.00000000E+00 7.77711804E-11 0.00000000E+00-1.11705524E-13 2.68815852E-06 + 3.25940067E-21-1.60037175E-08-1.92415306E-23 7.29497447E-05 0.00000000E+00 +-4.37725845E-07 0.00000000E+00-2.45420636E-05-6.64909702E-11-2.71131037E-08 +-5.03503294E-14 0.00000000E+00-7.91124323E-11 0.00000000E+00-5.63813042E-14 +-2.45420636E-05-6.64909702E-11-2.71131037E-08-5.03503294E-14 0.00000000E+00 +-7.91124323E-11 0.00000000E+00-5.63813042E-14 3.55149452E-04 8.91938128E-19 + 2.23727643E-06 5.74488050E-21 1.20796356E-02 0.00000000E+00 7.54205759E-05 + 0.00000000E+00 2.35287727E-04 6.38016603E-10 0.00000000E+00 7.59358956E-10 + 2.35287727E-04 6.38016603E-10 0.00000000E+00 7.59358956E-10 2.25808368E-03 + 4.37920279E-18 4.84715292E-07-4.37096832E-21 6.86256096E-02 0.00000000E+00 +-2.67003179E-06 0.00000000E+00-4.60609016E-03-1.25887561E-08-5.12809205E-03 +-1.39553818E-08 0.00000000E+00-1.49907114E-08 0.00000000E+00-1.66124406E-08 +-4.60609016E-03-1.25887561E-08-5.12809205E-03-1.39553818E-08 0.00000000E+00 +-1.49907114E-08 0.00000000E+00-1.66124406E-08 4.27146865E-04 5.19429226E-19 +-2.65276132E-06-3.21283219E-21 1.16830136E-02 0.00000000E+00-7.31316285E-05 + 0.00000000E+00-4.71680355E-03-1.27863801E-08 2.31029267E-04 6.30415478E-10 + 0.00000000E+00-1.52145515E-08 0.00000000E+00 7.50747861E-10-4.71680355E-03 +-1.27863801E-08 2.31029267E-04 6.30415478E-10 0.00000000E+00-1.52145515E-08 + 0.00000000E+00 7.50747861E-10-7.56204789E-05 0.00000000E+00-4.52588468E-07 + 0.00000000E+00-2.20341842E-06 5.43899306E-21-1.33062681E-08 3.37229159E-23 + 0.00000000E+00-5.54148281E-14 2.81786064E-08-4.83425387E-14 0.00000000E+00 +-5.54148281E-14 2.81786064E-08-4.83425387E-14-2.67003179E-06 0.00000000E+00 + 1.18686740E-06 0.00000000E+00 4.84715292E-07 4.37096832E-21 3.90613288E-08 +-7.37330988E-23 0.00000000E+00 7.77711804E-11 0.00000000E+00-1.11705524E-13 +-2.38786309E-05 6.53068033E-11 5.52676095E-08-9.86333132E-14 0.00000000E+00 + 7.77711804E-11 0.00000000E+00-1.11705524E-13-2.38786309E-05 6.53068033E-11 + 5.52676095E-08-9.86333132E-14 7.29497447E-05 0.00000000E+00-4.37725845E-07 + 0.00000000E+00 2.68815852E-06-3.25940067E-21-1.60037175E-08 1.92415306E-23 + 0.00000000E+00-7.91124323E-11 0.00000000E+00-5.63813042E-14 2.45420636E-05 +-6.64909702E-11 2.71131037E-08-5.03503294E-14 0.00000000E+00-7.91124323E-11 + 0.00000000E+00-5.63813042E-14 2.45420636E-05-6.64909702E-11 2.71131037E-08 +-5.03503294E-14 0.00000000E+00 1.49138935E-08 0.00000000E+00 7.75495211E-11 +-4.56702803E-03 1.25217424E-08-2.37659165E-05 6.51134331E-11 2.14552658E-03 + 0.00000000E+00 1.08694880E-03-1.90613701E-18 2.14552658E-03 0.00000000E+00 + 1.08694880E-03-1.90613701E-18 0.00000000E+00 1.49907114E-08 0.00000000E+00 +-7.77711804E-11-4.60609016E-03 1.25887561E-08 2.38786309E-05-6.53068033E-11 + 1.75659463E-02 0.00000000E+00 2.24602511E-03 0.00000000E+00 9.07401719E-03 +-2.34019835E-17 1.18182383E-03-4.14256900E-18 1.75659463E-02 0.00000000E+00 + 2.24602511E-03 0.00000000E+00 9.07401719E-03-2.34019835E-17 1.18182383E-03 +-4.14256900E-18 4.56702803E-03 1.25217424E-08 2.37659165E-05 6.51134331E-11 + 0.00000000E+00 1.49138935E-08 0.00000000E+00 7.75495211E-11 1.08694880E-03 + 1.90613701E-18 2.14552658E-03 0.00000000E+00 1.08694880E-03 1.90613701E-18 + 2.14552658E-03 0.00000000E+00 4.60609016E-03 1.25887561E-08-2.38786309E-05 +-6.53068033E-11 0.00000000E+00 1.49907114E-08 0.00000000E+00-7.77711804E-11 + 9.07401719E-03 2.34019835E-17 1.18182383E-03 4.14256900E-18 1.75659463E-02 + 0.00000000E+00 2.24602511E-03 0.00000000E+00 9.07401719E-03 2.34019835E-17 + 1.18182383E-03 4.14256900E-18 1.75659463E-02 0.00000000E+00 2.24602511E-03 + 0.00000000E+00 0.00000000E+00 1.49138935E-08 0.00000000E+00 7.75495211E-11 +-4.56702803E-03 1.25217424E-08-2.37659165E-05 6.51134331E-11 2.14552658E-03 + 0.00000000E+00 1.08694880E-03-1.90613701E-18 9.40750979E-02 0.00000000E+00 + 3.13643641E-02-9.02920365E-17 0.00000000E+00 1.49907114E-08 0.00000000E+00 +-7.77711804E-11-4.60609016E-03 1.25887561E-08 2.38786309E-05-6.53068033E-11 + 1.75659463E-02 0.00000000E+00 2.24602511E-03 0.00000000E+00 9.07401719E-03 +-2.34019835E-17 1.18182383E-03-4.14256900E-18 7.37362444E-01 0.00000000E+00 + 9.02890128E-02 0.00000000E+00 2.51232869E-01-8.54002422E-16 3.14440656E-02 +-9.47329908E-17 1.25161774E-02 0.00000000E+00 7.81397790E-05 0.00000000E+00 + 2.86330873E-04 7.03309438E-19 1.80627310E-06 4.22269426E-21 0.00000000E+00 + 7.44342461E-10-2.27770981E-04 6.24822253E-10 0.00000000E+00 7.44342461E-10 +-2.27770981E-04 6.24822253E-10 7.10295563E-02 0.00000000E+00-2.93864895E-06 + 0.00000000E+00 1.85130119E-03-6.44848100E-19 4.63330949E-07-1.29760010E-20 + 0.00000000E+00-1.46940833E-08 0.00000000E+00-1.62838947E-08 4.45212851E-03 +-1.23323976E-08 4.96101603E-03-1.36687762E-08 0.00000000E+00-1.46940833E-08 + 0.00000000E+00-1.62838947E-08 4.45212851E-03-1.23323976E-08 4.96101603E-03 +-1.36687762E-08 1.20796356E-02 0.00000000E+00-7.56204789E-05 0.00000000E+00 + 3.55149452E-04-8.91938128E-19-2.20341842E-06 5.43899306E-21 0.00000000E+00 +-1.49138935E-08 0.00000000E+00 7.35886779E-10 4.56702803E-03-1.25217424E-08 +-2.23352058E-04 6.17540149E-10 0.00000000E+00-1.49138935E-08 0.00000000E+00 + 7.35886779E-10 4.56702803E-03-1.25217424E-08-2.23352058E-04 6.17540149E-10 +-2.15402643E-04-6.05248399E-10 2.92002098E-08 4.62118784E-14 0.00000000E+00 +-7.21314530E-10 0.00000000E+00 5.43662646E-14-5.20699550E-04-1.41675763E-18 +-1.04786517E-03 0.00000000E+00-1.56630516E-02-1.10609084E-17-4.80709288E-02 + 0.00000000E+00 4.96101603E-03 1.36687762E-08 5.73620276E-08 9.45031645E-14 + 0.00000000E+00 1.62838947E-08 0.00000000E+00 1.09696856E-13 1.08695041E-03 + 1.86290511E-18 4.34914589E-03 9.06031726E-18 2.14553501E-03 0.00000000E+00 + 8.58244086E-03 0.00000000E+00 3.13644545E-02 3.95776748E-17 1.25458708E-01 + 2.48569063E-16 9.40732007E-02 0.00000000E+00 3.76422033E-01 0.00000000E+00 +-2.35287727E-04-6.38016603E-10 2.81786064E-08 4.83425387E-14 0.00000000E+00 +-7.59358956E-10 0.00000000E+00 5.54148281E-14 1.08694880E-03 1.90613701E-18 +-5.67193156E-04-1.51217650E-18 2.14552658E-03 0.00000000E+00-1.09788792E-03 + 0.00000000E+00 3.13643641E-02 9.02920365E-17-1.57021074E-02-4.62562568E-17 + 9.40750979E-02 0.00000000E+00-4.60910277E-02 0.00000000E+00 0.00000000E+00 +-7.21314530E-10 0.00000000E+00 5.43662646E-14 2.15402643E-04-6.05248399E-10 +-2.92002098E-08 4.62118784E-14-1.04786517E-03 0.00000000E+00-5.20699550E-04 + 1.41675763E-18-4.80709288E-02 0.00000000E+00-1.56630516E-02 1.10609084E-17 + 0.00000000E+00 1.62838947E-08 0.00000000E+00 1.09696856E-13-4.96101603E-03 + 1.36687762E-08-5.73620276E-08 9.45031645E-14 2.14553501E-03 0.00000000E+00 + 8.58244086E-03 0.00000000E+00 1.08695041E-03-1.86290511E-18 4.34914589E-03 +-9.06031726E-18 9.40732007E-02 0.00000000E+00 3.76422033E-01 0.00000000E+00 + 3.13644545E-02-3.95776748E-17 1.25458708E-01-2.48569063E-16 0.00000000E+00 +-7.59358956E-10 0.00000000E+00 5.54148281E-14 2.35287727E-04-6.38016603E-10 +-2.81786064E-08 4.83425387E-14 2.14552658E-03 0.00000000E+00-1.09788792E-03 + 0.00000000E+00 1.08694880E-03-1.90613701E-18-5.67193156E-04 1.51217650E-18 + 9.40750979E-02 0.00000000E+00-4.60910277E-02 0.00000000E+00 3.13643641E-02 +-9.02920365E-17-1.57021074E-02 4.62562568E-17-2.15402643E-04-6.05248399E-10 + 2.92002098E-08 4.62118784E-14 0.00000000E+00-7.21314530E-10 0.00000000E+00 + 5.43662646E-14-5.20699550E-04-1.41675763E-18-1.04786517E-03 0.00000000E+00 +-5.20699550E-04-1.41675763E-18-1.04786517E-03 0.00000000E+00 4.96101603E-03 + 1.36687762E-08 5.73620276E-08 9.45031645E-14 0.00000000E+00 1.62838947E-08 + 0.00000000E+00 1.09696856E-13 1.08695041E-03 1.86290511E-18 4.34914589E-03 + 9.06031726E-18 2.14553501E-03 0.00000000E+00 8.58244086E-03 0.00000000E+00 + 1.08695041E-03 1.86290511E-18 4.34914589E-03 9.06031726E-18 2.14553501E-03 + 0.00000000E+00 8.58244086E-03 0.00000000E+00-2.35287727E-04-6.38016603E-10 + 2.81786064E-08 4.83425387E-14 0.00000000E+00-7.59358956E-10 0.00000000E+00 + 5.54148281E-14 1.08694880E-03 1.90613701E-18-5.67193156E-04-1.51217650E-18 + 2.14552658E-03 0.00000000E+00-1.09788792E-03 0.00000000E+00 1.08694880E-03 + 1.90613701E-18-5.67193156E-04-1.51217650E-18 2.14552658E-03 0.00000000E+00 +-1.09788792E-03 0.00000000E+00 0.00000000E+00-7.21314530E-10 0.00000000E+00 + 5.43662646E-14 2.15402643E-04-6.05248399E-10-2.92002098E-08 4.62118784E-14 +-1.04786517E-03 0.00000000E+00-5.20699550E-04 1.41675763E-18-1.04786517E-03 + 0.00000000E+00-5.20699550E-04 1.41675763E-18 0.00000000E+00 1.62838947E-08 + 0.00000000E+00 1.09696856E-13-4.96101603E-03 1.36687762E-08-5.73620276E-08 + 9.45031645E-14 2.14553501E-03 0.00000000E+00 8.58244086E-03 0.00000000E+00 + 1.08695041E-03-1.86290511E-18 4.34914589E-03-9.06031726E-18 2.14553501E-03 + 0.00000000E+00 8.58244086E-03 0.00000000E+00 1.08695041E-03-1.86290511E-18 + 4.34914589E-03-9.06031726E-18 0.00000000E+00-7.59358956E-10 0.00000000E+00 + 5.54148281E-14 2.35287727E-04-6.38016603E-10-2.81786064E-08 4.83425387E-14 + 2.14552658E-03 0.00000000E+00-1.09788792E-03 0.00000000E+00 1.08694880E-03 +-1.90613701E-18-5.67193156E-04 1.51217650E-18 2.14552658E-03 0.00000000E+00 +-1.09788792E-03 0.00000000E+00 1.08694880E-03-1.90613701E-18-5.67193156E-04 + 1.51217650E-18-1.77393866E-06 4.60215281E-21-1.07278859E-08 2.66510190E-23 +-7.83601306E-05 0.00000000E+00-4.68946898E-07 0.00000000E+00-2.92002098E-08 +-4.62118784E-14 0.00000000E+00-5.43662646E-14-2.92002098E-08-4.62118784E-14 + 0.00000000E+00-5.43662646E-14 4.63330949E-07 1.29760010E-20 3.20270768E-08 + 1.03705704E-23-2.93864895E-06 0.00000000E+00 1.22846603E-06 0.00000000E+00 + 2.30773953E-05 6.39788789E-11-5.73620276E-08-9.45031645E-14 0.00000000E+00 + 7.62324141E-11 0.00000000E+00-1.09696856E-13 2.30773953E-05 6.39788789E-11 +-5.73620276E-08-9.45031645E-14 0.00000000E+00 7.62324141E-11 0.00000000E+00 +-1.09696856E-13 2.23727643E-06 5.74488050E-21-1.33062681E-08-3.37229159E-23 + 7.54205759E-05 0.00000000E+00-4.52588468E-07 0.00000000E+00-2.37659165E-05 +-6.51134331E-11-2.81786064E-08-4.83425387E-14 0.00000000E+00-7.75495211E-11 + 0.00000000E+00-5.54148281E-14-2.37659165E-05-6.51134331E-11-2.81786064E-08 +-4.83425387E-14 0.00000000E+00-7.75495211E-11 0.00000000E+00-5.54148281E-14 + 2.86330873E-04-7.03309438E-19 1.80627310E-06-4.22269426E-21 1.25161774E-02 + 0.00000000E+00 7.81397790E-05 0.00000000E+00 2.27770981E-04 6.24822253E-10 + 0.00000000E+00 7.44342461E-10 2.27770981E-04 6.24822253E-10 0.00000000E+00 + 7.44342461E-10 1.85130119E-03 6.44848100E-19 4.63330949E-07 1.29760010E-20 + 7.10295563E-02 0.00000000E+00-2.93864895E-06 0.00000000E+00-4.45212851E-03 +-1.23323976E-08-4.96101603E-03-1.36687762E-08 0.00000000E+00-1.46940833E-08 + 0.00000000E+00-1.62838947E-08-4.45212851E-03-1.23323976E-08-4.96101603E-03 +-1.36687762E-08 0.00000000E+00-1.46940833E-08 0.00000000E+00-1.62838947E-08 + 3.55149452E-04 8.91938128E-19-2.20341842E-06-5.43899306E-21 1.20796356E-02 + 0.00000000E+00-7.56204789E-05 0.00000000E+00-4.56702803E-03-1.25217424E-08 + 2.23352058E-04 6.17540149E-10 0.00000000E+00-1.49138935E-08 0.00000000E+00 + 7.35886779E-10-4.56702803E-03-1.25217424E-08 2.23352058E-04 6.17540149E-10 + 0.00000000E+00-1.49138935E-08 0.00000000E+00 7.35886779E-10-7.83601306E-05 + 0.00000000E+00-4.68946898E-07 0.00000000E+00-1.77393866E-06-4.60215281E-21 +-1.07278859E-08-2.66510190E-23 0.00000000E+00-5.43662646E-14 2.92002098E-08 +-4.62118784E-14 0.00000000E+00-5.43662646E-14 2.92002098E-08-4.62118784E-14 +-2.93864895E-06 0.00000000E+00 1.22846603E-06 0.00000000E+00 4.63330949E-07 +-1.29760010E-20 3.20270768E-08-1.03705704E-23 0.00000000E+00 7.62324141E-11 + 0.00000000E+00-1.09696856E-13-2.30773953E-05 6.39788789E-11 5.73620276E-08 +-9.45031645E-14 0.00000000E+00 7.62324141E-11 0.00000000E+00-1.09696856E-13 +-2.30773953E-05 6.39788789E-11 5.73620276E-08-9.45031645E-14 7.54205759E-05 + 0.00000000E+00-4.52588468E-07 0.00000000E+00 2.23727643E-06-5.74488050E-21 +-1.33062681E-08 3.37229159E-23 0.00000000E+00-7.75495211E-11 0.00000000E+00 +-5.54148281E-14 2.37659165E-05-6.51134331E-11 2.81786064E-08-4.83425387E-14 + 0.00000000E+00-7.75495211E-11 0.00000000E+00-5.54148281E-14 2.37659165E-05 +-6.51134331E-11 2.81786064E-08-4.83425387E-14 4.41165039E-03 1.22683379E-08 + 2.29605944E-05 6.37940314E-11 0.00000000E+00 1.46187193E-08 0.00000000E+00 + 7.60149490E-11 9.95847790E-04 3.80412543E-18 2.04592565E-03 0.00000000E+00 + 3.12877521E-02 4.66595877E-18 9.82105147E-02 0.00000000E+00 4.45212851E-03 + 1.23323976E-08-2.30773953E-05-6.39788789E-11 0.00000000E+00 1.46940833E-08 + 0.00000000E+00-7.62324141E-11 8.33010976E-03 2.15738525E-17 1.08695041E-03 + 1.86290511E-18 1.67655945E-02 0.00000000E+00 2.14553501E-03 0.00000000E+00 + 2.50607962E-01 7.04733661E-17 3.13644545E-02 3.95776748E-17 7.69027795E-01 + 0.00000000E+00 9.40732007E-02 0.00000000E+00 0.00000000E+00 1.46187193E-08 + 0.00000000E+00 7.60149490E-11-4.41165039E-03 1.22683379E-08-2.29605944E-05 + 6.37940314E-11 2.04592565E-03 0.00000000E+00 9.95847790E-04-3.80412543E-18 + 2.04592565E-03 0.00000000E+00 9.95847790E-04-3.80412543E-18 0.00000000E+00 + 1.46940833E-08 0.00000000E+00-7.62324141E-11-4.45212851E-03 1.23323976E-08 + 2.30773953E-05-6.39788789E-11 1.67655945E-02 0.00000000E+00 2.14553501E-03 + 0.00000000E+00 8.33010976E-03-2.15738525E-17 1.08695041E-03-1.86290511E-18 + 1.67655945E-02 0.00000000E+00 2.14553501E-03 0.00000000E+00 8.33010976E-03 +-2.15738525E-17 1.08695041E-03-1.86290511E-18 4.41165039E-03 1.22683379E-08 + 2.29605944E-05 6.37940314E-11 0.00000000E+00 1.46187193E-08 0.00000000E+00 + 7.60149490E-11 9.95847790E-04 3.80412543E-18 2.04592565E-03 0.00000000E+00 + 9.95847790E-04 3.80412543E-18 2.04592565E-03 0.00000000E+00 4.45212851E-03 + 1.23323976E-08-2.30773953E-05-6.39788789E-11 0.00000000E+00 1.46940833E-08 + 0.00000000E+00-7.62324141E-11 8.33010976E-03 2.15738525E-17 1.08695041E-03 + 1.86290511E-18 1.67655945E-02 0.00000000E+00 2.14553501E-03 0.00000000E+00 + 8.33010976E-03 2.15738525E-17 1.08695041E-03 1.86290511E-18 1.67655945E-02 + 0.00000000E+00 2.14553501E-03 0.00000000E+00 0.00000000E+00 1.46187193E-08 + 0.00000000E+00 7.60149490E-11-4.41165039E-03 1.22683379E-08-2.29605944E-05 + 6.37940314E-11 2.04592565E-03 0.00000000E+00 9.95847790E-04-3.80412543E-18 + 9.82105147E-02 0.00000000E+00 3.12877521E-02-4.66595877E-18 0.00000000E+00 + 1.46940833E-08 0.00000000E+00-7.62324141E-11-4.45212851E-03 1.23323976E-08 + 2.30773953E-05-6.39788789E-11 1.67655945E-02 0.00000000E+00 2.14553501E-03 + 0.00000000E+00 8.33010976E-03-2.15738525E-17 1.08695041E-03-1.86290511E-18 + 7.69027795E-01 0.00000000E+00 9.40732007E-02 0.00000000E+00 2.50607962E-01 +-7.04733661E-17 3.13644545E-02-3.95776748E-17 1.29981872E-02 0.00000000E+00 + 8.11418015E-05 0.00000000E+00 2.20677511E-04 2.22842284E-19 1.39505857E-06 + 1.51864099E-21 0.00000000E+00 7.29600947E-10-2.19974859E-04 6.12190746E-10 + 0.00000000E+00 7.29600947E-10-2.19974859E-04 6.12190746E-10 7.36795879E-02 + 0.00000000E+00-3.24461298E-06 0.00000000E+00 1.46283271E-03 3.45021393E-18 + 4.42018187E-07 4.76749403E-21 0.00000000E+00-1.44032962E-08 0.00000000E+00 +-1.59615704E-08 4.29276622E-03-1.20878074E-08 4.78788415E-03-1.33948108E-08 + 0.00000000E+00-1.44032962E-08 0.00000000E+00-1.59615704E-08 4.29276622E-03 +-1.20878074E-08 4.78788415E-03-1.33948108E-08 1.25161774E-02 0.00000000E+00 +-7.83601306E-05 0.00000000E+00 2.86330873E-04 7.03309438E-19-1.77393866E-06 +-4.60215281E-21 0.00000000E+00-1.46187193E-08 0.00000000E+00 7.21314530E-10 + 4.41165039E-03-1.22683379E-08-2.15402643E-04 6.05248399E-10 0.00000000E+00 +-1.46187193E-08 0.00000000E+00 7.21314530E-10 4.41165039E-03-1.22683379E-08 +-2.15402643E-04 6.05248399E-10 4.25094497E-03 1.20269034E-08 2.21275126E-05 + 6.25365547E-11 0.00000000E+00 1.43295207E-08 0.00000000E+00 7.45112456E-11 + 9.08553320E-04 5.74139386E-18 1.94717265E-03 0.00000000E+00 3.12141924E-02 + 1.26192557E-16 1.02746784E-01 0.00000000E+00 4.29276622E-03 1.20878074E-08 +-2.22481889E-05-6.27122977E-11 0.00000000E+00 1.44032962E-08 0.00000000E+00 +-7.47241280E-11 7.61651613E-03 4.13241572E-17 9.95848971E-04 4.26554444E-18 + 1.59721872E-02 0.00000000E+00 2.04593346E-03 0.00000000E+00 2.50007257E-01 + 6.97128680E-16 3.12878419E-02 3.75651676E-17 8.03697274E-01 0.00000000E+00 + 9.82082056E-02 0.00000000E+00 0.00000000E+00 1.43295207E-08 0.00000000E+00 + 7.45112456E-11-4.25094497E-03 1.20269034E-08-2.21275126E-05 6.25365547E-11 + 1.94717265E-03 0.00000000E+00 9.08553320E-04-5.74139386E-18 1.94717265E-03 + 0.00000000E+00 9.08553320E-04-5.74139386E-18 0.00000000E+00 1.44032962E-08 + 0.00000000E+00-7.47241280E-11-4.29276622E-03 1.20878074E-08 2.22481889E-05 +-6.27122977E-11 1.59721872E-02 0.00000000E+00 2.04593346E-03 0.00000000E+00 + 7.61651613E-03-4.13241572E-17 9.95848971E-04-4.26554444E-18 1.59721872E-02 + 0.00000000E+00 2.04593346E-03 0.00000000E+00 7.61651613E-03-4.13241572E-17 + 9.95848971E-04-4.26554444E-18 4.25094497E-03 1.20269034E-08 2.21275126E-05 + 6.25365547E-11 0.00000000E+00 1.43295207E-08 0.00000000E+00 7.45112456E-11 + 9.08553320E-04 5.74139386E-18 1.94717265E-03 0.00000000E+00 9.08553320E-04 + 5.74139386E-18 1.94717265E-03 0.00000000E+00 4.29276622E-03 1.20878074E-08 +-2.22481889E-05-6.27122977E-11 0.00000000E+00 1.44032962E-08 0.00000000E+00 +-7.47241280E-11 7.61651613E-03 4.13241572E-17 9.95848971E-04 4.26554444E-18 + 1.59721872E-02 0.00000000E+00 2.04593346E-03 0.00000000E+00 7.61651613E-03 + 4.13241572E-17 9.95848971E-04 4.26554444E-18 1.59721872E-02 0.00000000E+00 + 2.04593346E-03 0.00000000E+00 0.00000000E+00 1.43295207E-08 0.00000000E+00 + 7.45112456E-11-4.25094497E-03 1.20269034E-08-2.21275126E-05 6.25365547E-11 + 1.94717265E-03 0.00000000E+00 9.08553320E-04-5.74139386E-18 1.02746784E-01 + 0.00000000E+00 3.12141924E-02-1.26192557E-16 0.00000000E+00 1.44032962E-08 + 0.00000000E+00-7.47241280E-11-4.29276622E-03 1.20878074E-08 2.22481889E-05 +-6.27122977E-11 1.59721872E-02 0.00000000E+00 2.04593346E-03 0.00000000E+00 + 7.61651613E-03-4.13241572E-17 9.95848971E-04-4.26554444E-18 8.03697274E-01 + 0.00000000E+00 9.82082056E-02 0.00000000E+00 2.50007257E-01-6.97128680E-16 + 3.12878419E-02-3.75651676E-17-2.07196130E-04-5.93581114E-10 3.01690769E-08 + 4.39357560E-14 0.00000000E+00-7.07058392E-10 0.00000000E+00 5.32206124E-14 +-4.76100573E-04-2.50173457E-18-9.98276528E-04 0.00000000E+00-1.56255086E-02 +-4.09394313E-17-5.02387473E-02 0.00000000E+00 4.78788415E-03 1.33948108E-08 + 5.93527872E-08 9.01065735E-14 0.00000000E+00 1.59615704E-08 0.00000000E+00 + 1.07510426E-13 9.95848971E-04 4.26554444E-18 3.98475333E-03 1.59708701E-17 + 2.04593346E-03 0.00000000E+00 8.18402138E-03 0.00000000E+00 3.12878419E-02 + 3.75651676E-17 1.25152278E-01 1.29328808E-16 9.82082056E-02 0.00000000E+00 + 3.92980746E-01 0.00000000E+00-2.27770981E-04-6.24822253E-10 2.92002098E-08 + 4.62118784E-14 0.00000000E+00-7.44342461E-10 0.00000000E+00 5.43662646E-14 + 9.95847790E-04 3.80412543E-18-5.20699550E-04-1.41675763E-18 2.04592565E-03 + 0.00000000E+00-1.04786517E-03 0.00000000E+00 3.12877521E-02 4.66595877E-18 +-1.56630516E-02-1.10609084E-17 9.82105147E-02 0.00000000E+00-4.80709288E-02 + 0.00000000E+00 0.00000000E+00-7.07058392E-10 0.00000000E+00 5.32206124E-14 + 2.07196130E-04-5.93581114E-10-3.01690769E-08 4.39357560E-14-9.98276528E-04 + 0.00000000E+00-4.76100573E-04 2.50173457E-18-5.02387473E-02 0.00000000E+00 +-1.56255086E-02 4.09394313E-17 0.00000000E+00 1.59615704E-08 0.00000000E+00 + 1.07510426E-13-4.78788415E-03 1.33948108E-08-5.93527872E-08 9.01065735E-14 + 2.04593346E-03 0.00000000E+00 8.18402138E-03 0.00000000E+00 9.95848971E-04 +-4.26554444E-18 3.98475333E-03-1.59708701E-17 9.82082056E-02 0.00000000E+00 + 3.92980746E-01 0.00000000E+00 3.12878419E-02-3.75651676E-17 1.25152278E-01 +-1.29328808E-16 0.00000000E+00-7.44342461E-10 0.00000000E+00 5.43662646E-14 + 2.27770981E-04-6.24822253E-10-2.92002098E-08 4.62118784E-14 2.04592565E-03 + 0.00000000E+00-1.04786517E-03 0.00000000E+00 9.95847790E-04-3.80412543E-18 +-5.20699550E-04 1.41675763E-18 9.82105147E-02 0.00000000E+00-4.80709288E-02 + 0.00000000E+00 3.12877521E-02-4.66595877E-18-1.56630516E-02 1.10609084E-17 +-2.07196130E-04-5.93581114E-10 3.01690769E-08 4.39357560E-14 0.00000000E+00 +-7.07058392E-10 0.00000000E+00 5.32206124E-14-4.76100573E-04-2.50173457E-18 +-9.98276528E-04 0.00000000E+00-4.76100573E-04-2.50173457E-18-9.98276528E-04 + 0.00000000E+00 4.78788415E-03 1.33948108E-08 5.93527872E-08 9.01065735E-14 + 0.00000000E+00 1.59615704E-08 0.00000000E+00 1.07510426E-13 9.95848971E-04 + 4.26554444E-18 3.98475333E-03 1.59708701E-17 2.04593346E-03 0.00000000E+00 + 8.18402138E-03 0.00000000E+00 9.95848971E-04 4.26554444E-18 3.98475333E-03 + 1.59708701E-17 2.04593346E-03 0.00000000E+00 8.18402138E-03 0.00000000E+00 +-2.27770981E-04-6.24822253E-10 2.92002098E-08 4.62118784E-14 0.00000000E+00 +-7.44342461E-10 0.00000000E+00 5.43662646E-14 9.95847790E-04 3.80412543E-18 +-5.20699550E-04-1.41675763E-18 2.04592565E-03 0.00000000E+00-1.04786517E-03 + 0.00000000E+00 9.95847790E-04 3.80412543E-18-5.20699550E-04-1.41675763E-18 + 2.04592565E-03 0.00000000E+00-1.04786517E-03 0.00000000E+00 0.00000000E+00 +-7.07058392E-10 0.00000000E+00 5.32206124E-14 2.07196130E-04-5.93581114E-10 +-3.01690769E-08 4.39357560E-14-9.98276528E-04 0.00000000E+00-4.76100573E-04 + 2.50173457E-18-9.98276528E-04 0.00000000E+00-4.76100573E-04 2.50173457E-18 + 0.00000000E+00 1.59615704E-08 0.00000000E+00 1.07510426E-13-4.78788415E-03 + 1.33948108E-08-5.93527872E-08 9.01065735E-14 2.04593346E-03 0.00000000E+00 + 8.18402138E-03 0.00000000E+00 9.95848971E-04-4.26554444E-18 3.98475333E-03 +-1.59708701E-17 2.04593346E-03 0.00000000E+00 8.18402138E-03 0.00000000E+00 + 9.95848971E-04-4.26554444E-18 3.98475333E-03-1.59708701E-17 0.00000000E+00 +-7.44342461E-10 0.00000000E+00 5.43662646E-14 2.27770981E-04-6.24822253E-10 +-2.92002098E-08 4.62118784E-14 2.04592565E-03 0.00000000E+00-1.04786517E-03 + 0.00000000E+00 9.95847790E-04-3.80412543E-18-5.20699550E-04 1.41675763E-18 + 2.04592565E-03 0.00000000E+00-1.04786517E-03 0.00000000E+00 9.95847790E-04 +-3.80412543E-18-5.20699550E-04 1.41675763E-18-1.36424265E-06 1.25717766E-21 +-8.26806837E-09 8.24642932E-24-8.13855135E-05 0.00000000E+00-4.87009031E-07 + 0.00000000E+00-3.01690769E-08-4.39357560E-14 0.00000000E+00-5.32206124E-14 +-3.01690769E-08-4.39357560E-14 0.00000000E+00-5.32206124E-14 4.42018187E-07 +-4.76749403E-21 2.53095368E-08-5.42617630E-23-3.24461298E-06 0.00000000E+00 + 1.27432483E-06 0.00000000E+00 2.22481889E-05 6.27122977E-11-5.93527872E-08 +-9.01065735E-14 0.00000000E+00 7.47241280E-11 0.00000000E+00-1.07510426E-13 + 2.22481889E-05 6.27122977E-11-5.93527872E-08-9.01065735E-14 0.00000000E+00 + 7.47241280E-11 0.00000000E+00-1.07510426E-13 1.80627310E-06-4.22269426E-21 +-1.07278859E-08 2.66510190E-23 7.81397790E-05 0.00000000E+00-4.68946898E-07 + 0.00000000E+00-2.29605944E-05-6.37940314E-11-2.92002098E-08-4.62118784E-14 + 0.00000000E+00-7.60149490E-11 0.00000000E+00-5.43662646E-14-2.29605944E-05 +-6.37940314E-11-2.92002098E-08-4.62118784E-14 0.00000000E+00-7.60149490E-11 + 0.00000000E+00-5.43662646E-14 2.20677511E-04-2.22842284E-19 1.39505857E-06 +-1.51864099E-21 1.29981872E-02 0.00000000E+00 8.11418015E-05 0.00000000E+00 + 2.19974859E-04 6.12190746E-10 0.00000000E+00 7.29600947E-10 2.19974859E-04 + 6.12190746E-10 0.00000000E+00 7.29600947E-10 1.46283271E-03-3.45021393E-18 + 4.42018187E-07-4.76749403E-21 7.36795879E-02 0.00000000E+00-3.24461298E-06 + 0.00000000E+00-4.29276622E-03-1.20878074E-08-4.78788415E-03-1.33948108E-08 + 0.00000000E+00-1.44032962E-08 0.00000000E+00-1.59615704E-08-4.29276622E-03 +-1.20878074E-08-4.78788415E-03-1.33948108E-08 0.00000000E+00-1.44032962E-08 + 0.00000000E+00-1.59615704E-08 2.86330873E-04-7.03309438E-19-1.77393866E-06 + 4.60215281E-21 1.25161774E-02 0.00000000E+00-7.83601306E-05 0.00000000E+00 +-4.41165039E-03-1.22683379E-08 2.15402643E-04 6.05248399E-10 0.00000000E+00 +-1.46187193E-08 0.00000000E+00 7.21314530E-10-4.41165039E-03-1.22683379E-08 + 2.15402643E-04 6.05248399E-10 0.00000000E+00-1.46187193E-08 0.00000000E+00 + 7.21314530E-10-8.13855135E-05 0.00000000E+00-4.87009031E-07 0.00000000E+00 +-1.36424265E-06-1.25717766E-21-8.26806837E-09-8.24642932E-24 0.00000000E+00 +-5.32206124E-14 3.01690769E-08-4.39357560E-14 0.00000000E+00-5.32206124E-14 + 3.01690769E-08-4.39357560E-14-3.24461298E-06 0.00000000E+00 1.27432483E-06 + 0.00000000E+00 4.42018187E-07 4.76749403E-21 2.53095368E-08 5.42617630E-23 + 0.00000000E+00 7.47241280E-11 0.00000000E+00-1.07510426E-13-2.22481889E-05 + 6.27122977E-11 5.93527872E-08-9.01065735E-14 0.00000000E+00 7.47241280E-11 + 0.00000000E+00-1.07510426E-13-2.22481889E-05 6.27122977E-11 5.93527872E-08 +-9.01065735E-14 7.81397790E-05 0.00000000E+00-4.68946898E-07 0.00000000E+00 + 1.80627310E-06 4.22269426E-21-1.07278859E-08-2.66510190E-23 0.00000000E+00 +-7.60149490E-11 0.00000000E+00-5.43662646E-14 2.29605944E-05-6.37940314E-11 + 2.92002098E-08-4.62118784E-14 0.00000000E+00-7.60149490E-11 0.00000000E+00 +-5.43662646E-14 2.29605944E-05-6.37940314E-11 2.92002098E-08-4.62118784E-14 + 4.08515012E-03 1.17983182E-08 2.12679336E-05 6.13455240E-11 0.00000000E+00 + 1.40468853E-08 0.00000000E+00 7.30414309E-11 8.25099295E-04 2.13808026E-18 + 1.84922867E-03 0.00000000E+00 3.11437367E-02 7.90831089E-17 1.07743833E-01 + 0.00000000E+00 4.12826266E-03 1.18558249E-08-2.13923373E-05-6.15114654E-11 + 0.00000000E+00 1.41189107E-08 0.00000000E+00-7.32492647E-11 6.93351243E-03 + 3.23746447E-17 9.08554351E-04 5.73751484E-18 1.51854102E-02 0.00000000E+00 + 1.94718030E-03 0.00000000E+00 2.49431184E-01 8.23739222E-16 3.12142826E-02 + 1.21747515E-16 8.41809663E-01 0.00000000E+00 1.02743957E-01 0.00000000E+00 + 1.35322671E-02 0.00000000E+00 8.44676488E-05 0.00000000E+00 1.58166401E-04 +-1.38437490E-19 1.00349453E-06-6.84029931E-22 0.00000000E+00 7.15159044E-10 +-2.11914964E-04 6.00159004E-10 0.00000000E+00 7.15159044E-10-2.11914964E-04 + 6.00159004E-10 7.66107330E-02 0.00000000E+00-3.59498918E-06 0.00000000E+00 + 1.09259860E-03 3.99518305E-19 4.20864329E-07 1.70102969E-21 0.00000000E+00 +-1.41189107E-08 0.00000000E+00-1.56460445E-08 4.12826266E-03-1.18558249E-08 + 4.60900226E-03-1.31343496E-08 0.00000000E+00-1.41189107E-08 0.00000000E+00 +-1.56460445E-08 4.12826266E-03-1.18558249E-08 4.60900226E-03-1.31343496E-08 + 1.29981872E-02 0.00000000E+00-8.13855135E-05 0.00000000E+00 2.20677511E-04 + 2.22842284E-19-1.36424265E-06-1.25717766E-21 0.00000000E+00-1.43295207E-08 + 0.00000000E+00 7.07058392E-10 4.25094497E-03-1.20269034E-08-2.07196130E-04 + 5.93581114E-10 0.00000000E+00-1.43295207E-08 0.00000000E+00 7.07058392E-10 + 4.25094497E-03-1.20269034E-08-2.07196130E-04 5.93581114E-10-1.98741655E-04 +-5.82587417E-10 3.11009177E-08 4.14853645E-14 0.00000000E+00-6.93151216E-10 + 0.00000000E+00 5.19584639E-14-4.33413411E-04-1.96889877E-18-9.49102242E-04 + 0.00000000E+00-1.55895048E-02-5.02076560E-17-5.26219474E-02 0.00000000E+00 + 4.60900226E-03 1.31343496E-08 6.12475543E-08 8.53921978E-14 0.00000000E+00 + 1.56460445E-08 0.00000000E+00 1.05111746E-13 9.08554351E-04 5.73751484E-18 + 3.63558713E-03 2.11199572E-17 1.94718030E-03 0.00000000E+00 7.78899499E-03 + 0.00000000E+00 3.12142826E-02 1.21747515E-16 1.24858058E-01 4.48277839E-16 + 1.02743957E-01 0.00000000E+00 4.11146227E-01 0.00000000E+00-2.19974859E-04 +-6.12190746E-10 3.01690769E-08 4.39357560E-14 0.00000000E+00-7.29600947E-10 + 0.00000000E+00 5.32206124E-14 9.08553320E-04 5.74139386E-18-4.76100573E-04 +-2.50173457E-18 1.94717265E-03 0.00000000E+00-9.98276528E-04 0.00000000E+00 + 3.12141924E-02 1.26192557E-16-1.56255086E-02-4.09394313E-17 1.02746784E-01 + 0.00000000E+00-5.02387473E-02 0.00000000E+00 0.00000000E+00-6.93151216E-10 + 0.00000000E+00 5.19584639E-14 1.98741655E-04-5.82587417E-10-3.11009177E-08 + 4.14853645E-14-9.49102242E-04 0.00000000E+00-4.33413411E-04 1.96889877E-18 +-5.26219474E-02 0.00000000E+00-1.55895048E-02 5.02076560E-17 0.00000000E+00 + 1.56460445E-08 0.00000000E+00 1.05111746E-13-4.60900226E-03 1.31343496E-08 +-6.12475543E-08 8.53921978E-14 1.94718030E-03 0.00000000E+00 7.78899499E-03 + 0.00000000E+00 9.08554351E-04-5.73751484E-18 3.63558713E-03-2.11199572E-17 + 1.02743957E-01 0.00000000E+00 4.11146227E-01 0.00000000E+00 3.12142826E-02 +-1.21747515E-16 1.24858058E-01-4.48277839E-16 0.00000000E+00-7.29600947E-10 + 0.00000000E+00 5.32206124E-14 2.19974859E-04-6.12190746E-10-3.01690769E-08 + 4.39357560E-14 1.94717265E-03 0.00000000E+00-9.98276528E-04 0.00000000E+00 + 9.08553320E-04-5.74139386E-18-4.76100573E-04 2.50173457E-18 1.02746784E-01 + 0.00000000E+00-5.02387473E-02 0.00000000E+00 3.12141924E-02-1.26192557E-16 +-1.56255086E-02 4.09394313E-17-1.98741655E-04-5.82587417E-10 3.11009177E-08 + 4.14853645E-14 0.00000000E+00-6.93151216E-10 0.00000000E+00 5.19584639E-14 +-4.33413411E-04-1.96889877E-18-9.49102242E-04 0.00000000E+00-4.33413411E-04 +-1.96889877E-18-9.49102242E-04 0.00000000E+00 4.60900226E-03 1.31343496E-08 + 6.12475543E-08 8.53921978E-14 0.00000000E+00 1.56460445E-08 0.00000000E+00 + 1.05111746E-13 9.08554351E-04 5.73751484E-18 3.63558713E-03 2.11199572E-17 + 1.94718030E-03 0.00000000E+00 7.78899499E-03 0.00000000E+00 9.08554351E-04 + 5.73751484E-18 3.63558713E-03 2.11199572E-17 1.94718030E-03 0.00000000E+00 + 7.78899499E-03 0.00000000E+00-2.19974859E-04-6.12190746E-10 3.01690769E-08 + 4.39357560E-14 0.00000000E+00-7.29600947E-10 0.00000000E+00 5.32206124E-14 + 9.08553320E-04 5.74139386E-18-4.76100573E-04-2.50173457E-18 1.94717265E-03 + 0.00000000E+00-9.98276528E-04 0.00000000E+00 9.08553320E-04 5.74139386E-18 +-4.76100573E-04-2.50173457E-18 1.94717265E-03 0.00000000E+00-9.98276528E-04 + 0.00000000E+00 0.00000000E+00-6.93151216E-10 0.00000000E+00 5.19584639E-14 + 1.98741655E-04-5.82587417E-10-3.11009177E-08 4.14853645E-14-9.49102242E-04 + 0.00000000E+00-4.33413411E-04 1.96889877E-18-9.49102242E-04 0.00000000E+00 +-4.33413411E-04 1.96889877E-18 0.00000000E+00 1.56460445E-08 0.00000000E+00 + 1.05111746E-13-4.60900226E-03 1.31343496E-08-6.12475543E-08 8.53921978E-14 + 1.94718030E-03 0.00000000E+00 7.78899499E-03 0.00000000E+00 9.08554351E-04 +-5.73751484E-18 3.63558713E-03-2.11199572E-17 1.94718030E-03 0.00000000E+00 + 7.78899499E-03 0.00000000E+00 9.08554351E-04-5.73751484E-18 3.63558713E-03 +-2.11199572E-17 0.00000000E+00-7.29600947E-10 0.00000000E+00 5.32206124E-14 + 2.19974859E-04-6.12190746E-10-3.01690769E-08 4.39357560E-14 1.94717265E-03 + 0.00000000E+00-9.98276528E-04 0.00000000E+00 9.08553320E-04-5.74139386E-18 +-4.76100573E-04 2.50173457E-18 1.94717265E-03 0.00000000E+00-9.98276528E-04 + 0.00000000E+00 9.08553320E-04-5.74139386E-18-4.76100573E-04 2.50173457E-18 +-9.74181797E-07-1.04121684E-21-5.92595622E-09-5.13084454E-24-8.47381769E-05 + 0.00000000E+00-5.07022245E-07 0.00000000E+00-3.11009177E-08-4.14853645E-14 + 0.00000000E+00-5.19584639E-14-3.11009177E-08-4.14853645E-14 0.00000000E+00 +-5.19584639E-14 4.20864329E-07-1.70102969E-21 1.89071502E-08-5.53760052E-24 +-3.59498918E-06 0.00000000E+00 1.32505010E-06 0.00000000E+00 2.13923373E-05 + 6.15114654E-11-6.12475543E-08-8.53921978E-14 0.00000000E+00 7.32492647E-11 + 0.00000000E+00-1.05111746E-13 2.13923373E-05 6.15114654E-11-6.12475543E-08 +-8.53921978E-14 0.00000000E+00 7.32492647E-11 0.00000000E+00-1.05111746E-13 + 1.39505857E-06-1.51864099E-21-8.26806837E-09 8.24642932E-24 8.11418015E-05 + 0.00000000E+00-4.87009031E-07 0.00000000E+00-2.21275126E-05-6.25365547E-11 +-3.01690769E-08-4.39357560E-14 0.00000000E+00-7.45112456E-11 0.00000000E+00 +-5.32206124E-14-2.21275126E-05-6.25365547E-11-3.01690769E-08-4.39357560E-14 + 0.00000000E+00-7.45112456E-11 0.00000000E+00-5.32206124E-14 1.58166401E-04 + 1.38437490E-19 1.00349453E-06 6.84029931E-22 1.35322671E-02 0.00000000E+00 + 8.44676488E-05 0.00000000E+00 2.11914964E-04 6.00159004E-10 0.00000000E+00 + 7.15159044E-10 2.11914964E-04 6.00159004E-10 0.00000000E+00 7.15159044E-10 + 1.09259860E-03-3.99518305E-19 4.20864329E-07-1.70102969E-21 7.66107330E-02 + 0.00000000E+00-3.59498918E-06 0.00000000E+00-4.12826266E-03-1.18558249E-08 +-4.60900226E-03-1.31343496E-08 0.00000000E+00-1.41189107E-08 0.00000000E+00 +-1.56460445E-08-4.12826266E-03-1.18558249E-08-4.60900226E-03-1.31343496E-08 + 0.00000000E+00-1.41189107E-08 0.00000000E+00-1.56460445E-08 2.20677511E-04 +-2.22842284E-19-1.36424265E-06 1.25717766E-21 1.29981872E-02 0.00000000E+00 +-8.13855135E-05 0.00000000E+00-4.25094497E-03-1.20269034E-08 2.07196130E-04 + 5.93581114E-10 0.00000000E+00-1.43295207E-08 0.00000000E+00 7.07058392E-10 +-4.25094497E-03-1.20269034E-08 2.07196130E-04 5.93581114E-10 0.00000000E+00 +-1.43295207E-08 0.00000000E+00 7.07058392E-10-8.47381769E-05 0.00000000E+00 +-5.07022245E-07 0.00000000E+00-9.74181797E-07 1.04121684E-21-5.92595622E-09 + 5.13084454E-24 0.00000000E+00-5.19584639E-14 3.11009177E-08-4.14853645E-14 + 0.00000000E+00-5.19584639E-14 3.11009177E-08-4.14853645E-14-3.59498918E-06 + 0.00000000E+00 1.32505010E-06 0.00000000E+00 4.20864329E-07 1.70102969E-21 + 1.89071502E-08 5.53760052E-24 0.00000000E+00 7.32492647E-11 0.00000000E+00 +-1.05111746E-13-2.13923373E-05 6.15114654E-11 6.12475543E-08-8.53921978E-14 + 0.00000000E+00 7.32492647E-11 0.00000000E+00-1.05111746E-13-2.13923373E-05 + 6.15114654E-11 6.12475543E-08-8.53921978E-14 8.11418015E-05 0.00000000E+00 +-4.87009031E-07 0.00000000E+00 1.39505857E-06 1.51864099E-21-8.26806837E-09 +-8.24642932E-24 0.00000000E+00-7.45112456E-11 0.00000000E+00-5.32206124E-14 + 2.21275126E-05-6.25365547E-11 3.01690769E-08-4.39357560E-14 0.00000000E+00 +-7.45112456E-11 0.00000000E+00-5.32206124E-14 2.21275126E-05-6.25365547E-11 + 3.01690769E-08-4.39357560E-14 0.00000000E+00 1.40468853E-08 0.00000000E+00 + 7.30414309E-11-4.08515012E-03 1.17983182E-08-2.12679336E-05 6.13455240E-11 + 1.84922867E-03 0.00000000E+00 8.25099295E-04-2.13808026E-18 1.84922867E-03 + 0.00000000E+00 8.25099295E-04-2.13808026E-18 0.00000000E+00 1.41189107E-08 + 0.00000000E+00-7.32492647E-11-4.12826266E-03 1.18558249E-08 2.13923373E-05 +-6.15114654E-11 1.51854102E-02 0.00000000E+00 1.94718030E-03 0.00000000E+00 + 6.93351243E-03-3.23746447E-17 9.08554351E-04-5.73751484E-18 1.51854102E-02 + 0.00000000E+00 1.94718030E-03 0.00000000E+00 6.93351243E-03-3.23746447E-17 + 9.08554351E-04-5.73751484E-18 4.08515012E-03 1.17983182E-08 2.12679336E-05 + 6.13455240E-11 0.00000000E+00 1.40468853E-08 0.00000000E+00 7.30414309E-11 + 8.25099295E-04 2.13808026E-18 1.84922867E-03 0.00000000E+00 8.25099295E-04 + 2.13808026E-18 1.84922867E-03 0.00000000E+00 4.12826266E-03 1.18558249E-08 +-2.13923373E-05-6.15114654E-11 0.00000000E+00 1.41189107E-08 0.00000000E+00 +-7.32492647E-11 6.93351243E-03 3.23746447E-17 9.08554351E-04 5.73751484E-18 + 1.51854102E-02 0.00000000E+00 1.94718030E-03 0.00000000E+00 6.93351243E-03 + 3.23746447E-17 9.08554351E-04 5.73751484E-18 1.51854102E-02 0.00000000E+00 + 1.94718030E-03 0.00000000E+00 0.00000000E+00 1.40468853E-08 0.00000000E+00 + 7.30414309E-11-4.08515012E-03 1.17983182E-08-2.12679336E-05 6.13455240E-11 + 1.84922867E-03 0.00000000E+00 8.25099295E-04-2.13808026E-18 1.07743833E-01 + 0.00000000E+00 3.11437367E-02-7.90831089E-17 0.00000000E+00 1.41189107E-08 + 0.00000000E+00-7.32492647E-11-4.12826266E-03 1.18558249E-08 2.13923373E-05 +-6.15114654E-11 1.51854102E-02 0.00000000E+00 1.94718030E-03 0.00000000E+00 + 6.93351243E-03-3.23746447E-17 9.08554351E-04-5.73751484E-18 8.41809663E-01 + 0.00000000E+00 1.02743957E-01 0.00000000E+00 2.49431184E-01-8.23739222E-16 + 3.12142826E-02-1.21747515E-16 1.47902400E-02 0.00000000E+00 9.22992794E-05 + 0.00000000E+00 4.24401357E-05 1.09801840E-18 2.78497228E-07 6.73284424E-21 + 0.00000000E+00 6.87298010E-10-1.95044666E-04 5.78080161E-10 0.00000000E+00 + 6.87298010E-10-1.95044666E-04 5.78080161E-10 8.34925839E-02 0.00000000E+00 +-4.46820848E-06 0.00000000E+00 4.06106333E-04 2.83643359E-18 3.79212329E-07 +-1.03438315E-20 0.00000000E+00-1.35721818E-08 0.00000000E+00-1.50382976E-08 + 3.78481071E-03-1.14339307E-08 4.23501993E-03-1.26582949E-08 0.00000000E+00 +-1.35721818E-08 0.00000000E+00-1.50382976E-08 3.78481071E-03-1.14339307E-08 + 4.23501993E-03-1.26582949E-08 1.41263674E-02 0.00000000E+00-8.84682196E-05 + 0.00000000E+00 9.87625279E-05-2.68239386E-19-6.03536231E-07 1.39113583E-21 + 0.00000000E+00-1.37715204E-08 0.00000000E+00 6.79632666E-10 3.91451593E-03 +-1.15836412E-08-1.90055869E-04 5.72326723E-10 0.00000000E+00-1.37715204E-08 + 0.00000000E+00 6.79632666E-10 3.91451593E-03-1.15836412E-08-1.90055869E-04 + 5.72326723E-10-1.81150365E-04-5.62871447E-10 3.28032585E-08 3.59076205E-14 + 0.00000000E+00-6.66550967E-10 0.00000000E+00 4.89825262E-14-3.53838664E-04 +-1.19874041E-18-8.51917043E-04 0.00000000E+00-1.55222111E-02-4.06153673E-17 +-5.81740847E-02 0.00000000E+00 4.23501993E-03 1.26582949E-08 6.47577476E-08 + 7.47367728E-14 0.00000000E+00 1.50382976E-08 0.00000000E+00 9.94952174E-14 + 7.45517793E-04 2.53812162E-18 2.98346350E-03 8.70731385E-18 1.75206054E-03 + 0.00000000E+00 7.00848874E-03 0.00000000E+00 3.10765226E-02 5.64284492E-17 + 1.24307051E-01 2.43899722E-16 1.13269851E-01 0.00000000E+00 4.53310505E-01 + 0.00000000E+00-2.03598858E-04-5.88771117E-10 3.19735630E-08 3.88245308E-14 + 0.00000000E+00-7.01046243E-10 0.00000000E+00 5.05558018E-14 7.45517145E-04 + 1.93232118E-18-3.92654312E-04-8.60863394E-19 1.75205353E-03 0.00000000E+00 +-9.00322371E-04 0.00000000E+00 3.10764326E-02 5.37289317E-17-1.55550648E-02 +-3.09519654E-17 1.13274191E-01 0.00000000E+00-5.52536338E-02 0.00000000E+00 + 0.00000000E+00-6.66550967E-10 0.00000000E+00 4.89825262E-14 1.81150365E-04 +-5.62871447E-10-3.28032585E-08 3.59076205E-14-8.51917043E-04 0.00000000E+00 +-3.53838664E-04 1.19874041E-18-5.81740847E-02 0.00000000E+00-1.55222111E-02 + 4.06153673E-17 0.00000000E+00 1.50382976E-08 0.00000000E+00 9.94952174E-14 +-4.23501993E-03 1.26582949E-08-6.47577476E-08 7.47367728E-14 1.75206054E-03 + 0.00000000E+00 7.00848874E-03 0.00000000E+00 7.45517793E-04-2.53812162E-18 + 2.98346350E-03-8.70731385E-18 1.13269851E-01 0.00000000E+00 4.53310505E-01 + 0.00000000E+00 3.10765226E-02-5.64284492E-17 1.24307051E-01-2.43899722E-16 + 0.00000000E+00-7.01046243E-10 0.00000000E+00 5.05558018E-14 2.03598858E-04 +-5.88771117E-10-3.19735630E-08 3.88245308E-14 1.75205353E-03 0.00000000E+00 +-9.00322371E-04 0.00000000E+00 7.45517145E-04-1.93232118E-18-3.92654312E-04 + 8.60863394E-19 1.13274191E-01 0.00000000E+00-5.52536338E-02 0.00000000E+00 + 3.10764326E-02-5.37289317E-17-1.55550648E-02 3.09519654E-17-1.81150365E-04 +-5.62871447E-10 3.28032585E-08 3.59076205E-14 0.00000000E+00-6.66550967E-10 + 0.00000000E+00 4.89825262E-14-3.53838664E-04-1.19874041E-18-8.51917043E-04 + 0.00000000E+00-3.53838664E-04-1.19874041E-18-8.51917043E-04 0.00000000E+00 + 4.23501993E-03 1.26582949E-08 6.47577476E-08 7.47367728E-14 0.00000000E+00 + 1.50382976E-08 0.00000000E+00 9.94952174E-14 7.45517793E-04 2.53812162E-18 + 2.98346350E-03 8.70731385E-18 1.75206054E-03 0.00000000E+00 7.00848874E-03 + 0.00000000E+00 7.45517793E-04 2.53812162E-18 2.98346350E-03 8.70731385E-18 + 1.75206054E-03 0.00000000E+00 7.00848874E-03 0.00000000E+00-2.03598858E-04 +-5.88771117E-10 3.19735630E-08 3.88245308E-14 0.00000000E+00-7.01046243E-10 + 0.00000000E+00 5.05558018E-14 7.45517145E-04 1.93232118E-18-3.92654312E-04 +-8.60863394E-19 1.75205353E-03 0.00000000E+00-9.00322371E-04 0.00000000E+00 + 7.45517145E-04 1.93232118E-18-3.92654312E-04-8.60863394E-19 1.75205353E-03 + 0.00000000E+00-9.00322371E-04 0.00000000E+00 0.00000000E+00-6.66550967E-10 + 0.00000000E+00 4.89825262E-14 1.81150365E-04-5.62871447E-10-3.28032585E-08 + 3.59076205E-14-8.51917043E-04 0.00000000E+00-3.53838664E-04 1.19874041E-18 +-8.51917043E-04 0.00000000E+00-3.53838664E-04 1.19874041E-18 0.00000000E+00 + 1.50382976E-08 0.00000000E+00 9.94952174E-14-4.23501993E-03 1.26582949E-08 +-6.47577476E-08 7.47367728E-14 1.75206054E-03 0.00000000E+00 7.00848874E-03 + 0.00000000E+00 7.45517793E-04-2.53812162E-18 2.98346350E-03-8.70731385E-18 + 1.75206054E-03 0.00000000E+00 7.00848874E-03 0.00000000E+00 7.45517793E-04 +-2.53812162E-18 2.98346350E-03-8.70731385E-18 0.00000000E+00-7.01046243E-10 + 0.00000000E+00 5.05558018E-14 2.03598858E-04-5.88771117E-10-3.19735630E-08 + 3.88245308E-14 1.75205353E-03 0.00000000E+00-9.00322371E-04 0.00000000E+00 + 7.45517145E-04-1.93232118E-18-3.92654312E-04 8.60863394E-19 1.75205353E-03 + 0.00000000E+00-9.00322371E-04 0.00000000E+00 7.45517145E-04-1.93232118E-18 +-3.92654312E-04 8.60863394E-19-2.52151547E-07 7.01480269E-21-1.58994964E-09 + 4.13167003E-23-9.26370669E-05 0.00000000E+00-5.54160978E-07 0.00000000E+00 +-3.28032585E-08-3.59076205E-14 0.00000000E+00-4.89825262E-14-3.28032585E-08 +-3.59076205E-14 0.00000000E+00-4.89825262E-14 3.79212329E-07 1.03438315E-20 + 7.03563362E-09-4.54808695E-23-4.46820848E-06 0.00000000E+00 1.44415519E-06 + 0.00000000E+00 1.96058431E-05 5.93293506E-11-6.47577476E-08-7.47367728E-14 + 0.00000000E+00 7.04147030E-11 0.00000000E+00-9.94952174E-14 1.96058431E-05 + 5.93293506E-11-6.47577476E-08-7.47367728E-14 0.00000000E+00 7.04147030E-11 + 0.00000000E+00-9.94952174E-14 6.31363271E-07 1.98195865E-21-3.70023844E-09 +-1.02358979E-23 8.81666361E-05 0.00000000E+00-5.29284424E-07 0.00000000E+00 +-2.03831153E-05-6.02263797E-11-3.19735630E-08-3.88245308E-14 0.00000000E+00 +-7.16091402E-11 0.00000000E+00-5.05558018E-14-2.03831153E-05-6.02263797E-11 +-3.19735630E-08-3.88245308E-14 0.00000000E+00-7.16091402E-11 0.00000000E+00 +-5.05558018E-14 4.24401357E-05-1.09801840E-18 2.78497228E-07-6.73284424E-21 + 1.47902400E-02 0.00000000E+00 9.22992794E-05 0.00000000E+00 1.95044666E-04 + 5.78080161E-10 0.00000000E+00 6.87298010E-10 1.95044666E-04 5.78080161E-10 + 0.00000000E+00 6.87298010E-10 4.06106333E-04-2.83643359E-18 3.79212329E-07 + 1.03438315E-20 8.34925839E-02 0.00000000E+00-4.46820848E-06 0.00000000E+00 +-3.78481071E-03-1.14339307E-08-4.23501993E-03-1.26582949E-08 0.00000000E+00 +-1.35721818E-08 0.00000000E+00-1.50382976E-08-3.78481071E-03-1.14339307E-08 +-4.23501993E-03-1.26582949E-08 0.00000000E+00-1.35721818E-08 0.00000000E+00 +-1.50382976E-08 9.87625279E-05 2.68239386E-19-6.03536231E-07-1.39113583E-21 + 1.41263674E-02 0.00000000E+00-8.84682196E-05 0.00000000E+00-3.91451593E-03 +-1.15836412E-08 1.90055869E-04 5.72326723E-10 0.00000000E+00-1.37715204E-08 + 0.00000000E+00 6.79632666E-10-3.91451593E-03-1.15836412E-08 1.90055869E-04 + 5.72326723E-10 0.00000000E+00-1.37715204E-08 0.00000000E+00 6.79632666E-10 +-9.26370669E-05 0.00000000E+00-5.54160978E-07 0.00000000E+00-2.52151547E-07 +-7.01480269E-21-1.58994964E-09-4.13167003E-23 0.00000000E+00-4.89825262E-14 + 3.28032585E-08-3.59076205E-14 0.00000000E+00-4.89825262E-14 3.28032585E-08 +-3.59076205E-14-4.46820848E-06 0.00000000E+00 1.44415519E-06 0.00000000E+00 + 3.79212329E-07-1.03438315E-20 7.03563362E-09 4.54808695E-23 0.00000000E+00 + 7.04147030E-11 0.00000000E+00-9.94952174E-14-1.96058431E-05 5.93293506E-11 + 6.47577476E-08-7.47367728E-14 0.00000000E+00 7.04147030E-11 0.00000000E+00 +-9.94952174E-14-1.96058431E-05 5.93293506E-11 6.47577476E-08-7.47367728E-14 + 8.81666361E-05 0.00000000E+00-5.29284424E-07 0.00000000E+00 6.31363271E-07 +-1.98195865E-21-3.70023844E-09 1.02358979E-23 0.00000000E+00-7.16091402E-11 + 0.00000000E+00-5.05558018E-14 2.03831153E-05-6.02263797E-11 3.19735630E-08 +-3.88245308E-14 0.00000000E+00-7.16091402E-11 0.00000000E+00-5.05558018E-14 + 2.03831153E-05-6.02263797E-11 3.19735630E-08-3.88245308E-14 1.41263674E-02 + 0.00000000E+00 8.81666361E-05 0.00000000E+00 9.87625279E-05-2.68239386E-19 + 6.31363271E-07-1.98195865E-21 0.00000000E+00 7.01046243E-10-2.03598858E-04 + 5.88771117E-10 0.00000000E+00 7.01046243E-10-2.03598858E-04 5.88771117E-10 + 7.98647335E-02 0.00000000E+00-3.99877596E-06 0.00000000E+00 7.40421380E-04 +-2.41283213E-18 3.99947940E-07 1.82900681E-21 0.00000000E+00-1.38416010E-08 + 0.00000000E+00-1.53380087E-08 3.95883840E-03-1.16374589E-08 4.42460317E-03 +-1.28884278E-08 0.00000000E+00-1.38416010E-08 0.00000000E+00-1.53380087E-08 + 3.95883840E-03-1.16374589E-08 4.42460317E-03-1.28884278E-08 1.35322671E-02 + 0.00000000E+00-8.47381769E-05 0.00000000E+00 1.58166401E-04-1.38437490E-19 +-9.74181797E-07 1.04121684E-21 0.00000000E+00-1.40468853E-08 0.00000000E+00 + 6.93151216E-10 4.08515012E-03-1.17983182E-08-1.98741655E-04 5.82587417E-10 + 0.00000000E+00-1.40468853E-08 0.00000000E+00 6.93151216E-10 4.08515012E-03 +-1.17983182E-08-1.98741655E-04 5.82587417E-10-1.90055869E-04-5.72326723E-10 + 3.19735630E-08 3.88245308E-14 0.00000000E+00-6.79632666E-10 0.00000000E+00 + 5.05558018E-14-3.92654312E-04-8.60863394E-19-9.00322371E-04 0.00000000E+00 +-1.55550648E-02-3.09519654E-17-5.52536338E-02 0.00000000E+00 4.42460317E-03 + 1.28884278E-08 6.30678974E-08 8.02958786E-14 0.00000000E+00 1.53380087E-08 + 0.00000000E+00 1.02457764E-13 8.25100105E-04 1.51113240E-18 3.30178179E-03 + 8.74338825E-18 1.84923596E-03 0.00000000E+00 7.39720404E-03 0.00000000E+00 + 3.11438266E-02 7.00789299E-17 1.24576252E-01 3.07803770E-16 1.07740344E-01 + 0.00000000E+00 4.31159054E-01 0.00000000E+00-2.11914964E-04-6.00159004E-10 + 3.11009177E-08 4.14853645E-14 0.00000000E+00-7.15159044E-10 0.00000000E+00 + 5.19584639E-14 8.25099295E-04 2.13808026E-18-4.33413411E-04-1.96889877E-18 + 1.84922867E-03 0.00000000E+00-9.49102242E-04 0.00000000E+00 3.11437367E-02 + 7.90831089E-17-1.55895048E-02-5.02076560E-17 1.07743833E-01 0.00000000E+00 +-5.26219474E-02 0.00000000E+00 0.00000000E+00-6.79632666E-10 0.00000000E+00 + 5.05558018E-14 1.90055869E-04-5.72326723E-10-3.19735630E-08 3.88245308E-14 +-9.00322371E-04 0.00000000E+00-3.92654312E-04 8.60863394E-19-5.52536338E-02 + 0.00000000E+00-1.55550648E-02 3.09519654E-17 0.00000000E+00 1.53380087E-08 + 0.00000000E+00 1.02457764E-13-4.42460317E-03 1.28884278E-08-6.30678974E-08 + 8.02958786E-14 1.84923596E-03 0.00000000E+00 7.39720404E-03 0.00000000E+00 + 8.25100105E-04-1.51113240E-18 3.30178179E-03-8.74338825E-18 1.07740344E-01 + 0.00000000E+00 4.31159054E-01 0.00000000E+00 3.11438266E-02-7.00789299E-17 + 1.24576252E-01-3.07803770E-16 0.00000000E+00-7.15159044E-10 0.00000000E+00 + 5.19584639E-14 2.11914964E-04-6.00159004E-10-3.11009177E-08 4.14853645E-14 + 1.84922867E-03 0.00000000E+00-9.49102242E-04 0.00000000E+00 8.25099295E-04 +-2.13808026E-18-4.33413411E-04 1.96889877E-18 1.07743833E-01 0.00000000E+00 +-5.26219474E-02 0.00000000E+00 3.11437367E-02-7.90831089E-17-1.55895048E-02 + 5.02076560E-17-1.90055869E-04-5.72326723E-10 3.19735630E-08 3.88245308E-14 + 0.00000000E+00-6.79632666E-10 0.00000000E+00 5.05558018E-14-3.92654312E-04 +-8.60863394E-19-9.00322371E-04 0.00000000E+00-3.92654312E-04-8.60863394E-19 +-9.00322371E-04 0.00000000E+00 4.42460317E-03 1.28884278E-08 6.30678974E-08 + 8.02958786E-14 0.00000000E+00 1.53380087E-08 0.00000000E+00 1.02457764E-13 + 8.25100105E-04 1.51113240E-18 3.30178179E-03 8.74338825E-18 1.84923596E-03 + 0.00000000E+00 7.39720404E-03 0.00000000E+00 8.25100105E-04 1.51113240E-18 + 3.30178179E-03 8.74338825E-18 1.84923596E-03 0.00000000E+00 7.39720404E-03 + 0.00000000E+00-2.11914964E-04-6.00159004E-10 3.11009177E-08 4.14853645E-14 + 0.00000000E+00-7.15159044E-10 0.00000000E+00 5.19584639E-14 8.25099295E-04 + 2.13808026E-18-4.33413411E-04-1.96889877E-18 1.84922867E-03 0.00000000E+00 +-9.49102242E-04 0.00000000E+00 8.25099295E-04 2.13808026E-18-4.33413411E-04 +-1.96889877E-18 1.84922867E-03 0.00000000E+00-9.49102242E-04 0.00000000E+00 + 0.00000000E+00-6.79632666E-10 0.00000000E+00 5.05558018E-14 1.90055869E-04 +-5.72326723E-10-3.19735630E-08 3.88245308E-14-9.00322371E-04 0.00000000E+00 +-3.92654312E-04 8.60863394E-19-9.00322371E-04 0.00000000E+00-3.92654312E-04 + 8.60863394E-19 0.00000000E+00 1.53380087E-08 0.00000000E+00 1.02457764E-13 +-4.42460317E-03 1.28884278E-08-6.30678974E-08 8.02958786E-14 1.84923596E-03 + 0.00000000E+00 7.39720404E-03 0.00000000E+00 8.25100105E-04-1.51113240E-18 + 3.30178179E-03-8.74338825E-18 1.84923596E-03 0.00000000E+00 7.39720404E-03 + 0.00000000E+00 8.25100105E-04-1.51113240E-18 3.30178179E-03-8.74338825E-18 + 0.00000000E+00-7.15159044E-10 0.00000000E+00 5.19584639E-14 2.11914964E-04 +-6.00159004E-10-3.11009177E-08 4.14853645E-14 1.84922867E-03 0.00000000E+00 +-9.49102242E-04 0.00000000E+00 8.25099295E-04-2.13808026E-18-4.33413411E-04 + 1.96889877E-18 1.84922867E-03 0.00000000E+00-9.49102242E-04 0.00000000E+00 + 8.25099295E-04-2.13808026E-18-4.33413411E-04 1.96889877E-18-6.03536231E-07 +-1.39113583E-21-3.70023844E-09-1.02358979E-23-8.84682196E-05 0.00000000E+00 +-5.29284424E-07 0.00000000E+00-3.19735630E-08-3.88245308E-14 0.00000000E+00 +-5.05558018E-14-3.19735630E-08-3.88245308E-14 0.00000000E+00-5.05558018E-14 + 3.99947940E-07-1.82900681E-21 1.28169235E-08 3.24107635E-23-3.99877596E-06 + 0.00000000E+00 1.38136591E-06 0.00000000E+00 2.05110095E-05 6.03816778E-11 +-6.30678974E-08-8.02958786E-14 0.00000000E+00 7.18113634E-11 0.00000000E+00 +-1.02457764E-13 2.05110095E-05 6.03816778E-11-6.30678974E-08-8.02958786E-14 + 0.00000000E+00 7.18113634E-11 0.00000000E+00-1.02457764E-13 1.00349453E-06 + 6.84029931E-22-5.92595622E-09-5.13084454E-24 8.44676488E-05 0.00000000E+00 +-5.07022245E-07 0.00000000E+00-2.12679336E-05-6.13455240E-11-3.11009177E-08 +-4.14853645E-14 0.00000000E+00-7.30414309E-11 0.00000000E+00-5.19584639E-14 +-2.12679336E-05-6.13455240E-11-3.11009177E-08-4.14853645E-14 0.00000000E+00 +-7.30414309E-11 0.00000000E+00-5.19584639E-14 9.87625279E-05 2.68239386E-19 + 6.31363271E-07 1.98195865E-21 1.41263674E-02 0.00000000E+00 8.81666361E-05 + 0.00000000E+00 2.03598858E-04 5.88771117E-10 0.00000000E+00 7.01046243E-10 + 2.03598858E-04 5.88771117E-10 0.00000000E+00 7.01046243E-10 7.40421380E-04 + 2.41283213E-18 3.99947940E-07-1.82900681E-21 7.98647335E-02 0.00000000E+00 +-3.99877596E-06 0.00000000E+00-3.95883840E-03-1.16374589E-08-4.42460317E-03 +-1.28884278E-08 0.00000000E+00-1.38416010E-08 0.00000000E+00-1.53380087E-08 +-3.95883840E-03-1.16374589E-08-4.42460317E-03-1.28884278E-08 0.00000000E+00 +-1.38416010E-08 0.00000000E+00-1.53380087E-08 1.58166401E-04 1.38437490E-19 +-9.74181797E-07-1.04121684E-21 1.35322671E-02 0.00000000E+00-8.47381769E-05 + 0.00000000E+00-4.08515012E-03-1.17983182E-08 1.98741655E-04 5.82587417E-10 + 0.00000000E+00-1.40468853E-08 0.00000000E+00 6.93151216E-10-4.08515012E-03 +-1.17983182E-08 1.98741655E-04 5.82587417E-10 0.00000000E+00-1.40468853E-08 + 0.00000000E+00 6.93151216E-10-8.84682196E-05 0.00000000E+00-5.29284424E-07 + 0.00000000E+00-6.03536231E-07 1.39113583E-21-3.70023844E-09 1.02358979E-23 + 0.00000000E+00-5.05558018E-14 3.19735630E-08-3.88245308E-14 0.00000000E+00 +-5.05558018E-14 3.19735630E-08-3.88245308E-14-3.99877596E-06 0.00000000E+00 + 1.38136591E-06 0.00000000E+00 3.99947940E-07 1.82900681E-21 1.28169235E-08 +-3.24107635E-23 0.00000000E+00 7.18113634E-11 0.00000000E+00-1.02457764E-13 +-2.05110095E-05 6.03816778E-11 6.30678974E-08-8.02958786E-14 0.00000000E+00 + 7.18113634E-11 0.00000000E+00-1.02457764E-13-2.05110095E-05 6.03816778E-11 + 6.30678974E-08-8.02958786E-14 8.44676488E-05 0.00000000E+00-5.07022245E-07 + 0.00000000E+00 1.00349453E-06-6.84029931E-22-5.92595622E-09 5.13084454E-24 + 0.00000000E+00-7.30414309E-11 0.00000000E+00-5.19584639E-14 2.12679336E-05 +-6.13455240E-11 3.11009177E-08-4.14853645E-14 0.00000000E+00-7.30414309E-11 + 0.00000000E+00-5.19584639E-14 2.12679336E-05-6.13455240E-11 3.11009177E-08 +-4.14853645E-14 3.91451593E-03 1.15836412E-08 2.03831153E-05 6.02263797E-11 + 0.00000000E+00 1.37715204E-08 0.00000000E+00 7.16091402E-11 7.45517145E-04 + 1.93232118E-18 1.75205353E-03 0.00000000E+00 3.10764326E-02 5.37289317E-17 + 1.13274191E-01 0.00000000E+00 3.95883840E-03 1.16374589E-08-2.05110095E-05 +-6.03816778E-11 0.00000000E+00 1.38416010E-08 0.00000000E+00-7.18113634E-11 + 6.28135815E-03 1.19431478E-17 8.25100105E-04 1.51113240E-18 1.44049436E-02 + 0.00000000E+00 1.84923596E-03 0.00000000E+00 2.48880130E-01 4.69783448E-16 + 3.11438266E-02 7.00789299E-17 8.83893766E-01 0.00000000E+00 1.07740344E-01 + 0.00000000E+00 0.00000000E+00 1.37715204E-08 0.00000000E+00 7.16091402E-11 +-3.91451593E-03 1.15836412E-08-2.03831153E-05 6.02263797E-11 1.75205353E-03 + 0.00000000E+00 7.45517145E-04-1.93232118E-18 1.75205353E-03 0.00000000E+00 + 7.45517145E-04-1.93232118E-18 0.00000000E+00 1.38416010E-08 0.00000000E+00 +-7.18113634E-11-3.95883840E-03 1.16374589E-08 2.05110095E-05-6.03816778E-11 + 1.44049436E-02 0.00000000E+00 1.84923596E-03 0.00000000E+00 6.28135815E-03 +-1.19431478E-17 8.25100105E-04-1.51113240E-18 1.44049436E-02 0.00000000E+00 + 1.84923596E-03 0.00000000E+00 6.28135815E-03-1.19431478E-17 8.25100105E-04 +-1.51113240E-18 3.91451593E-03 1.15836412E-08 2.03831153E-05 6.02263797E-11 + 0.00000000E+00 1.37715204E-08 0.00000000E+00 7.16091402E-11 7.45517145E-04 + 1.93232118E-18 1.75205353E-03 0.00000000E+00 7.45517145E-04 1.93232118E-18 + 1.75205353E-03 0.00000000E+00 3.95883840E-03 1.16374589E-08-2.05110095E-05 +-6.03816778E-11 0.00000000E+00 1.38416010E-08 0.00000000E+00-7.18113634E-11 + 6.28135815E-03 1.19431478E-17 8.25100105E-04 1.51113240E-18 1.44049436E-02 + 0.00000000E+00 1.84923596E-03 0.00000000E+00 6.28135815E-03 1.19431478E-17 + 8.25100105E-04 1.51113240E-18 1.44049436E-02 0.00000000E+00 1.84923596E-03 + 0.00000000E+00 0.00000000E+00 1.37715204E-08 0.00000000E+00 7.16091402E-11 +-3.91451593E-03 1.15836412E-08-2.03831153E-05 6.02263797E-11 1.75205353E-03 + 0.00000000E+00 7.45517145E-04-1.93232118E-18 1.13274191E-01 0.00000000E+00 + 3.10764326E-02-5.37289317E-17 0.00000000E+00 1.38416010E-08 0.00000000E+00 +-7.18113634E-11-3.95883840E-03 1.16374589E-08 2.05110095E-05-6.03816778E-11 + 1.44049436E-02 0.00000000E+00 1.84923596E-03 0.00000000E+00 6.28135815E-03 +-1.19431478E-17 8.25100105E-04-1.51113240E-18 8.83893766E-01 0.00000000E+00 + 1.07740344E-01 0.00000000E+00 2.48880130E-01-4.69783448E-16 3.11438266E-02 +-7.00789299E-17 \ No newline at end of file diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/dfgmr.c b/src/Libraries/superlu-5.2.1/EXAMPLE/dfgmr.c new file mode 100644 index 00000000..cbfdf579 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/dfgmr.c @@ -0,0 +1,308 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dfgmr.c + * \brief flexible GMRES from ITSOL developed by Yousef Saad. + */ + +/* ITSOL COPYRIGHT + +Copyright (C) 2006, the University of Minnesota + +ITSOL is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation [version 2 of the License, or any later version] +For details, see + +http://www.gnu.org/copyleft/gpl.html + +A copy of the GNU licencing agreement is attached to the ITSOL package +in the file GNU. For additional information contact the Free Software +Foundation Inc., 65 Mass Ave, Cambridge, MA 02139, USA. + +DISCLAIMER +---------- + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +For information on ITSOL contact saad@cs.umn.edu +*/ + +#include "slu_ddefs.h" + +#define epsmac 1.0e-16 + +extern double ddot_(int *, double [], int *, double [], int *); +extern double dnrm2_(int *, double [], int *); + + +int dfgmr(int n, + void (*dmatvec) (double, double[], double, double[]), + void (*dpsolve) (int, double[], double[]), + double *rhs, double *sol, double tol, int im, int *itmax, FILE * fits) +{ +/*---------------------------------------------------------------------- +| *** Preconditioned FGMRES *** ++----------------------------------------------------------------------- +| This is a simple version of the ARMS preconditioned FGMRES algorithm. ++----------------------------------------------------------------------- +| Y. S. Dec. 2000. -- Apr. 2008 ++----------------------------------------------------------------------- +| on entry: +|---------- +| +| rhs = real vector of length n containing the right hand side. +| sol = real vector of length n containing an initial guess to the +| solution on input. +| tol = tolerance for stopping iteration +| im = Krylov subspace dimension +| (itmax) = max number of iterations allowed. +| fits = NULL: no output +| != NULL: file handle to output " resid vs time and its" +| +| on return: +|---------- +| fgmr int = 0 --> successful return. +| int = 1 --> convergence not achieved in itmax iterations. +| sol = contains an approximate solution (upon successful return). +| itmax = has changed. It now contains the number of steps required +| to converge -- ++----------------------------------------------------------------------- +| internal work arrays: +|---------- +| vv = work array of length [im+1][n] (used to store the Arnoldi +| basis) +| hh = work array of length [im][im+1] (Householder matrix) +| z = work array of length [im][n] to store preconditioned vectors ++----------------------------------------------------------------------- +| subroutines called : +| matvec - matrix-vector multiplication operation +| psolve - (right) preconditionning operation +| psolve can be a NULL pointer (GMRES without preconditioner) ++---------------------------------------------------------------------*/ + + int maxits = *itmax; + int i, i1, ii, j, k, k1, its, retval, i_1 = 1, i_2 = 2; + double beta, eps1 = 0.0, t, t0, gam; + double **hh, *c, *s, *rs; + double **vv, **z, tt; + double zero = 0.0; + double one = 1.0; + + its = 0; + vv = (double **)SUPERLU_MALLOC((im + 1) * sizeof(double *)); + for (i = 0; i <= im; i++) vv[i] = doubleMalloc(n); + z = (double **)SUPERLU_MALLOC(im * sizeof(double *)); + hh = (double **)SUPERLU_MALLOC(im * sizeof(double *)); + for (i = 0; i < im; i++) + { + hh[i] = doubleMalloc(i + 2); + z[i] = doubleMalloc(n); + } + c = doubleMalloc(im); + s = doubleMalloc(im); + rs = doubleMalloc(im + 1); + + /*---- outer loop starts here ----*/ + do + { + /*---- compute initial residual vector ----*/ + dmatvec(one, sol, zero, vv[0]); + for (j = 0; j < n; j++) + vv[0][j] = rhs[j] - vv[0][j]; /* vv[0]= initial residual */ + beta = dnrm2_(&n, vv[0], &i_1); + + /*---- print info if fits != null ----*/ + if (fits != NULL && its == 0) + fprintf(fits, "%8d %10.2e\n", its, beta); + /*if ( beta <= tol * dnrm2_(&n, rhs, &i_1) )*/ + if ( !(beta > tol * dnrm2_(&n, rhs, &i_1)) ) + break; + t = 1.0 / beta; + + /*---- normalize: vv[0] = vv[0] / beta ----*/ + for (j = 0; j < n; j++) + vv[0][j] = vv[0][j] * t; + if (its == 0) + eps1 = tol * beta; + + /*---- initialize 1-st term of rhs of hessenberg system ----*/ + rs[0] = beta; + for (i = 0; i < im; i++) + { + its++; + i1 = i + 1; + + /*------------------------------------------------------------ + | (Right) Preconditioning Operation z_{j} = M^{-1} v_{j} + +-----------------------------------------------------------*/ + if (dpsolve) + dpsolve(n, z[i], vv[i]); + else + dcopy_(&n, vv[i], &i_1, z[i], &i_1); + + /*---- matvec operation w = A z_{j} = A M^{-1} v_{j} ----*/ + dmatvec(one, z[i], zero, vv[i1]); + + /*------------------------------------------------------------ + | modified gram - schmidt... + | h_{i,j} = (w,v_{i}) + | w = w - h_{i,j} v_{i} + +------------------------------------------------------------*/ + t0 = dnrm2_(&n, vv[i1], &i_1); + for (j = 0; j <= i; j++) + { + double negt; + tt = ddot_(&n, vv[j], &i_1, vv[i1], &i_1); + hh[i][j] = tt; + negt = -tt; + daxpy_(&n, &negt, vv[j], &i_1, vv[i1], &i_1); + } + + /*---- h_{j+1,j} = ||w||_{2} ----*/ + t = dnrm2_(&n, vv[i1], &i_1); + while (t < 0.5 * t0) + { + t0 = t; + for (j = 0; j <= i; j++) + { + double negt; + tt = ddot_(&n, vv[j], &i_1, vv[i1], &i_1); + hh[i][j] += tt; + negt = -tt; + daxpy_(&n, &negt, vv[j], &i_1, vv[i1], &i_1); + } + t = dnrm2_(&n, vv[i1], &i_1); + } + + hh[i][i1] = t; + + if (t != 0.0) + { + /*---- v_{j+1} = w / h_{j+1,j} ----*/ + t = 1.0 / t; + for (k = 0; k < n; k++) + vv[i1][k] = vv[i1][k] * t; + } + /*--------------------------------------------------- + | done with modified gram schimdt and arnoldi step + | now update factorization of hh + +--------------------------------------------------*/ + + /*-------------------------------------------------------- + | perform previous transformations on i-th column of h + +-------------------------------------------------------*/ + for (k = 1; k <= i; k++) + { + k1 = k - 1; + tt = hh[i][k1]; + hh[i][k1] = c[k1] * tt + s[k1] * hh[i][k]; + hh[i][k] = -s[k1] * tt + c[k1] * hh[i][k]; + } + + gam = sqrt(pow(hh[i][i], 2) + pow(hh[i][i1], 2)); + + /*--------------------------------------------------- + | if gamma is zero then any small value will do + | affect only residual estimate + +--------------------------------------------------*/ + /* if (gam == 0.0) gam = epsmac; */ + + /*---- get next plane rotation ---*/ + if (gam == 0.0) + { + c[i] = one; + s[i] = zero; + } + else + { + c[i] = hh[i][i] / gam; + s[i] = hh[i][i1] / gam; + } + + rs[i1] = -s[i] * rs[i]; + rs[i] = c[i] * rs[i]; + + /*---------------------------------------------------- + | determine residual norm and test for convergence + +---------------------------------------------------*/ + hh[i][i] = c[i] * hh[i][i] + s[i] * hh[i][i1]; + beta = fabs(rs[i1]); + if (fits != NULL) + fprintf(fits, "%8d %10.2e\n", its, beta); + if (beta <= eps1 || its >= maxits) + break; + } + + if (i == im) i--; + + /*---- now compute solution. 1st, solve upper triangular system ----*/ + rs[i] = rs[i] / hh[i][i]; + + for (ii = 1; ii <= i; ii++) + { + k = i - ii; + k1 = k + 1; + tt = rs[k]; + for (j = k1; j <= i; j++) + tt = tt - hh[j][k] * rs[j]; + rs[k] = tt / hh[k][k]; + } + + /*---- linear combination of v[i]'s to get sol. ----*/ + for (j = 0; j <= i; j++) + { + tt = rs[j]; + for (k = 0; k < n; k++) + sol[k] += tt * z[j][k]; + } + + /* calculate the residual and output */ + dmatvec(one, sol, zero, vv[0]); + for (j = 0; j < n; j++) + vv[0][j] = rhs[j] - vv[0][j]; /* vv[0]= initial residual */ + + /*---- print info if fits != null ----*/ + beta = dnrm2_(&n, vv[0], &i_1); + + /*---- restart outer loop if needed ----*/ + /*if (beta >= eps1 / tol)*/ + if ( !(beta < eps1 / tol) ) + { + its = maxits + 10; + break; + } + if (beta <= eps1) + break; + } while(its < maxits); + + retval = (its >= maxits); + for (i = 0; i <= im; i++) + SUPERLU_FREE(vv[i]); + SUPERLU_FREE(vv); + for (i = 0; i < im; i++) + { + SUPERLU_FREE(hh[i]); + SUPERLU_FREE(z[i]); + } + SUPERLU_FREE(hh); + SUPERLU_FREE(z); + SUPERLU_FREE(c); + SUPERLU_FREE(s); + SUPERLU_FREE(rs); + + *itmax = its; + + return retval; +} /*----end of fgmr ----*/ diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/ditersol.c b/src/Libraries/superlu-5.2.1/EXAMPLE/ditersol.c new file mode 100644 index 00000000..1b4deb5b --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/ditersol.c @@ -0,0 +1,384 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ditersol.c + * \brief Example #1 showing how to use ILU to precondition GMRES + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Lawrence Berkeley National Laboratory
+ * November, 2010
+ * August, 2011
+ *
+ * This example shows that ILU is computed from the equilibrated matrix,
+ * and the preconditioned GMRES is applied to the equilibrated system.
+ * The driver routine DGSISX is called twice to perform factorization
+ * and apply preconditioner separately.
+ * 
+ * Note that DGSISX performs the following factorization:
+ *     Pr*Dr*A*Dc*Pc^T ~= LU
+ * with Pr being obtained from MC64 statically then partial pivoting
+ * dynamically. On return, A is overwritten as A1 = Dr*A*Dc.
+ *
+ * We can solve the transformed system, A1*y = Dr*B, using FGMRES.
+ * B is first overwritten as Dr*B.
+ * Then GMRES step requires requires 2 procedures:
+ *   1) Apply preconditioner M^{-1} = Pc^T*U^{-1}*L^{-1}*Pr
+ *   2) Matrix-vector multiplication: w = A1*v
+ * 
+ * 
+ */ + +#include "slu_ddefs.h" + +superlu_options_t *GLOBAL_OPTIONS; +double *GLOBAL_R, *GLOBAL_C; +int *GLOBAL_PERM_C, *GLOBAL_PERM_R; +SuperMatrix *GLOBAL_A, *GLOBAL_L, *GLOBAL_U; +SuperLUStat_t *GLOBAL_STAT; +mem_usage_t *GLOBAL_MEM_USAGE; + +void dpsolve(int n, + double x[], /* solution */ + double y[] /* right-hand side */ +) +{ + SuperMatrix *A = GLOBAL_A, *L = GLOBAL_L, *U = GLOBAL_U; + SuperLUStat_t *stat = GLOBAL_STAT; + int *perm_c = GLOBAL_PERM_C, *perm_r = GLOBAL_PERM_R; + char equed[1] = {'N'}; + double *R = GLOBAL_R, *C = GLOBAL_C; + superlu_options_t *options = GLOBAL_OPTIONS; + mem_usage_t *mem_usage = GLOBAL_MEM_USAGE; + int info; + static DNformat X, Y; + static SuperMatrix XX = {SLU_DN, SLU_D, SLU_GE, 1, 1, &X}; + static SuperMatrix YY = {SLU_DN, SLU_D, SLU_GE, 1, 1, &Y}; + double rpg, rcond; + + XX.nrow = YY.nrow = n; + X.lda = Y.lda = n; + X.nzval = x; + Y.nzval = y; + +#if 0 + dcopy_(&n, y, &i_1, x, &i_1); + dgstrs(NOTRANS, L, U, perm_c, perm_r, &XX, stat, &info); +#else + dgsisx(options, A, perm_c, perm_r, NULL, equed, R, C, + L, U, NULL, 0, &YY, &XX, &rpg, &rcond, NULL, + mem_usage, stat, &info); +#endif +} + +void dmatvec_mult(double alpha, double x[], double beta, double y[]) +{ + SuperMatrix *A = GLOBAL_A; + + sp_dgemv("N", alpha, A, x, 1, beta, y, 1); +} + +int main(int argc, char *argv[]) +{ + void dmatvec_mult(double alpha, double x[], double beta, double y[]); + void dpsolve(int n, double x[], double y[]); + extern int dfgmr( int n, + void (*matvec_mult)(double, double [], double, double []), + void (*psolve)(int n, double [], double[]), + double *rhs, double *sol, double tol, int restrt, int *itmax, + FILE *fits); + extern int dfill_diag(int n, NCformat *Astore); + + char equed[1] = {'B'}; + yes_no_t equil; + trans_t trans; + SuperMatrix A, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + double *a; + int *asub, *xa; + int *etree; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + int nrhs, ldx, lwork, info, m, n, nnz; + double *rhsb, *rhsx, *xact; + double *work = NULL; + double *R, *C; + double u, rpg, rcond; + double zero = 0.0; + double one = 1.0; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + int restrt, iter, maxit, i; + double resid; + double *x, *b; + +#ifdef DEBUG + extern int num_drop_L, num_drop_U; +#endif + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 0.1; //different from complete LU + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + options.RowPerm = LargeDiag; + options.ILU_DropTol = 1e-4; + options.ILU_FillTol = 1e-2; + options.ILU_FillFactor = 10.0; + options.ILU_DropRule = DROP_BASIC | DROP_AREA; + options.ILU_Norm = INF_NORM; + options.ILU_MILU = SILU; + */ + ilu_set_default_options(&options); + + /* Modify the defaults. */ + options.PivotGrowth = YES; /* Compute reciprocal pivot growth */ + options.ConditionNumber = YES;/* Compute reciprocal condition number */ + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) ABORT("Malloc fails for work[]."); + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + if (argc < 2) + { + printf("Usage:\n%s [OPTION] < [INPUT] > [OUTPUT]\nOPTION:\n" + "-h -hb:\n\t[INPUT] is a Harwell-Boeing format matrix.\n" + "-r -rb:\n\t[INPUT] is a Rutherford-Boeing format matrix.\n" + "-t -triplet:\n\t[INPUT] is a triplet format matrix.\n", + argv[0]); + return 0; + } + else + { + switch (argv[1][1]) + { + case 'H': + case 'h': + printf("Input a Harwell-Boeing format matrix:\n"); + dreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + break; + case 'R': + case 'r': + printf("Input a Rutherford-Boeing format matrix:\n"); + dreadrb(&m, &n, &nnz, &a, &asub, &xa); + break; + case 'T': + case 't': + printf("Input a triplet format matrix:\n"); + dreadtriple(&m, &n, &nnz, &a, &asub, &xa); + break; + default: + printf("Unrecognized format.\n"); + return 0; + } + } + + dCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, + SLU_NC, SLU_D, SLU_GE); + Astore = A.Store; + dfill_diag(n, Astore); + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + fflush(stdout); + + /* Generate the right-hand side */ + if ( !(rhsb = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + dCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_D, SLU_GE); + dCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_D, SLU_GE); + xact = doubleMalloc(n * nrhs); + ldx = n; + dGenXtrue(n, nrhs, xact, ldx); + dFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (double *) SUPERLU_MALLOC(A.nrow * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (double *) SUPERLU_MALLOC(A.ncol * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + + info = 0; +#ifdef DEBUG + num_drop_L = 0; + num_drop_U = 0; +#endif + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* Compute the incomplete factorization and compute the condition number + and pivot growth using dgsisx. */ + B.ncol = 0; /* not to perform triangular solution */ + dgsisx(&options, &A, perm_c, perm_r, etree, equed, R, C, &L, &U, work, + lwork, &B, &X, &rpg, &rcond, &Glu, &mem_usage, &stat, &info); + + /* Set RHS for GMRES. */ + if (!(b = doubleMalloc(m))) ABORT("Malloc fails for b[]."); + if (*equed == 'R' || *equed == 'B') { + for (i = 0; i < n; ++i) b[i] = rhsb[i] * R[i]; + } else { + for (i = 0; i < m; i++) b[i] = rhsb[i]; + } + + printf("dgsisx(): info %d, equed %c\n", info, equed[0]); + if (info > 0 || rcond < 1e-8 || rpg > 1e8) + printf("WARNING: This preconditioner might be unstable.\n"); + + if ( info == 0 || info == n+1 ) { + if ( options.PivotGrowth == YES ) + printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber == YES ) + printf("Recip. condition number = %e\n", rcond); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("n(A) = %d, nnz(A) = %d\n", n, Astore->nnz); + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("Fill ratio: nnz(F)/nnz(A) = %.3f\n", + ((double)(Lstore->nnz) + (double)(Ustore->nnz) - (double)n) + / (double)Astore->nnz); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + fflush(stdout); + + /* Set the global variables. */ + GLOBAL_A = &A; + GLOBAL_L = &L; + GLOBAL_U = &U; + GLOBAL_STAT = &stat; + GLOBAL_PERM_C = perm_c; + GLOBAL_PERM_R = perm_r; + GLOBAL_OPTIONS = &options; + GLOBAL_R = R; + GLOBAL_C = C; + GLOBAL_MEM_USAGE = &mem_usage; + + /* Set the options to do solve-only. */ + options.Fact = FACTORED; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + + /* Set the variables used by GMRES. */ + restrt = SUPERLU_MIN(n / 3 + 1, 50); + maxit = 1000; + iter = maxit; + resid = 1e-8; + if (!(x = doubleMalloc(n))) ABORT("Malloc fails for x[]."); + + if (info <= n + 1) + { + int i_1 = 1; + double maxferr = 0.0, nrmA, nrmB, res, t; + double temp; + extern double dnrm2_(int *, double [], int *); + extern void daxpy_(int *, double *, double [], int *, double [], int *); + + /* Initial guess */ + for (i = 0; i < n; i++) x[i] = zero; + + t = SuperLU_timer_(); + + /* Call GMRES */ + dfgmr(n, dmatvec_mult, dpsolve, b, x, resid, restrt, &iter, stdout); + + t = SuperLU_timer_() - t; + + /* Output the result. */ + nrmA = dnrm2_(&(Astore->nnz), (double *)((DNformat *)A.Store)->nzval, + &i_1); + nrmB = dnrm2_(&m, b, &i_1); + sp_dgemv("N", -1.0, &A, x, 1, 1.0, b, 1); + res = dnrm2_(&m, b, &i_1); + resid = res / nrmB; + printf("||A||_F = %.1e, ||B||_2 = %.1e, ||B-A*X||_2 = %.1e, " + "relres = %.1e\n", nrmA, nrmB, res, resid); + + if (iter >= maxit) + { + if (resid >= 1.0) iter = -180; + else if (resid > 1e-8) iter = -111; + } + printf("iteration: %d\nresidual: %.1e\nGMRES time: %.2f seconds.\n", + iter, resid, t); + + /* Scale the solution back if equilibration was performed. */ + if (*equed == 'C' || *equed == 'B') + for (i = 0; i < n; i++) x[i] *= C[i]; + + for (i = 0; i < m; i++) { + maxferr = SUPERLU_MAX(maxferr, fabs(x[i] - xact[i])); + } + printf("||X-X_true||_oo = %.1e\n", maxferr); + } +#ifdef DEBUG + printf("%d entries in L and %d entries in U dropped.\n", + num_drop_L, num_drop_U); +#endif + fflush(stdout); + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork >= 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } + SUPERLU_FREE(b); + SUPERLU_FREE(x); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/ditersol1.c b/src/Libraries/superlu-5.2.1/EXAMPLE/ditersol1.c new file mode 100644 index 00000000..4d880092 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/ditersol1.c @@ -0,0 +1,393 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ditersol1.c + * \brief Example #2 showing how to use ILU to precondition GMRES + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Lawrence Berkeley National Laboratory
+ * November, 2010
+ * August, 2011
+ *
+ * This example shows that ILU is computed from the equilibrated matrix,
+ * but the preconditioned GMRES is applied to the original system.
+ * The driver routine DGSISX is called twice to perform factorization
+ * and apply preconditioner separately.
+ * 
+ * Note that DGSISX performs the following factorization:
+ *     Pr*Dr*A*Dc*Pc^T ~= LU
+ * with Pr being obtained from MC64 statically then partial pivoting
+ * dynamically. On return, A is overwritten as A1 = Dr*A*Dc.
+ *
+ * We need to save a copy of the original matrix A, then solve
+ * the original system, A*x = B, using FGMRES.
+ * Each GMRES step requires requires 2 procedures:
+ *   1) Apply preconditioner M^{-1} = Dc*Pc^T*U^{-1}*L^{-1}*Pr*Dr
+ *   2) Matrix-vector multiplication: w = A*v
+ *
+ * 
+ */ + +#include "slu_ddefs.h" + +char *GLOBAL_EQUED; +superlu_options_t *GLOBAL_OPTIONS; +double *GLOBAL_R, *GLOBAL_C; +int *GLOBAL_PERM_C, *GLOBAL_PERM_R; +SuperMatrix *GLOBAL_A, *GLOBAL_A_ORIG, *GLOBAL_L, *GLOBAL_U; +SuperLUStat_t *GLOBAL_STAT; +mem_usage_t *GLOBAL_MEM_USAGE; + +void dpsolve(int n, + double x[], /* solution */ + double y[] /* right-hand side */ +) +{ + SuperMatrix *A = GLOBAL_A, *L = GLOBAL_L, *U = GLOBAL_U; + SuperLUStat_t *stat = GLOBAL_STAT; + int *perm_c = GLOBAL_PERM_C, *perm_r = GLOBAL_PERM_R; + char *equed = GLOBAL_EQUED; + double *R = GLOBAL_R, *C = GLOBAL_C; + superlu_options_t *options = GLOBAL_OPTIONS; + mem_usage_t *mem_usage = GLOBAL_MEM_USAGE; + int info; + static DNformat X, Y; + static SuperMatrix XX = {SLU_DN, SLU_D, SLU_GE, 1, 1, &X}; + static SuperMatrix YY = {SLU_DN, SLU_D, SLU_GE, 1, 1, &Y}; + double rpg, rcond; + + XX.nrow = YY.nrow = n; + X.lda = Y.lda = n; + X.nzval = x; + Y.nzval = y; + +#if 0 + dcopy_(&n, y, &i_1, x, &i_1); + dgstrs(NOTRANS, L, U, perm_c, perm_r, &XX, stat, &info); +#else + dgsisx(options, A, perm_c, perm_r, NULL, equed, R, C, + L, U, NULL, 0, &YY, &XX, &rpg, &rcond, NULL, + mem_usage, stat, &info); +#endif +} + +void dmatvec_mult(double alpha, double x[], double beta, double y[]) +{ + SuperMatrix *A = GLOBAL_A_ORIG; + + sp_dgemv("N", alpha, A, x, 1, beta, y, 1); +} + +int main(int argc, char *argv[]) +{ + void dmatvec_mult(double alpha, double x[], double beta, double y[]); + void dpsolve(int n, double x[], double y[]); + extern int dfgmr( int n, + void (*matvec_mult)(double, double [], double, double []), + void (*psolve)(int n, double [], double[]), + double *rhs, double *sol, double tol, int restrt, int *itmax, + FILE *fits); + extern int dfill_diag(int n, NCformat *Astore); + + char equed[1] = {'B'}; + yes_no_t equil; + trans_t trans; + SuperMatrix A, AA, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + double *a, *a_orig; + int *asub, *xa, *asub_orig, *xa_orig; + int *etree; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + int nrhs, ldx, lwork, info, m, n, nnz; + double *rhsb, *rhsx, *xact; + double *work = NULL; + double *R, *C; + double u, rpg, rcond; + double zero = 0.0; + double one = 1.0; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + int restrt, iter, maxit, i; + double resid; + double *x, *b; + +#ifdef DEBUG + extern int num_drop_L, num_drop_U; +#endif + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 0.1; //different from complete LU + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + options.RowPerm = LargeDiag; + options.ILU_DropTol = 1e-4; + options.ILU_FillTol = 1e-2; + options.ILU_FillFactor = 10.0; + options.ILU_DropRule = DROP_BASIC | DROP_AREA; + options.ILU_Norm = INF_NORM; + options.ILU_MILU = SILU; + */ + ilu_set_default_options(&options); + + /* Modify the defaults. */ + options.PivotGrowth = YES; /* Compute reciprocal pivot growth */ + options.ConditionNumber = YES;/* Compute reciprocal condition number */ + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) ABORT("Malloc fails for work[]."); + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + if (argc < 2) + { + printf("Usage:\n%s [OPTION] < [INPUT] > [OUTPUT]\nOPTION:\n" + "-h -hb:\n\t[INPUT] is a Harwell-Boeing format matrix.\n" + "-r -rb:\n\t[INPUT] is a Rutherford-Boeing format matrix.\n" + "-t -triplet:\n\t[INPUT] is a triplet format matrix.\n", + argv[0]); + return 0; + } + else + { + switch (argv[1][1]) + { + case 'H': + case 'h': + printf("Input a Harwell-Boeing format matrix:\n"); + dreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + break; + case 'R': + case 'r': + printf("Input a Rutherford-Boeing format matrix:\n"); + dreadrb(&m, &n, &nnz, &a, &asub, &xa); + break; + case 'T': + case 't': + printf("Input a triplet format matrix:\n"); + dreadtriple(&m, &n, &nnz, &a, &asub, &xa); + break; + default: + printf("Unrecognized format.\n"); + return 0; + } + } + + dCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, + SLU_NC, SLU_D, SLU_GE); + Astore = A.Store; + dfill_diag(n, Astore); + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + fflush(stdout); + + /* Make a copy of the original matrix. */ + nnz = Astore->nnz; + a_orig = doubleMalloc(nnz); + asub_orig = intMalloc(nnz); + xa_orig = intMalloc(n+1); + for (i = 0; i < nnz; ++i) { + a_orig[i] = ((double *)Astore->nzval)[i]; + asub_orig[i] = Astore->rowind[i]; + } + for (i = 0; i <= n; ++i) xa_orig[i] = Astore->colptr[i]; + dCreate_CompCol_Matrix(&AA, m, n, nnz, a_orig, asub_orig, xa_orig, + SLU_NC, SLU_D, SLU_GE); + + /* Generate the right-hand side */ + if ( !(rhsb = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + dCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_D, SLU_GE); + dCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_D, SLU_GE); + xact = doubleMalloc(n * nrhs); + ldx = n; + dGenXtrue(n, nrhs, xact, ldx); + dFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (double *) SUPERLU_MALLOC(A.nrow * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (double *) SUPERLU_MALLOC(A.ncol * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + + info = 0; +#ifdef DEBUG + num_drop_L = 0; + num_drop_U = 0; +#endif + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* Compute the incomplete factorization and compute the condition number + and pivot growth using dgsisx. */ + B.ncol = 0; /* not to perform triangular solution */ + dgsisx(&options, &A, perm_c, perm_r, etree, equed, R, C, &L, &U, work, + lwork, &B, &X, &rpg, &rcond, &Glu, &mem_usage, &stat, &info); + + /* Set RHS for GMRES. */ + if (!(b = doubleMalloc(m))) ABORT("Malloc fails for b[]."); + for (i = 0; i < m; i++) b[i] = rhsb[i]; + + printf("dgsisx(): info %d, equed %c\n", info, equed[0]); + if (info > 0 || rcond < 1e-8 || rpg > 1e8) + printf("WARNING: This preconditioner might be unstable.\n"); + + if ( info == 0 || info == n+1 ) { + if ( options.PivotGrowth == YES ) + printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber == YES ) + printf("Recip. condition number = %e\n", rcond); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("n(A) = %d, nnz(A) = %d\n", n, Astore->nnz); + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("Fill ratio: nnz(F)/nnz(A) = %.3f\n", + ((double)(Lstore->nnz) + (double)(Ustore->nnz) - (double)n) + / (double)Astore->nnz); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + fflush(stdout); + + /* Set the global variables. */ + GLOBAL_A = &A; + GLOBAL_A_ORIG = &AA; + GLOBAL_L = &L; + GLOBAL_U = &U; + GLOBAL_STAT = &stat; + GLOBAL_PERM_C = perm_c; + GLOBAL_PERM_R = perm_r; + GLOBAL_OPTIONS = &options; + GLOBAL_EQUED = equed; + GLOBAL_R = R; + GLOBAL_C = C; + GLOBAL_MEM_USAGE = &mem_usage; + + /* Set the options to do solve-only. */ + options.Fact = FACTORED; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + + /* Set the variables used by GMRES. */ + restrt = SUPERLU_MIN(n / 3 + 1, 50); + maxit = 1000; + iter = maxit; + resid = 1e-8; + if (!(x = doubleMalloc(n))) ABORT("Malloc fails for x[]."); + + if (info <= n + 1) + { + int i_1 = 1; + double maxferr = 0.0, nrmA, nrmB, res, t; + double temp; + extern double dnrm2_(int *, double [], int *); + extern void daxpy_(int *, double *, double [], int *, double [], int *); + + /* Initial guess */ + for (i = 0; i < n; i++) x[i] = zero; + + t = SuperLU_timer_(); + + /* Call GMRES */ + dfgmr(n, dmatvec_mult, dpsolve, b, x, resid, restrt, &iter, stdout); + + t = SuperLU_timer_() - t; + + /* Output the result. */ + nrmA = dnrm2_(&(Astore->nnz), (double *)((DNformat *)A.Store)->nzval, + &i_1); + nrmB = dnrm2_(&m, b, &i_1); + sp_dgemv("N", -1.0, &A, x, 1, 1.0, b, 1); + res = dnrm2_(&m, b, &i_1); + resid = res / nrmB; + printf("||A||_F = %.1e, ||B||_2 = %.1e, ||B-A*X||_2 = %.1e, " + "relres = %.1e\n", nrmA, nrmB, res, resid); + + if (iter >= maxit) + { + if (resid >= 1.0) iter = -180; + else if (resid > 1e-8) iter = -111; + } + printf("iteration: %d\nresidual: %.1e\nGMRES time: %.2f seconds.\n", + iter, resid, t); + + for (i = 0; i < m; i++) { + maxferr = SUPERLU_MAX(maxferr, fabs(x[i] - xact[i])); + } + printf("||X-X_true||_oo = %.1e\n", maxferr); + } +#ifdef DEBUG + printf("%d entries in L and %d entries in U dropped.\n", + num_drop_L, num_drop_U); +#endif + fflush(stdout); + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + Destroy_CompCol_Matrix(&A); + Destroy_CompCol_Matrix(&AA); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork >= 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } + SUPERLU_FREE(b); + SUPERLU_FREE(x); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsol.c b/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsol.c new file mode 100644 index 00000000..189824d0 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsol.c @@ -0,0 +1,126 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 3.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + */ +#include "slu_ddefs.h" + +int main(int argc, char *argv[]) +{ + SuperMatrix A; + NCformat *Astore; + double *a; + int *asub, *xa; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + SuperMatrix L; /* factor L */ + SCformat *Lstore; + SuperMatrix U; /* factor U */ + NCformat *Ustore; + SuperMatrix B; + int nrhs, ldx, info, m, n, nnz; + double *xact, *rhs; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Read the matrix in Harwell-Boeing format. */ + dreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + dCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_D, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + nrhs = 1; + if ( !(rhs = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhs[]."); + dCreate_Dense_Matrix(&B, m, nrhs, rhs, m, SLU_DN, SLU_D, SLU_GE); + xact = doubleMalloc(n * nrhs); + ldx = n; + dGenXtrue(n, nrhs, xact, ldx); + dFillRHS(options.Trans, nrhs, xact, ldx, &A, &B); + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + dgssv(&options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info); + + if ( info == 0 ) { + + /* This is how you could access the solution matrix. */ + double *sol = (double*) ((DNformat*) B.Store)->nzval; + + /* Compute the infinity norm of the error. */ + dinf_norm_error(nrhs, &B, xact); + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + dQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + + } else { + printf("dgssv() error returns INFO= %d\n", info); + if ( info <= n ) { /* factorization completes */ + dQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + } + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhs); + SUPERLU_FREE (xact); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsol1.c b/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsol1.c new file mode 100644 index 00000000..55d7deaf --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsol1.c @@ -0,0 +1,131 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 3.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + */ +#include "slu_ddefs.h" + +int main(int argc, char *argv[]) +{ + SuperMatrix A; + NCformat *Astore; + double *a; + int *asub, *xa; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + SuperMatrix L; /* factor L */ + SCformat *Lstore; + SuperMatrix U; /* factor U */ + NCformat *Ustore; + SuperMatrix B; + int nrhs, ldx, info, m, n, nnz; + double *xact, *rhs; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Now we modify the default options to use the symmetric mode. */ + options.SymmetricMode = YES; + options.ColPerm = MMD_AT_PLUS_A; + options.DiagPivotThresh = 0.001; + + /* Read the matrix in Harwell-Boeing format. */ + dreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + dCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_D, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + nrhs = 1; + if ( !(rhs = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhs[]."); + dCreate_Dense_Matrix(&B, m, nrhs, rhs, m, SLU_DN, SLU_D, SLU_GE); + xact = doubleMalloc(n * nrhs); + ldx = n; + dGenXtrue(n, nrhs, xact, ldx); + dFillRHS(options.Trans, nrhs, xact, ldx, &A, &B); + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + dgssv(&options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info); + + if ( info == 0 ) { + + /* This is how you could access the solution matrix. */ + double *sol = (double*) ((DNformat*) B.Store)->nzval; + + /* Compute the infinity norm of the error. */ + dinf_norm_error(nrhs, &B, xact); + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + dQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + + } else { + printf("dgssv() error returns INFO= %d\n", info); + if ( info <= n ) { /* factorization completes */ + dQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + } + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhs); + SUPERLU_FREE (xact); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsolx.c b/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsolx.c new file mode 100644 index 00000000..d128a278 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsolx.c @@ -0,0 +1,226 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 3.1) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * August 1, 2008 + * + */ +#include "slu_ddefs.h" + +int main(int argc, char *argv[]) +{ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + double *a; + int *asub, *xa; + int *perm_r; /* row permutations from partial pivoting */ + int *perm_c; /* column permutation vector */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, m, n, nnz; + double *rhsb, *rhsx, *xact; + double *R, *C; + double *ferr, *berr; + double u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + /* Add more functionalities that the defaults. */ + options.PivotGrowth = YES; /* Compute reciprocal pivot growth */ + options.ConditionNumber = YES;/* Compute reciprocal condition number */ + options.IterRefine = SLU_DOUBLE; /* Perform double-precision refinement */ + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("DLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + dreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + dCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_D, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + dCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_D, SLU_GE); + dCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_D, SLU_GE); + xact = doubleMalloc(n * nrhs); + ldx = n; + dGenXtrue(n, nrhs, xact, ldx); + dFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (double *) SUPERLU_MALLOC(A.nrow * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (double *) SUPERLU_MALLOC(A.ncol * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* Solve the system and compute the condition number + and error bounds using dgssvx. */ + + dgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("dgssvx(): info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + double *sol = (double*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth == YES ) + printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber == YES ) + printf("Recip. condition number = %e\n", rcond); + if ( options.IterRefine != NOREFINE ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork == 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + + +/* + * Parse command line inputs. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + double *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:w:r:u:f:t:p:e:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsolx1.c b/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsolx1.c new file mode 100644 index 00000000..da676630 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsolx1.c @@ -0,0 +1,257 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 5.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + * Last update: July 10, 2015 + * + */ +#include "slu_ddefs.h" + +int main(int argc, char *argv[]) +{ +/* + * Purpose + * ======= + * + * The driver program DLINSOLX1. + * + * This example illustrates how to use DGSSVX to solve systems with the same + * A but different right-hand side. + * In this case, we factorize A only once in the first call to DGSSVX, + * and reuse the following data structures in the subsequent call to DGSSVX: + * perm_c, perm_r, R, C, L, U. + * + */ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + double *a; + int *asub, *xa; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, m, n, nnz; + double *rhsb, *rhsx, *xact; + double *R, *C; + double *ferr, *berr; + double u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default values for options argument: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("DLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + dreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + dCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_D, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + dCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_D, SLU_GE); + dCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_D, SLU_GE); + xact = doubleMalloc(n * nrhs); + ldx = n; + dGenXtrue(n, nrhs, xact, ldx); + dFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (double *) SUPERLU_MALLOC(A.nrow * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (double *) SUPERLU_MALLOC(A.ncol * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* ONLY PERFORM THE LU DECOMPOSITION */ + B.ncol = 0; /* Indicate not to solve the system */ + dgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("LU factorization: dgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + /* ------------------------------------------------------------ + NOW WE SOLVE THE LINEAR SYSTEM USING THE FACTORED FORM OF A. + ------------------------------------------------------------*/ + options.Fact = FACTORED; /* Indicate the factored form of A is supplied. */ + B.ncol = nrhs; /* Set the number of right-hand side */ + + /* Initialize the statistics variables. */ + StatInit(&stat); + + dgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("Triangular solve: dgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + double *sol = (double*) ((DNformat*) X.Store)->nzval; + + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork == 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + +/* + * Parse command line options to get relaxed snode size, panel size, etc. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + double *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:u:e:t:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsolx2.c b/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsolx2.c new file mode 100644 index 00000000..da74969d --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsolx2.c @@ -0,0 +1,293 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 5.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + * Last update: July 10, 2015 + * + */ +#include "slu_ddefs.h" + +int main(int argc, char *argv[]) +{ +/* + * Purpose + * ======= + * + * The driver program DLINSOLX2. + * + * This example illustrates how to use DGSSVX to solve systems repeatedly + * with the same sparsity pattern of matrix A. + * In this case, the column permutation vector perm_c is computed once. + * The following data structures will be reused in the subsequent call to + * DGSSVX: perm_c, etree + * + */ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, A1, L, U; + SuperMatrix B, B1, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + double *a, *a1; + int *asub, *xa, *asub1, *xa1; + int *perm_r; /* row permutations from partial pivoting */ + int *perm_c; /* column permutation vector */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, j, m, n, nnz; + double *rhsb, *rhsb1, *rhsx, *xact; + double *R, *C; + double *ferr, *berr; + double u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("DLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + dreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + if ( !(a1 = doubleMalloc(nnz)) ) ABORT("Malloc fails for a1[]."); + if ( !(asub1 = intMalloc(nnz)) ) ABORT("Malloc fails for asub1[]."); + if ( !(xa1 = intMalloc(n+1)) ) ABORT("Malloc fails for xa1[]."); + for (i = 0; i < nnz; ++i) { + a1[i] = a[i]; + asub1[i] = asub[i]; + } + for (i = 0; i < n+1; ++i) xa1[i] = xa[i]; + + dCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_D, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsb1 = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb1[]."); + if ( !(rhsx = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + dCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_D, SLU_GE); + dCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_D, SLU_GE); + xact = doubleMalloc(n * nrhs); + ldx = n; + dGenXtrue(n, nrhs, xact, ldx); + dFillRHS(trans, nrhs, xact, ldx, &A, &B); + for (j = 0; j < nrhs; ++j) + for (i = 0; i < m; ++i) rhsb1[i+j*m] = rhsb[i+j*m]; + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(R = (double *) SUPERLU_MALLOC(A.nrow * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (double *) SUPERLU_MALLOC(A.ncol * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* ------------------------------------------------------------ + WE SOLVE THE LINEAR SYSTEM FOR THE FIRST TIME: AX = B + ------------------------------------------------------------*/ + dgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("First system: dgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + double *sol = (double*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + Destroy_CompCol_Matrix(&A); + Destroy_Dense_Matrix(&B); + if ( lwork >= 0 ) { /* Deallocate storage associated with L and U. */ + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } + + /* ------------------------------------------------------------ + NOW WE SOLVE ANOTHER LINEAR SYSTEM: A1*X = B1 + ONLY THE SPARSITY PATTERN OF A1 IS THE SAME AS THAT OF A. + ------------------------------------------------------------*/ + options.Fact = SamePattern; + StatInit(&stat); /* Initialize the statistics variables. */ + + dCreate_CompCol_Matrix(&A1, m, n, nnz, a1, asub1, xa1, + SLU_NC, SLU_D, SLU_GE); + dCreate_Dense_Matrix(&B1, m, nrhs, rhsb1, m, SLU_DN, SLU_D, SLU_GE); + + dgssvx(&options, &A1, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B1, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("\nSecond system: dgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + double *sol = (double*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A1); + Destroy_Dense_Matrix(&B1); + Destroy_Dense_Matrix(&X); + if ( lwork == 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + +/* + * Parse command line options to get relaxed snode size, panel size, etc. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + double *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:u:e:t:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsolx3.c b/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsolx3.c new file mode 100644 index 00000000..24325dce --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/dlinsolx3.c @@ -0,0 +1,288 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 5.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + * Last update: July 10, 2015 + * + */ +#include "slu_ddefs.h" + +int main(int argc, char *argv[]) +{ +/* + * Purpose + * ======= + * + * The driver program DLINSOLX2. + * + * This example illustrates how to use DGSSVX to solve systems repeatedly + * with the same sparsity pattern and similar values of matrix A. + * In this case, the permutation vectors perm_r and perm_c are computed once. + * The following data structures will be reused in the subsequent call to + * DGSSVX: perm_r, perm_c, etree, L, U. + * + */ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, A1, L, U; + SuperMatrix B, B1, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; + double *a, *a1; + int *asub, *xa, *asub1, *xa1; + int *perm_r; /* row permutations from partial pivoting */ + int *perm_c; /* column permutation vector */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, j, m, n, nnz; + double *rhsb, *rhsb1, *rhsx, *xact; + double *R, *C; + double *ferr, *berr; + double u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("DLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + dreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + if ( !(a1 = doubleMalloc(nnz)) ) ABORT("Malloc fails for a1[]."); + if ( !(asub1 = intMalloc(nnz)) ) ABORT("Malloc fails for asub1[]."); + if ( !(xa1 = intMalloc(n+1)) ) ABORT("Malloc fails for xa1[]."); + for (i = 0; i < nnz; ++i) { + a1[i] = a[i]; + asub1[i] = asub[i]; + } + for (i = 0; i < n+1; ++i) xa1[i] = xa[i]; + + dCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_D, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsb1 = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb1[]."); + if ( !(rhsx = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + dCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_D, SLU_GE); + dCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_D, SLU_GE); + xact = doubleMalloc(n * nrhs); + ldx = n; + dGenXtrue(n, nrhs, xact, ldx); + dFillRHS(trans, nrhs, xact, ldx, &A, &B); + for (j = 0; j < nrhs; ++j) + for (i = 0; i < m; ++i) rhsb1[i+j*m] = rhsb[i+j*m]; + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(R = (double *) SUPERLU_MALLOC(A.nrow * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (double *) SUPERLU_MALLOC(A.ncol * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* ------------------------------------------------------------ + WE SOLVE THE LINEAR SYSTEM FOR THE FIRST TIME: AX = B + ------------------------------------------------------------*/ + dgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("First system: dgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + double *sol = (double*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + Destroy_CompCol_Matrix(&A); + Destroy_Dense_Matrix(&B); + + /* ------------------------------------------------------------ + NOW WE SOLVE ANOTHER LINEAR SYSTEM: A1*X = B1 + ONLY THE SPARSITY PATTERN OF A1 IS THE SAME AS THAT OF A. + ------------------------------------------------------------*/ + options.Fact = SamePattern_SameRowPerm; + StatInit(&stat); /* Initialize the statistics variables. */ + + dCreate_CompCol_Matrix(&A1, m, n, nnz, a1, asub1, xa1, + SLU_NC, SLU_D, SLU_GE); + dCreate_Dense_Matrix(&B1, m, nrhs, rhsb1, m, SLU_DN, SLU_D, SLU_GE); + + dgssvx(&options, &A1, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B1, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("\nSecond system: dgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + double *sol = (double*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A1); + Destroy_Dense_Matrix(&B1); + Destroy_Dense_Matrix(&X); + if ( lwork == 0 ) { /* Deallocate storage associated with L and U. */ + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + +/* + * Parse command line options to get relaxed snode size, panel size, etc. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + double *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:u:e:t:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/fgmr.c b/src/Libraries/superlu-5.2.1/EXAMPLE/fgmr.c new file mode 100644 index 00000000..5d69b94a --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/fgmr.c @@ -0,0 +1,273 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +#include +#include +#include +#include +#include "slu_ddefs.h" + +#define epsmac 1.0e-16 +extern double ddot_(int *, double [], int *, double [], int *); +extern double dnrm2_(int *, double [], int *); +extern void daxpy_(int *, double *, double [], int *, double [], int *); +extern double dcopy_(int *, double [], int *, double [], int *); + +int fgmr(int n, + void (*matvec) (double, double[], double, double[]), + void (*psolve) (int, double[], double[]), + double *rhs, double *sol, double tol, int im, int *itmax, FILE * fits) +{ +/*---------------------------------------------------------------------- +| *** Preconditioned FGMRES *** ++----------------------------------------------------------------------- +| This is a simple version of the ARMS preconditioned FGMRES algorithm. ++----------------------------------------------------------------------- +| Y. S. Dec. 2000. -- Apr. 2008 ++----------------------------------------------------------------------- +| on entry: +|---------- +| +| rhs = real vector of length n containing the right hand side. +| sol = real vector of length n containing an initial guess to the +| solution on input. +| tol = tolerance for stopping iteration +| im = Krylov subspace dimension +| (itmax) = max number of iterations allowed. +| fits = NULL: no output +| != NULL: file handle to output " resid vs time and its" +| +| on return: +|---------- +| fgmr int = 0 --> successful return. +| int = 1 --> convergence not achieved in itmax iterations. +| sol = contains an approximate solution (upon successful return). +| itmax = has changed. It now contains the number of steps required +| to converge -- ++----------------------------------------------------------------------- +| internal work arrays: +|---------- +| vv = work array of length [im+1][n] (used to store the Arnoldi +| basis) +| hh = work array of length [im][im+1] (Householder matrix) +| z = work array of length [im][n] to store preconditioned vectors ++----------------------------------------------------------------------- +| subroutines called : +| matvec - matrix-vector multiplication operation +| psolve - (right) preconditionning operation +| psolve can be a NULL pointer (GMRES without preconditioner) ++---------------------------------------------------------------------*/ + + int maxits = *itmax; + int i, i1, ii, j, k, k1, its, retval, i_1 = 1; + double **hh, *c, *s, *rs, t, t0; + double beta, eps1 = 0.0, gam, **vv, **z; + + its = 0; + vv = (double **)SUPERLU_MALLOC((im + 1) * sizeof(double *)); + for (i = 0; i <= im; i++) + vv[i] = doubleMalloc(n); + z = (double **)SUPERLU_MALLOC(im * sizeof(double *)); + hh = (double **)SUPERLU_MALLOC(im * sizeof(double *)); + for (i = 0; i < im; i++) + { + hh[i] = doubleMalloc(i + 2); + z[i] = doubleMalloc(n); + } + c = doubleMalloc(im); + s = doubleMalloc(im); + rs = doubleMalloc(im + 1); + + /*---- outer loop starts here ----*/ + do + { + /*---- compute initial residual vector ----*/ + matvec(1.0, sol, 0.0, vv[0]); + for (j = 0; j < n; j++) + vv[0][j] = rhs[j] - vv[0][j]; /* vv[0]= initial residual */ + beta = dnrm2_(&n, vv[0], &i_1); + + /*---- print info if fits != null ----*/ + if (fits != NULL && its == 0) + fprintf(fits, "%8d %10.2e\n", its, beta); + /*if ( beta < tol * dnrm2_(&n, rhs, &i_1) )*/ + if ( !(beta >= tol * dnrm2_(&n, rhs, &i_1)) ) + break; + t = 1.0 / beta; + + /*---- normalize: vv[0] = vv[0] / beta ----*/ + for (j = 0; j < n; j++) + vv[0][j] = vv[0][j] * t; + if (its == 0) + eps1 = tol * beta; + + /*---- initialize 1-st term of rhs of hessenberg system ----*/ + rs[0] = beta; + for (i = 0; i < im; i++) + { + its++; + i1 = i + 1; + + /*------------------------------------------------------------ + | (Right) Preconditioning Operation z_{j} = M^{-1} v_{j} + +-----------------------------------------------------------*/ + if (psolve) + psolve(n, z[i], vv[i]); + else + dcopy_(&n, vv[i], &i_1, z[i], &i_1); + + /*---- matvec operation w = A z_{j} = A M^{-1} v_{j} ----*/ + matvec(1.0, z[i], 0.0, vv[i1]); + + /*------------------------------------------------------------ + | modified gram - schmidt... + | h_{i,j} = (w,v_{i}) + | w = w - h_{i,j} v_{i} + +------------------------------------------------------------*/ + t0 = dnrm2_(&n, vv[i1], &i_1); + for (j = 0; j <= i; j++) + { + double negt; + t = ddot_(&n, vv[j], &i_1, vv[i1], &i_1); + hh[i][j] = t; + negt = -t; + daxpy_(&n, &negt, vv[j], &i_1, vv[i1], &i_1); + } + + /*---- h_{j+1,j} = ||w||_{2} ----*/ + t = dnrm2_(&n, vv[i1], &i_1); + while (t < 0.5 * t0) + { + t0 = t; + for (j = 0; j <= i; j++) + { + double negt; + t = ddot_(&n, vv[j], &i_1, vv[i1], &i_1); + hh[i][j] += t; + negt = -t; + daxpy_(&n, &negt, vv[j], &i_1, vv[i1], &i_1); + } + t = dnrm2_(&n, vv[i1], &i_1); + } + hh[i][i1] = t; + if (t != 0.0) + { + /*---- v_{j+1} = w / h_{j+1,j} ----*/ + t = 1.0 / t; + for (k = 0; k < n; k++) + vv[i1][k] = vv[i1][k] * t; + } + /*--------------------------------------------------- + | done with modified gram schimdt and arnoldi step + | now update factorization of hh + +--------------------------------------------------*/ + + /*-------------------------------------------------------- + | perform previous transformations on i-th column of h + +-------------------------------------------------------*/ + for (k = 1; k <= i; k++) + { + k1 = k - 1; + t = hh[i][k1]; + hh[i][k1] = c[k1] * t + s[k1] * hh[i][k]; + hh[i][k] = -s[k1] * t + c[k1] * hh[i][k]; + } + gam = sqrt(pow(hh[i][i], 2) + pow(hh[i][i1], 2)); + + /*--------------------------------------------------- + | if gamma is zero then any small value will do + | affect only residual estimate + +--------------------------------------------------*/ + /* if (gam == 0.0) gam = epsmac; */ + + /*---- get next plane rotation ---*/ + if (gam > 0.0) + { + c[i] = hh[i][i] / gam; + s[i] = hh[i][i1] / gam; + } + else + { + c[i] = 1.0; + s[i] = 0.0; + } + rs[i1] = -s[i] * rs[i]; + rs[i] = c[i] * rs[i]; + + /*---------------------------------------------------- + | determine residual norm and test for convergence + +---------------------------------------------------*/ + hh[i][i] = c[i] * hh[i][i] + s[i] * hh[i][i1]; + beta = fabs(rs[i1]); + if (fits != NULL) + fprintf(fits, "%8d %10.2e\n", its, beta); + if (beta <= eps1 || its >= maxits) + break; + } + + if (i == im) i--; + /*---- now compute solution. 1st, solve upper triangular system ----*/ + rs[i] = rs[i] / hh[i][i]; + for (ii = 1; ii <= i; ii++) + { + k = i - ii; + k1 = k + 1; + t = rs[k]; + for (j = k1; j <= i; j++) + t = t - hh[j][k] * rs[j]; + rs[k] = t / hh[k][k]; + } + + /*---- linear combination of v[i]'s to get sol. ----*/ + for (j = 0; j <= i; j++) + { + t = rs[j]; + for (k = 0; k < n; k++) + sol[k] += t * z[j][k]; + } + + /* calculate the residual and output */ + matvec(1.0, sol, 0.0, vv[0]); + for (j = 0; j < n; j++) + vv[0][j] = rhs[j] - vv[0][j]; /* vv[0]= initial residual */ + + /*---- print info if fits != null ----*/ + beta = dnrm2_(&n, vv[0], &i_1); + + /*---- restart outer loop if needed ----*/ + /*if (beta >= eps1 / tol)*/ + if ( !(beta < eps1 / tol) ) + { + its = maxits + 10; + break; + } + if (beta <= eps1) + break; + } while(its < maxits); + + retval = (its >= maxits); + for (i = 0; i <= im; i++) + SUPERLU_FREE(vv[i]); + SUPERLU_FREE(vv); + for (i = 0; i < im; i++) + { + SUPERLU_FREE(hh[i]); + SUPERLU_FREE(z[i]); + } + SUPERLU_FREE(hh); + SUPERLU_FREE(z); + SUPERLU_FREE(c); + SUPERLU_FREE(s); + SUPERLU_FREE(rs); + + *itmax = its; + + return retval; +} /*----end of fgmr ----*/ diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/g20.rua b/src/Libraries/superlu-5.2.1/EXAMPLE/g20.rua new file mode 100644 index 00000000..382c9c43 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/g20.rua @@ -0,0 +1,534 @@ +g20, symm permuted by SYMMMD SYM + 530 26 120 384 0 +RUA 400 400 1920 0 +(16I5) (16I5) (5E15.8) (5E15.8) + 1 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 + 81 86 91 96 101 106 111 116 121 126 131 136 141 146 151 156 + 161 166 171 176 181 186 191 196 201 206 210 214 218 223 228 231 + 235 239 243 248 253 257 262 266 271 276 281 286 291 295 300 304 + 309 313 318 323 328 332 337 342 347 352 357 362 367 372 377 382 + 387 392 397 402 407 412 417 422 427 432 437 442 447 452 457 462 + 467 472 477 482 487 492 497 501 505 510 514 519 524 529 534 539 + 544 549 554 559 564 568 572 576 580 583 588 593 597 601 606 610 + 614 619 624 629 634 639 644 649 654 659 664 669 674 678 682 686 + 691 696 701 706 710 714 718 723 728 732 737 742 747 752 757 762 + 767 772 777 781 786 791 796 800 805 810 815 820 825 830 835 839 + 844 849 854 859 864 869 874 879 884 889 894 899 904 909 914 919 + 923 928 932 937 941 946 951 956 961 966 971 976 981 986 991 996 + 1001 1006 1011 1015 1020 1024 1029 1033 1038 1043 1048 1053 1058 1063 1068 1073 + 1078 1083 1088 1093 1098 1103 1108 1113 1117 1122 1126 1130 1133 1138 1142 1147 + 1152 1156 1161 1165 1170 1174 1179 1183 1188 1193 1198 1203 1208 1212 1217 1221 + 1226 1230 1235 1240 1245 1249 1254 1259 1264 1269 1274 1279 1284 1288 1293 1298 + 1303 1308 1313 1317 1322 1327 1332 1337 1342 1347 1352 1357 1362 1367 1372 1377 + 1382 1387 1392 1397 1402 1407 1412 1417 1422 1427 1432 1437 1442 1446 1451 1455 + 1459 1464 1468 1472 1477 1482 1487 1492 1497 1501 1506 1510 1515 1519 1522 1526 + 1530 1535 1539 1544 1549 1554 1559 1563 1568 1573 1578 1583 1587 1592 1596 1601 + 1605 1610 1615 1620 1625 1630 1635 1640 1645 1650 1655 1660 1665 1670 1674 1679 + 1684 1689 1694 1699 1704 1709 1714 1719 1724 1729 1734 1738 1743 1748 1753 1758 + 1763 1768 1773 1778 1783 1788 1792 1797 1802 1807 1811 1816 1821 1826 1831 1836 + 1841 1846 1851 1856 1861 1866 1871 1876 1881 1886 1891 1896 1901 1906 1911 1916 + 1921 + 1 9 32 391 395 2 9 392 395 400 3 8 389 393 394 4 + 8 9 392 394 5 7 8 381 389 6 7 8 9 32 5 6 + 7 33 382 3 4 5 6 8 1 2 4 6 9 10 31 396 + 398 399 11 18 29 30 31 12 18 31 397 399 13 17 386 387 + 388 14 17 18 30 387 15 17 383 388 390 16 17 18 390 397 + 13 14 15 16 17 11 12 14 16 18 19 28 33 380 382 20 + 22 28 29 33 21 22 29 31 398 20 21 22 32 391 23 27 + 379 384 385 24 27 28 379 380 25 27 30 385 387 26 27 28 + 29 30 23 24 25 26 27 19 20 24 26 28 11 20 21 26 + 29 11 14 25 26 30 10 11 12 21 31 1 6 22 32 33 + 7 19 20 32 33 34 74 92 370 372 35 40 70 174 176 36 + 40 91 174 177 37 39 40 70 71 38 39 40 90 91 37 38 + 39 74 92 35 36 37 38 40 41 56 70 71 73 42 44 55 + 56 43 44 175 176 42 43 44 45 44 45 56 70 176 46 54 + 55 56 73 47 49 53 48 49 54 55 47 48 49 52 50 51 + 53 69 50 51 52 68 72 49 51 52 53 54 47 50 52 53 + 46 48 52 54 72 42 46 48 55 41 42 45 46 56 57 59 + 67 68 72 58 59 67 74 372 57 58 59 71 73 60 66 67 + 372 373 61 62 65 69 61 62 66 67 68 63 64 65 374 63 + 64 66 371 373 61 63 65 66 60 62 64 65 66 57 58 60 + 62 67 51 57 62 68 69 50 61 68 69 35 37 41 45 70 + 37 41 59 71 74 51 54 57 72 73 41 46 59 72 73 34 + 39 58 71 74 75 89 369 381 389 76 78 92 370 375 77 78 + 89 369 375 76 77 78 88 90 79 87 91 177 178 80 87 88 + 90 91 81 86 87 173 178 82 86 173 379 380 83 85 86 87 + 88 84 85 86 380 382 83 84 85 89 381 81 82 83 84 86 + 79 80 81 83 87 78 80 83 88 89 75 77 85 88 89 38 + 78 80 90 92 36 38 79 80 91 34 39 76 90 92 93 172 + 385 386 387 94 98 168 169 170 95 98 169 172 386 96 98 109 + 170 171 97 98 109 386 388 94 95 96 97 98 99 108 377 383 + 390 100 108 376 377 378 101 107 109 167 171 102 107 109 383 388 + 103 106 107 167 104 106 108 378 105 106 107 108 383 103 104 105 + 106 101 102 103 105 107 99 100 104 105 108 96 97 101 102 109 + 110 166 173 379 384 111 132 138 162 164 112 132 138 168 169 113 + 131 132 163 164 114 130 131 132 168 115 129 130 168 170 116 123 + 128 129 130 117 121 123 128 118 120 131 163 119 120 121 123 118 + 119 120 122 117 119 121 120 122 123 130 131 116 117 119 122 123 + 124 127 128 129 125 127 167 171 126 127 129 170 171 124 125 126 + 127 116 117 124 128 115 116 124 126 129 114 115 116 122 130 113 + 114 118 122 131 111 112 113 114 132 133 137 138 162 165 134 137 + 165 166 384 135 137 138 169 172 136 137 172 384 385 133 134 135 + 136 137 111 112 133 135 138 139 145 174 175 176 140 145 161 174 + 177 141 143 145 175 142 143 153 160 141 142 143 144 143 144 145 + 160 161 139 140 141 144 145 146 152 153 159 160 147 152 159 162 + 165 148 150 152 153 149 150 163 164 148 149 150 151 150 151 152 + 162 164 146 147 148 151 152 142 146 148 153 154 158 159 160 161 + 155 158 161 177 178 156 158 159 165 166 157 158 166 173 178 154 + 155 156 157 158 146 147 154 156 159 142 144 146 154 160 140 144 + 154 155 161 111 133 147 151 162 113 118 149 163 111 113 149 151 + 164 133 134 147 156 165 110 134 156 157 166 101 103 125 167 94 + 112 114 115 168 94 95 112 135 169 94 96 115 126 170 96 101 + 125 126 171 93 95 135 136 172 81 82 110 157 173 35 36 139 + 140 174 43 139 141 175 35 43 45 139 176 36 79 140 155 177 + 79 81 155 157 178 179 183 201 369 375 180 183 200 201 274 181 + 183 369 389 393 182 183 272 274 393 179 180 181 182 183 184 188 + 370 372 373 185 188 199 371 373 186 188 201 370 375 187 188 199 + 200 201 184 185 186 187 188 189 198 200 274 277 190 198 273 276 + 277 191 197 198 199 200 192 193 196 374 192 193 197 199 371 194 + 195 196 275 194 195 197 198 276 192 194 196 197 191 193 195 196 + 197 189 190 191 195 198 185 187 191 193 199 180 187 189 191 200 + 179 180 186 187 201 202 271 272 393 394 203 207 272 274 277 204 + 207 218 273 277 205 207 267 271 272 206 207 218 266 267 203 204 + 205 206 207 208 217 218 266 268 209 217 265 268 270 210 216 217 + 218 273 211 212 215 275 211 212 216 273 276 213 214 215 269 213 + 214 216 217 270 211 213 215 216 210 212 214 215 216 208 209 210 + 214 217 204 206 208 210 218 219 223 271 392 394 220 223 229 267 + 271 221 223 365 392 400 222 223 229 365 366 219 220 221 222 223 + 224 228 229 266 267 225 228 263 266 268 226 228 229 264 366 227 + 228 262 263 264 224 225 226 227 228 220 222 224 226 229 230 249 + 263 265 268 231 239 248 249 265 232 233 238 269 232 233 239 265 + 270 234 236 237 238 235 236 237 247 234 235 236 234 235 237 239 + 248 232 234 238 239 231 233 237 238 239 240 246 249 262 263 241 + 242 245 247 241 242 246 248 249 243 244 245 261 243 244 246 260 + 262 241 243 245 246 240 242 244 245 246 235 241 247 248 231 237 + 242 247 248 230 231 240 242 249 250 259 264 364 366 251 259 260 + 262 264 252 258 259 364 367 253 254 257 261 253 254 258 259 260 + 255 256 257 363 255 256 258 367 368 253 255 257 258 252 254 256 + 257 258 250 251 252 254 259 244 251 254 260 261 243 253 260 261 + 227 240 244 251 262 225 227 230 240 263 226 227 250 251 264 209 + 230 231 233 265 206 208 224 225 266 205 206 220 224 267 208 209 + 225 230 268 213 232 269 270 209 214 233 269 270 202 205 219 220 + 271 182 202 203 205 272 190 204 210 212 273 180 182 189 203 274 + 194 211 275 276 190 195 212 275 276 189 190 203 204 277 278 283 + 289 395 400 279 283 289 361 362 280 282 283 391 395 281 282 283 + 359 361 280 281 282 396 398 278 279 280 281 283 284 288 289 365 + 400 285 288 364 365 366 286 288 289 360 362 287 288 360 364 367 + 284 285 286 287 288 278 279 284 286 289 290 292 298 396 399 291 + 292 298 355 357 290 291 292 358 359 293 297 377 390 397 294 297 + 298 397 399 295 297 356 376 377 296 297 298 355 356 293 294 295 + 296 297 290 291 294 296 298 299 328 351 355 357 300 308 328 355 + 356 301 307 326 327 302 307 308 326 328 303 306 376 378 304 306 + 307 308 305 306 308 356 376 303 304 305 306 301 302 304 307 300 + 302 304 305 308 309 311 326 328 351 310 311 324 326 327 309 310 + 311 325 353 312 323 325 352 353 313 314 322 350 313 314 323 352 + 354 315 316 320 322 315 316 321 323 325 317 319 324 327 318 319 + 320 317 318 319 321 315 318 320 321 316 319 320 321 324 313 315 + 322 323 312 314 316 322 323 310 317 321 324 325 311 312 316 324 + 325 301 302 309 310 326 301 310 317 327 299 300 302 309 328 329 + 338 349 360 362 330 338 360 367 368 331 337 338 348 349 332 333 + 336 363 332 333 337 338 368 334 335 336 350 334 335 337 348 354 + 332 334 336 337 331 333 335 336 337 329 330 331 333 338 339 347 + 358 359 361 340 347 349 361 362 341 346 347 348 349 342 346 348 + 352 354 343 345 346 347 358 344 345 346 352 353 343 344 345 351 + 357 341 342 343 344 346 339 340 341 343 347 331 335 341 342 348 + 329 331 340 341 349 313 334 350 354 299 309 345 351 353 312 314 + 342 344 352 311 312 344 351 353 314 335 342 350 354 291 296 299 + 300 355 295 296 300 305 356 291 299 345 357 358 292 339 343 357 + 358 281 292 339 359 396 286 287 329 330 360 279 281 339 340 361 + 279 286 329 340 362 255 332 363 368 250 252 285 287 364 221 222 + 284 285 365 222 226 250 285 366 252 256 287 330 367 256 330 333 + 363 368 75 77 179 181 369 34 76 184 186 370 64 185 193 371 + 374 34 58 60 184 372 60 64 184 185 373 63 192 371 374 76 + 77 179 186 375 100 295 303 305 376 99 100 293 295 377 100 104 + 303 378 23 24 82 110 379 19 24 82 84 380 5 75 85 381 + 382 7 19 84 381 382 15 99 102 105 383 23 110 134 136 384 + 23 25 93 136 385 13 93 95 97 386 13 14 25 93 387 13 + 15 97 102 388 3 5 75 181 389 15 16 99 293 390 1 22 + 280 391 398 2 4 219 221 392 3 181 182 202 393 3 4 202 + 219 394 1 2 278 280 395 10 282 290 359 396 12 16 293 294 + 397 10 21 282 391 398 10 12 290 294 399 2 221 278 284 400 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 +-1.00000000E+00 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 + 4.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00-1.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 +-1.00000000E+00-1.00000000E+00-1.00000000E+00-1.00000000E+00 4.00000000E+00 diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/sfgmr.c b/src/Libraries/superlu-5.2.1/EXAMPLE/sfgmr.c new file mode 100644 index 00000000..e332c69c --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/sfgmr.c @@ -0,0 +1,308 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sfgmr.c + * \brief flexible GMRES from ITSOL developed by Yousef Saad. + */ + +/* ITSOL COPYRIGHT + +Copyright (C) 2006, the University of Minnesota + +ITSOL is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation [version 2 of the License, or any later version] +For details, see + +http://www.gnu.org/copyleft/gpl.html + +A copy of the GNU licencing agreement is attached to the ITSOL package +in the file GNU. For additional information contact the Free Software +Foundation Inc., 65 Mass Ave, Cambridge, MA 02139, USA. + +DISCLAIMER +---------- + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +For information on ITSOL contact saad@cs.umn.edu +*/ + +#include "slu_sdefs.h" + +#define epsmac 1.0e-16 + +extern float sdot_(int *, float [], int *, float [], int *); +extern float snrm2_(int *, float [], int *); + + +int sfgmr(int n, + void (*smatvec) (float, float[], float, float[]), + void (*spsolve) (int, float[], float[]), + float *rhs, float *sol, double tol, int im, int *itmax, FILE * fits) +{ +/*---------------------------------------------------------------------- +| *** Preconditioned FGMRES *** ++----------------------------------------------------------------------- +| This is a simple version of the ARMS preconditioned FGMRES algorithm. ++----------------------------------------------------------------------- +| Y. S. Dec. 2000. -- Apr. 2008 ++----------------------------------------------------------------------- +| on entry: +|---------- +| +| rhs = real vector of length n containing the right hand side. +| sol = real vector of length n containing an initial guess to the +| solution on input. +| tol = tolerance for stopping iteration +| im = Krylov subspace dimension +| (itmax) = max number of iterations allowed. +| fits = NULL: no output +| != NULL: file handle to output " resid vs time and its" +| +| on return: +|---------- +| fgmr int = 0 --> successful return. +| int = 1 --> convergence not achieved in itmax iterations. +| sol = contains an approximate solution (upon successful return). +| itmax = has changed. It now contains the number of steps required +| to converge -- ++----------------------------------------------------------------------- +| internal work arrays: +|---------- +| vv = work array of length [im+1][n] (used to store the Arnoldi +| basis) +| hh = work array of length [im][im+1] (Householder matrix) +| z = work array of length [im][n] to store preconditioned vectors ++----------------------------------------------------------------------- +| subroutines called : +| matvec - matrix-vector multiplication operation +| psolve - (right) preconditionning operation +| psolve can be a NULL pointer (GMRES without preconditioner) ++---------------------------------------------------------------------*/ + + int maxits = *itmax; + int i, i1, ii, j, k, k1, its, retval, i_1 = 1, i_2 = 2; + float beta, eps1 = 0.0, t, t0, gam; + float **hh, *c, *s, *rs; + float **vv, **z, tt; + float zero = 0.0; + float one = 1.0; + + its = 0; + vv = (float **)SUPERLU_MALLOC((im + 1) * sizeof(float *)); + for (i = 0; i <= im; i++) vv[i] = floatMalloc(n); + z = (float **)SUPERLU_MALLOC(im * sizeof(float *)); + hh = (float **)SUPERLU_MALLOC(im * sizeof(float *)); + for (i = 0; i < im; i++) + { + hh[i] = floatMalloc(i + 2); + z[i] = floatMalloc(n); + } + c = floatMalloc(im); + s = floatMalloc(im); + rs = floatMalloc(im + 1); + + /*---- outer loop starts here ----*/ + do + { + /*---- compute initial residual vector ----*/ + smatvec(one, sol, zero, vv[0]); + for (j = 0; j < n; j++) + vv[0][j] = rhs[j] - vv[0][j]; /* vv[0]= initial residual */ + beta = snrm2_(&n, vv[0], &i_1); + + /*---- print info if fits != null ----*/ + if (fits != NULL && its == 0) + fprintf(fits, "%8d %10.2e\n", its, beta); + /*if ( beta <= tol * dnrm2_(&n, rhs, &i_1) )*/ + if ( !(beta > tol * snrm2_(&n, rhs, &i_1)) ) + break; + t = 1.0 / beta; + + /*---- normalize: vv[0] = vv[0] / beta ----*/ + for (j = 0; j < n; j++) + vv[0][j] = vv[0][j] * t; + if (its == 0) + eps1 = tol * beta; + + /*---- initialize 1-st term of rhs of hessenberg system ----*/ + rs[0] = beta; + for (i = 0; i < im; i++) + { + its++; + i1 = i + 1; + + /*------------------------------------------------------------ + | (Right) Preconditioning Operation z_{j} = M^{-1} v_{j} + +-----------------------------------------------------------*/ + if (spsolve) + spsolve(n, z[i], vv[i]); + else + scopy_(&n, vv[i], &i_1, z[i], &i_1); + + /*---- matvec operation w = A z_{j} = A M^{-1} v_{j} ----*/ + smatvec(one, z[i], zero, vv[i1]); + + /*------------------------------------------------------------ + | modified gram - schmidt... + | h_{i,j} = (w,v_{i}) + | w = w - h_{i,j} v_{i} + +------------------------------------------------------------*/ + t0 = snrm2_(&n, vv[i1], &i_1); + for (j = 0; j <= i; j++) + { + float negt; + tt = sdot_(&n, vv[j], &i_1, vv[i1], &i_1); + hh[i][j] = tt; + negt = -tt; + saxpy_(&n, &negt, vv[j], &i_1, vv[i1], &i_1); + } + + /*---- h_{j+1,j} = ||w||_{2} ----*/ + t = snrm2_(&n, vv[i1], &i_1); + while (t < 0.5 * t0) + { + t0 = t; + for (j = 0; j <= i; j++) + { + float negt; + tt = sdot_(&n, vv[j], &i_1, vv[i1], &i_1); + hh[i][j] += tt; + negt = -tt; + saxpy_(&n, &negt, vv[j], &i_1, vv[i1], &i_1); + } + t = snrm2_(&n, vv[i1], &i_1); + } + + hh[i][i1] = t; + + if (t != 0.0) + { + /*---- v_{j+1} = w / h_{j+1,j} ----*/ + t = 1.0 / t; + for (k = 0; k < n; k++) + vv[i1][k] = vv[i1][k] * t; + } + /*--------------------------------------------------- + | done with modified gram schimdt and arnoldi step + | now update factorization of hh + +--------------------------------------------------*/ + + /*-------------------------------------------------------- + | perform previous transformations on i-th column of h + +-------------------------------------------------------*/ + for (k = 1; k <= i; k++) + { + k1 = k - 1; + tt = hh[i][k1]; + hh[i][k1] = c[k1] * tt + s[k1] * hh[i][k]; + hh[i][k] = -s[k1] * tt + c[k1] * hh[i][k]; + } + + gam = sqrt(pow(hh[i][i], 2) + pow(hh[i][i1], 2)); + + /*--------------------------------------------------- + | if gamma is zero then any small value will do + | affect only residual estimate + +--------------------------------------------------*/ + /* if (gam == 0.0) gam = epsmac; */ + + /*---- get next plane rotation ---*/ + if (gam == 0.0) + { + c[i] = one; + s[i] = zero; + } + else + { + c[i] = hh[i][i] / gam; + s[i] = hh[i][i1] / gam; + } + + rs[i1] = -s[i] * rs[i]; + rs[i] = c[i] * rs[i]; + + /*---------------------------------------------------- + | determine residual norm and test for convergence + +---------------------------------------------------*/ + hh[i][i] = c[i] * hh[i][i] + s[i] * hh[i][i1]; + beta = fabs(rs[i1]); + if (fits != NULL) + fprintf(fits, "%8d %10.2e\n", its, beta); + if (beta <= eps1 || its >= maxits) + break; + } + + if (i == im) i--; + + /*---- now compute solution. 1st, solve upper triangular system ----*/ + rs[i] = rs[i] / hh[i][i]; + + for (ii = 1; ii <= i; ii++) + { + k = i - ii; + k1 = k + 1; + tt = rs[k]; + for (j = k1; j <= i; j++) + tt = tt - hh[j][k] * rs[j]; + rs[k] = tt / hh[k][k]; + } + + /*---- linear combination of v[i]'s to get sol. ----*/ + for (j = 0; j <= i; j++) + { + tt = rs[j]; + for (k = 0; k < n; k++) + sol[k] += tt * z[j][k]; + } + + /* calculate the residual and output */ + smatvec(one, sol, zero, vv[0]); + for (j = 0; j < n; j++) + vv[0][j] = rhs[j] - vv[0][j]; /* vv[0]= initial residual */ + + /*---- print info if fits != null ----*/ + beta = snrm2_(&n, vv[0], &i_1); + + /*---- restart outer loop if needed ----*/ + /*if (beta >= eps1 / tol)*/ + if ( !(beta < eps1 / tol) ) + { + its = maxits + 10; + break; + } + if (beta <= eps1) + break; + } while(its < maxits); + + retval = (its >= maxits); + for (i = 0; i <= im; i++) + SUPERLU_FREE(vv[i]); + SUPERLU_FREE(vv); + for (i = 0; i < im; i++) + { + SUPERLU_FREE(hh[i]); + SUPERLU_FREE(z[i]); + } + SUPERLU_FREE(hh); + SUPERLU_FREE(z); + SUPERLU_FREE(c); + SUPERLU_FREE(s); + SUPERLU_FREE(rs); + + *itmax = its; + + return retval; +} /*----end of fgmr ----*/ diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/sitersol.c b/src/Libraries/superlu-5.2.1/EXAMPLE/sitersol.c new file mode 100644 index 00000000..3e3c75f6 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/sitersol.c @@ -0,0 +1,384 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sitersol.c + * \brief Example #1 showing how to use ILU to precondition GMRES + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Lawrence Berkeley National Laboratory
+ * November, 2010
+ * August, 2011
+ *
+ * This example shows that ILU is computed from the equilibrated matrix,
+ * and the preconditioned GMRES is applied to the equilibrated system.
+ * The driver routine SGSISX is called twice to perform factorization
+ * and apply preconditioner separately.
+ * 
+ * Note that SGSISX performs the following factorization:
+ *     Pr*Dr*A*Dc*Pc^T ~= LU
+ * with Pr being obtained from MC64 statically then partial pivoting
+ * dynamically. On return, A is overwritten as A1 = Dr*A*Dc.
+ *
+ * We can solve the transformed system, A1*y = Dr*B, using FGMRES.
+ * B is first overwritten as Dr*B.
+ * Then GMRES step requires requires 2 procedures:
+ *   1) Apply preconditioner M^{-1} = Pc^T*U^{-1}*L^{-1}*Pr
+ *   2) Matrix-vector multiplication: w = A1*v
+ * 
+ * 
+ */ + +#include "slu_sdefs.h" + +superlu_options_t *GLOBAL_OPTIONS; +float *GLOBAL_R, *GLOBAL_C; +int *GLOBAL_PERM_C, *GLOBAL_PERM_R; +SuperMatrix *GLOBAL_A, *GLOBAL_L, *GLOBAL_U; +SuperLUStat_t *GLOBAL_STAT; +mem_usage_t *GLOBAL_MEM_USAGE; + +void spsolve(int n, + float x[], /* solution */ + float y[] /* right-hand side */ +) +{ + SuperMatrix *A = GLOBAL_A, *L = GLOBAL_L, *U = GLOBAL_U; + SuperLUStat_t *stat = GLOBAL_STAT; + int *perm_c = GLOBAL_PERM_C, *perm_r = GLOBAL_PERM_R; + char equed[1] = {'N'}; + float *R = GLOBAL_R, *C = GLOBAL_C; + superlu_options_t *options = GLOBAL_OPTIONS; + mem_usage_t *mem_usage = GLOBAL_MEM_USAGE; + int info; + static DNformat X, Y; + static SuperMatrix XX = {SLU_DN, SLU_S, SLU_GE, 1, 1, &X}; + static SuperMatrix YY = {SLU_DN, SLU_S, SLU_GE, 1, 1, &Y}; + float rpg, rcond; + + XX.nrow = YY.nrow = n; + X.lda = Y.lda = n; + X.nzval = x; + Y.nzval = y; + +#if 0 + dcopy_(&n, y, &i_1, x, &i_1); + sgstrs(NOTRANS, L, U, perm_c, perm_r, &XX, stat, &info); +#else + sgsisx(options, A, perm_c, perm_r, NULL, equed, R, C, + L, U, NULL, 0, &YY, &XX, &rpg, &rcond, NULL, + mem_usage, stat, &info); +#endif +} + +void smatvec_mult(float alpha, float x[], float beta, float y[]) +{ + SuperMatrix *A = GLOBAL_A; + + sp_sgemv("N", alpha, A, x, 1, beta, y, 1); +} + +int main(int argc, char *argv[]) +{ + void smatvec_mult(float alpha, float x[], float beta, float y[]); + void spsolve(int n, float x[], float y[]); + extern int sfgmr( int n, + void (*matvec_mult)(float, float [], float, float []), + void (*psolve)(int n, float [], float[]), + float *rhs, float *sol, double tol, int restrt, int *itmax, + FILE *fits); + extern int sfill_diag(int n, NCformat *Astore); + + char equed[1] = {'B'}; + yes_no_t equil; + trans_t trans; + SuperMatrix A, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + float *a; + int *asub, *xa; + int *etree; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + int nrhs, ldx, lwork, info, m, n, nnz; + float *rhsb, *rhsx, *xact; + float *work = NULL; + float *R, *C; + float u, rpg, rcond; + float zero = 0.0; + float one = 1.0; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + int restrt, iter, maxit, i; + double resid; + float *x, *b; + +#ifdef DEBUG + extern int num_drop_L, num_drop_U; +#endif + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 0.1; //different from complete LU + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + options.RowPerm = LargeDiag; + options.ILU_DropTol = 1e-4; + options.ILU_FillTol = 1e-2; + options.ILU_FillFactor = 10.0; + options.ILU_DropRule = DROP_BASIC | DROP_AREA; + options.ILU_Norm = INF_NORM; + options.ILU_MILU = SILU; + */ + ilu_set_default_options(&options); + + /* Modify the defaults. */ + options.PivotGrowth = YES; /* Compute reciprocal pivot growth */ + options.ConditionNumber = YES;/* Compute reciprocal condition number */ + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) ABORT("Malloc fails for work[]."); + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + if (argc < 2) + { + printf("Usage:\n%s [OPTION] < [INPUT] > [OUTPUT]\nOPTION:\n" + "-h -hb:\n\t[INPUT] is a Harwell-Boeing format matrix.\n" + "-r -rb:\n\t[INPUT] is a Rutherford-Boeing format matrix.\n" + "-t -triplet:\n\t[INPUT] is a triplet format matrix.\n", + argv[0]); + return 0; + } + else + { + switch (argv[1][1]) + { + case 'H': + case 'h': + printf("Input a Harwell-Boeing format matrix:\n"); + sreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + break; + case 'R': + case 'r': + printf("Input a Rutherford-Boeing format matrix:\n"); + sreadrb(&m, &n, &nnz, &a, &asub, &xa); + break; + case 'T': + case 't': + printf("Input a triplet format matrix:\n"); + sreadtriple(&m, &n, &nnz, &a, &asub, &xa); + break; + default: + printf("Unrecognized format.\n"); + return 0; + } + } + + sCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, + SLU_NC, SLU_S, SLU_GE); + Astore = A.Store; + sfill_diag(n, Astore); + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + fflush(stdout); + + /* Generate the right-hand side */ + if ( !(rhsb = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + sCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_S, SLU_GE); + sCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_S, SLU_GE); + xact = floatMalloc(n * nrhs); + ldx = n; + sGenXtrue(n, nrhs, xact, ldx); + sFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (float *) SUPERLU_MALLOC(A.nrow * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (float *) SUPERLU_MALLOC(A.ncol * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + + info = 0; +#ifdef DEBUG + num_drop_L = 0; + num_drop_U = 0; +#endif + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* Compute the incomplete factorization and compute the condition number + and pivot growth using dgsisx. */ + B.ncol = 0; /* not to perform triangular solution */ + sgsisx(&options, &A, perm_c, perm_r, etree, equed, R, C, &L, &U, work, + lwork, &B, &X, &rpg, &rcond, &Glu, &mem_usage, &stat, &info); + + /* Set RHS for GMRES. */ + if (!(b = floatMalloc(m))) ABORT("Malloc fails for b[]."); + if (*equed == 'R' || *equed == 'B') { + for (i = 0; i < n; ++i) b[i] = rhsb[i] * R[i]; + } else { + for (i = 0; i < m; i++) b[i] = rhsb[i]; + } + + printf("sgsisx(): info %d, equed %c\n", info, equed[0]); + if (info > 0 || rcond < 1e-8 || rpg > 1e8) + printf("WARNING: This preconditioner might be unstable.\n"); + + if ( info == 0 || info == n+1 ) { + if ( options.PivotGrowth == YES ) + printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber == YES ) + printf("Recip. condition number = %e\n", rcond); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("n(A) = %d, nnz(A) = %d\n", n, Astore->nnz); + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("Fill ratio: nnz(F)/nnz(A) = %.3f\n", + ((double)(Lstore->nnz) + (double)(Ustore->nnz) - (double)n) + / (double)Astore->nnz); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + fflush(stdout); + + /* Set the global variables. */ + GLOBAL_A = &A; + GLOBAL_L = &L; + GLOBAL_U = &U; + GLOBAL_STAT = &stat; + GLOBAL_PERM_C = perm_c; + GLOBAL_PERM_R = perm_r; + GLOBAL_OPTIONS = &options; + GLOBAL_R = R; + GLOBAL_C = C; + GLOBAL_MEM_USAGE = &mem_usage; + + /* Set the options to do solve-only. */ + options.Fact = FACTORED; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + + /* Set the variables used by GMRES. */ + restrt = SUPERLU_MIN(n / 3 + 1, 50); + maxit = 1000; + iter = maxit; + resid = 1e-4; + if (!(x = floatMalloc(n))) ABORT("Malloc fails for x[]."); + + if (info <= n + 1) + { + int i_1 = 1; + double maxferr = 0.0, nrmA, nrmB, res, t; + float temp; + extern float snrm2_(int *, float [], int *); + extern void saxpy_(int *, float *, float [], int *, float [], int *); + + /* Initial guess */ + for (i = 0; i < n; i++) x[i] = zero; + + t = SuperLU_timer_(); + + /* Call GMRES */ + sfgmr(n, smatvec_mult, spsolve, b, x, resid, restrt, &iter, stdout); + + t = SuperLU_timer_() - t; + + /* Output the result. */ + nrmA = snrm2_(&(Astore->nnz), (float *)((DNformat *)A.Store)->nzval, + &i_1); + nrmB = snrm2_(&m, b, &i_1); + sp_sgemv("N", -1.0, &A, x, 1, 1.0, b, 1); + res = snrm2_(&m, b, &i_1); + resid = res / nrmB; + printf("||A||_F = %.1e, ||B||_2 = %.1e, ||B-A*X||_2 = %.1e, " + "relres = %.1e\n", nrmA, nrmB, res, resid); + + if (iter >= maxit) + { + if (resid >= 1.0) iter = -180; + else if (resid > 1e-8) iter = -111; + } + printf("iteration: %d\nresidual: %.1e\nGMRES time: %.2f seconds.\n", + iter, resid, t); + + /* Scale the solution back if equilibration was performed. */ + if (*equed == 'C' || *equed == 'B') + for (i = 0; i < n; i++) x[i] *= C[i]; + + for (i = 0; i < m; i++) { + maxferr = SUPERLU_MAX(maxferr, fabs(x[i] - xact[i])); + } + printf("||X-X_true||_oo = %.1e\n", maxferr); + } +#ifdef DEBUG + printf("%d entries in L and %d entries in U dropped.\n", + num_drop_L, num_drop_U); +#endif + fflush(stdout); + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork >= 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } + SUPERLU_FREE(b); + SUPERLU_FREE(x); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/sitersol1.c b/src/Libraries/superlu-5.2.1/EXAMPLE/sitersol1.c new file mode 100644 index 00000000..a1749845 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/sitersol1.c @@ -0,0 +1,393 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sitersol1.c + * \brief Example #2 showing how to use ILU to precondition GMRES + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Lawrence Berkeley National Laboratory
+ * November, 2010
+ * August, 2011
+ *
+ * This example shows that ILU is computed from the equilibrated matrix,
+ * but the preconditioned GMRES is applied to the original system.
+ * The driver routine SGSISX is called twice to perform factorization
+ * and apply preconditioner separately.
+ * 
+ * Note that SGSISX performs the following factorization:
+ *     Pr*Dr*A*Dc*Pc^T ~= LU
+ * with Pr being obtained from MC64 statically then partial pivoting
+ * dynamically. On return, A is overwritten as A1 = Dr*A*Dc.
+ *
+ * We need to save a copy of the original matrix A, then solve
+ * the original system, A*x = B, using FGMRES.
+ * Each GMRES step requires requires 2 procedures:
+ *   1) Apply preconditioner M^{-1} = Dc*Pc^T*U^{-1}*L^{-1}*Pr*Dr
+ *   2) Matrix-vector multiplication: w = A*v
+ *
+ * 
+ */ + +#include "slu_sdefs.h" + +char *GLOBAL_EQUED; +superlu_options_t *GLOBAL_OPTIONS; +float *GLOBAL_R, *GLOBAL_C; +int *GLOBAL_PERM_C, *GLOBAL_PERM_R; +SuperMatrix *GLOBAL_A, *GLOBAL_A_ORIG, *GLOBAL_L, *GLOBAL_U; +SuperLUStat_t *GLOBAL_STAT; +mem_usage_t *GLOBAL_MEM_USAGE; + +void spsolve(int n, + float x[], /* solution */ + float y[] /* right-hand side */ +) +{ + SuperMatrix *A = GLOBAL_A, *L = GLOBAL_L, *U = GLOBAL_U; + SuperLUStat_t *stat = GLOBAL_STAT; + int *perm_c = GLOBAL_PERM_C, *perm_r = GLOBAL_PERM_R; + char *equed = GLOBAL_EQUED; + float *R = GLOBAL_R, *C = GLOBAL_C; + superlu_options_t *options = GLOBAL_OPTIONS; + mem_usage_t *mem_usage = GLOBAL_MEM_USAGE; + int info; + static DNformat X, Y; + static SuperMatrix XX = {SLU_DN, SLU_S, SLU_GE, 1, 1, &X}; + static SuperMatrix YY = {SLU_DN, SLU_S, SLU_GE, 1, 1, &Y}; + float rpg, rcond; + + XX.nrow = YY.nrow = n; + X.lda = Y.lda = n; + X.nzval = x; + Y.nzval = y; + +#if 0 + scopy_(&n, y, &i_1, x, &i_1); + sgstrs(NOTRANS, L, U, perm_c, perm_r, &XX, stat, &info); +#else + sgsisx(options, A, perm_c, perm_r, NULL, equed, R, C, + L, U, NULL, 0, &YY, &XX, &rpg, &rcond, NULL, + mem_usage, stat, &info); +#endif +} + +void smatvec_mult(float alpha, float x[], float beta, float y[]) +{ + SuperMatrix *A = GLOBAL_A_ORIG; + + sp_sgemv("N", alpha, A, x, 1, beta, y, 1); +} + +int main(int argc, char *argv[]) +{ + void smatvec_mult(float alpha, float x[], float beta, float y[]); + void spsolve(int n, float x[], float y[]); + extern int sfgmr( int n, + void (*matvec_mult)(float, float [], float, float []), + void (*psolve)(int n, float [], float[]), + float *rhs, float *sol, double tol, int restrt, int *itmax, + FILE *fits); + extern int sfill_diag(int n, NCformat *Astore); + + char equed[1] = {'B'}; + yes_no_t equil; + trans_t trans; + SuperMatrix A, AA, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + float *a, *a_orig; + int *asub, *xa, *asub_orig, *xa_orig; + int *etree; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + int nrhs, ldx, lwork, info, m, n, nnz; + float *rhsb, *rhsx, *xact; + float *work = NULL; + float *R, *C; + float u, rpg, rcond; + float zero = 0.0; + float one = 1.0; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + int restrt, iter, maxit, i; + double resid; + float *x, *b; + +#ifdef DEBUG + extern int num_drop_L, num_drop_U; +#endif + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 0.1; //different from complete LU + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + options.RowPerm = LargeDiag; + options.ILU_DropTol = 1e-4; + options.ILU_FillTol = 1e-2; + options.ILU_FillFactor = 10.0; + options.ILU_DropRule = DROP_BASIC | DROP_AREA; + options.ILU_Norm = INF_NORM; + options.ILU_MILU = SILU; + */ + ilu_set_default_options(&options); + + /* Modify the defaults. */ + options.PivotGrowth = YES; /* Compute reciprocal pivot growth */ + options.ConditionNumber = YES;/* Compute reciprocal condition number */ + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) ABORT("Malloc fails for work[]."); + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + if (argc < 2) + { + printf("Usage:\n%s [OPTION] < [INPUT] > [OUTPUT]\nOPTION:\n" + "-h -hb:\n\t[INPUT] is a Harwell-Boeing format matrix.\n" + "-r -rb:\n\t[INPUT] is a Rutherford-Boeing format matrix.\n" + "-t -triplet:\n\t[INPUT] is a triplet format matrix.\n", + argv[0]); + return 0; + } + else + { + switch (argv[1][1]) + { + case 'H': + case 'h': + printf("Input a Harwell-Boeing format matrix:\n"); + sreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + break; + case 'R': + case 'r': + printf("Input a Rutherford-Boeing format matrix:\n"); + sreadrb(&m, &n, &nnz, &a, &asub, &xa); + break; + case 'T': + case 't': + printf("Input a triplet format matrix:\n"); + sreadtriple(&m, &n, &nnz, &a, &asub, &xa); + break; + default: + printf("Unrecognized format.\n"); + return 0; + } + } + + sCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, + SLU_NC, SLU_S, SLU_GE); + Astore = A.Store; + sfill_diag(n, Astore); + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + fflush(stdout); + + /* Make a copy of the original matrix. */ + nnz = Astore->nnz; + a_orig = floatMalloc(nnz); + asub_orig = intMalloc(nnz); + xa_orig = intMalloc(n+1); + for (i = 0; i < nnz; ++i) { + a_orig[i] = ((float *)Astore->nzval)[i]; + asub_orig[i] = Astore->rowind[i]; + } + for (i = 0; i <= n; ++i) xa_orig[i] = Astore->colptr[i]; + sCreate_CompCol_Matrix(&AA, m, n, nnz, a_orig, asub_orig, xa_orig, + SLU_NC, SLU_S, SLU_GE); + + /* Generate the right-hand side */ + if ( !(rhsb = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + sCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_S, SLU_GE); + sCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_S, SLU_GE); + xact = floatMalloc(n * nrhs); + ldx = n; + sGenXtrue(n, nrhs, xact, ldx); + sFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (float *) SUPERLU_MALLOC(A.nrow * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (float *) SUPERLU_MALLOC(A.ncol * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + + info = 0; +#ifdef DEBUG + num_drop_L = 0; + num_drop_U = 0; +#endif + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* Compute the incomplete factorization and compute the condition number + and pivot growth using dgsisx. */ + B.ncol = 0; /* not to perform triangular solution */ + sgsisx(&options, &A, perm_c, perm_r, etree, equed, R, C, &L, &U, work, + lwork, &B, &X, &rpg, &rcond, &Glu, &mem_usage, &stat, &info); + + /* Set RHS for GMRES. */ + if (!(b = floatMalloc(m))) ABORT("Malloc fails for b[]."); + for (i = 0; i < m; i++) b[i] = rhsb[i]; + + printf("sgsisx(): info %d, equed %c\n", info, equed[0]); + if (info > 0 || rcond < 1e-8 || rpg > 1e8) + printf("WARNING: This preconditioner might be unstable.\n"); + + if ( info == 0 || info == n+1 ) { + if ( options.PivotGrowth == YES ) + printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber == YES ) + printf("Recip. condition number = %e\n", rcond); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("n(A) = %d, nnz(A) = %d\n", n, Astore->nnz); + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("Fill ratio: nnz(F)/nnz(A) = %.3f\n", + ((double)(Lstore->nnz) + (double)(Ustore->nnz) - (double)n) + / (double)Astore->nnz); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + fflush(stdout); + + /* Set the global variables. */ + GLOBAL_A = &A; + GLOBAL_A_ORIG = &AA; + GLOBAL_L = &L; + GLOBAL_U = &U; + GLOBAL_STAT = &stat; + GLOBAL_PERM_C = perm_c; + GLOBAL_PERM_R = perm_r; + GLOBAL_OPTIONS = &options; + GLOBAL_EQUED = equed; + GLOBAL_R = R; + GLOBAL_C = C; + GLOBAL_MEM_USAGE = &mem_usage; + + /* Set the options to do solve-only. */ + options.Fact = FACTORED; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + + /* Set the variables used by GMRES. */ + restrt = SUPERLU_MIN(n / 3 + 1, 50); + maxit = 1000; + iter = maxit; + resid = 1e-8; + if (!(x = floatMalloc(n))) ABORT("Malloc fails for x[]."); + + if (info <= n + 1) + { + int i_1 = 1; + double maxferr = 0.0, nrmA, nrmB, res, t; + float temp; + extern float snrm2_(int *, float [], int *); + extern void saxpy_(int *, float *, float [], int *, float [], int *); + + /* Initial guess */ + for (i = 0; i < n; i++) x[i] = zero; + + t = SuperLU_timer_(); + + /* Call GMRES */ + sfgmr(n, smatvec_mult, spsolve, b, x, resid, restrt, &iter, stdout); + + t = SuperLU_timer_() - t; + + /* Output the result. */ + nrmA = snrm2_(&(Astore->nnz), (float *)((DNformat *)A.Store)->nzval, + &i_1); + nrmB = snrm2_(&m, b, &i_1); + sp_sgemv("N", -1.0, &A, x, 1, 1.0, b, 1); + res = snrm2_(&m, b, &i_1); + resid = res / nrmB; + printf("||A||_F = %.1e, ||B||_2 = %.1e, ||B-A*X||_2 = %.1e, " + "relres = %.1e\n", nrmA, nrmB, res, resid); + + if (iter >= maxit) + { + if (resid >= 1.0) iter = -180; + else if (resid > 1e-8) iter = -111; + } + printf("iteration: %d\nresidual: %.1e\nGMRES time: %.2f seconds.\n", + iter, resid, t); + + for (i = 0; i < m; i++) { + maxferr = SUPERLU_MAX(maxferr, fabs(x[i] - xact[i])); + } + printf("||X-X_true||_oo = %.1e\n", maxferr); + } +#ifdef DEBUG + printf("%d entries in L and %d entries in U dropped.\n", + num_drop_L, num_drop_U); +#endif + fflush(stdout); + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + Destroy_CompCol_Matrix(&A); + Destroy_CompCol_Matrix(&AA); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork >= 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } + SUPERLU_FREE(b); + SUPERLU_FREE(x); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/slinsol.c b/src/Libraries/superlu-5.2.1/EXAMPLE/slinsol.c new file mode 100644 index 00000000..86a3141a --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/slinsol.c @@ -0,0 +1,126 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 3.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + */ +#include "slu_sdefs.h" + +int main(int argc, char *argv[]) +{ + SuperMatrix A; + NCformat *Astore; + float *a; + int *asub, *xa; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + SuperMatrix L; /* factor L */ + SCformat *Lstore; + SuperMatrix U; /* factor U */ + NCformat *Ustore; + SuperMatrix B; + int nrhs, ldx, info, m, n, nnz; + float *xact, *rhs; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Read the matrix in Harwell-Boeing format. */ + sreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + sCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_S, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + nrhs = 1; + if ( !(rhs = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhs[]."); + sCreate_Dense_Matrix(&B, m, nrhs, rhs, m, SLU_DN, SLU_S, SLU_GE); + xact = floatMalloc(n * nrhs); + ldx = n; + sGenXtrue(n, nrhs, xact, ldx); + sFillRHS(options.Trans, nrhs, xact, ldx, &A, &B); + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + sgssv(&options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info); + + if ( info == 0 ) { + + /* This is how you could access the solution matrix. */ + float *sol = (float*) ((DNformat*) B.Store)->nzval; + + /* Compute the infinity norm of the error. */ + sinf_norm_error(nrhs, &B, xact); + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + sQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + + } else { + printf("sgssv() error returns INFO= %d\n", info); + if ( info <= n ) { /* factorization completes */ + sQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + } + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhs); + SUPERLU_FREE (xact); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/slinsol1.c b/src/Libraries/superlu-5.2.1/EXAMPLE/slinsol1.c new file mode 100644 index 00000000..bf6b4fcc --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/slinsol1.c @@ -0,0 +1,131 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 3.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + */ +#include "slu_sdefs.h" + +int main(int argc, char *argv[]) +{ + SuperMatrix A; + NCformat *Astore; + float *a; + int *asub, *xa; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + SuperMatrix L; /* factor L */ + SCformat *Lstore; + SuperMatrix U; /* factor U */ + NCformat *Ustore; + SuperMatrix B; + int nrhs, ldx, info, m, n, nnz; + float *xact, *rhs; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Now we modify the default options to use the symmetric mode. */ + options.SymmetricMode = YES; + options.ColPerm = MMD_AT_PLUS_A; + options.DiagPivotThresh = 0.001; + + /* Read the matrix in Harwell-Boeing format. */ + sreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + sCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_S, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + nrhs = 1; + if ( !(rhs = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhs[]."); + sCreate_Dense_Matrix(&B, m, nrhs, rhs, m, SLU_DN, SLU_S, SLU_GE); + xact = floatMalloc(n * nrhs); + ldx = n; + sGenXtrue(n, nrhs, xact, ldx); + sFillRHS(options.Trans, nrhs, xact, ldx, &A, &B); + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + sgssv(&options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info); + + if ( info == 0 ) { + + /* This is how you could access the solution matrix. */ + float *sol = (float*) ((DNformat*) B.Store)->nzval; + + /* Compute the infinity norm of the error. */ + sinf_norm_error(nrhs, &B, xact); + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + sQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + + } else { + printf("sgssv() error returns INFO= %d\n", info); + if ( info <= n ) { /* factorization completes */ + sQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + } + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhs); + SUPERLU_FREE (xact); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/slinsolx.c b/src/Libraries/superlu-5.2.1/EXAMPLE/slinsolx.c new file mode 100644 index 00000000..d26c9544 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/slinsolx.c @@ -0,0 +1,226 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 3.1) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * August 1, 2008 + * + */ +#include "slu_sdefs.h" + +int main(int argc, char *argv[]) +{ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + float *a; + int *asub, *xa; + int *perm_r; /* row permutations from partial pivoting */ + int *perm_c; /* column permutation vector */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, m, n, nnz; + float *rhsb, *rhsx, *xact; + float *R, *C; + float *ferr, *berr; + float u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + /* Add more functionalities that the defaults. */ + options.PivotGrowth = YES; /* Compute reciprocal pivot growth */ + options.ConditionNumber = YES;/* Compute reciprocal condition number */ + options.IterRefine = SLU_SINGLE; /* Perform single-precision refinement */ + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("SLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + sreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + sCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_S, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + sCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_S, SLU_GE); + sCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_S, SLU_GE); + xact = floatMalloc(n * nrhs); + ldx = n; + sGenXtrue(n, nrhs, xact, ldx); + sFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (float *) SUPERLU_MALLOC(A.nrow * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (float *) SUPERLU_MALLOC(A.ncol * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* Solve the system and compute the condition number + and error bounds using dgssvx. */ + + sgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("sgssvx(): info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + float *sol = (float*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth == YES ) + printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber == YES ) + printf("Recip. condition number = %e\n", rcond); + if ( options.IterRefine != NOREFINE ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork == 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + + +/* + * Parse command line inputs. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + float *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:w:r:u:f:t:p:e:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/slinsolx1.c b/src/Libraries/superlu-5.2.1/EXAMPLE/slinsolx1.c new file mode 100644 index 00000000..8c79ccb2 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/slinsolx1.c @@ -0,0 +1,257 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 5.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + * Last update: July 10, 2015 + * + */ +#include "slu_sdefs.h" + +int main(int argc, char *argv[]) +{ +/* + * Purpose + * ======= + * + * The driver program SLINSOLX1. + * + * This example illustrates how to use SGSSVX to solve systems with the same + * A but different right-hand side. + * In this case, we factorize A only once in the first call to DGSSVX, + * and reuse the following data structures in the subsequent call to SGSSVX: + * perm_c, perm_r, R, C, L, U. + * + */ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + float *a; + int *asub, *xa; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, m, n, nnz; + float *rhsb, *rhsx, *xact; + float *R, *C; + float *ferr, *berr; + float u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default values for options argument: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("SLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + sreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + sCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_S, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + sCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_S, SLU_GE); + sCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_S, SLU_GE); + xact = floatMalloc(n * nrhs); + ldx = n; + sGenXtrue(n, nrhs, xact, ldx); + sFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (float *) SUPERLU_MALLOC(A.nrow * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (float *) SUPERLU_MALLOC(A.ncol * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* ONLY PERFORM THE LU DECOMPOSITION */ + B.ncol = 0; /* Indicate not to solve the system */ + sgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("LU factorization: sgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + /* ------------------------------------------------------------ + NOW WE SOLVE THE LINEAR SYSTEM USING THE FACTORED FORM OF A. + ------------------------------------------------------------*/ + options.Fact = FACTORED; /* Indicate the factored form of A is supplied. */ + B.ncol = nrhs; /* Set the number of right-hand side */ + + /* Initialize the statistics variables. */ + StatInit(&stat); + + sgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("Triangular solve: sgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + float *sol = (float*) ((DNformat*) X.Store)->nzval; + + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork == 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + +/* + * Parse command line options to get relaxed snode size, panel size, etc. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + float *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:u:e:t:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/slinsolx2.c b/src/Libraries/superlu-5.2.1/EXAMPLE/slinsolx2.c new file mode 100644 index 00000000..b0f2eb48 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/slinsolx2.c @@ -0,0 +1,293 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 5.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + * Last update: July 10, 2015 + * + */ +#include "slu_sdefs.h" + +int main(int argc, char *argv[]) +{ +/* + * Purpose + * ======= + * + * The driver program SLINSOLX2. + * + * This example illustrates how to use SGSSVX to solve systems repeatedly + * with the same sparsity pattern of matrix A. + * In this case, the column permutation vector perm_c is computed once. + * The following data structures will be reused in the subsequent call to + * SGSSVX: perm_c, etree + * + */ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, A1, L, U; + SuperMatrix B, B1, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + float *a, *a1; + int *asub, *xa, *asub1, *xa1; + int *perm_r; /* row permutations from partial pivoting */ + int *perm_c; /* column permutation vector */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, j, m, n, nnz; + float *rhsb, *rhsb1, *rhsx, *xact; + float *R, *C; + float *ferr, *berr; + float u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("DLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + sreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + if ( !(a1 = floatMalloc(nnz)) ) ABORT("Malloc fails for a1[]."); + if ( !(asub1 = intMalloc(nnz)) ) ABORT("Malloc fails for asub1[]."); + if ( !(xa1 = intMalloc(n+1)) ) ABORT("Malloc fails for xa1[]."); + for (i = 0; i < nnz; ++i) { + a1[i] = a[i]; + asub1[i] = asub[i]; + } + for (i = 0; i < n+1; ++i) xa1[i] = xa[i]; + + sCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_S, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsb1 = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb1[]."); + if ( !(rhsx = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + sCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_S, SLU_GE); + sCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_S, SLU_GE); + xact = floatMalloc(n * nrhs); + ldx = n; + sGenXtrue(n, nrhs, xact, ldx); + sFillRHS(trans, nrhs, xact, ldx, &A, &B); + for (j = 0; j < nrhs; ++j) + for (i = 0; i < m; ++i) rhsb1[i+j*m] = rhsb[i+j*m]; + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(R = (float *) SUPERLU_MALLOC(A.nrow * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (float *) SUPERLU_MALLOC(A.ncol * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* ------------------------------------------------------------ + WE SOLVE THE LINEAR SYSTEM FOR THE FIRST TIME: AX = B + ------------------------------------------------------------*/ + sgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("First system: sgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + float *sol = (float*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + Destroy_CompCol_Matrix(&A); + Destroy_Dense_Matrix(&B); + if ( lwork >= 0 ) { /* Deallocate storage associated with L and U. */ + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } + + /* ------------------------------------------------------------ + NOW WE SOLVE ANOTHER LINEAR SYSTEM: A1*X = B1 + ONLY THE SPARSITY PATTERN OF A1 IS THE SAME AS THAT OF A. + ------------------------------------------------------------*/ + options.Fact = SamePattern; + StatInit(&stat); /* Initialize the statistics variables. */ + + sCreate_CompCol_Matrix(&A1, m, n, nnz, a1, asub1, xa1, + SLU_NC, SLU_S, SLU_GE); + sCreate_Dense_Matrix(&B1, m, nrhs, rhsb1, m, SLU_DN, SLU_S, SLU_GE); + + sgssvx(&options, &A1, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B1, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("\nSecond system: sgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + float *sol = (float*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A1); + Destroy_Dense_Matrix(&B1); + Destroy_Dense_Matrix(&X); + if ( lwork == 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + +/* + * Parse command line options to get relaxed snode size, panel size, etc. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + double *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:u:e:t:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/slinsolx3.c b/src/Libraries/superlu-5.2.1/EXAMPLE/slinsolx3.c new file mode 100644 index 00000000..9df622d4 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/slinsolx3.c @@ -0,0 +1,288 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 5.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + * Last update: July 10, 2015 + * + */ +#include "slu_sdefs.h" + +int main(int argc, char *argv[]) +{ +/* + * Purpose + * ======= + * + * The driver program SLINSOLX2. + * + * This example illustrates how to use SGSSVX to solve systems repeatedly + * with the same sparsity pattern and similar values of matrix A. + * In this case, the permutation vectors perm_r and perm_c are computed once. + * The following data structures will be reused in the subsequent call to + * SGSSVX: perm_r, perm_c, etree, L, U. + * + */ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, A1, L, U; + SuperMatrix B, B1, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; + float *a, *a1; + int *asub, *xa, *asub1, *xa1; + int *perm_r; /* row permutations from partial pivoting */ + int *perm_c; /* column permutation vector */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, j, m, n, nnz; + float *rhsb, *rhsb1, *rhsx, *xact; + float *R, *C; + float *ferr, *berr; + float u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("DLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + sreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + if ( !(a1 = floatMalloc(nnz)) ) ABORT("Malloc fails for a1[]."); + if ( !(asub1 = intMalloc(nnz)) ) ABORT("Malloc fails for asub1[]."); + if ( !(xa1 = intMalloc(n+1)) ) ABORT("Malloc fails for xa1[]."); + for (i = 0; i < nnz; ++i) { + a1[i] = a[i]; + asub1[i] = asub[i]; + } + for (i = 0; i < n+1; ++i) xa1[i] = xa[i]; + + sCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_S, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsb1 = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb1[]."); + if ( !(rhsx = floatMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + sCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_S, SLU_GE); + sCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_S, SLU_GE); + xact = floatMalloc(n * nrhs); + ldx = n; + sGenXtrue(n, nrhs, xact, ldx); + sFillRHS(trans, nrhs, xact, ldx, &A, &B); + for (j = 0; j < nrhs; ++j) + for (i = 0; i < m; ++i) rhsb1[i+j*m] = rhsb[i+j*m]; + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(R = (float *) SUPERLU_MALLOC(A.nrow * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (float *) SUPERLU_MALLOC(A.ncol * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (float *) SUPERLU_MALLOC(nrhs * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* ------------------------------------------------------------ + WE SOLVE THE LINEAR SYSTEM FOR THE FIRST TIME: AX = B + ------------------------------------------------------------*/ + sgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("First system: sgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + float *sol = (float*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + Destroy_CompCol_Matrix(&A); + Destroy_Dense_Matrix(&B); + + /* ------------------------------------------------------------ + NOW WE SOLVE ANOTHER LINEAR SYSTEM: A1*X = B1 + ONLY THE SPARSITY PATTERN OF A1 IS THE SAME AS THAT OF A. + ------------------------------------------------------------*/ + options.Fact = SamePattern_SameRowPerm; + StatInit(&stat); /* Initialize the statistics variables. */ + + sCreate_CompCol_Matrix(&A1, m, n, nnz, a1, asub1, xa1, + SLU_NC, SLU_S, SLU_GE); + sCreate_Dense_Matrix(&B1, m, nrhs, rhsb1, m, SLU_DN, SLU_S, SLU_GE); + + sgssvx(&options, &A1, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B1, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("\nSecond system: sgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + float *sol = (float*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A1); + Destroy_Dense_Matrix(&B1); + Destroy_Dense_Matrix(&X); + if ( lwork == 0 ) { /* Deallocate storage associated with L and U. */ + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + +/* + * Parse command line options to get relaxed snode size, panel size, etc. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + double *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:u:e:t:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/sp_ienv.c b/src/Libraries/superlu-5.2.1/EXAMPLE/sp_ienv.c new file mode 100644 index 00000000..f8bab39d --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/sp_ienv.c @@ -0,0 +1,89 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file sp_ienv.c + * \brief Chooses machine-dependent parameters for the local environment. + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November, 2010
+ * 
+*/ + +/* + * File name: sp_ienv.c + * History: Modified from lapack routine ILAENV + */ +#include "slu_Cnames.h" + +/*! \brief + +
+    Purpose   
+    =======   
+
+    sp_ienv() is inquired to choose machine-dependent parameters for the
+    local environment. See ISPEC for a description of the parameters.   
+
+    This version provides a set of parameters which should give good,   
+    but not optimal, performance on many of the currently available   
+    computers.  Users are encouraged to modify this subroutine to set   
+    the tuning parameters for their particular machine using the option   
+    and problem size information in the arguments.   
+
+    Arguments   
+    =========   
+
+    ISPEC   (input) int
+            Specifies the parameter to be returned as the value of SP_IENV.   
+            = 1: the panel size w; a panel consists of w consecutive
+	         columns of matrix A in the process of Gaussian elimination.
+		 The best value depends on machine's cache characters.
+            = 2: the relaxation parameter relax; if the number of
+	         nodes (columns) in a subtree of the elimination tree is less
+		 than relax, this subtree is considered as one supernode,
+		 regardless of their row structures.
+            = 3: the maximum size for a supernode in complete LU;
+	    = 4: the minimum row dimension for 2-D blocking to be used;
+	    = 5: the minimum column dimension for 2-D blocking to be used;
+	    = 6: the estimated fills factor for L and U, compared with A;
+	    = 7: the maximum size for a supernode in ILU.
+	    
+   (SP_IENV) (output) int
+            >= 0: the value of the parameter specified by ISPEC   
+            < 0:  if SP_IENV = -k, the k-th argument had an illegal value. 
+  
+    ===================================================================== 
+
+*/ +int +sp_ienv(int ispec) +{ + int i; + + switch (ispec) { + case 1: return (1); + case 2: return (1); + case 3: return (200); + case 4: return (200); + case 5: return (100); + case 6: return (30); + case 7: return (10); + } + + /* Invalid value for ISPEC */ + i = 1; + input_error("sp_ienv", &i); + return 0; + +} /* sp_ienv_ */ + diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/superlu.c b/src/Libraries/superlu-5.2.1/EXAMPLE/superlu.c new file mode 100644 index 00000000..fd42a6ad --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/superlu.c @@ -0,0 +1,94 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file superlu.c + * \brief a small 5x5 example + * + *
+ * * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ */ +#include "slu_ddefs.h" + +main(int argc, char *argv[]) +{ +/* + * Purpose + * ======= + * + * This is the small 5x5 example used in the Sections 2 and 3 of the + * Users' Guide to illustrate how to call a SuperLU routine, and the + * matrix data structures used by SuperLU. + * + */ + SuperMatrix A, L, U, B; + double *a, *rhs; + double s, u, p, e, r, l; + int *asub, *xa; + int *perm_r; /* row permutations from partial pivoting */ + int *perm_c; /* column permutation vector */ + int nrhs, info, i, m, n, nnz, permc_spec; + superlu_options_t options; + SuperLUStat_t stat; + + /* Initialize matrix A. */ + m = n = 5; + nnz = 12; + if ( !(a = doubleMalloc(nnz)) ) ABORT("Malloc fails for a[]."); + if ( !(asub = intMalloc(nnz)) ) ABORT("Malloc fails for asub[]."); + if ( !(xa = intMalloc(n+1)) ) ABORT("Malloc fails for xa[]."); + s = 19.0; u = 21.0; p = 16.0; e = 5.0; r = 18.0; l = 12.0; + a[0] = s; a[1] = l; a[2] = l; a[3] = u; a[4] = l; a[5] = l; + a[6] = u; a[7] = p; a[8] = u; a[9] = e; a[10]= u; a[11]= r; + asub[0] = 0; asub[1] = 1; asub[2] = 4; asub[3] = 1; + asub[4] = 2; asub[5] = 4; asub[6] = 0; asub[7] = 2; + asub[8] = 0; asub[9] = 3; asub[10]= 3; asub[11]= 4; + xa[0] = 0; xa[1] = 3; xa[2] = 6; xa[3] = 8; xa[4] = 10; xa[5] = 12; + + /* Create matrix A in the format expected by SuperLU. */ + dCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_D, SLU_GE); + + /* Create right-hand side matrix B. */ + nrhs = 1; + if ( !(rhs = doubleMalloc(m * nrhs)) ) ABORT("Malloc fails for rhs[]."); + for (i = 0; i < m; ++i) rhs[i] = 1.0; + dCreate_Dense_Matrix(&B, m, nrhs, rhs, m, SLU_DN, SLU_D, SLU_GE); + + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + + /* Set the default input options. */ + set_default_options(&options); + options.ColPerm = NATURAL; + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* Solve the linear system. */ + dgssv(&options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info); + + dPrint_CompCol_Matrix("A", &A); + dPrint_CompCol_Matrix("U", &U); + dPrint_SuperNode_Matrix("L", &L); + print_int_vec("\nperm_r", m, perm_r); + + /* De-allocate storage */ + SUPERLU_FREE (rhs); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + StatFree(&stat); +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/zfgmr.c b/src/Libraries/superlu-5.2.1/EXAMPLE/zfgmr.c new file mode 100644 index 00000000..733c05a7 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/zfgmr.c @@ -0,0 +1,344 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zfgmr.c + * \brief flexible GMRES from ITSOL developed by Yousef Saad. + */ + +/* ITSOL COPYRIGHT + +Copyright (C) 2006, the University of Minnesota + +ITSOL is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation [version 2 of the License, or any later version] +For details, see + +http://www.gnu.org/copyleft/gpl.html + +A copy of the GNU licencing agreement is attached to the ITSOL package +in the file GNU. For additional information contact the Free Software +Foundation Inc., 65 Mass Ave, Cambridge, MA 02139, USA. + +DISCLAIMER +---------- + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +For information on ITSOL contact saad@cs.umn.edu +*/ + +#include "slu_zdefs.h" + +#define epsmac 1.0e-16 + +extern void zdotc_(doublecomplex *, int *, doublecomplex [], int *, doublecomplex [], int *); +extern double dznrm2_(int *, doublecomplex [], int *); + + +int zfgmr(int n, + void (*zmatvec) (doublecomplex, doublecomplex[], doublecomplex, doublecomplex[]), + void (*zpsolve) (int, doublecomplex[], doublecomplex[]), + doublecomplex *rhs, doublecomplex *sol, double tol, int im, int *itmax, FILE * fits) +{ +/*---------------------------------------------------------------------- +| *** Preconditioned FGMRES *** ++----------------------------------------------------------------------- +| This is a simple version of the ARMS preconditioned FGMRES algorithm. ++----------------------------------------------------------------------- +| Y. S. Dec. 2000. -- Apr. 2008 ++----------------------------------------------------------------------- +| on entry: +|---------- +| +| rhs = real vector of length n containing the right hand side. +| sol = real vector of length n containing an initial guess to the +| solution on input. +| tol = tolerance for stopping iteration +| im = Krylov subspace dimension +| (itmax) = max number of iterations allowed. +| fits = NULL: no output +| != NULL: file handle to output " resid vs time and its" +| +| on return: +|---------- +| fgmr int = 0 --> successful return. +| int = 1 --> convergence not achieved in itmax iterations. +| sol = contains an approximate solution (upon successful return). +| itmax = has changed. It now contains the number of steps required +| to converge -- ++----------------------------------------------------------------------- +| internal work arrays: +|---------- +| vv = work array of length [im+1][n] (used to store the Arnoldi +| basis) +| hh = work array of length [im][im+1] (Householder matrix) +| z = work array of length [im][n] to store preconditioned vectors ++----------------------------------------------------------------------- +| subroutines called : +| matvec - matrix-vector multiplication operation +| psolve - (right) preconditionning operation +| psolve can be a NULL pointer (GMRES without preconditioner) ++---------------------------------------------------------------------*/ + + int maxits = *itmax; + int i, i1, ii, j, k, k1, its, retval, i_1 = 1, i_2 = 2; + double beta, eps1 = 0.0, t, t0, gam; + doublecomplex **hh, *c, *s, *rs; + doublecomplex **vv, **z, tt; + doublecomplex zero = {0.0, 0.0}; + doublecomplex one = {1.0, 0.0}; + doublecomplex tt1, tt2; + + its = 0; + vv = (doublecomplex **)SUPERLU_MALLOC((im + 1) * sizeof(doublecomplex *)); + for (i = 0; i <= im; i++) vv[i] = doublecomplexMalloc(n); + z = (doublecomplex **)SUPERLU_MALLOC(im * sizeof(doublecomplex *)); + hh = (doublecomplex **)SUPERLU_MALLOC(im * sizeof(doublecomplex *)); + for (i = 0; i < im; i++) + { + hh[i] = doublecomplexMalloc(i + 2); + z[i] = doublecomplexMalloc(n); + } + c = doublecomplexMalloc(im); + s = doublecomplexMalloc(im); + rs = doublecomplexMalloc(im + 1); + + /*---- outer loop starts here ----*/ + do + { + /*---- compute initial residual vector ----*/ + zmatvec(one, sol, zero, vv[0]); + for (j = 0; j < n; j++) + z_sub(&vv[0][j], &rhs[j], &vv[0][j]); /* vv[0]= initial residual */ + beta = dznrm2_(&n, vv[0], &i_1); + + /*---- print info if fits != null ----*/ + if (fits != NULL && its == 0) + fprintf(fits, "%8d %10.2e\n", its, beta); + /*if ( beta <= tol * dnrm2_(&n, rhs, &i_1) )*/ + if ( !(beta > tol * dznrm2_(&n, rhs, &i_1)) ) + break; + t = 1.0 / beta; + + /*---- normalize: vv[0] = vv[0] / beta ----*/ + for (j = 0; j < n; j++) + zd_mult(&vv[0][j], &vv[0][j], t); + if (its == 0) + eps1 = tol * beta; + + /*---- initialize 1-st term of rhs of hessenberg system ----*/ + rs[0].r = beta; + rs[0].i = 0.0; + for (i = 0; i < im; i++) + { + its++; + i1 = i + 1; + + /*------------------------------------------------------------ + | (Right) Preconditioning Operation z_{j} = M^{-1} v_{j} + +-----------------------------------------------------------*/ + if (zpsolve) + zpsolve(n, z[i], vv[i]); + else + zcopy_(&n, vv[i], &i_1, z[i], &i_1); + + /*---- matvec operation w = A z_{j} = A M^{-1} v_{j} ----*/ + zmatvec(one, z[i], zero, vv[i1]); + + /*------------------------------------------------------------ + | modified gram - schmidt... + | h_{i,j} = (w,v_{i}) + | w = w - h_{i,j} v_{i} + +------------------------------------------------------------*/ + t0 = dznrm2_(&n, vv[i1], &i_1); + for (j = 0; j <= i; j++) + { + doublecomplex negt; +#if 0 + zdotc_(&tt, &n, vv[j], &i_1, vv[i1], &i_1); +#else + tt = zero; + for (k = 0; k < n; ++k) { + zz_conj(&tt1, &vv[j][k]); + zz_mult(&tt2, &tt1, &vv[i1][k]); + z_add(&tt, &tt, &tt2); + } +#endif + hh[i][j] = tt; + negt.r = -tt.r; + negt.i = -tt.i; + zaxpy_(&n, &negt, vv[j], &i_1, vv[i1], &i_1); + } + + /*---- h_{j+1,j} = ||w||_{2} ----*/ + t = dznrm2_(&n, vv[i1], &i_1); + while (t < 0.5 * t0) + { + t0 = t; + for (j = 0; j <= i; j++) + { + doublecomplex negt; +#if 0 + zdotc_(&tt, &n, vv[j], &i_1, vv[i1], &i_1); +#else + tt = zero; + for (k = 0; k < n; ++k) { + zz_conj(&tt1, &vv[j][k]); + zz_mult(&tt2, &tt1, &vv[i1][k]); + z_add(&tt, &tt, &tt2); + } +#endif + z_add(&hh[i][j], &hh[i][j], &tt); + negt.r = -tt.r; + negt.i = -tt.i; + zaxpy_(&n, &negt, vv[j], &i_1, vv[i1], &i_1); + } + t = dznrm2_(&n, vv[i1], &i_1); + } + + hh[i][i1].r = t; + hh[i][i1].i = 0.0; + + if (t != 0.0) + { + /*---- v_{j+1} = w / h_{j+1,j} ----*/ + t = 1.0 / t; + for (k = 0; k < n; k++) + zd_mult(&vv[i1][k], &vv[i1][k], t); + } + /*--------------------------------------------------- + | done with modified gram schimdt and arnoldi step + | now update factorization of hh + +--------------------------------------------------*/ + + /*-------------------------------------------------------- + | perform previous transformations on i-th column of h + +-------------------------------------------------------*/ + for (k = 1; k <= i; k++) + { + k1 = k - 1; + tt = hh[i][k1]; + zz_mult(&tt1, &c[k1], &tt); + zz_mult(&tt2, &s[k1], &hh[i][k]); + z_add(&hh[i][k1], &tt1, &tt2); + + zz_mult(&tt1, &s[k1], &tt); + zz_mult(&tt2, &c[k1], &hh[i][k]); + z_sub(&hh[i][k], &tt2, &tt1); + } + + gam = dznrm2_(&i_2, &hh[i][i], &i_1); + + /*--------------------------------------------------- + | if gamma is zero then any small value will do + | affect only residual estimate + +--------------------------------------------------*/ + /* if (gam == 0.0) gam = epsmac; */ + + /*---- get next plane rotation ---*/ + if (gam == 0.0) + { + c[i] = one; + s[i] = zero; + } + else + { + gam = 1.0 / gam; + zd_mult(&c[i], &hh[i][i], gam); + zd_mult(&s[i], &hh[i][i1], gam); + } + + zz_mult(&rs[i1], &s[i], &rs[i]); + rs[i1].r = -rs[i1].r; rs[i1].i = -rs[i1].i; + zz_mult(&rs[i], &c[i], &rs[i]); + + /*---------------------------------------------------- + | determine residual norm and test for convergence + +---------------------------------------------------*/ + zz_mult(&tt1, &c[i], &hh[i][i]); + zz_mult(&tt2, &s[i], &hh[i][i1]); + z_add(&hh[i][i], &tt1, &tt2); + beta = z_abs1(&rs[i1]); + if (fits != NULL) + fprintf(fits, "%8d %10.2e\n", its, beta); + if (beta <= eps1 || its >= maxits) + break; + } + + if (i == im) i--; + + /*---- now compute solution. 1st, solve upper triangular system ----*/ + z_div(&rs[i], &rs[i], &hh[i][i]); + + for (ii = 1; ii <= i; ii++) + { + k = i - ii; + k1 = k + 1; + tt = rs[k]; + for (j = k1; j <= i; j++) { + zz_mult(&tt1, &hh[j][k], &rs[j]); + z_sub(&tt, &tt, &tt1); + } + z_div(&rs[k], &tt, &hh[k][k]); + } + + /*---- linear combination of v[i]'s to get sol. ----*/ + for (j = 0; j <= i; j++) + { + tt = rs[j]; + for (k = 0; k < n; k++) { + zz_mult(&tt1, &tt, &z[j][k]); + z_add(&sol[k], &sol[k], &tt1); + } + } + + /* calculate the residual and output */ + zmatvec(one, sol, zero, vv[0]); + for (j = 0; j < n; j++) + z_sub(&vv[0][j], &rhs[j], &vv[0][j]);/* vv[0]= initial residual */ + + /*---- print info if fits != null ----*/ + beta = dznrm2_(&n, vv[0], &i_1); + + /*---- restart outer loop if needed ----*/ + /*if (beta >= eps1 / tol)*/ + if ( !(beta < eps1 / tol) ) + { + its = maxits + 10; + break; + } + if (beta <= eps1) + break; + } while(its < maxits); + + retval = (its >= maxits); + for (i = 0; i <= im; i++) + SUPERLU_FREE(vv[i]); + SUPERLU_FREE(vv); + for (i = 0; i < im; i++) + { + SUPERLU_FREE(hh[i]); + SUPERLU_FREE(z[i]); + } + SUPERLU_FREE(hh); + SUPERLU_FREE(z); + SUPERLU_FREE(c); + SUPERLU_FREE(s); + SUPERLU_FREE(rs); + + *itmax = its; + + return retval; +} /*----end of fgmr ----*/ diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/zitersol.c b/src/Libraries/superlu-5.2.1/EXAMPLE/zitersol.c new file mode 100644 index 00000000..14ee4e4d --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/zitersol.c @@ -0,0 +1,386 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zitersol.c + * \brief Example #1 showing how to use ILU to precondition GMRES + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Lawrence Berkeley National Laboratory
+ * November, 2010
+ * August, 2011
+ *
+ * This example shows that ILU is computed from the equilibrated matrix,
+ * and the preconditioned GMRES is applied to the equilibrated system.
+ * The driver routine ZGSISX is called twice to perform factorization
+ * and apply preconditioner separately.
+ * 
+ * Note that ZGSISX performs the following factorization:
+ *     Pr*Dr*A*Dc*Pc^T ~= LU
+ * with Pr being obtained from MC64 statically then partial pivoting
+ * dynamically. On return, A is overwritten as A1 = Dr*A*Dc.
+ *
+ * We can solve the transformed system, A1*y = Dr*B, using FGMRES.
+ * B is first overwritten as Dr*B.
+ * Then GMRES step requires requires 2 procedures:
+ *   1) Apply preconditioner M^{-1} = Pc^T*U^{-1}*L^{-1}*Pr
+ *   2) Matrix-vector multiplication: w = A1*v
+ * 
+ * 
+ */ + +#include "slu_zdefs.h" + +superlu_options_t *GLOBAL_OPTIONS; +double *GLOBAL_R, *GLOBAL_C; +int *GLOBAL_PERM_C, *GLOBAL_PERM_R; +SuperMatrix *GLOBAL_A, *GLOBAL_L, *GLOBAL_U; +SuperLUStat_t *GLOBAL_STAT; +mem_usage_t *GLOBAL_MEM_USAGE; + +void zpsolve(int n, + doublecomplex x[], /* solution */ + doublecomplex y[] /* right-hand side */ +) +{ + SuperMatrix *A = GLOBAL_A, *L = GLOBAL_L, *U = GLOBAL_U; + SuperLUStat_t *stat = GLOBAL_STAT; + int *perm_c = GLOBAL_PERM_C, *perm_r = GLOBAL_PERM_R; + char equed[1] = {'N'}; + double *R = GLOBAL_R, *C = GLOBAL_C; + superlu_options_t *options = GLOBAL_OPTIONS; + mem_usage_t *mem_usage = GLOBAL_MEM_USAGE; + int info; + static DNformat X, Y; + static SuperMatrix XX = {SLU_DN, SLU_Z, SLU_GE, 1, 1, &X}; + static SuperMatrix YY = {SLU_DN, SLU_Z, SLU_GE, 1, 1, &Y}; + double rpg, rcond; + + XX.nrow = YY.nrow = n; + X.lda = Y.lda = n; + X.nzval = x; + Y.nzval = y; + +#if 0 + dcopy_(&n, y, &i_1, x, &i_1); + zgstrs(NOTRANS, L, U, perm_c, perm_r, &XX, stat, &info); +#else + zgsisx(options, A, perm_c, perm_r, NULL, equed, R, C, + L, U, NULL, 0, &YY, &XX, &rpg, &rcond, NULL, + mem_usage, stat, &info); +#endif +} + +void zmatvec_mult(doublecomplex alpha, doublecomplex x[], doublecomplex beta, doublecomplex y[]) +{ + SuperMatrix *A = GLOBAL_A; + + sp_zgemv("N", alpha, A, x, 1, beta, y, 1); +} + +int main(int argc, char *argv[]) +{ + void zmatvec_mult(doublecomplex alpha, doublecomplex x[], doublecomplex beta, doublecomplex y[]); + void zpsolve(int n, doublecomplex x[], doublecomplex y[]); + extern int zfgmr( int n, + void (*matvec_mult)(doublecomplex, doublecomplex [], doublecomplex, doublecomplex []), + void (*psolve)(int n, doublecomplex [], doublecomplex[]), + doublecomplex *rhs, doublecomplex *sol, double tol, int restrt, int *itmax, + FILE *fits); + extern int zfill_diag(int n, NCformat *Astore); + + char equed[1] = {'B'}; + yes_no_t equil; + trans_t trans; + SuperMatrix A, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + doublecomplex *a; + int *asub, *xa; + int *etree; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + int nrhs, ldx, lwork, info, m, n, nnz; + doublecomplex *rhsb, *rhsx, *xact; + doublecomplex *work = NULL; + double *R, *C; + double u, rpg, rcond; + doublecomplex zero = {0.0, 0.0}; + doublecomplex one = {1.0, 0.0}; + doublecomplex none = {-1.0, 0.0}; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + int restrt, iter, maxit, i; + double resid; + doublecomplex *x, *b; + +#ifdef DEBUG + extern int num_drop_L, num_drop_U; +#endif + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 0.1; //different from complete LU + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + options.RowPerm = LargeDiag; + options.ILU_DropTol = 1e-4; + options.ILU_FillTol = 1e-2; + options.ILU_FillFactor = 10.0; + options.ILU_DropRule = DROP_BASIC | DROP_AREA; + options.ILU_Norm = INF_NORM; + options.ILU_MILU = SILU; + */ + ilu_set_default_options(&options); + + /* Modify the defaults. */ + options.PivotGrowth = YES; /* Compute reciprocal pivot growth */ + options.ConditionNumber = YES;/* Compute reciprocal condition number */ + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) ABORT("Malloc fails for work[]."); + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + if (argc < 2) + { + printf("Usage:\n%s [OPTION] < [INPUT] > [OUTPUT]\nOPTION:\n" + "-h -hb:\n\t[INPUT] is a Harwell-Boeing format matrix.\n" + "-r -rb:\n\t[INPUT] is a Rutherford-Boeing format matrix.\n" + "-t -triplet:\n\t[INPUT] is a triplet format matrix.\n", + argv[0]); + return 0; + } + else + { + switch (argv[1][1]) + { + case 'H': + case 'h': + printf("Input a Harwell-Boeing format matrix:\n"); + zreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + break; + case 'R': + case 'r': + printf("Input a Rutherford-Boeing format matrix:\n"); + zreadrb(&m, &n, &nnz, &a, &asub, &xa); + break; + case 'T': + case 't': + printf("Input a triplet format matrix:\n"); + zreadtriple(&m, &n, &nnz, &a, &asub, &xa); + break; + default: + printf("Unrecognized format.\n"); + return 0; + } + } + + zCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, + SLU_NC, SLU_Z, SLU_GE); + Astore = A.Store; + zfill_diag(n, Astore); + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + fflush(stdout); + + /* Generate the right-hand side */ + if ( !(rhsb = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + zCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_Z, SLU_GE); + zCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_Z, SLU_GE); + xact = doublecomplexMalloc(n * nrhs); + ldx = n; + zGenXtrue(n, nrhs, xact, ldx); + zFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (double *) SUPERLU_MALLOC(A.nrow * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (double *) SUPERLU_MALLOC(A.ncol * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + + info = 0; +#ifdef DEBUG + num_drop_L = 0; + num_drop_U = 0; +#endif + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* Compute the incomplete factorization and compute the condition number + and pivot growth using dgsisx. */ + B.ncol = 0; /* not to perform triangular solution */ + zgsisx(&options, &A, perm_c, perm_r, etree, equed, R, C, &L, &U, work, + lwork, &B, &X, &rpg, &rcond, &Glu, &mem_usage, &stat, &info); + + /* Set RHS for GMRES. */ + if (!(b = doublecomplexMalloc(m))) ABORT("Malloc fails for b[]."); + if (*equed == 'R' || *equed == 'B') { + for (i = 0; i < n; ++i) zd_mult(&b[i], &rhsb[i], R[i]); + } else { + for (i = 0; i < m; i++) b[i] = rhsb[i]; + } + + printf("zgsisx(): info %d, equed %c\n", info, equed[0]); + if (info > 0 || rcond < 1e-8 || rpg > 1e8) + printf("WARNING: This preconditioner might be unstable.\n"); + + if ( info == 0 || info == n+1 ) { + if ( options.PivotGrowth == YES ) + printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber == YES ) + printf("Recip. condition number = %e\n", rcond); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("n(A) = %d, nnz(A) = %d\n", n, Astore->nnz); + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("Fill ratio: nnz(F)/nnz(A) = %.3f\n", + ((double)(Lstore->nnz) + (double)(Ustore->nnz) - (double)n) + / (double)Astore->nnz); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + fflush(stdout); + + /* Set the global variables. */ + GLOBAL_A = &A; + GLOBAL_L = &L; + GLOBAL_U = &U; + GLOBAL_STAT = &stat; + GLOBAL_PERM_C = perm_c; + GLOBAL_PERM_R = perm_r; + GLOBAL_OPTIONS = &options; + GLOBAL_R = R; + GLOBAL_C = C; + GLOBAL_MEM_USAGE = &mem_usage; + + /* Set the options to do solve-only. */ + options.Fact = FACTORED; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + + /* Set the variables used by GMRES. */ + restrt = SUPERLU_MIN(n / 3 + 1, 50); + maxit = 1000; + iter = maxit; + resid = 1e-8; + if (!(x = doublecomplexMalloc(n))) ABORT("Malloc fails for x[]."); + + if (info <= n + 1) + { + int i_1 = 1; + double maxferr = 0.0, nrmA, nrmB, res, t; + doublecomplex temp; + extern double dznrm2_(int *, doublecomplex [], int *); + extern void zaxpy_(int *, doublecomplex *, doublecomplex [], int *, doublecomplex [], int *); + + /* Initial guess */ + for (i = 0; i < n; i++) x[i] = zero; + + t = SuperLU_timer_(); + + /* Call GMRES */ + zfgmr(n, zmatvec_mult, zpsolve, b, x, resid, restrt, &iter, stdout); + + t = SuperLU_timer_() - t; + + /* Output the result. */ + nrmA = dznrm2_(&(Astore->nnz), (doublecomplex *)((DNformat *)A.Store)->nzval, + &i_1); + nrmB = dznrm2_(&m, b, &i_1); + sp_zgemv("N", none, &A, x, 1, one, b, 1); + res = dznrm2_(&m, b, &i_1); + resid = res / nrmB; + printf("||A||_F = %.1e, ||B||_2 = %.1e, ||B-A*X||_2 = %.1e, " + "relres = %.1e\n", nrmA, nrmB, res, resid); + + if (iter >= maxit) + { + if (resid >= 1.0) iter = -180; + else if (resid > 1e-8) iter = -111; + } + printf("iteration: %d\nresidual: %.1e\nGMRES time: %.2f seconds.\n", + iter, resid, t); + + /* Scale the solution back if equilibration was performed. */ + if (*equed == 'C' || *equed == 'B') + for (i = 0; i < n; i++) zd_mult(&x[i], &x[i], C[i]); + + for (i = 0; i < m; i++) { + z_sub(&temp, &x[i], &xact[i]); + maxferr = SUPERLU_MAX(maxferr, z_abs1(&temp)); + } + printf("||X-X_true||_oo = %.1e\n", maxferr); + } +#ifdef DEBUG + printf("%d entries in L and %d entries in U dropped.\n", + num_drop_L, num_drop_U); +#endif + fflush(stdout); + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork >= 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } + SUPERLU_FREE(b); + SUPERLU_FREE(x); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/zitersol1.c b/src/Libraries/superlu-5.2.1/EXAMPLE/zitersol1.c new file mode 100644 index 00000000..468c7fad --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/zitersol1.c @@ -0,0 +1,395 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zitersol1.c + * \brief Example #2 showing how to use ILU to precondition GMRES + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Lawrence Berkeley National Laboratory
+ * November, 2010
+ * August, 2011
+ *
+ * This example shows that ILU is computed from the equilibrated matrix,
+ * but the preconditioned GMRES is applied to the original system.
+ * The driver routine ZGSISX is called twice to perform factorization
+ * and apply preconditioner separately.
+ * 
+ * Note that ZGSISX performs the following factorization:
+ *     Pr*Dr*A*Dc*Pc^T ~= LU
+ * with Pr being obtained from MC64 statically then partial pivoting
+ * dynamically. On return, A is overwritten as A1 = Dr*A*Dc.
+ *
+ * We need to save a copy of the original matrix A, then solve
+ * the original system, A*x = B, using FGMRES.
+ * Each GMRES step requires requires 2 procedures:
+ *   1) Apply preconditioner M^{-1} = Dc*Pc^T*U^{-1}*L^{-1}*Pr*Dr
+ *   2) Matrix-vector multiplication: w = A*v
+ *
+ * 
+ */ + +#include "slu_zdefs.h" + +char *GLOBAL_EQUED; +superlu_options_t *GLOBAL_OPTIONS; +double *GLOBAL_R, *GLOBAL_C; +int *GLOBAL_PERM_C, *GLOBAL_PERM_R; +SuperMatrix *GLOBAL_A, *GLOBAL_A_ORIG, *GLOBAL_L, *GLOBAL_U; +SuperLUStat_t *GLOBAL_STAT; +mem_usage_t *GLOBAL_MEM_USAGE; + +void zpsolve(int n, + doublecomplex x[], /* solution */ + doublecomplex y[] /* right-hand side */ +) +{ + SuperMatrix *A = GLOBAL_A, *L = GLOBAL_L, *U = GLOBAL_U; + SuperLUStat_t *stat = GLOBAL_STAT; + int *perm_c = GLOBAL_PERM_C, *perm_r = GLOBAL_PERM_R; + char *equed = GLOBAL_EQUED; + double *R = GLOBAL_R, *C = GLOBAL_C; + superlu_options_t *options = GLOBAL_OPTIONS; + mem_usage_t *mem_usage = GLOBAL_MEM_USAGE; + int info; + static DNformat X, Y; + static SuperMatrix XX = {SLU_DN, SLU_Z, SLU_GE, 1, 1, &X}; + static SuperMatrix YY = {SLU_DN, SLU_Z, SLU_GE, 1, 1, &Y}; + double rpg, rcond; + + XX.nrow = YY.nrow = n; + X.lda = Y.lda = n; + X.nzval = x; + Y.nzval = y; + +#if 0 + zcopy_(&n, y, &i_1, x, &i_1); + zgstrs(NOTRANS, L, U, perm_c, perm_r, &XX, stat, &info); +#else + zgsisx(options, A, perm_c, perm_r, NULL, equed, R, C, + L, U, NULL, 0, &YY, &XX, &rpg, &rcond, NULL, + mem_usage, stat, &info); +#endif +} + +void zmatvec_mult(doublecomplex alpha, doublecomplex x[], doublecomplex beta, doublecomplex y[]) +{ + SuperMatrix *A = GLOBAL_A_ORIG; + + sp_zgemv("N", alpha, A, x, 1, beta, y, 1); +} + +int main(int argc, char *argv[]) +{ + void zmatvec_mult(doublecomplex alpha, doublecomplex x[], doublecomplex beta, doublecomplex y[]); + void zpsolve(int n, doublecomplex x[], doublecomplex y[]); + extern int zfgmr( int n, + void (*matvec_mult)(doublecomplex, doublecomplex [], doublecomplex, doublecomplex []), + void (*psolve)(int n, doublecomplex [], doublecomplex[]), + doublecomplex *rhs, doublecomplex *sol, double tol, int restrt, int *itmax, + FILE *fits); + extern int zfill_diag(int n, NCformat *Astore); + + char equed[1] = {'B'}; + yes_no_t equil; + trans_t trans; + SuperMatrix A, AA, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + doublecomplex *a, *a_orig; + int *asub, *xa, *asub_orig, *xa_orig; + int *etree; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + int nrhs, ldx, lwork, info, m, n, nnz; + doublecomplex *rhsb, *rhsx, *xact; + doublecomplex *work = NULL; + double *R, *C; + double u, rpg, rcond; + doublecomplex zero = {0.0, 0.0}; + doublecomplex one = {1.0, 0.0}; + doublecomplex none = {-1.0, 0.0}; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + int restrt, iter, maxit, i; + double resid; + doublecomplex *x, *b; + +#ifdef DEBUG + extern int num_drop_L, num_drop_U; +#endif + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 0.1; //different from complete LU + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + options.RowPerm = LargeDiag; + options.ILU_DropTol = 1e-4; + options.ILU_FillTol = 1e-2; + options.ILU_FillFactor = 10.0; + options.ILU_DropRule = DROP_BASIC | DROP_AREA; + options.ILU_Norm = INF_NORM; + options.ILU_MILU = SILU; + */ + ilu_set_default_options(&options); + + /* Modify the defaults. */ + options.PivotGrowth = YES; /* Compute reciprocal pivot growth */ + options.ConditionNumber = YES;/* Compute reciprocal condition number */ + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) ABORT("Malloc fails for work[]."); + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + if (argc < 2) + { + printf("Usage:\n%s [OPTION] < [INPUT] > [OUTPUT]\nOPTION:\n" + "-h -hb:\n\t[INPUT] is a Harwell-Boeing format matrix.\n" + "-r -rb:\n\t[INPUT] is a Rutherford-Boeing format matrix.\n" + "-t -triplet:\n\t[INPUT] is a triplet format matrix.\n", + argv[0]); + return 0; + } + else + { + switch (argv[1][1]) + { + case 'H': + case 'h': + printf("Input a Harwell-Boeing format matrix:\n"); + zreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + break; + case 'R': + case 'r': + printf("Input a Rutherford-Boeing format matrix:\n"); + zreadrb(&m, &n, &nnz, &a, &asub, &xa); + break; + case 'T': + case 't': + printf("Input a triplet format matrix:\n"); + zreadtriple(&m, &n, &nnz, &a, &asub, &xa); + break; + default: + printf("Unrecognized format.\n"); + return 0; + } + } + + zCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, + SLU_NC, SLU_Z, SLU_GE); + Astore = A.Store; + zfill_diag(n, Astore); + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + fflush(stdout); + + /* Make a copy of the original matrix. */ + nnz = Astore->nnz; + a_orig = doublecomplexMalloc(nnz); + asub_orig = intMalloc(nnz); + xa_orig = intMalloc(n+1); + for (i = 0; i < nnz; ++i) { + a_orig[i] = ((doublecomplex *)Astore->nzval)[i]; + asub_orig[i] = Astore->rowind[i]; + } + for (i = 0; i <= n; ++i) xa_orig[i] = Astore->colptr[i]; + zCreate_CompCol_Matrix(&AA, m, n, nnz, a_orig, asub_orig, xa_orig, + SLU_NC, SLU_Z, SLU_GE); + + /* Generate the right-hand side */ + if ( !(rhsb = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + zCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_Z, SLU_GE); + zCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_Z, SLU_GE); + xact = doublecomplexMalloc(n * nrhs); + ldx = n; + zGenXtrue(n, nrhs, xact, ldx); + zFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (double *) SUPERLU_MALLOC(A.nrow * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (double *) SUPERLU_MALLOC(A.ncol * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + + info = 0; +#ifdef DEBUG + num_drop_L = 0; + num_drop_U = 0; +#endif + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* Compute the incomplete factorization and compute the condition number + and pivot growth using dgsisx. */ + B.ncol = 0; /* not to perform triangular solution */ + zgsisx(&options, &A, perm_c, perm_r, etree, equed, R, C, &L, &U, work, + lwork, &B, &X, &rpg, &rcond, &Glu, &mem_usage, &stat, &info); + + /* Set RHS for GMRES. */ + if (!(b = doublecomplexMalloc(m))) ABORT("Malloc fails for b[]."); + for (i = 0; i < m; i++) b[i] = rhsb[i]; + + printf("zgsisx(): info %d, equed %c\n", info, equed[0]); + if (info > 0 || rcond < 1e-8 || rpg > 1e8) + printf("WARNING: This preconditioner might be unstable.\n"); + + if ( info == 0 || info == n+1 ) { + if ( options.PivotGrowth == YES ) + printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber == YES ) + printf("Recip. condition number = %e\n", rcond); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("n(A) = %d, nnz(A) = %d\n", n, Astore->nnz); + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("Fill ratio: nnz(F)/nnz(A) = %.3f\n", + ((double)(Lstore->nnz) + (double)(Ustore->nnz) - (double)n) + / (double)Astore->nnz); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + fflush(stdout); + + /* Set the global variables. */ + GLOBAL_A = &A; + GLOBAL_A_ORIG = &AA; + GLOBAL_L = &L; + GLOBAL_U = &U; + GLOBAL_STAT = &stat; + GLOBAL_PERM_C = perm_c; + GLOBAL_PERM_R = perm_r; + GLOBAL_OPTIONS = &options; + GLOBAL_EQUED = equed; + GLOBAL_R = R; + GLOBAL_C = C; + GLOBAL_MEM_USAGE = &mem_usage; + + /* Set the options to do solve-only. */ + options.Fact = FACTORED; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + + /* Set the variables used by GMRES. */ + restrt = SUPERLU_MIN(n / 3 + 1, 50); + maxit = 1000; + iter = maxit; + resid = 1e-8; + if (!(x = doublecomplexMalloc(n))) ABORT("Malloc fails for x[]."); + + if (info <= n + 1) + { + int i_1 = 1; + double maxferr = 0.0, nrmA, nrmB, res, t; + doublecomplex temp; + extern double dznrm2_(int *, doublecomplex [], int *); + extern void zaxpy_(int *, doublecomplex *, doublecomplex [], int *, doublecomplex [], int *); + + /* Initial guess */ + for (i = 0; i < n; i++) x[i] = zero; + + t = SuperLU_timer_(); + + /* Call GMRES */ + zfgmr(n, zmatvec_mult, zpsolve, b, x, resid, restrt, &iter, stdout); + + t = SuperLU_timer_() - t; + + /* Output the result. */ + nrmA = dznrm2_(&(Astore->nnz), (doublecomplex *)((DNformat *)A.Store)->nzval, + &i_1); + nrmB = dznrm2_(&m, b, &i_1); + sp_zgemv("N", none, &AA, x, 1, one, b, 1); /* Original matrix */ + res = dznrm2_(&m, b, &i_1); + resid = res / nrmB; + printf("||A||_F = %.1e, ||B||_2 = %.1e, ||B-A*X||_2 = %.1e, " + "relres = %.1e\n", nrmA, nrmB, res, resid); + + if (iter >= maxit) + { + if (resid >= 1.0) iter = -180; + else if (resid > 1e-8) iter = -111; + } + printf("iteration: %d\nresidual: %.1e\nGMRES time: %.2f seconds.\n", + iter, resid, t); + + for (i = 0; i < m; i++) { + z_sub(&temp, &x[i], &xact[i]); + maxferr = SUPERLU_MAX(maxferr, z_abs1(&temp)); + } + printf("||X-X_true||_oo = %.1e\n", maxferr); + } +#ifdef DEBUG + printf("%d entries in L and %d entries in U dropped.\n", + num_drop_L, num_drop_U); +#endif + fflush(stdout); + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + Destroy_CompCol_Matrix(&A); + Destroy_CompCol_Matrix(&AA); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork >= 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } + SUPERLU_FREE(b); + SUPERLU_FREE(x); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsol.c b/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsol.c new file mode 100644 index 00000000..76454d19 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsol.c @@ -0,0 +1,126 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 3.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + */ +#include "slu_zdefs.h" + +int main(int argc, char *argv[]) +{ + SuperMatrix A; + NCformat *Astore; + doublecomplex *a; + int *asub, *xa; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + SuperMatrix L; /* factor L */ + SCformat *Lstore; + SuperMatrix U; /* factor U */ + NCformat *Ustore; + SuperMatrix B; + int nrhs, ldx, info, m, n, nnz; + doublecomplex *xact, *rhs; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Read the matrix in Harwell-Boeing format. */ + zreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + zCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_Z, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + nrhs = 1; + if ( !(rhs = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhs[]."); + zCreate_Dense_Matrix(&B, m, nrhs, rhs, m, SLU_DN, SLU_Z, SLU_GE); + xact = doublecomplexMalloc(n * nrhs); + ldx = n; + zGenXtrue(n, nrhs, xact, ldx); + zFillRHS(options.Trans, nrhs, xact, ldx, &A, &B); + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + zgssv(&options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info); + + if ( info == 0 ) { + + /* This is how you could access the solution matrix. */ + doublecomplex *sol = (doublecomplex*) ((DNformat*) B.Store)->nzval; + + /* Compute the infinity norm of the error. */ + zinf_norm_error(nrhs, &B, xact); + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + zQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + + } else { + printf("zgssv() error returns INFO= %d\n", info); + if ( info <= n ) { /* factorization completes */ + zQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + } + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhs); + SUPERLU_FREE (xact); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsol1.c b/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsol1.c new file mode 100644 index 00000000..3974d4de --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsol1.c @@ -0,0 +1,131 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 3.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + */ +#include "slu_zdefs.h" + +int main(int argc, char *argv[]) +{ + SuperMatrix A; + NCformat *Astore; + doublecomplex *a; + int *asub, *xa; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + SuperMatrix L; /* factor L */ + SCformat *Lstore; + SuperMatrix U; /* factor U */ + NCformat *Ustore; + SuperMatrix B; + int nrhs, ldx, info, m, n, nnz; + doublecomplex *xact, *rhs; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Now we modify the default options to use the symmetric mode. */ + options.SymmetricMode = YES; + options.ColPerm = MMD_AT_PLUS_A; + options.DiagPivotThresh = 0.001; + + /* Read the matrix in Harwell-Boeing format. */ + zreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + zCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_Z, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + nrhs = 1; + if ( !(rhs = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhs[]."); + zCreate_Dense_Matrix(&B, m, nrhs, rhs, m, SLU_DN, SLU_Z, SLU_GE); + xact = doublecomplexMalloc(n * nrhs); + ldx = n; + zGenXtrue(n, nrhs, xact, ldx); + zFillRHS(options.Trans, nrhs, xact, ldx, &A, &B); + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + zgssv(&options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info); + + if ( info == 0 ) { + + /* This is how you could access the solution matrix. */ + doublecomplex *sol = (doublecomplex*) ((DNformat*) B.Store)->nzval; + + /* Compute the infinity norm of the error. */ + zinf_norm_error(nrhs, &B, xact); + + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + zQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + + } else { + printf("zgssv() error returns INFO= %d\n", info); + if ( info <= n ) { /* factorization completes */ + zQuerySpace(&L, &U, &mem_usage); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + } + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhs); + SUPERLU_FREE (xact); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsolx.c b/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsolx.c new file mode 100644 index 00000000..b916bd3b --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsolx.c @@ -0,0 +1,226 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 3.1) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * August 1, 2008 + * + */ +#include "slu_zdefs.h" + +int main(int argc, char *argv[]) +{ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + doublecomplex *a; + int *asub, *xa; + int *perm_r; /* row permutations from partial pivoting */ + int *perm_c; /* column permutation vector */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, m, n, nnz; + doublecomplex *rhsb, *rhsx, *xact; + double *R, *C; + double *ferr, *berr; + double u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + /* Add more functionalities that the defaults. */ + options.PivotGrowth = YES; /* Compute reciprocal pivot growth */ + options.ConditionNumber = YES;/* Compute reciprocal condition number */ + options.IterRefine = SLU_DOUBLE; /* Perform double-precision refinement */ + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("ZLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + zreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + zCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_Z, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + zCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_Z, SLU_GE); + zCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_Z, SLU_GE); + xact = doublecomplexMalloc(n * nrhs); + ldx = n; + zGenXtrue(n, nrhs, xact, ldx); + zFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (double *) SUPERLU_MALLOC(A.nrow * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (double *) SUPERLU_MALLOC(A.ncol * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* Solve the system and compute the condition number + and error bounds using dgssvx. */ + + zgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("zgssvx(): info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + doublecomplex *sol = (doublecomplex*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth == YES ) + printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber == YES ) + printf("Recip. condition number = %e\n", rcond); + if ( options.IterRefine != NOREFINE ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork == 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + + +/* + * Parse command line inputs. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + double *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:w:r:u:f:t:p:e:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsolx1.c b/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsolx1.c new file mode 100644 index 00000000..843772ea --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsolx1.c @@ -0,0 +1,257 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 5.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + * Last update: July 10, 2015 + * + */ +#include "slu_zdefs.h" + +int main(int argc, char *argv[]) +{ +/* + * Purpose + * ======= + * + * The driver program ZLINSOLX1. + * + * This example illustrates how to use ZGSSVX to solve systems with the same + * A but different right-hand side. + * In this case, we factorize A only once in the first call to DGSSVX, + * and reuse the following data structures in the subsequent call to ZGSSVX: + * perm_c, perm_r, R, C, L, U. + * + */ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, L, U; + SuperMatrix B, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + doublecomplex *a; + int *asub, *xa; + int *perm_c; /* column permutation vector */ + int *perm_r; /* row permutations from partial pivoting */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, m, n, nnz; + doublecomplex *rhsb, *rhsx, *xact; + double *R, *C; + double *ferr, *berr; + double u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default values for options argument: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("ZLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + zreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + + zCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_Z, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsx = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + zCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_Z, SLU_GE); + zCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_Z, SLU_GE); + xact = doublecomplexMalloc(n * nrhs); + ldx = n; + zGenXtrue(n, nrhs, xact, ldx); + zFillRHS(trans, nrhs, xact, ldx, &A, &B); + + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(R = (double *) SUPERLU_MALLOC(A.nrow * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (double *) SUPERLU_MALLOC(A.ncol * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* ONLY PERFORM THE LU DECOMPOSITION */ + B.ncol = 0; /* Indicate not to solve the system */ + zgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("LU factorization: zgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + /* ------------------------------------------------------------ + NOW WE SOLVE THE LINEAR SYSTEM USING THE FACTORED FORM OF A. + ------------------------------------------------------------*/ + options.Fact = FACTORED; /* Indicate the factored form of A is supplied. */ + B.ncol = nrhs; /* Set the number of right-hand side */ + + /* Initialize the statistics variables. */ + StatInit(&stat); + + zgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("Triangular solve: zgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + doublecomplex *sol = (doublecomplex*) ((DNformat*) X.Store)->nzval; + + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (rhsb); + SUPERLU_FREE (rhsx); + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A); + Destroy_SuperMatrix_Store(&B); + Destroy_SuperMatrix_Store(&X); + if ( lwork == 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + +/* + * Parse command line options to get relaxed snode size, panel size, etc. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + double *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:u:e:t:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsolx2.c b/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsolx2.c new file mode 100644 index 00000000..aa1069aa --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsolx2.c @@ -0,0 +1,293 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 5.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + * Last update: July 10, 2015 + * + */ +#include "slu_zdefs.h" + +int main(int argc, char *argv[]) +{ +/* + * Purpose + * ======= + * + * The driver program ZLINSOLX2. + * + * This example illustrates how to use ZGSSVX to solve systems repeatedly + * with the same sparsity pattern of matrix A. + * In this case, the column permutation vector perm_c is computed once. + * The following data structures will be reused in the subsequent call to + * ZGSSVX: perm_c, etree + * + */ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, A1, L, U; + SuperMatrix B, B1, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; /* facilitate multiple factorizations with + SamePattern_SameRowPerm */ + doublecomplex *a, *a1; + int *asub, *xa, *asub1, *xa1; + int *perm_r; /* row permutations from partial pivoting */ + int *perm_c; /* column permutation vector */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, j, m, n, nnz; + doublecomplex *rhsb, *rhsb1, *rhsx, *xact; + double *R, *C; + double *ferr, *berr; + double u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("DLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + zreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + if ( !(a1 = doublecomplexMalloc(nnz)) ) ABORT("Malloc fails for a1[]."); + if ( !(asub1 = intMalloc(nnz)) ) ABORT("Malloc fails for asub1[]."); + if ( !(xa1 = intMalloc(n+1)) ) ABORT("Malloc fails for xa1[]."); + for (i = 0; i < nnz; ++i) { + a1[i] = a[i]; + asub1[i] = asub[i]; + } + for (i = 0; i < n+1; ++i) xa1[i] = xa[i]; + + zCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_Z, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsb1 = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb1[]."); + if ( !(rhsx = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + zCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_Z, SLU_GE); + zCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_Z, SLU_GE); + xact = doublecomplexMalloc(n * nrhs); + ldx = n; + zGenXtrue(n, nrhs, xact, ldx); + zFillRHS(trans, nrhs, xact, ldx, &A, &B); + for (j = 0; j < nrhs; ++j) + for (i = 0; i < m; ++i) rhsb1[i+j*m] = rhsb[i+j*m]; + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(R = (double *) SUPERLU_MALLOC(A.nrow * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (double *) SUPERLU_MALLOC(A.ncol * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* ------------------------------------------------------------ + WE SOLVE THE LINEAR SYSTEM FOR THE FIRST TIME: AX = B + ------------------------------------------------------------*/ + zgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("First system: zgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + doublecomplex *sol = (doublecomplex*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + Destroy_CompCol_Matrix(&A); + Destroy_Dense_Matrix(&B); + if ( lwork >= 0 ) { /* Deallocate storage associated with L and U. */ + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } + + /* ------------------------------------------------------------ + NOW WE SOLVE ANOTHER LINEAR SYSTEM: A1*X = B1 + ONLY THE SPARSITY PATTERN OF A1 IS THE SAME AS THAT OF A. + ------------------------------------------------------------*/ + options.Fact = SamePattern; + StatInit(&stat); /* Initialize the statistics variables. */ + + zCreate_CompCol_Matrix(&A1, m, n, nnz, a1, asub1, xa1, + SLU_NC, SLU_Z, SLU_GE); + zCreate_Dense_Matrix(&B1, m, nrhs, rhsb1, m, SLU_DN, SLU_Z, SLU_GE); + + zgssvx(&options, &A1, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B1, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("\nSecond system: zgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + doublecomplex *sol = (doublecomplex*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A1); + Destroy_Dense_Matrix(&B1); + Destroy_Dense_Matrix(&X); + if ( lwork == 0 ) { + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + +/* + * Parse command line options to get relaxed snode size, panel size, etc. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + double *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:u:e:t:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsolx3.c b/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsolx3.c new file mode 100644 index 00000000..94b298f4 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/EXAMPLE/zlinsolx3.c @@ -0,0 +1,288 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/* + * -- SuperLU routine (version 5.0) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * October 15, 2003 + * + * Last update: July 10, 2015 + * + */ +#include "slu_zdefs.h" + +int main(int argc, char *argv[]) +{ +/* + * Purpose + * ======= + * + * The driver program ZLINSOLX2. + * + * This example illustrates how to use ZGSSVX to solve systems repeatedly + * with the same sparsity pattern and similar values of matrix A. + * In this case, the permutation vectors perm_r and perm_c are computed once. + * The following data structures will be reused in the subsequent call to + * ZGSSVX: perm_r, perm_c, etree, L, U. + * + */ + char equed[1]; + yes_no_t equil; + trans_t trans; + SuperMatrix A, A1, L, U; + SuperMatrix B, B1, X; + NCformat *Astore; + NCformat *Ustore; + SCformat *Lstore; + GlobalLU_t Glu; + doublecomplex *a, *a1; + int *asub, *xa, *asub1, *xa1; + int *perm_r; /* row permutations from partial pivoting */ + int *perm_c; /* column permutation vector */ + int *etree; + void *work; + int info, lwork, nrhs, ldx; + int i, j, m, n, nnz; + doublecomplex *rhsb, *rhsb1, *rhsx, *xact; + double *R, *C; + double *ferr, *berr; + double u, rpg, rcond; + mem_usage_t mem_usage; + superlu_options_t options; + SuperLUStat_t stat; + FILE *fp = stdin; + + extern void parse_command_line(); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter main()"); +#endif + + /* Defaults */ + lwork = 0; + nrhs = 1; + equil = YES; + u = 1.0; + trans = NOTRANS; + + /* Set the default input options: + options.Fact = DOFACT; + options.Equil = YES; + options.ColPerm = COLAMD; + options.DiagPivotThresh = 1.0; + options.Trans = NOTRANS; + options.IterRefine = NOREFINE; + options.SymmetricMode = NO; + options.PivotGrowth = NO; + options.ConditionNumber = NO; + options.PrintStat = YES; + */ + set_default_options(&options); + + /* Can use command line input to modify the defaults. */ + parse_command_line(argc, argv, &lwork, &u, &equil, &trans); + options.Equil = equil; + options.DiagPivotThresh = u; + options.Trans = trans; + + if ( lwork > 0 ) { + work = SUPERLU_MALLOC(lwork); + if ( !work ) { + ABORT("DLINSOLX: cannot allocate work[]"); + } + } + + /* Read matrix A from a file in Harwell-Boeing format.*/ + zreadhb(fp, &m, &n, &nnz, &a, &asub, &xa); + if ( !(a1 = doublecomplexMalloc(nnz)) ) ABORT("Malloc fails for a1[]."); + if ( !(asub1 = intMalloc(nnz)) ) ABORT("Malloc fails for asub1[]."); + if ( !(xa1 = intMalloc(n+1)) ) ABORT("Malloc fails for xa1[]."); + for (i = 0; i < nnz; ++i) { + a1[i] = a[i]; + asub1[i] = asub[i]; + } + for (i = 0; i < n+1; ++i) xa1[i] = xa[i]; + + zCreate_CompCol_Matrix(&A, m, n, nnz, a, asub, xa, SLU_NC, SLU_Z, SLU_GE); + Astore = A.Store; + printf("Dimension %dx%d; # nonzeros %d\n", A.nrow, A.ncol, Astore->nnz); + + if ( !(rhsb = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb[]."); + if ( !(rhsb1 = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsb1[]."); + if ( !(rhsx = doublecomplexMalloc(m * nrhs)) ) ABORT("Malloc fails for rhsx[]."); + zCreate_Dense_Matrix(&B, m, nrhs, rhsb, m, SLU_DN, SLU_Z, SLU_GE); + zCreate_Dense_Matrix(&X, m, nrhs, rhsx, m, SLU_DN, SLU_Z, SLU_GE); + xact = doublecomplexMalloc(n * nrhs); + ldx = n; + zGenXtrue(n, nrhs, xact, ldx); + zFillRHS(trans, nrhs, xact, ldx, &A, &B); + for (j = 0; j < nrhs; ++j) + for (i = 0; i < m; ++i) rhsb1[i+j*m] = rhsb[i+j*m]; + + if ( !(perm_c = intMalloc(n)) ) ABORT("Malloc fails for perm_c[]."); + if ( !(perm_r = intMalloc(m)) ) ABORT("Malloc fails for perm_r[]."); + if ( !(etree = intMalloc(n)) ) ABORT("Malloc fails for etree[]."); + if ( !(R = (double *) SUPERLU_MALLOC(A.nrow * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for R[]."); + if ( !(C = (double *) SUPERLU_MALLOC(A.ncol * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for C[]."); + if ( !(ferr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for ferr[]."); + if ( !(berr = (double *) SUPERLU_MALLOC(nrhs * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for berr[]."); + + /* Initialize the statistics variables. */ + StatInit(&stat); + + /* ------------------------------------------------------------ + WE SOLVE THE LINEAR SYSTEM FOR THE FIRST TIME: AX = B + ------------------------------------------------------------*/ + zgssvx(&options, &A, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("First system: zgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + doublecomplex *sol = (doublecomplex*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("FILL ratio = %.1f\n", (float)(Lstore->nnz + Ustore->nnz - n)/nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + Destroy_CompCol_Matrix(&A); + Destroy_Dense_Matrix(&B); + + /* ------------------------------------------------------------ + NOW WE SOLVE ANOTHER LINEAR SYSTEM: A1*X = B1 + ONLY THE SPARSITY PATTERN OF A1 IS THE SAME AS THAT OF A. + ------------------------------------------------------------*/ + options.Fact = SamePattern_SameRowPerm; + StatInit(&stat); /* Initialize the statistics variables. */ + + zCreate_CompCol_Matrix(&A1, m, n, nnz, a1, asub1, xa1, + SLU_NC, SLU_Z, SLU_GE); + zCreate_Dense_Matrix(&B1, m, nrhs, rhsb1, m, SLU_DN, SLU_Z, SLU_GE); + + zgssvx(&options, &A1, perm_c, perm_r, etree, equed, R, C, + &L, &U, work, lwork, &B1, &X, &rpg, &rcond, ferr, berr, + &Glu, &mem_usage, &stat, &info); + + printf("\nSecond system: zgssvx() returns info %d\n", info); + + if ( info == 0 || info == n+1 ) { + + /* This is how you could access the solution matrix. */ + doublecomplex *sol = (doublecomplex*) ((DNformat*) X.Store)->nzval; + + if ( options.PivotGrowth ) printf("Recip. pivot growth = %e\n", rpg); + if ( options.ConditionNumber ) + printf("Recip. condition number = %e\n", rcond); + Lstore = (SCformat *) L.Store; + Ustore = (NCformat *) U.Store; + printf("No of nonzeros in factor L = %d\n", Lstore->nnz); + printf("No of nonzeros in factor U = %d\n", Ustore->nnz); + printf("No of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz - n); + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage.for_lu/1e6, mem_usage.total_needed/1e6); + if ( options.IterRefine ) { + printf("Iterative Refinement:\n"); + printf("%8s%8s%16s%16s\n", "rhs", "Steps", "FERR", "BERR"); + for (i = 0; i < nrhs; ++i) + printf("%8d%8d%16e%16e\n", i+1, stat.RefineSteps, ferr[i], berr[i]); + } + fflush(stdout); + } else if ( info > 0 && lwork == -1 ) { + printf("** Estimated memory: %d bytes\n", info - n); + } + + if ( options.PrintStat ) StatPrint(&stat); + StatFree(&stat); + + SUPERLU_FREE (xact); + SUPERLU_FREE (etree); + SUPERLU_FREE (perm_r); + SUPERLU_FREE (perm_c); + SUPERLU_FREE (R); + SUPERLU_FREE (C); + SUPERLU_FREE (ferr); + SUPERLU_FREE (berr); + Destroy_CompCol_Matrix(&A1); + Destroy_Dense_Matrix(&B1); + Destroy_Dense_Matrix(&X); + if ( lwork == 0 ) { /* Deallocate storage associated with L and U. */ + Destroy_SuperNode_Matrix(&L); + Destroy_CompCol_Matrix(&U); + } else if ( lwork > 0 ) { + SUPERLU_FREE(work); + } + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit main()"); +#endif +} + +/* + * Parse command line options to get relaxed snode size, panel size, etc. + */ +void +parse_command_line(int argc, char *argv[], int *lwork, + double *u, yes_no_t *equil, trans_t *trans ) +{ + int c; + extern char *optarg; + + while ( (c = getopt(argc, argv, "hl:u:e:t:")) != EOF ) { + switch (c) { + case 'h': + printf("Options:\n"); + printf("\t-l - length of work[*] array\n"); + printf("\t-u - pivoting threshold\n"); + printf("\t-e <0 or 1> - equilibrate or not\n"); + printf("\t-t <0 or 1> - solve transposed system or not\n"); + exit(1); + break; + case 'l': *lwork = atoi(optarg); + break; + case 'u': *u = atof(optarg); + break; + case 'e': *equil = atoi(optarg); + break; + case 't': *trans = atoi(optarg); + break; + } + } +} diff --git a/src/Libraries/superlu-5.2.1/Makefile b/src/Libraries/superlu-5.2.1/Makefile new file mode 100644 index 00000000..6fd4f957 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/Makefile @@ -0,0 +1,43 @@ +# +# +SHELL = /bin/sh + + +dFILES = ${wildcard ${addsuffix d*.c,./SRC/}} + + +ALLAUX = superlu_timer.c util.c memory.c get_perm_c.c mmd.c \ + sp_coletree.c sp_preorder.c sp_ienv.c relax_snode.c \ + heap_relax_snode.c colamd.c \ + ilu_relax_snode.c ilu_heap_relax_snode.c mark_relax.c \ + mc64ad.c qselect.c input_error.c smach.c dmach.c + +DLUSRC = \ + dgssv.c dgssvx.c \ + dsp_blas2.c dsp_blas3.c dgscon.c \ + dlangs.c dgsequ.c dlaqgs.c dpivotgrowth.c \ + dgsrfs.c dgstrf.c dgstrs.c dcopy_to_ucol.c \ + dsnode_dfs.c dsnode_bmod.c dpanel_dfs.c dpanel_bmod.c \ + dreadhb.c dreadrb.c dreadtriple.c \ + dcolumn_dfs.c dcolumn_bmod.c dpivotL.c dpruneL.c \ + dmemory.c dutil.c dmyblas2.c \ + dgsisx.c dgsitrf.c dldperm.c \ + ilu_ddrop_row.c ilu_dsnode_dfs.c \ + ilu_dcolumn_dfs.c ilu_dpanel_dfs.c ilu_dcopy_to_ucol.c \ + ilu_dpivotL.c ddiagonal.c dlacon2.c + ## dgstrsL.c dgstrsU.c + +FILES = ${DLUSRC} ${ALLAUX} + +test: + @echo "#if defined(__cplusplus)" + @echo " extern "C" {" + @echo "#endif" + @echo + @for i in ${FILES}; do \ + echo "#include \"./SRC/$$i\"" ; \ + done + @echo + @echo "#if defined(__cplusplus)" + @echo " }" + @echo "#endif" diff --git a/src/Libraries/superlu-5.2.1/SRC/.dropbox.attr b/src/Libraries/superlu-5.2.1/SRC/.dropbox.attr new file mode 100755 index 00000000..9e26dfee --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/.dropbox.attr @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/Libraries/superlu-5.2.1/SRC/CMakeLists.txt b/src/Libraries/superlu-5.2.1/SRC/CMakeLists.txt new file mode 100644 index 00000000..bd70af22 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/CMakeLists.txt @@ -0,0 +1,246 @@ + +set(headers + supermatrix.h + slu_Cnames.h + slu_dcomplex.h + slu_scomplex.h + slu_util.h + superlu_enum_consts.h) + +set(sources + superlu_timer.c + util.c + memory.c + get_perm_c.c + mmd.c + sp_coletree.c + sp_preorder.c + sp_ienv.c + relax_snode.c + heap_relax_snode.c + colamd.c + ilu_relax_snode.c + ilu_heap_relax_snode.c + mark_relax.c + mc64ad.c + qselect.c + input_error.c +) +set_source_files_properties(superlu_timer.c PROPERTIES COMPILE_FLAGS -O0) + +if(enable_single) + list(APPEND headers + slu_sdefs.h + ) + + list(APPEND sources + slacon2.c + smach.c + sgssv.c + sgssvx.c + ssp_blas2.c + ssp_blas3.c + sgscon.c + slangs.c + sgsequ.c + slaqgs.c + spivotgrowth.c + sgsrfs.c + sgstrf.c + sgstrs.c + scopy_to_ucol.c + ssnode_dfs.c + ssnode_bmod.c + spanel_dfs.c + spanel_bmod.c + sreadhb.c + sreadrb.c + sreadtriple.c + scolumn_dfs.c + scolumn_bmod.c + spivotL.c + spruneL.c + smemory.c + sutil.c + smyblas2.c + sgsisx.c + sgsitrf.c + sldperm.c + ilu_sdrop_row.c + ilu_ssnode_dfs.c + ilu_scolumn_dfs.c + ilu_spanel_dfs.c + ilu_scopy_to_ucol.c + ilu_spivotL.c + sdiagonal.c + ) + set_source_files_properties(smach.c PROPERTIES COMPILE_FLAGS -O0) +endif() + +if(enable_double) + list(APPEND headers + slu_ddefs.h + ) + + list(APPEND sources + dlacon2.c + dmach.c + dgssv.c + dgssvx.c + dsp_blas2.c + dsp_blas3.c + dgscon.c + dlangs.c + dgsequ.c + dlaqgs.c + dpivotgrowth.c + dgsrfs.c + dgstrf.c + dgstrs.c + dcopy_to_ucol.c + dsnode_dfs.c + dsnode_bmod.c + dpanel_dfs.c + dpanel_bmod.c + dreadhb.c + dreadrb.c + dreadtriple.c + dcolumn_dfs.c + dcolumn_bmod.c + dpivotL.c + dpruneL.c + dmemory.c + dutil.c + dmyblas2.c + dgsisx.c + dgsitrf.c + dldperm.c + ilu_ddrop_row.c + ilu_dsnode_dfs.c + ilu_dcolumn_dfs.c + ilu_dpanel_dfs.c + ilu_dcopy_to_ucol.c + ilu_dpivotL.c + ddiagonal.c + ) + set_source_files_properties(dmach.c PROPERTIES COMPILE_FLAGS -O0) +endif() + +if(enable_complex) + list(APPEND headers + slu_cdefs.h + ) + + list(APPEND sources + clacon2.c + scsum1.c + icmax1.c + scomplex.c + cgssv.c + cgssvx.c + csp_blas2.c + csp_blas3.c + cgscon.c + clangs.c + cgsequ.c + claqgs.c + cpivotgrowth.c + cgsrfs.c + cgstrf.c + cgstrs.c + ccopy_to_ucol.c + csnode_dfs.c + csnode_bmod.c + cpanel_dfs.c + cpanel_bmod.c + creadhb.c + creadrb.c + creadtriple.c + ccolumn_dfs.c + ccolumn_bmod.c + cpivotL.c + cpruneL.c + cmemory.c + cutil.c + cmyblas2.c + cgsisx.c + cgsitrf.c + cldperm.c + ilu_cdrop_row.c + ilu_csnode_dfs.c + ilu_ccolumn_dfs.c + ilu_cpanel_dfs.c + ilu_ccopy_to_ucol.c + ilu_cpivotL.c + cdiagonal.c + ) +endif() + +if(enable_complex16) + list(APPEND headers + slu_zdefs.h + ) + + list(APPEND sources + zlacon2.c + dzsum1.c + izmax1.c + dcomplex.c + zgssv.c + zgssvx.c + zsp_blas2.c + zsp_blas3.c + zgscon.c + zlangs.c + zgsequ.c + zlaqgs.c + zpivotgrowth.c + zgsrfs.c + zgstrf.c + zgstrs.c + zcopy_to_ucol.c + zsnode_dfs.c + zsnode_bmod.c + zpanel_dfs.c + zpanel_bmod.c + zreadhb.c + zreadrb.c + zreadtriple.c + zcolumn_dfs.c + zcolumn_bmod.c + zpivotL.c + zpruneL.c + zmemory.c + zutil.c + zmyblas2.c + zgsisx.c + zgsitrf.c + zldperm.c + ilu_zdrop_row.c + ilu_zsnode_dfs.c + ilu_zcolumn_dfs.c + ilu_zpanel_dfs.c + ilu_zcopy_to_ucol.c + ilu_zpivotL.c + zdiagonal.c + ) +endif() + +add_library(superlu ${sources} ${HEADERS}) + +target_link_libraries(superlu ${BLAS_LIB} m) +set_target_properties(superlu PROPERTIES + VERSION ${PROJECT_VERSION} SOVERSION ${VERSION_MAJOR} + ) + +include(GNUInstallDirs) + +install(TARGETS superlu +# DESTINATION ${CMAKE_INSTALL_PREFIX}/lib + DESTINATION ${CMAKE_INSTALL_LIBDIR} +) + +install(FILES ${headers} +# DESTINATION ${CMAKE_INSTALL_PREFIX}/include + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) diff --git a/src/Libraries/superlu-5.2.1/SRC/Makefile b/src/Libraries/superlu-5.2.1/SRC/Makefile new file mode 100644 index 00000000..b8550ce3 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/Makefile @@ -0,0 +1,128 @@ +# makefile for sparse supernodal LU, implemented in ANSI C +include ../make.inc + +####################################################################### +# This is the makefile to create a library for SuperLU. +# The files are organized as follows: +# +# ALLAUX -- Auxiliary routines called from all precisions of SuperLU +# SLUSRC -- Single precision real SuperLU routines +# DLUSRC -- Double precision real SuperLU routines +# CLUSRC -- Single precision complex SuperLU routines +# ZLUSRC -- Double precision complex SuperLU routines +# +# The library can be set up to include routines for any combination +# of the four precisions. To create or add to the library, enter make +# followed by one or more of the precisions desired. Some examples: +# make single +# make single double +# make single double complex complex16 +# Alternatively, the command +# make +# without any arguments creates a library of all four precisions. +# The library is called +# superlu.a +# and is created at the next higher directory level. +# +# To remove the object files after the library is created, enter +# make clean +# +####################################################################### + +### return machine parameters +SCAUX = smach.o +DZAUX = dmach.o + +### SuperLU +ALLAUX = superlu_timer.o util.o memory.o get_perm_c.o mmd.o \ + sp_coletree.o sp_preorder.o sp_ienv.o relax_snode.o \ + heap_relax_snode.o colamd.o \ + ilu_relax_snode.o ilu_heap_relax_snode.o mark_relax.o \ + mc64ad.o qselect.o input_error.o smach.o dmach.o + +SLUSRC = \ + sgssv.o sgssvx.o \ + ssp_blas2.o ssp_blas3.o sgscon.o \ + slangs.o sgsequ.o slaqgs.o spivotgrowth.o \ + sgsrfs.o sgstrf.o sgstrs.o scopy_to_ucol.o \ + ssnode_dfs.o ssnode_bmod.o \ + spanel_dfs.o spanel_bmod.o \ + sreadhb.o sreadrb.o sreadtriple.o \ + scolumn_dfs.o scolumn_bmod.o spivotL.o spruneL.o \ + smemory.o sutil.o smyblas2.o \ + sgsisx.o sgsitrf.o sldperm.o \ + ilu_sdrop_row.o ilu_ssnode_dfs.o \ + ilu_scolumn_dfs.o ilu_spanel_dfs.o ilu_scopy_to_ucol.o \ + ilu_spivotL.o sdiagonal.o slacon2.o + +DLUSRC = \ + dgssv.o dgssvx.o \ + dsp_blas2.o dsp_blas3.o dgscon.o \ + dlangs.o dgsequ.o dlaqgs.o dpivotgrowth.o \ + dgsrfs.o dgstrf.o dgstrs.o dcopy_to_ucol.o \ + dsnode_dfs.o dsnode_bmod.o dpanel_dfs.o dpanel_bmod.o \ + dreadhb.o dreadrb.o dreadtriple.o \ + dcolumn_dfs.o dcolumn_bmod.o dpivotL.o dpruneL.o \ + dmemory.o dutil.o dmyblas2.o \ + dgsisx.o dgsitrf.o dldperm.o \ + ilu_ddrop_row.o ilu_dsnode_dfs.o \ + ilu_dcolumn_dfs.o ilu_dpanel_dfs.o ilu_dcopy_to_ucol.o \ + ilu_dpivotL.o ddiagonal.o dlacon2.o + ## dgstrsL.o dgstrsU.o + +CLUSRC = \ + scomplex.o cgssv.o cgssvx.o csp_blas2.o csp_blas3.o cgscon.o \ + clangs.o cgsequ.o claqgs.o cpivotgrowth.o \ + cgsrfs.o cgstrf.o cgstrs.o ccopy_to_ucol.o \ + csnode_dfs.o csnode_bmod.o \ + cpanel_dfs.o cpanel_bmod.o \ + creadhb.o creadrb.o creadtriple.o \ + ccolumn_dfs.o ccolumn_bmod.o cpivotL.o cpruneL.o \ + cmemory.o cutil.o cmyblas2.o \ + cgsisx.o cgsitrf.o cldperm.o \ + ilu_cdrop_row.o ilu_csnode_dfs.o \ + ilu_ccolumn_dfs.o ilu_cpanel_dfs.o ilu_ccopy_to_ucol.o \ + ilu_cpivotL.o cdiagonal.o clacon2.o scsum1.o icmax1.o + +ZLUSRC = \ + dcomplex.o zgssv.o zgssvx.o zsp_blas2.o zsp_blas3.o zgscon.o \ + zlangs.o zgsequ.o zlaqgs.o zpivotgrowth.o \ + zgsrfs.o zgstrf.o zgstrs.o zcopy_to_ucol.o \ + zsnode_dfs.o zsnode_bmod.o \ + zpanel_dfs.o zpanel_bmod.o \ + zreadhb.o zreadrb.o zreadtriple.o \ + zcolumn_dfs.o zcolumn_bmod.o zpivotL.o zpruneL.o \ + zmemory.o zutil.o zmyblas2.o \ + zgsisx.o zgsitrf.o zldperm.o \ + ilu_zdrop_row.o ilu_zsnode_dfs.o \ + ilu_zcolumn_dfs.o ilu_zpanel_dfs.o ilu_zcopy_to_ucol.o \ + ilu_zpivotL.o zdiagonal.o zlacon2.o dzsum1.o izmax1.o + +all: single double complex complex16 + +single: $(SLUSRC) $(ALLAUX) $(SCAUX) + $(ARCH) $(ARCHFLAGS) $(SUPERLULIB) $(SLUSRC) $(ALLAUX) $(SCAUX) + $(RANLIB) $(SUPERLULIB) + +double: $(DLUSRC) $(ALLAUX) $(DZLAUX) + $(ARCH) $(ARCHFLAGS) $(SUPERLULIB) $(DLUSRC) $(ALLAUX) $(DZLAUX) + $(RANLIB) $(SUPERLULIB) + +complex: $(CLUSRC) $(ALLAUX) $(SCAUX) + $(ARCH) $(ARCHFLAGS) $(SUPERLULIB) $(CLUSRC) $(ALLAUX) $(SCAUX) + $(RANLIB) $(SUPERLULIB) + +complex16: $(ZLUSRC) $(ALLAUX) $(DZLAUX) + $(ARCH) $(ARCHFLAGS) $(SUPERLULIB) $(ZLUSRC) $(ALLAUX) $(DZLAUX) + $(RANLIB) $(SUPERLULIB) + +################################## + +.c.o: + $(CC) $(CFLAGS) $(CDEFS) $(BLASDEF) -c $< $(VERBOSE) + +.f.o: + $(FORTRAN) $(FFLAGS) -c $< + +clean: + rm -f *.o $(SUPERLULIB) diff --git a/src/Libraries/superlu-5.2.1/SRC/ccolumn_bmod.c b/src/Libraries/superlu-5.2.1/SRC/ccolumn_bmod.c new file mode 100644 index 00000000..ae507c9a --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ccolumn_bmod.c @@ -0,0 +1,375 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ccolumn_bmod.c + * \brief performs numeric block updates + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ *  Permission is hereby granted to use or copy this program for any
+ *  purpose, provided the above notices are retained on all copies.
+ *  Permission to modify the code and to distribute modified code is
+ *  granted, provided the above notices are retained, and a notice that
+ *  the code was modified is included with the above copyright notice.
+ * 
+*/ + +#include +#include +#include "slu_cdefs.h" + +/* + * Function prototypes + */ +void cusolve(int, int, complex*, complex*); +void clsolve(int, int, complex*, complex*); +void cmatvec(int, int, int, complex*, complex*, complex*); + + + +/*! \brief + * + *
+ * Purpose:
+ * ========
+ * Performs numeric block updates (sup-col) in topological order.
+ * It features: col-col, 2cols-col, 3cols-col, and sup-col updates.
+ * Special processing on the supernodal portion of L\U[*,j]
+ * Return value:   0 - successful return
+ *               > 0 - number of bytes allocated when run out of space
+ * 
+ */ +int +ccolumn_bmod ( + const int jcol, /* in */ + const int nseg, /* in */ + complex *dense, /* in */ + complex *tempv, /* working array */ + int *segrep, /* in */ + int *repfnz, /* in */ + int fpanelc, /* in -- first column in the current panel */ + GlobalLU_t *Glu, /* modified */ + SuperLUStat_t *stat /* output */ + ) +{ + +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + int incx = 1, incy = 1; + complex alpha, beta; + + /* krep = representative of current k-th supernode + * fsupc = first supernodal column + * nsupc = no of columns in supernode + * nsupr = no of rows in supernode (used as leading dimension) + * luptr = location of supernodal LU-block in storage + * kfnz = first nonz in the k-th supernodal segment + * no_zeros = no of leading zeros in a supernodal U-segment + */ + complex ukj, ukj1, ukj2; + int luptr, luptr1, luptr2; + int fsupc, nsupc, nsupr, segsze; + int nrow; /* No of rows in the matrix of matrix-vector */ + int jcolp1, jsupno, k, ksub, krep, krep_ind, ksupno; + register int lptr, kfnz, isub, irow, i; + register int no_zeros, new_next; + int ufirst, nextlu; + int fst_col; /* First column within small LU update */ + int d_fsupc; /* Distance between the first column of the current + panel and the first column of the current snode. */ + int *xsup, *supno; + int *lsub, *xlsub; + complex *lusup; + int *xlusup; + int nzlumax; + complex *tempv1; + complex zero = {0.0, 0.0}; + complex one = {1.0, 0.0}; + complex none = {-1.0, 0.0}; + complex comp_temp, comp_temp1; + int mem_error; + flops_t *ops = stat->ops; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (complex *) Glu->lusup; + xlusup = Glu->xlusup; + nzlumax = Glu->nzlumax; + jcolp1 = jcol + 1; + jsupno = supno[jcol]; + + /* + * For each nonz supernode segment of U[*,j] in topological order + */ + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { + + krep = segrep[k]; + k--; + ksupno = supno[krep]; + if ( jsupno != ksupno ) { /* Outside the rectangular supernode */ + + fsupc = xsup[ksupno]; + fst_col = SUPERLU_MAX ( fsupc, fpanelc ); + + /* Distance from the current supernode to the current panel; + d_fsupc=0 if fsupc > fpanelc. */ + d_fsupc = fst_col - fsupc; + + luptr = xlusup[fst_col] + d_fsupc; + lptr = xlsub[fsupc] + d_fsupc; + + kfnz = repfnz[krep]; + kfnz = SUPERLU_MAX ( kfnz, fpanelc ); + + segsze = krep - kfnz + 1; + nsupc = krep - fst_col + 1; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; /* Leading dimension */ + nrow = nsupr - d_fsupc - nsupc; + krep_ind = lptr + nsupc - 1; + + + + + /* + * Case 1: Update U-segment of size 1 -- col-col update + */ + if ( segsze == 1 ) { + ukj = dense[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc; + + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + cc_mult(&comp_temp, &ukj, &lusup[luptr]); + c_sub(&dense[irow], &dense[irow], &comp_temp); + luptr++; + } + + } else if ( segsze <= 3 ) { + ukj = dense[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc-1; + ukj1 = dense[lsub[krep_ind - 1]]; + luptr1 = luptr - nsupr; + + if ( segsze == 2 ) { /* Case 2: 2cols-col update */ + cc_mult(&comp_temp, &ukj1, &lusup[luptr1]); + c_sub(&ukj, &ukj, &comp_temp); + dense[lsub[krep_ind]] = ukj; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; + luptr1++; + cc_mult(&comp_temp, &ukj, &lusup[luptr]); + cc_mult(&comp_temp1, &ukj1, &lusup[luptr1]); + c_add(&comp_temp, &comp_temp, &comp_temp1); + c_sub(&dense[irow], &dense[irow], &comp_temp); + } + } else { /* Case 3: 3cols-col update */ + ukj2 = dense[lsub[krep_ind - 2]]; + luptr2 = luptr1 - nsupr; + cc_mult(&comp_temp, &ukj2, &lusup[luptr2-1]); + c_sub(&ukj1, &ukj1, &comp_temp); + + cc_mult(&comp_temp, &ukj1, &lusup[luptr1]); + cc_mult(&comp_temp1, &ukj2, &lusup[luptr2]); + c_add(&comp_temp, &comp_temp, &comp_temp1); + c_sub(&ukj, &ukj, &comp_temp); + + dense[lsub[krep_ind]] = ukj; + dense[lsub[krep_ind-1]] = ukj1; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; + luptr1++; + luptr2++; + cc_mult(&comp_temp, &ukj, &lusup[luptr]); + cc_mult(&comp_temp1, &ukj1, &lusup[luptr1]); + c_add(&comp_temp, &comp_temp, &comp_temp1); + cc_mult(&comp_temp1, &ukj2, &lusup[luptr2]); + c_add(&comp_temp, &comp_temp, &comp_temp1); + c_sub(&dense[irow], &dense[irow], &comp_temp); + } + } + + + } else { + /* + * Case: sup-col update + * Perform a triangular solve and block update, + * then scatter the result of sup-col update to dense + */ + + no_zeros = kfnz - fst_col; + + /* Copy U[*,j] segment from dense[*] to tempv[*] */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + tempv[i] = dense[irow]; + ++isub; + } + + /* Dense triangular solve -- start effective triangle */ + luptr += nsupr * no_zeros + no_zeros; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + CTRSV( ftcs1, ftcs2, ftcs3, &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#else + ctrsv_( "L", "N", "U", &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#endif + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + alpha = one; + beta = zero; +#ifdef _CRAY + CGEMV( ftcs2, &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#else + cgemv_( "N", &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#endif +#else + clsolve ( nsupr, segsze, &lusup[luptr], tempv ); + + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + cmatvec (nsupr, nrow , segsze, &lusup[luptr], tempv, tempv1); +#endif + + + /* Scatter tempv[] into SPA dense[] as a temporary storage */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + dense[irow] = tempv[i]; + tempv[i] = zero; + ++isub; + } + + /* Scatter tempv1[] into SPA dense[] */ + for (i = 0; i < nrow; i++) { + irow = lsub[isub]; + c_sub(&dense[irow], &dense[irow], &tempv1[i]); + tempv1[i] = zero; + ++isub; + } + } + + } /* if jsupno ... */ + + } /* for each segment... */ + + /* + * Process the supernodal portion of L\U[*,j] + */ + nextlu = xlusup[jcol]; + fsupc = xsup[jsupno]; + + /* Copy the SPA dense into L\U[*,j] */ + new_next = nextlu + xlsub[fsupc+1] - xlsub[fsupc]; + while ( new_next > nzlumax ) { + if (mem_error = cLUMemXpand(jcol, nextlu, LUSUP, &nzlumax, Glu)) + return (mem_error); + lusup = (complex *) Glu->lusup; + lsub = Glu->lsub; + } + + for (isub = xlsub[fsupc]; isub < xlsub[fsupc+1]; isub++) { + irow = lsub[isub]; + lusup[nextlu] = dense[irow]; + dense[irow] = zero; + ++nextlu; + } + + xlusup[jcolp1] = nextlu; /* Close L\U[*,jcol] */ + + /* For more updates within the panel (also within the current supernode), + * should start from the first column of the panel, or the first column + * of the supernode, whichever is bigger. There are 2 cases: + * 1) fsupc < fpanelc, then fst_col := fpanelc + * 2) fsupc >= fpanelc, then fst_col := fsupc + */ + fst_col = SUPERLU_MAX ( fsupc, fpanelc ); + + if ( fst_col < jcol ) { + + /* Distance between the current supernode and the current panel. + d_fsupc=0 if fsupc >= fpanelc. */ + d_fsupc = fst_col - fsupc; + + lptr = xlsub[fsupc] + d_fsupc; + luptr = xlusup[fst_col] + d_fsupc; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; /* Leading dimension */ + nsupc = jcol - fst_col; /* Excluding jcol */ + nrow = nsupr - d_fsupc - nsupc; + + /* Points to the beginning of jcol in snode L\U(jsupno) */ + ufirst = xlusup[jcol] + d_fsupc; + + ops[TRSV] += 4 * nsupc * (nsupc - 1); + ops[GEMV] += 8 * nrow * nsupc; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + CTRSV( ftcs1, ftcs2, ftcs3, &nsupc, &lusup[luptr], + &nsupr, &lusup[ufirst], &incx ); +#else + ctrsv_( "L", "N", "U", &nsupc, &lusup[luptr], + &nsupr, &lusup[ufirst], &incx ); +#endif + + alpha = none; beta = one; /* y := beta*y + alpha*A*x */ + +#ifdef _CRAY + CGEMV( ftcs2, &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#else + cgemv_( "N", &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#endif +#else + clsolve ( nsupr, nsupc, &lusup[luptr], &lusup[ufirst] ); + + cmatvec ( nsupr, nrow, nsupc, &lusup[luptr+nsupc], + &lusup[ufirst], tempv ); + + /* Copy updates from tempv[*] into lusup[*] */ + isub = ufirst + nsupc; + for (i = 0; i < nrow; i++) { + c_sub(&lusup[isub], &lusup[isub], &tempv[i]); + tempv[i] = zero; + ++isub; + } + +#endif + + + } /* if fst_col < jcol ... */ + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ccolumn_dfs.c b/src/Libraries/superlu-5.2.1/SRC/ccolumn_dfs.c new file mode 100644 index 00000000..8fa6587e --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ccolumn_dfs.c @@ -0,0 +1,281 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ccolumn_dfs.c + * \brief Performs a symbolic factorization + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+*/ + +#include "slu_cdefs.h" + +/*! \brief What type of supernodes we want */ +#define T2_SUPER + + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   CCOLUMN_DFS performs a symbolic factorization on column jcol, and
+ *   decide the supernode boundary.
+ *
+ *   This routine does not use numeric values, but only use the RHS 
+ *   row indices to start the dfs.
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives. The routine returns a list of such supernodal 
+ *   representatives in topological order of the dfs that generates them.
+ *   The location of the first nonzero in each such supernodal segment
+ *   (supernodal entry location) is also returned.
+ *
+ * Local parameters
+ * ================
+ *   nseg: no of segments in current U[*,j]
+ *   jsuper: jsuper=EMPTY if column j does not belong to the same
+ *	supernode as j-1. Otherwise, jsuper=nsuper.
+ *
+ *   marker2: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ *
+ * Return value
+ * ============
+ *     0  success;
+ *   > 0  number of bytes allocated when run out of space.
+ * 
+ */ +int +ccolumn_dfs( + const int m, /* in - number of rows in the matrix */ + const int jcol, /* in */ + int *perm_r, /* in */ + int *nseg, /* modified - with new segments appended */ + int *lsub_col, /* in - defines the RHS vector to start the dfs */ + int *segrep, /* modified - with new segments appended */ + int *repfnz, /* modified */ + int *xprune, /* modified */ + int *marker, /* modified */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ + ) +{ + + int jcolp1, jcolm1, jsuper, nsuper, nextl; + int k, krep, krow, kmark, kperm; + int *marker2; /* Used for small panel LU */ + int fsupc; /* First column of a snode */ + int myfnz; /* First nonz column of a U-segment */ + int chperm, chmark, chrep, kchild; + int xdfs, maxdfs, kpar, oldrep; + int jptr, jm1ptr; + int ito, ifrom, istop; /* Used to compress row subscripts */ + int mem_error; + int *xsup, *supno, *lsub, *xlsub; + int nzlmax; + int maxsuper; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + maxsuper = sp_ienv(3); + jcolp1 = jcol + 1; + jcolm1 = jcol - 1; + nsuper = supno[jcol]; + jsuper = nsuper; + nextl = xlsub[jcol]; + marker2 = &marker[2*m]; + + /* For each nonzero in A[*,jcol] do dfs */ + for (k = 0; lsub_col[k] != EMPTY; k++) { + + krow = lsub_col[k]; + lsub_col[k] = EMPTY; + kmark = marker2[krow]; + + /* krow was visited before, go to the next nonz */ + if ( kmark == jcol ) continue; + + /* For each unmarked nbr krow of jcol + * krow is in L: place it in structure of L[*,jcol] + */ + marker2[krow] = jcol; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + lsub[nextl++] = krow; /* krow is indexed into A */ + if ( nextl >= nzlmax ) { + if ( mem_error = cLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + if ( kmark != jcolm1 ) jsuper = EMPTY;/* Row index subset testing */ + } else { + /* krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz[krep]; + + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > kperm ) repfnz[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz[krep] = kperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; + + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker2[kchild]; + + if ( chmark != jcol ) { /* Not reached yet */ + marker2[kchild] = jcol; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,k] */ + if ( chperm == EMPTY ) { + lsub[nextl++] = kchild; + if ( nextl >= nzlmax ) { + if ( mem_error = + cLUMemXpand(jcol,nextl,LSUB,&nzlmax,Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + if ( chmark != jcolm1 ) jsuper = EMPTY; + } else { + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz[chrep]; + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz[chrep] = chperm; + } else { + /* Continue dfs at super-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L^t) */ + parent[krep] = oldrep; + repfnz[krep] = chperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; + } /* else */ + + } /* else */ + + } /* if */ + + } /* while */ + + /* krow has no more unexplored nbrs; + * place supernode-rep krep in postorder DFS. + * backtrack dfs to its parent + */ + segrep[*nseg] = krep; + ++(*nseg); + kpar = parent[krep]; /* Pop from stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xprune[krep]; + + } while ( kpar != EMPTY ); /* Until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonzero ... */ + + /* Check to see if j belongs in the same supernode as j-1 */ + if ( jcol == 0 ) { /* Do nothing for column 0 */ + nsuper = supno[0] = 0; + } else { + fsupc = xsup[nsuper]; + jptr = xlsub[jcol]; /* Not compressed yet */ + jm1ptr = xlsub[jcolm1]; + +#ifdef T2_SUPER + if ( (nextl-jptr != jptr-jm1ptr-1) ) jsuper = EMPTY; +#endif + /* Make sure the number of columns in a supernode doesn't + exceed threshold. */ + if ( jcol - fsupc >= maxsuper ) jsuper = EMPTY; + + /* If jcol starts a new supernode, reclaim storage space in + * lsub from the previous supernode. Note we only store + * the subscript set of the first and last columns of + * a supernode. (first for num values, last for pruning) + */ + if ( jsuper == EMPTY ) { /* starts a new supernode */ + if ( (fsupc < jcolm1-1) ) { /* >= 3 columns in nsuper */ +#ifdef CHK_COMPRESS + printf(" Compress lsub[] at super %d-%d\n", fsupc, jcolm1); +#endif + ito = xlsub[fsupc+1]; + xlsub[jcolm1] = ito; + istop = ito + jptr - jm1ptr; + xprune[jcolm1] = istop; /* Initialize xprune[jcol-1] */ + xlsub[jcol] = istop; + for (ifrom = jm1ptr; ifrom < nextl; ++ifrom, ++ito) + lsub[ito] = lsub[ifrom]; + nextl = ito; /* = istop + length(jcol) */ + } + nsuper++; + supno[jcol] = nsuper; + } /* if a new supernode */ + + } /* else: jcol > 0 */ + + /* Tidy up the pointers before exit */ + xsup[nsuper+1] = jcolp1; + supno[jcolp1] = nsuper; + xprune[jcol] = nextl; /* Initialize upper bound for pruning */ + xlsub[jcolp1] = nextl; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ccopy_to_ucol.c b/src/Libraries/superlu-5.2.1/SRC/ccopy_to_ucol.c new file mode 100644 index 00000000..c910e5cd --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ccopy_to_ucol.c @@ -0,0 +1,113 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ccopy_to_ucol.c + * \brief Copy a computed column of U to the compressed data structure + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + +#include "slu_cdefs.h" + +int +ccopy_to_ucol( + int jcol, /* in */ + int nseg, /* in */ + int *segrep, /* in */ + int *repfnz, /* in */ + int *perm_r, /* in */ + complex *dense, /* modified - reset to zero on return */ + GlobalLU_t *Glu /* modified */ + ) +{ +/* + * Gather from SPA dense[*] to global ucol[*]. + */ + int ksub, krep, ksupno; + int i, k, kfnz, segsze; + int fsupc, isub, irow; + int jsupno, nextu; + int new_next, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + complex *ucol; + int *usub, *xusub; + int nzumax; + complex zero = {0.0, 0.0}; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + ucol = (complex *) Glu->ucol; + usub = Glu->usub; + xusub = Glu->xusub; + nzumax = Glu->nzumax; + + jsupno = supno[jcol]; + nextu = xusub[jcol]; + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { + krep = segrep[k--]; + ksupno = supno[krep]; + + if ( ksupno != jsupno ) { /* Should go into ucol[] */ + kfnz = repfnz[krep]; + if ( kfnz != EMPTY ) { /* Nonzero U-segment */ + + fsupc = xsup[ksupno]; + isub = xlsub[fsupc] + kfnz - fsupc; + segsze = krep - kfnz + 1; + + new_next = nextu + segsze; + while ( new_next > nzumax ) { + if (mem_error = cLUMemXpand(jcol, nextu, UCOL, &nzumax, Glu)) + return (mem_error); + ucol = (complex *) Glu->ucol; + if (mem_error = cLUMemXpand(jcol, nextu, USUB, &nzumax, Glu)) + return (mem_error); + usub = Glu->usub; + lsub = Glu->lsub; + } + + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + usub[nextu] = perm_r[irow]; + ucol[nextu] = dense[irow]; + dense[irow] = zero; + nextu++; + isub++; + } + + } + + } + + } /* for each segment... */ + + xusub[jcol + 1] = nextu; /* Close U[*,jcol] */ + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/cdiagonal.c b/src/Libraries/superlu-5.2.1/SRC/cdiagonal.c new file mode 100644 index 00000000..6909ff5b --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cdiagonal.c @@ -0,0 +1,143 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cdiagonal.c + * \brief Auxiliary routines to work with diagonal elements + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + +#include "slu_cdefs.h" + +int cfill_diag(int n, NCformat *Astore) +/* fill explicit zeros on the diagonal entries, so that the matrix is not + structurally singular. */ +{ + complex *nzval = (complex *)Astore->nzval; + int *rowind = Astore->rowind; + int *colptr = Astore->colptr; + int nnz = colptr[n]; + int fill = 0; + complex *nzval_new; + complex zero = {1.0, 0.0}; + int *rowind_new; + int i, j, diag; + + for (i = 0; i < n; i++) + { + diag = -1; + for (j = colptr[i]; j < colptr[i + 1]; j++) + if (rowind[j] == i) diag = j; + if (diag < 0) fill++; + } + if (fill) + { + nzval_new = complexMalloc(nnz + fill); + rowind_new = intMalloc(nnz + fill); + fill = 0; + for (i = 0; i < n; i++) + { + diag = -1; + for (j = colptr[i] - fill; j < colptr[i + 1]; j++) + { + if ((rowind_new[j + fill] = rowind[j]) == i) diag = j; + nzval_new[j + fill] = nzval[j]; + } + if (diag < 0) + { + rowind_new[colptr[i + 1] + fill] = i; + nzval_new[colptr[i + 1] + fill] = zero; + fill++; + } + colptr[i + 1] += fill; + } + Astore->nzval = nzval_new; + Astore->rowind = rowind_new; + SUPERLU_FREE(nzval); + SUPERLU_FREE(rowind); + } + Astore->nnz += fill; + return fill; +} + +int cdominate(int n, NCformat *Astore) +/* make the matrix diagonally dominant */ +{ + complex *nzval = (complex *)Astore->nzval; + int *rowind = Astore->rowind; + int *colptr = Astore->colptr; + int nnz = colptr[n]; + int fill = 0; + complex *nzval_new; + int *rowind_new; + int i, j, diag; + double s; + + for (i = 0; i < n; i++) + { + diag = -1; + for (j = colptr[i]; j < colptr[i + 1]; j++) + if (rowind[j] == i) diag = j; + if (diag < 0) fill++; + } + if (fill) + { + nzval_new = complexMalloc(nnz + fill); + rowind_new = intMalloc(nnz+ fill); + fill = 0; + for (i = 0; i < n; i++) + { + s = 1e-6; + diag = -1; + for (j = colptr[i] - fill; j < colptr[i + 1]; j++) + { + if ((rowind_new[j + fill] = rowind[j]) == i) diag = j; + nzval_new[j + fill] = nzval[j]; + s += c_abs1(&nzval_new[j + fill]); + } + if (diag >= 0) { + nzval_new[diag+fill].r = s * 3.0; + nzval_new[diag+fill].i = 0.0; + } else { + rowind_new[colptr[i + 1] + fill] = i; + nzval_new[colptr[i + 1] + fill].r = s * 3.0; + nzval_new[colptr[i + 1] + fill].i = 0.0; + fill++; + } + colptr[i + 1] += fill; + } + Astore->nzval = nzval_new; + Astore->rowind = rowind_new; + SUPERLU_FREE(nzval); + SUPERLU_FREE(rowind); + } + else + { + for (i = 0; i < n; i++) + { + s = 1e-6; + diag = -1; + for (j = colptr[i]; j < colptr[i + 1]; j++) + { + if (rowind[j] == i) diag = j; + s += c_abs1(&nzval[j]); + } + nzval[diag].r = s * 3.0; + nzval[diag].i = 0.0; + } + } + Astore->nnz += fill; + return fill; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/cgscon.c b/src/Libraries/superlu-5.2.1/SRC/cgscon.c new file mode 100644 index 00000000..3d813741 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cgscon.c @@ -0,0 +1,165 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cgscon.c + * \brief Estimates reciprocal of the condition number of a general matrix + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * July 25, 2015
+ *
+ * Modified from lapack routines CGECON.
+ * 
+ */ + +/* + * File name: cgscon.c + * History: Modified from lapack routines CGECON. + */ +#include +#include "slu_cdefs.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   CGSCON estimates the reciprocal of the condition number of a general 
+ *   real matrix A, in either the 1-norm or the infinity-norm, using   
+ *   the LU factorization computed by CGETRF.   *
+ *
+ *   An estimate is obtained for norm(inv(A)), and the reciprocal of the   
+ *   condition number is computed as   
+ *      RCOND = 1 / ( norm(A) * norm(inv(A)) ).   
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ * 
+ *   Arguments   
+ *   =========   
+ *
+ *    NORM    (input) char*
+ *            Specifies whether the 1-norm condition number or the   
+ *            infinity-norm condition number is required:   
+ *            = '1' or 'O':  1-norm;   
+ *            = 'I':         Infinity-norm.
+ *	    
+ *    L       (input) SuperMatrix*
+ *            The factor L from the factorization Pr*A*Pc=L*U as computed by
+ *            cgstrf(). Use compressed row subscripts storage for supernodes,
+ *            i.e., L has types: Stype = SLU_SC, Dtype = SLU_C, Mtype = SLU_TRLU.
+ * 
+ *    U       (input) SuperMatrix*
+ *            The factor U from the factorization Pr*A*Pc=L*U as computed by
+ *            cgstrf(). Use column-wise storage scheme, i.e., U has types:
+ *            Stype = SLU_NC, Dtype = SLU_C, Mtype = SLU_TRU.
+ *	    
+ *    ANORM   (input) float
+ *            If NORM = '1' or 'O', the 1-norm of the original matrix A.   
+ *            If NORM = 'I', the infinity-norm of the original matrix A.
+ *	    
+ *    RCOND   (output) float*
+ *           The reciprocal of the condition number of the matrix A,   
+ *           computed as RCOND = 1/(norm(A) * norm(inv(A))).
+ *	    
+ *    INFO    (output) int*
+ *           = 0:  successful exit   
+ *           < 0:  if INFO = -i, the i-th argument had an illegal value   
+ *
+ *    ===================================================================== 
+ * 
+ */ + +void +cgscon(char *norm, SuperMatrix *L, SuperMatrix *U, + float anorm, float *rcond, SuperLUStat_t *stat, int *info) +{ + + + /* Local variables */ + int kase, kase1, onenrm, i; + float ainvnm; + complex *work; + int isave[3]; + extern int crscl_(int *, complex *, complex *, int *); + + extern int clacon2_(int *, complex *, complex *, float *, int *, int []); + + + /* Test the input parameters. */ + *info = 0; + onenrm = *(unsigned char *)norm == '1' || strncmp(norm, "O", 1)==0; + if (! onenrm && ! strncmp(norm, "I", 1)==0) *info = -1; + else if (L->nrow < 0 || L->nrow != L->ncol || + L->Stype != SLU_SC || L->Dtype != SLU_C || L->Mtype != SLU_TRLU) + *info = -2; + else if (U->nrow < 0 || U->nrow != U->ncol || + U->Stype != SLU_NC || U->Dtype != SLU_C || U->Mtype != SLU_TRU) + *info = -3; + if (*info != 0) { + i = -(*info); + input_error("cgscon", &i); + return; + } + + /* Quick return if possible */ + *rcond = 0.; + if ( L->nrow == 0 || U->nrow == 0) { + *rcond = 1.; + return; + } + + work = complexCalloc( 3*L->nrow ); + + + if ( !work ) + ABORT("Malloc fails for work arrays in cgscon."); + + /* Estimate the norm of inv(A). */ + ainvnm = 0.; + if ( onenrm ) kase1 = 1; + else kase1 = 2; + kase = 0; + + do { + clacon2_(&L->nrow, &work[L->nrow], &work[0], &ainvnm, &kase, isave); + + if (kase == 0) break; + + if (kase == kase1) { + /* Multiply by inv(L). */ + sp_ctrsv("L", "No trans", "Unit", L, U, &work[0], stat, info); + + /* Multiply by inv(U). */ + sp_ctrsv("U", "No trans", "Non-unit", L, U, &work[0], stat, info); + + } else { + + /* Multiply by inv(U'). */ + sp_ctrsv("U", "Transpose", "Non-unit", L, U, &work[0], stat, info); + + /* Multiply by inv(L'). */ + sp_ctrsv("L", "Transpose", "Unit", L, U, &work[0], stat, info); + + } + + } while ( kase != 0 ); + + /* Compute the estimate of the reciprocal condition number. */ + if (ainvnm != 0.) *rcond = (1. / ainvnm) / anorm; + + SUPERLU_FREE (work); + return; + +} /* cgscon */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/cgsequ.c b/src/Libraries/superlu-5.2.1/SRC/cgsequ.c new file mode 100644 index 00000000..c87db442 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cgsequ.c @@ -0,0 +1,205 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cgsequ.c + * \brief Computes row and column scalings + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Modified from LAPACK routine CGEEQU
+ * 
+ */ +/* + * File name: cgsequ.c + * History: Modified from LAPACK routine CGEEQU + */ +#include +#include "slu_cdefs.h" + + + +/*! \brief + * + *
+ * Purpose   
+ *   =======   
+ *
+ *   CGSEQU computes row and column scalings intended to equilibrate an   
+ *   M-by-N sparse matrix A and reduce its condition number. R returns the row
+ *   scale factors and C the column scale factors, chosen to try to make   
+ *   the largest element in each row and column of the matrix B with   
+ *   elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1.   
+ *
+ *   R(i) and C(j) are restricted to be between SMLNUM = smallest safe   
+ *   number and BIGNUM = largest safe number.  Use of these scaling   
+ *   factors is not guaranteed to reduce the condition number of A but   
+ *   works well in practice.   
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   A       (input) SuperMatrix*
+ *           The matrix of dimension (A->nrow, A->ncol) whose equilibration
+ *           factors are to be computed. The type of A can be:
+ *           Stype = SLU_NC; Dtype = SLU_C; Mtype = SLU_GE.
+ *	    
+ *   R       (output) float*, size A->nrow
+ *           If INFO = 0 or INFO > M, R contains the row scale factors   
+ *           for A.
+ *	    
+ *   C       (output) float*, size A->ncol
+ *           If INFO = 0,  C contains the column scale factors for A.
+ *	    
+ *   ROWCND  (output) float*
+ *           If INFO = 0 or INFO > M, ROWCND contains the ratio of the   
+ *           smallest R(i) to the largest R(i).  If ROWCND >= 0.1 and   
+ *           AMAX is neither too large nor too small, it is not worth   
+ *           scaling by R.
+ *	    
+ *   COLCND  (output) float*
+ *           If INFO = 0, COLCND contains the ratio of the smallest   
+ *           C(i) to the largest C(i).  If COLCND >= 0.1, it is not   
+ *           worth scaling by C.
+ *	    
+ *   AMAX    (output) float*
+ *           Absolute value of largest matrix element.  If AMAX is very   
+ *           close to overflow or very close to underflow, the matrix   
+ *           should be scaled.
+ *	    
+ *   INFO    (output) int*
+ *           = 0:  successful exit   
+ *           < 0:  if INFO = -i, the i-th argument had an illegal value   
+ *           > 0:  if INFO = i,  and i is   
+ *                 <= A->nrow:  the i-th row of A is exactly zero   
+ *                 >  A->ncol:  the (i-M)-th column of A is exactly zero   
+ *
+ *   ===================================================================== 
+ * 
+ */ +void +cgsequ(SuperMatrix *A, float *r, float *c, float *rowcnd, + float *colcnd, float *amax, int *info) +{ + + + /* Local variables */ + NCformat *Astore; + complex *Aval; + int i, j, irow; + float rcmin, rcmax; + float bignum, smlnum; + extern float smach(char *); + + /* Test the input parameters. */ + *info = 0; + if ( A->nrow < 0 || A->ncol < 0 || + A->Stype != SLU_NC || A->Dtype != SLU_C || A->Mtype != SLU_GE ) + *info = -1; + if (*info != 0) { + i = -(*info); + input_error("cgsequ", &i); + return; + } + + /* Quick return if possible */ + if ( A->nrow == 0 || A->ncol == 0 ) { + *rowcnd = 1.; + *colcnd = 1.; + *amax = 0.; + return; + } + + Astore = A->Store; + Aval = Astore->nzval; + + /* Get machine constants. */ + smlnum = smach("S"); /* slamch_("S"); */ + bignum = 1. / smlnum; + + /* Compute row scale factors. */ + for (i = 0; i < A->nrow; ++i) r[i] = 0.; + + /* Find the maximum element in each row. */ + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + r[irow] = SUPERLU_MAX( r[irow], c_abs1(&Aval[i]) ); + } + + /* Find the maximum and minimum scale factors. */ + rcmin = bignum; + rcmax = 0.; + for (i = 0; i < A->nrow; ++i) { + rcmax = SUPERLU_MAX(rcmax, r[i]); + rcmin = SUPERLU_MIN(rcmin, r[i]); + } + *amax = rcmax; + + if (rcmin == 0.) { + /* Find the first zero scale factor and return an error code. */ + for (i = 0; i < A->nrow; ++i) + if (r[i] == 0.) { + *info = i + 1; + return; + } + } else { + /* Invert the scale factors. */ + for (i = 0; i < A->nrow; ++i) + r[i] = 1. / SUPERLU_MIN( SUPERLU_MAX( r[i], smlnum ), bignum ); + /* Compute ROWCND = min(R(I)) / max(R(I)) */ + *rowcnd = SUPERLU_MAX( rcmin, smlnum ) / SUPERLU_MIN( rcmax, bignum ); + } + + /* Compute column scale factors */ + for (j = 0; j < A->ncol; ++j) c[j] = 0.; + + /* Find the maximum element in each column, assuming the row + scalings computed above. */ + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + c[j] = SUPERLU_MAX( c[j], c_abs1(&Aval[i]) * r[irow] ); + } + + /* Find the maximum and minimum scale factors. */ + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->ncol; ++j) { + rcmax = SUPERLU_MAX(rcmax, c[j]); + rcmin = SUPERLU_MIN(rcmin, c[j]); + } + + if (rcmin == 0.) { + /* Find the first zero scale factor and return an error code. */ + for (j = 0; j < A->ncol; ++j) + if ( c[j] == 0. ) { + *info = A->nrow + j + 1; + return; + } + } else { + /* Invert the scale factors. */ + for (j = 0; j < A->ncol; ++j) + c[j] = 1. / SUPERLU_MIN( SUPERLU_MAX( c[j], smlnum ), bignum); + /* Compute COLCND = min(C(J)) / max(C(J)) */ + *colcnd = SUPERLU_MAX( rcmin, smlnum ) / SUPERLU_MIN( rcmax, bignum ); + } + + return; + +} /* cgsequ */ + + diff --git a/src/Libraries/superlu-5.2.1/SRC/cgsisx.c b/src/Libraries/superlu-5.2.1/SRC/cgsisx.c new file mode 100644 index 00000000..c01d1ce6 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cgsisx.c @@ -0,0 +1,738 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cgsisx.c + * \brief Computes an approximate solutions of linear equations A*X=B or A'*X=B + * + *
+ * -- SuperLU routine (version 4.2) --
+ * Lawrence Berkeley National Laboratory.
+ * November, 2010
+ * August, 2011
+ * 
+ */ +#include "slu_cdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * CGSISX computes an approximate solutions of linear equations
+ * A*X=B or A'*X=B, using the ILU factorization from cgsitrf().
+ * An estimation of the condition number is provided. 
+ * The routine performs the following steps:
+ *
+ *   1. If A is stored column-wise (A->Stype = SLU_NC):
+ *  
+ *	1.1. If options->Equil = YES or options->RowPerm = LargeDiag, scaling
+ *	     factors are computed to equilibrate the system:
+ *	     options->Trans = NOTRANS:
+ *		 diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *	     options->Trans = TRANS:
+ *		 (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *	     options->Trans = CONJ:
+ *		 (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *	     Whether or not the system will be equilibrated depends on the
+ *	     scaling of the matrix A, but if equilibration is used, A is
+ *	     overwritten by diag(R)*A*diag(C) and B by diag(R)*B
+ *	     (if options->Trans=NOTRANS) or diag(C)*B (if options->Trans
+ *	     = TRANS or CONJ).
+ *
+ *	1.2. Permute columns of A, forming A*Pc, where Pc is a permutation
+ *	     matrix that usually preserves sparsity.
+ *	     For more details of this step, see sp_preorder.c.
+ *
+ *	1.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *	     factor the matrix A (after equilibration if options->Equil = YES)
+ *	     as Pr*A*Pc = L*U, with Pr determined by partial pivoting.
+ *
+ *	1.4. Compute the reciprocal pivot growth factor.
+ *
+ *	1.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *	     routine fills a small number on the diagonal entry, that is
+ *		U(i,i) = ||A(:,i)||_oo * options->ILU_FillTol ** (1 - i / n),
+ *	     and info will be increased by 1. The factored form of A is used
+ *	     to estimate the condition number of the preconditioner. If the
+ *	     reciprocal of the condition number is less than machine precision,
+ *	     info = A->ncol+1 is returned as a warning, but the routine still
+ *	     goes on to solve for X.
+ *
+ *	1.6. The system of equations is solved for X using the factored form
+ *	     of A.
+ *
+ *	1.7. options->IterRefine is not used
+ *
+ *	1.8. If equilibration was used, the matrix X is premultiplied by
+ *	     diag(C) (if options->Trans = NOTRANS) or diag(R)
+ *	     (if options->Trans = TRANS or CONJ) so that it solves the
+ *	     original system before equilibration.
+ *
+ *	1.9. options for ILU only
+ *	     1) If options->RowPerm = LargeDiag, MC64 is used to scale and
+ *		permute the matrix to an I-matrix, that is Pr*Dr*A*Dc has
+ *		entries of modulus 1 on the diagonal and off-diagonal entries
+ *		of modulus at most 1. If MC64 fails, dgsequ() is used to
+ *		equilibrate the system.
+ *              ( Default: LargeDiag )
+ *	     2) options->ILU_DropTol = tau is the threshold for dropping.
+ *		For L, it is used directly (for the whole row in a supernode);
+ *		For U, ||A(:,i)||_oo * tau is used as the threshold
+ *	        for the	i-th column.
+ *		If a secondary dropping rule is required, tau will
+ *	        also be used to compute the second threshold.
+ *              ( Default: 1e-4 )
+ *	     3) options->ILU_FillFactor = gamma, used as the initial guess
+ *		of memory growth.
+ *		If a secondary dropping rule is required, it will also
+ *              be used as an upper bound of the memory.
+ *              ( Default: 10 )
+ *	     4) options->ILU_DropRule specifies the dropping rule.
+ *		Option	      Meaning
+ *		======	      ===========
+ *		DROP_BASIC:   Basic dropping rule, supernodal based ILUTP(tau).
+ *		DROP_PROWS:   Supernodal based ILUTP(p,tau), p = gamma*nnz(A)/n.
+ *		DROP_COLUMN:  Variant of ILUTP(p,tau), for j-th column,
+ *			      p = gamma * nnz(A(:,j)).
+ *		DROP_AREA:    Variation of ILUTP, for j-th column, use
+ *			      nnz(F(:,1:j)) / nnz(A(:,1:j)) to control memory.
+ *		DROP_DYNAMIC: Modify the threshold tau during factorizaion:
+ *			      If nnz(L(:,1:j)) / nnz(A(:,1:j)) > gamma
+ *				  tau_L(j) := MIN(tau_0, tau_L(j-1) * 2);
+ *			      Otherwise
+ *				  tau_L(j) := MAX(tau_0, tau_L(j-1) / 2);
+ *			      tau_U(j) uses the similar rule.
+ *			      NOTE: the thresholds used by L and U are separate.
+ *		DROP_INTERP:  Compute the second dropping threshold by
+ *			      interpolation instead of sorting (default).
+ *			      In this case, the actual fill ratio is not
+ *			      guaranteed smaller than gamma.
+ *		DROP_PROWS, DROP_COLUMN and DROP_AREA are mutually exclusive.
+ *		( Default: DROP_BASIC | DROP_AREA )
+ *	     5) options->ILU_Norm is the criterion of measuring the magnitude
+ *		of a row in a supernode of L. ( Default is INF_NORM )
+ *		options->ILU_Norm	RowSize(x[1:n])
+ *		=================	===============
+ *		ONE_NORM		||x||_1 / n
+ *		TWO_NORM		||x||_2 / sqrt(n)
+ *		INF_NORM		max{|x[i]|}
+ *	     6) options->ILU_MILU specifies the type of MILU's variation.
+ *		= SILU: do not perform Modified ILU;
+ *		= SMILU_1 (not recommended):
+ *		    U(i,i) := U(i,i) + sum(dropped entries);
+ *		= SMILU_2:
+ *		    U(i,i) := U(i,i) + SGN(U(i,i)) * sum(dropped entries);
+ *		= SMILU_3:
+ *		    U(i,i) := U(i,i) + SGN(U(i,i)) * sum(|dropped entries|);
+ *		NOTE: Even SMILU_1 does not preserve the column sum because of
+ *		late dropping.
+ *              ( Default: SILU )
+ *	     7) options->ILU_FillTol is used as the perturbation when
+ *		encountering zero pivots. If some U(i,i) = 0, so that U is
+ *		exactly singular, then
+ *		   U(i,i) := ||A(:,i)|| * options->ILU_FillTol ** (1 - i / n).
+ *              ( Default: 1e-2 )
+ *
+ *   2. If A is stored row-wise (A->Stype = SLU_NR), apply the above algorithm
+ *	to the transpose of A:
+ *
+ *	2.1. If options->Equil = YES or options->RowPerm = LargeDiag, scaling
+ *	     factors are computed to equilibrate the system:
+ *	     options->Trans = NOTRANS:
+ *		 diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *	     options->Trans = TRANS:
+ *		 (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *	     options->Trans = CONJ:
+ *		 (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *	     Whether or not the system will be equilibrated depends on the
+ *	     scaling of the matrix A, but if equilibration is used, A' is
+ *	     overwritten by diag(R)*A'*diag(C) and B by diag(R)*B
+ *	     (if trans='N') or diag(C)*B (if trans = 'T' or 'C').
+ *
+ *	2.2. Permute columns of transpose(A) (rows of A),
+ *	     forming transpose(A)*Pc, where Pc is a permutation matrix that
+ *	     usually preserves sparsity.
+ *	     For more details of this step, see sp_preorder.c.
+ *
+ *	2.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *	     factor the transpose(A) (after equilibration if
+ *	     options->Fact = YES) as Pr*transpose(A)*Pc = L*U with the
+ *	     permutation Pr determined by partial pivoting.
+ *
+ *	2.4. Compute the reciprocal pivot growth factor.
+ *
+ *	2.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *	     routine fills a small number on the diagonal entry, that is
+ *		 U(i,i) = ||A(:,i)||_oo * options->ILU_FillTol ** (1 - i / n).
+ *	     And info will be increased by 1. The factored form of A is used
+ *	     to estimate the condition number of the preconditioner. If the
+ *	     reciprocal of the condition number is less than machine precision,
+ *	     info = A->ncol+1 is returned as a warning, but the routine still
+ *	     goes on to solve for X.
+ *
+ *	2.6. The system of equations is solved for X using the factored form
+ *	     of transpose(A).
+ *
+ *	2.7. If options->IterRefine is not used.
+ *
+ *	2.8. If equilibration was used, the matrix X is premultiplied by
+ *	     diag(C) (if options->Trans = NOTRANS) or diag(R)
+ *	     (if options->Trans = TRANS or CONJ) so that it solves the
+ *	     original system before equilibration.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *	   The structure defines the input parameters to control
+ *	   how the LU decomposition will be performed and how the
+ *	   system will be solved.
+ *
+ * A	   (input/output) SuperMatrix*
+ *	   Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
+ *	   of the linear equations is A->nrow. Currently, the type of A can be:
+ *	   Stype = SLU_NC or SLU_NR, Dtype = SLU_C, Mtype = SLU_GE.
+ *	   In the future, more general A may be handled.
+ *
+ *	   On entry, If options->Fact = FACTORED and equed is not 'N',
+ *	   then A must have been equilibrated by the scaling factors in
+ *	   R and/or C.
+ *	   On exit, A is not modified
+ *         if options->Equil = NO, or
+ *         if options->Equil = YES but equed = 'N' on exit, or
+ *         if options->RowPerm = NO.
+ *
+ *	   Otherwise, if options->Equil = YES and equed is not 'N',
+ *	   A is scaled as follows:
+ *	   If A->Stype = SLU_NC:
+ *	     equed = 'R':  A := diag(R) * A
+ *	     equed = 'C':  A := A * diag(C)
+ *	     equed = 'B':  A := diag(R) * A * diag(C).
+ *	   If A->Stype = SLU_NR:
+ *	     equed = 'R':  transpose(A) := diag(R) * transpose(A)
+ *	     equed = 'C':  transpose(A) := transpose(A) * diag(C)
+ *	     equed = 'B':  transpose(A) := diag(R) * transpose(A) * diag(C).
+ *
+ *         If options->RowPerm = LargeDiag, MC64 is used to scale and permute
+ *            the matrix to an I-matrix, that is A is modified as follows:
+ *            P*Dr*A*Dc has entries of modulus 1 on the diagonal and 
+ *            off-diagonal entries of modulus at most 1. P is a permutation
+ *            obtained from MC64.
+ *            If MC64 fails, cgsequ() is used to equilibrate the system,
+ *            and A is scaled as above, but no permutation is involved.
+ *            On exit, A is restored to the orginal row numbering, so
+ *            Dr*A*Dc is returned.
+ *
+ * perm_c  (input/output) int*
+ *	   If A->Stype = SLU_NC, Column permutation vector of size A->ncol,
+ *	   which defines the permutation matrix Pc; perm_c[i] = j means
+ *	   column i of A is in position j in A*Pc.
+ *	   On exit, perm_c may be overwritten by the product of the input
+ *	   perm_c and a permutation that postorders the elimination tree
+ *	   of Pc'*A'*A*Pc; perm_c is not changed if the elimination tree
+ *	   is already in postorder.
+ *
+ *	   If A->Stype = SLU_NR, column permutation vector of size A->nrow,
+ *	   which describes permutation of columns of transpose(A) 
+ *	   (rows of A) as described above.
+ *
+ * perm_r  (input/output) int*
+ *	   If A->Stype = SLU_NC, row permutation vector of size A->nrow, 
+ *	   which defines the permutation matrix Pr, and is determined
+ *	   by MC64 first then followed by partial pivoting.
+ *         perm_r[i] = j means row i of A is in position j in Pr*A.
+ *
+ *	   If A->Stype = SLU_NR, permutation vector of size A->ncol, which
+ *	   determines permutation of rows of transpose(A)
+ *	   (columns of A) as described above.
+ *
+ *	   If options->Fact = SamePattern_SameRowPerm, the pivoting routine
+ *	   will try to use the input perm_r, unless a certain threshold
+ *	   criterion is violated. In that case, perm_r is overwritten by a
+ *	   new permutation determined by partial pivoting or diagonal
+ *	   threshold pivoting.
+ *	   Otherwise, perm_r is output argument.
+ *
+ * etree   (input/output) int*,  dimension (A->ncol)
+ *	   Elimination tree of Pc'*A'*A*Pc.
+ *	   If options->Fact != FACTORED and options->Fact != DOFACT,
+ *	   etree is an input argument, otherwise it is an output argument.
+ *	   Note: etree is a vector of parent pointers for a forest whose
+ *	   vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *
+ * equed   (input/output) char*
+ *	   Specifies the form of equilibration that was done.
+ *	   = 'N': No equilibration.
+ *	   = 'R': Row equilibration, i.e., A was premultiplied by diag(R).
+ *	   = 'C': Column equilibration, i.e., A was postmultiplied by diag(C).
+ *	   = 'B': Both row and column equilibration, i.e., A was replaced 
+ *		  by diag(R)*A*diag(C).
+ *	   If options->Fact = FACTORED, equed is an input argument,
+ *	   otherwise it is an output argument.
+ *
+ * R	   (input/output) float*, dimension (A->nrow)
+ *	   The row scale factors for A or transpose(A).
+ *	   If equed = 'R' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *	       (if A->Stype = SLU_NR) is multiplied on the left by diag(R).
+ *	   If equed = 'N' or 'C', R is not accessed.
+ *	   If options->Fact = FACTORED, R is an input argument,
+ *	       otherwise, R is output.
+ *	   If options->Fact = FACTORED and equed = 'R' or 'B', each element
+ *	       of R must be positive.
+ *
+ * C	   (input/output) float*, dimension (A->ncol)
+ *	   The column scale factors for A or transpose(A).
+ *	   If equed = 'C' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *	       (if A->Stype = SLU_NR) is multiplied on the right by diag(C).
+ *	   If equed = 'N' or 'R', C is not accessed.
+ *	   If options->Fact = FACTORED, C is an input argument,
+ *	       otherwise, C is output.
+ *	   If options->Fact = FACTORED and equed = 'C' or 'B', each element
+ *	       of C must be positive.
+ *
+ * L	   (output) SuperMatrix*
+ *	   The factor L from the factorization
+ *	       Pr*A*Pc=L*U		(if A->Stype SLU_= NC) or
+ *	       Pr*transpose(A)*Pc=L*U	(if A->Stype = SLU_NR).
+ *	   Uses compressed row subscripts storage for supernodes, i.e.,
+ *	   L has types: Stype = SLU_SC, Dtype = SLU_C, Mtype = SLU_TRLU.
+ *
+ * U	   (output) SuperMatrix*
+ *	   The factor U from the factorization
+ *	       Pr*A*Pc=L*U		(if A->Stype = SLU_NC) or
+ *	       Pr*transpose(A)*Pc=L*U	(if A->Stype = SLU_NR).
+ *	   Uses column-wise storage scheme, i.e., U has types:
+ *	   Stype = SLU_NC, Dtype = SLU_C, Mtype = SLU_TRU.
+ *
+ * work    (workspace/output) void*, size (lwork) (in bytes)
+ *	   User supplied workspace, should be large enough
+ *	   to hold data structures for factors L and U.
+ *	   On exit, if fact is not 'F', L and U point to this array.
+ *
+ * lwork   (input) int
+ *	   Specifies the size of work array in bytes.
+ *	   = 0:  allocate space internally by system malloc;
+ *	   > 0:  use user-supplied work array of length lwork in bytes,
+ *		 returns error if space runs out.
+ *	   = -1: the routine guesses the amount of space needed without
+ *		 performing the factorization, and returns it in
+ *		 mem_usage->total_needed; no other side effects.
+ *
+ *	   See argument 'mem_usage' for memory usage statistics.
+ *
+ * B	   (input/output) SuperMatrix*
+ *	   B has types: Stype = SLU_DN, Dtype = SLU_C, Mtype = SLU_GE.
+ *	   On entry, the right hand side matrix.
+ *	   If B->ncol = 0, only LU decomposition is performed, the triangular
+ *			   solve is skipped.
+ *	   On exit,
+ *	      if equed = 'N', B is not modified; otherwise
+ *	      if A->Stype = SLU_NC:
+ *		 if options->Trans = NOTRANS and equed = 'R' or 'B',
+ *		    B is overwritten by diag(R)*B;
+ *		 if options->Trans = TRANS or CONJ and equed = 'C' of 'B',
+ *		    B is overwritten by diag(C)*B;
+ *	      if A->Stype = SLU_NR:
+ *		 if options->Trans = NOTRANS and equed = 'C' or 'B',
+ *		    B is overwritten by diag(C)*B;
+ *		 if options->Trans = TRANS or CONJ and equed = 'R' of 'B',
+ *		    B is overwritten by diag(R)*B.
+ *
+ * X	   (output) SuperMatrix*
+ *	   X has types: Stype = SLU_DN, Dtype = SLU_C, Mtype = SLU_GE.
+ *	   If info = 0 or info = A->ncol+1, X contains the solution matrix
+ *	   to the original system of equations. Note that A and B are modified
+ *	   on exit if equed is not 'N', and the solution to the equilibrated
+ *	   system is inv(diag(C))*X if options->Trans = NOTRANS and
+ *	   equed = 'C' or 'B', or inv(diag(R))*X if options->Trans = 'T' or 'C'
+ *	   and equed = 'R' or 'B'.
+ *
+ * recip_pivot_growth (output) float*
+ *	   The reciprocal pivot growth factor max_j( norm(A_j)/norm(U_j) ).
+ *	   The infinity norm is used. If recip_pivot_growth is much less
+ *	   than 1, the stability of the LU factorization could be poor.
+ *
+ * rcond   (output) float*
+ *	   The estimate of the reciprocal condition number of the matrix A
+ *	   after equilibration (if done). If rcond is less than the machine
+ *	   precision (in particular, if rcond = 0), the matrix is singular
+ *	   to working precision. This condition is indicated by a return
+ *	   code of info > 0.
+ *
+ * mem_usage (output) mem_usage_t*
+ *	   Record the memory usage statistics, consisting of following fields:
+ *	   - for_lu (float)
+ *	     The amount of space used in bytes for L\U data structures.
+ *	   - total_needed (float)
+ *	     The amount of space needed in bytes to perform factorization.
+ *	   - expansions (int)
+ *	     The number of memory expansions during the LU factorization.
+ *
+ * stat   (output) SuperLUStat_t*
+ *	  Record the statistics on runtime and floating-point operation count.
+ *	  See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ *	   = 0: successful exit
+ *	   < 0: if info = -i, the i-th argument had an illegal value
+ *	   > 0: if info = i, and i is
+ *		<= A->ncol: number of zero pivots. They are replaced by small
+ *		      entries due to options->ILU_FillTol.
+ *		= A->ncol+1: U is nonsingular, but RCOND is less than machine
+ *		      precision, meaning that the matrix is singular to
+ *		      working precision. Nevertheless, the solution and
+ *		      error bounds are computed because there are a number
+ *		      of situations where the computed solution can be more
+ *		      accurate than the value of RCOND would suggest.
+ *		> A->ncol+1: number of bytes allocated when memory allocation
+ *		      failure occurred, plus A->ncol.
+ * 
+ */ + +void +cgsisx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, + int *etree, char *equed, float *R, float *C, + SuperMatrix *L, SuperMatrix *U, void *work, int lwork, + SuperMatrix *B, SuperMatrix *X, + float *recip_pivot_growth, float *rcond, + GlobalLU_t *Glu, mem_usage_t *mem_usage, SuperLUStat_t *stat, int *info) +{ + + DNformat *Bstore, *Xstore; + complex *Bmat, *Xmat; + int ldb, ldx, nrhs, n; + SuperMatrix *AA;/* A in SLU_NC format used by the factorization routine.*/ + SuperMatrix AC; /* Matrix postmultiplied by Pc */ + int colequ, equil, nofact, notran, rowequ, permc_spec, mc64; + trans_t trant; + char norm[1]; + int i, j, info1; + float amax, anorm, bignum, smlnum, colcnd, rowcnd, rcmax, rcmin; + int relax, panel_size; + float diag_pivot_thresh; + double t0; /* temporary time */ + double *utime; + + int *perm = NULL; /* permutation returned from MC64 */ + + /* External functions */ + extern float clangs(char *, SuperMatrix *); + + Bstore = B->Store; + Xstore = X->Store; + Bmat = Bstore->nzval; + Xmat = Xstore->nzval; + ldb = Bstore->lda; + ldx = Xstore->lda; + nrhs = B->ncol; + n = B->nrow; + + *info = 0; + nofact = (options->Fact != FACTORED); + equil = (options->Equil == YES); + notran = (options->Trans == NOTRANS); + mc64 = (options->RowPerm == LargeDiag); + if ( nofact ) { + *(unsigned char *)equed = 'N'; + rowequ = FALSE; + colequ = FALSE; + } else { + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + smlnum = smach("Safe minimum"); /* lamch_("Safe minimum"); */ + bignum = 1. / smlnum; + } + + /* Test the input parameters */ + if (options->Fact != DOFACT && options->Fact != SamePattern && + options->Fact != SamePattern_SameRowPerm && + options->Fact != FACTORED && + options->Trans != NOTRANS && options->Trans != TRANS && + options->Trans != CONJ && + options->Equil != NO && options->Equil != YES) + *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + (A->Stype != SLU_NC && A->Stype != SLU_NR) || + A->Dtype != SLU_C || A->Mtype != SLU_GE ) + *info = -2; + else if ( options->Fact == FACTORED && + !(rowequ || colequ || strncmp(equed, "N", 1)==0) ) + *info = -6; + else { + if (rowequ) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, R[j]); + rcmax = SUPERLU_MAX(rcmax, R[j]); + } + if (rcmin <= 0.) *info = -7; + else if ( A->nrow > 0) + rowcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else rowcnd = 1.; + } + if (colequ && *info == 0) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, C[j]); + rcmax = SUPERLU_MAX(rcmax, C[j]); + } + if (rcmin <= 0.) *info = -8; + else if (A->nrow > 0) + colcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else colcnd = 1.; + } + if (*info == 0) { + if ( lwork < -1 ) *info = -12; + else if ( B->ncol < 0 || Bstore->lda < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_C || + B->Mtype != SLU_GE ) + *info = -13; + else if ( X->ncol < 0 || Xstore->lda < SUPERLU_MAX(0, A->nrow) || + (B->ncol != 0 && B->ncol != X->ncol) || + X->Stype != SLU_DN || + X->Dtype != SLU_C || X->Mtype != SLU_GE ) + *info = -14; + } + } + if (*info != 0) { + i = -(*info); + input_error("cgsisx", &i); + return; + } + + /* Initialization for factor parameters */ + panel_size = sp_ienv(1); + relax = sp_ienv(2); + diag_pivot_thresh = options->DiagPivotThresh; + + utime = stat->utime; + + /* Convert A to SLU_NC format when necessary. */ + if ( A->Stype == SLU_NR ) { + NRformat *Astore = A->Store; + AA = (SuperMatrix *) SUPERLU_MALLOC( sizeof(SuperMatrix) ); + cCreate_CompCol_Matrix(AA, A->ncol, A->nrow, Astore->nnz, + Astore->nzval, Astore->colind, Astore->rowptr, + SLU_NC, A->Dtype, A->Mtype); + if ( notran ) { /* Reverse the transpose argument. */ + trant = TRANS; + notran = 0; + } else { + trant = NOTRANS; + notran = 1; + } + } else { /* A->Stype == SLU_NC */ + trant = options->Trans; + AA = A; + } + + if ( nofact ) { + register int i, j; + NCformat *Astore = AA->Store; + int nnz = Astore->nnz; + int *colptr = Astore->colptr; + int *rowind = Astore->rowind; + complex *nzval = (complex *)Astore->nzval; + + if ( mc64 ) { + t0 = SuperLU_timer_(); + if ((perm = intMalloc(n)) == NULL) + ABORT("SUPERLU_MALLOC fails for perm[]"); + + info1 = cldperm(5, n, nnz, colptr, rowind, nzval, perm, R, C); + + if (info1 != 0) { /* MC64 fails, call cgsequ() later */ + mc64 = 0; + SUPERLU_FREE(perm); + perm = NULL; + } else { + if ( equil ) { + rowequ = colequ = 1; + for (i = 0; i < n; i++) { + R[i] = exp(R[i]); + C[i] = exp(C[i]); + } + /* scale the matrix */ + for (j = 0; j < n; j++) { + for (i = colptr[j]; i < colptr[j + 1]; i++) { + cs_mult(&nzval[i], &nzval[i], R[rowind[i]] * C[j]); + } + } + *equed = 'B'; + } + + /* permute the matrix */ + for (j = 0; j < n; j++) { + for (i = colptr[j]; i < colptr[j + 1]; i++) { + /*nzval[i] *= R[rowind[i]] * C[j];*/ + rowind[i] = perm[rowind[i]]; + } + } + } + utime[EQUIL] = SuperLU_timer_() - t0; + } + + if ( !mc64 & equil ) { /* Only perform equilibration, no row perm */ + t0 = SuperLU_timer_(); + /* Compute row and column scalings to equilibrate the matrix A. */ + cgsequ(AA, R, C, &rowcnd, &colcnd, &amax, &info1); + + if ( info1 == 0 ) { + /* Equilibrate matrix A. */ + claqgs(AA, R, C, rowcnd, colcnd, amax, equed); + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + } + utime[EQUIL] = SuperLU_timer_() - t0; + } + } + + + if ( nofact ) { + + t0 = SuperLU_timer_(); + /* + * Gnet column permutation vector perm_c[], according to permc_spec: + * permc_spec = NATURAL: natural ordering + * permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A + * permc_spec = MMD_ATA: minimum degree on structure of A'*A + * permc_spec = COLAMD: approximate minimum degree column ordering + * permc_spec = MY_PERMC: the ordering already supplied in perm_c[] + */ + permc_spec = options->ColPerm; + if ( permc_spec != MY_PERMC && options->Fact == DOFACT ) + get_perm_c(permc_spec, AA, perm_c); + utime[COLPERM] = SuperLU_timer_() - t0; + + t0 = SuperLU_timer_(); + sp_preorder(options, AA, perm_c, etree, &AC); + utime[ETREE] = SuperLU_timer_() - t0; + + /* Compute the LU factorization of A*Pc. */ + t0 = SuperLU_timer_(); + cgsitrf(options, &AC, relax, panel_size, etree, work, lwork, + perm_c, perm_r, L, U, Glu, stat, info); + utime[FACT] = SuperLU_timer_() - t0; + + if ( lwork == -1 ) { + mem_usage->total_needed = *info - A->ncol; + return; + } + + if ( mc64 ) { /* Fold MC64's perm[] into perm_r[]. */ + NCformat *Astore = AA->Store; + int nnz = Astore->nnz, *rowind = Astore->rowind; + int *perm_tmp, *iperm; + if ((perm_tmp = intMalloc(2*n)) == NULL) + ABORT("SUPERLU_MALLOC fails for perm_tmp[]"); + iperm = perm_tmp + n; + for (i = 0; i < n; ++i) perm_tmp[i] = perm_r[perm[i]]; + for (i = 0; i < n; ++i) { + perm_r[i] = perm_tmp[i]; + iperm[perm[i]] = i; + } + + /* Restore A's original row indices. */ + for (i = 0; i < nnz; ++i) rowind[i] = iperm[rowind[i]]; + + SUPERLU_FREE(perm); /* MC64 permutation */ + SUPERLU_FREE(perm_tmp); + } + } + + if ( options->PivotGrowth ) { + if ( *info > 0 ) return; + + /* Compute the reciprocal pivot growth factor *recip_pivot_growth. */ + *recip_pivot_growth = cPivotGrowth(A->ncol, AA, perm_c, L, U); + } + + if ( options->ConditionNumber ) { + /* Estimate the reciprocal of the condition number of A. */ + t0 = SuperLU_timer_(); + if ( notran ) { + *(unsigned char *)norm = '1'; + } else { + *(unsigned char *)norm = 'I'; + } + anorm = clangs(norm, AA); + cgscon(norm, L, U, anorm, rcond, stat, &info1); + utime[RCOND] = SuperLU_timer_() - t0; + } + + if ( nrhs > 0 ) { /* Solve the system */ + complex *rhs_work; + + /* Scale and permute the right-hand side if equilibration + and permutation from MC64 were performed. */ + if ( notran ) { + if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) + cs_mult(&Bmat[i+j*ldb], &Bmat[i+j*ldb], R[i]); + } + } else if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) { + cs_mult(&Bmat[i+j*ldb], &Bmat[i+j*ldb], C[i]); + } + } + + /* Compute the solution matrix X. */ + for (j = 0; j < nrhs; j++) /* Save a copy of the right hand sides */ + for (i = 0; i < B->nrow; i++) + Xmat[i + j*ldx] = Bmat[i + j*ldb]; + + t0 = SuperLU_timer_(); + cgstrs (trant, L, U, perm_c, perm_r, X, stat, &info1); + utime[SOLVE] = SuperLU_timer_() - t0; + + /* Transform the solution matrix X to a solution of the original + system. */ + if ( notran ) { + if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) { + cs_mult(&Xmat[i+j*ldx], &Xmat[i+j*ldx], C[i]); + } + } + } else { /* transposed system */ + if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) { + cs_mult(&Xmat[i+j*ldx], &Xmat[i+j*ldx], R[i]); + } + } + } + + } /* end if nrhs > 0 */ + + if ( options->ConditionNumber ) { + /* The matrix is singular to working precision. */ + /* if ( *rcond < slamch_("E") && *info == 0) *info = A->ncol + 1; */ + if ( *rcond < smach("E") && *info == 0) *info = A->ncol + 1; + } + + if ( nofact ) { + ilu_cQuerySpace(L, U, mem_usage); + Destroy_CompCol_Permuted(&AC); + } + if ( A->Stype == SLU_NR ) { + Destroy_SuperMatrix_Store(AA); + SUPERLU_FREE(AA); + } + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/cgsitrf.c b/src/Libraries/superlu-5.2.1/SRC/cgsitrf.c new file mode 100644 index 00000000..fd21080f --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cgsitrf.c @@ -0,0 +1,661 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cgsitrf.c + * \brief Computes an ILU factorization of a general sparse matrix + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ *
+ * 
+ */ + +#include "slu_cdefs.h" + +#ifdef DEBUG +int num_drop_L; +#endif + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * CGSITRF computes an ILU factorization of a general sparse m-by-n
+ * matrix A using partial pivoting with row interchanges.
+ * The factorization has the form
+ *     Pr * A = L * U
+ * where Pr is a row permutation matrix, L is lower triangular with unit
+ * diagonal elements (lower trapezoidal if A->nrow > A->ncol), and U is upper
+ * triangular (upper trapezoidal if A->nrow < A->ncol).
+ *
+ * See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *	   The structure defines the input parameters to control
+ *	   how the ILU decomposition will be performed.
+ *
+ * A	    (input) SuperMatrix*
+ *	    Original matrix A, permuted by columns, of dimension
+ *	    (A->nrow, A->ncol). The type of A can be:
+ *	    Stype = SLU_NCP; Dtype = SLU_C; Mtype = SLU_GE.
+ *
+ * relax    (input) int
+ *	    To control degree of relaxing supernodes. If the number
+ *	    of nodes (columns) in a subtree of the elimination tree is less
+ *	    than relax, this subtree is considered as one supernode,
+ *	    regardless of the row structures of those columns.
+ *
+ * panel_size (input) int
+ *	    A panel consists of at most panel_size consecutive columns.
+ *
+ * etree    (input) int*, dimension (A->ncol)
+ *	    Elimination tree of A'*A.
+ *	    Note: etree is a vector of parent pointers for a forest whose
+ *	    vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *	    On input, the columns of A should be permuted so that the
+ *	    etree is in a certain postorder.
+ *
+ * work     (input/output) void*, size (lwork) (in bytes)
+ *	    User-supplied work space and space for the output data structures.
+ *	    Not referenced if lwork = 0;
+ *
+ * lwork   (input) int
+ *	   Specifies the size of work array in bytes.
+ *	   = 0:  allocate space internally by system malloc;
+ *	   > 0:  use user-supplied work array of length lwork in bytes,
+ *		 returns error if space runs out.
+ *	   = -1: the routine guesses the amount of space needed without
+ *		 performing the factorization, and returns it in
+ *		 *info; no other side effects.
+ *
+ * perm_c   (input) int*, dimension (A->ncol)
+ *	    Column permutation vector, which defines the
+ *	    permutation matrix Pc; perm_c[i] = j means column i of A is
+ *	    in position j in A*Pc.
+ *	    When searching for diagonal, perm_c[*] is applied to the
+ *	    row subscripts of A, so that diagonal threshold pivoting
+ *	    can find the diagonal of A, rather than that of A*Pc.
+ *
+ * perm_r   (input/output) int*, dimension (A->nrow)
+ *	    Row permutation vector which defines the permutation matrix Pr,
+ *	    perm_r[i] = j means row i of A is in position j in Pr*A.
+ *	    If options->Fact = SamePattern_SameRowPerm, the pivoting routine
+ *	       will try to use the input perm_r, unless a certain threshold
+ *	       criterion is violated. In that case, perm_r is overwritten by
+ *	       a new permutation determined by partial pivoting or diagonal
+ *	       threshold pivoting.
+ *	    Otherwise, perm_r is output argument;
+ *
+ * L	    (output) SuperMatrix*
+ *	    The factor L from the factorization Pr*A=L*U; use compressed row
+ *	    subscripts storage for supernodes, i.e., L has type:
+ *	    Stype = SLU_SC, Dtype = SLU_C, Mtype = SLU_TRLU.
+ *
+ * U	    (output) SuperMatrix*
+ *	    The factor U from the factorization Pr*A*Pc=L*U. Use column-wise
+ *	    storage scheme, i.e., U has types: Stype = SLU_NC,
+ *	    Dtype = SLU_C, Mtype = SLU_TRU.
+ *
+ * Glu      (input/output) GlobalLU_t *
+ *          If options->Fact == SamePattern_SameRowPerm, it is an input;
+ *              The matrix A will be factorized assuming that a 
+ *              factorization of a matrix with the same sparsity pattern
+ *              and similar numerical values was performed prior to this one.
+ *              Therefore, this factorization will reuse both row and column
+ *		scaling factors R and C, both row and column permutation
+ *		vectors perm_r and perm_c, and the L & U data structures
+ *		set up from the previous factorization.
+ *          Otherwise, it is an output.
+ *
+ * stat     (output) SuperLUStat_t*
+ *	    Record the statistics on runtime and floating-point operation count.
+ *	    See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info     (output) int*
+ *	    = 0: successful exit
+ *	    < 0: if info = -i, the i-th argument had an illegal value
+ *	    > 0: if info = i, and i is
+ *	       <= A->ncol: number of zero pivots. They are replaced by small
+ *		  entries according to options->ILU_FillTol.
+ *	       > A->ncol: number of bytes allocated when memory allocation
+ *		  failure occurred, plus A->ncol. If lwork = -1, it is
+ *		  the estimated amount of space needed, plus A->ncol.
+ *
+ * ======================================================================
+ *
+ * Local Working Arrays:
+ * ======================
+ *   m = number of rows in the matrix
+ *   n = number of columns in the matrix
+ *
+ *   marker[0:3*m-1]: marker[i] = j means that node i has been
+ *	reached when working on column j.
+ *	Storage: relative to original row subscripts
+ *	NOTE: There are 4 of them:
+ *	      marker/marker1 are used for panel dfs, see (ilu_)dpanel_dfs.c;
+ *	      marker2 is used for inner-factorization, see (ilu)_dcolumn_dfs.c;
+ *	      marker_relax(has its own space) is used for relaxed supernodes.
+ *
+ *   parent[0:m-1]: parent vector used during dfs
+ *	Storage: relative to new row subscripts
+ *
+ *   xplore[0:m-1]: xplore[i] gives the location of the next (dfs)
+ *	unexplored neighbor of i in lsub[*]
+ *
+ *   segrep[0:nseg-1]: contains the list of supernodal representatives
+ *	in topological order of the dfs. A supernode representative is the
+ *	last column of a supernode.
+ *	The maximum size of segrep[] is n.
+ *
+ *   repfnz[0:W*m-1]: for a nonzero segment U[*,j] that ends at a
+ *	supernodal representative r, repfnz[r] is the location of the first
+ *	nonzero in this segment.  It is also used during the dfs: repfnz[r]>0
+ *	indicates the supernode r has been explored.
+ *	NOTE: There are W of them, each used for one column of a panel.
+ *
+ *   panel_lsub[0:W*m-1]: temporary for the nonzeros row indices below
+ *	the panel diagonal. These are filled in during dpanel_dfs(), and are
+ *	used later in the inner LU factorization within the panel.
+ *	panel_lsub[]/dense[] pair forms the SPA data structure.
+ *	NOTE: There are W of them.
+ *
+ *   dense[0:W*m-1]: sparse accumulating (SPA) vector for intermediate values;
+ *		   NOTE: there are W of them.
+ *
+ *   tempv[0:*]: real temporary used for dense numeric kernels;
+ *	The size of this array is defined by NUM_TEMPV() in slu_util.h.
+ *	It is also used by the dropping routine ilu_ddrop_row().
+ * 
+ */ + +void +cgsitrf(superlu_options_t *options, SuperMatrix *A, int relax, int panel_size, + int *etree, void *work, int lwork, int *perm_c, int *perm_r, + SuperMatrix *L, SuperMatrix *U, + GlobalLU_t *Glu, /* persistent to facilitate multiple factorizations */ + SuperLUStat_t *stat, int *info) +{ + /* Local working arrays */ + NCPformat *Astore; + int *iperm_r = NULL; /* inverse of perm_r; used when + options->Fact == SamePattern_SameRowPerm */ + int *iperm_c; /* inverse of perm_c */ + int *swap, *iswap; /* swap is used to store the row permutation + during the factorization. Initially, it is set + to iperm_c (row indeces of Pc*A*Pc'). + iswap is the inverse of swap. After the + factorization, it is equal to perm_r. */ + int *iwork; + complex *cwork; + int *segrep, *repfnz, *parent, *xplore; + int *panel_lsub; /* dense[]/panel_lsub[] pair forms a w-wide SPA */ + int *marker, *marker_relax; + complex *dense, *tempv; + float *stempv; + int *relax_end, *relax_fsupc; + complex *a; + int *asub; + int *xa_begin, *xa_end; + int *xsup, *supno; + int *xlsub, *xlusup, *xusub; + int nzlumax; + float *amax; + complex drop_sum; + float alpha, omega; /* used in MILU, mimicing DRIC */ + float *swork2; /* used by the second dropping rule */ + + /* Local scalars */ + fact_t fact = options->Fact; + double diag_pivot_thresh = options->DiagPivotThresh; + double drop_tol = options->ILU_DropTol; /* tau */ + double fill_ini = options->ILU_FillTol; /* tau^hat */ + double gamma = options->ILU_FillFactor; + int drop_rule = options->ILU_DropRule; + milu_t milu = options->ILU_MILU; + double fill_tol; + int pivrow; /* pivotal row number in the original matrix A */ + int nseg1; /* no of segments in U-column above panel row jcol */ + int nseg; /* no of segments in each U-column */ + register int jcol; + register int kcol; /* end column of a relaxed snode */ + register int icol; + register int i, k, jj, new_next, iinfo; + int m, n, min_mn, jsupno, fsupc, nextlu, nextu; + int w_def; /* upper bound on panel width */ + int usepr, iperm_r_allocated = 0; + int nnzL, nnzU; + int *panel_histo = stat->panel_histo; + flops_t *ops = stat->ops; + + int last_drop;/* the last column which the dropping rules applied */ + int quota; + int nnzAj; /* number of nonzeros in A(:,1:j) */ + int nnzLj, nnzUj; + double tol_L = drop_tol, tol_U = drop_tol; + complex zero = {0.0, 0.0}; + float one = 1.0; + + /* Executable */ + iinfo = 0; + m = A->nrow; + n = A->ncol; + min_mn = SUPERLU_MIN(m, n); + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + + /* Allocate storage common to the factor routines */ + *info = cLUMemInit(fact, work, lwork, m, n, Astore->nnz, panel_size, + gamma, L, U, Glu, &iwork, &cwork); + if ( *info ) return; + + xsup = Glu->xsup; + supno = Glu->supno; + xlsub = Glu->xlsub; + xlusup = Glu->xlusup; + xusub = Glu->xusub; + + SetIWork(m, n, panel_size, iwork, &segrep, &parent, &xplore, + &repfnz, &panel_lsub, &marker_relax, &marker); + cSetRWork(m, panel_size, cwork, &dense, &tempv); + + usepr = (fact == SamePattern_SameRowPerm); + if ( usepr ) { + /* Compute the inverse of perm_r */ + iperm_r = (int *) intMalloc(m); + for (k = 0; k < m; ++k) iperm_r[perm_r[k]] = k; + iperm_r_allocated = 1; + } + + iperm_c = (int *) intMalloc(n); + for (k = 0; k < n; ++k) iperm_c[perm_c[k]] = k; + swap = (int *)intMalloc(n); + for (k = 0; k < n; k++) swap[k] = iperm_c[k]; + iswap = (int *)intMalloc(n); + for (k = 0; k < n; k++) iswap[k] = perm_c[k]; + amax = (float *) floatMalloc(panel_size); + if (drop_rule & DROP_SECONDARY) + swork2 = (float *)floatMalloc(n); + else + swork2 = NULL; + + nnzAj = 0; + nnzLj = 0; + nnzUj = 0; + last_drop = SUPERLU_MAX(min_mn - 2 * sp_ienv(7), (int)(min_mn * 0.95)); + alpha = pow((double)n, -1.0 / options->ILU_MILU_Dim); + + /* Identify relaxed snodes */ + relax_end = (int *) intMalloc(n); + relax_fsupc = (int *) intMalloc(n); + if ( options->SymmetricMode == YES ) + ilu_heap_relax_snode(n, etree, relax, marker, relax_end, relax_fsupc); + else + ilu_relax_snode(n, etree, relax, marker, relax_end, relax_fsupc); + + ifill (perm_r, m, EMPTY); + ifill (marker, m * NO_MARKER, EMPTY); + supno[0] = -1; + xsup[0] = xlsub[0] = xusub[0] = xlusup[0] = 0; + w_def = panel_size; + + /* Mark the rows used by relaxed supernodes */ + ifill (marker_relax, m, EMPTY); + i = mark_relax(m, relax_end, relax_fsupc, xa_begin, xa_end, + asub, marker_relax); +#if ( PRNTlevel >= 1) + printf("%d relaxed supernodes.\n", i); +#endif + + /* + * Work on one "panel" at a time. A panel is one of the following: + * (a) a relaxed supernode at the bottom of the etree, or + * (b) panel_size contiguous columns, defined by the user + */ + for (jcol = 0; jcol < min_mn; ) { + + if ( relax_end[jcol] != EMPTY ) { /* start of a relaxed snode */ + kcol = relax_end[jcol]; /* end of the relaxed snode */ + panel_histo[kcol-jcol+1]++; + + /* Drop small rows in the previous supernode. */ + if (jcol > 0 && jcol < last_drop) { + int first = xsup[supno[jcol - 1]]; + int last = jcol - 1; + int quota; + + /* Compute the quota */ + if (drop_rule & DROP_PROWS) + quota = gamma * Astore->nnz / m * (m - first) / m + * (last - first + 1); + else if (drop_rule & DROP_COLUMN) { + int i; + quota = 0; + for (i = first; i <= last; i++) + quota += xa_end[i] - xa_begin[i]; + quota = gamma * quota * (m - first) / m; + } else if (drop_rule & DROP_AREA) + quota = gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) / m) + - nnzLj; + else + quota = m * n; + fill_tol = pow(fill_ini, 1.0 - 0.5 * (first + last) / min_mn); + + /* Drop small rows */ + stempv = (float *) tempv; + i = ilu_cdrop_row(options, first, last, tol_L, quota, &nnzLj, + &fill_tol, Glu, stempv, swork2, 0); + /* Reset the parameters */ + if (drop_rule & DROP_DYNAMIC) { + if (gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) / m) + < nnzLj) + tol_L = SUPERLU_MIN(1.0, tol_L * 2.0); + else + tol_L = SUPERLU_MAX(drop_tol, tol_L * 0.5); + } + if (fill_tol < 0) iinfo -= (int)fill_tol; +#ifdef DEBUG + num_drop_L += i * (last - first + 1); +#endif + } + + /* -------------------------------------- + * Factorize the relaxed supernode(jcol:kcol) + * -------------------------------------- */ + /* Determine the union of the row structure of the snode */ + if ( (*info = ilu_csnode_dfs(jcol, kcol, asub, xa_begin, xa_end, + marker, Glu)) != 0 ) + return; + + nextu = xusub[jcol]; + nextlu = xlusup[jcol]; + jsupno = supno[jcol]; + fsupc = xsup[jsupno]; + new_next = nextlu + (xlsub[fsupc+1]-xlsub[fsupc])*(kcol-jcol+1); + nzlumax = Glu->nzlumax; + while ( new_next > nzlumax ) { + if ((*info = cLUMemXpand(jcol, nextlu, LUSUP, &nzlumax, Glu))) + return; + } + + for (icol = jcol; icol <= kcol; icol++) { + xusub[icol+1] = nextu; + + amax[0] = 0.0; + /* Scatter into SPA dense[*] */ + for (k = xa_begin[icol]; k < xa_end[icol]; k++) { + register float tmp = c_abs1 (&a[k]); + if (tmp > amax[0]) amax[0] = tmp; + dense[asub[k]] = a[k]; + } + nnzAj += xa_end[icol] - xa_begin[icol]; + if (amax[0] == 0.0) { + amax[0] = fill_ini; +#if ( PRNTlevel >= 1) + printf("Column %d is entirely zero!\n", icol); + fflush(stdout); +#endif + } + + /* Numeric update within the snode */ + csnode_bmod(icol, jsupno, fsupc, dense, tempv, Glu, stat); + + if (usepr) pivrow = iperm_r[icol]; + fill_tol = pow(fill_ini, 1.0 - (double)icol / (double)min_mn); + if ( (*info = ilu_cpivotL(icol, diag_pivot_thresh, &usepr, + perm_r, iperm_c[icol], swap, iswap, + marker_relax, &pivrow, + amax[0] * fill_tol, milu, zero, + Glu, stat)) ) { + iinfo++; + marker[pivrow] = kcol; + } + + } + + jcol = kcol + 1; + + } else { /* Work on one panel of panel_size columns */ + + /* Adjust panel_size so that a panel won't overlap with the next + * relaxed snode. + */ + panel_size = w_def; + for (k = jcol + 1; k < SUPERLU_MIN(jcol+panel_size, min_mn); k++) + if ( relax_end[k] != EMPTY ) { + panel_size = k - jcol; + break; + } + if ( k == min_mn ) panel_size = min_mn - jcol; + panel_histo[panel_size]++; + + /* symbolic factor on a panel of columns */ + ilu_cpanel_dfs(m, panel_size, jcol, A, perm_r, &nseg1, + dense, amax, panel_lsub, segrep, repfnz, + marker, parent, xplore, Glu); + + /* numeric sup-panel updates in topological order */ + cpanel_bmod(m, panel_size, jcol, nseg1, dense, + tempv, segrep, repfnz, Glu, stat); + + /* Sparse LU within the panel, and below panel diagonal */ + for (jj = jcol; jj < jcol + panel_size; jj++) { + + k = (jj - jcol) * m; /* column index for w-wide arrays */ + + nseg = nseg1; /* Begin after all the panel segments */ + + nnzAj += xa_end[jj] - xa_begin[jj]; + + if ((*info = ilu_ccolumn_dfs(m, jj, perm_r, &nseg, + &panel_lsub[k], segrep, &repfnz[k], + marker, parent, xplore, Glu))) + return; + + /* Numeric updates */ + if ((*info = ccolumn_bmod(jj, (nseg - nseg1), &dense[k], + tempv, &segrep[nseg1], &repfnz[k], + jcol, Glu, stat)) != 0) return; + + /* Make a fill-in position if the column is entirely zero */ + if (xlsub[jj + 1] == xlsub[jj]) { + register int i, row; + int nextl; + int nzlmax = Glu->nzlmax; + int *lsub = Glu->lsub; + int *marker2 = marker + 2 * m; + + /* Allocate memory */ + nextl = xlsub[jj] + 1; + if (nextl >= nzlmax) { + int error = cLUMemXpand(jj, nextl, LSUB, &nzlmax, Glu); + if (error) { *info = error; return; } + lsub = Glu->lsub; + } + xlsub[jj + 1]++; + assert(xlusup[jj]==xlusup[jj+1]); + xlusup[jj + 1]++; + ((complex *) Glu->lusup)[xlusup[jj]] = zero; + + /* Choose a row index (pivrow) for fill-in */ + for (i = jj; i < n; i++) + if (marker_relax[swap[i]] <= jj) break; + row = swap[i]; + marker2[row] = jj; + lsub[xlsub[jj]] = row; +#ifdef DEBUG + printf("Fill col %d.\n", jj); + fflush(stdout); +#endif + } + + /* Computer the quota */ + if (drop_rule & DROP_PROWS) + quota = gamma * Astore->nnz / m * jj / m; + else if (drop_rule & DROP_COLUMN) + quota = gamma * (xa_end[jj] - xa_begin[jj]) * + (jj + 1) / m; + else if (drop_rule & DROP_AREA) + quota = gamma * 0.9 * nnzAj * 0.5 - nnzUj; + else + quota = m; + + /* Copy the U-segments to ucol[*] and drop small entries */ + if ((*info = ilu_ccopy_to_ucol(jj, nseg, segrep, &repfnz[k], + perm_r, &dense[k], drop_rule, + milu, amax[jj - jcol] * tol_U, + quota, &drop_sum, &nnzUj, Glu, + swork2)) != 0) + return; + + /* Reset the dropping threshold if required */ + if (drop_rule & DROP_DYNAMIC) { + if (gamma * 0.9 * nnzAj * 0.5 < nnzLj) + tol_U = SUPERLU_MIN(1.0, tol_U * 2.0); + else + tol_U = SUPERLU_MAX(drop_tol, tol_U * 0.5); + } + + if (drop_sum.r != 0.0 && drop_sum.i != 0.0) + { + omega = SUPERLU_MIN(2.0*(1.0-alpha)/c_abs1(&drop_sum), 1.0); + cs_mult(&drop_sum, &drop_sum, omega); + } + if (usepr) pivrow = iperm_r[jj]; + fill_tol = pow(fill_ini, 1.0 - (double)jj / (double)min_mn); + if ( (*info = ilu_cpivotL(jj, diag_pivot_thresh, &usepr, perm_r, + iperm_c[jj], swap, iswap, + marker_relax, &pivrow, + amax[jj - jcol] * fill_tol, milu, + drop_sum, Glu, stat)) ) { + iinfo++; + marker[m + pivrow] = jj; + marker[2 * m + pivrow] = jj; + } + + /* Reset repfnz[] for this column */ + resetrep_col (nseg, segrep, &repfnz[k]); + + /* Start a new supernode, drop the previous one */ + if (jj > 0 && supno[jj] > supno[jj - 1] && jj < last_drop) { + int first = xsup[supno[jj - 1]]; + int last = jj - 1; + int quota; + + /* Compute the quota */ + if (drop_rule & DROP_PROWS) + quota = gamma * Astore->nnz / m * (m - first) / m + * (last - first + 1); + else if (drop_rule & DROP_COLUMN) { + int i; + quota = 0; + for (i = first; i <= last; i++) + quota += xa_end[i] - xa_begin[i]; + quota = gamma * quota * (m - first) / m; + } else if (drop_rule & DROP_AREA) + quota = gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) + / m) - nnzLj; + else + quota = m * n; + fill_tol = pow(fill_ini, 1.0 - 0.5 * (first + last) / + (double)min_mn); + + /* Drop small rows */ + stempv = (float *) tempv; + i = ilu_cdrop_row(options, first, last, tol_L, quota, + &nnzLj, &fill_tol, Glu, stempv, swork2, + 1); + + /* Reset the parameters */ + if (drop_rule & DROP_DYNAMIC) { + if (gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) / m) + < nnzLj) + tol_L = SUPERLU_MIN(1.0, tol_L * 2.0); + else + tol_L = SUPERLU_MAX(drop_tol, tol_L * 0.5); + } + if (fill_tol < 0) iinfo -= (int)fill_tol; +#ifdef DEBUG + num_drop_L += i * (last - first + 1); +#endif + } /* if start a new supernode */ + + } /* for */ + + jcol += panel_size; /* Move to the next panel */ + + } /* else */ + + } /* for */ + + *info = iinfo; + + if ( m > n ) { + k = 0; + for (i = 0; i < m; ++i) + if ( perm_r[i] == EMPTY ) { + perm_r[i] = n + k; + ++k; + } + } + + ilu_countnz(min_mn, &nnzL, &nnzU, Glu); + fixupL(min_mn, perm_r, Glu); + + cLUWorkFree(iwork, cwork, Glu); /* Free work space and compress storage */ + + if ( fact == SamePattern_SameRowPerm ) { + /* L and U structures may have changed due to possibly different + pivoting, even though the storage is available. + There could also be memory expansions, so the array locations + may have changed, */ + ((SCformat *)L->Store)->nnz = nnzL; + ((SCformat *)L->Store)->nsuper = Glu->supno[n]; + ((SCformat *)L->Store)->nzval = (complex *) Glu->lusup; + ((SCformat *)L->Store)->nzval_colptr = Glu->xlusup; + ((SCformat *)L->Store)->rowind = Glu->lsub; + ((SCformat *)L->Store)->rowind_colptr = Glu->xlsub; + ((NCformat *)U->Store)->nnz = nnzU; + ((NCformat *)U->Store)->nzval = (complex *) Glu->ucol; + ((NCformat *)U->Store)->rowind = Glu->usub; + ((NCformat *)U->Store)->colptr = Glu->xusub; + } else { + cCreate_SuperNode_Matrix(L, A->nrow, min_mn, nnzL, + (complex *) Glu->lusup, Glu->xlusup, + Glu->lsub, Glu->xlsub, Glu->supno, Glu->xsup, + SLU_SC, SLU_C, SLU_TRLU); + cCreate_CompCol_Matrix(U, min_mn, min_mn, nnzU, + (complex *) Glu->ucol, Glu->usub, Glu->xusub, + SLU_NC, SLU_C, SLU_TRU); + } + + ops[FACT] += ops[TRSV] + ops[GEMV]; + stat->expansions = --(Glu->num_expansions); + + if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r); + SUPERLU_FREE (iperm_c); + SUPERLU_FREE (relax_end); + SUPERLU_FREE (swap); + SUPERLU_FREE (iswap); + SUPERLU_FREE (relax_fsupc); + SUPERLU_FREE (amax); + if ( swork2 ) SUPERLU_FREE (swork2); + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/cgsrfs.c b/src/Libraries/superlu-5.2.1/SRC/cgsrfs.c new file mode 100644 index 00000000..a7dd2f8f --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cgsrfs.c @@ -0,0 +1,475 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cgsrfs.c + * \brief Improves computed solution to a system of inear equations + * + *
+ * -- SuperLU routine (version 5.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Modified from lapack routine CGERFS
+ * Last modified: December 3, 2015
+ * 
+ */ +/* + * File name: cgsrfs.c + * History: Modified from lapack routine CGERFS + */ +#include +#include "slu_cdefs.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   CGSRFS improves the computed solution to a system of linear   
+ *   equations and provides error bounds and backward error estimates for 
+ *   the solution.   
+ *
+ *   If equilibration was performed, the system becomes:
+ *           (diag(R)*A_original*diag(C)) * X = diag(R)*B_original.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ *   Arguments   
+ *   =========   
+ *
+ * trans   (input) trans_t
+ *          Specifies the form of the system of equations:
+ *          = NOTRANS: A * X = B  (No transpose)
+ *          = TRANS:   A'* X = B  (Transpose)
+ *          = CONJ:    A**H * X = B  (Conjugate transpose)
+ *   
+ *   A       (input) SuperMatrix*
+ *           The original matrix A in the system, or the scaled A if
+ *           equilibration was done. The type of A can be:
+ *           Stype = SLU_NC, Dtype = SLU_C, Mtype = SLU_GE.
+ *    
+ *   L       (input) SuperMatrix*
+ *	     The factor L from the factorization Pr*A*Pc=L*U. Use
+ *           compressed row subscripts storage for supernodes, 
+ *           i.e., L has types: Stype = SLU_SC, Dtype = SLU_C, Mtype = SLU_TRLU.
+ * 
+ *   U       (input) SuperMatrix*
+ *           The factor U from the factorization Pr*A*Pc=L*U as computed by
+ *           cgstrf(). Use column-wise storage scheme, 
+ *           i.e., U has types: Stype = SLU_NC, Dtype = SLU_C, Mtype = SLU_TRU.
+ *
+ *   perm_c  (input) int*, dimension (A->ncol)
+ *	     Column permutation vector, which defines the 
+ *           permutation matrix Pc; perm_c[i] = j means column i of A is 
+ *           in position j in A*Pc.
+ *
+ *   perm_r  (input) int*, dimension (A->nrow)
+ *           Row permutation vector, which defines the permutation matrix Pr;
+ *           perm_r[i] = j means row i of A is in position j in Pr*A.
+ *
+ *   equed   (input) Specifies the form of equilibration that was done.
+ *           = 'N': No equilibration.
+ *           = 'R': Row equilibration, i.e., A was premultiplied by diag(R).
+ *           = 'C': Column equilibration, i.e., A was postmultiplied by
+ *                  diag(C).
+ *           = 'B': Both row and column equilibration, i.e., A was replaced 
+ *                  by diag(R)*A*diag(C).
+ *
+ *   R       (input) float*, dimension (A->nrow)
+ *           The row scale factors for A.
+ *           If equed = 'R' or 'B', A is premultiplied by diag(R).
+ *           If equed = 'N' or 'C', R is not accessed.
+ * 
+ *   C       (input) float*, dimension (A->ncol)
+ *           The column scale factors for A.
+ *           If equed = 'C' or 'B', A is postmultiplied by diag(C).
+ *           If equed = 'N' or 'R', C is not accessed.
+ *
+ *   B       (input) SuperMatrix*
+ *           B has types: Stype = SLU_DN, Dtype = SLU_C, Mtype = SLU_GE.
+ *           The right hand side matrix B.
+ *           if equed = 'R' or 'B', B is premultiplied by diag(R).
+ *
+ *   X       (input/output) SuperMatrix*
+ *           X has types: Stype = SLU_DN, Dtype = SLU_C, Mtype = SLU_GE.
+ *           On entry, the solution matrix X, as computed by cgstrs().
+ *           On exit, the improved solution matrix X.
+ *           if *equed = 'C' or 'B', X should be premultiplied by diag(C)
+ *               in order to obtain the solution to the original system.
+ *
+ *   FERR    (output) float*, dimension (B->ncol)   
+ *           The estimated forward error bound for each solution vector   
+ *           X(j) (the j-th column of the solution matrix X).   
+ *           If XTRUE is the true solution corresponding to X(j), FERR(j) 
+ *           is an estimated upper bound for the magnitude of the largest 
+ *           element in (X(j) - XTRUE) divided by the magnitude of the   
+ *           largest element in X(j).  The estimate is as reliable as   
+ *           the estimate for RCOND, and is almost always a slight   
+ *           overestimate of the true error.
+ *
+ *   BERR    (output) float*, dimension (B->ncol)   
+ *           The componentwise relative backward error of each solution   
+ *           vector X(j) (i.e., the smallest relative change in   
+ *           any element of A or B that makes X(j) an exact solution).
+ *
+ *   stat     (output) SuperLUStat_t*
+ *            Record the statistics on runtime and floating-point operation count.
+ *            See util.h for the definition of 'SuperLUStat_t'.
+ *
+ *   info    (output) int*   
+ *           = 0:  successful exit   
+ *            < 0:  if INFO = -i, the i-th argument had an illegal value   
+ *
+ *    Internal Parameters   
+ *    ===================   
+ *
+ *    ITMAX is the maximum number of steps of iterative refinement.   
+ *
+ * 
+ */ +void +cgsrfs(trans_t trans, SuperMatrix *A, SuperMatrix *L, SuperMatrix *U, + int *perm_c, int *perm_r, char *equed, float *R, float *C, + SuperMatrix *B, SuperMatrix *X, float *ferr, float *berr, + SuperLUStat_t *stat, int *info) +{ + + +#define ITMAX 5 + + /* Table of constant values */ + int ione = 1; + complex ndone = {-1., 0.}; + complex done = {1., 0.}; + + /* Local variables */ + NCformat *Astore; + complex *Aval; + SuperMatrix Bjcol; + DNformat *Bstore, *Xstore, *Bjcol_store; + complex *Bmat, *Xmat, *Bptr, *Xptr; + int kase; + float safe1, safe2; + int i, j, k, irow, nz, count, notran, rowequ, colequ; + int ldb, ldx, nrhs; + float s, xk, lstres, eps, safmin; + char transc[1]; + trans_t transt; + complex *work; + float *rwork; + int *iwork; + int isave[3]; + + extern int clacon2_(int *, complex *, complex *, float *, int *, int []); +#ifdef _CRAY + extern int CCOPY(int *, complex *, int *, complex *, int *); + extern int CSAXPY(int *, complex *, complex *, int *, complex *, int *); +#else + extern int ccopy_(int *, complex *, int *, complex *, int *); + extern int caxpy_(int *, complex *, complex *, int *, complex *, int *); +#endif + + Astore = A->Store; + Aval = Astore->nzval; + Bstore = B->Store; + Xstore = X->Store; + Bmat = Bstore->nzval; + Xmat = Xstore->nzval; + ldb = Bstore->lda; + ldx = Xstore->lda; + nrhs = B->ncol; + + /* Test the input parameters */ + *info = 0; + notran = (trans == NOTRANS); + if ( !notran && trans != TRANS && trans != CONJ ) *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + A->Stype != SLU_NC || A->Dtype != SLU_C || A->Mtype != SLU_GE ) + *info = -2; + else if ( L->nrow != L->ncol || L->nrow < 0 || + L->Stype != SLU_SC || L->Dtype != SLU_C || L->Mtype != SLU_TRLU ) + *info = -3; + else if ( U->nrow != U->ncol || U->nrow < 0 || + U->Stype != SLU_NC || U->Dtype != SLU_C || U->Mtype != SLU_TRU ) + *info = -4; + else if ( ldb < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_C || B->Mtype != SLU_GE ) + *info = -10; + else if ( ldx < SUPERLU_MAX(0, A->nrow) || + X->Stype != SLU_DN || X->Dtype != SLU_C || X->Mtype != SLU_GE ) + *info = -11; + if (*info != 0) { + i = -(*info); + input_error("cgsrfs", &i); + return; + } + + /* Quick return if possible */ + if ( A->nrow == 0 || nrhs == 0) { + for (j = 0; j < nrhs; ++j) { + ferr[j] = 0.; + berr[j] = 0.; + } + return; + } + + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + + /* Allocate working space */ + work = complexMalloc(2*A->nrow); + rwork = (float *) SUPERLU_MALLOC( A->nrow * sizeof(float) ); + iwork = intMalloc(A->nrow); + if ( !work || !rwork || !iwork ) + ABORT("Malloc fails for work/rwork/iwork."); + + if ( notran ) { + *(unsigned char *)transc = 'N'; + transt = TRANS; + } else if ( trans == TRANS ) { + *(unsigned char *)transc = 'T'; + transt = NOTRANS; + } else if ( trans == CONJ ) { + *(unsigned char *)transc = 'C'; + transt = NOTRANS; + } + + /* NZ = maximum number of nonzero elements in each row of A, plus 1 */ + nz = A->ncol + 1; + eps = smach("Epsilon"); + safmin = smach("Safe minimum"); + + /* Set SAFE1 essentially to be the underflow threshold times the + number of additions in each row. */ + safe1 = nz * safmin; + safe2 = safe1 / eps; + + /* Compute the number of nonzeros in each row (or column) of A */ + for (i = 0; i < A->nrow; ++i) iwork[i] = 0; + if ( notran ) { + for (k = 0; k < A->ncol; ++k) + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) + ++iwork[Astore->rowind[i]]; + } else { + for (k = 0; k < A->ncol; ++k) + iwork[k] = Astore->colptr[k+1] - Astore->colptr[k]; + } + + /* Copy one column of RHS B into Bjcol. */ + Bjcol.Stype = B->Stype; + Bjcol.Dtype = B->Dtype; + Bjcol.Mtype = B->Mtype; + Bjcol.nrow = B->nrow; + Bjcol.ncol = 1; + Bjcol.Store = (void *) SUPERLU_MALLOC( sizeof(DNformat) ); + if ( !Bjcol.Store ) ABORT("SUPERLU_MALLOC fails for Bjcol.Store"); + Bjcol_store = Bjcol.Store; + Bjcol_store->lda = ldb; + Bjcol_store->nzval = work; /* address aliasing */ + + /* Do for each right hand side ... */ + for (j = 0; j < nrhs; ++j) { + count = 0; + lstres = 3.; + Bptr = &Bmat[j*ldb]; + Xptr = &Xmat[j*ldx]; + + while (1) { /* Loop until stopping criterion is satisfied. */ + + /* Compute residual R = B - op(A) * X, + where op(A) = A, A**T, or A**H, depending on TRANS. */ + +#ifdef _CRAY + CCOPY(&A->nrow, Bptr, &ione, work, &ione); +#else + ccopy_(&A->nrow, Bptr, &ione, work, &ione); +#endif + sp_cgemv(transc, ndone, A, Xptr, ione, done, work, ione); + + /* Compute componentwise relative backward error from formula + max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) ) + where abs(Z) is the componentwise absolute value of the matrix + or vector Z. If the i-th component of the denominator is less + than SAFE2, then SAFE1 is added to the i-th component of the + numerator before dividing. */ + + for (i = 0; i < A->nrow; ++i) rwork[i] = c_abs1( &Bptr[i] ); + + /* Compute abs(op(A))*abs(X) + abs(B). */ + if ( notran ) { + for (k = 0; k < A->ncol; ++k) { + xk = c_abs1( &Xptr[k] ); + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) + rwork[Astore->rowind[i]] += c_abs1(&Aval[i]) * xk; + } + } else { /* trans = TRANS or CONJ */ + for (k = 0; k < A->ncol; ++k) { + s = 0.; + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) { + irow = Astore->rowind[i]; + s += c_abs1(&Aval[i]) * c_abs1(&Xptr[irow]); + } + rwork[k] += s; + } + } + s = 0.; + for (i = 0; i < A->nrow; ++i) { + if (rwork[i] > safe2) { + s = SUPERLU_MAX( s, c_abs1(&work[i]) / rwork[i] ); + } else if ( rwork[i] != 0.0 ) { + s = SUPERLU_MAX( s, (c_abs1(&work[i]) + safe1) / rwork[i] ); + } + /* If rwork[i] is exactly 0.0, then we know the true + residual also must be exactly 0.0. */ + } + berr[j] = s; + + /* Test stopping criterion. Continue iterating if + 1) The residual BERR(J) is larger than machine epsilon, and + 2) BERR(J) decreased by at least a factor of 2 during the + last iteration, and + 3) At most ITMAX iterations tried. */ + + if (berr[j] > eps && berr[j] * 2. <= lstres && count < ITMAX) { + /* Update solution and try again. */ + cgstrs (trans, L, U, perm_c, perm_r, &Bjcol, stat, info); + +#ifdef _CRAY + CAXPY(&A->nrow, &done, work, &ione, + &Xmat[j*ldx], &ione); +#else + caxpy_(&A->nrow, &done, work, &ione, + &Xmat[j*ldx], &ione); +#endif + lstres = berr[j]; + ++count; + } else { + break; + } + + } /* end while */ + + stat->RefineSteps = count; + + /* Bound error from formula: + norm(X - XTRUE) / norm(X) .le. FERR = norm( abs(inv(op(A)))* + ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X) + where + norm(Z) is the magnitude of the largest component of Z + inv(op(A)) is the inverse of op(A) + abs(Z) is the componentwise absolute value of the matrix or + vector Z + NZ is the maximum number of nonzeros in any row of A, plus 1 + EPS is machine epsilon + + The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B)) + is incremented by SAFE1 if the i-th component of + abs(op(A))*abs(X) + abs(B) is less than SAFE2. + + Use CLACON2 to estimate the infinity-norm of the matrix + inv(op(A)) * diag(W), + where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) */ + + for (i = 0; i < A->nrow; ++i) rwork[i] = c_abs1( &Bptr[i] ); + + /* Compute abs(op(A))*abs(X) + abs(B). */ + if ( notran ) { + for (k = 0; k < A->ncol; ++k) { + xk = c_abs1( &Xptr[k] ); + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) + rwork[Astore->rowind[i]] += c_abs1(&Aval[i]) * xk; + } + } else { /* trans == TRANS or CONJ */ + for (k = 0; k < A->ncol; ++k) { + s = 0.; + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) { + irow = Astore->rowind[i]; + xk = c_abs1( &Xptr[irow] ); + s += c_abs1(&Aval[i]) * xk; + } + rwork[k] += s; + } + } + + for (i = 0; i < A->nrow; ++i) + if (rwork[i] > safe2) + rwork[i] = c_abs(&work[i]) + (iwork[i]+1)*eps*rwork[i]; + else + rwork[i] = c_abs(&work[i])+(iwork[i]+1)*eps*rwork[i]+safe1; + kase = 0; + + do { + clacon2_(&A->nrow, &work[A->nrow], work, &ferr[j], &kase, isave); + if (kase == 0) break; + + if (kase == 1) { + /* Multiply by diag(W)*inv(op(A)**T)*(diag(C) or diag(R)). */ + if ( notran && colequ ) + for (i = 0; i < A->ncol; ++i) { + cs_mult(&work[i], &work[i], C[i]); + } + else if ( !notran && rowequ ) + for (i = 0; i < A->nrow; ++i) { + cs_mult(&work[i], &work[i], R[i]); + } + + cgstrs (transt, L, U, perm_c, perm_r, &Bjcol, stat, info); + + for (i = 0; i < A->nrow; ++i) { + cs_mult(&work[i], &work[i], rwork[i]); + } + } else { + /* Multiply by (diag(C) or diag(R))*inv(op(A))*diag(W). */ + for (i = 0; i < A->nrow; ++i) { + cs_mult(&work[i], &work[i], rwork[i]); + } + + cgstrs (trans, L, U, perm_c, perm_r, &Bjcol, stat, info); + + if ( notran && colequ ) + for (i = 0; i < A->ncol; ++i) { + cs_mult(&work[i], &work[i], C[i]); + } + else if ( !notran && rowequ ) + for (i = 0; i < A->ncol; ++i) { + cs_mult(&work[i], &work[i], R[i]); + } + } + + } while ( kase != 0 ); + + /* Normalize error. */ + lstres = 0.; + if ( notran && colequ ) { + for (i = 0; i < A->nrow; ++i) + lstres = SUPERLU_MAX( lstres, C[i] * c_abs1( &Xptr[i]) ); + } else if ( !notran && rowequ ) { + for (i = 0; i < A->nrow; ++i) + lstres = SUPERLU_MAX( lstres, R[i] * c_abs1( &Xptr[i]) ); + } else { + for (i = 0; i < A->nrow; ++i) + lstres = SUPERLU_MAX( lstres, c_abs1( &Xptr[i]) ); + } + if ( lstres != 0. ) + ferr[j] /= lstres; + + } /* for each RHS j ... */ + + SUPERLU_FREE(work); + SUPERLU_FREE(rwork); + SUPERLU_FREE(iwork); + SUPERLU_FREE(Bjcol.Store); + + return; + +} /* cgsrfs */ diff --git a/src/Libraries/superlu-5.2.1/SRC/cgssv.c b/src/Libraries/superlu-5.2.1/SRC/cgssv.c new file mode 100644 index 00000000..38e9136f --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cgssv.c @@ -0,0 +1,238 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cgssv.c + * \brief Solves the system of linear equations A*X=B + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ * 
+ */ +#include "slu_cdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * CGSSV solves the system of linear equations A*X=B, using the
+ * LU factorization from CGSTRF. It performs the following steps:
+ *
+ *   1. If A is stored column-wise (A->Stype = SLU_NC):
+ *
+ *      1.1. Permute the columns of A, forming A*Pc, where Pc
+ *           is a permutation matrix. For more details of this step, 
+ *           see sp_preorder.c.
+ *
+ *      1.2. Factor A as Pr*A*Pc=L*U with the permutation Pr determined
+ *           by Gaussian elimination with partial pivoting.
+ *           L is unit lower triangular with offdiagonal entries
+ *           bounded by 1 in magnitude, and U is upper triangular.
+ *
+ *      1.3. Solve the system of equations A*X=B using the factored
+ *           form of A.
+ *
+ *   2. If A is stored row-wise (A->Stype = SLU_NR), apply the
+ *      above algorithm to the transpose of A:
+ *
+ *      2.1. Permute columns of transpose(A) (rows of A),
+ *           forming transpose(A)*Pc, where Pc is a permutation matrix. 
+ *           For more details of this step, see sp_preorder.c.
+ *
+ *      2.2. Factor A as Pr*transpose(A)*Pc=L*U with the permutation Pr
+ *           determined by Gaussian elimination with partial pivoting.
+ *           L is unit lower triangular with offdiagonal entries
+ *           bounded by 1 in magnitude, and U is upper triangular.
+ *
+ *      2.3. Solve the system of equations A*X=B using the factored
+ *           form of A.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ * 
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *         The structure defines the input parameters to control
+ *         how the LU decomposition will be performed and how the
+ *         system will be solved.
+ *
+ * A       (input) SuperMatrix*
+ *         Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
+ *         of linear equations is A->nrow. Currently, the type of A can be:
+ *         Stype = SLU_NC or SLU_NR; Dtype = SLU_C; Mtype = SLU_GE.
+ *         In the future, more general A may be handled.
+ *
+ * perm_c  (input/output) int*
+ *         If A->Stype = SLU_NC, column permutation vector of size A->ncol
+ *         which defines the permutation matrix Pc; perm_c[i] = j means 
+ *         column i of A is in position j in A*Pc.
+ *         If A->Stype = SLU_NR, column permutation vector of size A->nrow
+ *         which describes permutation of columns of transpose(A) 
+ *         (rows of A) as described above.
+ * 
+ *         If options->ColPerm = MY_PERMC or options->Fact = SamePattern or
+ *            options->Fact = SamePattern_SameRowPerm, it is an input argument.
+ *            On exit, perm_c may be overwritten by the product of the input
+ *            perm_c and a permutation that postorders the elimination tree
+ *            of Pc'*A'*A*Pc; perm_c is not changed if the elimination tree
+ *            is already in postorder.
+ *         Otherwise, it is an output argument.
+ * 
+ * perm_r  (input/output) int*
+ *         If A->Stype = SLU_NC, row permutation vector of size A->nrow, 
+ *         which defines the permutation matrix Pr, and is determined 
+ *         by partial pivoting.  perm_r[i] = j means row i of A is in 
+ *         position j in Pr*A.
+ *         If A->Stype = SLU_NR, permutation vector of size A->ncol, which
+ *         determines permutation of rows of transpose(A)
+ *         (columns of A) as described above.
+ *
+ *         If options->RowPerm = MY_PERMR or
+ *            options->Fact = SamePattern_SameRowPerm, perm_r is an
+ *            input argument.
+ *         otherwise it is an output argument.
+ *
+ * L       (output) SuperMatrix*
+ *         The factor L from the factorization 
+ *             Pr*A*Pc=L*U              (if A->Stype = SLU_NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses compressed row subscripts storage for supernodes, i.e.,
+ *         L has types: Stype = SLU_SC, Dtype = SLU_C, Mtype = SLU_TRLU.
+ *         
+ * U       (output) SuperMatrix*
+ *	   The factor U from the factorization 
+ *             Pr*A*Pc=L*U              (if A->Stype = SLU_NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses column-wise storage scheme, i.e., U has types:
+ *         Stype = SLU_NC, Dtype = SLU_C, Mtype = SLU_TRU.
+ *
+ * B       (input/output) SuperMatrix*
+ *         B has types: Stype = SLU_DN, Dtype = SLU_C, Mtype = SLU_GE.
+ *         On entry, the right hand side matrix.
+ *         On exit, the solution matrix if info = 0;
+ *
+ * stat   (output) SuperLUStat_t*
+ *        Record the statistics on runtime and floating-point operation count.
+ *        See util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ *	   = 0: successful exit
+ *         > 0: if info = i, and i is
+ *             <= A->ncol: U(i,i) is exactly zero. The factorization has
+ *                been completed, but the factor U is exactly singular,
+ *                so the solution could not be computed.
+ *             > A->ncol: number of bytes allocated when memory allocation
+ *                failure occurred, plus A->ncol.
+ * 
+ */ + +void +cgssv(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, + SuperMatrix *L, SuperMatrix *U, SuperMatrix *B, + SuperLUStat_t *stat, int *info ) +{ + + DNformat *Bstore; + SuperMatrix *AA;/* A in SLU_NC format used by the factorization routine.*/ + SuperMatrix AC; /* Matrix postmultiplied by Pc */ + int lwork = 0, *etree, i; + GlobalLU_t Glu; /* Not needed on return. */ + + /* Set default values for some parameters */ + int panel_size; /* panel size */ + int relax; /* no of columns in a relaxed snodes */ + int permc_spec; + trans_t trans = NOTRANS; + double *utime; + double t; /* Temporary time */ + + /* Test the input parameters ... */ + *info = 0; + Bstore = B->Store; + if ( options->Fact != DOFACT ) *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + (A->Stype != SLU_NC && A->Stype != SLU_NR) || + A->Dtype != SLU_C || A->Mtype != SLU_GE ) + *info = -2; + else if ( B->ncol < 0 || Bstore->lda < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_C || B->Mtype != SLU_GE ) + *info = -7; + if ( *info != 0 ) { + i = -(*info); + input_error("cgssv", &i); + return; + } + + utime = stat->utime; + + /* Convert A to SLU_NC format when necessary. */ + if ( A->Stype == SLU_NR ) { + NRformat *Astore = A->Store; + AA = (SuperMatrix *) SUPERLU_MALLOC( sizeof(SuperMatrix) ); + cCreate_CompCol_Matrix(AA, A->ncol, A->nrow, Astore->nnz, + Astore->nzval, Astore->colind, Astore->rowptr, + SLU_NC, A->Dtype, A->Mtype); + trans = TRANS; + } else { + if ( A->Stype == SLU_NC ) AA = A; + } + + t = SuperLU_timer_(); + /* + * Get column permutation vector perm_c[], according to permc_spec: + * permc_spec = NATURAL: natural ordering + * permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A + * permc_spec = MMD_ATA: minimum degree on structure of A'*A + * permc_spec = COLAMD: approximate minimum degree column ordering + * permc_spec = MY_PERMC: the ordering already supplied in perm_c[] + */ + permc_spec = options->ColPerm; + if ( permc_spec != MY_PERMC && options->Fact == DOFACT ) + get_perm_c(permc_spec, AA, perm_c); + utime[COLPERM] = SuperLU_timer_() - t; + + etree = intMalloc(A->ncol); + + t = SuperLU_timer_(); + sp_preorder(options, AA, perm_c, etree, &AC); + utime[ETREE] = SuperLU_timer_() - t; + + panel_size = sp_ienv(1); + relax = sp_ienv(2); + + /*printf("Factor PA = LU ... relax %d\tw %d\tmaxsuper %d\trowblk %d\n", + relax, panel_size, sp_ienv(3), sp_ienv(4));*/ + t = SuperLU_timer_(); + /* Compute the LU factorization of A. */ + cgstrf(options, &AC, relax, panel_size, etree, + NULL, lwork, perm_c, perm_r, L, U, &Glu, stat, info); + utime[FACT] = SuperLU_timer_() - t; + + t = SuperLU_timer_(); + if ( *info == 0 ) { + /* Solve the system A*X=B, overwriting B with X. */ + cgstrs (trans, L, U, perm_c, perm_r, B, stat, info); + } + utime[SOLVE] = SuperLU_timer_() - t; + + SUPERLU_FREE (etree); + Destroy_CompCol_Permuted(&AC); + if ( A->Stype == SLU_NR ) { + Destroy_SuperMatrix_Store(AA); + SUPERLU_FREE(AA); + } + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/cgssvx.c b/src/Libraries/superlu-5.2.1/SRC/cgssvx.c new file mode 100644 index 00000000..e214d45f --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cgssvx.c @@ -0,0 +1,646 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cgssvx.c + * \brief Solves the system of linear equations A*X=B or A'*X=B + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ * 
+ */ +#include "slu_cdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * CGSSVX solves the system of linear equations A*X=B or A'*X=B, using
+ * the LU factorization from cgstrf(). Error bounds on the solution and
+ * a condition estimate are also provided. It performs the following steps:
+ *
+ *   1. If A is stored column-wise (A->Stype = SLU_NC):
+ *  
+ *      1.1. If options->Equil = YES, scaling factors are computed to
+ *           equilibrate the system:
+ *           options->Trans = NOTRANS:
+ *               diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *           options->Trans = TRANS:
+ *               (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *           options->Trans = CONJ:
+ *               (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *           Whether or not the system will be equilibrated depends on the
+ *           scaling of the matrix A, but if equilibration is used, A is
+ *           overwritten by diag(R)*A*diag(C) and B by diag(R)*B
+ *           (if options->Trans=NOTRANS) or diag(C)*B (if options->Trans
+ *           = TRANS or CONJ).
+ *
+ *      1.2. Permute columns of A, forming A*Pc, where Pc is a permutation
+ *           matrix that usually preserves sparsity.
+ *           For more details of this step, see sp_preorder.c.
+ *
+ *      1.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *           factor the matrix A (after equilibration if options->Equil = YES)
+ *           as Pr*A*Pc = L*U, with Pr determined by partial pivoting.
+ *
+ *      1.4. Compute the reciprocal pivot growth factor.
+ *
+ *      1.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *           routine returns with info = i. Otherwise, the factored form of 
+ *           A is used to estimate the condition number of the matrix A. If
+ *           the reciprocal of the condition number is less than machine
+ *           precision, info = A->ncol+1 is returned as a warning, but the
+ *           routine still goes on to solve for X and computes error bounds
+ *           as described below.
+ *
+ *      1.6. The system of equations is solved for X using the factored form
+ *           of A.
+ *
+ *      1.7. If options->IterRefine != NOREFINE, iterative refinement is
+ *           applied to improve the computed solution matrix and calculate
+ *           error bounds and backward error estimates for it.
+ *
+ *      1.8. If equilibration was used, the matrix X is premultiplied by
+ *           diag(C) (if options->Trans = NOTRANS) or diag(R)
+ *           (if options->Trans = TRANS or CONJ) so that it solves the
+ *           original system before equilibration.
+ *
+ *   2. If A is stored row-wise (A->Stype = SLU_NR), apply the above algorithm
+ *      to the transpose of A:
+ *
+ *      2.1. If options->Equil = YES, scaling factors are computed to
+ *           equilibrate the system:
+ *           options->Trans = NOTRANS:
+ *               diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *           options->Trans = TRANS:
+ *               (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *           options->Trans = CONJ:
+ *               (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *           Whether or not the system will be equilibrated depends on the
+ *           scaling of the matrix A, but if equilibration is used, A' is
+ *           overwritten by diag(R)*A'*diag(C) and B by diag(R)*B 
+ *           (if trans='N') or diag(C)*B (if trans = 'T' or 'C').
+ *
+ *      2.2. Permute columns of transpose(A) (rows of A), 
+ *           forming transpose(A)*Pc, where Pc is a permutation matrix that 
+ *           usually preserves sparsity.
+ *           For more details of this step, see sp_preorder.c.
+ *
+ *      2.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *           factor the transpose(A) (after equilibration if 
+ *           options->Fact = YES) as Pr*transpose(A)*Pc = L*U with the
+ *           permutation Pr determined by partial pivoting.
+ *
+ *      2.4. Compute the reciprocal pivot growth factor.
+ *
+ *      2.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *           routine returns with info = i. Otherwise, the factored form 
+ *           of transpose(A) is used to estimate the condition number of the
+ *           matrix A. If the reciprocal of the condition number
+ *           is less than machine precision, info = A->nrow+1 is returned as
+ *           a warning, but the routine still goes on to solve for X and
+ *           computes error bounds as described below.
+ *
+ *      2.6. The system of equations is solved for X using the factored form
+ *           of transpose(A).
+ *
+ *      2.7. If options->IterRefine != NOREFINE, iterative refinement is
+ *           applied to improve the computed solution matrix and calculate
+ *           error bounds and backward error estimates for it.
+ *
+ *      2.8. If equilibration was used, the matrix X is premultiplied by
+ *           diag(C) (if options->Trans = NOTRANS) or diag(R) 
+ *           (if options->Trans = TRANS or CONJ) so that it solves the
+ *           original system before equilibration.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *         The structure defines the input parameters to control
+ *         how the LU decomposition will be performed and how the
+ *         system will be solved.
+ *
+ * A       (input/output) SuperMatrix*
+ *         Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
+ *         of the linear equations is A->nrow. Currently, the type of A can be:
+ *         Stype = SLU_NC or SLU_NR, Dtype = SLU_D, Mtype = SLU_GE.
+ *         In the future, more general A may be handled.
+ *
+ *         On entry, If options->Fact = FACTORED and equed is not 'N', 
+ *         then A must have been equilibrated by the scaling factors in
+ *         R and/or C.  
+ *         On exit, A is not modified if options->Equil = NO, or if 
+ *         options->Equil = YES but equed = 'N' on exit.
+ *         Otherwise, if options->Equil = YES and equed is not 'N',
+ *         A is scaled as follows:
+ *         If A->Stype = SLU_NC:
+ *           equed = 'R':  A := diag(R) * A
+ *           equed = 'C':  A := A * diag(C)
+ *           equed = 'B':  A := diag(R) * A * diag(C).
+ *         If A->Stype = SLU_NR:
+ *           equed = 'R':  transpose(A) := diag(R) * transpose(A)
+ *           equed = 'C':  transpose(A) := transpose(A) * diag(C)
+ *           equed = 'B':  transpose(A) := diag(R) * transpose(A) * diag(C).
+ *
+ * perm_c  (input/output) int*
+ *	   If A->Stype = SLU_NC, Column permutation vector of size A->ncol,
+ *         which defines the permutation matrix Pc; perm_c[i] = j means
+ *         column i of A is in position j in A*Pc.
+ *         On exit, perm_c may be overwritten by the product of the input
+ *         perm_c and a permutation that postorders the elimination tree
+ *         of Pc'*A'*A*Pc; perm_c is not changed if the elimination tree
+ *         is already in postorder.
+ *
+ *         If A->Stype = SLU_NR, column permutation vector of size A->nrow,
+ *         which describes permutation of columns of transpose(A) 
+ *         (rows of A) as described above.
+ * 
+ * perm_r  (input/output) int*
+ *         If A->Stype = SLU_NC, row permutation vector of size A->nrow, 
+ *         which defines the permutation matrix Pr, and is determined
+ *         by partial pivoting.  perm_r[i] = j means row i of A is in 
+ *         position j in Pr*A.
+ *
+ *         If A->Stype = SLU_NR, permutation vector of size A->ncol, which
+ *         determines permutation of rows of transpose(A)
+ *         (columns of A) as described above.
+ *
+ *         If options->Fact = SamePattern_SameRowPerm, the pivoting routine
+ *         will try to use the input perm_r, unless a certain threshold
+ *         criterion is violated. In that case, perm_r is overwritten by a
+ *         new permutation determined by partial pivoting or diagonal
+ *         threshold pivoting.
+ *         Otherwise, perm_r is output argument.
+ * 
+ * etree   (input/output) int*,  dimension (A->ncol)
+ *         Elimination tree of Pc'*A'*A*Pc.
+ *         If options->Fact != FACTORED and options->Fact != DOFACT,
+ *         etree is an input argument, otherwise it is an output argument.
+ *         Note: etree is a vector of parent pointers for a forest whose
+ *         vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *
+ * equed   (input/output) char*
+ *         Specifies the form of equilibration that was done.
+ *         = 'N': No equilibration.
+ *         = 'R': Row equilibration, i.e., A was premultiplied by diag(R).
+ *         = 'C': Column equilibration, i.e., A was postmultiplied by diag(C).
+ *         = 'B': Both row and column equilibration, i.e., A was replaced 
+ *                by diag(R)*A*diag(C).
+ *         If options->Fact = FACTORED, equed is an input argument,
+ *         otherwise it is an output argument.
+ *
+ * R       (input/output) float*, dimension (A->nrow)
+ *         The row scale factors for A or transpose(A).
+ *         If equed = 'R' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *             (if A->Stype = SLU_NR) is multiplied on the left by diag(R).
+ *         If equed = 'N' or 'C', R is not accessed.
+ *         If options->Fact = FACTORED, R is an input argument,
+ *             otherwise, R is output.
+ *         If options->zFact = FACTORED and equed = 'R' or 'B', each element
+ *             of R must be positive.
+ * 
+ * C       (input/output) float*, dimension (A->ncol)
+ *         The column scale factors for A or transpose(A).
+ *         If equed = 'C' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *             (if A->Stype = SLU_NR) is multiplied on the right by diag(C).
+ *         If equed = 'N' or 'R', C is not accessed.
+ *         If options->Fact = FACTORED, C is an input argument,
+ *             otherwise, C is output.
+ *         If options->Fact = FACTORED and equed = 'C' or 'B', each element
+ *             of C must be positive.
+ *         
+ * L       (output) SuperMatrix*
+ *	   The factor L from the factorization
+ *             Pr*A*Pc=L*U              (if A->Stype SLU_= NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses compressed row subscripts storage for supernodes, i.e.,
+ *         L has types: Stype = SLU_SC, Dtype = SLU_C, Mtype = SLU_TRLU.
+ *
+ * U       (output) SuperMatrix*
+ *	   The factor U from the factorization
+ *             Pr*A*Pc=L*U              (if A->Stype = SLU_NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses column-wise storage scheme, i.e., U has types:
+ *         Stype = SLU_NC, Dtype = SLU_C, Mtype = SLU_TRU.
+ *
+ * work    (workspace/output) void*, size (lwork) (in bytes)
+ *         User supplied workspace, should be large enough
+ *         to hold data structures for factors L and U.
+ *         On exit, if fact is not 'F', L and U point to this array.
+ *
+ * lwork   (input) int
+ *         Specifies the size of work array in bytes.
+ *         = 0:  allocate space internally by system malloc;
+ *         > 0:  use user-supplied work array of length lwork in bytes,
+ *               returns error if space runs out.
+ *         = -1: the routine guesses the amount of space needed without
+ *               performing the factorization, and returns it in
+ *               mem_usage->total_needed; no other side effects.
+ *
+ *         See argument 'mem_usage' for memory usage statistics.
+ *
+ * B       (input/output) SuperMatrix*
+ *         B has types: Stype = SLU_DN, Dtype = SLU_C, Mtype = SLU_GE.
+ *         On entry, the right hand side matrix.
+ *         If B->ncol = 0, only LU decomposition is performed, the triangular
+ *                         solve is skipped.
+ *         On exit,
+ *            if equed = 'N', B is not modified; otherwise
+ *            if A->Stype = SLU_NC:
+ *               if options->Trans = NOTRANS and equed = 'R' or 'B',
+ *                  B is overwritten by diag(R)*B;
+ *               if options->Trans = TRANS or CONJ and equed = 'C' of 'B',
+ *                  B is overwritten by diag(C)*B;
+ *            if A->Stype = SLU_NR:
+ *               if options->Trans = NOTRANS and equed = 'C' or 'B',
+ *                  B is overwritten by diag(C)*B;
+ *               if options->Trans = TRANS or CONJ and equed = 'R' of 'B',
+ *                  B is overwritten by diag(R)*B.
+ *
+ * X       (output) SuperMatrix*
+ *         X has types: Stype = SLU_DN, Dtype = SLU_C, Mtype = SLU_GE. 
+ *         If info = 0 or info = A->ncol+1, X contains the solution matrix
+ *         to the original system of equations. Note that A and B are modified
+ *         on exit if equed is not 'N', and the solution to the equilibrated
+ *         system is inv(diag(C))*X if options->Trans = NOTRANS and
+ *         equed = 'C' or 'B', or inv(diag(R))*X if options->Trans = 'T' or 'C'
+ *         and equed = 'R' or 'B'.
+ *
+ * recip_pivot_growth (output) float*
+ *         The reciprocal pivot growth factor max_j( norm(A_j)/norm(U_j) ).
+ *         The infinity norm is used. If recip_pivot_growth is much less
+ *         than 1, the stability of the LU factorization could be poor.
+ *
+ * rcond   (output) float*
+ *         The estimate of the reciprocal condition number of the matrix A
+ *         after equilibration (if done). If rcond is less than the machine
+ *         precision (in particular, if rcond = 0), the matrix is singular
+ *         to working precision. This condition is indicated by a return
+ *         code of info > 0.
+ *
+ * FERR    (output) float*, dimension (B->ncol)   
+ *         The estimated forward error bound for each solution vector   
+ *         X(j) (the j-th column of the solution matrix X).   
+ *         If XTRUE is the true solution corresponding to X(j), FERR(j) 
+ *         is an estimated upper bound for the magnitude of the largest 
+ *         element in (X(j) - XTRUE) divided by the magnitude of the   
+ *         largest element in X(j).  The estimate is as reliable as   
+ *         the estimate for RCOND, and is almost always a slight   
+ *         overestimate of the true error.
+ *         If options->IterRefine = NOREFINE, ferr = 1.0.
+ *
+ * BERR    (output) float*, dimension (B->ncol)
+ *         The componentwise relative backward error of each solution   
+ *         vector X(j) (i.e., the smallest relative change in   
+ *         any element of A or B that makes X(j) an exact solution).
+ *         If options->IterRefine = NOREFINE, berr = 1.0.
+ *
+ * Glu      (input/output) GlobalLU_t *
+ *          If options->Fact == SamePattern_SameRowPerm, it is an input;
+ *              The matrix A will be factorized assuming that a 
+ *              factorization of a matrix with the same sparsity pattern
+ *              and similar numerical values was performed prior to this one.
+ *              Therefore, this factorization will reuse both row and column
+ *		scaling factors R and C, both row and column permutation
+ *		vectors perm_r and perm_c, and the L & U data structures
+ *		set up from the previous factorization.
+ *          Otherwise, it is an output.
+ *
+ * mem_usage (output) mem_usage_t*
+ *         Record the memory usage statistics, consisting of following fields:
+ *         - for_lu (float)
+ *           The amount of space used in bytes for L\U data structures.
+ *         - total_needed (float)
+ *           The amount of space needed in bytes to perform factorization.
+ *         - expansions (int)
+ *           The number of memory expansions during the LU factorization.
+ *
+ * stat   (output) SuperLUStat_t*
+ *        Record the statistics on runtime and floating-point operation count.
+ *        See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ *         = 0: successful exit   
+ *         < 0: if info = -i, the i-th argument had an illegal value   
+ *         > 0: if info = i, and i is   
+ *              <= A->ncol: U(i,i) is exactly zero. The factorization has   
+ *                    been completed, but the factor U is exactly   
+ *                    singular, so the solution and error bounds   
+ *                    could not be computed.   
+ *              = A->ncol+1: U is nonsingular, but RCOND is less than machine
+ *                    precision, meaning that the matrix is singular to
+ *                    working precision. Nevertheless, the solution and
+ *                    error bounds are computed because there are a number
+ *                    of situations where the computed solution can be more
+ *                    accurate than the value of RCOND would suggest.   
+ *              > A->ncol+1: number of bytes allocated when memory allocation
+ *                    failure occurred, plus A->ncol.
+ * 
+ */ + +void +cgssvx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, + int *etree, char *equed, float *R, float *C, + SuperMatrix *L, SuperMatrix *U, void *work, int lwork, + SuperMatrix *B, SuperMatrix *X, float *recip_pivot_growth, + float *rcond, float *ferr, float *berr, + GlobalLU_t *Glu, mem_usage_t *mem_usage, SuperLUStat_t *stat, int *info ) +{ + + + DNformat *Bstore, *Xstore; + complex *Bmat, *Xmat; + int ldb, ldx, nrhs; + SuperMatrix *AA;/* A in SLU_NC format used by the factorization routine.*/ + SuperMatrix AC; /* Matrix postmultiplied by Pc */ + int colequ, equil, nofact, notran, rowequ, permc_spec; + trans_t trant; + char norm[1]; + int i, j, info1; + float amax, anorm, bignum, smlnum, colcnd, rowcnd, rcmax, rcmin; + int relax, panel_size; + float diag_pivot_thresh; + double t0; /* temporary time */ + double *utime; + + /* External functions */ + extern float clangs(char *, SuperMatrix *); + + Bstore = B->Store; + Xstore = X->Store; + Bmat = Bstore->nzval; + Xmat = Xstore->nzval; + ldb = Bstore->lda; + ldx = Xstore->lda; + nrhs = B->ncol; + + *info = 0; + nofact = (options->Fact != FACTORED); + equil = (options->Equil == YES); + notran = (options->Trans == NOTRANS); + if ( nofact ) { + *(unsigned char *)equed = 'N'; + rowequ = FALSE; + colequ = FALSE; + } else { + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + smlnum = smach("Safe minimum"); /* lamch_("Safe minimum"); */ + bignum = 1. / smlnum; + } + +#if 0 +printf("dgssvx: Fact=%4d, Trans=%4d, equed=%c\n", + options->Fact, options->Trans, *equed); +#endif + + /* Test the input parameters */ + if (options->Fact != DOFACT && options->Fact != SamePattern && + options->Fact != SamePattern_SameRowPerm && + options->Fact != FACTORED && + options->Trans != NOTRANS && options->Trans != TRANS && + options->Trans != CONJ && + options->Equil != NO && options->Equil != YES) + *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + (A->Stype != SLU_NC && A->Stype != SLU_NR) || + A->Dtype != SLU_C || A->Mtype != SLU_GE ) + *info = -2; + else if ( options->Fact == FACTORED && + !(rowequ || colequ || strncmp(equed, "N", 1)==0) ) + *info = -6; + else { + if (rowequ) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, R[j]); + rcmax = SUPERLU_MAX(rcmax, R[j]); + } + if (rcmin <= 0.) *info = -7; + else if ( A->nrow > 0) + rowcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else rowcnd = 1.; + } + if (colequ && *info == 0) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, C[j]); + rcmax = SUPERLU_MAX(rcmax, C[j]); + } + if (rcmin <= 0.) *info = -8; + else if (A->nrow > 0) + colcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else colcnd = 1.; + } + if (*info == 0) { + if ( lwork < -1 ) *info = -12; + else if ( B->ncol < 0 ) *info = -13; + else if ( B->ncol > 0 ) { /* no checking if B->ncol=0 */ + if ( Bstore->lda < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_C || + B->Mtype != SLU_GE ) + *info = -13; + } + if ( X->ncol < 0 ) *info = -14; + else if ( X->ncol > 0 ) { /* no checking if X->ncol=0 */ + if ( Xstore->lda < SUPERLU_MAX(0, A->nrow) || + (B->ncol != 0 && B->ncol != X->ncol) || + X->Stype != SLU_DN || + X->Dtype != SLU_C || X->Mtype != SLU_GE ) + *info = -14; + } + } + } + if (*info != 0) { + i = -(*info); + input_error("cgssvx", &i); + return; + } + + /* Initialization for factor parameters */ + panel_size = sp_ienv(1); + relax = sp_ienv(2); + diag_pivot_thresh = options->DiagPivotThresh; + + utime = stat->utime; + + /* Convert A to SLU_NC format when necessary. */ + if ( A->Stype == SLU_NR ) { + NRformat *Astore = A->Store; + AA = (SuperMatrix *) SUPERLU_MALLOC( sizeof(SuperMatrix) ); + cCreate_CompCol_Matrix(AA, A->ncol, A->nrow, Astore->nnz, + Astore->nzval, Astore->colind, Astore->rowptr, + SLU_NC, A->Dtype, A->Mtype); + if ( notran ) { /* Reverse the transpose argument. */ + trant = TRANS; + notran = 0; + } else { + trant = NOTRANS; + notran = 1; + } + } else { /* A->Stype == SLU_NC */ + trant = options->Trans; + AA = A; + } + + if ( nofact && equil ) { + t0 = SuperLU_timer_(); + /* Compute row and column scalings to equilibrate the matrix A. */ + cgsequ(AA, R, C, &rowcnd, &colcnd, &amax, &info1); + + if ( info1 == 0 ) { + /* Equilibrate matrix A. */ + claqgs(AA, R, C, rowcnd, colcnd, amax, equed); + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + } + utime[EQUIL] = SuperLU_timer_() - t0; + } + + + if ( nofact ) { + + t0 = SuperLU_timer_(); + /* + * Gnet column permutation vector perm_c[], according to permc_spec: + * permc_spec = NATURAL: natural ordering + * permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A + * permc_spec = MMD_ATA: minimum degree on structure of A'*A + * permc_spec = COLAMD: approximate minimum degree column ordering + * permc_spec = MY_PERMC: the ordering already supplied in perm_c[] + */ + permc_spec = options->ColPerm; + if ( permc_spec != MY_PERMC && options->Fact == DOFACT ) + get_perm_c(permc_spec, AA, perm_c); + utime[COLPERM] = SuperLU_timer_() - t0; + + t0 = SuperLU_timer_(); + sp_preorder(options, AA, perm_c, etree, &AC); + utime[ETREE] = SuperLU_timer_() - t0; + +/* printf("Factor PA = LU ... relax %d\tw %d\tmaxsuper %d\trowblk %d\n", + relax, panel_size, sp_ienv(3), sp_ienv(4)); + fflush(stdout); */ + + /* Compute the LU factorization of A*Pc. */ + t0 = SuperLU_timer_(); + cgstrf(options, &AC, relax, panel_size, etree, + work, lwork, perm_c, perm_r, L, U, Glu, stat, info); + utime[FACT] = SuperLU_timer_() - t0; + + if ( lwork == -1 ) { + mem_usage->total_needed = *info - A->ncol; + return; + } + } + + if ( *info > 0 ) { + if ( *info <= A->ncol ) { + /* Compute the reciprocal pivot growth factor of the leading + rank-deficient (*info) columns of A. */ + *recip_pivot_growth = cPivotGrowth(*info, AA, perm_c, L, U); + } + return; + } + + /* *info == 0 at this point. */ + + if ( options->PivotGrowth ) { + /* Compute the reciprocal pivot growth factor *recip_pivot_growth. */ + *recip_pivot_growth = cPivotGrowth(A->ncol, AA, perm_c, L, U); + } + + if ( options->ConditionNumber ) { + /* Estimate the reciprocal of the condition number of A. */ + t0 = SuperLU_timer_(); + if ( notran ) { + *(unsigned char *)norm = '1'; + } else { + *(unsigned char *)norm = 'I'; + } + anorm = clangs(norm, AA); + cgscon(norm, L, U, anorm, rcond, stat, &info1); + utime[RCOND] = SuperLU_timer_() - t0; + } + + if ( nrhs > 0 ) { + /* Scale the right hand side if equilibration was performed. */ + if ( notran ) { + if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + cs_mult(&Bmat[i+j*ldb], &Bmat[i+j*ldb], R[i]); + } + } else if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + cs_mult(&Bmat[i+j*ldb], &Bmat[i+j*ldb], C[i]); + } + + /* Compute the solution matrix X. */ + for (j = 0; j < nrhs; j++) /* Save a copy of the right hand sides */ + for (i = 0; i < B->nrow; i++) + Xmat[i + j*ldx] = Bmat[i + j*ldb]; + + t0 = SuperLU_timer_(); + cgstrs (trant, L, U, perm_c, perm_r, X, stat, &info1); + utime[SOLVE] = SuperLU_timer_() - t0; + + /* Use iterative refinement to improve the computed solution and compute + error bounds and backward error estimates for it. */ + t0 = SuperLU_timer_(); + if ( options->IterRefine != NOREFINE ) { + cgsrfs(trant, AA, L, U, perm_c, perm_r, equed, R, C, B, + X, ferr, berr, stat, &info1); + } else { + for (j = 0; j < nrhs; ++j) ferr[j] = berr[j] = 1.0; + } + utime[REFINE] = SuperLU_timer_() - t0; + + /* Transform the solution matrix X to a solution of the original system. */ + if ( notran ) { + if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + cs_mult(&Xmat[i+j*ldx], &Xmat[i+j*ldx], C[i]); + } + } else if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + cs_mult(&Xmat[i+j*ldx], &Xmat[i+j*ldx], R[i]); + } + } /* end if nrhs > 0 */ + + if ( options->ConditionNumber ) { + /* Set INFO = A->ncol+1 if the matrix is singular to working precision. */ + /*if ( *rcond < slamch_("E") ) *info = A->ncol + 1;*/ + if ( *rcond < smach("E") ) *info = A->ncol + 1; + } + + if ( nofact ) { + cQuerySpace(L, U, mem_usage); + Destroy_CompCol_Permuted(&AC); + } + if ( A->Stype == SLU_NR ) { + Destroy_SuperMatrix_Store(AA); + SUPERLU_FREE(AA); + } + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/cgstrf.c b/src/Libraries/superlu-5.2.1/SRC/cgstrf.c new file mode 100644 index 00000000..2cd14a9a --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cgstrf.c @@ -0,0 +1,459 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cgstrf.c + * \brief Computes an LU factorization of a general sparse matrix + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ * 
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_cdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * CGSTRF computes an LU factorization of a general sparse m-by-n
+ * matrix A using partial pivoting with row interchanges.
+ * The factorization has the form
+ *     Pr * A = L * U
+ * where Pr is a row permutation matrix, L is lower triangular with unit
+ * diagonal elements (lower trapezoidal if A->nrow > A->ncol), and U is upper 
+ * triangular (upper trapezoidal if A->nrow < A->ncol).
+ *
+ * See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *         The structure defines the input parameters to control
+ *         how the LU decomposition will be performed.
+ *
+ * A        (input) SuperMatrix*
+ *	    Original matrix A, permuted by columns, of dimension
+ *          (A->nrow, A->ncol). The type of A can be:
+ *          Stype = SLU_NCP; Dtype = SLU_C; Mtype = SLU_GE.
+ *
+ * relax    (input) int
+ *          To control degree of relaxing supernodes. If the number
+ *          of nodes (columns) in a subtree of the elimination tree is less
+ *          than relax, this subtree is considered as one supernode,
+ *          regardless of the row structures of those columns.
+ *
+ * panel_size (input) int
+ *          A panel consists of at most panel_size consecutive columns.
+ *
+ * etree    (input) int*, dimension (A->ncol)
+ *          Elimination tree of A'*A.
+ *          Note: etree is a vector of parent pointers for a forest whose
+ *          vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *          On input, the columns of A should be permuted so that the
+ *          etree is in a certain postorder.
+ *
+ * work     (input/output) void*, size (lwork) (in bytes)
+ *          User-supplied work space and space for the output data structures.
+ *          Not referenced if lwork = 0;
+ *
+ * lwork   (input) int
+ *         Specifies the size of work array in bytes.
+ *         = 0:  allocate space internally by system malloc;
+ *         > 0:  use user-supplied work array of length lwork in bytes,
+ *               returns error if space runs out.
+ *         = -1: the routine guesses the amount of space needed without
+ *               performing the factorization, and returns it in
+ *               *info; no other side effects.
+ *
+ * perm_c   (input) int*, dimension (A->ncol)
+ *	    Column permutation vector, which defines the 
+ *          permutation matrix Pc; perm_c[i] = j means column i of A is 
+ *          in position j in A*Pc.
+ *          When searching for diagonal, perm_c[*] is applied to the
+ *          row subscripts of A, so that diagonal threshold pivoting
+ *          can find the diagonal of A, rather than that of A*Pc.
+ *
+ * perm_r   (input/output) int*, dimension (A->nrow)
+ *          Row permutation vector which defines the permutation matrix Pr,
+ *          perm_r[i] = j means row i of A is in position j in Pr*A.
+ *          If options->Fact == SamePattern_SameRowPerm, the pivoting routine
+ *             will try to use the input perm_r, unless a certain threshold
+ *             criterion is violated. In that case, perm_r is overwritten by
+ *             a new permutation determined by partial pivoting or diagonal
+ *             threshold pivoting.
+ *          Otherwise, perm_r is output argument;
+ *
+ * L        (output) SuperMatrix*
+ *          The factor L from the factorization Pr*A=L*U; use compressed row 
+ *          subscripts storage for supernodes, i.e., L has type: 
+ *          Stype = SLU_SC, Dtype = SLU_C, Mtype = SLU_TRLU.
+ *
+ * U        (output) SuperMatrix*
+ *	    The factor U from the factorization Pr*A*Pc=L*U. Use column-wise
+ *          storage scheme, i.e., U has types: Stype = SLU_NC, 
+ *          Dtype = SLU_C, Mtype = SLU_TRU.
+ *
+ * Glu      (input/output) GlobalLU_t *
+ *          If options->Fact == SamePattern_SameRowPerm, it is an input;
+ *              The matrix A will be factorized assuming that a 
+ *              factorization of a matrix with the same sparsity pattern
+ *              and similar numerical values was performed prior to this one.
+ *              Therefore, this factorization will reuse both row and column
+ *		scaling factors R and C, both row and column permutation
+ *		vectors perm_r and perm_c, and the L & U data structures
+ *		set up from the previous factorization.
+ *          Otherwise, it is an output.
+ *
+ * stat     (output) SuperLUStat_t*
+ *          Record the statistics on runtime and floating-point operation count.
+ *          See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info     (output) int*
+ *          = 0: successful exit
+ *          < 0: if info = -i, the i-th argument had an illegal value
+ *          > 0: if info = i, and i is
+ *             <= A->ncol: U(i,i) is exactly zero. The factorization has
+ *                been completed, but the factor U is exactly singular,
+ *                and division by zero will occur if it is used to solve a
+ *                system of equations.
+ *             > A->ncol: number of bytes allocated when memory allocation
+ *                failure occurred, plus A->ncol. If lwork = -1, it is
+ *                the estimated amount of space needed, plus A->ncol.
+ *
+ * ======================================================================
+ *
+ * Local Working Arrays: 
+ * ======================
+ *   m = number of rows in the matrix
+ *   n = number of columns in the matrix
+ *
+ *   xprune[0:n-1]: xprune[*] points to locations in subscript 
+ *	vector lsub[*]. For column i, xprune[i] denotes the point where 
+ *	structural pruning begins. I.e. only xlsub[i],..,xprune[i]-1 need 
+ *	to be traversed for symbolic factorization.
+ *
+ *   marker[0:3*m-1]: marker[i] = j means that node i has been 
+ *	reached when working on column j.
+ *	Storage: relative to original row subscripts
+ *	NOTE: There are 3 of them: marker/marker1 are used for panel dfs, 
+ *	      see cpanel_dfs.c; marker2 is used for inner-factorization,
+ *            see ccolumn_dfs.c.
+ *
+ *   parent[0:m-1]: parent vector used during dfs
+ *      Storage: relative to new row subscripts
+ *
+ *   xplore[0:m-1]: xplore[i] gives the location of the next (dfs) 
+ *	unexplored neighbor of i in lsub[*]
+ *
+ *   segrep[0:nseg-1]: contains the list of supernodal representatives
+ *	in topological order of the dfs. A supernode representative is the 
+ *	last column of a supernode.
+ *      The maximum size of segrep[] is n.
+ *
+ *   repfnz[0:W*m-1]: for a nonzero segment U[*,j] that ends at a 
+ *	supernodal representative r, repfnz[r] is the location of the first 
+ *	nonzero in this segment.  It is also used during the dfs: repfnz[r]>0
+ *	indicates the supernode r has been explored.
+ *	NOTE: There are W of them, each used for one column of a panel. 
+ *
+ *   panel_lsub[0:W*m-1]: temporary for the nonzeros row indices below 
+ *      the panel diagonal. These are filled in during cpanel_dfs(), and are
+ *      used later in the inner LU factorization within the panel.
+ *	panel_lsub[]/dense[] pair forms the SPA data structure.
+ *	NOTE: There are W of them.
+ *
+ *   dense[0:W*m-1]: sparse accumulating (SPA) vector for intermediate values;
+ *	    	   NOTE: there are W of them.
+ *
+ *   tempv[0:*]: real temporary used for dense numeric kernels;
+ *	The size of this array is defined by NUM_TEMPV() in slu_cdefs.h.
+ * 
+ */ + +void +cgstrf (superlu_options_t *options, SuperMatrix *A, + int relax, int panel_size, int *etree, void *work, int lwork, + int *perm_c, int *perm_r, SuperMatrix *L, SuperMatrix *U, + GlobalLU_t *Glu, /* persistent to facilitate multiple factorizations */ + SuperLUStat_t *stat, int *info) +{ + /* Local working arrays */ + NCPformat *Astore; + int *iperm_r = NULL; /* inverse of perm_r; used when + options->Fact == SamePattern_SameRowPerm */ + int *iperm_c; /* inverse of perm_c */ + int *iwork; + complex *cwork; + int *segrep, *repfnz, *parent, *xplore; + int *panel_lsub; /* dense[]/panel_lsub[] pair forms a w-wide SPA */ + int *xprune; + int *marker; + complex *dense, *tempv; + int *relax_end; + complex *a; + int *asub; + int *xa_begin, *xa_end; + int *xsup, *supno; + int *xlsub, *xlusup, *xusub; + int nzlumax; + float fill_ratio = sp_ienv(6); /* estimated fill ratio */ + + /* Local scalars */ + fact_t fact = options->Fact; + double diag_pivot_thresh = options->DiagPivotThresh; + int pivrow; /* pivotal row number in the original matrix A */ + int nseg1; /* no of segments in U-column above panel row jcol */ + int nseg; /* no of segments in each U-column */ + register int jcol; + register int kcol; /* end column of a relaxed snode */ + register int icol; + register int i, k, jj, new_next, iinfo; + int m, n, min_mn, jsupno, fsupc, nextlu, nextu; + int w_def; /* upper bound on panel width */ + int usepr, iperm_r_allocated = 0; + int nnzL, nnzU; + int *panel_histo = stat->panel_histo; + flops_t *ops = stat->ops; + + iinfo = 0; + m = A->nrow; + n = A->ncol; + min_mn = SUPERLU_MIN(m, n); + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + + /* Allocate storage common to the factor routines */ + *info = cLUMemInit(fact, work, lwork, m, n, Astore->nnz, + panel_size, fill_ratio, L, U, Glu, &iwork, &cwork); + if ( *info ) return; + + xsup = Glu->xsup; + supno = Glu->supno; + xlsub = Glu->xlsub; + xlusup = Glu->xlusup; + xusub = Glu->xusub; + + SetIWork(m, n, panel_size, iwork, &segrep, &parent, &xplore, + &repfnz, &panel_lsub, &xprune, &marker); + cSetRWork(m, panel_size, cwork, &dense, &tempv); + + usepr = (fact == SamePattern_SameRowPerm); + if ( usepr ) { + /* Compute the inverse of perm_r */ + iperm_r = (int *) intMalloc(m); + for (k = 0; k < m; ++k) iperm_r[perm_r[k]] = k; + iperm_r_allocated = 1; + } + iperm_c = (int *) intMalloc(n); + for (k = 0; k < n; ++k) iperm_c[perm_c[k]] = k; + + /* Identify relaxed snodes */ + relax_end = (int *) intMalloc(n); + if ( options->SymmetricMode == YES ) { + heap_relax_snode(n, etree, relax, marker, relax_end); + } else { + relax_snode(n, etree, relax, marker, relax_end); + } + + ifill (perm_r, m, EMPTY); + ifill (marker, m * NO_MARKER, EMPTY); + supno[0] = -1; + xsup[0] = xlsub[0] = xusub[0] = xlusup[0] = 0; + w_def = panel_size; + + /* + * Work on one "panel" at a time. A panel is one of the following: + * (a) a relaxed supernode at the bottom of the etree, or + * (b) panel_size contiguous columns, defined by the user + */ + for (jcol = 0; jcol < min_mn; ) { + + if ( relax_end[jcol] != EMPTY ) { /* start of a relaxed snode */ + kcol = relax_end[jcol]; /* end of the relaxed snode */ + panel_histo[kcol-jcol+1]++; + + /* -------------------------------------- + * Factorize the relaxed supernode(jcol:kcol) + * -------------------------------------- */ + /* Determine the union of the row structure of the snode */ + if ( (*info = csnode_dfs(jcol, kcol, asub, xa_begin, xa_end, + xprune, marker, Glu)) != 0 ) + return; + + nextu = xusub[jcol]; + nextlu = xlusup[jcol]; + jsupno = supno[jcol]; + fsupc = xsup[jsupno]; + new_next = nextlu + (xlsub[fsupc+1]-xlsub[fsupc])*(kcol-jcol+1); + nzlumax = Glu->nzlumax; + while ( new_next > nzlumax ) { + if ( (*info = cLUMemXpand(jcol, nextlu, LUSUP, &nzlumax, Glu)) ) + return; + } + + for (icol = jcol; icol<= kcol; icol++) { + xusub[icol+1] = nextu; + + /* Scatter into SPA dense[*] */ + for (k = xa_begin[icol]; k < xa_end[icol]; k++) + dense[asub[k]] = a[k]; + + /* Numeric update within the snode */ + csnode_bmod(icol, jsupno, fsupc, dense, tempv, Glu, stat); + + if ( (*info = cpivotL(icol, diag_pivot_thresh, &usepr, perm_r, + iperm_r, iperm_c, &pivrow, Glu, stat)) ) + if ( iinfo == 0 ) iinfo = *info; + +#ifdef DEBUG + cprint_lu_col("[1]: ", icol, pivrow, xprune, Glu); +#endif + + } + + jcol = icol; + + } else { /* Work on one panel of panel_size columns */ + + /* Adjust panel_size so that a panel won't overlap with the next + * relaxed snode. + */ + panel_size = w_def; + for (k = jcol + 1; k < SUPERLU_MIN(jcol+panel_size, min_mn); k++) + if ( relax_end[k] != EMPTY ) { + panel_size = k - jcol; + break; + } + if ( k == min_mn ) panel_size = min_mn - jcol; + panel_histo[panel_size]++; + + /* symbolic factor on a panel of columns */ + cpanel_dfs(m, panel_size, jcol, A, perm_r, &nseg1, + dense, panel_lsub, segrep, repfnz, xprune, + marker, parent, xplore, Glu); + + /* numeric sup-panel updates in topological order */ + cpanel_bmod(m, panel_size, jcol, nseg1, dense, + tempv, segrep, repfnz, Glu, stat); + + /* Sparse LU within the panel, and below panel diagonal */ + for ( jj = jcol; jj < jcol + panel_size; jj++) { + k = (jj - jcol) * m; /* column index for w-wide arrays */ + + nseg = nseg1; /* Begin after all the panel segments */ + + if ((*info = ccolumn_dfs(m, jj, perm_r, &nseg, &panel_lsub[k], + segrep, &repfnz[k], xprune, marker, + parent, xplore, Glu)) != 0) return; + + /* Numeric updates */ + if ((*info = ccolumn_bmod(jj, (nseg - nseg1), &dense[k], + tempv, &segrep[nseg1], &repfnz[k], + jcol, Glu, stat)) != 0) return; + + /* Copy the U-segments to ucol[*] */ + if ((*info = ccopy_to_ucol(jj, nseg, segrep, &repfnz[k], + perm_r, &dense[k], Glu)) != 0) + return; + + if ( (*info = cpivotL(jj, diag_pivot_thresh, &usepr, perm_r, + iperm_r, iperm_c, &pivrow, Glu, stat)) ) + if ( iinfo == 0 ) iinfo = *info; + + /* Prune columns (0:jj-1) using column jj */ + cpruneL(jj, perm_r, pivrow, nseg, segrep, + &repfnz[k], xprune, Glu); + + /* Reset repfnz[] for this column */ + resetrep_col (nseg, segrep, &repfnz[k]); + +#ifdef DEBUG + cprint_lu_col("[2]: ", jj, pivrow, xprune, Glu); +#endif + + } + + jcol += panel_size; /* Move to the next panel */ + + } /* else */ + + } /* for */ + + *info = iinfo; + + if ( m > n ) { + k = 0; + for (i = 0; i < m; ++i) + if ( perm_r[i] == EMPTY ) { + perm_r[i] = n + k; + ++k; + } + } + + countnz(min_mn, xprune, &nnzL, &nnzU, Glu); + fixupL(min_mn, perm_r, Glu); + + cLUWorkFree(iwork, cwork, Glu); /* Free work space and compress storage */ + + if ( fact == SamePattern_SameRowPerm ) { + /* L and U structures may have changed due to possibly different + pivoting, even though the storage is available. + There could also be memory expansions, so the array locations + may have changed, */ + ((SCformat *)L->Store)->nnz = nnzL; + ((SCformat *)L->Store)->nsuper = Glu->supno[n]; + ((SCformat *)L->Store)->nzval = (complex *) Glu->lusup; + ((SCformat *)L->Store)->nzval_colptr = Glu->xlusup; + ((SCformat *)L->Store)->rowind = Glu->lsub; + ((SCformat *)L->Store)->rowind_colptr = Glu->xlsub; + ((NCformat *)U->Store)->nnz = nnzU; + ((NCformat *)U->Store)->nzval = (complex *) Glu->ucol; + ((NCformat *)U->Store)->rowind = Glu->usub; + ((NCformat *)U->Store)->colptr = Glu->xusub; + } else { + cCreate_SuperNode_Matrix(L, A->nrow, min_mn, nnzL, + (complex *) Glu->lusup, Glu->xlusup, + Glu->lsub, Glu->xlsub, Glu->supno, Glu->xsup, + SLU_SC, SLU_C, SLU_TRLU); + cCreate_CompCol_Matrix(U, min_mn, min_mn, nnzU, + (complex *) Glu->ucol, Glu->usub, Glu->xusub, + SLU_NC, SLU_C, SLU_TRU); + } + + ops[FACT] += ops[TRSV] + ops[GEMV]; + stat->expansions = --(Glu->num_expansions); + + if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r); + SUPERLU_FREE (iperm_c); + SUPERLU_FREE (relax_end); + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/cgstrs.c b/src/Libraries/superlu-5.2.1/SRC/cgstrs.c new file mode 100644 index 00000000..f0cc2fcc --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cgstrs.c @@ -0,0 +1,360 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cgstrs.c + * \brief Solves a system using LU factorization + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + +#include "slu_cdefs.h" + + +/* + * Function prototypes + */ +void cusolve(int, int, complex*, complex*); +void clsolve(int, int, complex*, complex*); +void cmatvec(int, int, int, complex*, complex*, complex*); + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * CGSTRS solves a system of linear equations A*X=B or A'*X=B
+ * with A sparse and B dense, using the LU factorization computed by
+ * CGSTRF.
+ *
+ * See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * trans   (input) trans_t
+ *          Specifies the form of the system of equations:
+ *          = NOTRANS: A * X = B  (No transpose)
+ *          = TRANS:   A'* X = B  (Transpose)
+ *          = CONJ:    A**H * X = B  (Conjugate transpose)
+ *
+ * L       (input) SuperMatrix*
+ *         The factor L from the factorization Pr*A*Pc=L*U as computed by
+ *         cgstrf(). Use compressed row subscripts storage for supernodes,
+ *         i.e., L has types: Stype = SLU_SC, Dtype = SLU_C, Mtype = SLU_TRLU.
+ *
+ * U       (input) SuperMatrix*
+ *         The factor U from the factorization Pr*A*Pc=L*U as computed by
+ *         cgstrf(). Use column-wise storage scheme, i.e., U has types:
+ *         Stype = SLU_NC, Dtype = SLU_C, Mtype = SLU_TRU.
+ *
+ * perm_c  (input) int*, dimension (L->ncol)
+ *	   Column permutation vector, which defines the 
+ *         permutation matrix Pc; perm_c[i] = j means column i of A is 
+ *         in position j in A*Pc.
+ *
+ * perm_r  (input) int*, dimension (L->nrow)
+ *         Row permutation vector, which defines the permutation matrix Pr; 
+ *         perm_r[i] = j means row i of A is in position j in Pr*A.
+ *
+ * B       (input/output) SuperMatrix*
+ *         B has types: Stype = SLU_DN, Dtype = SLU_C, Mtype = SLU_GE.
+ *         On entry, the right hand side matrix.
+ *         On exit, the solution matrix if info = 0;
+ *
+ * stat     (output) SuperLUStat_t*
+ *          Record the statistics on runtime and floating-point operation count.
+ *          See util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ * 	   = 0: successful exit
+ *	   < 0: if info = -i, the i-th argument had an illegal value
+ * 
+ */ + +void +cgstrs (trans_t trans, SuperMatrix *L, SuperMatrix *U, + int *perm_c, int *perm_r, SuperMatrix *B, + SuperLUStat_t *stat, int *info) +{ + +#ifdef _CRAY + _fcd ftcs1, ftcs2, ftcs3, ftcs4; +#endif + int incx = 1, incy = 1; +#ifdef USE_VENDOR_BLAS + complex alpha = {1.0, 0.0}, beta = {1.0, 0.0}; + complex *work_col; +#endif + complex temp_comp; + DNformat *Bstore; + complex *Bmat; + SCformat *Lstore; + NCformat *Ustore; + complex *Lval, *Uval; + int fsupc, nrow, nsupr, nsupc, luptr, istart, irow; + int i, j, k, iptr, jcol, n, ldb, nrhs; + complex *work, *rhs_work, *soln; + flops_t solve_ops; + void cprint_soln(); + + /* Test input parameters ... */ + *info = 0; + Bstore = B->Store; + ldb = Bstore->lda; + nrhs = B->ncol; + if ( trans != NOTRANS && trans != TRANS && trans != CONJ ) *info = -1; + else if ( L->nrow != L->ncol || L->nrow < 0 || + L->Stype != SLU_SC || L->Dtype != SLU_C || L->Mtype != SLU_TRLU ) + *info = -2; + else if ( U->nrow != U->ncol || U->nrow < 0 || + U->Stype != SLU_NC || U->Dtype != SLU_C || U->Mtype != SLU_TRU ) + *info = -3; + else if ( ldb < SUPERLU_MAX(0, L->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_C || B->Mtype != SLU_GE ) + *info = -6; + if ( *info ) { + i = -(*info); + input_error("cgstrs", &i); + return; + } + + n = L->nrow; + work = complexCalloc(n * nrhs); + if ( !work ) ABORT("Malloc fails for local work[]."); + soln = complexMalloc(n); + if ( !soln ) ABORT("Malloc fails for local soln[]."); + + Bmat = Bstore->nzval; + Lstore = L->Store; + Lval = Lstore->nzval; + Ustore = U->Store; + Uval = Ustore->nzval; + solve_ops = 0; + + if ( trans == NOTRANS ) { + /* Permute right hand sides to form Pr*B */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[perm_r[k]] = rhs_work[k]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + /* Forward solve PLy=Pb. */ + for (k = 0; k <= Lstore->nsuper; k++) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + nrow = nsupr - nsupc; + + solve_ops += 4 * nsupc * (nsupc - 1) * nrhs; + solve_ops += 8 * nrow * nsupc * nrhs; + + if ( nsupc == 1 ) { + for (j = 0; j < nrhs; j++) { + rhs_work = &Bmat[j*ldb]; + luptr = L_NZ_START(fsupc); + for (iptr=istart+1; iptr < L_SUB_START(fsupc+1); iptr++){ + irow = L_SUB(iptr); + ++luptr; + cc_mult(&temp_comp, &rhs_work[fsupc], &Lval[luptr]); + c_sub(&rhs_work[irow], &rhs_work[irow], &temp_comp); + } + } + } else { + luptr = L_NZ_START(fsupc); +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + ftcs1 = _cptofcd("L", strlen("L")); + ftcs2 = _cptofcd("N", strlen("N")); + ftcs3 = _cptofcd("U", strlen("U")); + CTRSM( ftcs1, ftcs1, ftcs2, ftcs3, &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); + + CGEMM( ftcs2, ftcs2, &nrow, &nrhs, &nsupc, &alpha, + &Lval[luptr+nsupc], &nsupr, &Bmat[fsupc], &ldb, + &beta, &work[0], &n ); +#else + ctrsm_("L", "L", "N", "U", &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); + + cgemm_( "N", "N", &nrow, &nrhs, &nsupc, &alpha, + &Lval[luptr+nsupc], &nsupr, &Bmat[fsupc], &ldb, + &beta, &work[0], &n ); +#endif + for (j = 0; j < nrhs; j++) { + rhs_work = &Bmat[j*ldb]; + work_col = &work[j*n]; + iptr = istart + nsupc; + for (i = 0; i < nrow; i++) { + irow = L_SUB(iptr); + c_sub(&rhs_work[irow], &rhs_work[irow], &work_col[i]); + work_col[i].r = 0.0; + work_col[i].i = 0.0; + iptr++; + } + } +#else + for (j = 0; j < nrhs; j++) { + rhs_work = &Bmat[j*ldb]; + clsolve (nsupr, nsupc, &Lval[luptr], &rhs_work[fsupc]); + cmatvec (nsupr, nrow, nsupc, &Lval[luptr+nsupc], + &rhs_work[fsupc], &work[0] ); + + iptr = istart + nsupc; + for (i = 0; i < nrow; i++) { + irow = L_SUB(iptr); + c_sub(&rhs_work[irow], &rhs_work[irow], &work[i]); + work[i].r = 0.; + work[i].i = 0.; + iptr++; + } + } +#endif + } /* else ... */ + } /* for L-solve */ + +#ifdef DEBUG + printf("After L-solve: y=\n"); + cprint_soln(n, nrhs, Bmat); +#endif + + /* + * Back solve Ux=y. + */ + for (k = Lstore->nsuper; k >= 0; k--) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + solve_ops += 4 * nsupc * (nsupc + 1) * nrhs; + + if ( nsupc == 1 ) { + rhs_work = &Bmat[0]; + for (j = 0; j < nrhs; j++) { + c_div(&rhs_work[fsupc], &rhs_work[fsupc], &Lval[luptr]); + rhs_work += ldb; + } + } else { +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + ftcs1 = _cptofcd("L", strlen("L")); + ftcs2 = _cptofcd("U", strlen("U")); + ftcs3 = _cptofcd("N", strlen("N")); + CTRSM( ftcs1, ftcs2, ftcs3, ftcs3, &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); +#else + ctrsm_("L", "U", "N", "N", &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); +#endif +#else + for (j = 0; j < nrhs; j++) + cusolve ( nsupr, nsupc, &Lval[luptr], &Bmat[fsupc+j*ldb] ); +#endif + } + + for (j = 0; j < nrhs; ++j) { + rhs_work = &Bmat[j*ldb]; + for (jcol = fsupc; jcol < fsupc + nsupc; jcol++) { + solve_ops += 8*(U_NZ_START(jcol+1) - U_NZ_START(jcol)); + for (i = U_NZ_START(jcol); i < U_NZ_START(jcol+1); i++ ){ + irow = U_SUB(i); + cc_mult(&temp_comp, &rhs_work[jcol], &Uval[i]); + c_sub(&rhs_work[irow], &rhs_work[irow], &temp_comp); + } + } + } + + } /* for U-solve */ + +#ifdef DEBUG + printf("After U-solve: x=\n"); + cprint_soln(n, nrhs, Bmat); +#endif + + /* Compute the final solution X := Pc*X. */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[k] = rhs_work[perm_c[k]]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + stat->ops[SOLVE] = solve_ops; + + } else { /* Solve A'*X=B or CONJ(A)*X=B */ + /* Permute right hand sides to form Pc'*B. */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[perm_c[k]] = rhs_work[k]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + stat->ops[SOLVE] = 0; + if (trans == TRANS) { + for (k = 0; k < nrhs; ++k) { + /* Multiply by inv(U'). */ + sp_ctrsv("U", "T", "N", L, U, &Bmat[k*ldb], stat, info); + + /* Multiply by inv(L'). */ + sp_ctrsv("L", "T", "U", L, U, &Bmat[k*ldb], stat, info); + } + } else { /* trans == CONJ */ + for (k = 0; k < nrhs; ++k) { + /* Multiply by conj(inv(U')). */ + sp_ctrsv("U", "C", "N", L, U, &Bmat[k*ldb], stat, info); + + /* Multiply by conj(inv(L')). */ + sp_ctrsv("L", "C", "U", L, U, &Bmat[k*ldb], stat, info); + } + } + /* Compute the final solution X := Pr'*X (=inv(Pr)*X) */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[k] = rhs_work[perm_r[k]]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + } + + SUPERLU_FREE(work); + SUPERLU_FREE(soln); +} + +/* + * Diagnostic print of the solution vector + */ +void +cprint_soln(int n, int nrhs, complex *soln) +{ + int i; + + for (i = 0; i < n; i++) + printf("\t%d: %.4f\t%.4f\n", i, soln[i].r, soln[i].i); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/clacon.c b/src/Libraries/superlu-5.2.1/SRC/clacon.c new file mode 100644 index 00000000..f850bdb5 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/clacon.c @@ -0,0 +1,232 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file clacon.c + * \brief Estimates the 1-norm + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ */ +#include +#include "slu_Cnames.h" +#include "slu_scomplex.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   CLACON estimates the 1-norm of a square matrix A.   
+ *   Reverse communication is used for evaluating matrix-vector products. 
+ * 
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   N      (input) INT
+ *          The order of the matrix.  N >= 1.   
+ *
+ *   V      (workspace) COMPLEX PRECISION array, dimension (N)   
+ *          On the final return, V = A*W,  where  EST = norm(V)/norm(W)   
+ *          (W is not returned).   
+ *
+ *   X      (input/output) COMPLEX PRECISION array, dimension (N)   
+ *          On an intermediate return, X should be overwritten by   
+ *                A * X,   if KASE=1,   
+ *                A' * X,  if KASE=2,
+ *          where A' is the conjugate transpose of A,
+ *         and CLACON must be re-called with all the other parameters   
+ *          unchanged.   
+ *
+ *
+ *   EST    (output) FLOAT PRECISION   
+ *          An estimate (a lower bound) for norm(A).   
+ *
+ *   KASE   (input/output) INT
+ *          On the initial call to CLACON, KASE should be 0.   
+ *          On an intermediate return, KASE will be 1 or 2, indicating   
+ *          whether X should be overwritten by A * X  or A' * X.   
+ *          On the final return from CLACON, KASE will again be 0.   
+ *
+ *   Further Details   
+ *   ======= =======   
+ *
+ *   Contributed by Nick Higham, University of Manchester.   
+ *   Originally named CONEST, dated March 16, 1988.   
+ *
+ *   Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of 
+ *   a real or complex matrix, with applications to condition estimation", 
+ *   ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.   
+ *   ===================================================================== 
+ * 
+ */ + +int +clacon_(int *n, complex *v, complex *x, float *est, int *kase) + +{ + + + /* Table of constant values */ + int c__1 = 1; + complex zero = {0.0, 0.0}; + complex one = {1.0, 0.0}; + + /* System generated locals */ + float d__1; + + /* Local variables */ + static int jump; + int jlast; + int iter; + float altsgn, estold; + int i, j; + float temp; + float safmin; + extern float slamch_(char *); + extern int icmax1_slu(int *, complex *, int *); + extern double scsum1_slu(int *, complex *, int *); + + safmin = slamch_("Safe minimum"); + if ( *kase == 0 ) { + for (i = 0; i < *n; ++i) { + x[i].r = 1. / (float) (*n); + x[i].i = 0.; + } + *kase = 1; + jump = 1; + return 0; + } + + switch (jump) { + case 1: goto L20; + case 2: goto L40; + case 3: goto L70; + case 4: goto L110; + case 5: goto L140; + } + + /* ................ ENTRY (JUMP = 1) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY A*X. */ + L20: + if (*n == 1) { + v[0] = x[0]; + *est = c_abs(&v[0]); + /* ... QUIT */ + goto L150; + } + *est = scsum1_slu(n, x, &c__1); + + for (i = 0; i < *n; ++i) { + d__1 = c_abs(&x[i]); + if (d__1 > safmin) { + d__1 = 1 / d__1; + x[i].r *= d__1; + x[i].i *= d__1; + } else { + x[i] = one; + } + } + *kase = 2; + jump = 2; + return 0; + + /* ................ ENTRY (JUMP = 2) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X. */ +L40: + j = icmax1_slu(n, &x[0], &c__1); + --j; + iter = 2; + + /* MAIN LOOP - ITERATIONS 2,3,...,ITMAX. */ +L50: + for (i = 0; i < *n; ++i) x[i] = zero; + x[j] = one; + *kase = 1; + jump = 3; + return 0; + + /* ................ ENTRY (JUMP = 3) + X HAS BEEN OVERWRITTEN BY A*X. */ +L70: +#ifdef _CRAY + CCOPY(n, x, &c__1, v, &c__1); +#else + ccopy_(n, x, &c__1, v, &c__1); +#endif + estold = *est; + *est = scsum1_slu(n, v, &c__1); + + +L90: + /* TEST FOR CYCLING. */ + if (*est <= estold) goto L120; + + for (i = 0; i < *n; ++i) { + d__1 = c_abs(&x[i]); + if (d__1 > safmin) { + d__1 = 1 / d__1; + x[i].r *= d__1; + x[i].i *= d__1; + } else { + x[i] = one; + } + } + *kase = 2; + jump = 4; + return 0; + + /* ................ ENTRY (JUMP = 4) + X HAS BEEN OVERWRITTEN BY TRANDPOSE(A)*X. */ +L110: + jlast = j; + j = icmax1_slu(n, &x[0], &c__1); + --j; + if (x[jlast].r != (d__1 = x[j].r, fabs(d__1)) && iter < 5) { + ++iter; + goto L50; + } + + /* ITERATION COMPLETE. FINAL STAGE. */ +L120: + altsgn = 1.; + for (i = 1; i <= *n; ++i) { + x[i-1].r = altsgn * ((float)(i - 1) / (float)(*n - 1) + 1.); + x[i-1].i = 0.; + altsgn = -altsgn; + } + *kase = 1; + jump = 5; + return 0; + + /* ................ ENTRY (JUMP = 5) + X HAS BEEN OVERWRITTEN BY A*X. */ +L140: + temp = scsum1_slu(n, x, &c__1) / (float)(*n * 3) * 2.; + if (temp > *est) { +#ifdef _CRAY + CCOPY(n, &x[0], &c__1, &v[0], &c__1); +#else + ccopy_(n, &x[0], &c__1, &v[0], &c__1); +#endif + *est = temp; + } + +L150: + *kase = 0; + return 0; + +} /* clacon_ */ diff --git a/src/Libraries/superlu-5.2.1/SRC/clacon2.c b/src/Libraries/superlu-5.2.1/SRC/clacon2.c new file mode 100644 index 00000000..107bb644 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/clacon2.c @@ -0,0 +1,239 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file clacon2.c + * \brief Estimates the 1-norm + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * July 25, 2015
+ * 
+ */ +#include +#include "slu_Cnames.h" +#include "slu_scomplex.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   CLACON2 estimates the 1-norm of a square matrix A.   
+ *   Reverse communication is used for evaluating matrix-vector products. 
+ * 
+ *   This is a thread safe version of CLACON, which uses the array ISAVE
+ *   in place of a STATIC variables, as follows:
+ *
+ *     CLACON     CLACON2
+ *      jump     isave[0]
+ *      j        isave[1]
+ *      iter     isave[2]
+ *
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   N      (input) INT
+ *          The order of the matrix.  N >= 1.   
+ *
+ *   V      (workspace) COMPLEX PRECISION array, dimension (N)   
+ *          On the final return, V = A*W,  where  EST = norm(V)/norm(W)   
+ *          (W is not returned).   
+ *
+ *   X      (input/output) COMPLEX PRECISION array, dimension (N)   
+ *          On an intermediate return, X should be overwritten by   
+ *                A * X,   if KASE=1,   
+ *                A' * X,  if KASE=2,
+ *          where A' is the conjugate transpose of A,
+ *         and CLACON must be re-called with all the other parameters   
+ *          unchanged.   
+ *
+ *
+ *   EST    (output) FLOAT PRECISION   
+ *          An estimate (a lower bound) for norm(A).   
+ *
+ *   KASE   (input/output) INT
+ *          On the initial call to CLACON, KASE should be 0.   
+ *          On an intermediate return, KASE will be 1 or 2, indicating   
+ *          whether X should be overwritten by A * X  or A' * X.   
+ *          On the final return from CLACON, KASE will again be 0.   
+ *
+ *   isave  (input/output) int [3]
+ *          ISAVE is INTEGER array, dimension (3)
+ *          ISAVE is used to save variables between calls to CLACON2
+ *
+ *   Further Details   
+ *   ===============   
+ *
+ *   Contributed by Nick Higham, University of Manchester.   
+ *   Originally named CONEST, dated March 16, 1988.   
+ *
+ *   Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of 
+ *   a real or complex matrix, with applications to condition estimation", 
+ *   ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.   
+ *   ===================================================================== 
+ * 
+ */ + +int +clacon2_(int *n, complex *v, complex *x, float *est, int *kase, int isave[3]) +{ + /* Table of constant values */ + int c__1 = 1; + complex zero = {0.0, 0.0}; + complex one = {1.0, 0.0}; + + /* System generated locals */ + float d__1; + + /* Local variables */ + int jlast; + float altsgn, estold; + int i; + float temp; + float safmin; + extern float smach(char *); + extern int icmax1_slu(int *, complex *, int *); + extern double scsum1_slu(int *, complex *, int *); + + safmin = smach("Safe minimum"); /* lamch_("Safe minimum"); */ + if ( *kase == 0 ) { + for (i = 0; i < *n; ++i) { + x[i].r = 1. / (float) (*n); + x[i].i = 0.; + } + *kase = 1; + isave[0] = 1; /* jump = 1; */ + return 0; + } + + switch (isave[0]) { + case 1: goto L20; + case 2: goto L40; + case 3: goto L70; + case 4: goto L110; + case 5: goto L140; + } + + /* ................ ENTRY (isave[0] = 1) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY A*X. */ + L20: + if (*n == 1) { + v[0] = x[0]; + *est = c_abs(&v[0]); + /* ... QUIT */ + goto L150; + } + *est = scsum1_slu(n, x, &c__1); + + for (i = 0; i < *n; ++i) { + d__1 = c_abs(&x[i]); + if (d__1 > safmin) { + d__1 = 1 / d__1; + x[i].r *= d__1; + x[i].i *= d__1; + } else { + x[i] = one; + } + } + *kase = 2; + isave[0] = 2; /* jump = 2; */ + return 0; + + /* ................ ENTRY (isave[0] = 2) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X. */ +L40: + isave[1] = icmax1_slu(n, &x[0], &c__1); /* j */ + --isave[1]; /* --j; */ + isave[2] = 2; /* iter = 2; */ + + /* MAIN LOOP - ITERATIONS 2,3,...,ITMAX. */ +L50: + for (i = 0; i < *n; ++i) x[i] = zero; + x[isave[1]] = one; + *kase = 1; + isave[0] = 3; /* jump = 3; */ + return 0; + + /* ................ ENTRY (isave[0] = 3) + X HAS BEEN OVERWRITTEN BY A*X. */ +L70: +#ifdef _CRAY + CCOPY(n, x, &c__1, v, &c__1); +#else + ccopy_(n, x, &c__1, v, &c__1); +#endif + estold = *est; + *est = scsum1_slu(n, v, &c__1); + + +L90: + /* TEST FOR CYCLING. */ + if (*est <= estold) goto L120; + + for (i = 0; i < *n; ++i) { + d__1 = c_abs(&x[i]); + if (d__1 > safmin) { + d__1 = 1 / d__1; + x[i].r *= d__1; + x[i].i *= d__1; + } else { + x[i] = one; + } + } + *kase = 2; + isave[0] = 4; /* jump = 4; */ + return 0; + + /* ................ ENTRY (isave[0] = 4) + X HAS BEEN OVERWRITTEN BY TRANDPOSE(A)*X. */ +L110: + jlast = isave[1]; /* j; */ + isave[1] = icmax1_slu(n, &x[0], &c__1); /* j */ + isave[1] = isave[1] - 1; /* --j; */ + if (x[jlast].r != (d__1 = x[isave[1]].r, fabs(d__1)) && isave[2] < 5) { + isave[2] = isave[2] + 1; /* ++iter; */ + goto L50; + } + + /* ITERATION COMPLETE. FINAL STAGE. */ +L120: + altsgn = 1.; + for (i = 1; i <= *n; ++i) { + x[i-1].r = altsgn * ((float)(i - 1) / (float)(*n - 1) + 1.); + x[i-1].i = 0.; + altsgn = -altsgn; + } + *kase = 1; + isave[0] = 5; /* jump = 5; */ + return 0; + + /* ................ ENTRY (isave[0] = 5) + X HAS BEEN OVERWRITTEN BY A*X. */ +L140: + temp = scsum1_slu(n, x, &c__1) / (float)(*n * 3) * 2.; + if (temp > *est) { +#ifdef _CRAY + CCOPY(n, &x[0], &c__1, &v[0], &c__1); +#else + ccopy_(n, &x[0], &c__1, &v[0], &c__1); +#endif + *est = temp; + } + +L150: + *kase = 0; + return 0; + +} /* clacon_ */ diff --git a/src/Libraries/superlu-5.2.1/SRC/clangs.c b/src/Libraries/superlu-5.2.1/SRC/clangs.c new file mode 100644 index 00000000..fa8ad8d5 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/clangs.c @@ -0,0 +1,129 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file clangs.c + * \brief Returns the value of the one norm + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Modified from lapack routine CLANGE 
+ * 
+ */ +/* + * File name: clangs.c + * History: Modified from lapack routine CLANGE + */ +#include +#include "slu_cdefs.h" + +/*! \brief + * + *
+ * Purpose   
+ *   =======   
+ *
+ *   CLANGS returns the value of the one norm, or the Frobenius norm, or 
+ *   the infinity norm, or the element of largest absolute value of a 
+ *   real matrix A.   
+ *
+ *   Description   
+ *   ===========   
+ *
+ *   CLANGE returns the value   
+ *
+ *      CLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm'   
+ *               (   
+ *               ( norm1(A),         NORM = '1', 'O' or 'o'   
+ *               (   
+ *               ( normI(A),         NORM = 'I' or 'i'   
+ *               (   
+ *               ( normF(A),         NORM = 'F', 'f', 'E' or 'e'   
+ *
+ *   where  norm1  denotes the  one norm of a matrix (maximum column sum), 
+ *   normI  denotes the  infinity norm  of a matrix  (maximum row sum) and 
+ *   normF  denotes the  Frobenius norm of a matrix (square root of sum of 
+ *   squares).  Note that  max(abs(A(i,j)))  is not a  matrix norm.   
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   NORM    (input) CHARACTER*1   
+ *           Specifies the value to be returned in CLANGE as described above.   
+ *   A       (input) SuperMatrix*
+ *           The M by N sparse matrix A. 
+ *
+ *  =====================================================================
+ * 
+ */ + +float clangs(char *norm, SuperMatrix *A) +{ + + /* Local variables */ + NCformat *Astore; + complex *Aval; + int i, j, irow; + float value, sum; + float *rwork; + + Astore = A->Store; + Aval = Astore->nzval; + + if ( SUPERLU_MIN(A->nrow, A->ncol) == 0) { + value = 0.; + + } else if (strncmp(norm, "M", 1)==0) { + /* Find max(abs(A(i,j))). */ + value = 0.; + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++) + value = SUPERLU_MAX( value, c_abs( &Aval[i]) ); + + } else if (strncmp(norm, "O", 1)==0 || *(unsigned char *)norm == '1') { + /* Find norm1(A). */ + value = 0.; + for (j = 0; j < A->ncol; ++j) { + sum = 0.; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++) + sum += c_abs( &Aval[i] ); + value = SUPERLU_MAX(value,sum); + } + + } else if (strncmp(norm, "I", 1)==0) { + /* Find normI(A). */ + if ( !(rwork = (float *) SUPERLU_MALLOC(A->nrow * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for rwork."); + for (i = 0; i < A->nrow; ++i) rwork[i] = 0.; + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++) { + irow = Astore->rowind[i]; + rwork[irow] += c_abs( &Aval[i] ); + } + value = 0.; + for (i = 0; i < A->nrow; ++i) + value = SUPERLU_MAX(value, rwork[i]); + + SUPERLU_FREE (rwork); + + } else if (strncmp(norm, "F", 1)==0 || strncmp(norm, "E", 1)==0) { + /* Find normF(A). */ + ABORT("Not implemented."); + } else + ABORT("Illegal norm specified."); + + return (value); + +} /* clangs */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/claqgs.c b/src/Libraries/superlu-5.2.1/SRC/claqgs.c new file mode 100644 index 00000000..71361a3c --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/claqgs.c @@ -0,0 +1,157 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file claqgs.c + * \brief Equlibrates a general sprase matrix + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ * Modified from LAPACK routine CLAQGE
+ * 
+ */ +/* + * File name: claqgs.c + * History: Modified from LAPACK routine CLAQGE + */ +#include +#include "slu_cdefs.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   CLAQGS equilibrates a general sparse M by N matrix A using the row and   
+ *   scaling factors in the vectors R and C.   
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   A       (input/output) SuperMatrix*
+ *           On exit, the equilibrated matrix.  See EQUED for the form of 
+ *           the equilibrated matrix. The type of A can be:
+ *	    Stype = NC; Dtype = SLU_C; Mtype = GE.
+ *	    
+ *   R       (input) float*, dimension (A->nrow)
+ *           The row scale factors for A.
+ *	    
+ *   C       (input) float*, dimension (A->ncol)
+ *           The column scale factors for A.
+ *	    
+ *   ROWCND  (input) float
+ *           Ratio of the smallest R(i) to the largest R(i).
+ *	    
+ *   COLCND  (input) float
+ *           Ratio of the smallest C(i) to the largest C(i).
+ *	    
+ *   AMAX    (input) float
+ *           Absolute value of largest matrix entry.
+ *	    
+ *   EQUED   (output) char*
+ *           Specifies the form of equilibration that was done.   
+ *           = 'N':  No equilibration   
+ *           = 'R':  Row equilibration, i.e., A has been premultiplied by  
+ *                   diag(R).   
+ *           = 'C':  Column equilibration, i.e., A has been postmultiplied  
+ *                   by diag(C).   
+ *           = 'B':  Both row and column equilibration, i.e., A has been
+ *                   replaced by diag(R) * A * diag(C).   
+ *
+ *   Internal Parameters   
+ *   ===================   
+ *
+ *   THRESH is a threshold value used to decide if row or column scaling   
+ *   should be done based on the ratio of the row or column scaling   
+ *   factors.  If ROWCND < THRESH, row scaling is done, and if   
+ *   COLCND < THRESH, column scaling is done.   
+ *
+ *   LARGE and SMALL are threshold values used to decide if row scaling   
+ *   should be done based on the absolute size of the largest matrix   
+ *   element.  If AMAX > LARGE or AMAX < SMALL, row scaling is done.   
+ *
+ *   ===================================================================== 
+ * 
+ */ + +void +claqgs(SuperMatrix *A, float *r, float *c, + float rowcnd, float colcnd, float amax, char *equed) +{ + + +#define THRESH (0.1) + + /* Local variables */ + NCformat *Astore; + complex *Aval; + int i, j, irow; + float large, small, cj; + float temp; + + + /* Quick return if possible */ + if (A->nrow <= 0 || A->ncol <= 0) { + *(unsigned char *)equed = 'N'; + return; + } + + Astore = A->Store; + Aval = Astore->nzval; + + /* Initialize LARGE and SMALL. */ + small = smach("Safe minimum") / smach("Precision"); + large = 1. / small; + + if (rowcnd >= THRESH && amax >= small && amax <= large) { + if (colcnd >= THRESH) + *(unsigned char *)equed = 'N'; + else { + /* Column scaling */ + for (j = 0; j < A->ncol; ++j) { + cj = c[j]; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + cs_mult(&Aval[i], &Aval[i], cj); + } + } + *(unsigned char *)equed = 'C'; + } + } else if (colcnd >= THRESH) { + /* Row scaling, no column scaling */ + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + cs_mult(&Aval[i], &Aval[i], r[irow]); + } + *(unsigned char *)equed = 'R'; + } else { + /* Row and column scaling */ + for (j = 0; j < A->ncol; ++j) { + cj = c[j]; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + temp = cj * r[irow]; + cs_mult(&Aval[i], &Aval[i], temp); + } + } + *(unsigned char *)equed = 'B'; + } + + return; + +} /* claqgs */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/cldperm.c b/src/Libraries/superlu-5.2.1/SRC/cldperm.c new file mode 100644 index 00000000..2cf88032 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cldperm.c @@ -0,0 +1,178 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file + * \brief Finds a row permutation so that the matrix has large entries on the diagonal + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ + +#include "slu_cdefs.h" + +extern int_t mc64id_(int_t*); +extern int_t mc64ad_(int_t*, int_t*, int_t*, int_t [], int_t [], double [], + int_t*, int_t [], int_t*, int_t[], int_t*, double [], + int_t [], int_t []); + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *   CLDPERM finds a row permutation so that the matrix has large
+ *   entries on the diagonal.
+ *
+ * Arguments
+ * =========
+ *
+ * job    (input) int
+ *        Control the action. Possible values for JOB are:
+ *        = 1 : Compute a row permutation of the matrix so that the
+ *              permuted matrix has as many entries on its diagonal as
+ *              possible. The values on the diagonal are of arbitrary size.
+ *              HSL subroutine MC21A/AD is used for this.
+ *        = 2 : Compute a row permutation of the matrix so that the smallest 
+ *              value on the diagonal of the permuted matrix is maximized.
+ *        = 3 : Compute a row permutation of the matrix so that the smallest
+ *              value on the diagonal of the permuted matrix is maximized.
+ *              The algorithm differs from the one used for JOB = 2 and may
+ *              have quite a different performance.
+ *        = 4 : Compute a row permutation of the matrix so that the sum
+ *              of the diagonal entries of the permuted matrix is maximized.
+ *        = 5 : Compute a row permutation of the matrix so that the product
+ *              of the diagonal entries of the permuted matrix is maximized
+ *              and vectors to scale the matrix so that the nonzero diagonal 
+ *              entries of the permuted matrix are one in absolute value and 
+ *              all the off-diagonal entries are less than or equal to one in 
+ *              absolute value.
+ *        Restriction: 1 <= JOB <= 5.
+ *
+ * n      (input) int
+ *        The order of the matrix.
+ *
+ * nnz    (input) int
+ *        The number of nonzeros in the matrix.
+ *
+ * adjncy (input) int*, of size nnz
+ *        The adjacency structure of the matrix, which contains the row
+ *        indices of the nonzeros.
+ *
+ * colptr (input) int*, of size n+1
+ *        The pointers to the beginning of each column in ADJNCY.
+ *
+ * nzval  (input) complex*, of size nnz
+ *        The nonzero values of the matrix. nzval[k] is the value of
+ *        the entry corresponding to adjncy[k].
+ *        It is not used if job = 1.
+ *
+ * perm   (output) int*, of size n
+ *        The permutation vector. perm[i] = j means row i in the
+ *        original matrix is in row j of the permuted matrix.
+ *
+ * u      (output) double*, of size n
+ *        If job = 5, the natural logarithms of the row scaling factors. 
+ *
+ * v      (output) double*, of size n
+ *        If job = 5, the natural logarithms of the column scaling factors. 
+ *        The scaled matrix B has entries b_ij = a_ij * exp(u_i + v_j).
+ * 
+ */ + +int +cldperm(int_t job, int_t n, int_t nnz, int_t colptr[], int_t adjncy[], + complex nzval[], int_t *perm, float u[], float v[]) +{ + int_t i, liw, ldw, num; + int_t *iw, icntl[10], info[10]; + double *dw; + double *nzval_d = (double *) SUPERLU_MALLOC(nnz * sizeof(double)); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter cldperm()"); +#endif + liw = 5*n; + if ( job == 3 ) liw = 10*n + nnz; + if ( !(iw = intMalloc(liw)) ) ABORT("Malloc fails for iw[]"); + ldw = 3*n + nnz; + if ( !(dw = (double*) SUPERLU_MALLOC(ldw * sizeof(double))) ) + ABORT("Malloc fails for dw[]"); + + /* Increment one to get 1-based indexing. */ + for (i = 0; i <= n; ++i) ++colptr[i]; + for (i = 0; i < nnz; ++i) ++adjncy[i]; +#if ( DEBUGlevel>=2 ) + printf("LDPERM(): n %d, nnz %d\n", n, nnz); + slu_PrintInt10("colptr", n+1, colptr); + slu_PrintInt10("adjncy", nnz, adjncy); +#endif + + /* + * NOTE: + * ===== + * + * MC64AD assumes that column permutation vector is defined as: + * perm(i) = j means column i of permuted A is in column j of original A. + * + * Since a symmetric permutation preserves the diagonal entries. Then + * by the following relation: + * P'(A*P')P = P'A + * we can apply inverse(perm) to rows of A to get large diagonal entries. + * But, since 'perm' defined in MC64AD happens to be the reverse of + * SuperLU's definition of permutation vector, therefore, it is already + * an inverse for our purpose. We will thus use it directly. + * + */ + mc64id_(icntl); +#if 0 + /* Suppress error and warning messages. */ + icntl[0] = -1; + icntl[1] = -1; +#endif + + for (i = 0; i < nnz; ++i) nzval_d[i] = c_abs1(&nzval[i]); + mc64ad_(&job, &n, &nnz, colptr, adjncy, nzval_d, &num, perm, + &liw, iw, &ldw, dw, icntl, info); + +#if ( DEBUGlevel>=2 ) + slu_PrintInt10("perm", n, perm); + printf(".. After MC64AD info %d\tsize of matching %d\n", info[0], num); +#endif + if ( info[0] == 1 ) { /* Structurally singular */ + printf(".. The last %d permutations:\n", n-num); + slu_PrintInt10("perm", n-num, &perm[num]); + } + + /* Restore to 0-based indexing. */ + for (i = 0; i <= n; ++i) --colptr[i]; + for (i = 0; i < nnz; ++i) --adjncy[i]; + for (i = 0; i < n; ++i) --perm[i]; + + if ( job == 5 ) + for (i = 0; i < n; ++i) { + u[i] = dw[i]; + v[i] = dw[n+i]; + } + + SUPERLU_FREE(iw); + SUPERLU_FREE(dw); + SUPERLU_FREE(nzval_d); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit cldperm()"); +#endif + + return info[0]; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/cmemory.c b/src/Libraries/superlu-5.2.1/SRC/cmemory.c new file mode 100644 index 00000000..b41aef21 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cmemory.c @@ -0,0 +1,710 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cmemory.c + * \brief Memory details + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ +#include "slu_cdefs.h" + + +/* Internal prototypes */ +void *cexpand (int *, MemType,int, int, GlobalLU_t *); +int cLUWorkInit (int, int, int, int **, complex **, GlobalLU_t *); +void copy_mem_complex (int, void *, void *); +void cStackCompress (GlobalLU_t *); +void cSetupSpace (void *, int, GlobalLU_t *); +void *cuser_malloc (int, int, GlobalLU_t *); +void cuser_free (int, int, GlobalLU_t *); + +/* External prototypes (in memory.c - prec-independent) */ +extern void copy_mem_int (int, void *, void *); +extern void user_bcopy (char *, char *, int); + + +/* Macros to manipulate stack */ +#define StackFull(x) ( x + Glu->stack.used >= Glu->stack.size ) +#define NotDoubleAlign(addr) ( (intptr_t)addr & 7 ) +#define DoubleAlign(addr) ( ((intptr_t)addr + 7) & ~7L ) +#define TempSpace(m, w) ( (2*w + 4 + NO_MARKER) * m * sizeof(int) + \ + (w + 1) * m * sizeof(complex) ) +#define Reduce(alpha) ((alpha + 1) / 2) /* i.e. (alpha-1)/2 + 1 */ + + + + +/*! \brief Setup the memory model to be used for factorization. + * + * lwork = 0: use system malloc; + * lwork > 0: use user-supplied work[] space. + */ +void cSetupSpace(void *work, int lwork, GlobalLU_t *Glu) +{ + if ( lwork == 0 ) { + Glu->MemModel = SYSTEM; /* malloc/free */ + } else if ( lwork > 0 ) { + Glu->MemModel = USER; /* user provided space */ + Glu->stack.used = 0; + Glu->stack.top1 = 0; + Glu->stack.top2 = (lwork/4)*4; /* must be word addressable */ + Glu->stack.size = Glu->stack.top2; + Glu->stack.array = (void *) work; + } +} + + + +void *cuser_malloc(int bytes, int which_end, GlobalLU_t *Glu) +{ + void *buf; + + if ( StackFull(bytes) ) return (NULL); + + if ( which_end == HEAD ) { + buf = (char*) Glu->stack.array + Glu->stack.top1; + Glu->stack.top1 += bytes; + } else { + Glu->stack.top2 -= bytes; + buf = (char*) Glu->stack.array + Glu->stack.top2; + } + + Glu->stack.used += bytes; + return buf; +} + + +void cuser_free(int bytes, int which_end, GlobalLU_t *Glu) +{ + if ( which_end == HEAD ) { + Glu->stack.top1 -= bytes; + } else { + Glu->stack.top2 += bytes; + } + Glu->stack.used -= bytes; +} + + + +/*! \brief + * + *
+ * mem_usage consists of the following fields:
+ *    - for_lu (float)
+ *      The amount of space used in bytes for the L\U data structures.
+ *    - total_needed (float)
+ *      The amount of space needed in bytes to perform factorization.
+ * 
+ */ +int cQuerySpace(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage) +{ + SCformat *Lstore; + NCformat *Ustore; + register int n, iword, dword, panel_size = sp_ienv(1); + + Lstore = L->Store; + Ustore = U->Store; + n = L->ncol; + iword = sizeof(int); + dword = sizeof(complex); + + /* For LU factors */ + mem_usage->for_lu = (float)( (4.0*n + 3.0) * iword + + Lstore->nzval_colptr[n] * dword + + Lstore->rowind_colptr[n] * iword ); + mem_usage->for_lu += (float)( (n + 1.0) * iword + + Ustore->colptr[n] * (dword + iword) ); + + /* Working storage to support factorization */ + mem_usage->total_needed = mem_usage->for_lu + + (float)( (2.0 * panel_size + 4.0 + NO_MARKER) * n * iword + + (panel_size + 1.0) * n * dword ); + + return 0; +} /* cQuerySpace */ + + +/*! \brief + * + *
+ * mem_usage consists of the following fields:
+ *    - for_lu (float)
+ *      The amount of space used in bytes for the L\U data structures.
+ *    - total_needed (float)
+ *      The amount of space needed in bytes to perform factorization.
+ * 
+ */ +int ilu_cQuerySpace(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage) +{ + SCformat *Lstore; + NCformat *Ustore; + register int n, panel_size = sp_ienv(1); + register float iword, dword; + + Lstore = L->Store; + Ustore = U->Store; + n = L->ncol; + iword = sizeof(int); + dword = sizeof(double); + + /* For LU factors */ + mem_usage->for_lu = (float)( (4.0f * n + 3.0f) * iword + + Lstore->nzval_colptr[n] * dword + + Lstore->rowind_colptr[n] * iword ); + mem_usage->for_lu += (float)( (n + 1.0f) * iword + + Ustore->colptr[n] * (dword + iword) ); + + /* Working storage to support factorization. + ILU needs 5*n more integers than LU */ + mem_usage->total_needed = mem_usage->for_lu + + (float)( (2.0f * panel_size + 9.0f + NO_MARKER) * n * iword + + (panel_size + 1.0f) * n * dword ); + + return 0; +} /* ilu_cQuerySpace */ + + +/*! \brief Allocate storage for the data structures common to all factor routines. + * + *
+ * For those unpredictable size, estimate as fill_ratio * nnz(A).
+ * Return value:
+ *     If lwork = -1, return the estimated amount of space required, plus n;
+ *     otherwise, return the amount of space actually allocated when
+ *     memory allocation failure occurred.
+ * 
+ */ +int +cLUMemInit(fact_t fact, void *work, int lwork, int m, int n, int annz, + int panel_size, float fill_ratio, SuperMatrix *L, SuperMatrix *U, + GlobalLU_t *Glu, int **iwork, complex **dwork) +{ + int info, iword, dword; + SCformat *Lstore; + NCformat *Ustore; + int *xsup, *supno; + int *lsub, *xlsub; + complex *lusup; + int *xlusup; + complex *ucol; + int *usub, *xusub; + int nzlmax, nzumax, nzlumax; + + iword = sizeof(int); + dword = sizeof(complex); + Glu->n = n; + Glu->num_expansions = 0; + + Glu->expanders = (ExpHeader *) SUPERLU_MALLOC( NO_MEMTYPE * + sizeof(ExpHeader) ); + if ( !Glu->expanders ) ABORT("SUPERLU_MALLOC fails for expanders"); + + if ( fact != SamePattern_SameRowPerm ) { + /* Guess for L\U factors */ + nzumax = nzlumax = fill_ratio * annz; + nzlmax = SUPERLU_MAX(1, fill_ratio/4.) * annz; + + if ( lwork == -1 ) { + return ( GluIntArray(n) * iword + TempSpace(m, panel_size) + + (nzlmax+nzumax)*iword + (nzlumax+nzumax)*dword + n ); + } else { + cSetupSpace(work, lwork, Glu); + } + +#if ( PRNTlevel >= 1 ) + printf("cLUMemInit() called: fill_ratio %.0f, nzlmax %ld, nzumax %ld\n", + fill_ratio, nzlmax, nzumax); + fflush(stdout); +#endif + + /* Integer pointers for L\U factors */ + if ( Glu->MemModel == SYSTEM ) { + xsup = intMalloc(n+1); + supno = intMalloc(n+1); + xlsub = intMalloc(n+1); + xlusup = intMalloc(n+1); + xusub = intMalloc(n+1); + } else { + xsup = (int *)cuser_malloc((n+1) * iword, HEAD, Glu); + supno = (int *)cuser_malloc((n+1) * iword, HEAD, Glu); + xlsub = (int *)cuser_malloc((n+1) * iword, HEAD, Glu); + xlusup = (int *)cuser_malloc((n+1) * iword, HEAD, Glu); + xusub = (int *)cuser_malloc((n+1) * iword, HEAD, Glu); + } + + lusup = (complex *) cexpand( &nzlumax, LUSUP, 0, 0, Glu ); + ucol = (complex *) cexpand( &nzumax, UCOL, 0, 0, Glu ); + lsub = (int *) cexpand( &nzlmax, LSUB, 0, 0, Glu ); + usub = (int *) cexpand( &nzumax, USUB, 0, 1, Glu ); + + while ( !lusup || !ucol || !lsub || !usub ) { + if ( Glu->MemModel == SYSTEM ) { + SUPERLU_FREE(lusup); + SUPERLU_FREE(ucol); + SUPERLU_FREE(lsub); + SUPERLU_FREE(usub); + } else { + cuser_free((nzlumax+nzumax)*dword+(nzlmax+nzumax)*iword, + HEAD, Glu); + } + nzlumax /= 2; + nzumax /= 2; + nzlmax /= 2; + if ( nzlumax < annz ) { + printf("Not enough memory to perform factorization.\n"); + return (cmemory_usage(nzlmax, nzumax, nzlumax, n) + n); + } +#if ( PRNTlevel >= 1) + printf("cLUMemInit() reduce size: nzlmax %ld, nzumax %ld\n", + nzlmax, nzumax); + fflush(stdout); +#endif + lusup = (complex *) cexpand( &nzlumax, LUSUP, 0, 0, Glu ); + ucol = (complex *) cexpand( &nzumax, UCOL, 0, 0, Glu ); + lsub = (int *) cexpand( &nzlmax, LSUB, 0, 0, Glu ); + usub = (int *) cexpand( &nzumax, USUB, 0, 1, Glu ); + } + + } else { + /* fact == SamePattern_SameRowPerm */ + Lstore = L->Store; + Ustore = U->Store; + xsup = Lstore->sup_to_col; + supno = Lstore->col_to_sup; + xlsub = Lstore->rowind_colptr; + xlusup = Lstore->nzval_colptr; + xusub = Ustore->colptr; + nzlmax = Glu->nzlmax; /* max from previous factorization */ + nzumax = Glu->nzumax; + nzlumax = Glu->nzlumax; + + if ( lwork == -1 ) { + return ( GluIntArray(n) * iword + TempSpace(m, panel_size) + + (nzlmax+nzumax)*iword + (nzlumax+nzumax)*dword + n ); + } else if ( lwork == 0 ) { + Glu->MemModel = SYSTEM; + } else { + Glu->MemModel = USER; + Glu->stack.top2 = (lwork/4)*4; /* must be word-addressable */ + Glu->stack.size = Glu->stack.top2; + } + + lsub = Glu->expanders[LSUB].mem = Lstore->rowind; + lusup = Glu->expanders[LUSUP].mem = Lstore->nzval; + usub = Glu->expanders[USUB].mem = Ustore->rowind; + ucol = Glu->expanders[UCOL].mem = Ustore->nzval;; + Glu->expanders[LSUB].size = nzlmax; + Glu->expanders[LUSUP].size = nzlumax; + Glu->expanders[USUB].size = nzumax; + Glu->expanders[UCOL].size = nzumax; + } + + Glu->xsup = xsup; + Glu->supno = supno; + Glu->lsub = lsub; + Glu->xlsub = xlsub; + Glu->lusup = (void *) lusup; + Glu->xlusup = xlusup; + Glu->ucol = (void *) ucol; + Glu->usub = usub; + Glu->xusub = xusub; + Glu->nzlmax = nzlmax; + Glu->nzumax = nzumax; + Glu->nzlumax = nzlumax; + + info = cLUWorkInit(m, n, panel_size, iwork, dwork, Glu); + if ( info ) + return ( info + cmemory_usage(nzlmax, nzumax, nzlumax, n) + n); + + ++Glu->num_expansions; + return 0; + +} /* cLUMemInit */ + +/*! \brief Allocate known working storage. Returns 0 if success, otherwise + returns the number of bytes allocated so far when failure occurred. */ +int +cLUWorkInit(int m, int n, int panel_size, int **iworkptr, + complex **dworkptr, GlobalLU_t *Glu) +{ + int isize, dsize, extra; + complex *old_ptr; + int maxsuper = SUPERLU_MAX( sp_ienv(3), sp_ienv(7) ), + rowblk = sp_ienv(4); + + isize = ( (2 * panel_size + 3 + NO_MARKER ) * m + n ) * sizeof(int); + dsize = (m * panel_size + + NUM_TEMPV(m,panel_size,maxsuper,rowblk)) * sizeof(complex); + + if ( Glu->MemModel == SYSTEM ) + *iworkptr = (int *) intCalloc(isize/sizeof(int)); + else + *iworkptr = (int *) cuser_malloc(isize, TAIL, Glu); + if ( ! *iworkptr ) { + fprintf(stderr, "cLUWorkInit: malloc fails for local iworkptr[]\n"); + return (isize + n); + } + + if ( Glu->MemModel == SYSTEM ) + *dworkptr = (complex *) SUPERLU_MALLOC(dsize); + else { + *dworkptr = (complex *) cuser_malloc(dsize, TAIL, Glu); + if ( NotDoubleAlign(*dworkptr) ) { + old_ptr = *dworkptr; + *dworkptr = (complex*) DoubleAlign(*dworkptr); + *dworkptr = (complex*) ((double*)*dworkptr - 1); + extra = (char*)old_ptr - (char*)*dworkptr; +#ifdef DEBUG + printf("cLUWorkInit: not aligned, extra %d\n", extra); +#endif + Glu->stack.top2 -= extra; + Glu->stack.used += extra; + } + } + if ( ! *dworkptr ) { + fprintf(stderr, "malloc fails for local dworkptr[]."); + return (isize + dsize + n); + } + + return 0; +} + + +/*! \brief Set up pointers for real working arrays. + */ +void +cSetRWork(int m, int panel_size, complex *dworkptr, + complex **dense, complex **tempv) +{ + complex zero = {0.0, 0.0}; + + int maxsuper = SUPERLU_MAX( sp_ienv(3), sp_ienv(7) ), + rowblk = sp_ienv(4); + *dense = dworkptr; + *tempv = *dense + panel_size*m; + cfill (*dense, m * panel_size, zero); + cfill (*tempv, NUM_TEMPV(m,panel_size,maxsuper,rowblk), zero); +} + +/*! \brief Free the working storage used by factor routines. + */ +void cLUWorkFree(int *iwork, complex *dwork, GlobalLU_t *Glu) +{ + if ( Glu->MemModel == SYSTEM ) { + SUPERLU_FREE (iwork); + SUPERLU_FREE (dwork); + } else { + Glu->stack.used -= (Glu->stack.size - Glu->stack.top2); + Glu->stack.top2 = Glu->stack.size; +/* cStackCompress(Glu); */ + } + + SUPERLU_FREE (Glu->expanders); + Glu->expanders = NULL; +} + +/*! \brief Expand the data structures for L and U during the factorization. + * + *
+ * Return value:   0 - successful return
+ *               > 0 - number of bytes allocated when run out of space
+ * 
+ */ +int +cLUMemXpand(int jcol, + int next, /* number of elements currently in the factors */ + MemType mem_type, /* which type of memory to expand */ + int *maxlen, /* modified - maximum length of a data structure */ + GlobalLU_t *Glu /* modified - global LU data structures */ + ) +{ + void *new_mem; + +#ifdef DEBUG + printf("cLUMemXpand(): jcol %d, next %d, maxlen %d, MemType %d\n", + jcol, next, *maxlen, mem_type); +#endif + + if (mem_type == USUB) + new_mem = cexpand(maxlen, mem_type, next, 1, Glu); + else + new_mem = cexpand(maxlen, mem_type, next, 0, Glu); + + if ( !new_mem ) { + int nzlmax = Glu->nzlmax; + int nzumax = Glu->nzumax; + int nzlumax = Glu->nzlumax; + fprintf(stderr, "Can't expand MemType %d: jcol %d\n", mem_type, jcol); + return (cmemory_usage(nzlmax, nzumax, nzlumax, Glu->n) + Glu->n); + } + + switch ( mem_type ) { + case LUSUP: + Glu->lusup = (void *) new_mem; + Glu->nzlumax = *maxlen; + break; + case UCOL: + Glu->ucol = (void *) new_mem; + Glu->nzumax = *maxlen; + break; + case LSUB: + Glu->lsub = (int *) new_mem; + Glu->nzlmax = *maxlen; + break; + case USUB: + Glu->usub = (int *) new_mem; + Glu->nzumax = *maxlen; + break; + } + + return 0; + +} + + + +void +copy_mem_complex(int howmany, void *old, void *new) +{ + register int i; + complex *dold = old; + complex *dnew = new; + for (i = 0; i < howmany; i++) dnew[i] = dold[i]; +} + +/*! \brief Expand the existing storage to accommodate more fill-ins. + */ +void +*cexpand ( + int *prev_len, /* length used from previous call */ + MemType type, /* which part of the memory to expand */ + int len_to_copy, /* size of the memory to be copied to new store */ + int keep_prev, /* = 1: use prev_len; + = 0: compute new_len to expand */ + GlobalLU_t *Glu /* modified - global LU data structures */ + ) +{ + float EXPAND = 1.5; + float alpha; + void *new_mem, *old_mem; + int new_len, tries, lword, extra, bytes_to_copy; + ExpHeader *expanders = Glu->expanders; /* Array of 4 types of memory */ + + alpha = EXPAND; + + if ( Glu->num_expansions == 0 || keep_prev ) { + /* First time allocate requested */ + new_len = *prev_len; + } else { + new_len = alpha * *prev_len; + } + + if ( type == LSUB || type == USUB ) lword = sizeof(int); + else lword = sizeof(complex); + + if ( Glu->MemModel == SYSTEM ) { + new_mem = (void *) SUPERLU_MALLOC((size_t)new_len * lword); + if ( Glu->num_expansions != 0 ) { + tries = 0; + if ( keep_prev ) { + if ( !new_mem ) return (NULL); + } else { + while ( !new_mem ) { + if ( ++tries > 10 ) return (NULL); + alpha = Reduce(alpha); + new_len = alpha * *prev_len; + new_mem = (void *) SUPERLU_MALLOC((size_t)new_len * lword); + } + } + if ( type == LSUB || type == USUB ) { + copy_mem_int(len_to_copy, expanders[type].mem, new_mem); + } else { + copy_mem_complex(len_to_copy, expanders[type].mem, new_mem); + } + SUPERLU_FREE (expanders[type].mem); + } + expanders[type].mem = (void *) new_mem; + + } else { /* MemModel == USER */ + if ( Glu->num_expansions == 0 ) { + new_mem = cuser_malloc(new_len * lword, HEAD, Glu); + if ( NotDoubleAlign(new_mem) && + (type == LUSUP || type == UCOL) ) { + old_mem = new_mem; + new_mem = (void *)DoubleAlign(new_mem); + extra = (char*)new_mem - (char*)old_mem; +#ifdef DEBUG + printf("expand(): not aligned, extra %d\n", extra); +#endif + Glu->stack.top1 += extra; + Glu->stack.used += extra; + } + expanders[type].mem = (void *) new_mem; + } else { + tries = 0; + extra = (new_len - *prev_len) * lword; + if ( keep_prev ) { + if ( StackFull(extra) ) return (NULL); + } else { + while ( StackFull(extra) ) { + if ( ++tries > 10 ) return (NULL); + alpha = Reduce(alpha); + new_len = alpha * *prev_len; + extra = (new_len - *prev_len) * lword; + } + } + + if ( type != USUB ) { + new_mem = (void*)((char*)expanders[type + 1].mem + extra); + bytes_to_copy = (char*)Glu->stack.array + Glu->stack.top1 + - (char*)expanders[type + 1].mem; + user_bcopy(expanders[type+1].mem, new_mem, bytes_to_copy); + + if ( type < USUB ) { + Glu->usub = expanders[USUB].mem = + (void*)((char*)expanders[USUB].mem + extra); + } + if ( type < LSUB ) { + Glu->lsub = expanders[LSUB].mem = + (void*)((char*)expanders[LSUB].mem + extra); + } + if ( type < UCOL ) { + Glu->ucol = expanders[UCOL].mem = + (void*)((char*)expanders[UCOL].mem + extra); + } + Glu->stack.top1 += extra; + Glu->stack.used += extra; + if ( type == UCOL ) { + Glu->stack.top1 += extra; /* Add same amount for USUB */ + Glu->stack.used += extra; + } + + } /* if ... */ + + } /* else ... */ + } + + expanders[type].size = new_len; + *prev_len = new_len; + if ( Glu->num_expansions ) ++Glu->num_expansions; + + return (void *) expanders[type].mem; + +} /* cexpand */ + + +/*! \brief Compress the work[] array to remove fragmentation. + */ +void +cStackCompress(GlobalLU_t *Glu) +{ + register int iword, dword, ndim; + char *last, *fragment; + int *ifrom, *ito; + complex *dfrom, *dto; + int *xlsub, *lsub, *xusub, *usub, *xlusup; + complex *ucol, *lusup; + + iword = sizeof(int); + dword = sizeof(complex); + ndim = Glu->n; + + xlsub = Glu->xlsub; + lsub = Glu->lsub; + xusub = Glu->xusub; + usub = Glu->usub; + xlusup = Glu->xlusup; + ucol = Glu->ucol; + lusup = Glu->lusup; + + dfrom = ucol; + dto = (complex *)((char*)lusup + xlusup[ndim] * dword); + copy_mem_complex(xusub[ndim], dfrom, dto); + ucol = dto; + + ifrom = lsub; + ito = (int *) ((char*)ucol + xusub[ndim] * iword); + copy_mem_int(xlsub[ndim], ifrom, ito); + lsub = ito; + + ifrom = usub; + ito = (int *) ((char*)lsub + xlsub[ndim] * iword); + copy_mem_int(xusub[ndim], ifrom, ito); + usub = ito; + + last = (char*)usub + xusub[ndim] * iword; + fragment = (char*) (((char*)Glu->stack.array + Glu->stack.top1) - last); + Glu->stack.used -= (long int) fragment; + Glu->stack.top1 -= (long int) fragment; + + Glu->ucol = ucol; + Glu->lsub = lsub; + Glu->usub = usub; + +#ifdef DEBUG + printf("cStackCompress: fragment %d\n", fragment); + /* for (last = 0; last < ndim; ++last) + print_lu_col("After compress:", last, 0);*/ +#endif + +} + +/*! \brief Allocate storage for original matrix A + */ +void +callocateA(int n, int nnz, complex **a, int **asub, int **xa) +{ + *a = (complex *) complexMalloc(nnz); + *asub = (int *) intMalloc(nnz); + *xa = (int *) intMalloc(n+1); +} + + +complex *complexMalloc(int n) +{ + complex *buf; + buf = (complex *) SUPERLU_MALLOC((size_t)n * sizeof(complex)); + if ( !buf ) { + ABORT("SUPERLU_MALLOC failed for buf in complexMalloc()\n"); + } + return (buf); +} + +complex *complexCalloc(int n) +{ + complex *buf; + register int i; + complex zero = {0.0, 0.0}; + buf = (complex *) SUPERLU_MALLOC((size_t)n * sizeof(complex)); + if ( !buf ) { + ABORT("SUPERLU_MALLOC failed for buf in complexCalloc()\n"); + } + for (i = 0; i < n; ++i) buf[i] = zero; + return (buf); +} + + +int cmemory_usage(const int nzlmax, const int nzumax, + const int nzlumax, const int n) +{ + register int iword, dword; + + iword = sizeof(int); + dword = sizeof(complex); + + return (10 * n * iword + + nzlmax * iword + nzumax * (iword + dword) + nzlumax * dword); + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/cmyblas2.c b/src/Libraries/superlu-5.2.1/SRC/cmyblas2.c new file mode 100644 index 00000000..094138b5 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cmyblas2.c @@ -0,0 +1,198 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cmyblas2.c + * \brief Level 2 Blas operations + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ * Purpose: + * Level 2 BLAS operations: solves and matvec, written in C. + * Note: + * This is only used when the system lacks an efficient BLAS library. + * + */ +/* + * File name: cmyblas2.c + */ +#include "slu_scomplex.h" + +/*! \brief Solves a dense UNIT lower triangular system + * + * The unit lower + * triangular matrix is stored in a 2D array M(1:nrow,1:ncol). + * The solution will be returned in the rhs vector. + */ +void clsolve ( int ldm, int ncol, complex *M, complex *rhs ) +{ + int k; + complex x0, x1, x2, x3, temp; + complex *M0; + complex *Mki0, *Mki1, *Mki2, *Mki3; + register int firstcol = 0; + + M0 = &M[0]; + + + while ( firstcol < ncol - 3 ) { /* Do 4 columns */ + Mki0 = M0 + 1; + Mki1 = Mki0 + ldm + 1; + Mki2 = Mki1 + ldm + 1; + Mki3 = Mki2 + ldm + 1; + + x0 = rhs[firstcol]; + cc_mult(&temp, &x0, Mki0); Mki0++; + c_sub(&x1, &rhs[firstcol+1], &temp); + cc_mult(&temp, &x0, Mki0); Mki0++; + c_sub(&x2, &rhs[firstcol+2], &temp); + cc_mult(&temp, &x1, Mki1); Mki1++; + c_sub(&x2, &x2, &temp); + cc_mult(&temp, &x0, Mki0); Mki0++; + c_sub(&x3, &rhs[firstcol+3], &temp); + cc_mult(&temp, &x1, Mki1); Mki1++; + c_sub(&x3, &x3, &temp); + cc_mult(&temp, &x2, Mki2); Mki2++; + c_sub(&x3, &x3, &temp); + + rhs[++firstcol] = x1; + rhs[++firstcol] = x2; + rhs[++firstcol] = x3; + ++firstcol; + + for (k = firstcol; k < ncol; k++) { + cc_mult(&temp, &x0, Mki0); Mki0++; + c_sub(&rhs[k], &rhs[k], &temp); + cc_mult(&temp, &x1, Mki1); Mki1++; + c_sub(&rhs[k], &rhs[k], &temp); + cc_mult(&temp, &x2, Mki2); Mki2++; + c_sub(&rhs[k], &rhs[k], &temp); + cc_mult(&temp, &x3, Mki3); Mki3++; + c_sub(&rhs[k], &rhs[k], &temp); + } + + M0 += 4 * ldm + 4; + } + + if ( firstcol < ncol - 1 ) { /* Do 2 columns */ + Mki0 = M0 + 1; + Mki1 = Mki0 + ldm + 1; + + x0 = rhs[firstcol]; + cc_mult(&temp, &x0, Mki0); Mki0++; + c_sub(&x1, &rhs[firstcol+1], &temp); + + rhs[++firstcol] = x1; + ++firstcol; + + for (k = firstcol; k < ncol; k++) { + cc_mult(&temp, &x0, Mki0); Mki0++; + c_sub(&rhs[k], &rhs[k], &temp); + cc_mult(&temp, &x1, Mki1); Mki1++; + c_sub(&rhs[k], &rhs[k], &temp); + } + } + +} + +/*! \brief Solves a dense upper triangular system. + * + * The upper triangular matrix is + * stored in a 2-dim array M(1:ldm,1:ncol). The solution will be returned + * in the rhs vector. + */ +void +cusolve ( ldm, ncol, M, rhs ) +int ldm; /* in */ +int ncol; /* in */ +complex *M; /* in */ +complex *rhs; /* modified */ +{ + complex xj, temp; + int jcol, j, irow; + + jcol = ncol - 1; + + for (j = 0; j < ncol; j++) { + + c_div(&xj, &rhs[jcol], &M[jcol + jcol*ldm]); /* M(jcol, jcol) */ + rhs[jcol] = xj; + + for (irow = 0; irow < jcol; irow++) { + cc_mult(&temp, &xj, &M[irow+jcol*ldm]); /* M(irow, jcol) */ + c_sub(&rhs[irow], &rhs[irow], &temp); + } + + jcol--; + + } +} + + +/*! \brief Performs a dense matrix-vector multiply: Mxvec = Mxvec + M * vec. + * + * The input matrix is M(1:nrow,1:ncol); The product is returned in Mxvec[]. + */ +void cmatvec ( ldm, nrow, ncol, M, vec, Mxvec ) +int ldm; /* in -- leading dimension of M */ +int nrow; /* in */ +int ncol; /* in */ +complex *M; /* in */ +complex *vec; /* in */ +complex *Mxvec; /* in/out */ +{ + complex vi0, vi1, vi2, vi3; + complex *M0, temp; + complex *Mki0, *Mki1, *Mki2, *Mki3; + register int firstcol = 0; + int k; + + M0 = &M[0]; + + while ( firstcol < ncol - 3 ) { /* Do 4 columns */ + Mki0 = M0; + Mki1 = Mki0 + ldm; + Mki2 = Mki1 + ldm; + Mki3 = Mki2 + ldm; + + vi0 = vec[firstcol++]; + vi1 = vec[firstcol++]; + vi2 = vec[firstcol++]; + vi3 = vec[firstcol++]; + for (k = 0; k < nrow; k++) { + cc_mult(&temp, &vi0, Mki0); Mki0++; + c_add(&Mxvec[k], &Mxvec[k], &temp); + cc_mult(&temp, &vi1, Mki1); Mki1++; + c_add(&Mxvec[k], &Mxvec[k], &temp); + cc_mult(&temp, &vi2, Mki2); Mki2++; + c_add(&Mxvec[k], &Mxvec[k], &temp); + cc_mult(&temp, &vi3, Mki3); Mki3++; + c_add(&Mxvec[k], &Mxvec[k], &temp); + } + + M0 += 4 * ldm; + } + + while ( firstcol < ncol ) { /* Do 1 column */ + Mki0 = M0; + vi0 = vec[firstcol++]; + for (k = 0; k < nrow; k++) { + cc_mult(&temp, &vi0, Mki0); Mki0++; + c_add(&Mxvec[k], &Mxvec[k], &temp); + } + M0 += ldm; + } + +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/colamd.c b/src/Libraries/superlu-5.2.1/SRC/colamd.c new file mode 100644 index 00000000..5500e684 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/colamd.c @@ -0,0 +1,3424 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file colamd.c + *\brief A sparse matrix column ordering algorithm + +
+    ========================================================================== 
+    === colamd/symamd - a sparse matrix column ordering algorithm ============ 
+    ========================================================================== 
+
+
+    colamd:  an approximate minimum degree column ordering algorithm,
+    	for LU factorization of symmetric or unsymmetric matrices,
+	QR factorization, least squares, interior point methods for
+	linear programming problems, and other related problems.
+
+    symamd:  an approximate minimum degree ordering algorithm for Cholesky
+    	factorization of symmetric matrices.
+
+    Purpose:
+
+	Colamd computes a permutation Q such that the Cholesky factorization of
+	(AQ)'(AQ) has less fill-in and requires fewer floating point operations
+	than A'A.  This also provides a good ordering for sparse partial
+	pivoting methods, P(AQ) = LU, where Q is computed prior to numerical
+	factorization, and P is computed during numerical factorization via
+	conventional partial pivoting with row interchanges.  Colamd is the
+	column ordering method used in SuperLU, part of the ScaLAPACK library.
+	It is also available as built-in function in MATLAB Version 6,
+	available from MathWorks, Inc. (http://www.mathworks.com).  This
+	routine can be used in place of colmmd in MATLAB.
+
+    	Symamd computes a permutation P of a symmetric matrix A such that the
+	Cholesky factorization of PAP' has less fill-in and requires fewer
+	floating point operations than A.  Symamd constructs a matrix M such
+	that M'M has the same nonzero pattern of A, and then orders the columns
+	of M using colmmd.  The column ordering of M is then returned as the
+	row and column ordering P of A. 
+
+    Authors:
+
+	The authors of the code itself are Stefan I. Larimore and Timothy A.
+	Davis (davis@cise.ufl.edu), University of Florida.  The algorithm was
+	developed in collaboration with John Gilbert, Xerox PARC, and Esmond
+	Ng, Oak Ridge National Laboratory.
+
+    Date:
+
+	September 8, 2003.  Version 2.3.
+
+    Acknowledgements:
+
+	This work was supported by the National Science Foundation, under
+	grants DMS-9504974 and DMS-9803599.
+
+    Copyright and License:
+
+	Copyright (c) 1998-2003 by the University of Florida.
+	All Rights Reserved.
+
+	THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+	EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+
+	Permission is hereby granted to use, copy, modify, and/or distribute
+	this program, provided that the Copyright, this License, and the
+	Availability of the original version is retained on all copies and made
+	accessible to the end-user of any code or package that includes COLAMD
+	or any modified version of COLAMD. 
+
+    Availability:
+
+	The colamd/symamd library is available at
+
+	    http://www.cise.ufl.edu/research/sparse/colamd/
+
+	This is the http://www.cise.ufl.edu/research/sparse/colamd/colamd.c
+	file.  It requires the colamd.h file.  It is required by the colamdmex.c
+	and symamdmex.c files, for the MATLAB interface to colamd and symamd.
+
+    See the ChangeLog file for changes since Version 1.0.
+
+    ========================================================================== 
+    === Description of user-callable routines ================================ 
+    ========================================================================== 
+
+
+    ----------------------------------------------------------------------------
+    colamd_recommended:
+    ----------------------------------------------------------------------------
+
+	C syntax:
+
+	    #include "colamd.h"
+	    int colamd_recommended (int nnz, int n_row, int n_col) ;
+
+	    or as a C macro
+
+	    #include "colamd.h"
+	    Alen = COLAMD_RECOMMENDED (int nnz, int n_row, int n_col) ;
+
+	Purpose:
+
+	    Returns recommended value of Alen for use by colamd.  Returns -1
+	    if any input argument is negative.  The use of this routine
+	    or macro is optional.  Note that the macro uses its arguments
+	    more than once, so be careful for side effects, if you pass
+	    expressions as arguments to COLAMD_RECOMMENDED.  Not needed for
+	    symamd, which dynamically allocates its own memory.
+
+	Arguments (all input arguments):
+
+	    int nnz ;		Number of nonzeros in the matrix A.  This must
+				be the same value as p [n_col] in the call to
+				colamd - otherwise you will get a wrong value
+				of the recommended memory to use.
+
+	    int n_row ;		Number of rows in the matrix A.
+
+	    int n_col ;		Number of columns in the matrix A.
+
+    ----------------------------------------------------------------------------
+    colamd_set_defaults:
+    ----------------------------------------------------------------------------
+
+	C syntax:
+
+	    #include "colamd.h"
+	    colamd_set_defaults (double knobs [COLAMD_KNOBS]) ;
+
+	Purpose:
+
+	    Sets the default parameters.  The use of this routine is optional.
+
+	Arguments:
+
+	    double knobs [COLAMD_KNOBS] ;	Output only.
+
+		Colamd: rows with more than (knobs [COLAMD_DENSE_ROW] * n_col)
+		entries are removed prior to ordering.  Columns with more than
+		(knobs [COLAMD_DENSE_COL] * n_row) entries are removed prior to
+		ordering, and placed last in the output column ordering. 
+
+		Symamd: uses only knobs [COLAMD_DENSE_ROW], which is knobs [0].
+		Rows and columns with more than (knobs [COLAMD_DENSE_ROW] * n)
+		entries are removed prior to ordering, and placed last in the
+		output ordering.
+
+		COLAMD_DENSE_ROW and COLAMD_DENSE_COL are defined as 0 and 1,
+		respectively, in colamd.h.  Default values of these two knobs
+		are both 0.5.  Currently, only knobs [0] and knobs [1] are
+		used, but future versions may use more knobs.  If so, they will
+		be properly set to their defaults by the future version of
+		colamd_set_defaults, so that the code that calls colamd will
+		not need to change, assuming that you either use
+		colamd_set_defaults, or pass a (double *) NULL pointer as the
+		knobs array to colamd or symamd.
+
+    ----------------------------------------------------------------------------
+    colamd:
+    ----------------------------------------------------------------------------
+
+	C syntax:
+
+	    #include "colamd.h"
+	    int colamd (int n_row, int n_col, int Alen, int *A, int *p,
+	    	double knobs [COLAMD_KNOBS], int stats [COLAMD_STATS]) ;
+
+	Purpose:
+
+	    Computes a column ordering (Q) of A such that P(AQ)=LU or
+	    (AQ)'AQ=LL' have less fill-in and require fewer floating point
+	    operations than factorizing the unpermuted matrix A or A'A,
+	    respectively.
+	    
+	Returns:
+
+	    TRUE (1) if successful, FALSE (0) otherwise.
+
+	Arguments:
+
+	    int n_row ;		Input argument.
+
+		Number of rows in the matrix A.
+		Restriction:  n_row >= 0.
+		Colamd returns FALSE if n_row is negative.
+
+	    int n_col ;		Input argument.
+
+		Number of columns in the matrix A.
+		Restriction:  n_col >= 0.
+		Colamd returns FALSE if n_col is negative.
+
+	    int Alen ;		Input argument.
+
+		Restriction (see note):
+		Alen >= 2*nnz + 6*(n_col+1) + 4*(n_row+1) + n_col
+		Colamd returns FALSE if these conditions are not met.
+
+		Note:  this restriction makes an modest assumption regarding
+		the size of the two typedef's structures in colamd.h.
+		We do, however, guarantee that
+
+			Alen >= colamd_recommended (nnz, n_row, n_col)
+		
+		or equivalently as a C preprocessor macro: 
+
+			Alen >= COLAMD_RECOMMENDED (nnz, n_row, n_col)
+
+		will be sufficient.
+
+	    int A [Alen] ;	Input argument, undefined on output.
+
+		A is an integer array of size Alen.  Alen must be at least as
+		large as the bare minimum value given above, but this is very
+		low, and can result in excessive run time.  For best
+		performance, we recommend that Alen be greater than or equal to
+		colamd_recommended (nnz, n_row, n_col), which adds
+		nnz/5 to the bare minimum value given above.
+
+		On input, the row indices of the entries in column c of the
+		matrix are held in A [(p [c]) ... (p [c+1]-1)].  The row indices
+		in a given column c need not be in ascending order, and
+		duplicate row indices may be be present.  However, colamd will
+		work a little faster if both of these conditions are met
+		(Colamd puts the matrix into this format, if it finds that the
+		the conditions are not met).
+
+		The matrix is 0-based.  That is, rows are in the range 0 to
+		n_row-1, and columns are in the range 0 to n_col-1.  Colamd
+		returns FALSE if any row index is out of range.
+
+		The contents of A are modified during ordering, and are
+		undefined on output.
+
+	    int p [n_col+1] ;	Both input and output argument.
+
+		p is an integer array of size n_col+1.  On input, it holds the
+		"pointers" for the column form of the matrix A.  Column c of
+		the matrix A is held in A [(p [c]) ... (p [c+1]-1)].  The first
+		entry, p [0], must be zero, and p [c] <= p [c+1] must hold
+		for all c in the range 0 to n_col-1.  The value p [n_col] is
+		thus the total number of entries in the pattern of the matrix A.
+		Colamd returns FALSE if these conditions are not met.
+
+		On output, if colamd returns TRUE, the array p holds the column
+		permutation (Q, for P(AQ)=LU or (AQ)'(AQ)=LL'), where p [0] is
+		the first column index in the new ordering, and p [n_col-1] is
+		the last.  That is, p [k] = j means that column j of A is the
+		kth pivot column, in AQ, where k is in the range 0 to n_col-1
+		(p [0] = j means that column j of A is the first column in AQ).
+
+		If colamd returns FALSE, then no permutation is returned, and
+		p is undefined on output.
+
+	    double knobs [COLAMD_KNOBS] ;	Input argument.
+
+		See colamd_set_defaults for a description.
+
+	    int stats [COLAMD_STATS] ;		Output argument.
+
+		Statistics on the ordering, and error status.
+		See colamd.h for related definitions.
+		Colamd returns FALSE if stats is not present.
+
+		stats [0]:  number of dense or empty rows ignored.
+
+		stats [1]:  number of dense or empty columns ignored (and
+				ordered last in the output permutation p)
+				Note that a row can become "empty" if it
+				contains only "dense" and/or "empty" columns,
+				and similarly a column can become "empty" if it
+				only contains "dense" and/or "empty" rows.
+
+		stats [2]:  number of garbage collections performed.
+				This can be excessively high if Alen is close
+				to the minimum required value.
+
+		stats [3]:  status code.  < 0 is an error code.
+			    > 1 is a warning or notice.
+
+			0	OK.  Each column of the input matrix contained
+				row indices in increasing order, with no
+				duplicates.
+
+			1	OK, but columns of input matrix were jumbled
+				(unsorted columns or duplicate entries).  Colamd
+				had to do some extra work to sort the matrix
+				first and remove duplicate entries, but it
+				still was able to return a valid permutation
+				(return value of colamd was TRUE).
+
+					stats [4]: highest numbered column that
+						is unsorted or has duplicate
+						entries.
+					stats [5]: last seen duplicate or
+						unsorted row index.
+					stats [6]: number of duplicate or
+						unsorted row indices.
+
+			-1	A is a null pointer
+
+			-2	p is a null pointer
+
+			-3 	n_row is negative
+
+					stats [4]: n_row
+
+			-4	n_col is negative
+
+					stats [4]: n_col
+
+			-5	number of nonzeros in matrix is negative
+
+					stats [4]: number of nonzeros, p [n_col]
+
+			-6	p [0] is nonzero
+
+					stats [4]: p [0]
+
+			-7	A is too small
+
+					stats [4]: required size
+					stats [5]: actual size (Alen)
+
+			-8	a column has a negative number of entries
+
+					stats [4]: column with < 0 entries
+					stats [5]: number of entries in col
+
+			-9	a row index is out of bounds
+
+					stats [4]: column with bad row index
+					stats [5]: bad row index
+					stats [6]: n_row, # of rows of matrx
+
+			-10	(unused; see symamd.c)
+
+			-999	(unused; see symamd.c)
+
+		Future versions may return more statistics in the stats array.
+
+	Example:
+	
+	    See http://www.cise.ufl.edu/research/sparse/colamd/example.c
+	    for a complete example.
+
+	    To order the columns of a 5-by-4 matrix with 11 nonzero entries in
+	    the following nonzero pattern
+
+	    	x 0 x 0
+		x 0 x x
+		0 x x 0
+		0 0 x x
+		x x 0 0
+
+	    with default knobs and no output statistics, do the following:
+
+		#include "colamd.h"
+		#define ALEN COLAMD_RECOMMENDED (11, 5, 4)
+		int A [ALEN] = {1, 2, 5, 3, 5, 1, 2, 3, 4, 2, 4} ;
+		int p [ ] = {0, 3, 5, 9, 11} ;
+		int stats [COLAMD_STATS] ;
+		colamd (5, 4, ALEN, A, p, (double *) NULL, stats) ;
+
+	    The permutation is returned in the array p, and A is destroyed.
+
+    ----------------------------------------------------------------------------
+    symamd:
+    ----------------------------------------------------------------------------
+
+	C syntax:
+
+	    #include "colamd.h"
+	    int symamd (int n, int *A, int *p, int *perm,
+	    	double knobs [COLAMD_KNOBS], int stats [COLAMD_STATS],
+		void (*allocate) (size_t, size_t), void (*release) (void *)) ;
+
+	Purpose:
+
+    	    The symamd routine computes an ordering P of a symmetric sparse
+	    matrix A such that the Cholesky factorization PAP' = LL' remains
+	    sparse.  It is based on a column ordering of a matrix M constructed
+	    so that the nonzero pattern of M'M is the same as A.  The matrix A
+	    is assumed to be symmetric; only the strictly lower triangular part
+	    is accessed.  You must pass your selected memory allocator (usually
+	    calloc/free or mxCalloc/mxFree) to symamd, for it to allocate
+	    memory for the temporary matrix M.
+
+	Returns:
+
+	    TRUE (1) if successful, FALSE (0) otherwise.
+
+	Arguments:
+
+	    int n ;		Input argument.
+
+	    	Number of rows and columns in the symmetrix matrix A.
+		Restriction:  n >= 0.
+		Symamd returns FALSE if n is negative.
+
+	    int A [nnz] ;	Input argument.
+
+	    	A is an integer array of size nnz, where nnz = p [n].
+		
+		The row indices of the entries in column c of the matrix are
+		held in A [(p [c]) ... (p [c+1]-1)].  The row indices in a
+		given column c need not be in ascending order, and duplicate
+		row indices may be present.  However, symamd will run faster
+		if the columns are in sorted order with no duplicate entries. 
+
+		The matrix is 0-based.  That is, rows are in the range 0 to
+		n-1, and columns are in the range 0 to n-1.  Symamd
+		returns FALSE if any row index is out of range.
+
+		The contents of A are not modified.
+
+	    int p [n+1] ;   	Input argument.
+
+		p is an integer array of size n+1.  On input, it holds the
+		"pointers" for the column form of the matrix A.  Column c of
+		the matrix A is held in A [(p [c]) ... (p [c+1]-1)].  The first
+		entry, p [0], must be zero, and p [c] <= p [c+1] must hold
+		for all c in the range 0 to n-1.  The value p [n] is
+		thus the total number of entries in the pattern of the matrix A.
+		Symamd returns FALSE if these conditions are not met.
+
+		The contents of p are not modified.
+
+	    int perm [n+1] ;   	Output argument.
+
+		On output, if symamd returns TRUE, the array perm holds the
+		permutation P, where perm [0] is the first index in the new
+		ordering, and perm [n-1] is the last.  That is, perm [k] = j
+		means that row and column j of A is the kth column in PAP',
+		where k is in the range 0 to n-1 (perm [0] = j means
+		that row and column j of A are the first row and column in
+		PAP').  The array is used as a workspace during the ordering,
+		which is why it must be of length n+1, not just n.
+
+	    double knobs [COLAMD_KNOBS] ;	Input argument.
+
+		See colamd_set_defaults for a description.
+
+	    int stats [COLAMD_STATS] ;		Output argument.
+
+		Statistics on the ordering, and error status.
+		See colamd.h for related definitions.
+		Symamd returns FALSE if stats is not present.
+
+		stats [0]:  number of dense or empty row and columns ignored
+				(and ordered last in the output permutation 
+				perm).  Note that a row/column can become
+				"empty" if it contains only "dense" and/or
+				"empty" columns/rows.
+
+		stats [1]:  (same as stats [0])
+
+		stats [2]:  number of garbage collections performed.
+
+		stats [3]:  status code.  < 0 is an error code.
+			    > 1 is a warning or notice.
+
+			0	OK.  Each column of the input matrix contained
+				row indices in increasing order, with no
+				duplicates.
+
+			1	OK, but columns of input matrix were jumbled
+				(unsorted columns or duplicate entries).  Symamd
+				had to do some extra work to sort the matrix
+				first and remove duplicate entries, but it
+				still was able to return a valid permutation
+				(return value of symamd was TRUE).
+
+					stats [4]: highest numbered column that
+						is unsorted or has duplicate
+						entries.
+					stats [5]: last seen duplicate or
+						unsorted row index.
+					stats [6]: number of duplicate or
+						unsorted row indices.
+
+			-1	A is a null pointer
+
+			-2	p is a null pointer
+
+			-3	(unused, see colamd.c)
+
+			-4 	n is negative
+
+					stats [4]: n
+
+			-5	number of nonzeros in matrix is negative
+
+					stats [4]: # of nonzeros (p [n]).
+
+			-6	p [0] is nonzero
+
+					stats [4]: p [0]
+
+			-7	(unused)
+
+			-8	a column has a negative number of entries
+
+					stats [4]: column with < 0 entries
+					stats [5]: number of entries in col
+
+			-9	a row index is out of bounds
+
+					stats [4]: column with bad row index
+					stats [5]: bad row index
+					stats [6]: n_row, # of rows of matrx
+
+			-10	out of memory (unable to allocate temporary
+				workspace for M or count arrays using the
+				"allocate" routine passed into symamd).
+
+			-999	internal error.  colamd failed to order the
+				matrix M, when it should have succeeded.  This
+				indicates a bug.  If this (and *only* this)
+				error code occurs, please contact the authors.
+				Don't contact the authors if you get any other
+				error code.
+
+		Future versions may return more statistics in the stats array.
+
+	    void * (*allocate) (size_t, size_t)
+
+	    	A pointer to a function providing memory allocation.  The
+		allocated memory must be returned initialized to zero.  For a
+		C application, this argument should normally be a pointer to
+		calloc.  For a MATLAB mexFunction, the routine mxCalloc is
+		passed instead.
+
+	    void (*release) (size_t, size_t)
+
+	    	A pointer to a function that frees memory allocated by the
+		memory allocation routine above.  For a C application, this
+		argument should normally be a pointer to free.  For a MATLAB
+		mexFunction, the routine mxFree is passed instead.
+
+
+    ----------------------------------------------------------------------------
+    colamd_report:
+    ----------------------------------------------------------------------------
+
+	C syntax:
+
+	    #include "colamd.h"
+	    colamd_report (int stats [COLAMD_STATS]) ;
+
+	Purpose:
+
+	    Prints the error status and statistics recorded in the stats
+	    array on the standard error output (for a standard C routine)
+	    or on the MATLAB output (for a mexFunction).
+
+	Arguments:
+
+	    int stats [COLAMD_STATS] ;	Input only.  Statistics from colamd.
+
+
+    ----------------------------------------------------------------------------
+    symamd_report:
+    ----------------------------------------------------------------------------
+
+	C syntax:
+
+	    #include "colamd.h"
+	    symamd_report (int stats [COLAMD_STATS]) ;
+
+	Purpose:
+
+	    Prints the error status and statistics recorded in the stats
+	    array on the standard error output (for a standard C routine)
+	    or on the MATLAB output (for a mexFunction).
+
+	Arguments:
+
+	    int stats [COLAMD_STATS] ;	Input only.  Statistics from symamd.
+
+ 
+*/ + +/* ========================================================================== */ +/* === Scaffolding code definitions ======================================== */ +/* ========================================================================== */ + +/* Ensure that debugging is turned off: */ +#ifndef NDEBUG +#define NDEBUG +#endif /* NDEBUG */ + +/* + Our "scaffolding code" philosophy: In our opinion, well-written library + code should keep its "debugging" code, and just normally have it turned off + by the compiler so as not to interfere with performance. This serves + several purposes: + + (1) assertions act as comments to the reader, telling you what the code + expects at that point. All assertions will always be true (unless + there really is a bug, of course). + + (2) leaving in the scaffolding code assists anyone who would like to modify + the code, or understand the algorithm (by reading the debugging output, + one can get a glimpse into what the code is doing). + + (3) (gasp!) for actually finding bugs. This code has been heavily tested + and "should" be fully functional and bug-free ... but you never know... + + To enable debugging, comment out the "#define NDEBUG" above. For a MATLAB + mexFunction, you will also need to modify mexopts.sh to remove the -DNDEBUG + definition. The code will become outrageously slow when debugging is + enabled. To control the level of debugging output, set an environment + variable D to 0 (little), 1 (some), 2, 3, or 4 (lots). When debugging, + you should see the following message on the standard output: + + colamd: debug version, D = 1 (THIS WILL BE SLOW!) + + or a similar message for symamd. If you don't, then debugging has not + been enabled. + +*/ + +/* ========================================================================== */ +/* === Include files ======================================================== */ +/* ========================================================================== */ + +#include "colamd.h" +#include + +#ifdef MATLAB_MEX_FILE +#include "mex.h" +#include "matrix.h" +#else +#include +#include +#endif /* MATLAB_MEX_FILE */ + +/* ========================================================================== */ +/* === Definitions ========================================================== */ +/* ========================================================================== */ + +/* Routines are either PUBLIC (user-callable) or PRIVATE (not user-callable) */ +#define PUBLIC +#define PRIVATE static + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +#define ONES_COMPLEMENT(r) (-(r)-1) + +/* -------------------------------------------------------------------------- */ +/* Change for version 2.1: define TRUE and FALSE only if not yet defined */ +/* -------------------------------------------------------------------------- */ + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +/* -------------------------------------------------------------------------- */ + +#define EMPTY (-1) + +/* Row and column status */ +#define ALIVE (0) +#define DEAD (-1) + +/* Column status */ +#define DEAD_PRINCIPAL (-1) +#define DEAD_NON_PRINCIPAL (-2) + +/* Macros for row and column status update and checking. */ +#define ROW_IS_DEAD(r) ROW_IS_MARKED_DEAD (Row[r].shared2.mark) +#define ROW_IS_MARKED_DEAD(row_mark) (row_mark < ALIVE) +#define ROW_IS_ALIVE(r) (Row [r].shared2.mark >= ALIVE) +#define COL_IS_DEAD(c) (Col [c].start < ALIVE) +#define COL_IS_ALIVE(c) (Col [c].start >= ALIVE) +#define COL_IS_DEAD_PRINCIPAL(c) (Col [c].start == DEAD_PRINCIPAL) +#define KILL_ROW(r) { Row [r].shared2.mark = DEAD ; } +#define KILL_PRINCIPAL_COL(c) { Col [c].start = DEAD_PRINCIPAL ; } +#define KILL_NON_PRINCIPAL_COL(c) { Col [c].start = DEAD_NON_PRINCIPAL ; } + +/* ========================================================================== */ +/* === Colamd reporting mechanism =========================================== */ +/* ========================================================================== */ + +#ifdef MATLAB_MEX_FILE + +/* use mexPrintf in a MATLAB mexFunction, for debugging and statistics output */ +#define PRINTF mexPrintf + +/* In MATLAB, matrices are 1-based to the user, but 0-based internally */ +#define INDEX(i) ((i)+1) + +#else + +/* Use printf in standard C environment, for debugging and statistics output. */ +/* Output is generated only if debugging is enabled at compile time, or if */ +/* the caller explicitly calls colamd_report or symamd_report. */ +#define PRINTF printf + +/* In C, matrices are 0-based and indices are reported as such in *_report */ +#define INDEX(i) (i) + +#endif /* MATLAB_MEX_FILE */ + +/* ========================================================================== */ +/* === Prototypes of PRIVATE routines ======================================= */ +/* ========================================================================== */ + +PRIVATE int init_rows_cols +( + int n_row, + int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + int A [], + int p [], + int stats [COLAMD_STATS] +) ; + +PRIVATE void init_scoring +( + int n_row, + int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + int A [], + int head [], + double knobs [COLAMD_KNOBS], + int *p_n_row2, + int *p_n_col2, + int *p_max_deg +) ; + +PRIVATE int find_ordering +( + int n_row, + int n_col, + int Alen, + Colamd_Row Row [], + Colamd_Col Col [], + int A [], + int head [], + int n_col2, + int max_deg, + int pfree +) ; + +PRIVATE void order_children +( + int n_col, + Colamd_Col Col [], + int p [] +) ; + +PRIVATE void detect_super_cols +( + +#ifndef NDEBUG + int n_col, + Colamd_Row Row [], +#endif /* NDEBUG */ + + Colamd_Col Col [], + int A [], + int head [], + int row_start, + int row_length +) ; + +PRIVATE int garbage_collection +( + int n_row, + int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + int A [], + int *pfree +) ; + +PRIVATE int clear_mark +( + int n_row, + Colamd_Row Row [] +) ; + +PRIVATE void print_report +( + char *method, + int stats [COLAMD_STATS] +) ; + +/* ========================================================================== */ +/* === Debugging prototypes and definitions ================================= */ +/* ========================================================================== */ + +#ifndef NDEBUG + +/* colamd_debug is the *ONLY* global variable, and is only */ +/* present when debugging */ + +PRIVATE int colamd_debug ; /* debug print level */ + +#define DEBUG0(params) { (void) PRINTF params ; } +#define DEBUG1(params) { if (colamd_debug >= 1) (void) PRINTF params ; } +#define DEBUG2(params) { if (colamd_debug >= 2) (void) PRINTF params ; } +#define DEBUG3(params) { if (colamd_debug >= 3) (void) PRINTF params ; } +#define DEBUG4(params) { if (colamd_debug >= 4) (void) PRINTF params ; } + +#ifdef MATLAB_MEX_FILE +#define ASSERT(expression) (mxAssert ((expression), "")) +#else +#define ASSERT(expression) (assert (expression)) +#endif /* MATLAB_MEX_FILE */ + +PRIVATE void colamd_get_debug /* gets the debug print level from getenv */ +( + char *method +) ; + +PRIVATE void debug_deg_lists +( + int n_row, + int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + int head [], + int min_score, + int should, + int max_deg +) ; + +PRIVATE void debug_mark +( + int n_row, + Colamd_Row Row [], + int tag_mark, + int max_mark +) ; + +PRIVATE void debug_matrix +( + int n_row, + int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + int A [] +) ; + +PRIVATE void debug_structures +( + int n_row, + int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + int A [], + int n_col2 +) ; + +#else /* NDEBUG */ + +/* === No debugging ========================================================= */ + +#define DEBUG0(params) ; +#define DEBUG1(params) ; +#define DEBUG2(params) ; +#define DEBUG3(params) ; +#define DEBUG4(params) ; + +#define ASSERT(expression) ((void) 0) + +#endif /* NDEBUG */ + +/* ========================================================================== */ + + + +/* ========================================================================== */ +/* === USER-CALLABLE ROUTINES: ============================================== */ +/* ========================================================================== */ + + +/* ========================================================================== */ +/* === colamd_recommended =================================================== */ +/* ========================================================================== */ + +/* + The colamd_recommended routine returns the suggested size for Alen. This + value has been determined to provide good balance between the number of + garbage collections and the memory requirements for colamd. If any + argument is negative, a -1 is returned as an error condition. This + function is also available as a macro defined in colamd.h, so that you + can use it for a statically-allocated array size. +*/ + +PUBLIC int colamd_recommended /* returns recommended value of Alen. */ +( + /* === Parameters ======================================================= */ + + int nnz, /* number of nonzeros in A */ + int n_row, /* number of rows in A */ + int n_col /* number of columns in A */ +) +{ + return (COLAMD_RECOMMENDED (nnz, n_row, n_col)) ; +} + + +/* ========================================================================== */ +/* === colamd_set_defaults ================================================== */ +/* ========================================================================== */ + +/* + The colamd_set_defaults routine sets the default values of the user- + controllable parameters for colamd: + + knobs [0] rows with knobs[0]*n_col entries or more are removed + prior to ordering in colamd. Rows and columns with + knobs[0]*n_col entries or more are removed prior to + ordering in symamd and placed last in the output + ordering. + + knobs [1] columns with knobs[1]*n_row entries or more are removed + prior to ordering in colamd, and placed last in the + column permutation. Symamd ignores this knob. + + knobs [2..19] unused, but future versions might use this +*/ + +PUBLIC void colamd_set_defaults +( + /* === Parameters ======================================================= */ + + double knobs [COLAMD_KNOBS] /* knob array */ +) +{ + /* === Local variables ================================================== */ + + int i ; + + if (!knobs) + { + return ; /* no knobs to initialize */ + } + for (i = 0 ; i < COLAMD_KNOBS ; i++) + { + knobs [i] = 0 ; + } + knobs [COLAMD_DENSE_ROW] = 0.5 ; /* ignore rows over 50% dense */ + knobs [COLAMD_DENSE_COL] = 0.5 ; /* ignore columns over 50% dense */ +} + + +/* ========================================================================== */ +/* === symamd =============================================================== */ +/* ========================================================================== */ + +PUBLIC int symamd /* return TRUE if OK, FALSE otherwise */ +( + /* === Parameters ======================================================= */ + + int n, /* number of rows and columns of A */ + int A [], /* row indices of A */ + int p [], /* column pointers of A */ + int perm [], /* output permutation, size n+1 */ + double knobs [COLAMD_KNOBS], /* parameters (uses defaults if NULL) */ + int stats [COLAMD_STATS], /* output statistics and error codes */ + void * (*allocate) (size_t, size_t), + /* pointer to calloc (ANSI C) or */ + /* mxCalloc (for MATLAB mexFunction) */ + void (*release) (void *) + /* pointer to free (ANSI C) or */ + /* mxFree (for MATLAB mexFunction) */ +) +{ + /* === Local variables ================================================== */ + + int *count ; /* length of each column of M, and col pointer*/ + int *mark ; /* mark array for finding duplicate entries */ + int *M ; /* row indices of matrix M */ + int Mlen ; /* length of M */ + int n_row ; /* number of rows in M */ + int nnz ; /* number of entries in A */ + int i ; /* row index of A */ + int j ; /* column index of A */ + int k ; /* row index of M */ + int mnz ; /* number of nonzeros in M */ + int pp ; /* index into a column of A */ + int last_row ; /* last row seen in the current column */ + int length ; /* number of nonzeros in a column */ + + double cknobs [COLAMD_KNOBS] ; /* knobs for colamd */ + double default_knobs [COLAMD_KNOBS] ; /* default knobs for colamd */ + int cstats [COLAMD_STATS] ; /* colamd stats */ + +#ifndef NDEBUG + colamd_get_debug ("symamd") ; +#endif /* NDEBUG */ + + /* === Check the input arguments ======================================== */ + + if (!stats) + { + DEBUG0 (("symamd: stats not present\n")) ; + return (FALSE) ; + } + for (i = 0 ; i < COLAMD_STATS ; i++) + { + stats [i] = 0 ; + } + stats [COLAMD_STATUS] = COLAMD_OK ; + stats [COLAMD_INFO1] = -1 ; + stats [COLAMD_INFO2] = -1 ; + + if (!A) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_A_not_present ; + DEBUG0 (("symamd: A not present\n")) ; + return (FALSE) ; + } + + if (!p) /* p is not present */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_p_not_present ; + DEBUG0 (("symamd: p not present\n")) ; + return (FALSE) ; + } + + if (n < 0) /* n must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_ncol_negative ; + stats [COLAMD_INFO1] = n ; + DEBUG0 (("symamd: n negative %d\n", n)) ; + return (FALSE) ; + } + + nnz = p [n] ; + if (nnz < 0) /* nnz must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_nnz_negative ; + stats [COLAMD_INFO1] = nnz ; + DEBUG0 (("symamd: number of entries negative %d\n", nnz)) ; + return (FALSE) ; + } + + if (p [0] != 0) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_p0_nonzero ; + stats [COLAMD_INFO1] = p [0] ; + DEBUG0 (("symamd: p[0] not zero %d\n", p [0])) ; + return (FALSE) ; + } + + /* === If no knobs, set default knobs =================================== */ + + if (!knobs) + { + colamd_set_defaults (default_knobs) ; + knobs = default_knobs ; + } + + /* === Allocate count and mark ========================================== */ + + count = (int *) ((*allocate) (n+1, sizeof (int))) ; + if (!count) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; + DEBUG0 (("symamd: allocate count (size %d) failed\n", n+1)) ; + return (FALSE) ; + } + + mark = (int *) ((*allocate) (n+1, sizeof (int))) ; + if (!mark) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; + (*release) ((void *) count) ; + DEBUG0 (("symamd: allocate mark (size %d) failed\n", n+1)) ; + return (FALSE) ; + } + + /* === Compute column counts of M, check if A is valid ================== */ + + stats [COLAMD_INFO3] = 0 ; /* number of duplicate or unsorted row indices*/ + + for (i = 0 ; i < n ; i++) + { + mark [i] = -1 ; + } + + for (j = 0 ; j < n ; j++) + { + last_row = -1 ; + + length = p [j+1] - p [j] ; + if (length < 0) + { + /* column pointers must be non-decreasing */ + stats [COLAMD_STATUS] = COLAMD_ERROR_col_length_negative ; + stats [COLAMD_INFO1] = j ; + stats [COLAMD_INFO2] = length ; + (*release) ((void *) count) ; + (*release) ((void *) mark) ; + DEBUG0 (("symamd: col %d negative length %d\n", j, length)) ; + return (FALSE) ; + } + + for (pp = p [j] ; pp < p [j+1] ; pp++) + { + i = A [pp] ; + if (i < 0 || i >= n) + { + /* row index i, in column j, is out of bounds */ + stats [COLAMD_STATUS] = COLAMD_ERROR_row_index_out_of_bounds ; + stats [COLAMD_INFO1] = j ; + stats [COLAMD_INFO2] = i ; + stats [COLAMD_INFO3] = n ; + (*release) ((void *) count) ; + (*release) ((void *) mark) ; + DEBUG0 (("symamd: row %d col %d out of bounds\n", i, j)) ; + return (FALSE) ; + } + + if (i <= last_row || mark [i] == j) + { + /* row index is unsorted or repeated (or both), thus col */ + /* is jumbled. This is a notice, not an error condition. */ + stats [COLAMD_STATUS] = COLAMD_OK_BUT_JUMBLED ; + stats [COLAMD_INFO1] = j ; + stats [COLAMD_INFO2] = i ; + (stats [COLAMD_INFO3]) ++ ; + DEBUG1 (("symamd: row %d col %d unsorted/duplicate\n", i, j)) ; + } + + if (i > j && mark [i] != j) + { + /* row k of M will contain column indices i and j */ + count [i]++ ; + count [j]++ ; + } + + /* mark the row as having been seen in this column */ + mark [i] = j ; + + last_row = i ; + } + } + + if (stats [COLAMD_STATUS] == COLAMD_OK) + { + /* if there are no duplicate entries, then mark is no longer needed */ + (*release) ((void *) mark) ; + } + + /* === Compute column pointers of M ===================================== */ + + /* use output permutation, perm, for column pointers of M */ + perm [0] = 0 ; + for (j = 1 ; j <= n ; j++) + { + perm [j] = perm [j-1] + count [j-1] ; + } + for (j = 0 ; j < n ; j++) + { + count [j] = perm [j] ; + } + + /* === Construct M ====================================================== */ + + mnz = perm [n] ; + n_row = mnz / 2 ; + Mlen = colamd_recommended (mnz, n_row, n) ; + M = (int *) ((*allocate) (Mlen, sizeof (int))) ; + DEBUG0 (("symamd: M is %d-by-%d with %d entries, Mlen = %d\n", + n_row, n, mnz, Mlen)) ; + + if (!M) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; + (*release) ((void *) count) ; + (*release) ((void *) mark) ; + DEBUG0 (("symamd: allocate M (size %d) failed\n", Mlen)) ; + return (FALSE) ; + } + + k = 0 ; + + if (stats [COLAMD_STATUS] == COLAMD_OK) + { + /* Matrix is OK */ + for (j = 0 ; j < n ; j++) + { + ASSERT (p [j+1] - p [j] >= 0) ; + for (pp = p [j] ; pp < p [j+1] ; pp++) + { + i = A [pp] ; + ASSERT (i >= 0 && i < n) ; + if (i > j) + { + /* row k of M contains column indices i and j */ + M [count [i]++] = k ; + M [count [j]++] = k ; + k++ ; + } + } + } + } + else + { + /* Matrix is jumbled. Do not add duplicates to M. Unsorted cols OK. */ + DEBUG0 (("symamd: Duplicates in A.\n")) ; + for (i = 0 ; i < n ; i++) + { + mark [i] = -1 ; + } + for (j = 0 ; j < n ; j++) + { + ASSERT (p [j+1] - p [j] >= 0) ; + for (pp = p [j] ; pp < p [j+1] ; pp++) + { + i = A [pp] ; + ASSERT (i >= 0 && i < n) ; + if (i > j && mark [i] != j) + { + /* row k of M contains column indices i and j */ + M [count [i]++] = k ; + M [count [j]++] = k ; + k++ ; + mark [i] = j ; + } + } + } + (*release) ((void *) mark) ; + } + + /* count and mark no longer needed */ + (*release) ((void *) count) ; + ASSERT (k == n_row) ; + + /* === Adjust the knobs for M =========================================== */ + + for (i = 0 ; i < COLAMD_KNOBS ; i++) + { + cknobs [i] = knobs [i] ; + } + + /* there are no dense rows in M */ + cknobs [COLAMD_DENSE_ROW] = 1.0 ; + + if (n_row != 0 && n < n_row) + { + /* On input, the knob is a fraction of 1..n, the number of rows of A. */ + /* Convert it to a fraction of 1..n_row, of the number of rows of M. */ + cknobs [COLAMD_DENSE_COL] = (knobs [COLAMD_DENSE_ROW] * n) / n_row ; + } + else + { + /* no dense columns in M */ + cknobs [COLAMD_DENSE_COL] = 1.0 ; + } + + DEBUG0 (("symamd: dense col knob for M: %g\n", cknobs [COLAMD_DENSE_COL])) ; + + /* === Order the columns of M =========================================== */ + + if (!colamd (n_row, n, Mlen, M, perm, cknobs, cstats)) + { + /* This "cannot" happen, unless there is a bug in the code. */ + stats [COLAMD_STATUS] = COLAMD_ERROR_internal_error ; + (*release) ((void *) M) ; + DEBUG0 (("symamd: internal error!\n")) ; + return (FALSE) ; + } + + /* Note that the output permutation is now in perm */ + + /* === get the statistics for symamd from colamd ======================== */ + + /* note that a dense column in colamd means a dense row and col in symamd */ + stats [COLAMD_DENSE_ROW] = cstats [COLAMD_DENSE_COL] ; + stats [COLAMD_DENSE_COL] = cstats [COLAMD_DENSE_COL] ; + stats [COLAMD_DEFRAG_COUNT] = cstats [COLAMD_DEFRAG_COUNT] ; + + /* === Free M =========================================================== */ + + (*release) ((void *) M) ; + DEBUG0 (("symamd: done.\n")) ; + return (TRUE) ; + +} + +/* ========================================================================== */ +/* === colamd =============================================================== */ +/* ========================================================================== */ + +/* + The colamd routine computes a column ordering Q of a sparse matrix + A such that the LU factorization P(AQ) = LU remains sparse, where P is + selected via partial pivoting. The routine can also be viewed as + providing a permutation Q such that the Cholesky factorization + (AQ)'(AQ) = LL' remains sparse. +*/ + +PUBLIC int colamd /* returns TRUE if successful, FALSE otherwise*/ +( + /* === Parameters ======================================================= */ + + int n_row, /* number of rows in A */ + int n_col, /* number of columns in A */ + int Alen, /* length of A */ + int A [], /* row indices of A */ + int p [], /* pointers to columns in A */ + double knobs [COLAMD_KNOBS],/* parameters (uses defaults if NULL) */ + int stats [COLAMD_STATS] /* output statistics and error codes */ +) +{ + /* === Local variables ================================================== */ + + int i ; /* loop index */ + int nnz ; /* nonzeros in A */ + int Row_size ; /* size of Row [], in integers */ + int Col_size ; /* size of Col [], in integers */ + int need ; /* minimum required length of A */ + Colamd_Row *Row ; /* pointer into A of Row [0..n_row] array */ + Colamd_Col *Col ; /* pointer into A of Col [0..n_col] array */ + int n_col2 ; /* number of non-dense, non-empty columns */ + int n_row2 ; /* number of non-dense, non-empty rows */ + int ngarbage ; /* number of garbage collections performed */ + int max_deg ; /* maximum row degree */ + double default_knobs [COLAMD_KNOBS] ; /* default knobs array */ + +#ifndef NDEBUG + colamd_get_debug ("colamd") ; +#endif /* NDEBUG */ + + /* === Check the input arguments ======================================== */ + + if (!stats) + { + DEBUG0 (("colamd: stats not present\n")) ; + return (FALSE) ; + } + for (i = 0 ; i < COLAMD_STATS ; i++) + { + stats [i] = 0 ; + } + stats [COLAMD_STATUS] = COLAMD_OK ; + stats [COLAMD_INFO1] = -1 ; + stats [COLAMD_INFO2] = -1 ; + + if (!A) /* A is not present */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_A_not_present ; + DEBUG0 (("colamd: A not present\n")) ; + return (FALSE) ; + } + + if (!p) /* p is not present */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_p_not_present ; + DEBUG0 (("colamd: p not present\n")) ; + return (FALSE) ; + } + + if (n_row < 0) /* n_row must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_nrow_negative ; + stats [COLAMD_INFO1] = n_row ; + DEBUG0 (("colamd: nrow negative %d\n", n_row)) ; + return (FALSE) ; + } + + if (n_col < 0) /* n_col must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_ncol_negative ; + stats [COLAMD_INFO1] = n_col ; + DEBUG0 (("colamd: ncol negative %d\n", n_col)) ; + return (FALSE) ; + } + + nnz = p [n_col] ; + if (nnz < 0) /* nnz must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_nnz_negative ; + stats [COLAMD_INFO1] = nnz ; + DEBUG0 (("colamd: number of entries negative %d\n", nnz)) ; + return (FALSE) ; + } + + if (p [0] != 0) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_p0_nonzero ; + stats [COLAMD_INFO1] = p [0] ; + DEBUG0 (("colamd: p[0] not zero %d\n", p [0])) ; + return (FALSE) ; + } + + /* === If no knobs, set default knobs =================================== */ + + if (!knobs) + { + colamd_set_defaults (default_knobs) ; + knobs = default_knobs ; + } + + /* === Allocate the Row and Col arrays from array A ===================== */ + + Col_size = COLAMD_C (n_col) ; + Row_size = COLAMD_R (n_row) ; + need = 2*nnz + n_col + Col_size + Row_size ; + + if (need > Alen) + { + /* not enough space in array A to perform the ordering */ + stats [COLAMD_STATUS] = COLAMD_ERROR_A_too_small ; + stats [COLAMD_INFO1] = need ; + stats [COLAMD_INFO2] = Alen ; + DEBUG0 (("colamd: Need Alen >= %d, given only Alen = %d\n", need,Alen)); + return (FALSE) ; + } + + Alen -= Col_size + Row_size ; + Col = (Colamd_Col *) &A [Alen] ; + Row = (Colamd_Row *) &A [Alen + Col_size] ; + + /* === Construct the row and column data structures ===================== */ + + if (!init_rows_cols (n_row, n_col, Row, Col, A, p, stats)) + { + /* input matrix is invalid */ + DEBUG0 (("colamd: Matrix invalid\n")) ; + return (FALSE) ; + } + + /* === Initialize scores, kill dense rows/columns ======================= */ + + init_scoring (n_row, n_col, Row, Col, A, p, knobs, + &n_row2, &n_col2, &max_deg) ; + + /* === Order the supercolumns =========================================== */ + + ngarbage = find_ordering (n_row, n_col, Alen, Row, Col, A, p, + n_col2, max_deg, 2*nnz) ; + + /* === Order the non-principal columns ================================== */ + + order_children (n_col, Col, p) ; + + /* === Return statistics in stats ======================================= */ + + stats [COLAMD_DENSE_ROW] = n_row - n_row2 ; + stats [COLAMD_DENSE_COL] = n_col - n_col2 ; + stats [COLAMD_DEFRAG_COUNT] = ngarbage ; + DEBUG0 (("colamd: done.\n")) ; + return (TRUE) ; +} + + +/* ========================================================================== */ +/* === colamd_report ======================================================== */ +/* ========================================================================== */ + +PUBLIC void colamd_report +( + int stats [COLAMD_STATS] +) +{ + print_report ("colamd", stats) ; +} + + +/* ========================================================================== */ +/* === symamd_report ======================================================== */ +/* ========================================================================== */ + +PUBLIC void symamd_report +( + int stats [COLAMD_STATS] +) +{ + print_report ("symamd", stats) ; +} + + + +/* ========================================================================== */ +/* === NON-USER-CALLABLE ROUTINES: ========================================== */ +/* ========================================================================== */ + +/* There are no user-callable routines beyond this point in the file */ + + +/* ========================================================================== */ +/* === init_rows_cols ======================================================= */ +/* ========================================================================== */ + +/* + Takes the column form of the matrix in A and creates the row form of the + matrix. Also, row and column attributes are stored in the Col and Row + structs. If the columns are un-sorted or contain duplicate row indices, + this routine will also sort and remove duplicate row indices from the + column form of the matrix. Returns FALSE if the matrix is invalid, + TRUE otherwise. Not user-callable. +*/ + +PRIVATE int init_rows_cols /* returns TRUE if OK, or FALSE otherwise */ +( + /* === Parameters ======================================================= */ + + int n_row, /* number of rows of A */ + int n_col, /* number of columns of A */ + Colamd_Row Row [], /* of size n_row+1 */ + Colamd_Col Col [], /* of size n_col+1 */ + int A [], /* row indices of A, of size Alen */ + int p [], /* pointers to columns in A, of size n_col+1 */ + int stats [COLAMD_STATS] /* colamd statistics */ +) +{ + /* === Local variables ================================================== */ + + int col ; /* a column index */ + int row ; /* a row index */ + int *cp ; /* a column pointer */ + int *cp_end ; /* a pointer to the end of a column */ + int *rp ; /* a row pointer */ + int *rp_end ; /* a pointer to the end of a row */ + int last_row ; /* previous row */ + + /* === Initialize columns, and check column pointers ==================== */ + + for (col = 0 ; col < n_col ; col++) + { + Col [col].start = p [col] ; + Col [col].length = p [col+1] - p [col] ; + + if (Col [col].length < 0) + { + /* column pointers must be non-decreasing */ + stats [COLAMD_STATUS] = COLAMD_ERROR_col_length_negative ; + stats [COLAMD_INFO1] = col ; + stats [COLAMD_INFO2] = Col [col].length ; + DEBUG0 (("colamd: col %d length %d < 0\n", col, Col [col].length)) ; + return (FALSE) ; + } + + Col [col].shared1.thickness = 1 ; + Col [col].shared2.score = 0 ; + Col [col].shared3.prev = EMPTY ; + Col [col].shared4.degree_next = EMPTY ; + } + + /* p [0..n_col] no longer needed, used as "head" in subsequent routines */ + + /* === Scan columns, compute row degrees, and check row indices ========= */ + + stats [COLAMD_INFO3] = 0 ; /* number of duplicate or unsorted row indices*/ + + for (row = 0 ; row < n_row ; row++) + { + Row [row].length = 0 ; + Row [row].shared2.mark = -1 ; + } + + for (col = 0 ; col < n_col ; col++) + { + last_row = -1 ; + + cp = &A [p [col]] ; + cp_end = &A [p [col+1]] ; + + while (cp < cp_end) + { + row = *cp++ ; + + /* make sure row indices within range */ + if (row < 0 || row >= n_row) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_row_index_out_of_bounds ; + stats [COLAMD_INFO1] = col ; + stats [COLAMD_INFO2] = row ; + stats [COLAMD_INFO3] = n_row ; + DEBUG0 (("colamd: row %d col %d out of bounds\n", row, col)) ; + return (FALSE) ; + } + + if (row <= last_row || Row [row].shared2.mark == col) + { + /* row index are unsorted or repeated (or both), thus col */ + /* is jumbled. This is a notice, not an error condition. */ + stats [COLAMD_STATUS] = COLAMD_OK_BUT_JUMBLED ; + stats [COLAMD_INFO1] = col ; + stats [COLAMD_INFO2] = row ; + (stats [COLAMD_INFO3]) ++ ; + DEBUG1 (("colamd: row %d col %d unsorted/duplicate\n",row,col)); + } + + if (Row [row].shared2.mark != col) + { + Row [row].length++ ; + } + else + { + /* this is a repeated entry in the column, */ + /* it will be removed */ + Col [col].length-- ; + } + + /* mark the row as having been seen in this column */ + Row [row].shared2.mark = col ; + + last_row = row ; + } + } + + /* === Compute row pointers ============================================= */ + + /* row form of the matrix starts directly after the column */ + /* form of matrix in A */ + Row [0].start = p [n_col] ; + Row [0].shared1.p = Row [0].start ; + Row [0].shared2.mark = -1 ; + for (row = 1 ; row < n_row ; row++) + { + Row [row].start = Row [row-1].start + Row [row-1].length ; + Row [row].shared1.p = Row [row].start ; + Row [row].shared2.mark = -1 ; + } + + /* === Create row form ================================================== */ + + if (stats [COLAMD_STATUS] == COLAMD_OK_BUT_JUMBLED) + { + /* if cols jumbled, watch for repeated row indices */ + for (col = 0 ; col < n_col ; col++) + { + cp = &A [p [col]] ; + cp_end = &A [p [col+1]] ; + while (cp < cp_end) + { + row = *cp++ ; + if (Row [row].shared2.mark != col) + { + A [(Row [row].shared1.p)++] = col ; + Row [row].shared2.mark = col ; + } + } + } + } + else + { + /* if cols not jumbled, we don't need the mark (this is faster) */ + for (col = 0 ; col < n_col ; col++) + { + cp = &A [p [col]] ; + cp_end = &A [p [col+1]] ; + while (cp < cp_end) + { + A [(Row [*cp++].shared1.p)++] = col ; + } + } + } + + /* === Clear the row marks and set row degrees ========================== */ + + for (row = 0 ; row < n_row ; row++) + { + Row [row].shared2.mark = 0 ; + Row [row].shared1.degree = Row [row].length ; + } + + /* === See if we need to re-create columns ============================== */ + + if (stats [COLAMD_STATUS] == COLAMD_OK_BUT_JUMBLED) + { + DEBUG0 (("colamd: reconstructing column form, matrix jumbled\n")) ; + +#ifndef NDEBUG + /* make sure column lengths are correct */ + for (col = 0 ; col < n_col ; col++) + { + p [col] = Col [col].length ; + } + for (row = 0 ; row < n_row ; row++) + { + rp = &A [Row [row].start] ; + rp_end = rp + Row [row].length ; + while (rp < rp_end) + { + p [*rp++]-- ; + } + } + for (col = 0 ; col < n_col ; col++) + { + ASSERT (p [col] == 0) ; + } + /* now p is all zero (different than when debugging is turned off) */ +#endif /* NDEBUG */ + + /* === Compute col pointers ========================================= */ + + /* col form of the matrix starts at A [0]. */ + /* Note, we may have a gap between the col form and the row */ + /* form if there were duplicate entries, if so, it will be */ + /* removed upon the first garbage collection */ + Col [0].start = 0 ; + p [0] = Col [0].start ; + for (col = 1 ; col < n_col ; col++) + { + /* note that the lengths here are for pruned columns, i.e. */ + /* no duplicate row indices will exist for these columns */ + Col [col].start = Col [col-1].start + Col [col-1].length ; + p [col] = Col [col].start ; + } + + /* === Re-create col form =========================================== */ + + for (row = 0 ; row < n_row ; row++) + { + rp = &A [Row [row].start] ; + rp_end = rp + Row [row].length ; + while (rp < rp_end) + { + A [(p [*rp++])++] = row ; + } + } + } + + /* === Done. Matrix is not (or no longer) jumbled ====================== */ + + return (TRUE) ; +} + + +/* ========================================================================== */ +/* === init_scoring ========================================================= */ +/* ========================================================================== */ + +/* + Kills dense or empty columns and rows, calculates an initial score for + each column, and places all columns in the degree lists. Not user-callable. +*/ + +PRIVATE void init_scoring +( + /* === Parameters ======================================================= */ + + int n_row, /* number of rows of A */ + int n_col, /* number of columns of A */ + Colamd_Row Row [], /* of size n_row+1 */ + Colamd_Col Col [], /* of size n_col+1 */ + int A [], /* column form and row form of A */ + int head [], /* of size n_col+1 */ + double knobs [COLAMD_KNOBS],/* parameters */ + int *p_n_row2, /* number of non-dense, non-empty rows */ + int *p_n_col2, /* number of non-dense, non-empty columns */ + int *p_max_deg /* maximum row degree */ +) +{ + /* === Local variables ================================================== */ + + int c ; /* a column index */ + int r, row ; /* a row index */ + int *cp ; /* a column pointer */ + int deg ; /* degree of a row or column */ + int *cp_end ; /* a pointer to the end of a column */ + int *new_cp ; /* new column pointer */ + int col_length ; /* length of pruned column */ + int score ; /* current column score */ + int n_col2 ; /* number of non-dense, non-empty columns */ + int n_row2 ; /* number of non-dense, non-empty rows */ + int dense_row_count ; /* remove rows with more entries than this */ + int dense_col_count ; /* remove cols with more entries than this */ + int min_score ; /* smallest column score */ + int max_deg ; /* maximum row degree */ + int next_col ; /* Used to add to degree list.*/ + +#ifndef NDEBUG + int debug_count ; /* debug only. */ +#endif /* NDEBUG */ + + /* === Extract knobs ==================================================== */ + + dense_row_count = MAX (0, MIN (knobs [COLAMD_DENSE_ROW] * n_col, n_col)) ; + dense_col_count = MAX (0, MIN (knobs [COLAMD_DENSE_COL] * n_row, n_row)) ; + DEBUG1 (("colamd: densecount: %d %d\n", dense_row_count, dense_col_count)) ; + max_deg = 0 ; + n_col2 = n_col ; + n_row2 = n_row ; + + /* === Kill empty columns =============================================== */ + + /* Put the empty columns at the end in their natural order, so that LU */ + /* factorization can proceed as far as possible. */ + for (c = n_col-1 ; c >= 0 ; c--) + { + deg = Col [c].length ; + if (deg == 0) + { + /* this is a empty column, kill and order it last */ + Col [c].shared2.order = --n_col2 ; + KILL_PRINCIPAL_COL (c) ; + } + } + DEBUG1 (("colamd: null columns killed: %d\n", n_col - n_col2)) ; + + /* === Kill dense columns =============================================== */ + + /* Put the dense columns at the end, in their natural order */ + for (c = n_col-1 ; c >= 0 ; c--) + { + /* skip any dead columns */ + if (COL_IS_DEAD (c)) + { + continue ; + } + deg = Col [c].length ; + if (deg > dense_col_count) + { + /* this is a dense column, kill and order it last */ + Col [c].shared2.order = --n_col2 ; + /* decrement the row degrees */ + cp = &A [Col [c].start] ; + cp_end = cp + Col [c].length ; + while (cp < cp_end) + { + Row [*cp++].shared1.degree-- ; + } + KILL_PRINCIPAL_COL (c) ; + } + } + DEBUG1 (("colamd: Dense and null columns killed: %d\n", n_col - n_col2)) ; + + /* === Kill dense and empty rows ======================================== */ + + for (r = 0 ; r < n_row ; r++) + { + deg = Row [r].shared1.degree ; + ASSERT (deg >= 0 && deg <= n_col) ; + if (deg > dense_row_count || deg == 0) + { + /* kill a dense or empty row */ + KILL_ROW (r) ; + --n_row2 ; + } + else + { + /* keep track of max degree of remaining rows */ + max_deg = MAX (max_deg, deg) ; + } + } + DEBUG1 (("colamd: Dense and null rows killed: %d\n", n_row - n_row2)) ; + + /* === Compute initial column scores ==================================== */ + + /* At this point the row degrees are accurate. They reflect the number */ + /* of "live" (non-dense) columns in each row. No empty rows exist. */ + /* Some "live" columns may contain only dead rows, however. These are */ + /* pruned in the code below. */ + + /* now find the initial matlab score for each column */ + for (c = n_col-1 ; c >= 0 ; c--) + { + /* skip dead column */ + if (COL_IS_DEAD (c)) + { + continue ; + } + score = 0 ; + cp = &A [Col [c].start] ; + new_cp = cp ; + cp_end = cp + Col [c].length ; + while (cp < cp_end) + { + /* get a row */ + row = *cp++ ; + /* skip if dead */ + if (ROW_IS_DEAD (row)) + { + continue ; + } + /* compact the column */ + *new_cp++ = row ; + /* add row's external degree */ + score += Row [row].shared1.degree - 1 ; + /* guard against integer overflow */ + score = MIN (score, n_col) ; + } + /* determine pruned column length */ + col_length = (int) (new_cp - &A [Col [c].start]) ; + if (col_length == 0) + { + /* a newly-made null column (all rows in this col are "dense" */ + /* and have already been killed) */ + DEBUG2 (("Newly null killed: %d\n", c)) ; + Col [c].shared2.order = --n_col2 ; + KILL_PRINCIPAL_COL (c) ; + } + else + { + /* set column length and set score */ + ASSERT (score >= 0) ; + ASSERT (score <= n_col) ; + Col [c].length = col_length ; + Col [c].shared2.score = score ; + } + } + DEBUG1 (("colamd: Dense, null, and newly-null columns killed: %d\n", + n_col-n_col2)) ; + + /* At this point, all empty rows and columns are dead. All live columns */ + /* are "clean" (containing no dead rows) and simplicial (no supercolumns */ + /* yet). Rows may contain dead columns, but all live rows contain at */ + /* least one live column. */ + +#ifndef NDEBUG + debug_structures (n_row, n_col, Row, Col, A, n_col2) ; +#endif /* NDEBUG */ + + /* === Initialize degree lists ========================================== */ + +#ifndef NDEBUG + debug_count = 0 ; +#endif /* NDEBUG */ + + /* clear the hash buckets */ + for (c = 0 ; c <= n_col ; c++) + { + head [c] = EMPTY ; + } + min_score = n_col ; + /* place in reverse order, so low column indices are at the front */ + /* of the lists. This is to encourage natural tie-breaking */ + for (c = n_col-1 ; c >= 0 ; c--) + { + /* only add principal columns to degree lists */ + if (COL_IS_ALIVE (c)) + { + DEBUG4 (("place %d score %d minscore %d ncol %d\n", + c, Col [c].shared2.score, min_score, n_col)) ; + + /* === Add columns score to DList =============================== */ + + score = Col [c].shared2.score ; + + ASSERT (min_score >= 0) ; + ASSERT (min_score <= n_col) ; + ASSERT (score >= 0) ; + ASSERT (score <= n_col) ; + ASSERT (head [score] >= EMPTY) ; + + /* now add this column to dList at proper score location */ + next_col = head [score] ; + Col [c].shared3.prev = EMPTY ; + Col [c].shared4.degree_next = next_col ; + + /* if there already was a column with the same score, set its */ + /* previous pointer to this new column */ + if (next_col != EMPTY) + { + Col [next_col].shared3.prev = c ; + } + head [score] = c ; + + /* see if this score is less than current min */ + min_score = MIN (min_score, score) ; + +#ifndef NDEBUG + debug_count++ ; +#endif /* NDEBUG */ + + } + } + +#ifndef NDEBUG + DEBUG1 (("colamd: Live cols %d out of %d, non-princ: %d\n", + debug_count, n_col, n_col-debug_count)) ; + ASSERT (debug_count == n_col2) ; + debug_deg_lists (n_row, n_col, Row, Col, head, min_score, n_col2, max_deg) ; +#endif /* NDEBUG */ + + /* === Return number of remaining columns, and max row degree =========== */ + + *p_n_col2 = n_col2 ; + *p_n_row2 = n_row2 ; + *p_max_deg = max_deg ; +} + + +/* ========================================================================== */ +/* === find_ordering ======================================================== */ +/* ========================================================================== */ + +/* + Order the principal columns of the supercolumn form of the matrix + (no supercolumns on input). Uses a minimum approximate column minimum + degree ordering method. Not user-callable. +*/ + +PRIVATE int find_ordering /* return the number of garbage collections */ +( + /* === Parameters ======================================================= */ + + int n_row, /* number of rows of A */ + int n_col, /* number of columns of A */ + int Alen, /* size of A, 2*nnz + n_col or larger */ + Colamd_Row Row [], /* of size n_row+1 */ + Colamd_Col Col [], /* of size n_col+1 */ + int A [], /* column form and row form of A */ + int head [], /* of size n_col+1 */ + int n_col2, /* Remaining columns to order */ + int max_deg, /* Maximum row degree */ + int pfree /* index of first free slot (2*nnz on entry) */ +) +{ + /* === Local variables ================================================== */ + + int k ; /* current pivot ordering step */ + int pivot_col ; /* current pivot column */ + int *cp ; /* a column pointer */ + int *rp ; /* a row pointer */ + int pivot_row ; /* current pivot row */ + int *new_cp ; /* modified column pointer */ + int *new_rp ; /* modified row pointer */ + int pivot_row_start ; /* pointer to start of pivot row */ + int pivot_row_degree ; /* number of columns in pivot row */ + int pivot_row_length ; /* number of supercolumns in pivot row */ + int pivot_col_score ; /* score of pivot column */ + int needed_memory ; /* free space needed for pivot row */ + int *cp_end ; /* pointer to the end of a column */ + int *rp_end ; /* pointer to the end of a row */ + int row ; /* a row index */ + int col ; /* a column index */ + int max_score ; /* maximum possible score */ + int cur_score ; /* score of current column */ + unsigned int hash ; /* hash value for supernode detection */ + int head_column ; /* head of hash bucket */ + int first_col ; /* first column in hash bucket */ + int tag_mark ; /* marker value for mark array */ + int row_mark ; /* Row [row].shared2.mark */ + int set_difference ; /* set difference size of row with pivot row */ + int min_score ; /* smallest column score */ + int col_thickness ; /* "thickness" (no. of columns in a supercol) */ + int max_mark ; /* maximum value of tag_mark */ + int pivot_col_thickness ; /* number of columns represented by pivot col */ + int prev_col ; /* Used by Dlist operations. */ + int next_col ; /* Used by Dlist operations. */ + int ngarbage ; /* number of garbage collections performed */ + +#ifndef NDEBUG + int debug_d ; /* debug loop counter */ + int debug_step = 0 ; /* debug loop counter */ +#endif /* NDEBUG */ + + /* === Initialization and clear mark ==================================== */ + + max_mark = INT_MAX - n_col ; /* INT_MAX defined in */ + tag_mark = clear_mark (n_row, Row) ; + min_score = 0 ; + ngarbage = 0 ; + DEBUG1 (("colamd: Ordering, n_col2=%d\n", n_col2)) ; + + /* === Order the columns ================================================ */ + + for (k = 0 ; k < n_col2 ; /* 'k' is incremented below */) + { + +#ifndef NDEBUG + if (debug_step % 100 == 0) + { + DEBUG2 (("\n... Step k: %d out of n_col2: %d\n", k, n_col2)) ; + } + else + { + DEBUG3 (("\n----------Step k: %d out of n_col2: %d\n", k, n_col2)) ; + } + debug_step++ ; + debug_deg_lists (n_row, n_col, Row, Col, head, + min_score, n_col2-k, max_deg) ; + debug_matrix (n_row, n_col, Row, Col, A) ; +#endif /* NDEBUG */ + + /* === Select pivot column, and order it ============================ */ + + /* make sure degree list isn't empty */ + ASSERT (min_score >= 0) ; + ASSERT (min_score <= n_col) ; + ASSERT (head [min_score] >= EMPTY) ; + +#ifndef NDEBUG + for (debug_d = 0 ; debug_d < min_score ; debug_d++) + { + ASSERT (head [debug_d] == EMPTY) ; + } +#endif /* NDEBUG */ + + /* get pivot column from head of minimum degree list */ + while (head [min_score] == EMPTY && min_score < n_col) + { + min_score++ ; + } + pivot_col = head [min_score] ; + ASSERT (pivot_col >= 0 && pivot_col <= n_col) ; + next_col = Col [pivot_col].shared4.degree_next ; + head [min_score] = next_col ; + if (next_col != EMPTY) + { + Col [next_col].shared3.prev = EMPTY ; + } + + ASSERT (COL_IS_ALIVE (pivot_col)) ; + DEBUG3 (("Pivot col: %d\n", pivot_col)) ; + + /* remember score for defrag check */ + pivot_col_score = Col [pivot_col].shared2.score ; + + /* the pivot column is the kth column in the pivot order */ + Col [pivot_col].shared2.order = k ; + + /* increment order count by column thickness */ + pivot_col_thickness = Col [pivot_col].shared1.thickness ; + k += pivot_col_thickness ; + ASSERT (pivot_col_thickness > 0) ; + + /* === Garbage_collection, if necessary ============================= */ + + needed_memory = MIN (pivot_col_score, n_col - k) ; + if (pfree + needed_memory >= Alen) + { + pfree = garbage_collection (n_row, n_col, Row, Col, A, &A [pfree]) ; + ngarbage++ ; + /* after garbage collection we will have enough */ + ASSERT (pfree + needed_memory < Alen) ; + /* garbage collection has wiped out the Row[].shared2.mark array */ + tag_mark = clear_mark (n_row, Row) ; + +#ifndef NDEBUG + debug_matrix (n_row, n_col, Row, Col, A) ; +#endif /* NDEBUG */ + } + + /* === Compute pivot row pattern ==================================== */ + + /* get starting location for this new merged row */ + pivot_row_start = pfree ; + + /* initialize new row counts to zero */ + pivot_row_degree = 0 ; + + /* tag pivot column as having been visited so it isn't included */ + /* in merged pivot row */ + Col [pivot_col].shared1.thickness = -pivot_col_thickness ; + + /* pivot row is the union of all rows in the pivot column pattern */ + cp = &A [Col [pivot_col].start] ; + cp_end = cp + Col [pivot_col].length ; + while (cp < cp_end) + { + /* get a row */ + row = *cp++ ; + DEBUG4 (("Pivot col pattern %d %d\n", ROW_IS_ALIVE (row), row)) ; + /* skip if row is dead */ + if (ROW_IS_DEAD (row)) + { + continue ; + } + rp = &A [Row [row].start] ; + rp_end = rp + Row [row].length ; + while (rp < rp_end) + { + /* get a column */ + col = *rp++ ; + /* add the column, if alive and untagged */ + col_thickness = Col [col].shared1.thickness ; + if (col_thickness > 0 && COL_IS_ALIVE (col)) + { + /* tag column in pivot row */ + Col [col].shared1.thickness = -col_thickness ; + ASSERT (pfree < Alen) ; + /* place column in pivot row */ + A [pfree++] = col ; + pivot_row_degree += col_thickness ; + } + } + } + + /* clear tag on pivot column */ + Col [pivot_col].shared1.thickness = pivot_col_thickness ; + max_deg = MAX (max_deg, pivot_row_degree) ; + +#ifndef NDEBUG + DEBUG3 (("check2\n")) ; + debug_mark (n_row, Row, tag_mark, max_mark) ; +#endif /* NDEBUG */ + + /* === Kill all rows used to construct pivot row ==================== */ + + /* also kill pivot row, temporarily */ + cp = &A [Col [pivot_col].start] ; + cp_end = cp + Col [pivot_col].length ; + while (cp < cp_end) + { + /* may be killing an already dead row */ + row = *cp++ ; + DEBUG3 (("Kill row in pivot col: %d\n", row)) ; + KILL_ROW (row) ; + } + + /* === Select a row index to use as the new pivot row =============== */ + + pivot_row_length = pfree - pivot_row_start ; + if (pivot_row_length > 0) + { + /* pick the "pivot" row arbitrarily (first row in col) */ + pivot_row = A [Col [pivot_col].start] ; + DEBUG3 (("Pivotal row is %d\n", pivot_row)) ; + } + else + { + /* there is no pivot row, since it is of zero length */ + pivot_row = EMPTY ; + ASSERT (pivot_row_length == 0) ; + } + ASSERT (Col [pivot_col].length > 0 || pivot_row_length == 0) ; + + /* === Approximate degree computation =============================== */ + + /* Here begins the computation of the approximate degree. The column */ + /* score is the sum of the pivot row "length", plus the size of the */ + /* set differences of each row in the column minus the pattern of the */ + /* pivot row itself. The column ("thickness") itself is also */ + /* excluded from the column score (we thus use an approximate */ + /* external degree). */ + + /* The time taken by the following code (compute set differences, and */ + /* add them up) is proportional to the size of the data structure */ + /* being scanned - that is, the sum of the sizes of each column in */ + /* the pivot row. Thus, the amortized time to compute a column score */ + /* is proportional to the size of that column (where size, in this */ + /* context, is the column "length", or the number of row indices */ + /* in that column). The number of row indices in a column is */ + /* monotonically non-decreasing, from the length of the original */ + /* column on input to colamd. */ + + /* === Compute set differences ====================================== */ + + DEBUG3 (("** Computing set differences phase. **\n")) ; + + /* pivot row is currently dead - it will be revived later. */ + + DEBUG3 (("Pivot row: ")) ; + /* for each column in pivot row */ + rp = &A [pivot_row_start] ; + rp_end = rp + pivot_row_length ; + while (rp < rp_end) + { + col = *rp++ ; + ASSERT (COL_IS_ALIVE (col) && col != pivot_col) ; + DEBUG3 (("Col: %d\n", col)) ; + + /* clear tags used to construct pivot row pattern */ + col_thickness = -Col [col].shared1.thickness ; + ASSERT (col_thickness > 0) ; + Col [col].shared1.thickness = col_thickness ; + + /* === Remove column from degree list =========================== */ + + cur_score = Col [col].shared2.score ; + prev_col = Col [col].shared3.prev ; + next_col = Col [col].shared4.degree_next ; + ASSERT (cur_score >= 0) ; + ASSERT (cur_score <= n_col) ; + ASSERT (cur_score >= EMPTY) ; + if (prev_col == EMPTY) + { + head [cur_score] = next_col ; + } + else + { + Col [prev_col].shared4.degree_next = next_col ; + } + if (next_col != EMPTY) + { + Col [next_col].shared3.prev = prev_col ; + } + + /* === Scan the column ========================================== */ + + cp = &A [Col [col].start] ; + cp_end = cp + Col [col].length ; + while (cp < cp_end) + { + /* get a row */ + row = *cp++ ; + row_mark = Row [row].shared2.mark ; + /* skip if dead */ + if (ROW_IS_MARKED_DEAD (row_mark)) + { + continue ; + } + ASSERT (row != pivot_row) ; + set_difference = row_mark - tag_mark ; + /* check if the row has been seen yet */ + if (set_difference < 0) + { + ASSERT (Row [row].shared1.degree <= max_deg) ; + set_difference = Row [row].shared1.degree ; + } + /* subtract column thickness from this row's set difference */ + set_difference -= col_thickness ; + ASSERT (set_difference >= 0) ; + /* absorb this row if the set difference becomes zero */ + if (set_difference == 0) + { + DEBUG3 (("aggressive absorption. Row: %d\n", row)) ; + KILL_ROW (row) ; + } + else + { + /* save the new mark */ + Row [row].shared2.mark = set_difference + tag_mark ; + } + } + } + +#ifndef NDEBUG + debug_deg_lists (n_row, n_col, Row, Col, head, + min_score, n_col2-k-pivot_row_degree, max_deg) ; +#endif /* NDEBUG */ + + /* === Add up set differences for each column ======================= */ + + DEBUG3 (("** Adding set differences phase. **\n")) ; + + /* for each column in pivot row */ + rp = &A [pivot_row_start] ; + rp_end = rp + pivot_row_length ; + while (rp < rp_end) + { + /* get a column */ + col = *rp++ ; + ASSERT (COL_IS_ALIVE (col) && col != pivot_col) ; + hash = 0 ; + cur_score = 0 ; + cp = &A [Col [col].start] ; + /* compact the column */ + new_cp = cp ; + cp_end = cp + Col [col].length ; + + DEBUG4 (("Adding set diffs for Col: %d.\n", col)) ; + + while (cp < cp_end) + { + /* get a row */ + row = *cp++ ; + ASSERT(row >= 0 && row < n_row) ; + row_mark = Row [row].shared2.mark ; + /* skip if dead */ + if (ROW_IS_MARKED_DEAD (row_mark)) + { + continue ; + } + ASSERT (row_mark > tag_mark) ; + /* compact the column */ + *new_cp++ = row ; + /* compute hash function */ + hash += row ; + /* add set difference */ + cur_score += row_mark - tag_mark ; + /* integer overflow... */ + cur_score = MIN (cur_score, n_col) ; + } + + /* recompute the column's length */ + Col [col].length = (int) (new_cp - &A [Col [col].start]) ; + + /* === Further mass elimination ================================= */ + + if (Col [col].length == 0) + { + DEBUG4 (("further mass elimination. Col: %d\n", col)) ; + /* nothing left but the pivot row in this column */ + KILL_PRINCIPAL_COL (col) ; + pivot_row_degree -= Col [col].shared1.thickness ; + ASSERT (pivot_row_degree >= 0) ; + /* order it */ + Col [col].shared2.order = k ; + /* increment order count by column thickness */ + k += Col [col].shared1.thickness ; + } + else + { + /* === Prepare for supercolumn detection ==================== */ + + DEBUG4 (("Preparing supercol detection for Col: %d.\n", col)) ; + + /* save score so far */ + Col [col].shared2.score = cur_score ; + + /* add column to hash table, for supercolumn detection */ + hash %= n_col + 1 ; + + DEBUG4 ((" Hash = %d, n_col = %d.\n", hash, n_col)) ; + ASSERT (hash <= n_col) ; + + head_column = head [hash] ; + if (head_column > EMPTY) + { + /* degree list "hash" is non-empty, use prev (shared3) of */ + /* first column in degree list as head of hash bucket */ + first_col = Col [head_column].shared3.headhash ; + Col [head_column].shared3.headhash = col ; + } + else + { + /* degree list "hash" is empty, use head as hash bucket */ + first_col = - (head_column + 2) ; + head [hash] = - (col + 2) ; + } + Col [col].shared4.hash_next = first_col ; + + /* save hash function in Col [col].shared3.hash */ + Col [col].shared3.hash = (int) hash ; + ASSERT (COL_IS_ALIVE (col)) ; + } + } + + /* The approximate external column degree is now computed. */ + + /* === Supercolumn detection ======================================== */ + + DEBUG3 (("** Supercolumn detection phase. **\n")) ; + + detect_super_cols ( + +#ifndef NDEBUG + n_col, Row, +#endif /* NDEBUG */ + + Col, A, head, pivot_row_start, pivot_row_length) ; + + /* === Kill the pivotal column ====================================== */ + + KILL_PRINCIPAL_COL (pivot_col) ; + + /* === Clear mark =================================================== */ + + tag_mark += (max_deg + 1) ; + if (tag_mark >= max_mark) + { + DEBUG2 (("clearing tag_mark\n")) ; + tag_mark = clear_mark (n_row, Row) ; + } + +#ifndef NDEBUG + DEBUG3 (("check3\n")) ; + debug_mark (n_row, Row, tag_mark, max_mark) ; +#endif /* NDEBUG */ + + /* === Finalize the new pivot row, and column scores ================ */ + + DEBUG3 (("** Finalize scores phase. **\n")) ; + + /* for each column in pivot row */ + rp = &A [pivot_row_start] ; + /* compact the pivot row */ + new_rp = rp ; + rp_end = rp + pivot_row_length ; + while (rp < rp_end) + { + col = *rp++ ; + /* skip dead columns */ + if (COL_IS_DEAD (col)) + { + continue ; + } + *new_rp++ = col ; + /* add new pivot row to column */ + A [Col [col].start + (Col [col].length++)] = pivot_row ; + + /* retrieve score so far and add on pivot row's degree. */ + /* (we wait until here for this in case the pivot */ + /* row's degree was reduced due to mass elimination). */ + cur_score = Col [col].shared2.score + pivot_row_degree ; + + /* calculate the max possible score as the number of */ + /* external columns minus the 'k' value minus the */ + /* columns thickness */ + max_score = n_col - k - Col [col].shared1.thickness ; + + /* make the score the external degree of the union-of-rows */ + cur_score -= Col [col].shared1.thickness ; + + /* make sure score is less or equal than the max score */ + cur_score = MIN (cur_score, max_score) ; + ASSERT (cur_score >= 0) ; + + /* store updated score */ + Col [col].shared2.score = cur_score ; + + /* === Place column back in degree list ========================= */ + + ASSERT (min_score >= 0) ; + ASSERT (min_score <= n_col) ; + ASSERT (cur_score >= 0) ; + ASSERT (cur_score <= n_col) ; + ASSERT (head [cur_score] >= EMPTY) ; + next_col = head [cur_score] ; + Col [col].shared4.degree_next = next_col ; + Col [col].shared3.prev = EMPTY ; + if (next_col != EMPTY) + { + Col [next_col].shared3.prev = col ; + } + head [cur_score] = col ; + + /* see if this score is less than current min */ + min_score = MIN (min_score, cur_score) ; + + } + +#ifndef NDEBUG + debug_deg_lists (n_row, n_col, Row, Col, head, + min_score, n_col2-k, max_deg) ; +#endif /* NDEBUG */ + + /* === Resurrect the new pivot row ================================== */ + + if (pivot_row_degree > 0) + { + /* update pivot row length to reflect any cols that were killed */ + /* during super-col detection and mass elimination */ + Row [pivot_row].start = pivot_row_start ; + Row [pivot_row].length = (int) (new_rp - &A[pivot_row_start]) ; + Row [pivot_row].shared1.degree = pivot_row_degree ; + Row [pivot_row].shared2.mark = 0 ; + /* pivot row is no longer dead */ + } + } + + /* === All principal columns have now been ordered ====================== */ + + return (ngarbage) ; +} + + +/* ========================================================================== */ +/* === order_children ======================================================= */ +/* ========================================================================== */ + +/* + The find_ordering routine has ordered all of the principal columns (the + representatives of the supercolumns). The non-principal columns have not + yet been ordered. This routine orders those columns by walking up the + parent tree (a column is a child of the column which absorbed it). The + final permutation vector is then placed in p [0 ... n_col-1], with p [0] + being the first column, and p [n_col-1] being the last. It doesn't look + like it at first glance, but be assured that this routine takes time linear + in the number of columns. Although not immediately obvious, the time + taken by this routine is O (n_col), that is, linear in the number of + columns. Not user-callable. +*/ + +PRIVATE void order_children +( + /* === Parameters ======================================================= */ + + int n_col, /* number of columns of A */ + Colamd_Col Col [], /* of size n_col+1 */ + int p [] /* p [0 ... n_col-1] is the column permutation*/ +) +{ + /* === Local variables ================================================== */ + + int i ; /* loop counter for all columns */ + int c ; /* column index */ + int parent ; /* index of column's parent */ + int order ; /* column's order */ + + /* === Order each non-principal column ================================== */ + + for (i = 0 ; i < n_col ; i++) + { + /* find an un-ordered non-principal column */ + ASSERT (COL_IS_DEAD (i)) ; + if (!COL_IS_DEAD_PRINCIPAL (i) && Col [i].shared2.order == EMPTY) + { + parent = i ; + /* once found, find its principal parent */ + do + { + parent = Col [parent].shared1.parent ; + } while (!COL_IS_DEAD_PRINCIPAL (parent)) ; + + /* now, order all un-ordered non-principal columns along path */ + /* to this parent. collapse tree at the same time */ + c = i ; + /* get order of parent */ + order = Col [parent].shared2.order ; + + do + { + ASSERT (Col [c].shared2.order == EMPTY) ; + + /* order this column */ + Col [c].shared2.order = order++ ; + /* collaps tree */ + Col [c].shared1.parent = parent ; + + /* get immediate parent of this column */ + c = Col [c].shared1.parent ; + + /* continue until we hit an ordered column. There are */ + /* guarranteed not to be anymore unordered columns */ + /* above an ordered column */ + } while (Col [c].shared2.order == EMPTY) ; + + /* re-order the super_col parent to largest order for this group */ + Col [parent].shared2.order = order ; + } + } + + /* === Generate the permutation ========================================= */ + + for (c = 0 ; c < n_col ; c++) + { + p [Col [c].shared2.order] = c ; + } +} + + +/* ========================================================================== */ +/* === detect_super_cols ==================================================== */ +/* ========================================================================== */ + +/* + Detects supercolumns by finding matches between columns in the hash buckets. + Check amongst columns in the set A [row_start ... row_start + row_length-1]. + The columns under consideration are currently *not* in the degree lists, + and have already been placed in the hash buckets. + + The hash bucket for columns whose hash function is equal to h is stored + as follows: + + if head [h] is >= 0, then head [h] contains a degree list, so: + + head [h] is the first column in degree bucket h. + Col [head [h]].headhash gives the first column in hash bucket h. + + otherwise, the degree list is empty, and: + + -(head [h] + 2) is the first column in hash bucket h. + + For a column c in a hash bucket, Col [c].shared3.prev is NOT a "previous + column" pointer. Col [c].shared3.hash is used instead as the hash number + for that column. The value of Col [c].shared4.hash_next is the next column + in the same hash bucket. + + Assuming no, or "few" hash collisions, the time taken by this routine is + linear in the sum of the sizes (lengths) of each column whose score has + just been computed in the approximate degree computation. + Not user-callable. +*/ + +PRIVATE void detect_super_cols +( + /* === Parameters ======================================================= */ + +#ifndef NDEBUG + /* these two parameters are only needed when debugging is enabled: */ + int n_col, /* number of columns of A */ + Colamd_Row Row [], /* of size n_row+1 */ +#endif /* NDEBUG */ + + Colamd_Col Col [], /* of size n_col+1 */ + int A [], /* row indices of A */ + int head [], /* head of degree lists and hash buckets */ + int row_start, /* pointer to set of columns to check */ + int row_length /* number of columns to check */ +) +{ + /* === Local variables ================================================== */ + + int hash ; /* hash value for a column */ + int *rp ; /* pointer to a row */ + int c ; /* a column index */ + int super_c ; /* column index of the column to absorb into */ + int *cp1 ; /* column pointer for column super_c */ + int *cp2 ; /* column pointer for column c */ + int length ; /* length of column super_c */ + int prev_c ; /* column preceding c in hash bucket */ + int i ; /* loop counter */ + int *rp_end ; /* pointer to the end of the row */ + int col ; /* a column index in the row to check */ + int head_column ; /* first column in hash bucket or degree list */ + int first_col ; /* first column in hash bucket */ + + /* === Consider each column in the row ================================== */ + + rp = &A [row_start] ; + rp_end = rp + row_length ; + while (rp < rp_end) + { + col = *rp++ ; + if (COL_IS_DEAD (col)) + { + continue ; + } + + /* get hash number for this column */ + hash = Col [col].shared3.hash ; + ASSERT (hash <= n_col) ; + + /* === Get the first column in this hash bucket ===================== */ + + head_column = head [hash] ; + if (head_column > EMPTY) + { + first_col = Col [head_column].shared3.headhash ; + } + else + { + first_col = - (head_column + 2) ; + } + + /* === Consider each column in the hash bucket ====================== */ + + for (super_c = first_col ; super_c != EMPTY ; + super_c = Col [super_c].shared4.hash_next) + { + ASSERT (COL_IS_ALIVE (super_c)) ; + ASSERT (Col [super_c].shared3.hash == hash) ; + length = Col [super_c].length ; + + /* prev_c is the column preceding column c in the hash bucket */ + prev_c = super_c ; + + /* === Compare super_c with all columns after it ================ */ + + for (c = Col [super_c].shared4.hash_next ; + c != EMPTY ; c = Col [c].shared4.hash_next) + { + ASSERT (c != super_c) ; + ASSERT (COL_IS_ALIVE (c)) ; + ASSERT (Col [c].shared3.hash == hash) ; + + /* not identical if lengths or scores are different */ + if (Col [c].length != length || + Col [c].shared2.score != Col [super_c].shared2.score) + { + prev_c = c ; + continue ; + } + + /* compare the two columns */ + cp1 = &A [Col [super_c].start] ; + cp2 = &A [Col [c].start] ; + + for (i = 0 ; i < length ; i++) + { + /* the columns are "clean" (no dead rows) */ + ASSERT (ROW_IS_ALIVE (*cp1)) ; + ASSERT (ROW_IS_ALIVE (*cp2)) ; + /* row indices will same order for both supercols, */ + /* no gather scatter nessasary */ + if (*cp1++ != *cp2++) + { + break ; + } + } + + /* the two columns are different if the for-loop "broke" */ + if (i != length) + { + prev_c = c ; + continue ; + } + + /* === Got it! two columns are identical =================== */ + + ASSERT (Col [c].shared2.score == Col [super_c].shared2.score) ; + + Col [super_c].shared1.thickness += Col [c].shared1.thickness ; + Col [c].shared1.parent = super_c ; + KILL_NON_PRINCIPAL_COL (c) ; + /* order c later, in order_children() */ + Col [c].shared2.order = EMPTY ; + /* remove c from hash bucket */ + Col [prev_c].shared4.hash_next = Col [c].shared4.hash_next ; + } + } + + /* === Empty this hash bucket ======================================= */ + + if (head_column > EMPTY) + { + /* corresponding degree list "hash" is not empty */ + Col [head_column].shared3.headhash = EMPTY ; + } + else + { + /* corresponding degree list "hash" is empty */ + head [hash] = EMPTY ; + } + } +} + + +/* ========================================================================== */ +/* === garbage_collection =================================================== */ +/* ========================================================================== */ + +/* + Defragments and compacts columns and rows in the workspace A. Used when + all avaliable memory has been used while performing row merging. Returns + the index of the first free position in A, after garbage collection. The + time taken by this routine is linear is the size of the array A, which is + itself linear in the number of nonzeros in the input matrix. + Not user-callable. +*/ + +PRIVATE int garbage_collection /* returns the new value of pfree */ +( + /* === Parameters ======================================================= */ + + int n_row, /* number of rows */ + int n_col, /* number of columns */ + Colamd_Row Row [], /* row info */ + Colamd_Col Col [], /* column info */ + int A [], /* A [0 ... Alen-1] holds the matrix */ + int *pfree /* &A [0] ... pfree is in use */ +) +{ + /* === Local variables ================================================== */ + + int *psrc ; /* source pointer */ + int *pdest ; /* destination pointer */ + int j ; /* counter */ + int r ; /* a row index */ + int c ; /* a column index */ + int length ; /* length of a row or column */ + +#ifndef NDEBUG + int debug_rows ; + DEBUG2 (("Defrag..\n")) ; + for (psrc = &A[0] ; psrc < pfree ; psrc++) ASSERT (*psrc >= 0) ; + debug_rows = 0 ; +#endif /* NDEBUG */ + + /* === Defragment the columns =========================================== */ + + pdest = &A[0] ; + for (c = 0 ; c < n_col ; c++) + { + if (COL_IS_ALIVE (c)) + { + psrc = &A [Col [c].start] ; + + /* move and compact the column */ + ASSERT (pdest <= psrc) ; + Col [c].start = (int) (pdest - &A [0]) ; + length = Col [c].length ; + for (j = 0 ; j < length ; j++) + { + r = *psrc++ ; + if (ROW_IS_ALIVE (r)) + { + *pdest++ = r ; + } + } + Col [c].length = (int) (pdest - &A [Col [c].start]) ; + } + } + + /* === Prepare to defragment the rows =================================== */ + + for (r = 0 ; r < n_row ; r++) + { + if (ROW_IS_ALIVE (r)) + { + if (Row [r].length == 0) + { + /* this row is of zero length. cannot compact it, so kill it */ + DEBUG3 (("Defrag row kill\n")) ; + KILL_ROW (r) ; + } + else + { + /* save first column index in Row [r].shared2.first_column */ + psrc = &A [Row [r].start] ; + Row [r].shared2.first_column = *psrc ; + ASSERT (ROW_IS_ALIVE (r)) ; + /* flag the start of the row with the one's complement of row */ + *psrc = ONES_COMPLEMENT (r) ; + +#ifndef NDEBUG + debug_rows++ ; +#endif /* NDEBUG */ + + } + } + } + + /* === Defragment the rows ============================================== */ + + psrc = pdest ; + while (psrc < pfree) + { + /* find a negative number ... the start of a row */ + if (*psrc++ < 0) + { + psrc-- ; + /* get the row index */ + r = ONES_COMPLEMENT (*psrc) ; + ASSERT (r >= 0 && r < n_row) ; + /* restore first column index */ + *psrc = Row [r].shared2.first_column ; + ASSERT (ROW_IS_ALIVE (r)) ; + + /* move and compact the row */ + ASSERT (pdest <= psrc) ; + Row [r].start = (int) (pdest - &A [0]) ; + length = Row [r].length ; + for (j = 0 ; j < length ; j++) + { + c = *psrc++ ; + if (COL_IS_ALIVE (c)) + { + *pdest++ = c ; + } + } + Row [r].length = (int) (pdest - &A [Row [r].start]) ; + +#ifndef NDEBUG + debug_rows-- ; +#endif /* NDEBUG */ + + } + } + /* ensure we found all the rows */ + ASSERT (debug_rows == 0) ; + + /* === Return the new value of pfree ==================================== */ + + return ((int) (pdest - &A [0])) ; +} + + +/* ========================================================================== */ +/* === clear_mark =========================================================== */ +/* ========================================================================== */ + +/* + Clears the Row [].shared2.mark array, and returns the new tag_mark. + Return value is the new tag_mark. Not user-callable. +*/ + +PRIVATE int clear_mark /* return the new value for tag_mark */ +( + /* === Parameters ======================================================= */ + + int n_row, /* number of rows in A */ + Colamd_Row Row [] /* Row [0 ... n_row-1].shared2.mark is set to zero */ +) +{ + /* === Local variables ================================================== */ + + int r ; + + for (r = 0 ; r < n_row ; r++) + { + if (ROW_IS_ALIVE (r)) + { + Row [r].shared2.mark = 0 ; + } + } + return (1) ; +} + + +/* ========================================================================== */ +/* === print_report ========================================================= */ +/* ========================================================================== */ + +PRIVATE void print_report +( + char *method, + int stats [COLAMD_STATS] +) +{ + + int i1, i2, i3 ; + + if (!stats) + { + PRINTF ("%s: No statistics available.\n", method) ; + return ; + } + + i1 = stats [COLAMD_INFO1] ; + i2 = stats [COLAMD_INFO2] ; + i3 = stats [COLAMD_INFO3] ; + + if (stats [COLAMD_STATUS] >= 0) + { + PRINTF ("%s: OK. ", method) ; + } + else + { + PRINTF ("%s: ERROR. ", method) ; + } + + switch (stats [COLAMD_STATUS]) + { + + case COLAMD_OK_BUT_JUMBLED: + + PRINTF ("Matrix has unsorted or duplicate row indices.\n") ; + + PRINTF ("%s: number of duplicate or out-of-order row indices: %d\n", + method, i3) ; + + PRINTF ("%s: last seen duplicate or out-of-order row index: %d\n", + method, INDEX (i2)) ; + + PRINTF ("%s: last seen in column: %d", + method, INDEX (i1)) ; + + /* no break - fall through to next case instead */ + + case COLAMD_OK: + + PRINTF ("\n") ; + + PRINTF ("%s: number of dense or empty rows ignored: %d\n", + method, stats [COLAMD_DENSE_ROW]) ; + + PRINTF ("%s: number of dense or empty columns ignored: %d\n", + method, stats [COLAMD_DENSE_COL]) ; + + PRINTF ("%s: number of garbage collections performed: %d\n", + method, stats [COLAMD_DEFRAG_COUNT]) ; + break ; + + case COLAMD_ERROR_A_not_present: + + PRINTF ("Array A (row indices of matrix) not present.\n") ; + break ; + + case COLAMD_ERROR_p_not_present: + + PRINTF ("Array p (column pointers for matrix) not present.\n") ; + break ; + + case COLAMD_ERROR_nrow_negative: + + PRINTF ("Invalid number of rows (%d).\n", i1) ; + break ; + + case COLAMD_ERROR_ncol_negative: + + PRINTF ("Invalid number of columns (%d).\n", i1) ; + break ; + + case COLAMD_ERROR_nnz_negative: + + PRINTF ("Invalid number of nonzero entries (%d).\n", i1) ; + break ; + + case COLAMD_ERROR_p0_nonzero: + + PRINTF ("Invalid column pointer, p [0] = %d, must be zero.\n", i1) ; + break ; + + case COLAMD_ERROR_A_too_small: + + PRINTF ("Array A too small.\n") ; + PRINTF (" Need Alen >= %d, but given only Alen = %d.\n", + i1, i2) ; + break ; + + case COLAMD_ERROR_col_length_negative: + + PRINTF + ("Column %d has a negative number of nonzero entries (%d).\n", + INDEX (i1), i2) ; + break ; + + case COLAMD_ERROR_row_index_out_of_bounds: + + PRINTF + ("Row index (row %d) out of bounds (%d to %d) in column %d.\n", + INDEX (i2), INDEX (0), INDEX (i3-1), INDEX (i1)) ; + break ; + + case COLAMD_ERROR_out_of_memory: + + PRINTF ("Out of memory.\n") ; + break ; + + case COLAMD_ERROR_internal_error: + + /* if this happens, there is a bug in the code */ + PRINTF + ("Internal error! Please contact authors (davis@cise.ufl.edu).\n") ; + break ; + } +} + + + + +/* ========================================================================== */ +/* === colamd debugging routines ============================================ */ +/* ========================================================================== */ + +/* When debugging is disabled, the remainder of this file is ignored. */ + +#ifndef NDEBUG + + +/* ========================================================================== */ +/* === debug_structures ===================================================== */ +/* ========================================================================== */ + +/* + At this point, all empty rows and columns are dead. All live columns + are "clean" (containing no dead rows) and simplicial (no supercolumns + yet). Rows may contain dead columns, but all live rows contain at + least one live column. +*/ + +PRIVATE void debug_structures +( + /* === Parameters ======================================================= */ + + int n_row, + int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + int A [], + int n_col2 +) +{ + /* === Local variables ================================================== */ + + int i ; + int c ; + int *cp ; + int *cp_end ; + int len ; + int score ; + int r ; + int *rp ; + int *rp_end ; + int deg ; + + /* === Check A, Row, and Col ============================================ */ + + for (c = 0 ; c < n_col ; c++) + { + if (COL_IS_ALIVE (c)) + { + len = Col [c].length ; + score = Col [c].shared2.score ; + DEBUG4 (("initial live col %5d %5d %5d\n", c, len, score)) ; + ASSERT (len > 0) ; + ASSERT (score >= 0) ; + ASSERT (Col [c].shared1.thickness == 1) ; + cp = &A [Col [c].start] ; + cp_end = cp + len ; + while (cp < cp_end) + { + r = *cp++ ; + ASSERT (ROW_IS_ALIVE (r)) ; + } + } + else + { + i = Col [c].shared2.order ; + ASSERT (i >= n_col2 && i < n_col) ; + } + } + + for (r = 0 ; r < n_row ; r++) + { + if (ROW_IS_ALIVE (r)) + { + i = 0 ; + len = Row [r].length ; + deg = Row [r].shared1.degree ; + ASSERT (len > 0) ; + ASSERT (deg > 0) ; + rp = &A [Row [r].start] ; + rp_end = rp + len ; + while (rp < rp_end) + { + c = *rp++ ; + if (COL_IS_ALIVE (c)) + { + i++ ; + } + } + ASSERT (i > 0) ; + } + } +} + + +/* ========================================================================== */ +/* === debug_deg_lists ====================================================== */ +/* ========================================================================== */ + +/* + Prints the contents of the degree lists. Counts the number of columns + in the degree list and compares it to the total it should have. Also + checks the row degrees. +*/ + +PRIVATE void debug_deg_lists +( + /* === Parameters ======================================================= */ + + int n_row, + int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + int head [], + int min_score, + int should, + int max_deg +) +{ + /* === Local variables ================================================== */ + + int deg ; + int col ; + int have ; + int row ; + + /* === Check the degree lists =========================================== */ + + if (n_col > 10000 && colamd_debug <= 0) + { + return ; + } + have = 0 ; + DEBUG4 (("Degree lists: %d\n", min_score)) ; + for (deg = 0 ; deg <= n_col ; deg++) + { + col = head [deg] ; + if (col == EMPTY) + { + continue ; + } + DEBUG4 (("%d:", deg)) ; + while (col != EMPTY) + { + DEBUG4 ((" %d", col)) ; + have += Col [col].shared1.thickness ; + ASSERT (COL_IS_ALIVE (col)) ; + col = Col [col].shared4.degree_next ; + } + DEBUG4 (("\n")) ; + } + DEBUG4 (("should %d have %d\n", should, have)) ; + ASSERT (should == have) ; + + /* === Check the row degrees ============================================ */ + + if (n_row > 10000 && colamd_debug <= 0) + { + return ; + } + for (row = 0 ; row < n_row ; row++) + { + if (ROW_IS_ALIVE (row)) + { + ASSERT (Row [row].shared1.degree <= max_deg) ; + } + } +} + + +/* ========================================================================== */ +/* === debug_mark =========================================================== */ +/* ========================================================================== */ + +/* + Ensures that the tag_mark is less that the maximum and also ensures that + each entry in the mark array is less than the tag mark. +*/ + +PRIVATE void debug_mark +( + /* === Parameters ======================================================= */ + + int n_row, + Colamd_Row Row [], + int tag_mark, + int max_mark +) +{ + /* === Local variables ================================================== */ + + int r ; + + /* === Check the Row marks ============================================== */ + + ASSERT (tag_mark > 0 && tag_mark <= max_mark) ; + if (n_row > 10000 && colamd_debug <= 0) + { + return ; + } + for (r = 0 ; r < n_row ; r++) + { + ASSERT (Row [r].shared2.mark < tag_mark) ; + } +} + + +/* ========================================================================== */ +/* === debug_matrix ========================================================= */ +/* ========================================================================== */ + +/* + Prints out the contents of the columns and the rows. +*/ + +PRIVATE void debug_matrix +( + /* === Parameters ======================================================= */ + + int n_row, + int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + int A [] +) +{ + /* === Local variables ================================================== */ + + int r ; + int c ; + int *rp ; + int *rp_end ; + int *cp ; + int *cp_end ; + + /* === Dump the rows and columns of the matrix ========================== */ + + if (colamd_debug < 3) + { + return ; + } + DEBUG3 (("DUMP MATRIX:\n")) ; + for (r = 0 ; r < n_row ; r++) + { + DEBUG3 (("Row %d alive? %d\n", r, ROW_IS_ALIVE (r))) ; + if (ROW_IS_DEAD (r)) + { + continue ; + } + DEBUG3 (("start %d length %d degree %d\n", + Row [r].start, Row [r].length, Row [r].shared1.degree)) ; + rp = &A [Row [r].start] ; + rp_end = rp + Row [r].length ; + while (rp < rp_end) + { + c = *rp++ ; + DEBUG4 ((" %d col %d\n", COL_IS_ALIVE (c), c)) ; + } + } + + for (c = 0 ; c < n_col ; c++) + { + DEBUG3 (("Col %d alive? %d\n", c, COL_IS_ALIVE (c))) ; + if (COL_IS_DEAD (c)) + { + continue ; + } + DEBUG3 (("start %d length %d shared1 %d shared2 %d\n", + Col [c].start, Col [c].length, + Col [c].shared1.thickness, Col [c].shared2.score)) ; + cp = &A [Col [c].start] ; + cp_end = cp + Col [c].length ; + while (cp < cp_end) + { + r = *cp++ ; + DEBUG4 ((" %d row %d\n", ROW_IS_ALIVE (r), r)) ; + } + } +} + +PRIVATE void colamd_get_debug +( + char *method +) +{ + colamd_debug = 0 ; /* no debug printing */ + + /* get "D" environment variable, which gives the debug printing level */ + if (getenv ("D")) + { + colamd_debug = atoi (getenv ("D")) ; + } + + DEBUG0 (("%s: debug version, D = %d (THIS WILL BE SLOW!)\n", + method, colamd_debug)) ; +} + +#endif /* NDEBUG */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/colamd.h b/src/Libraries/superlu-5.2.1/SRC/colamd.h new file mode 100644 index 00000000..03fc3bd1 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/colamd.h @@ -0,0 +1,259 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file colamd.h + \brief Colamd prototypes and definitions + +
 
+    ==========================================================================
+    === colamd/symamd prototypes and definitions =============================
+    ==========================================================================
+
+    You must include this file (colamd.h) in any routine that uses colamd,
+    symamd, or the related macros and definitions.
+
+    Authors:
+
+	The authors of the code itself are Stefan I. Larimore and Timothy A.
+	Davis (davis@cise.ufl.edu), University of Florida.  The algorithm was
+	developed in collaboration with John Gilbert, Xerox PARC, and Esmond
+	Ng, Oak Ridge National Laboratory.
+
+    Date:
+
+	September 8, 2003.  Version 2.3.
+
+    Acknowledgements:
+
+	This work was supported by the National Science Foundation, under
+	grants DMS-9504974 and DMS-9803599.
+
+    Notice:
+
+	Copyright (c) 1998-2003 by the University of Florida.
+	All Rights Reserved.
+
+	THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+	EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+
+	Permission is hereby granted to use, copy, modify, and/or distribute
+	this program, provided that the Copyright, this License, and the
+	Availability of the original version is retained on all copies and made
+	accessible to the end-user of any code or package that includes COLAMD
+	or any modified version of COLAMD. 
+
+    Availability:
+
+	The colamd/symamd library is available at
+
+	    http://www.cise.ufl.edu/research/sparse/colamd/
+
+	This is the http://www.cise.ufl.edu/research/sparse/colamd/colamd.h
+	file.  It is required by the colamd.c, colamdmex.c, and symamdmex.c
+	files, and by any C code that calls the routines whose prototypes are
+	listed below, or that uses the colamd/symamd definitions listed below.
+ 
+*/ + +#ifndef COLAMD_H +#define COLAMD_H + +/* ========================================================================== */ +/* === Include files ======================================================== */ +/* ========================================================================== */ + +#include + +/* ========================================================================== */ +/* === Knob and statistics definitions ====================================== */ +/* ========================================================================== */ + +/* size of the knobs [ ] array. Only knobs [0..1] are currently used. */ +#define COLAMD_KNOBS 20 + +/* number of output statistics. Only stats [0..6] are currently used. */ +#define COLAMD_STATS 20 + +/* knobs [0] and stats [0]: dense row knob and output statistic. */ +#define COLAMD_DENSE_ROW 0 + +/* knobs [1] and stats [1]: dense column knob and output statistic. */ +#define COLAMD_DENSE_COL 1 + +/* stats [2]: memory defragmentation count output statistic */ +#define COLAMD_DEFRAG_COUNT 2 + +/* stats [3]: colamd status: zero OK, > 0 warning or notice, < 0 error */ +#define COLAMD_STATUS 3 + +/* stats [4..6]: error info, or info on jumbled columns */ +#define COLAMD_INFO1 4 +#define COLAMD_INFO2 5 +#define COLAMD_INFO3 6 + +/* error codes returned in stats [3]: */ +#define COLAMD_OK (0) +#define COLAMD_OK_BUT_JUMBLED (1) +#define COLAMD_ERROR_A_not_present (-1) +#define COLAMD_ERROR_p_not_present (-2) +#define COLAMD_ERROR_nrow_negative (-3) +#define COLAMD_ERROR_ncol_negative (-4) +#define COLAMD_ERROR_nnz_negative (-5) +#define COLAMD_ERROR_p0_nonzero (-6) +#define COLAMD_ERROR_A_too_small (-7) +#define COLAMD_ERROR_col_length_negative (-8) +#define COLAMD_ERROR_row_index_out_of_bounds (-9) +#define COLAMD_ERROR_out_of_memory (-10) +#define COLAMD_ERROR_internal_error (-999) + +/* ========================================================================== */ +/* === Row and Column structures ============================================ */ +/* ========================================================================== */ + +/* User code that makes use of the colamd/symamd routines need not directly */ +/* reference these structures. They are used only for the COLAMD_RECOMMENDED */ +/* macro. */ + +typedef struct Colamd_Col_struct +{ + int start ; /* index for A of first row in this column, or DEAD */ + /* if column is dead */ + int length ; /* number of rows in this column */ + union + { + int thickness ; /* number of original columns represented by this */ + /* col, if the column is alive */ + int parent ; /* parent in parent tree super-column structure, if */ + /* the column is dead */ + } shared1 ; + union + { + int score ; /* the score used to maintain heap, if col is alive */ + int order ; /* pivot ordering of this column, if col is dead */ + } shared2 ; + union + { + int headhash ; /* head of a hash bucket, if col is at the head of */ + /* a degree list */ + int hash ; /* hash value, if col is not in a degree list */ + int prev ; /* previous column in degree list, if col is in a */ + /* degree list (but not at the head of a degree list) */ + } shared3 ; + union + { + int degree_next ; /* next column, if col is in a degree list */ + int hash_next ; /* next column, if col is in a hash list */ + } shared4 ; + +} Colamd_Col ; + +typedef struct Colamd_Row_struct +{ + int start ; /* index for A of first col in this row */ + int length ; /* number of principal columns in this row */ + union + { + int degree ; /* number of principal & non-principal columns in row */ + int p ; /* used as a row pointer in init_rows_cols () */ + } shared1 ; + union + { + int mark ; /* for computing set differences and marking dead rows*/ + int first_column ;/* first column in row (used in garbage collection) */ + } shared2 ; + +} Colamd_Row ; + +/* ========================================================================== */ +/* === Colamd recommended memory size ======================================= */ +/* ========================================================================== */ + +/* + The recommended length Alen of the array A passed to colamd is given by + the COLAMD_RECOMMENDED (nnz, n_row, n_col) macro. It returns -1 if any + argument is negative. 2*nnz space is required for the row and column + indices of the matrix. COLAMD_C (n_col) + COLAMD_R (n_row) space is + required for the Col and Row arrays, respectively, which are internal to + colamd. An additional n_col space is the minimal amount of "elbow room", + and nnz/5 more space is recommended for run time efficiency. + + This macro is not needed when using symamd. + + Explicit typecast to int added Sept. 23, 2002, COLAMD version 2.2, to avoid + gcc -pedantic warning messages. +*/ + +#define COLAMD_C(n_col) ((int) (((n_col) + 1) * sizeof (Colamd_Col) / sizeof (int))) +#define COLAMD_R(n_row) ((int) (((n_row) + 1) * sizeof (Colamd_Row) / sizeof (int))) + +#define COLAMD_RECOMMENDED(nnz, n_row, n_col) \ +( \ +((nnz) < 0 || (n_row) < 0 || (n_col) < 0) \ +? \ + (-1) \ +: \ + (2 * (nnz) + COLAMD_C (n_col) + COLAMD_R (n_row) + (n_col) + ((nnz) / 5)) \ +) + +/* ========================================================================== */ +/* === Prototypes of user-callable routines ================================= */ +/* ========================================================================== */ + +int colamd_recommended /* returns recommended value of Alen, */ + /* or (-1) if input arguments are erroneous */ +( + int nnz, /* nonzeros in A */ + int n_row, /* number of rows in A */ + int n_col /* number of columns in A */ +) ; + +void colamd_set_defaults /* sets default parameters */ +( /* knobs argument is modified on output */ + double knobs [COLAMD_KNOBS] /* parameter settings for colamd */ +) ; + +int colamd /* returns (1) if successful, (0) otherwise*/ +( /* A and p arguments are modified on output */ + int n_row, /* number of rows in A */ + int n_col, /* number of columns in A */ + int Alen, /* size of the array A */ + int A [], /* row indices of A, of size Alen */ + int p [], /* column pointers of A, of size n_col+1 */ + double knobs [COLAMD_KNOBS],/* parameter settings for colamd */ + int stats [COLAMD_STATS] /* colamd output statistics and error codes */ +) ; + +int symamd /* return (1) if OK, (0) otherwise */ +( + int n, /* number of rows and columns of A */ + int A [], /* row indices of A */ + int p [], /* column pointers of A */ + int perm [], /* output permutation, size n_col+1 */ + double knobs [COLAMD_KNOBS], /* parameters (uses defaults if NULL) */ + int stats [COLAMD_STATS], /* output statistics and error codes */ + void * (*allocate) (size_t, size_t), + /* pointer to calloc (ANSI C) or */ + /* mxCalloc (for MATLAB mexFunction) */ + void (*release) (void *) + /* pointer to free (ANSI C) or */ + /* mxFree (for MATLAB mexFunction) */ +) ; + +void colamd_report +( + int stats [COLAMD_STATS] +) ; + +void symamd_report +( + int stats [COLAMD_STATS] +) ; + +#endif /* COLAMD_H */ diff --git a/src/Libraries/superlu-5.2.1/SRC/cpanel_bmod.c b/src/Libraries/superlu-5.2.1/SRC/cpanel_bmod.c new file mode 100644 index 00000000..fdb9696b --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cpanel_bmod.c @@ -0,0 +1,494 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cpanel_bmod.c + * \brief Performs numeric block updates + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ +/* + +*/ + +#include +#include +#include "slu_cdefs.h" + +/* + * Function prototypes + */ +void clsolve(int, int, complex *, complex *); +void cmatvec(int, int, int, complex *, complex *, complex *); +extern void ccheck_tempv(); + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *    Performs numeric block updates (sup-panel) in topological order.
+ *    It features: col-col, 2cols-col, 3cols-col, and sup-col updates.
+ *    Special processing on the supernodal portion of L\U[*,j]
+ *
+ *    Before entering this routine, the original nonzeros in the panel 
+ *    were already copied into the spa[m,w].
+ *
+ *    Updated/Output parameters-
+ *    dense[0:m-1,w]: L[*,j:j+w-1] and U[*,j:j+w-1] are returned 
+ *    collectively in the m-by-w vector dense[*]. 
+ * 
+ */ + +void +cpanel_bmod ( + const int m, /* in - number of rows in the matrix */ + const int w, /* in */ + const int jcol, /* in */ + const int nseg, /* in */ + complex *dense, /* out, of size n by w */ + complex *tempv, /* working array */ + int *segrep, /* in */ + int *repfnz, /* in, of size n by w */ + GlobalLU_t *Glu, /* modified */ + SuperLUStat_t *stat /* output */ + ) +{ + + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + int incx = 1, incy = 1; + complex alpha, beta; +#endif + + register int k, ksub; + int fsupc, nsupc, nsupr, nrow; + int krep, krep_ind; + complex ukj, ukj1, ukj2; + int luptr, luptr1, luptr2; + int segsze; + int block_nrow; /* no of rows in a block row */ + register int lptr; /* Points to the row subscripts of a supernode */ + int kfnz, irow, no_zeros; + register int isub, isub1, i; + register int jj; /* Index through each column in the panel */ + int *xsup, *supno; + int *lsub, *xlsub; + complex *lusup; + int *xlusup; + int *repfnz_col; /* repfnz[] for a column in the panel */ + complex *dense_col; /* dense[] for a column in the panel */ + complex *tempv1; /* Used in 1-D update */ + complex *TriTmp, *MatvecTmp; /* used in 2-D update */ + complex zero = {0.0, 0.0}; + complex one = {1.0, 0.0}; + complex comp_temp, comp_temp1; + register int ldaTmp; + register int r_ind, r_hi; + int maxsuper, rowblk, colblk; + flops_t *ops = stat->ops; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (complex *) Glu->lusup; + xlusup = Glu->xlusup; + + maxsuper = SUPERLU_MAX( sp_ienv(3), sp_ienv(7) ); + rowblk = sp_ienv(4); + colblk = sp_ienv(5); + ldaTmp = maxsuper + rowblk; + + /* + * For each nonz supernode segment of U[*,j] in topological order + */ + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { /* for each updating supernode */ + + /* krep = representative of current k-th supernode + * fsupc = first supernodal column + * nsupc = no of columns in a supernode + * nsupr = no of rows in a supernode + */ + krep = segrep[k--]; + fsupc = xsup[supno[krep]]; + nsupc = krep - fsupc + 1; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; + nrow = nsupr - nsupc; + lptr = xlsub[fsupc]; + krep_ind = lptr + nsupc - 1; + + repfnz_col = repfnz; + dense_col = dense; + + if ( nsupc >= colblk && nrow > rowblk ) { /* 2-D block update */ + + TriTmp = tempv; + + /* Sequence through each column in panel -- triangular solves */ + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m, TriTmp += ldaTmp ) { + + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + luptr = xlusup[fsupc]; + + ops[TRSV] += 4 * segsze * (segsze - 1); + ops[GEMV] += 8 * nrow * segsze; + + /* Case 1: Update U-segment of size 1 -- col-col update */ + if ( segsze == 1 ) { + ukj = dense_col[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc; + + for (i = lptr + nsupc; i < xlsub[fsupc+1]; i++) { + irow = lsub[i]; + cc_mult(&comp_temp, &ukj, &lusup[luptr]); + c_sub(&dense_col[irow], &dense_col[irow], &comp_temp); + ++luptr; + } + + } else if ( segsze <= 3 ) { + ukj = dense_col[lsub[krep_ind]]; + ukj1 = dense_col[lsub[krep_ind - 1]]; + luptr += nsupr*(nsupc-1) + nsupc-1; + luptr1 = luptr - nsupr; + + if ( segsze == 2 ) { + cc_mult(&comp_temp, &ukj1, &lusup[luptr1]); + c_sub(&ukj, &ukj, &comp_temp); + dense_col[lsub[krep_ind]] = ukj; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; luptr1++; + cc_mult(&comp_temp, &ukj, &lusup[luptr]); + cc_mult(&comp_temp1, &ukj1, &lusup[luptr1]); + c_add(&comp_temp, &comp_temp, &comp_temp1); + c_sub(&dense_col[irow], &dense_col[irow], &comp_temp); + } + } else { + ukj2 = dense_col[lsub[krep_ind - 2]]; + luptr2 = luptr1 - nsupr; + cc_mult(&comp_temp, &ukj2, &lusup[luptr2-1]); + c_sub(&ukj1, &ukj1, &comp_temp); + + cc_mult(&comp_temp, &ukj1, &lusup[luptr1]); + cc_mult(&comp_temp1, &ukj2, &lusup[luptr2]); + c_add(&comp_temp, &comp_temp, &comp_temp1); + c_sub(&ukj, &ukj, &comp_temp); + dense_col[lsub[krep_ind]] = ukj; + dense_col[lsub[krep_ind-1]] = ukj1; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; luptr1++; luptr2++; + cc_mult(&comp_temp, &ukj, &lusup[luptr]); + cc_mult(&comp_temp1, &ukj1, &lusup[luptr1]); + c_add(&comp_temp, &comp_temp, &comp_temp1); + cc_mult(&comp_temp1, &ukj2, &lusup[luptr2]); + c_add(&comp_temp, &comp_temp, &comp_temp1); + c_sub(&dense_col[irow], &dense_col[irow], &comp_temp); + } + } + + } else { /* segsze >= 4 */ + + /* Copy U[*,j] segment from dense[*] to TriTmp[*], which + holds the result of triangular solves. */ + no_zeros = kfnz - fsupc; + isub = lptr + no_zeros; + for (i = 0; i < segsze; ++i) { + irow = lsub[isub]; + TriTmp[i] = dense_col[irow]; /* Gather */ + ++isub; + } + + /* start effective triangle */ + luptr += nsupr * no_zeros + no_zeros; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + CTRSV( ftcs1, ftcs2, ftcs3, &segsze, &lusup[luptr], + &nsupr, TriTmp, &incx ); +#else + ctrsv_( "L", "N", "U", &segsze, &lusup[luptr], + &nsupr, TriTmp, &incx ); +#endif +#else + clsolve ( nsupr, segsze, &lusup[luptr], TriTmp ); +#endif + + + } /* else ... */ + + } /* for jj ... end tri-solves */ + + /* Block row updates; push all the way into dense[*] block */ + for ( r_ind = 0; r_ind < nrow; r_ind += rowblk ) { + + r_hi = SUPERLU_MIN(nrow, r_ind + rowblk); + block_nrow = SUPERLU_MIN(rowblk, r_hi - r_ind); + luptr = xlusup[fsupc] + nsupc + r_ind; + isub1 = lptr + nsupc + r_ind; + + repfnz_col = repfnz; + TriTmp = tempv; + dense_col = dense; + + /* Sequence through each column in panel -- matrix-vector */ + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m, TriTmp += ldaTmp) { + + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + if ( segsze <= 3 ) continue; /* skip unrolled cases */ + + /* Perform a block update, and scatter the result of + matrix-vector to dense[]. */ + no_zeros = kfnz - fsupc; + luptr1 = luptr + nsupr * no_zeros; + MatvecTmp = &TriTmp[maxsuper]; + +#ifdef USE_VENDOR_BLAS + alpha = one; + beta = zero; +#ifdef _CRAY + CGEMV(ftcs2, &block_nrow, &segsze, &alpha, &lusup[luptr1], + &nsupr, TriTmp, &incx, &beta, MatvecTmp, &incy); +#else + cgemv_("N", &block_nrow, &segsze, &alpha, &lusup[luptr1], + &nsupr, TriTmp, &incx, &beta, MatvecTmp, &incy); +#endif +#else + cmatvec(nsupr, block_nrow, segsze, &lusup[luptr1], + TriTmp, MatvecTmp); +#endif + + /* Scatter MatvecTmp[*] into SPA dense[*] temporarily + * such that MatvecTmp[*] can be re-used for the + * the next blok row update. dense[] will be copied into + * global store after the whole panel has been finished. + */ + isub = isub1; + for (i = 0; i < block_nrow; i++) { + irow = lsub[isub]; + c_sub(&dense_col[irow], &dense_col[irow], + &MatvecTmp[i]); + MatvecTmp[i] = zero; + ++isub; + } + + } /* for jj ... */ + + } /* for each block row ... */ + + /* Scatter the triangular solves into SPA dense[*] */ + repfnz_col = repfnz; + TriTmp = tempv; + dense_col = dense; + + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m, TriTmp += ldaTmp) { + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + if ( segsze <= 3 ) continue; /* skip unrolled cases */ + + no_zeros = kfnz - fsupc; + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + dense_col[irow] = TriTmp[i]; + TriTmp[i] = zero; + ++isub; + } + + } /* for jj ... */ + + } else { /* 1-D block modification */ + + + /* Sequence through each column in the panel */ + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m) { + + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + luptr = xlusup[fsupc]; + + ops[TRSV] += 4 * segsze * (segsze - 1); + ops[GEMV] += 8 * nrow * segsze; + + /* Case 1: Update U-segment of size 1 -- col-col update */ + if ( segsze == 1 ) { + ukj = dense_col[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc; + + for (i = lptr + nsupc; i < xlsub[fsupc+1]; i++) { + irow = lsub[i]; + cc_mult(&comp_temp, &ukj, &lusup[luptr]); + c_sub(&dense_col[irow], &dense_col[irow], &comp_temp); + ++luptr; + } + + } else if ( segsze <= 3 ) { + ukj = dense_col[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc-1; + ukj1 = dense_col[lsub[krep_ind - 1]]; + luptr1 = luptr - nsupr; + + if ( segsze == 2 ) { + cc_mult(&comp_temp, &ukj1, &lusup[luptr1]); + c_sub(&ukj, &ukj, &comp_temp); + dense_col[lsub[krep_ind]] = ukj; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + ++luptr; ++luptr1; + cc_mult(&comp_temp, &ukj, &lusup[luptr]); + cc_mult(&comp_temp1, &ukj1, &lusup[luptr1]); + c_add(&comp_temp, &comp_temp, &comp_temp1); + c_sub(&dense_col[irow], &dense_col[irow], &comp_temp); + } + } else { + ukj2 = dense_col[lsub[krep_ind - 2]]; + luptr2 = luptr1 - nsupr; + cc_mult(&comp_temp, &ukj2, &lusup[luptr2-1]); + c_sub(&ukj1, &ukj1, &comp_temp); + + cc_mult(&comp_temp, &ukj1, &lusup[luptr1]); + cc_mult(&comp_temp1, &ukj2, &lusup[luptr2]); + c_add(&comp_temp, &comp_temp, &comp_temp1); + c_sub(&ukj, &ukj, &comp_temp); + dense_col[lsub[krep_ind]] = ukj; + dense_col[lsub[krep_ind-1]] = ukj1; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + ++luptr; ++luptr1; ++luptr2; + cc_mult(&comp_temp, &ukj, &lusup[luptr]); + cc_mult(&comp_temp1, &ukj1, &lusup[luptr1]); + c_add(&comp_temp, &comp_temp, &comp_temp1); + cc_mult(&comp_temp1, &ukj2, &lusup[luptr2]); + c_add(&comp_temp, &comp_temp, &comp_temp1); + c_sub(&dense_col[irow], &dense_col[irow], &comp_temp); + } + } + + } else { /* segsze >= 4 */ + /* + * Perform a triangular solve and block update, + * then scatter the result of sup-col update to dense[]. + */ + no_zeros = kfnz - fsupc; + + /* Copy U[*,j] segment from dense[*] to tempv[*]: + * The result of triangular solve is in tempv[*]; + * The result of matrix vector update is in dense_col[*] + */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; ++i) { + irow = lsub[isub]; + tempv[i] = dense_col[irow]; /* Gather */ + ++isub; + } + + /* start effective triangle */ + luptr += nsupr * no_zeros + no_zeros; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + CTRSV( ftcs1, ftcs2, ftcs3, &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#else + ctrsv_( "L", "N", "U", &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#endif + + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + alpha = one; + beta = zero; +#ifdef _CRAY + CGEMV( ftcs2, &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#else + cgemv_( "N", &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#endif +#else + clsolve ( nsupr, segsze, &lusup[luptr], tempv ); + + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + cmatvec (nsupr, nrow, segsze, &lusup[luptr], tempv, tempv1); +#endif + + /* Scatter tempv[*] into SPA dense[*] temporarily, such + * that tempv[*] can be used for the triangular solve of + * the next column of the panel. They will be copied into + * ucol[*] after the whole panel has been finished. + */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + dense_col[irow] = tempv[i]; + tempv[i] = zero; + isub++; + } + + /* Scatter the update from tempv1[*] into SPA dense[*] */ + /* Start dense rectangular L */ + for (i = 0; i < nrow; i++) { + irow = lsub[isub]; + c_sub(&dense_col[irow], &dense_col[irow], &tempv1[i]); + tempv1[i] = zero; + ++isub; + } + + } /* else segsze>=4 ... */ + + } /* for each column in the panel... */ + + } /* else 1-D update ... */ + + } /* for each updating supernode ... */ + +} + + + diff --git a/src/Libraries/superlu-5.2.1/SRC/cpanel_dfs.c b/src/Libraries/superlu-5.2.1/SRC/cpanel_dfs.c new file mode 100644 index 00000000..988dad7b --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cpanel_dfs.c @@ -0,0 +1,264 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cpanel_dfs.c + * \brief Peforms a symbolic factorization on a panel of symbols + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_cdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *   Performs a symbolic factorization on a panel of columns [jcol, jcol+w).
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives.
+ *
+ *   The routine returns one list of the supernodal representatives
+ *   in topological order of the dfs that generates them. This list is
+ *   a superset of the topological order of each individual column within
+ *   the panel. 
+ *   The location of the first nonzero in each supernodal segment
+ *   (supernodal entry location) is also returned. Each column has a 
+ *   separate list for this purpose.
+ *
+ *   Two marker arrays are used for dfs:
+ *     marker[i] == jj, if i was visited during dfs of current column jj;
+ *     marker1[i] >= jcol, if i was visited by earlier columns in this panel;
+ *
+ *   marker: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ * 
+ */ + +void +cpanel_dfs ( + const int m, /* in - number of rows in the matrix */ + const int w, /* in */ + const int jcol, /* in */ + SuperMatrix *A, /* in - original matrix */ + int *perm_r, /* in */ + int *nseg, /* out */ + complex *dense, /* out */ + int *panel_lsub, /* out */ + int *segrep, /* out */ + int *repfnz, /* out */ + int *xprune, /* out */ + int *marker, /* out */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ + ) +{ + + NCPformat *Astore; + complex *a; + int *asub; + int *xa_begin, *xa_end; + int krep, chperm, chmark, chrep, oldrep, kchild, myfnz; + int k, krow, kmark, kperm; + int xdfs, maxdfs, kpar; + int jj; /* index through each column in the panel */ + int *marker1; /* marker1[jj] >= jcol if vertex jj was visited + by a previous column within this panel. */ + int *repfnz_col; /* start of each column in the panel */ + complex *dense_col; /* start of each column in the panel */ + int nextl_col; /* next available position in panel_lsub[*,jj] */ + int *xsup, *supno; + int *lsub, *xlsub; + + /* Initialize pointers */ + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + marker1 = marker + m; + repfnz_col = repfnz; + dense_col = dense; + *nseg = 0; + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + + /* For each column in the panel */ + for (jj = jcol; jj < jcol + w; jj++) { + nextl_col = (jj - jcol) * m; + +#ifdef CHK_DFS + printf("\npanel col %d: ", jj); +#endif + + /* For each nonz in A[*,jj] do dfs */ + for (k = xa_begin[jj]; k < xa_end[jj]; k++) { + krow = asub[k]; + dense_col[krow] = a[k]; + kmark = marker[krow]; + if ( kmark == jj ) + continue; /* krow visited before, go to the next nonzero */ + + /* For each unmarked nbr krow of jj + * krow is in L: place it in structure of L[*,jj] + */ + marker[krow] = jj; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + panel_lsub[nextl_col++] = krow; /* krow is indexed into A */ + } + /* + * krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + else { + + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz_col[krep]; + +#ifdef CHK_DFS + printf("krep %d, myfnz %d, perm_r[%d] %d\n", krep, myfnz, krow, kperm); +#endif + if ( myfnz != EMPTY ) { /* Representative visited before */ + if ( myfnz > kperm ) repfnz_col[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz_col[krep] = kperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; + +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker[kchild]; + + if ( chmark != jj ) { /* Not reached yet */ + marker[kchild] = jj; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,j] */ + if ( chperm == EMPTY ) { + panel_lsub[nextl_col++] = kchild; + } + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + else { + + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz_col[chrep]; +#ifdef CHK_DFS + printf("chrep %d,myfnz %d,perm_r[%d] %d\n",chrep,myfnz,kchild,chperm); +#endif + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz_col[chrep] = chperm; + } + else { + /* Cont. dfs at snode-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L) */ + parent[krep] = oldrep; + repfnz_col[krep] = chperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } /* else */ + + } /* else */ + + } /* if... */ + + } /* while xdfs < maxdfs */ + + /* krow has no more unexplored nbrs: + * Place snode-rep krep in postorder DFS, if this + * segment is seen for the first time. (Note that + * "repfnz[krep]" may change later.) + * Backtrack dfs to its parent. + */ + if ( marker1[krep] < jcol ) { + segrep[*nseg] = krep; + ++(*nseg); + marker1[krep] = jj; + } + + kpar = parent[krep]; /* Pop stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xprune[krep]; + +#ifdef CHK_DFS + printf(" pop stack: krep %d,xdfs %d,maxdfs %d: ", krep,xdfs,maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } while ( kpar != EMPTY ); /* do-while - until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonz in A[*,jj] */ + + repfnz_col += m; /* Move to next column */ + dense_col += m; + + } /* for jj ... */ + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/cpivotL.c b/src/Libraries/superlu-5.2.1/SRC/cpivotL.c new file mode 100644 index 00000000..46bf8e93 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cpivotL.c @@ -0,0 +1,195 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cpivotL.c + * \brief Performs numerical pivoting + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include +#include +#include "slu_cdefs.h" + +#undef DEBUG + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   Performs the numerical pivoting on the current column of L,
+ *   and the CDIV operation.
+ *
+ *   Pivot policy:
+ *   (1) Compute thresh = u * max_(i>=j) abs(A_ij);
+ *   (2) IF user specifies pivot row k and abs(A_kj) >= thresh THEN
+ *           pivot row = k;
+ *       ELSE IF abs(A_jj) >= thresh THEN
+ *           pivot row = j;
+ *       ELSE
+ *           pivot row = m;
+ * 
+ *   Note: If you absolutely want to use a given pivot order, then set u=0.0.
+ *
+ *   Return value: 0      success;
+ *                 i > 0  U(i,i) is exactly zero.
+ * 
+ */ + +int +cpivotL( + const int jcol, /* in */ + const double u, /* in - diagonal pivoting threshold */ + int *usepr, /* re-use the pivot sequence given by perm_r/iperm_r */ + int *perm_r, /* may be modified */ + int *iperm_r, /* in - inverse of perm_r */ + int *iperm_c, /* in - used to find diagonal of Pc*A*Pc' */ + int *pivrow, /* out */ + GlobalLU_t *Glu, /* modified - global LU data structures */ + SuperLUStat_t *stat /* output */ + ) +{ + + complex one = {1.0, 0.0}; + int fsupc; /* first column in the supernode */ + int nsupc; /* no of columns in the supernode */ + int nsupr; /* no of rows in the supernode */ + int lptr; /* points to the starting subscript of the supernode */ + int pivptr, old_pivptr, diag, diagind; + float pivmax, rtemp, thresh; + complex temp; + complex *lu_sup_ptr; + complex *lu_col_ptr; + int *lsub_ptr; + int isub, icol, k, itemp; + int *lsub, *xlsub; + complex *lusup; + int *xlusup; + flops_t *ops = stat->ops; + + /* Initialize pointers */ + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (complex *) Glu->lusup; + xlusup = Glu->xlusup; + fsupc = (Glu->xsup)[(Glu->supno)[jcol]]; + nsupc = jcol - fsupc; /* excluding jcol; nsupc >= 0 */ + lptr = xlsub[fsupc]; + nsupr = xlsub[fsupc+1] - lptr; + lu_sup_ptr = &lusup[xlusup[fsupc]]; /* start of the current supernode */ + lu_col_ptr = &lusup[xlusup[jcol]]; /* start of jcol in the supernode */ + lsub_ptr = &lsub[lptr]; /* start of row indices of the supernode */ + +#ifdef DEBUG +if ( jcol == MIN_COL ) { + printf("Before cdiv: col %d\n", jcol); + for (k = nsupc; k < nsupr; k++) + printf(" lu[%d] %f\n", lsub_ptr[k], lu_col_ptr[k]); +} +#endif + + /* Determine the largest abs numerical value for partial pivoting; + Also search for user-specified pivot, and diagonal element. */ + if ( *usepr ) *pivrow = iperm_r[jcol]; + diagind = iperm_c[jcol]; + pivmax = 0.0; + pivptr = nsupc; + diag = EMPTY; + old_pivptr = nsupc; + for (isub = nsupc; isub < nsupr; ++isub) { + rtemp = c_abs1 (&lu_col_ptr[isub]); + if ( rtemp > pivmax ) { + pivmax = rtemp; + pivptr = isub; + } + if ( *usepr && lsub_ptr[isub] == *pivrow ) old_pivptr = isub; + if ( lsub_ptr[isub] == diagind ) diag = isub; + } + + /* Test for singularity */ + if ( pivmax == 0.0 ) { +#if 1 + *pivrow = lsub_ptr[pivptr]; + perm_r[*pivrow] = jcol; +#else + perm_r[diagind] = jcol; +#endif + *usepr = 0; + return (jcol+1); + } + + thresh = u * pivmax; + + /* Choose appropriate pivotal element by our policy. */ + if ( *usepr ) { + rtemp = c_abs1 (&lu_col_ptr[old_pivptr]); + if ( rtemp != 0.0 && rtemp >= thresh ) + pivptr = old_pivptr; + else + *usepr = 0; + } + if ( *usepr == 0 ) { + /* Use diagonal pivot? */ + if ( diag >= 0 ) { /* diagonal exists */ + rtemp = c_abs1 (&lu_col_ptr[diag]); + if ( rtemp != 0.0 && rtemp >= thresh ) pivptr = diag; + } + *pivrow = lsub_ptr[pivptr]; + } + + /* Record pivot row */ + perm_r[*pivrow] = jcol; + + /* Interchange row subscripts */ + if ( pivptr != nsupc ) { + itemp = lsub_ptr[pivptr]; + lsub_ptr[pivptr] = lsub_ptr[nsupc]; + lsub_ptr[nsupc] = itemp; + + /* Interchange numerical values as well, for the whole snode, such + * that L is indexed the same way as A. + */ + for (icol = 0; icol <= nsupc; icol++) { + itemp = pivptr + icol * nsupr; + temp = lu_sup_ptr[itemp]; + lu_sup_ptr[itemp] = lu_sup_ptr[nsupc + icol*nsupr]; + lu_sup_ptr[nsupc + icol*nsupr] = temp; + } + } /* if */ + + /* cdiv operation */ + ops[FACT] += 10 * (nsupr - nsupc); + + c_div(&temp, &one, &lu_col_ptr[nsupc]); + for (k = nsupc+1; k < nsupr; k++) + cc_mult(&lu_col_ptr[k], &lu_col_ptr[k], &temp); + + return 0; +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/cpivotgrowth.c b/src/Libraries/superlu-5.2.1/SRC/cpivotgrowth.c new file mode 100644 index 00000000..8f3a1294 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cpivotgrowth.c @@ -0,0 +1,124 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cpivotgrowth.c + * \brief Computes the reciprocal pivot growth factor + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ */ +#include +#include "slu_cdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * Compute the reciprocal pivot growth factor of the leading ncols columns
+ * of the matrix, using the formula:
+ *     min_j ( max_i(abs(A_ij)) / max_i(abs(U_ij)) )
+ *
+ * Arguments
+ * =========
+ *
+ * ncols    (input) int
+ *          The number of columns of matrices A, L and U.
+ *
+ * A        (input) SuperMatrix*
+ *	    Original matrix A, permuted by columns, of dimension
+ *          (A->nrow, A->ncol). The type of A can be:
+ *          Stype = NC; Dtype = SLU_C; Mtype = GE.
+ *
+ * L        (output) SuperMatrix*
+ *          The factor L from the factorization Pr*A=L*U; use compressed row 
+ *          subscripts storage for supernodes, i.e., L has type: 
+ *          Stype = SC; Dtype = SLU_C; Mtype = TRLU.
+ *
+ * U        (output) SuperMatrix*
+ *	    The factor U from the factorization Pr*A*Pc=L*U. Use column-wise
+ *          storage scheme, i.e., U has types: Stype = NC;
+ *          Dtype = SLU_C; Mtype = TRU.
+ * 
+ */ + +float +cPivotGrowth(int ncols, SuperMatrix *A, int *perm_c, + SuperMatrix *L, SuperMatrix *U) +{ + + NCformat *Astore; + SCformat *Lstore; + NCformat *Ustore; + complex *Aval, *Lval, *Uval; + int fsupc, nsupr, luptr, nz_in_U; + int i, j, k, oldcol; + int *inv_perm_c; + float rpg, maxaj, maxuj; + float smlnum; + complex *luval; + complex temp_comp; + + /* Get machine constants. */ + smlnum = smach("S"); + rpg = 1. / smlnum; + + Astore = A->Store; + Lstore = L->Store; + Ustore = U->Store; + Aval = Astore->nzval; + Lval = Lstore->nzval; + Uval = Ustore->nzval; + + inv_perm_c = (int *) SUPERLU_MALLOC(A->ncol*sizeof(int)); + for (j = 0; j < A->ncol; ++j) inv_perm_c[perm_c[j]] = j; + + for (k = 0; k <= Lstore->nsuper; ++k) { + fsupc = L_FST_SUPC(k); + nsupr = L_SUB_START(fsupc+1) - L_SUB_START(fsupc); + luptr = L_NZ_START(fsupc); + luval = &Lval[luptr]; + nz_in_U = 1; + + for (j = fsupc; j < L_FST_SUPC(k+1) && j < ncols; ++j) { + maxaj = 0.; + oldcol = inv_perm_c[j]; + for (i = Astore->colptr[oldcol]; i < Astore->colptr[oldcol+1]; ++i) + maxaj = SUPERLU_MAX( maxaj, c_abs1( &Aval[i]) ); + + maxuj = 0.; + for (i = Ustore->colptr[j]; i < Ustore->colptr[j+1]; i++) + maxuj = SUPERLU_MAX( maxuj, c_abs1( &Uval[i]) ); + + /* Supernode */ + for (i = 0; i < nz_in_U; ++i) + maxuj = SUPERLU_MAX( maxuj, c_abs1( &luval[i]) ); + + ++nz_in_U; + luval += nsupr; + + if ( maxuj == 0. ) + rpg = SUPERLU_MIN( rpg, 1.); + else + rpg = SUPERLU_MIN( rpg, maxaj / maxuj ); + } + + if ( j >= ncols ) break; + } + + SUPERLU_FREE(inv_perm_c); + return (rpg); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/cpruneL.c b/src/Libraries/superlu-5.2.1/SRC/cpruneL.c new file mode 100644 index 00000000..08169203 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cpruneL.c @@ -0,0 +1,164 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cpruneL.c + * \brief Prunes the L-structure + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ *
+ */ + + +#include "slu_cdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   Prunes the L-structure of supernodes whose L-structure
+ *   contains the current pivot row "pivrow"
+ * 
+ */ + +void +cpruneL( + const int jcol, /* in */ + const int *perm_r, /* in */ + const int pivrow, /* in */ + const int nseg, /* in */ + const int *segrep, /* in */ + const int *repfnz, /* in */ + int *xprune, /* out */ + GlobalLU_t *Glu /* modified - global LU data structures */ + ) +{ + + complex utemp; + int jsupno, irep, irep1, kmin, kmax, krow, movnum; + int i, ktemp, minloc, maxloc; + int do_prune; /* logical variable */ + int *xsup, *supno; + int *lsub, *xlsub; + complex *lusup; + int *xlusup; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (complex *) Glu->lusup; + xlusup = Glu->xlusup; + + /* + * For each supernode-rep irep in U[*,j] + */ + jsupno = supno[jcol]; + for (i = 0; i < nseg; i++) { + + irep = segrep[i]; + irep1 = irep + 1; + do_prune = FALSE; + + /* Don't prune with a zero U-segment */ + if ( repfnz[irep] == EMPTY ) + continue; + + /* If a snode overlaps with the next panel, then the U-segment + * is fragmented into two parts -- irep and irep1. We should let + * pruning occur at the rep-column in irep1's snode. + */ + if ( supno[irep] == supno[irep1] ) /* Don't prune */ + continue; + + /* + * If it has not been pruned & it has a nonz in row L[pivrow,i] + */ + if ( supno[irep] != jsupno ) { + if ( xprune[irep] >= xlsub[irep1] ) { + kmin = xlsub[irep]; + kmax = xlsub[irep1] - 1; + for (krow = kmin; krow <= kmax; krow++) + if ( lsub[krow] == pivrow ) { + do_prune = TRUE; + break; + } + } + + if ( do_prune ) { + + /* Do a quicksort-type partition + * movnum=TRUE means that the num values have to be exchanged. + */ + movnum = FALSE; + if ( irep == xsup[supno[irep]] ) /* Snode of size 1 */ + movnum = TRUE; + + while ( kmin <= kmax ) { + + if ( perm_r[lsub[kmax]] == EMPTY ) + kmax--; + else if ( perm_r[lsub[kmin]] != EMPTY ) + kmin++; + else { /* kmin below pivrow (not yet pivoted), and kmax + * above pivrow: interchange the two subscripts + */ + ktemp = lsub[kmin]; + lsub[kmin] = lsub[kmax]; + lsub[kmax] = ktemp; + + /* If the supernode has only one column, then we + * only keep one set of subscripts. For any subscript + * interchange performed, similar interchange must be + * done on the numerical values. + */ + if ( movnum ) { + minloc = xlusup[irep] + (kmin - xlsub[irep]); + maxloc = xlusup[irep] + (kmax - xlsub[irep]); + utemp = lusup[minloc]; + lusup[minloc] = lusup[maxloc]; + lusup[maxloc] = utemp; + } + + kmin++; + kmax--; + + } + + } /* while */ + + xprune[irep] = kmin; /* Pruning */ + +#ifdef CHK_PRUNE + printf(" After cpruneL(),using col %d: xprune[%d] = %d\n", + jcol, irep, kmin); +#endif + } /* if do_prune */ + + } /* if */ + + } /* for each U-segment... */ +} diff --git a/src/Libraries/superlu-5.2.1/SRC/creadhb.c b/src/Libraries/superlu-5.2.1/SRC/creadhb.c new file mode 100644 index 00000000..b5b61ecd --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/creadhb.c @@ -0,0 +1,379 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file creadhb.c + * \brief Read a matrix stored in Harwell-Boeing format + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Purpose
+ * =======
+ * 
+ * Read a COMPLEX PRECISION matrix stored in Harwell-Boeing format 
+ * as described below.
+ * 
+ * Line 1 (A72,A8) 
+ *  	Col. 1 - 72   Title (TITLE) 
+ *	Col. 73 - 80  Key (KEY) 
+ * 
+ * Line 2 (5I14) 
+ * 	Col. 1 - 14   Total number of lines excluding header (TOTCRD) 
+ * 	Col. 15 - 28  Number of lines for pointers (PTRCRD) 
+ * 	Col. 29 - 42  Number of lines for row (or variable) indices (INDCRD) 
+ * 	Col. 43 - 56  Number of lines for numerical values (VALCRD) 
+ *	Col. 57 - 70  Number of lines for right-hand sides (RHSCRD) 
+ *                    (including starting guesses and solution vectors 
+ *		       if present) 
+ *           	      (zero indicates no right-hand side data is present) 
+ *
+ * Line 3 (A3, 11X, 4I14) 
+ *   	Col. 1 - 3    Matrix type (see below) (MXTYPE) 
+ * 	Col. 15 - 28  Number of rows (or variables) (NROW) 
+ * 	Col. 29 - 42  Number of columns (or elements) (NCOL) 
+ *	Col. 43 - 56  Number of row (or variable) indices (NNZERO) 
+ *	              (equal to number of entries for assembled matrices) 
+ * 	Col. 57 - 70  Number of elemental matrix entries (NELTVL) 
+ *	              (zero in the case of assembled matrices) 
+ * Line 4 (2A16, 2A20) 
+ * 	Col. 1 - 16   Format for pointers (PTRFMT) 
+ *	Col. 17 - 32  Format for row (or variable) indices (INDFMT) 
+ *	Col. 33 - 52  Format for numerical values of coefficient matrix (VALFMT) 
+ * 	Col. 53 - 72 Format for numerical values of right-hand sides (RHSFMT) 
+ *
+ * Line 5 (A3, 11X, 2I14) Only present if there are right-hand sides present 
+ *    	Col. 1 	      Right-hand side type: 
+ *	         	  F for full storage or M for same format as matrix 
+ *    	Col. 2        G if a starting vector(s) (Guess) is supplied. (RHSTYP) 
+ *    	Col. 3        X if an exact solution vector(s) is supplied. 
+ *	Col. 15 - 28  Number of right-hand sides (NRHS) 
+ *	Col. 29 - 42  Number of row indices (NRHSIX) 
+ *          	      (ignored in case of unassembled matrices) 
+ *
+ * The three character type field on line 3 describes the matrix type. 
+ * The following table lists the permitted values for each of the three 
+ * characters. As an example of the type field, RSA denotes that the matrix 
+ * is real, symmetric, and assembled. 
+ *
+ * First Character: 
+ *	R Real matrix 
+ *	C Complex matrix 
+ *	P Pattern only (no numerical values supplied) 
+ *
+ * Second Character: 
+ *	S Symmetric 
+ *	U Unsymmetric 
+ *	H Hermitian 
+ *	Z Skew symmetric 
+ *	R Rectangular 
+ *
+ * Third Character: 
+ *	A Assembled 
+ *	E Elemental matrices (unassembled) 
+ *
+ * 
+ */ +#include +#include +#include "slu_cdefs.h" + + +/*! \brief Eat up the rest of the current line */ +int cDumpLine(FILE *fp) +{ + register int c; + while ((c = fgetc(fp)) != '\n') ; + return 0; +} + +int cParseIntFormat(char *buf, int *num, int *size) +{ + char *tmp; + + tmp = buf; + while (*tmp++ != '(') ; + sscanf(tmp, "%d", num); + while (*tmp != 'I' && *tmp != 'i') ++tmp; + ++tmp; + sscanf(tmp, "%d", size); + return 0; +} + +int cParseFloatFormat(char *buf, int *num, int *size) +{ + char *tmp, *period; + + tmp = buf; + while (*tmp++ != '(') ; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + while (*tmp != 'E' && *tmp != 'e' && *tmp != 'D' && *tmp != 'd' + && *tmp != 'F' && *tmp != 'f') { + /* May find kP before nE/nD/nF, like (1P6F13.6). In this case the + num picked up refers to P, which should be skipped. */ + if (*tmp=='p' || *tmp=='P') { + ++tmp; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + } else { + ++tmp; + } + } + ++tmp; + period = tmp; + while (*period != '.' && *period != ')') ++period ; + *period = '\0'; + *size = atoi(tmp); /*sscanf(tmp, "%2d", size);*/ + + return 0; +} + +static int ReadVector(FILE *fp, int n, int *where, int perline, int persize) +{ + register int i, j, item; + char tmp, buf[100]; + + i = 0; + while (i < n) { + fgets(buf, 100, fp); /* read a line at a time */ + for (j=0; j + * On input, nonz/nzval/rowind/colptr represents lower part of a symmetric + * matrix. On exit, it represents the full matrix with lower and upper parts. + * + */ +static void +FormFullA(int n, int *nonz, complex **nzval, int **rowind, int **colptr) +{ + register int i, j, k, col, new_nnz; + int *t_rowind, *t_colptr, *al_rowind, *al_colptr, *a_rowind, *a_colptr; + int *marker; + complex *t_val, *al_val, *a_val; + + al_rowind = *rowind; + al_colptr = *colptr; + al_val = *nzval; + + if ( !(marker =(int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for marker[]"); + if ( !(t_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC t_colptr[]"); + if ( !(t_rowind = (int *) SUPERLU_MALLOC( *nonz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for t_rowind[]"); + if ( !(t_val = (complex*) SUPERLU_MALLOC( *nonz * sizeof(complex)) ) ) + ABORT("SUPERLU_MALLOC fails for t_val[]"); + + /* Get counts of each column of T, and set up column pointers */ + for (i = 0; i < n; ++i) marker[i] = 0; + for (j = 0; j < n; ++j) { + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) + ++marker[al_rowind[i]]; + } + t_colptr[0] = 0; + for (i = 0; i < n; ++i) { + t_colptr[i+1] = t_colptr[i] + marker[i]; + marker[i] = t_colptr[i]; + } + + /* Transpose matrix A to T */ + for (j = 0; j < n; ++j) + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + col = al_rowind[i]; + t_rowind[marker[col]] = j; + t_val[marker[col]] = al_val[i]; + ++marker[col]; + } + + new_nnz = *nonz * 2 - n; + if ( !(a_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC a_colptr[]"); + if ( !(a_rowind = (int *) SUPERLU_MALLOC( new_nnz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for a_rowind[]"); + if ( !(a_val = (complex*) SUPERLU_MALLOC( new_nnz * sizeof(complex)) ) ) + ABORT("SUPERLU_MALLOC fails for a_val[]"); + + a_colptr[0] = 0; + k = 0; + for (j = 0; j < n; ++j) { + for (i = t_colptr[j]; i < t_colptr[j+1]; ++i) { + if ( t_rowind[i] != j ) { /* not diagonal */ + a_rowind[k] = t_rowind[i]; + a_val[k] = t_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + } + + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + a_rowind[k] = al_rowind[i]; + a_val[k] = al_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + + a_colptr[j+1] = k; + } + + printf("FormFullA: new_nnz = %d, k = %d\n", new_nnz, k); + + SUPERLU_FREE(al_val); + SUPERLU_FREE(al_rowind); + SUPERLU_FREE(al_colptr); + SUPERLU_FREE(marker); + SUPERLU_FREE(t_val); + SUPERLU_FREE(t_rowind); + SUPERLU_FREE(t_colptr); + + *nzval = a_val; + *rowind = a_rowind; + *colptr = a_colptr; + *nonz = new_nnz; +} + +void +creadhb(FILE *fp, int *nrow, int *ncol, int *nonz, + complex **nzval, int **rowind, int **colptr) +{ + + register int i, numer_lines = 0, rhscrd = 0; + int tmp, colnum, colsize, rownum, rowsize, valnum, valsize; + char buf[100], type[4], key[10]; + int sym; + + /* Line 1 */ + fgets(buf, 100, fp); + fputs(buf, stdout); +#if 0 + fscanf(fp, "%72c", buf); buf[72] = 0; + printf("Title: %s", buf); + fscanf(fp, "%8c", key); key[8] = 0; + printf("Key: %s\n", key); + cDumpLine(fp); +#endif + + /* Line 2 */ + for (i=0; i<5; i++) { + fscanf(fp, "%14c", buf); buf[14] = 0; + sscanf(buf, "%d", &tmp); + if (i == 3) numer_lines = tmp; + if (i == 4 && tmp) rhscrd = tmp; + } + cDumpLine(fp); + + /* Line 3 */ + fscanf(fp, "%3c", type); + fscanf(fp, "%11c", buf); /* pad */ + type[3] = 0; +#ifdef DEBUG + printf("Matrix type %s\n", type); +#endif + + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nrow); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", ncol); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nonz); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", &tmp); + + if (tmp != 0) + printf("This is not an assembled matrix!\n"); + if (*nrow != *ncol) + printf("Matrix is not square.\n"); + cDumpLine(fp); + + /* Allocate storage for the three arrays ( nzval, rowind, colptr ) */ + callocateA(*ncol, *nonz, nzval, rowind, colptr); + + /* Line 4: format statement */ + fscanf(fp, "%16c", buf); + cParseIntFormat(buf, &colnum, &colsize); + fscanf(fp, "%16c", buf); + cParseIntFormat(buf, &rownum, &rowsize); + fscanf(fp, "%20c", buf); + cParseFloatFormat(buf, &valnum, &valsize); + fscanf(fp, "%20c", buf); + cDumpLine(fp); + + /* Line 5: right-hand side */ + if ( rhscrd ) cDumpLine(fp); /* skip RHSFMT */ + +#ifdef DEBUG + printf("%d rows, %d nonzeros\n", *nrow, *nonz); + printf("colnum %d, colsize %d\n", colnum, colsize); + printf("rownum %d, rowsize %d\n", rownum, rowsize); + printf("valnum %d, valsize %d\n", valnum, valsize); +#endif + + ReadVector(fp, *ncol+1, *colptr, colnum, colsize); + ReadVector(fp, *nonz, *rowind, rownum, rowsize); + if ( numer_lines ) { + cReadValues(fp, *nonz, *nzval, valnum, valsize); + } + + sym = (type[1] == 'S' || type[1] == 's'); + if ( sym ) { + FormFullA(*ncol, nonz, nzval, rowind, colptr); + } + + fclose(fp); +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/creadrb.c b/src/Libraries/superlu-5.2.1/SRC/creadrb.c new file mode 100644 index 00000000..e5c63fd3 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/creadrb.c @@ -0,0 +1,365 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file creadrb.c + * \brief Read a matrix stored in Rutherford-Boeing format + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ * + * Purpose + * ======= + * + * Read a COMPLEX PRECISION matrix stored in Rutherford-Boeing format + * as described below. + * + * Line 1 (A72, A8) + * Col. 1 - 72 Title (TITLE) + * Col. 73 - 80 Matrix name / identifier (MTRXID) + * + * Line 2 (I14, 3(1X, I13)) + * Col. 1 - 14 Total number of lines excluding header (TOTCRD) + * Col. 16 - 28 Number of lines for pointers (PTRCRD) + * Col. 30 - 42 Number of lines for row (or variable) indices (INDCRD) + * Col. 44 - 56 Number of lines for numerical values (VALCRD) + * + * Line 3 (A3, 11X, 4(1X, I13)) + * Col. 1 - 3 Matrix type (see below) (MXTYPE) + * Col. 15 - 28 Compressed Column: Number of rows (NROW) + * Elemental: Largest integer used to index variable (MVAR) + * Col. 30 - 42 Compressed Column: Number of columns (NCOL) + * Elemental: Number of element matrices (NELT) + * Col. 44 - 56 Compressed Column: Number of entries (NNZERO) + * Elemental: Number of variable indeces (NVARIX) + * Col. 58 - 70 Compressed Column: Unused, explicitly zero + * Elemental: Number of elemental matrix entries (NELTVL) + * + * Line 4 (2A16, A20) + * Col. 1 - 16 Fortran format for pointers (PTRFMT) + * Col. 17 - 32 Fortran format for row (or variable) indices (INDFMT) + * Col. 33 - 52 Fortran format for numerical values of coefficient matrix + * (VALFMT) + * (blank in the case of matrix patterns) + * + * The three character type field on line 3 describes the matrix type. + * The following table lists the permitted values for each of the three + * characters. As an example of the type field, RSA denotes that the matrix + * is real, symmetric, and assembled. + * + * First Character: + * R Real matrix + * C Complex matrix + * I integer matrix + * P Pattern only (no numerical values supplied) + * Q Pattern only (numerical values supplied in associated auxiliary value + * file) + * + * Second Character: + * S Symmetric + * U Unsymmetric + * H Hermitian + * Z Skew symmetric + * R Rectangular + * + * Third Character: + * A Compressed column form + * E Elemental form + * + * + */ + +#include +#include +#include "slu_cdefs.h" + + +/*! \brief Eat up the rest of the current line */ +static int cDumpLine(FILE *fp) +{ + register int c; + while ((c = fgetc(fp)) != '\n') ; + return 0; +} + +static int cParseIntFormat(char *buf, int *num, int *size) +{ + char *tmp; + + tmp = buf; + while (*tmp++ != '(') ; + sscanf(tmp, "%d", num); + while (*tmp != 'I' && *tmp != 'i') ++tmp; + ++tmp; + sscanf(tmp, "%d", size); + return 0; +} + +static int cParseFloatFormat(char *buf, int *num, int *size) +{ + char *tmp, *period; + + tmp = buf; + while (*tmp++ != '(') ; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + while (*tmp != 'E' && *tmp != 'e' && *tmp != 'D' && *tmp != 'd' + && *tmp != 'F' && *tmp != 'f') { + /* May find kP before nE/nD/nF, like (1P6F13.6). In this case the + num picked up refers to P, which should be skipped. */ + if (*tmp=='p' || *tmp=='P') { + ++tmp; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + } else { + ++tmp; + } + } + ++tmp; + period = tmp; + while (*period != '.' && *period != ')') ++period ; + *period = '\0'; + *size = atoi(tmp); /*sscanf(tmp, "%2d", size);*/ + + return 0; +} + +static int ReadVector(FILE *fp, int n, int *where, int perline, int persize) +{ + register int i, j, item; + char tmp, buf[100]; + + i = 0; + while (i < n) { + fgets(buf, 100, fp); /* read a line at a time */ + for (j=0; j + * On input, nonz/nzval/rowind/colptr represents lower part of a symmetric + * matrix. On exit, it represents the full matrix with lower and upper parts. + * + */ +static void +FormFullA(int n, int *nonz, complex **nzval, int **rowind, int **colptr) +{ + register int i, j, k, col, new_nnz; + int *t_rowind, *t_colptr, *al_rowind, *al_colptr, *a_rowind, *a_colptr; + int *marker; + complex *t_val, *al_val, *a_val; + + al_rowind = *rowind; + al_colptr = *colptr; + al_val = *nzval; + + if ( !(marker =(int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for marker[]"); + if ( !(t_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC t_colptr[]"); + if ( !(t_rowind = (int *) SUPERLU_MALLOC( *nonz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for t_rowind[]"); + if ( !(t_val = (complex*) SUPERLU_MALLOC( *nonz * sizeof(complex)) ) ) + ABORT("SUPERLU_MALLOC fails for t_val[]"); + + /* Get counts of each column of T, and set up column pointers */ + for (i = 0; i < n; ++i) marker[i] = 0; + for (j = 0; j < n; ++j) { + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) + ++marker[al_rowind[i]]; + } + t_colptr[0] = 0; + for (i = 0; i < n; ++i) { + t_colptr[i+1] = t_colptr[i] + marker[i]; + marker[i] = t_colptr[i]; + } + + /* Transpose matrix A to T */ + for (j = 0; j < n; ++j) + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + col = al_rowind[i]; + t_rowind[marker[col]] = j; + t_val[marker[col]] = al_val[i]; + ++marker[col]; + } + + new_nnz = *nonz * 2 - n; + if ( !(a_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC a_colptr[]"); + if ( !(a_rowind = (int *) SUPERLU_MALLOC( new_nnz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for a_rowind[]"); + if ( !(a_val = (complex*) SUPERLU_MALLOC( new_nnz * sizeof(complex)) ) ) + ABORT("SUPERLU_MALLOC fails for a_val[]"); + + a_colptr[0] = 0; + k = 0; + for (j = 0; j < n; ++j) { + for (i = t_colptr[j]; i < t_colptr[j+1]; ++i) { + if ( t_rowind[i] != j ) { /* not diagonal */ + a_rowind[k] = t_rowind[i]; + a_val[k] = t_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + } + + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + a_rowind[k] = al_rowind[i]; + a_val[k] = al_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + + a_colptr[j+1] = k; + } + + printf("FormFullA: new_nnz = %d, k = %d\n", new_nnz, k); + + SUPERLU_FREE(al_val); + SUPERLU_FREE(al_rowind); + SUPERLU_FREE(al_colptr); + SUPERLU_FREE(marker); + SUPERLU_FREE(t_val); + SUPERLU_FREE(t_rowind); + SUPERLU_FREE(t_colptr); + + *nzval = a_val; + *rowind = a_rowind; + *colptr = a_colptr; + *nonz = new_nnz; +} + +void +creadrb(int *nrow, int *ncol, int *nonz, + complex **nzval, int **rowind, int **colptr) +{ + + register int i, numer_lines = 0; + int tmp, colnum, colsize, rownum, rowsize, valnum, valsize; + char buf[100], type[4]; + int sym; + FILE *fp; + + fp = stdin; + + /* Line 1 */ + fgets(buf, 100, fp); + fputs(buf, stdout); + + /* Line 2 */ + for (i=0; i<4; i++) { + fscanf(fp, "%14c", buf); buf[14] = 0; + sscanf(buf, "%d", &tmp); + if (i == 3) numer_lines = tmp; + } + cDumpLine(fp); + + /* Line 3 */ + fscanf(fp, "%3c", type); + fscanf(fp, "%11c", buf); /* pad */ + type[3] = 0; +#ifdef DEBUG + printf("Matrix type %s\n", type); +#endif + + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nrow); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", ncol); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nonz); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", &tmp); + + if (tmp != 0) + printf("This is not an assembled matrix!\n"); + if (*nrow != *ncol) + printf("Matrix is not square.\n"); + cDumpLine(fp); + + /* Allocate storage for the three arrays ( nzval, rowind, colptr ) */ + callocateA(*ncol, *nonz, nzval, rowind, colptr); + + /* Line 4: format statement */ + fscanf(fp, "%16c", buf); + cParseIntFormat(buf, &colnum, &colsize); + fscanf(fp, "%16c", buf); + cParseIntFormat(buf, &rownum, &rowsize); + fscanf(fp, "%20c", buf); + cParseFloatFormat(buf, &valnum, &valsize); + cDumpLine(fp); + +#ifdef DEBUG + printf("%d rows, %d nonzeros\n", *nrow, *nonz); + printf("colnum %d, colsize %d\n", colnum, colsize); + printf("rownum %d, rowsize %d\n", rownum, rowsize); + printf("valnum %d, valsize %d\n", valnum, valsize); +#endif + + ReadVector(fp, *ncol+1, *colptr, colnum, colsize); + ReadVector(fp, *nonz, *rowind, rownum, rowsize); + if ( numer_lines ) { + cReadValues(fp, *nonz, *nzval, valnum, valsize); + } + + sym = (type[1] == 'S' || type[1] == 's'); + if ( sym ) { + FormFullA(*ncol, nonz, nzval, rowind, colptr); + } + + fclose(fp); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/creadtriple.c b/src/Libraries/superlu-5.2.1/SRC/creadtriple.c new file mode 100644 index 00000000..97cf70a1 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/creadtriple.c @@ -0,0 +1,150 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file creadtriple.c + * \brief Read a matrix stored in triplet (coordinate) format + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ + +#include "slu_cdefs.h" + + +void +creadtriple(int *m, int *n, int *nonz, + complex **nzval, int **rowind, int **colptr) +{ +/* + * Output parameters + * ================= + * (a,asub,xa): asub[*] contains the row subscripts of nonzeros + * in columns of matrix A; a[*] the numerical values; + * row i of A is given by a[k],k=xa[i],...,xa[i+1]-1. + * + */ + int j, k, jsize, nnz, nz; + complex *a, *val; + int *asub, *xa, *row, *col; + int zero_base = 0; + + /* Matrix format: + * First line: #rows, #cols, #non-zero + * Triplet in the rest of lines: + * row, col, value + */ + + scanf("%d%d", n, nonz); + *m = *n; + printf("m %d, n %d, nonz %d\n", *m, *n, *nonz); + callocateA(*n, *nonz, nzval, rowind, colptr); /* Allocate storage */ + a = *nzval; + asub = *rowind; + xa = *colptr; + + val = (complex *) SUPERLU_MALLOC(*nonz * sizeof(complex)); + row = (int *) SUPERLU_MALLOC(*nonz * sizeof(int)); + col = (int *) SUPERLU_MALLOC(*nonz * sizeof(int)); + + for (j = 0; j < *n; ++j) xa[j] = 0; + + /* Read into the triplet array from a file */ + for (nnz = 0, nz = 0; nnz < *nonz; ++nnz) { + scanf("%d%d%f%f\n", &row[nz], &col[nz], &val[nz].r, &val[nz].i); + + if ( nnz == 0 ) { /* first nonzero */ + if ( row[0] == 0 || col[0] == 0 ) { + zero_base = 1; + printf("triplet file: row/col indices are zero-based.\n"); + } else + printf("triplet file: row/col indices are one-based.\n"); + } + + if ( !zero_base ) { + /* Change to 0-based indexing. */ + --row[nz]; + --col[nz]; + } + + if (row[nz] < 0 || row[nz] >= *m || col[nz] < 0 || col[nz] >= *n + /*|| val[nz] == 0.*/) { + fprintf(stderr, "nz %d, (%d, %d) = (%e,%e) out of bound, removed\n", + nz, row[nz], col[nz], val[nz].r, val[nz].i); + exit(-1); + } else { + ++xa[col[nz]]; + ++nz; + } + } + + *nonz = nz; + + /* Initialize the array of column pointers */ + k = 0; + jsize = xa[0]; + xa[0] = 0; + for (j = 1; j < *n; ++j) { + k += jsize; + jsize = xa[j]; + xa[j] = k; + } + + /* Copy the triplets into the column oriented storage */ + for (nz = 0; nz < *nonz; ++nz) { + j = col[nz]; + k = xa[j]; + asub[k] = row[nz]; + a[k] = val[nz]; + ++xa[j]; + } + + /* Reset the column pointers to the beginning of each column */ + for (j = *n; j > 0; --j) + xa[j] = xa[j-1]; + xa[0] = 0; + + SUPERLU_FREE(val); + SUPERLU_FREE(row); + SUPERLU_FREE(col); + +#ifdef CHK_INPUT + { + int i; + for (i = 0; i < *n; i++) { + printf("Col %d, xa %d\n", i, xa[i]); + for (k = xa[i]; k < xa[i+1]; k++) + printf("%d\t%16.10f\n", asub[k], a[k]); + } + } +#endif + +} + + +void creadrhs(int m, complex *b) +{ + FILE *fp, *fopen(); + int i; + /*int j;*/ + + if ( !(fp = fopen("b.dat", "r")) ) { + fprintf(stderr, "dreadrhs: file does not exist\n"); + exit(-1); + } + for (i = 0; i < m; ++i) + fscanf(fp, "%f%f\n", &b[i].r, &b[i].i); + + /* readpair_(j, &b[i]);*/ + fclose(fp); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/csnode_bmod.c b/src/Libraries/superlu-5.2.1/SRC/csnode_bmod.c new file mode 100644 index 00000000..1d5c6f48 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/csnode_bmod.c @@ -0,0 +1,130 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file csnode_bmod.c + * \brief Performs numeric block updates within the relaxed snode. + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_cdefs.h" + + +/*! \brief Performs numeric block updates within the relaxed snode. + */ +int +csnode_bmod ( + const int jcol, /* in */ + const int jsupno, /* in */ + const int fsupc, /* in */ + complex *dense, /* in */ + complex *tempv, /* working array */ + GlobalLU_t *Glu, /* modified */ + SuperLUStat_t *stat /* output */ + ) +{ +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + int incx = 1, incy = 1; + complex alpha = {-1.0, 0.0}, beta = {1.0, 0.0}; +#endif + + complex comp_zero = {0.0, 0.0}; + int luptr, nsupc, nsupr, nrow; + int isub, irow, i, iptr; + register int ufirst, nextlu; + int *lsub, *xlsub; + complex *lusup; + int *xlusup; + flops_t *ops = stat->ops; + + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (complex *) Glu->lusup; + xlusup = Glu->xlusup; + + nextlu = xlusup[jcol]; + + /* + * Process the supernodal portion of L\U[*,j] + */ + for (isub = xlsub[fsupc]; isub < xlsub[fsupc+1]; isub++) { + irow = lsub[isub]; + lusup[nextlu] = dense[irow]; + dense[irow] = comp_zero; + ++nextlu; + } + + xlusup[jcol + 1] = nextlu; /* Initialize xlusup for next column */ + + if ( fsupc < jcol ) { + + luptr = xlusup[fsupc]; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; + nsupc = jcol - fsupc; /* Excluding jcol */ + ufirst = xlusup[jcol]; /* Points to the beginning of column + jcol in supernode L\U(jsupno). */ + nrow = nsupr - nsupc; + + ops[TRSV] += 4 * nsupc * (nsupc - 1); + ops[GEMV] += 8 * nrow * nsupc; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + CTRSV( ftcs1, ftcs2, ftcs3, &nsupc, &lusup[luptr], &nsupr, + &lusup[ufirst], &incx ); + CGEMV( ftcs2, &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#else + ctrsv_( "L", "N", "U", &nsupc, &lusup[luptr], &nsupr, + &lusup[ufirst], &incx ); + cgemv_( "N", &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#endif +#else + clsolve ( nsupr, nsupc, &lusup[luptr], &lusup[ufirst] ); + cmatvec ( nsupr, nrow, nsupc, &lusup[luptr+nsupc], + &lusup[ufirst], &tempv[0] ); + + /* Scatter tempv[*] into lusup[*] */ + iptr = ufirst + nsupc; + for (i = 0; i < nrow; i++) { + c_sub(&lusup[iptr], &lusup[iptr], &tempv[i]); + ++iptr; + tempv[i] = comp_zero; + } +#endif + + } + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/csnode_dfs.c b/src/Libraries/superlu-5.2.1/SRC/csnode_dfs.c new file mode 100644 index 00000000..f9748cdb --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/csnode_dfs.c @@ -0,0 +1,122 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file csnode_dfs.c + * \brief Determines the union of row structures of columns within the relaxed node + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_cdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *    csnode_dfs() - Determine the union of the row structures of those 
+ *    columns within the relaxed snode.
+ *    Note: The relaxed snodes are leaves of the supernodal etree, therefore, 
+ *    the portion outside the rectangular supernode must be zero.
+ *
+ * Return value
+ * ============
+ *     0   success;
+ *    >0   number of bytes allocated when run out of memory.
+ * 
+ */ + +int +csnode_dfs ( + const int jcol, /* in - start of the supernode */ + const int kcol, /* in - end of the supernode */ + const int *asub, /* in */ + const int *xa_begin, /* in */ + const int *xa_end, /* in */ + int *xprune, /* out */ + int *marker, /* modified */ + GlobalLU_t *Glu /* modified */ + ) +{ + + register int i, k, ifrom, ito, nextl, new_next; + int nsuper, krow, kmark, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + int nzlmax; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + nsuper = ++supno[jcol]; /* Next available supernode number */ + nextl = xlsub[jcol]; + + for (i = jcol; i <= kcol; i++) { + /* For each nonzero in A[*,i] */ + for (k = xa_begin[i]; k < xa_end[i]; k++) { + krow = asub[k]; + kmark = marker[krow]; + if ( kmark != kcol ) { /* First time visit krow */ + marker[krow] = kcol; + lsub[nextl++] = krow; + if ( nextl >= nzlmax ) { + if ( mem_error = cLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + } + } + supno[i] = nsuper; + } + + /* Supernode > 1, then make a copy of the subscripts for pruning */ + if ( jcol < kcol ) { + new_next = nextl + (nextl - xlsub[jcol]); + while ( new_next > nzlmax ) { + if ( mem_error = cLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + ito = nextl; + for (ifrom = xlsub[jcol]; ifrom < nextl; ) + lsub[ito++] = lsub[ifrom++]; + for (i = jcol+1; i <= kcol; i++) xlsub[i] = nextl; + nextl = ito; + } + + xsup[nsuper+1] = kcol + 1; + supno[kcol+1] = nsuper; + xprune[kcol] = nextl; + xlsub[kcol+1] = nextl; + + return 0; +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/csp_blas2.c b/src/Libraries/superlu-5.2.1/SRC/csp_blas2.c new file mode 100644 index 00000000..93311dfb --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/csp_blas2.c @@ -0,0 +1,608 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file csp_blas2.c + * \brief Sparse BLAS 2, using some dense BLAS 2 operations + * + *
+ * -- SuperLU routine (version 5.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Last update: December 3, 2015
+ * 
+ */ +/* + * File name: csp_blas2.c + * Purpose: Sparse BLAS 2, using some dense BLAS 2 operations. + */ + +#include "slu_cdefs.h" + +/* + * Function prototypes + */ +void cusolve(int, int, complex*, complex*); +void clsolve(int, int, complex*, complex*); +void cmatvec(int, int, int, complex*, complex*, complex*); + +/*! \brief Solves one of the systems of equations A*x = b, or A'*x = b + * + *
+ *   Purpose
+ *   =======
+ *
+ *   sp_ctrsv() solves one of the systems of equations   
+ *       A*x = b,   or   A'*x = b,
+ *   where b and x are n element vectors and A is a sparse unit , or   
+ *   non-unit, upper or lower triangular matrix.   
+ *   No test for singularity or near-singularity is included in this   
+ *   routine. Such tests must be performed before calling this routine.   
+ *
+ *   Parameters   
+ *   ==========   
+ *
+ *   uplo   - (input) char*
+ *            On entry, uplo specifies whether the matrix is an upper or   
+ *             lower triangular matrix as follows:   
+ *                uplo = 'U' or 'u'   A is an upper triangular matrix.   
+ *                uplo = 'L' or 'l'   A is a lower triangular matrix.   
+ *
+ *   trans  - (input) char*
+ *             On entry, trans specifies the equations to be solved as   
+ *             follows:   
+ *                trans = 'N' or 'n'   A*x = b.   
+ *                trans = 'T' or 't'   A'*x = b.
+ *                trans = 'C' or 'c'   A^H*x = b.   
+ *
+ *   diag   - (input) char*
+ *             On entry, diag specifies whether or not A is unit   
+ *             triangular as follows:   
+ *                diag = 'U' or 'u'   A is assumed to be unit triangular.   
+ *                diag = 'N' or 'n'   A is not assumed to be unit   
+ *                                    triangular.   
+ *	     
+ *   L       - (input) SuperMatrix*
+ *	       The factor L from the factorization Pr*A*Pc=L*U. Use
+ *             compressed row subscripts storage for supernodes,
+ *             i.e., L has types: Stype = SC, Dtype = SLU_C, Mtype = TRLU.
+ *
+ *   U       - (input) SuperMatrix*
+ *	        The factor U from the factorization Pr*A*Pc=L*U.
+ *	        U has types: Stype = NC, Dtype = SLU_C, Mtype = TRU.
+ *    
+ *   x       - (input/output) complex*
+ *             Before entry, the incremented array X must contain the n   
+ *             element right-hand side vector b. On exit, X is overwritten 
+ *             with the solution vector x.
+ *
+ *   info    - (output) int*
+ *             If *info = -i, the i-th argument had an illegal value.
+ * 
+ */ +int +sp_ctrsv(char *uplo, char *trans, char *diag, SuperMatrix *L, + SuperMatrix *U, complex *x, SuperLUStat_t *stat, int *info) +{ +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + SCformat *Lstore; + NCformat *Ustore; + complex *Lval, *Uval; + int incx = 1, incy = 1; + complex temp; + complex alpha = {1.0, 0.0}, beta = {1.0, 0.0}; + complex comp_zero = {0.0, 0.0}; + int nrow; + int fsupc, nsupr, nsupc, luptr, istart, irow; + int i, k, iptr, jcol; + complex *work; + flops_t solve_ops; + + /* Test the input parameters */ + *info = 0; + if ( strncmp(uplo,"L", 1)!=0 && strncmp(uplo, "U", 1)!=0 ) *info = -1; + else if ( strncmp(trans, "N", 1)!=0 && strncmp(trans, "T", 1)!=0 && + strncmp(trans, "C", 1)!=0) *info = -2; + else if ( strncmp(diag, "U", 1)!=0 && strncmp(diag, "N", 1)!=0 ) + *info = -3; + else if ( L->nrow != L->ncol || L->nrow < 0 ) *info = -4; + else if ( U->nrow != U->ncol || U->nrow < 0 ) *info = -5; + if ( *info ) { + i = -(*info); + input_error("sp_ctrsv", &i); + return 0; + } + + Lstore = L->Store; + Lval = Lstore->nzval; + Ustore = U->Store; + Uval = Ustore->nzval; + solve_ops = 0; + + if ( !(work = complexCalloc(L->nrow)) ) + ABORT("Malloc fails for work in sp_ctrsv()."); + + if ( strncmp(trans, "N", 1)==0 ) { /* Form x := inv(A)*x. */ + + if ( strncmp(uplo, "L", 1)==0 ) { + /* Form x := inv(L)*x */ + if ( L->nrow == 0 ) return 0; /* Quick return */ + + for (k = 0; k <= Lstore->nsuper; k++) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + nrow = nsupr - nsupc; + + /* 1 c_div costs 10 flops */ + solve_ops += 4 * nsupc * (nsupc - 1) + 10 * nsupc; + solve_ops += 8 * nrow * nsupc; + + if ( nsupc == 1 ) { + for (iptr=istart+1; iptr < L_SUB_START(fsupc+1); ++iptr) { + irow = L_SUB(iptr); + ++luptr; + cc_mult(&comp_zero, &x[fsupc], &Lval[luptr]); + c_sub(&x[irow], &x[irow], &comp_zero); + } + } else { +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + CTRSV(ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); + + CGEMV(ftcs2, &nrow, &nsupc, &alpha, &Lval[luptr+nsupc], + &nsupr, &x[fsupc], &incx, &beta, &work[0], &incy); +#else + ctrsv_("L", "N", "U", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); + + cgemv_("N", &nrow, &nsupc, &alpha, &Lval[luptr+nsupc], + &nsupr, &x[fsupc], &incx, &beta, &work[0], &incy); +#endif +#else + clsolve ( nsupr, nsupc, &Lval[luptr], &x[fsupc]); + + cmatvec ( nsupr, nsupr-nsupc, nsupc, &Lval[luptr+nsupc], + &x[fsupc], &work[0] ); +#endif + + iptr = istart + nsupc; + for (i = 0; i < nrow; ++i, ++iptr) { + irow = L_SUB(iptr); + c_sub(&x[irow], &x[irow], &work[i]); /* Scatter */ + work[i] = comp_zero; + + } + } + } /* for k ... */ + + } else { + /* Form x := inv(U)*x */ + + if ( U->nrow == 0 ) return 0; /* Quick return */ + + for (k = Lstore->nsuper; k >= 0; k--) { + fsupc = L_FST_SUPC(k); + nsupr = L_SUB_START(fsupc+1) - L_SUB_START(fsupc); + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + /* 1 c_div costs 10 flops */ + solve_ops += 4 * nsupc * (nsupc + 1) + 10 * nsupc; + + if ( nsupc == 1 ) { + c_div(&x[fsupc], &x[fsupc], &Lval[luptr]); + for (i = U_NZ_START(fsupc); i < U_NZ_START(fsupc+1); ++i) { + irow = U_SUB(i); + cc_mult(&comp_zero, &x[fsupc], &Uval[i]); + c_sub(&x[irow], &x[irow], &comp_zero); + } + } else { +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + CTRSV(ftcs3, ftcs2, ftcs2, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + ctrsv_("U", "N", "N", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif +#else + cusolve ( nsupr, nsupc, &Lval[luptr], &x[fsupc] ); +#endif + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + solve_ops += 8*(U_NZ_START(jcol+1) - U_NZ_START(jcol)); + for (i = U_NZ_START(jcol); i < U_NZ_START(jcol+1); + i++) { + irow = U_SUB(i); + cc_mult(&comp_zero, &x[jcol], &Uval[i]); + c_sub(&x[irow], &x[irow], &comp_zero); + } + } + } + } /* for k ... */ + + } + } else if ( strncmp(trans, "T", 1)==0 ) { /* Form x := inv(A')*x */ + + if ( strncmp(uplo, "L", 1)==0 ) { + /* Form x := inv(L')*x */ + if ( L->nrow == 0 ) return 0; /* Quick return */ + + for (k = Lstore->nsuper; k >= 0; --k) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + solve_ops += 8 * (nsupr - nsupc) * nsupc; + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + iptr = istart + nsupc; + for (i = L_NZ_START(jcol) + nsupc; + i < L_NZ_START(jcol+1); i++) { + irow = L_SUB(iptr); + cc_mult(&comp_zero, &x[irow], &Lval[i]); + c_sub(&x[jcol], &x[jcol], &comp_zero); + iptr++; + } + } + + if ( nsupc > 1 ) { + solve_ops += 4 * nsupc * (nsupc - 1); +#ifdef _CRAY + ftcs1 = _cptofcd("L", strlen("L")); + ftcs2 = _cptofcd("T", strlen("T")); + ftcs3 = _cptofcd("U", strlen("U")); + CTRSV(ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + ctrsv_("L", "T", "U", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif + } + } + } else { + /* Form x := inv(U')*x */ + if ( U->nrow == 0 ) return 0; /* Quick return */ + + for (k = 0; k <= Lstore->nsuper; k++) { + fsupc = L_FST_SUPC(k); + nsupr = L_SUB_START(fsupc+1) - L_SUB_START(fsupc); + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + solve_ops += 8*(U_NZ_START(jcol+1) - U_NZ_START(jcol)); + for (i = U_NZ_START(jcol); i < U_NZ_START(jcol+1); i++) { + irow = U_SUB(i); + cc_mult(&comp_zero, &x[irow], &Uval[i]); + c_sub(&x[jcol], &x[jcol], &comp_zero); + } + } + + /* 1 c_div costs 10 flops */ + solve_ops += 4 * nsupc * (nsupc + 1) + 10 * nsupc; + + if ( nsupc == 1 ) { + c_div(&x[fsupc], &x[fsupc], &Lval[luptr]); + } else { +#ifdef _CRAY + ftcs1 = _cptofcd("U", strlen("U")); + ftcs2 = _cptofcd("T", strlen("T")); + ftcs3 = _cptofcd("N", strlen("N")); + CTRSV( ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + ctrsv_("U", "T", "N", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif + } + } /* for k ... */ + } + } else { /* Form x := conj(inv(A'))*x */ + + if ( strncmp(uplo, "L", 1)==0 ) { + /* Form x := conj(inv(L'))*x */ + if ( L->nrow == 0 ) return 0; /* Quick return */ + + for (k = Lstore->nsuper; k >= 0; --k) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + solve_ops += 8 * (nsupr - nsupc) * nsupc; + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + iptr = istart + nsupc; + for (i = L_NZ_START(jcol) + nsupc; + i < L_NZ_START(jcol+1); i++) { + irow = L_SUB(iptr); + cc_conj(&temp, &Lval[i]); + cc_mult(&comp_zero, &x[irow], &temp); + c_sub(&x[jcol], &x[jcol], &comp_zero); + iptr++; + } + } + + if ( nsupc > 1 ) { + solve_ops += 4 * nsupc * (nsupc - 1); +#ifdef _CRAY + ftcs1 = _cptofcd("L", strlen("L")); + ftcs2 = _cptofcd(trans, strlen("T")); + ftcs3 = _cptofcd("U", strlen("U")); + CTRSV(ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + ctrsv_("L", trans, "U", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif + } + } + } else { + /* Form x := conj(inv(U'))*x */ + if ( U->nrow == 0 ) return 0; /* Quick return */ + + for (k = 0; k <= Lstore->nsuper; k++) { + fsupc = L_FST_SUPC(k); + nsupr = L_SUB_START(fsupc+1) - L_SUB_START(fsupc); + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + solve_ops += 8*(U_NZ_START(jcol+1) - U_NZ_START(jcol)); + for (i = U_NZ_START(jcol); i < U_NZ_START(jcol+1); i++) { + irow = U_SUB(i); + cc_conj(&temp, &Uval[i]); + cc_mult(&comp_zero, &x[irow], &temp); + c_sub(&x[jcol], &x[jcol], &comp_zero); + } + } + + /* 1 c_div costs 10 flops */ + solve_ops += 4 * nsupc * (nsupc + 1) + 10 * nsupc; + + if ( nsupc == 1 ) { + cc_conj(&temp, &Lval[luptr]); + c_div(&x[fsupc], &x[fsupc], &temp); + } else { +#ifdef _CRAY + ftcs1 = _cptofcd("U", strlen("U")); + ftcs2 = _cptofcd(trans, strlen("T")); + ftcs3 = _cptofcd("N", strlen("N")); + CTRSV( ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + ctrsv_("U", trans, "N", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif + } + } /* for k ... */ + } + } + + stat->ops[SOLVE] += solve_ops; + SUPERLU_FREE(work); + return 0; +} + + + +/*! \brief Performs one of the matrix-vector operations y := alpha*A*x + beta*y, or y := alpha*A'*x + beta*y + * + *
  
+ *   Purpose   
+ *   =======   
+ *
+ *   sp_cgemv()  performs one of the matrix-vector operations   
+ *      y := alpha*A*x + beta*y,   or   y := alpha*A'*x + beta*y,   
+ *   where alpha and beta are scalars, x and y are vectors and A is a
+ *   sparse A->nrow by A->ncol matrix.   
+ *
+ *   Parameters   
+ *   ==========   
+ *
+ *   TRANS  - (input) char*
+ *            On entry, TRANS specifies the operation to be performed as   
+ *            follows:   
+ *               TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.   
+ *               TRANS = 'T' or 't'   y := alpha*A'*x + beta*y.   
+ *               TRANS = 'C' or 'c'   y := alpha*A^H*x + beta*y.   
+ *
+ *   ALPHA  - (input) complex
+ *            On entry, ALPHA specifies the scalar alpha.   
+ *
+ *   A      - (input) SuperMatrix*
+ *            Before entry, the leading m by n part of the array A must   
+ *            contain the matrix of coefficients.   
+ *
+ *   X      - (input) complex*, array of DIMENSION at least   
+ *            ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'   
+ *           and at least   
+ *            ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.   
+ *            Before entry, the incremented array X must contain the   
+ *            vector x.   
+ * 
+ *   INCX   - (input) int
+ *            On entry, INCX specifies the increment for the elements of   
+ *            X. INCX must not be zero.   
+ *
+ *   BETA   - (input) complex
+ *            On entry, BETA specifies the scalar beta. When BETA is   
+ *            supplied as zero then Y need not be set on input.   
+ *
+ *   Y      - (output) complex*,  array of DIMENSION at least   
+ *            ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'   
+ *            and at least   
+ *            ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.   
+ *            Before entry with BETA non-zero, the incremented array Y   
+ *            must contain the vector y. On exit, Y is overwritten by the 
+ *            updated vector y.
+ *	      
+ *   INCY   - (input) int
+ *            On entry, INCY specifies the increment for the elements of   
+ *            Y. INCY must not be zero.   
+ *
+ *    ==== Sparse Level 2 Blas routine.   
+ * 
+*/ +int +sp_cgemv(char *trans, complex alpha, SuperMatrix *A, complex *x, + int incx, complex beta, complex *y, int incy) +{ + + /* Local variables */ + NCformat *Astore; + complex *Aval; + int info; + complex temp, temp1; + int lenx, leny, i, j, irow; + int iy, jx, jy, kx, ky; + int notran; + complex comp_zero = {0.0, 0.0}; + complex comp_one = {1.0, 0.0}; + + notran = ( strncmp(trans, "N", 1)==0 || strncmp(trans, "n", 1)==0 ); + Astore = A->Store; + Aval = Astore->nzval; + + /* Test the input parameters */ + info = 0; + if ( !notran && strncmp(trans, "T", 1)!=0 && strncmp(trans, "C", 1)!=0) + info = 1; + else if ( A->nrow < 0 || A->ncol < 0 ) info = 3; + else if (incx == 0) info = 5; + else if (incy == 0) info = 8; + if (info != 0) { + input_error("sp_cgemv ", &info); + return 0; + } + + /* Quick return if possible. */ + if (A->nrow == 0 || A->ncol == 0 || + c_eq(&alpha, &comp_zero) && + c_eq(&beta, &comp_one)) + return 0; + + /* Set LENX and LENY, the lengths of the vectors x and y, and set + up the start points in X and Y. */ + if ( notran ) { + lenx = A->ncol; + leny = A->nrow; + } else { + lenx = A->nrow; + leny = A->ncol; + } + if (incx > 0) kx = 0; + else kx = - (lenx - 1) * incx; + if (incy > 0) ky = 0; + else ky = - (leny - 1) * incy; + + /* Start the operations. In this version the elements of A are + accessed sequentially with one pass through A. */ + /* First form y := beta*y. */ + if ( !c_eq(&beta, &comp_one) ) { + if (incy == 1) { + if ( c_eq(&beta, &comp_zero) ) + for (i = 0; i < leny; ++i) y[i] = comp_zero; + else + for (i = 0; i < leny; ++i) + cc_mult(&y[i], &beta, &y[i]); + } else { + iy = ky; + if ( c_eq(&beta, &comp_zero) ) + for (i = 0; i < leny; ++i) { + y[iy] = comp_zero; + iy += incy; + } + else + for (i = 0; i < leny; ++i) { + cc_mult(&y[iy], &beta, &y[iy]); + iy += incy; + } + } + } + + if ( c_eq(&alpha, &comp_zero) ) return 0; + + if ( notran ) { + /* Form y := alpha*A*x + y. */ + jx = kx; + if (incy == 1) { + for (j = 0; j < A->ncol; ++j) { + if ( !c_eq(&x[jx], &comp_zero) ) { + cc_mult(&temp, &alpha, &x[jx]); + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + cc_mult(&temp1, &temp, &Aval[i]); + c_add(&y[irow], &y[irow], &temp1); + } + } + jx += incx; + } + } else { + ABORT("Not implemented."); + } + } else if (strncmp(trans, "T", 1) == 0 || strncmp(trans, "t", 1) == 0) { + /* Form y := alpha*A'*x + y. */ + jy = ky; + if (incx == 1) { + for (j = 0; j < A->ncol; ++j) { + temp = comp_zero; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + cc_mult(&temp1, &Aval[i], &x[irow]); + c_add(&temp, &temp, &temp1); + } + cc_mult(&temp1, &alpha, &temp); + c_add(&y[jy], &y[jy], &temp1); + jy += incy; + } + } else { + ABORT("Not implemented."); + } + } else { /* trans == 'C' or 'c' */ + /* Form y := alpha * conj(A) * x + y. */ + complex temp2; + jy = ky; + if (incx == 1) { + for (j = 0; j < A->ncol; ++j) { + temp = comp_zero; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + temp2.r = Aval[i].r; + temp2.i = -Aval[i].i; /* conjugation */ + cc_mult(&temp1, &temp2, &x[irow]); + c_add(&temp, &temp, &temp1); + } + cc_mult(&temp1, &alpha, &temp); + c_add(&y[jy], &y[jy], &temp1); + jy += incy; + } + } else { + ABORT("Not implemented."); + } + } + + return 0; +} /* sp_cgemv */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/csp_blas3.c b/src/Libraries/superlu-5.2.1/SRC/csp_blas3.c new file mode 100644 index 00000000..1f3023d0 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/csp_blas3.c @@ -0,0 +1,137 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file csp_blas3.c + * \brief Sparse BLAS3, using some dense BLAS3 operations + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ */ +/* + * File name: sp_blas3.c + * Purpose: Sparse BLAS3, using some dense BLAS3 operations. + */ + +#include "slu_cdefs.h" + +/*! \brief + * + *
+ * Purpose   
+ *   =======   
+ * 
+ *   sp_c performs one of the matrix-matrix operations   
+ * 
+ *      C := alpha*op( A )*op( B ) + beta*C,   
+ * 
+ *   where  op( X ) is one of 
+ * 
+ *      op( X ) = X   or   op( X ) = X'   or   op( X ) = conjg( X' ),
+ * 
+ *   alpha and beta are scalars, and A, B and C are matrices, with op( A ) 
+ *   an m by k matrix,  op( B )  a  k by n matrix and  C an m by n matrix. 
+ *   
+ * 
+ *   Parameters   
+ *   ==========   
+ * 
+ *   TRANSA - (input) char*
+ *            On entry, TRANSA specifies the form of op( A ) to be used in 
+ *            the matrix multiplication as follows:   
+ *               TRANSA = 'N' or 'n',  op( A ) = A.   
+ *               TRANSA = 'T' or 't',  op( A ) = A'.   
+ *               TRANSA = 'C' or 'c',  op( A ) = conjg( A' ).   
+ *            Unchanged on exit.   
+ * 
+ *   TRANSB - (input) char*
+ *            On entry, TRANSB specifies the form of op( B ) to be used in 
+ *            the matrix multiplication as follows:   
+ *               TRANSB = 'N' or 'n',  op( B ) = B.   
+ *               TRANSB = 'T' or 't',  op( B ) = B'.   
+ *               TRANSB = 'C' or 'c',  op( B ) = conjg( B' ).   
+ *            Unchanged on exit.   
+ * 
+ *   M      - (input) int   
+ *            On entry,  M  specifies  the number of rows of the matrix 
+ *	     op( A ) and of the matrix C.  M must be at least zero. 
+ *	     Unchanged on exit.   
+ * 
+ *   N      - (input) int
+ *            On entry,  N specifies the number of columns of the matrix 
+ *	     op( B ) and the number of columns of the matrix C. N must be 
+ *	     at least zero.
+ *	     Unchanged on exit.   
+ * 
+ *   K      - (input) int
+ *            On entry, K specifies the number of columns of the matrix 
+ *	     op( A ) and the number of rows of the matrix op( B ). K must 
+ *	     be at least  zero.   
+ *           Unchanged on exit.
+ *      
+ *   ALPHA  - (input) complex
+ *            On entry, ALPHA specifies the scalar alpha.   
+ * 
+ *   A      - (input) SuperMatrix*
+ *            Matrix A with a sparse format, of dimension (A->nrow, A->ncol).
+ *            Currently, the type of A can be:
+ *                Stype = NC or NCP; Dtype = SLU_C; Mtype = GE. 
+ *            In the future, more general A can be handled.
+ * 
+ *   B      - COMPLEX PRECISION array of DIMENSION ( LDB, kb ), where kb is 
+ *            n when TRANSB = 'N' or 'n',  and is  k otherwise.   
+ *            Before entry with  TRANSB = 'N' or 'n',  the leading k by n 
+ *            part of the array B must contain the matrix B, otherwise 
+ *            the leading n by k part of the array B must contain the 
+ *            matrix B.   
+ *            Unchanged on exit.   
+ * 
+ *   LDB    - (input) int
+ *            On entry, LDB specifies the first dimension of B as declared 
+ *            in the calling (sub) program. LDB must be at least max( 1, n ).  
+ *            Unchanged on exit.   
+ * 
+ *   BETA   - (input) complex
+ *            On entry, BETA specifies the scalar beta. When BETA is   
+ *            supplied as zero then C need not be set on input.   
+ *  
+ *   C      - COMPLEX PRECISION array of DIMENSION ( LDC, n ).   
+ *            Before entry, the leading m by n part of the array C must 
+ *            contain the matrix C,  except when beta is zero, in which 
+ *            case C need not be set on entry.   
+ *            On exit, the array C is overwritten by the m by n matrix 
+ *	     ( alpha*op( A )*B + beta*C ).   
+ *  
+ *   LDC    - (input) int
+ *            On entry, LDC specifies the first dimension of C as declared 
+ *            in the calling (sub)program. LDC must be at least max(1,m).   
+ *            Unchanged on exit.   
+ *  
+ *   ==== Sparse Level 3 Blas routine.   
+ * 
+ */ + +int +sp_cgemm(char *transa, char *transb, int m, int n, int k, + complex alpha, SuperMatrix *A, complex *b, int ldb, + complex beta, complex *c, int ldc) +{ + int incx = 1, incy = 1; + int j; + + for (j = 0; j < n; ++j) { + sp_cgemv(transa, alpha, A, &b[ldb*j], incx, beta, &c[ldc*j], incy); + } + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/cutil.c b/src/Libraries/superlu-5.2.1/SRC/cutil.c new file mode 100644 index 00000000..6c58d300 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/cutil.c @@ -0,0 +1,485 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file cutil.c + * \brief Matrix utility functions + * + *
+ * -- SuperLU routine (version 3.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * August 1, 2008
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include +#include "slu_cdefs.h" + +void +cCreate_CompCol_Matrix(SuperMatrix *A, int m, int n, int nnz, + complex *nzval, int *rowind, int *colptr, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + NCformat *Astore; + + A->Stype = stype; + A->Dtype = dtype; + A->Mtype = mtype; + A->nrow = m; + A->ncol = n; + A->Store = (void *) SUPERLU_MALLOC( sizeof(NCformat) ); + if ( !(A->Store) ) ABORT("SUPERLU_MALLOC fails for A->Store"); + Astore = A->Store; + Astore->nnz = nnz; + Astore->nzval = nzval; + Astore->rowind = rowind; + Astore->colptr = colptr; +} + +void +cCreate_CompRow_Matrix(SuperMatrix *A, int m, int n, int nnz, + complex *nzval, int *colind, int *rowptr, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + NRformat *Astore; + + A->Stype = stype; + A->Dtype = dtype; + A->Mtype = mtype; + A->nrow = m; + A->ncol = n; + A->Store = (void *) SUPERLU_MALLOC( sizeof(NRformat) ); + if ( !(A->Store) ) ABORT("SUPERLU_MALLOC fails for A->Store"); + Astore = A->Store; + Astore->nnz = nnz; + Astore->nzval = nzval; + Astore->colind = colind; + Astore->rowptr = rowptr; +} + +/*! \brief Copy matrix A into matrix B. */ +void +cCopy_CompCol_Matrix(SuperMatrix *A, SuperMatrix *B) +{ + NCformat *Astore, *Bstore; + int ncol, nnz, i; + + B->Stype = A->Stype; + B->Dtype = A->Dtype; + B->Mtype = A->Mtype; + B->nrow = A->nrow;; + B->ncol = ncol = A->ncol; + Astore = (NCformat *) A->Store; + Bstore = (NCformat *) B->Store; + Bstore->nnz = nnz = Astore->nnz; + for (i = 0; i < nnz; ++i) + ((complex *)Bstore->nzval)[i] = ((complex *)Astore->nzval)[i]; + for (i = 0; i < nnz; ++i) Bstore->rowind[i] = Astore->rowind[i]; + for (i = 0; i <= ncol; ++i) Bstore->colptr[i] = Astore->colptr[i]; +} + + +void +cCreate_Dense_Matrix(SuperMatrix *X, int m, int n, complex *x, int ldx, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + DNformat *Xstore; + + X->Stype = stype; + X->Dtype = dtype; + X->Mtype = mtype; + X->nrow = m; + X->ncol = n; + X->Store = (void *) SUPERLU_MALLOC( sizeof(DNformat) ); + if ( !(X->Store) ) ABORT("SUPERLU_MALLOC fails for X->Store"); + Xstore = (DNformat *) X->Store; + Xstore->lda = ldx; + Xstore->nzval = (complex *) x; +} + +void +cCopy_Dense_Matrix(int M, int N, complex *X, int ldx, + complex *Y, int ldy) +{ +/*! \brief Copies a two-dimensional matrix X to another matrix Y. + */ + int i, j; + + for (j = 0; j < N; ++j) + for (i = 0; i < M; ++i) + Y[i + j*ldy] = X[i + j*ldx]; +} + +void +cCreate_SuperNode_Matrix(SuperMatrix *L, int m, int n, int nnz, + complex *nzval, int *nzval_colptr, int *rowind, + int *rowind_colptr, int *col_to_sup, int *sup_to_col, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + SCformat *Lstore; + + L->Stype = stype; + L->Dtype = dtype; + L->Mtype = mtype; + L->nrow = m; + L->ncol = n; + L->Store = (void *) SUPERLU_MALLOC( sizeof(SCformat) ); + if ( !(L->Store) ) ABORT("SUPERLU_MALLOC fails for L->Store"); + Lstore = L->Store; + Lstore->nnz = nnz; + Lstore->nsuper = col_to_sup[n]; + Lstore->nzval = nzval; + Lstore->nzval_colptr = nzval_colptr; + Lstore->rowind = rowind; + Lstore->rowind_colptr = rowind_colptr; + Lstore->col_to_sup = col_to_sup; + Lstore->sup_to_col = sup_to_col; + +} + + +/*! \brief Convert a row compressed storage into a column compressed storage. + */ +void +cCompRow_to_CompCol(int m, int n, int nnz, + complex *a, int *colind, int *rowptr, + complex **at, int **rowind, int **colptr) +{ + register int i, j, col, relpos; + int *marker; + + /* Allocate storage for another copy of the matrix. */ + *at = (complex *) complexMalloc(nnz); + *rowind = (int *) intMalloc(nnz); + *colptr = (int *) intMalloc(n+1); + marker = (int *) intCalloc(n); + + /* Get counts of each column of A, and set up column pointers */ + for (i = 0; i < m; ++i) + for (j = rowptr[i]; j < rowptr[i+1]; ++j) ++marker[colind[j]]; + (*colptr)[0] = 0; + for (j = 0; j < n; ++j) { + (*colptr)[j+1] = (*colptr)[j] + marker[j]; + marker[j] = (*colptr)[j]; + } + + /* Transfer the matrix into the compressed column storage. */ + for (i = 0; i < m; ++i) { + for (j = rowptr[i]; j < rowptr[i+1]; ++j) { + col = colind[j]; + relpos = marker[col]; + (*rowind)[relpos] = i; + (*at)[relpos] = a[j]; + ++marker[col]; + } + } + + SUPERLU_FREE(marker); +} + + +void +cPrint_CompCol_Matrix(char *what, SuperMatrix *A) +{ + NCformat *Astore; + register int i,n; + float *dp; + + printf("\nCompCol matrix %s:\n", what); + printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype); + n = A->ncol; + Astore = (NCformat *) A->Store; + dp = (float *) Astore->nzval; + printf("nrow %d, ncol %d, nnz %d\n", A->nrow,A->ncol,Astore->nnz); + printf("nzval: "); + for (i = 0; i < 2*Astore->colptr[n]; ++i) printf("%f ", dp[i]); + printf("\nrowind: "); + for (i = 0; i < Astore->colptr[n]; ++i) printf("%d ", Astore->rowind[i]); + printf("\ncolptr: "); + for (i = 0; i <= n; ++i) printf("%d ", Astore->colptr[i]); + printf("\n"); + fflush(stdout); +} + +void +cPrint_SuperNode_Matrix(char *what, SuperMatrix *A) +{ + SCformat *Astore; + register int i, j, k, c, d, n, nsup; + float *dp; + int *col_to_sup, *sup_to_col, *rowind, *rowind_colptr; + + printf("\nSuperNode matrix %s:\n", what); + printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype); + n = A->ncol; + Astore = (SCformat *) A->Store; + dp = (float *) Astore->nzval; + col_to_sup = Astore->col_to_sup; + sup_to_col = Astore->sup_to_col; + rowind_colptr = Astore->rowind_colptr; + rowind = Astore->rowind; + printf("nrow %d, ncol %d, nnz %d, nsuper %d\n", + A->nrow,A->ncol,Astore->nnz,Astore->nsuper); + printf("nzval:\n"); + for (k = 0; k <= Astore->nsuper; ++k) { + c = sup_to_col[k]; + nsup = sup_to_col[k+1] - c; + for (j = c; j < c + nsup; ++j) { + d = Astore->nzval_colptr[j]; + for (i = rowind_colptr[c]; i < rowind_colptr[c+1]; ++i) { + printf("%d\t%d\t%e\t%e\n", rowind[i], j, dp[d], dp[d+1]); + d += 2; + } + } + } +#if 0 + for (i = 0; i < 2*Astore->nzval_colptr[n]; ++i) printf("%f ", dp[i]); +#endif + printf("\nnzval_colptr: "); + for (i = 0; i <= n; ++i) printf("%d ", Astore->nzval_colptr[i]); + printf("\nrowind: "); + for (i = 0; i < Astore->rowind_colptr[n]; ++i) + printf("%d ", Astore->rowind[i]); + printf("\nrowind_colptr: "); + for (i = 0; i <= n; ++i) printf("%d ", Astore->rowind_colptr[i]); + printf("\ncol_to_sup: "); + for (i = 0; i < n; ++i) printf("%d ", col_to_sup[i]); + printf("\nsup_to_col: "); + for (i = 0; i <= Astore->nsuper+1; ++i) + printf("%d ", sup_to_col[i]); + printf("\n"); + fflush(stdout); +} + +void +cPrint_Dense_Matrix(char *what, SuperMatrix *A) +{ + DNformat *Astore = (DNformat *) A->Store; + register int i, j, lda = Astore->lda; + float *dp; + + printf("\nDense matrix %s:\n", what); + printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype); + dp = (float *) Astore->nzval; + printf("nrow %d, ncol %d, lda %d\n", A->nrow,A->ncol,lda); + printf("\nnzval: "); + for (j = 0; j < A->ncol; ++j) { + for (i = 0; i < 2*A->nrow; ++i) printf("%f ", dp[i + j*2*lda]); + printf("\n"); + } + printf("\n"); + fflush(stdout); +} + +/*! \brief Diagnostic print of column "jcol" in the U/L factor. + */ +void +cprint_lu_col(char *msg, int jcol, int pivrow, int *xprune, GlobalLU_t *Glu) +{ + int i, k, fsupc; + int *xsup, *supno; + int *xlsub, *lsub; + complex *lusup; + int *xlusup; + complex *ucol; + int *usub, *xusub; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (complex *) Glu->lusup; + xlusup = Glu->xlusup; + ucol = (complex *) Glu->ucol; + usub = Glu->usub; + xusub = Glu->xusub; + + printf("%s", msg); + printf("col %d: pivrow %d, supno %d, xprune %d\n", + jcol, pivrow, supno[jcol], xprune[jcol]); + + printf("\tU-col:\n"); + for (i = xusub[jcol]; i < xusub[jcol+1]; i++) + printf("\t%d%10.4f, %10.4f\n", usub[i], ucol[i].r, ucol[i].i); + printf("\tL-col in rectangular snode:\n"); + fsupc = xsup[supno[jcol]]; /* first col of the snode */ + i = xlsub[fsupc]; + k = xlusup[jcol]; + while ( i < xlsub[fsupc+1] && k < xlusup[jcol+1] ) { + printf("\t%d\t%10.4f, %10.4f\n", lsub[i], lusup[k].r, lusup[k].i); + i++; k++; + } + fflush(stdout); +} + + +/*! \brief Check whether tempv[] == 0. This should be true before and after calling any numeric routines, i.e., "panel_bmod" and "column_bmod". + */ +void ccheck_tempv(int n, complex *tempv) +{ + int i; + + for (i = 0; i < n; i++) { + if ((tempv[i].r != 0.0) || (tempv[i].i != 0.0)) + { + fprintf(stderr,"tempv[%d] = {%f, %f}\n", i, tempv[i].r, tempv[i].i); + ABORT("ccheck_tempv"); + } + } +} + + +void +cGenXtrue(int n, int nrhs, complex *x, int ldx) +{ + int i, j; + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) { + x[i + j*ldx].r = 1.0; + x[i + j*ldx].i = 0.0; + } +} + +/*! \brief Let rhs[i] = sum of i-th row of A, so the solution vector is all 1's + */ +void +cFillRHS(trans_t trans, int nrhs, complex *x, int ldx, + SuperMatrix *A, SuperMatrix *B) +{ + NCformat *Astore; + complex *Aval; + DNformat *Bstore; + complex *rhs; + complex one = {1.0, 0.0}; + complex zero = {0.0, 0.0}; + int ldc; + char transc[1]; + + Astore = A->Store; + Aval = (complex *) Astore->nzval; + Bstore = B->Store; + rhs = Bstore->nzval; + ldc = Bstore->lda; + + if ( trans == NOTRANS ) *(unsigned char *)transc = 'N'; + else *(unsigned char *)transc = 'T'; + + sp_cgemm(transc, "N", A->nrow, nrhs, A->ncol, one, A, + x, ldx, zero, rhs, ldc); + +} + +/*! \brief Fills a complex precision array with a given value. + */ +void +cfill(complex *a, int alen, complex dval) +{ + register int i; + for (i = 0; i < alen; i++) a[i] = dval; +} + + + +/*! \brief Check the inf-norm of the error vector + */ +void cinf_norm_error(int nrhs, SuperMatrix *X, complex *xtrue) +{ + DNformat *Xstore; + float err, xnorm; + complex *Xmat, *soln_work; + complex temp; + int i, j; + + Xstore = X->Store; + Xmat = Xstore->nzval; + + for (j = 0; j < nrhs; j++) { + soln_work = &Xmat[j*Xstore->lda]; + err = xnorm = 0.0; + for (i = 0; i < X->nrow; i++) { + c_sub(&temp, &soln_work[i], &xtrue[i]); + err = SUPERLU_MAX(err, c_abs(&temp)); + xnorm = SUPERLU_MAX(xnorm, c_abs(&soln_work[i])); + } + err = err / xnorm; + printf("||X - Xtrue||/||X|| = %e\n", err); + } +} + + + +/*! \brief Print performance of the code. */ +void +cPrintPerf(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage, + float rpg, float rcond, float *ferr, + float *berr, char *equed, SuperLUStat_t *stat) +{ + SCformat *Lstore; + NCformat *Ustore; + double *utime; + flops_t *ops; + + utime = stat->utime; + ops = stat->ops; + + if ( utime[FACT] != 0. ) + printf("Factor flops = %e\tMflops = %8.2f\n", ops[FACT], + ops[FACT]*1e-6/utime[FACT]); + printf("Identify relaxed snodes = %8.2f\n", utime[RELAX]); + if ( utime[SOLVE] != 0. ) + printf("Solve flops = %.0f, Mflops = %8.2f\n", ops[SOLVE], + ops[SOLVE]*1e-6/utime[SOLVE]); + + Lstore = (SCformat *) L->Store; + Ustore = (NCformat *) U->Store; + printf("\tNo of nonzeros in factor L = %d\n", Lstore->nnz); + printf("\tNo of nonzeros in factor U = %d\n", Ustore->nnz); + printf("\tNo of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage->for_lu/1e6, mem_usage->total_needed/1e6); + printf("Number of memory expansions: %d\n", stat->expansions); + + printf("\tFactor\tMflops\tSolve\tMflops\tEtree\tEquil\tRcond\tRefine\n"); + printf("PERF:%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f\n", + utime[FACT], ops[FACT]*1e-6/utime[FACT], + utime[SOLVE], ops[SOLVE]*1e-6/utime[SOLVE], + utime[ETREE], utime[EQUIL], utime[RCOND], utime[REFINE]); + + printf("\tRpg\t\tRcond\t\tFerr\t\tBerr\t\tEquil?\n"); + printf("NUM:\t%e\t%e\t%e\t%e\t%s\n", + rpg, rcond, ferr[0], berr[0], equed); + +} + + + + +print_complex_vec(char *what, int n, complex *vec) +{ + int i; + printf("%s: n %d\n", what, n); + for (i = 0; i < n; ++i) printf("%d\t%f%f\n", i, vec[i].r, vec[i].i); + return 0; +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/dcolumn_bmod.c b/src/Libraries/superlu-5.2.1/SRC/dcolumn_bmod.c new file mode 100644 index 00000000..19fd4255 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dcolumn_bmod.c @@ -0,0 +1,362 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dcolumn_bmod.c + * \brief performs numeric block updates + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ *  Permission is hereby granted to use or copy this program for any
+ *  purpose, provided the above notices are retained on all copies.
+ *  Permission to modify the code and to distribute modified code is
+ *  granted, provided the above notices are retained, and a notice that
+ *  the code was modified is included with the above copyright notice.
+ * 
+*/ + +#include +#include +#include "slu_ddefs.h" + +/* + * Function prototypes + */ +void dusolve(int, int, double*, double*); +void dlsolve(int, int, double*, double*); +void dmatvec(int, int, int, double*, double*, double*); + + + +/*! \brief + * + *
+ * Purpose:
+ * ========
+ * Performs numeric block updates (sup-col) in topological order.
+ * It features: col-col, 2cols-col, 3cols-col, and sup-col updates.
+ * Special processing on the supernodal portion of L\U[*,j]
+ * Return value:   0 - successful return
+ *               > 0 - number of bytes allocated when run out of space
+ * 
+ */ +int +dcolumn_bmod ( + const int jcol, /* in */ + const int nseg, /* in */ + double *dense, /* in */ + double *tempv, /* working array */ + int *segrep, /* in */ + int *repfnz, /* in */ + int fpanelc, /* in -- first column in the current panel */ + GlobalLU_t *Glu, /* modified */ + SuperLUStat_t *stat /* output */ + ) +{ + +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + int incx = 1, incy = 1; + double alpha, beta; + + /* krep = representative of current k-th supernode + * fsupc = first supernodal column + * nsupc = no of columns in supernode + * nsupr = no of rows in supernode (used as leading dimension) + * luptr = location of supernodal LU-block in storage + * kfnz = first nonz in the k-th supernodal segment + * no_zeros = no of leading zeros in a supernodal U-segment + */ + double ukj, ukj1, ukj2; + int luptr, luptr1, luptr2; + int fsupc, nsupc, nsupr, segsze; + int nrow; /* No of rows in the matrix of matrix-vector */ + int jcolp1, jsupno, k, ksub, krep, krep_ind, ksupno; + register int lptr, kfnz, isub, irow, i; + register int no_zeros, new_next; + int ufirst, nextlu; + int fst_col; /* First column within small LU update */ + int d_fsupc; /* Distance between the first column of the current + panel and the first column of the current snode. */ + int *xsup, *supno; + int *lsub, *xlsub; + double *lusup; + int *xlusup; + int nzlumax; + double *tempv1; + double zero = 0.0; + double one = 1.0; + double none = -1.0; + int mem_error; + flops_t *ops = stat->ops; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (double *) Glu->lusup; + xlusup = Glu->xlusup; + nzlumax = Glu->nzlumax; + jcolp1 = jcol + 1; + jsupno = supno[jcol]; + + /* + * For each nonz supernode segment of U[*,j] in topological order + */ + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { + + krep = segrep[k]; + k--; + ksupno = supno[krep]; + if ( jsupno != ksupno ) { /* Outside the rectangular supernode */ + + fsupc = xsup[ksupno]; + fst_col = SUPERLU_MAX ( fsupc, fpanelc ); + + /* Distance from the current supernode to the current panel; + d_fsupc=0 if fsupc > fpanelc. */ + d_fsupc = fst_col - fsupc; + + luptr = xlusup[fst_col] + d_fsupc; + lptr = xlsub[fsupc] + d_fsupc; + + kfnz = repfnz[krep]; + kfnz = SUPERLU_MAX ( kfnz, fpanelc ); + + segsze = krep - kfnz + 1; + nsupc = krep - fst_col + 1; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; /* Leading dimension */ + nrow = nsupr - d_fsupc - nsupc; + krep_ind = lptr + nsupc - 1; + + ops[TRSV] += segsze * (segsze - 1); + ops[GEMV] += 2 * nrow * segsze; + + + /* + * Case 1: Update U-segment of size 1 -- col-col update + */ + if ( segsze == 1 ) { + ukj = dense[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc; + + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + dense[irow] -= ukj*lusup[luptr]; + luptr++; + } + + } else if ( segsze <= 3 ) { + ukj = dense[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc-1; + ukj1 = dense[lsub[krep_ind - 1]]; + luptr1 = luptr - nsupr; + + if ( segsze == 2 ) { /* Case 2: 2cols-col update */ + ukj -= ukj1 * lusup[luptr1]; + dense[lsub[krep_ind]] = ukj; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; + luptr1++; + dense[irow] -= ( ukj*lusup[luptr] + + ukj1*lusup[luptr1] ); + } + } else { /* Case 3: 3cols-col update */ + ukj2 = dense[lsub[krep_ind - 2]]; + luptr2 = luptr1 - nsupr; + ukj1 -= ukj2 * lusup[luptr2-1]; + ukj = ukj - ukj1*lusup[luptr1] - ukj2*lusup[luptr2]; + dense[lsub[krep_ind]] = ukj; + dense[lsub[krep_ind-1]] = ukj1; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; + luptr1++; + luptr2++; + dense[irow] -= ( ukj*lusup[luptr] + + ukj1*lusup[luptr1] + ukj2*lusup[luptr2] ); + } + } + + + + } else { + /* + * Case: sup-col update + * Perform a triangular solve and block update, + * then scatter the result of sup-col update to dense + */ + + no_zeros = kfnz - fst_col; + + /* Copy U[*,j] segment from dense[*] to tempv[*] */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + tempv[i] = dense[irow]; + ++isub; + } + + /* Dense triangular solve -- start effective triangle */ + luptr += nsupr * no_zeros + no_zeros; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + STRSV( ftcs1, ftcs2, ftcs3, &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#else + dtrsv_( "L", "N", "U", &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#endif + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + alpha = one; + beta = zero; +#ifdef _CRAY + SGEMV( ftcs2, &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#else + dgemv_( "N", &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#endif +#else + dlsolve ( nsupr, segsze, &lusup[luptr], tempv ); + + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + dmatvec (nsupr, nrow , segsze, &lusup[luptr], tempv, tempv1); +#endif + + + /* Scatter tempv[] into SPA dense[] as a temporary storage */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + dense[irow] = tempv[i]; + tempv[i] = zero; + ++isub; + } + + /* Scatter tempv1[] into SPA dense[] */ + for (i = 0; i < nrow; i++) { + irow = lsub[isub]; + dense[irow] -= tempv1[i]; + tempv1[i] = zero; + ++isub; + } + } + + } /* if jsupno ... */ + + } /* for each segment... */ + + /* + * Process the supernodal portion of L\U[*,j] + */ + nextlu = xlusup[jcol]; + fsupc = xsup[jsupno]; + + /* Copy the SPA dense into L\U[*,j] */ + new_next = nextlu + xlsub[fsupc+1] - xlsub[fsupc]; + while ( new_next > nzlumax ) { + if (mem_error = dLUMemXpand(jcol, nextlu, LUSUP, &nzlumax, Glu)) + return (mem_error); + lusup = (double *) Glu->lusup; + lsub = Glu->lsub; + } + + for (isub = xlsub[fsupc]; isub < xlsub[fsupc+1]; isub++) { + irow = lsub[isub]; + lusup[nextlu] = dense[irow]; + dense[irow] = zero; + ++nextlu; + } + + xlusup[jcolp1] = nextlu; /* Close L\U[*,jcol] */ + + /* For more updates within the panel (also within the current supernode), + * should start from the first column of the panel, or the first column + * of the supernode, whichever is bigger. There are 2 cases: + * 1) fsupc < fpanelc, then fst_col := fpanelc + * 2) fsupc >= fpanelc, then fst_col := fsupc + */ + fst_col = SUPERLU_MAX ( fsupc, fpanelc ); + + if ( fst_col < jcol ) { + + /* Distance between the current supernode and the current panel. + d_fsupc=0 if fsupc >= fpanelc. */ + d_fsupc = fst_col - fsupc; + + lptr = xlsub[fsupc] + d_fsupc; + luptr = xlusup[fst_col] + d_fsupc; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; /* Leading dimension */ + nsupc = jcol - fst_col; /* Excluding jcol */ + nrow = nsupr - d_fsupc - nsupc; + + /* Points to the beginning of jcol in snode L\U(jsupno) */ + ufirst = xlusup[jcol] + d_fsupc; + + ops[TRSV] += nsupc * (nsupc - 1); + ops[GEMV] += 2 * nrow * nsupc; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + STRSV( ftcs1, ftcs2, ftcs3, &nsupc, &lusup[luptr], + &nsupr, &lusup[ufirst], &incx ); +#else + dtrsv_( "L", "N", "U", &nsupc, &lusup[luptr], + &nsupr, &lusup[ufirst], &incx ); +#endif + + alpha = none; beta = one; /* y := beta*y + alpha*A*x */ + +#ifdef _CRAY + SGEMV( ftcs2, &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#else + dgemv_( "N", &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#endif +#else + dlsolve ( nsupr, nsupc, &lusup[luptr], &lusup[ufirst] ); + + dmatvec ( nsupr, nrow, nsupc, &lusup[luptr+nsupc], + &lusup[ufirst], tempv ); + + /* Copy updates from tempv[*] into lusup[*] */ + isub = ufirst + nsupc; + for (i = 0; i < nrow; i++) { + lusup[isub] -= tempv[i]; + tempv[i] = 0.0; + ++isub; + } + +#endif + + + } /* if fst_col < jcol ... */ + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dcolumn_dfs.c b/src/Libraries/superlu-5.2.1/SRC/dcolumn_dfs.c new file mode 100644 index 00000000..96c14097 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dcolumn_dfs.c @@ -0,0 +1,281 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dcolumn_dfs.c + * \brief Performs a symbolic factorization + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+*/ + +#include "slu_ddefs.h" + +/*! \brief What type of supernodes we want */ +#define T2_SUPER + + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   DCOLUMN_DFS performs a symbolic factorization on column jcol, and
+ *   decide the supernode boundary.
+ *
+ *   This routine does not use numeric values, but only use the RHS 
+ *   row indices to start the dfs.
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives. The routine returns a list of such supernodal 
+ *   representatives in topological order of the dfs that generates them.
+ *   The location of the first nonzero in each such supernodal segment
+ *   (supernodal entry location) is also returned.
+ *
+ * Local parameters
+ * ================
+ *   nseg: no of segments in current U[*,j]
+ *   jsuper: jsuper=EMPTY if column j does not belong to the same
+ *	supernode as j-1. Otherwise, jsuper=nsuper.
+ *
+ *   marker2: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ *
+ * Return value
+ * ============
+ *     0  success;
+ *   > 0  number of bytes allocated when run out of space.
+ * 
+ */ +int +dcolumn_dfs( + const int m, /* in - number of rows in the matrix */ + const int jcol, /* in */ + int *perm_r, /* in */ + int *nseg, /* modified - with new segments appended */ + int *lsub_col, /* in - defines the RHS vector to start the dfs */ + int *segrep, /* modified - with new segments appended */ + int *repfnz, /* modified */ + int *xprune, /* modified */ + int *marker, /* modified */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ + ) +{ + + int jcolp1, jcolm1, jsuper, nsuper, nextl; + int k, krep, krow, kmark, kperm; + int *marker2; /* Used for small panel LU */ + int fsupc; /* First column of a snode */ + int myfnz; /* First nonz column of a U-segment */ + int chperm, chmark, chrep, kchild; + int xdfs, maxdfs, kpar, oldrep; + int jptr, jm1ptr; + int ito, ifrom, istop; /* Used to compress row subscripts */ + int mem_error; + int *xsup, *supno, *lsub, *xlsub; + int nzlmax; + int maxsuper; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + maxsuper = sp_ienv(3); + jcolp1 = jcol + 1; + jcolm1 = jcol - 1; + nsuper = supno[jcol]; + jsuper = nsuper; + nextl = xlsub[jcol]; + marker2 = &marker[2*m]; + + /* For each nonzero in A[*,jcol] do dfs */ + for (k = 0; lsub_col[k] != EMPTY; k++) { + + krow = lsub_col[k]; + lsub_col[k] = EMPTY; + kmark = marker2[krow]; + + /* krow was visited before, go to the next nonz */ + if ( kmark == jcol ) continue; + + /* For each unmarked nbr krow of jcol + * krow is in L: place it in structure of L[*,jcol] + */ + marker2[krow] = jcol; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + lsub[nextl++] = krow; /* krow is indexed into A */ + if ( nextl >= nzlmax ) { + if ( mem_error = dLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + if ( kmark != jcolm1 ) jsuper = EMPTY;/* Row index subset testing */ + } else { + /* krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz[krep]; + + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > kperm ) repfnz[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz[krep] = kperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; + + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker2[kchild]; + + if ( chmark != jcol ) { /* Not reached yet */ + marker2[kchild] = jcol; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,k] */ + if ( chperm == EMPTY ) { + lsub[nextl++] = kchild; + if ( nextl >= nzlmax ) { + if ( mem_error = + dLUMemXpand(jcol,nextl,LSUB,&nzlmax,Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + if ( chmark != jcolm1 ) jsuper = EMPTY; + } else { + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz[chrep]; + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz[chrep] = chperm; + } else { + /* Continue dfs at super-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L^t) */ + parent[krep] = oldrep; + repfnz[krep] = chperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; + } /* else */ + + } /* else */ + + } /* if */ + + } /* while */ + + /* krow has no more unexplored nbrs; + * place supernode-rep krep in postorder DFS. + * backtrack dfs to its parent + */ + segrep[*nseg] = krep; + ++(*nseg); + kpar = parent[krep]; /* Pop from stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xprune[krep]; + + } while ( kpar != EMPTY ); /* Until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonzero ... */ + + /* Check to see if j belongs in the same supernode as j-1 */ + if ( jcol == 0 ) { /* Do nothing for column 0 */ + nsuper = supno[0] = 0; + } else { + fsupc = xsup[nsuper]; + jptr = xlsub[jcol]; /* Not compressed yet */ + jm1ptr = xlsub[jcolm1]; + +#ifdef T2_SUPER + if ( (nextl-jptr != jptr-jm1ptr-1) ) jsuper = EMPTY; +#endif + /* Make sure the number of columns in a supernode doesn't + exceed threshold. */ + if ( jcol - fsupc >= maxsuper ) jsuper = EMPTY; + + /* If jcol starts a new supernode, reclaim storage space in + * lsub from the previous supernode. Note we only store + * the subscript set of the first and last columns of + * a supernode. (first for num values, last for pruning) + */ + if ( jsuper == EMPTY ) { /* starts a new supernode */ + if ( (fsupc < jcolm1-1) ) { /* >= 3 columns in nsuper */ +#ifdef CHK_COMPRESS + printf(" Compress lsub[] at super %d-%d\n", fsupc, jcolm1); +#endif + ito = xlsub[fsupc+1]; + xlsub[jcolm1] = ito; + istop = ito + jptr - jm1ptr; + xprune[jcolm1] = istop; /* Initialize xprune[jcol-1] */ + xlsub[jcol] = istop; + for (ifrom = jm1ptr; ifrom < nextl; ++ifrom, ++ito) + lsub[ito] = lsub[ifrom]; + nextl = ito; /* = istop + length(jcol) */ + } + nsuper++; + supno[jcol] = nsuper; + } /* if a new supernode */ + + } /* else: jcol > 0 */ + + /* Tidy up the pointers before exit */ + xsup[nsuper+1] = jcolp1; + supno[jcolp1] = nsuper; + xprune[jcol] = nextl; /* Initialize upper bound for pruning */ + xlsub[jcolp1] = nextl; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dcomplex.c b/src/Libraries/superlu-5.2.1/SRC/dcomplex.c new file mode 100644 index 00000000..0da48a94 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dcomplex.c @@ -0,0 +1,157 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dcomplex.c + * \brief Common arithmetic for complex type + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * This file defines common arithmetic operations for complex type.
+ * 
+ */ + +#include +#include +#include +#include "slu_dcomplex.h" + + +/*! \brief Complex Division c = a/b */ +void z_div(doublecomplex *c, doublecomplex *a, doublecomplex *b) +{ + double ratio, den; + double abr, abi, cr, ci; + + if( (abr = b->r) < 0.) + abr = - abr; + if( (abi = b->i) < 0.) + abi = - abi; + if( abr <= abi ) { + if (abi == 0) { + fprintf(stderr, "z_div.c: division by zero\n"); + exit(-1); + } + ratio = b->r / b->i ; + den = b->i * (1 + ratio*ratio); + cr = (a->r*ratio + a->i) / den; + ci = (a->i*ratio - a->r) / den; + } else { + ratio = b->i / b->r ; + den = b->r * (1 + ratio*ratio); + cr = (a->r + a->i*ratio) / den; + ci = (a->i - a->r*ratio) / den; + } + c->r = cr; + c->i = ci; +} + + +/*! \brief Returns sqrt(z.r^2 + z.i^2) */ +double z_abs(doublecomplex *z) +{ + double temp; + double real = z->r; + double imag = z->i; + + if (real < 0) real = -real; + if (imag < 0) imag = -imag; + if (imag > real) { + temp = real; + real = imag; + imag = temp; + } + if ((real+imag) == real) return(real); + + temp = imag/real; + temp = real*sqrt(1.0 + temp*temp); /*overflow!!*/ + return (temp); +} + + +/*! \brief Approximates the abs. Returns abs(z.r) + abs(z.i) */ +double z_abs1(doublecomplex *z) +{ + double real = z->r; + double imag = z->i; + + if (real < 0) real = -real; + if (imag < 0) imag = -imag; + + return (real + imag); +} + +/*! \brief Return the exponentiation */ +void z_exp(doublecomplex *r, doublecomplex *z) +{ + double expx; + + expx = exp(z->r); + r->r = expx * cos(z->i); + r->i = expx * sin(z->i); +} + +/*! \brief Return the complex conjugate */ +void d_cnjg(doublecomplex *r, doublecomplex *z) +{ + r->r = z->r; + r->i = -z->i; +} + +/*! \brief Return the imaginary part */ +double d_imag(doublecomplex *z) +{ + return (z->i); +} + + +/*! \brief SIGN functions for complex number. Returns z/abs(z) */ +doublecomplex z_sgn(doublecomplex *z) +{ + register double t = z_abs(z); + register doublecomplex retval; + + if (t == 0.0) { + retval.r = 1.0, retval.i = 0.0; + } else { + retval.r = z->r / t, retval.i = z->i / t; + } + + return retval; +} + +/*! \brief Square-root of a complex number. */ +doublecomplex z_sqrt(doublecomplex *z) +{ + doublecomplex retval; + register double cr, ci, real, imag; + + real = z->r; + imag = z->i; + + if ( imag == 0.0 ) { + retval.r = sqrt(real); + retval.i = 0.0; + } else { + ci = (sqrt(real*real + imag*imag) - real) / 2.0; + ci = sqrt(ci); + cr = imag / (2.0 * ci); + retval.r = cr; + retval.i = ci; + } + + return retval; +} + + diff --git a/src/Libraries/superlu-5.2.1/SRC/dcopy_to_ucol.c b/src/Libraries/superlu-5.2.1/SRC/dcopy_to_ucol.c new file mode 100644 index 00000000..d56f71c6 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dcopy_to_ucol.c @@ -0,0 +1,113 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dcopy_to_ucol.c + * \brief Copy a computed column of U to the compressed data structure + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + +#include "slu_ddefs.h" + +int +dcopy_to_ucol( + int jcol, /* in */ + int nseg, /* in */ + int *segrep, /* in */ + int *repfnz, /* in */ + int *perm_r, /* in */ + double *dense, /* modified - reset to zero on return */ + GlobalLU_t *Glu /* modified */ + ) +{ +/* + * Gather from SPA dense[*] to global ucol[*]. + */ + int ksub, krep, ksupno; + int i, k, kfnz, segsze; + int fsupc, isub, irow; + int jsupno, nextu; + int new_next, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + double *ucol; + int *usub, *xusub; + int nzumax; + double zero = 0.0; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + ucol = (double *) Glu->ucol; + usub = Glu->usub; + xusub = Glu->xusub; + nzumax = Glu->nzumax; + + jsupno = supno[jcol]; + nextu = xusub[jcol]; + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { + krep = segrep[k--]; + ksupno = supno[krep]; + + if ( ksupno != jsupno ) { /* Should go into ucol[] */ + kfnz = repfnz[krep]; + if ( kfnz != EMPTY ) { /* Nonzero U-segment */ + + fsupc = xsup[ksupno]; + isub = xlsub[fsupc] + kfnz - fsupc; + segsze = krep - kfnz + 1; + + new_next = nextu + segsze; + while ( new_next > nzumax ) { + if (mem_error = dLUMemXpand(jcol, nextu, UCOL, &nzumax, Glu)) + return (mem_error); + ucol = (double *) Glu->ucol; + if (mem_error = dLUMemXpand(jcol, nextu, USUB, &nzumax, Glu)) + return (mem_error); + usub = Glu->usub; + lsub = Glu->lsub; + } + + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + usub[nextu] = perm_r[irow]; + ucol[nextu] = dense[irow]; + dense[irow] = zero; + nextu++; + isub++; + } + + } + + } + + } /* for each segment... */ + + xusub[jcol + 1] = nextu; /* Close U[*,jcol] */ + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ddiagonal.c b/src/Libraries/superlu-5.2.1/SRC/ddiagonal.c new file mode 100644 index 00000000..98c79906 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ddiagonal.c @@ -0,0 +1,139 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ddiagonal.c + * \brief Auxiliary routines to work with diagonal elements + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + +#include "slu_ddefs.h" + +int dfill_diag(int n, NCformat *Astore) +/* fill explicit zeros on the diagonal entries, so that the matrix is not + structurally singular. */ +{ + double *nzval = (double *)Astore->nzval; + int *rowind = Astore->rowind; + int *colptr = Astore->colptr; + int nnz = colptr[n]; + int fill = 0; + double *nzval_new; + double zero = 0.0; + int *rowind_new; + int i, j, diag; + + for (i = 0; i < n; i++) + { + diag = -1; + for (j = colptr[i]; j < colptr[i + 1]; j++) + if (rowind[j] == i) diag = j; + if (diag < 0) fill++; + } + if (fill) + { + nzval_new = doubleMalloc(nnz + fill); + rowind_new = intMalloc(nnz + fill); + fill = 0; + for (i = 0; i < n; i++) + { + diag = -1; + for (j = colptr[i] - fill; j < colptr[i + 1]; j++) + { + if ((rowind_new[j + fill] = rowind[j]) == i) diag = j; + nzval_new[j + fill] = nzval[j]; + } + if (diag < 0) + { + rowind_new[colptr[i + 1] + fill] = i; + nzval_new[colptr[i + 1] + fill] = zero; + fill++; + } + colptr[i + 1] += fill; + } + Astore->nzval = nzval_new; + Astore->rowind = rowind_new; + SUPERLU_FREE(nzval); + SUPERLU_FREE(rowind); + } + Astore->nnz += fill; + return fill; +} + +int ddominate(int n, NCformat *Astore) +/* make the matrix diagonally dominant */ +{ + double *nzval = (double *)Astore->nzval; + int *rowind = Astore->rowind; + int *colptr = Astore->colptr; + int nnz = colptr[n]; + int fill = 0; + double *nzval_new; + int *rowind_new; + int i, j, diag; + double s; + + for (i = 0; i < n; i++) + { + diag = -1; + for (j = colptr[i]; j < colptr[i + 1]; j++) + if (rowind[j] == i) diag = j; + if (diag < 0) fill++; + } + if (fill) + { + nzval_new = doubleMalloc(nnz + fill); + rowind_new = intMalloc(nnz+ fill); + fill = 0; + for (i = 0; i < n; i++) + { + s = 1e-6; + diag = -1; + for (j = colptr[i] - fill; j < colptr[i + 1]; j++) + { + if ((rowind_new[j + fill] = rowind[j]) == i) diag = j; + s += fabs(nzval_new[j + fill] = nzval[j]); + } + if (diag >= 0) { + nzval_new[diag+fill] = s * 3.0; + } else { + rowind_new[colptr[i + 1] + fill] = i; + nzval_new[colptr[i + 1] + fill] = s * 3.0; + fill++; + } + colptr[i + 1] += fill; + } + Astore->nzval = nzval_new; + Astore->rowind = rowind_new; + SUPERLU_FREE(nzval); + SUPERLU_FREE(rowind); + } + else + { + for (i = 0; i < n; i++) + { + s = 1e-6; + diag = -1; + for (j = colptr[i]; j < colptr[i + 1]; j++) + { + if (rowind[j] == i) diag = j; + s += fabs(nzval[j]); + } + nzval[diag] = s * 3.0; + } + } + Astore->nnz += fill; + return fill; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dgscon.c b/src/Libraries/superlu-5.2.1/SRC/dgscon.c new file mode 100644 index 00000000..d51f24c3 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dgscon.c @@ -0,0 +1,168 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dgscon.c + * \brief Estimates reciprocal of the condition number of a general matrix + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * July 25, 2015
+ *
+ * Modified from lapack routines DGECON.
+ * 
+ */ + +/* + * File name: dgscon.c + * History: Modified from lapack routines DGECON. + */ +#include +#include "slu_ddefs.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   DGSCON estimates the reciprocal of the condition number of a general 
+ *   real matrix A, in either the 1-norm or the infinity-norm, using   
+ *   the LU factorization computed by DGETRF.   *
+ *
+ *   An estimate is obtained for norm(inv(A)), and the reciprocal of the   
+ *   condition number is computed as   
+ *      RCOND = 1 / ( norm(A) * norm(inv(A)) ).   
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ * 
+ *   Arguments   
+ *   =========   
+ *
+ *    NORM    (input) char*
+ *            Specifies whether the 1-norm condition number or the   
+ *            infinity-norm condition number is required:   
+ *            = '1' or 'O':  1-norm;   
+ *            = 'I':         Infinity-norm.
+ *	    
+ *    L       (input) SuperMatrix*
+ *            The factor L from the factorization Pr*A*Pc=L*U as computed by
+ *            dgstrf(). Use compressed row subscripts storage for supernodes,
+ *            i.e., L has types: Stype = SLU_SC, Dtype = SLU_D, Mtype = SLU_TRLU.
+ * 
+ *    U       (input) SuperMatrix*
+ *            The factor U from the factorization Pr*A*Pc=L*U as computed by
+ *            dgstrf(). Use column-wise storage scheme, i.e., U has types:
+ *            Stype = SLU_NC, Dtype = SLU_D, Mtype = SLU_TRU.
+ *	    
+ *    ANORM   (input) double
+ *            If NORM = '1' or 'O', the 1-norm of the original matrix A.   
+ *            If NORM = 'I', the infinity-norm of the original matrix A.
+ *	    
+ *    RCOND   (output) double*
+ *           The reciprocal of the condition number of the matrix A,   
+ *           computed as RCOND = 1/(norm(A) * norm(inv(A))).
+ *	    
+ *    INFO    (output) int*
+ *           = 0:  successful exit   
+ *           < 0:  if INFO = -i, the i-th argument had an illegal value   
+ *
+ *    ===================================================================== 
+ * 
+ */ + +void +dgscon(char *norm, SuperMatrix *L, SuperMatrix *U, + double anorm, double *rcond, SuperLUStat_t *stat, int *info) +{ + + + /* Local variables */ + int kase, kase1, onenrm, i; + double ainvnm; + double *work; + int *iwork; + int isave[3]; + extern int drscl_(int *, double *, double *, int *); + + extern int dlacon2_(int *, double *, double *, int *, double *, int *, int []); + + + /* Test the input parameters. */ + *info = 0; + onenrm = *(unsigned char *)norm == '1' || strncmp(norm, "O", 1)==0; + if (! onenrm && ! strncmp(norm, "I", 1)==0) *info = -1; + else if (L->nrow < 0 || L->nrow != L->ncol || + L->Stype != SLU_SC || L->Dtype != SLU_D || L->Mtype != SLU_TRLU) + *info = -2; + else if (U->nrow < 0 || U->nrow != U->ncol || + U->Stype != SLU_NC || U->Dtype != SLU_D || U->Mtype != SLU_TRU) + *info = -3; + if (*info != 0) { + i = -(*info); + input_error("dgscon", &i); + return; + } + + /* Quick return if possible */ + *rcond = 0.; + if ( L->nrow == 0 || U->nrow == 0) { + *rcond = 1.; + return; + } + + work = doubleCalloc( 3*L->nrow ); + iwork = intMalloc( L->nrow ); + + + if ( !work || !iwork ) + ABORT("Malloc fails for work arrays in dgscon."); + + /* Estimate the norm of inv(A). */ + ainvnm = 0.; + if ( onenrm ) kase1 = 1; + else kase1 = 2; + kase = 0; + + do { + dlacon2_(&L->nrow, &work[L->nrow], &work[0], &iwork[0], &ainvnm, &kase, isave); + + if (kase == 0) break; + + if (kase == kase1) { + /* Multiply by inv(L). */ + sp_dtrsv("L", "No trans", "Unit", L, U, &work[0], stat, info); + + /* Multiply by inv(U). */ + sp_dtrsv("U", "No trans", "Non-unit", L, U, &work[0], stat, info); + + } else { + + /* Multiply by inv(U'). */ + sp_dtrsv("U", "Transpose", "Non-unit", L, U, &work[0], stat, info); + + /* Multiply by inv(L'). */ + sp_dtrsv("L", "Transpose", "Unit", L, U, &work[0], stat, info); + + } + + } while ( kase != 0 ); + + /* Compute the estimate of the reciprocal condition number. */ + if (ainvnm != 0.) *rcond = (1. / ainvnm) / anorm; + + SUPERLU_FREE (work); + SUPERLU_FREE (iwork); + return; + +} /* dgscon */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/dgsequ.c b/src/Libraries/superlu-5.2.1/SRC/dgsequ.c new file mode 100644 index 00000000..8de29dce --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dgsequ.c @@ -0,0 +1,205 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dgsequ.c + * \brief Computes row and column scalings + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Modified from LAPACK routine DGEEQU
+ * 
+ */ +/* + * File name: dgsequ.c + * History: Modified from LAPACK routine DGEEQU + */ +#include +#include "slu_ddefs.h" + + + +/*! \brief + * + *
+ * Purpose   
+ *   =======   
+ *
+ *   DGSEQU computes row and column scalings intended to equilibrate an   
+ *   M-by-N sparse matrix A and reduce its condition number. R returns the row
+ *   scale factors and C the column scale factors, chosen to try to make   
+ *   the largest element in each row and column of the matrix B with   
+ *   elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1.   
+ *
+ *   R(i) and C(j) are restricted to be between SMLNUM = smallest safe   
+ *   number and BIGNUM = largest safe number.  Use of these scaling   
+ *   factors is not guaranteed to reduce the condition number of A but   
+ *   works well in practice.   
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   A       (input) SuperMatrix*
+ *           The matrix of dimension (A->nrow, A->ncol) whose equilibration
+ *           factors are to be computed. The type of A can be:
+ *           Stype = SLU_NC; Dtype = SLU_D; Mtype = SLU_GE.
+ *	    
+ *   R       (output) double*, size A->nrow
+ *           If INFO = 0 or INFO > M, R contains the row scale factors   
+ *           for A.
+ *	    
+ *   C       (output) double*, size A->ncol
+ *           If INFO = 0,  C contains the column scale factors for A.
+ *	    
+ *   ROWCND  (output) double*
+ *           If INFO = 0 or INFO > M, ROWCND contains the ratio of the   
+ *           smallest R(i) to the largest R(i).  If ROWCND >= 0.1 and   
+ *           AMAX is neither too large nor too small, it is not worth   
+ *           scaling by R.
+ *	    
+ *   COLCND  (output) double*
+ *           If INFO = 0, COLCND contains the ratio of the smallest   
+ *           C(i) to the largest C(i).  If COLCND >= 0.1, it is not   
+ *           worth scaling by C.
+ *	    
+ *   AMAX    (output) double*
+ *           Absolute value of largest matrix element.  If AMAX is very   
+ *           close to overflow or very close to underflow, the matrix   
+ *           should be scaled.
+ *	    
+ *   INFO    (output) int*
+ *           = 0:  successful exit   
+ *           < 0:  if INFO = -i, the i-th argument had an illegal value   
+ *           > 0:  if INFO = i,  and i is   
+ *                 <= A->nrow:  the i-th row of A is exactly zero   
+ *                 >  A->ncol:  the (i-M)-th column of A is exactly zero   
+ *
+ *   ===================================================================== 
+ * 
+ */ +void +dgsequ(SuperMatrix *A, double *r, double *c, double *rowcnd, + double *colcnd, double *amax, int *info) +{ + + + /* Local variables */ + NCformat *Astore; + double *Aval; + int i, j, irow; + double rcmin, rcmax; + double bignum, smlnum; + extern double dmach(char *); + + /* Test the input parameters. */ + *info = 0; + if ( A->nrow < 0 || A->ncol < 0 || + A->Stype != SLU_NC || A->Dtype != SLU_D || A->Mtype != SLU_GE ) + *info = -1; + if (*info != 0) { + i = -(*info); + input_error("dgsequ", &i); + return; + } + + /* Quick return if possible */ + if ( A->nrow == 0 || A->ncol == 0 ) { + *rowcnd = 1.; + *colcnd = 1.; + *amax = 0.; + return; + } + + Astore = A->Store; + Aval = Astore->nzval; + + /* Get machine constants. */ + smlnum = dmach("S"); /* slamch_("S"); */ + bignum = 1. / smlnum; + + /* Compute row scale factors. */ + for (i = 0; i < A->nrow; ++i) r[i] = 0.; + + /* Find the maximum element in each row. */ + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + r[irow] = SUPERLU_MAX( r[irow], fabs(Aval[i]) ); + } + + /* Find the maximum and minimum scale factors. */ + rcmin = bignum; + rcmax = 0.; + for (i = 0; i < A->nrow; ++i) { + rcmax = SUPERLU_MAX(rcmax, r[i]); + rcmin = SUPERLU_MIN(rcmin, r[i]); + } + *amax = rcmax; + + if (rcmin == 0.) { + /* Find the first zero scale factor and return an error code. */ + for (i = 0; i < A->nrow; ++i) + if (r[i] == 0.) { + *info = i + 1; + return; + } + } else { + /* Invert the scale factors. */ + for (i = 0; i < A->nrow; ++i) + r[i] = 1. / SUPERLU_MIN( SUPERLU_MAX( r[i], smlnum ), bignum ); + /* Compute ROWCND = min(R(I)) / max(R(I)) */ + *rowcnd = SUPERLU_MAX( rcmin, smlnum ) / SUPERLU_MIN( rcmax, bignum ); + } + + /* Compute column scale factors */ + for (j = 0; j < A->ncol; ++j) c[j] = 0.; + + /* Find the maximum element in each column, assuming the row + scalings computed above. */ + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + c[j] = SUPERLU_MAX( c[j], fabs(Aval[i]) * r[irow] ); + } + + /* Find the maximum and minimum scale factors. */ + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->ncol; ++j) { + rcmax = SUPERLU_MAX(rcmax, c[j]); + rcmin = SUPERLU_MIN(rcmin, c[j]); + } + + if (rcmin == 0.) { + /* Find the first zero scale factor and return an error code. */ + for (j = 0; j < A->ncol; ++j) + if ( c[j] == 0. ) { + *info = A->nrow + j + 1; + return; + } + } else { + /* Invert the scale factors. */ + for (j = 0; j < A->ncol; ++j) + c[j] = 1. / SUPERLU_MIN( SUPERLU_MAX( c[j], smlnum ), bignum); + /* Compute COLCND = min(C(J)) / max(C(J)) */ + *colcnd = SUPERLU_MAX( rcmin, smlnum ) / SUPERLU_MIN( rcmax, bignum ); + } + + return; + +} /* dgsequ */ + + diff --git a/src/Libraries/superlu-5.2.1/SRC/dgsisx.c b/src/Libraries/superlu-5.2.1/SRC/dgsisx.c new file mode 100644 index 00000000..17651db3 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dgsisx.c @@ -0,0 +1,738 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dgsisx.c + * \brief Computes an approximate solutions of linear equations A*X=B or A'*X=B + * + *
+ * -- SuperLU routine (version 4.2) --
+ * Lawrence Berkeley National Laboratory.
+ * November, 2010
+ * August, 2011
+ * 
+ */ +#include "slu_ddefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * DGSISX computes an approximate solutions of linear equations
+ * A*X=B or A'*X=B, using the ILU factorization from dgsitrf().
+ * An estimation of the condition number is provided. 
+ * The routine performs the following steps:
+ *
+ *   1. If A is stored column-wise (A->Stype = SLU_NC):
+ *  
+ *	1.1. If options->Equil = YES or options->RowPerm = LargeDiag, scaling
+ *	     factors are computed to equilibrate the system:
+ *	     options->Trans = NOTRANS:
+ *		 diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *	     options->Trans = TRANS:
+ *		 (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *	     options->Trans = CONJ:
+ *		 (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *	     Whether or not the system will be equilibrated depends on the
+ *	     scaling of the matrix A, but if equilibration is used, A is
+ *	     overwritten by diag(R)*A*diag(C) and B by diag(R)*B
+ *	     (if options->Trans=NOTRANS) or diag(C)*B (if options->Trans
+ *	     = TRANS or CONJ).
+ *
+ *	1.2. Permute columns of A, forming A*Pc, where Pc is a permutation
+ *	     matrix that usually preserves sparsity.
+ *	     For more details of this step, see sp_preorder.c.
+ *
+ *	1.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *	     factor the matrix A (after equilibration if options->Equil = YES)
+ *	     as Pr*A*Pc = L*U, with Pr determined by partial pivoting.
+ *
+ *	1.4. Compute the reciprocal pivot growth factor.
+ *
+ *	1.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *	     routine fills a small number on the diagonal entry, that is
+ *		U(i,i) = ||A(:,i)||_oo * options->ILU_FillTol ** (1 - i / n),
+ *	     and info will be increased by 1. The factored form of A is used
+ *	     to estimate the condition number of the preconditioner. If the
+ *	     reciprocal of the condition number is less than machine precision,
+ *	     info = A->ncol+1 is returned as a warning, but the routine still
+ *	     goes on to solve for X.
+ *
+ *	1.6. The system of equations is solved for X using the factored form
+ *	     of A.
+ *
+ *	1.7. options->IterRefine is not used
+ *
+ *	1.8. If equilibration was used, the matrix X is premultiplied by
+ *	     diag(C) (if options->Trans = NOTRANS) or diag(R)
+ *	     (if options->Trans = TRANS or CONJ) so that it solves the
+ *	     original system before equilibration.
+ *
+ *	1.9. options for ILU only
+ *	     1) If options->RowPerm = LargeDiag, MC64 is used to scale and
+ *		permute the matrix to an I-matrix, that is Pr*Dr*A*Dc has
+ *		entries of modulus 1 on the diagonal and off-diagonal entries
+ *		of modulus at most 1. If MC64 fails, dgsequ() is used to
+ *		equilibrate the system.
+ *              ( Default: LargeDiag )
+ *	     2) options->ILU_DropTol = tau is the threshold for dropping.
+ *		For L, it is used directly (for the whole row in a supernode);
+ *		For U, ||A(:,i)||_oo * tau is used as the threshold
+ *	        for the	i-th column.
+ *		If a secondary dropping rule is required, tau will
+ *	        also be used to compute the second threshold.
+ *              ( Default: 1e-4 )
+ *	     3) options->ILU_FillFactor = gamma, used as the initial guess
+ *		of memory growth.
+ *		If a secondary dropping rule is required, it will also
+ *              be used as an upper bound of the memory.
+ *              ( Default: 10 )
+ *	     4) options->ILU_DropRule specifies the dropping rule.
+ *		Option	      Meaning
+ *		======	      ===========
+ *		DROP_BASIC:   Basic dropping rule, supernodal based ILUTP(tau).
+ *		DROP_PROWS:   Supernodal based ILUTP(p,tau), p = gamma*nnz(A)/n.
+ *		DROP_COLUMN:  Variant of ILUTP(p,tau), for j-th column,
+ *			      p = gamma * nnz(A(:,j)).
+ *		DROP_AREA:    Variation of ILUTP, for j-th column, use
+ *			      nnz(F(:,1:j)) / nnz(A(:,1:j)) to control memory.
+ *		DROP_DYNAMIC: Modify the threshold tau during factorizaion:
+ *			      If nnz(L(:,1:j)) / nnz(A(:,1:j)) > gamma
+ *				  tau_L(j) := MIN(tau_0, tau_L(j-1) * 2);
+ *			      Otherwise
+ *				  tau_L(j) := MAX(tau_0, tau_L(j-1) / 2);
+ *			      tau_U(j) uses the similar rule.
+ *			      NOTE: the thresholds used by L and U are separate.
+ *		DROP_INTERP:  Compute the second dropping threshold by
+ *			      interpolation instead of sorting (default).
+ *			      In this case, the actual fill ratio is not
+ *			      guaranteed smaller than gamma.
+ *		DROP_PROWS, DROP_COLUMN and DROP_AREA are mutually exclusive.
+ *		( Default: DROP_BASIC | DROP_AREA )
+ *	     5) options->ILU_Norm is the criterion of measuring the magnitude
+ *		of a row in a supernode of L. ( Default is INF_NORM )
+ *		options->ILU_Norm	RowSize(x[1:n])
+ *		=================	===============
+ *		ONE_NORM		||x||_1 / n
+ *		TWO_NORM		||x||_2 / sqrt(n)
+ *		INF_NORM		max{|x[i]|}
+ *	     6) options->ILU_MILU specifies the type of MILU's variation.
+ *		= SILU: do not perform Modified ILU;
+ *		= SMILU_1 (not recommended):
+ *		    U(i,i) := U(i,i) + sum(dropped entries);
+ *		= SMILU_2:
+ *		    U(i,i) := U(i,i) + SGN(U(i,i)) * sum(dropped entries);
+ *		= SMILU_3:
+ *		    U(i,i) := U(i,i) + SGN(U(i,i)) * sum(|dropped entries|);
+ *		NOTE: Even SMILU_1 does not preserve the column sum because of
+ *		late dropping.
+ *              ( Default: SILU )
+ *	     7) options->ILU_FillTol is used as the perturbation when
+ *		encountering zero pivots. If some U(i,i) = 0, so that U is
+ *		exactly singular, then
+ *		   U(i,i) := ||A(:,i)|| * options->ILU_FillTol ** (1 - i / n).
+ *              ( Default: 1e-2 )
+ *
+ *   2. If A is stored row-wise (A->Stype = SLU_NR), apply the above algorithm
+ *	to the transpose of A:
+ *
+ *	2.1. If options->Equil = YES or options->RowPerm = LargeDiag, scaling
+ *	     factors are computed to equilibrate the system:
+ *	     options->Trans = NOTRANS:
+ *		 diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *	     options->Trans = TRANS:
+ *		 (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *	     options->Trans = CONJ:
+ *		 (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *	     Whether or not the system will be equilibrated depends on the
+ *	     scaling of the matrix A, but if equilibration is used, A' is
+ *	     overwritten by diag(R)*A'*diag(C) and B by diag(R)*B
+ *	     (if trans='N') or diag(C)*B (if trans = 'T' or 'C').
+ *
+ *	2.2. Permute columns of transpose(A) (rows of A),
+ *	     forming transpose(A)*Pc, where Pc is a permutation matrix that
+ *	     usually preserves sparsity.
+ *	     For more details of this step, see sp_preorder.c.
+ *
+ *	2.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *	     factor the transpose(A) (after equilibration if
+ *	     options->Fact = YES) as Pr*transpose(A)*Pc = L*U with the
+ *	     permutation Pr determined by partial pivoting.
+ *
+ *	2.4. Compute the reciprocal pivot growth factor.
+ *
+ *	2.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *	     routine fills a small number on the diagonal entry, that is
+ *		 U(i,i) = ||A(:,i)||_oo * options->ILU_FillTol ** (1 - i / n).
+ *	     And info will be increased by 1. The factored form of A is used
+ *	     to estimate the condition number of the preconditioner. If the
+ *	     reciprocal of the condition number is less than machine precision,
+ *	     info = A->ncol+1 is returned as a warning, but the routine still
+ *	     goes on to solve for X.
+ *
+ *	2.6. The system of equations is solved for X using the factored form
+ *	     of transpose(A).
+ *
+ *	2.7. If options->IterRefine is not used.
+ *
+ *	2.8. If equilibration was used, the matrix X is premultiplied by
+ *	     diag(C) (if options->Trans = NOTRANS) or diag(R)
+ *	     (if options->Trans = TRANS or CONJ) so that it solves the
+ *	     original system before equilibration.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *	   The structure defines the input parameters to control
+ *	   how the LU decomposition will be performed and how the
+ *	   system will be solved.
+ *
+ * A	   (input/output) SuperMatrix*
+ *	   Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
+ *	   of the linear equations is A->nrow. Currently, the type of A can be:
+ *	   Stype = SLU_NC or SLU_NR, Dtype = SLU_D, Mtype = SLU_GE.
+ *	   In the future, more general A may be handled.
+ *
+ *	   On entry, If options->Fact = FACTORED and equed is not 'N',
+ *	   then A must have been equilibrated by the scaling factors in
+ *	   R and/or C.
+ *	   On exit, A is not modified
+ *         if options->Equil = NO, or
+ *         if options->Equil = YES but equed = 'N' on exit, or
+ *         if options->RowPerm = NO.
+ *
+ *	   Otherwise, if options->Equil = YES and equed is not 'N',
+ *	   A is scaled as follows:
+ *	   If A->Stype = SLU_NC:
+ *	     equed = 'R':  A := diag(R) * A
+ *	     equed = 'C':  A := A * diag(C)
+ *	     equed = 'B':  A := diag(R) * A * diag(C).
+ *	   If A->Stype = SLU_NR:
+ *	     equed = 'R':  transpose(A) := diag(R) * transpose(A)
+ *	     equed = 'C':  transpose(A) := transpose(A) * diag(C)
+ *	     equed = 'B':  transpose(A) := diag(R) * transpose(A) * diag(C).
+ *
+ *         If options->RowPerm = LargeDiag, MC64 is used to scale and permute
+ *            the matrix to an I-matrix, that is A is modified as follows:
+ *            P*Dr*A*Dc has entries of modulus 1 on the diagonal and 
+ *            off-diagonal entries of modulus at most 1. P is a permutation
+ *            obtained from MC64.
+ *            If MC64 fails, dgsequ() is used to equilibrate the system,
+ *            and A is scaled as above, but no permutation is involved.
+ *            On exit, A is restored to the orginal row numbering, so
+ *            Dr*A*Dc is returned.
+ *
+ * perm_c  (input/output) int*
+ *	   If A->Stype = SLU_NC, Column permutation vector of size A->ncol,
+ *	   which defines the permutation matrix Pc; perm_c[i] = j means
+ *	   column i of A is in position j in A*Pc.
+ *	   On exit, perm_c may be overwritten by the product of the input
+ *	   perm_c and a permutation that postorders the elimination tree
+ *	   of Pc'*A'*A*Pc; perm_c is not changed if the elimination tree
+ *	   is already in postorder.
+ *
+ *	   If A->Stype = SLU_NR, column permutation vector of size A->nrow,
+ *	   which describes permutation of columns of transpose(A) 
+ *	   (rows of A) as described above.
+ *
+ * perm_r  (input/output) int*
+ *	   If A->Stype = SLU_NC, row permutation vector of size A->nrow, 
+ *	   which defines the permutation matrix Pr, and is determined
+ *	   by MC64 first then followed by partial pivoting.
+ *         perm_r[i] = j means row i of A is in position j in Pr*A.
+ *
+ *	   If A->Stype = SLU_NR, permutation vector of size A->ncol, which
+ *	   determines permutation of rows of transpose(A)
+ *	   (columns of A) as described above.
+ *
+ *	   If options->Fact = SamePattern_SameRowPerm, the pivoting routine
+ *	   will try to use the input perm_r, unless a certain threshold
+ *	   criterion is violated. In that case, perm_r is overwritten by a
+ *	   new permutation determined by partial pivoting or diagonal
+ *	   threshold pivoting.
+ *	   Otherwise, perm_r is output argument.
+ *
+ * etree   (input/output) int*,  dimension (A->ncol)
+ *	   Elimination tree of Pc'*A'*A*Pc.
+ *	   If options->Fact != FACTORED and options->Fact != DOFACT,
+ *	   etree is an input argument, otherwise it is an output argument.
+ *	   Note: etree is a vector of parent pointers for a forest whose
+ *	   vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *
+ * equed   (input/output) char*
+ *	   Specifies the form of equilibration that was done.
+ *	   = 'N': No equilibration.
+ *	   = 'R': Row equilibration, i.e., A was premultiplied by diag(R).
+ *	   = 'C': Column equilibration, i.e., A was postmultiplied by diag(C).
+ *	   = 'B': Both row and column equilibration, i.e., A was replaced 
+ *		  by diag(R)*A*diag(C).
+ *	   If options->Fact = FACTORED, equed is an input argument,
+ *	   otherwise it is an output argument.
+ *
+ * R	   (input/output) double*, dimension (A->nrow)
+ *	   The row scale factors for A or transpose(A).
+ *	   If equed = 'R' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *	       (if A->Stype = SLU_NR) is multiplied on the left by diag(R).
+ *	   If equed = 'N' or 'C', R is not accessed.
+ *	   If options->Fact = FACTORED, R is an input argument,
+ *	       otherwise, R is output.
+ *	   If options->Fact = FACTORED and equed = 'R' or 'B', each element
+ *	       of R must be positive.
+ *
+ * C	   (input/output) double*, dimension (A->ncol)
+ *	   The column scale factors for A or transpose(A).
+ *	   If equed = 'C' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *	       (if A->Stype = SLU_NR) is multiplied on the right by diag(C).
+ *	   If equed = 'N' or 'R', C is not accessed.
+ *	   If options->Fact = FACTORED, C is an input argument,
+ *	       otherwise, C is output.
+ *	   If options->Fact = FACTORED and equed = 'C' or 'B', each element
+ *	       of C must be positive.
+ *
+ * L	   (output) SuperMatrix*
+ *	   The factor L from the factorization
+ *	       Pr*A*Pc=L*U		(if A->Stype SLU_= NC) or
+ *	       Pr*transpose(A)*Pc=L*U	(if A->Stype = SLU_NR).
+ *	   Uses compressed row subscripts storage for supernodes, i.e.,
+ *	   L has types: Stype = SLU_SC, Dtype = SLU_D, Mtype = SLU_TRLU.
+ *
+ * U	   (output) SuperMatrix*
+ *	   The factor U from the factorization
+ *	       Pr*A*Pc=L*U		(if A->Stype = SLU_NC) or
+ *	       Pr*transpose(A)*Pc=L*U	(if A->Stype = SLU_NR).
+ *	   Uses column-wise storage scheme, i.e., U has types:
+ *	   Stype = SLU_NC, Dtype = SLU_D, Mtype = SLU_TRU.
+ *
+ * work    (workspace/output) void*, size (lwork) (in bytes)
+ *	   User supplied workspace, should be large enough
+ *	   to hold data structures for factors L and U.
+ *	   On exit, if fact is not 'F', L and U point to this array.
+ *
+ * lwork   (input) int
+ *	   Specifies the size of work array in bytes.
+ *	   = 0:  allocate space internally by system malloc;
+ *	   > 0:  use user-supplied work array of length lwork in bytes,
+ *		 returns error if space runs out.
+ *	   = -1: the routine guesses the amount of space needed without
+ *		 performing the factorization, and returns it in
+ *		 mem_usage->total_needed; no other side effects.
+ *
+ *	   See argument 'mem_usage' for memory usage statistics.
+ *
+ * B	   (input/output) SuperMatrix*
+ *	   B has types: Stype = SLU_DN, Dtype = SLU_D, Mtype = SLU_GE.
+ *	   On entry, the right hand side matrix.
+ *	   If B->ncol = 0, only LU decomposition is performed, the triangular
+ *			   solve is skipped.
+ *	   On exit,
+ *	      if equed = 'N', B is not modified; otherwise
+ *	      if A->Stype = SLU_NC:
+ *		 if options->Trans = NOTRANS and equed = 'R' or 'B',
+ *		    B is overwritten by diag(R)*B;
+ *		 if options->Trans = TRANS or CONJ and equed = 'C' of 'B',
+ *		    B is overwritten by diag(C)*B;
+ *	      if A->Stype = SLU_NR:
+ *		 if options->Trans = NOTRANS and equed = 'C' or 'B',
+ *		    B is overwritten by diag(C)*B;
+ *		 if options->Trans = TRANS or CONJ and equed = 'R' of 'B',
+ *		    B is overwritten by diag(R)*B.
+ *
+ * X	   (output) SuperMatrix*
+ *	   X has types: Stype = SLU_DN, Dtype = SLU_D, Mtype = SLU_GE.
+ *	   If info = 0 or info = A->ncol+1, X contains the solution matrix
+ *	   to the original system of equations. Note that A and B are modified
+ *	   on exit if equed is not 'N', and the solution to the equilibrated
+ *	   system is inv(diag(C))*X if options->Trans = NOTRANS and
+ *	   equed = 'C' or 'B', or inv(diag(R))*X if options->Trans = 'T' or 'C'
+ *	   and equed = 'R' or 'B'.
+ *
+ * recip_pivot_growth (output) double*
+ *	   The reciprocal pivot growth factor max_j( norm(A_j)/norm(U_j) ).
+ *	   The infinity norm is used. If recip_pivot_growth is much less
+ *	   than 1, the stability of the LU factorization could be poor.
+ *
+ * rcond   (output) double*
+ *	   The estimate of the reciprocal condition number of the matrix A
+ *	   after equilibration (if done). If rcond is less than the machine
+ *	   precision (in particular, if rcond = 0), the matrix is singular
+ *	   to working precision. This condition is indicated by a return
+ *	   code of info > 0.
+ *
+ * mem_usage (output) mem_usage_t*
+ *	   Record the memory usage statistics, consisting of following fields:
+ *	   - for_lu (float)
+ *	     The amount of space used in bytes for L\U data structures.
+ *	   - total_needed (float)
+ *	     The amount of space needed in bytes to perform factorization.
+ *	   - expansions (int)
+ *	     The number of memory expansions during the LU factorization.
+ *
+ * stat   (output) SuperLUStat_t*
+ *	  Record the statistics on runtime and floating-point operation count.
+ *	  See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ *	   = 0: successful exit
+ *	   < 0: if info = -i, the i-th argument had an illegal value
+ *	   > 0: if info = i, and i is
+ *		<= A->ncol: number of zero pivots. They are replaced by small
+ *		      entries due to options->ILU_FillTol.
+ *		= A->ncol+1: U is nonsingular, but RCOND is less than machine
+ *		      precision, meaning that the matrix is singular to
+ *		      working precision. Nevertheless, the solution and
+ *		      error bounds are computed because there are a number
+ *		      of situations where the computed solution can be more
+ *		      accurate than the value of RCOND would suggest.
+ *		> A->ncol+1: number of bytes allocated when memory allocation
+ *		      failure occurred, plus A->ncol.
+ * 
+ */ + +void +dgsisx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, + int *etree, char *equed, double *R, double *C, + SuperMatrix *L, SuperMatrix *U, void *work, int lwork, + SuperMatrix *B, SuperMatrix *X, + double *recip_pivot_growth, double *rcond, + GlobalLU_t *Glu, mem_usage_t *mem_usage, SuperLUStat_t *stat, int *info) +{ + + DNformat *Bstore, *Xstore; + double *Bmat, *Xmat; + int ldb, ldx, nrhs, n; + SuperMatrix *AA;/* A in SLU_NC format used by the factorization routine.*/ + SuperMatrix AC; /* Matrix postmultiplied by Pc */ + int colequ, equil, nofact, notran, rowequ, permc_spec, mc64; + trans_t trant; + char norm[1]; + int i, j, info1; + double amax, anorm, bignum, smlnum, colcnd, rowcnd, rcmax, rcmin; + int relax, panel_size; + double diag_pivot_thresh; + double t0; /* temporary time */ + double *utime; + + int *perm = NULL; /* permutation returned from MC64 */ + + /* External functions */ + extern double dlangs(char *, SuperMatrix *); + + Bstore = B->Store; + Xstore = X->Store; + Bmat = Bstore->nzval; + Xmat = Xstore->nzval; + ldb = Bstore->lda; + ldx = Xstore->lda; + nrhs = B->ncol; + n = B->nrow; + + *info = 0; + nofact = (options->Fact != FACTORED); + equil = (options->Equil == YES); + notran = (options->Trans == NOTRANS); + mc64 = (options->RowPerm == LargeDiag); + if ( nofact ) { + *(unsigned char *)equed = 'N'; + rowequ = FALSE; + colequ = FALSE; + } else { + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + smlnum = dmach("Safe minimum"); /* lamch_("Safe minimum"); */ + bignum = 1. / smlnum; + } + + /* Test the input parameters */ + if (options->Fact != DOFACT && options->Fact != SamePattern && + options->Fact != SamePattern_SameRowPerm && + options->Fact != FACTORED && + options->Trans != NOTRANS && options->Trans != TRANS && + options->Trans != CONJ && + options->Equil != NO && options->Equil != YES) + *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + (A->Stype != SLU_NC && A->Stype != SLU_NR) || + A->Dtype != SLU_D || A->Mtype != SLU_GE ) + *info = -2; + else if ( options->Fact == FACTORED && + !(rowequ || colequ || strncmp(equed, "N", 1)==0) ) + *info = -6; + else { + if (rowequ) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, R[j]); + rcmax = SUPERLU_MAX(rcmax, R[j]); + } + if (rcmin <= 0.) *info = -7; + else if ( A->nrow > 0) + rowcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else rowcnd = 1.; + } + if (colequ && *info == 0) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, C[j]); + rcmax = SUPERLU_MAX(rcmax, C[j]); + } + if (rcmin <= 0.) *info = -8; + else if (A->nrow > 0) + colcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else colcnd = 1.; + } + if (*info == 0) { + if ( lwork < -1 ) *info = -12; + else if ( B->ncol < 0 || Bstore->lda < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_D || + B->Mtype != SLU_GE ) + *info = -13; + else if ( X->ncol < 0 || Xstore->lda < SUPERLU_MAX(0, A->nrow) || + (B->ncol != 0 && B->ncol != X->ncol) || + X->Stype != SLU_DN || + X->Dtype != SLU_D || X->Mtype != SLU_GE ) + *info = -14; + } + } + if (*info != 0) { + i = -(*info); + input_error("dgsisx", &i); + return; + } + + /* Initialization for factor parameters */ + panel_size = sp_ienv(1); + relax = sp_ienv(2); + diag_pivot_thresh = options->DiagPivotThresh; + + utime = stat->utime; + + /* Convert A to SLU_NC format when necessary. */ + if ( A->Stype == SLU_NR ) { + NRformat *Astore = A->Store; + AA = (SuperMatrix *) SUPERLU_MALLOC( sizeof(SuperMatrix) ); + dCreate_CompCol_Matrix(AA, A->ncol, A->nrow, Astore->nnz, + Astore->nzval, Astore->colind, Astore->rowptr, + SLU_NC, A->Dtype, A->Mtype); + if ( notran ) { /* Reverse the transpose argument. */ + trant = TRANS; + notran = 0; + } else { + trant = NOTRANS; + notran = 1; + } + } else { /* A->Stype == SLU_NC */ + trant = options->Trans; + AA = A; + } + + if ( nofact ) { + register int i, j; + NCformat *Astore = AA->Store; + int nnz = Astore->nnz; + int *colptr = Astore->colptr; + int *rowind = Astore->rowind; + double *nzval = (double *)Astore->nzval; + + if ( mc64 ) { + t0 = SuperLU_timer_(); + if ((perm = intMalloc(n)) == NULL) + ABORT("SUPERLU_MALLOC fails for perm[]"); + + info1 = dldperm(5, n, nnz, colptr, rowind, nzval, perm, R, C); + + if (info1 != 0) { /* MC64 fails, call dgsequ() later */ + mc64 = 0; + SUPERLU_FREE(perm); + perm = NULL; + } else { + if ( equil ) { + rowequ = colequ = 1; + for (i = 0; i < n; i++) { + R[i] = exp(R[i]); + C[i] = exp(C[i]); + } + /* scale the matrix */ + for (j = 0; j < n; j++) { + for (i = colptr[j]; i < colptr[j + 1]; i++) { + nzval[i] *= R[rowind[i]] * C[j]; + } + } + *equed = 'B'; + } + + /* permute the matrix */ + for (j = 0; j < n; j++) { + for (i = colptr[j]; i < colptr[j + 1]; i++) { + /*nzval[i] *= R[rowind[i]] * C[j];*/ + rowind[i] = perm[rowind[i]]; + } + } + } + utime[EQUIL] = SuperLU_timer_() - t0; + } + + if ( !mc64 & equil ) { /* Only perform equilibration, no row perm */ + t0 = SuperLU_timer_(); + /* Compute row and column scalings to equilibrate the matrix A. */ + dgsequ(AA, R, C, &rowcnd, &colcnd, &amax, &info1); + + if ( info1 == 0 ) { + /* Equilibrate matrix A. */ + dlaqgs(AA, R, C, rowcnd, colcnd, amax, equed); + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + } + utime[EQUIL] = SuperLU_timer_() - t0; + } + } + + + if ( nofact ) { + + t0 = SuperLU_timer_(); + /* + * Gnet column permutation vector perm_c[], according to permc_spec: + * permc_spec = NATURAL: natural ordering + * permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A + * permc_spec = MMD_ATA: minimum degree on structure of A'*A + * permc_spec = COLAMD: approximate minimum degree column ordering + * permc_spec = MY_PERMC: the ordering already supplied in perm_c[] + */ + permc_spec = options->ColPerm; + if ( permc_spec != MY_PERMC && options->Fact == DOFACT ) + get_perm_c(permc_spec, AA, perm_c); + utime[COLPERM] = SuperLU_timer_() - t0; + + t0 = SuperLU_timer_(); + sp_preorder(options, AA, perm_c, etree, &AC); + utime[ETREE] = SuperLU_timer_() - t0; + + /* Compute the LU factorization of A*Pc. */ + t0 = SuperLU_timer_(); + dgsitrf(options, &AC, relax, panel_size, etree, work, lwork, + perm_c, perm_r, L, U, Glu, stat, info); + utime[FACT] = SuperLU_timer_() - t0; + + if ( lwork == -1 ) { + mem_usage->total_needed = *info - A->ncol; + return; + } + + if ( mc64 ) { /* Fold MC64's perm[] into perm_r[]. */ + NCformat *Astore = AA->Store; + int nnz = Astore->nnz, *rowind = Astore->rowind; + int *perm_tmp, *iperm; + if ((perm_tmp = intMalloc(2*n)) == NULL) + ABORT("SUPERLU_MALLOC fails for perm_tmp[]"); + iperm = perm_tmp + n; + for (i = 0; i < n; ++i) perm_tmp[i] = perm_r[perm[i]]; + for (i = 0; i < n; ++i) { + perm_r[i] = perm_tmp[i]; + iperm[perm[i]] = i; + } + + /* Restore A's original row indices. */ + for (i = 0; i < nnz; ++i) rowind[i] = iperm[rowind[i]]; + + SUPERLU_FREE(perm); /* MC64 permutation */ + SUPERLU_FREE(perm_tmp); + } + } + + if ( options->PivotGrowth ) { + if ( *info > 0 ) return; + + /* Compute the reciprocal pivot growth factor *recip_pivot_growth. */ + *recip_pivot_growth = dPivotGrowth(A->ncol, AA, perm_c, L, U); + } + + if ( options->ConditionNumber ) { + /* Estimate the reciprocal of the condition number of A. */ + t0 = SuperLU_timer_(); + if ( notran ) { + *(unsigned char *)norm = '1'; + } else { + *(unsigned char *)norm = 'I'; + } + anorm = dlangs(norm, AA); + dgscon(norm, L, U, anorm, rcond, stat, &info1); + utime[RCOND] = SuperLU_timer_() - t0; + } + + if ( nrhs > 0 ) { /* Solve the system */ + double *rhs_work; + + /* Scale and permute the right-hand side if equilibration + and permutation from MC64 were performed. */ + if ( notran ) { + if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) + Bmat[i + j*ldb] *= R[i]; + } + } else if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) { + Bmat[i + j*ldb] *= C[i]; + } + } + + /* Compute the solution matrix X. */ + for (j = 0; j < nrhs; j++) /* Save a copy of the right hand sides */ + for (i = 0; i < B->nrow; i++) + Xmat[i + j*ldx] = Bmat[i + j*ldb]; + + t0 = SuperLU_timer_(); + dgstrs (trant, L, U, perm_c, perm_r, X, stat, &info1); + utime[SOLVE] = SuperLU_timer_() - t0; + + /* Transform the solution matrix X to a solution of the original + system. */ + if ( notran ) { + if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) { + Xmat[i + j*ldx] *= C[i]; + } + } + } else { /* transposed system */ + if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) { + Xmat[i + j*ldx] *= R[i]; + } + } + } + + } /* end if nrhs > 0 */ + + if ( options->ConditionNumber ) { + /* The matrix is singular to working precision. */ + /* if ( *rcond < dlamch_("E") && *info == 0) *info = A->ncol + 1; */ + if ( *rcond < dmach("E") && *info == 0) *info = A->ncol + 1; + } + + if ( nofact ) { + ilu_dQuerySpace(L, U, mem_usage); + Destroy_CompCol_Permuted(&AC); + } + if ( A->Stype == SLU_NR ) { + Destroy_SuperMatrix_Store(AA); + SUPERLU_FREE(AA); + } + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dgsitrf.c b/src/Libraries/superlu-5.2.1/SRC/dgsitrf.c new file mode 100644 index 00000000..d95b2287 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dgsitrf.c @@ -0,0 +1,663 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dgsitrf.c + * \brief Computes an ILU factorization of a general sparse matrix + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ *
+ * 
+ */ + +#include "slu_ddefs.h" + +#ifdef DEBUG +int num_drop_L; +#endif + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * DGSITRF computes an ILU factorization of a general sparse m-by-n
+ * matrix A using partial pivoting with row interchanges.
+ * The factorization has the form
+ *     Pr * A = L * U
+ * where Pr is a row permutation matrix, L is lower triangular with unit
+ * diagonal elements (lower trapezoidal if A->nrow > A->ncol), and U is upper
+ * triangular (upper trapezoidal if A->nrow < A->ncol).
+ *
+ * See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *	   The structure defines the input parameters to control
+ *	   how the ILU decomposition will be performed.
+ *
+ * A	    (input) SuperMatrix*
+ *	    Original matrix A, permuted by columns, of dimension
+ *	    (A->nrow, A->ncol). The type of A can be:
+ *	    Stype = SLU_NCP; Dtype = SLU_D; Mtype = SLU_GE.
+ *
+ * relax    (input) int
+ *	    To control degree of relaxing supernodes. If the number
+ *	    of nodes (columns) in a subtree of the elimination tree is less
+ *	    than relax, this subtree is considered as one supernode,
+ *	    regardless of the row structures of those columns.
+ *
+ * panel_size (input) int
+ *	    A panel consists of at most panel_size consecutive columns.
+ *
+ * etree    (input) int*, dimension (A->ncol)
+ *	    Elimination tree of A'*A.
+ *	    Note: etree is a vector of parent pointers for a forest whose
+ *	    vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *	    On input, the columns of A should be permuted so that the
+ *	    etree is in a certain postorder.
+ *
+ * work     (input/output) void*, size (lwork) (in bytes)
+ *	    User-supplied work space and space for the output data structures.
+ *	    Not referenced if lwork = 0;
+ *
+ * lwork   (input) int
+ *	   Specifies the size of work array in bytes.
+ *	   = 0:  allocate space internally by system malloc;
+ *	   > 0:  use user-supplied work array of length lwork in bytes,
+ *		 returns error if space runs out.
+ *	   = -1: the routine guesses the amount of space needed without
+ *		 performing the factorization, and returns it in
+ *		 *info; no other side effects.
+ *
+ * perm_c   (input) int*, dimension (A->ncol)
+ *	    Column permutation vector, which defines the
+ *	    permutation matrix Pc; perm_c[i] = j means column i of A is
+ *	    in position j in A*Pc.
+ *	    When searching for diagonal, perm_c[*] is applied to the
+ *	    row subscripts of A, so that diagonal threshold pivoting
+ *	    can find the diagonal of A, rather than that of A*Pc.
+ *
+ * perm_r   (input/output) int*, dimension (A->nrow)
+ *	    Row permutation vector which defines the permutation matrix Pr,
+ *	    perm_r[i] = j means row i of A is in position j in Pr*A.
+ *	    If options->Fact = SamePattern_SameRowPerm, the pivoting routine
+ *	       will try to use the input perm_r, unless a certain threshold
+ *	       criterion is violated. In that case, perm_r is overwritten by
+ *	       a new permutation determined by partial pivoting or diagonal
+ *	       threshold pivoting.
+ *	    Otherwise, perm_r is output argument;
+ *
+ * L	    (output) SuperMatrix*
+ *	    The factor L from the factorization Pr*A=L*U; use compressed row
+ *	    subscripts storage for supernodes, i.e., L has type:
+ *	    Stype = SLU_SC, Dtype = SLU_D, Mtype = SLU_TRLU.
+ *
+ * U	    (output) SuperMatrix*
+ *	    The factor U from the factorization Pr*A*Pc=L*U. Use column-wise
+ *	    storage scheme, i.e., U has types: Stype = SLU_NC,
+ *	    Dtype = SLU_D, Mtype = SLU_TRU.
+ *
+ * Glu      (input/output) GlobalLU_t *
+ *          If options->Fact == SamePattern_SameRowPerm, it is an input;
+ *              The matrix A will be factorized assuming that a 
+ *              factorization of a matrix with the same sparsity pattern
+ *              and similar numerical values was performed prior to this one.
+ *              Therefore, this factorization will reuse both row and column
+ *		scaling factors R and C, both row and column permutation
+ *		vectors perm_r and perm_c, and the L & U data structures
+ *		set up from the previous factorization.
+ *          Otherwise, it is an output.
+ *
+ * stat     (output) SuperLUStat_t*
+ *	    Record the statistics on runtime and floating-point operation count.
+ *	    See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info     (output) int*
+ *	    = 0: successful exit
+ *	    < 0: if info = -i, the i-th argument had an illegal value
+ *	    > 0: if info = i, and i is
+ *	       <= A->ncol: number of zero pivots. They are replaced by small
+ *		  entries according to options->ILU_FillTol.
+ *	       > A->ncol: number of bytes allocated when memory allocation
+ *		  failure occurred, plus A->ncol. If lwork = -1, it is
+ *		  the estimated amount of space needed, plus A->ncol.
+ *
+ * ======================================================================
+ *
+ * Local Working Arrays:
+ * ======================
+ *   m = number of rows in the matrix
+ *   n = number of columns in the matrix
+ *
+ *   marker[0:3*m-1]: marker[i] = j means that node i has been
+ *	reached when working on column j.
+ *	Storage: relative to original row subscripts
+ *	NOTE: There are 4 of them:
+ *	      marker/marker1 are used for panel dfs, see (ilu_)dpanel_dfs.c;
+ *	      marker2 is used for inner-factorization, see (ilu)_dcolumn_dfs.c;
+ *	      marker_relax(has its own space) is used for relaxed supernodes.
+ *
+ *   parent[0:m-1]: parent vector used during dfs
+ *	Storage: relative to new row subscripts
+ *
+ *   xplore[0:m-1]: xplore[i] gives the location of the next (dfs)
+ *	unexplored neighbor of i in lsub[*]
+ *
+ *   segrep[0:nseg-1]: contains the list of supernodal representatives
+ *	in topological order of the dfs. A supernode representative is the
+ *	last column of a supernode.
+ *	The maximum size of segrep[] is n.
+ *
+ *   repfnz[0:W*m-1]: for a nonzero segment U[*,j] that ends at a
+ *	supernodal representative r, repfnz[r] is the location of the first
+ *	nonzero in this segment.  It is also used during the dfs: repfnz[r]>0
+ *	indicates the supernode r has been explored.
+ *	NOTE: There are W of them, each used for one column of a panel.
+ *
+ *   panel_lsub[0:W*m-1]: temporary for the nonzeros row indices below
+ *	the panel diagonal. These are filled in during dpanel_dfs(), and are
+ *	used later in the inner LU factorization within the panel.
+ *	panel_lsub[]/dense[] pair forms the SPA data structure.
+ *	NOTE: There are W of them.
+ *
+ *   dense[0:W*m-1]: sparse accumulating (SPA) vector for intermediate values;
+ *		   NOTE: there are W of them.
+ *
+ *   tempv[0:*]: real temporary used for dense numeric kernels;
+ *	The size of this array is defined by NUM_TEMPV() in slu_util.h.
+ *	It is also used by the dropping routine ilu_ddrop_row().
+ * 
+ */ + +void +dgsitrf(superlu_options_t *options, SuperMatrix *A, int relax, int panel_size, + int *etree, void *work, int lwork, int *perm_c, int *perm_r, + SuperMatrix *L, SuperMatrix *U, + GlobalLU_t *Glu, /* persistent to facilitate multiple factorizations */ + SuperLUStat_t *stat, int *info) +{ + /* Local working arrays */ + NCPformat *Astore; + int *iperm_r = NULL; /* inverse of perm_r; used when + options->Fact == SamePattern_SameRowPerm */ + int *iperm_c; /* inverse of perm_c */ + int *swap, *iswap; /* swap is used to store the row permutation + during the factorization. Initially, it is set + to iperm_c (row indeces of Pc*A*Pc'). + iswap is the inverse of swap. After the + factorization, it is equal to perm_r. */ + int *iwork; + double *dwork; + int *segrep, *repfnz, *parent, *xplore; + int *panel_lsub; /* dense[]/panel_lsub[] pair forms a w-wide SPA */ + int *marker, *marker_relax; + double *dense, *tempv; + int *relax_end, *relax_fsupc; + double *a; + int *asub; + int *xa_begin, *xa_end; + int *xsup, *supno; + int *xlsub, *xlusup, *xusub; + int nzlumax; + double *amax; + double drop_sum; + double alpha, omega; /* used in MILU, mimicing DRIC */ + double *dwork2; /* used by the second dropping rule */ + + /* Local scalars */ + fact_t fact = options->Fact; + double diag_pivot_thresh = options->DiagPivotThresh; + double drop_tol = options->ILU_DropTol; /* tau */ + double fill_ini = options->ILU_FillTol; /* tau^hat */ + double gamma = options->ILU_FillFactor; + int drop_rule = options->ILU_DropRule; + milu_t milu = options->ILU_MILU; + double fill_tol; + int pivrow; /* pivotal row number in the original matrix A */ + int nseg1; /* no of segments in U-column above panel row jcol */ + int nseg; /* no of segments in each U-column */ + register int jcol; + register int kcol; /* end column of a relaxed snode */ + register int icol; + register int i, k, jj, new_next, iinfo; + int m, n, min_mn, jsupno, fsupc, nextlu, nextu; + int w_def; /* upper bound on panel width */ + int usepr, iperm_r_allocated = 0; + int nnzL, nnzU; + int *panel_histo = stat->panel_histo; + flops_t *ops = stat->ops; + + int last_drop;/* the last column which the dropping rules applied */ + int quota; + int nnzAj; /* number of nonzeros in A(:,1:j) */ + int nnzLj, nnzUj; + double tol_L = drop_tol, tol_U = drop_tol; + double zero = 0.0; + double one = 1.0; + + /* Executable */ + iinfo = 0; + m = A->nrow; + n = A->ncol; + min_mn = SUPERLU_MIN(m, n); + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + + /* Allocate storage common to the factor routines */ + *info = dLUMemInit(fact, work, lwork, m, n, Astore->nnz, panel_size, + gamma, L, U, Glu, &iwork, &dwork); + if ( *info ) return; + + xsup = Glu->xsup; + supno = Glu->supno; + xlsub = Glu->xlsub; + xlusup = Glu->xlusup; + xusub = Glu->xusub; + + SetIWork(m, n, panel_size, iwork, &segrep, &parent, &xplore, + &repfnz, &panel_lsub, &marker_relax, &marker); + dSetRWork(m, panel_size, dwork, &dense, &tempv); + + usepr = (fact == SamePattern_SameRowPerm); + if ( usepr ) { + /* Compute the inverse of perm_r */ + iperm_r = (int *) intMalloc(m); + for (k = 0; k < m; ++k) iperm_r[perm_r[k]] = k; + iperm_r_allocated = 1; + } + + iperm_c = (int *) intMalloc(n); + for (k = 0; k < n; ++k) iperm_c[perm_c[k]] = k; + swap = (int *)intMalloc(n); + for (k = 0; k < n; k++) swap[k] = iperm_c[k]; + iswap = (int *)intMalloc(n); + for (k = 0; k < n; k++) iswap[k] = perm_c[k]; + amax = (double *) doubleMalloc(panel_size); + if (drop_rule & DROP_SECONDARY) + dwork2 = (double *)doubleMalloc(n); + else + dwork2 = NULL; + + nnzAj = 0; + nnzLj = 0; + nnzUj = 0; + last_drop = SUPERLU_MAX(min_mn - 2 * sp_ienv(7), (int)(min_mn * 0.95)); + alpha = pow((double)n, -1.0 / options->ILU_MILU_Dim); + + /* Identify relaxed snodes */ + relax_end = (int *) intMalloc(n); + relax_fsupc = (int *) intMalloc(n); + if ( options->SymmetricMode == YES ) + ilu_heap_relax_snode(n, etree, relax, marker, relax_end, relax_fsupc); + else + ilu_relax_snode(n, etree, relax, marker, relax_end, relax_fsupc); + + ifill (perm_r, m, EMPTY); + ifill (marker, m * NO_MARKER, EMPTY); + supno[0] = -1; + xsup[0] = xlsub[0] = xusub[0] = xlusup[0] = 0; + w_def = panel_size; + + /* Mark the rows used by relaxed supernodes */ + ifill (marker_relax, m, EMPTY); + i = mark_relax(m, relax_end, relax_fsupc, xa_begin, xa_end, + asub, marker_relax); +#if ( PRNTlevel >= 1) + printf("%d relaxed supernodes.\n", i); +#endif + + /* + * Work on one "panel" at a time. A panel is one of the following: + * (a) a relaxed supernode at the bottom of the etree, or + * (b) panel_size contiguous columns, defined by the user + */ + for (jcol = 0; jcol < min_mn; ) { + + if ( relax_end[jcol] != EMPTY ) { /* start of a relaxed snode */ + kcol = relax_end[jcol]; /* end of the relaxed snode */ + panel_histo[kcol-jcol+1]++; + + /* Drop small rows in the previous supernode. */ + if (jcol > 0 && jcol < last_drop) { + int first = xsup[supno[jcol - 1]]; + int last = jcol - 1; + int quota; + + /* Compute the quota */ + if (drop_rule & DROP_PROWS) + quota = gamma * Astore->nnz / m * (m - first) / m + * (last - first + 1); + else if (drop_rule & DROP_COLUMN) { + int i; + quota = 0; + for (i = first; i <= last; i++) + quota += xa_end[i] - xa_begin[i]; + quota = gamma * quota * (m - first) / m; + } else if (drop_rule & DROP_AREA) + quota = gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) / m) + - nnzLj; + else + quota = m * n; + fill_tol = pow(fill_ini, 1.0 - 0.5 * (first + last) / min_mn); + + /* Drop small rows */ + i = ilu_ddrop_row(options, first, last, tol_L, quota, &nnzLj, + &fill_tol, Glu, tempv, dwork2, 0); + /* Reset the parameters */ + if (drop_rule & DROP_DYNAMIC) { + if (gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) / m) + < nnzLj) + tol_L = SUPERLU_MIN(1.0, tol_L * 2.0); + else + tol_L = SUPERLU_MAX(drop_tol, tol_L * 0.5); + } + if (fill_tol < 0) iinfo -= (int)fill_tol; +#ifdef DEBUG + num_drop_L += i * (last - first + 1); +#endif + } + + /* -------------------------------------- + * Factorize the relaxed supernode(jcol:kcol) + * -------------------------------------- */ + /* Determine the union of the row structure of the snode */ + if ( (*info = ilu_dsnode_dfs(jcol, kcol, asub, xa_begin, xa_end, + marker, Glu)) != 0 ) + return; + + nextu = xusub[jcol]; + nextlu = xlusup[jcol]; + jsupno = supno[jcol]; + fsupc = xsup[jsupno]; + new_next = nextlu + (xlsub[fsupc+1]-xlsub[fsupc])*(kcol-jcol+1); + nzlumax = Glu->nzlumax; + while ( new_next > nzlumax ) { + if ((*info = dLUMemXpand(jcol, nextlu, LUSUP, &nzlumax, Glu))) + return; + } + + for (icol = jcol; icol <= kcol; icol++) { + xusub[icol+1] = nextu; + + amax[0] = 0.0; + /* Scatter into SPA dense[*] */ + for (k = xa_begin[icol]; k < xa_end[icol]; k++) { + register double tmp = fabs(a[k]); + if (tmp > amax[0]) amax[0] = tmp; + dense[asub[k]] = a[k]; + } + nnzAj += xa_end[icol] - xa_begin[icol]; + if (amax[0] == 0.0) { + amax[0] = fill_ini; +#if ( PRNTlevel >= 1) + printf("Column %d is entirely zero!\n", icol); + fflush(stdout); +#endif + } + + /* Numeric update within the snode */ + dsnode_bmod(icol, jsupno, fsupc, dense, tempv, Glu, stat); + + if (usepr) pivrow = iperm_r[icol]; + fill_tol = pow(fill_ini, 1.0 - (double)icol / (double)min_mn); + if ( (*info = ilu_dpivotL(icol, diag_pivot_thresh, &usepr, + perm_r, iperm_c[icol], swap, iswap, + marker_relax, &pivrow, + amax[0] * fill_tol, milu, zero, + Glu, stat)) ) { + iinfo++; + marker[pivrow] = kcol; + } + + } + + jcol = kcol + 1; + + } else { /* Work on one panel of panel_size columns */ + + /* Adjust panel_size so that a panel won't overlap with the next + * relaxed snode. + */ + panel_size = w_def; + for (k = jcol + 1; k < SUPERLU_MIN(jcol+panel_size, min_mn); k++) + if ( relax_end[k] != EMPTY ) { + panel_size = k - jcol; + break; + } + if ( k == min_mn ) panel_size = min_mn - jcol; + panel_histo[panel_size]++; + + /* symbolic factor on a panel of columns */ + ilu_dpanel_dfs(m, panel_size, jcol, A, perm_r, &nseg1, + dense, amax, panel_lsub, segrep, repfnz, + marker, parent, xplore, Glu); + + /* numeric sup-panel updates in topological order */ + dpanel_bmod(m, panel_size, jcol, nseg1, dense, + tempv, segrep, repfnz, Glu, stat); + + /* Sparse LU within the panel, and below panel diagonal */ + for (jj = jcol; jj < jcol + panel_size; jj++) { + + k = (jj - jcol) * m; /* column index for w-wide arrays */ + + nseg = nseg1; /* Begin after all the panel segments */ + + nnzAj += xa_end[jj] - xa_begin[jj]; + + if ((*info = ilu_dcolumn_dfs(m, jj, perm_r, &nseg, + &panel_lsub[k], segrep, &repfnz[k], + marker, parent, xplore, Glu))) + return; + + /* Numeric updates */ + if ((*info = dcolumn_bmod(jj, (nseg - nseg1), &dense[k], + tempv, &segrep[nseg1], &repfnz[k], + jcol, Glu, stat)) != 0) return; + + /* Make a fill-in position if the column is entirely zero */ + if (xlsub[jj + 1] == xlsub[jj]) { + register int i, row; + int nextl; + int nzlmax = Glu->nzlmax; + int *lsub = Glu->lsub; + int *marker2 = marker + 2 * m; + + /* Allocate memory */ + nextl = xlsub[jj] + 1; + if (nextl >= nzlmax) { + int error = dLUMemXpand(jj, nextl, LSUB, &nzlmax, Glu); + if (error) { *info = error; return; } + lsub = Glu->lsub; + } + xlsub[jj + 1]++; + assert(xlusup[jj]==xlusup[jj+1]); + xlusup[jj + 1]++; + ((double *) Glu->lusup)[xlusup[jj]] = zero; + + /* Choose a row index (pivrow) for fill-in */ + for (i = jj; i < n; i++) + if (marker_relax[swap[i]] <= jj) break; + row = swap[i]; + marker2[row] = jj; + lsub[xlsub[jj]] = row; +#ifdef DEBUG + printf("Fill col %d.\n", jj); + fflush(stdout); +#endif + } + + /* Computer the quota */ + if (drop_rule & DROP_PROWS) + quota = gamma * Astore->nnz / m * jj / m; + else if (drop_rule & DROP_COLUMN) + quota = gamma * (xa_end[jj] - xa_begin[jj]) * + (jj + 1) / m; + else if (drop_rule & DROP_AREA) + quota = gamma * 0.9 * nnzAj * 0.5 - nnzUj; + else + quota = m; + + /* Copy the U-segments to ucol[*] and drop small entries */ + if ((*info = ilu_dcopy_to_ucol(jj, nseg, segrep, &repfnz[k], + perm_r, &dense[k], drop_rule, + milu, amax[jj - jcol] * tol_U, + quota, &drop_sum, &nnzUj, Glu, + dwork2)) != 0) + return; + + /* Reset the dropping threshold if required */ + if (drop_rule & DROP_DYNAMIC) { + if (gamma * 0.9 * nnzAj * 0.5 < nnzLj) + tol_U = SUPERLU_MIN(1.0, tol_U * 2.0); + else + tol_U = SUPERLU_MAX(drop_tol, tol_U * 0.5); + } + + if (drop_sum != zero) + { + if (drop_sum > zero) + omega = SUPERLU_MIN(2.0 * (1.0 - alpha) + * amax[jj - jcol] / drop_sum, one); + else + omega = SUPERLU_MAX(2.0 * (1.0 - alpha) + * amax[jj - jcol] / drop_sum, -one); + drop_sum *= omega; + } + if (usepr) pivrow = iperm_r[jj]; + fill_tol = pow(fill_ini, 1.0 - (double)jj / (double)min_mn); + if ( (*info = ilu_dpivotL(jj, diag_pivot_thresh, &usepr, perm_r, + iperm_c[jj], swap, iswap, + marker_relax, &pivrow, + amax[jj - jcol] * fill_tol, milu, + drop_sum, Glu, stat)) ) { + iinfo++; + marker[m + pivrow] = jj; + marker[2 * m + pivrow] = jj; + } + + /* Reset repfnz[] for this column */ + resetrep_col (nseg, segrep, &repfnz[k]); + + /* Start a new supernode, drop the previous one */ + if (jj > 0 && supno[jj] > supno[jj - 1] && jj < last_drop) { + int first = xsup[supno[jj - 1]]; + int last = jj - 1; + int quota; + + /* Compute the quota */ + if (drop_rule & DROP_PROWS) + quota = gamma * Astore->nnz / m * (m - first) / m + * (last - first + 1); + else if (drop_rule & DROP_COLUMN) { + int i; + quota = 0; + for (i = first; i <= last; i++) + quota += xa_end[i] - xa_begin[i]; + quota = gamma * quota * (m - first) / m; + } else if (drop_rule & DROP_AREA) + quota = gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) + / m) - nnzLj; + else + quota = m * n; + fill_tol = pow(fill_ini, 1.0 - 0.5 * (first + last) / + (double)min_mn); + + /* Drop small rows */ + i = ilu_ddrop_row(options, first, last, tol_L, quota, + &nnzLj, &fill_tol, Glu, tempv, dwork2, + 1); + + /* Reset the parameters */ + if (drop_rule & DROP_DYNAMIC) { + if (gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) / m) + < nnzLj) + tol_L = SUPERLU_MIN(1.0, tol_L * 2.0); + else + tol_L = SUPERLU_MAX(drop_tol, tol_L * 0.5); + } + if (fill_tol < 0) iinfo -= (int)fill_tol; +#ifdef DEBUG + num_drop_L += i * (last - first + 1); +#endif + } /* if start a new supernode */ + + } /* for */ + + jcol += panel_size; /* Move to the next panel */ + + } /* else */ + + } /* for */ + + *info = iinfo; + + if ( m > n ) { + k = 0; + for (i = 0; i < m; ++i) + if ( perm_r[i] == EMPTY ) { + perm_r[i] = n + k; + ++k; + } + } + + ilu_countnz(min_mn, &nnzL, &nnzU, Glu); + fixupL(min_mn, perm_r, Glu); + + dLUWorkFree(iwork, dwork, Glu); /* Free work space and compress storage */ + + if ( fact == SamePattern_SameRowPerm ) { + /* L and U structures may have changed due to possibly different + pivoting, even though the storage is available. + There could also be memory expansions, so the array locations + may have changed, */ + ((SCformat *)L->Store)->nnz = nnzL; + ((SCformat *)L->Store)->nsuper = Glu->supno[n]; + ((SCformat *)L->Store)->nzval = (double *) Glu->lusup; + ((SCformat *)L->Store)->nzval_colptr = Glu->xlusup; + ((SCformat *)L->Store)->rowind = Glu->lsub; + ((SCformat *)L->Store)->rowind_colptr = Glu->xlsub; + ((NCformat *)U->Store)->nnz = nnzU; + ((NCformat *)U->Store)->nzval = (double *) Glu->ucol; + ((NCformat *)U->Store)->rowind = Glu->usub; + ((NCformat *)U->Store)->colptr = Glu->xusub; + } else { + dCreate_SuperNode_Matrix(L, A->nrow, min_mn, nnzL, + (double *) Glu->lusup, Glu->xlusup, + Glu->lsub, Glu->xlsub, Glu->supno, Glu->xsup, + SLU_SC, SLU_D, SLU_TRLU); + dCreate_CompCol_Matrix(U, min_mn, min_mn, nnzU, + (double *) Glu->ucol, Glu->usub, Glu->xusub, + SLU_NC, SLU_D, SLU_TRU); + } + + ops[FACT] += ops[TRSV] + ops[GEMV]; + stat->expansions = --(Glu->num_expansions); + + if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r); + SUPERLU_FREE (iperm_c); + SUPERLU_FREE (relax_end); + SUPERLU_FREE (swap); + SUPERLU_FREE (iswap); + SUPERLU_FREE (relax_fsupc); + SUPERLU_FREE (amax); + if ( dwork2 ) SUPERLU_FREE (dwork2); + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dgsrfs.c b/src/Libraries/superlu-5.2.1/SRC/dgsrfs.c new file mode 100644 index 00000000..d3722603 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dgsrfs.c @@ -0,0 +1,468 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dgsrfs.c + * \brief Improves computed solution to a system of inear equations + * + *
+ * -- SuperLU routine (version 5.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Modified from lapack routine DGERFS
+ * Last modified: December 3, 2015
+ * 
+ */ +/* + * File name: dgsrfs.c + * History: Modified from lapack routine DGERFS + */ +#include +#include "slu_ddefs.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   DGSRFS improves the computed solution to a system of linear   
+ *   equations and provides error bounds and backward error estimates for 
+ *   the solution.   
+ *
+ *   If equilibration was performed, the system becomes:
+ *           (diag(R)*A_original*diag(C)) * X = diag(R)*B_original.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ *   Arguments   
+ *   =========   
+ *
+ * trans   (input) trans_t
+ *          Specifies the form of the system of equations:
+ *          = NOTRANS: A * X = B  (No transpose)
+ *          = TRANS:   A'* X = B  (Transpose)
+ *          = CONJ:    A**H * X = B  (Conjugate transpose)
+ *   
+ *   A       (input) SuperMatrix*
+ *           The original matrix A in the system, or the scaled A if
+ *           equilibration was done. The type of A can be:
+ *           Stype = SLU_NC, Dtype = SLU_D, Mtype = SLU_GE.
+ *    
+ *   L       (input) SuperMatrix*
+ *	     The factor L from the factorization Pr*A*Pc=L*U. Use
+ *           compressed row subscripts storage for supernodes, 
+ *           i.e., L has types: Stype = SLU_SC, Dtype = SLU_D, Mtype = SLU_TRLU.
+ * 
+ *   U       (input) SuperMatrix*
+ *           The factor U from the factorization Pr*A*Pc=L*U as computed by
+ *           dgstrf(). Use column-wise storage scheme, 
+ *           i.e., U has types: Stype = SLU_NC, Dtype = SLU_D, Mtype = SLU_TRU.
+ *
+ *   perm_c  (input) int*, dimension (A->ncol)
+ *	     Column permutation vector, which defines the 
+ *           permutation matrix Pc; perm_c[i] = j means column i of A is 
+ *           in position j in A*Pc.
+ *
+ *   perm_r  (input) int*, dimension (A->nrow)
+ *           Row permutation vector, which defines the permutation matrix Pr;
+ *           perm_r[i] = j means row i of A is in position j in Pr*A.
+ *
+ *   equed   (input) Specifies the form of equilibration that was done.
+ *           = 'N': No equilibration.
+ *           = 'R': Row equilibration, i.e., A was premultiplied by diag(R).
+ *           = 'C': Column equilibration, i.e., A was postmultiplied by
+ *                  diag(C).
+ *           = 'B': Both row and column equilibration, i.e., A was replaced 
+ *                  by diag(R)*A*diag(C).
+ *
+ *   R       (input) double*, dimension (A->nrow)
+ *           The row scale factors for A.
+ *           If equed = 'R' or 'B', A is premultiplied by diag(R).
+ *           If equed = 'N' or 'C', R is not accessed.
+ * 
+ *   C       (input) double*, dimension (A->ncol)
+ *           The column scale factors for A.
+ *           If equed = 'C' or 'B', A is postmultiplied by diag(C).
+ *           If equed = 'N' or 'R', C is not accessed.
+ *
+ *   B       (input) SuperMatrix*
+ *           B has types: Stype = SLU_DN, Dtype = SLU_D, Mtype = SLU_GE.
+ *           The right hand side matrix B.
+ *           if equed = 'R' or 'B', B is premultiplied by diag(R).
+ *
+ *   X       (input/output) SuperMatrix*
+ *           X has types: Stype = SLU_DN, Dtype = SLU_D, Mtype = SLU_GE.
+ *           On entry, the solution matrix X, as computed by dgstrs().
+ *           On exit, the improved solution matrix X.
+ *           if *equed = 'C' or 'B', X should be premultiplied by diag(C)
+ *               in order to obtain the solution to the original system.
+ *
+ *   FERR    (output) double*, dimension (B->ncol)   
+ *           The estimated forward error bound for each solution vector   
+ *           X(j) (the j-th column of the solution matrix X).   
+ *           If XTRUE is the true solution corresponding to X(j), FERR(j) 
+ *           is an estimated upper bound for the magnitude of the largest 
+ *           element in (X(j) - XTRUE) divided by the magnitude of the   
+ *           largest element in X(j).  The estimate is as reliable as   
+ *           the estimate for RCOND, and is almost always a slight   
+ *           overestimate of the true error.
+ *
+ *   BERR    (output) double*, dimension (B->ncol)   
+ *           The componentwise relative backward error of each solution   
+ *           vector X(j) (i.e., the smallest relative change in   
+ *           any element of A or B that makes X(j) an exact solution).
+ *
+ *   stat     (output) SuperLUStat_t*
+ *            Record the statistics on runtime and floating-point operation count.
+ *            See util.h for the definition of 'SuperLUStat_t'.
+ *
+ *   info    (output) int*   
+ *           = 0:  successful exit   
+ *            < 0:  if INFO = -i, the i-th argument had an illegal value   
+ *
+ *    Internal Parameters   
+ *    ===================   
+ *
+ *    ITMAX is the maximum number of steps of iterative refinement.   
+ *
+ * 
+ */ +void +dgsrfs(trans_t trans, SuperMatrix *A, SuperMatrix *L, SuperMatrix *U, + int *perm_c, int *perm_r, char *equed, double *R, double *C, + SuperMatrix *B, SuperMatrix *X, double *ferr, double *berr, + SuperLUStat_t *stat, int *info) +{ + + +#define ITMAX 5 + + /* Table of constant values */ + int ione = 1; + double ndone = -1.; + double done = 1.; + + /* Local variables */ + NCformat *Astore; + double *Aval; + SuperMatrix Bjcol; + DNformat *Bstore, *Xstore, *Bjcol_store; + double *Bmat, *Xmat, *Bptr, *Xptr; + int kase; + double safe1, safe2; + int i, j, k, irow, nz, count, notran, rowequ, colequ; + int ldb, ldx, nrhs; + double s, xk, lstres, eps, safmin; + char transc[1]; + trans_t transt; + double *work; + double *rwork; + int *iwork; + int isave[3]; + + extern int dlacon2_(int *, double *, double *, int *, double *, int *, int []); +#ifdef _CRAY + extern int SCOPY(int *, double *, int *, double *, int *); + extern int SSAXPY(int *, double *, double *, int *, double *, int *); +#else + extern int dcopy_(int *, double *, int *, double *, int *); + extern int daxpy_(int *, double *, double *, int *, double *, int *); +#endif + + Astore = A->Store; + Aval = Astore->nzval; + Bstore = B->Store; + Xstore = X->Store; + Bmat = Bstore->nzval; + Xmat = Xstore->nzval; + ldb = Bstore->lda; + ldx = Xstore->lda; + nrhs = B->ncol; + + /* Test the input parameters */ + *info = 0; + notran = (trans == NOTRANS); + if ( !notran && trans != TRANS && trans != CONJ ) *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + A->Stype != SLU_NC || A->Dtype != SLU_D || A->Mtype != SLU_GE ) + *info = -2; + else if ( L->nrow != L->ncol || L->nrow < 0 || + L->Stype != SLU_SC || L->Dtype != SLU_D || L->Mtype != SLU_TRLU ) + *info = -3; + else if ( U->nrow != U->ncol || U->nrow < 0 || + U->Stype != SLU_NC || U->Dtype != SLU_D || U->Mtype != SLU_TRU ) + *info = -4; + else if ( ldb < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_D || B->Mtype != SLU_GE ) + *info = -10; + else if ( ldx < SUPERLU_MAX(0, A->nrow) || + X->Stype != SLU_DN || X->Dtype != SLU_D || X->Mtype != SLU_GE ) + *info = -11; + if (*info != 0) { + i = -(*info); + input_error("dgsrfs", &i); + return; + } + + /* Quick return if possible */ + if ( A->nrow == 0 || nrhs == 0) { + for (j = 0; j < nrhs; ++j) { + ferr[j] = 0.; + berr[j] = 0.; + } + return; + } + + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + + /* Allocate working space */ + work = doubleMalloc(2*A->nrow); + rwork = (double *) SUPERLU_MALLOC( A->nrow * sizeof(double) ); + iwork = intMalloc(2*A->nrow); + if ( !work || !rwork || !iwork ) + ABORT("Malloc fails for work/rwork/iwork."); + + if ( notran ) { + *(unsigned char *)transc = 'N'; + transt = TRANS; + } else if ( trans == TRANS ) { + *(unsigned char *)transc = 'T'; + transt = NOTRANS; + } else if ( trans == CONJ ) { + *(unsigned char *)transc = 'C'; + transt = NOTRANS; + } + + /* NZ = maximum number of nonzero elements in each row of A, plus 1 */ + nz = A->ncol + 1; + eps = dmach("Epsilon"); + safmin = dmach("Safe minimum"); + + /* Set SAFE1 essentially to be the underflow threshold times the + number of additions in each row. */ + safe1 = nz * safmin; + safe2 = safe1 / eps; + + /* Compute the number of nonzeros in each row (or column) of A */ + for (i = 0; i < A->nrow; ++i) iwork[i] = 0; + if ( notran ) { + for (k = 0; k < A->ncol; ++k) + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) + ++iwork[Astore->rowind[i]]; + } else { + for (k = 0; k < A->ncol; ++k) + iwork[k] = Astore->colptr[k+1] - Astore->colptr[k]; + } + + /* Copy one column of RHS B into Bjcol. */ + Bjcol.Stype = B->Stype; + Bjcol.Dtype = B->Dtype; + Bjcol.Mtype = B->Mtype; + Bjcol.nrow = B->nrow; + Bjcol.ncol = 1; + Bjcol.Store = (void *) SUPERLU_MALLOC( sizeof(DNformat) ); + if ( !Bjcol.Store ) ABORT("SUPERLU_MALLOC fails for Bjcol.Store"); + Bjcol_store = Bjcol.Store; + Bjcol_store->lda = ldb; + Bjcol_store->nzval = work; /* address aliasing */ + + /* Do for each right hand side ... */ + for (j = 0; j < nrhs; ++j) { + count = 0; + lstres = 3.; + Bptr = &Bmat[j*ldb]; + Xptr = &Xmat[j*ldx]; + + while (1) { /* Loop until stopping criterion is satisfied. */ + + /* Compute residual R = B - op(A) * X, + where op(A) = A, A**T, or A**H, depending on TRANS. */ + +#ifdef _CRAY + SCOPY(&A->nrow, Bptr, &ione, work, &ione); +#else + dcopy_(&A->nrow, Bptr, &ione, work, &ione); +#endif + sp_dgemv(transc, ndone, A, Xptr, ione, done, work, ione); + + /* Compute componentwise relative backward error from formula + max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) ) + where abs(Z) is the componentwise absolute value of the matrix + or vector Z. If the i-th component of the denominator is less + than SAFE2, then SAFE1 is added to the i-th component of the + numerator before dividing. */ + + for (i = 0; i < A->nrow; ++i) rwork[i] = fabs( Bptr[i] ); + + /* Compute abs(op(A))*abs(X) + abs(B). */ + if ( notran ) { + for (k = 0; k < A->ncol; ++k) { + xk = fabs( Xptr[k] ); + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) + rwork[Astore->rowind[i]] += fabs(Aval[i]) * xk; + } + } else { /* trans = TRANS or CONJ */ + for (k = 0; k < A->ncol; ++k) { + s = 0.; + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) { + irow = Astore->rowind[i]; + s += fabs(Aval[i]) * fabs(Xptr[irow]); + } + rwork[k] += s; + } + } + s = 0.; + for (i = 0; i < A->nrow; ++i) { + if (rwork[i] > safe2) { + s = SUPERLU_MAX( s, fabs(work[i]) / rwork[i] ); + } else if ( rwork[i] != 0.0 ) { + /* Adding SAFE1 to the numerator guards against + spuriously zero residuals (underflow). */ + s = SUPERLU_MAX( s, (safe1 + fabs(work[i])) / rwork[i] ); + } + /* If rwork[i] is exactly 0.0, then we know the true + residual also must be exactly 0.0. */ + } + berr[j] = s; + + /* Test stopping criterion. Continue iterating if + 1) The residual BERR(J) is larger than machine epsilon, and + 2) BERR(J) decreased by at least a factor of 2 during the + last iteration, and + 3) At most ITMAX iterations tried. */ + + if (berr[j] > eps && berr[j] * 2. <= lstres && count < ITMAX) { + /* Update solution and try again. */ + dgstrs (trans, L, U, perm_c, perm_r, &Bjcol, stat, info); + +#ifdef _CRAY + SAXPY(&A->nrow, &done, work, &ione, + &Xmat[j*ldx], &ione); +#else + daxpy_(&A->nrow, &done, work, &ione, + &Xmat[j*ldx], &ione); +#endif + lstres = berr[j]; + ++count; + } else { + break; + } + + } /* end while */ + + stat->RefineSteps = count; + + /* Bound error from formula: + norm(X - XTRUE) / norm(X) .le. FERR = norm( abs(inv(op(A)))* + ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X) + where + norm(Z) is the magnitude of the largest component of Z + inv(op(A)) is the inverse of op(A) + abs(Z) is the componentwise absolute value of the matrix or + vector Z + NZ is the maximum number of nonzeros in any row of A, plus 1 + EPS is machine epsilon + + The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B)) + is incremented by SAFE1 if the i-th component of + abs(op(A))*abs(X) + abs(B) is less than SAFE2. + + Use DLACON2 to estimate the infinity-norm of the matrix + inv(op(A)) * diag(W), + where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) */ + + for (i = 0; i < A->nrow; ++i) rwork[i] = fabs( Bptr[i] ); + + /* Compute abs(op(A))*abs(X) + abs(B). */ + if ( notran ) { + for (k = 0; k < A->ncol; ++k) { + xk = fabs( Xptr[k] ); + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) + rwork[Astore->rowind[i]] += fabs(Aval[i]) * xk; + } + } else { /* trans == TRANS or CONJ */ + for (k = 0; k < A->ncol; ++k) { + s = 0.; + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) { + irow = Astore->rowind[i]; + xk = fabs( Xptr[irow] ); + s += fabs(Aval[i]) * xk; + } + rwork[k] += s; + } + } + + for (i = 0; i < A->nrow; ++i) + if (rwork[i] > safe2) + rwork[i] = fabs(work[i]) + (iwork[i]+1)*eps*rwork[i]; + else + rwork[i] = fabs(work[i])+(iwork[i]+1)*eps*rwork[i]+safe1; + + kase = 0; + + do { + dlacon2_(&A->nrow, &work[A->nrow], work, + &iwork[A->nrow], &ferr[j], &kase, isave); + if (kase == 0) break; + + if (kase == 1) { + /* Multiply by diag(W)*inv(op(A)**T)*(diag(C) or diag(R)). */ + if ( notran && colequ ) + for (i = 0; i < A->ncol; ++i) work[i] *= C[i]; + else if ( !notran && rowequ ) + for (i = 0; i < A->nrow; ++i) work[i] *= R[i]; + + dgstrs (transt, L, U, perm_c, perm_r, &Bjcol, stat, info); + + for (i = 0; i < A->nrow; ++i) work[i] *= rwork[i]; + } else { + /* Multiply by (diag(C) or diag(R))*inv(op(A))*diag(W). */ + for (i = 0; i < A->nrow; ++i) work[i] *= rwork[i]; + + dgstrs (trans, L, U, perm_c, perm_r, &Bjcol, stat, info); + + if ( notran && colequ ) + for (i = 0; i < A->ncol; ++i) work[i] *= C[i]; + else if ( !notran && rowequ ) + for (i = 0; i < A->ncol; ++i) work[i] *= R[i]; + } + + } while ( kase != 0 ); + + + /* Normalize error. */ + lstres = 0.; + if ( notran && colequ ) { + for (i = 0; i < A->nrow; ++i) + lstres = SUPERLU_MAX( lstres, C[i] * fabs( Xptr[i]) ); + } else if ( !notran && rowequ ) { + for (i = 0; i < A->nrow; ++i) + lstres = SUPERLU_MAX( lstres, R[i] * fabs( Xptr[i]) ); + } else { + for (i = 0; i < A->nrow; ++i) + lstres = SUPERLU_MAX( lstres, fabs( Xptr[i]) ); + } + if ( lstres != 0. ) + ferr[j] /= lstres; + + } /* for each RHS j ... */ + + SUPERLU_FREE(work); + SUPERLU_FREE(rwork); + SUPERLU_FREE(iwork); + SUPERLU_FREE(Bjcol.Store); + + return; + +} /* dgsrfs */ diff --git a/src/Libraries/superlu-5.2.1/SRC/dgssv.c b/src/Libraries/superlu-5.2.1/SRC/dgssv.c new file mode 100644 index 00000000..a41d6f07 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dgssv.c @@ -0,0 +1,238 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dgssv.c + * \brief Solves the system of linear equations A*X=B + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ * 
+ */ +#include "slu_ddefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * DGSSV solves the system of linear equations A*X=B, using the
+ * LU factorization from DGSTRF. It performs the following steps:
+ *
+ *   1. If A is stored column-wise (A->Stype = SLU_NC):
+ *
+ *      1.1. Permute the columns of A, forming A*Pc, where Pc
+ *           is a permutation matrix. For more details of this step, 
+ *           see sp_preorder.c.
+ *
+ *      1.2. Factor A as Pr*A*Pc=L*U with the permutation Pr determined
+ *           by Gaussian elimination with partial pivoting.
+ *           L is unit lower triangular with offdiagonal entries
+ *           bounded by 1 in magnitude, and U is upper triangular.
+ *
+ *      1.3. Solve the system of equations A*X=B using the factored
+ *           form of A.
+ *
+ *   2. If A is stored row-wise (A->Stype = SLU_NR), apply the
+ *      above algorithm to the transpose of A:
+ *
+ *      2.1. Permute columns of transpose(A) (rows of A),
+ *           forming transpose(A)*Pc, where Pc is a permutation matrix. 
+ *           For more details of this step, see sp_preorder.c.
+ *
+ *      2.2. Factor A as Pr*transpose(A)*Pc=L*U with the permutation Pr
+ *           determined by Gaussian elimination with partial pivoting.
+ *           L is unit lower triangular with offdiagonal entries
+ *           bounded by 1 in magnitude, and U is upper triangular.
+ *
+ *      2.3. Solve the system of equations A*X=B using the factored
+ *           form of A.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ * 
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *         The structure defines the input parameters to control
+ *         how the LU decomposition will be performed and how the
+ *         system will be solved.
+ *
+ * A       (input) SuperMatrix*
+ *         Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
+ *         of linear equations is A->nrow. Currently, the type of A can be:
+ *         Stype = SLU_NC or SLU_NR; Dtype = SLU_D; Mtype = SLU_GE.
+ *         In the future, more general A may be handled.
+ *
+ * perm_c  (input/output) int*
+ *         If A->Stype = SLU_NC, column permutation vector of size A->ncol
+ *         which defines the permutation matrix Pc; perm_c[i] = j means 
+ *         column i of A is in position j in A*Pc.
+ *         If A->Stype = SLU_NR, column permutation vector of size A->nrow
+ *         which describes permutation of columns of transpose(A) 
+ *         (rows of A) as described above.
+ * 
+ *         If options->ColPerm = MY_PERMC or options->Fact = SamePattern or
+ *            options->Fact = SamePattern_SameRowPerm, it is an input argument.
+ *            On exit, perm_c may be overwritten by the product of the input
+ *            perm_c and a permutation that postorders the elimination tree
+ *            of Pc'*A'*A*Pc; perm_c is not changed if the elimination tree
+ *            is already in postorder.
+ *         Otherwise, it is an output argument.
+ * 
+ * perm_r  (input/output) int*
+ *         If A->Stype = SLU_NC, row permutation vector of size A->nrow, 
+ *         which defines the permutation matrix Pr, and is determined 
+ *         by partial pivoting.  perm_r[i] = j means row i of A is in 
+ *         position j in Pr*A.
+ *         If A->Stype = SLU_NR, permutation vector of size A->ncol, which
+ *         determines permutation of rows of transpose(A)
+ *         (columns of A) as described above.
+ *
+ *         If options->RowPerm = MY_PERMR or
+ *            options->Fact = SamePattern_SameRowPerm, perm_r is an
+ *            input argument.
+ *         otherwise it is an output argument.
+ *
+ * L       (output) SuperMatrix*
+ *         The factor L from the factorization 
+ *             Pr*A*Pc=L*U              (if A->Stype = SLU_NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses compressed row subscripts storage for supernodes, i.e.,
+ *         L has types: Stype = SLU_SC, Dtype = SLU_D, Mtype = SLU_TRLU.
+ *         
+ * U       (output) SuperMatrix*
+ *	   The factor U from the factorization 
+ *             Pr*A*Pc=L*U              (if A->Stype = SLU_NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses column-wise storage scheme, i.e., U has types:
+ *         Stype = SLU_NC, Dtype = SLU_D, Mtype = SLU_TRU.
+ *
+ * B       (input/output) SuperMatrix*
+ *         B has types: Stype = SLU_DN, Dtype = SLU_D, Mtype = SLU_GE.
+ *         On entry, the right hand side matrix.
+ *         On exit, the solution matrix if info = 0;
+ *
+ * stat   (output) SuperLUStat_t*
+ *        Record the statistics on runtime and floating-point operation count.
+ *        See util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ *	   = 0: successful exit
+ *         > 0: if info = i, and i is
+ *             <= A->ncol: U(i,i) is exactly zero. The factorization has
+ *                been completed, but the factor U is exactly singular,
+ *                so the solution could not be computed.
+ *             > A->ncol: number of bytes allocated when memory allocation
+ *                failure occurred, plus A->ncol.
+ * 
+ */ + +void +dgssv(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, + SuperMatrix *L, SuperMatrix *U, SuperMatrix *B, + SuperLUStat_t *stat, int *info ) +{ + + DNformat *Bstore; + SuperMatrix *AA;/* A in SLU_NC format used by the factorization routine.*/ + SuperMatrix AC; /* Matrix postmultiplied by Pc */ + int lwork = 0, *etree, i; + GlobalLU_t Glu; /* Not needed on return. */ + + /* Set default values for some parameters */ + int panel_size; /* panel size */ + int relax; /* no of columns in a relaxed snodes */ + int permc_spec; + trans_t trans = NOTRANS; + double *utime; + double t; /* Temporary time */ + + /* Test the input parameters ... */ + *info = 0; + Bstore = B->Store; + if ( options->Fact != DOFACT ) *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + (A->Stype != SLU_NC && A->Stype != SLU_NR) || + A->Dtype != SLU_D || A->Mtype != SLU_GE ) + *info = -2; + else if ( B->ncol < 0 || Bstore->lda < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_D || B->Mtype != SLU_GE ) + *info = -7; + if ( *info != 0 ) { + i = -(*info); + input_error("dgssv", &i); + return; + } + + utime = stat->utime; + + /* Convert A to SLU_NC format when necessary. */ + if ( A->Stype == SLU_NR ) { + NRformat *Astore = A->Store; + AA = (SuperMatrix *) SUPERLU_MALLOC( sizeof(SuperMatrix) ); + dCreate_CompCol_Matrix(AA, A->ncol, A->nrow, Astore->nnz, + Astore->nzval, Astore->colind, Astore->rowptr, + SLU_NC, A->Dtype, A->Mtype); + trans = TRANS; + } else { + if ( A->Stype == SLU_NC ) AA = A; + } + + t = SuperLU_timer_(); + /* + * Get column permutation vector perm_c[], according to permc_spec: + * permc_spec = NATURAL: natural ordering + * permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A + * permc_spec = MMD_ATA: minimum degree on structure of A'*A + * permc_spec = COLAMD: approximate minimum degree column ordering + * permc_spec = MY_PERMC: the ordering already supplied in perm_c[] + */ + permc_spec = options->ColPerm; + if ( permc_spec != MY_PERMC && options->Fact == DOFACT ) + get_perm_c(permc_spec, AA, perm_c); + utime[COLPERM] = SuperLU_timer_() - t; + + etree = intMalloc(A->ncol); + + t = SuperLU_timer_(); + sp_preorder(options, AA, perm_c, etree, &AC); + utime[ETREE] = SuperLU_timer_() - t; + + panel_size = sp_ienv(1); + relax = sp_ienv(2); + + /*printf("Factor PA = LU ... relax %d\tw %d\tmaxsuper %d\trowblk %d\n", + relax, panel_size, sp_ienv(3), sp_ienv(4));*/ + t = SuperLU_timer_(); + /* Compute the LU factorization of A. */ + dgstrf(options, &AC, relax, panel_size, etree, + NULL, lwork, perm_c, perm_r, L, U, &Glu, stat, info); + utime[FACT] = SuperLU_timer_() - t; + + t = SuperLU_timer_(); + if ( *info == 0 ) { + /* Solve the system A*X=B, overwriting B with X. */ + dgstrs (trans, L, U, perm_c, perm_r, B, stat, info); + } + utime[SOLVE] = SuperLU_timer_() - t; + + SUPERLU_FREE (etree); + Destroy_CompCol_Permuted(&AC); + if ( A->Stype == SLU_NR ) { + Destroy_SuperMatrix_Store(AA); + SUPERLU_FREE(AA); + } + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dgssvx.c b/src/Libraries/superlu-5.2.1/SRC/dgssvx.c new file mode 100644 index 00000000..e48d73e5 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dgssvx.c @@ -0,0 +1,646 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dgssvx.c + * \brief Solves the system of linear equations A*X=B or A'*X=B + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ * 
+ */ +#include "slu_ddefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * DGSSVX solves the system of linear equations A*X=B or A'*X=B, using
+ * the LU factorization from dgstrf(). Error bounds on the solution and
+ * a condition estimate are also provided. It performs the following steps:
+ *
+ *   1. If A is stored column-wise (A->Stype = SLU_NC):
+ *  
+ *      1.1. If options->Equil = YES, scaling factors are computed to
+ *           equilibrate the system:
+ *           options->Trans = NOTRANS:
+ *               diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *           options->Trans = TRANS:
+ *               (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *           options->Trans = CONJ:
+ *               (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *           Whether or not the system will be equilibrated depends on the
+ *           scaling of the matrix A, but if equilibration is used, A is
+ *           overwritten by diag(R)*A*diag(C) and B by diag(R)*B
+ *           (if options->Trans=NOTRANS) or diag(C)*B (if options->Trans
+ *           = TRANS or CONJ).
+ *
+ *      1.2. Permute columns of A, forming A*Pc, where Pc is a permutation
+ *           matrix that usually preserves sparsity.
+ *           For more details of this step, see sp_preorder.c.
+ *
+ *      1.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *           factor the matrix A (after equilibration if options->Equil = YES)
+ *           as Pr*A*Pc = L*U, with Pr determined by partial pivoting.
+ *
+ *      1.4. Compute the reciprocal pivot growth factor.
+ *
+ *      1.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *           routine returns with info = i. Otherwise, the factored form of 
+ *           A is used to estimate the condition number of the matrix A. If
+ *           the reciprocal of the condition number is less than machine
+ *           precision, info = A->ncol+1 is returned as a warning, but the
+ *           routine still goes on to solve for X and computes error bounds
+ *           as described below.
+ *
+ *      1.6. The system of equations is solved for X using the factored form
+ *           of A.
+ *
+ *      1.7. If options->IterRefine != NOREFINE, iterative refinement is
+ *           applied to improve the computed solution matrix and calculate
+ *           error bounds and backward error estimates for it.
+ *
+ *      1.8. If equilibration was used, the matrix X is premultiplied by
+ *           diag(C) (if options->Trans = NOTRANS) or diag(R)
+ *           (if options->Trans = TRANS or CONJ) so that it solves the
+ *           original system before equilibration.
+ *
+ *   2. If A is stored row-wise (A->Stype = SLU_NR), apply the above algorithm
+ *      to the transpose of A:
+ *
+ *      2.1. If options->Equil = YES, scaling factors are computed to
+ *           equilibrate the system:
+ *           options->Trans = NOTRANS:
+ *               diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *           options->Trans = TRANS:
+ *               (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *           options->Trans = CONJ:
+ *               (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *           Whether or not the system will be equilibrated depends on the
+ *           scaling of the matrix A, but if equilibration is used, A' is
+ *           overwritten by diag(R)*A'*diag(C) and B by diag(R)*B 
+ *           (if trans='N') or diag(C)*B (if trans = 'T' or 'C').
+ *
+ *      2.2. Permute columns of transpose(A) (rows of A), 
+ *           forming transpose(A)*Pc, where Pc is a permutation matrix that 
+ *           usually preserves sparsity.
+ *           For more details of this step, see sp_preorder.c.
+ *
+ *      2.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *           factor the transpose(A) (after equilibration if 
+ *           options->Fact = YES) as Pr*transpose(A)*Pc = L*U with the
+ *           permutation Pr determined by partial pivoting.
+ *
+ *      2.4. Compute the reciprocal pivot growth factor.
+ *
+ *      2.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *           routine returns with info = i. Otherwise, the factored form 
+ *           of transpose(A) is used to estimate the condition number of the
+ *           matrix A. If the reciprocal of the condition number
+ *           is less than machine precision, info = A->nrow+1 is returned as
+ *           a warning, but the routine still goes on to solve for X and
+ *           computes error bounds as described below.
+ *
+ *      2.6. The system of equations is solved for X using the factored form
+ *           of transpose(A).
+ *
+ *      2.7. If options->IterRefine != NOREFINE, iterative refinement is
+ *           applied to improve the computed solution matrix and calculate
+ *           error bounds and backward error estimates for it.
+ *
+ *      2.8. If equilibration was used, the matrix X is premultiplied by
+ *           diag(C) (if options->Trans = NOTRANS) or diag(R) 
+ *           (if options->Trans = TRANS or CONJ) so that it solves the
+ *           original system before equilibration.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *         The structure defines the input parameters to control
+ *         how the LU decomposition will be performed and how the
+ *         system will be solved.
+ *
+ * A       (input/output) SuperMatrix*
+ *         Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
+ *         of the linear equations is A->nrow. Currently, the type of A can be:
+ *         Stype = SLU_NC or SLU_NR, Dtype = SLU_D, Mtype = SLU_GE.
+ *         In the future, more general A may be handled.
+ *
+ *         On entry, If options->Fact = FACTORED and equed is not 'N', 
+ *         then A must have been equilibrated by the scaling factors in
+ *         R and/or C.  
+ *         On exit, A is not modified if options->Equil = NO, or if 
+ *         options->Equil = YES but equed = 'N' on exit.
+ *         Otherwise, if options->Equil = YES and equed is not 'N',
+ *         A is scaled as follows:
+ *         If A->Stype = SLU_NC:
+ *           equed = 'R':  A := diag(R) * A
+ *           equed = 'C':  A := A * diag(C)
+ *           equed = 'B':  A := diag(R) * A * diag(C).
+ *         If A->Stype = SLU_NR:
+ *           equed = 'R':  transpose(A) := diag(R) * transpose(A)
+ *           equed = 'C':  transpose(A) := transpose(A) * diag(C)
+ *           equed = 'B':  transpose(A) := diag(R) * transpose(A) * diag(C).
+ *
+ * perm_c  (input/output) int*
+ *	   If A->Stype = SLU_NC, Column permutation vector of size A->ncol,
+ *         which defines the permutation matrix Pc; perm_c[i] = j means
+ *         column i of A is in position j in A*Pc.
+ *         On exit, perm_c may be overwritten by the product of the input
+ *         perm_c and a permutation that postorders the elimination tree
+ *         of Pc'*A'*A*Pc; perm_c is not changed if the elimination tree
+ *         is already in postorder.
+ *
+ *         If A->Stype = SLU_NR, column permutation vector of size A->nrow,
+ *         which describes permutation of columns of transpose(A) 
+ *         (rows of A) as described above.
+ * 
+ * perm_r  (input/output) int*
+ *         If A->Stype = SLU_NC, row permutation vector of size A->nrow, 
+ *         which defines the permutation matrix Pr, and is determined
+ *         by partial pivoting.  perm_r[i] = j means row i of A is in 
+ *         position j in Pr*A.
+ *
+ *         If A->Stype = SLU_NR, permutation vector of size A->ncol, which
+ *         determines permutation of rows of transpose(A)
+ *         (columns of A) as described above.
+ *
+ *         If options->Fact = SamePattern_SameRowPerm, the pivoting routine
+ *         will try to use the input perm_r, unless a certain threshold
+ *         criterion is violated. In that case, perm_r is overwritten by a
+ *         new permutation determined by partial pivoting or diagonal
+ *         threshold pivoting.
+ *         Otherwise, perm_r is output argument.
+ * 
+ * etree   (input/output) int*,  dimension (A->ncol)
+ *         Elimination tree of Pc'*A'*A*Pc.
+ *         If options->Fact != FACTORED and options->Fact != DOFACT,
+ *         etree is an input argument, otherwise it is an output argument.
+ *         Note: etree is a vector of parent pointers for a forest whose
+ *         vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *
+ * equed   (input/output) char*
+ *         Specifies the form of equilibration that was done.
+ *         = 'N': No equilibration.
+ *         = 'R': Row equilibration, i.e., A was premultiplied by diag(R).
+ *         = 'C': Column equilibration, i.e., A was postmultiplied by diag(C).
+ *         = 'B': Both row and column equilibration, i.e., A was replaced 
+ *                by diag(R)*A*diag(C).
+ *         If options->Fact = FACTORED, equed is an input argument,
+ *         otherwise it is an output argument.
+ *
+ * R       (input/output) double*, dimension (A->nrow)
+ *         The row scale factors for A or transpose(A).
+ *         If equed = 'R' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *             (if A->Stype = SLU_NR) is multiplied on the left by diag(R).
+ *         If equed = 'N' or 'C', R is not accessed.
+ *         If options->Fact = FACTORED, R is an input argument,
+ *             otherwise, R is output.
+ *         If options->zFact = FACTORED and equed = 'R' or 'B', each element
+ *             of R must be positive.
+ * 
+ * C       (input/output) double*, dimension (A->ncol)
+ *         The column scale factors for A or transpose(A).
+ *         If equed = 'C' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *             (if A->Stype = SLU_NR) is multiplied on the right by diag(C).
+ *         If equed = 'N' or 'R', C is not accessed.
+ *         If options->Fact = FACTORED, C is an input argument,
+ *             otherwise, C is output.
+ *         If options->Fact = FACTORED and equed = 'C' or 'B', each element
+ *             of C must be positive.
+ *         
+ * L       (output) SuperMatrix*
+ *	   The factor L from the factorization
+ *             Pr*A*Pc=L*U              (if A->Stype SLU_= NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses compressed row subscripts storage for supernodes, i.e.,
+ *         L has types: Stype = SLU_SC, Dtype = SLU_D, Mtype = SLU_TRLU.
+ *
+ * U       (output) SuperMatrix*
+ *	   The factor U from the factorization
+ *             Pr*A*Pc=L*U              (if A->Stype = SLU_NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses column-wise storage scheme, i.e., U has types:
+ *         Stype = SLU_NC, Dtype = SLU_D, Mtype = SLU_TRU.
+ *
+ * work    (workspace/output) void*, size (lwork) (in bytes)
+ *         User supplied workspace, should be large enough
+ *         to hold data structures for factors L and U.
+ *         On exit, if fact is not 'F', L and U point to this array.
+ *
+ * lwork   (input) int
+ *         Specifies the size of work array in bytes.
+ *         = 0:  allocate space internally by system malloc;
+ *         > 0:  use user-supplied work array of length lwork in bytes,
+ *               returns error if space runs out.
+ *         = -1: the routine guesses the amount of space needed without
+ *               performing the factorization, and returns it in
+ *               mem_usage->total_needed; no other side effects.
+ *
+ *         See argument 'mem_usage' for memory usage statistics.
+ *
+ * B       (input/output) SuperMatrix*
+ *         B has types: Stype = SLU_DN, Dtype = SLU_D, Mtype = SLU_GE.
+ *         On entry, the right hand side matrix.
+ *         If B->ncol = 0, only LU decomposition is performed, the triangular
+ *                         solve is skipped.
+ *         On exit,
+ *            if equed = 'N', B is not modified; otherwise
+ *            if A->Stype = SLU_NC:
+ *               if options->Trans = NOTRANS and equed = 'R' or 'B',
+ *                  B is overwritten by diag(R)*B;
+ *               if options->Trans = TRANS or CONJ and equed = 'C' of 'B',
+ *                  B is overwritten by diag(C)*B;
+ *            if A->Stype = SLU_NR:
+ *               if options->Trans = NOTRANS and equed = 'C' or 'B',
+ *                  B is overwritten by diag(C)*B;
+ *               if options->Trans = TRANS or CONJ and equed = 'R' of 'B',
+ *                  B is overwritten by diag(R)*B.
+ *
+ * X       (output) SuperMatrix*
+ *         X has types: Stype = SLU_DN, Dtype = SLU_D, Mtype = SLU_GE. 
+ *         If info = 0 or info = A->ncol+1, X contains the solution matrix
+ *         to the original system of equations. Note that A and B are modified
+ *         on exit if equed is not 'N', and the solution to the equilibrated
+ *         system is inv(diag(C))*X if options->Trans = NOTRANS and
+ *         equed = 'C' or 'B', or inv(diag(R))*X if options->Trans = 'T' or 'C'
+ *         and equed = 'R' or 'B'.
+ *
+ * recip_pivot_growth (output) double*
+ *         The reciprocal pivot growth factor max_j( norm(A_j)/norm(U_j) ).
+ *         The infinity norm is used. If recip_pivot_growth is much less
+ *         than 1, the stability of the LU factorization could be poor.
+ *
+ * rcond   (output) double*
+ *         The estimate of the reciprocal condition number of the matrix A
+ *         after equilibration (if done). If rcond is less than the machine
+ *         precision (in particular, if rcond = 0), the matrix is singular
+ *         to working precision. This condition is indicated by a return
+ *         code of info > 0.
+ *
+ * FERR    (output) double*, dimension (B->ncol)   
+ *         The estimated forward error bound for each solution vector   
+ *         X(j) (the j-th column of the solution matrix X).   
+ *         If XTRUE is the true solution corresponding to X(j), FERR(j) 
+ *         is an estimated upper bound for the magnitude of the largest 
+ *         element in (X(j) - XTRUE) divided by the magnitude of the   
+ *         largest element in X(j).  The estimate is as reliable as   
+ *         the estimate for RCOND, and is almost always a slight   
+ *         overestimate of the true error.
+ *         If options->IterRefine = NOREFINE, ferr = 1.0.
+ *
+ * BERR    (output) double*, dimension (B->ncol)
+ *         The componentwise relative backward error of each solution   
+ *         vector X(j) (i.e., the smallest relative change in   
+ *         any element of A or B that makes X(j) an exact solution).
+ *         If options->IterRefine = NOREFINE, berr = 1.0.
+ *
+ * Glu      (input/output) GlobalLU_t *
+ *          If options->Fact == SamePattern_SameRowPerm, it is an input;
+ *              The matrix A will be factorized assuming that a 
+ *              factorization of a matrix with the same sparsity pattern
+ *              and similar numerical values was performed prior to this one.
+ *              Therefore, this factorization will reuse both row and column
+ *		scaling factors R and C, both row and column permutation
+ *		vectors perm_r and perm_c, and the L & U data structures
+ *		set up from the previous factorization.
+ *          Otherwise, it is an output.
+ *
+ * mem_usage (output) mem_usage_t*
+ *         Record the memory usage statistics, consisting of following fields:
+ *         - for_lu (float)
+ *           The amount of space used in bytes for L\U data structures.
+ *         - total_needed (float)
+ *           The amount of space needed in bytes to perform factorization.
+ *         - expansions (int)
+ *           The number of memory expansions during the LU factorization.
+ *
+ * stat   (output) SuperLUStat_t*
+ *        Record the statistics on runtime and floating-point operation count.
+ *        See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ *         = 0: successful exit   
+ *         < 0: if info = -i, the i-th argument had an illegal value   
+ *         > 0: if info = i, and i is   
+ *              <= A->ncol: U(i,i) is exactly zero. The factorization has   
+ *                    been completed, but the factor U is exactly   
+ *                    singular, so the solution and error bounds   
+ *                    could not be computed.   
+ *              = A->ncol+1: U is nonsingular, but RCOND is less than machine
+ *                    precision, meaning that the matrix is singular to
+ *                    working precision. Nevertheless, the solution and
+ *                    error bounds are computed because there are a number
+ *                    of situations where the computed solution can be more
+ *                    accurate than the value of RCOND would suggest.   
+ *              > A->ncol+1: number of bytes allocated when memory allocation
+ *                    failure occurred, plus A->ncol.
+ * 
+ */ + +void +dgssvx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, + int *etree, char *equed, double *R, double *C, + SuperMatrix *L, SuperMatrix *U, void *work, int lwork, + SuperMatrix *B, SuperMatrix *X, double *recip_pivot_growth, + double *rcond, double *ferr, double *berr, + GlobalLU_t *Glu, mem_usage_t *mem_usage, SuperLUStat_t *stat, int *info ) +{ + + + DNformat *Bstore, *Xstore; + double *Bmat, *Xmat; + int ldb, ldx, nrhs; + SuperMatrix *AA;/* A in SLU_NC format used by the factorization routine.*/ + SuperMatrix AC; /* Matrix postmultiplied by Pc */ + int colequ, equil, nofact, notran, rowequ, permc_spec; + trans_t trant; + char norm[1]; + int i, j, info1; + double amax, anorm, bignum, smlnum, colcnd, rowcnd, rcmax, rcmin; + int relax, panel_size; + double diag_pivot_thresh; + double t0; /* temporary time */ + double *utime; + + /* External functions */ + extern double dlangs(char *, SuperMatrix *); + + Bstore = B->Store; + Xstore = X->Store; + Bmat = Bstore->nzval; + Xmat = Xstore->nzval; + ldb = Bstore->lda; + ldx = Xstore->lda; + nrhs = B->ncol; + + *info = 0; + nofact = (options->Fact != FACTORED); + equil = (options->Equil == YES); + notran = (options->Trans == NOTRANS); + if ( nofact ) { + *(unsigned char *)equed = 'N'; + rowequ = FALSE; + colequ = FALSE; + } else { + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + smlnum = dmach("Safe minimum"); /* lamch_("Safe minimum"); */ + bignum = 1. / smlnum; + } + +#if 0 +printf("dgssvx: Fact=%4d, Trans=%4d, equed=%c\n", + options->Fact, options->Trans, *equed); +#endif + + /* Test the input parameters */ + if (options->Fact != DOFACT && options->Fact != SamePattern && + options->Fact != SamePattern_SameRowPerm && + options->Fact != FACTORED && + options->Trans != NOTRANS && options->Trans != TRANS && + options->Trans != CONJ && + options->Equil != NO && options->Equil != YES) + *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + (A->Stype != SLU_NC && A->Stype != SLU_NR) || + A->Dtype != SLU_D || A->Mtype != SLU_GE ) + *info = -2; + else if ( options->Fact == FACTORED && + !(rowequ || colequ || strncmp(equed, "N", 1)==0) ) + *info = -6; + else { + if (rowequ) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, R[j]); + rcmax = SUPERLU_MAX(rcmax, R[j]); + } + if (rcmin <= 0.) *info = -7; + else if ( A->nrow > 0) + rowcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else rowcnd = 1.; + } + if (colequ && *info == 0) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, C[j]); + rcmax = SUPERLU_MAX(rcmax, C[j]); + } + if (rcmin <= 0.) *info = -8; + else if (A->nrow > 0) + colcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else colcnd = 1.; + } + if (*info == 0) { + if ( lwork < -1 ) *info = -12; + else if ( B->ncol < 0 ) *info = -13; + else if ( B->ncol > 0 ) { /* no checking if B->ncol=0 */ + if ( Bstore->lda < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_D || + B->Mtype != SLU_GE ) + *info = -13; + } + if ( X->ncol < 0 ) *info = -14; + else if ( X->ncol > 0 ) { /* no checking if X->ncol=0 */ + if ( Xstore->lda < SUPERLU_MAX(0, A->nrow) || + (B->ncol != 0 && B->ncol != X->ncol) || + X->Stype != SLU_DN || + X->Dtype != SLU_D || X->Mtype != SLU_GE ) + *info = -14; + } + } + } + if (*info != 0) { + i = -(*info); + input_error("dgssvx", &i); + return; + } + + /* Initialization for factor parameters */ + panel_size = sp_ienv(1); + relax = sp_ienv(2); + diag_pivot_thresh = options->DiagPivotThresh; + + utime = stat->utime; + + /* Convert A to SLU_NC format when necessary. */ + if ( A->Stype == SLU_NR ) { + NRformat *Astore = A->Store; + AA = (SuperMatrix *) SUPERLU_MALLOC( sizeof(SuperMatrix) ); + dCreate_CompCol_Matrix(AA, A->ncol, A->nrow, Astore->nnz, + Astore->nzval, Astore->colind, Astore->rowptr, + SLU_NC, A->Dtype, A->Mtype); + if ( notran ) { /* Reverse the transpose argument. */ + trant = TRANS; + notran = 0; + } else { + trant = NOTRANS; + notran = 1; + } + } else { /* A->Stype == SLU_NC */ + trant = options->Trans; + AA = A; + } + + if ( nofact && equil ) { + t0 = SuperLU_timer_(); + /* Compute row and column scalings to equilibrate the matrix A. */ + dgsequ(AA, R, C, &rowcnd, &colcnd, &amax, &info1); + + if ( info1 == 0 ) { + /* Equilibrate matrix A. */ + dlaqgs(AA, R, C, rowcnd, colcnd, amax, equed); + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + } + utime[EQUIL] = SuperLU_timer_() - t0; + } + + + if ( nofact ) { + + t0 = SuperLU_timer_(); + /* + * Gnet column permutation vector perm_c[], according to permc_spec: + * permc_spec = NATURAL: natural ordering + * permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A + * permc_spec = MMD_ATA: minimum degree on structure of A'*A + * permc_spec = COLAMD: approximate minimum degree column ordering + * permc_spec = MY_PERMC: the ordering already supplied in perm_c[] + */ + permc_spec = options->ColPerm; + if ( permc_spec != MY_PERMC && options->Fact == DOFACT ) + get_perm_c(permc_spec, AA, perm_c); + utime[COLPERM] = SuperLU_timer_() - t0; + + t0 = SuperLU_timer_(); + sp_preorder(options, AA, perm_c, etree, &AC); + utime[ETREE] = SuperLU_timer_() - t0; + +/* printf("Factor PA = LU ... relax %d\tw %d\tmaxsuper %d\trowblk %d\n", + relax, panel_size, sp_ienv(3), sp_ienv(4)); + fflush(stdout); */ + + /* Compute the LU factorization of A*Pc. */ + t0 = SuperLU_timer_(); + dgstrf(options, &AC, relax, panel_size, etree, + work, lwork, perm_c, perm_r, L, U, Glu, stat, info); + utime[FACT] = SuperLU_timer_() - t0; + + if ( lwork == -1 ) { + mem_usage->total_needed = *info - A->ncol; + return; + } + } + + if ( *info > 0 ) { + if ( *info <= A->ncol ) { + /* Compute the reciprocal pivot growth factor of the leading + rank-deficient (*info) columns of A. */ + *recip_pivot_growth = dPivotGrowth(*info, AA, perm_c, L, U); + } + return; + } + + /* *info == 0 at this point. */ + + if ( options->PivotGrowth ) { + /* Compute the reciprocal pivot growth factor *recip_pivot_growth. */ + *recip_pivot_growth = dPivotGrowth(A->ncol, AA, perm_c, L, U); + } + + if ( options->ConditionNumber ) { + /* Estimate the reciprocal of the condition number of A. */ + t0 = SuperLU_timer_(); + if ( notran ) { + *(unsigned char *)norm = '1'; + } else { + *(unsigned char *)norm = 'I'; + } + anorm = dlangs(norm, AA); + dgscon(norm, L, U, anorm, rcond, stat, &info1); + utime[RCOND] = SuperLU_timer_() - t0; + } + + if ( nrhs > 0 ) { + /* Scale the right hand side if equilibration was performed. */ + if ( notran ) { + if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + Bmat[i + j*ldb] *= R[i]; + } + } else if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + Bmat[i + j*ldb] *= C[i]; + } + + /* Compute the solution matrix X. */ + for (j = 0; j < nrhs; j++) /* Save a copy of the right hand sides */ + for (i = 0; i < B->nrow; i++) + Xmat[i + j*ldx] = Bmat[i + j*ldb]; + + t0 = SuperLU_timer_(); + dgstrs (trant, L, U, perm_c, perm_r, X, stat, &info1); + utime[SOLVE] = SuperLU_timer_() - t0; + + /* Use iterative refinement to improve the computed solution and compute + error bounds and backward error estimates for it. */ + t0 = SuperLU_timer_(); + if ( options->IterRefine != NOREFINE ) { + dgsrfs(trant, AA, L, U, perm_c, perm_r, equed, R, C, B, + X, ferr, berr, stat, &info1); + } else { + for (j = 0; j < nrhs; ++j) ferr[j] = berr[j] = 1.0; + } + utime[REFINE] = SuperLU_timer_() - t0; + + /* Transform the solution matrix X to a solution of the original system. */ + if ( notran ) { + if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + Xmat[i + j*ldx] *= C[i]; + } + } else if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + Xmat[i + j*ldx] *= R[i]; + } + } /* end if nrhs > 0 */ + + if ( options->ConditionNumber ) { + /* Set INFO = A->ncol+1 if the matrix is singular to working precision. */ + /*if ( *rcond < dlamch_("E") ) *info = A->ncol + 1;*/ + if ( *rcond < dmach("E") ) *info = A->ncol + 1; + } + + if ( nofact ) { + dQuerySpace(L, U, mem_usage); + Destroy_CompCol_Permuted(&AC); + } + if ( A->Stype == SLU_NR ) { + Destroy_SuperMatrix_Store(AA); + SUPERLU_FREE(AA); + } + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dgstrf.c b/src/Libraries/superlu-5.2.1/SRC/dgstrf.c new file mode 100644 index 00000000..25fdf5a8 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dgstrf.c @@ -0,0 +1,459 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dgstrf.c + * \brief Computes an LU factorization of a general sparse matrix + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ * 
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_ddefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * DGSTRF computes an LU factorization of a general sparse m-by-n
+ * matrix A using partial pivoting with row interchanges.
+ * The factorization has the form
+ *     Pr * A = L * U
+ * where Pr is a row permutation matrix, L is lower triangular with unit
+ * diagonal elements (lower trapezoidal if A->nrow > A->ncol), and U is upper 
+ * triangular (upper trapezoidal if A->nrow < A->ncol).
+ *
+ * See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *         The structure defines the input parameters to control
+ *         how the LU decomposition will be performed.
+ *
+ * A        (input) SuperMatrix*
+ *	    Original matrix A, permuted by columns, of dimension
+ *          (A->nrow, A->ncol). The type of A can be:
+ *          Stype = SLU_NCP; Dtype = SLU_D; Mtype = SLU_GE.
+ *
+ * relax    (input) int
+ *          To control degree of relaxing supernodes. If the number
+ *          of nodes (columns) in a subtree of the elimination tree is less
+ *          than relax, this subtree is considered as one supernode,
+ *          regardless of the row structures of those columns.
+ *
+ * panel_size (input) int
+ *          A panel consists of at most panel_size consecutive columns.
+ *
+ * etree    (input) int*, dimension (A->ncol)
+ *          Elimination tree of A'*A.
+ *          Note: etree is a vector of parent pointers for a forest whose
+ *          vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *          On input, the columns of A should be permuted so that the
+ *          etree is in a certain postorder.
+ *
+ * work     (input/output) void*, size (lwork) (in bytes)
+ *          User-supplied work space and space for the output data structures.
+ *          Not referenced if lwork = 0;
+ *
+ * lwork   (input) int
+ *         Specifies the size of work array in bytes.
+ *         = 0:  allocate space internally by system malloc;
+ *         > 0:  use user-supplied work array of length lwork in bytes,
+ *               returns error if space runs out.
+ *         = -1: the routine guesses the amount of space needed without
+ *               performing the factorization, and returns it in
+ *               *info; no other side effects.
+ *
+ * perm_c   (input) int*, dimension (A->ncol)
+ *	    Column permutation vector, which defines the 
+ *          permutation matrix Pc; perm_c[i] = j means column i of A is 
+ *          in position j in A*Pc.
+ *          When searching for diagonal, perm_c[*] is applied to the
+ *          row subscripts of A, so that diagonal threshold pivoting
+ *          can find the diagonal of A, rather than that of A*Pc.
+ *
+ * perm_r   (input/output) int*, dimension (A->nrow)
+ *          Row permutation vector which defines the permutation matrix Pr,
+ *          perm_r[i] = j means row i of A is in position j in Pr*A.
+ *          If options->Fact == SamePattern_SameRowPerm, the pivoting routine
+ *             will try to use the input perm_r, unless a certain threshold
+ *             criterion is violated. In that case, perm_r is overwritten by
+ *             a new permutation determined by partial pivoting or diagonal
+ *             threshold pivoting.
+ *          Otherwise, perm_r is output argument;
+ *
+ * L        (output) SuperMatrix*
+ *          The factor L from the factorization Pr*A=L*U; use compressed row 
+ *          subscripts storage for supernodes, i.e., L has type: 
+ *          Stype = SLU_SC, Dtype = SLU_D, Mtype = SLU_TRLU.
+ *
+ * U        (output) SuperMatrix*
+ *	    The factor U from the factorization Pr*A*Pc=L*U. Use column-wise
+ *          storage scheme, i.e., U has types: Stype = SLU_NC, 
+ *          Dtype = SLU_D, Mtype = SLU_TRU.
+ *
+ * Glu      (input/output) GlobalLU_t *
+ *          If options->Fact == SamePattern_SameRowPerm, it is an input;
+ *              The matrix A will be factorized assuming that a 
+ *              factorization of a matrix with the same sparsity pattern
+ *              and similar numerical values was performed prior to this one.
+ *              Therefore, this factorization will reuse both row and column
+ *		scaling factors R and C, both row and column permutation
+ *		vectors perm_r and perm_c, and the L & U data structures
+ *		set up from the previous factorization.
+ *          Otherwise, it is an output.
+ *
+ * stat     (output) SuperLUStat_t*
+ *          Record the statistics on runtime and floating-point operation count.
+ *          See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info     (output) int*
+ *          = 0: successful exit
+ *          < 0: if info = -i, the i-th argument had an illegal value
+ *          > 0: if info = i, and i is
+ *             <= A->ncol: U(i,i) is exactly zero. The factorization has
+ *                been completed, but the factor U is exactly singular,
+ *                and division by zero will occur if it is used to solve a
+ *                system of equations.
+ *             > A->ncol: number of bytes allocated when memory allocation
+ *                failure occurred, plus A->ncol. If lwork = -1, it is
+ *                the estimated amount of space needed, plus A->ncol.
+ *
+ * ======================================================================
+ *
+ * Local Working Arrays: 
+ * ======================
+ *   m = number of rows in the matrix
+ *   n = number of columns in the matrix
+ *
+ *   xprune[0:n-1]: xprune[*] points to locations in subscript 
+ *	vector lsub[*]. For column i, xprune[i] denotes the point where 
+ *	structural pruning begins. I.e. only xlsub[i],..,xprune[i]-1 need 
+ *	to be traversed for symbolic factorization.
+ *
+ *   marker[0:3*m-1]: marker[i] = j means that node i has been 
+ *	reached when working on column j.
+ *	Storage: relative to original row subscripts
+ *	NOTE: There are 3 of them: marker/marker1 are used for panel dfs, 
+ *	      see dpanel_dfs.c; marker2 is used for inner-factorization,
+ *            see dcolumn_dfs.c.
+ *
+ *   parent[0:m-1]: parent vector used during dfs
+ *      Storage: relative to new row subscripts
+ *
+ *   xplore[0:m-1]: xplore[i] gives the location of the next (dfs) 
+ *	unexplored neighbor of i in lsub[*]
+ *
+ *   segrep[0:nseg-1]: contains the list of supernodal representatives
+ *	in topological order of the dfs. A supernode representative is the 
+ *	last column of a supernode.
+ *      The maximum size of segrep[] is n.
+ *
+ *   repfnz[0:W*m-1]: for a nonzero segment U[*,j] that ends at a 
+ *	supernodal representative r, repfnz[r] is the location of the first 
+ *	nonzero in this segment.  It is also used during the dfs: repfnz[r]>0
+ *	indicates the supernode r has been explored.
+ *	NOTE: There are W of them, each used for one column of a panel. 
+ *
+ *   panel_lsub[0:W*m-1]: temporary for the nonzeros row indices below 
+ *      the panel diagonal. These are filled in during dpanel_dfs(), and are
+ *      used later in the inner LU factorization within the panel.
+ *	panel_lsub[]/dense[] pair forms the SPA data structure.
+ *	NOTE: There are W of them.
+ *
+ *   dense[0:W*m-1]: sparse accumulating (SPA) vector for intermediate values;
+ *	    	   NOTE: there are W of them.
+ *
+ *   tempv[0:*]: real temporary used for dense numeric kernels;
+ *	The size of this array is defined by NUM_TEMPV() in slu_ddefs.h.
+ * 
+ */ + +void +dgstrf (superlu_options_t *options, SuperMatrix *A, + int relax, int panel_size, int *etree, void *work, int lwork, + int *perm_c, int *perm_r, SuperMatrix *L, SuperMatrix *U, + GlobalLU_t *Glu, /* persistent to facilitate multiple factorizations */ + SuperLUStat_t *stat, int *info) +{ + /* Local working arrays */ + NCPformat *Astore; + int *iperm_r = NULL; /* inverse of perm_r; used when + options->Fact == SamePattern_SameRowPerm */ + int *iperm_c; /* inverse of perm_c */ + int *iwork; + double *dwork; + int *segrep, *repfnz, *parent, *xplore; + int *panel_lsub; /* dense[]/panel_lsub[] pair forms a w-wide SPA */ + int *xprune; + int *marker; + double *dense, *tempv; + int *relax_end; + double *a; + int *asub; + int *xa_begin, *xa_end; + int *xsup, *supno; + int *xlsub, *xlusup, *xusub; + int nzlumax; + double fill_ratio = sp_ienv(6); /* estimated fill ratio */ + + /* Local scalars */ + fact_t fact = options->Fact; + double diag_pivot_thresh = options->DiagPivotThresh; + int pivrow; /* pivotal row number in the original matrix A */ + int nseg1; /* no of segments in U-column above panel row jcol */ + int nseg; /* no of segments in each U-column */ + register int jcol; + register int kcol; /* end column of a relaxed snode */ + register int icol; + register int i, k, jj, new_next, iinfo; + int m, n, min_mn, jsupno, fsupc, nextlu, nextu; + int w_def; /* upper bound on panel width */ + int usepr, iperm_r_allocated = 0; + int nnzL, nnzU; + int *panel_histo = stat->panel_histo; + flops_t *ops = stat->ops; + + iinfo = 0; + m = A->nrow; + n = A->ncol; + min_mn = SUPERLU_MIN(m, n); + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + + /* Allocate storage common to the factor routines */ + *info = dLUMemInit(fact, work, lwork, m, n, Astore->nnz, + panel_size, fill_ratio, L, U, Glu, &iwork, &dwork); + if ( *info ) return; + + xsup = Glu->xsup; + supno = Glu->supno; + xlsub = Glu->xlsub; + xlusup = Glu->xlusup; + xusub = Glu->xusub; + + SetIWork(m, n, panel_size, iwork, &segrep, &parent, &xplore, + &repfnz, &panel_lsub, &xprune, &marker); + dSetRWork(m, panel_size, dwork, &dense, &tempv); + + usepr = (fact == SamePattern_SameRowPerm); + if ( usepr ) { + /* Compute the inverse of perm_r */ + iperm_r = (int *) intMalloc(m); + for (k = 0; k < m; ++k) iperm_r[perm_r[k]] = k; + iperm_r_allocated = 1; + } + iperm_c = (int *) intMalloc(n); + for (k = 0; k < n; ++k) iperm_c[perm_c[k]] = k; + + /* Identify relaxed snodes */ + relax_end = (int *) intMalloc(n); + if ( options->SymmetricMode == YES ) { + heap_relax_snode(n, etree, relax, marker, relax_end); + } else { + relax_snode(n, etree, relax, marker, relax_end); + } + + ifill (perm_r, m, EMPTY); + ifill (marker, m * NO_MARKER, EMPTY); + supno[0] = -1; + xsup[0] = xlsub[0] = xusub[0] = xlusup[0] = 0; + w_def = panel_size; + + /* + * Work on one "panel" at a time. A panel is one of the following: + * (a) a relaxed supernode at the bottom of the etree, or + * (b) panel_size contiguous columns, defined by the user + */ + for (jcol = 0; jcol < min_mn; ) { + + if ( relax_end[jcol] != EMPTY ) { /* start of a relaxed snode */ + kcol = relax_end[jcol]; /* end of the relaxed snode */ + panel_histo[kcol-jcol+1]++; + + /* -------------------------------------- + * Factorize the relaxed supernode(jcol:kcol) + * -------------------------------------- */ + /* Determine the union of the row structure of the snode */ + if ( (*info = dsnode_dfs(jcol, kcol, asub, xa_begin, xa_end, + xprune, marker, Glu)) != 0 ) + return; + + nextu = xusub[jcol]; + nextlu = xlusup[jcol]; + jsupno = supno[jcol]; + fsupc = xsup[jsupno]; + new_next = nextlu + (xlsub[fsupc+1]-xlsub[fsupc])*(kcol-jcol+1); + nzlumax = Glu->nzlumax; + while ( new_next > nzlumax ) { + if ( (*info = dLUMemXpand(jcol, nextlu, LUSUP, &nzlumax, Glu)) ) + return; + } + + for (icol = jcol; icol<= kcol; icol++) { + xusub[icol+1] = nextu; + + /* Scatter into SPA dense[*] */ + for (k = xa_begin[icol]; k < xa_end[icol]; k++) + dense[asub[k]] = a[k]; + + /* Numeric update within the snode */ + dsnode_bmod(icol, jsupno, fsupc, dense, tempv, Glu, stat); + + if ( (*info = dpivotL(icol, diag_pivot_thresh, &usepr, perm_r, + iperm_r, iperm_c, &pivrow, Glu, stat)) ) + if ( iinfo == 0 ) iinfo = *info; + +#ifdef DEBUG + dprint_lu_col("[1]: ", icol, pivrow, xprune, Glu); +#endif + + } + + jcol = icol; + + } else { /* Work on one panel of panel_size columns */ + + /* Adjust panel_size so that a panel won't overlap with the next + * relaxed snode. + */ + panel_size = w_def; + for (k = jcol + 1; k < SUPERLU_MIN(jcol+panel_size, min_mn); k++) + if ( relax_end[k] != EMPTY ) { + panel_size = k - jcol; + break; + } + if ( k == min_mn ) panel_size = min_mn - jcol; + panel_histo[panel_size]++; + + /* symbolic factor on a panel of columns */ + dpanel_dfs(m, panel_size, jcol, A, perm_r, &nseg1, + dense, panel_lsub, segrep, repfnz, xprune, + marker, parent, xplore, Glu); + + /* numeric sup-panel updates in topological order */ + dpanel_bmod(m, panel_size, jcol, nseg1, dense, + tempv, segrep, repfnz, Glu, stat); + + /* Sparse LU within the panel, and below panel diagonal */ + for ( jj = jcol; jj < jcol + panel_size; jj++) { + k = (jj - jcol) * m; /* column index for w-wide arrays */ + + nseg = nseg1; /* Begin after all the panel segments */ + + if ((*info = dcolumn_dfs(m, jj, perm_r, &nseg, &panel_lsub[k], + segrep, &repfnz[k], xprune, marker, + parent, xplore, Glu)) != 0) return; + + /* Numeric updates */ + if ((*info = dcolumn_bmod(jj, (nseg - nseg1), &dense[k], + tempv, &segrep[nseg1], &repfnz[k], + jcol, Glu, stat)) != 0) return; + + /* Copy the U-segments to ucol[*] */ + if ((*info = dcopy_to_ucol(jj, nseg, segrep, &repfnz[k], + perm_r, &dense[k], Glu)) != 0) + return; + + if ( (*info = dpivotL(jj, diag_pivot_thresh, &usepr, perm_r, + iperm_r, iperm_c, &pivrow, Glu, stat)) ) + if ( iinfo == 0 ) iinfo = *info; + + /* Prune columns (0:jj-1) using column jj */ + dpruneL(jj, perm_r, pivrow, nseg, segrep, + &repfnz[k], xprune, Glu); + + /* Reset repfnz[] for this column */ + resetrep_col (nseg, segrep, &repfnz[k]); + +#ifdef DEBUG + dprint_lu_col("[2]: ", jj, pivrow, xprune, Glu); +#endif + + } + + jcol += panel_size; /* Move to the next panel */ + + } /* else */ + + } /* for */ + + *info = iinfo; + + if ( m > n ) { + k = 0; + for (i = 0; i < m; ++i) + if ( perm_r[i] == EMPTY ) { + perm_r[i] = n + k; + ++k; + } + } + + countnz(min_mn, xprune, &nnzL, &nnzU, Glu); + fixupL(min_mn, perm_r, Glu); + + dLUWorkFree(iwork, dwork, Glu); /* Free work space and compress storage */ + + if ( fact == SamePattern_SameRowPerm ) { + /* L and U structures may have changed due to possibly different + pivoting, even though the storage is available. + There could also be memory expansions, so the array locations + may have changed, */ + ((SCformat *)L->Store)->nnz = nnzL; + ((SCformat *)L->Store)->nsuper = Glu->supno[n]; + ((SCformat *)L->Store)->nzval = (double *) Glu->lusup; + ((SCformat *)L->Store)->nzval_colptr = Glu->xlusup; + ((SCformat *)L->Store)->rowind = Glu->lsub; + ((SCformat *)L->Store)->rowind_colptr = Glu->xlsub; + ((NCformat *)U->Store)->nnz = nnzU; + ((NCformat *)U->Store)->nzval = (double *) Glu->ucol; + ((NCformat *)U->Store)->rowind = Glu->usub; + ((NCformat *)U->Store)->colptr = Glu->xusub; + } else { + dCreate_SuperNode_Matrix(L, A->nrow, min_mn, nnzL, + (double *) Glu->lusup, Glu->xlusup, + Glu->lsub, Glu->xlsub, Glu->supno, Glu->xsup, + SLU_SC, SLU_D, SLU_TRLU); + dCreate_CompCol_Matrix(U, min_mn, min_mn, nnzU, + (double *) Glu->ucol, Glu->usub, Glu->xusub, + SLU_NC, SLU_D, SLU_TRU); + } + + ops[FACT] += ops[TRSV] + ops[GEMV]; + stat->expansions = --(Glu->num_expansions); + + if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r); + SUPERLU_FREE (iperm_c); + SUPERLU_FREE (relax_end); + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dgstrs.c b/src/Libraries/superlu-5.2.1/SRC/dgstrs.c new file mode 100644 index 00000000..8482c658 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dgstrs.c @@ -0,0 +1,347 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dgstrs.c + * \brief Solves a system using LU factorization + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + +#include "slu_ddefs.h" + + +/* + * Function prototypes + */ +void dusolve(int, int, double*, double*); +void dlsolve(int, int, double*, double*); +void dmatvec(int, int, int, double*, double*, double*); + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * DGSTRS solves a system of linear equations A*X=B or A'*X=B
+ * with A sparse and B dense, using the LU factorization computed by
+ * DGSTRF.
+ *
+ * See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * trans   (input) trans_t
+ *          Specifies the form of the system of equations:
+ *          = NOTRANS: A * X = B  (No transpose)
+ *          = TRANS:   A'* X = B  (Transpose)
+ *          = CONJ:    A**H * X = B  (Conjugate transpose)
+ *
+ * L       (input) SuperMatrix*
+ *         The factor L from the factorization Pr*A*Pc=L*U as computed by
+ *         dgstrf(). Use compressed row subscripts storage for supernodes,
+ *         i.e., L has types: Stype = SLU_SC, Dtype = SLU_D, Mtype = SLU_TRLU.
+ *
+ * U       (input) SuperMatrix*
+ *         The factor U from the factorization Pr*A*Pc=L*U as computed by
+ *         dgstrf(). Use column-wise storage scheme, i.e., U has types:
+ *         Stype = SLU_NC, Dtype = SLU_D, Mtype = SLU_TRU.
+ *
+ * perm_c  (input) int*, dimension (L->ncol)
+ *	   Column permutation vector, which defines the 
+ *         permutation matrix Pc; perm_c[i] = j means column i of A is 
+ *         in position j in A*Pc.
+ *
+ * perm_r  (input) int*, dimension (L->nrow)
+ *         Row permutation vector, which defines the permutation matrix Pr; 
+ *         perm_r[i] = j means row i of A is in position j in Pr*A.
+ *
+ * B       (input/output) SuperMatrix*
+ *         B has types: Stype = SLU_DN, Dtype = SLU_D, Mtype = SLU_GE.
+ *         On entry, the right hand side matrix.
+ *         On exit, the solution matrix if info = 0;
+ *
+ * stat     (output) SuperLUStat_t*
+ *          Record the statistics on runtime and floating-point operation count.
+ *          See util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ * 	   = 0: successful exit
+ *	   < 0: if info = -i, the i-th argument had an illegal value
+ * 
+ */ + +void +dgstrs (trans_t trans, SuperMatrix *L, SuperMatrix *U, + int *perm_c, int *perm_r, SuperMatrix *B, + SuperLUStat_t *stat, int *info) +{ + +#ifdef _CRAY + _fcd ftcs1, ftcs2, ftcs3, ftcs4; +#endif + int incx = 1, incy = 1; +#ifdef USE_VENDOR_BLAS + double alpha = 1.0, beta = 1.0; + double *work_col; +#endif + DNformat *Bstore; + double *Bmat; + SCformat *Lstore; + NCformat *Ustore; + double *Lval, *Uval; + int fsupc, nrow, nsupr, nsupc, luptr, istart, irow; + int i, j, k, iptr, jcol, n, ldb, nrhs; + double *work, *rhs_work, *soln; + flops_t solve_ops; + void dprint_soln(); + + /* Test input parameters ... */ + *info = 0; + Bstore = B->Store; + ldb = Bstore->lda; + nrhs = B->ncol; + if ( trans != NOTRANS && trans != TRANS && trans != CONJ ) *info = -1; + else if ( L->nrow != L->ncol || L->nrow < 0 || + L->Stype != SLU_SC || L->Dtype != SLU_D || L->Mtype != SLU_TRLU ) + *info = -2; + else if ( U->nrow != U->ncol || U->nrow < 0 || + U->Stype != SLU_NC || U->Dtype != SLU_D || U->Mtype != SLU_TRU ) + *info = -3; + else if ( ldb < SUPERLU_MAX(0, L->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_D || B->Mtype != SLU_GE ) + *info = -6; + if ( *info ) { + i = -(*info); + input_error("dgstrs", &i); + return; + } + + n = L->nrow; + work = doubleCalloc(n * nrhs); + if ( !work ) ABORT("Malloc fails for local work[]."); + soln = doubleMalloc(n); + if ( !soln ) ABORT("Malloc fails for local soln[]."); + + Bmat = Bstore->nzval; + Lstore = L->Store; + Lval = Lstore->nzval; + Ustore = U->Store; + Uval = Ustore->nzval; + solve_ops = 0; + + if ( trans == NOTRANS ) { + /* Permute right hand sides to form Pr*B */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[perm_r[k]] = rhs_work[k]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + /* Forward solve PLy=Pb. */ + for (k = 0; k <= Lstore->nsuper; k++) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + nrow = nsupr - nsupc; + + solve_ops += nsupc * (nsupc - 1) * nrhs; + solve_ops += 2 * nrow * nsupc * nrhs; + + if ( nsupc == 1 ) { + for (j = 0; j < nrhs; j++) { + rhs_work = &Bmat[j*ldb]; + luptr = L_NZ_START(fsupc); + for (iptr=istart+1; iptr < L_SUB_START(fsupc+1); iptr++){ + irow = L_SUB(iptr); + ++luptr; + rhs_work[irow] -= rhs_work[fsupc] * Lval[luptr]; + } + } + } else { + luptr = L_NZ_START(fsupc); +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + ftcs1 = _cptofcd("L", strlen("L")); + ftcs2 = _cptofcd("N", strlen("N")); + ftcs3 = _cptofcd("U", strlen("U")); + STRSM( ftcs1, ftcs1, ftcs2, ftcs3, &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); + + SGEMM( ftcs2, ftcs2, &nrow, &nrhs, &nsupc, &alpha, + &Lval[luptr+nsupc], &nsupr, &Bmat[fsupc], &ldb, + &beta, &work[0], &n ); +#else + dtrsm_("L", "L", "N", "U", &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); + + dgemm_( "N", "N", &nrow, &nrhs, &nsupc, &alpha, + &Lval[luptr+nsupc], &nsupr, &Bmat[fsupc], &ldb, + &beta, &work[0], &n ); +#endif + for (j = 0; j < nrhs; j++) { + rhs_work = &Bmat[j*ldb]; + work_col = &work[j*n]; + iptr = istart + nsupc; + for (i = 0; i < nrow; i++) { + irow = L_SUB(iptr); + rhs_work[irow] -= work_col[i]; /* Scatter */ + work_col[i] = 0.0; + iptr++; + } + } +#else + for (j = 0; j < nrhs; j++) { + rhs_work = &Bmat[j*ldb]; + dlsolve (nsupr, nsupc, &Lval[luptr], &rhs_work[fsupc]); + dmatvec (nsupr, nrow, nsupc, &Lval[luptr+nsupc], + &rhs_work[fsupc], &work[0] ); + + iptr = istart + nsupc; + for (i = 0; i < nrow; i++) { + irow = L_SUB(iptr); + rhs_work[irow] -= work[i]; + work[i] = 0.0; + iptr++; + } + } +#endif + } /* else ... */ + } /* for L-solve */ + +#ifdef DEBUG + printf("After L-solve: y=\n"); + dprint_soln(n, nrhs, Bmat); +#endif + + /* + * Back solve Ux=y. + */ + for (k = Lstore->nsuper; k >= 0; k--) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + solve_ops += nsupc * (nsupc + 1) * nrhs; + + if ( nsupc == 1 ) { + rhs_work = &Bmat[0]; + for (j = 0; j < nrhs; j++) { + rhs_work[fsupc] /= Lval[luptr]; + rhs_work += ldb; + } + } else { +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + ftcs1 = _cptofcd("L", strlen("L")); + ftcs2 = _cptofcd("U", strlen("U")); + ftcs3 = _cptofcd("N", strlen("N")); + STRSM( ftcs1, ftcs2, ftcs3, ftcs3, &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); +#else + dtrsm_("L", "U", "N", "N", &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); +#endif +#else + for (j = 0; j < nrhs; j++) + dusolve ( nsupr, nsupc, &Lval[luptr], &Bmat[fsupc+j*ldb] ); +#endif + } + + for (j = 0; j < nrhs; ++j) { + rhs_work = &Bmat[j*ldb]; + for (jcol = fsupc; jcol < fsupc + nsupc; jcol++) { + solve_ops += 2*(U_NZ_START(jcol+1) - U_NZ_START(jcol)); + for (i = U_NZ_START(jcol); i < U_NZ_START(jcol+1); i++ ){ + irow = U_SUB(i); + rhs_work[irow] -= rhs_work[jcol] * Uval[i]; + } + } + } + + } /* for U-solve */ + +#ifdef DEBUG + printf("After U-solve: x=\n"); + dprint_soln(n, nrhs, Bmat); +#endif + + /* Compute the final solution X := Pc*X. */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[k] = rhs_work[perm_c[k]]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + stat->ops[SOLVE] = solve_ops; + + } else { /* Solve A'*X=B or CONJ(A)*X=B */ + /* Permute right hand sides to form Pc'*B. */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[perm_c[k]] = rhs_work[k]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + stat->ops[SOLVE] = 0; + for (k = 0; k < nrhs; ++k) { + + /* Multiply by inv(U'). */ + sp_dtrsv("U", "T", "N", L, U, &Bmat[k*ldb], stat, info); + + /* Multiply by inv(L'). */ + sp_dtrsv("L", "T", "U", L, U, &Bmat[k*ldb], stat, info); + + } + /* Compute the final solution X := Pr'*X (=inv(Pr)*X) */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[k] = rhs_work[perm_r[k]]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + } + + SUPERLU_FREE(work); + SUPERLU_FREE(soln); +} + +/* + * Diagnostic print of the solution vector + */ +void +dprint_soln(int n, int nrhs, double *soln) +{ + int i; + + for (i = 0; i < n; i++) + printf("\t%d: %.4f\n", i, soln[i]); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dlacon.c b/src/Libraries/superlu-5.2.1/SRC/dlacon.c new file mode 100644 index 00000000..ab79a54d --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dlacon.c @@ -0,0 +1,247 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dlacon.c + * \brief Estimates the 1-norm + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ */ +#include +#include "slu_Cnames.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   DLACON estimates the 1-norm of a square matrix A.   
+ *   Reverse communication is used for evaluating matrix-vector products. 
+ * 
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   N      (input) INT
+ *          The order of the matrix.  N >= 1.   
+ *
+ *   V      (workspace) DOUBLE PRECISION array, dimension (N)   
+ *          On the final return, V = A*W,  where  EST = norm(V)/norm(W)   
+ *          (W is not returned).   
+ *
+ *   X      (input/output) DOUBLE PRECISION array, dimension (N)   
+ *          On an intermediate return, X should be overwritten by   
+ *                A * X,   if KASE=1,   
+ *                A' * X,  if KASE=2,
+ *         and DLACON must be re-called with all the other parameters   
+ *          unchanged.   
+ *
+ *   ISGN   (workspace) INT array, dimension (N)
+ *
+ *   EST    (output) DOUBLE PRECISION   
+ *          An estimate (a lower bound) for norm(A).   
+ *
+ *   KASE   (input/output) INT
+ *          On the initial call to DLACON, KASE should be 0.   
+ *          On an intermediate return, KASE will be 1 or 2, indicating   
+ *          whether X should be overwritten by A * X  or A' * X.   
+ *          On the final return from DLACON, KASE will again be 0.   
+ *
+ *   Further Details   
+ *   ======= =======   
+ *
+ *   Contributed by Nick Higham, University of Manchester.   
+ *   Originally named CONEST, dated March 16, 1988.   
+ *
+ *   Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of 
+ *   a real or complex matrix, with applications to condition estimation", 
+ *   ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.   
+ *   ===================================================================== 
+ * 
+ */ + +int +dlacon_(int *n, double *v, double *x, int *isgn, double *est, int *kase) + +{ + + + /* Table of constant values */ + int c__1 = 1; + double zero = 0.0; + double one = 1.0; + + /* Local variables */ + static int jump; + int iter; + int jlast; + double altsgn, estold; + int i, j; + double temp; +#ifdef _CRAY + extern int ISAMAX(int *, double *, int *); + extern double SASUM(int *, double *, int *); + extern int SCOPY(int *, double *, int *, double *, int *); +#else + extern int idamax_(int *, double *, int *); + extern double dasum_(int *, double *, int *); + extern int dcopy_(int *, double *, int *, double *, int *); +#endif +#define d_sign(a, b) (b >= 0 ? fabs(a) : -fabs(a)) /* Copy sign */ +#define i_dnnt(a) \ + ( a>=0 ? floor(a+.5) : -floor(.5-a) ) /* Round to nearest integer */ + + if ( *kase == 0 ) { + for (i = 0; i < *n; ++i) { + x[i] = 1. / (double) (*n); + } + *kase = 1; + jump = 1; + return 0; + } + + switch (jump) { + case 1: goto L20; + case 2: goto L40; + case 3: goto L70; + case 4: goto L110; + case 5: goto L140; + } + + /* ................ ENTRY (JUMP = 1) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY A*X. */ + L20: + if (*n == 1) { + v[0] = x[0]; + *est = fabs(v[0]); + /* ... QUIT */ + goto L150; + } +#ifdef _CRAY + *est = SASUM(n, x, &c__1); +#else + *est = dasum_(n, x, &c__1); +#endif + + for (i = 0; i < *n; ++i) { + x[i] = d_sign(one, x[i]); + isgn[i] = i_dnnt(x[i]); + } + *kase = 2; + jump = 2; + return 0; + + /* ................ ENTRY (JUMP = 2) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X. */ +L40: +#ifdef _CRAY + j = ISAMAX(n, &x[0], &c__1); +#else + j = idamax_(n, &x[0], &c__1); +#endif + --j; + iter = 2; + + /* MAIN LOOP - ITERATIONS 2,3,...,ITMAX. */ +L50: + for (i = 0; i < *n; ++i) x[i] = zero; + x[j] = one; + *kase = 1; + jump = 3; + return 0; + + /* ................ ENTRY (JUMP = 3) + X HAS BEEN OVERWRITTEN BY A*X. */ +L70: +#ifdef _CRAY + SCOPY(n, x, &c__1, v, &c__1); +#else + dcopy_(n, x, &c__1, v, &c__1); +#endif + estold = *est; +#ifdef _CRAY + *est = SASUM(n, v, &c__1); +#else + *est = dasum_(n, v, &c__1); +#endif + + for (i = 0; i < *n; ++i) + if (i_dnnt(d_sign(one, x[i])) != isgn[i]) + goto L90; + + /* REPEATED SIGN VECTOR DETECTED, HENCE ALGORITHM HAS CONVERGED. */ + goto L120; + +L90: + /* TEST FOR CYCLING. */ + if (*est <= estold) goto L120; + + for (i = 0; i < *n; ++i) { + x[i] = d_sign(one, x[i]); + isgn[i] = i_dnnt(x[i]); + } + *kase = 2; + jump = 4; + return 0; + + /* ................ ENTRY (JUMP = 4) + X HAS BEEN OVERWRITTEN BY TRANDPOSE(A)*X. */ +L110: + jlast = j; +#ifdef _CRAY + j = ISAMAX(n, &x[0], &c__1); +#else + j = idamax_(n, &x[0], &c__1); +#endif + --j; + if (x[jlast] != fabs(x[j]) && iter < 5) { + ++iter; + goto L50; + } + + /* ITERATION COMPLETE. FINAL STAGE. */ +L120: + altsgn = 1.; + for (i = 1; i <= *n; ++i) { + x[i-1] = altsgn * ((double)(i - 1) / (double)(*n - 1) + 1.); + altsgn = -altsgn; + } + *kase = 1; + jump = 5; + return 0; + + /* ................ ENTRY (JUMP = 5) + X HAS BEEN OVERWRITTEN BY A*X. */ +L140: +#ifdef _CRAY + temp = SASUM(n, x, &c__1) / (double)(*n * 3) * 2.; +#else + temp = dasum_(n, x, &c__1) / (double)(*n * 3) * 2.; +#endif + if (temp > *est) { +#ifdef _CRAY + SCOPY(n, &x[0], &c__1, &v[0], &c__1); +#else + dcopy_(n, &x[0], &c__1, &v[0], &c__1); +#endif + *est = temp; + } + +L150: + *kase = 0; + return 0; + +} /* dlacon_ */ diff --git a/src/Libraries/superlu-5.2.1/SRC/dlacon2.c b/src/Libraries/superlu-5.2.1/SRC/dlacon2.c new file mode 100644 index 00000000..1855b115 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dlacon2.c @@ -0,0 +1,254 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dlacon2.c + * \brief Estimates the 1-norm + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * July 25, 2015
+ * 
+ */ +#include +#include "slu_Cnames.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   DLACON2 estimates the 1-norm of a square matrix A.   
+ *   Reverse communication is used for evaluating matrix-vector products. 
+ * 
+ *   This is a thread safe version of DLACON, which uses the array ISAVE
+ *   in place of a STATIC variables, as follows:
+ *
+ *     DLACON     DLACON2
+ *      jump     isave[0]
+ *      j        isave[1]
+ *      iter     isave[2]
+ *
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   N      (input) INT
+ *          The order of the matrix.  N >= 1.   
+ *
+ *   V      (workspace) DOUBLE PRECISION array, dimension (N)   
+ *          On the final return, V = A*W,  where  EST = norm(V)/norm(W)   
+ *          (W is not returned).   
+ *
+ *   X      (input/output) DOUBLE PRECISION array, dimension (N)   
+ *          On an intermediate return, X should be overwritten by   
+ *                A * X,   if KASE=1,   
+ *                A' * X,  if KASE=2,
+ *         and DLACON must be re-called with all the other parameters   
+ *          unchanged.   
+ *
+ *   ISGN   (workspace) INT array, dimension (N)
+ *
+ *   EST    (output) DOUBLE PRECISION   
+ *          An estimate (a lower bound) for norm(A).   
+ *
+ *   KASE   (input/output) INT
+ *          On the initial call to DLACON, KASE should be 0.   
+ *          On an intermediate return, KASE will be 1 or 2, indicating   
+ *          whether X should be overwritten by A * X  or A' * X.   
+ *          On the final return from DLACON, KASE will again be 0.   
+ *
+ *   isave  (input/output) int [3]
+ *          ISAVE is INTEGER array, dimension (3)
+ *          ISAVE is used to save variables between calls to DLACON2
+ *
+ *   Further Details   
+ *   ===============   
+ *
+ *   Contributed by Nick Higham, University of Manchester.   
+ *   Originally named CONEST, dated March 16, 1988.   
+ *
+ *   Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of 
+ *   a real or complex matrix, with applications to condition estimation", 
+ *   ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.   
+ *   ===================================================================== 
+ * 
+ */ + +int +dlacon2_(int *n, double *v, double *x, int *isgn, double *est, int *kase, int isave[3]) +{ + /* Table of constant values */ + int c__1 = 1; + double zero = 0.0; + double one = 1.0; + + /* Local variables */ + int jlast; + double altsgn, estold; + int i; + double temp; +#ifdef _CRAY + extern int ISAMAX(int *, double *, int *); + extern double SASUM(int *, double *, int *); + extern int SCOPY(int *, double *, int *, double *, int *); +#else + extern int idamax_(int *, double *, int *); + extern double dasum_(int *, double *, int *); + extern int dcopy_(int *, double *, int *, double *, int *); +#endif +#define d_sign(a, b) (b >= 0 ? fabs(a) : -fabs(a)) /* Copy sign */ +#define i_dnnt(a) \ + ( a>=0 ? floor(a+.5) : -floor(.5-a) ) /* Round to nearest integer */ + + if ( *kase == 0 ) { + for (i = 0; i < *n; ++i) { + x[i] = 1. / (double) (*n); + } + *kase = 1; + isave[0] = 1; /* jump = 1; */ + return 0; + } + + switch (isave[0]) { + case 1: goto L20; + case 2: goto L40; + case 3: goto L70; + case 4: goto L110; + case 5: goto L140; + } + + /* ................ ENTRY (isave[0] = 1) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY A*X. */ + L20: + if (*n == 1) { + v[0] = x[0]; + *est = fabs(v[0]); + /* ... QUIT */ + goto L150; + } +#ifdef _CRAY + *est = SASUM(n, x, &c__1); +#else + *est = dasum_(n, x, &c__1); +#endif + + for (i = 0; i < *n; ++i) { + x[i] = d_sign(one, x[i]); + isgn[i] = i_dnnt(x[i]); + } + *kase = 2; + isave[0] = 2; /* jump = 2; */ + return 0; + + /* ................ ENTRY (isave[0] = 2) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X. */ +L40: +#ifdef _CRAY + isave[1] = ISAMAX(n, &x[0], &c__1); /* j */ +#else + isave[1] = idamax_(n, &x[0], &c__1); /* j */ +#endif + --isave[1]; /* --j; */ + isave[2] = 2; /* iter = 2; */ + + /* MAIN LOOP - ITERATIONS 2,3,...,ITMAX. */ +L50: + for (i = 0; i < *n; ++i) x[i] = zero; + x[isave[1]] = one; + *kase = 1; + isave[0] = 3; /* jump = 3; */ + return 0; + + /* ................ ENTRY (isave[0] = 3) + X HAS BEEN OVERWRITTEN BY A*X. */ +L70: +#ifdef _CRAY + SCOPY(n, x, &c__1, v, &c__1); +#else + dcopy_(n, x, &c__1, v, &c__1); +#endif + estold = *est; +#ifdef _CRAY + *est = SASUM(n, v, &c__1); +#else + *est = dasum_(n, v, &c__1); +#endif + + for (i = 0; i < *n; ++i) + if (i_dnnt(d_sign(one, x[i])) != isgn[i]) + goto L90; + + /* REPEATED SIGN VECTOR DETECTED, HENCE ALGORITHM HAS CONVERGED. */ + goto L120; + +L90: + /* TEST FOR CYCLING. */ + if (*est <= estold) goto L120; + + for (i = 0; i < *n; ++i) { + x[i] = d_sign(one, x[i]); + isgn[i] = i_dnnt(x[i]); + } + *kase = 2; + isave[0] = 4; /* jump = 4; */ + return 0; + + /* ................ ENTRY (isave[0] = 4) + X HAS BEEN OVERWRITTEN BY TRANDPOSE(A)*X. */ +L110: + jlast = isave[1]; /* j; */ +#ifdef _CRAY + isave[1] = ISAMAX(n, &x[0], &c__1); /* j */ +#else + isave[1] = idamax_(n, &x[0], &c__1); /* j */ +#endif + isave[1] = isave[1] - 1; /* --j; */ + if (x[jlast] != fabs(x[isave[1]]) && isave[2] < 5) { + isave[2] = isave[2] + 1; /* ++iter; */ + goto L50; + } + + /* ITERATION COMPLETE. FINAL STAGE. */ +L120: + altsgn = 1.; + for (i = 1; i <= *n; ++i) { + x[i-1] = altsgn * ((double)(i - 1) / (double)(*n - 1) + 1.); + altsgn = -altsgn; + } + *kase = 1; + isave[0] = 5; /* jump = 5; */ + return 0; + + /* ................ ENTRY (isave[0] = 5) + X HAS BEEN OVERWRITTEN BY A*X. */ +L140: +#ifdef _CRAY + temp = SASUM(n, x, &c__1) / (double)(*n * 3) * 2.; +#else + temp = dasum_(n, x, &c__1) / (double)(*n * 3) * 2.; +#endif + if (temp > *est) { +#ifdef _CRAY + SCOPY(n, &x[0], &c__1, &v[0], &c__1); +#else + dcopy_(n, &x[0], &c__1, &v[0], &c__1); +#endif + *est = temp; + } + +L150: + *kase = 0; + return 0; + +} /* dlacon_ */ diff --git a/src/Libraries/superlu-5.2.1/SRC/dlangs.c b/src/Libraries/superlu-5.2.1/SRC/dlangs.c new file mode 100644 index 00000000..013fde6a --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dlangs.c @@ -0,0 +1,129 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dlangs.c + * \brief Returns the value of the one norm + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Modified from lapack routine DLANGE 
+ * 
+ */ +/* + * File name: dlangs.c + * History: Modified from lapack routine DLANGE + */ +#include +#include "slu_ddefs.h" + +/*! \brief + * + *
+ * Purpose   
+ *   =======   
+ *
+ *   DLANGS returns the value of the one norm, or the Frobenius norm, or 
+ *   the infinity norm, or the element of largest absolute value of a 
+ *   real matrix A.   
+ *
+ *   Description   
+ *   ===========   
+ *
+ *   DLANGE returns the value   
+ *
+ *      DLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm'   
+ *               (   
+ *               ( norm1(A),         NORM = '1', 'O' or 'o'   
+ *               (   
+ *               ( normI(A),         NORM = 'I' or 'i'   
+ *               (   
+ *               ( normF(A),         NORM = 'F', 'f', 'E' or 'e'   
+ *
+ *   where  norm1  denotes the  one norm of a matrix (maximum column sum), 
+ *   normI  denotes the  infinity norm  of a matrix  (maximum row sum) and 
+ *   normF  denotes the  Frobenius norm of a matrix (square root of sum of 
+ *   squares).  Note that  max(abs(A(i,j)))  is not a  matrix norm.   
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   NORM    (input) CHARACTER*1   
+ *           Specifies the value to be returned in DLANGE as described above.   
+ *   A       (input) SuperMatrix*
+ *           The M by N sparse matrix A. 
+ *
+ *  =====================================================================
+ * 
+ */ + +double dlangs(char *norm, SuperMatrix *A) +{ + + /* Local variables */ + NCformat *Astore; + double *Aval; + int i, j, irow; + double value, sum; + double *rwork; + + Astore = A->Store; + Aval = Astore->nzval; + + if ( SUPERLU_MIN(A->nrow, A->ncol) == 0) { + value = 0.; + + } else if (strncmp(norm, "M", 1)==0) { + /* Find max(abs(A(i,j))). */ + value = 0.; + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++) + value = SUPERLU_MAX( value, fabs( Aval[i]) ); + + } else if (strncmp(norm, "O", 1)==0 || *(unsigned char *)norm == '1') { + /* Find norm1(A). */ + value = 0.; + for (j = 0; j < A->ncol; ++j) { + sum = 0.; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++) + sum += fabs(Aval[i]); + value = SUPERLU_MAX(value,sum); + } + + } else if (strncmp(norm, "I", 1)==0) { + /* Find normI(A). */ + if ( !(rwork = (double *) SUPERLU_MALLOC(A->nrow * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for rwork."); + for (i = 0; i < A->nrow; ++i) rwork[i] = 0.; + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++) { + irow = Astore->rowind[i]; + rwork[irow] += fabs(Aval[i]); + } + value = 0.; + for (i = 0; i < A->nrow; ++i) + value = SUPERLU_MAX(value, rwork[i]); + + SUPERLU_FREE (rwork); + + } else if (strncmp(norm, "F", 1)==0 || strncmp(norm, "E", 1)==0) { + /* Find normF(A). */ + ABORT("Not implemented."); + } else + ABORT("Illegal norm specified."); + + return (value); + +} /* dlangs */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/dlaqgs.c b/src/Libraries/superlu-5.2.1/SRC/dlaqgs.c new file mode 100644 index 00000000..5a85288e --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dlaqgs.c @@ -0,0 +1,155 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dlaqgs.c + * \brief Equlibrates a general sprase matrix + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ * Modified from LAPACK routine DLAQGE
+ * 
+ */ +/* + * File name: dlaqgs.c + * History: Modified from LAPACK routine DLAQGE + */ +#include +#include "slu_ddefs.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   DLAQGS equilibrates a general sparse M by N matrix A using the row and   
+ *   scaling factors in the vectors R and C.   
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   A       (input/output) SuperMatrix*
+ *           On exit, the equilibrated matrix.  See EQUED for the form of 
+ *           the equilibrated matrix. The type of A can be:
+ *	    Stype = NC; Dtype = SLU_D; Mtype = GE.
+ *	    
+ *   R       (input) double*, dimension (A->nrow)
+ *           The row scale factors for A.
+ *	    
+ *   C       (input) double*, dimension (A->ncol)
+ *           The column scale factors for A.
+ *	    
+ *   ROWCND  (input) double
+ *           Ratio of the smallest R(i) to the largest R(i).
+ *	    
+ *   COLCND  (input) double
+ *           Ratio of the smallest C(i) to the largest C(i).
+ *	    
+ *   AMAX    (input) double
+ *           Absolute value of largest matrix entry.
+ *	    
+ *   EQUED   (output) char*
+ *           Specifies the form of equilibration that was done.   
+ *           = 'N':  No equilibration   
+ *           = 'R':  Row equilibration, i.e., A has been premultiplied by  
+ *                   diag(R).   
+ *           = 'C':  Column equilibration, i.e., A has been postmultiplied  
+ *                   by diag(C).   
+ *           = 'B':  Both row and column equilibration, i.e., A has been
+ *                   replaced by diag(R) * A * diag(C).   
+ *
+ *   Internal Parameters   
+ *   ===================   
+ *
+ *   THRESH is a threshold value used to decide if row or column scaling   
+ *   should be done based on the ratio of the row or column scaling   
+ *   factors.  If ROWCND < THRESH, row scaling is done, and if   
+ *   COLCND < THRESH, column scaling is done.   
+ *
+ *   LARGE and SMALL are threshold values used to decide if row scaling   
+ *   should be done based on the absolute size of the largest matrix   
+ *   element.  If AMAX > LARGE or AMAX < SMALL, row scaling is done.   
+ *
+ *   ===================================================================== 
+ * 
+ */ + +void +dlaqgs(SuperMatrix *A, double *r, double *c, + double rowcnd, double colcnd, double amax, char *equed) +{ + + +#define THRESH (0.1) + + /* Local variables */ + NCformat *Astore; + double *Aval; + int i, j, irow; + double large, small, cj; + + + /* Quick return if possible */ + if (A->nrow <= 0 || A->ncol <= 0) { + *(unsigned char *)equed = 'N'; + return; + } + + Astore = A->Store; + Aval = Astore->nzval; + + /* Initialize LARGE and SMALL. */ + small = dmach("Safe minimum") / dmach("Precision"); + large = 1. / small; + + if (rowcnd >= THRESH && amax >= small && amax <= large) { + if (colcnd >= THRESH) + *(unsigned char *)equed = 'N'; + else { + /* Column scaling */ + for (j = 0; j < A->ncol; ++j) { + cj = c[j]; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + Aval[i] *= cj; + } + } + *(unsigned char *)equed = 'C'; + } + } else if (colcnd >= THRESH) { + /* Row scaling, no column scaling */ + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + Aval[i] *= r[irow]; + } + *(unsigned char *)equed = 'R'; + } else { + /* Row and column scaling */ + for (j = 0; j < A->ncol; ++j) { + cj = c[j]; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + Aval[i] *= cj * r[irow]; + } + } + *(unsigned char *)equed = 'B'; + } + + return; + +} /* dlaqgs */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/dldperm.c b/src/Libraries/superlu-5.2.1/SRC/dldperm.c new file mode 100644 index 00000000..3995f7a5 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dldperm.c @@ -0,0 +1,175 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file + * \brief Finds a row permutation so that the matrix has large entries on the diagonal + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ + +#include "slu_ddefs.h" + +extern int_t mc64id_(int_t*); +extern int_t mc64ad_(int_t*, int_t*, int_t*, int_t [], int_t [], double [], + int_t*, int_t [], int_t*, int_t[], int_t*, double [], + int_t [], int_t []); + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *   DLDPERM finds a row permutation so that the matrix has large
+ *   entries on the diagonal.
+ *
+ * Arguments
+ * =========
+ *
+ * job    (input) int
+ *        Control the action. Possible values for JOB are:
+ *        = 1 : Compute a row permutation of the matrix so that the
+ *              permuted matrix has as many entries on its diagonal as
+ *              possible. The values on the diagonal are of arbitrary size.
+ *              HSL subroutine MC21A/AD is used for this.
+ *        = 2 : Compute a row permutation of the matrix so that the smallest 
+ *              value on the diagonal of the permuted matrix is maximized.
+ *        = 3 : Compute a row permutation of the matrix so that the smallest
+ *              value on the diagonal of the permuted matrix is maximized.
+ *              The algorithm differs from the one used for JOB = 2 and may
+ *              have quite a different performance.
+ *        = 4 : Compute a row permutation of the matrix so that the sum
+ *              of the diagonal entries of the permuted matrix is maximized.
+ *        = 5 : Compute a row permutation of the matrix so that the product
+ *              of the diagonal entries of the permuted matrix is maximized
+ *              and vectors to scale the matrix so that the nonzero diagonal 
+ *              entries of the permuted matrix are one in absolute value and 
+ *              all the off-diagonal entries are less than or equal to one in 
+ *              absolute value.
+ *        Restriction: 1 <= JOB <= 5.
+ *
+ * n      (input) int
+ *        The order of the matrix.
+ *
+ * nnz    (input) int
+ *        The number of nonzeros in the matrix.
+ *
+ * adjncy (input) int*, of size nnz
+ *        The adjacency structure of the matrix, which contains the row
+ *        indices of the nonzeros.
+ *
+ * colptr (input) int*, of size n+1
+ *        The pointers to the beginning of each column in ADJNCY.
+ *
+ * nzval  (input) double*, of size nnz
+ *        The nonzero values of the matrix. nzval[k] is the value of
+ *        the entry corresponding to adjncy[k].
+ *        It is not used if job = 1.
+ *
+ * perm   (output) int*, of size n
+ *        The permutation vector. perm[i] = j means row i in the
+ *        original matrix is in row j of the permuted matrix.
+ *
+ * u      (output) double*, of size n
+ *        If job = 5, the natural logarithms of the row scaling factors. 
+ *
+ * v      (output) double*, of size n
+ *        If job = 5, the natural logarithms of the column scaling factors. 
+ *        The scaled matrix B has entries b_ij = a_ij * exp(u_i + v_j).
+ * 
+ */ + +int +dldperm(int_t job, int_t n, int_t nnz, int_t colptr[], int_t adjncy[], + double nzval[], int_t *perm, double u[], double v[]) +{ + int_t i, liw, ldw, num; + int_t *iw, icntl[10], info[10]; + double *dw; + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter dldperm()"); +#endif + liw = 5*n; + if ( job == 3 ) liw = 10*n + nnz; + if ( !(iw = intMalloc(liw)) ) ABORT("Malloc fails for iw[]"); + ldw = 3*n + nnz; + if ( !(dw = (double*) SUPERLU_MALLOC(ldw * sizeof(double))) ) + ABORT("Malloc fails for dw[]"); + + /* Increment one to get 1-based indexing. */ + for (i = 0; i <= n; ++i) ++colptr[i]; + for (i = 0; i < nnz; ++i) ++adjncy[i]; +#if ( DEBUGlevel>=2 ) + printf("LDPERM(): n %d, nnz %d\n", n, nnz); + slu_PrintInt10("colptr", n+1, colptr); + slu_PrintInt10("adjncy", nnz, adjncy); +#endif + + /* + * NOTE: + * ===== + * + * MC64AD assumes that column permutation vector is defined as: + * perm(i) = j means column i of permuted A is in column j of original A. + * + * Since a symmetric permutation preserves the diagonal entries. Then + * by the following relation: + * P'(A*P')P = P'A + * we can apply inverse(perm) to rows of A to get large diagonal entries. + * But, since 'perm' defined in MC64AD happens to be the reverse of + * SuperLU's definition of permutation vector, therefore, it is already + * an inverse for our purpose. We will thus use it directly. + * + */ + mc64id_(icntl); +#if 0 + /* Suppress error and warning messages. */ + icntl[0] = -1; + icntl[1] = -1; +#endif + + mc64ad_(&job, &n, &nnz, colptr, adjncy, nzval, &num, perm, + &liw, iw, &ldw, dw, icntl, info); + +#if ( DEBUGlevel>=2 ) + slu_PrintInt10("perm", n, perm); + printf(".. After MC64AD info %d\tsize of matching %d\n", info[0], num); +#endif + if ( info[0] == 1 ) { /* Structurally singular */ + printf(".. The last %d permutations:\n", n-num); + slu_PrintInt10("perm", n-num, &perm[num]); + } + + /* Restore to 0-based indexing. */ + for (i = 0; i <= n; ++i) --colptr[i]; + for (i = 0; i < nnz; ++i) --adjncy[i]; + for (i = 0; i < n; ++i) --perm[i]; + + if ( job == 5 ) + for (i = 0; i < n; ++i) { + u[i] = dw[i]; + v[i] = dw[n+i]; + } + + SUPERLU_FREE(iw); + SUPERLU_FREE(dw); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit dldperm()"); +#endif + + return info[0]; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dmach.c b/src/Libraries/superlu-5.2.1/SRC/dmach.c new file mode 100644 index 00000000..73beacb4 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dmach.c @@ -0,0 +1,93 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +#include +#include +#include + +double dmach(char *cmach) +{ +/* -- SuperLU auxiliary routine (version 5.0) -- + This uses C99 standard constants, and is thread safe. + + Must be compiled with -std=c99 flag. + + + Purpose + ======= + + DMACH returns double precision machine parameters. + + Arguments + ========= + + CMACH (input) CHARACTER*1 + Specifies the value to be returned by DMACH: + = 'E' or 'e', DMACH := eps + = 'S' or 's , DMACH := sfmin + = 'B' or 'b', DMACH := base + = 'P' or 'p', DMACH := eps*base + = 'N' or 'n', DMACH := t + = 'R' or 'r', DMACH := rnd + = 'M' or 'm', DMACH := emin + = 'U' or 'u', DMACH := rmin + = 'L' or 'l', DMACH := emax + = 'O' or 'o', DMACH := rmax + + where + + eps = relative machine precision + sfmin = safe minimum, such that 1/sfmin does not overflow + base = base of the machine + prec = eps*base + t = number of (base) digits in the mantissa + rnd = 1.0 when rounding occurs in addition, 0.0 otherwise + emin = minimum exponent before (gradual) underflow + rmin = underflow threshold - base**(emin-1) + emax = largest exponent before overflow + rmax = overflow threshold - (base**emax)*(1-eps) + + ===================================================================== +*/ + + double sfmin, small, rmach; + + if (strncmp(cmach, "E", 1)==0) { + rmach = DBL_EPSILON * 0.5; + } else if (strncmp(cmach, "S", 1)==0) { + sfmin = DBL_MIN; + small = 1. / DBL_MAX; + if (small >= sfmin) { + /* Use SMALL plus a bit, to avoid the possibility of rounding + causing overflow when computing 1/sfmin. */ + sfmin = small * (DBL_EPSILON*0.5 + 1.); + } + rmach = sfmin; + } else if (strncmp(cmach, "B", 1)==0) { + rmach = FLT_RADIX; + } else if (strncmp(cmach, "P", 1)==0) { + rmach = DBL_EPSILON * 0.5 * FLT_RADIX; + } else if (strncmp(cmach, "N", 1)==0) { + rmach = DBL_MANT_DIG; + } else if (strncmp(cmach, "R", 1)==0) { + rmach = FLT_ROUNDS; + } else if (strncmp(cmach, "M", 1)==0) { + rmach = DBL_MIN_EXP; + } else if (strncmp(cmach, "U", 1)==0) { + rmach = DBL_MIN; + } else if (strncmp(cmach, "L", 1)==0) { + rmach = DBL_MAX_EXP; + } else if (strncmp(cmach, "O", 1)==0) { + rmach = DBL_MAX; + } + + return rmach; + +} /* end dmach */ diff --git a/src/Libraries/superlu-5.2.1/SRC/dmemory.c b/src/Libraries/superlu-5.2.1/SRC/dmemory.c new file mode 100644 index 00000000..bd9a38bb --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dmemory.c @@ -0,0 +1,710 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dmemory.c + * \brief Memory details + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ +#include "slu_ddefs.h" + + +/* Internal prototypes */ +void *dexpand (int *, MemType,int, int, GlobalLU_t *); +int dLUWorkInit (int, int, int, int **, double **, GlobalLU_t *); +void copy_mem_double (int, void *, void *); +void dStackCompress (GlobalLU_t *); +void dSetupSpace (void *, int, GlobalLU_t *); +void *duser_malloc (int, int, GlobalLU_t *); +void duser_free (int, int, GlobalLU_t *); + +/* External prototypes (in memory.c - prec-independent) */ +extern void copy_mem_int (int, void *, void *); +extern void user_bcopy (char *, char *, int); + + +/* Macros to manipulate stack */ +#define StackFull(x) ( x + Glu->stack.used >= Glu->stack.size ) +#define NotDoubleAlign(addr) ( (intptr_t)addr & 7 ) +#define DoubleAlign(addr) ( ((intptr_t)addr + 7) & ~7L ) +#define TempSpace(m, w) ( (2*w + 4 + NO_MARKER) * m * sizeof(int) + \ + (w + 1) * m * sizeof(double) ) +#define Reduce(alpha) ((alpha + 1) / 2) /* i.e. (alpha-1)/2 + 1 */ + + + + +/*! \brief Setup the memory model to be used for factorization. + * + * lwork = 0: use system malloc; + * lwork > 0: use user-supplied work[] space. + */ +void dSetupSpace(void *work, int lwork, GlobalLU_t *Glu) +{ + if ( lwork == 0 ) { + Glu->MemModel = SYSTEM; /* malloc/free */ + } else if ( lwork > 0 ) { + Glu->MemModel = USER; /* user provided space */ + Glu->stack.used = 0; + Glu->stack.top1 = 0; + Glu->stack.top2 = (lwork/4)*4; /* must be word addressable */ + Glu->stack.size = Glu->stack.top2; + Glu->stack.array = (void *) work; + } +} + + + +void *duser_malloc(int bytes, int which_end, GlobalLU_t *Glu) +{ + void *buf; + + if ( StackFull(bytes) ) return (NULL); + + if ( which_end == HEAD ) { + buf = (char*) Glu->stack.array + Glu->stack.top1; + Glu->stack.top1 += bytes; + } else { + Glu->stack.top2 -= bytes; + buf = (char*) Glu->stack.array + Glu->stack.top2; + } + + Glu->stack.used += bytes; + return buf; +} + + +void duser_free(int bytes, int which_end, GlobalLU_t *Glu) +{ + if ( which_end == HEAD ) { + Glu->stack.top1 -= bytes; + } else { + Glu->stack.top2 += bytes; + } + Glu->stack.used -= bytes; +} + + + +/*! \brief + * + *
+ * mem_usage consists of the following fields:
+ *    - for_lu (float)
+ *      The amount of space used in bytes for the L\U data structures.
+ *    - total_needed (float)
+ *      The amount of space needed in bytes to perform factorization.
+ * 
+ */ +int dQuerySpace(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage) +{ + SCformat *Lstore; + NCformat *Ustore; + register int n, iword, dword, panel_size = sp_ienv(1); + + Lstore = L->Store; + Ustore = U->Store; + n = L->ncol; + iword = sizeof(int); + dword = sizeof(double); + + /* For LU factors */ + mem_usage->for_lu = (float)( (4.0*n + 3.0) * iword + + Lstore->nzval_colptr[n] * dword + + Lstore->rowind_colptr[n] * iword ); + mem_usage->for_lu += (float)( (n + 1.0) * iword + + Ustore->colptr[n] * (dword + iword) ); + + /* Working storage to support factorization */ + mem_usage->total_needed = mem_usage->for_lu + + (float)( (2.0 * panel_size + 4.0 + NO_MARKER) * n * iword + + (panel_size + 1.0) * n * dword ); + + return 0; +} /* dQuerySpace */ + + +/*! \brief + * + *
+ * mem_usage consists of the following fields:
+ *    - for_lu (float)
+ *      The amount of space used in bytes for the L\U data structures.
+ *    - total_needed (float)
+ *      The amount of space needed in bytes to perform factorization.
+ * 
+ */ +int ilu_dQuerySpace(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage) +{ + SCformat *Lstore; + NCformat *Ustore; + register int n, panel_size = sp_ienv(1); + register float iword, dword; + + Lstore = L->Store; + Ustore = U->Store; + n = L->ncol; + iword = sizeof(int); + dword = sizeof(double); + + /* For LU factors */ + mem_usage->for_lu = (float)( (4.0f * n + 3.0f) * iword + + Lstore->nzval_colptr[n] * dword + + Lstore->rowind_colptr[n] * iword ); + mem_usage->for_lu += (float)( (n + 1.0f) * iword + + Ustore->colptr[n] * (dword + iword) ); + + /* Working storage to support factorization. + ILU needs 5*n more integers than LU */ + mem_usage->total_needed = mem_usage->for_lu + + (float)( (2.0f * panel_size + 9.0f + NO_MARKER) * n * iword + + (panel_size + 1.0f) * n * dword ); + + return 0; +} /* ilu_dQuerySpace */ + + +/*! \brief Allocate storage for the data structures common to all factor routines. + * + *
+ * For those unpredictable size, estimate as fill_ratio * nnz(A).
+ * Return value:
+ *     If lwork = -1, return the estimated amount of space required, plus n;
+ *     otherwise, return the amount of space actually allocated when
+ *     memory allocation failure occurred.
+ * 
+ */ +int +dLUMemInit(fact_t fact, void *work, int lwork, int m, int n, int annz, + int panel_size, double fill_ratio, SuperMatrix *L, SuperMatrix *U, + GlobalLU_t *Glu, int **iwork, double **dwork) +{ + int info, iword, dword; + SCformat *Lstore; + NCformat *Ustore; + int *xsup, *supno; + int *lsub, *xlsub; + double *lusup; + int *xlusup; + double *ucol; + int *usub, *xusub; + int nzlmax, nzumax, nzlumax; + + iword = sizeof(int); + dword = sizeof(double); + Glu->n = n; + Glu->num_expansions = 0; + + Glu->expanders = (ExpHeader *) SUPERLU_MALLOC( NO_MEMTYPE * + sizeof(ExpHeader) ); + if ( !Glu->expanders ) ABORT("SUPERLU_MALLOC fails for expanders"); + + if ( fact != SamePattern_SameRowPerm ) { + /* Guess for L\U factors */ + nzumax = nzlumax = fill_ratio * annz; + nzlmax = SUPERLU_MAX(1, fill_ratio/4.) * annz; + + if ( lwork == -1 ) { + return ( GluIntArray(n) * iword + TempSpace(m, panel_size) + + (nzlmax+nzumax)*iword + (nzlumax+nzumax)*dword + n ); + } else { + dSetupSpace(work, lwork, Glu); + } + +#if ( PRNTlevel >= 1 ) + printf("dLUMemInit() called: fill_ratio %.0f, nzlmax %ld, nzumax %ld\n", + fill_ratio, nzlmax, nzumax); + fflush(stdout); +#endif + + /* Integer pointers for L\U factors */ + if ( Glu->MemModel == SYSTEM ) { + xsup = intMalloc(n+1); + supno = intMalloc(n+1); + xlsub = intMalloc(n+1); + xlusup = intMalloc(n+1); + xusub = intMalloc(n+1); + } else { + xsup = (int *)duser_malloc((n+1) * iword, HEAD, Glu); + supno = (int *)duser_malloc((n+1) * iword, HEAD, Glu); + xlsub = (int *)duser_malloc((n+1) * iword, HEAD, Glu); + xlusup = (int *)duser_malloc((n+1) * iword, HEAD, Glu); + xusub = (int *)duser_malloc((n+1) * iword, HEAD, Glu); + } + + lusup = (double *) dexpand( &nzlumax, LUSUP, 0, 0, Glu ); + ucol = (double *) dexpand( &nzumax, UCOL, 0, 0, Glu ); + lsub = (int *) dexpand( &nzlmax, LSUB, 0, 0, Glu ); + usub = (int *) dexpand( &nzumax, USUB, 0, 1, Glu ); + + while ( !lusup || !ucol || !lsub || !usub ) { + if ( Glu->MemModel == SYSTEM ) { + SUPERLU_FREE(lusup); + SUPERLU_FREE(ucol); + SUPERLU_FREE(lsub); + SUPERLU_FREE(usub); + } else { + duser_free((nzlumax+nzumax)*dword+(nzlmax+nzumax)*iword, + HEAD, Glu); + } + nzlumax /= 2; + nzumax /= 2; + nzlmax /= 2; + if ( nzlumax < annz ) { + printf("Not enough memory to perform factorization.\n"); + return (dmemory_usage(nzlmax, nzumax, nzlumax, n) + n); + } +#if ( PRNTlevel >= 1) + printf("dLUMemInit() reduce size: nzlmax %ld, nzumax %ld\n", + nzlmax, nzumax); + fflush(stdout); +#endif + lusup = (double *) dexpand( &nzlumax, LUSUP, 0, 0, Glu ); + ucol = (double *) dexpand( &nzumax, UCOL, 0, 0, Glu ); + lsub = (int *) dexpand( &nzlmax, LSUB, 0, 0, Glu ); + usub = (int *) dexpand( &nzumax, USUB, 0, 1, Glu ); + } + + } else { + /* fact == SamePattern_SameRowPerm */ + Lstore = L->Store; + Ustore = U->Store; + xsup = Lstore->sup_to_col; + supno = Lstore->col_to_sup; + xlsub = Lstore->rowind_colptr; + xlusup = Lstore->nzval_colptr; + xusub = Ustore->colptr; + nzlmax = Glu->nzlmax; /* max from previous factorization */ + nzumax = Glu->nzumax; + nzlumax = Glu->nzlumax; + + if ( lwork == -1 ) { + return ( GluIntArray(n) * iword + TempSpace(m, panel_size) + + (nzlmax+nzumax)*iword + (nzlumax+nzumax)*dword + n ); + } else if ( lwork == 0 ) { + Glu->MemModel = SYSTEM; + } else { + Glu->MemModel = USER; + Glu->stack.top2 = (lwork/4)*4; /* must be word-addressable */ + Glu->stack.size = Glu->stack.top2; + } + + lsub = Glu->expanders[LSUB].mem = Lstore->rowind; + lusup = Glu->expanders[LUSUP].mem = Lstore->nzval; + usub = Glu->expanders[USUB].mem = Ustore->rowind; + ucol = Glu->expanders[UCOL].mem = Ustore->nzval;; + Glu->expanders[LSUB].size = nzlmax; + Glu->expanders[LUSUP].size = nzlumax; + Glu->expanders[USUB].size = nzumax; + Glu->expanders[UCOL].size = nzumax; + } + + Glu->xsup = xsup; + Glu->supno = supno; + Glu->lsub = lsub; + Glu->xlsub = xlsub; + Glu->lusup = (void *) lusup; + Glu->xlusup = xlusup; + Glu->ucol = (void *) ucol; + Glu->usub = usub; + Glu->xusub = xusub; + Glu->nzlmax = nzlmax; + Glu->nzumax = nzumax; + Glu->nzlumax = nzlumax; + + info = dLUWorkInit(m, n, panel_size, iwork, dwork, Glu); + if ( info ) + return ( info + dmemory_usage(nzlmax, nzumax, nzlumax, n) + n); + + ++Glu->num_expansions; + return 0; + +} /* dLUMemInit */ + +/*! \brief Allocate known working storage. Returns 0 if success, otherwise + returns the number of bytes allocated so far when failure occurred. */ +int +dLUWorkInit(int m, int n, int panel_size, int **iworkptr, + double **dworkptr, GlobalLU_t *Glu) +{ + int isize, dsize, extra; + double *old_ptr; + int maxsuper = SUPERLU_MAX( sp_ienv(3), sp_ienv(7) ), + rowblk = sp_ienv(4); + + isize = ( (2 * panel_size + 3 + NO_MARKER ) * m + n ) * sizeof(int); + dsize = (m * panel_size + + NUM_TEMPV(m,panel_size,maxsuper,rowblk)) * sizeof(double); + + if ( Glu->MemModel == SYSTEM ) + *iworkptr = (int *) intCalloc(isize/sizeof(int)); + else + *iworkptr = (int *) duser_malloc(isize, TAIL, Glu); + if ( ! *iworkptr ) { + fprintf(stderr, "dLUWorkInit: malloc fails for local iworkptr[]\n"); + return (isize + n); + } + + if ( Glu->MemModel == SYSTEM ) + *dworkptr = (double *) SUPERLU_MALLOC(dsize); + else { + *dworkptr = (double *) duser_malloc(dsize, TAIL, Glu); + if ( NotDoubleAlign(*dworkptr) ) { + old_ptr = *dworkptr; + *dworkptr = (double*) DoubleAlign(*dworkptr); + *dworkptr = (double*) ((double*)*dworkptr - 1); + extra = (char*)old_ptr - (char*)*dworkptr; +#ifdef DEBUG + printf("dLUWorkInit: not aligned, extra %d\n", extra); +#endif + Glu->stack.top2 -= extra; + Glu->stack.used += extra; + } + } + if ( ! *dworkptr ) { + fprintf(stderr, "malloc fails for local dworkptr[]."); + return (isize + dsize + n); + } + + return 0; +} + + +/*! \brief Set up pointers for real working arrays. + */ +void +dSetRWork(int m, int panel_size, double *dworkptr, + double **dense, double **tempv) +{ + double zero = 0.0; + + int maxsuper = SUPERLU_MAX( sp_ienv(3), sp_ienv(7) ), + rowblk = sp_ienv(4); + *dense = dworkptr; + *tempv = *dense + panel_size*m; + dfill (*dense, m * panel_size, zero); + dfill (*tempv, NUM_TEMPV(m,panel_size,maxsuper,rowblk), zero); +} + +/*! \brief Free the working storage used by factor routines. + */ +void dLUWorkFree(int *iwork, double *dwork, GlobalLU_t *Glu) +{ + if ( Glu->MemModel == SYSTEM ) { + SUPERLU_FREE (iwork); + SUPERLU_FREE (dwork); + } else { + Glu->stack.used -= (Glu->stack.size - Glu->stack.top2); + Glu->stack.top2 = Glu->stack.size; +/* dStackCompress(Glu); */ + } + + SUPERLU_FREE (Glu->expanders); + Glu->expanders = NULL; +} + +/*! \brief Expand the data structures for L and U during the factorization. + * + *
+ * Return value:   0 - successful return
+ *               > 0 - number of bytes allocated when run out of space
+ * 
+ */ +int +dLUMemXpand(int jcol, + int next, /* number of elements currently in the factors */ + MemType mem_type, /* which type of memory to expand */ + int *maxlen, /* modified - maximum length of a data structure */ + GlobalLU_t *Glu /* modified - global LU data structures */ + ) +{ + void *new_mem; + +#ifdef DEBUG + printf("dLUMemXpand(): jcol %d, next %d, maxlen %d, MemType %d\n", + jcol, next, *maxlen, mem_type); +#endif + + if (mem_type == USUB) + new_mem = dexpand(maxlen, mem_type, next, 1, Glu); + else + new_mem = dexpand(maxlen, mem_type, next, 0, Glu); + + if ( !new_mem ) { + int nzlmax = Glu->nzlmax; + int nzumax = Glu->nzumax; + int nzlumax = Glu->nzlumax; + fprintf(stderr, "Can't expand MemType %d: jcol %d\n", mem_type, jcol); + return (dmemory_usage(nzlmax, nzumax, nzlumax, Glu->n) + Glu->n); + } + + switch ( mem_type ) { + case LUSUP: + Glu->lusup = (void *) new_mem; + Glu->nzlumax = *maxlen; + break; + case UCOL: + Glu->ucol = (void *) new_mem; + Glu->nzumax = *maxlen; + break; + case LSUB: + Glu->lsub = (int *) new_mem; + Glu->nzlmax = *maxlen; + break; + case USUB: + Glu->usub = (int *) new_mem; + Glu->nzumax = *maxlen; + break; + } + + return 0; + +} + + + +void +copy_mem_double(int howmany, void *old, void *new) +{ + register int i; + double *dold = old; + double *dnew = new; + for (i = 0; i < howmany; i++) dnew[i] = dold[i]; +} + +/*! \brief Expand the existing storage to accommodate more fill-ins. + */ +void +*dexpand ( + int *prev_len, /* length used from previous call */ + MemType type, /* which part of the memory to expand */ + int len_to_copy, /* size of the memory to be copied to new store */ + int keep_prev, /* = 1: use prev_len; + = 0: compute new_len to expand */ + GlobalLU_t *Glu /* modified - global LU data structures */ + ) +{ + float EXPAND = 1.5; + float alpha; + void *new_mem, *old_mem; + int new_len, tries, lword, extra, bytes_to_copy; + ExpHeader *expanders = Glu->expanders; /* Array of 4 types of memory */ + + alpha = EXPAND; + + if ( Glu->num_expansions == 0 || keep_prev ) { + /* First time allocate requested */ + new_len = *prev_len; + } else { + new_len = alpha * *prev_len; + } + + if ( type == LSUB || type == USUB ) lword = sizeof(int); + else lword = sizeof(double); + + if ( Glu->MemModel == SYSTEM ) { + new_mem = (void *) SUPERLU_MALLOC((size_t)new_len * lword); + if ( Glu->num_expansions != 0 ) { + tries = 0; + if ( keep_prev ) { + if ( !new_mem ) return (NULL); + } else { + while ( !new_mem ) { + if ( ++tries > 10 ) return (NULL); + alpha = Reduce(alpha); + new_len = alpha * *prev_len; + new_mem = (void *) SUPERLU_MALLOC((size_t)new_len * lword); + } + } + if ( type == LSUB || type == USUB ) { + copy_mem_int(len_to_copy, expanders[type].mem, new_mem); + } else { + copy_mem_double(len_to_copy, expanders[type].mem, new_mem); + } + SUPERLU_FREE (expanders[type].mem); + } + expanders[type].mem = (void *) new_mem; + + } else { /* MemModel == USER */ + if ( Glu->num_expansions == 0 ) { + new_mem = duser_malloc(new_len * lword, HEAD, Glu); + if ( NotDoubleAlign(new_mem) && + (type == LUSUP || type == UCOL) ) { + old_mem = new_mem; + new_mem = (void *)DoubleAlign(new_mem); + extra = (char*)new_mem - (char*)old_mem; +#ifdef DEBUG + printf("expand(): not aligned, extra %d\n", extra); +#endif + Glu->stack.top1 += extra; + Glu->stack.used += extra; + } + expanders[type].mem = (void *) new_mem; + } else { + tries = 0; + extra = (new_len - *prev_len) * lword; + if ( keep_prev ) { + if ( StackFull(extra) ) return (NULL); + } else { + while ( StackFull(extra) ) { + if ( ++tries > 10 ) return (NULL); + alpha = Reduce(alpha); + new_len = alpha * *prev_len; + extra = (new_len - *prev_len) * lword; + } + } + + if ( type != USUB ) { + new_mem = (void*)((char*)expanders[type + 1].mem + extra); + bytes_to_copy = (char*)Glu->stack.array + Glu->stack.top1 + - (char*)expanders[type + 1].mem; + user_bcopy(expanders[type+1].mem, new_mem, bytes_to_copy); + + if ( type < USUB ) { + Glu->usub = expanders[USUB].mem = + (void*)((char*)expanders[USUB].mem + extra); + } + if ( type < LSUB ) { + Glu->lsub = expanders[LSUB].mem = + (void*)((char*)expanders[LSUB].mem + extra); + } + if ( type < UCOL ) { + Glu->ucol = expanders[UCOL].mem = + (void*)((char*)expanders[UCOL].mem + extra); + } + Glu->stack.top1 += extra; + Glu->stack.used += extra; + if ( type == UCOL ) { + Glu->stack.top1 += extra; /* Add same amount for USUB */ + Glu->stack.used += extra; + } + + } /* if ... */ + + } /* else ... */ + } + + expanders[type].size = new_len; + *prev_len = new_len; + if ( Glu->num_expansions ) ++Glu->num_expansions; + + return (void *) expanders[type].mem; + +} /* dexpand */ + + +/*! \brief Compress the work[] array to remove fragmentation. + */ +void +dStackCompress(GlobalLU_t *Glu) +{ + register int iword, dword, ndim; + char *last, *fragment; + int *ifrom, *ito; + double *dfrom, *dto; + int *xlsub, *lsub, *xusub, *usub, *xlusup; + double *ucol, *lusup; + + iword = sizeof(int); + dword = sizeof(double); + ndim = Glu->n; + + xlsub = Glu->xlsub; + lsub = Glu->lsub; + xusub = Glu->xusub; + usub = Glu->usub; + xlusup = Glu->xlusup; + ucol = Glu->ucol; + lusup = Glu->lusup; + + dfrom = ucol; + dto = (double *)((char*)lusup + xlusup[ndim] * dword); + copy_mem_double(xusub[ndim], dfrom, dto); + ucol = dto; + + ifrom = lsub; + ito = (int *) ((char*)ucol + xusub[ndim] * iword); + copy_mem_int(xlsub[ndim], ifrom, ito); + lsub = ito; + + ifrom = usub; + ito = (int *) ((char*)lsub + xlsub[ndim] * iword); + copy_mem_int(xusub[ndim], ifrom, ito); + usub = ito; + + last = (char*)usub + xusub[ndim] * iword; + fragment = (char*) (((char*)Glu->stack.array + Glu->stack.top1) - last); + Glu->stack.used -= (long int) fragment; + Glu->stack.top1 -= (long int) fragment; + + Glu->ucol = ucol; + Glu->lsub = lsub; + Glu->usub = usub; + +#ifdef DEBUG + printf("dStackCompress: fragment %d\n", fragment); + /* for (last = 0; last < ndim; ++last) + print_lu_col("After compress:", last, 0);*/ +#endif + +} + +/*! \brief Allocate storage for original matrix A + */ +void +dallocateA(int n, int nnz, double **a, int **asub, int **xa) +{ + *a = (double *) doubleMalloc(nnz); + *asub = (int *) intMalloc(nnz); + *xa = (int *) intMalloc(n+1); +} + + +double *doubleMalloc(int n) +{ + double *buf; + buf = (double *) SUPERLU_MALLOC((size_t)n * sizeof(double)); + if ( !buf ) { + ABORT("SUPERLU_MALLOC failed for buf in doubleMalloc()\n"); + } + return (buf); +} + +double *doubleCalloc(int n) +{ + double *buf; + register int i; + double zero = 0.0; + buf = (double *) SUPERLU_MALLOC((size_t)n * sizeof(double)); + if ( !buf ) { + ABORT("SUPERLU_MALLOC failed for buf in doubleCalloc()\n"); + } + for (i = 0; i < n; ++i) buf[i] = zero; + return (buf); +} + + +int dmemory_usage(const int nzlmax, const int nzumax, + const int nzlumax, const int n) +{ + register int iword, dword; + + iword = sizeof(int); + dword = sizeof(double); + + return (10 * n * iword + + nzlmax * iword + nzumax * (iword + dword) + nzlumax * dword); + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dmyblas2.c b/src/Libraries/superlu-5.2.1/SRC/dmyblas2.c new file mode 100644 index 00000000..e4357274 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dmyblas2.c @@ -0,0 +1,240 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dmyblas2.c + * \brief Level 2 Blas operations + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ * Purpose: + * Level 2 BLAS operations: solves and matvec, written in C. + * Note: + * This is only used when the system lacks an efficient BLAS library. + * + */ +/* + * File name: dmyblas2.c + */ + +/*! \brief Solves a dense UNIT lower triangular system + * + * The unit lower + * triangular matrix is stored in a 2D array M(1:nrow,1:ncol). + * The solution will be returned in the rhs vector. + */ +void dlsolve ( int ldm, int ncol, double *M, double *rhs ) +{ + int k; + double x0, x1, x2, x3, x4, x5, x6, x7; + double *M0; + register double *Mki0, *Mki1, *Mki2, *Mki3, *Mki4, *Mki5, *Mki6, *Mki7; + register int firstcol = 0; + + M0 = &M[0]; + + while ( firstcol < ncol - 7 ) { /* Do 8 columns */ + Mki0 = M0 + 1; + Mki1 = Mki0 + ldm + 1; + Mki2 = Mki1 + ldm + 1; + Mki3 = Mki2 + ldm + 1; + Mki4 = Mki3 + ldm + 1; + Mki5 = Mki4 + ldm + 1; + Mki6 = Mki5 + ldm + 1; + Mki7 = Mki6 + ldm + 1; + + x0 = rhs[firstcol]; + x1 = rhs[firstcol+1] - x0 * *Mki0++; + x2 = rhs[firstcol+2] - x0 * *Mki0++ - x1 * *Mki1++; + x3 = rhs[firstcol+3] - x0 * *Mki0++ - x1 * *Mki1++ - x2 * *Mki2++; + x4 = rhs[firstcol+4] - x0 * *Mki0++ - x1 * *Mki1++ - x2 * *Mki2++ + - x3 * *Mki3++; + x5 = rhs[firstcol+5] - x0 * *Mki0++ - x1 * *Mki1++ - x2 * *Mki2++ + - x3 * *Mki3++ - x4 * *Mki4++; + x6 = rhs[firstcol+6] - x0 * *Mki0++ - x1 * *Mki1++ - x2 * *Mki2++ + - x3 * *Mki3++ - x4 * *Mki4++ - x5 * *Mki5++; + x7 = rhs[firstcol+7] - x0 * *Mki0++ - x1 * *Mki1++ - x2 * *Mki2++ + - x3 * *Mki3++ - x4 * *Mki4++ - x5 * *Mki5++ + - x6 * *Mki6++; + + rhs[++firstcol] = x1; + rhs[++firstcol] = x2; + rhs[++firstcol] = x3; + rhs[++firstcol] = x4; + rhs[++firstcol] = x5; + rhs[++firstcol] = x6; + rhs[++firstcol] = x7; + ++firstcol; + + for (k = firstcol; k < ncol; k++) + rhs[k] = rhs[k] - x0 * *Mki0++ - x1 * *Mki1++ + - x2 * *Mki2++ - x3 * *Mki3++ + - x4 * *Mki4++ - x5 * *Mki5++ + - x6 * *Mki6++ - x7 * *Mki7++; + + M0 += 8 * ldm + 8; + } + + while ( firstcol < ncol - 3 ) { /* Do 4 columns */ + Mki0 = M0 + 1; + Mki1 = Mki0 + ldm + 1; + Mki2 = Mki1 + ldm + 1; + Mki3 = Mki2 + ldm + 1; + + x0 = rhs[firstcol]; + x1 = rhs[firstcol+1] - x0 * *Mki0++; + x2 = rhs[firstcol+2] - x0 * *Mki0++ - x1 * *Mki1++; + x3 = rhs[firstcol+3] - x0 * *Mki0++ - x1 * *Mki1++ - x2 * *Mki2++; + + rhs[++firstcol] = x1; + rhs[++firstcol] = x2; + rhs[++firstcol] = x3; + ++firstcol; + + for (k = firstcol; k < ncol; k++) + rhs[k] = rhs[k] - x0 * *Mki0++ - x1 * *Mki1++ + - x2 * *Mki2++ - x3 * *Mki3++; + + M0 += 4 * ldm + 4; + } + + if ( firstcol < ncol - 1 ) { /* Do 2 columns */ + Mki0 = M0 + 1; + Mki1 = Mki0 + ldm + 1; + + x0 = rhs[firstcol]; + x1 = rhs[firstcol+1] - x0 * *Mki0++; + + rhs[++firstcol] = x1; + ++firstcol; + + for (k = firstcol; k < ncol; k++) + rhs[k] = rhs[k] - x0 * *Mki0++ - x1 * *Mki1++; + + } + +} + +/*! \brief Solves a dense upper triangular system + * + * The upper triangular matrix is + * stored in a 2-dim array M(1:ldm,1:ncol). The solution will be returned + * in the rhs vector. + */ +void +dusolve ( ldm, ncol, M, rhs ) +int ldm; /* in */ +int ncol; /* in */ +double *M; /* in */ +double *rhs; /* modified */ +{ + double xj; + int jcol, j, irow; + + jcol = ncol - 1; + + for (j = 0; j < ncol; j++) { + + xj = rhs[jcol] / M[jcol + jcol*ldm]; /* M(jcol, jcol) */ + rhs[jcol] = xj; + + for (irow = 0; irow < jcol; irow++) + rhs[irow] -= xj * M[irow + jcol*ldm]; /* M(irow, jcol) */ + + jcol--; + + } +} + + +/*! \brief Performs a dense matrix-vector multiply: Mxvec = Mxvec + M * vec. + * + * The input matrix is M(1:nrow,1:ncol); The product is returned in Mxvec[]. + */ +void dmatvec ( ldm, nrow, ncol, M, vec, Mxvec ) + +int ldm; /* in -- leading dimension of M */ +int nrow; /* in */ +int ncol; /* in */ +double *M; /* in */ +double *vec; /* in */ +double *Mxvec; /* in/out */ + +{ + double vi0, vi1, vi2, vi3, vi4, vi5, vi6, vi7; + double *M0; + register double *Mki0, *Mki1, *Mki2, *Mki3, *Mki4, *Mki5, *Mki6, *Mki7; + register int firstcol = 0; + int k; + + M0 = &M[0]; + while ( firstcol < ncol - 7 ) { /* Do 8 columns */ + + Mki0 = M0; + Mki1 = Mki0 + ldm; + Mki2 = Mki1 + ldm; + Mki3 = Mki2 + ldm; + Mki4 = Mki3 + ldm; + Mki5 = Mki4 + ldm; + Mki6 = Mki5 + ldm; + Mki7 = Mki6 + ldm; + + vi0 = vec[firstcol++]; + vi1 = vec[firstcol++]; + vi2 = vec[firstcol++]; + vi3 = vec[firstcol++]; + vi4 = vec[firstcol++]; + vi5 = vec[firstcol++]; + vi6 = vec[firstcol++]; + vi7 = vec[firstcol++]; + + for (k = 0; k < nrow; k++) + Mxvec[k] += vi0 * *Mki0++ + vi1 * *Mki1++ + + vi2 * *Mki2++ + vi3 * *Mki3++ + + vi4 * *Mki4++ + vi5 * *Mki5++ + + vi6 * *Mki6++ + vi7 * *Mki7++; + + M0 += 8 * ldm; + } + + while ( firstcol < ncol - 3 ) { /* Do 4 columns */ + + Mki0 = M0; + Mki1 = Mki0 + ldm; + Mki2 = Mki1 + ldm; + Mki3 = Mki2 + ldm; + + vi0 = vec[firstcol++]; + vi1 = vec[firstcol++]; + vi2 = vec[firstcol++]; + vi3 = vec[firstcol++]; + for (k = 0; k < nrow; k++) + Mxvec[k] += vi0 * *Mki0++ + vi1 * *Mki1++ + + vi2 * *Mki2++ + vi3 * *Mki3++ ; + + M0 += 4 * ldm; + } + + while ( firstcol < ncol ) { /* Do 1 column */ + + Mki0 = M0; + vi0 = vec[firstcol++]; + for (k = 0; k < nrow; k++) + Mxvec[k] += vi0 * *Mki0++; + + M0 += ldm; + } + +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/dpanel_bmod.c b/src/Libraries/superlu-5.2.1/SRC/dpanel_bmod.c new file mode 100644 index 00000000..2d7c0163 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dpanel_bmod.c @@ -0,0 +1,466 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dpanel_bmod.c + * \brief Performs numeric block updates + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ +/* + +*/ + +#include +#include +#include "slu_ddefs.h" + +/* + * Function prototypes + */ +void dlsolve(int, int, double *, double *); +void dmatvec(int, int, int, double *, double *, double *); +extern void dcheck_tempv(); + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *    Performs numeric block updates (sup-panel) in topological order.
+ *    It features: col-col, 2cols-col, 3cols-col, and sup-col updates.
+ *    Special processing on the supernodal portion of L\U[*,j]
+ *
+ *    Before entering this routine, the original nonzeros in the panel 
+ *    were already copied into the spa[m,w].
+ *
+ *    Updated/Output parameters-
+ *    dense[0:m-1,w]: L[*,j:j+w-1] and U[*,j:j+w-1] are returned 
+ *    collectively in the m-by-w vector dense[*]. 
+ * 
+ */ + +void +dpanel_bmod ( + const int m, /* in - number of rows in the matrix */ + const int w, /* in */ + const int jcol, /* in */ + const int nseg, /* in */ + double *dense, /* out, of size n by w */ + double *tempv, /* working array */ + int *segrep, /* in */ + int *repfnz, /* in, of size n by w */ + GlobalLU_t *Glu, /* modified */ + SuperLUStat_t *stat /* output */ + ) +{ + + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + int incx = 1, incy = 1; + double alpha, beta; +#endif + + register int k, ksub; + int fsupc, nsupc, nsupr, nrow; + int krep, krep_ind; + double ukj, ukj1, ukj2; + int luptr, luptr1, luptr2; + int segsze; + int block_nrow; /* no of rows in a block row */ + register int lptr; /* Points to the row subscripts of a supernode */ + int kfnz, irow, no_zeros; + register int isub, isub1, i; + register int jj; /* Index through each column in the panel */ + int *xsup, *supno; + int *lsub, *xlsub; + double *lusup; + int *xlusup; + int *repfnz_col; /* repfnz[] for a column in the panel */ + double *dense_col; /* dense[] for a column in the panel */ + double *tempv1; /* Used in 1-D update */ + double *TriTmp, *MatvecTmp; /* used in 2-D update */ + double zero = 0.0; + double one = 1.0; + register int ldaTmp; + register int r_ind, r_hi; + int maxsuper, rowblk, colblk; + flops_t *ops = stat->ops; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (double *) Glu->lusup; + xlusup = Glu->xlusup; + + maxsuper = SUPERLU_MAX( sp_ienv(3), sp_ienv(7) ); + rowblk = sp_ienv(4); + colblk = sp_ienv(5); + ldaTmp = maxsuper + rowblk; + + /* + * For each nonz supernode segment of U[*,j] in topological order + */ + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { /* for each updating supernode */ + + /* krep = representative of current k-th supernode + * fsupc = first supernodal column + * nsupc = no of columns in a supernode + * nsupr = no of rows in a supernode + */ + krep = segrep[k--]; + fsupc = xsup[supno[krep]]; + nsupc = krep - fsupc + 1; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; + nrow = nsupr - nsupc; + lptr = xlsub[fsupc]; + krep_ind = lptr + nsupc - 1; + + repfnz_col = repfnz; + dense_col = dense; + + if ( nsupc >= colblk && nrow > rowblk ) { /* 2-D block update */ + + TriTmp = tempv; + + /* Sequence through each column in panel -- triangular solves */ + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m, TriTmp += ldaTmp ) { + + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + luptr = xlusup[fsupc]; + + ops[TRSV] += segsze * (segsze - 1); + ops[GEMV] += 2 * nrow * segsze; + + /* Case 1: Update U-segment of size 1 -- col-col update */ + if ( segsze == 1 ) { + ukj = dense_col[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc; + + for (i = lptr + nsupc; i < xlsub[fsupc+1]; i++) { + irow = lsub[i]; + dense_col[irow] -= ukj * lusup[luptr]; + ++luptr; + } + + } else if ( segsze <= 3 ) { + ukj = dense_col[lsub[krep_ind]]; + ukj1 = dense_col[lsub[krep_ind - 1]]; + luptr += nsupr*(nsupc-1) + nsupc-1; + luptr1 = luptr - nsupr; + + if ( segsze == 2 ) { + ukj -= ukj1 * lusup[luptr1]; + dense_col[lsub[krep_ind]] = ukj; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; luptr1++; + dense_col[irow] -= (ukj*lusup[luptr] + + ukj1*lusup[luptr1]); + } + } else { + ukj2 = dense_col[lsub[krep_ind - 2]]; + luptr2 = luptr1 - nsupr; + ukj1 -= ukj2 * lusup[luptr2-1]; + ukj = ukj - ukj1*lusup[luptr1] - ukj2*lusup[luptr2]; + dense_col[lsub[krep_ind]] = ukj; + dense_col[lsub[krep_ind-1]] = ukj1; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; luptr1++; luptr2++; + dense_col[irow] -= ( ukj*lusup[luptr] + + ukj1*lusup[luptr1] + ukj2*lusup[luptr2] ); + } + } + + } else { /* segsze >= 4 */ + + /* Copy U[*,j] segment from dense[*] to TriTmp[*], which + holds the result of triangular solves. */ + no_zeros = kfnz - fsupc; + isub = lptr + no_zeros; + for (i = 0; i < segsze; ++i) { + irow = lsub[isub]; + TriTmp[i] = dense_col[irow]; /* Gather */ + ++isub; + } + + /* start effective triangle */ + luptr += nsupr * no_zeros + no_zeros; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + STRSV( ftcs1, ftcs2, ftcs3, &segsze, &lusup[luptr], + &nsupr, TriTmp, &incx ); +#else + dtrsv_( "L", "N", "U", &segsze, &lusup[luptr], + &nsupr, TriTmp, &incx ); +#endif +#else + dlsolve ( nsupr, segsze, &lusup[luptr], TriTmp ); +#endif + + + } /* else ... */ + + } /* for jj ... end tri-solves */ + + /* Block row updates; push all the way into dense[*] block */ + for ( r_ind = 0; r_ind < nrow; r_ind += rowblk ) { + + r_hi = SUPERLU_MIN(nrow, r_ind + rowblk); + block_nrow = SUPERLU_MIN(rowblk, r_hi - r_ind); + luptr = xlusup[fsupc] + nsupc + r_ind; + isub1 = lptr + nsupc + r_ind; + + repfnz_col = repfnz; + TriTmp = tempv; + dense_col = dense; + + /* Sequence through each column in panel -- matrix-vector */ + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m, TriTmp += ldaTmp) { + + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + if ( segsze <= 3 ) continue; /* skip unrolled cases */ + + /* Perform a block update, and scatter the result of + matrix-vector to dense[]. */ + no_zeros = kfnz - fsupc; + luptr1 = luptr + nsupr * no_zeros; + MatvecTmp = &TriTmp[maxsuper]; + +#ifdef USE_VENDOR_BLAS + alpha = one; + beta = zero; +#ifdef _CRAY + SGEMV(ftcs2, &block_nrow, &segsze, &alpha, &lusup[luptr1], + &nsupr, TriTmp, &incx, &beta, MatvecTmp, &incy); +#else + dgemv_("N", &block_nrow, &segsze, &alpha, &lusup[luptr1], + &nsupr, TriTmp, &incx, &beta, MatvecTmp, &incy); +#endif +#else + dmatvec(nsupr, block_nrow, segsze, &lusup[luptr1], + TriTmp, MatvecTmp); +#endif + + /* Scatter MatvecTmp[*] into SPA dense[*] temporarily + * such that MatvecTmp[*] can be re-used for the + * the next blok row update. dense[] will be copied into + * global store after the whole panel has been finished. + */ + isub = isub1; + for (i = 0; i < block_nrow; i++) { + irow = lsub[isub]; + dense_col[irow] -= MatvecTmp[i]; + MatvecTmp[i] = zero; + ++isub; + } + + } /* for jj ... */ + + } /* for each block row ... */ + + /* Scatter the triangular solves into SPA dense[*] */ + repfnz_col = repfnz; + TriTmp = tempv; + dense_col = dense; + + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m, TriTmp += ldaTmp) { + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + if ( segsze <= 3 ) continue; /* skip unrolled cases */ + + no_zeros = kfnz - fsupc; + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + dense_col[irow] = TriTmp[i]; + TriTmp[i] = zero; + ++isub; + } + + } /* for jj ... */ + + } else { /* 1-D block modification */ + + + /* Sequence through each column in the panel */ + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m) { + + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + luptr = xlusup[fsupc]; + + ops[TRSV] += segsze * (segsze - 1); + ops[GEMV] += 2 * nrow * segsze; + + /* Case 1: Update U-segment of size 1 -- col-col update */ + if ( segsze == 1 ) { + ukj = dense_col[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc; + + for (i = lptr + nsupc; i < xlsub[fsupc+1]; i++) { + irow = lsub[i]; + dense_col[irow] -= ukj * lusup[luptr]; + ++luptr; + } + + } else if ( segsze <= 3 ) { + ukj = dense_col[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc-1; + ukj1 = dense_col[lsub[krep_ind - 1]]; + luptr1 = luptr - nsupr; + + if ( segsze == 2 ) { + ukj -= ukj1 * lusup[luptr1]; + dense_col[lsub[krep_ind]] = ukj; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + ++luptr; ++luptr1; + dense_col[irow] -= (ukj*lusup[luptr] + + ukj1*lusup[luptr1]); + } + } else { + ukj2 = dense_col[lsub[krep_ind - 2]]; + luptr2 = luptr1 - nsupr; + ukj1 -= ukj2 * lusup[luptr2-1]; + ukj = ukj - ukj1*lusup[luptr1] - ukj2*lusup[luptr2]; + dense_col[lsub[krep_ind]] = ukj; + dense_col[lsub[krep_ind-1]] = ukj1; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + ++luptr; ++luptr1; ++luptr2; + dense_col[irow] -= ( ukj*lusup[luptr] + + ukj1*lusup[luptr1] + ukj2*lusup[luptr2] ); + } + } + + } else { /* segsze >= 4 */ + /* + * Perform a triangular solve and block update, + * then scatter the result of sup-col update to dense[]. + */ + no_zeros = kfnz - fsupc; + + /* Copy U[*,j] segment from dense[*] to tempv[*]: + * The result of triangular solve is in tempv[*]; + * The result of matrix vector update is in dense_col[*] + */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; ++i) { + irow = lsub[isub]; + tempv[i] = dense_col[irow]; /* Gather */ + ++isub; + } + + /* start effective triangle */ + luptr += nsupr * no_zeros + no_zeros; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + STRSV( ftcs1, ftcs2, ftcs3, &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#else + dtrsv_( "L", "N", "U", &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#endif + + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + alpha = one; + beta = zero; +#ifdef _CRAY + SGEMV( ftcs2, &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#else + dgemv_( "N", &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#endif +#else + dlsolve ( nsupr, segsze, &lusup[luptr], tempv ); + + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + dmatvec (nsupr, nrow, segsze, &lusup[luptr], tempv, tempv1); +#endif + + /* Scatter tempv[*] into SPA dense[*] temporarily, such + * that tempv[*] can be used for the triangular solve of + * the next column of the panel. They will be copied into + * ucol[*] after the whole panel has been finished. + */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + dense_col[irow] = tempv[i]; + tempv[i] = zero; + isub++; + } + + /* Scatter the update from tempv1[*] into SPA dense[*] */ + /* Start dense rectangular L */ + for (i = 0; i < nrow; i++) { + irow = lsub[isub]; + dense_col[irow] -= tempv1[i]; + tempv1[i] = zero; + ++isub; + } + + } /* else segsze>=4 ... */ + + } /* for each column in the panel... */ + + } /* else 1-D update ... */ + + } /* for each updating supernode ... */ + +} + + + diff --git a/src/Libraries/superlu-5.2.1/SRC/dpanel_dfs.c b/src/Libraries/superlu-5.2.1/SRC/dpanel_dfs.c new file mode 100644 index 00000000..c1aa11ae --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dpanel_dfs.c @@ -0,0 +1,264 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dpanel_dfs.c + * \brief Peforms a symbolic factorization on a panel of symbols + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_ddefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *   Performs a symbolic factorization on a panel of columns [jcol, jcol+w).
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives.
+ *
+ *   The routine returns one list of the supernodal representatives
+ *   in topological order of the dfs that generates them. This list is
+ *   a superset of the topological order of each individual column within
+ *   the panel. 
+ *   The location of the first nonzero in each supernodal segment
+ *   (supernodal entry location) is also returned. Each column has a 
+ *   separate list for this purpose.
+ *
+ *   Two marker arrays are used for dfs:
+ *     marker[i] == jj, if i was visited during dfs of current column jj;
+ *     marker1[i] >= jcol, if i was visited by earlier columns in this panel;
+ *
+ *   marker: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ * 
+ */ + +void +dpanel_dfs ( + const int m, /* in - number of rows in the matrix */ + const int w, /* in */ + const int jcol, /* in */ + SuperMatrix *A, /* in - original matrix */ + int *perm_r, /* in */ + int *nseg, /* out */ + double *dense, /* out */ + int *panel_lsub, /* out */ + int *segrep, /* out */ + int *repfnz, /* out */ + int *xprune, /* out */ + int *marker, /* out */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ + ) +{ + + NCPformat *Astore; + double *a; + int *asub; + int *xa_begin, *xa_end; + int krep, chperm, chmark, chrep, oldrep, kchild, myfnz; + int k, krow, kmark, kperm; + int xdfs, maxdfs, kpar; + int jj; /* index through each column in the panel */ + int *marker1; /* marker1[jj] >= jcol if vertex jj was visited + by a previous column within this panel. */ + int *repfnz_col; /* start of each column in the panel */ + double *dense_col; /* start of each column in the panel */ + int nextl_col; /* next available position in panel_lsub[*,jj] */ + int *xsup, *supno; + int *lsub, *xlsub; + + /* Initialize pointers */ + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + marker1 = marker + m; + repfnz_col = repfnz; + dense_col = dense; + *nseg = 0; + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + + /* For each column in the panel */ + for (jj = jcol; jj < jcol + w; jj++) { + nextl_col = (jj - jcol) * m; + +#ifdef CHK_DFS + printf("\npanel col %d: ", jj); +#endif + + /* For each nonz in A[*,jj] do dfs */ + for (k = xa_begin[jj]; k < xa_end[jj]; k++) { + krow = asub[k]; + dense_col[krow] = a[k]; + kmark = marker[krow]; + if ( kmark == jj ) + continue; /* krow visited before, go to the next nonzero */ + + /* For each unmarked nbr krow of jj + * krow is in L: place it in structure of L[*,jj] + */ + marker[krow] = jj; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + panel_lsub[nextl_col++] = krow; /* krow is indexed into A */ + } + /* + * krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + else { + + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz_col[krep]; + +#ifdef CHK_DFS + printf("krep %d, myfnz %d, perm_r[%d] %d\n", krep, myfnz, krow, kperm); +#endif + if ( myfnz != EMPTY ) { /* Representative visited before */ + if ( myfnz > kperm ) repfnz_col[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz_col[krep] = kperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; + +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker[kchild]; + + if ( chmark != jj ) { /* Not reached yet */ + marker[kchild] = jj; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,j] */ + if ( chperm == EMPTY ) { + panel_lsub[nextl_col++] = kchild; + } + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + else { + + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz_col[chrep]; +#ifdef CHK_DFS + printf("chrep %d,myfnz %d,perm_r[%d] %d\n",chrep,myfnz,kchild,chperm); +#endif + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz_col[chrep] = chperm; + } + else { + /* Cont. dfs at snode-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L) */ + parent[krep] = oldrep; + repfnz_col[krep] = chperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } /* else */ + + } /* else */ + + } /* if... */ + + } /* while xdfs < maxdfs */ + + /* krow has no more unexplored nbrs: + * Place snode-rep krep in postorder DFS, if this + * segment is seen for the first time. (Note that + * "repfnz[krep]" may change later.) + * Backtrack dfs to its parent. + */ + if ( marker1[krep] < jcol ) { + segrep[*nseg] = krep; + ++(*nseg); + marker1[krep] = jj; + } + + kpar = parent[krep]; /* Pop stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xprune[krep]; + +#ifdef CHK_DFS + printf(" pop stack: krep %d,xdfs %d,maxdfs %d: ", krep,xdfs,maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } while ( kpar != EMPTY ); /* do-while - until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonz in A[*,jj] */ + + repfnz_col += m; /* Move to next column */ + dense_col += m; + + } /* for jj ... */ + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dpivotL.c b/src/Libraries/superlu-5.2.1/SRC/dpivotL.c new file mode 100644 index 00000000..e3fd651c --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dpivotL.c @@ -0,0 +1,194 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dpivotL.c + * \brief Performs numerical pivoting + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include +#include +#include "slu_ddefs.h" + +#undef DEBUG + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   Performs the numerical pivoting on the current column of L,
+ *   and the CDIV operation.
+ *
+ *   Pivot policy:
+ *   (1) Compute thresh = u * max_(i>=j) abs(A_ij);
+ *   (2) IF user specifies pivot row k and abs(A_kj) >= thresh THEN
+ *           pivot row = k;
+ *       ELSE IF abs(A_jj) >= thresh THEN
+ *           pivot row = j;
+ *       ELSE
+ *           pivot row = m;
+ * 
+ *   Note: If you absolutely want to use a given pivot order, then set u=0.0.
+ *
+ *   Return value: 0      success;
+ *                 i > 0  U(i,i) is exactly zero.
+ * 
+ */ + +int +dpivotL( + const int jcol, /* in */ + const double u, /* in - diagonal pivoting threshold */ + int *usepr, /* re-use the pivot sequence given by perm_r/iperm_r */ + int *perm_r, /* may be modified */ + int *iperm_r, /* in - inverse of perm_r */ + int *iperm_c, /* in - used to find diagonal of Pc*A*Pc' */ + int *pivrow, /* out */ + GlobalLU_t *Glu, /* modified - global LU data structures */ + SuperLUStat_t *stat /* output */ + ) +{ + + int fsupc; /* first column in the supernode */ + int nsupc; /* no of columns in the supernode */ + int nsupr; /* no of rows in the supernode */ + int lptr; /* points to the starting subscript of the supernode */ + int pivptr, old_pivptr, diag, diagind; + double pivmax, rtemp, thresh; + double temp; + double *lu_sup_ptr; + double *lu_col_ptr; + int *lsub_ptr; + int isub, icol, k, itemp; + int *lsub, *xlsub; + double *lusup; + int *xlusup; + flops_t *ops = stat->ops; + + /* Initialize pointers */ + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (double *) Glu->lusup; + xlusup = Glu->xlusup; + fsupc = (Glu->xsup)[(Glu->supno)[jcol]]; + nsupc = jcol - fsupc; /* excluding jcol; nsupc >= 0 */ + lptr = xlsub[fsupc]; + nsupr = xlsub[fsupc+1] - lptr; + lu_sup_ptr = &lusup[xlusup[fsupc]]; /* start of the current supernode */ + lu_col_ptr = &lusup[xlusup[jcol]]; /* start of jcol in the supernode */ + lsub_ptr = &lsub[lptr]; /* start of row indices of the supernode */ + +#ifdef DEBUG +if ( jcol == MIN_COL ) { + printf("Before cdiv: col %d\n", jcol); + for (k = nsupc; k < nsupr; k++) + printf(" lu[%d] %f\n", lsub_ptr[k], lu_col_ptr[k]); +} +#endif + + /* Determine the largest abs numerical value for partial pivoting; + Also search for user-specified pivot, and diagonal element. */ + if ( *usepr ) *pivrow = iperm_r[jcol]; + diagind = iperm_c[jcol]; + pivmax = 0.0; + pivptr = nsupc; + diag = EMPTY; + old_pivptr = nsupc; + for (isub = nsupc; isub < nsupr; ++isub) { + rtemp = fabs (lu_col_ptr[isub]); + if ( rtemp > pivmax ) { + pivmax = rtemp; + pivptr = isub; + } + if ( *usepr && lsub_ptr[isub] == *pivrow ) old_pivptr = isub; + if ( lsub_ptr[isub] == diagind ) diag = isub; + } + + /* Test for singularity */ + if ( pivmax == 0.0 ) { +#if 1 + *pivrow = lsub_ptr[pivptr]; + perm_r[*pivrow] = jcol; +#else + perm_r[diagind] = jcol; +#endif + *usepr = 0; + return (jcol+1); + } + + thresh = u * pivmax; + + /* Choose appropriate pivotal element by our policy. */ + if ( *usepr ) { + rtemp = fabs (lu_col_ptr[old_pivptr]); + if ( rtemp != 0.0 && rtemp >= thresh ) + pivptr = old_pivptr; + else + *usepr = 0; + } + if ( *usepr == 0 ) { + /* Use diagonal pivot? */ + if ( diag >= 0 ) { /* diagonal exists */ + rtemp = fabs (lu_col_ptr[diag]); + if ( rtemp != 0.0 && rtemp >= thresh ) pivptr = diag; + } + *pivrow = lsub_ptr[pivptr]; + } + + /* Record pivot row */ + perm_r[*pivrow] = jcol; + + /* Interchange row subscripts */ + if ( pivptr != nsupc ) { + itemp = lsub_ptr[pivptr]; + lsub_ptr[pivptr] = lsub_ptr[nsupc]; + lsub_ptr[nsupc] = itemp; + + /* Interchange numerical values as well, for the whole snode, such + * that L is indexed the same way as A. + */ + for (icol = 0; icol <= nsupc; icol++) { + itemp = pivptr + icol * nsupr; + temp = lu_sup_ptr[itemp]; + lu_sup_ptr[itemp] = lu_sup_ptr[nsupc + icol*nsupr]; + lu_sup_ptr[nsupc + icol*nsupr] = temp; + } + } /* if */ + + /* cdiv operation */ + ops[FACT] += nsupr - nsupc; + + temp = 1.0 / lu_col_ptr[nsupc]; + for (k = nsupc+1; k < nsupr; k++) + lu_col_ptr[k] *= temp; + + return 0; +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/dpivotgrowth.c b/src/Libraries/superlu-5.2.1/SRC/dpivotgrowth.c new file mode 100644 index 00000000..23293414 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dpivotgrowth.c @@ -0,0 +1,123 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dpivotgrowth.c + * \brief Computes the reciprocal pivot growth factor + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ */ +#include +#include "slu_ddefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * Compute the reciprocal pivot growth factor of the leading ncols columns
+ * of the matrix, using the formula:
+ *     min_j ( max_i(abs(A_ij)) / max_i(abs(U_ij)) )
+ *
+ * Arguments
+ * =========
+ *
+ * ncols    (input) int
+ *          The number of columns of matrices A, L and U.
+ *
+ * A        (input) SuperMatrix*
+ *	    Original matrix A, permuted by columns, of dimension
+ *          (A->nrow, A->ncol). The type of A can be:
+ *          Stype = NC; Dtype = SLU_D; Mtype = GE.
+ *
+ * L        (output) SuperMatrix*
+ *          The factor L from the factorization Pr*A=L*U; use compressed row 
+ *          subscripts storage for supernodes, i.e., L has type: 
+ *          Stype = SC; Dtype = SLU_D; Mtype = TRLU.
+ *
+ * U        (output) SuperMatrix*
+ *	    The factor U from the factorization Pr*A*Pc=L*U. Use column-wise
+ *          storage scheme, i.e., U has types: Stype = NC;
+ *          Dtype = SLU_D; Mtype = TRU.
+ * 
+ */ + +double +dPivotGrowth(int ncols, SuperMatrix *A, int *perm_c, + SuperMatrix *L, SuperMatrix *U) +{ + + NCformat *Astore; + SCformat *Lstore; + NCformat *Ustore; + double *Aval, *Lval, *Uval; + int fsupc, nsupr, luptr, nz_in_U; + int i, j, k, oldcol; + int *inv_perm_c; + double rpg, maxaj, maxuj; + double smlnum; + double *luval; + + /* Get machine constants. */ + smlnum = dmach("S"); + rpg = 1. / smlnum; + + Astore = A->Store; + Lstore = L->Store; + Ustore = U->Store; + Aval = Astore->nzval; + Lval = Lstore->nzval; + Uval = Ustore->nzval; + + inv_perm_c = (int *) SUPERLU_MALLOC(A->ncol*sizeof(int)); + for (j = 0; j < A->ncol; ++j) inv_perm_c[perm_c[j]] = j; + + for (k = 0; k <= Lstore->nsuper; ++k) { + fsupc = L_FST_SUPC(k); + nsupr = L_SUB_START(fsupc+1) - L_SUB_START(fsupc); + luptr = L_NZ_START(fsupc); + luval = &Lval[luptr]; + nz_in_U = 1; + + for (j = fsupc; j < L_FST_SUPC(k+1) && j < ncols; ++j) { + maxaj = 0.; + oldcol = inv_perm_c[j]; + for (i = Astore->colptr[oldcol]; i < Astore->colptr[oldcol+1]; ++i) + maxaj = SUPERLU_MAX( maxaj, fabs(Aval[i]) ); + + maxuj = 0.; + for (i = Ustore->colptr[j]; i < Ustore->colptr[j+1]; i++) + maxuj = SUPERLU_MAX( maxuj, fabs(Uval[i]) ); + + /* Supernode */ + for (i = 0; i < nz_in_U; ++i) + maxuj = SUPERLU_MAX( maxuj, fabs(luval[i]) ); + + ++nz_in_U; + luval += nsupr; + + if ( maxuj == 0. ) + rpg = SUPERLU_MIN( rpg, 1.); + else + rpg = SUPERLU_MIN( rpg, maxaj / maxuj ); + } + + if ( j >= ncols ) break; + } + + SUPERLU_FREE(inv_perm_c); + return (rpg); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dpruneL.c b/src/Libraries/superlu-5.2.1/SRC/dpruneL.c new file mode 100644 index 00000000..77d68e80 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dpruneL.c @@ -0,0 +1,164 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dpruneL.c + * \brief Prunes the L-structure + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ *
+ */ + + +#include "slu_ddefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   Prunes the L-structure of supernodes whose L-structure
+ *   contains the current pivot row "pivrow"
+ * 
+ */ + +void +dpruneL( + const int jcol, /* in */ + const int *perm_r, /* in */ + const int pivrow, /* in */ + const int nseg, /* in */ + const int *segrep, /* in */ + const int *repfnz, /* in */ + int *xprune, /* out */ + GlobalLU_t *Glu /* modified - global LU data structures */ + ) +{ + + double utemp; + int jsupno, irep, irep1, kmin, kmax, krow, movnum; + int i, ktemp, minloc, maxloc; + int do_prune; /* logical variable */ + int *xsup, *supno; + int *lsub, *xlsub; + double *lusup; + int *xlusup; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (double *) Glu->lusup; + xlusup = Glu->xlusup; + + /* + * For each supernode-rep irep in U[*,j] + */ + jsupno = supno[jcol]; + for (i = 0; i < nseg; i++) { + + irep = segrep[i]; + irep1 = irep + 1; + do_prune = FALSE; + + /* Don't prune with a zero U-segment */ + if ( repfnz[irep] == EMPTY ) + continue; + + /* If a snode overlaps with the next panel, then the U-segment + * is fragmented into two parts -- irep and irep1. We should let + * pruning occur at the rep-column in irep1's snode. + */ + if ( supno[irep] == supno[irep1] ) /* Don't prune */ + continue; + + /* + * If it has not been pruned & it has a nonz in row L[pivrow,i] + */ + if ( supno[irep] != jsupno ) { + if ( xprune[irep] >= xlsub[irep1] ) { + kmin = xlsub[irep]; + kmax = xlsub[irep1] - 1; + for (krow = kmin; krow <= kmax; krow++) + if ( lsub[krow] == pivrow ) { + do_prune = TRUE; + break; + } + } + + if ( do_prune ) { + + /* Do a quicksort-type partition + * movnum=TRUE means that the num values have to be exchanged. + */ + movnum = FALSE; + if ( irep == xsup[supno[irep]] ) /* Snode of size 1 */ + movnum = TRUE; + + while ( kmin <= kmax ) { + + if ( perm_r[lsub[kmax]] == EMPTY ) + kmax--; + else if ( perm_r[lsub[kmin]] != EMPTY ) + kmin++; + else { /* kmin below pivrow (not yet pivoted), and kmax + * above pivrow: interchange the two subscripts + */ + ktemp = lsub[kmin]; + lsub[kmin] = lsub[kmax]; + lsub[kmax] = ktemp; + + /* If the supernode has only one column, then we + * only keep one set of subscripts. For any subscript + * interchange performed, similar interchange must be + * done on the numerical values. + */ + if ( movnum ) { + minloc = xlusup[irep] + (kmin - xlsub[irep]); + maxloc = xlusup[irep] + (kmax - xlsub[irep]); + utemp = lusup[minloc]; + lusup[minloc] = lusup[maxloc]; + lusup[maxloc] = utemp; + } + + kmin++; + kmax--; + + } + + } /* while */ + + xprune[irep] = kmin; /* Pruning */ + +#ifdef CHK_PRUNE + printf(" After dpruneL(),using col %d: xprune[%d] = %d\n", + jcol, irep, kmin); +#endif + } /* if do_prune */ + + } /* if */ + + } /* for each U-segment... */ +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dreadhb.c b/src/Libraries/superlu-5.2.1/SRC/dreadhb.c new file mode 100644 index 00000000..a46bd99d --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dreadhb.c @@ -0,0 +1,369 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dreadhb.c + * \brief Read a matrix stored in Harwell-Boeing format + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Purpose
+ * =======
+ * 
+ * Read a DOUBLE PRECISION matrix stored in Harwell-Boeing format 
+ * as described below.
+ * 
+ * Line 1 (A72,A8) 
+ *  	Col. 1 - 72   Title (TITLE) 
+ *	Col. 73 - 80  Key (KEY) 
+ * 
+ * Line 2 (5I14) 
+ * 	Col. 1 - 14   Total number of lines excluding header (TOTCRD) 
+ * 	Col. 15 - 28  Number of lines for pointers (PTRCRD) 
+ * 	Col. 29 - 42  Number of lines for row (or variable) indices (INDCRD) 
+ * 	Col. 43 - 56  Number of lines for numerical values (VALCRD) 
+ *	Col. 57 - 70  Number of lines for right-hand sides (RHSCRD) 
+ *                    (including starting guesses and solution vectors 
+ *		       if present) 
+ *           	      (zero indicates no right-hand side data is present) 
+ *
+ * Line 3 (A3, 11X, 4I14) 
+ *   	Col. 1 - 3    Matrix type (see below) (MXTYPE) 
+ * 	Col. 15 - 28  Number of rows (or variables) (NROW) 
+ * 	Col. 29 - 42  Number of columns (or elements) (NCOL) 
+ *	Col. 43 - 56  Number of row (or variable) indices (NNZERO) 
+ *	              (equal to number of entries for assembled matrices) 
+ * 	Col. 57 - 70  Number of elemental matrix entries (NELTVL) 
+ *	              (zero in the case of assembled matrices) 
+ * Line 4 (2A16, 2A20) 
+ * 	Col. 1 - 16   Format for pointers (PTRFMT) 
+ *	Col. 17 - 32  Format for row (or variable) indices (INDFMT) 
+ *	Col. 33 - 52  Format for numerical values of coefficient matrix (VALFMT) 
+ * 	Col. 53 - 72 Format for numerical values of right-hand sides (RHSFMT) 
+ *
+ * Line 5 (A3, 11X, 2I14) Only present if there are right-hand sides present 
+ *    	Col. 1 	      Right-hand side type: 
+ *	         	  F for full storage or M for same format as matrix 
+ *    	Col. 2        G if a starting vector(s) (Guess) is supplied. (RHSTYP) 
+ *    	Col. 3        X if an exact solution vector(s) is supplied. 
+ *	Col. 15 - 28  Number of right-hand sides (NRHS) 
+ *	Col. 29 - 42  Number of row indices (NRHSIX) 
+ *          	      (ignored in case of unassembled matrices) 
+ *
+ * The three character type field on line 3 describes the matrix type. 
+ * The following table lists the permitted values for each of the three 
+ * characters. As an example of the type field, RSA denotes that the matrix 
+ * is real, symmetric, and assembled. 
+ *
+ * First Character: 
+ *	R Real matrix 
+ *	C Complex matrix 
+ *	P Pattern only (no numerical values supplied) 
+ *
+ * Second Character: 
+ *	S Symmetric 
+ *	U Unsymmetric 
+ *	H Hermitian 
+ *	Z Skew symmetric 
+ *	R Rectangular 
+ *
+ * Third Character: 
+ *	A Assembled 
+ *	E Elemental matrices (unassembled) 
+ *
+ * 
+ */ +#include +#include +#include "slu_ddefs.h" + + +/*! \brief Eat up the rest of the current line */ +int dDumpLine(FILE *fp) +{ + register int c; + while ((c = fgetc(fp)) != '\n') ; + return 0; +} + +int dParseIntFormat(char *buf, int *num, int *size) +{ + char *tmp; + + tmp = buf; + while (*tmp++ != '(') ; + sscanf(tmp, "%d", num); + while (*tmp != 'I' && *tmp != 'i') ++tmp; + ++tmp; + sscanf(tmp, "%d", size); + return 0; +} + +int dParseFloatFormat(char *buf, int *num, int *size) +{ + char *tmp, *period; + + tmp = buf; + while (*tmp++ != '(') ; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + while (*tmp != 'E' && *tmp != 'e' && *tmp != 'D' && *tmp != 'd' + && *tmp != 'F' && *tmp != 'f') { + /* May find kP before nE/nD/nF, like (1P6F13.6). In this case the + num picked up refers to P, which should be skipped. */ + if (*tmp=='p' || *tmp=='P') { + ++tmp; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + } else { + ++tmp; + } + } + ++tmp; + period = tmp; + while (*period != '.' && *period != ')') ++period ; + *period = '\0'; + *size = atoi(tmp); /*sscanf(tmp, "%2d", size);*/ + + return 0; +} + +static int ReadVector(FILE *fp, int n, int *where, int perline, int persize) +{ + register int i, j, item; + char tmp, buf[100]; + + i = 0; + while (i < n) { + fgets(buf, 100, fp); /* read a line at a time */ + for (j=0; j + * On input, nonz/nzval/rowind/colptr represents lower part of a symmetric + * matrix. On exit, it represents the full matrix with lower and upper parts. + * + */ +static void +FormFullA(int n, int *nonz, double **nzval, int **rowind, int **colptr) +{ + register int i, j, k, col, new_nnz; + int *t_rowind, *t_colptr, *al_rowind, *al_colptr, *a_rowind, *a_colptr; + int *marker; + double *t_val, *al_val, *a_val; + + al_rowind = *rowind; + al_colptr = *colptr; + al_val = *nzval; + + if ( !(marker =(int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for marker[]"); + if ( !(t_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC t_colptr[]"); + if ( !(t_rowind = (int *) SUPERLU_MALLOC( *nonz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for t_rowind[]"); + if ( !(t_val = (double*) SUPERLU_MALLOC( *nonz * sizeof(double)) ) ) + ABORT("SUPERLU_MALLOC fails for t_val[]"); + + /* Get counts of each column of T, and set up column pointers */ + for (i = 0; i < n; ++i) marker[i] = 0; + for (j = 0; j < n; ++j) { + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) + ++marker[al_rowind[i]]; + } + t_colptr[0] = 0; + for (i = 0; i < n; ++i) { + t_colptr[i+1] = t_colptr[i] + marker[i]; + marker[i] = t_colptr[i]; + } + + /* Transpose matrix A to T */ + for (j = 0; j < n; ++j) + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + col = al_rowind[i]; + t_rowind[marker[col]] = j; + t_val[marker[col]] = al_val[i]; + ++marker[col]; + } + + new_nnz = *nonz * 2 - n; + if ( !(a_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC a_colptr[]"); + if ( !(a_rowind = (int *) SUPERLU_MALLOC( new_nnz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for a_rowind[]"); + if ( !(a_val = (double*) SUPERLU_MALLOC( new_nnz * sizeof(double)) ) ) + ABORT("SUPERLU_MALLOC fails for a_val[]"); + + a_colptr[0] = 0; + k = 0; + for (j = 0; j < n; ++j) { + for (i = t_colptr[j]; i < t_colptr[j+1]; ++i) { + if ( t_rowind[i] != j ) { /* not diagonal */ + a_rowind[k] = t_rowind[i]; + a_val[k] = t_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + } + + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + a_rowind[k] = al_rowind[i]; + a_val[k] = al_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + + a_colptr[j+1] = k; + } + + printf("FormFullA: new_nnz = %d, k = %d\n", new_nnz, k); + + SUPERLU_FREE(al_val); + SUPERLU_FREE(al_rowind); + SUPERLU_FREE(al_colptr); + SUPERLU_FREE(marker); + SUPERLU_FREE(t_val); + SUPERLU_FREE(t_rowind); + SUPERLU_FREE(t_colptr); + + *nzval = a_val; + *rowind = a_rowind; + *colptr = a_colptr; + *nonz = new_nnz; +} + +void +dreadhb(FILE *fp, int *nrow, int *ncol, int *nonz, + double **nzval, int **rowind, int **colptr) +{ + + register int i, numer_lines = 0, rhscrd = 0; + int tmp, colnum, colsize, rownum, rowsize, valnum, valsize; + char buf[100], type[4], key[10]; + int sym; + + /* Line 1 */ + fgets(buf, 100, fp); + fputs(buf, stdout); +#if 0 + fscanf(fp, "%72c", buf); buf[72] = 0; + printf("Title: %s", buf); + fscanf(fp, "%8c", key); key[8] = 0; + printf("Key: %s\n", key); + dDumpLine(fp); +#endif + + /* Line 2 */ + for (i=0; i<5; i++) { + fscanf(fp, "%14c", buf); buf[14] = 0; + sscanf(buf, "%d", &tmp); + if (i == 3) numer_lines = tmp; + if (i == 4 && tmp) rhscrd = tmp; + } + dDumpLine(fp); + + /* Line 3 */ + fscanf(fp, "%3c", type); + fscanf(fp, "%11c", buf); /* pad */ + type[3] = 0; +#ifdef DEBUG + printf("Matrix type %s\n", type); +#endif + + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nrow); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", ncol); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nonz); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", &tmp); + + if (tmp != 0) + printf("This is not an assembled matrix!\n"); + if (*nrow != *ncol) + printf("Matrix is not square.\n"); + dDumpLine(fp); + + /* Allocate storage for the three arrays ( nzval, rowind, colptr ) */ + dallocateA(*ncol, *nonz, nzval, rowind, colptr); + + /* Line 4: format statement */ + fscanf(fp, "%16c", buf); + dParseIntFormat(buf, &colnum, &colsize); + fscanf(fp, "%16c", buf); + dParseIntFormat(buf, &rownum, &rowsize); + fscanf(fp, "%20c", buf); + dParseFloatFormat(buf, &valnum, &valsize); + fscanf(fp, "%20c", buf); + dDumpLine(fp); + + /* Line 5: right-hand side */ + if ( rhscrd ) dDumpLine(fp); /* skip RHSFMT */ + +#ifdef DEBUG + printf("%d rows, %d nonzeros\n", *nrow, *nonz); + printf("colnum %d, colsize %d\n", colnum, colsize); + printf("rownum %d, rowsize %d\n", rownum, rowsize); + printf("valnum %d, valsize %d\n", valnum, valsize); +#endif + + ReadVector(fp, *ncol+1, *colptr, colnum, colsize); + ReadVector(fp, *nonz, *rowind, rownum, rowsize); + if ( numer_lines ) { + dReadValues(fp, *nonz, *nzval, valnum, valsize); + } + + sym = (type[1] == 'S' || type[1] == 's'); + if ( sym ) { + FormFullA(*ncol, nonz, nzval, rowind, colptr); + } + + fclose(fp); +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/dreadrb.c b/src/Libraries/superlu-5.2.1/SRC/dreadrb.c new file mode 100644 index 00000000..1270dc7c --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dreadrb.c @@ -0,0 +1,356 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dreadrb.c + * \brief Read a matrix stored in Rutherford-Boeing format + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ * + * Purpose + * ======= + * + * Read a DOUBLE PRECISION matrix stored in Rutherford-Boeing format + * as described below. + * + * Line 1 (A72, A8) + * Col. 1 - 72 Title (TITLE) + * Col. 73 - 80 Matrix name / identifier (MTRXID) + * + * Line 2 (I14, 3(1X, I13)) + * Col. 1 - 14 Total number of lines excluding header (TOTCRD) + * Col. 16 - 28 Number of lines for pointers (PTRCRD) + * Col. 30 - 42 Number of lines for row (or variable) indices (INDCRD) + * Col. 44 - 56 Number of lines for numerical values (VALCRD) + * + * Line 3 (A3, 11X, 4(1X, I13)) + * Col. 1 - 3 Matrix type (see below) (MXTYPE) + * Col. 15 - 28 Compressed Column: Number of rows (NROW) + * Elemental: Largest integer used to index variable (MVAR) + * Col. 30 - 42 Compressed Column: Number of columns (NCOL) + * Elemental: Number of element matrices (NELT) + * Col. 44 - 56 Compressed Column: Number of entries (NNZERO) + * Elemental: Number of variable indeces (NVARIX) + * Col. 58 - 70 Compressed Column: Unused, explicitly zero + * Elemental: Number of elemental matrix entries (NELTVL) + * + * Line 4 (2A16, A20) + * Col. 1 - 16 Fortran format for pointers (PTRFMT) + * Col. 17 - 32 Fortran format for row (or variable) indices (INDFMT) + * Col. 33 - 52 Fortran format for numerical values of coefficient matrix + * (VALFMT) + * (blank in the case of matrix patterns) + * + * The three character type field on line 3 describes the matrix type. + * The following table lists the permitted values for each of the three + * characters. As an example of the type field, RSA denotes that the matrix + * is real, symmetric, and assembled. + * + * First Character: + * R Real matrix + * C Complex matrix + * I integer matrix + * P Pattern only (no numerical values supplied) + * Q Pattern only (numerical values supplied in associated auxiliary value + * file) + * + * Second Character: + * S Symmetric + * U Unsymmetric + * H Hermitian + * Z Skew symmetric + * R Rectangular + * + * Third Character: + * A Compressed column form + * E Elemental form + * + * + */ + +#include +#include +#include "slu_ddefs.h" + + +/*! \brief Eat up the rest of the current line */ +static int dDumpLine(FILE *fp) +{ + register int c; + while ((c = fgetc(fp)) != '\n') ; + return 0; +} + +static int dParseIntFormat(char *buf, int *num, int *size) +{ + char *tmp; + + tmp = buf; + while (*tmp++ != '(') ; + sscanf(tmp, "%d", num); + while (*tmp != 'I' && *tmp != 'i') ++tmp; + ++tmp; + sscanf(tmp, "%d", size); + return 0; +} + +static int dParseFloatFormat(char *buf, int *num, int *size) +{ + char *tmp, *period; + + tmp = buf; + while (*tmp++ != '(') ; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + while (*tmp != 'E' && *tmp != 'e' && *tmp != 'D' && *tmp != 'd' + && *tmp != 'F' && *tmp != 'f') { + /* May find kP before nE/nD/nF, like (1P6F13.6). In this case the + num picked up refers to P, which should be skipped. */ + if (*tmp=='p' || *tmp=='P') { + ++tmp; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + } else { + ++tmp; + } + } + ++tmp; + period = tmp; + while (*period != '.' && *period != ')') ++period ; + *period = '\0'; + *size = atoi(tmp); /*sscanf(tmp, "%2d", size);*/ + + return 0; +} + +static int ReadVector(FILE *fp, int n, int *where, int perline, int persize) +{ + register int i, j, item; + char tmp, buf[100]; + + i = 0; + while (i < n) { + fgets(buf, 100, fp); /* read a line at a time */ + for (j=0; j + * On input, nonz/nzval/rowind/colptr represents lower part of a symmetric + * matrix. On exit, it represents the full matrix with lower and upper parts. + * + */ +static void +FormFullA(int n, int *nonz, double **nzval, int **rowind, int **colptr) +{ + register int i, j, k, col, new_nnz; + int *t_rowind, *t_colptr, *al_rowind, *al_colptr, *a_rowind, *a_colptr; + int *marker; + double *t_val, *al_val, *a_val; + + al_rowind = *rowind; + al_colptr = *colptr; + al_val = *nzval; + + if ( !(marker =(int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for marker[]"); + if ( !(t_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC t_colptr[]"); + if ( !(t_rowind = (int *) SUPERLU_MALLOC( *nonz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for t_rowind[]"); + if ( !(t_val = (double*) SUPERLU_MALLOC( *nonz * sizeof(double)) ) ) + ABORT("SUPERLU_MALLOC fails for t_val[]"); + + /* Get counts of each column of T, and set up column pointers */ + for (i = 0; i < n; ++i) marker[i] = 0; + for (j = 0; j < n; ++j) { + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) + ++marker[al_rowind[i]]; + } + t_colptr[0] = 0; + for (i = 0; i < n; ++i) { + t_colptr[i+1] = t_colptr[i] + marker[i]; + marker[i] = t_colptr[i]; + } + + /* Transpose matrix A to T */ + for (j = 0; j < n; ++j) + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + col = al_rowind[i]; + t_rowind[marker[col]] = j; + t_val[marker[col]] = al_val[i]; + ++marker[col]; + } + + new_nnz = *nonz * 2 - n; + if ( !(a_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC a_colptr[]"); + if ( !(a_rowind = (int *) SUPERLU_MALLOC( new_nnz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for a_rowind[]"); + if ( !(a_val = (double*) SUPERLU_MALLOC( new_nnz * sizeof(double)) ) ) + ABORT("SUPERLU_MALLOC fails for a_val[]"); + + a_colptr[0] = 0; + k = 0; + for (j = 0; j < n; ++j) { + for (i = t_colptr[j]; i < t_colptr[j+1]; ++i) { + if ( t_rowind[i] != j ) { /* not diagonal */ + a_rowind[k] = t_rowind[i]; + a_val[k] = t_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + } + + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + a_rowind[k] = al_rowind[i]; + a_val[k] = al_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + + a_colptr[j+1] = k; + } + + printf("FormFullA: new_nnz = %d, k = %d\n", new_nnz, k); + + SUPERLU_FREE(al_val); + SUPERLU_FREE(al_rowind); + SUPERLU_FREE(al_colptr); + SUPERLU_FREE(marker); + SUPERLU_FREE(t_val); + SUPERLU_FREE(t_rowind); + SUPERLU_FREE(t_colptr); + + *nzval = a_val; + *rowind = a_rowind; + *colptr = a_colptr; + *nonz = new_nnz; +} + +void +dreadrb(int *nrow, int *ncol, int *nonz, + double **nzval, int **rowind, int **colptr) +{ + + register int i, numer_lines = 0; + int tmp, colnum, colsize, rownum, rowsize, valnum, valsize; + char buf[100], type[4]; + int sym; + FILE *fp; + + fp = stdin; + + /* Line 1 */ + fgets(buf, 100, fp); + fputs(buf, stdout); + + /* Line 2 */ + for (i=0; i<4; i++) { + fscanf(fp, "%14c", buf); buf[14] = 0; + sscanf(buf, "%d", &tmp); + if (i == 3) numer_lines = tmp; + } + dDumpLine(fp); + + /* Line 3 */ + fscanf(fp, "%3c", type); + fscanf(fp, "%11c", buf); /* pad */ + type[3] = 0; +#ifdef DEBUG + printf("Matrix type %s\n", type); +#endif + + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nrow); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", ncol); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nonz); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", &tmp); + + if (tmp != 0) + printf("This is not an assembled matrix!\n"); + if (*nrow != *ncol) + printf("Matrix is not square.\n"); + dDumpLine(fp); + + /* Allocate storage for the three arrays ( nzval, rowind, colptr ) */ + dallocateA(*ncol, *nonz, nzval, rowind, colptr); + + /* Line 4: format statement */ + fscanf(fp, "%16c", buf); + dParseIntFormat(buf, &colnum, &colsize); + fscanf(fp, "%16c", buf); + dParseIntFormat(buf, &rownum, &rowsize); + fscanf(fp, "%20c", buf); + dParseFloatFormat(buf, &valnum, &valsize); + dDumpLine(fp); + +#ifdef DEBUG + printf("%d rows, %d nonzeros\n", *nrow, *nonz); + printf("colnum %d, colsize %d\n", colnum, colsize); + printf("rownum %d, rowsize %d\n", rownum, rowsize); + printf("valnum %d, valsize %d\n", valnum, valsize); +#endif + + ReadVector(fp, *ncol+1, *colptr, colnum, colsize); + ReadVector(fp, *nonz, *rowind, rownum, rowsize); + if ( numer_lines ) { + dReadValues(fp, *nonz, *nzval, valnum, valsize); + } + + sym = (type[1] == 'S' || type[1] == 's'); + if ( sym ) { + FormFullA(*ncol, nonz, nzval, rowind, colptr); + } + + fclose(fp); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dreadtriple.c b/src/Libraries/superlu-5.2.1/SRC/dreadtriple.c new file mode 100644 index 00000000..3e2451f2 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dreadtriple.c @@ -0,0 +1,150 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dreadtriple.c + * \brief Read a matrix stored in triplet (coordinate) format + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ + +#include "slu_ddefs.h" + + +void +dreadtriple(int *m, int *n, int *nonz, + double **nzval, int **rowind, int **colptr) +{ +/* + * Output parameters + * ================= + * (a,asub,xa): asub[*] contains the row subscripts of nonzeros + * in columns of matrix A; a[*] the numerical values; + * row i of A is given by a[k],k=xa[i],...,xa[i+1]-1. + * + */ + int j, k, jsize, nnz, nz; + double *a, *val; + int *asub, *xa, *row, *col; + int zero_base = 0; + + /* Matrix format: + * First line: #rows, #cols, #non-zero + * Triplet in the rest of lines: + * row, col, value + */ + + scanf("%d%d", n, nonz); + *m = *n; + printf("m %d, n %d, nonz %d\n", *m, *n, *nonz); + dallocateA(*n, *nonz, nzval, rowind, colptr); /* Allocate storage */ + a = *nzval; + asub = *rowind; + xa = *colptr; + + val = (double *) SUPERLU_MALLOC(*nonz * sizeof(double)); + row = (int *) SUPERLU_MALLOC(*nonz * sizeof(int)); + col = (int *) SUPERLU_MALLOC(*nonz * sizeof(int)); + + for (j = 0; j < *n; ++j) xa[j] = 0; + + /* Read into the triplet array from a file */ + for (nnz = 0, nz = 0; nnz < *nonz; ++nnz) { + scanf("%d%d%lf\n", &row[nz], &col[nz], &val[nz]); + + if ( nnz == 0 ) { /* first nonzero */ + if ( row[0] == 0 || col[0] == 0 ) { + zero_base = 1; + printf("triplet file: row/col indices are zero-based.\n"); + } else + printf("triplet file: row/col indices are one-based.\n"); + } + + if ( !zero_base ) { + /* Change to 0-based indexing. */ + --row[nz]; + --col[nz]; + } + + if (row[nz] < 0 || row[nz] >= *m || col[nz] < 0 || col[nz] >= *n + /*|| val[nz] == 0.*/) { + fprintf(stderr, "nz %d, (%d, %d) = %e out of bound, removed\n", + nz, row[nz], col[nz], val[nz]); + exit(-1); + } else { + ++xa[col[nz]]; + ++nz; + } + } + + *nonz = nz; + + /* Initialize the array of column pointers */ + k = 0; + jsize = xa[0]; + xa[0] = 0; + for (j = 1; j < *n; ++j) { + k += jsize; + jsize = xa[j]; + xa[j] = k; + } + + /* Copy the triplets into the column oriented storage */ + for (nz = 0; nz < *nonz; ++nz) { + j = col[nz]; + k = xa[j]; + asub[k] = row[nz]; + a[k] = val[nz]; + ++xa[j]; + } + + /* Reset the column pointers to the beginning of each column */ + for (j = *n; j > 0; --j) + xa[j] = xa[j-1]; + xa[0] = 0; + + SUPERLU_FREE(val); + SUPERLU_FREE(row); + SUPERLU_FREE(col); + +#ifdef CHK_INPUT + { + int i; + for (i = 0; i < *n; i++) { + printf("Col %d, xa %d\n", i, xa[i]); + for (k = xa[i]; k < xa[i+1]; k++) + printf("%d\t%16.10f\n", asub[k], a[k]); + } + } +#endif + +} + + +void dreadrhs(int m, double *b) +{ + FILE *fp, *fopen(); + int i; + /*int j;*/ + + if ( !(fp = fopen("b.dat", "r")) ) { + fprintf(stderr, "dreadrhs: file does not exist\n"); + exit(-1); + } + for (i = 0; i < m; ++i) + fscanf(fp, "%lf\n", &b[i]); + + /* readpair_(j, &b[i]);*/ + fclose(fp); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dsnode_bmod.c b/src/Libraries/superlu-5.2.1/SRC/dsnode_bmod.c new file mode 100644 index 00000000..b4a8b8b7 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dsnode_bmod.c @@ -0,0 +1,128 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dsnode_bmod.c + * \brief Performs numeric block updates within the relaxed snode. + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_ddefs.h" + + +/*! \brief Performs numeric block updates within the relaxed snode. + */ +int +dsnode_bmod ( + const int jcol, /* in */ + const int jsupno, /* in */ + const int fsupc, /* in */ + double *dense, /* in */ + double *tempv, /* working array */ + GlobalLU_t *Glu, /* modified */ + SuperLUStat_t *stat /* output */ + ) +{ +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + int incx = 1, incy = 1; + double alpha = -1.0, beta = 1.0; +#endif + + int luptr, nsupc, nsupr, nrow; + int isub, irow, i, iptr; + register int ufirst, nextlu; + int *lsub, *xlsub; + double *lusup; + int *xlusup; + flops_t *ops = stat->ops; + + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (double *) Glu->lusup; + xlusup = Glu->xlusup; + + nextlu = xlusup[jcol]; + + /* + * Process the supernodal portion of L\U[*,j] + */ + for (isub = xlsub[fsupc]; isub < xlsub[fsupc+1]; isub++) { + irow = lsub[isub]; + lusup[nextlu] = dense[irow]; + dense[irow] = 0; + ++nextlu; + } + + xlusup[jcol + 1] = nextlu; /* Initialize xlusup for next column */ + + if ( fsupc < jcol ) { + + luptr = xlusup[fsupc]; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; + nsupc = jcol - fsupc; /* Excluding jcol */ + ufirst = xlusup[jcol]; /* Points to the beginning of column + jcol in supernode L\U(jsupno). */ + nrow = nsupr - nsupc; + + ops[TRSV] += nsupc * (nsupc - 1); + ops[GEMV] += 2 * nrow * nsupc; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + STRSV( ftcs1, ftcs2, ftcs3, &nsupc, &lusup[luptr], &nsupr, + &lusup[ufirst], &incx ); + SGEMV( ftcs2, &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#else + dtrsv_( "L", "N", "U", &nsupc, &lusup[luptr], &nsupr, + &lusup[ufirst], &incx ); + dgemv_( "N", &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#endif +#else + dlsolve ( nsupr, nsupc, &lusup[luptr], &lusup[ufirst] ); + dmatvec ( nsupr, nrow, nsupc, &lusup[luptr+nsupc], + &lusup[ufirst], &tempv[0] ); + + /* Scatter tempv[*] into lusup[*] */ + iptr = ufirst + nsupc; + for (i = 0; i < nrow; i++) { + lusup[iptr++] -= tempv[i]; + tempv[i] = 0.0; + } +#endif + + } + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dsnode_dfs.c b/src/Libraries/superlu-5.2.1/SRC/dsnode_dfs.c new file mode 100644 index 00000000..155f42f0 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dsnode_dfs.c @@ -0,0 +1,122 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dsnode_dfs.c + * \brief Determines the union of row structures of columns within the relaxed node + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_ddefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *    dsnode_dfs() - Determine the union of the row structures of those 
+ *    columns within the relaxed snode.
+ *    Note: The relaxed snodes are leaves of the supernodal etree, therefore, 
+ *    the portion outside the rectangular supernode must be zero.
+ *
+ * Return value
+ * ============
+ *     0   success;
+ *    >0   number of bytes allocated when run out of memory.
+ * 
+ */ + +int +dsnode_dfs ( + const int jcol, /* in - start of the supernode */ + const int kcol, /* in - end of the supernode */ + const int *asub, /* in */ + const int *xa_begin, /* in */ + const int *xa_end, /* in */ + int *xprune, /* out */ + int *marker, /* modified */ + GlobalLU_t *Glu /* modified */ + ) +{ + + register int i, k, ifrom, ito, nextl, new_next; + int nsuper, krow, kmark, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + int nzlmax; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + nsuper = ++supno[jcol]; /* Next available supernode number */ + nextl = xlsub[jcol]; + + for (i = jcol; i <= kcol; i++) { + /* For each nonzero in A[*,i] */ + for (k = xa_begin[i]; k < xa_end[i]; k++) { + krow = asub[k]; + kmark = marker[krow]; + if ( kmark != kcol ) { /* First time visit krow */ + marker[krow] = kcol; + lsub[nextl++] = krow; + if ( nextl >= nzlmax ) { + if ( mem_error = dLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + } + } + supno[i] = nsuper; + } + + /* Supernode > 1, then make a copy of the subscripts for pruning */ + if ( jcol < kcol ) { + new_next = nextl + (nextl - xlsub[jcol]); + while ( new_next > nzlmax ) { + if ( mem_error = dLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + ito = nextl; + for (ifrom = xlsub[jcol]; ifrom < nextl; ) + lsub[ito++] = lsub[ifrom++]; + for (i = jcol+1; i <= kcol; i++) xlsub[i] = nextl; + nextl = ito; + } + + xsup[nsuper+1] = kcol + 1; + supno[kcol+1] = nsuper; + xprune[kcol] = nextl; + xlsub[kcol+1] = nextl; + + return 0; +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/dsp_blas2.c b/src/Libraries/superlu-5.2.1/SRC/dsp_blas2.c new file mode 100644 index 00000000..4b632d34 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dsp_blas2.c @@ -0,0 +1,490 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dsp_blas2.c + * \brief Sparse BLAS 2, using some dense BLAS 2 operations + * + *
+ * -- SuperLU routine (version 5.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Last update: December 3, 2015
+ * 
+ */ +/* + * File name: dsp_blas2.c + * Purpose: Sparse BLAS 2, using some dense BLAS 2 operations. + */ + +#include "slu_ddefs.h" + +/* + * Function prototypes + */ +void dusolve(int, int, double*, double*); +void dlsolve(int, int, double*, double*); +void dmatvec(int, int, int, double*, double*, double*); + +/*! \brief Solves one of the systems of equations A*x = b, or A'*x = b + * + *
+ *   Purpose
+ *   =======
+ *
+ *   sp_dtrsv() solves one of the systems of equations   
+ *       A*x = b,   or   A'*x = b,
+ *   where b and x are n element vectors and A is a sparse unit , or   
+ *   non-unit, upper or lower triangular matrix.   
+ *   No test for singularity or near-singularity is included in this   
+ *   routine. Such tests must be performed before calling this routine.   
+ *
+ *   Parameters   
+ *   ==========   
+ *
+ *   uplo   - (input) char*
+ *            On entry, uplo specifies whether the matrix is an upper or   
+ *             lower triangular matrix as follows:   
+ *                uplo = 'U' or 'u'   A is an upper triangular matrix.   
+ *                uplo = 'L' or 'l'   A is a lower triangular matrix.   
+ *
+ *   trans  - (input) char*
+ *             On entry, trans specifies the equations to be solved as   
+ *             follows:   
+ *                trans = 'N' or 'n'   A*x = b.   
+ *                trans = 'T' or 't'   A'*x = b.
+ *                trans = 'C' or 'c'   A'*x = b.   
+ *
+ *   diag   - (input) char*
+ *             On entry, diag specifies whether or not A is unit   
+ *             triangular as follows:   
+ *                diag = 'U' or 'u'   A is assumed to be unit triangular.   
+ *                diag = 'N' or 'n'   A is not assumed to be unit   
+ *                                    triangular.   
+ *	     
+ *   L       - (input) SuperMatrix*
+ *	       The factor L from the factorization Pr*A*Pc=L*U. Use
+ *             compressed row subscripts storage for supernodes,
+ *             i.e., L has types: Stype = SC, Dtype = SLU_D, Mtype = TRLU.
+ *
+ *   U       - (input) SuperMatrix*
+ *	        The factor U from the factorization Pr*A*Pc=L*U.
+ *	        U has types: Stype = NC, Dtype = SLU_D, Mtype = TRU.
+ *    
+ *   x       - (input/output) double*
+ *             Before entry, the incremented array X must contain the n   
+ *             element right-hand side vector b. On exit, X is overwritten 
+ *             with the solution vector x.
+ *
+ *   info    - (output) int*
+ *             If *info = -i, the i-th argument had an illegal value.
+ * 
+ */ +int +sp_dtrsv(char *uplo, char *trans, char *diag, SuperMatrix *L, + SuperMatrix *U, double *x, SuperLUStat_t *stat, int *info) +{ +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + SCformat *Lstore; + NCformat *Ustore; + double *Lval, *Uval; + int incx = 1, incy = 1; + double alpha = 1.0, beta = 1.0; + int nrow; + int fsupc, nsupr, nsupc, luptr, istart, irow; + int i, k, iptr, jcol; + double *work; + flops_t solve_ops; + + /* Test the input parameters */ + *info = 0; + if ( strncmp(uplo,"L", 1)!=0 && strncmp(uplo, "U", 1)!=0 ) *info = -1; + else if ( strncmp(trans, "N", 1)!=0 && strncmp(trans, "T", 1)!=0 && + strncmp(trans, "C", 1)!=0) *info = -2; + else if ( strncmp(diag, "U", 1)!=0 && strncmp(diag, "N", 1)!=0 ) + *info = -3; + else if ( L->nrow != L->ncol || L->nrow < 0 ) *info = -4; + else if ( U->nrow != U->ncol || U->nrow < 0 ) *info = -5; + if ( *info ) { + i = -(*info); + input_error("sp_dtrsv", &i); + return 0; + } + + Lstore = L->Store; + Lval = Lstore->nzval; + Ustore = U->Store; + Uval = Ustore->nzval; + solve_ops = 0; + + if ( !(work = doubleCalloc(L->nrow)) ) + ABORT("Malloc fails for work in sp_dtrsv()."); + + if ( strncmp(trans, "N", 1)==0 ) { /* Form x := inv(A)*x. */ + + if ( strncmp(uplo, "L", 1)==0 ) { + /* Form x := inv(L)*x */ + if ( L->nrow == 0 ) return 0; /* Quick return */ + + for (k = 0; k <= Lstore->nsuper; k++) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + nrow = nsupr - nsupc; + + solve_ops += nsupc * (nsupc - 1); + solve_ops += 2 * nrow * nsupc; + + if ( nsupc == 1 ) { + for (iptr=istart+1; iptr < L_SUB_START(fsupc+1); ++iptr) { + irow = L_SUB(iptr); + ++luptr; + x[irow] -= x[fsupc] * Lval[luptr]; + } + } else { +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + STRSV(ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); + + SGEMV(ftcs2, &nrow, &nsupc, &alpha, &Lval[luptr+nsupc], + &nsupr, &x[fsupc], &incx, &beta, &work[0], &incy); +#else + dtrsv_("L", "N", "U", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); + + dgemv_("N", &nrow, &nsupc, &alpha, &Lval[luptr+nsupc], + &nsupr, &x[fsupc], &incx, &beta, &work[0], &incy); +#endif +#else + dlsolve ( nsupr, nsupc, &Lval[luptr], &x[fsupc]); + + dmatvec ( nsupr, nsupr-nsupc, nsupc, &Lval[luptr+nsupc], + &x[fsupc], &work[0] ); +#endif + + iptr = istart + nsupc; + for (i = 0; i < nrow; ++i, ++iptr) { + irow = L_SUB(iptr); + x[irow] -= work[i]; /* Scatter */ + work[i] = 0.0; + + } + } + } /* for k ... */ + + } else { + /* Form x := inv(U)*x */ + + if ( U->nrow == 0 ) return 0; /* Quick return */ + + for (k = Lstore->nsuper; k >= 0; k--) { + fsupc = L_FST_SUPC(k); + nsupr = L_SUB_START(fsupc+1) - L_SUB_START(fsupc); + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + solve_ops += nsupc * (nsupc + 1); + + if ( nsupc == 1 ) { + x[fsupc] /= Lval[luptr]; + for (i = U_NZ_START(fsupc); i < U_NZ_START(fsupc+1); ++i) { + irow = U_SUB(i); + x[irow] -= x[fsupc] * Uval[i]; + } + } else { +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + STRSV(ftcs3, ftcs2, ftcs2, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + dtrsv_("U", "N", "N", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif +#else + dusolve ( nsupr, nsupc, &Lval[luptr], &x[fsupc] ); +#endif + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + solve_ops += 2*(U_NZ_START(jcol+1) - U_NZ_START(jcol)); + for (i = U_NZ_START(jcol); i < U_NZ_START(jcol+1); + i++) { + irow = U_SUB(i); + x[irow] -= x[jcol] * Uval[i]; + } + } + } + } /* for k ... */ + + } + } else { /* Form x := inv(A')*x */ + + if ( strncmp(uplo, "L", 1)==0 ) { + /* Form x := inv(L')*x */ + if ( L->nrow == 0 ) return 0; /* Quick return */ + + for (k = Lstore->nsuper; k >= 0; --k) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + solve_ops += 2 * (nsupr - nsupc) * nsupc; + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + iptr = istart + nsupc; + for (i = L_NZ_START(jcol) + nsupc; + i < L_NZ_START(jcol+1); i++) { + irow = L_SUB(iptr); + x[jcol] -= x[irow] * Lval[i]; + iptr++; + } + } + + if ( nsupc > 1 ) { + solve_ops += nsupc * (nsupc - 1); +#ifdef _CRAY + ftcs1 = _cptofcd("L", strlen("L")); + ftcs2 = _cptofcd("T", strlen("T")); + ftcs3 = _cptofcd("U", strlen("U")); + STRSV(ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + dtrsv_("L", "T", "U", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif + } + } + } else { + /* Form x := inv(U')*x */ + if ( U->nrow == 0 ) return 0; /* Quick return */ + + for (k = 0; k <= Lstore->nsuper; k++) { + fsupc = L_FST_SUPC(k); + nsupr = L_SUB_START(fsupc+1) - L_SUB_START(fsupc); + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + solve_ops += 2*(U_NZ_START(jcol+1) - U_NZ_START(jcol)); + for (i = U_NZ_START(jcol); i < U_NZ_START(jcol+1); i++) { + irow = U_SUB(i); + x[jcol] -= x[irow] * Uval[i]; + } + } + + solve_ops += nsupc * (nsupc + 1); + + if ( nsupc == 1 ) { + x[fsupc] /= Lval[luptr]; + } else { +#ifdef _CRAY + ftcs1 = _cptofcd("U", strlen("U")); + ftcs2 = _cptofcd("T", strlen("T")); + ftcs3 = _cptofcd("N", strlen("N")); + STRSV( ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + dtrsv_("U", "T", "N", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif + } + } /* for k ... */ + } + } + + stat->ops[SOLVE] += solve_ops; + SUPERLU_FREE(work); + return 0; +} + + + +/*! \brief Performs one of the matrix-vector operations y := alpha*A*x + beta*y, or y := alpha*A'*x + beta*y, + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   sp_dgemv()  performs one of the matrix-vector operations   
+ *      y := alpha*A*x + beta*y,   or   y := alpha*A'*x + beta*y,   
+ *   where alpha and beta are scalars, x and y are vectors and A is a
+ *   sparse A->nrow by A->ncol matrix.   
+ *
+ *   Parameters   
+ *   ==========   
+ *
+ *   TRANS  - (input) char*
+ *            On entry, TRANS specifies the operation to be performed as   
+ *            follows:   
+ *               TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.   
+ *               TRANS = 'T' or 't'   y := alpha*A'*x + beta*y.   
+ *               TRANS = 'C' or 'c'   y := alpha*A'*x + beta*y.   
+ *
+ *   ALPHA  - (input) double
+ *            On entry, ALPHA specifies the scalar alpha.   
+ *
+ *   A      - (input) SuperMatrix*
+ *            Matrix A with a sparse format, of dimension (A->nrow, A->ncol).
+ *            Currently, the type of A can be:
+ *                Stype = NC or NCP; Dtype = SLU_D; Mtype = GE. 
+ *            In the future, more general A can be handled.
+ *
+ *   X      - (input) double*, array of DIMENSION at least   
+ *            ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'   
+ *            and at least   
+ *            ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.   
+ *            Before entry, the incremented array X must contain the   
+ *            vector x.   
+ *
+ *   INCX   - (input) int
+ *            On entry, INCX specifies the increment for the elements of   
+ *            X. INCX must not be zero.   
+ *
+ *   BETA   - (input) double
+ *            On entry, BETA specifies the scalar beta. When BETA is   
+ *            supplied as zero then Y need not be set on input.   
+ *
+ *   Y      - (output) double*,  array of DIMENSION at least   
+ *            ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'   
+ *            and at least   
+ *            ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.   
+ *            Before entry with BETA non-zero, the incremented array Y   
+ *            must contain the vector y. On exit, Y is overwritten by the 
+ *            updated vector y.
+ *	     
+ *   INCY   - (input) int
+ *            On entry, INCY specifies the increment for the elements of   
+ *            Y. INCY must not be zero.   
+ *
+ *   ==== Sparse Level 2 Blas routine.   
+ * 
+ */ + +int +sp_dgemv(char *trans, double alpha, SuperMatrix *A, double *x, + int incx, double beta, double *y, int incy) +{ + /* Local variables */ + NCformat *Astore; + double *Aval; + int info; + double temp; + int lenx, leny, i, j, irow; + int iy, jx, jy, kx, ky; + int notran; + + notran = ( strncmp(trans, "N", 1)==0 || strncmp(trans, "n", 1)==0 ); + Astore = A->Store; + Aval = Astore->nzval; + + /* Test the input parameters */ + info = 0; + if ( !notran && strncmp(trans, "T", 1)!=0 && strncmp(trans, "C", 1)!=0 ) + info = 1; + else if ( A->nrow < 0 || A->ncol < 0 ) info = 3; + else if (incx == 0) info = 5; + else if (incy == 0) info = 8; + if (info != 0) { + input_error("sp_dgemv ", &info); + return 0; + } + + /* Quick return if possible. */ + if (A->nrow == 0 || A->ncol == 0 || (alpha == 0. && beta == 1.)) + return 0; + + /* Set LENX and LENY, the lengths of the vectors x and y, and set + up the start points in X and Y. */ + if (strncmp(trans, "N", 1)==0) { + lenx = A->ncol; + leny = A->nrow; + } else { + lenx = A->nrow; + leny = A->ncol; + } + if (incx > 0) kx = 0; + else kx = - (lenx - 1) * incx; + if (incy > 0) ky = 0; + else ky = - (leny - 1) * incy; + + /* Start the operations. In this version the elements of A are + accessed sequentially with one pass through A. */ + /* First form y := beta*y. */ + if (beta != 1.) { + if (incy == 1) { + if (beta == 0.) + for (i = 0; i < leny; ++i) y[i] = 0.; + else + for (i = 0; i < leny; ++i) y[i] = beta * y[i]; + } else { + iy = ky; + if (beta == 0.) + for (i = 0; i < leny; ++i) { + y[iy] = 0.; + iy += incy; + } + else + for (i = 0; i < leny; ++i) { + y[iy] = beta * y[iy]; + iy += incy; + } + } + } + + if (alpha == 0.) return 0; + + if ( notran ) { + /* Form y := alpha*A*x + y. */ + jx = kx; + if (incy == 1) { + for (j = 0; j < A->ncol; ++j) { + if (x[jx] != 0.) { + temp = alpha * x[jx]; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + y[irow] += temp * Aval[i]; + } + } + jx += incx; + } + } else { + ABORT("Not implemented."); + } + } else { + /* Form y := alpha*A'*x + y. */ + jy = ky; + if (incx == 1) { + for (j = 0; j < A->ncol; ++j) { + temp = 0.; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + temp += Aval[i] * x[irow]; + } + y[jy] += alpha * temp; + jy += incy; + } + } else { + ABORT("Not implemented."); + } + } + + return 0; +} /* sp_dgemv */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/dsp_blas3.c b/src/Libraries/superlu-5.2.1/SRC/dsp_blas3.c new file mode 100644 index 00000000..127d590d --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dsp_blas3.c @@ -0,0 +1,137 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dsp_blas3.c + * \brief Sparse BLAS3, using some dense BLAS3 operations + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ */ +/* + * File name: sp_blas3.c + * Purpose: Sparse BLAS3, using some dense BLAS3 operations. + */ + +#include "slu_ddefs.h" + +/*! \brief + * + *
+ * Purpose   
+ *   =======   
+ * 
+ *   sp_d performs one of the matrix-matrix operations   
+ * 
+ *      C := alpha*op( A )*op( B ) + beta*C,   
+ * 
+ *   where  op( X ) is one of 
+ * 
+ *      op( X ) = X   or   op( X ) = X'   or   op( X ) = conjg( X' ),
+ * 
+ *   alpha and beta are scalars, and A, B and C are matrices, with op( A ) 
+ *   an m by k matrix,  op( B )  a  k by n matrix and  C an m by n matrix. 
+ *   
+ * 
+ *   Parameters   
+ *   ==========   
+ * 
+ *   TRANSA - (input) char*
+ *            On entry, TRANSA specifies the form of op( A ) to be used in 
+ *            the matrix multiplication as follows:   
+ *               TRANSA = 'N' or 'n',  op( A ) = A.   
+ *               TRANSA = 'T' or 't',  op( A ) = A'.   
+ *               TRANSA = 'C' or 'c',  op( A ) = conjg( A' ).   
+ *            Unchanged on exit.   
+ * 
+ *   TRANSB - (input) char*
+ *            On entry, TRANSB specifies the form of op( B ) to be used in 
+ *            the matrix multiplication as follows:   
+ *               TRANSB = 'N' or 'n',  op( B ) = B.   
+ *               TRANSB = 'T' or 't',  op( B ) = B'.   
+ *               TRANSB = 'C' or 'c',  op( B ) = conjg( B' ).   
+ *            Unchanged on exit.   
+ * 
+ *   M      - (input) int   
+ *            On entry,  M  specifies  the number of rows of the matrix 
+ *	     op( A ) and of the matrix C.  M must be at least zero. 
+ *	     Unchanged on exit.   
+ * 
+ *   N      - (input) int
+ *            On entry,  N specifies the number of columns of the matrix 
+ *	     op( B ) and the number of columns of the matrix C. N must be 
+ *	     at least zero.
+ *	     Unchanged on exit.   
+ * 
+ *   K      - (input) int
+ *            On entry, K specifies the number of columns of the matrix 
+ *	     op( A ) and the number of rows of the matrix op( B ). K must 
+ *	     be at least  zero.   
+ *           Unchanged on exit.
+ *      
+ *   ALPHA  - (input) double
+ *            On entry, ALPHA specifies the scalar alpha.   
+ * 
+ *   A      - (input) SuperMatrix*
+ *            Matrix A with a sparse format, of dimension (A->nrow, A->ncol).
+ *            Currently, the type of A can be:
+ *                Stype = NC or NCP; Dtype = SLU_D; Mtype = GE. 
+ *            In the future, more general A can be handled.
+ * 
+ *   B      - DOUBLE PRECISION array of DIMENSION ( LDB, kb ), where kb is 
+ *            n when TRANSB = 'N' or 'n',  and is  k otherwise.   
+ *            Before entry with  TRANSB = 'N' or 'n',  the leading k by n 
+ *            part of the array B must contain the matrix B, otherwise 
+ *            the leading n by k part of the array B must contain the 
+ *            matrix B.   
+ *            Unchanged on exit.   
+ * 
+ *   LDB    - (input) int
+ *            On entry, LDB specifies the first dimension of B as declared 
+ *            in the calling (sub) program. LDB must be at least max( 1, n ).  
+ *            Unchanged on exit.   
+ * 
+ *   BETA   - (input) double
+ *            On entry, BETA specifies the scalar beta. When BETA is   
+ *            supplied as zero then C need not be set on input.   
+ *  
+ *   C      - DOUBLE PRECISION array of DIMENSION ( LDC, n ).   
+ *            Before entry, the leading m by n part of the array C must 
+ *            contain the matrix C,  except when beta is zero, in which 
+ *            case C need not be set on entry.   
+ *            On exit, the array C is overwritten by the m by n matrix 
+ *	     ( alpha*op( A )*B + beta*C ).   
+ *  
+ *   LDC    - (input) int
+ *            On entry, LDC specifies the first dimension of C as declared 
+ *            in the calling (sub)program. LDC must be at least max(1,m).   
+ *            Unchanged on exit.   
+ *  
+ *   ==== Sparse Level 3 Blas routine.   
+ * 
+ */ + +int +sp_dgemm(char *transa, char *transb, int m, int n, int k, + double alpha, SuperMatrix *A, double *b, int ldb, + double beta, double *c, int ldc) +{ + int incx = 1, incy = 1; + int j; + + for (j = 0; j < n; ++j) { + sp_dgemv(transa, alpha, A, &b[ldb*j], incx, beta, &c[ldc*j], incy); + } + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/dutil.c b/src/Libraries/superlu-5.2.1/SRC/dutil.c new file mode 100644 index 00000000..1ed1e962 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dutil.c @@ -0,0 +1,481 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file dutil.c + * \brief Matrix utility functions + * + *
+ * -- SuperLU routine (version 3.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * August 1, 2008
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include +#include "slu_ddefs.h" + +void +dCreate_CompCol_Matrix(SuperMatrix *A, int m, int n, int nnz, + double *nzval, int *rowind, int *colptr, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + NCformat *Astore; + + A->Stype = stype; + A->Dtype = dtype; + A->Mtype = mtype; + A->nrow = m; + A->ncol = n; + A->Store = (void *) SUPERLU_MALLOC( sizeof(NCformat) ); + if ( !(A->Store) ) ABORT("SUPERLU_MALLOC fails for A->Store"); + Astore = A->Store; + Astore->nnz = nnz; + Astore->nzval = nzval; + Astore->rowind = rowind; + Astore->colptr = colptr; +} + +void +dCreate_CompRow_Matrix(SuperMatrix *A, int m, int n, int nnz, + double *nzval, int *colind, int *rowptr, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + NRformat *Astore; + + A->Stype = stype; + A->Dtype = dtype; + A->Mtype = mtype; + A->nrow = m; + A->ncol = n; + A->Store = (void *) SUPERLU_MALLOC( sizeof(NRformat) ); + if ( !(A->Store) ) ABORT("SUPERLU_MALLOC fails for A->Store"); + Astore = A->Store; + Astore->nnz = nnz; + Astore->nzval = nzval; + Astore->colind = colind; + Astore->rowptr = rowptr; +} + +/*! \brief Copy matrix A into matrix B. */ +void +dCopy_CompCol_Matrix(SuperMatrix *A, SuperMatrix *B) +{ + NCformat *Astore, *Bstore; + int ncol, nnz, i; + + B->Stype = A->Stype; + B->Dtype = A->Dtype; + B->Mtype = A->Mtype; + B->nrow = A->nrow;; + B->ncol = ncol = A->ncol; + Astore = (NCformat *) A->Store; + Bstore = (NCformat *) B->Store; + Bstore->nnz = nnz = Astore->nnz; + for (i = 0; i < nnz; ++i) + ((double *)Bstore->nzval)[i] = ((double *)Astore->nzval)[i]; + for (i = 0; i < nnz; ++i) Bstore->rowind[i] = Astore->rowind[i]; + for (i = 0; i <= ncol; ++i) Bstore->colptr[i] = Astore->colptr[i]; +} + + +void +dCreate_Dense_Matrix(SuperMatrix *X, int m, int n, double *x, int ldx, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + DNformat *Xstore; + + X->Stype = stype; + X->Dtype = dtype; + X->Mtype = mtype; + X->nrow = m; + X->ncol = n; + X->Store = (void *) SUPERLU_MALLOC( sizeof(DNformat) ); + if ( !(X->Store) ) ABORT("SUPERLU_MALLOC fails for X->Store"); + Xstore = (DNformat *) X->Store; + Xstore->lda = ldx; + Xstore->nzval = (double *) x; +} + +void +dCopy_Dense_Matrix(int M, int N, double *X, int ldx, + double *Y, int ldy) +{ +/*! \brief Copies a two-dimensional matrix X to another matrix Y. + */ + int i, j; + + for (j = 0; j < N; ++j) + for (i = 0; i < M; ++i) + Y[i + j*ldy] = X[i + j*ldx]; +} + +void +dCreate_SuperNode_Matrix(SuperMatrix *L, int m, int n, int nnz, + double *nzval, int *nzval_colptr, int *rowind, + int *rowind_colptr, int *col_to_sup, int *sup_to_col, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + SCformat *Lstore; + + L->Stype = stype; + L->Dtype = dtype; + L->Mtype = mtype; + L->nrow = m; + L->ncol = n; + L->Store = (void *) SUPERLU_MALLOC( sizeof(SCformat) ); + if ( !(L->Store) ) ABORT("SUPERLU_MALLOC fails for L->Store"); + Lstore = L->Store; + Lstore->nnz = nnz; + Lstore->nsuper = col_to_sup[n]; + Lstore->nzval = nzval; + Lstore->nzval_colptr = nzval_colptr; + Lstore->rowind = rowind; + Lstore->rowind_colptr = rowind_colptr; + Lstore->col_to_sup = col_to_sup; + Lstore->sup_to_col = sup_to_col; + +} + + +/*! \brief Convert a row compressed storage into a column compressed storage. + */ +void +dCompRow_to_CompCol(int m, int n, int nnz, + double *a, int *colind, int *rowptr, + double **at, int **rowind, int **colptr) +{ + register int i, j, col, relpos; + int *marker; + + /* Allocate storage for another copy of the matrix. */ + *at = (double *) doubleMalloc(nnz); + *rowind = (int *) intMalloc(nnz); + *colptr = (int *) intMalloc(n+1); + marker = (int *) intCalloc(n); + + /* Get counts of each column of A, and set up column pointers */ + for (i = 0; i < m; ++i) + for (j = rowptr[i]; j < rowptr[i+1]; ++j) ++marker[colind[j]]; + (*colptr)[0] = 0; + for (j = 0; j < n; ++j) { + (*colptr)[j+1] = (*colptr)[j] + marker[j]; + marker[j] = (*colptr)[j]; + } + + /* Transfer the matrix into the compressed column storage. */ + for (i = 0; i < m; ++i) { + for (j = rowptr[i]; j < rowptr[i+1]; ++j) { + col = colind[j]; + relpos = marker[col]; + (*rowind)[relpos] = i; + (*at)[relpos] = a[j]; + ++marker[col]; + } + } + + SUPERLU_FREE(marker); +} + + +void +dPrint_CompCol_Matrix(char *what, SuperMatrix *A) +{ + NCformat *Astore; + register int i,n; + double *dp; + + printf("\nCompCol matrix %s:\n", what); + printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype); + n = A->ncol; + Astore = (NCformat *) A->Store; + dp = (double *) Astore->nzval; + printf("nrow %d, ncol %d, nnz %d\n", A->nrow,A->ncol,Astore->nnz); + printf("nzval: "); + for (i = 0; i < Astore->colptr[n]; ++i) printf("%f ", dp[i]); + printf("\nrowind: "); + for (i = 0; i < Astore->colptr[n]; ++i) printf("%d ", Astore->rowind[i]); + printf("\ncolptr: "); + for (i = 0; i <= n; ++i) printf("%d ", Astore->colptr[i]); + printf("\n"); + fflush(stdout); +} + +void +dPrint_SuperNode_Matrix(char *what, SuperMatrix *A) +{ + SCformat *Astore; + register int i, j, k, c, d, n, nsup; + double *dp; + int *col_to_sup, *sup_to_col, *rowind, *rowind_colptr; + + printf("\nSuperNode matrix %s:\n", what); + printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype); + n = A->ncol; + Astore = (SCformat *) A->Store; + dp = (double *) Astore->nzval; + col_to_sup = Astore->col_to_sup; + sup_to_col = Astore->sup_to_col; + rowind_colptr = Astore->rowind_colptr; + rowind = Astore->rowind; + printf("nrow %d, ncol %d, nnz %d, nsuper %d\n", + A->nrow,A->ncol,Astore->nnz,Astore->nsuper); + printf("nzval:\n"); + for (k = 0; k <= Astore->nsuper; ++k) { + c = sup_to_col[k]; + nsup = sup_to_col[k+1] - c; + for (j = c; j < c + nsup; ++j) { + d = Astore->nzval_colptr[j]; + for (i = rowind_colptr[c]; i < rowind_colptr[c+1]; ++i) { + printf("%d\t%d\t%e\n", rowind[i], j, dp[d++]); + } + } + } +#if 0 + for (i = 0; i < Astore->nzval_colptr[n]; ++i) printf("%f ", dp[i]); +#endif + printf("\nnzval_colptr: "); + for (i = 0; i <= n; ++i) printf("%d ", Astore->nzval_colptr[i]); + printf("\nrowind: "); + for (i = 0; i < Astore->rowind_colptr[n]; ++i) + printf("%d ", Astore->rowind[i]); + printf("\nrowind_colptr: "); + for (i = 0; i <= n; ++i) printf("%d ", Astore->rowind_colptr[i]); + printf("\ncol_to_sup: "); + for (i = 0; i < n; ++i) printf("%d ", col_to_sup[i]); + printf("\nsup_to_col: "); + for (i = 0; i <= Astore->nsuper+1; ++i) + printf("%d ", sup_to_col[i]); + printf("\n"); + fflush(stdout); +} + +void +dPrint_Dense_Matrix(char *what, SuperMatrix *A) +{ + DNformat *Astore = (DNformat *) A->Store; + register int i, j, lda = Astore->lda; + double *dp; + + printf("\nDense matrix %s:\n", what); + printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype); + dp = (double *) Astore->nzval; + printf("nrow %d, ncol %d, lda %d\n", A->nrow,A->ncol,lda); + printf("\nnzval: "); + for (j = 0; j < A->ncol; ++j) { + for (i = 0; i < A->nrow; ++i) printf("%f ", dp[i + j*lda]); + printf("\n"); + } + printf("\n"); + fflush(stdout); +} + +/*! \brief Diagnostic print of column "jcol" in the U/L factor. + */ +void +dprint_lu_col(char *msg, int jcol, int pivrow, int *xprune, GlobalLU_t *Glu) +{ + int i, k, fsupc; + int *xsup, *supno; + int *xlsub, *lsub; + double *lusup; + int *xlusup; + double *ucol; + int *usub, *xusub; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (double *) Glu->lusup; + xlusup = Glu->xlusup; + ucol = (double *) Glu->ucol; + usub = Glu->usub; + xusub = Glu->xusub; + + printf("%s", msg); + printf("col %d: pivrow %d, supno %d, xprune %d\n", + jcol, pivrow, supno[jcol], xprune[jcol]); + + printf("\tU-col:\n"); + for (i = xusub[jcol]; i < xusub[jcol+1]; i++) + printf("\t%d%10.4f\n", usub[i], ucol[i]); + printf("\tL-col in rectangular snode:\n"); + fsupc = xsup[supno[jcol]]; /* first col of the snode */ + i = xlsub[fsupc]; + k = xlusup[jcol]; + while ( i < xlsub[fsupc+1] && k < xlusup[jcol+1] ) { + printf("\t%d\t%10.4f\n", lsub[i], lusup[k]); + i++; k++; + } + fflush(stdout); +} + + +/*! \brief Check whether tempv[] == 0. This should be true before and after calling any numeric routines, i.e., "panel_bmod" and "column_bmod". + */ +void dcheck_tempv(int n, double *tempv) +{ + int i; + + for (i = 0; i < n; i++) { + if (tempv[i] != 0.0) + { + fprintf(stderr,"tempv[%d] = %f\n", i,tempv[i]); + ABORT("dcheck_tempv"); + } + } +} + + +void +dGenXtrue(int n, int nrhs, double *x, int ldx) +{ + int i, j; + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) { + x[i + j*ldx] = 1.0;/* + (double)(i+1.)/n;*/ + } +} + +/*! \brief Let rhs[i] = sum of i-th row of A, so the solution vector is all 1's + */ +void +dFillRHS(trans_t trans, int nrhs, double *x, int ldx, + SuperMatrix *A, SuperMatrix *B) +{ + NCformat *Astore; + double *Aval; + DNformat *Bstore; + double *rhs; + double one = 1.0; + double zero = 0.0; + int ldc; + char transc[1]; + + Astore = A->Store; + Aval = (double *) Astore->nzval; + Bstore = B->Store; + rhs = Bstore->nzval; + ldc = Bstore->lda; + + if ( trans == NOTRANS ) *(unsigned char *)transc = 'N'; + else *(unsigned char *)transc = 'T'; + + sp_dgemm(transc, "N", A->nrow, nrhs, A->ncol, one, A, + x, ldx, zero, rhs, ldc); + +} + +/*! \brief Fills a double precision array with a given value. + */ +void +dfill(double *a, int alen, double dval) +{ + register int i; + for (i = 0; i < alen; i++) a[i] = dval; +} + + + +/*! \brief Check the inf-norm of the error vector + */ +void dinf_norm_error(int nrhs, SuperMatrix *X, double *xtrue) +{ + DNformat *Xstore; + double err, xnorm; + double *Xmat, *soln_work; + int i, j; + + Xstore = X->Store; + Xmat = Xstore->nzval; + + for (j = 0; j < nrhs; j++) { + soln_work = &Xmat[j*Xstore->lda]; + err = xnorm = 0.0; + for (i = 0; i < X->nrow; i++) { + err = SUPERLU_MAX(err, fabs(soln_work[i] - xtrue[i])); + xnorm = SUPERLU_MAX(xnorm, fabs(soln_work[i])); + } + err = err / xnorm; + printf("||X - Xtrue||/||X|| = %e\n", err); + } +} + + + +/*! \brief Print performance of the code. */ +void +dPrintPerf(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage, + double rpg, double rcond, double *ferr, + double *berr, char *equed, SuperLUStat_t *stat) +{ + SCformat *Lstore; + NCformat *Ustore; + double *utime; + flops_t *ops; + + utime = stat->utime; + ops = stat->ops; + + if ( utime[FACT] != 0. ) + printf("Factor flops = %e\tMflops = %8.2f\n", ops[FACT], + ops[FACT]*1e-6/utime[FACT]); + printf("Identify relaxed snodes = %8.2f\n", utime[RELAX]); + if ( utime[SOLVE] != 0. ) + printf("Solve flops = %.0f, Mflops = %8.2f\n", ops[SOLVE], + ops[SOLVE]*1e-6/utime[SOLVE]); + + Lstore = (SCformat *) L->Store; + Ustore = (NCformat *) U->Store; + printf("\tNo of nonzeros in factor L = %d\n", Lstore->nnz); + printf("\tNo of nonzeros in factor U = %d\n", Ustore->nnz); + printf("\tNo of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage->for_lu/1e6, mem_usage->total_needed/1e6); + printf("Number of memory expansions: %d\n", stat->expansions); + + printf("\tFactor\tMflops\tSolve\tMflops\tEtree\tEquil\tRcond\tRefine\n"); + printf("PERF:%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f\n", + utime[FACT], ops[FACT]*1e-6/utime[FACT], + utime[SOLVE], ops[SOLVE]*1e-6/utime[SOLVE], + utime[ETREE], utime[EQUIL], utime[RCOND], utime[REFINE]); + + printf("\tRpg\t\tRcond\t\tFerr\t\tBerr\t\tEquil?\n"); + printf("NUM:\t%e\t%e\t%e\t%e\t%s\n", + rpg, rcond, ferr[0], berr[0], equed); + +} + + + + +print_double_vec(char *what, int n, double *vec) +{ + int i; + printf("%s: n %d\n", what, n); + for (i = 0; i < n; ++i) printf("%d\t%f\n", i, vec[i]); + return 0; +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/dzsum1.c b/src/Libraries/superlu-5.2.1/SRC/dzsum1.c new file mode 100644 index 00000000..8037bbd0 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/dzsum1.c @@ -0,0 +1,104 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file dzsum1.c + * \brief Takes sum of the absolute values of a complex vector and returns a double precision result + * + *
+ *     -- LAPACK auxiliary routine (version 2.0) --   
+ *     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
+ *     Courant Institute, Argonne National Lab, and Rice University   
+ *     October 31, 1992   
+ * 
+ */ + +#include "slu_dcomplex.h" +#include "slu_Cnames.h" + +/*! \brief + +
+    Purpose   
+    =======   
+
+    DZSUM1 takes the sum of the absolute values of a complex   
+    vector and returns a double precision result.   
+
+    Based on DZASUM from the Level 1 BLAS.   
+    The change is to use the 'genuine' absolute value.   
+
+    Contributed by Nick Higham for use with ZLACON.   
+
+    Arguments   
+    =========   
+
+    N       (input) INT   
+            The number of elements in the vector CX.   
+
+    CX      (input) COMPLEX*16 array, dimension (N)   
+            The vector whose elements will be summed.   
+
+    INCX    (input) INT   
+            The spacing between successive values of CX.  INCX > 0.   
+
+    ===================================================================== 
+
+*/ +double dzsum1_slu(int *n, doublecomplex *cx, int *incx) +{ + + /* Builtin functions */ + double z_abs(doublecomplex *); + + /* Local variables */ + int i, nincx; + double stemp; + + +#define CX(I) cx[(I)-1] + + stemp = 0.; + if (*n <= 0) { + return stemp; + } + if (*incx == 1) { + goto L20; + } + + /* CODE FOR INCREMENT NOT EQUAL TO 1 */ + + nincx = *n * *incx; + for (i = 1; *incx < 0 ? i >= nincx : i <= nincx; i += *incx) { + + /* NEXT LINE MODIFIED. */ + + stemp += z_abs(&CX(i)); +/* L10: */ + } + + return stemp; + + /* CODE FOR INCREMENT EQUAL TO 1 */ + +L20: + for (i = 1; i <= *n; ++i) { + + /* NEXT LINE MODIFIED. */ + + stemp += z_abs(&CX(i)); +/* L30: */ + } + + return stemp; + + /* End of DZSUM1 */ + +} /* dzsum1_slu */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/get_perm_c.c b/src/Libraries/superlu-5.2.1/SRC/get_perm_c.c new file mode 100644 index 00000000..728f8cd2 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/get_perm_c.c @@ -0,0 +1,467 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file get_perm_c.c + * \brief Matrix permutation operations + * + *
+ * -- SuperLU routine (version 3.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * August 1, 2008
+ * 
+ */ +#include "slu_ddefs.h" +#include "colamd.h" + +extern int genmmd_(int *, int *, int *, int *, int *, int *, int *, + int *, int *, int *, int *, int *); + +void +get_colamd( + const int m, /* number of rows in matrix A. */ + const int n, /* number of columns in matrix A. */ + const int nnz,/* number of nonzeros in matrix A. */ + int *colptr, /* column pointer of size n+1 for matrix A. */ + int *rowind, /* row indices of size nz for matrix A. */ + int *perm_c /* out - the column permutation vector. */ + ) +{ + int Alen, *A, i, info, *p; + double knobs[COLAMD_KNOBS]; + int stats[COLAMD_STATS]; + + Alen = colamd_recommended(nnz, m, n); + + colamd_set_defaults(knobs); + + if (!(A = (int *) SUPERLU_MALLOC(Alen * sizeof(int))) ) + ABORT("Malloc fails for A[]"); + if (!(p = (int *) SUPERLU_MALLOC((n+1) * sizeof(int))) ) + ABORT("Malloc fails for p[]"); + for (i = 0; i <= n; ++i) p[i] = colptr[i]; + for (i = 0; i < nnz; ++i) A[i] = rowind[i]; + info = colamd(m, n, Alen, A, p, knobs, stats); + if ( info == FALSE ) ABORT("COLAMD failed"); + + for (i = 0; i < n; ++i) perm_c[p[i]] = i; + + SUPERLU_FREE(A); + SUPERLU_FREE(p); +} +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * Form the structure of A'*A. A is an m-by-n matrix in column oriented
+ * format represented by (colptr, rowind). The output A'*A is in column
+ * oriented format (symmetrically, also row oriented), represented by
+ * (ata_colptr, ata_rowind).
+ *
+ * This routine is modified from GETATA routine by Tim Davis.
+ * The complexity of this algorithm is: SUM_{i=1,m} r(i)^2,
+ * i.e., the sum of the square of the row counts.
+ *
+ * Questions
+ * =========
+ *     o  Do I need to withhold the *dense* rows?
+ *     o  How do I know the number of nonzeros in A'*A?
+ * 
+ */ +void +getata( + const int m, /* number of rows in matrix A. */ + const int n, /* number of columns in matrix A. */ + const int nz, /* number of nonzeros in matrix A */ + int *colptr, /* column pointer of size n+1 for matrix A. */ + int *rowind, /* row indices of size nz for matrix A. */ + int *atanz, /* out - on exit, returns the actual number of + nonzeros in matrix A'*A. */ + int **ata_colptr, /* out - size n+1 */ + int **ata_rowind /* out - size *atanz */ + ) +{ + register int i, j, k, col, num_nz, ti, trow; + int *marker, *b_colptr, *b_rowind; + int *t_colptr, *t_rowind; /* a column oriented form of T = A' */ + + if ( !(marker = (int*) SUPERLU_MALLOC((SUPERLU_MAX(m,n)+1)*sizeof(int))) ) + ABORT("SUPERLU_MALLOC fails for marker[]"); + if ( !(t_colptr = (int*) SUPERLU_MALLOC((m+1) * sizeof(int))) ) + ABORT("SUPERLU_MALLOC t_colptr[]"); + if ( !(t_rowind = (int*) SUPERLU_MALLOC(nz * sizeof(int))) ) + ABORT("SUPERLU_MALLOC fails for t_rowind[]"); + + + /* Get counts of each column of T, and set up column pointers */ + for (i = 0; i < m; ++i) marker[i] = 0; + for (j = 0; j < n; ++j) { + for (i = colptr[j]; i < colptr[j+1]; ++i) + ++marker[rowind[i]]; + } + t_colptr[0] = 0; + for (i = 0; i < m; ++i) { + t_colptr[i+1] = t_colptr[i] + marker[i]; + marker[i] = t_colptr[i]; + } + + /* Transpose the matrix from A to T */ + for (j = 0; j < n; ++j) + for (i = colptr[j]; i < colptr[j+1]; ++i) { + col = rowind[i]; + t_rowind[marker[col]] = j; + ++marker[col]; + } + + + /* ---------------------------------------------------------------- + compute B = T * A, where column j of B is: + + Struct (B_*j) = UNION ( Struct (T_*k) ) + A_kj != 0 + + do not include the diagonal entry + + ( Partition A as: A = (A_*1, ..., A_*n) + Then B = T * A = (T * A_*1, ..., T * A_*n), where + T * A_*j = (T_*1, ..., T_*m) * A_*j. ) + ---------------------------------------------------------------- */ + + /* Zero the diagonal flag */ + for (i = 0; i < n; ++i) marker[i] = -1; + + /* First pass determines number of nonzeros in B */ + num_nz = 0; + for (j = 0; j < n; ++j) { + /* Flag the diagonal so it's not included in the B matrix */ + marker[j] = j; + + for (i = colptr[j]; i < colptr[j+1]; ++i) { + /* A_kj is nonzero, add pattern of column T_*k to B_*j */ + k = rowind[i]; + for (ti = t_colptr[k]; ti < t_colptr[k+1]; ++ti) { + trow = t_rowind[ti]; + if ( marker[trow] != j ) { + marker[trow] = j; + num_nz++; + } + } + } + } + *atanz = num_nz; + + /* Allocate storage for A'*A */ + if ( !(*ata_colptr = (int*) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for ata_colptr[]"); + if ( *atanz ) { + if ( !(*ata_rowind = (int*) SUPERLU_MALLOC( *atanz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for ata_rowind[]"); + } + b_colptr = *ata_colptr; /* aliasing */ + b_rowind = *ata_rowind; + + /* Zero the diagonal flag */ + for (i = 0; i < n; ++i) marker[i] = -1; + + /* Compute each column of B, one at a time */ + num_nz = 0; + for (j = 0; j < n; ++j) { + b_colptr[j] = num_nz; + + /* Flag the diagonal so it's not included in the B matrix */ + marker[j] = j; + + for (i = colptr[j]; i < colptr[j+1]; ++i) { + /* A_kj is nonzero, add pattern of column T_*k to B_*j */ + k = rowind[i]; + for (ti = t_colptr[k]; ti < t_colptr[k+1]; ++ti) { + trow = t_rowind[ti]; + if ( marker[trow] != j ) { + marker[trow] = j; + b_rowind[num_nz++] = trow; + } + } + } + } + b_colptr[n] = num_nz; + + SUPERLU_FREE(marker); + SUPERLU_FREE(t_colptr); + SUPERLU_FREE(t_rowind); +} + + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * Form the structure of A'+A. A is an n-by-n matrix in column oriented
+ * format represented by (colptr, rowind). The output A'+A is in column
+ * oriented format (symmetrically, also row oriented), represented by
+ * (b_colptr, b_rowind).
+ * 
+ */ +void +at_plus_a( + const int n, /* number of columns in matrix A. */ + const int nz, /* number of nonzeros in matrix A */ + int *colptr, /* column pointer of size n+1 for matrix A. */ + int *rowind, /* row indices of size nz for matrix A. */ + int *bnz, /* out - on exit, returns the actual number of + nonzeros in matrix A'*A. */ + int **b_colptr, /* out - size n+1 */ + int **b_rowind /* out - size *bnz */ + ) +{ + register int i, j, k, col, num_nz; + int *t_colptr, *t_rowind; /* a column oriented form of T = A' */ + int *marker; + + if ( !(marker = (int*) SUPERLU_MALLOC( n * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for marker[]"); + if ( !(t_colptr = (int*) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for t_colptr[]"); + if ( !(t_rowind = (int*) SUPERLU_MALLOC( nz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails t_rowind[]"); + + + /* Get counts of each column of T, and set up column pointers */ + for (i = 0; i < n; ++i) marker[i] = 0; + for (j = 0; j < n; ++j) { + for (i = colptr[j]; i < colptr[j+1]; ++i) + ++marker[rowind[i]]; + } + t_colptr[0] = 0; + for (i = 0; i < n; ++i) { + t_colptr[i+1] = t_colptr[i] + marker[i]; + marker[i] = t_colptr[i]; + } + + /* Transpose the matrix from A to T */ + for (j = 0; j < n; ++j) + for (i = colptr[j]; i < colptr[j+1]; ++i) { + col = rowind[i]; + t_rowind[marker[col]] = j; + ++marker[col]; + } + + + /* ---------------------------------------------------------------- + compute B = A + T, where column j of B is: + + Struct (B_*j) = Struct (A_*k) UNION Struct (T_*k) + + do not include the diagonal entry + ---------------------------------------------------------------- */ + + /* Zero the diagonal flag */ + for (i = 0; i < n; ++i) marker[i] = -1; + + /* First pass determines number of nonzeros in B */ + num_nz = 0; + for (j = 0; j < n; ++j) { + /* Flag the diagonal so it's not included in the B matrix */ + marker[j] = j; + + /* Add pattern of column A_*k to B_*j */ + for (i = colptr[j]; i < colptr[j+1]; ++i) { + k = rowind[i]; + if ( marker[k] != j ) { + marker[k] = j; + ++num_nz; + } + } + + /* Add pattern of column T_*k to B_*j */ + for (i = t_colptr[j]; i < t_colptr[j+1]; ++i) { + k = t_rowind[i]; + if ( marker[k] != j ) { + marker[k] = j; + ++num_nz; + } + } + } + *bnz = num_nz; + + /* Allocate storage for A+A' */ + if ( !(*b_colptr = (int*) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for b_colptr[]"); + if ( *bnz) { + if ( !(*b_rowind = (int*) SUPERLU_MALLOC( *bnz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for b_rowind[]"); + } + + /* Zero the diagonal flag */ + for (i = 0; i < n; ++i) marker[i] = -1; + + /* Compute each column of B, one at a time */ + num_nz = 0; + for (j = 0; j < n; ++j) { + (*b_colptr)[j] = num_nz; + + /* Flag the diagonal so it's not included in the B matrix */ + marker[j] = j; + + /* Add pattern of column A_*k to B_*j */ + for (i = colptr[j]; i < colptr[j+1]; ++i) { + k = rowind[i]; + if ( marker[k] != j ) { + marker[k] = j; + (*b_rowind)[num_nz++] = k; + } + } + + /* Add pattern of column T_*k to B_*j */ + for (i = t_colptr[j]; i < t_colptr[j+1]; ++i) { + k = t_rowind[i]; + if ( marker[k] != j ) { + marker[k] = j; + (*b_rowind)[num_nz++] = k; + } + } + } + (*b_colptr)[n] = num_nz; + + SUPERLU_FREE(marker); + SUPERLU_FREE(t_colptr); + SUPERLU_FREE(t_rowind); +} + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * GET_PERM_C obtains a permutation matrix Pc, by applying the multiple
+ * minimum degree ordering code by Joseph Liu to matrix A'*A or A+A'.
+ * or using approximate minimum degree column ordering by Davis et. al.
+ * The LU factorization of A*Pc tends to have less fill than the LU 
+ * factorization of A.
+ *
+ * Arguments
+ * =========
+ *
+ * ispec   (input) int
+ *         Specifies the type of column ordering to reduce fill:
+ *         = 1: minimum degree on the structure of A^T * A
+ *         = 2: minimum degree on the structure of A^T + A
+ *         = 3: approximate minimum degree for unsymmetric matrices
+ *         If ispec == 0, the natural ordering (i.e., Pc = I) is returned.
+ * 
+ * A       (input) SuperMatrix*
+ *         Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
+ *         of the linear equations is A->nrow. Currently, the type of A 
+ *         can be: Stype = NC; Dtype = _D; Mtype = GE. In the future,
+ *         more general A can be handled.
+ *
+ * perm_c  (output) int*
+ *	   Column permutation vector of size A->ncol, which defines the 
+ *         permutation matrix Pc; perm_c[i] = j means column i of A is 
+ *         in position j in A*Pc.
+ * 
+ */ +void +get_perm_c(int ispec, SuperMatrix *A, int *perm_c) +{ + NCformat *Astore = A->Store; + int m, n, bnz = 0, *b_colptr, i; + int delta, maxint, nofsub, *invp; + int *b_rowind, *dhead, *qsize, *llist, *marker; + double t, SuperLU_timer_(); + + m = A->nrow; + n = A->ncol; + + t = SuperLU_timer_(); + switch ( ispec ) { + case (NATURAL): /* Natural ordering */ + for (i = 0; i < n; ++i) perm_c[i] = i; +#if ( PRNTlevel>=1 ) + printf("Use natural column ordering.\n"); +#endif + return; + case (MMD_ATA): /* Minimum degree ordering on A'*A */ + getata(m, n, Astore->nnz, Astore->colptr, Astore->rowind, + &bnz, &b_colptr, &b_rowind); +#if ( PRNTlevel>=1 ) + printf("Use minimum degree ordering on A'*A.\n"); +#endif + t = SuperLU_timer_() - t; + /*printf("Form A'*A time = %8.3f\n", t);*/ + break; + case (MMD_AT_PLUS_A): /* Minimum degree ordering on A'+A */ + if ( m != n ) ABORT("Matrix is not square"); + at_plus_a(n, Astore->nnz, Astore->colptr, Astore->rowind, + &bnz, &b_colptr, &b_rowind); +#if ( PRNTlevel>=1 ) + printf("Use minimum degree ordering on A'+A.\n"); +#endif + t = SuperLU_timer_() - t; + /*printf("Form A'+A time = %8.3f\n", t);*/ + break; + case (COLAMD): /* Approximate minimum degree column ordering. */ + get_colamd(m, n, Astore->nnz, Astore->colptr, Astore->rowind, perm_c); +#if ( PRNTlevel>=1 ) + printf(".. Use approximate minimum degree column ordering.\n"); +#endif + return; + default: + ABORT("Invalid ISPEC"); + } + + if ( bnz != 0 ) { + t = SuperLU_timer_(); + + /* Initialize and allocate storage for GENMMD. */ + delta = 0; /* DELTA is a parameter to allow the choice of nodes + whose degree <= min-degree + DELTA. */ + maxint = 2147483647; /* 2**31 - 1 */ + invp = (int *) SUPERLU_MALLOC((n+delta)*sizeof(int)); + if ( !invp ) ABORT("SUPERLU_MALLOC fails for invp."); + dhead = (int *) SUPERLU_MALLOC((n+delta)*sizeof(int)); + if ( !dhead ) ABORT("SUPERLU_MALLOC fails for dhead."); + qsize = (int *) SUPERLU_MALLOC((n+delta)*sizeof(int)); + if ( !qsize ) ABORT("SUPERLU_MALLOC fails for qsize."); + llist = (int *) SUPERLU_MALLOC(n*sizeof(int)); + if ( !llist ) ABORT("SUPERLU_MALLOC fails for llist."); + marker = (int *) SUPERLU_MALLOC(n*sizeof(int)); + if ( !marker ) ABORT("SUPERLU_MALLOC fails for marker."); + + /* Transform adjacency list into 1-based indexing required by GENMMD.*/ + for (i = 0; i <= n; ++i) ++b_colptr[i]; + for (i = 0; i < bnz; ++i) ++b_rowind[i]; + + genmmd_(&n, b_colptr, b_rowind, perm_c, invp, &delta, dhead, + qsize, llist, marker, &maxint, &nofsub); + + /* Transform perm_c into 0-based indexing. */ + for (i = 0; i < n; ++i) --perm_c[i]; + + SUPERLU_FREE(invp); + SUPERLU_FREE(dhead); + SUPERLU_FREE(qsize); + SUPERLU_FREE(llist); + SUPERLU_FREE(marker); + SUPERLU_FREE(b_rowind); + + t = SuperLU_timer_() - t; + /* printf("call GENMMD time = %8.3f\n", t);*/ + + } else { /* Empty adjacency structure */ + for (i = 0; i < n; ++i) perm_c[i] = i; + } + + SUPERLU_FREE(b_colptr); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/heap_relax_snode.c b/src/Libraries/superlu-5.2.1/SRC/heap_relax_snode.c new file mode 100644 index 00000000..62713550 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/heap_relax_snode.c @@ -0,0 +1,134 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file heap_relax_snode.c + * \brief Identify the initial relaxed supernodes + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + +#include "slu_ddefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *    relax_snode() - Identify the initial relaxed supernodes, assuming that 
+ *    the matrix has been reordered according to the postorder of the etree.
+ * 
+ */ + +void +heap_relax_snode ( + const int n, + int *et, /* column elimination tree */ + const int relax_columns, /* max no of columns allowed in a + relaxed snode */ + int *descendants, /* no of descendants of each node + in the etree */ + int *relax_end /* last column in a supernode */ + ) +{ + register int i, j, k, l, parent; + register int snode_start; /* beginning of a snode */ + int *et_save, *post, *inv_post, *iwork; + int nsuper_et = 0, nsuper_et_post = 0; + + /* The etree may not be postordered, but is heap ordered. */ + + iwork = (int*) intMalloc(3*n+2); + if ( !iwork ) ABORT("SUPERLU_MALLOC fails for iwork[]"); + inv_post = iwork + n+1; + et_save = inv_post + n+1; + + /* Post order etree */ + post = (int *) TreePostorder(n, et); + for (i = 0; i < n+1; ++i) inv_post[post[i]] = i; + + /* Renumber etree in postorder */ + for (i = 0; i < n; ++i) { + iwork[post[i]] = post[et[i]]; + et_save[i] = et[i]; /* Save the original etree */ + } + for (i = 0; i < n; ++i) et[i] = iwork[i]; + + /* Compute the number of descendants of each node in the etree */ + ifill (relax_end, n, EMPTY); + for (j = 0; j < n; j++) descendants[j] = 0; + for (j = 0; j < n; j++) { + parent = et[j]; + if ( parent != n ) /* not the dummy root */ + descendants[parent] += descendants[j] + 1; + } + + /* Identify the relaxed supernodes by postorder traversal of the etree. */ + for (j = 0; j < n; ) { + parent = et[j]; + snode_start = j; + while ( parent != n && descendants[parent] < relax_columns ) { + j = parent; + parent = et[j]; + } + /* Found a supernode in postordered etree; j is the last column. */ + ++nsuper_et_post; + k = n; + for (i = snode_start; i <= j; ++i) + k = SUPERLU_MIN(k, inv_post[i]); + l = inv_post[j]; + if ( (l - k) == (j - snode_start) ) { + /* It's also a supernode in the original etree */ + relax_end[k] = l; /* Last column is recorded */ + ++nsuper_et; + } else { + for (i = snode_start; i <= j; ++i) { + l = inv_post[i]; + if ( descendants[i] == 0 ) { + relax_end[l] = l; + ++nsuper_et; + } + } + } + j++; + /* Search for a new leaf */ + while ( descendants[j] != 0 && j < n ) j++; + } + +#if ( PRNTlevel>=1 ) + printf(".. heap_snode_relax:\n" + "\tNo of relaxed snodes in postordered etree:\t%d\n" + "\tNo of relaxed snodes in original etree:\t%d\n", + nsuper_et_post, nsuper_et); +#endif + + /* Recover the original etree */ + for (i = 0; i < n; ++i) et[i] = et_save[i]; + + SUPERLU_FREE(post); + SUPERLU_FREE(iwork); +} + + diff --git a/src/Libraries/superlu-5.2.1/SRC/html_mainpage.h b/src/Libraries/superlu-5.2.1/SRC/html_mainpage.h new file mode 100644 index 00000000..73152c8f --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/html_mainpage.h @@ -0,0 +1,31 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! \mainpage SuperLU Documentation + +SuperLU is a general purpose library for the direct solution of large, +sparse, nonsymmetric systems of linear equations on high performance +machines. The library is written in C and is callable from either C or +Fortran. The library routines perform an LU decomposition with +partial pivoting and triangular system solves through forward and back +substitution. The library also provides threshold-based ILU factorization +preconditioners. + +The factorization routines can handle non-square +matrices but the triangular solves are performed only for square +matrices. The matrix columns may be preordered (before factorization) +either through library or user supplied routines. This preordering for +sparsity is completely separate from the factorization. Working +precision iterative refinement subroutines are provided for improved +backward stability. Routines are also provided to equilibrate the +system, estimate the condition number, calculate the relative backward +error, and estimate error bounds for the refined solutions. + + */ diff --git a/src/Libraries/superlu-5.2.1/SRC/icmax1.c b/src/Libraries/superlu-5.2.1/SRC/icmax1.c new file mode 100644 index 00000000..41e949d2 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/icmax1.c @@ -0,0 +1,126 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file icmax1.c + * \brief Finds the index of the element whose real part has maximum absolute value + * + *
+ *     -- LAPACK auxiliary routine (version 2.0) --   
+ *     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
+ *     Courant Institute, Argonne National Lab, and Rice University   
+ *     October 31, 1992   
+ * 
+ */ +#include +#include "slu_scomplex.h" +#include "slu_Cnames.h" + +/*! \brief + +
+    Purpose   
+    =======   
+
+    ICMAX1 finds the index of the element whose real part has maximum   
+    absolute value.   
+
+    Based on ICAMAX from Level 1 BLAS.   
+    The change is to use the 'genuine' absolute value.   
+
+    Contributed by Nick Higham for use with CLACON.   
+
+    Arguments   
+    =========   
+
+    N       (input) INT   
+            The number of elements in the vector CX.   
+
+    CX      (input) COMPLEX array, dimension (N)   
+            The vector whose elements will be summed.   
+
+    INCX    (input) INT   
+            The spacing between successive values of CX.  INCX >= 1.   
+
+   ===================================================================== 
+  
+*/ +int icmax1_slu(int *n, complex *cx, int *incx) +{ +/* + NEXT LINE IS THE ONLY MODIFICATION. + + + Parameter adjustments + Function Body */ + /* System generated locals */ + int ret_val, i__1, i__2; + float r__1; + /* Local variables */ + static float smax; + static int i, ix; + + +#define CX(I) cx[(I)-1] + + + ret_val = 0; + if (*n < 1) { + return ret_val; + } + ret_val = 1; + if (*n == 1) { + return ret_val; + } + if (*incx == 1) { + goto L30; + } + +/* CODE FOR INCREMENT NOT EQUAL TO 1 */ + + ix = 1; + smax = (r__1 = CX(1).r, fabs(r__1)); + ix += *incx; + i__1 = *n; + for (i = 2; i <= *n; ++i) { + i__2 = ix; + if ((r__1 = CX(ix).r, fabs(r__1)) <= smax) { + goto L10; + } + ret_val = i; + i__2 = ix; + smax = (r__1 = CX(ix).r, fabs(r__1)); +L10: + ix += *incx; +/* L20: */ + } + return ret_val; + +/* CODE FOR INCREMENT EQUAL TO 1 */ + +L30: + smax = (r__1 = CX(1).r, fabs(r__1)); + i__1 = *n; + for (i = 2; i <= *n; ++i) { + i__2 = i; + if ((r__1 = CX(i).r, fabs(r__1)) <= smax) { + goto L40; + } + ret_val = i; + i__2 = i; + smax = (r__1 = CX(i).r, fabs(r__1)); +L40: + ; + } + return ret_val; + +/* End of ICMAX1 */ + +} /* icmax1_slu */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_ccolumn_dfs.c b/src/Libraries/superlu-5.2.1/SRC/ilu_ccolumn_dfs.c new file mode 100644 index 00000000..6c902dd3 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_ccolumn_dfs.c @@ -0,0 +1,265 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_ccolumn_dfs.c + * \brief Performs a symbolic factorization + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+*/ + +#include "slu_cdefs.h" + + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   ILU_CCOLUMN_DFS performs a symbolic factorization on column jcol, and
+ *   decide the supernode boundary.
+ *
+ *   This routine does not use numeric values, but only use the RHS
+ *   row indices to start the dfs.
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives. The routine returns a list of such supernodal
+ *   representatives in topological order of the dfs that generates them.
+ *   The location of the first nonzero in each such supernodal segment
+ *   (supernodal entry location) is also returned.
+ *
+ * Local parameters
+ * ================
+ *   nseg: no of segments in current U[*,j]
+ *   jsuper: jsuper=EMPTY if column j does not belong to the same
+ *	supernode as j-1. Otherwise, jsuper=nsuper.
+ *
+ *   marker2: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ *
+ * Return value
+ * ============
+ *     0  success;
+ *   > 0  number of bytes allocated when run out of space.
+ * 
+ */ +int +ilu_ccolumn_dfs( + const int m, /* in - number of rows in the matrix */ + const int jcol, /* in */ + int *perm_r, /* in */ + int *nseg, /* modified - with new segments appended */ + int *lsub_col, /* in - defines the RHS vector to start the + dfs */ + int *segrep, /* modified - with new segments appended */ + int *repfnz, /* modified */ + int *marker, /* modified */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ + ) +{ + + int jcolp1, jcolm1, jsuper, nsuper, nextl; + int k, krep, krow, kmark, kperm; + int *marker2; /* Used for small panel LU */ + int fsupc; /* First column of a snode */ + int myfnz; /* First nonz column of a U-segment */ + int chperm, chmark, chrep, kchild; + int xdfs, maxdfs, kpar, oldrep; + int jptr, jm1ptr; + int ito, ifrom; /* Used to compress row subscripts */ + int mem_error; + int *xsup, *supno, *lsub, *xlsub; + int nzlmax; + int maxsuper; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + maxsuper = sp_ienv(7); + jcolp1 = jcol + 1; + jcolm1 = jcol - 1; + nsuper = supno[jcol]; + jsuper = nsuper; + nextl = xlsub[jcol]; + marker2 = &marker[2*m]; + + + /* For each nonzero in A[*,jcol] do dfs */ + for (k = 0; lsub_col[k] != EMPTY; k++) { + + krow = lsub_col[k]; + lsub_col[k] = EMPTY; + kmark = marker2[krow]; + + /* krow was visited before, go to the next nonzero */ + if ( kmark == jcol ) continue; + + /* For each unmarked nbr krow of jcol + * krow is in L: place it in structure of L[*,jcol] + */ + marker2[krow] = jcol; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + lsub[nextl++] = krow; /* krow is indexed into A */ + if ( nextl >= nzlmax ) { + if ((mem_error = cLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu))) + return (mem_error); + lsub = Glu->lsub; + } + if ( kmark != jcolm1 ) jsuper = EMPTY;/* Row index subset testing */ + } else { + /* krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz[krep]; + + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > kperm ) repfnz[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz[krep] = kperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; + + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker2[kchild]; + + if ( chmark != jcol ) { /* Not reached yet */ + marker2[kchild] = jcol; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,k] */ + if ( chperm == EMPTY ) { + lsub[nextl++] = kchild; + if ( nextl >= nzlmax ) { + if ( (mem_error = cLUMemXpand(jcol,nextl, + LSUB,&nzlmax,Glu)) ) + return (mem_error); + lsub = Glu->lsub; + } + if ( chmark != jcolm1 ) jsuper = EMPTY; + } else { + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz[chrep]; + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz[chrep] = chperm; + } else { + /* Continue dfs at super-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L^t) */ + parent[krep] = oldrep; + repfnz[krep] = chperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; + } /* else */ + + } /* else */ + + } /* if */ + + } /* while */ + + /* krow has no more unexplored nbrs; + * place supernode-rep krep in postorder DFS. + * backtrack dfs to its parent + */ + segrep[*nseg] = krep; + ++(*nseg); + kpar = parent[krep]; /* Pop from stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xlsub[krep + 1]; + + } while ( kpar != EMPTY ); /* Until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonzero ... */ + + /* Check to see if j belongs in the same supernode as j-1 */ + if ( jcol == 0 ) { /* Do nothing for column 0 */ + nsuper = supno[0] = 0; + } else { + fsupc = xsup[nsuper]; + jptr = xlsub[jcol]; /* Not compressed yet */ + jm1ptr = xlsub[jcolm1]; + + if ( (nextl-jptr != jptr-jm1ptr-1) ) jsuper = EMPTY; + + /* Always start a new supernode for a singular column */ + if ( nextl == jptr ) jsuper = EMPTY; + + /* Make sure the number of columns in a supernode doesn't + exceed threshold. */ + if ( jcol - fsupc >= maxsuper ) jsuper = EMPTY; + + /* If jcol starts a new supernode, reclaim storage space in + * lsub from the previous supernode. Note we only store + * the subscript set of the first columns of the supernode. + */ + if ( jsuper == EMPTY ) { /* starts a new supernode */ + if ( (fsupc < jcolm1) ) { /* >= 2 columns in nsuper */ +#ifdef CHK_COMPRESS + printf(" Compress lsub[] at super %d-%d\n", fsupc, jcolm1); +#endif + ito = xlsub[fsupc+1]; + xlsub[jcolm1] = ito; + xlsub[jcol] = ito; + for (ifrom = jptr; ifrom < nextl; ++ifrom, ++ito) + lsub[ito] = lsub[ifrom]; + nextl = ito; + } + nsuper++; + supno[jcol] = nsuper; + } /* if a new supernode */ + + } /* else: jcol > 0 */ + + /* Tidy up the pointers before exit */ + xsup[nsuper+1] = jcolp1; + supno[jcolp1] = nsuper; + xlsub[jcolp1] = nextl; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_ccopy_to_ucol.c b/src/Libraries/superlu-5.2.1/SRC/ilu_ccopy_to_ucol.c new file mode 100644 index 00000000..a5eb0b61 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_ccopy_to_ucol.c @@ -0,0 +1,221 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_ccopy_to_ucol.c + * \brief Copy a computed column of U to the compressed data structure + * and drop some small entries + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Lawrence Berkeley National Laboratory
+ * November, 2010
+ * 
+ */ + +#include "slu_cdefs.h" + +#ifdef DEBUG +int num_drop_U; +#endif + +extern void ccopy_(int *, complex [], int *, complex [], int *); + +#if 0 +static complex *A; /* used in _compare_ only */ +static int _compare_(const void *a, const void *b) +{ + register int *x = (int *)a, *y = (int *)b; + register float xx = c_abs1(&A[*x]), yy = c_abs1(&A[*y]); + if (xx > yy) return -1; + else if (xx < yy) return 1; + else return 0; +} +#endif + +int +ilu_ccopy_to_ucol( + int jcol, /* in */ + int nseg, /* in */ + int *segrep, /* in */ + int *repfnz, /* in */ + int *perm_r, /* in */ + complex *dense, /* modified - reset to zero on return */ + int drop_rule,/* in */ + milu_t milu, /* in */ + double drop_tol, /* in */ + int quota, /* maximum nonzero entries allowed */ + complex *sum, /* out - the sum of dropped entries */ + int *nnzUj, /* in - out */ + GlobalLU_t *Glu, /* modified */ + float *work /* working space with minimum size n, + * used by the second dropping rule */ + ) +{ +/* + * Gather from SPA dense[*] to global ucol[*]. + */ + int ksub, krep, ksupno; + int i, k, kfnz, segsze; + int fsupc, isub, irow; + int jsupno, nextu; + int new_next, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + complex *ucol; + int *usub, *xusub; + int nzumax; + int m; /* number of entries in the nonzero U-segments */ + register float d_max = 0.0, d_min = 1.0 / smach("Safe minimum"); + register double tmp; + complex zero = {0.0, 0.0}; + int i_1 = 1; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + ucol = (complex *) Glu->ucol; + usub = Glu->usub; + xusub = Glu->xusub; + nzumax = Glu->nzumax; + + *sum = zero; + if (drop_rule == NODROP) { + drop_tol = -1.0, quota = Glu->n; + } + + jsupno = supno[jcol]; + nextu = xusub[jcol]; + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { + krep = segrep[k--]; + ksupno = supno[krep]; + + if ( ksupno != jsupno ) { /* Should go into ucol[] */ + kfnz = repfnz[krep]; + if ( kfnz != EMPTY ) { /* Nonzero U-segment */ + + fsupc = xsup[ksupno]; + isub = xlsub[fsupc] + kfnz - fsupc; + segsze = krep - kfnz + 1; + + new_next = nextu + segsze; + while ( new_next > nzumax ) { + if ((mem_error = cLUMemXpand(jcol, nextu, UCOL, &nzumax, + Glu)) != 0) + return (mem_error); + ucol = Glu->ucol; + if ((mem_error = cLUMemXpand(jcol, nextu, USUB, &nzumax, + Glu)) != 0) + return (mem_error); + usub = Glu->usub; + lsub = Glu->lsub; + } + + for (i = 0; i < segsze; i++) { + irow = lsub[isub++]; + tmp = c_abs1(&dense[irow]); + + /* first dropping rule */ + if (quota > 0 && tmp >= drop_tol) { + if (tmp > d_max) d_max = tmp; + if (tmp < d_min) d_min = tmp; + usub[nextu] = perm_r[irow]; + ucol[nextu] = dense[irow]; + nextu++; + } else { + switch (milu) { + case SMILU_1: + case SMILU_2: + c_add(sum, sum, &dense[irow]); + break; + case SMILU_3: + /* *sum += fabs(dense[irow]);*/ + sum->r += tmp; + break; + case SILU: + default: + break; + } +#ifdef DEBUG + num_drop_U++; +#endif + } + dense[irow] = zero; + } + + } + + } + + } /* for each segment... */ + + xusub[jcol + 1] = nextu; /* Close U[*,jcol] */ + m = xusub[jcol + 1] - xusub[jcol]; + + /* second dropping rule */ + if (drop_rule & DROP_SECONDARY && m > quota) { + register double tol = d_max; + register int m0 = xusub[jcol] + m - 1; + + if (quota > 0) { + if (drop_rule & DROP_INTERP) { + d_max = 1.0 / d_max; d_min = 1.0 / d_min; + tol = 1.0 / (d_max + (d_min - d_max) * quota / m); + } else { + i_1 = xusub[jcol]; + for (i = 0; i < m; ++i, ++i_1) work[i] = c_abs1(&ucol[i_1]); + tol = sqselect(m, work, quota); +#if 0 + A = &ucol[xusub[jcol]]; + for (i = 0; i < m; i++) work[i] = i; + qsort(work, m, sizeof(int), _compare_); + tol = fabs(usub[xusub[jcol] + work[quota]]); +#endif + } + } + for (i = xusub[jcol]; i <= m0; ) { + if (c_abs1(&ucol[i]) <= tol) { + switch (milu) { + case SMILU_1: + case SMILU_2: + c_add(sum, sum, &ucol[i]); + break; + case SMILU_3: + sum->r += tmp; + break; + case SILU: + default: + break; + } + ucol[i] = ucol[m0]; + usub[i] = usub[m0]; + m0--; + m--; +#ifdef DEBUG + num_drop_U++; +#endif + xusub[jcol + 1]--; + continue; + } + i++; + } + } + + if (milu == SMILU_2) { + sum->r = c_abs1(sum); sum->i = 0.0; + } + if (milu == SMILU_3) sum->i = 0.0; + + *nnzUj += m; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_cdrop_row.c b/src/Libraries/superlu-5.2.1/SRC/ilu_cdrop_row.c new file mode 100644 index 00000000..4987548d --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_cdrop_row.c @@ -0,0 +1,349 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_cdrop_row.c + * \brief Drop small rows from L + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ + +#include +#include +#include "slu_cdefs.h" + +extern void cswap_(int *, complex [], int *, complex [], int *); +extern void caxpy_(int *, complex *, complex [], int *, complex [], int *); +extern void ccopy_(int *, complex [], int *, complex [], int *); +extern float scasum_(int *, complex *, int *); +extern float scnrm2_(int *, complex *, int *); +extern double dnrm2_(int *, double [], int *); +extern int icamax_(int *, complex [], int *); + +static float *A; /* used in _compare_ only */ +static int _compare_(const void *a, const void *b) +{ + register int *x = (int *)a, *y = (int *)b; + if (A[*x] - A[*y] > 0.0) return -1; + else if (A[*x] - A[*y] < 0.0) return 1; + else return 0; +} + +/*! \brief + *
+ * Purpose
+ * =======
+ *    ilu_cdrop_row() - Drop some small rows from the previous 
+ *    supernode (L-part only).
+ * 
+ */ +int ilu_cdrop_row( + superlu_options_t *options, /* options */ + int first, /* index of the first column in the supernode */ + int last, /* index of the last column in the supernode */ + double drop_tol, /* dropping parameter */ + int quota, /* maximum nonzero entries allowed */ + int *nnzLj, /* in/out number of nonzeros in L(:, 1:last) */ + double *fill_tol, /* in/out - on exit, fill_tol=-num_zero_pivots, + * does not change if options->ILU_MILU != SMILU1 */ + GlobalLU_t *Glu, /* modified */ + float swork[], /* working space + * the length of swork[] should be no less than + * the number of rows in the supernode */ + float swork2[], /* working space with the same size as swork[], + * used only by the second dropping rule */ + int lastc /* if lastc == 0, there is nothing after the + * working supernode [first:last]; + * if lastc == 1, there is one more column after + * the working supernode. */ ) +{ + register int i, j, k, m1; + register int nzlc; /* number of nonzeros in column last+1 */ + register int xlusup_first, xlsub_first; + int m, n; /* m x n is the size of the supernode */ + int r = 0; /* number of dropped rows */ + register float *temp; + register complex *lusup = (complex *) Glu->lusup; + register int *lsub = Glu->lsub; + register int *xlsub = Glu->xlsub; + register int *xlusup = Glu->xlusup; + register float d_max = 0.0, d_min = 1.0; + int drop_rule = options->ILU_DropRule; + milu_t milu = options->ILU_MILU; + norm_t nrm = options->ILU_Norm; + complex zero = {0.0, 0.0}; + complex one = {1.0, 0.0}; + complex none = {-1.0, 0.0}; + int i_1 = 1; + int inc_diag; /* inc_diag = m + 1 */ + int nzp = 0; /* number of zero pivots */ + float alpha = pow((double)(Glu->n), -1.0 / options->ILU_MILU_Dim); + + xlusup_first = xlusup[first]; + xlsub_first = xlsub[first]; + m = xlusup[first + 1] - xlusup_first; + n = last - first + 1; + m1 = m - 1; + inc_diag = m + 1; + nzlc = lastc ? (xlusup[last + 2] - xlusup[last + 1]) : 0; + temp = swork - n; + + /* Quick return if nothing to do. */ + if (m == 0 || m == n || drop_rule == NODROP) + { + *nnzLj += m * n; + return 0; + } + + /* basic dropping: ILU(tau) */ + for (i = n; i <= m1; ) + { + /* the average abs value of ith row */ + switch (nrm) + { + case ONE_NORM: + temp[i] = scasum_(&n, &lusup[xlusup_first + i], &m) / (double)n; + break; + case TWO_NORM: + temp[i] = scnrm2_(&n, &lusup[xlusup_first + i], &m) + / sqrt((double)n); + break; + case INF_NORM: + default: + k = icamax_(&n, &lusup[xlusup_first + i], &m) - 1; + temp[i] = c_abs1(&lusup[xlusup_first + i + m * k]); + break; + } + + /* drop small entries due to drop_tol */ + if (drop_rule & DROP_BASIC && temp[i] < drop_tol) + { + r++; + /* drop the current row and move the last undropped row here */ + if (r > 1) /* add to last row */ + { + /* accumulate the sum (for MILU) */ + switch (milu) + { + case SMILU_1: + case SMILU_2: + caxpy_(&n, &one, &lusup[xlusup_first + i], &m, + &lusup[xlusup_first + m - 1], &m); + break; + case SMILU_3: + for (j = 0; j < n; j++) + lusup[xlusup_first + (m - 1) + j * m].r += + c_abs1(&lusup[xlusup_first + i + j * m]); + break; + case SILU: + default: + break; + } + ccopy_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + } /* if (r > 1) */ + else /* move to last row */ + { + cswap_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + if (milu == SMILU_3) + for (j = 0; j < n; j++) { + lusup[xlusup_first + m1 + j * m].r = + c_abs1(&lusup[xlusup_first + m1 + j * m]); + lusup[xlusup_first + m1 + j * m].i = 0.0; + } + } + lsub[xlsub_first + i] = lsub[xlsub_first + m1]; + m1--; + continue; + } /* if dropping */ + else + { + if (temp[i] > d_max) d_max = temp[i]; + if (temp[i] < d_min) d_min = temp[i]; + } + i++; + } /* for */ + + /* Secondary dropping: drop more rows according to the quota. */ + quota = ceil((double)quota / (double)n); + if (drop_rule & DROP_SECONDARY && m - r > quota) + { + register double tol = d_max; + + /* Calculate the second dropping tolerance */ + if (quota > n) + { + if (drop_rule & DROP_INTERP) /* by interpolation */ + { + d_max = 1.0 / d_max; d_min = 1.0 / d_min; + tol = 1.0 / (d_max + (d_min - d_max) * quota / (m - n - r)); + } + else /* by quick select */ + { + int len = m1 - n + 1; + scopy_(&len, swork, &i_1, swork2, &i_1); + tol = sqselect(len, swork2, quota - n); +#if 0 + register int *itemp = iwork - n; + A = temp; + for (i = n; i <= m1; i++) itemp[i] = i; + qsort(iwork, m1 - n + 1, sizeof(int), _compare_); + tol = temp[itemp[quota]]; +#endif + } + } + + for (i = n; i <= m1; ) + { + if (temp[i] <= tol) + { + register int j; + r++; + /* drop the current row and move the last undropped row here */ + if (r > 1) /* add to last row */ + { + /* accumulate the sum (for MILU) */ + switch (milu) + { + case SMILU_1: + case SMILU_2: + caxpy_(&n, &one, &lusup[xlusup_first + i], &m, + &lusup[xlusup_first + m - 1], &m); + break; + case SMILU_3: + for (j = 0; j < n; j++) + lusup[xlusup_first + (m - 1) + j * m].r += + c_abs1(&lusup[xlusup_first + i + j * m]); + break; + case SILU: + default: + break; + } + ccopy_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + } /* if (r > 1) */ + else /* move to last row */ + { + cswap_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + if (milu == SMILU_3) + for (j = 0; j < n; j++) { + lusup[xlusup_first + m1 + j * m].r = + c_abs1(&lusup[xlusup_first + m1 + j * m]); + lusup[xlusup_first + m1 + j * m].i = 0.0; + } + } + lsub[xlsub_first + i] = lsub[xlsub_first + m1]; + m1--; + temp[i] = temp[m1]; + + continue; + } + i++; + + } /* for */ + + } /* if secondary dropping */ + + for (i = n; i < m; i++) temp[i] = 0.0; + + if (r == 0) + { + *nnzLj += m * n; + return 0; + } + + /* add dropped entries to the diagnal */ + if (milu != SILU) + { + register int j; + complex t; + float omega; + for (j = 0; j < n; j++) + { + t = lusup[xlusup_first + (m - 1) + j * m]; + if (t.r == 0.0 && t.i == 0.0) continue; + omega = SUPERLU_MIN(2.0 * (1.0 - alpha) / c_abs1(&t), 1.0); + cs_mult(&t, &t, omega); + + switch (milu) + { + case SMILU_1: + if ( !(c_eq(&t, &none)) ) { + c_add(&t, &t, &one); + cc_mult(&lusup[xlusup_first + j * inc_diag], + &lusup[xlusup_first + j * inc_diag], + &t); + } + else + { + cs_mult( + &lusup[xlusup_first + j * inc_diag], + &lusup[xlusup_first + j * inc_diag], + *fill_tol); +#ifdef DEBUG + printf("[1] ZERO PIVOT: FILL col %d.\n", first + j); + fflush(stdout); +#endif + nzp++; + } + break; + case SMILU_2: + cs_mult(&lusup[xlusup_first + j * inc_diag], + &lusup[xlusup_first + j * inc_diag], + 1.0 + c_abs1(&t)); + break; + case SMILU_3: + c_add(&t, &t, &one); + cc_mult(&lusup[xlusup_first + j * inc_diag], + &lusup[xlusup_first + j * inc_diag], + &t); + break; + case SILU: + default: + break; + } + } + if (nzp > 0) *fill_tol = -nzp; + } + + /* Remove dropped entries from the memory and fix the pointers. */ + m1 = m - r; + for (j = 1; j < n; j++) + { + register int tmp1, tmp2; + tmp1 = xlusup_first + j * m1; + tmp2 = xlusup_first + j * m; + for (i = 0; i < m1; i++) + lusup[i + tmp1] = lusup[i + tmp2]; + } + for (i = 0; i < nzlc; i++) + lusup[xlusup_first + i + n * m1] = lusup[xlusup_first + i + n * m]; + for (i = 0; i < nzlc; i++) + lsub[xlsub[last + 1] - r + i] = lsub[xlsub[last + 1] + i]; + for (i = first + 1; i <= last + 1; i++) + { + xlusup[i] -= r * (i - first); + xlsub[i] -= r; + } + if (lastc) + { + xlusup[last + 2] -= r * n; + xlsub[last + 2] -= r; + } + + *nnzLj += (m - r) * n; + return r; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_cpanel_dfs.c b/src/Libraries/superlu-5.2.1/SRC/ilu_cpanel_dfs.c new file mode 100644 index 00000000..394088f2 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_cpanel_dfs.c @@ -0,0 +1,258 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_cpanel_dfs.c + * \brief Peforms a symbolic factorization on a panel of symbols and + * record the entries with maximum absolute value in each column + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + +#include "slu_cdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *   Performs a symbolic factorization on a panel of columns [jcol, jcol+w).
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives.
+ *
+ *   The routine returns one list of the supernodal representatives
+ *   in topological order of the dfs that generates them. This list is
+ *   a superset of the topological order of each individual column within
+ *   the panel.
+ *   The location of the first nonzero in each supernodal segment
+ *   (supernodal entry location) is also returned. Each column has a
+ *   separate list for this purpose.
+ *
+ *   Two marker arrays are used for dfs:
+ *     marker[i] == jj, if i was visited during dfs of current column jj;
+ *     marker1[i] >= jcol, if i was visited by earlier columns in this panel;
+ *
+ *   marker: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ * 
+ */ +void +ilu_cpanel_dfs( + const int m, /* in - number of rows in the matrix */ + const int w, /* in */ + const int jcol, /* in */ + SuperMatrix *A, /* in - original matrix */ + int *perm_r, /* in */ + int *nseg, /* out */ + complex *dense, /* out */ + float *amax, /* out - max. abs. value of each column in panel */ + int *panel_lsub, /* out */ + int *segrep, /* out */ + int *repfnz, /* out */ + int *marker, /* out */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ +) +{ + + NCPformat *Astore; + complex *a; + int *asub; + int *xa_begin, *xa_end; + int krep, chperm, chmark, chrep, oldrep, kchild, myfnz; + int k, krow, kmark, kperm; + int xdfs, maxdfs, kpar; + int jj; /* index through each column in the panel */ + int *marker1; /* marker1[jj] >= jcol if vertex jj was visited + by a previous column within this panel. */ + int *repfnz_col; /* start of each column in the panel */ + complex *dense_col; /* start of each column in the panel */ + int nextl_col; /* next available position in panel_lsub[*,jj] */ + int *xsup, *supno; + int *lsub, *xlsub; + float *amax_col; + register double tmp; + + /* Initialize pointers */ + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + marker1 = marker + m; + repfnz_col = repfnz; + dense_col = dense; + amax_col = amax; + *nseg = 0; + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + + /* For each column in the panel */ + for (jj = jcol; jj < jcol + w; jj++) { + nextl_col = (jj - jcol) * m; + +#ifdef CHK_DFS + printf("\npanel col %d: ", jj); +#endif + + *amax_col = 0.0; + /* For each nonz in A[*,jj] do dfs */ + for (k = xa_begin[jj]; k < xa_end[jj]; k++) { + krow = asub[k]; + tmp = c_abs1(&a[k]); + if (tmp > *amax_col) *amax_col = tmp; + dense_col[krow] = a[k]; + kmark = marker[krow]; + if ( kmark == jj ) + continue; /* krow visited before, go to the next nonzero */ + + /* For each unmarked nbr krow of jj + * krow is in L: place it in structure of L[*,jj] + */ + marker[krow] = jj; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + panel_lsub[nextl_col++] = krow; /* krow is indexed into A */ + } + /* + * krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + else { + + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz_col[krep]; + +#ifdef CHK_DFS + printf("krep %d, myfnz %d, perm_r[%d] %d\n", krep, myfnz, krow, kperm); +#endif + if ( myfnz != EMPTY ) { /* Representative visited before */ + if ( myfnz > kperm ) repfnz_col[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz_col[krep] = kperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; + +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker[kchild]; + + if ( chmark != jj ) { /* Not reached yet */ + marker[kchild] = jj; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,j] */ + if ( chperm == EMPTY ) { + panel_lsub[nextl_col++] = kchild; + } + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + else { + + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz_col[chrep]; +#ifdef CHK_DFS + printf("chrep %d,myfnz %d,perm_r[%d] %d\n",chrep,myfnz,kchild,chperm); +#endif + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz_col[chrep] = chperm; + } + else { + /* Cont. dfs at snode-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L) */ + parent[krep] = oldrep; + repfnz_col[krep] = chperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } /* else */ + + } /* else */ + + } /* if... */ + + } /* while xdfs < maxdfs */ + + /* krow has no more unexplored nbrs: + * Place snode-rep krep in postorder DFS, if this + * segment is seen for the first time. (Note that + * "repfnz[krep]" may change later.) + * Backtrack dfs to its parent. + */ + if ( marker1[krep] < jcol ) { + segrep[*nseg] = krep; + ++(*nseg); + marker1[krep] = jj; + } + + kpar = parent[krep]; /* Pop stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xlsub[krep + 1]; + +#ifdef CHK_DFS + printf(" pop stack: krep %d,xdfs %d,maxdfs %d: ", krep,xdfs,maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } while ( kpar != EMPTY ); /* do-while - until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonz in A[*,jj] */ + + repfnz_col += m; /* Move to next column */ + dense_col += m; + amax_col++; + + } /* for jj ... */ + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_cpivotL.c b/src/Libraries/superlu-5.2.1/SRC/ilu_cpivotL.c new file mode 100644 index 00000000..4f96de80 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_cpivotL.c @@ -0,0 +1,284 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_cpivotL.c + * \brief Performs numerical pivoting + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + + +#include +#include +#include "slu_cdefs.h" + +#ifndef SGN +#define SGN(x) ((x)>=0?1:-1) +#endif + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   Performs the numerical pivoting on the current column of L,
+ *   and the CDIV operation.
+ *
+ *   Pivot policy:
+ *   (1) Compute thresh = u * max_(i>=j) abs(A_ij);
+ *   (2) IF user specifies pivot row k and abs(A_kj) >= thresh THEN
+ *	     pivot row = k;
+ *	 ELSE IF abs(A_jj) >= thresh THEN
+ *	     pivot row = j;
+ *	 ELSE
+ *	     pivot row = m;
+ *
+ *   Note: If you absolutely want to use a given pivot order, then set u=0.0.
+ *
+ *   Return value: 0	  success;
+ *		   i > 0  U(i,i) is exactly zero.
+ * 
+ */ + +int +ilu_cpivotL( + const int jcol, /* in */ + const double u, /* in - diagonal pivoting threshold */ + int *usepr, /* re-use the pivot sequence given by + * perm_r/iperm_r */ + int *perm_r, /* may be modified */ + int diagind, /* diagonal of Pc*A*Pc' */ + int *swap, /* in/out record the row permutation */ + int *iswap, /* in/out inverse of swap, it is the same as + perm_r after the factorization */ + int *marker, /* in */ + int *pivrow, /* in/out, as an input if *usepr!=0 */ + double fill_tol, /* in - fill tolerance of current column + * used for a singular column */ + milu_t milu, /* in */ + complex drop_sum, /* in - computed in ilu_ccopy_to_ucol() + (MILU only) */ + GlobalLU_t *Glu, /* modified - global LU data structures */ + SuperLUStat_t *stat /* output */ + ) +{ + + int n; /* number of columns */ + int fsupc; /* first column in the supernode */ + int nsupc; /* no of columns in the supernode */ + int nsupr; /* no of rows in the supernode */ + int lptr; /* points to the starting subscript of the supernode */ + register int pivptr; + int old_pivptr, diag, ptr0; + register float pivmax, rtemp; + float thresh; + complex temp; + complex *lu_sup_ptr; + complex *lu_col_ptr; + int *lsub_ptr; + register int isub, icol, k, itemp; + int *lsub, *xlsub; + complex *lusup; + int *xlusup; + flops_t *ops = stat->ops; + int info; + complex one = {1.0, 0.0}; + + /* Initialize pointers */ + n = Glu->n; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (complex *) Glu->lusup; + xlusup = Glu->xlusup; + fsupc = (Glu->xsup)[(Glu->supno)[jcol]]; + nsupc = jcol - fsupc; /* excluding jcol; nsupc >= 0 */ + lptr = xlsub[fsupc]; + nsupr = xlsub[fsupc+1] - lptr; + lu_sup_ptr = &lusup[xlusup[fsupc]]; /* start of the current supernode */ + lu_col_ptr = &lusup[xlusup[jcol]]; /* start of jcol in the supernode */ + lsub_ptr = &lsub[lptr]; /* start of row indices of the supernode */ + + /* Determine the largest abs numerical value for partial pivoting; + Also search for user-specified pivot, and diagonal element. */ + pivmax = -1.0; + pivptr = nsupc; + diag = EMPTY; + old_pivptr = nsupc; + ptr0 = EMPTY; + for (isub = nsupc; isub < nsupr; ++isub) { + if (marker[lsub_ptr[isub]] > jcol) + continue; /* do not overlap with a later relaxed supernode */ + + switch (milu) { + case SMILU_1: + c_add(&temp, &lu_col_ptr[isub], &drop_sum); + rtemp = c_abs1(&temp); + break; + case SMILU_2: + case SMILU_3: + /* In this case, drop_sum contains the sum of the abs. value */ + rtemp = c_abs1(&lu_col_ptr[isub]); + break; + case SILU: + default: + rtemp = c_abs1(&lu_col_ptr[isub]); + break; + } + if (rtemp > pivmax) { pivmax = rtemp; pivptr = isub; } + if (*usepr && lsub_ptr[isub] == *pivrow) old_pivptr = isub; + if (lsub_ptr[isub] == diagind) diag = isub; + if (ptr0 == EMPTY) ptr0 = isub; + } + + if (milu == SMILU_2 || milu == SMILU_3) pivmax += drop_sum.r; + + /* Test for singularity */ + if (pivmax < 0.0) { + fprintf(stderr, "[0]: jcol=%d, SINGULAR!!!\n", jcol); + fflush(stderr); + exit(1); + } + if ( pivmax == 0.0 ) { + if (diag != EMPTY) + *pivrow = lsub_ptr[pivptr = diag]; + else if (ptr0 != EMPTY) + *pivrow = lsub_ptr[pivptr = ptr0]; + else { + /* look for the first row which does not + belong to any later supernodes */ + for (icol = jcol; icol < n; icol++) + if (marker[swap[icol]] <= jcol) break; + if (icol >= n) { + fprintf(stderr, "[1]: jcol=%d, SINGULAR!!!\n", jcol); + fflush(stderr); + exit(1); + } + + *pivrow = swap[icol]; + + /* pick up the pivot row */ + for (isub = nsupc; isub < nsupr; ++isub) + if ( lsub_ptr[isub] == *pivrow ) { pivptr = isub; break; } + } + pivmax = fill_tol; + lu_col_ptr[pivptr].r = pivmax; + lu_col_ptr[pivptr].i = 0.0; + *usepr = 0; +#ifdef DEBUG + printf("[0] ZERO PIVOT: FILL (%d, %d).\n", *pivrow, jcol); + fflush(stdout); +#endif + info =jcol + 1; + } /* if (*pivrow == 0.0) */ + else { + thresh = u * pivmax; + + /* Choose appropriate pivotal element by our policy. */ + if ( *usepr ) { + switch (milu) { + case SMILU_1: + c_add(&temp, &lu_col_ptr[old_pivptr], &drop_sum); + rtemp = c_abs1(&temp); + break; + case SMILU_2: + case SMILU_3: + rtemp = c_abs1(&lu_col_ptr[old_pivptr]) + drop_sum.r; + break; + case SILU: + default: + rtemp = c_abs1(&lu_col_ptr[old_pivptr]); + break; + } + if ( rtemp != 0.0 && rtemp >= thresh ) pivptr = old_pivptr; + else *usepr = 0; + } + if ( *usepr == 0 ) { + /* Use diagonal pivot? */ + if ( diag >= 0 ) { /* diagonal exists */ + switch (milu) { + case SMILU_1: + c_add(&temp, &lu_col_ptr[diag], &drop_sum); + rtemp = c_abs1(&temp); + break; + case SMILU_2: + case SMILU_3: + rtemp = c_abs1(&lu_col_ptr[diag]) + drop_sum.r; + break; + case SILU: + default: + rtemp = c_abs1(&lu_col_ptr[diag]); + break; + } + if ( rtemp != 0.0 && rtemp >= thresh ) pivptr = diag; + } + *pivrow = lsub_ptr[pivptr]; + } + info = 0; + + /* Reset the diagonal */ + switch (milu) { + case SMILU_1: + c_add(&lu_col_ptr[pivptr], &lu_col_ptr[pivptr], &drop_sum); + break; + case SMILU_2: + case SMILU_3: + temp = c_sgn(&lu_col_ptr[pivptr]); + cc_mult(&temp, &temp, &drop_sum); + c_add(&lu_col_ptr[pivptr], &lu_col_ptr[pivptr], &drop_sum); + break; + case SILU: + default: + break; + } + + } /* else */ + + /* Record pivot row */ + perm_r[*pivrow] = jcol; + if (jcol < n - 1) { + register int t1, t2, t; + t1 = iswap[*pivrow]; t2 = jcol; + if (t1 != t2) { + t = swap[t1]; swap[t1] = swap[t2]; swap[t2] = t; + t1 = swap[t1]; t2 = t; + t = iswap[t1]; iswap[t1] = iswap[t2]; iswap[t2] = t; + } + } /* if (jcol < n - 1) */ + + /* Interchange row subscripts */ + if ( pivptr != nsupc ) { + itemp = lsub_ptr[pivptr]; + lsub_ptr[pivptr] = lsub_ptr[nsupc]; + lsub_ptr[nsupc] = itemp; + + /* Interchange numerical values as well, for the whole snode, such + * that L is indexed the same way as A. + */ + for (icol = 0; icol <= nsupc; icol++) { + itemp = pivptr + icol * nsupr; + temp = lu_sup_ptr[itemp]; + lu_sup_ptr[itemp] = lu_sup_ptr[nsupc + icol*nsupr]; + lu_sup_ptr[nsupc + icol*nsupr] = temp; + } + } /* if */ + + /* cdiv operation */ + ops[FACT] += 10 * (nsupr - nsupc); + c_div(&temp, &one, &lu_col_ptr[nsupc]); + for (k = nsupc+1; k < nsupr; k++) + cc_mult(&lu_col_ptr[k], &lu_col_ptr[k], &temp); + + return info; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_csnode_dfs.c b/src/Libraries/superlu-5.2.1/SRC/ilu_csnode_dfs.c new file mode 100644 index 00000000..c67aa9ba --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_csnode_dfs.c @@ -0,0 +1,100 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_csnode_dfs.c + * \brief Determines the union of row structures of columns within the relaxed node + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + +#include "slu_cdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *    ilu_csnode_dfs() - Determine the union of the row structures of those
+ *    columns within the relaxed snode.
+ *    Note: The relaxed snodes are leaves of the supernodal etree, therefore,
+ *    the portion outside the rectangular supernode must be zero.
+ *
+ * Return value
+ * ============
+ *     0   success;
+ *    >0   number of bytes allocated when run out of memory.
+ * 
+ */ + +int +ilu_csnode_dfs( + const int jcol, /* in - start of the supernode */ + const int kcol, /* in - end of the supernode */ + const int *asub, /* in */ + const int *xa_begin, /* in */ + const int *xa_end, /* in */ + int *marker, /* modified */ + GlobalLU_t *Glu /* modified */ + ) +{ + + register int i, k, nextl; + int nsuper, krow, kmark, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + int nzlmax; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + nsuper = ++supno[jcol]; /* Next available supernode number */ + nextl = xlsub[jcol]; + + for (i = jcol; i <= kcol; i++) + { + /* For each nonzero in A[*,i] */ + for (k = xa_begin[i]; k < xa_end[i]; k++) + { + krow = asub[k]; + kmark = marker[krow]; + if ( kmark != kcol ) + { /* First time visit krow */ + marker[krow] = kcol; + lsub[nextl++] = krow; + if ( nextl >= nzlmax ) + { + if ( (mem_error = cLUMemXpand(jcol, nextl, LSUB, &nzlmax, + Glu)) != 0) + return (mem_error); + lsub = Glu->lsub; + } + } + } + supno[i] = nsuper; + } + + /* Supernode > 1 */ + if ( jcol < kcol ) + for (i = jcol+1; i <= kcol; i++) xlsub[i] = nextl; + + xsup[nsuper+1] = kcol + 1; + supno[kcol+1] = nsuper; + xlsub[kcol+1] = nextl; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_dcolumn_dfs.c b/src/Libraries/superlu-5.2.1/SRC/ilu_dcolumn_dfs.c new file mode 100644 index 00000000..5cd0453e --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_dcolumn_dfs.c @@ -0,0 +1,265 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_dcolumn_dfs.c + * \brief Performs a symbolic factorization + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+*/ + +#include "slu_ddefs.h" + + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   ILU_DCOLUMN_DFS performs a symbolic factorization on column jcol, and
+ *   decide the supernode boundary.
+ *
+ *   This routine does not use numeric values, but only use the RHS
+ *   row indices to start the dfs.
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives. The routine returns a list of such supernodal
+ *   representatives in topological order of the dfs that generates them.
+ *   The location of the first nonzero in each such supernodal segment
+ *   (supernodal entry location) is also returned.
+ *
+ * Local parameters
+ * ================
+ *   nseg: no of segments in current U[*,j]
+ *   jsuper: jsuper=EMPTY if column j does not belong to the same
+ *	supernode as j-1. Otherwise, jsuper=nsuper.
+ *
+ *   marker2: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ *
+ * Return value
+ * ============
+ *     0  success;
+ *   > 0  number of bytes allocated when run out of space.
+ * 
+ */ +int +ilu_dcolumn_dfs( + const int m, /* in - number of rows in the matrix */ + const int jcol, /* in */ + int *perm_r, /* in */ + int *nseg, /* modified - with new segments appended */ + int *lsub_col, /* in - defines the RHS vector to start the + dfs */ + int *segrep, /* modified - with new segments appended */ + int *repfnz, /* modified */ + int *marker, /* modified */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ + ) +{ + + int jcolp1, jcolm1, jsuper, nsuper, nextl; + int k, krep, krow, kmark, kperm; + int *marker2; /* Used for small panel LU */ + int fsupc; /* First column of a snode */ + int myfnz; /* First nonz column of a U-segment */ + int chperm, chmark, chrep, kchild; + int xdfs, maxdfs, kpar, oldrep; + int jptr, jm1ptr; + int ito, ifrom; /* Used to compress row subscripts */ + int mem_error; + int *xsup, *supno, *lsub, *xlsub; + int nzlmax; + int maxsuper; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + maxsuper = sp_ienv(7); + jcolp1 = jcol + 1; + jcolm1 = jcol - 1; + nsuper = supno[jcol]; + jsuper = nsuper; + nextl = xlsub[jcol]; + marker2 = &marker[2*m]; + + + /* For each nonzero in A[*,jcol] do dfs */ + for (k = 0; lsub_col[k] != EMPTY; k++) { + + krow = lsub_col[k]; + lsub_col[k] = EMPTY; + kmark = marker2[krow]; + + /* krow was visited before, go to the next nonzero */ + if ( kmark == jcol ) continue; + + /* For each unmarked nbr krow of jcol + * krow is in L: place it in structure of L[*,jcol] + */ + marker2[krow] = jcol; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + lsub[nextl++] = krow; /* krow is indexed into A */ + if ( nextl >= nzlmax ) { + if ((mem_error = dLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu))) + return (mem_error); + lsub = Glu->lsub; + } + if ( kmark != jcolm1 ) jsuper = EMPTY;/* Row index subset testing */ + } else { + /* krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz[krep]; + + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > kperm ) repfnz[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz[krep] = kperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; + + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker2[kchild]; + + if ( chmark != jcol ) { /* Not reached yet */ + marker2[kchild] = jcol; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,k] */ + if ( chperm == EMPTY ) { + lsub[nextl++] = kchild; + if ( nextl >= nzlmax ) { + if ( (mem_error = dLUMemXpand(jcol,nextl, + LSUB,&nzlmax,Glu)) ) + return (mem_error); + lsub = Glu->lsub; + } + if ( chmark != jcolm1 ) jsuper = EMPTY; + } else { + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz[chrep]; + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz[chrep] = chperm; + } else { + /* Continue dfs at super-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L^t) */ + parent[krep] = oldrep; + repfnz[krep] = chperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; + } /* else */ + + } /* else */ + + } /* if */ + + } /* while */ + + /* krow has no more unexplored nbrs; + * place supernode-rep krep in postorder DFS. + * backtrack dfs to its parent + */ + segrep[*nseg] = krep; + ++(*nseg); + kpar = parent[krep]; /* Pop from stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xlsub[krep + 1]; + + } while ( kpar != EMPTY ); /* Until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonzero ... */ + + /* Check to see if j belongs in the same supernode as j-1 */ + if ( jcol == 0 ) { /* Do nothing for column 0 */ + nsuper = supno[0] = 0; + } else { + fsupc = xsup[nsuper]; + jptr = xlsub[jcol]; /* Not compressed yet */ + jm1ptr = xlsub[jcolm1]; + + if ( (nextl-jptr != jptr-jm1ptr-1) ) jsuper = EMPTY; + + /* Always start a new supernode for a singular column */ + if ( nextl == jptr ) jsuper = EMPTY; + + /* Make sure the number of columns in a supernode doesn't + exceed threshold. */ + if ( jcol - fsupc >= maxsuper ) jsuper = EMPTY; + + /* If jcol starts a new supernode, reclaim storage space in + * lsub from the previous supernode. Note we only store + * the subscript set of the first columns of the supernode. + */ + if ( jsuper == EMPTY ) { /* starts a new supernode */ + if ( (fsupc < jcolm1) ) { /* >= 2 columns in nsuper */ +#ifdef CHK_COMPRESS + printf(" Compress lsub[] at super %d-%d\n", fsupc, jcolm1); +#endif + ito = xlsub[fsupc+1]; + xlsub[jcolm1] = ito; + xlsub[jcol] = ito; + for (ifrom = jptr; ifrom < nextl; ++ifrom, ++ito) + lsub[ito] = lsub[ifrom]; + nextl = ito; + } + nsuper++; + supno[jcol] = nsuper; + } /* if a new supernode */ + + } /* else: jcol > 0 */ + + /* Tidy up the pointers before exit */ + xsup[nsuper+1] = jcolp1; + supno[jcolp1] = nsuper; + xlsub[jcolp1] = nextl; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_dcopy_to_ucol.c b/src/Libraries/superlu-5.2.1/SRC/ilu_dcopy_to_ucol.c new file mode 100644 index 00000000..2bb889c3 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_dcopy_to_ucol.c @@ -0,0 +1,217 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_dcopy_to_ucol.c + * \brief Copy a computed column of U to the compressed data structure + * and drop some small entries + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Lawrence Berkeley National Laboratory
+ * November, 2010
+ * 
+ */ + +#include "slu_ddefs.h" + +#ifdef DEBUG +int num_drop_U; +#endif + +extern void dcopy_(int *, double [], int *, double [], int *); + +#if 0 +static double *A; /* used in _compare_ only */ +static int _compare_(const void *a, const void *b) +{ + register int *x = (int *)a, *y = (int *)b; + register double xx = fabs(A[*x]), yy = fabs(A[*y]); + if (xx > yy) return -1; + else if (xx < yy) return 1; + else return 0; +} +#endif + +int +ilu_dcopy_to_ucol( + int jcol, /* in */ + int nseg, /* in */ + int *segrep, /* in */ + int *repfnz, /* in */ + int *perm_r, /* in */ + double *dense, /* modified - reset to zero on return */ + int drop_rule,/* in */ + milu_t milu, /* in */ + double drop_tol, /* in */ + int quota, /* maximum nonzero entries allowed */ + double *sum, /* out - the sum of dropped entries */ + int *nnzUj, /* in - out */ + GlobalLU_t *Glu, /* modified */ + double *work /* working space with minimum size n, + * used by the second dropping rule */ + ) +{ +/* + * Gather from SPA dense[*] to global ucol[*]. + */ + int ksub, krep, ksupno; + int i, k, kfnz, segsze; + int fsupc, isub, irow; + int jsupno, nextu; + int new_next, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + double *ucol; + int *usub, *xusub; + int nzumax; + int m; /* number of entries in the nonzero U-segments */ + register double d_max = 0.0, d_min = 1.0 / dmach("Safe minimum"); + register double tmp; + double zero = 0.0; + int i_1 = 1; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + ucol = (double *) Glu->ucol; + usub = Glu->usub; + xusub = Glu->xusub; + nzumax = Glu->nzumax; + + *sum = zero; + if (drop_rule == NODROP) { + drop_tol = -1.0, quota = Glu->n; + } + + jsupno = supno[jcol]; + nextu = xusub[jcol]; + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { + krep = segrep[k--]; + ksupno = supno[krep]; + + if ( ksupno != jsupno ) { /* Should go into ucol[] */ + kfnz = repfnz[krep]; + if ( kfnz != EMPTY ) { /* Nonzero U-segment */ + + fsupc = xsup[ksupno]; + isub = xlsub[fsupc] + kfnz - fsupc; + segsze = krep - kfnz + 1; + + new_next = nextu + segsze; + while ( new_next > nzumax ) { + if ((mem_error = dLUMemXpand(jcol, nextu, UCOL, &nzumax, + Glu)) != 0) + return (mem_error); + ucol = Glu->ucol; + if ((mem_error = dLUMemXpand(jcol, nextu, USUB, &nzumax, + Glu)) != 0) + return (mem_error); + usub = Glu->usub; + lsub = Glu->lsub; + } + + for (i = 0; i < segsze; i++) { + irow = lsub[isub++]; + tmp = fabs(dense[irow]); + + /* first dropping rule */ + if (quota > 0 && tmp >= drop_tol) { + if (tmp > d_max) d_max = tmp; + if (tmp < d_min) d_min = tmp; + usub[nextu] = perm_r[irow]; + ucol[nextu] = dense[irow]; + nextu++; + } else { + switch (milu) { + case SMILU_1: + case SMILU_2: + *sum += dense[irow]; + break; + case SMILU_3: + /* *sum += fabs(dense[irow]);*/ + *sum += tmp; + break; + case SILU: + default: + break; + } +#ifdef DEBUG + num_drop_U++; +#endif + } + dense[irow] = zero; + } + + } + + } + + } /* for each segment... */ + + xusub[jcol + 1] = nextu; /* Close U[*,jcol] */ + m = xusub[jcol + 1] - xusub[jcol]; + + /* second dropping rule */ + if (drop_rule & DROP_SECONDARY && m > quota) { + register double tol = d_max; + register int m0 = xusub[jcol] + m - 1; + + if (quota > 0) { + if (drop_rule & DROP_INTERP) { + d_max = 1.0 / d_max; d_min = 1.0 / d_min; + tol = 1.0 / (d_max + (d_min - d_max) * quota / m); + } else { + dcopy_(&m, &ucol[xusub[jcol]], &i_1, work, &i_1); + tol = dqselect(m, work, quota); +#if 0 + A = &ucol[xusub[jcol]]; + for (i = 0; i < m; i++) work[i] = i; + qsort(work, m, sizeof(int), _compare_); + tol = fabs(usub[xusub[jcol] + work[quota]]); +#endif + } + } + for (i = xusub[jcol]; i <= m0; ) { + if (fabs(ucol[i]) <= tol) { + switch (milu) { + case SMILU_1: + case SMILU_2: + *sum += ucol[i]; + break; + case SMILU_3: + *sum += fabs(ucol[i]); + break; + case SILU: + default: + break; + } + ucol[i] = ucol[m0]; + usub[i] = usub[m0]; + m0--; + m--; +#ifdef DEBUG + num_drop_U++; +#endif + xusub[jcol + 1]--; + continue; + } + i++; + } + } + + if (milu == SMILU_2) *sum = fabs(*sum); + + *nnzUj += m; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_ddrop_row.c b/src/Libraries/superlu-5.2.1/SRC/ilu_ddrop_row.c new file mode 100644 index 00000000..f25b5085 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_ddrop_row.c @@ -0,0 +1,339 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_ddrop_row.c + * \brief Drop small rows from L + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ + +#include +#include +#include "slu_ddefs.h" + +extern void dswap_(int *, double [], int *, double [], int *); +extern void daxpy_(int *, double *, double [], int *, double [], int *); +extern void dcopy_(int *, double [], int *, double [], int *); +extern double dasum_(int *, double *, int *); +extern double dnrm2_(int *, double *, int *); +extern double dnrm2_(int *, double [], int *); +extern int idamax_(int *, double [], int *); + +static double *A; /* used in _compare_ only */ +static int _compare_(const void *a, const void *b) +{ + register int *x = (int *)a, *y = (int *)b; + if (A[*x] - A[*y] > 0.0) return -1; + else if (A[*x] - A[*y] < 0.0) return 1; + else return 0; +} + +/*! \brief + *
+ * Purpose
+ * =======
+ *    ilu_ddrop_row() - Drop some small rows from the previous 
+ *    supernode (L-part only).
+ * 
+ */ +int ilu_ddrop_row( + superlu_options_t *options, /* options */ + int first, /* index of the first column in the supernode */ + int last, /* index of the last column in the supernode */ + double drop_tol, /* dropping parameter */ + int quota, /* maximum nonzero entries allowed */ + int *nnzLj, /* in/out number of nonzeros in L(:, 1:last) */ + double *fill_tol, /* in/out - on exit, fill_tol=-num_zero_pivots, + * does not change if options->ILU_MILU != SMILU1 */ + GlobalLU_t *Glu, /* modified */ + double dwork[], /* working space + * the length of dwork[] should be no less than + * the number of rows in the supernode */ + double dwork2[], /* working space with the same size as dwork[], + * used only by the second dropping rule */ + int lastc /* if lastc == 0, there is nothing after the + * working supernode [first:last]; + * if lastc == 1, there is one more column after + * the working supernode. */ ) +{ + register int i, j, k, m1; + register int nzlc; /* number of nonzeros in column last+1 */ + register int xlusup_first, xlsub_first; + int m, n; /* m x n is the size of the supernode */ + int r = 0; /* number of dropped rows */ + register double *temp; + register double *lusup = (double *) Glu->lusup; + register int *lsub = Glu->lsub; + register int *xlsub = Glu->xlsub; + register int *xlusup = Glu->xlusup; + register double d_max = 0.0, d_min = 1.0; + int drop_rule = options->ILU_DropRule; + milu_t milu = options->ILU_MILU; + norm_t nrm = options->ILU_Norm; + double zero = 0.0; + double one = 1.0; + double none = -1.0; + int i_1 = 1; + int inc_diag; /* inc_diag = m + 1 */ + int nzp = 0; /* number of zero pivots */ + double alpha = pow((double)(Glu->n), -1.0 / options->ILU_MILU_Dim); + + xlusup_first = xlusup[first]; + xlsub_first = xlsub[first]; + m = xlusup[first + 1] - xlusup_first; + n = last - first + 1; + m1 = m - 1; + inc_diag = m + 1; + nzlc = lastc ? (xlusup[last + 2] - xlusup[last + 1]) : 0; + temp = dwork - n; + + /* Quick return if nothing to do. */ + if (m == 0 || m == n || drop_rule == NODROP) + { + *nnzLj += m * n; + return 0; + } + + /* basic dropping: ILU(tau) */ + for (i = n; i <= m1; ) + { + /* the average abs value of ith row */ + switch (nrm) + { + case ONE_NORM: + temp[i] = dasum_(&n, &lusup[xlusup_first + i], &m) / (double)n; + break; + case TWO_NORM: + temp[i] = dnrm2_(&n, &lusup[xlusup_first + i], &m) + / sqrt((double)n); + break; + case INF_NORM: + default: + k = idamax_(&n, &lusup[xlusup_first + i], &m) - 1; + temp[i] = fabs(lusup[xlusup_first + i + m * k]); + break; + } + + /* drop small entries due to drop_tol */ + if (drop_rule & DROP_BASIC && temp[i] < drop_tol) + { + r++; + /* drop the current row and move the last undropped row here */ + if (r > 1) /* add to last row */ + { + /* accumulate the sum (for MILU) */ + switch (milu) + { + case SMILU_1: + case SMILU_2: + daxpy_(&n, &one, &lusup[xlusup_first + i], &m, + &lusup[xlusup_first + m - 1], &m); + break; + case SMILU_3: + for (j = 0; j < n; j++) + lusup[xlusup_first + (m - 1) + j * m] += + fabs(lusup[xlusup_first + i + j * m]); + break; + case SILU: + default: + break; + } + dcopy_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + } /* if (r > 1) */ + else /* move to last row */ + { + dswap_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + if (milu == SMILU_3) + for (j = 0; j < n; j++) { + lusup[xlusup_first + m1 + j * m] = + fabs(lusup[xlusup_first + m1 + j * m]); + } + } + lsub[xlsub_first + i] = lsub[xlsub_first + m1]; + m1--; + continue; + } /* if dropping */ + else + { + if (temp[i] > d_max) d_max = temp[i]; + if (temp[i] < d_min) d_min = temp[i]; + } + i++; + } /* for */ + + /* Secondary dropping: drop more rows according to the quota. */ + quota = ceil((double)quota / (double)n); + if (drop_rule & DROP_SECONDARY && m - r > quota) + { + register double tol = d_max; + + /* Calculate the second dropping tolerance */ + if (quota > n) + { + if (drop_rule & DROP_INTERP) /* by interpolation */ + { + d_max = 1.0 / d_max; d_min = 1.0 / d_min; + tol = 1.0 / (d_max + (d_min - d_max) * quota / (m - n - r)); + } + else /* by quick select */ + { + int len = m1 - n + 1; + dcopy_(&len, dwork, &i_1, dwork2, &i_1); + tol = dqselect(len, dwork2, quota - n); +#if 0 + register int *itemp = iwork - n; + A = temp; + for (i = n; i <= m1; i++) itemp[i] = i; + qsort(iwork, m1 - n + 1, sizeof(int), _compare_); + tol = temp[itemp[quota]]; +#endif + } + } + + for (i = n; i <= m1; ) + { + if (temp[i] <= tol) + { + register int j; + r++; + /* drop the current row and move the last undropped row here */ + if (r > 1) /* add to last row */ + { + /* accumulate the sum (for MILU) */ + switch (milu) + { + case SMILU_1: + case SMILU_2: + daxpy_(&n, &one, &lusup[xlusup_first + i], &m, + &lusup[xlusup_first + m - 1], &m); + break; + case SMILU_3: + for (j = 0; j < n; j++) + lusup[xlusup_first + (m - 1) + j * m] += + fabs(lusup[xlusup_first + i + j * m]); + break; + case SILU: + default: + break; + } + dcopy_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + } /* if (r > 1) */ + else /* move to last row */ + { + dswap_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + if (milu == SMILU_3) + for (j = 0; j < n; j++) { + lusup[xlusup_first + m1 + j * m] = + fabs(lusup[xlusup_first + m1 + j * m]); + } + } + lsub[xlsub_first + i] = lsub[xlsub_first + m1]; + m1--; + temp[i] = temp[m1]; + + continue; + } + i++; + + } /* for */ + + } /* if secondary dropping */ + + for (i = n; i < m; i++) temp[i] = 0.0; + + if (r == 0) + { + *nnzLj += m * n; + return 0; + } + + /* add dropped entries to the diagnal */ + if (milu != SILU) + { + register int j; + double t; + double omega; + for (j = 0; j < n; j++) + { + t = lusup[xlusup_first + (m - 1) + j * m]; + if (t == zero) continue; + if (t > zero) + omega = SUPERLU_MIN(2.0 * (1.0 - alpha) / t, 1.0); + else + omega = SUPERLU_MAX(2.0 * (1.0 - alpha) / t, -1.0); + t *= omega; + + switch (milu) + { + case SMILU_1: + if (t != none) { + lusup[xlusup_first + j * inc_diag] *= (one + t); + } + else + { + lusup[xlusup_first + j * inc_diag] *= *fill_tol; +#ifdef DEBUG + printf("[1] ZERO PIVOT: FILL col %d.\n", first + j); + fflush(stdout); +#endif + nzp++; + } + break; + case SMILU_2: + lusup[xlusup_first + j * inc_diag] *= (1.0 + fabs(t)); + break; + case SMILU_3: + lusup[xlusup_first + j * inc_diag] *= (one + t); + break; + case SILU: + default: + break; + } + } + if (nzp > 0) *fill_tol = -nzp; + } + + /* Remove dropped entries from the memory and fix the pointers. */ + m1 = m - r; + for (j = 1; j < n; j++) + { + register int tmp1, tmp2; + tmp1 = xlusup_first + j * m1; + tmp2 = xlusup_first + j * m; + for (i = 0; i < m1; i++) + lusup[i + tmp1] = lusup[i + tmp2]; + } + for (i = 0; i < nzlc; i++) + lusup[xlusup_first + i + n * m1] = lusup[xlusup_first + i + n * m]; + for (i = 0; i < nzlc; i++) + lsub[xlsub[last + 1] - r + i] = lsub[xlsub[last + 1] + i]; + for (i = first + 1; i <= last + 1; i++) + { + xlusup[i] -= r * (i - first); + xlsub[i] -= r; + } + if (lastc) + { + xlusup[last + 2] -= r * n; + xlsub[last + 2] -= r; + } + + *nnzLj += (m - r) * n; + return r; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_dpanel_dfs.c b/src/Libraries/superlu-5.2.1/SRC/ilu_dpanel_dfs.c new file mode 100644 index 00000000..0d14b3ce --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_dpanel_dfs.c @@ -0,0 +1,258 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_dpanel_dfs.c + * \brief Peforms a symbolic factorization on a panel of symbols and + * record the entries with maximum absolute value in each column + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + +#include "slu_ddefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *   Performs a symbolic factorization on a panel of columns [jcol, jcol+w).
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives.
+ *
+ *   The routine returns one list of the supernodal representatives
+ *   in topological order of the dfs that generates them. This list is
+ *   a superset of the topological order of each individual column within
+ *   the panel.
+ *   The location of the first nonzero in each supernodal segment
+ *   (supernodal entry location) is also returned. Each column has a
+ *   separate list for this purpose.
+ *
+ *   Two marker arrays are used for dfs:
+ *     marker[i] == jj, if i was visited during dfs of current column jj;
+ *     marker1[i] >= jcol, if i was visited by earlier columns in this panel;
+ *
+ *   marker: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ * 
+ */ +void +ilu_dpanel_dfs( + const int m, /* in - number of rows in the matrix */ + const int w, /* in */ + const int jcol, /* in */ + SuperMatrix *A, /* in - original matrix */ + int *perm_r, /* in */ + int *nseg, /* out */ + double *dense, /* out */ + double *amax, /* out - max. abs. value of each column in panel */ + int *panel_lsub, /* out */ + int *segrep, /* out */ + int *repfnz, /* out */ + int *marker, /* out */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ +) +{ + + NCPformat *Astore; + double *a; + int *asub; + int *xa_begin, *xa_end; + int krep, chperm, chmark, chrep, oldrep, kchild, myfnz; + int k, krow, kmark, kperm; + int xdfs, maxdfs, kpar; + int jj; /* index through each column in the panel */ + int *marker1; /* marker1[jj] >= jcol if vertex jj was visited + by a previous column within this panel. */ + int *repfnz_col; /* start of each column in the panel */ + double *dense_col; /* start of each column in the panel */ + int nextl_col; /* next available position in panel_lsub[*,jj] */ + int *xsup, *supno; + int *lsub, *xlsub; + double *amax_col; + register double tmp; + + /* Initialize pointers */ + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + marker1 = marker + m; + repfnz_col = repfnz; + dense_col = dense; + amax_col = amax; + *nseg = 0; + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + + /* For each column in the panel */ + for (jj = jcol; jj < jcol + w; jj++) { + nextl_col = (jj - jcol) * m; + +#ifdef CHK_DFS + printf("\npanel col %d: ", jj); +#endif + + *amax_col = 0.0; + /* For each nonz in A[*,jj] do dfs */ + for (k = xa_begin[jj]; k < xa_end[jj]; k++) { + krow = asub[k]; + tmp = fabs(a[k]); + if (tmp > *amax_col) *amax_col = tmp; + dense_col[krow] = a[k]; + kmark = marker[krow]; + if ( kmark == jj ) + continue; /* krow visited before, go to the next nonzero */ + + /* For each unmarked nbr krow of jj + * krow is in L: place it in structure of L[*,jj] + */ + marker[krow] = jj; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + panel_lsub[nextl_col++] = krow; /* krow is indexed into A */ + } + /* + * krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + else { + + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz_col[krep]; + +#ifdef CHK_DFS + printf("krep %d, myfnz %d, perm_r[%d] %d\n", krep, myfnz, krow, kperm); +#endif + if ( myfnz != EMPTY ) { /* Representative visited before */ + if ( myfnz > kperm ) repfnz_col[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz_col[krep] = kperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; + +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker[kchild]; + + if ( chmark != jj ) { /* Not reached yet */ + marker[kchild] = jj; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,j] */ + if ( chperm == EMPTY ) { + panel_lsub[nextl_col++] = kchild; + } + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + else { + + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz_col[chrep]; +#ifdef CHK_DFS + printf("chrep %d,myfnz %d,perm_r[%d] %d\n",chrep,myfnz,kchild,chperm); +#endif + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz_col[chrep] = chperm; + } + else { + /* Cont. dfs at snode-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L) */ + parent[krep] = oldrep; + repfnz_col[krep] = chperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } /* else */ + + } /* else */ + + } /* if... */ + + } /* while xdfs < maxdfs */ + + /* krow has no more unexplored nbrs: + * Place snode-rep krep in postorder DFS, if this + * segment is seen for the first time. (Note that + * "repfnz[krep]" may change later.) + * Backtrack dfs to its parent. + */ + if ( marker1[krep] < jcol ) { + segrep[*nseg] = krep; + ++(*nseg); + marker1[krep] = jj; + } + + kpar = parent[krep]; /* Pop stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xlsub[krep + 1]; + +#ifdef CHK_DFS + printf(" pop stack: krep %d,xdfs %d,maxdfs %d: ", krep,xdfs,maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } while ( kpar != EMPTY ); /* do-while - until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonz in A[*,jj] */ + + repfnz_col += m; /* Move to next column */ + dense_col += m; + amax_col++; + + } /* for jj ... */ + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_dpivotL.c b/src/Libraries/superlu-5.2.1/SRC/ilu_dpivotL.c new file mode 100644 index 00000000..7afc630a --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_dpivotL.c @@ -0,0 +1,276 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_dpivotL.c + * \brief Performs numerical pivoting + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + + +#include +#include +#include "slu_ddefs.h" + +#ifndef SGN +#define SGN(x) ((x)>=0?1:-1) +#endif + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   Performs the numerical pivoting on the current column of L,
+ *   and the CDIV operation.
+ *
+ *   Pivot policy:
+ *   (1) Compute thresh = u * max_(i>=j) abs(A_ij);
+ *   (2) IF user specifies pivot row k and abs(A_kj) >= thresh THEN
+ *	     pivot row = k;
+ *	 ELSE IF abs(A_jj) >= thresh THEN
+ *	     pivot row = j;
+ *	 ELSE
+ *	     pivot row = m;
+ *
+ *   Note: If you absolutely want to use a given pivot order, then set u=0.0.
+ *
+ *   Return value: 0	  success;
+ *		   i > 0  U(i,i) is exactly zero.
+ * 
+ */ + +int +ilu_dpivotL( + const int jcol, /* in */ + const double u, /* in - diagonal pivoting threshold */ + int *usepr, /* re-use the pivot sequence given by + * perm_r/iperm_r */ + int *perm_r, /* may be modified */ + int diagind, /* diagonal of Pc*A*Pc' */ + int *swap, /* in/out record the row permutation */ + int *iswap, /* in/out inverse of swap, it is the same as + perm_r after the factorization */ + int *marker, /* in */ + int *pivrow, /* in/out, as an input if *usepr!=0 */ + double fill_tol, /* in - fill tolerance of current column + * used for a singular column */ + milu_t milu, /* in */ + double drop_sum, /* in - computed in ilu_dcopy_to_ucol() + (MILU only) */ + GlobalLU_t *Glu, /* modified - global LU data structures */ + SuperLUStat_t *stat /* output */ + ) +{ + + int n; /* number of columns */ + int fsupc; /* first column in the supernode */ + int nsupc; /* no of columns in the supernode */ + int nsupr; /* no of rows in the supernode */ + int lptr; /* points to the starting subscript of the supernode */ + register int pivptr; + int old_pivptr, diag, ptr0; + register double pivmax, rtemp; + double thresh; + double temp; + double *lu_sup_ptr; + double *lu_col_ptr; + int *lsub_ptr; + register int isub, icol, k, itemp; + int *lsub, *xlsub; + double *lusup; + int *xlusup; + flops_t *ops = stat->ops; + int info; + + /* Initialize pointers */ + n = Glu->n; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (double *) Glu->lusup; + xlusup = Glu->xlusup; + fsupc = (Glu->xsup)[(Glu->supno)[jcol]]; + nsupc = jcol - fsupc; /* excluding jcol; nsupc >= 0 */ + lptr = xlsub[fsupc]; + nsupr = xlsub[fsupc+1] - lptr; + lu_sup_ptr = &lusup[xlusup[fsupc]]; /* start of the current supernode */ + lu_col_ptr = &lusup[xlusup[jcol]]; /* start of jcol in the supernode */ + lsub_ptr = &lsub[lptr]; /* start of row indices of the supernode */ + + /* Determine the largest abs numerical value for partial pivoting; + Also search for user-specified pivot, and diagonal element. */ + pivmax = -1.0; + pivptr = nsupc; + diag = EMPTY; + old_pivptr = nsupc; + ptr0 = EMPTY; + for (isub = nsupc; isub < nsupr; ++isub) { + if (marker[lsub_ptr[isub]] > jcol) + continue; /* do not overlap with a later relaxed supernode */ + + switch (milu) { + case SMILU_1: + rtemp = fabs(lu_col_ptr[isub] + drop_sum); + break; + case SMILU_2: + case SMILU_3: + /* In this case, drop_sum contains the sum of the abs. value */ + rtemp = fabs(lu_col_ptr[isub]); + break; + case SILU: + default: + rtemp = fabs(lu_col_ptr[isub]); + break; + } + if (rtemp > pivmax) { pivmax = rtemp; pivptr = isub; } + if (*usepr && lsub_ptr[isub] == *pivrow) old_pivptr = isub; + if (lsub_ptr[isub] == diagind) diag = isub; + if (ptr0 == EMPTY) ptr0 = isub; + } + + if (milu == SMILU_2 || milu == SMILU_3) pivmax += drop_sum; + + /* Test for singularity */ + if (pivmax < 0.0) { + fprintf(stderr, "[0]: jcol=%d, SINGULAR!!!\n", jcol); + fflush(stderr); + exit(1); + } + if ( pivmax == 0.0 ) { + if (diag != EMPTY) + *pivrow = lsub_ptr[pivptr = diag]; + else if (ptr0 != EMPTY) + *pivrow = lsub_ptr[pivptr = ptr0]; + else { + /* look for the first row which does not + belong to any later supernodes */ + for (icol = jcol; icol < n; icol++) + if (marker[swap[icol]] <= jcol) break; + if (icol >= n) { + fprintf(stderr, "[1]: jcol=%d, SINGULAR!!!\n", jcol); + fflush(stderr); + exit(1); + } + + *pivrow = swap[icol]; + + /* pick up the pivot row */ + for (isub = nsupc; isub < nsupr; ++isub) + if ( lsub_ptr[isub] == *pivrow ) { pivptr = isub; break; } + } + pivmax = fill_tol; + lu_col_ptr[pivptr] = pivmax; + *usepr = 0; +#ifdef DEBUG + printf("[0] ZERO PIVOT: FILL (%d, %d).\n", *pivrow, jcol); + fflush(stdout); +#endif + info =jcol + 1; + } /* if (*pivrow == 0.0) */ + else { + thresh = u * pivmax; + + /* Choose appropriate pivotal element by our policy. */ + if ( *usepr ) { + switch (milu) { + case SMILU_1: + rtemp = fabs(lu_col_ptr[old_pivptr] + drop_sum); + break; + case SMILU_2: + case SMILU_3: + rtemp = fabs(lu_col_ptr[old_pivptr]) + drop_sum; + break; + case SILU: + default: + rtemp = fabs(lu_col_ptr[old_pivptr]); + break; + } + if ( rtemp != 0.0 && rtemp >= thresh ) pivptr = old_pivptr; + else *usepr = 0; + } + if ( *usepr == 0 ) { + /* Use diagonal pivot? */ + if ( diag >= 0 ) { /* diagonal exists */ + switch (milu) { + case SMILU_1: + rtemp = fabs(lu_col_ptr[diag] + drop_sum); + break; + case SMILU_2: + case SMILU_3: + rtemp = fabs(lu_col_ptr[diag]) + drop_sum; + break; + case SILU: + default: + rtemp = fabs(lu_col_ptr[diag]); + break; + } + if ( rtemp != 0.0 && rtemp >= thresh ) pivptr = diag; + } + *pivrow = lsub_ptr[pivptr]; + } + info = 0; + + /* Reset the diagonal */ + switch (milu) { + case SMILU_1: + lu_col_ptr[pivptr] += drop_sum; + break; + case SMILU_2: + case SMILU_3: + lu_col_ptr[pivptr] += SGN(lu_col_ptr[pivptr]) * drop_sum; + break; + case SILU: + default: + break; + } + + } /* else */ + + /* Record pivot row */ + perm_r[*pivrow] = jcol; + if (jcol < n - 1) { + register int t1, t2, t; + t1 = iswap[*pivrow]; t2 = jcol; + if (t1 != t2) { + t = swap[t1]; swap[t1] = swap[t2]; swap[t2] = t; + t1 = swap[t1]; t2 = t; + t = iswap[t1]; iswap[t1] = iswap[t2]; iswap[t2] = t; + } + } /* if (jcol < n - 1) */ + + /* Interchange row subscripts */ + if ( pivptr != nsupc ) { + itemp = lsub_ptr[pivptr]; + lsub_ptr[pivptr] = lsub_ptr[nsupc]; + lsub_ptr[nsupc] = itemp; + + /* Interchange numerical values as well, for the whole snode, such + * that L is indexed the same way as A. + */ + for (icol = 0; icol <= nsupc; icol++) { + itemp = pivptr + icol * nsupr; + temp = lu_sup_ptr[itemp]; + lu_sup_ptr[itemp] = lu_sup_ptr[nsupc + icol*nsupr]; + lu_sup_ptr[nsupc + icol*nsupr] = temp; + } + } /* if */ + + /* cdiv operation */ + ops[FACT] += nsupr - nsupc; + temp = 1.0 / lu_col_ptr[nsupc]; + for (k = nsupc+1; k < nsupr; k++) lu_col_ptr[k] *= temp; + + return info; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_dsnode_dfs.c b/src/Libraries/superlu-5.2.1/SRC/ilu_dsnode_dfs.c new file mode 100644 index 00000000..afcea29f --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_dsnode_dfs.c @@ -0,0 +1,100 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_dsnode_dfs.c + * \brief Determines the union of row structures of columns within the relaxed node + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + +#include "slu_ddefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *    ilu_dsnode_dfs() - Determine the union of the row structures of those
+ *    columns within the relaxed snode.
+ *    Note: The relaxed snodes are leaves of the supernodal etree, therefore,
+ *    the portion outside the rectangular supernode must be zero.
+ *
+ * Return value
+ * ============
+ *     0   success;
+ *    >0   number of bytes allocated when run out of memory.
+ * 
+ */ + +int +ilu_dsnode_dfs( + const int jcol, /* in - start of the supernode */ + const int kcol, /* in - end of the supernode */ + const int *asub, /* in */ + const int *xa_begin, /* in */ + const int *xa_end, /* in */ + int *marker, /* modified */ + GlobalLU_t *Glu /* modified */ + ) +{ + + register int i, k, nextl; + int nsuper, krow, kmark, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + int nzlmax; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + nsuper = ++supno[jcol]; /* Next available supernode number */ + nextl = xlsub[jcol]; + + for (i = jcol; i <= kcol; i++) + { + /* For each nonzero in A[*,i] */ + for (k = xa_begin[i]; k < xa_end[i]; k++) + { + krow = asub[k]; + kmark = marker[krow]; + if ( kmark != kcol ) + { /* First time visit krow */ + marker[krow] = kcol; + lsub[nextl++] = krow; + if ( nextl >= nzlmax ) + { + if ( (mem_error = dLUMemXpand(jcol, nextl, LSUB, &nzlmax, + Glu)) != 0) + return (mem_error); + lsub = Glu->lsub; + } + } + } + supno[i] = nsuper; + } + + /* Supernode > 1 */ + if ( jcol < kcol ) + for (i = jcol+1; i <= kcol; i++) xlsub[i] = nextl; + + xsup[nsuper+1] = kcol + 1; + supno[kcol+1] = nsuper; + xlsub[kcol+1] = nextl; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_heap_relax_snode.c b/src/Libraries/superlu-5.2.1/SRC/ilu_heap_relax_snode.c new file mode 100644 index 00000000..eccc08e7 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_heap_relax_snode.c @@ -0,0 +1,130 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file ilu_heap_relax_snode.c + * \brief Identify the initial relaxed supernodes + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 1, 2009
+ * 
+ */ + +#include "slu_ddefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *    ilu_heap_relax_snode() - Identify the initial relaxed supernodes,
+ *    assuming that the matrix has been reordered according to the postorder
+ *    of the etree.
+ * 
+ */ + +void +ilu_heap_relax_snode ( + const int n, + int *et, /* column elimination tree */ + const int relax_columns, /* max no of columns allowed in a + relaxed snode */ + int *descendants, /* no of descendants of each node + in the etree */ + int *relax_end, /* last column in a supernode + * if j-th column starts a relaxed + * supernode, relax_end[j] represents + * the last column of this supernode */ + int *relax_fsupc /* first column in a supernode + * relax_fsupc[j] represents the first + * column of j-th supernode */ + ) +{ + register int i, j, k, l, f, parent; + register int snode_start; /* beginning of a snode */ + int *et_save, *post, *inv_post, *iwork; + int nsuper_et = 0, nsuper_et_post = 0; + + /* The etree may not be postordered, but is heap ordered. */ + + iwork = (int*) intMalloc(3*n+2); + if ( !iwork ) ABORT("SUPERLU_MALLOC fails for iwork[]"); + inv_post = iwork + n+1; + et_save = inv_post + n+1; + + /* Post order etree */ + post = (int *) TreePostorder(n, et); + for (i = 0; i < n+1; ++i) inv_post[post[i]] = i; + + /* Renumber etree in postorder */ + for (i = 0; i < n; ++i) { + iwork[post[i]] = post[et[i]]; + et_save[i] = et[i]; /* Save the original etree */ + } + for (i = 0; i < n; ++i) et[i] = iwork[i]; + + /* Compute the number of descendants of each node in the etree */ + ifill (relax_end, n, EMPTY); + ifill (relax_fsupc, n, EMPTY); + for (j = 0; j < n; j++) descendants[j] = 0; + for (j = 0; j < n; j++) { + parent = et[j]; + if ( parent != n ) /* not the dummy root */ + descendants[parent] += descendants[j] + 1; + } + + /* Identify the relaxed supernodes by postorder traversal of the etree. */ + for ( f = j = 0; j < n; ) { + parent = et[j]; + snode_start = j; + while ( parent != n && descendants[parent] < relax_columns ) { + j = parent; + parent = et[j]; + } + /* Found a supernode in postordered etree; j is the last column. */ + ++nsuper_et_post; + k = n; + for (i = snode_start; i <= j; ++i) + k = SUPERLU_MIN(k, inv_post[i]); + l = inv_post[j]; + if ( (l - k) == (j - snode_start) ) { + /* It's also a supernode in the original etree */ + relax_end[k] = l; /* Last column is recorded */ + relax_fsupc[f++] = k; + ++nsuper_et; + } else { + for (i = snode_start; i <= j; ++i) { + l = inv_post[i]; + if ( descendants[i] == 0 ) { + relax_end[l] = l; + relax_fsupc[f++] = l; + ++nsuper_et; + } + } + } + j++; + /* Search for a new leaf */ + while ( descendants[j] != 0 && j < n ) j++; + } + +#if ( PRNTlevel>=1 ) + printf(".. heap_snode_relax:\n" + "\tNo of relaxed snodes in postordered etree:\t%d\n" + "\tNo of relaxed snodes in original etree:\t%d\n", + nsuper_et_post, nsuper_et); +#endif + + /* Recover the original etree */ + for (i = 0; i < n; ++i) et[i] = et_save[i]; + + SUPERLU_FREE(post); + SUPERLU_FREE(iwork); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_relax_snode.c b/src/Libraries/superlu-5.2.1/SRC/ilu_relax_snode.c new file mode 100644 index 00000000..0cfd030c --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_relax_snode.c @@ -0,0 +1,79 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file ilu_relax_snode.c + * \brief Identify initial relaxed supernodes + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 1, 2009
+ * 
+ */ + +#include "slu_ddefs.h" +/*! \brief + * + *
+ * Purpose
+ * =======
+ *    ilu_relax_snode() - Identify the initial relaxed supernodes, assuming
+ *    that the matrix has been reordered according to the postorder of the
+ *    etree.
+ * 
+ */ +void +ilu_relax_snode ( + const int n, + int *et, /* column elimination tree */ + const int relax_columns, /* max no of columns allowed in a + relaxed snode */ + int *descendants, /* no of descendants of each node + in the etree */ + int *relax_end, /* last column in a supernode + * if j-th column starts a relaxed + * supernode, relax_end[j] represents + * the last column of this supernode */ + int *relax_fsupc /* first column in a supernode + * relax_fsupc[j] represents the first + * column of j-th supernode */ + ) +{ + + register int j, f, parent; + register int snode_start; /* beginning of a snode */ + + ifill (relax_end, n, EMPTY); + ifill (relax_fsupc, n, EMPTY); + for (j = 0; j < n; j++) descendants[j] = 0; + + /* Compute the number of descendants of each node in the etree */ + for (j = 0; j < n; j++) { + parent = et[j]; + if ( parent != n ) /* not the dummy root */ + descendants[parent] += descendants[j] + 1; + } + + /* Identify the relaxed supernodes by postorder traversal of the etree. */ + for (j = f = 0; j < n; ) { + parent = et[j]; + snode_start = j; + while ( parent != n && descendants[parent] < relax_columns ) { + j = parent; + parent = et[j]; + } + /* Found a supernode with j being the last column. */ + relax_end[snode_start] = j; /* Last column is recorded */ + j++; + relax_fsupc[f++] = snode_start; + /* Search for a new leaf */ + while ( descendants[j] != 0 && j < n ) j++; + } +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_scolumn_dfs.c b/src/Libraries/superlu-5.2.1/SRC/ilu_scolumn_dfs.c new file mode 100644 index 00000000..d767a074 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_scolumn_dfs.c @@ -0,0 +1,265 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_scolumn_dfs.c + * \brief Performs a symbolic factorization + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+*/ + +#include "slu_sdefs.h" + + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   ILU_SCOLUMN_DFS performs a symbolic factorization on column jcol, and
+ *   decide the supernode boundary.
+ *
+ *   This routine does not use numeric values, but only use the RHS
+ *   row indices to start the dfs.
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives. The routine returns a list of such supernodal
+ *   representatives in topological order of the dfs that generates them.
+ *   The location of the first nonzero in each such supernodal segment
+ *   (supernodal entry location) is also returned.
+ *
+ * Local parameters
+ * ================
+ *   nseg: no of segments in current U[*,j]
+ *   jsuper: jsuper=EMPTY if column j does not belong to the same
+ *	supernode as j-1. Otherwise, jsuper=nsuper.
+ *
+ *   marker2: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ *
+ * Return value
+ * ============
+ *     0  success;
+ *   > 0  number of bytes allocated when run out of space.
+ * 
+ */ +int +ilu_scolumn_dfs( + const int m, /* in - number of rows in the matrix */ + const int jcol, /* in */ + int *perm_r, /* in */ + int *nseg, /* modified - with new segments appended */ + int *lsub_col, /* in - defines the RHS vector to start the + dfs */ + int *segrep, /* modified - with new segments appended */ + int *repfnz, /* modified */ + int *marker, /* modified */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ + ) +{ + + int jcolp1, jcolm1, jsuper, nsuper, nextl; + int k, krep, krow, kmark, kperm; + int *marker2; /* Used for small panel LU */ + int fsupc; /* First column of a snode */ + int myfnz; /* First nonz column of a U-segment */ + int chperm, chmark, chrep, kchild; + int xdfs, maxdfs, kpar, oldrep; + int jptr, jm1ptr; + int ito, ifrom; /* Used to compress row subscripts */ + int mem_error; + int *xsup, *supno, *lsub, *xlsub; + int nzlmax; + int maxsuper; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + maxsuper = sp_ienv(7); + jcolp1 = jcol + 1; + jcolm1 = jcol - 1; + nsuper = supno[jcol]; + jsuper = nsuper; + nextl = xlsub[jcol]; + marker2 = &marker[2*m]; + + + /* For each nonzero in A[*,jcol] do dfs */ + for (k = 0; lsub_col[k] != EMPTY; k++) { + + krow = lsub_col[k]; + lsub_col[k] = EMPTY; + kmark = marker2[krow]; + + /* krow was visited before, go to the next nonzero */ + if ( kmark == jcol ) continue; + + /* For each unmarked nbr krow of jcol + * krow is in L: place it in structure of L[*,jcol] + */ + marker2[krow] = jcol; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + lsub[nextl++] = krow; /* krow is indexed into A */ + if ( nextl >= nzlmax ) { + if ((mem_error = sLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu))) + return (mem_error); + lsub = Glu->lsub; + } + if ( kmark != jcolm1 ) jsuper = EMPTY;/* Row index subset testing */ + } else { + /* krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz[krep]; + + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > kperm ) repfnz[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz[krep] = kperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; + + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker2[kchild]; + + if ( chmark != jcol ) { /* Not reached yet */ + marker2[kchild] = jcol; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,k] */ + if ( chperm == EMPTY ) { + lsub[nextl++] = kchild; + if ( nextl >= nzlmax ) { + if ( (mem_error = sLUMemXpand(jcol,nextl, + LSUB,&nzlmax,Glu)) ) + return (mem_error); + lsub = Glu->lsub; + } + if ( chmark != jcolm1 ) jsuper = EMPTY; + } else { + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz[chrep]; + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz[chrep] = chperm; + } else { + /* Continue dfs at super-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L^t) */ + parent[krep] = oldrep; + repfnz[krep] = chperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; + } /* else */ + + } /* else */ + + } /* if */ + + } /* while */ + + /* krow has no more unexplored nbrs; + * place supernode-rep krep in postorder DFS. + * backtrack dfs to its parent + */ + segrep[*nseg] = krep; + ++(*nseg); + kpar = parent[krep]; /* Pop from stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xlsub[krep + 1]; + + } while ( kpar != EMPTY ); /* Until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonzero ... */ + + /* Check to see if j belongs in the same supernode as j-1 */ + if ( jcol == 0 ) { /* Do nothing for column 0 */ + nsuper = supno[0] = 0; + } else { + fsupc = xsup[nsuper]; + jptr = xlsub[jcol]; /* Not compressed yet */ + jm1ptr = xlsub[jcolm1]; + + if ( (nextl-jptr != jptr-jm1ptr-1) ) jsuper = EMPTY; + + /* Always start a new supernode for a singular column */ + if ( nextl == jptr ) jsuper = EMPTY; + + /* Make sure the number of columns in a supernode doesn't + exceed threshold. */ + if ( jcol - fsupc >= maxsuper ) jsuper = EMPTY; + + /* If jcol starts a new supernode, reclaim storage space in + * lsub from the previous supernode. Note we only store + * the subscript set of the first columns of the supernode. + */ + if ( jsuper == EMPTY ) { /* starts a new supernode */ + if ( (fsupc < jcolm1) ) { /* >= 2 columns in nsuper */ +#ifdef CHK_COMPRESS + printf(" Compress lsub[] at super %d-%d\n", fsupc, jcolm1); +#endif + ito = xlsub[fsupc+1]; + xlsub[jcolm1] = ito; + xlsub[jcol] = ito; + for (ifrom = jptr; ifrom < nextl; ++ifrom, ++ito) + lsub[ito] = lsub[ifrom]; + nextl = ito; + } + nsuper++; + supno[jcol] = nsuper; + } /* if a new supernode */ + + } /* else: jcol > 0 */ + + /* Tidy up the pointers before exit */ + xsup[nsuper+1] = jcolp1; + supno[jcolp1] = nsuper; + xlsub[jcolp1] = nextl; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_scopy_to_ucol.c b/src/Libraries/superlu-5.2.1/SRC/ilu_scopy_to_ucol.c new file mode 100644 index 00000000..6dc0460c --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_scopy_to_ucol.c @@ -0,0 +1,217 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_scopy_to_ucol.c + * \brief Copy a computed column of U to the compressed data structure + * and drop some small entries + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Lawrence Berkeley National Laboratory
+ * November, 2010
+ * 
+ */ + +#include "slu_sdefs.h" + +#ifdef DEBUG +int num_drop_U; +#endif + +extern void scopy_(int *, float [], int *, float [], int *); + +#if 0 +static float *A; /* used in _compare_ only */ +static int _compare_(const void *a, const void *b) +{ + register int *x = (int *)a, *y = (int *)b; + register double xx = fabs(A[*x]), yy = fabs(A[*y]); + if (xx > yy) return -1; + else if (xx < yy) return 1; + else return 0; +} +#endif + +int +ilu_scopy_to_ucol( + int jcol, /* in */ + int nseg, /* in */ + int *segrep, /* in */ + int *repfnz, /* in */ + int *perm_r, /* in */ + float *dense, /* modified - reset to zero on return */ + int drop_rule,/* in */ + milu_t milu, /* in */ + double drop_tol, /* in */ + int quota, /* maximum nonzero entries allowed */ + float *sum, /* out - the sum of dropped entries */ + int *nnzUj, /* in - out */ + GlobalLU_t *Glu, /* modified */ + float *work /* working space with minimum size n, + * used by the second dropping rule */ + ) +{ +/* + * Gather from SPA dense[*] to global ucol[*]. + */ + int ksub, krep, ksupno; + int i, k, kfnz, segsze; + int fsupc, isub, irow; + int jsupno, nextu; + int new_next, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + float *ucol; + int *usub, *xusub; + int nzumax; + int m; /* number of entries in the nonzero U-segments */ + register float d_max = 0.0, d_min = 1.0 / smach("Safe minimum"); + register double tmp; + float zero = 0.0; + int i_1 = 1; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + ucol = (float *) Glu->ucol; + usub = Glu->usub; + xusub = Glu->xusub; + nzumax = Glu->nzumax; + + *sum = zero; + if (drop_rule == NODROP) { + drop_tol = -1.0, quota = Glu->n; + } + + jsupno = supno[jcol]; + nextu = xusub[jcol]; + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { + krep = segrep[k--]; + ksupno = supno[krep]; + + if ( ksupno != jsupno ) { /* Should go into ucol[] */ + kfnz = repfnz[krep]; + if ( kfnz != EMPTY ) { /* Nonzero U-segment */ + + fsupc = xsup[ksupno]; + isub = xlsub[fsupc] + kfnz - fsupc; + segsze = krep - kfnz + 1; + + new_next = nextu + segsze; + while ( new_next > nzumax ) { + if ((mem_error = sLUMemXpand(jcol, nextu, UCOL, &nzumax, + Glu)) != 0) + return (mem_error); + ucol = Glu->ucol; + if ((mem_error = sLUMemXpand(jcol, nextu, USUB, &nzumax, + Glu)) != 0) + return (mem_error); + usub = Glu->usub; + lsub = Glu->lsub; + } + + for (i = 0; i < segsze; i++) { + irow = lsub[isub++]; + tmp = fabs(dense[irow]); + + /* first dropping rule */ + if (quota > 0 && tmp >= drop_tol) { + if (tmp > d_max) d_max = tmp; + if (tmp < d_min) d_min = tmp; + usub[nextu] = perm_r[irow]; + ucol[nextu] = dense[irow]; + nextu++; + } else { + switch (milu) { + case SMILU_1: + case SMILU_2: + *sum += dense[irow]; + break; + case SMILU_3: + /* *sum += fabs(dense[irow]);*/ + *sum += tmp; + break; + case SILU: + default: + break; + } +#ifdef DEBUG + num_drop_U++; +#endif + } + dense[irow] = zero; + } + + } + + } + + } /* for each segment... */ + + xusub[jcol + 1] = nextu; /* Close U[*,jcol] */ + m = xusub[jcol + 1] - xusub[jcol]; + + /* second dropping rule */ + if (drop_rule & DROP_SECONDARY && m > quota) { + register double tol = d_max; + register int m0 = xusub[jcol] + m - 1; + + if (quota > 0) { + if (drop_rule & DROP_INTERP) { + d_max = 1.0 / d_max; d_min = 1.0 / d_min; + tol = 1.0 / (d_max + (d_min - d_max) * quota / m); + } else { + scopy_(&m, &ucol[xusub[jcol]], &i_1, work, &i_1); + tol = sqselect(m, work, quota); +#if 0 + A = &ucol[xusub[jcol]]; + for (i = 0; i < m; i++) work[i] = i; + qsort(work, m, sizeof(int), _compare_); + tol = fabs(usub[xusub[jcol] + work[quota]]); +#endif + } + } + for (i = xusub[jcol]; i <= m0; ) { + if (fabs(ucol[i]) <= tol) { + switch (milu) { + case SMILU_1: + case SMILU_2: + *sum += ucol[i]; + break; + case SMILU_3: + *sum += fabs(ucol[i]); + break; + case SILU: + default: + break; + } + ucol[i] = ucol[m0]; + usub[i] = usub[m0]; + m0--; + m--; +#ifdef DEBUG + num_drop_U++; +#endif + xusub[jcol + 1]--; + continue; + } + i++; + } + } + + if (milu == SMILU_2) *sum = fabs(*sum); + + *nnzUj += m; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_sdrop_row.c b/src/Libraries/superlu-5.2.1/SRC/ilu_sdrop_row.c new file mode 100644 index 00000000..836ee545 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_sdrop_row.c @@ -0,0 +1,339 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_sdrop_row.c + * \brief Drop small rows from L + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ + +#include +#include +#include "slu_sdefs.h" + +extern void sswap_(int *, float [], int *, float [], int *); +extern void saxpy_(int *, float *, float [], int *, float [], int *); +extern void scopy_(int *, float [], int *, float [], int *); +extern float sasum_(int *, float *, int *); +extern float snrm2_(int *, float *, int *); +extern double dnrm2_(int *, double [], int *); +extern int isamax_(int *, float [], int *); + +static float *A; /* used in _compare_ only */ +static int _compare_(const void *a, const void *b) +{ + register int *x = (int *)a, *y = (int *)b; + if (A[*x] - A[*y] > 0.0) return -1; + else if (A[*x] - A[*y] < 0.0) return 1; + else return 0; +} + +/*! \brief + *
+ * Purpose
+ * =======
+ *    ilu_sdrop_row() - Drop some small rows from the previous 
+ *    supernode (L-part only).
+ * 
+ */ +int ilu_sdrop_row( + superlu_options_t *options, /* options */ + int first, /* index of the first column in the supernode */ + int last, /* index of the last column in the supernode */ + double drop_tol, /* dropping parameter */ + int quota, /* maximum nonzero entries allowed */ + int *nnzLj, /* in/out number of nonzeros in L(:, 1:last) */ + double *fill_tol, /* in/out - on exit, fill_tol=-num_zero_pivots, + * does not change if options->ILU_MILU != SMILU1 */ + GlobalLU_t *Glu, /* modified */ + float swork[], /* working space + * the length of swork[] should be no less than + * the number of rows in the supernode */ + float swork2[], /* working space with the same size as swork[], + * used only by the second dropping rule */ + int lastc /* if lastc == 0, there is nothing after the + * working supernode [first:last]; + * if lastc == 1, there is one more column after + * the working supernode. */ ) +{ + register int i, j, k, m1; + register int nzlc; /* number of nonzeros in column last+1 */ + register int xlusup_first, xlsub_first; + int m, n; /* m x n is the size of the supernode */ + int r = 0; /* number of dropped rows */ + register float *temp; + register float *lusup = (float *) Glu->lusup; + register int *lsub = Glu->lsub; + register int *xlsub = Glu->xlsub; + register int *xlusup = Glu->xlusup; + register float d_max = 0.0, d_min = 1.0; + int drop_rule = options->ILU_DropRule; + milu_t milu = options->ILU_MILU; + norm_t nrm = options->ILU_Norm; + float zero = 0.0; + float one = 1.0; + float none = -1.0; + int i_1 = 1; + int inc_diag; /* inc_diag = m + 1 */ + int nzp = 0; /* number of zero pivots */ + float alpha = pow((double)(Glu->n), -1.0 / options->ILU_MILU_Dim); + + xlusup_first = xlusup[first]; + xlsub_first = xlsub[first]; + m = xlusup[first + 1] - xlusup_first; + n = last - first + 1; + m1 = m - 1; + inc_diag = m + 1; + nzlc = lastc ? (xlusup[last + 2] - xlusup[last + 1]) : 0; + temp = swork - n; + + /* Quick return if nothing to do. */ + if (m == 0 || m == n || drop_rule == NODROP) + { + *nnzLj += m * n; + return 0; + } + + /* basic dropping: ILU(tau) */ + for (i = n; i <= m1; ) + { + /* the average abs value of ith row */ + switch (nrm) + { + case ONE_NORM: + temp[i] = sasum_(&n, &lusup[xlusup_first + i], &m) / (double)n; + break; + case TWO_NORM: + temp[i] = snrm2_(&n, &lusup[xlusup_first + i], &m) + / sqrt((double)n); + break; + case INF_NORM: + default: + k = isamax_(&n, &lusup[xlusup_first + i], &m) - 1; + temp[i] = fabs(lusup[xlusup_first + i + m * k]); + break; + } + + /* drop small entries due to drop_tol */ + if (drop_rule & DROP_BASIC && temp[i] < drop_tol) + { + r++; + /* drop the current row and move the last undropped row here */ + if (r > 1) /* add to last row */ + { + /* accumulate the sum (for MILU) */ + switch (milu) + { + case SMILU_1: + case SMILU_2: + saxpy_(&n, &one, &lusup[xlusup_first + i], &m, + &lusup[xlusup_first + m - 1], &m); + break; + case SMILU_3: + for (j = 0; j < n; j++) + lusup[xlusup_first + (m - 1) + j * m] += + fabs(lusup[xlusup_first + i + j * m]); + break; + case SILU: + default: + break; + } + scopy_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + } /* if (r > 1) */ + else /* move to last row */ + { + sswap_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + if (milu == SMILU_3) + for (j = 0; j < n; j++) { + lusup[xlusup_first + m1 + j * m] = + fabs(lusup[xlusup_first + m1 + j * m]); + } + } + lsub[xlsub_first + i] = lsub[xlsub_first + m1]; + m1--; + continue; + } /* if dropping */ + else + { + if (temp[i] > d_max) d_max = temp[i]; + if (temp[i] < d_min) d_min = temp[i]; + } + i++; + } /* for */ + + /* Secondary dropping: drop more rows according to the quota. */ + quota = ceil((double)quota / (double)n); + if (drop_rule & DROP_SECONDARY && m - r > quota) + { + register double tol = d_max; + + /* Calculate the second dropping tolerance */ + if (quota > n) + { + if (drop_rule & DROP_INTERP) /* by interpolation */ + { + d_max = 1.0 / d_max; d_min = 1.0 / d_min; + tol = 1.0 / (d_max + (d_min - d_max) * quota / (m - n - r)); + } + else /* by quick select */ + { + int len = m1 - n + 1; + scopy_(&len, swork, &i_1, swork2, &i_1); + tol = sqselect(len, swork2, quota - n); +#if 0 + register int *itemp = iwork - n; + A = temp; + for (i = n; i <= m1; i++) itemp[i] = i; + qsort(iwork, m1 - n + 1, sizeof(int), _compare_); + tol = temp[itemp[quota]]; +#endif + } + } + + for (i = n; i <= m1; ) + { + if (temp[i] <= tol) + { + register int j; + r++; + /* drop the current row and move the last undropped row here */ + if (r > 1) /* add to last row */ + { + /* accumulate the sum (for MILU) */ + switch (milu) + { + case SMILU_1: + case SMILU_2: + saxpy_(&n, &one, &lusup[xlusup_first + i], &m, + &lusup[xlusup_first + m - 1], &m); + break; + case SMILU_3: + for (j = 0; j < n; j++) + lusup[xlusup_first + (m - 1) + j * m] += + fabs(lusup[xlusup_first + i + j * m]); + break; + case SILU: + default: + break; + } + scopy_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + } /* if (r > 1) */ + else /* move to last row */ + { + sswap_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + if (milu == SMILU_3) + for (j = 0; j < n; j++) { + lusup[xlusup_first + m1 + j * m] = + fabs(lusup[xlusup_first + m1 + j * m]); + } + } + lsub[xlsub_first + i] = lsub[xlsub_first + m1]; + m1--; + temp[i] = temp[m1]; + + continue; + } + i++; + + } /* for */ + + } /* if secondary dropping */ + + for (i = n; i < m; i++) temp[i] = 0.0; + + if (r == 0) + { + *nnzLj += m * n; + return 0; + } + + /* add dropped entries to the diagnal */ + if (milu != SILU) + { + register int j; + float t; + float omega; + for (j = 0; j < n; j++) + { + t = lusup[xlusup_first + (m - 1) + j * m]; + if (t == zero) continue; + if (t > zero) + omega = SUPERLU_MIN(2.0 * (1.0 - alpha) / t, 1.0); + else + omega = SUPERLU_MAX(2.0 * (1.0 - alpha) / t, -1.0); + t *= omega; + + switch (milu) + { + case SMILU_1: + if (t != none) { + lusup[xlusup_first + j * inc_diag] *= (one + t); + } + else + { + lusup[xlusup_first + j * inc_diag] *= *fill_tol; +#ifdef DEBUG + printf("[1] ZERO PIVOT: FILL col %d.\n", first + j); + fflush(stdout); +#endif + nzp++; + } + break; + case SMILU_2: + lusup[xlusup_first + j * inc_diag] *= (1.0 + fabs(t)); + break; + case SMILU_3: + lusup[xlusup_first + j * inc_diag] *= (one + t); + break; + case SILU: + default: + break; + } + } + if (nzp > 0) *fill_tol = -nzp; + } + + /* Remove dropped entries from the memory and fix the pointers. */ + m1 = m - r; + for (j = 1; j < n; j++) + { + register int tmp1, tmp2; + tmp1 = xlusup_first + j * m1; + tmp2 = xlusup_first + j * m; + for (i = 0; i < m1; i++) + lusup[i + tmp1] = lusup[i + tmp2]; + } + for (i = 0; i < nzlc; i++) + lusup[xlusup_first + i + n * m1] = lusup[xlusup_first + i + n * m]; + for (i = 0; i < nzlc; i++) + lsub[xlsub[last + 1] - r + i] = lsub[xlsub[last + 1] + i]; + for (i = first + 1; i <= last + 1; i++) + { + xlusup[i] -= r * (i - first); + xlsub[i] -= r; + } + if (lastc) + { + xlusup[last + 2] -= r * n; + xlsub[last + 2] -= r; + } + + *nnzLj += (m - r) * n; + return r; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_spanel_dfs.c b/src/Libraries/superlu-5.2.1/SRC/ilu_spanel_dfs.c new file mode 100644 index 00000000..8a6bf6fd --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_spanel_dfs.c @@ -0,0 +1,258 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_spanel_dfs.c + * \brief Peforms a symbolic factorization on a panel of symbols and + * record the entries with maximum absolute value in each column + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + +#include "slu_sdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *   Performs a symbolic factorization on a panel of columns [jcol, jcol+w).
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives.
+ *
+ *   The routine returns one list of the supernodal representatives
+ *   in topological order of the dfs that generates them. This list is
+ *   a superset of the topological order of each individual column within
+ *   the panel.
+ *   The location of the first nonzero in each supernodal segment
+ *   (supernodal entry location) is also returned. Each column has a
+ *   separate list for this purpose.
+ *
+ *   Two marker arrays are used for dfs:
+ *     marker[i] == jj, if i was visited during dfs of current column jj;
+ *     marker1[i] >= jcol, if i was visited by earlier columns in this panel;
+ *
+ *   marker: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ * 
+ */ +void +ilu_spanel_dfs( + const int m, /* in - number of rows in the matrix */ + const int w, /* in */ + const int jcol, /* in */ + SuperMatrix *A, /* in - original matrix */ + int *perm_r, /* in */ + int *nseg, /* out */ + float *dense, /* out */ + float *amax, /* out - max. abs. value of each column in panel */ + int *panel_lsub, /* out */ + int *segrep, /* out */ + int *repfnz, /* out */ + int *marker, /* out */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ +) +{ + + NCPformat *Astore; + float *a; + int *asub; + int *xa_begin, *xa_end; + int krep, chperm, chmark, chrep, oldrep, kchild, myfnz; + int k, krow, kmark, kperm; + int xdfs, maxdfs, kpar; + int jj; /* index through each column in the panel */ + int *marker1; /* marker1[jj] >= jcol if vertex jj was visited + by a previous column within this panel. */ + int *repfnz_col; /* start of each column in the panel */ + float *dense_col; /* start of each column in the panel */ + int nextl_col; /* next available position in panel_lsub[*,jj] */ + int *xsup, *supno; + int *lsub, *xlsub; + float *amax_col; + register double tmp; + + /* Initialize pointers */ + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + marker1 = marker + m; + repfnz_col = repfnz; + dense_col = dense; + amax_col = amax; + *nseg = 0; + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + + /* For each column in the panel */ + for (jj = jcol; jj < jcol + w; jj++) { + nextl_col = (jj - jcol) * m; + +#ifdef CHK_DFS + printf("\npanel col %d: ", jj); +#endif + + *amax_col = 0.0; + /* For each nonz in A[*,jj] do dfs */ + for (k = xa_begin[jj]; k < xa_end[jj]; k++) { + krow = asub[k]; + tmp = fabs(a[k]); + if (tmp > *amax_col) *amax_col = tmp; + dense_col[krow] = a[k]; + kmark = marker[krow]; + if ( kmark == jj ) + continue; /* krow visited before, go to the next nonzero */ + + /* For each unmarked nbr krow of jj + * krow is in L: place it in structure of L[*,jj] + */ + marker[krow] = jj; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + panel_lsub[nextl_col++] = krow; /* krow is indexed into A */ + } + /* + * krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + else { + + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz_col[krep]; + +#ifdef CHK_DFS + printf("krep %d, myfnz %d, perm_r[%d] %d\n", krep, myfnz, krow, kperm); +#endif + if ( myfnz != EMPTY ) { /* Representative visited before */ + if ( myfnz > kperm ) repfnz_col[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz_col[krep] = kperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; + +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker[kchild]; + + if ( chmark != jj ) { /* Not reached yet */ + marker[kchild] = jj; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,j] */ + if ( chperm == EMPTY ) { + panel_lsub[nextl_col++] = kchild; + } + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + else { + + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz_col[chrep]; +#ifdef CHK_DFS + printf("chrep %d,myfnz %d,perm_r[%d] %d\n",chrep,myfnz,kchild,chperm); +#endif + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz_col[chrep] = chperm; + } + else { + /* Cont. dfs at snode-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L) */ + parent[krep] = oldrep; + repfnz_col[krep] = chperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } /* else */ + + } /* else */ + + } /* if... */ + + } /* while xdfs < maxdfs */ + + /* krow has no more unexplored nbrs: + * Place snode-rep krep in postorder DFS, if this + * segment is seen for the first time. (Note that + * "repfnz[krep]" may change later.) + * Backtrack dfs to its parent. + */ + if ( marker1[krep] < jcol ) { + segrep[*nseg] = krep; + ++(*nseg); + marker1[krep] = jj; + } + + kpar = parent[krep]; /* Pop stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xlsub[krep + 1]; + +#ifdef CHK_DFS + printf(" pop stack: krep %d,xdfs %d,maxdfs %d: ", krep,xdfs,maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } while ( kpar != EMPTY ); /* do-while - until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonz in A[*,jj] */ + + repfnz_col += m; /* Move to next column */ + dense_col += m; + amax_col++; + + } /* for jj ... */ + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_spivotL.c b/src/Libraries/superlu-5.2.1/SRC/ilu_spivotL.c new file mode 100644 index 00000000..f0db8dab --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_spivotL.c @@ -0,0 +1,276 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_spivotL.c + * \brief Performs numerical pivoting + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + + +#include +#include +#include "slu_sdefs.h" + +#ifndef SGN +#define SGN(x) ((x)>=0?1:-1) +#endif + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   Performs the numerical pivoting on the current column of L,
+ *   and the CDIV operation.
+ *
+ *   Pivot policy:
+ *   (1) Compute thresh = u * max_(i>=j) abs(A_ij);
+ *   (2) IF user specifies pivot row k and abs(A_kj) >= thresh THEN
+ *	     pivot row = k;
+ *	 ELSE IF abs(A_jj) >= thresh THEN
+ *	     pivot row = j;
+ *	 ELSE
+ *	     pivot row = m;
+ *
+ *   Note: If you absolutely want to use a given pivot order, then set u=0.0.
+ *
+ *   Return value: 0	  success;
+ *		   i > 0  U(i,i) is exactly zero.
+ * 
+ */ + +int +ilu_spivotL( + const int jcol, /* in */ + const double u, /* in - diagonal pivoting threshold */ + int *usepr, /* re-use the pivot sequence given by + * perm_r/iperm_r */ + int *perm_r, /* may be modified */ + int diagind, /* diagonal of Pc*A*Pc' */ + int *swap, /* in/out record the row permutation */ + int *iswap, /* in/out inverse of swap, it is the same as + perm_r after the factorization */ + int *marker, /* in */ + int *pivrow, /* in/out, as an input if *usepr!=0 */ + double fill_tol, /* in - fill tolerance of current column + * used for a singular column */ + milu_t milu, /* in */ + float drop_sum, /* in - computed in ilu_scopy_to_ucol() + (MILU only) */ + GlobalLU_t *Glu, /* modified - global LU data structures */ + SuperLUStat_t *stat /* output */ + ) +{ + + int n; /* number of columns */ + int fsupc; /* first column in the supernode */ + int nsupc; /* no of columns in the supernode */ + int nsupr; /* no of rows in the supernode */ + int lptr; /* points to the starting subscript of the supernode */ + register int pivptr; + int old_pivptr, diag, ptr0; + register float pivmax, rtemp; + float thresh; + float temp; + float *lu_sup_ptr; + float *lu_col_ptr; + int *lsub_ptr; + register int isub, icol, k, itemp; + int *lsub, *xlsub; + float *lusup; + int *xlusup; + flops_t *ops = stat->ops; + int info; + + /* Initialize pointers */ + n = Glu->n; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (float *) Glu->lusup; + xlusup = Glu->xlusup; + fsupc = (Glu->xsup)[(Glu->supno)[jcol]]; + nsupc = jcol - fsupc; /* excluding jcol; nsupc >= 0 */ + lptr = xlsub[fsupc]; + nsupr = xlsub[fsupc+1] - lptr; + lu_sup_ptr = &lusup[xlusup[fsupc]]; /* start of the current supernode */ + lu_col_ptr = &lusup[xlusup[jcol]]; /* start of jcol in the supernode */ + lsub_ptr = &lsub[lptr]; /* start of row indices of the supernode */ + + /* Determine the largest abs numerical value for partial pivoting; + Also search for user-specified pivot, and diagonal element. */ + pivmax = -1.0; + pivptr = nsupc; + diag = EMPTY; + old_pivptr = nsupc; + ptr0 = EMPTY; + for (isub = nsupc; isub < nsupr; ++isub) { + if (marker[lsub_ptr[isub]] > jcol) + continue; /* do not overlap with a later relaxed supernode */ + + switch (milu) { + case SMILU_1: + rtemp = fabs(lu_col_ptr[isub] + drop_sum); + break; + case SMILU_2: + case SMILU_3: + /* In this case, drop_sum contains the sum of the abs. value */ + rtemp = fabs(lu_col_ptr[isub]); + break; + case SILU: + default: + rtemp = fabs(lu_col_ptr[isub]); + break; + } + if (rtemp > pivmax) { pivmax = rtemp; pivptr = isub; } + if (*usepr && lsub_ptr[isub] == *pivrow) old_pivptr = isub; + if (lsub_ptr[isub] == diagind) diag = isub; + if (ptr0 == EMPTY) ptr0 = isub; + } + + if (milu == SMILU_2 || milu == SMILU_3) pivmax += drop_sum; + + /* Test for singularity */ + if (pivmax < 0.0) { + fprintf(stderr, "[0]: jcol=%d, SINGULAR!!!\n", jcol); + fflush(stderr); + exit(1); + } + if ( pivmax == 0.0 ) { + if (diag != EMPTY) + *pivrow = lsub_ptr[pivptr = diag]; + else if (ptr0 != EMPTY) + *pivrow = lsub_ptr[pivptr = ptr0]; + else { + /* look for the first row which does not + belong to any later supernodes */ + for (icol = jcol; icol < n; icol++) + if (marker[swap[icol]] <= jcol) break; + if (icol >= n) { + fprintf(stderr, "[1]: jcol=%d, SINGULAR!!!\n", jcol); + fflush(stderr); + exit(1); + } + + *pivrow = swap[icol]; + + /* pick up the pivot row */ + for (isub = nsupc; isub < nsupr; ++isub) + if ( lsub_ptr[isub] == *pivrow ) { pivptr = isub; break; } + } + pivmax = fill_tol; + lu_col_ptr[pivptr] = pivmax; + *usepr = 0; +#ifdef DEBUG + printf("[0] ZERO PIVOT: FILL (%d, %d).\n", *pivrow, jcol); + fflush(stdout); +#endif + info =jcol + 1; + } /* if (*pivrow == 0.0) */ + else { + thresh = u * pivmax; + + /* Choose appropriate pivotal element by our policy. */ + if ( *usepr ) { + switch (milu) { + case SMILU_1: + rtemp = fabs(lu_col_ptr[old_pivptr] + drop_sum); + break; + case SMILU_2: + case SMILU_3: + rtemp = fabs(lu_col_ptr[old_pivptr]) + drop_sum; + break; + case SILU: + default: + rtemp = fabs(lu_col_ptr[old_pivptr]); + break; + } + if ( rtemp != 0.0 && rtemp >= thresh ) pivptr = old_pivptr; + else *usepr = 0; + } + if ( *usepr == 0 ) { + /* Use diagonal pivot? */ + if ( diag >= 0 ) { /* diagonal exists */ + switch (milu) { + case SMILU_1: + rtemp = fabs(lu_col_ptr[diag] + drop_sum); + break; + case SMILU_2: + case SMILU_3: + rtemp = fabs(lu_col_ptr[diag]) + drop_sum; + break; + case SILU: + default: + rtemp = fabs(lu_col_ptr[diag]); + break; + } + if ( rtemp != 0.0 && rtemp >= thresh ) pivptr = diag; + } + *pivrow = lsub_ptr[pivptr]; + } + info = 0; + + /* Reset the diagonal */ + switch (milu) { + case SMILU_1: + lu_col_ptr[pivptr] += drop_sum; + break; + case SMILU_2: + case SMILU_3: + lu_col_ptr[pivptr] += SGN(lu_col_ptr[pivptr]) * drop_sum; + break; + case SILU: + default: + break; + } + + } /* else */ + + /* Record pivot row */ + perm_r[*pivrow] = jcol; + if (jcol < n - 1) { + register int t1, t2, t; + t1 = iswap[*pivrow]; t2 = jcol; + if (t1 != t2) { + t = swap[t1]; swap[t1] = swap[t2]; swap[t2] = t; + t1 = swap[t1]; t2 = t; + t = iswap[t1]; iswap[t1] = iswap[t2]; iswap[t2] = t; + } + } /* if (jcol < n - 1) */ + + /* Interchange row subscripts */ + if ( pivptr != nsupc ) { + itemp = lsub_ptr[pivptr]; + lsub_ptr[pivptr] = lsub_ptr[nsupc]; + lsub_ptr[nsupc] = itemp; + + /* Interchange numerical values as well, for the whole snode, such + * that L is indexed the same way as A. + */ + for (icol = 0; icol <= nsupc; icol++) { + itemp = pivptr + icol * nsupr; + temp = lu_sup_ptr[itemp]; + lu_sup_ptr[itemp] = lu_sup_ptr[nsupc + icol*nsupr]; + lu_sup_ptr[nsupc + icol*nsupr] = temp; + } + } /* if */ + + /* cdiv operation */ + ops[FACT] += nsupr - nsupc; + temp = 1.0 / lu_col_ptr[nsupc]; + for (k = nsupc+1; k < nsupr; k++) lu_col_ptr[k] *= temp; + + return info; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_ssnode_dfs.c b/src/Libraries/superlu-5.2.1/SRC/ilu_ssnode_dfs.c new file mode 100644 index 00000000..33ea02b6 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_ssnode_dfs.c @@ -0,0 +1,100 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_ssnode_dfs.c + * \brief Determines the union of row structures of columns within the relaxed node + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + +#include "slu_sdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *    ilu_ssnode_dfs() - Determine the union of the row structures of those
+ *    columns within the relaxed snode.
+ *    Note: The relaxed snodes are leaves of the supernodal etree, therefore,
+ *    the portion outside the rectangular supernode must be zero.
+ *
+ * Return value
+ * ============
+ *     0   success;
+ *    >0   number of bytes allocated when run out of memory.
+ * 
+ */ + +int +ilu_ssnode_dfs( + const int jcol, /* in - start of the supernode */ + const int kcol, /* in - end of the supernode */ + const int *asub, /* in */ + const int *xa_begin, /* in */ + const int *xa_end, /* in */ + int *marker, /* modified */ + GlobalLU_t *Glu /* modified */ + ) +{ + + register int i, k, nextl; + int nsuper, krow, kmark, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + int nzlmax; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + nsuper = ++supno[jcol]; /* Next available supernode number */ + nextl = xlsub[jcol]; + + for (i = jcol; i <= kcol; i++) + { + /* For each nonzero in A[*,i] */ + for (k = xa_begin[i]; k < xa_end[i]; k++) + { + krow = asub[k]; + kmark = marker[krow]; + if ( kmark != kcol ) + { /* First time visit krow */ + marker[krow] = kcol; + lsub[nextl++] = krow; + if ( nextl >= nzlmax ) + { + if ( (mem_error = sLUMemXpand(jcol, nextl, LSUB, &nzlmax, + Glu)) != 0) + return (mem_error); + lsub = Glu->lsub; + } + } + } + supno[i] = nsuper; + } + + /* Supernode > 1 */ + if ( jcol < kcol ) + for (i = jcol+1; i <= kcol; i++) xlsub[i] = nextl; + + xsup[nsuper+1] = kcol + 1; + supno[kcol+1] = nsuper; + xlsub[kcol+1] = nextl; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_zcolumn_dfs.c b/src/Libraries/superlu-5.2.1/SRC/ilu_zcolumn_dfs.c new file mode 100644 index 00000000..bc0d68e6 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_zcolumn_dfs.c @@ -0,0 +1,265 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_zcolumn_dfs.c + * \brief Performs a symbolic factorization + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+*/ + +#include "slu_zdefs.h" + + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   ILU_ZCOLUMN_DFS performs a symbolic factorization on column jcol, and
+ *   decide the supernode boundary.
+ *
+ *   This routine does not use numeric values, but only use the RHS
+ *   row indices to start the dfs.
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives. The routine returns a list of such supernodal
+ *   representatives in topological order of the dfs that generates them.
+ *   The location of the first nonzero in each such supernodal segment
+ *   (supernodal entry location) is also returned.
+ *
+ * Local parameters
+ * ================
+ *   nseg: no of segments in current U[*,j]
+ *   jsuper: jsuper=EMPTY if column j does not belong to the same
+ *	supernode as j-1. Otherwise, jsuper=nsuper.
+ *
+ *   marker2: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ *
+ * Return value
+ * ============
+ *     0  success;
+ *   > 0  number of bytes allocated when run out of space.
+ * 
+ */ +int +ilu_zcolumn_dfs( + const int m, /* in - number of rows in the matrix */ + const int jcol, /* in */ + int *perm_r, /* in */ + int *nseg, /* modified - with new segments appended */ + int *lsub_col, /* in - defines the RHS vector to start the + dfs */ + int *segrep, /* modified - with new segments appended */ + int *repfnz, /* modified */ + int *marker, /* modified */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ + ) +{ + + int jcolp1, jcolm1, jsuper, nsuper, nextl; + int k, krep, krow, kmark, kperm; + int *marker2; /* Used for small panel LU */ + int fsupc; /* First column of a snode */ + int myfnz; /* First nonz column of a U-segment */ + int chperm, chmark, chrep, kchild; + int xdfs, maxdfs, kpar, oldrep; + int jptr, jm1ptr; + int ito, ifrom; /* Used to compress row subscripts */ + int mem_error; + int *xsup, *supno, *lsub, *xlsub; + int nzlmax; + int maxsuper; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + maxsuper = sp_ienv(7); + jcolp1 = jcol + 1; + jcolm1 = jcol - 1; + nsuper = supno[jcol]; + jsuper = nsuper; + nextl = xlsub[jcol]; + marker2 = &marker[2*m]; + + + /* For each nonzero in A[*,jcol] do dfs */ + for (k = 0; lsub_col[k] != EMPTY; k++) { + + krow = lsub_col[k]; + lsub_col[k] = EMPTY; + kmark = marker2[krow]; + + /* krow was visited before, go to the next nonzero */ + if ( kmark == jcol ) continue; + + /* For each unmarked nbr krow of jcol + * krow is in L: place it in structure of L[*,jcol] + */ + marker2[krow] = jcol; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + lsub[nextl++] = krow; /* krow is indexed into A */ + if ( nextl >= nzlmax ) { + if ((mem_error = zLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu))) + return (mem_error); + lsub = Glu->lsub; + } + if ( kmark != jcolm1 ) jsuper = EMPTY;/* Row index subset testing */ + } else { + /* krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz[krep]; + + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > kperm ) repfnz[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz[krep] = kperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; + + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker2[kchild]; + + if ( chmark != jcol ) { /* Not reached yet */ + marker2[kchild] = jcol; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,k] */ + if ( chperm == EMPTY ) { + lsub[nextl++] = kchild; + if ( nextl >= nzlmax ) { + if ( (mem_error = zLUMemXpand(jcol,nextl, + LSUB,&nzlmax,Glu)) ) + return (mem_error); + lsub = Glu->lsub; + } + if ( chmark != jcolm1 ) jsuper = EMPTY; + } else { + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz[chrep]; + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz[chrep] = chperm; + } else { + /* Continue dfs at super-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L^t) */ + parent[krep] = oldrep; + repfnz[krep] = chperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; + } /* else */ + + } /* else */ + + } /* if */ + + } /* while */ + + /* krow has no more unexplored nbrs; + * place supernode-rep krep in postorder DFS. + * backtrack dfs to its parent + */ + segrep[*nseg] = krep; + ++(*nseg); + kpar = parent[krep]; /* Pop from stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xlsub[krep + 1]; + + } while ( kpar != EMPTY ); /* Until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonzero ... */ + + /* Check to see if j belongs in the same supernode as j-1 */ + if ( jcol == 0 ) { /* Do nothing for column 0 */ + nsuper = supno[0] = 0; + } else { + fsupc = xsup[nsuper]; + jptr = xlsub[jcol]; /* Not compressed yet */ + jm1ptr = xlsub[jcolm1]; + + if ( (nextl-jptr != jptr-jm1ptr-1) ) jsuper = EMPTY; + + /* Always start a new supernode for a singular column */ + if ( nextl == jptr ) jsuper = EMPTY; + + /* Make sure the number of columns in a supernode doesn't + exceed threshold. */ + if ( jcol - fsupc >= maxsuper ) jsuper = EMPTY; + + /* If jcol starts a new supernode, reclaim storage space in + * lsub from the previous supernode. Note we only store + * the subscript set of the first columns of the supernode. + */ + if ( jsuper == EMPTY ) { /* starts a new supernode */ + if ( (fsupc < jcolm1) ) { /* >= 2 columns in nsuper */ +#ifdef CHK_COMPRESS + printf(" Compress lsub[] at super %d-%d\n", fsupc, jcolm1); +#endif + ito = xlsub[fsupc+1]; + xlsub[jcolm1] = ito; + xlsub[jcol] = ito; + for (ifrom = jptr; ifrom < nextl; ++ifrom, ++ito) + lsub[ito] = lsub[ifrom]; + nextl = ito; + } + nsuper++; + supno[jcol] = nsuper; + } /* if a new supernode */ + + } /* else: jcol > 0 */ + + /* Tidy up the pointers before exit */ + xsup[nsuper+1] = jcolp1; + supno[jcolp1] = nsuper; + xlsub[jcolp1] = nextl; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_zcopy_to_ucol.c b/src/Libraries/superlu-5.2.1/SRC/ilu_zcopy_to_ucol.c new file mode 100644 index 00000000..afe4a7e0 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_zcopy_to_ucol.c @@ -0,0 +1,221 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_zcopy_to_ucol.c + * \brief Copy a computed column of U to the compressed data structure + * and drop some small entries + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Lawrence Berkeley National Laboratory
+ * November, 2010
+ * 
+ */ + +#include "slu_zdefs.h" + +#ifdef DEBUG +int num_drop_U; +#endif + +extern void zcopy_(int *, doublecomplex [], int *, doublecomplex [], int *); + +#if 0 +static doublecomplex *A; /* used in _compare_ only */ +static int _compare_(const void *a, const void *b) +{ + register int *x = (int *)a, *y = (int *)b; + register double xx = z_abs1(&A[*x]), yy = z_abs1(&A[*y]); + if (xx > yy) return -1; + else if (xx < yy) return 1; + else return 0; +} +#endif + +int +ilu_zcopy_to_ucol( + int jcol, /* in */ + int nseg, /* in */ + int *segrep, /* in */ + int *repfnz, /* in */ + int *perm_r, /* in */ + doublecomplex *dense, /* modified - reset to zero on return */ + int drop_rule,/* in */ + milu_t milu, /* in */ + double drop_tol, /* in */ + int quota, /* maximum nonzero entries allowed */ + doublecomplex *sum, /* out - the sum of dropped entries */ + int *nnzUj, /* in - out */ + GlobalLU_t *Glu, /* modified */ + double *work /* working space with minimum size n, + * used by the second dropping rule */ + ) +{ +/* + * Gather from SPA dense[*] to global ucol[*]. + */ + int ksub, krep, ksupno; + int i, k, kfnz, segsze; + int fsupc, isub, irow; + int jsupno, nextu; + int new_next, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + doublecomplex *ucol; + int *usub, *xusub; + int nzumax; + int m; /* number of entries in the nonzero U-segments */ + register double d_max = 0.0, d_min = 1.0 / dmach("Safe minimum"); + register double tmp; + doublecomplex zero = {0.0, 0.0}; + int i_1 = 1; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + ucol = (doublecomplex *) Glu->ucol; + usub = Glu->usub; + xusub = Glu->xusub; + nzumax = Glu->nzumax; + + *sum = zero; + if (drop_rule == NODROP) { + drop_tol = -1.0, quota = Glu->n; + } + + jsupno = supno[jcol]; + nextu = xusub[jcol]; + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { + krep = segrep[k--]; + ksupno = supno[krep]; + + if ( ksupno != jsupno ) { /* Should go into ucol[] */ + kfnz = repfnz[krep]; + if ( kfnz != EMPTY ) { /* Nonzero U-segment */ + + fsupc = xsup[ksupno]; + isub = xlsub[fsupc] + kfnz - fsupc; + segsze = krep - kfnz + 1; + + new_next = nextu + segsze; + while ( new_next > nzumax ) { + if ((mem_error = zLUMemXpand(jcol, nextu, UCOL, &nzumax, + Glu)) != 0) + return (mem_error); + ucol = Glu->ucol; + if ((mem_error = zLUMemXpand(jcol, nextu, USUB, &nzumax, + Glu)) != 0) + return (mem_error); + usub = Glu->usub; + lsub = Glu->lsub; + } + + for (i = 0; i < segsze; i++) { + irow = lsub[isub++]; + tmp = z_abs1(&dense[irow]); + + /* first dropping rule */ + if (quota > 0 && tmp >= drop_tol) { + if (tmp > d_max) d_max = tmp; + if (tmp < d_min) d_min = tmp; + usub[nextu] = perm_r[irow]; + ucol[nextu] = dense[irow]; + nextu++; + } else { + switch (milu) { + case SMILU_1: + case SMILU_2: + z_add(sum, sum, &dense[irow]); + break; + case SMILU_3: + /* *sum += fabs(dense[irow]);*/ + sum->r += tmp; + break; + case SILU: + default: + break; + } +#ifdef DEBUG + num_drop_U++; +#endif + } + dense[irow] = zero; + } + + } + + } + + } /* for each segment... */ + + xusub[jcol + 1] = nextu; /* Close U[*,jcol] */ + m = xusub[jcol + 1] - xusub[jcol]; + + /* second dropping rule */ + if (drop_rule & DROP_SECONDARY && m > quota) { + register double tol = d_max; + register int m0 = xusub[jcol] + m - 1; + + if (quota > 0) { + if (drop_rule & DROP_INTERP) { + d_max = 1.0 / d_max; d_min = 1.0 / d_min; + tol = 1.0 / (d_max + (d_min - d_max) * quota / m); + } else { + i_1 = xusub[jcol]; + for (i = 0; i < m; ++i, ++i_1) work[i] = z_abs1(&ucol[i_1]); + tol = dqselect(m, work, quota); +#if 0 + A = &ucol[xusub[jcol]]; + for (i = 0; i < m; i++) work[i] = i; + qsort(work, m, sizeof(int), _compare_); + tol = fabs(usub[xusub[jcol] + work[quota]]); +#endif + } + } + for (i = xusub[jcol]; i <= m0; ) { + if (z_abs1(&ucol[i]) <= tol) { + switch (milu) { + case SMILU_1: + case SMILU_2: + z_add(sum, sum, &ucol[i]); + break; + case SMILU_3: + sum->r += tmp; + break; + case SILU: + default: + break; + } + ucol[i] = ucol[m0]; + usub[i] = usub[m0]; + m0--; + m--; +#ifdef DEBUG + num_drop_U++; +#endif + xusub[jcol + 1]--; + continue; + } + i++; + } + } + + if (milu == SMILU_2) { + sum->r = z_abs1(sum); sum->i = 0.0; + } + if (milu == SMILU_3) sum->i = 0.0; + + *nnzUj += m; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_zdrop_row.c b/src/Libraries/superlu-5.2.1/SRC/ilu_zdrop_row.c new file mode 100644 index 00000000..f434dd98 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_zdrop_row.c @@ -0,0 +1,349 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_zdrop_row.c + * \brief Drop small rows from L + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ + +#include +#include +#include "slu_zdefs.h" + +extern void zswap_(int *, doublecomplex [], int *, doublecomplex [], int *); +extern void zaxpy_(int *, doublecomplex *, doublecomplex [], int *, doublecomplex [], int *); +extern void zcopy_(int *, doublecomplex [], int *, doublecomplex [], int *); +extern double dzasum_(int *, doublecomplex *, int *); +extern double dznrm2_(int *, doublecomplex *, int *); +extern double dnrm2_(int *, double [], int *); +extern int izamax_(int *, doublecomplex [], int *); + +static double *A; /* used in _compare_ only */ +static int _compare_(const void *a, const void *b) +{ + register int *x = (int *)a, *y = (int *)b; + if (A[*x] - A[*y] > 0.0) return -1; + else if (A[*x] - A[*y] < 0.0) return 1; + else return 0; +} + +/*! \brief + *
+ * Purpose
+ * =======
+ *    ilu_zdrop_row() - Drop some small rows from the previous 
+ *    supernode (L-part only).
+ * 
+ */ +int ilu_zdrop_row( + superlu_options_t *options, /* options */ + int first, /* index of the first column in the supernode */ + int last, /* index of the last column in the supernode */ + double drop_tol, /* dropping parameter */ + int quota, /* maximum nonzero entries allowed */ + int *nnzLj, /* in/out number of nonzeros in L(:, 1:last) */ + double *fill_tol, /* in/out - on exit, fill_tol=-num_zero_pivots, + * does not change if options->ILU_MILU != SMILU1 */ + GlobalLU_t *Glu, /* modified */ + double dwork[], /* working space + * the length of dwork[] should be no less than + * the number of rows in the supernode */ + double dwork2[], /* working space with the same size as dwork[], + * used only by the second dropping rule */ + int lastc /* if lastc == 0, there is nothing after the + * working supernode [first:last]; + * if lastc == 1, there is one more column after + * the working supernode. */ ) +{ + register int i, j, k, m1; + register int nzlc; /* number of nonzeros in column last+1 */ + register int xlusup_first, xlsub_first; + int m, n; /* m x n is the size of the supernode */ + int r = 0; /* number of dropped rows */ + register double *temp; + register doublecomplex *lusup = (doublecomplex *) Glu->lusup; + register int *lsub = Glu->lsub; + register int *xlsub = Glu->xlsub; + register int *xlusup = Glu->xlusup; + register double d_max = 0.0, d_min = 1.0; + int drop_rule = options->ILU_DropRule; + milu_t milu = options->ILU_MILU; + norm_t nrm = options->ILU_Norm; + doublecomplex zero = {0.0, 0.0}; + doublecomplex one = {1.0, 0.0}; + doublecomplex none = {-1.0, 0.0}; + int i_1 = 1; + int inc_diag; /* inc_diag = m + 1 */ + int nzp = 0; /* number of zero pivots */ + double alpha = pow((double)(Glu->n), -1.0 / options->ILU_MILU_Dim); + + xlusup_first = xlusup[first]; + xlsub_first = xlsub[first]; + m = xlusup[first + 1] - xlusup_first; + n = last - first + 1; + m1 = m - 1; + inc_diag = m + 1; + nzlc = lastc ? (xlusup[last + 2] - xlusup[last + 1]) : 0; + temp = dwork - n; + + /* Quick return if nothing to do. */ + if (m == 0 || m == n || drop_rule == NODROP) + { + *nnzLj += m * n; + return 0; + } + + /* basic dropping: ILU(tau) */ + for (i = n; i <= m1; ) + { + /* the average abs value of ith row */ + switch (nrm) + { + case ONE_NORM: + temp[i] = dzasum_(&n, &lusup[xlusup_first + i], &m) / (double)n; + break; + case TWO_NORM: + temp[i] = dznrm2_(&n, &lusup[xlusup_first + i], &m) + / sqrt((double)n); + break; + case INF_NORM: + default: + k = izamax_(&n, &lusup[xlusup_first + i], &m) - 1; + temp[i] = z_abs1(&lusup[xlusup_first + i + m * k]); + break; + } + + /* drop small entries due to drop_tol */ + if (drop_rule & DROP_BASIC && temp[i] < drop_tol) + { + r++; + /* drop the current row and move the last undropped row here */ + if (r > 1) /* add to last row */ + { + /* accumulate the sum (for MILU) */ + switch (milu) + { + case SMILU_1: + case SMILU_2: + zaxpy_(&n, &one, &lusup[xlusup_first + i], &m, + &lusup[xlusup_first + m - 1], &m); + break; + case SMILU_3: + for (j = 0; j < n; j++) + lusup[xlusup_first + (m - 1) + j * m].r += + z_abs1(&lusup[xlusup_first + i + j * m]); + break; + case SILU: + default: + break; + } + zcopy_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + } /* if (r > 1) */ + else /* move to last row */ + { + zswap_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + if (milu == SMILU_3) + for (j = 0; j < n; j++) { + lusup[xlusup_first + m1 + j * m].r = + z_abs1(&lusup[xlusup_first + m1 + j * m]); + lusup[xlusup_first + m1 + j * m].i = 0.0; + } + } + lsub[xlsub_first + i] = lsub[xlsub_first + m1]; + m1--; + continue; + } /* if dropping */ + else + { + if (temp[i] > d_max) d_max = temp[i]; + if (temp[i] < d_min) d_min = temp[i]; + } + i++; + } /* for */ + + /* Secondary dropping: drop more rows according to the quota. */ + quota = ceil((double)quota / (double)n); + if (drop_rule & DROP_SECONDARY && m - r > quota) + { + register double tol = d_max; + + /* Calculate the second dropping tolerance */ + if (quota > n) + { + if (drop_rule & DROP_INTERP) /* by interpolation */ + { + d_max = 1.0 / d_max; d_min = 1.0 / d_min; + tol = 1.0 / (d_max + (d_min - d_max) * quota / (m - n - r)); + } + else /* by quick select */ + { + int len = m1 - n + 1; + dcopy_(&len, dwork, &i_1, dwork2, &i_1); + tol = dqselect(len, dwork2, quota - n); +#if 0 + register int *itemp = iwork - n; + A = temp; + for (i = n; i <= m1; i++) itemp[i] = i; + qsort(iwork, m1 - n + 1, sizeof(int), _compare_); + tol = temp[itemp[quota]]; +#endif + } + } + + for (i = n; i <= m1; ) + { + if (temp[i] <= tol) + { + register int j; + r++; + /* drop the current row and move the last undropped row here */ + if (r > 1) /* add to last row */ + { + /* accumulate the sum (for MILU) */ + switch (milu) + { + case SMILU_1: + case SMILU_2: + zaxpy_(&n, &one, &lusup[xlusup_first + i], &m, + &lusup[xlusup_first + m - 1], &m); + break; + case SMILU_3: + for (j = 0; j < n; j++) + lusup[xlusup_first + (m - 1) + j * m].r += + z_abs1(&lusup[xlusup_first + i + j * m]); + break; + case SILU: + default: + break; + } + zcopy_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + } /* if (r > 1) */ + else /* move to last row */ + { + zswap_(&n, &lusup[xlusup_first + m1], &m, + &lusup[xlusup_first + i], &m); + if (milu == SMILU_3) + for (j = 0; j < n; j++) { + lusup[xlusup_first + m1 + j * m].r = + z_abs1(&lusup[xlusup_first + m1 + j * m]); + lusup[xlusup_first + m1 + j * m].i = 0.0; + } + } + lsub[xlsub_first + i] = lsub[xlsub_first + m1]; + m1--; + temp[i] = temp[m1]; + + continue; + } + i++; + + } /* for */ + + } /* if secondary dropping */ + + for (i = n; i < m; i++) temp[i] = 0.0; + + if (r == 0) + { + *nnzLj += m * n; + return 0; + } + + /* add dropped entries to the diagnal */ + if (milu != SILU) + { + register int j; + doublecomplex t; + double omega; + for (j = 0; j < n; j++) + { + t = lusup[xlusup_first + (m - 1) + j * m]; + if (t.r == 0.0 && t.i == 0.0) continue; + omega = SUPERLU_MIN(2.0 * (1.0 - alpha) / z_abs1(&t), 1.0); + zd_mult(&t, &t, omega); + + switch (milu) + { + case SMILU_1: + if ( !(z_eq(&t, &none)) ) { + z_add(&t, &t, &one); + zz_mult(&lusup[xlusup_first + j * inc_diag], + &lusup[xlusup_first + j * inc_diag], + &t); + } + else + { + zd_mult( + &lusup[xlusup_first + j * inc_diag], + &lusup[xlusup_first + j * inc_diag], + *fill_tol); +#ifdef DEBUG + printf("[1] ZERO PIVOT: FILL col %d.\n", first + j); + fflush(stdout); +#endif + nzp++; + } + break; + case SMILU_2: + zd_mult(&lusup[xlusup_first + j * inc_diag], + &lusup[xlusup_first + j * inc_diag], + 1.0 + z_abs1(&t)); + break; + case SMILU_3: + z_add(&t, &t, &one); + zz_mult(&lusup[xlusup_first + j * inc_diag], + &lusup[xlusup_first + j * inc_diag], + &t); + break; + case SILU: + default: + break; + } + } + if (nzp > 0) *fill_tol = -nzp; + } + + /* Remove dropped entries from the memory and fix the pointers. */ + m1 = m - r; + for (j = 1; j < n; j++) + { + register int tmp1, tmp2; + tmp1 = xlusup_first + j * m1; + tmp2 = xlusup_first + j * m; + for (i = 0; i < m1; i++) + lusup[i + tmp1] = lusup[i + tmp2]; + } + for (i = 0; i < nzlc; i++) + lusup[xlusup_first + i + n * m1] = lusup[xlusup_first + i + n * m]; + for (i = 0; i < nzlc; i++) + lsub[xlsub[last + 1] - r + i] = lsub[xlsub[last + 1] + i]; + for (i = first + 1; i <= last + 1; i++) + { + xlusup[i] -= r * (i - first); + xlsub[i] -= r; + } + if (lastc) + { + xlusup[last + 2] -= r * n; + xlsub[last + 2] -= r; + } + + *nnzLj += (m - r) * n; + return r; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_zpanel_dfs.c b/src/Libraries/superlu-5.2.1/SRC/ilu_zpanel_dfs.c new file mode 100644 index 00000000..a13e74b6 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_zpanel_dfs.c @@ -0,0 +1,258 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_zpanel_dfs.c + * \brief Peforms a symbolic factorization on a panel of symbols and + * record the entries with maximum absolute value in each column + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + +#include "slu_zdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *   Performs a symbolic factorization on a panel of columns [jcol, jcol+w).
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives.
+ *
+ *   The routine returns one list of the supernodal representatives
+ *   in topological order of the dfs that generates them. This list is
+ *   a superset of the topological order of each individual column within
+ *   the panel.
+ *   The location of the first nonzero in each supernodal segment
+ *   (supernodal entry location) is also returned. Each column has a
+ *   separate list for this purpose.
+ *
+ *   Two marker arrays are used for dfs:
+ *     marker[i] == jj, if i was visited during dfs of current column jj;
+ *     marker1[i] >= jcol, if i was visited by earlier columns in this panel;
+ *
+ *   marker: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ * 
+ */ +void +ilu_zpanel_dfs( + const int m, /* in - number of rows in the matrix */ + const int w, /* in */ + const int jcol, /* in */ + SuperMatrix *A, /* in - original matrix */ + int *perm_r, /* in */ + int *nseg, /* out */ + doublecomplex *dense, /* out */ + double *amax, /* out - max. abs. value of each column in panel */ + int *panel_lsub, /* out */ + int *segrep, /* out */ + int *repfnz, /* out */ + int *marker, /* out */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ +) +{ + + NCPformat *Astore; + doublecomplex *a; + int *asub; + int *xa_begin, *xa_end; + int krep, chperm, chmark, chrep, oldrep, kchild, myfnz; + int k, krow, kmark, kperm; + int xdfs, maxdfs, kpar; + int jj; /* index through each column in the panel */ + int *marker1; /* marker1[jj] >= jcol if vertex jj was visited + by a previous column within this panel. */ + int *repfnz_col; /* start of each column in the panel */ + doublecomplex *dense_col; /* start of each column in the panel */ + int nextl_col; /* next available position in panel_lsub[*,jj] */ + int *xsup, *supno; + int *lsub, *xlsub; + double *amax_col; + register double tmp; + + /* Initialize pointers */ + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + marker1 = marker + m; + repfnz_col = repfnz; + dense_col = dense; + amax_col = amax; + *nseg = 0; + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + + /* For each column in the panel */ + for (jj = jcol; jj < jcol + w; jj++) { + nextl_col = (jj - jcol) * m; + +#ifdef CHK_DFS + printf("\npanel col %d: ", jj); +#endif + + *amax_col = 0.0; + /* For each nonz in A[*,jj] do dfs */ + for (k = xa_begin[jj]; k < xa_end[jj]; k++) { + krow = asub[k]; + tmp = z_abs1(&a[k]); + if (tmp > *amax_col) *amax_col = tmp; + dense_col[krow] = a[k]; + kmark = marker[krow]; + if ( kmark == jj ) + continue; /* krow visited before, go to the next nonzero */ + + /* For each unmarked nbr krow of jj + * krow is in L: place it in structure of L[*,jj] + */ + marker[krow] = jj; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + panel_lsub[nextl_col++] = krow; /* krow is indexed into A */ + } + /* + * krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + else { + + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz_col[krep]; + +#ifdef CHK_DFS + printf("krep %d, myfnz %d, perm_r[%d] %d\n", krep, myfnz, krow, kperm); +#endif + if ( myfnz != EMPTY ) { /* Representative visited before */ + if ( myfnz > kperm ) repfnz_col[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz_col[krep] = kperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; + +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker[kchild]; + + if ( chmark != jj ) { /* Not reached yet */ + marker[kchild] = jj; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,j] */ + if ( chperm == EMPTY ) { + panel_lsub[nextl_col++] = kchild; + } + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + else { + + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz_col[chrep]; +#ifdef CHK_DFS + printf("chrep %d,myfnz %d,perm_r[%d] %d\n",chrep,myfnz,kchild,chperm); +#endif + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz_col[chrep] = chperm; + } + else { + /* Cont. dfs at snode-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L) */ + parent[krep] = oldrep; + repfnz_col[krep] = chperm; + xdfs = xlsub[xsup[supno[krep]]]; + maxdfs = xlsub[krep + 1]; +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } /* else */ + + } /* else */ + + } /* if... */ + + } /* while xdfs < maxdfs */ + + /* krow has no more unexplored nbrs: + * Place snode-rep krep in postorder DFS, if this + * segment is seen for the first time. (Note that + * "repfnz[krep]" may change later.) + * Backtrack dfs to its parent. + */ + if ( marker1[krep] < jcol ) { + segrep[*nseg] = krep; + ++(*nseg); + marker1[krep] = jj; + } + + kpar = parent[krep]; /* Pop stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xlsub[krep + 1]; + +#ifdef CHK_DFS + printf(" pop stack: krep %d,xdfs %d,maxdfs %d: ", krep,xdfs,maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } while ( kpar != EMPTY ); /* do-while - until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonz in A[*,jj] */ + + repfnz_col += m; /* Move to next column */ + dense_col += m; + amax_col++; + + } /* for jj ... */ + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_zpivotL.c b/src/Libraries/superlu-5.2.1/SRC/ilu_zpivotL.c new file mode 100644 index 00000000..a558a80c --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_zpivotL.c @@ -0,0 +1,284 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_zpivotL.c + * \brief Performs numerical pivoting + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + + +#include +#include +#include "slu_zdefs.h" + +#ifndef SGN +#define SGN(x) ((x)>=0?1:-1) +#endif + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   Performs the numerical pivoting on the current column of L,
+ *   and the CDIV operation.
+ *
+ *   Pivot policy:
+ *   (1) Compute thresh = u * max_(i>=j) abs(A_ij);
+ *   (2) IF user specifies pivot row k and abs(A_kj) >= thresh THEN
+ *	     pivot row = k;
+ *	 ELSE IF abs(A_jj) >= thresh THEN
+ *	     pivot row = j;
+ *	 ELSE
+ *	     pivot row = m;
+ *
+ *   Note: If you absolutely want to use a given pivot order, then set u=0.0.
+ *
+ *   Return value: 0	  success;
+ *		   i > 0  U(i,i) is exactly zero.
+ * 
+ */ + +int +ilu_zpivotL( + const int jcol, /* in */ + const double u, /* in - diagonal pivoting threshold */ + int *usepr, /* re-use the pivot sequence given by + * perm_r/iperm_r */ + int *perm_r, /* may be modified */ + int diagind, /* diagonal of Pc*A*Pc' */ + int *swap, /* in/out record the row permutation */ + int *iswap, /* in/out inverse of swap, it is the same as + perm_r after the factorization */ + int *marker, /* in */ + int *pivrow, /* in/out, as an input if *usepr!=0 */ + double fill_tol, /* in - fill tolerance of current column + * used for a singular column */ + milu_t milu, /* in */ + doublecomplex drop_sum, /* in - computed in ilu_zcopy_to_ucol() + (MILU only) */ + GlobalLU_t *Glu, /* modified - global LU data structures */ + SuperLUStat_t *stat /* output */ + ) +{ + + int n; /* number of columns */ + int fsupc; /* first column in the supernode */ + int nsupc; /* no of columns in the supernode */ + int nsupr; /* no of rows in the supernode */ + int lptr; /* points to the starting subscript of the supernode */ + register int pivptr; + int old_pivptr, diag, ptr0; + register double pivmax, rtemp; + double thresh; + doublecomplex temp; + doublecomplex *lu_sup_ptr; + doublecomplex *lu_col_ptr; + int *lsub_ptr; + register int isub, icol, k, itemp; + int *lsub, *xlsub; + doublecomplex *lusup; + int *xlusup; + flops_t *ops = stat->ops; + int info; + doublecomplex one = {1.0, 0.0}; + + /* Initialize pointers */ + n = Glu->n; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (doublecomplex *) Glu->lusup; + xlusup = Glu->xlusup; + fsupc = (Glu->xsup)[(Glu->supno)[jcol]]; + nsupc = jcol - fsupc; /* excluding jcol; nsupc >= 0 */ + lptr = xlsub[fsupc]; + nsupr = xlsub[fsupc+1] - lptr; + lu_sup_ptr = &lusup[xlusup[fsupc]]; /* start of the current supernode */ + lu_col_ptr = &lusup[xlusup[jcol]]; /* start of jcol in the supernode */ + lsub_ptr = &lsub[lptr]; /* start of row indices of the supernode */ + + /* Determine the largest abs numerical value for partial pivoting; + Also search for user-specified pivot, and diagonal element. */ + pivmax = -1.0; + pivptr = nsupc; + diag = EMPTY; + old_pivptr = nsupc; + ptr0 = EMPTY; + for (isub = nsupc; isub < nsupr; ++isub) { + if (marker[lsub_ptr[isub]] > jcol) + continue; /* do not overlap with a later relaxed supernode */ + + switch (milu) { + case SMILU_1: + z_add(&temp, &lu_col_ptr[isub], &drop_sum); + rtemp = z_abs1(&temp); + break; + case SMILU_2: + case SMILU_3: + /* In this case, drop_sum contains the sum of the abs. value */ + rtemp = z_abs1(&lu_col_ptr[isub]); + break; + case SILU: + default: + rtemp = z_abs1(&lu_col_ptr[isub]); + break; + } + if (rtemp > pivmax) { pivmax = rtemp; pivptr = isub; } + if (*usepr && lsub_ptr[isub] == *pivrow) old_pivptr = isub; + if (lsub_ptr[isub] == diagind) diag = isub; + if (ptr0 == EMPTY) ptr0 = isub; + } + + if (milu == SMILU_2 || milu == SMILU_3) pivmax += drop_sum.r; + + /* Test for singularity */ + if (pivmax < 0.0) { + fprintf(stderr, "[0]: jcol=%d, SINGULAR!!!\n", jcol); + fflush(stderr); + exit(1); + } + if ( pivmax == 0.0 ) { + if (diag != EMPTY) + *pivrow = lsub_ptr[pivptr = diag]; + else if (ptr0 != EMPTY) + *pivrow = lsub_ptr[pivptr = ptr0]; + else { + /* look for the first row which does not + belong to any later supernodes */ + for (icol = jcol; icol < n; icol++) + if (marker[swap[icol]] <= jcol) break; + if (icol >= n) { + fprintf(stderr, "[1]: jcol=%d, SINGULAR!!!\n", jcol); + fflush(stderr); + exit(1); + } + + *pivrow = swap[icol]; + + /* pick up the pivot row */ + for (isub = nsupc; isub < nsupr; ++isub) + if ( lsub_ptr[isub] == *pivrow ) { pivptr = isub; break; } + } + pivmax = fill_tol; + lu_col_ptr[pivptr].r = pivmax; + lu_col_ptr[pivptr].i = 0.0; + *usepr = 0; +#ifdef DEBUG + printf("[0] ZERO PIVOT: FILL (%d, %d).\n", *pivrow, jcol); + fflush(stdout); +#endif + info =jcol + 1; + } /* if (*pivrow == 0.0) */ + else { + thresh = u * pivmax; + + /* Choose appropriate pivotal element by our policy. */ + if ( *usepr ) { + switch (milu) { + case SMILU_1: + z_add(&temp, &lu_col_ptr[old_pivptr], &drop_sum); + rtemp = z_abs1(&temp); + break; + case SMILU_2: + case SMILU_3: + rtemp = z_abs1(&lu_col_ptr[old_pivptr]) + drop_sum.r; + break; + case SILU: + default: + rtemp = z_abs1(&lu_col_ptr[old_pivptr]); + break; + } + if ( rtemp != 0.0 && rtemp >= thresh ) pivptr = old_pivptr; + else *usepr = 0; + } + if ( *usepr == 0 ) { + /* Use diagonal pivot? */ + if ( diag >= 0 ) { /* diagonal exists */ + switch (milu) { + case SMILU_1: + z_add(&temp, &lu_col_ptr[diag], &drop_sum); + rtemp = z_abs1(&temp); + break; + case SMILU_2: + case SMILU_3: + rtemp = z_abs1(&lu_col_ptr[diag]) + drop_sum.r; + break; + case SILU: + default: + rtemp = z_abs1(&lu_col_ptr[diag]); + break; + } + if ( rtemp != 0.0 && rtemp >= thresh ) pivptr = diag; + } + *pivrow = lsub_ptr[pivptr]; + } + info = 0; + + /* Reset the diagonal */ + switch (milu) { + case SMILU_1: + z_add(&lu_col_ptr[pivptr], &lu_col_ptr[pivptr], &drop_sum); + break; + case SMILU_2: + case SMILU_3: + temp = z_sgn(&lu_col_ptr[pivptr]); + zz_mult(&temp, &temp, &drop_sum); + z_add(&lu_col_ptr[pivptr], &lu_col_ptr[pivptr], &drop_sum); + break; + case SILU: + default: + break; + } + + } /* else */ + + /* Record pivot row */ + perm_r[*pivrow] = jcol; + if (jcol < n - 1) { + register int t1, t2, t; + t1 = iswap[*pivrow]; t2 = jcol; + if (t1 != t2) { + t = swap[t1]; swap[t1] = swap[t2]; swap[t2] = t; + t1 = swap[t1]; t2 = t; + t = iswap[t1]; iswap[t1] = iswap[t2]; iswap[t2] = t; + } + } /* if (jcol < n - 1) */ + + /* Interchange row subscripts */ + if ( pivptr != nsupc ) { + itemp = lsub_ptr[pivptr]; + lsub_ptr[pivptr] = lsub_ptr[nsupc]; + lsub_ptr[nsupc] = itemp; + + /* Interchange numerical values as well, for the whole snode, such + * that L is indexed the same way as A. + */ + for (icol = 0; icol <= nsupc; icol++) { + itemp = pivptr + icol * nsupr; + temp = lu_sup_ptr[itemp]; + lu_sup_ptr[itemp] = lu_sup_ptr[nsupc + icol*nsupr]; + lu_sup_ptr[nsupc + icol*nsupr] = temp; + } + } /* if */ + + /* cdiv operation */ + ops[FACT] += 10 * (nsupr - nsupc); + z_div(&temp, &one, &lu_col_ptr[nsupc]); + for (k = nsupc+1; k < nsupr; k++) + zz_mult(&lu_col_ptr[k], &lu_col_ptr[k], &temp); + + return info; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ilu_zsnode_dfs.c b/src/Libraries/superlu-5.2.1/SRC/ilu_zsnode_dfs.c new file mode 100644 index 00000000..5ab33337 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ilu_zsnode_dfs.c @@ -0,0 +1,100 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ilu_zsnode_dfs.c + * \brief Determines the union of row structures of columns within the relaxed node + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + +#include "slu_zdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *    ilu_zsnode_dfs() - Determine the union of the row structures of those
+ *    columns within the relaxed snode.
+ *    Note: The relaxed snodes are leaves of the supernodal etree, therefore,
+ *    the portion outside the rectangular supernode must be zero.
+ *
+ * Return value
+ * ============
+ *     0   success;
+ *    >0   number of bytes allocated when run out of memory.
+ * 
+ */ + +int +ilu_zsnode_dfs( + const int jcol, /* in - start of the supernode */ + const int kcol, /* in - end of the supernode */ + const int *asub, /* in */ + const int *xa_begin, /* in */ + const int *xa_end, /* in */ + int *marker, /* modified */ + GlobalLU_t *Glu /* modified */ + ) +{ + + register int i, k, nextl; + int nsuper, krow, kmark, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + int nzlmax; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + nsuper = ++supno[jcol]; /* Next available supernode number */ + nextl = xlsub[jcol]; + + for (i = jcol; i <= kcol; i++) + { + /* For each nonzero in A[*,i] */ + for (k = xa_begin[i]; k < xa_end[i]; k++) + { + krow = asub[k]; + kmark = marker[krow]; + if ( kmark != kcol ) + { /* First time visit krow */ + marker[krow] = kcol; + lsub[nextl++] = krow; + if ( nextl >= nzlmax ) + { + if ( (mem_error = zLUMemXpand(jcol, nextl, LSUB, &nzlmax, + Glu)) != 0) + return (mem_error); + lsub = Glu->lsub; + } + } + } + supno[i] = nsuper; + } + + /* Supernode > 1 */ + if ( jcol < kcol ) + for (i = jcol+1; i <= kcol; i++) xlsub[i] = nextl; + + xsup[nsuper+1] = kcol + 1; + supno[kcol+1] = nsuper; + xlsub[kcol+1] = nextl; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/input_error.c b/src/Libraries/superlu-5.2.1/SRC/input_error.c new file mode 100644 index 00000000..4d37de80 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/input_error.c @@ -0,0 +1,50 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +#include +#include "slu_Cnames.h" + +/*! @file input_error.c + * \brief Error handler for input parameters. + * + *
+ * -- SuperLU routine (version 4.4) --
+ * Lawrence Berkeley National Lab, Univ. of California Berkeley.
+ * November 20, 2012
+ * 
+ */ + +/*! \brief + * + *
+ * Purpose   
+ * =======   
+ *
+ * INPUT_ERROR is called if an input parameter has an   
+ * invalid value.  A message is printed and execution stops.   
+ *
+ * Arguments   
+ * =========   
+ *
+ * srname  (input) character*6
+ *         The name of the routine which called INPUT_ERROR.
+ *
+ * info    (input) int
+ *         The position of the invalid parameter in the parameter list   
+ *         of the calling routine.
+ *
+ * 
+ */ +int input_error(char *srname, int *info) +{ + printf("** On entry to %6s, parameter number %2d had an illegal value\n", + srname, *info); + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/izmax1.c b/src/Libraries/superlu-5.2.1/SRC/izmax1.c new file mode 100644 index 00000000..308447dc --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/izmax1.c @@ -0,0 +1,123 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file izmax1.c + * \brief Finds the index of the element whose real part has maximum absolute value + * + *
+ *     -- LAPACK auxiliary routine (version 2.0) --   
+ *     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
+ *     Courant Institute, Argonne National Lab, and Rice University   
+ *     October 31, 1992   
+ * 
+ */ +#include +#include "slu_dcomplex.h" +#include "slu_Cnames.h" + +/*! \brief + +
+    Purpose   
+    =======   
+
+    IZMAX1 finds the index of the element whose real part has maximum   
+    absolute value.   
+
+    Based on IZAMAX from Level 1 BLAS.   
+    The change is to use the 'genuine' absolute value.   
+
+    Contributed by Nick Higham for use with ZLACON.   
+
+    Arguments   
+    =========   
+
+    N       (input) INT   
+            The number of elements in the vector CX.   
+
+    CX      (input) COMPLEX*16 array, dimension (N)   
+            The vector whose elements will be summed.   
+
+    INCX    (input) INT   
+            The spacing between successive values of CX.  INCX >= 1.   
+
+   ===================================================================== 
+
+*/ + +int +izmax1_slu(int *n, doublecomplex *cx, int *incx) +{ + + + /* System generated locals */ + int ret_val, i__1, i__2; + double d__1; + + /* Local variables */ + double smax; + int i, ix; + +#define CX(I) cx[(I)-1] + + ret_val = 0; + if (*n < 1) { + return ret_val; + } + ret_val = 1; + if (*n == 1) { + return ret_val; + } + if (*incx == 1) { + goto L30; + } + +/* CODE FOR INCREMENT NOT EQUAL TO 1 */ + + ix = 1; + smax = (d__1 = CX(1).r, fabs(d__1)); + ix += *incx; + i__1 = *n; + for (i = 2; i <= *n; ++i) { + i__2 = ix; + if ((d__1 = CX(ix).r, fabs(d__1)) <= smax) { + goto L10; + } + ret_val = i; + i__2 = ix; + smax = (d__1 = CX(ix).r, fabs(d__1)); +L10: + ix += *incx; +/* L20: */ + } + return ret_val; + +/* CODE FOR INCREMENT EQUAL TO 1 */ + +L30: + smax = (d__1 = CX(1).r, fabs(d__1)); + i__1 = *n; + for (i = 2; i <= *n; ++i) { + i__2 = i; + if ((d__1 = CX(i).r, fabs(d__1)) <= smax) { + goto L40; + } + ret_val = i; + i__2 = i; + smax = (d__1 = CX(i).r, fabs(d__1)); +L40: + ; + } + return ret_val; + +/* End of IZMAX1 */ + +} /* izmax1_slu */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/mark_relax.c b/src/Libraries/superlu-5.2.1/SRC/mark_relax.c new file mode 100644 index 00000000..73014aa7 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/mark_relax.c @@ -0,0 +1,57 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file mark_relax.c + * \brief Record the rows pivoted by the relaxed supernodes. + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 1, 2009
+ * <\pre>
+ */
+#include "slu_ddefs.h"
+
+/*! \brief
+ *
+ * 
+ * Purpose
+ * =======
+ *    mark_relax() - record the rows used by the relaxed supernodes.
+ * 
+ */ +int mark_relax( + int n, /* order of the matrix A */ + int *relax_end, /* last column in a relaxed supernode. + * if j-th column starts a relaxed supernode, + * relax_end[j] represents the last column of + * this supernode. */ + int *relax_fsupc, /* first column in a relaxed supernode. + * relax_fsupc[j] represents the first column of + * j-th supernode. */ + int *xa_begin, /* Astore->colbeg */ + int *xa_end, /* Astore->colend */ + int *asub, /* row index of A */ + int *marker /* marker[j] is the maximum column index if j-th + * row belongs to a relaxed supernode. */ ) +{ + register int jcol, kcol; + register int i, j, k; + + for (i = 0; i < n && relax_fsupc[i] != EMPTY; i++) + { + jcol = relax_fsupc[i]; /* first column */ + kcol = relax_end[jcol]; /* last column */ + for (j = jcol; j <= kcol; j++) + for (k = xa_begin[j]; k < xa_end[j]; k++) + marker[asub[k]] = jcol; + } + return i; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/mc64ad.c b/src/Libraries/superlu-5.2.1/SRC/mc64ad.c new file mode 100644 index 00000000..d9ffdaed --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/mc64ad.c @@ -0,0 +1,2645 @@ +/* mc64ad.f -- translated by f2c (version 20100827). + You must link the resulting object file with libf2c: + on Microsoft Windows system, link with libf2c.lib; + on Linux or Unix systems, link with .../path/to/libf2c.a -lm + or, if you install libf2c.a in a standard place, with -lf2c -lm + -- in that order, at the end of the command line, as in + cc *.o -lf2c -lm + Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., + + http://www.netlib.org/f2c/libf2c.zip +*/ + +#include "slu_ddefs.h" + +#define abs(a) ((a) >= 0) ? (a) : -(a) +#define min(a,b) ((a) < (b)) ? (a) : (b) + +#if 0 +/* Table of constant values */ +static int_t c__1 = 1; +static int_t c__2 = 2; +#endif + +/* CCCC COPYRIGHT (c) 1999 Council for the Central Laboratory of the */ +/* CCCC Research Councils. All rights reserved. */ +/* CCCC PACKAGE MC64A/AD */ +/* CCCC AUTHORS Iain Duff (i.duff@rl.ac.uk) and Jacko Koster (jak@ii.uib.no) */ +/* CCCC LAST UPDATE 20/09/99 */ +/* CCCC */ +/* *** Conditions on external use *** */ + +/* The user shall acknowledge the contribution of this */ +/* package in any publication of material dependent upon the use of */ +/* the package. The user shall use reasonable endeavours to notify */ +/* the authors of the package of this publication. */ + +/* The user can modify this code but, at no time */ +/* shall the right or title to all or any part of this package pass */ +/* to the user. The user shall make available free of charge */ +/* to the authors for any purpose all information relating to any */ +/* alteration or addition made to this package for the purposes of */ +/* extending the capabilities or enhancing the performance of this */ +/* package. */ + +/* The user shall not pass this code directly to a third party without the */ +/* express prior consent of the authors. Users wanting to licence their */ +/* own copy of these routines should send email to hsl@stfc.ac.uk */ + +/* None of the comments from the Copyright notice up to and including this */ +/* one shall be removed or altered in any way. */ +/* ********************************************************************** */ +/* Subroutine */ int_t mc64id_(int_t *icntl) +{ + int_t i__; + + +/* *** Copyright (c) 1999 Council for the Central Laboratory of the */ +/* Research Councils *** */ +/* *** Although every effort has been made to ensure robustness and *** */ +/* *** reliability of the subroutines in this MC64 suite, we *** */ +/* *** disclaim any liability arising through the use or misuse of *** */ +/* *** any of the subroutines. *** */ +/* *** Any problems? Contact ... */ +/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */ + +/* Purpose */ +/* ======= */ + +/* The components of the array ICNTL control the action of MC64A/AD. */ +/* Default values for these are set in this subroutine. */ + +/* Parameters */ +/* ========== */ + + +/* Local variables */ + +/* ICNTL(1) has default value 6. */ +/* It is the output stream for error messages. If it */ +/* is negative, these messages will be suppressed. */ + +/* ICNTL(2) has default value 6. */ +/* It is the output stream for warning messages. */ +/* If it is negative, these messages are suppressed. */ + +/* ICNTL(3) has default value -1. */ +/* It is the output stream for monitoring printing. */ +/* If it is negative, these messages are suppressed. */ + +/* ICNTL(4) has default value 0. */ +/* If left at the defaut value, the incoming data is checked for */ +/* out-of-range indices and duplicates. Setting ICNTL(4) to any */ +/* other will avoid the checks but is likely to cause problems */ +/* later if out-of-range indices or duplicates are present. */ +/* The user should only set ICNTL(4) non-zero, if the data is */ +/* known to avoid these problems. */ + +/* ICNTL(5) to ICNTL(10) are not used by MC64A/AD but are set to */ +/* zero in this routine. */ +/* Initialization of the ICNTL array. */ + /* Parameter adjustments */ + --icntl; + + /* Function Body */ + icntl[1] = 6; + icntl[2] = 6; + icntl[3] = -1; + for (i__ = 4; i__ <= 10; ++i__) { + icntl[i__] = 0; +/* L10: */ + } + return 0; +} /* mc64id_ */ + +/* ********************************************************************** */ +/* Subroutine */ int_t mc64ad_(int_t *job, int_t *n, int_t *ne, int_t * + ip, int_t *irn, double *a, int_t *num, int_t *cperm, + int_t *liw, int_t *iw, int_t *ldw, double *dw, int_t * + icntl, int_t *info) +{ + /* System generated locals */ + int_t i__1, i__2; + double d__1, d__2; + + /* Builtin functions */ + double log(double); + + /* Local variables */ + int_t i__, j, k; + double fact, rinf; + + extern /* Subroutine */ int_t mc21ad_(int_t *, int_t *, int_t *, + int_t *, int_t *, int_t *, int_t *, int_t *), mc64bd_( + int_t *, int_t *, int_t *, int_t *, double *, int_t + *, int_t *, int_t *, int_t *, int_t *, int_t *, + double *), mc64rd_(int_t *, int_t *, int_t *, int_t *, + double *), mc64sd_(int_t *, int_t *, int_t *, int_t * + , double *, int_t *, int_t *, int_t *, int_t *, + int_t *, int_t *, int_t *, int_t *, int_t *), mc64wd_( + int_t *, int_t *, int_t *, int_t *, double *, int_t + *, int_t *, int_t *, int_t *, int_t *, int_t *, int_t + *, double *, double *); + +/* *** Copyright (c) 1999 Council for the Central Laboratory of the */ +/* Research Councils *** */ +/* *** Although every effort has been made to ensure robustness and *** */ +/* *** reliability of the subroutines in this MC64 suite, we *** */ +/* *** disclaim any liability arising through the use or misuse of *** */ +/* *** any of the subroutines. *** */ +/* *** Any problems? Contact ... */ +/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */ + +/* Purpose */ +/* ======= */ + +/* This subroutine attempts to find a column permutation for an NxN */ +/* sparse matrix A = {a_ij} that makes the permuted matrix have N */ +/* entries on its diagonal. */ +/* If the matrix is structurally nonsingular, the subroutine optionally */ +/* returns a column permutation that maximizes the smallest element */ +/* on the diagonal, maximizes the sum of the diagonal entries, or */ +/* maximizes the product of the diagonal entries of the permuted matrix. */ +/* For the latter option, the subroutine also finds scaling factors */ +/* that may be used to scale the matrix so that the nonzero diagonal */ +/* entries of the permuted matrix are one in absolute value and all the */ +/* off-diagonal entries are less than or equal to one in absolute value. */ +/* The natural logarithms of the scaling factors u(i), i=1..N, for the */ +/* rows and v(j), j=1..N, for the columns are returned so that the */ +/* scaled matrix B = {b_ij} has entries b_ij = a_ij * EXP(u_i + v_j). */ + +/* Parameters */ +/* ========== */ + + +/* JOB is an INT_T variable which must be set by the user to */ +/* control the action. It is not altered by the subroutine. */ +/* Possible values for JOB are: */ +/* 1 Compute a column permutation of the matrix so that the */ +/* permuted matrix has as many entries on its diagonal as possible. */ +/* The values on the diagonal are of arbitrary size. HSL subroutine */ +/* MC21A/AD is used for this. See [1]. */ +/* 2 Compute a column permutation of the matrix so that the smallest */ +/* value on the diagonal of the permuted matrix is maximized. */ +/* See [3]. */ +/* 3 Compute a column permutation of the matrix so that the smallest */ +/* value on the diagonal of the permuted matrix is maximized. */ +/* The algorithm differs from the one used for JOB = 2 and may */ +/* have quite a different performance. See [2]. */ +/* 4 Compute a column permutation of the matrix so that the sum */ +/* of the diagonal entries of the permuted matrix is maximized. */ +/* See [3]. */ +/* 5 Compute a column permutation of the matrix so that the product */ +/* of the diagonal entries of the permuted matrix is maximized */ +/* and vectors to scale the matrix so that the nonzero diagonal */ +/* entries of the permuted matrix are one in absolute value and */ +/* all the off-diagonal entries are less than or equal to one in */ +/* absolute value. See [3]. */ +/* Restriction: 1 <= JOB <= 5. */ + +/* N is an INT_T variable which must be set by the user to the */ +/* order of the matrix A. It is not altered by the subroutine. */ +/* Restriction: N >= 1. */ + +/* NE is an INT_T variable which must be set by the user to the */ +/* number of entries in the matrix. It is not altered by the */ +/* subroutine. */ +/* Restriction: NE >= 1. */ + +/* IP is an INT_T array of length N+1. */ +/* IP(J), J=1..N, must be set by the user to the position in array IRN */ +/* of the first row index of an entry in column J. IP(N+1) must be set */ +/* to NE+1. It is not altered by the subroutine. */ + +/* IRN is an INT_T array of length NE. */ +/* IRN(K), K=1..NE, must be set by the user to hold the row indices of */ +/* the entries of the matrix. Those belonging to column J must be */ +/* stored contiguously in the positions IP(J)..IP(J+1)-1. The ordering */ +/* of the row indices within each column is unimportant. Repeated */ +/* entries are not allowed. The array IRN is not altered by the */ +/* subroutine. */ + +/* A is a REAL (DOUBLE PRECISION in the D-version) array of length NE. */ +/* The user must set A(K), K=1..NE, to the numerical value of the */ +/* entry that corresponds to IRN(K). */ +/* It is not used by the subroutine when JOB = 1. */ +/* It is not altered by the subroutine. */ + +/* NUM is an INT_T variable that need not be set by the user. */ +/* On successful exit, NUM will be the number of entries on the */ +/* diagonal of the permuted matrix. */ +/* If NUM < N, the matrix is structurally singular. */ + +/* CPERM is an INT_T array of length N that need not be set by the */ +/* user. On successful exit, CPERM contains the column permutation. */ +/* Column CPERM(J) of the original matrix is column J in the permuted */ +/* matrix, J=1..N. */ + +/* LIW is an INT_T variable that must be set by the user to */ +/* the dimension of array IW. It is not altered by the subroutine. */ +/* Restriction: */ +/* JOB = 1 : LIW >= 5N */ +/* JOB = 2 : LIW >= 4N */ +/* JOB = 3 : LIW >= 10N + NE */ +/* JOB = 4 : LIW >= 5N */ +/* JOB = 5 : LIW >= 5N */ + +/* IW is an INT_T array of length LIW that is used for workspace. */ + +/* LDW is an INT_T variable that must be set by the user to the */ +/* dimension of array DW. It is not altered by the subroutine. */ +/* Restriction: */ +/* JOB = 1 : LDW is not used */ +/* JOB = 2 : LDW >= N */ +/* JOB = 3 : LDW >= NE */ +/* JOB = 4 : LDW >= 2N + NE */ +/* JOB = 5 : LDW >= 3N + NE */ + +/* DW is a REAL (DOUBLE PRECISION in the D-version) array of length LDW */ +/* that is used for workspace. If JOB = 5, on return, */ +/* DW(i) contains u_i, i=1..N, and DW(N+j) contains v_j, j=1..N. */ + +/* ICNTL is an INT_T array of length 10. Its components control the */ +/* output of MC64A/AD and must be set by the user before calling */ +/* MC64A/AD. They are not altered by the subroutine. */ + +/* ICNTL(1) must be set to specify the output stream for */ +/* error messages. If ICNTL(1) < 0, messages are suppressed. */ +/* The default value set by MC46I/ID is 6. */ + +/* ICNTL(2) must be set by the user to specify the output stream for */ +/* warning messages. If ICNTL(2) < 0, messages are suppressed. */ +/* The default value set by MC46I/ID is 6. */ + +/* ICNTL(3) must be set by the user to specify the output stream for */ +/* diagnostic messages. If ICNTL(3) < 0, messages are suppressed. */ +/* The default value set by MC46I/ID is -1. */ + +/* ICNTL(4) must be set by the user to a value other than 0 to avoid */ +/* checking of the input data. */ +/* The default value set by MC46I/ID is 0. */ + +/* INFO is an INT_T array of length 10 which need not be set by the */ +/* user. INFO(1) is set non-negative to indicate success. A negative */ +/* value is returned if an error occurred, a positive value if a */ +/* warning occurred. INFO(2) holds further information on the error. */ +/* On exit from the subroutine, INFO(1) will take one of the */ +/* following values: */ +/* 0 : successful entry (for structurally nonsingular matrix). */ +/* +1 : successful entry (for structurally singular matrix). */ +/* +2 : the returned scaling factors are large and may cause */ +/* overflow when used to scale the matrix. */ +/* (For JOB = 5 entry only.) */ +/* -1 : JOB < 1 or JOB > 5. Value of JOB held in INFO(2). */ +/* -2 : N < 1. Value of N held in INFO(2). */ +/* -3 : NE < 1. Value of NE held in INFO(2). */ +/* -4 : the defined length LIW violates the restriction on LIW. */ +/* Value of LIW required given by INFO(2). */ +/* -5 : the defined length LDW violates the restriction on LDW. */ +/* Value of LDW required given by INFO(2). */ +/* -6 : entries are found whose row indices are out of range. INFO(2) */ +/* contains the index of a column in which such an entry is found. */ +/* -7 : repeated entries are found. INFO(2) contains the index of a */ +/* column in which such entries are found. */ +/* INFO(3) to INFO(10) are not currently used and are set to zero by */ +/* the routine. */ + +/* References: */ +/* [1] I. S. Duff, (1981), */ +/* "Algorithm 575. Permutations for a zero-free diagonal", */ +/* ACM Trans. Math. Software 7(3), 387-390. */ +/* [2] I. S. Duff and J. Koster, (1998), */ +/* "The design and use of algorithms for permuting large */ +/* entries to the diagonal of sparse matrices", */ +/* SIAM J. Matrix Anal. Appl., vol. 20, no. 4, pp. 889-901. */ +/* [3] I. S. Duff and J. Koster, (1999), */ +/* "On algorithms for permuting large entries to the diagonal */ +/* of sparse matrices", */ +/* Technical Report RAL-TR-1999-030, RAL, Oxfordshire, England. */ +/* Local variables and parameters */ +/* External routines and functions */ +/* EXTERNAL FD05AD */ +/* DOUBLE PRECISION FD05AD */ +/* Intrinsic functions */ +/* Set RINF to largest positive real number (infinity) */ +/* XSL RINF = FD05AD(5) */ + /* Parameter adjustments */ + --cperm; + --ip; + --a; + --irn; + --iw; + --dw; + --icntl; + --info; + + /* Function Body */ + rinf = dmach("Overflow"); +/* Check value of JOB */ + if (*job < 1 || *job > 5) { + info[1] = -1; + info[2] = *job; + if (icntl[1] >= 0) { + printf(" ****** Error in MC64A/AD. INFO(1) = %2d" + " because JOB = %d\n", info[1], *job); + } + goto L99; + } +/* Check value of N */ + if (*n < 1) { + info[1] = -2; + info[2] = *n; + if (icntl[1] >= 0) { + printf(" ****** Error in MC64A/AD. INFO(1) = %2d" + " because N = %d\n", info[1], *job); + } + goto L99; + } +/* Check value of NE */ + if (*ne < 1) { + info[1] = -3; + info[2] = *ne; + if (icntl[1] >= 0) { + printf(" ****** Error in MC64A/AD. INFO(1) = %2d" + " because NE = %d\n", info[1], *job); + } + goto L99; + } +/* Check LIW */ + if (*job == 1) { + k = *n * 5; + } + if (*job == 2) { + k = *n << 2; + } + if (*job == 3) { + k = *n * 10 + *ne; + } + if (*job == 4) { + k = *n * 5; + } + if (*job == 5) { + k = *n * 5; + } + if (*liw < k) { + info[1] = -4; + info[2] = k; + if (icntl[1] >= 0) { + printf(" ****** Error in MC64A/AD. INFO(1) = %2d" + " LIW too small, must be at least %8d\n", info[1], k); + } + goto L99; + } +/* Check LDW */ +/* If JOB = 1, do not check */ + if (*job > 1) { + if (*job == 2) { + k = *n; + } + if (*job == 3) { + k = *ne; + } + if (*job == 4) { + k = (*n << 1) + *ne; + } + if (*job == 5) { + k = *n * 3 + *ne; + } + if (*ldw < k) { + info[1] = -5; + info[2] = k; + if (icntl[1] >= 0) { + printf(" ****** Error in MC64A/AD. INFO(1) = %2d" + " LDW too small, must be at least %8d\n", info[1], k); + } + goto L99; + } + } + if (icntl[4] == 0) { +/* Check row indices. Use IW(1:N) as workspace */ + i__1 = *n; + for (i__ = 1; i__ <= i__1; ++i__) { + iw[i__] = 0; +/* L3: */ + } + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = ip[j + 1] - 1; + for (k = ip[j]; k <= i__2; ++k) { + i__ = irn[k]; +/* Check for row indices that are out of range */ + if (i__ < 1 || i__ > *n) { + info[1] = -6; + info[2] = j; + if (icntl[1] >= 0) { + printf(" ****** Error in MC64A/AD. INFO(1) = %2d Column %8d" + " contains an entry with invalid row index %8d\n", + info[1], j, i__); + } + goto L99; + } +/* Check for repeated row indices within a column */ + if (iw[i__] == j) { + info[1] = -7; + info[2] = j; + if (icntl[1] >= 0) { + printf(" ****** Error in MC64A/AD. INFO(1) = %2d" + " Column %8d" + " contains two or more entries with row index %8d\n", + info[1], j, i__); + } + goto L99; + } else { + iw[i__] = j; + } +/* L4: */ + } +/* L6: */ + } + } +/* Print diagnostics on input */ + if (icntl[3] >= 0) { + printf(" ****** Input parameters for MC64A/AD: JOB = %8d," + " N = %d, NE = %8d\n", *job, *n, *ne); + printf(" IP(1:N+1) = "); + for (j=1; j<=(*n+1); ++j) { + printf("%8d", ip[j]); + if (j%8 == 0) printf("\n"); + } + printf("\n IRN(1:NE) = "); + for (j=1; j<=(*ne); ++j) { + printf("%8d", irn[j]); + if (j%8 == 0) printf("\n"); + } + printf("\n"); + + if (*job > 1) { + printf(" A(1:NE) = "); + for (j=1; j<=(*ne); ++j) { + printf("%f14.4", a[j]); + if (j%4 == 0) printf("\n"); + } + printf("\n"); + } + } +/* Set components of INFO to zero */ + for (i__ = 1; i__ <= 10; ++i__) { + info[i__] = 0; +/* L8: */ + } +/* Compute maximum matching with MC21A/AD */ + if (*job == 1) { +/* Put length of column J in IW(J) */ + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + iw[j] = ip[j + 1] - ip[j]; +/* L10: */ + } +/* IW(N+1:5N) is workspace */ +#if 0 + mc21ad_(n, &irn[1], ne, &ip[1], &iw[1], &cperm[1], num, &iw[*n+1]); +#else + printf(" ****** Warning from MC64A/AD. Need to link mc21ad.\n"); +#endif + goto L90; + } +/* Compute bottleneck matching */ + if (*job == 2) { +/* IW(1:5N), DW(1:N) are workspaces */ + mc64bd_(n, ne, &ip[1], &irn[1], &a[1], &cperm[1], num, &iw[1], &iw[*n + + 1], &iw[(*n << 1) + 1], &iw[*n * 3 + 1], &dw[1]); + goto L90; + } +/* Compute bottleneck matching */ + if (*job == 3) { +/* Copy IRN(K) into IW(K), ABS(A(K)) into DW(K), K=1..NE */ + i__1 = *ne; + for (k = 1; k <= i__1; ++k) { + iw[k] = irn[k]; + dw[k] = (d__1 = a[k], abs(d__1)); +/* L20: */ + } +/* Sort entries in each column by decreasing value. */ + mc64rd_(n, ne, &ip[1], &iw[1], &dw[1]); +/* IW(NE+1:NE+10N) is workspace */ + mc64sd_(n, ne, &ip[1], &iw[1], &dw[1], &cperm[1], num, &iw[*ne + 1], & + iw[*ne + *n + 1], &iw[*ne + (*n << 1) + 1], &iw[*ne + *n * 3 + + 1], &iw[*ne + (*n << 2) + 1], &iw[*ne + *n * 5 + 1], &iw[* + ne + *n * 6 + 1]); + goto L90; + } + if (*job == 4) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + fact = 0.; + i__2 = ip[j + 1] - 1; + for (k = ip[j]; k <= i__2; ++k) { + if ((d__1 = a[k], abs(d__1)) > fact) { + fact = (d__2 = a[k], abs(d__2)); + } +/* L30: */ + } + i__2 = ip[j + 1] - 1; + for (k = ip[j]; k <= i__2; ++k) { + dw[(*n << 1) + k] = fact - (d__1 = a[k], abs(d__1)); +/* L40: */ + } +/* L50: */ + } +/* B = DW(2N+1:2N+NE); IW(1:5N) and DW(1:2N) are workspaces */ + mc64wd_(n, ne, &ip[1], &irn[1], &dw[(*n << 1) + 1], &cperm[1], num, & + iw[1], &iw[*n + 1], &iw[(*n << 1) + 1], &iw[*n * 3 + 1], &iw[( + *n << 2) + 1], &dw[1], &dw[*n + 1]); + goto L90; + } + if (*job == 5) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + fact = 0.; + i__2 = ip[j + 1] - 1; + for (k = ip[j]; k <= i__2; ++k) { + dw[*n * 3 + k] = (d__1 = a[k], abs(d__1)); + if (dw[*n * 3 + k] > fact) { + fact = dw[*n * 3 + k]; + } +/* L60: */ + } + dw[(*n << 1) + j] = fact; + if (fact != 0.) { + fact = log(fact); + } else { + fact = rinf / *n; + } + i__2 = ip[j + 1] - 1; + for (k = ip[j]; k <= i__2; ++k) { + if (dw[*n * 3 + k] != 0.) { + dw[*n * 3 + k] = fact - log(dw[*n * 3 + k]); + } else { + dw[*n * 3 + k] = rinf / *n; + } +/* L70: */ + } +/* L75: */ + } +/* B = DW(3N+1:3N+NE); IW(1:5N) and DW(1:2N) are workspaces */ + mc64wd_(n, ne, &ip[1], &irn[1], &dw[*n * 3 + 1], &cperm[1], num, &iw[ + 1], &iw[*n + 1], &iw[(*n << 1) + 1], &iw[*n * 3 + 1], &iw[(*n + << 2) + 1], &dw[1], &dw[*n + 1]); + if (*num == *n) { + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (dw[(*n << 1) + j] != 0.) { + dw[*n + j] -= log(dw[(*n << 1) + j]); + } else { + dw[*n + j] = 0.; + } +/* L80: */ + } + } +/* Check size of scaling factors */ + fact = log(rinf) * .5f; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (dw[j] < fact && dw[*n + j] < fact) { + goto L86; + } + info[1] = 2; + goto L90; +L86: + ; + } +/* GO TO 90 */ + } +L90: + if (info[1] == 0 && *num < *n) { +/* Matrix is structurally singular, return with warning */ + info[1] = 1; + if (icntl[2] >= 0) { + printf(" ****** Warning from MC64A/AD. INFO(1) = %2d" + " The matrix is structurally singular.\n", info[1]); + } + } + if (info[1] == 2) { +/* Scaling factors are large, return with warning */ + if (icntl[2] >= 0) { + printf(" ****** Warning from MC64A/AD. INFO(1) = %2d\n" + " Some scaling factors may be too large.\n", info[1]); + } + } +/* Print diagnostics on output */ + if (icntl[3] >= 0) { + printf(" ****** Output parameters for MC64A/AD: INFO(1:2) = %8d%8d\n", + info[1], info[2]); + printf(" NUM = %8d", *num); + printf(" CPERM(1:N) = "); + for (j=1; j<=*n; ++j) { + printf("%8d", cperm[j]); + if (j%8 == 0) printf("\n"); + } + if (*job == 5) { + printf("\n DW(1:N) = "); + for (j=1; j<=*n; ++j) { + printf("%11.3f", dw[j]); + if (j%5 == 0) printf("\n"); + } + printf("\n DW(N+1:2N) = "); + for (j=1; j<=*n; ++j) { + printf("%11.3f", dw[*n+j]); + if (j%5 == 0) printf("\n"); + } + printf("\n"); + } + } +/* Return from subroutine. */ +L99: + return 0; +} /* mc64ad_ */ + +/* ********************************************************************** */ +/* Subroutine */ int_t mc64bd_(int_t *n, int_t *ne, int_t *ip, int_t * + irn, double *a, int_t *iperm, int_t *num, int_t *jperm, + int_t *pr, int_t *q, int_t *l, double *d__) +{ + /* System generated locals */ + int_t i__1, i__2, i__3; + double d__1, d__2, d__3; + int_t c__1 = 1; + + /* Local variables */ + int_t i__, j, k; + double a0; + int_t i0, q0; + double ai, di; + int_t ii, jj, kk; + double bv; + int_t up; + double dq0; + int_t kk1, kk2; + double csp; + int_t isp, jsp, low; + double dnew; + int_t jord, qlen, idum, jdum; + double rinf; + extern /* Subroutine */ int_t mc64dd_(int_t *, int_t *, int_t *, + double *, int_t *, int_t *), mc64ed_(int_t *, int_t *, + int_t *, double *, int_t *, int_t *), mc64fd_(int_t * + , int_t *, int_t *, int_t *, double *, int_t *, int_t *); + + +/* *** Copyright (c) 1999 Council for the Central Laboratory of the */ +/* Research Councils *** */ +/* *** Although every effort has been made to ensure robustness and *** */ +/* *** reliability of the subroutines in this MC64 suite, we *** */ +/* *** disclaim any liability arising through the use or misuse of *** */ +/* *** any of the subroutines. *** */ +/* *** Any problems? Contact ... */ +/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */ + +/* N, NE, IP, IRN are described in MC64A/AD. */ +/* A is a REAL (DOUBLE PRECISION in the D-version) array of length */ +/* NE. A(K), K=1..NE, must be set to the value of the entry */ +/* that corresponds to IRN(K). It is not altered. */ +/* IPERM is an INT_T array of length N. On exit, it contains the */ +/* matching: IPERM(I) = 0 or row I is matched to column IPERM(I). */ +/* NUM is INT_T variable. On exit, it contains the cardinality of the */ +/* matching stored in IPERM. */ +/* IW is an INT_T work array of length 4N. */ +/* DW is a REAL (DOUBLE PRECISION in D-version) work array of length N. */ +/* Local variables */ +/* Local parameters */ +/* Intrinsic functions */ +/* External subroutines and/or functions */ +/* EXTERNAL FD05AD,MC64DD,MC64ED,MC64FD, DMACH */ +/* DOUBLE PRECISION FD05AD, DMACH */ +/* Set RINF to largest positive real number */ +/* XSL RINF = FD05AD(5) */ + /* Parameter adjustments */ + --d__; + --l; + --q; + --pr; + --jperm; + --iperm; + --ip; + --a; + --irn; + + /* Function Body */ + rinf = dmach("Overflow"); +/* Initialization */ + *num = 0; + bv = rinf; + i__1 = *n; + for (k = 1; k <= i__1; ++k) { + iperm[k] = 0; + jperm[k] = 0; + pr[k] = ip[k]; + d__[k] = 0.; +/* L10: */ + } +/* Scan columns of matrix; */ + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + a0 = -1.; + i__2 = ip[j + 1] - 1; + for (k = ip[j]; k <= i__2; ++k) { + i__ = irn[k]; + ai = (d__1 = a[k], abs(d__1)); + if (ai > d__[i__]) { + d__[i__] = ai; + } + if (jperm[j] != 0) { + goto L30; + } + if (ai >= bv) { + a0 = bv; + if (iperm[i__] != 0) { + goto L30; + } + jperm[j] = i__; + iperm[i__] = j; + ++(*num); + } else { + if (ai <= a0) { + goto L30; + } + a0 = ai; + i0 = i__; + } +L30: + ; + } + if (a0 != -1. && a0 < bv) { + bv = a0; + if (iperm[i0] != 0) { + goto L20; + } + iperm[i0] = j; + jperm[j] = i0; + ++(*num); + } +L20: + ; + } +/* Update BV with smallest of all the largest maximum absolute values */ +/* of the rows. */ + i__1 = *n; + for (i__ = 1; i__ <= i__1; ++i__) { +/* Computing MIN */ + d__1 = bv, d__2 = d__[i__]; + bv = min(d__1,d__2); +/* L25: */ + } + if (*num == *n) { + goto L1000; + } +/* Rescan unassigned columns; improve initial assignment */ + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (jperm[j] != 0) { + goto L95; + } + i__2 = ip[j + 1] - 1; + for (k = ip[j]; k <= i__2; ++k) { + i__ = irn[k]; + ai = (d__1 = a[k], abs(d__1)); + if (ai < bv) { + goto L50; + } + if (iperm[i__] == 0) { + goto L90; + } + jj = iperm[i__]; + kk1 = pr[jj]; + kk2 = ip[jj + 1] - 1; + if (kk1 > kk2) { + goto L50; + } + i__3 = kk2; + for (kk = kk1; kk <= i__3; ++kk) { + ii = irn[kk]; + if (iperm[ii] != 0) { + goto L70; + } + if ((d__1 = a[kk], abs(d__1)) >= bv) { + goto L80; + } +L70: + ; + } + pr[jj] = kk2 + 1; +L50: + ; + } + goto L95; +L80: + jperm[jj] = ii; + iperm[ii] = jj; + pr[jj] = kk + 1; +L90: + ++(*num); + jperm[j] = i__; + iperm[i__] = j; + pr[j] = k + 1; +L95: + ; + } + if (*num == *n) { + goto L1000; + } +/* Prepare for main loop */ + i__1 = *n; + for (i__ = 1; i__ <= i__1; ++i__) { + d__[i__] = -1.; + l[i__] = 0; +/* L99: */ + } +/* Main loop ... each pass round this loop is similar to Dijkstra's */ +/* algorithm for solving the single source shortest path problem */ + i__1 = *n; + for (jord = 1; jord <= i__1; ++jord) { + if (jperm[jord] != 0) { + goto L100; + } + qlen = 0; + low = *n + 1; + up = *n + 1; +/* CSP is cost of shortest path to any unassigned row */ +/* ISP is matrix position of unassigned row element in shortest path */ +/* JSP is column index of unassigned row element in shortest path */ + csp = -1.; +/* Build shortest path tree starting from unassigned column JORD */ + j = jord; + pr[j] = -1; +/* Scan column J */ + i__2 = ip[j + 1] - 1; + for (k = ip[j]; k <= i__2; ++k) { + i__ = irn[k]; + dnew = (d__1 = a[k], abs(d__1)); + if (csp >= dnew) { + goto L115; + } + if (iperm[i__] == 0) { +/* Row I is unassigned; update shortest path info */ + csp = dnew; + isp = i__; + jsp = j; + if (csp >= bv) { + goto L160; + } + } else { + d__[i__] = dnew; + if (dnew >= bv) { +/* Add row I to Q2 */ + --low; + q[low] = i__; + } else { +/* Add row I to Q, and push it */ + ++qlen; + l[i__] = qlen; + mc64dd_(&i__, n, &q[1], &d__[1], &l[1], &c__1); + } + jj = iperm[i__]; + pr[jj] = j; + } +L115: + ; + } + i__2 = *num; + for (jdum = 1; jdum <= i__2; ++jdum) { +/* If Q2 is empty, extract new rows from Q */ + if (low == up) { + if (qlen == 0) { + goto L160; + } + i__ = q[1]; + if (csp >= d__[i__]) { + goto L160; + } + bv = d__[i__]; + i__3 = *n; + for (idum = 1; idum <= i__3; ++idum) { + mc64ed_(&qlen, n, &q[1], &d__[1], &l[1], &c__1); + l[i__] = 0; + --low; + q[low] = i__; + if (qlen == 0) { + goto L153; + } + i__ = q[1]; + if (d__[i__] != bv) { + goto L153; + } +/* L152: */ + } +/* End of dummy loop; this point is never reached */ + } +/* Move row Q0 */ +L153: + --up; + q0 = q[up]; + dq0 = d__[q0]; + l[q0] = up; +/* Scan column that matches with row Q0 */ + j = iperm[q0]; + i__3 = ip[j + 1] - 1; + for (k = ip[j]; k <= i__3; ++k) { + i__ = irn[k]; +/* Update D(I) */ + if (l[i__] >= up) { + goto L155; + } +/* Computing MIN */ + d__2 = dq0, d__3 = (d__1 = a[k], abs(d__1)); + dnew = min(d__2,d__3); + if (csp >= dnew) { + goto L155; + } + if (iperm[i__] == 0) { +/* Row I is unassigned; update shortest path info */ + csp = dnew; + isp = i__; + jsp = j; + if (csp >= bv) { + goto L160; + } + } else { + di = d__[i__]; + if (di >= bv || di >= dnew) { + goto L155; + } + d__[i__] = dnew; + if (dnew >= bv) { +/* Delete row I from Q (if necessary); add row I to Q2 */ + if (di != -1.) { + mc64fd_(&l[i__], &qlen, n, &q[1], &d__[1], &l[1], + &c__1); + } + l[i__] = 0; + --low; + q[low] = i__; + } else { +/* Add row I to Q (if necessary); push row I up Q */ + if (di == -1.) { + ++qlen; + l[i__] = qlen; + } + mc64dd_(&i__, n, &q[1], &d__[1], &l[1], &c__1); + } +/* Update tree */ + jj = iperm[i__]; + pr[jj] = j; + } +L155: + ; + } +/* L150: */ + } +/* If CSP = MINONE, no augmenting path is found */ +L160: + if (csp == -1.) { + goto L190; + } +/* Update bottleneck value */ + bv = min(bv,csp); +/* Find augmenting path by tracing backward in PR; update IPERM,JPERM */ + ++(*num); + i__ = isp; + j = jsp; + i__2 = *num + 1; + for (jdum = 1; jdum <= i__2; ++jdum) { + i0 = jperm[j]; + jperm[j] = i__; + iperm[i__] = j; + j = pr[j]; + if (j == -1) { + goto L190; + } + i__ = i0; +/* L170: */ + } +/* End of dummy loop; this point is never reached */ +L190: + i__2 = *n; + for (kk = up; kk <= i__2; ++kk) { + i__ = q[kk]; + d__[i__] = -1.; + l[i__] = 0; +/* L191: */ + } + i__2 = up - 1; + for (kk = low; kk <= i__2; ++kk) { + i__ = q[kk]; + d__[i__] = -1.; +/* L192: */ + } + i__2 = qlen; + for (kk = 1; kk <= i__2; ++kk) { + i__ = q[kk]; + d__[i__] = -1.; + l[i__] = 0; +/* L193: */ + } +L100: + ; + } +/* End of main loop */ +/* BV is bottleneck value of final matching */ + if (*num == *n) { + goto L1000; + } +/* Matrix is structurally singular, complete IPERM. */ +/* JPERM, PR are work arrays */ + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + jperm[j] = 0; +/* L300: */ + } + k = 0; + i__1 = *n; + for (i__ = 1; i__ <= i__1; ++i__) { + if (iperm[i__] == 0) { + ++k; + pr[k] = i__; + } else { + j = iperm[i__]; + jperm[j] = i__; + } +/* L310: */ + } + k = 0; + i__1 = *n; + for (i__ = 1; i__ <= i__1; ++i__) { + if (jperm[i__] != 0) { + goto L320; + } + ++k; + jdum = pr[k]; + iperm[jdum] = i__; +L320: + ; + } +L1000: + return 0; +} /* mc64bd_ */ + +/* ********************************************************************** */ +/* Subroutine */ int_t mc64dd_(int_t *i__, int_t *n, int_t *q, double + *d__, int_t *l, int_t *iway) +{ + /* System generated locals */ + int_t i__1; + int_t c__1 = 1; + + /* Local variables */ + double di; + int_t qk, pos, idum, posk; + + +/* *** Copyright (c) 1999 Council for the Central Laboratory of the */ +/* Research Councils *** */ +/* *** Although every effort has been made to ensure robustness and *** */ +/* *** reliability of the subroutines in this MC64 suite, we *** */ +/* *** disclaim any liability arising through the use or misuse of *** */ +/* *** any of the subroutines. *** */ +/* *** Any problems? Contact ... */ +/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */ + +/* Variables N,Q,D,L are described in MC64B/BD */ +/* IF IWAY is equal to 1, then */ +/* node I is pushed from its current position upwards */ +/* IF IWAY is not equal to 1, then */ +/* node I is pushed from its current position downwards */ +/* Local variables and parameters */ + /* Parameter adjustments */ + --l; + --d__; + --q; + + /* Function Body */ + di = d__[*i__]; + pos = l[*i__]; +/* POS is index of current position of I in the tree */ + if (*iway == 1) { + i__1 = *n; + for (idum = 1; idum <= i__1; ++idum) { + if (pos <= 1) { + goto L20; + } + posk = pos / 2; + qk = q[posk]; + if (di <= d__[qk]) { + goto L20; + } + q[pos] = qk; + l[qk] = pos; + pos = posk; +/* L10: */ + } +/* End of dummy loop; this point is never reached */ + } else { + i__1 = *n; + for (idum = 1; idum <= i__1; ++idum) { + if (pos <= 1) { + goto L20; + } + posk = pos / 2; + qk = q[posk]; + if (di >= d__[qk]) { + goto L20; + } + q[pos] = qk; + l[qk] = pos; + pos = posk; +/* L15: */ + } +/* End of dummy loop; this point is never reached */ + } +/* End of dummy if; this point is never reached */ +L20: + q[pos] = *i__; + l[*i__] = pos; + return 0; +} /* mc64dd_ */ + +/* ********************************************************************** */ +/* Subroutine */ int_t mc64ed_(int_t *qlen, int_t *n, int_t *q, + double *d__, int_t *l, int_t *iway) +{ + /* System generated locals */ + int_t i__1; + + /* Local variables */ + int_t i__; + double di, dk, dr; + int_t pos, idum, posk; + + +/* *** Copyright (c) 1999 Council for the Central Laboratory of the */ +/* Research Councils *** */ +/* *** Although every effort has been made to ensure robustness and *** */ +/* *** reliability of the subroutines in this MC64 suite, we *** */ +/* *** disclaim any liability arising through the use or misuse of *** */ +/* *** any of the subroutines. *** */ +/* *** Any problems? Contact ... */ +/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */ + +/* Variables QLEN,N,Q,D,L are described in MC64B/BD (IWAY = 1) or */ +/* MC64W/WD (IWAY = 2) */ +/* The root node is deleted from the binary heap. */ +/* Local variables and parameters */ +/* Move last element to begin of Q */ + /* Parameter adjustments */ + --l; + --d__; + --q; + + /* Function Body */ + i__ = q[*qlen]; + di = d__[i__]; + --(*qlen); + pos = 1; + if (*iway == 1) { + i__1 = *n; + for (idum = 1; idum <= i__1; ++idum) { + posk = pos << 1; + if (posk > *qlen) { + goto L20; + } + dk = d__[q[posk]]; + if (posk < *qlen) { + dr = d__[q[posk + 1]]; + if (dk < dr) { + ++posk; + dk = dr; + } + } + if (di >= dk) { + goto L20; + } +/* Exchange old last element with larger priority child */ + q[pos] = q[posk]; + l[q[pos]] = pos; + pos = posk; +/* L10: */ + } +/* End of dummy loop; this point is never reached */ + } else { + i__1 = *n; + for (idum = 1; idum <= i__1; ++idum) { + posk = pos << 1; + if (posk > *qlen) { + goto L20; + } + dk = d__[q[posk]]; + if (posk < *qlen) { + dr = d__[q[posk + 1]]; + if (dk > dr) { + ++posk; + dk = dr; + } + } + if (di <= dk) { + goto L20; + } +/* Exchange old last element with smaller child */ + q[pos] = q[posk]; + l[q[pos]] = pos; + pos = posk; +/* L15: */ + } +/* End of dummy loop; this point is never reached */ + } +/* End of dummy if; this point is never reached */ +L20: + q[pos] = i__; + l[i__] = pos; + return 0; +} /* mc64ed_ */ + +/* ********************************************************************** */ +/* Subroutine */ int_t mc64fd_(int_t *pos0, int_t *qlen, int_t *n, + int_t *q, double *d__, int_t *l, int_t *iway) +{ + /* System generated locals */ + int_t i__1; + + /* Local variables */ + int_t i__; + double di, dk, dr; + int_t qk, pos, idum, posk; + + +/* *** Copyright (c) 1999 Council for the Central Laboratory of the */ +/* Research Councils *** */ +/* *** Although every effort has been made to ensure robustness and *** */ +/* *** reliability of the subroutines in this MC64 suite, we *** */ +/* *** disclaim any liability arising through the use or misuse of *** */ +/* *** any of the subroutines. *** */ +/* *** Any problems? Contact ... */ +/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */ + +/* Variables QLEN,N,Q,D,L are described in MC64B/BD (IWAY = 1) or */ +/* MC64WD (IWAY = 2). */ +/* Move last element in the heap */ +/* Quick return, if possible */ + /* Parameter adjustments */ + --l; + --d__; + --q; + + /* Function Body */ + if (*qlen == *pos0) { + --(*qlen); + return 0; + } +/* Move last element from queue Q to position POS0 */ +/* POS is current position of node I in the tree */ + i__ = q[*qlen]; + di = d__[i__]; + --(*qlen); + pos = *pos0; + if (*iway == 1) { + i__1 = *n; + for (idum = 1; idum <= i__1; ++idum) { + if (pos <= 1) { + goto L20; + } + posk = pos / 2; + qk = q[posk]; + if (di <= d__[qk]) { + goto L20; + } + q[pos] = qk; + l[qk] = pos; + pos = posk; +/* L10: */ + } +/* End of dummy loop; this point is never reached */ +L20: + q[pos] = i__; + l[i__] = pos; + i__1 = *n; + for (idum = 1; idum <= i__1; ++idum) { + posk = pos << 1; + if (posk > *qlen) { + goto L40; + } + dk = d__[q[posk]]; + if (posk < *qlen) { + dr = d__[q[posk + 1]]; + if (dk < dr) { + ++posk; + dk = dr; + } + } + if (di >= dk) { + goto L40; + } + qk = q[posk]; + q[pos] = qk; + l[qk] = pos; + pos = posk; +/* L30: */ + } +/* End of dummy loop; this point is never reached */ + } else { + i__1 = *n; + for (idum = 1; idum <= i__1; ++idum) { + if (pos <= 1) { + goto L34; + } + posk = pos / 2; + qk = q[posk]; + if (di >= d__[qk]) { + goto L34; + } + q[pos] = qk; + l[qk] = pos; + pos = posk; +/* L32: */ + } +/* End of dummy loop; this point is never reached */ +L34: + q[pos] = i__; + l[i__] = pos; + i__1 = *n; + for (idum = 1; idum <= i__1; ++idum) { + posk = pos << 1; + if (posk > *qlen) { + goto L40; + } + dk = d__[q[posk]]; + if (posk < *qlen) { + dr = d__[q[posk + 1]]; + if (dk > dr) { + ++posk; + dk = dr; + } + } + if (di <= dk) { + goto L40; + } + qk = q[posk]; + q[pos] = qk; + l[qk] = pos; + pos = posk; +/* L36: */ + } +/* End of dummy loop; this point is never reached */ + } +/* End of dummy if; this point is never reached */ +L40: + q[pos] = i__; + l[i__] = pos; + return 0; +} /* mc64fd_ */ + +/* ********************************************************************** */ +/* Subroutine */ int_t mc64rd_(int_t *n, int_t *ne, int_t *ip, int_t * + irn, double *a) +{ + /* System generated locals */ + int_t i__1, i__2, i__3; + + /* Local variables */ + int_t j, k, r__, s; + double ha; + int_t hi, td, mid, len, ipj; + double key; + int_t last, todo[50], first; + + +/* *** Copyright (c) 1999 Council for the Central Laboratory of the */ +/* Research Councils *** */ +/* *** Although every effort has been made to ensure robustness and *** */ +/* *** reliability of the subroutines in this MC64 suite, we *** */ +/* *** disclaim any liability arising through the use or misuse of *** */ +/* *** any of the subroutines. *** */ +/* *** Any problems? Contact ... */ +/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */ + +/* This subroutine sorts the entries in each column of the */ +/* sparse matrix (defined by N,NE,IP,IRN,A) by decreasing */ +/* numerical value. */ +/* Local constants */ +/* Local variables */ +/* Local arrays */ + /* Parameter adjustments */ + --ip; + --a; + --irn; + + /* Function Body */ + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + len = ip[j + 1] - ip[j]; + if (len <= 1) { + goto L100; + } + ipj = ip[j]; +/* Sort array roughly with partial quicksort */ + if (len < 15) { + goto L400; + } + todo[0] = ipj; + todo[1] = ipj + len; + td = 2; +L500: + first = todo[td - 2]; + last = todo[td - 1]; +/* KEY is the smallest of two values present in interval [FIRST,LAST) */ + key = a[(first + last) / 2]; + i__2 = last - 1; + for (k = first; k <= i__2; ++k) { + ha = a[k]; + if (ha == key) { + goto L475; + } + if (ha > key) { + goto L470; + } + key = ha; + goto L470; +L475: + ; + } +/* Only one value found in interval, so it is already sorted */ + td += -2; + goto L425; +/* Reorder interval [FIRST,LAST) such that entries before MID are gt KEY */ +L470: + mid = first; + i__2 = last - 1; + for (k = first; k <= i__2; ++k) { + if (a[k] <= key) { + goto L450; + } + ha = a[mid]; + a[mid] = a[k]; + a[k] = ha; + hi = irn[mid]; + irn[mid] = irn[k]; + irn[k] = hi; + ++mid; +L450: + ; + } +/* Both subintervals [FIRST,MID), [MID,LAST) are nonempty */ +/* Stack the longest of the two subintervals first */ + if (mid - first >= last - mid) { + todo[td + 1] = last; + todo[td] = mid; + todo[td - 1] = mid; +/* TODO(TD-1) = FIRST */ + } else { + todo[td + 1] = mid; + todo[td] = first; + todo[td - 1] = last; + todo[td - 2] = mid; + } + td += 2; +L425: + if (td == 0) { + goto L400; + } +/* There is still work to be done */ + if (todo[td - 1] - todo[td - 2] >= 15) { + goto L500; + } +/* Next interval is already short enough for straightforward insertion */ + td += -2; + goto L425; +/* Complete sorting with straightforward insertion */ +L400: + i__2 = ipj + len - 1; + for (r__ = ipj + 1; r__ <= i__2; ++r__) { + if (a[r__ - 1] < a[r__]) { + ha = a[r__]; + hi = irn[r__]; + a[r__] = a[r__ - 1]; + irn[r__] = irn[r__ - 1]; + i__3 = ipj + 1; + for (s = r__ - 1; s >= i__3; --s) { + if (a[s - 1] < ha) { + a[s] = a[s - 1]; + irn[s] = irn[s - 1]; + } else { + a[s] = ha; + irn[s] = hi; + goto L200; + } +/* L300: */ + } + a[ipj] = ha; + irn[ipj] = hi; + } +L200: + ; + } +L100: + ; + } + return 0; +} /* mc64rd_ */ + +/* ********************************************************************** */ +/* Subroutine */ int_t mc64sd_(int_t *n, int_t *ne, int_t *ip, int_t * + irn, double *a, int_t *iperm, int_t *numx, int_t *w, + int_t *len, int_t *lenl, int_t *lenh, int_t *fc, int_t *iw, + int_t *iw4) +{ + /* System generated locals */ + int_t i__1, i__2, i__3, i__4; + + /* Local variables */ + int_t i__, j, k, l, ii, mod, cnt, num; + double bval, bmin, bmax, rinf; + int_t nval, wlen, idum1, idum2, idum3; + extern /* Subroutine */ int_t mc64qd_(int_t *, int_t *, int_t *, + int_t *, int_t *, double *, int_t *, double *), + mc64ud_(int_t *, int_t *, int_t *, int_t *, int_t *, + int_t *, int_t *, int_t *, int_t *, int_t *, int_t *, + int_t *, int_t *, int_t *, int_t *); + +/* *** Copyright (c) 1999 Council for the Central Laboratory of the */ +/* Research Councils *** */ +/* *** Although every effort has been made to ensure robustness and *** */ +/* *** reliability of the subroutines in this MC64 suite, we *** */ +/* *** disclaim any liability arising through the use or misuse of *** */ +/* *** any of the subroutines. *** */ +/* *** Any problems? Contact ... */ +/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */ + +/* N, NE, IP, IRN, are described in MC64A/AD. */ +/* A is a REAL (DOUBLE PRECISION in the D-version) array of length NE. */ +/* A(K), K=1..NE, must be set to the value of the entry that */ +/* corresponds to IRN(k). The entries in each column must be */ +/* non-negative and ordered by decreasing value. */ +/* IPERM is an INT_T array of length N. On exit, it contains the */ +/* bottleneck matching: IPERM(I) - 0 or row I is matched to column */ +/* IPERM(I). */ +/* NUMX is an INT_T variable. On exit, it contains the cardinality */ +/* of the matching stored in IPERM. */ +/* IW is an INT_T work array of length 10N. */ +/* FC is an int_t array of length N that contains the list of */ +/* unmatched columns. */ +/* LEN(J), LENL(J), LENH(J) are int_t arrays of length N that point */ +/* to entries in matrix column J. */ +/* In the matrix defined by the column parts IP(J)+LENL(J) we know */ +/* a matching does not exist; in the matrix defined by the column */ +/* parts IP(J)+LENH(J) we know one exists. */ +/* LEN(J) lies between LENL(J) and LENH(J) and determines the matrix */ +/* that is tested for a maximum matching. */ +/* W is an int_t array of length N and contains the indices of the */ +/* columns for which LENL ne LENH. */ +/* WLEN is number of indices stored in array W. */ +/* IW is int_t work array of length N. */ +/* IW4 is int_t work array of length 4N used by MC64U/UD. */ +/* EXTERNAL FD05AD,MC64QD,MC64UD */ +/* DOUBLE PRECISION FD05AD */ +/* BMIN and BMAX are such that a maximum matching exists for the input */ +/* matrix in which all entries smaller than BMIN are dropped. */ +/* For BMAX, a maximum matching does not exist. */ +/* BVAL is a value between BMIN and BMAX. */ +/* CNT is the number of calls made to MC64U/UD so far. */ +/* NUM is the cardinality of last matching found. */ +/* Set RINF to largest positive real number */ +/* XSL RINF = FD05AD(5) */ + /* Parameter adjustments */ + --iw4; + --iw; + --fc; + --lenh; + --lenl; + --len; + --w; + --iperm; + --ip; + --a; + --irn; + + /* Function Body */ + rinf = dmach("Overflow"); +/* Compute a first maximum matching from scratch on whole matrix. */ + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + fc[j] = j; + iw[j] = 0; + len[j] = ip[j + 1] - ip[j]; +/* L20: */ + } +/* The first call to MC64U/UD */ + cnt = 1; + mod = 1; + *numx = 0; + mc64ud_(&cnt, &mod, n, &irn[1], ne, &ip[1], &len[1], &fc[1], &iw[1], numx, + n, &iw4[1], &iw4[*n + 1], &iw4[(*n << 1) + 1], &iw4[*n * 3 + 1]); +/* IW contains a maximum matching of length NUMX. */ + num = *numx; + if (num != *n) { +/* Matrix is structurally singular */ + bmax = rinf; + } else { +/* Matrix is structurally nonsingular, NUM=NUMX=N; */ +/* Set BMAX just above the smallest of all the maximum absolute */ +/* values of the columns */ + bmax = rinf; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + bval = 0.f; + i__2 = ip[j + 1] - 1; + for (k = ip[j]; k <= i__2; ++k) { + if (a[k] > bval) { + bval = a[k]; + } +/* L25: */ + } + if (bval < bmax) { + bmax = bval; + } +/* L30: */ + } + bmax *= 1.001f; + } +/* Initialize BVAL,BMIN */ + bval = 0.f; + bmin = 0.f; +/* Initialize LENL,LEN,LENH,W,WLEN according to BMAX. */ +/* Set LEN(J), LENH(J) just after last entry in column J. */ +/* Set LENL(J) just after last entry in column J with value ge BMAX. */ + wlen = 0; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + l = ip[j + 1] - ip[j]; + lenh[j] = l; + len[j] = l; + i__2 = ip[j + 1] - 1; + for (k = ip[j]; k <= i__2; ++k) { + if (a[k] < bmax) { + goto L46; + } +/* L45: */ + } +/* Column J is empty or all entries are ge BMAX */ + k = ip[j + 1]; +L46: + lenl[j] = k - ip[j]; +/* Add J to W if LENL(J) ne LENH(J) */ + if (lenl[j] == l) { + goto L48; + } + ++wlen; + w[wlen] = j; +L48: + ; + } +/* Main loop */ + i__1 = *ne; + for (idum1 = 1; idum1 <= i__1; ++idum1) { + if (num == *numx) { +/* We have a maximum matching in IW; store IW in IPERM */ + i__2 = *n; + for (i__ = 1; i__ <= i__2; ++i__) { + iperm[i__] = iw[i__]; +/* L50: */ + } +/* Keep going round this loop until matching IW is no longer maximum. */ + i__2 = *ne; + for (idum2 = 1; idum2 <= i__2; ++idum2) { + bmin = bval; + if (bmax == bmin) { + goto L99; + } +/* Find splitting value BVAL */ + mc64qd_(&ip[1], &lenl[1], &len[1], &w[1], &wlen, &a[1], &nval, + &bval); + if (nval <= 1) { + goto L99; + } +/* Set LEN such that all matrix entries with value lt BVAL are */ +/* discarded. Store old LEN in LENH. Do this for all columns W(K). */ +/* Each step, either K is incremented or WLEN is decremented. */ + k = 1; + i__3 = *n; + for (idum3 = 1; idum3 <= i__3; ++idum3) { + if (k > wlen) { + goto L71; + } + j = w[k]; + i__4 = ip[j] + lenl[j]; + for (ii = ip[j] + len[j] - 1; ii >= i__4; --ii) { + if (a[ii] >= bval) { + goto L60; + } + i__ = irn[ii]; + if (iw[i__] != j) { + goto L55; + } +/* Remove entry from matching */ + iw[i__] = 0; + --num; + fc[*n - num] = j; +L55: + ; + } +L60: + lenh[j] = len[j]; +/* IP(J)+LEN(J)-1 is last entry in column ge BVAL */ + len[j] = ii - ip[j] + 1; +/* If LENH(J) = LENL(J), remove J from W */ + if (lenl[j] == lenh[j]) { + w[k] = w[wlen]; + --wlen; + } else { + ++k; + } +/* L70: */ + } +L71: + if (num < *numx) { + goto L81; + } +/* L80: */ + } +/* End of dummy loop; this point is never reached */ +/* Set mode for next call to MC64U/UD */ +L81: + mod = 1; + } else { +/* We do not have a maximum matching in IW. */ + bmax = bval; +/* BMIN is the bottleneck value of a maximum matching; */ +/* for BMAX the matching is not maximum, so BMAX>BMIN */ +/* IF (BMAX .EQ. BMIN) GO TO 99 */ +/* Find splitting value BVAL */ + mc64qd_(&ip[1], &len[1], &lenh[1], &w[1], &wlen, &a[1], &nval, & + bval); + if (nval == 0 || bval == bmin) { + goto L99; + } +/* Set LEN such that all matrix entries with value ge BVAL are */ +/* inside matrix. Store old LEN in LENL. Do this for all columns W(K). */ +/* Each step, either K is incremented or WLEN is decremented. */ + k = 1; + i__2 = *n; + for (idum3 = 1; idum3 <= i__2; ++idum3) { + if (k > wlen) { + goto L88; + } + j = w[k]; + i__3 = ip[j] + lenh[j] - 1; + for (ii = ip[j] + len[j]; ii <= i__3; ++ii) { + if (a[ii] < bval) { + goto L86; + } +/* L85: */ + } +L86: + lenl[j] = len[j]; + len[j] = ii - ip[j]; + if (lenl[j] == lenh[j]) { + w[k] = w[wlen]; + --wlen; + } else { + ++k; + } +/* L87: */ + } +/* End of dummy loop; this point is never reached */ +/* Set mode for next call to MC64U/UD */ +L88: + mod = 0; + } + ++cnt; + mc64ud_(&cnt, &mod, n, &irn[1], ne, &ip[1], &len[1], &fc[1], &iw[1], & + num, numx, &iw4[1], &iw4[*n + 1], &iw4[(*n << 1) + 1], &iw4[* + n * 3 + 1]); +/* IW contains maximum matching of length NUM */ +/* L90: */ + } +/* End of dummy loop; this point is never reached */ +/* BMIN is bottleneck value of final matching */ +L99: + if (*numx == *n) { + goto L1000; + } +/* The matrix is structurally singular, complete IPERM */ +/* W, IW are work arrays */ + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + w[j] = 0; +/* L300: */ + } + k = 0; + i__1 = *n; + for (i__ = 1; i__ <= i__1; ++i__) { + if (iperm[i__] == 0) { + ++k; + iw[k] = i__; + } else { + j = iperm[i__]; + w[j] = i__; + } +/* L310: */ + } + k = 0; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (w[j] != 0) { + goto L320; + } + ++k; + idum1 = iw[k]; + iperm[idum1] = j; +L320: + ; + } +L1000: + return 0; +} /* mc64sd_ */ + +/* ********************************************************************** */ +/* Subroutine */ int_t mc64qd_(int_t *ip, int_t *lenl, int_t *lenh, + int_t *w, int_t *wlen, double *a, int_t *nval, double * + val) +{ + /* System generated locals */ + int_t i__1, i__2, i__3; + + /* Local variables */ + int_t j, k, s; + double ha; + int_t ii, pos; + double split[10]; + + +/* *** Copyright (c) 1999 Council for the Central Laboratory of the */ +/* Research Councils *** */ +/* *** Although every effort has been made to ensure robustness and *** */ +/* *** reliability of the subroutines in this MC64 suite, we *** */ +/* *** disclaim any liability arising through the use or misuse of *** */ +/* *** any of the subroutines. *** */ +/* *** Any problems? Contact ... */ +/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */ + +/* This routine searches for at most XX different numerical values */ +/* in the columns W(1:WLEN). XX>=2. */ +/* Each column J is scanned between IP(J)+LENL(J) and IP(J)+LENH(J)-1 */ +/* until XX values are found or all columns have been considered. */ +/* On output, NVAL is the number of different values that is found */ +/* and SPLIT(1:NVAL) contains the values in decreasing order. */ +/* If NVAL > 0, the routine returns VAL = SPLIT((NVAL+1)/2). */ + +/* Scan columns in W(1:WLEN). For each encountered value, if value not */ +/* already present in SPLIT(1:NVAL), insert value such that SPLIT */ +/* remains sorted by decreasing value. */ +/* The sorting is done by straightforward insertion; therefore the use */ +/* of this routine should be avoided for large XX (XX < 20). */ + /* Parameter adjustments */ + --a; + --w; + --lenh; + --lenl; + --ip; + + /* Function Body */ + *nval = 0; + i__1 = *wlen; + for (k = 1; k <= i__1; ++k) { + j = w[k]; + i__2 = ip[j] + lenh[j] - 1; + for (ii = ip[j] + lenl[j]; ii <= i__2; ++ii) { + ha = a[ii]; + if (*nval == 0) { + split[0] = ha; + *nval = 1; + } else { +/* Check presence of HA in SPLIT */ + for (s = *nval; s >= 1; --s) { + if (split[s - 1] == ha) { + goto L15; + } + if (split[s - 1] > ha) { + pos = s + 1; + goto L21; + } +/* L20: */ + } + pos = 1; +/* The insertion */ +L21: + i__3 = pos; + for (s = *nval; s >= i__3; --s) { + split[s] = split[s - 1]; +/* L22: */ + } + split[pos - 1] = ha; + ++(*nval); + } +/* Exit loop if XX values are found */ + if (*nval == 10) { + goto L11; + } +L15: + ; + } +/* L10: */ + } +/* Determine VAL */ +L11: + if (*nval > 0) { + *val = split[(*nval + 1) / 2 - 1]; + } + return 0; +} /* mc64qd_ */ + +/* ********************************************************************** */ +/* Subroutine */ int_t mc64ud_(int_t *id, int_t *mod, int_t *n, int_t * + irn, int_t *lirn, int_t *ip, int_t *lenc, int_t *fc, int_t * + iperm, int_t *num, int_t *numx, int_t *pr, int_t *arp, + int_t *cv, int_t *out) +{ + /* System generated locals */ + int_t i__1, i__2, i__3, i__4; + + /* Local variables */ + int_t i__, j, k, j1, ii, kk, id0, id1, in1, in2, nfc, num0, num1, num2, + jord, last; + + +/* *** Copyright (c) 1999 Council for the Central Laboratory of the */ +/* Research Councils *** */ +/* *** Although every effort has been made to ensure robustness and *** */ +/* *** reliability of the subroutines in this MC64 suite, we *** */ +/* *** disclaim any liability arising through the use or misuse of *** */ +/* *** any of the subroutines. *** */ +/* *** Any problems? Contact ... */ +/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */ + +/* PR(J) is the previous column to J in the depth first search. */ +/* Array PR is used as workspace in the sorting algorithm. */ +/* Elements (I,IPERM(I)) I=1,..,N are entries at the end of the */ +/* algorithm unless N assignments have not been made in which case */ +/* N-NUM pairs (I,IPERM(I)) will not be entries in the matrix. */ +/* CV(I) is the most recent loop number (ID+JORD) at which row I */ +/* was visited. */ +/* ARP(J) is the number of entries in column J which have been scanned */ +/* when looking for a cheap assignment. */ +/* OUT(J) is one less than the number of entries in column J which have */ +/* not been scanned during one pass through the main loop. */ +/* NUMX is maximum possible size of matching. */ + /* Parameter adjustments */ + --out; + --cv; + --arp; + --pr; + --iperm; + --fc; + --lenc; + --ip; + --irn; + + /* Function Body */ + if (*id == 1) { +/* The first call to MC64U/UD. */ +/* Initialize CV and ARP; parameters MOD, NUMX are not accessed */ + i__1 = *n; + for (i__ = 1; i__ <= i__1; ++i__) { + cv[i__] = 0; + arp[i__] = 0; +/* L5: */ + } + num1 = *n; + num2 = *n; + } else { +/* Not the first call to MC64U/UD. */ +/* Re-initialize ARP if entries were deleted since last call to MC64U/UD */ + if (*mod == 1) { + i__1 = *n; + for (i__ = 1; i__ <= i__1; ++i__) { + arp[i__] = 0; +/* L8: */ + } + } + num1 = *numx; + num2 = *n - *numx; + } + num0 = *num; +/* NUM0 is size of input matching */ +/* NUM1 is maximum possible size of matching */ +/* NUM2 is maximum allowed number of unassigned rows/columns */ +/* NUM is size of current matching */ +/* Quick return if possible */ +/* IF (NUM.EQ.N) GO TO 199 */ +/* NFC is number of rows/columns that could not be assigned */ + nfc = 0; +/* Integers ID0+1 to ID0+N are unique numbers for call ID to MC64U/UD, */ +/* so 1st call uses 1..N, 2nd call uses N+1..2N, etc */ + id0 = (*id - 1) * *n; +/* Main loop. Each pass round this loop either results in a new */ +/* assignment or gives a column with no assignment */ + i__1 = *n; + for (jord = num0 + 1; jord <= i__1; ++jord) { +/* Each pass uses unique number ID1 */ + id1 = id0 + jord; +/* J is unmatched column */ + j = fc[jord - num0]; + pr[j] = -1; + i__2 = jord; + for (k = 1; k <= i__2; ++k) { +/* Look for a cheap assignment */ + if (arp[j] >= lenc[j]) { + goto L30; + } + in1 = ip[j] + arp[j]; + in2 = ip[j] + lenc[j] - 1; + i__3 = in2; + for (ii = in1; ii <= i__3; ++ii) { + i__ = irn[ii]; + if (iperm[i__] == 0) { + goto L80; + } +/* L20: */ + } +/* No cheap assignment in row */ + arp[j] = lenc[j]; +/* Begin looking for assignment chain starting with row J */ +L30: + out[j] = lenc[j] - 1; +/* Inner loop. Extends chain by one or backtracks */ + i__3 = jord; + for (kk = 1; kk <= i__3; ++kk) { + in1 = out[j]; + if (in1 < 0) { + goto L50; + } + in2 = ip[j] + lenc[j] - 1; + in1 = in2 - in1; +/* Forward scan */ + i__4 = in2; + for (ii = in1; ii <= i__4; ++ii) { + i__ = irn[ii]; + if (cv[i__] == id1) { + goto L40; + } +/* Column J has not yet been accessed during this pass */ + j1 = j; + j = iperm[i__]; + cv[i__] = id1; + pr[j] = j1; + out[j1] = in2 - ii - 1; + goto L70; +L40: + ; + } +/* Backtracking step. */ +L50: + j1 = pr[j]; + if (j1 == -1) { +/* No augmenting path exists for column J. */ + ++nfc; + fc[nfc] = j; + if (nfc > num2) { +/* A matching of maximum size NUM1 is not possible */ + last = jord; + goto L101; + } + goto L100; + } + j = j1; +/* L60: */ + } +/* End of dummy loop; this point is never reached */ +L70: + ; + } +/* End of dummy loop; this point is never reached */ +/* New assignment is made. */ +L80: + iperm[i__] = j; + arp[j] = ii - ip[j] + 1; + ++(*num); + i__2 = jord; + for (k = 1; k <= i__2; ++k) { + j = pr[j]; + if (j == -1) { + goto L95; + } + ii = ip[j] + lenc[j] - out[j] - 2; + i__ = irn[ii]; + iperm[i__] = j; +/* L90: */ + } +/* End of dummy loop; this point is never reached */ +L95: + if (*num == num1) { +/* A matching of maximum size NUM1 is found */ + last = jord; + goto L101; + } + +L100: + ; + } +/* All unassigned columns have been considered */ + last = *n; +/* Now, a transversal is computed or is not possible. */ +/* Complete FC before returning. */ +L101: + i__1 = *n; + for (jord = last + 1; jord <= i__1; ++jord) { + ++nfc; + fc[nfc] = fc[jord - num0]; +/* L110: */ + } +/* 199 RETURN */ + return 0; +} /* mc64ud_ */ + +/* ********************************************************************** */ +/* Subroutine */ int_t mc64wd_(int_t *n, int_t *ne, int_t *ip, int_t * + irn, double *a, int_t *iperm, int_t *num, int_t *jperm, + int_t *out, int_t *pr, int_t *q, int_t *l, double *u, + double *d__) +{ + /* System generated locals */ + int_t i__1, i__2, i__3, c__2 = 2; + + /* Local variables */ + int_t i__, j, k, i0, k0, k1, k2, q0; + double di; + int_t ii, jj, kk; + double vj; + int_t up; + double dq0; + int_t kk1, kk2; + double csp; + int_t isp, jsp, low; + double dmin__, dnew; + int_t jord, qlen, jdum; + double rinf; + extern /* Subroutine */ int_t mc64dd_(int_t *, int_t *, int_t *, + double *, int_t *, int_t *), mc64ed_(int_t *, int_t *, + int_t *, double *, int_t *, int_t *), mc64fd_(int_t * + , int_t *, int_t *, int_t *, double *, int_t *, + int_t *); + + +/* *** Copyright (c) 1999 Council for the Central Laboratory of the */ +/* Research Councils *** */ +/* *** Although every effort has been made to ensure robustness and *** */ +/* *** reliability of the subroutines in this MC64 suite, we *** */ +/* *** disclaim any liability arising through the use or misuse of *** */ +/* *** any of the subroutines. *** */ +/* *** Any problems? Contact ... */ +/* Iain Duff (I.Duff@rl.ac.uk) or Jacko Koster (jak@ii.uib.no) *** */ + +/* N, NE, IP, IRN are described in MC64A/AD. */ +/* A is a REAL (DOUBLE PRECISION in the D-version) array of length NE. */ +/* A(K), K=1..NE, must be set to the value of the entry that */ +/* corresponds to IRN(K). It is not altered. */ +/* All values A(K) must be non-negative. */ +/* IPERM is an INT_T array of length N. On exit, it contains the */ +/* weighted matching: IPERM(I) = 0 or row I is matched to column */ +/* IPERM(I). */ +/* NUM is an INT_T variable. On exit, it contains the cardinality of */ +/* the matching stored in IPERM. */ +/* IW is an INT_T work array of length 5N. */ +/* DW is a REAL (DOUBLE PRECISION in the D-version) array of length 2N. */ +/* On exit, U = D(1:N) contains the dual row variable and */ +/* V = D(N+1:2N) contains the dual column variable. If the matrix */ +/* is structurally nonsingular (NUM = N), the following holds: */ +/* U(I)+V(J) <= A(I,J) if IPERM(I) |= J */ +/* U(I)+V(J) = A(I,J) if IPERM(I) = J */ +/* U(I) = 0 if IPERM(I) = 0 */ +/* V(J) = 0 if there is no I for which IPERM(I) = J */ +/* Local variables */ +/* Local parameters */ +/* External subroutines and/or functions */ +/* EXTERNAL FD05AD,MC64DD,MC64ED,MC64FD */ +/* DOUBLE PRECISION FD05AD */ +/* Set RINF to largest positive real number */ +/* XSL RINF = FD05AD(5) */ + /* Parameter adjustments */ + --d__; + --u; + --l; + --q; + --pr; + --out; + --jperm; + --iperm; + --ip; + --a; + --irn; + + /* Function Body */ + rinf = dmach("Overflow"); +/* Initialization */ + *num = 0; + i__1 = *n; + for (k = 1; k <= i__1; ++k) { + u[k] = rinf; + d__[k] = 0.; + iperm[k] = 0; + jperm[k] = 0; + pr[k] = ip[k]; + l[k] = 0; +/* L10: */ + } +/* Initialize U(I) */ + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + i__2 = ip[j + 1] - 1; + for (k = ip[j]; k <= i__2; ++k) { + i__ = irn[k]; + if (a[k] > u[i__]) { + goto L20; + } + u[i__] = a[k]; + iperm[i__] = j; + l[i__] = k; +L20: + ; + } +/* L30: */ + } + i__1 = *n; + for (i__ = 1; i__ <= i__1; ++i__) { + j = iperm[i__]; + if (j == 0) { + goto L40; + } +/* Row I is not empty */ + iperm[i__] = 0; + if (jperm[j] != 0) { + goto L40; + } +/* Assignment of column J to row I */ + ++(*num); + iperm[i__] = j; + jperm[j] = l[i__]; +L40: + ; + } + if (*num == *n) { + goto L1000; + } +/* Scan unassigned columns; improve assignment */ + i__1 = *n; + for (j = 1; j <= i__1; ++j) { +/* JPERM(J) ne 0 iff column J is already assigned */ + if (jperm[j] != 0) { + goto L95; + } + k1 = ip[j]; + k2 = ip[j + 1] - 1; +/* Continue only if column J is not empty */ + if (k1 > k2) { + goto L95; + } + vj = rinf; + i__2 = k2; + for (k = k1; k <= i__2; ++k) { + i__ = irn[k]; + di = a[k] - u[i__]; + if (di > vj) { + goto L50; + } + if (di < vj || di == rinf) { + goto L55; + } + if (iperm[i__] != 0 || iperm[i0] == 0) { + goto L50; + } +L55: + vj = di; + i0 = i__; + k0 = k; +L50: + ; + } + d__[j] = vj; + k = k0; + i__ = i0; + if (iperm[i__] == 0) { + goto L90; + } + i__2 = k2; + for (k = k0; k <= i__2; ++k) { + i__ = irn[k]; + if (a[k] - u[i__] > vj) { + goto L60; + } + jj = iperm[i__]; +/* Scan remaining part of assigned column JJ */ + kk1 = pr[jj]; + kk2 = ip[jj + 1] - 1; + if (kk1 > kk2) { + goto L60; + } + i__3 = kk2; + for (kk = kk1; kk <= i__3; ++kk) { + ii = irn[kk]; + if (iperm[ii] > 0) { + goto L70; + } + if (a[kk] - u[ii] <= d__[jj]) { + goto L80; + } +L70: + ; + } + pr[jj] = kk2 + 1; +L60: + ; + } + goto L95; +L80: + jperm[jj] = kk; + iperm[ii] = jj; + pr[jj] = kk + 1; +L90: + ++(*num); + jperm[j] = k; + iperm[i__] = j; + pr[j] = k + 1; +L95: + ; + } + if (*num == *n) { + goto L1000; + } +/* Prepare for main loop */ + i__1 = *n; + for (i__ = 1; i__ <= i__1; ++i__) { + d__[i__] = rinf; + l[i__] = 0; +/* L99: */ + } +/* Main loop ... each pass round this loop is similar to Dijkstra's */ +/* algorithm for solving the single source shortest path problem */ + i__1 = *n; + for (jord = 1; jord <= i__1; ++jord) { + if (jperm[jord] != 0) { + goto L100; + } +/* JORD is next unmatched column */ +/* DMIN is the length of shortest path in the tree */ + dmin__ = rinf; + qlen = 0; + low = *n + 1; + up = *n + 1; +/* CSP is the cost of the shortest augmenting path to unassigned row */ +/* IRN(ISP). The corresponding column index is JSP. */ + csp = rinf; +/* Build shortest path tree starting from unassigned column (root) JORD */ + j = jord; + pr[j] = -1; +/* Scan column J */ + i__2 = ip[j + 1] - 1; + for (k = ip[j]; k <= i__2; ++k) { + i__ = irn[k]; + dnew = a[k] - u[i__]; + if (dnew >= csp) { + goto L115; + } + if (iperm[i__] == 0) { + csp = dnew; + isp = k; + jsp = j; + } else { + if (dnew < dmin__) { + dmin__ = dnew; + } + d__[i__] = dnew; + ++qlen; + q[qlen] = k; + } +L115: + ; + } +/* Initialize heap Q and Q2 with rows held in Q(1:QLEN) */ + q0 = qlen; + qlen = 0; + i__2 = q0; + for (kk = 1; kk <= i__2; ++kk) { + k = q[kk]; + i__ = irn[k]; + if (csp <= d__[i__]) { + d__[i__] = rinf; + goto L120; + } + if (d__[i__] <= dmin__) { + --low; + q[low] = i__; + l[i__] = low; + } else { + ++qlen; + l[i__] = qlen; + mc64dd_(&i__, n, &q[1], &d__[1], &l[1], &c__2); + } +/* Update tree */ + jj = iperm[i__]; + out[jj] = k; + pr[jj] = j; +L120: + ; + } + i__2 = *num; + for (jdum = 1; jdum <= i__2; ++jdum) { +/* If Q2 is empty, extract rows from Q */ + if (low == up) { + if (qlen == 0) { + goto L160; + } + i__ = q[1]; + if (d__[i__] >= csp) { + goto L160; + } + dmin__ = d__[i__]; +L152: + mc64ed_(&qlen, n, &q[1], &d__[1], &l[1], &c__2); + --low; + q[low] = i__; + l[i__] = low; + if (qlen == 0) { + goto L153; + } + i__ = q[1]; + if (d__[i__] > dmin__) { + goto L153; + } + goto L152; + } +/* Q0 is row whose distance D(Q0) to the root is smallest */ +L153: + q0 = q[up - 1]; + dq0 = d__[q0]; +/* Exit loop if path to Q0 is longer than the shortest augmenting path */ + if (dq0 >= csp) { + goto L160; + } + --up; +/* Scan column that matches with row Q0 */ + j = iperm[q0]; + vj = dq0 - a[jperm[j]] + u[q0]; + i__3 = ip[j + 1] - 1; + for (k = ip[j]; k <= i__3; ++k) { + i__ = irn[k]; + if (l[i__] >= up) { + goto L155; + } +/* DNEW is new cost */ + dnew = vj + a[k] - u[i__]; +/* Do not update D(I) if DNEW ge cost of shortest path */ + if (dnew >= csp) { + goto L155; + } + if (iperm[i__] == 0) { +/* Row I is unmatched; update shortest path info */ + csp = dnew; + isp = k; + jsp = j; + } else { +/* Row I is matched; do not update D(I) if DNEW is larger */ + di = d__[i__]; + if (di <= dnew) { + goto L155; + } + if (l[i__] >= low) { + goto L155; + } + d__[i__] = dnew; + if (dnew <= dmin__) { + if (l[i__] != 0) { + mc64fd_(&l[i__], &qlen, n, &q[1], &d__[1], &l[1], + &c__2); + } + --low; + q[low] = i__; + l[i__] = low; + } else { + if (l[i__] == 0) { + ++qlen; + l[i__] = qlen; + } + mc64dd_(&i__, n, &q[1], &d__[1], &l[1], &c__2); + } +/* Update tree */ + jj = iperm[i__]; + out[jj] = k; + pr[jj] = j; + } +L155: + ; + } +/* L150: */ + } +/* If CSP = RINF, no augmenting path is found */ +L160: + if (csp == rinf) { + goto L190; + } +/* Find augmenting path by tracing backward in PR; update IPERM,JPERM */ + ++(*num); + i__ = irn[isp]; + iperm[i__] = jsp; + jperm[jsp] = isp; + j = jsp; + i__2 = *num; + for (jdum = 1; jdum <= i__2; ++jdum) { + jj = pr[j]; + if (jj == -1) { + goto L180; + } + k = out[j]; + i__ = irn[k]; + iperm[i__] = jj; + jperm[jj] = k; + j = jj; +/* L170: */ + } +/* End of dummy loop; this point is never reached */ +/* Update U for rows in Q(UP:N) */ +L180: + i__2 = *n; + for (kk = up; kk <= i__2; ++kk) { + i__ = q[kk]; + u[i__] = u[i__] + d__[i__] - csp; +/* L185: */ + } +L190: + i__2 = *n; + for (kk = low; kk <= i__2; ++kk) { + i__ = q[kk]; + d__[i__] = rinf; + l[i__] = 0; +/* L191: */ + } + i__2 = qlen; + for (kk = 1; kk <= i__2; ++kk) { + i__ = q[kk]; + d__[i__] = rinf; + l[i__] = 0; +/* L193: */ + } +L100: + ; + } +/* End of main loop */ +/* Set dual column variable in D(1:N) */ +L1000: + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + k = jperm[j]; + if (k != 0) { + d__[j] = a[k] - u[irn[k]]; + } else { + d__[j] = 0.; + } + if (iperm[j] == 0) { + u[j] = 0.; + } +/* L200: */ + } + if (*num == *n) { + goto L1100; + } +/* The matrix is structurally singular, complete IPERM. */ +/* JPERM, OUT are work arrays */ + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + jperm[j] = 0; +/* L300: */ + } + k = 0; + i__1 = *n; + for (i__ = 1; i__ <= i__1; ++i__) { + if (iperm[i__] == 0) { + ++k; + out[k] = i__; + } else { + j = iperm[i__]; + jperm[j] = i__; + } +/* L310: */ + } + k = 0; + i__1 = *n; + for (j = 1; j <= i__1; ++j) { + if (jperm[j] != 0) { + goto L320; + } + ++k; + jdum = out[k]; + iperm[jdum] = j; +L320: + ; + } +L1100: + return 0; +} /* mc64wd_ */ + + diff --git a/src/Libraries/superlu-5.2.1/SRC/memory.c b/src/Libraries/superlu-5.2.1/SRC/memory.c new file mode 100644 index 00000000..aaba7252 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/memory.c @@ -0,0 +1,220 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file memory.c + * \brief Precision-independent memory-related routines + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ */ +/** Precision-independent memory-related routines. + (Shared by [sdcz]memory.c) **/ + +#include "slu_ddefs.h" + + +#if ( DEBUGlevel>=1 ) /* Debug malloc/free. */ +int superlu_malloc_total = 0; + +#define PAD_FACTOR 2 +#define DWORD (sizeof(double)) /* Be sure it's no smaller than double. */ +/* size_t is usually defined as 'unsigned long' */ + +void *superlu_malloc(size_t size) +{ + char *buf; + + buf = (char *) malloc(size + DWORD); + if ( !buf ) { + printf("superlu_malloc fails: malloc_total %.0f MB, size %ld\n", + superlu_malloc_total*1e-6, size); + ABORT("superlu_malloc: out of memory"); + } + + ((size_t_t *) buf)[0] = size; +#if 0 + superlu_malloc_total += size + DWORD; +#else + superlu_malloc_total += size; +#endif + return (void *) (buf + DWORD); +} + +void superlu_free(void *addr) +{ + char *p = ((char *) addr) - DWORD; + + if ( !addr ) + ABORT("superlu_free: tried to free NULL pointer"); + + if ( !p ) + ABORT("superlu_free: tried to free NULL+DWORD pointer"); + + { + int_t n = ((size_t *) p)[0]; + + if ( !n ) + ABORT("superlu_free: tried to free a freed pointer"); + *((size_t *) p) = 0; /* Set to zero to detect duplicate free's. */ +#if 0 + superlu_malloc_total -= (n + DWORD); +#else + superlu_malloc_total -= n; +#endif + + if ( superlu_malloc_total < 0 ) + ABORT("superlu_malloc_total went negative!"); + + /*free (addr);*/ + free (p); + } + +} + +#else /* production mode */ + +void *superlu_malloc(size_t size) +{ + void *buf; + buf = (void *) malloc(size); + return (buf); +} + +void superlu_free(void *addr) +{ + free (addr); +} + +#endif + + +/*! \brief Set up pointers for integer working arrays. + */ +void +SetIWork(int m, int n, int panel_size, int *iworkptr, int **segrep, + int **parent, int **xplore, int **repfnz, int **panel_lsub, + int **xprune, int **marker) +{ + *segrep = iworkptr; + *parent = iworkptr + m; + *xplore = *parent + m; + *repfnz = *xplore + m; + *panel_lsub = *repfnz + panel_size * m; + *xprune = *panel_lsub + panel_size * m; + *marker = *xprune + n; + ifill (*repfnz, m * panel_size, EMPTY); + ifill (*panel_lsub, m * panel_size, EMPTY); +} + + +void +copy_mem_int(int howmany, void *old, void *new) +{ + register int i; + int *iold = old; + int *inew = new; + for (i = 0; i < howmany; i++) inew[i] = iold[i]; +} + + +void +user_bcopy(char *src, char *dest, int bytes) +{ + char *s_ptr, *d_ptr; + + s_ptr = src + bytes - 1; + d_ptr = dest + bytes - 1; + for (; d_ptr >= dest; --s_ptr, --d_ptr ) *d_ptr = *s_ptr; +} + + + +int *intMalloc(int n) +{ + int *buf; + buf = (int *) SUPERLU_MALLOC((size_t) n * sizeof(int)); + if ( !buf ) { + ABORT("SUPERLU_MALLOC fails for buf in intMalloc()"); + } + return (buf); +} + +int *intCalloc(int n) +{ + int *buf; + register int i; + buf = (int *) SUPERLU_MALLOC(n * sizeof(int)); + if ( !buf ) { + ABORT("SUPERLU_MALLOC fails for buf in intCalloc()"); + } + for (i = 0; i < n; ++i) buf[i] = 0; + return (buf); +} + + + +#if 0 +check_expanders() +{ + int p; + printf("Check expanders:\n"); + for (p = 0; p < NO_MEMTYPE; p++) { + printf("type %d, size %d, mem %d\n", + p, expanders[p].size, (int)expanders[p].mem); + } + + return 0; +} + + +StackInfo() +{ + printf("Stack: size %d, used %d, top1 %d, top2 %d\n", + stack.size, stack.used, stack.top1, stack.top2); + return 0; +} + + + +PrintStack(char *msg, GlobalLU_t *Glu) +{ + int i; + int *xlsub, *lsub, *xusub, *usub; + + xlsub = Glu->xlsub; + lsub = Glu->lsub; + xusub = Glu->xusub; + usub = Glu->usub; + + printf("%s\n", msg); + +/* printf("\nUCOL: "); + for (i = 0; i < xusub[ndim]; ++i) + printf("%f ", ucol[i]); + + printf("\nLSUB: "); + for (i = 0; i < xlsub[ndim]; ++i) + printf("%d ", lsub[i]); + + printf("\nUSUB: "); + for (i = 0; i < xusub[ndim]; ++i) + printf("%d ", usub[i]); + + printf("\n");*/ + return 0; +} +#endif + + + diff --git a/src/Libraries/superlu-5.2.1/SRC/mmd.c b/src/Libraries/superlu-5.2.1/SRC/mmd.c new file mode 100644 index 00000000..16a71598 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/mmd.c @@ -0,0 +1,1022 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +typedef int shortint; + +/* *************************************************************** */ +/* *************************************************************** */ +/* **** GENMMD ..... MULTIPLE MINIMUM EXTERNAL DEGREE **** */ +/* *************************************************************** */ +/* *************************************************************** */ + +/* AUTHOR - JOSEPH W.H. LIU */ +/* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */ + +/* PURPOSE - THIS ROUTINE IMPLEMENTS THE MINIMUM DEGREE */ +/* ALGORITHM. IT MAKES USE OF THE IMPLICIT REPRESENTATION */ +/* OF ELIMINATION GRAPHS BY QUOTIENT GRAPHS, AND THE */ +/* NOTION OF INDISTINGUISHABLE NODES. IT ALSO IMPLEMENTS */ +/* THE MODIFICATIONS BY MULTIPLE ELIMINATION AND MINIMUM */ +/* EXTERNAL DEGREE. */ +/* --------------------------------------------- */ +/* CAUTION - THE ADJACENCY VECTOR ADJNCY WILL BE */ +/* DESTROYED. */ +/* --------------------------------------------- */ + +/* INPUT PARAMETERS - */ +/* NEQNS - NUMBER OF EQUATIONS. */ +/* (XADJ,ADJNCY) - THE ADJACENCY STRUCTURE. */ +/* DELTA - TOLERANCE VALUE FOR MULTIPLE ELIMINATION. */ +/* MAXINT - MAXIMUM MACHINE REPRESENTABLE (SHORT) INTEGER */ +/* (ANY SMALLER ESTIMATE WILL DO) FOR MARKING */ +/* NODES. */ + +/* OUTPUT PARAMETERS - */ +/* PERM - THE MINIMUM DEGREE ORDERING. */ +/* INVP - THE INVERSE OF PERM. */ +/* NOFSUB - AN UPPER BOUND ON THE NUMBER OF NONZERO */ +/* SUBSCRIPTS FOR THE COMPRESSED STORAGE SCHEME. */ + +/* WORKING PARAMETERS - */ +/* DHEAD - VECTOR FOR HEAD OF DEGREE LISTS. */ +/* INVP - USED TEMPORARILY FOR DEGREE FORWARD LINK. */ +/* PERM - USED TEMPORARILY FOR DEGREE BACKWARD LINK. */ +/* QSIZE - VECTOR FOR SIZE OF SUPERNODES. */ +/* LLIST - VECTOR FOR TEMPORARY LINKED LISTS. */ +/* MARKER - A TEMPORARY MARKER VECTOR. */ + +/* PROGRAM SUBROUTINES - */ +/* MMDELM, MMDINT, MMDNUM, MMDUPD. */ + +/* *************************************************************** */ + +/* Subroutine */ int genmmd_(int *neqns, int *xadj, shortint *adjncy, + shortint *invp, shortint *perm, int *delta, shortint *dhead, + shortint *qsize, shortint *llist, shortint *marker, int *maxint, + int *nofsub) +{ + /* System generated locals */ + int i__1; + + /* Local variables */ + int mdeg, ehead, i, mdlmt, mdnode; + extern /* Subroutine */ int slu_mmdelm_(int *, int *, shortint *, + shortint *, shortint *, shortint *, shortint *, shortint *, + shortint *, int *, int *), slu_mmdupd_(int *, int *, + int *, shortint *, int *, int *, shortint *, shortint + *, shortint *, shortint *, shortint *, shortint *, int *, + int *), slu_mmdint_(int *, int *, shortint *, shortint *, + shortint *, shortint *, shortint *, shortint *, shortint *), + slu_mmdnum_(int *, shortint *, shortint *, shortint *); + int nextmd, tag, num; + + +/* *************************************************************** */ + + +/* *************************************************************** */ + + /* Parameter adjustments */ + --marker; + --llist; + --qsize; + --dhead; + --perm; + --invp; + --adjncy; + --xadj; + + /* Function Body */ + if (*neqns <= 0) { + return 0; + } + +/* ------------------------------------------------ */ +/* INITIALIZATION FOR THE MINIMUM DEGREE ALGORITHM. */ +/* ------------------------------------------------ */ + *nofsub = 0; + slu_mmdint_(neqns, &xadj[1], &adjncy[1], &dhead[1], &invp[1], &perm[1], & + qsize[1], &llist[1], &marker[1]); + +/* ---------------------------------------------- */ +/* NUM COUNTS THE NUMBER OF ORDERED NODES PLUS 1. */ +/* ---------------------------------------------- */ + num = 1; + +/* ----------------------------- */ +/* ELIMINATE ALL ISOLATED NODES. */ +/* ----------------------------- */ + nextmd = dhead[1]; +L100: + if (nextmd <= 0) { + goto L200; + } + mdnode = nextmd; + nextmd = invp[mdnode]; + marker[mdnode] = *maxint; + invp[mdnode] = -num; + ++num; + goto L100; + +L200: +/* ---------------------------------------- */ +/* SEARCH FOR NODE OF THE MINIMUM DEGREE. */ +/* MDEG IS THE CURRENT MINIMUM DEGREE; */ +/* TAG IS USED TO FACILITATE MARKING NODES. */ +/* ---------------------------------------- */ + if (num > *neqns) { + goto L1000; + } + tag = 1; + dhead[1] = 0; + mdeg = 2; +L300: + if (dhead[mdeg] > 0) { + goto L400; + } + ++mdeg; + goto L300; +L400: +/* ------------------------------------------------- */ +/* USE VALUE OF DELTA TO SET UP MDLMT, WHICH GOVERNS */ +/* WHEN A DEGREE UPDATE IS TO BE PERFORMED. */ +/* ------------------------------------------------- */ + mdlmt = mdeg + *delta; + ehead = 0; + +L500: + mdnode = dhead[mdeg]; + if (mdnode > 0) { + goto L600; + } + ++mdeg; + if (mdeg > mdlmt) { + goto L900; + } + goto L500; +L600: +/* ---------------------------------------- */ +/* REMOVE MDNODE FROM THE DEGREE STRUCTURE. */ +/* ---------------------------------------- */ + nextmd = invp[mdnode]; + dhead[mdeg] = nextmd; + if (nextmd > 0) { + perm[nextmd] = -mdeg; + } + invp[mdnode] = -num; + *nofsub = *nofsub + mdeg + qsize[mdnode] - 2; + if (num + qsize[mdnode] > *neqns) { + goto L1000; + } +/* ---------------------------------------------- */ +/* ELIMINATE MDNODE AND PERFORM QUOTIENT GRAPH */ +/* TRANSFORMATION. RESET TAG VALUE IF NECESSARY. */ +/* ---------------------------------------------- */ + ++tag; + if (tag < *maxint) { + goto L800; + } + tag = 1; + i__1 = *neqns; + for (i = 1; i <= i__1; ++i) { + if (marker[i] < *maxint) { + marker[i] = 0; + } +/* L700: */ + } +L800: + slu_mmdelm_(&mdnode, &xadj[1], &adjncy[1], &dhead[1], &invp[1], &perm[1], & + qsize[1], &llist[1], &marker[1], maxint, &tag); + num += qsize[mdnode]; + llist[mdnode] = ehead; + ehead = mdnode; + if (*delta >= 0) { + goto L500; + } +L900: +/* ------------------------------------------- */ +/* UPDATE DEGREES OF THE NODES INVOLVED IN THE */ +/* MINIMUM DEGREE NODES ELIMINATION. */ +/* ------------------------------------------- */ + if (num > *neqns) { + goto L1000; + } + slu_mmdupd_(&ehead, neqns, &xadj[1], &adjncy[1], delta, &mdeg, &dhead[1], & + invp[1], &perm[1], &qsize[1], &llist[1], &marker[1], maxint, &tag) + ; + goto L300; + +L1000: + slu_mmdnum_(neqns, &perm[1], &invp[1], &qsize[1]); + return 0; + +} /* genmmd_ */ + +/* *************************************************************** */ +/* *************************************************************** */ +/* *** MMDINT ..... MULT MINIMUM DEGREE INITIALIZATION *** */ +/* *************************************************************** */ +/* *************************************************************** */ + +/* AUTHOR - JOSEPH W.H. LIU */ +/* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */ + +/* PURPOSE - THIS ROUTINE PERFORMS INITIALIZATION FOR THE */ +/* MULTIPLE ELIMINATION VERSION OF THE MINIMUM DEGREE */ +/* ALGORITHM. */ + +/* INPUT PARAMETERS - */ +/* NEQNS - NUMBER OF EQUATIONS. */ +/* (XADJ,ADJNCY) - ADJACENCY STRUCTURE. */ + +/* OUTPUT PARAMETERS - */ +/* (DHEAD,DFORW,DBAKW) - DEGREE DOUBLY LINKED STRUCTURE. */ +/* QSIZE - SIZE OF SUPERNODE (INITIALIZED TO ONE). */ +/* LLIST - LINKED LIST. */ +/* MARKER - MARKER VECTOR. */ + +/* *************************************************************** */ + +/* Subroutine */ int slu_mmdint_(int *neqns, int *xadj, shortint *adjncy, + shortint *dhead, shortint *dforw, shortint *dbakw, shortint *qsize, + shortint *llist, shortint *marker) +{ + /* System generated locals */ + int i__1; + + /* Local variables */ + int ndeg, node, fnode; + + +/* *************************************************************** */ + + +/* *************************************************************** */ + + /* Parameter adjustments */ + --marker; + --llist; + --qsize; + --dbakw; + --dforw; + --dhead; + --adjncy; + --xadj; + + /* Function Body */ + i__1 = *neqns; + for (node = 1; node <= i__1; ++node) { + dhead[node] = 0; + qsize[node] = 1; + marker[node] = 0; + llist[node] = 0; +/* L100: */ + } +/* ------------------------------------------ */ +/* INITIALIZE THE DEGREE DOUBLY LINKED LISTS. */ +/* ------------------------------------------ */ + i__1 = *neqns; + for (node = 1; node <= i__1; ++node) { + ndeg = xadj[node + 1] - xadj[node] + 1; + fnode = dhead[ndeg]; + dforw[node] = fnode; + dhead[ndeg] = node; + if (fnode > 0) { + dbakw[fnode] = node; + } + dbakw[node] = -ndeg; +/* L200: */ + } + return 0; + +} /* slu_mmdint_ */ + +/* *************************************************************** */ +/* *************************************************************** */ +/* ** MMDELM ..... MULTIPLE MINIMUM DEGREE ELIMINATION *** */ +/* *************************************************************** */ +/* *************************************************************** */ + +/* AUTHOR - JOSEPH W.H. LIU */ +/* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */ + +/* PURPOSE - THIS ROUTINE ELIMINATES THE NODE MDNODE OF */ +/* MINIMUM DEGREE FROM THE ADJACENCY STRUCTURE, WHICH */ +/* IS STORED IN THE QUOTIENT GRAPH FORMAT. IT ALSO */ +/* TRANSFORMS THE QUOTIENT GRAPH REPRESENTATION OF THE */ +/* ELIMINATION GRAPH. */ + +/* INPUT PARAMETERS - */ +/* MDNODE - NODE OF MINIMUM DEGREE. */ +/* MAXINT - ESTIMATE OF MAXIMUM REPRESENTABLE (SHORT) */ +/* INT. */ +/* TAG - TAG VALUE. */ + +/* UPDATED PARAMETERS - */ +/* (XADJ,ADJNCY) - UPDATED ADJACENCY STRUCTURE. */ +/* (DHEAD,DFORW,DBAKW) - DEGREE DOUBLY LINKED STRUCTURE. */ +/* QSIZE - SIZE OF SUPERNODE. */ +/* MARKER - MARKER VECTOR. */ +/* LLIST - TEMPORARY LINKED LIST OF ELIMINATED NABORS. */ + +/* *************************************************************** */ + +/* Subroutine */ int slu_mmdelm_(int *mdnode, int *xadj, shortint *adjncy, + shortint *dhead, shortint *dforw, shortint *dbakw, shortint *qsize, + shortint *llist, shortint *marker, int *maxint, int *tag) +{ + /* System generated locals */ + int i__1, i__2; + + /* Local variables */ + int node, link, rloc, rlmt, i, j, nabor, rnode, elmnt, xqnbr, + istop, jstop, istrt, jstrt, nxnode, pvnode, nqnbrs, npv; + + +/* *************************************************************** */ + + +/* *************************************************************** */ + +/* ----------------------------------------------- */ +/* FIND REACHABLE SET AND PLACE IN DATA STRUCTURE. */ +/* ----------------------------------------------- */ + /* Parameter adjustments */ + --marker; + --llist; + --qsize; + --dbakw; + --dforw; + --dhead; + --adjncy; + --xadj; + + /* Function Body */ + marker[*mdnode] = *tag; + istrt = xadj[*mdnode]; + istop = xadj[*mdnode + 1] - 1; +/* ------------------------------------------------------- */ +/* ELMNT POINTS TO THE BEGINNING OF THE LIST OF ELIMINATED */ +/* NABORS OF MDNODE, AND RLOC GIVES THE STORAGE LOCATION */ +/* FOR THE NEXT REACHABLE NODE. */ +/* ------------------------------------------------------- */ + elmnt = 0; + rloc = istrt; + rlmt = istop; + i__1 = istop; + for (i = istrt; i <= i__1; ++i) { + nabor = adjncy[i]; + if (nabor == 0) { + goto L300; + } + if (marker[nabor] >= *tag) { + goto L200; + } + marker[nabor] = *tag; + if (dforw[nabor] < 0) { + goto L100; + } + adjncy[rloc] = nabor; + ++rloc; + goto L200; +L100: + llist[nabor] = elmnt; + elmnt = nabor; +L200: + ; + } +L300: +/* ----------------------------------------------------- */ +/* MERGE WITH REACHABLE NODES FROM GENERALIZED ELEMENTS. */ +/* ----------------------------------------------------- */ + if (elmnt <= 0) { + goto L1000; + } + adjncy[rlmt] = -elmnt; + link = elmnt; +L400: + jstrt = xadj[link]; + jstop = xadj[link + 1] - 1; + i__1 = jstop; + for (j = jstrt; j <= i__1; ++j) { + node = adjncy[j]; + link = -node; + if (node < 0) { + goto L400; + } else if (node == 0) { + goto L900; + } else { + goto L500; + } +L500: + if (marker[node] >= *tag || dforw[node] < 0) { + goto L800; + } + marker[node] = *tag; +/* --------------------------------- */ +/* USE STORAGE FROM ELIMINATED NODES */ +/* IF NECESSARY. */ +/* --------------------------------- */ +L600: + if (rloc < rlmt) { + goto L700; + } + link = -adjncy[rlmt]; + rloc = xadj[link]; + rlmt = xadj[link + 1] - 1; + goto L600; +L700: + adjncy[rloc] = node; + ++rloc; +L800: + ; + } +L900: + elmnt = llist[elmnt]; + goto L300; +L1000: + if (rloc <= rlmt) { + adjncy[rloc] = 0; + } +/* -------------------------------------------------------- */ +/* FOR EACH NODE IN THE REACHABLE SET, DO THE FOLLOWING ... */ +/* -------------------------------------------------------- */ + link = *mdnode; +L1100: + istrt = xadj[link]; + istop = xadj[link + 1] - 1; + i__1 = istop; + for (i = istrt; i <= i__1; ++i) { + rnode = adjncy[i]; + link = -rnode; + if (rnode < 0) { + goto L1100; + } else if (rnode == 0) { + goto L1800; + } else { + goto L1200; + } +L1200: +/* -------------------------------------------- */ +/* IF RNODE IS IN THE DEGREE LIST STRUCTURE ... */ +/* -------------------------------------------- */ + pvnode = dbakw[rnode]; + if (pvnode == 0 || pvnode == -(*maxint)) { + goto L1300; + } +/* ------------------------------------- */ +/* THEN REMOVE RNODE FROM THE STRUCTURE. */ +/* ------------------------------------- */ + nxnode = dforw[rnode]; + if (nxnode > 0) { + dbakw[nxnode] = pvnode; + } + if (pvnode > 0) { + dforw[pvnode] = nxnode; + } + npv = -pvnode; + if (pvnode < 0) { + dhead[npv] = nxnode; + } +L1300: +/* ---------------------------------------- */ +/* PURGE INACTIVE QUOTIENT NABORS OF RNODE. */ +/* ---------------------------------------- */ + jstrt = xadj[rnode]; + jstop = xadj[rnode + 1] - 1; + xqnbr = jstrt; + i__2 = jstop; + for (j = jstrt; j <= i__2; ++j) { + nabor = adjncy[j]; + if (nabor == 0) { + goto L1500; + } + if (marker[nabor] >= *tag) { + goto L1400; + } + adjncy[xqnbr] = nabor; + ++xqnbr; +L1400: + ; + } +L1500: +/* ---------------------------------------- */ +/* IF NO ACTIVE NABOR AFTER THE PURGING ... */ +/* ---------------------------------------- */ + nqnbrs = xqnbr - jstrt; + if (nqnbrs > 0) { + goto L1600; + } +/* ----------------------------- */ +/* THEN MERGE RNODE WITH MDNODE. */ +/* ----------------------------- */ + qsize[*mdnode] += qsize[rnode]; + qsize[rnode] = 0; + marker[rnode] = *maxint; + dforw[rnode] = -(*mdnode); + dbakw[rnode] = -(*maxint); + goto L1700; +L1600: +/* -------------------------------------- */ +/* ELSE FLAG RNODE FOR DEGREE UPDATE, AND */ +/* ADD MDNODE AS A NABOR OF RNODE. */ +/* -------------------------------------- */ + dforw[rnode] = nqnbrs + 1; + dbakw[rnode] = 0; + adjncy[xqnbr] = *mdnode; + ++xqnbr; + if (xqnbr <= jstop) { + adjncy[xqnbr] = 0; + } + +L1700: + ; + } +L1800: + return 0; + +} /* slu_mmdelm_ */ + +/* *************************************************************** */ +/* *************************************************************** */ +/* ***** MMDUPD ..... MULTIPLE MINIMUM DEGREE UPDATE ***** */ +/* *************************************************************** */ +/* *************************************************************** */ + +/* AUTHOR - JOSEPH W.H. LIU */ +/* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */ + +/* PURPOSE - THIS ROUTINE UPDATES THE DEGREES OF NODES */ +/* AFTER A MULTIPLE ELIMINATION STEP. */ + +/* INPUT PARAMETERS - */ +/* EHEAD - THE BEGINNING OF THE LIST OF ELIMINATED */ +/* NODES (I.E., NEWLY FORMED ELEMENTS). */ +/* NEQNS - NUMBER OF EQUATIONS. */ +/* (XADJ,ADJNCY) - ADJACENCY STRUCTURE. */ +/* DELTA - TOLERANCE VALUE FOR MULTIPLE ELIMINATION. */ +/* MAXINT - MAXIMUM MACHINE REPRESENTABLE (SHORT) */ +/* INTEGER. */ + +/* UPDATED PARAMETERS - */ +/* MDEG - NEW MINIMUM DEGREE AFTER DEGREE UPDATE. */ +/* (DHEAD,DFORW,DBAKW) - DEGREE DOUBLY LINKED STRUCTURE. */ +/* QSIZE - SIZE OF SUPERNODE. */ +/* LLIST - WORKING LINKED LIST. */ +/* MARKER - MARKER VECTOR FOR DEGREE UPDATE. */ +/* TAG - TAG VALUE. */ + +/* *************************************************************** */ + +/* Subroutine */ int slu_mmdupd_(int *ehead, int *neqns, int *xadj, + shortint *adjncy, int *delta, int *mdeg, shortint *dhead, + shortint *dforw, shortint *dbakw, shortint *qsize, shortint *llist, + shortint *marker, int *maxint, int *tag) +{ + /* System generated locals */ + int i__1, i__2; + + /* Local variables */ + int node, mtag, link, mdeg0, i, j, enode, fnode, nabor, elmnt, + istop, jstop, q2head, istrt, jstrt, qxhead, iq2, deg, deg0; + + +/* *************************************************************** */ + + +/* *************************************************************** */ + + /* Parameter adjustments */ + --marker; + --llist; + --qsize; + --dbakw; + --dforw; + --dhead; + --adjncy; + --xadj; + + /* Function Body */ + mdeg0 = *mdeg + *delta; + elmnt = *ehead; +L100: +/* ------------------------------------------------------- */ +/* FOR EACH OF THE NEWLY FORMED ELEMENT, DO THE FOLLOWING. */ +/* (RESET TAG VALUE IF NECESSARY.) */ +/* ------------------------------------------------------- */ + if (elmnt <= 0) { + return 0; + } + mtag = *tag + mdeg0; + if (mtag < *maxint) { + goto L300; + } + *tag = 1; + i__1 = *neqns; + for (i = 1; i <= i__1; ++i) { + if (marker[i] < *maxint) { + marker[i] = 0; + } +/* L200: */ + } + mtag = *tag + mdeg0; +L300: +/* --------------------------------------------- */ +/* CREATE TWO LINKED LISTS FROM NODES ASSOCIATED */ +/* WITH ELMNT: ONE WITH TWO NABORS (Q2HEAD) IN */ +/* ADJACENCY STRUCTURE, AND THE OTHER WITH MORE */ +/* THAN TWO NABORS (QXHEAD). ALSO COMPUTE DEG0, */ +/* NUMBER OF NODES IN THIS ELEMENT. */ +/* --------------------------------------------- */ + q2head = 0; + qxhead = 0; + deg0 = 0; + link = elmnt; +L400: + istrt = xadj[link]; + istop = xadj[link + 1] - 1; + i__1 = istop; + for (i = istrt; i <= i__1; ++i) { + enode = adjncy[i]; + link = -enode; + if (enode < 0) { + goto L400; + } else if (enode == 0) { + goto L800; + } else { + goto L500; + } + +L500: + if (qsize[enode] == 0) { + goto L700; + } + deg0 += qsize[enode]; + marker[enode] = mtag; +/* ---------------------------------- */ +/* IF ENODE REQUIRES A DEGREE UPDATE, */ +/* THEN DO THE FOLLOWING. */ +/* ---------------------------------- */ + if (dbakw[enode] != 0) { + goto L700; + } +/* --------------------------------------- +*/ +/* PLACE EITHER IN QXHEAD OR Q2HEAD LISTS. +*/ +/* --------------------------------------- +*/ + if (dforw[enode] == 2) { + goto L600; + } + llist[enode] = qxhead; + qxhead = enode; + goto L700; +L600: + llist[enode] = q2head; + q2head = enode; +L700: + ; + } +L800: +/* -------------------------------------------- */ +/* FOR EACH ENODE IN Q2 LIST, DO THE FOLLOWING. */ +/* -------------------------------------------- */ + enode = q2head; + iq2 = 1; +L900: + if (enode <= 0) { + goto L1500; + } + if (dbakw[enode] != 0) { + goto L2200; + } + ++(*tag); + deg = deg0; +/* ------------------------------------------ */ +/* IDENTIFY THE OTHER ADJACENT ELEMENT NABOR. */ +/* ------------------------------------------ */ + istrt = xadj[enode]; + nabor = adjncy[istrt]; + if (nabor == elmnt) { + nabor = adjncy[istrt + 1]; + } +/* ------------------------------------------------ */ +/* IF NABOR IS UNELIMINATED, INCREASE DEGREE COUNT. */ +/* ------------------------------------------------ */ + link = nabor; + if (dforw[nabor] < 0) { + goto L1000; + } + deg += qsize[nabor]; + goto L2100; +L1000: +/* -------------------------------------------- */ +/* OTHERWISE, FOR EACH NODE IN THE 2ND ELEMENT, */ +/* DO THE FOLLOWING. */ +/* -------------------------------------------- */ + istrt = xadj[link]; + istop = xadj[link + 1] - 1; + i__1 = istop; + for (i = istrt; i <= i__1; ++i) { + node = adjncy[i]; + link = -node; + if (node == enode) { + goto L1400; + } + if (node < 0) { + goto L1000; + } else if (node == 0) { + goto L2100; + } else { + goto L1100; + } + +L1100: + if (qsize[node] == 0) { + goto L1400; + } + if (marker[node] >= *tag) { + goto L1200; + } +/* ----------------------------------- +-- */ +/* CASE WHEN NODE IS NOT YET CONSIDERED +. */ +/* ----------------------------------- +-- */ + marker[node] = *tag; + deg += qsize[node]; + goto L1400; +L1200: +/* ---------------------------------------- + */ +/* CASE WHEN NODE IS INDISTINGUISHABLE FROM + */ +/* ENODE. MERGE THEM INTO A NEW SUPERNODE. + */ +/* ---------------------------------------- + */ + if (dbakw[node] != 0) { + goto L1400; + } + if (dforw[node] != 2) { + goto L1300; + } + qsize[enode] += qsize[node]; + qsize[node] = 0; + marker[node] = *maxint; + dforw[node] = -enode; + dbakw[node] = -(*maxint); + goto L1400; +L1300: +/* -------------------------------------- +*/ +/* CASE WHEN NODE IS OUTMATCHED BY ENODE. +*/ +/* -------------------------------------- +*/ + if (dbakw[node] == 0) { + dbakw[node] = -(*maxint); + } +L1400: + ; + } + goto L2100; +L1500: +/* ------------------------------------------------ */ +/* FOR EACH ENODE IN THE QX LIST, DO THE FOLLOWING. */ +/* ------------------------------------------------ */ + enode = qxhead; + iq2 = 0; +L1600: + if (enode <= 0) { + goto L2300; + } + if (dbakw[enode] != 0) { + goto L2200; + } + ++(*tag); + deg = deg0; +/* --------------------------------- */ +/* FOR EACH UNMARKED NABOR OF ENODE, */ +/* DO THE FOLLOWING. */ +/* --------------------------------- */ + istrt = xadj[enode]; + istop = xadj[enode + 1] - 1; + i__1 = istop; + for (i = istrt; i <= i__1; ++i) { + nabor = adjncy[i]; + if (nabor == 0) { + goto L2100; + } + if (marker[nabor] >= *tag) { + goto L2000; + } + marker[nabor] = *tag; + link = nabor; +/* ------------------------------ */ +/* IF UNELIMINATED, INCLUDE IT IN */ +/* DEG COUNT. */ +/* ------------------------------ */ + if (dforw[nabor] < 0) { + goto L1700; + } + deg += qsize[nabor]; + goto L2000; +L1700: +/* ------------------------------- +*/ +/* IF ELIMINATED, INCLUDE UNMARKED +*/ +/* NODES IN THIS ELEMENT INTO THE +*/ +/* DEGREE COUNT. */ +/* ------------------------------- +*/ + jstrt = xadj[link]; + jstop = xadj[link + 1] - 1; + i__2 = jstop; + for (j = jstrt; j <= i__2; ++j) { + node = adjncy[j]; + link = -node; + if (node < 0) { + goto L1700; + } else if (node == 0) { + goto L2000; + } else { + goto L1800; + } + +L1800: + if (marker[node] >= *tag) { + goto L1900; + } + marker[node] = *tag; + deg += qsize[node]; +L1900: + ; + } +L2000: + ; + } +L2100: +/* ------------------------------------------- */ +/* UPDATE EXTERNAL DEGREE OF ENODE IN DEGREE */ +/* STRUCTURE, AND MDEG (MIN DEG) IF NECESSARY. */ +/* ------------------------------------------- */ + deg = deg - qsize[enode] + 1; + fnode = dhead[deg]; + dforw[enode] = fnode; + dbakw[enode] = -deg; + if (fnode > 0) { + dbakw[fnode] = enode; + } + dhead[deg] = enode; + if (deg < *mdeg) { + *mdeg = deg; + } +L2200: +/* ---------------------------------- */ +/* GET NEXT ENODE IN CURRENT ELEMENT. */ +/* ---------------------------------- */ + enode = llist[enode]; + if (iq2 == 1) { + goto L900; + } + goto L1600; +L2300: +/* ----------------------------- */ +/* GET NEXT ELEMENT IN THE LIST. */ +/* ----------------------------- */ + *tag = mtag; + elmnt = llist[elmnt]; + goto L100; + +} /* slu_mmdupd_ */ + +/* *************************************************************** */ +/* *************************************************************** */ +/* ***** MMDNUM ..... MULTI MINIMUM DEGREE NUMBERING ***** */ +/* *************************************************************** */ +/* *************************************************************** */ + +/* AUTHOR - JOSEPH W.H. LIU */ +/* DEPT OF COMPUTER SCIENCE, YORK UNIVERSITY. */ + +/* PURPOSE - THIS ROUTINE PERFORMS THE FINAL STEP IN */ +/* PRODUCING THE PERMUTATION AND INVERSE PERMUTATION */ +/* VECTORS IN THE MULTIPLE ELIMINATION VERSION OF THE */ +/* MINIMUM DEGREE ORDERING ALGORITHM. */ + +/* INPUT PARAMETERS - */ +/* NEQNS - NUMBER OF EQUATIONS. */ +/* QSIZE - SIZE OF SUPERNODES AT ELIMINATION. */ + +/* UPDATED PARAMETERS - */ +/* INVP - INVERSE PERMUTATION VECTOR. ON INPUT, */ +/* IF QSIZE(NODE)=0, THEN NODE HAS BEEN MERGED */ +/* INTO THE NODE -INVP(NODE); OTHERWISE, */ +/* -INVP(NODE) IS ITS INVERSE LABELLING. */ + +/* OUTPUT PARAMETERS - */ +/* PERM - THE PERMUTATION VECTOR. */ + +/* *************************************************************** */ + +/* Subroutine */ int slu_mmdnum_(int *neqns, shortint *perm, shortint *invp, + shortint *qsize) +{ + /* System generated locals */ + int i__1; + + /* Local variables */ + int node, root, nextf, father, nqsize, num; + + +/* *************************************************************** */ + + +/* *************************************************************** */ + + /* Parameter adjustments */ + --qsize; + --invp; + --perm; + + /* Function Body */ + i__1 = *neqns; + for (node = 1; node <= i__1; ++node) { + nqsize = qsize[node]; + if (nqsize <= 0) { + perm[node] = invp[node]; + } + if (nqsize > 0) { + perm[node] = -invp[node]; + } +/* L100: */ + } +/* ------------------------------------------------------ */ +/* FOR EACH NODE WHICH HAS BEEN MERGED, DO THE FOLLOWING. */ +/* ------------------------------------------------------ */ + i__1 = *neqns; + for (node = 1; node <= i__1; ++node) { + if (perm[node] > 0) { + goto L500; + } +/* ----------------------------------------- */ +/* TRACE THE MERGED TREE UNTIL ONE WHICH HAS */ +/* NOT BEEN MERGED, CALL IT ROOT. */ +/* ----------------------------------------- */ + father = node; +L200: + if (perm[father] > 0) { + goto L300; + } + father = -perm[father]; + goto L200; +L300: +/* ----------------------- */ +/* NUMBER NODE AFTER ROOT. */ +/* ----------------------- */ + root = father; + num = perm[root] + 1; + invp[node] = -num; + perm[root] = num; +/* ------------------------ */ +/* SHORTEN THE MERGED TREE. */ +/* ------------------------ */ + father = node; +L400: + nextf = -perm[father]; + if (nextf <= 0) { + goto L500; + } + perm[father] = -root; + father = nextf; + goto L400; +L500: + ; + } +/* ---------------------- */ +/* READY TO COMPUTE PERM. */ +/* ---------------------- */ + i__1 = *neqns; + for (node = 1; node <= i__1; ++node) { + num = -invp[node]; + invp[node] = num; + perm[num] = node; +/* L600: */ + } + return 0; + +} /* slu_mmdnum_ */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/qselect.c b/src/Libraries/superlu-5.2.1/SRC/qselect.c new file mode 100644 index 00000000..1525d5a7 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/qselect.c @@ -0,0 +1,84 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file qselect.c + * \brief Quickselect: returns the k-th (zero-based) largest value in A[]. + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Lawrence Berkeley National Laboratory.
+ * November, 2010
+ * 
+ */ + +#include "slu_ddefs.h" + +double dqselect(int n, double A[], int k) +{ + register int i, j, p; + register double val; + + k = SUPERLU_MAX(k, 0); + k = SUPERLU_MIN(k, n - 1); + while (n > 1) + { + i = 0; j = n-1; + p = j; val = A[p]; + while (i < j) + { + for (; A[i] >= val && i < p; i++); + if (A[i] < val) { A[p] = A[i]; p = i; } + for (; A[j] <= val && j > p; j--); + if (A[j] > val) { A[p] = A[j]; p = j; } + } + A[p] = val; + if (p == k) return val; + else if (p > k) n = p; + else + { + p++; + n -= p; A += p; k -= p; + } + } + + return A[0]; +} + +float sqselect(int n, float A[], int k) +{ + register int i, j, p; + register float val; + + k = SUPERLU_MAX(k, 0); + k = SUPERLU_MIN(k, n - 1); + while (n > 1) + { + i = 0; j = n-1; + p = j; val = A[p]; + while (i < j) + { + for (; A[i] >= val && i < p; i++); + if (A[i] < val) { A[p] = A[i]; p = i; } + for (; A[j] <= val && j > p; j--); + if (A[j] > val) { A[p] = A[j]; p = j; } + } + A[p] = val; + if (p == k) return val; + else if (p > k) n = p; + else + { + p++; + n -= p; A += p; k -= p; + } + } + + return A[0]; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/relax_snode.c b/src/Libraries/superlu-5.2.1/SRC/relax_snode.c new file mode 100644 index 00000000..930e2b31 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/relax_snode.c @@ -0,0 +1,85 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file relax_snode.c + * \brief Identify initial relaxed supernodes + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + +#include "slu_ddefs.h" +/*! \brief + * + *
+ * Purpose
+ * =======
+ *    relax_snode() - Identify the initial relaxed supernodes, assuming that 
+ *    the matrix has been reordered according to the postorder of the etree.
+ * 
+ */ +void +relax_snode ( + const int n, + int *et, /* column elimination tree */ + const int relax_columns, /* max no of columns allowed in a + relaxed snode */ + int *descendants, /* no of descendants of each node + in the etree */ + int *relax_end /* last column in a supernode */ + ) +{ + + register int j, parent; + register int snode_start; /* beginning of a snode */ + + ifill (relax_end, n, EMPTY); + for (j = 0; j < n; j++) descendants[j] = 0; + + /* Compute the number of descendants of each node in the etree */ + for (j = 0; j < n; j++) { + parent = et[j]; + if ( parent != n ) /* not the dummy root */ + descendants[parent] += descendants[j] + 1; + } + + /* Identify the relaxed supernodes by postorder traversal of the etree. */ + for (j = 0; j < n; ) { + parent = et[j]; + snode_start = j; + while ( parent != n && descendants[parent] < relax_columns ) { + j = parent; + parent = et[j]; + } + /* Found a supernode with j being the last column. */ + relax_end[snode_start] = j; /* Last column is recorded */ + j++; + /* Search for a new leaf */ + while ( descendants[j] != 0 && j < n ) j++; + } + + /*printf("No of relaxed snodes: %d; relaxed columns: %d\n", + nsuper, no_relaxed_col); */ +} diff --git a/src/Libraries/superlu-5.2.1/SRC/scolumn_bmod.c b/src/Libraries/superlu-5.2.1/SRC/scolumn_bmod.c new file mode 100644 index 00000000..23dbf897 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/scolumn_bmod.c @@ -0,0 +1,362 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file scolumn_bmod.c + * \brief performs numeric block updates + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ *  Permission is hereby granted to use or copy this program for any
+ *  purpose, provided the above notices are retained on all copies.
+ *  Permission to modify the code and to distribute modified code is
+ *  granted, provided the above notices are retained, and a notice that
+ *  the code was modified is included with the above copyright notice.
+ * 
+*/ + +#include +#include +#include "slu_sdefs.h" + +/* + * Function prototypes + */ +void susolve(int, int, float*, float*); +void slsolve(int, int, float*, float*); +void smatvec(int, int, int, float*, float*, float*); + + + +/*! \brief + * + *
+ * Purpose:
+ * ========
+ * Performs numeric block updates (sup-col) in topological order.
+ * It features: col-col, 2cols-col, 3cols-col, and sup-col updates.
+ * Special processing on the supernodal portion of L\U[*,j]
+ * Return value:   0 - successful return
+ *               > 0 - number of bytes allocated when run out of space
+ * 
+ */ +int +scolumn_bmod ( + const int jcol, /* in */ + const int nseg, /* in */ + float *dense, /* in */ + float *tempv, /* working array */ + int *segrep, /* in */ + int *repfnz, /* in */ + int fpanelc, /* in -- first column in the current panel */ + GlobalLU_t *Glu, /* modified */ + SuperLUStat_t *stat /* output */ + ) +{ + +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + int incx = 1, incy = 1; + float alpha, beta; + + /* krep = representative of current k-th supernode + * fsupc = first supernodal column + * nsupc = no of columns in supernode + * nsupr = no of rows in supernode (used as leading dimension) + * luptr = location of supernodal LU-block in storage + * kfnz = first nonz in the k-th supernodal segment + * no_zeros = no of leading zeros in a supernodal U-segment + */ + float ukj, ukj1, ukj2; + int luptr, luptr1, luptr2; + int fsupc, nsupc, nsupr, segsze; + int nrow; /* No of rows in the matrix of matrix-vector */ + int jcolp1, jsupno, k, ksub, krep, krep_ind, ksupno; + register int lptr, kfnz, isub, irow, i; + register int no_zeros, new_next; + int ufirst, nextlu; + int fst_col; /* First column within small LU update */ + int d_fsupc; /* Distance between the first column of the current + panel and the first column of the current snode. */ + int *xsup, *supno; + int *lsub, *xlsub; + float *lusup; + int *xlusup; + int nzlumax; + float *tempv1; + float zero = 0.0; + float one = 1.0; + float none = -1.0; + int mem_error; + flops_t *ops = stat->ops; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (float *) Glu->lusup; + xlusup = Glu->xlusup; + nzlumax = Glu->nzlumax; + jcolp1 = jcol + 1; + jsupno = supno[jcol]; + + /* + * For each nonz supernode segment of U[*,j] in topological order + */ + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { + + krep = segrep[k]; + k--; + ksupno = supno[krep]; + if ( jsupno != ksupno ) { /* Outside the rectangular supernode */ + + fsupc = xsup[ksupno]; + fst_col = SUPERLU_MAX ( fsupc, fpanelc ); + + /* Distance from the current supernode to the current panel; + d_fsupc=0 if fsupc > fpanelc. */ + d_fsupc = fst_col - fsupc; + + luptr = xlusup[fst_col] + d_fsupc; + lptr = xlsub[fsupc] + d_fsupc; + + kfnz = repfnz[krep]; + kfnz = SUPERLU_MAX ( kfnz, fpanelc ); + + segsze = krep - kfnz + 1; + nsupc = krep - fst_col + 1; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; /* Leading dimension */ + nrow = nsupr - d_fsupc - nsupc; + krep_ind = lptr + nsupc - 1; + + ops[TRSV] += segsze * (segsze - 1); + ops[GEMV] += 2 * nrow * segsze; + + + /* + * Case 1: Update U-segment of size 1 -- col-col update + */ + if ( segsze == 1 ) { + ukj = dense[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc; + + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + dense[irow] -= ukj*lusup[luptr]; + luptr++; + } + + } else if ( segsze <= 3 ) { + ukj = dense[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc-1; + ukj1 = dense[lsub[krep_ind - 1]]; + luptr1 = luptr - nsupr; + + if ( segsze == 2 ) { /* Case 2: 2cols-col update */ + ukj -= ukj1 * lusup[luptr1]; + dense[lsub[krep_ind]] = ukj; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; + luptr1++; + dense[irow] -= ( ukj*lusup[luptr] + + ukj1*lusup[luptr1] ); + } + } else { /* Case 3: 3cols-col update */ + ukj2 = dense[lsub[krep_ind - 2]]; + luptr2 = luptr1 - nsupr; + ukj1 -= ukj2 * lusup[luptr2-1]; + ukj = ukj - ukj1*lusup[luptr1] - ukj2*lusup[luptr2]; + dense[lsub[krep_ind]] = ukj; + dense[lsub[krep_ind-1]] = ukj1; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; + luptr1++; + luptr2++; + dense[irow] -= ( ukj*lusup[luptr] + + ukj1*lusup[luptr1] + ukj2*lusup[luptr2] ); + } + } + + + + } else { + /* + * Case: sup-col update + * Perform a triangular solve and block update, + * then scatter the result of sup-col update to dense + */ + + no_zeros = kfnz - fst_col; + + /* Copy U[*,j] segment from dense[*] to tempv[*] */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + tempv[i] = dense[irow]; + ++isub; + } + + /* Dense triangular solve -- start effective triangle */ + luptr += nsupr * no_zeros + no_zeros; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + STRSV( ftcs1, ftcs2, ftcs3, &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#else + strsv_( "L", "N", "U", &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#endif + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + alpha = one; + beta = zero; +#ifdef _CRAY + SGEMV( ftcs2, &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#else + sgemv_( "N", &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#endif +#else + slsolve ( nsupr, segsze, &lusup[luptr], tempv ); + + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + smatvec (nsupr, nrow , segsze, &lusup[luptr], tempv, tempv1); +#endif + + + /* Scatter tempv[] into SPA dense[] as a temporary storage */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + dense[irow] = tempv[i]; + tempv[i] = zero; + ++isub; + } + + /* Scatter tempv1[] into SPA dense[] */ + for (i = 0; i < nrow; i++) { + irow = lsub[isub]; + dense[irow] -= tempv1[i]; + tempv1[i] = zero; + ++isub; + } + } + + } /* if jsupno ... */ + + } /* for each segment... */ + + /* + * Process the supernodal portion of L\U[*,j] + */ + nextlu = xlusup[jcol]; + fsupc = xsup[jsupno]; + + /* Copy the SPA dense into L\U[*,j] */ + new_next = nextlu + xlsub[fsupc+1] - xlsub[fsupc]; + while ( new_next > nzlumax ) { + if (mem_error = sLUMemXpand(jcol, nextlu, LUSUP, &nzlumax, Glu)) + return (mem_error); + lusup = (float *) Glu->lusup; + lsub = Glu->lsub; + } + + for (isub = xlsub[fsupc]; isub < xlsub[fsupc+1]; isub++) { + irow = lsub[isub]; + lusup[nextlu] = dense[irow]; + dense[irow] = zero; + ++nextlu; + } + + xlusup[jcolp1] = nextlu; /* Close L\U[*,jcol] */ + + /* For more updates within the panel (also within the current supernode), + * should start from the first column of the panel, or the first column + * of the supernode, whichever is bigger. There are 2 cases: + * 1) fsupc < fpanelc, then fst_col := fpanelc + * 2) fsupc >= fpanelc, then fst_col := fsupc + */ + fst_col = SUPERLU_MAX ( fsupc, fpanelc ); + + if ( fst_col < jcol ) { + + /* Distance between the current supernode and the current panel. + d_fsupc=0 if fsupc >= fpanelc. */ + d_fsupc = fst_col - fsupc; + + lptr = xlsub[fsupc] + d_fsupc; + luptr = xlusup[fst_col] + d_fsupc; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; /* Leading dimension */ + nsupc = jcol - fst_col; /* Excluding jcol */ + nrow = nsupr - d_fsupc - nsupc; + + /* Points to the beginning of jcol in snode L\U(jsupno) */ + ufirst = xlusup[jcol] + d_fsupc; + + ops[TRSV] += nsupc * (nsupc - 1); + ops[GEMV] += 2 * nrow * nsupc; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + STRSV( ftcs1, ftcs2, ftcs3, &nsupc, &lusup[luptr], + &nsupr, &lusup[ufirst], &incx ); +#else + strsv_( "L", "N", "U", &nsupc, &lusup[luptr], + &nsupr, &lusup[ufirst], &incx ); +#endif + + alpha = none; beta = one; /* y := beta*y + alpha*A*x */ + +#ifdef _CRAY + SGEMV( ftcs2, &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#else + sgemv_( "N", &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#endif +#else + slsolve ( nsupr, nsupc, &lusup[luptr], &lusup[ufirst] ); + + smatvec ( nsupr, nrow, nsupc, &lusup[luptr+nsupc], + &lusup[ufirst], tempv ); + + /* Copy updates from tempv[*] into lusup[*] */ + isub = ufirst + nsupc; + for (i = 0; i < nrow; i++) { + lusup[isub] -= tempv[i]; + tempv[i] = 0.0; + ++isub; + } + +#endif + + + } /* if fst_col < jcol ... */ + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/scolumn_dfs.c b/src/Libraries/superlu-5.2.1/SRC/scolumn_dfs.c new file mode 100644 index 00000000..bec976f9 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/scolumn_dfs.c @@ -0,0 +1,281 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file scolumn_dfs.c + * \brief Performs a symbolic factorization + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+*/ + +#include "slu_sdefs.h" + +/*! \brief What type of supernodes we want */ +#define T2_SUPER + + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   SCOLUMN_DFS performs a symbolic factorization on column jcol, and
+ *   decide the supernode boundary.
+ *
+ *   This routine does not use numeric values, but only use the RHS 
+ *   row indices to start the dfs.
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives. The routine returns a list of such supernodal 
+ *   representatives in topological order of the dfs that generates them.
+ *   The location of the first nonzero in each such supernodal segment
+ *   (supernodal entry location) is also returned.
+ *
+ * Local parameters
+ * ================
+ *   nseg: no of segments in current U[*,j]
+ *   jsuper: jsuper=EMPTY if column j does not belong to the same
+ *	supernode as j-1. Otherwise, jsuper=nsuper.
+ *
+ *   marker2: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ *
+ * Return value
+ * ============
+ *     0  success;
+ *   > 0  number of bytes allocated when run out of space.
+ * 
+ */ +int +scolumn_dfs( + const int m, /* in - number of rows in the matrix */ + const int jcol, /* in */ + int *perm_r, /* in */ + int *nseg, /* modified - with new segments appended */ + int *lsub_col, /* in - defines the RHS vector to start the dfs */ + int *segrep, /* modified - with new segments appended */ + int *repfnz, /* modified */ + int *xprune, /* modified */ + int *marker, /* modified */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ + ) +{ + + int jcolp1, jcolm1, jsuper, nsuper, nextl; + int k, krep, krow, kmark, kperm; + int *marker2; /* Used for small panel LU */ + int fsupc; /* First column of a snode */ + int myfnz; /* First nonz column of a U-segment */ + int chperm, chmark, chrep, kchild; + int xdfs, maxdfs, kpar, oldrep; + int jptr, jm1ptr; + int ito, ifrom, istop; /* Used to compress row subscripts */ + int mem_error; + int *xsup, *supno, *lsub, *xlsub; + int nzlmax; + int maxsuper; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + maxsuper = sp_ienv(3); + jcolp1 = jcol + 1; + jcolm1 = jcol - 1; + nsuper = supno[jcol]; + jsuper = nsuper; + nextl = xlsub[jcol]; + marker2 = &marker[2*m]; + + /* For each nonzero in A[*,jcol] do dfs */ + for (k = 0; lsub_col[k] != EMPTY; k++) { + + krow = lsub_col[k]; + lsub_col[k] = EMPTY; + kmark = marker2[krow]; + + /* krow was visited before, go to the next nonz */ + if ( kmark == jcol ) continue; + + /* For each unmarked nbr krow of jcol + * krow is in L: place it in structure of L[*,jcol] + */ + marker2[krow] = jcol; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + lsub[nextl++] = krow; /* krow is indexed into A */ + if ( nextl >= nzlmax ) { + if ( mem_error = sLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + if ( kmark != jcolm1 ) jsuper = EMPTY;/* Row index subset testing */ + } else { + /* krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz[krep]; + + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > kperm ) repfnz[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz[krep] = kperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; + + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker2[kchild]; + + if ( chmark != jcol ) { /* Not reached yet */ + marker2[kchild] = jcol; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,k] */ + if ( chperm == EMPTY ) { + lsub[nextl++] = kchild; + if ( nextl >= nzlmax ) { + if ( mem_error = + sLUMemXpand(jcol,nextl,LSUB,&nzlmax,Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + if ( chmark != jcolm1 ) jsuper = EMPTY; + } else { + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz[chrep]; + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz[chrep] = chperm; + } else { + /* Continue dfs at super-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L^t) */ + parent[krep] = oldrep; + repfnz[krep] = chperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; + } /* else */ + + } /* else */ + + } /* if */ + + } /* while */ + + /* krow has no more unexplored nbrs; + * place supernode-rep krep in postorder DFS. + * backtrack dfs to its parent + */ + segrep[*nseg] = krep; + ++(*nseg); + kpar = parent[krep]; /* Pop from stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xprune[krep]; + + } while ( kpar != EMPTY ); /* Until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonzero ... */ + + /* Check to see if j belongs in the same supernode as j-1 */ + if ( jcol == 0 ) { /* Do nothing for column 0 */ + nsuper = supno[0] = 0; + } else { + fsupc = xsup[nsuper]; + jptr = xlsub[jcol]; /* Not compressed yet */ + jm1ptr = xlsub[jcolm1]; + +#ifdef T2_SUPER + if ( (nextl-jptr != jptr-jm1ptr-1) ) jsuper = EMPTY; +#endif + /* Make sure the number of columns in a supernode doesn't + exceed threshold. */ + if ( jcol - fsupc >= maxsuper ) jsuper = EMPTY; + + /* If jcol starts a new supernode, reclaim storage space in + * lsub from the previous supernode. Note we only store + * the subscript set of the first and last columns of + * a supernode. (first for num values, last for pruning) + */ + if ( jsuper == EMPTY ) { /* starts a new supernode */ + if ( (fsupc < jcolm1-1) ) { /* >= 3 columns in nsuper */ +#ifdef CHK_COMPRESS + printf(" Compress lsub[] at super %d-%d\n", fsupc, jcolm1); +#endif + ito = xlsub[fsupc+1]; + xlsub[jcolm1] = ito; + istop = ito + jptr - jm1ptr; + xprune[jcolm1] = istop; /* Initialize xprune[jcol-1] */ + xlsub[jcol] = istop; + for (ifrom = jm1ptr; ifrom < nextl; ++ifrom, ++ito) + lsub[ito] = lsub[ifrom]; + nextl = ito; /* = istop + length(jcol) */ + } + nsuper++; + supno[jcol] = nsuper; + } /* if a new supernode */ + + } /* else: jcol > 0 */ + + /* Tidy up the pointers before exit */ + xsup[nsuper+1] = jcolp1; + supno[jcolp1] = nsuper; + xprune[jcol] = nextl; /* Initialize upper bound for pruning */ + xlsub[jcolp1] = nextl; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/scomplex.c b/src/Libraries/superlu-5.2.1/SRC/scomplex.c new file mode 100644 index 00000000..0d833724 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/scomplex.c @@ -0,0 +1,157 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file scomplex.c + * \brief Common arithmetic for complex type + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * This file defines common arithmetic operations for complex type.
+ * 
+ */ + +#include +#include +#include +#include "slu_scomplex.h" + + +/*! \brief Complex Division c = a/b */ +void c_div(complex *c, complex *a, complex *b) +{ + float ratio, den; + float abr, abi, cr, ci; + + if( (abr = b->r) < 0.) + abr = - abr; + if( (abi = b->i) < 0.) + abi = - abi; + if( abr <= abi ) { + if (abi == 0) { + fprintf(stderr, "z_div.c: division by zero\n"); + exit(-1); + } + ratio = b->r / b->i ; + den = b->i * (1 + ratio*ratio); + cr = (a->r*ratio + a->i) / den; + ci = (a->i*ratio - a->r) / den; + } else { + ratio = b->i / b->r ; + den = b->r * (1 + ratio*ratio); + cr = (a->r + a->i*ratio) / den; + ci = (a->i - a->r*ratio) / den; + } + c->r = cr; + c->i = ci; +} + + +/*! \brief Returns sqrt(z.r^2 + z.i^2) */ +double c_abs(complex *z) +{ + float temp; + float real = z->r; + float imag = z->i; + + if (real < 0) real = -real; + if (imag < 0) imag = -imag; + if (imag > real) { + temp = real; + real = imag; + imag = temp; + } + if ((real+imag) == real) return(real); + + temp = imag/real; + temp = real*sqrt(1.0 + temp*temp); /*overflow!!*/ + return (temp); +} + + +/*! \brief Approximates the abs. Returns abs(z.r) + abs(z.i) */ +double c_abs1(complex *z) +{ + float real = z->r; + float imag = z->i; + + if (real < 0) real = -real; + if (imag < 0) imag = -imag; + + return (real + imag); +} + +/*! \brief Return the exponentiation */ +void c_exp(complex *r, complex *z) +{ + float expx; + + expx = exp(z->r); + r->r = expx * cos(z->i); + r->i = expx * sin(z->i); +} + +/*! \brief Return the complex conjugate */ +void r_cnjg(complex *r, complex *z) +{ + r->r = z->r; + r->i = -z->i; +} + +/*! \brief Return the imaginary part */ +double r_imag(complex *z) +{ + return (z->i); +} + + +/*! \brief SIGN functions for complex number. Returns z/abs(z) */ +complex c_sgn(complex *z) +{ + register float t = c_abs(z); + register complex retval; + + if (t == 0.0) { + retval.r = 1.0, retval.i = 0.0; + } else { + retval.r = z->r / t, retval.i = z->i / t; + } + + return retval; +} + +/*! \brief Square-root of a complex number. */ +complex c_sqrt(complex *z) +{ + complex retval; + register float cr, ci, real, imag; + + real = z->r; + imag = z->i; + + if ( imag == 0.0 ) { + retval.r = sqrt(real); + retval.i = 0.0; + } else { + ci = (sqrt(real*real + imag*imag) - real) / 2.0; + ci = sqrt(ci); + cr = imag / (2.0 * ci); + retval.r = cr; + retval.i = ci; + } + + return retval; +} + + diff --git a/src/Libraries/superlu-5.2.1/SRC/scopy_to_ucol.c b/src/Libraries/superlu-5.2.1/SRC/scopy_to_ucol.c new file mode 100644 index 00000000..7bc8d963 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/scopy_to_ucol.c @@ -0,0 +1,113 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file scopy_to_ucol.c + * \brief Copy a computed column of U to the compressed data structure + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + +#include "slu_sdefs.h" + +int +scopy_to_ucol( + int jcol, /* in */ + int nseg, /* in */ + int *segrep, /* in */ + int *repfnz, /* in */ + int *perm_r, /* in */ + float *dense, /* modified - reset to zero on return */ + GlobalLU_t *Glu /* modified */ + ) +{ +/* + * Gather from SPA dense[*] to global ucol[*]. + */ + int ksub, krep, ksupno; + int i, k, kfnz, segsze; + int fsupc, isub, irow; + int jsupno, nextu; + int new_next, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + float *ucol; + int *usub, *xusub; + int nzumax; + float zero = 0.0; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + ucol = (float *) Glu->ucol; + usub = Glu->usub; + xusub = Glu->xusub; + nzumax = Glu->nzumax; + + jsupno = supno[jcol]; + nextu = xusub[jcol]; + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { + krep = segrep[k--]; + ksupno = supno[krep]; + + if ( ksupno != jsupno ) { /* Should go into ucol[] */ + kfnz = repfnz[krep]; + if ( kfnz != EMPTY ) { /* Nonzero U-segment */ + + fsupc = xsup[ksupno]; + isub = xlsub[fsupc] + kfnz - fsupc; + segsze = krep - kfnz + 1; + + new_next = nextu + segsze; + while ( new_next > nzumax ) { + if (mem_error = sLUMemXpand(jcol, nextu, UCOL, &nzumax, Glu)) + return (mem_error); + ucol = (float *) Glu->ucol; + if (mem_error = sLUMemXpand(jcol, nextu, USUB, &nzumax, Glu)) + return (mem_error); + usub = Glu->usub; + lsub = Glu->lsub; + } + + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + usub[nextu] = perm_r[irow]; + ucol[nextu] = dense[irow]; + dense[irow] = zero; + nextu++; + isub++; + } + + } + + } + + } /* for each segment... */ + + xusub[jcol + 1] = nextu; /* Close U[*,jcol] */ + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/scsum1.c b/src/Libraries/superlu-5.2.1/SRC/scsum1.c new file mode 100644 index 00000000..48bdf799 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/scsum1.c @@ -0,0 +1,109 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file scsum1.c + * \brief Takes sum of the absolute values of a complex vector and returns a single precision result + * + *
+ *     -- LAPACK auxiliary routine (version 2.0) --   
+ *     Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,   
+ *     Courant Institute, Argonne National Lab, and Rice University   
+ *     October 31, 1992   
+ * 
+ */ +#include "slu_scomplex.h" +#include "slu_Cnames.h" + +/*! \brief + +
+    Purpose   
+    =======   
+
+    SCSUM1 takes the sum of the absolute values of a complex   
+    vector and returns a single precision result.   
+
+    Based on SCASUM from the Level 1 BLAS.   
+    The change is to use the 'genuine' absolute value.   
+
+    Contributed by Nick Higham for use with CLACON.   
+
+    Arguments   
+    =========   
+
+    N       (input) INT
+            The number of elements in the vector CX.   
+
+    CX      (input) COMPLEX array, dimension (N)   
+            The vector whose elements will be summed.   
+
+    INCX    (input) INT
+            The spacing between successive values of CX.  INCX > 0.   
+
+    ===================================================================== 
+
+*/ +double scsum1_slu(int *n, complex *cx, int *incx) +{ + /* System generated locals */ + int i__1, i__2; + float ret_val; + /* Builtin functions */ + double c_abs(complex *); + /* Local variables */ + static int i, nincx; + static float stemp; + + +#define CX(I) cx[(I)-1] + + + ret_val = 0.f; + stemp = 0.f; + if (*n <= 0) { + return ret_val; + } + if (*incx == 1) { + goto L20; + } + +/* CODE FOR INCREMENT NOT EQUAL TO 1 */ + + nincx = *n * *incx; + i__1 = nincx; + i__2 = *incx; + for (i = 1; *incx < 0 ? i >= nincx : i <= nincx; i += *incx) { + +/* NEXT LINE MODIFIED. */ + + stemp += c_abs(&CX(i)); +/* L10: */ + } + ret_val = stemp; + return ret_val; + +/* CODE FOR INCREMENT EQUAL TO 1 */ + +L20: + i__2 = *n; + for (i = 1; i <= *n; ++i) { + +/* NEXT LINE MODIFIED. */ + + stemp += c_abs(&CX(i)); +/* L30: */ + } + ret_val = stemp; + return ret_val; + +/* End of SCSUM1 */ + +} /* scsum1_slu */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/sdiagonal.c b/src/Libraries/superlu-5.2.1/SRC/sdiagonal.c new file mode 100644 index 00000000..ed5fb6df --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sdiagonal.c @@ -0,0 +1,139 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sdiagonal.c + * \brief Auxiliary routines to work with diagonal elements + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + +#include "slu_sdefs.h" + +int sfill_diag(int n, NCformat *Astore) +/* fill explicit zeros on the diagonal entries, so that the matrix is not + structurally singular. */ +{ + float *nzval = (float *)Astore->nzval; + int *rowind = Astore->rowind; + int *colptr = Astore->colptr; + int nnz = colptr[n]; + int fill = 0; + float *nzval_new; + float zero = 0.0; + int *rowind_new; + int i, j, diag; + + for (i = 0; i < n; i++) + { + diag = -1; + for (j = colptr[i]; j < colptr[i + 1]; j++) + if (rowind[j] == i) diag = j; + if (diag < 0) fill++; + } + if (fill) + { + nzval_new = floatMalloc(nnz + fill); + rowind_new = intMalloc(nnz + fill); + fill = 0; + for (i = 0; i < n; i++) + { + diag = -1; + for (j = colptr[i] - fill; j < colptr[i + 1]; j++) + { + if ((rowind_new[j + fill] = rowind[j]) == i) diag = j; + nzval_new[j + fill] = nzval[j]; + } + if (diag < 0) + { + rowind_new[colptr[i + 1] + fill] = i; + nzval_new[colptr[i + 1] + fill] = zero; + fill++; + } + colptr[i + 1] += fill; + } + Astore->nzval = nzval_new; + Astore->rowind = rowind_new; + SUPERLU_FREE(nzval); + SUPERLU_FREE(rowind); + } + Astore->nnz += fill; + return fill; +} + +int sdominate(int n, NCformat *Astore) +/* make the matrix diagonally dominant */ +{ + float *nzval = (float *)Astore->nzval; + int *rowind = Astore->rowind; + int *colptr = Astore->colptr; + int nnz = colptr[n]; + int fill = 0; + float *nzval_new; + int *rowind_new; + int i, j, diag; + double s; + + for (i = 0; i < n; i++) + { + diag = -1; + for (j = colptr[i]; j < colptr[i + 1]; j++) + if (rowind[j] == i) diag = j; + if (diag < 0) fill++; + } + if (fill) + { + nzval_new = floatMalloc(nnz + fill); + rowind_new = intMalloc(nnz+ fill); + fill = 0; + for (i = 0; i < n; i++) + { + s = 1e-6; + diag = -1; + for (j = colptr[i] - fill; j < colptr[i + 1]; j++) + { + if ((rowind_new[j + fill] = rowind[j]) == i) diag = j; + s += fabs(nzval_new[j + fill] = nzval[j]); + } + if (diag >= 0) { + nzval_new[diag+fill] = s * 3.0; + } else { + rowind_new[colptr[i + 1] + fill] = i; + nzval_new[colptr[i + 1] + fill] = s * 3.0; + fill++; + } + colptr[i + 1] += fill; + } + Astore->nzval = nzval_new; + Astore->rowind = rowind_new; + SUPERLU_FREE(nzval); + SUPERLU_FREE(rowind); + } + else + { + for (i = 0; i < n; i++) + { + s = 1e-6; + diag = -1; + for (j = colptr[i]; j < colptr[i + 1]; j++) + { + if (rowind[j] == i) diag = j; + s += fabs(nzval[j]); + } + nzval[diag] = s * 3.0; + } + } + Astore->nnz += fill; + return fill; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/sgscon.c b/src/Libraries/superlu-5.2.1/SRC/sgscon.c new file mode 100644 index 00000000..0554b652 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sgscon.c @@ -0,0 +1,168 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sgscon.c + * \brief Estimates reciprocal of the condition number of a general matrix + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * July 25, 2015
+ *
+ * Modified from lapack routines SGECON.
+ * 
+ */ + +/* + * File name: sgscon.c + * History: Modified from lapack routines SGECON. + */ +#include +#include "slu_sdefs.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   SGSCON estimates the reciprocal of the condition number of a general 
+ *   real matrix A, in either the 1-norm or the infinity-norm, using   
+ *   the LU factorization computed by SGETRF.   *
+ *
+ *   An estimate is obtained for norm(inv(A)), and the reciprocal of the   
+ *   condition number is computed as   
+ *      RCOND = 1 / ( norm(A) * norm(inv(A)) ).   
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ * 
+ *   Arguments   
+ *   =========   
+ *
+ *    NORM    (input) char*
+ *            Specifies whether the 1-norm condition number or the   
+ *            infinity-norm condition number is required:   
+ *            = '1' or 'O':  1-norm;   
+ *            = 'I':         Infinity-norm.
+ *	    
+ *    L       (input) SuperMatrix*
+ *            The factor L from the factorization Pr*A*Pc=L*U as computed by
+ *            sgstrf(). Use compressed row subscripts storage for supernodes,
+ *            i.e., L has types: Stype = SLU_SC, Dtype = SLU_S, Mtype = SLU_TRLU.
+ * 
+ *    U       (input) SuperMatrix*
+ *            The factor U from the factorization Pr*A*Pc=L*U as computed by
+ *            sgstrf(). Use column-wise storage scheme, i.e., U has types:
+ *            Stype = SLU_NC, Dtype = SLU_S, Mtype = SLU_TRU.
+ *	    
+ *    ANORM   (input) float
+ *            If NORM = '1' or 'O', the 1-norm of the original matrix A.   
+ *            If NORM = 'I', the infinity-norm of the original matrix A.
+ *	    
+ *    RCOND   (output) float*
+ *           The reciprocal of the condition number of the matrix A,   
+ *           computed as RCOND = 1/(norm(A) * norm(inv(A))).
+ *	    
+ *    INFO    (output) int*
+ *           = 0:  successful exit   
+ *           < 0:  if INFO = -i, the i-th argument had an illegal value   
+ *
+ *    ===================================================================== 
+ * 
+ */ + +void +sgscon(char *norm, SuperMatrix *L, SuperMatrix *U, + float anorm, float *rcond, SuperLUStat_t *stat, int *info) +{ + + + /* Local variables */ + int kase, kase1, onenrm, i; + float ainvnm; + float *work; + int *iwork; + int isave[3]; + extern int srscl_(int *, float *, float *, int *); + + extern int slacon2_(int *, float *, float *, int *, float *, int *, int []); + + + /* Test the input parameters. */ + *info = 0; + onenrm = *(unsigned char *)norm == '1' || strncmp(norm, "O", 1)==0; + if (! onenrm && ! strncmp(norm, "I", 1)==0) *info = -1; + else if (L->nrow < 0 || L->nrow != L->ncol || + L->Stype != SLU_SC || L->Dtype != SLU_S || L->Mtype != SLU_TRLU) + *info = -2; + else if (U->nrow < 0 || U->nrow != U->ncol || + U->Stype != SLU_NC || U->Dtype != SLU_S || U->Mtype != SLU_TRU) + *info = -3; + if (*info != 0) { + i = -(*info); + input_error("sgscon", &i); + return; + } + + /* Quick return if possible */ + *rcond = 0.; + if ( L->nrow == 0 || U->nrow == 0) { + *rcond = 1.; + return; + } + + work = floatCalloc( 3*L->nrow ); + iwork = intMalloc( L->nrow ); + + + if ( !work || !iwork ) + ABORT("Malloc fails for work arrays in sgscon."); + + /* Estimate the norm of inv(A). */ + ainvnm = 0.; + if ( onenrm ) kase1 = 1; + else kase1 = 2; + kase = 0; + + do { + slacon2_(&L->nrow, &work[L->nrow], &work[0], &iwork[0], &ainvnm, &kase, isave); + + if (kase == 0) break; + + if (kase == kase1) { + /* Multiply by inv(L). */ + sp_strsv("L", "No trans", "Unit", L, U, &work[0], stat, info); + + /* Multiply by inv(U). */ + sp_strsv("U", "No trans", "Non-unit", L, U, &work[0], stat, info); + + } else { + + /* Multiply by inv(U'). */ + sp_strsv("U", "Transpose", "Non-unit", L, U, &work[0], stat, info); + + /* Multiply by inv(L'). */ + sp_strsv("L", "Transpose", "Unit", L, U, &work[0], stat, info); + + } + + } while ( kase != 0 ); + + /* Compute the estimate of the reciprocal condition number. */ + if (ainvnm != 0.) *rcond = (1. / ainvnm) / anorm; + + SUPERLU_FREE (work); + SUPERLU_FREE (iwork); + return; + +} /* sgscon */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/sgsequ.c b/src/Libraries/superlu-5.2.1/SRC/sgsequ.c new file mode 100644 index 00000000..ca1711a6 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sgsequ.c @@ -0,0 +1,205 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sgsequ.c + * \brief Computes row and column scalings + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Modified from LAPACK routine SGEEQU
+ * 
+ */ +/* + * File name: sgsequ.c + * History: Modified from LAPACK routine SGEEQU + */ +#include +#include "slu_sdefs.h" + + + +/*! \brief + * + *
+ * Purpose   
+ *   =======   
+ *
+ *   SGSEQU computes row and column scalings intended to equilibrate an   
+ *   M-by-N sparse matrix A and reduce its condition number. R returns the row
+ *   scale factors and C the column scale factors, chosen to try to make   
+ *   the largest element in each row and column of the matrix B with   
+ *   elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1.   
+ *
+ *   R(i) and C(j) are restricted to be between SMLNUM = smallest safe   
+ *   number and BIGNUM = largest safe number.  Use of these scaling   
+ *   factors is not guaranteed to reduce the condition number of A but   
+ *   works well in practice.   
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   A       (input) SuperMatrix*
+ *           The matrix of dimension (A->nrow, A->ncol) whose equilibration
+ *           factors are to be computed. The type of A can be:
+ *           Stype = SLU_NC; Dtype = SLU_S; Mtype = SLU_GE.
+ *	    
+ *   R       (output) float*, size A->nrow
+ *           If INFO = 0 or INFO > M, R contains the row scale factors   
+ *           for A.
+ *	    
+ *   C       (output) float*, size A->ncol
+ *           If INFO = 0,  C contains the column scale factors for A.
+ *	    
+ *   ROWCND  (output) float*
+ *           If INFO = 0 or INFO > M, ROWCND contains the ratio of the   
+ *           smallest R(i) to the largest R(i).  If ROWCND >= 0.1 and   
+ *           AMAX is neither too large nor too small, it is not worth   
+ *           scaling by R.
+ *	    
+ *   COLCND  (output) float*
+ *           If INFO = 0, COLCND contains the ratio of the smallest   
+ *           C(i) to the largest C(i).  If COLCND >= 0.1, it is not   
+ *           worth scaling by C.
+ *	    
+ *   AMAX    (output) float*
+ *           Absolute value of largest matrix element.  If AMAX is very   
+ *           close to overflow or very close to underflow, the matrix   
+ *           should be scaled.
+ *	    
+ *   INFO    (output) int*
+ *           = 0:  successful exit   
+ *           < 0:  if INFO = -i, the i-th argument had an illegal value   
+ *           > 0:  if INFO = i,  and i is   
+ *                 <= A->nrow:  the i-th row of A is exactly zero   
+ *                 >  A->ncol:  the (i-M)-th column of A is exactly zero   
+ *
+ *   ===================================================================== 
+ * 
+ */ +void +sgsequ(SuperMatrix *A, float *r, float *c, float *rowcnd, + float *colcnd, float *amax, int *info) +{ + + + /* Local variables */ + NCformat *Astore; + float *Aval; + int i, j, irow; + float rcmin, rcmax; + float bignum, smlnum; + extern float smach(char *); + + /* Test the input parameters. */ + *info = 0; + if ( A->nrow < 0 || A->ncol < 0 || + A->Stype != SLU_NC || A->Dtype != SLU_S || A->Mtype != SLU_GE ) + *info = -1; + if (*info != 0) { + i = -(*info); + input_error("sgsequ", &i); + return; + } + + /* Quick return if possible */ + if ( A->nrow == 0 || A->ncol == 0 ) { + *rowcnd = 1.; + *colcnd = 1.; + *amax = 0.; + return; + } + + Astore = A->Store; + Aval = Astore->nzval; + + /* Get machine constants. */ + smlnum = smach("S"); /* slamch_("S"); */ + bignum = 1. / smlnum; + + /* Compute row scale factors. */ + for (i = 0; i < A->nrow; ++i) r[i] = 0.; + + /* Find the maximum element in each row. */ + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + r[irow] = SUPERLU_MAX( r[irow], fabs(Aval[i]) ); + } + + /* Find the maximum and minimum scale factors. */ + rcmin = bignum; + rcmax = 0.; + for (i = 0; i < A->nrow; ++i) { + rcmax = SUPERLU_MAX(rcmax, r[i]); + rcmin = SUPERLU_MIN(rcmin, r[i]); + } + *amax = rcmax; + + if (rcmin == 0.) { + /* Find the first zero scale factor and return an error code. */ + for (i = 0; i < A->nrow; ++i) + if (r[i] == 0.) { + *info = i + 1; + return; + } + } else { + /* Invert the scale factors. */ + for (i = 0; i < A->nrow; ++i) + r[i] = 1. / SUPERLU_MIN( SUPERLU_MAX( r[i], smlnum ), bignum ); + /* Compute ROWCND = min(R(I)) / max(R(I)) */ + *rowcnd = SUPERLU_MAX( rcmin, smlnum ) / SUPERLU_MIN( rcmax, bignum ); + } + + /* Compute column scale factors */ + for (j = 0; j < A->ncol; ++j) c[j] = 0.; + + /* Find the maximum element in each column, assuming the row + scalings computed above. */ + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + c[j] = SUPERLU_MAX( c[j], fabs(Aval[i]) * r[irow] ); + } + + /* Find the maximum and minimum scale factors. */ + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->ncol; ++j) { + rcmax = SUPERLU_MAX(rcmax, c[j]); + rcmin = SUPERLU_MIN(rcmin, c[j]); + } + + if (rcmin == 0.) { + /* Find the first zero scale factor and return an error code. */ + for (j = 0; j < A->ncol; ++j) + if ( c[j] == 0. ) { + *info = A->nrow + j + 1; + return; + } + } else { + /* Invert the scale factors. */ + for (j = 0; j < A->ncol; ++j) + c[j] = 1. / SUPERLU_MIN( SUPERLU_MAX( c[j], smlnum ), bignum); + /* Compute COLCND = min(C(J)) / max(C(J)) */ + *colcnd = SUPERLU_MAX( rcmin, smlnum ) / SUPERLU_MIN( rcmax, bignum ); + } + + return; + +} /* sgsequ */ + + diff --git a/src/Libraries/superlu-5.2.1/SRC/sgsisx.c b/src/Libraries/superlu-5.2.1/SRC/sgsisx.c new file mode 100644 index 00000000..e58c8dfd --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sgsisx.c @@ -0,0 +1,738 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sgsisx.c + * \brief Computes an approximate solutions of linear equations A*X=B or A'*X=B + * + *
+ * -- SuperLU routine (version 4.2) --
+ * Lawrence Berkeley National Laboratory.
+ * November, 2010
+ * August, 2011
+ * 
+ */ +#include "slu_sdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * SGSISX computes an approximate solutions of linear equations
+ * A*X=B or A'*X=B, using the ILU factorization from sgsitrf().
+ * An estimation of the condition number is provided. 
+ * The routine performs the following steps:
+ *
+ *   1. If A is stored column-wise (A->Stype = SLU_NC):
+ *  
+ *	1.1. If options->Equil = YES or options->RowPerm = LargeDiag, scaling
+ *	     factors are computed to equilibrate the system:
+ *	     options->Trans = NOTRANS:
+ *		 diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *	     options->Trans = TRANS:
+ *		 (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *	     options->Trans = CONJ:
+ *		 (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *	     Whether or not the system will be equilibrated depends on the
+ *	     scaling of the matrix A, but if equilibration is used, A is
+ *	     overwritten by diag(R)*A*diag(C) and B by diag(R)*B
+ *	     (if options->Trans=NOTRANS) or diag(C)*B (if options->Trans
+ *	     = TRANS or CONJ).
+ *
+ *	1.2. Permute columns of A, forming A*Pc, where Pc is a permutation
+ *	     matrix that usually preserves sparsity.
+ *	     For more details of this step, see sp_preorder.c.
+ *
+ *	1.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *	     factor the matrix A (after equilibration if options->Equil = YES)
+ *	     as Pr*A*Pc = L*U, with Pr determined by partial pivoting.
+ *
+ *	1.4. Compute the reciprocal pivot growth factor.
+ *
+ *	1.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *	     routine fills a small number on the diagonal entry, that is
+ *		U(i,i) = ||A(:,i)||_oo * options->ILU_FillTol ** (1 - i / n),
+ *	     and info will be increased by 1. The factored form of A is used
+ *	     to estimate the condition number of the preconditioner. If the
+ *	     reciprocal of the condition number is less than machine precision,
+ *	     info = A->ncol+1 is returned as a warning, but the routine still
+ *	     goes on to solve for X.
+ *
+ *	1.6. The system of equations is solved for X using the factored form
+ *	     of A.
+ *
+ *	1.7. options->IterRefine is not used
+ *
+ *	1.8. If equilibration was used, the matrix X is premultiplied by
+ *	     diag(C) (if options->Trans = NOTRANS) or diag(R)
+ *	     (if options->Trans = TRANS or CONJ) so that it solves the
+ *	     original system before equilibration.
+ *
+ *	1.9. options for ILU only
+ *	     1) If options->RowPerm = LargeDiag, MC64 is used to scale and
+ *		permute the matrix to an I-matrix, that is Pr*Dr*A*Dc has
+ *		entries of modulus 1 on the diagonal and off-diagonal entries
+ *		of modulus at most 1. If MC64 fails, dgsequ() is used to
+ *		equilibrate the system.
+ *              ( Default: LargeDiag )
+ *	     2) options->ILU_DropTol = tau is the threshold for dropping.
+ *		For L, it is used directly (for the whole row in a supernode);
+ *		For U, ||A(:,i)||_oo * tau is used as the threshold
+ *	        for the	i-th column.
+ *		If a secondary dropping rule is required, tau will
+ *	        also be used to compute the second threshold.
+ *              ( Default: 1e-4 )
+ *	     3) options->ILU_FillFactor = gamma, used as the initial guess
+ *		of memory growth.
+ *		If a secondary dropping rule is required, it will also
+ *              be used as an upper bound of the memory.
+ *              ( Default: 10 )
+ *	     4) options->ILU_DropRule specifies the dropping rule.
+ *		Option	      Meaning
+ *		======	      ===========
+ *		DROP_BASIC:   Basic dropping rule, supernodal based ILUTP(tau).
+ *		DROP_PROWS:   Supernodal based ILUTP(p,tau), p = gamma*nnz(A)/n.
+ *		DROP_COLUMN:  Variant of ILUTP(p,tau), for j-th column,
+ *			      p = gamma * nnz(A(:,j)).
+ *		DROP_AREA:    Variation of ILUTP, for j-th column, use
+ *			      nnz(F(:,1:j)) / nnz(A(:,1:j)) to control memory.
+ *		DROP_DYNAMIC: Modify the threshold tau during factorizaion:
+ *			      If nnz(L(:,1:j)) / nnz(A(:,1:j)) > gamma
+ *				  tau_L(j) := MIN(tau_0, tau_L(j-1) * 2);
+ *			      Otherwise
+ *				  tau_L(j) := MAX(tau_0, tau_L(j-1) / 2);
+ *			      tau_U(j) uses the similar rule.
+ *			      NOTE: the thresholds used by L and U are separate.
+ *		DROP_INTERP:  Compute the second dropping threshold by
+ *			      interpolation instead of sorting (default).
+ *			      In this case, the actual fill ratio is not
+ *			      guaranteed smaller than gamma.
+ *		DROP_PROWS, DROP_COLUMN and DROP_AREA are mutually exclusive.
+ *		( Default: DROP_BASIC | DROP_AREA )
+ *	     5) options->ILU_Norm is the criterion of measuring the magnitude
+ *		of a row in a supernode of L. ( Default is INF_NORM )
+ *		options->ILU_Norm	RowSize(x[1:n])
+ *		=================	===============
+ *		ONE_NORM		||x||_1 / n
+ *		TWO_NORM		||x||_2 / sqrt(n)
+ *		INF_NORM		max{|x[i]|}
+ *	     6) options->ILU_MILU specifies the type of MILU's variation.
+ *		= SILU: do not perform Modified ILU;
+ *		= SMILU_1 (not recommended):
+ *		    U(i,i) := U(i,i) + sum(dropped entries);
+ *		= SMILU_2:
+ *		    U(i,i) := U(i,i) + SGN(U(i,i)) * sum(dropped entries);
+ *		= SMILU_3:
+ *		    U(i,i) := U(i,i) + SGN(U(i,i)) * sum(|dropped entries|);
+ *		NOTE: Even SMILU_1 does not preserve the column sum because of
+ *		late dropping.
+ *              ( Default: SILU )
+ *	     7) options->ILU_FillTol is used as the perturbation when
+ *		encountering zero pivots. If some U(i,i) = 0, so that U is
+ *		exactly singular, then
+ *		   U(i,i) := ||A(:,i)|| * options->ILU_FillTol ** (1 - i / n).
+ *              ( Default: 1e-2 )
+ *
+ *   2. If A is stored row-wise (A->Stype = SLU_NR), apply the above algorithm
+ *	to the transpose of A:
+ *
+ *	2.1. If options->Equil = YES or options->RowPerm = LargeDiag, scaling
+ *	     factors are computed to equilibrate the system:
+ *	     options->Trans = NOTRANS:
+ *		 diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *	     options->Trans = TRANS:
+ *		 (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *	     options->Trans = CONJ:
+ *		 (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *	     Whether or not the system will be equilibrated depends on the
+ *	     scaling of the matrix A, but if equilibration is used, A' is
+ *	     overwritten by diag(R)*A'*diag(C) and B by diag(R)*B
+ *	     (if trans='N') or diag(C)*B (if trans = 'T' or 'C').
+ *
+ *	2.2. Permute columns of transpose(A) (rows of A),
+ *	     forming transpose(A)*Pc, where Pc is a permutation matrix that
+ *	     usually preserves sparsity.
+ *	     For more details of this step, see sp_preorder.c.
+ *
+ *	2.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *	     factor the transpose(A) (after equilibration if
+ *	     options->Fact = YES) as Pr*transpose(A)*Pc = L*U with the
+ *	     permutation Pr determined by partial pivoting.
+ *
+ *	2.4. Compute the reciprocal pivot growth factor.
+ *
+ *	2.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *	     routine fills a small number on the diagonal entry, that is
+ *		 U(i,i) = ||A(:,i)||_oo * options->ILU_FillTol ** (1 - i / n).
+ *	     And info will be increased by 1. The factored form of A is used
+ *	     to estimate the condition number of the preconditioner. If the
+ *	     reciprocal of the condition number is less than machine precision,
+ *	     info = A->ncol+1 is returned as a warning, but the routine still
+ *	     goes on to solve for X.
+ *
+ *	2.6. The system of equations is solved for X using the factored form
+ *	     of transpose(A).
+ *
+ *	2.7. If options->IterRefine is not used.
+ *
+ *	2.8. If equilibration was used, the matrix X is premultiplied by
+ *	     diag(C) (if options->Trans = NOTRANS) or diag(R)
+ *	     (if options->Trans = TRANS or CONJ) so that it solves the
+ *	     original system before equilibration.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *	   The structure defines the input parameters to control
+ *	   how the LU decomposition will be performed and how the
+ *	   system will be solved.
+ *
+ * A	   (input/output) SuperMatrix*
+ *	   Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
+ *	   of the linear equations is A->nrow. Currently, the type of A can be:
+ *	   Stype = SLU_NC or SLU_NR, Dtype = SLU_S, Mtype = SLU_GE.
+ *	   In the future, more general A may be handled.
+ *
+ *	   On entry, If options->Fact = FACTORED and equed is not 'N',
+ *	   then A must have been equilibrated by the scaling factors in
+ *	   R and/or C.
+ *	   On exit, A is not modified
+ *         if options->Equil = NO, or
+ *         if options->Equil = YES but equed = 'N' on exit, or
+ *         if options->RowPerm = NO.
+ *
+ *	   Otherwise, if options->Equil = YES and equed is not 'N',
+ *	   A is scaled as follows:
+ *	   If A->Stype = SLU_NC:
+ *	     equed = 'R':  A := diag(R) * A
+ *	     equed = 'C':  A := A * diag(C)
+ *	     equed = 'B':  A := diag(R) * A * diag(C).
+ *	   If A->Stype = SLU_NR:
+ *	     equed = 'R':  transpose(A) := diag(R) * transpose(A)
+ *	     equed = 'C':  transpose(A) := transpose(A) * diag(C)
+ *	     equed = 'B':  transpose(A) := diag(R) * transpose(A) * diag(C).
+ *
+ *         If options->RowPerm = LargeDiag, MC64 is used to scale and permute
+ *            the matrix to an I-matrix, that is A is modified as follows:
+ *            P*Dr*A*Dc has entries of modulus 1 on the diagonal and 
+ *            off-diagonal entries of modulus at most 1. P is a permutation
+ *            obtained from MC64.
+ *            If MC64 fails, sgsequ() is used to equilibrate the system,
+ *            and A is scaled as above, but no permutation is involved.
+ *            On exit, A is restored to the orginal row numbering, so
+ *            Dr*A*Dc is returned.
+ *
+ * perm_c  (input/output) int*
+ *	   If A->Stype = SLU_NC, Column permutation vector of size A->ncol,
+ *	   which defines the permutation matrix Pc; perm_c[i] = j means
+ *	   column i of A is in position j in A*Pc.
+ *	   On exit, perm_c may be overwritten by the product of the input
+ *	   perm_c and a permutation that postorders the elimination tree
+ *	   of Pc'*A'*A*Pc; perm_c is not changed if the elimination tree
+ *	   is already in postorder.
+ *
+ *	   If A->Stype = SLU_NR, column permutation vector of size A->nrow,
+ *	   which describes permutation of columns of transpose(A) 
+ *	   (rows of A) as described above.
+ *
+ * perm_r  (input/output) int*
+ *	   If A->Stype = SLU_NC, row permutation vector of size A->nrow, 
+ *	   which defines the permutation matrix Pr, and is determined
+ *	   by MC64 first then followed by partial pivoting.
+ *         perm_r[i] = j means row i of A is in position j in Pr*A.
+ *
+ *	   If A->Stype = SLU_NR, permutation vector of size A->ncol, which
+ *	   determines permutation of rows of transpose(A)
+ *	   (columns of A) as described above.
+ *
+ *	   If options->Fact = SamePattern_SameRowPerm, the pivoting routine
+ *	   will try to use the input perm_r, unless a certain threshold
+ *	   criterion is violated. In that case, perm_r is overwritten by a
+ *	   new permutation determined by partial pivoting or diagonal
+ *	   threshold pivoting.
+ *	   Otherwise, perm_r is output argument.
+ *
+ * etree   (input/output) int*,  dimension (A->ncol)
+ *	   Elimination tree of Pc'*A'*A*Pc.
+ *	   If options->Fact != FACTORED and options->Fact != DOFACT,
+ *	   etree is an input argument, otherwise it is an output argument.
+ *	   Note: etree is a vector of parent pointers for a forest whose
+ *	   vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *
+ * equed   (input/output) char*
+ *	   Specifies the form of equilibration that was done.
+ *	   = 'N': No equilibration.
+ *	   = 'R': Row equilibration, i.e., A was premultiplied by diag(R).
+ *	   = 'C': Column equilibration, i.e., A was postmultiplied by diag(C).
+ *	   = 'B': Both row and column equilibration, i.e., A was replaced 
+ *		  by diag(R)*A*diag(C).
+ *	   If options->Fact = FACTORED, equed is an input argument,
+ *	   otherwise it is an output argument.
+ *
+ * R	   (input/output) float*, dimension (A->nrow)
+ *	   The row scale factors for A or transpose(A).
+ *	   If equed = 'R' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *	       (if A->Stype = SLU_NR) is multiplied on the left by diag(R).
+ *	   If equed = 'N' or 'C', R is not accessed.
+ *	   If options->Fact = FACTORED, R is an input argument,
+ *	       otherwise, R is output.
+ *	   If options->Fact = FACTORED and equed = 'R' or 'B', each element
+ *	       of R must be positive.
+ *
+ * C	   (input/output) float*, dimension (A->ncol)
+ *	   The column scale factors for A or transpose(A).
+ *	   If equed = 'C' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *	       (if A->Stype = SLU_NR) is multiplied on the right by diag(C).
+ *	   If equed = 'N' or 'R', C is not accessed.
+ *	   If options->Fact = FACTORED, C is an input argument,
+ *	       otherwise, C is output.
+ *	   If options->Fact = FACTORED and equed = 'C' or 'B', each element
+ *	       of C must be positive.
+ *
+ * L	   (output) SuperMatrix*
+ *	   The factor L from the factorization
+ *	       Pr*A*Pc=L*U		(if A->Stype SLU_= NC) or
+ *	       Pr*transpose(A)*Pc=L*U	(if A->Stype = SLU_NR).
+ *	   Uses compressed row subscripts storage for supernodes, i.e.,
+ *	   L has types: Stype = SLU_SC, Dtype = SLU_S, Mtype = SLU_TRLU.
+ *
+ * U	   (output) SuperMatrix*
+ *	   The factor U from the factorization
+ *	       Pr*A*Pc=L*U		(if A->Stype = SLU_NC) or
+ *	       Pr*transpose(A)*Pc=L*U	(if A->Stype = SLU_NR).
+ *	   Uses column-wise storage scheme, i.e., U has types:
+ *	   Stype = SLU_NC, Dtype = SLU_S, Mtype = SLU_TRU.
+ *
+ * work    (workspace/output) void*, size (lwork) (in bytes)
+ *	   User supplied workspace, should be large enough
+ *	   to hold data structures for factors L and U.
+ *	   On exit, if fact is not 'F', L and U point to this array.
+ *
+ * lwork   (input) int
+ *	   Specifies the size of work array in bytes.
+ *	   = 0:  allocate space internally by system malloc;
+ *	   > 0:  use user-supplied work array of length lwork in bytes,
+ *		 returns error if space runs out.
+ *	   = -1: the routine guesses the amount of space needed without
+ *		 performing the factorization, and returns it in
+ *		 mem_usage->total_needed; no other side effects.
+ *
+ *	   See argument 'mem_usage' for memory usage statistics.
+ *
+ * B	   (input/output) SuperMatrix*
+ *	   B has types: Stype = SLU_DN, Dtype = SLU_S, Mtype = SLU_GE.
+ *	   On entry, the right hand side matrix.
+ *	   If B->ncol = 0, only LU decomposition is performed, the triangular
+ *			   solve is skipped.
+ *	   On exit,
+ *	      if equed = 'N', B is not modified; otherwise
+ *	      if A->Stype = SLU_NC:
+ *		 if options->Trans = NOTRANS and equed = 'R' or 'B',
+ *		    B is overwritten by diag(R)*B;
+ *		 if options->Trans = TRANS or CONJ and equed = 'C' of 'B',
+ *		    B is overwritten by diag(C)*B;
+ *	      if A->Stype = SLU_NR:
+ *		 if options->Trans = NOTRANS and equed = 'C' or 'B',
+ *		    B is overwritten by diag(C)*B;
+ *		 if options->Trans = TRANS or CONJ and equed = 'R' of 'B',
+ *		    B is overwritten by diag(R)*B.
+ *
+ * X	   (output) SuperMatrix*
+ *	   X has types: Stype = SLU_DN, Dtype = SLU_S, Mtype = SLU_GE.
+ *	   If info = 0 or info = A->ncol+1, X contains the solution matrix
+ *	   to the original system of equations. Note that A and B are modified
+ *	   on exit if equed is not 'N', and the solution to the equilibrated
+ *	   system is inv(diag(C))*X if options->Trans = NOTRANS and
+ *	   equed = 'C' or 'B', or inv(diag(R))*X if options->Trans = 'T' or 'C'
+ *	   and equed = 'R' or 'B'.
+ *
+ * recip_pivot_growth (output) float*
+ *	   The reciprocal pivot growth factor max_j( norm(A_j)/norm(U_j) ).
+ *	   The infinity norm is used. If recip_pivot_growth is much less
+ *	   than 1, the stability of the LU factorization could be poor.
+ *
+ * rcond   (output) float*
+ *	   The estimate of the reciprocal condition number of the matrix A
+ *	   after equilibration (if done). If rcond is less than the machine
+ *	   precision (in particular, if rcond = 0), the matrix is singular
+ *	   to working precision. This condition is indicated by a return
+ *	   code of info > 0.
+ *
+ * mem_usage (output) mem_usage_t*
+ *	   Record the memory usage statistics, consisting of following fields:
+ *	   - for_lu (float)
+ *	     The amount of space used in bytes for L\U data structures.
+ *	   - total_needed (float)
+ *	     The amount of space needed in bytes to perform factorization.
+ *	   - expansions (int)
+ *	     The number of memory expansions during the LU factorization.
+ *
+ * stat   (output) SuperLUStat_t*
+ *	  Record the statistics on runtime and floating-point operation count.
+ *	  See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ *	   = 0: successful exit
+ *	   < 0: if info = -i, the i-th argument had an illegal value
+ *	   > 0: if info = i, and i is
+ *		<= A->ncol: number of zero pivots. They are replaced by small
+ *		      entries due to options->ILU_FillTol.
+ *		= A->ncol+1: U is nonsingular, but RCOND is less than machine
+ *		      precision, meaning that the matrix is singular to
+ *		      working precision. Nevertheless, the solution and
+ *		      error bounds are computed because there are a number
+ *		      of situations where the computed solution can be more
+ *		      accurate than the value of RCOND would suggest.
+ *		> A->ncol+1: number of bytes allocated when memory allocation
+ *		      failure occurred, plus A->ncol.
+ * 
+ */ + +void +sgsisx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, + int *etree, char *equed, float *R, float *C, + SuperMatrix *L, SuperMatrix *U, void *work, int lwork, + SuperMatrix *B, SuperMatrix *X, + float *recip_pivot_growth, float *rcond, + GlobalLU_t *Glu, mem_usage_t *mem_usage, SuperLUStat_t *stat, int *info) +{ + + DNformat *Bstore, *Xstore; + float *Bmat, *Xmat; + int ldb, ldx, nrhs, n; + SuperMatrix *AA;/* A in SLU_NC format used by the factorization routine.*/ + SuperMatrix AC; /* Matrix postmultiplied by Pc */ + int colequ, equil, nofact, notran, rowequ, permc_spec, mc64; + trans_t trant; + char norm[1]; + int i, j, info1; + float amax, anorm, bignum, smlnum, colcnd, rowcnd, rcmax, rcmin; + int relax, panel_size; + float diag_pivot_thresh; + double t0; /* temporary time */ + double *utime; + + int *perm = NULL; /* permutation returned from MC64 */ + + /* External functions */ + extern float slangs(char *, SuperMatrix *); + + Bstore = B->Store; + Xstore = X->Store; + Bmat = Bstore->nzval; + Xmat = Xstore->nzval; + ldb = Bstore->lda; + ldx = Xstore->lda; + nrhs = B->ncol; + n = B->nrow; + + *info = 0; + nofact = (options->Fact != FACTORED); + equil = (options->Equil == YES); + notran = (options->Trans == NOTRANS); + mc64 = (options->RowPerm == LargeDiag); + if ( nofact ) { + *(unsigned char *)equed = 'N'; + rowequ = FALSE; + colequ = FALSE; + } else { + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + smlnum = smach("Safe minimum"); /* lamch_("Safe minimum"); */ + bignum = 1. / smlnum; + } + + /* Test the input parameters */ + if (options->Fact != DOFACT && options->Fact != SamePattern && + options->Fact != SamePattern_SameRowPerm && + options->Fact != FACTORED && + options->Trans != NOTRANS && options->Trans != TRANS && + options->Trans != CONJ && + options->Equil != NO && options->Equil != YES) + *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + (A->Stype != SLU_NC && A->Stype != SLU_NR) || + A->Dtype != SLU_S || A->Mtype != SLU_GE ) + *info = -2; + else if ( options->Fact == FACTORED && + !(rowequ || colequ || strncmp(equed, "N", 1)==0) ) + *info = -6; + else { + if (rowequ) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, R[j]); + rcmax = SUPERLU_MAX(rcmax, R[j]); + } + if (rcmin <= 0.) *info = -7; + else if ( A->nrow > 0) + rowcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else rowcnd = 1.; + } + if (colequ && *info == 0) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, C[j]); + rcmax = SUPERLU_MAX(rcmax, C[j]); + } + if (rcmin <= 0.) *info = -8; + else if (A->nrow > 0) + colcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else colcnd = 1.; + } + if (*info == 0) { + if ( lwork < -1 ) *info = -12; + else if ( B->ncol < 0 || Bstore->lda < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_S || + B->Mtype != SLU_GE ) + *info = -13; + else if ( X->ncol < 0 || Xstore->lda < SUPERLU_MAX(0, A->nrow) || + (B->ncol != 0 && B->ncol != X->ncol) || + X->Stype != SLU_DN || + X->Dtype != SLU_S || X->Mtype != SLU_GE ) + *info = -14; + } + } + if (*info != 0) { + i = -(*info); + input_error("sgsisx", &i); + return; + } + + /* Initialization for factor parameters */ + panel_size = sp_ienv(1); + relax = sp_ienv(2); + diag_pivot_thresh = options->DiagPivotThresh; + + utime = stat->utime; + + /* Convert A to SLU_NC format when necessary. */ + if ( A->Stype == SLU_NR ) { + NRformat *Astore = A->Store; + AA = (SuperMatrix *) SUPERLU_MALLOC( sizeof(SuperMatrix) ); + sCreate_CompCol_Matrix(AA, A->ncol, A->nrow, Astore->nnz, + Astore->nzval, Astore->colind, Astore->rowptr, + SLU_NC, A->Dtype, A->Mtype); + if ( notran ) { /* Reverse the transpose argument. */ + trant = TRANS; + notran = 0; + } else { + trant = NOTRANS; + notran = 1; + } + } else { /* A->Stype == SLU_NC */ + trant = options->Trans; + AA = A; + } + + if ( nofact ) { + register int i, j; + NCformat *Astore = AA->Store; + int nnz = Astore->nnz; + int *colptr = Astore->colptr; + int *rowind = Astore->rowind; + float *nzval = (float *)Astore->nzval; + + if ( mc64 ) { + t0 = SuperLU_timer_(); + if ((perm = intMalloc(n)) == NULL) + ABORT("SUPERLU_MALLOC fails for perm[]"); + + info1 = sldperm(5, n, nnz, colptr, rowind, nzval, perm, R, C); + + if (info1 != 0) { /* MC64 fails, call sgsequ() later */ + mc64 = 0; + SUPERLU_FREE(perm); + perm = NULL; + } else { + if ( equil ) { + rowequ = colequ = 1; + for (i = 0; i < n; i++) { + R[i] = exp(R[i]); + C[i] = exp(C[i]); + } + /* scale the matrix */ + for (j = 0; j < n; j++) { + for (i = colptr[j]; i < colptr[j + 1]; i++) { + nzval[i] *= R[rowind[i]] * C[j]; + } + } + *equed = 'B'; + } + + /* permute the matrix */ + for (j = 0; j < n; j++) { + for (i = colptr[j]; i < colptr[j + 1]; i++) { + /*nzval[i] *= R[rowind[i]] * C[j];*/ + rowind[i] = perm[rowind[i]]; + } + } + } + utime[EQUIL] = SuperLU_timer_() - t0; + } + + if ( !mc64 & equil ) { /* Only perform equilibration, no row perm */ + t0 = SuperLU_timer_(); + /* Compute row and column scalings to equilibrate the matrix A. */ + sgsequ(AA, R, C, &rowcnd, &colcnd, &amax, &info1); + + if ( info1 == 0 ) { + /* Equilibrate matrix A. */ + slaqgs(AA, R, C, rowcnd, colcnd, amax, equed); + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + } + utime[EQUIL] = SuperLU_timer_() - t0; + } + } + + + if ( nofact ) { + + t0 = SuperLU_timer_(); + /* + * Gnet column permutation vector perm_c[], according to permc_spec: + * permc_spec = NATURAL: natural ordering + * permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A + * permc_spec = MMD_ATA: minimum degree on structure of A'*A + * permc_spec = COLAMD: approximate minimum degree column ordering + * permc_spec = MY_PERMC: the ordering already supplied in perm_c[] + */ + permc_spec = options->ColPerm; + if ( permc_spec != MY_PERMC && options->Fact == DOFACT ) + get_perm_c(permc_spec, AA, perm_c); + utime[COLPERM] = SuperLU_timer_() - t0; + + t0 = SuperLU_timer_(); + sp_preorder(options, AA, perm_c, etree, &AC); + utime[ETREE] = SuperLU_timer_() - t0; + + /* Compute the LU factorization of A*Pc. */ + t0 = SuperLU_timer_(); + sgsitrf(options, &AC, relax, panel_size, etree, work, lwork, + perm_c, perm_r, L, U, Glu, stat, info); + utime[FACT] = SuperLU_timer_() - t0; + + if ( lwork == -1 ) { + mem_usage->total_needed = *info - A->ncol; + return; + } + + if ( mc64 ) { /* Fold MC64's perm[] into perm_r[]. */ + NCformat *Astore = AA->Store; + int nnz = Astore->nnz, *rowind = Astore->rowind; + int *perm_tmp, *iperm; + if ((perm_tmp = intMalloc(2*n)) == NULL) + ABORT("SUPERLU_MALLOC fails for perm_tmp[]"); + iperm = perm_tmp + n; + for (i = 0; i < n; ++i) perm_tmp[i] = perm_r[perm[i]]; + for (i = 0; i < n; ++i) { + perm_r[i] = perm_tmp[i]; + iperm[perm[i]] = i; + } + + /* Restore A's original row indices. */ + for (i = 0; i < nnz; ++i) rowind[i] = iperm[rowind[i]]; + + SUPERLU_FREE(perm); /* MC64 permutation */ + SUPERLU_FREE(perm_tmp); + } + } + + if ( options->PivotGrowth ) { + if ( *info > 0 ) return; + + /* Compute the reciprocal pivot growth factor *recip_pivot_growth. */ + *recip_pivot_growth = sPivotGrowth(A->ncol, AA, perm_c, L, U); + } + + if ( options->ConditionNumber ) { + /* Estimate the reciprocal of the condition number of A. */ + t0 = SuperLU_timer_(); + if ( notran ) { + *(unsigned char *)norm = '1'; + } else { + *(unsigned char *)norm = 'I'; + } + anorm = slangs(norm, AA); + sgscon(norm, L, U, anorm, rcond, stat, &info1); + utime[RCOND] = SuperLU_timer_() - t0; + } + + if ( nrhs > 0 ) { /* Solve the system */ + float *rhs_work; + + /* Scale and permute the right-hand side if equilibration + and permutation from MC64 were performed. */ + if ( notran ) { + if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) + Bmat[i + j*ldb] *= R[i]; + } + } else if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) { + Bmat[i + j*ldb] *= C[i]; + } + } + + /* Compute the solution matrix X. */ + for (j = 0; j < nrhs; j++) /* Save a copy of the right hand sides */ + for (i = 0; i < B->nrow; i++) + Xmat[i + j*ldx] = Bmat[i + j*ldb]; + + t0 = SuperLU_timer_(); + sgstrs (trant, L, U, perm_c, perm_r, X, stat, &info1); + utime[SOLVE] = SuperLU_timer_() - t0; + + /* Transform the solution matrix X to a solution of the original + system. */ + if ( notran ) { + if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) { + Xmat[i + j*ldx] *= C[i]; + } + } + } else { /* transposed system */ + if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) { + Xmat[i + j*ldx] *= R[i]; + } + } + } + + } /* end if nrhs > 0 */ + + if ( options->ConditionNumber ) { + /* The matrix is singular to working precision. */ + /* if ( *rcond < slamch_("E") && *info == 0) *info = A->ncol + 1; */ + if ( *rcond < smach("E") && *info == 0) *info = A->ncol + 1; + } + + if ( nofact ) { + ilu_sQuerySpace(L, U, mem_usage); + Destroy_CompCol_Permuted(&AC); + } + if ( A->Stype == SLU_NR ) { + Destroy_SuperMatrix_Store(AA); + SUPERLU_FREE(AA); + } + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/sgsitrf.c b/src/Libraries/superlu-5.2.1/SRC/sgsitrf.c new file mode 100644 index 00000000..81bb97f5 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sgsitrf.c @@ -0,0 +1,663 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sgsitrf.c + * \brief Computes an ILU factorization of a general sparse matrix + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ *
+ * 
+ */ + +#include "slu_sdefs.h" + +#ifdef DEBUG +int num_drop_L; +#endif + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * SGSITRF computes an ILU factorization of a general sparse m-by-n
+ * matrix A using partial pivoting with row interchanges.
+ * The factorization has the form
+ *     Pr * A = L * U
+ * where Pr is a row permutation matrix, L is lower triangular with unit
+ * diagonal elements (lower trapezoidal if A->nrow > A->ncol), and U is upper
+ * triangular (upper trapezoidal if A->nrow < A->ncol).
+ *
+ * See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *	   The structure defines the input parameters to control
+ *	   how the ILU decomposition will be performed.
+ *
+ * A	    (input) SuperMatrix*
+ *	    Original matrix A, permuted by columns, of dimension
+ *	    (A->nrow, A->ncol). The type of A can be:
+ *	    Stype = SLU_NCP; Dtype = SLU_S; Mtype = SLU_GE.
+ *
+ * relax    (input) int
+ *	    To control degree of relaxing supernodes. If the number
+ *	    of nodes (columns) in a subtree of the elimination tree is less
+ *	    than relax, this subtree is considered as one supernode,
+ *	    regardless of the row structures of those columns.
+ *
+ * panel_size (input) int
+ *	    A panel consists of at most panel_size consecutive columns.
+ *
+ * etree    (input) int*, dimension (A->ncol)
+ *	    Elimination tree of A'*A.
+ *	    Note: etree is a vector of parent pointers for a forest whose
+ *	    vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *	    On input, the columns of A should be permuted so that the
+ *	    etree is in a certain postorder.
+ *
+ * work     (input/output) void*, size (lwork) (in bytes)
+ *	    User-supplied work space and space for the output data structures.
+ *	    Not referenced if lwork = 0;
+ *
+ * lwork   (input) int
+ *	   Specifies the size of work array in bytes.
+ *	   = 0:  allocate space internally by system malloc;
+ *	   > 0:  use user-supplied work array of length lwork in bytes,
+ *		 returns error if space runs out.
+ *	   = -1: the routine guesses the amount of space needed without
+ *		 performing the factorization, and returns it in
+ *		 *info; no other side effects.
+ *
+ * perm_c   (input) int*, dimension (A->ncol)
+ *	    Column permutation vector, which defines the
+ *	    permutation matrix Pc; perm_c[i] = j means column i of A is
+ *	    in position j in A*Pc.
+ *	    When searching for diagonal, perm_c[*] is applied to the
+ *	    row subscripts of A, so that diagonal threshold pivoting
+ *	    can find the diagonal of A, rather than that of A*Pc.
+ *
+ * perm_r   (input/output) int*, dimension (A->nrow)
+ *	    Row permutation vector which defines the permutation matrix Pr,
+ *	    perm_r[i] = j means row i of A is in position j in Pr*A.
+ *	    If options->Fact = SamePattern_SameRowPerm, the pivoting routine
+ *	       will try to use the input perm_r, unless a certain threshold
+ *	       criterion is violated. In that case, perm_r is overwritten by
+ *	       a new permutation determined by partial pivoting or diagonal
+ *	       threshold pivoting.
+ *	    Otherwise, perm_r is output argument;
+ *
+ * L	    (output) SuperMatrix*
+ *	    The factor L from the factorization Pr*A=L*U; use compressed row
+ *	    subscripts storage for supernodes, i.e., L has type:
+ *	    Stype = SLU_SC, Dtype = SLU_S, Mtype = SLU_TRLU.
+ *
+ * U	    (output) SuperMatrix*
+ *	    The factor U from the factorization Pr*A*Pc=L*U. Use column-wise
+ *	    storage scheme, i.e., U has types: Stype = SLU_NC,
+ *	    Dtype = SLU_S, Mtype = SLU_TRU.
+ *
+ * Glu      (input/output) GlobalLU_t *
+ *          If options->Fact == SamePattern_SameRowPerm, it is an input;
+ *              The matrix A will be factorized assuming that a 
+ *              factorization of a matrix with the same sparsity pattern
+ *              and similar numerical values was performed prior to this one.
+ *              Therefore, this factorization will reuse both row and column
+ *		scaling factors R and C, both row and column permutation
+ *		vectors perm_r and perm_c, and the L & U data structures
+ *		set up from the previous factorization.
+ *          Otherwise, it is an output.
+ *
+ * stat     (output) SuperLUStat_t*
+ *	    Record the statistics on runtime and floating-point operation count.
+ *	    See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info     (output) int*
+ *	    = 0: successful exit
+ *	    < 0: if info = -i, the i-th argument had an illegal value
+ *	    > 0: if info = i, and i is
+ *	       <= A->ncol: number of zero pivots. They are replaced by small
+ *		  entries according to options->ILU_FillTol.
+ *	       > A->ncol: number of bytes allocated when memory allocation
+ *		  failure occurred, plus A->ncol. If lwork = -1, it is
+ *		  the estimated amount of space needed, plus A->ncol.
+ *
+ * ======================================================================
+ *
+ * Local Working Arrays:
+ * ======================
+ *   m = number of rows in the matrix
+ *   n = number of columns in the matrix
+ *
+ *   marker[0:3*m-1]: marker[i] = j means that node i has been
+ *	reached when working on column j.
+ *	Storage: relative to original row subscripts
+ *	NOTE: There are 4 of them:
+ *	      marker/marker1 are used for panel dfs, see (ilu_)dpanel_dfs.c;
+ *	      marker2 is used for inner-factorization, see (ilu)_dcolumn_dfs.c;
+ *	      marker_relax(has its own space) is used for relaxed supernodes.
+ *
+ *   parent[0:m-1]: parent vector used during dfs
+ *	Storage: relative to new row subscripts
+ *
+ *   xplore[0:m-1]: xplore[i] gives the location of the next (dfs)
+ *	unexplored neighbor of i in lsub[*]
+ *
+ *   segrep[0:nseg-1]: contains the list of supernodal representatives
+ *	in topological order of the dfs. A supernode representative is the
+ *	last column of a supernode.
+ *	The maximum size of segrep[] is n.
+ *
+ *   repfnz[0:W*m-1]: for a nonzero segment U[*,j] that ends at a
+ *	supernodal representative r, repfnz[r] is the location of the first
+ *	nonzero in this segment.  It is also used during the dfs: repfnz[r]>0
+ *	indicates the supernode r has been explored.
+ *	NOTE: There are W of them, each used for one column of a panel.
+ *
+ *   panel_lsub[0:W*m-1]: temporary for the nonzeros row indices below
+ *	the panel diagonal. These are filled in during dpanel_dfs(), and are
+ *	used later in the inner LU factorization within the panel.
+ *	panel_lsub[]/dense[] pair forms the SPA data structure.
+ *	NOTE: There are W of them.
+ *
+ *   dense[0:W*m-1]: sparse accumulating (SPA) vector for intermediate values;
+ *		   NOTE: there are W of them.
+ *
+ *   tempv[0:*]: real temporary used for dense numeric kernels;
+ *	The size of this array is defined by NUM_TEMPV() in slu_util.h.
+ *	It is also used by the dropping routine ilu_ddrop_row().
+ * 
+ */ + +void +sgsitrf(superlu_options_t *options, SuperMatrix *A, int relax, int panel_size, + int *etree, void *work, int lwork, int *perm_c, int *perm_r, + SuperMatrix *L, SuperMatrix *U, + GlobalLU_t *Glu, /* persistent to facilitate multiple factorizations */ + SuperLUStat_t *stat, int *info) +{ + /* Local working arrays */ + NCPformat *Astore; + int *iperm_r = NULL; /* inverse of perm_r; used when + options->Fact == SamePattern_SameRowPerm */ + int *iperm_c; /* inverse of perm_c */ + int *swap, *iswap; /* swap is used to store the row permutation + during the factorization. Initially, it is set + to iperm_c (row indeces of Pc*A*Pc'). + iswap is the inverse of swap. After the + factorization, it is equal to perm_r. */ + int *iwork; + float *swork; + int *segrep, *repfnz, *parent, *xplore; + int *panel_lsub; /* dense[]/panel_lsub[] pair forms a w-wide SPA */ + int *marker, *marker_relax; + float *dense, *tempv; + int *relax_end, *relax_fsupc; + float *a; + int *asub; + int *xa_begin, *xa_end; + int *xsup, *supno; + int *xlsub, *xlusup, *xusub; + int nzlumax; + float *amax; + float drop_sum; + float alpha, omega; /* used in MILU, mimicing DRIC */ + float *swork2; /* used by the second dropping rule */ + + /* Local scalars */ + fact_t fact = options->Fact; + double diag_pivot_thresh = options->DiagPivotThresh; + double drop_tol = options->ILU_DropTol; /* tau */ + double fill_ini = options->ILU_FillTol; /* tau^hat */ + double gamma = options->ILU_FillFactor; + int drop_rule = options->ILU_DropRule; + milu_t milu = options->ILU_MILU; + double fill_tol; + int pivrow; /* pivotal row number in the original matrix A */ + int nseg1; /* no of segments in U-column above panel row jcol */ + int nseg; /* no of segments in each U-column */ + register int jcol; + register int kcol; /* end column of a relaxed snode */ + register int icol; + register int i, k, jj, new_next, iinfo; + int m, n, min_mn, jsupno, fsupc, nextlu, nextu; + int w_def; /* upper bound on panel width */ + int usepr, iperm_r_allocated = 0; + int nnzL, nnzU; + int *panel_histo = stat->panel_histo; + flops_t *ops = stat->ops; + + int last_drop;/* the last column which the dropping rules applied */ + int quota; + int nnzAj; /* number of nonzeros in A(:,1:j) */ + int nnzLj, nnzUj; + double tol_L = drop_tol, tol_U = drop_tol; + float zero = 0.0; + float one = 1.0; + + /* Executable */ + iinfo = 0; + m = A->nrow; + n = A->ncol; + min_mn = SUPERLU_MIN(m, n); + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + + /* Allocate storage common to the factor routines */ + *info = sLUMemInit(fact, work, lwork, m, n, Astore->nnz, panel_size, + gamma, L, U, Glu, &iwork, &swork); + if ( *info ) return; + + xsup = Glu->xsup; + supno = Glu->supno; + xlsub = Glu->xlsub; + xlusup = Glu->xlusup; + xusub = Glu->xusub; + + SetIWork(m, n, panel_size, iwork, &segrep, &parent, &xplore, + &repfnz, &panel_lsub, &marker_relax, &marker); + sSetRWork(m, panel_size, swork, &dense, &tempv); + + usepr = (fact == SamePattern_SameRowPerm); + if ( usepr ) { + /* Compute the inverse of perm_r */ + iperm_r = (int *) intMalloc(m); + for (k = 0; k < m; ++k) iperm_r[perm_r[k]] = k; + iperm_r_allocated = 1; + } + + iperm_c = (int *) intMalloc(n); + for (k = 0; k < n; ++k) iperm_c[perm_c[k]] = k; + swap = (int *)intMalloc(n); + for (k = 0; k < n; k++) swap[k] = iperm_c[k]; + iswap = (int *)intMalloc(n); + for (k = 0; k < n; k++) iswap[k] = perm_c[k]; + amax = (float *) floatMalloc(panel_size); + if (drop_rule & DROP_SECONDARY) + swork2 = (float *)floatMalloc(n); + else + swork2 = NULL; + + nnzAj = 0; + nnzLj = 0; + nnzUj = 0; + last_drop = SUPERLU_MAX(min_mn - 2 * sp_ienv(7), (int)(min_mn * 0.95)); + alpha = pow((double)n, -1.0 / options->ILU_MILU_Dim); + + /* Identify relaxed snodes */ + relax_end = (int *) intMalloc(n); + relax_fsupc = (int *) intMalloc(n); + if ( options->SymmetricMode == YES ) + ilu_heap_relax_snode(n, etree, relax, marker, relax_end, relax_fsupc); + else + ilu_relax_snode(n, etree, relax, marker, relax_end, relax_fsupc); + + ifill (perm_r, m, EMPTY); + ifill (marker, m * NO_MARKER, EMPTY); + supno[0] = -1; + xsup[0] = xlsub[0] = xusub[0] = xlusup[0] = 0; + w_def = panel_size; + + /* Mark the rows used by relaxed supernodes */ + ifill (marker_relax, m, EMPTY); + i = mark_relax(m, relax_end, relax_fsupc, xa_begin, xa_end, + asub, marker_relax); +#if ( PRNTlevel >= 1) + printf("%d relaxed supernodes.\n", i); +#endif + + /* + * Work on one "panel" at a time. A panel is one of the following: + * (a) a relaxed supernode at the bottom of the etree, or + * (b) panel_size contiguous columns, defined by the user + */ + for (jcol = 0; jcol < min_mn; ) { + + if ( relax_end[jcol] != EMPTY ) { /* start of a relaxed snode */ + kcol = relax_end[jcol]; /* end of the relaxed snode */ + panel_histo[kcol-jcol+1]++; + + /* Drop small rows in the previous supernode. */ + if (jcol > 0 && jcol < last_drop) { + int first = xsup[supno[jcol - 1]]; + int last = jcol - 1; + int quota; + + /* Compute the quota */ + if (drop_rule & DROP_PROWS) + quota = gamma * Astore->nnz / m * (m - first) / m + * (last - first + 1); + else if (drop_rule & DROP_COLUMN) { + int i; + quota = 0; + for (i = first; i <= last; i++) + quota += xa_end[i] - xa_begin[i]; + quota = gamma * quota * (m - first) / m; + } else if (drop_rule & DROP_AREA) + quota = gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) / m) + - nnzLj; + else + quota = m * n; + fill_tol = pow(fill_ini, 1.0 - 0.5 * (first + last) / min_mn); + + /* Drop small rows */ + i = ilu_sdrop_row(options, first, last, tol_L, quota, &nnzLj, + &fill_tol, Glu, tempv, swork2, 0); + /* Reset the parameters */ + if (drop_rule & DROP_DYNAMIC) { + if (gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) / m) + < nnzLj) + tol_L = SUPERLU_MIN(1.0, tol_L * 2.0); + else + tol_L = SUPERLU_MAX(drop_tol, tol_L * 0.5); + } + if (fill_tol < 0) iinfo -= (int)fill_tol; +#ifdef DEBUG + num_drop_L += i * (last - first + 1); +#endif + } + + /* -------------------------------------- + * Factorize the relaxed supernode(jcol:kcol) + * -------------------------------------- */ + /* Determine the union of the row structure of the snode */ + if ( (*info = ilu_ssnode_dfs(jcol, kcol, asub, xa_begin, xa_end, + marker, Glu)) != 0 ) + return; + + nextu = xusub[jcol]; + nextlu = xlusup[jcol]; + jsupno = supno[jcol]; + fsupc = xsup[jsupno]; + new_next = nextlu + (xlsub[fsupc+1]-xlsub[fsupc])*(kcol-jcol+1); + nzlumax = Glu->nzlumax; + while ( new_next > nzlumax ) { + if ((*info = sLUMemXpand(jcol, nextlu, LUSUP, &nzlumax, Glu))) + return; + } + + for (icol = jcol; icol <= kcol; icol++) { + xusub[icol+1] = nextu; + + amax[0] = 0.0; + /* Scatter into SPA dense[*] */ + for (k = xa_begin[icol]; k < xa_end[icol]; k++) { + register float tmp = fabs(a[k]); + if (tmp > amax[0]) amax[0] = tmp; + dense[asub[k]] = a[k]; + } + nnzAj += xa_end[icol] - xa_begin[icol]; + if (amax[0] == 0.0) { + amax[0] = fill_ini; +#if ( PRNTlevel >= 1) + printf("Column %d is entirely zero!\n", icol); + fflush(stdout); +#endif + } + + /* Numeric update within the snode */ + ssnode_bmod(icol, jsupno, fsupc, dense, tempv, Glu, stat); + + if (usepr) pivrow = iperm_r[icol]; + fill_tol = pow(fill_ini, 1.0 - (double)icol / (double)min_mn); + if ( (*info = ilu_spivotL(icol, diag_pivot_thresh, &usepr, + perm_r, iperm_c[icol], swap, iswap, + marker_relax, &pivrow, + amax[0] * fill_tol, milu, zero, + Glu, stat)) ) { + iinfo++; + marker[pivrow] = kcol; + } + + } + + jcol = kcol + 1; + + } else { /* Work on one panel of panel_size columns */ + + /* Adjust panel_size so that a panel won't overlap with the next + * relaxed snode. + */ + panel_size = w_def; + for (k = jcol + 1; k < SUPERLU_MIN(jcol+panel_size, min_mn); k++) + if ( relax_end[k] != EMPTY ) { + panel_size = k - jcol; + break; + } + if ( k == min_mn ) panel_size = min_mn - jcol; + panel_histo[panel_size]++; + + /* symbolic factor on a panel of columns */ + ilu_spanel_dfs(m, panel_size, jcol, A, perm_r, &nseg1, + dense, amax, panel_lsub, segrep, repfnz, + marker, parent, xplore, Glu); + + /* numeric sup-panel updates in topological order */ + spanel_bmod(m, panel_size, jcol, nseg1, dense, + tempv, segrep, repfnz, Glu, stat); + + /* Sparse LU within the panel, and below panel diagonal */ + for (jj = jcol; jj < jcol + panel_size; jj++) { + + k = (jj - jcol) * m; /* column index for w-wide arrays */ + + nseg = nseg1; /* Begin after all the panel segments */ + + nnzAj += xa_end[jj] - xa_begin[jj]; + + if ((*info = ilu_scolumn_dfs(m, jj, perm_r, &nseg, + &panel_lsub[k], segrep, &repfnz[k], + marker, parent, xplore, Glu))) + return; + + /* Numeric updates */ + if ((*info = scolumn_bmod(jj, (nseg - nseg1), &dense[k], + tempv, &segrep[nseg1], &repfnz[k], + jcol, Glu, stat)) != 0) return; + + /* Make a fill-in position if the column is entirely zero */ + if (xlsub[jj + 1] == xlsub[jj]) { + register int i, row; + int nextl; + int nzlmax = Glu->nzlmax; + int *lsub = Glu->lsub; + int *marker2 = marker + 2 * m; + + /* Allocate memory */ + nextl = xlsub[jj] + 1; + if (nextl >= nzlmax) { + int error = sLUMemXpand(jj, nextl, LSUB, &nzlmax, Glu); + if (error) { *info = error; return; } + lsub = Glu->lsub; + } + xlsub[jj + 1]++; + assert(xlusup[jj]==xlusup[jj+1]); + xlusup[jj + 1]++; + ((float *) Glu->lusup)[xlusup[jj]] = zero; + + /* Choose a row index (pivrow) for fill-in */ + for (i = jj; i < n; i++) + if (marker_relax[swap[i]] <= jj) break; + row = swap[i]; + marker2[row] = jj; + lsub[xlsub[jj]] = row; +#ifdef DEBUG + printf("Fill col %d.\n", jj); + fflush(stdout); +#endif + } + + /* Computer the quota */ + if (drop_rule & DROP_PROWS) + quota = gamma * Astore->nnz / m * jj / m; + else if (drop_rule & DROP_COLUMN) + quota = gamma * (xa_end[jj] - xa_begin[jj]) * + (jj + 1) / m; + else if (drop_rule & DROP_AREA) + quota = gamma * 0.9 * nnzAj * 0.5 - nnzUj; + else + quota = m; + + /* Copy the U-segments to ucol[*] and drop small entries */ + if ((*info = ilu_scopy_to_ucol(jj, nseg, segrep, &repfnz[k], + perm_r, &dense[k], drop_rule, + milu, amax[jj - jcol] * tol_U, + quota, &drop_sum, &nnzUj, Glu, + swork2)) != 0) + return; + + /* Reset the dropping threshold if required */ + if (drop_rule & DROP_DYNAMIC) { + if (gamma * 0.9 * nnzAj * 0.5 < nnzLj) + tol_U = SUPERLU_MIN(1.0, tol_U * 2.0); + else + tol_U = SUPERLU_MAX(drop_tol, tol_U * 0.5); + } + + if (drop_sum != zero) + { + if (drop_sum > zero) + omega = SUPERLU_MIN(2.0 * (1.0 - alpha) + * amax[jj - jcol] / drop_sum, one); + else + omega = SUPERLU_MAX(2.0 * (1.0 - alpha) + * amax[jj - jcol] / drop_sum, -one); + drop_sum *= omega; + } + if (usepr) pivrow = iperm_r[jj]; + fill_tol = pow(fill_ini, 1.0 - (double)jj / (double)min_mn); + if ( (*info = ilu_spivotL(jj, diag_pivot_thresh, &usepr, perm_r, + iperm_c[jj], swap, iswap, + marker_relax, &pivrow, + amax[jj - jcol] * fill_tol, milu, + drop_sum, Glu, stat)) ) { + iinfo++; + marker[m + pivrow] = jj; + marker[2 * m + pivrow] = jj; + } + + /* Reset repfnz[] for this column */ + resetrep_col (nseg, segrep, &repfnz[k]); + + /* Start a new supernode, drop the previous one */ + if (jj > 0 && supno[jj] > supno[jj - 1] && jj < last_drop) { + int first = xsup[supno[jj - 1]]; + int last = jj - 1; + int quota; + + /* Compute the quota */ + if (drop_rule & DROP_PROWS) + quota = gamma * Astore->nnz / m * (m - first) / m + * (last - first + 1); + else if (drop_rule & DROP_COLUMN) { + int i; + quota = 0; + for (i = first; i <= last; i++) + quota += xa_end[i] - xa_begin[i]; + quota = gamma * quota * (m - first) / m; + } else if (drop_rule & DROP_AREA) + quota = gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) + / m) - nnzLj; + else + quota = m * n; + fill_tol = pow(fill_ini, 1.0 - 0.5 * (first + last) / + (double)min_mn); + + /* Drop small rows */ + i = ilu_sdrop_row(options, first, last, tol_L, quota, + &nnzLj, &fill_tol, Glu, tempv, swork2, + 1); + + /* Reset the parameters */ + if (drop_rule & DROP_DYNAMIC) { + if (gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) / m) + < nnzLj) + tol_L = SUPERLU_MIN(1.0, tol_L * 2.0); + else + tol_L = SUPERLU_MAX(drop_tol, tol_L * 0.5); + } + if (fill_tol < 0) iinfo -= (int)fill_tol; +#ifdef DEBUG + num_drop_L += i * (last - first + 1); +#endif + } /* if start a new supernode */ + + } /* for */ + + jcol += panel_size; /* Move to the next panel */ + + } /* else */ + + } /* for */ + + *info = iinfo; + + if ( m > n ) { + k = 0; + for (i = 0; i < m; ++i) + if ( perm_r[i] == EMPTY ) { + perm_r[i] = n + k; + ++k; + } + } + + ilu_countnz(min_mn, &nnzL, &nnzU, Glu); + fixupL(min_mn, perm_r, Glu); + + sLUWorkFree(iwork, swork, Glu); /* Free work space and compress storage */ + + if ( fact == SamePattern_SameRowPerm ) { + /* L and U structures may have changed due to possibly different + pivoting, even though the storage is available. + There could also be memory expansions, so the array locations + may have changed, */ + ((SCformat *)L->Store)->nnz = nnzL; + ((SCformat *)L->Store)->nsuper = Glu->supno[n]; + ((SCformat *)L->Store)->nzval = (float *) Glu->lusup; + ((SCformat *)L->Store)->nzval_colptr = Glu->xlusup; + ((SCformat *)L->Store)->rowind = Glu->lsub; + ((SCformat *)L->Store)->rowind_colptr = Glu->xlsub; + ((NCformat *)U->Store)->nnz = nnzU; + ((NCformat *)U->Store)->nzval = (float *) Glu->ucol; + ((NCformat *)U->Store)->rowind = Glu->usub; + ((NCformat *)U->Store)->colptr = Glu->xusub; + } else { + sCreate_SuperNode_Matrix(L, A->nrow, min_mn, nnzL, + (float *) Glu->lusup, Glu->xlusup, + Glu->lsub, Glu->xlsub, Glu->supno, Glu->xsup, + SLU_SC, SLU_S, SLU_TRLU); + sCreate_CompCol_Matrix(U, min_mn, min_mn, nnzU, + (float *) Glu->ucol, Glu->usub, Glu->xusub, + SLU_NC, SLU_S, SLU_TRU); + } + + ops[FACT] += ops[TRSV] + ops[GEMV]; + stat->expansions = --(Glu->num_expansions); + + if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r); + SUPERLU_FREE (iperm_c); + SUPERLU_FREE (relax_end); + SUPERLU_FREE (swap); + SUPERLU_FREE (iswap); + SUPERLU_FREE (relax_fsupc); + SUPERLU_FREE (amax); + if ( swork2 ) SUPERLU_FREE (swork2); + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/sgsrfs.c b/src/Libraries/superlu-5.2.1/SRC/sgsrfs.c new file mode 100644 index 00000000..5faab1df --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sgsrfs.c @@ -0,0 +1,468 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sgsrfs.c + * \brief Improves computed solution to a system of inear equations + * + *
+ * -- SuperLU routine (version 5.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Modified from lapack routine SGERFS
+ * Last modified: December 3, 2015
+ * 
+ */ +/* + * File name: sgsrfs.c + * History: Modified from lapack routine SGERFS + */ +#include +#include "slu_sdefs.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   SGSRFS improves the computed solution to a system of linear   
+ *   equations and provides error bounds and backward error estimates for 
+ *   the solution.   
+ *
+ *   If equilibration was performed, the system becomes:
+ *           (diag(R)*A_original*diag(C)) * X = diag(R)*B_original.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ *   Arguments   
+ *   =========   
+ *
+ * trans   (input) trans_t
+ *          Specifies the form of the system of equations:
+ *          = NOTRANS: A * X = B  (No transpose)
+ *          = TRANS:   A'* X = B  (Transpose)
+ *          = CONJ:    A**H * X = B  (Conjugate transpose)
+ *   
+ *   A       (input) SuperMatrix*
+ *           The original matrix A in the system, or the scaled A if
+ *           equilibration was done. The type of A can be:
+ *           Stype = SLU_NC, Dtype = SLU_S, Mtype = SLU_GE.
+ *    
+ *   L       (input) SuperMatrix*
+ *	     The factor L from the factorization Pr*A*Pc=L*U. Use
+ *           compressed row subscripts storage for supernodes, 
+ *           i.e., L has types: Stype = SLU_SC, Dtype = SLU_S, Mtype = SLU_TRLU.
+ * 
+ *   U       (input) SuperMatrix*
+ *           The factor U from the factorization Pr*A*Pc=L*U as computed by
+ *           sgstrf(). Use column-wise storage scheme, 
+ *           i.e., U has types: Stype = SLU_NC, Dtype = SLU_S, Mtype = SLU_TRU.
+ *
+ *   perm_c  (input) int*, dimension (A->ncol)
+ *	     Column permutation vector, which defines the 
+ *           permutation matrix Pc; perm_c[i] = j means column i of A is 
+ *           in position j in A*Pc.
+ *
+ *   perm_r  (input) int*, dimension (A->nrow)
+ *           Row permutation vector, which defines the permutation matrix Pr;
+ *           perm_r[i] = j means row i of A is in position j in Pr*A.
+ *
+ *   equed   (input) Specifies the form of equilibration that was done.
+ *           = 'N': No equilibration.
+ *           = 'R': Row equilibration, i.e., A was premultiplied by diag(R).
+ *           = 'C': Column equilibration, i.e., A was postmultiplied by
+ *                  diag(C).
+ *           = 'B': Both row and column equilibration, i.e., A was replaced 
+ *                  by diag(R)*A*diag(C).
+ *
+ *   R       (input) float*, dimension (A->nrow)
+ *           The row scale factors for A.
+ *           If equed = 'R' or 'B', A is premultiplied by diag(R).
+ *           If equed = 'N' or 'C', R is not accessed.
+ * 
+ *   C       (input) float*, dimension (A->ncol)
+ *           The column scale factors for A.
+ *           If equed = 'C' or 'B', A is postmultiplied by diag(C).
+ *           If equed = 'N' or 'R', C is not accessed.
+ *
+ *   B       (input) SuperMatrix*
+ *           B has types: Stype = SLU_DN, Dtype = SLU_S, Mtype = SLU_GE.
+ *           The right hand side matrix B.
+ *           if equed = 'R' or 'B', B is premultiplied by diag(R).
+ *
+ *   X       (input/output) SuperMatrix*
+ *           X has types: Stype = SLU_DN, Dtype = SLU_S, Mtype = SLU_GE.
+ *           On entry, the solution matrix X, as computed by sgstrs().
+ *           On exit, the improved solution matrix X.
+ *           if *equed = 'C' or 'B', X should be premultiplied by diag(C)
+ *               in order to obtain the solution to the original system.
+ *
+ *   FERR    (output) float*, dimension (B->ncol)   
+ *           The estimated forward error bound for each solution vector   
+ *           X(j) (the j-th column of the solution matrix X).   
+ *           If XTRUE is the true solution corresponding to X(j), FERR(j) 
+ *           is an estimated upper bound for the magnitude of the largest 
+ *           element in (X(j) - XTRUE) divided by the magnitude of the   
+ *           largest element in X(j).  The estimate is as reliable as   
+ *           the estimate for RCOND, and is almost always a slight   
+ *           overestimate of the true error.
+ *
+ *   BERR    (output) float*, dimension (B->ncol)   
+ *           The componentwise relative backward error of each solution   
+ *           vector X(j) (i.e., the smallest relative change in   
+ *           any element of A or B that makes X(j) an exact solution).
+ *
+ *   stat     (output) SuperLUStat_t*
+ *            Record the statistics on runtime and floating-point operation count.
+ *            See util.h for the definition of 'SuperLUStat_t'.
+ *
+ *   info    (output) int*   
+ *           = 0:  successful exit   
+ *            < 0:  if INFO = -i, the i-th argument had an illegal value   
+ *
+ *    Internal Parameters   
+ *    ===================   
+ *
+ *    ITMAX is the maximum number of steps of iterative refinement.   
+ *
+ * 
+ */ +void +sgsrfs(trans_t trans, SuperMatrix *A, SuperMatrix *L, SuperMatrix *U, + int *perm_c, int *perm_r, char *equed, float *R, float *C, + SuperMatrix *B, SuperMatrix *X, float *ferr, float *berr, + SuperLUStat_t *stat, int *info) +{ + + +#define ITMAX 5 + + /* Table of constant values */ + int ione = 1; + float ndone = -1.; + float done = 1.; + + /* Local variables */ + NCformat *Astore; + float *Aval; + SuperMatrix Bjcol; + DNformat *Bstore, *Xstore, *Bjcol_store; + float *Bmat, *Xmat, *Bptr, *Xptr; + int kase; + float safe1, safe2; + int i, j, k, irow, nz, count, notran, rowequ, colequ; + int ldb, ldx, nrhs; + float s, xk, lstres, eps, safmin; + char transc[1]; + trans_t transt; + float *work; + float *rwork; + int *iwork; + int isave[3]; + + extern int slacon2_(int *, float *, float *, int *, float *, int *, int []); +#ifdef _CRAY + extern int SCOPY(int *, float *, int *, float *, int *); + extern int SSAXPY(int *, float *, float *, int *, float *, int *); +#else + extern int scopy_(int *, float *, int *, float *, int *); + extern int saxpy_(int *, float *, float *, int *, float *, int *); +#endif + + Astore = A->Store; + Aval = Astore->nzval; + Bstore = B->Store; + Xstore = X->Store; + Bmat = Bstore->nzval; + Xmat = Xstore->nzval; + ldb = Bstore->lda; + ldx = Xstore->lda; + nrhs = B->ncol; + + /* Test the input parameters */ + *info = 0; + notran = (trans == NOTRANS); + if ( !notran && trans != TRANS && trans != CONJ ) *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + A->Stype != SLU_NC || A->Dtype != SLU_S || A->Mtype != SLU_GE ) + *info = -2; + else if ( L->nrow != L->ncol || L->nrow < 0 || + L->Stype != SLU_SC || L->Dtype != SLU_S || L->Mtype != SLU_TRLU ) + *info = -3; + else if ( U->nrow != U->ncol || U->nrow < 0 || + U->Stype != SLU_NC || U->Dtype != SLU_S || U->Mtype != SLU_TRU ) + *info = -4; + else if ( ldb < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_S || B->Mtype != SLU_GE ) + *info = -10; + else if ( ldx < SUPERLU_MAX(0, A->nrow) || + X->Stype != SLU_DN || X->Dtype != SLU_S || X->Mtype != SLU_GE ) + *info = -11; + if (*info != 0) { + i = -(*info); + input_error("sgsrfs", &i); + return; + } + + /* Quick return if possible */ + if ( A->nrow == 0 || nrhs == 0) { + for (j = 0; j < nrhs; ++j) { + ferr[j] = 0.; + berr[j] = 0.; + } + return; + } + + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + + /* Allocate working space */ + work = floatMalloc(2*A->nrow); + rwork = (float *) SUPERLU_MALLOC( A->nrow * sizeof(float) ); + iwork = intMalloc(2*A->nrow); + if ( !work || !rwork || !iwork ) + ABORT("Malloc fails for work/rwork/iwork."); + + if ( notran ) { + *(unsigned char *)transc = 'N'; + transt = TRANS; + } else if ( trans == TRANS ) { + *(unsigned char *)transc = 'T'; + transt = NOTRANS; + } else if ( trans == CONJ ) { + *(unsigned char *)transc = 'C'; + transt = NOTRANS; + } + + /* NZ = maximum number of nonzero elements in each row of A, plus 1 */ + nz = A->ncol + 1; + eps = smach("Epsilon"); + safmin = smach("Safe minimum"); + + /* Set SAFE1 essentially to be the underflow threshold times the + number of additions in each row. */ + safe1 = nz * safmin; + safe2 = safe1 / eps; + + /* Compute the number of nonzeros in each row (or column) of A */ + for (i = 0; i < A->nrow; ++i) iwork[i] = 0; + if ( notran ) { + for (k = 0; k < A->ncol; ++k) + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) + ++iwork[Astore->rowind[i]]; + } else { + for (k = 0; k < A->ncol; ++k) + iwork[k] = Astore->colptr[k+1] - Astore->colptr[k]; + } + + /* Copy one column of RHS B into Bjcol. */ + Bjcol.Stype = B->Stype; + Bjcol.Dtype = B->Dtype; + Bjcol.Mtype = B->Mtype; + Bjcol.nrow = B->nrow; + Bjcol.ncol = 1; + Bjcol.Store = (void *) SUPERLU_MALLOC( sizeof(DNformat) ); + if ( !Bjcol.Store ) ABORT("SUPERLU_MALLOC fails for Bjcol.Store"); + Bjcol_store = Bjcol.Store; + Bjcol_store->lda = ldb; + Bjcol_store->nzval = work; /* address aliasing */ + + /* Do for each right hand side ... */ + for (j = 0; j < nrhs; ++j) { + count = 0; + lstres = 3.; + Bptr = &Bmat[j*ldb]; + Xptr = &Xmat[j*ldx]; + + while (1) { /* Loop until stopping criterion is satisfied. */ + + /* Compute residual R = B - op(A) * X, + where op(A) = A, A**T, or A**H, depending on TRANS. */ + +#ifdef _CRAY + SCOPY(&A->nrow, Bptr, &ione, work, &ione); +#else + scopy_(&A->nrow, Bptr, &ione, work, &ione); +#endif + sp_sgemv(transc, ndone, A, Xptr, ione, done, work, ione); + + /* Compute componentwise relative backward error from formula + max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) ) + where abs(Z) is the componentwise absolute value of the matrix + or vector Z. If the i-th component of the denominator is less + than SAFE2, then SAFE1 is added to the i-th component of the + numerator before dividing. */ + + for (i = 0; i < A->nrow; ++i) rwork[i] = fabs( Bptr[i] ); + + /* Compute abs(op(A))*abs(X) + abs(B). */ + if ( notran ) { + for (k = 0; k < A->ncol; ++k) { + xk = fabs( Xptr[k] ); + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) + rwork[Astore->rowind[i]] += fabs(Aval[i]) * xk; + } + } else { /* trans = TRANS or CONJ */ + for (k = 0; k < A->ncol; ++k) { + s = 0.; + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) { + irow = Astore->rowind[i]; + s += fabs(Aval[i]) * fabs(Xptr[irow]); + } + rwork[k] += s; + } + } + s = 0.; + for (i = 0; i < A->nrow; ++i) { + if (rwork[i] > safe2) { + s = SUPERLU_MAX( s, fabs(work[i]) / rwork[i] ); + } else if ( rwork[i] != 0.0 ) { + /* Adding SAFE1 to the numerator guards against + spuriously zero residuals (underflow). */ + s = SUPERLU_MAX( s, (safe1 + fabs(work[i])) / rwork[i] ); + } + /* If rwork[i] is exactly 0.0, then we know the true + residual also must be exactly 0.0. */ + } + berr[j] = s; + + /* Test stopping criterion. Continue iterating if + 1) The residual BERR(J) is larger than machine epsilon, and + 2) BERR(J) decreased by at least a factor of 2 during the + last iteration, and + 3) At most ITMAX iterations tried. */ + + if (berr[j] > eps && berr[j] * 2. <= lstres && count < ITMAX) { + /* Update solution and try again. */ + sgstrs (trans, L, U, perm_c, perm_r, &Bjcol, stat, info); + +#ifdef _CRAY + SAXPY(&A->nrow, &done, work, &ione, + &Xmat[j*ldx], &ione); +#else + saxpy_(&A->nrow, &done, work, &ione, + &Xmat[j*ldx], &ione); +#endif + lstres = berr[j]; + ++count; + } else { + break; + } + + } /* end while */ + + stat->RefineSteps = count; + + /* Bound error from formula: + norm(X - XTRUE) / norm(X) .le. FERR = norm( abs(inv(op(A)))* + ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X) + where + norm(Z) is the magnitude of the largest component of Z + inv(op(A)) is the inverse of op(A) + abs(Z) is the componentwise absolute value of the matrix or + vector Z + NZ is the maximum number of nonzeros in any row of A, plus 1 + EPS is machine epsilon + + The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B)) + is incremented by SAFE1 if the i-th component of + abs(op(A))*abs(X) + abs(B) is less than SAFE2. + + Use SLACON2 to estimate the infinity-norm of the matrix + inv(op(A)) * diag(W), + where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) */ + + for (i = 0; i < A->nrow; ++i) rwork[i] = fabs( Bptr[i] ); + + /* Compute abs(op(A))*abs(X) + abs(B). */ + if ( notran ) { + for (k = 0; k < A->ncol; ++k) { + xk = fabs( Xptr[k] ); + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) + rwork[Astore->rowind[i]] += fabs(Aval[i]) * xk; + } + } else { /* trans == TRANS or CONJ */ + for (k = 0; k < A->ncol; ++k) { + s = 0.; + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) { + irow = Astore->rowind[i]; + xk = fabs( Xptr[irow] ); + s += fabs(Aval[i]) * xk; + } + rwork[k] += s; + } + } + + for (i = 0; i < A->nrow; ++i) + if (rwork[i] > safe2) + rwork[i] = fabs(work[i]) + (iwork[i]+1)*eps*rwork[i]; + else + rwork[i] = fabs(work[i])+(iwork[i]+1)*eps*rwork[i]+safe1; + + kase = 0; + + do { + slacon2_(&A->nrow, &work[A->nrow], work, + &iwork[A->nrow], &ferr[j], &kase, isave); + if (kase == 0) break; + + if (kase == 1) { + /* Multiply by diag(W)*inv(op(A)**T)*(diag(C) or diag(R)). */ + if ( notran && colequ ) + for (i = 0; i < A->ncol; ++i) work[i] *= C[i]; + else if ( !notran && rowequ ) + for (i = 0; i < A->nrow; ++i) work[i] *= R[i]; + + sgstrs (transt, L, U, perm_c, perm_r, &Bjcol, stat, info); + + for (i = 0; i < A->nrow; ++i) work[i] *= rwork[i]; + } else { + /* Multiply by (diag(C) or diag(R))*inv(op(A))*diag(W). */ + for (i = 0; i < A->nrow; ++i) work[i] *= rwork[i]; + + sgstrs (trans, L, U, perm_c, perm_r, &Bjcol, stat, info); + + if ( notran && colequ ) + for (i = 0; i < A->ncol; ++i) work[i] *= C[i]; + else if ( !notran && rowequ ) + for (i = 0; i < A->ncol; ++i) work[i] *= R[i]; + } + + } while ( kase != 0 ); + + + /* Normalize error. */ + lstres = 0.; + if ( notran && colequ ) { + for (i = 0; i < A->nrow; ++i) + lstres = SUPERLU_MAX( lstres, C[i] * fabs( Xptr[i]) ); + } else if ( !notran && rowequ ) { + for (i = 0; i < A->nrow; ++i) + lstres = SUPERLU_MAX( lstres, R[i] * fabs( Xptr[i]) ); + } else { + for (i = 0; i < A->nrow; ++i) + lstres = SUPERLU_MAX( lstres, fabs( Xptr[i]) ); + } + if ( lstres != 0. ) + ferr[j] /= lstres; + + } /* for each RHS j ... */ + + SUPERLU_FREE(work); + SUPERLU_FREE(rwork); + SUPERLU_FREE(iwork); + SUPERLU_FREE(Bjcol.Store); + + return; + +} /* sgsrfs */ diff --git a/src/Libraries/superlu-5.2.1/SRC/sgssv.c b/src/Libraries/superlu-5.2.1/SRC/sgssv.c new file mode 100644 index 00000000..9dd7096f --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sgssv.c @@ -0,0 +1,238 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sgssv.c + * \brief Solves the system of linear equations A*X=B + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ * 
+ */ +#include "slu_sdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * SGSSV solves the system of linear equations A*X=B, using the
+ * LU factorization from SGSTRF. It performs the following steps:
+ *
+ *   1. If A is stored column-wise (A->Stype = SLU_NC):
+ *
+ *      1.1. Permute the columns of A, forming A*Pc, where Pc
+ *           is a permutation matrix. For more details of this step, 
+ *           see sp_preorder.c.
+ *
+ *      1.2. Factor A as Pr*A*Pc=L*U with the permutation Pr determined
+ *           by Gaussian elimination with partial pivoting.
+ *           L is unit lower triangular with offdiagonal entries
+ *           bounded by 1 in magnitude, and U is upper triangular.
+ *
+ *      1.3. Solve the system of equations A*X=B using the factored
+ *           form of A.
+ *
+ *   2. If A is stored row-wise (A->Stype = SLU_NR), apply the
+ *      above algorithm to the transpose of A:
+ *
+ *      2.1. Permute columns of transpose(A) (rows of A),
+ *           forming transpose(A)*Pc, where Pc is a permutation matrix. 
+ *           For more details of this step, see sp_preorder.c.
+ *
+ *      2.2. Factor A as Pr*transpose(A)*Pc=L*U with the permutation Pr
+ *           determined by Gaussian elimination with partial pivoting.
+ *           L is unit lower triangular with offdiagonal entries
+ *           bounded by 1 in magnitude, and U is upper triangular.
+ *
+ *      2.3. Solve the system of equations A*X=B using the factored
+ *           form of A.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ * 
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *         The structure defines the input parameters to control
+ *         how the LU decomposition will be performed and how the
+ *         system will be solved.
+ *
+ * A       (input) SuperMatrix*
+ *         Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
+ *         of linear equations is A->nrow. Currently, the type of A can be:
+ *         Stype = SLU_NC or SLU_NR; Dtype = SLU_S; Mtype = SLU_GE.
+ *         In the future, more general A may be handled.
+ *
+ * perm_c  (input/output) int*
+ *         If A->Stype = SLU_NC, column permutation vector of size A->ncol
+ *         which defines the permutation matrix Pc; perm_c[i] = j means 
+ *         column i of A is in position j in A*Pc.
+ *         If A->Stype = SLU_NR, column permutation vector of size A->nrow
+ *         which describes permutation of columns of transpose(A) 
+ *         (rows of A) as described above.
+ * 
+ *         If options->ColPerm = MY_PERMC or options->Fact = SamePattern or
+ *            options->Fact = SamePattern_SameRowPerm, it is an input argument.
+ *            On exit, perm_c may be overwritten by the product of the input
+ *            perm_c and a permutation that postorders the elimination tree
+ *            of Pc'*A'*A*Pc; perm_c is not changed if the elimination tree
+ *            is already in postorder.
+ *         Otherwise, it is an output argument.
+ * 
+ * perm_r  (input/output) int*
+ *         If A->Stype = SLU_NC, row permutation vector of size A->nrow, 
+ *         which defines the permutation matrix Pr, and is determined 
+ *         by partial pivoting.  perm_r[i] = j means row i of A is in 
+ *         position j in Pr*A.
+ *         If A->Stype = SLU_NR, permutation vector of size A->ncol, which
+ *         determines permutation of rows of transpose(A)
+ *         (columns of A) as described above.
+ *
+ *         If options->RowPerm = MY_PERMR or
+ *            options->Fact = SamePattern_SameRowPerm, perm_r is an
+ *            input argument.
+ *         otherwise it is an output argument.
+ *
+ * L       (output) SuperMatrix*
+ *         The factor L from the factorization 
+ *             Pr*A*Pc=L*U              (if A->Stype = SLU_NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses compressed row subscripts storage for supernodes, i.e.,
+ *         L has types: Stype = SLU_SC, Dtype = SLU_S, Mtype = SLU_TRLU.
+ *         
+ * U       (output) SuperMatrix*
+ *	   The factor U from the factorization 
+ *             Pr*A*Pc=L*U              (if A->Stype = SLU_NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses column-wise storage scheme, i.e., U has types:
+ *         Stype = SLU_NC, Dtype = SLU_S, Mtype = SLU_TRU.
+ *
+ * B       (input/output) SuperMatrix*
+ *         B has types: Stype = SLU_DN, Dtype = SLU_S, Mtype = SLU_GE.
+ *         On entry, the right hand side matrix.
+ *         On exit, the solution matrix if info = 0;
+ *
+ * stat   (output) SuperLUStat_t*
+ *        Record the statistics on runtime and floating-point operation count.
+ *        See util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ *	   = 0: successful exit
+ *         > 0: if info = i, and i is
+ *             <= A->ncol: U(i,i) is exactly zero. The factorization has
+ *                been completed, but the factor U is exactly singular,
+ *                so the solution could not be computed.
+ *             > A->ncol: number of bytes allocated when memory allocation
+ *                failure occurred, plus A->ncol.
+ * 
+ */ + +void +sgssv(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, + SuperMatrix *L, SuperMatrix *U, SuperMatrix *B, + SuperLUStat_t *stat, int *info ) +{ + + DNformat *Bstore; + SuperMatrix *AA;/* A in SLU_NC format used by the factorization routine.*/ + SuperMatrix AC; /* Matrix postmultiplied by Pc */ + int lwork = 0, *etree, i; + GlobalLU_t Glu; /* Not needed on return. */ + + /* Set default values for some parameters */ + int panel_size; /* panel size */ + int relax; /* no of columns in a relaxed snodes */ + int permc_spec; + trans_t trans = NOTRANS; + double *utime; + double t; /* Temporary time */ + + /* Test the input parameters ... */ + *info = 0; + Bstore = B->Store; + if ( options->Fact != DOFACT ) *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + (A->Stype != SLU_NC && A->Stype != SLU_NR) || + A->Dtype != SLU_S || A->Mtype != SLU_GE ) + *info = -2; + else if ( B->ncol < 0 || Bstore->lda < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_S || B->Mtype != SLU_GE ) + *info = -7; + if ( *info != 0 ) { + i = -(*info); + input_error("sgssv", &i); + return; + } + + utime = stat->utime; + + /* Convert A to SLU_NC format when necessary. */ + if ( A->Stype == SLU_NR ) { + NRformat *Astore = A->Store; + AA = (SuperMatrix *) SUPERLU_MALLOC( sizeof(SuperMatrix) ); + sCreate_CompCol_Matrix(AA, A->ncol, A->nrow, Astore->nnz, + Astore->nzval, Astore->colind, Astore->rowptr, + SLU_NC, A->Dtype, A->Mtype); + trans = TRANS; + } else { + if ( A->Stype == SLU_NC ) AA = A; + } + + t = SuperLU_timer_(); + /* + * Get column permutation vector perm_c[], according to permc_spec: + * permc_spec = NATURAL: natural ordering + * permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A + * permc_spec = MMD_ATA: minimum degree on structure of A'*A + * permc_spec = COLAMD: approximate minimum degree column ordering + * permc_spec = MY_PERMC: the ordering already supplied in perm_c[] + */ + permc_spec = options->ColPerm; + if ( permc_spec != MY_PERMC && options->Fact == DOFACT ) + get_perm_c(permc_spec, AA, perm_c); + utime[COLPERM] = SuperLU_timer_() - t; + + etree = intMalloc(A->ncol); + + t = SuperLU_timer_(); + sp_preorder(options, AA, perm_c, etree, &AC); + utime[ETREE] = SuperLU_timer_() - t; + + panel_size = sp_ienv(1); + relax = sp_ienv(2); + + /*printf("Factor PA = LU ... relax %d\tw %d\tmaxsuper %d\trowblk %d\n", + relax, panel_size, sp_ienv(3), sp_ienv(4));*/ + t = SuperLU_timer_(); + /* Compute the LU factorization of A. */ + sgstrf(options, &AC, relax, panel_size, etree, + NULL, lwork, perm_c, perm_r, L, U, &Glu, stat, info); + utime[FACT] = SuperLU_timer_() - t; + + t = SuperLU_timer_(); + if ( *info == 0 ) { + /* Solve the system A*X=B, overwriting B with X. */ + sgstrs (trans, L, U, perm_c, perm_r, B, stat, info); + } + utime[SOLVE] = SuperLU_timer_() - t; + + SUPERLU_FREE (etree); + Destroy_CompCol_Permuted(&AC); + if ( A->Stype == SLU_NR ) { + Destroy_SuperMatrix_Store(AA); + SUPERLU_FREE(AA); + } + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/sgssvx.c b/src/Libraries/superlu-5.2.1/SRC/sgssvx.c new file mode 100644 index 00000000..c7aa79b3 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sgssvx.c @@ -0,0 +1,646 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sgssvx.c + * \brief Solves the system of linear equations A*X=B or A'*X=B + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ * 
+ */ +#include "slu_sdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * SGSSVX solves the system of linear equations A*X=B or A'*X=B, using
+ * the LU factorization from sgstrf(). Error bounds on the solution and
+ * a condition estimate are also provided. It performs the following steps:
+ *
+ *   1. If A is stored column-wise (A->Stype = SLU_NC):
+ *  
+ *      1.1. If options->Equil = YES, scaling factors are computed to
+ *           equilibrate the system:
+ *           options->Trans = NOTRANS:
+ *               diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *           options->Trans = TRANS:
+ *               (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *           options->Trans = CONJ:
+ *               (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *           Whether or not the system will be equilibrated depends on the
+ *           scaling of the matrix A, but if equilibration is used, A is
+ *           overwritten by diag(R)*A*diag(C) and B by diag(R)*B
+ *           (if options->Trans=NOTRANS) or diag(C)*B (if options->Trans
+ *           = TRANS or CONJ).
+ *
+ *      1.2. Permute columns of A, forming A*Pc, where Pc is a permutation
+ *           matrix that usually preserves sparsity.
+ *           For more details of this step, see sp_preorder.c.
+ *
+ *      1.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *           factor the matrix A (after equilibration if options->Equil = YES)
+ *           as Pr*A*Pc = L*U, with Pr determined by partial pivoting.
+ *
+ *      1.4. Compute the reciprocal pivot growth factor.
+ *
+ *      1.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *           routine returns with info = i. Otherwise, the factored form of 
+ *           A is used to estimate the condition number of the matrix A. If
+ *           the reciprocal of the condition number is less than machine
+ *           precision, info = A->ncol+1 is returned as a warning, but the
+ *           routine still goes on to solve for X and computes error bounds
+ *           as described below.
+ *
+ *      1.6. The system of equations is solved for X using the factored form
+ *           of A.
+ *
+ *      1.7. If options->IterRefine != NOREFINE, iterative refinement is
+ *           applied to improve the computed solution matrix and calculate
+ *           error bounds and backward error estimates for it.
+ *
+ *      1.8. If equilibration was used, the matrix X is premultiplied by
+ *           diag(C) (if options->Trans = NOTRANS) or diag(R)
+ *           (if options->Trans = TRANS or CONJ) so that it solves the
+ *           original system before equilibration.
+ *
+ *   2. If A is stored row-wise (A->Stype = SLU_NR), apply the above algorithm
+ *      to the transpose of A:
+ *
+ *      2.1. If options->Equil = YES, scaling factors are computed to
+ *           equilibrate the system:
+ *           options->Trans = NOTRANS:
+ *               diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *           options->Trans = TRANS:
+ *               (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *           options->Trans = CONJ:
+ *               (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *           Whether or not the system will be equilibrated depends on the
+ *           scaling of the matrix A, but if equilibration is used, A' is
+ *           overwritten by diag(R)*A'*diag(C) and B by diag(R)*B 
+ *           (if trans='N') or diag(C)*B (if trans = 'T' or 'C').
+ *
+ *      2.2. Permute columns of transpose(A) (rows of A), 
+ *           forming transpose(A)*Pc, where Pc is a permutation matrix that 
+ *           usually preserves sparsity.
+ *           For more details of this step, see sp_preorder.c.
+ *
+ *      2.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *           factor the transpose(A) (after equilibration if 
+ *           options->Fact = YES) as Pr*transpose(A)*Pc = L*U with the
+ *           permutation Pr determined by partial pivoting.
+ *
+ *      2.4. Compute the reciprocal pivot growth factor.
+ *
+ *      2.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *           routine returns with info = i. Otherwise, the factored form 
+ *           of transpose(A) is used to estimate the condition number of the
+ *           matrix A. If the reciprocal of the condition number
+ *           is less than machine precision, info = A->nrow+1 is returned as
+ *           a warning, but the routine still goes on to solve for X and
+ *           computes error bounds as described below.
+ *
+ *      2.6. The system of equations is solved for X using the factored form
+ *           of transpose(A).
+ *
+ *      2.7. If options->IterRefine != NOREFINE, iterative refinement is
+ *           applied to improve the computed solution matrix and calculate
+ *           error bounds and backward error estimates for it.
+ *
+ *      2.8. If equilibration was used, the matrix X is premultiplied by
+ *           diag(C) (if options->Trans = NOTRANS) or diag(R) 
+ *           (if options->Trans = TRANS or CONJ) so that it solves the
+ *           original system before equilibration.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *         The structure defines the input parameters to control
+ *         how the LU decomposition will be performed and how the
+ *         system will be solved.
+ *
+ * A       (input/output) SuperMatrix*
+ *         Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
+ *         of the linear equations is A->nrow. Currently, the type of A can be:
+ *         Stype = SLU_NC or SLU_NR, Dtype = SLU_D, Mtype = SLU_GE.
+ *         In the future, more general A may be handled.
+ *
+ *         On entry, If options->Fact = FACTORED and equed is not 'N', 
+ *         then A must have been equilibrated by the scaling factors in
+ *         R and/or C.  
+ *         On exit, A is not modified if options->Equil = NO, or if 
+ *         options->Equil = YES but equed = 'N' on exit.
+ *         Otherwise, if options->Equil = YES and equed is not 'N',
+ *         A is scaled as follows:
+ *         If A->Stype = SLU_NC:
+ *           equed = 'R':  A := diag(R) * A
+ *           equed = 'C':  A := A * diag(C)
+ *           equed = 'B':  A := diag(R) * A * diag(C).
+ *         If A->Stype = SLU_NR:
+ *           equed = 'R':  transpose(A) := diag(R) * transpose(A)
+ *           equed = 'C':  transpose(A) := transpose(A) * diag(C)
+ *           equed = 'B':  transpose(A) := diag(R) * transpose(A) * diag(C).
+ *
+ * perm_c  (input/output) int*
+ *	   If A->Stype = SLU_NC, Column permutation vector of size A->ncol,
+ *         which defines the permutation matrix Pc; perm_c[i] = j means
+ *         column i of A is in position j in A*Pc.
+ *         On exit, perm_c may be overwritten by the product of the input
+ *         perm_c and a permutation that postorders the elimination tree
+ *         of Pc'*A'*A*Pc; perm_c is not changed if the elimination tree
+ *         is already in postorder.
+ *
+ *         If A->Stype = SLU_NR, column permutation vector of size A->nrow,
+ *         which describes permutation of columns of transpose(A) 
+ *         (rows of A) as described above.
+ * 
+ * perm_r  (input/output) int*
+ *         If A->Stype = SLU_NC, row permutation vector of size A->nrow, 
+ *         which defines the permutation matrix Pr, and is determined
+ *         by partial pivoting.  perm_r[i] = j means row i of A is in 
+ *         position j in Pr*A.
+ *
+ *         If A->Stype = SLU_NR, permutation vector of size A->ncol, which
+ *         determines permutation of rows of transpose(A)
+ *         (columns of A) as described above.
+ *
+ *         If options->Fact = SamePattern_SameRowPerm, the pivoting routine
+ *         will try to use the input perm_r, unless a certain threshold
+ *         criterion is violated. In that case, perm_r is overwritten by a
+ *         new permutation determined by partial pivoting or diagonal
+ *         threshold pivoting.
+ *         Otherwise, perm_r is output argument.
+ * 
+ * etree   (input/output) int*,  dimension (A->ncol)
+ *         Elimination tree of Pc'*A'*A*Pc.
+ *         If options->Fact != FACTORED and options->Fact != DOFACT,
+ *         etree is an input argument, otherwise it is an output argument.
+ *         Note: etree is a vector of parent pointers for a forest whose
+ *         vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *
+ * equed   (input/output) char*
+ *         Specifies the form of equilibration that was done.
+ *         = 'N': No equilibration.
+ *         = 'R': Row equilibration, i.e., A was premultiplied by diag(R).
+ *         = 'C': Column equilibration, i.e., A was postmultiplied by diag(C).
+ *         = 'B': Both row and column equilibration, i.e., A was replaced 
+ *                by diag(R)*A*diag(C).
+ *         If options->Fact = FACTORED, equed is an input argument,
+ *         otherwise it is an output argument.
+ *
+ * R       (input/output) float*, dimension (A->nrow)
+ *         The row scale factors for A or transpose(A).
+ *         If equed = 'R' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *             (if A->Stype = SLU_NR) is multiplied on the left by diag(R).
+ *         If equed = 'N' or 'C', R is not accessed.
+ *         If options->Fact = FACTORED, R is an input argument,
+ *             otherwise, R is output.
+ *         If options->zFact = FACTORED and equed = 'R' or 'B', each element
+ *             of R must be positive.
+ * 
+ * C       (input/output) float*, dimension (A->ncol)
+ *         The column scale factors for A or transpose(A).
+ *         If equed = 'C' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *             (if A->Stype = SLU_NR) is multiplied on the right by diag(C).
+ *         If equed = 'N' or 'R', C is not accessed.
+ *         If options->Fact = FACTORED, C is an input argument,
+ *             otherwise, C is output.
+ *         If options->Fact = FACTORED and equed = 'C' or 'B', each element
+ *             of C must be positive.
+ *         
+ * L       (output) SuperMatrix*
+ *	   The factor L from the factorization
+ *             Pr*A*Pc=L*U              (if A->Stype SLU_= NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses compressed row subscripts storage for supernodes, i.e.,
+ *         L has types: Stype = SLU_SC, Dtype = SLU_S, Mtype = SLU_TRLU.
+ *
+ * U       (output) SuperMatrix*
+ *	   The factor U from the factorization
+ *             Pr*A*Pc=L*U              (if A->Stype = SLU_NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses column-wise storage scheme, i.e., U has types:
+ *         Stype = SLU_NC, Dtype = SLU_S, Mtype = SLU_TRU.
+ *
+ * work    (workspace/output) void*, size (lwork) (in bytes)
+ *         User supplied workspace, should be large enough
+ *         to hold data structures for factors L and U.
+ *         On exit, if fact is not 'F', L and U point to this array.
+ *
+ * lwork   (input) int
+ *         Specifies the size of work array in bytes.
+ *         = 0:  allocate space internally by system malloc;
+ *         > 0:  use user-supplied work array of length lwork in bytes,
+ *               returns error if space runs out.
+ *         = -1: the routine guesses the amount of space needed without
+ *               performing the factorization, and returns it in
+ *               mem_usage->total_needed; no other side effects.
+ *
+ *         See argument 'mem_usage' for memory usage statistics.
+ *
+ * B       (input/output) SuperMatrix*
+ *         B has types: Stype = SLU_DN, Dtype = SLU_S, Mtype = SLU_GE.
+ *         On entry, the right hand side matrix.
+ *         If B->ncol = 0, only LU decomposition is performed, the triangular
+ *                         solve is skipped.
+ *         On exit,
+ *            if equed = 'N', B is not modified; otherwise
+ *            if A->Stype = SLU_NC:
+ *               if options->Trans = NOTRANS and equed = 'R' or 'B',
+ *                  B is overwritten by diag(R)*B;
+ *               if options->Trans = TRANS or CONJ and equed = 'C' of 'B',
+ *                  B is overwritten by diag(C)*B;
+ *            if A->Stype = SLU_NR:
+ *               if options->Trans = NOTRANS and equed = 'C' or 'B',
+ *                  B is overwritten by diag(C)*B;
+ *               if options->Trans = TRANS or CONJ and equed = 'R' of 'B',
+ *                  B is overwritten by diag(R)*B.
+ *
+ * X       (output) SuperMatrix*
+ *         X has types: Stype = SLU_DN, Dtype = SLU_S, Mtype = SLU_GE. 
+ *         If info = 0 or info = A->ncol+1, X contains the solution matrix
+ *         to the original system of equations. Note that A and B are modified
+ *         on exit if equed is not 'N', and the solution to the equilibrated
+ *         system is inv(diag(C))*X if options->Trans = NOTRANS and
+ *         equed = 'C' or 'B', or inv(diag(R))*X if options->Trans = 'T' or 'C'
+ *         and equed = 'R' or 'B'.
+ *
+ * recip_pivot_growth (output) float*
+ *         The reciprocal pivot growth factor max_j( norm(A_j)/norm(U_j) ).
+ *         The infinity norm is used. If recip_pivot_growth is much less
+ *         than 1, the stability of the LU factorization could be poor.
+ *
+ * rcond   (output) float*
+ *         The estimate of the reciprocal condition number of the matrix A
+ *         after equilibration (if done). If rcond is less than the machine
+ *         precision (in particular, if rcond = 0), the matrix is singular
+ *         to working precision. This condition is indicated by a return
+ *         code of info > 0.
+ *
+ * FERR    (output) float*, dimension (B->ncol)   
+ *         The estimated forward error bound for each solution vector   
+ *         X(j) (the j-th column of the solution matrix X).   
+ *         If XTRUE is the true solution corresponding to X(j), FERR(j) 
+ *         is an estimated upper bound for the magnitude of the largest 
+ *         element in (X(j) - XTRUE) divided by the magnitude of the   
+ *         largest element in X(j).  The estimate is as reliable as   
+ *         the estimate for RCOND, and is almost always a slight   
+ *         overestimate of the true error.
+ *         If options->IterRefine = NOREFINE, ferr = 1.0.
+ *
+ * BERR    (output) float*, dimension (B->ncol)
+ *         The componentwise relative backward error of each solution   
+ *         vector X(j) (i.e., the smallest relative change in   
+ *         any element of A or B that makes X(j) an exact solution).
+ *         If options->IterRefine = NOREFINE, berr = 1.0.
+ *
+ * Glu      (input/output) GlobalLU_t *
+ *          If options->Fact == SamePattern_SameRowPerm, it is an input;
+ *              The matrix A will be factorized assuming that a 
+ *              factorization of a matrix with the same sparsity pattern
+ *              and similar numerical values was performed prior to this one.
+ *              Therefore, this factorization will reuse both row and column
+ *		scaling factors R and C, both row and column permutation
+ *		vectors perm_r and perm_c, and the L & U data structures
+ *		set up from the previous factorization.
+ *          Otherwise, it is an output.
+ *
+ * mem_usage (output) mem_usage_t*
+ *         Record the memory usage statistics, consisting of following fields:
+ *         - for_lu (float)
+ *           The amount of space used in bytes for L\U data structures.
+ *         - total_needed (float)
+ *           The amount of space needed in bytes to perform factorization.
+ *         - expansions (int)
+ *           The number of memory expansions during the LU factorization.
+ *
+ * stat   (output) SuperLUStat_t*
+ *        Record the statistics on runtime and floating-point operation count.
+ *        See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ *         = 0: successful exit   
+ *         < 0: if info = -i, the i-th argument had an illegal value   
+ *         > 0: if info = i, and i is   
+ *              <= A->ncol: U(i,i) is exactly zero. The factorization has   
+ *                    been completed, but the factor U is exactly   
+ *                    singular, so the solution and error bounds   
+ *                    could not be computed.   
+ *              = A->ncol+1: U is nonsingular, but RCOND is less than machine
+ *                    precision, meaning that the matrix is singular to
+ *                    working precision. Nevertheless, the solution and
+ *                    error bounds are computed because there are a number
+ *                    of situations where the computed solution can be more
+ *                    accurate than the value of RCOND would suggest.   
+ *              > A->ncol+1: number of bytes allocated when memory allocation
+ *                    failure occurred, plus A->ncol.
+ * 
+ */ + +void +sgssvx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, + int *etree, char *equed, float *R, float *C, + SuperMatrix *L, SuperMatrix *U, void *work, int lwork, + SuperMatrix *B, SuperMatrix *X, float *recip_pivot_growth, + float *rcond, float *ferr, float *berr, + GlobalLU_t *Glu, mem_usage_t *mem_usage, SuperLUStat_t *stat, int *info ) +{ + + + DNformat *Bstore, *Xstore; + float *Bmat, *Xmat; + int ldb, ldx, nrhs; + SuperMatrix *AA;/* A in SLU_NC format used by the factorization routine.*/ + SuperMatrix AC; /* Matrix postmultiplied by Pc */ + int colequ, equil, nofact, notran, rowequ, permc_spec; + trans_t trant; + char norm[1]; + int i, j, info1; + float amax, anorm, bignum, smlnum, colcnd, rowcnd, rcmax, rcmin; + int relax, panel_size; + float diag_pivot_thresh; + double t0; /* temporary time */ + double *utime; + + /* External functions */ + extern float slangs(char *, SuperMatrix *); + + Bstore = B->Store; + Xstore = X->Store; + Bmat = Bstore->nzval; + Xmat = Xstore->nzval; + ldb = Bstore->lda; + ldx = Xstore->lda; + nrhs = B->ncol; + + *info = 0; + nofact = (options->Fact != FACTORED); + equil = (options->Equil == YES); + notran = (options->Trans == NOTRANS); + if ( nofact ) { + *(unsigned char *)equed = 'N'; + rowequ = FALSE; + colequ = FALSE; + } else { + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + smlnum = smach("Safe minimum"); /* lamch_("Safe minimum"); */ + bignum = 1. / smlnum; + } + +#if 0 +printf("dgssvx: Fact=%4d, Trans=%4d, equed=%c\n", + options->Fact, options->Trans, *equed); +#endif + + /* Test the input parameters */ + if (options->Fact != DOFACT && options->Fact != SamePattern && + options->Fact != SamePattern_SameRowPerm && + options->Fact != FACTORED && + options->Trans != NOTRANS && options->Trans != TRANS && + options->Trans != CONJ && + options->Equil != NO && options->Equil != YES) + *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + (A->Stype != SLU_NC && A->Stype != SLU_NR) || + A->Dtype != SLU_S || A->Mtype != SLU_GE ) + *info = -2; + else if ( options->Fact == FACTORED && + !(rowequ || colequ || strncmp(equed, "N", 1)==0) ) + *info = -6; + else { + if (rowequ) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, R[j]); + rcmax = SUPERLU_MAX(rcmax, R[j]); + } + if (rcmin <= 0.) *info = -7; + else if ( A->nrow > 0) + rowcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else rowcnd = 1.; + } + if (colequ && *info == 0) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, C[j]); + rcmax = SUPERLU_MAX(rcmax, C[j]); + } + if (rcmin <= 0.) *info = -8; + else if (A->nrow > 0) + colcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else colcnd = 1.; + } + if (*info == 0) { + if ( lwork < -1 ) *info = -12; + else if ( B->ncol < 0 ) *info = -13; + else if ( B->ncol > 0 ) { /* no checking if B->ncol=0 */ + if ( Bstore->lda < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_S || + B->Mtype != SLU_GE ) + *info = -13; + } + if ( X->ncol < 0 ) *info = -14; + else if ( X->ncol > 0 ) { /* no checking if X->ncol=0 */ + if ( Xstore->lda < SUPERLU_MAX(0, A->nrow) || + (B->ncol != 0 && B->ncol != X->ncol) || + X->Stype != SLU_DN || + X->Dtype != SLU_S || X->Mtype != SLU_GE ) + *info = -14; + } + } + } + if (*info != 0) { + i = -(*info); + input_error("sgssvx", &i); + return; + } + + /* Initialization for factor parameters */ + panel_size = sp_ienv(1); + relax = sp_ienv(2); + diag_pivot_thresh = options->DiagPivotThresh; + + utime = stat->utime; + + /* Convert A to SLU_NC format when necessary. */ + if ( A->Stype == SLU_NR ) { + NRformat *Astore = A->Store; + AA = (SuperMatrix *) SUPERLU_MALLOC( sizeof(SuperMatrix) ); + sCreate_CompCol_Matrix(AA, A->ncol, A->nrow, Astore->nnz, + Astore->nzval, Astore->colind, Astore->rowptr, + SLU_NC, A->Dtype, A->Mtype); + if ( notran ) { /* Reverse the transpose argument. */ + trant = TRANS; + notran = 0; + } else { + trant = NOTRANS; + notran = 1; + } + } else { /* A->Stype == SLU_NC */ + trant = options->Trans; + AA = A; + } + + if ( nofact && equil ) { + t0 = SuperLU_timer_(); + /* Compute row and column scalings to equilibrate the matrix A. */ + sgsequ(AA, R, C, &rowcnd, &colcnd, &amax, &info1); + + if ( info1 == 0 ) { + /* Equilibrate matrix A. */ + slaqgs(AA, R, C, rowcnd, colcnd, amax, equed); + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + } + utime[EQUIL] = SuperLU_timer_() - t0; + } + + + if ( nofact ) { + + t0 = SuperLU_timer_(); + /* + * Gnet column permutation vector perm_c[], according to permc_spec: + * permc_spec = NATURAL: natural ordering + * permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A + * permc_spec = MMD_ATA: minimum degree on structure of A'*A + * permc_spec = COLAMD: approximate minimum degree column ordering + * permc_spec = MY_PERMC: the ordering already supplied in perm_c[] + */ + permc_spec = options->ColPerm; + if ( permc_spec != MY_PERMC && options->Fact == DOFACT ) + get_perm_c(permc_spec, AA, perm_c); + utime[COLPERM] = SuperLU_timer_() - t0; + + t0 = SuperLU_timer_(); + sp_preorder(options, AA, perm_c, etree, &AC); + utime[ETREE] = SuperLU_timer_() - t0; + +/* printf("Factor PA = LU ... relax %d\tw %d\tmaxsuper %d\trowblk %d\n", + relax, panel_size, sp_ienv(3), sp_ienv(4)); + fflush(stdout); */ + + /* Compute the LU factorization of A*Pc. */ + t0 = SuperLU_timer_(); + sgstrf(options, &AC, relax, panel_size, etree, + work, lwork, perm_c, perm_r, L, U, Glu, stat, info); + utime[FACT] = SuperLU_timer_() - t0; + + if ( lwork == -1 ) { + mem_usage->total_needed = *info - A->ncol; + return; + } + } + + if ( *info > 0 ) { + if ( *info <= A->ncol ) { + /* Compute the reciprocal pivot growth factor of the leading + rank-deficient (*info) columns of A. */ + *recip_pivot_growth = sPivotGrowth(*info, AA, perm_c, L, U); + } + return; + } + + /* *info == 0 at this point. */ + + if ( options->PivotGrowth ) { + /* Compute the reciprocal pivot growth factor *recip_pivot_growth. */ + *recip_pivot_growth = sPivotGrowth(A->ncol, AA, perm_c, L, U); + } + + if ( options->ConditionNumber ) { + /* Estimate the reciprocal of the condition number of A. */ + t0 = SuperLU_timer_(); + if ( notran ) { + *(unsigned char *)norm = '1'; + } else { + *(unsigned char *)norm = 'I'; + } + anorm = slangs(norm, AA); + sgscon(norm, L, U, anorm, rcond, stat, &info1); + utime[RCOND] = SuperLU_timer_() - t0; + } + + if ( nrhs > 0 ) { + /* Scale the right hand side if equilibration was performed. */ + if ( notran ) { + if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + Bmat[i + j*ldb] *= R[i]; + } + } else if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + Bmat[i + j*ldb] *= C[i]; + } + + /* Compute the solution matrix X. */ + for (j = 0; j < nrhs; j++) /* Save a copy of the right hand sides */ + for (i = 0; i < B->nrow; i++) + Xmat[i + j*ldx] = Bmat[i + j*ldb]; + + t0 = SuperLU_timer_(); + sgstrs (trant, L, U, perm_c, perm_r, X, stat, &info1); + utime[SOLVE] = SuperLU_timer_() - t0; + + /* Use iterative refinement to improve the computed solution and compute + error bounds and backward error estimates for it. */ + t0 = SuperLU_timer_(); + if ( options->IterRefine != NOREFINE ) { + sgsrfs(trant, AA, L, U, perm_c, perm_r, equed, R, C, B, + X, ferr, berr, stat, &info1); + } else { + for (j = 0; j < nrhs; ++j) ferr[j] = berr[j] = 1.0; + } + utime[REFINE] = SuperLU_timer_() - t0; + + /* Transform the solution matrix X to a solution of the original system. */ + if ( notran ) { + if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + Xmat[i + j*ldx] *= C[i]; + } + } else if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + Xmat[i + j*ldx] *= R[i]; + } + } /* end if nrhs > 0 */ + + if ( options->ConditionNumber ) { + /* Set INFO = A->ncol+1 if the matrix is singular to working precision. */ + /*if ( *rcond < slamch_("E") ) *info = A->ncol + 1;*/ + if ( *rcond < smach("E") ) *info = A->ncol + 1; + } + + if ( nofact ) { + sQuerySpace(L, U, mem_usage); + Destroy_CompCol_Permuted(&AC); + } + if ( A->Stype == SLU_NR ) { + Destroy_SuperMatrix_Store(AA); + SUPERLU_FREE(AA); + } + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/sgstrf.c b/src/Libraries/superlu-5.2.1/SRC/sgstrf.c new file mode 100644 index 00000000..8d738bc1 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sgstrf.c @@ -0,0 +1,459 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sgstrf.c + * \brief Computes an LU factorization of a general sparse matrix + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ * 
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_sdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * SGSTRF computes an LU factorization of a general sparse m-by-n
+ * matrix A using partial pivoting with row interchanges.
+ * The factorization has the form
+ *     Pr * A = L * U
+ * where Pr is a row permutation matrix, L is lower triangular with unit
+ * diagonal elements (lower trapezoidal if A->nrow > A->ncol), and U is upper 
+ * triangular (upper trapezoidal if A->nrow < A->ncol).
+ *
+ * See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *         The structure defines the input parameters to control
+ *         how the LU decomposition will be performed.
+ *
+ * A        (input) SuperMatrix*
+ *	    Original matrix A, permuted by columns, of dimension
+ *          (A->nrow, A->ncol). The type of A can be:
+ *          Stype = SLU_NCP; Dtype = SLU_S; Mtype = SLU_GE.
+ *
+ * relax    (input) int
+ *          To control degree of relaxing supernodes. If the number
+ *          of nodes (columns) in a subtree of the elimination tree is less
+ *          than relax, this subtree is considered as one supernode,
+ *          regardless of the row structures of those columns.
+ *
+ * panel_size (input) int
+ *          A panel consists of at most panel_size consecutive columns.
+ *
+ * etree    (input) int*, dimension (A->ncol)
+ *          Elimination tree of A'*A.
+ *          Note: etree is a vector of parent pointers for a forest whose
+ *          vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *          On input, the columns of A should be permuted so that the
+ *          etree is in a certain postorder.
+ *
+ * work     (input/output) void*, size (lwork) (in bytes)
+ *          User-supplied work space and space for the output data structures.
+ *          Not referenced if lwork = 0;
+ *
+ * lwork   (input) int
+ *         Specifies the size of work array in bytes.
+ *         = 0:  allocate space internally by system malloc;
+ *         > 0:  use user-supplied work array of length lwork in bytes,
+ *               returns error if space runs out.
+ *         = -1: the routine guesses the amount of space needed without
+ *               performing the factorization, and returns it in
+ *               *info; no other side effects.
+ *
+ * perm_c   (input) int*, dimension (A->ncol)
+ *	    Column permutation vector, which defines the 
+ *          permutation matrix Pc; perm_c[i] = j means column i of A is 
+ *          in position j in A*Pc.
+ *          When searching for diagonal, perm_c[*] is applied to the
+ *          row subscripts of A, so that diagonal threshold pivoting
+ *          can find the diagonal of A, rather than that of A*Pc.
+ *
+ * perm_r   (input/output) int*, dimension (A->nrow)
+ *          Row permutation vector which defines the permutation matrix Pr,
+ *          perm_r[i] = j means row i of A is in position j in Pr*A.
+ *          If options->Fact == SamePattern_SameRowPerm, the pivoting routine
+ *             will try to use the input perm_r, unless a certain threshold
+ *             criterion is violated. In that case, perm_r is overwritten by
+ *             a new permutation determined by partial pivoting or diagonal
+ *             threshold pivoting.
+ *          Otherwise, perm_r is output argument;
+ *
+ * L        (output) SuperMatrix*
+ *          The factor L from the factorization Pr*A=L*U; use compressed row 
+ *          subscripts storage for supernodes, i.e., L has type: 
+ *          Stype = SLU_SC, Dtype = SLU_S, Mtype = SLU_TRLU.
+ *
+ * U        (output) SuperMatrix*
+ *	    The factor U from the factorization Pr*A*Pc=L*U. Use column-wise
+ *          storage scheme, i.e., U has types: Stype = SLU_NC, 
+ *          Dtype = SLU_S, Mtype = SLU_TRU.
+ *
+ * Glu      (input/output) GlobalLU_t *
+ *          If options->Fact == SamePattern_SameRowPerm, it is an input;
+ *              The matrix A will be factorized assuming that a 
+ *              factorization of a matrix with the same sparsity pattern
+ *              and similar numerical values was performed prior to this one.
+ *              Therefore, this factorization will reuse both row and column
+ *		scaling factors R and C, both row and column permutation
+ *		vectors perm_r and perm_c, and the L & U data structures
+ *		set up from the previous factorization.
+ *          Otherwise, it is an output.
+ *
+ * stat     (output) SuperLUStat_t*
+ *          Record the statistics on runtime and floating-point operation count.
+ *          See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info     (output) int*
+ *          = 0: successful exit
+ *          < 0: if info = -i, the i-th argument had an illegal value
+ *          > 0: if info = i, and i is
+ *             <= A->ncol: U(i,i) is exactly zero. The factorization has
+ *                been completed, but the factor U is exactly singular,
+ *                and division by zero will occur if it is used to solve a
+ *                system of equations.
+ *             > A->ncol: number of bytes allocated when memory allocation
+ *                failure occurred, plus A->ncol. If lwork = -1, it is
+ *                the estimated amount of space needed, plus A->ncol.
+ *
+ * ======================================================================
+ *
+ * Local Working Arrays: 
+ * ======================
+ *   m = number of rows in the matrix
+ *   n = number of columns in the matrix
+ *
+ *   xprune[0:n-1]: xprune[*] points to locations in subscript 
+ *	vector lsub[*]. For column i, xprune[i] denotes the point where 
+ *	structural pruning begins. I.e. only xlsub[i],..,xprune[i]-1 need 
+ *	to be traversed for symbolic factorization.
+ *
+ *   marker[0:3*m-1]: marker[i] = j means that node i has been 
+ *	reached when working on column j.
+ *	Storage: relative to original row subscripts
+ *	NOTE: There are 3 of them: marker/marker1 are used for panel dfs, 
+ *	      see spanel_dfs.c; marker2 is used for inner-factorization,
+ *            see scolumn_dfs.c.
+ *
+ *   parent[0:m-1]: parent vector used during dfs
+ *      Storage: relative to new row subscripts
+ *
+ *   xplore[0:m-1]: xplore[i] gives the location of the next (dfs) 
+ *	unexplored neighbor of i in lsub[*]
+ *
+ *   segrep[0:nseg-1]: contains the list of supernodal representatives
+ *	in topological order of the dfs. A supernode representative is the 
+ *	last column of a supernode.
+ *      The maximum size of segrep[] is n.
+ *
+ *   repfnz[0:W*m-1]: for a nonzero segment U[*,j] that ends at a 
+ *	supernodal representative r, repfnz[r] is the location of the first 
+ *	nonzero in this segment.  It is also used during the dfs: repfnz[r]>0
+ *	indicates the supernode r has been explored.
+ *	NOTE: There are W of them, each used for one column of a panel. 
+ *
+ *   panel_lsub[0:W*m-1]: temporary for the nonzeros row indices below 
+ *      the panel diagonal. These are filled in during spanel_dfs(), and are
+ *      used later in the inner LU factorization within the panel.
+ *	panel_lsub[]/dense[] pair forms the SPA data structure.
+ *	NOTE: There are W of them.
+ *
+ *   dense[0:W*m-1]: sparse accumulating (SPA) vector for intermediate values;
+ *	    	   NOTE: there are W of them.
+ *
+ *   tempv[0:*]: real temporary used for dense numeric kernels;
+ *	The size of this array is defined by NUM_TEMPV() in slu_sdefs.h.
+ * 
+ */ + +void +sgstrf (superlu_options_t *options, SuperMatrix *A, + int relax, int panel_size, int *etree, void *work, int lwork, + int *perm_c, int *perm_r, SuperMatrix *L, SuperMatrix *U, + GlobalLU_t *Glu, /* persistent to facilitate multiple factorizations */ + SuperLUStat_t *stat, int *info) +{ + /* Local working arrays */ + NCPformat *Astore; + int *iperm_r = NULL; /* inverse of perm_r; used when + options->Fact == SamePattern_SameRowPerm */ + int *iperm_c; /* inverse of perm_c */ + int *iwork; + float *swork; + int *segrep, *repfnz, *parent, *xplore; + int *panel_lsub; /* dense[]/panel_lsub[] pair forms a w-wide SPA */ + int *xprune; + int *marker; + float *dense, *tempv; + int *relax_end; + float *a; + int *asub; + int *xa_begin, *xa_end; + int *xsup, *supno; + int *xlsub, *xlusup, *xusub; + int nzlumax; + float fill_ratio = sp_ienv(6); /* estimated fill ratio */ + + /* Local scalars */ + fact_t fact = options->Fact; + double diag_pivot_thresh = options->DiagPivotThresh; + int pivrow; /* pivotal row number in the original matrix A */ + int nseg1; /* no of segments in U-column above panel row jcol */ + int nseg; /* no of segments in each U-column */ + register int jcol; + register int kcol; /* end column of a relaxed snode */ + register int icol; + register int i, k, jj, new_next, iinfo; + int m, n, min_mn, jsupno, fsupc, nextlu, nextu; + int w_def; /* upper bound on panel width */ + int usepr, iperm_r_allocated = 0; + int nnzL, nnzU; + int *panel_histo = stat->panel_histo; + flops_t *ops = stat->ops; + + iinfo = 0; + m = A->nrow; + n = A->ncol; + min_mn = SUPERLU_MIN(m, n); + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + + /* Allocate storage common to the factor routines */ + *info = sLUMemInit(fact, work, lwork, m, n, Astore->nnz, + panel_size, fill_ratio, L, U, Glu, &iwork, &swork); + if ( *info ) return; + + xsup = Glu->xsup; + supno = Glu->supno; + xlsub = Glu->xlsub; + xlusup = Glu->xlusup; + xusub = Glu->xusub; + + SetIWork(m, n, panel_size, iwork, &segrep, &parent, &xplore, + &repfnz, &panel_lsub, &xprune, &marker); + sSetRWork(m, panel_size, swork, &dense, &tempv); + + usepr = (fact == SamePattern_SameRowPerm); + if ( usepr ) { + /* Compute the inverse of perm_r */ + iperm_r = (int *) intMalloc(m); + for (k = 0; k < m; ++k) iperm_r[perm_r[k]] = k; + iperm_r_allocated = 1; + } + iperm_c = (int *) intMalloc(n); + for (k = 0; k < n; ++k) iperm_c[perm_c[k]] = k; + + /* Identify relaxed snodes */ + relax_end = (int *) intMalloc(n); + if ( options->SymmetricMode == YES ) { + heap_relax_snode(n, etree, relax, marker, relax_end); + } else { + relax_snode(n, etree, relax, marker, relax_end); + } + + ifill (perm_r, m, EMPTY); + ifill (marker, m * NO_MARKER, EMPTY); + supno[0] = -1; + xsup[0] = xlsub[0] = xusub[0] = xlusup[0] = 0; + w_def = panel_size; + + /* + * Work on one "panel" at a time. A panel is one of the following: + * (a) a relaxed supernode at the bottom of the etree, or + * (b) panel_size contiguous columns, defined by the user + */ + for (jcol = 0; jcol < min_mn; ) { + + if ( relax_end[jcol] != EMPTY ) { /* start of a relaxed snode */ + kcol = relax_end[jcol]; /* end of the relaxed snode */ + panel_histo[kcol-jcol+1]++; + + /* -------------------------------------- + * Factorize the relaxed supernode(jcol:kcol) + * -------------------------------------- */ + /* Determine the union of the row structure of the snode */ + if ( (*info = ssnode_dfs(jcol, kcol, asub, xa_begin, xa_end, + xprune, marker, Glu)) != 0 ) + return; + + nextu = xusub[jcol]; + nextlu = xlusup[jcol]; + jsupno = supno[jcol]; + fsupc = xsup[jsupno]; + new_next = nextlu + (xlsub[fsupc+1]-xlsub[fsupc])*(kcol-jcol+1); + nzlumax = Glu->nzlumax; + while ( new_next > nzlumax ) { + if ( (*info = sLUMemXpand(jcol, nextlu, LUSUP, &nzlumax, Glu)) ) + return; + } + + for (icol = jcol; icol<= kcol; icol++) { + xusub[icol+1] = nextu; + + /* Scatter into SPA dense[*] */ + for (k = xa_begin[icol]; k < xa_end[icol]; k++) + dense[asub[k]] = a[k]; + + /* Numeric update within the snode */ + ssnode_bmod(icol, jsupno, fsupc, dense, tempv, Glu, stat); + + if ( (*info = spivotL(icol, diag_pivot_thresh, &usepr, perm_r, + iperm_r, iperm_c, &pivrow, Glu, stat)) ) + if ( iinfo == 0 ) iinfo = *info; + +#ifdef DEBUG + sprint_lu_col("[1]: ", icol, pivrow, xprune, Glu); +#endif + + } + + jcol = icol; + + } else { /* Work on one panel of panel_size columns */ + + /* Adjust panel_size so that a panel won't overlap with the next + * relaxed snode. + */ + panel_size = w_def; + for (k = jcol + 1; k < SUPERLU_MIN(jcol+panel_size, min_mn); k++) + if ( relax_end[k] != EMPTY ) { + panel_size = k - jcol; + break; + } + if ( k == min_mn ) panel_size = min_mn - jcol; + panel_histo[panel_size]++; + + /* symbolic factor on a panel of columns */ + spanel_dfs(m, panel_size, jcol, A, perm_r, &nseg1, + dense, panel_lsub, segrep, repfnz, xprune, + marker, parent, xplore, Glu); + + /* numeric sup-panel updates in topological order */ + spanel_bmod(m, panel_size, jcol, nseg1, dense, + tempv, segrep, repfnz, Glu, stat); + + /* Sparse LU within the panel, and below panel diagonal */ + for ( jj = jcol; jj < jcol + panel_size; jj++) { + k = (jj - jcol) * m; /* column index for w-wide arrays */ + + nseg = nseg1; /* Begin after all the panel segments */ + + if ((*info = scolumn_dfs(m, jj, perm_r, &nseg, &panel_lsub[k], + segrep, &repfnz[k], xprune, marker, + parent, xplore, Glu)) != 0) return; + + /* Numeric updates */ + if ((*info = scolumn_bmod(jj, (nseg - nseg1), &dense[k], + tempv, &segrep[nseg1], &repfnz[k], + jcol, Glu, stat)) != 0) return; + + /* Copy the U-segments to ucol[*] */ + if ((*info = scopy_to_ucol(jj, nseg, segrep, &repfnz[k], + perm_r, &dense[k], Glu)) != 0) + return; + + if ( (*info = spivotL(jj, diag_pivot_thresh, &usepr, perm_r, + iperm_r, iperm_c, &pivrow, Glu, stat)) ) + if ( iinfo == 0 ) iinfo = *info; + + /* Prune columns (0:jj-1) using column jj */ + spruneL(jj, perm_r, pivrow, nseg, segrep, + &repfnz[k], xprune, Glu); + + /* Reset repfnz[] for this column */ + resetrep_col (nseg, segrep, &repfnz[k]); + +#ifdef DEBUG + sprint_lu_col("[2]: ", jj, pivrow, xprune, Glu); +#endif + + } + + jcol += panel_size; /* Move to the next panel */ + + } /* else */ + + } /* for */ + + *info = iinfo; + + if ( m > n ) { + k = 0; + for (i = 0; i < m; ++i) + if ( perm_r[i] == EMPTY ) { + perm_r[i] = n + k; + ++k; + } + } + + countnz(min_mn, xprune, &nnzL, &nnzU, Glu); + fixupL(min_mn, perm_r, Glu); + + sLUWorkFree(iwork, swork, Glu); /* Free work space and compress storage */ + + if ( fact == SamePattern_SameRowPerm ) { + /* L and U structures may have changed due to possibly different + pivoting, even though the storage is available. + There could also be memory expansions, so the array locations + may have changed, */ + ((SCformat *)L->Store)->nnz = nnzL; + ((SCformat *)L->Store)->nsuper = Glu->supno[n]; + ((SCformat *)L->Store)->nzval = (float *) Glu->lusup; + ((SCformat *)L->Store)->nzval_colptr = Glu->xlusup; + ((SCformat *)L->Store)->rowind = Glu->lsub; + ((SCformat *)L->Store)->rowind_colptr = Glu->xlsub; + ((NCformat *)U->Store)->nnz = nnzU; + ((NCformat *)U->Store)->nzval = (float *) Glu->ucol; + ((NCformat *)U->Store)->rowind = Glu->usub; + ((NCformat *)U->Store)->colptr = Glu->xusub; + } else { + sCreate_SuperNode_Matrix(L, A->nrow, min_mn, nnzL, + (float *) Glu->lusup, Glu->xlusup, + Glu->lsub, Glu->xlsub, Glu->supno, Glu->xsup, + SLU_SC, SLU_S, SLU_TRLU); + sCreate_CompCol_Matrix(U, min_mn, min_mn, nnzU, + (float *) Glu->ucol, Glu->usub, Glu->xusub, + SLU_NC, SLU_S, SLU_TRU); + } + + ops[FACT] += ops[TRSV] + ops[GEMV]; + stat->expansions = --(Glu->num_expansions); + + if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r); + SUPERLU_FREE (iperm_c); + SUPERLU_FREE (relax_end); + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/sgstrs.c b/src/Libraries/superlu-5.2.1/SRC/sgstrs.c new file mode 100644 index 00000000..b6750736 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sgstrs.c @@ -0,0 +1,347 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sgstrs.c + * \brief Solves a system using LU factorization + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + +#include "slu_sdefs.h" + + +/* + * Function prototypes + */ +void susolve(int, int, float*, float*); +void slsolve(int, int, float*, float*); +void smatvec(int, int, int, float*, float*, float*); + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * SGSTRS solves a system of linear equations A*X=B or A'*X=B
+ * with A sparse and B dense, using the LU factorization computed by
+ * SGSTRF.
+ *
+ * See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * trans   (input) trans_t
+ *          Specifies the form of the system of equations:
+ *          = NOTRANS: A * X = B  (No transpose)
+ *          = TRANS:   A'* X = B  (Transpose)
+ *          = CONJ:    A**H * X = B  (Conjugate transpose)
+ *
+ * L       (input) SuperMatrix*
+ *         The factor L from the factorization Pr*A*Pc=L*U as computed by
+ *         sgstrf(). Use compressed row subscripts storage for supernodes,
+ *         i.e., L has types: Stype = SLU_SC, Dtype = SLU_S, Mtype = SLU_TRLU.
+ *
+ * U       (input) SuperMatrix*
+ *         The factor U from the factorization Pr*A*Pc=L*U as computed by
+ *         sgstrf(). Use column-wise storage scheme, i.e., U has types:
+ *         Stype = SLU_NC, Dtype = SLU_S, Mtype = SLU_TRU.
+ *
+ * perm_c  (input) int*, dimension (L->ncol)
+ *	   Column permutation vector, which defines the 
+ *         permutation matrix Pc; perm_c[i] = j means column i of A is 
+ *         in position j in A*Pc.
+ *
+ * perm_r  (input) int*, dimension (L->nrow)
+ *         Row permutation vector, which defines the permutation matrix Pr; 
+ *         perm_r[i] = j means row i of A is in position j in Pr*A.
+ *
+ * B       (input/output) SuperMatrix*
+ *         B has types: Stype = SLU_DN, Dtype = SLU_S, Mtype = SLU_GE.
+ *         On entry, the right hand side matrix.
+ *         On exit, the solution matrix if info = 0;
+ *
+ * stat     (output) SuperLUStat_t*
+ *          Record the statistics on runtime and floating-point operation count.
+ *          See util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ * 	   = 0: successful exit
+ *	   < 0: if info = -i, the i-th argument had an illegal value
+ * 
+ */ + +void +sgstrs (trans_t trans, SuperMatrix *L, SuperMatrix *U, + int *perm_c, int *perm_r, SuperMatrix *B, + SuperLUStat_t *stat, int *info) +{ + +#ifdef _CRAY + _fcd ftcs1, ftcs2, ftcs3, ftcs4; +#endif + int incx = 1, incy = 1; +#ifdef USE_VENDOR_BLAS + float alpha = 1.0, beta = 1.0; + float *work_col; +#endif + DNformat *Bstore; + float *Bmat; + SCformat *Lstore; + NCformat *Ustore; + float *Lval, *Uval; + int fsupc, nrow, nsupr, nsupc, luptr, istart, irow; + int i, j, k, iptr, jcol, n, ldb, nrhs; + float *work, *rhs_work, *soln; + flops_t solve_ops; + void sprint_soln(); + + /* Test input parameters ... */ + *info = 0; + Bstore = B->Store; + ldb = Bstore->lda; + nrhs = B->ncol; + if ( trans != NOTRANS && trans != TRANS && trans != CONJ ) *info = -1; + else if ( L->nrow != L->ncol || L->nrow < 0 || + L->Stype != SLU_SC || L->Dtype != SLU_S || L->Mtype != SLU_TRLU ) + *info = -2; + else if ( U->nrow != U->ncol || U->nrow < 0 || + U->Stype != SLU_NC || U->Dtype != SLU_S || U->Mtype != SLU_TRU ) + *info = -3; + else if ( ldb < SUPERLU_MAX(0, L->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_S || B->Mtype != SLU_GE ) + *info = -6; + if ( *info ) { + i = -(*info); + input_error("sgstrs", &i); + return; + } + + n = L->nrow; + work = floatCalloc(n * nrhs); + if ( !work ) ABORT("Malloc fails for local work[]."); + soln = floatMalloc(n); + if ( !soln ) ABORT("Malloc fails for local soln[]."); + + Bmat = Bstore->nzval; + Lstore = L->Store; + Lval = Lstore->nzval; + Ustore = U->Store; + Uval = Ustore->nzval; + solve_ops = 0; + + if ( trans == NOTRANS ) { + /* Permute right hand sides to form Pr*B */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[perm_r[k]] = rhs_work[k]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + /* Forward solve PLy=Pb. */ + for (k = 0; k <= Lstore->nsuper; k++) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + nrow = nsupr - nsupc; + + solve_ops += nsupc * (nsupc - 1) * nrhs; + solve_ops += 2 * nrow * nsupc * nrhs; + + if ( nsupc == 1 ) { + for (j = 0; j < nrhs; j++) { + rhs_work = &Bmat[j*ldb]; + luptr = L_NZ_START(fsupc); + for (iptr=istart+1; iptr < L_SUB_START(fsupc+1); iptr++){ + irow = L_SUB(iptr); + ++luptr; + rhs_work[irow] -= rhs_work[fsupc] * Lval[luptr]; + } + } + } else { + luptr = L_NZ_START(fsupc); +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + ftcs1 = _cptofcd("L", strlen("L")); + ftcs2 = _cptofcd("N", strlen("N")); + ftcs3 = _cptofcd("U", strlen("U")); + STRSM( ftcs1, ftcs1, ftcs2, ftcs3, &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); + + SGEMM( ftcs2, ftcs2, &nrow, &nrhs, &nsupc, &alpha, + &Lval[luptr+nsupc], &nsupr, &Bmat[fsupc], &ldb, + &beta, &work[0], &n ); +#else + strsm_("L", "L", "N", "U", &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); + + sgemm_( "N", "N", &nrow, &nrhs, &nsupc, &alpha, + &Lval[luptr+nsupc], &nsupr, &Bmat[fsupc], &ldb, + &beta, &work[0], &n ); +#endif + for (j = 0; j < nrhs; j++) { + rhs_work = &Bmat[j*ldb]; + work_col = &work[j*n]; + iptr = istart + nsupc; + for (i = 0; i < nrow; i++) { + irow = L_SUB(iptr); + rhs_work[irow] -= work_col[i]; /* Scatter */ + work_col[i] = 0.0; + iptr++; + } + } +#else + for (j = 0; j < nrhs; j++) { + rhs_work = &Bmat[j*ldb]; + slsolve (nsupr, nsupc, &Lval[luptr], &rhs_work[fsupc]); + smatvec (nsupr, nrow, nsupc, &Lval[luptr+nsupc], + &rhs_work[fsupc], &work[0] ); + + iptr = istart + nsupc; + for (i = 0; i < nrow; i++) { + irow = L_SUB(iptr); + rhs_work[irow] -= work[i]; + work[i] = 0.0; + iptr++; + } + } +#endif + } /* else ... */ + } /* for L-solve */ + +#ifdef DEBUG + printf("After L-solve: y=\n"); + sprint_soln(n, nrhs, Bmat); +#endif + + /* + * Back solve Ux=y. + */ + for (k = Lstore->nsuper; k >= 0; k--) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + solve_ops += nsupc * (nsupc + 1) * nrhs; + + if ( nsupc == 1 ) { + rhs_work = &Bmat[0]; + for (j = 0; j < nrhs; j++) { + rhs_work[fsupc] /= Lval[luptr]; + rhs_work += ldb; + } + } else { +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + ftcs1 = _cptofcd("L", strlen("L")); + ftcs2 = _cptofcd("U", strlen("U")); + ftcs3 = _cptofcd("N", strlen("N")); + STRSM( ftcs1, ftcs2, ftcs3, ftcs3, &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); +#else + strsm_("L", "U", "N", "N", &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); +#endif +#else + for (j = 0; j < nrhs; j++) + susolve ( nsupr, nsupc, &Lval[luptr], &Bmat[fsupc+j*ldb] ); +#endif + } + + for (j = 0; j < nrhs; ++j) { + rhs_work = &Bmat[j*ldb]; + for (jcol = fsupc; jcol < fsupc + nsupc; jcol++) { + solve_ops += 2*(U_NZ_START(jcol+1) - U_NZ_START(jcol)); + for (i = U_NZ_START(jcol); i < U_NZ_START(jcol+1); i++ ){ + irow = U_SUB(i); + rhs_work[irow] -= rhs_work[jcol] * Uval[i]; + } + } + } + + } /* for U-solve */ + +#ifdef DEBUG + printf("After U-solve: x=\n"); + sprint_soln(n, nrhs, Bmat); +#endif + + /* Compute the final solution X := Pc*X. */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[k] = rhs_work[perm_c[k]]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + stat->ops[SOLVE] = solve_ops; + + } else { /* Solve A'*X=B or CONJ(A)*X=B */ + /* Permute right hand sides to form Pc'*B. */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[perm_c[k]] = rhs_work[k]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + stat->ops[SOLVE] = 0; + for (k = 0; k < nrhs; ++k) { + + /* Multiply by inv(U'). */ + sp_strsv("U", "T", "N", L, U, &Bmat[k*ldb], stat, info); + + /* Multiply by inv(L'). */ + sp_strsv("L", "T", "U", L, U, &Bmat[k*ldb], stat, info); + + } + /* Compute the final solution X := Pr'*X (=inv(Pr)*X) */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[k] = rhs_work[perm_r[k]]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + } + + SUPERLU_FREE(work); + SUPERLU_FREE(soln); +} + +/* + * Diagnostic print of the solution vector + */ +void +sprint_soln(int n, int nrhs, float *soln) +{ + int i; + + for (i = 0; i < n; i++) + printf("\t%d: %.4f\n", i, soln[i]); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/slacon.c b/src/Libraries/superlu-5.2.1/SRC/slacon.c new file mode 100644 index 00000000..2906efcb --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/slacon.c @@ -0,0 +1,247 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file slacon.c + * \brief Estimates the 1-norm + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ */ +#include +#include "slu_Cnames.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   SLACON estimates the 1-norm of a square matrix A.   
+ *   Reverse communication is used for evaluating matrix-vector products. 
+ * 
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   N      (input) INT
+ *          The order of the matrix.  N >= 1.   
+ *
+ *   V      (workspace) FLOAT PRECISION array, dimension (N)   
+ *          On the final return, V = A*W,  where  EST = norm(V)/norm(W)   
+ *          (W is not returned).   
+ *
+ *   X      (input/output) FLOAT PRECISION array, dimension (N)   
+ *          On an intermediate return, X should be overwritten by   
+ *                A * X,   if KASE=1,   
+ *                A' * X,  if KASE=2,
+ *         and SLACON must be re-called with all the other parameters   
+ *          unchanged.   
+ *
+ *   ISGN   (workspace) INT array, dimension (N)
+ *
+ *   EST    (output) FLOAT PRECISION   
+ *          An estimate (a lower bound) for norm(A).   
+ *
+ *   KASE   (input/output) INT
+ *          On the initial call to SLACON, KASE should be 0.   
+ *          On an intermediate return, KASE will be 1 or 2, indicating   
+ *          whether X should be overwritten by A * X  or A' * X.   
+ *          On the final return from SLACON, KASE will again be 0.   
+ *
+ *   Further Details   
+ *   ======= =======   
+ *
+ *   Contributed by Nick Higham, University of Manchester.   
+ *   Originally named CONEST, dated March 16, 1988.   
+ *
+ *   Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of 
+ *   a real or complex matrix, with applications to condition estimation", 
+ *   ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.   
+ *   ===================================================================== 
+ * 
+ */ + +int +slacon_(int *n, float *v, float *x, int *isgn, float *est, int *kase) + +{ + + + /* Table of constant values */ + int c__1 = 1; + float zero = 0.0; + float one = 1.0; + + /* Local variables */ + static int jump; + int jlast; + int iter; + float altsgn, estold; + int i, j; + float temp; +#ifdef _CRAY + extern int ISAMAX(int *, float *, int *); + extern float SASUM(int *, float *, int *); + extern int SCOPY(int *, float *, int *, float *, int *); +#else + extern int isamax_(int *, float *, int *); + extern float sasum_(int *, float *, int *); + extern int scopy_(int *, float *, int *, float *, int *); +#endif +#define d_sign(a, b) (b >= 0 ? fabs(a) : -fabs(a)) /* Copy sign */ +#define i_dnnt(a) \ + ( a>=0 ? floor(a+.5) : -floor(.5-a) ) /* Round to nearest integer */ + + if ( *kase == 0 ) { + for (i = 0; i < *n; ++i) { + x[i] = 1. / (float) (*n); + } + *kase = 1; + jump = 1; + return 0; + } + + switch (jump) { + case 1: goto L20; + case 2: goto L40; + case 3: goto L70; + case 4: goto L110; + case 5: goto L140; + } + + /* ................ ENTRY (JUMP = 1) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY A*X. */ + L20: + if (*n == 1) { + v[0] = x[0]; + *est = fabs(v[0]); + /* ... QUIT */ + goto L150; + } +#ifdef _CRAY + *est = SASUM(n, x, &c__1); +#else + *est = sasum_(n, x, &c__1); +#endif + + for (i = 0; i < *n; ++i) { + x[i] = d_sign(one, x[i]); + isgn[i] = i_dnnt(x[i]); + } + *kase = 2; + jump = 2; + return 0; + + /* ................ ENTRY (JUMP = 2) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X. */ +L40: +#ifdef _CRAY + j = ISAMAX(n, &x[0], &c__1); +#else + j = isamax_(n, &x[0], &c__1); +#endif + --j; + iter = 2; + + /* MAIN LOOP - ITERATIONS 2,3,...,ITMAX. */ +L50: + for (i = 0; i < *n; ++i) x[i] = zero; + x[j] = one; + *kase = 1; + jump = 3; + return 0; + + /* ................ ENTRY (JUMP = 3) + X HAS BEEN OVERWRITTEN BY A*X. */ +L70: +#ifdef _CRAY + SCOPY(n, x, &c__1, v, &c__1); +#else + scopy_(n, x, &c__1, v, &c__1); +#endif + estold = *est; +#ifdef _CRAY + *est = SASUM(n, v, &c__1); +#else + *est = sasum_(n, v, &c__1); +#endif + + for (i = 0; i < *n; ++i) + if (i_dnnt(d_sign(one, x[i])) != isgn[i]) + goto L90; + + /* REPEATED SIGN VECTOR DETECTED, HENCE ALGORITHM HAS CONVERGED. */ + goto L120; + +L90: + /* TEST FOR CYCLING. */ + if (*est <= estold) goto L120; + + for (i = 0; i < *n; ++i) { + x[i] = d_sign(one, x[i]); + isgn[i] = i_dnnt(x[i]); + } + *kase = 2; + jump = 4; + return 0; + + /* ................ ENTRY (JUMP = 4) + X HAS BEEN OVERWRITTEN BY TRANDPOSE(A)*X. */ +L110: + jlast = j; +#ifdef _CRAY + j = ISAMAX(n, &x[0], &c__1); +#else + j = isamax_(n, &x[0], &c__1); +#endif + --j; + if (x[jlast] != fabs(x[j]) && iter < 5) { + ++iter; + goto L50; + } + + /* ITERATION COMPLETE. FINAL STAGE. */ +L120: + altsgn = 1.; + for (i = 1; i <= *n; ++i) { + x[i-1] = altsgn * ((float)(i - 1) / (float)(*n - 1) + 1.); + altsgn = -altsgn; + } + *kase = 1; + jump = 5; + return 0; + + /* ................ ENTRY (JUMP = 5) + X HAS BEEN OVERWRITTEN BY A*X. */ +L140: +#ifdef _CRAY + temp = SASUM(n, x, &c__1) / (float)(*n * 3) * 2.; +#else + temp = sasum_(n, x, &c__1) / (float)(*n * 3) * 2.; +#endif + if (temp > *est) { +#ifdef _CRAY + SCOPY(n, &x[0], &c__1, &v[0], &c__1); +#else + scopy_(n, &x[0], &c__1, &v[0], &c__1); +#endif + *est = temp; + } + +L150: + *kase = 0; + return 0; + +} /* slacon_ */ diff --git a/src/Libraries/superlu-5.2.1/SRC/slacon2.c b/src/Libraries/superlu-5.2.1/SRC/slacon2.c new file mode 100644 index 00000000..7c933411 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/slacon2.c @@ -0,0 +1,254 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file slacon2.c + * \brief Estimates the 1-norm + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * July 25, 2015
+ * 
+ */ +#include +#include "slu_Cnames.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   SLACON2 estimates the 1-norm of a square matrix A.   
+ *   Reverse communication is used for evaluating matrix-vector products. 
+ * 
+ *   This is a thread safe version of SLACON, which uses the array ISAVE
+ *   in place of a STATIC variables, as follows:
+ *
+ *     SLACON     SLACON2
+ *      jump     isave[0]
+ *      j        isave[1]
+ *      iter     isave[2]
+ *
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   N      (input) INT
+ *          The order of the matrix.  N >= 1.   
+ *
+ *   V      (workspace) FLOAT PRECISION array, dimension (N)   
+ *          On the final return, V = A*W,  where  EST = norm(V)/norm(W)   
+ *          (W is not returned).   
+ *
+ *   X      (input/output) FLOAT PRECISION array, dimension (N)   
+ *          On an intermediate return, X should be overwritten by   
+ *                A * X,   if KASE=1,   
+ *                A' * X,  if KASE=2,
+ *         and SLACON must be re-called with all the other parameters   
+ *          unchanged.   
+ *
+ *   ISGN   (workspace) INT array, dimension (N)
+ *
+ *   EST    (output) FLOAT PRECISION   
+ *          An estimate (a lower bound) for norm(A).   
+ *
+ *   KASE   (input/output) INT
+ *          On the initial call to SLACON, KASE should be 0.   
+ *          On an intermediate return, KASE will be 1 or 2, indicating   
+ *          whether X should be overwritten by A * X  or A' * X.   
+ *          On the final return from SLACON, KASE will again be 0.   
+ *
+ *   isave  (input/output) int [3]
+ *          ISAVE is INTEGER array, dimension (3)
+ *          ISAVE is used to save variables between calls to SLACON2
+ *
+ *   Further Details   
+ *   ===============   
+ *
+ *   Contributed by Nick Higham, University of Manchester.   
+ *   Originally named CONEST, dated March 16, 1988.   
+ *
+ *   Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of 
+ *   a real or complex matrix, with applications to condition estimation", 
+ *   ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.   
+ *   ===================================================================== 
+ * 
+ */ + +int +slacon2_(int *n, float *v, float *x, int *isgn, float *est, int *kase, int isave[3]) +{ + /* Table of constant values */ + int c__1 = 1; + float zero = 0.0; + float one = 1.0; + + /* Local variables */ + int jlast; + float altsgn, estold; + int i; + float temp; +#ifdef _CRAY + extern int ISAMAX(int *, float *, int *); + extern float SASUM(int *, float *, int *); + extern int SCOPY(int *, float *, int *, float *, int *); +#else + extern int isamax_(int *, float *, int *); + extern float sasum_(int *, float *, int *); + extern int scopy_(int *, float *, int *, float *, int *); +#endif +#define d_sign(a, b) (b >= 0 ? fabs(a) : -fabs(a)) /* Copy sign */ +#define i_dnnt(a) \ + ( a>=0 ? floor(a+.5) : -floor(.5-a) ) /* Round to nearest integer */ + + if ( *kase == 0 ) { + for (i = 0; i < *n; ++i) { + x[i] = 1. / (float) (*n); + } + *kase = 1; + isave[0] = 1; /* jump = 1; */ + return 0; + } + + switch (isave[0]) { + case 1: goto L20; + case 2: goto L40; + case 3: goto L70; + case 4: goto L110; + case 5: goto L140; + } + + /* ................ ENTRY (isave[0] = 1) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY A*X. */ + L20: + if (*n == 1) { + v[0] = x[0]; + *est = fabs(v[0]); + /* ... QUIT */ + goto L150; + } +#ifdef _CRAY + *est = SASUM(n, x, &c__1); +#else + *est = sasum_(n, x, &c__1); +#endif + + for (i = 0; i < *n; ++i) { + x[i] = d_sign(one, x[i]); + isgn[i] = i_dnnt(x[i]); + } + *kase = 2; + isave[0] = 2; /* jump = 2; */ + return 0; + + /* ................ ENTRY (isave[0] = 2) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X. */ +L40: +#ifdef _CRAY + isave[1] = ISAMAX(n, &x[0], &c__1); /* j */ +#else + isave[1] = idamax_(n, &x[0], &c__1); /* j */ +#endif + --isave[1]; /* --j; */ + isave[2] = 2; /* iter = 2; */ + + /* MAIN LOOP - ITERATIONS 2,3,...,ITMAX. */ +L50: + for (i = 0; i < *n; ++i) x[i] = zero; + x[isave[1]] = one; + *kase = 1; + isave[0] = 3; /* jump = 3; */ + return 0; + + /* ................ ENTRY (isave[0] = 3) + X HAS BEEN OVERWRITTEN BY A*X. */ +L70: +#ifdef _CRAY + SCOPY(n, x, &c__1, v, &c__1); +#else + scopy_(n, x, &c__1, v, &c__1); +#endif + estold = *est; +#ifdef _CRAY + *est = SASUM(n, v, &c__1); +#else + *est = sasum_(n, v, &c__1); +#endif + + for (i = 0; i < *n; ++i) + if (i_dnnt(d_sign(one, x[i])) != isgn[i]) + goto L90; + + /* REPEATED SIGN VECTOR DETECTED, HENCE ALGORITHM HAS CONVERGED. */ + goto L120; + +L90: + /* TEST FOR CYCLING. */ + if (*est <= estold) goto L120; + + for (i = 0; i < *n; ++i) { + x[i] = d_sign(one, x[i]); + isgn[i] = i_dnnt(x[i]); + } + *kase = 2; + isave[0] = 4; /* jump = 4; */ + return 0; + + /* ................ ENTRY (isave[0] = 4) + X HAS BEEN OVERWRITTEN BY TRANDPOSE(A)*X. */ +L110: + jlast = isave[1]; /* j; */ +#ifdef _CRAY + isave[1] = ISAMAX(n, &x[0], &c__1); /* j */ +#else + isave[1] = isamax_(n, &x[0], &c__1); /* j */ +#endif + isave[1] = isave[1] - 1; /* --j; */ + if (x[jlast] != fabs(x[isave[1]]) && isave[2] < 5) { + isave[2] = isave[2] + 1; /* ++iter; */ + goto L50; + } + + /* ITERATION COMPLETE. FINAL STAGE. */ +L120: + altsgn = 1.; + for (i = 1; i <= *n; ++i) { + x[i-1] = altsgn * ((float)(i - 1) / (float)(*n - 1) + 1.); + altsgn = -altsgn; + } + *kase = 1; + isave[0] = 5; /* jump = 5; */ + return 0; + + /* ................ ENTRY (isave[0] = 5) + X HAS BEEN OVERWRITTEN BY A*X. */ +L140: +#ifdef _CRAY + temp = SASUM(n, x, &c__1) / (float)(*n * 3) * 2.; +#else + temp = sasum_(n, x, &c__1) / (float)(*n * 3) * 2.; +#endif + if (temp > *est) { +#ifdef _CRAY + SCOPY(n, &x[0], &c__1, &v[0], &c__1); +#else + scopy_(n, &x[0], &c__1, &v[0], &c__1); +#endif + *est = temp; + } + +L150: + *kase = 0; + return 0; + +} /* slacon_ */ diff --git a/src/Libraries/superlu-5.2.1/SRC/slangs.c b/src/Libraries/superlu-5.2.1/SRC/slangs.c new file mode 100644 index 00000000..9219082e --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/slangs.c @@ -0,0 +1,129 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file slangs.c + * \brief Returns the value of the one norm + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Modified from lapack routine SLANGE 
+ * 
+ */ +/* + * File name: slangs.c + * History: Modified from lapack routine SLANGE + */ +#include +#include "slu_sdefs.h" + +/*! \brief + * + *
+ * Purpose   
+ *   =======   
+ *
+ *   SLANGS returns the value of the one norm, or the Frobenius norm, or 
+ *   the infinity norm, or the element of largest absolute value of a 
+ *   real matrix A.   
+ *
+ *   Description   
+ *   ===========   
+ *
+ *   SLANGE returns the value   
+ *
+ *      SLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm'   
+ *               (   
+ *               ( norm1(A),         NORM = '1', 'O' or 'o'   
+ *               (   
+ *               ( normI(A),         NORM = 'I' or 'i'   
+ *               (   
+ *               ( normF(A),         NORM = 'F', 'f', 'E' or 'e'   
+ *
+ *   where  norm1  denotes the  one norm of a matrix (maximum column sum), 
+ *   normI  denotes the  infinity norm  of a matrix  (maximum row sum) and 
+ *   normF  denotes the  Frobenius norm of a matrix (square root of sum of 
+ *   squares).  Note that  max(abs(A(i,j)))  is not a  matrix norm.   
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   NORM    (input) CHARACTER*1   
+ *           Specifies the value to be returned in SLANGE as described above.   
+ *   A       (input) SuperMatrix*
+ *           The M by N sparse matrix A. 
+ *
+ *  =====================================================================
+ * 
+ */ + +float slangs(char *norm, SuperMatrix *A) +{ + + /* Local variables */ + NCformat *Astore; + float *Aval; + int i, j, irow; + float value, sum; + float *rwork; + + Astore = A->Store; + Aval = Astore->nzval; + + if ( SUPERLU_MIN(A->nrow, A->ncol) == 0) { + value = 0.; + + } else if (strncmp(norm, "M", 1)==0) { + /* Find max(abs(A(i,j))). */ + value = 0.; + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++) + value = SUPERLU_MAX( value, fabs( Aval[i]) ); + + } else if (strncmp(norm, "O", 1)==0 || *(unsigned char *)norm == '1') { + /* Find norm1(A). */ + value = 0.; + for (j = 0; j < A->ncol; ++j) { + sum = 0.; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++) + sum += fabs(Aval[i]); + value = SUPERLU_MAX(value,sum); + } + + } else if (strncmp(norm, "I", 1)==0) { + /* Find normI(A). */ + if ( !(rwork = (float *) SUPERLU_MALLOC(A->nrow * sizeof(float))) ) + ABORT("SUPERLU_MALLOC fails for rwork."); + for (i = 0; i < A->nrow; ++i) rwork[i] = 0.; + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++) { + irow = Astore->rowind[i]; + rwork[irow] += fabs(Aval[i]); + } + value = 0.; + for (i = 0; i < A->nrow; ++i) + value = SUPERLU_MAX(value, rwork[i]); + + SUPERLU_FREE (rwork); + + } else if (strncmp(norm, "F", 1)==0 || strncmp(norm, "E", 1)==0) { + /* Find normF(A). */ + ABORT("Not implemented."); + } else + ABORT("Illegal norm specified."); + + return (value); + +} /* slangs */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/slaqgs.c b/src/Libraries/superlu-5.2.1/SRC/slaqgs.c new file mode 100644 index 00000000..f6a15bb5 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/slaqgs.c @@ -0,0 +1,155 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file slaqgs.c + * \brief Equlibrates a general sprase matrix + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ * Modified from LAPACK routine SLAQGE
+ * 
+ */ +/* + * File name: slaqgs.c + * History: Modified from LAPACK routine SLAQGE + */ +#include +#include "slu_sdefs.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   SLAQGS equilibrates a general sparse M by N matrix A using the row and   
+ *   scaling factors in the vectors R and C.   
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   A       (input/output) SuperMatrix*
+ *           On exit, the equilibrated matrix.  See EQUED for the form of 
+ *           the equilibrated matrix. The type of A can be:
+ *	    Stype = NC; Dtype = SLU_S; Mtype = GE.
+ *	    
+ *   R       (input) float*, dimension (A->nrow)
+ *           The row scale factors for A.
+ *	    
+ *   C       (input) float*, dimension (A->ncol)
+ *           The column scale factors for A.
+ *	    
+ *   ROWCND  (input) float
+ *           Ratio of the smallest R(i) to the largest R(i).
+ *	    
+ *   COLCND  (input) float
+ *           Ratio of the smallest C(i) to the largest C(i).
+ *	    
+ *   AMAX    (input) float
+ *           Absolute value of largest matrix entry.
+ *	    
+ *   EQUED   (output) char*
+ *           Specifies the form of equilibration that was done.   
+ *           = 'N':  No equilibration   
+ *           = 'R':  Row equilibration, i.e., A has been premultiplied by  
+ *                   diag(R).   
+ *           = 'C':  Column equilibration, i.e., A has been postmultiplied  
+ *                   by diag(C).   
+ *           = 'B':  Both row and column equilibration, i.e., A has been
+ *                   replaced by diag(R) * A * diag(C).   
+ *
+ *   Internal Parameters   
+ *   ===================   
+ *
+ *   THRESH is a threshold value used to decide if row or column scaling   
+ *   should be done based on the ratio of the row or column scaling   
+ *   factors.  If ROWCND < THRESH, row scaling is done, and if   
+ *   COLCND < THRESH, column scaling is done.   
+ *
+ *   LARGE and SMALL are threshold values used to decide if row scaling   
+ *   should be done based on the absolute size of the largest matrix   
+ *   element.  If AMAX > LARGE or AMAX < SMALL, row scaling is done.   
+ *
+ *   ===================================================================== 
+ * 
+ */ + +void +slaqgs(SuperMatrix *A, float *r, float *c, + float rowcnd, float colcnd, float amax, char *equed) +{ + + +#define THRESH (0.1) + + /* Local variables */ + NCformat *Astore; + float *Aval; + int i, j, irow; + float large, small, cj; + + + /* Quick return if possible */ + if (A->nrow <= 0 || A->ncol <= 0) { + *(unsigned char *)equed = 'N'; + return; + } + + Astore = A->Store; + Aval = Astore->nzval; + + /* Initialize LARGE and SMALL. */ + small = smach("Safe minimum") / smach("Precision"); + large = 1. / small; + + if (rowcnd >= THRESH && amax >= small && amax <= large) { + if (colcnd >= THRESH) + *(unsigned char *)equed = 'N'; + else { + /* Column scaling */ + for (j = 0; j < A->ncol; ++j) { + cj = c[j]; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + Aval[i] *= cj; + } + } + *(unsigned char *)equed = 'C'; + } + } else if (colcnd >= THRESH) { + /* Row scaling, no column scaling */ + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + Aval[i] *= r[irow]; + } + *(unsigned char *)equed = 'R'; + } else { + /* Row and column scaling */ + for (j = 0; j < A->ncol; ++j) { + cj = c[j]; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + Aval[i] *= cj * r[irow]; + } + } + *(unsigned char *)equed = 'B'; + } + + return; + +} /* slaqgs */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/sldperm.c b/src/Libraries/superlu-5.2.1/SRC/sldperm.c new file mode 100644 index 00000000..3b257c63 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sldperm.c @@ -0,0 +1,178 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file + * \brief Finds a row permutation so that the matrix has large entries on the diagonal + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ + +#include "slu_sdefs.h" + +extern int_t mc64id_(int_t*); +extern int_t mc64ad_(int_t*, int_t*, int_t*, int_t [], int_t [], double [], + int_t*, int_t [], int_t*, int_t[], int_t*, double [], + int_t [], int_t []); + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *   SLDPERM finds a row permutation so that the matrix has large
+ *   entries on the diagonal.
+ *
+ * Arguments
+ * =========
+ *
+ * job    (input) int
+ *        Control the action. Possible values for JOB are:
+ *        = 1 : Compute a row permutation of the matrix so that the
+ *              permuted matrix has as many entries on its diagonal as
+ *              possible. The values on the diagonal are of arbitrary size.
+ *              HSL subroutine MC21A/AD is used for this.
+ *        = 2 : Compute a row permutation of the matrix so that the smallest 
+ *              value on the diagonal of the permuted matrix is maximized.
+ *        = 3 : Compute a row permutation of the matrix so that the smallest
+ *              value on the diagonal of the permuted matrix is maximized.
+ *              The algorithm differs from the one used for JOB = 2 and may
+ *              have quite a different performance.
+ *        = 4 : Compute a row permutation of the matrix so that the sum
+ *              of the diagonal entries of the permuted matrix is maximized.
+ *        = 5 : Compute a row permutation of the matrix so that the product
+ *              of the diagonal entries of the permuted matrix is maximized
+ *              and vectors to scale the matrix so that the nonzero diagonal 
+ *              entries of the permuted matrix are one in absolute value and 
+ *              all the off-diagonal entries are less than or equal to one in 
+ *              absolute value.
+ *        Restriction: 1 <= JOB <= 5.
+ *
+ * n      (input) int
+ *        The order of the matrix.
+ *
+ * nnz    (input) int
+ *        The number of nonzeros in the matrix.
+ *
+ * adjncy (input) int*, of size nnz
+ *        The adjacency structure of the matrix, which contains the row
+ *        indices of the nonzeros.
+ *
+ * colptr (input) int*, of size n+1
+ *        The pointers to the beginning of each column in ADJNCY.
+ *
+ * nzval  (input) float*, of size nnz
+ *        The nonzero values of the matrix. nzval[k] is the value of
+ *        the entry corresponding to adjncy[k].
+ *        It is not used if job = 1.
+ *
+ * perm   (output) int*, of size n
+ *        The permutation vector. perm[i] = j means row i in the
+ *        original matrix is in row j of the permuted matrix.
+ *
+ * u      (output) double*, of size n
+ *        If job = 5, the natural logarithms of the row scaling factors. 
+ *
+ * v      (output) double*, of size n
+ *        If job = 5, the natural logarithms of the column scaling factors. 
+ *        The scaled matrix B has entries b_ij = a_ij * exp(u_i + v_j).
+ * 
+ */ + +int +sldperm(int_t job, int_t n, int_t nnz, int_t colptr[], int_t adjncy[], + float nzval[], int_t *perm, float u[], float v[]) +{ + int_t i, liw, ldw, num; + int_t *iw, icntl[10], info[10]; + double *dw; + double *nzval_d = (double *) SUPERLU_MALLOC(nnz * sizeof(double)); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter sldperm()"); +#endif + liw = 5*n; + if ( job == 3 ) liw = 10*n + nnz; + if ( !(iw = intMalloc(liw)) ) ABORT("Malloc fails for iw[]"); + ldw = 3*n + nnz; + if ( !(dw = (double*) SUPERLU_MALLOC(ldw * sizeof(double))) ) + ABORT("Malloc fails for dw[]"); + + /* Increment one to get 1-based indexing. */ + for (i = 0; i <= n; ++i) ++colptr[i]; + for (i = 0; i < nnz; ++i) ++adjncy[i]; +#if ( DEBUGlevel>=2 ) + printf("LDPERM(): n %d, nnz %d\n", n, nnz); + slu_PrintInt10("colptr", n+1, colptr); + slu_PrintInt10("adjncy", nnz, adjncy); +#endif + + /* + * NOTE: + * ===== + * + * MC64AD assumes that column permutation vector is defined as: + * perm(i) = j means column i of permuted A is in column j of original A. + * + * Since a symmetric permutation preserves the diagonal entries. Then + * by the following relation: + * P'(A*P')P = P'A + * we can apply inverse(perm) to rows of A to get large diagonal entries. + * But, since 'perm' defined in MC64AD happens to be the reverse of + * SuperLU's definition of permutation vector, therefore, it is already + * an inverse for our purpose. We will thus use it directly. + * + */ + mc64id_(icntl); +#if 0 + /* Suppress error and warning messages. */ + icntl[0] = -1; + icntl[1] = -1; +#endif + + for (i = 0; i < nnz; ++i) nzval_d[i] = nzval[i]; + mc64ad_(&job, &n, &nnz, colptr, adjncy, nzval_d, &num, perm, + &liw, iw, &ldw, dw, icntl, info); + +#if ( DEBUGlevel>=2 ) + slu_PrintInt10("perm", n, perm); + printf(".. After MC64AD info %d\tsize of matching %d\n", info[0], num); +#endif + if ( info[0] == 1 ) { /* Structurally singular */ + printf(".. The last %d permutations:\n", n-num); + slu_PrintInt10("perm", n-num, &perm[num]); + } + + /* Restore to 0-based indexing. */ + for (i = 0; i <= n; ++i) --colptr[i]; + for (i = 0; i < nnz; ++i) --adjncy[i]; + for (i = 0; i < n; ++i) --perm[i]; + + if ( job == 5 ) + for (i = 0; i < n; ++i) { + u[i] = dw[i]; + v[i] = dw[n+i]; + } + + SUPERLU_FREE(iw); + SUPERLU_FREE(dw); + SUPERLU_FREE(nzval_d); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit sldperm()"); +#endif + + return info[0]; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/slu_Cnames.h b/src/Libraries/superlu-5.2.1/SRC/slu_Cnames.h new file mode 100644 index 00000000..1d73d824 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/slu_Cnames.h @@ -0,0 +1,452 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file slu_Cnames.h + * \brief Macros defining how C routines will be called + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 1, 1997
+ *
+ * These macros define how C routines will be called.  ADD_ assumes that
+ * they will be called by fortran, which expects C routines to have an
+ * underscore postfixed to the name (Suns, and the Intel expect this).
+ * NOCHANGE indicates that fortran will be calling, and that it expects
+ * the name called by fortran to be identical to that compiled by the C
+ * (RS6K's do this).  UPCASE says it expects C routines called by fortran
+ * to be in all upcase (CRAY wants this). 
+ * 
+ */ +#ifndef __SUPERLU_CNAMES /* allow multiple inclusions */ +#define __SUPERLU_CNAMES + + +#define ADD_ 0 +#define ADD__ 1 +#define NOCHANGE 2 +#define UPCASE 3 +#define OLD_CRAY 4 +#define C_CALL 5 + +#ifdef UpCase +#define F77_CALL_C UPCASE +#endif + +#ifdef NoChange +#define F77_CALL_C NOCHANGE +#endif + +#ifdef Add_ +#define F77_CALL_C ADD_ +#endif + +#ifdef Add__ +#define F77_CALL_C ADD__ +#endif + +#ifdef _CRAY +#define F77_CALL_C OLD_CRAY +#endif + +/* Default */ +#ifndef F77_CALL_C +#define F77_CALL_C ADD_ +#endif + + +#if (F77_CALL_C == ADD_) +/* + * These defines set up the naming scheme required to have a fortran 77 + * routine call a C routine + * No redefinition necessary to have following Fortran to C interface: + * FORTRAN CALL C DECLARATION + * call dgemm(...) void dgemm_(...) + * + * This is the default. + */ + +#endif + +#if (F77_CALL_C == ADD__) +/* + * These defines set up the naming scheme required to have a fortran 77 + * routine call a C routine + * for following Fortran to C interface: + * FORTRAN CALL C DECLARATION + * call dgemm(...) void dgemm__(...) + */ +/* BLAS */ +#define sswap_ sswap__ +#define saxpy_ saxpy__ +#define sasum_ sasum__ +#define isamax_ isamax__ +#define scopy_ scopy__ +#define sscal_ sscal__ +#define sger_ sger__ +#define snrm2_ snrm2__ +#define ssymv_ ssymv__ +#define sdot_ sdot__ +#define saxpy_ saxpy__ +#define ssyr2_ ssyr2__ +#define srot_ srot__ +#define sgemv_ sgemv__ +#define strsv_ strsv__ +#define sgemm_ sgemm__ +#define strsm_ strsm__ + +#define dswap_ dswap__ +#define daxpy_ daxpy__ +#define dasum_ dasum__ +#define idamax_ idamax__ +#define dcopy_ dcopy__ +#define dscal_ dscal__ +#define dger_ dger__ +#define dnrm2_ dnrm2__ +#define dsymv_ dsymv__ +#define ddot_ ddot__ +#define dsyr2_ dsyr2__ +#define drot_ drot__ +#define dgemv_ dgemv__ +#define dtrsv_ dtrsv__ +#define dgemm_ dgemm__ +#define dtrsm_ dtrsm__ + +#define cswap_ cswap__ +#define caxpy_ caxpy__ +#define scasum_ scasum__ +#define icamax_ icamax__ +#define ccopy_ ccopy__ +#define cscal_ cscal__ +#define scnrm2_ scnrm2__ +#define caxpy_ caxpy__ +#define cgemv_ cgemv__ +#define ctrsv_ ctrsv__ +#define cgemm_ cgemm__ +#define ctrsm_ ctrsm__ +#define cgerc_ cgerc__ +#define chemv_ chemv__ +#define cher2_ cher2__ + +#define zswap_ zswap__ +#define zaxpy_ zaxpy__ +#define dzasum_ dzasum__ +#define izamax_ izamax__ +#define zcopy_ zcopy__ +#define zscal_ zscal__ +#define dznrm2_ dznrm2__ +#define zaxpy_ zaxpy__ +#define zgemv_ zgemv__ +#define ztrsv_ ztrsv__ +#define zgemm_ zgemm__ +#define ztrsm_ ztrsm__ +#define zgerc_ zgerc__ +#define zhemv_ zhemv__ +#define zher2_ zher2__ + +/* LAPACK */ +#define dlacon_ dlacon__ +#define slacon_ slacon__ +#define icmax1_ icmax1__ +#define scsum1_ scsum1__ +#define clacon_ clacon__ +#define dzsum1_ dzsum1__ +#define izmax1_ izmax1__ +#define zlacon_ zlacon__ + +/* Fortran interface */ +#define c_bridge_dgssv_ c_bridge_dgssv__ +#define c_fortran_sgssv_ c_fortran_sgssv__ +#define c_fortran_dgssv_ c_fortran_dgssv__ +#define c_fortran_cgssv_ c_fortran_cgssv__ +#define c_fortran_zgssv_ c_fortran_zgssv__ +#endif + +#if (F77_CALL_C == UPCASE) +/* + * These defines set up the naming scheme required to have a fortran 77 + * routine call a C routine + * following Fortran to C interface: + * FORTRAN CALL C DECLARATION + * call dgemm(...) void DGEMM(...) + */ +/* BLAS */ +#define sswap_ SSWAP +#define saxpy_ SAXPY +#define sasum_ SASUM +#define isamax_ ISAMAX +#define scopy_ SCOPY +#define sscal_ SSCAL +#define sger_ SGER +#define snrm2_ SNRM2 +#define ssymv_ SSYMV +#define sdot_ SDOT +#define saxpy_ SAXPY +#define ssyr2_ SSYR2 +#define srot_ SROT +#define sgemv_ SGEMV +#define strsv_ STRSV +#define sgemm_ SGEMM +#define strsm_ STRSM + +#define dswap_ DSWAP +#define daxpy_ DAXPY +#define dasum_ DASUM +#define idamax_ IDAMAX +#define dcopy_ DCOPY +#define dscal_ DSCAL +#define dger_ DGER +#define dnrm2_ DNRM2 +#define dsymv_ DSYMV +#define ddot_ DDOT +#define dsyr2_ DSYR2 +#define drot_ DROT +#define dgemv_ DGEMV +#define dtrsv_ DTRSV +#define dgemm_ DGEMM +#define dtrsm_ DTRSM + +#define cswap_ CSWAP +#define caxpy_ CAXPY +#define scasum_ SCASUM +#define icamax_ ICAMAX +#define ccopy_ CCOPY +#define cscal_ CSCAL +#define scnrm2_ SCNRM2 +#define cgemv_ CGEMV +#define ctrsv_ CTRSV +#define cgemm_ CGEMM +#define ctrsm_ CTRSM +#define cgerc_ CGERC +#define chemv_ CHEMV +#define cher2_ CHER2 + +#define zswap_ ZSWAP +#define zaxpy_ ZAXPY +#define dzasum_ DZASUM +#define izamax_ IZAMAX +#define zcopy_ ZCOPY +#define zscal_ ZSCAL +#define dznrm2_ DZNRM2 +#define zgemv_ ZGEMV +#define ztrsv_ ZTRSV +#define zgemm_ ZGEMM +#define ztrsm_ ZTRSM +#define zgerc_ ZGERC +#define zhemv_ ZHEMV +#define zher2_ ZHER2 + +/* LAPACK */ +#define dlacon_ DLACON +#define slacon_ SLACON +#define icmax1_ ICMAX1 +#define scsum1_ SCSUM1 +#define clacon_ CLACON +#define dzsum1_ DZSUM1 +#define izmax1_ IZMAX1 +#define zlacon_ ZLACON + +/* Fortran interface */ +#define c_bridge_dgssv_ C_BRIDGE_DGSSV +#define c_fortran_sgssv_ C_FORTRAN_SGSSV +#define c_fortran_dgssv_ C_FORTRAN_DGSSV +#define c_fortran_cgssv_ C_FORTRAN_CGSSV +#define c_fortran_zgssv_ C_FORTRAN_ZGSSV +#endif + + +#if (F77_CALL_C == OLD_CRAY) +/* + * These defines set up the naming scheme required to have a fortran 77 + * routine call a C routine + * following Fortran to C interface: + * FORTRAN CALL C DECLARATION + * call dgemm(...) void SGEMM(...) + */ +/* BLAS */ +#define sswap_ SSWAP +#define saxpy_ SAXPY +#define sasum_ SASUM +#define isamax_ ISAMAX +#define scopy_ SCOPY +#define sscal_ SSCAL +#define sger_ SGER +#define snrm2_ SNRM2 +#define ssymv_ SSYMV +#define sdot_ SDOT +#define ssyr2_ SSYR2 +#define srot_ SROT +#define sgemv_ SGEMV +#define strsv_ STRSV +#define sgemm_ SGEMM +#define strsm_ STRSM + +#define dswap_ SSWAP +#define daxpy_ SAXPY +#define dasum_ SASUM +#define idamax_ ISAMAX +#define dcopy_ SCOPY +#define dscal_ SSCAL +#define dger_ SGER +#define dnrm2_ SNRM2 +#define dsymv_ SSYMV +#define ddot_ SDOT +#define dsyr2_ SSYR2 +#define drot_ SROT +#define dgemv_ SGEMV +#define dtrsv_ STRSV +#define dgemm_ SGEMM +#define dtrsm_ STRSM + +#define cswap_ CSWAP +#define caxpy_ CAXPY +#define scasum_ SCASUM +#define icamax_ ICAMAX +#define ccopy_ CCOPY +#define cscal_ CSCAL +#define scnrm2_ SCNRM2 +#define caxpy_ CAXPY +#define cgemv_ CGEMV +#define ctrsv_ CTRSV +#define cgemm_ CGEMM +#define ctrsm_ CTRSM +#define cgerc_ CGERC +#define chemv_ CHEMV +#define cher2_ CHER2 + +#define zswap_ ZSWAP +#define zaxpy_ ZAXPY +#define dzasum_ DZASUM +#define izamax_ IZAMAX +#define zcopy_ ZCOPY +#define zscal_ ZSCAL +#define dznrm2_ DZNRM2 +#define zgemv_ ZGEMV +#define ztrsv_ ZTRSV +#define zgemm_ ZGEMM +#define ztrsm_ ZTRSM +#define zgerc_ ZGERC +#define zhemv_ ZHEMV +#define zher2_ ZHER2 + +/* LAPACK */ +#define dlacon_ DLACON +#define slacon_ SLACON +#define icmax1_ ICMAX1 +#define scsum1_ SCSUM1 +#define clacon_ CLACON +#define dzsum1_ DZSUM1 +#define izmax1_ IZMAX1 +#define zlacon_ ZLACON + +/* Fortran interface */ +#define c_bridge_dgssv_ C_BRIDGE_DGSSV +#define c_fortran_sgssv_ C_FORTRAN_SGSSV +#define c_fortran_dgssv_ C_FORTRAN_DGSSV +#define c_fortran_cgssv_ C_FORTRAN_CGSSV +#define c_fortran_zgssv_ C_FORTRAN_ZGSSV +#endif + + +#if (F77_CALL_C == NOCHANGE) +/* + * These defines set up the naming scheme required to have a fortran 77 + * routine call a C routine + * for following Fortran to C interface: + * FORTRAN CALL C DECLARATION + * call dgemm(...) void dgemm(...) + */ +/* BLAS */ +#define sswap_ sswap +#define saxpy_ saxpy +#define sasum_ sasum +#define isamax_ isamax +#define scopy_ scopy +#define sscal_ sscal +#define sger_ sger +#define snrm2_ snrm2 +#define ssymv_ ssymv +#define sdot_ sdot +#define saxpy_ saxpy +#define ssyr2_ ssyr2 +#define srot_ srot +#define sgemv_ sgemv +#define strsv_ strsv +#define sgemm_ sgemm +#define strsm_ strsm + +#define dswap_ dswap +#define daxpy_ daxpy +#define dasum_ dasum +#define idamax_ idamax +#define dcopy_ dcopy +#define dscal_ dscal +#define dger_ dger +#define dnrm2_ dnrm2 +#define dsymv_ dsymv +#define ddot_ ddot +#define dsyr2_ dsyr2 +#define drot_ drot +#define dgemv_ dgemv +#define dtrsv_ dtrsv +#define dgemm_ dgemm +#define dtrsm_ dtrsm + +#define cswap_ cswap +#define caxpy_ caxpy +#define scasum_ scasum +#define icamax_ icamax +#define ccopy_ ccopy +#define cscal_ cscal +#define scnrm2_ scnrm2 +#define cgemv_ cgemv +#define ctrsv_ ctrsv +#define cgemm_ cgemm +#define ctrsm_ ctrsm +#define cgerc_ cgerc +#define chemv_ chemv +#define cher2_ cher2 + +#define zswap_ zswap +#define zaxpy_ zaxpy +#define dzasum_ dzasum +#define izamax_ izamax +#define zcopy_ zcopy +#define zscal_ zscal +#define dznrm2_ dznrm2 +#define zgemv_ zgemv +#define ztrsv_ ztrsv +#define zgemm_ zgemm +#define ztrsm_ ztrsm +#define zgerc_ zgerc +#define zhemv_ zhemv +#define zher2_ zher2 + +/* LAPACK */ +#define dlacon_ dlacon +#define slacon_ slacon +#define icmax1_ icmax1 +#define scsum1_ scsum1 +#define clacon_ clacon +#define dzsum1_ dzsum1 +#define izmax1_ izmax1 +#define zlacon_ zlacon + +/* Fortran interface */ +#define c_bridge_dgssv_ c_bridge_dgssv +#define c_fortran_sgssv_ c_fortran_sgssv +#define c_fortran_dgssv_ c_fortran_dgssv +#define c_fortran_cgssv_ c_fortran_cgssv +#define c_fortran_zgssv_ c_fortran_zgssv +#endif + + +#endif /* __SUPERLU_CNAMES */ diff --git a/src/Libraries/superlu-5.2.1/SRC/slu_cdefs.h b/src/Libraries/superlu-5.2.1/SRC/slu_cdefs.h new file mode 100644 index 00000000..b1d7dd88 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/slu_cdefs.h @@ -0,0 +1,285 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file slu_cdefs.h + * \brief Header file for real operations + * + *
 
+ * -- SuperLU routine (version 4.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November, 2010
+ * 
+ * Global data structures used in LU factorization -
+ * 
+ *   nsuper: #supernodes = nsuper + 1, numbered [0, nsuper].
+ *   (xsup,supno): supno[i] is the supernode no to which i belongs;
+ *	xsup(s) points to the beginning of the s-th supernode.
+ *	e.g.   supno 0 1 2 2 3 3 3 4 4 4 4 4   (n=12)
+ *	        xsup 0 1 2 4 7 12
+ *	Note: dfs will be performed on supernode rep. relative to the new 
+ *	      row pivoting ordering
+ *
+ *   (xlsub,lsub): lsub[*] contains the compressed subscript of
+ *	rectangular supernodes; xlsub[j] points to the starting
+ *	location of the j-th column in lsub[*]. Note that xlsub 
+ *	is indexed by column.
+ *	Storage: original row subscripts
+ *
+ *      During the course of sparse LU factorization, we also use
+ *	(xlsub,lsub) for the purpose of symmetric pruning. For each
+ *	supernode {s,s+1,...,t=s+r} with first column s and last
+ *	column t, the subscript set
+ *		lsub[j], j=xlsub[s], .., xlsub[s+1]-1
+ *	is the structure of column s (i.e. structure of this supernode).
+ *	It is used for the storage of numerical values.
+ *	Furthermore,
+ *		lsub[j], j=xlsub[t], .., xlsub[t+1]-1
+ *	is the structure of the last column t of this supernode.
+ *	It is for the purpose of symmetric pruning. Therefore, the
+ *	structural subscripts can be rearranged without making physical
+ *	interchanges among the numerical values.
+ *
+ *	However, if the supernode has only one column, then we
+ *	only keep one set of subscripts. For any subscript interchange
+ *	performed, similar interchange must be done on the numerical
+ *	values.
+ *
+ *	The last column structures (for pruning) will be removed
+ *	after the numercial LU factorization phase.
+ *
+ *   (xlusup,lusup): lusup[*] contains the numerical values of the
+ *	rectangular supernodes; xlusup[j] points to the starting
+ *	location of the j-th column in storage vector lusup[*]
+ *	Note: xlusup is indexed by column.
+ *	Each rectangular supernode is stored by column-major
+ *	scheme, consistent with Fortran 2-dim array storage.
+ *
+ *   (xusub,ucol,usub): ucol[*] stores the numerical values of
+ *	U-columns outside the rectangular supernodes. The row
+ *	subscript of nonzero ucol[k] is stored in usub[k].
+ *	xusub[i] points to the starting location of column i in ucol.
+ *	Storage: new row subscripts; that is subscripts of PA.
+ * 
+ */ +#ifndef __SUPERLU_cSP_DEFS /* allow multiple inclusions */ +#define __SUPERLU_cSP_DEFS + +/* + * File name: csp_defs.h + * Purpose: Sparse matrix types and function prototypes + * History: + */ + +#ifdef _CRAY +#include +#endif + +/* Define my integer type int_t */ +typedef int int_t; /* default */ + +#include +#include +#include +#include +#include +#include +#include "slu_Cnames.h" +#include "supermatrix.h" +#include "slu_util.h" +#include "slu_scomplex.h" + + +/* -------- Prototypes -------- */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \brief Driver routines */ +extern void +cgssv(superlu_options_t *, SuperMatrix *, int *, int *, SuperMatrix *, + SuperMatrix *, SuperMatrix *, SuperLUStat_t *, int *); +extern void +cgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *, + char *, float *, float *, SuperMatrix *, SuperMatrix *, + void *, int, SuperMatrix *, SuperMatrix *, + float *, float *, float *, float *, + GlobalLU_t *, mem_usage_t *, SuperLUStat_t *, int *); + /* ILU */ +extern void +cgsisv(superlu_options_t *, SuperMatrix *, int *, int *, SuperMatrix *, + SuperMatrix *, SuperMatrix *, SuperLUStat_t *, int *); +extern void +cgsisx(superlu_options_t *, SuperMatrix *, int *, int *, int *, + char *, float *, float *, SuperMatrix *, SuperMatrix *, + void *, int, SuperMatrix *, SuperMatrix *, float *, float *, + GlobalLU_t *, mem_usage_t *, SuperLUStat_t *, int *); + + +/*! \brief Supernodal LU factor related */ +extern void +cCreate_CompCol_Matrix(SuperMatrix *, int, int, int, complex *, + int *, int *, Stype_t, Dtype_t, Mtype_t); +extern void +cCreate_CompRow_Matrix(SuperMatrix *, int, int, int, complex *, + int *, int *, Stype_t, Dtype_t, Mtype_t); +extern void +cCopy_CompCol_Matrix(SuperMatrix *, SuperMatrix *); +extern void +cCreate_Dense_Matrix(SuperMatrix *, int, int, complex *, int, + Stype_t, Dtype_t, Mtype_t); +extern void +cCreate_SuperNode_Matrix(SuperMatrix *, int, int, int, complex *, + int *, int *, int *, int *, int *, + Stype_t, Dtype_t, Mtype_t); +extern void +cCopy_Dense_Matrix(int, int, complex *, int, complex *, int); + +extern void countnz (const int, int *, int *, int *, GlobalLU_t *); +extern void ilu_countnz (const int, int *, int *, GlobalLU_t *); +extern void fixupL (const int, const int *, GlobalLU_t *); + +extern void callocateA (int, int, complex **, int **, int **); +extern void cgstrf (superlu_options_t*, SuperMatrix*, + int, int, int*, void *, int, int *, int *, + SuperMatrix *, SuperMatrix *, GlobalLU_t *, + SuperLUStat_t*, int *); +extern int csnode_dfs (const int, const int, const int *, const int *, + const int *, int *, int *, GlobalLU_t *); +extern int csnode_bmod (const int, const int, const int, complex *, + complex *, GlobalLU_t *, SuperLUStat_t*); +extern void cpanel_dfs (const int, const int, const int, SuperMatrix *, + int *, int *, complex *, int *, int *, int *, + int *, int *, int *, int *, GlobalLU_t *); +extern void cpanel_bmod (const int, const int, const int, const int, + complex *, complex *, int *, int *, + GlobalLU_t *, SuperLUStat_t*); +extern int ccolumn_dfs (const int, const int, int *, int *, int *, int *, + int *, int *, int *, int *, int *, GlobalLU_t *); +extern int ccolumn_bmod (const int, const int, complex *, + complex *, int *, int *, int, + GlobalLU_t *, SuperLUStat_t*); +extern int ccopy_to_ucol (int, int, int *, int *, int *, + complex *, GlobalLU_t *); +extern int cpivotL (const int, const double, int *, int *, + int *, int *, int *, GlobalLU_t *, SuperLUStat_t*); +extern void cpruneL (const int, const int *, const int, const int, + const int *, const int *, int *, GlobalLU_t *); +extern void creadmt (int *, int *, int *, complex **, int **, int **); +extern void cGenXtrue (int, int, complex *, int); +extern void cFillRHS (trans_t, int, complex *, int, SuperMatrix *, + SuperMatrix *); +extern void cgstrs (trans_t, SuperMatrix *, SuperMatrix *, int *, int *, + SuperMatrix *, SuperLUStat_t*, int *); +/* ILU */ +extern void cgsitrf (superlu_options_t*, SuperMatrix*, int, int, int*, + void *, int, int *, int *, SuperMatrix *, SuperMatrix *, + GlobalLU_t *, SuperLUStat_t*, int *); +extern int cldperm(int, int, int, int [], int [], complex [], + int [], float [], float []); +extern int ilu_csnode_dfs (const int, const int, const int *, const int *, + const int *, int *, GlobalLU_t *); +extern void ilu_cpanel_dfs (const int, const int, const int, SuperMatrix *, + int *, int *, complex *, float *, int *, int *, + int *, int *, int *, int *, GlobalLU_t *); +extern int ilu_ccolumn_dfs (const int, const int, int *, int *, int *, + int *, int *, int *, int *, int *, + GlobalLU_t *); +extern int ilu_ccopy_to_ucol (int, int, int *, int *, int *, + complex *, int, milu_t, double, int, + complex *, int *, GlobalLU_t *, float *); +extern int ilu_cpivotL (const int, const double, int *, int *, int, int *, + int *, int *, int *, double, milu_t, + complex, GlobalLU_t *, SuperLUStat_t*); +extern int ilu_cdrop_row (superlu_options_t *, int, int, double, + int, int *, double *, GlobalLU_t *, + float *, float *, int); + + +/*! \brief Driver related */ + +extern void cgsequ (SuperMatrix *, float *, float *, float *, + float *, float *, int *); +extern void claqgs (SuperMatrix *, float *, float *, float, + float, float, char *); +extern void cgscon (char *, SuperMatrix *, SuperMatrix *, + float, float *, SuperLUStat_t*, int *); +extern float cPivotGrowth(int, SuperMatrix *, int *, + SuperMatrix *, SuperMatrix *); +extern void cgsrfs (trans_t, SuperMatrix *, SuperMatrix *, + SuperMatrix *, int *, int *, char *, float *, + float *, SuperMatrix *, SuperMatrix *, + float *, float *, SuperLUStat_t*, int *); + +extern int sp_ctrsv (char *, char *, char *, SuperMatrix *, + SuperMatrix *, complex *, SuperLUStat_t*, int *); +extern int sp_cgemv (char *, complex, SuperMatrix *, complex *, + int, complex, complex *, int); + +extern int sp_cgemm (char *, char *, int, int, int, complex, + SuperMatrix *, complex *, int, complex, + complex *, int); +extern float smach(char *); /* from C99 standard, in float.h */ + +/*! \brief Memory-related */ +extern int cLUMemInit (fact_t, void *, int, int, int, int, int, + float, SuperMatrix *, SuperMatrix *, + GlobalLU_t *, int **, complex **); +extern void cSetRWork (int, int, complex *, complex **, complex **); +extern void cLUWorkFree (int *, complex *, GlobalLU_t *); +extern int cLUMemXpand (int, int, MemType, int *, GlobalLU_t *); + +extern complex *complexMalloc(int); +extern complex *complexCalloc(int); +extern float *floatMalloc(int); +extern float *floatCalloc(int); +extern int cmemory_usage(const int, const int, const int, const int); +extern int cQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *); +extern int ilu_cQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *); + +/*! \brief Auxiliary routines */ +extern void creadhb(FILE *, int *, int *, int *, complex **, int **, int **); +extern void creadrb(int *, int *, int *, complex **, int **, int **); +extern void creadtriple(int *, int *, int *, complex **, int **, int **); +extern void cCompRow_to_CompCol(int, int, int, complex*, int*, int*, + complex **, int **, int **); +extern void cfill (complex *, int, complex); +extern void cinf_norm_error (int, SuperMatrix *, complex *); +extern float sqselect(int, float *, int); + + +/*! \brief Routines for debugging */ +extern void cPrint_CompCol_Matrix(char *, SuperMatrix *); +extern void cPrint_SuperNode_Matrix(char *, SuperMatrix *); +extern void cPrint_Dense_Matrix(char *, SuperMatrix *); +extern void cprint_lu_col(char *, int, int, int *, GlobalLU_t *); +extern int print_double_vec(char *, int, double *); +extern void ccheck_tempv(int, complex *); + +/*! \brief BLAS */ + +extern int cgemm_(const char*, const char*, const int*, const int*, const int*, + const complex*, const complex*, const int*, const complex*, + const int*, const complex*, complex*, const int*); +extern int ctrsv_(char*, char*, char*, int*, complex*, int*, + complex*, int*); +extern int ctrsm_(char*, char*, char*, char*, int*, int*, + complex*, complex*, int*, complex*, int*); +extern int cgemv_(char *, int *, int *, complex *, complex *a, int *, + complex *, int *, complex *, complex *, int *); + +#ifdef __cplusplus + } +#endif + +#endif /* __SUPERLU_cSP_DEFS */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/slu_dcomplex.h b/src/Libraries/superlu-5.2.1/SRC/slu_dcomplex.h new file mode 100644 index 00000000..67e83bcc --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/slu_dcomplex.h @@ -0,0 +1,88 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file slu_dcomplex.h + * \brief Header file for complex operations + *
 
+ *  -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Contains definitions for various complex operations.
+ * This header file is to be included in source files z*.c
+ * 
+ */ +#ifndef __SUPERLU_DCOMPLEX /* allow multiple inclusions */ +#define __SUPERLU_DCOMPLEX + + +#ifndef DCOMPLEX_INCLUDE +#define DCOMPLEX_INCLUDE + +typedef struct { double r, i; } doublecomplex; + + +/* Macro definitions */ + +/*! \brief Complex Addition c = a + b */ +#define z_add(c, a, b) { (c)->r = (a)->r + (b)->r; \ + (c)->i = (a)->i + (b)->i; } + +/*! \brief Complex Subtraction c = a - b */ +#define z_sub(c, a, b) { (c)->r = (a)->r - (b)->r; \ + (c)->i = (a)->i - (b)->i; } + +/*! \brief Complex-Double Multiplication */ +#define zd_mult(c, a, b) { (c)->r = (a)->r * (b); \ + (c)->i = (a)->i * (b); } + +/*! \brief Complex-Complex Multiplication */ +#define zz_mult(c, a, b) { \ + double cr, ci; \ + cr = (a)->r * (b)->r - (a)->i * (b)->i; \ + ci = (a)->i * (b)->r + (a)->r * (b)->i; \ + (c)->r = cr; \ + (c)->i = ci; \ + } + +#define zz_conj(a, b) { \ + (a)->r = (b)->r; \ + (a)->i = -((b)->i); \ + } + +/*! \brief Complex equality testing */ +#define z_eq(a, b) ( (a)->r == (b)->r && (a)->i == (b)->i ) + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Prototypes for functions in dcomplex.c */ +void z_div(doublecomplex *, doublecomplex *, doublecomplex *); +double z_abs(doublecomplex *); /* exact */ +double z_abs1(doublecomplex *); /* approximate */ +void z_exp(doublecomplex *, doublecomplex *); +void d_cnjg(doublecomplex *r, doublecomplex *z); +double d_imag(doublecomplex *); +doublecomplex z_sgn(doublecomplex *); +doublecomplex z_sqrt(doublecomplex *); + + + +#ifdef __cplusplus + } +#endif + +#endif + +#endif /* __SUPERLU_DCOMPLEX */ diff --git a/src/Libraries/superlu-5.2.1/SRC/slu_ddefs.h b/src/Libraries/superlu-5.2.1/SRC/slu_ddefs.h new file mode 100644 index 00000000..07ea5556 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/slu_ddefs.h @@ -0,0 +1,282 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file slu_ddefs.h + * \brief Header file for real operations + * + *
 
+ * -- SuperLU routine (version 4.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November, 2010
+ * 
+ * Global data structures used in LU factorization -
+ * 
+ *   nsuper: #supernodes = nsuper + 1, numbered [0, nsuper].
+ *   (xsup,supno): supno[i] is the supernode no to which i belongs;
+ *	xsup(s) points to the beginning of the s-th supernode.
+ *	e.g.   supno 0 1 2 2 3 3 3 4 4 4 4 4   (n=12)
+ *	        xsup 0 1 2 4 7 12
+ *	Note: dfs will be performed on supernode rep. relative to the new 
+ *	      row pivoting ordering
+ *
+ *   (xlsub,lsub): lsub[*] contains the compressed subscript of
+ *	rectangular supernodes; xlsub[j] points to the starting
+ *	location of the j-th column in lsub[*]. Note that xlsub 
+ *	is indexed by column.
+ *	Storage: original row subscripts
+ *
+ *      During the course of sparse LU factorization, we also use
+ *	(xlsub,lsub) for the purpose of symmetric pruning. For each
+ *	supernode {s,s+1,...,t=s+r} with first column s and last
+ *	column t, the subscript set
+ *		lsub[j], j=xlsub[s], .., xlsub[s+1]-1
+ *	is the structure of column s (i.e. structure of this supernode).
+ *	It is used for the storage of numerical values.
+ *	Furthermore,
+ *		lsub[j], j=xlsub[t], .., xlsub[t+1]-1
+ *	is the structure of the last column t of this supernode.
+ *	It is for the purpose of symmetric pruning. Therefore, the
+ *	structural subscripts can be rearranged without making physical
+ *	interchanges among the numerical values.
+ *
+ *	However, if the supernode has only one column, then we
+ *	only keep one set of subscripts. For any subscript interchange
+ *	performed, similar interchange must be done on the numerical
+ *	values.
+ *
+ *	The last column structures (for pruning) will be removed
+ *	after the numercial LU factorization phase.
+ *
+ *   (xlusup,lusup): lusup[*] contains the numerical values of the
+ *	rectangular supernodes; xlusup[j] points to the starting
+ *	location of the j-th column in storage vector lusup[*]
+ *	Note: xlusup is indexed by column.
+ *	Each rectangular supernode is stored by column-major
+ *	scheme, consistent with Fortran 2-dim array storage.
+ *
+ *   (xusub,ucol,usub): ucol[*] stores the numerical values of
+ *	U-columns outside the rectangular supernodes. The row
+ *	subscript of nonzero ucol[k] is stored in usub[k].
+ *	xusub[i] points to the starting location of column i in ucol.
+ *	Storage: new row subscripts; that is subscripts of PA.
+ * 
+ */ +#ifndef __SUPERLU_dSP_DEFS /* allow multiple inclusions */ +#define __SUPERLU_dSP_DEFS + +/* + * File name: dsp_defs.h + * Purpose: Sparse matrix types and function prototypes + * History: + */ + +#ifdef _CRAY +#include +#endif + +/* Define my integer type int_t */ +typedef int int_t; /* default */ + +#include +#include +#include +#include +#include +#include +#include "slu_Cnames.h" +#include "supermatrix.h" +#include "slu_util.h" + + +/* -------- Prototypes -------- */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \brief Driver routines */ +extern void +dgssv(superlu_options_t *, SuperMatrix *, int *, int *, SuperMatrix *, + SuperMatrix *, SuperMatrix *, SuperLUStat_t *, int *); +extern void +dgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *, + char *, double *, double *, SuperMatrix *, SuperMatrix *, + void *, int, SuperMatrix *, SuperMatrix *, + double *, double *, double *, double *, + GlobalLU_t *, mem_usage_t *, SuperLUStat_t *, int *); + /* ILU */ +extern void +dgsisv(superlu_options_t *, SuperMatrix *, int *, int *, SuperMatrix *, + SuperMatrix *, SuperMatrix *, SuperLUStat_t *, int *); +extern void +dgsisx(superlu_options_t *, SuperMatrix *, int *, int *, int *, + char *, double *, double *, SuperMatrix *, SuperMatrix *, + void *, int, SuperMatrix *, SuperMatrix *, double *, double *, + GlobalLU_t *, mem_usage_t *, SuperLUStat_t *, int *); + + +/*! \brief Supernodal LU factor related */ +extern void +dCreate_CompCol_Matrix(SuperMatrix *, int, int, int, double *, + int *, int *, Stype_t, Dtype_t, Mtype_t); +extern void +dCreate_CompRow_Matrix(SuperMatrix *, int, int, int, double *, + int *, int *, Stype_t, Dtype_t, Mtype_t); +extern void +dCopy_CompCol_Matrix(SuperMatrix *, SuperMatrix *); +extern void +dCreate_Dense_Matrix(SuperMatrix *, int, int, double *, int, + Stype_t, Dtype_t, Mtype_t); +extern void +dCreate_SuperNode_Matrix(SuperMatrix *, int, int, int, double *, + int *, int *, int *, int *, int *, + Stype_t, Dtype_t, Mtype_t); +extern void +dCopy_Dense_Matrix(int, int, double *, int, double *, int); + +extern void countnz (const int, int *, int *, int *, GlobalLU_t *); +extern void ilu_countnz (const int, int *, int *, GlobalLU_t *); +extern void fixupL (const int, const int *, GlobalLU_t *); + +extern void dallocateA (int, int, double **, int **, int **); +extern void dgstrf (superlu_options_t*, SuperMatrix*, + int, int, int*, void *, int, int *, int *, + SuperMatrix *, SuperMatrix *, GlobalLU_t *, + SuperLUStat_t*, int *); +extern int dsnode_dfs (const int, const int, const int *, const int *, + const int *, int *, int *, GlobalLU_t *); +extern int dsnode_bmod (const int, const int, const int, double *, + double *, GlobalLU_t *, SuperLUStat_t*); +extern void dpanel_dfs (const int, const int, const int, SuperMatrix *, + int *, int *, double *, int *, int *, int *, + int *, int *, int *, int *, GlobalLU_t *); +extern void dpanel_bmod (const int, const int, const int, const int, + double *, double *, int *, int *, + GlobalLU_t *, SuperLUStat_t*); +extern int dcolumn_dfs (const int, const int, int *, int *, int *, int *, + int *, int *, int *, int *, int *, GlobalLU_t *); +extern int dcolumn_bmod (const int, const int, double *, + double *, int *, int *, int, + GlobalLU_t *, SuperLUStat_t*); +extern int dcopy_to_ucol (int, int, int *, int *, int *, + double *, GlobalLU_t *); +extern int dpivotL (const int, const double, int *, int *, + int *, int *, int *, GlobalLU_t *, SuperLUStat_t*); +extern void dpruneL (const int, const int *, const int, const int, + const int *, const int *, int *, GlobalLU_t *); +extern void dreadmt (int *, int *, int *, double **, int **, int **); +extern void dGenXtrue (int, int, double *, int); +extern void dFillRHS (trans_t, int, double *, int, SuperMatrix *, + SuperMatrix *); +extern void dgstrs (trans_t, SuperMatrix *, SuperMatrix *, int *, int *, + SuperMatrix *, SuperLUStat_t*, int *); +/* ILU */ +extern void dgsitrf (superlu_options_t*, SuperMatrix*, int, int, int*, + void *, int, int *, int *, SuperMatrix *, SuperMatrix *, + GlobalLU_t *, SuperLUStat_t*, int *); +extern int dldperm(int, int, int, int [], int [], double [], + int [], double [], double []); +extern int ilu_dsnode_dfs (const int, const int, const int *, const int *, + const int *, int *, GlobalLU_t *); +extern void ilu_dpanel_dfs (const int, const int, const int, SuperMatrix *, + int *, int *, double *, double *, int *, int *, + int *, int *, int *, int *, GlobalLU_t *); +extern int ilu_dcolumn_dfs (const int, const int, int *, int *, int *, + int *, int *, int *, int *, int *, + GlobalLU_t *); +extern int ilu_dcopy_to_ucol (int, int, int *, int *, int *, + double *, int, milu_t, double, int, + double *, int *, GlobalLU_t *, double *); +extern int ilu_dpivotL (const int, const double, int *, int *, int, int *, + int *, int *, int *, double, milu_t, + double, GlobalLU_t *, SuperLUStat_t*); +extern int ilu_ddrop_row (superlu_options_t *, int, int, double, + int, int *, double *, GlobalLU_t *, + double *, double *, int); + + +/*! \brief Driver related */ + +extern void dgsequ (SuperMatrix *, double *, double *, double *, + double *, double *, int *); +extern void dlaqgs (SuperMatrix *, double *, double *, double, + double, double, char *); +extern void dgscon (char *, SuperMatrix *, SuperMatrix *, + double, double *, SuperLUStat_t*, int *); +extern double dPivotGrowth(int, SuperMatrix *, int *, + SuperMatrix *, SuperMatrix *); +extern void dgsrfs (trans_t, SuperMatrix *, SuperMatrix *, + SuperMatrix *, int *, int *, char *, double *, + double *, SuperMatrix *, SuperMatrix *, + double *, double *, SuperLUStat_t*, int *); + +extern int sp_dtrsv (char *, char *, char *, SuperMatrix *, + SuperMatrix *, double *, SuperLUStat_t*, int *); +extern int sp_dgemv (char *, double, SuperMatrix *, double *, + int, double, double *, int); + +extern int sp_dgemm (char *, char *, int, int, int, double, + SuperMatrix *, double *, int, double, + double *, int); +extern double dmach(char *); /* from C99 standard, in float.h */ + +/*! \brief Memory-related */ +extern int dLUMemInit (fact_t, void *, int, int, int, int, int, + double, SuperMatrix *, SuperMatrix *, + GlobalLU_t *, int **, double **); +extern void dSetRWork (int, int, double *, double **, double **); +extern void dLUWorkFree (int *, double *, GlobalLU_t *); +extern int dLUMemXpand (int, int, MemType, int *, GlobalLU_t *); + +extern double *doubleMalloc(int); +extern double *doubleCalloc(int); +extern int dmemory_usage(const int, const int, const int, const int); +extern int dQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *); +extern int ilu_dQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *); + +/*! \brief Auxiliary routines */ +extern void dreadhb(FILE *, int *, int *, int *, double **, int **, int **); +extern void dreadrb(int *, int *, int *, double **, int **, int **); +extern void dreadtriple(int *, int *, int *, double **, int **, int **); +extern void dCompRow_to_CompCol(int, int, int, double*, int*, int*, + double **, int **, int **); +extern void dfill (double *, int, double); +extern void dinf_norm_error (int, SuperMatrix *, double *); +extern double dqselect(int, double *, int); + + +/*! \brief Routines for debugging */ +extern void dPrint_CompCol_Matrix(char *, SuperMatrix *); +extern void dPrint_SuperNode_Matrix(char *, SuperMatrix *); +extern void dPrint_Dense_Matrix(char *, SuperMatrix *); +extern void dprint_lu_col(char *, int, int, int *, GlobalLU_t *); +extern int print_double_vec(char *, int, double *); +extern void dcheck_tempv(int, double *); + +/*! \brief BLAS */ + +extern int dgemm_(const char*, const char*, const int*, const int*, const int*, + const double*, const double*, const int*, const double*, + const int*, const double*, double*, const int*); +extern int dtrsv_(char*, char*, char*, int*, double*, int*, + double*, int*); +extern int dtrsm_(char*, char*, char*, char*, int*, int*, + double*, double*, int*, double*, int*); +extern int dgemv_(char *, int *, int *, double *, double *a, int *, + double *, int *, double *, double *, int *); + +#ifdef __cplusplus + } +#endif + +#endif /* __SUPERLU_dSP_DEFS */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/slu_scomplex.h b/src/Libraries/superlu-5.2.1/SRC/slu_scomplex.h new file mode 100644 index 00000000..5c9aa705 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/slu_scomplex.h @@ -0,0 +1,88 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file slu_scomplex.h + * \brief Header file for complex operations + *
 
+ *  -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Contains definitions for various complex operations.
+ * This header file is to be included in source files c*.c
+ * 
+ */ +#ifndef __SUPERLU_SCOMPLEX /* allow multiple inclusions */ +#define __SUPERLU_SCOMPLEX + + +#ifndef SCOMPLEX_INCLUDE +#define SCOMPLEX_INCLUDE + +typedef struct { float r, i; } complex; + + +/* Macro definitions */ + +/*! \brief Complex Addition c = a + b */ +#define c_add(c, a, b) { (c)->r = (a)->r + (b)->r; \ + (c)->i = (a)->i + (b)->i; } + +/*! \brief Complex Subtraction c = a - b */ +#define c_sub(c, a, b) { (c)->r = (a)->r - (b)->r; \ + (c)->i = (a)->i - (b)->i; } + +/*! \brief Complex-Double Multiplication */ +#define cs_mult(c, a, b) { (c)->r = (a)->r * (b); \ + (c)->i = (a)->i * (b); } + +/*! \brief Complex-Complex Multiplication */ +#define cc_mult(c, a, b) { \ + float cr, ci; \ + cr = (a)->r * (b)->r - (a)->i * (b)->i; \ + ci = (a)->i * (b)->r + (a)->r * (b)->i; \ + (c)->r = cr; \ + (c)->i = ci; \ + } + +#define cc_conj(a, b) { \ + (a)->r = (b)->r; \ + (a)->i = -((b)->i); \ + } + +/*! \brief Complex equality testing */ +#define c_eq(a, b) ( (a)->r == (b)->r && (a)->i == (b)->i ) + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Prototypes for functions in scomplex.c */ +void c_div(complex *, complex *, complex *); +double c_abs(complex *); /* exact */ +double c_abs1(complex *); /* approximate */ +void c_exp(complex *, complex *); +void r_cnjg(complex *, complex *); +double r_imag(complex *); +complex c_sgn(complex *); +complex c_sqrt(complex *); + + + +#ifdef __cplusplus + } +#endif + +#endif + +#endif /* __SUPERLU_SCOMPLEX */ diff --git a/src/Libraries/superlu-5.2.1/SRC/slu_sdefs.h b/src/Libraries/superlu-5.2.1/SRC/slu_sdefs.h new file mode 100644 index 00000000..ab063701 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/slu_sdefs.h @@ -0,0 +1,282 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file slu_sdefs.h + * \brief Header file for real operations + * + *
 
+ * -- SuperLU routine (version 4.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November, 2010
+ * 
+ * Global data structures used in LU factorization -
+ * 
+ *   nsuper: #supernodes = nsuper + 1, numbered [0, nsuper].
+ *   (xsup,supno): supno[i] is the supernode no to which i belongs;
+ *	xsup(s) points to the beginning of the s-th supernode.
+ *	e.g.   supno 0 1 2 2 3 3 3 4 4 4 4 4   (n=12)
+ *	        xsup 0 1 2 4 7 12
+ *	Note: dfs will be performed on supernode rep. relative to the new 
+ *	      row pivoting ordering
+ *
+ *   (xlsub,lsub): lsub[*] contains the compressed subscript of
+ *	rectangular supernodes; xlsub[j] points to the starting
+ *	location of the j-th column in lsub[*]. Note that xlsub 
+ *	is indexed by column.
+ *	Storage: original row subscripts
+ *
+ *      During the course of sparse LU factorization, we also use
+ *	(xlsub,lsub) for the purpose of symmetric pruning. For each
+ *	supernode {s,s+1,...,t=s+r} with first column s and last
+ *	column t, the subscript set
+ *		lsub[j], j=xlsub[s], .., xlsub[s+1]-1
+ *	is the structure of column s (i.e. structure of this supernode).
+ *	It is used for the storage of numerical values.
+ *	Furthermore,
+ *		lsub[j], j=xlsub[t], .., xlsub[t+1]-1
+ *	is the structure of the last column t of this supernode.
+ *	It is for the purpose of symmetric pruning. Therefore, the
+ *	structural subscripts can be rearranged without making physical
+ *	interchanges among the numerical values.
+ *
+ *	However, if the supernode has only one column, then we
+ *	only keep one set of subscripts. For any subscript interchange
+ *	performed, similar interchange must be done on the numerical
+ *	values.
+ *
+ *	The last column structures (for pruning) will be removed
+ *	after the numercial LU factorization phase.
+ *
+ *   (xlusup,lusup): lusup[*] contains the numerical values of the
+ *	rectangular supernodes; xlusup[j] points to the starting
+ *	location of the j-th column in storage vector lusup[*]
+ *	Note: xlusup is indexed by column.
+ *	Each rectangular supernode is stored by column-major
+ *	scheme, consistent with Fortran 2-dim array storage.
+ *
+ *   (xusub,ucol,usub): ucol[*] stores the numerical values of
+ *	U-columns outside the rectangular supernodes. The row
+ *	subscript of nonzero ucol[k] is stored in usub[k].
+ *	xusub[i] points to the starting location of column i in ucol.
+ *	Storage: new row subscripts; that is subscripts of PA.
+ * 
+ */ +#ifndef __SUPERLU_sSP_DEFS /* allow multiple inclusions */ +#define __SUPERLU_sSP_DEFS + +/* + * File name: ssp_defs.h + * Purpose: Sparse matrix types and function prototypes + * History: + */ + +#ifdef _CRAY +#include +#endif + +/* Define my integer type int_t */ +typedef int int_t; /* default */ + +#include +#include +#include +#include +#include +#include +#include "slu_Cnames.h" +#include "supermatrix.h" +#include "slu_util.h" + + +/* -------- Prototypes -------- */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \brief Driver routines */ +extern void +sgssv(superlu_options_t *, SuperMatrix *, int *, int *, SuperMatrix *, + SuperMatrix *, SuperMatrix *, SuperLUStat_t *, int *); +extern void +sgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *, + char *, float *, float *, SuperMatrix *, SuperMatrix *, + void *, int, SuperMatrix *, SuperMatrix *, + float *, float *, float *, float *, + GlobalLU_t *, mem_usage_t *, SuperLUStat_t *, int *); + /* ILU */ +extern void +sgsisv(superlu_options_t *, SuperMatrix *, int *, int *, SuperMatrix *, + SuperMatrix *, SuperMatrix *, SuperLUStat_t *, int *); +extern void +sgsisx(superlu_options_t *, SuperMatrix *, int *, int *, int *, + char *, float *, float *, SuperMatrix *, SuperMatrix *, + void *, int, SuperMatrix *, SuperMatrix *, float *, float *, + GlobalLU_t *, mem_usage_t *, SuperLUStat_t *, int *); + + +/*! \brief Supernodal LU factor related */ +extern void +sCreate_CompCol_Matrix(SuperMatrix *, int, int, int, float *, + int *, int *, Stype_t, Dtype_t, Mtype_t); +extern void +sCreate_CompRow_Matrix(SuperMatrix *, int, int, int, float *, + int *, int *, Stype_t, Dtype_t, Mtype_t); +extern void +sCopy_CompCol_Matrix(SuperMatrix *, SuperMatrix *); +extern void +sCreate_Dense_Matrix(SuperMatrix *, int, int, float *, int, + Stype_t, Dtype_t, Mtype_t); +extern void +sCreate_SuperNode_Matrix(SuperMatrix *, int, int, int, float *, + int *, int *, int *, int *, int *, + Stype_t, Dtype_t, Mtype_t); +extern void +sCopy_Dense_Matrix(int, int, float *, int, float *, int); + +extern void countnz (const int, int *, int *, int *, GlobalLU_t *); +extern void ilu_countnz (const int, int *, int *, GlobalLU_t *); +extern void fixupL (const int, const int *, GlobalLU_t *); + +extern void sallocateA (int, int, float **, int **, int **); +extern void sgstrf (superlu_options_t*, SuperMatrix*, + int, int, int*, void *, int, int *, int *, + SuperMatrix *, SuperMatrix *, GlobalLU_t *, + SuperLUStat_t*, int *); +extern int ssnode_dfs (const int, const int, const int *, const int *, + const int *, int *, int *, GlobalLU_t *); +extern int ssnode_bmod (const int, const int, const int, float *, + float *, GlobalLU_t *, SuperLUStat_t*); +extern void spanel_dfs (const int, const int, const int, SuperMatrix *, + int *, int *, float *, int *, int *, int *, + int *, int *, int *, int *, GlobalLU_t *); +extern void spanel_bmod (const int, const int, const int, const int, + float *, float *, int *, int *, + GlobalLU_t *, SuperLUStat_t*); +extern int scolumn_dfs (const int, const int, int *, int *, int *, int *, + int *, int *, int *, int *, int *, GlobalLU_t *); +extern int scolumn_bmod (const int, const int, float *, + float *, int *, int *, int, + GlobalLU_t *, SuperLUStat_t*); +extern int scopy_to_ucol (int, int, int *, int *, int *, + float *, GlobalLU_t *); +extern int spivotL (const int, const double, int *, int *, + int *, int *, int *, GlobalLU_t *, SuperLUStat_t*); +extern void spruneL (const int, const int *, const int, const int, + const int *, const int *, int *, GlobalLU_t *); +extern void sreadmt (int *, int *, int *, float **, int **, int **); +extern void sGenXtrue (int, int, float *, int); +extern void sFillRHS (trans_t, int, float *, int, SuperMatrix *, + SuperMatrix *); +extern void sgstrs (trans_t, SuperMatrix *, SuperMatrix *, int *, int *, + SuperMatrix *, SuperLUStat_t*, int *); +/* ILU */ +extern void sgsitrf (superlu_options_t*, SuperMatrix*, int, int, int*, + void *, int, int *, int *, SuperMatrix *, SuperMatrix *, + GlobalLU_t *, SuperLUStat_t*, int *); +extern int sldperm(int, int, int, int [], int [], float [], + int [], float [], float []); +extern int ilu_ssnode_dfs (const int, const int, const int *, const int *, + const int *, int *, GlobalLU_t *); +extern void ilu_spanel_dfs (const int, const int, const int, SuperMatrix *, + int *, int *, float *, float *, int *, int *, + int *, int *, int *, int *, GlobalLU_t *); +extern int ilu_scolumn_dfs (const int, const int, int *, int *, int *, + int *, int *, int *, int *, int *, + GlobalLU_t *); +extern int ilu_scopy_to_ucol (int, int, int *, int *, int *, + float *, int, milu_t, double, int, + float *, int *, GlobalLU_t *, float *); +extern int ilu_spivotL (const int, const double, int *, int *, int, int *, + int *, int *, int *, double, milu_t, + float, GlobalLU_t *, SuperLUStat_t*); +extern int ilu_sdrop_row (superlu_options_t *, int, int, double, + int, int *, double *, GlobalLU_t *, + float *, float *, int); + + +/*! \brief Driver related */ + +extern void sgsequ (SuperMatrix *, float *, float *, float *, + float *, float *, int *); +extern void slaqgs (SuperMatrix *, float *, float *, float, + float, float, char *); +extern void sgscon (char *, SuperMatrix *, SuperMatrix *, + float, float *, SuperLUStat_t*, int *); +extern float sPivotGrowth(int, SuperMatrix *, int *, + SuperMatrix *, SuperMatrix *); +extern void sgsrfs (trans_t, SuperMatrix *, SuperMatrix *, + SuperMatrix *, int *, int *, char *, float *, + float *, SuperMatrix *, SuperMatrix *, + float *, float *, SuperLUStat_t*, int *); + +extern int sp_strsv (char *, char *, char *, SuperMatrix *, + SuperMatrix *, float *, SuperLUStat_t*, int *); +extern int sp_sgemv (char *, float, SuperMatrix *, float *, + int, float, float *, int); + +extern int sp_sgemm (char *, char *, int, int, int, float, + SuperMatrix *, float *, int, float, + float *, int); +extern float smach(char *); /* from C99 standard, in float.h */ + +/*! \brief Memory-related */ +extern int sLUMemInit (fact_t, void *, int, int, int, int, int, + float, SuperMatrix *, SuperMatrix *, + GlobalLU_t *, int **, float **); +extern void sSetRWork (int, int, float *, float **, float **); +extern void sLUWorkFree (int *, float *, GlobalLU_t *); +extern int sLUMemXpand (int, int, MemType, int *, GlobalLU_t *); + +extern float *floatMalloc(int); +extern float *floatCalloc(int); +extern int smemory_usage(const int, const int, const int, const int); +extern int sQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *); +extern int ilu_sQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *); + +/*! \brief Auxiliary routines */ +extern void sreadhb(FILE *, int *, int *, int *, float **, int **, int **); +extern void sreadrb(int *, int *, int *, float **, int **, int **); +extern void sreadtriple(int *, int *, int *, float **, int **, int **); +extern void sCompRow_to_CompCol(int, int, int, float*, int*, int*, + float **, int **, int **); +extern void sfill (float *, int, float); +extern void sinf_norm_error (int, SuperMatrix *, float *); +extern float sqselect(int, float *, int); + + +/*! \brief Routines for debugging */ +extern void sPrint_CompCol_Matrix(char *, SuperMatrix *); +extern void sPrint_SuperNode_Matrix(char *, SuperMatrix *); +extern void sPrint_Dense_Matrix(char *, SuperMatrix *); +extern void sprint_lu_col(char *, int, int, int *, GlobalLU_t *); +extern int print_double_vec(char *, int, double *); +extern void scheck_tempv(int, float *); + +/*! \brief BLAS */ + +extern int sgemm_(const char*, const char*, const int*, const int*, const int*, + const float*, const float*, const int*, const float*, + const int*, const float*, float*, const int*); +extern int strsv_(char*, char*, char*, int*, float*, int*, + float*, int*); +extern int strsm_(char*, char*, char*, char*, int*, int*, + float*, float*, int*, float*, int*); +extern int sgemv_(char *, int *, int *, float *, float *a, int *, + float *, int *, float *, float *, int *); + +#ifdef __cplusplus + } +#endif + +#endif /* __SUPERLU_sSP_DEFS */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/slu_util.h b/src/Libraries/superlu-5.2.1/SRC/slu_util.h new file mode 100644 index 00000000..31776294 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/slu_util.h @@ -0,0 +1,416 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/** @file slu_util.h + * \brief Utility header file + * + * -- SuperLU routine (version 4.1) -- + * Univ. of California Berkeley, Xerox Palo Alto Research Center, + * and Lawrence Berkeley National Lab. + * November, 2010 + * + */ + +#ifndef __SUPERLU_UTIL /* allow multiple inclusions */ +#define __SUPERLU_UTIL + +#include +#include +#include +/* +#ifndef __STDC__ +#include +#endif +*/ +#include +#include "superlu_enum_consts.h" + + +/*********************************************************************** + * Macros + ***********************************************************************/ +/* + * You can support older version of SuperLU. + * At compile-time, you can catch the new release as: + * #ifdef SUPERLU_MAIN_VERSION == 5 + * use the new interface + * #else + * use the old interface + * #endif + * Versions 4.x and earlier do not include a #define'd version numbers. + */ +#define SUPERLU_MAJOR_VERSION 5 +#define SUPERLU_MINOR_VERSION 2 +#define SUPERLU_PATCH_VERSION 1 + + +#define FIRSTCOL_OF_SNODE(i) (xsup[i]) +/* No of marker arrays used in the symbolic factorization, + each of size n */ +#define NO_MARKER 3 +#define NUM_TEMPV(m,w,t,b) ( SUPERLU_MAX(m, (t + b)*w) ) + +#ifndef USER_ABORT +#define USER_ABORT(msg) superlu_abort_and_exit(msg) +#endif + +#define ABORT(err_msg) \ + { char msg[256];\ + sprintf(msg,"%s at line %d in file %s\n",err_msg,__LINE__, __FILE__);\ + USER_ABORT(msg); } + + +#ifndef USER_MALLOC +#if 1 +#define USER_MALLOC(size) superlu_malloc(size) +#else +/* The following may check out some uninitialized data */ +#define USER_MALLOC(size) memset (superlu_malloc(size), '\x0F', size) +#endif +#endif + +#define SUPERLU_MALLOC(size) USER_MALLOC(size) + +#ifndef USER_FREE +#define USER_FREE(addr) superlu_free(addr) +#endif + +#define SUPERLU_FREE(addr) USER_FREE(addr) + +#define CHECK_MALLOC(where) { \ + extern int superlu_malloc_total; \ + printf("%s: malloc_total %d Bytes\n", \ + where, superlu_malloc_total); \ +} + +#define SUPERLU_MAX(x, y) ( (x) > (y) ? (x) : (y) ) +#define SUPERLU_MIN(x, y) ( (x) < (y) ? (x) : (y) ) + +/********************************************************* + * Macros used for easy access of sparse matrix entries. * + *********************************************************/ +#define L_SUB_START(col) ( Lstore->rowind_colptr[col] ) +#define L_SUB(ptr) ( Lstore->rowind[ptr] ) +#define L_NZ_START(col) ( Lstore->nzval_colptr[col] ) +#define L_FST_SUPC(superno) ( Lstore->sup_to_col[superno] ) +#define U_NZ_START(col) ( Ustore->colptr[col] ) +#define U_SUB(ptr) ( Ustore->rowind[ptr] ) + + +/*********************************************************************** + * Constants + ***********************************************************************/ +#define EMPTY (-1) +/*#define NO (-1)*/ +#define FALSE 0 +#define TRUE 1 + +#define NO_MEMTYPE 4 /* 0: lusup; + 1: ucol; + 2: lsub; + 3: usub */ + +#define GluIntArray(n) (5 * (n) + 5) + +/* Dropping rules */ +#define NODROP ( 0x0000 ) +#define DROP_BASIC ( 0x0001 ) /* ILU(tau) */ +#define DROP_PROWS ( 0x0002 ) /* ILUTP: keep p maximum rows */ +#define DROP_COLUMN ( 0x0004 ) /* ILUTP: for j-th column, + p = gamma * nnz(A(:,j)) */ +#define DROP_AREA ( 0x0008 ) /* ILUTP: for j-th column, use + nnz(F(:,1:j)) / nnz(A(:,1:j)) + to limit memory growth */ +#define DROP_SECONDARY ( 0x000E ) /* PROWS | COLUMN | AREA */ +#define DROP_DYNAMIC ( 0x0010 ) /* adaptive tau */ +#define DROP_INTERP ( 0x0100 ) /* use interpolation */ + + +#if 1 +#define MILU_ALPHA (1.0e-2) /* multiple of drop_sum to be added to diagonal */ +#else +#define MILU_ALPHA 1.0 /* multiple of drop_sum to be added to diagonal */ +#endif + + +/*********************************************************************** + * Type definitions + ***********************************************************************/ +typedef float flops_t; +typedef unsigned char Logical; + +/* + *-- This contains the options used to control the solution process. + * + * Fact (fact_t) + * Specifies whether or not the factored form of the matrix + * A is supplied on entry, and if not, how the matrix A should + * be factorizaed. + * = DOFACT: The matrix A will be factorized from scratch, and the + * factors will be stored in L and U. + * = SamePattern: The matrix A will be factorized assuming + * that a factorization of a matrix with the same sparsity + * pattern was performed prior to this one. Therefore, this + * factorization will reuse column permutation vector + * ScalePermstruct->perm_c and the column elimination tree + * LUstruct->etree. + * = SamePattern_SameRowPerm: The matrix A will be factorized + * assuming that a factorization of a matrix with the same + * sparsity pattern and similar numerical values was performed + * prior to this one. Therefore, this factorization will reuse + * both row and column scaling factors R and C, both row and + * column permutation vectors perm_r and perm_c, and the + * L & U data structures set up from the previous factorization. + * = FACTORED: On entry, L, U, perm_r and perm_c contain the + * factored form of A. If DiagScale is not NOEQUIL, the matrix + * A has been equilibrated with scaling factors R and C. + * + * Equil (yes_no_t) + * Specifies whether to equilibrate the system (scale A's row and + * columns to have unit norm). + * + * ColPerm (colperm_t) + * Specifies what type of column permutation to use to reduce fill. + * = NATURAL: use the natural ordering + * = MMD_ATA: use minimum degree ordering on structure of A'*A + * = MMD_AT_PLUS_A: use minimum degree ordering on structure of A'+A + * = COLAMD: use approximate minimum degree column ordering + * = MY_PERMC: use the ordering specified by the user + * + * Trans (trans_t) + * Specifies the form of the system of equations: + * = NOTRANS: A * X = B (No transpose) + * = TRANS: A**T * X = B (Transpose) + * = CONJ: A**H * X = B (Transpose) + * + * IterRefine (IterRefine_t) + * Specifies whether to perform iterative refinement. + * = NO: no iterative refinement + * = SLU_SINGLE: perform iterative refinement in single precision + * = SLU_DOUBLE: perform iterative refinement in double precision + * = SLU_EXTRA: perform iterative refinement in extra precision + * + * DiagPivotThresh (double, in [0.0, 1.0]) (only for sequential SuperLU) + * Specifies the threshold used for a diagonal entry to be an + * acceptable pivot. + * + * SymmetricMode (yest_no_t) + * Specifies whether to use symmetric mode. Symmetric mode gives + * preference to diagonal pivots, and uses an (A'+A)-based column + * permutation algorithm. + * + * PivotGrowth (yes_no_t) + * Specifies whether to compute the reciprocal pivot growth. + * + * ConditionNumber (ues_no_t) + * Specifies whether to compute the reciprocal condition number. + * + * RowPerm (rowperm_t) (only for SuperLU_DIST or ILU) + * Specifies whether to permute rows of the original matrix. + * = NO: not to permute the rows + * = LargeDiag: make the diagonal large relative to the off-diagonal + * = MY_PERMR: use the permutation given by the user + * + * ILU_DropRule (int) + * Specifies the dropping rule: + * = DROP_BASIC: Basic dropping rule, supernodal based ILUTP(tau). + * = DROP_PROWS: Supernodal based ILUTP(p,tau), p = gamma * nnz(A)/n. + * = DROP_COLUMN: Variant of ILUTP(p,tau), for j-th column, + * p = gamma * nnz(A(:,j)). + * = DROP_AREA: Variation of ILUTP, for j-th column, use + * nnz(F(:,1:j)) / nnz(A(:,1:j)) to control memory. + * = DROP_DYNAMIC: Modify the threshold tau during factorizaion: + * If nnz(L(:,1:j)) / nnz(A(:,1:j)) > gamma + * tau_L(j) := MIN(tau_0, tau_L(j-1) * 2); + * Otherwise + * tau_L(j) := MAX(tau_0, tau_L(j-1) / 2); + * tau_U(j) uses the similar rule. + * NOTE: the thresholds used by L and U are separate. + * = DROP_INTERP: Compute the second dropping threshold by + * interpolation instead of sorting (default). + * In this case, the actual fill ratio is not + * guaranteed to be smaller than gamma. + * Note: DROP_PROWS, DROP_COLUMN and DROP_AREA are mutually exclusive. + * ( Default: DROP_BASIC | DROP_AREA ) + * + * ILU_DropTol (double) + * numerical threshold for dropping. + * + * ILU_FillFactor (double) + * Gamma in the secondary dropping. + * + * ILU_Norm (norm_t) + * Specify which norm to use to measure the row size in a + * supernode: infinity-norm, 1-norm, or 2-norm. + * + * ILU_FillTol (double) + * numerical threshold for zero pivot perturbation. + * + * ILU_MILU (milu_t) + * Specifies which version of MILU to use. + * + * ILU_MILU_Dim (double) + * Dimension of the PDE if available. + * + * ReplaceTinyPivot (yes_no_t) (only for SuperLU_DIST) + * Specifies whether to replace the tiny diagonals by + * sqrt(epsilon)*||A|| during LU factorization. + * + * SolveInitialized (yes_no_t) (only for SuperLU_DIST) + * Specifies whether the initialization has been performed to the + * triangular solve. + * + * RefineInitialized (yes_no_t) (only for SuperLU_DIST) + * Specifies whether the initialization has been performed to the + * sparse matrix-vector multiplication routine needed in iterative + * refinement. + * + * PrintStat (yes_no_t) + * Specifies whether to print the solver's statistics. + */ +typedef struct { + fact_t Fact; + yes_no_t Equil; + colperm_t ColPerm; + trans_t Trans; + IterRefine_t IterRefine; + double DiagPivotThresh; + yes_no_t SymmetricMode; + yes_no_t PivotGrowth; + yes_no_t ConditionNumber; + rowperm_t RowPerm; + int ILU_DropRule; + double ILU_DropTol; /* threshold for dropping */ + double ILU_FillFactor; /* gamma in the secondary dropping */ + norm_t ILU_Norm; /* infinity-norm, 1-norm, or 2-norm */ + double ILU_FillTol; /* threshold for zero pivot perturbation */ + milu_t ILU_MILU; + double ILU_MILU_Dim; /* Dimension of PDE (if available) */ + yes_no_t ParSymbFact; + yes_no_t ReplaceTinyPivot; /* used in SuperLU_DIST */ + yes_no_t SolveInitialized; + yes_no_t RefineInitialized; + yes_no_t PrintStat; + int nnzL, nnzU; /* used to store nnzs for now */ + int num_lookaheads; /* num of levels in look-ahead */ + yes_no_t lookahead_etree; /* use etree computed from the + serial symbolic factorization */ + yes_no_t SymPattern; /* symmetric factorization */ +} superlu_options_t; + +/*! \brief Headers for 4 types of dynamatically managed memory */ +typedef struct e_node { + int size; /* length of the memory that has been used */ + void *mem; /* pointer to the new malloc'd store */ +} ExpHeader; + +typedef struct { + int size; + int used; + int top1; /* grow upward, relative to &array[0] */ + int top2; /* grow downward */ + void *array; +} LU_stack_t; + +typedef struct { + int *panel_histo; /* histogram of panel size distribution */ + double *utime; /* running time at various phases */ + flops_t *ops; /* operation count at various phases */ + int TinyPivots; /* number of tiny pivots */ + int RefineSteps; /* number of iterative refinement steps */ + int expansions; /* number of memory expansions */ +} SuperLUStat_t; + +typedef struct { + float for_lu; + float total_needed; +} mem_usage_t; + + +typedef struct { + int *xsup; /* supernode and column mapping */ + int *supno; + int *lsub; /* compressed L subscripts */ + int *xlsub; + void *lusup; /* L supernodes */ + int *xlusup; + void *ucol; /* U columns */ + int *usub; + int *xusub; + int nzlmax; /* current max size of lsub */ + int nzumax; /* " " " ucol */ + int nzlumax; /* " " " lusup */ + int n; /* number of columns in the matrix */ + LU_space_t MemModel; /* 0 - system malloc'd; 1 - user provided */ + int num_expansions; + ExpHeader *expanders; /* Array of pointers to 4 types of memory */ + LU_stack_t stack; /* use user supplied memory */ +} GlobalLU_t; + + + +/*********************************************************************** + * Prototypes + ***********************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +extern int input_error(char *, int *); + +extern void Destroy_SuperMatrix_Store(SuperMatrix *); +extern void Destroy_CompCol_Matrix(SuperMatrix *); +extern void Destroy_CompRow_Matrix(SuperMatrix *); +extern void Destroy_SuperNode_Matrix(SuperMatrix *); +extern void Destroy_CompCol_Permuted(SuperMatrix *); +extern void Destroy_Dense_Matrix(SuperMatrix *); +extern void get_perm_c(int, SuperMatrix *, int *); +extern void set_default_options(superlu_options_t *options); +extern void ilu_set_default_options(superlu_options_t *options); +extern void sp_preorder (superlu_options_t *, SuperMatrix*, int*, int*, + SuperMatrix*); +extern void superlu_abort_and_exit(char*); +extern void *superlu_malloc (size_t); +extern int *intMalloc (int); +extern int *intCalloc (int); +extern void superlu_free (void*); +extern void SetIWork (int, int, int, int *, int **, int **, int **, + int **, int **, int **, int **); +extern int sp_coletree (int *, int *, int *, int, int, int *); +extern void relax_snode (const int, int *, const int, int *, int *); +extern void heap_relax_snode (const int, int *, const int, int *, int *); +extern int mark_relax(int, int *, int *, int *, int *, int *, int *); +extern void ilu_relax_snode (const int, int *, const int, int *, + int *, int *); +extern void ilu_heap_relax_snode (const int, int *, const int, int *, + int *, int*); +extern void resetrep_col (const int, const int *, int *); +extern int spcoletree (int *, int *, int *, int, int, int *); +extern int *TreePostorder (int, int *); +extern double SuperLU_timer_ (); +extern int sp_ienv (int); +extern int xerbla_ (char *, int *); +extern void ifill (int *, int, int); +extern void snode_profile (int, int *); +extern void super_stats (int, int *); +extern void check_repfnz(int, int, int, int *); +extern void PrintSumm (char *, int, int, int); +extern void StatInit(SuperLUStat_t *); +extern void StatPrint (SuperLUStat_t *); +extern void StatFree(SuperLUStat_t *); +extern void print_panel_seg(int, int, int, int, int *, int *); +extern int print_int_vec(char *,int, int *); +extern int slu_PrintInt10(char *, int, int *); + +#ifdef __cplusplus + } +#endif + +#endif /* __SUPERLU_UTIL */ diff --git a/src/Libraries/superlu-5.2.1/SRC/slu_zdefs.h b/src/Libraries/superlu-5.2.1/SRC/slu_zdefs.h new file mode 100644 index 00000000..577c5aa8 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/slu_zdefs.h @@ -0,0 +1,285 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file slu_zdefs.h + * \brief Header file for real operations + * + *
 
+ * -- SuperLU routine (version 4.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November, 2010
+ * 
+ * Global data structures used in LU factorization -
+ * 
+ *   nsuper: #supernodes = nsuper + 1, numbered [0, nsuper].
+ *   (xsup,supno): supno[i] is the supernode no to which i belongs;
+ *	xsup(s) points to the beginning of the s-th supernode.
+ *	e.g.   supno 0 1 2 2 3 3 3 4 4 4 4 4   (n=12)
+ *	        xsup 0 1 2 4 7 12
+ *	Note: dfs will be performed on supernode rep. relative to the new 
+ *	      row pivoting ordering
+ *
+ *   (xlsub,lsub): lsub[*] contains the compressed subscript of
+ *	rectangular supernodes; xlsub[j] points to the starting
+ *	location of the j-th column in lsub[*]. Note that xlsub 
+ *	is indexed by column.
+ *	Storage: original row subscripts
+ *
+ *      During the course of sparse LU factorization, we also use
+ *	(xlsub,lsub) for the purpose of symmetric pruning. For each
+ *	supernode {s,s+1,...,t=s+r} with first column s and last
+ *	column t, the subscript set
+ *		lsub[j], j=xlsub[s], .., xlsub[s+1]-1
+ *	is the structure of column s (i.e. structure of this supernode).
+ *	It is used for the storage of numerical values.
+ *	Furthermore,
+ *		lsub[j], j=xlsub[t], .., xlsub[t+1]-1
+ *	is the structure of the last column t of this supernode.
+ *	It is for the purpose of symmetric pruning. Therefore, the
+ *	structural subscripts can be rearranged without making physical
+ *	interchanges among the numerical values.
+ *
+ *	However, if the supernode has only one column, then we
+ *	only keep one set of subscripts. For any subscript interchange
+ *	performed, similar interchange must be done on the numerical
+ *	values.
+ *
+ *	The last column structures (for pruning) will be removed
+ *	after the numercial LU factorization phase.
+ *
+ *   (xlusup,lusup): lusup[*] contains the numerical values of the
+ *	rectangular supernodes; xlusup[j] points to the starting
+ *	location of the j-th column in storage vector lusup[*]
+ *	Note: xlusup is indexed by column.
+ *	Each rectangular supernode is stored by column-major
+ *	scheme, consistent with Fortran 2-dim array storage.
+ *
+ *   (xusub,ucol,usub): ucol[*] stores the numerical values of
+ *	U-columns outside the rectangular supernodes. The row
+ *	subscript of nonzero ucol[k] is stored in usub[k].
+ *	xusub[i] points to the starting location of column i in ucol.
+ *	Storage: new row subscripts; that is subscripts of PA.
+ * 
+ */ +#ifndef __SUPERLU_zSP_DEFS /* allow multiple inclusions */ +#define __SUPERLU_zSP_DEFS + +/* + * File name: zsp_defs.h + * Purpose: Sparse matrix types and function prototypes + * History: + */ + +#ifdef _CRAY +#include +#endif + +/* Define my integer type int_t */ +typedef int int_t; /* default */ + +#include +#include +#include +#include +#include +#include +#include "slu_Cnames.h" +#include "supermatrix.h" +#include "slu_util.h" +#include "slu_dcomplex.h" + + +/* -------- Prototypes -------- */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \brief Driver routines */ +extern void +zgssv(superlu_options_t *, SuperMatrix *, int *, int *, SuperMatrix *, + SuperMatrix *, SuperMatrix *, SuperLUStat_t *, int *); +extern void +zgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *, + char *, double *, double *, SuperMatrix *, SuperMatrix *, + void *, int, SuperMatrix *, SuperMatrix *, + double *, double *, double *, double *, + GlobalLU_t *, mem_usage_t *, SuperLUStat_t *, int *); + /* ILU */ +extern void +zgsisv(superlu_options_t *, SuperMatrix *, int *, int *, SuperMatrix *, + SuperMatrix *, SuperMatrix *, SuperLUStat_t *, int *); +extern void +zgsisx(superlu_options_t *, SuperMatrix *, int *, int *, int *, + char *, double *, double *, SuperMatrix *, SuperMatrix *, + void *, int, SuperMatrix *, SuperMatrix *, double *, double *, + GlobalLU_t *, mem_usage_t *, SuperLUStat_t *, int *); + + +/*! \brief Supernodal LU factor related */ +extern void +zCreate_CompCol_Matrix(SuperMatrix *, int, int, int, doublecomplex *, + int *, int *, Stype_t, Dtype_t, Mtype_t); +extern void +zCreate_CompRow_Matrix(SuperMatrix *, int, int, int, doublecomplex *, + int *, int *, Stype_t, Dtype_t, Mtype_t); +extern void +zCopy_CompCol_Matrix(SuperMatrix *, SuperMatrix *); +extern void +zCreate_Dense_Matrix(SuperMatrix *, int, int, doublecomplex *, int, + Stype_t, Dtype_t, Mtype_t); +extern void +zCreate_SuperNode_Matrix(SuperMatrix *, int, int, int, doublecomplex *, + int *, int *, int *, int *, int *, + Stype_t, Dtype_t, Mtype_t); +extern void +zCopy_Dense_Matrix(int, int, doublecomplex *, int, doublecomplex *, int); + +extern void countnz (const int, int *, int *, int *, GlobalLU_t *); +extern void ilu_countnz (const int, int *, int *, GlobalLU_t *); +extern void fixupL (const int, const int *, GlobalLU_t *); + +extern void zallocateA (int, int, doublecomplex **, int **, int **); +extern void zgstrf (superlu_options_t*, SuperMatrix*, + int, int, int*, void *, int, int *, int *, + SuperMatrix *, SuperMatrix *, GlobalLU_t *, + SuperLUStat_t*, int *); +extern int zsnode_dfs (const int, const int, const int *, const int *, + const int *, int *, int *, GlobalLU_t *); +extern int zsnode_bmod (const int, const int, const int, doublecomplex *, + doublecomplex *, GlobalLU_t *, SuperLUStat_t*); +extern void zpanel_dfs (const int, const int, const int, SuperMatrix *, + int *, int *, doublecomplex *, int *, int *, int *, + int *, int *, int *, int *, GlobalLU_t *); +extern void zpanel_bmod (const int, const int, const int, const int, + doublecomplex *, doublecomplex *, int *, int *, + GlobalLU_t *, SuperLUStat_t*); +extern int zcolumn_dfs (const int, const int, int *, int *, int *, int *, + int *, int *, int *, int *, int *, GlobalLU_t *); +extern int zcolumn_bmod (const int, const int, doublecomplex *, + doublecomplex *, int *, int *, int, + GlobalLU_t *, SuperLUStat_t*); +extern int zcopy_to_ucol (int, int, int *, int *, int *, + doublecomplex *, GlobalLU_t *); +extern int zpivotL (const int, const double, int *, int *, + int *, int *, int *, GlobalLU_t *, SuperLUStat_t*); +extern void zpruneL (const int, const int *, const int, const int, + const int *, const int *, int *, GlobalLU_t *); +extern void zreadmt (int *, int *, int *, doublecomplex **, int **, int **); +extern void zGenXtrue (int, int, doublecomplex *, int); +extern void zFillRHS (trans_t, int, doublecomplex *, int, SuperMatrix *, + SuperMatrix *); +extern void zgstrs (trans_t, SuperMatrix *, SuperMatrix *, int *, int *, + SuperMatrix *, SuperLUStat_t*, int *); +/* ILU */ +extern void zgsitrf (superlu_options_t*, SuperMatrix*, int, int, int*, + void *, int, int *, int *, SuperMatrix *, SuperMatrix *, + GlobalLU_t *, SuperLUStat_t*, int *); +extern int zldperm(int, int, int, int [], int [], doublecomplex [], + int [], double [], double []); +extern int ilu_zsnode_dfs (const int, const int, const int *, const int *, + const int *, int *, GlobalLU_t *); +extern void ilu_zpanel_dfs (const int, const int, const int, SuperMatrix *, + int *, int *, doublecomplex *, double *, int *, int *, + int *, int *, int *, int *, GlobalLU_t *); +extern int ilu_zcolumn_dfs (const int, const int, int *, int *, int *, + int *, int *, int *, int *, int *, + GlobalLU_t *); +extern int ilu_zcopy_to_ucol (int, int, int *, int *, int *, + doublecomplex *, int, milu_t, double, int, + doublecomplex *, int *, GlobalLU_t *, double *); +extern int ilu_zpivotL (const int, const double, int *, int *, int, int *, + int *, int *, int *, double, milu_t, + doublecomplex, GlobalLU_t *, SuperLUStat_t*); +extern int ilu_zdrop_row (superlu_options_t *, int, int, double, + int, int *, double *, GlobalLU_t *, + double *, double *, int); + + +/*! \brief Driver related */ + +extern void zgsequ (SuperMatrix *, double *, double *, double *, + double *, double *, int *); +extern void zlaqgs (SuperMatrix *, double *, double *, double, + double, double, char *); +extern void zgscon (char *, SuperMatrix *, SuperMatrix *, + double, double *, SuperLUStat_t*, int *); +extern double zPivotGrowth(int, SuperMatrix *, int *, + SuperMatrix *, SuperMatrix *); +extern void zgsrfs (trans_t, SuperMatrix *, SuperMatrix *, + SuperMatrix *, int *, int *, char *, double *, + double *, SuperMatrix *, SuperMatrix *, + double *, double *, SuperLUStat_t*, int *); + +extern int sp_ztrsv (char *, char *, char *, SuperMatrix *, + SuperMatrix *, doublecomplex *, SuperLUStat_t*, int *); +extern int sp_zgemv (char *, doublecomplex, SuperMatrix *, doublecomplex *, + int, doublecomplex, doublecomplex *, int); + +extern int sp_zgemm (char *, char *, int, int, int, doublecomplex, + SuperMatrix *, doublecomplex *, int, doublecomplex, + doublecomplex *, int); +extern double dmach(char *); /* from C99 standard, in float.h */ + +/*! \brief Memory-related */ +extern int zLUMemInit (fact_t, void *, int, int, int, int, int, + double, SuperMatrix *, SuperMatrix *, + GlobalLU_t *, int **, doublecomplex **); +extern void zSetRWork (int, int, doublecomplex *, doublecomplex **, doublecomplex **); +extern void zLUWorkFree (int *, doublecomplex *, GlobalLU_t *); +extern int zLUMemXpand (int, int, MemType, int *, GlobalLU_t *); + +extern doublecomplex *doublecomplexMalloc(int); +extern doublecomplex *doublecomplexCalloc(int); +extern double *doubleMalloc(int); +extern double *doubleCalloc(int); +extern int zmemory_usage(const int, const int, const int, const int); +extern int zQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *); +extern int ilu_zQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *); + +/*! \brief Auxiliary routines */ +extern void zreadhb(FILE *, int *, int *, int *, doublecomplex **, int **, int **); +extern void zreadrb(int *, int *, int *, doublecomplex **, int **, int **); +extern void zreadtriple(int *, int *, int *, doublecomplex **, int **, int **); +extern void zCompRow_to_CompCol(int, int, int, doublecomplex*, int*, int*, + doublecomplex **, int **, int **); +extern void zfill (doublecomplex *, int, doublecomplex); +extern void zinf_norm_error (int, SuperMatrix *, doublecomplex *); +extern double dqselect(int, double *, int); + + +/*! \brief Routines for debugging */ +extern void zPrint_CompCol_Matrix(char *, SuperMatrix *); +extern void zPrint_SuperNode_Matrix(char *, SuperMatrix *); +extern void zPrint_Dense_Matrix(char *, SuperMatrix *); +extern void zprint_lu_col(char *, int, int, int *, GlobalLU_t *); +extern int print_double_vec(char *, int, double *); +extern void zcheck_tempv(int, doublecomplex *); + +/*! \brief BLAS */ + +extern int zgemm_(const char*, const char*, const int*, const int*, const int*, + const doublecomplex*, const doublecomplex*, const int*, const doublecomplex*, + const int*, const doublecomplex*, doublecomplex*, const int*); +extern int ztrsv_(char*, char*, char*, int*, doublecomplex*, int*, + doublecomplex*, int*); +extern int ztrsm_(char*, char*, char*, char*, int*, int*, + doublecomplex*, doublecomplex*, int*, doublecomplex*, int*); +extern int zgemv_(char *, int *, int *, doublecomplex *, doublecomplex *a, int *, + doublecomplex *, int *, doublecomplex *, doublecomplex *, int *); + +#ifdef __cplusplus + } +#endif + +#endif /* __SUPERLU_zSP_DEFS */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/smach.c b/src/Libraries/superlu-5.2.1/SRC/smach.c new file mode 100644 index 00000000..fff6c5fe --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/smach.c @@ -0,0 +1,93 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +#include +#include +#include + +float smach(char *cmach) +{ +/* -- SuperLU auxiliary routine (version 5.0) -- + This uses C99 standard constants, and is thread safe. + + Must be compiled with "-std=c99" flag. + + + Purpose + ======= + + SMACH returns single precision machine parameters. + + Arguments + ========= + + CMACH (input) CHARACTER*1 + Specifies the value to be returned by SMACH: + = 'E' or 'e', SMACH := eps + = 'S' or 's , SMACH := sfmin + = 'B' or 'b', SMACH := base + = 'P' or 'p', SMACH := eps*base + = 'N' or 'n', SMACH := t + = 'R' or 'r', SMACH := rnd + = 'M' or 'm', SMACH := emin + = 'U' or 'u', SMACH := rmin + = 'L' or 'l', SMACH := emax + = 'O' or 'o', SMACH := rmax + + where + + eps = relative machine precision + sfmin = safe minimum, such that 1/sfmin does not overflow + base = base of the machine + prec = eps*base + t = number of (base) digits in the mantissa + rnd = 1.0 when rounding occurs in addition, 0.0 otherwise + emin = minimum exponent before (gradual) underflow + rmin = underflow threshold - base**(emin-1) + emax = largest exponent before overflow + rmax = overflow threshold - (base**emax)*(1-eps) + + ===================================================================== +*/ + + float sfmin, small, rmach; + + if (strncmp(cmach, "E", 1)==0) { + rmach = FLT_EPSILON * 0.5; + } else if (strncmp(cmach, "S", 1)==0) { + sfmin = FLT_MIN; + small = 1. / FLT_MAX; + if (small >= sfmin) { + /* Use SMALL plus a bit, to avoid the possibility of rounding + causing overflow when computing 1/sfmin. */ + sfmin = small * (FLT_EPSILON*0.5 + 1.); + } + rmach = sfmin; + } else if (strncmp(cmach, "B", 1)==0) { + rmach = FLT_RADIX; + } else if (strncmp(cmach, "P", 1)==0) { + rmach = FLT_EPSILON * 0.5 * FLT_RADIX; + } else if (strncmp(cmach, "N", 1)==0) { + rmach = FLT_MANT_DIG; + } else if (strncmp(cmach, "R", 1)==0) { + rmach = FLT_ROUNDS; + } else if (strncmp(cmach, "M", 1)==0) { + rmach = FLT_MIN_EXP; + } else if (strncmp(cmach, "U", 1)==0) { + rmach = FLT_MIN; + } else if (strncmp(cmach, "L", 1)==0) { + rmach = FLT_MAX_EXP; + } else if (strncmp(cmach, "O", 1)==0) { + rmach = FLT_MAX; + } + + return rmach; + +} /* end smach */ diff --git a/src/Libraries/superlu-5.2.1/SRC/smemory.c b/src/Libraries/superlu-5.2.1/SRC/smemory.c new file mode 100644 index 00000000..14414b50 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/smemory.c @@ -0,0 +1,710 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file smemory.c + * \brief Memory details + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ +#include "slu_sdefs.h" + + +/* Internal prototypes */ +void *sexpand (int *, MemType,int, int, GlobalLU_t *); +int sLUWorkInit (int, int, int, int **, float **, GlobalLU_t *); +void copy_mem_float (int, void *, void *); +void sStackCompress (GlobalLU_t *); +void sSetupSpace (void *, int, GlobalLU_t *); +void *suser_malloc (int, int, GlobalLU_t *); +void suser_free (int, int, GlobalLU_t *); + +/* External prototypes (in memory.c - prec-independent) */ +extern void copy_mem_int (int, void *, void *); +extern void user_bcopy (char *, char *, int); + + +/* Macros to manipulate stack */ +#define StackFull(x) ( x + Glu->stack.used >= Glu->stack.size ) +#define NotDoubleAlign(addr) ( (intptr_t)addr & 7 ) +#define DoubleAlign(addr) ( ((intptr_t)addr + 7) & ~7L ) +#define TempSpace(m, w) ( (2*w + 4 + NO_MARKER) * m * sizeof(int) + \ + (w + 1) * m * sizeof(float) ) +#define Reduce(alpha) ((alpha + 1) / 2) /* i.e. (alpha-1)/2 + 1 */ + + + + +/*! \brief Setup the memory model to be used for factorization. + * + * lwork = 0: use system malloc; + * lwork > 0: use user-supplied work[] space. + */ +void sSetupSpace(void *work, int lwork, GlobalLU_t *Glu) +{ + if ( lwork == 0 ) { + Glu->MemModel = SYSTEM; /* malloc/free */ + } else if ( lwork > 0 ) { + Glu->MemModel = USER; /* user provided space */ + Glu->stack.used = 0; + Glu->stack.top1 = 0; + Glu->stack.top2 = (lwork/4)*4; /* must be word addressable */ + Glu->stack.size = Glu->stack.top2; + Glu->stack.array = (void *) work; + } +} + + + +void *suser_malloc(int bytes, int which_end, GlobalLU_t *Glu) +{ + void *buf; + + if ( StackFull(bytes) ) return (NULL); + + if ( which_end == HEAD ) { + buf = (char*) Glu->stack.array + Glu->stack.top1; + Glu->stack.top1 += bytes; + } else { + Glu->stack.top2 -= bytes; + buf = (char*) Glu->stack.array + Glu->stack.top2; + } + + Glu->stack.used += bytes; + return buf; +} + + +void suser_free(int bytes, int which_end, GlobalLU_t *Glu) +{ + if ( which_end == HEAD ) { + Glu->stack.top1 -= bytes; + } else { + Glu->stack.top2 += bytes; + } + Glu->stack.used -= bytes; +} + + + +/*! \brief + * + *
+ * mem_usage consists of the following fields:
+ *    - for_lu (float)
+ *      The amount of space used in bytes for the L\U data structures.
+ *    - total_needed (float)
+ *      The amount of space needed in bytes to perform factorization.
+ * 
+ */ +int sQuerySpace(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage) +{ + SCformat *Lstore; + NCformat *Ustore; + register int n, iword, dword, panel_size = sp_ienv(1); + + Lstore = L->Store; + Ustore = U->Store; + n = L->ncol; + iword = sizeof(int); + dword = sizeof(float); + + /* For LU factors */ + mem_usage->for_lu = (float)( (4.0*n + 3.0) * iword + + Lstore->nzval_colptr[n] * dword + + Lstore->rowind_colptr[n] * iword ); + mem_usage->for_lu += (float)( (n + 1.0) * iword + + Ustore->colptr[n] * (dword + iword) ); + + /* Working storage to support factorization */ + mem_usage->total_needed = mem_usage->for_lu + + (float)( (2.0 * panel_size + 4.0 + NO_MARKER) * n * iword + + (panel_size + 1.0) * n * dword ); + + return 0; +} /* sQuerySpace */ + + +/*! \brief + * + *
+ * mem_usage consists of the following fields:
+ *    - for_lu (float)
+ *      The amount of space used in bytes for the L\U data structures.
+ *    - total_needed (float)
+ *      The amount of space needed in bytes to perform factorization.
+ * 
+ */ +int ilu_sQuerySpace(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage) +{ + SCformat *Lstore; + NCformat *Ustore; + register int n, panel_size = sp_ienv(1); + register float iword, dword; + + Lstore = L->Store; + Ustore = U->Store; + n = L->ncol; + iword = sizeof(int); + dword = sizeof(double); + + /* For LU factors */ + mem_usage->for_lu = (float)( (4.0f * n + 3.0f) * iword + + Lstore->nzval_colptr[n] * dword + + Lstore->rowind_colptr[n] * iword ); + mem_usage->for_lu += (float)( (n + 1.0f) * iword + + Ustore->colptr[n] * (dword + iword) ); + + /* Working storage to support factorization. + ILU needs 5*n more integers than LU */ + mem_usage->total_needed = mem_usage->for_lu + + (float)( (2.0f * panel_size + 9.0f + NO_MARKER) * n * iword + + (panel_size + 1.0f) * n * dword ); + + return 0; +} /* ilu_sQuerySpace */ + + +/*! \brief Allocate storage for the data structures common to all factor routines. + * + *
+ * For those unpredictable size, estimate as fill_ratio * nnz(A).
+ * Return value:
+ *     If lwork = -1, return the estimated amount of space required, plus n;
+ *     otherwise, return the amount of space actually allocated when
+ *     memory allocation failure occurred.
+ * 
+ */ +int +sLUMemInit(fact_t fact, void *work, int lwork, int m, int n, int annz, + int panel_size, float fill_ratio, SuperMatrix *L, SuperMatrix *U, + GlobalLU_t *Glu, int **iwork, float **dwork) +{ + int info, iword, dword; + SCformat *Lstore; + NCformat *Ustore; + int *xsup, *supno; + int *lsub, *xlsub; + float *lusup; + int *xlusup; + float *ucol; + int *usub, *xusub; + int nzlmax, nzumax, nzlumax; + + iword = sizeof(int); + dword = sizeof(float); + Glu->n = n; + Glu->num_expansions = 0; + + Glu->expanders = (ExpHeader *) SUPERLU_MALLOC( NO_MEMTYPE * + sizeof(ExpHeader) ); + if ( !Glu->expanders ) ABORT("SUPERLU_MALLOC fails for expanders"); + + if ( fact != SamePattern_SameRowPerm ) { + /* Guess for L\U factors */ + nzumax = nzlumax = fill_ratio * annz; + nzlmax = SUPERLU_MAX(1, fill_ratio/4.) * annz; + + if ( lwork == -1 ) { + return ( GluIntArray(n) * iword + TempSpace(m, panel_size) + + (nzlmax+nzumax)*iword + (nzlumax+nzumax)*dword + n ); + } else { + sSetupSpace(work, lwork, Glu); + } + +#if ( PRNTlevel >= 1 ) + printf("sLUMemInit() called: fill_ratio %.0f, nzlmax %ld, nzumax %ld\n", + fill_ratio, nzlmax, nzumax); + fflush(stdout); +#endif + + /* Integer pointers for L\U factors */ + if ( Glu->MemModel == SYSTEM ) { + xsup = intMalloc(n+1); + supno = intMalloc(n+1); + xlsub = intMalloc(n+1); + xlusup = intMalloc(n+1); + xusub = intMalloc(n+1); + } else { + xsup = (int *)suser_malloc((n+1) * iword, HEAD, Glu); + supno = (int *)suser_malloc((n+1) * iword, HEAD, Glu); + xlsub = (int *)suser_malloc((n+1) * iword, HEAD, Glu); + xlusup = (int *)suser_malloc((n+1) * iword, HEAD, Glu); + xusub = (int *)suser_malloc((n+1) * iword, HEAD, Glu); + } + + lusup = (float *) sexpand( &nzlumax, LUSUP, 0, 0, Glu ); + ucol = (float *) sexpand( &nzumax, UCOL, 0, 0, Glu ); + lsub = (int *) sexpand( &nzlmax, LSUB, 0, 0, Glu ); + usub = (int *) sexpand( &nzumax, USUB, 0, 1, Glu ); + + while ( !lusup || !ucol || !lsub || !usub ) { + if ( Glu->MemModel == SYSTEM ) { + SUPERLU_FREE(lusup); + SUPERLU_FREE(ucol); + SUPERLU_FREE(lsub); + SUPERLU_FREE(usub); + } else { + suser_free((nzlumax+nzumax)*dword+(nzlmax+nzumax)*iword, + HEAD, Glu); + } + nzlumax /= 2; + nzumax /= 2; + nzlmax /= 2; + if ( nzlumax < annz ) { + printf("Not enough memory to perform factorization.\n"); + return (smemory_usage(nzlmax, nzumax, nzlumax, n) + n); + } +#if ( PRNTlevel >= 1) + printf("sLUMemInit() reduce size: nzlmax %ld, nzumax %ld\n", + nzlmax, nzumax); + fflush(stdout); +#endif + lusup = (float *) sexpand( &nzlumax, LUSUP, 0, 0, Glu ); + ucol = (float *) sexpand( &nzumax, UCOL, 0, 0, Glu ); + lsub = (int *) sexpand( &nzlmax, LSUB, 0, 0, Glu ); + usub = (int *) sexpand( &nzumax, USUB, 0, 1, Glu ); + } + + } else { + /* fact == SamePattern_SameRowPerm */ + Lstore = L->Store; + Ustore = U->Store; + xsup = Lstore->sup_to_col; + supno = Lstore->col_to_sup; + xlsub = Lstore->rowind_colptr; + xlusup = Lstore->nzval_colptr; + xusub = Ustore->colptr; + nzlmax = Glu->nzlmax; /* max from previous factorization */ + nzumax = Glu->nzumax; + nzlumax = Glu->nzlumax; + + if ( lwork == -1 ) { + return ( GluIntArray(n) * iword + TempSpace(m, panel_size) + + (nzlmax+nzumax)*iword + (nzlumax+nzumax)*dword + n ); + } else if ( lwork == 0 ) { + Glu->MemModel = SYSTEM; + } else { + Glu->MemModel = USER; + Glu->stack.top2 = (lwork/4)*4; /* must be word-addressable */ + Glu->stack.size = Glu->stack.top2; + } + + lsub = Glu->expanders[LSUB].mem = Lstore->rowind; + lusup = Glu->expanders[LUSUP].mem = Lstore->nzval; + usub = Glu->expanders[USUB].mem = Ustore->rowind; + ucol = Glu->expanders[UCOL].mem = Ustore->nzval;; + Glu->expanders[LSUB].size = nzlmax; + Glu->expanders[LUSUP].size = nzlumax; + Glu->expanders[USUB].size = nzumax; + Glu->expanders[UCOL].size = nzumax; + } + + Glu->xsup = xsup; + Glu->supno = supno; + Glu->lsub = lsub; + Glu->xlsub = xlsub; + Glu->lusup = (void *) lusup; + Glu->xlusup = xlusup; + Glu->ucol = (void *) ucol; + Glu->usub = usub; + Glu->xusub = xusub; + Glu->nzlmax = nzlmax; + Glu->nzumax = nzumax; + Glu->nzlumax = nzlumax; + + info = sLUWorkInit(m, n, panel_size, iwork, dwork, Glu); + if ( info ) + return ( info + smemory_usage(nzlmax, nzumax, nzlumax, n) + n); + + ++Glu->num_expansions; + return 0; + +} /* sLUMemInit */ + +/*! \brief Allocate known working storage. Returns 0 if success, otherwise + returns the number of bytes allocated so far when failure occurred. */ +int +sLUWorkInit(int m, int n, int panel_size, int **iworkptr, + float **dworkptr, GlobalLU_t *Glu) +{ + int isize, dsize, extra; + float *old_ptr; + int maxsuper = SUPERLU_MAX( sp_ienv(3), sp_ienv(7) ), + rowblk = sp_ienv(4); + + isize = ( (2 * panel_size + 3 + NO_MARKER ) * m + n ) * sizeof(int); + dsize = (m * panel_size + + NUM_TEMPV(m,panel_size,maxsuper,rowblk)) * sizeof(float); + + if ( Glu->MemModel == SYSTEM ) + *iworkptr = (int *) intCalloc(isize/sizeof(int)); + else + *iworkptr = (int *) suser_malloc(isize, TAIL, Glu); + if ( ! *iworkptr ) { + fprintf(stderr, "sLUWorkInit: malloc fails for local iworkptr[]\n"); + return (isize + n); + } + + if ( Glu->MemModel == SYSTEM ) + *dworkptr = (float *) SUPERLU_MALLOC(dsize); + else { + *dworkptr = (float *) suser_malloc(dsize, TAIL, Glu); + if ( NotDoubleAlign(*dworkptr) ) { + old_ptr = *dworkptr; + *dworkptr = (float*) DoubleAlign(*dworkptr); + *dworkptr = (float*) ((double*)*dworkptr - 1); + extra = (char*)old_ptr - (char*)*dworkptr; +#ifdef DEBUG + printf("sLUWorkInit: not aligned, extra %d\n", extra); +#endif + Glu->stack.top2 -= extra; + Glu->stack.used += extra; + } + } + if ( ! *dworkptr ) { + fprintf(stderr, "malloc fails for local dworkptr[]."); + return (isize + dsize + n); + } + + return 0; +} + + +/*! \brief Set up pointers for real working arrays. + */ +void +sSetRWork(int m, int panel_size, float *dworkptr, + float **dense, float **tempv) +{ + float zero = 0.0; + + int maxsuper = SUPERLU_MAX( sp_ienv(3), sp_ienv(7) ), + rowblk = sp_ienv(4); + *dense = dworkptr; + *tempv = *dense + panel_size*m; + sfill (*dense, m * panel_size, zero); + sfill (*tempv, NUM_TEMPV(m,panel_size,maxsuper,rowblk), zero); +} + +/*! \brief Free the working storage used by factor routines. + */ +void sLUWorkFree(int *iwork, float *dwork, GlobalLU_t *Glu) +{ + if ( Glu->MemModel == SYSTEM ) { + SUPERLU_FREE (iwork); + SUPERLU_FREE (dwork); + } else { + Glu->stack.used -= (Glu->stack.size - Glu->stack.top2); + Glu->stack.top2 = Glu->stack.size; +/* sStackCompress(Glu); */ + } + + SUPERLU_FREE (Glu->expanders); + Glu->expanders = NULL; +} + +/*! \brief Expand the data structures for L and U during the factorization. + * + *
+ * Return value:   0 - successful return
+ *               > 0 - number of bytes allocated when run out of space
+ * 
+ */ +int +sLUMemXpand(int jcol, + int next, /* number of elements currently in the factors */ + MemType mem_type, /* which type of memory to expand */ + int *maxlen, /* modified - maximum length of a data structure */ + GlobalLU_t *Glu /* modified - global LU data structures */ + ) +{ + void *new_mem; + +#ifdef DEBUG + printf("sLUMemXpand(): jcol %d, next %d, maxlen %d, MemType %d\n", + jcol, next, *maxlen, mem_type); +#endif + + if (mem_type == USUB) + new_mem = sexpand(maxlen, mem_type, next, 1, Glu); + else + new_mem = sexpand(maxlen, mem_type, next, 0, Glu); + + if ( !new_mem ) { + int nzlmax = Glu->nzlmax; + int nzumax = Glu->nzumax; + int nzlumax = Glu->nzlumax; + fprintf(stderr, "Can't expand MemType %d: jcol %d\n", mem_type, jcol); + return (smemory_usage(nzlmax, nzumax, nzlumax, Glu->n) + Glu->n); + } + + switch ( mem_type ) { + case LUSUP: + Glu->lusup = (void *) new_mem; + Glu->nzlumax = *maxlen; + break; + case UCOL: + Glu->ucol = (void *) new_mem; + Glu->nzumax = *maxlen; + break; + case LSUB: + Glu->lsub = (int *) new_mem; + Glu->nzlmax = *maxlen; + break; + case USUB: + Glu->usub = (int *) new_mem; + Glu->nzumax = *maxlen; + break; + } + + return 0; + +} + + + +void +copy_mem_float(int howmany, void *old, void *new) +{ + register int i; + float *dold = old; + float *dnew = new; + for (i = 0; i < howmany; i++) dnew[i] = dold[i]; +} + +/*! \brief Expand the existing storage to accommodate more fill-ins. + */ +void +*sexpand ( + int *prev_len, /* length used from previous call */ + MemType type, /* which part of the memory to expand */ + int len_to_copy, /* size of the memory to be copied to new store */ + int keep_prev, /* = 1: use prev_len; + = 0: compute new_len to expand */ + GlobalLU_t *Glu /* modified - global LU data structures */ + ) +{ + float EXPAND = 1.5; + float alpha; + void *new_mem, *old_mem; + int new_len, tries, lword, extra, bytes_to_copy; + ExpHeader *expanders = Glu->expanders; /* Array of 4 types of memory */ + + alpha = EXPAND; + + if ( Glu->num_expansions == 0 || keep_prev ) { + /* First time allocate requested */ + new_len = *prev_len; + } else { + new_len = alpha * *prev_len; + } + + if ( type == LSUB || type == USUB ) lword = sizeof(int); + else lword = sizeof(float); + + if ( Glu->MemModel == SYSTEM ) { + new_mem = (void *) SUPERLU_MALLOC((size_t)new_len * lword); + if ( Glu->num_expansions != 0 ) { + tries = 0; + if ( keep_prev ) { + if ( !new_mem ) return (NULL); + } else { + while ( !new_mem ) { + if ( ++tries > 10 ) return (NULL); + alpha = Reduce(alpha); + new_len = alpha * *prev_len; + new_mem = (void *) SUPERLU_MALLOC((size_t)new_len * lword); + } + } + if ( type == LSUB || type == USUB ) { + copy_mem_int(len_to_copy, expanders[type].mem, new_mem); + } else { + copy_mem_float(len_to_copy, expanders[type].mem, new_mem); + } + SUPERLU_FREE (expanders[type].mem); + } + expanders[type].mem = (void *) new_mem; + + } else { /* MemModel == USER */ + if ( Glu->num_expansions == 0 ) { + new_mem = suser_malloc(new_len * lword, HEAD, Glu); + if ( NotDoubleAlign(new_mem) && + (type == LUSUP || type == UCOL) ) { + old_mem = new_mem; + new_mem = (void *)DoubleAlign(new_mem); + extra = (char*)new_mem - (char*)old_mem; +#ifdef DEBUG + printf("expand(): not aligned, extra %d\n", extra); +#endif + Glu->stack.top1 += extra; + Glu->stack.used += extra; + } + expanders[type].mem = (void *) new_mem; + } else { + tries = 0; + extra = (new_len - *prev_len) * lword; + if ( keep_prev ) { + if ( StackFull(extra) ) return (NULL); + } else { + while ( StackFull(extra) ) { + if ( ++tries > 10 ) return (NULL); + alpha = Reduce(alpha); + new_len = alpha * *prev_len; + extra = (new_len - *prev_len) * lword; + } + } + + if ( type != USUB ) { + new_mem = (void*)((char*)expanders[type + 1].mem + extra); + bytes_to_copy = (char*)Glu->stack.array + Glu->stack.top1 + - (char*)expanders[type + 1].mem; + user_bcopy(expanders[type+1].mem, new_mem, bytes_to_copy); + + if ( type < USUB ) { + Glu->usub = expanders[USUB].mem = + (void*)((char*)expanders[USUB].mem + extra); + } + if ( type < LSUB ) { + Glu->lsub = expanders[LSUB].mem = + (void*)((char*)expanders[LSUB].mem + extra); + } + if ( type < UCOL ) { + Glu->ucol = expanders[UCOL].mem = + (void*)((char*)expanders[UCOL].mem + extra); + } + Glu->stack.top1 += extra; + Glu->stack.used += extra; + if ( type == UCOL ) { + Glu->stack.top1 += extra; /* Add same amount for USUB */ + Glu->stack.used += extra; + } + + } /* if ... */ + + } /* else ... */ + } + + expanders[type].size = new_len; + *prev_len = new_len; + if ( Glu->num_expansions ) ++Glu->num_expansions; + + return (void *) expanders[type].mem; + +} /* sexpand */ + + +/*! \brief Compress the work[] array to remove fragmentation. + */ +void +sStackCompress(GlobalLU_t *Glu) +{ + register int iword, dword, ndim; + char *last, *fragment; + int *ifrom, *ito; + float *dfrom, *dto; + int *xlsub, *lsub, *xusub, *usub, *xlusup; + float *ucol, *lusup; + + iword = sizeof(int); + dword = sizeof(float); + ndim = Glu->n; + + xlsub = Glu->xlsub; + lsub = Glu->lsub; + xusub = Glu->xusub; + usub = Glu->usub; + xlusup = Glu->xlusup; + ucol = Glu->ucol; + lusup = Glu->lusup; + + dfrom = ucol; + dto = (float *)((char*)lusup + xlusup[ndim] * dword); + copy_mem_float(xusub[ndim], dfrom, dto); + ucol = dto; + + ifrom = lsub; + ito = (int *) ((char*)ucol + xusub[ndim] * iword); + copy_mem_int(xlsub[ndim], ifrom, ito); + lsub = ito; + + ifrom = usub; + ito = (int *) ((char*)lsub + xlsub[ndim] * iword); + copy_mem_int(xusub[ndim], ifrom, ito); + usub = ito; + + last = (char*)usub + xusub[ndim] * iword; + fragment = (char*) (((char*)Glu->stack.array + Glu->stack.top1) - last); + Glu->stack.used -= (long int) fragment; + Glu->stack.top1 -= (long int) fragment; + + Glu->ucol = ucol; + Glu->lsub = lsub; + Glu->usub = usub; + +#ifdef DEBUG + printf("sStackCompress: fragment %d\n", fragment); + /* for (last = 0; last < ndim; ++last) + print_lu_col("After compress:", last, 0);*/ +#endif + +} + +/*! \brief Allocate storage for original matrix A + */ +void +sallocateA(int n, int nnz, float **a, int **asub, int **xa) +{ + *a = (float *) floatMalloc(nnz); + *asub = (int *) intMalloc(nnz); + *xa = (int *) intMalloc(n+1); +} + + +float *floatMalloc(int n) +{ + float *buf; + buf = (float *) SUPERLU_MALLOC((size_t)n * sizeof(float)); + if ( !buf ) { + ABORT("SUPERLU_MALLOC failed for buf in floatMalloc()\n"); + } + return (buf); +} + +float *floatCalloc(int n) +{ + float *buf; + register int i; + float zero = 0.0; + buf = (float *) SUPERLU_MALLOC((size_t)n * sizeof(float)); + if ( !buf ) { + ABORT("SUPERLU_MALLOC failed for buf in floatCalloc()\n"); + } + for (i = 0; i < n; ++i) buf[i] = zero; + return (buf); +} + + +int smemory_usage(const int nzlmax, const int nzumax, + const int nzlumax, const int n) +{ + register int iword, dword; + + iword = sizeof(int); + dword = sizeof(float); + + return (10 * n * iword + + nzlmax * iword + nzumax * (iword + dword) + nzlumax * dword); + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/smyblas2.c b/src/Libraries/superlu-5.2.1/SRC/smyblas2.c new file mode 100644 index 00000000..9cef2007 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/smyblas2.c @@ -0,0 +1,240 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file smyblas2.c + * \brief Level 2 Blas operations + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ * Purpose: + * Level 2 BLAS operations: solves and matvec, written in C. + * Note: + * This is only used when the system lacks an efficient BLAS library. + *
+ */ +/* + * File name: smyblas2.c + */ + +/*! \brief Solves a dense UNIT lower triangular system + * + * The unit lower + * triangular matrix is stored in a 2D array M(1:nrow,1:ncol). + * The solution will be returned in the rhs vector. + */ +void slsolve ( int ldm, int ncol, float *M, float *rhs ) +{ + int k; + float x0, x1, x2, x3, x4, x5, x6, x7; + float *M0; + register float *Mki0, *Mki1, *Mki2, *Mki3, *Mki4, *Mki5, *Mki6, *Mki7; + register int firstcol = 0; + + M0 = &M[0]; + + while ( firstcol < ncol - 7 ) { /* Do 8 columns */ + Mki0 = M0 + 1; + Mki1 = Mki0 + ldm + 1; + Mki2 = Mki1 + ldm + 1; + Mki3 = Mki2 + ldm + 1; + Mki4 = Mki3 + ldm + 1; + Mki5 = Mki4 + ldm + 1; + Mki6 = Mki5 + ldm + 1; + Mki7 = Mki6 + ldm + 1; + + x0 = rhs[firstcol]; + x1 = rhs[firstcol+1] - x0 * *Mki0++; + x2 = rhs[firstcol+2] - x0 * *Mki0++ - x1 * *Mki1++; + x3 = rhs[firstcol+3] - x0 * *Mki0++ - x1 * *Mki1++ - x2 * *Mki2++; + x4 = rhs[firstcol+4] - x0 * *Mki0++ - x1 * *Mki1++ - x2 * *Mki2++ + - x3 * *Mki3++; + x5 = rhs[firstcol+5] - x0 * *Mki0++ - x1 * *Mki1++ - x2 * *Mki2++ + - x3 * *Mki3++ - x4 * *Mki4++; + x6 = rhs[firstcol+6] - x0 * *Mki0++ - x1 * *Mki1++ - x2 * *Mki2++ + - x3 * *Mki3++ - x4 * *Mki4++ - x5 * *Mki5++; + x7 = rhs[firstcol+7] - x0 * *Mki0++ - x1 * *Mki1++ - x2 * *Mki2++ + - x3 * *Mki3++ - x4 * *Mki4++ - x5 * *Mki5++ + - x6 * *Mki6++; + + rhs[++firstcol] = x1; + rhs[++firstcol] = x2; + rhs[++firstcol] = x3; + rhs[++firstcol] = x4; + rhs[++firstcol] = x5; + rhs[++firstcol] = x6; + rhs[++firstcol] = x7; + ++firstcol; + + for (k = firstcol; k < ncol; k++) + rhs[k] = rhs[k] - x0 * *Mki0++ - x1 * *Mki1++ + - x2 * *Mki2++ - x3 * *Mki3++ + - x4 * *Mki4++ - x5 * *Mki5++ + - x6 * *Mki6++ - x7 * *Mki7++; + + M0 += 8 * ldm + 8; + } + + while ( firstcol < ncol - 3 ) { /* Do 4 columns */ + Mki0 = M0 + 1; + Mki1 = Mki0 + ldm + 1; + Mki2 = Mki1 + ldm + 1; + Mki3 = Mki2 + ldm + 1; + + x0 = rhs[firstcol]; + x1 = rhs[firstcol+1] - x0 * *Mki0++; + x2 = rhs[firstcol+2] - x0 * *Mki0++ - x1 * *Mki1++; + x3 = rhs[firstcol+3] - x0 * *Mki0++ - x1 * *Mki1++ - x2 * *Mki2++; + + rhs[++firstcol] = x1; + rhs[++firstcol] = x2; + rhs[++firstcol] = x3; + ++firstcol; + + for (k = firstcol; k < ncol; k++) + rhs[k] = rhs[k] - x0 * *Mki0++ - x1 * *Mki1++ + - x2 * *Mki2++ - x3 * *Mki3++; + + M0 += 4 * ldm + 4; + } + + if ( firstcol < ncol - 1 ) { /* Do 2 columns */ + Mki0 = M0 + 1; + Mki1 = Mki0 + ldm + 1; + + x0 = rhs[firstcol]; + x1 = rhs[firstcol+1] - x0 * *Mki0++; + + rhs[++firstcol] = x1; + ++firstcol; + + for (k = firstcol; k < ncol; k++) + rhs[k] = rhs[k] - x0 * *Mki0++ - x1 * *Mki1++; + + } + +} + +/*! \brief Solves a dense upper triangular system + * + * The upper triangular matrix is + * stored in a 2-dim array M(1:ldm,1:ncol). The solution will be returned + * in the rhs vector. + */ +void +susolve ( ldm, ncol, M, rhs ) +int ldm; /* in */ +int ncol; /* in */ +float *M; /* in */ +float *rhs; /* modified */ +{ + float xj; + int jcol, j, irow; + + jcol = ncol - 1; + + for (j = 0; j < ncol; j++) { + + xj = rhs[jcol] / M[jcol + jcol*ldm]; /* M(jcol, jcol) */ + rhs[jcol] = xj; + + for (irow = 0; irow < jcol; irow++) + rhs[irow] -= xj * M[irow + jcol*ldm]; /* M(irow, jcol) */ + + jcol--; + + } +} + + +/*! \brief Performs a dense matrix-vector multiply: Mxvec = Mxvec + M * vec. + * + * The input matrix is M(1:nrow,1:ncol); The product is returned in Mxvec[]. + */ +void smatvec ( ldm, nrow, ncol, M, vec, Mxvec ) + +int ldm; /* in -- leading dimension of M */ +int nrow; /* in */ +int ncol; /* in */ +float *M; /* in */ +float *vec; /* in */ +float *Mxvec; /* in/out */ + +{ + float vi0, vi1, vi2, vi3, vi4, vi5, vi6, vi7; + float *M0; + register float *Mki0, *Mki1, *Mki2, *Mki3, *Mki4, *Mki5, *Mki6, *Mki7; + register int firstcol = 0; + int k; + + M0 = &M[0]; + while ( firstcol < ncol - 7 ) { /* Do 8 columns */ + + Mki0 = M0; + Mki1 = Mki0 + ldm; + Mki2 = Mki1 + ldm; + Mki3 = Mki2 + ldm; + Mki4 = Mki3 + ldm; + Mki5 = Mki4 + ldm; + Mki6 = Mki5 + ldm; + Mki7 = Mki6 + ldm; + + vi0 = vec[firstcol++]; + vi1 = vec[firstcol++]; + vi2 = vec[firstcol++]; + vi3 = vec[firstcol++]; + vi4 = vec[firstcol++]; + vi5 = vec[firstcol++]; + vi6 = vec[firstcol++]; + vi7 = vec[firstcol++]; + + for (k = 0; k < nrow; k++) + Mxvec[k] += vi0 * *Mki0++ + vi1 * *Mki1++ + + vi2 * *Mki2++ + vi3 * *Mki3++ + + vi4 * *Mki4++ + vi5 * *Mki5++ + + vi6 * *Mki6++ + vi7 * *Mki7++; + + M0 += 8 * ldm; + } + + while ( firstcol < ncol - 3 ) { /* Do 4 columns */ + + Mki0 = M0; + Mki1 = Mki0 + ldm; + Mki2 = Mki1 + ldm; + Mki3 = Mki2 + ldm; + + vi0 = vec[firstcol++]; + vi1 = vec[firstcol++]; + vi2 = vec[firstcol++]; + vi3 = vec[firstcol++]; + for (k = 0; k < nrow; k++) + Mxvec[k] += vi0 * *Mki0++ + vi1 * *Mki1++ + + vi2 * *Mki2++ + vi3 * *Mki3++ ; + + M0 += 4 * ldm; + } + + while ( firstcol < ncol ) { /* Do 1 column */ + + Mki0 = M0; + vi0 = vec[firstcol++]; + for (k = 0; k < nrow; k++) + Mxvec[k] += vi0 * *Mki0++; + + M0 += ldm; + } + +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/sp_coletree.c b/src/Libraries/superlu-5.2.1/SRC/sp_coletree.c new file mode 100644 index 00000000..8a327843 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sp_coletree.c @@ -0,0 +1,429 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file sp_coletree.c + * \brief Tree layout and computation routines + * + *
+ * -- SuperLU routine (version 3.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * August 1, 2008
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+*/ + +/* Elimination tree computation and layout routines */ + +#include +#include +#include "slu_ddefs.h" + +/* + * Implementation of disjoint set union routines. + * Elements are integers in 0..n-1, and the + * names of the sets themselves are of type int. + * + * Calls are: + * initialize_disjoint_sets (n) initial call. + * s = make_set (i) returns a set containing only i. + * s = link (t, u) returns s = t union u, destroying t and u. + * s = find (i) return name of set containing i. + * finalize_disjoint_sets final call. + * + * This implementation uses path compression but not weighted union. + * See Tarjan's book for details. + * John Gilbert, CMI, 1987. + * + * Implemented path-halving by XSL 07/05/95. + */ + + +static +int *mxCallocInt(int n) +{ + register int i; + int *buf; + + buf = (int *) SUPERLU_MALLOC( n * sizeof(int) ); + if ( !buf ) { + ABORT("SUPERLU_MALLOC fails for buf in mxCallocInt()"); + } + for (i = 0; i < n; i++) buf[i] = 0; + return (buf); +} + +static +void initialize_disjoint_sets ( + int n, + int **pp + ) +{ + (*pp) = mxCallocInt(n); +} + + +static +int make_set ( + int i, + int *pp + ) +{ + pp[i] = i; + return i; +} + + +static +int link ( + int s, + int t, + int *pp + ) +{ + pp[s] = t; + return t; +} + + +/* PATH HALVING */ +static +int find ( + int i, + int *pp + ) +{ + register int p, gp; + + p = pp[i]; + gp = pp[p]; + while (gp != p) { + pp[i] = gp; + i = gp; + p = pp[i]; + gp = pp[p]; + } + return (p); +} + +#if 0 +/* PATH COMPRESSION */ +static +int find ( + int i + ) +{ + if (pp[i] != i) + pp[i] = find (pp[i]); + return pp[i]; +} +#endif + +static +void finalize_disjoint_sets ( + int *pp + ) +{ + SUPERLU_FREE(pp); +} + + +/* + * Find the elimination tree for A'*A. + * This uses something similar to Liu's algorithm. + * It runs in time O(nz(A)*log n) and does not form A'*A. + * + * Input: + * Sparse matrix A. Numeric values are ignored, so any + * explicit zeros are treated as nonzero. + * Output: + * Integer array of parents representing the elimination + * tree of the symbolic product A'*A. Each vertex is a + * column of A, and nc means a root of the elimination forest. + * + * John R. Gilbert, Xerox, 10 Dec 1990 + * Based on code by JRG dated 1987, 1988, and 1990. + */ + +/* + * Nonsymmetric elimination tree + */ +int +sp_coletree( + int *acolst, int *acolend, /* column start and end past 1 */ + int *arow, /* row indices of A */ + int nr, int nc, /* dimension of A */ + int *parent /* parent in elim tree */ + ) +{ + int *root; /* root of subtee of etree */ + int *firstcol; /* first nonzero col in each row*/ + int rset, cset; + int row, col; + int rroot; + int p; + int *pp; + + root = mxCallocInt (nc); + initialize_disjoint_sets (nc, &pp); + + /* Compute firstcol[row] = first nonzero column in row */ + + firstcol = mxCallocInt (nr); + for (row = 0; row < nr; firstcol[row++] = nc); + for (col = 0; col < nc; col++) + for (p = acolst[col]; p < acolend[col]; p++) { + row = arow[p]; + firstcol[row] = SUPERLU_MIN(firstcol[row], col); + } + + /* Compute etree by Liu's algorithm for symmetric matrices, + except use (firstcol[r],c) in place of an edge (r,c) of A. + Thus each row clique in A'*A is replaced by a star + centered at its first vertex, which has the same fill. */ + + for (col = 0; col < nc; col++) { + cset = make_set (col, pp); + root[cset] = col; + parent[col] = nc; /* Matlab */ + for (p = acolst[col]; p < acolend[col]; p++) { + row = firstcol[arow[p]]; + if (row >= col) continue; + rset = find (row, pp); + rroot = root[rset]; + if (rroot != col) { + parent[rroot] = col; + cset = link (cset, rset, pp); + root[cset] = col; + } + } + } + + SUPERLU_FREE (root); + SUPERLU_FREE (firstcol); + finalize_disjoint_sets (pp); + return 0; +} + +/* + * q = TreePostorder (n, p); + * + * Postorder a tree. + * Input: + * p is a vector of parent pointers for a forest whose + * vertices are the integers 0 to n-1; p[root]==n. + * Output: + * q is a vector indexed by 0..n-1 such that q[i] is the + * i-th vertex in a postorder numbering of the tree. + * + * ( 2/7/95 modified by X.Li: + * q is a vector indexed by 0:n-1 such that vertex i is the + * q[i]-th vertex in a postorder numbering of the tree. + * That is, this is the inverse of the previous q. ) + * + * In the child structure, lower-numbered children are represented + * first, so that a tree which is already numbered in postorder + * will not have its order changed. + * + * Written by John Gilbert, Xerox, 10 Dec 1990. + * Based on code written by John Gilbert at CMI in 1987. + */ + +static +/* + * Depth-first search from vertex v. + */ +void etdfs ( + int v, + int first_kid[], + int next_kid[], + int post[], + int *postnum + ) +{ + int w; + + for (w = first_kid[v]; w != -1; w = next_kid[w]) { + etdfs (w, first_kid, next_kid, post, postnum); + } + /* post[postnum++] = v; in Matlab */ + post[v] = (*postnum)++; /* Modified by X. Li on 08/10/07 */ +} + + +static +/* + * Depth-first search from vertex n. No recursion. + * This routine was contributed by Cédric Doucet, CEDRAT Group, Meylan, France. + */ +void nr_etdfs (int n, int *parent, + int *first_kid, int *next_kid, + int *post, int postnum) +{ + int current = n, first, next; + + while (postnum != n){ + + /* no kid for the current node */ + first = first_kid[current]; + + /* no first kid for the current node */ + if (first == -1){ + + /* numbering this node because it has no kid */ + post[current] = postnum++; + + /* looking for the next kid */ + next = next_kid[current]; + + while (next == -1){ + + /* no more kids : back to the parent node */ + current = parent[current]; + + /* numbering the parent node */ + post[current] = postnum++; + + /* get the next kid */ + next = next_kid[current]; + } + + /* stopping criterion */ + if (postnum==n+1) return; + + /* updating current node */ + current = next; + } + /* updating current node */ + else { + current = first; + } + } +} + +/* + * Post order a tree + */ +int *TreePostorder( + int n, + int *parent + ) +{ + int *first_kid, *next_kid; /* Linked list of children. */ + int *post, postnum; + int v, dad; + + /* Allocate storage for working arrays and results */ + first_kid = mxCallocInt (n+1); + next_kid = mxCallocInt (n+1); + post = mxCallocInt (n+1); + + /* Set up structure describing children */ + for (v = 0; v <= n; first_kid[v++] = -1); + for (v = n-1; v >= 0; v--) { + dad = parent[v]; + next_kid[v] = first_kid[dad]; + first_kid[dad] = v; + } + + /* Depth-first search from dummy root vertex #n */ + postnum = 0; +#if 0 + /* recursion */ + etdfs (n, first_kid, next_kid, post, &postnum); +#else + /* no recursion */ + nr_etdfs(n, parent, first_kid, next_kid, post, postnum); +#endif + + SUPERLU_FREE (first_kid); + SUPERLU_FREE (next_kid); + return post; +} + + +/* + * p = spsymetree (A); + * + * Find the elimination tree for symmetric matrix A. + * This uses Liu's algorithm, and runs in time O(nz*log n). + * + * Input: + * Square sparse matrix A. No check is made for symmetry; + * elements below and on the diagonal are ignored. + * Numeric values are ignored, so any explicit zeros are + * treated as nonzero. + * Output: + * Integer array of parents representing the etree, with n + * meaning a root of the elimination forest. + * Note: + * This routine uses only the upper triangle, while sparse + * Cholesky (as in spchol.c) uses only the lower. Matlab's + * dense Cholesky uses only the upper. This routine could + * be modified to use the lower triangle either by transposing + * the matrix or by traversing it by rows with auxiliary + * pointer and link arrays. + * + * John R. Gilbert, Xerox, 10 Dec 1990 + * Based on code by JRG dated 1987, 1988, and 1990. + * Modified by X.S. Li, November 1999. + */ + +/* + * Symmetric elimination tree + */ +int +sp_symetree( + int *acolst, int *acolend, /* column starts and ends past 1 */ + int *arow, /* row indices of A */ + int n, /* dimension of A */ + int *parent /* parent in elim tree */ + ) +{ + int *root; /* root of subtree of etree */ + int rset, cset; + int row, col; + int rroot; + int p; + int *pp; + + root = mxCallocInt (n); + initialize_disjoint_sets (n, &pp); + + for (col = 0; col < n; col++) { + cset = make_set (col, pp); + root[cset] = col; + parent[col] = n; /* Matlab */ + for (p = acolst[col]; p < acolend[col]; p++) { + row = arow[p]; + if (row >= col) continue; + rset = find (row, pp); + rroot = root[rset]; + if (rroot != col) { + parent[rroot] = col; + cset = link (cset, rset, pp); + root[cset] = col; + } + } + } + SUPERLU_FREE (root); + finalize_disjoint_sets (pp); + return 0; +} /* SP_SYMETREE */ diff --git a/src/Libraries/superlu-5.2.1/SRC/sp_ienv.c b/src/Libraries/superlu-5.2.1/SRC/sp_ienv.c new file mode 100644 index 00000000..855d9013 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sp_ienv.c @@ -0,0 +1,89 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file sp_ienv.c + * \brief Chooses machine-dependent parameters for the local environment. + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November, 2010
+ * 
+*/ + +/* + * File name: sp_ienv.c + * History: Modified from lapack routine ILAENV + */ +#include "slu_Cnames.h" + +/*! \brief + +
+    Purpose   
+    =======   
+
+    sp_ienv() is inquired to choose machine-dependent parameters for the
+    local environment. See ISPEC for a description of the parameters.   
+
+    This version provides a set of parameters which should give good,   
+    but not optimal, performance on many of the currently available   
+    computers.  Users are encouraged to modify this subroutine to set   
+    the tuning parameters for their particular machine using the option   
+    and problem size information in the arguments.   
+
+    Arguments   
+    =========   
+
+    ISPEC   (input) int
+            Specifies the parameter to be returned as the value of SP_IENV.   
+            = 1: the panel size w; a panel consists of w consecutive
+	         columns of matrix A in the process of Gaussian elimination.
+		 The best value depends on machine's cache characters.
+            = 2: the relaxation parameter relax; if the number of
+	         nodes (columns) in a subtree of the elimination tree is less
+		 than relax, this subtree is considered as one supernode,
+		 regardless of their row structures.
+            = 3: the maximum size for a supernode in complete LU;
+	    = 4: the minimum row dimension for 2-D blocking to be used;
+	    = 5: the minimum column dimension for 2-D blocking to be used;
+	    = 6: the estimated fills factor for L and U, compared with A;
+	    = 7: the maximum size for a supernode in ILU.
+	    
+   (SP_IENV) (output) int
+            >= 0: the value of the parameter specified by ISPEC   
+            < 0:  if SP_IENV = -k, the k-th argument had an illegal value. 
+  
+    ===================================================================== 
+
+*/ +int +sp_ienv(int ispec) +{ + int i; + + switch (ispec) { + case 1: return (20); + case 2: return (10); + case 3: return (200); + case 4: return (200); + case 5: return (100); + case 6: return (30); + case 7: return (10); + } + + /* Invalid value for ISPEC */ + i = 1; + input_error("sp_ienv", &i); + return 0; + +} /* sp_ienv_ */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/sp_preorder.c b/src/Libraries/superlu-5.2.1/SRC/sp_preorder.c new file mode 100644 index 00000000..c2dffbce --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sp_preorder.c @@ -0,0 +1,220 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file sp_preorder.c + * \brief Permute and performs functions on columns of orginal matrix + */ +#include "slu_ddefs.h" + + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * sp_preorder() permutes the columns of the original matrix. It performs
+ * the following steps:
+ *
+ *    1. Apply column permutation perm_c[] to A's column pointers to form AC;
+ *
+ *    2. If options->Fact = DOFACT, then
+ *       (1) Compute column elimination tree etree[] of AC'AC;
+ *       (2) Post order etree[] to get a postordered elimination tree etree[],
+ *           and a postorder permutation post[];
+ *       (3) Apply post[] permutation to columns of AC;
+ *       (4) Overwrite perm_c[] with the product perm_c * post.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *         Specifies whether or not the elimination tree will be re-used.
+ *         If options->Fact == DOFACT, this means first time factor A, 
+ *         etree is computed, postered, and output.
+ *         Otherwise, re-factor A, etree is input, unchanged on exit.
+ *
+ * A       (input) SuperMatrix*
+ *         Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
+ *         of the linear equations is A->nrow. Currently, the type of A can be:
+ *         Stype = NC or SLU_NCP; Mtype = SLU_GE.
+ *         In the future, more general A may be handled.
+ *
+ * perm_c  (input/output) int*
+ *	   Column permutation vector of size A->ncol, which defines the 
+ *         permutation matrix Pc; perm_c[i] = j means column i of A is 
+ *         in position j in A*Pc.
+ *         If options->Fact == DOFACT, perm_c is both input and output.
+ *         On output, it is changed according to a postorder of etree.
+ *         Otherwise, perm_c is input.
+ *
+ * etree   (input/output) int*
+ *         Elimination tree of Pc'*A'*A*Pc, dimension A->ncol.
+ *         If options->Fact == DOFACT, etree is an output argument,
+ *         otherwise it is an input argument.
+ *         Note: etree is a vector of parent pointers for a forest whose
+ *         vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *
+ * AC      (output) SuperMatrix*
+ *         The resulting matrix after applied the column permutation
+ *         perm_c[] to matrix A. The type of AC can be:
+ *         Stype = SLU_NCP; Dtype = A->Dtype; Mtype = SLU_GE.
+ * 
+ */ +void +sp_preorder(superlu_options_t *options, SuperMatrix *A, int *perm_c, + int *etree, SuperMatrix *AC) +{ + NCformat *Astore; + NCPformat *ACstore; + int *iwork, *post; + register int n, i; + + n = A->ncol; + + /* Apply column permutation perm_c to A's column pointers so to + obtain NCP format in AC = A*Pc. */ + AC->Stype = SLU_NCP; + AC->Dtype = A->Dtype; + AC->Mtype = A->Mtype; + AC->nrow = A->nrow; + AC->ncol = A->ncol; + Astore = A->Store; + ACstore = AC->Store = (void *) SUPERLU_MALLOC( sizeof(NCPformat) ); + if ( !ACstore ) ABORT("SUPERLU_MALLOC fails for ACstore"); + ACstore->nnz = Astore->nnz; + ACstore->nzval = Astore->nzval; + ACstore->rowind = Astore->rowind; + ACstore->colbeg = (int*) SUPERLU_MALLOC(n*sizeof(int)); + if ( !(ACstore->colbeg) ) ABORT("SUPERLU_MALLOC fails for ACstore->colbeg"); + ACstore->colend = (int*) SUPERLU_MALLOC(n*sizeof(int)); + if ( !(ACstore->colend) ) ABORT("SUPERLU_MALLOC fails for ACstore->colend"); + +#ifdef DEBUG + print_int_vec("pre_order:", n, perm_c); + check_perm("Initial perm_c", n, perm_c); +#endif + + for (i = 0; i < n; i++) { + ACstore->colbeg[perm_c[i]] = Astore->colptr[i]; + ACstore->colend[perm_c[i]] = Astore->colptr[i+1]; + } + + if ( options->Fact == DOFACT ) { +#undef ETREE_ATplusA +#ifdef ETREE_ATplusA + /*-------------------------------------------- + COMPUTE THE ETREE OF Pc*(A'+A)*Pc'. + --------------------------------------------*/ + int *b_colptr, *b_rowind, bnz, j; + int *c_colbeg, *c_colend; + + /*printf("Use etree(A'+A)\n");*/ + + /* Form B = A + A'. */ + at_plus_a(n, Astore->nnz, Astore->colptr, Astore->rowind, + &bnz, &b_colptr, &b_rowind); + + /* Form C = Pc*B*Pc'. */ + c_colbeg = (int*) SUPERLU_MALLOC(2*n*sizeof(int)); + c_colend = c_colbeg + n; + if (!c_colbeg ) ABORT("SUPERLU_MALLOC fails for c_colbeg/c_colend"); + for (i = 0; i < n; i++) { + c_colbeg[perm_c[i]] = b_colptr[i]; + c_colend[perm_c[i]] = b_colptr[i+1]; + } + for (j = 0; j < n; ++j) { + for (i = c_colbeg[j]; i < c_colend[j]; ++i) { + b_rowind[i] = perm_c[b_rowind[i]]; + } + } + + /* Compute etree of C. */ + sp_symetree(c_colbeg, c_colend, b_rowind, n, etree); + + SUPERLU_FREE(b_colptr); + if ( bnz ) SUPERLU_FREE(b_rowind); + SUPERLU_FREE(c_colbeg); + +#else + /*-------------------------------------------- + COMPUTE THE COLUMN ELIMINATION TREE. + --------------------------------------------*/ + sp_coletree(ACstore->colbeg, ACstore->colend, ACstore->rowind, + A->nrow, A->ncol, etree); +#endif +#ifdef DEBUG + print_int_vec("etree:", n, etree); +#endif + + /* In symmetric mode, do not do postorder here. */ + if ( options->SymmetricMode == NO ) { + /* Post order etree */ + post = (int *) TreePostorder(n, etree); + /* for (i = 0; i < n+1; ++i) inv_post[post[i]] = i; + iwork = post; */ + +#ifdef DEBUG + print_int_vec("post:", n+1, post); + check_perm("post", n, post); +#endif + iwork = (int*) SUPERLU_MALLOC((n+1)*sizeof(int)); + if ( !iwork ) ABORT("SUPERLU_MALLOC fails for iwork[]"); + + /* Renumber etree in postorder */ + for (i = 0; i < n; ++i) iwork[post[i]] = post[etree[i]]; + for (i = 0; i < n; ++i) etree[i] = iwork[i]; + +#ifdef DEBUG + print_int_vec("postorder etree:", n, etree); +#endif + + /* Postmultiply A*Pc by post[] */ + for (i = 0; i < n; ++i) iwork[post[i]] = ACstore->colbeg[i]; + for (i = 0; i < n; ++i) ACstore->colbeg[i] = iwork[i]; + for (i = 0; i < n; ++i) iwork[post[i]] = ACstore->colend[i]; + for (i = 0; i < n; ++i) ACstore->colend[i] = iwork[i]; + + for (i = 0; i < n; ++i) + iwork[i] = post[perm_c[i]]; /* product of perm_c and post */ + for (i = 0; i < n; ++i) perm_c[i] = iwork[i]; + +#ifdef DEBUG + print_int_vec("Pc*post:", n, perm_c); + check_perm("final perm_c", n, perm_c); +#endif + SUPERLU_FREE (post); + SUPERLU_FREE (iwork); + } /* end postordering */ + + } /* if options->Fact == DOFACT ... */ + +} + +int check_perm(char *what, int n, int *perm) +{ + register int i; + int *marker; + /*marker = (int *) calloc(n, sizeof(int));*/ + marker = (int *) malloc(n * sizeof(int)); + for (i = 0; i < n; ++i) marker[i] = 0; + + for (i = 0; i < n; ++i) { + if ( marker[perm[i]] == 1 || perm[i] >= n ) { + printf("%s: Not a valid PERM[%d] = %d\n", what, i, perm[i]); + ABORT("check_perm"); + } else { + marker[perm[i]] = 1; + } + } + + SUPERLU_FREE(marker); + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/spanel_bmod.c b/src/Libraries/superlu-5.2.1/SRC/spanel_bmod.c new file mode 100644 index 00000000..b1e7f91f --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/spanel_bmod.c @@ -0,0 +1,466 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file spanel_bmod.c + * \brief Performs numeric block updates + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ +/* + +*/ + +#include +#include +#include "slu_sdefs.h" + +/* + * Function prototypes + */ +void slsolve(int, int, float *, float *); +void smatvec(int, int, int, float *, float *, float *); +extern void scheck_tempv(); + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *    Performs numeric block updates (sup-panel) in topological order.
+ *    It features: col-col, 2cols-col, 3cols-col, and sup-col updates.
+ *    Special processing on the supernodal portion of L\U[*,j]
+ *
+ *    Before entering this routine, the original nonzeros in the panel 
+ *    were already copied into the spa[m,w].
+ *
+ *    Updated/Output parameters-
+ *    dense[0:m-1,w]: L[*,j:j+w-1] and U[*,j:j+w-1] are returned 
+ *    collectively in the m-by-w vector dense[*]. 
+ * 
+ */ + +void +spanel_bmod ( + const int m, /* in - number of rows in the matrix */ + const int w, /* in */ + const int jcol, /* in */ + const int nseg, /* in */ + float *dense, /* out, of size n by w */ + float *tempv, /* working array */ + int *segrep, /* in */ + int *repfnz, /* in, of size n by w */ + GlobalLU_t *Glu, /* modified */ + SuperLUStat_t *stat /* output */ + ) +{ + + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + int incx = 1, incy = 1; + float alpha, beta; +#endif + + register int k, ksub; + int fsupc, nsupc, nsupr, nrow; + int krep, krep_ind; + float ukj, ukj1, ukj2; + int luptr, luptr1, luptr2; + int segsze; + int block_nrow; /* no of rows in a block row */ + register int lptr; /* Points to the row subscripts of a supernode */ + int kfnz, irow, no_zeros; + register int isub, isub1, i; + register int jj; /* Index through each column in the panel */ + int *xsup, *supno; + int *lsub, *xlsub; + float *lusup; + int *xlusup; + int *repfnz_col; /* repfnz[] for a column in the panel */ + float *dense_col; /* dense[] for a column in the panel */ + float *tempv1; /* Used in 1-D update */ + float *TriTmp, *MatvecTmp; /* used in 2-D update */ + float zero = 0.0; + float one = 1.0; + register int ldaTmp; + register int r_ind, r_hi; + int maxsuper, rowblk, colblk; + flops_t *ops = stat->ops; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (float *) Glu->lusup; + xlusup = Glu->xlusup; + + maxsuper = SUPERLU_MAX( sp_ienv(3), sp_ienv(7) ); + rowblk = sp_ienv(4); + colblk = sp_ienv(5); + ldaTmp = maxsuper + rowblk; + + /* + * For each nonz supernode segment of U[*,j] in topological order + */ + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { /* for each updating supernode */ + + /* krep = representative of current k-th supernode + * fsupc = first supernodal column + * nsupc = no of columns in a supernode + * nsupr = no of rows in a supernode + */ + krep = segrep[k--]; + fsupc = xsup[supno[krep]]; + nsupc = krep - fsupc + 1; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; + nrow = nsupr - nsupc; + lptr = xlsub[fsupc]; + krep_ind = lptr + nsupc - 1; + + repfnz_col = repfnz; + dense_col = dense; + + if ( nsupc >= colblk && nrow > rowblk ) { /* 2-D block update */ + + TriTmp = tempv; + + /* Sequence through each column in panel -- triangular solves */ + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m, TriTmp += ldaTmp ) { + + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + luptr = xlusup[fsupc]; + + ops[TRSV] += segsze * (segsze - 1); + ops[GEMV] += 2 * nrow * segsze; + + /* Case 1: Update U-segment of size 1 -- col-col update */ + if ( segsze == 1 ) { + ukj = dense_col[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc; + + for (i = lptr + nsupc; i < xlsub[fsupc+1]; i++) { + irow = lsub[i]; + dense_col[irow] -= ukj * lusup[luptr]; + ++luptr; + } + + } else if ( segsze <= 3 ) { + ukj = dense_col[lsub[krep_ind]]; + ukj1 = dense_col[lsub[krep_ind - 1]]; + luptr += nsupr*(nsupc-1) + nsupc-1; + luptr1 = luptr - nsupr; + + if ( segsze == 2 ) { + ukj -= ukj1 * lusup[luptr1]; + dense_col[lsub[krep_ind]] = ukj; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; luptr1++; + dense_col[irow] -= (ukj*lusup[luptr] + + ukj1*lusup[luptr1]); + } + } else { + ukj2 = dense_col[lsub[krep_ind - 2]]; + luptr2 = luptr1 - nsupr; + ukj1 -= ukj2 * lusup[luptr2-1]; + ukj = ukj - ukj1*lusup[luptr1] - ukj2*lusup[luptr2]; + dense_col[lsub[krep_ind]] = ukj; + dense_col[lsub[krep_ind-1]] = ukj1; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; luptr1++; luptr2++; + dense_col[irow] -= ( ukj*lusup[luptr] + + ukj1*lusup[luptr1] + ukj2*lusup[luptr2] ); + } + } + + } else { /* segsze >= 4 */ + + /* Copy U[*,j] segment from dense[*] to TriTmp[*], which + holds the result of triangular solves. */ + no_zeros = kfnz - fsupc; + isub = lptr + no_zeros; + for (i = 0; i < segsze; ++i) { + irow = lsub[isub]; + TriTmp[i] = dense_col[irow]; /* Gather */ + ++isub; + } + + /* start effective triangle */ + luptr += nsupr * no_zeros + no_zeros; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + STRSV( ftcs1, ftcs2, ftcs3, &segsze, &lusup[luptr], + &nsupr, TriTmp, &incx ); +#else + strsv_( "L", "N", "U", &segsze, &lusup[luptr], + &nsupr, TriTmp, &incx ); +#endif +#else + slsolve ( nsupr, segsze, &lusup[luptr], TriTmp ); +#endif + + + } /* else ... */ + + } /* for jj ... end tri-solves */ + + /* Block row updates; push all the way into dense[*] block */ + for ( r_ind = 0; r_ind < nrow; r_ind += rowblk ) { + + r_hi = SUPERLU_MIN(nrow, r_ind + rowblk); + block_nrow = SUPERLU_MIN(rowblk, r_hi - r_ind); + luptr = xlusup[fsupc] + nsupc + r_ind; + isub1 = lptr + nsupc + r_ind; + + repfnz_col = repfnz; + TriTmp = tempv; + dense_col = dense; + + /* Sequence through each column in panel -- matrix-vector */ + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m, TriTmp += ldaTmp) { + + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + if ( segsze <= 3 ) continue; /* skip unrolled cases */ + + /* Perform a block update, and scatter the result of + matrix-vector to dense[]. */ + no_zeros = kfnz - fsupc; + luptr1 = luptr + nsupr * no_zeros; + MatvecTmp = &TriTmp[maxsuper]; + +#ifdef USE_VENDOR_BLAS + alpha = one; + beta = zero; +#ifdef _CRAY + SGEMV(ftcs2, &block_nrow, &segsze, &alpha, &lusup[luptr1], + &nsupr, TriTmp, &incx, &beta, MatvecTmp, &incy); +#else + sgemv_("N", &block_nrow, &segsze, &alpha, &lusup[luptr1], + &nsupr, TriTmp, &incx, &beta, MatvecTmp, &incy); +#endif +#else + smatvec(nsupr, block_nrow, segsze, &lusup[luptr1], + TriTmp, MatvecTmp); +#endif + + /* Scatter MatvecTmp[*] into SPA dense[*] temporarily + * such that MatvecTmp[*] can be re-used for the + * the next blok row update. dense[] will be copied into + * global store after the whole panel has been finished. + */ + isub = isub1; + for (i = 0; i < block_nrow; i++) { + irow = lsub[isub]; + dense_col[irow] -= MatvecTmp[i]; + MatvecTmp[i] = zero; + ++isub; + } + + } /* for jj ... */ + + } /* for each block row ... */ + + /* Scatter the triangular solves into SPA dense[*] */ + repfnz_col = repfnz; + TriTmp = tempv; + dense_col = dense; + + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m, TriTmp += ldaTmp) { + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + if ( segsze <= 3 ) continue; /* skip unrolled cases */ + + no_zeros = kfnz - fsupc; + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + dense_col[irow] = TriTmp[i]; + TriTmp[i] = zero; + ++isub; + } + + } /* for jj ... */ + + } else { /* 1-D block modification */ + + + /* Sequence through each column in the panel */ + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m) { + + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + luptr = xlusup[fsupc]; + + ops[TRSV] += segsze * (segsze - 1); + ops[GEMV] += 2 * nrow * segsze; + + /* Case 1: Update U-segment of size 1 -- col-col update */ + if ( segsze == 1 ) { + ukj = dense_col[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc; + + for (i = lptr + nsupc; i < xlsub[fsupc+1]; i++) { + irow = lsub[i]; + dense_col[irow] -= ukj * lusup[luptr]; + ++luptr; + } + + } else if ( segsze <= 3 ) { + ukj = dense_col[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc-1; + ukj1 = dense_col[lsub[krep_ind - 1]]; + luptr1 = luptr - nsupr; + + if ( segsze == 2 ) { + ukj -= ukj1 * lusup[luptr1]; + dense_col[lsub[krep_ind]] = ukj; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + ++luptr; ++luptr1; + dense_col[irow] -= (ukj*lusup[luptr] + + ukj1*lusup[luptr1]); + } + } else { + ukj2 = dense_col[lsub[krep_ind - 2]]; + luptr2 = luptr1 - nsupr; + ukj1 -= ukj2 * lusup[luptr2-1]; + ukj = ukj - ukj1*lusup[luptr1] - ukj2*lusup[luptr2]; + dense_col[lsub[krep_ind]] = ukj; + dense_col[lsub[krep_ind-1]] = ukj1; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + ++luptr; ++luptr1; ++luptr2; + dense_col[irow] -= ( ukj*lusup[luptr] + + ukj1*lusup[luptr1] + ukj2*lusup[luptr2] ); + } + } + + } else { /* segsze >= 4 */ + /* + * Perform a triangular solve and block update, + * then scatter the result of sup-col update to dense[]. + */ + no_zeros = kfnz - fsupc; + + /* Copy U[*,j] segment from dense[*] to tempv[*]: + * The result of triangular solve is in tempv[*]; + * The result of matrix vector update is in dense_col[*] + */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; ++i) { + irow = lsub[isub]; + tempv[i] = dense_col[irow]; /* Gather */ + ++isub; + } + + /* start effective triangle */ + luptr += nsupr * no_zeros + no_zeros; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + STRSV( ftcs1, ftcs2, ftcs3, &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#else + strsv_( "L", "N", "U", &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#endif + + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + alpha = one; + beta = zero; +#ifdef _CRAY + SGEMV( ftcs2, &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#else + sgemv_( "N", &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#endif +#else + slsolve ( nsupr, segsze, &lusup[luptr], tempv ); + + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + smatvec (nsupr, nrow, segsze, &lusup[luptr], tempv, tempv1); +#endif + + /* Scatter tempv[*] into SPA dense[*] temporarily, such + * that tempv[*] can be used for the triangular solve of + * the next column of the panel. They will be copied into + * ucol[*] after the whole panel has been finished. + */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + dense_col[irow] = tempv[i]; + tempv[i] = zero; + isub++; + } + + /* Scatter the update from tempv1[*] into SPA dense[*] */ + /* Start dense rectangular L */ + for (i = 0; i < nrow; i++) { + irow = lsub[isub]; + dense_col[irow] -= tempv1[i]; + tempv1[i] = zero; + ++isub; + } + + } /* else segsze>=4 ... */ + + } /* for each column in the panel... */ + + } /* else 1-D update ... */ + + } /* for each updating supernode ... */ + +} + + + diff --git a/src/Libraries/superlu-5.2.1/SRC/spanel_dfs.c b/src/Libraries/superlu-5.2.1/SRC/spanel_dfs.c new file mode 100644 index 00000000..c2b736d1 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/spanel_dfs.c @@ -0,0 +1,264 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file spanel_dfs.c + * \brief Peforms a symbolic factorization on a panel of symbols + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_sdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *   Performs a symbolic factorization on a panel of columns [jcol, jcol+w).
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives.
+ *
+ *   The routine returns one list of the supernodal representatives
+ *   in topological order of the dfs that generates them. This list is
+ *   a superset of the topological order of each individual column within
+ *   the panel. 
+ *   The location of the first nonzero in each supernodal segment
+ *   (supernodal entry location) is also returned. Each column has a 
+ *   separate list for this purpose.
+ *
+ *   Two marker arrays are used for dfs:
+ *     marker[i] == jj, if i was visited during dfs of current column jj;
+ *     marker1[i] >= jcol, if i was visited by earlier columns in this panel;
+ *
+ *   marker: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ * 
+ */ + +void +spanel_dfs ( + const int m, /* in - number of rows in the matrix */ + const int w, /* in */ + const int jcol, /* in */ + SuperMatrix *A, /* in - original matrix */ + int *perm_r, /* in */ + int *nseg, /* out */ + float *dense, /* out */ + int *panel_lsub, /* out */ + int *segrep, /* out */ + int *repfnz, /* out */ + int *xprune, /* out */ + int *marker, /* out */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ + ) +{ + + NCPformat *Astore; + float *a; + int *asub; + int *xa_begin, *xa_end; + int krep, chperm, chmark, chrep, oldrep, kchild, myfnz; + int k, krow, kmark, kperm; + int xdfs, maxdfs, kpar; + int jj; /* index through each column in the panel */ + int *marker1; /* marker1[jj] >= jcol if vertex jj was visited + by a previous column within this panel. */ + int *repfnz_col; /* start of each column in the panel */ + float *dense_col; /* start of each column in the panel */ + int nextl_col; /* next available position in panel_lsub[*,jj] */ + int *xsup, *supno; + int *lsub, *xlsub; + + /* Initialize pointers */ + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + marker1 = marker + m; + repfnz_col = repfnz; + dense_col = dense; + *nseg = 0; + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + + /* For each column in the panel */ + for (jj = jcol; jj < jcol + w; jj++) { + nextl_col = (jj - jcol) * m; + +#ifdef CHK_DFS + printf("\npanel col %d: ", jj); +#endif + + /* For each nonz in A[*,jj] do dfs */ + for (k = xa_begin[jj]; k < xa_end[jj]; k++) { + krow = asub[k]; + dense_col[krow] = a[k]; + kmark = marker[krow]; + if ( kmark == jj ) + continue; /* krow visited before, go to the next nonzero */ + + /* For each unmarked nbr krow of jj + * krow is in L: place it in structure of L[*,jj] + */ + marker[krow] = jj; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + panel_lsub[nextl_col++] = krow; /* krow is indexed into A */ + } + /* + * krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + else { + + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz_col[krep]; + +#ifdef CHK_DFS + printf("krep %d, myfnz %d, perm_r[%d] %d\n", krep, myfnz, krow, kperm); +#endif + if ( myfnz != EMPTY ) { /* Representative visited before */ + if ( myfnz > kperm ) repfnz_col[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz_col[krep] = kperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; + +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker[kchild]; + + if ( chmark != jj ) { /* Not reached yet */ + marker[kchild] = jj; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,j] */ + if ( chperm == EMPTY ) { + panel_lsub[nextl_col++] = kchild; + } + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + else { + + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz_col[chrep]; +#ifdef CHK_DFS + printf("chrep %d,myfnz %d,perm_r[%d] %d\n",chrep,myfnz,kchild,chperm); +#endif + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz_col[chrep] = chperm; + } + else { + /* Cont. dfs at snode-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L) */ + parent[krep] = oldrep; + repfnz_col[krep] = chperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } /* else */ + + } /* else */ + + } /* if... */ + + } /* while xdfs < maxdfs */ + + /* krow has no more unexplored nbrs: + * Place snode-rep krep in postorder DFS, if this + * segment is seen for the first time. (Note that + * "repfnz[krep]" may change later.) + * Backtrack dfs to its parent. + */ + if ( marker1[krep] < jcol ) { + segrep[*nseg] = krep; + ++(*nseg); + marker1[krep] = jj; + } + + kpar = parent[krep]; /* Pop stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xprune[krep]; + +#ifdef CHK_DFS + printf(" pop stack: krep %d,xdfs %d,maxdfs %d: ", krep,xdfs,maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } while ( kpar != EMPTY ); /* do-while - until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonz in A[*,jj] */ + + repfnz_col += m; /* Move to next column */ + dense_col += m; + + } /* for jj ... */ + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/spivotL.c b/src/Libraries/superlu-5.2.1/SRC/spivotL.c new file mode 100644 index 00000000..2c63cabf --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/spivotL.c @@ -0,0 +1,194 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file spivotL.c + * \brief Performs numerical pivoting + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include +#include +#include "slu_sdefs.h" + +#undef DEBUG + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   Performs the numerical pivoting on the current column of L,
+ *   and the CDIV operation.
+ *
+ *   Pivot policy:
+ *   (1) Compute thresh = u * max_(i>=j) abs(A_ij);
+ *   (2) IF user specifies pivot row k and abs(A_kj) >= thresh THEN
+ *           pivot row = k;
+ *       ELSE IF abs(A_jj) >= thresh THEN
+ *           pivot row = j;
+ *       ELSE
+ *           pivot row = m;
+ * 
+ *   Note: If you absolutely want to use a given pivot order, then set u=0.0.
+ *
+ *   Return value: 0      success;
+ *                 i > 0  U(i,i) is exactly zero.
+ * 
+ */ + +int +spivotL( + const int jcol, /* in */ + const double u, /* in - diagonal pivoting threshold */ + int *usepr, /* re-use the pivot sequence given by perm_r/iperm_r */ + int *perm_r, /* may be modified */ + int *iperm_r, /* in - inverse of perm_r */ + int *iperm_c, /* in - used to find diagonal of Pc*A*Pc' */ + int *pivrow, /* out */ + GlobalLU_t *Glu, /* modified - global LU data structures */ + SuperLUStat_t *stat /* output */ + ) +{ + + int fsupc; /* first column in the supernode */ + int nsupc; /* no of columns in the supernode */ + int nsupr; /* no of rows in the supernode */ + int lptr; /* points to the starting subscript of the supernode */ + int pivptr, old_pivptr, diag, diagind; + float pivmax, rtemp, thresh; + float temp; + float *lu_sup_ptr; + float *lu_col_ptr; + int *lsub_ptr; + int isub, icol, k, itemp; + int *lsub, *xlsub; + float *lusup; + int *xlusup; + flops_t *ops = stat->ops; + + /* Initialize pointers */ + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (float *) Glu->lusup; + xlusup = Glu->xlusup; + fsupc = (Glu->xsup)[(Glu->supno)[jcol]]; + nsupc = jcol - fsupc; /* excluding jcol; nsupc >= 0 */ + lptr = xlsub[fsupc]; + nsupr = xlsub[fsupc+1] - lptr; + lu_sup_ptr = &lusup[xlusup[fsupc]]; /* start of the current supernode */ + lu_col_ptr = &lusup[xlusup[jcol]]; /* start of jcol in the supernode */ + lsub_ptr = &lsub[lptr]; /* start of row indices of the supernode */ + +#ifdef DEBUG +if ( jcol == MIN_COL ) { + printf("Before cdiv: col %d\n", jcol); + for (k = nsupc; k < nsupr; k++) + printf(" lu[%d] %f\n", lsub_ptr[k], lu_col_ptr[k]); +} +#endif + + /* Determine the largest abs numerical value for partial pivoting; + Also search for user-specified pivot, and diagonal element. */ + if ( *usepr ) *pivrow = iperm_r[jcol]; + diagind = iperm_c[jcol]; + pivmax = 0.0; + pivptr = nsupc; + diag = EMPTY; + old_pivptr = nsupc; + for (isub = nsupc; isub < nsupr; ++isub) { + rtemp = fabs (lu_col_ptr[isub]); + if ( rtemp > pivmax ) { + pivmax = rtemp; + pivptr = isub; + } + if ( *usepr && lsub_ptr[isub] == *pivrow ) old_pivptr = isub; + if ( lsub_ptr[isub] == diagind ) diag = isub; + } + + /* Test for singularity */ + if ( pivmax == 0.0 ) { +#if 1 + *pivrow = lsub_ptr[pivptr]; + perm_r[*pivrow] = jcol; +#else + perm_r[diagind] = jcol; +#endif + *usepr = 0; + return (jcol+1); + } + + thresh = u * pivmax; + + /* Choose appropriate pivotal element by our policy. */ + if ( *usepr ) { + rtemp = fabs (lu_col_ptr[old_pivptr]); + if ( rtemp != 0.0 && rtemp >= thresh ) + pivptr = old_pivptr; + else + *usepr = 0; + } + if ( *usepr == 0 ) { + /* Use diagonal pivot? */ + if ( diag >= 0 ) { /* diagonal exists */ + rtemp = fabs (lu_col_ptr[diag]); + if ( rtemp != 0.0 && rtemp >= thresh ) pivptr = diag; + } + *pivrow = lsub_ptr[pivptr]; + } + + /* Record pivot row */ + perm_r[*pivrow] = jcol; + + /* Interchange row subscripts */ + if ( pivptr != nsupc ) { + itemp = lsub_ptr[pivptr]; + lsub_ptr[pivptr] = lsub_ptr[nsupc]; + lsub_ptr[nsupc] = itemp; + + /* Interchange numerical values as well, for the whole snode, such + * that L is indexed the same way as A. + */ + for (icol = 0; icol <= nsupc; icol++) { + itemp = pivptr + icol * nsupr; + temp = lu_sup_ptr[itemp]; + lu_sup_ptr[itemp] = lu_sup_ptr[nsupc + icol*nsupr]; + lu_sup_ptr[nsupc + icol*nsupr] = temp; + } + } /* if */ + + /* cdiv operation */ + ops[FACT] += nsupr - nsupc; + + temp = 1.0 / lu_col_ptr[nsupc]; + for (k = nsupc+1; k < nsupr; k++) + lu_col_ptr[k] *= temp; + + return 0; +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/spivotgrowth.c b/src/Libraries/superlu-5.2.1/SRC/spivotgrowth.c new file mode 100644 index 00000000..e8363913 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/spivotgrowth.c @@ -0,0 +1,123 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file spivotgrowth.c + * \brief Computes the reciprocal pivot growth factor + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ */ +#include +#include "slu_sdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * Compute the reciprocal pivot growth factor of the leading ncols columns
+ * of the matrix, using the formula:
+ *     min_j ( max_i(abs(A_ij)) / max_i(abs(U_ij)) )
+ *
+ * Arguments
+ * =========
+ *
+ * ncols    (input) int
+ *          The number of columns of matrices A, L and U.
+ *
+ * A        (input) SuperMatrix*
+ *	    Original matrix A, permuted by columns, of dimension
+ *          (A->nrow, A->ncol). The type of A can be:
+ *          Stype = NC; Dtype = SLU_S; Mtype = GE.
+ *
+ * L        (output) SuperMatrix*
+ *          The factor L from the factorization Pr*A=L*U; use compressed row 
+ *          subscripts storage for supernodes, i.e., L has type: 
+ *          Stype = SC; Dtype = SLU_S; Mtype = TRLU.
+ *
+ * U        (output) SuperMatrix*
+ *	    The factor U from the factorization Pr*A*Pc=L*U. Use column-wise
+ *          storage scheme, i.e., U has types: Stype = NC;
+ *          Dtype = SLU_S; Mtype = TRU.
+ * 
+ */ + +float +sPivotGrowth(int ncols, SuperMatrix *A, int *perm_c, + SuperMatrix *L, SuperMatrix *U) +{ + + NCformat *Astore; + SCformat *Lstore; + NCformat *Ustore; + float *Aval, *Lval, *Uval; + int fsupc, nsupr, luptr, nz_in_U; + int i, j, k, oldcol; + int *inv_perm_c; + float rpg, maxaj, maxuj; + float smlnum; + float *luval; + + /* Get machine constants. */ + smlnum = smach("S"); + rpg = 1. / smlnum; + + Astore = A->Store; + Lstore = L->Store; + Ustore = U->Store; + Aval = Astore->nzval; + Lval = Lstore->nzval; + Uval = Ustore->nzval; + + inv_perm_c = (int *) SUPERLU_MALLOC(A->ncol*sizeof(int)); + for (j = 0; j < A->ncol; ++j) inv_perm_c[perm_c[j]] = j; + + for (k = 0; k <= Lstore->nsuper; ++k) { + fsupc = L_FST_SUPC(k); + nsupr = L_SUB_START(fsupc+1) - L_SUB_START(fsupc); + luptr = L_NZ_START(fsupc); + luval = &Lval[luptr]; + nz_in_U = 1; + + for (j = fsupc; j < L_FST_SUPC(k+1) && j < ncols; ++j) { + maxaj = 0.; + oldcol = inv_perm_c[j]; + for (i = Astore->colptr[oldcol]; i < Astore->colptr[oldcol+1]; ++i) + maxaj = SUPERLU_MAX( maxaj, fabs(Aval[i]) ); + + maxuj = 0.; + for (i = Ustore->colptr[j]; i < Ustore->colptr[j+1]; i++) + maxuj = SUPERLU_MAX( maxuj, fabs(Uval[i]) ); + + /* Supernode */ + for (i = 0; i < nz_in_U; ++i) + maxuj = SUPERLU_MAX( maxuj, fabs(luval[i]) ); + + ++nz_in_U; + luval += nsupr; + + if ( maxuj == 0. ) + rpg = SUPERLU_MIN( rpg, 1.); + else + rpg = SUPERLU_MIN( rpg, maxaj / maxuj ); + } + + if ( j >= ncols ) break; + } + + SUPERLU_FREE(inv_perm_c); + return (rpg); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/spruneL.c b/src/Libraries/superlu-5.2.1/SRC/spruneL.c new file mode 100644 index 00000000..c9b800df --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/spruneL.c @@ -0,0 +1,164 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file spruneL.c + * \brief Prunes the L-structure + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ *
+ */ + + +#include "slu_sdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   Prunes the L-structure of supernodes whose L-structure
+ *   contains the current pivot row "pivrow"
+ * 
+ */ + +void +spruneL( + const int jcol, /* in */ + const int *perm_r, /* in */ + const int pivrow, /* in */ + const int nseg, /* in */ + const int *segrep, /* in */ + const int *repfnz, /* in */ + int *xprune, /* out */ + GlobalLU_t *Glu /* modified - global LU data structures */ + ) +{ + + float utemp; + int jsupno, irep, irep1, kmin, kmax, krow, movnum; + int i, ktemp, minloc, maxloc; + int do_prune; /* logical variable */ + int *xsup, *supno; + int *lsub, *xlsub; + float *lusup; + int *xlusup; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (float *) Glu->lusup; + xlusup = Glu->xlusup; + + /* + * For each supernode-rep irep in U[*,j] + */ + jsupno = supno[jcol]; + for (i = 0; i < nseg; i++) { + + irep = segrep[i]; + irep1 = irep + 1; + do_prune = FALSE; + + /* Don't prune with a zero U-segment */ + if ( repfnz[irep] == EMPTY ) + continue; + + /* If a snode overlaps with the next panel, then the U-segment + * is fragmented into two parts -- irep and irep1. We should let + * pruning occur at the rep-column in irep1's snode. + */ + if ( supno[irep] == supno[irep1] ) /* Don't prune */ + continue; + + /* + * If it has not been pruned & it has a nonz in row L[pivrow,i] + */ + if ( supno[irep] != jsupno ) { + if ( xprune[irep] >= xlsub[irep1] ) { + kmin = xlsub[irep]; + kmax = xlsub[irep1] - 1; + for (krow = kmin; krow <= kmax; krow++) + if ( lsub[krow] == pivrow ) { + do_prune = TRUE; + break; + } + } + + if ( do_prune ) { + + /* Do a quicksort-type partition + * movnum=TRUE means that the num values have to be exchanged. + */ + movnum = FALSE; + if ( irep == xsup[supno[irep]] ) /* Snode of size 1 */ + movnum = TRUE; + + while ( kmin <= kmax ) { + + if ( perm_r[lsub[kmax]] == EMPTY ) + kmax--; + else if ( perm_r[lsub[kmin]] != EMPTY ) + kmin++; + else { /* kmin below pivrow (not yet pivoted), and kmax + * above pivrow: interchange the two subscripts + */ + ktemp = lsub[kmin]; + lsub[kmin] = lsub[kmax]; + lsub[kmax] = ktemp; + + /* If the supernode has only one column, then we + * only keep one set of subscripts. For any subscript + * interchange performed, similar interchange must be + * done on the numerical values. + */ + if ( movnum ) { + minloc = xlusup[irep] + (kmin - xlsub[irep]); + maxloc = xlusup[irep] + (kmax - xlsub[irep]); + utemp = lusup[minloc]; + lusup[minloc] = lusup[maxloc]; + lusup[maxloc] = utemp; + } + + kmin++; + kmax--; + + } + + } /* while */ + + xprune[irep] = kmin; /* Pruning */ + +#ifdef CHK_PRUNE + printf(" After spruneL(),using col %d: xprune[%d] = %d\n", + jcol, irep, kmin); +#endif + } /* if do_prune */ + + } /* if */ + + } /* for each U-segment... */ +} diff --git a/src/Libraries/superlu-5.2.1/SRC/sreadhb.c b/src/Libraries/superlu-5.2.1/SRC/sreadhb.c new file mode 100644 index 00000000..2b91d4e9 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sreadhb.c @@ -0,0 +1,369 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sreadhb.c + * \brief Read a matrix stored in Harwell-Boeing format + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Purpose
+ * =======
+ * 
+ * Read a FLOAT PRECISION matrix stored in Harwell-Boeing format 
+ * as described below.
+ * 
+ * Line 1 (A72,A8) 
+ *  	Col. 1 - 72   Title (TITLE) 
+ *	Col. 73 - 80  Key (KEY) 
+ * 
+ * Line 2 (5I14) 
+ * 	Col. 1 - 14   Total number of lines excluding header (TOTCRD) 
+ * 	Col. 15 - 28  Number of lines for pointers (PTRCRD) 
+ * 	Col. 29 - 42  Number of lines for row (or variable) indices (INDCRD) 
+ * 	Col. 43 - 56  Number of lines for numerical values (VALCRD) 
+ *	Col. 57 - 70  Number of lines for right-hand sides (RHSCRD) 
+ *                    (including starting guesses and solution vectors 
+ *		       if present) 
+ *           	      (zero indicates no right-hand side data is present) 
+ *
+ * Line 3 (A3, 11X, 4I14) 
+ *   	Col. 1 - 3    Matrix type (see below) (MXTYPE) 
+ * 	Col. 15 - 28  Number of rows (or variables) (NROW) 
+ * 	Col. 29 - 42  Number of columns (or elements) (NCOL) 
+ *	Col. 43 - 56  Number of row (or variable) indices (NNZERO) 
+ *	              (equal to number of entries for assembled matrices) 
+ * 	Col. 57 - 70  Number of elemental matrix entries (NELTVL) 
+ *	              (zero in the case of assembled matrices) 
+ * Line 4 (2A16, 2A20) 
+ * 	Col. 1 - 16   Format for pointers (PTRFMT) 
+ *	Col. 17 - 32  Format for row (or variable) indices (INDFMT) 
+ *	Col. 33 - 52  Format for numerical values of coefficient matrix (VALFMT) 
+ * 	Col. 53 - 72 Format for numerical values of right-hand sides (RHSFMT) 
+ *
+ * Line 5 (A3, 11X, 2I14) Only present if there are right-hand sides present 
+ *    	Col. 1 	      Right-hand side type: 
+ *	         	  F for full storage or M for same format as matrix 
+ *    	Col. 2        G if a starting vector(s) (Guess) is supplied. (RHSTYP) 
+ *    	Col. 3        X if an exact solution vector(s) is supplied. 
+ *	Col. 15 - 28  Number of right-hand sides (NRHS) 
+ *	Col. 29 - 42  Number of row indices (NRHSIX) 
+ *          	      (ignored in case of unassembled matrices) 
+ *
+ * The three character type field on line 3 describes the matrix type. 
+ * The following table lists the permitted values for each of the three 
+ * characters. As an example of the type field, RSA denotes that the matrix 
+ * is real, symmetric, and assembled. 
+ *
+ * First Character: 
+ *	R Real matrix 
+ *	C Complex matrix 
+ *	P Pattern only (no numerical values supplied) 
+ *
+ * Second Character: 
+ *	S Symmetric 
+ *	U Unsymmetric 
+ *	H Hermitian 
+ *	Z Skew symmetric 
+ *	R Rectangular 
+ *
+ * Third Character: 
+ *	A Assembled 
+ *	E Elemental matrices (unassembled) 
+ *
+ * 
+ */ +#include +#include +#include "slu_sdefs.h" + + +/*! \brief Eat up the rest of the current line */ +int sDumpLine(FILE *fp) +{ + register int c; + while ((c = fgetc(fp)) != '\n') ; + return 0; +} + +int sParseIntFormat(char *buf, int *num, int *size) +{ + char *tmp; + + tmp = buf; + while (*tmp++ != '(') ; + sscanf(tmp, "%d", num); + while (*tmp != 'I' && *tmp != 'i') ++tmp; + ++tmp; + sscanf(tmp, "%d", size); + return 0; +} + +int sParseFloatFormat(char *buf, int *num, int *size) +{ + char *tmp, *period; + + tmp = buf; + while (*tmp++ != '(') ; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + while (*tmp != 'E' && *tmp != 'e' && *tmp != 'D' && *tmp != 'd' + && *tmp != 'F' && *tmp != 'f') { + /* May find kP before nE/nD/nF, like (1P6F13.6). In this case the + num picked up refers to P, which should be skipped. */ + if (*tmp=='p' || *tmp=='P') { + ++tmp; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + } else { + ++tmp; + } + } + ++tmp; + period = tmp; + while (*period != '.' && *period != ')') ++period ; + *period = '\0'; + *size = atoi(tmp); /*sscanf(tmp, "%2d", size);*/ + + return 0; +} + +static int ReadVector(FILE *fp, int n, int *where, int perline, int persize) +{ + register int i, j, item; + char tmp, buf[100]; + + i = 0; + while (i < n) { + fgets(buf, 100, fp); /* read a line at a time */ + for (j=0; j + * On input, nonz/nzval/rowind/colptr represents lower part of a symmetric + * matrix. On exit, it represents the full matrix with lower and upper parts. + * + */ +static void +FormFullA(int n, int *nonz, float **nzval, int **rowind, int **colptr) +{ + register int i, j, k, col, new_nnz; + int *t_rowind, *t_colptr, *al_rowind, *al_colptr, *a_rowind, *a_colptr; + int *marker; + float *t_val, *al_val, *a_val; + + al_rowind = *rowind; + al_colptr = *colptr; + al_val = *nzval; + + if ( !(marker =(int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for marker[]"); + if ( !(t_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC t_colptr[]"); + if ( !(t_rowind = (int *) SUPERLU_MALLOC( *nonz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for t_rowind[]"); + if ( !(t_val = (float*) SUPERLU_MALLOC( *nonz * sizeof(float)) ) ) + ABORT("SUPERLU_MALLOC fails for t_val[]"); + + /* Get counts of each column of T, and set up column pointers */ + for (i = 0; i < n; ++i) marker[i] = 0; + for (j = 0; j < n; ++j) { + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) + ++marker[al_rowind[i]]; + } + t_colptr[0] = 0; + for (i = 0; i < n; ++i) { + t_colptr[i+1] = t_colptr[i] + marker[i]; + marker[i] = t_colptr[i]; + } + + /* Transpose matrix A to T */ + for (j = 0; j < n; ++j) + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + col = al_rowind[i]; + t_rowind[marker[col]] = j; + t_val[marker[col]] = al_val[i]; + ++marker[col]; + } + + new_nnz = *nonz * 2 - n; + if ( !(a_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC a_colptr[]"); + if ( !(a_rowind = (int *) SUPERLU_MALLOC( new_nnz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for a_rowind[]"); + if ( !(a_val = (float*) SUPERLU_MALLOC( new_nnz * sizeof(float)) ) ) + ABORT("SUPERLU_MALLOC fails for a_val[]"); + + a_colptr[0] = 0; + k = 0; + for (j = 0; j < n; ++j) { + for (i = t_colptr[j]; i < t_colptr[j+1]; ++i) { + if ( t_rowind[i] != j ) { /* not diagonal */ + a_rowind[k] = t_rowind[i]; + a_val[k] = t_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + } + + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + a_rowind[k] = al_rowind[i]; + a_val[k] = al_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + + a_colptr[j+1] = k; + } + + printf("FormFullA: new_nnz = %d, k = %d\n", new_nnz, k); + + SUPERLU_FREE(al_val); + SUPERLU_FREE(al_rowind); + SUPERLU_FREE(al_colptr); + SUPERLU_FREE(marker); + SUPERLU_FREE(t_val); + SUPERLU_FREE(t_rowind); + SUPERLU_FREE(t_colptr); + + *nzval = a_val; + *rowind = a_rowind; + *colptr = a_colptr; + *nonz = new_nnz; +} + +void +sreadhb(FILE *fp, int *nrow, int *ncol, int *nonz, + float **nzval, int **rowind, int **colptr) +{ + + register int i, numer_lines = 0, rhscrd = 0; + int tmp, colnum, colsize, rownum, rowsize, valnum, valsize; + char buf[100], type[4], key[10]; + int sym; + + /* Line 1 */ + fgets(buf, 100, fp); + fputs(buf, stdout); +#if 0 + fscanf(fp, "%72c", buf); buf[72] = 0; + printf("Title: %s", buf); + fscanf(fp, "%8c", key); key[8] = 0; + printf("Key: %s\n", key); + sDumpLine(fp); +#endif + + /* Line 2 */ + for (i=0; i<5; i++) { + fscanf(fp, "%14c", buf); buf[14] = 0; + sscanf(buf, "%d", &tmp); + if (i == 3) numer_lines = tmp; + if (i == 4 && tmp) rhscrd = tmp; + } + sDumpLine(fp); + + /* Line 3 */ + fscanf(fp, "%3c", type); + fscanf(fp, "%11c", buf); /* pad */ + type[3] = 0; +#ifdef DEBUG + printf("Matrix type %s\n", type); +#endif + + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nrow); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", ncol); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nonz); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", &tmp); + + if (tmp != 0) + printf("This is not an assembled matrix!\n"); + if (*nrow != *ncol) + printf("Matrix is not square.\n"); + sDumpLine(fp); + + /* Allocate storage for the three arrays ( nzval, rowind, colptr ) */ + sallocateA(*ncol, *nonz, nzval, rowind, colptr); + + /* Line 4: format statement */ + fscanf(fp, "%16c", buf); + sParseIntFormat(buf, &colnum, &colsize); + fscanf(fp, "%16c", buf); + sParseIntFormat(buf, &rownum, &rowsize); + fscanf(fp, "%20c", buf); + sParseFloatFormat(buf, &valnum, &valsize); + fscanf(fp, "%20c", buf); + sDumpLine(fp); + + /* Line 5: right-hand side */ + if ( rhscrd ) sDumpLine(fp); /* skip RHSFMT */ + +#ifdef DEBUG + printf("%d rows, %d nonzeros\n", *nrow, *nonz); + printf("colnum %d, colsize %d\n", colnum, colsize); + printf("rownum %d, rowsize %d\n", rownum, rowsize); + printf("valnum %d, valsize %d\n", valnum, valsize); +#endif + + ReadVector(fp, *ncol+1, *colptr, colnum, colsize); + ReadVector(fp, *nonz, *rowind, rownum, rowsize); + if ( numer_lines ) { + sReadValues(fp, *nonz, *nzval, valnum, valsize); + } + + sym = (type[1] == 'S' || type[1] == 's'); + if ( sym ) { + FormFullA(*ncol, nonz, nzval, rowind, colptr); + } + + fclose(fp); +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/sreadrb.c b/src/Libraries/superlu-5.2.1/SRC/sreadrb.c new file mode 100644 index 00000000..57438ef1 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sreadrb.c @@ -0,0 +1,356 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sreadrb.c + * \brief Read a matrix stored in Rutherford-Boeing format + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ * + * Purpose + * ======= + * + * Read a FLOAT PRECISION matrix stored in Rutherford-Boeing format + * as described below. + * + * Line 1 (A72, A8) + * Col. 1 - 72 Title (TITLE) + * Col. 73 - 80 Matrix name / identifier (MTRXID) + * + * Line 2 (I14, 3(1X, I13)) + * Col. 1 - 14 Total number of lines excluding header (TOTCRD) + * Col. 16 - 28 Number of lines for pointers (PTRCRD) + * Col. 30 - 42 Number of lines for row (or variable) indices (INDCRD) + * Col. 44 - 56 Number of lines for numerical values (VALCRD) + * + * Line 3 (A3, 11X, 4(1X, I13)) + * Col. 1 - 3 Matrix type (see below) (MXTYPE) + * Col. 15 - 28 Compressed Column: Number of rows (NROW) + * Elemental: Largest integer used to index variable (MVAR) + * Col. 30 - 42 Compressed Column: Number of columns (NCOL) + * Elemental: Number of element matrices (NELT) + * Col. 44 - 56 Compressed Column: Number of entries (NNZERO) + * Elemental: Number of variable indeces (NVARIX) + * Col. 58 - 70 Compressed Column: Unused, explicitly zero + * Elemental: Number of elemental matrix entries (NELTVL) + * + * Line 4 (2A16, A20) + * Col. 1 - 16 Fortran format for pointers (PTRFMT) + * Col. 17 - 32 Fortran format for row (or variable) indices (INDFMT) + * Col. 33 - 52 Fortran format for numerical values of coefficient matrix + * (VALFMT) + * (blank in the case of matrix patterns) + * + * The three character type field on line 3 describes the matrix type. + * The following table lists the permitted values for each of the three + * characters. As an example of the type field, RSA denotes that the matrix + * is real, symmetric, and assembled. + * + * First Character: + * R Real matrix + * C Complex matrix + * I integer matrix + * P Pattern only (no numerical values supplied) + * Q Pattern only (numerical values supplied in associated auxiliary value + * file) + * + * Second Character: + * S Symmetric + * U Unsymmetric + * H Hermitian + * Z Skew symmetric + * R Rectangular + * + * Third Character: + * A Compressed column form + * E Elemental form + * + * + */ + +#include +#include +#include "slu_sdefs.h" + + +/*! \brief Eat up the rest of the current line */ +static int sDumpLine(FILE *fp) +{ + register int c; + while ((c = fgetc(fp)) != '\n') ; + return 0; +} + +static int sParseIntFormat(char *buf, int *num, int *size) +{ + char *tmp; + + tmp = buf; + while (*tmp++ != '(') ; + sscanf(tmp, "%d", num); + while (*tmp != 'I' && *tmp != 'i') ++tmp; + ++tmp; + sscanf(tmp, "%d", size); + return 0; +} + +static int sParseFloatFormat(char *buf, int *num, int *size) +{ + char *tmp, *period; + + tmp = buf; + while (*tmp++ != '(') ; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + while (*tmp != 'E' && *tmp != 'e' && *tmp != 'D' && *tmp != 'd' + && *tmp != 'F' && *tmp != 'f') { + /* May find kP before nE/nD/nF, like (1P6F13.6). In this case the + num picked up refers to P, which should be skipped. */ + if (*tmp=='p' || *tmp=='P') { + ++tmp; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + } else { + ++tmp; + } + } + ++tmp; + period = tmp; + while (*period != '.' && *period != ')') ++period ; + *period = '\0'; + *size = atoi(tmp); /*sscanf(tmp, "%2d", size);*/ + + return 0; +} + +static int ReadVector(FILE *fp, int n, int *where, int perline, int persize) +{ + register int i, j, item; + char tmp, buf[100]; + + i = 0; + while (i < n) { + fgets(buf, 100, fp); /* read a line at a time */ + for (j=0; j + * On input, nonz/nzval/rowind/colptr represents lower part of a symmetric + * matrix. On exit, it represents the full matrix with lower and upper parts. + * + */ +static void +FormFullA(int n, int *nonz, float **nzval, int **rowind, int **colptr) +{ + register int i, j, k, col, new_nnz; + int *t_rowind, *t_colptr, *al_rowind, *al_colptr, *a_rowind, *a_colptr; + int *marker; + float *t_val, *al_val, *a_val; + + al_rowind = *rowind; + al_colptr = *colptr; + al_val = *nzval; + + if ( !(marker =(int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for marker[]"); + if ( !(t_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC t_colptr[]"); + if ( !(t_rowind = (int *) SUPERLU_MALLOC( *nonz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for t_rowind[]"); + if ( !(t_val = (float*) SUPERLU_MALLOC( *nonz * sizeof(float)) ) ) + ABORT("SUPERLU_MALLOC fails for t_val[]"); + + /* Get counts of each column of T, and set up column pointers */ + for (i = 0; i < n; ++i) marker[i] = 0; + for (j = 0; j < n; ++j) { + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) + ++marker[al_rowind[i]]; + } + t_colptr[0] = 0; + for (i = 0; i < n; ++i) { + t_colptr[i+1] = t_colptr[i] + marker[i]; + marker[i] = t_colptr[i]; + } + + /* Transpose matrix A to T */ + for (j = 0; j < n; ++j) + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + col = al_rowind[i]; + t_rowind[marker[col]] = j; + t_val[marker[col]] = al_val[i]; + ++marker[col]; + } + + new_nnz = *nonz * 2 - n; + if ( !(a_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC a_colptr[]"); + if ( !(a_rowind = (int *) SUPERLU_MALLOC( new_nnz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for a_rowind[]"); + if ( !(a_val = (float*) SUPERLU_MALLOC( new_nnz * sizeof(float)) ) ) + ABORT("SUPERLU_MALLOC fails for a_val[]"); + + a_colptr[0] = 0; + k = 0; + for (j = 0; j < n; ++j) { + for (i = t_colptr[j]; i < t_colptr[j+1]; ++i) { + if ( t_rowind[i] != j ) { /* not diagonal */ + a_rowind[k] = t_rowind[i]; + a_val[k] = t_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + } + + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + a_rowind[k] = al_rowind[i]; + a_val[k] = al_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + + a_colptr[j+1] = k; + } + + printf("FormFullA: new_nnz = %d, k = %d\n", new_nnz, k); + + SUPERLU_FREE(al_val); + SUPERLU_FREE(al_rowind); + SUPERLU_FREE(al_colptr); + SUPERLU_FREE(marker); + SUPERLU_FREE(t_val); + SUPERLU_FREE(t_rowind); + SUPERLU_FREE(t_colptr); + + *nzval = a_val; + *rowind = a_rowind; + *colptr = a_colptr; + *nonz = new_nnz; +} + +void +sreadrb(int *nrow, int *ncol, int *nonz, + float **nzval, int **rowind, int **colptr) +{ + + register int i, numer_lines = 0; + int tmp, colnum, colsize, rownum, rowsize, valnum, valsize; + char buf[100], type[4]; + int sym; + FILE *fp; + + fp = stdin; + + /* Line 1 */ + fgets(buf, 100, fp); + fputs(buf, stdout); + + /* Line 2 */ + for (i=0; i<4; i++) { + fscanf(fp, "%14c", buf); buf[14] = 0; + sscanf(buf, "%d", &tmp); + if (i == 3) numer_lines = tmp; + } + sDumpLine(fp); + + /* Line 3 */ + fscanf(fp, "%3c", type); + fscanf(fp, "%11c", buf); /* pad */ + type[3] = 0; +#ifdef DEBUG + printf("Matrix type %s\n", type); +#endif + + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nrow); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", ncol); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nonz); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", &tmp); + + if (tmp != 0) + printf("This is not an assembled matrix!\n"); + if (*nrow != *ncol) + printf("Matrix is not square.\n"); + sDumpLine(fp); + + /* Allocate storage for the three arrays ( nzval, rowind, colptr ) */ + sallocateA(*ncol, *nonz, nzval, rowind, colptr); + + /* Line 4: format statement */ + fscanf(fp, "%16c", buf); + sParseIntFormat(buf, &colnum, &colsize); + fscanf(fp, "%16c", buf); + sParseIntFormat(buf, &rownum, &rowsize); + fscanf(fp, "%20c", buf); + sParseFloatFormat(buf, &valnum, &valsize); + sDumpLine(fp); + +#ifdef DEBUG + printf("%d rows, %d nonzeros\n", *nrow, *nonz); + printf("colnum %d, colsize %d\n", colnum, colsize); + printf("rownum %d, rowsize %d\n", rownum, rowsize); + printf("valnum %d, valsize %d\n", valnum, valsize); +#endif + + ReadVector(fp, *ncol+1, *colptr, colnum, colsize); + ReadVector(fp, *nonz, *rowind, rownum, rowsize); + if ( numer_lines ) { + sReadValues(fp, *nonz, *nzval, valnum, valsize); + } + + sym = (type[1] == 'S' || type[1] == 's'); + if ( sym ) { + FormFullA(*ncol, nonz, nzval, rowind, colptr); + } + + fclose(fp); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/sreadtriple.c b/src/Libraries/superlu-5.2.1/SRC/sreadtriple.c new file mode 100644 index 00000000..a3d9233d --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sreadtriple.c @@ -0,0 +1,150 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sreadtriple.c + * \brief Read a matrix stored in triplet (coordinate) format + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ + +#include "slu_sdefs.h" + + +void +sreadtriple(int *m, int *n, int *nonz, + float **nzval, int **rowind, int **colptr) +{ +/* + * Output parameters + * ================= + * (a,asub,xa): asub[*] contains the row subscripts of nonzeros + * in columns of matrix A; a[*] the numerical values; + * row i of A is given by a[k],k=xa[i],...,xa[i+1]-1. + * + */ + int j, k, jsize, nnz, nz; + float *a, *val; + int *asub, *xa, *row, *col; + int zero_base = 0; + + /* Matrix format: + * First line: #rows, #cols, #non-zero + * Triplet in the rest of lines: + * row, col, value + */ + + scanf("%d%d", n, nonz); + *m = *n; + printf("m %d, n %d, nonz %d\n", *m, *n, *nonz); + sallocateA(*n, *nonz, nzval, rowind, colptr); /* Allocate storage */ + a = *nzval; + asub = *rowind; + xa = *colptr; + + val = (float *) SUPERLU_MALLOC(*nonz * sizeof(float)); + row = (int *) SUPERLU_MALLOC(*nonz * sizeof(int)); + col = (int *) SUPERLU_MALLOC(*nonz * sizeof(int)); + + for (j = 0; j < *n; ++j) xa[j] = 0; + + /* Read into the triplet array from a file */ + for (nnz = 0, nz = 0; nnz < *nonz; ++nnz) { + scanf("%d%d%f\n", &row[nz], &col[nz], &val[nz]); + + if ( nnz == 0 ) { /* first nonzero */ + if ( row[0] == 0 || col[0] == 0 ) { + zero_base = 1; + printf("triplet file: row/col indices are zero-based.\n"); + } else + printf("triplet file: row/col indices are one-based.\n"); + } + + if ( !zero_base ) { + /* Change to 0-based indexing. */ + --row[nz]; + --col[nz]; + } + + if (row[nz] < 0 || row[nz] >= *m || col[nz] < 0 || col[nz] >= *n + /*|| val[nz] == 0.*/) { + fprintf(stderr, "nz %d, (%d, %d) = %e out of bound, removed\n", + nz, row[nz], col[nz], val[nz]); + exit(-1); + } else { + ++xa[col[nz]]; + ++nz; + } + } + + *nonz = nz; + + /* Initialize the array of column pointers */ + k = 0; + jsize = xa[0]; + xa[0] = 0; + for (j = 1; j < *n; ++j) { + k += jsize; + jsize = xa[j]; + xa[j] = k; + } + + /* Copy the triplets into the column oriented storage */ + for (nz = 0; nz < *nonz; ++nz) { + j = col[nz]; + k = xa[j]; + asub[k] = row[nz]; + a[k] = val[nz]; + ++xa[j]; + } + + /* Reset the column pointers to the beginning of each column */ + for (j = *n; j > 0; --j) + xa[j] = xa[j-1]; + xa[0] = 0; + + SUPERLU_FREE(val); + SUPERLU_FREE(row); + SUPERLU_FREE(col); + +#ifdef CHK_INPUT + { + int i; + for (i = 0; i < *n; i++) { + printf("Col %d, xa %d\n", i, xa[i]); + for (k = xa[i]; k < xa[i+1]; k++) + printf("%d\t%16.10f\n", asub[k], a[k]); + } + } +#endif + +} + + +void sreadrhs(int m, float *b) +{ + FILE *fp, *fopen(); + int i; + /*int j;*/ + + if ( !(fp = fopen("b.dat", "r")) ) { + fprintf(stderr, "dreadrhs: file does not exist\n"); + exit(-1); + } + for (i = 0; i < m; ++i) + fscanf(fp, "%f\n", &b[i]); + + /* readpair_(j, &b[i]);*/ + fclose(fp); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ssnode_bmod.c b/src/Libraries/superlu-5.2.1/SRC/ssnode_bmod.c new file mode 100644 index 00000000..fd1f9c6f --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ssnode_bmod.c @@ -0,0 +1,128 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ssnode_bmod.c + * \brief Performs numeric block updates within the relaxed snode. + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_sdefs.h" + + +/*! \brief Performs numeric block updates within the relaxed snode. + */ +int +ssnode_bmod ( + const int jcol, /* in */ + const int jsupno, /* in */ + const int fsupc, /* in */ + float *dense, /* in */ + float *tempv, /* working array */ + GlobalLU_t *Glu, /* modified */ + SuperLUStat_t *stat /* output */ + ) +{ +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + int incx = 1, incy = 1; + float alpha = -1.0, beta = 1.0; +#endif + + int luptr, nsupc, nsupr, nrow; + int isub, irow, i, iptr; + register int ufirst, nextlu; + int *lsub, *xlsub; + float *lusup; + int *xlusup; + flops_t *ops = stat->ops; + + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (float *) Glu->lusup; + xlusup = Glu->xlusup; + + nextlu = xlusup[jcol]; + + /* + * Process the supernodal portion of L\U[*,j] + */ + for (isub = xlsub[fsupc]; isub < xlsub[fsupc+1]; isub++) { + irow = lsub[isub]; + lusup[nextlu] = dense[irow]; + dense[irow] = 0; + ++nextlu; + } + + xlusup[jcol + 1] = nextlu; /* Initialize xlusup for next column */ + + if ( fsupc < jcol ) { + + luptr = xlusup[fsupc]; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; + nsupc = jcol - fsupc; /* Excluding jcol */ + ufirst = xlusup[jcol]; /* Points to the beginning of column + jcol in supernode L\U(jsupno). */ + nrow = nsupr - nsupc; + + ops[TRSV] += nsupc * (nsupc - 1); + ops[GEMV] += 2 * nrow * nsupc; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + STRSV( ftcs1, ftcs2, ftcs3, &nsupc, &lusup[luptr], &nsupr, + &lusup[ufirst], &incx ); + SGEMV( ftcs2, &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#else + strsv_( "L", "N", "U", &nsupc, &lusup[luptr], &nsupr, + &lusup[ufirst], &incx ); + sgemv_( "N", &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#endif +#else + slsolve ( nsupr, nsupc, &lusup[luptr], &lusup[ufirst] ); + smatvec ( nsupr, nrow, nsupc, &lusup[luptr+nsupc], + &lusup[ufirst], &tempv[0] ); + + /* Scatter tempv[*] into lusup[*] */ + iptr = ufirst + nsupc; + for (i = 0; i < nrow; i++) { + lusup[iptr++] -= tempv[i]; + tempv[i] = 0.0; + } +#endif + + } + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/ssnode_dfs.c b/src/Libraries/superlu-5.2.1/SRC/ssnode_dfs.c new file mode 100644 index 00000000..902cc60b --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ssnode_dfs.c @@ -0,0 +1,122 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ssnode_dfs.c + * \brief Determines the union of row structures of columns within the relaxed node + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_sdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *    ssnode_dfs() - Determine the union of the row structures of those 
+ *    columns within the relaxed snode.
+ *    Note: The relaxed snodes are leaves of the supernodal etree, therefore, 
+ *    the portion outside the rectangular supernode must be zero.
+ *
+ * Return value
+ * ============
+ *     0   success;
+ *    >0   number of bytes allocated when run out of memory.
+ * 
+ */ + +int +ssnode_dfs ( + const int jcol, /* in - start of the supernode */ + const int kcol, /* in - end of the supernode */ + const int *asub, /* in */ + const int *xa_begin, /* in */ + const int *xa_end, /* in */ + int *xprune, /* out */ + int *marker, /* modified */ + GlobalLU_t *Glu /* modified */ + ) +{ + + register int i, k, ifrom, ito, nextl, new_next; + int nsuper, krow, kmark, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + int nzlmax; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + nsuper = ++supno[jcol]; /* Next available supernode number */ + nextl = xlsub[jcol]; + + for (i = jcol; i <= kcol; i++) { + /* For each nonzero in A[*,i] */ + for (k = xa_begin[i]; k < xa_end[i]; k++) { + krow = asub[k]; + kmark = marker[krow]; + if ( kmark != kcol ) { /* First time visit krow */ + marker[krow] = kcol; + lsub[nextl++] = krow; + if ( nextl >= nzlmax ) { + if ( mem_error = sLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + } + } + supno[i] = nsuper; + } + + /* Supernode > 1, then make a copy of the subscripts for pruning */ + if ( jcol < kcol ) { + new_next = nextl + (nextl - xlsub[jcol]); + while ( new_next > nzlmax ) { + if ( mem_error = sLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + ito = nextl; + for (ifrom = xlsub[jcol]; ifrom < nextl; ) + lsub[ito++] = lsub[ifrom++]; + for (i = jcol+1; i <= kcol; i++) xlsub[i] = nextl; + nextl = ito; + } + + xsup[nsuper+1] = kcol + 1; + supno[kcol+1] = nsuper; + xprune[kcol] = nextl; + xlsub[kcol+1] = nextl; + + return 0; +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/ssp_blas2.c b/src/Libraries/superlu-5.2.1/SRC/ssp_blas2.c new file mode 100644 index 00000000..91b03802 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ssp_blas2.c @@ -0,0 +1,490 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ssp_blas2.c + * \brief Sparse BLAS 2, using some dense BLAS 2 operations + * + *
+ * -- SuperLU routine (version 5.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Last update: December 3, 2015
+ * 
+ */ +/* + * File name: ssp_blas2.c + * Purpose: Sparse BLAS 2, using some dense BLAS 2 operations. + */ + +#include "slu_sdefs.h" + +/* + * Function prototypes + */ +void susolve(int, int, float*, float*); +void slsolve(int, int, float*, float*); +void smatvec(int, int, int, float*, float*, float*); + +/*! \brief Solves one of the systems of equations A*x = b, or A'*x = b + * + *
+ *   Purpose
+ *   =======
+ *
+ *   sp_strsv() solves one of the systems of equations   
+ *       A*x = b,   or   A'*x = b,
+ *   where b and x are n element vectors and A is a sparse unit , or   
+ *   non-unit, upper or lower triangular matrix.   
+ *   No test for singularity or near-singularity is included in this   
+ *   routine. Such tests must be performed before calling this routine.   
+ *
+ *   Parameters   
+ *   ==========   
+ *
+ *   uplo   - (input) char*
+ *            On entry, uplo specifies whether the matrix is an upper or   
+ *             lower triangular matrix as follows:   
+ *                uplo = 'U' or 'u'   A is an upper triangular matrix.   
+ *                uplo = 'L' or 'l'   A is a lower triangular matrix.   
+ *
+ *   trans  - (input) char*
+ *             On entry, trans specifies the equations to be solved as   
+ *             follows:   
+ *                trans = 'N' or 'n'   A*x = b.   
+ *                trans = 'T' or 't'   A'*x = b.
+ *                trans = 'C' or 'c'   A'*x = b.   
+ *
+ *   diag   - (input) char*
+ *             On entry, diag specifies whether or not A is unit   
+ *             triangular as follows:   
+ *                diag = 'U' or 'u'   A is assumed to be unit triangular.   
+ *                diag = 'N' or 'n'   A is not assumed to be unit   
+ *                                    triangular.   
+ *	     
+ *   L       - (input) SuperMatrix*
+ *	       The factor L from the factorization Pr*A*Pc=L*U. Use
+ *             compressed row subscripts storage for supernodes,
+ *             i.e., L has types: Stype = SC, Dtype = SLU_S, Mtype = TRLU.
+ *
+ *   U       - (input) SuperMatrix*
+ *	        The factor U from the factorization Pr*A*Pc=L*U.
+ *	        U has types: Stype = NC, Dtype = SLU_S, Mtype = TRU.
+ *    
+ *   x       - (input/output) float*
+ *             Before entry, the incremented array X must contain the n   
+ *             element right-hand side vector b. On exit, X is overwritten 
+ *             with the solution vector x.
+ *
+ *   info    - (output) int*
+ *             If *info = -i, the i-th argument had an illegal value.
+ * 
+ */ +int +sp_strsv(char *uplo, char *trans, char *diag, SuperMatrix *L, + SuperMatrix *U, float *x, SuperLUStat_t *stat, int *info) +{ +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + SCformat *Lstore; + NCformat *Ustore; + float *Lval, *Uval; + int incx = 1, incy = 1; + float alpha = 1.0, beta = 1.0; + int nrow; + int fsupc, nsupr, nsupc, luptr, istart, irow; + int i, k, iptr, jcol; + float *work; + flops_t solve_ops; + + /* Test the input parameters */ + *info = 0; + if ( strncmp(uplo,"L", 1)!=0 && strncmp(uplo, "U", 1)!=0 ) *info = -1; + else if ( strncmp(trans, "N", 1)!=0 && strncmp(trans, "T", 1)!=0 && + strncmp(trans, "C", 1)!=0) *info = -2; + else if ( strncmp(diag, "U", 1)!=0 && strncmp(diag, "N", 1)!=0 ) + *info = -3; + else if ( L->nrow != L->ncol || L->nrow < 0 ) *info = -4; + else if ( U->nrow != U->ncol || U->nrow < 0 ) *info = -5; + if ( *info ) { + i = -(*info); + input_error("sp_strsv", &i); + return 0; + } + + Lstore = L->Store; + Lval = Lstore->nzval; + Ustore = U->Store; + Uval = Ustore->nzval; + solve_ops = 0; + + if ( !(work = floatCalloc(L->nrow)) ) + ABORT("Malloc fails for work in sp_strsv()."); + + if ( strncmp(trans, "N", 1)==0 ) { /* Form x := inv(A)*x. */ + + if ( strncmp(uplo, "L", 1)==0 ) { + /* Form x := inv(L)*x */ + if ( L->nrow == 0 ) return 0; /* Quick return */ + + for (k = 0; k <= Lstore->nsuper; k++) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + nrow = nsupr - nsupc; + + solve_ops += nsupc * (nsupc - 1); + solve_ops += 2 * nrow * nsupc; + + if ( nsupc == 1 ) { + for (iptr=istart+1; iptr < L_SUB_START(fsupc+1); ++iptr) { + irow = L_SUB(iptr); + ++luptr; + x[irow] -= x[fsupc] * Lval[luptr]; + } + } else { +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + STRSV(ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); + + SGEMV(ftcs2, &nrow, &nsupc, &alpha, &Lval[luptr+nsupc], + &nsupr, &x[fsupc], &incx, &beta, &work[0], &incy); +#else + strsv_("L", "N", "U", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); + + sgemv_("N", &nrow, &nsupc, &alpha, &Lval[luptr+nsupc], + &nsupr, &x[fsupc], &incx, &beta, &work[0], &incy); +#endif +#else + slsolve ( nsupr, nsupc, &Lval[luptr], &x[fsupc]); + + smatvec ( nsupr, nsupr-nsupc, nsupc, &Lval[luptr+nsupc], + &x[fsupc], &work[0] ); +#endif + + iptr = istart + nsupc; + for (i = 0; i < nrow; ++i, ++iptr) { + irow = L_SUB(iptr); + x[irow] -= work[i]; /* Scatter */ + work[i] = 0.0; + + } + } + } /* for k ... */ + + } else { + /* Form x := inv(U)*x */ + + if ( U->nrow == 0 ) return 0; /* Quick return */ + + for (k = Lstore->nsuper; k >= 0; k--) { + fsupc = L_FST_SUPC(k); + nsupr = L_SUB_START(fsupc+1) - L_SUB_START(fsupc); + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + solve_ops += nsupc * (nsupc + 1); + + if ( nsupc == 1 ) { + x[fsupc] /= Lval[luptr]; + for (i = U_NZ_START(fsupc); i < U_NZ_START(fsupc+1); ++i) { + irow = U_SUB(i); + x[irow] -= x[fsupc] * Uval[i]; + } + } else { +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + STRSV(ftcs3, ftcs2, ftcs2, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + strsv_("U", "N", "N", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif +#else + susolve ( nsupr, nsupc, &Lval[luptr], &x[fsupc] ); +#endif + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + solve_ops += 2*(U_NZ_START(jcol+1) - U_NZ_START(jcol)); + for (i = U_NZ_START(jcol); i < U_NZ_START(jcol+1); + i++) { + irow = U_SUB(i); + x[irow] -= x[jcol] * Uval[i]; + } + } + } + } /* for k ... */ + + } + } else { /* Form x := inv(A')*x */ + + if ( strncmp(uplo, "L", 1)==0 ) { + /* Form x := inv(L')*x */ + if ( L->nrow == 0 ) return 0; /* Quick return */ + + for (k = Lstore->nsuper; k >= 0; --k) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + solve_ops += 2 * (nsupr - nsupc) * nsupc; + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + iptr = istart + nsupc; + for (i = L_NZ_START(jcol) + nsupc; + i < L_NZ_START(jcol+1); i++) { + irow = L_SUB(iptr); + x[jcol] -= x[irow] * Lval[i]; + iptr++; + } + } + + if ( nsupc > 1 ) { + solve_ops += nsupc * (nsupc - 1); +#ifdef _CRAY + ftcs1 = _cptofcd("L", strlen("L")); + ftcs2 = _cptofcd("T", strlen("T")); + ftcs3 = _cptofcd("U", strlen("U")); + STRSV(ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + strsv_("L", "T", "U", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif + } + } + } else { + /* Form x := inv(U')*x */ + if ( U->nrow == 0 ) return 0; /* Quick return */ + + for (k = 0; k <= Lstore->nsuper; k++) { + fsupc = L_FST_SUPC(k); + nsupr = L_SUB_START(fsupc+1) - L_SUB_START(fsupc); + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + solve_ops += 2*(U_NZ_START(jcol+1) - U_NZ_START(jcol)); + for (i = U_NZ_START(jcol); i < U_NZ_START(jcol+1); i++) { + irow = U_SUB(i); + x[jcol] -= x[irow] * Uval[i]; + } + } + + solve_ops += nsupc * (nsupc + 1); + + if ( nsupc == 1 ) { + x[fsupc] /= Lval[luptr]; + } else { +#ifdef _CRAY + ftcs1 = _cptofcd("U", strlen("U")); + ftcs2 = _cptofcd("T", strlen("T")); + ftcs3 = _cptofcd("N", strlen("N")); + STRSV( ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + strsv_("U", "T", "N", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif + } + } /* for k ... */ + } + } + + stat->ops[SOLVE] += solve_ops; + SUPERLU_FREE(work); + return 0; +} + + + +/*! \brief Performs one of the matrix-vector operations y := alpha*A*x + beta*y, or y := alpha*A'*x + beta*y, + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   sp_sgemv()  performs one of the matrix-vector operations   
+ *      y := alpha*A*x + beta*y,   or   y := alpha*A'*x + beta*y,   
+ *   where alpha and beta are scalars, x and y are vectors and A is a
+ *   sparse A->nrow by A->ncol matrix.   
+ *
+ *   Parameters   
+ *   ==========   
+ *
+ *   TRANS  - (input) char*
+ *            On entry, TRANS specifies the operation to be performed as   
+ *            follows:   
+ *               TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.   
+ *               TRANS = 'T' or 't'   y := alpha*A'*x + beta*y.   
+ *               TRANS = 'C' or 'c'   y := alpha*A'*x + beta*y.   
+ *
+ *   ALPHA  - (input) float
+ *            On entry, ALPHA specifies the scalar alpha.   
+ *
+ *   A      - (input) SuperMatrix*
+ *            Matrix A with a sparse format, of dimension (A->nrow, A->ncol).
+ *            Currently, the type of A can be:
+ *                Stype = NC or NCP; Dtype = SLU_S; Mtype = GE. 
+ *            In the future, more general A can be handled.
+ *
+ *   X      - (input) float*, array of DIMENSION at least   
+ *            ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'   
+ *            and at least   
+ *            ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.   
+ *            Before entry, the incremented array X must contain the   
+ *            vector x.   
+ *
+ *   INCX   - (input) int
+ *            On entry, INCX specifies the increment for the elements of   
+ *            X. INCX must not be zero.   
+ *
+ *   BETA   - (input) float
+ *            On entry, BETA specifies the scalar beta. When BETA is   
+ *            supplied as zero then Y need not be set on input.   
+ *
+ *   Y      - (output) float*,  array of DIMENSION at least   
+ *            ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'   
+ *            and at least   
+ *            ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.   
+ *            Before entry with BETA non-zero, the incremented array Y   
+ *            must contain the vector y. On exit, Y is overwritten by the 
+ *            updated vector y.
+ *	     
+ *   INCY   - (input) int
+ *            On entry, INCY specifies the increment for the elements of   
+ *            Y. INCY must not be zero.   
+ *
+ *   ==== Sparse Level 2 Blas routine.   
+ * 
+ */ + +int +sp_sgemv(char *trans, float alpha, SuperMatrix *A, float *x, + int incx, float beta, float *y, int incy) +{ + /* Local variables */ + NCformat *Astore; + float *Aval; + int info; + float temp; + int lenx, leny, i, j, irow; + int iy, jx, jy, kx, ky; + int notran; + + notran = ( strncmp(trans, "N", 1)==0 || strncmp(trans, "n", 1)==0 ); + Astore = A->Store; + Aval = Astore->nzval; + + /* Test the input parameters */ + info = 0; + if ( !notran && strncmp(trans, "T", 1)!=0 && strncmp(trans, "C", 1)!=0 ) + info = 1; + else if ( A->nrow < 0 || A->ncol < 0 ) info = 3; + else if (incx == 0) info = 5; + else if (incy == 0) info = 8; + if (info != 0) { + input_error("sp_sgemv ", &info); + return 0; + } + + /* Quick return if possible. */ + if (A->nrow == 0 || A->ncol == 0 || (alpha == 0. && beta == 1.)) + return 0; + + /* Set LENX and LENY, the lengths of the vectors x and y, and set + up the start points in X and Y. */ + if (strncmp(trans, "N", 1)==0) { + lenx = A->ncol; + leny = A->nrow; + } else { + lenx = A->nrow; + leny = A->ncol; + } + if (incx > 0) kx = 0; + else kx = - (lenx - 1) * incx; + if (incy > 0) ky = 0; + else ky = - (leny - 1) * incy; + + /* Start the operations. In this version the elements of A are + accessed sequentially with one pass through A. */ + /* First form y := beta*y. */ + if (beta != 1.) { + if (incy == 1) { + if (beta == 0.) + for (i = 0; i < leny; ++i) y[i] = 0.; + else + for (i = 0; i < leny; ++i) y[i] = beta * y[i]; + } else { + iy = ky; + if (beta == 0.) + for (i = 0; i < leny; ++i) { + y[iy] = 0.; + iy += incy; + } + else + for (i = 0; i < leny; ++i) { + y[iy] = beta * y[iy]; + iy += incy; + } + } + } + + if (alpha == 0.) return 0; + + if ( notran ) { + /* Form y := alpha*A*x + y. */ + jx = kx; + if (incy == 1) { + for (j = 0; j < A->ncol; ++j) { + if (x[jx] != 0.) { + temp = alpha * x[jx]; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + y[irow] += temp * Aval[i]; + } + } + jx += incx; + } + } else { + ABORT("Not implemented."); + } + } else { + /* Form y := alpha*A'*x + y. */ + jy = ky; + if (incx == 1) { + for (j = 0; j < A->ncol; ++j) { + temp = 0.; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + temp += Aval[i] * x[irow]; + } + y[jy] += alpha * temp; + jy += incy; + } + } else { + ABORT("Not implemented."); + } + } + + return 0; +} /* sp_sgemv */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/ssp_blas3.c b/src/Libraries/superlu-5.2.1/SRC/ssp_blas3.c new file mode 100644 index 00000000..91ae3ac9 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/ssp_blas3.c @@ -0,0 +1,137 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file ssp_blas3.c + * \brief Sparse BLAS3, using some dense BLAS3 operations + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ */ +/* + * File name: sp_blas3.c + * Purpose: Sparse BLAS3, using some dense BLAS3 operations. + */ + +#include "slu_sdefs.h" + +/*! \brief + * + *
+ * Purpose   
+ *   =======   
+ * 
+ *   sp_s performs one of the matrix-matrix operations   
+ * 
+ *      C := alpha*op( A )*op( B ) + beta*C,   
+ * 
+ *   where  op( X ) is one of 
+ * 
+ *      op( X ) = X   or   op( X ) = X'   or   op( X ) = conjg( X' ),
+ * 
+ *   alpha and beta are scalars, and A, B and C are matrices, with op( A ) 
+ *   an m by k matrix,  op( B )  a  k by n matrix and  C an m by n matrix. 
+ *   
+ * 
+ *   Parameters   
+ *   ==========   
+ * 
+ *   TRANSA - (input) char*
+ *            On entry, TRANSA specifies the form of op( A ) to be used in 
+ *            the matrix multiplication as follows:   
+ *               TRANSA = 'N' or 'n',  op( A ) = A.   
+ *               TRANSA = 'T' or 't',  op( A ) = A'.   
+ *               TRANSA = 'C' or 'c',  op( A ) = conjg( A' ).   
+ *            Unchanged on exit.   
+ * 
+ *   TRANSB - (input) char*
+ *            On entry, TRANSB specifies the form of op( B ) to be used in 
+ *            the matrix multiplication as follows:   
+ *               TRANSB = 'N' or 'n',  op( B ) = B.   
+ *               TRANSB = 'T' or 't',  op( B ) = B'.   
+ *               TRANSB = 'C' or 'c',  op( B ) = conjg( B' ).   
+ *            Unchanged on exit.   
+ * 
+ *   M      - (input) int   
+ *            On entry,  M  specifies  the number of rows of the matrix 
+ *	     op( A ) and of the matrix C.  M must be at least zero. 
+ *	     Unchanged on exit.   
+ * 
+ *   N      - (input) int
+ *            On entry,  N specifies the number of columns of the matrix 
+ *	     op( B ) and the number of columns of the matrix C. N must be 
+ *	     at least zero.
+ *	     Unchanged on exit.   
+ * 
+ *   K      - (input) int
+ *            On entry, K specifies the number of columns of the matrix 
+ *	     op( A ) and the number of rows of the matrix op( B ). K must 
+ *	     be at least  zero.   
+ *           Unchanged on exit.
+ *      
+ *   ALPHA  - (input) float
+ *            On entry, ALPHA specifies the scalar alpha.   
+ * 
+ *   A      - (input) SuperMatrix*
+ *            Matrix A with a sparse format, of dimension (A->nrow, A->ncol).
+ *            Currently, the type of A can be:
+ *                Stype = NC or NCP; Dtype = SLU_S; Mtype = GE. 
+ *            In the future, more general A can be handled.
+ * 
+ *   B      - FLOAT PRECISION array of DIMENSION ( LDB, kb ), where kb is 
+ *            n when TRANSB = 'N' or 'n',  and is  k otherwise.   
+ *            Before entry with  TRANSB = 'N' or 'n',  the leading k by n 
+ *            part of the array B must contain the matrix B, otherwise 
+ *            the leading n by k part of the array B must contain the 
+ *            matrix B.   
+ *            Unchanged on exit.   
+ * 
+ *   LDB    - (input) int
+ *            On entry, LDB specifies the first dimension of B as declared 
+ *            in the calling (sub) program. LDB must be at least max( 1, n ).  
+ *            Unchanged on exit.   
+ * 
+ *   BETA   - (input) float
+ *            On entry, BETA specifies the scalar beta. When BETA is   
+ *            supplied as zero then C need not be set on input.   
+ *  
+ *   C      - FLOAT PRECISION array of DIMENSION ( LDC, n ).   
+ *            Before entry, the leading m by n part of the array C must 
+ *            contain the matrix C,  except when beta is zero, in which 
+ *            case C need not be set on entry.   
+ *            On exit, the array C is overwritten by the m by n matrix 
+ *	     ( alpha*op( A )*B + beta*C ).   
+ *  
+ *   LDC    - (input) int
+ *            On entry, LDC specifies the first dimension of C as declared 
+ *            in the calling (sub)program. LDC must be at least max(1,m).   
+ *            Unchanged on exit.   
+ *  
+ *   ==== Sparse Level 3 Blas routine.   
+ * 
+ */ + +int +sp_sgemm(char *transa, char *transb, int m, int n, int k, + float alpha, SuperMatrix *A, float *b, int ldb, + float beta, float *c, int ldc) +{ + int incx = 1, incy = 1; + int j; + + for (j = 0; j < n; ++j) { + sp_sgemv(transa, alpha, A, &b[ldb*j], incx, beta, &c[ldc*j], incy); + } + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/superlu_enum_consts.h b/src/Libraries/superlu-5.2.1/SRC/superlu_enum_consts.h new file mode 100644 index 00000000..07fb1a4a --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/superlu_enum_consts.h @@ -0,0 +1,81 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/** @file superlu_enum_consts.h + * \brief enum constants header file + * + * -- SuperLU routine (version 4.1) -- + * Lawrence Berkeley National Lab, Univ. of California Berkeley, + * October 1, 2010 + * + */ + +#ifndef __SUPERLU_ENUM_CONSTS /* allow multiple inclusions */ +#define __SUPERLU_ENUM_CONSTS + +/*********************************************************************** + * Enumerate types + ***********************************************************************/ +typedef enum {NO, YES} yes_no_t; +typedef enum {DOFACT, SamePattern, SamePattern_SameRowPerm, FACTORED} fact_t; +typedef enum {NOROWPERM, LargeDiag, MY_PERMR} rowperm_t; +typedef enum {NATURAL, MMD_ATA, MMD_AT_PLUS_A, COLAMD, + METIS_AT_PLUS_A, PARMETIS, ZOLTAN, MY_PERMC} colperm_t; +typedef enum {NOTRANS, TRANS, CONJ} trans_t; +typedef enum {NOEQUIL, ROW, COL, BOTH} DiagScale_t; +typedef enum {NOREFINE, SLU_SINGLE=1, SLU_DOUBLE, SLU_EXTRA} IterRefine_t; +typedef enum {LUSUP, UCOL, LSUB, USUB, LLVL, ULVL} MemType; +typedef enum {HEAD, TAIL} stack_end_t; +typedef enum {SYSTEM, USER} LU_space_t; +typedef enum {ONE_NORM, TWO_NORM, INF_NORM} norm_t; +typedef enum {SILU, SMILU_1, SMILU_2, SMILU_3} milu_t; +#if 0 +typedef enum {NODROP = 0x0000, + DROP_BASIC = 0x0001, /* ILU(tau) */ + DROP_PROWS = 0x0002, /* ILUTP: keep p maximum rows */ + DROP_COLUMN = 0x0004, /* ILUTP: for j-th column, + p = gamma * nnz(A(:,j)) */ + DROP_AREA = 0x0008, /* ILUTP: for j-th column, use + nnz(F(:,1:j)) / nnz(A(:,1:j)) + to limit memory growth */ + DROP_SECONDARY = 0x000E, /* PROWS | COLUMN | AREA */ + DROP_DYNAMIC = 0x0010, + DROP_INTERP = 0x0100} rule_t; +#endif + + +/* + * The following enumerate type is used by the statistics variable + * to keep track of flop count and time spent at various stages. + * + * Note that not all of the fields are disjoint. + */ +typedef enum { + COLPERM, /* find a column ordering that minimizes fills */ + ROWPERM, /* find a row ordering maximizes diagonal. */ + RELAX, /* find artificial supernodes */ + ETREE, /* compute column etree */ + EQUIL, /* equilibrate the original matrix */ + SYMBFAC, /* symbolic factorization. */ + DIST, /* distribute matrix. */ + FACT, /* perform LU factorization */ + COMM, /* communication for factorization */ + SOL_COMM,/* communication for solve */ + RCOND, /* estimate reciprocal condition number */ + SOLVE, /* forward and back solves */ + REFINE, /* perform iterative refinement */ + TRSV, /* fraction of FACT spent in xTRSV */ + GEMV, /* fraction of FACT spent in xGEMV */ + FERR, /* estimate error bounds after iterative refinement */ + NPHASES /* total number of phases */ +} PhaseType; + + +#endif /* __SUPERLU_ENUM_CONSTS */ diff --git a/src/Libraries/superlu-5.2.1/SRC/superlu_timer.c b/src/Libraries/superlu-5.2.1/SRC/superlu_timer.c new file mode 100644 index 00000000..1d2283f8 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/superlu_timer.c @@ -0,0 +1,82 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file superlu_timer.c + * \brief Returns the time used + * + *
+ * Purpose
+ * ======= 
+ * 
+ * Returns the time in seconds used by the process.
+ *
+ * Note: the timer function call is machine dependent. Use conditional
+ *       compilation to choose the appropriate function.
+ * 
+ */ + + +#ifdef SUN +/* + * It uses the system call gethrtime(3C), which is accurate to + * nanoseconds. +*/ +#include + +double SuperLU_timer_() { + return ( (double)gethrtime() / 1e9 ); +} + +#elif _WIN32 + +#include + +double SuperLU_timer_() +{ + clock_t t; + t=clock(); + + return ((double)t)/CLOCKS_PER_SEC; +} + +#else + +#ifndef NO_TIMER +#include +#include +#include +#include +#endif + +/*! \brief Timer function + */ + +double SuperLU_timer_() +{ +#ifdef NO_TIMER + /* no sys/times.h on WIN32 */ + double tmp; + tmp = 0.0; + /* return (double)(tmp) / CLK_TCK;*/ + return 0.0; +#else + struct tms use; + double tmp; + int clocks_per_sec = sysconf(_SC_CLK_TCK); + + times ( &use ); + tmp = use.tms_utime; + tmp += use.tms_stime; + return (double)(tmp) / clocks_per_sec; +#endif +} + +#endif + diff --git a/src/Libraries/superlu-5.2.1/SRC/supermatrix.h b/src/Libraries/superlu-5.2.1/SRC/supermatrix.h new file mode 100644 index 00000000..52374519 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/supermatrix.h @@ -0,0 +1,190 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file supermatrix.h + * \brief Defines matrix types + */ +#ifndef __SUPERLU_SUPERMATRIX /* allow multiple inclusions */ +#define __SUPERLU_SUPERMATRIX + + +/******************************************** + * The matrix types are defined as follows. * + ********************************************/ +typedef enum { + SLU_NC, /* column-wise, no supernode */ + SLU_NCP, /* column-wise, column-permuted, no supernode + (The consecutive columns of nonzeros, after permutation, + may not be stored contiguously.) */ + SLU_NR, /* row-wize, no supernode */ + SLU_SC, /* column-wise, supernode */ + SLU_SCP, /* supernode, column-wise, permuted */ + SLU_SR, /* row-wise, supernode */ + SLU_DN, /* Fortran style column-wise storage for dense matrix */ + SLU_NR_loc /* distributed compressed row format */ +} Stype_t; + +typedef enum { + SLU_S, /* single */ + SLU_D, /* double */ + SLU_C, /* single complex */ + SLU_Z /* double complex */ +} Dtype_t; + +typedef enum { + SLU_GE, /* general */ + SLU_TRLU, /* lower triangular, unit diagonal */ + SLU_TRUU, /* upper triangular, unit diagonal */ + SLU_TRL, /* lower triangular */ + SLU_TRU, /* upper triangular */ + SLU_SYL, /* symmetric, store lower half */ + SLU_SYU, /* symmetric, store upper half */ + SLU_HEL, /* Hermitian, store lower half */ + SLU_HEU /* Hermitian, store upper half */ +} Mtype_t; + +typedef struct { + Stype_t Stype; /* Storage type: interprets the storage structure + pointed to by *Store. */ + Dtype_t Dtype; /* Data type. */ + Mtype_t Mtype; /* Matrix type: describes the mathematical property of + the matrix. */ + int_t nrow; /* number of rows */ + int_t ncol; /* number of columns */ + void *Store; /* pointer to the actual storage of the matrix */ +} SuperMatrix; + +/*********************************************** + * The storage schemes are defined as follows. * + ***********************************************/ + +/* Stype == SLU_NC (Also known as Harwell-Boeing sparse matrix format) */ +typedef struct { + int_t nnz; /* number of nonzeros in the matrix */ + void *nzval; /* pointer to array of nonzero values, packed by column */ + int_t *rowind; /* pointer to array of row indices of the nonzeros */ + int_t *colptr; /* pointer to array of beginning of columns in nzval[] + and rowind[] */ + /* Note: + Zero-based indexing is used; + colptr[] has ncol+1 entries, the last one pointing + beyond the last column, so that colptr[ncol] = nnz. */ +} NCformat; + +/* Stype == SLU_NR */ +typedef struct { + int_t nnz; /* number of nonzeros in the matrix */ + void *nzval; /* pointer to array of nonzero values, packed by raw */ + int_t *colind; /* pointer to array of columns indices of the nonzeros */ + int_t *rowptr; /* pointer to array of beginning of rows in nzval[] + and colind[] */ + /* Note: + Zero-based indexing is used; + rowptr[] has nrow+1 entries, the last one pointing + beyond the last row, so that rowptr[nrow] = nnz. */ +} NRformat; + +/* Stype == SLU_SC */ +typedef struct { + int_t nnz; /* number of nonzeros in the matrix */ + int_t nsuper; /* number of supernodes, minus 1 */ + void *nzval; /* pointer to array of nonzero values, packed by column */ + int_t *nzval_colptr;/* pointer to array of beginning of columns in nzval[] */ + int_t *rowind; /* pointer to array of compressed row indices of + rectangular supernodes */ + int_t *rowind_colptr;/* pointer to array of beginning of columns in rowind[] */ + int_t *col_to_sup; /* col_to_sup[j] is the supernode number to which column + j belongs; mapping from column to supernode number. */ + int_t *sup_to_col; /* sup_to_col[s] points to the start of the s-th + supernode; mapping from supernode number to column. + e.g.: col_to_sup: 0 1 2 2 3 3 3 4 4 4 4 4 4 (ncol=12) + sup_to_col: 0 1 2 4 7 12 (nsuper=4) */ + /* Note: + Zero-based indexing is used; + nzval_colptr[], rowind_colptr[], col_to_sup and + sup_to_col[] have ncol+1 entries, the last one + pointing beyond the last column. + For col_to_sup[], only the first ncol entries are + defined. For sup_to_col[], only the first nsuper+2 + entries are defined. */ +} SCformat; + +/* Stype == SLU_SCP */ +typedef struct { + int_t nnz; /* number of nonzeros in the matrix */ + int_t nsuper; /* number of supernodes */ + void *nzval; /* pointer to array of nonzero values, packed by column */ + int_t *nzval_colbeg;/* nzval_colbeg[j] points to beginning of column j + in nzval[] */ + int_t *nzval_colend;/* nzval_colend[j] points to one past the last element + of column j in nzval[] */ + int_t *rowind; /* pointer to array of compressed row indices of + rectangular supernodes */ + int_t *rowind_colbeg;/* rowind_colbeg[j] points to beginning of column j + in rowind[] */ + int_t *rowind_colend;/* rowind_colend[j] points to one past the last element + of column j in rowind[] */ + int_t *col_to_sup; /* col_to_sup[j] is the supernode number to which column + j belongs; mapping from column to supernode. */ + int_t *sup_to_colbeg; /* sup_to_colbeg[s] points to the start of the s-th + supernode; mapping from supernode to column.*/ + int_t *sup_to_colend; /* sup_to_colend[s] points to one past the end of the + s-th supernode; mapping from supernode number to + column. + e.g.: col_to_sup: 0 1 2 2 3 3 3 4 4 4 4 4 4 (ncol=12) + sup_to_colbeg: 0 1 2 4 7 (nsuper=4) + sup_to_colend: 1 2 4 7 12 */ + /* Note: + Zero-based indexing is used; + nzval_colptr[], rowind_colptr[], col_to_sup and + sup_to_col[] have ncol+1 entries, the last one + pointing beyond the last column. */ +} SCPformat; + +/* Stype == SLU_NCP */ +typedef struct { + int_t nnz; /* number of nonzeros in the matrix */ + void *nzval; /* pointer to array of nonzero values, packed by column */ + int_t *rowind;/* pointer to array of row indices of the nonzeros */ + /* Note: nzval[]/rowind[] always have the same length */ + int_t *colbeg;/* colbeg[j] points to the beginning of column j in nzval[] + and rowind[] */ + int_t *colend;/* colend[j] points to one past the last element of column + j in nzval[] and rowind[] */ + /* Note: + Zero-based indexing is used; + The consecutive columns of the nonzeros may not be + contiguous in storage, because the matrix has been + postmultiplied by a column permutation matrix. */ +} NCPformat; + +/* Stype == SLU_DN */ +typedef struct { + int_t lda; /* leading dimension */ + void *nzval; /* array of size lda*ncol to represent a dense matrix */ +} DNformat; + +/* Stype == SLU_NR_loc (Distributed Compressed Row Format) */ +typedef struct { + int_t nnz_loc; /* number of nonzeros in the local submatrix */ + int_t m_loc; /* number of rows local to this processor */ + int_t fst_row; /* global index of the first row */ + void *nzval; /* pointer to array of nonzero values, packed by row */ + int_t *rowptr; /* pointer to array of beginning of rows in nzval[] + and colind[] */ + int_t *colind; /* pointer to array of column indices of the nonzeros */ + /* Note: + Zero-based indexing is used; + rowptr[] has n_loc + 1 entries, the last one pointing + beyond the last row, so that rowptr[n_loc] = nnz_loc.*/ +} NRformat_loc; + + +#endif /* __SUPERLU_SUPERMATRIX */ diff --git a/src/Libraries/superlu-5.2.1/SRC/sutil.c b/src/Libraries/superlu-5.2.1/SRC/sutil.c new file mode 100644 index 00000000..65c6d0da --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/sutil.c @@ -0,0 +1,481 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file sutil.c + * \brief Matrix utility functions + * + *
+ * -- SuperLU routine (version 3.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * August 1, 2008
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include +#include "slu_sdefs.h" + +void +sCreate_CompCol_Matrix(SuperMatrix *A, int m, int n, int nnz, + float *nzval, int *rowind, int *colptr, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + NCformat *Astore; + + A->Stype = stype; + A->Dtype = dtype; + A->Mtype = mtype; + A->nrow = m; + A->ncol = n; + A->Store = (void *) SUPERLU_MALLOC( sizeof(NCformat) ); + if ( !(A->Store) ) ABORT("SUPERLU_MALLOC fails for A->Store"); + Astore = A->Store; + Astore->nnz = nnz; + Astore->nzval = nzval; + Astore->rowind = rowind; + Astore->colptr = colptr; +} + +void +sCreate_CompRow_Matrix(SuperMatrix *A, int m, int n, int nnz, + float *nzval, int *colind, int *rowptr, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + NRformat *Astore; + + A->Stype = stype; + A->Dtype = dtype; + A->Mtype = mtype; + A->nrow = m; + A->ncol = n; + A->Store = (void *) SUPERLU_MALLOC( sizeof(NRformat) ); + if ( !(A->Store) ) ABORT("SUPERLU_MALLOC fails for A->Store"); + Astore = A->Store; + Astore->nnz = nnz; + Astore->nzval = nzval; + Astore->colind = colind; + Astore->rowptr = rowptr; +} + +/*! \brief Copy matrix A into matrix B. */ +void +sCopy_CompCol_Matrix(SuperMatrix *A, SuperMatrix *B) +{ + NCformat *Astore, *Bstore; + int ncol, nnz, i; + + B->Stype = A->Stype; + B->Dtype = A->Dtype; + B->Mtype = A->Mtype; + B->nrow = A->nrow;; + B->ncol = ncol = A->ncol; + Astore = (NCformat *) A->Store; + Bstore = (NCformat *) B->Store; + Bstore->nnz = nnz = Astore->nnz; + for (i = 0; i < nnz; ++i) + ((float *)Bstore->nzval)[i] = ((float *)Astore->nzval)[i]; + for (i = 0; i < nnz; ++i) Bstore->rowind[i] = Astore->rowind[i]; + for (i = 0; i <= ncol; ++i) Bstore->colptr[i] = Astore->colptr[i]; +} + + +void +sCreate_Dense_Matrix(SuperMatrix *X, int m, int n, float *x, int ldx, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + DNformat *Xstore; + + X->Stype = stype; + X->Dtype = dtype; + X->Mtype = mtype; + X->nrow = m; + X->ncol = n; + X->Store = (void *) SUPERLU_MALLOC( sizeof(DNformat) ); + if ( !(X->Store) ) ABORT("SUPERLU_MALLOC fails for X->Store"); + Xstore = (DNformat *) X->Store; + Xstore->lda = ldx; + Xstore->nzval = (float *) x; +} + +void +sCopy_Dense_Matrix(int M, int N, float *X, int ldx, + float *Y, int ldy) +{ +/*! \brief Copies a two-dimensional matrix X to another matrix Y. + */ + int i, j; + + for (j = 0; j < N; ++j) + for (i = 0; i < M; ++i) + Y[i + j*ldy] = X[i + j*ldx]; +} + +void +sCreate_SuperNode_Matrix(SuperMatrix *L, int m, int n, int nnz, + float *nzval, int *nzval_colptr, int *rowind, + int *rowind_colptr, int *col_to_sup, int *sup_to_col, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + SCformat *Lstore; + + L->Stype = stype; + L->Dtype = dtype; + L->Mtype = mtype; + L->nrow = m; + L->ncol = n; + L->Store = (void *) SUPERLU_MALLOC( sizeof(SCformat) ); + if ( !(L->Store) ) ABORT("SUPERLU_MALLOC fails for L->Store"); + Lstore = L->Store; + Lstore->nnz = nnz; + Lstore->nsuper = col_to_sup[n]; + Lstore->nzval = nzval; + Lstore->nzval_colptr = nzval_colptr; + Lstore->rowind = rowind; + Lstore->rowind_colptr = rowind_colptr; + Lstore->col_to_sup = col_to_sup; + Lstore->sup_to_col = sup_to_col; + +} + + +/*! \brief Convert a row compressed storage into a column compressed storage. + */ +void +sCompRow_to_CompCol(int m, int n, int nnz, + float *a, int *colind, int *rowptr, + float **at, int **rowind, int **colptr) +{ + register int i, j, col, relpos; + int *marker; + + /* Allocate storage for another copy of the matrix. */ + *at = (float *) floatMalloc(nnz); + *rowind = (int *) intMalloc(nnz); + *colptr = (int *) intMalloc(n+1); + marker = (int *) intCalloc(n); + + /* Get counts of each column of A, and set up column pointers */ + for (i = 0; i < m; ++i) + for (j = rowptr[i]; j < rowptr[i+1]; ++j) ++marker[colind[j]]; + (*colptr)[0] = 0; + for (j = 0; j < n; ++j) { + (*colptr)[j+1] = (*colptr)[j] + marker[j]; + marker[j] = (*colptr)[j]; + } + + /* Transfer the matrix into the compressed column storage. */ + for (i = 0; i < m; ++i) { + for (j = rowptr[i]; j < rowptr[i+1]; ++j) { + col = colind[j]; + relpos = marker[col]; + (*rowind)[relpos] = i; + (*at)[relpos] = a[j]; + ++marker[col]; + } + } + + SUPERLU_FREE(marker); +} + + +void +sPrint_CompCol_Matrix(char *what, SuperMatrix *A) +{ + NCformat *Astore; + register int i,n; + float *dp; + + printf("\nCompCol matrix %s:\n", what); + printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype); + n = A->ncol; + Astore = (NCformat *) A->Store; + dp = (float *) Astore->nzval; + printf("nrow %d, ncol %d, nnz %d\n", A->nrow,A->ncol,Astore->nnz); + printf("nzval: "); + for (i = 0; i < Astore->colptr[n]; ++i) printf("%f ", dp[i]); + printf("\nrowind: "); + for (i = 0; i < Astore->colptr[n]; ++i) printf("%d ", Astore->rowind[i]); + printf("\ncolptr: "); + for (i = 0; i <= n; ++i) printf("%d ", Astore->colptr[i]); + printf("\n"); + fflush(stdout); +} + +void +sPrint_SuperNode_Matrix(char *what, SuperMatrix *A) +{ + SCformat *Astore; + register int i, j, k, c, d, n, nsup; + float *dp; + int *col_to_sup, *sup_to_col, *rowind, *rowind_colptr; + + printf("\nSuperNode matrix %s:\n", what); + printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype); + n = A->ncol; + Astore = (SCformat *) A->Store; + dp = (float *) Astore->nzval; + col_to_sup = Astore->col_to_sup; + sup_to_col = Astore->sup_to_col; + rowind_colptr = Astore->rowind_colptr; + rowind = Astore->rowind; + printf("nrow %d, ncol %d, nnz %d, nsuper %d\n", + A->nrow,A->ncol,Astore->nnz,Astore->nsuper); + printf("nzval:\n"); + for (k = 0; k <= Astore->nsuper; ++k) { + c = sup_to_col[k]; + nsup = sup_to_col[k+1] - c; + for (j = c; j < c + nsup; ++j) { + d = Astore->nzval_colptr[j]; + for (i = rowind_colptr[c]; i < rowind_colptr[c+1]; ++i) { + printf("%d\t%d\t%e\n", rowind[i], j, dp[d++]); + } + } + } +#if 0 + for (i = 0; i < Astore->nzval_colptr[n]; ++i) printf("%f ", dp[i]); +#endif + printf("\nnzval_colptr: "); + for (i = 0; i <= n; ++i) printf("%d ", Astore->nzval_colptr[i]); + printf("\nrowind: "); + for (i = 0; i < Astore->rowind_colptr[n]; ++i) + printf("%d ", Astore->rowind[i]); + printf("\nrowind_colptr: "); + for (i = 0; i <= n; ++i) printf("%d ", Astore->rowind_colptr[i]); + printf("\ncol_to_sup: "); + for (i = 0; i < n; ++i) printf("%d ", col_to_sup[i]); + printf("\nsup_to_col: "); + for (i = 0; i <= Astore->nsuper+1; ++i) + printf("%d ", sup_to_col[i]); + printf("\n"); + fflush(stdout); +} + +void +sPrint_Dense_Matrix(char *what, SuperMatrix *A) +{ + DNformat *Astore = (DNformat *) A->Store; + register int i, j, lda = Astore->lda; + float *dp; + + printf("\nDense matrix %s:\n", what); + printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype); + dp = (float *) Astore->nzval; + printf("nrow %d, ncol %d, lda %d\n", A->nrow,A->ncol,lda); + printf("\nnzval: "); + for (j = 0; j < A->ncol; ++j) { + for (i = 0; i < A->nrow; ++i) printf("%f ", dp[i + j*lda]); + printf("\n"); + } + printf("\n"); + fflush(stdout); +} + +/*! \brief Diagnostic print of column "jcol" in the U/L factor. + */ +void +sprint_lu_col(char *msg, int jcol, int pivrow, int *xprune, GlobalLU_t *Glu) +{ + int i, k, fsupc; + int *xsup, *supno; + int *xlsub, *lsub; + float *lusup; + int *xlusup; + float *ucol; + int *usub, *xusub; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (float *) Glu->lusup; + xlusup = Glu->xlusup; + ucol = (float *) Glu->ucol; + usub = Glu->usub; + xusub = Glu->xusub; + + printf("%s", msg); + printf("col %d: pivrow %d, supno %d, xprune %d\n", + jcol, pivrow, supno[jcol], xprune[jcol]); + + printf("\tU-col:\n"); + for (i = xusub[jcol]; i < xusub[jcol+1]; i++) + printf("\t%d%10.4f\n", usub[i], ucol[i]); + printf("\tL-col in rectangular snode:\n"); + fsupc = xsup[supno[jcol]]; /* first col of the snode */ + i = xlsub[fsupc]; + k = xlusup[jcol]; + while ( i < xlsub[fsupc+1] && k < xlusup[jcol+1] ) { + printf("\t%d\t%10.4f\n", lsub[i], lusup[k]); + i++; k++; + } + fflush(stdout); +} + + +/*! \brief Check whether tempv[] == 0. This should be true before and after calling any numeric routines, i.e., "panel_bmod" and "column_bmod". + */ +void scheck_tempv(int n, float *tempv) +{ + int i; + + for (i = 0; i < n; i++) { + if (tempv[i] != 0.0) + { + fprintf(stderr,"tempv[%d] = %f\n", i,tempv[i]); + ABORT("scheck_tempv"); + } + } +} + + +void +sGenXtrue(int n, int nrhs, float *x, int ldx) +{ + int i, j; + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) { + x[i + j*ldx] = 1.0;/* + (float)(i+1.)/n;*/ + } +} + +/*! \brief Let rhs[i] = sum of i-th row of A, so the solution vector is all 1's + */ +void +sFillRHS(trans_t trans, int nrhs, float *x, int ldx, + SuperMatrix *A, SuperMatrix *B) +{ + NCformat *Astore; + float *Aval; + DNformat *Bstore; + float *rhs; + float one = 1.0; + float zero = 0.0; + int ldc; + char transc[1]; + + Astore = A->Store; + Aval = (float *) Astore->nzval; + Bstore = B->Store; + rhs = Bstore->nzval; + ldc = Bstore->lda; + + if ( trans == NOTRANS ) *(unsigned char *)transc = 'N'; + else *(unsigned char *)transc = 'T'; + + sp_sgemm(transc, "N", A->nrow, nrhs, A->ncol, one, A, + x, ldx, zero, rhs, ldc); + +} + +/*! \brief Fills a float precision array with a given value. + */ +void +sfill(float *a, int alen, float dval) +{ + register int i; + for (i = 0; i < alen; i++) a[i] = dval; +} + + + +/*! \brief Check the inf-norm of the error vector + */ +void sinf_norm_error(int nrhs, SuperMatrix *X, float *xtrue) +{ + DNformat *Xstore; + float err, xnorm; + float *Xmat, *soln_work; + int i, j; + + Xstore = X->Store; + Xmat = Xstore->nzval; + + for (j = 0; j < nrhs; j++) { + soln_work = &Xmat[j*Xstore->lda]; + err = xnorm = 0.0; + for (i = 0; i < X->nrow; i++) { + err = SUPERLU_MAX(err, fabs(soln_work[i] - xtrue[i])); + xnorm = SUPERLU_MAX(xnorm, fabs(soln_work[i])); + } + err = err / xnorm; + printf("||X - Xtrue||/||X|| = %e\n", err); + } +} + + + +/*! \brief Print performance of the code. */ +void +sPrintPerf(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage, + float rpg, float rcond, float *ferr, + float *berr, char *equed, SuperLUStat_t *stat) +{ + SCformat *Lstore; + NCformat *Ustore; + double *utime; + flops_t *ops; + + utime = stat->utime; + ops = stat->ops; + + if ( utime[FACT] != 0. ) + printf("Factor flops = %e\tMflops = %8.2f\n", ops[FACT], + ops[FACT]*1e-6/utime[FACT]); + printf("Identify relaxed snodes = %8.2f\n", utime[RELAX]); + if ( utime[SOLVE] != 0. ) + printf("Solve flops = %.0f, Mflops = %8.2f\n", ops[SOLVE], + ops[SOLVE]*1e-6/utime[SOLVE]); + + Lstore = (SCformat *) L->Store; + Ustore = (NCformat *) U->Store; + printf("\tNo of nonzeros in factor L = %d\n", Lstore->nnz); + printf("\tNo of nonzeros in factor U = %d\n", Ustore->nnz); + printf("\tNo of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage->for_lu/1e6, mem_usage->total_needed/1e6); + printf("Number of memory expansions: %d\n", stat->expansions); + + printf("\tFactor\tMflops\tSolve\tMflops\tEtree\tEquil\tRcond\tRefine\n"); + printf("PERF:%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f\n", + utime[FACT], ops[FACT]*1e-6/utime[FACT], + utime[SOLVE], ops[SOLVE]*1e-6/utime[SOLVE], + utime[ETREE], utime[EQUIL], utime[RCOND], utime[REFINE]); + + printf("\tRpg\t\tRcond\t\tFerr\t\tBerr\t\tEquil?\n"); + printf("NUM:\t%e\t%e\t%e\t%e\t%s\n", + rpg, rcond, ferr[0], berr[0], equed); + +} + + + + +print_float_vec(char *what, int n, float *vec) +{ + int i; + printf("%s: n %d\n", what, n); + for (i = 0; i < n; ++i) printf("%d\t%f\n", i, vec[i]); + return 0; +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/util.c b/src/Libraries/superlu-5.2.1/SRC/util.c new file mode 100644 index 00000000..a08e83e4 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/util.c @@ -0,0 +1,503 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ +/*! @file util.c + * \brief Utility functions + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November, 2010
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include +#include "slu_ddefs.h" + +/*! \brief Global statistics variale + */ + +void superlu_abort_and_exit(char* msg) +{ + fprintf(stderr, "%s", msg); + exit (-1); +} + +/*! \brief Set the default values for the options argument. + */ +void set_default_options(superlu_options_t *options) +{ + options->Fact = DOFACT; + options->Equil = YES; + options->ColPerm = COLAMD; + options->Trans = NOTRANS; + options->IterRefine = NOREFINE; + options->DiagPivotThresh = 1.0; + options->SymmetricMode = NO; + options->PivotGrowth = NO; + options->ConditionNumber = NO; + options->PrintStat = YES; +} + +/*! \brief Set the default values for the options argument for ILU. + */ +void ilu_set_default_options(superlu_options_t *options) +{ + set_default_options(options); + + /* further options for incomplete factorization */ + options->DiagPivotThresh = 0.1; + options->RowPerm = LargeDiag; + options->ILU_DropRule = DROP_BASIC | DROP_AREA; + options->ILU_DropTol = 1e-4; + options->ILU_FillFactor = 10.0; + options->ILU_Norm = INF_NORM; + options->ILU_MILU = SILU; + options->ILU_MILU_Dim = 3.0; /* -log(n)/log(h) is perfect */ + options->ILU_FillTol = 1e-2; +} + +/*! \brief Print the options setting. + */ +void print_options(superlu_options_t *options) +{ + printf(".. options:\n"); + printf("\tFact\t %8d\n", options->Fact); + printf("\tEquil\t %8d\n", options->Equil); + printf("\tColPerm\t %8d\n", options->ColPerm); + printf("\tDiagPivotThresh %8.4f\n", options->DiagPivotThresh); + printf("\tTrans\t %8d\n", options->Trans); + printf("\tIterRefine\t%4d\n", options->IterRefine); + printf("\tSymmetricMode\t%4d\n", options->SymmetricMode); + printf("\tPivotGrowth\t%4d\n", options->PivotGrowth); + printf("\tConditionNumber\t%4d\n", options->ConditionNumber); + printf("..\n"); +} + +/*! \brief Print the options setting. + */ +void print_ilu_options(superlu_options_t *options) +{ + printf(".. ILU options:\n"); + printf("\tDiagPivotThresh\t%6.2e\n", options->DiagPivotThresh); + printf("\ttau\t%6.2e\n", options->ILU_DropTol); + printf("\tgamma\t%6.2f\n", options->ILU_FillFactor); + printf("\tDropRule\t%0x\n", options->ILU_DropRule); + printf("\tMILU\t%d\n", options->ILU_MILU); + printf("\tMILU_ALPHA\t%6.2e\n", MILU_ALPHA); + printf("\tDiagFillTol\t%6.2e\n", options->ILU_FillTol); + printf("..\n"); +} + +/*! \brief Deallocate the structure pointing to the actual storage of the matrix. */ +void +Destroy_SuperMatrix_Store(SuperMatrix *A) +{ + SUPERLU_FREE ( A->Store ); +} + +void +Destroy_CompCol_Matrix(SuperMatrix *A) +{ + SUPERLU_FREE( ((NCformat *)A->Store)->rowind ); + SUPERLU_FREE( ((NCformat *)A->Store)->colptr ); + SUPERLU_FREE( ((NCformat *)A->Store)->nzval ); + SUPERLU_FREE( A->Store ); +} + +void +Destroy_CompRow_Matrix(SuperMatrix *A) +{ + SUPERLU_FREE( ((NRformat *)A->Store)->colind ); + SUPERLU_FREE( ((NRformat *)A->Store)->rowptr ); + SUPERLU_FREE( ((NRformat *)A->Store)->nzval ); + SUPERLU_FREE( A->Store ); +} + +void +Destroy_SuperNode_Matrix(SuperMatrix *A) +{ + SUPERLU_FREE ( ((SCformat *)A->Store)->rowind ); + SUPERLU_FREE ( ((SCformat *)A->Store)->rowind_colptr ); + SUPERLU_FREE ( ((SCformat *)A->Store)->nzval ); + SUPERLU_FREE ( ((SCformat *)A->Store)->nzval_colptr ); + SUPERLU_FREE ( ((SCformat *)A->Store)->col_to_sup ); + SUPERLU_FREE ( ((SCformat *)A->Store)->sup_to_col ); + SUPERLU_FREE ( A->Store ); +} + +/*! \brief A is of type Stype==NCP */ +void +Destroy_CompCol_Permuted(SuperMatrix *A) +{ + SUPERLU_FREE ( ((NCPformat *)A->Store)->colbeg ); + SUPERLU_FREE ( ((NCPformat *)A->Store)->colend ); + SUPERLU_FREE ( A->Store ); +} + +/*! \brief A is of type Stype==DN */ +void +Destroy_Dense_Matrix(SuperMatrix *A) +{ + DNformat* Astore = A->Store; + SUPERLU_FREE (Astore->nzval); + SUPERLU_FREE ( A->Store ); +} + +/*! \brief Reset repfnz[] for the current column + */ +void +resetrep_col (const int nseg, const int *segrep, int *repfnz) +{ + int i, irep; + + for (i = 0; i < nseg; i++) { + irep = segrep[i]; + repfnz[irep] = EMPTY; + } +} + + +/*! \brief Count the total number of nonzeros in factors L and U, and in the symmetrically reduced L. + */ +void +countnz(const int n, int *xprune, int *nnzL, int *nnzU, GlobalLU_t *Glu) +{ + int nsuper, fsupc, i, j; + int nnzL0, jlen, irep; + int *xsup, *xlsub; + + xsup = Glu->xsup; + xlsub = Glu->xlsub; + *nnzL = 0; + *nnzU = (Glu->xusub)[n]; + nnzL0 = 0; + nsuper = (Glu->supno)[n]; + + if ( n <= 0 ) return; + + /* + * For each supernode + */ + for (i = 0; i <= nsuper; i++) { + fsupc = xsup[i]; + jlen = xlsub[fsupc+1] - xlsub[fsupc]; + + for (j = fsupc; j < xsup[i+1]; j++) { + *nnzL += jlen; + *nnzU += j - fsupc + 1; + jlen--; + } + irep = xsup[i+1] - 1; + nnzL0 += xprune[irep] - xlsub[irep]; + } + + /* printf("\tNo of nonzeros in symm-reduced L = %d\n", nnzL0);*/ +} + +/*! \brief Count the total number of nonzeros in factors L and U. + */ +void +ilu_countnz(const int n, int *nnzL, int *nnzU, GlobalLU_t *Glu) +{ + int nsuper, fsupc, i, j; + int jlen, irep; + int *xsup, *xlsub; + + xsup = Glu->xsup; + xlsub = Glu->xlsub; + *nnzL = 0; + *nnzU = (Glu->xusub)[n]; + nsuper = (Glu->supno)[n]; + + if ( n <= 0 ) return; + + /* + * For each supernode + */ + for (i = 0; i <= nsuper; i++) { + fsupc = xsup[i]; + jlen = xlsub[fsupc+1] - xlsub[fsupc]; + + for (j = fsupc; j < xsup[i+1]; j++) { + *nnzL += jlen; + *nnzU += j - fsupc + 1; + jlen--; + } + irep = xsup[i+1] - 1; + } +} + + +/*! \brief Fix up the data storage lsub for L-subscripts. It removes the subscript sets for structural pruning, and applies permuation to the remaining subscripts. + */ +void +fixupL(const int n, const int *perm_r, GlobalLU_t *Glu) +{ + register int nsuper, fsupc, nextl, i, j, k, jstrt; + int *xsup, *lsub, *xlsub; + + if ( n <= 1 ) return; + + xsup = Glu->xsup; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nextl = 0; + nsuper = (Glu->supno)[n]; + + /* + * For each supernode ... + */ + for (i = 0; i <= nsuper; i++) { + fsupc = xsup[i]; + jstrt = xlsub[fsupc]; + xlsub[fsupc] = nextl; + for (j = jstrt; j < xlsub[fsupc+1]; j++) { + lsub[nextl] = perm_r[lsub[j]]; /* Now indexed into P*A */ + nextl++; + } + for (k = fsupc+1; k < xsup[i+1]; k++) + xlsub[k] = nextl; /* Other columns in supernode i */ + + } + + xlsub[n] = nextl; +} + + +/*! \brief Diagnostic print of segment info after panel_dfs(). + */ +void print_panel_seg(int n, int w, int jcol, int nseg, + int *segrep, int *repfnz) +{ + int j, k; + + for (j = jcol; j < jcol+w; j++) { + printf("\tcol %d:\n", j); + for (k = 0; k < nseg; k++) + printf("\t\tseg %d, segrep %d, repfnz %d\n", k, + segrep[k], repfnz[(j-jcol)*n + segrep[k]]); + } + +} + + +void +StatInit(SuperLUStat_t *stat) +{ + register int i, w, panel_size, relax; + + panel_size = sp_ienv(1); + relax = sp_ienv(2); + w = SUPERLU_MAX(panel_size, relax); + stat->panel_histo = intCalloc(w+1); + stat->utime = (double *) SUPERLU_MALLOC(NPHASES * sizeof(double)); + if (!stat->utime) ABORT("SUPERLU_MALLOC fails for stat->utime"); + stat->ops = (flops_t *) SUPERLU_MALLOC(NPHASES * sizeof(flops_t)); + if (!stat->ops) ABORT("SUPERLU_MALLOC fails for stat->ops"); + for (i = 0; i < NPHASES; ++i) { + stat->utime[i] = 0.; + stat->ops[i] = 0.; + } + stat->TinyPivots = 0; + stat->RefineSteps = 0; + stat->expansions = 0; +#if ( PRNTlevel >= 1 ) + printf(".. parameters in sp_ienv():\n"); + printf("\t 1: panel size \t %4d \n" + "\t 2: relax \t %4d \n" + "\t 3: max. super \t %4d \n" + "\t 4: row-dim 2D \t %4d \n" + "\t 5: col-dim 2D \t %4d \n" + "\t 6: fill ratio \t %4d \n", + sp_ienv(1), sp_ienv(2), sp_ienv(3), + sp_ienv(4), sp_ienv(5), sp_ienv(6)); +#endif +} + + +void +StatPrint(SuperLUStat_t *stat) +{ + double *utime; + flops_t *ops; + + utime = stat->utime; + ops = stat->ops; + printf("Factor time = %8.2f\n", utime[FACT]); + if ( utime[FACT] != 0.0 ) + printf("Factor flops = %e\tMflops = %8.2f\n", ops[FACT], + ops[FACT]*1e-6/utime[FACT]); + + printf("Solve time = %8.2f\n", utime[SOLVE]); + if ( utime[SOLVE] != 0.0 ) + printf("Solve flops = %e\tMflops = %8.2f\n", ops[SOLVE], + ops[SOLVE]*1e-6/utime[SOLVE]); + + printf("Number of memory expansions: %d\n", stat->expansions); + +} + + +void +StatFree(SuperLUStat_t *stat) +{ + SUPERLU_FREE(stat->panel_histo); + SUPERLU_FREE(stat->utime); + SUPERLU_FREE(stat->ops); +} + + +flops_t +LUFactFlops(SuperLUStat_t *stat) +{ + return (stat->ops[FACT]); +} + +flops_t +LUSolveFlops(SuperLUStat_t *stat) +{ + return (stat->ops[SOLVE]); +} + + + + + +/*! \brief Fills an integer array with a given value. + */ +void ifill(int *a, int alen, int ival) +{ + register int i; + for (i = 0; i < alen; i++) a[i] = ival; +} + + + +/*! \brief Get the statistics of the supernodes + */ +#define NBUCKS 10 + +void super_stats(int nsuper, int *xsup) +{ + register int nsup1 = 0; + int i, isize, whichb, bl, bh; + int bucket[NBUCKS]; + int max_sup_size = 0; + + for (i = 0; i <= nsuper; i++) { + isize = xsup[i+1] - xsup[i]; + if ( isize == 1 ) nsup1++; + if ( max_sup_size < isize ) max_sup_size = isize; + } + + printf(" Supernode statistics:\n\tno of super = %d\n", nsuper+1); + printf("\tmax supernode size = %d\n", max_sup_size); + printf("\tno of size 1 supernodes = %d\n", nsup1); + + /* Histogram of the supernode sizes */ + ifill (bucket, NBUCKS, 0); + + for (i = 0; i <= nsuper; i++) { + isize = xsup[i+1] - xsup[i]; + whichb = (float) isize / max_sup_size * NBUCKS; + if (whichb >= NBUCKS) whichb = NBUCKS - 1; + bucket[whichb]++; + } + + printf("\tHistogram of supernode sizes:\n"); + for (i = 0; i < NBUCKS; i++) { + bl = (float) i * max_sup_size / NBUCKS; + bh = (float) (i+1) * max_sup_size / NBUCKS; + printf("\tsnode: %d-%d\t\t%d\n", bl+1, bh, bucket[i]); + } + +} + + +float SpaSize(int n, int np, float sum_npw) +{ + return (sum_npw*8 + np*8 + n*4)/1024.; +} + +float DenseSize(int n, float sum_nw) +{ + return (sum_nw*8 + n*8)/1024.;; +} + + + +/*! \brief Check whether repfnz[] == EMPTY after reset. + */ +void check_repfnz(int n, int w, int jcol, int *repfnz) +{ + int jj, k; + + for (jj = jcol; jj < jcol+w; jj++) + for (k = 0; k < n; k++) + if ( repfnz[(jj-jcol)*n + k] != EMPTY ) { + fprintf(stderr, "col %d, repfnz_col[%d] = %d\n", jj, + k, repfnz[(jj-jcol)*n + k]); + ABORT("check_repfnz"); + } +} + + +/*! \brief Print a summary of the testing results. */ +void +PrintSumm(char *type, int nfail, int nrun, int nerrs) +{ + if ( nfail > 0 ) + printf("%3s driver: %d out of %d tests failed to pass the threshold\n", + type, nfail, nrun); + else + printf("All tests for %3s driver passed the threshold (%6d tests run)\n", type, nrun); + + if ( nerrs > 0 ) + printf("%6d error messages recorded\n", nerrs); +} + + +int print_int_vec(char *what, int n, int *vec) +{ + int i; + printf("%s\n", what); + for (i = 0; i < n; ++i) printf("%d\t%d\n", i, vec[i]); + return 0; +} + +int slu_PrintInt10(char *name, int len, int *x) +{ + register int i; + + printf("%10s:", name); + for (i = 0; i < len; ++i) + { + if ( i % 10 == 0 ) printf("\n\t[%2d-%2d]", i, i + 9); + printf("%6d", x[i]); + } + printf("\n"); + return 0; +} + + diff --git a/src/Libraries/superlu-5.2.1/SRC/zcolumn_bmod.c b/src/Libraries/superlu-5.2.1/SRC/zcolumn_bmod.c new file mode 100644 index 00000000..453ebe65 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zcolumn_bmod.c @@ -0,0 +1,377 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zcolumn_bmod.c + * \brief performs numeric block updates + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ *  Permission is hereby granted to use or copy this program for any
+ *  purpose, provided the above notices are retained on all copies.
+ *  Permission to modify the code and to distribute modified code is
+ *  granted, provided the above notices are retained, and a notice that
+ *  the code was modified is included with the above copyright notice.
+ * 
+*/ + +#include +#include +#include "slu_zdefs.h" + +/* + * Function prototypes + */ +void zusolve(int, int, doublecomplex*, doublecomplex*); +void zlsolve(int, int, doublecomplex*, doublecomplex*); +void zmatvec(int, int, int, doublecomplex*, doublecomplex*, doublecomplex*); + + + +/*! \brief + * + *
+ * Purpose:
+ * ========
+ * Performs numeric block updates (sup-col) in topological order.
+ * It features: col-col, 2cols-col, 3cols-col, and sup-col updates.
+ * Special processing on the supernodal portion of L\U[*,j]
+ * Return value:   0 - successful return
+ *               > 0 - number of bytes allocated when run out of space
+ * 
+ */ +int +zcolumn_bmod ( + const int jcol, /* in */ + const int nseg, /* in */ + doublecomplex *dense, /* in */ + doublecomplex *tempv, /* working array */ + int *segrep, /* in */ + int *repfnz, /* in */ + int fpanelc, /* in -- first column in the current panel */ + GlobalLU_t *Glu, /* modified */ + SuperLUStat_t *stat /* output */ + ) +{ + +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + int incx = 1, incy = 1; + doublecomplex alpha, beta; + + /* krep = representative of current k-th supernode + * fsupc = first supernodal column + * nsupc = no of columns in supernode + * nsupr = no of rows in supernode (used as leading dimension) + * luptr = location of supernodal LU-block in storage + * kfnz = first nonz in the k-th supernodal segment + * no_zeros = no of leading zeros in a supernodal U-segment + */ + doublecomplex ukj, ukj1, ukj2; + int luptr, luptr1, luptr2; + int fsupc, nsupc, nsupr, segsze; + int nrow; /* No of rows in the matrix of matrix-vector */ + int jcolp1, jsupno, k, ksub, krep, krep_ind, ksupno; + register int lptr, kfnz, isub, irow, i; + register int no_zeros, new_next; + int ufirst, nextlu; + int fst_col; /* First column within small LU update */ + int d_fsupc; /* Distance between the first column of the current + panel and the first column of the current snode. */ + int *xsup, *supno; + int *lsub, *xlsub; + doublecomplex *lusup; + int *xlusup; + int nzlumax; + doublecomplex *tempv1; + doublecomplex zero = {0.0, 0.0}; + doublecomplex one = {1.0, 0.0}; + doublecomplex none = {-1.0, 0.0}; + doublecomplex comp_temp, comp_temp1; + int mem_error; + flops_t *ops = stat->ops; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (doublecomplex *) Glu->lusup; + xlusup = Glu->xlusup; + nzlumax = Glu->nzlumax; + jcolp1 = jcol + 1; + jsupno = supno[jcol]; + + /* + * For each nonz supernode segment of U[*,j] in topological order + */ + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { + + krep = segrep[k]; + k--; + ksupno = supno[krep]; + if ( jsupno != ksupno ) { /* Outside the rectangular supernode */ + + fsupc = xsup[ksupno]; + fst_col = SUPERLU_MAX ( fsupc, fpanelc ); + + /* Distance from the current supernode to the current panel; + d_fsupc=0 if fsupc > fpanelc. */ + d_fsupc = fst_col - fsupc; + + luptr = xlusup[fst_col] + d_fsupc; + lptr = xlsub[fsupc] + d_fsupc; + + kfnz = repfnz[krep]; + kfnz = SUPERLU_MAX ( kfnz, fpanelc ); + + segsze = krep - kfnz + 1; + nsupc = krep - fst_col + 1; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; /* Leading dimension */ + nrow = nsupr - d_fsupc - nsupc; + krep_ind = lptr + nsupc - 1; + + ops[TRSV] += 4 * segsze * (segsze - 1); + ops[GEMV] += 8 * nrow * segsze; + + + + /* + * Case 1: Update U-segment of size 1 -- col-col update + */ + if ( segsze == 1 ) { + ukj = dense[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc; + + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + zz_mult(&comp_temp, &ukj, &lusup[luptr]); + z_sub(&dense[irow], &dense[irow], &comp_temp); + luptr++; + } + + } else if ( segsze <= 3 ) { + ukj = dense[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc-1; + ukj1 = dense[lsub[krep_ind - 1]]; + luptr1 = luptr - nsupr; + + if ( segsze == 2 ) { /* Case 2: 2cols-col update */ + zz_mult(&comp_temp, &ukj1, &lusup[luptr1]); + z_sub(&ukj, &ukj, &comp_temp); + dense[lsub[krep_ind]] = ukj; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; + luptr1++; + zz_mult(&comp_temp, &ukj, &lusup[luptr]); + zz_mult(&comp_temp1, &ukj1, &lusup[luptr1]); + z_add(&comp_temp, &comp_temp, &comp_temp1); + z_sub(&dense[irow], &dense[irow], &comp_temp); + } + } else { /* Case 3: 3cols-col update */ + ukj2 = dense[lsub[krep_ind - 2]]; + luptr2 = luptr1 - nsupr; + zz_mult(&comp_temp, &ukj2, &lusup[luptr2-1]); + z_sub(&ukj1, &ukj1, &comp_temp); + + zz_mult(&comp_temp, &ukj1, &lusup[luptr1]); + zz_mult(&comp_temp1, &ukj2, &lusup[luptr2]); + z_add(&comp_temp, &comp_temp, &comp_temp1); + z_sub(&ukj, &ukj, &comp_temp); + + dense[lsub[krep_ind]] = ukj; + dense[lsub[krep_ind-1]] = ukj1; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; + luptr1++; + luptr2++; + zz_mult(&comp_temp, &ukj, &lusup[luptr]); + zz_mult(&comp_temp1, &ukj1, &lusup[luptr1]); + z_add(&comp_temp, &comp_temp, &comp_temp1); + zz_mult(&comp_temp1, &ukj2, &lusup[luptr2]); + z_add(&comp_temp, &comp_temp, &comp_temp1); + z_sub(&dense[irow], &dense[irow], &comp_temp); + } + } + + + } else { + /* + * Case: sup-col update + * Perform a triangular solve and block update, + * then scatter the result of sup-col update to dense + */ + + no_zeros = kfnz - fst_col; + + /* Copy U[*,j] segment from dense[*] to tempv[*] */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + tempv[i] = dense[irow]; + ++isub; + } + + /* Dense triangular solve -- start effective triangle */ + luptr += nsupr * no_zeros + no_zeros; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + CTRSV( ftcs1, ftcs2, ftcs3, &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#else + ztrsv_( "L", "N", "U", &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#endif + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + alpha = one; + beta = zero; +#ifdef _CRAY + CGEMV( ftcs2, &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#else + zgemv_( "N", &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#endif +#else + zlsolve ( nsupr, segsze, &lusup[luptr], tempv ); + + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + zmatvec (nsupr, nrow , segsze, &lusup[luptr], tempv, tempv1); +#endif + + + /* Scatter tempv[] into SPA dense[] as a temporary storage */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + dense[irow] = tempv[i]; + tempv[i] = zero; + ++isub; + } + + /* Scatter tempv1[] into SPA dense[] */ + for (i = 0; i < nrow; i++) { + irow = lsub[isub]; + z_sub(&dense[irow], &dense[irow], &tempv1[i]); + tempv1[i] = zero; + ++isub; + } + } + + } /* if jsupno ... */ + + } /* for each segment... */ + + /* + * Process the supernodal portion of L\U[*,j] + */ + nextlu = xlusup[jcol]; + fsupc = xsup[jsupno]; + + /* Copy the SPA dense into L\U[*,j] */ + new_next = nextlu + xlsub[fsupc+1] - xlsub[fsupc]; + while ( new_next > nzlumax ) { + if (mem_error = zLUMemXpand(jcol, nextlu, LUSUP, &nzlumax, Glu)) + return (mem_error); + lusup = (doublecomplex *) Glu->lusup; + lsub = Glu->lsub; + } + + for (isub = xlsub[fsupc]; isub < xlsub[fsupc+1]; isub++) { + irow = lsub[isub]; + lusup[nextlu] = dense[irow]; + dense[irow] = zero; + ++nextlu; + } + + xlusup[jcolp1] = nextlu; /* Close L\U[*,jcol] */ + + /* For more updates within the panel (also within the current supernode), + * should start from the first column of the panel, or the first column + * of the supernode, whichever is bigger. There are 2 cases: + * 1) fsupc < fpanelc, then fst_col := fpanelc + * 2) fsupc >= fpanelc, then fst_col := fsupc + */ + fst_col = SUPERLU_MAX ( fsupc, fpanelc ); + + if ( fst_col < jcol ) { + + /* Distance between the current supernode and the current panel. + d_fsupc=0 if fsupc >= fpanelc. */ + d_fsupc = fst_col - fsupc; + + lptr = xlsub[fsupc] + d_fsupc; + luptr = xlusup[fst_col] + d_fsupc; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; /* Leading dimension */ + nsupc = jcol - fst_col; /* Excluding jcol */ + nrow = nsupr - d_fsupc - nsupc; + + /* Points to the beginning of jcol in snode L\U(jsupno) */ + ufirst = xlusup[jcol] + d_fsupc; + + ops[TRSV] += 4 * nsupc * (nsupc - 1); + ops[GEMV] += 8 * nrow * nsupc; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + CTRSV( ftcs1, ftcs2, ftcs3, &nsupc, &lusup[luptr], + &nsupr, &lusup[ufirst], &incx ); +#else + ztrsv_( "L", "N", "U", &nsupc, &lusup[luptr], + &nsupr, &lusup[ufirst], &incx ); +#endif + + alpha = none; beta = one; /* y := beta*y + alpha*A*x */ + +#ifdef _CRAY + CGEMV( ftcs2, &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#else + zgemv_( "N", &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#endif +#else + zlsolve ( nsupr, nsupc, &lusup[luptr], &lusup[ufirst] ); + + zmatvec ( nsupr, nrow, nsupc, &lusup[luptr+nsupc], + &lusup[ufirst], tempv ); + + /* Copy updates from tempv[*] into lusup[*] */ + isub = ufirst + nsupc; + for (i = 0; i < nrow; i++) { + z_sub(&lusup[isub], &lusup[isub], &tempv[i]); + tempv[i] = zero; + ++isub; + } + +#endif + + + } /* if fst_col < jcol ... */ + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zcolumn_dfs.c b/src/Libraries/superlu-5.2.1/SRC/zcolumn_dfs.c new file mode 100644 index 00000000..ab048372 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zcolumn_dfs.c @@ -0,0 +1,281 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zcolumn_dfs.c + * \brief Performs a symbolic factorization + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+*/ + +#include "slu_zdefs.h" + +/*! \brief What type of supernodes we want */ +#define T2_SUPER + + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   ZCOLUMN_DFS performs a symbolic factorization on column jcol, and
+ *   decide the supernode boundary.
+ *
+ *   This routine does not use numeric values, but only use the RHS 
+ *   row indices to start the dfs.
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives. The routine returns a list of such supernodal 
+ *   representatives in topological order of the dfs that generates them.
+ *   The location of the first nonzero in each such supernodal segment
+ *   (supernodal entry location) is also returned.
+ *
+ * Local parameters
+ * ================
+ *   nseg: no of segments in current U[*,j]
+ *   jsuper: jsuper=EMPTY if column j does not belong to the same
+ *	supernode as j-1. Otherwise, jsuper=nsuper.
+ *
+ *   marker2: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ *
+ * Return value
+ * ============
+ *     0  success;
+ *   > 0  number of bytes allocated when run out of space.
+ * 
+ */ +int +zcolumn_dfs( + const int m, /* in - number of rows in the matrix */ + const int jcol, /* in */ + int *perm_r, /* in */ + int *nseg, /* modified - with new segments appended */ + int *lsub_col, /* in - defines the RHS vector to start the dfs */ + int *segrep, /* modified - with new segments appended */ + int *repfnz, /* modified */ + int *xprune, /* modified */ + int *marker, /* modified */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ + ) +{ + + int jcolp1, jcolm1, jsuper, nsuper, nextl; + int k, krep, krow, kmark, kperm; + int *marker2; /* Used for small panel LU */ + int fsupc; /* First column of a snode */ + int myfnz; /* First nonz column of a U-segment */ + int chperm, chmark, chrep, kchild; + int xdfs, maxdfs, kpar, oldrep; + int jptr, jm1ptr; + int ito, ifrom, istop; /* Used to compress row subscripts */ + int mem_error; + int *xsup, *supno, *lsub, *xlsub; + int nzlmax; + int maxsuper; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + maxsuper = sp_ienv(3); + jcolp1 = jcol + 1; + jcolm1 = jcol - 1; + nsuper = supno[jcol]; + jsuper = nsuper; + nextl = xlsub[jcol]; + marker2 = &marker[2*m]; + + /* For each nonzero in A[*,jcol] do dfs */ + for (k = 0; lsub_col[k] != EMPTY; k++) { + + krow = lsub_col[k]; + lsub_col[k] = EMPTY; + kmark = marker2[krow]; + + /* krow was visited before, go to the next nonz */ + if ( kmark == jcol ) continue; + + /* For each unmarked nbr krow of jcol + * krow is in L: place it in structure of L[*,jcol] + */ + marker2[krow] = jcol; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + lsub[nextl++] = krow; /* krow is indexed into A */ + if ( nextl >= nzlmax ) { + if ( mem_error = zLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + if ( kmark != jcolm1 ) jsuper = EMPTY;/* Row index subset testing */ + } else { + /* krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz[krep]; + + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > kperm ) repfnz[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz[krep] = kperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; + + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker2[kchild]; + + if ( chmark != jcol ) { /* Not reached yet */ + marker2[kchild] = jcol; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,k] */ + if ( chperm == EMPTY ) { + lsub[nextl++] = kchild; + if ( nextl >= nzlmax ) { + if ( mem_error = + zLUMemXpand(jcol,nextl,LSUB,&nzlmax,Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + if ( chmark != jcolm1 ) jsuper = EMPTY; + } else { + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz[chrep]; + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz[chrep] = chperm; + } else { + /* Continue dfs at super-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L^t) */ + parent[krep] = oldrep; + repfnz[krep] = chperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; + } /* else */ + + } /* else */ + + } /* if */ + + } /* while */ + + /* krow has no more unexplored nbrs; + * place supernode-rep krep in postorder DFS. + * backtrack dfs to its parent + */ + segrep[*nseg] = krep; + ++(*nseg); + kpar = parent[krep]; /* Pop from stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xprune[krep]; + + } while ( kpar != EMPTY ); /* Until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonzero ... */ + + /* Check to see if j belongs in the same supernode as j-1 */ + if ( jcol == 0 ) { /* Do nothing for column 0 */ + nsuper = supno[0] = 0; + } else { + fsupc = xsup[nsuper]; + jptr = xlsub[jcol]; /* Not compressed yet */ + jm1ptr = xlsub[jcolm1]; + +#ifdef T2_SUPER + if ( (nextl-jptr != jptr-jm1ptr-1) ) jsuper = EMPTY; +#endif + /* Make sure the number of columns in a supernode doesn't + exceed threshold. */ + if ( jcol - fsupc >= maxsuper ) jsuper = EMPTY; + + /* If jcol starts a new supernode, reclaim storage space in + * lsub from the previous supernode. Note we only store + * the subscript set of the first and last columns of + * a supernode. (first for num values, last for pruning) + */ + if ( jsuper == EMPTY ) { /* starts a new supernode */ + if ( (fsupc < jcolm1-1) ) { /* >= 3 columns in nsuper */ +#ifdef CHK_COMPRESS + printf(" Compress lsub[] at super %d-%d\n", fsupc, jcolm1); +#endif + ito = xlsub[fsupc+1]; + xlsub[jcolm1] = ito; + istop = ito + jptr - jm1ptr; + xprune[jcolm1] = istop; /* Initialize xprune[jcol-1] */ + xlsub[jcol] = istop; + for (ifrom = jm1ptr; ifrom < nextl; ++ifrom, ++ito) + lsub[ito] = lsub[ifrom]; + nextl = ito; /* = istop + length(jcol) */ + } + nsuper++; + supno[jcol] = nsuper; + } /* if a new supernode */ + + } /* else: jcol > 0 */ + + /* Tidy up the pointers before exit */ + xsup[nsuper+1] = jcolp1; + supno[jcolp1] = nsuper; + xprune[jcol] = nextl; /* Initialize upper bound for pruning */ + xlsub[jcolp1] = nextl; + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zcopy_to_ucol.c b/src/Libraries/superlu-5.2.1/SRC/zcopy_to_ucol.c new file mode 100644 index 00000000..32716f62 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zcopy_to_ucol.c @@ -0,0 +1,113 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zcopy_to_ucol.c + * \brief Copy a computed column of U to the compressed data structure + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + +#include "slu_zdefs.h" + +int +zcopy_to_ucol( + int jcol, /* in */ + int nseg, /* in */ + int *segrep, /* in */ + int *repfnz, /* in */ + int *perm_r, /* in */ + doublecomplex *dense, /* modified - reset to zero on return */ + GlobalLU_t *Glu /* modified */ + ) +{ +/* + * Gather from SPA dense[*] to global ucol[*]. + */ + int ksub, krep, ksupno; + int i, k, kfnz, segsze; + int fsupc, isub, irow; + int jsupno, nextu; + int new_next, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + doublecomplex *ucol; + int *usub, *xusub; + int nzumax; + doublecomplex zero = {0.0, 0.0}; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + ucol = (doublecomplex *) Glu->ucol; + usub = Glu->usub; + xusub = Glu->xusub; + nzumax = Glu->nzumax; + + jsupno = supno[jcol]; + nextu = xusub[jcol]; + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { + krep = segrep[k--]; + ksupno = supno[krep]; + + if ( ksupno != jsupno ) { /* Should go into ucol[] */ + kfnz = repfnz[krep]; + if ( kfnz != EMPTY ) { /* Nonzero U-segment */ + + fsupc = xsup[ksupno]; + isub = xlsub[fsupc] + kfnz - fsupc; + segsze = krep - kfnz + 1; + + new_next = nextu + segsze; + while ( new_next > nzumax ) { + if (mem_error = zLUMemXpand(jcol, nextu, UCOL, &nzumax, Glu)) + return (mem_error); + ucol = (doublecomplex *) Glu->ucol; + if (mem_error = zLUMemXpand(jcol, nextu, USUB, &nzumax, Glu)) + return (mem_error); + usub = Glu->usub; + lsub = Glu->lsub; + } + + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + usub[nextu] = perm_r[irow]; + ucol[nextu] = dense[irow]; + dense[irow] = zero; + nextu++; + isub++; + } + + } + + } + + } /* for each segment... */ + + xusub[jcol + 1] = nextu; /* Close U[*,jcol] */ + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zdiagonal.c b/src/Libraries/superlu-5.2.1/SRC/zdiagonal.c new file mode 100644 index 00000000..83191947 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zdiagonal.c @@ -0,0 +1,143 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zdiagonal.c + * \brief Auxiliary routines to work with diagonal elements + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory
+ * June 30, 2009
+ * 
+ */ + +#include "slu_zdefs.h" + +int zfill_diag(int n, NCformat *Astore) +/* fill explicit zeros on the diagonal entries, so that the matrix is not + structurally singular. */ +{ + doublecomplex *nzval = (doublecomplex *)Astore->nzval; + int *rowind = Astore->rowind; + int *colptr = Astore->colptr; + int nnz = colptr[n]; + int fill = 0; + doublecomplex *nzval_new; + doublecomplex zero = {1.0, 0.0}; + int *rowind_new; + int i, j, diag; + + for (i = 0; i < n; i++) + { + diag = -1; + for (j = colptr[i]; j < colptr[i + 1]; j++) + if (rowind[j] == i) diag = j; + if (diag < 0) fill++; + } + if (fill) + { + nzval_new = doublecomplexMalloc(nnz + fill); + rowind_new = intMalloc(nnz + fill); + fill = 0; + for (i = 0; i < n; i++) + { + diag = -1; + for (j = colptr[i] - fill; j < colptr[i + 1]; j++) + { + if ((rowind_new[j + fill] = rowind[j]) == i) diag = j; + nzval_new[j + fill] = nzval[j]; + } + if (diag < 0) + { + rowind_new[colptr[i + 1] + fill] = i; + nzval_new[colptr[i + 1] + fill] = zero; + fill++; + } + colptr[i + 1] += fill; + } + Astore->nzval = nzval_new; + Astore->rowind = rowind_new; + SUPERLU_FREE(nzval); + SUPERLU_FREE(rowind); + } + Astore->nnz += fill; + return fill; +} + +int zdominate(int n, NCformat *Astore) +/* make the matrix diagonally dominant */ +{ + doublecomplex *nzval = (doublecomplex *)Astore->nzval; + int *rowind = Astore->rowind; + int *colptr = Astore->colptr; + int nnz = colptr[n]; + int fill = 0; + doublecomplex *nzval_new; + int *rowind_new; + int i, j, diag; + double s; + + for (i = 0; i < n; i++) + { + diag = -1; + for (j = colptr[i]; j < colptr[i + 1]; j++) + if (rowind[j] == i) diag = j; + if (diag < 0) fill++; + } + if (fill) + { + nzval_new = doublecomplexMalloc(nnz + fill); + rowind_new = intMalloc(nnz+ fill); + fill = 0; + for (i = 0; i < n; i++) + { + s = 1e-6; + diag = -1; + for (j = colptr[i] - fill; j < colptr[i + 1]; j++) + { + if ((rowind_new[j + fill] = rowind[j]) == i) diag = j; + nzval_new[j + fill] = nzval[j]; + s += z_abs1(&nzval_new[j + fill]); + } + if (diag >= 0) { + nzval_new[diag+fill].r = s * 3.0; + nzval_new[diag+fill].i = 0.0; + } else { + rowind_new[colptr[i + 1] + fill] = i; + nzval_new[colptr[i + 1] + fill].r = s * 3.0; + nzval_new[colptr[i + 1] + fill].i = 0.0; + fill++; + } + colptr[i + 1] += fill; + } + Astore->nzval = nzval_new; + Astore->rowind = rowind_new; + SUPERLU_FREE(nzval); + SUPERLU_FREE(rowind); + } + else + { + for (i = 0; i < n; i++) + { + s = 1e-6; + diag = -1; + for (j = colptr[i]; j < colptr[i + 1]; j++) + { + if (rowind[j] == i) diag = j; + s += z_abs1(&nzval[j]); + } + nzval[diag].r = s * 3.0; + nzval[diag].i = 0.0; + } + } + Astore->nnz += fill; + return fill; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zgscon.c b/src/Libraries/superlu-5.2.1/SRC/zgscon.c new file mode 100644 index 00000000..5159dfed --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zgscon.c @@ -0,0 +1,165 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zgscon.c + * \brief Estimates reciprocal of the condition number of a general matrix + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * July 25, 2015
+ *
+ * Modified from lapack routines ZGECON.
+ * 
+ */ + +/* + * File name: zgscon.c + * History: Modified from lapack routines ZGECON. + */ +#include +#include "slu_zdefs.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   ZGSCON estimates the reciprocal of the condition number of a general 
+ *   real matrix A, in either the 1-norm or the infinity-norm, using   
+ *   the LU factorization computed by ZGETRF.   *
+ *
+ *   An estimate is obtained for norm(inv(A)), and the reciprocal of the   
+ *   condition number is computed as   
+ *      RCOND = 1 / ( norm(A) * norm(inv(A)) ).   
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ * 
+ *   Arguments   
+ *   =========   
+ *
+ *    NORM    (input) char*
+ *            Specifies whether the 1-norm condition number or the   
+ *            infinity-norm condition number is required:   
+ *            = '1' or 'O':  1-norm;   
+ *            = 'I':         Infinity-norm.
+ *	    
+ *    L       (input) SuperMatrix*
+ *            The factor L from the factorization Pr*A*Pc=L*U as computed by
+ *            zgstrf(). Use compressed row subscripts storage for supernodes,
+ *            i.e., L has types: Stype = SLU_SC, Dtype = SLU_Z, Mtype = SLU_TRLU.
+ * 
+ *    U       (input) SuperMatrix*
+ *            The factor U from the factorization Pr*A*Pc=L*U as computed by
+ *            zgstrf(). Use column-wise storage scheme, i.e., U has types:
+ *            Stype = SLU_NC, Dtype = SLU_Z, Mtype = SLU_TRU.
+ *	    
+ *    ANORM   (input) double
+ *            If NORM = '1' or 'O', the 1-norm of the original matrix A.   
+ *            If NORM = 'I', the infinity-norm of the original matrix A.
+ *	    
+ *    RCOND   (output) double*
+ *           The reciprocal of the condition number of the matrix A,   
+ *           computed as RCOND = 1/(norm(A) * norm(inv(A))).
+ *	    
+ *    INFO    (output) int*
+ *           = 0:  successful exit   
+ *           < 0:  if INFO = -i, the i-th argument had an illegal value   
+ *
+ *    ===================================================================== 
+ * 
+ */ + +void +zgscon(char *norm, SuperMatrix *L, SuperMatrix *U, + double anorm, double *rcond, SuperLUStat_t *stat, int *info) +{ + + + /* Local variables */ + int kase, kase1, onenrm, i; + double ainvnm; + doublecomplex *work; + int isave[3]; + extern int zrscl_(int *, doublecomplex *, doublecomplex *, int *); + + extern int zlacon2_(int *, doublecomplex *, doublecomplex *, double *, int *, int []); + + + /* Test the input parameters. */ + *info = 0; + onenrm = *(unsigned char *)norm == '1' || strncmp(norm, "O", 1)==0; + if (! onenrm && ! strncmp(norm, "I", 1)==0) *info = -1; + else if (L->nrow < 0 || L->nrow != L->ncol || + L->Stype != SLU_SC || L->Dtype != SLU_Z || L->Mtype != SLU_TRLU) + *info = -2; + else if (U->nrow < 0 || U->nrow != U->ncol || + U->Stype != SLU_NC || U->Dtype != SLU_Z || U->Mtype != SLU_TRU) + *info = -3; + if (*info != 0) { + i = -(*info); + input_error("zgscon", &i); + return; + } + + /* Quick return if possible */ + *rcond = 0.; + if ( L->nrow == 0 || U->nrow == 0) { + *rcond = 1.; + return; + } + + work = doublecomplexCalloc( 3*L->nrow ); + + + if ( !work ) + ABORT("Malloc fails for work arrays in zgscon."); + + /* Estimate the norm of inv(A). */ + ainvnm = 0.; + if ( onenrm ) kase1 = 1; + else kase1 = 2; + kase = 0; + + do { + zlacon2_(&L->nrow, &work[L->nrow], &work[0], &ainvnm, &kase, isave); + + if (kase == 0) break; + + if (kase == kase1) { + /* Multiply by inv(L). */ + sp_ztrsv("L", "No trans", "Unit", L, U, &work[0], stat, info); + + /* Multiply by inv(U). */ + sp_ztrsv("U", "No trans", "Non-unit", L, U, &work[0], stat, info); + + } else { + + /* Multiply by inv(U'). */ + sp_ztrsv("U", "Transpose", "Non-unit", L, U, &work[0], stat, info); + + /* Multiply by inv(L'). */ + sp_ztrsv("L", "Transpose", "Unit", L, U, &work[0], stat, info); + + } + + } while ( kase != 0 ); + + /* Compute the estimate of the reciprocal condition number. */ + if (ainvnm != 0.) *rcond = (1. / ainvnm) / anorm; + + SUPERLU_FREE (work); + return; + +} /* zgscon */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/zgsequ.c b/src/Libraries/superlu-5.2.1/SRC/zgsequ.c new file mode 100644 index 00000000..a73d1bbb --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zgsequ.c @@ -0,0 +1,205 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zgsequ.c + * \brief Computes row and column scalings + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Modified from LAPACK routine ZGEEQU
+ * 
+ */ +/* + * File name: zgsequ.c + * History: Modified from LAPACK routine ZGEEQU + */ +#include +#include "slu_zdefs.h" + + + +/*! \brief + * + *
+ * Purpose   
+ *   =======   
+ *
+ *   ZGSEQU computes row and column scalings intended to equilibrate an   
+ *   M-by-N sparse matrix A and reduce its condition number. R returns the row
+ *   scale factors and C the column scale factors, chosen to try to make   
+ *   the largest element in each row and column of the matrix B with   
+ *   elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1.   
+ *
+ *   R(i) and C(j) are restricted to be between SMLNUM = smallest safe   
+ *   number and BIGNUM = largest safe number.  Use of these scaling   
+ *   factors is not guaranteed to reduce the condition number of A but   
+ *   works well in practice.   
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   A       (input) SuperMatrix*
+ *           The matrix of dimension (A->nrow, A->ncol) whose equilibration
+ *           factors are to be computed. The type of A can be:
+ *           Stype = SLU_NC; Dtype = SLU_Z; Mtype = SLU_GE.
+ *	    
+ *   R       (output) double*, size A->nrow
+ *           If INFO = 0 or INFO > M, R contains the row scale factors   
+ *           for A.
+ *	    
+ *   C       (output) double*, size A->ncol
+ *           If INFO = 0,  C contains the column scale factors for A.
+ *	    
+ *   ROWCND  (output) double*
+ *           If INFO = 0 or INFO > M, ROWCND contains the ratio of the   
+ *           smallest R(i) to the largest R(i).  If ROWCND >= 0.1 and   
+ *           AMAX is neither too large nor too small, it is not worth   
+ *           scaling by R.
+ *	    
+ *   COLCND  (output) double*
+ *           If INFO = 0, COLCND contains the ratio of the smallest   
+ *           C(i) to the largest C(i).  If COLCND >= 0.1, it is not   
+ *           worth scaling by C.
+ *	    
+ *   AMAX    (output) double*
+ *           Absolute value of largest matrix element.  If AMAX is very   
+ *           close to overflow or very close to underflow, the matrix   
+ *           should be scaled.
+ *	    
+ *   INFO    (output) int*
+ *           = 0:  successful exit   
+ *           < 0:  if INFO = -i, the i-th argument had an illegal value   
+ *           > 0:  if INFO = i,  and i is   
+ *                 <= A->nrow:  the i-th row of A is exactly zero   
+ *                 >  A->ncol:  the (i-M)-th column of A is exactly zero   
+ *
+ *   ===================================================================== 
+ * 
+ */ +void +zgsequ(SuperMatrix *A, double *r, double *c, double *rowcnd, + double *colcnd, double *amax, int *info) +{ + + + /* Local variables */ + NCformat *Astore; + doublecomplex *Aval; + int i, j, irow; + double rcmin, rcmax; + double bignum, smlnum; + extern double dmach(char *); + + /* Test the input parameters. */ + *info = 0; + if ( A->nrow < 0 || A->ncol < 0 || + A->Stype != SLU_NC || A->Dtype != SLU_Z || A->Mtype != SLU_GE ) + *info = -1; + if (*info != 0) { + i = -(*info); + input_error("zgsequ", &i); + return; + } + + /* Quick return if possible */ + if ( A->nrow == 0 || A->ncol == 0 ) { + *rowcnd = 1.; + *colcnd = 1.; + *amax = 0.; + return; + } + + Astore = A->Store; + Aval = Astore->nzval; + + /* Get machine constants. */ + smlnum = dmach("S"); /* slamch_("S"); */ + bignum = 1. / smlnum; + + /* Compute row scale factors. */ + for (i = 0; i < A->nrow; ++i) r[i] = 0.; + + /* Find the maximum element in each row. */ + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + r[irow] = SUPERLU_MAX( r[irow], z_abs1(&Aval[i]) ); + } + + /* Find the maximum and minimum scale factors. */ + rcmin = bignum; + rcmax = 0.; + for (i = 0; i < A->nrow; ++i) { + rcmax = SUPERLU_MAX(rcmax, r[i]); + rcmin = SUPERLU_MIN(rcmin, r[i]); + } + *amax = rcmax; + + if (rcmin == 0.) { + /* Find the first zero scale factor and return an error code. */ + for (i = 0; i < A->nrow; ++i) + if (r[i] == 0.) { + *info = i + 1; + return; + } + } else { + /* Invert the scale factors. */ + for (i = 0; i < A->nrow; ++i) + r[i] = 1. / SUPERLU_MIN( SUPERLU_MAX( r[i], smlnum ), bignum ); + /* Compute ROWCND = min(R(I)) / max(R(I)) */ + *rowcnd = SUPERLU_MAX( rcmin, smlnum ) / SUPERLU_MIN( rcmax, bignum ); + } + + /* Compute column scale factors */ + for (j = 0; j < A->ncol; ++j) c[j] = 0.; + + /* Find the maximum element in each column, assuming the row + scalings computed above. */ + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + c[j] = SUPERLU_MAX( c[j], z_abs1(&Aval[i]) * r[irow] ); + } + + /* Find the maximum and minimum scale factors. */ + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->ncol; ++j) { + rcmax = SUPERLU_MAX(rcmax, c[j]); + rcmin = SUPERLU_MIN(rcmin, c[j]); + } + + if (rcmin == 0.) { + /* Find the first zero scale factor and return an error code. */ + for (j = 0; j < A->ncol; ++j) + if ( c[j] == 0. ) { + *info = A->nrow + j + 1; + return; + } + } else { + /* Invert the scale factors. */ + for (j = 0; j < A->ncol; ++j) + c[j] = 1. / SUPERLU_MIN( SUPERLU_MAX( c[j], smlnum ), bignum); + /* Compute COLCND = min(C(J)) / max(C(J)) */ + *colcnd = SUPERLU_MAX( rcmin, smlnum ) / SUPERLU_MIN( rcmax, bignum ); + } + + return; + +} /* zgsequ */ + + diff --git a/src/Libraries/superlu-5.2.1/SRC/zgsisx.c b/src/Libraries/superlu-5.2.1/SRC/zgsisx.c new file mode 100644 index 00000000..d5cccaff --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zgsisx.c @@ -0,0 +1,738 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zgsisx.c + * \brief Computes an approximate solutions of linear equations A*X=B or A'*X=B + * + *
+ * -- SuperLU routine (version 4.2) --
+ * Lawrence Berkeley National Laboratory.
+ * November, 2010
+ * August, 2011
+ * 
+ */ +#include "slu_zdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * ZGSISX computes an approximate solutions of linear equations
+ * A*X=B or A'*X=B, using the ILU factorization from zgsitrf().
+ * An estimation of the condition number is provided. 
+ * The routine performs the following steps:
+ *
+ *   1. If A is stored column-wise (A->Stype = SLU_NC):
+ *  
+ *	1.1. If options->Equil = YES or options->RowPerm = LargeDiag, scaling
+ *	     factors are computed to equilibrate the system:
+ *	     options->Trans = NOTRANS:
+ *		 diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *	     options->Trans = TRANS:
+ *		 (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *	     options->Trans = CONJ:
+ *		 (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *	     Whether or not the system will be equilibrated depends on the
+ *	     scaling of the matrix A, but if equilibration is used, A is
+ *	     overwritten by diag(R)*A*diag(C) and B by diag(R)*B
+ *	     (if options->Trans=NOTRANS) or diag(C)*B (if options->Trans
+ *	     = TRANS or CONJ).
+ *
+ *	1.2. Permute columns of A, forming A*Pc, where Pc is a permutation
+ *	     matrix that usually preserves sparsity.
+ *	     For more details of this step, see sp_preorder.c.
+ *
+ *	1.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *	     factor the matrix A (after equilibration if options->Equil = YES)
+ *	     as Pr*A*Pc = L*U, with Pr determined by partial pivoting.
+ *
+ *	1.4. Compute the reciprocal pivot growth factor.
+ *
+ *	1.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *	     routine fills a small number on the diagonal entry, that is
+ *		U(i,i) = ||A(:,i)||_oo * options->ILU_FillTol ** (1 - i / n),
+ *	     and info will be increased by 1. The factored form of A is used
+ *	     to estimate the condition number of the preconditioner. If the
+ *	     reciprocal of the condition number is less than machine precision,
+ *	     info = A->ncol+1 is returned as a warning, but the routine still
+ *	     goes on to solve for X.
+ *
+ *	1.6. The system of equations is solved for X using the factored form
+ *	     of A.
+ *
+ *	1.7. options->IterRefine is not used
+ *
+ *	1.8. If equilibration was used, the matrix X is premultiplied by
+ *	     diag(C) (if options->Trans = NOTRANS) or diag(R)
+ *	     (if options->Trans = TRANS or CONJ) so that it solves the
+ *	     original system before equilibration.
+ *
+ *	1.9. options for ILU only
+ *	     1) If options->RowPerm = LargeDiag, MC64 is used to scale and
+ *		permute the matrix to an I-matrix, that is Pr*Dr*A*Dc has
+ *		entries of modulus 1 on the diagonal and off-diagonal entries
+ *		of modulus at most 1. If MC64 fails, dgsequ() is used to
+ *		equilibrate the system.
+ *              ( Default: LargeDiag )
+ *	     2) options->ILU_DropTol = tau is the threshold for dropping.
+ *		For L, it is used directly (for the whole row in a supernode);
+ *		For U, ||A(:,i)||_oo * tau is used as the threshold
+ *	        for the	i-th column.
+ *		If a secondary dropping rule is required, tau will
+ *	        also be used to compute the second threshold.
+ *              ( Default: 1e-4 )
+ *	     3) options->ILU_FillFactor = gamma, used as the initial guess
+ *		of memory growth.
+ *		If a secondary dropping rule is required, it will also
+ *              be used as an upper bound of the memory.
+ *              ( Default: 10 )
+ *	     4) options->ILU_DropRule specifies the dropping rule.
+ *		Option	      Meaning
+ *		======	      ===========
+ *		DROP_BASIC:   Basic dropping rule, supernodal based ILUTP(tau).
+ *		DROP_PROWS:   Supernodal based ILUTP(p,tau), p = gamma*nnz(A)/n.
+ *		DROP_COLUMN:  Variant of ILUTP(p,tau), for j-th column,
+ *			      p = gamma * nnz(A(:,j)).
+ *		DROP_AREA:    Variation of ILUTP, for j-th column, use
+ *			      nnz(F(:,1:j)) / nnz(A(:,1:j)) to control memory.
+ *		DROP_DYNAMIC: Modify the threshold tau during factorizaion:
+ *			      If nnz(L(:,1:j)) / nnz(A(:,1:j)) > gamma
+ *				  tau_L(j) := MIN(tau_0, tau_L(j-1) * 2);
+ *			      Otherwise
+ *				  tau_L(j) := MAX(tau_0, tau_L(j-1) / 2);
+ *			      tau_U(j) uses the similar rule.
+ *			      NOTE: the thresholds used by L and U are separate.
+ *		DROP_INTERP:  Compute the second dropping threshold by
+ *			      interpolation instead of sorting (default).
+ *			      In this case, the actual fill ratio is not
+ *			      guaranteed smaller than gamma.
+ *		DROP_PROWS, DROP_COLUMN and DROP_AREA are mutually exclusive.
+ *		( Default: DROP_BASIC | DROP_AREA )
+ *	     5) options->ILU_Norm is the criterion of measuring the magnitude
+ *		of a row in a supernode of L. ( Default is INF_NORM )
+ *		options->ILU_Norm	RowSize(x[1:n])
+ *		=================	===============
+ *		ONE_NORM		||x||_1 / n
+ *		TWO_NORM		||x||_2 / sqrt(n)
+ *		INF_NORM		max{|x[i]|}
+ *	     6) options->ILU_MILU specifies the type of MILU's variation.
+ *		= SILU: do not perform Modified ILU;
+ *		= SMILU_1 (not recommended):
+ *		    U(i,i) := U(i,i) + sum(dropped entries);
+ *		= SMILU_2:
+ *		    U(i,i) := U(i,i) + SGN(U(i,i)) * sum(dropped entries);
+ *		= SMILU_3:
+ *		    U(i,i) := U(i,i) + SGN(U(i,i)) * sum(|dropped entries|);
+ *		NOTE: Even SMILU_1 does not preserve the column sum because of
+ *		late dropping.
+ *              ( Default: SILU )
+ *	     7) options->ILU_FillTol is used as the perturbation when
+ *		encountering zero pivots. If some U(i,i) = 0, so that U is
+ *		exactly singular, then
+ *		   U(i,i) := ||A(:,i)|| * options->ILU_FillTol ** (1 - i / n).
+ *              ( Default: 1e-2 )
+ *
+ *   2. If A is stored row-wise (A->Stype = SLU_NR), apply the above algorithm
+ *	to the transpose of A:
+ *
+ *	2.1. If options->Equil = YES or options->RowPerm = LargeDiag, scaling
+ *	     factors are computed to equilibrate the system:
+ *	     options->Trans = NOTRANS:
+ *		 diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *	     options->Trans = TRANS:
+ *		 (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *	     options->Trans = CONJ:
+ *		 (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *	     Whether or not the system will be equilibrated depends on the
+ *	     scaling of the matrix A, but if equilibration is used, A' is
+ *	     overwritten by diag(R)*A'*diag(C) and B by diag(R)*B
+ *	     (if trans='N') or diag(C)*B (if trans = 'T' or 'C').
+ *
+ *	2.2. Permute columns of transpose(A) (rows of A),
+ *	     forming transpose(A)*Pc, where Pc is a permutation matrix that
+ *	     usually preserves sparsity.
+ *	     For more details of this step, see sp_preorder.c.
+ *
+ *	2.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *	     factor the transpose(A) (after equilibration if
+ *	     options->Fact = YES) as Pr*transpose(A)*Pc = L*U with the
+ *	     permutation Pr determined by partial pivoting.
+ *
+ *	2.4. Compute the reciprocal pivot growth factor.
+ *
+ *	2.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *	     routine fills a small number on the diagonal entry, that is
+ *		 U(i,i) = ||A(:,i)||_oo * options->ILU_FillTol ** (1 - i / n).
+ *	     And info will be increased by 1. The factored form of A is used
+ *	     to estimate the condition number of the preconditioner. If the
+ *	     reciprocal of the condition number is less than machine precision,
+ *	     info = A->ncol+1 is returned as a warning, but the routine still
+ *	     goes on to solve for X.
+ *
+ *	2.6. The system of equations is solved for X using the factored form
+ *	     of transpose(A).
+ *
+ *	2.7. If options->IterRefine is not used.
+ *
+ *	2.8. If equilibration was used, the matrix X is premultiplied by
+ *	     diag(C) (if options->Trans = NOTRANS) or diag(R)
+ *	     (if options->Trans = TRANS or CONJ) so that it solves the
+ *	     original system before equilibration.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *	   The structure defines the input parameters to control
+ *	   how the LU decomposition will be performed and how the
+ *	   system will be solved.
+ *
+ * A	   (input/output) SuperMatrix*
+ *	   Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
+ *	   of the linear equations is A->nrow. Currently, the type of A can be:
+ *	   Stype = SLU_NC or SLU_NR, Dtype = SLU_Z, Mtype = SLU_GE.
+ *	   In the future, more general A may be handled.
+ *
+ *	   On entry, If options->Fact = FACTORED and equed is not 'N',
+ *	   then A must have been equilibrated by the scaling factors in
+ *	   R and/or C.
+ *	   On exit, A is not modified
+ *         if options->Equil = NO, or
+ *         if options->Equil = YES but equed = 'N' on exit, or
+ *         if options->RowPerm = NO.
+ *
+ *	   Otherwise, if options->Equil = YES and equed is not 'N',
+ *	   A is scaled as follows:
+ *	   If A->Stype = SLU_NC:
+ *	     equed = 'R':  A := diag(R) * A
+ *	     equed = 'C':  A := A * diag(C)
+ *	     equed = 'B':  A := diag(R) * A * diag(C).
+ *	   If A->Stype = SLU_NR:
+ *	     equed = 'R':  transpose(A) := diag(R) * transpose(A)
+ *	     equed = 'C':  transpose(A) := transpose(A) * diag(C)
+ *	     equed = 'B':  transpose(A) := diag(R) * transpose(A) * diag(C).
+ *
+ *         If options->RowPerm = LargeDiag, MC64 is used to scale and permute
+ *            the matrix to an I-matrix, that is A is modified as follows:
+ *            P*Dr*A*Dc has entries of modulus 1 on the diagonal and 
+ *            off-diagonal entries of modulus at most 1. P is a permutation
+ *            obtained from MC64.
+ *            If MC64 fails, zgsequ() is used to equilibrate the system,
+ *            and A is scaled as above, but no permutation is involved.
+ *            On exit, A is restored to the orginal row numbering, so
+ *            Dr*A*Dc is returned.
+ *
+ * perm_c  (input/output) int*
+ *	   If A->Stype = SLU_NC, Column permutation vector of size A->ncol,
+ *	   which defines the permutation matrix Pc; perm_c[i] = j means
+ *	   column i of A is in position j in A*Pc.
+ *	   On exit, perm_c may be overwritten by the product of the input
+ *	   perm_c and a permutation that postorders the elimination tree
+ *	   of Pc'*A'*A*Pc; perm_c is not changed if the elimination tree
+ *	   is already in postorder.
+ *
+ *	   If A->Stype = SLU_NR, column permutation vector of size A->nrow,
+ *	   which describes permutation of columns of transpose(A) 
+ *	   (rows of A) as described above.
+ *
+ * perm_r  (input/output) int*
+ *	   If A->Stype = SLU_NC, row permutation vector of size A->nrow, 
+ *	   which defines the permutation matrix Pr, and is determined
+ *	   by MC64 first then followed by partial pivoting.
+ *         perm_r[i] = j means row i of A is in position j in Pr*A.
+ *
+ *	   If A->Stype = SLU_NR, permutation vector of size A->ncol, which
+ *	   determines permutation of rows of transpose(A)
+ *	   (columns of A) as described above.
+ *
+ *	   If options->Fact = SamePattern_SameRowPerm, the pivoting routine
+ *	   will try to use the input perm_r, unless a certain threshold
+ *	   criterion is violated. In that case, perm_r is overwritten by a
+ *	   new permutation determined by partial pivoting or diagonal
+ *	   threshold pivoting.
+ *	   Otherwise, perm_r is output argument.
+ *
+ * etree   (input/output) int*,  dimension (A->ncol)
+ *	   Elimination tree of Pc'*A'*A*Pc.
+ *	   If options->Fact != FACTORED and options->Fact != DOFACT,
+ *	   etree is an input argument, otherwise it is an output argument.
+ *	   Note: etree is a vector of parent pointers for a forest whose
+ *	   vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *
+ * equed   (input/output) char*
+ *	   Specifies the form of equilibration that was done.
+ *	   = 'N': No equilibration.
+ *	   = 'R': Row equilibration, i.e., A was premultiplied by diag(R).
+ *	   = 'C': Column equilibration, i.e., A was postmultiplied by diag(C).
+ *	   = 'B': Both row and column equilibration, i.e., A was replaced 
+ *		  by diag(R)*A*diag(C).
+ *	   If options->Fact = FACTORED, equed is an input argument,
+ *	   otherwise it is an output argument.
+ *
+ * R	   (input/output) double*, dimension (A->nrow)
+ *	   The row scale factors for A or transpose(A).
+ *	   If equed = 'R' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *	       (if A->Stype = SLU_NR) is multiplied on the left by diag(R).
+ *	   If equed = 'N' or 'C', R is not accessed.
+ *	   If options->Fact = FACTORED, R is an input argument,
+ *	       otherwise, R is output.
+ *	   If options->Fact = FACTORED and equed = 'R' or 'B', each element
+ *	       of R must be positive.
+ *
+ * C	   (input/output) double*, dimension (A->ncol)
+ *	   The column scale factors for A or transpose(A).
+ *	   If equed = 'C' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *	       (if A->Stype = SLU_NR) is multiplied on the right by diag(C).
+ *	   If equed = 'N' or 'R', C is not accessed.
+ *	   If options->Fact = FACTORED, C is an input argument,
+ *	       otherwise, C is output.
+ *	   If options->Fact = FACTORED and equed = 'C' or 'B', each element
+ *	       of C must be positive.
+ *
+ * L	   (output) SuperMatrix*
+ *	   The factor L from the factorization
+ *	       Pr*A*Pc=L*U		(if A->Stype SLU_= NC) or
+ *	       Pr*transpose(A)*Pc=L*U	(if A->Stype = SLU_NR).
+ *	   Uses compressed row subscripts storage for supernodes, i.e.,
+ *	   L has types: Stype = SLU_SC, Dtype = SLU_Z, Mtype = SLU_TRLU.
+ *
+ * U	   (output) SuperMatrix*
+ *	   The factor U from the factorization
+ *	       Pr*A*Pc=L*U		(if A->Stype = SLU_NC) or
+ *	       Pr*transpose(A)*Pc=L*U	(if A->Stype = SLU_NR).
+ *	   Uses column-wise storage scheme, i.e., U has types:
+ *	   Stype = SLU_NC, Dtype = SLU_Z, Mtype = SLU_TRU.
+ *
+ * work    (workspace/output) void*, size (lwork) (in bytes)
+ *	   User supplied workspace, should be large enough
+ *	   to hold data structures for factors L and U.
+ *	   On exit, if fact is not 'F', L and U point to this array.
+ *
+ * lwork   (input) int
+ *	   Specifies the size of work array in bytes.
+ *	   = 0:  allocate space internally by system malloc;
+ *	   > 0:  use user-supplied work array of length lwork in bytes,
+ *		 returns error if space runs out.
+ *	   = -1: the routine guesses the amount of space needed without
+ *		 performing the factorization, and returns it in
+ *		 mem_usage->total_needed; no other side effects.
+ *
+ *	   See argument 'mem_usage' for memory usage statistics.
+ *
+ * B	   (input/output) SuperMatrix*
+ *	   B has types: Stype = SLU_DN, Dtype = SLU_Z, Mtype = SLU_GE.
+ *	   On entry, the right hand side matrix.
+ *	   If B->ncol = 0, only LU decomposition is performed, the triangular
+ *			   solve is skipped.
+ *	   On exit,
+ *	      if equed = 'N', B is not modified; otherwise
+ *	      if A->Stype = SLU_NC:
+ *		 if options->Trans = NOTRANS and equed = 'R' or 'B',
+ *		    B is overwritten by diag(R)*B;
+ *		 if options->Trans = TRANS or CONJ and equed = 'C' of 'B',
+ *		    B is overwritten by diag(C)*B;
+ *	      if A->Stype = SLU_NR:
+ *		 if options->Trans = NOTRANS and equed = 'C' or 'B',
+ *		    B is overwritten by diag(C)*B;
+ *		 if options->Trans = TRANS or CONJ and equed = 'R' of 'B',
+ *		    B is overwritten by diag(R)*B.
+ *
+ * X	   (output) SuperMatrix*
+ *	   X has types: Stype = SLU_DN, Dtype = SLU_Z, Mtype = SLU_GE.
+ *	   If info = 0 or info = A->ncol+1, X contains the solution matrix
+ *	   to the original system of equations. Note that A and B are modified
+ *	   on exit if equed is not 'N', and the solution to the equilibrated
+ *	   system is inv(diag(C))*X if options->Trans = NOTRANS and
+ *	   equed = 'C' or 'B', or inv(diag(R))*X if options->Trans = 'T' or 'C'
+ *	   and equed = 'R' or 'B'.
+ *
+ * recip_pivot_growth (output) double*
+ *	   The reciprocal pivot growth factor max_j( norm(A_j)/norm(U_j) ).
+ *	   The infinity norm is used. If recip_pivot_growth is much less
+ *	   than 1, the stability of the LU factorization could be poor.
+ *
+ * rcond   (output) double*
+ *	   The estimate of the reciprocal condition number of the matrix A
+ *	   after equilibration (if done). If rcond is less than the machine
+ *	   precision (in particular, if rcond = 0), the matrix is singular
+ *	   to working precision. This condition is indicated by a return
+ *	   code of info > 0.
+ *
+ * mem_usage (output) mem_usage_t*
+ *	   Record the memory usage statistics, consisting of following fields:
+ *	   - for_lu (float)
+ *	     The amount of space used in bytes for L\U data structures.
+ *	   - total_needed (float)
+ *	     The amount of space needed in bytes to perform factorization.
+ *	   - expansions (int)
+ *	     The number of memory expansions during the LU factorization.
+ *
+ * stat   (output) SuperLUStat_t*
+ *	  Record the statistics on runtime and floating-point operation count.
+ *	  See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ *	   = 0: successful exit
+ *	   < 0: if info = -i, the i-th argument had an illegal value
+ *	   > 0: if info = i, and i is
+ *		<= A->ncol: number of zero pivots. They are replaced by small
+ *		      entries due to options->ILU_FillTol.
+ *		= A->ncol+1: U is nonsingular, but RCOND is less than machine
+ *		      precision, meaning that the matrix is singular to
+ *		      working precision. Nevertheless, the solution and
+ *		      error bounds are computed because there are a number
+ *		      of situations where the computed solution can be more
+ *		      accurate than the value of RCOND would suggest.
+ *		> A->ncol+1: number of bytes allocated when memory allocation
+ *		      failure occurred, plus A->ncol.
+ * 
+ */ + +void +zgsisx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, + int *etree, char *equed, double *R, double *C, + SuperMatrix *L, SuperMatrix *U, void *work, int lwork, + SuperMatrix *B, SuperMatrix *X, + double *recip_pivot_growth, double *rcond, + GlobalLU_t *Glu, mem_usage_t *mem_usage, SuperLUStat_t *stat, int *info) +{ + + DNformat *Bstore, *Xstore; + doublecomplex *Bmat, *Xmat; + int ldb, ldx, nrhs, n; + SuperMatrix *AA;/* A in SLU_NC format used by the factorization routine.*/ + SuperMatrix AC; /* Matrix postmultiplied by Pc */ + int colequ, equil, nofact, notran, rowequ, permc_spec, mc64; + trans_t trant; + char norm[1]; + int i, j, info1; + double amax, anorm, bignum, smlnum, colcnd, rowcnd, rcmax, rcmin; + int relax, panel_size; + double diag_pivot_thresh; + double t0; /* temporary time */ + double *utime; + + int *perm = NULL; /* permutation returned from MC64 */ + + /* External functions */ + extern double zlangs(char *, SuperMatrix *); + + Bstore = B->Store; + Xstore = X->Store; + Bmat = Bstore->nzval; + Xmat = Xstore->nzval; + ldb = Bstore->lda; + ldx = Xstore->lda; + nrhs = B->ncol; + n = B->nrow; + + *info = 0; + nofact = (options->Fact != FACTORED); + equil = (options->Equil == YES); + notran = (options->Trans == NOTRANS); + mc64 = (options->RowPerm == LargeDiag); + if ( nofact ) { + *(unsigned char *)equed = 'N'; + rowequ = FALSE; + colequ = FALSE; + } else { + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + smlnum = dmach("Safe minimum"); /* lamch_("Safe minimum"); */ + bignum = 1. / smlnum; + } + + /* Test the input parameters */ + if (options->Fact != DOFACT && options->Fact != SamePattern && + options->Fact != SamePattern_SameRowPerm && + options->Fact != FACTORED && + options->Trans != NOTRANS && options->Trans != TRANS && + options->Trans != CONJ && + options->Equil != NO && options->Equil != YES) + *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + (A->Stype != SLU_NC && A->Stype != SLU_NR) || + A->Dtype != SLU_Z || A->Mtype != SLU_GE ) + *info = -2; + else if ( options->Fact == FACTORED && + !(rowequ || colequ || strncmp(equed, "N", 1)==0) ) + *info = -6; + else { + if (rowequ) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, R[j]); + rcmax = SUPERLU_MAX(rcmax, R[j]); + } + if (rcmin <= 0.) *info = -7; + else if ( A->nrow > 0) + rowcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else rowcnd = 1.; + } + if (colequ && *info == 0) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, C[j]); + rcmax = SUPERLU_MAX(rcmax, C[j]); + } + if (rcmin <= 0.) *info = -8; + else if (A->nrow > 0) + colcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else colcnd = 1.; + } + if (*info == 0) { + if ( lwork < -1 ) *info = -12; + else if ( B->ncol < 0 || Bstore->lda < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_Z || + B->Mtype != SLU_GE ) + *info = -13; + else if ( X->ncol < 0 || Xstore->lda < SUPERLU_MAX(0, A->nrow) || + (B->ncol != 0 && B->ncol != X->ncol) || + X->Stype != SLU_DN || + X->Dtype != SLU_Z || X->Mtype != SLU_GE ) + *info = -14; + } + } + if (*info != 0) { + i = -(*info); + input_error("zgsisx", &i); + return; + } + + /* Initialization for factor parameters */ + panel_size = sp_ienv(1); + relax = sp_ienv(2); + diag_pivot_thresh = options->DiagPivotThresh; + + utime = stat->utime; + + /* Convert A to SLU_NC format when necessary. */ + if ( A->Stype == SLU_NR ) { + NRformat *Astore = A->Store; + AA = (SuperMatrix *) SUPERLU_MALLOC( sizeof(SuperMatrix) ); + zCreate_CompCol_Matrix(AA, A->ncol, A->nrow, Astore->nnz, + Astore->nzval, Astore->colind, Astore->rowptr, + SLU_NC, A->Dtype, A->Mtype); + if ( notran ) { /* Reverse the transpose argument. */ + trant = TRANS; + notran = 0; + } else { + trant = NOTRANS; + notran = 1; + } + } else { /* A->Stype == SLU_NC */ + trant = options->Trans; + AA = A; + } + + if ( nofact ) { + register int i, j; + NCformat *Astore = AA->Store; + int nnz = Astore->nnz; + int *colptr = Astore->colptr; + int *rowind = Astore->rowind; + doublecomplex *nzval = (doublecomplex *)Astore->nzval; + + if ( mc64 ) { + t0 = SuperLU_timer_(); + if ((perm = intMalloc(n)) == NULL) + ABORT("SUPERLU_MALLOC fails for perm[]"); + + info1 = zldperm(5, n, nnz, colptr, rowind, nzval, perm, R, C); + + if (info1 != 0) { /* MC64 fails, call zgsequ() later */ + mc64 = 0; + SUPERLU_FREE(perm); + perm = NULL; + } else { + if ( equil ) { + rowequ = colequ = 1; + for (i = 0; i < n; i++) { + R[i] = exp(R[i]); + C[i] = exp(C[i]); + } + /* scale the matrix */ + for (j = 0; j < n; j++) { + for (i = colptr[j]; i < colptr[j + 1]; i++) { + zd_mult(&nzval[i], &nzval[i], R[rowind[i]] * C[j]); + } + } + *equed = 'B'; + } + + /* permute the matrix */ + for (j = 0; j < n; j++) { + for (i = colptr[j]; i < colptr[j + 1]; i++) { + /*nzval[i] *= R[rowind[i]] * C[j];*/ + rowind[i] = perm[rowind[i]]; + } + } + } + utime[EQUIL] = SuperLU_timer_() - t0; + } + + if ( !mc64 & equil ) { /* Only perform equilibration, no row perm */ + t0 = SuperLU_timer_(); + /* Compute row and column scalings to equilibrate the matrix A. */ + zgsequ(AA, R, C, &rowcnd, &colcnd, &amax, &info1); + + if ( info1 == 0 ) { + /* Equilibrate matrix A. */ + zlaqgs(AA, R, C, rowcnd, colcnd, amax, equed); + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + } + utime[EQUIL] = SuperLU_timer_() - t0; + } + } + + + if ( nofact ) { + + t0 = SuperLU_timer_(); + /* + * Gnet column permutation vector perm_c[], according to permc_spec: + * permc_spec = NATURAL: natural ordering + * permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A + * permc_spec = MMD_ATA: minimum degree on structure of A'*A + * permc_spec = COLAMD: approximate minimum degree column ordering + * permc_spec = MY_PERMC: the ordering already supplied in perm_c[] + */ + permc_spec = options->ColPerm; + if ( permc_spec != MY_PERMC && options->Fact == DOFACT ) + get_perm_c(permc_spec, AA, perm_c); + utime[COLPERM] = SuperLU_timer_() - t0; + + t0 = SuperLU_timer_(); + sp_preorder(options, AA, perm_c, etree, &AC); + utime[ETREE] = SuperLU_timer_() - t0; + + /* Compute the LU factorization of A*Pc. */ + t0 = SuperLU_timer_(); + zgsitrf(options, &AC, relax, panel_size, etree, work, lwork, + perm_c, perm_r, L, U, Glu, stat, info); + utime[FACT] = SuperLU_timer_() - t0; + + if ( lwork == -1 ) { + mem_usage->total_needed = *info - A->ncol; + return; + } + + if ( mc64 ) { /* Fold MC64's perm[] into perm_r[]. */ + NCformat *Astore = AA->Store; + int nnz = Astore->nnz, *rowind = Astore->rowind; + int *perm_tmp, *iperm; + if ((perm_tmp = intMalloc(2*n)) == NULL) + ABORT("SUPERLU_MALLOC fails for perm_tmp[]"); + iperm = perm_tmp + n; + for (i = 0; i < n; ++i) perm_tmp[i] = perm_r[perm[i]]; + for (i = 0; i < n; ++i) { + perm_r[i] = perm_tmp[i]; + iperm[perm[i]] = i; + } + + /* Restore A's original row indices. */ + for (i = 0; i < nnz; ++i) rowind[i] = iperm[rowind[i]]; + + SUPERLU_FREE(perm); /* MC64 permutation */ + SUPERLU_FREE(perm_tmp); + } + } + + if ( options->PivotGrowth ) { + if ( *info > 0 ) return; + + /* Compute the reciprocal pivot growth factor *recip_pivot_growth. */ + *recip_pivot_growth = zPivotGrowth(A->ncol, AA, perm_c, L, U); + } + + if ( options->ConditionNumber ) { + /* Estimate the reciprocal of the condition number of A. */ + t0 = SuperLU_timer_(); + if ( notran ) { + *(unsigned char *)norm = '1'; + } else { + *(unsigned char *)norm = 'I'; + } + anorm = zlangs(norm, AA); + zgscon(norm, L, U, anorm, rcond, stat, &info1); + utime[RCOND] = SuperLU_timer_() - t0; + } + + if ( nrhs > 0 ) { /* Solve the system */ + doublecomplex *rhs_work; + + /* Scale and permute the right-hand side if equilibration + and permutation from MC64 were performed. */ + if ( notran ) { + if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) + zd_mult(&Bmat[i+j*ldb], &Bmat[i+j*ldb], R[i]); + } + } else if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) { + zd_mult(&Bmat[i+j*ldb], &Bmat[i+j*ldb], C[i]); + } + } + + /* Compute the solution matrix X. */ + for (j = 0; j < nrhs; j++) /* Save a copy of the right hand sides */ + for (i = 0; i < B->nrow; i++) + Xmat[i + j*ldx] = Bmat[i + j*ldb]; + + t0 = SuperLU_timer_(); + zgstrs (trant, L, U, perm_c, perm_r, X, stat, &info1); + utime[SOLVE] = SuperLU_timer_() - t0; + + /* Transform the solution matrix X to a solution of the original + system. */ + if ( notran ) { + if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) { + zd_mult(&Xmat[i+j*ldx], &Xmat[i+j*ldx], C[i]); + } + } + } else { /* transposed system */ + if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) { + zd_mult(&Xmat[i+j*ldx], &Xmat[i+j*ldx], R[i]); + } + } + } + + } /* end if nrhs > 0 */ + + if ( options->ConditionNumber ) { + /* The matrix is singular to working precision. */ + /* if ( *rcond < dlamch_("E") && *info == 0) *info = A->ncol + 1; */ + if ( *rcond < dmach("E") && *info == 0) *info = A->ncol + 1; + } + + if ( nofact ) { + ilu_zQuerySpace(L, U, mem_usage); + Destroy_CompCol_Permuted(&AC); + } + if ( A->Stype == SLU_NR ) { + Destroy_SuperMatrix_Store(AA); + SUPERLU_FREE(AA); + } + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zgsitrf.c b/src/Libraries/superlu-5.2.1/SRC/zgsitrf.c new file mode 100644 index 00000000..4050134b --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zgsitrf.c @@ -0,0 +1,661 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zgsitrf.c + * \brief Computes an ILU factorization of a general sparse matrix + * + *
+ * -- SuperLU routine (version 4.1) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ *
+ * 
+ */ + +#include "slu_zdefs.h" + +#ifdef DEBUG +int num_drop_L; +#endif + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * ZGSITRF computes an ILU factorization of a general sparse m-by-n
+ * matrix A using partial pivoting with row interchanges.
+ * The factorization has the form
+ *     Pr * A = L * U
+ * where Pr is a row permutation matrix, L is lower triangular with unit
+ * diagonal elements (lower trapezoidal if A->nrow > A->ncol), and U is upper
+ * triangular (upper trapezoidal if A->nrow < A->ncol).
+ *
+ * See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *	   The structure defines the input parameters to control
+ *	   how the ILU decomposition will be performed.
+ *
+ * A	    (input) SuperMatrix*
+ *	    Original matrix A, permuted by columns, of dimension
+ *	    (A->nrow, A->ncol). The type of A can be:
+ *	    Stype = SLU_NCP; Dtype = SLU_Z; Mtype = SLU_GE.
+ *
+ * relax    (input) int
+ *	    To control degree of relaxing supernodes. If the number
+ *	    of nodes (columns) in a subtree of the elimination tree is less
+ *	    than relax, this subtree is considered as one supernode,
+ *	    regardless of the row structures of those columns.
+ *
+ * panel_size (input) int
+ *	    A panel consists of at most panel_size consecutive columns.
+ *
+ * etree    (input) int*, dimension (A->ncol)
+ *	    Elimination tree of A'*A.
+ *	    Note: etree is a vector of parent pointers for a forest whose
+ *	    vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *	    On input, the columns of A should be permuted so that the
+ *	    etree is in a certain postorder.
+ *
+ * work     (input/output) void*, size (lwork) (in bytes)
+ *	    User-supplied work space and space for the output data structures.
+ *	    Not referenced if lwork = 0;
+ *
+ * lwork   (input) int
+ *	   Specifies the size of work array in bytes.
+ *	   = 0:  allocate space internally by system malloc;
+ *	   > 0:  use user-supplied work array of length lwork in bytes,
+ *		 returns error if space runs out.
+ *	   = -1: the routine guesses the amount of space needed without
+ *		 performing the factorization, and returns it in
+ *		 *info; no other side effects.
+ *
+ * perm_c   (input) int*, dimension (A->ncol)
+ *	    Column permutation vector, which defines the
+ *	    permutation matrix Pc; perm_c[i] = j means column i of A is
+ *	    in position j in A*Pc.
+ *	    When searching for diagonal, perm_c[*] is applied to the
+ *	    row subscripts of A, so that diagonal threshold pivoting
+ *	    can find the diagonal of A, rather than that of A*Pc.
+ *
+ * perm_r   (input/output) int*, dimension (A->nrow)
+ *	    Row permutation vector which defines the permutation matrix Pr,
+ *	    perm_r[i] = j means row i of A is in position j in Pr*A.
+ *	    If options->Fact = SamePattern_SameRowPerm, the pivoting routine
+ *	       will try to use the input perm_r, unless a certain threshold
+ *	       criterion is violated. In that case, perm_r is overwritten by
+ *	       a new permutation determined by partial pivoting or diagonal
+ *	       threshold pivoting.
+ *	    Otherwise, perm_r is output argument;
+ *
+ * L	    (output) SuperMatrix*
+ *	    The factor L from the factorization Pr*A=L*U; use compressed row
+ *	    subscripts storage for supernodes, i.e., L has type:
+ *	    Stype = SLU_SC, Dtype = SLU_Z, Mtype = SLU_TRLU.
+ *
+ * U	    (output) SuperMatrix*
+ *	    The factor U from the factorization Pr*A*Pc=L*U. Use column-wise
+ *	    storage scheme, i.e., U has types: Stype = SLU_NC,
+ *	    Dtype = SLU_Z, Mtype = SLU_TRU.
+ *
+ * Glu      (input/output) GlobalLU_t *
+ *          If options->Fact == SamePattern_SameRowPerm, it is an input;
+ *              The matrix A will be factorized assuming that a 
+ *              factorization of a matrix with the same sparsity pattern
+ *              and similar numerical values was performed prior to this one.
+ *              Therefore, this factorization will reuse both row and column
+ *		scaling factors R and C, both row and column permutation
+ *		vectors perm_r and perm_c, and the L & U data structures
+ *		set up from the previous factorization.
+ *          Otherwise, it is an output.
+ *
+ * stat     (output) SuperLUStat_t*
+ *	    Record the statistics on runtime and floating-point operation count.
+ *	    See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info     (output) int*
+ *	    = 0: successful exit
+ *	    < 0: if info = -i, the i-th argument had an illegal value
+ *	    > 0: if info = i, and i is
+ *	       <= A->ncol: number of zero pivots. They are replaced by small
+ *		  entries according to options->ILU_FillTol.
+ *	       > A->ncol: number of bytes allocated when memory allocation
+ *		  failure occurred, plus A->ncol. If lwork = -1, it is
+ *		  the estimated amount of space needed, plus A->ncol.
+ *
+ * ======================================================================
+ *
+ * Local Working Arrays:
+ * ======================
+ *   m = number of rows in the matrix
+ *   n = number of columns in the matrix
+ *
+ *   marker[0:3*m-1]: marker[i] = j means that node i has been
+ *	reached when working on column j.
+ *	Storage: relative to original row subscripts
+ *	NOTE: There are 4 of them:
+ *	      marker/marker1 are used for panel dfs, see (ilu_)dpanel_dfs.c;
+ *	      marker2 is used for inner-factorization, see (ilu)_dcolumn_dfs.c;
+ *	      marker_relax(has its own space) is used for relaxed supernodes.
+ *
+ *   parent[0:m-1]: parent vector used during dfs
+ *	Storage: relative to new row subscripts
+ *
+ *   xplore[0:m-1]: xplore[i] gives the location of the next (dfs)
+ *	unexplored neighbor of i in lsub[*]
+ *
+ *   segrep[0:nseg-1]: contains the list of supernodal representatives
+ *	in topological order of the dfs. A supernode representative is the
+ *	last column of a supernode.
+ *	The maximum size of segrep[] is n.
+ *
+ *   repfnz[0:W*m-1]: for a nonzero segment U[*,j] that ends at a
+ *	supernodal representative r, repfnz[r] is the location of the first
+ *	nonzero in this segment.  It is also used during the dfs: repfnz[r]>0
+ *	indicates the supernode r has been explored.
+ *	NOTE: There are W of them, each used for one column of a panel.
+ *
+ *   panel_lsub[0:W*m-1]: temporary for the nonzeros row indices below
+ *	the panel diagonal. These are filled in during dpanel_dfs(), and are
+ *	used later in the inner LU factorization within the panel.
+ *	panel_lsub[]/dense[] pair forms the SPA data structure.
+ *	NOTE: There are W of them.
+ *
+ *   dense[0:W*m-1]: sparse accumulating (SPA) vector for intermediate values;
+ *		   NOTE: there are W of them.
+ *
+ *   tempv[0:*]: real temporary used for dense numeric kernels;
+ *	The size of this array is defined by NUM_TEMPV() in slu_util.h.
+ *	It is also used by the dropping routine ilu_ddrop_row().
+ * 
+ */ + +void +zgsitrf(superlu_options_t *options, SuperMatrix *A, int relax, int panel_size, + int *etree, void *work, int lwork, int *perm_c, int *perm_r, + SuperMatrix *L, SuperMatrix *U, + GlobalLU_t *Glu, /* persistent to facilitate multiple factorizations */ + SuperLUStat_t *stat, int *info) +{ + /* Local working arrays */ + NCPformat *Astore; + int *iperm_r = NULL; /* inverse of perm_r; used when + options->Fact == SamePattern_SameRowPerm */ + int *iperm_c; /* inverse of perm_c */ + int *swap, *iswap; /* swap is used to store the row permutation + during the factorization. Initially, it is set + to iperm_c (row indeces of Pc*A*Pc'). + iswap is the inverse of swap. After the + factorization, it is equal to perm_r. */ + int *iwork; + doublecomplex *zwork; + int *segrep, *repfnz, *parent, *xplore; + int *panel_lsub; /* dense[]/panel_lsub[] pair forms a w-wide SPA */ + int *marker, *marker_relax; + doublecomplex *dense, *tempv; + double *dtempv; + int *relax_end, *relax_fsupc; + doublecomplex *a; + int *asub; + int *xa_begin, *xa_end; + int *xsup, *supno; + int *xlsub, *xlusup, *xusub; + int nzlumax; + double *amax; + doublecomplex drop_sum; + double alpha, omega; /* used in MILU, mimicing DRIC */ + double *dwork2; /* used by the second dropping rule */ + + /* Local scalars */ + fact_t fact = options->Fact; + double diag_pivot_thresh = options->DiagPivotThresh; + double drop_tol = options->ILU_DropTol; /* tau */ + double fill_ini = options->ILU_FillTol; /* tau^hat */ + double gamma = options->ILU_FillFactor; + int drop_rule = options->ILU_DropRule; + milu_t milu = options->ILU_MILU; + double fill_tol; + int pivrow; /* pivotal row number in the original matrix A */ + int nseg1; /* no of segments in U-column above panel row jcol */ + int nseg; /* no of segments in each U-column */ + register int jcol; + register int kcol; /* end column of a relaxed snode */ + register int icol; + register int i, k, jj, new_next, iinfo; + int m, n, min_mn, jsupno, fsupc, nextlu, nextu; + int w_def; /* upper bound on panel width */ + int usepr, iperm_r_allocated = 0; + int nnzL, nnzU; + int *panel_histo = stat->panel_histo; + flops_t *ops = stat->ops; + + int last_drop;/* the last column which the dropping rules applied */ + int quota; + int nnzAj; /* number of nonzeros in A(:,1:j) */ + int nnzLj, nnzUj; + double tol_L = drop_tol, tol_U = drop_tol; + doublecomplex zero = {0.0, 0.0}; + double one = 1.0; + + /* Executable */ + iinfo = 0; + m = A->nrow; + n = A->ncol; + min_mn = SUPERLU_MIN(m, n); + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + + /* Allocate storage common to the factor routines */ + *info = zLUMemInit(fact, work, lwork, m, n, Astore->nnz, panel_size, + gamma, L, U, Glu, &iwork, &zwork); + if ( *info ) return; + + xsup = Glu->xsup; + supno = Glu->supno; + xlsub = Glu->xlsub; + xlusup = Glu->xlusup; + xusub = Glu->xusub; + + SetIWork(m, n, panel_size, iwork, &segrep, &parent, &xplore, + &repfnz, &panel_lsub, &marker_relax, &marker); + zSetRWork(m, panel_size, zwork, &dense, &tempv); + + usepr = (fact == SamePattern_SameRowPerm); + if ( usepr ) { + /* Compute the inverse of perm_r */ + iperm_r = (int *) intMalloc(m); + for (k = 0; k < m; ++k) iperm_r[perm_r[k]] = k; + iperm_r_allocated = 1; + } + + iperm_c = (int *) intMalloc(n); + for (k = 0; k < n; ++k) iperm_c[perm_c[k]] = k; + swap = (int *)intMalloc(n); + for (k = 0; k < n; k++) swap[k] = iperm_c[k]; + iswap = (int *)intMalloc(n); + for (k = 0; k < n; k++) iswap[k] = perm_c[k]; + amax = (double *) doubleMalloc(panel_size); + if (drop_rule & DROP_SECONDARY) + dwork2 = (double *)doubleMalloc(n); + else + dwork2 = NULL; + + nnzAj = 0; + nnzLj = 0; + nnzUj = 0; + last_drop = SUPERLU_MAX(min_mn - 2 * sp_ienv(7), (int)(min_mn * 0.95)); + alpha = pow((double)n, -1.0 / options->ILU_MILU_Dim); + + /* Identify relaxed snodes */ + relax_end = (int *) intMalloc(n); + relax_fsupc = (int *) intMalloc(n); + if ( options->SymmetricMode == YES ) + ilu_heap_relax_snode(n, etree, relax, marker, relax_end, relax_fsupc); + else + ilu_relax_snode(n, etree, relax, marker, relax_end, relax_fsupc); + + ifill (perm_r, m, EMPTY); + ifill (marker, m * NO_MARKER, EMPTY); + supno[0] = -1; + xsup[0] = xlsub[0] = xusub[0] = xlusup[0] = 0; + w_def = panel_size; + + /* Mark the rows used by relaxed supernodes */ + ifill (marker_relax, m, EMPTY); + i = mark_relax(m, relax_end, relax_fsupc, xa_begin, xa_end, + asub, marker_relax); +#if ( PRNTlevel >= 1) + printf("%d relaxed supernodes.\n", i); +#endif + + /* + * Work on one "panel" at a time. A panel is one of the following: + * (a) a relaxed supernode at the bottom of the etree, or + * (b) panel_size contiguous columns, defined by the user + */ + for (jcol = 0; jcol < min_mn; ) { + + if ( relax_end[jcol] != EMPTY ) { /* start of a relaxed snode */ + kcol = relax_end[jcol]; /* end of the relaxed snode */ + panel_histo[kcol-jcol+1]++; + + /* Drop small rows in the previous supernode. */ + if (jcol > 0 && jcol < last_drop) { + int first = xsup[supno[jcol - 1]]; + int last = jcol - 1; + int quota; + + /* Compute the quota */ + if (drop_rule & DROP_PROWS) + quota = gamma * Astore->nnz / m * (m - first) / m + * (last - first + 1); + else if (drop_rule & DROP_COLUMN) { + int i; + quota = 0; + for (i = first; i <= last; i++) + quota += xa_end[i] - xa_begin[i]; + quota = gamma * quota * (m - first) / m; + } else if (drop_rule & DROP_AREA) + quota = gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) / m) + - nnzLj; + else + quota = m * n; + fill_tol = pow(fill_ini, 1.0 - 0.5 * (first + last) / min_mn); + + /* Drop small rows */ + dtempv = (double *) tempv; + i = ilu_zdrop_row(options, first, last, tol_L, quota, &nnzLj, + &fill_tol, Glu, dtempv, dwork2, 0); + /* Reset the parameters */ + if (drop_rule & DROP_DYNAMIC) { + if (gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) / m) + < nnzLj) + tol_L = SUPERLU_MIN(1.0, tol_L * 2.0); + else + tol_L = SUPERLU_MAX(drop_tol, tol_L * 0.5); + } + if (fill_tol < 0) iinfo -= (int)fill_tol; +#ifdef DEBUG + num_drop_L += i * (last - first + 1); +#endif + } + + /* -------------------------------------- + * Factorize the relaxed supernode(jcol:kcol) + * -------------------------------------- */ + /* Determine the union of the row structure of the snode */ + if ( (*info = ilu_zsnode_dfs(jcol, kcol, asub, xa_begin, xa_end, + marker, Glu)) != 0 ) + return; + + nextu = xusub[jcol]; + nextlu = xlusup[jcol]; + jsupno = supno[jcol]; + fsupc = xsup[jsupno]; + new_next = nextlu + (xlsub[fsupc+1]-xlsub[fsupc])*(kcol-jcol+1); + nzlumax = Glu->nzlumax; + while ( new_next > nzlumax ) { + if ((*info = zLUMemXpand(jcol, nextlu, LUSUP, &nzlumax, Glu))) + return; + } + + for (icol = jcol; icol <= kcol; icol++) { + xusub[icol+1] = nextu; + + amax[0] = 0.0; + /* Scatter into SPA dense[*] */ + for (k = xa_begin[icol]; k < xa_end[icol]; k++) { + register double tmp = z_abs1 (&a[k]); + if (tmp > amax[0]) amax[0] = tmp; + dense[asub[k]] = a[k]; + } + nnzAj += xa_end[icol] - xa_begin[icol]; + if (amax[0] == 0.0) { + amax[0] = fill_ini; +#if ( PRNTlevel >= 1) + printf("Column %d is entirely zero!\n", icol); + fflush(stdout); +#endif + } + + /* Numeric update within the snode */ + zsnode_bmod(icol, jsupno, fsupc, dense, tempv, Glu, stat); + + if (usepr) pivrow = iperm_r[icol]; + fill_tol = pow(fill_ini, 1.0 - (double)icol / (double)min_mn); + if ( (*info = ilu_zpivotL(icol, diag_pivot_thresh, &usepr, + perm_r, iperm_c[icol], swap, iswap, + marker_relax, &pivrow, + amax[0] * fill_tol, milu, zero, + Glu, stat)) ) { + iinfo++; + marker[pivrow] = kcol; + } + + } + + jcol = kcol + 1; + + } else { /* Work on one panel of panel_size columns */ + + /* Adjust panel_size so that a panel won't overlap with the next + * relaxed snode. + */ + panel_size = w_def; + for (k = jcol + 1; k < SUPERLU_MIN(jcol+panel_size, min_mn); k++) + if ( relax_end[k] != EMPTY ) { + panel_size = k - jcol; + break; + } + if ( k == min_mn ) panel_size = min_mn - jcol; + panel_histo[panel_size]++; + + /* symbolic factor on a panel of columns */ + ilu_zpanel_dfs(m, panel_size, jcol, A, perm_r, &nseg1, + dense, amax, panel_lsub, segrep, repfnz, + marker, parent, xplore, Glu); + + /* numeric sup-panel updates in topological order */ + zpanel_bmod(m, panel_size, jcol, nseg1, dense, + tempv, segrep, repfnz, Glu, stat); + + /* Sparse LU within the panel, and below panel diagonal */ + for (jj = jcol; jj < jcol + panel_size; jj++) { + + k = (jj - jcol) * m; /* column index for w-wide arrays */ + + nseg = nseg1; /* Begin after all the panel segments */ + + nnzAj += xa_end[jj] - xa_begin[jj]; + + if ((*info = ilu_zcolumn_dfs(m, jj, perm_r, &nseg, + &panel_lsub[k], segrep, &repfnz[k], + marker, parent, xplore, Glu))) + return; + + /* Numeric updates */ + if ((*info = zcolumn_bmod(jj, (nseg - nseg1), &dense[k], + tempv, &segrep[nseg1], &repfnz[k], + jcol, Glu, stat)) != 0) return; + + /* Make a fill-in position if the column is entirely zero */ + if (xlsub[jj + 1] == xlsub[jj]) { + register int i, row; + int nextl; + int nzlmax = Glu->nzlmax; + int *lsub = Glu->lsub; + int *marker2 = marker + 2 * m; + + /* Allocate memory */ + nextl = xlsub[jj] + 1; + if (nextl >= nzlmax) { + int error = zLUMemXpand(jj, nextl, LSUB, &nzlmax, Glu); + if (error) { *info = error; return; } + lsub = Glu->lsub; + } + xlsub[jj + 1]++; + assert(xlusup[jj]==xlusup[jj+1]); + xlusup[jj + 1]++; + ((doublecomplex *) Glu->lusup)[xlusup[jj]] = zero; + + /* Choose a row index (pivrow) for fill-in */ + for (i = jj; i < n; i++) + if (marker_relax[swap[i]] <= jj) break; + row = swap[i]; + marker2[row] = jj; + lsub[xlsub[jj]] = row; +#ifdef DEBUG + printf("Fill col %d.\n", jj); + fflush(stdout); +#endif + } + + /* Computer the quota */ + if (drop_rule & DROP_PROWS) + quota = gamma * Astore->nnz / m * jj / m; + else if (drop_rule & DROP_COLUMN) + quota = gamma * (xa_end[jj] - xa_begin[jj]) * + (jj + 1) / m; + else if (drop_rule & DROP_AREA) + quota = gamma * 0.9 * nnzAj * 0.5 - nnzUj; + else + quota = m; + + /* Copy the U-segments to ucol[*] and drop small entries */ + if ((*info = ilu_zcopy_to_ucol(jj, nseg, segrep, &repfnz[k], + perm_r, &dense[k], drop_rule, + milu, amax[jj - jcol] * tol_U, + quota, &drop_sum, &nnzUj, Glu, + dwork2)) != 0) + return; + + /* Reset the dropping threshold if required */ + if (drop_rule & DROP_DYNAMIC) { + if (gamma * 0.9 * nnzAj * 0.5 < nnzLj) + tol_U = SUPERLU_MIN(1.0, tol_U * 2.0); + else + tol_U = SUPERLU_MAX(drop_tol, tol_U * 0.5); + } + + if (drop_sum.r != 0.0 && drop_sum.i != 0.0) + { + omega = SUPERLU_MIN(2.0*(1.0-alpha)/z_abs1(&drop_sum), 1.0); + zd_mult(&drop_sum, &drop_sum, omega); + } + if (usepr) pivrow = iperm_r[jj]; + fill_tol = pow(fill_ini, 1.0 - (double)jj / (double)min_mn); + if ( (*info = ilu_zpivotL(jj, diag_pivot_thresh, &usepr, perm_r, + iperm_c[jj], swap, iswap, + marker_relax, &pivrow, + amax[jj - jcol] * fill_tol, milu, + drop_sum, Glu, stat)) ) { + iinfo++; + marker[m + pivrow] = jj; + marker[2 * m + pivrow] = jj; + } + + /* Reset repfnz[] for this column */ + resetrep_col (nseg, segrep, &repfnz[k]); + + /* Start a new supernode, drop the previous one */ + if (jj > 0 && supno[jj] > supno[jj - 1] && jj < last_drop) { + int first = xsup[supno[jj - 1]]; + int last = jj - 1; + int quota; + + /* Compute the quota */ + if (drop_rule & DROP_PROWS) + quota = gamma * Astore->nnz / m * (m - first) / m + * (last - first + 1); + else if (drop_rule & DROP_COLUMN) { + int i; + quota = 0; + for (i = first; i <= last; i++) + quota += xa_end[i] - xa_begin[i]; + quota = gamma * quota * (m - first) / m; + } else if (drop_rule & DROP_AREA) + quota = gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) + / m) - nnzLj; + else + quota = m * n; + fill_tol = pow(fill_ini, 1.0 - 0.5 * (first + last) / + (double)min_mn); + + /* Drop small rows */ + dtempv = (double *) tempv; + i = ilu_zdrop_row(options, first, last, tol_L, quota, + &nnzLj, &fill_tol, Glu, dtempv, dwork2, + 1); + + /* Reset the parameters */ + if (drop_rule & DROP_DYNAMIC) { + if (gamma * nnzAj * (1.0 - 0.5 * (last + 1.0) / m) + < nnzLj) + tol_L = SUPERLU_MIN(1.0, tol_L * 2.0); + else + tol_L = SUPERLU_MAX(drop_tol, tol_L * 0.5); + } + if (fill_tol < 0) iinfo -= (int)fill_tol; +#ifdef DEBUG + num_drop_L += i * (last - first + 1); +#endif + } /* if start a new supernode */ + + } /* for */ + + jcol += panel_size; /* Move to the next panel */ + + } /* else */ + + } /* for */ + + *info = iinfo; + + if ( m > n ) { + k = 0; + for (i = 0; i < m; ++i) + if ( perm_r[i] == EMPTY ) { + perm_r[i] = n + k; + ++k; + } + } + + ilu_countnz(min_mn, &nnzL, &nnzU, Glu); + fixupL(min_mn, perm_r, Glu); + + zLUWorkFree(iwork, zwork, Glu); /* Free work space and compress storage */ + + if ( fact == SamePattern_SameRowPerm ) { + /* L and U structures may have changed due to possibly different + pivoting, even though the storage is available. + There could also be memory expansions, so the array locations + may have changed, */ + ((SCformat *)L->Store)->nnz = nnzL; + ((SCformat *)L->Store)->nsuper = Glu->supno[n]; + ((SCformat *)L->Store)->nzval = (doublecomplex *) Glu->lusup; + ((SCformat *)L->Store)->nzval_colptr = Glu->xlusup; + ((SCformat *)L->Store)->rowind = Glu->lsub; + ((SCformat *)L->Store)->rowind_colptr = Glu->xlsub; + ((NCformat *)U->Store)->nnz = nnzU; + ((NCformat *)U->Store)->nzval = (doublecomplex *) Glu->ucol; + ((NCformat *)U->Store)->rowind = Glu->usub; + ((NCformat *)U->Store)->colptr = Glu->xusub; + } else { + zCreate_SuperNode_Matrix(L, A->nrow, min_mn, nnzL, + (doublecomplex *) Glu->lusup, Glu->xlusup, + Glu->lsub, Glu->xlsub, Glu->supno, Glu->xsup, + SLU_SC, SLU_Z, SLU_TRLU); + zCreate_CompCol_Matrix(U, min_mn, min_mn, nnzU, + (doublecomplex *) Glu->ucol, Glu->usub, Glu->xusub, + SLU_NC, SLU_Z, SLU_TRU); + } + + ops[FACT] += ops[TRSV] + ops[GEMV]; + stat->expansions = --(Glu->num_expansions); + + if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r); + SUPERLU_FREE (iperm_c); + SUPERLU_FREE (relax_end); + SUPERLU_FREE (swap); + SUPERLU_FREE (iswap); + SUPERLU_FREE (relax_fsupc); + SUPERLU_FREE (amax); + if ( dwork2 ) SUPERLU_FREE (dwork2); + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zgsrfs.c b/src/Libraries/superlu-5.2.1/SRC/zgsrfs.c new file mode 100644 index 00000000..02b63df3 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zgsrfs.c @@ -0,0 +1,475 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zgsrfs.c + * \brief Improves computed solution to a system of inear equations + * + *
+ * -- SuperLU routine (version 5.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Modified from lapack routine ZGERFS
+ * Last modified: December 3, 2015
+ * 
+ */ +/* + * File name: zgsrfs.c + * History: Modified from lapack routine ZGERFS + */ +#include +#include "slu_zdefs.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   ZGSRFS improves the computed solution to a system of linear   
+ *   equations and provides error bounds and backward error estimates for 
+ *   the solution.   
+ *
+ *   If equilibration was performed, the system becomes:
+ *           (diag(R)*A_original*diag(C)) * X = diag(R)*B_original.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ *   Arguments   
+ *   =========   
+ *
+ * trans   (input) trans_t
+ *          Specifies the form of the system of equations:
+ *          = NOTRANS: A * X = B  (No transpose)
+ *          = TRANS:   A'* X = B  (Transpose)
+ *          = CONJ:    A**H * X = B  (Conjugate transpose)
+ *   
+ *   A       (input) SuperMatrix*
+ *           The original matrix A in the system, or the scaled A if
+ *           equilibration was done. The type of A can be:
+ *           Stype = SLU_NC, Dtype = SLU_Z, Mtype = SLU_GE.
+ *    
+ *   L       (input) SuperMatrix*
+ *	     The factor L from the factorization Pr*A*Pc=L*U. Use
+ *           compressed row subscripts storage for supernodes, 
+ *           i.e., L has types: Stype = SLU_SC, Dtype = SLU_Z, Mtype = SLU_TRLU.
+ * 
+ *   U       (input) SuperMatrix*
+ *           The factor U from the factorization Pr*A*Pc=L*U as computed by
+ *           zgstrf(). Use column-wise storage scheme, 
+ *           i.e., U has types: Stype = SLU_NC, Dtype = SLU_Z, Mtype = SLU_TRU.
+ *
+ *   perm_c  (input) int*, dimension (A->ncol)
+ *	     Column permutation vector, which defines the 
+ *           permutation matrix Pc; perm_c[i] = j means column i of A is 
+ *           in position j in A*Pc.
+ *
+ *   perm_r  (input) int*, dimension (A->nrow)
+ *           Row permutation vector, which defines the permutation matrix Pr;
+ *           perm_r[i] = j means row i of A is in position j in Pr*A.
+ *
+ *   equed   (input) Specifies the form of equilibration that was done.
+ *           = 'N': No equilibration.
+ *           = 'R': Row equilibration, i.e., A was premultiplied by diag(R).
+ *           = 'C': Column equilibration, i.e., A was postmultiplied by
+ *                  diag(C).
+ *           = 'B': Both row and column equilibration, i.e., A was replaced 
+ *                  by diag(R)*A*diag(C).
+ *
+ *   R       (input) double*, dimension (A->nrow)
+ *           The row scale factors for A.
+ *           If equed = 'R' or 'B', A is premultiplied by diag(R).
+ *           If equed = 'N' or 'C', R is not accessed.
+ * 
+ *   C       (input) double*, dimension (A->ncol)
+ *           The column scale factors for A.
+ *           If equed = 'C' or 'B', A is postmultiplied by diag(C).
+ *           If equed = 'N' or 'R', C is not accessed.
+ *
+ *   B       (input) SuperMatrix*
+ *           B has types: Stype = SLU_DN, Dtype = SLU_Z, Mtype = SLU_GE.
+ *           The right hand side matrix B.
+ *           if equed = 'R' or 'B', B is premultiplied by diag(R).
+ *
+ *   X       (input/output) SuperMatrix*
+ *           X has types: Stype = SLU_DN, Dtype = SLU_Z, Mtype = SLU_GE.
+ *           On entry, the solution matrix X, as computed by zgstrs().
+ *           On exit, the improved solution matrix X.
+ *           if *equed = 'C' or 'B', X should be premultiplied by diag(C)
+ *               in order to obtain the solution to the original system.
+ *
+ *   FERR    (output) double*, dimension (B->ncol)   
+ *           The estimated forward error bound for each solution vector   
+ *           X(j) (the j-th column of the solution matrix X).   
+ *           If XTRUE is the true solution corresponding to X(j), FERR(j) 
+ *           is an estimated upper bound for the magnitude of the largest 
+ *           element in (X(j) - XTRUE) divided by the magnitude of the   
+ *           largest element in X(j).  The estimate is as reliable as   
+ *           the estimate for RCOND, and is almost always a slight   
+ *           overestimate of the true error.
+ *
+ *   BERR    (output) double*, dimension (B->ncol)   
+ *           The componentwise relative backward error of each solution   
+ *           vector X(j) (i.e., the smallest relative change in   
+ *           any element of A or B that makes X(j) an exact solution).
+ *
+ *   stat     (output) SuperLUStat_t*
+ *            Record the statistics on runtime and floating-point operation count.
+ *            See util.h for the definition of 'SuperLUStat_t'.
+ *
+ *   info    (output) int*   
+ *           = 0:  successful exit   
+ *            < 0:  if INFO = -i, the i-th argument had an illegal value   
+ *
+ *    Internal Parameters   
+ *    ===================   
+ *
+ *    ITMAX is the maximum number of steps of iterative refinement.   
+ *
+ * 
+ */ +void +zgsrfs(trans_t trans, SuperMatrix *A, SuperMatrix *L, SuperMatrix *U, + int *perm_c, int *perm_r, char *equed, double *R, double *C, + SuperMatrix *B, SuperMatrix *X, double *ferr, double *berr, + SuperLUStat_t *stat, int *info) +{ + + +#define ITMAX 5 + + /* Table of constant values */ + int ione = 1; + doublecomplex ndone = {-1., 0.}; + doublecomplex done = {1., 0.}; + + /* Local variables */ + NCformat *Astore; + doublecomplex *Aval; + SuperMatrix Bjcol; + DNformat *Bstore, *Xstore, *Bjcol_store; + doublecomplex *Bmat, *Xmat, *Bptr, *Xptr; + int kase; + double safe1, safe2; + int i, j, k, irow, nz, count, notran, rowequ, colequ; + int ldb, ldx, nrhs; + double s, xk, lstres, eps, safmin; + char transc[1]; + trans_t transt; + doublecomplex *work; + double *rwork; + int *iwork; + int isave[3]; + + extern int zlacon2_(int *, doublecomplex *, doublecomplex *, double *, int *, int []); +#ifdef _CRAY + extern int CCOPY(int *, doublecomplex *, int *, doublecomplex *, int *); + extern int CSAXPY(int *, doublecomplex *, doublecomplex *, int *, doublecomplex *, int *); +#else + extern int zcopy_(int *, doublecomplex *, int *, doublecomplex *, int *); + extern int zaxpy_(int *, doublecomplex *, doublecomplex *, int *, doublecomplex *, int *); +#endif + + Astore = A->Store; + Aval = Astore->nzval; + Bstore = B->Store; + Xstore = X->Store; + Bmat = Bstore->nzval; + Xmat = Xstore->nzval; + ldb = Bstore->lda; + ldx = Xstore->lda; + nrhs = B->ncol; + + /* Test the input parameters */ + *info = 0; + notran = (trans == NOTRANS); + if ( !notran && trans != TRANS && trans != CONJ ) *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + A->Stype != SLU_NC || A->Dtype != SLU_Z || A->Mtype != SLU_GE ) + *info = -2; + else if ( L->nrow != L->ncol || L->nrow < 0 || + L->Stype != SLU_SC || L->Dtype != SLU_Z || L->Mtype != SLU_TRLU ) + *info = -3; + else if ( U->nrow != U->ncol || U->nrow < 0 || + U->Stype != SLU_NC || U->Dtype != SLU_Z || U->Mtype != SLU_TRU ) + *info = -4; + else if ( ldb < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_Z || B->Mtype != SLU_GE ) + *info = -10; + else if ( ldx < SUPERLU_MAX(0, A->nrow) || + X->Stype != SLU_DN || X->Dtype != SLU_Z || X->Mtype != SLU_GE ) + *info = -11; + if (*info != 0) { + i = -(*info); + input_error("zgsrfs", &i); + return; + } + + /* Quick return if possible */ + if ( A->nrow == 0 || nrhs == 0) { + for (j = 0; j < nrhs; ++j) { + ferr[j] = 0.; + berr[j] = 0.; + } + return; + } + + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + + /* Allocate working space */ + work = doublecomplexMalloc(2*A->nrow); + rwork = (double *) SUPERLU_MALLOC( A->nrow * sizeof(double) ); + iwork = intMalloc(A->nrow); + if ( !work || !rwork || !iwork ) + ABORT("Malloc fails for work/rwork/iwork."); + + if ( notran ) { + *(unsigned char *)transc = 'N'; + transt = TRANS; + } else if ( trans == TRANS ) { + *(unsigned char *)transc = 'T'; + transt = NOTRANS; + } else if ( trans == CONJ ) { + *(unsigned char *)transc = 'C'; + transt = NOTRANS; + } + + /* NZ = maximum number of nonzero elements in each row of A, plus 1 */ + nz = A->ncol + 1; + eps = dmach("Epsilon"); + safmin = dmach("Safe minimum"); + + /* Set SAFE1 essentially to be the underflow threshold times the + number of additions in each row. */ + safe1 = nz * safmin; + safe2 = safe1 / eps; + + /* Compute the number of nonzeros in each row (or column) of A */ + for (i = 0; i < A->nrow; ++i) iwork[i] = 0; + if ( notran ) { + for (k = 0; k < A->ncol; ++k) + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) + ++iwork[Astore->rowind[i]]; + } else { + for (k = 0; k < A->ncol; ++k) + iwork[k] = Astore->colptr[k+1] - Astore->colptr[k]; + } + + /* Copy one column of RHS B into Bjcol. */ + Bjcol.Stype = B->Stype; + Bjcol.Dtype = B->Dtype; + Bjcol.Mtype = B->Mtype; + Bjcol.nrow = B->nrow; + Bjcol.ncol = 1; + Bjcol.Store = (void *) SUPERLU_MALLOC( sizeof(DNformat) ); + if ( !Bjcol.Store ) ABORT("SUPERLU_MALLOC fails for Bjcol.Store"); + Bjcol_store = Bjcol.Store; + Bjcol_store->lda = ldb; + Bjcol_store->nzval = work; /* address aliasing */ + + /* Do for each right hand side ... */ + for (j = 0; j < nrhs; ++j) { + count = 0; + lstres = 3.; + Bptr = &Bmat[j*ldb]; + Xptr = &Xmat[j*ldx]; + + while (1) { /* Loop until stopping criterion is satisfied. */ + + /* Compute residual R = B - op(A) * X, + where op(A) = A, A**T, or A**H, depending on TRANS. */ + +#ifdef _CRAY + CCOPY(&A->nrow, Bptr, &ione, work, &ione); +#else + zcopy_(&A->nrow, Bptr, &ione, work, &ione); +#endif + sp_zgemv(transc, ndone, A, Xptr, ione, done, work, ione); + + /* Compute componentwise relative backward error from formula + max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) ) + where abs(Z) is the componentwise absolute value of the matrix + or vector Z. If the i-th component of the denominator is less + than SAFE2, then SAFE1 is added to the i-th component of the + numerator before dividing. */ + + for (i = 0; i < A->nrow; ++i) rwork[i] = z_abs1( &Bptr[i] ); + + /* Compute abs(op(A))*abs(X) + abs(B). */ + if ( notran ) { + for (k = 0; k < A->ncol; ++k) { + xk = z_abs1( &Xptr[k] ); + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) + rwork[Astore->rowind[i]] += z_abs1(&Aval[i]) * xk; + } + } else { /* trans = TRANS or CONJ */ + for (k = 0; k < A->ncol; ++k) { + s = 0.; + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) { + irow = Astore->rowind[i]; + s += z_abs1(&Aval[i]) * z_abs1(&Xptr[irow]); + } + rwork[k] += s; + } + } + s = 0.; + for (i = 0; i < A->nrow; ++i) { + if (rwork[i] > safe2) { + s = SUPERLU_MAX( s, z_abs1(&work[i]) / rwork[i] ); + } else if ( rwork[i] != 0.0 ) { + s = SUPERLU_MAX( s, (z_abs1(&work[i]) + safe1) / rwork[i] ); + } + /* If rwork[i] is exactly 0.0, then we know the true + residual also must be exactly 0.0. */ + } + berr[j] = s; + + /* Test stopping criterion. Continue iterating if + 1) The residual BERR(J) is larger than machine epsilon, and + 2) BERR(J) decreased by at least a factor of 2 during the + last iteration, and + 3) At most ITMAX iterations tried. */ + + if (berr[j] > eps && berr[j] * 2. <= lstres && count < ITMAX) { + /* Update solution and try again. */ + zgstrs (trans, L, U, perm_c, perm_r, &Bjcol, stat, info); + +#ifdef _CRAY + CAXPY(&A->nrow, &done, work, &ione, + &Xmat[j*ldx], &ione); +#else + zaxpy_(&A->nrow, &done, work, &ione, + &Xmat[j*ldx], &ione); +#endif + lstres = berr[j]; + ++count; + } else { + break; + } + + } /* end while */ + + stat->RefineSteps = count; + + /* Bound error from formula: + norm(X - XTRUE) / norm(X) .le. FERR = norm( abs(inv(op(A)))* + ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X) + where + norm(Z) is the magnitude of the largest component of Z + inv(op(A)) is the inverse of op(A) + abs(Z) is the componentwise absolute value of the matrix or + vector Z + NZ is the maximum number of nonzeros in any row of A, plus 1 + EPS is machine epsilon + + The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B)) + is incremented by SAFE1 if the i-th component of + abs(op(A))*abs(X) + abs(B) is less than SAFE2. + + Use ZLACON2 to estimate the infinity-norm of the matrix + inv(op(A)) * diag(W), + where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) */ + + for (i = 0; i < A->nrow; ++i) rwork[i] = z_abs1( &Bptr[i] ); + + /* Compute abs(op(A))*abs(X) + abs(B). */ + if ( notran ) { + for (k = 0; k < A->ncol; ++k) { + xk = z_abs1( &Xptr[k] ); + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) + rwork[Astore->rowind[i]] += z_abs1(&Aval[i]) * xk; + } + } else { /* trans == TRANS or CONJ */ + for (k = 0; k < A->ncol; ++k) { + s = 0.; + for (i = Astore->colptr[k]; i < Astore->colptr[k+1]; ++i) { + irow = Astore->rowind[i]; + xk = z_abs1( &Xptr[irow] ); + s += z_abs1(&Aval[i]) * xk; + } + rwork[k] += s; + } + } + + for (i = 0; i < A->nrow; ++i) + if (rwork[i] > safe2) + rwork[i] = z_abs(&work[i]) + (iwork[i]+1)*eps*rwork[i]; + else + rwork[i] = z_abs(&work[i])+(iwork[i]+1)*eps*rwork[i]+safe1; + kase = 0; + + do { + zlacon2_(&A->nrow, &work[A->nrow], work, &ferr[j], &kase, isave); + if (kase == 0) break; + + if (kase == 1) { + /* Multiply by diag(W)*inv(op(A)**T)*(diag(C) or diag(R)). */ + if ( notran && colequ ) + for (i = 0; i < A->ncol; ++i) { + zd_mult(&work[i], &work[i], C[i]); + } + else if ( !notran && rowequ ) + for (i = 0; i < A->nrow; ++i) { + zd_mult(&work[i], &work[i], R[i]); + } + + zgstrs (transt, L, U, perm_c, perm_r, &Bjcol, stat, info); + + for (i = 0; i < A->nrow; ++i) { + zd_mult(&work[i], &work[i], rwork[i]); + } + } else { + /* Multiply by (diag(C) or diag(R))*inv(op(A))*diag(W). */ + for (i = 0; i < A->nrow; ++i) { + zd_mult(&work[i], &work[i], rwork[i]); + } + + zgstrs (trans, L, U, perm_c, perm_r, &Bjcol, stat, info); + + if ( notran && colequ ) + for (i = 0; i < A->ncol; ++i) { + zd_mult(&work[i], &work[i], C[i]); + } + else if ( !notran && rowequ ) + for (i = 0; i < A->ncol; ++i) { + zd_mult(&work[i], &work[i], R[i]); + } + } + + } while ( kase != 0 ); + + /* Normalize error. */ + lstres = 0.; + if ( notran && colequ ) { + for (i = 0; i < A->nrow; ++i) + lstres = SUPERLU_MAX( lstres, C[i] * z_abs1( &Xptr[i]) ); + } else if ( !notran && rowequ ) { + for (i = 0; i < A->nrow; ++i) + lstres = SUPERLU_MAX( lstres, R[i] * z_abs1( &Xptr[i]) ); + } else { + for (i = 0; i < A->nrow; ++i) + lstres = SUPERLU_MAX( lstres, z_abs1( &Xptr[i]) ); + } + if ( lstres != 0. ) + ferr[j] /= lstres; + + } /* for each RHS j ... */ + + SUPERLU_FREE(work); + SUPERLU_FREE(rwork); + SUPERLU_FREE(iwork); + SUPERLU_FREE(Bjcol.Store); + + return; + +} /* zgsrfs */ diff --git a/src/Libraries/superlu-5.2.1/SRC/zgssv.c b/src/Libraries/superlu-5.2.1/SRC/zgssv.c new file mode 100644 index 00000000..b364c286 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zgssv.c @@ -0,0 +1,238 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zgssv.c + * \brief Solves the system of linear equations A*X=B + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ * 
+ */ +#include "slu_zdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * ZGSSV solves the system of linear equations A*X=B, using the
+ * LU factorization from ZGSTRF. It performs the following steps:
+ *
+ *   1. If A is stored column-wise (A->Stype = SLU_NC):
+ *
+ *      1.1. Permute the columns of A, forming A*Pc, where Pc
+ *           is a permutation matrix. For more details of this step, 
+ *           see sp_preorder.c.
+ *
+ *      1.2. Factor A as Pr*A*Pc=L*U with the permutation Pr determined
+ *           by Gaussian elimination with partial pivoting.
+ *           L is unit lower triangular with offdiagonal entries
+ *           bounded by 1 in magnitude, and U is upper triangular.
+ *
+ *      1.3. Solve the system of equations A*X=B using the factored
+ *           form of A.
+ *
+ *   2. If A is stored row-wise (A->Stype = SLU_NR), apply the
+ *      above algorithm to the transpose of A:
+ *
+ *      2.1. Permute columns of transpose(A) (rows of A),
+ *           forming transpose(A)*Pc, where Pc is a permutation matrix. 
+ *           For more details of this step, see sp_preorder.c.
+ *
+ *      2.2. Factor A as Pr*transpose(A)*Pc=L*U with the permutation Pr
+ *           determined by Gaussian elimination with partial pivoting.
+ *           L is unit lower triangular with offdiagonal entries
+ *           bounded by 1 in magnitude, and U is upper triangular.
+ *
+ *      2.3. Solve the system of equations A*X=B using the factored
+ *           form of A.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ * 
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *         The structure defines the input parameters to control
+ *         how the LU decomposition will be performed and how the
+ *         system will be solved.
+ *
+ * A       (input) SuperMatrix*
+ *         Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
+ *         of linear equations is A->nrow. Currently, the type of A can be:
+ *         Stype = SLU_NC or SLU_NR; Dtype = SLU_Z; Mtype = SLU_GE.
+ *         In the future, more general A may be handled.
+ *
+ * perm_c  (input/output) int*
+ *         If A->Stype = SLU_NC, column permutation vector of size A->ncol
+ *         which defines the permutation matrix Pc; perm_c[i] = j means 
+ *         column i of A is in position j in A*Pc.
+ *         If A->Stype = SLU_NR, column permutation vector of size A->nrow
+ *         which describes permutation of columns of transpose(A) 
+ *         (rows of A) as described above.
+ * 
+ *         If options->ColPerm = MY_PERMC or options->Fact = SamePattern or
+ *            options->Fact = SamePattern_SameRowPerm, it is an input argument.
+ *            On exit, perm_c may be overwritten by the product of the input
+ *            perm_c and a permutation that postorders the elimination tree
+ *            of Pc'*A'*A*Pc; perm_c is not changed if the elimination tree
+ *            is already in postorder.
+ *         Otherwise, it is an output argument.
+ * 
+ * perm_r  (input/output) int*
+ *         If A->Stype = SLU_NC, row permutation vector of size A->nrow, 
+ *         which defines the permutation matrix Pr, and is determined 
+ *         by partial pivoting.  perm_r[i] = j means row i of A is in 
+ *         position j in Pr*A.
+ *         If A->Stype = SLU_NR, permutation vector of size A->ncol, which
+ *         determines permutation of rows of transpose(A)
+ *         (columns of A) as described above.
+ *
+ *         If options->RowPerm = MY_PERMR or
+ *            options->Fact = SamePattern_SameRowPerm, perm_r is an
+ *            input argument.
+ *         otherwise it is an output argument.
+ *
+ * L       (output) SuperMatrix*
+ *         The factor L from the factorization 
+ *             Pr*A*Pc=L*U              (if A->Stype = SLU_NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses compressed row subscripts storage for supernodes, i.e.,
+ *         L has types: Stype = SLU_SC, Dtype = SLU_Z, Mtype = SLU_TRLU.
+ *         
+ * U       (output) SuperMatrix*
+ *	   The factor U from the factorization 
+ *             Pr*A*Pc=L*U              (if A->Stype = SLU_NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses column-wise storage scheme, i.e., U has types:
+ *         Stype = SLU_NC, Dtype = SLU_Z, Mtype = SLU_TRU.
+ *
+ * B       (input/output) SuperMatrix*
+ *         B has types: Stype = SLU_DN, Dtype = SLU_Z, Mtype = SLU_GE.
+ *         On entry, the right hand side matrix.
+ *         On exit, the solution matrix if info = 0;
+ *
+ * stat   (output) SuperLUStat_t*
+ *        Record the statistics on runtime and floating-point operation count.
+ *        See util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ *	   = 0: successful exit
+ *         > 0: if info = i, and i is
+ *             <= A->ncol: U(i,i) is exactly zero. The factorization has
+ *                been completed, but the factor U is exactly singular,
+ *                so the solution could not be computed.
+ *             > A->ncol: number of bytes allocated when memory allocation
+ *                failure occurred, plus A->ncol.
+ * 
+ */ + +void +zgssv(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, + SuperMatrix *L, SuperMatrix *U, SuperMatrix *B, + SuperLUStat_t *stat, int *info ) +{ + + DNformat *Bstore; + SuperMatrix *AA;/* A in SLU_NC format used by the factorization routine.*/ + SuperMatrix AC; /* Matrix postmultiplied by Pc */ + int lwork = 0, *etree, i; + GlobalLU_t Glu; /* Not needed on return. */ + + /* Set default values for some parameters */ + int panel_size; /* panel size */ + int relax; /* no of columns in a relaxed snodes */ + int permc_spec; + trans_t trans = NOTRANS; + double *utime; + double t; /* Temporary time */ + + /* Test the input parameters ... */ + *info = 0; + Bstore = B->Store; + if ( options->Fact != DOFACT ) *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + (A->Stype != SLU_NC && A->Stype != SLU_NR) || + A->Dtype != SLU_Z || A->Mtype != SLU_GE ) + *info = -2; + else if ( B->ncol < 0 || Bstore->lda < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_Z || B->Mtype != SLU_GE ) + *info = -7; + if ( *info != 0 ) { + i = -(*info); + input_error("zgssv", &i); + return; + } + + utime = stat->utime; + + /* Convert A to SLU_NC format when necessary. */ + if ( A->Stype == SLU_NR ) { + NRformat *Astore = A->Store; + AA = (SuperMatrix *) SUPERLU_MALLOC( sizeof(SuperMatrix) ); + zCreate_CompCol_Matrix(AA, A->ncol, A->nrow, Astore->nnz, + Astore->nzval, Astore->colind, Astore->rowptr, + SLU_NC, A->Dtype, A->Mtype); + trans = TRANS; + } else { + if ( A->Stype == SLU_NC ) AA = A; + } + + t = SuperLU_timer_(); + /* + * Get column permutation vector perm_c[], according to permc_spec: + * permc_spec = NATURAL: natural ordering + * permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A + * permc_spec = MMD_ATA: minimum degree on structure of A'*A + * permc_spec = COLAMD: approximate minimum degree column ordering + * permc_spec = MY_PERMC: the ordering already supplied in perm_c[] + */ + permc_spec = options->ColPerm; + if ( permc_spec != MY_PERMC && options->Fact == DOFACT ) + get_perm_c(permc_spec, AA, perm_c); + utime[COLPERM] = SuperLU_timer_() - t; + + etree = intMalloc(A->ncol); + + t = SuperLU_timer_(); + sp_preorder(options, AA, perm_c, etree, &AC); + utime[ETREE] = SuperLU_timer_() - t; + + panel_size = sp_ienv(1); + relax = sp_ienv(2); + + /*printf("Factor PA = LU ... relax %d\tw %d\tmaxsuper %d\trowblk %d\n", + relax, panel_size, sp_ienv(3), sp_ienv(4));*/ + t = SuperLU_timer_(); + /* Compute the LU factorization of A. */ + zgstrf(options, &AC, relax, panel_size, etree, + NULL, lwork, perm_c, perm_r, L, U, &Glu, stat, info); + utime[FACT] = SuperLU_timer_() - t; + + t = SuperLU_timer_(); + if ( *info == 0 ) { + /* Solve the system A*X=B, overwriting B with X. */ + zgstrs (trans, L, U, perm_c, perm_r, B, stat, info); + } + utime[SOLVE] = SuperLU_timer_() - t; + + SUPERLU_FREE (etree); + Destroy_CompCol_Permuted(&AC); + if ( A->Stype == SLU_NR ) { + Destroy_SuperMatrix_Store(AA); + SUPERLU_FREE(AA); + } + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zgssvx.c b/src/Libraries/superlu-5.2.1/SRC/zgssvx.c new file mode 100644 index 00000000..b95b57f2 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zgssvx.c @@ -0,0 +1,646 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zgssvx.c + * \brief Solves the system of linear equations A*X=B or A'*X=B + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ * 
+ */ +#include "slu_zdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * ZGSSVX solves the system of linear equations A*X=B or A'*X=B, using
+ * the LU factorization from zgstrf(). Error bounds on the solution and
+ * a condition estimate are also provided. It performs the following steps:
+ *
+ *   1. If A is stored column-wise (A->Stype = SLU_NC):
+ *  
+ *      1.1. If options->Equil = YES, scaling factors are computed to
+ *           equilibrate the system:
+ *           options->Trans = NOTRANS:
+ *               diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *           options->Trans = TRANS:
+ *               (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *           options->Trans = CONJ:
+ *               (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *           Whether or not the system will be equilibrated depends on the
+ *           scaling of the matrix A, but if equilibration is used, A is
+ *           overwritten by diag(R)*A*diag(C) and B by diag(R)*B
+ *           (if options->Trans=NOTRANS) or diag(C)*B (if options->Trans
+ *           = TRANS or CONJ).
+ *
+ *      1.2. Permute columns of A, forming A*Pc, where Pc is a permutation
+ *           matrix that usually preserves sparsity.
+ *           For more details of this step, see sp_preorder.c.
+ *
+ *      1.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *           factor the matrix A (after equilibration if options->Equil = YES)
+ *           as Pr*A*Pc = L*U, with Pr determined by partial pivoting.
+ *
+ *      1.4. Compute the reciprocal pivot growth factor.
+ *
+ *      1.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *           routine returns with info = i. Otherwise, the factored form of 
+ *           A is used to estimate the condition number of the matrix A. If
+ *           the reciprocal of the condition number is less than machine
+ *           precision, info = A->ncol+1 is returned as a warning, but the
+ *           routine still goes on to solve for X and computes error bounds
+ *           as described below.
+ *
+ *      1.6. The system of equations is solved for X using the factored form
+ *           of A.
+ *
+ *      1.7. If options->IterRefine != NOREFINE, iterative refinement is
+ *           applied to improve the computed solution matrix and calculate
+ *           error bounds and backward error estimates for it.
+ *
+ *      1.8. If equilibration was used, the matrix X is premultiplied by
+ *           diag(C) (if options->Trans = NOTRANS) or diag(R)
+ *           (if options->Trans = TRANS or CONJ) so that it solves the
+ *           original system before equilibration.
+ *
+ *   2. If A is stored row-wise (A->Stype = SLU_NR), apply the above algorithm
+ *      to the transpose of A:
+ *
+ *      2.1. If options->Equil = YES, scaling factors are computed to
+ *           equilibrate the system:
+ *           options->Trans = NOTRANS:
+ *               diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B
+ *           options->Trans = TRANS:
+ *               (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
+ *           options->Trans = CONJ:
+ *               (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
+ *           Whether or not the system will be equilibrated depends on the
+ *           scaling of the matrix A, but if equilibration is used, A' is
+ *           overwritten by diag(R)*A'*diag(C) and B by diag(R)*B 
+ *           (if trans='N') or diag(C)*B (if trans = 'T' or 'C').
+ *
+ *      2.2. Permute columns of transpose(A) (rows of A), 
+ *           forming transpose(A)*Pc, where Pc is a permutation matrix that 
+ *           usually preserves sparsity.
+ *           For more details of this step, see sp_preorder.c.
+ *
+ *      2.3. If options->Fact != FACTORED, the LU decomposition is used to
+ *           factor the transpose(A) (after equilibration if 
+ *           options->Fact = YES) as Pr*transpose(A)*Pc = L*U with the
+ *           permutation Pr determined by partial pivoting.
+ *
+ *      2.4. Compute the reciprocal pivot growth factor.
+ *
+ *      2.5. If some U(i,i) = 0, so that U is exactly singular, then the
+ *           routine returns with info = i. Otherwise, the factored form 
+ *           of transpose(A) is used to estimate the condition number of the
+ *           matrix A. If the reciprocal of the condition number
+ *           is less than machine precision, info = A->nrow+1 is returned as
+ *           a warning, but the routine still goes on to solve for X and
+ *           computes error bounds as described below.
+ *
+ *      2.6. The system of equations is solved for X using the factored form
+ *           of transpose(A).
+ *
+ *      2.7. If options->IterRefine != NOREFINE, iterative refinement is
+ *           applied to improve the computed solution matrix and calculate
+ *           error bounds and backward error estimates for it.
+ *
+ *      2.8. If equilibration was used, the matrix X is premultiplied by
+ *           diag(C) (if options->Trans = NOTRANS) or diag(R) 
+ *           (if options->Trans = TRANS or CONJ) so that it solves the
+ *           original system before equilibration.
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *         The structure defines the input parameters to control
+ *         how the LU decomposition will be performed and how the
+ *         system will be solved.
+ *
+ * A       (input/output) SuperMatrix*
+ *         Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
+ *         of the linear equations is A->nrow. Currently, the type of A can be:
+ *         Stype = SLU_NC or SLU_NR, Dtype = SLU_D, Mtype = SLU_GE.
+ *         In the future, more general A may be handled.
+ *
+ *         On entry, If options->Fact = FACTORED and equed is not 'N', 
+ *         then A must have been equilibrated by the scaling factors in
+ *         R and/or C.  
+ *         On exit, A is not modified if options->Equil = NO, or if 
+ *         options->Equil = YES but equed = 'N' on exit.
+ *         Otherwise, if options->Equil = YES and equed is not 'N',
+ *         A is scaled as follows:
+ *         If A->Stype = SLU_NC:
+ *           equed = 'R':  A := diag(R) * A
+ *           equed = 'C':  A := A * diag(C)
+ *           equed = 'B':  A := diag(R) * A * diag(C).
+ *         If A->Stype = SLU_NR:
+ *           equed = 'R':  transpose(A) := diag(R) * transpose(A)
+ *           equed = 'C':  transpose(A) := transpose(A) * diag(C)
+ *           equed = 'B':  transpose(A) := diag(R) * transpose(A) * diag(C).
+ *
+ * perm_c  (input/output) int*
+ *	   If A->Stype = SLU_NC, Column permutation vector of size A->ncol,
+ *         which defines the permutation matrix Pc; perm_c[i] = j means
+ *         column i of A is in position j in A*Pc.
+ *         On exit, perm_c may be overwritten by the product of the input
+ *         perm_c and a permutation that postorders the elimination tree
+ *         of Pc'*A'*A*Pc; perm_c is not changed if the elimination tree
+ *         is already in postorder.
+ *
+ *         If A->Stype = SLU_NR, column permutation vector of size A->nrow,
+ *         which describes permutation of columns of transpose(A) 
+ *         (rows of A) as described above.
+ * 
+ * perm_r  (input/output) int*
+ *         If A->Stype = SLU_NC, row permutation vector of size A->nrow, 
+ *         which defines the permutation matrix Pr, and is determined
+ *         by partial pivoting.  perm_r[i] = j means row i of A is in 
+ *         position j in Pr*A.
+ *
+ *         If A->Stype = SLU_NR, permutation vector of size A->ncol, which
+ *         determines permutation of rows of transpose(A)
+ *         (columns of A) as described above.
+ *
+ *         If options->Fact = SamePattern_SameRowPerm, the pivoting routine
+ *         will try to use the input perm_r, unless a certain threshold
+ *         criterion is violated. In that case, perm_r is overwritten by a
+ *         new permutation determined by partial pivoting or diagonal
+ *         threshold pivoting.
+ *         Otherwise, perm_r is output argument.
+ * 
+ * etree   (input/output) int*,  dimension (A->ncol)
+ *         Elimination tree of Pc'*A'*A*Pc.
+ *         If options->Fact != FACTORED and options->Fact != DOFACT,
+ *         etree is an input argument, otherwise it is an output argument.
+ *         Note: etree is a vector of parent pointers for a forest whose
+ *         vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *
+ * equed   (input/output) char*
+ *         Specifies the form of equilibration that was done.
+ *         = 'N': No equilibration.
+ *         = 'R': Row equilibration, i.e., A was premultiplied by diag(R).
+ *         = 'C': Column equilibration, i.e., A was postmultiplied by diag(C).
+ *         = 'B': Both row and column equilibration, i.e., A was replaced 
+ *                by diag(R)*A*diag(C).
+ *         If options->Fact = FACTORED, equed is an input argument,
+ *         otherwise it is an output argument.
+ *
+ * R       (input/output) double*, dimension (A->nrow)
+ *         The row scale factors for A or transpose(A).
+ *         If equed = 'R' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *             (if A->Stype = SLU_NR) is multiplied on the left by diag(R).
+ *         If equed = 'N' or 'C', R is not accessed.
+ *         If options->Fact = FACTORED, R is an input argument,
+ *             otherwise, R is output.
+ *         If options->zFact = FACTORED and equed = 'R' or 'B', each element
+ *             of R must be positive.
+ * 
+ * C       (input/output) double*, dimension (A->ncol)
+ *         The column scale factors for A or transpose(A).
+ *         If equed = 'C' or 'B', A (if A->Stype = SLU_NC) or transpose(A)
+ *             (if A->Stype = SLU_NR) is multiplied on the right by diag(C).
+ *         If equed = 'N' or 'R', C is not accessed.
+ *         If options->Fact = FACTORED, C is an input argument,
+ *             otherwise, C is output.
+ *         If options->Fact = FACTORED and equed = 'C' or 'B', each element
+ *             of C must be positive.
+ *         
+ * L       (output) SuperMatrix*
+ *	   The factor L from the factorization
+ *             Pr*A*Pc=L*U              (if A->Stype SLU_= NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses compressed row subscripts storage for supernodes, i.e.,
+ *         L has types: Stype = SLU_SC, Dtype = SLU_Z, Mtype = SLU_TRLU.
+ *
+ * U       (output) SuperMatrix*
+ *	   The factor U from the factorization
+ *             Pr*A*Pc=L*U              (if A->Stype = SLU_NC) or
+ *             Pr*transpose(A)*Pc=L*U   (if A->Stype = SLU_NR).
+ *         Uses column-wise storage scheme, i.e., U has types:
+ *         Stype = SLU_NC, Dtype = SLU_Z, Mtype = SLU_TRU.
+ *
+ * work    (workspace/output) void*, size (lwork) (in bytes)
+ *         User supplied workspace, should be large enough
+ *         to hold data structures for factors L and U.
+ *         On exit, if fact is not 'F', L and U point to this array.
+ *
+ * lwork   (input) int
+ *         Specifies the size of work array in bytes.
+ *         = 0:  allocate space internally by system malloc;
+ *         > 0:  use user-supplied work array of length lwork in bytes,
+ *               returns error if space runs out.
+ *         = -1: the routine guesses the amount of space needed without
+ *               performing the factorization, and returns it in
+ *               mem_usage->total_needed; no other side effects.
+ *
+ *         See argument 'mem_usage' for memory usage statistics.
+ *
+ * B       (input/output) SuperMatrix*
+ *         B has types: Stype = SLU_DN, Dtype = SLU_Z, Mtype = SLU_GE.
+ *         On entry, the right hand side matrix.
+ *         If B->ncol = 0, only LU decomposition is performed, the triangular
+ *                         solve is skipped.
+ *         On exit,
+ *            if equed = 'N', B is not modified; otherwise
+ *            if A->Stype = SLU_NC:
+ *               if options->Trans = NOTRANS and equed = 'R' or 'B',
+ *                  B is overwritten by diag(R)*B;
+ *               if options->Trans = TRANS or CONJ and equed = 'C' of 'B',
+ *                  B is overwritten by diag(C)*B;
+ *            if A->Stype = SLU_NR:
+ *               if options->Trans = NOTRANS and equed = 'C' or 'B',
+ *                  B is overwritten by diag(C)*B;
+ *               if options->Trans = TRANS or CONJ and equed = 'R' of 'B',
+ *                  B is overwritten by diag(R)*B.
+ *
+ * X       (output) SuperMatrix*
+ *         X has types: Stype = SLU_DN, Dtype = SLU_Z, Mtype = SLU_GE. 
+ *         If info = 0 or info = A->ncol+1, X contains the solution matrix
+ *         to the original system of equations. Note that A and B are modified
+ *         on exit if equed is not 'N', and the solution to the equilibrated
+ *         system is inv(diag(C))*X if options->Trans = NOTRANS and
+ *         equed = 'C' or 'B', or inv(diag(R))*X if options->Trans = 'T' or 'C'
+ *         and equed = 'R' or 'B'.
+ *
+ * recip_pivot_growth (output) double*
+ *         The reciprocal pivot growth factor max_j( norm(A_j)/norm(U_j) ).
+ *         The infinity norm is used. If recip_pivot_growth is much less
+ *         than 1, the stability of the LU factorization could be poor.
+ *
+ * rcond   (output) double*
+ *         The estimate of the reciprocal condition number of the matrix A
+ *         after equilibration (if done). If rcond is less than the machine
+ *         precision (in particular, if rcond = 0), the matrix is singular
+ *         to working precision. This condition is indicated by a return
+ *         code of info > 0.
+ *
+ * FERR    (output) double*, dimension (B->ncol)   
+ *         The estimated forward error bound for each solution vector   
+ *         X(j) (the j-th column of the solution matrix X).   
+ *         If XTRUE is the true solution corresponding to X(j), FERR(j) 
+ *         is an estimated upper bound for the magnitude of the largest 
+ *         element in (X(j) - XTRUE) divided by the magnitude of the   
+ *         largest element in X(j).  The estimate is as reliable as   
+ *         the estimate for RCOND, and is almost always a slight   
+ *         overestimate of the true error.
+ *         If options->IterRefine = NOREFINE, ferr = 1.0.
+ *
+ * BERR    (output) double*, dimension (B->ncol)
+ *         The componentwise relative backward error of each solution   
+ *         vector X(j) (i.e., the smallest relative change in   
+ *         any element of A or B that makes X(j) an exact solution).
+ *         If options->IterRefine = NOREFINE, berr = 1.0.
+ *
+ * Glu      (input/output) GlobalLU_t *
+ *          If options->Fact == SamePattern_SameRowPerm, it is an input;
+ *              The matrix A will be factorized assuming that a 
+ *              factorization of a matrix with the same sparsity pattern
+ *              and similar numerical values was performed prior to this one.
+ *              Therefore, this factorization will reuse both row and column
+ *		scaling factors R and C, both row and column permutation
+ *		vectors perm_r and perm_c, and the L & U data structures
+ *		set up from the previous factorization.
+ *          Otherwise, it is an output.
+ *
+ * mem_usage (output) mem_usage_t*
+ *         Record the memory usage statistics, consisting of following fields:
+ *         - for_lu (float)
+ *           The amount of space used in bytes for L\U data structures.
+ *         - total_needed (float)
+ *           The amount of space needed in bytes to perform factorization.
+ *         - expansions (int)
+ *           The number of memory expansions during the LU factorization.
+ *
+ * stat   (output) SuperLUStat_t*
+ *        Record the statistics on runtime and floating-point operation count.
+ *        See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ *         = 0: successful exit   
+ *         < 0: if info = -i, the i-th argument had an illegal value   
+ *         > 0: if info = i, and i is   
+ *              <= A->ncol: U(i,i) is exactly zero. The factorization has   
+ *                    been completed, but the factor U is exactly   
+ *                    singular, so the solution and error bounds   
+ *                    could not be computed.   
+ *              = A->ncol+1: U is nonsingular, but RCOND is less than machine
+ *                    precision, meaning that the matrix is singular to
+ *                    working precision. Nevertheless, the solution and
+ *                    error bounds are computed because there are a number
+ *                    of situations where the computed solution can be more
+ *                    accurate than the value of RCOND would suggest.   
+ *              > A->ncol+1: number of bytes allocated when memory allocation
+ *                    failure occurred, plus A->ncol.
+ * 
+ */ + +void +zgssvx(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r, + int *etree, char *equed, double *R, double *C, + SuperMatrix *L, SuperMatrix *U, void *work, int lwork, + SuperMatrix *B, SuperMatrix *X, double *recip_pivot_growth, + double *rcond, double *ferr, double *berr, + GlobalLU_t *Glu, mem_usage_t *mem_usage, SuperLUStat_t *stat, int *info ) +{ + + + DNformat *Bstore, *Xstore; + doublecomplex *Bmat, *Xmat; + int ldb, ldx, nrhs; + SuperMatrix *AA;/* A in SLU_NC format used by the factorization routine.*/ + SuperMatrix AC; /* Matrix postmultiplied by Pc */ + int colequ, equil, nofact, notran, rowequ, permc_spec; + trans_t trant; + char norm[1]; + int i, j, info1; + double amax, anorm, bignum, smlnum, colcnd, rowcnd, rcmax, rcmin; + int relax, panel_size; + double diag_pivot_thresh; + double t0; /* temporary time */ + double *utime; + + /* External functions */ + extern double zlangs(char *, SuperMatrix *); + + Bstore = B->Store; + Xstore = X->Store; + Bmat = Bstore->nzval; + Xmat = Xstore->nzval; + ldb = Bstore->lda; + ldx = Xstore->lda; + nrhs = B->ncol; + + *info = 0; + nofact = (options->Fact != FACTORED); + equil = (options->Equil == YES); + notran = (options->Trans == NOTRANS); + if ( nofact ) { + *(unsigned char *)equed = 'N'; + rowequ = FALSE; + colequ = FALSE; + } else { + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + smlnum = dmach("Safe minimum"); /* lamch_("Safe minimum"); */ + bignum = 1. / smlnum; + } + +#if 0 +printf("dgssvx: Fact=%4d, Trans=%4d, equed=%c\n", + options->Fact, options->Trans, *equed); +#endif + + /* Test the input parameters */ + if (options->Fact != DOFACT && options->Fact != SamePattern && + options->Fact != SamePattern_SameRowPerm && + options->Fact != FACTORED && + options->Trans != NOTRANS && options->Trans != TRANS && + options->Trans != CONJ && + options->Equil != NO && options->Equil != YES) + *info = -1; + else if ( A->nrow != A->ncol || A->nrow < 0 || + (A->Stype != SLU_NC && A->Stype != SLU_NR) || + A->Dtype != SLU_Z || A->Mtype != SLU_GE ) + *info = -2; + else if ( options->Fact == FACTORED && + !(rowequ || colequ || strncmp(equed, "N", 1)==0) ) + *info = -6; + else { + if (rowequ) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, R[j]); + rcmax = SUPERLU_MAX(rcmax, R[j]); + } + if (rcmin <= 0.) *info = -7; + else if ( A->nrow > 0) + rowcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else rowcnd = 1.; + } + if (colequ && *info == 0) { + rcmin = bignum; + rcmax = 0.; + for (j = 0; j < A->nrow; ++j) { + rcmin = SUPERLU_MIN(rcmin, C[j]); + rcmax = SUPERLU_MAX(rcmax, C[j]); + } + if (rcmin <= 0.) *info = -8; + else if (A->nrow > 0) + colcnd = SUPERLU_MAX(rcmin,smlnum) / SUPERLU_MIN(rcmax,bignum); + else colcnd = 1.; + } + if (*info == 0) { + if ( lwork < -1 ) *info = -12; + else if ( B->ncol < 0 ) *info = -13; + else if ( B->ncol > 0 ) { /* no checking if B->ncol=0 */ + if ( Bstore->lda < SUPERLU_MAX(0, A->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_Z || + B->Mtype != SLU_GE ) + *info = -13; + } + if ( X->ncol < 0 ) *info = -14; + else if ( X->ncol > 0 ) { /* no checking if X->ncol=0 */ + if ( Xstore->lda < SUPERLU_MAX(0, A->nrow) || + (B->ncol != 0 && B->ncol != X->ncol) || + X->Stype != SLU_DN || + X->Dtype != SLU_Z || X->Mtype != SLU_GE ) + *info = -14; + } + } + } + if (*info != 0) { + i = -(*info); + input_error("zgssvx", &i); + return; + } + + /* Initialization for factor parameters */ + panel_size = sp_ienv(1); + relax = sp_ienv(2); + diag_pivot_thresh = options->DiagPivotThresh; + + utime = stat->utime; + + /* Convert A to SLU_NC format when necessary. */ + if ( A->Stype == SLU_NR ) { + NRformat *Astore = A->Store; + AA = (SuperMatrix *) SUPERLU_MALLOC( sizeof(SuperMatrix) ); + zCreate_CompCol_Matrix(AA, A->ncol, A->nrow, Astore->nnz, + Astore->nzval, Astore->colind, Astore->rowptr, + SLU_NC, A->Dtype, A->Mtype); + if ( notran ) { /* Reverse the transpose argument. */ + trant = TRANS; + notran = 0; + } else { + trant = NOTRANS; + notran = 1; + } + } else { /* A->Stype == SLU_NC */ + trant = options->Trans; + AA = A; + } + + if ( nofact && equil ) { + t0 = SuperLU_timer_(); + /* Compute row and column scalings to equilibrate the matrix A. */ + zgsequ(AA, R, C, &rowcnd, &colcnd, &amax, &info1); + + if ( info1 == 0 ) { + /* Equilibrate matrix A. */ + zlaqgs(AA, R, C, rowcnd, colcnd, amax, equed); + rowequ = strncmp(equed, "R", 1)==0 || strncmp(equed, "B", 1)==0; + colequ = strncmp(equed, "C", 1)==0 || strncmp(equed, "B", 1)==0; + } + utime[EQUIL] = SuperLU_timer_() - t0; + } + + + if ( nofact ) { + + t0 = SuperLU_timer_(); + /* + * Gnet column permutation vector perm_c[], according to permc_spec: + * permc_spec = NATURAL: natural ordering + * permc_spec = MMD_AT_PLUS_A: minimum degree on structure of A'+A + * permc_spec = MMD_ATA: minimum degree on structure of A'*A + * permc_spec = COLAMD: approximate minimum degree column ordering + * permc_spec = MY_PERMC: the ordering already supplied in perm_c[] + */ + permc_spec = options->ColPerm; + if ( permc_spec != MY_PERMC && options->Fact == DOFACT ) + get_perm_c(permc_spec, AA, perm_c); + utime[COLPERM] = SuperLU_timer_() - t0; + + t0 = SuperLU_timer_(); + sp_preorder(options, AA, perm_c, etree, &AC); + utime[ETREE] = SuperLU_timer_() - t0; + +/* printf("Factor PA = LU ... relax %d\tw %d\tmaxsuper %d\trowblk %d\n", + relax, panel_size, sp_ienv(3), sp_ienv(4)); + fflush(stdout); */ + + /* Compute the LU factorization of A*Pc. */ + t0 = SuperLU_timer_(); + zgstrf(options, &AC, relax, panel_size, etree, + work, lwork, perm_c, perm_r, L, U, Glu, stat, info); + utime[FACT] = SuperLU_timer_() - t0; + + if ( lwork == -1 ) { + mem_usage->total_needed = *info - A->ncol; + return; + } + } + + if ( *info > 0 ) { + if ( *info <= A->ncol ) { + /* Compute the reciprocal pivot growth factor of the leading + rank-deficient (*info) columns of A. */ + *recip_pivot_growth = zPivotGrowth(*info, AA, perm_c, L, U); + } + return; + } + + /* *info == 0 at this point. */ + + if ( options->PivotGrowth ) { + /* Compute the reciprocal pivot growth factor *recip_pivot_growth. */ + *recip_pivot_growth = zPivotGrowth(A->ncol, AA, perm_c, L, U); + } + + if ( options->ConditionNumber ) { + /* Estimate the reciprocal of the condition number of A. */ + t0 = SuperLU_timer_(); + if ( notran ) { + *(unsigned char *)norm = '1'; + } else { + *(unsigned char *)norm = 'I'; + } + anorm = zlangs(norm, AA); + zgscon(norm, L, U, anorm, rcond, stat, &info1); + utime[RCOND] = SuperLU_timer_() - t0; + } + + if ( nrhs > 0 ) { + /* Scale the right hand side if equilibration was performed. */ + if ( notran ) { + if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + zd_mult(&Bmat[i+j*ldb], &Bmat[i+j*ldb], R[i]); + } + } else if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + zd_mult(&Bmat[i+j*ldb], &Bmat[i+j*ldb], C[i]); + } + + /* Compute the solution matrix X. */ + for (j = 0; j < nrhs; j++) /* Save a copy of the right hand sides */ + for (i = 0; i < B->nrow; i++) + Xmat[i + j*ldx] = Bmat[i + j*ldb]; + + t0 = SuperLU_timer_(); + zgstrs (trant, L, U, perm_c, perm_r, X, stat, &info1); + utime[SOLVE] = SuperLU_timer_() - t0; + + /* Use iterative refinement to improve the computed solution and compute + error bounds and backward error estimates for it. */ + t0 = SuperLU_timer_(); + if ( options->IterRefine != NOREFINE ) { + zgsrfs(trant, AA, L, U, perm_c, perm_r, equed, R, C, B, + X, ferr, berr, stat, &info1); + } else { + for (j = 0; j < nrhs; ++j) ferr[j] = berr[j] = 1.0; + } + utime[REFINE] = SuperLU_timer_() - t0; + + /* Transform the solution matrix X to a solution of the original system. */ + if ( notran ) { + if ( colequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + zd_mult(&Xmat[i+j*ldx], &Xmat[i+j*ldx], C[i]); + } + } else if ( rowequ ) { + for (j = 0; j < nrhs; ++j) + for (i = 0; i < A->nrow; ++i) + zd_mult(&Xmat[i+j*ldx], &Xmat[i+j*ldx], R[i]); + } + } /* end if nrhs > 0 */ + + if ( options->ConditionNumber ) { + /* Set INFO = A->ncol+1 if the matrix is singular to working precision. */ + /*if ( *rcond < dlamch_("E") ) *info = A->ncol + 1;*/ + if ( *rcond < dmach("E") ) *info = A->ncol + 1; + } + + if ( nofact ) { + zQuerySpace(L, U, mem_usage); + Destroy_CompCol_Permuted(&AC); + } + if ( A->Stype == SLU_NR ) { + Destroy_SuperMatrix_Store(AA); + SUPERLU_FREE(AA); + } + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zgstrf.c b/src/Libraries/superlu-5.2.1/SRC/zgstrf.c new file mode 100644 index 00000000..2992612a --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zgstrf.c @@ -0,0 +1,459 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zgstrf.c + * \brief Computes an LU factorization of a general sparse matrix + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ * 
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_zdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * ZGSTRF computes an LU factorization of a general sparse m-by-n
+ * matrix A using partial pivoting with row interchanges.
+ * The factorization has the form
+ *     Pr * A = L * U
+ * where Pr is a row permutation matrix, L is lower triangular with unit
+ * diagonal elements (lower trapezoidal if A->nrow > A->ncol), and U is upper 
+ * triangular (upper trapezoidal if A->nrow < A->ncol).
+ *
+ * See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * options (input) superlu_options_t*
+ *         The structure defines the input parameters to control
+ *         how the LU decomposition will be performed.
+ *
+ * A        (input) SuperMatrix*
+ *	    Original matrix A, permuted by columns, of dimension
+ *          (A->nrow, A->ncol). The type of A can be:
+ *          Stype = SLU_NCP; Dtype = SLU_Z; Mtype = SLU_GE.
+ *
+ * relax    (input) int
+ *          To control degree of relaxing supernodes. If the number
+ *          of nodes (columns) in a subtree of the elimination tree is less
+ *          than relax, this subtree is considered as one supernode,
+ *          regardless of the row structures of those columns.
+ *
+ * panel_size (input) int
+ *          A panel consists of at most panel_size consecutive columns.
+ *
+ * etree    (input) int*, dimension (A->ncol)
+ *          Elimination tree of A'*A.
+ *          Note: etree is a vector of parent pointers for a forest whose
+ *          vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
+ *          On input, the columns of A should be permuted so that the
+ *          etree is in a certain postorder.
+ *
+ * work     (input/output) void*, size (lwork) (in bytes)
+ *          User-supplied work space and space for the output data structures.
+ *          Not referenced if lwork = 0;
+ *
+ * lwork   (input) int
+ *         Specifies the size of work array in bytes.
+ *         = 0:  allocate space internally by system malloc;
+ *         > 0:  use user-supplied work array of length lwork in bytes,
+ *               returns error if space runs out.
+ *         = -1: the routine guesses the amount of space needed without
+ *               performing the factorization, and returns it in
+ *               *info; no other side effects.
+ *
+ * perm_c   (input) int*, dimension (A->ncol)
+ *	    Column permutation vector, which defines the 
+ *          permutation matrix Pc; perm_c[i] = j means column i of A is 
+ *          in position j in A*Pc.
+ *          When searching for diagonal, perm_c[*] is applied to the
+ *          row subscripts of A, so that diagonal threshold pivoting
+ *          can find the diagonal of A, rather than that of A*Pc.
+ *
+ * perm_r   (input/output) int*, dimension (A->nrow)
+ *          Row permutation vector which defines the permutation matrix Pr,
+ *          perm_r[i] = j means row i of A is in position j in Pr*A.
+ *          If options->Fact == SamePattern_SameRowPerm, the pivoting routine
+ *             will try to use the input perm_r, unless a certain threshold
+ *             criterion is violated. In that case, perm_r is overwritten by
+ *             a new permutation determined by partial pivoting or diagonal
+ *             threshold pivoting.
+ *          Otherwise, perm_r is output argument;
+ *
+ * L        (output) SuperMatrix*
+ *          The factor L from the factorization Pr*A=L*U; use compressed row 
+ *          subscripts storage for supernodes, i.e., L has type: 
+ *          Stype = SLU_SC, Dtype = SLU_Z, Mtype = SLU_TRLU.
+ *
+ * U        (output) SuperMatrix*
+ *	    The factor U from the factorization Pr*A*Pc=L*U. Use column-wise
+ *          storage scheme, i.e., U has types: Stype = SLU_NC, 
+ *          Dtype = SLU_Z, Mtype = SLU_TRU.
+ *
+ * Glu      (input/output) GlobalLU_t *
+ *          If options->Fact == SamePattern_SameRowPerm, it is an input;
+ *              The matrix A will be factorized assuming that a 
+ *              factorization of a matrix with the same sparsity pattern
+ *              and similar numerical values was performed prior to this one.
+ *              Therefore, this factorization will reuse both row and column
+ *		scaling factors R and C, both row and column permutation
+ *		vectors perm_r and perm_c, and the L & U data structures
+ *		set up from the previous factorization.
+ *          Otherwise, it is an output.
+ *
+ * stat     (output) SuperLUStat_t*
+ *          Record the statistics on runtime and floating-point operation count.
+ *          See slu_util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info     (output) int*
+ *          = 0: successful exit
+ *          < 0: if info = -i, the i-th argument had an illegal value
+ *          > 0: if info = i, and i is
+ *             <= A->ncol: U(i,i) is exactly zero. The factorization has
+ *                been completed, but the factor U is exactly singular,
+ *                and division by zero will occur if it is used to solve a
+ *                system of equations.
+ *             > A->ncol: number of bytes allocated when memory allocation
+ *                failure occurred, plus A->ncol. If lwork = -1, it is
+ *                the estimated amount of space needed, plus A->ncol.
+ *
+ * ======================================================================
+ *
+ * Local Working Arrays: 
+ * ======================
+ *   m = number of rows in the matrix
+ *   n = number of columns in the matrix
+ *
+ *   xprune[0:n-1]: xprune[*] points to locations in subscript 
+ *	vector lsub[*]. For column i, xprune[i] denotes the point where 
+ *	structural pruning begins. I.e. only xlsub[i],..,xprune[i]-1 need 
+ *	to be traversed for symbolic factorization.
+ *
+ *   marker[0:3*m-1]: marker[i] = j means that node i has been 
+ *	reached when working on column j.
+ *	Storage: relative to original row subscripts
+ *	NOTE: There are 3 of them: marker/marker1 are used for panel dfs, 
+ *	      see zpanel_dfs.c; marker2 is used for inner-factorization,
+ *            see zcolumn_dfs.c.
+ *
+ *   parent[0:m-1]: parent vector used during dfs
+ *      Storage: relative to new row subscripts
+ *
+ *   xplore[0:m-1]: xplore[i] gives the location of the next (dfs) 
+ *	unexplored neighbor of i in lsub[*]
+ *
+ *   segrep[0:nseg-1]: contains the list of supernodal representatives
+ *	in topological order of the dfs. A supernode representative is the 
+ *	last column of a supernode.
+ *      The maximum size of segrep[] is n.
+ *
+ *   repfnz[0:W*m-1]: for a nonzero segment U[*,j] that ends at a 
+ *	supernodal representative r, repfnz[r] is the location of the first 
+ *	nonzero in this segment.  It is also used during the dfs: repfnz[r]>0
+ *	indicates the supernode r has been explored.
+ *	NOTE: There are W of them, each used for one column of a panel. 
+ *
+ *   panel_lsub[0:W*m-1]: temporary for the nonzeros row indices below 
+ *      the panel diagonal. These are filled in during zpanel_dfs(), and are
+ *      used later in the inner LU factorization within the panel.
+ *	panel_lsub[]/dense[] pair forms the SPA data structure.
+ *	NOTE: There are W of them.
+ *
+ *   dense[0:W*m-1]: sparse accumulating (SPA) vector for intermediate values;
+ *	    	   NOTE: there are W of them.
+ *
+ *   tempv[0:*]: real temporary used for dense numeric kernels;
+ *	The size of this array is defined by NUM_TEMPV() in slu_zdefs.h.
+ * 
+ */ + +void +zgstrf (superlu_options_t *options, SuperMatrix *A, + int relax, int panel_size, int *etree, void *work, int lwork, + int *perm_c, int *perm_r, SuperMatrix *L, SuperMatrix *U, + GlobalLU_t *Glu, /* persistent to facilitate multiple factorizations */ + SuperLUStat_t *stat, int *info) +{ + /* Local working arrays */ + NCPformat *Astore; + int *iperm_r = NULL; /* inverse of perm_r; used when + options->Fact == SamePattern_SameRowPerm */ + int *iperm_c; /* inverse of perm_c */ + int *iwork; + doublecomplex *zwork; + int *segrep, *repfnz, *parent, *xplore; + int *panel_lsub; /* dense[]/panel_lsub[] pair forms a w-wide SPA */ + int *xprune; + int *marker; + doublecomplex *dense, *tempv; + int *relax_end; + doublecomplex *a; + int *asub; + int *xa_begin, *xa_end; + int *xsup, *supno; + int *xlsub, *xlusup, *xusub; + int nzlumax; + double fill_ratio = sp_ienv(6); /* estimated fill ratio */ + + /* Local scalars */ + fact_t fact = options->Fact; + double diag_pivot_thresh = options->DiagPivotThresh; + int pivrow; /* pivotal row number in the original matrix A */ + int nseg1; /* no of segments in U-column above panel row jcol */ + int nseg; /* no of segments in each U-column */ + register int jcol; + register int kcol; /* end column of a relaxed snode */ + register int icol; + register int i, k, jj, new_next, iinfo; + int m, n, min_mn, jsupno, fsupc, nextlu, nextu; + int w_def; /* upper bound on panel width */ + int usepr, iperm_r_allocated = 0; + int nnzL, nnzU; + int *panel_histo = stat->panel_histo; + flops_t *ops = stat->ops; + + iinfo = 0; + m = A->nrow; + n = A->ncol; + min_mn = SUPERLU_MIN(m, n); + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + + /* Allocate storage common to the factor routines */ + *info = zLUMemInit(fact, work, lwork, m, n, Astore->nnz, + panel_size, fill_ratio, L, U, Glu, &iwork, &zwork); + if ( *info ) return; + + xsup = Glu->xsup; + supno = Glu->supno; + xlsub = Glu->xlsub; + xlusup = Glu->xlusup; + xusub = Glu->xusub; + + SetIWork(m, n, panel_size, iwork, &segrep, &parent, &xplore, + &repfnz, &panel_lsub, &xprune, &marker); + zSetRWork(m, panel_size, zwork, &dense, &tempv); + + usepr = (fact == SamePattern_SameRowPerm); + if ( usepr ) { + /* Compute the inverse of perm_r */ + iperm_r = (int *) intMalloc(m); + for (k = 0; k < m; ++k) iperm_r[perm_r[k]] = k; + iperm_r_allocated = 1; + } + iperm_c = (int *) intMalloc(n); + for (k = 0; k < n; ++k) iperm_c[perm_c[k]] = k; + + /* Identify relaxed snodes */ + relax_end = (int *) intMalloc(n); + if ( options->SymmetricMode == YES ) { + heap_relax_snode(n, etree, relax, marker, relax_end); + } else { + relax_snode(n, etree, relax, marker, relax_end); + } + + ifill (perm_r, m, EMPTY); + ifill (marker, m * NO_MARKER, EMPTY); + supno[0] = -1; + xsup[0] = xlsub[0] = xusub[0] = xlusup[0] = 0; + w_def = panel_size; + + /* + * Work on one "panel" at a time. A panel is one of the following: + * (a) a relaxed supernode at the bottom of the etree, or + * (b) panel_size contiguous columns, defined by the user + */ + for (jcol = 0; jcol < min_mn; ) { + + if ( relax_end[jcol] != EMPTY ) { /* start of a relaxed snode */ + kcol = relax_end[jcol]; /* end of the relaxed snode */ + panel_histo[kcol-jcol+1]++; + + /* -------------------------------------- + * Factorize the relaxed supernode(jcol:kcol) + * -------------------------------------- */ + /* Determine the union of the row structure of the snode */ + if ( (*info = zsnode_dfs(jcol, kcol, asub, xa_begin, xa_end, + xprune, marker, Glu)) != 0 ) + return; + + nextu = xusub[jcol]; + nextlu = xlusup[jcol]; + jsupno = supno[jcol]; + fsupc = xsup[jsupno]; + new_next = nextlu + (xlsub[fsupc+1]-xlsub[fsupc])*(kcol-jcol+1); + nzlumax = Glu->nzlumax; + while ( new_next > nzlumax ) { + if ( (*info = zLUMemXpand(jcol, nextlu, LUSUP, &nzlumax, Glu)) ) + return; + } + + for (icol = jcol; icol<= kcol; icol++) { + xusub[icol+1] = nextu; + + /* Scatter into SPA dense[*] */ + for (k = xa_begin[icol]; k < xa_end[icol]; k++) + dense[asub[k]] = a[k]; + + /* Numeric update within the snode */ + zsnode_bmod(icol, jsupno, fsupc, dense, tempv, Glu, stat); + + if ( (*info = zpivotL(icol, diag_pivot_thresh, &usepr, perm_r, + iperm_r, iperm_c, &pivrow, Glu, stat)) ) + if ( iinfo == 0 ) iinfo = *info; + +#ifdef DEBUG + zprint_lu_col("[1]: ", icol, pivrow, xprune, Glu); +#endif + + } + + jcol = icol; + + } else { /* Work on one panel of panel_size columns */ + + /* Adjust panel_size so that a panel won't overlap with the next + * relaxed snode. + */ + panel_size = w_def; + for (k = jcol + 1; k < SUPERLU_MIN(jcol+panel_size, min_mn); k++) + if ( relax_end[k] != EMPTY ) { + panel_size = k - jcol; + break; + } + if ( k == min_mn ) panel_size = min_mn - jcol; + panel_histo[panel_size]++; + + /* symbolic factor on a panel of columns */ + zpanel_dfs(m, panel_size, jcol, A, perm_r, &nseg1, + dense, panel_lsub, segrep, repfnz, xprune, + marker, parent, xplore, Glu); + + /* numeric sup-panel updates in topological order */ + zpanel_bmod(m, panel_size, jcol, nseg1, dense, + tempv, segrep, repfnz, Glu, stat); + + /* Sparse LU within the panel, and below panel diagonal */ + for ( jj = jcol; jj < jcol + panel_size; jj++) { + k = (jj - jcol) * m; /* column index for w-wide arrays */ + + nseg = nseg1; /* Begin after all the panel segments */ + + if ((*info = zcolumn_dfs(m, jj, perm_r, &nseg, &panel_lsub[k], + segrep, &repfnz[k], xprune, marker, + parent, xplore, Glu)) != 0) return; + + /* Numeric updates */ + if ((*info = zcolumn_bmod(jj, (nseg - nseg1), &dense[k], + tempv, &segrep[nseg1], &repfnz[k], + jcol, Glu, stat)) != 0) return; + + /* Copy the U-segments to ucol[*] */ + if ((*info = zcopy_to_ucol(jj, nseg, segrep, &repfnz[k], + perm_r, &dense[k], Glu)) != 0) + return; + + if ( (*info = zpivotL(jj, diag_pivot_thresh, &usepr, perm_r, + iperm_r, iperm_c, &pivrow, Glu, stat)) ) + if ( iinfo == 0 ) iinfo = *info; + + /* Prune columns (0:jj-1) using column jj */ + zpruneL(jj, perm_r, pivrow, nseg, segrep, + &repfnz[k], xprune, Glu); + + /* Reset repfnz[] for this column */ + resetrep_col (nseg, segrep, &repfnz[k]); + +#ifdef DEBUG + zprint_lu_col("[2]: ", jj, pivrow, xprune, Glu); +#endif + + } + + jcol += panel_size; /* Move to the next panel */ + + } /* else */ + + } /* for */ + + *info = iinfo; + + if ( m > n ) { + k = 0; + for (i = 0; i < m; ++i) + if ( perm_r[i] == EMPTY ) { + perm_r[i] = n + k; + ++k; + } + } + + countnz(min_mn, xprune, &nnzL, &nnzU, Glu); + fixupL(min_mn, perm_r, Glu); + + zLUWorkFree(iwork, zwork, Glu); /* Free work space and compress storage */ + + if ( fact == SamePattern_SameRowPerm ) { + /* L and U structures may have changed due to possibly different + pivoting, even though the storage is available. + There could also be memory expansions, so the array locations + may have changed, */ + ((SCformat *)L->Store)->nnz = nnzL; + ((SCformat *)L->Store)->nsuper = Glu->supno[n]; + ((SCformat *)L->Store)->nzval = (doublecomplex *) Glu->lusup; + ((SCformat *)L->Store)->nzval_colptr = Glu->xlusup; + ((SCformat *)L->Store)->rowind = Glu->lsub; + ((SCformat *)L->Store)->rowind_colptr = Glu->xlsub; + ((NCformat *)U->Store)->nnz = nnzU; + ((NCformat *)U->Store)->nzval = (doublecomplex *) Glu->ucol; + ((NCformat *)U->Store)->rowind = Glu->usub; + ((NCformat *)U->Store)->colptr = Glu->xusub; + } else { + zCreate_SuperNode_Matrix(L, A->nrow, min_mn, nnzL, + (doublecomplex *) Glu->lusup, Glu->xlusup, + Glu->lsub, Glu->xlsub, Glu->supno, Glu->xsup, + SLU_SC, SLU_Z, SLU_TRLU); + zCreate_CompCol_Matrix(U, min_mn, min_mn, nnzU, + (doublecomplex *) Glu->ucol, Glu->usub, Glu->xusub, + SLU_NC, SLU_Z, SLU_TRU); + } + + ops[FACT] += ops[TRSV] + ops[GEMV]; + stat->expansions = --(Glu->num_expansions); + + if ( iperm_r_allocated ) SUPERLU_FREE (iperm_r); + SUPERLU_FREE (iperm_c); + SUPERLU_FREE (relax_end); + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zgstrs.c b/src/Libraries/superlu-5.2.1/SRC/zgstrs.c new file mode 100644 index 00000000..df95d6fd --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zgstrs.c @@ -0,0 +1,360 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zgstrs.c + * \brief Solves a system using LU factorization + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + +#include "slu_zdefs.h" + + +/* + * Function prototypes + */ +void zusolve(int, int, doublecomplex*, doublecomplex*); +void zlsolve(int, int, doublecomplex*, doublecomplex*); +void zmatvec(int, int, int, doublecomplex*, doublecomplex*, doublecomplex*); + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * ZGSTRS solves a system of linear equations A*X=B or A'*X=B
+ * with A sparse and B dense, using the LU factorization computed by
+ * ZGSTRF.
+ *
+ * See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ * Arguments
+ * =========
+ *
+ * trans   (input) trans_t
+ *          Specifies the form of the system of equations:
+ *          = NOTRANS: A * X = B  (No transpose)
+ *          = TRANS:   A'* X = B  (Transpose)
+ *          = CONJ:    A**H * X = B  (Conjugate transpose)
+ *
+ * L       (input) SuperMatrix*
+ *         The factor L from the factorization Pr*A*Pc=L*U as computed by
+ *         zgstrf(). Use compressed row subscripts storage for supernodes,
+ *         i.e., L has types: Stype = SLU_SC, Dtype = SLU_Z, Mtype = SLU_TRLU.
+ *
+ * U       (input) SuperMatrix*
+ *         The factor U from the factorization Pr*A*Pc=L*U as computed by
+ *         zgstrf(). Use column-wise storage scheme, i.e., U has types:
+ *         Stype = SLU_NC, Dtype = SLU_Z, Mtype = SLU_TRU.
+ *
+ * perm_c  (input) int*, dimension (L->ncol)
+ *	   Column permutation vector, which defines the 
+ *         permutation matrix Pc; perm_c[i] = j means column i of A is 
+ *         in position j in A*Pc.
+ *
+ * perm_r  (input) int*, dimension (L->nrow)
+ *         Row permutation vector, which defines the permutation matrix Pr; 
+ *         perm_r[i] = j means row i of A is in position j in Pr*A.
+ *
+ * B       (input/output) SuperMatrix*
+ *         B has types: Stype = SLU_DN, Dtype = SLU_Z, Mtype = SLU_GE.
+ *         On entry, the right hand side matrix.
+ *         On exit, the solution matrix if info = 0;
+ *
+ * stat     (output) SuperLUStat_t*
+ *          Record the statistics on runtime and floating-point operation count.
+ *          See util.h for the definition of 'SuperLUStat_t'.
+ *
+ * info    (output) int*
+ * 	   = 0: successful exit
+ *	   < 0: if info = -i, the i-th argument had an illegal value
+ * 
+ */ + +void +zgstrs (trans_t trans, SuperMatrix *L, SuperMatrix *U, + int *perm_c, int *perm_r, SuperMatrix *B, + SuperLUStat_t *stat, int *info) +{ + +#ifdef _CRAY + _fcd ftcs1, ftcs2, ftcs3, ftcs4; +#endif + int incx = 1, incy = 1; +#ifdef USE_VENDOR_BLAS + doublecomplex alpha = {1.0, 0.0}, beta = {1.0, 0.0}; + doublecomplex *work_col; +#endif + doublecomplex temp_comp; + DNformat *Bstore; + doublecomplex *Bmat; + SCformat *Lstore; + NCformat *Ustore; + doublecomplex *Lval, *Uval; + int fsupc, nrow, nsupr, nsupc, luptr, istart, irow; + int i, j, k, iptr, jcol, n, ldb, nrhs; + doublecomplex *work, *rhs_work, *soln; + flops_t solve_ops; + void zprint_soln(); + + /* Test input parameters ... */ + *info = 0; + Bstore = B->Store; + ldb = Bstore->lda; + nrhs = B->ncol; + if ( trans != NOTRANS && trans != TRANS && trans != CONJ ) *info = -1; + else if ( L->nrow != L->ncol || L->nrow < 0 || + L->Stype != SLU_SC || L->Dtype != SLU_Z || L->Mtype != SLU_TRLU ) + *info = -2; + else if ( U->nrow != U->ncol || U->nrow < 0 || + U->Stype != SLU_NC || U->Dtype != SLU_Z || U->Mtype != SLU_TRU ) + *info = -3; + else if ( ldb < SUPERLU_MAX(0, L->nrow) || + B->Stype != SLU_DN || B->Dtype != SLU_Z || B->Mtype != SLU_GE ) + *info = -6; + if ( *info ) { + i = -(*info); + input_error("zgstrs", &i); + return; + } + + n = L->nrow; + work = doublecomplexCalloc(n * nrhs); + if ( !work ) ABORT("Malloc fails for local work[]."); + soln = doublecomplexMalloc(n); + if ( !soln ) ABORT("Malloc fails for local soln[]."); + + Bmat = Bstore->nzval; + Lstore = L->Store; + Lval = Lstore->nzval; + Ustore = U->Store; + Uval = Ustore->nzval; + solve_ops = 0; + + if ( trans == NOTRANS ) { + /* Permute right hand sides to form Pr*B */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[perm_r[k]] = rhs_work[k]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + /* Forward solve PLy=Pb. */ + for (k = 0; k <= Lstore->nsuper; k++) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + nrow = nsupr - nsupc; + + solve_ops += 4 * nsupc * (nsupc - 1) * nrhs; + solve_ops += 8 * nrow * nsupc * nrhs; + + if ( nsupc == 1 ) { + for (j = 0; j < nrhs; j++) { + rhs_work = &Bmat[j*ldb]; + luptr = L_NZ_START(fsupc); + for (iptr=istart+1; iptr < L_SUB_START(fsupc+1); iptr++){ + irow = L_SUB(iptr); + ++luptr; + zz_mult(&temp_comp, &rhs_work[fsupc], &Lval[luptr]); + z_sub(&rhs_work[irow], &rhs_work[irow], &temp_comp); + } + } + } else { + luptr = L_NZ_START(fsupc); +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + ftcs1 = _cptofcd("L", strlen("L")); + ftcs2 = _cptofcd("N", strlen("N")); + ftcs3 = _cptofcd("U", strlen("U")); + CTRSM( ftcs1, ftcs1, ftcs2, ftcs3, &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); + + CGEMM( ftcs2, ftcs2, &nrow, &nrhs, &nsupc, &alpha, + &Lval[luptr+nsupc], &nsupr, &Bmat[fsupc], &ldb, + &beta, &work[0], &n ); +#else + ztrsm_("L", "L", "N", "U", &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); + + zgemm_( "N", "N", &nrow, &nrhs, &nsupc, &alpha, + &Lval[luptr+nsupc], &nsupr, &Bmat[fsupc], &ldb, + &beta, &work[0], &n ); +#endif + for (j = 0; j < nrhs; j++) { + rhs_work = &Bmat[j*ldb]; + work_col = &work[j*n]; + iptr = istart + nsupc; + for (i = 0; i < nrow; i++) { + irow = L_SUB(iptr); + z_sub(&rhs_work[irow], &rhs_work[irow], &work_col[i]); + work_col[i].r = 0.0; + work_col[i].i = 0.0; + iptr++; + } + } +#else + for (j = 0; j < nrhs; j++) { + rhs_work = &Bmat[j*ldb]; + zlsolve (nsupr, nsupc, &Lval[luptr], &rhs_work[fsupc]); + zmatvec (nsupr, nrow, nsupc, &Lval[luptr+nsupc], + &rhs_work[fsupc], &work[0] ); + + iptr = istart + nsupc; + for (i = 0; i < nrow; i++) { + irow = L_SUB(iptr); + z_sub(&rhs_work[irow], &rhs_work[irow], &work[i]); + work[i].r = 0.; + work[i].i = 0.; + iptr++; + } + } +#endif + } /* else ... */ + } /* for L-solve */ + +#ifdef DEBUG + printf("After L-solve: y=\n"); + zprint_soln(n, nrhs, Bmat); +#endif + + /* + * Back solve Ux=y. + */ + for (k = Lstore->nsuper; k >= 0; k--) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + solve_ops += 4 * nsupc * (nsupc + 1) * nrhs; + + if ( nsupc == 1 ) { + rhs_work = &Bmat[0]; + for (j = 0; j < nrhs; j++) { + z_div(&rhs_work[fsupc], &rhs_work[fsupc], &Lval[luptr]); + rhs_work += ldb; + } + } else { +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + ftcs1 = _cptofcd("L", strlen("L")); + ftcs2 = _cptofcd("U", strlen("U")); + ftcs3 = _cptofcd("N", strlen("N")); + CTRSM( ftcs1, ftcs2, ftcs3, ftcs3, &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); +#else + ztrsm_("L", "U", "N", "N", &nsupc, &nrhs, &alpha, + &Lval[luptr], &nsupr, &Bmat[fsupc], &ldb); +#endif +#else + for (j = 0; j < nrhs; j++) + zusolve ( nsupr, nsupc, &Lval[luptr], &Bmat[fsupc+j*ldb] ); +#endif + } + + for (j = 0; j < nrhs; ++j) { + rhs_work = &Bmat[j*ldb]; + for (jcol = fsupc; jcol < fsupc + nsupc; jcol++) { + solve_ops += 8*(U_NZ_START(jcol+1) - U_NZ_START(jcol)); + for (i = U_NZ_START(jcol); i < U_NZ_START(jcol+1); i++ ){ + irow = U_SUB(i); + zz_mult(&temp_comp, &rhs_work[jcol], &Uval[i]); + z_sub(&rhs_work[irow], &rhs_work[irow], &temp_comp); + } + } + } + + } /* for U-solve */ + +#ifdef DEBUG + printf("After U-solve: x=\n"); + zprint_soln(n, nrhs, Bmat); +#endif + + /* Compute the final solution X := Pc*X. */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[k] = rhs_work[perm_c[k]]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + stat->ops[SOLVE] = solve_ops; + + } else { /* Solve A'*X=B or CONJ(A)*X=B */ + /* Permute right hand sides to form Pc'*B. */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[perm_c[k]] = rhs_work[k]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + stat->ops[SOLVE] = 0; + if (trans == TRANS) { + for (k = 0; k < nrhs; ++k) { + /* Multiply by inv(U'). */ + sp_ztrsv("U", "T", "N", L, U, &Bmat[k*ldb], stat, info); + + /* Multiply by inv(L'). */ + sp_ztrsv("L", "T", "U", L, U, &Bmat[k*ldb], stat, info); + } + } else { /* trans == CONJ */ + for (k = 0; k < nrhs; ++k) { + /* Multiply by conj(inv(U')). */ + sp_ztrsv("U", "C", "N", L, U, &Bmat[k*ldb], stat, info); + + /* Multiply by conj(inv(L')). */ + sp_ztrsv("L", "C", "U", L, U, &Bmat[k*ldb], stat, info); + } + } + /* Compute the final solution X := Pr'*X (=inv(Pr)*X) */ + for (i = 0; i < nrhs; i++) { + rhs_work = &Bmat[i*ldb]; + for (k = 0; k < n; k++) soln[k] = rhs_work[perm_r[k]]; + for (k = 0; k < n; k++) rhs_work[k] = soln[k]; + } + + } + + SUPERLU_FREE(work); + SUPERLU_FREE(soln); +} + +/* + * Diagnostic print of the solution vector + */ +void +zprint_soln(int n, int nrhs, doublecomplex *soln) +{ + int i; + + for (i = 0; i < n; i++) + printf("\t%d: %.4f\t%.4f\n", i, soln[i].r, soln[i].i); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zlacon.c b/src/Libraries/superlu-5.2.1/SRC/zlacon.c new file mode 100644 index 00000000..2cb54ba2 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zlacon.c @@ -0,0 +1,232 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zlacon.c + * \brief Estimates the 1-norm + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ */ +#include +#include "slu_Cnames.h" +#include "slu_dcomplex.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   ZLACON estimates the 1-norm of a square matrix A.   
+ *   Reverse communication is used for evaluating matrix-vector products. 
+ * 
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   N      (input) INT
+ *          The order of the matrix.  N >= 1.   
+ *
+ *   V      (workspace) DOUBLE COMPLEX PRECISION array, dimension (N)   
+ *          On the final return, V = A*W,  where  EST = norm(V)/norm(W)   
+ *          (W is not returned).   
+ *
+ *   X      (input/output) DOUBLE COMPLEX PRECISION array, dimension (N)   
+ *          On an intermediate return, X should be overwritten by   
+ *                A * X,   if KASE=1,   
+ *                A' * X,  if KASE=2,
+ *          where A' is the conjugate transpose of A,
+ *         and ZLACON must be re-called with all the other parameters   
+ *          unchanged.   
+ *
+ *
+ *   EST    (output) DOUBLE PRECISION   
+ *          An estimate (a lower bound) for norm(A).   
+ *
+ *   KASE   (input/output) INT
+ *          On the initial call to ZLACON, KASE should be 0.   
+ *          On an intermediate return, KASE will be 1 or 2, indicating   
+ *          whether X should be overwritten by A * X  or A' * X.   
+ *          On the final return from ZLACON, KASE will again be 0.   
+ *
+ *   Further Details   
+ *   ======= =======   
+ *
+ *   Contributed by Nick Higham, University of Manchester.   
+ *   Originally named CONEST, dated March 16, 1988.   
+ *
+ *   Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of 
+ *   a real or complex matrix, with applications to condition estimation", 
+ *   ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.   
+ *   ===================================================================== 
+ * 
+ */ + +int +zlacon_(int *n, doublecomplex *v, doublecomplex *x, double *est, int *kase) + +{ + + + /* Table of constant values */ + int c__1 = 1; + doublecomplex zero = {0.0, 0.0}; + doublecomplex one = {1.0, 0.0}; + + /* System generated locals */ + double d__1; + + /* Local variables */ + static int jump; + int jlast; + int iter; + double altsgn, estold; + int i, j; + double temp; + double safmin; + extern double dlamch_(char *); + extern int izmax1_slu(int *, doublecomplex *, int *); + extern double dzsum1_slu(int *, doublecomplex *, int *); + + safmin = dlamch_("Safe minimum"); + if ( *kase == 0 ) { + for (i = 0; i < *n; ++i) { + x[i].r = 1. / (double) (*n); + x[i].i = 0.; + } + *kase = 1; + jump = 1; + return 0; + } + + switch (jump) { + case 1: goto L20; + case 2: goto L40; + case 3: goto L70; + case 4: goto L110; + case 5: goto L140; + } + + /* ................ ENTRY (JUMP = 1) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY A*X. */ + L20: + if (*n == 1) { + v[0] = x[0]; + *est = z_abs(&v[0]); + /* ... QUIT */ + goto L150; + } + *est = dzsum1_slu(n, x, &c__1); + + for (i = 0; i < *n; ++i) { + d__1 = z_abs(&x[i]); + if (d__1 > safmin) { + d__1 = 1 / d__1; + x[i].r *= d__1; + x[i].i *= d__1; + } else { + x[i] = one; + } + } + *kase = 2; + jump = 2; + return 0; + + /* ................ ENTRY (JUMP = 2) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X. */ +L40: + j = izmax1_slu(n, &x[0], &c__1); + --j; + iter = 2; + + /* MAIN LOOP - ITERATIONS 2,3,...,ITMAX. */ +L50: + for (i = 0; i < *n; ++i) x[i] = zero; + x[j] = one; + *kase = 1; + jump = 3; + return 0; + + /* ................ ENTRY (JUMP = 3) + X HAS BEEN OVERWRITTEN BY A*X. */ +L70: +#ifdef _CRAY + CCOPY(n, x, &c__1, v, &c__1); +#else + zcopy_(n, x, &c__1, v, &c__1); +#endif + estold = *est; + *est = dzsum1_slu(n, v, &c__1); + + +L90: + /* TEST FOR CYCLING. */ + if (*est <= estold) goto L120; + + for (i = 0; i < *n; ++i) { + d__1 = z_abs(&x[i]); + if (d__1 > safmin) { + d__1 = 1 / d__1; + x[i].r *= d__1; + x[i].i *= d__1; + } else { + x[i] = one; + } + } + *kase = 2; + jump = 4; + return 0; + + /* ................ ENTRY (JUMP = 4) + X HAS BEEN OVERWRITTEN BY TRANDPOSE(A)*X. */ +L110: + jlast = j; + j = izmax1_slu(n, &x[0], &c__1); + --j; + if (x[jlast].r != (d__1 = x[j].r, fabs(d__1)) && iter < 5) { + ++iter; + goto L50; + } + + /* ITERATION COMPLETE. FINAL STAGE. */ +L120: + altsgn = 1.; + for (i = 1; i <= *n; ++i) { + x[i-1].r = altsgn * ((double)(i - 1) / (double)(*n - 1) + 1.); + x[i-1].i = 0.; + altsgn = -altsgn; + } + *kase = 1; + jump = 5; + return 0; + + /* ................ ENTRY (JUMP = 5) + X HAS BEEN OVERWRITTEN BY A*X. */ +L140: + temp = dzsum1_slu(n, x, &c__1) / (double)(*n * 3) * 2.; + if (temp > *est) { +#ifdef _CRAY + CCOPY(n, &x[0], &c__1, &v[0], &c__1); +#else + zcopy_(n, &x[0], &c__1, &v[0], &c__1); +#endif + *est = temp; + } + +L150: + *kase = 0; + return 0; + +} /* zlacon_ */ diff --git a/src/Libraries/superlu-5.2.1/SRC/zlacon2.c b/src/Libraries/superlu-5.2.1/SRC/zlacon2.c new file mode 100644 index 00000000..b43c619c --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zlacon2.c @@ -0,0 +1,239 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zlacon2.c + * \brief Estimates the 1-norm + * + *
+ * -- SuperLU routine (version 5.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * July 25, 2015
+ * 
+ */ +#include +#include "slu_Cnames.h" +#include "slu_dcomplex.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   ZLACON2 estimates the 1-norm of a square matrix A.   
+ *   Reverse communication is used for evaluating matrix-vector products. 
+ * 
+ *   This is a thread safe version of ZLACON, which uses the array ISAVE
+ *   in place of a STATIC variables, as follows:
+ *
+ *     ZLACON     ZLACON2
+ *      jump     isave[0]
+ *      j        isave[1]
+ *      iter     isave[2]
+ *
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   N      (input) INT
+ *          The order of the matrix.  N >= 1.   
+ *
+ *   V      (workspace) DOUBLE COMPLEX PRECISION array, dimension (N)   
+ *          On the final return, V = A*W,  where  EST = norm(V)/norm(W)   
+ *          (W is not returned).   
+ *
+ *   X      (input/output) DOUBLE COMPLEX PRECISION array, dimension (N)   
+ *          On an intermediate return, X should be overwritten by   
+ *                A * X,   if KASE=1,   
+ *                A' * X,  if KASE=2,
+ *          where A' is the conjugate transpose of A,
+ *         and ZLACON must be re-called with all the other parameters   
+ *          unchanged.   
+ *
+ *
+ *   EST    (output) DOUBLE PRECISION   
+ *          An estimate (a lower bound) for norm(A).   
+ *
+ *   KASE   (input/output) INT
+ *          On the initial call to ZLACON, KASE should be 0.   
+ *          On an intermediate return, KASE will be 1 or 2, indicating   
+ *          whether X should be overwritten by A * X  or A' * X.   
+ *          On the final return from ZLACON, KASE will again be 0.   
+ *
+ *   isave  (input/output) int [3]
+ *          ISAVE is INTEGER array, dimension (3)
+ *          ISAVE is used to save variables between calls to ZLACON2
+ *
+ *   Further Details   
+ *   ===============   
+ *
+ *   Contributed by Nick Higham, University of Manchester.   
+ *   Originally named CONEST, dated March 16, 1988.   
+ *
+ *   Reference: N.J. Higham, "FORTRAN codes for estimating the one-norm of 
+ *   a real or complex matrix, with applications to condition estimation", 
+ *   ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.   
+ *   ===================================================================== 
+ * 
+ */ + +int +zlacon2_(int *n, doublecomplex *v, doublecomplex *x, double *est, int *kase, int isave[3]) +{ + /* Table of constant values */ + int c__1 = 1; + doublecomplex zero = {0.0, 0.0}; + doublecomplex one = {1.0, 0.0}; + + /* System generated locals */ + double d__1; + + /* Local variables */ + int jlast; + double altsgn, estold; + int i; + double temp; + double safmin; + extern double dmach(char *); + extern int izmax1_slu(int *, doublecomplex *, int *); + extern double dzsum1_slu(int *, doublecomplex *, int *); + + safmin = dmach("Safe minimum"); /* lamch_("Safe minimum"); */ + if ( *kase == 0 ) { + for (i = 0; i < *n; ++i) { + x[i].r = 1. / (double) (*n); + x[i].i = 0.; + } + *kase = 1; + isave[0] = 1; /* jump = 1; */ + return 0; + } + + switch (isave[0]) { + case 1: goto L20; + case 2: goto L40; + case 3: goto L70; + case 4: goto L110; + case 5: goto L140; + } + + /* ................ ENTRY (isave[0] = 1) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY A*X. */ + L20: + if (*n == 1) { + v[0] = x[0]; + *est = z_abs(&v[0]); + /* ... QUIT */ + goto L150; + } + *est = dzsum1_slu(n, x, &c__1); + + for (i = 0; i < *n; ++i) { + d__1 = z_abs(&x[i]); + if (d__1 > safmin) { + d__1 = 1 / d__1; + x[i].r *= d__1; + x[i].i *= d__1; + } else { + x[i] = one; + } + } + *kase = 2; + isave[0] = 2; /* jump = 2; */ + return 0; + + /* ................ ENTRY (isave[0] = 2) + FIRST ITERATION. X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X. */ +L40: + isave[1] = izmax1_slu(n, &x[0], &c__1); /* j */ + --isave[1]; /* --j; */ + isave[2] = 2; /* iter = 2; */ + + /* MAIN LOOP - ITERATIONS 2,3,...,ITMAX. */ +L50: + for (i = 0; i < *n; ++i) x[i] = zero; + x[isave[1]] = one; + *kase = 1; + isave[0] = 3; /* jump = 3; */ + return 0; + + /* ................ ENTRY (isave[0] = 3) + X HAS BEEN OVERWRITTEN BY A*X. */ +L70: +#ifdef _CRAY + CCOPY(n, x, &c__1, v, &c__1); +#else + zcopy_(n, x, &c__1, v, &c__1); +#endif + estold = *est; + *est = dzsum1_slu(n, v, &c__1); + + +L90: + /* TEST FOR CYCLING. */ + if (*est <= estold) goto L120; + + for (i = 0; i < *n; ++i) { + d__1 = z_abs(&x[i]); + if (d__1 > safmin) { + d__1 = 1 / d__1; + x[i].r *= d__1; + x[i].i *= d__1; + } else { + x[i] = one; + } + } + *kase = 2; + isave[0] = 4; /* jump = 4; */ + return 0; + + /* ................ ENTRY (isave[0] = 4) + X HAS BEEN OVERWRITTEN BY TRANDPOSE(A)*X. */ +L110: + jlast = isave[1]; /* j; */ + isave[1] = izmax1_slu(n, &x[0], &c__1); /* j */ + isave[1] = isave[1] - 1; /* --j; */ + if (x[jlast].r != (d__1 = x[isave[1]].r, fabs(d__1)) && isave[2] < 5) { + isave[2] = isave[2] + 1; /* ++iter; */ + goto L50; + } + + /* ITERATION COMPLETE. FINAL STAGE. */ +L120: + altsgn = 1.; + for (i = 1; i <= *n; ++i) { + x[i-1].r = altsgn * ((double)(i - 1) / (double)(*n - 1) + 1.); + x[i-1].i = 0.; + altsgn = -altsgn; + } + *kase = 1; + isave[0] = 5; /* jump = 5; */ + return 0; + + /* ................ ENTRY (isave[0] = 5) + X HAS BEEN OVERWRITTEN BY A*X. */ +L140: + temp = dzsum1_slu(n, x, &c__1) / (double)(*n * 3) * 2.; + if (temp > *est) { +#ifdef _CRAY + CCOPY(n, &x[0], &c__1, &v[0], &c__1); +#else + zcopy_(n, &x[0], &c__1, &v[0], &c__1); +#endif + *est = temp; + } + +L150: + *kase = 0; + return 0; + +} /* zlacon_ */ diff --git a/src/Libraries/superlu-5.2.1/SRC/zlangs.c b/src/Libraries/superlu-5.2.1/SRC/zlangs.c new file mode 100644 index 00000000..595b9e98 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zlangs.c @@ -0,0 +1,129 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zlangs.c + * \brief Returns the value of the one norm + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Modified from lapack routine ZLANGE 
+ * 
+ */ +/* + * File name: zlangs.c + * History: Modified from lapack routine ZLANGE + */ +#include +#include "slu_zdefs.h" + +/*! \brief + * + *
+ * Purpose   
+ *   =======   
+ *
+ *   ZLANGS returns the value of the one norm, or the Frobenius norm, or 
+ *   the infinity norm, or the element of largest absolute value of a 
+ *   real matrix A.   
+ *
+ *   Description   
+ *   ===========   
+ *
+ *   ZLANGE returns the value   
+ *
+ *      ZLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm'   
+ *               (   
+ *               ( norm1(A),         NORM = '1', 'O' or 'o'   
+ *               (   
+ *               ( normI(A),         NORM = 'I' or 'i'   
+ *               (   
+ *               ( normF(A),         NORM = 'F', 'f', 'E' or 'e'   
+ *
+ *   where  norm1  denotes the  one norm of a matrix (maximum column sum), 
+ *   normI  denotes the  infinity norm  of a matrix  (maximum row sum) and 
+ *   normF  denotes the  Frobenius norm of a matrix (square root of sum of 
+ *   squares).  Note that  max(abs(A(i,j)))  is not a  matrix norm.   
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   NORM    (input) CHARACTER*1   
+ *           Specifies the value to be returned in ZLANGE as described above.   
+ *   A       (input) SuperMatrix*
+ *           The M by N sparse matrix A. 
+ *
+ *  =====================================================================
+ * 
+ */ + +double zlangs(char *norm, SuperMatrix *A) +{ + + /* Local variables */ + NCformat *Astore; + doublecomplex *Aval; + int i, j, irow; + double value, sum; + double *rwork; + + Astore = A->Store; + Aval = Astore->nzval; + + if ( SUPERLU_MIN(A->nrow, A->ncol) == 0) { + value = 0.; + + } else if (strncmp(norm, "M", 1)==0) { + /* Find max(abs(A(i,j))). */ + value = 0.; + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++) + value = SUPERLU_MAX( value, z_abs( &Aval[i]) ); + + } else if (strncmp(norm, "O", 1)==0 || *(unsigned char *)norm == '1') { + /* Find norm1(A). */ + value = 0.; + for (j = 0; j < A->ncol; ++j) { + sum = 0.; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++) + sum += z_abs( &Aval[i] ); + value = SUPERLU_MAX(value,sum); + } + + } else if (strncmp(norm, "I", 1)==0) { + /* Find normI(A). */ + if ( !(rwork = (double *) SUPERLU_MALLOC(A->nrow * sizeof(double))) ) + ABORT("SUPERLU_MALLOC fails for rwork."); + for (i = 0; i < A->nrow; ++i) rwork[i] = 0.; + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++) { + irow = Astore->rowind[i]; + rwork[irow] += z_abs( &Aval[i] ); + } + value = 0.; + for (i = 0; i < A->nrow; ++i) + value = SUPERLU_MAX(value, rwork[i]); + + SUPERLU_FREE (rwork); + + } else if (strncmp(norm, "F", 1)==0 || strncmp(norm, "E", 1)==0) { + /* Find normF(A). */ + ABORT("Not implemented."); + } else + ABORT("Illegal norm specified."); + + return (value); + +} /* zlangs */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/zlaqgs.c b/src/Libraries/superlu-5.2.1/SRC/zlaqgs.c new file mode 100644 index 00000000..d434ec7f --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zlaqgs.c @@ -0,0 +1,157 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zlaqgs.c + * \brief Equlibrates a general sprase matrix + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ * Modified from LAPACK routine ZLAQGE
+ * 
+ */ +/* + * File name: zlaqgs.c + * History: Modified from LAPACK routine ZLAQGE + */ +#include +#include "slu_zdefs.h" + +/*! \brief + * + *
+ *   Purpose   
+ *   =======   
+ *
+ *   ZLAQGS equilibrates a general sparse M by N matrix A using the row and   
+ *   scaling factors in the vectors R and C.   
+ *
+ *   See supermatrix.h for the definition of 'SuperMatrix' structure.
+ *
+ *   Arguments   
+ *   =========   
+ *
+ *   A       (input/output) SuperMatrix*
+ *           On exit, the equilibrated matrix.  See EQUED for the form of 
+ *           the equilibrated matrix. The type of A can be:
+ *	    Stype = NC; Dtype = SLU_Z; Mtype = GE.
+ *	    
+ *   R       (input) double*, dimension (A->nrow)
+ *           The row scale factors for A.
+ *	    
+ *   C       (input) double*, dimension (A->ncol)
+ *           The column scale factors for A.
+ *	    
+ *   ROWCND  (input) double
+ *           Ratio of the smallest R(i) to the largest R(i).
+ *	    
+ *   COLCND  (input) double
+ *           Ratio of the smallest C(i) to the largest C(i).
+ *	    
+ *   AMAX    (input) double
+ *           Absolute value of largest matrix entry.
+ *	    
+ *   EQUED   (output) char*
+ *           Specifies the form of equilibration that was done.   
+ *           = 'N':  No equilibration   
+ *           = 'R':  Row equilibration, i.e., A has been premultiplied by  
+ *                   diag(R).   
+ *           = 'C':  Column equilibration, i.e., A has been postmultiplied  
+ *                   by diag(C).   
+ *           = 'B':  Both row and column equilibration, i.e., A has been
+ *                   replaced by diag(R) * A * diag(C).   
+ *
+ *   Internal Parameters   
+ *   ===================   
+ *
+ *   THRESH is a threshold value used to decide if row or column scaling   
+ *   should be done based on the ratio of the row or column scaling   
+ *   factors.  If ROWCND < THRESH, row scaling is done, and if   
+ *   COLCND < THRESH, column scaling is done.   
+ *
+ *   LARGE and SMALL are threshold values used to decide if row scaling   
+ *   should be done based on the absolute size of the largest matrix   
+ *   element.  If AMAX > LARGE or AMAX < SMALL, row scaling is done.   
+ *
+ *   ===================================================================== 
+ * 
+ */ + +void +zlaqgs(SuperMatrix *A, double *r, double *c, + double rowcnd, double colcnd, double amax, char *equed) +{ + + +#define THRESH (0.1) + + /* Local variables */ + NCformat *Astore; + doublecomplex *Aval; + int i, j, irow; + double large, small, cj; + double temp; + + + /* Quick return if possible */ + if (A->nrow <= 0 || A->ncol <= 0) { + *(unsigned char *)equed = 'N'; + return; + } + + Astore = A->Store; + Aval = Astore->nzval; + + /* Initialize LARGE and SMALL. */ + small = dmach("Safe minimum") / dmach("Precision"); + large = 1. / small; + + if (rowcnd >= THRESH && amax >= small && amax <= large) { + if (colcnd >= THRESH) + *(unsigned char *)equed = 'N'; + else { + /* Column scaling */ + for (j = 0; j < A->ncol; ++j) { + cj = c[j]; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + zd_mult(&Aval[i], &Aval[i], cj); + } + } + *(unsigned char *)equed = 'C'; + } + } else if (colcnd >= THRESH) { + /* Row scaling, no column scaling */ + for (j = 0; j < A->ncol; ++j) + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + zd_mult(&Aval[i], &Aval[i], r[irow]); + } + *(unsigned char *)equed = 'R'; + } else { + /* Row and column scaling */ + for (j = 0; j < A->ncol; ++j) { + cj = c[j]; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + temp = cj * r[irow]; + zd_mult(&Aval[i], &Aval[i], temp); + } + } + *(unsigned char *)equed = 'B'; + } + + return; + +} /* zlaqgs */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/zldperm.c b/src/Libraries/superlu-5.2.1/SRC/zldperm.c new file mode 100644 index 00000000..5802699c --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zldperm.c @@ -0,0 +1,178 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file + * \brief Finds a row permutation so that the matrix has large entries on the diagonal + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ + +#include "slu_zdefs.h" + +extern int_t mc64id_(int_t*); +extern int_t mc64ad_(int_t*, int_t*, int_t*, int_t [], int_t [], double [], + int_t*, int_t [], int_t*, int_t[], int_t*, double [], + int_t [], int_t []); + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *   ZLDPERM finds a row permutation so that the matrix has large
+ *   entries on the diagonal.
+ *
+ * Arguments
+ * =========
+ *
+ * job    (input) int
+ *        Control the action. Possible values for JOB are:
+ *        = 1 : Compute a row permutation of the matrix so that the
+ *              permuted matrix has as many entries on its diagonal as
+ *              possible. The values on the diagonal are of arbitrary size.
+ *              HSL subroutine MC21A/AD is used for this.
+ *        = 2 : Compute a row permutation of the matrix so that the smallest 
+ *              value on the diagonal of the permuted matrix is maximized.
+ *        = 3 : Compute a row permutation of the matrix so that the smallest
+ *              value on the diagonal of the permuted matrix is maximized.
+ *              The algorithm differs from the one used for JOB = 2 and may
+ *              have quite a different performance.
+ *        = 4 : Compute a row permutation of the matrix so that the sum
+ *              of the diagonal entries of the permuted matrix is maximized.
+ *        = 5 : Compute a row permutation of the matrix so that the product
+ *              of the diagonal entries of the permuted matrix is maximized
+ *              and vectors to scale the matrix so that the nonzero diagonal 
+ *              entries of the permuted matrix are one in absolute value and 
+ *              all the off-diagonal entries are less than or equal to one in 
+ *              absolute value.
+ *        Restriction: 1 <= JOB <= 5.
+ *
+ * n      (input) int
+ *        The order of the matrix.
+ *
+ * nnz    (input) int
+ *        The number of nonzeros in the matrix.
+ *
+ * adjncy (input) int*, of size nnz
+ *        The adjacency structure of the matrix, which contains the row
+ *        indices of the nonzeros.
+ *
+ * colptr (input) int*, of size n+1
+ *        The pointers to the beginning of each column in ADJNCY.
+ *
+ * nzval  (input) doublecomplex*, of size nnz
+ *        The nonzero values of the matrix. nzval[k] is the value of
+ *        the entry corresponding to adjncy[k].
+ *        It is not used if job = 1.
+ *
+ * perm   (output) int*, of size n
+ *        The permutation vector. perm[i] = j means row i in the
+ *        original matrix is in row j of the permuted matrix.
+ *
+ * u      (output) double*, of size n
+ *        If job = 5, the natural logarithms of the row scaling factors. 
+ *
+ * v      (output) double*, of size n
+ *        If job = 5, the natural logarithms of the column scaling factors. 
+ *        The scaled matrix B has entries b_ij = a_ij * exp(u_i + v_j).
+ * 
+ */ + +int +zldperm(int_t job, int_t n, int_t nnz, int_t colptr[], int_t adjncy[], + doublecomplex nzval[], int_t *perm, double u[], double v[]) +{ + int_t i, liw, ldw, num; + int_t *iw, icntl[10], info[10]; + double *dw; + double *nzval_d = (double *) SUPERLU_MALLOC(nnz * sizeof(double)); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Enter zldperm()"); +#endif + liw = 5*n; + if ( job == 3 ) liw = 10*n + nnz; + if ( !(iw = intMalloc(liw)) ) ABORT("Malloc fails for iw[]"); + ldw = 3*n + nnz; + if ( !(dw = (double*) SUPERLU_MALLOC(ldw * sizeof(double))) ) + ABORT("Malloc fails for dw[]"); + + /* Increment one to get 1-based indexing. */ + for (i = 0; i <= n; ++i) ++colptr[i]; + for (i = 0; i < nnz; ++i) ++adjncy[i]; +#if ( DEBUGlevel>=2 ) + printf("LDPERM(): n %d, nnz %d\n", n, nnz); + slu_PrintInt10("colptr", n+1, colptr); + slu_PrintInt10("adjncy", nnz, adjncy); +#endif + + /* + * NOTE: + * ===== + * + * MC64AD assumes that column permutation vector is defined as: + * perm(i) = j means column i of permuted A is in column j of original A. + * + * Since a symmetric permutation preserves the diagonal entries. Then + * by the following relation: + * P'(A*P')P = P'A + * we can apply inverse(perm) to rows of A to get large diagonal entries. + * But, since 'perm' defined in MC64AD happens to be the reverse of + * SuperLU's definition of permutation vector, therefore, it is already + * an inverse for our purpose. We will thus use it directly. + * + */ + mc64id_(icntl); +#if 0 + /* Suppress error and warning messages. */ + icntl[0] = -1; + icntl[1] = -1; +#endif + + for (i = 0; i < nnz; ++i) nzval_d[i] = z_abs1(&nzval[i]); + mc64ad_(&job, &n, &nnz, colptr, adjncy, nzval_d, &num, perm, + &liw, iw, &ldw, dw, icntl, info); + +#if ( DEBUGlevel>=2 ) + slu_PrintInt10("perm", n, perm); + printf(".. After MC64AD info %d\tsize of matching %d\n", info[0], num); +#endif + if ( info[0] == 1 ) { /* Structurally singular */ + printf(".. The last %d permutations:\n", n-num); + slu_PrintInt10("perm", n-num, &perm[num]); + } + + /* Restore to 0-based indexing. */ + for (i = 0; i <= n; ++i) --colptr[i]; + for (i = 0; i < nnz; ++i) --adjncy[i]; + for (i = 0; i < n; ++i) --perm[i]; + + if ( job == 5 ) + for (i = 0; i < n; ++i) { + u[i] = dw[i]; + v[i] = dw[n+i]; + } + + SUPERLU_FREE(iw); + SUPERLU_FREE(dw); + SUPERLU_FREE(nzval_d); + +#if ( DEBUGlevel>=1 ) + CHECK_MALLOC("Exit zldperm()"); +#endif + + return info[0]; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zmemory.c b/src/Libraries/superlu-5.2.1/SRC/zmemory.c new file mode 100644 index 00000000..4d99315e --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zmemory.c @@ -0,0 +1,710 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zmemory.c + * \brief Memory details + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ +#include "slu_zdefs.h" + + +/* Internal prototypes */ +void *zexpand (int *, MemType,int, int, GlobalLU_t *); +int zLUWorkInit (int, int, int, int **, doublecomplex **, GlobalLU_t *); +void copy_mem_doublecomplex (int, void *, void *); +void zStackCompress (GlobalLU_t *); +void zSetupSpace (void *, int, GlobalLU_t *); +void *zuser_malloc (int, int, GlobalLU_t *); +void zuser_free (int, int, GlobalLU_t *); + +/* External prototypes (in memory.c - prec-independent) */ +extern void copy_mem_int (int, void *, void *); +extern void user_bcopy (char *, char *, int); + + +/* Macros to manipulate stack */ +#define StackFull(x) ( x + Glu->stack.used >= Glu->stack.size ) +#define NotDoubleAlign(addr) ( (intptr_t)addr & 7 ) +#define DoubleAlign(addr) ( ((intptr_t)addr + 7) & ~7L ) +#define TempSpace(m, w) ( (2*w + 4 + NO_MARKER) * m * sizeof(int) + \ + (w + 1) * m * sizeof(doublecomplex) ) +#define Reduce(alpha) ((alpha + 1) / 2) /* i.e. (alpha-1)/2 + 1 */ + + + + +/*! \brief Setup the memory model to be used for factorization. + * + * lwork = 0: use system malloc; + * lwork > 0: use user-supplied work[] space. + */ +void zSetupSpace(void *work, int lwork, GlobalLU_t *Glu) +{ + if ( lwork == 0 ) { + Glu->MemModel = SYSTEM; /* malloc/free */ + } else if ( lwork > 0 ) { + Glu->MemModel = USER; /* user provided space */ + Glu->stack.used = 0; + Glu->stack.top1 = 0; + Glu->stack.top2 = (lwork/4)*4; /* must be word addressable */ + Glu->stack.size = Glu->stack.top2; + Glu->stack.array = (void *) work; + } +} + + + +void *zuser_malloc(int bytes, int which_end, GlobalLU_t *Glu) +{ + void *buf; + + if ( StackFull(bytes) ) return (NULL); + + if ( which_end == HEAD ) { + buf = (char*) Glu->stack.array + Glu->stack.top1; + Glu->stack.top1 += bytes; + } else { + Glu->stack.top2 -= bytes; + buf = (char*) Glu->stack.array + Glu->stack.top2; + } + + Glu->stack.used += bytes; + return buf; +} + + +void zuser_free(int bytes, int which_end, GlobalLU_t *Glu) +{ + if ( which_end == HEAD ) { + Glu->stack.top1 -= bytes; + } else { + Glu->stack.top2 += bytes; + } + Glu->stack.used -= bytes; +} + + + +/*! \brief + * + *
+ * mem_usage consists of the following fields:
+ *    - for_lu (float)
+ *      The amount of space used in bytes for the L\U data structures.
+ *    - total_needed (float)
+ *      The amount of space needed in bytes to perform factorization.
+ * 
+ */ +int zQuerySpace(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage) +{ + SCformat *Lstore; + NCformat *Ustore; + register int n, iword, dword, panel_size = sp_ienv(1); + + Lstore = L->Store; + Ustore = U->Store; + n = L->ncol; + iword = sizeof(int); + dword = sizeof(doublecomplex); + + /* For LU factors */ + mem_usage->for_lu = (float)( (4.0*n + 3.0) * iword + + Lstore->nzval_colptr[n] * dword + + Lstore->rowind_colptr[n] * iword ); + mem_usage->for_lu += (float)( (n + 1.0) * iword + + Ustore->colptr[n] * (dword + iword) ); + + /* Working storage to support factorization */ + mem_usage->total_needed = mem_usage->for_lu + + (float)( (2.0 * panel_size + 4.0 + NO_MARKER) * n * iword + + (panel_size + 1.0) * n * dword ); + + return 0; +} /* zQuerySpace */ + + +/*! \brief + * + *
+ * mem_usage consists of the following fields:
+ *    - for_lu (float)
+ *      The amount of space used in bytes for the L\U data structures.
+ *    - total_needed (float)
+ *      The amount of space needed in bytes to perform factorization.
+ * 
+ */ +int ilu_zQuerySpace(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage) +{ + SCformat *Lstore; + NCformat *Ustore; + register int n, panel_size = sp_ienv(1); + register float iword, dword; + + Lstore = L->Store; + Ustore = U->Store; + n = L->ncol; + iword = sizeof(int); + dword = sizeof(double); + + /* For LU factors */ + mem_usage->for_lu = (float)( (4.0f * n + 3.0f) * iword + + Lstore->nzval_colptr[n] * dword + + Lstore->rowind_colptr[n] * iword ); + mem_usage->for_lu += (float)( (n + 1.0f) * iword + + Ustore->colptr[n] * (dword + iword) ); + + /* Working storage to support factorization. + ILU needs 5*n more integers than LU */ + mem_usage->total_needed = mem_usage->for_lu + + (float)( (2.0f * panel_size + 9.0f + NO_MARKER) * n * iword + + (panel_size + 1.0f) * n * dword ); + + return 0; +} /* ilu_zQuerySpace */ + + +/*! \brief Allocate storage for the data structures common to all factor routines. + * + *
+ * For those unpredictable size, estimate as fill_ratio * nnz(A).
+ * Return value:
+ *     If lwork = -1, return the estimated amount of space required, plus n;
+ *     otherwise, return the amount of space actually allocated when
+ *     memory allocation failure occurred.
+ * 
+ */ +int +zLUMemInit(fact_t fact, void *work, int lwork, int m, int n, int annz, + int panel_size, double fill_ratio, SuperMatrix *L, SuperMatrix *U, + GlobalLU_t *Glu, int **iwork, doublecomplex **dwork) +{ + int info, iword, dword; + SCformat *Lstore; + NCformat *Ustore; + int *xsup, *supno; + int *lsub, *xlsub; + doublecomplex *lusup; + int *xlusup; + doublecomplex *ucol; + int *usub, *xusub; + int nzlmax, nzumax, nzlumax; + + iword = sizeof(int); + dword = sizeof(doublecomplex); + Glu->n = n; + Glu->num_expansions = 0; + + Glu->expanders = (ExpHeader *) SUPERLU_MALLOC( NO_MEMTYPE * + sizeof(ExpHeader) ); + if ( !Glu->expanders ) ABORT("SUPERLU_MALLOC fails for expanders"); + + if ( fact != SamePattern_SameRowPerm ) { + /* Guess for L\U factors */ + nzumax = nzlumax = fill_ratio * annz; + nzlmax = SUPERLU_MAX(1, fill_ratio/4.) * annz; + + if ( lwork == -1 ) { + return ( GluIntArray(n) * iword + TempSpace(m, panel_size) + + (nzlmax+nzumax)*iword + (nzlumax+nzumax)*dword + n ); + } else { + zSetupSpace(work, lwork, Glu); + } + +#if ( PRNTlevel >= 1 ) + printf("zLUMemInit() called: fill_ratio %.0f, nzlmax %ld, nzumax %ld\n", + fill_ratio, nzlmax, nzumax); + fflush(stdout); +#endif + + /* Integer pointers for L\U factors */ + if ( Glu->MemModel == SYSTEM ) { + xsup = intMalloc(n+1); + supno = intMalloc(n+1); + xlsub = intMalloc(n+1); + xlusup = intMalloc(n+1); + xusub = intMalloc(n+1); + } else { + xsup = (int *)zuser_malloc((n+1) * iword, HEAD, Glu); + supno = (int *)zuser_malloc((n+1) * iword, HEAD, Glu); + xlsub = (int *)zuser_malloc((n+1) * iword, HEAD, Glu); + xlusup = (int *)zuser_malloc((n+1) * iword, HEAD, Glu); + xusub = (int *)zuser_malloc((n+1) * iword, HEAD, Glu); + } + + lusup = (doublecomplex *) zexpand( &nzlumax, LUSUP, 0, 0, Glu ); + ucol = (doublecomplex *) zexpand( &nzumax, UCOL, 0, 0, Glu ); + lsub = (int *) zexpand( &nzlmax, LSUB, 0, 0, Glu ); + usub = (int *) zexpand( &nzumax, USUB, 0, 1, Glu ); + + while ( !lusup || !ucol || !lsub || !usub ) { + if ( Glu->MemModel == SYSTEM ) { + SUPERLU_FREE(lusup); + SUPERLU_FREE(ucol); + SUPERLU_FREE(lsub); + SUPERLU_FREE(usub); + } else { + zuser_free((nzlumax+nzumax)*dword+(nzlmax+nzumax)*iword, + HEAD, Glu); + } + nzlumax /= 2; + nzumax /= 2; + nzlmax /= 2; + if ( nzlumax < annz ) { + printf("Not enough memory to perform factorization.\n"); + return (zmemory_usage(nzlmax, nzumax, nzlumax, n) + n); + } +#if ( PRNTlevel >= 1) + printf("zLUMemInit() reduce size: nzlmax %ld, nzumax %ld\n", + nzlmax, nzumax); + fflush(stdout); +#endif + lusup = (doublecomplex *) zexpand( &nzlumax, LUSUP, 0, 0, Glu ); + ucol = (doublecomplex *) zexpand( &nzumax, UCOL, 0, 0, Glu ); + lsub = (int *) zexpand( &nzlmax, LSUB, 0, 0, Glu ); + usub = (int *) zexpand( &nzumax, USUB, 0, 1, Glu ); + } + + } else { + /* fact == SamePattern_SameRowPerm */ + Lstore = L->Store; + Ustore = U->Store; + xsup = Lstore->sup_to_col; + supno = Lstore->col_to_sup; + xlsub = Lstore->rowind_colptr; + xlusup = Lstore->nzval_colptr; + xusub = Ustore->colptr; + nzlmax = Glu->nzlmax; /* max from previous factorization */ + nzumax = Glu->nzumax; + nzlumax = Glu->nzlumax; + + if ( lwork == -1 ) { + return ( GluIntArray(n) * iword + TempSpace(m, panel_size) + + (nzlmax+nzumax)*iword + (nzlumax+nzumax)*dword + n ); + } else if ( lwork == 0 ) { + Glu->MemModel = SYSTEM; + } else { + Glu->MemModel = USER; + Glu->stack.top2 = (lwork/4)*4; /* must be word-addressable */ + Glu->stack.size = Glu->stack.top2; + } + + lsub = Glu->expanders[LSUB].mem = Lstore->rowind; + lusup = Glu->expanders[LUSUP].mem = Lstore->nzval; + usub = Glu->expanders[USUB].mem = Ustore->rowind; + ucol = Glu->expanders[UCOL].mem = Ustore->nzval;; + Glu->expanders[LSUB].size = nzlmax; + Glu->expanders[LUSUP].size = nzlumax; + Glu->expanders[USUB].size = nzumax; + Glu->expanders[UCOL].size = nzumax; + } + + Glu->xsup = xsup; + Glu->supno = supno; + Glu->lsub = lsub; + Glu->xlsub = xlsub; + Glu->lusup = (void *) lusup; + Glu->xlusup = xlusup; + Glu->ucol = (void *) ucol; + Glu->usub = usub; + Glu->xusub = xusub; + Glu->nzlmax = nzlmax; + Glu->nzumax = nzumax; + Glu->nzlumax = nzlumax; + + info = zLUWorkInit(m, n, panel_size, iwork, dwork, Glu); + if ( info ) + return ( info + zmemory_usage(nzlmax, nzumax, nzlumax, n) + n); + + ++Glu->num_expansions; + return 0; + +} /* zLUMemInit */ + +/*! \brief Allocate known working storage. Returns 0 if success, otherwise + returns the number of bytes allocated so far when failure occurred. */ +int +zLUWorkInit(int m, int n, int panel_size, int **iworkptr, + doublecomplex **dworkptr, GlobalLU_t *Glu) +{ + int isize, dsize, extra; + doublecomplex *old_ptr; + int maxsuper = SUPERLU_MAX( sp_ienv(3), sp_ienv(7) ), + rowblk = sp_ienv(4); + + isize = ( (2 * panel_size + 3 + NO_MARKER ) * m + n ) * sizeof(int); + dsize = (m * panel_size + + NUM_TEMPV(m,panel_size,maxsuper,rowblk)) * sizeof(doublecomplex); + + if ( Glu->MemModel == SYSTEM ) + *iworkptr = (int *) intCalloc(isize/sizeof(int)); + else + *iworkptr = (int *) zuser_malloc(isize, TAIL, Glu); + if ( ! *iworkptr ) { + fprintf(stderr, "zLUWorkInit: malloc fails for local iworkptr[]\n"); + return (isize + n); + } + + if ( Glu->MemModel == SYSTEM ) + *dworkptr = (doublecomplex *) SUPERLU_MALLOC(dsize); + else { + *dworkptr = (doublecomplex *) zuser_malloc(dsize, TAIL, Glu); + if ( NotDoubleAlign(*dworkptr) ) { + old_ptr = *dworkptr; + *dworkptr = (doublecomplex*) DoubleAlign(*dworkptr); + *dworkptr = (doublecomplex*) ((double*)*dworkptr - 1); + extra = (char*)old_ptr - (char*)*dworkptr; +#ifdef DEBUG + printf("zLUWorkInit: not aligned, extra %d\n", extra); +#endif + Glu->stack.top2 -= extra; + Glu->stack.used += extra; + } + } + if ( ! *dworkptr ) { + fprintf(stderr, "malloc fails for local dworkptr[]."); + return (isize + dsize + n); + } + + return 0; +} + + +/*! \brief Set up pointers for real working arrays. + */ +void +zSetRWork(int m, int panel_size, doublecomplex *dworkptr, + doublecomplex **dense, doublecomplex **tempv) +{ + doublecomplex zero = {0.0, 0.0}; + + int maxsuper = SUPERLU_MAX( sp_ienv(3), sp_ienv(7) ), + rowblk = sp_ienv(4); + *dense = dworkptr; + *tempv = *dense + panel_size*m; + zfill (*dense, m * panel_size, zero); + zfill (*tempv, NUM_TEMPV(m,panel_size,maxsuper,rowblk), zero); +} + +/*! \brief Free the working storage used by factor routines. + */ +void zLUWorkFree(int *iwork, doublecomplex *dwork, GlobalLU_t *Glu) +{ + if ( Glu->MemModel == SYSTEM ) { + SUPERLU_FREE (iwork); + SUPERLU_FREE (dwork); + } else { + Glu->stack.used -= (Glu->stack.size - Glu->stack.top2); + Glu->stack.top2 = Glu->stack.size; +/* zStackCompress(Glu); */ + } + + SUPERLU_FREE (Glu->expanders); + Glu->expanders = NULL; +} + +/*! \brief Expand the data structures for L and U during the factorization. + * + *
+ * Return value:   0 - successful return
+ *               > 0 - number of bytes allocated when run out of space
+ * 
+ */ +int +zLUMemXpand(int jcol, + int next, /* number of elements currently in the factors */ + MemType mem_type, /* which type of memory to expand */ + int *maxlen, /* modified - maximum length of a data structure */ + GlobalLU_t *Glu /* modified - global LU data structures */ + ) +{ + void *new_mem; + +#ifdef DEBUG + printf("zLUMemXpand(): jcol %d, next %d, maxlen %d, MemType %d\n", + jcol, next, *maxlen, mem_type); +#endif + + if (mem_type == USUB) + new_mem = zexpand(maxlen, mem_type, next, 1, Glu); + else + new_mem = zexpand(maxlen, mem_type, next, 0, Glu); + + if ( !new_mem ) { + int nzlmax = Glu->nzlmax; + int nzumax = Glu->nzumax; + int nzlumax = Glu->nzlumax; + fprintf(stderr, "Can't expand MemType %d: jcol %d\n", mem_type, jcol); + return (zmemory_usage(nzlmax, nzumax, nzlumax, Glu->n) + Glu->n); + } + + switch ( mem_type ) { + case LUSUP: + Glu->lusup = (void *) new_mem; + Glu->nzlumax = *maxlen; + break; + case UCOL: + Glu->ucol = (void *) new_mem; + Glu->nzumax = *maxlen; + break; + case LSUB: + Glu->lsub = (int *) new_mem; + Glu->nzlmax = *maxlen; + break; + case USUB: + Glu->usub = (int *) new_mem; + Glu->nzumax = *maxlen; + break; + } + + return 0; + +} + + + +void +copy_mem_doublecomplex(int howmany, void *old, void *new) +{ + register int i; + doublecomplex *dold = old; + doublecomplex *dnew = new; + for (i = 0; i < howmany; i++) dnew[i] = dold[i]; +} + +/*! \brief Expand the existing storage to accommodate more fill-ins. + */ +void +*zexpand ( + int *prev_len, /* length used from previous call */ + MemType type, /* which part of the memory to expand */ + int len_to_copy, /* size of the memory to be copied to new store */ + int keep_prev, /* = 1: use prev_len; + = 0: compute new_len to expand */ + GlobalLU_t *Glu /* modified - global LU data structures */ + ) +{ + float EXPAND = 1.5; + float alpha; + void *new_mem, *old_mem; + int new_len, tries, lword, extra, bytes_to_copy; + ExpHeader *expanders = Glu->expanders; /* Array of 4 types of memory */ + + alpha = EXPAND; + + if ( Glu->num_expansions == 0 || keep_prev ) { + /* First time allocate requested */ + new_len = *prev_len; + } else { + new_len = alpha * *prev_len; + } + + if ( type == LSUB || type == USUB ) lword = sizeof(int); + else lword = sizeof(doublecomplex); + + if ( Glu->MemModel == SYSTEM ) { + new_mem = (void *) SUPERLU_MALLOC((size_t)new_len * lword); + if ( Glu->num_expansions != 0 ) { + tries = 0; + if ( keep_prev ) { + if ( !new_mem ) return (NULL); + } else { + while ( !new_mem ) { + if ( ++tries > 10 ) return (NULL); + alpha = Reduce(alpha); + new_len = alpha * *prev_len; + new_mem = (void *) SUPERLU_MALLOC((size_t)new_len * lword); + } + } + if ( type == LSUB || type == USUB ) { + copy_mem_int(len_to_copy, expanders[type].mem, new_mem); + } else { + copy_mem_doublecomplex(len_to_copy, expanders[type].mem, new_mem); + } + SUPERLU_FREE (expanders[type].mem); + } + expanders[type].mem = (void *) new_mem; + + } else { /* MemModel == USER */ + if ( Glu->num_expansions == 0 ) { + new_mem = zuser_malloc(new_len * lword, HEAD, Glu); + if ( NotDoubleAlign(new_mem) && + (type == LUSUP || type == UCOL) ) { + old_mem = new_mem; + new_mem = (void *)DoubleAlign(new_mem); + extra = (char*)new_mem - (char*)old_mem; +#ifdef DEBUG + printf("expand(): not aligned, extra %d\n", extra); +#endif + Glu->stack.top1 += extra; + Glu->stack.used += extra; + } + expanders[type].mem = (void *) new_mem; + } else { + tries = 0; + extra = (new_len - *prev_len) * lword; + if ( keep_prev ) { + if ( StackFull(extra) ) return (NULL); + } else { + while ( StackFull(extra) ) { + if ( ++tries > 10 ) return (NULL); + alpha = Reduce(alpha); + new_len = alpha * *prev_len; + extra = (new_len - *prev_len) * lword; + } + } + + if ( type != USUB ) { + new_mem = (void*)((char*)expanders[type + 1].mem + extra); + bytes_to_copy = (char*)Glu->stack.array + Glu->stack.top1 + - (char*)expanders[type + 1].mem; + user_bcopy(expanders[type+1].mem, new_mem, bytes_to_copy); + + if ( type < USUB ) { + Glu->usub = expanders[USUB].mem = + (void*)((char*)expanders[USUB].mem + extra); + } + if ( type < LSUB ) { + Glu->lsub = expanders[LSUB].mem = + (void*)((char*)expanders[LSUB].mem + extra); + } + if ( type < UCOL ) { + Glu->ucol = expanders[UCOL].mem = + (void*)((char*)expanders[UCOL].mem + extra); + } + Glu->stack.top1 += extra; + Glu->stack.used += extra; + if ( type == UCOL ) { + Glu->stack.top1 += extra; /* Add same amount for USUB */ + Glu->stack.used += extra; + } + + } /* if ... */ + + } /* else ... */ + } + + expanders[type].size = new_len; + *prev_len = new_len; + if ( Glu->num_expansions ) ++Glu->num_expansions; + + return (void *) expanders[type].mem; + +} /* zexpand */ + + +/*! \brief Compress the work[] array to remove fragmentation. + */ +void +zStackCompress(GlobalLU_t *Glu) +{ + register int iword, dword, ndim; + char *last, *fragment; + int *ifrom, *ito; + doublecomplex *dfrom, *dto; + int *xlsub, *lsub, *xusub, *usub, *xlusup; + doublecomplex *ucol, *lusup; + + iword = sizeof(int); + dword = sizeof(doublecomplex); + ndim = Glu->n; + + xlsub = Glu->xlsub; + lsub = Glu->lsub; + xusub = Glu->xusub; + usub = Glu->usub; + xlusup = Glu->xlusup; + ucol = Glu->ucol; + lusup = Glu->lusup; + + dfrom = ucol; + dto = (doublecomplex *)((char*)lusup + xlusup[ndim] * dword); + copy_mem_doublecomplex(xusub[ndim], dfrom, dto); + ucol = dto; + + ifrom = lsub; + ito = (int *) ((char*)ucol + xusub[ndim] * iword); + copy_mem_int(xlsub[ndim], ifrom, ito); + lsub = ito; + + ifrom = usub; + ito = (int *) ((char*)lsub + xlsub[ndim] * iword); + copy_mem_int(xusub[ndim], ifrom, ito); + usub = ito; + + last = (char*)usub + xusub[ndim] * iword; + fragment = (char*) (((char*)Glu->stack.array + Glu->stack.top1) - last); + Glu->stack.used -= (long int) fragment; + Glu->stack.top1 -= (long int) fragment; + + Glu->ucol = ucol; + Glu->lsub = lsub; + Glu->usub = usub; + +#ifdef DEBUG + printf("zStackCompress: fragment %d\n", fragment); + /* for (last = 0; last < ndim; ++last) + print_lu_col("After compress:", last, 0);*/ +#endif + +} + +/*! \brief Allocate storage for original matrix A + */ +void +zallocateA(int n, int nnz, doublecomplex **a, int **asub, int **xa) +{ + *a = (doublecomplex *) doublecomplexMalloc(nnz); + *asub = (int *) intMalloc(nnz); + *xa = (int *) intMalloc(n+1); +} + + +doublecomplex *doublecomplexMalloc(int n) +{ + doublecomplex *buf; + buf = (doublecomplex *) SUPERLU_MALLOC((size_t)n * sizeof(doublecomplex)); + if ( !buf ) { + ABORT("SUPERLU_MALLOC failed for buf in doublecomplexMalloc()\n"); + } + return (buf); +} + +doublecomplex *doublecomplexCalloc(int n) +{ + doublecomplex *buf; + register int i; + doublecomplex zero = {0.0, 0.0}; + buf = (doublecomplex *) SUPERLU_MALLOC((size_t)n * sizeof(doublecomplex)); + if ( !buf ) { + ABORT("SUPERLU_MALLOC failed for buf in doublecomplexCalloc()\n"); + } + for (i = 0; i < n; ++i) buf[i] = zero; + return (buf); +} + + +int zmemory_usage(const int nzlmax, const int nzumax, + const int nzlumax, const int n) +{ + register int iword, dword; + + iword = sizeof(int); + dword = sizeof(doublecomplex); + + return (10 * n * iword + + nzlmax * iword + nzumax * (iword + dword) + nzlumax * dword); + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zmyblas2.c b/src/Libraries/superlu-5.2.1/SRC/zmyblas2.c new file mode 100644 index 00000000..6924cfc0 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zmyblas2.c @@ -0,0 +1,198 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zmyblas2.c + * \brief Level 2 Blas operations + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ * Purpose: + * Level 2 BLAS operations: solves and matvec, written in C. + * Note: + * This is only used when the system lacks an efficient BLAS library. + * + */ +/* + * File name: zmyblas2.c + */ +#include "slu_dcomplex.h" + +/*! \brief Solves a dense UNIT lower triangular system + * + * The unit lower + * triangular matrix is stored in a 2D array M(1:nrow,1:ncol). + * The solution will be returned in the rhs vector. + */ +void zlsolve ( int ldm, int ncol, doublecomplex *M, doublecomplex *rhs ) +{ + int k; + doublecomplex x0, x1, x2, x3, temp; + doublecomplex *M0; + doublecomplex *Mki0, *Mki1, *Mki2, *Mki3; + register int firstcol = 0; + + M0 = &M[0]; + + + while ( firstcol < ncol - 3 ) { /* Do 4 columns */ + Mki0 = M0 + 1; + Mki1 = Mki0 + ldm + 1; + Mki2 = Mki1 + ldm + 1; + Mki3 = Mki2 + ldm + 1; + + x0 = rhs[firstcol]; + zz_mult(&temp, &x0, Mki0); Mki0++; + z_sub(&x1, &rhs[firstcol+1], &temp); + zz_mult(&temp, &x0, Mki0); Mki0++; + z_sub(&x2, &rhs[firstcol+2], &temp); + zz_mult(&temp, &x1, Mki1); Mki1++; + z_sub(&x2, &x2, &temp); + zz_mult(&temp, &x0, Mki0); Mki0++; + z_sub(&x3, &rhs[firstcol+3], &temp); + zz_mult(&temp, &x1, Mki1); Mki1++; + z_sub(&x3, &x3, &temp); + zz_mult(&temp, &x2, Mki2); Mki2++; + z_sub(&x3, &x3, &temp); + + rhs[++firstcol] = x1; + rhs[++firstcol] = x2; + rhs[++firstcol] = x3; + ++firstcol; + + for (k = firstcol; k < ncol; k++) { + zz_mult(&temp, &x0, Mki0); Mki0++; + z_sub(&rhs[k], &rhs[k], &temp); + zz_mult(&temp, &x1, Mki1); Mki1++; + z_sub(&rhs[k], &rhs[k], &temp); + zz_mult(&temp, &x2, Mki2); Mki2++; + z_sub(&rhs[k], &rhs[k], &temp); + zz_mult(&temp, &x3, Mki3); Mki3++; + z_sub(&rhs[k], &rhs[k], &temp); + } + + M0 += 4 * ldm + 4; + } + + if ( firstcol < ncol - 1 ) { /* Do 2 columns */ + Mki0 = M0 + 1; + Mki1 = Mki0 + ldm + 1; + + x0 = rhs[firstcol]; + zz_mult(&temp, &x0, Mki0); Mki0++; + z_sub(&x1, &rhs[firstcol+1], &temp); + + rhs[++firstcol] = x1; + ++firstcol; + + for (k = firstcol; k < ncol; k++) { + zz_mult(&temp, &x0, Mki0); Mki0++; + z_sub(&rhs[k], &rhs[k], &temp); + zz_mult(&temp, &x1, Mki1); Mki1++; + z_sub(&rhs[k], &rhs[k], &temp); + } + } + +} + +/*! \brief Solves a dense upper triangular system. + * + * The upper triangular matrix is + * stored in a 2-dim array M(1:ldm,1:ncol). The solution will be returned + * in the rhs vector. + */ +void +zusolve ( ldm, ncol, M, rhs ) +int ldm; /* in */ +int ncol; /* in */ +doublecomplex *M; /* in */ +doublecomplex *rhs; /* modified */ +{ + doublecomplex xj, temp; + int jcol, j, irow; + + jcol = ncol - 1; + + for (j = 0; j < ncol; j++) { + + z_div(&xj, &rhs[jcol], &M[jcol + jcol*ldm]); /* M(jcol, jcol) */ + rhs[jcol] = xj; + + for (irow = 0; irow < jcol; irow++) { + zz_mult(&temp, &xj, &M[irow+jcol*ldm]); /* M(irow, jcol) */ + z_sub(&rhs[irow], &rhs[irow], &temp); + } + + jcol--; + + } +} + + +/*! \brief Performs a dense matrix-vector multiply: Mxvec = Mxvec + M * vec. + * + * The input matrix is M(1:nrow,1:ncol); The product is returned in Mxvec[]. + */ +void zmatvec ( ldm, nrow, ncol, M, vec, Mxvec ) +int ldm; /* in -- leading dimension of M */ +int nrow; /* in */ +int ncol; /* in */ +doublecomplex *M; /* in */ +doublecomplex *vec; /* in */ +doublecomplex *Mxvec; /* in/out */ +{ + doublecomplex vi0, vi1, vi2, vi3; + doublecomplex *M0, temp; + doublecomplex *Mki0, *Mki1, *Mki2, *Mki3; + register int firstcol = 0; + int k; + + M0 = &M[0]; + + while ( firstcol < ncol - 3 ) { /* Do 4 columns */ + Mki0 = M0; + Mki1 = Mki0 + ldm; + Mki2 = Mki1 + ldm; + Mki3 = Mki2 + ldm; + + vi0 = vec[firstcol++]; + vi1 = vec[firstcol++]; + vi2 = vec[firstcol++]; + vi3 = vec[firstcol++]; + for (k = 0; k < nrow; k++) { + zz_mult(&temp, &vi0, Mki0); Mki0++; + z_add(&Mxvec[k], &Mxvec[k], &temp); + zz_mult(&temp, &vi1, Mki1); Mki1++; + z_add(&Mxvec[k], &Mxvec[k], &temp); + zz_mult(&temp, &vi2, Mki2); Mki2++; + z_add(&Mxvec[k], &Mxvec[k], &temp); + zz_mult(&temp, &vi3, Mki3); Mki3++; + z_add(&Mxvec[k], &Mxvec[k], &temp); + } + + M0 += 4 * ldm; + } + + while ( firstcol < ncol ) { /* Do 1 column */ + Mki0 = M0; + vi0 = vec[firstcol++]; + for (k = 0; k < nrow; k++) { + zz_mult(&temp, &vi0, Mki0); Mki0++; + z_add(&Mxvec[k], &Mxvec[k], &temp); + } + M0 += ldm; + } + +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/zpanel_bmod.c b/src/Libraries/superlu-5.2.1/SRC/zpanel_bmod.c new file mode 100644 index 00000000..9e21cab4 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zpanel_bmod.c @@ -0,0 +1,494 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zpanel_bmod.c + * \brief Performs numeric block updates + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ +/* + +*/ + +#include +#include +#include "slu_zdefs.h" + +/* + * Function prototypes + */ +void zlsolve(int, int, doublecomplex *, doublecomplex *); +void zmatvec(int, int, int, doublecomplex *, doublecomplex *, doublecomplex *); +extern void zcheck_tempv(); + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *    Performs numeric block updates (sup-panel) in topological order.
+ *    It features: col-col, 2cols-col, 3cols-col, and sup-col updates.
+ *    Special processing on the supernodal portion of L\U[*,j]
+ *
+ *    Before entering this routine, the original nonzeros in the panel 
+ *    were already copied into the spa[m,w].
+ *
+ *    Updated/Output parameters-
+ *    dense[0:m-1,w]: L[*,j:j+w-1] and U[*,j:j+w-1] are returned 
+ *    collectively in the m-by-w vector dense[*]. 
+ * 
+ */ + +void +zpanel_bmod ( + const int m, /* in - number of rows in the matrix */ + const int w, /* in */ + const int jcol, /* in */ + const int nseg, /* in */ + doublecomplex *dense, /* out, of size n by w */ + doublecomplex *tempv, /* working array */ + int *segrep, /* in */ + int *repfnz, /* in, of size n by w */ + GlobalLU_t *Glu, /* modified */ + SuperLUStat_t *stat /* output */ + ) +{ + + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + int incx = 1, incy = 1; + doublecomplex alpha, beta; +#endif + + register int k, ksub; + int fsupc, nsupc, nsupr, nrow; + int krep, krep_ind; + doublecomplex ukj, ukj1, ukj2; + int luptr, luptr1, luptr2; + int segsze; + int block_nrow; /* no of rows in a block row */ + register int lptr; /* Points to the row subscripts of a supernode */ + int kfnz, irow, no_zeros; + register int isub, isub1, i; + register int jj; /* Index through each column in the panel */ + int *xsup, *supno; + int *lsub, *xlsub; + doublecomplex *lusup; + int *xlusup; + int *repfnz_col; /* repfnz[] for a column in the panel */ + doublecomplex *dense_col; /* dense[] for a column in the panel */ + doublecomplex *tempv1; /* Used in 1-D update */ + doublecomplex *TriTmp, *MatvecTmp; /* used in 2-D update */ + doublecomplex zero = {0.0, 0.0}; + doublecomplex one = {1.0, 0.0}; + doublecomplex comp_temp, comp_temp1; + register int ldaTmp; + register int r_ind, r_hi; + int maxsuper, rowblk, colblk; + flops_t *ops = stat->ops; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (doublecomplex *) Glu->lusup; + xlusup = Glu->xlusup; + + maxsuper = SUPERLU_MAX( sp_ienv(3), sp_ienv(7) ); + rowblk = sp_ienv(4); + colblk = sp_ienv(5); + ldaTmp = maxsuper + rowblk; + + /* + * For each nonz supernode segment of U[*,j] in topological order + */ + k = nseg - 1; + for (ksub = 0; ksub < nseg; ksub++) { /* for each updating supernode */ + + /* krep = representative of current k-th supernode + * fsupc = first supernodal column + * nsupc = no of columns in a supernode + * nsupr = no of rows in a supernode + */ + krep = segrep[k--]; + fsupc = xsup[supno[krep]]; + nsupc = krep - fsupc + 1; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; + nrow = nsupr - nsupc; + lptr = xlsub[fsupc]; + krep_ind = lptr + nsupc - 1; + + repfnz_col = repfnz; + dense_col = dense; + + if ( nsupc >= colblk && nrow > rowblk ) { /* 2-D block update */ + + TriTmp = tempv; + + /* Sequence through each column in panel -- triangular solves */ + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m, TriTmp += ldaTmp ) { + + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + luptr = xlusup[fsupc]; + + ops[TRSV] += 4 * segsze * (segsze - 1); + ops[GEMV] += 8 * nrow * segsze; + + /* Case 1: Update U-segment of size 1 -- col-col update */ + if ( segsze == 1 ) { + ukj = dense_col[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc; + + for (i = lptr + nsupc; i < xlsub[fsupc+1]; i++) { + irow = lsub[i]; + zz_mult(&comp_temp, &ukj, &lusup[luptr]); + z_sub(&dense_col[irow], &dense_col[irow], &comp_temp); + ++luptr; + } + + } else if ( segsze <= 3 ) { + ukj = dense_col[lsub[krep_ind]]; + ukj1 = dense_col[lsub[krep_ind - 1]]; + luptr += nsupr*(nsupc-1) + nsupc-1; + luptr1 = luptr - nsupr; + + if ( segsze == 2 ) { + zz_mult(&comp_temp, &ukj1, &lusup[luptr1]); + z_sub(&ukj, &ukj, &comp_temp); + dense_col[lsub[krep_ind]] = ukj; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; luptr1++; + zz_mult(&comp_temp, &ukj, &lusup[luptr]); + zz_mult(&comp_temp1, &ukj1, &lusup[luptr1]); + z_add(&comp_temp, &comp_temp, &comp_temp1); + z_sub(&dense_col[irow], &dense_col[irow], &comp_temp); + } + } else { + ukj2 = dense_col[lsub[krep_ind - 2]]; + luptr2 = luptr1 - nsupr; + zz_mult(&comp_temp, &ukj2, &lusup[luptr2-1]); + z_sub(&ukj1, &ukj1, &comp_temp); + + zz_mult(&comp_temp, &ukj1, &lusup[luptr1]); + zz_mult(&comp_temp1, &ukj2, &lusup[luptr2]); + z_add(&comp_temp, &comp_temp, &comp_temp1); + z_sub(&ukj, &ukj, &comp_temp); + dense_col[lsub[krep_ind]] = ukj; + dense_col[lsub[krep_ind-1]] = ukj1; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + luptr++; luptr1++; luptr2++; + zz_mult(&comp_temp, &ukj, &lusup[luptr]); + zz_mult(&comp_temp1, &ukj1, &lusup[luptr1]); + z_add(&comp_temp, &comp_temp, &comp_temp1); + zz_mult(&comp_temp1, &ukj2, &lusup[luptr2]); + z_add(&comp_temp, &comp_temp, &comp_temp1); + z_sub(&dense_col[irow], &dense_col[irow], &comp_temp); + } + } + + } else { /* segsze >= 4 */ + + /* Copy U[*,j] segment from dense[*] to TriTmp[*], which + holds the result of triangular solves. */ + no_zeros = kfnz - fsupc; + isub = lptr + no_zeros; + for (i = 0; i < segsze; ++i) { + irow = lsub[isub]; + TriTmp[i] = dense_col[irow]; /* Gather */ + ++isub; + } + + /* start effective triangle */ + luptr += nsupr * no_zeros + no_zeros; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + CTRSV( ftcs1, ftcs2, ftcs3, &segsze, &lusup[luptr], + &nsupr, TriTmp, &incx ); +#else + ztrsv_( "L", "N", "U", &segsze, &lusup[luptr], + &nsupr, TriTmp, &incx ); +#endif +#else + zlsolve ( nsupr, segsze, &lusup[luptr], TriTmp ); +#endif + + + } /* else ... */ + + } /* for jj ... end tri-solves */ + + /* Block row updates; push all the way into dense[*] block */ + for ( r_ind = 0; r_ind < nrow; r_ind += rowblk ) { + + r_hi = SUPERLU_MIN(nrow, r_ind + rowblk); + block_nrow = SUPERLU_MIN(rowblk, r_hi - r_ind); + luptr = xlusup[fsupc] + nsupc + r_ind; + isub1 = lptr + nsupc + r_ind; + + repfnz_col = repfnz; + TriTmp = tempv; + dense_col = dense; + + /* Sequence through each column in panel -- matrix-vector */ + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m, TriTmp += ldaTmp) { + + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + if ( segsze <= 3 ) continue; /* skip unrolled cases */ + + /* Perform a block update, and scatter the result of + matrix-vector to dense[]. */ + no_zeros = kfnz - fsupc; + luptr1 = luptr + nsupr * no_zeros; + MatvecTmp = &TriTmp[maxsuper]; + +#ifdef USE_VENDOR_BLAS + alpha = one; + beta = zero; +#ifdef _CRAY + CGEMV(ftcs2, &block_nrow, &segsze, &alpha, &lusup[luptr1], + &nsupr, TriTmp, &incx, &beta, MatvecTmp, &incy); +#else + zgemv_("N", &block_nrow, &segsze, &alpha, &lusup[luptr1], + &nsupr, TriTmp, &incx, &beta, MatvecTmp, &incy); +#endif +#else + zmatvec(nsupr, block_nrow, segsze, &lusup[luptr1], + TriTmp, MatvecTmp); +#endif + + /* Scatter MatvecTmp[*] into SPA dense[*] temporarily + * such that MatvecTmp[*] can be re-used for the + * the next blok row update. dense[] will be copied into + * global store after the whole panel has been finished. + */ + isub = isub1; + for (i = 0; i < block_nrow; i++) { + irow = lsub[isub]; + z_sub(&dense_col[irow], &dense_col[irow], + &MatvecTmp[i]); + MatvecTmp[i] = zero; + ++isub; + } + + } /* for jj ... */ + + } /* for each block row ... */ + + /* Scatter the triangular solves into SPA dense[*] */ + repfnz_col = repfnz; + TriTmp = tempv; + dense_col = dense; + + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m, TriTmp += ldaTmp) { + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + if ( segsze <= 3 ) continue; /* skip unrolled cases */ + + no_zeros = kfnz - fsupc; + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + dense_col[irow] = TriTmp[i]; + TriTmp[i] = zero; + ++isub; + } + + } /* for jj ... */ + + } else { /* 1-D block modification */ + + + /* Sequence through each column in the panel */ + for (jj = jcol; jj < jcol + w; jj++, + repfnz_col += m, dense_col += m) { + + kfnz = repfnz_col[krep]; + if ( kfnz == EMPTY ) continue; /* Skip any zero segment */ + + segsze = krep - kfnz + 1; + luptr = xlusup[fsupc]; + + ops[TRSV] += 4 * segsze * (segsze - 1); + ops[GEMV] += 8 * nrow * segsze; + + /* Case 1: Update U-segment of size 1 -- col-col update */ + if ( segsze == 1 ) { + ukj = dense_col[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc; + + for (i = lptr + nsupc; i < xlsub[fsupc+1]; i++) { + irow = lsub[i]; + zz_mult(&comp_temp, &ukj, &lusup[luptr]); + z_sub(&dense_col[irow], &dense_col[irow], &comp_temp); + ++luptr; + } + + } else if ( segsze <= 3 ) { + ukj = dense_col[lsub[krep_ind]]; + luptr += nsupr*(nsupc-1) + nsupc-1; + ukj1 = dense_col[lsub[krep_ind - 1]]; + luptr1 = luptr - nsupr; + + if ( segsze == 2 ) { + zz_mult(&comp_temp, &ukj1, &lusup[luptr1]); + z_sub(&ukj, &ukj, &comp_temp); + dense_col[lsub[krep_ind]] = ukj; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + ++luptr; ++luptr1; + zz_mult(&comp_temp, &ukj, &lusup[luptr]); + zz_mult(&comp_temp1, &ukj1, &lusup[luptr1]); + z_add(&comp_temp, &comp_temp, &comp_temp1); + z_sub(&dense_col[irow], &dense_col[irow], &comp_temp); + } + } else { + ukj2 = dense_col[lsub[krep_ind - 2]]; + luptr2 = luptr1 - nsupr; + zz_mult(&comp_temp, &ukj2, &lusup[luptr2-1]); + z_sub(&ukj1, &ukj1, &comp_temp); + + zz_mult(&comp_temp, &ukj1, &lusup[luptr1]); + zz_mult(&comp_temp1, &ukj2, &lusup[luptr2]); + z_add(&comp_temp, &comp_temp, &comp_temp1); + z_sub(&ukj, &ukj, &comp_temp); + dense_col[lsub[krep_ind]] = ukj; + dense_col[lsub[krep_ind-1]] = ukj1; + for (i = lptr + nsupc; i < xlsub[fsupc+1]; ++i) { + irow = lsub[i]; + ++luptr; ++luptr1; ++luptr2; + zz_mult(&comp_temp, &ukj, &lusup[luptr]); + zz_mult(&comp_temp1, &ukj1, &lusup[luptr1]); + z_add(&comp_temp, &comp_temp, &comp_temp1); + zz_mult(&comp_temp1, &ukj2, &lusup[luptr2]); + z_add(&comp_temp, &comp_temp, &comp_temp1); + z_sub(&dense_col[irow], &dense_col[irow], &comp_temp); + } + } + + } else { /* segsze >= 4 */ + /* + * Perform a triangular solve and block update, + * then scatter the result of sup-col update to dense[]. + */ + no_zeros = kfnz - fsupc; + + /* Copy U[*,j] segment from dense[*] to tempv[*]: + * The result of triangular solve is in tempv[*]; + * The result of matrix vector update is in dense_col[*] + */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; ++i) { + irow = lsub[isub]; + tempv[i] = dense_col[irow]; /* Gather */ + ++isub; + } + + /* start effective triangle */ + luptr += nsupr * no_zeros + no_zeros; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + CTRSV( ftcs1, ftcs2, ftcs3, &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#else + ztrsv_( "L", "N", "U", &segsze, &lusup[luptr], + &nsupr, tempv, &incx ); +#endif + + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + alpha = one; + beta = zero; +#ifdef _CRAY + CGEMV( ftcs2, &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#else + zgemv_( "N", &nrow, &segsze, &alpha, &lusup[luptr], + &nsupr, tempv, &incx, &beta, tempv1, &incy ); +#endif +#else + zlsolve ( nsupr, segsze, &lusup[luptr], tempv ); + + luptr += segsze; /* Dense matrix-vector */ + tempv1 = &tempv[segsze]; + zmatvec (nsupr, nrow, segsze, &lusup[luptr], tempv, tempv1); +#endif + + /* Scatter tempv[*] into SPA dense[*] temporarily, such + * that tempv[*] can be used for the triangular solve of + * the next column of the panel. They will be copied into + * ucol[*] after the whole panel has been finished. + */ + isub = lptr + no_zeros; + for (i = 0; i < segsze; i++) { + irow = lsub[isub]; + dense_col[irow] = tempv[i]; + tempv[i] = zero; + isub++; + } + + /* Scatter the update from tempv1[*] into SPA dense[*] */ + /* Start dense rectangular L */ + for (i = 0; i < nrow; i++) { + irow = lsub[isub]; + z_sub(&dense_col[irow], &dense_col[irow], &tempv1[i]); + tempv1[i] = zero; + ++isub; + } + + } /* else segsze>=4 ... */ + + } /* for each column in the panel... */ + + } /* else 1-D update ... */ + + } /* for each updating supernode ... */ + +} + + + diff --git a/src/Libraries/superlu-5.2.1/SRC/zpanel_dfs.c b/src/Libraries/superlu-5.2.1/SRC/zpanel_dfs.c new file mode 100644 index 00000000..03c34ca6 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zpanel_dfs.c @@ -0,0 +1,264 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zpanel_dfs.c + * \brief Peforms a symbolic factorization on a panel of symbols + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_zdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ *   Performs a symbolic factorization on a panel of columns [jcol, jcol+w).
+ *
+ *   A supernode representative is the last column of a supernode.
+ *   The nonzeros in U[*,j] are segments that end at supernodal
+ *   representatives.
+ *
+ *   The routine returns one list of the supernodal representatives
+ *   in topological order of the dfs that generates them. This list is
+ *   a superset of the topological order of each individual column within
+ *   the panel. 
+ *   The location of the first nonzero in each supernodal segment
+ *   (supernodal entry location) is also returned. Each column has a 
+ *   separate list for this purpose.
+ *
+ *   Two marker arrays are used for dfs:
+ *     marker[i] == jj, if i was visited during dfs of current column jj;
+ *     marker1[i] >= jcol, if i was visited by earlier columns in this panel;
+ *
+ *   marker: A-row --> A-row/col (0/1)
+ *   repfnz: SuperA-col --> PA-row
+ *   parent: SuperA-col --> SuperA-col
+ *   xplore: SuperA-col --> index to L-structure
+ * 
+ */ + +void +zpanel_dfs ( + const int m, /* in - number of rows in the matrix */ + const int w, /* in */ + const int jcol, /* in */ + SuperMatrix *A, /* in - original matrix */ + int *perm_r, /* in */ + int *nseg, /* out */ + doublecomplex *dense, /* out */ + int *panel_lsub, /* out */ + int *segrep, /* out */ + int *repfnz, /* out */ + int *xprune, /* out */ + int *marker, /* out */ + int *parent, /* working array */ + int *xplore, /* working array */ + GlobalLU_t *Glu /* modified */ + ) +{ + + NCPformat *Astore; + doublecomplex *a; + int *asub; + int *xa_begin, *xa_end; + int krep, chperm, chmark, chrep, oldrep, kchild, myfnz; + int k, krow, kmark, kperm; + int xdfs, maxdfs, kpar; + int jj; /* index through each column in the panel */ + int *marker1; /* marker1[jj] >= jcol if vertex jj was visited + by a previous column within this panel. */ + int *repfnz_col; /* start of each column in the panel */ + doublecomplex *dense_col; /* start of each column in the panel */ + int nextl_col; /* next available position in panel_lsub[*,jj] */ + int *xsup, *supno; + int *lsub, *xlsub; + + /* Initialize pointers */ + Astore = A->Store; + a = Astore->nzval; + asub = Astore->rowind; + xa_begin = Astore->colbeg; + xa_end = Astore->colend; + marker1 = marker + m; + repfnz_col = repfnz; + dense_col = dense; + *nseg = 0; + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + + /* For each column in the panel */ + for (jj = jcol; jj < jcol + w; jj++) { + nextl_col = (jj - jcol) * m; + +#ifdef CHK_DFS + printf("\npanel col %d: ", jj); +#endif + + /* For each nonz in A[*,jj] do dfs */ + for (k = xa_begin[jj]; k < xa_end[jj]; k++) { + krow = asub[k]; + dense_col[krow] = a[k]; + kmark = marker[krow]; + if ( kmark == jj ) + continue; /* krow visited before, go to the next nonzero */ + + /* For each unmarked nbr krow of jj + * krow is in L: place it in structure of L[*,jj] + */ + marker[krow] = jj; + kperm = perm_r[krow]; + + if ( kperm == EMPTY ) { + panel_lsub[nextl_col++] = krow; /* krow is indexed into A */ + } + /* + * krow is in U: if its supernode-rep krep + * has been explored, update repfnz[*] + */ + else { + + krep = xsup[supno[kperm]+1] - 1; + myfnz = repfnz_col[krep]; + +#ifdef CHK_DFS + printf("krep %d, myfnz %d, perm_r[%d] %d\n", krep, myfnz, krow, kperm); +#endif + if ( myfnz != EMPTY ) { /* Representative visited before */ + if ( myfnz > kperm ) repfnz_col[krep] = kperm; + /* continue; */ + } + else { + /* Otherwise, perform dfs starting at krep */ + oldrep = EMPTY; + parent[krep] = oldrep; + repfnz_col[krep] = kperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; + +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + do { + /* + * For each unmarked kchild of krep + */ + while ( xdfs < maxdfs ) { + + kchild = lsub[xdfs]; + xdfs++; + chmark = marker[kchild]; + + if ( chmark != jj ) { /* Not reached yet */ + marker[kchild] = jj; + chperm = perm_r[kchild]; + + /* Case kchild is in L: place it in L[*,j] */ + if ( chperm == EMPTY ) { + panel_lsub[nextl_col++] = kchild; + } + /* Case kchild is in U: + * chrep = its supernode-rep. If its rep has + * been explored, update its repfnz[*] + */ + else { + + chrep = xsup[supno[chperm]+1] - 1; + myfnz = repfnz_col[chrep]; +#ifdef CHK_DFS + printf("chrep %d,myfnz %d,perm_r[%d] %d\n",chrep,myfnz,kchild,chperm); +#endif + if ( myfnz != EMPTY ) { /* Visited before */ + if ( myfnz > chperm ) + repfnz_col[chrep] = chperm; + } + else { + /* Cont. dfs at snode-rep of kchild */ + xplore[krep] = xdfs; + oldrep = krep; + krep = chrep; /* Go deeper down G(L) */ + parent[krep] = oldrep; + repfnz_col[krep] = chperm; + xdfs = xlsub[krep]; + maxdfs = xprune[krep]; +#ifdef CHK_DFS + printf(" xdfs %d, maxdfs %d: ", xdfs, maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } /* else */ + + } /* else */ + + } /* if... */ + + } /* while xdfs < maxdfs */ + + /* krow has no more unexplored nbrs: + * Place snode-rep krep in postorder DFS, if this + * segment is seen for the first time. (Note that + * "repfnz[krep]" may change later.) + * Backtrack dfs to its parent. + */ + if ( marker1[krep] < jcol ) { + segrep[*nseg] = krep; + ++(*nseg); + marker1[krep] = jj; + } + + kpar = parent[krep]; /* Pop stack, mimic recursion */ + if ( kpar == EMPTY ) break; /* dfs done */ + krep = kpar; + xdfs = xplore[krep]; + maxdfs = xprune[krep]; + +#ifdef CHK_DFS + printf(" pop stack: krep %d,xdfs %d,maxdfs %d: ", krep,xdfs,maxdfs); + for (i = xdfs; i < maxdfs; i++) printf(" %d", lsub[i]); + printf("\n"); +#endif + } while ( kpar != EMPTY ); /* do-while - until empty stack */ + + } /* else */ + + } /* else */ + + } /* for each nonz in A[*,jj] */ + + repfnz_col += m; /* Move to next column */ + dense_col += m; + + } /* for jj ... */ + +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zpivotL.c b/src/Libraries/superlu-5.2.1/SRC/zpivotL.c new file mode 100644 index 00000000..2aa5231d --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zpivotL.c @@ -0,0 +1,195 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zpivotL.c + * \brief Performs numerical pivoting + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include +#include +#include "slu_zdefs.h" + +#undef DEBUG + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   Performs the numerical pivoting on the current column of L,
+ *   and the CDIV operation.
+ *
+ *   Pivot policy:
+ *   (1) Compute thresh = u * max_(i>=j) abs(A_ij);
+ *   (2) IF user specifies pivot row k and abs(A_kj) >= thresh THEN
+ *           pivot row = k;
+ *       ELSE IF abs(A_jj) >= thresh THEN
+ *           pivot row = j;
+ *       ELSE
+ *           pivot row = m;
+ * 
+ *   Note: If you absolutely want to use a given pivot order, then set u=0.0.
+ *
+ *   Return value: 0      success;
+ *                 i > 0  U(i,i) is exactly zero.
+ * 
+ */ + +int +zpivotL( + const int jcol, /* in */ + const double u, /* in - diagonal pivoting threshold */ + int *usepr, /* re-use the pivot sequence given by perm_r/iperm_r */ + int *perm_r, /* may be modified */ + int *iperm_r, /* in - inverse of perm_r */ + int *iperm_c, /* in - used to find diagonal of Pc*A*Pc' */ + int *pivrow, /* out */ + GlobalLU_t *Glu, /* modified - global LU data structures */ + SuperLUStat_t *stat /* output */ + ) +{ + + doublecomplex one = {1.0, 0.0}; + int fsupc; /* first column in the supernode */ + int nsupc; /* no of columns in the supernode */ + int nsupr; /* no of rows in the supernode */ + int lptr; /* points to the starting subscript of the supernode */ + int pivptr, old_pivptr, diag, diagind; + double pivmax, rtemp, thresh; + doublecomplex temp; + doublecomplex *lu_sup_ptr; + doublecomplex *lu_col_ptr; + int *lsub_ptr; + int isub, icol, k, itemp; + int *lsub, *xlsub; + doublecomplex *lusup; + int *xlusup; + flops_t *ops = stat->ops; + + /* Initialize pointers */ + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (doublecomplex *) Glu->lusup; + xlusup = Glu->xlusup; + fsupc = (Glu->xsup)[(Glu->supno)[jcol]]; + nsupc = jcol - fsupc; /* excluding jcol; nsupc >= 0 */ + lptr = xlsub[fsupc]; + nsupr = xlsub[fsupc+1] - lptr; + lu_sup_ptr = &lusup[xlusup[fsupc]]; /* start of the current supernode */ + lu_col_ptr = &lusup[xlusup[jcol]]; /* start of jcol in the supernode */ + lsub_ptr = &lsub[lptr]; /* start of row indices of the supernode */ + +#ifdef DEBUG +if ( jcol == MIN_COL ) { + printf("Before cdiv: col %d\n", jcol); + for (k = nsupc; k < nsupr; k++) + printf(" lu[%d] %f\n", lsub_ptr[k], lu_col_ptr[k]); +} +#endif + + /* Determine the largest abs numerical value for partial pivoting; + Also search for user-specified pivot, and diagonal element. */ + if ( *usepr ) *pivrow = iperm_r[jcol]; + diagind = iperm_c[jcol]; + pivmax = 0.0; + pivptr = nsupc; + diag = EMPTY; + old_pivptr = nsupc; + for (isub = nsupc; isub < nsupr; ++isub) { + rtemp = z_abs1 (&lu_col_ptr[isub]); + if ( rtemp > pivmax ) { + pivmax = rtemp; + pivptr = isub; + } + if ( *usepr && lsub_ptr[isub] == *pivrow ) old_pivptr = isub; + if ( lsub_ptr[isub] == diagind ) diag = isub; + } + + /* Test for singularity */ + if ( pivmax == 0.0 ) { +#if 1 + *pivrow = lsub_ptr[pivptr]; + perm_r[*pivrow] = jcol; +#else + perm_r[diagind] = jcol; +#endif + *usepr = 0; + return (jcol+1); + } + + thresh = u * pivmax; + + /* Choose appropriate pivotal element by our policy. */ + if ( *usepr ) { + rtemp = z_abs1 (&lu_col_ptr[old_pivptr]); + if ( rtemp != 0.0 && rtemp >= thresh ) + pivptr = old_pivptr; + else + *usepr = 0; + } + if ( *usepr == 0 ) { + /* Use diagonal pivot? */ + if ( diag >= 0 ) { /* diagonal exists */ + rtemp = z_abs1 (&lu_col_ptr[diag]); + if ( rtemp != 0.0 && rtemp >= thresh ) pivptr = diag; + } + *pivrow = lsub_ptr[pivptr]; + } + + /* Record pivot row */ + perm_r[*pivrow] = jcol; + + /* Interchange row subscripts */ + if ( pivptr != nsupc ) { + itemp = lsub_ptr[pivptr]; + lsub_ptr[pivptr] = lsub_ptr[nsupc]; + lsub_ptr[nsupc] = itemp; + + /* Interchange numerical values as well, for the whole snode, such + * that L is indexed the same way as A. + */ + for (icol = 0; icol <= nsupc; icol++) { + itemp = pivptr + icol * nsupr; + temp = lu_sup_ptr[itemp]; + lu_sup_ptr[itemp] = lu_sup_ptr[nsupc + icol*nsupr]; + lu_sup_ptr[nsupc + icol*nsupr] = temp; + } + } /* if */ + + /* cdiv operation */ + ops[FACT] += 10 * (nsupr - nsupc); + + z_div(&temp, &one, &lu_col_ptr[nsupc]); + for (k = nsupc+1; k < nsupr; k++) + zz_mult(&lu_col_ptr[k], &lu_col_ptr[k], &temp); + + return 0; +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/zpivotgrowth.c b/src/Libraries/superlu-5.2.1/SRC/zpivotgrowth.c new file mode 100644 index 00000000..23568742 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zpivotgrowth.c @@ -0,0 +1,124 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zpivotgrowth.c + * \brief Computes the reciprocal pivot growth factor + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ */ +#include +#include "slu_zdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *
+ * Compute the reciprocal pivot growth factor of the leading ncols columns
+ * of the matrix, using the formula:
+ *     min_j ( max_i(abs(A_ij)) / max_i(abs(U_ij)) )
+ *
+ * Arguments
+ * =========
+ *
+ * ncols    (input) int
+ *          The number of columns of matrices A, L and U.
+ *
+ * A        (input) SuperMatrix*
+ *	    Original matrix A, permuted by columns, of dimension
+ *          (A->nrow, A->ncol). The type of A can be:
+ *          Stype = NC; Dtype = SLU_Z; Mtype = GE.
+ *
+ * L        (output) SuperMatrix*
+ *          The factor L from the factorization Pr*A=L*U; use compressed row 
+ *          subscripts storage for supernodes, i.e., L has type: 
+ *          Stype = SC; Dtype = SLU_Z; Mtype = TRLU.
+ *
+ * U        (output) SuperMatrix*
+ *	    The factor U from the factorization Pr*A*Pc=L*U. Use column-wise
+ *          storage scheme, i.e., U has types: Stype = NC;
+ *          Dtype = SLU_Z; Mtype = TRU.
+ * 
+ */ + +double +zPivotGrowth(int ncols, SuperMatrix *A, int *perm_c, + SuperMatrix *L, SuperMatrix *U) +{ + + NCformat *Astore; + SCformat *Lstore; + NCformat *Ustore; + doublecomplex *Aval, *Lval, *Uval; + int fsupc, nsupr, luptr, nz_in_U; + int i, j, k, oldcol; + int *inv_perm_c; + double rpg, maxaj, maxuj; + double smlnum; + doublecomplex *luval; + doublecomplex temp_comp; + + /* Get machine constants. */ + smlnum = dmach("S"); + rpg = 1. / smlnum; + + Astore = A->Store; + Lstore = L->Store; + Ustore = U->Store; + Aval = Astore->nzval; + Lval = Lstore->nzval; + Uval = Ustore->nzval; + + inv_perm_c = (int *) SUPERLU_MALLOC(A->ncol*sizeof(int)); + for (j = 0; j < A->ncol; ++j) inv_perm_c[perm_c[j]] = j; + + for (k = 0; k <= Lstore->nsuper; ++k) { + fsupc = L_FST_SUPC(k); + nsupr = L_SUB_START(fsupc+1) - L_SUB_START(fsupc); + luptr = L_NZ_START(fsupc); + luval = &Lval[luptr]; + nz_in_U = 1; + + for (j = fsupc; j < L_FST_SUPC(k+1) && j < ncols; ++j) { + maxaj = 0.; + oldcol = inv_perm_c[j]; + for (i = Astore->colptr[oldcol]; i < Astore->colptr[oldcol+1]; ++i) + maxaj = SUPERLU_MAX( maxaj, z_abs1( &Aval[i]) ); + + maxuj = 0.; + for (i = Ustore->colptr[j]; i < Ustore->colptr[j+1]; i++) + maxuj = SUPERLU_MAX( maxuj, z_abs1( &Uval[i]) ); + + /* Supernode */ + for (i = 0; i < nz_in_U; ++i) + maxuj = SUPERLU_MAX( maxuj, z_abs1( &luval[i]) ); + + ++nz_in_U; + luval += nsupr; + + if ( maxuj == 0. ) + rpg = SUPERLU_MIN( rpg, 1.); + else + rpg = SUPERLU_MIN( rpg, maxaj / maxuj ); + } + + if ( j >= ncols ) break; + } + + SUPERLU_FREE(inv_perm_c); + return (rpg); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zpruneL.c b/src/Libraries/superlu-5.2.1/SRC/zpruneL.c new file mode 100644 index 00000000..2f258687 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zpruneL.c @@ -0,0 +1,164 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zpruneL.c + * \brief Prunes the L-structure + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ *
+ */ + + +#include "slu_zdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *   Prunes the L-structure of supernodes whose L-structure
+ *   contains the current pivot row "pivrow"
+ * 
+ */ + +void +zpruneL( + const int jcol, /* in */ + const int *perm_r, /* in */ + const int pivrow, /* in */ + const int nseg, /* in */ + const int *segrep, /* in */ + const int *repfnz, /* in */ + int *xprune, /* out */ + GlobalLU_t *Glu /* modified - global LU data structures */ + ) +{ + + doublecomplex utemp; + int jsupno, irep, irep1, kmin, kmax, krow, movnum; + int i, ktemp, minloc, maxloc; + int do_prune; /* logical variable */ + int *xsup, *supno; + int *lsub, *xlsub; + doublecomplex *lusup; + int *xlusup; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (doublecomplex *) Glu->lusup; + xlusup = Glu->xlusup; + + /* + * For each supernode-rep irep in U[*,j] + */ + jsupno = supno[jcol]; + for (i = 0; i < nseg; i++) { + + irep = segrep[i]; + irep1 = irep + 1; + do_prune = FALSE; + + /* Don't prune with a zero U-segment */ + if ( repfnz[irep] == EMPTY ) + continue; + + /* If a snode overlaps with the next panel, then the U-segment + * is fragmented into two parts -- irep and irep1. We should let + * pruning occur at the rep-column in irep1's snode. + */ + if ( supno[irep] == supno[irep1] ) /* Don't prune */ + continue; + + /* + * If it has not been pruned & it has a nonz in row L[pivrow,i] + */ + if ( supno[irep] != jsupno ) { + if ( xprune[irep] >= xlsub[irep1] ) { + kmin = xlsub[irep]; + kmax = xlsub[irep1] - 1; + for (krow = kmin; krow <= kmax; krow++) + if ( lsub[krow] == pivrow ) { + do_prune = TRUE; + break; + } + } + + if ( do_prune ) { + + /* Do a quicksort-type partition + * movnum=TRUE means that the num values have to be exchanged. + */ + movnum = FALSE; + if ( irep == xsup[supno[irep]] ) /* Snode of size 1 */ + movnum = TRUE; + + while ( kmin <= kmax ) { + + if ( perm_r[lsub[kmax]] == EMPTY ) + kmax--; + else if ( perm_r[lsub[kmin]] != EMPTY ) + kmin++; + else { /* kmin below pivrow (not yet pivoted), and kmax + * above pivrow: interchange the two subscripts + */ + ktemp = lsub[kmin]; + lsub[kmin] = lsub[kmax]; + lsub[kmax] = ktemp; + + /* If the supernode has only one column, then we + * only keep one set of subscripts. For any subscript + * interchange performed, similar interchange must be + * done on the numerical values. + */ + if ( movnum ) { + minloc = xlusup[irep] + (kmin - xlsub[irep]); + maxloc = xlusup[irep] + (kmax - xlsub[irep]); + utemp = lusup[minloc]; + lusup[minloc] = lusup[maxloc]; + lusup[maxloc] = utemp; + } + + kmin++; + kmax--; + + } + + } /* while */ + + xprune[irep] = kmin; /* Pruning */ + +#ifdef CHK_PRUNE + printf(" After zpruneL(),using col %d: xprune[%d] = %d\n", + jcol, irep, kmin); +#endif + } /* if do_prune */ + + } /* if */ + + } /* for each U-segment... */ +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zreadhb.c b/src/Libraries/superlu-5.2.1/SRC/zreadhb.c new file mode 100644 index 00000000..ec338c2f --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zreadhb.c @@ -0,0 +1,379 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zreadhb.c + * \brief Read a matrix stored in Harwell-Boeing format + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Purpose
+ * =======
+ * 
+ * Read a DOUBLE COMPLEX PRECISION matrix stored in Harwell-Boeing format 
+ * as described below.
+ * 
+ * Line 1 (A72,A8) 
+ *  	Col. 1 - 72   Title (TITLE) 
+ *	Col. 73 - 80  Key (KEY) 
+ * 
+ * Line 2 (5I14) 
+ * 	Col. 1 - 14   Total number of lines excluding header (TOTCRD) 
+ * 	Col. 15 - 28  Number of lines for pointers (PTRCRD) 
+ * 	Col. 29 - 42  Number of lines for row (or variable) indices (INDCRD) 
+ * 	Col. 43 - 56  Number of lines for numerical values (VALCRD) 
+ *	Col. 57 - 70  Number of lines for right-hand sides (RHSCRD) 
+ *                    (including starting guesses and solution vectors 
+ *		       if present) 
+ *           	      (zero indicates no right-hand side data is present) 
+ *
+ * Line 3 (A3, 11X, 4I14) 
+ *   	Col. 1 - 3    Matrix type (see below) (MXTYPE) 
+ * 	Col. 15 - 28  Number of rows (or variables) (NROW) 
+ * 	Col. 29 - 42  Number of columns (or elements) (NCOL) 
+ *	Col. 43 - 56  Number of row (or variable) indices (NNZERO) 
+ *	              (equal to number of entries for assembled matrices) 
+ * 	Col. 57 - 70  Number of elemental matrix entries (NELTVL) 
+ *	              (zero in the case of assembled matrices) 
+ * Line 4 (2A16, 2A20) 
+ * 	Col. 1 - 16   Format for pointers (PTRFMT) 
+ *	Col. 17 - 32  Format for row (or variable) indices (INDFMT) 
+ *	Col. 33 - 52  Format for numerical values of coefficient matrix (VALFMT) 
+ * 	Col. 53 - 72 Format for numerical values of right-hand sides (RHSFMT) 
+ *
+ * Line 5 (A3, 11X, 2I14) Only present if there are right-hand sides present 
+ *    	Col. 1 	      Right-hand side type: 
+ *	         	  F for full storage or M for same format as matrix 
+ *    	Col. 2        G if a starting vector(s) (Guess) is supplied. (RHSTYP) 
+ *    	Col. 3        X if an exact solution vector(s) is supplied. 
+ *	Col. 15 - 28  Number of right-hand sides (NRHS) 
+ *	Col. 29 - 42  Number of row indices (NRHSIX) 
+ *          	      (ignored in case of unassembled matrices) 
+ *
+ * The three character type field on line 3 describes the matrix type. 
+ * The following table lists the permitted values for each of the three 
+ * characters. As an example of the type field, RSA denotes that the matrix 
+ * is real, symmetric, and assembled. 
+ *
+ * First Character: 
+ *	R Real matrix 
+ *	C Complex matrix 
+ *	P Pattern only (no numerical values supplied) 
+ *
+ * Second Character: 
+ *	S Symmetric 
+ *	U Unsymmetric 
+ *	H Hermitian 
+ *	Z Skew symmetric 
+ *	R Rectangular 
+ *
+ * Third Character: 
+ *	A Assembled 
+ *	E Elemental matrices (unassembled) 
+ *
+ * 
+ */ +#include +#include +#include "slu_zdefs.h" + + +/*! \brief Eat up the rest of the current line */ +int zDumpLine(FILE *fp) +{ + register int c; + while ((c = fgetc(fp)) != '\n') ; + return 0; +} + +int zParseIntFormat(char *buf, int *num, int *size) +{ + char *tmp; + + tmp = buf; + while (*tmp++ != '(') ; + sscanf(tmp, "%d", num); + while (*tmp != 'I' && *tmp != 'i') ++tmp; + ++tmp; + sscanf(tmp, "%d", size); + return 0; +} + +int zParseFloatFormat(char *buf, int *num, int *size) +{ + char *tmp, *period; + + tmp = buf; + while (*tmp++ != '(') ; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + while (*tmp != 'E' && *tmp != 'e' && *tmp != 'D' && *tmp != 'd' + && *tmp != 'F' && *tmp != 'f') { + /* May find kP before nE/nD/nF, like (1P6F13.6). In this case the + num picked up refers to P, which should be skipped. */ + if (*tmp=='p' || *tmp=='P') { + ++tmp; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + } else { + ++tmp; + } + } + ++tmp; + period = tmp; + while (*period != '.' && *period != ')') ++period ; + *period = '\0'; + *size = atoi(tmp); /*sscanf(tmp, "%2d", size);*/ + + return 0; +} + +static int ReadVector(FILE *fp, int n, int *where, int perline, int persize) +{ + register int i, j, item; + char tmp, buf[100]; + + i = 0; + while (i < n) { + fgets(buf, 100, fp); /* read a line at a time */ + for (j=0; j + * On input, nonz/nzval/rowind/colptr represents lower part of a symmetric + * matrix. On exit, it represents the full matrix with lower and upper parts. + * + */ +static void +FormFullA(int n, int *nonz, doublecomplex **nzval, int **rowind, int **colptr) +{ + register int i, j, k, col, new_nnz; + int *t_rowind, *t_colptr, *al_rowind, *al_colptr, *a_rowind, *a_colptr; + int *marker; + doublecomplex *t_val, *al_val, *a_val; + + al_rowind = *rowind; + al_colptr = *colptr; + al_val = *nzval; + + if ( !(marker =(int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for marker[]"); + if ( !(t_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC t_colptr[]"); + if ( !(t_rowind = (int *) SUPERLU_MALLOC( *nonz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for t_rowind[]"); + if ( !(t_val = (doublecomplex*) SUPERLU_MALLOC( *nonz * sizeof(doublecomplex)) ) ) + ABORT("SUPERLU_MALLOC fails for t_val[]"); + + /* Get counts of each column of T, and set up column pointers */ + for (i = 0; i < n; ++i) marker[i] = 0; + for (j = 0; j < n; ++j) { + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) + ++marker[al_rowind[i]]; + } + t_colptr[0] = 0; + for (i = 0; i < n; ++i) { + t_colptr[i+1] = t_colptr[i] + marker[i]; + marker[i] = t_colptr[i]; + } + + /* Transpose matrix A to T */ + for (j = 0; j < n; ++j) + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + col = al_rowind[i]; + t_rowind[marker[col]] = j; + t_val[marker[col]] = al_val[i]; + ++marker[col]; + } + + new_nnz = *nonz * 2 - n; + if ( !(a_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC a_colptr[]"); + if ( !(a_rowind = (int *) SUPERLU_MALLOC( new_nnz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for a_rowind[]"); + if ( !(a_val = (doublecomplex*) SUPERLU_MALLOC( new_nnz * sizeof(doublecomplex)) ) ) + ABORT("SUPERLU_MALLOC fails for a_val[]"); + + a_colptr[0] = 0; + k = 0; + for (j = 0; j < n; ++j) { + for (i = t_colptr[j]; i < t_colptr[j+1]; ++i) { + if ( t_rowind[i] != j ) { /* not diagonal */ + a_rowind[k] = t_rowind[i]; + a_val[k] = t_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + } + + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + a_rowind[k] = al_rowind[i]; + a_val[k] = al_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + + a_colptr[j+1] = k; + } + + printf("FormFullA: new_nnz = %d, k = %d\n", new_nnz, k); + + SUPERLU_FREE(al_val); + SUPERLU_FREE(al_rowind); + SUPERLU_FREE(al_colptr); + SUPERLU_FREE(marker); + SUPERLU_FREE(t_val); + SUPERLU_FREE(t_rowind); + SUPERLU_FREE(t_colptr); + + *nzval = a_val; + *rowind = a_rowind; + *colptr = a_colptr; + *nonz = new_nnz; +} + +void +zreadhb(FILE *fp, int *nrow, int *ncol, int *nonz, + doublecomplex **nzval, int **rowind, int **colptr) +{ + + register int i, numer_lines = 0, rhscrd = 0; + int tmp, colnum, colsize, rownum, rowsize, valnum, valsize; + char buf[100], type[4], key[10]; + int sym; + + /* Line 1 */ + fgets(buf, 100, fp); + fputs(buf, stdout); +#if 0 + fscanf(fp, "%72c", buf); buf[72] = 0; + printf("Title: %s", buf); + fscanf(fp, "%8c", key); key[8] = 0; + printf("Key: %s\n", key); + zDumpLine(fp); +#endif + + /* Line 2 */ + for (i=0; i<5; i++) { + fscanf(fp, "%14c", buf); buf[14] = 0; + sscanf(buf, "%d", &tmp); + if (i == 3) numer_lines = tmp; + if (i == 4 && tmp) rhscrd = tmp; + } + zDumpLine(fp); + + /* Line 3 */ + fscanf(fp, "%3c", type); + fscanf(fp, "%11c", buf); /* pad */ + type[3] = 0; +#ifdef DEBUG + printf("Matrix type %s\n", type); +#endif + + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nrow); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", ncol); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nonz); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", &tmp); + + if (tmp != 0) + printf("This is not an assembled matrix!\n"); + if (*nrow != *ncol) + printf("Matrix is not square.\n"); + zDumpLine(fp); + + /* Allocate storage for the three arrays ( nzval, rowind, colptr ) */ + zallocateA(*ncol, *nonz, nzval, rowind, colptr); + + /* Line 4: format statement */ + fscanf(fp, "%16c", buf); + zParseIntFormat(buf, &colnum, &colsize); + fscanf(fp, "%16c", buf); + zParseIntFormat(buf, &rownum, &rowsize); + fscanf(fp, "%20c", buf); + zParseFloatFormat(buf, &valnum, &valsize); + fscanf(fp, "%20c", buf); + zDumpLine(fp); + + /* Line 5: right-hand side */ + if ( rhscrd ) zDumpLine(fp); /* skip RHSFMT */ + +#ifdef DEBUG + printf("%d rows, %d nonzeros\n", *nrow, *nonz); + printf("colnum %d, colsize %d\n", colnum, colsize); + printf("rownum %d, rowsize %d\n", rownum, rowsize); + printf("valnum %d, valsize %d\n", valnum, valsize); +#endif + + ReadVector(fp, *ncol+1, *colptr, colnum, colsize); + ReadVector(fp, *nonz, *rowind, rownum, rowsize); + if ( numer_lines ) { + zReadValues(fp, *nonz, *nzval, valnum, valsize); + } + + sym = (type[1] == 'S' || type[1] == 's'); + if ( sym ) { + FormFullA(*ncol, nonz, nzval, rowind, colptr); + } + + fclose(fp); +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/zreadrb.c b/src/Libraries/superlu-5.2.1/SRC/zreadrb.c new file mode 100644 index 00000000..7641fe27 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zreadrb.c @@ -0,0 +1,365 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zreadrb.c + * \brief Read a matrix stored in Rutherford-Boeing format + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ * + * Purpose + * ======= + * + * Read a DOUBLE COMPLEX PRECISION matrix stored in Rutherford-Boeing format + * as described below. + * + * Line 1 (A72, A8) + * Col. 1 - 72 Title (TITLE) + * Col. 73 - 80 Matrix name / identifier (MTRXID) + * + * Line 2 (I14, 3(1X, I13)) + * Col. 1 - 14 Total number of lines excluding header (TOTCRD) + * Col. 16 - 28 Number of lines for pointers (PTRCRD) + * Col. 30 - 42 Number of lines for row (or variable) indices (INDCRD) + * Col. 44 - 56 Number of lines for numerical values (VALCRD) + * + * Line 3 (A3, 11X, 4(1X, I13)) + * Col. 1 - 3 Matrix type (see below) (MXTYPE) + * Col. 15 - 28 Compressed Column: Number of rows (NROW) + * Elemental: Largest integer used to index variable (MVAR) + * Col. 30 - 42 Compressed Column: Number of columns (NCOL) + * Elemental: Number of element matrices (NELT) + * Col. 44 - 56 Compressed Column: Number of entries (NNZERO) + * Elemental: Number of variable indeces (NVARIX) + * Col. 58 - 70 Compressed Column: Unused, explicitly zero + * Elemental: Number of elemental matrix entries (NELTVL) + * + * Line 4 (2A16, A20) + * Col. 1 - 16 Fortran format for pointers (PTRFMT) + * Col. 17 - 32 Fortran format for row (or variable) indices (INDFMT) + * Col. 33 - 52 Fortran format for numerical values of coefficient matrix + * (VALFMT) + * (blank in the case of matrix patterns) + * + * The three character type field on line 3 describes the matrix type. + * The following table lists the permitted values for each of the three + * characters. As an example of the type field, RSA denotes that the matrix + * is real, symmetric, and assembled. + * + * First Character: + * R Real matrix + * C Complex matrix + * I integer matrix + * P Pattern only (no numerical values supplied) + * Q Pattern only (numerical values supplied in associated auxiliary value + * file) + * + * Second Character: + * S Symmetric + * U Unsymmetric + * H Hermitian + * Z Skew symmetric + * R Rectangular + * + * Third Character: + * A Compressed column form + * E Elemental form + * + * + */ + +#include +#include +#include "slu_zdefs.h" + + +/*! \brief Eat up the rest of the current line */ +static int zDumpLine(FILE *fp) +{ + register int c; + while ((c = fgetc(fp)) != '\n') ; + return 0; +} + +static int zParseIntFormat(char *buf, int *num, int *size) +{ + char *tmp; + + tmp = buf; + while (*tmp++ != '(') ; + sscanf(tmp, "%d", num); + while (*tmp != 'I' && *tmp != 'i') ++tmp; + ++tmp; + sscanf(tmp, "%d", size); + return 0; +} + +static int zParseFloatFormat(char *buf, int *num, int *size) +{ + char *tmp, *period; + + tmp = buf; + while (*tmp++ != '(') ; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + while (*tmp != 'E' && *tmp != 'e' && *tmp != 'D' && *tmp != 'd' + && *tmp != 'F' && *tmp != 'f') { + /* May find kP before nE/nD/nF, like (1P6F13.6). In this case the + num picked up refers to P, which should be skipped. */ + if (*tmp=='p' || *tmp=='P') { + ++tmp; + *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/ + } else { + ++tmp; + } + } + ++tmp; + period = tmp; + while (*period != '.' && *period != ')') ++period ; + *period = '\0'; + *size = atoi(tmp); /*sscanf(tmp, "%2d", size);*/ + + return 0; +} + +static int ReadVector(FILE *fp, int n, int *where, int perline, int persize) +{ + register int i, j, item; + char tmp, buf[100]; + + i = 0; + while (i < n) { + fgets(buf, 100, fp); /* read a line at a time */ + for (j=0; j + * On input, nonz/nzval/rowind/colptr represents lower part of a symmetric + * matrix. On exit, it represents the full matrix with lower and upper parts. + * + */ +static void +FormFullA(int n, int *nonz, doublecomplex **nzval, int **rowind, int **colptr) +{ + register int i, j, k, col, new_nnz; + int *t_rowind, *t_colptr, *al_rowind, *al_colptr, *a_rowind, *a_colptr; + int *marker; + doublecomplex *t_val, *al_val, *a_val; + + al_rowind = *rowind; + al_colptr = *colptr; + al_val = *nzval; + + if ( !(marker =(int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for marker[]"); + if ( !(t_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC t_colptr[]"); + if ( !(t_rowind = (int *) SUPERLU_MALLOC( *nonz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for t_rowind[]"); + if ( !(t_val = (doublecomplex*) SUPERLU_MALLOC( *nonz * sizeof(doublecomplex)) ) ) + ABORT("SUPERLU_MALLOC fails for t_val[]"); + + /* Get counts of each column of T, and set up column pointers */ + for (i = 0; i < n; ++i) marker[i] = 0; + for (j = 0; j < n; ++j) { + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) + ++marker[al_rowind[i]]; + } + t_colptr[0] = 0; + for (i = 0; i < n; ++i) { + t_colptr[i+1] = t_colptr[i] + marker[i]; + marker[i] = t_colptr[i]; + } + + /* Transpose matrix A to T */ + for (j = 0; j < n; ++j) + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + col = al_rowind[i]; + t_rowind[marker[col]] = j; + t_val[marker[col]] = al_val[i]; + ++marker[col]; + } + + new_nnz = *nonz * 2 - n; + if ( !(a_colptr = (int *) SUPERLU_MALLOC( (n+1) * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC a_colptr[]"); + if ( !(a_rowind = (int *) SUPERLU_MALLOC( new_nnz * sizeof(int)) ) ) + ABORT("SUPERLU_MALLOC fails for a_rowind[]"); + if ( !(a_val = (doublecomplex*) SUPERLU_MALLOC( new_nnz * sizeof(doublecomplex)) ) ) + ABORT("SUPERLU_MALLOC fails for a_val[]"); + + a_colptr[0] = 0; + k = 0; + for (j = 0; j < n; ++j) { + for (i = t_colptr[j]; i < t_colptr[j+1]; ++i) { + if ( t_rowind[i] != j ) { /* not diagonal */ + a_rowind[k] = t_rowind[i]; + a_val[k] = t_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + } + + for (i = al_colptr[j]; i < al_colptr[j+1]; ++i) { + a_rowind[k] = al_rowind[i]; + a_val[k] = al_val[i]; +#ifdef DEBUG + if ( fabs(a_val[k]) < 4.047e-300 ) + printf("%5d: %e\n", k, a_val[k]); +#endif + ++k; + } + + a_colptr[j+1] = k; + } + + printf("FormFullA: new_nnz = %d, k = %d\n", new_nnz, k); + + SUPERLU_FREE(al_val); + SUPERLU_FREE(al_rowind); + SUPERLU_FREE(al_colptr); + SUPERLU_FREE(marker); + SUPERLU_FREE(t_val); + SUPERLU_FREE(t_rowind); + SUPERLU_FREE(t_colptr); + + *nzval = a_val; + *rowind = a_rowind; + *colptr = a_colptr; + *nonz = new_nnz; +} + +void +zreadrb(int *nrow, int *ncol, int *nonz, + doublecomplex **nzval, int **rowind, int **colptr) +{ + + register int i, numer_lines = 0; + int tmp, colnum, colsize, rownum, rowsize, valnum, valsize; + char buf[100], type[4]; + int sym; + FILE *fp; + + fp = stdin; + + /* Line 1 */ + fgets(buf, 100, fp); + fputs(buf, stdout); + + /* Line 2 */ + for (i=0; i<4; i++) { + fscanf(fp, "%14c", buf); buf[14] = 0; + sscanf(buf, "%d", &tmp); + if (i == 3) numer_lines = tmp; + } + zDumpLine(fp); + + /* Line 3 */ + fscanf(fp, "%3c", type); + fscanf(fp, "%11c", buf); /* pad */ + type[3] = 0; +#ifdef DEBUG + printf("Matrix type %s\n", type); +#endif + + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nrow); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", ncol); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", nonz); + fscanf(fp, "%14c", buf); sscanf(buf, "%d", &tmp); + + if (tmp != 0) + printf("This is not an assembled matrix!\n"); + if (*nrow != *ncol) + printf("Matrix is not square.\n"); + zDumpLine(fp); + + /* Allocate storage for the three arrays ( nzval, rowind, colptr ) */ + zallocateA(*ncol, *nonz, nzval, rowind, colptr); + + /* Line 4: format statement */ + fscanf(fp, "%16c", buf); + zParseIntFormat(buf, &colnum, &colsize); + fscanf(fp, "%16c", buf); + zParseIntFormat(buf, &rownum, &rowsize); + fscanf(fp, "%20c", buf); + zParseFloatFormat(buf, &valnum, &valsize); + zDumpLine(fp); + +#ifdef DEBUG + printf("%d rows, %d nonzeros\n", *nrow, *nonz); + printf("colnum %d, colsize %d\n", colnum, colsize); + printf("rownum %d, rowsize %d\n", rownum, rowsize); + printf("valnum %d, valsize %d\n", valnum, valsize); +#endif + + ReadVector(fp, *ncol+1, *colptr, colnum, colsize); + ReadVector(fp, *nonz, *rowind, rownum, rowsize); + if ( numer_lines ) { + zReadValues(fp, *nonz, *nzval, valnum, valsize); + } + + sym = (type[1] == 'S' || type[1] == 's'); + if ( sym ) { + FormFullA(*ncol, nonz, nzval, rowind, colptr); + } + + fclose(fp); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zreadtriple.c b/src/Libraries/superlu-5.2.1/SRC/zreadtriple.c new file mode 100644 index 00000000..fc834ec5 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zreadtriple.c @@ -0,0 +1,150 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zreadtriple.c + * \brief Read a matrix stored in triplet (coordinate) format + * + *
+ * -- SuperLU routine (version 4.0) --
+ * Lawrence Berkeley National Laboratory.
+ * June 30, 2009
+ * 
+ */ + +#include "slu_zdefs.h" + + +void +zreadtriple(int *m, int *n, int *nonz, + doublecomplex **nzval, int **rowind, int **colptr) +{ +/* + * Output parameters + * ================= + * (a,asub,xa): asub[*] contains the row subscripts of nonzeros + * in columns of matrix A; a[*] the numerical values; + * row i of A is given by a[k],k=xa[i],...,xa[i+1]-1. + * + */ + int j, k, jsize, nnz, nz; + doublecomplex *a, *val; + int *asub, *xa, *row, *col; + int zero_base = 0; + + /* Matrix format: + * First line: #rows, #cols, #non-zero + * Triplet in the rest of lines: + * row, col, value + */ + + scanf("%d%d", n, nonz); + *m = *n; + printf("m %d, n %d, nonz %d\n", *m, *n, *nonz); + zallocateA(*n, *nonz, nzval, rowind, colptr); /* Allocate storage */ + a = *nzval; + asub = *rowind; + xa = *colptr; + + val = (doublecomplex *) SUPERLU_MALLOC(*nonz * sizeof(doublecomplex)); + row = (int *) SUPERLU_MALLOC(*nonz * sizeof(int)); + col = (int *) SUPERLU_MALLOC(*nonz * sizeof(int)); + + for (j = 0; j < *n; ++j) xa[j] = 0; + + /* Read into the triplet array from a file */ + for (nnz = 0, nz = 0; nnz < *nonz; ++nnz) { + scanf("%d%d%lf%lf\n", &row[nz], &col[nz], &val[nz].r, &val[nz].i); + + if ( nnz == 0 ) { /* first nonzero */ + if ( row[0] == 0 || col[0] == 0 ) { + zero_base = 1; + printf("triplet file: row/col indices are zero-based.\n"); + } else + printf("triplet file: row/col indices are one-based.\n"); + } + + if ( !zero_base ) { + /* Change to 0-based indexing. */ + --row[nz]; + --col[nz]; + } + + if (row[nz] < 0 || row[nz] >= *m || col[nz] < 0 || col[nz] >= *n + /*|| val[nz] == 0.*/) { + fprintf(stderr, "nz %d, (%d, %d) = (%e,%e) out of bound, removed\n", + nz, row[nz], col[nz], val[nz].r, val[nz].i); + exit(-1); + } else { + ++xa[col[nz]]; + ++nz; + } + } + + *nonz = nz; + + /* Initialize the array of column pointers */ + k = 0; + jsize = xa[0]; + xa[0] = 0; + for (j = 1; j < *n; ++j) { + k += jsize; + jsize = xa[j]; + xa[j] = k; + } + + /* Copy the triplets into the column oriented storage */ + for (nz = 0; nz < *nonz; ++nz) { + j = col[nz]; + k = xa[j]; + asub[k] = row[nz]; + a[k] = val[nz]; + ++xa[j]; + } + + /* Reset the column pointers to the beginning of each column */ + for (j = *n; j > 0; --j) + xa[j] = xa[j-1]; + xa[0] = 0; + + SUPERLU_FREE(val); + SUPERLU_FREE(row); + SUPERLU_FREE(col); + +#ifdef CHK_INPUT + { + int i; + for (i = 0; i < *n; i++) { + printf("Col %d, xa %d\n", i, xa[i]); + for (k = xa[i]; k < xa[i+1]; k++) + printf("%d\t%16.10f\n", asub[k], a[k]); + } + } +#endif + +} + + +void zreadrhs(int m, doublecomplex *b) +{ + FILE *fp, *fopen(); + int i; + /*int j;*/ + + if ( !(fp = fopen("b.dat", "r")) ) { + fprintf(stderr, "dreadrhs: file does not exist\n"); + exit(-1); + } + for (i = 0; i < m; ++i) + fscanf(fp, "%lf%lf\n", &b[i].r, &b[i].i); + + /* readpair_(j, &b[i]);*/ + fclose(fp); +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zsnode_bmod.c b/src/Libraries/superlu-5.2.1/SRC/zsnode_bmod.c new file mode 100644 index 00000000..403b7ee1 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zsnode_bmod.c @@ -0,0 +1,130 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zsnode_bmod.c + * \brief Performs numeric block updates within the relaxed snode. + * + *
+ * -- SuperLU routine (version 3.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_zdefs.h" + + +/*! \brief Performs numeric block updates within the relaxed snode. + */ +int +zsnode_bmod ( + const int jcol, /* in */ + const int jsupno, /* in */ + const int fsupc, /* in */ + doublecomplex *dense, /* in */ + doublecomplex *tempv, /* working array */ + GlobalLU_t *Glu, /* modified */ + SuperLUStat_t *stat /* output */ + ) +{ +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + int incx = 1, incy = 1; + doublecomplex alpha = {-1.0, 0.0}, beta = {1.0, 0.0}; +#endif + + doublecomplex comp_zero = {0.0, 0.0}; + int luptr, nsupc, nsupr, nrow; + int isub, irow, i, iptr; + register int ufirst, nextlu; + int *lsub, *xlsub; + doublecomplex *lusup; + int *xlusup; + flops_t *ops = stat->ops; + + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (doublecomplex *) Glu->lusup; + xlusup = Glu->xlusup; + + nextlu = xlusup[jcol]; + + /* + * Process the supernodal portion of L\U[*,j] + */ + for (isub = xlsub[fsupc]; isub < xlsub[fsupc+1]; isub++) { + irow = lsub[isub]; + lusup[nextlu] = dense[irow]; + dense[irow] = comp_zero; + ++nextlu; + } + + xlusup[jcol + 1] = nextlu; /* Initialize xlusup for next column */ + + if ( fsupc < jcol ) { + + luptr = xlusup[fsupc]; + nsupr = xlsub[fsupc+1] - xlsub[fsupc]; + nsupc = jcol - fsupc; /* Excluding jcol */ + ufirst = xlusup[jcol]; /* Points to the beginning of column + jcol in supernode L\U(jsupno). */ + nrow = nsupr - nsupc; + + ops[TRSV] += 4 * nsupc * (nsupc - 1); + ops[GEMV] += 8 * nrow * nsupc; + +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + CTRSV( ftcs1, ftcs2, ftcs3, &nsupc, &lusup[luptr], &nsupr, + &lusup[ufirst], &incx ); + CGEMV( ftcs2, &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#else + ztrsv_( "L", "N", "U", &nsupc, &lusup[luptr], &nsupr, + &lusup[ufirst], &incx ); + zgemv_( "N", &nrow, &nsupc, &alpha, &lusup[luptr+nsupc], &nsupr, + &lusup[ufirst], &incx, &beta, &lusup[ufirst+nsupc], &incy ); +#endif +#else + zlsolve ( nsupr, nsupc, &lusup[luptr], &lusup[ufirst] ); + zmatvec ( nsupr, nrow, nsupc, &lusup[luptr+nsupc], + &lusup[ufirst], &tempv[0] ); + + /* Scatter tempv[*] into lusup[*] */ + iptr = ufirst + nsupc; + for (i = 0; i < nrow; i++) { + z_sub(&lusup[iptr], &lusup[iptr], &tempv[i]); + ++iptr; + tempv[i] = comp_zero; + } +#endif + + } + + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zsnode_dfs.c b/src/Libraries/superlu-5.2.1/SRC/zsnode_dfs.c new file mode 100644 index 00000000..e1a81bcb --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zsnode_dfs.c @@ -0,0 +1,122 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zsnode_dfs.c + * \brief Determines the union of row structures of columns within the relaxed node + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include "slu_zdefs.h" + +/*! \brief + * + *
+ * Purpose
+ * =======
+ *    zsnode_dfs() - Determine the union of the row structures of those 
+ *    columns within the relaxed snode.
+ *    Note: The relaxed snodes are leaves of the supernodal etree, therefore, 
+ *    the portion outside the rectangular supernode must be zero.
+ *
+ * Return value
+ * ============
+ *     0   success;
+ *    >0   number of bytes allocated when run out of memory.
+ * 
+ */ + +int +zsnode_dfs ( + const int jcol, /* in - start of the supernode */ + const int kcol, /* in - end of the supernode */ + const int *asub, /* in */ + const int *xa_begin, /* in */ + const int *xa_end, /* in */ + int *xprune, /* out */ + int *marker, /* modified */ + GlobalLU_t *Glu /* modified */ + ) +{ + + register int i, k, ifrom, ito, nextl, new_next; + int nsuper, krow, kmark, mem_error; + int *xsup, *supno; + int *lsub, *xlsub; + int nzlmax; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + nzlmax = Glu->nzlmax; + + nsuper = ++supno[jcol]; /* Next available supernode number */ + nextl = xlsub[jcol]; + + for (i = jcol; i <= kcol; i++) { + /* For each nonzero in A[*,i] */ + for (k = xa_begin[i]; k < xa_end[i]; k++) { + krow = asub[k]; + kmark = marker[krow]; + if ( kmark != kcol ) { /* First time visit krow */ + marker[krow] = kcol; + lsub[nextl++] = krow; + if ( nextl >= nzlmax ) { + if ( mem_error = zLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + } + } + supno[i] = nsuper; + } + + /* Supernode > 1, then make a copy of the subscripts for pruning */ + if ( jcol < kcol ) { + new_next = nextl + (nextl - xlsub[jcol]); + while ( new_next > nzlmax ) { + if ( mem_error = zLUMemXpand(jcol, nextl, LSUB, &nzlmax, Glu) ) + return (mem_error); + lsub = Glu->lsub; + } + ito = nextl; + for (ifrom = xlsub[jcol]; ifrom < nextl; ) + lsub[ito++] = lsub[ifrom++]; + for (i = jcol+1; i <= kcol; i++) xlsub[i] = nextl; + nextl = ito; + } + + xsup[nsuper+1] = kcol + 1; + supno[kcol+1] = nsuper; + xprune[kcol] = nextl; + xlsub[kcol+1] = nextl; + + return 0; +} + diff --git a/src/Libraries/superlu-5.2.1/SRC/zsp_blas2.c b/src/Libraries/superlu-5.2.1/SRC/zsp_blas2.c new file mode 100644 index 00000000..1e340123 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zsp_blas2.c @@ -0,0 +1,608 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zsp_blas2.c + * \brief Sparse BLAS 2, using some dense BLAS 2 operations + * + *
+ * -- SuperLU routine (version 5.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * October 15, 2003
+ *
+ * Last update: December 3, 2015
+ * 
+ */ +/* + * File name: zsp_blas2.c + * Purpose: Sparse BLAS 2, using some dense BLAS 2 operations. + */ + +#include "slu_zdefs.h" + +/* + * Function prototypes + */ +void zusolve(int, int, doublecomplex*, doublecomplex*); +void zlsolve(int, int, doublecomplex*, doublecomplex*); +void zmatvec(int, int, int, doublecomplex*, doublecomplex*, doublecomplex*); + +/*! \brief Solves one of the systems of equations A*x = b, or A'*x = b + * + *
+ *   Purpose
+ *   =======
+ *
+ *   sp_ztrsv() solves one of the systems of equations   
+ *       A*x = b,   or   A'*x = b,
+ *   where b and x are n element vectors and A is a sparse unit , or   
+ *   non-unit, upper or lower triangular matrix.   
+ *   No test for singularity or near-singularity is included in this   
+ *   routine. Such tests must be performed before calling this routine.   
+ *
+ *   Parameters   
+ *   ==========   
+ *
+ *   uplo   - (input) char*
+ *            On entry, uplo specifies whether the matrix is an upper or   
+ *             lower triangular matrix as follows:   
+ *                uplo = 'U' or 'u'   A is an upper triangular matrix.   
+ *                uplo = 'L' or 'l'   A is a lower triangular matrix.   
+ *
+ *   trans  - (input) char*
+ *             On entry, trans specifies the equations to be solved as   
+ *             follows:   
+ *                trans = 'N' or 'n'   A*x = b.   
+ *                trans = 'T' or 't'   A'*x = b.
+ *                trans = 'C' or 'c'   A^H*x = b.   
+ *
+ *   diag   - (input) char*
+ *             On entry, diag specifies whether or not A is unit   
+ *             triangular as follows:   
+ *                diag = 'U' or 'u'   A is assumed to be unit triangular.   
+ *                diag = 'N' or 'n'   A is not assumed to be unit   
+ *                                    triangular.   
+ *	     
+ *   L       - (input) SuperMatrix*
+ *	       The factor L from the factorization Pr*A*Pc=L*U. Use
+ *             compressed row subscripts storage for supernodes,
+ *             i.e., L has types: Stype = SC, Dtype = SLU_Z, Mtype = TRLU.
+ *
+ *   U       - (input) SuperMatrix*
+ *	        The factor U from the factorization Pr*A*Pc=L*U.
+ *	        U has types: Stype = NC, Dtype = SLU_Z, Mtype = TRU.
+ *    
+ *   x       - (input/output) doublecomplex*
+ *             Before entry, the incremented array X must contain the n   
+ *             element right-hand side vector b. On exit, X is overwritten 
+ *             with the solution vector x.
+ *
+ *   info    - (output) int*
+ *             If *info = -i, the i-th argument had an illegal value.
+ * 
+ */ +int +sp_ztrsv(char *uplo, char *trans, char *diag, SuperMatrix *L, + SuperMatrix *U, doublecomplex *x, SuperLUStat_t *stat, int *info) +{ +#ifdef _CRAY + _fcd ftcs1 = _cptofcd("L", strlen("L")), + ftcs2 = _cptofcd("N", strlen("N")), + ftcs3 = _cptofcd("U", strlen("U")); +#endif + SCformat *Lstore; + NCformat *Ustore; + doublecomplex *Lval, *Uval; + int incx = 1, incy = 1; + doublecomplex temp; + doublecomplex alpha = {1.0, 0.0}, beta = {1.0, 0.0}; + doublecomplex comp_zero = {0.0, 0.0}; + int nrow; + int fsupc, nsupr, nsupc, luptr, istart, irow; + int i, k, iptr, jcol; + doublecomplex *work; + flops_t solve_ops; + + /* Test the input parameters */ + *info = 0; + if ( strncmp(uplo,"L", 1)!=0 && strncmp(uplo, "U", 1)!=0 ) *info = -1; + else if ( strncmp(trans, "N", 1)!=0 && strncmp(trans, "T", 1)!=0 && + strncmp(trans, "C", 1)!=0) *info = -2; + else if ( strncmp(diag, "U", 1)!=0 && strncmp(diag, "N", 1)!=0 ) + *info = -3; + else if ( L->nrow != L->ncol || L->nrow < 0 ) *info = -4; + else if ( U->nrow != U->ncol || U->nrow < 0 ) *info = -5; + if ( *info ) { + i = -(*info); + input_error("sp_ztrsv", &i); + return 0; + } + + Lstore = L->Store; + Lval = Lstore->nzval; + Ustore = U->Store; + Uval = Ustore->nzval; + solve_ops = 0; + + if ( !(work = doublecomplexCalloc(L->nrow)) ) + ABORT("Malloc fails for work in sp_ztrsv()."); + + if ( strncmp(trans, "N", 1)==0 ) { /* Form x := inv(A)*x. */ + + if ( strncmp(uplo, "L", 1)==0 ) { + /* Form x := inv(L)*x */ + if ( L->nrow == 0 ) return 0; /* Quick return */ + + for (k = 0; k <= Lstore->nsuper; k++) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + nrow = nsupr - nsupc; + + /* 1 z_div costs 10 flops */ + solve_ops += 4 * nsupc * (nsupc - 1) + 10 * nsupc; + solve_ops += 8 * nrow * nsupc; + + if ( nsupc == 1 ) { + for (iptr=istart+1; iptr < L_SUB_START(fsupc+1); ++iptr) { + irow = L_SUB(iptr); + ++luptr; + zz_mult(&comp_zero, &x[fsupc], &Lval[luptr]); + z_sub(&x[irow], &x[irow], &comp_zero); + } + } else { +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + CTRSV(ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); + + CGEMV(ftcs2, &nrow, &nsupc, &alpha, &Lval[luptr+nsupc], + &nsupr, &x[fsupc], &incx, &beta, &work[0], &incy); +#else + ztrsv_("L", "N", "U", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); + + zgemv_("N", &nrow, &nsupc, &alpha, &Lval[luptr+nsupc], + &nsupr, &x[fsupc], &incx, &beta, &work[0], &incy); +#endif +#else + zlsolve ( nsupr, nsupc, &Lval[luptr], &x[fsupc]); + + zmatvec ( nsupr, nsupr-nsupc, nsupc, &Lval[luptr+nsupc], + &x[fsupc], &work[0] ); +#endif + + iptr = istart + nsupc; + for (i = 0; i < nrow; ++i, ++iptr) { + irow = L_SUB(iptr); + z_sub(&x[irow], &x[irow], &work[i]); /* Scatter */ + work[i] = comp_zero; + + } + } + } /* for k ... */ + + } else { + /* Form x := inv(U)*x */ + + if ( U->nrow == 0 ) return 0; /* Quick return */ + + for (k = Lstore->nsuper; k >= 0; k--) { + fsupc = L_FST_SUPC(k); + nsupr = L_SUB_START(fsupc+1) - L_SUB_START(fsupc); + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + /* 1 z_div costs 10 flops */ + solve_ops += 4 * nsupc * (nsupc + 1) + 10 * nsupc; + + if ( nsupc == 1 ) { + z_div(&x[fsupc], &x[fsupc], &Lval[luptr]); + for (i = U_NZ_START(fsupc); i < U_NZ_START(fsupc+1); ++i) { + irow = U_SUB(i); + zz_mult(&comp_zero, &x[fsupc], &Uval[i]); + z_sub(&x[irow], &x[irow], &comp_zero); + } + } else { +#ifdef USE_VENDOR_BLAS +#ifdef _CRAY + CTRSV(ftcs3, ftcs2, ftcs2, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + ztrsv_("U", "N", "N", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif +#else + zusolve ( nsupr, nsupc, &Lval[luptr], &x[fsupc] ); +#endif + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + solve_ops += 8*(U_NZ_START(jcol+1) - U_NZ_START(jcol)); + for (i = U_NZ_START(jcol); i < U_NZ_START(jcol+1); + i++) { + irow = U_SUB(i); + zz_mult(&comp_zero, &x[jcol], &Uval[i]); + z_sub(&x[irow], &x[irow], &comp_zero); + } + } + } + } /* for k ... */ + + } + } else if ( strncmp(trans, "T", 1)==0 ) { /* Form x := inv(A')*x */ + + if ( strncmp(uplo, "L", 1)==0 ) { + /* Form x := inv(L')*x */ + if ( L->nrow == 0 ) return 0; /* Quick return */ + + for (k = Lstore->nsuper; k >= 0; --k) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + solve_ops += 8 * (nsupr - nsupc) * nsupc; + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + iptr = istart + nsupc; + for (i = L_NZ_START(jcol) + nsupc; + i < L_NZ_START(jcol+1); i++) { + irow = L_SUB(iptr); + zz_mult(&comp_zero, &x[irow], &Lval[i]); + z_sub(&x[jcol], &x[jcol], &comp_zero); + iptr++; + } + } + + if ( nsupc > 1 ) { + solve_ops += 4 * nsupc * (nsupc - 1); +#ifdef _CRAY + ftcs1 = _cptofcd("L", strlen("L")); + ftcs2 = _cptofcd("T", strlen("T")); + ftcs3 = _cptofcd("U", strlen("U")); + CTRSV(ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + ztrsv_("L", "T", "U", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif + } + } + } else { + /* Form x := inv(U')*x */ + if ( U->nrow == 0 ) return 0; /* Quick return */ + + for (k = 0; k <= Lstore->nsuper; k++) { + fsupc = L_FST_SUPC(k); + nsupr = L_SUB_START(fsupc+1) - L_SUB_START(fsupc); + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + solve_ops += 8*(U_NZ_START(jcol+1) - U_NZ_START(jcol)); + for (i = U_NZ_START(jcol); i < U_NZ_START(jcol+1); i++) { + irow = U_SUB(i); + zz_mult(&comp_zero, &x[irow], &Uval[i]); + z_sub(&x[jcol], &x[jcol], &comp_zero); + } + } + + /* 1 z_div costs 10 flops */ + solve_ops += 4 * nsupc * (nsupc + 1) + 10 * nsupc; + + if ( nsupc == 1 ) { + z_div(&x[fsupc], &x[fsupc], &Lval[luptr]); + } else { +#ifdef _CRAY + ftcs1 = _cptofcd("U", strlen("U")); + ftcs2 = _cptofcd("T", strlen("T")); + ftcs3 = _cptofcd("N", strlen("N")); + CTRSV( ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + ztrsv_("U", "T", "N", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif + } + } /* for k ... */ + } + } else { /* Form x := conj(inv(A'))*x */ + + if ( strncmp(uplo, "L", 1)==0 ) { + /* Form x := conj(inv(L'))*x */ + if ( L->nrow == 0 ) return 0; /* Quick return */ + + for (k = Lstore->nsuper; k >= 0; --k) { + fsupc = L_FST_SUPC(k); + istart = L_SUB_START(fsupc); + nsupr = L_SUB_START(fsupc+1) - istart; + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + solve_ops += 8 * (nsupr - nsupc) * nsupc; + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + iptr = istart + nsupc; + for (i = L_NZ_START(jcol) + nsupc; + i < L_NZ_START(jcol+1); i++) { + irow = L_SUB(iptr); + zz_conj(&temp, &Lval[i]); + zz_mult(&comp_zero, &x[irow], &temp); + z_sub(&x[jcol], &x[jcol], &comp_zero); + iptr++; + } + } + + if ( nsupc > 1 ) { + solve_ops += 4 * nsupc * (nsupc - 1); +#ifdef _CRAY + ftcs1 = _cptofcd("L", strlen("L")); + ftcs2 = _cptofcd(trans, strlen("T")); + ftcs3 = _cptofcd("U", strlen("U")); + ZTRSV(ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + ztrsv_("L", trans, "U", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif + } + } + } else { + /* Form x := conj(inv(U'))*x */ + if ( U->nrow == 0 ) return 0; /* Quick return */ + + for (k = 0; k <= Lstore->nsuper; k++) { + fsupc = L_FST_SUPC(k); + nsupr = L_SUB_START(fsupc+1) - L_SUB_START(fsupc); + nsupc = L_FST_SUPC(k+1) - fsupc; + luptr = L_NZ_START(fsupc); + + for (jcol = fsupc; jcol < L_FST_SUPC(k+1); jcol++) { + solve_ops += 8*(U_NZ_START(jcol+1) - U_NZ_START(jcol)); + for (i = U_NZ_START(jcol); i < U_NZ_START(jcol+1); i++) { + irow = U_SUB(i); + zz_conj(&temp, &Uval[i]); + zz_mult(&comp_zero, &x[irow], &temp); + z_sub(&x[jcol], &x[jcol], &comp_zero); + } + } + + /* 1 z_div costs 10 flops */ + solve_ops += 4 * nsupc * (nsupc + 1) + 10 * nsupc; + + if ( nsupc == 1 ) { + zz_conj(&temp, &Lval[luptr]); + z_div(&x[fsupc], &x[fsupc], &temp); + } else { +#ifdef _CRAY + ftcs1 = _cptofcd("U", strlen("U")); + ftcs2 = _cptofcd(trans, strlen("T")); + ftcs3 = _cptofcd("N", strlen("N")); + ZTRSV( ftcs1, ftcs2, ftcs3, &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#else + ztrsv_("U", trans, "N", &nsupc, &Lval[luptr], &nsupr, + &x[fsupc], &incx); +#endif + } + } /* for k ... */ + } + } + + stat->ops[SOLVE] += solve_ops; + SUPERLU_FREE(work); + return 0; +} + + + +/*! \brief Performs one of the matrix-vector operations y := alpha*A*x + beta*y, or y := alpha*A'*x + beta*y + * + *
  
+ *   Purpose   
+ *   =======   
+ *
+ *   sp_zgemv()  performs one of the matrix-vector operations   
+ *      y := alpha*A*x + beta*y,   or   y := alpha*A'*x + beta*y,   
+ *   where alpha and beta are scalars, x and y are vectors and A is a
+ *   sparse A->nrow by A->ncol matrix.   
+ *
+ *   Parameters   
+ *   ==========   
+ *
+ *   TRANS  - (input) char*
+ *            On entry, TRANS specifies the operation to be performed as   
+ *            follows:   
+ *               TRANS = 'N' or 'n'   y := alpha*A*x + beta*y.   
+ *               TRANS = 'T' or 't'   y := alpha*A'*x + beta*y.   
+ *               TRANS = 'C' or 'c'   y := alpha*A^H*x + beta*y.   
+ *
+ *   ALPHA  - (input) doublecomplex
+ *            On entry, ALPHA specifies the scalar alpha.   
+ *
+ *   A      - (input) SuperMatrix*
+ *            Before entry, the leading m by n part of the array A must   
+ *            contain the matrix of coefficients.   
+ *
+ *   X      - (input) doublecomplex*, array of DIMENSION at least   
+ *            ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'   
+ *           and at least   
+ *            ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.   
+ *            Before entry, the incremented array X must contain the   
+ *            vector x.   
+ * 
+ *   INCX   - (input) int
+ *            On entry, INCX specifies the increment for the elements of   
+ *            X. INCX must not be zero.   
+ *
+ *   BETA   - (input) doublecomplex
+ *            On entry, BETA specifies the scalar beta. When BETA is   
+ *            supplied as zero then Y need not be set on input.   
+ *
+ *   Y      - (output) doublecomplex*,  array of DIMENSION at least   
+ *            ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'   
+ *            and at least   
+ *            ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.   
+ *            Before entry with BETA non-zero, the incremented array Y   
+ *            must contain the vector y. On exit, Y is overwritten by the 
+ *            updated vector y.
+ *	      
+ *   INCY   - (input) int
+ *            On entry, INCY specifies the increment for the elements of   
+ *            Y. INCY must not be zero.   
+ *
+ *    ==== Sparse Level 2 Blas routine.   
+ * 
+*/ +int +sp_zgemv(char *trans, doublecomplex alpha, SuperMatrix *A, doublecomplex *x, + int incx, doublecomplex beta, doublecomplex *y, int incy) +{ + + /* Local variables */ + NCformat *Astore; + doublecomplex *Aval; + int info; + doublecomplex temp, temp1; + int lenx, leny, i, j, irow; + int iy, jx, jy, kx, ky; + int notran; + doublecomplex comp_zero = {0.0, 0.0}; + doublecomplex comp_one = {1.0, 0.0}; + + notran = ( strncmp(trans, "N", 1)==0 || strncmp(trans, "n", 1)==0 ); + Astore = A->Store; + Aval = Astore->nzval; + + /* Test the input parameters */ + info = 0; + if ( !notran && strncmp(trans, "T", 1)!=0 && strncmp(trans, "C", 1)!=0) + info = 1; + else if ( A->nrow < 0 || A->ncol < 0 ) info = 3; + else if (incx == 0) info = 5; + else if (incy == 0) info = 8; + if (info != 0) { + input_error("sp_zgemv ", &info); + return 0; + } + + /* Quick return if possible. */ + if (A->nrow == 0 || A->ncol == 0 || + z_eq(&alpha, &comp_zero) && + z_eq(&beta, &comp_one)) + return 0; + + /* Set LENX and LENY, the lengths of the vectors x and y, and set + up the start points in X and Y. */ + if ( notran ) { + lenx = A->ncol; + leny = A->nrow; + } else { + lenx = A->nrow; + leny = A->ncol; + } + if (incx > 0) kx = 0; + else kx = - (lenx - 1) * incx; + if (incy > 0) ky = 0; + else ky = - (leny - 1) * incy; + + /* Start the operations. In this version the elements of A are + accessed sequentially with one pass through A. */ + /* First form y := beta*y. */ + if ( !z_eq(&beta, &comp_one) ) { + if (incy == 1) { + if ( z_eq(&beta, &comp_zero) ) + for (i = 0; i < leny; ++i) y[i] = comp_zero; + else + for (i = 0; i < leny; ++i) + zz_mult(&y[i], &beta, &y[i]); + } else { + iy = ky; + if ( z_eq(&beta, &comp_zero) ) + for (i = 0; i < leny; ++i) { + y[iy] = comp_zero; + iy += incy; + } + else + for (i = 0; i < leny; ++i) { + zz_mult(&y[iy], &beta, &y[iy]); + iy += incy; + } + } + } + + if ( z_eq(&alpha, &comp_zero) ) return 0; + + if ( notran ) { + /* Form y := alpha*A*x + y. */ + jx = kx; + if (incy == 1) { + for (j = 0; j < A->ncol; ++j) { + if ( !z_eq(&x[jx], &comp_zero) ) { + zz_mult(&temp, &alpha, &x[jx]); + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + zz_mult(&temp1, &temp, &Aval[i]); + z_add(&y[irow], &y[irow], &temp1); + } + } + jx += incx; + } + } else { + ABORT("Not implemented."); + } + } else if (strncmp(trans, "T", 1) == 0 || strncmp(trans, "t", 1) == 0) { + /* Form y := alpha*A'*x + y. */ + jy = ky; + if (incx == 1) { + for (j = 0; j < A->ncol; ++j) { + temp = comp_zero; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + zz_mult(&temp1, &Aval[i], &x[irow]); + z_add(&temp, &temp, &temp1); + } + zz_mult(&temp1, &alpha, &temp); + z_add(&y[jy], &y[jy], &temp1); + jy += incy; + } + } else { + ABORT("Not implemented."); + } + } else { /* trans == 'C' or 'c' */ + /* Form y := alpha * conj(A) * x + y. */ + doublecomplex temp2; + jy = ky; + if (incx == 1) { + for (j = 0; j < A->ncol; ++j) { + temp = comp_zero; + for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; ++i) { + irow = Astore->rowind[i]; + temp2.r = Aval[i].r; + temp2.i = -Aval[i].i; /* conjugation */ + zz_mult(&temp1, &temp2, &x[irow]); + z_add(&temp, &temp, &temp1); + } + zz_mult(&temp1, &alpha, &temp); + z_add(&y[jy], &y[jy], &temp1); + jy += incy; + } + } else { + ABORT("Not implemented."); + } + } + + return 0; +} /* sp_zgemv */ + diff --git a/src/Libraries/superlu-5.2.1/SRC/zsp_blas3.c b/src/Libraries/superlu-5.2.1/SRC/zsp_blas3.c new file mode 100644 index 00000000..4125ba90 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zsp_blas3.c @@ -0,0 +1,137 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zsp_blas3.c + * \brief Sparse BLAS3, using some dense BLAS3 operations + * + *
+ * -- SuperLU routine (version 2.0) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * November 15, 1997
+ * 
+ */ +/* + * File name: sp_blas3.c + * Purpose: Sparse BLAS3, using some dense BLAS3 operations. + */ + +#include "slu_zdefs.h" + +/*! \brief + * + *
+ * Purpose   
+ *   =======   
+ * 
+ *   sp_z performs one of the matrix-matrix operations   
+ * 
+ *      C := alpha*op( A )*op( B ) + beta*C,   
+ * 
+ *   where  op( X ) is one of 
+ * 
+ *      op( X ) = X   or   op( X ) = X'   or   op( X ) = conjg( X' ),
+ * 
+ *   alpha and beta are scalars, and A, B and C are matrices, with op( A ) 
+ *   an m by k matrix,  op( B )  a  k by n matrix and  C an m by n matrix. 
+ *   
+ * 
+ *   Parameters   
+ *   ==========   
+ * 
+ *   TRANSA - (input) char*
+ *            On entry, TRANSA specifies the form of op( A ) to be used in 
+ *            the matrix multiplication as follows:   
+ *               TRANSA = 'N' or 'n',  op( A ) = A.   
+ *               TRANSA = 'T' or 't',  op( A ) = A'.   
+ *               TRANSA = 'C' or 'c',  op( A ) = conjg( A' ).   
+ *            Unchanged on exit.   
+ * 
+ *   TRANSB - (input) char*
+ *            On entry, TRANSB specifies the form of op( B ) to be used in 
+ *            the matrix multiplication as follows:   
+ *               TRANSB = 'N' or 'n',  op( B ) = B.   
+ *               TRANSB = 'T' or 't',  op( B ) = B'.   
+ *               TRANSB = 'C' or 'c',  op( B ) = conjg( B' ).   
+ *            Unchanged on exit.   
+ * 
+ *   M      - (input) int   
+ *            On entry,  M  specifies  the number of rows of the matrix 
+ *	     op( A ) and of the matrix C.  M must be at least zero. 
+ *	     Unchanged on exit.   
+ * 
+ *   N      - (input) int
+ *            On entry,  N specifies the number of columns of the matrix 
+ *	     op( B ) and the number of columns of the matrix C. N must be 
+ *	     at least zero.
+ *	     Unchanged on exit.   
+ * 
+ *   K      - (input) int
+ *            On entry, K specifies the number of columns of the matrix 
+ *	     op( A ) and the number of rows of the matrix op( B ). K must 
+ *	     be at least  zero.   
+ *           Unchanged on exit.
+ *      
+ *   ALPHA  - (input) doublecomplex
+ *            On entry, ALPHA specifies the scalar alpha.   
+ * 
+ *   A      - (input) SuperMatrix*
+ *            Matrix A with a sparse format, of dimension (A->nrow, A->ncol).
+ *            Currently, the type of A can be:
+ *                Stype = NC or NCP; Dtype = SLU_Z; Mtype = GE. 
+ *            In the future, more general A can be handled.
+ * 
+ *   B      - DOUBLE COMPLEX PRECISION array of DIMENSION ( LDB, kb ), where kb is 
+ *            n when TRANSB = 'N' or 'n',  and is  k otherwise.   
+ *            Before entry with  TRANSB = 'N' or 'n',  the leading k by n 
+ *            part of the array B must contain the matrix B, otherwise 
+ *            the leading n by k part of the array B must contain the 
+ *            matrix B.   
+ *            Unchanged on exit.   
+ * 
+ *   LDB    - (input) int
+ *            On entry, LDB specifies the first dimension of B as declared 
+ *            in the calling (sub) program. LDB must be at least max( 1, n ).  
+ *            Unchanged on exit.   
+ * 
+ *   BETA   - (input) doublecomplex
+ *            On entry, BETA specifies the scalar beta. When BETA is   
+ *            supplied as zero then C need not be set on input.   
+ *  
+ *   C      - DOUBLE COMPLEX PRECISION array of DIMENSION ( LDC, n ).   
+ *            Before entry, the leading m by n part of the array C must 
+ *            contain the matrix C,  except when beta is zero, in which 
+ *            case C need not be set on entry.   
+ *            On exit, the array C is overwritten by the m by n matrix 
+ *	     ( alpha*op( A )*B + beta*C ).   
+ *  
+ *   LDC    - (input) int
+ *            On entry, LDC specifies the first dimension of C as declared 
+ *            in the calling (sub)program. LDC must be at least max(1,m).   
+ *            Unchanged on exit.   
+ *  
+ *   ==== Sparse Level 3 Blas routine.   
+ * 
+ */ + +int +sp_zgemm(char *transa, char *transb, int m, int n, int k, + doublecomplex alpha, SuperMatrix *A, doublecomplex *b, int ldb, + doublecomplex beta, doublecomplex *c, int ldc) +{ + int incx = 1, incy = 1; + int j; + + for (j = 0; j < n; ++j) { + sp_zgemv(transa, alpha, A, &b[ldb*j], incx, beta, &c[ldc*j], incy); + } + return 0; +} diff --git a/src/Libraries/superlu-5.2.1/SRC/zutil.c b/src/Libraries/superlu-5.2.1/SRC/zutil.c new file mode 100644 index 00000000..23c292ca --- /dev/null +++ b/src/Libraries/superlu-5.2.1/SRC/zutil.c @@ -0,0 +1,485 @@ +/*! \file +Copyright (c) 2003, The Regents of the University of California, through +Lawrence Berkeley National Laboratory (subject to receipt of any required +approvals from U.S. Dept. of Energy) + +All rights reserved. + +The source code is distributed under BSD license, see the file License.txt +at the top-level directory. +*/ + +/*! @file zutil.c + * \brief Matrix utility functions + * + *
+ * -- SuperLU routine (version 3.1) --
+ * Univ. of California Berkeley, Xerox Palo Alto Research Center,
+ * and Lawrence Berkeley National Lab.
+ * August 1, 2008
+ *
+ * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
+ * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
+ * 
+ * Permission is hereby granted to use or copy this program for any
+ * purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is
+ * granted, provided the above notices are retained, and a notice that
+ * the code was modified is included with the above copyright notice.
+ * 
+ */ + + +#include +#include "slu_zdefs.h" + +void +zCreate_CompCol_Matrix(SuperMatrix *A, int m, int n, int nnz, + doublecomplex *nzval, int *rowind, int *colptr, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + NCformat *Astore; + + A->Stype = stype; + A->Dtype = dtype; + A->Mtype = mtype; + A->nrow = m; + A->ncol = n; + A->Store = (void *) SUPERLU_MALLOC( sizeof(NCformat) ); + if ( !(A->Store) ) ABORT("SUPERLU_MALLOC fails for A->Store"); + Astore = A->Store; + Astore->nnz = nnz; + Astore->nzval = nzval; + Astore->rowind = rowind; + Astore->colptr = colptr; +} + +void +zCreate_CompRow_Matrix(SuperMatrix *A, int m, int n, int nnz, + doublecomplex *nzval, int *colind, int *rowptr, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + NRformat *Astore; + + A->Stype = stype; + A->Dtype = dtype; + A->Mtype = mtype; + A->nrow = m; + A->ncol = n; + A->Store = (void *) SUPERLU_MALLOC( sizeof(NRformat) ); + if ( !(A->Store) ) ABORT("SUPERLU_MALLOC fails for A->Store"); + Astore = A->Store; + Astore->nnz = nnz; + Astore->nzval = nzval; + Astore->colind = colind; + Astore->rowptr = rowptr; +} + +/*! \brief Copy matrix A into matrix B. */ +void +zCopy_CompCol_Matrix(SuperMatrix *A, SuperMatrix *B) +{ + NCformat *Astore, *Bstore; + int ncol, nnz, i; + + B->Stype = A->Stype; + B->Dtype = A->Dtype; + B->Mtype = A->Mtype; + B->nrow = A->nrow;; + B->ncol = ncol = A->ncol; + Astore = (NCformat *) A->Store; + Bstore = (NCformat *) B->Store; + Bstore->nnz = nnz = Astore->nnz; + for (i = 0; i < nnz; ++i) + ((doublecomplex *)Bstore->nzval)[i] = ((doublecomplex *)Astore->nzval)[i]; + for (i = 0; i < nnz; ++i) Bstore->rowind[i] = Astore->rowind[i]; + for (i = 0; i <= ncol; ++i) Bstore->colptr[i] = Astore->colptr[i]; +} + + +void +zCreate_Dense_Matrix(SuperMatrix *X, int m, int n, doublecomplex *x, int ldx, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + DNformat *Xstore; + + X->Stype = stype; + X->Dtype = dtype; + X->Mtype = mtype; + X->nrow = m; + X->ncol = n; + X->Store = (void *) SUPERLU_MALLOC( sizeof(DNformat) ); + if ( !(X->Store) ) ABORT("SUPERLU_MALLOC fails for X->Store"); + Xstore = (DNformat *) X->Store; + Xstore->lda = ldx; + Xstore->nzval = (doublecomplex *) x; +} + +void +zCopy_Dense_Matrix(int M, int N, doublecomplex *X, int ldx, + doublecomplex *Y, int ldy) +{ +/*! \brief Copies a two-dimensional matrix X to another matrix Y. + */ + int i, j; + + for (j = 0; j < N; ++j) + for (i = 0; i < M; ++i) + Y[i + j*ldy] = X[i + j*ldx]; +} + +void +zCreate_SuperNode_Matrix(SuperMatrix *L, int m, int n, int nnz, + doublecomplex *nzval, int *nzval_colptr, int *rowind, + int *rowind_colptr, int *col_to_sup, int *sup_to_col, + Stype_t stype, Dtype_t dtype, Mtype_t mtype) +{ + SCformat *Lstore; + + L->Stype = stype; + L->Dtype = dtype; + L->Mtype = mtype; + L->nrow = m; + L->ncol = n; + L->Store = (void *) SUPERLU_MALLOC( sizeof(SCformat) ); + if ( !(L->Store) ) ABORT("SUPERLU_MALLOC fails for L->Store"); + Lstore = L->Store; + Lstore->nnz = nnz; + Lstore->nsuper = col_to_sup[n]; + Lstore->nzval = nzval; + Lstore->nzval_colptr = nzval_colptr; + Lstore->rowind = rowind; + Lstore->rowind_colptr = rowind_colptr; + Lstore->col_to_sup = col_to_sup; + Lstore->sup_to_col = sup_to_col; + +} + + +/*! \brief Convert a row compressed storage into a column compressed storage. + */ +void +zCompRow_to_CompCol(int m, int n, int nnz, + doublecomplex *a, int *colind, int *rowptr, + doublecomplex **at, int **rowind, int **colptr) +{ + register int i, j, col, relpos; + int *marker; + + /* Allocate storage for another copy of the matrix. */ + *at = (doublecomplex *) doublecomplexMalloc(nnz); + *rowind = (int *) intMalloc(nnz); + *colptr = (int *) intMalloc(n+1); + marker = (int *) intCalloc(n); + + /* Get counts of each column of A, and set up column pointers */ + for (i = 0; i < m; ++i) + for (j = rowptr[i]; j < rowptr[i+1]; ++j) ++marker[colind[j]]; + (*colptr)[0] = 0; + for (j = 0; j < n; ++j) { + (*colptr)[j+1] = (*colptr)[j] + marker[j]; + marker[j] = (*colptr)[j]; + } + + /* Transfer the matrix into the compressed column storage. */ + for (i = 0; i < m; ++i) { + for (j = rowptr[i]; j < rowptr[i+1]; ++j) { + col = colind[j]; + relpos = marker[col]; + (*rowind)[relpos] = i; + (*at)[relpos] = a[j]; + ++marker[col]; + } + } + + SUPERLU_FREE(marker); +} + + +void +zPrint_CompCol_Matrix(char *what, SuperMatrix *A) +{ + NCformat *Astore; + register int i,n; + double *dp; + + printf("\nCompCol matrix %s:\n", what); + printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype); + n = A->ncol; + Astore = (NCformat *) A->Store; + dp = (double *) Astore->nzval; + printf("nrow %d, ncol %d, nnz %d\n", A->nrow,A->ncol,Astore->nnz); + printf("nzval: "); + for (i = 0; i < 2*Astore->colptr[n]; ++i) printf("%f ", dp[i]); + printf("\nrowind: "); + for (i = 0; i < Astore->colptr[n]; ++i) printf("%d ", Astore->rowind[i]); + printf("\ncolptr: "); + for (i = 0; i <= n; ++i) printf("%d ", Astore->colptr[i]); + printf("\n"); + fflush(stdout); +} + +void +zPrint_SuperNode_Matrix(char *what, SuperMatrix *A) +{ + SCformat *Astore; + register int i, j, k, c, d, n, nsup; + double *dp; + int *col_to_sup, *sup_to_col, *rowind, *rowind_colptr; + + printf("\nSuperNode matrix %s:\n", what); + printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype); + n = A->ncol; + Astore = (SCformat *) A->Store; + dp = (double *) Astore->nzval; + col_to_sup = Astore->col_to_sup; + sup_to_col = Astore->sup_to_col; + rowind_colptr = Astore->rowind_colptr; + rowind = Astore->rowind; + printf("nrow %d, ncol %d, nnz %d, nsuper %d\n", + A->nrow,A->ncol,Astore->nnz,Astore->nsuper); + printf("nzval:\n"); + for (k = 0; k <= Astore->nsuper; ++k) { + c = sup_to_col[k]; + nsup = sup_to_col[k+1] - c; + for (j = c; j < c + nsup; ++j) { + d = Astore->nzval_colptr[j]; + for (i = rowind_colptr[c]; i < rowind_colptr[c+1]; ++i) { + printf("%d\t%d\t%e\t%e\n", rowind[i], j, dp[d], dp[d+1]); + d += 2; + } + } + } +#if 0 + for (i = 0; i < 2*Astore->nzval_colptr[n]; ++i) printf("%f ", dp[i]); +#endif + printf("\nnzval_colptr: "); + for (i = 0; i <= n; ++i) printf("%d ", Astore->nzval_colptr[i]); + printf("\nrowind: "); + for (i = 0; i < Astore->rowind_colptr[n]; ++i) + printf("%d ", Astore->rowind[i]); + printf("\nrowind_colptr: "); + for (i = 0; i <= n; ++i) printf("%d ", Astore->rowind_colptr[i]); + printf("\ncol_to_sup: "); + for (i = 0; i < n; ++i) printf("%d ", col_to_sup[i]); + printf("\nsup_to_col: "); + for (i = 0; i <= Astore->nsuper+1; ++i) + printf("%d ", sup_to_col[i]); + printf("\n"); + fflush(stdout); +} + +void +zPrint_Dense_Matrix(char *what, SuperMatrix *A) +{ + DNformat *Astore = (DNformat *) A->Store; + register int i, j, lda = Astore->lda; + double *dp; + + printf("\nDense matrix %s:\n", what); + printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype); + dp = (double *) Astore->nzval; + printf("nrow %d, ncol %d, lda %d\n", A->nrow,A->ncol,lda); + printf("\nnzval: "); + for (j = 0; j < A->ncol; ++j) { + for (i = 0; i < 2*A->nrow; ++i) printf("%f ", dp[i + j*2*lda]); + printf("\n"); + } + printf("\n"); + fflush(stdout); +} + +/*! \brief Diagnostic print of column "jcol" in the U/L factor. + */ +void +zprint_lu_col(char *msg, int jcol, int pivrow, int *xprune, GlobalLU_t *Glu) +{ + int i, k, fsupc; + int *xsup, *supno; + int *xlsub, *lsub; + doublecomplex *lusup; + int *xlusup; + doublecomplex *ucol; + int *usub, *xusub; + + xsup = Glu->xsup; + supno = Glu->supno; + lsub = Glu->lsub; + xlsub = Glu->xlsub; + lusup = (doublecomplex *) Glu->lusup; + xlusup = Glu->xlusup; + ucol = (doublecomplex *) Glu->ucol; + usub = Glu->usub; + xusub = Glu->xusub; + + printf("%s", msg); + printf("col %d: pivrow %d, supno %d, xprune %d\n", + jcol, pivrow, supno[jcol], xprune[jcol]); + + printf("\tU-col:\n"); + for (i = xusub[jcol]; i < xusub[jcol+1]; i++) + printf("\t%d%10.4f, %10.4f\n", usub[i], ucol[i].r, ucol[i].i); + printf("\tL-col in rectangular snode:\n"); + fsupc = xsup[supno[jcol]]; /* first col of the snode */ + i = xlsub[fsupc]; + k = xlusup[jcol]; + while ( i < xlsub[fsupc+1] && k < xlusup[jcol+1] ) { + printf("\t%d\t%10.4f, %10.4f\n", lsub[i], lusup[k].r, lusup[k].i); + i++; k++; + } + fflush(stdout); +} + + +/*! \brief Check whether tempv[] == 0. This should be true before and after calling any numeric routines, i.e., "panel_bmod" and "column_bmod". + */ +void zcheck_tempv(int n, doublecomplex *tempv) +{ + int i; + + for (i = 0; i < n; i++) { + if ((tempv[i].r != 0.0) || (tempv[i].i != 0.0)) + { + fprintf(stderr,"tempv[%d] = {%f, %f}\n", i, tempv[i].r, tempv[i].i); + ABORT("zcheck_tempv"); + } + } +} + + +void +zGenXtrue(int n, int nrhs, doublecomplex *x, int ldx) +{ + int i, j; + for (j = 0; j < nrhs; ++j) + for (i = 0; i < n; ++i) { + x[i + j*ldx].r = 1.0; + x[i + j*ldx].i = 0.0; + } +} + +/*! \brief Let rhs[i] = sum of i-th row of A, so the solution vector is all 1's + */ +void +zFillRHS(trans_t trans, int nrhs, doublecomplex *x, int ldx, + SuperMatrix *A, SuperMatrix *B) +{ + NCformat *Astore; + doublecomplex *Aval; + DNformat *Bstore; + doublecomplex *rhs; + doublecomplex one = {1.0, 0.0}; + doublecomplex zero = {0.0, 0.0}; + int ldc; + char transc[1]; + + Astore = A->Store; + Aval = (doublecomplex *) Astore->nzval; + Bstore = B->Store; + rhs = Bstore->nzval; + ldc = Bstore->lda; + + if ( trans == NOTRANS ) *(unsigned char *)transc = 'N'; + else *(unsigned char *)transc = 'T'; + + sp_zgemm(transc, "N", A->nrow, nrhs, A->ncol, one, A, + x, ldx, zero, rhs, ldc); + +} + +/*! \brief Fills a doublecomplex precision array with a given value. + */ +void +zfill(doublecomplex *a, int alen, doublecomplex dval) +{ + register int i; + for (i = 0; i < alen; i++) a[i] = dval; +} + + + +/*! \brief Check the inf-norm of the error vector + */ +void zinf_norm_error(int nrhs, SuperMatrix *X, doublecomplex *xtrue) +{ + DNformat *Xstore; + double err, xnorm; + doublecomplex *Xmat, *soln_work; + doublecomplex temp; + int i, j; + + Xstore = X->Store; + Xmat = Xstore->nzval; + + for (j = 0; j < nrhs; j++) { + soln_work = &Xmat[j*Xstore->lda]; + err = xnorm = 0.0; + for (i = 0; i < X->nrow; i++) { + z_sub(&temp, &soln_work[i], &xtrue[i]); + err = SUPERLU_MAX(err, z_abs(&temp)); + xnorm = SUPERLU_MAX(xnorm, z_abs(&soln_work[i])); + } + err = err / xnorm; + printf("||X - Xtrue||/||X|| = %e\n", err); + } +} + + + +/*! \brief Print performance of the code. */ +void +zPrintPerf(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage, + double rpg, double rcond, double *ferr, + double *berr, char *equed, SuperLUStat_t *stat) +{ + SCformat *Lstore; + NCformat *Ustore; + double *utime; + flops_t *ops; + + utime = stat->utime; + ops = stat->ops; + + if ( utime[FACT] != 0. ) + printf("Factor flops = %e\tMflops = %8.2f\n", ops[FACT], + ops[FACT]*1e-6/utime[FACT]); + printf("Identify relaxed snodes = %8.2f\n", utime[RELAX]); + if ( utime[SOLVE] != 0. ) + printf("Solve flops = %.0f, Mflops = %8.2f\n", ops[SOLVE], + ops[SOLVE]*1e-6/utime[SOLVE]); + + Lstore = (SCformat *) L->Store; + Ustore = (NCformat *) U->Store; + printf("\tNo of nonzeros in factor L = %d\n", Lstore->nnz); + printf("\tNo of nonzeros in factor U = %d\n", Ustore->nnz); + printf("\tNo of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz); + + printf("L\\U MB %.3f\ttotal MB needed %.3f\n", + mem_usage->for_lu/1e6, mem_usage->total_needed/1e6); + printf("Number of memory expansions: %d\n", stat->expansions); + + printf("\tFactor\tMflops\tSolve\tMflops\tEtree\tEquil\tRcond\tRefine\n"); + printf("PERF:%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f\n", + utime[FACT], ops[FACT]*1e-6/utime[FACT], + utime[SOLVE], ops[SOLVE]*1e-6/utime[SOLVE], + utime[ETREE], utime[EQUIL], utime[RCOND], utime[REFINE]); + + printf("\tRpg\t\tRcond\t\tFerr\t\tBerr\t\tEquil?\n"); + printf("NUM:\t%e\t%e\t%e\t%e\t%s\n", + rpg, rcond, ferr[0], berr[0], equed); + +} + + + + +print_doublecomplex_vec(char *what, int n, doublecomplex *vec) +{ + int i; + printf("%s: n %d\n", what, n); + for (i = 0; i < n; ++i) printf("%d\t%f%f\n", i, vec[i].r, vec[i].i); + return 0; +} + diff --git a/src/Libraries/superlu-5.2.1/superlu-5.2.1.c.error_in_compliling b/src/Libraries/superlu-5.2.1/superlu-5.2.1.c.error_in_compliling new file mode 100644 index 00000000..6245f441 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/superlu-5.2.1.c.error_in_compliling @@ -0,0 +1,65 @@ +#if defined(__cplusplus) + extern C { +#endif + +#include "./SRC/dgssv.c" +#include "./SRC/dgssvx.c" +#include "./SRC/dsp_blas2.c" +#include "./SRC/dsp_blas3.c" +#include "./SRC/dgscon.c" +#include "./SRC/dlangs.c" +#include "./SRC/dgsequ.c" +#include "./SRC/dlaqgs.c" +#include "./SRC/dpivotgrowth.c" +#include "./SRC/dgsrfs.c" +#include "./SRC/dgstrf.c" +#include "./SRC/dgstrs.c" +#include "./SRC/dcopy_to_ucol.c" +#include "./SRC/dsnode_dfs.c" +#include "./SRC/dsnode_bmod.c" +#include "./SRC/dpanel_dfs.c" +#include "./SRC/dpanel_bmod.c" +#include "./SRC/dreadhb.c" +#include "./SRC/dreadrb.c" +#include "./SRC/dreadtriple.c" +#include "./SRC/dcolumn_dfs.c" +#include "./SRC/dcolumn_bmod.c" +#include "./SRC/dpivotL.c" +#include "./SRC/dpruneL.c" +#include "./SRC/dmemory.c" +#include "./SRC/dutil.c" +#include "./SRC/dmyblas2.c" +#include "./SRC/dgsisx.c" +#include "./SRC/dgsitrf.c" +#include "./SRC/dldperm.c" +#include "./SRC/ilu_ddrop_row.c" +#include "./SRC/ilu_dsnode_dfs.c" +#include "./SRC/ilu_dcolumn_dfs.c" +#include "./SRC/ilu_dpanel_dfs.c" +#include "./SRC/ilu_dcopy_to_ucol.c" +#include "./SRC/ilu_dpivotL.c" +#include "./SRC/ddiagonal.c" +#include "./SRC/dlacon2.c" +#include "./SRC/superlu_timer.c" +#include "./SRC/util.c" +#include "./SRC/memory.c" +#include "./SRC/get_perm_c.c" +#include "./SRC/mmd.c" +#include "./SRC/sp_coletree.c" +#include "./SRC/sp_preorder.c" +#include "./SRC/sp_ienv.c" +#include "./SRC/relax_snode.c" +#include "./SRC/heap_relax_snode.c" +#include "./SRC/colamd.c" +#include "./SRC/ilu_relax_snode.c" +#include "./SRC/ilu_heap_relax_snode.c" +#include "./SRC/mark_relax.c" +#include "./SRC/mc64ad.c" +#include "./SRC/qselect.c" +#include "./SRC/input_error.c" +#include "./SRC/smach.c" +#include "./SRC/dmach.c" + +#if defined(__cplusplus) + } +#endif diff --git a/src/Libraries/superlu-5.2.1/superlu-5.2.1.h b/src/Libraries/superlu-5.2.1/superlu-5.2.1.h new file mode 100644 index 00000000..e3efffa8 --- /dev/null +++ b/src/Libraries/superlu-5.2.1/superlu-5.2.1.h @@ -0,0 +1 @@ +#include "./SRC/slu_ddefs.h" diff --git a/src/Libraries/superlu.h b/src/Libraries/superlu.h new file mode 100644 index 00000000..5acc14da --- /dev/null +++ b/src/Libraries/superlu.h @@ -0,0 +1 @@ +#include "./superlu-5.2.1/superlu-5.2.1.h" diff --git a/src/Main/Bil.c b/src/Main/Bil.c index 9c378016..c95308f3 100644 --- a/src/Main/Bil.c +++ b/src/Main/Bil.c @@ -348,6 +348,7 @@ void Bil_PrintUsage(char* path) Message_Direct(" Available methods are:\n") ; Message_Direct(" - crout : CROUT method (default),\n") ; Message_Direct(" - slu : SuperLU (if installed).\n") ; + Message_Direct(" - ma38 : HSL-MA38 (if installed).\n") ; #endif Message_Direct(" -post \"fmt\" Generates the post-processing files \n") ; diff --git a/src/Main/Context.c b/src/Main/Context.c index 379c22b3..c0b70879 100644 --- a/src/Main/Context.c +++ b/src/Main/Context.c @@ -107,6 +107,18 @@ void (Context_Initialize)(Context_t* ctx,int argc,char** argv) } else { Message_FatalError("Missing solver") ; } + + /* Skip two more entries if the following entry is "-ff" + * i.e. an input for a Fill Factor for multi-frontal methods */ + { + if(!strncmp(argv[i + 1],"-ff",strlen(argv[i + 1]))) { + if(i + 2 < argc) { + i += 2 ; + } else { + Message_FatalError("Missing solver") ; + } + } + } } else if(strncmp(argv[i],"-debug",strlen(argv[i])) == 0) { Context_GetDebug(ctx) = (char**) argv + i ; diff --git a/src/Makefile b/src/Makefile index 1390aff6..61d96891 100644 --- a/src/Makefile +++ b/src/Makefile @@ -141,7 +141,7 @@ ${DIRMODELFILES}%.o: ${DIRMODELFILES}%.c ${DIRMODELFILES}%.o: ${DIRMODELFILES}%.cpp @echo "\nCompilation of the C++ model: "$< - ${CC} ${OPTIM} ${CFLAGS-MODELS} -D 'BASENAME=${basename ${notdir $@}}' -c $< -o $@ + ${CPP} ${OPTIM} ${CFLAGS-MODELS} -D 'BASENAME=${basename ${notdir $@}}' -c $< -o $@ ${DIRMODULEFILES}%.o: ${DIRMODULEFILES}%.c @echo "\nCompilation of the C module: "$< @@ -149,7 +149,7 @@ ${DIRMODULEFILES}%.o: ${DIRMODULEFILES}%.c ${DIRMODULEFILES}%.o: ${DIRMODULEFILES}%.cpp @echo "\nCompilation of the C++ module: "$< - ${CC} ${OPTIM} ${CFLAGS-MODULES} -D 'BASENAME=${basename ${notdir $@}}' -c $< -o $@ + ${CPP} ${OPTIM} ${CFLAGS-MODULES} -D 'BASENAME=${basename ${notdir $@}}' -c $< -o $@ %.o: %.c @echo "\nCompilation of the C source: "$< @@ -157,7 +157,7 @@ ${DIRMODULEFILES}%.o: ${DIRMODULEFILES}%.cpp %.o: %.cpp @echo "\nCompilation of the C++ source: "$< - ${CC} ${OPTIM} ${CFLAGS} -c $< -o $@ + ${CPP} ${OPTIM} ${CFLAGS} -c $< -o $@ %.o: %.f @echo "\nCompilation of the fortran source: "$< diff --git a/src/Models/ConstitutiveLaws/Plasticity.c b/src/Models/ConstitutiveLaws/Plasticity.c index 6a7e27b8..7290d943 100644 --- a/src/Models/ConstitutiveLaws/Plasticity.c +++ b/src/Models/ConstitutiveLaws/Plasticity.c @@ -15,12 +15,12 @@ typedef double (Plasticity_Criterion_t)(Plasticity_t*,const double*,const dou /* Drucker-Prager */ static int pmDruckerPrager(const char* s) ; static double Plasticity_CriterionDruckerPrager(Plasticity_t*,const double*,const double,const double,const double,const double,const double,const double) ; -static double Plasticity_ReturnMappingDruckerPrager(Plasticity_t*,const double,const double,const double,const double,const double) ; +static double Plasticity_ReturnMappingDruckerPrager(Plasticity_t*,double*,double*,double*,const double,const double,const double,const double,const double) ; /* Cam-Clay */ static int pmCamClay(const char* s) ; -static double Plasticity_CriterionCamClay(Plasticity_t*,const double*,const double,double*,double*,double*,const double,const double,const double,const double) ; +static double Plasticity_CriterionCamClay(Plasticity_t*,const double*,const double,const double,const double,const double,const double) ; static double Plasticity_ReturnMappingCamClay(Plasticity_t*,double*,double*,double*,const double,const double,const double,const double,const double) ; diff --git a/src/Models/ModelFiles/ESAC1.c b/src/Models/ModelFiles/ESAC1.c index f516eecd..0f24a7b6 100644 --- a/src/Models/ModelFiles/ESAC1.c +++ b/src/Models/ModelFiles/ESAC1.c @@ -1739,7 +1739,7 @@ void ComputeSecondaryVariables(Element_t* el,double t,double dt,double* x) double zn_si_s = 1 ; double zn_ca_s = x[U_ZN_Ca_S] ; double zn_al_s = x[U_ZN_Al_S] ; - double c_cl = 0 ; + double c_cl = 1.e-99 ; double psi = x[U_PSI] ; /* Solve cement chemistry */ diff --git a/src/Models/ModelFiles/Sulfaco.c b/src/Models/ModelFiles/Sulfaco.c index d1ac1174..5c9a25b9 100644 --- a/src/Models/ModelFiles/Sulfaco.c +++ b/src/Models/ModelFiles/Sulfaco.c @@ -444,13 +444,13 @@ static double phi0 ; static double r_afm,r_aft,r_c3ah6,r_csh2 ; static double n_ca_ref,n_si_ref,n_al_ref ; static double n_afm_0,n_aft_0,n_c3ah6_0,n_csh2_0 ; -static double a_AFt ; +static double ai_AFt ; static double RT ; static Curve_t* satcurve ; static double K_bulk ; static double strain0 ; static double strainf ; -static double a_p ; +static double ap_AFt ; static double alphacoef ; static double betacoef ; @@ -576,7 +576,7 @@ int pm(const char *s) else if(strcmp(s,"R_AFt") == 0) return (13) ; else if(strcmp(s,"R_C3AH6") == 0) return (14) ; else if(strcmp(s,"R_CSH2") == 0) return (15) ; - else if(strcmp(s,"a_AFt") == 0) return (16) ; + else if(strcmp(s,"A_i") == 0) return (16) ; else if(strcmp(s,"K_bulk") == 0) return (17) ; else if(strcmp(s,"Strain0") == 0) return (18) ; else if(strcmp(s,"Strainf") == 0) return (19) ; @@ -601,11 +601,11 @@ void GetProperties(Element_t* el) r_aft = GetProperty("R_AFt") ; r_c3ah6 = GetProperty("R_C3AH6") ; r_csh2 = GetProperty("R_CSH2") ; - a_AFt = GetProperty("a_AFt") ; + ai_AFt = GetProperty("A_i") ; K_bulk = GetProperty("K_bulk") ; strain0 = GetProperty("Strain0") ; strainf = GetProperty("Strainf") ; - a_p = GetProperty("A_p") ; + ap_AFt = GetProperty("A_p") ; alphacoef = GetProperty("AlphaCoef") ; betacoef = GetProperty("BetaCoef") ; @@ -1845,7 +1845,7 @@ void ComputeSecondaryVariables(Element_t* el,double t,double dt,double* x) double strain_n = x[I_Strain_n] ; double straind_n = x[I_Straind_n] ; double beta_p = PoreWallEquilibriumSaturationIndex(beta_pn,strain_n,straind_n,s_aft,s_c,dt) ; - double strain = strain_n + dt*a_p*(1 - beta_p/s_aft) ; + double strain = strain_n + dt*ap_AFt*(1 - beta_p/s_aft) ; /* Compute the crystal pore deformation */ double varphi_c = s_c * strain ; @@ -2153,10 +2153,10 @@ double Radius(double r_n,double s_aft,double dt,Element_t* el) /* Kinetic law */ /* Modified 03/06/2017 */ - double eq = s_l - s_ln + dt*a_AFt*(1 - beta/s_aft) ; - double deq = ds_l - dt*a_AFt*dbeta/s_aft ; - //double eq = s_l - s_ln + dt*a_AFt*(s_aft/beta - 1) ; - //double deq = ds_l - dt*a_AFt*s_aft*dbeta/beta/beta ; + double eq = s_l - s_ln + dt*ai_AFt*(1 - beta/s_aft) ; + double deq = ds_l - dt*ai_AFt*dbeta/s_aft ; + //double eq = s_l - s_ln + dt*ai_AFt*(s_aft/beta - 1) ; + //double deq = ds_l - dt*ai_AFt*s_aft*dbeta/beta/beta ; double dr = (fabs(deq) > 0) ? - eq/deq : 0. ; @@ -2236,8 +2236,8 @@ double PoreWallEquilibriumSaturationIndex(double beta_pn,double strain_n,double int i ; for(i = 0 ; i < iterations ; i++) { - double strain = strain_n + dt*a_p*(1 - beta_p/s_aft) ; - double dstrain = - dt*a_p/s_aft ; + double strain = strain_n + dt*ap_AFt*(1 - beta_p/s_aft) ; + double dstrain = - dt*ap_AFt/s_aft ; double stress = ElasticDamageStress(strain,straind_n) ; double dstress = dElasticDamageStress(strain,straind_n) ; double pc = CrystallizationPressure(beta_p) ; diff --git a/src/Modules/ModuleFiles/Module1.c b/src/Modules/ModuleFiles/Module1.c index 490ddb49..58617c82 100644 --- a/src/Modules/ModuleFiles/Module1.c +++ b/src/Modules/ModuleFiles/Module1.c @@ -395,10 +395,10 @@ static int Algorithm(DataSet_t* jdd,Solutions_t* sols,Solver_t* solver,OutputF if(IterProcess_ConvergenceIsMet(iterprocess)) break ; { - char* level = Options_GetPrintLevel(options) ; - - if(!strcmp(level,"2") && IterProcess_LastIterationIsNotReached(iterprocess)) { - IterProcess_PrintCurrentError(iterprocess) ; + if(Options_IsToPrintOutAtEachIteration(options)) { + if(IterProcess_LastIterationIsNotReached(iterprocess)) { + IterProcess_PrintCurrentError(iterprocess) ; + } } } } @@ -537,58 +537,6 @@ int ComputeMatrix(Mesh_t* mesh,double t,double dt,Matrix_t* a) } -#if 0 -int ComputeMatrix(Mesh_t* mesh,double t,double dt,Matrix_t* a) -{ -#define NE (Element_MaxNbOfNodes*Model_MaxNbOfEquations) - int cole[NE],lige[NE] ; - double ke[NE*NE] ; - unsigned int n_el = Mesh_GetNbOfElements(mesh) ; - Element_t* el = Mesh_GetElement(mesh) ; - unsigned int ie ; - double zero = 0. ; - - { - unsigned int nnz = Matrix_GetNbOfNonZeroValues(a) ; - unsigned int j ; - - for(j = 0 ; j < nnz ; j++) Matrix_GetNonZeroValue(a)[j] = zero ; - - Matrix_SetToInitialState(a) ; - } - - for(ie = 0 ; ie < n_el ; ie++) { - int nn = Element_GetNbOfNodes(el + ie) ; - Material_t* mat = Element_GetMaterial(el + ie) ; - - if(mat) { - int neq = Material_GetNbOfEquations(mat) ; - int i ; - - Element_FreeBuffer(el + ie) ; - i = Element_ComputeMatrix(el + ie,t,dt,ke) ; - if(i != 0) return(i) ; - - /* assembling */ - for(i = 0 ; i < nn ; i++) { - Node_t* node_i = Element_GetNode(el + ie,i) ; - int j ; - for(j = 0 ; j < neq ; j++) { - int ij = i*neq + j ; - int jj_col = Element_GetUnknownPosition(el + ie)[ij] ; - int jj_row = Element_GetEquationPosition(el + ie)[ij] ; - cole[ij] = (jj_col >= 0) ? Node_GetMatrixColumnIndex(node_i)[jj_col] : -1 ; - lige[ij] = (jj_row >= 0) ? Node_GetMatrixRowIndex(node_i)[jj_row] : -1 ; - } - } - Matrix_AssembleElementMatrix_(a,ke,cole,lige,nn*neq) ; - } - } - - return(0) ; -#undef NE -} -#endif void ComputeResidu(Mesh_t* mesh,double t,double dt,double* r,Loads_t* loads) diff --git a/src/Solver/CCSformat.h b/src/Solver/CCSFormat.h similarity index 56% rename from src/Solver/CCSformat.h rename to src/Solver/CCSFormat.h index 3cfadff4..0b6bc7db 100644 --- a/src/Solver/CCSformat.h +++ b/src/Solver/CCSFormat.h @@ -3,18 +3,18 @@ -/* class-like structure "CCSformat_t" and attributes */ +/* class-like structure "CCSFormat_t" and attributes */ /* vacuous declarations and typedef names */ -struct CCSformat_s ; typedef struct CCSformat_s CCSformat_t ; +struct CCSFormat_s ; typedef struct CCSFormat_s CCSFormat_t ; /** The getters */ -#define CCSformat_GetNbOfNonZeroValues(a) ((a)->nnz) -#define CCSformat_GetNonZeroValue(a) ((a)->nzval) -#define CCSformat_GetRowIndexOfTheNonZeroValue(a) ((a)->rowind) -#define CCSformat_GetFirstNonZeroValueIndexOfColumn(a) ((a)->colptr) +#define CCSFormat_GetNbOfNonZeroValues(a) ((a)->nnz) +#define CCSFormat_GetNonZeroValue(a) ((a)->nzval) +#define CCSFormat_GetRowIndexOfNonZeroValue(a) ((a)->rowind) +#define CCSFormat_GetFirstNonZeroValueIndexOfColumn(a) ((a)->colptr) @@ -23,8 +23,11 @@ struct CCSformat_s ; typedef struct CCSformat_s CCSformat_t ; /* complete the structure types by using the typedef */ /* Compressed column storage format (known as Harwell-Boeing sparse matrix format) + * nzval contains the non zero values column-wise + * rowind contains the row indices + * colptr points to the columns in both rowind and nzval * If a_ij = nzval[k] then rowind[k] = i and colptr[j] <= k < colptr[j + 1] */ -struct CCSformat_s { +struct CCSFormat_s { unsigned int nnz ; /* nb of non zero values */ double* nzval ; /* Non zero values */ unsigned int* rowind ; /* Row indices of the non zeros */ diff --git a/src/Solver/CRSformat.h b/src/Solver/CRSFormat.h similarity index 62% rename from src/Solver/CRSformat.h rename to src/Solver/CRSFormat.h index 3b8a2bb1..77464de7 100644 --- a/src/Solver/CRSformat.h +++ b/src/Solver/CRSFormat.h @@ -3,20 +3,20 @@ -/* class-like structure "CRSformat_t" and attributes */ +/* class-like structure "CRSFormat_t" and attributes */ /* vacuous declarations and typedef names */ -struct CRSformat_s ; typedef struct CRSformat_s CRSformat_t ; +struct CRSFormat_s ; typedef struct CRSFormat_s CRSFormat_t ; #include "Mesh.h" /** The getters */ -#define CRSformat_GetNbOfNonZeroValues(a) ((a)->nnz) -#define CRSformat_GetNonZeroValue(a) ((a)->nzval) -#define CRSformat_GetColumnIndexOfTheNonZeroValue(a) ((a)->colind) -#define CRSformat_GetFirstNonZeroValueIndexOfRow(a) ((a)->rowptr) +#define CRSFormat_GetNbOfNonZeroValues(a) ((a)->nnz) +#define CRSFormat_GetNonZeroValue(a) ((a)->nzval) +#define CRSFormat_GetColumnIndexOfNonZeroValue(a) ((a)->colind) +#define CRSFormat_GetFirstNonZeroValueIndexOfRow(a) ((a)->rowptr) @@ -24,7 +24,7 @@ struct CRSformat_s ; typedef struct CRSformat_s CRSformat_t ; /* Compressed row storage format * If a_ij = nzval[k] then colind[k] = j and rowptr[i] <= k < rowptr[i + 1] */ -struct CRSformat_s { +struct CRSFormat_s { unsigned int nnz ; /* nb of non zero values */ double* nzval ; /* Non zero values */ unsigned int* colind ; /* Column indices of the non zeros */ diff --git a/src/Solver/CoordinateFormat.c b/src/Solver/CoordinateFormat.c new file mode 100644 index 00000000..c4ffa4a7 --- /dev/null +++ b/src/Solver/CoordinateFormat.c @@ -0,0 +1,155 @@ +#include +#include +#include +#include +#include +#include "Options.h" +#include "Mesh.h" +#include "Message.h" +#include "BilLib.h" +#include "CoordinateFormat.h" + + + +CoordinateFormat_t* (CoordinateFormat_Create)(Mesh_t* mesh,Options_t* options) +/** Create a matrix in CoordinateFormat format with duplicate entries */ +{ + CoordinateFormat_t* ac = (CoordinateFormat_t*) malloc(sizeof(CoordinateFormat_t)) ; + + assert(ac) ; + + { + /* Nb of entries */ + { + int nnz = Mesh_ComputeNbOfMatrixEntries(mesh) ; + + CoordinateFormat_GetNbOfNonZeroValues(ac) = nnz ; + } + + /* Allocate memory space for the values */ + { + int nnz = CoordinateFormat_GetNbOfNonZeroValues(ac) ; + /* The length required by ma38 must not be lower than 2*nnz */ + int ff = Options_GetFillFactor(options) ; + int lv = ff*(2*nnz) ; + size_t sz = lv * sizeof(double) ; + double* v = (double*) malloc(sz) ; + + assert(v) ; + + CoordinateFormat_GetLengthOfArrayValue(ac) = lv ; + CoordinateFormat_GetNonZeroValue(ac) = v ; + } + + /* Allocate memory space for the indices, namely: + * the row and column indices; + * some other informations provided by ma38 */ + { + int nnz = CoordinateFormat_GetNbOfNonZeroValues(ac) ; + int n = Mesh_GetNbOfMatrixColumns(mesh) ; + /* The length required by ma38 must not be lower than 3*nnz+2*n+1 */ + int ff = Options_GetFillFactor(options) ; + int lindex = ff*(3*nnz + 2*n + 1) ; + size_t sz = lindex * sizeof(int) ; + int* index = (int*) malloc(sz) ; + + assert(index) ; + + CoordinateFormat_GetLengthOfArrayIndex(ac) = lindex ; + CoordinateFormat_GetIndex(ac) = index ; + } + } + + CoordinateFormat_GetOptions(ac) = options ; + + return(ac) ; +} + + + +void (CoordinateFormat_Delete)(void* self) +{ + CoordinateFormat_t** pac = (CoordinateFormat_t**) self ; + CoordinateFormat_t* ac = *pac ; + + free(CoordinateFormat_GetNonZeroValue(ac)) ; + free(CoordinateFormat_GetIndex(ac)) ; + free(ac) ; + *pac = NULL ; +} + + + + + + + +int CoordinateFormat_AssembleElementMatrix(CoordinateFormat_t* a,Element_t* el,double* ke, int nnz) +/** Assemble the local matrix ke into the global matrix a + * Return the updated nb of entries */ +{ +#define KE(i,j) (ke[(i)*ndof+(j)]) + int ndof = Element_GetNbOfDOF(el) ; + double* val = CoordinateFormat_GetNonZeroValue(a) ; + int* colind = CoordinateFormat_GetColumnIndexOfValue(a) ; + int* rowind = CoordinateFormat_GetRowIndexOfValue(a) ; + int* row = Element_ComputeMatrixRowAndColumnIndices(el) ; + int* col = row + ndof ; + + + { + int je ; + + for(je = 0 ; je < ndof ; je++) { + int jcol = col[je] ; + int ie ; + + if(jcol < 0) continue ; + + for(ie = 0 ; ie < ndof ; ie++) { + int irow = row[ie] ; + + if(irow < 0) continue ; + + if(KE(ie,je) == 0.) irow = -1 ; + + val[nnz] = KE(ie,je) ; + colind[nnz] = jcol + 1 ; + rowind[nnz] = irow + 1 ; + + nnz++ ; + } + } + } + + return(nnz) ; + +#undef KE +} + + + + +void CoordinateFormat_PrintMatrix(CoordinateFormat_t* a,const int n_col,const char* keyword) +{ + double* val = CoordinateFormat_GetNonZeroValue(a) ; + int* colind = CoordinateFormat_GetColumnIndexOfValue(a) ; + int* rowind = CoordinateFormat_GetRowIndexOfValue(a) ; + int nnz = CoordinateFormat_GetNbOfNonZeroValues(a) ; + + fprintf(stdout,"\n") ; + fprintf(stdout,"Matrix in coordinate format with duplicate entries:\n") ; + fprintf(stdout,"order = %u ; nb of entries = %d\n",n_col,nnz) ; + fprintf(stdout,"\n") ; + + { + int k ; + + for(k = 0 ; k < nnz ; k++) { + + fprintf(stdout,"%d: K(%d,%d) = %e",k,rowind[k],colind[k],val[k]) ; + + fprintf(stdout,"\n") ; + } + } +} diff --git a/src/Solver/CoordinateFormat.h b/src/Solver/CoordinateFormat.h new file mode 100644 index 00000000..ab0210df --- /dev/null +++ b/src/Solver/CoordinateFormat.h @@ -0,0 +1,59 @@ +#ifndef COORDINATEFORMAT_H +#define COORDINATEFORMAT_H + + + +/* class-like structure "CoordinateFormat_t" and attributes */ + +/* vacuous declarations and typedef names */ +struct CoordinateFormat_s ; typedef struct CoordinateFormat_s CoordinateFormat_t ; + + + +#include "Mesh.h" +#include "Options.h" + +extern CoordinateFormat_t* (CoordinateFormat_Create)(Mesh_t*,Options_t*) ; +extern void (CoordinateFormat_Delete)(void*) ; +extern int (CoordinateFormat_AssembleElementMatrix)(CoordinateFormat_t*,Element_t*,double*,int) ; +extern void (CoordinateFormat_PrintMatrix)(CoordinateFormat_t*,const int,const char*) ; + + + + + +/** The getters */ +#define CoordinateFormat_GetNbOfNonZeroValues(F) ((F)->nnz) +#define CoordinateFormat_GetLengthOfArrayValue(F) ((F)->lvalue) +#define CoordinateFormat_GetLengthOfArrayIndex(F) ((F)->lindex) +#define CoordinateFormat_GetNonZeroValue(F) ((F)->value) +#define CoordinateFormat_GetIndex(F) ((F)->index) +#define CoordinateFormat_GetOptions(F) ((F)->options) + + + + +#define CoordinateFormat_GetColumnIndexOfValue(F) \ + (CoordinateFormat_GetIndex(F) + CoordinateFormat_GetNbOfNonZeroValues(F)) + + +#define CoordinateFormat_GetRowIndexOfValue(F) \ + CoordinateFormat_GetIndex(F) + + +/* complete the structure types by using the typedef */ + +/* Coordinate format: + * a_ij = val[k] ; j = colind[k] ; i = rowind[k] for k = 0,..,nnz-1 */ +struct CoordinateFormat_s { + int nnz ; /* Nb of non zero values */ + int lvalue ; /* Lentgth of array value */ + int lindex ; /* Length of array index */ + double* value ; /* Values */ + int* index ; /* Indices */ + int* colind ; /* Column indices of the non zeros */ + int* rowind ; /* Row indices of the non zeros */ + Options_t* options ; +} ; + +#endif diff --git a/src/Solver/CroutMethod.c b/src/Solver/CroutMethod.c new file mode 100644 index 00000000..ba8641ff --- /dev/null +++ b/src/Solver/CroutMethod.c @@ -0,0 +1,298 @@ +#include +#include +#include +#include +#include +#include "CroutMethod.h" +#include "Matrix.h" +#include "Message.h" +#include "LDUSKLFormat.h" + + +static int ludcmp(LDUSKLFormat_t*,int) ; +static void lubksb(LDUSKLFormat_t*,double*,double*,int) ; + + + +/* + * CROUT method + * ------------ + */ +int CroutMethod_Solve(Solver_t* solver) +/** Resolution of a.x = b by Crout's method */ +{ + Matrix_t* a = Solver_GetMatrix(solver) ; + double* b = Solver_GetRHS(solver) ; + double* x = Solver_GetSolution(solver) ; + int n = Solver_GetNbOfColumns(solver) ; + LDUSKLFormat_t* askl = (LDUSKLFormat_t*) Matrix_GetStorage(a) ; + + if(Matrix_WasNotModified(a)) { + int i = ludcmp(askl,n) ; + + Matrix_SetToModifiedState(a) ; + + if(i < 0) return(i) ; + } + + lubksb(askl,x,b,n) ; + + return(0) ; +} + + +int ludcmp(LDUSKLFormat_t* a,int n) +/** + * Replace the given matrix a by the LDU decomposition (after NR). + * "a" is arranged as a skyline matrix given as "LDU". + + * D pointer to the diagonal. + * U pointer to the strictly upper triangular matrix. + * L pointer to the strictly lower triangular matrix. + * + * U[j] pointer to the first non zero value of the column j + 1. + * L[i] pointer to the first non zero value of the row i + 1. + * U[j] - U[j - 1] is the height of the column j of the upper matrix. + * L[i] - L[i - 1] is the height of the row i of the lower matrix. + * + * diagonal : a(i,i) = D[i] + * upper matrix : a(i,j) = (U[j] - j)[i] if i1 <= i < j , a(i,j) = 0 otherwise + * lower matrix : a(i,j) = (L[i] - i)[j] if j1 <= j < i , a(i,j) = 0 otherwise + * with i1 = (j - U[j] + U[j-1]) + * and j1 = (i - L[i] + L[i-1]). + */ +{ +#define UpperColumn(j) (LDUSKLFormat_GetUpperColumn(a,j)) +#define LowerRow(i) (LDUSKLFormat_GetLowerRow(a,i)) + double* diag = LDUSKLFormat_GetDiagonal(a) ; + double dum = 0. ; + double zero = 0. ; + int j ; + + + /* Loop on columns (Crout's algorithm) */ + for(j = 0 ; j < n ; j++) { + double* colj = UpperColumn(j) ; + /* i1 is the row index which starts the column j */ + int i1 = (j > 0) ? LDUSKLFormat_RowIndexStartingColumn(a,j) : 0 ; + int i ; + + /* 1. U_ij = a_ij - sum_1^{i-1} L_ik * U_kj for i <= j */ + if(j > 0) { /* U(0,0) unchanged */ + + /* 1.a For i < j */ + for(i = i1 + 1 ; i < j ; i++) { /* a(i1,j) unchanged */ + /* j1 is the column index which starts the row i */ + int j1 = LDUSKLFormat_ColumnIndexStartingRow(a,i) ; + int k1 = (i1 > j1) ? i1 : j1 ; + double* rowi = LowerRow(i) ; + int k ; + + for(k = k1 ; k < i ; k++) { + colj[i] -= rowi[k]*colj[k] ; + } + } + + /* 1.b For i = j */ + { + /* Column index which starts the row j */ + int j1 = LDUSKLFormat_ColumnIndexStartingRow(a,j) ; + int k1 = (i1 > j1) ? i1 : j1 ; + double* rowj = LowerRow(j) ; + int k ; + + for(k = k1 ; k < j ; k++) { + diag[j] -= rowj[k]*colj[k] ; + } + } + } + + if(diag[j] == zero) { + Message_Direct("\nludcmp: diagonal term (pivot) is zero at row/col %d",j) ; + return(-1) ; + + } else dum = 1./diag[j] ; + + /* 2. L(i,j) = (a(i,j) - sum_1^{j-1}L(i,k)*U(k,j))/U(j,j) pour i > j */ + for(i = j + 1 ; i < n ; i++) { + /* Column index which starts the row i */ + int j1 = LDUSKLFormat_ColumnIndexStartingRow(a,i) ; + + if(j1 <= j) { /* a(i,j) i > j is zero */ + int k1 = (i1 > j1) ? i1 : j1 ; + double* rowi = LowerRow(i) ; + int k ; + + for(k = k1 ; k < j ; k++) { + rowi[j] -= rowi[k]*colj[k] ; + } + + rowi[j] *= dum ; + } + } + } + + return(0) ; +#undef UpperColumn +#undef LowerRow +} + + +void lubksb(LDUSKLFormat_t* a,double* x,double* b,int n) +/* Solve a*x = b. + * Here a is input as its LU decomposition determined by ludcmp. + */ +{ +#define UpperColumn(j) (LDUSKLFormat_GetUpperColumn(a,j)) +#define LowerRow(i) (LDUSKLFormat_GetLowerRow(a,i)) + double* diag = LDUSKLFormat_GetDiagonal(a) ; + int i ; + + if(x != b) { + for(i = 0 ; i < n ; i++) x[i] = b[i] ; + } + + /* Forward substitution : y_i = b_i - sum_0^{i-1} L_ij * y_j */ + for(i = 1 ; i < n ; i++) { /* x[0] unchanged */ + double* rowi = LowerRow(i) ; + /* j1 is the column index which starts the row i */ + int j1 = LDUSKLFormat_ColumnIndexStartingRow(a,i) ; + int j ; + + for(j = j1 ; j < i ; j++) { + x[i] -= rowi[j]*x[j] ; + } + } + + /* Backsubstitution : x_i = (y_i - sum_{i+1}^n U_ij * x_j)/D_ii */ + for(i = n - 1 ; i >= 0 ; i--) { + int j ; + + for(j = i + 1 ; j < n ; j++) { + /* i1 is the row index which starts the column j */ + int i1 = LDUSKLFormat_RowIndexStartingColumn(a,j) ; + + /* a(i,j) = 0 for i < i1 */ + if(i >= i1) { + double* colj = UpperColumn(j) ; + + x[i] -= colj[i]*x[j] ; + } + } + + x[i] /= diag[i] ; + } +#undef UpperColumn +#undef LowerRow +} + + + +/* Not used */ +#ifdef NOTDEFINED + +int ludcmp1(LDUSKLFormat_t* a,int n) +/* +Remplace une matrice par sa decomposition LU (d apres NR). +"a" est une matrice ligne de ciel donnee sous la forme "LDU": + + D = a->d , U = a->u , L = a->l + + D pointe sur le premier terme de la diagonale. + U[0] pointe sur le premier terme non nul de la matrice triangulaire sup. + L[0] pointe sur le premier terme non nul de la matrice triangulaire inf. + U[j] - U[j-1] donne la hauteur de la colonne j de la matrice sup. + L[i] - L[i-1] donne la longueur de la ligne i de la matrice inf. + +diagonale : a(i,i) = D[i] +matrice sup : a(i,j) = *(U[j]-j+i) si i1 <= i < j , a(i,j) = 0 sinon +matrice inf : a(i,j) = *(L[i]-i+j) si j1 <= j < i , a(i,j) = 0 sinon +avec i1 = (j - U[j] + U[j-1]) et j1 = (i - L[i] + L[i-1]). +*/ +{ +#define PU(i,j) (LDUSKLFormat_GetPointerToUpperColumn(a)[j] - j + i) +#define PL(i,j) (LDUSKLFormat_GetPointerToLowerRow(a)[i] - i + j) + double** u = LDUSKLFormat_GetPointerToUpperColumn(a) ; + double** l = LDUSKLFormat_GetPointerToLowerRow(a); + double* d = LDUSKLFormat_GetDiagonal(a) ; + int i,j,k,i1 = 0,j1,k1 ; + double dum = 0.,*p,*pl,*pu ; + double zero = 0. ; + + /* boucle sur les colonnes (algorithme de Crout) */ + for(j=0;j<(int) n;j++) { + /* 1. U(i,j) = a(i,j) - sum_1^{i-1}L(i,k)*U(k,j) pour i<=j */ + if(j>0) { /* U(0,0) inchange */ + /* 1.a pour i j1) ? i1 : j1 ; + p = PU(i,j) ; /* pointe sur a(i,j) ik1 */ + pu = PU(k1,j) ; /* pointe sur a(k1,j) k1 j1) ? i1 : j1 ; + p = d + j ; /* pointe sur a(j,j) */ + pl = PL(i,k1) ; /* pointe sur a(i,k1) i>k1 */ + pu = PU(k1,j) ; /* pointe sur a(k1,j) k1j */ + if(j==0) i1 = 0 ; + for(i=j+1;i<(int) n;i++) { + j1 = i - (l[i] - l[i-1]) ; /* 1ere colonne non nulle de la ligne i */ + if(j1 > j) continue ; /* a(i,j) i>j est nul */ + k1 = (i1 > j1) ? i1 : j1 ; + p = PL(i,j) ; /* pointe sur a(i,j) i>j */ + pl = PL(i,k1) ; /* pointe sur a(i,k1) i>k1 */ + pu = PU(k1,j) ; /* pointe sur a(k1,j) k1=0;i--) { + p = b+i ; + for(j=i+1;j<(int) n;j++) { + i1 = j - (u[j] - u[j-1]) ; /* 1ere ligne non nulle de la colonne j */ + if(i1 > i) continue ; /* a(i,j) i j) L(i,j) += KE(ie,je) ; + if(i == j) D(i) += KE(ie,je) ; + else if(i < j) U(i,j) += KE(ie,je) ; + else if(i > j) L(i,j) += KE(ie,je) ; + } } } @@ -208,12 +210,12 @@ void LDUSKLformat_AssembleElementMatrix(LDUSKLformat_t* a,double* ke,int* cole,i -void LDUSKLformat_PrintMatrix(LDUSKLformat_t* a,unsigned int n,const char* keyword) +void LDUSKLFormat_PrintMatrix(LDUSKLFormat_t* a,unsigned int n,const char* keyword) { - double* d = LDUSKLformat_GetDiagonal(a) ; - double** u = LDUSKLformat_GetPointerToUpperColumn(a) ; - double** l = LDUSKLformat_GetPointerToLowerRow(a) ; - int nnz = LDUSKLformat_GetNbOfNonZeroValues(a) ; + double* d = LDUSKLFormat_GetDiagonal(a) ; + double** u = LDUSKLFormat_GetPointerToUpperColumn(a) ; + double** l = LDUSKLFormat_GetPointerToLowerRow(a) ; + int nnz = LDUSKLFormat_GetNbOfNonZeroValues(a) ; int irow,jcol ; fprintf(stdout,"\n") ; diff --git a/src/Solver/LDUSKLFormat.h b/src/Solver/LDUSKLFormat.h new file mode 100644 index 00000000..286002c1 --- /dev/null +++ b/src/Solver/LDUSKLFormat.h @@ -0,0 +1,75 @@ +#ifndef LDUSKLFORMAT_H +#define LDUSKLFORMAT_H + + + +/* class-like structure "LDUSKLFormat_t" and attributes */ + +/* vacuous declarations and typedef names */ +struct LDUSKLFormat_s ; typedef struct LDUSKLFormat_s LDUSKLFormat_t ; + + +#include "Mesh.h" + + +extern LDUSKLFormat_t* (LDUSKLFormat_Create)(Mesh_t*) ; +extern void (LDUSKLFormat_Delete)(void*) ; +extern void LDUSKLFormat_AssembleElementMatrix(LDUSKLFormat_t*,double*,int*,int*,int) ; +extern void LDUSKLFormat_PrintMatrix(LDUSKLFormat_t*,unsigned int,const char*) ; + + + + +/** The getters */ +#define LDUSKLFormat_GetNbOfNonZeroValues(a) ((a)->nnz) +#define LDUSKLFormat_GetNonZeroValue(a) ((a)->d) +#define LDUSKLFormat_GetDiagonal(a) ((a)->d) +#define LDUSKLFormat_GetPointerToLowerRow(a) ((a)->l) +#define LDUSKLFormat_GetPointerToUpperColumn(a) ((a)->u) + + + +#define LDUSKLFormat_GetUpperColumn(a,j) \ + (LDUSKLFormat_GetPointerToUpperColumn(a)[j] - (j)) + +#define LDUSKLFormat_GetLowerRow(a,i) \ + (LDUSKLFormat_GetPointerToLowerRow(a)[i] - (i)) + +#define LDUSKLFormat_HeightOfUpperColumn(a,j) \ + ((j > 0) ? (LDUSKLFormat_GetPointerToUpperColumn(a)[j] - \ + LDUSKLFormat_GetPointerToUpperColumn(a)[j - 1]) : 0) + +#define LDUSKLFormat_LengthOfLowerRow(a,i) \ + ((i > 0) ? (LDUSKLFormat_GetPointerToLowerRow(a)[i] - \ + LDUSKLFormat_GetPointerToLowerRow(a)[i - 1]) : 0) + +/* +#define LDUSKLFormat_UpperValue(a,i,j) (LDUSKLFormat_GetUpperColumn(a,j)[i]) +#define LDUSKLFormat_LowerValue(a,i,j) (LDUSKLFormat_GetLowerRow(a,i)[j]) +#define LDUSKLFormat_DiagonalValue(a,i) (LDUSKLFormat_GetDiagonal(a)[i]) +#define LDUSKLFormat_Value(a,i,j) ((i < j) ? LDUSKLFormat_UpperValue(a,i,j) : \ + ((i > j) ? LDUSKLFormat_LowerValue(a,i,j) : \ + LDUSKLFormat_DiagonalValue(a)[i])) +*/ + +#define LDUSKLFormat_ColumnIndexStartingRow(a,i) \ + ((i > 0) ? (i) - LDUSKLFormat_LengthOfLowerRow(a,i) : 0) + +#define LDUSKLFormat_RowIndexStartingColumn(a,j) \ + ((j > 0) ? (j) - LDUSKLFormat_HeightOfUpperColumn(a,j) : 0) + + + + +/* complete the structure types by using the typedef */ + +/* LDU Skyline format */ +struct LDUSKLFormat_s { /* LDU Skyline storage format */ + unsigned int nnz ; /* Nb of non zero values */ + double* d ; /* Diagonal matrix values */ + double** l ; /* Pointer to strictly lower triangular matrix values */ + double** u ; /* Pointer to strictly upper triangular matrix values */ +} ; + + +#endif diff --git a/src/Solver/LDUSKLformat.h b/src/Solver/LDUSKLformat.h deleted file mode 100644 index cbc38359..00000000 --- a/src/Solver/LDUSKLformat.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef LDUSKLFORMAT_H -#define LDUSKLFORMAT_H - - - -/* class-like structure "LDUSKLformat_t" and attributes */ - -/* vacuous declarations and typedef names */ -struct LDUSKLformat_s ; typedef struct LDUSKLformat_s LDUSKLformat_t ; - - -#include "Mesh.h" - - -extern LDUSKLformat_t* (LDUSKLformat_Create)(Mesh_t*) ; -extern void (LDUSKLformat_Delete)(void*) ; -extern void LDUSKLformat_AssembleElementMatrix(LDUSKLformat_t*,double*,int*,int*,int) ; -extern void LDUSKLformat_PrintMatrix(LDUSKLformat_t*,unsigned int,const char*) ; - - - - -/** The getters */ -#define LDUSKLformat_GetNbOfNonZeroValues(a) ((a)->nnz) -#define LDUSKLformat_GetNonZeroValue(a) ((a)->d) -#define LDUSKLformat_GetDiagonal(a) ((a)->d) -#define LDUSKLformat_GetPointerToLowerRow(a) ((a)->l) -#define LDUSKLformat_GetPointerToUpperColumn(a) ((a)->u) - - - -#define LDUSKLformat_GetUpperColumn(a,j) \ - (LDUSKLformat_GetPointerToUpperColumn(a)[j] - (j)) - -#define LDUSKLformat_GetLowerRow(a,i) \ - (LDUSKLformat_GetPointerToLowerRow(a)[i] - (i)) - -#define LDUSKLformat_HeightOfUpperColumn(a,j) \ - ((j > 0) ? (LDUSKLformat_GetPointerToUpperColumn(a)[j] - \ - LDUSKLformat_GetPointerToUpperColumn(a)[j - 1]) : 0) - -#define LDUSKLformat_LengthOfLowerRow(a,i) \ - ((i > 0) ? (LDUSKLformat_GetPointerToLowerRow(a)[i] - \ - LDUSKLformat_GetPointerToLowerRow(a)[i - 1]) : 0) - -/* -#define LDUSKLformat_UpperValue(a,i,j) (LDUSKLformat_GetUpperColumn(a,j)[i]) -#define LDUSKLformat_LowerValue(a,i,j) (LDUSKLformat_GetLowerRow(a,i)[j]) -#define LDUSKLformat_DiagonalValue(a,i) (LDUSKLformat_GetDiagonal(a)[i]) -#define LDUSKLformat_Value(a,i,j) ((i < j) ? LDUSKLformat_UpperValue(a,i,j) : \ - ((i > j) ? LDUSKLformat_LowerValue(a,i,j) : \ - LDUSKLformat_DiagonalValue(a)[i])) -*/ - -#define LDUSKLformat_ColumnIndexStartingRow(a,i) \ - ((i > 0) ? (i) - LDUSKLformat_LengthOfLowerRow(a,i) : 0) - -#define LDUSKLformat_RowIndexStartingColumn(a,j) \ - ((j > 0) ? (j) - LDUSKLformat_HeightOfUpperColumn(a,j) : 0) - - - - -/* complete the structure types by using the typedef */ - -/* LDU Skyline format */ -struct LDUSKLformat_s { /* LDU Skyline storage format */ - unsigned int nnz ; /* nb of non zero values */ - double* d ; /* diagonal matrix values */ - double** l ; /* pointer to strictly lower triangular matrix values */ - double** u ; /* pointer to strictly upper triangular matrix values */ -} ; - - -#endif diff --git a/src/Solver/MA38Method.c b/src/Solver/MA38Method.c new file mode 100644 index 00000000..e9fd31b3 --- /dev/null +++ b/src/Solver/MA38Method.c @@ -0,0 +1,204 @@ +#include +#include +#include +#include +#include +#include +#include "MA38Method.h" +#include "Solver.h" +#include "Message.h" +#include "Matrix.h" + + +#include "CoordinateFormat.h" + + + + +/* + * HSL - MA38 method + * ----------------- + */ +int MA38Method_Solve(Solver_t* solver) +/** Solve a sparse unsymmetric system a.x = b + * by a multifrontal approach through ma38 from HSL + */ +{ + Matrix_t* a = Solver_GetMatrix(solver) ; + CoordinateFormat_t* ac = (CoordinateFormat_t*) Matrix_GetStorage(a) ; + double* b = Solver_GetRHS(solver) ; + double* x = Solver_GetSolution(solver) ; + int n = Solver_GetNbOfColumns(solver) ; + int ne = CoordinateFormat_GetNbOfNonZeroValues(ac) ; + double* w = (double*) Matrix_GetWorkSpace(a) ; + + int lvalue = CoordinateFormat_GetLengthOfArrayValue(ac) ; + int lindex = CoordinateFormat_GetLengthOfArrayIndex(ac) ; + double* value = CoordinateFormat_GetNonZeroValue(ac) ; + int* index = CoordinateFormat_GetIndex(ac) ; + + int keep[20] ; + int icntl[20] ; + double cntl[10] ; + int info[40] ; + double rinfo[20] ; + + /* Initialize controls */ + ma38id_(keep,cntl,icntl) ; + + /* Printing controls: + * 1: Print only error messages, + * 2: + warnings, + * 3: + terse diagnostics + */ + { + Options_t* options = CoordinateFormat_GetOptions(ac) ; + + icntl[2] = 1 ; + + if(Options_IsToPrintOutAtEachIteration(options)) { + icntl[2] = 2 ; + } + } + + /* Factorize the matrix */ + { + int job = 0 ; + bool transa = false ; + + ma38ad_(&n,&ne,&job,&transa,&lvalue,&lindex,value,index,keep,cntl,icntl,info,rinfo) ; + + if(info[0] < 0) { + return(-1) ; + } + } + + /* Solve a * x = b */ + { + int job = 0 ; + bool transc = false ; + + ma38cd_(&n,&job,&transc,&lvalue,&lindex,value,index,keep,b,x,w,cntl,icntl,info,rinfo) ; + + if(info[0] < 0) { + return(-1) ; + } + } + + return(0) ; +} + + + + + + + +/* Not used */ +#ifdef NOTDEFINED + +int ludcmp1(LDUSKLFormat_t* a,int n) +/* +Remplace une matrice par sa decomposition LU (d apres NR). +"a" est une matrice ligne de ciel donnee sous la forme "LDU": + + D = a->d , U = a->u , L = a->l + + D pointe sur le premier terme de la diagonale. + U[0] pointe sur le premier terme non nul de la matrice triangulaire sup. + L[0] pointe sur le premier terme non nul de la matrice triangulaire inf. + U[j] - U[j-1] donne la hauteur de la colonne j de la matrice sup. + L[i] - L[i-1] donne la longueur de la ligne i de la matrice inf. + +diagonale : a(i,i) = D[i] +matrice sup : a(i,j) = *(U[j]-j+i) si i1 <= i < j , a(i,j) = 0 sinon +matrice inf : a(i,j) = *(L[i]-i+j) si j1 <= j < i , a(i,j) = 0 sinon +avec i1 = (j - U[j] + U[j-1]) et j1 = (i - L[i] + L[i-1]). +*/ +{ +#define PU(i,j) (LDUSKLFormat_GetPointerToUpperColumn(a)[j] - j + i) +#define PL(i,j) (LDUSKLFormat_GetPointerToLowerRow(a)[i] - i + j) + double** u = LDUSKLFormat_GetPointerToUpperColumn(a) ; + double** l = LDUSKLFormat_GetPointerToLowerRow(a); + double* d = LDUSKLFormat_GetDiagonal(a) ; + int i,j,k,i1 = 0,j1,k1 ; + double dum = 0.,*p,*pl,*pu ; + double zero = 0. ; + + /* boucle sur les colonnes (algorithme de Crout) */ + for(j=0;j<(int) n;j++) { + /* 1. U(i,j) = a(i,j) - sum_1^{i-1}L(i,k)*U(k,j) pour i<=j */ + if(j>0) { /* U(0,0) inchange */ + /* 1.a pour i j1) ? i1 : j1 ; + p = PU(i,j) ; /* pointe sur a(i,j) ik1 */ + pu = PU(k1,j) ; /* pointe sur a(k1,j) k1 j1) ? i1 : j1 ; + p = d + j ; /* pointe sur a(j,j) */ + pl = PL(i,k1) ; /* pointe sur a(i,k1) i>k1 */ + pu = PU(k1,j) ; /* pointe sur a(k1,j) k1j */ + if(j==0) i1 = 0 ; + for(i=j+1;i<(int) n;i++) { + j1 = i - (l[i] - l[i-1]) ; /* 1ere colonne non nulle de la ligne i */ + if(j1 > j) continue ; /* a(i,j) i>j est nul */ + k1 = (i1 > j1) ? i1 : j1 ; + p = PL(i,j) ; /* pointe sur a(i,j) i>j */ + pl = PL(i,k1) ; /* pointe sur a(i,k1) i>k1 */ + pu = PU(k1,j) ; /* pointe sur a(k1,j) k1=0;i--) { + p = b+i ; + for(j=i+1;j<(int) n;j++) { + i1 = j - (u[j] - u[j-1]) ; /* 1ere ligne non nulle de la colonne j */ + if(i1 > i) continue ; /* a(i,j) ifmt) #define Matrix_GetNbOfRows(MAT) ((MAT)->n) #define Matrix_GetNbOfColumns(MAT) ((MAT)->n) +#define Matrix_GetNbOfEntries(MAT) ((MAT)->len) #define Matrix_GetNbOfNonZeroValues(MAT) ((MAT)->nnz) -#define Matrix_GetNonZeroValue(MAT) ((MAT)->s) +#define Matrix_GetNonZeroValue(MAT) ((MAT)->nzval) #define Matrix_GetWorkSpace(MAT) ((MAT)->work) #define Matrix_GetStorage(MAT) ((MAT)->store) #define Matrix_GetState(MAT) ((MAT)->state) @@ -44,38 +46,11 @@ extern void (Matrix_PrintMatrix)(Matrix_t*,const char* keyword) ; unsigned int k ; \ for(k = 0 ; k < Matrix_GetNbOfNonZeroValues(MAT) ; k++) { \ Matrix_GetNonZeroValue(MAT)[k] = 0. ; \ - Matrix_SetToInitialState(MAT) ; \ } \ + Matrix_GetNbOfEntries(MAT) = 0 ; \ + Matrix_SetToInitialState(MAT) ; \ } while(0) - - - -#include "Element.h" -#include "Node.h" - -#define Matrix_AssembleElementMatrix(MAT,EL,KE) \ - do { \ - int cole[Element_MaxNbOfNodes*Model_MaxNbOfEquations] ; \ - int lige[Element_MaxNbOfNodes*Model_MaxNbOfEquations] ; \ - int nn = Element_GetNbOfNodes(EL) ; \ - int neq = Element_GetNbOfEquations(EL) ; \ - int i ; \ - for(i = 0 ; i < nn ; i++) { \ - Node_t* node_i = Element_GetNode(EL,i) ; \ - int j ; \ - for(j = 0 ; j < neq ; j++) { \ - int ij = i*neq + j ; \ - int jj_col = Element_GetUnknownPosition(EL)[ij] ; \ - int jj_row = Element_GetEquationPosition(EL)[ij] ; \ - cole[ij] = (jj_col >= 0) ? Node_GetMatrixColumnIndex(node_i)[jj_col] : -1 ; \ - lige[ij] = (jj_row >= 0) ? Node_GetMatrixRowIndex(node_i)[jj_row] : -1 ; \ - } \ - } \ - Matrix_AssembleElementMatrix_(MAT,KE,cole,lige,nn*neq) ; \ - } while(0) - - @@ -89,8 +64,9 @@ extern void (Matrix_PrintMatrix)(Matrix_t*,const char* keyword) ; struct Matrix_s { /* Matrix */ MatrixStorageFormat_t fmt ; /* Storage format */ unsigned int n ; /* Nb of rows/columns */ - unsigned int nnz ; /* Nb of non zero terms */ - double* s ; /* Pointer to the non zero terms */ + unsigned int nnz ; /* Nb of non zero values */ + unsigned int len ; /* Nb of entries in nzval */ + double* nzval ; /* Pointer to the non zero values */ void* work ; /* Pointer to a working memory space */ void* store ; /* Pointer to the actual storage of the matrix */ char state ; /* State of the matrix */ diff --git a/src/Solver/MatrixStorageFormat.h b/src/Solver/MatrixStorageFormat.h index 48221c26..d617fa01 100644 --- a/src/Solver/MatrixStorageFormat.h +++ b/src/Solver/MatrixStorageFormat.h @@ -3,12 +3,14 @@ -enum MatrixStorageFormat_e { /* format of the matrix to be stored */ - MatrixStorageFormat_LDUSKL, /* LDU Skyline format */ - MatrixStorageFormat_SuperLU, /* Harwell-Boeing SuperLU format */ - MatrixStorageFormat_CCS, /* Compressed column storage format */ +enum MatrixStorageFormat_e { /* format of the matrix to be stored */ + MatrixStorageFormat_LDUSKL, /* LDU Skyline format */ + MatrixStorageFormat_SKL, /* Skyline format */ + MatrixStorageFormat_SuperLU, /* Harwell-Boeing SuperLU format */ + MatrixStorageFormat_CCS, /* Compressed column storage format */ MatrixStorageFormat_NC = MatrixStorageFormat_CCS, - MatrixStorageFormat_CRS, /* Compressed row storage format */ + MatrixStorageFormat_CRS, /* Compressed row storage format */ + MatrixStorageFormat_Coordinate, /* Coordinate format */ MatrixStorageFormat_NULL } ; diff --git a/src/Solver/NCformat.c b/src/Solver/NCFormat.c similarity index 72% rename from src/Solver/NCformat.c rename to src/Solver/NCFormat.c index 90941eb1..c5ac3228 100644 --- a/src/Solver/NCformat.c +++ b/src/Solver/NCFormat.c @@ -7,17 +7,16 @@ #include "Mesh.h" #include "Message.h" #include "BilLib.h" -#include "NCformat.h" +#include "NCFormat.h" /* Extern functions */ -#ifdef SLU_DIR -NCformat_t* NCformat_Create(Mesh_t* mesh) -/** Create a matrix in NCformat */ +NCFormat_t* NCFormat_Create(Mesh_t* mesh) +/** Create a matrix in NCFormat */ { int n_el = Mesh_GetNbOfElements(mesh) ; int n_col = Mesh_GetNbOfMatrixColumns(mesh) ; @@ -26,7 +25,7 @@ NCformat_t* NCformat_Create(Mesh_t* mesh) int ie ; int i,j ; int nnz_max ; - NCformat_t* asluNC = (NCformat_t*) malloc(sizeof(NCformat_t)) ; + NCFormat_t* asluNC = (NCFormat_t*) malloc(sizeof(NCFormat_t)) ; assert(asluNC) ; @@ -74,7 +73,7 @@ NCformat_t* NCformat_Create(Mesh_t* mesh) assert(colptr) ; - NCformat_GetFirstNonZeroValueIndexOfColumn(asluNC) = colptr ; + NCFormat_GetFirstNonZeroValueIndexOfColumn(asluNC) = colptr ; } { @@ -82,14 +81,14 @@ NCformat_t* NCformat_Create(Mesh_t* mesh) assert(rowind) ; - NCformat_GetRowIndexOfTheNonZeroValue(asluNC) = rowind ; + NCFormat_GetRowIndexOfNonZeroValue(asluNC) = rowind ; } /* initialisation */ { - int* colptr = NCformat_GetFirstNonZeroValueIndexOfColumn(asluNC) ; - int* rowind = NCformat_GetRowIndexOfTheNonZeroValue(asluNC) ; + int* colptr = NCFormat_GetFirstNonZeroValueIndexOfColumn(asluNC) ; + int* rowind = NCFormat_GetRowIndexOfNonZeroValue(asluNC) ; for(i = 0 ; i < n_col + 1 ; i++) colptr[i] = 0 ; @@ -149,8 +148,8 @@ NCformat_t* NCformat_Create(Mesh_t* mesh) /* compression de rowind */ { - int* colptr = NCformat_GetFirstNonZeroValueIndexOfColumn(asluNC) ; - int* rowind = NCformat_GetRowIndexOfTheNonZeroValue(asluNC) ; + int* colptr = NCFormat_GetFirstNonZeroValueIndexOfColumn(asluNC) ; + int* rowind = NCFormat_GetRowIndexOfNonZeroValue(asluNC) ; colptr[0] = 0 ; @@ -169,37 +168,41 @@ NCformat_t* NCformat_Create(Mesh_t* mesh) { - int* colptr = NCformat_GetFirstNonZeroValueIndexOfColumn(asluNC) ; + int* colptr = NCFormat_GetFirstNonZeroValueIndexOfColumn(asluNC) ; - if(nnz_max < colptr[n_col]) arret("NCformat_Create: memory issue") ; + if(nnz_max < colptr[n_col]) { + arret("NCFormat_Create: memory issue") ; + } - NCformat_GetNbOfNonZeroValues(asluNC) = colptr[n_col] ; + NCFormat_GetNbOfNonZeroValues(asluNC) = colptr[n_col] ; } /* reallocation de la memoire */ { - int* rowind = NCformat_GetRowIndexOfTheNonZeroValue(asluNC) ; - int nnz = NCformat_GetNbOfNonZeroValues(asluNC) ; + int* rowind = NCFormat_GetRowIndexOfNonZeroValue(asluNC) ; + int nnz = NCFormat_GetNbOfNonZeroValues(asluNC) ; int* rowind1 = (int*) realloc(rowind,nnz*sizeof(int)) ; - if(!rowind1) arret("NCformat_Create: reallocation issue") ; + if(!rowind1) { + arret("NCFormat_Create: reallocation issue") ; + } if(rowind1 != rowind) { - NCformat_GetRowIndexOfTheNonZeroValue(asluNC) = rowind1 ; - Message_Warning("NCformat_Create: new memory allocation") ; + NCFormat_GetRowIndexOfNonZeroValue(asluNC) = rowind1 ; + Message_Warning("NCFormat_Create: new memory allocation") ; } } /* 1. allocation de l'espace memoire pour la matice */ { - int nnz = NCformat_GetNbOfNonZeroValues(asluNC) ; + int nnz = NCFormat_GetNbOfNonZeroValues(asluNC) ; double* nzval = (double*) malloc(nnz*sizeof(double)) ; assert(nzval) ; - NCformat_GetNonZeroValue(asluNC) = nzval ; + NCFormat_GetNonZeroValue(asluNC) = nzval ; } return(asluNC) ; @@ -208,13 +211,13 @@ NCformat_t* NCformat_Create(Mesh_t* mesh) -void NCformat_Delete(void* self) +void NCFormat_Delete(void* self) { - NCformat_t** a = (NCformat_t**) self ; + NCFormat_t** a = (NCFormat_t**) self ; - free(NCformat_GetFirstNonZeroValueIndexOfColumn(*a)) ; - free(NCformat_GetRowIndexOfTheNonZeroValue(*a)) ; - free(NCformat_GetNonZeroValue(*a)) ; + free(NCFormat_GetFirstNonZeroValueIndexOfColumn(*a)) ; + free(NCFormat_GetRowIndexOfNonZeroValue(*a)) ; + free(NCFormat_GetNonZeroValue(*a)) ; free(*a) ; *a = NULL ; } @@ -222,13 +225,13 @@ void NCformat_Delete(void* self) -void NCformat_AssembleElementMatrix(NCformat_t* a,double* ke,int* cole,int* lige,int n,int* rowptr,int n_row) +void NCFormat_AssembleElementMatrix(NCFormat_t* a,double* ke,int* cole,int* lige,int n,int* rowptr,int n_row) /* Assemblage de la matrice elementaire ke dans la matrice globale a */ { #define KE(i,j) (ke[(i)*n+(j)]) - double* nzval = NCformat_GetNonZeroValue(a) ; - int* colptr = NCformat_GetFirstNonZeroValueIndexOfColumn(a) ; - int* rowind = NCformat_GetRowIndexOfTheNonZeroValue(a) ; + double* nzval = (double*) NCFormat_GetNonZeroValue(a) ; + int* colptr = NCFormat_GetFirstNonZeroValueIndexOfColumn(a) ; + int* rowind = NCFormat_GetRowIndexOfNonZeroValue(a) ; int je,i ; for(i = 0 ; i < n_row ; i++) rowptr[i] = -1 ; @@ -247,7 +250,7 @@ void NCformat_AssembleElementMatrix(NCformat_t* a,double* ke,int* cole,int* lige if(irow < 0) continue ; if(rowptr[irow] < 0) { - arret("NCformat_AssembleElementMatrix: assembling not possible") ; + arret("NCFormat_AssembleElementMatrix: assembling not possible") ; } nzval[rowptr[irow]] += KE(ie,je) ; @@ -262,16 +265,16 @@ void NCformat_AssembleElementMatrix(NCformat_t* a,double* ke,int* cole,int* lige -void NCformat_PrintMatrix(NCformat_t* a,unsigned int n_col,const char* keyword) +void NCFormat_PrintMatrix(NCFormat_t* a,unsigned int n_col,const char* keyword) { - double* nzval = NCformat_GetNonZeroValue(a) ; - int* colptr = NCformat_GetFirstNonZeroValueIndexOfColumn(a) ; - int* rowind = NCformat_GetRowIndexOfTheNonZeroValue(a) ; - int nnz = NCformat_GetNbOfNonZeroValues(a) ; + double* nzval = (double*) NCFormat_GetNonZeroValue(a) ; + int* colptr = NCFormat_GetFirstNonZeroValueIndexOfColumn(a) ; + int* rowind = NCFormat_GetRowIndexOfNonZeroValue(a) ; + int nnz = NCFormat_GetNbOfNonZeroValues(a) ; int jcol ; fprintf(stdout,"\n") ; - fprintf(stdout,"matrice par colonne compressee :\n") ; + fprintf(stdout,"Matrix in compressed column format:\n") ; fprintf(stdout,"n_col = %u nnz = %d\n",n_col,nnz) ; fprintf(stdout,"\n") ; @@ -292,4 +295,3 @@ void NCformat_PrintMatrix(NCformat_t* a,unsigned int n_col,const char* keyword) } } -#endif diff --git a/src/Solver/NCFormat.h b/src/Solver/NCFormat.h new file mode 100644 index 00000000..2f4536be --- /dev/null +++ b/src/Solver/NCFormat.h @@ -0,0 +1,49 @@ +#ifndef NCFORMAT_H +#define NCFORMAT_H + + +/* class-like structure "NCFormat_t" and attributes */ + +/* vacuous declarations and typedef names */ +struct NCFormat_s ; typedef struct NCFormat_s NCFormat_t ; +//#define NCFormat_t NCformat /* Mimic the NCformat struct defined in SuperLu */ + + +#include "Mesh.h" + + +extern NCFormat_t* (NCFormat_Create)(Mesh_t*) ; +extern void (NCFormat_Delete)(void*) ; +extern void (NCFormat_AssembleElementMatrix)(NCFormat_t*,double*,int*,int*,int,int*,int) ; +extern void (NCFormat_PrintMatrix)(NCFormat_t*,unsigned int,const char*) ; + + + + +/** The getters */ +#define NCFormat_GetNbOfNonZeroValues(F) ((F)->nnz) +#define NCFormat_GetNonZeroValue(F) ((F)->nzval) +#define NCFormat_GetRowIndexOfNonZeroValue(F) ((F)->rowind) +#define NCFormat_GetFirstNonZeroValueIndexOfColumn(F) ((F)->colptr) + +/* +#define NCFormat_NbOfNonZeroValuesInColumn(F,j) ((F)->colptr[j + 1] - (F)->colptr[j]) +#define NCFormat_RowIndexStartingColumn(F,j) ((F)->rowind[(F)->colptr[j]]) +#define NCFormat_UpperColumn(F,j) ((F)->nzval + (F)->colptr[j + 1] - (j)) +*/ + + +/* complete the structure types by using the typedef */ + +/* Same as CCSFormat + * Compressed column storage format (known as Harwell-Boeing sparse matrix format) + * If a_ij = nzval[k] then rowind[k] = i and colptr[j] <= k < colptr[j + 1] */ +struct NCFormat_s { + int nnz ; /* nb of non zero values */ + double* nzval ; /* Non zero values */ + int* rowind ; /* Row indices of the non zeros */ + int* colptr ; /* Index of element in nzval which starts a column */ +} ; + + +#endif diff --git a/src/Solver/NCformat.h b/src/Solver/NCformat.h deleted file mode 100644 index 3b99f5b5..00000000 --- a/src/Solver/NCformat.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef NCFORMAT_H -#define NCFORMAT_H - - -/* class-like structure "NCformat_t" and attributes */ - -/* vacuous declarations and typedef names */ -//struct NCformat_s ; typedef struct NCformat_s NCformat_t ; -#define NCformat_t NCformat /* Mimic the NCformat struct defined in SuperLu */ - - -#include "Mesh.h" - -#ifdef SLU_DIR - #define val(x) #x - #define xval(x) val(x) - #include xval(SLU_DIR/SRC/dsp_defs.h) - #undef val - #undef xval - - extern NCformat_t* (NCformat_Create)(Mesh_t*) ; - extern void (NCformat_Delete)(void*) ; - extern void (NCformat_AssembleElementMatrix)(NCformat_t*,double*,int*,int*,int,int*,int) ; - extern void (NCformat_PrintMatrix)(NCformat_t*,unsigned int,const char*) ; -#endif - - - -/** The getters */ -#define NCformat_GetNbOfNonZeroValues(a) ((a)->nnz) -#define NCformat_GetNonZeroValue(a) ((a)->nzval) -#define NCformat_GetRowIndexOfTheNonZeroValue(a) ((a)->rowind) -#define NCformat_GetFirstNonZeroValueIndexOfColumn(a) ((a)->colptr) - -/* -#define NCformat_NbOfNonZeroValuesInColumn(a,j) ((a)->colptr[j + 1] - (a)->colptr[j]) -#define NCformat_RowIndexStartingColumn(a,j) ((a)->rowind[(a)->colptr[j]]) -#define NCformat_UpperColumn(a,j) ((a)->nzval + (a)->colptr[j + 1] - (j)) -*/ - - -/* complete the structure types by using the typedef */ - -/* Same as CCSformat - * Compressed column storage format (known as Harwell-Boeing sparse matrix format) - * If a_ij = nzval[k] then rowind[k] = i and colptr[j] <= k < colptr[j + 1] */ -struct NCformat_s { - unsigned int nnz ; /* nb of non zero values */ - double* nzval ; /* Non zero values */ - unsigned int* rowind ; /* Row indices of the non zeros */ - unsigned int* colptr ; /* Index of element in nzval which starts a column */ -} ; - - -#endif diff --git a/src/Solver/ResolutionMethod.h b/src/Solver/ResolutionMethod.h index 455df7bb..6c9d7726 100644 --- a/src/Solver/ResolutionMethod.h +++ b/src/Solver/ResolutionMethod.h @@ -4,7 +4,8 @@ enum ResolutionMethod_e { /* Type of resolution method */ ResolutionMethod_CROUT, /* Crout method */ - ResolutionMethod_SLU /* SuperLU method*/ + ResolutionMethod_SLU, /* SuperLU method*/ + ResolutionMethod_MA38 /* MA38 method*/ } ; @@ -14,4 +15,5 @@ enum ResolutionMethod_e { /* Type of resolution method */ typedef enum ResolutionMethod_e ResolutionMethod_t ; + #endif diff --git a/src/Solver/SKLFormat.h b/src/Solver/SKLFormat.h new file mode 100644 index 00000000..862c8522 --- /dev/null +++ b/src/Solver/SKLFormat.h @@ -0,0 +1,34 @@ +#ifndef SKLFORMAT_H +#define SKLFORMAT_H + + +/* class-like structure "SKLFormat_t" and attributes */ + +/* vacuous declarations and typedef names */ +struct SKLFormat_s ; typedef struct SKLFormat_s SKLFormat_t ; + + + +/** The getters */ +#define SKLFormat_GetNbOfNonZeroValues(a) ((a)->nnz) +#define SKLFormat_GetNonZeroValue(a) ((a)->nzval) +#define SKLFormat_GetPointerToLowerRow(a) ((a)->l) +#define SKLFormat_GetPointerToUpperColumn(a) ((a)->u) +#define SKLFormat_GetFirstNonZeroValueIndexOfLowerRow(a) ((a)->rowptr) +#define SKLFormat_GetFirstNonZeroValueIndexOfUpperColumn(a) ((a)->colptr) + + + +/* complete the structure types by using the typedef */ + +/* Skyline format */ +struct SKLFormat_s { /* Skyline storage format */ + unsigned int nnz ; /* Nb of non zero values */ + double* nzval ; /* Non zero values */ + double* l ; /* Strictly lower triangular matrix values */ + double* u ; /* Upper triangular matrix values including diagonal */ + unsigned int* colptr ; /* Index of element in u which starts a column */ + unsigned int* rowptr ; /* Index of element in l which starts a row */ +} ; + +#endif diff --git a/src/Solver/SKLformat.h b/src/Solver/SKLformat.h deleted file mode 100644 index 2384f00c..00000000 --- a/src/Solver/SKLformat.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef SKLFORMAT_H -#define SKLFORMAT_H - - -/* class-like structure "SKLformat_t" and attributes */ - -/* vacuous declarations and typedef names */ -struct SKLformat_s ; typedef struct SKLformat_s SKLformat_t ; - - - -/** The getters */ -#define SKLformat_GetNbOfNonZeroValues(a) ((a)->nnz) -#define SKLformat_GetNonZeroValue(a) ((a)->d) -#define SKLformat_GetDiagonal(a) ((a)->d) -#define SKLformat_GetPointerToLowerRow(a) ((a)->l) -#define SKLformat_GetPointerToUpperColumn(a) ((a)->u) -#define SKLformat_GetFirstNonZeroValueIndexOfLowerRow(a) ((a)->rowptr) -#define SKLformat_GetFirstNonZeroValueIndexOfUpperColumn(a) ((a)->colptr) - - - -/* complete the structure types by using the typedef */ - -/* Skyline format */ -struct SKLformat_s { /* Skyline storage format */ - unsigned int nnz ; /* nb of non zero values */ - double* d ; /* diagonal matrix values */ - double* l ; /* strictly lower triangular matrix values */ - double* u ; /* strictly upper triangular matrix values */ - unsigned int* colptr ; /* Index of element in u which starts a column */ - unsigned int* rowptr ; /* Index of element in l which starts a row */ -} ; - -#endif diff --git a/src/Solver/Solver.c b/src/Solver/Solver.c index 5bd84336..42a57383 100644 --- a/src/Solver/Solver.c +++ b/src/Solver/Solver.c @@ -3,35 +3,17 @@ #include #include #include +#include #include "Solver.h" #include "Message.h" #include "BilLib.h" +#include "CroutMethod.h" +#include "SuperLUMethod.h" +#include "MA38Method.h" -#include "LDUSKLformat.h" -#include "NCformat.h" -#include "SuperLUformat.h" -#ifdef SLU_DIR - #define val(x) #x - #define xval(x) val(x) - #include xval(SLU_DIR/SRC/dsp_defs.h) - #undef val - #undef xval -#endif - - -static int solveCROUT(Solver_t*) ; -static int ludcmp(LDUSKLformat_t*,int) ; -static void lubksb(LDUSKLformat_t*,double*,double*,int) ; - - -#ifdef SLU_DIR -static void resolSLU(Matrix_t*,double*,double*,int) ; -static int solveSLU(Solver_t*) ; -#endif - /* Extern functions @@ -51,17 +33,22 @@ Solver_t* Solver_Create(Mesh_t* mesh,Options_t* options,const int n) if(!strcmp(method,"crout")) { Solver_GetResolutionMethod(solver) = ResolutionMethod_CROUT ; - Solver_GetSolve(solver) = solveCROUT ; + Solver_GetSolve(solver) = CroutMethod_Solve ; - #ifdef SLU_DIR + #ifdef SUPERLULIB } else if(!strcmp(method,"slu")) { Solver_GetResolutionMethod(solver) = ResolutionMethod_SLU ; - Solver_GetSolve(solver) = solveSLU ; + Solver_GetSolve(solver) = SuperLUMethod_Solve ; #endif + } else if(!strcmp(method,"ma38")) { + + Solver_GetResolutionMethod(solver) = ResolutionMethod_MA38 ; + Solver_GetSolve(solver) = MA38Method_Solve ; + } else { - arret("Solver_Create(1) : methode non connue") ; + arret("Solver_Create(1): unknown method") ; } } @@ -154,407 +141,3 @@ void Solver_Print(Solver_t* solver,char* keyword) } - -/* Intern functions */ - - -int ludcmp(LDUSKLformat_t* a,int n) -/** - * Replace the given matrix a by the LDU decomposition (after NR). - * "a" is arranged as a skyline matrix given as "LDU". - - * D pointer to the diagonal. - * U pointer to the strictly upper triangular matrix. - * L pointer to the strictly lower triangular matrix. - * - * U[j] pointer to the first non zero value of the column j + 1. - * L[i] pointer to the first non zero value of the row i + 1. - * U[j] - U[j - 1] is the height of the column j of the upper matrix. - * L[i] - L[i - 1] is the height of the row i of the lower matrix. - * - * diagonal : a(i,i) = D[i] - * upper matrix : a(i,j) = (U[j] - j)[i] if i1 <= i < j , a(i,j) = 0 otherwise - * lower matrix : a(i,j) = (L[i] - i)[j] if j1 <= j < i , a(i,j) = 0 otherwise - * with i1 = (j - U[j] + U[j-1]) - * and j1 = (i - L[i] + L[i-1]). - */ -{ -#define UpperColumn(j) (LDUSKLformat_GetUpperColumn(a,j)) -#define LowerRow(i) (LDUSKLformat_GetLowerRow(a,i)) - double* diag = LDUSKLformat_GetDiagonal(a) ; - double dum = 0. ; - double zero = 0. ; - int j ; - - - /* Loop on columns (Crout's algorithm) */ - for(j = 0 ; j < n ; j++) { - double* colj = UpperColumn(j) ; - /* i1 is the row index which starts the column j */ - int i1 = (j > 0) ? LDUSKLformat_RowIndexStartingColumn(a,j) : 0 ; - int i ; - - /* 1. U_ij = a_ij - sum_1^{i-1} L_ik * U_kj for i <= j */ - if(j > 0) { /* U(0,0) unchanged */ - - /* 1.a For i < j */ - for(i = i1 + 1 ; i < j ; i++) { /* a(i1,j) unchanged */ - /* j1 is the column index which starts the row i */ - int j1 = LDUSKLformat_ColumnIndexStartingRow(a,i) ; - int k1 = (i1 > j1) ? i1 : j1 ; - double* rowi = LowerRow(i) ; - int k ; - - for(k = k1 ; k < i ; k++) { - colj[i] -= rowi[k]*colj[k] ; - } - } - - /* 1.b For i = j */ - { - /* Column index which starts the row j */ - int j1 = LDUSKLformat_ColumnIndexStartingRow(a,j) ; - int k1 = (i1 > j1) ? i1 : j1 ; - double* rowj = LowerRow(j) ; - int k ; - - for(k = k1 ; k < j ; k++) { - diag[j] -= rowj[k]*colj[k] ; - } - } - } - - if(diag[j] == zero) { - Message_Direct("\nludcmp: diagonal term (pivot) is zero at row/col %d",j) ; - return(-1) ; - - } else dum = 1./diag[j] ; - - /* 2. L(i,j) = (a(i,j) - sum_1^{j-1}L(i,k)*U(k,j))/U(j,j) pour i > j */ - for(i = j + 1 ; i < n ; i++) { - /* Column index which starts the row i */ - int j1 = LDUSKLformat_ColumnIndexStartingRow(a,i) ; - - if(j1 <= j) { /* a(i,j) i > j is zero */ - int k1 = (i1 > j1) ? i1 : j1 ; - double* rowi = LowerRow(i) ; - int k ; - - for(k = k1 ; k < j ; k++) { - rowi[j] -= rowi[k]*colj[k] ; - } - - rowi[j] *= dum ; - } - } - } - - return(0) ; -#undef UpperColumn -#undef LowerRow -} - - -void lubksb(LDUSKLformat_t* a,double* x,double* b,int n) -/* Solve a*x = b. - * Here a is input as its LU decomposition determined by ludcmp. - */ -{ -#define UpperColumn(j) (LDUSKLformat_GetUpperColumn(a,j)) -#define LowerRow(i) (LDUSKLformat_GetLowerRow(a,i)) - double* diag = LDUSKLformat_GetDiagonal(a) ; - int i ; - - if(x != b) { - for(i = 0 ; i < n ; i++) x[i] = b[i] ; - } - - /* Forward substitution : y_i = b_i - sum_0^{i-1} L_ij * y_j */ - for(i = 1 ; i < n ; i++) { /* x[0] unchanged */ - double* rowi = LowerRow(i) ; - /* j1 is the column index which starts the row i */ - int j1 = LDUSKLformat_ColumnIndexStartingRow(a,i) ; - int j ; - - for(j = j1 ; j < i ; j++) { - x[i] -= rowi[j]*x[j] ; - } - } - - /* Backsubstitution : x_i = (y_i - sum_{i+1}^n U_ij * x_j)/D_ii */ - for(i = n - 1 ; i >= 0 ; i--) { - int j ; - - for(j = i + 1 ; j < n ; j++) { - /* i1 is the row index which starts the column j */ - int i1 = LDUSKLformat_RowIndexStartingColumn(a,j) ; - - /* a(i,j) = 0 for i < i1 */ - if(i >= i1) { - double* colj = UpperColumn(j) ; - - x[i] -= colj[i]*x[j] ; - } - } - - x[i] /= diag[i] ; - } -#undef UpperColumn -#undef LowerRow -} - - - -int solveCROUT(Solver_t* solver) -/** Resolution of a.x = b by Crout's method */ -{ - Matrix_t* a = Solver_GetMatrix(solver) ; - double* b = Solver_GetRHS(solver) ; - double* x = Solver_GetSolution(solver) ; - int n = Solver_GetNbOfColumns(solver) ; - LDUSKLformat_t* askl = (LDUSKLformat_t*) Matrix_GetStorage(a) ; - - if(Matrix_WasNotModified(a)) { - int i = ludcmp(askl,n) ; - - Matrix_SetToModifiedState(a) ; - - if(i < 0) return(i) ; - } - - lubksb(askl,x,b,n) ; - - return(0) ; -} - - - -#ifdef SLU_DIR -int solveSLU(Solver_t* solver) -/** Resolution of a.x = b by SuperLU's method */ -{ - Matrix_t* a = Solver_GetMatrix(solver) ; - double* b = Solver_GetRHS(solver) ; - double* x = Solver_GetSolution(solver) ; - int n = Solver_GetNbOfColumns(solver) ; - - resolSLU(a,x,b,n) ; - return(0) ; -} - - -void resolSLU(Matrix_t* a,double* x,double* b,int n) -/* Resolution of a.x = b by SuperLU's method */ -{ - /* pour dgssv */ - SuperLUformat_t* Aslu = Matrix_GetStorage(a) ; - SuperLUformat_t L,U,B ; - DNformat Bstore ; - superlu_options_t options ; - SuperLUStat_t stat ; - int info ; - /* int *perm_r = a.work,*perm_c = (int *) a.work + n ; */ - static int* perm_r ; - static int* perm_c ; - /* pour dgssvx */ - char equed[1] ; - double rpg ; - double rcond ; - mem_usage_t mem_usage ; - static int iresol = 0 ; - static int* etree ; - SuperLUformat_t X ; - DNformat Xstore ; - static double* R ; - static double* C ; - static void* work ; - static int lwork = 0 ; - static double ferr[1] ; - static double berr[1] ; - - /* allocation de memoire pour les variables statiques */ - if(!iresol) { - perm_r = (int*) malloc(n*sizeof(int)) ; - if(!perm_r) arret("resolSLU(1) : allocation impossible") ; - perm_c = (int*) malloc(n*sizeof(int)) ; - if(!perm_c) arret("resolSLU(2) : allocation impossible") ; - etree = (int*) malloc(n*sizeof(int)) ; - if(!etree) arret("resolSLU(3) : allocation impossible") ; - R = (double*) malloc(n*sizeof(double)) ; - if(!R) arret("resolSLU(5) : allocation impossible") ; - C = (double*) malloc(n*sizeof(double)) ; - if(!C) arret("resolSLU(6) : allocation impossible") ; - if(lwork > 0) { - work = (double*) malloc(lwork*sizeof(double)) ; - if(!work) arret("resolSLU(7) : allocation impossible") ; - } - } - - /* le second membre */ - B.Stype = SLU_DN ; - B.Dtype = SLU_D ; - B.Mtype = SLU_GE ; - B.nrow = n ; - B.ncol = 1 ; - B.Store = (DNformat *) &Bstore ; - Bstore.lda = n ; - Bstore.nzval = (double*) b ; - /* dCreate_Dense_Matrix(&B,n,1,b,n,SLU_DN,SLU_D,SLU_GE) ; */ - - /* la solution */ - X.Stype = SLU_DN ; - X.Dtype = SLU_D ; - X.Mtype = SLU_GE ; - X.nrow = n ; - X.ncol = 1 ; - X.Store = (DNformat *) &Xstore ; - Xstore.lda = n ; - Xstore.nzval = (double*) x ; - - /* les options */ - /* par defaut - options->Fact = DOFACT; - options->Equil = YES; - options->ColPerm = COLAMD; - options->DiagPivotThresh = 1.0; - options->Trans = NOTRANS; - options->IterRefine = NOREFINE; - options->SymmetricMode = NO; - options->PivotGrowth = NO; - options->ConditionNumber = NO; - options->PrintStat = YES; - */ - set_default_options(&options) ; - if(iresol++) options.Fact = SamePattern ; - options.ColPerm = NATURAL ; - options.PrintStat = NO ; - /* options.DiagPivotThresh = 0. ; */ - /* options.IterRefine = EXTRA ; */ - - /* les statistiques */ - StatInit(&stat) ; - - /* dgssv(&options,Aslu,perm_c,perm_r,&L,&U,&B,&stat,&info) ; */ - - dgssvx(&options,Aslu,perm_c,perm_r,etree,equed,R,C, - &L,&U,work,lwork,&B,&X,&rpg,&rcond,ferr,berr, - &mem_usage,&stat,&info); - - /* if(options.PrintStat) StatPrint(&stat) ; */ -} -#endif - - - - - - - -/* Not used */ -#ifdef NOTDEFINED - -int ludcmp1(LDUSKLformat_t* a,int n) -/* -Remplace une matrice par sa decomposition LU (d apres NR). -"a" est une matrice ligne de ciel donnee sous la forme "LDU": - - D = a->d , U = a->u , L = a->l - - D pointe sur le premier terme de la diagonale. - U[0] pointe sur le premier terme non nul de la matrice triangulaire sup. - L[0] pointe sur le premier terme non nul de la matrice triangulaire inf. - U[j] - U[j-1] donne la hauteur de la colonne j de la matrice sup. - L[i] - L[i-1] donne la longueur de la ligne i de la matrice inf. - -diagonale : a(i,i) = D[i] -matrice sup : a(i,j) = *(U[j]-j+i) si i1 <= i < j , a(i,j) = 0 sinon -matrice inf : a(i,j) = *(L[i]-i+j) si j1 <= j < i , a(i,j) = 0 sinon -avec i1 = (j - U[j] + U[j-1]) et j1 = (i - L[i] + L[i-1]). -*/ -{ -#define PU(i,j) (LDUSKLformat_GetPointerToUpperColumn(a)[j] - j + i) -#define PL(i,j) (LDUSKLformat_GetPointerToLowerRow(a)[i] - i + j) - double** u = LDUSKLformat_GetPointerToUpperColumn(a) ; - double** l = LDUSKLformat_GetPointerToLowerRow(a); - double* d = LDUSKLformat_GetDiagonal(a) ; - int i,j,k,i1 = 0,j1,k1 ; - double dum = 0.,*p,*pl,*pu ; - double zero = 0. ; - - /* boucle sur les colonnes (algorithme de Crout) */ - for(j=0;j<(int) n;j++) { - /* 1. U(i,j) = a(i,j) - sum_1^{i-1}L(i,k)*U(k,j) pour i<=j */ - if(j>0) { /* U(0,0) inchange */ - /* 1.a pour i j1) ? i1 : j1 ; - p = PU(i,j) ; /* pointe sur a(i,j) ik1 */ - pu = PU(k1,j) ; /* pointe sur a(k1,j) k1 j1) ? i1 : j1 ; - p = d + j ; /* pointe sur a(j,j) */ - pl = PL(i,k1) ; /* pointe sur a(i,k1) i>k1 */ - pu = PU(k1,j) ; /* pointe sur a(k1,j) k1j */ - if(j==0) i1 = 0 ; - for(i=j+1;i<(int) n;i++) { - j1 = i - (l[i] - l[i-1]) ; /* 1ere colonne non nulle de la ligne i */ - if(j1 > j) continue ; /* a(i,j) i>j est nul */ - k1 = (i1 > j1) ? i1 : j1 ; - p = PL(i,j) ; /* pointe sur a(i,j) i>j */ - pl = PL(i,k1) ; /* pointe sur a(i,k1) i>k1 */ - pu = PU(k1,j) ; /* pointe sur a(k1,j) k1=0;i--) { - p = b+i ; - for(j=i+1;j<(int) n;j++) { - i1 = j - (u[j] - u[j-1]) ; /* 1ere ligne non nulle de la colonne j */ - if(i1 > i) continue ; /* a(i,j) i +#include +#include +#include +#include +#include "BilLib.h" +#include "Options.h" +#include "Mesh.h" +#include "Message.h" + + +#include "SuperLUFormat.h" +#include "NCFormat.h" + + + +/* Extern functions */ + + +#ifdef SUPERLULIB + +SuperLUFormat_t* SuperLUFormat_Create(Mesh_t* mesh) +/* Create a matrix in SuperLUFormat format */ +{ + SuperLUFormat_t* aslu = (SuperLUFormat_t*) malloc(sizeof(SuperLUFormat_t)) ; + + assert(aslu) ; + + SuperLUFormat_GetStorageType(aslu) = SLU_NC ; + SuperLUFormat_GetDataType(aslu) = SLU_D ; + SuperLUFormat_GetMatrixType(aslu) = SLU_GE ; + + { + int n_col = Mesh_GetNbOfMatrixColumns(mesh) ; + + SuperLUFormat_GetNbOfColumns(aslu) = n_col ; + SuperLUFormat_GetNbOfRows(aslu) = n_col ; + } + + { + NCFormat_t* asluNC = NCFormat_Create(mesh) ; + + SuperLUFormat_GetStorage(aslu) = (void*) asluNC ; + } + + return(aslu) ; +} + + + +void SuperLUFormat_Delete(void* self) +{ + SuperLUFormat_t** aslu = (SuperLUFormat_t**) self ; + NCFormat_t* asluNC = (NCFormat_t*) SuperLUFormat_GetStorage(*aslu) ; + + NCFormat_Delete(&asluNC) ; + + free(*aslu) ; + *aslu = NULL ; +} + +#endif diff --git a/src/Solver/SuperLUFormat.h b/src/Solver/SuperLUFormat.h new file mode 100644 index 00000000..009c32f2 --- /dev/null +++ b/src/Solver/SuperLUFormat.h @@ -0,0 +1,101 @@ +#ifndef SUPERLUFORMAT_H +#define SUPERLUFORMAT_H + + +/* class-like structure "SuperLUFormat_t" and attributes */ + +/* vacuous declarations and typedef names */ +//struct SuperLUFormat_s ; typedef struct SuperLUFormat_s SuperLUFormat_t ; +#define SuperLUFormat_t SuperMatrix /* Mimic the SuperMatrix struct defined in SuperLu */ + + + +#include "Mesh.h" + + +#ifdef SUPERLULIB + + #define val(x) #x + #define xval(x) val(x) + //#include xval(SUPERLULIB/SRC/dsp_defs.h) + //#include "/home/dangla/Documents/Softwares/getfem-4.0.0/superlu/slu_ddefs.h" + #include "superlu.h" + #undef val + #undef xval + +#endif + + +extern SuperLUFormat_t* (SuperLUFormat_Create)(Mesh_t*) ; +extern void (SuperLUFormat_Delete)(void*) ; + + + + + + +/** The getters */ +#define SuperLUFormat_GetNbOfRows(a) ((a)->nrow) +#define SuperLUFormat_GetNbOfColumns(a) ((a)->ncol) +#define SuperLUFormat_GetStorage(a) ((a)->Store) +#define SuperLUFormat_GetStorageType(a) ((a)->Stype) +#define SuperLUFormat_GetDataType(a) ((a)->Dtype) +#define SuperLUFormat_GetMatrixType(a) ((a)->Mtype) + + + + +/* complete the structure types by using the typedef */ + +#if 0 +/* Copy of the SuperMatrix struc as defined in SuperLU */ +enum Stype_e { + SLU_NC, /* column-wise, no supernode */ + SLU_NR, /* row-wize, no supernode */ + SLU_SC, /* column-wise, supernode */ + SLU_SR, /* row-wise, supernode */ + SLU_NCP, /* column-wise, column-permuted, no supernode + (The consecutive columns of nonzeros, after permutation, + may not be stored contiguously.) */ + SLU_DN /* Fortran style column-wise storage for dense matrix */ +} ; + +typedef enum Stype_e Stype_t ; + +enum Dtype_e { + SLU_S, /* single */ + SLU_D, /* double */ + SLU_C, /* single complex */ + SLU_Z /* double complex */ +} ; + +typedef enum Dtype_e Dtype_t ; + +enum Mtype_e { + SLU_GE, /* general */ + SLU_TRLU, /* lower triangular, unit diagonal */ + SLU_TRUU, /* upper triangular, unit diagonal */ + SLU_TRL, /* lower triangular */ + SLU_TRU, /* upper triangular */ + SLU_SYL, /* symmetric, store lower half */ + SLU_SYU, /* symmetric, store upper half */ + SLU_HEL, /* Hermitian, store lower half */ + SLU_HEU /* Hermitian, store upper half */ +} ; + +typedef enum Mtype_e Mtype_t ; +#endif + + +struct SuperLUFormat_s { + Stype_t Stype; /* Storage format (SLU_[NC,NR,SC,SR,NCP,DN]) */ + Dtype_t Dtype; /* Data type (SLU_[S,D,C,Z])*/ + Mtype_t Mtype; /* Mathematical property of the matrix (SLU_[GE,..]) */ + int nrow; /* number of rows */ + int ncol; /* number of columns */ + void* Store; /* pointer to the actual storage of the matrix */ +} ; + + + +#endif diff --git a/src/Solver/SuperLUMethod.c b/src/Solver/SuperLUMethod.c new file mode 100644 index 00000000..ba7eef2f --- /dev/null +++ b/src/Solver/SuperLUMethod.c @@ -0,0 +1,203 @@ +#include +#include +#include +#include +#include +#include "BilLib.h" +#include "SuperLUMethod.h" +#include "Solver.h" +#include "Message.h" +#include "Matrix.h" +#include "SuperLUFormat.h" + + + +#ifdef SUPERLULIB + + #define val(x) #x + #define xval(x) val(x) + //#include xval(SUPERLULIB/SRC/dsp_defs.h) + //#include "/home/dangla/Documents/Softwares/getfem-4.0.0/superlu/slu_ddefs.h" + #include "superlu.h" + #undef val + #undef xval + +#endif + + +#ifdef SUPERLULIB + +int SuperLUMethod_Solve(Solver_t* solver) +/** Resolution of a.x = b by SuperLU's method */ +{ + Matrix_t* a = Solver_GetMatrix(solver) ; + double* b = Solver_GetRHS(solver) ; + double* x = Solver_GetSolution(solver) ; + int n = Solver_GetNbOfColumns(solver) ; + + /* for dgssv */ + SuperLUFormat_t* A = (SuperLUFormat_t*) Matrix_GetStorage(a) ; + SuperLUFormat_t L ; + SuperLUFormat_t U ; + SuperLUFormat_t B ; + DNformat Bstore ; + superlu_options_t options ; + SuperLUStat_t stat ; + int info ; + /* int *perm_r = a.work,*perm_c = (int *) a.work + n ; */ + static int* perm_r ; + static int* perm_c ; + /* for dgssvx */ + static int iresol = 0 ; + SuperLUFormat_t X ; + DNformat Xstore ; + + /* Allocate memory space for the permutations of rows and columns */ + if(!iresol) { + perm_r = (int*) malloc(n*sizeof(int)) ; + + assert(perm_r) ; + + perm_c = (int*) malloc(n*sizeof(int)) ; + + assert(perm_c) ; + } + + + /* Options */ + /* Set the default input options: + options->Fact = DOFACT; + options->Equil = YES; + options->ColPerm = COLAMD; + options->DiagPivotThresh = 1.0; + options->Trans = NOTRANS; + options->IterRefine = NOREFINE; + options->SymmetricMode = NO; + options->PivotGrowth = NO; + options->ConditionNumber = NO; + options->PrintStat = YES; + */ + set_default_options(&options) ; + options.PrintStat = NO ; + //options.ColPerm = NATURAL ; + //options.DiagPivotThresh = 0. ; + //options.IterRefine = EXTRA ; + if(iresol) { + options.Fact = SamePattern ; + } + + + + /* Initialize the statistics variables */ + StatInit(&stat) ; + + + /* The rhs */ + { + B.Stype = SLU_DN ; + B.Dtype = SLU_D ; + B.Mtype = SLU_GE ; + B.nrow = n ; + B.ncol = 1 ; + B.Store = (DNformat *) &Bstore ; + Bstore.lda = n ; + Bstore.nzval = (double*) b ; + } +#if 0 + if(!iresol) { + dCreate_Dense_Matrix(&B,n,1,b,n,SLU_DN,SLU_D,SLU_GE) ; + } +#endif + + + /* The solution */ + { + X.Stype = SLU_DN ; + X.Dtype = SLU_D ; + X.Mtype = SLU_GE ; + X.nrow = n ; + X.ncol = 1 ; + X.Store = (DNformat *) &Xstore ; + Xstore.lda = n ; + Xstore.nzval = (double*) x ; + } +#if 0 + if(!iresol) { + dCreate_Dense_Matrix(&X,n,1,x,n,SLU_DN,SLU_D,SLU_GE) ; + } +#endif + + +#if 0 + { + dgssv(&options,A,perm_c,perm_r,&L,&U,&B,&stat,&info) ; + + { + int i ; + + for(i = 0 ; i < n ; i++) { + x[i] = b[i] ; + } + } + } +#endif + + +#if 1 + { + double rpg ; + double rcond ; + mem_usage_t mem_usage ; + /* facilitate multiple factorizations with SamePattern_SameRowPerm */ + GlobalLU_t Glu ; + char equed[1] ; + static double ferr[1] ; + static double berr[1] ; + static int* etree ; + static double* R ; + static double* C ; + static void* work ; + /* The FILL factor */ + int ff = 0 ; + /* lwork = 0 allocate space internally by system malloc */ + int lwork = ff * Matrix_GetNbOfNonZeroValues(a) ; + + /* Allocate memory space for the static variables */ + if(!iresol) { + etree = (int*) malloc(n*sizeof(int)) ; + + assert(etree) ; + + R = (double*) malloc(n*sizeof(double)) ; + + assert(R) ; + + C = (double*) malloc(n*sizeof(double)) ; + + assert(C) ; + + if(lwork > 0) { + work = (double*) malloc(lwork*sizeof(double)) ; + + assert(work) ; + } + } + + { + dgssvx(&options,A,perm_c,perm_r,etree,equed,R,C,&L,&U,work,lwork,&B,&X,&rpg,&rcond,ferr,berr,&Glu,&mem_usage,&stat,&info) ; + } + } +#endif + + + if(options.PrintStat) StatPrint(&stat) ; + + StatFree(&stat); + + iresol++ ; + + return(0) ; +} + +#endif + diff --git a/src/Solver/SuperLUMethod.h b/src/Solver/SuperLUMethod.h new file mode 100644 index 00000000..066868a8 --- /dev/null +++ b/src/Solver/SuperLUMethod.h @@ -0,0 +1,9 @@ +#ifndef SUPERLUMETHOD_H +#define SUPERLUMETHOD_H + + +#include "Solver.h" + +extern int SuperLUMethod_Solve(Solver_t*) ; + +#endif diff --git a/src/Solver/SuperLUformat.c b/src/Solver/SuperLUformat.c deleted file mode 100644 index 807c360a..00000000 --- a/src/Solver/SuperLUformat.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include -#include "Options.h" -#include "Mesh.h" -#include "Message.h" -#include "BilLib.h" -#include "SuperLUformat.h" - - - -/* Extern functions */ - - -#ifdef SLU_DIR - -SuperLUformat_t* SuperLUformat_Create(Mesh_t* mesh) -/* Create a matrix in SuperLUformat format */ -{ - int n_col = Mesh_GetNbOfMatrixColumns(mesh) ; - NCformat_t* asluNC = NCformat_Create(mesh) ; - SuperLUformat_t* aslu = (SuperLUformat_t*) malloc(sizeof(SuperLUformat_t)) ; - - assert(aslu) ; - - SuperLUformat_GetStorageType(aslu) = SLU_NC ; - SuperLUformat_GetDataType(aslu) = SLU_D ; - SuperLUformat_GetMatrixType(aslu) = SLU_GE ; - SuperLUformat_GetNbOfColumns(aslu) = n_col ; - SuperLUformat_GetNbOfRows(aslu) = n_col ; - SuperLUformat_GetStorage(aslu) = (void*) asluNC ; - - return(aslu) ; -} - - - -void SuperLUformat_Delete(void* self) -{ - SuperLUformat_t** aslu = (SuperLUformat_t**) self ; - NCformat_t* asluNC = (NCformat_t*) SuperLUformat_GetStorage(*aslu) ; - - NCformat_Delete(&asluNC) ; - - free(*aslu) ; - *aslu = NULL ; -} - -#endif diff --git a/src/Solver/SuperLUformat.h b/src/Solver/SuperLUformat.h deleted file mode 100644 index 6a52585a..00000000 --- a/src/Solver/SuperLUformat.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef SUPERLUFORMAT_H -#define SUPERLUFORMAT_H - - -/* class-like structure "SuperLUformat_t" and attributes */ - -/* vacuous declarations and typedef names */ -/* struct SuperLUformat_s ; typedef struct SuperLUformat_s SuperLUformat_t ; */ -#define SuperLUformat_t SuperMatrix /* Mimic the SuperMatrix struct defined in SuperLu */ - - -#include "Mesh.h" - -#ifdef SLU_DIR - #define val(x) #x - #define xval(x) val(x) - #include xval(SLU_DIR/SRC/dsp_defs.h) - #undef val - #undef xval - - - extern SuperLUformat_t* (SuperLUformat_Create)(Mesh_t*) ; - extern void (SuperLUformat_Delete)(void*) ; -#endif - - - - - -/** The getters */ -#define SuperLUformat_GetNbOfRows(a) ((a)->nrow) -#define SuperLUformat_GetNbOfColumns(a) ((a)->ncol) -#define SuperLUformat_GetStorage(a) ((a)->Store) -#define SuperLUformat_GetStorageType(a) ((a)->Stype) -#define SuperLUformat_GetDataType(a) ((a)->Dtype) -#define SuperLUformat_GetMatrixType(a) ((a)->Mtype) - - - - -/* complete the structure types by using the typedef */ - -/* Copy of the SuperLUformat struc as defined in SuperLU */ -#ifdef SLU_DIR -struct SuperLUformat_s { - Stype_t Stype; /* Storage format (SLU_[NC,NR,SC,SR,NCP,DN]) */ - Dtype_t Dtype; /* Data type (SLU_[S,D,C,Z])*/ - Mtype_t Mtype; /* Mathematical property of the matrix (SLU_[GE,..]) */ - int nrow; /* number of rows */ - int ncol; /* number of columns */ - void* Store; /* pointer to the actual storage of the matrix */ -} ; -#endif - - -#endif diff --git a/src/Tools/Stack.h b/src/Tools/Stack.h index e3199196..c6d96578 100644 --- a/src/Tools/Stack.h +++ b/src/Tools/Stack.h @@ -17,7 +17,7 @@ struct Stack_s ; typedef struct Stack_s Stack_t ; extern Stack_t* (Stack_New) (void) ; extern void (Stack_Delete) (Stack_t**) ; -extern Stack_t* (Stack_Push_) (int,size_t,TypeId_t) ; +extern Stack_t* (Stack_Push_) (Stack_t*,int,void*,TypeId_t) ; extern Stack_t* (Stack_Pop) (Stack_t*) ; diff --git a/utils/bilfind.sh b/utils/bilfind.sh index 76120eab..746eba62 100755 --- a/utils/bilfind.sh +++ b/utils/bilfind.sh @@ -1,4 +1,4 @@ #!/bin/sh -grep --exclude-dir=backup --include="*.[c,h,cpp,hpp]" --include="Makefile" --exclude="*.o" -r -T -E --color -e "$1" ${BIL}/src +grep --exclude-dir=backup --include="*.[c,h,cpp,hpp,f]" --include="Makefile" --exclude="*.o" -r -T -E --color -e "$1" ${BIL}/src diff --git a/utils/bilwc.sh b/utils/bilwc.sh index f82ae135..087e01c0 100755 --- a/utils/bilwc.sh +++ b/utils/bilwc.sh @@ -1,3 +1,3 @@ #!/bin/sh -find ${BIL}/src -name "*.[c,h,cpp,hpp]" | xargs wc -l +find ${BIL}/src -name "*.[c,h,cpp,hpp,f]" | xargs wc -l