How to reformat the display output precision of e.g. the TF() function?
51 views (last 30 days)
Show older comments
When asking for a transfer function, given a state-space object sysd, MATLAB prints the result like this:
>> tfd = tf(sysd)
tfd =
0.05563 z + 0.05568
----------------------
z^2 - 1.988 z + 0.9923
The precision used is insufficient for my purposes (I need more than 7 significant digits). It appears not to be possible to use e.g. "format long e" to change this?
Of course I can ask for tfd.num and tf.den and print these arrays with long e, but that is not very convenient (I like the pretty printed display and don't see an easy way to write that myself). How to instruct MATLAB to use the proper format in this case?
PS: There are more functions and figures that display data in difficult to change numeric formats or in ugly windows (like the Bode and pz diagrams from the control toolbox). It would be nice if one could change all that in a (semi-)permanent way.
4 Comments
Star Strider
on 7 May 2022
Use:
format lonog
num = tfd.Numerator
den = tfd.Denominator
to get the full-precision vectors.
Accepted Answer
Paul
on 7 May 2022
Edited: Paul
on 22 Oct 2022
EDIT 22 Oct 2022: Updated code to fix a bug where the leading coeficient of a polynomial is -1. followed by digits after the decimal point, in response to this comment
The function poly2str in the CST may be of interest, I think that the numerical formatting is governed by a single line, so I guess you could make a local copy and modify that line and go from there.
which poly2str
Here's my attempt. I have not fully tested it and so there may be (probably are!) some corner cases I haven't considered.
User beware.
It assumes a discrete time tf in the variable z. I'm sure it could be generalized.
rng(100);
tfd = tf(rand(1,3).*[-1 -1 1],rand(1,5).*[1 -1 1 -1 1],-1)
localdisptf(tfd);
tfd = tf([-1 1],[1 -2.00000001 1],-1)
localdisptf(tfd);
tfd = tf([-1],[-1 -1 1],-1)
localdisptf(tfd);
Matlab always displays with leading coeffficient of denominator positive. Code can be modfied if desired.
tfd = tf(1.000004,-5.31256,-1)
localdisptf(tfd);
Matlab displays static gains as a single number. Code can be modified if desired.
This example was not handled correctly prior to the edit on 22 Oct 2022.
tfd = tf([-1.1 1],[-1.1 1 1],-1)
localdisptf(tfd)
Matlab enforces that leading coefficient on denominator is positive. Code can be modified if desired to follow that convention.
function polystr = localpolystr(polynomial)
% convert numerical coefficients to string representation
polystr = split(string(num2str(polynomial,16))); % change fmt as needed, or it can be a function input
% delete leading terms with coefficients of zero
firstnonzero = find(polystr~= "0",1);
polystr(1:firstnonzero-1) = [];
% append the z variable to each term, except z^0
for ii = 1:numel(polystr)-1
polystr(ii) = polystr(ii) + " z^" + string(numel(polystr)-ii);
end
% delete the ^1 from the z^1 term so it only displays as z
polystr = erase(polystr,"^1");
% find all the terms that have a negative coefficient
negativeterms = find(extractBefore(polystr,2) == "-");
% except the first term that will be treated separately
negativeterms(negativeterms == 1) = [];
% only keep the number after the negative sign for the negative coefficients
polystr(negativeterms) = extractAfter(polystr(negativeterms),1);
% + or - dividers between each term in the expression
dividers = ["" ; repmat(" + ",numel(polystr)-1,1)];
dividers(negativeterms) = " - ";
% don't show coefficient if it's 1
unityterms = find(extractBefore(polystr(1:end-1),3) == "1 ");
polystr(unityterms) = extractAfter(polystr(unityterms),2);
% special case for -1 leading coefficient of a polynomial
if numel(polystr) > 1 && strlength(polystr(1)) > 3 && extractBefore(polystr(1),4) == "-1 "
polystr(1) = "-" + extractAfter(polystr(1),3);
end
polystr = dividers + polystr;
polystr = join(polystr,"");
end
function localdisptf(htf)
% extract numerator and denominator
num = htf.num{1};
den = htf.den{1};
% convert to string representation
denstr = localpolystr(den);
numstr = localpolystr(num);
% create the fraction divider
divider = join(repmat("-",1,max(strlength(denstr),strlength(numstr))),"");
% center the numerator, divider, and denominator strings
tfstrings = strjust(pad([numstr;divider;denstr]),'center');
% display
disp(inputname(1) + " =")
disp(tfstrings(1));
disp(tfstrings(2));
disp(tfstrings(3));
end
7 Comments
Paul
on 22 Oct 2022
Yes, that leading coefficient of the numerator would have been truncated to -1 with the old code.
Thanks again for pointing out the problem. Would have been easy for you to proceed after commenting out the original offending lines and leaving incorrect code in the Answer here.
BTW, given your application, would it be better to keep all the exact "1" coefficients explict in the display?
More Answers (0)
See Also
Categories
Find more on Conway's Game of Life in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!