I have a class in Matlab in which I have overloaded the mtimes(a,b) = a*b
operation.
For instance, I can do:
A = MyClass(1);
B = MyClass(2);
A*B; % ->that works
I would like to be able to use
[A B C].*[D ; E]
while using the element-wise behavior of Matlab, but with my definition of *
. For instance, while dealing with matrices of compatible size but not identical:
A = [1 2 3]; B = [1;2]
Matlab gives
A.*B
ans =
1 2 3
2 4 6
How can I overload times(a,b) = a.*b
in order to have the element-wise behavior of Matlab?
CodePudding user response:
I would think you need to loop over your arrays, and have a special case where, if for one dimension one of the inputs has size 1 and the other doesn't, then the same element for that array is used. A simple way to accomplish this is to index with (i-1)*step 1
, where step
is 0 if the array has size 1, and 1 otherwise.
One thing to note is that, in your overloaded method, indexing doesn't use your custom indexing definition (subsref
and subsasgn
), but the built-in one.
For example, assuming you only allow 2D arrays of your class:
function C = times(A, B)
szA = size(A);
szB = size(B);
if numel(szA)~=2 || numel(szB)~=2
error('Only 2D arrays are supported')
end
szC = max(szA, szB);
stepA = [matchSizes(szA(1), szC(1)), matchSizes(szA(2), szC(2))];
stepB = [matchSizes(szB(1), szC(1)), matchSizes(szB(2), szC(2))];
C = MyClass.empty(szC);
for jj = 1:szC(2)
for ii = 1:szC(1)
C(ii,jj) = A((ii-1)*stepA(1) 1,(jj-1)*stepA(2) 1) * B((ii-1)*stepB(1) 1,(jj-1)*stepB(2) 1);
end
end
% private helper function, keep in the same file
function step = matchSizes(szIn, szOut)
step = 1;
if szIn ~= szOut
if szIn == 1
step = 0;
else
error('Sizes not compatible')
end
end
NOTE: Code not tested.
NOTE2: This is one of the cases where 0-based indexing is more convenient!
CodePudding user response:
If MyClass
has a property val
to store numeric values I think (hope) that this should be possible (not tested):
function obj = times(A, B)
r = reshape([A.val], size(A)) .* reshape([B.val], size(B));
obj = arrayfun(@MyClass, r);
end