/*--------------------------------------------------------------------------*\ FILE........: VQTRAIN.C AUTHOR......: David Rowe DATE CREATED: 23/2/95 This program trains vector quantisers using K dimensional Lloyd-Max method. \*--------------------------------------------------------------------------*/ /* Copyright (C) 2009 David Rowe All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2, as published by the Free Software Foundation. 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 Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /*-----------------------------------------------------------------------*\ INCLUDES \*-----------------------------------------------------------------------*/ #include #include #include #include #include /*-----------------------------------------------------------------------*\ DEFINES \*-----------------------------------------------------------------------*/ #define DELTAQ 0.01 /* quiting distortion */ #define MAX_STR 80 /* maximum string length */ /*-----------------------------------------------------------------------*\ FUNCTION PROTOTYPES \*-----------------------------------------------------------------------*/ void zero(float v[], int k); void acc(float v1[], float v2[], int k); void norm(float v[], int k, long n); long quantise(float cb[], float vec[], int k, int m, float *se); /*-----------------------------------------------------------------------*\ MAIN \*-----------------------------------------------------------------------*/ int main(int argc, char *argv[]) { long k,m; /* dimension and codebook size */ float *vec; /* current vector */ float *cb; /* vector codebook */ float *cent; /* centroids for each codebook entry */ long *n; /* number of vectors in this interval */ long J; /* number of vectors in training set */ long i,j; long ind; /* index of current vector */ float se; /* squared error for this iteration */ float Dn,Dn_1; /* current and previous iterations distortion */ float delta; /* improvement in distortion */ FILE *ftrain; /* file containing training set */ FILE *fvq; /* file containing vector quantiser */ /* Interpret command line arguments */ if (argc != 5) { printf("usage: vqtrain TrainFile K M VQFile\n"); exit(0); } /* Open training file */ ftrain = fopen(argv[1],"rb"); if (ftrain == NULL) { printf("Error opening training database file: %s\n",argv[1]); exit(1); } /* determine k and m, and allocate arrays */ k = atol(argv[2]); m = atol(argv[3]); printf("dimension K=%ld number of entries M=%ld\n", k,m); vec = (float*)malloc(sizeof(float)*k); cb = (float*)malloc(sizeof(float)*k*m); cent = (float*)malloc(sizeof(float)*k*m); n = (long*)malloc(sizeof(long)*m); if (cb == NULL || cb == NULL || cent == NULL || vec == NULL) { printf("Error in malloc.\n"); exit(1); } /* determine size of training set */ J = 0; while(fread(vec, sizeof(float), k, ftrain) == k) J++; printf("J=%ld entries in training set\n", J); /* set up initial codebook state from samples of training set */ rewind(ftrain); fread(cb, sizeof(float), k*m, ftrain); /* main loop */ Dn = 1E32; j = 1; do { Dn_1 = Dn; /* zero centroids */ for(i=0; i DELTAQ) for(i=0; i DELTAQ); /* save codebook to disk */ fvq = fopen(argv[4],"wt"); if (fvq == NULL) { printf("Error opening VQ file: %s\n",argv[4]); exit(1); } for(j=0; j