spSolve.c

Go to the documentation of this file.
00001 /*
00002  *  MATRIX SOLVE MODULE
00003  *
00004  *  Author:                     Advising professor:
00005  *      Kenneth S. Kundert          Alberto Sangiovanni-Vincentelli
00006  *      UC Berkeley
00007  *
00008  *  This file contains the forward and backward substitution routines for
00009  *  the sparse matrix routines.
00010  *
00011  *  >>> User accessible functions contained in this file:
00012  *  spSolve
00013  *  spSolveTransposed
00014  *
00015  *  >>> Other functions contained in this file:
00016  *  SolveComplexMatrix
00017  *  SolveComplexTransposedMatrix
00018  */
00019 
00020 
00021 /*
00022  *  Revision and copyright information.
00023  *
00024  *  Copyright (c) 1985,86,87,88
00025  *  by Kenneth S. Kundert and the University of California.
00026  *
00027  *  Permission to use, copy, modify, and distribute this software and
00028  *  its documentation for any purpose and without fee is hereby granted,
00029  *  provided that the copyright notices appear in all copies and
00030  *  supporting documentation and that the authors and the University of
00031  *  California are properly credited.  The authors and the University of
00032  *  California make no representations as to the suitability of this
00033  *  software for any purpose.  It is provided `as is', without express
00034  *  or implied warranty.
00035  */
00036 
00037 
00038 /*
00039  *  IMPORTS
00040  *
00041  *  >>> Import descriptions:
00042  *  spConfig.h
00043  *     Macros that customize the sparse matrix routines.
00044  *  spmatrix.h
00045  *     Macros and declarations to be imported by the user.
00046  *  spDefs.h
00047  *     Matrix type and macro definitions for the sparse matrix routines.
00048  */
00049 
00050 #define spINSIDE_SPARSE
00051 #include "spSolve.h"
00052 
00053 /*
00054  *  SOLVE MATRIX EQUATION
00055  *
00056  *  Performs forward elimination and back substitution to find the
00057  *  unknown vector from the RHS vector and factored matrix.  This
00058  *  routine assumes that the pivots are associated with the lower
00059  *  triangular (L) matrix and that the diagonal of the upper triangular
00060  *  (U) matrix consists of ones.  This routine arranges the computation
00061  *  in different way than is traditionally used in order to exploit the
00062  *  sparsity of the right-hand side.  See the reference in spRevision.
00063  *
00064  *  >>> Arguments:
00065  *  Matrix  <input>  (char *)
00066  *      Pointer to matrix.
00067  *  RHS  <input>  (RealVector)
00068  *      RHS is the input data array, the right hand side. This data is
00069  *      undisturbed and may be reused for other solves.
00070  *  Solution  <output>  (RealVector)
00071  *      Solution is the output data array. This routine is constructed such that
00072  *      RHS and Solution can be the same array.
00073  *  iRHS  <input>  (RealVector)
00074  *      iRHS is the imaginary portion of the input data array, the right
00075  *      hand side. This data is undisturbed and may be reused for other solves.
00076  *      This argument is only necessary if matrix is complex and if
00077  *      spSEPARATED_COMPLEX_VECTOR is set true.
00078  *  iSolution  <output>  (RealVector)
00079  *      iSolution is the imaginary portion of the output data array. This
00080  *      routine is constructed such that iRHS and iSolution can be
00081  *      the same array.  This argument is only necessary if matrix is complex
00082  *      and if spSEPARATED_COMPLEX_VECTOR is set true.
00083  *
00084  *  >>> Local variables:
00085  *  Intermediate  (RealVector)
00086  *      Temporary storage for use in forward elimination and backward
00087  *      substitution.  Commonly referred to as c, when the LU factorization
00088  *      equations are given as  Ax = b, Lc = b, Ux = c Local version of
00089  *      Matrix->Intermediate, which was created during the initial
00090  *      factorization in function CreateInternalVectors() in the matrix
00091  *      factorization module.
00092  *  pElement  (ElementPtr)
00093  *      Pointer used to address elements in both the lower and upper triangle
00094  *      matrices.
00095  *  pExtOrder  (int *)
00096  *      Pointer used to sequentially access each entry in IntToExtRowMap
00097  *      and IntToExtColMap arrays.  Used to quickly scramble and unscramble
00098  *      RHS and Solution to account for row and column interchanges.
00099  *  pPivot  (ElementPtr)
00100  *      Pointer that points to current pivot or diagonal element.
00101  *  Size  (int)
00102  *      Size of matrix. Made local to reduce indirection.
00103  *  Temp  (RealNumber)
00104  *      Temporary storage for entries in arrays.
00105  *
00106  *  >>> Obscure Macros
00107  *  IMAG_VECTORS
00108  *      Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and
00109  *      spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears
00110  *      without a trace.
00111  */
00112 
00113 /*VARARGS3*/
00114 
00115 void
00116 spSolve( eMatrix, RHS, Solution IMAG_VECTORS )
00117 
00118 char *eMatrix;
00119 RealVector  RHS, Solution IMAG_VECTORS;
00120 {
00121 MatrixPtr  Matrix = (MatrixPtr)eMatrix;
00122 register  ElementPtr  pElement;
00123 register  RealVector  Intermediate;
00124 register  RealNumber  Temp;
00125 register  int  I, *pExtOrder, Size;
00126 ElementPtr  pPivot;
00127 
00128 /* Begin `spSolve'. */
00129     ASSERT( IS_VALID(Matrix) AND IS_FACTORED(Matrix) );
00130 
00131 #if spCOMPLEX
00132     if (Matrix->Complex)
00133     {   SolveComplexMatrix( Matrix, RHS, Solution IMAG_VECTORS );
00134         return;
00135     }
00136 #endif
00137 
00138 #if REAL
00139     Intermediate = Matrix->Intermediate;
00140     Size = Matrix->Size;
00141 
00142 /* Correct array pointers for ARRAY_OFFSET. */
00143 #if NOT ARRAY_OFFSET
00144     --RHS;
00145     --Solution;
00146 #endif
00147 
00148 /* Initialize Intermediate vector. */
00149     pExtOrder = &Matrix->IntToExtRowMap[Size];
00150     for (I = Size; I > 0; I--)
00151         Intermediate[I] = RHS[*(pExtOrder--)];
00152 
00153 /* Forward elimination. Solves Lc = b.*/
00154     for (I = 1; I <= Size; I++)
00155     {   
00156       
00157 /* This step of the elimination is skipped if Temp equals zero. */
00158         if ((Temp = Intermediate[I]) != 0.0)
00159         {   
00160           pPivot = Matrix->Diag[I];
00161           if ( pPivot != 0 && ELEMENT_MAG(pPivot) >  Matrix->AbsThreshold )
00162             {
00163               /*jpc    Intermediate[I] = (Temp *= pPivot->Real);*/
00164               Intermediate[I] = (Temp /= pPivot->Real);
00165               
00166               pElement = pPivot->NextInCol;
00167               while (pElement != NULL)
00168                 {   Intermediate[pElement->Row] -= Temp * pElement->Real;
00169                     pElement = pElement->NextInCol;
00170                   }
00171             }
00172           else
00173             Intermediate[I]= 0.0;
00174         }
00175       }
00176 
00177 /* Backward Substitution. Solves Ux = c.*/
00178 /* modification for singular matrix a diagonal element can be a null pointer */
00179 
00180     for (I = Size ; I > 0; I--)
00181     {   Temp = Intermediate[I];
00182         if ( Matrix->Diag[I] == 0) /* test for nul pointer */
00183           {
00184             Intermediate[I]=0.0;
00185           }
00186         else 
00187           {
00188             pElement = Matrix->Diag[I]->NextInRow;
00189             while (pElement != NULL)
00190               {   Temp -= pElement->Real * Intermediate[pElement->Col];
00191                   pElement = pElement->NextInRow;
00192                 }
00193             Intermediate[I] = Temp;
00194           }
00195       }
00196 
00197 /* Unscramble Intermediate vector while placing data in to Solution vector. */
00198     pExtOrder = &Matrix->IntToExtColMap[Size];
00199     for (I = Size; I > 0; I--)
00200         Solution[*(pExtOrder--)] = Intermediate[I];
00201 
00202     return;
00203 #endif /* REAL */
00204 }
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 #if spCOMPLEX
00217 /*
00218  *  SOLVE COMPLEX MATRIX EQUATION
00219  *
00220  *  Performs forward elimination and back substitution to find the
00221  *  unknown vector from the RHS vector and factored matrix.  This
00222  *  routine assumes that the pivots are associated with the lower
00223  *  triangular (L) matrix and that the diagonal of the upper triangular
00224  *  (U) matrix consists of ones.  This routine arranges the computation
00225  *  in different way than is traditionally used in order to exploit the
00226  *  sparsity of the right-hand side.  See the reference in spRevision.
00227  *
00228  *  >>> Arguments:
00229  *  Matrix  <input>  (char *)
00230  *      Pointer to matrix.
00231  *  RHS  <input>  (RealVector)
00232  *      RHS is the real portion of the input data array, the right hand
00233  *      side. This data is undisturbed and may be reused for other solves.
00234  *  Solution  <output>  (RealVector)
00235  *      Solution is the real portion of the output data array. This routine
00236  *      is constructed such that RHS and Solution can be the same
00237  *      array.
00238  *  iRHS  <input>  (RealVector)
00239  *      iRHS is the imaginary portion of the input data array, the right
00240  *      hand side. This data is undisturbed and may be reused for other solves.
00241  *      If spSEPARATED_COMPLEX_VECTOR is set false, there is no need to
00242  *      supply this array.
00243  *  iSolution  <output>  (RealVector)
00244  *      iSolution is the imaginary portion of the output data array. This
00245  *      routine is constructed such that iRHS and iSolution can be
00246  *      the same array.  If spSEPARATED_COMPLEX_VECTOR is set false, there is no
00247  *      need to supply this array.
00248  *
00249  *  >>> Local variables:
00250  *  Intermediate  (ComplexVector)
00251  *      Temporary storage for use in forward elimination and backward
00252  *      substitution.  Commonly referred to as c, when the LU factorization
00253  *      equations are given as  Ax = b, Lc = b, Ux = c.
00254  *      Local version of Matrix->Intermediate, which was created during
00255  *      the initial factorization in function CreateInternalVectors() in the
00256  *      matrix factorization module.
00257  *  pElement  (ElementPtr)
00258  *      Pointer used to address elements in both the lower and upper triangle
00259  *      matrices.
00260  *  pExtOrder  (int *)
00261  *      Pointer used to sequentially access each entry in IntToExtRowMap
00262  *      and IntToExtColMap arrays.  Used to quickly scramble and unscramble
00263  *      RHS and Solution to account for row and column interchanges.
00264  *  pPivot  (ElementPtr)
00265  *      Pointer that points to current pivot or diagonal element.
00266  *  Size  (int)
00267  *      Size of matrix. Made local to reduce indirection.
00268  *  Temp  (ComplexNumber)
00269  *      Temporary storage for entries in arrays.
00270  *
00271  *  >>> Obscure Macros
00272  *  IMAG_VECTORS
00273  *      Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and
00274  *      spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears
00275  *      without a trace.
00276  */
00277 
00278 static void
00279 SolveComplexMatrix( MatrixPtr Matrix, RealVector RHS, RealVector Solution IMAG_VECTORS )
00280 {
00281 register  ElementPtr  pElement;
00282 register  ComplexVector  Intermediate;
00283 register  int  I, *pExtOrder, Size;
00284 ElementPtr  pPivot;
00285 register ComplexVector  ExtVector;
00286 ComplexNumber  Temp;
00287 
00288 /* Begin `SolveComplexMatrix'. */
00289 
00290     Size = Matrix->Size;
00291     Intermediate = (ComplexVector)Matrix->Intermediate;
00292 
00293 /* Correct array pointers for ARRAY_OFFSET. */
00294 #if NOT ARRAY_OFFSET
00295 #if spSEPARATED_COMPLEX_VECTORS
00296     --RHS;      --iRHS;
00297     --Solution; --iSolution;
00298 #else
00299     RHS -= 2; Solution -= 2;
00300 #endif
00301 #endif
00302 
00303 /* Initialize Intermediate vector. */
00304     pExtOrder = &Matrix->IntToExtRowMap[Size];
00305 
00306 #if spSEPARATED_COMPLEX_VECTORS
00307     for (I = Size; I > 0; I--)
00308     {   Intermediate[I].Real = RHS[*(pExtOrder)];
00309         Intermediate[I].Imag = iRHS[*(pExtOrder--)];
00310     }
00311 #else
00312     ExtVector = (ComplexVector)RHS;
00313     for (I = Size; I > 0; I--)
00314         Intermediate[I] = ExtVector[*(pExtOrder--)];
00315 #endif
00316 
00317 /* Forward substitution. Solves Lc = b.*/
00318     for (I = 1; I <= Size; I++)
00319     {   Temp = Intermediate[I];
00320 
00321 /* This step of the substitution is skipped if Temp equals zero. */
00322         if ((Temp.Real != 0.0) OR (Temp.Imag != 0.0))
00323         {   pPivot = Matrix->Diag[I];
00324 /* Cmplx expr: Temp *= (1.0 / Pivot). */
00325             CMPLX_MULT_ASSIGN(Temp, *pPivot);
00326             Intermediate[I] = Temp;
00327             pElement = pPivot->NextInCol;
00328             while (pElement != NULL)
00329             {
00330 /* Cmplx expr: Intermediate[Element->Row] -= Temp * *Element. */
00331                 CMPLX_MULT_SUBT_ASSIGN(Intermediate[pElement->Row],
00332                                        Temp, *pElement);
00333                 pElement = pElement->NextInCol;
00334             }
00335         }
00336     }
00337 
00338 /* Backward Substitution. Solves Ux = c.*/
00339     for (I = Size; I > 0; I--)
00340     {   Temp = Intermediate[I];
00341         pElement = Matrix->Diag[I]->NextInRow;
00342 
00343         while (pElement != NULL)
00344         {
00345 /* Cmplx expr: Temp -= *Element * Intermediate[Element->Col]. */
00346             CMPLX_MULT_SUBT_ASSIGN(Temp, *pElement,Intermediate[pElement->Col]);
00347             pElement = pElement->NextInRow;
00348         }
00349         Intermediate[I] = Temp;
00350     }
00351 
00352 /* Unscramble Intermediate vector while placing data in to Solution vector. */
00353     pExtOrder = &Matrix->IntToExtColMap[Size];
00354 
00355 #if spSEPARATED_COMPLEX_VECTORS
00356     for (I = Size; I > 0; I--)
00357     {   Solution[*(pExtOrder)] = Intermediate[I].Real;
00358         iSolution[*(pExtOrder--)] = Intermediate[I].Imag;
00359     }
00360 #else
00361     ExtVector = (ComplexVector)Solution;
00362     for (I = Size; I > 0; I--)
00363         ExtVector[*(pExtOrder--)] = Intermediate[I];
00364 #endif
00365 
00366     return;
00367 }
00368 #endif /* spCOMPLEX */
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 #if TRANSPOSE
00384 /*
00385  *  SOLVE TRANSPOSED MATRIX EQUATION
00386  *
00387  *  Performs forward elimination and back substitution to find the
00388  *  unknown vector from the RHS vector and transposed factored
00389  *  matrix. This routine is useful when performing sensitivity analysis
00390  *  on a circuit using the adjoint method.  This routine assumes that
00391  *  the pivots are associated with the untransposed lower triangular
00392  *  (L) matrix and that the diagonal of the untransposed upper
00393  *  triangular (U) matrix consists of ones.
00394  *
00395  *  >>> Arguments:
00396  *  Matrix  <input>  (char *)
00397  *      Pointer to matrix.
00398  *  RHS  <input>  (RealVector)
00399  *      RHS is the input data array, the right hand side. This data is
00400  *      undisturbed and may be reused for other solves.
00401  *  Solution  <output>  (RealVector)
00402  *      Solution is the output data array. This routine is constructed such that
00403  *      RHS and Solution can be the same array.
00404  *  iRHS  <input>  (RealVector)
00405  *      iRHS is the imaginary portion of the input data array, the right
00406  *      hand side. This data is undisturbed and may be reused for other solves.
00407  *      If spSEPARATED_COMPLEX_VECTOR is set false, or if matrix is real, there
00408  *      is no need to supply this array.
00409  *  iSolution  <output>  (RealVector)
00410  *      iSolution is the imaginary portion of the output data array. This
00411  *      routine is constructed such that iRHS and iSolution can be
00412  *      the same array.  If spSEPARATED_COMPLEX_VECTOR is set false, or if
00413  *      matrix is real, there is no need to supply this array.
00414  *
00415  *  >>> Local variables:
00416  *  Intermediate  (RealVector)
00417  *      Temporary storage for use in forward elimination and backward
00418  *      substitution.  Commonly referred to as c, when the LU factorization
00419  *      equations are given as  Ax = b, Lc = b, Ux = c.  Local version of
00420  *      Matrix->Intermediate, which was created during the initial
00421  *      factorization in function CreateInternalVectors() in the matrix
00422  *      factorization module.
00423  *  pElement  (ElementPtr)
00424  *      Pointer used to address elements in both the lower and upper triangle
00425  *      matrices.
00426  *  pExtOrder  (int *)
00427  *      Pointer used to sequentially access each entry in IntToExtRowMap
00428  *      and IntToExtRowMap arrays.  Used to quickly scramble and unscramble
00429  *      RHS and Solution to account for row and column interchanges.
00430  *  pPivot  (ElementPtr)
00431  *      Pointer that points to current pivot or diagonal element.
00432  *  Size  (int)
00433  *      Size of matrix. Made local to reduce indirection.
00434  *  Temp  (RealNumber)
00435  *      Temporary storage for entries in arrays.
00436  *
00437  *  >>> Obscure Macros
00438  *  IMAG_VECTORS
00439  *      Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and
00440  *      spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears
00441  *      without a trace.
00442  */
00443 
00444 /*VARARGS3*/
00445 
00446 void
00447 spSolveTransposed( char *eMatrix, RealVector  RHS, RealVector  Solution IMAG_VECTORS )
00448 {
00449 MatrixPtr  Matrix = (MatrixPtr)eMatrix;
00450 register  ElementPtr  pElement;
00451 register  RealVector  Intermediate;
00452 register  int  I, *pExtOrder, Size;
00453 ElementPtr  pPivot;
00454 RealNumber  Temp;
00455 
00456 
00457 /* Begin `spSolveTransposed'. */
00458     ASSERT( IS_VALID(Matrix) AND IS_FACTORED(Matrix) );
00459 
00460 #if spCOMPLEX
00461     if (Matrix->Complex)
00462     {   SolveComplexTransposedMatrix( Matrix, RHS, Solution IMAG_VECTORS );
00463         return;
00464     }
00465 #endif
00466 
00467 #if REAL
00468     Size = Matrix->Size;
00469     Intermediate = Matrix->Intermediate;
00470 
00471 /* Correct array pointers for ARRAY_OFFSET. */
00472 #if NOT ARRAY_OFFSET
00473     --RHS;
00474     --Solution;
00475 #endif
00476 
00477 /* Initialize Intermediate vector. */
00478     pExtOrder = &Matrix->IntToExtColMap[Size];
00479     for (I = Size; I > 0; I--)
00480         Intermediate[I] = RHS[*(pExtOrder--)];
00481 
00482 /* Forward elimination. */
00483     for (I = 1; I <= Size; I++)
00484     {   
00485 /* This step of the elimination is skipped if Temp equals zero. */
00486         if ((Temp = Intermediate[I]) != 0.0)
00487         {   pElement = Matrix->Diag[I]->NextInRow;
00488             while (pElement != NULL)
00489             {   Intermediate[pElement->Col] -= Temp * pElement->Real;
00490                 pElement = pElement->NextInRow;
00491             }
00492 
00493         }
00494     }
00495 
00496 /* Backward Substitution. */
00497     for (I = Size; I > 0; I--)
00498     {   pPivot = Matrix->Diag[I];
00499         Temp = Intermediate[I];
00500         pElement = pPivot->NextInCol;
00501         while (pElement != NULL)
00502         {   Temp -= pElement->Real * Intermediate[pElement->Row];
00503             pElement = pElement->NextInCol;
00504         }
00505         Intermediate[I] = Temp * pPivot->Real;
00506     }
00507 
00508 /* Unscramble Intermediate vector while placing data in to Solution vector. */
00509     pExtOrder = &Matrix->IntToExtRowMap[Size];
00510     for (I = Size; I > 0; I--)
00511         Solution[*(pExtOrder--)] = Intermediate[I];
00512 
00513     return;
00514 #endif /* REAL */
00515 }
00516 #endif /* TRANSPOSE */
00517 
00518 
00519 
00520 
00521 
00522 
00523 
00524 
00525 
00526 
00527 #if TRANSPOSE AND spCOMPLEX
00528 /*
00529  *  SOLVE COMPLEX TRANSPOSED MATRIX EQUATION
00530  *
00531  *  Performs forward elimination and back substitution to find the
00532  *  unknown vector from the RHS vector and transposed factored
00533  *  matrix. This routine is useful when performing sensitivity analysis
00534  *  on a circuit using the adjoint method.  This routine assumes that
00535  *  the pivots are associated with the untransposed lower triangular
00536  *  (L) matrix and that the diagonal of the untransposed upper
00537  *  triangular (U) matrix consists of ones.
00538  *
00539  *  >>> Arguments:
00540  *  Matrix  <input>  (char *)
00541  *      Pointer to matrix.
00542  *  RHS  <input>  (RealVector)
00543  *      RHS is the input data array, the right hand
00544  *      side. This data is undisturbed and may be reused for other solves.
00545  *      This vector is only the real portion if the matrix is complex and
00546  *      spSEPARATED_COMPLEX_VECTORS is set true.
00547  *  Solution  <output>  (RealVector)
00548  *      Solution is the real portion of the output data array. This routine
00549  *      is constructed such that RHS and Solution can be the same array.
00550  *      This vector is only the real portion if the matrix is complex and
00551  *      spSEPARATED_COMPLEX_VECTORS is set true.
00552  *  iRHS  <input>  (RealVector)
00553  *      iRHS is the imaginary portion of the input data array, the right
00554  *      hand side. This data is undisturbed and may be reused for other solves.
00555  *      If either spCOMPLEX or spSEPARATED_COMPLEX_VECTOR is set false, there
00556  *      is no need to supply this array.
00557  *  iSolution  <output>  (RealVector)
00558  *      iSolution is the imaginary portion of the output data array. This
00559  *      routine is constructed such that iRHS and iSolution can be
00560  *      the same array.  If spCOMPLEX or spSEPARATED_COMPLEX_VECTOR is set
00561  *      false, there is no need to supply this array.
00562  *
00563  *  >>> Local variables:
00564  *  Intermediate  (ComplexVector)
00565  *      Temporary storage for use in forward elimination and backward
00566  *      substitution.  Commonly referred to as c, when the LU factorization
00567  *      equations are given as  Ax = b, Lc = b, Ux = c.  Local version of
00568  *      Matrix->Intermediate, which was created during
00569  *      the initial factorization in function CreateInternalVectors() in the
00570  *      matrix factorization module.
00571  *  pElement  (ElementPtr)
00572  *      Pointer used to address elements in both the lower and upper triangle
00573  *      matrices.
00574  *  pExtOrder  (int *)
00575  *      Pointer used to sequentially access each entry in IntToExtRowMap
00576  *      and IntToExtColMap arrays.  Used to quickly scramble and unscramble
00577  *      RHS and Solution to account for row and column interchanges.
00578  *  pPivot  (ElementPtr)
00579  *      Pointer that points to current pivot or diagonal element.
00580  *  Size  (int)
00581  *      Size of matrix. Made local to reduce indirection.
00582  *  Temp  (ComplexNumber)
00583  *      Temporary storage for entries in arrays.
00584  *
00585  *  >>> Obscure Macros
00586  *  IMAG_VECTORS
00587  *      Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and
00588  *      spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears
00589  *      without a trace.
00590  */
00591 
00592 static void
00593 SolveComplexTransposedMatrix(MatrixPtr Matrix, RealVector RHS, RealVector Solution IMAG_VECTORS )
00594 {
00595 register  ElementPtr  pElement;
00596 register  ComplexVector  Intermediate;
00597 register  int  I, *pExtOrder, Size;
00598 register  ComplexVector  ExtVector;
00599 ElementPtr  pPivot;
00600 ComplexNumber  Temp;
00601 
00602 /* Begin `SolveComplexTransposedMatrix'. */
00603 
00604     Size = Matrix->Size;
00605     Intermediate = (ComplexVector)Matrix->Intermediate;
00606 
00607 /* Correct array pointers for ARRAY_OFFSET. */
00608 #if NOT ARRAY_OFFSET
00609 #if spSEPARATED_COMPLEX_VECTORS
00610     --RHS;      --iRHS;
00611     --Solution; --iSolution;
00612 #else
00613     RHS -= 2;   Solution -= 2;
00614 #endif
00615 #endif
00616 
00617 /* Initialize Intermediate vector. */
00618     pExtOrder = &Matrix->IntToExtColMap[Size];
00619 
00620 #if spSEPARATED_COMPLEX_VECTORS
00621     for (I = Size; I > 0; I--)
00622     {   Intermediate[I].Real = RHS[*(pExtOrder)];
00623         Intermediate[I].Imag = iRHS[*(pExtOrder--)];
00624     }
00625 #else
00626     ExtVector = (ComplexVector)RHS;
00627     for (I = Size; I > 0; I--)
00628         Intermediate[I] = ExtVector[*(pExtOrder--)];
00629 #endif
00630 
00631 /* Forward elimination. */
00632     for (I = 1; I <= Size; I++)
00633     {   Temp = Intermediate[I];
00634 
00635 /* This step of the elimination is skipped if Temp equals zero. */
00636         if ((Temp.Real != 0.0) OR (Temp.Imag != 0.0))
00637         {   pElement = Matrix->Diag[I]->NextInRow;
00638             while (pElement != NULL)
00639             {
00640 /* Cmplx expr: Intermediate[Element->Col] -= Temp * *Element. */
00641                 CMPLX_MULT_SUBT_ASSIGN( Intermediate[pElement->Col],
00642                                         Temp, *pElement);
00643                 pElement = pElement->NextInRow;
00644             }
00645         }
00646     }
00647 
00648 /* Backward Substitution. */
00649     for (I = Size; I > 0; I--)
00650     {   pPivot = Matrix->Diag[I];
00651         Temp = Intermediate[I];
00652         pElement = pPivot->NextInCol;
00653 
00654         while (pElement != NULL)
00655         {
00656 /* Cmplx expr: Temp -= Intermediate[Element->Row] * *Element. */
00657             CMPLX_MULT_SUBT_ASSIGN(Temp,Intermediate[pElement->Row],*pElement);
00658 
00659             pElement = pElement->NextInCol;
00660         }
00661 /* Cmplx expr: Intermediate = Temp * (1.0 / *pPivot). */
00662         CMPLX_MULT(Intermediate[I], Temp, *pPivot);
00663     }
00664 
00665 /* Unscramble Intermediate vector while placing data in to Solution vector. */
00666     pExtOrder = &Matrix->IntToExtRowMap[Size];
00667 
00668 #if spSEPARATED_COMPLEX_VECTORS
00669     for (I = Size; I > 0; I--)
00670     {   Solution[*(pExtOrder)] = Intermediate[I].Real;
00671         iSolution[*(pExtOrder--)] = Intermediate[I].Imag;
00672     }
00673 #else
00674     ExtVector = (ComplexVector)Solution;
00675     for (I = Size; I > 0; I--)
00676         ExtVector[*(pExtOrder--)] = Intermediate[I];
00677 #endif
00678 
00679     return;
00680 }
00681 #endif /* TRANSPOSE AND spCOMPLEX */

Generated on Sun Mar 4 15:04:00 2007 for Scilab [trunk] by  doxygen 1.5.1