Home > Net >  Overload times() and mtimes() with element-wise operation
Overload times() and mtimes() with element-wise operation

Time:12-07

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
  • Related