changeset 10271:2cdd5eed2769 octave-forge

control-devel: work on multi-experiment identification
author paramaniac
date Fri, 18 May 2012 16:04:20 +0000
parents c40aea585f21
children 48db51e91ef4
files extra/control-devel/src/slident.cc
diffstat 1 files changed, 175 insertions(+), 155 deletions(-) [+]
line wrap: on
line diff
--- a/extra/control-devel/src/slident.cc	Fri May 18 15:01:56 2012 +0000
+++ b/extra/control-devel/src/slident.cc	Fri May 18 16:04:20 2012 +0000
@@ -28,7 +28,8 @@
 */
 
 #include <octave/oct.h>
-#include <f77-fcn.h>
+#include <octave/f77-fcn.h>
+#include <octave/Cell.h>
 #include "common.h"
 
 extern "C"
@@ -114,14 +115,16 @@
         char conct;
         char ctrl;
         
-        Matrix y = args(0).matrix_value ();
-        Matrix u = args(1).matrix_value ();
+        const Cell y_cell = args(0).cell_value ();
+        const Cell u_cell = args(1).cell_value ();
+        //Matrix y = args(0).matrix_value ();
+        //Matrix u = args(1).matrix_value ();
         int nobr = args(2).int_value ();
         int nuser = args(3).int_value ();
         
         const int imeth = args(4).int_value ();
         const int ialg = args(5).int_value ();
-        const int ibatch = args(6).int_value ();
+        // const int ibatch = args(6).int_value (); // löschen
         const int iconct = args(7).int_value ();
         const int ictrl = args(8).int_value ();
         
@@ -169,24 +172,6 @@
             jobd = 'M';
         else                    // meth_a == 'N'
             jobd = 'N';         // IB01AD.f says: This parameter is not relevant for METH = 'N'
-      
-        switch (ibatch)
-        {
-            case 0:
-                batch = 'F';
-                break;
-            case 1:
-                batch = 'I';
-                break;
-            case 2:
-                batch = 'L';
-                break;
-            case 3:
-                batch = 'O';
-                break;
-            default:
-                error ("slib01ad: argument 'batch' invalid");
-        }
 
         if (iconct == 0)
             conct = 'C';
@@ -199,31 +184,10 @@
             ctrl = 'N';
 
 
-        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 n_exp = y_cell.nelem ();    // number of experiments
         
-        if (batch == 'O')
-        {
-            if (nsmp < 2*(m+l+1)*nobr - 1)
-                error ("slident: require NSMP >= 2*(M+L+1)*NOBR - 1");
-        }
-        else
-        {
-            if (nsmp < 2*nobr)
-                error ("slident: require NSMP >= 2*NOBR");
-        }
-        
-        int ldu;
-        
-        if (m == 0)
-            ldu = 1;
-        else                    // m > 0
-            ldu = nsmp;
-
-        int ldy = nsmp;
+        int m = u_cell.elem(0).columns ();   // m: number of inputs
+        int l = y_cell.elem(0).columns ();   // l: number of outputs
 
         // arguments out
         int n;
@@ -239,77 +203,132 @@
         Matrix r (ldr, 2*(m+l)*nobr);
         ColumnVector sv (l*nobr);
 
-        // workspace
-        int liwork_a;
 
-        if (meth_a == 'N')            // if METH = 'N'
-            liwork_a = (m+l)*nobr;
-        else if (alg == 'F')        // if METH = 'M' and ALG = 'F'
-            liwork_a = m+l;
-        else                        // if METH = 'M' and ALG = 'C' or 'Q'
-            liwork_a = 0;
-
-        // TODO: Handle 'k' for DWORK
-
-        int ldwork_a;
-        int ns = nsmp - 2*nobr + 1;
-        
-        if (alg == 'C')
+        for (int i = 0; i < n_exp; i++)
         {
-            if (batch == 'F' || batch == 'I')
-            {
-                if (conct == 'C')
-                    ldwork_a = (4*nobr-2)*(m+l);
-                else    // (conct == 'N')
-                    ldwork_a = 1;
-            }
-            else if (meth_a == 'M')   // && (batch == 'L' || batch == 'O')
+            if (n_exp == 1)
+                batch = 'O';        // one block only
+            else if (i == 0)
+                batch = 'F';        // first block
+            else if (i == n_exp-1)
+                batch = 'L';        // last block
+            else
+                batch = 'I';        // intermediate block
+      
+            Matrix y = y_cell.elem(i).matrix_value ();
+            Matrix u = u_cell.elem(i).matrix_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
+        
+            if (batch == 'O')
             {
-                if (conct == 'C' && batch == 'L')
-                    ldwork_a = max ((4*nobr-2)*(m+l), 5*l*nobr);
-                else if (jobd == 'M')
-                    ldwork_a = max ((2*m-1)*nobr, (m+l)*nobr, 5*l*nobr);
-                else    // (jobd == 'N')
-                    ldwork_a = 5*l*nobr;
+                if (nsmp < 2*(m+l+1)*nobr - 1)
+                    error ("slident: require NSMP >= 2*(M+L+1)*NOBR - 1");
             }
-            else    // meth_b == 'N' && (batch == 'L' || batch == 'O')
+            else
             {
-                ldwork_a = 5*(m+l)*nobr + 1;
+                if (nsmp < 2*nobr)
+                    error ("slident: require NSMP >= 2*NOBR");
             }
-        }
-        else if (alg == 'F')
-        {
-            if (batch != 'O' && conct == 'C')
-                ldwork_a = (m+l)*2*nobr*(m+l+3);
-            else if (batch == 'F' || batch == 'I')  // && conct == 'N'
-                ldwork_a = (m+l)*2*nobr*(m+l+1);
-            else    // (batch == 'L' || '0' && conct == 'N')
-                ldwork_a = (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')
+        
+            int ldu;
+        
+            if (m == 0)
+                ldu = 1;
+            else                    // m > 0
+                ldu = nsmp;
+
+            int ldy = nsmp;
+/*
+        // arguments out
+        int n;
+        int ldr;
+        
+        if (meth_a == 'M' && jobd == 'M')
+            ldr = max (2*(m+l)*nobr, 3*m*nobr);
+        else if (meth_a == 'N' || (meth_a == '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_a;
+
+            if (meth_a == 'N')            // if METH = 'N'
+                liwork_a = (m+l)*nobr;
+            else if (alg == 'F')        // if METH = 'M' and ALG = 'F'
+                liwork_a = m+l;
+            else                        // if METH = 'M' and ALG = 'C' or 'Q'
+                liwork_a = 0;
+
+            // TODO: Handle 'k' for DWORK
+
+            int ldwork_a;
+            //int ns = nsmp - 2*nobr + 1;
+        
+            if (alg == 'C')
             {
-                ldwork_a = 4*(m+l)*nobr;
-            }
-            else if (ldr >= ns && batch == 'O')
-            {
-                if (meth_a == 'M')
-                    ldwork_a = max (4*(m+l)*nobr, 5*l*nobr);
-                else    // (meth == 'N')
+                if (batch == 'F' || batch == 'I')
+                {
+                    if (conct == 'C')
+                        ldwork_a = (4*nobr-2)*(m+l);
+                    else    // (conct == 'N')
+                        ldwork_a = 1;
+                }
+                else if (meth_a == 'M')   // && (batch == 'L' || batch == 'O')
+                {
+                    if (conct == 'C' && batch == 'L')
+                        ldwork_a = max ((4*nobr-2)*(m+l), 5*l*nobr);
+                    else if (jobd == 'M')
+                        ldwork_a = max ((2*m-1)*nobr, (m+l)*nobr, 5*l*nobr);
+                    else    // (jobd == 'N')
+                        ldwork_a = 5*l*nobr;
+                }
+                else    // meth_b == 'N' && (batch == 'L' || batch == 'O')
+                {
                     ldwork_a = 5*(m+l)*nobr + 1;
+                }
             }
-            else if (conct == 'C' && (batch == 'I' || batch == 'L'))
+            else if (alg == 'F')
             {
-                ldwork_a = 4*(nobr+1)*(m+l)*nobr;
+                if (batch != 'O' && conct == 'C')
+                    ldwork_a = (m+l)*2*nobr*(m+l+3);
+                else if (batch == 'F' || batch == 'I')  // && conct == 'N'
+                    ldwork_a = (m+l)*2*nobr*(m+l+1);
+                else    // (batch == 'L' || '0' && conct == 'N')
+                    ldwork_a = (m+l)*4*nobr*(m+l+1)+(m+l)*2*nobr;
             }
-            else    // if ALG = 'Q', (BATCH = 'F' or 'O', and LDR < NS), or (BATCH = 'I' or 'L' and CONCT = 'N')
+            else    // (alg == 'Q')
             {
-                ldwork_a = 6*(m+l)*nobr;
+                int ns = nsmp - 2*nobr + 1;
+                
+                if (ldr >= ns && batch == 'F')
+                {
+                    ldwork_a = 4*(m+l)*nobr;
+                }
+                else if (ldr >= ns && batch == 'O')
+                {
+                    if (meth_a == 'M')
+                        ldwork_a = max (4*(m+l)*nobr, 5*l*nobr);
+                    else    // (meth == 'N')
+                        ldwork_a = 5*(m+l)*nobr + 1;
+                }
+                else if (conct == 'C' && (batch == 'I' || batch == 'L'))
+                {
+                    ldwork_a = 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_a = 6*(m+l)*nobr;
+                }
             }
-        }
 
 /*
 IB01AD.f Lines 438-445
@@ -343,66 +362,67 @@
 */
 
 
-        OCTAVE_LOCAL_BUFFER (int, iwork_a, liwork_a);
-        OCTAVE_LOCAL_BUFFER (double, dwork_a, ldwork_a);
+            OCTAVE_LOCAL_BUFFER (int, iwork_a, liwork_a);
+            OCTAVE_LOCAL_BUFFER (double, dwork_a, ldwork_a);
         
-        // error indicators
-        int iwarn_a = 0;
-        int info_a = 0;
+            // error indicators
+            int iwarn_a = 0;
+            int info_a = 0;
 
 
-        // SLICOT routine IB01AD
-        F77_XFCN (ib01ad, IB01AD,
-                 (meth_a, 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_a,
-                  iwork_a,
-                  dwork_a, ldwork_a,
-                  iwarn_a, info_a));
+            // SLICOT routine IB01AD
+            F77_XFCN (ib01ad, IB01AD,
+                     (meth_a, 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_a,
+                      iwork_a,
+                      dwork_a, ldwork_a,
+                      iwarn_a, info_a));
 
 
-        if (f77_exception_encountered)
-            error ("ident: exception in SLICOT subroutine IB01AD");
+            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* 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"};
+            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: IB01AD", info_a, 2, err_msg);
-        warning_msg ("ident: IB01AD", iwarn_a, 5, warn_msg);
+            error_msg ("ident: IB01AD", info_a, 2, err_msg);
+            warning_msg ("ident: IB01AD", iwarn_a, 5, warn_msg);
+        }
 
 
         // resize