Commit acbf7bcf authored by denis's avatar denis

Added persistence1d library to /src

see: https://people.mpi-inf.mpg.de/~weinkauf/notes/persistence1d.html
The source is in C++ and everything is contained in persistence1d.hpp
To make it accessible to ichinscratchy, I added a wrapper that will handle
the C++ specifics and interface with standard C.
Further, the makefile was adapted to the new need of compiling and linking C++
parent eabea2b4
CC = c99
SRCPATH = $(wildcard src/*.c)
OBJPATH = $(addprefix build/,$(notdir $(SRCPATH:.c=.o)))
CC = gcc
CXX = g++
CSRCPATH = $(wildcard src/*.c)
CXXSRCPATH = $(wildcard src/*.cpp)
OBJPATH = $(addprefix build/,$(notdir $(CSRCPATH:.c=.o) $(CXXSRCPATH:.cpp=.o)))
INCLUDES = -I/usr/include/mysql
LIBS = -L/usr/lib/mysql -lmysqlclient -lm
CFLAGS = -lm -Wall -O2 -L/usr/lib/mysql/ -lmysqlclient -pedantic -Wextra
CFLAGS = -lm -Wall -O2 -L/usr/lib/mysql/ -lmysqlclient -pedantic -Wextra -std=c99
CCFLAGS=-Wall -g -std=c++11
LDFLAGS=-g -Wall -lstdc++
all:ichinscratchy
ichinscratchy: $(OBJPATH)
$(CC) -g -o $@ $^ $(LIBS)
$(CC) -g -o $@ $^ $(LIBS) $(LDFLAGS)
build/%.o: src/%.c
$(CC) $(CFLAGS) -g -c $(INCLUDES) -o $@ $<
build/%.o: src/%.cpp
$(CXX) $(CCFLAGS) -g -c -o $@ $<
clean:
rm -f $(OBJPATH)
......
#include "p1d_wrapper.h"
#include "persistence1d.hpp"
using namespace std;
using namespace p1d;
extern "C" {
///////////////////////////////////////////////////////////////////////////////
/**
* @brief "Constructor function" to Persistence1D object
*
* This is the wrapping function for the Persistence1D object constructor, to
* make it available from C
* @return Pointer to new object
*/
///////////////////////////////////////////////////////////////////////////////
Class_Persistence1D *WRAPPER_Persistence1D_new()
{
Persistence1D *object = new Persistence1D;
return (Class_Persistence1D *) object;
}
///////////////////////////////////////////////////////////////////////////////
/**
* @brief "Destructor function" to Persistence1D object
*
* This is the wrapping function for the Persistence1D object destructor, to
* make it available from C
* @param *object Pointer to object
*/
///////////////////////////////////////////////////////////////////////////////
void WRAPPER_Persistence1D_delete(Class_Persistence1D *object)
{
Persistence1D *t = (Persistence1D *) object;
delete t;
}
///////////////////////////////////////////////////////////////////////////////
/**
* @brief fills C++ float vector with data from C-style float Nx1 matrix
*
* fills C++ float vector with data from C-style float Nx1 matrix
* @param *datavec pointer to float Nx1 matrix
* @param nr_data number of values in matrix/vector
* @returns pointer to vector
*/
///////////////////////////////////////////////////////////////////////////////
float *WRAPPER_array2vector(float *datavec, int nr_data)
{
//create vector
vector< float > data;
//fill vector with data (from C-style matrix)
int i;
for(i=0; i< nr_data; i++)
data.push_back(datavec[i]);
return &data[0];
}
///////////////////////////////////////////////////////////////////////////////
/**
* @brief wrapping function to get local minima/maxima from Nx1 float matrix
*
* This function utilizes the Persistence1D class functions to determince
* local minima and maxima in a given float Nx1 matrix. It provides the
* interface in a way that makes it possible to call this function from C code.
* @note the arrays minima and maxima, that contain the indices of the local
* extrema, are resized and filled within this function
* @note Due to the nature of the algorithm there will always be a global
* minimum, which is determined separately by the class function. Thus
* the number of minima will always be by 1 higher than the number of maxima.
* A global maximum is not calculated by the library.
* @param *datavec pointer to float Nx1 matrix with data points
* @param nr_data number of values in matrix
* @param **minima unsigned int matrix with minima
* @param **maxima unsigned int matrix with maxima
* @param *nr_min nr of local minima (equals nr. of local maxima)
* @returns 0 if successful, 1 otherwise
*/
///////////////////////////////////////////////////////////////////////////////
int get_extrema_indices(float *datavec, int nr_data, unsigned int **minima, unsigned int **maxima, unsigned int *nr_min)
{
//create vector
vector< float > data;
//fill vector with data (from C-style matrix)
int i;
for(i=0; i< nr_data; i++)
data.push_back(datavec[i]);
// create vectors for local minima/maxima and paired extrema
vector<int> min, max;
vector<TPairedExtrema> pairs;
int globalMinIndex; // index for global minimum
// create instance of persistence1d object, run iton the data
Persistence1D p;
p.RunPersistence(data);
// extract the indices of local extrema
p.GetExtremaIndices(min, max);
// additionally get the index of global minimum
globalMinIndex = p.GetGlobalMinimumIndex();
p.GetPairedExtrema(pairs);
// float filterThreshold = (pairs.front().Persistence + pairs.back().Persistence)/2;
// p.GetExtremaIndices(min, max, filterThreshold);
// create C-style parameters that store numbers of extremas
unsigned int nr_local_minima = static_cast<unsigned int>(min.size());
unsigned int nr_local_maxima = static_cast<unsigned int>(max.size());
*nr_min = nr_local_minima;
// resize the given extrema arrays according to nr of found extremas
*minima = (unsigned int*) realloc(*minima, (nr_local_minima+1) * sizeof(unsigned int));
*maxima = (unsigned int*) realloc(*maxima, nr_local_maxima * sizeof(unsigned int));
// fill arrays with indices of extremas
for(i=0; i<nr_local_minima; i++)
{
(*minima)[i]=min[i];
(*maxima)[i]=max[i];
}
// finally add global minimum index
(*minima)[nr_local_minima] = p.GetGlobalMinimumIndex();
// thats it :)
return 0;
}
}
typedef void Class_Persistence1D;
#ifdef __cplusplus
extern "C" {
#endif
Class_Persistence1D *WRAPPER_Persistence1D_new();
void WRAPPER_Persistence1D_delete(Class_Persistence1D *object);
float *WRAPPER_array2vector(float *datavec, int nr_data);
int get_extrema_indices(float *datavec, int nr_data, unsigned int **minima,unsigned int **maxima, unsigned int *nr_min);
#ifdef __cplusplus
}
#endif
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment