Amesos Package Browser (Single Doxygen Collection) Development
amesos_cholmod_resymbol.c
Go to the documentation of this file.
00001 /* ========================================================================== */
00002 /* === Cholesky/cholmod_resymbol ============================================ */
00003 /* ========================================================================== */
00004 
00005 /* -----------------------------------------------------------------------------
00006  * CHOLMOD/Cholesky Module.  Copyright (C) 2005-2006, Timothy A. Davis
00007  * The CHOLMOD/Cholesky Module is licensed under Version 2.1 of the GNU
00008  * Lesser General Public License.  See lesser.txt for a text of the license.
00009  * CHOLMOD is also available under other licenses; contact authors for details.
00010  * http://www.cise.ufl.edu/research/sparse
00011  * -------------------------------------------------------------------------- */
00012 
00013 /* Recompute the symbolic pattern of L.  Entries not in the symbolic pattern
00014  * are dropped.  L->Perm can be used (or not) to permute the input matrix A.
00015  *
00016  * These routines are used after a supernodal factorization is converted into
00017  * a simplicial one, to remove zero entries that were added due to relaxed
00018  * supernode amalgamation.  They can also be used after a series of downdates
00019  * to remove entries that would no longer be present if the matrix were
00020  * factorized from scratch.  A downdate (cholmod_updown) does not remove any
00021  * entries from L.
00022  *
00023  * workspace: Flag (nrow), Head (nrow+1),
00024  *  if symmetric:   Iwork (2*nrow)
00025  *  if unsymmetric: Iwork (2*nrow+ncol).
00026  *  Allocates up to 2 copies of its input matrix A (pattern only).
00027  */
00028 
00029 #ifndef NCHOLESKY
00030 
00031 #include "amesos_cholmod_internal.h"
00032 #include "amesos_cholmod_cholesky.h"
00033 
00034 /* ========================================================================== */
00035 /* === cholmod_resymbol ===================================================== */
00036 /* ========================================================================== */
00037 
00038 /* Remove entries from L that are not in the factorization of P*A*P', P*A*A'*P',
00039  * or P*F*F'*P' (depending on A->stype and whether fset is NULL or not).
00040  *
00041  * cholmod_resymbol is the same as cholmod_resymbol_noperm, except that it
00042  * first permutes A according to L->Perm.  A can be upper/lower/unsymmetric,
00043  * in contrast to cholmod_resymbol_noperm (which can be lower or unsym). */
00044 
00045 int CHOLMOD(resymbol)
00046 (
00047     /* ---- input ---- */
00048     cholmod_sparse *A,  /* matrix to analyze */
00049     Int *fset,    /* subset of 0:(A->ncol)-1 */
00050     size_t fsize, /* size of fset */
00051     int pack,   /* if TRUE, pack the columns of L */
00052     /* ---- in/out --- */
00053     cholmod_factor *L,  /* factorization, entries pruned on output */
00054     /* --------------- */
00055     cholmod_common *Common
00056 )
00057 {
00058     cholmod_sparse *H, *F, *G ;
00059     Int stype, nrow, ncol ;
00060     size_t s ;
00061     int ok = TRUE ;
00062 
00063     /* ---------------------------------------------------------------------- */
00064     /* check inputs */
00065     /* ---------------------------------------------------------------------- */
00066 
00067     RETURN_IF_NULL_COMMON (FALSE) ;
00068     RETURN_IF_NULL (A, FALSE) ;
00069     RETURN_IF_NULL (L, FALSE) ;
00070     RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ;
00071     RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ;
00072     Common->status = CHOLMOD_OK ;
00073     if (L->is_super)
00074     {
00075   /* cannot operate on a supernodal factorization */
00076   ERROR (CHOLMOD_INVALID, "cannot operate on supernodal L") ;
00077   return (FALSE) ;
00078     }
00079     if (L->n != A->nrow)
00080     {
00081   /* dimensions must agree */
00082   ERROR (CHOLMOD_INVALID, "A and L dimensions do not match") ;
00083   return (FALSE) ;
00084     }
00085 
00086     /* ---------------------------------------------------------------------- */
00087     /* allocate workspace */
00088     /* ---------------------------------------------------------------------- */
00089 
00090     stype = A->stype ;
00091     nrow = A->nrow ;
00092     ncol = A->ncol ;
00093 
00094     /* s = 2*nrow + (stype ? 0 : ncol) */
00095     s = CHOLMOD(mult_size_t) (nrow, 2, &ok) ;
00096     s = CHOLMOD(add_size_t) (s, (stype ? 0 : ncol), &ok) ;
00097     if (!ok)
00098     {
00099   ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
00100   return (FALSE) ;
00101     }
00102 
00103     CHOLMOD(allocate_work) (nrow, s, 0, Common) ;
00104     if (Common->status < CHOLMOD_OK)
00105     {
00106   return (FALSE) ;
00107     }
00108 
00109     /* ---------------------------------------------------------------------- */
00110     /* permute the input matrix if necessary */
00111     /* ---------------------------------------------------------------------- */
00112 
00113     H = NULL ;
00114     G = NULL ;
00115 
00116     if (stype > 0)
00117     {
00118   if (L->ordering == CHOLMOD_NATURAL)
00119   {
00120       /* F = triu(A)' */
00121       /* workspace: Iwork (nrow) */
00122       G = CHOLMOD(ptranspose) (A, 0, NULL, NULL, 0, Common) ;
00123   }
00124   else
00125   {
00126       /* F = triu(A(p,p))' */
00127       /* workspace: Iwork (2*nrow) */
00128       G = CHOLMOD(ptranspose) (A, 0, L->Perm, NULL, 0, Common) ;
00129   }
00130   F = G ;
00131     }
00132     else if (stype < 0)
00133     {
00134   if (L->ordering == CHOLMOD_NATURAL)
00135   {
00136       F = A ;
00137   }
00138   else
00139   {
00140       /* G = triu(A(p,p))' */
00141       /* workspace: Iwork (2*nrow) */
00142       G = CHOLMOD(ptranspose) (A, 0, L->Perm, NULL, 0, Common) ;
00143       /* H = G' */
00144       /* workspace: Iwork (nrow) */
00145       H = CHOLMOD(ptranspose) (G, 0, NULL, NULL, 0, Common) ;
00146       F = H ;
00147   }
00148     }
00149     else
00150     {
00151   if (L->ordering == CHOLMOD_NATURAL)
00152   {
00153       F = A ;
00154   }
00155   else
00156   {
00157       /* G = A(p,f)' */
00158       /* workspace: Iwork (nrow if no fset; MAX (nrow,ncol) if fset)*/
00159       G = CHOLMOD(ptranspose) (A, 0, L->Perm, fset, fsize, Common) ;
00160       /* H = G' */
00161       /* workspace: Iwork (ncol) */
00162       H = CHOLMOD(ptranspose) (G, 0, NULL, NULL, 0, Common) ;
00163       F = H ;
00164   }
00165     }
00166 
00167     /* No need to check for failure here.  cholmod_resymbol_noperm will return
00168      * FALSE if F is NULL. */
00169 
00170     /* ---------------------------------------------------------------------- */
00171     /* resymbol */
00172     /* ---------------------------------------------------------------------- */
00173 
00174     ok = CHOLMOD(resymbol_noperm) (F, fset, fsize, pack, L, Common) ;
00175 
00176     /* ---------------------------------------------------------------------- */
00177     /* free the temporary matrices, if they exist */
00178     /* ---------------------------------------------------------------------- */
00179 
00180     CHOLMOD(free_sparse) (&H, Common) ;
00181     CHOLMOD(free_sparse) (&G, Common) ;
00182     return (ok) ;
00183 }
00184 
00185 
00186 /* ========================================================================== */
00187 /* === cholmod_resymbol_noperm ============================================== */
00188 /* ========================================================================== */
00189 
00190 /* Redo symbolic LDL' or LL' factorization of I + F*F' or I+A, where F=A(:,f).
00191  *
00192  * L already exists, but is a superset of the true dynamic pattern (simple
00193  * column downdates and row deletions haven't pruned anything).  Just redo the
00194  * symbolic factorization and drop entries that are no longer there.  The
00195  * diagonal is not modified.  The number of nonzeros in column j of L
00196  * (L->nz[j]) can decrease.  The column pointers (L->p[j]) remain unchanged if
00197  * pack is FALSE or if L is not monotonic.  Otherwise, the columns of L are
00198  * packed in place.
00199  *
00200  * For the symmetric case, the columns of the lower triangular part of A
00201  * are accessed by column.  NOTE that this the transpose of the general case.
00202  *
00203  * For the unsymmetric case, F=A(:,f) is accessed by column.
00204  *
00205  * A need not be sorted, and can be packed or unpacked.  If L->Perm is not
00206  * identity, then A must already be permuted according to the permutation used
00207  * to factorize L.  The advantage of using this routine is that it does not
00208  * need to create permuted copies of A first.
00209  *
00210  * This routine can be called if L is only partially factored via cholmod_rowfac
00211  * since all it does is prune.  If an entry is in F*F' or A, but not in L, it
00212  * isn't added to L.
00213  *
00214  * L must be simplicial LDL' or LL'; it cannot be supernodal or symbolic.
00215  *
00216  * The set f is held in fset and fsize.
00217  *  fset = NULL means ":" in MATLAB. fset is ignored.
00218  *  fset != NULL means f = fset [0..fset-1].
00219  *  fset != NULL and fsize = 0 means f is the empty set.
00220  *  There can be no duplicates in fset.
00221  *  Common->status is set to CHOLMOD_INVALID if fset is invalid.
00222  *
00223  * workspace: Flag (nrow), Head (nrow+1),
00224  *  if symmetric:   Iwork (2*nrow)
00225  *  if unsymmetric: Iwork (2*nrow+ncol).
00226  *  Unlike cholmod_resymbol, this routine does not allocate any temporary
00227  *  copies of its input matrix.
00228  */
00229 
00230 int CHOLMOD(resymbol_noperm)
00231 (
00232     /* ---- input ---- */
00233     cholmod_sparse *A,  /* matrix to analyze */
00234     Int *fset,    /* subset of 0:(A->ncol)-1 */
00235     size_t fsize, /* size of fset */
00236     int pack,   /* if TRUE, pack the columns of L */
00237     /* ---- in/out --- */
00238     cholmod_factor *L,  /* factorization, entries pruned on output */
00239     /* --------------- */
00240     cholmod_common *Common
00241 )
00242 {
00243     double *Lx, *Lz ;
00244     Int i, j, k, row, parent, p, pend, pdest, ncol, apacked, sorted, nrow, nf,
00245   use_fset, mark, jj, stype, xtype ;
00246     Int *Ap, *Ai, *Anz, *Li, *Lp, *Lnz, *Flag, *Head, *Link, *Anext, *Iwork ;
00247     size_t s ;
00248     int ok = TRUE ;
00249 
00250     /* ---------------------------------------------------------------------- */
00251     /* check inputs */
00252     /* ---------------------------------------------------------------------- */
00253 
00254     RETURN_IF_NULL_COMMON (FALSE) ;
00255     RETURN_IF_NULL (A, FALSE) ;
00256     RETURN_IF_NULL (L, FALSE) ;
00257     RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ;
00258     RETURN_IF_XTYPE_INVALID (L, CHOLMOD_REAL, CHOLMOD_ZOMPLEX, FALSE) ;
00259     ncol = A->ncol ;
00260     nrow = A->nrow ;
00261     stype = A->stype ;
00262     ASSERT (IMPLIES (stype != 0, nrow == ncol)) ;
00263     if (stype > 0)
00264     {
00265   /* symmetric, with upper triangular part, not supported */
00266   ERROR (CHOLMOD_INVALID, "symmetric upper not supported ") ;
00267   return (FALSE) ;
00268     }
00269     if (L->is_super)
00270     {
00271   /* cannot operate on a supernodal or symbolic factorization */
00272   ERROR (CHOLMOD_INVALID, "cannot operate on supernodal L") ;
00273   return (FALSE) ;
00274     }
00275     if (L->n != A->nrow)
00276     {
00277   /* dimensions must agree */
00278   ERROR (CHOLMOD_INVALID, "A and L dimensions do not match") ;
00279   return (FALSE) ;
00280     }
00281     Common->status = CHOLMOD_OK ;
00282 
00283     /* ---------------------------------------------------------------------- */
00284     /* allocate workspace */
00285     /* ---------------------------------------------------------------------- */
00286 
00287     /* s = 2*nrow + (stype ? 0 : ncol) */
00288     s = CHOLMOD(mult_size_t) (nrow, 2, &ok) ;
00289     if (stype != 0)
00290     {
00291   s = CHOLMOD(add_size_t) (s, ncol, &ok) ;
00292     }
00293     if (!ok)
00294     {
00295   ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
00296   return (FALSE) ;
00297     }
00298 
00299     CHOLMOD(allocate_work) (nrow, s, 0, Common) ;
00300     if (Common->status < CHOLMOD_OK)
00301     {
00302   return (FALSE) ;  /* out of memory */
00303     }
00304     ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ;
00305 
00306     /* ---------------------------------------------------------------------- */
00307     /* get inputs */
00308     /* ---------------------------------------------------------------------- */
00309 
00310     Ai = A->i ;
00311     Ap = A->p ;
00312     Anz = A->nz ;
00313     apacked = A->packed ;
00314     sorted = A->sorted ;
00315 
00316     Li = L->i ;
00317     Lx = L->x ;
00318     Lz = L->z ;
00319     Lp = L->p ;
00320     Lnz = L->nz ;
00321     xtype = L->xtype ;
00322 
00323     /* If L is monotonic on input, then it can be packed or
00324      * unpacked on output, depending on the pack input parameter. */
00325 
00326     /* cannot pack a non-monotonic matrix */
00327     if (!(L->is_monotonic))
00328     {
00329   pack = FALSE ;
00330     }
00331 
00332     ASSERT (L->nzmax >= (size_t) (Lp [L->n])) ;
00333 
00334     pdest = 0 ;
00335 
00336     PRINT1 (("\n\n===================== Resymbol pack %d Apacked %d\n",
00337   pack, A->packed)) ;
00338     ASSERT (CHOLMOD(dump_sparse) (A, "ReSymbol A:", Common) >= 0) ;
00339     DEBUG (CHOLMOD(dump_factor) (L, "ReSymbol initial L (i, x):", Common)) ;
00340 
00341     /* ---------------------------------------------------------------------- */
00342     /* get workspace */
00343     /* ---------------------------------------------------------------------- */
00344 
00345     Flag  = Common->Flag ;  /* size nrow */
00346     Head  = Common->Head ;  /* size nrow+1 */
00347     Iwork = Common->Iwork ;
00348     Link  = Iwork ;   /* size nrow (i/i/l) [ */
00349     Lnz   = Iwork + nrow ;  /* size nrow (i/i/l), if L not packed */
00350     Anext = Iwork + 2*((size_t) nrow) ; /* size ncol (i/i/l), unsym. only */
00351     for (j = 0 ; j < nrow ; j++)
00352     {
00353   Link [j] = EMPTY ;
00354     }
00355 
00356     /* use Lnz in L itself */
00357     Lnz = L->nz ;
00358     ASSERT (Lnz != NULL) ;
00359 
00360     /* ---------------------------------------------------------------------- */
00361     /* for the unsymmetric case, queue each column of A (:,f) */
00362     /* ---------------------------------------------------------------------- */
00363 
00364     /* place each column of the basis set on the link list corresponding to */
00365     /* the smallest row index in that column */
00366 
00367     if (stype == 0)
00368     {
00369   use_fset = (fset != NULL) ;
00370   if (use_fset)
00371   {
00372       nf = fsize ;
00373       /* This is the only O(ncol) loop in cholmod_resymbol.
00374        * It is required only to check the fset. */
00375       for (j = 0 ; j < ncol ; j++)
00376       {
00377     Anext [j] = -2 ;
00378       }
00379       for (jj = 0 ; jj < nf ; jj++)
00380       {
00381     j = fset [jj] ;
00382     if (j < 0 || j > ncol || Anext [j] != -2)
00383     {
00384         /* out-of-range or duplicate entry in fset */
00385         ERROR (CHOLMOD_INVALID, "fset invalid") ;
00386         ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ;
00387         return (FALSE) ;
00388     }
00389     /* flag column j as having been seen */
00390     Anext [j] = EMPTY ;
00391       }
00392       /* the fset is now valid */
00393       ASSERT (CHOLMOD(dump_perm) (fset, nf, ncol, "fset", Common)) ;
00394   }
00395   else
00396   {
00397       nf = ncol ;
00398   }
00399   for (jj = 0 ; jj < nf ; jj++)
00400   {
00401       j = (use_fset) ? (fset [jj]) : jj ;
00402       /* column j is the fset; find the smallest row (if any) */
00403       p = Ap [j] ;
00404       pend = (apacked) ? (Ap [j+1]) : (p + Anz [j]) ;
00405       if (pend > p)
00406       {
00407     k = Ai [p] ;
00408     if (!sorted)
00409     {
00410         for ( ; p < pend ; p++)
00411         {
00412       k = MIN (k, Ai [p]) ;
00413         }
00414     }
00415     /* place column j on link list k */
00416     ASSERT (k >= 0 && k < nrow) ;
00417     Anext [j] = Head [k] ;
00418     Head [k] = j ;
00419       }
00420   }
00421     }
00422 
00423     /* ---------------------------------------------------------------------- */
00424     /* recompute symbolic LDL' factorization */
00425     /* ---------------------------------------------------------------------- */
00426 
00427     for (k = 0 ; k < nrow ; k++)
00428     {
00429 
00430 #ifndef NDEBUG
00431   PRINT1 (("\n\n================== Initial column k = "ID"\n", k)) ;
00432   for (p = Lp [k] ; p < Lp [k] + Lnz [k] ; p++)
00433   {
00434       PRINT1 ((" row: "ID"  value: ", Li [p])) ;
00435       PRINT1 (("\n")) ;
00436   }
00437   PRINT1 (("Recomputing LDL, column k = "ID"\n", k)) ;
00438 #endif
00439 
00440   /* ------------------------------------------------------------------ */
00441   /* compute column k of I+F*F' or I+A */
00442   /* ------------------------------------------------------------------ */
00443 
00444   /* flag the diagonal entry */
00445   mark = CHOLMOD(clear_flag) (Common) ;
00446   Flag [k] = mark ;
00447   PRINT1 (("  row: "ID" (diagonal)\n", k)) ;
00448 
00449   if (stype != 0)
00450   {
00451       /* merge column k of A into Flag (lower triangular part only) */
00452       p = Ap [k] ;
00453       pend = (apacked) ? (Ap [k+1]) : (p + Anz [k]) ;
00454       for ( ; p < pend ; p++)
00455       {
00456     i = Ai [p] ;
00457     if (i > k)
00458     {
00459         Flag [i] = mark ;
00460     }
00461       }
00462   }
00463   else
00464   {
00465       /* for each column j whos first row index is in row k */
00466       for (j = Head [k] ; j != EMPTY ; j = Anext [j])
00467       {
00468     /* merge column j of A into Flag */
00469     PRINT1 (("  ---- A column "ID"\n", j)) ;
00470     p = Ap [j] ;
00471     pend = (apacked) ? (Ap [j+1]) : (p + Anz [j]) ;
00472     PRINT1 (("  length "ID"  adding\n", pend-p)) ;
00473     for ( ; p < pend ; p++)
00474     {
00475 #ifndef NDEBUG
00476         ASSERT (Ai [p] >= k && Ai [p] < nrow) ;
00477         if (Flag [Ai [p]] < mark) PRINT1 ((" row "ID"\n", Ai [p])) ;
00478 #endif
00479         Flag [Ai [p]] = mark ;
00480     }
00481       }
00482       /* clear the kth link list */
00483       Head [k] = EMPTY ;
00484   }
00485 
00486   /* ------------------------------------------------------------------ */
00487   /* compute pruned pattern of kth column of L = union of children */
00488   /* ------------------------------------------------------------------ */
00489 
00490   /* for each column j of L whose parent is k */
00491   for (j = Link [k] ; j != EMPTY ; j = Link [j])
00492   {
00493       /* merge column j of L into Flag */
00494       PRINT1 (("  ---- L column "ID"\n", k)) ;
00495       ASSERT (j < k) ;
00496       ASSERT (Lnz [j] > 0) ;
00497       p = Lp [j] ;
00498       pend = p + Lnz [j] ;
00499       ASSERT (Li [p] == j && Li [p+1] == k) ;
00500       p++ ;     /* skip past the diagonal entry */
00501       for ( ; p < pend ; p++)
00502       {
00503     /* add to pattern */
00504     ASSERT (Li [p] >= k && Li [p] < nrow) ;
00505     Flag [Li [p]] = mark ;
00506       }
00507   }
00508 
00509   /* ------------------------------------------------------------------ */
00510   /* prune the kth column of L */
00511   /* ------------------------------------------------------------------ */
00512 
00513   PRINT1 (("Final column of L:\n")) ;
00514   p = Lp [k] ;
00515   pend = p + Lnz [k] ;
00516 
00517   if (pack)
00518   {
00519       /* shift column k upwards */
00520       Lp [k] = pdest ;
00521   }
00522   else
00523   {
00524       /* leave column k in place, just reduce Lnz [k] */
00525       pdest = p ;
00526   }
00527 
00528   for ( ; p < pend ; p++)
00529   {
00530       ASSERT (pdest < pend) ;
00531       ASSERT (pdest <= p) ;
00532       row = Li [p] ;
00533       ASSERT (row >= k && row < nrow) ;
00534       if (Flag [row] == mark)
00535       {
00536     /* keep this entry */
00537     Li [pdest] = row ;
00538     if (xtype == CHOLMOD_REAL)
00539     {
00540         Lx [pdest] = Lx [p] ;
00541     }
00542     else if (xtype == CHOLMOD_COMPLEX)
00543     {
00544         Lx [2*pdest  ] = Lx [2*p  ] ;
00545         Lx [2*pdest+1] = Lx [2*p+1] ;
00546     }
00547     else if (xtype == CHOLMOD_ZOMPLEX)
00548     {
00549         Lx [pdest] = Lx [p] ;
00550         Lz [pdest] = Lz [p] ;
00551     }
00552     pdest++ ;
00553       }
00554   }
00555 
00556   /* ------------------------------------------------------------------ */
00557   /* prepare this column for its parent */
00558   /* ------------------------------------------------------------------ */
00559 
00560   Lnz [k] = pdest - Lp [k] ;
00561 
00562   PRINT1 ((" L("ID") length "ID"\n", k, Lnz [k])) ;
00563   ASSERT (Lnz [k] > 0) ;
00564 
00565   /* parent is the first entry in the column after the diagonal */
00566   parent = (Lnz [k] > 1) ? (Li [Lp [k] + 1]) : EMPTY ;
00567 
00568   PRINT1 (("parent ("ID") = "ID"\n", k, parent)) ;
00569   ASSERT ((parent > k && parent < nrow) || (parent == EMPTY)) ;
00570 
00571   if (parent != EMPTY)
00572   {
00573       Link [k] = Link [parent] ;
00574       Link [parent] = k ;
00575   }
00576     }
00577 
00578     /* done using Iwork for Link, Lnz (if needed), and Anext ] */
00579 
00580     /* ---------------------------------------------------------------------- */
00581     /* convert L to packed, if requested */
00582     /* ---------------------------------------------------------------------- */
00583 
00584     if (pack)
00585     {
00586   /* finalize Lp */
00587   Lp [nrow] = pdest ;
00588   /* Shrink L to be just large enough.  It cannot fail. */
00589   /* workspace: none */
00590   ASSERT ((size_t) (Lp [nrow]) <= L->nzmax) ;
00591   CHOLMOD(reallocate_factor) (Lp [nrow], L, Common) ;
00592   ASSERT (Common->status >= CHOLMOD_OK) ;
00593     }
00594 
00595     /* ---------------------------------------------------------------------- */
00596     /* clear workspace */
00597     /* ---------------------------------------------------------------------- */
00598 
00599     CHOLMOD(clear_flag) (Common) ;
00600     DEBUG (CHOLMOD(dump_factor) (L, "ReSymbol final L (i, x):", Common)) ;
00601     ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ;
00602     return (TRUE) ;
00603 }
00604 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines