summaryrefslogtreecommitdiff
path: root/macros/cummax.sci
diff options
context:
space:
mode:
Diffstat (limited to 'macros/cummax.sci')
-rw-r--r--macros/cummax.sci196
1 files changed, 196 insertions, 0 deletions
diff --git a/macros/cummax.sci b/macros/cummax.sci
new file mode 100644
index 0000000..672dc5c
--- /dev/null
+++ b/macros/cummax.sci
@@ -0,0 +1,196 @@
+function M = cummax(varargin)
+ // Cumulative maximum
+ //
+ // Calling Sequence
+ // M = cummax(A)
+ // returns the cumulative maximum of the arguments of A. The dimension
+ // of M is same as the dimension of A. If A is a 2D matrix, the operation
+ // is performed along the columns. For a hypermatrix, the operation is
+ // performed along the first non-zero dimension
+ // M = cummax(A,dim)
+ // The operation is performed along the dimension specified by dim
+ // M = cummax(_,direction)
+ // direction specifies as the direction of operation
+ //
+ // Parameters
+ // A - real|complex numbers - vector|matrix
+ // Input Array
+ // For complex elements, cummax compares the magnitude of elements. If
+ // the magnitude are same, phase angles are compared.
+ // dim - positive integer - scalar
+ // Dimension to operate along
+ // If no dimension is specified, then the default value is the first
+ // array dimension whose value is greater than 1
+ // direction - string flag - 'forward' (default) or 'reverse'
+ // Direction of cumulation
+ // If the direction is forward, cummax works from 1 to end of the active
+ // dimension. Otherwise, it works in the opposite sense
+ //
+ // Examples
+ // 1) Cumulative maximum values in a vector
+ // v = [8 9 1 10 6 1 3 6 10 10]
+ // M = cummax(v)
+ //
+ // Expected output: [8 8 1 1 1 1 1 1 1 1]
+ //
+ // Authors
+ // Ayush Baid
+ //
+ // See Also
+ // cummax | cumprod | cumsum | max | max
+
+
+
+ [numOutArgs,numInArgs] = argn(0);
+
+ // ** Checking number of arguments
+
+ if numInArgs<1 | numInArgs>3 then
+ msg = "cummax: Wrong number of input argument; 1-6 expected";
+ error(77,msg);
+ end
+
+ if numOutArgs~=1 then
+ msg = "cummax: Wrong number of output argument; 1 expected";
+ error(78,msg);
+ end
+
+
+ // ** Parsing input args **
+
+ // defining default arguments
+ isForward = %t;
+ dim = [];
+ directionArg = "";
+ A = varargin(1);
+
+ // A should contain numeric entries
+ if ~(type(A)==1 | type(A)==8 | type(A)==17) then
+ msg = "cummax: Wrong type for argument #1 (A); Real or complex entries expected ";
+ error(53,msg);
+ end
+
+ if numInArgs>1 then
+ temp = varargin(2);
+ if type(temp)==10 then
+ // it is the direction argument
+ directionArg = temp;
+ elseif type(temp)==1 | type(temp)==8 then
+ dim = int(temp);
+ else
+ msg = "cummax: Wrong type for argument #2; Either dim (integer) or direction (string) expected";
+ error(53,msg);
+ end
+ end
+
+ if numInArgs>2 then
+ directionArg = varargin(3);
+ if type(directionArg)~=10 then
+ msg = "cummax: Wrong type for argument #3 (direction); String expected";
+ error(53,msg);
+ end
+ end
+
+ if isempty(dim) then
+ dimArray = 1:ndims(A);
+ dim = find(size(A)~=1,1);
+ end
+
+ // additional checks on dim
+ if size(A,dim)==1 then
+ M = A;
+ return
+ end
+
+ // extracting direction
+ if strcmpi(directionArg,"reverse")==0 then
+ isForward = %f;
+ elseif strcmpi(directionArg,"forward")==0 then
+ isForward = %t;
+ elseif strcmpi(directionArg,"")~=0 then
+ msg = "cummax: Wrong value for argument #3 (direction)";
+ error(53,msg);
+ end
+
+ sizeA = size(A);
+ sizeDim = size(A,dim);
+
+ // restructuring A into a 3D matrix with the specified dimension as the middle elements
+
+ leftSize = prod(sizeA(1:dim-1));
+ rightSize = prod(sizeA(dim+1:$));
+ middleSize = sizeDim;
+
+
+ A_ = matrix(A,[leftSize,middleSize,rightSize]);
+ M_ = zeros(leftSize,middleSize,rightSize);
+
+ for i=1:leftSize
+ for j=1:rightSize
+ M_(i,:,j) = cummaxVec(A_(i,:,j),isForward);
+ end
+ end
+
+ M = matrix(M_,sizeA);
+
+endfunction
+
+
+function out = cummaxVec(inp,isForward)
+ // performs cummax on vector inputs
+
+ if isForward then
+ startIndex=1;
+ endIndex = length(inp);
+ step = 1;
+ else
+ startIndex=length(inp);
+ endIndex = 1;
+ step = -1;
+ end
+
+ out(startIndex) = inp(startIndex);
+ if isreal(inp) then
+ for i=startIndex+step:step:endIndex
+ if isnan(out(i-step)) then
+ out(i) = inp(i);
+ elseif inp(i)>=out(i-step) then
+ out(i) = inp(i);
+ else
+ out(i) = out(i-step);
+ end
+ end
+ else
+ magVec = abs(inp);
+ phaseVec = atan(imag(inp),real(inp));
+
+ // phase - first compare absolute value; then give priority to positive phases
+
+ prevMag = magVec(startIndex);
+ prevPhase = phaseVec(startIndex);
+
+ for i=(startIndex+step):step:endIndex
+ if isnan(out(i-step)) then
+ out(i) = inp(i);
+ prevMag = magVec(i);
+ prevPhase = phaseVec(i);
+ elseif magVec(i)>prevMag then
+ out(i) = inp(i);
+ prevMag = magVec(i);
+ prevPhase = phaseVec(i);
+ elseif magVec(i)<prevMag then
+ out(i) = out(i-step);
+ else
+ if phaseVec(i)>prevPhase then
+ out(i) = inp(i);
+ prevMag = magVec(i);
+ prevPhase = phaseVec(i);
+ else
+ out(i) = out(i-step);
+ end
+ end
+ end
+ end
+
+
+endfunction