Not very MATLABy code and no guarantees:
function cof=cof3x3(m)
% function cof=cof3x3(m)
%
% cofactor matrix of a 3x3 matrix m
%
% m1 m4 m7
% m2 m5 m8
% m3 m6 m9
cof(1,1)=(m(5)*m(9)-m(6)*m(8));
cof(2,1)=-1*(m(4)*m(9)-m(6)*m(7));
cof(3,1)=(m(4)*m(8)-m(5)*m(7));
cof(1,2)=-1*(m(2)*m(9)-m(3)*m(8));
cof(2,2)=(m(1)*m(9)-m(3)*m(7));
cof(3,2)=-1*(m(1)*m(8)-m(2)*m(7));
cof(1,3)=(m(2)*m(6)-m(3)*m(5));
cof(2,3)=-1*(m(1)*m(6)-m(3)*m(4));
cof(3,3)=(m(1)*m(5)-m(2)*m(4));
...snip implementation...
does Matlab realy have no such function? This seems strange given that
matrices is matlab main strength.
In Mathematica this function comes build-in, part of standard package called
Combinatorica , here is an example using it:
<< "Combinatorica`"
m = Table[RandomReal[], {i, 3}, {j, 3}] (*make random 3x3 matrix*)
{{0.9156755376566044, 0.044201843398463225, 0.9510501062833085},
{0.6517228097660346, 0.5536631453244356, 0.34116883508021023},
{0.1931334687360664, 0.06892668106181365, 0.2687111883031803}}
Cofactor[m, {1, 1}] (*find cofactor of m(1,1) *)
0.12525984621600134
I think Matlab should add such a function?
Nasser
If you really want cofactor functions, they're not hard to implement from
the definition:
cofactor = @(A, r, c) (-1)^(r+c)*det(A([1:r-1 r+1:end], [1:c-1 c+1:end]));
or
function d = cofactor(A, r, c)
B = A;
B(r, :) = [];
B(:, c) = [];
d = (-1)^(r+c);
d = d*det(B);
or
cofactor = @(A, r, c) (-1)^(r+c)*det(A(setdiff(1:size(A, 1), r),
setdiff(1:size(A, 2), c)));
Add error checking to taste. The main use case I know of for cofactors is
computing determinants, and we already have a function DET to do that.
*snip*
> I think Matlab should add such a function?
What's you use case? By that, I mean what do you want to use it for? What
would such a function allow you to do that you can't do with the builtin
functions we have now?
--
Steve Lord
sl...@mathworks.com
I need to construct the cofactor matrix of a 3x3 matrix in order to decompose an essential matrix into rotation and translation.
I'm using the transpose of the output of ADJ (the adjoint), on the FEX:
http://www.mathworks.de/matlabcentral/fileexchange/35
Another option would be to use my absolute orientation tool
http://www.mathworks.com/matlabcentral/fileexchange/26186-absolute-orientation-horns-method
Example:
t=[1;2;3]; %A translation vector
%A rotation matrix
R =
0.7660 -0.4924 0.4132
0.6428 0.5868 -0.4924
0 0.6428 0.7660
E=R*xprodmat(t); %An essential matrix - see below for defintion of xprodmat
%%%Now decompose E
n=null(E);
%%first solution
>> sol1=absorientParams(xprodmat(n),E,1); Rotation=sol1.R, Translation=n*sol1.s
Rotation =
-0.6202 0.7841 0.0243
-0.5943 -0.4899 0.6378
0.5120 0.3811 0.7698
Translation =
-1.0000
-2.0000
-3.0000
%%2nd solution
>> sol2=absorientParams(xprodmat(-n),E,1); Rotation=sol2.R, Translation=-n*sol2.s
Rotation =
0.7660 -0.4924 0.4132
0.6428 0.5868 -0.4924
0.0000 0.6428 0.7660
Translation =
1.0000
2.0000
3.0000
function A=xprodmat(a)
%Matrix representation of a cross product
%
% A=xprodmat(a)
%
%in:
%
% a: 3D vector
%
%out:
%
% A: a matrix such that A*b=cross(a,b)
if length(a)<3, v(a)=0; end
ax=a(1);
ay=a(2);
az=a(3);
A=zeros(3);
A(2,1)=az; A(1,2)=-az;
A(3,1)=-ay; A(1,3)=ay;
A(3,2)=ax; A(2,3)=-ax;
Thanks Matt. Your function is actually even better than decomposing my essential matrix, which is computed from only 5 points, not all the inliers.
Sorry, ignore what I just said. It's a different problem. I have only 2d matches in images, not 3d points. I'll look into using your function for the E decomposition though.