vqtrain.cpp
Go to the documentation of this file.
#include <itpp/srccode/vqtrain.h>
#include <itpp/base/matfunc.h>
#include <itpp/base/random.h>
#include <itpp/base/sort.h>
#include <itpp/base/specmat.h>
#include <itpp/base/math/min_max.h>
#include <itpp/stat/misc_stat.h>
#include <iostream>
namespace itpp
{
// the cols contains codevectors
double kmeansiter(Array<vec> &DB, mat &codebook)
{
int DIM = DB(0).length(), SIZE = codebook.cols(), T = DB.length();
vec x, xnum(SIZE);
mat xsum(DIM, SIZE);
int MinIndex, i, j, k;
double MinS, S, D, *xp, *cp;
xsum.clear();
xnum.clear();
D = 1E20;
D = 0;
for (k = 0;k < T;k++) {
x = DB(k);
xp = x._data();
MinS = 1E20;
MinIndex = 0;
for (i = 0;i < SIZE;i++) {
cp = &codebook(0, i);
S = sqr(xp[0] - cp[0]);
for (j = 1;j < DIM;j++) {
S += sqr(xp[j] - cp[j]);
if (S >= MinS) goto sune;
}
MinS = S;
MinIndex = i;
sune:
void();
}
D += MinS;
cp = &xsum(0, MinIndex);
for (j = 0;j < DIM;j++) {
cp[j] += xp[j];
}
xnum(MinIndex)++;
}
for (i = 0;i < SIZE;i++) {
for (j = 0;j < DIM;j++) {
codebook(j, i) = xsum(j, i) / xnum(i);
}
}
return D;
}
mat kmeans(Array<vec> &DB, int SIZE, int NOITER, bool VERBOSE)
{
int DIM = DB(0).length(), T = DB.length();
mat codebook(DIM, SIZE);
int n, i, j;
double D, Dold;
ivec ind(SIZE);
for (i = 0;i < SIZE;i++) {
ind(i) = randi(0, T - 1);
j = 0;
while (j < i) {
if (ind(j) == ind(i)) {
ind(i) = randi(0, T - 1);
j = 0;
}
j++;
}
codebook.set_col(i, DB(ind(i)));
}
if (VERBOSE) std::cout << "Training VQ..." << std::endl ;
D = 1E20;
for (n = 0;n < NOITER;n++) {
Dold = D;
D = kmeansiter(DB, codebook);
if (VERBOSE) std::cout << n << ": " << D / T << " ";
if (std::abs((D - Dold) / D) < 1e-4) break;
}
return codebook;
}
mat lbg(Array<vec> &DB, int SIZE, int NOITER, bool VERBOSE)
{
int S = 1, DIM = DB(0).length(), T = DB.length(), i, n;
mat cb;
vec delta = 0.001 * randn(DIM), x;
double D, Dold;
x = zeros(DIM);
for (i = 0;i < T;i++) {
x += DB(i);
}
x /= T;
cb.set_size(DIM, 1);
cb.set_col(0, x);
while (cb.cols() < SIZE) {
S = cb.cols();
if (2*S <= SIZE) cb.set_size(DIM, 2*S, true);
else cb.set_size(DIM, 2*S, true);
for (i = S;i < cb.cols();i++) {
cb.set_col(i, cb.get_col(i - S) + delta);
}
D = 1E20;
for (n = 0;n < NOITER;n++) {
Dold = D;
D = kmeansiter(DB, cb);
if (VERBOSE) std::cout << n << ": " << D / T << " ";
if (std::abs((D - Dold) / D) < 1e-4) break;
}
}
return cb;
}
mat vqtrain(Array<vec> &DB, int SIZE, int NOITER, double STARTSTEP, bool VERBOSE)
{
int DIM = DB(0).length();
vec x;
vec codebook(DIM*SIZE);
int n, MinIndex, i, j;
double MinS, S, D, step, *xp, *cp;
for (i = 0;i < SIZE;i++) {
codebook.replace_mid(i*DIM, DB(randi(0, DB.length() - 1)));
}
if (VERBOSE) std::cout << "Training VQ..." << std::endl ;
res:
D = 0;
for (n = 0;n < NOITER;n++) {
step = STARTSTEP * (1.0 - double(n) / NOITER);
if (step < 0) step = 0;
x = DB(randi(0, DB.length() - 1)); // seems unnecessary! Check it up.
xp = x._data();
MinS = 1E20;
MinIndex = 0;
for (i = 0;i < SIZE;i++) {
cp = &codebook(i * DIM);
S = sqr(xp[0] - cp[0]);
for (j = 1;j < DIM;j++) {
S += sqr(xp[j] - cp[j]);
if (S >= MinS) goto sune;
}
MinS = S;
MinIndex = i;
sune:
i = i;
}
D += MinS;
cp = &codebook(MinIndex * DIM);
for (j = 0;j < DIM;j++) {
cp[j] += step * (xp[j] - cp[j]);
}
if ((n % 20000 == 0) && (n > 1)) {
if (VERBOSE) std::cout << n << ": " << D / 20000 << " ";
D = 0;
}
}
// checking training result
vec dist(SIZE), num(SIZE);
dist.clear();
num.clear();
for (n = 0;n < DB.length();n++) {
x = DB(n);
xp = x._data();
MinS = 1E20;
MinIndex = 0;
for (i = 0;i < SIZE;i++) {
cp = &codebook(i * DIM);
S = sqr(xp[0] - cp[0]);
for (j = 1;j < DIM;j++) {
S += sqr(xp[j] - cp[j]);
if (S >= MinS) goto sune2;
}
MinS = S;
MinIndex = i;
sune2:
i = i;
}
dist(MinIndex) += MinS;
num(MinIndex) += 1;
}
dist = 10 * log10(dist * dist.length() / sum(dist));
if (VERBOSE) std::cout << std::endl << "Distortion contribution: " << dist << std::endl ;
if (VERBOSE) std::cout << "Num spread: " << num / DB.length()*100 << " %" << std::endl << std::endl ;
if (min(dist) < -30) {
std::cout << "Points without entries! Retraining" << std::endl ;
j = min_index(dist);
i = max_index(num);
codebook.replace_mid(j*DIM, codebook.mid(i*DIM, DIM));
goto res;
}
mat cb(DIM, SIZE);
for (i = 0;i < SIZE;i++) {
cb.set_col(i, codebook.mid(i*DIM, DIM));
}
return cb;
}
vec sqtrain(const vec &inDB, int SIZE)
{
vec DB(inDB);
vec Levels, Levels_old;
ivec indexlist(SIZE + 1);
int il, im, ih, i;
int SIZEDB = inDB.length();
double x;
sort(DB);
Levels = DB(round_i(linspace(0.01 * SIZEDB, 0.99 * SIZEDB, SIZE)));
Levels_old = zeros(SIZE);
while (energy(Levels - Levels_old) > 0.0001) {
Levels_old = Levels;
for (i = 0;i < SIZE - 1;i++) {
x = (Levels(i) + Levels(i + 1)) / 2;
il = 0;
ih = SIZEDB - 1;
while (il < ih - 1) {
im = (il + ih) / 2;
if (x < DB(im)) ih = im;
else il = im;
}
indexlist(i + 1) = il;
}
indexlist(0) = -1;
indexlist(SIZE) = SIZEDB - 1;
for (i = 0;i < SIZE;i++) Levels(i) = mean(DB(indexlist(i) + 1, indexlist(i + 1)));
}
return Levels;
}
ivec bitalloc(const vec &variances, int nobits)
{
ivec bitvec(variances.length());
bitvec.clear();
int i, bits = nobits;
vec var = variances;
while (bits > 0) {
i = max_index(var);
var(i) /= 4;
bitvec(i)++;
bits--;
}
return bitvec;
}
} // namespace itpp
itpp::kmeansiter
ITPP_EXPORT double kmeansiter(Array< vec > &DB, mat &codebook)
ADD DOCUMENTATION HERE.
itpp
itpp namespace
Definition: itmex.h:36
itpp::energy
double energy(const Vec< T > &v)
Calculate the energy: squared 2-norm. energy(v)=sum(abs(v).^2)
Definition: misc_stat.h:253
itpp::randi
int randi(int low, int high)
Generates a random integer in the interval [low,high].
Definition: random.h:815
random.h
Definition of classes for random number generators.
itpp::min
T min(const Vec< T > &in)
Minimum value of vector.
Definition: min_max.h:125
misc_stat.h
Miscellaneous statistics functions and classes - header file.
itpp::randn
double randn(void)
Generates a random Gaussian (0,1) variable.
Definition: random.h:831
matfunc.h
Various functions on vectors and matrices - header file.
itpp::log10
vec log10(const vec &x)
log-10 of the elements
Definition: log_exp.h:271
itpp::max_index
int max_index(const Vec< T > &in)
Return the postion of the maximum element in the vector.
Definition: min_max.h:208
itpp::linspace
vec linspace(double from, double to, int points)
linspace (works in the same way as the MATLAB version)
Definition: specmat.cpp:106
specmat.h
Definitions of special vectors and matrices.
itpp::kmeans
ITPP_EXPORT mat kmeans(Array< vec > &DB, int SIZE, int NOITER=9999, bool VERBOSE=true)
ADD DOCUMENTATION HERE.
itpp::sqr
vec sqr(const cvec &data)
Absolute square of elements.
Definition: elem_math.cpp:36
itpp::mean
double mean(const vec &v)
The mean value.
Definition: misc_stat.cpp:36
itpp::min_index
int min_index(const Vec< T > &in)
Return the postion of the minimum element in the vector.
Definition: min_max.h:234
itpp::zeros
ITPP_EXPORT vec zeros(int size)
A Double vector of zeros.
vqtrain.h
Definitions of a vector quantizer training functions.
itpp::abs
bin abs(const bin &inbin)
absolute value of bin
Definition: binary.h:174
itpp::sqtrain
ITPP_EXPORT vec sqtrain(const vec &inDB, int SIZE)
ADD DOCUMENTATION HERE.
sort.h
Sorting functions.
itpp::lbg
ITPP_EXPORT mat lbg(Array< vec > &DB, int SIZE, int NOITER=9999, bool VERBOSE=true)
ADD DOCUMENTATION HERE.
itpp::bitalloc
ITPP_EXPORT ivec bitalloc(const vec &variances, int nobits)
ADD DOCUMENTATION HERE.
itpp::round_i
ITPP_EXPORT int round_i(double x)
Round to nearest integer.
min_max.h
Minimum and maximum functions on vectors and matrices.
itpp::vqtrain
ITPP_EXPORT mat vqtrain(Array< vec > &DB, int SIZE, int NOITER, double STARTSTEP=0.2, bool VERBOSE=true)
Function for vector quantization training.
itpp::sum
T sum(const Vec< T > &v)
Sum of all elements in the vector.
Definition: matfunc.h:59

Generated on Mon Mar 23 2020 06:18:03 for IT++ by Doxygen 1.8.17