mirror of
https://github.com/simon987/wavelib.git
synced 2025-04-10 14:06:46 +00:00
325 lines
6.3 KiB
C
325 lines
6.3 KiB
C
#include "../header/wauxlib.h"
|
|
#include "waux.h"
|
|
|
|
int compare_double(const void* a, const void* b)
|
|
{
|
|
double arg1 = *(const double*)a;
|
|
double arg2 = *(const double*)b;
|
|
|
|
if (arg1 < arg2) return -1;
|
|
if (arg1 > arg2) return 1;
|
|
return 0;
|
|
|
|
}
|
|
|
|
double mean(const double* vec, int N) {
|
|
int i;
|
|
double m;
|
|
m = 0.0;
|
|
|
|
for (i = 0; i < N; ++i) {
|
|
m+= vec[i];
|
|
}
|
|
m = m / N;
|
|
return m;
|
|
}
|
|
|
|
double var(const double* vec, int N) {
|
|
double v,temp,m;
|
|
int i;
|
|
v = 0.0;
|
|
m = mean(vec,N);
|
|
|
|
for (i = 0; i < N; ++i) {
|
|
temp = vec[i] - m;
|
|
v+= temp*temp;
|
|
}
|
|
|
|
v = v / N;
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
double median(double *x, int N) {
|
|
double sigma;
|
|
|
|
qsort(x, N, sizeof(double), compare_double);
|
|
|
|
if ((N % 2) == 0) {
|
|
sigma = (x[N/2 - 1] + x[N/2] ) / 2.0;
|
|
} else {
|
|
sigma = x[N/2];
|
|
}
|
|
|
|
return sigma;
|
|
}
|
|
|
|
double mad(double *x, int N) {
|
|
double sigma;
|
|
int i;
|
|
|
|
sigma = median(x,N);
|
|
|
|
for(i = 0; i < N;++i) {
|
|
x[i] = (x[i] - sigma) > 0 ? (x[i] - sigma) : -(x[i] - sigma);
|
|
}
|
|
|
|
sigma = median(x,N);
|
|
|
|
return sigma;
|
|
}
|
|
|
|
int minindex(const double *arr, int N) {
|
|
double min;
|
|
int index,i;
|
|
|
|
min = DBL_MAX;
|
|
index = 0;
|
|
for(i = 0; i < N;++i) {
|
|
if (arr[i] < min) {
|
|
min = arr[i];
|
|
index = i;
|
|
}
|
|
}
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
void getDWTAppx(wt_object wt, double *appx,int N) {
|
|
/*
|
|
Wavelet decomposition is stored as
|
|
[A(J) D(J) D(J-1) ..... D(1)] in wt->output vector
|
|
|
|
Length of A(J) , N = wt->length[0]
|
|
*/
|
|
int i;
|
|
|
|
for (i = 0; i < N; ++i) {
|
|
appx[i] = wt->output[i];
|
|
}
|
|
}
|
|
|
|
void getDWTDetail(wt_object wt, double *detail, int N, int level) {
|
|
/*
|
|
returns Detail coefficents at the jth level where j = J,J-1,...,1
|
|
and Wavelet decomposition is stored as
|
|
[A(J) D(J) D(J-1) ..... D(1)] in wt->output vector
|
|
Use getDWTAppx() to get A(J)
|
|
Level 1 : Length of D(J), ie N, is stored in wt->length[1]
|
|
Level 2 :Length of D(J-1), ie N, is stored in wt->length[2]
|
|
....
|
|
Level J : Length of D(1), ie N, is stored in wt->length[J]
|
|
*/
|
|
int i, iter, J;
|
|
J = wt->J;
|
|
|
|
if (level > J || level < 1) {
|
|
printf("The decomposition only has 1,..,%d levels", J);
|
|
exit(-1);
|
|
}
|
|
|
|
iter = wt->length[0];
|
|
|
|
for (i = 1; i < J-level; ++i) {
|
|
iter += wt->length[i];
|
|
}
|
|
|
|
for (i = 0; i < N; ++i) {
|
|
detail[i] = wt->output[i + iter];
|
|
}
|
|
}
|
|
|
|
void getDWTRecCoeff(double *coeff,int *length,const char *ctype,const char *ext, int level, int J,double *lpr,
|
|
double *hpr,int lf,int siglength,double *reccoeff) {
|
|
|
|
int i,j,k,det_len,N,l,m,n,v,t,l2;
|
|
double *out,*X_lp,*filt;
|
|
out = (double*)malloc(sizeof(double)* (siglength + 1));
|
|
l2 = lf / 2;
|
|
m = -2;
|
|
n = -1;
|
|
if (!strcmp(ext, "per")) {
|
|
if (!strcmp((ctype), "appx")) {
|
|
det_len = length[0];
|
|
} else {
|
|
det_len = length[J - level + 1];
|
|
}
|
|
|
|
N = 2 * length[J];
|
|
|
|
X_lp = (double*)malloc(sizeof(double)* (N + 2 * lf - 1));
|
|
|
|
for (i = 0; i < det_len; ++i) {
|
|
out[i] = coeff[i];
|
|
}
|
|
|
|
for (j = level; j > 0; --j) {
|
|
|
|
//idwt1(wt, temp, cA_up, out, det_len, wt->output + iter, det_len, X_lp, X_hp, out);
|
|
|
|
if (!strcmp((ctype), "det") && j == level) {
|
|
filt = hpr;
|
|
} else {
|
|
filt = lpr;
|
|
}
|
|
|
|
//idwt_per(wt,out, det_len, wt->output + iter, det_len, X_lp);
|
|
m = -2;
|
|
n = -1;
|
|
|
|
for (i = 0; i < det_len + l2 - 1; ++i) {
|
|
m += 2;
|
|
n += 2;
|
|
X_lp[m] = 0.0;
|
|
X_lp[n] = 0.0;
|
|
for (l = 0; l < l2; ++l) {
|
|
t = 2 * l;
|
|
if ((i - l) >= 0 && (i - l) < det_len) {
|
|
X_lp[m] += filt[t] * out[i - l];
|
|
X_lp[n] += filt[t + 1] * out[i - l];
|
|
}
|
|
else if ((i - l) >= det_len && (i-l) < det_len + lf - 1) {
|
|
X_lp[m] += filt[t] * out[i - l - det_len];
|
|
X_lp[n] += filt[t + 1] * out[i - l - det_len];
|
|
}
|
|
else if ((i - l) < 0 && (i-l) > -l2) {
|
|
X_lp[m] += filt[t] * out[det_len + i - l] ;
|
|
X_lp[n] += filt[t + 1] * out[det_len + i - l];
|
|
}
|
|
}
|
|
}
|
|
|
|
for (k = lf/2 - 1; k < 2 * det_len + lf/2 - 1; ++k) {
|
|
out[k - lf/2 + 1] = X_lp[k];
|
|
}
|
|
|
|
if (j != 1) {
|
|
det_len = length[J - j + 2];
|
|
}
|
|
}
|
|
|
|
free(X_lp);
|
|
|
|
}
|
|
else if (!strcmp(ext, "sym")) {
|
|
if (!strcmp((ctype), "appx")) {
|
|
det_len = length[0];
|
|
} else {
|
|
det_len = length[J - level + 1];
|
|
}
|
|
|
|
N = 2 * length[J] - 1;
|
|
|
|
X_lp = (double*)malloc(sizeof(double)* (N + 2 * lf - 1));
|
|
|
|
for (i = 0; i < det_len; ++i) {
|
|
out[i] = coeff[i];
|
|
}
|
|
|
|
for (j = level; j > 0; --j) {
|
|
|
|
//idwt1(wt, temp, cA_up, out, det_len, wt->output + iter, det_len, X_lp, X_hp, out);
|
|
|
|
if (!strcmp((ctype), "det") && j == level) {
|
|
filt = hpr;
|
|
} else {
|
|
filt = lpr;
|
|
}
|
|
|
|
//idwt_sym(wt, out, det_len, wt->output + iter, det_len, X_lp);
|
|
|
|
m = -2;
|
|
n = -1;
|
|
|
|
for (v = 0; v < det_len; ++v) {
|
|
i = v;
|
|
m += 2;
|
|
n += 2;
|
|
X_lp[m] = 0.0;
|
|
X_lp[n] = 0.0;
|
|
for (l = 0; l < lf / 2; ++l) {
|
|
t = 2 * l;
|
|
if ((i - l) >= 0 && (i - l) < det_len) {
|
|
X_lp[m] += filt[t] * out[i - l];
|
|
X_lp[n] += filt[t + 1] * out[i - l];
|
|
}
|
|
}
|
|
}
|
|
|
|
for (k = lf-2; k < 2 * det_len; ++k) {
|
|
out[k - lf + 2] = X_lp[k];
|
|
}
|
|
|
|
|
|
if (j != 1) {
|
|
det_len = length[J - j + 2];
|
|
}
|
|
}
|
|
|
|
free(X_lp);
|
|
|
|
}
|
|
else {
|
|
printf("Signal extension can be either per or sym");
|
|
exit(-1);
|
|
}
|
|
|
|
for (i = 0; i < siglength; ++i) {
|
|
reccoeff[i] = out[i];
|
|
}
|
|
|
|
free(out);
|
|
|
|
}
|
|
|
|
|
|
void autocovar(const double* vec,int N, double* acov,int M) {
|
|
double m,temp1,temp2;
|
|
int i,t;
|
|
m = mean(vec,N);
|
|
|
|
if ( M > N) {
|
|
M = N-1;
|
|
printf("\n Lag is greater than the length N of the input vector. It is automatically set to length N - 1.\n");
|
|
printf("\n The Output Vector only contains N calculated values.");
|
|
} else if ( M < 0) {
|
|
M = 0;
|
|
}
|
|
|
|
for(i = 0; i < M;i++) {
|
|
acov[i] = 0.0;
|
|
for (t = 0; t < N-i;t++) {
|
|
temp1 = vec[t] - m;
|
|
temp2 = vec[t+i] - m;
|
|
acov[i]+= temp1*temp2;
|
|
}
|
|
acov[i] = acov[i] / N;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void autocorr(const double* vec,int N,double* acorr, int M) {
|
|
double var;
|
|
int i;
|
|
if (M > N) {
|
|
M = N - 1;
|
|
printf("\n Lag is greater than the length N of the input vector. It is automatically set to length N - 1.\n");
|
|
printf("\n The Output Vector only contains N calculated values.");
|
|
}
|
|
else if (M < 0) {
|
|
M = 0;
|
|
}
|
|
autocovar(vec,N,acorr,M);
|
|
var = acorr[0];
|
|
acorr[0] = 1.0;
|
|
|
|
for(i = 1; i < M; i++) {
|
|
acorr[i] = acorr[i]/var;
|
|
}
|
|
|
|
}
|