26#if defined (HAVE_CONFIG_H)
71#if defined (HAVE_ARPACK)
83 F77_INT f77_incx = to_f77_int (incx);
93 F77_INT f77_incx = to_f77_int (incx);
102 F77_INT f77_n = to_f77_int (n);
103 F77_INT f77_incx = to_f77_int (incx);
112 F77_INT f77_n = to_f77_int (n);
113 F77_INT f77_incx = to_f77_int (incx);
125template <
typename T,
typename R>
132 if (math::isnan (result))
134 bool has_inf =
false;
137 if (math::isnan (data[i]))
139 if (math::isinf (data[i]))
143 return numeric_limits<R>::Inf ();
159 m.
data (), lda, work, result
160 F77_CHAR_ARG_LEN (1));
175 m.
data (), lda, work, result
176 F77_CHAR_ARG_LEN (1));
193 F77_CHAR_ARG_LEN (1));
210 F77_CHAR_ARG_LEN (1));
230class norm_accumulator_p
235 norm_accumulator_p (R pp) : m_p (pp), m_scl (0), m_sum (1) { }
237 OCTAVE_DEFAULT_CONSTRUCT_COPY_MOVE_DELETE (norm_accumulator_p)
239 template <
typename U>
242 AT t = std::abs (val);
249 m_sum *= std::pow (m_scl / t,
static_cast<AT
> (m_p));
254 m_sum += std::pow (t / m_scl,
static_cast<AT
> (m_p));
260 return static_cast<R
> (m_scl * std::pow (m_sum, 1 /
static_cast<AT
> (m_p)));
270class norm_accumulator_mp
275 norm_accumulator_mp (R pp) : m_p (pp), m_scl (0), m_sum (1) { }
277 OCTAVE_DEFAULT_CONSTRUCT_COPY_MOVE_DELETE (norm_accumulator_mp)
279 template <
typename U>
282 AT t = 1 / std::abs (val);
287 m_sum *= std::pow (m_scl / t,
static_cast<AT
> (m_p));
292 m_sum += std::pow (t / m_scl,
static_cast<AT
> (m_p));
297 return static_cast<R
> (m_scl * std::pow (m_sum, -1 /
static_cast<AT
> (m_p)));
308class norm_accumulator_2
313 norm_accumulator_2 () : m_scl (0), m_sum (0) { }
315 OCTAVE_DEFAULT_COPY_MOVE_DELETE (norm_accumulator_2)
319 AT t = std::abs (val);
339 void accum (std::complex<R> val)
347 return static_cast<R
> (m_scl * std::sqrt (m_sum));
356class norm_accumulator_1
361 norm_accumulator_1 () : m_sum (0) { }
363 OCTAVE_DEFAULT_COPY_MOVE_DELETE (norm_accumulator_1)
365 template <
typename U>
368 m_sum += std::abs (val);
371 operator R () {
return static_cast<R
> (m_sum); }
379class norm_accumulator_inf
383 norm_accumulator_inf () : m_max (0) { }
385 OCTAVE_DEFAULT_COPY_MOVE_DELETE (norm_accumulator_inf)
387 template <
typename U>
390 if (math::isnan (val))
391 m_max = numeric_limits<R>::NaN ();
393 m_max = std::max (m_max, std::abs (val));
396 operator R () {
return m_max; }
404class norm_accumulator_minf
408 norm_accumulator_minf () : m_min (numeric_limits<R>::
Inf ()) { }
410 OCTAVE_DEFAULT_COPY_MOVE_DELETE (norm_accumulator_minf)
412 template <
typename U>
415 if (math::isnan (val))
416 m_min = numeric_limits<R>::NaN ();
418 m_min = std::min (m_min, std::abs (val));
421 operator R () {
return m_min; }
429class norm_accumulator_0
433 norm_accumulator_0 () : m_num (0) { }
435 OCTAVE_DEFAULT_COPY_MOVE_DELETE (norm_accumulator_0)
437 template <
typename U>
440 if (val !=
static_cast<U
> (0)) ++m_num;
443 operator R () {
return m_num; }
451template <
typename T,
typename R,
typename ACC>
462template <
typename T,
typename R,
typename ACC>
468 acc.accum (v.
data (i));
474template <
typename T,
typename R,
typename ACC>
483 accj.accum (m(i, j));
485 res.
xelem (j) = accj;
489template <
typename T,
typename R,
typename ACC>
494 std::vector<ACC> acci (m.
rows (), acc);
498 acci[i].accum (m(i, j));
502 res.
xelem (i) = acci[i];
506template <
typename T,
typename R,
typename ACC>
515 accj.accum (m.
data (k));
517 res.
xelem (j) = accj;
521template <
typename T,
typename R,
typename ACC>
526 std::vector<ACC> acci (m.
rows (), acc);
530 acci[m.
ridx (k)].accum (m.
data (k));
534 res.
xelem (i) = acci[i];
538template <
typename T,
typename R>
546template <
typename T,
typename R>
552 res = vector_norm_2_blas<T, R> (v);
555 else if (math::isinf (p))
572template <
typename T,
typename R>
581 else if (math::isinf (p))
598#define DEFINE_COLROW_DISPATCHER(FCN_NAME, ARG_TYPE, RES_TYPE) \
599template <typename T, typename R> \
600RES_TYPE FCN_NAME (const ARG_TYPE& v, R p) \
604 FCN_NAME (v, res, norm_accumulator_2<R> ()); \
606 FCN_NAME (v, res, norm_accumulator_1<R> ()); \
607 else if (math::isinf (p)) \
610 FCN_NAME (v, res, norm_accumulator_inf<R> ()); \
612 FCN_NAME (v, res, norm_accumulator_minf<R> ()); \
615 FCN_NAME (v, res, norm_accumulator_0<R> ()); \
617 FCN_NAME (v, res, norm_accumulator_p<R> (p)); \
619 FCN_NAME (v, res, norm_accumulator_mp<R> (p)); \
632template <typename ColVectorT, typename R>
634higham_subp (const ColVectorT& y, const ColVectorT& col,
641 R fi = i *
static_cast<R
> (M_PI) / nsamp;
642 R lambda1 = cos (fi);
644 R lmnr = std::pow (std::pow (std::abs (lambda1), p)
645 + std::pow (std::abs (mu1), p), 1 / p);
646 lambda1 /= lmnr; mu1 /= lmnr;
660template <
typename ColVectorT,
typename R>
662higham_subp (
const ColVectorT& y,
const ColVectorT& col,
664 std::complex<R>& lambda, std::complex<R>& mu)
666 typedef std::complex<R> CR;
669 CR lamcu = lambda / std::abs (lambda);
674 R fi = i *
static_cast<R
> (M_PI) / nsamp;
675 R lambda1 = cos (fi);
677 R lmnr = std::pow (std::pow (std::abs (lambda1), p)
678 + std::pow (std::abs (mu1), p), 1 / p);
679 lambda1 /= lmnr; mu1 /= lmnr;
680 R nrm1 =
vector_norm (lambda1 * lamcu * y + mu1 * col, p);
683 lambda = lambda1 * lamcu;
688 R lama = std::abs (lambda);
693 R fi = i *
static_cast<R
> (M_PI) / nsamp;
694 lamcu = CR (cos (fi), sin (fi));
695 R nrm1 =
vector_norm (lama * lamcu * y + mu * col, p);
698 lambda = lama * lamcu;
705template <
typename T,
typename R>
709 return math::signum (
x) * std::pow (std::abs (
x), p - 1);
716template <
typename VectorT,
typename R>
720 VectorT res (
x.dims ());
727template <
typename MatrixT,
typename VectorT,
typename R>
729higham (
const MatrixT& m, R p, R tol,
int maxiter,
732 x.resize (m.columns (), 1);
734 VectorT y (m.rows (), 1, 0), z (m.rows (), 1);
735 typedef typename VectorT::element_type RR;
741 VectorT col (m.column (k));
743 higham_subp (y, col, 4*k, p, lambda, mu);
747 y = lambda * y + mu * col;
756 while (iter < maxiter)
788template <
typename MatrixT,
typename VectorT,
typename R>
795 math::svd<MatrixT> fact (m, math::svd<MatrixT>::Type::sigma_only);
796 res = fact.singular_values () (0, 0);
799 res =
lange (
'O', m);
800 else if (math::isinf (p) && p > 1)
801 res =
lange (
'I', m);
805 const R sqrteps = std::sqrt (std::numeric_limits<R>::epsilon ());
818 if constexpr (std::is_arithmetic_v<T>)
821 return std::conj (
x);
825template <
typename VectorT>
829 using T =
typename VectorT::element_type;
840template <
typename MatrixT,
typename VectorT,
typename R>
847 if (nc == 0 || nr == 0)
851 const bool use_aat = (nr < nc);
855 VectorT
x (n, 1, R (1) / std::sqrt (
static_cast<R
> (n)));
858 R lambda = 0, lambda_prev = 0;
860 for (
int iter = 0; iter < maxiter; iter++)
868 auto z = m.hermitian () *
x;
875 y = m.hermitian () * z;
879 lambda_prev = lambda;
891 if (iter > 0 && std::abs (lambda - lambda_prev) <= tol * lambda)
895 return std::sqrt (lambda);
898#if defined (HAVE_ARPACK)
909 if (nc == 0 || nr == 0)
920 aug = aug.
insert (m, 0, nr);
940 eig_vec, eig_val,
B, permB, resid,
941 std::cout, tol,
false,
false, 0, maxiter);
945 if (info < 0 || eig_val.
numel () == 0)
948 return std::abs (eig_val (0));
958 if (nc == 0 || nr == 0)
968 aug = aug.
insert (m, 0, nr);
988 eig_vec, eig_val,
B, permB, resid,
989 std::cout, tol,
false,
false, 0, maxiter);
993 if (info < 0 || eig_val.
numel () == 0)
996 return std::abs (eig_val (0));
1002template <
typename MatrixT,
typename VectorT,
typename R>
1006#if defined (HAVE_ARPACK)
1018template <
typename MatrixT,
typename VectorT,
typename R>
1025 else if (math::isinf (p) && p > 1)
1030 const R sqrteps = std::sqrt (std::numeric_limits<R>::epsilon ());
1036 const R sqrteps = std::sqrt (std::numeric_limits<R>::epsilon ());
1047#define DEFINE_XNORM_FCNS(PREFIX, RTYPE) \
1048RTYPE xnorm (const PREFIX##ColumnVector& x, RTYPE p) \
1050 return vector_norm (x, p); \
1052RTYPE xnorm (const PREFIX##RowVector& x, RTYPE p) \
1054 return vector_norm (x, p); \
1056RTYPE xnorm (const PREFIX##Matrix& x, RTYPE p) \
1058 return svd_matrix_norm (x, p, PREFIX##Matrix ()); \
1060RTYPE xfrobnorm (const PREFIX##Matrix& x) \
1062 return lange ('F', x); \
1071template <typename T, typename R>
1074 norm_accumulator_2<R> acc;
1081#define DEFINE_XNORM_SPARSE_FCNS(PREFIX, RTYPE) \
1082RTYPE xnorm (const Sparse##PREFIX##Matrix& x, RTYPE p) \
1084 return matrix_norm (x, p, PREFIX##Matrix ()); \
1086RTYPE xfrobnorm (const Sparse##PREFIX##Matrix& x) \
1089 array_norm_2 (x.data (), x.nnz (), res); \
1096#define DEFINE_COLROW_NORM_FCNS(PREFIX, RPREFIX, RTYPE) \
1098xcolnorms (const PREFIX##Matrix& m, RTYPE p) \
1100 return column_norms (m, p); \
1102RPREFIX##ColumnVector \
1103xrownorms (const PREFIX##Matrix& m, RTYPE p) \
1105 return row_norms (m, p); \
1116OCTAVE_END_NAMESPACE(octave)
N Dimensional Array with copy-on-write semantics.
T & xelem(octave_idx_type n)
Size of the specified dimension.
octave_idx_type rows() const
octave_idx_type columns() const
octave_idx_type cols() const
const T * data() const
Size of the specified dimension.
octave_idx_type numel() const
Number of elements in the array.
Template for N-dimensional array classes with like-type math operators.
SparseComplexMatrix hermitian() const
SparseComplexMatrix & insert(const SparseComplexMatrix &a, octave_idx_type r, octave_idx_type c)
SparseMatrix & insert(const SparseMatrix &a, octave_idx_type r, octave_idx_type c)
SparseMatrix transpose() const
octave_idx_type cols() const
octave_idx_type columns() const
octave_idx_type nnz() const
Actual number of nonzero terms.
octave_idx_type rows() const
Vector representing the dimensions (size) of an Array.
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
octave_idx_type EigsComplexNonSymmetricMatrix(const M &m, const std::string typ, octave_idx_type k_arg, octave_idx_type p_arg, octave_idx_type &info, ComplexMatrix &eig_vec, ComplexColumnVector &eig_val, const M &_b, ColumnVector &permB, ComplexColumnVector &cresid, std::ostream &os, double tol, bool rvec, bool cholB, int disp, int maxit)
octave_idx_type EigsRealSymmetricMatrix(const M &m, const std::string typ, octave_idx_type k_arg, octave_idx_type p_arg, octave_idx_type &info, Matrix &eig_vec, ColumnVector &eig_val, const M &_b, ColumnVector &permB, ColumnVector &resid, std::ostream &os, double tol, bool rvec, bool cholB, int disp, int maxit)
#define F77_CONST_CMPLX_ARG(x)
octave_f77_int_type F77_INT
#define F77_CONST_DBLE_CMPLX_ARG(x)
F77_RET_T const F77_INT F77_CMPLX const F77_INT F77_CMPLX * B
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
std::complex< double > Complex
std::complex< float > FloatComplex
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
VectorT dual_p(const VectorT &x, R p, R q)
void array_norm_2(const T *v, octave_idx_type n, R &res)
std::conditional_t< std::is_same_v< R, float >, double, R > accum_type
R matrix_norm(const MatrixT &m, R p, VectorT)
#define DEFINE_COLROW_NORM_FCNS(PREFIX, RPREFIX, RTYPE)
RowVector xcolnorms(const Matrix &m, double p)
constexpr const char * p_less1_gripe
constexpr T safe_conj(T x)
R sparse_2norm_power(const MatrixT &m, R tol, int maxiter, VectorT)
double sparse_2norm_arpack(const SparseMatrix &m, double tol, int maxiter)
#define DEFINE_COLROW_DISPATCHER(FCN_NAME, ARG_TYPE, RES_TYPE)
double lange(char norm_type, const Matrix &m)
R vector_norm_2_blas(const MArray< T > &v)
void column_norms(const MArray< T > &m, MArray< R > &res, ACC acc)
auto vector_dot(const VectorT &x, const VectorT &y)
ColumnVector xrownorms(const Matrix &m, double p)
#define DEFINE_XNORM_SPARSE_FCNS(PREFIX, RTYPE)
void vector_norm(const Array< T > &v, R &res, ACC acc)
void row_norms(const MArray< T > &m, MArray< R > &res, ACC acc)
double blas_nrm2(octave_idx_type n, const double *x, octave_idx_type incx)
R svd_matrix_norm(const MatrixT &m, R p, VectorT)
R sparse_2norm(const MatrixT &m, R tol, int maxiter, VectorT)
R higham(const MatrixT &m, R p, R tol, int maxiter, VectorT &x)
constexpr int max_norm_iter
#define DEFINE_XNORM_FCNS(PREFIX, RTYPE)
R lange_inf_fixup(R result, const T *data, octave_idx_type numel)
T::size_type numel(const T &str)
F77_RET_T const F77_DBLE * x
subroutine xclange(norm, m, n, a, lda, work, retval)
subroutine xdlange(norm, m, n, a, lda, work, retval)
subroutine xdnrm2(n, x, incx, retval)
subroutine xdznrm2(n, x, incx, retval)
F77_RET_T F77_FUNC(xerbla, XERBLA)(F77_CONST_CHAR_ARG_DEF(s_arg
subroutine xscnrm2(n, x, incx, retval)
subroutine xslange(norm, m, n, a, lda, work, retval)
subroutine xsnrm2(n, x, incx, retval)
subroutine xzlange(norm, m, n, a, lda, work, retval)