added current c++ code

This commit is contained in:
2016-01-02 17:40:22 +01:00
parent b58fb8f27b
commit 7ce2718306
11 changed files with 2611 additions and 454 deletions

112
workspace/pca/Data.h Normal file
View File

@@ -0,0 +1,112 @@
#ifndef TRAINDATA_H
#define TRAINDATA_H
#include "Settings.h"
#include <KLib/fs/File.h>
#include "../Interpolator.h"
#include "../sensors/SensorReader.h"
struct ClassifiedPattern {
std::string className;
std::vector<float> pattern;
ClassifiedPattern(const std::string& className, const std::vector<float>& pattern) : className(className), pattern(pattern) {;}
};
struct ClassifiedFeature {
std::string className;
std::vector<float> feature;
ClassifiedFeature(const std::string& className, const std::vector<float>& feature) : className(className), feature(feature) {;}
ClassifiedFeature() : className("??????") {;}
/** get the l2- distance to the given vector */
float getDistance(const std::vector<float>& vec) const {
if (vec.size() != feature.size()) {throw "error!";}
float dist = 0;
for (int i = 0; i < (int)vec.size(); ++i) {dist += (vec[i]-feature[i])*(vec[i]-feature[i]);}
return std::sqrt(dist);
}
};
struct ClassifiedDataFile {
std::string className;
std::string fileName;
ClassifiedDataFile(const std::string& className, const std::string& fileName) : className(className), fileName(fileName) {;}
};
class Data {
public:
/** get X data-files for each class */
static std::vector<ClassifiedDataFile> getDataFiles(const int filesPerClass) {
Settings s;
std::vector<ClassifiedDataFile> files;
K::File folder(s.path);
for (const std::string& className : s.classNames) {
K::File classFolder(folder, className);
int i = 0;
for (const K::File classFile : classFolder.listFiles()) {
const std::string fileName = classFile.getAbsolutePath();
if (fileName[fileName.length()-1] == 'm') {continue;}
if (++i > filesPerClass) {break;}
ClassifiedDataFile cdf(className, fileName);
files.push_back(cdf);
}
}
return files;
}
/** get sample date from the given data-file */
static std::vector<std::vector<float>> getSamples(const std::string fileName, const int windowSize_ms, const int regionStart_ms, const float regionPercent, const int stepSize_ms) {
// read all sensor-values within the given data-file
Recording rec = SensorReader::read(fileName);
// get the value-interpolator
K::Interpolator<uint64_t, SensorAccelerometer> intAccel;
for (const auto& val : rec.accel.values) {intAccel.add(val.ts, val.val);}
intAccel.makeRelative();
const int regionEnd_ms = intAccel.values.back().key * regionPercent;
// construct all sample windows
std::vector<std::vector<float>> samples;
for (int center = regionStart_ms; center < regionEnd_ms; center += stepSize_ms) {
std::vector<float> window = getSampleWindow(intAccel, center, windowSize_ms, stepSize_ms);
samples.push_back(window);
}
return samples;
}
template <typename T> static std::vector<float> getSampleWindow(K::Interpolator<uint64_t, T>& interpol, const int center_ms, const int windowSize_ms, const int stepSize_ms) {
std::vector<float> window;
const int start = center_ms - windowSize_ms/2;
const int end = center_ms + windowSize_ms/2;
for (uint64_t ms = start; ms < end; ms += stepSize_ms) {
const T val = interpol.get(ms);
window.push_back(val.x);
window.push_back(val.y);
window.push_back(val.z);
}
return window;
}
};
#endif // TRAINDATA_H

41
workspace/pca/KNN.h Normal file
View File

@@ -0,0 +1,41 @@
#ifndef KNN_H
#define KNN_H
#include <vector>
#include <algorithm>
template <typename T, int dim> class KNN {
private:
std::vector<T> elems;
public:
/** add a new element */
void add(const T& elem) {
elems.push_back(elem);
}
void build() {;}
/** get the nearest n elements */
template <typename T2> std::vector<T> get(const T2& src, const int num) {
auto lambda = [&] (const T& e1, const T& e2) {
return e1.getDistance(src) < e2.getDistance(src);
};
std::sort(elems.begin(), elems.end(), lambda);
std::vector<T> res;
for (int i = 0; i < num; ++i) { res.push_back(elems[i]); }
return res;
}
};
#endif // KNN_H

25
workspace/pca/Settings.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef SETTINGS_H
#define SETTINGS_H
#include <string>
class Settings {
public:
std::string path = "/mnt/firma/kunden/HandyGames/daten";
std::vector<std::string> classNames = {"forwardbend", "jumpingjack", "kneebend", "pushups", "situps"};
static int classToInt(const std::string className) {
if ("forwardbend" == className) {return 0;}
if ("jumpingjack" == className) {return 1;}
if ("kneebend" == className) {return 2;}
if ("pushups" == className) {return 3;}
if ("situps" == className) {return 4;}
throw "error";
}
};
#endif // SETTINGS_H

108
workspace/pca/TrainPCA.h Normal file
View File

@@ -0,0 +1,108 @@
#ifndef TRAINPCA_H
#define TRAINPCA_H
#include "Data.h"
#include "Settings.h"
#include <KLib/math/linearTransform/PCA.h>
class TrainPCA {
private:
public:
struct Matrices {
K::DynMatrix<float> A1;
K::DynMatrix<float> A2;
K::DynMatrix<float> A3;
};
static std::vector<ClassifiedPattern> getTestData() {
const int windowSize_ms = 1000;
const int regionStart_ms = 1500 + 25; // worst case: half-window-size offset
const float regionPercent = 0.85;
const int stepSize_ms = 50;
// get 10 data-files per class
std::vector<ClassifiedDataFile> files = Data::getDataFiles(30);
// get patterns for each class
std::vector<ClassifiedPattern> patterns;
for (ClassifiedDataFile cdf : files) {
std::cout << cdf.fileName << std::endl;
std::vector<std::vector<float>> samples = Data::getSamples(cdf.fileName, windowSize_ms, regionStart_ms, regionPercent, stepSize_ms);
for (const std::vector<float> vec : samples) {
patterns.push_back(ClassifiedPattern(cdf.className, vec));
}
}
return patterns;
}
/** train PCA features */
static std::vector<ClassifiedPattern> getTrainData() {
const int windowSize_ms = 1000;
const int regionStart_ms = 1500;
const float regionPercent = 0.4;
const int stepSize_ms = 50;
// get 5 data-files per class
std::vector<ClassifiedDataFile> files = Data::getDataFiles(30);
// get patterns for each class
std::vector<ClassifiedPattern> patterns;
for (ClassifiedDataFile cdf : files) {
std::cout << cdf.fileName << std::endl;
std::vector<std::vector<float>> samples = Data::getSamples(cdf.fileName, windowSize_ms, regionStart_ms, regionPercent, stepSize_ms);
std::cout << "\tgot" << samples.size() << " samples, each " << samples[0].size() << " values" << std::endl;
for (const std::vector<float> vec : samples) {
patterns.push_back(ClassifiedPattern(cdf.className, vec));
}
}
return patterns;
}
/** get the A1,A2,A3 matrices for the given training data */
static Matrices getMatrices(const std::vector<ClassifiedPattern>& data, const int numFeatures) {
K::LinearTransform<float>::PCA pca;
K::LinearTransform<float>::MaxInterClassDistance<std::string> inter;
K::LinearTransform<float>::MinIntraClassDistance<std::string> intra;
for (const ClassifiedPattern& pat : data) {
pca.add(pat.pattern);
inter.add(pat.className, pat.pattern);
intra.add(pat.className, pat.pattern);
}
Matrices m;
m.A1 = pca.getA(numFeatures);
m.A2 = inter.getA(numFeatures);
m.A3 = intra.getA(numFeatures);
std::cout << "A1: " << std::endl << m.A1 << std::endl;
std::cout << "A2: " << std::endl << m.A2 << std::endl;
std::cout << "A3: " << std::endl << m.A3 << std::endl;
return m;
}
};
#endif // TRAINPCA_H

73
workspace/pca/aKNN.h Normal file
View File

@@ -0,0 +1,73 @@
#ifndef AKNN_H
#define AKNN_H
#include "nanoflann.hpp"
using namespace nanoflann;
template <typename T, int dim> class aKNN {
struct DataSet {
std::vector<T> elems;
inline size_t kdtree_get_point_count() const {return elems.size();}
inline float kdtree_distance(const float* p1, const size_t idxP2, size_t) const {
float dist = 0;
for (int i = 0; i < dim; ++i) {
float delta = (p1[i] - kdtree_get_pt(idxP2, i));
dist += delta*delta;
}
return dist;
}
inline float kdtree_get_pt(const size_t idx, int pos) const {
return elems[idx].feature[pos];
}
template <class BBOX> bool kdtree_get_bbox(BBOX&) const {return false;}
} data;
typedef KDTreeSingleIndexAdaptor<L2_Simple_Adaptor<float, DataSet>, DataSet, dim> MyTree;
MyTree* tree = nullptr;
public:
/** add a new element */
void add(const T& elem) {
data.elems.push_back(elem);
}
/** build the KD-Tree */
void build() {
tree = new MyTree(dim, data, KDTreeSingleIndexAdaptorParams(10) );
tree->buildIndex();
}
/** get the nearest n elements */
template <typename T2> std::vector<T> get(const T2* query, const int numResults) {
float distances[numResults];
size_t indices[numResults];
KNNResultSet<float> res(numResults);
res.init(indices, distances);
tree->knnSearch(query, numResults, indices, distances);
std::vector<T> vec;
for (int i = 0; i < numResults; ++i) {
vec.push_back(data.elems[indices[i]]);
}
return vec;
}
};
#endif // AKNN_H

1397
workspace/pca/nanoflann.hpp Normal file

File diff suppressed because it is too large Load Diff