diff --git a/Makefile.am b/Makefile.am index e71a78e..ca045b9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -58,7 +58,6 @@ fortrandir = $(datadir)/$(PACKAGE_NAME)/fortran/ dist_fortran_DATA = $(qmckl_f) AM_CPPFLAGS = -I$(srcdir)/src -I$(srcdir)/include -# AM_FCFLAGS = -fno-underscoring lib_LTLIBRARIES = src/libqmckl.la src_libqmckl_la_SOURCES = $(qmckl_h) $(src_qmckl_f) $(C_FILES) $(F_FILES) $(H_PRIVATE_FUNC_FILES) $(H_PRIVATE_TYPE_FILES) $(header_tests) diff --git a/org/qmckl_sherman_morrison_woodbury.org b/org/qmckl_sherman_morrison_woodbury.org index 8ce4822..dc573fd 100644 --- a/org/qmckl_sherman_morrison_woodbury.org +++ b/org/qmckl_sherman_morrison_woodbury.org @@ -25,8 +25,7 @@ int main() { qmckl_exit_code rc; #+end_src - - + * Naïve Sherman-Morrison ** ~qmckl_sherman_morrison~ @@ -36,7 +35,6 @@ int main() { :FRetType: qmckl_exit_code :END: - This is the simplest of the available Sherman-Morrison-Woodbury kernels. It applies rank-1 updates one by one in the order that is given. It only checks if the denominator in the Sherman-Morrison formula is not too close to zero when an update is evaluated. It will exit with an error code of the denominator is too close to zero. @@ -97,28 +95,11 @@ int main() { double* Slater_inv ); #+end_src -*** Source Fortran - - #+begin_src f90 :tangle (eval f) -integer function qmckl_sherman_morrison_f(context, Dim, N_updates, & - Updates, Updates_index, breakdown, Slater_inv) result(info) - use qmckl - implicit none - integer(qmckl_context) , intent(in) :: context - integer*8 , intent(in), value :: Dim, N_updates - integer*8 , intent(in) :: Updates_index(N_updates) - real*8 , intent(in) :: Updates(N_updates*Dim) - real*8 , intent(in) :: breakdown - real*8 , intent(inout) :: Slater_inv(Dim*Dim) - !logical, external :: qmckl_sherman_morrison_f - info = qmckl_sherman_morrison(context, Dim, N_updates, Updates, Updates_index, breakdown, Slater_inv) -end function qmckl_sherman_morrison_f - #+end_src - -*** Source C +*** Source #+begin_src c :tangle (eval c) :comments org #include +#include #include "qmckl.h" qmckl_exit_code qmckl_sherman_morrison_c(const qmckl_context context, @@ -171,7 +152,6 @@ qmckl_exit_code qmckl_sherman_morrison_c(const qmckl_context context, return QMCKL_SUCCESS; } - #+end_src *** Performance @@ -184,54 +164,8 @@ qmckl_exit_code qmckl_sherman_morrison_c(const qmckl_context context, #+CALL: generate_c_interface(table=qmckl_sherman_morrison_args,rettyp=get_value("FRetType"),fname=get_value("Name")) - #+RESULTS: - #+begin_src f90 :tangle (eval f) :comments org :exports none - integer(c_int32_t) function qmckl_sherman_morrison & - (context, Dim, N_updates, Updates, Updates_index, breakdown, Slater_inv) & - bind(C) result(info) - - use, intrinsic :: iso_c_binding - implicit none - - integer (c_int64_t) , intent(in) , value :: context - integer (c_int64_t) , intent(in) , value :: Dim - integer (c_int64_t) , intent(in) , value :: N_updates - real (c_double ) , intent(in) :: Updates(N_updates*Dim) - integer (c_int64_t) , intent(in) :: Updates_index(N_updates) - real (c_double ) , intent(in) :: breakdown - real (c_double ) , intent(inout) :: Slater_inv(Dim*Dim) - - integer(c_int32_t), external :: qmckl_sherman_morrison_c - info = qmckl_sherman_morrison_c & - (context, Dim, N_updates, Updates, Updates_index, breakdown, Slater_inv) - - end function qmckl_sherman_morrison - #+end_src - #+CALL: generate_f_interface(table=qmckl_sherman_morrison_args,rettyp=get_value("FRetType"),fname=get_value("Name")) - #+RESULTS: - #+begin_src f90 :tangle (eval fh_func) :comments org :exports none - interface - integer(c_int32_t) function qmckl_sherman_morrison & - (context, Dim, N_updates, Updates, Updates_index, breakdown, Slater_inv) & - bind(C) - use, intrinsic :: iso_c_binding - import - implicit none - - integer (c_int64_t) , intent(in) , value :: context - integer (c_int64_t) , intent(in) , value :: Dim - integer (c_int64_t) , intent(in) , value :: N_updates - real (c_double ) , intent(in) :: Updates(N_updates*Dim) - integer (c_int64_t) , intent(in) :: Updates_index(N_updates) - real (c_double ) , intent(in) :: breakdown - real (c_double ) , intent(inout) :: Slater_inv(Dim*Dim) - - end function qmckl_sherman_morrison - end interface - #+end_src - *** Test :noexport: The tests for the kernels are executed on datasets that are extracted from a run of QMC=Chem on Benzene (21 spin-up/21 spin down electrons) using 329 unique alpha determinants. The tests are run such that the kernels reject the computed inverse whenever the computed intermediate determinants or denominators are smaller than 1e-3. This is the default value in QMC=Chem. The tests will return QMCKL_SUCCESS whenever all the elements of the final matrix $R=S.S^-1 - 1$ are smaller than the given tolerance value of 1e-3, and will return QMCKL_FAILURE if the values are larger than this tolerance value. @@ -297,7 +231,6 @@ for (unsigned int i = 0; i < Dim; i++) { assert(rc == QMCKL_SUCCESS); #+end_src - * Woodbury 2x2 ** ~qmckl_woodbury_2~ @@ -353,28 +286,11 @@ assert(rc == QMCKL_SUCCESS); double* Slater_inv ); #+end_src -*** Source Fortran - - #+begin_src f90 :tangle (eval f) -integer function qmckl_woodbury_2_f(context, Dim, & - Updates, Updates_index, breakdown, Slater_inv) result(info) - use qmckl - implicit none - integer(qmckl_context) , intent(in) :: context - integer*8 , intent(in), value :: Dim - integer*8 , intent(in) :: Updates_index(2) - real*8 , intent(in) :: Updates(2*Dim) - real*8 , intent(in) :: breakdown - real*8 , intent(inout) :: Slater_inv(Dim*Dim) - !logical, external :: qmckl_woodbury_2_f - info = qmckl_woodbury_2(context, Dim, Updates, Updates_index, breakdown, Slater_inv) -end function qmckl_woodbury_2_f - #+end_src - -*** Source C +*** Source #+begin_src c :tangle (eval c) :comments org #include +#include #include "qmckl.h" qmckl_exit_code qmckl_woodbury_2_c(const qmckl_context context, @@ -387,7 +303,7 @@ qmckl_exit_code qmckl_woodbury_2_c(const qmckl_context context, C := S^{-1} * U, dim x 2 B := 1 + V * C, 2 x 2 D := V * S^{-1}, 2 x dim -*/ +,*/ // #ifdef DEBUG // Leave commented out since debugging information is not yet implemented in QMCkl. // std::cerr << "Called Woodbury 2x2 kernel" << std::endl; // #endif @@ -445,64 +361,19 @@ qmckl_exit_code qmckl_woodbury_2_c(const qmckl_context context, return QMCKL_SUCCESS; } - #+end_src *** Performance This function is most efficient when used in cases where there are only 2 rank-1 updates and it is sure they will not result in a singular matrix. - + ** C interface :noexport: #+CALL: generate_c_interface(table=qmckl_woodbury_2_args,rettyp=get_value("FRetType"),fname=get_value("Name")) - #+RESULTS: - #+begin_src f90 :tangle (eval f) :comments org :exports none - integer(c_int32_t) function qmckl_woodbury_2 & - (context, Dim, Updates, Updates_index, breakdown, Slater_inv) & - bind(C) result(info) - - use, intrinsic :: iso_c_binding - implicit none - - integer (c_int64_t) , intent(in) , value :: context - integer (c_int64_t) , intent(in) , value :: Dim - real (c_double ) , intent(in) :: Updates(2*Dim) - integer (c_int64_t) , intent(in) :: Updates_index(2) - real (c_double ) , intent(in) :: breakdown - real (c_double ) , intent(inout) :: Slater_inv(Dim*Dim) - - integer(c_int32_t), external :: qmckl_woodbury_2_c - info = qmckl_woodbury_2_c & - (context, Dim, Updates, Updates_index, breakdown, Slater_inv) - - end function qmckl_woodbury_2 - #+end_src - #+CALL: generate_f_interface(table=qmckl_woodbury_2_args,rettyp=get_value("FRetType"),fname=get_value("Name")) - #+RESULTS: - #+begin_src f90 :tangle (eval fh_func) :comments org :exports none - interface - integer(c_int32_t) function qmckl_woodbury_2 & - (context, Dim, Updates, Updates_index, breakdown, Slater_inv) & - bind(C) - use, intrinsic :: iso_c_binding - import - implicit none - - integer (c_int64_t) , intent(in) , value :: context - integer (c_int64_t) , intent(in) , value :: Dim - real (c_double ) , intent(in) :: Updates(2*Dim) - integer (c_int64_t) , intent(in) :: Updates_index(2) - real (c_double ) , intent(in) :: breakdown - real (c_double ) , intent(inout) :: Slater_inv(Dim*Dim) - - end function qmckl_woodbury_2 - end interface - #+end_src - *** Test :noexport: #+begin_src c :tangle (eval c_test) @@ -529,7 +400,6 @@ for (unsigned int i = 0; i < Dim; i++) { assert(rc == QMCKL_SUCCESS); #+end_src - * Woodbury 3x3 ** ~qmckl_woodbury_3~ @@ -579,28 +449,11 @@ assert(rc == QMCKL_SUCCESS); double* Slater_inv ); #+end_src -*** Source Fortran - - #+begin_src f90 :tangle (eval f) -integer function qmckl_woodbury_3_f(context, Dim, & - Updates, Updates_index, breakdown, Slater_inv) result(info) - use qmckl - implicit none - integer(qmckl_context) , intent(in) :: context - integer*8 , intent(in), value :: Dim - integer*8 , intent(in) :: Updates_index(3) - real*8 , intent(in) :: Updates(3*Dim) - real*8 , intent(in) :: breakdown - real*8 , intent(inout) :: Slater_inv(Dim*Dim) - !logical, external :: qmckl_woodbury_3_f - info = qmckl_woodbury_3(context, Dim, Updates, Updates_index, breakdown, Slater_inv) -end function qmckl_woodbury_3_f - #+end_src - -*** Source C +*** Source #+begin_src c :tangle (eval c) :comments org #include +#include #include "qmckl.h" qmckl_exit_code qmckl_woodbury_3_c(const qmckl_context context, @@ -698,52 +551,8 @@ qmckl_exit_code qmckl_woodbury_3_c(const qmckl_context context, #+CALL: generate_c_interface(table=qmckl_woodbury_3_args,rettyp=get_value("FRetType"),fname=get_value("Name")) - #+RESULTS: - #+begin_src f90 :tangle (eval f) :comments org :exports none - integer(c_int32_t) function qmckl_woodbury_3 & - (context, Dim, Updates, Updates_index, breakdown, Slater_inv) & - bind(C) result(info) - - use, intrinsic :: iso_c_binding - implicit none - - integer (c_int64_t) , intent(in) , value :: context - integer (c_int64_t) , intent(in) , value :: Dim - real (c_double ) , intent(in) :: Updates(3*Dim) - integer (c_int64_t) , intent(in) :: Updates_index(3) - real (c_double ) , intent(in) , value :: breakdown - real (c_double ) , intent(inout) :: Slater_inv(Dim*Dim) - - integer(c_int32_t), external :: qmckl_woodbury_3_c - info = qmckl_woodbury_3_c & - (context, Dim, Updates, Updates_index, breakdown, Slater_inv) - - end function qmckl_woodbury_3 - #+end_src - #+CALL: generate_f_interface(table=qmckl_woodbury_3_args,rettyp=get_value("FRetType"),fname=get_value("Name")) - #+RESULTS: - #+begin_src f90 :tangle (eval fh_func) :comments org :exports none - interface - integer(c_int32_t) function qmckl_woodbury_3 & - (context, Dim, Updates, Updates_index, breakdown, Slater_inv) & - bind(C) - use, intrinsic :: iso_c_binding - import - implicit none - - integer (c_int64_t) , intent(in) , value :: context - integer (c_int64_t) , intent(in) , value :: Dim - real (c_double ) , intent(in) :: Updates(3*Dim) - integer (c_int64_t) , intent(in) :: Updates_index(3) - real (c_double ) , intent(in) , value :: breakdown - real (c_double ) , intent(inout) :: Slater_inv(Dim*Dim) - - end function qmckl_woodbury_3 - end interface - #+end_src - *** Test :noexport: #+begin_src c :tangle (eval c_test) @@ -770,7 +579,6 @@ for (unsigned int i = 0; i < Dim; i++) { assert(rc == QMCKL_SUCCESS); #+end_src - * Sherman-Morrison with update splitting ** ~qmckl_sherman_morrison_splitting~ @@ -826,24 +634,7 @@ assert(rc == QMCKL_SUCCESS); double* Slater_inv ); #+end_src -*** Source Fortran - - #+begin_src f90 :tangle (eval f) -integer function qmckl_sherman_morrison_splitting_f(context, Dim, N_updates, & - Updates, Updates_index, breakdown, Slater_inv) result(info) - use qmckl - implicit none - integer(qmckl_context) , intent(in) :: context - integer*8 , intent(in), value :: Dim, N_updates - integer*8 , intent(in) :: Updates_index(N_updates) - real*8 , intent(in) :: Updates(N_updates*Dim) - real*8 , intent(in) :: breakdown - real*8 , intent(inout) :: Slater_inv(Dim*Dim) - info = qmckl_sherman_morrison_splitting(context, Dim, N_updates, Updates, Updates_index, breakdown, Slater_inv) -end function qmckl_sherman_morrison_splitting_f - #+end_src - -*** Source C +*** Source #+begin_src c :tangle (eval c) :comments org #include @@ -860,17 +651,15 @@ qmckl_exit_code qmckl_sherman_morrison_splitting_c(const qmckl_context context, // std::cerr << "Called qmckl_sherman_morrison_splitting with " << N_updates << " updates" << std::endl; // #endif - qmckl_exit_code rc; - double later_updates[Dim * N_updates]; uint64_t later_index[N_updates]; uint64_t later = 0; - rc = qmckl_slagel_splitting_c(Dim, N_updates, Updates, Updates_index, + (void) qmckl_slagel_splitting_c(Dim, N_updates, Updates, Updates_index, breakdown, Slater_inv, later_updates, later_index, &later); if (later > 0) { - rc = qmckl_sherman_morrison_splitting_c(context, Dim, later, + (void) qmckl_sherman_morrison_splitting_c(context, Dim, later, later_updates, later_index, breakdown, Slater_inv); } @@ -887,55 +676,8 @@ qmckl_exit_code qmckl_sherman_morrison_splitting_c(const qmckl_context context, #+CALL: generate_c_interface(table=qmckl_sherman_morrison_splitting_args,rettyp=get_value("FRetType"),fname=get_value("Name")) - #+RESULTS: - #+begin_src f90 :tangle (eval f) :comments org :exports none - integer(c_int32_t) function qmckl_sherman_morrison_splitting & - (context, Dim, N_updates, Updates, Updates_index, breakdown, Slater_inv) & - bind(C) result(info) - - use, intrinsic :: iso_c_binding - implicit none - - integer (c_int64_t) , intent(in) , value :: context - integer (c_int64_t) , intent(in) , value :: Dim - integer (c_int64_t) , intent(in) , value :: N_updates - real (c_double ) , intent(in) :: Updates(N_updates*Dim) - integer (c_int64_t) , intent(in) :: Updates_index(N_updates) - real (c_double ) , intent(in) , value :: breakdown - real (c_double ) , intent(inout) :: Slater_inv(Dim*Dim) - - integer(c_int32_t), external :: qmckl_sherman_morrison_splitting_c - info = qmckl_sherman_morrison_splitting_c & - (context, Dim, N_updates, Updates, Updates_index, breakdown, Slater_inv) - - end function qmckl_sherman_morrison_splitting - #+end_src - #+CALL: generate_f_interface(table=qmckl_sherman_morrison_splitting_args,rettyp=get_value("FRetType"),fname=get_value("Name")) - #+RESULTS: - #+begin_src f90 :tangle (eval fh_func) :comments org :exports none - interface - integer(c_int32_t) function qmckl_sherman_morrison_splitting & - (context, Dim, N_updates, Updates, Updates_index, breakdown, Slater_inv) & - bind(C) - use, intrinsic :: iso_c_binding - import - implicit none - - integer (c_int64_t) , intent(in) , value :: context - integer (c_int64_t) , intent(in) , value :: Dim - integer (c_int64_t) , intent(in) , value :: N_updates - real (c_double ) , intent(in) :: Updates(N_updates*Dim) - integer (c_int64_t) , intent(in) :: Updates_index(N_updates) - real (c_double ) , intent(in) , value :: breakdown - real (c_double ) , intent(inout) :: Slater_inv(Dim*Dim) - - end function qmckl_sherman_morrison_splitting - end interface - #+end_src - - *** Test :noexport: #+begin_src c :tangle (eval c_test) @@ -962,7 +704,6 @@ for (unsigned int i = 0; i < Dim; i++) { assert(rc == QMCKL_SUCCESS); #+end_src - * Woodbury 3x3 and 2x2 with Sherman-Morrison and update splitting ** ~qmckl_sherman_morrison_smw32s~ @@ -1013,24 +754,7 @@ assert(rc == QMCKL_SUCCESS); double* Slater_inv ); #+end_src -*** Source Fortran - - #+begin_src f90 :tangle (eval f) -integer function qmckl_sherman_morrison_smw32s_f(context, Slater_inv, Dim, N_updates, & - Updates, Updates_index) result(info) - use qmckl - implicit none - integer(qmckl_context) , intent(in) :: context - integer*8 , intent(in), value :: Dim, N_updates - integer*8 , intent(in) :: Updates_index(N_updates) - real*8 , intent(in) :: Updates(N_updates*Dim) - real*8 , intent(inout) :: Slater_inv(Dim*Dim) - !logical, external :: qmckl_sherman_morrison_f - info = qmckl_sherman_morrison_smw32s(context, Dim, N_updates, Updates, Updates_index, Slater_inv) -end function qmckl_sherman_morrison_smw32s_f - #+end_src - -*** Source C +*** Source #+begin_src c :tangle (eval c) :comments org #include @@ -1079,7 +803,7 @@ qmckl_exit_code qmckl_sherman_morrison_smw32s_c(const qmckl_context context, rc = qmckl_woodbury_2_c(context, Dim, Updates_2block, Updates_index_2block, breakdown, Slater_inv); if (rc != 0) { // Send the entire block to slagel_splitting uint64_t l = 0; - rc = qmckl_slagel_splitting_c(Dim, 2, Updates_2block, Updates_index_2block, + (void) qmckl_slagel_splitting_c(Dim, 2, Updates_2block, Updates_index_2block, breakdown, Slater_inv, later_updates + (Dim * later), later_index + later, &l); later = later + l; } @@ -1088,13 +812,13 @@ qmckl_exit_code qmckl_sherman_morrison_smw32s_c(const qmckl_context context, const double *Updates_1block = &Updates[n_of_3blocks * length_3block]; const uint64_t *Updates_index_1block = &Updates_index[3 * n_of_3blocks]; uint64_t l = 0; - rc = qmckl_slagel_splitting_c(Dim, 1, Updates_1block, Updates_index_1block, + (void) qmckl_slagel_splitting_c(Dim, 1, Updates_1block, Updates_index_1block, breakdown, Slater_inv, later_updates + (Dim * later), later_index + later, &l); later = later + l; } if (later > 0) { - rc = qmckl_sherman_morrison_splitting_c(context, Dim, later, later_updates, later_index, breakdown, Slater_inv); + (void) qmckl_sherman_morrison_splitting_c(context, Dim, later, later_updates, later_index, breakdown, Slater_inv); } return QMCKL_SUCCESS; } @@ -1109,52 +833,8 @@ qmckl_exit_code qmckl_sherman_morrison_smw32s_c(const qmckl_context context, #+CALL: generate_c_interface(table=qmckl_sherman_morrison_smw32s_args,rettyp=get_value("FRetType"),fname=get_value("Name")) - #+RESULTS: - #+begin_src f90 :tangle (eval f) :comments org :exports none - integer(c_int32_t) function qmckl_sherman_morrison_smw32s & - (context, Dim, N_updates, Updates, Updates_index, Slater_inv) & - bind(C) result(info) - - use, intrinsic :: iso_c_binding - implicit none - - integer (c_int64_t) , intent(in) , value :: context - integer (c_int64_t) , intent(in) , value :: Dim - integer (c_int64_t) , intent(in) , value :: N_updates - real (c_double ) , intent(in) :: Updates(N_updates*Dim) - integer (c_int64_t) , intent(in) :: Updates_index(N_updates) - real (c_double ) , intent(inout) :: Slater_inv(Dim*Dim) - - integer(c_int32_t), external :: qmckl_sherman_morrison_smw32s_c - info = qmckl_sherman_morrison_smw32s_c & - (context, Dim, N_updates, Updates, Updates_index, Slater_inv) - - end function qmckl_sherman_morrison_smw32s - #+end_src - #+CALL: generate_f_interface(table=qmckl_sherman_morrison_smw32s_args,rettyp=get_value("FRetType"),fname=get_value("Name")) - #+RESULTS: - #+begin_src f90 :tangle (eval fh_func) :comments org :exports none - interface - integer(c_int32_t) function qmckl_sherman_morrison_smw32s & - (context, Dim, N_updates, Updates, Updates_index, Slater_inv) & - bind(C) - use, intrinsic :: iso_c_binding - import - implicit none - - integer (c_int64_t) , intent(in) , value :: context - integer (c_int64_t) , intent(in) , value :: Dim - integer (c_int64_t) , intent(in) , value :: N_updates - real (c_double ) , intent(in) :: Updates(N_updates*Dim) - integer (c_int64_t) , intent(in) :: Updates_index(N_updates) - real (c_double ) , intent(inout) :: Slater_inv(Dim*Dim) - - end function qmckl_sherman_morrison_smw32s - end interface - #+end_src - *** Test :noexport: #+begin_src c :tangle (eval c_test) @@ -1181,7 +861,6 @@ for (unsigned int i = 0; i < Dim; i++) { assert(rc == QMCKL_SUCCESS); #+end_src - * Helper Functions Private helper-functions that are used by the Sherman-Morrison-Woodbury kernels. @@ -1245,9 +924,7 @@ These functions can only be used internally by the kernels in this module. uint64_t* later ); #+end_src -*** Source Fortran - -*** Source C +*** Source #+begin_src c :tangle (eval c) :comments org #include @@ -1322,42 +999,14 @@ qmckl_exit_code qmckl_slagel_splitting_c(uint64_t Dim, This function cannot be used by itself and is used in Sherman-Morrison with update splitting and Woodbury 3x3 and 2x2 with Sherman-Morrison and update splitting. Please look at the performance reccomendations for those two kernels. - ** C interface :noexport: #+CALL: generate_c_interface(table=qmckl_slagel_splitting_args,rettyp=get_value("FRetType"),fname=get_value("Name")) - - #+RESULTS: - #+begin_src f90 :tangle (eval f) :comments org :exports none - integer(c_int32_t) function qmckl_slagel_splitting & - (Dim, N_updates, Updates, Updates_index, breakdown, Slater_inv, later_updates, later_index, later) & - bind(C) result(info) - - use, intrinsic :: iso_c_binding - implicit none - - integer (c_int64_t) , intent(in) , value :: Dim - integer (c_int64_t) , intent(in) , value :: N_updates - real (c_double ) , intent(in) :: Updates(N_updates*Dim) - integer (c_int64_t) , intent(in) :: Updates_index(N_updates) - real (c_double ) , intent(in) , value :: breakdown - real (c_double ) , intent(inout) :: Slater_inv(Dim*Dim) - real (c_double ) , intent(inout) :: later_updates(Dim * N_updates) - integer (c_int64_t) , intent(inout) :: later_index(N_updates) - integer (c_int64_t) , intent(inout) :: later - - integer(c_int32_t), external :: qmckl_slagel_splitting_c - info = qmckl_slagel_splitting_c & - (Dim, N_updates, Updates, Updates_index, breakdown, Slater_inv, later_updates, later_index, later) - - end function qmckl_slagel_splitting - #+end_src - + *** Test :noexport: This kernel does not have an explicit test because it is only used internally by higher-level Sherman-Morrison-Woodbury kernels. - * End of files #+begin_src c :comments link :tangle (eval c_test) @@ -1367,6 +1016,5 @@ with Sherman-Morrison and update splitting. Please look at the performance recco #+end_src - # -*- mode: org -*- # vim: syntax=c