GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
mgorth.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2009-2018 Carlo de Falco
4 Copyright (C) 2010 VZLU Prague
5 
6 This file is part of Octave.
7 
8 Octave is free software: you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <https://www.gnu.org/licenses/>.
21 
22 */
23 
24 #if defined (HAVE_CONFIG_H)
25 # include "config.h"
26 #endif
27 
28 #include "oct-norm.h"
29 #include "defun.h"
30 #include "error.h"
31 #include "errwarn.h"
32 
33 template <typename ColumnVector, typename Matrix, typename RowVector>
34 static void
36 {
37  octave_idx_type Vc = V.columns ();
38  h = RowVector (Vc + 1);
39  for (octave_idx_type j = 0; j < Vc; j++)
40  {
41  ColumnVector Vcj = V.column (j);
42  h(j) = RowVector (Vcj.hermitian ()) * x;
43  x -= h(j) * Vcj;
44  }
45 
46  h(Vc) = xnorm (x);
47  if (std::real (h(Vc)) > 0)
48  x /= h(Vc);
49 }
50 
51 DEFUN (mgorth, args, ,
52  doc: /* -*- texinfo -*-
53 @deftypefn {} {[@var{y}, @var{h}] =} mgorth (@var{x}, @var{v})
54 Orthogonalize a given column vector @var{x} with respect to a set of
55 orthonormal vectors comprising the columns of @var{v} using the modified
56 Gram-Schmidt method.
57 
58 On exit, @var{y} is a unit vector such that:
59 
60 @example
61 @group
62  norm (@var{y}) = 1
63  @var{v}' * @var{y} = 0
64  @var{x} = [@var{v}, @var{y}]*@var{h}'
65 @end group
66 @end example
67 
68 @end deftypefn */)
69 {
70  if (args.length () != 2)
71  print_usage ();
72 
73  octave_value arg_x = args(0);
74  octave_value arg_v = args(1);
75 
76  if (arg_v.ndims () != 2 || arg_x.ndims () != 2 || arg_x.columns () != 1
77  || arg_v.rows () != arg_x.rows ())
78  error ("mgorth: V should be a matrix, and X a column vector with"
79  " the same number of rows as V.");
80 
81  if (! arg_x.isnumeric () && ! arg_v.isnumeric ())
82  error ("mgorth: X and V must be numeric");
83 
85 
86  bool iscomplex = (arg_x.iscomplex () || arg_v.iscomplex ());
87  if (arg_x.is_single_type () || arg_v.is_single_type ())
88  {
89  if (iscomplex)
90  {
95  do_mgorth (x, V, h);
96  retval = ovl (x, h);
97  }
98  else
99  {
101  FloatMatrix V = arg_v.float_matrix_value ();
103  do_mgorth (x, V, h);
104  retval = ovl (x, h);
105  }
106  }
107  else
108  {
109  if (iscomplex)
110  {
114  do_mgorth (x, V, h);
115  retval = ovl (x, h);
116  }
117  else
118  {
120  Matrix V = arg_v.matrix_value ();
121  RowVector h;
122  do_mgorth (x, V, h);
123  retval = ovl (x, h);
124  }
125  }
126 
127  return retval;
128 }
129 
130 /*
131 %!test
132 %! for ii=1:100
133 %! assert (abs (mgorth (randn (5, 1), eye (5, 4))), [0 0 0 0 1]', eps);
134 %! endfor
135 
136 %!test
137 %! a = hilb (5);
138 %! a(:, 1) /= norm (a(:, 1));
139 %! for ii = 1:5
140 %! a(:, ii) = mgorth (a(:, ii), a(:, 1:ii-1));
141 %! endfor
142 %! assert (a' * a, eye (5), 1e10);
143 */
F77_RET_T const F77_INT const F77_INT const F77_INT const F77_DBLE const F77_DBLE F77_INT F77_DBLE * V
FloatComplexColumnVector float_complex_column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
MArray< T > hermitian(T(*fcn)(const T &)=nullptr) const
Definition: MArray.h:106
OCTINTERP_API void print_usage(void)
Definition: defun.cc:54
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:53
void error(const char *fmt,...)
Definition: error.cc:578
FloatMatrix float_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:837
int ndims(void) const
Definition: ov.h:478
static void do_mgorth(ColumnVector &x, const Matrix &V, RowVector &h)
Definition: mgorth.cc:35
FloatComplexMatrix float_complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:856
double h
Definition: graphics.cc:11808
octave_idx_type columns(void) const
Definition: ov.h:474
bool is_single_type(void) const
Definition: ov.h:651
ComplexColumnVector complex_column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
octave_idx_type rows(void) const
Definition: ov.h:472
octave_value retval
Definition: data.cc:6246
OCTAVE_API double xnorm(const ColumnVector &x, double p)
Definition: oct-norm.cc:550
Definition: dMatrix.h:36
FloatColumnVector float_column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).isinteger())
ColumnVector column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
bool iscomplex(void) const
Definition: ov.h:710
ComplexMatrix complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:852
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:135
bool isnumeric(void) const
Definition: ov.h:723
Matrix matrix_value(bool frc_str_conv=false) const
Definition: ov.h:834
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 const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T const F77_DBLE * x