%PAGEFUN Apply a function to each page of gpuArray
%   PAGEFUN iterates over the pages of a gpuArray, applying the same 
%   function to each page.   
%   
%   A = PAGEFUN(FUN, B) applies the function specified by FUN to each page
%   of the gpuArray B, and returns the results in gpuArray
%   A such that A(:,:,I,J,...) = FUN(B(:,:,I,J,...)).  FUN is a function handle 
%   to a function that takes one two-dimensional input argument.
%   
%   A = PAGEFUN(FUN, B, C, ...) evaluates the function specified by FUN using pages of the 
%   arrays B, C, ... as input arguments with scalar expansion enabled.  Any of the
%   input page dimensions that are scalar will be virtually replicated to match the 
%   size of the other arrays in that dimension so that 
%   A(:,:,I,J,...) = FUN(B(:,:,I,J,...), C(:,:,I,J,...), ...).  At least one of 
%   the inputs B, C, ... must be a gpuArray.  Any other inputs held in CPU 
%   memory are converted to a gpuArray before calling the function.
%   If an array is to be used in several different PAGEFUN calls it is more 
%   efficient to convert that array to a gpuArray before your series of 
%   PAGEFUN calls.  The input pages B(:,:,I, J, ...), C(:,:,I, J, ...), ... must 
%   satisfy all of FUN's input and output requirements.
%   
%   [A, B, ...] = PAGEFUN(FUN, C, ...), where FUN is a function handle
%   to a function that returns multiple outputs, returns gpuArrays
%   A, B,..., each corresponding to one of the output arguments of FUN.  PAGEFUN
%   invokes FUN with as many outputs as there are in the call to PAGEFUN.
%   All elements of A must be the same class; B can be a different class from A, 
%   but all elements of B must be of the same class.
%   
%   PAGEFUN supports most element-wise gpuArray functions for FUN. These functions
%   are also supported:
%       @conv
%       @conv2
%       @ctranspose
%       @fliplr
%       @flipud
%       @inv
%       @mldivide
%       @mrdivide
%       @mtimes
%       @rot90
%       @transpose
%       @tril
%       @triu
%   
%   Examples:
%    
%       M = 3;                                  % output number of rows
%       K = 6;                                  % matrix multiply inner dimension
%       N = 2;                                  % output number of columns
%       P1 = 10;                                % size of first page dimension
%       P2 = 17;                                % size of second page dimension
%       P3 = 4;                                 % size of third page dimension
%       P4 = 12;                                % size of fourth page dimension
%       A = gpuArray.rand(M, K, P1,  1, P3);
%       B = gpuArray.rand(K, N,  1, P2, P3, P4);
%       C = pagefun(@mtimes, A, B);
%       size(C)                                 % M x N x P1 x P2 x P3 x P4
%   
%    
%       M = 300;                     % output number of rows
%       K = 500;                     % matrix multiply inner dimension
%       N = 1000;                    % output number of columns
%       P = 200;                     % number of pages
%       A = gpuArray.rand(M, K);   
%       B = gpuArray.rand(K, N, P);
%       C = pagefun(@mtimes, A, B);
%       size(C)                      % returns M x N x P 
%   
%   See also  GPUARRAY, function_handle, arrayfun, bsxfun, gather, pagemtimes.
%   


%   Copyright 2013-2021 The MathWorks, Inc.
