26 #if defined (HAVE_CONFIG_H)
36 #include "builtin-defun-decls.h"
41 #if defined (HAVE_CXX_COMPLEX_SETTERS)
43 #elif defined (HAVE_CXX_COMPLEX_REFERENCE_ACCESSORS)
44 b.imag () = -b.imag ();
58 if (pivot.imag () != 0)
59 error (
"ichol: non-real pivot encountered. The matrix must be Hermitian.");
60 else if (pivot.real () < 0)
61 error (
"ichol: negative pivot encountered");
69 error (
"ichol: negative pivot encountered");
74 template <
typename octave_matrix_t,
typename T, T (*ichol_mult) (T, T),
75 bool (*ichol_checkpivot) (T)>
76 void ichol_0 (octave_matrix_t& sm,
const std::string michol =
"off")
79 octave_idx_type j1, jend, j2, jrow, jjrow, j, jw, i, k, jj,
r;
101 for (i = 0; i <
n; i++)
110 for (k = 0; k <
n; k++)
114 for (j = j1; j < j2; j++)
121 jjrow = Lfirst[jrow];
123 for (jj = jjrow; jj < jend; jj++)
127 tl = ichol_mult (data[jj], data[jjrow]);
140 if ((jjrow + 1) < jend)
145 Llist[j] = Llist[ridx[Lfirst[j]]];
146 Llist[ridx[Lfirst[j]]] = j;
153 data[j1] += dropsums[k];
156 if (j1 == j2 || ridx[j1] != k)
157 error (
"ichol: encountered a pivot equal to 0");
159 if (! ichol_checkpivot (data[j1]))
162 data[cidx[k]] = std::sqrt (data[j1]);
169 for (i = j1 + 1; i < j2; i++)
175 if ((Lfirst[k] + 1) < j2)
178 jjrow = ridx[Lfirst[k]];
179 Llist[k] = Llist[jjrow];
186 DEFUN (__ichol0__, args, ,
192 if (args.length () != 2)
195 std::string michol = args(1).string_value ();
200 if (! args(0).iscomplex ())
210 =
Ftril (args(0))(0).sparse_complex_matrix_value ();
217 template <
typename octave_matrix_t,
typename T, T (*ichol_mult) (T, T),
218 bool (*ichol_checkpivot) (T)>
219 void ichol_t (
const octave_matrix_t& sm, octave_matrix_t& L,
const T* cols_norm,
220 const T droptol,
const std::string michol =
"off")
236 T* data = sm.data ();
246 max_len += (0.1 * max_len) >
n ? 0.1 * max_len :
n;
259 std::vector<octave_idx_type> vec (
n, 0);
260 std::vector<bool> mark (
n,
false);
264 for (i = 0; i <
n; i++)
273 for (k = 0; k <
n; k++)
276 for (j = cidx[k]; j < cidx[k+1]; j++)
278 w_data[ridx[j]] = data[j];
281 mark[ridx[j]] =
true;
291 jjrow = Lfirst[jrow];
292 jend = cidx_l[jrow+1];
293 for (jj = jjrow; jj < jend; jj++)
305 w_data[j] -= ichol_mult (data_l[jj], data_l[jjrow]);
309 if ((jjrow + 1) < jend)
314 Llist[j] = Llist[ridx_l[Lfirst[j]]];
315 Llist[ridx_l[Lfirst[j]]] = j;
322 if ((max_len - total_len) <
n)
324 max_len += (0.1 * max_len) >
n ? 0.1 * max_len :
n;
336 std::sort (vec.begin (), vec.begin () + ind);
338 data_l[total_len] = w_data[k];
339 ridx_l[total_len] = k;
344 for (i = 0; i < ind ; i++)
347 if (w_data[jrow] != zero)
349 if (
std::abs (w_data[jrow]) < (droptol * cols_norm[k]))
353 col_drops[k] += w_data[jrow];
354 col_drops[jrow] += w_data[jrow];
359 data_l[total_len + w_len] = w_data[jrow];
360 ridx_l[total_len + w_len] = jrow;
372 data_l[total_len] += col_drops[k];
374 if (data_l[total_len] == zero)
375 error (
"ichol: encountered a pivot equal to 0");
377 if (! ichol_checkpivot (data_l[total_len]))
382 data_l[total_len] = std::sqrt (data_l[total_len]);
383 for (jj = total_len + 1; jj < (total_len + w_len); jj++)
384 data_l[jj] /= data_l[total_len];
389 error (
"ichol: integer overflow. Too many fill-in elements in L");
391 cidx_l[k+1] = cidx_l[k] - cidx_l[0] + w_len;
396 Lfirst[k] = cidx_l[k];
397 if ((Lfirst[k] + 1) < cidx_l[k+1])
400 jjrow = ridx_l[Lfirst[k]];
401 Llist[k] = Llist[jjrow];
408 L = octave_matrix_t (
n,
n, total_len);
410 for (i = 0; i <=
n; i++)
411 L.cidx (i) = cidx_l[i];
413 for (i = 0; i < total_len; i++)
415 L.ridx (i) = ridx_l[i];
416 L.data (i) = data_l[i];
420 DEFUN (__icholt__, args, ,
426 if (args.length () != 3)
429 double droptol = args(1).double_value ();
430 std::string michol = args(2).string_value ();
432 if (! args(0).iscomplex ())
446 =
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)
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
const T * fortran_vec(void) const
Size of the specified dimension.
Vector representing the dimensions (size) of an Array.
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,...)
std::complex< double > Complex
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
OCTAVE_API 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)