GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
sylvester.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-2024 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 "defun.h"
31 #include "error.h"
32 #include "errwarn.h"
33 #include "ovl.h"
34 
36 
37 DEFUN (sylvester, args, ,
38  doc: /* -*- texinfo -*-
39 @deftypefn {} {@var{X} =} sylvester (@var{A}, @var{B}, @var{C})
40 Solve the Sylvester equation.
41 
42 The Sylvester equation is defined as:
43 @tex
44 $$
45  A X + X B = C
46 $$
47 @end tex
48 @ifnottex
49 
50 @example
51 A X + X B = C
52 @end example
53 
54 @end ifnottex
55 The solution is computed using standard @sc{lapack} subroutines.
56 
57 For example:
58 
59 @example
60 @group
61 sylvester ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12])
62  @result{} [ 0.50000, 0.66667; 0.66667, 0.50000 ]
63 @end group
64 @end example
65 @end deftypefn */)
66 {
67  if (args.length () != 3)
68  print_usage ();
69 
70  octave_value retval;
71 
72  octave_value arg_a = args(0);
73  octave_value arg_b = args(1);
74  octave_value arg_c = args(2);
75 
76  octave_idx_type a_nr = arg_a.rows ();
77  octave_idx_type a_nc = arg_a.columns ();
78 
79  octave_idx_type b_nr = arg_b.rows ();
80  octave_idx_type b_nc = arg_b.columns ();
81 
82  octave_idx_type c_nr = arg_c.rows ();
83  octave_idx_type c_nc = arg_c.columns ();
84 
85  bool isfloat = arg_a.is_single_type ()
86  || arg_b.is_single_type ()
87  || arg_c.is_single_type ();
88 
89  if (arg_a.isempty () || arg_b.isempty () || arg_c.isempty ())
90  {
91  if (isfloat)
92  return ovl (FloatMatrix ());
93  else
94  return ovl (Matrix ());
95  }
96 
97  // Arguments are not empty, so check for correct dimensions.
98 
99  if (a_nr != a_nc)
100  err_square_matrix_required ("sylvester", "A");
101  if (b_nr != b_nc)
102  err_square_matrix_required ("sylvester", "B");
103  if (a_nr != c_nr || b_nr != c_nc)
105 
106  if (isfloat)
107  {
108  if (arg_a.iscomplex ()
109  || arg_b.iscomplex ()
110  || arg_c.iscomplex ())
111  {
112  // Do everything in complex arithmetic;
113 
117 
118  retval = Sylvester (ca, cb, cc);
119  }
120  else
121  {
122  // Do everything in real arithmetic.
123 
124  FloatMatrix ca = arg_a.float_matrix_value ();
125  FloatMatrix cb = arg_b.float_matrix_value ();
126  FloatMatrix cc = arg_c.float_matrix_value ();
127 
128  retval = Sylvester (ca, cb, cc);
129  }
130  }
131  else
132  {
133  if (arg_a.iscomplex ()
134  || arg_b.iscomplex ()
135  || arg_c.iscomplex ())
136  {
137  // Do everything in complex arithmetic;
138 
139  ComplexMatrix ca = arg_a.complex_matrix_value ();
140  ComplexMatrix cb = arg_b.complex_matrix_value ();
141  ComplexMatrix cc = arg_c.complex_matrix_value ();
142 
143  retval = Sylvester (ca, cb, cc);
144  }
145  else
146  {
147  // Do everything in real arithmetic.
148 
149  Matrix ca = arg_a.matrix_value ();
150  Matrix cb = arg_b.matrix_value ();
151  Matrix cc = arg_c.matrix_value ();
152 
153  retval = Sylvester (ca, cb, cc);
154  }
155  }
156 
157  return retval;
158 }
159 
160 /*
161 %!assert (sylvester ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12]),
162 %! [1/2, 2/3; 2/3, 1/2], sqrt (eps))
163 %!assert (sylvester (single ([1, 2; 3, 4]), single ([5, 6; 7, 8]), single ([9, 10; 11, 12])),
164 %! single ([1/2, 2/3; 2/3, 1/2]), sqrt (eps ("single")))
165 
166 ## Test input validation
167 %!error sylvester ()
168 %!error sylvester (1)
169 %!error sylvester (1,2)
170 %!error sylvester (1, 2, 3, 4)
171 %!error <A must be a square matrix> sylvester (ones (2,3), ones (2,2), ones (2,2))
172 %!error <B must be a square matrix> sylvester (ones (2,2), ones (2,3), ones (2,2))
173 %!error <nonconformant matrices> sylvester (ones (2,2), ones (2,2), ones (3,3))
174 */
175 
176 OCTAVE_END_NAMESPACE(octave)
ComplexMatrix Sylvester(const ComplexMatrix &a, const ComplexMatrix &b, const ComplexMatrix &c)
Definition: CMatrix.cc:3248
Definition: dMatrix.h:42
octave_idx_type rows() const
Definition: ov.h:545
ComplexMatrix complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:871
bool is_single_type() const
Definition: ov.h:698
bool isempty() const
Definition: ov.h:601
FloatMatrix float_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:856
bool iscomplex() const
Definition: ov.h:741
octave_idx_type columns() const
Definition: ov.h:547
Matrix matrix_value(bool frc_str_conv=false) const
Definition: ov.h:853
FloatComplexMatrix float_complex_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:875
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
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 err_square_matrix_required(const char *fcn, const char *name)
Definition: errwarn.cc:122
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:219