Mercurial > forge
view extra/control-devel/src/slitest.cc @ 9911:92e41d7346ca octave-forge
control-devel: update debugging stuff for ib01ad
author | paramaniac |
---|---|
date | Thu, 29 Mar 2012 15:33:41 +0000 |
parents | ea2023de7d8f |
children | 6d530850180c |
line wrap: on
line source
/* Copyright (C) 2012 Lukas F. Reichlin This file is part of LTI Syncope. LTI Syncope is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. LTI Syncope is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with LTI Syncope. If not, see <http://www.gnu.org/licenses/>. SLICOT system identification Uses SLICOT IB01AD, IB01BD and IB01CD by courtesy of NICONET e.V. <http://www.slicot.org> Author: Lukas Reichlin <lukas.reichlin@gmail.com> Created: March 2012 Version: 0.1 */ #include <octave/oct.h> #include <f77-fcn.h> #include "common.h" extern "C" { int F77_FUNC (ib01ad, IB01AD) (char& METH, char& ALG, char& JOBD, char& BATCH, char& CONCT, char& CTRL, int& NOBR, int& M, int& L, int& NSMP, double* U, int& LDU, double* Y, int& LDY, int& N, double* R, int& LDR, double* SV, double& RCOND, double& TOL, int* IWORK, double* DWORK, int& LDWORK, int& IWARN, int& INFO); int F77_FUNC (ib01bd, IB01BD) (char& METH, char& JOB, char& JOBCK, int& NOBR, int& N, int& M, int& L, int& NSMPL, double* R, int& LDR, double* A, int& LDA, double* C, int& LDC, double* B, int& LDB, double* D, int& LDD, double* Q, int& LDQ, double* RY, int& LDRY, double* S, int& LDS, double* K, int& LDK, double& TOL, int* IWORK, double* DWORK, int& LDWORK, bool* BWORK, int& IWARN, int& INFO); int F77_FUNC (ib01cd, IB01CD) (char& JOBX0, char& COMUSE, char& JOB, int& N, int& M, int& L, int& NSMP, double* A, int& LDA, double* B, int& LDB, double* C, int& LDC, double* D, int& LDD, double* U, int& LDU, double* Y, int& LDY, double* X0, double* V, int& LDV, double& TOL, int* IWORK, double* DWORK, int& LDWORK, int& IWARN, int& INFO); } // PKG_ADD: autoload ("slitest", "devel_slicot_functions.oct"); DEFUN_DLD (slitest, args, nargout, "-*- texinfo -*-\n\ Slicot IB01AD Release 5.0\n\ No argument checking.\n\ For internal use only.") { int nargin = args.length (); octave_value_list retval; if (nargin != 4) { print_usage (); } else { //////////////////////////////////////////////////////////////////////////////////// // SLICOT IB01AD - preprocess the input-output data // //////////////////////////////////////////////////////////////////////////////////// // arguments in char meth = 'N'; // <--- not used, use metha char alg = 'C'; char jobd = 'N'; char batch = 'O'; char conct = 'N'; char ctrl = 'N'; char metha = 'N'; // ??? char jobda ; Matrix y = args(0).matrix_value (); Matrix u = args(1).matrix_value (); int nobr = args(2).int_value (); double rcond = 0.0; double tol = -1.0; int ldwork = args(3).int_value (); int m = u.columns (); // m: number of inputs int l = y.columns (); // l: number of outputs int nsmp = y.rows (); // nsmp: number of samples // y.rows == u.rows is checked by iddata class // TODO: check minimal nsmp size int ldu = nsmp; int ldy = nsmp; // arguments out int n; int ldr; if (metha == 'M' && jobd == 'M') ldr = max (2*(m+l)*nobr, 3*m*nobr); else if (metha == 'N' || (metha == 'M' && jobd == 'N')) ldr = 2*(m+l)*nobr; else error ("slib01ad: could not handle 'ldr' case"); Matrix r (ldr, 2*(m+l)*nobr); ColumnVector sv (l*nobr); // workspace int liwork; if (metha == 'N') // if METH = 'N' liwork = (m+l)*nobr; else if (alg == 'F') // if METH = 'M' and ALG = 'F' liwork = m+l; else // if METH = 'M' and ALG = 'C' or 'Q' liwork = 0; // TODO: Handle 'k' for DWORK /* int ldwork; if (alg == 'C') { if (batch == 'F' || batch == 'I') { if (conct == 'C') ldwork = (4*nobr-2)*(m+l); else // (conct == 'N') ldwork = 1; } else if (metha == 'M') // && (batch == 'L' || batch == 'O') { if (conct == 'C' && batch == 'L') ldwork = max ((4*nobr-2)*(m+l), 5*l*nobr); else if (jobd == 'M') ldwork = max ((2*m-1)*nobr, (m+l)*nobr, 5*l*nobr); else // (jobd == 'N') ldwork = 5*l*nobr; } else // meth == 'N' && (batch == 'L' || batch == 'O') { ldwork = 5*(m+l)*nobr + 1; } } else if (alg == 'F') { if (batch != 'O' && conct == 'C') ldwork = (m+l)*2*nobr*(m+l+3); else if (batch == 'F' || batch == 'I') // && conct == 'N' ldwork = (m+l)*2*nobr*(m+l+1); else // (batch == 'L' || '0' && conct == 'N') ldwork = (m+l)*4*nobr*(m+l+1)+(m+l)*2*nobr; } else // (alg == 'Q') { int ns = nsmp - 2*nobr + 1; if (ldr >= ns && batch == 'F') { ldwork = 4*(m+l)*nobr; } else if (ldr >= ns && batch == 'O') { if (metha == 'M') ldwork = max (4*(m+l)*nobr, 5*l*nobr); else // (meth == 'N') ldwork = 5*(m+l)*nobr + 1; } else if (conct == 'C' && (batch == 'I' || batch == 'L')) { ldwork = 4*(nobr+1)*(m+l)*nobr; } else // if ALG = 'Q', (BATCH = 'F' or 'O', and LDR < NS), or (BATCH = 'I' or 'L' and CONCT = 'N') { ldwork = 6*(m+l)*nobr; } } //////////////////////////////////////////////////////////////////// // TO BE REMOVED !!! //////////////////////////////////////////////////////////////////// ldwork *= 2; //ldwork = 1000000; //////////////////////////////////////////////////////////////////// */ OCTAVE_LOCAL_BUFFER (int, iwork, liwork); OCTAVE_LOCAL_BUFFER (double, dwork, ldwork); // error indicators int iwarn = 0; int info = 0; // SLICOT routine IB01AD F77_XFCN (ib01ad, IB01AD, (metha, alg, jobd, batch, conct, ctrl, nobr, m, l, nsmp, u.fortran_vec (), ldu, y.fortran_vec (), ldy, n, r.fortran_vec (), ldr, sv.fortran_vec (), rcond, tol, iwork, dwork, ldwork, iwarn, info)); if (f77_exception_encountered) error ("ident: exception in SLICOT subroutine IB01AD"); static const char* err_msg[] = { "0: OK", "1: a fast algorithm was requested (ALG = 'C', or 'F') " "in sequential data processing, but it failed; the " "routine can be repeatedly called again using the " "standard QR algorithm", "2: the singular value decomposition (SVD) algorithm did " "not converge"}; static const char* warn_msg[] = { "0: OK", "1: the number of 100 cycles in sequential data " "processing has been exhausted without signaling " "that the last block of data was get; the cycle " "counter was reinitialized", "2: a fast algorithm was requested (ALG = 'C' or 'F'), " "but it failed, and the QR algorithm was then used " "(non-sequential data processing)", "3: all singular values were exactly zero, hence N = 0 " "(both input and output were identically zero)", "4: the least squares problems with coefficient matrix " "U_f, used for computing the weighted oblique " "projection (for METH = 'N'), have a rank-deficient " "coefficient matrix", "5: the least squares problem with coefficient matrix " "r_1 [6], used for computing the weighted oblique " "projection (for METH = 'N'), has a rank-deficient " "coefficient matrix"}; error_msg ("ident", info, 2, err_msg); warning_msg ("ident", iwarn, 5, warn_msg); // resize int rs = 2*(m+l)*nobr; r.resize (rs, rs); retval(0) = r; retval(1) = sv; retval(2) = octave_value (n); } return retval; }