Skip to content

Create functions for better indexing of MIMO transfer functions #256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
murrayrm opened this issue Dec 28, 2018 · 8 comments · Fixed by #1012
Closed

Create functions for better indexing of MIMO transfer functions #256

murrayrm opened this issue Dec 28, 2018 · 8 comments · Fixed by #1012

Comments

@murrayrm
Copy link
Member

murrayrm commented Dec 28, 2018

Motivated by PR #246, which implemented indexing for transfer functions, it would be nice to be able to use Python slice notation for MIMO system objects. So if you had a MIMO transfer function G, you could say things like G[:,1:3] to get a subset of the transfer functions.

A full implementation should allow slice functionality to be used in simulation and plotting functions, block diagram functions (issue #20), etc.

Will use this issue to keep track of some of the possibilities and see if there is a good way forward.

@roryyorke
Copy link
Contributor

What is "slide functionality" ?

I glanced at #20, it's not immediately obvious to me how this is related to MIMO slicing, other than allowing a MIMO sub-object to be submitted for block diagram operations.

If I read #246 right, it does implement this for TFs - do you want this for FRD and SS objects too? Maybe change the title to "MIMO system objects", as it is in the text.

@murrayrm
Copy link
Member Author

Sorry that should have been slice functionality.

What I was thinking on #20 is that the way you specify inputs and outputs for the feedback function should use slice notation.

Correct that the goal was to extend #246 to other objects (and functions).

@roryyorke
Copy link
Contributor

Ah, right; I think my mind jumped to GUI sliders.

Unfortunately, and unlike Matlab, Python only supports slice (and ellipsis ...) notation when indexing (using []), so foo(1:2) is a syntax error. One could allow feedback(f, g, slice(1,2,3), slice(4,5,6)) - is that what you had in mind?

Tangentially related: the last time I used the control toolbox, I found the signal naming capability very handy; this lets one combine a number of LTI objects using connect; assuming all the objects have the correct names, one only has to specify the final inputs and outputs, as cell arrays of strings, and the toolbox does the rest.

@rega0051
Copy link

rega0051 commented Jan 6, 2021

@roryyorke I use signal naming extensively. I wrote a little wrapper around 'connect' for my work. Would like to have I/O names as an element of the systems so they are preserved through normal transformations. As it is I use the ConnectName function for adding, multiplying, feedback operations; but its not very clean. Slicing should also be accomplished by name, rather than trying to keep track of the indices. I've always found managing named signals much less error prone than counting out index numbers.


# Controller definition
sysK = control.ss([], [], [], 0.5 * np.eye(2))
sysK.InputName = ['e1', 'e2']
sysK.OutputName = ['uCtrl1', 'uCtrl2']

# Reference Input: e = r - z
sysSumR = control.ss([], [], [], [[1, 0, -1, 0], [0, 1, 0, -1]])
sysSumR.InputName = ['r1', 'r2', 'z1', 'z2']
sysSumR.OutputName = ['e1', 'e2']

connectNames = sysK.InputName
inKeep = sysSumR.InputName
outKeep = sysK.OutputName
sysCtrl = ConnectName([sysSumR, sysK], connectNames, inKeep, outKeep)


def ConnectName(sysList, connectNames, inKeep, outKeep):

    sys = []
    for s in sysList:
        if sys == []:
            sys = s
        else:
            sys = control.append(sys, control.ss(s))

    inNames = []
    outNames = []
    for s in sysList:
        inNames += s.InputName
        outNames += s.OutputName

    Q = [[inNames.index(s)+1, outNames.index(s)+1]  for s in connectNames]

    inputv = [inNames.index(s)+1 for s in inKeep]
    outputv = [outNames.index(s)+1 for s in outKeep]

    sysOut = control.connect(sys, Q, inputv, outputv)

    sysOut.InputName = inKeep
    sysOut.OutputName = outKeep

    return sysOut

@murrayrm
Copy link
Member Author

murrayrm commented Jan 6, 2021

FYI, the iosys module supports signal naming and there is an interconnect function the latest master that supports this sort of named connection structure. See #497 for some details.

@rega0051
Copy link

rega0051 commented Jan 8, 2021

@murrayrm Thanks, I'll look for it.

@ilayn
Copy link

ilayn commented Jan 9, 2021

It is actually not that sophisticated. It's the slice notation of numpy and python that is a bit annoying. We have to regularize things like [:4, 3] or [[1,2,5], [3,2]] etc. and unfortunately there is no simple way to detect these so the easiest way is to pass the index directly to a monotone integer sequence and then use them as indices.

https://github.com/ilayn/harold/blob/2b06ccce1dd64f5d7171fe9e4c914a83c0ecd3d1/harold/_classes.py#L968-L993

Same is also present for the State class in the same file

@ilayn
Copy link

ilayn commented Jan 9, 2021

oops just saw the timestamps sorry for the noise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants