26 #if defined (HAVE_CONFIG_H)
75 class norm_accumulator_p
79 norm_accumulator_p (R pp) : m_p(pp), m_scl(0), m_sum(1) { }
81 OCTAVE_DEFAULT_CONSTRUCT_COPY_MOVE_DELETE (norm_accumulator_p)
100 operator R () {
return m_scl *
std::pow (m_sum, 1/m_p); }
107 template <
typename R>
108 class norm_accumulator_mp
112 norm_accumulator_mp (R pp) : m_p(pp), m_scl(0), m_sum(1) { }
114 OCTAVE_DEFAULT_CONSTRUCT_COPY_MOVE_DELETE (norm_accumulator_mp)
116 template <
typename U>
120 R t = 1 / std::abs (val);
133 operator R () {
return m_scl *
std::pow (m_sum, -1/m_p); }
140 template <
typename R>
141 class norm_accumulator_2
145 norm_accumulator_2 () : m_scl(0), m_sum(1) { }
147 OCTAVE_DEFAULT_COPY_MOVE_DELETE (norm_accumulator_2)
151 R t = std::abs (val);
156 m_sum *= pow2 (m_scl/t);
161 m_sum += pow2 (t/m_scl);
164 void accum (std::complex<R> val)
170 operator R () {
return m_scl * std::sqrt (m_sum); }
173 static inline R pow2 (R
x) {
return x*
x; }
181 template <
typename R>
182 class norm_accumulator_1
186 norm_accumulator_1 () : m_sum (0) { }
188 OCTAVE_DEFAULT_COPY_MOVE_DELETE (norm_accumulator_1)
190 template <
typename U>
193 m_sum += std::abs (val);
196 operator R () {
return m_sum; }
203 template <
typename R>
204 class norm_accumulator_inf
208 norm_accumulator_inf () : m_max (0) { }
210 OCTAVE_DEFAULT_COPY_MOVE_DELETE (norm_accumulator_inf)
212 template <
typename U>
218 m_max =
std::max (m_max, std::abs (val));
221 operator R () {
return m_max; }
228 template <
typename R>
229 class norm_accumulator_minf
233 norm_accumulator_minf () : m_min (numeric_limits<R>::
Inf ()) { }
235 OCTAVE_DEFAULT_COPY_MOVE_DELETE (norm_accumulator_minf)
237 template <
typename U>
243 m_min =
std::min (m_min, std::abs (val));
246 operator R () {
return m_min; }
253 template <
typename R>
254 class norm_accumulator_0
258 norm_accumulator_0 () : m_num (0) { }
260 OCTAVE_DEFAULT_COPY_MOVE_DELETE (norm_accumulator_0)
262 template <
typename U>
265 if (val !=
static_cast<U
> (0)) ++m_num;
268 operator R () {
return m_num; }
276 template <
typename T,
typename R,
typename ACC>
287 template <
typename T,
typename R,
typename ACC>
296 accj.accum (
m(i, j));
298 res.
xelem (j) = accj;
302 template <
typename T,
typename R,
typename ACC>
307 std::vector<ACC> acci (
m.rows (), acc);
311 acci[i].accum (
m(i, j));
315 res.
xelem (i) = acci[i];
319 template <
typename T,
typename R,
typename ACC>
328 accj.accum (
m.data (k));
330 res.
xelem (j) = accj;
334 template <
typename T,
typename R,
typename ACC>
339 std::vector<ACC> acci (
m.rows (), acc);
343 acci[
m.ridx (k)].accum (
m.data (k));
347 res.
xelem (i) = acci[i];
351 #define DEFINE_DISPATCHER(FCN_NAME, ARG_TYPE, RES_TYPE) \
352 template <typename T, typename R> \
353 RES_TYPE FCN_NAME (const ARG_TYPE& v, R p) \
357 FCN_NAME (v, res, norm_accumulator_2<R> ()); \
359 FCN_NAME (v, res, norm_accumulator_1<R> ()); \
360 else if (lo_ieee_isinf (p)) \
363 FCN_NAME (v, res, norm_accumulator_inf<R> ()); \
365 FCN_NAME (v, res, norm_accumulator_minf<R> ()); \
368 FCN_NAME (v, res, norm_accumulator_0<R> ()); \
370 FCN_NAME (v, res, norm_accumulator_p<R> (p)); \
372 FCN_NAME (v, res, norm_accumulator_mp<R> (p)); \
386 template <typename ColVectorT, typename R>
388 higham_subp (const ColVectorT& y, const ColVectorT& col,
395 R fi = i *
static_cast<R
> (M_PI) / nsamp;
396 R lambda1 = cos (fi);
400 lambda1 /= lmnr; mu1 /= lmnr;
414 template <
typename ColVectorT,
typename R>
416 higham_subp (
const ColVectorT& y,
const ColVectorT& col,
418 std::complex<R>& lambda, std::complex<R>& mu)
420 typedef std::complex<R> CR;
423 CR lamcu = lambda / std::abs (lambda);
428 R fi = i *
static_cast<R
> (M_PI) / nsamp;
429 R lambda1 = cos (fi);
433 lambda1 /= lmnr; mu1 /= lmnr;
434 R nrm1 =
vector_norm (lambda1 * lamcu * y + mu1 * col, p);
437 lambda = lambda1 * lamcu;
442 R lama = std::abs (lambda);
447 R fi = i *
static_cast<R
> (M_PI) / nsamp;
448 lamcu = CR (cos (fi), sin (fi));
449 R nrm1 =
vector_norm (lama * lamcu * y + mu * col, p);
452 lambda = lama * lamcu;
459 template <
typename T,
typename R>
470 template <
typename VectorT,
typename R>
474 VectorT res (
x.dims ());
481 template <
typename MatrixT,
typename VectorT,
typename R>
483 higham (
const MatrixT&
m, R p, R tol,
int maxiter,
486 x.resize (
m.columns (), 1);
488 VectorT y(
m.rows (), 1, 0), z(
m.rows (), 1);
489 typedef typename VectorT::element_type RR;
495 VectorT col (
m.column (k));
497 higham_subp (y, col, 4*k, p, lambda, mu);
501 y = lambda * y + mu * col;
510 while (iter < maxiter)
534 static const char *p_less1_gripe =
"xnorm: p must be >= 1";
539 static int max_norm_iter = 100;
542 template <
typename MatrixT,
typename VectorT,
typename R>
549 math::svd<MatrixT> fact (
m, math::svd<MatrixT>::Type::sigma_only);
550 res = fact.singular_values () (0, 0);
559 const R sqrteps = std::sqrt (std::numeric_limits<R>::epsilon ());
560 res =
higham (
m, p, sqrteps, max_norm_iter,
x);
569 template <
typename MatrixT,
typename VectorT,
typename R>
581 const R sqrteps = std::sqrt (std::numeric_limits<R>::epsilon ());
582 res =
higham (
m, p, sqrteps, max_norm_iter,
x);
592 #define DEFINE_XNORM_FCNS(PREFIX, RTYPE) \
593 RTYPE xnorm (const PREFIX##ColumnVector& x, RTYPE p) \
595 return vector_norm (x, p); \
597 RTYPE xnorm (const PREFIX##RowVector& x, RTYPE p) \
599 return vector_norm (x, p); \
601 RTYPE xnorm (const PREFIX##Matrix& x, RTYPE p) \
603 return svd_matrix_norm (x, p, PREFIX##Matrix ()); \
605 RTYPE xfrobnorm (const PREFIX##Matrix& x) \
607 return vector_norm (x, static_cast<RTYPE> (2)); \
616 template <typename T, typename R>
619 norm_accumulator_2<R> acc;
626 #define DEFINE_XNORM_SPARSE_FCNS(PREFIX, RTYPE) \
627 RTYPE xnorm (const Sparse##PREFIX##Matrix& x, RTYPE p) \
629 return matrix_norm (x, p, PREFIX##Matrix ()); \
631 RTYPE xfrobnorm (const Sparse##PREFIX##Matrix& x) \
634 array_norm_2 (x.data (), x.nnz (), res); \
641 #define DEFINE_COLROW_NORM_FCNS(PREFIX, RPREFIX, RTYPE) \
643 xcolnorms (const PREFIX##Matrix& m, RTYPE p) \
645 return column_norms (m, p); \
647 RPREFIX##ColumnVector \
648 xrownorms (const PREFIX##Matrix& m, RTYPE p) \
650 return row_norms (m, p); \
661 OCTAVE_END_NAMESPACE(
octave)
charNDArray max(char d, const charNDArray &m)
charNDArray min(char d, const charNDArray &m)
T & xelem(octave_idx_type n)
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.
Vector representing the dimensions (size) of an Array.
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
F77_RET_T const F77_DBLE * x
std::complex< double > Complex
std::complex< float > FloatComplex
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
VectorT dual_p(const VectorT &x, R p, R q)
void array_norm_2(const T *v, octave_idx_type n, R &res)
R matrix_norm(const MatrixT &m, R p, VectorT)
#define DEFINE_COLROW_NORM_FCNS(PREFIX, RPREFIX, RTYPE)
RowVector xcolnorms(const Matrix &m, double p)
void column_norms(const MArray< T > &m, MArray< R > &res, ACC acc)
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)
R svd_matrix_norm(const MatrixT &m, R p, VectorT)
R higham(const MatrixT &m, R p, R tol, int maxiter, VectorT &x)
#define DEFINE_XNORM_FCNS(PREFIX, RTYPE)
#define DEFINE_DISPATCHER(FCN_NAME, ARG_TYPE, RES_TYPE)