// OCT implementation of SUMSKIPNAN - this function is part of the NaN-toolbox.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//
// $Id: sumskipnan.cc,v 1.4 2005/12/21 21:00:46 adb014 Exp $
// Copyright (C) 2005 by Alois Schloegl <a.schloegl@ieee.org>
// This is part of the NaN-toolbox
// http://www.dpmi.tu-graz.ac.at/~schloegl/matlab/NaN/
#include <octave/oct.h>
DEFUN_DLD (sumskipnan, args, ,
"-*- texinfo -*-\n\
@deftypefn {Loadable Function} {[@var{y}, @var{n}, @var{ssq}] =} sumskipnan (@var{x}, @var{dim})\n\
\n\
Adds all non-NaN values.\n\
\n\
Input:\n\
@table @asis\n\
@item @var{x}\n\
Array to sum\n\
@item @var{dim}\n\
dimension to sum (1=columns; 2=rows; doesn't work for dim>2!!).\n\
Default is 1\n\
@end table\n\
\n\
Output:\n\
@table @asis\n\
@item @var{y}\n\
Sums.\n\
@item @var{n}\n\
Count of valid elements (optional)\n\
@item @var{ssq}\n\
Sums of squares (optional)\n\
@c @item @var{ssqsq}\n\
@c Sums of squares of squares (optional)\n\
@end table\n\
@end deftypefn\n")
{
int DIM = 0;
int ND;
int j, k1, k2, k3, D1, D2, D3, ix1, ix2, N;
dim_vector SZ, SZ2;
double aux, s, n, s2, s4;
octave_value_list retval;
int nargin = args.length ();
if ( args.length() == 2 )
{
Matrix xin2( args(1).matrix_value() );
DIM = (int) xin2(0);
}
else if ( args.length() > 3 )
{
error("SUMSKIPNAN.OCT takes at most 2 arguments");
return retval;
}
warning("SUMSKIPNAN.OCT supports only real double matrices.\n");
// only real double matrices are supported; arrays, integer or complex matrices are not supported (yet)
NDArray xin1( args(0).array_value() );
ND = xin1.ndims ();
SZ = xin1.dims ();
for (j = 0; (DIM < 1) && (j < ND); j++)
if (SZ(j)>1) DIM = j+1;
if (DIM < 1) DIM=1; // in case DIM is still undefined
SZ2 = SZ;
for (j=ND; j<DIM; SZ2(j++)=1);
if (DIM>ND)
{ error("SUMSKIPNAN.OCT: DIM larger than LENGTH(SIZE(X))");
return retval;
}
for (j=0, D1=1; j<DIM-1; D1=D1*SZ(j++)); // D1 is the number of elements between two elements along dimension DIM
D2 = SZ(DIM-1); // D2 contains the size along dimension DIM
for (j=DIM, D3=1; j<ND; D3=D3*SZ(j++)); // D3 is the number of blocks containing D1*D2 elements
SZ2(DIM-1) = 1;
// Currently, only matrices (2D-arrays) are supported. In future, also N-D arrays should be supported.
NDArray xout1(SZ2);
NDArray xout2(SZ2);
NDArray xout3(SZ2);
// NDArray xout4(SZ2);
// OUTER LOOP: along dimensions > DIM
for (k3 = 0; k3<D3; k3++)
{
ix2 = k3*D1; // index for output
ix1 = ix2*D2; // index for input
// Inner LOOP: along dimensions < DIM
for (k1 = 0; k1<D1; k1++, ix1++, ix2++)
{
s = 0.0;
N = 0;
s2 = 0.0;
// s4 = 0.0;
// LOOP along dimension DIM
for (k2=0; k2<D2; k2++)
{
aux = xin1(ix1 + k2*D1);
if (aux==aux) // test for NaN
{
N++;
s += aux;
aux *= aux;
s2 += aux;
// s4 += aux*aux;
}
}
xout1(ix2) = s;
xout2(ix2) = (double) N;
xout3(ix2) = s2;
// xout4(ix2) = s4;
}
}
retval.append(octave_value(xout1));
retval.append(octave_value(xout2));
retval.append(octave_value(xout3));
// retval.append(octave_value(xout4));
}
syntax highlighted by Code2HTML, v. 0.9.1