user9985
user9985

Reputation: 172

Time Varying Transfer Function

I have a discrete transfer function whose numerator and denominator are coming from an input port. At every sample time these numerator and denominator vectors change.

E.g.

@ t == 0

den == [1 0 -1]

@ t == 1

den == [1 0 0 -1]

What do I have to do in order for the transfer function to work with this?

I have tried:

  1. Having a variable length signal.

SIMULINK did not like this and refused to run, complaining that the discrete transfer function block could not handle variable sized input.

  1. Padding the vector with many leading zeros

This led to periodic spikes in the signal. Additionally, Simulink does not let you do this if you enter the values by hand, rather than as an input, so I don't think this is the way to do it either.

Any help is much appreciated.

Upvotes: 2

Views: 1390

Answers (1)

Brethlosze
Brethlosze

Reputation: 1622

This is solved trivially with a single Simulink S-Function file sfuntvf.m, like this.

In there, a custom fixed vector state with y and us history is saved, and the time varying part is simply applied over the time history (depicted in cyan and yellow); here a FIR Filter with a random order (depicted in magenta).

Other build-in implementations shall consider the sucessive initial conditions between calls, and require the verification of the initial condition structure. The shown implementation is the easiest to deploy and understand.

The A and B vectors can be modified accordingly.

function [sys,x0,str,ts] = sfuntvf(t,x,u,flag)
N=20;
n=randi(N-2)+1;
A=[1;zeros(N-1,1)];
B=[1/n*ones(n,1);zeros(N-n,1)];
switch flag,
  case 0, [sys,x0,str,ts] = mdlInitializeSizes(N);
  case 2, sys = mdlUpdate(t,x,u,N,A,B); 
  case 3, sys = mdlOutputs(t,x,u,N,n);
  case 9, sys = []; 
  otherwise DAStudio.error('Simulink:blocks:unhandledFlag',num2str(flag));
end

function [sys,x0,str,ts] = mdlInitializeSizes(N)
sizes = simsizes;
sizes.NumContStates  = 0;
sizes.NumDiscStates  = 2*N;
sizes.NumOutputs     = 2;
sizes.NumInputs      = 1;
sizes.DirFeedthrough = 0;
sizes.NumSampleTimes = 1;
sys = simsizes(sizes);

x0  = zeros(2*N,1);
str = [];
ts  = [1 0]; 

function sys = mdlUpdate(t,x,u,N,A,B)
un=x(1:N,1);
yn=x(N+1:2*N,1);
y=-A(2:end)'*yn(2:end)+B'*un;
sys = [u;un(1:end-1);y;yn(1:end-1)];

function sys = mdlOutputs(t,x,u,N,n)
sys = [x(N+1);n];

Model Plot

Upvotes: 0

Related Questions