1 /* 2 3 Copyright (C) 2009-2016 Lukas F. Reichlin 4 5 This file is part of LTI Syncope. 6 7 LTI Syncope is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation, either version 3 of the License, or 10 (at your option) any later version. 11 12 LTI Syncope is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with LTI Syncope. If not, see <http://www.gnu.org/licenses/>. 19 20 First, this function implemented the following Octave function in C++ 21 22 function [mat_idx, opt_idx] = __lti_input_idx__ (varargin) 23 24 str_idx = find (cellfun (@ischar, varargin)); 25 26 if (isempty (str_idx)) 27 mat_idx = 1 : nargin; 28 opt_idx = []; 29 else 30 mat_idx = 1 : str_idx(1)-1; 31 opt_idx = str_idx(1) : nargin; 32 endif 33 34 endfunction 35 36 Later on, the C++ function was extended such that 37 it recognizes classes in some cases. See comment 38 block in the code for details. I know this looks 39 like a horrible definition for a function, but it 40 is exactly the behavior I need. 41 42 Author: Lukas Reichlin <lukas.reichlin@gmail.com> 43 Created: October 2015 44 Version: 0.1 45 46 */ 47 48 49 #include <octave/oct.h> 50 #include "config.h" 51 52 // PKG_ADD: autoload ("__lti_input_idx__", "__control_helper_functions__.oct"); 53 DEFUN_DLD (__lti_input_idx__, args, , 54 "-*- texinfo -*-\n\ 55 @deftypefn {Loadable Function} {[@var{mat_idx}, @var{opt_idx}, @var{obj_flg}] =} __lti_input_idx__ (@var{args})\n\ 56 Return some indices for cell @var{args}. For internal use only.\n\ 57 Read the source code in @code{lti_input_idx.cc} for details.\n\ 58 @end deftypefn") 59 { 60 octave_value_list retval; 61 octave_idx_type nargin = args.length (); 62 63 // first, check whether a cell is passed 64 if (nargin == 1 && args(0).is_defined () && args(0).OV_ISCELL ()) 65 { 66 octave_idx_type len = args(0).cell_value().numel(); 67 octave_idx_type idx = len; 68 octave_idx_type offset = 0; 69 70 // if the cell is not empty, look for the first string 71 for (octave_idx_type i = 0; i < len; i++) 72 { 73 if (args(0).cell_value().elem(i).is_string ()) 74 { 75 idx = i; 76 break; 77 } 78 } 79 80 // ** If the element before the first string is an object, 81 // then this object belongs to the option index. 82 // ss (d, ltisys, 'key', val) 83 // ** If there is no string at all in cell args(0), check 84 // whether the last element in args(0) is an object. 85 // If so, this object also belongs to the option index. 86 // tf (num, den, ltisys) 87 // ** All other objects (before built-in types (except chars) 88 // and after strings) are not recognized as objects. 89 // ss (a, b, ltisys, c, d, 'key', val, 'lti', ltisys) 90 if (len > 0 && idx > 0 91 && args(0).cell_value().elem(idx-1).OV_ISOBJECT ()) 92 { 93 offset = 1; 94 } 95 96 Range mat_idx (1, idx-offset); 97 Range opt_idx (idx+1-offset, len); 98 99 retval(2) = offset; // abused as logical in the LTI constructors 100 retval(1) = opt_idx; 101 retval(0) = mat_idx; 102 } 103 else 104 { 105 print_usage (); 106 } 107 108 return retval; 109 } 110