Mercurial > forge
changeset 1041:eddc036a8113 octave-forge
C-MEX mplementation for SUMSKIPNAN included - thanks to Patrick Houweling
author | schloegl |
---|---|
date | Thu, 18 Sep 2003 13:34:32 +0000 |
parents | 04395a6dc071 |
children | 5085a3b5eb1a |
files | extra/NaN/sumskipnan2.cpp |
diffstat | 1 files changed, 158 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extra/NaN/sumskipnan2.cpp Thu Sep 18 13:34:32 2003 +0000 @@ -0,0 +1,158 @@ +//------------------------------------------------------------------- +#pragma hdrstop +//------------------------------------------------------------------- +// sumskipnan2: sums all non-NaN values +// +// Input: +// - array to sum +// - dimension to sum (1=columns; 2=rows; doesn't work for dim>2!!) +// +// Output: +// - sums +// - count of valid elements (optional) +// - sums of squares (optional) +// - sums of squares of squares (optional) +// +// Author: Patrick Houweling (phouweling@yahoo.com) +// Version: 1.0 +// Date: 17 september 2003 +// +// +// 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 +// +// +//------------------------------------------------------------------- +#include <stdlib> +#include "mex.h" +//------------------------------------------------------------------- +void mexFunction(int POutputCount, mxArray* POutput[], int PInputCount, const mxArray *PInputs[]) +{ + int M, N, m, n; + int i, j; + int LDimension; + double* LInput; + double* LOutputSum; + double* LOutputCount; + double* LOutputSum2; + double* LOutputSum4; + double x, x2; + int LCount; + double LSum, LSum2, LSum4; + + // check for proper number of input and output arguments + if ((PInputCount <= 0) || (PInputCount > 2)) + mexErrMsgTxt("SumSkipNan2 requires 1 or 2 arguments."); + if (POutputCount > 5) + mexErrMsgTxt("SumSkipNan2 has 1 to 4 output arguments."); + + // get 1st argument + if(!mxIsNumeric(PInputs[0])) + mexErrMsgTxt("First argument must be numeric."); + M = mxGetM(PInputs[0]); + N = mxGetN(PInputs[0]); + LInput = mxGetPr(PInputs[0]); + + // get 2nd argument + if (PInputCount == 2){ + if ((!mxIsNumeric(PInputs[1])) || (mxGetM(PInputs[1]) != 1) || (mxGetN(PInputs[1]) != 1)) + mexErrMsgTxt("Second argument must be scalar."); + LDimension = mxGetScalar(PInputs[1]); + if ((LDimension < 0) || (LDimension > 2)) + mexErrMsgTxt("Only dimensions 1 and 2 are supported."); + } + else + LDimension = 1; + + // create outputs + if (LDimension == 1){ + m = 1; + n = N; + } + if (LDimension == 2){ + m = M; + n = 1; + } + POutput[0] = mxCreateDoubleMatrix(m, n, mxREAL); + LOutputSum = mxGetPr(POutput[0]); + if (POutputCount >= 2){ + POutput[1] = mxCreateDoubleMatrix(m, n, mxREAL); + LOutputCount = mxGetPr(POutput[1]); + } + if (POutputCount >= 3){ + POutput[2] = mxCreateDoubleMatrix(m, n, mxREAL); + LOutputSum2 = mxGetPr(POutput[2]); + } + if (POutputCount >= 4){ + POutput[3] = mxCreateDoubleMatrix(m, n, mxREAL); + LOutputSum4 = mxGetPr(POutput[3]); + } + + if (LDimension == 1){ + // sum all non-NaN elements of each column + for (j=0; j<N; j++){ + // init + LCount = 0; + LSum = 0; + LSum2 = 0; + LSum4 = 0; + + for (i=0; i<M; i++){ + x = LInput[i + j*M]; + if (!mxIsNaN(x)){ + LCount++; + LSum += x; + x2 = x*x; + LSum2 += x2; + LSum4 += x2*x2; + } + } + LOutputSum[j] = LSum; + if (POutputCount >= 2) + LOutputCount[j] = LCount; + if (POutputCount >= 3) + LOutputSum2[j] = LSum2; + if (POutputCount >= 4) + LOutputSum4[j] = LSum4; + } + } + if (LDimension == 2){ + // sum all non-NaN elements of each row + for (i=0; i<M; i++){ + // init + LCount = 0; + LSum = 0; + LSum2 = 0; + LSum4 = 0; + + for (j=0; j<N; j++){ + x = LInput[i + j*M]; + if (!mxIsNaN(x)){ + LCount++; + LSum += x; + x2 = x*x; + LSum2 += x2; + LSum4 += x2*x2; + } + } + LOutputSum[i] = LSum; + if (POutputCount >= 2) + LOutputCount[i] = LCount; + if (POutputCount >= 3) + LOutputSum2[i] = LSum2; + if (POutputCount >= 4) + LOutputSum4[i] = LSum4; + } + } +}