Search code examples
matlabvectorizationbsxfun

Matlab - Singleton expansion for more than two inputs


I have a function that takes in more than 2 variables

eg.

testFunction = @(x1, x2, x3, x4) x1.*x2.*x3.*x4;
testFunction2 = @(x1, x2, x3) sin(x1.*x2.^x3);

Is there a function available like bsxfun that allows singleton expansion for functions with more that 2 inputs?

example of bsxfun

binaryTestFunction = @(x1, x2) x1.*x2;
x1 = 9*eye(10);
x2 = 3*ones(10,1);
A = bsxfun(binaryTestFunction , x1 , x2);

Expands the singleton dimension in the x2 vector.
bsxfun is faster than repmat and also highly iterative and hence I want to know if singleton expansion my testFunction is possible.


Solution

  • You can define your own class which enables automatic usage of bsxfun:

    classdef bdouble < double
        %BDOUBLE double with automatic broadcasting enabled
    
        methods
            function obj=bdouble(data)
                obj = obj@double(data);
            end
            function r=plus(x,y)
                r=bsxfun(@plus,x,y);
            end
            function r=minus(x,y)
                r=bsxfun(@minus,x,y);
            end
            function r=power(x,y)
                r=bsxfun(@power,x,y);
            end
            function r=times(x,y)
                r=bsxfun(@times,x,y);
            end
            function r=rdivide(x,y)
                r=rdivide(@rdivide,x,y);
            end
            function r=ldivide(x,y)
                r=ldivide(@ldivide,x,y);
            end 
        end
    end
    

    Usage:

     testFunction(bdouble([1:3]),bdouble([1:4]'),bdouble(cat(3,1,1)),bdouble(1))
    

    If you prefer bsxfun syntax, you can put this on top:

    function varargout=nbsxfun(fun,varargin)
    varargout=cell(1:nargout);
    for idx=1:numel(varargin)
        if isa(varargin{idx},'double')
            varargin{idx}=bdouble(varargin{idx});
        end
    end
    varargout{1:max(nargout,1)}=fun(varargin{:});
    end
    

    Example:

    n=nbsxfun(testFunction,[1:3],[1:4]',cat(3,1,1),4)