5

I am working with Octave in the control package, and I want to take an array of transfer functions (initialized as follows) and just extract the diagonal elements of the matrix. Whenever I try to do this, I run into the following error. I have tried lots of workarounds (converting it to a state space diagram, storing the elements in a cell, etc.), but I either run into a similar error or I end up with an object that can no longer interact with other matrices of transfer functions. There are some unimplemented functions (like ss2ss) in the documentation that I think would be useful but are unavailable.

How can I work around this?

The code initializing the type of object I'm working with:

s = tf('s');
m = inv(s*e - mat); // e and mat are just square matrices of numbers

The code I am using to try to extract the diagonal components:

function D = getD(W) // W is of the similar type as above
    n = size(W,1);
    Dtemp = tf(eye(n));
    for i = 1:n
        Dtemp(i,i) = W(i,i);
    end
    D = Dtemp;
end

Errors that I keep getting:

error: lti: subsasgn: invalid subscripted assignment type '()'.  you must select an LTI key first, i.e.  sys.keyname(...) = ...

Note that when I initialized Dtemp as cell (n,n), I get this type:

{
  [1,1] =

    <class tf>

  [2,1] =

    <class tf>
etc.

Instead of this type: (which is what I want it to interact with)

{
  [1,1] =

    <class tf>

}

Even though they are both nxn in size. I am hoping to be able to convert the former into the latter, so I can interact with other objects of the latter type.

henxdl
  • 118
  • 14
Justin T
  • 101
  • 4

1 Answers1

1

In Octave, if you want to create an array of transfer functions and then extract the diagonal elements, you have to use cell arrays. The problem with your getD function is that you are trying to assign a transfer function object to a specific position in a transfer function array. This is not permitted, hence the error.

In your situation, you might want to consider the following approach:

  1. Initialize the cell array with transfer functions.
  2. Extract the diagonal elements into another cell array.
  3. Convert the cell array of transfer functions into a transfer function array when needed.

Here is how you can do it:

s = tf('s');
m = inv(s*e - mat);

function D = getD(W)
    n = size(W,1);
    Dtemp = cell(n,n);
    for i = 1:n
        Dtemp{i,i} = W{i,i};
    end
    D = Dtemp;
end

After calling getD, you'll get a cell array D containing the diagonal transfer functions. When you want D to interact with other transfer function arrays, you can convert it back using tfcell2tf from the control package:

D_tf = tfcell2tf(D);

Now D_tf is a transfer function array and can be used to interact with other transfer function arrays. Please keep in mind that tfcell2tf only works properly when non-diagonal elements in D are zero or equivalent to zero transfer functions.

Ravement
  • 13
  • 6