GNU Octave 7.1.0
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-2022 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if defined (HAVE_CONFIG_H)
27# include "config.h"
28#endif
29
30#include "oct-norm.h"
31#include "defun.h"
32#include "error.h"
33#include "errwarn.h"
34
35OCTAVE_NAMESPACE_BEGIN
36
37template <typename ColumnVector, typename Matrix, typename RowVector>
38static void
40{
41 octave_idx_type Vc = V.columns ();
42 h = RowVector (Vc + 1);
43 for (octave_idx_type j = 0; j < Vc; j++)
44 {
45 ColumnVector Vcj = V.column (j);
46 RowVector Vcjh = Vcj.hermitian ();
47 h(j) = Vcjh * x;
48 x -= h(j) * Vcj;
49 }
50
51 h(Vc) = xnorm (x);
52 if (std::real (h(Vc)) > 0)
53 x /= h(Vc);
54}
55
56DEFUN (mgorth, args, ,
57 doc: /* -*- texinfo -*-
58@deftypefn {} {[@var{y}, @var{h}] =} mgorth (@var{x}, @var{v})
59Orthogonalize a given column vector @var{x} with respect to a set of
60orthonormal vectors comprising the columns of @var{v} using the modified
61Gram-Schmidt method.
62
63On exit, @var{y} is a unit vector such that:
64
65@example
66@group
67 norm (@var{y}) = 1
68 @var{v}' * @var{y} = 0
69 @var{x} = [@var{v}, @var{y}]*@var{h}'
70@end group
71@end example
72
73@end deftypefn */)
74{
75 if (args.length () != 2)
76 print_usage ();
77
78 octave_value arg_x = args(0);
79 octave_value arg_v = args(1);
80
81 if (arg_v.ndims () != 2 || arg_x.ndims () != 2 || arg_x.columns () != 1
82 || arg_v.rows () != arg_x.rows ())
83 error ("mgorth: V should be a matrix, and X a column vector with"
84 " the same number of rows as V.");
85
86 if (! arg_x.isnumeric () && ! arg_v.isnumeric ())
87 error ("mgorth: X and V must be numeric");
88
89 octave_value_list retval;
90
91 bool iscomplex = (arg_x.iscomplex () || arg_v.iscomplex ());
92 if (arg_x.is_single_type () || arg_v.is_single_type ())
93 {
94 if (iscomplex)
95 {
100 do_mgorth (x, V, h);
101 retval = ovl (x, h);
102 }
103 else
104 {
108 do_mgorth (x, V, h);
109 retval = ovl (x, h);
110 }
111 }
112 else
113 {
114 if (iscomplex)
115 {
119 do_mgorth (x, V, h);
120 retval = ovl (x, h);
121 }
122 else
123 {
125 Matrix V = arg_v.matrix_value ();
126 RowVector h;
127 do_mgorth (x, V, h);
128 retval = ovl (x, h);
129 }
130 }
131
132 return retval;
133}
134
135/*
136%!test
137%! for ii=1:100
138%! assert (abs (mgorth (randn (5, 1), eye (5, 4))), [0 0 0 0 1]', eps);
139%! endfor
140
141%!test
142%! a = hilb (5);
143%! a(:, 1) /= norm (a(:, 1));
144%! for ii = 1:5
145%! a(:, ii) = mgorth (a(:, ii), a(:, 1:ii-1));
146%! endfor
147%! assert (a' * a, eye (5), 1e10);
148*/
149
150OCTAVE_NAMESPACE_END
MArray< T > hermitian(T(*fcn)(const T &)=nullptr) const
Definition: MArray.h:102
Definition: dMatrix.h:42
ComplexMatrix complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:916
octave_idx_type rows(void) const
Definition: ov.h:590
bool isnumeric(void) const
Definition: ov.h:795
OCTINTERP_API FloatComplexColumnVector float_complex_column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
octave_idx_type columns(void) const
Definition: ov.h:592
OCTINTERP_API ColumnVector column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
int ndims(void) const
Definition: ov.h:596
FloatMatrix float_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:901
bool is_single_type(void) const
Definition: ov.h:743
OCTINTERP_API ComplexColumnVector complex_column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
Matrix matrix_value(bool frc_str_conv=false) const
Definition: ov.h:898
FloatComplexMatrix float_complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:920
bool iscomplex(void) const
Definition: ov.h:786
OCTINTERP_API FloatColumnVector float_column_vector_value(bool frc_str_conv=false, bool frc_vec_conv=false) const
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:137
OCTINTERP_API void print_usage(void)
Definition: defun-int.h:72
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
void error(const char *fmt,...)
Definition: error.cc:980
F77_RET_T const F77_INT const F77_INT const F77_INT const F77_DBLE const F77_DBLE F77_INT F77_DBLE * V
F77_RET_T const F77_DBLE * x
static OCTAVE_NAMESPACE_BEGIN void do_mgorth(ColumnVector &x, const Matrix &V, RowVector &h)
Definition: mgorth.cc:39
class OCTAVE_API RowVector
Definition: mx-fwd.h:50
double xnorm(const ColumnVector &x, double p)
Definition: oct-norm.cc:585
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211