多层次熵算法C++实现

这是我在项目《基于心电信号(ECG)的冠心病辅助诊断软件设计——基于多层次熵与SVM》中完成的对多层次熵算法的C++实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

/* void entropy_tree_analysis(double *a, */
/* int num , */
/* int template_length, */
/* int depth , */
/* char* save_file_name, */
/* float r_percentage=0.1); */
/* ouput: 对序列做树分解,然后再求各层熵,结果保存在save_file_name */
/* input: double为时间序列的数据类型,a指向时间序列的起始地址,num为序列长度,*/
/* template_length为模板长度,depth为树分解深度,r_percentage为搜索半径的松弛系数.*/

/* 说明:为节省空间此函数会修改时间序列a里面的值,参数r_percentage用来算搜索半径,默认为10%,搜索半径为序列方差*r_percentage; */

/* This function calcuate the stand variance of the data. */
double stdvar(double * a, int num)
{

double sum = 0, sum_2 = 0, var;

for(int i=0; i<num; i++)
{
sum += a[i];
sum_2 += a[i]*a[i];
}
var = sum_2/num - (sum/num)*(sum/num);
if( var < 0 )
throw printf( "variance is less than 0");

return sqrt(var);
}

void tree_analysis_help(double *a, int num, double *d)
{

int new_num = num/2;

for ( int i = 0; i<new_num; i++ )
{
d[i] = a[2*i] + a[2*i + 1] ;
d[new_num + i] = a[2*i] - a[2*i + 1] ;
}
}

void entropy_tree_analysis(double *a, int num, int template_length, int depth, char* save_file_name, float r_percentage = 0.1)
{

int num_real = num - num%( 1<<depth );
double *_b = new double[num];
double *b = _b;
int start, length = num_real*2, entp_num = ( 1<<depth ) -1;
double *entp;
double *p_entp;
p_entp = new double[entp_num];

for ( int i = 0, j = 0; i<depth; i++)
{
if ( i == 0 )
{
entp = sampen(a, template_length, r_percentage * stdvar(a, num), num);
p_entp[j] = entp[4];
j++;
if ( entp != NULL ) {delete[] entp; entp = NULL;}
}
else
{
for ( start = 0, length/=2; start < num_real; start += length )
{
tree_analysis_help( a + start, length, b + start );
}

for ( start = 0; start < num_real; start += length/2 )
{
entp = sampen( b + start, template_length, r_percentage * stdvar( b + start, length/2 ), length/2 );
p_entp[j] = entp[4];
j++;
if ( entp != NULL ) {delete[] entp; entp = NULL;}
}
double *temp = a;
a = b;
b = temp;
}
}

FILE * outf;
outf = fopen(save_file_name, "wb");
fwrite( &entp_num, sizeof(int), 1, outf);
fwrite( p_entp, sizeof(double), entp_num, outf );
fclose( outf );

delete[] p_entp;
delete[] _b;
}