# HG changeset patch # User Daniel Kraft # Date 1410265923 -7200 # Tue Sep 09 14:32:03 2014 +0200 # Node ID be29bd5d63b2316988d1280e314b0443fe956f60 # Parent afc1a8965664c891630714c00e11bc705a842f12 Rework internal structure of sparse_base_chol_rep * liboctave/numeric/sparse-base-chol.h: Make sparse_base_chol_rep hold also cholmod_factor as a class member. Add routines to handle it. * liboctave/numeric/sparse-base-chol.cc: Split the code from sparse_base_chol_rep::init into multiple parts for initialising the cholmod_common, cleaning up, and converting the cholmod_factor to the final cholmod_sparse. diff -r afc1a8965664 -r be29bd5d63b2 .hgsubstate --- a/.hgsubstate Mon Sep 08 08:09:45 2014 +0200 +++ b/.hgsubstate Tue Sep 09 14:32:03 2014 +0200 @@ -1,1 +1,1 @@ -6d4e36653a40da6604507406f2a97e3e64bf9dbf gnulib-hg +2539dbbdf52a445c223b4366edac5cde5530be64 gnulib-hg diff -r afc1a8965664 -r be29bd5d63b2 liboctave/numeric/sparse-base-chol.cc --- a/liboctave/numeric/sparse-base-chol.cc Mon Sep 08 08:09:45 2014 +0200 +++ b/liboctave/numeric/sparse-base-chol.cc Tue Sep 09 14:32:03 2014 +0200 @@ -34,6 +34,82 @@ #include "MatrixType.h" #ifdef HAVE_CHOLMOD + +template +void +sparse_base_chol::sparse_base_chol_rep::init_common + () +{ + CHOLMOD_NAME(start) (&Common); + Common.prefer_zomplex = false; + + double spu = octave_sparse_params::get_key ("spumoni"); + if (spu == 0.) + { + Common.print = -1; + Common.print_function = 0; + } + else + { + Common.print = static_cast (spu) + 2; + Common.print_function =&SparseCholPrint; + } + + Common.error_handler = &SparseCholError; + Common.complex_divide = CHOLMOD_NAME(divcomplex); + Common.hypotenuse = CHOLMOD_NAME(hypot); + + Common.final_asis = false; + Common.final_super = false; + Common.final_ll = true; + Common.final_pack = true; + Common.final_monotonic = true; + Common.final_resymbol = false; +} + +template +void +sparse_base_chol::sparse_base_chol_rep + ::factor_to_sparse (bool natural) +{ + assert (Lfactor); + + BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + cond = CHOLMOD_NAME(rcond) (Lfactor, &Common); + END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + + minor_p = Lfactor->minor; + + clear_sparse (); + BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + Lsparse = CHOLMOD_NAME(factor_to_sparse) (Lfactor, &Common); + END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + + if (minor_p > 0 && minor_p < Lfactor->n) + { + size_t n1 = Lfactor->n + 1; + Lsparse->p = CHOLMOD_NAME(realloc) (minor_p+1, + sizeof(octave_idx_type), + Lsparse->p, &n1, &Common); + BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + CHOLMOD_NAME(reallocate_sparse) + (static_cast(Lsparse->p)[minor_p], Lsparse, &Common); + END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; + Lsparse->ncol = minor_p; + } + + drop_zeros (Lsparse); + + if (! natural) + { + perms.resize (Lfactor->n); + for (octave_idx_type i = 0; i < Lfactor->n; i++) + perms(i) = static_cast(Lfactor->Perm)[i]; + } + + clear_factor (); +} + // Can't use CHOLMOD_NAME(drop)(0.0, S, cm). It doesn't treat complex matrices template void @@ -95,35 +171,6 @@ return -1; } - cholmod_common *cm = &Common; - - // Setup initial parameters - CHOLMOD_NAME(start) (cm); - cm->prefer_zomplex = false; - - double spu = octave_sparse_params::get_key ("spumoni"); - if (spu == 0.) - { - cm->print = -1; - cm->print_function = 0; - } - else - { - cm->print = static_cast (spu) + 2; - cm->print_function =&SparseCholPrint; - } - - cm->error_handler = &SparseCholError; - cm->complex_divide = CHOLMOD_NAME(divcomplex); - cm->hypotenuse = CHOLMOD_NAME(hypot); - - cm->final_asis = false; - cm->final_super = false; - cm->final_ll = true; - cm->final_pack = true; - cm->final_monotonic = true; - cm->final_resymbol = false; - cholmod_sparse A; cholmod_sparse *ac = &A; double dummy; @@ -157,62 +204,22 @@ // use natural ordering if no q output parameter if (natural) { - cm->nmethods = 1 ; - cm->method[0].ordering = CHOLMOD_NATURAL ; - cm->postorder = false ; + Common.nmethods = 1 ; + Common.method[0].ordering = CHOLMOD_NATURAL ; + Common.postorder = false ; } - cholmod_factor *Lfactor; + clear_factor (); BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - Lfactor = CHOLMOD_NAME(analyze) (ac, cm); - CHOLMOD_NAME(factorize) (ac, Lfactor, cm); + Lfactor = CHOLMOD_NAME(analyze) (ac, &Common); + CHOLMOD_NAME(factorize) (ac, Lfactor, &Common); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - is_pd = cm->status == CHOLMOD_OK; - info = (is_pd ? 0 : cm->status); + is_pd = Common.status == CHOLMOD_OK; + info = (is_pd ? 0 : Common.status); if (is_pd || force) - { - BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - cond = CHOLMOD_NAME(rcond) (Lfactor, cm); - END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - - minor_p = Lfactor->minor; - - BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - Lsparse = CHOLMOD_NAME(factor_to_sparse) (Lfactor, cm); - END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - - if (minor_p > 0 && minor_p < a_nr) - { - size_t n1 = a_nr + 1; - Lsparse->p = CHOLMOD_NAME(realloc) (minor_p+1, - sizeof(octave_idx_type), - Lsparse->p, &n1, cm); - BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - CHOLMOD_NAME(reallocate_sparse) - (static_cast(Lsparse->p)[minor_p], Lsparse, cm); - END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - Lsparse->ncol = minor_p; - } - - drop_zeros (Lsparse); - - if (! natural) - { - perms.resize (a_nr); - for (octave_idx_type i = 0; i < a_nr; i++) - perms(i) = static_cast(Lfactor->Perm)[i]; - } - - static char tmp[] = " "; - - BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - CHOLMOD_NAME(free_factor) (&Lfactor, cm); - CHOLMOD_NAME(finish) (cm); - CHOLMOD_NAME(print_common) (tmp, cm); - END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - } + factor_to_sparse (natural); #else (*current_liboctave_error_handler) ("Missing CHOLMOD. Sparse cholesky factorization disabled"); diff -r afc1a8965664 -r be29bd5d63b2 liboctave/numeric/sparse-base-chol.h --- a/liboctave/numeric/sparse-base-chol.h Mon Sep 08 08:09:45 2014 +0200 +++ b/liboctave/numeric/sparse-base-chol.h Tue Sep 09 14:32:03 2014 +0200 @@ -37,31 +37,44 @@ { public: sparse_base_chol_rep (void) - : count (1), Lsparse (0), Common (), is_pd (false), minor_p (0), - perms (), cond (0) - { } + : count (1), Lsparse (0), Lfactor (0), Common (), + is_pd (false), minor_p (0), perms (), cond (0) + { + init_common (); + } sparse_base_chol_rep (const chol_type& a, bool natural, bool force) - : count (1), Lsparse (0), Common (), is_pd (false), minor_p (0), - perms (), cond (0) + : count (1), Lsparse (0), Lfactor (0), Common (), + is_pd (false), minor_p (0), perms (), cond (0) { + init_common (); init (a, natural, force); } sparse_base_chol_rep (const chol_type& a, octave_idx_type& info, bool natural, bool force) - : count (1), Lsparse (0), Common (), is_pd (false), minor_p (0), - perms (), cond (0) + : count (1), Lsparse (0), Lfactor (0), Common (), + is_pd (false), minor_p (0), perms (), cond (0) { + init_common (); info = init (a, natural, force); } ~sparse_base_chol_rep (void) { - if (is_pd) - CHOLMOD_NAME (free_sparse) (&Lsparse, &Common); + clear_factor (); + clear_sparse (); + + static char tmp[] = " "; + CHOLMOD_NAME (finish) (&Common); + CHOLMOD_NAME (print_common) (tmp, &Common); } + /* Convert Lfactor to Lsparse. This is used after manipulating + the factor (using up/downdates, row inserts and so on) is done + and before extracting the result. */ + void factor_to_sparse (bool natural); + cholmod_sparse * L (void) const { return Lsparse; } octave_idx_type P (void) const @@ -82,6 +95,7 @@ private: cholmod_sparse *Lsparse; + cholmod_factor *Lfactor; cholmod_common Common; @@ -93,10 +107,30 @@ double cond; + void init_common (); + octave_idx_type init (const chol_type& a, bool natural, bool force); void drop_zeros (const cholmod_sparse* S); + void clear_factor () + { + if (Lfactor) + { + CHOLMOD_NAME (free_factor) (&Lfactor, &Common); + Lfactor = 0; + } + } + + void clear_sparse () + { + if (Lsparse) + { + CHOLMOD_NAME (free_sparse) (&Lsparse, &Common); + Lsparse = 0; + } + } + // No copying! sparse_base_chol_rep (const sparse_base_chol_rep&); @@ -125,6 +159,8 @@ ~sparse_base_chol_rep (void) { } + void factor_to_sparse (bool) { } + octave_idx_type P (void) const { return 0; } ColumnVector perm (void) const { return perms + 1; } @@ -204,6 +240,8 @@ return *this; } + void factor_to_sparse (bool natural) { rep->factor_to_sparse (natural); } + chol_type L (void) const; chol_type R (void) const { return L ().hermitian (); }