47 template <
class CHOLT>
55 template <
class CHOLT>
65 @deftypefn {Loadable Function} {@var{R} =} chol (@var{A})\n\
66 @deftypefnx {Loadable Function} {[@var{R}, @var{p}] =} chol (@var{A})\n\
67 @deftypefnx {Loadable Function} {[@var{R}, @var{p}, @var{Q}] =} chol (@var{S})\n\
68 @deftypefnx {Loadable Function} {[@var{R}, @var{p}, @var{Q}] =} chol (@var{S}, \"vector\")\n\
69 @deftypefnx {Loadable Function} {[@var{L}, @dots{}] =} chol (@dots{}, \"lower\")\n\
70 @deftypefnx {Loadable Function} {[@var{L}, @dots{}] =} chol (@dots{}, \"upper\")\n\
71 @cindex Cholesky factorization\n\
72 Compute the Cholesky@tie{}factor, @var{R}, of the symmetric positive definite\n\
75 The Cholesky@tie{}factor is defined by\n\
82 @var{R}' * @var{R} = @var{A}.\n\
87 Called with one output argument @code{chol} fails if @var{A} or @var{S} is\n\
88 not positive definite. With two or more output arguments @var{p} flags\n\
89 whether the matrix was positive definite and @code{chol} does not fail. A\n\
90 zero value indicated that the matrix was positive definite and the @var{R}\n\
91 gives the factorization, and @var{p} will have a positive value otherwise.\n\
93 If called with 3 outputs then a sparsity preserving row/column permutation\n\
94 is applied to @var{A} prior to the factorization. That is @var{R} is the\n\
95 factorization of @code{@var{A}(@var{Q},@var{Q})} such that\n\
97 $ R^T R = Q^T A Q$.\n\
102 @var{R}' * @var{R} = @var{Q}' * @var{A} * @var{Q}.\n\
107 The sparsity preserving permutation is generally returned as a matrix.\n\
108 However, given the flag @qcode{\"vector\"}, @var{Q} will be returned as a\n\
111 $ R^T R = A (Q, Q)$.\n\
116 @var{R}' * @var{R} = @var{A}(@var{Q}, @var{Q}).\n\
121 Called with either a sparse or full matrix and using the @qcode{\"lower\"}\n\
122 flag, @code{chol} returns the lower triangular factorization such that\n\
129 @var{L} * @var{L}' = @var{A}.\n\
134 For full matrices, if the @qcode{\"lower\"} flag is set only the lower\n\
135 triangular part of the matrix is used for the factorization, otherwise the\n\
136 upper triangular part is used.\n\
138 In general the lower triangular factorization is significantly faster for\n\
140 @seealso{hess, lu, qr, qz, schur, svd, ichol, cholinv, chol2inv, cholupdate, cholinsert, choldelete, cholshift}\n\
144 int nargin = args.
length ();
148 if (nargin < 1 || nargin > 3 || nargout > 3
149 || (! args(0).is_sparse_type () && nargout > 2))
158 std::string tmp = args(n++).string_value ();
162 if (tmp.compare (
"vector") == 0)
164 else if (tmp.compare (
"lower") == 0)
170 else if (tmp.compare (
"upper") == 0)
173 error (
"chol: unexpected second or third input");
176 error (
"chol: expecting trailing string arguments");
186 int arg_is_empty =
empty_arg (
"chol", nr, nc);
188 if (arg_is_empty < 0)
190 if (arg_is_empty > 0)
196 bool natural = (nargout != 3);
197 bool force = nargout > 1;
210 retval(2) = fact.
perm ();
212 retval(2) = fact.
Q ();
215 if (nargout > 1 || info == 0)
219 retval(0) = fact.
L ();
221 retval(0) = fact.
R ();
224 error (
"chol: input matrix must be positive definite");
238 retval(2) = fact.
perm ();
240 retval(2) = fact.
Q ();
243 if (nargout > 1 || info == 0)
247 retval(0) = fact.
L ();
249 retval(0) = fact.
R ();
252 error (
"chol: input matrix must be positive definite");
274 if (nargout == 2 || info == 0)
283 error (
"chol: input matrix must be positive definite");
300 if (nargout == 2 || info == 0)
309 error (
"chol: input matrix must be positive definite");
329 fact =
CHOL (m, info);
331 if (nargout == 2 || info == 0)
340 error (
"chol: input matrix must be positive definite");
357 if (nargout == 2 || info == 0)
366 error (
"chol: input matrix must be positive definite");
394 @deftypefn {Loadable Function} {} cholinv (@var{A})\n\
395 Compute the inverse of the symmetric positive definite matrix @var{A} using\n\
396 the Cholesky@tie{}factorization.\n\
397 @seealso{chol, chol2inv, inv}\n\
402 int nargin = args.
length ();
411 if (nr == 0 || nc == 0)
430 error (
"cholinv: A must be positive definite");
444 error (
"cholinv: A must be positive definite");
463 error (
"cholinv: A must be positive definite");
477 error (
"cholinv: A must be positive definite");
496 error (
"cholinv: A must be positive definite");
510 error (
"cholinv: A must be positive definite");
541 @deftypefn {Loadable Function} {} chol2inv (@var{U})\n\
542 Invert a symmetric, positive definite square matrix from its Cholesky\n\
543 decomposition, @var{U}.\n\
545 Note that @var{U} should be an upper-triangular matrix with positive\n\
546 diagonal elements. @code{chol2inv (@var{U})} provides\n\
547 @code{inv (@var{U}'*@var{U})} but it is much faster than using @code{inv}.\n\
548 @seealso{chol, cholinv, inv}\n\
553 int nargin = args.
length ();
562 if (nr == 0 || nc == 0)
634 @deftypefn {Loadable Function} {[@var{R1}, @var{info}] =} cholupdate (@var{R}, @var{u}, @var{op})\n\
635 Update or downdate a Cholesky@tie{}factorization.\n\
637 Given an upper triangular matrix @var{R} and a column vector @var{u},\n\
638 attempt to determine another upper triangular matrix @var{R1} such that\n\
642 @var{R1}'*@var{R1} = @var{R}'*@var{R} + @var{u}*@var{u}'\n\
643 if @var{op} is @qcode{\"+\"}\n\
646 @var{R1}'*@var{R1} = @var{R}'*@var{R} - @var{u}*@var{u}'\n\
647 if @var{op} is @qcode{\"-\"}\n\
650 If @var{op} is @qcode{\"-\"}, @var{info} is set to\n\
653 @item 0 if the downdate was successful,\n\
655 @item 1 if @var{R}'*@var{R} - @var{u}*@var{u}' is not positive definite,\n\
657 @item 2 if @var{R} is singular.\n\
660 If @var{info} is not present, an error message is printed in cases 1 and 2.\n\
661 @seealso{chol, cholinsert, choldelete, cholshift}\n\
668 if (nargin > 3 || nargin < 2)
678 && (nargin < 3 || args(2).is_string ()))
682 std::string op = (nargin < 3) ?
"+" : args(2).string_value ();
684 bool down = op ==
"-";
686 if (down || op ==
"+")
765 error (
"cholupdate: downdate violates positiveness");
767 error (
"cholupdate: singular matrix");
770 error (
"cholupdate: dimension mismatch between R and U");
772 error (
"cholupdate: OP must be \"+\" or \"-\"");
844 @deftypefn {Loadable Function} {@var{R1} =} cholinsert (@var{R}, @var{j}, @var{u})\n\
845 @deftypefnx {Loadable Function} {[@var{R1}, @var{info}] =} cholinsert (@var{R}, @var{j}, @var{u})\n\
846 Given a Cholesky@tie{}factorization of a real symmetric or complex Hermitian\n\
847 positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper\n\
848 triangular, return the Cholesky@tie{}factorization of\n\
849 @var{A1}, where @w{A1(p,p) = A}, @w{A1(:,j) = A1(j,:)' = u} and\n\
850 @w{p = [1:j-1,j+1:n+1]}. @w{u(j)} should be positive.\n\
852 On return, @var{info} is set to\n\
855 @item 0 if the insertion was successful,\n\
857 @item 1 if @var{A1} is not positive definite,\n\
859 @item 2 if @var{R} is singular.\n\
862 If @var{info} is not present, an error message is printed in cases 1 and 2.\n\
863 @seealso{chol, cholupdate, choldelete, cholshift}\n\
888 if (j > 0 && j <= n+1)
951 error (
"cholinsert: insertion violates positiveness");
953 error (
"cholinsert: singular matrix");
955 error (
"cholinsert: diagonal element must be real");
958 error (
"cholinsert: index J out of range");
961 error (
"cholinsert: dimension mismatch between R and U");
1108 @deftypefn {Loadable Function} {@var{R1} =} choldelete (@var{R}, @var{j})\n\
1109 Given a Cholesky@tie{}factorization of a real symmetric or complex Hermitian\n\
1110 positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper\n\
1111 triangular, return the Cholesky@tie{}factorization of @w{A(p,p)}, where\n\
1112 @w{p = [1:j-1,j+1:n+1]}.\n\
1113 @seealso{chol, cholupdate, cholinsert, cholshift}\n\
1136 if (j > 0 && j <= n)
1190 error (
"choldelete: index J out of range");
1193 error (
"choldelete: matrix R must be square");
1241 @deftypefn {Loadable Function} {@var{R1} =} cholshift (@var{R}, @var{i}, @var{j})\n\
1242 Given a Cholesky@tie{}factorization of a real symmetric or complex Hermitian\n\
1243 positive definite matrix @w{@var{A} = @var{R}'*@var{R}}, @var{R}@tie{}upper\n\
1244 triangular, return the Cholesky@tie{}factorization of\n\
1245 @w{@var{A}(p,p)}, where @w{p} is the permutation @*\n\
1246 @code{p = [1:i-1, shift(i:j, 1), j+1:n]} if @w{@var{i} < @var{j}} @*\n\
1248 @code{p = [1:j-1, shift(j:i,-1), i+1:n]} if @w{@var{j} < @var{i}}. @*\n\
1250 @seealso{chol, cholupdate, cholinsert, choldelete}\n\
1276 if (j > 0 && j <= n+1 && i > 0 && i <= n+1)
1332 error (
"cholshift: index I or J is out of range");
1335 error (
"cholshift: R must be a square matrix");
FloatComplexMatrix transpose(void) const
ColumnVector column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
void shift_sym(octave_idx_type i, octave_idx_type j)
ColumnVector perm(void) const
bool is_real_type(void) const
void gripe_wrong_type_arg(const char *name, const char *s, bool is_error)
SparseMatrix inverse(void) const
octave_idx_type insert_sym(const FloatComplexColumnVector &u, octave_idx_type j)
octave_idx_type rows(void) const
octave_idx_type downdate(const ColumnVector &u)
FloatComplexMatrix float_complex_matrix_value(bool frc_str_conv=false) const
FloatColumnVector float_column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
OCTINTERP_API void print_usage(void)
octave_idx_type downdate(const FloatComplexColumnVector &u)
octave_idx_type length(void) const
ComplexMatrix inverse(void) const
FloatMatrix transpose(void) const
void update(const ColumnVector &u)
bool is_numeric_type(void) const
void update(const ComplexColumnVector &u)
void shift_sym(octave_idx_type i, octave_idx_type j)
void delete_sym(octave_idx_type j)
void error(const char *fmt,...)
SparseMatrix R(void) const
static octave_value get_chol_r(const CHOLT &fact)
int empty_arg(const char *, octave_idx_type nr, octave_idx_type nc)
octave_idx_type downdate(const ComplexColumnVector &u)
double scalar_value(bool frc_str_conv=false) const
SparseComplexMatrix inverse(void) const
FloatComplexMatrix inverse(void) const
void delete_sym(octave_idx_type j)
octave_idx_type insert_sym(const ColumnVector &u, octave_idx_type j)
static octave_value get_chol_l(const CHOLT &fact)
SparseMatrix Q(void) const
octave_idx_type columns(void) const
ComplexMatrix chol2inv(const ComplexMatrix &r)
void update(const FloatColumnVector &u)
bool is_sparse_type(void) const
octave_idx_type downdate(const FloatColumnVector &u)
bool is_real_scalar(void) const
void set(const ComplexMatrix &R)
SparseComplexMatrix R(void) const
octave_idx_type insert_sym(const FloatColumnVector &u, octave_idx_type j)
void shift_sym(octave_idx_type i, octave_idx_type j)
bool is_complex_type(void) const
Matrix inverse(void) const
Matrix transpose(void) const
octave_idx_type insert_sym(const ComplexColumnVector &u, octave_idx_type j)
SparseMatrix L(void) const
octave_idx_type length(void) const
ComplexMatrix transpose(void) const
SparseComplexMatrix sparse_complex_matrix_value(bool frc_str_conv=false) const
Matrix matrix_value(bool frc_str_conv=false) const
SparseComplexMatrix L(void) const
ComplexMatrix complex_matrix_value(bool frc_str_conv=false) const
FloatMatrix inverse(void) const
void delete_sym(octave_idx_type j)
FloatComplexColumnVector float_complex_column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
ColumnVector perm(void) const
FloatMatrix float_matrix_value(bool frc_str_conv=false) const
void set(const FloatMatrix &R)
void set(const FloatComplexMatrix &R)
ComplexColumnVector complex_column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
#define DEFUN_DLD(name, args_name, nargout_name, doc)
SparseMatrix sparse_matrix_value(bool frc_str_conv=false) const
bool is_single_type(void) const
void update(const FloatComplexColumnVector &u)
void shift_sym(octave_idx_type i, octave_idx_type j)
void delete_sym(octave_idx_type j)
void set(const Matrix &R)
return octave_value(v1.char_array_value().concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string())? '\'': '"'))
SparseMatrix Q(void) const