Effacer les filtres
Effacer les filtres

vpa not reducing the precision

15 vues (au cours des 30 derniers jours)
EngM
EngM le 11 Fév 2022
Commenté : Walter Roberson le 24 Fév 2022
Hello,
I am doing some symbolic calculations. Matlab is returning rediculously small numbers up to the order of -180 ! I tried the suggested usage of digits and vpa but none seem to do the job. here is an example of numbers up to -15 .
[ -15 -15 -15 ]
[1. 0.1224 10 -0.1224 10 0.1224 10 q2 + 1. q1]
This is a very simple homogeneous transformation of a frame in multi-body system. you can imagine multiplying these small numbers to get even smaller ones. This is keeping the symbolic variables q1, q2 ... in the experession and further complicating the calculations and slowing down the program.
I ran vpa on these results, it didn't work. I went down and applied vpa on every symbolic math in my sheet, still didn't work.
please adivse..
thanks.
  3 commentaires
EngM
EngM le 11 Fév 2022
Modifié(e) : KSSV le 11 Fév 2022
Here we go..
%This is a class definition of a Link defined in DH format
classdef LinkRecord
%DH Link Recrod
properties
% a =1;
% alpha =0;
% d =0;
% theta =0;
type {mustBeText , mustBeMember(type,{'revolute','prismatic','fixed'})} = 'revolute'
parent {mustBeNumeric} = 0;
TtoP = HTransfer(eye(3),zeros(3,1));
TtoB = HTransfer(eye(3),zeros(3,1));
path = [0 1];
name {mustBeText} = 'link'
end
methods
function obj = LinkRecord(tb,type,parent,name)
Rzz = @(alpha) vpa([cos(alpha) -sin(alpha) 0;sin(alpha) cos(alpha) 0;0 0 1]);
Rxx = @(alpha) vpa([1 0 0 ;0 cos(alpha) -sin(alpha);0 sin(alpha) cos(alpha)]);
HTransferr = @(R,p)vpa([[R;0 0 0] [p;1]]);
digits(4);
if iscell(tb)
obj.TtoP = vpa(HTransferr(Rzz(tb{4}),[0;0;tb{3}])*HTransferr(Rxx(tb{2}),[tb{1};0;0]),3);
else
obj.TtoP = vpa(HTransfer(Rz(tb(4)),[0;0;tb(3)])*HTransfer(Rx(tb(2)),[tb(1);0;0]),3);
end
obj.TtoB = obj.TtoP;
% obj.a = tb(1);
% obj.alpha = tb(2);
% obj.d = tb(3);
% obj.theta = tb(4);
obj.type = type;
obj.parent = parent;
obj.path = [0 1];
if ~exist('name','var')
% third parameter does not exist, so default it to something
obj.name = 'link';
else
obj.name = name;
end
end
end
end
EngM
EngM le 11 Fév 2022
thanks..

Connectez-vous pour commenter.

Réponse acceptée

Walter Roberson
Walter Roberson le 11 Fév 2022
Consider:
1
10^-49 * --------
x*10^-50
This is, of course, mathematically the same as x*10 -- but there are cases where MATLAB prefers to factor out constants even though it makes other constants "awkward" . Imagine for example 10*y + 10^-14*x then you could imagine that MATLAB might prefer to rewrite that in terms of x first and y, and might prefer to have small-integer coefficient for x by factoring it out, 10^-14 * (x + 10^15*y) . MATLAB does prefer to have the symbols of a summand appear in lexographic order, except in denominators in which case it prefers the first non-negative symbol to be first... and it is prepared to invent multiplications and divisions to reach its preferred internal factorization form.
The point is that Yes, there are definitely cases where MATLAB will factor out into large numbers times small coefficients... cases that are mathematically the same but involve coefficients with small magnitude.
Now imagine that vpa() had the role of going in and zeroing coefficients that were smaller than 1/10^Digits . Then for that first expression, it would be doing 10^-49 * 1/((ZERO the 10^-50) * x) ... which would be 10^-49 * 1/(0 * x) -->> 10^-49 / 0 --> +infinity
Therefore, vpa should not be zeroing "small" coefficients: those small coefficients might be very necessary in context.
You could, I am sure, imagine formulae that involve dividing by Avogadro's Number 6.022*10^23 -- and mathematically that division would be equivalent to multiplying by the reciprical of the number... so multiplying by about 1.6605*10^-24 . If vpa() automatically zeroed "small" constants then that would drastically change the meaning of the expression.
This does not mean that there is no way of getting MATLAB to zero out "small" numbers... but it does mean that it should not be done by vpa() and that when it is done, it has to be done carefully. The fancy symbolic rational expressions you see displayed are sometimes internally coded quite differently than you expect.
  10 commentaires
EngM
EngM le 22 Fév 2022
well, in my case, these are homogeneous transformation matrices, the terms are like 1e-32 * cos(theta) and they will be multiplied with each other or with a position vecotr, which I don't expect to be of a trillion km order.
the number of sym variables in a given matrix can be up to 12 or so, the execution is fairly fast when when less of these small numbers present.
before your code, I was using a function that uses SymToStr(), but after I removed Maple connector, the function no longer available. on the other hand, if I re-install it, the matlabfunction() command no longer be available! which I need to convert these experssions into functions.
Walter Roberson
Walter Roberson le 24 Fév 2022
If you want to go back to doing text manipulation to zero small coefficients, then use char() or string() . Just be careful because the computing language returned by char() or string() is not exactly MATLAB and is not exactly the internal symbolic language MuPAD. Some of the changes are pretty visible, with phrases like
k in R\Z
showing up. But some of the changes are easily overlooked, such as the order of parameters for the beta() function .
It is not guaranteed that you will be able to use char() followed by str2sym() to get back the original expression.
It is a bit more robust to use matlabFunction() to generate equivalent numeric MATLAB code... provided that your code does not use piecewise(), and provided that you are comfortable with int() being turned into integral()...

Connectez-vous pour commenter.

Plus de réponses (0)

Produits


Version

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by