GNU Octave  3.8.0
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
syl.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2013 John W. Eaton
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: A. S. Hodel <scotte@eng.auburn.edu>
24 
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28 
29 #include "defun.h"
30 #include "error.h"
31 #include "gripes.h"
32 #include "oct-obj.h"
33 #include "utils.h"
34 
35 DEFUN (syl, args, nargout,
36  "-*- texinfo -*-\n\
37 @deftypefn {Built-in Function} {@var{x} =} syl (@var{A}, @var{B}, @var{C})\n\
38 Solve the Sylvester equation\n\
39 @tex\n\
40 $$\n\
41  A X + X B + C = 0\n\
42 $$\n\
43 @end tex\n\
44 @ifnottex\n\
45 \n\
46 @example\n\
47 A X + X B + C = 0\n\
48 @end example\n\
49 \n\
50 @end ifnottex\n\
51 using standard @sc{lapack} subroutines. For example:\n\
52 \n\
53 @example\n\
54 @group\n\
55 syl ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12])\n\
56  @result{} [ -0.50000, -0.66667; -0.66667, -0.50000 ]\n\
57 @end group\n\
58 @end example\n\
59 @end deftypefn")
60 {
61  octave_value retval;
62 
63  int nargin = args.length ();
64 
65  if (nargin != 3 || nargout > 1)
66  {
67  print_usage ();
68  return retval;
69  }
70 
71  octave_value arg_a = args(0);
72  octave_value arg_b = args(1);
73  octave_value arg_c = args(2);
74 
75  octave_idx_type a_nr = arg_a.rows ();
76  octave_idx_type a_nc = arg_a.columns ();
77 
78  octave_idx_type b_nr = arg_b.rows ();
79  octave_idx_type b_nc = arg_b.columns ();
80 
81  octave_idx_type c_nr = arg_c.rows ();
82  octave_idx_type c_nc = arg_c.columns ();
83 
84  int arg_a_is_empty = empty_arg ("syl", a_nr, a_nc);
85  int arg_b_is_empty = empty_arg ("syl", b_nr, b_nc);
86  int arg_c_is_empty = empty_arg ("syl", c_nr, c_nc);
87 
88  bool isfloat = arg_a.is_single_type () || arg_b.is_single_type ()
89  || arg_c.is_single_type ();
90 
91  if (arg_a_is_empty > 0 && arg_b_is_empty > 0 && arg_c_is_empty > 0)
92  if (isfloat)
93  return octave_value (FloatMatrix ());
94  else
95  return octave_value (Matrix ());
96  else if (arg_a_is_empty || arg_b_is_empty || arg_c_is_empty)
97  return retval;
98 
99  // Arguments are not empty, so check for correct dimensions.
100 
101  if (a_nr != a_nc || b_nr != b_nc)
102  {
103  gripe_square_matrix_required ("syl: first two parameters:");
104  return retval;
105  }
106  else if (a_nr != c_nr || b_nr != c_nc)
107  {
109  return retval;
110  }
111 
112  // Dimensions look o.k., let's solve the problem.
113  if (isfloat)
114  {
115  if (arg_a.is_complex_type ()
116  || arg_b.is_complex_type ()
117  || arg_c.is_complex_type ())
118  {
119  // Do everything in complex arithmetic;
120 
122 
123  if (error_state)
124  return retval;
125 
127 
128  if (error_state)
129  return retval;
130 
132 
133  if (error_state)
134  return retval;
135 
136  retval = Sylvester (ca, cb, cc);
137  }
138  else
139  {
140  // Do everything in real arithmetic.
141 
142  FloatMatrix ca = arg_a.float_matrix_value ();
143 
144  if (error_state)
145  return retval;
146 
147  FloatMatrix cb = arg_b.float_matrix_value ();
148 
149  if (error_state)
150  return retval;
151 
152  FloatMatrix cc = arg_c.float_matrix_value ();
153 
154  if (error_state)
155  return retval;
156 
157  retval = Sylvester (ca, cb, cc);
158  }
159  }
160  else
161  {
162  if (arg_a.is_complex_type ()
163  || arg_b.is_complex_type ()
164  || arg_c.is_complex_type ())
165  {
166  // Do everything in complex arithmetic;
167 
168  ComplexMatrix ca = arg_a.complex_matrix_value ();
169 
170  if (error_state)
171  return retval;
172 
173  ComplexMatrix cb = arg_b.complex_matrix_value ();
174 
175  if (error_state)
176  return retval;
177 
178  ComplexMatrix cc = arg_c.complex_matrix_value ();
179 
180  if (error_state)
181  return retval;
182 
183  retval = Sylvester (ca, cb, cc);
184  }
185  else
186  {
187  // Do everything in real arithmetic.
188 
189  Matrix ca = arg_a.matrix_value ();
190 
191  if (error_state)
192  return retval;
193 
194  Matrix cb = arg_b.matrix_value ();
195 
196  if (error_state)
197  return retval;
198 
199  Matrix cc = arg_c.matrix_value ();
200 
201  if (error_state)
202  return retval;
203 
204  retval = Sylvester (ca, cb, cc);
205  }
206  }
207 
208  return retval;
209 }
210 
211 /*
212 %!assert (syl ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12]), [-1/2, -2/3; -2/3, -1/2], sqrt (eps))
213 %!assert (syl (single ([1, 2; 3, 4]), single ([5, 6; 7, 8]), single ([9, 10; 11, 12])), single ([-1/2, -2/3; -2/3, -1/2]), sqrt (eps ("single")))
214 
215 %!error syl ()
216 %!error syl (1, 2, 3, 4)
217 %!error <must be a square matrix> syl ([1, 2; 3, 4], [1, 2, 3; 4, 5, 6], [4, 3])
218 */