tsa/ 0000775 0023567 0023567 00000000000 12635260607 012064 5 ustar schloegl schloegl tsa/src/ 0000775 0023567 0023567 00000000000 12635260607 012653 5 ustar schloegl schloegl tsa/src/Makefile 0000664 0023567 0023567 00000011071 12635260607 014313 0 ustar schloegl schloegl ####################################################
# Copyright 2010,2011,2012 Alois Schloegl
# This is part of the TSA-toolbox - a statistics and machine learning toolbox for data with and without missing values.
# http://pub.ist.ac.at/~schloegl/matlab/tsa/
####################################################
### modify directories according to your needs
# Define non-default octave-version
# Octave - global install (e.g. from debian package)
# OCTAVE_VERSION=
# Better alternative: define an OCTAVE_VERSION bash variable (or in .bashrc or .profile)
# OCTAVE_VERSION=-3.6.3
# Matlab configuration
# MATLABDIR = /usr/local/MATLAB/R2010b
# comment the following line if you use MATLAB on 32-bit operating system
MEX_OPTION += -largeArrayDims
# Mingw crosscompiler: available at http://www.nongnu.org/mingw-cross-env/
CROSS = $(HOME)/src/mxe/usr/bin/i686-w64-mingw32.static
CROSS64 = $(HOME)/src/mxe/usr/bin/x86_64-w64-mingw32.static
# include directory for Win32-Matlab include
W32MAT_INC = -I$(HOME)/bin/win32/Matlab/R2010b/extern/include/
W64MAT_INC = -I$(HOME)/bin/win64/Matlab/R2010b/extern/include/
# path to GNUMEX libraries, available from here http://sourceforge.net/projects/gnumex/
GNUMEX = $(HOME)/bin/win32/gnumex
GNUMEX64 = $(HOME)/bin/win64/gnumex
# building gnumex64 was difficult, these hints were quite useful:
# http://sourceforge.net/mailarchive/forum.php?thread_name=AANLkTinZvxgC9ezp2P3UCX_a7TAUYuVsp2U40MQUV6qr%40mail.gmail.com&forum_name=gnumex-users
# Instead of building "mex shortpath.c" and "mex uigetpath.c", I used empty m-functions within argout=argin;
####################################################
W32MAT_INC += -I$(subst /usr/bin/,/usr/,$(CROSS))/include/
W64MAT_INC += -I$(subst /usr/bin/,/usr/,$(CROSS64))/include/
LDLIBS_W32 = $(subst /usr/bin/,/usr/,$(CROSS))/lib/
LDLIBS_W64 = $(subst /usr/bin/,/usr/,$(CROSS64))/lib/
W32_LIBS = $(LDLIBS_W32)liblapack.a
W64_LIBS = $(LDLIBS_W64)liblapack.a
W32_LIBS += $(LDLIBS_W32)libblas.a
W64_LIBS += $(LDLIBS_W64)libblas.a
CC ?= gcc
CXX ?= g++
CFLAGS = -Wall -Wextra -Wconversion -O2 -fPIC
OCTMEX = mkoctfile$(OCTAVE_VERSION) --mex -lgomp
RM = rm
ifneq (Darwin,$(shell uname))
CFLAGS += -fopenmp
MEX_OPTION += -lgomp
endif
MEX_OPTION += CC\#$(CXX) CXX\#$(CXX) CFLAGS\#"$(CFLAGS)" CXXFLAGS\#"$(CFLAGS)"
MATMEX = $(MATLABDIR)/bin/mex $(MEX_OPTION)
PROGS = covm_mex.mex sumskipnan_mex.mex #
### per default only the mex-files for octave are built
mex4o octave: $(PROGS)
### Matlab configuration - search for a matlab directory if not defined above
ifeq (,$(MATLABDIR))
ifneq (,$(shell ls -1 /usr/local/ |grep MATLAB))
# use oldest, typically mex-files a compatible with newer Matlab versions
MATLABDIR=/usr/local/MATLAB/$(shell ls -1rt /usr/local/MATLAB/ |grep "^R*" |head -1)
endif
endif
### if MATLABDIR has been found or defined
ifneq (,$(MATLABDIR))
ifneq (,$(shell ls -1 $(MATLABDIR)/bin/mexext))
MEX_EXT=$(shell $(MATLABDIR)/bin/mexext)
mex4m matlab: $(patsubst %.mex, %.$(MEX_EXT), $(PROGS))
endif
endif
mexw32 win32: $(patsubst %.mex, %.mexw32, $(PROGS))
mexw64 win64: $(patsubst %.mex, %.mexw64, $(PROGS))
all: octave win32 win64 mex4m
clean:
-$(RM) *.o *.obj *.o64 core octave-core *.oct *~ *.mex*
#########################################################
# Octave, MATLAB on Linux
#########################################################
%.oct: %.cc
mkoctfile$(OCTAVE_VERSION) "$<"
%.mex: %.cpp
$(OCTMEX) "$<" -llapack -lblas
%.$(MEX_EXT): %.cpp
$(MATMEX) "$<" -llapack -lblas
#########################################################
# MATLAB/WIN32
#########################################################
%.obj: %.cpp
$(CROSS)-$(CXX) -fopenmp -c -DMATLAB_MEX_FILE -x c++ -o "$@" $(W32MAT_INC) -O2 -DMX_COMPAT_32 "$<"
%.obj: %.c
$(CROSS)-$(CXX) -fopenmp -c -DMATLAB_MEX_FILE -x c++ -o "$@" $(W32MAT_INC) -O2 -DMX_COMPAT_32 "$<"
%.mexw32: %.obj
$(CROSS)-$(CXX) -shared $(GNUMEX)/mex.def -o "$@" -L$(GNUMEX) -s "$<" -llibmx -llibmex -llibmat -lcholmod -lgomp -lpthread -L$(LDLIBS_W32) -lblas -llapack
#########################################################
# MATLAB/WIN64
#########################################################
## ToDO: fix OpenMP support: currently -fopenmp causes Matlab to crash
%.o64: %.cpp
$(CROSS64)-$(CXX) -c -DMATLAB_MEX_FILE -x c++ -o "$@" $(W64MAT_INC) -O2 "$<"
%.o64: %.c
$(CROSS64)-$(CXX) -c -DMATLAB_MEX_FILE -x c++ -o "$@" $(W64MAT_INC) -O2 "$<"
%.mexw64: %.o64
$(CROSS64)-$(CXX) -shared $(GNUMEX64)/mex.def -o "$@" -L$(GNUMEX64) -s "$<" -llibmx -llibmex -llibmat -lcholmod -lgomp -lpthread -L$(LDLIBS_W64) -lblas -llapack
tsa/src/covm_mex.cpp 0000664 0023567 0023567 00000047110 12635260607 015177 0 ustar schloegl schloegl /*
//-------------------------------------------------------------------
// C-MEX implementation of COVM - 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 3 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, see .
//
//
// covm: in-product of matrices, NaN are skipped.
// usage:
// [cc,nn] = covm_mex(X,Y,flag,W);
//
// Input:
// - X:
// - Y: [optional], if empty, Y=X;
// - flag: if not empty, it is set to 1 if some NaN was observed
// - W: weight vector to compute weighted correlation
//
// Output:
// - CC = X' * sparse(diag(W)) * Y while NaN's are skipped
// - NN = real(~ISNAN(X)')*sparse(diag(W))*real(~ISNAN(Y)) count of valid (non-NaN) elements
// computed more efficiently
//
// $Id: covm_mex.cpp 12883 2015-11-30 14:20:02Z schloegl $
// Copyright (C) 2009,2010,2011 Alois Schloegl
// This function is part of the NaN-toolbox
// http://pub.ist.ac.at/~schloegl/matlab/NaN/
//
//-------------------------------------------------------------------
*/
#ifdef __GNUC__
#include
#endif
#include
#include "mex.h"
/*#define NO_FLAG*/
/*
math.h has isnan() defined for all sizes of floating point numbers,
but c++ assumes isnan(double), causing possible conversions for float and long double
*/
#define ISNAN(a) (a!=a)
void mexFunction(int POutputCount, mxArray* POutput[], int PInputCount, const mxArray *PInputs[])
{
double *X0=NULL, *Y0=NULL, *W=NULL;
double *CC;
double *NN = NULL;
size_t rX,cX,rY,cY;
size_t i;
char flag_isNaN = 0;
int ACC_LEVEL;
/*********** check input arguments *****************/
// check for proper number of input and output arguments
if ((PInputCount <= 0) || (PInputCount > 5)) {
mexPrintf("usage: [CC,NN] = covm_mex(X [,Y [,flag [,W [,'E']]]])\n\n");
mexPrintf("Do not use COVM_MEX directly, use COVM instead. \n");
/*
mexPrintf("\nCOVM_MEX computes the covariance matrix of real matrices and skips NaN's\n");
mexPrintf("\t[CC,NN] = covm_mex(...)\n\t\t computes CC=X'*Y, NN contains the number of not-NaN elements\n");
mexPrintf("\t\t CC./NN is the unbiased covariance matrix\n");
mexPrintf("\t... = covm_mex(X,Y,...)\n\t\t computes CC=X'*sparse(diag(W))*Y, number of rows of X and Y must match\n");
mexPrintf("\t... = covm_mex(X,[], ...)\n\t\t computes CC=X'*sparse(diag(W))*X\n");
mexPrintf("\t... = covm_mex(...,flag,...)\n\t\t if flag is not empty, it is set to 1 if some NaN occured in X or Y\n");
mexPrintf("\t... = covm_mex(...,W)\n\t\t W to compute weighted covariance, number of elements must match the number of rows of X\n");
mexPrintf("\t\t if isempty(W), all weights are 1\n");
mexPrintf("\t[CC,NN]=covm_mex(X,Y,flag,W)\n");
*/ return;
}
if (POutputCount > 2)
mexErrMsgTxt("covm.MEX has 1 to 2 output arguments.");
// get 1st argument
if(mxIsDouble(PInputs[0]) && !mxIsComplex(PInputs[0]) && !mxIsSparse(PInputs[0]) )
X0 = mxGetPr(PInputs[0]);
else
mexErrMsgTxt("First argument must be non-sparse REAL/DOUBLE.");
rX = mxGetM(PInputs[0]);
cX = mxGetN(PInputs[0]);
// get 2nd argument
if (PInputCount > 1) {
if (!mxGetNumberOfElements(PInputs[1]))
; // Y0 = NULL;
else if (mxIsDouble(PInputs[1]) && !mxIsComplex(PInputs[1]))
Y0 = mxGetPr(PInputs[1]);
else
mexErrMsgTxt("Second argument must be REAL/DOUBLE.");
}
// get weight vector for weighted sumskipnan
if (PInputCount > 3) {
// get 4th argument
size_t nW = mxGetNumberOfElements(PInputs[3]);
if (!nW)
;
else if (nW == rX)
W = mxGetPr(PInputs[3]);
else
mexErrMsgTxt("number of elements in W must match numbers of rows in X");
}
#ifdef __GNUC__
ACC_LEVEL = 0;
{
mxArray *LEVEL = NULL;
int s = mexCallMATLAB(1, &LEVEL, 0, NULL, "flag_accuracy_level");
if (!s) {
ACC_LEVEL = (int) mxGetScalar(LEVEL);
}
mxDestroyArray(LEVEL);
}
// mexPrintf("Accuracy Level=%i\n",ACC_LEVEL);
#endif
if (Y0==NULL) {
Y0 = X0;
rY = rX;
cY = cX;
}
else {
rY = mxGetM(PInputs[1]);
cY = mxGetN(PInputs[1]);
}
if (rX != rY)
mexErrMsgTxt("number of rows in X and Y do not match");
/*********** create output arguments *****************/
POutput[0] = mxCreateDoubleMatrix(cX, cY, mxREAL);
CC = mxGetPr(POutput[0]);
if (POutputCount > 1) {
POutput[1] = mxCreateDoubleMatrix(cX, cY, mxREAL);
NN = mxGetPr(POutput[1]);
}
/*********** compute covariance *****************/
#if 0
/*------ version 1 ---------------------
this solution is slower than the alternative solution below
for transposed matrices, this might be faster.
*/
for (k=0; k 2) && mxGetNumberOfElements(PInputs[2])) {
// set FLAG_NANS_OCCURED
switch (mxGetClassID(PInputs[2])) {
case mxDOUBLE_CLASS:
*(double*)mxGetData(PInputs[2]) = 1.0;
break;
case mxSINGLE_CLASS:
*(float*)mxGetData(PInputs[2]) = 1.0;
break;
case mxLOGICAL_CLASS:
case mxCHAR_CLASS:
case mxINT8_CLASS:
case mxUINT8_CLASS:
*(char*)mxGetData(PInputs[2]) = 1;
break;
#ifdef __GNUC__
case mxINT16_CLASS:
case mxUINT16_CLASS:
*(uint16_t*)mxGetData(PInputs[2]) = 1;
break;
case mxINT32_CLASS:
case mxUINT32_CLASS:
*(uint32_t*)mxGetData(PInputs[2])= 1;
break;
case mxINT64_CLASS:
case mxUINT64_CLASS:
*(uint64_t*)mxGetData(PInputs[2]) = 1;
break;
case mxFUNCTION_CLASS:
case mxUNKNOWN_CLASS:
case mxCELL_CLASS:
case mxSTRUCT_CLASS:
#endif
default:
mexPrintf("Type of 3rd input argument cannot be used to return status of NaN occurrence.");
}
}
#endif
#endif
}
tsa/src/histo_mex.cpp 0000664 0023567 0023567 00000026457 12635260607 015374 0 ustar schloegl schloegl //-------------------------------------------------------------------
// C-MEX implementation of Histogram - 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 3 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, see .
//
//
// histo_mex: computes histogram
//
// Input:
// - data matrix
// - flag for row-wise histogram
//
// Output:
// - histogram
// HIS.X
// HIS.H
//
// $Id: histo_mex.cpp 12878 2015-09-12 14:59:20Z schloegl $
// Copyright (C) 2009,2010,2011 Alois Schloegl
// This function is part of the NaN-toolbox
// http://pub.ist.ac.at/~schloegl/matlab/NaN/
//
//-------------------------------------------------------------------
/* TODO:
speed: its slower than the m-functions histo2/3/4
|-> use a more efficient sorting function
resembling of histo3 for multicolumn data.
support of complex data and char-strings
*/
#include
#include
#include
#include "mex.h"
/*
math.h has isnan() defined for all sizes of floating point numbers,
but c++ assumes isnan(double), causing possible conversions for float and long double
*/
#define ISNAN(a) (a!=a)
#ifdef tmwtypes_h
#if (MX_API_VER<=0x07020000)
typedef int mwSize;
#endif
#endif
struct sort_t {
uint8_t *Table; // data table
size_t Size; // sizeof elements e.g. 4 for single
size_t Stride; // for multicolumn data
size_t N; // number of rows
mxClassID Type; // data type
} Sort;
//inline int compare(const sqize_t *a, const size_t *b) {
int compare(const void *a, const void *b) {
int z = 0;
size_t i = 0;
size_t ix1 = *(size_t*)a;
size_t ix2 = *(size_t*)b;
while ((if2) z = 1;
break;
}
case mxUINT32_CLASS: {
uint32_t f1,f2;
f1 = ((uint32_t*)Sort.Table)[ix1];
f2 = ((uint32_t*)Sort.Table)[ix2];
if (f1f2) z = 1;
break;
}
case mxINT64_CLASS: {
int64_t f1,f2;
f1 = ((int64_t*)Sort.Table)[ix1];
f2 = ((int64_t*)Sort.Table)[ix2];
if (f1f2) z = 1;
break;
}
case mxUINT64_CLASS: {
uint64_t f1,f2;
f1 = ((uint64_t*)Sort.Table)[ix1];
f2 = ((uint64_t*)Sort.Table)[ix2];
if (f1f2) z = 1;
break;
}
case mxSINGLE_CLASS: {
float f1,f2;
f1 = ((float*)Sort.Table)[ix1];
f2 = ((float*)Sort.Table)[ix2];
z = ISNAN(f1) - ISNAN(f2);
if (z) break;
if (f1f2) z = 1;
// else f1==f2 || (isnan(f1) && isnan(f2))
break;
}
case mxDOUBLE_CLASS: {
double f1,f2;
f1 = ((double*)Sort.Table)[ix1];
f2 = ((double*)Sort.Table)[ix2];
z = ISNAN(f1) - ISNAN(f2);
if (z) break;
if (f1f2) z = 1;
// else f1==f2 || (isnan(f1) && isnan(f2))
break;
}
case mxINT16_CLASS: {
int16_t f1,f2;
f1 = ((int16_t*)Sort.Table)[ix1];
f2 = ((int16_t*)Sort.Table)[ix2];
if (f1f2) z = 1;
break;
}
case mxUINT16_CLASS: {
uint16_t f1,f2;
f1 = ((uint16_t*)Sort.Table)[ix1];
f2 = ((uint16_t*)Sort.Table)[ix2];
if (f1f2) z = 1;
break;
}
case mxINT8_CLASS: {
int8_t f1,f2;
f1 = ((int8_t*)Sort.Table)[ix1];
f2 = ((int8_t*)Sort.Table)[ix2];
if (f1f2) z = 1;
break;
}
case mxUINT8_CLASS: {
uint8_t f1,f2;
f1 = ((uint8_t*)Sort.Table)[ix1];
f2 = ((uint8_t*)Sort.Table)[ix2];
if (f1f2) z = 1;
break;
}
default:
mexErrMsgTxt("unsupported input type");
}
i++;
ix1 += Sort.Stride;
ix2 += Sort.Stride;
}
return(z);
}
void mexFunction(int POutputCount, mxArray* POutput[], int PInputCount, const mxArray *PInputs[])
{
const mwSize *SZ;
char flag_rows = 0;
char done = 0;
size_t j, k, l; // running indices
const mxArray *W = NULL;
double *w = NULL;
// check for proper number of input and output arguments
if ((PInputCount <= 0) || (PInputCount > 3)) {
mexPrintf("HISTO_MEX computes histogram from vector or column matrices\n\n");
mexPrintf("usage:\tHIS = histo_mex(Y)\n\t\tComputes histogram from each column\n");
mexPrintf("\t[HIS,tix] = histo_mex(Y,'rows')\n\t\tComputes row-wise histogram, tix is useful for data compression.\n\t\t Y = HIS.X(tix,:); \n\n");
mexPrintf("see also: HISTO2, HISTO3, HISTO4\n\n");
mexErrMsgTxt("HISTO_MEX requires 1 or 2 input arguments\n");
}
if (POutputCount > 2)
mexErrMsgTxt("histo.MEX has 1 output arguments.");
// get 1st argument
if (mxIsComplex(PInputs[0]))
mexErrMsgTxt("complex argument not supported (yet). ");
// TODO: support complex argument!
if (PInputCount==1)
; // histo_mex(X)
else if (mxIsChar(PInputs[1])) {
// histo_mex(X,'rows')
char *t = mxArrayToString(PInputs[1]);
flag_rows = !strcmp(t,"rows");
mxFree(t);
// histo_mex(X,'rows',W)
if ((PInputCount>2) && mxIsDouble(PInputs[2])) W = PInputs[2];
}
// histo_mex(X,W)
else if (mxIsDouble(PInputs[1])) {
W = PInputs[1];
}
else
mexErrMsgTxt("Weight vector must be REAL/DOUBLE.");
if (W != NULL) {
if (mxGetM(PInputs[0])==mxGetM(W) )
w = (double*)mxGetData(W);
else
mexErrMsgTxt("number of rows in X and W do not match.");
for (k=0; (k=0.0); k++);
if (k2)
mexErrMsgTxt("Error HISTO.MEX: input must be vector or matrix (no more than two dimensions)");
size_t n = SZ[0];
const char *fnames[] = {"datatype","X","H"};
mxArray *HIS = mxCreateStructMatrix(1, 1, 3, fnames);
mxSetField(HIS,0,"datatype",mxCreateString("HISTOGRAM"));
if (flag_rows || (SZ[1]==1)) {
///***** SORT each column: initialize sorting algorithm
size_t *idx = NULL;
idx = (size_t*) mxMalloc(SZ[0]*sizeof(size_t));
for (n=0; n1) {
POutput[1] = mxCreateNumericMatrix(SZ[0], 1, mxUINT64_CLASS,mxREAL);
tix = (uint64_t*)mxGetData(POutput[1]);
}
// fill HIS.H and HIS.X
mxArray *H = mxCreateNumericMatrix(n, 1, mxDOUBLE_CLASS,mxREAL);
mxArray *X = mxCreateNumericMatrix(n, SZ[1], mxGetClassID(PInputs[0]),mxREAL);
mxSetField(HIS,0,"H",H);
mxSetField(HIS,0,"X",X);
double *h = (double*)mxGetData(H);
uint8_t *x = (uint8_t*)mxGetData(X);
l = 0;
if (tix) tix[idx[0]] = 1;
for (k=0; k