Created
December 4, 2011 23:08
-
-
Save janisozaur/1431587 to your computer and use it in GitHub Desktop.
coś function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Cos.h" | |
Cos::Cos(int _r, int _n) : | |
mR(_r), mN(_n) | |
{ | |
} | |
void Cos::init(int _r, int _n) | |
{ | |
mR = _r; | |
mN = _n; | |
} | |
QVector<float> Cos::calculateVec(const FeatureVector *vector, const QVector<float> ¶ms) const | |
{ | |
QVector<float> ret_vec(mN); | |
QVector<float> tmpvector = multiplication(vector); | |
int offset = 0; | |
for(int i = 0; i < mN; i++) | |
{ | |
for(int j = 0; j < tmpvector.size(); j++) | |
{ | |
ret_vec[i] += params.at(offset++) * tmpvector.at(j); | |
} | |
} | |
return ret_vec; | |
} | |
FeatureVector *Cos::calculate(const FeatureVector *vector, const QVector<float> ¶ms) const | |
{ | |
QVector<float> ret_vec = calculateVec(vector, params); | |
FeatureVector *result = new FeatureVector(ret_vec.size()); | |
for (int i = 0; i < ret_vec.size(); i++) { | |
(*result)[i] = ret_vec.at(i); | |
} | |
return result; | |
} | |
QVector<float> Cos::multiplication(const FeatureVector *features) const | |
{ | |
int N = features->length(); | |
int new_length = howManyElements(N, mR); | |
QVector<float> ret_vec(new_length); | |
for( int z = 1; z <= mR; z++) | |
{ | |
//cout<< "test numer "<<z<<endl; | |
int *positions = new int[z]; | |
memset(positions, 0, z * sizeof(int)); | |
advance(positions, 0, 0, z, features, ret_vec); | |
delete [] positions; | |
} | |
return ret_vec; | |
} | |
QVector<float> Cos::multiplication2(const QVector<float> &features) const | |
{ | |
QVector<float> ret_vec; | |
int N= features.size(); | |
int new_length = howManyElements(N,mR); | |
ret_vec.resize(new_length); | |
for( int z =1; z<=mR; z++){ | |
//cout<< "test numer "<<z<<endl; | |
int *positions = new int[z]; | |
memset(positions, 0, z*sizeof(int)); | |
advance(positions, 0, 0, z, features, ret_vec); | |
delete [] positions; | |
} | |
return ret_vec; | |
} | |
void Cos::advance(int *positions, const int &k, const int &j, const int &x, | |
const FeatureVector *features, QVector<float> &ret_vec) const | |
{ | |
if(j == x) | |
{ | |
float a=1; | |
// cout << p << ". "; | |
for(int i = 0; i < x; i++) | |
{ | |
// cout << ' ' << positions[i]; | |
a=a*(*features)[positions[i]].re(); | |
if(i+1 == x) { | |
ret_vec.append(a); | |
} | |
//cout<<"\t wynik mnożenia to: "<<a; | |
//cout << endl; | |
//p++; | |
return; | |
} | |
for(quint32 l = k; l < features->length(); l++) | |
{ | |
positions[j] = l; | |
advance(positions, l, j + 1, x, features, ret_vec); | |
} | |
} | |
} | |
void Cos::advance(int *positions, const int &k, const int &j, const int &x, | |
const QVector<float> &features, QVector<float> &ret_vec) const | |
{ | |
if(j == x) | |
{ | |
float a=1; | |
//cout << p << ". "; | |
for(int i = 0; i < x; i++){ | |
//cout << ' ' << positions[i]; | |
a=a*features.at(positions[i]); | |
if(i+1 == x) { | |
ret_vec.append(a); | |
} | |
//cout << endl; | |
//p++; | |
return; | |
} | |
for(int l = k; l < features.size(); l++) | |
{ | |
positions[j] = l; | |
advance(positions, l, j + 1, x, features, ret_vec); | |
} | |
} | |
} | |
int Cos::factorial(const int &n) const | |
{ | |
int z =1; | |
for(int i=1;i<=n;i++) | |
{ | |
z=z*i; | |
} | |
return z; | |
} | |
int Cos::howManyElements(const int &n, const int &k) const | |
{ | |
int z=0; | |
for(int i=1;i<=k;i++){ | |
int suma = (factorial(n+i-1)) / (factorial(i) * factorial(n-1)); | |
z=z+suma; | |
} | |
return z; | |
} | |
int Cos::n() const | |
{ | |
return mN; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef COS_H | |
#define COS_H | |
#include "FeatureVector.h" | |
#include <QVector> | |
class Cos | |
{ | |
private: | |
int mR; | |
int mN; | |
public: | |
Cos(int mR = 0, int mN = 0); | |
void init(int r, int n); | |
QVector<float> calculateVec(const FeatureVector *vector, const QVector<float> ¶ms) const; // funkcja saka | |
FeatureVector *calculate(const FeatureVector *vector, const QVector<float> ¶ms) const; // funkcja saka zwracająca fv | |
QVector<float> multiplication(const FeatureVector *features) const; // funkcja marcina | |
QVector<float> multiplication2(const QVector<float> &features) const;//funkcja do mnożenia ale na wektorze floatów | |
int factorial(const int &n) const;//silnia | |
int howManyElements(const int &n, const int &k) const;//funkcja obliczająca ile elementów ma mieć wektor wyjściowy kombinacji z powtórzeniami | |
void advance(int *positions, const int &k, const int &j, const int &x, const QVector<float> &features, QVector<float> &ret_vec) const; | |
void advance(int *positions, const int &k, const int &j, const int &x, const FeatureVector *features, QVector<float> &ret_vec) const; | |
int n() const; | |
}; | |
#endif // COS_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "CosOptimizer.h" | |
#include "CosQualityFunction.h" | |
#include "IFeatureExtractor.h" | |
#include "ExtractorFactory.h" | |
#include "Cos.h" | |
#include "Vertex.h" | |
#include <QPointer> | |
#include <cmath> | |
#include <QDebug> | |
#include <cfloat> | |
CosOptimizer::CosOptimizer(const QString &extractorName, | |
const QStringList ¶meters, | |
const SurveyResults *results, const Cos *cos, | |
uint iterations, float reflection, float expansion, | |
float contraction, float reduction) : | |
m_bestResult(1), m_iterations(iterations), m_reflection(reflection), m_expansion(expansion), | |
m_contraction(contraction), m_reduction(reduction) | |
{ | |
IFeatureExtractor * extractor = 0; | |
extractor = ExtractorFactory::get(extractorName, parameters); | |
if(extractor == 0) | |
qCritical()<< QString("Error while creating extractor"); | |
m_vectorSize = cos->n(); | |
m_qualityFunction = new CosQualityFunction(results, extractor); | |
m_startingPoints.resize(m_vectorSize + 1); | |
for(uint i = 0; i <= m_vectorSize; i++) | |
{ | |
m_startingPoints[i].resize(m_vectorSize); | |
for(uint j = 0; j < m_vectorSize; j++) | |
m_startingPoints[i][j] = (float)qrand() / (float)RAND_MAX * 2.0f - 1.0f; | |
} | |
} | |
CosOptimizer::~CosOptimizer() | |
{ | |
delete m_qualityFunction; | |
} | |
QVector<float> CosOptimizer::optimize(int passes, float &minError) | |
{ | |
minError = FLT_MAX; | |
QVector<float> result = m_bestResult; | |
for(int i = 0; i < passes; i++) | |
{ | |
for(uint j = 0; j <= m_vectorSize; j++) | |
for(uint k = 0; k < m_vectorSize; k++) | |
m_startingPoints[j][k] = (float)qrand() / (float)RAND_MAX * 2.0f - 1.0f; | |
optimize(); | |
float error = m_qualityFunction->evaluate(m_bestResult); | |
qDebug()<<error; | |
if(error < minError) | |
{ | |
minError = error; | |
result = m_bestResult; | |
} | |
} | |
return result; | |
} | |
void CosOptimizer::optimize() | |
{ | |
QVector<QPointer<Vertex> > simplex(m_vectorSize + 1); | |
for(uint i = 0; i <= m_vectorSize; i++) | |
{ | |
simplex[i] = new Vertex(m_vectorSize); | |
for(uint j = 0; j < m_vectorSize; j++) { | |
simplex[i]->p[j] = (float)qrand() / (float)RAND_MAX * 2.0f - 1.0f; | |
} | |
simplex[i]->p = m_startingPoints.at(i); | |
simplex[i]->f = m_qualityFunction->evaluate(simplex[i]->p); | |
} | |
Vertex center(m_vectorSize), reflected, expanded, contracted; | |
uint iteration = 0; | |
while(iteration < m_iterations) | |
{ | |
qSort(simplex); | |
// obliczenie srodka ciezkosci | |
center.zeros(); | |
for(uint i = 0; i < m_vectorSize; i++) | |
center = center + (*simplex[i]); | |
center = (1.0f / (float)m_vectorSize) * center; | |
// odbicie | |
reflected = center + m_reflection * (center - (*simplex[m_vectorSize])); | |
reflected.f = m_qualityFunction->evaluate(reflected.p); | |
if(reflected.f < simplex[m_vectorSize - 1]->f) | |
{ | |
if(reflected.f < simplex[0]->f) | |
{ | |
// ekspansja | |
expanded = center + m_expansion * (center - (*simplex[m_vectorSize])); | |
expanded.f = m_qualityFunction->evaluate(expanded.p); | |
if(expanded.f < reflected.f) | |
(*simplex[m_vectorSize]) = expanded; | |
else | |
(*simplex[m_vectorSize]) = reflected; | |
} | |
else | |
{ | |
(*simplex[m_vectorSize]) = reflected; | |
} | |
} | |
else | |
{ | |
contracted = (*simplex[m_vectorSize]) + m_contraction * (center - (*simplex[m_vectorSize])); | |
contracted.f = m_qualityFunction->evaluate(contracted.p); | |
if(contracted.f < simplex[m_vectorSize]->f) | |
(*simplex[m_vectorSize]) = contracted; | |
else | |
// redukcja | |
for(uint i = 1; i <= m_vectorSize; i++) | |
(*simplex[i]) = (*simplex[0]) + m_reduction * ((*simplex[i]) - (*simplex[0])); | |
} | |
float d = simplex[0]->distance(*simplex[m_vectorSize]); | |
for(uint i = 0; i < m_vectorSize; i++) | |
d += simplex[i]->distance(*simplex[i + 1]); | |
if(d < 0.01) | |
iteration = m_iterations; | |
else | |
iteration++; | |
} | |
center.zeros(); | |
for(uint i = 0; i <= m_vectorSize; i++) | |
center = center + (*simplex[i]); | |
center = (1.0f / (m_vectorSize + 1.0f)) * center; | |
m_bestResult = center.p; | |
for(uint i = 0; i <= m_vectorSize; i++) | |
delete simplex[i]; | |
} | |
void CosOptimizer::setStartingPoints(const QVector<QVector<float> > &startingPoints) | |
{ | |
m_startingPoints = startingPoints; | |
} | |
QVector<float> CosOptimizer::bestResult() const | |
{ | |
return m_bestResult; | |
} | |
CosQualityFunction* CosOptimizer::qualityFunction() const { | |
return m_qualityFunction; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef COSOPTIMIZER_H | |
#define COSOPTIMIZER_H | |
#include <QString> | |
#include <QVector> | |
#include <QStringList> | |
#include "SurveyResults.h" | |
class CosQualityFunction; | |
class Cos; | |
class CosOptimizer { | |
public: | |
CosOptimizer(const QString &extractorName, const QStringList ¶meters, | |
const SurveyResults* results, const Cos *cos, | |
uint iterations = 100, float reflection = 0.1, | |
float expansion = 0.2, float contraction = 0.05f, | |
float reduction = 0.05); | |
~CosOptimizer(); | |
void optimize(); | |
QVector<float> optimize(int passes, float &minError); | |
QVector<float> bestResult() const; | |
void setStartingPoints(const QVector<QVector<float> > &startingPoints); | |
CosQualityFunction* qualityFunction() const; | |
private: | |
CosQualityFunction * m_qualityFunction; | |
QVector<float> m_bestResult; | |
uint m_vectorSize; | |
uint m_iterations; | |
float m_reflection, m_expansion, m_contraction, m_reduction; | |
QVector<QVector<float> > m_startingPoints; | |
}; | |
#endif // COSOPTIMIZER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "CosQualityFunction.h" | |
#include "SurveyResults.h" | |
#include "Cos.h" | |
#include <cmath> | |
#include <cfloat> | |
#include <QDebug> | |
#include <QPointF> | |
#include <QPair> | |
#include <QFile> | |
#include <QTextStream> | |
CosQualityFunction::CosQualityFunction(const SurveyResults *_results, | |
IFeatureExtractor *_extractor, | |
const Cos *cos) : | |
results(_results), | |
extractor(_extractor), | |
mCos(cos) | |
{ | |
} | |
float CosQualityFunction::distance(const FeatureVector &first, const FeatureVector &second) const | |
{ | |
if(first.length() != second.length()) | |
return FLT_MAX; | |
double result = 0.0f; | |
for(quint32 i = 0; i < first.length(); i++) | |
{ | |
double d = (first[i].re() - second[i].re()); | |
d *= d; | |
result += d; | |
} | |
return sqrt(result); | |
} | |
float CosQualityFunction::evaluate(const QVector<float> ¶ms) { | |
QList<QPair<QString, QString> > shapePairs = results->getShapePairs(); | |
distances.clear(); | |
QPair<QString, QString> p; | |
foreach(p, shapePairs) { | |
Shape* shapeA = results->getShape(p.first); | |
Shape* shapeB = results->getShape(p.second); | |
float surveySimilarity = results->getShapePairSimilarity(p); | |
FeatureVector* featureVectorA = extractor->extract(shapeA); | |
FeatureVector* featureVectorB = extractor->extract(shapeB); | |
FeatureVector *fvA = mCos->calculate(featureVectorA, params); | |
FeatureVector *fvB = mCos->calculate(featureVectorB, params); | |
float dist = distance(*fvA, *fvB); | |
delete featureVectorA; | |
delete featureVectorB; | |
delete fvA; | |
delete fvB; | |
QPointF res(surveySimilarity, dist); | |
distances.push_back(res); | |
} | |
double a,b; | |
return leastSquares(a,b); | |
} | |
void CosQualityFunction::dumpResults(QString filename, const QVector<float> ¶ms) { | |
QFile file(filename); | |
file.open(QFile::WriteOnly); | |
QTextStream stream(&file); | |
QList<QPair<QString, QString> > shapePairs = results->getShapePairs(); | |
double a,b; | |
leastSquares(a,b); | |
QPair<QString, QString> p; | |
foreach(p, shapePairs) { | |
Shape* shapeA = results->getShape(p.first); | |
Shape* shapeB = results->getShape(p.second); | |
float surveySimilarity = results->getShapePairSimilarity(p); | |
FeatureVector* featureVectorA = extractor->extract(shapeA); | |
FeatureVector* featureVectorB = extractor->extract(shapeB); | |
FeatureVector *fvA = mCos->calculate(featureVectorA, params); | |
FeatureVector *fvB = mCos->calculate(featureVectorB, params); | |
float dist = distance(*fvA, *fvB); | |
delete featureVectorA; | |
delete featureVectorB; | |
delete fvA; | |
delete fvB; | |
QPointF res(surveySimilarity, dist); | |
stream<<res.x()<<" "<<res.y()<<" "<<res.x()*a+b<<endl; | |
} | |
file.close(); | |
} | |
float CosQualityFunction::leastSquares(double& a, double& b) { | |
int n = distances.count(); | |
double S, Sx, Sy, Sxx, Sxy, Syy; | |
S=Sx=Sy=Sxx=Sxy=Syy=0.0; | |
S = n; | |
for(int i=0;i<n;i++) { | |
Sx += distances.at(i).x(); | |
Sy += distances.at(i).y(); | |
Sxx += distances.at(i).x()*distances.at(i).x(); | |
Sxy += distances.at(i).x()*distances.at(i).y(); | |
Syy += distances.at(i).y()*distances.at(i).y(); | |
} | |
double delta = S*Sxx - Sx*Sx; | |
a = (S*Sxy - Sx*Sy)/delta; | |
b = (Sxx*Sy - Sx*Sxy)/delta; | |
double error = 0; | |
for(int i=0;i<distances.count();i++) { | |
error += (distances.at(i).y() - a*distances.at(i).x()-b)/(-a*distances.at(i).x()-b)*(distances.at(i).y() - a*distances.at(i).x()-b)/(-a*distances.at(i).x()-b); | |
} | |
return error; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef COSQUALITYFUNCTION_H | |
#define COSQUALITYFUNCTION_H | |
#include <QVector> | |
class SurveyResults; | |
class QPointF; | |
class Cos; | |
#include "IFeatureExtractor.h" | |
#include "FeatureVector.h" | |
class CosQualityFunction | |
{ | |
public: | |
CosQualityFunction(const SurveyResults* _results, | |
IFeatureExtractor* extractor, | |
const Cos *cos = NULL); | |
/*Wyznacza wartość funkcji dla zadanych parametrów*/ | |
float evaluate(const QVector<float> ¶ms); | |
void dumpResults(QString filename, const QVector<float> ¶ms); | |
private: | |
/*oblicza odległość od dwóch wektorów cech*/ | |
float distance(const FeatureVector& first, const FeatureVector& second) const; | |
/*Liczy błąd metodą najmniejszych kwadratów*/ | |
float leastSquares(double& a, double& b); | |
const SurveyResults *results; | |
IFeatureExtractor *extractor; | |
/*Przechowuje tymczasowe wyniki gdzie pierwszy element pary to podobieństwo z ankiety, | |
a drugi to odległość wektrów cech*/ | |
QVector<QPointF> distances; | |
/* funkcja "coś" z task6 */ | |
const Cos *mCos; | |
}; | |
#endif // COSQUALITYFUNCTION_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Vertex.h" | |
#include <QPointer> | |
bool operator< (const QPointer<Vertex> &first, const QPointer<Vertex> &second) | |
{ | |
return (*first) < (*second); | |
} | |
Vertex operator* (const float a, const Vertex &v) | |
{ | |
Vertex result(v.p.size()); | |
for(int i = 0; i < v.p.size(); i++) | |
result.p[i] = a * v.p[i]; | |
return result; | |
} | |
Vertex operator+ (const Vertex &v1, const Vertex &v2) | |
{ | |
Vertex result(v1.p.size()); | |
for(int i = 0; i < v1.p.size(); i++) | |
result.p[i] = v1.p[i] + v2.p[i]; | |
return result; | |
} | |
Vertex operator- (const Vertex &v1, const Vertex &v2) | |
{ | |
Vertex result(v1.p.size()); | |
for(int i = 0; i < v1.p.size(); i++) | |
result.p[i] = v1.p[i] - v2.p[i]; | |
return result; | |
} | |
Vertex operator- (const Vertex &v) | |
{ | |
Vertex result(v.p.size()); | |
for(int i = 0; i < v.p.size(); i++) | |
result = -v.p[i]; | |
return result; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef VERTEX_H | |
#define VERTEX_H | |
#include <QVector> | |
#include <QObject> | |
#include <cmath> | |
class Vertex : public QObject | |
{ | |
Q_OBJECT | |
public: | |
QVector<float> p; | |
float f; | |
friend Vertex operator* (const float a, const Vertex &v); | |
friend Vertex operator+ (const Vertex &v1, const Vertex &v2); | |
friend Vertex operator- (const Vertex &v1, const Vertex &v2); | |
friend Vertex operator- (const Vertex &v); | |
Vertex(uint size = 1) : | |
p(size), f(0.0f) | |
{ | |
zeros(); | |
} | |
Vertex(const Vertex &other) : | |
QObject(other.parent()), p(other.p.size()), f(other.f) | |
{ | |
for(int i = 0; i < other.p.size(); i++) | |
p[i] = other.p[i]; | |
} | |
Vertex &operator= (const Vertex &other) | |
{ | |
f = other.f; | |
p.resize(other.p.size()); | |
for(int i = 0; i < p.size(); i++) | |
p[i] = other.p[i]; | |
return *this; | |
} | |
float distance(const Vertex &other) | |
{ | |
float d = 0.0f; | |
for(int i = 0; i < p.size(); i++) | |
{ | |
float dd = p[i] - other.p[i]; | |
d += dd*dd; | |
} | |
return sqrt(d); | |
} | |
bool operator< (const Vertex &other) | |
{ | |
return f < other.f; | |
} | |
void zeros() | |
{ | |
for(int i = 0; i < p.size(); i++) | |
p[i] = 0.0f; | |
} | |
}; | |
#endif // VERTEX_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment