26 #if defined (HAVE_CONFIG_H)
36 #include "builtin-defun-decls.h"
43 #if defined (HAVE_CXX_COMPLEX_SETTERS)
45 #elif defined (HAVE_CXX_COMPLEX_REFERENCE_ACCESSORS)
46 b.imag () = -b.imag ();
60 if (pivot.imag () != 0)
61 error (
"ichol: non-real pivot encountered. The matrix must be Hermitian.");
62 else if (pivot.real () < 0)
63 error (
"ichol: negative pivot encountered");
71 error (
"ichol: negative pivot encountered");
76 template <
typename octave_matrix_t,
typename T, T (*ichol_mult) (T, T),
77 bool (*ichol_checkpivot) (T)>
78 void ichol_0 (octave_matrix_t& sm,
const std::string michol =
"off")
81 octave_idx_type j1, jend, j2, jrow, jjrow, j, jw, i, k, jj,
r;
103 for (i = 0; i <
n; i++)
112 for (k = 0; k <
n; k++)
116 for (j = j1; j < j2; j++)
123 jjrow = Lfirst[jrow];
125 for (jj = jjrow; jj < jend; jj++)
129 tl = ichol_mult (data[jj], data[jjrow]);
142 if ((jjrow + 1) < jend)
147 Llist[j] = Llist[ridx[Lfirst[j]]];
148 Llist[ridx[Lfirst[j]]] = j;
155 data[j1] += dropsums[k];
158 if (j1 == j2 || ridx[j1] != k)
159 error (
"ichol: encountered a pivot equal to 0");
161 if (! ichol_checkpivot (data[j1]))
164 data[cidx[k]] = std::sqrt (data[j1]);
171 for (i = j1 + 1; i < j2; i++)
177 if ((Lfirst[k] + 1) < j2)
180 jjrow = ridx[Lfirst[k]];
181 Llist[k] = Llist[jjrow];
188 DEFUN (__ichol0__, args, ,
194 if (args.length () != 2)
197 std::string michol = args(1).string_value ();
202 if (! args(0).iscomplex ())
212 =
Ftril (args(0))(0).sparse_complex_matrix_value ();
219 template <
typename octave_matrix_t,
typename T, T (*ichol_mult) (T, T),
220 bool (*ichol_checkpivot) (T)>
221 void ichol_t (
const octave_matrix_t& sm, octave_matrix_t& L,
const T *cols_norm,
222 const T droptol,
const std::string michol =
"off")
238 T *data = sm.data ();
248 max_len += (0.1 * max_len) >
n ? 0.1 * max_len :
n;
261 std::vector<octave_idx_type> vec (
n, 0);
262 std::vector<bool> mark (
n,
false);
266 for (i = 0; i <
n; i++)
275 for (k = 0; k <
n; k++)
278 for (j = cidx[k]; j < cidx[k+1]; j++)
280 w_data[ridx[j]] = data[j];
283 mark[ridx[j]] =
true;
293 jjrow = Lfirst[jrow];
294 jend = cidx_l[jrow+1];
295 for (jj = jjrow; jj < jend; jj++)
307 w_data[j] -= ichol_mult (data_l[jj], data_l[jjrow]);
311 if ((jjrow + 1) < jend)
316 Llist[j] = Llist[ridx_l[Lfirst[j]]];
317 Llist[ridx_l[Lfirst[j]]] = j;
324 if ((max_len - total_len) <
n)
326 max_len += (0.1 * max_len) >
n ? 0.1 * max_len :
n;
338 std::sort (vec.begin (), vec.begin () + ind);
340 data_l[total_len] = w_data[k];
341 ridx_l[total_len] = k;
346 for (i = 0; i < ind ; i++)
349 if (w_data[jrow] != zero)
351 if (
std::abs (w_data[jrow]) < (droptol * cols_norm[k]))
355 col_drops[k] += w_data[jrow];
356 col_drops[jrow] += w_data[jrow];
361 data_l[total_len + w_len] = w_data[jrow];
362 ridx_l[total_len + w_len] = jrow;
374 data_l[total_len] += col_drops[k];
376 if (data_l[total_len] == zero)
377 error (
"ichol: encountered a pivot equal to 0");
379 if (! ichol_checkpivot (data_l[total_len]))
384 data_l[total_len] = std::sqrt (data_l[total_len]);
385 for (jj = total_len + 1; jj < (total_len + w_len); jj++)
386 data_l[jj] /= data_l[total_len];
391 error (
"ichol: integer overflow. Too many fill-in elements in L");
393 cidx_l[k+1] = cidx_l[k] - cidx_l[0] + w_len;
398 Lfirst[k] = cidx_l[k];
399 if ((Lfirst[k] + 1) < cidx_l[k+1])
402 jjrow = ridx_l[Lfirst[k]];
403 Llist[k] = Llist[jjrow];
410 L = octave_matrix_t (
n,
n, total_len);
412 for (i = 0; i <=
n; i++)
413 L.cidx (i) = cidx_l[i];
415 for (i = 0; i < total_len; i++)
417 L.ridx (i) = ridx_l[i];
418 L.data (i) = data_l[i];
422 DEFUN (__icholt__, args, ,
428 if (args.length () != 3)
431 double droptol = args(1).double_value ();
432 std::string michol = args(2).string_value ();
434 if (! args(0).iscomplex ())
441 (sm_l, L, sm_col_norms.
fortran_vec (), droptol, michol);
449 =
Ftril (args(0))(0).sparse_complex_matrix_value ();
bool ichol_checkpivot_complex(Complex pivot)
bool ichol_checkpivot_real(double pivot)
double ichol_mult_real(double a, double b)
void ichol_t(const octave_matrix_t &sm, octave_matrix_t &L, const T *cols_norm, const T droptol, const std::string michol="off")
void ichol_0(octave_matrix_t &sm, const std::string michol="off")
Complex ichol_mult_complex(Complex a, Complex b)
OCTARRAY_API void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
OCTARRAY_API T * fortran_vec(void)
Size of the specified dimension.
Vector representing the dimensions (size) of an Array.
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
OCTINTERP_API void print_usage(void)
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void error(const char *fmt,...)
class OCTAVE_API SparseMatrix
class OCTAVE_API SparseComplexMatrix
std::complex< double > Complex
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
RowVector xcolnorms(const Matrix &m, double p)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
OCTAVE_EXPORT octave_value_list Ftril(const octave_value_list &args, int)