Unable to run pinv (Moore Penrose) , get errors
Show older comments
Tried the following script:
r0=[0,0,0];
dq=double(pinv(J_BF_inB)*(rGoal-r0));
dq=double(subs(dq,[alpha,beta,gamma],[0,0.52,1.04]));
q=q0;
for n=1:10
q=q+dq;
end
I get the following errors:
Error using svd
First input must be single or double.
Error in pinv (line 18)
[U,s,V] = svd(A,'econ');
Error in solution (line 24)
dq=double(pinv(J_BF_inB)*(rGoal-r0));
Answers (1)
Walter Roberson
on 12 Feb 2022
0 votes
You cannot take the pseudo-inverse of a function handle.
If you were to construct a symbolic array you might be able to pinv() that, but you would not be able to double() the results.
Are you expecting that the 3x3 matrix might not have full rank? If full rank is expected then this would look more like a job for the \ operator
12 Comments
Ken
on 12 Feb 2022
J_BF_inB=@(alpha,beta,gama)[0,-cos(beta+gamma)-cos(beta),cos(alpha)*(cos(beta+gamma)+cos(beta)+1),
-sin(alpha)*(sin(beta+gamma)+sin(beta)),-sin(beta+gamma)*sin(alpha);...
sin(alpha)*(cos(beta+gamma)+cos(beta)+1),cos(alpha)*(sin(beta+gamma)+...
sin(beta)),sin(beta+gamma)*cos(alpha)];
Okay, that's a function handle.
dq=double(pinv(J_BF_inB)*(rGoal-r0));
What happens if we pinv() a function handle?
pinv(J_BF_inB)
Was it maybe the wrong function handle?
pinv(@(x)1)
No, even though pinv(1) would obviously be valid, pinv() of a function handle that would return 1, fails.
dq=double(pinv(J_BF_inB)*(rGoal-r0));
We can see from the position of the brackets, that whatever is returned by pinv(J_BF_inB)*(rGoal-r0) is to be converted to class double. Imagine that we had arranged J_BF_inB and rGoal-r0 to be something that double() could convert to double precision. Imagine, for example, that it returned [1 2 4; 3 5 6; 7 8 9]
dq=double([1 2 4; 3 5 6; 7 8 9])
whos dq
Okay, dq is 3 x 3, class double. Now let us go on to the next line
dq=double(subs(dq,[alpha,beta,gamma],[0,0.52,1.04]));
and let us focus on the subs() part
subs(dq,[alpha,beta,gamma],[0,0.52,1.04])
... which is because we did not define alpha, beta or gamma
syms alpha beta gamma
So now we have defined them as symbolic
dq=double([1 2 4; 3 5 6; 7 8 9])
subs(dq,[alpha,beta,gamma],[0,0.52,1.04])
But that's exactly the same as dq. Since you forced dq to be double precision in the line above, we can be certain that dq is not symbolic, so we can be certain that dq does not contain any symbolic variable alpha, beta, or gamma . So what is the point of doing the subs?
So maybe...
syms alpha beta gama
syms rGoal r0
J_BF_inB = [0,-cos(beta+gamma)-cos(beta),cos(alpha)*(cos(beta+gamma)+cos(beta)+1),
-sin(alpha)*(sin(beta+gamma)+sin(beta)),-sin(beta+gamma)*sin(alpha);...
sin(alpha)*(cos(beta+gamma)+cos(beta)+1),cos(alpha)*(sin(beta+gamma)+...
sin(beta)),sin(beta+gamma)*cos(alpha)]
What happened? Well, notice your original code
J_BF_inB=@(alpha,beta,gama)[0,-cos(beta+gamma)-cos(beta),cos(alpha)*(cos(beta+gamma)+cos(beta)+1),
-sin(alpha)*(sin(beta+gamma)+sin(beta)),-sin(beta+gamma)*sin(alpha);...
sin(alpha)*(cos(beta+gamma)+cos(beta)+1),cos(alpha)*(sin(beta+gamma)+...
sin(beta)),sin(beta+gamma)*cos(alpha)];
declares J_BF_inB to be a function of alpha, beta and gama but then is written in terms of alpha, beta and gamma . Notice that gama and gamma are not the same thing, so the references to gamma inside your function handle were references to the function gamma() not to the named parameter gama
Ken
on 12 Feb 2022
So let us go for symbolic gamma:
syms alpha beta gamma
syms rGoal r0
J_BF_inB = [0,-cos(beta+gamma)-cos(beta),cos(alpha)*(cos(beta+gamma)+cos(beta)+1),
-sin(alpha)*(sin(beta+gamma)+sin(beta)),-sin(beta+gamma)*sin(alpha);...
sin(alpha)*(cos(beta+gamma)+cos(beta)+1),cos(alpha)*(sin(beta+gamma)+...
sin(beta)),sin(beta+gamma)*cos(alpha)]
dq = pinv(J_BF_inB)*(rGoal-r0)
dq = subs(dq,[alpha,beta,gamma],[0,0.52,1.04])
What now?
Well, that comma at the end of the first line of your definition of J_BF_inB: are the things on the second line intended to be a continuation of the first line? If so then you would have 5 components in the first row, but only 3 in the second row (which would start where you have the semi-colon)
With your current coding, you have
[value1,value2,value3,
value4,value5;...
value6,value7+...
value8,value9]
and the way continuation lines work in MATLAB, that would be equivalent to
[value1,value2,value3,
value4,value5; value6,value7+ value8,value9]
and within [], MATLAB treats end of line (not preceeded with ... continuation marker) as a semi-colon, so that would be equivalent to
[value1,value2,value3,;value4,value5; value6,value7+ value8,value9]
In MATLAB, it is valid to have an extra comma before a semi-colon, and the extra comma will be ignored. Also, value7+ value8 will be treated as a single addition, plus(value7,value8): the odd spacing of no space after the first term but space before the second term is acceptable in MATLAB, and is all part of the same expression. (In MATLAB, inside [] it is different to have [value7+ value8] than it is to have [value7 +value8] with the second of those being equivalent to [value7,+value8] which is [value8,uplus(value8)] where uplus is the "unary plus" operator.)
So, that would be equivalent to
[value1,value2,value3;value4,value5;value6,value7+value8,value9]
Notice that is 3 items in the first row, 2 items in the second row, and 3 items in the third row.... which is inconsistent.
I will arbitrarily add a value into the second row, to see if we can get further
tic
syms alpha beta gamma real
syms rGoal r0 real
syms arbitrary real
J_BF_inB = [0,-cos(beta+gamma)-cos(beta),cos(alpha)*(cos(beta+gamma)+cos(beta)+1),
arbitrary,-sin(alpha)*(sin(beta+gamma)+sin(beta)),-sin(beta+gamma)*sin(alpha);...
sin(alpha)*(cos(beta+gamma)+cos(beta)+1),cos(alpha)*(sin(beta+gamma)+...
sin(beta)),sin(beta+gamma)*cos(alpha)]
dq = pinv(J_BF_inB)*(rGoal-r0)
dq = subs(dq,[alpha,beta,gamma],[0,0.52,1.04])
toc
Well, at least that is something that could be double() if your arbitary and r_0 and rGoal were numeric.
If you try to put the arbitrary as the second or third element of the second row, then the result of the pinv will be something that gives a division by 0 when you substitute 0 for alpha.
Ken
on 14 Feb 2022
Walter Roberson
on 14 Feb 2022
It helps solve your problem by pointing out where you went wrong on constructing the matrix.
It continues from there in stating that if you put in an arbitrary value for the 2nd or 3rd element of the middle row of the matrix (the one that is missing an element) then you get a singularity when you substitute alpha = 0, which makes it less likely (but not impossible) that the missing element is in the second or third position.
It then shows that if you put an arbitrary value as the first element of the second row, so that you can get out a 3 x 3 matrix, then you can calculate pinv(J_BF_inB)*(rGoal-r0) and then substitute in alpha, beta, gamma values .
How does it help you solve your overall question? Well it helps you debug the problem and shows you the kind of operations that can be done.
Does it solve the overall problem? Certainly not. As I have been explaining to you, your approach is wrong. Over in https://www.mathworks.com/matlabcentral/answers/1648515-unable-to-run-pinv-moore-penrose-with-accuracy-limit#answer_895320 I described the steps you need to take.
Ken
on 14 Feb 2022
Categories
Find more on Mathematics and Optimization 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!


