GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
oct-norm.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2008-2017 VZLU Prague, a.s.
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 // author: Jaroslav Hajek <highegg@gmail.com>
24 
25 #if defined (HAVE_CONFIG_H)
26 # include "config.h"
27 #endif
28 
29 #include <cassert>
30 #include <cfloat>
31 #include <cmath>
32 
33 #include <iostream>
34 #include <vector>
35 
36 #include "Array-util.h"
37 #include "Array.h"
38 #include "CColVector.h"
39 #include "CMatrix.h"
40 #include "CRowVector.h"
41 #include "CSparse.h"
42 #include "dColVector.h"
43 #include "dDiagMatrix.h"
44 #include "dMatrix.h"
45 #include "dRowVector.h"
46 #include "dSparse.h"
47 #include "fCColVector.h"
48 #include "fCMatrix.h"
49 #include "fCRowVector.h"
50 #include "fColVector.h"
51 #include "fDiagMatrix.h"
52 #include "fMatrix.h"
53 #include "fRowVector.h"
54 #include "lo-error.h"
55 #include "lo-ieee.h"
56 #include "mx-cm-s.h"
57 #include "mx-fcm-fs.h"
58 #include "mx-fs-fcm.h"
59 #include "mx-s-cm.h"
60 #include "oct-cmplx.h"
61 #include "svd.h"
62 
63 // Theory: norm accumulator is an object that has an accum method able
64 // to handle both real and complex element, and a cast operator
65 // returning the intermediate norm. Reference: Higham, N. "Estimating
66 // the Matrix p-Norm." Numer. Math. 62, 539-555, 1992.
67 
68 // norm accumulator for the p-norm
69 template <typename R>
71 {
72  R p,scl,sum;
73 public:
74  norm_accumulator_p () { } // we need this one for Array
75  norm_accumulator_p (R pp) : p(pp), scl(0), sum(1) { }
76 
77  template <typename U>
78  void accum (U val)
79  {
80  octave_quit ();
81  R t = std::abs (val);
82  if (scl == t) // we need this to handle Infs properly
83  sum += 1;
84  else if (scl < t)
85  {
86  sum *= std::pow (scl/t, p);
87  sum += 1;
88  scl = t;
89  }
90  else if (t != 0)
91  sum += std::pow (t/scl, p);
92  }
93  operator R () { return scl * std::pow (sum, 1/p); }
94 };
95 
96 // norm accumulator for the minus p-pseudonorm
97 template <typename R>
99 {
100  R p,scl,sum;
101 public:
102  norm_accumulator_mp () { } // we need this one for Array
103  norm_accumulator_mp (R pp) : p(pp), scl(0), sum(1) { }
104 
105  template <typename U>
106  void accum (U val)
107  {
108  octave_quit ();
109  R t = 1 / std::abs (val);
110  if (scl == t)
111  sum += 1;
112  else if (scl < t)
113  {
114  sum *= std::pow (scl/t, p);
115  sum += 1;
116  scl = t;
117  }
118  else if (t != 0)
119  sum += std::pow (t/scl, p);
120  }
121  operator R () { return scl * std::pow (sum, -1/p); }
122 };
123 
124 // norm accumulator for the 2-norm (euclidean)
125 template <typename R>
127 {
128  R scl,sum;
129  static R pow2 (R x) { return x*x; }
130 public:
131  norm_accumulator_2 () : scl(0), sum(1) { }
132 
133  void accum (R val)
134  {
135  R t = std::abs (val);
136  if (scl == t)
137  sum += 1;
138  else if (scl < t)
139  {
140  sum *= pow2 (scl/t);
141  sum += 1;
142  scl = t;
143  }
144  else if (t != 0)
145  sum += pow2 (t/scl);
146  }
147 
148  void accum (std::complex<R> val)
149  {
150  accum (val.real ());
151  accum (val.imag ());
152  }
153 
154  operator R () { return scl * std::sqrt (sum); }
155 };
156 
157 // norm accumulator for the 1-norm (city metric)
158 template <typename R>
160 {
161  R sum;
162 public:
163  norm_accumulator_1 () : sum (0) { }
164  template <typename U>
165  void accum (U val)
166  {
167  sum += std::abs (val);
168  }
169  operator R () { return sum; }
170 };
171 
172 // norm accumulator for the inf-norm (max metric)
173 template <typename R>
175 {
176  R max;
177 public:
178  norm_accumulator_inf () : max (0) { }
179  template <typename U>
180  void accum (U val)
181  {
182  if (octave::math::isnan (val))
184  else
185  max = std::max (max, std::abs (val));
186  }
187  operator R () { return max; }
188 };
189 
190 // norm accumulator for the -inf pseudonorm (min abs value)
191 template <typename R>
193 {
194  R min;
195 public:
196  norm_accumulator_minf () : min (octave::numeric_limits<R>::Inf ()) { }
197  template <typename U>
198  void accum (U val)
199  {
200  if (octave::math::isnan (val))
202  else
203  min = std::min (min, std::abs (val));
204  }
205  operator R () { return min; }
206 };
207 
208 // norm accumulator for the 0-pseudonorm (hamming distance)
209 template <typename R>
211 {
212  unsigned int num;
213 public:
214  norm_accumulator_0 () : num (0) { }
215  template <typename U>
216  void accum (U val)
217  {
218  if (val != static_cast<U> (0)) ++num;
219  }
220  operator R () { return num; }
221 };
222 
223 // OK, we're armed :) Now let's go for the fun
224 
225 template <typename T, typename R, typename ACC>
226 inline void vector_norm (const Array<T>& v, R& res, ACC acc)
227 {
228  for (octave_idx_type i = 0; i < v.numel (); i++)
229  acc.accum (v(i));
230 
231  res = acc;
232 }
233 
234 // dense versions
235 template <typename T, typename R, typename ACC>
236 void column_norms (const MArray<T>& m, MArray<R>& res, ACC acc)
237 {
238  res = MArray<R> (dim_vector (1, m.columns ()));
239  for (octave_idx_type j = 0; j < m.columns (); j++)
240  {
241  ACC accj = acc;
242  for (octave_idx_type i = 0; i < m.rows (); i++)
243  accj.accum (m(i, j));
244 
245  res.xelem (j) = accj;
246  }
247 }
248 
249 template <typename T, typename R, typename ACC>
250 void row_norms (const MArray<T>& m, MArray<R>& res, ACC acc)
251 {
252  res = MArray<R> (dim_vector (m.rows (), 1));
253  std::vector<ACC> acci (m.rows (), acc);
254  for (octave_idx_type j = 0; j < m.columns (); j++)
255  {
256  for (octave_idx_type i = 0; i < m.rows (); i++)
257  acci[i].accum (m(i, j));
258  }
259 
260  for (octave_idx_type i = 0; i < m.rows (); i++)
261  res.xelem (i) = acci[i];
262 }
263 
264 // sparse versions
265 template <typename T, typename R, typename ACC>
266 void column_norms (const MSparse<T>& m, MArray<R>& res, ACC acc)
267 {
268  res = MArray<R> (dim_vector (1, m.columns ()));
269  for (octave_idx_type j = 0; j < m.columns (); j++)
270  {
271  ACC accj = acc;
272  for (octave_idx_type k = m.cidx (j); k < m.cidx (j+1); k++)
273  accj.accum (m.data (k));
274 
275  res.xelem (j) = accj;
276  }
277 }
278 
279 template <typename T, typename R, typename ACC>
280 void row_norms (const MSparse<T>& m, MArray<R>& res, ACC acc)
281 {
282  res = MArray<R> (dim_vector (m.rows (), 1));
283  std::vector<ACC> acci (m.rows (), acc);
284  for (octave_idx_type j = 0; j < m.columns (); j++)
285  {
286  for (octave_idx_type k = m.cidx (j); k < m.cidx (j+1); k++)
287  acci[m.ridx (k)].accum (m.data (k));
288  }
289 
290  for (octave_idx_type i = 0; i < m.rows (); i++)
291  res.xelem (i) = acci[i];
292 }
293 
294 // now the dispatchers
295 #define DEFINE_DISPATCHER(FUNC_NAME, ARG_TYPE, RES_TYPE) \
296  template <typename T, typename R> \
297  RES_TYPE FUNC_NAME (const ARG_TYPE& v, R p) \
298  { \
299  RES_TYPE res; \
300  if (p == 2) \
301  FUNC_NAME (v, res, norm_accumulator_2<R> ()); \
302  else if (p == 1) \
303  FUNC_NAME (v, res, norm_accumulator_1<R> ()); \
304  else if (lo_ieee_isinf (p)) \
305  { \
306  if (p > 0) \
307  FUNC_NAME (v, res, norm_accumulator_inf<R> ()); \
308  else \
309  FUNC_NAME (v, res, norm_accumulator_minf<R> ()); \
310  } \
311  else if (p == 0) \
312  FUNC_NAME (v, res, norm_accumulator_0<R> ()); \
313  else if (p > 0) \
314  FUNC_NAME (v, res, norm_accumulator_p<R> (p)); \
315  else \
316  FUNC_NAME (v, res, norm_accumulator_mp<R> (p)); \
317  return res; \
318  }
319 
323 DEFINE_DISPATCHER (column_norms, MSparse<T>, MArray<R>)
324 DEFINE_DISPATCHER (row_norms, MSparse<T>, MArray<R>)
325 
326 // The approximate subproblem in Higham's method. Find lambda and mu such that
327 // norm ([lambda, mu], p) == 1 and norm (y*lambda + col*mu, p) is maximized.
328 // Real version. As in Higham's paper.
329 template <typename ColVectorT, typename R>
330 static void
331 higham_subp (const ColVectorT& y, const ColVectorT& col,
332  octave_idx_type nsamp, R p, R& lambda, R& mu)
333 {
334  R nrm = 0;
335  for (octave_idx_type i = 0; i < nsamp; i++)
336  {
337  octave_quit ();
338  R fi = i * static_cast<R> (M_PI) / nsamp;
339  R lambda1 = cos (fi);
340  R mu1 = sin (fi);
341  R lmnr = std::pow (std::pow (std::abs (lambda1), p) +
342  std::pow (std::abs (mu1), p), 1/p);
343  lambda1 /= lmnr; mu1 /= lmnr;
344  R nrm1 = vector_norm (lambda1 * y + mu1 * col, p);
345  if (nrm1 > nrm)
346  {
347  lambda = lambda1;
348  mu = mu1;
349  nrm = nrm1;
350  }
351  }
352 }
353 
354 // Complex version. Higham's paper does not deal with complex case, so we use
355 // a simple extension. First, guess the magnitudes as in real version, then
356 // try to rotate lambda to improve further.
357 template <typename ColVectorT, typename R>
358 static void
359 higham_subp (const ColVectorT& y, const ColVectorT& col,
360  octave_idx_type nsamp, R p,
361  std::complex<R>& lambda, std::complex<R>& mu)
362 {
363  typedef std::complex<R> CR;
364  R nrm = 0;
365  lambda = 1.0;
366  CR lamcu = lambda / std::abs (lambda);
367  // Probe magnitudes
368  for (octave_idx_type i = 0; i < nsamp; i++)
369  {
370  octave_quit ();
371  R fi = i * static_cast<R> (M_PI) / nsamp;
372  R lambda1 = cos (fi);
373  R mu1 = sin (fi);
374  R lmnr = std::pow (std::pow (std::abs (lambda1), p) +
375  std::pow (std::abs (mu1), p), 1/p);
376  lambda1 /= lmnr; mu1 /= lmnr;
377  R nrm1 = vector_norm (lambda1 * lamcu * y + mu1 * col, p);
378  if (nrm1 > nrm)
379  {
380  lambda = lambda1 * lamcu;
381  mu = mu1;
382  nrm = nrm1;
383  }
384  }
385  R lama = std::abs (lambda);
386  // Probe orientation
387  for (octave_idx_type i = 0; i < nsamp; i++)
388  {
389  octave_quit ();
390  R fi = i * static_cast<R> (M_PI) / nsamp;
391  lamcu = CR (cos (fi), sin (fi));
392  R nrm1 = vector_norm (lama * lamcu * y + mu * col, p);
393  if (nrm1 > nrm)
394  {
395  lambda = lama * lamcu;
396  nrm = nrm1;
397  }
398  }
399 }
400 
401 // the p-dual element (should work for both real and complex)
402 template <typename T, typename R>
403 inline T elem_dual_p (T x, R p)
404 {
405  return octave::math::signum (x) * std::pow (std::abs (x), p-1);
406 }
407 
408 // the VectorT is used for vectors, but actually it has to be
409 // a Matrix type to allow all the operations. For instance SparseMatrix
410 // does not support multiplication with column/row vectors.
411 // the dual vector
412 template <typename VectorT, typename R>
413 VectorT dual_p (const VectorT& x, R p, R q)
414 {
415  VectorT res (x.dims ());
416  for (octave_idx_type i = 0; i < x.numel (); i++)
417  res.xelem (i) = elem_dual_p (x(i), p);
418  return res / vector_norm (res, q);
419 }
420 
421 // Higham's hybrid method
422 template <typename MatrixT, typename VectorT, typename R>
423 R higham (const MatrixT& m, R p, R tol, int maxiter,
424  VectorT& x)
425 {
426  x.resize (m.columns (), 1);
427  // the OSE part
428  VectorT y(m.rows (), 1, 0), z(m.rows (), 1);
429  typedef typename VectorT::element_type RR;
430  RR lambda = 0;
431  RR mu = 1;
432  for (octave_idx_type k = 0; k < m.columns (); k++)
433  {
434  octave_quit ();
435  VectorT col (m.column (k));
436  if (k > 0)
437  higham_subp (y, col, 4*k, p, lambda, mu);
438  for (octave_idx_type i = 0; i < k; i++)
439  x(i) *= lambda;
440  x(k) = mu;
441  y = lambda * y + mu * col;
442  }
443 
444  // the PM part
445  x = x / vector_norm (x, p);
446  R q = p/(p-1);
447 
448  R gamma = 0, gamma1;
449  int iter = 0;
450  while (iter < maxiter)
451  {
452  octave_quit ();
453  y = m*x;
454  gamma1 = gamma;
455  gamma = vector_norm (y, p);
456  z = dual_p (y, p, q);
457  z = z.hermitian ();
458  z = z * m;
459 
460  if (iter > 0 && (vector_norm (z, q) <= gamma
461  || (gamma - gamma1) <= tol*gamma))
462  break;
463 
464  z = z.hermitian ();
465  x = dual_p (z, q, p);
466  iter++;
467  }
468 
469  return gamma;
470 }
471 
472 // derive column vector and SVD types
473 
474 static const char *p_less1_gripe = "xnorm: p must be at least 1";
475 
476 // Static constant to control the maximum number of iterations. 100 seems to
477 // be a good value. Eventually, we can provide a means to change this
478 // constant from Octave.
479 static int max_norm_iter = 100;
480 
481 // version with SVD for dense matrices
482 template <typename MatrixT, typename VectorT, typename R>
483 R svd_matrix_norm (const MatrixT& m, R p, VectorT)
484 {
485  R res = 0;
486  if (p == 2)
487  {
490  res = fact.singular_values () (0,0);
491  }
492  else if (p == 1)
493  res = xcolnorms (m, 1).max ();
494  else if (lo_ieee_isinf (p))
495  res = xrownorms (m, 1).max ();
496  else if (p > 1)
497  {
498  VectorT x;
499  const R sqrteps = std::sqrt (std::numeric_limits<R>::epsilon ());
500  res = higham (m, p, sqrteps, max_norm_iter, x);
501  }
502  else
504 
505  return res;
506 }
507 
508 // SVD-free version for sparse matrices
509 template <typename MatrixT, typename VectorT, typename R>
510 R matrix_norm (const MatrixT& m, R p, VectorT)
511 {
512  R res = 0;
513  if (p == 1)
514  res = xcolnorms (m, 1).max ();
515  else if (lo_ieee_isinf (p))
516  res = xrownorms (m, 1).max ();
517  else if (p > 1)
518  {
519  VectorT x;
520  const R sqrteps = std::sqrt (std::numeric_limits<R>::epsilon ());
521  res = higham (m, p, sqrteps, max_norm_iter, x);
522  }
523  else
525 
526  return res;
527 }
528 
529 // and finally, here's what we've promised in the header file
530 
531 #define DEFINE_XNORM_FUNCS(PREFIX, RTYPE) \
532  OCTAVE_API RTYPE xnorm (const PREFIX##ColumnVector& x, RTYPE p) \
533  { \
534  return vector_norm (x, p); \
535  } \
536  OCTAVE_API RTYPE xnorm (const PREFIX##RowVector& x, RTYPE p) \
537  { \
538  return vector_norm (x, p); \
539  } \
540  OCTAVE_API RTYPE xnorm (const PREFIX##Matrix& x, RTYPE p) \
541  { \
542  return svd_matrix_norm (x, p, PREFIX##Matrix ()); \
543  } \
544  OCTAVE_API RTYPE xfrobnorm (const PREFIX##Matrix& x) \
545  { \
546  return vector_norm (x, static_cast<RTYPE> (2)); \
547  }
548 
551 DEFINE_XNORM_FUNCS(Float, float)
553 
554 // this is needed to avoid copying the sparse matrix for xfrobnorm
555 template <typename T, typename R>
556 inline void array_norm_2 (const T* v, octave_idx_type n, R& res)
557 {
559  for (octave_idx_type i = 0; i < n; i++)
560  acc.accum (v[i]);
561 
562  res = acc;
563 }
564 
565 #define DEFINE_XNORM_SPARSE_FUNCS(PREFIX, RTYPE) \
566  OCTAVE_API RTYPE xnorm (const Sparse##PREFIX##Matrix& x, RTYPE p) \
567  { \
568  return matrix_norm (x, p, PREFIX##Matrix ()); \
569  } \
570  OCTAVE_API RTYPE xfrobnorm (const Sparse##PREFIX##Matrix& x) \
571  { \
572  RTYPE res; \
573  array_norm_2 (x.data (), x.nnz (), res); \
574  return res; \
575  }
576 
579 
580 #define DEFINE_COLROW_NORM_FUNCS(PREFIX, RPREFIX, RTYPE) \
581  extern OCTAVE_API RPREFIX##RowVector \
582  xcolnorms (const PREFIX##Matrix& m, RTYPE p) \
583  { \
584  return column_norms (m, p); \
585  } \
586  extern OCTAVE_API RPREFIX##ColumnVector \
587  xrownorms (const PREFIX##Matrix& m, RTYPE p) \
588  { \
589  return row_norms (m, p); \
590  } \
591 
593 DEFINE_COLROW_NORM_FUNCS(Complex, , double)
594 DEFINE_COLROW_NORM_FUNCS(Float, Float, float)
596 
598 DEFINE_COLROW_NORM_FUNCS(SparseComplex, , double)
OCTAVE_API ColumnVector xrownorms(const Matrix &m, double p)
Definition: oct-norm.cc:592
#define DEFINE_XNORM_FUNCS(PREFIX, RTYPE)
Definition: oct-norm.cc:531
Octave interface to the compression and uncompression libraries.
Definition: aepbalance.cc:47
T * data(void)
Definition: Sparse.h:521
octave_idx_type rows(void) const
Definition: Sparse.h:271
#define DEFINE_DISPATCHER(FUNC_NAME, ARG_TYPE, RES_TYPE)
Definition: oct-norm.cc:295
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:5068
VectorT dual_p(const VectorT &x, R p, R q)
Definition: oct-norm.cc:413
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
Definition: lo-error.c:38
void accum(U val)
Definition: oct-norm.cc:198
bool isnan(double x)
Definition: lo-mappers.cc:347
for large enough k
Definition: lu.cc:606
void accum(R val)
Definition: oct-norm.cc:133
static double fi[256]
Definition: randmtzig.cc:440
octave_idx_type * cidx(void)
Definition: Sparse.h:543
octave_idx_type columns(void) const
Definition: Sparse.h:273
#define lo_ieee_isinf(x)
Definition: lo-ieee.h:111
OCTAVE_EXPORT octave_value_list return the number of command line arguments passed to Octave If called with the optional argument the function t
Definition: ov-usr-fcn.cc:935
Template for N-dimensional array classes with like-type math operators.
Definition: MArray.h:32
void accum(U val)
Definition: oct-norm.cc:106
octave_idx_type rows(void) const
Definition: Array.h:401
T elem_dual_p(T x, R p)
Definition: oct-norm.cc:403
static void higham_subp(const ColVectorT &y, const ColVectorT &col, octave_idx_type nsamp, R p, R &lambda, R &mu)
Definition: oct-norm.cc:331
void accum(U val)
Definition: oct-norm.cc:165
static int max_norm_iter
Definition: oct-norm.cc:479
#define DEFINE_COLROW_NORM_FUNCS(PREFIX, RPREFIX, RTYPE)
Definition: oct-norm.cc:580
nd deftypefn *octave_map m
Definition: ov-struct.cc:2058
double max(void) const
Definition: dRowVector.cc:220
OCTAVE_API RowVector xcolnorms(const Matrix &m, double p)
Definition: oct-norm.cc:592
double signum(double x)
Definition: lo-mappers.h:259
static R pow2(R x)
Definition: oct-norm.cc:129
DM_T singular_values(void) const
Definition: svd.h:86
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
norm_accumulator_p(R pp)
Definition: oct-norm.cc:75
R matrix_norm(const MatrixT &m, R p, VectorT)
Definition: oct-norm.cc:510
unsigned int num
Definition: oct-norm.cc:212
static const char * p_less1_gripe
Definition: oct-norm.cc:474
void accum(std::complex< R > val)
Definition: oct-norm.cc:148
void accum(U val)
Definition: oct-norm.cc:216
T & xelem(octave_idx_type n)
Definition: Array.h:455
N Dimensional Array with copy-on-write semantics.
Definition: Array.h:126
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:228
#define Inf
Definition: Faddeeva.cc:247
octave_idx_type * ridx(void)
Definition: Sparse.h:530
double max(void) const
Definition: dColVector.cc:260
#define DEFINE_XNORM_SPARSE_FUNCS(PREFIX, RTYPE)
Definition: oct-norm.cc:565
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
norm_accumulator_mp(R pp)
Definition: oct-norm.cc:103
OCTAVE_EXPORT octave_value_list return the value of the option it must match the dimension of the state and the relative tolerance must also be a vector of the same length tem it must match the dimension of the state and the absolute tolerance must also be a vector of the same length The local error test applied at each integration step is xample roup abs(local error in x(i))<
void array_norm_2(const T *v, octave_idx_type n, R &res)
Definition: oct-norm.cc:556
p
Definition: lu.cc:138
function gamma(X)
Definition: gamma.f:2
void accum(U val)
Definition: oct-norm.cc:78
void row_norms(const MArray< T > &m, MArray< R > &res, ACC acc)
Definition: oct-norm.cc:250
the element is set to zero In other the statement xample y
Definition: data.cc:5342
OCTAVE_EXPORT octave_value_list or N dimensional array whose elements are all equal to the IEEE symbol NaN(Not a Number).NaN is the result of operations which do not produce a well defined 0 result.Common operations which produce a NaN are arithmetic with infinity ex($\infty-\infty $)
void vector_norm(const Array< T > &v, R &res, ACC acc)
Definition: oct-norm.cc:226
R svd_matrix_norm(const MatrixT &m, R p, VectorT)
Definition: oct-norm.cc:483
void accum(U val)
Definition: oct-norm.cc:180
void column_norms(const MArray< T > &m, MArray< R > &res, ACC acc)
Definition: oct-norm.cc:236
std::complex< float > FloatComplex
Definition: oct-cmplx.h:32
R higham(const MatrixT &m, R p, R tol, int maxiter, VectorT &x)
Definition: oct-norm.cc:423
std::complex< double > Complex
Definition: oct-cmplx.h:31
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
octave_idx_type columns(void) const
Definition: Array.h:410
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE * x
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:205