Difference between revisions of "Using tfest to find a system model"
(7 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
[[Category:Electronics]] | [[Category:Electronics]] | ||
{{Template:20.309}} | {{Template:20.309}} | ||
+ | The function <tt> FitTransferFunction</tt> below uses <tt>tfest</tt> to fit a linear model to frequency response data. | ||
− | + | The arguments NumeratorForm and DenominatorForm are vectors of ones and zeros. The model is a transfer function whose numerator and denominator are polynomials in <math>s</math>. (Recall that <math>s=j\omega</math>.) | |
+ | Each element of the vectors corresponds to a single term of the numerator or denominator, in order of decreasing powers of <math>s</math>. | ||
− | + | For example, if you want the function to fit a transfer function of the form <math>\frac{K_1 s}{K_2 s + K_3}</math> (a high-pass filter), you would use <tt>numeratorForm = [ 1 0 ]</tt> and<tt> denominatorForm = [ 1 1 ]</tt>. These parameters, <tt>tfest</tt> will fit a first-order polynomial for the numerator and denominator with no constant term in the numerator. | |
− | < | + | If you wanted to fit a transfer function of the form <math>\frac{K_1 s^2}{K_2 s^3 + K_3 s^2 + K_4 s + K_5}</math>, you would use <tt>numeratorForm = [ 1 0 0 ]</tt> and<tt> denominatorForm = [ 1 1 1 1]</tt> |
− | + | ||
− | s = | + | |
− | + | ||
− | + | <pre> | |
− | + | function EstimatedTransferFunction = FitTransferFunction( ... | |
− | + | MagnitudeRatio, PhaseDifferenceDegrees, FrequencyHertz, NumeratorForm, DenominatorForm ) | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | function EstimatedTransferFunction = FitTransferFunction( MagnitudeRatio, PhaseDifferenceDegrees, FrequencyHertz, NumeratorForm, DenominatorForm ) | + | |
% convert magnitude and phase to single complex vector | % convert magnitude and phase to single complex vector | ||
complexResponseData = MagnitudeRatio .* exp( 1i .* PhaseDifferenceDegrees .* pi ./ 180 ); | complexResponseData = MagnitudeRatio .* exp( 1i .* PhaseDifferenceDegrees .* pi ./ 180 ); | ||
Line 31: | Line 20: | ||
initalModel = idtf( NumeratorForm, DenominatorForm ); | initalModel = idtf( NumeratorForm, DenominatorForm ); | ||
zeroCoefficients = find( NumeratorForm == 0 ); | zeroCoefficients = find( NumeratorForm == 0 ); | ||
− | for ii = | + | for ii = zeroCoefficients |
initalModel.Structure.Numerator.Free(ii) = false; | initalModel.Structure.Numerator.Free(ii) = false; | ||
end | end | ||
zeroCoefficients = find( DenominatorForm == 0 ); | zeroCoefficients = find( DenominatorForm == 0 ); | ||
− | for ii = | + | for ii = zeroCoefficients |
initalModel.Structure.Denominator.Free(ii) = false; | initalModel.Structure.Denominator.Free(ii) = false; | ||
end | end | ||
Line 42: | Line 31: | ||
EstimatedTransferFunction = tfest( frequencyResponseData, initalModel ); | EstimatedTransferFunction = tfest( frequencyResponseData, initalModel ); | ||
end | end | ||
+ | </pre> | ||
+ | |||
+ | Here is some sample code you can use to test and understand <tt> FitTransferFunction</tt>. | ||
+ | |||
+ | <pre> | ||
+ | %Generate some synthetic frequency response measurement data | ||
+ | s = tf( [ 1 0 ], 1 ); | ||
+ | highPass = s / ( s + 1 ) | ||
+ | |||
+ | [ magnitude, phase, omega ] = bode( highPass ); | ||
+ | frequency = omega / ( 2 * pi ); | ||
+ | |||
+ | % add some random noise | ||
+ | noiseStandardDeviation = 0.05; | ||
+ | magnitude = magnitude + noiseStandardDeviation * randn( size( magnitude ) ); | ||
+ | phase = phase + noiseStandardDeviation * randn( size( phase ) ); | ||
+ | |||
+ | numeratorForm = [ 1 0 ]; % decreasing powers of s -- first order with no constant term | ||
+ | denominatorForm = [ 1 1 ]; % decreasing powers of s -- first order with constant term | ||
+ | |||
+ | estimatedTransferFunction = FitTransferFunction( ... | ||
+ | magnitude, phase, frequency, numeratorForm, denominatorForm ) | ||
</pre> | </pre> | ||
− | {{Template:20.309}} | + | {{Template:20.309 bottom}} |
Latest revision as of 22:03, 9 April 2019
The function FitTransferFunction below uses tfest to fit a linear model to frequency response data.
The arguments NumeratorForm and DenominatorForm are vectors of ones and zeros. The model is a transfer function whose numerator and denominator are polynomials in $ s $. (Recall that $ s=j\omega $.) Each element of the vectors corresponds to a single term of the numerator or denominator, in order of decreasing powers of $ s $.
For example, if you want the function to fit a transfer function of the form $ \frac{K_1 s}{K_2 s + K_3} $ (a high-pass filter), you would use numeratorForm = [ 1 0 ] and denominatorForm = [ 1 1 ]. These parameters, tfest will fit a first-order polynomial for the numerator and denominator with no constant term in the numerator.
If you wanted to fit a transfer function of the form $ \frac{K_1 s^2}{K_2 s^3 + K_3 s^2 + K_4 s + K_5} $, you would use numeratorForm = [ 1 0 0 ] and denominatorForm = [ 1 1 1 1]
function EstimatedTransferFunction = FitTransferFunction( ... MagnitudeRatio, PhaseDifferenceDegrees, FrequencyHertz, NumeratorForm, DenominatorForm ) % convert magnitude and phase to single complex vector complexResponseData = MagnitudeRatio .* exp( 1i .* PhaseDifferenceDegrees .* pi ./ 180 ); % create optional initial model for tfest so that known zero % coefficients can be constrained initalModel = idtf( NumeratorForm, DenominatorForm ); zeroCoefficients = find( NumeratorForm == 0 ); for ii = zeroCoefficients initalModel.Structure.Numerator.Free(ii) = false; end zeroCoefficients = find( DenominatorForm == 0 ); for ii = zeroCoefficients initalModel.Structure.Denominator.Free(ii) = false; end frequencyResponseData = frd( complexResponseData, FrequencyHertz, 'FrequencyUnit', 'Hz'); EstimatedTransferFunction = tfest( frequencyResponseData, initalModel ); end
Here is some sample code you can use to test and understand FitTransferFunction.
%Generate some synthetic frequency response measurement data s = tf( [ 1 0 ], 1 ); highPass = s / ( s + 1 ) [ magnitude, phase, omega ] = bode( highPass ); frequency = omega / ( 2 * pi ); % add some random noise noiseStandardDeviation = 0.05; magnitude = magnitude + noiseStandardDeviation * randn( size( magnitude ) ); phase = phase + noiseStandardDeviation * randn( size( phase ) ); numeratorForm = [ 1 0 ]; % decreasing powers of s -- first order with no constant term denominatorForm = [ 1 1 ]; % decreasing powers of s -- first order with constant term estimatedTransferFunction = FitTransferFunction( ... magnitude, phase, frequency, numeratorForm, denominatorForm )