syl.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 // Author: A. S. Hodel <scotte@eng.auburn.edu>
00024 
00025 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028 
00029 #include "defun-dld.h"
00030 #include "error.h"
00031 #include "gripes.h"
00032 #include "oct-obj.h"
00033 #include "utils.h"
00034 
00035 DEFUN_DLD (syl, args, nargout,
00036   "-*- texinfo -*-\n\
00037 @deftypefn {Loadable Function} {@var{x} =} syl (@var{A}, @var{B}, @var{C})\n\
00038 Solve the Sylvester equation\n\
00039 @tex\n\
00040 $$\n\
00041  A X + X B + C = 0\n\
00042 $$\n\
00043 @end tex\n\
00044 @ifnottex\n\
00045 \n\
00046 @example\n\
00047 A X + X B + C = 0\n\
00048 @end example\n\
00049 \n\
00050 @end ifnottex\n\
00051 using standard @sc{lapack} subroutines.  For example:\n\
00052 \n\
00053 @example\n\
00054 @group\n\
00055 syl ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12])\n\
00056      @result{} [ -0.50000, -0.66667; -0.66667, -0.50000 ]\n\
00057 @end group\n\
00058 @end example\n\
00059 @end deftypefn")
00060 {
00061   octave_value retval;
00062 
00063   int nargin = args.length ();
00064 
00065   if (nargin != 3 || nargout > 1)
00066     {
00067       print_usage ();
00068       return retval;
00069     }
00070 
00071   octave_value arg_a = args(0);
00072   octave_value arg_b = args(1);
00073   octave_value arg_c = args(2);
00074 
00075   octave_idx_type a_nr = arg_a.rows ();
00076   octave_idx_type a_nc = arg_a.columns ();
00077 
00078   octave_idx_type b_nr = arg_b.rows ();
00079   octave_idx_type b_nc = arg_b.columns ();
00080 
00081   octave_idx_type c_nr = arg_c.rows ();
00082   octave_idx_type c_nc = arg_c.columns ();
00083 
00084   int arg_a_is_empty = empty_arg ("syl", a_nr, a_nc);
00085   int arg_b_is_empty = empty_arg ("syl", b_nr, b_nc);
00086   int arg_c_is_empty = empty_arg ("syl", c_nr, c_nc);
00087 
00088   bool isfloat = arg_a.is_single_type () || arg_b.is_single_type () ||
00089     arg_c.is_single_type ();
00090 
00091   if (arg_a_is_empty > 0 && arg_b_is_empty > 0 && arg_c_is_empty > 0)
00092     if (isfloat)
00093       return octave_value (FloatMatrix ());
00094     else
00095       return octave_value (Matrix ());
00096   else if (arg_a_is_empty || arg_b_is_empty || arg_c_is_empty)
00097     return retval;
00098 
00099   // Arguments are not empty, so check for correct dimensions.
00100 
00101   if (a_nr != a_nc || b_nr != b_nc)
00102     {
00103       gripe_square_matrix_required ("syl: first two parameters:");
00104       return retval;
00105     }
00106   else if (a_nr != c_nr || b_nr != c_nc)
00107     {
00108       gripe_nonconformant ();
00109       return retval;
00110     }
00111 
00112   // Dimensions look o.k., let's solve the problem.
00113   if (isfloat)
00114     {
00115       if (arg_a.is_complex_type ()
00116           || arg_b.is_complex_type ()
00117           || arg_c.is_complex_type ())
00118         {
00119           // Do everything in complex arithmetic;
00120 
00121           FloatComplexMatrix ca = arg_a.float_complex_matrix_value ();
00122 
00123           if (error_state)
00124             return retval;
00125 
00126           FloatComplexMatrix cb = arg_b.float_complex_matrix_value ();
00127 
00128           if (error_state)
00129             return retval;
00130 
00131           FloatComplexMatrix cc = arg_c.float_complex_matrix_value ();
00132 
00133           if (error_state)
00134             return retval;
00135 
00136           retval = Sylvester (ca, cb, cc);
00137         }
00138       else
00139         {
00140           // Do everything in real arithmetic.
00141 
00142           FloatMatrix ca = arg_a.float_matrix_value ();
00143 
00144           if (error_state)
00145             return retval;
00146 
00147           FloatMatrix cb = arg_b.float_matrix_value ();
00148 
00149           if (error_state)
00150             return retval;
00151 
00152           FloatMatrix cc = arg_c.float_matrix_value ();
00153 
00154           if (error_state)
00155             return retval;
00156 
00157           retval = Sylvester (ca, cb, cc);
00158         }
00159     }
00160   else
00161     {
00162       if (arg_a.is_complex_type ()
00163           || arg_b.is_complex_type ()
00164           || arg_c.is_complex_type ())
00165         {
00166           // Do everything in complex arithmetic;
00167 
00168           ComplexMatrix ca = arg_a.complex_matrix_value ();
00169 
00170           if (error_state)
00171             return retval;
00172 
00173           ComplexMatrix cb = arg_b.complex_matrix_value ();
00174 
00175           if (error_state)
00176             return retval;
00177 
00178           ComplexMatrix cc = arg_c.complex_matrix_value ();
00179 
00180           if (error_state)
00181             return retval;
00182 
00183           retval = Sylvester (ca, cb, cc);
00184         }
00185       else
00186         {
00187           // Do everything in real arithmetic.
00188 
00189           Matrix ca = arg_a.matrix_value ();
00190 
00191           if (error_state)
00192             return retval;
00193 
00194           Matrix cb = arg_b.matrix_value ();
00195 
00196           if (error_state)
00197             return retval;
00198 
00199           Matrix cc = arg_c.matrix_value ();
00200 
00201           if (error_state)
00202             return retval;
00203 
00204           retval = Sylvester (ca, cb, cc);
00205         }
00206     }
00207 
00208   return retval;
00209 }
00210 
00211 /*
00212 
00213 %!assert(syl ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12]), [-1/2, -2/3; -2/3, -1/2], sqrt (eps));
00214 %!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')));
00215 
00216 %!error <Invalid call to syl> syl ();
00217 %!error <Invalid call to syl> syl (1, 2, 3, 4);
00218 %!error syl ([1, 2; 3, 4], [1, 2, 3; 4, 5, 6], [4, 3]);
00219 
00220 */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines