iPDC-suite/iPDC/src/Dynamic_time_warping.c

303 lines
10 KiB
C

#include "parser.h"
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <gtk/gtk.h>
#include <stdlib.h>
struct DTWfreqlist
{
int idcode;
long double *freq1;
long double *freq2;
int count_track1;
int count_track2;
int flag;
int result;
struct DTWfreqlist *next;
};
struct DTWvollist
{
int idcode;
long double *vol1;
long double *vol2;
int count_track1;
int count_track2;
int flag;
int result;
struct DTWvollist *next;
};
struct DTWfreqlist *dtwhead = NULL;
struct DTWvollist *dtwheadvol = NULL;
int DTWfreqDistance(struct data_frame *df)
{
if (dtwhead == NULL)
{
dtwhead = (struct DTWfreqlist *)malloc(sizeof(struct DTWfreqlist));
dtwhead->count_track1 = 0;
dtwhead->count_track2 = 0;
dtwhead->flag = 0;
dtwhead->idcode = to_intconvertor(df->idcode);
dtwhead->next = NULL;
dtwhead->result=1;
return 1;
}
else
{
struct DTWfreqlist *temp = dtwhead;
struct DTWfreqlist *previous;
while (temp != NULL)
{
if (to_intconvertor(df->idcode) == temp->idcode)
{
float CURR_FREQ;
if (df->dpmu[0]->fmt->freq == '0')
{
CURR_FREQ = 50 + to_intconvertor(df->dpmu[0]->freq) * 1e-3;
}
else
{
CURR_FREQ = decode_ieee_single(df->dpmu[0]->freq);
}
// printf("count1: %d\ncount2: %d\n",count_track1,count_track2);
// printf("curr_freq: %f\n",CURR_FREQ);
if (temp->count_track1 == 0)
{
if (temp->flag == 0)
{
temp->flag = 1;
temp->freq1 = (long double *)malloc(500 * sizeof(long double));
}
temp->freq1[temp->count_track2] = CURR_FREQ;
temp->count_track2++;
if (temp->count_track2 == 500)
{
temp->count_track2 = 0;
temp->flag = 0;
temp->count_track1++;
}
}
else if (temp->count_track1 == 1)
{
if (temp->flag == 0)
{
temp->flag = 1;
temp->freq2 = (long double *)malloc(500 * sizeof(long double));
}
temp->freq2[temp->count_track2] = CURR_FREQ;
temp->count_track2++;
if (temp->count_track2 == 500)
{
temp->count_track2 = 0;
temp->flag = 0;
temp->count_track1++;
}
}
else
{
float **DTW = (float **)malloc(501 * sizeof(float *));
for (int i = 0; i < 501; i++)
DTW[i] = (float *)malloc(501 * sizeof(float));
for (int i = 0; i < 501; i++)
{
for (int j = 0; j < 501; j++)
DTW[i][j] = 1000;
}
DTW[0][0] = 0;
for (int i = 1; i < 501; i++)
{
for (int j = 1; j < 501; j++)
{
float cost = fabs(temp->freq1[i - 1] - temp->freq2[j - 1]);
// printf("cost: %f",cost);
DTW[i][j] = cost + fmin(DTW[i][j - 1], fmin(DTW[i - 1][j], DTW[i - 1][j - 1]));
// printf(" DTW[%d][%d]: %f\n",i,j,DTW[i][j]);
}
}
printf("DTWdistance: %f\n", DTW[500][500]);
if (DTW[500][500] >= 35)
{
free(temp->freq2);
temp->result = 0;
}
else
{
long double *f = temp->freq1;
temp->freq1 = temp->freq2;
free(f);
temp->result = 1;
}
free(DTW);
temp->count_track1 = 1;
}
break;
}
previous = temp;
temp = temp->next;
}
if (temp == NULL)
{
struct DTWfreqlist *bring = (struct DTWfreqlist *)malloc(sizeof(struct DTWfreqlist));
bring->count_track1 = 0;
bring->count_track2 = 0;
bring->flag = 0;
bring->idcode = to_intconvertor(df->idcode);
bring->next = NULL;
bring->result=1;
previous->next = bring;
return 1;
}
return temp->result;
}
}
int DTWvolDistance(struct data_frame *df)
{
if (dtwheadvol == NULL)
{
dtwheadvol = (struct DTWvollist *)malloc(sizeof(struct DTWvollist));
dtwheadvol->count_track1 = 0;
dtwheadvol->count_track2 = 0;
dtwheadvol->flag = 0;
dtwheadvol->idcode = to_intconvertor(df->idcode);
dtwheadvol->next = NULL;
dtwheadvol->result=1;
return 1;
}
else
{
struct DTWvollist *temp = dtwheadvol;
struct DTWvollist *previous;
while (temp != NULL)
{
if (to_intconvertor(df->idcode) == temp->idcode)
{
float CURR_vol;
if (df->dpmu[0]->fmt->phasor == '0')
{
unsigned char s1[2];
unsigned char s2[2];
strncpy(s1,df->dpmu[0]->phasors[0],2);
strncpy(s2,df->dpmu[0]->phasors[0]+2,2);
long double v1 = to_intconvertor(s1);
long double v2 = to_intconvertor(s2);
CURR_vol = sqrt((v1*v1)+(v2*v2));
}
else
{
unsigned char s1[4];
unsigned char s2[4];
strncpy(s1,df->dpmu[0]->phasors[0],4);
strncpy(s2,df->dpmu[0]->phasors[0]+2,4);
long double v1 = decode_ieee_single(s1);
long double v2 =decode_ieee_single(s2);
CURR_vol = sqrt((v1*v1)+(v2*v2));
}
// printf("count1: %d\ncount2: %d\n",count_track1,count_track2);
// printf("curr_vol: %f\n",CURR_vol);
if (temp->count_track1 == 0)
{
if (temp->flag == 0)
{
temp->flag = 1;
temp->vol1 = (long double *)malloc(500 * sizeof(long double));
}
temp->vol1[temp->count_track2] = CURR_vol;
temp->count_track2++;
if (temp->count_track2 == 500)
{
temp->count_track2 = 0;
temp->flag = 0;
temp->count_track1++;
}
}
else if (temp->count_track1 == 1)
{
if (temp->flag == 0)
{
temp->flag = 1;
temp->vol2 = (long double *)malloc(500 * sizeof(long double));
}
temp->vol2[temp->count_track2] = CURR_vol;
temp->count_track2++;
if (temp->count_track2 == 500)
{
temp->count_track2 = 0;
temp->flag = 0;
temp->count_track1++;
}
}
else
{
float **DTW = (float **)malloc(501 * sizeof(float *));
for (int i = 0; i < 501; i++)
DTW[i] = (float *)malloc(501 * sizeof(float));
for (int i = 0; i < 501; i++)
{
for (int j = 0; j < 501; j++)
DTW[i][j] = 1000;
}
DTW[0][0] = 0;
for (int i = 1; i < 501; i++)
{
for (int j = 1; j < 501; j++)
{
float cost = fabs(temp->vol1[i - 1] - temp->vol2[j - 1]);
// printf("cost: %f",cost);
DTW[i][j] = cost + fmin(DTW[i][j - 1], fmin(DTW[i - 1][j], DTW[i - 1][j - 1]));
// printf(" DTW[%d][%d]: %f\n",i,j,DTW[i][j]);
}
}
printf("DTWdistance: %f\n", DTW[500][500]);
if (DTW[500][500] >= 35)
{
free(temp->vol2);
temp->result = 0;
}
else
{
long double *f = temp->vol1;
temp->vol1 = temp->vol2;
free(f);
temp->result = 1;
}
free(DTW);
temp->count_track1 = 1;
}
break;
}
previous = temp;
temp = temp->next;
}
if (temp == NULL)
{
struct DTWvollist *bring = (struct DTWvollist *)malloc(sizeof(struct DTWvollist));
bring->count_track1 = 0;
bring->count_track2 = 0;
bring->flag = 0;
bring->idcode = to_intconvertor(df->idcode);
bring->next = NULL;
bring->result=1;
previous->next = bring;
return 1;
}
return temp->result;
}
}
int DTWfreqvolDistance(struct data_frame *df)
{
return DTWfreqDistance(df) && DTWfreqvolDistance(df);
}