26 #if defined (HAVE_CONFIG_H)
45 #if defined (HAVE_CXX_COMPLEX_SETTERS)
47 #elif defined (HAVE_CXX_COMPLEX_REFERENCE_ACCESSORS)
48 b.imag () = -b.imag ();
64 if (fabs (pivot.imag ()) > std::numeric_limits<double>::epsilon())
65 error (
"ichol: non-real pivot encountered. The matrix must be Hermitian.");
66 else if (pivot.real () < 0)
67 error (
"ichol: negative pivot encountered");
76 error (
"ichol: negative pivot encountered");
81 template <
typename octave_matrix_t,
typename T, T (*ichol_mult) (T, T),
82 bool (*ichol_checkpivot) (T)>
84 ichol_0 (octave_matrix_t& sm,
const std::string michol =
"off")
87 octave_idx_type j1, jend, j2, jrow, jjrow, j, jw, i, k, jj,
r;
100 T *data = sm.data ();
109 for (i = 0; i <
n; i++)
118 for (k = 0; k <
n; k++)
122 for (j = j1; j < j2; j++)
129 jjrow = Lfirst[jrow];
131 for (jj = jjrow; jj < jend; jj++)
135 tl = ichol_mult (data[jj], data[jjrow]);
148 if ((jjrow + 1) < jend)
153 Llist[j] = Llist[ridx[Lfirst[j]]];
154 Llist[ridx[Lfirst[j]]] = j;
161 data[j1] += dropsums[k];
164 if (j1 == j2 || ridx[j1] != k)
165 error (
"ichol: encountered a pivot equal to 0");
167 if (! ichol_checkpivot (data[j1]))
170 data[cidx[k]] = std::sqrt (data[j1]);
177 for (i = j1 + 1; i < j2; i++)
183 if ((Lfirst[k] + 1) < j2)
186 jjrow = ridx[Lfirst[k]];
187 Llist[k] = Llist[jjrow];
194 DEFUN (__ichol0__, args, ,
200 if (args.length () != 2)
203 std::string michol = args(1).string_value ();
208 if (! args(0).iscomplex ())
218 =
Ftril (
ovl (args(0)))(0).sparse_complex_matrix_value ();
225 template <
typename octave_matrix_t,
typename T, T (*ichol_mult) (T, T),
226 bool (*ichol_checkpivot) (T)>
228 ichol_t (
const octave_matrix_t& sm, octave_matrix_t& L,
const T *cols_norm,
229 const T droptol,
const std::string michol =
"off")
245 T *data = sm.data ();
255 max_len += (0.1 * max_len) >
n ? 0.1 * max_len :
n;
268 std::vector<octave_idx_type> vec (
n, 0);
269 std::vector<bool> mark (
n,
false);
273 for (i = 0; i <
n; i++)
282 for (k = 0; k <
n; k++)
285 for (j = cidx[k]; j < cidx[k+1]; j++)
287 w_data[ridx[j]] = data[j];
290 mark[ridx[j]] =
true;
300 jjrow = Lfirst[jrow];
301 jend = cidx_l[jrow+1];
302 for (jj = jjrow; jj < jend; jj++)
314 w_data[j] -= ichol_mult (data_l[jj], data_l[jjrow]);
318 if ((jjrow + 1) < jend)
323 Llist[j] = Llist[ridx_l[Lfirst[j]]];
324 Llist[ridx_l[Lfirst[j]]] = j;
331 if ((max_len - total_len) <
n)
333 max_len += (0.1 * max_len) >
n ? 0.1 * max_len :
n;
345 std::sort (vec.begin (), vec.begin () + ind);
347 data_l[total_len] = w_data[k];
348 ridx_l[total_len] = k;
353 for (i = 0; i < ind ; i++)
356 if (w_data[jrow] != zero)
358 if (std::abs (w_data[jrow]) < (droptol * cols_norm[k]))
362 col_drops[k] += w_data[jrow];
363 col_drops[jrow] += w_data[jrow];
368 data_l[total_len + w_len] = w_data[jrow];
369 ridx_l[total_len + w_len] = jrow;
381 data_l[total_len] += col_drops[k];
383 if (data_l[total_len] == zero)
384 error (
"ichol: encountered a pivot equal to 0");
386 if (! ichol_checkpivot (data_l[total_len]))
391 data_l[total_len] = std::sqrt (data_l[total_len]);
392 for (jj = total_len + 1; jj < (total_len + w_len); jj++)
393 data_l[jj] /= data_l[total_len];
398 error (
"ichol: integer overflow. Too many fill-in elements in L");
400 cidx_l[k+1] = cidx_l[k] - cidx_l[0] + w_len;
405 Lfirst[k] = cidx_l[k];
406 if ((Lfirst[k] + 1) < cidx_l[k+1])
409 jjrow = ridx_l[Lfirst[k]];
410 Llist[k] = Llist[jjrow];
417 L = octave_matrix_t (
n,
n, total_len);
419 for (i = 0; i <=
n; i++)
420 L.cidx (i) = cidx_l[i];
422 for (i = 0; i < total_len; i++)
424 L.ridx (i) = ridx_l[i];
425 L.data (i) = data_l[i];
429 DEFUN (__icholt__, args, ,
435 if (args.length () != 3)
438 double droptol = args(1).double_value ();
439 std::string michol = args(2).string_value ();
441 if (! args(0).iscomplex ())
448 (sm_l, L, sm_col_norms.
fortran_vec (), droptol, michol);
456 =
Ftril (
ovl (args(0)))(0).sparse_complex_matrix_value ();
480 OCTAVE_END_NAMESPACE(
octave)
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)
octave_value_list Ftril(const octave_value_list &=octave_value_list(), int=0)
T * fortran_vec()
Size of the specified dimension.
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
Vector representing the dimensions (size) of an Array.
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#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)
RowVector xcolnorms(const Matrix &m, double p)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.