init
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
wavelib
|
||||
=======
|
||||
|
||||
C Implementation of Discrete Wavelet Transform (DWT,SWT and MODWT), Continuous Wavelet transform (CWT) and Discrete Packet Transform ( Full Tree Decomposition and Best Basis DWPT).
|
||||
|
||||
Discrete Wavelet Transform Methods Implemented
|
||||
|
||||
DWT/IDWT A decimated Discrete Wavelet Transform implementation using implicit signal extension and up/downsampling so it is a fast implementation. A FFT based implementation is optional but will not be usually needed. Both periodic and symmetric options are available.
|
||||
|
||||
SWT/ISWT Stationary Wavelet Transform. It works only for signal lengths that are multiples of 2^J where J is the number of decomposition levels. For signals of other lengths see MODWT implementation.
|
||||
|
||||
MODWT/IMODWT Maximal Overlap Discrete Wavelet Transform is another undecimated transform. It is implemented for signals of any length but only orthogonal wavelets (Daubechies, Symlets and Coiflets) can be deployed. This implementation is based on the method laid out in "Wavelet Methods For Wavelet Analysis" by Donald Percival and Andrew Walden.
|
||||
|
||||
Discrete Wavelet Packet Transform Methods Implemented
|
||||
|
||||
WTREE A Fully Decimated Wavelet Tree Decomposition. This is a highly redundant transform and retains all coefficients at each node. This is not recommended for compression and denoising applications.
|
||||
|
||||
DWPT/IDWPT Is a derivative of WTREE method which retains coefficients based on entropy methods. This is a non-redundant transform and output length is of the same order as the input.
|
||||
|
||||
CWT/ICWT C translation ( with some modifications) of Continuous Wavelet Transform Software provided by C. Torrence and G. Compo, and is available at URL: http://atoc.colorado.edu/research/wavelets/'. A generalized Inverse Transform with approximate reconstruction is also added.
|
||||
|
||||
Documentation Available at - https://github.com/rafat/wavelib/wiki
|
||||
|
||||
Live Demo (Emscripten) - http://rafat.github.io/wavelib/
|
||||
|
||||
License - BSD 3-Clause
|
||||
|
||||
Contace - rafat.hsn@gmail.com
|
||||
@@ -0,0 +1,240 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable : 4200)
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
#ifndef fft_type
|
||||
#define fft_type double
|
||||
#endif
|
||||
|
||||
#ifndef cplx_type
|
||||
#define cplx_type double
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct cplx_t
|
||||
{
|
||||
cplx_type re;
|
||||
cplx_type im;
|
||||
} cplx_data;
|
||||
|
||||
typedef struct wave_set* wave_object;
|
||||
|
||||
wave_object wave_init(char* wname);
|
||||
|
||||
struct wave_set
|
||||
{
|
||||
char wname[50];
|
||||
int filtlength;// When all filters are of the same length. [Matlab uses zero-padding to make all filters of the same length]
|
||||
int lpd_len;// Default filtlength = lpd_len = lpr_len = hpd_len = hpr_len
|
||||
int hpd_len;
|
||||
int lpr_len;
|
||||
int hpr_len;
|
||||
double* lpd;
|
||||
double* hpd;
|
||||
double* lpr;
|
||||
double* hpr;
|
||||
double params[0];
|
||||
};
|
||||
|
||||
typedef struct fft_t
|
||||
{
|
||||
fft_type re;
|
||||
fft_type im;
|
||||
} fft_data;
|
||||
|
||||
typedef struct fft_set* fft_object;
|
||||
|
||||
fft_object fft_init(int N, int sgn);
|
||||
|
||||
struct fft_set
|
||||
{
|
||||
int N;
|
||||
int sgn;
|
||||
int factors[64];
|
||||
int lf;
|
||||
int lt;
|
||||
fft_data twiddle[1];
|
||||
};
|
||||
|
||||
typedef struct fft_real_set* fft_real_object;
|
||||
|
||||
fft_real_object fft_real_init(int N, int sgn);
|
||||
|
||||
struct fft_real_set
|
||||
{
|
||||
fft_object cobj;
|
||||
fft_data twiddle2[1];
|
||||
};
|
||||
|
||||
typedef struct conv_set* conv_object;
|
||||
|
||||
conv_object conv_init(int N, int L);
|
||||
|
||||
struct conv_set
|
||||
{
|
||||
fft_real_object fobj;
|
||||
fft_real_object iobj;
|
||||
int ilen1;
|
||||
int ilen2;
|
||||
int clen;
|
||||
};
|
||||
|
||||
typedef struct wt_set* wt_object;
|
||||
|
||||
wt_object wt_init(wave_object wave, char* method, int siglength, int J);
|
||||
|
||||
struct wt_set
|
||||
{
|
||||
wave_object wave;
|
||||
conv_object cobj;
|
||||
char method[10];
|
||||
int siglength;// Length of the original signal.
|
||||
int outlength;// Length of the output DWT vector
|
||||
int lenlength;// Length of the Output Dimension Vector "length"
|
||||
int J; // Number of decomposition Levels
|
||||
int MaxIter;// Maximum Iterations J <= MaxIter
|
||||
int even;// even = 1 if signal is of even length. even = 0 otherwise
|
||||
char ext[10];// Type of Extension used - "per" or "sym"
|
||||
char cmethod[10]; // Convolution Method - "direct" or "FFT"
|
||||
|
||||
int N; //
|
||||
int cfftset;
|
||||
int zpad;
|
||||
int length[102];
|
||||
double* output;
|
||||
double params[0];
|
||||
};
|
||||
|
||||
typedef struct wtree_set* wtree_object;
|
||||
|
||||
wtree_object wtree_init(wave_object wave, int siglength, int J);
|
||||
|
||||
struct wtree_set
|
||||
{
|
||||
wave_object wave;
|
||||
conv_object cobj;
|
||||
char method[10];
|
||||
int siglength;// Length of the original signal.
|
||||
int outlength;// Length of the output DWT vector
|
||||
int lenlength;// Length of the Output Dimension Vector "length"
|
||||
int J; // Number of decomposition Levels
|
||||
int MaxIter;// Maximum Iterations J <= MaxIter
|
||||
int even;// even = 1 if signal is of even length. even = 0 otherwise
|
||||
char ext[10];// Type of Extension used - "per" or "sym"
|
||||
|
||||
int N; //
|
||||
int nodes;
|
||||
int cfftset;
|
||||
int zpad;
|
||||
int length[102];
|
||||
double* output;
|
||||
int* nodelength;
|
||||
int* coeflength;
|
||||
double params[0];
|
||||
};
|
||||
|
||||
typedef struct wpt_set* wpt_object;
|
||||
|
||||
wpt_object wpt_init(wave_object wave, int siglength, int J);
|
||||
|
||||
struct wpt_set
|
||||
{
|
||||
wave_object wave;
|
||||
conv_object cobj;
|
||||
int siglength;// Length of the original signal.
|
||||
int outlength;// Length of the output DWT vector
|
||||
int lenlength;// Length of the Output Dimension Vector "length"
|
||||
int J; // Number of decomposition Levels
|
||||
int MaxIter;// Maximum Iterations J <= MaxIter
|
||||
int even;// even = 1 if signal is of even length. even = 0 otherwise
|
||||
char ext[10];// Type of Extension used - "per" or "sym"
|
||||
char entropy[20];
|
||||
double eparam;
|
||||
|
||||
int N; //
|
||||
int nodes;
|
||||
int length[102];
|
||||
double* output;
|
||||
double* costvalues;
|
||||
double* basisvector;
|
||||
int* nodeindex;
|
||||
int* numnodeslevel;
|
||||
int* coeflength;
|
||||
double params[0];
|
||||
};
|
||||
|
||||
|
||||
typedef struct cwt_set* cwt_object;
|
||||
|
||||
cwt_object cwt_init(char* wave, double param, int siglength, double dt, int J);
|
||||
|
||||
struct cwt_set
|
||||
{
|
||||
char wave[10];// Wavelet - morl/morlet,paul,dog/dgauss
|
||||
int siglength;// Length of Input Data
|
||||
int J;// Total Number of Scales
|
||||
double s0;// Smallest scale. It depends on the sampling rate. s0 <= 2 * dt for most wavelets
|
||||
double dt;// Sampling Rate
|
||||
double dj;// Separation between scales. eg., scale = s0 * 2 ^ ( [0:N-1] *dj ) or scale = s0 *[0:N-1] * dj
|
||||
char type[10];// Scale Type - Power or Linear
|
||||
int pow;// Base of Power in case type = pow. Typical value is pow = 2
|
||||
int sflag;
|
||||
int pflag;
|
||||
int npad;
|
||||
int mother;
|
||||
double m;// Wavelet parameter param
|
||||
double smean;// Input Signal mean
|
||||
|
||||
cplx_data* output;
|
||||
double* scale;
|
||||
double* period;
|
||||
double* coi;
|
||||
double params[0];
|
||||
};
|
||||
|
||||
void dwt(wt_object wt, double* inp);
|
||||
void idwt(wt_object wt, double* dwtop);
|
||||
void wtree(wtree_object wt, double* inp);
|
||||
void dwpt(wpt_object wt, double* inp);
|
||||
void idwpt(wpt_object wt, double* dwtop);
|
||||
void swt(wt_object wt, double* inp);
|
||||
void iswt(wt_object wt, double* swtop);
|
||||
void modwt(wt_object wt, double* inp);
|
||||
void imodwt(wt_object wt, double* dwtop);
|
||||
void setDWTExtension(wt_object wt, char* extension);
|
||||
void setWTREEExtension(wtree_object wt, char* extension);
|
||||
void setDWPTExtension(wpt_object wt, char* extension);
|
||||
void setDWPTEntropy(wpt_object wt, char* entropy, double eparam);
|
||||
void setWTConv(wt_object wt, char* cmethod);
|
||||
int getWTREENodelength(wtree_object wt, int X);
|
||||
void getWTREECoeffs(wtree_object wt, int X, int Y, double* coeffs, int N);
|
||||
int getDWPTNodelength(wpt_object wt, int X);
|
||||
void getDWPTCoeffs(wpt_object wt, int X, int Y, double* coeffs, int N);
|
||||
int setCWTScales(cwt_object wt, double s0, double dj, char* type, int power);
|
||||
void setCWTScaleVector(cwt_object wt, double* scale, int J, double s0, double dj);
|
||||
void setCWTPadding(cwt_object wt, int pad);
|
||||
int cwt(cwt_object wt, double* inp);
|
||||
void icwt(cwt_object wt, double* cwtop);
|
||||
int getCWTScaleLength(int N);
|
||||
void wave_summary(wave_object obj);
|
||||
void wt_summary(wt_object wt);
|
||||
void wtree_summary(wtree_object wt);
|
||||
void wpt_summary(wpt_object wt);
|
||||
void cwt_summary(cwt_object wt);
|
||||
void wave_free(wave_object object);
|
||||
void wt_free(wt_object object);
|
||||
void wtree_free(wtree_object object);
|
||||
void wpt_free(wpt_object object);
|
||||
void cwt_free(cwt_object object);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* conv.c
|
||||
*
|
||||
* Created on: May 1, 2013
|
||||
* Author: Rafat Hussain
|
||||
*/
|
||||
|
||||
#include "conv.h"
|
||||
|
||||
int factorf(int M)
|
||||
{
|
||||
int N = M;
|
||||
while (N % 7 == 0) { N = N / 7; }
|
||||
while (N % 3 == 0) { N = N / 3; }
|
||||
while (N % 5 == 0) { N = N / 5; }
|
||||
while (N % 2 == 0) { N = N / 2; }
|
||||
|
||||
return N;
|
||||
}
|
||||
|
||||
|
||||
int findnext(int M)
|
||||
{
|
||||
int N = M;
|
||||
|
||||
while (factorf(N) != 1) { ++N; }
|
||||
|
||||
return N;
|
||||
}
|
||||
|
||||
int findnexte(int M)
|
||||
{
|
||||
int N = M;
|
||||
|
||||
while (factorf(N) != 1 || N % 2 != 0) { ++N; }
|
||||
|
||||
return N;
|
||||
}
|
||||
|
||||
|
||||
conv_object conv_init(int N, int L)
|
||||
{
|
||||
const int conv_len = N + L - 1;
|
||||
const conv_object obj = (conv_object)malloc(sizeof(struct conv_set));
|
||||
|
||||
//obj->clen = npow2(conv_len);
|
||||
//obj->clen = conv_len;
|
||||
obj->clen = findnexte(conv_len);
|
||||
obj->ilen1 = N;
|
||||
obj->ilen2 = L;
|
||||
|
||||
obj->fobj = fft_real_init(obj->clen, 1);
|
||||
obj->iobj = fft_real_init(obj->clen, -1);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
void conv_directx(fft_type* inp1, int N, fft_type* inp2, int L,fft_type* oup)
|
||||
{
|
||||
const int M = N + L - 1;
|
||||
|
||||
for (int k = 0; k < M; ++k)
|
||||
{
|
||||
oup[k] = 0.0;
|
||||
for (int n = 0; n < N; ++n) { if ((k - n) >= 0 && (k - n) < L) { oup[k] += inp1[n] * inp2[k - n]; } }
|
||||
}
|
||||
}
|
||||
|
||||
void conv_direct(fft_type* inp1, int N, fft_type* inp2, int L,fft_type* oup)
|
||||
{
|
||||
int k, m;
|
||||
fft_type t1, tmin;
|
||||
|
||||
const int M = N + L - 1;
|
||||
int i = 0;
|
||||
|
||||
if (N >= L)
|
||||
{
|
||||
for (k = 0; k < L; ++k)
|
||||
{
|
||||
oup[k] = 0.0;
|
||||
for (m = 0; m <= k; ++m) { oup[k] += inp1[m] * inp2[k - m]; }
|
||||
}
|
||||
|
||||
for (k = L; k < M; ++k)
|
||||
{
|
||||
oup[k] = 0.0;
|
||||
i++;
|
||||
t1 = L + i;
|
||||
tmin = MIN(t1, N);
|
||||
for (m = i; m < tmin; ++m) { oup[k] += inp1[m] * inp2[k - m]; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (k = 0; k < N; ++k)
|
||||
{
|
||||
oup[k] = 0.0;
|
||||
for (m = 0; m <= k; ++m) { oup[k] += inp2[m] * inp1[k - m]; }
|
||||
}
|
||||
|
||||
for (k = N; k < M; ++k)
|
||||
{
|
||||
oup[k] = 0.0;
|
||||
i++;
|
||||
t1 = N + i;
|
||||
tmin = MIN(t1, L);
|
||||
for (m = i; m < tmin; ++m) { oup[k] += inp2[m] * inp1[k - m]; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void conv_fft(const conv_object obj,fft_type* inp1,fft_type* inp2,fft_type* oup)
|
||||
{
|
||||
int i;
|
||||
|
||||
const int N = obj->clen;
|
||||
const int L1 = obj->ilen1;
|
||||
const int L2 = obj->ilen2;
|
||||
const int ls = L1 + L2 - 1;
|
||||
|
||||
fft_type* a = (fft_type*)malloc(sizeof(fft_data) * N);
|
||||
fft_type* b = (fft_type*)malloc(sizeof(fft_data) * N);
|
||||
fft_data* c = (fft_data*)malloc(sizeof(fft_data) * N);
|
||||
fft_data* ao = (fft_data*)malloc(sizeof(fft_data) * N);
|
||||
fft_data* bo = (fft_data*)malloc(sizeof(fft_data) * N);
|
||||
fft_type* co = (fft_type*)malloc(sizeof(fft_data) * N);
|
||||
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
if (i < L1) { a[i] = inp1[i]; }
|
||||
else { a[i] = 0.0; }
|
||||
|
||||
if (i < L2) { b[i] = inp2[i]; }
|
||||
else { b[i] = 0.0; }
|
||||
}
|
||||
|
||||
fft_r2c_exec(obj->fobj, a, ao);
|
||||
fft_r2c_exec(obj->fobj, b, bo);
|
||||
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
c[i].re = ao[i].re * bo[i].re - ao[i].im * bo[i].im;
|
||||
c[i].im = ao[i].im * bo[i].re + ao[i].re * bo[i].im;
|
||||
}
|
||||
|
||||
fft_c2r_exec(obj->iobj, c, co);
|
||||
|
||||
for (i = 0; i < ls; ++i) { oup[i] = co[i] / N; }
|
||||
|
||||
free(a);
|
||||
free(b);
|
||||
free(c);
|
||||
free(ao);
|
||||
free(bo);
|
||||
free(co);
|
||||
}
|
||||
|
||||
|
||||
void free_conv(conv_object object)
|
||||
{
|
||||
free_real_fft(object->fobj);
|
||||
free_real_fft(object->iobj);
|
||||
free(object);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* conv.h
|
||||
*
|
||||
* Created on: May 1, 2013
|
||||
* Author: Rafat Hussain
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "real.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
|
||||
typedef struct conv_set* conv_object;
|
||||
|
||||
conv_object conv_init(int N, int L);
|
||||
|
||||
struct conv_set
|
||||
{
|
||||
fft_real_object fobj;
|
||||
fft_real_object iobj;
|
||||
int ilen1;
|
||||
int ilen2;
|
||||
int clen;
|
||||
};
|
||||
|
||||
int factorf(int M);
|
||||
int findnext(int M);
|
||||
int findnexte(int M);
|
||||
void conv_direct(fft_type* inp1, int N, fft_type* inp2, int L, fft_type* oup);
|
||||
void conv_directx(fft_type* inp1, int N, fft_type* inp2, int L, fft_type* oup);
|
||||
//void conv_fft(const conv_object obj,fft_type *inp1,fft_type *inp2,fft_type *oup);
|
||||
//void conv_fft(const conv_object obj,fft_type *inp1,fft_type *inp2,fft_type *oup);
|
||||
void conv_fft(const conv_object obj, fft_type* inp1, fft_type* inp2, fft_type* oup);
|
||||
//void free_conv(conv_object object);
|
||||
void free_conv(conv_object object);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
Copyright (c) 2015, Rafat Hussain
|
||||
*/
|
||||
/*
|
||||
This code is a C translation ( with some modifications) of Wavelet Software provided by
|
||||
C. Torrence and G. Compo, and is available at URL: http://atoc.colorado.edu/research/wavelets/''.
|
||||
*/
|
||||
|
||||
#include "cwt.h"
|
||||
|
||||
/*
|
||||
static double factorial3(int N)
|
||||
{
|
||||
double factorial = 1;
|
||||
for (int i = 1; i <= N; ++i) { factorial *= i; }
|
||||
return factorial;
|
||||
}
|
||||
*/
|
||||
double factorial(int N)
|
||||
{
|
||||
if (N > 40)
|
||||
{
|
||||
printf("This program is only valid for N <= 40 \n");
|
||||
return -1.0;
|
||||
}
|
||||
double fact[41] = {
|
||||
1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000,
|
||||
20922789888000, 355687428096000, 6402373705728000, 121645100408832000.0, 2432902008176640000.0, 51090942171709440000.0, 1124000727777607680000.0,
|
||||
25852016738884976640000.0, 620448401733239439360000.0, 15511210043330985984000000.0, 403291461126605635584000000.0, 10888869450418352160768000000.0,
|
||||
304888344611713860501504000000.0, 8841761993739701954543616000000.0, 265252859812191058636308480000000.0, 8222838654177922817725562880000000.0,
|
||||
263130836933693530167218012160000000.0, 8683317618811886495518194401280000000.0, 295232799039604140847618609643520000000.0,
|
||||
10333147966386144929666651337523200000000.0,
|
||||
371993326789901217467999448150835200000000.0, 13763753091226345046315979581580902400000000.0, 523022617466601111760007224100074291200000000.0,
|
||||
20397882081197443358640281739902897356800000000.0, 815915283247897734345611269596115894272000000000.0
|
||||
};
|
||||
|
||||
return fact[N];
|
||||
}
|
||||
|
||||
static void wave_function(int nk, double dt, int mother, double param, double scale1, double* kwave, double pi, double* period1, double* coi1,
|
||||
fft_data* daughter)
|
||||
{
|
||||
double norm, expnt, fourier_factor;
|
||||
int k, m;
|
||||
double temp;
|
||||
int sign, re;
|
||||
|
||||
|
||||
if (mother == 0)
|
||||
{
|
||||
//MORLET
|
||||
if (param < 0.0) { param = 6.0; }
|
||||
norm = sqrt(2.0 * pi * scale1 / dt) * pow(pi, -0.25);
|
||||
|
||||
for (k = 1; k <= nk / 2 + 1; ++k)
|
||||
{
|
||||
temp = (scale1 * kwave[k - 1] - param);
|
||||
expnt = -0.5 * temp * temp;
|
||||
daughter[k - 1].re = norm * exp(expnt);
|
||||
daughter[k - 1].im = 0.0;
|
||||
}
|
||||
for (k = nk / 2 + 2; k <= nk; ++k) { daughter[k - 1].re = daughter[k - 1].im = 0.0; }
|
||||
fourier_factor = (4.0 * pi) / (param + sqrt(2.0 + param * param));
|
||||
*period1 = scale1 * fourier_factor;
|
||||
*coi1 = fourier_factor / sqrt(2.0);
|
||||
}
|
||||
else if (mother == 1)
|
||||
{
|
||||
// PAUL
|
||||
if (param < 0.0) { param = 4.0; }
|
||||
m = (int)param;
|
||||
norm = sqrt(2.0 * pi * scale1 / dt) * (pow(2.0, (double)m) / sqrt(m * factorial(2 * m - 1)));
|
||||
for (k = 1; k <= nk / 2 + 1; ++k)
|
||||
{
|
||||
temp = scale1 * kwave[k - 1];
|
||||
expnt = - temp;
|
||||
daughter[k - 1].re = norm * pow(temp, (double)m) * exp(expnt);
|
||||
daughter[k - 1].im = 0.0;
|
||||
}
|
||||
for (k = nk / 2 + 2; k <= nk; ++k) { daughter[k - 1].re = daughter[k - 1].im = 0.0; }
|
||||
fourier_factor = (4.0 * pi) / (2.0 * m + 1.0);
|
||||
*period1 = scale1 * fourier_factor;
|
||||
*coi1 = fourier_factor * sqrt(2.0);
|
||||
}
|
||||
else if (mother == 2)
|
||||
{
|
||||
if (param < 0.0) { param = 2.0; }
|
||||
m = (int)param;
|
||||
|
||||
if (m % 2 == 0) { re = 1; }
|
||||
else { re = 0; }
|
||||
|
||||
if (m % 4 == 0 || m % 4 == 1) { sign = -1; }
|
||||
else { sign = 1; }
|
||||
|
||||
|
||||
norm = sqrt(2.0 * pi * scale1 / dt) * sqrt(1.0 / gamma(m + 0.50));
|
||||
norm *= sign;
|
||||
|
||||
if (re == 1)
|
||||
{
|
||||
for (k = 1; k <= nk; ++k)
|
||||
{
|
||||
temp = scale1 * kwave[k - 1];
|
||||
daughter[k - 1].re = norm * pow(temp, (double)m) * exp(-0.50 * pow(temp, 2.0));
|
||||
daughter[k - 1].im = 0.0;
|
||||
}
|
||||
}
|
||||
else if (re == 0)
|
||||
{
|
||||
for (k = 1; k <= nk; ++k)
|
||||
{
|
||||
temp = scale1 * kwave[k - 1];
|
||||
daughter[k - 1].re = 0.0;
|
||||
daughter[k - 1].im = norm * pow(temp, (double)m) * exp(-0.50 * pow(temp, 2.0));
|
||||
}
|
||||
}
|
||||
fourier_factor = (2.0 * pi) * sqrt(2.0 / (2.0 * m + 1.0));
|
||||
*period1 = scale1 * fourier_factor;
|
||||
*coi1 = fourier_factor / sqrt(2.0);
|
||||
}
|
||||
}
|
||||
|
||||
int cwavelet(double* y, int N, double dt, int mother, double param, double s0, double dj, int jtot, int npad, double* wave, double* scale, double* period,
|
||||
double* coi)
|
||||
{
|
||||
double period1, coi1;
|
||||
|
||||
const double pi = 4.0 * atan(1.0);
|
||||
|
||||
if (npad < N)
|
||||
{
|
||||
printf("npad must be >= N \n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const fft_object obj = fft_init(npad, 1);
|
||||
const fft_object iobj = fft_init(npad, -1);
|
||||
|
||||
fft_data* ypad = (fft_data*)malloc(sizeof(fft_data) * npad);
|
||||
fft_data* yfft = (fft_data*)malloc(sizeof(fft_data) * npad);
|
||||
fft_data* daughter = (fft_data*)malloc(sizeof(fft_data) * npad);
|
||||
double* kwave = (double*)malloc(sizeof(double) * npad);
|
||||
|
||||
double ymean = 0.0;
|
||||
|
||||
for (int i = 0; i < N; ++i) { ymean += y[i]; }
|
||||
|
||||
ymean /= N;
|
||||
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
ypad[i].re = y[i] - ymean;
|
||||
ypad[i].im = 0.0;
|
||||
}
|
||||
|
||||
for (int i = N; i < npad; ++i) { ypad[i].re = ypad[i].im = 0.0; }
|
||||
|
||||
|
||||
// Find FFT of the input y (ypad)
|
||||
|
||||
fft_exec(obj, ypad, yfft);
|
||||
|
||||
for (int i = 0; i < npad; ++i)
|
||||
{
|
||||
yfft[i].re /= (double)npad;
|
||||
yfft[i].im /= (double)npad;
|
||||
}
|
||||
|
||||
|
||||
//Construct the wavenumber array
|
||||
|
||||
const double freq1 = 2.0 * pi / ((double)npad * dt);
|
||||
kwave[0] = 0.0;
|
||||
|
||||
for (int i = 1; i < npad / 2 + 1; ++i) { kwave[i] = i * freq1; }
|
||||
|
||||
for (int i = npad / 2 + 1; i < npad; ++i) { kwave[i] = -kwave[npad - i]; }
|
||||
|
||||
// Main loop
|
||||
|
||||
for (int j = 1; j <= jtot; ++j)
|
||||
{
|
||||
const double scale1 = scale[j - 1];// = s0*pow(2.0, (double)(j - 1)*dj);
|
||||
wave_function(npad, dt, mother, param, scale1, kwave, pi, &period1, &coi1, daughter);
|
||||
period[j - 1] = period1;
|
||||
for (int k = 0; k < npad; ++k)
|
||||
{
|
||||
const double tmp1 = daughter[k].re * yfft[k].re - daughter[k].im * yfft[k].im;
|
||||
const double tmp2 = daughter[k].re * yfft[k].im + daughter[k].im * yfft[k].re;
|
||||
daughter[k].re = tmp1;
|
||||
daughter[k].im = tmp2;
|
||||
}
|
||||
fft_exec(iobj, daughter, ypad);
|
||||
const int iter = 2 * (j - 1) * N;
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
wave[iter + 2 * i] = ypad[i].re;
|
||||
wave[iter + 2 * i + 1] = ypad[i].im;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i = 1; i <= (N + 1) / 2; ++i)
|
||||
{
|
||||
coi[i - 1] = coi1 * dt * ((double)i - 1.0);
|
||||
coi[N - i] = coi[i - 1];
|
||||
}
|
||||
|
||||
|
||||
free(kwave);
|
||||
free(ypad);
|
||||
free(yfft);
|
||||
free(daughter);
|
||||
|
||||
free_fft(obj);
|
||||
free_fft(iobj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void psi0(int mother, double param, double* val, int* real)
|
||||
{
|
||||
int sign;
|
||||
|
||||
const int m = (int)param;
|
||||
const double pi = 4.0 * atan(1.0);
|
||||
|
||||
if (mother == 0)
|
||||
{
|
||||
// Morlet
|
||||
*val = 1.0 / sqrt(sqrt(pi));
|
||||
*real = 1;
|
||||
}
|
||||
else if (mother == 1)
|
||||
{
|
||||
//Paul
|
||||
if (m % 2 == 0) { *real = 1; }
|
||||
else { *real = 0; }
|
||||
|
||||
if (m % 4 == 0 || m % 4 == 1) { sign = 1; }
|
||||
else { sign = -1; }
|
||||
*val = sign * pow(2.0, (double)m) * factorial(m) / (sqrt(pi * factorial(2 * m)));
|
||||
}
|
||||
else if (mother == 2)
|
||||
{
|
||||
// D.O.G
|
||||
*real = 1;
|
||||
|
||||
if (m % 2 == 0)
|
||||
{
|
||||
if (m % 4 == 0) { sign = -1; }
|
||||
else { sign = 1; }
|
||||
const double coeff = sign * pow(2.0, (double)m / 2) / gamma(0.5);
|
||||
*val = coeff * gamma(((double)m + 1.0) / 2.0) / sqrt(gamma(m + 0.50));
|
||||
}
|
||||
else { *val = 0; }
|
||||
}
|
||||
}
|
||||
|
||||
static int maxabs(double* array, int N)
|
||||
{
|
||||
double maxval = 0.0;
|
||||
int index = -1;
|
||||
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
const double temp = fabs(array[i]);
|
||||
if (temp >= maxval)
|
||||
{
|
||||
maxval = temp;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
double cdelta(int mother, double param, double psi0)
|
||||
{
|
||||
int N = 0;
|
||||
double s0 = 0;
|
||||
|
||||
double subscale = 8.0;
|
||||
const double dt = 0.25;
|
||||
if (mother == 0)
|
||||
{
|
||||
N = 16;
|
||||
s0 = dt / 4;
|
||||
}
|
||||
else if (mother == 1)
|
||||
{
|
||||
N = 16;
|
||||
s0 = dt / 4.0;
|
||||
}
|
||||
else if (mother == 2)
|
||||
{
|
||||
s0 = dt / 8.0;
|
||||
N = 256;
|
||||
if (param == 2.0)
|
||||
{
|
||||
subscale = 16.0;
|
||||
s0 = dt / 16.0;
|
||||
N = 2048;
|
||||
}
|
||||
}
|
||||
|
||||
const double dj = 1.0 / subscale;
|
||||
const int jtot = 16 * (int)subscale;
|
||||
|
||||
double* delta = (double*)malloc(sizeof(double) * N);
|
||||
double* wave = (double*)malloc(sizeof(double) * 2 * N * jtot);
|
||||
double* coi = (double*)malloc(sizeof(double) * N);
|
||||
double* scale = (double*)malloc(sizeof(double) * jtot);
|
||||
double* period = (double*)malloc(sizeof(double) * jtot);
|
||||
double* mval = (double*)malloc(sizeof(double) * N);
|
||||
|
||||
|
||||
delta[0] = 1;
|
||||
|
||||
for (int i = 1; i < N; ++i) { delta[i] = 0; }
|
||||
|
||||
for (int i = 0; i < jtot; ++i) { scale[i] = s0 * pow(2.0, (double)(i) * dj); }
|
||||
|
||||
cwavelet(delta, N, dt, mother, param, s0, dj, jtot, N, wave, scale, period, coi);
|
||||
|
||||
for (int i = 0; i < N; ++i) { mval[i] = 0; }
|
||||
|
||||
for (int j = 0; j < jtot; ++j)
|
||||
{
|
||||
const int iter = 2 * j * N;
|
||||
const double den = sqrt(scale[j]);
|
||||
for (int i = 0; i < N; ++i) { mval[i] += wave[iter + 2 * i] / den; }
|
||||
}
|
||||
|
||||
|
||||
const int maxarr = maxabs(mval, N);
|
||||
const double cdel = sqrt(dt) * dj * mval[maxarr] / psi0;
|
||||
|
||||
free(delta);
|
||||
free(wave);
|
||||
|
||||
free(scale);
|
||||
free(period);
|
||||
free(coi);
|
||||
free(mval);
|
||||
|
||||
return cdel;
|
||||
}
|
||||
|
||||
void icwavelet(double* wave, int N, double* scale, int jtot, double dt, double dj, double cdelta, double psi0, double* oup)
|
||||
{
|
||||
const double coeff = sqrt(dt) * dj / (cdelta * psi0);
|
||||
|
||||
for (int i = 0; i < N; ++i) { oup[i] = 0.0; }
|
||||
|
||||
for (int j = 0; j < jtot; ++j)
|
||||
{
|
||||
const int iter = 2 * j * N;
|
||||
const double den = sqrt(scale[j]);
|
||||
for (int i = 0; i < N; ++i) { oup[i] += wave[iter + 2 * i] / den; }
|
||||
}
|
||||
|
||||
for (int i = 0; i < N; ++i) { oup[i] *= coeff; }
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "wavefunc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int cwavelet(double* y, int N, double dt, int mother, double param, double s0, double dj, int jtot, int npad, double* wave, double* scale, double* period,
|
||||
double* coi);
|
||||
|
||||
void psi0(int mother, double param, double* val, int* real);
|
||||
|
||||
double factorial(int N);
|
||||
|
||||
double cdelta(int mother, double param, double psi0);
|
||||
|
||||
void icwavelet(double* wave, int N, double* scale, int jtot, double dt, double dj, double cdelta, double psi0, double* oup);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,299 @@
|
||||
#include "cwtmath.h"
|
||||
|
||||
static void nsfft_fd(const fft_object obj, fft_data* inp, fft_data* oup, const double lb, const double ub, double* w)
|
||||
{
|
||||
int i;
|
||||
|
||||
const int N = obj->N;
|
||||
const int L = N / 2;
|
||||
//w = (double*)malloc(sizeof(double)*N);
|
||||
|
||||
const int M = divideby(N, 2);
|
||||
|
||||
if (M == 0)
|
||||
{
|
||||
printf("The Non-Standard FFT Length must be a power of 2");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
double* temp1 = (double*)malloc(sizeof(double) * L);
|
||||
double* temp2 = (double*)malloc(sizeof(double) * L);
|
||||
|
||||
const double delta = (ub - lb) / N;
|
||||
int j = -N;
|
||||
const double den = 2 * (ub - lb);
|
||||
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
w[i] = (double)j / den;
|
||||
j += 2;
|
||||
}
|
||||
|
||||
fft_exec(obj, inp, oup);
|
||||
|
||||
|
||||
for (i = 0; i < L; ++i)
|
||||
{
|
||||
temp1[i] = oup[i].re;
|
||||
temp2[i] = oup[i].im;
|
||||
}
|
||||
|
||||
for (i = 0; i < N - L; ++i)
|
||||
{
|
||||
oup[i].re = oup[i + L].re;
|
||||
oup[i].im = oup[i + L].im;
|
||||
}
|
||||
|
||||
for (i = 0; i < L; ++i)
|
||||
{
|
||||
oup[N - L + i].re = temp1[i];
|
||||
oup[N - L + i].im = temp2[i];
|
||||
}
|
||||
|
||||
const double plb = PI2 * lb;
|
||||
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
const double tempr = oup[i].re;
|
||||
const double tempi = oup[i].im;
|
||||
const double theta = w[i] * plb;
|
||||
|
||||
oup[i].re = delta * (tempr * cos(theta) + tempi * sin(theta));
|
||||
oup[i].im = delta * (tempi * cos(theta) - tempr * sin(theta));
|
||||
}
|
||||
|
||||
|
||||
//free(w);
|
||||
free(temp1);
|
||||
free(temp2);
|
||||
}
|
||||
|
||||
static void nsfft_bk(fft_object obj, fft_data* inp, fft_data* oup, double lb, double ub, double* t)
|
||||
{
|
||||
int i;
|
||||
|
||||
const int N = obj->N;
|
||||
const int L = N / 2;
|
||||
|
||||
const int M = divideby(N, 2);
|
||||
|
||||
if (M == 0)
|
||||
{
|
||||
printf("The Non-Standard FFT Length must be a power of 2");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
double* temp1 = (double*)malloc(sizeof(double) * L);
|
||||
double* temp2 = (double*)malloc(sizeof(double) * L);
|
||||
double* w = (double*)malloc(sizeof(double) * N);
|
||||
fft_data* inpt = (fft_data*)malloc(sizeof(fft_data) * N);
|
||||
|
||||
const double delta = (ub - lb) / N;
|
||||
int j = -N;
|
||||
const double den = 2 * (ub - lb);
|
||||
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
w[i] = (double)j / den;
|
||||
j += 2;
|
||||
}
|
||||
|
||||
const double plb = PI2 * lb;
|
||||
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
const double theta = w[i] * plb;
|
||||
|
||||
inpt[i].re = (inp[i].re * cos(theta) - inp[i].im * sin(theta)) / delta;
|
||||
inpt[i].im = (inp[i].im * cos(theta) + inp[i].re * sin(theta)) / delta;
|
||||
}
|
||||
|
||||
for (i = 0; i < L; ++i)
|
||||
{
|
||||
temp1[i] = inpt[i].re;
|
||||
temp2[i] = inpt[i].im;
|
||||
}
|
||||
|
||||
for (i = 0; i < N - L; ++i)
|
||||
{
|
||||
inpt[i].re = inpt[i + L].re;
|
||||
inpt[i].im = inpt[i + L].im;
|
||||
}
|
||||
|
||||
for (i = 0; i < L; ++i)
|
||||
{
|
||||
inpt[N - L + i].re = temp1[i];
|
||||
inpt[N - L + i].im = temp2[i];
|
||||
}
|
||||
|
||||
fft_exec(obj, inpt, oup);
|
||||
|
||||
for (i = 0; i < N; ++i) { t[i] = lb + i * delta; }
|
||||
|
||||
free(w);
|
||||
free(temp1);
|
||||
free(temp2);
|
||||
free(inpt);
|
||||
}
|
||||
|
||||
void nsfft_exec(fft_object obj, fft_data* inp, fft_data* oup, double lb, double ub, double* w)
|
||||
{
|
||||
if (obj->sgn == 1) { nsfft_fd(obj, inp, oup, lb, ub, w); }
|
||||
else if (obj->sgn == -1) { nsfft_bk(obj, inp, oup, lb, ub, w); }
|
||||
}
|
||||
|
||||
static double fix(double x)
|
||||
{
|
||||
// Rounds to the integer nearest to zero
|
||||
if (x >= 0.) { return floor(x); }
|
||||
return ceil(x);
|
||||
}
|
||||
|
||||
int nint(double N)
|
||||
{
|
||||
//const int i = (int)(N + 0.49999);
|
||||
//return i;
|
||||
return (int)(N + 0.49999);
|
||||
}
|
||||
|
||||
double gamma(double x)
|
||||
{
|
||||
/*
|
||||
* This C program code is based on W J Cody's fortran code.
|
||||
* http://www.netlib.org/specfun/gamma
|
||||
*
|
||||
* References:
|
||||
"An Overview of Software Development for Special Functions",
|
||||
W. J. Cody, Lecture Notes in Mathematics, 506,
|
||||
Numerical Analysis Dundee, 1975, G. A. Watson (ed.),
|
||||
Springer Verlag, Berlin, 1976.
|
||||
|
||||
Computer Approximations, Hart, Et. Al., Wiley and sons, New York, 1968.
|
||||
*/
|
||||
|
||||
// numerator and denominator coefficients for 1 <= x <= 2
|
||||
|
||||
double oup, yi, z;
|
||||
int i;
|
||||
|
||||
const double spi = 0.9189385332046727417803297;
|
||||
const double pi = 3.1415926535897932384626434;
|
||||
const double xmax = 171.624e+0;
|
||||
const double xinf = 1.79e308;
|
||||
const double eps = 2.22e-16;
|
||||
const double xninf = 1.79e-308;
|
||||
|
||||
double num[8] = {
|
||||
-1.71618513886549492533811e+0,
|
||||
2.47656508055759199108314e+1,
|
||||
-3.79804256470945635097577e+2,
|
||||
6.29331155312818442661052e+2,
|
||||
8.66966202790413211295064e+2,
|
||||
-3.14512729688483675254357e+4,
|
||||
-3.61444134186911729807069e+4,
|
||||
6.64561438202405440627855e+4
|
||||
};
|
||||
|
||||
double den[8] = {
|
||||
-3.08402300119738975254353e+1,
|
||||
3.15350626979604161529144e+2,
|
||||
-1.01515636749021914166146e+3,
|
||||
-3.10777167157231109440444e+3,
|
||||
2.25381184209801510330112e+4,
|
||||
4.75584627752788110767815e+3,
|
||||
-1.34659959864969306392456e+5,
|
||||
-1.15132259675553483497211e+5
|
||||
};
|
||||
|
||||
// Coefficients for Hart's Minimax approximation x >= 12
|
||||
|
||||
|
||||
double c[7] = {
|
||||
-1.910444077728e-03,
|
||||
8.4171387781295e-04,
|
||||
-5.952379913043012e-04,
|
||||
7.93650793500350248e-04,
|
||||
-2.777777777777681622553e-03,
|
||||
8.333333333333333331554247e-02,
|
||||
5.7083835261e-03
|
||||
};
|
||||
|
||||
double y = x;
|
||||
int swi = 0;
|
||||
double fact = 1.0;
|
||||
int n = 0;
|
||||
|
||||
|
||||
if (y < 0.)
|
||||
{
|
||||
// Negative x
|
||||
y = -x;
|
||||
yi = fix(y);
|
||||
oup = y - yi;
|
||||
|
||||
if (oup != 0.0)
|
||||
{
|
||||
if (yi != fix(yi * .5) * 2.) { swi = 1; }
|
||||
fact = -pi / sin(pi * oup);
|
||||
y += 1.;
|
||||
}
|
||||
else { return xinf; }
|
||||
}
|
||||
|
||||
if (y < eps)
|
||||
{
|
||||
if (y >= xninf) { oup = 1.0 / y; }
|
||||
else { return xinf; }
|
||||
}
|
||||
else if (y < 12.)
|
||||
{
|
||||
yi = y;
|
||||
if (y < 1.)
|
||||
{
|
||||
z = y;
|
||||
y += 1.;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = (int)y - 1;
|
||||
y -= (double)n;
|
||||
z = y - 1.0;
|
||||
}
|
||||
double nsum = 0.;
|
||||
double dsum = 1.;
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
nsum = (nsum + num[i]) * z;
|
||||
dsum = dsum * z + den[i];
|
||||
}
|
||||
oup = nsum / dsum + 1.;
|
||||
|
||||
if (yi < y) { oup /= yi; }
|
||||
else if (yi > y)
|
||||
{
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
oup *= y;
|
||||
y += 1.;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y <= xmax)
|
||||
{
|
||||
const double y2 = y * y;
|
||||
double sum = c[6];
|
||||
for (i = 0; i < 6; ++i) { sum = sum / y2 + c[i]; }
|
||||
sum = sum / y - y + spi;
|
||||
sum += (y - .5) * log(y);
|
||||
oup = exp(sum);
|
||||
}
|
||||
else { return (xinf); }
|
||||
}
|
||||
|
||||
if (swi) { oup = -oup; }
|
||||
if (fact != 1.) { oup = fact / oup; }
|
||||
|
||||
return oup;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "wtmath.h"
|
||||
#include "hsfft.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void nsfft_exec(fft_object obj, fft_data* inp, fft_data* oup, double lb, double ub,
|
||||
double* w);// lb -lower bound, ub - upper bound, w - time or frequency grid (Size N)
|
||||
|
||||
double gamma(double x);
|
||||
|
||||
int nint(double N);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* hsfft.h
|
||||
*
|
||||
* Created on: Apr 14, 2013
|
||||
* Author: Rafat Hussain
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PI2 6.28318530717958647692528676655900577
|
||||
|
||||
#ifndef fft_type
|
||||
#define fft_type double
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct fft_t
|
||||
{
|
||||
fft_type re;
|
||||
fft_type im;
|
||||
} fft_data;
|
||||
/*
|
||||
#define SADD(a,b) ((a)+(b))
|
||||
|
||||
#define SSUB(a,b) ((a)+(b))
|
||||
|
||||
#define SMUL(a,b) ((a)*(b))
|
||||
*/
|
||||
|
||||
typedef struct fft_set* fft_object;
|
||||
|
||||
fft_object fft_init(int N, int sgn);
|
||||
|
||||
struct fft_set
|
||||
{
|
||||
int N;
|
||||
int sgn;
|
||||
int factors[64];
|
||||
int lf;
|
||||
int lt;
|
||||
fft_data twiddle[1];
|
||||
};
|
||||
|
||||
void fft_exec(fft_object obj, fft_data* inp, fft_data* oup);
|
||||
|
||||
int divideby(int M, int d);
|
||||
|
||||
int dividebyN(int N);
|
||||
|
||||
//void arrrev(int M, int* arr);
|
||||
|
||||
int factors(int M, int* arr);
|
||||
|
||||
void twiddle(fft_data* vec, int N, int radix);
|
||||
|
||||
void longvectorN(fft_data* sig, int N, int* array, int tx);
|
||||
|
||||
void free_fft(fft_object object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* real.c
|
||||
*
|
||||
* Created on: Apr 20, 2013
|
||||
* Author: Rafat Hussain
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "real.h"
|
||||
|
||||
fft_real_object fft_real_init(int N, int sgn)
|
||||
{
|
||||
fft_real_object obj = (fft_real_object)malloc(sizeof(struct fft_real_set) + sizeof(fft_data) * (N / 2));
|
||||
obj->cobj = fft_init(N / 2, sgn);
|
||||
|
||||
for (int k = 0; k < N / 2; ++k)
|
||||
{
|
||||
const fft_type theta = PI2 * k / N;
|
||||
obj->twiddle2[k].re = cos(theta);
|
||||
obj->twiddle2[k].im = sin(theta);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
void fft_r2c_exec(fft_real_object obj,fft_type* inp, fft_data* oup)
|
||||
{
|
||||
int i;
|
||||
const int N2 = obj->cobj->N;
|
||||
const int N = N2 * 2;
|
||||
|
||||
fft_data* cinp = (fft_data*)malloc(sizeof(fft_data) * N2);
|
||||
fft_data* coup = (fft_data*)malloc(sizeof(fft_data) * N2);
|
||||
|
||||
for (i = 0; i < N2; ++i)
|
||||
{
|
||||
cinp[i].re = inp[2 * i];
|
||||
cinp[i].im = inp[2 * i + 1];
|
||||
}
|
||||
|
||||
fft_exec(obj->cobj, cinp, coup);
|
||||
|
||||
oup[0].re = coup[0].re + coup[0].im;
|
||||
oup[0].im = 0.0;
|
||||
|
||||
for (i = 1; i < N2; ++i)
|
||||
{
|
||||
fft_type temp1 = coup[i].im + coup[N2 - i].im;
|
||||
fft_type temp2 = coup[N2 - i].re - coup[i].re;
|
||||
oup[i].re = (coup[i].re + coup[N2 - i].re + (temp1 * obj->twiddle2[i].re) + (temp2 * obj->twiddle2[i].im)) / 2.0;
|
||||
oup[i].im = (coup[i].im - coup[N2 - i].im + (temp2 * obj->twiddle2[i].re) - (temp1 * obj->twiddle2[i].im)) / 2.0;
|
||||
}
|
||||
|
||||
|
||||
oup[N2].re = coup[0].re - coup[0].im;
|
||||
oup[N2].im = 0.0;
|
||||
|
||||
for (i = 1; i < N2; ++i)
|
||||
{
|
||||
oup[N - i].re = oup[i].re;
|
||||
oup[N - i].im = -oup[i].im;
|
||||
}
|
||||
|
||||
|
||||
free(cinp);
|
||||
free(coup);
|
||||
}
|
||||
|
||||
void fft_c2r_exec(fft_real_object obj, fft_data* inp,fft_type* oup)
|
||||
{
|
||||
const int N2 = obj->cobj->N;
|
||||
|
||||
fft_data* cinp = (fft_data*)malloc(sizeof(fft_data) * N2);
|
||||
fft_data* coup = (fft_data*)malloc(sizeof(fft_data) * N2);
|
||||
|
||||
for (int i = 0; i < N2; ++i)
|
||||
{
|
||||
fft_type temp1 = -inp[i].im - inp[N2 - i].im;
|
||||
fft_type temp2 = -inp[N2 - i].re + inp[i].re;
|
||||
cinp[i].re = inp[i].re + inp[N2 - i].re + (temp1 * obj->twiddle2[i].re) - (temp2 * obj->twiddle2[i].im);
|
||||
cinp[i].im = inp[i].im - inp[N2 - i].im + (temp2 * obj->twiddle2[i].re) + (temp1 * obj->twiddle2[i].im);
|
||||
}
|
||||
|
||||
fft_exec(obj->cobj, cinp, coup);
|
||||
for (int i = 0; i < N2; ++i)
|
||||
{
|
||||
oup[2 * i] = coup[i].re;
|
||||
oup[2 * i + 1] = coup[i].im;
|
||||
}
|
||||
free(cinp);
|
||||
free(coup);
|
||||
}
|
||||
|
||||
void free_real_fft(fft_real_object object)
|
||||
{
|
||||
free_fft(object->cobj);
|
||||
free(object);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* real.h
|
||||
*
|
||||
* Created on: Apr 20, 2013
|
||||
* Author: Rafat Hussain
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "hsfft.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct fft_real_set* fft_real_object;
|
||||
|
||||
fft_real_object fft_real_init(int N, int sgn);
|
||||
|
||||
struct fft_real_set
|
||||
{
|
||||
fft_object cobj;
|
||||
fft_data twiddle2[1];
|
||||
};
|
||||
|
||||
void fft_r2c_exec(fft_real_object obj,fft_type* inp, fft_data* oup);
|
||||
|
||||
void fft_c2r_exec(fft_real_object obj, fft_data* inp,fft_type* oup);
|
||||
|
||||
void free_real_fft(fft_real_object object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
Copyright (c) 2014, Rafat Hussain
|
||||
Copyright (c) 2016, Holger Nahrstaedt
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include "conv.h"
|
||||
#define _USE_MATH_DEFINES
|
||||
#include "math.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
int filtlength(const char* name);
|
||||
|
||||
int filtcoef(const char* name, double* lp1, double* hp1, double* lp2, double* hp2);
|
||||
|
||||
void copy_reverse(const double* in, const int N, double* out);
|
||||
void qmf_even(const double* in, const int N, double* out);
|
||||
void qmf_wrev(const double* in, const int N, double* out);
|
||||
void copy(const double* in, const int N, double* out);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,219 @@
|
||||
#include "wavefunc.h"
|
||||
|
||||
void meyer(const int N, const double lb, const double ub, double* phi, double* psi, double* tgrid)
|
||||
{
|
||||
int i;
|
||||
double theta, x, x2, x3, x4, v, cs;
|
||||
|
||||
const int M = divideby(N, 2);
|
||||
|
||||
if (M == 0)
|
||||
{
|
||||
printf("Size of Wavelet must be a power of 2");
|
||||
exit(1);
|
||||
}
|
||||
if (lb >= ub)
|
||||
{
|
||||
printf("upper bound must be greater than lower bound");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
const fft_object obj = fft_init(N, -1);
|
||||
double* w = (double*)malloc(sizeof(double) * N);
|
||||
fft_data* phiw = (fft_data*)malloc(sizeof(fft_data) * N);
|
||||
fft_data* psiw = (fft_data*)malloc(sizeof(fft_data) * N);
|
||||
fft_data* oup = (fft_data*)malloc(sizeof(fft_data) * N);
|
||||
|
||||
const double delta = 2 * (ub - lb) / PI2;
|
||||
|
||||
double j = (double)N;
|
||||
j *= -1.0;
|
||||
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
w[i] = j / delta;
|
||||
j += 2.0;
|
||||
psiw[i].re = psiw[i].im = 0.0;
|
||||
phiw[i].re = phiw[i].im = 0.0;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
const double wf = fabs(w[i]);
|
||||
if (wf <= PI2 / 3.0) { phiw[i].re = 1.0; }
|
||||
if (wf > PI2 / 3.0 && wf <= 2 * PI2 / 3.0)
|
||||
{
|
||||
x = (3 * wf / PI2) - 1.0;
|
||||
x2 = x * x;
|
||||
x3 = x2 * x;
|
||||
x4 = x3 * x;
|
||||
v = x4 * (35 - 84 * x + 70 * x2 - 20 * x3);
|
||||
theta = v * PI2 / 4.0;
|
||||
cs = cos(theta);
|
||||
const double sn = sin(theta);
|
||||
|
||||
phiw[i].re = cs;
|
||||
psiw[i].re = cos(w[i] / 2.0) * sn;
|
||||
psiw[i].im = sin(w[i] / 2.0) * sn;
|
||||
}
|
||||
if (wf > 2.0 * PI2 / 3.0 && wf <= 4 * PI2 / 3.0)
|
||||
{
|
||||
x = (1.5 * wf / PI2) - 1.0;
|
||||
x2 = x * x;
|
||||
x3 = x2 * x;
|
||||
x4 = x3 * x;
|
||||
v = x4 * (35 - 84 * x + 70 * x2 - 20 * x3);
|
||||
theta = v * PI2 / 4.0;
|
||||
cs = cos(theta);
|
||||
|
||||
psiw[i].re = cos(w[i] / 2.0) * cs;
|
||||
psiw[i].im = sin(w[i] / 2.0) * cs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsfft_exec(obj, phiw, oup, lb, ub, tgrid);
|
||||
|
||||
|
||||
for (i = 0; i < N; ++i) { phi[i] = oup[i].re / N; }
|
||||
|
||||
nsfft_exec(obj, psiw, oup, lb, ub, tgrid);
|
||||
|
||||
|
||||
for (i = 0; i < N; ++i) { psi[i] = oup[i].re / N; }
|
||||
|
||||
|
||||
free(oup);
|
||||
free(phiw);
|
||||
free(psiw);
|
||||
free(w);
|
||||
}
|
||||
|
||||
void gauss(int N, int p, double lb, double ub, double* psi, double* t)
|
||||
{
|
||||
double num, t2, t4;
|
||||
int i;
|
||||
|
||||
if (lb >= ub)
|
||||
{
|
||||
printf("upper bound must be greater than lower bound");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
t[0] = lb;
|
||||
t[N - 1] = ub;
|
||||
const double delta = (ub - lb) / (N - 1);
|
||||
for (i = 1; i < N - 1; ++i) { t[i] = lb + delta * i; }
|
||||
|
||||
const double den = sqrt(gamma(p + 0.5));
|
||||
|
||||
if ((p + 1) % 2 == 0) { num = 1.0; }
|
||||
else { num = -1.0; }
|
||||
|
||||
num /= den;
|
||||
|
||||
//printf("\n%g\n",num);
|
||||
|
||||
if (p == 1) { for (i = 0; i < N; ++i) { psi[i] = -t[i] * exp(- t[i] * t[i] / 2.0) * num; } }
|
||||
else if (p == 2)
|
||||
{
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
t2 = t[i] * t[i];
|
||||
psi[i] = (-1.0 + t2) * exp(- t2 / 2.0) * num;
|
||||
}
|
||||
}
|
||||
else if (p == 3)
|
||||
{
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
t2 = t[i] * t[i];
|
||||
psi[i] = t[i] * (3.0 - t2) * exp(- t2 / 2.0) * num;
|
||||
}
|
||||
}
|
||||
else if (p == 4)
|
||||
{
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
t2 = t[i] * t[i];
|
||||
psi[i] = (t2 * t2 - 6.0 * t2 + 3.0) * exp(- t2 / 2.0) * num;
|
||||
}
|
||||
}
|
||||
else if (p == 5)
|
||||
{
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
t2 = t[i] * t[i];
|
||||
psi[i] = t[i] * (-t2 * t2 + 10.0 * t2 - 15.0) * exp(- t2 / 2.0) * num;
|
||||
}
|
||||
}
|
||||
else if (p == 6)
|
||||
{
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
t2 = t[i] * t[i];
|
||||
psi[i] = (t2 * t2 * t2 - 15.0 * t2 * t2 + 45.0 * t2 - 15.0) * exp(- t2 / 2.0) * num;
|
||||
}
|
||||
}
|
||||
else if (p == 7)
|
||||
{
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
t2 = t[i] * t[i];
|
||||
psi[i] = t[i] * (-t2 * t2 * t2 + 21.0 * t2 * t2 - 105.0 * t2 + 105.0) * exp(- t2 / 2.0) * num;
|
||||
}
|
||||
}
|
||||
else if (p == 8)
|
||||
{
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
t2 = t[i] * t[i];
|
||||
t4 = t2 * t2;
|
||||
psi[i] = (t4 * t4 - 28.0 * t4 * t2 + 210.0 * t4 - 420.0 * t2 + 105.0) * exp(- t2 / 2.0) * num;
|
||||
}
|
||||
}
|
||||
else if (p == 9)
|
||||
{
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
t2 = t[i] * t[i];
|
||||
t4 = t2 * t2;
|
||||
psi[i] = t[i] * (- t4 * t4 + 36.0 * t4 * t2 - 378.0 * t4 + 1260.0 * t2 - 945.0) * exp(- t2 / 2.0) * num;
|
||||
}
|
||||
}
|
||||
else if (p == 10)
|
||||
{
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
t2 = t[i] * t[i];
|
||||
t4 = t2 * t2;
|
||||
psi[i] = (t4 * t4 * t2 - 45.0 * t4 * t4 + 630.0 * t4 * t2 - 3150.0 * t4 + 4725.0 * t2 - 945.0) * exp(- t2 / 2.0) * num;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n The Gaussian Derivative Wavelet is only available for Derivatives 1 to 10");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void mexhat(int N, double lb, double ub, double* psi, double* t) { gauss(N, 2, lb, ub, psi, t); }
|
||||
|
||||
void morlet(int N, double lb, double ub, double* psi, double* t)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (lb >= ub)
|
||||
{
|
||||
printf("upper bound must be greater than lower bound");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
t[0] = lb;
|
||||
t[N - 1] = ub;
|
||||
const double delta = (ub - lb) / (N - 1);
|
||||
for (i = 1; i < N - 1; ++i) { t[i] = lb + delta * i; }
|
||||
|
||||
for (i = 0; i < N; ++i) { psi[i] = exp(- t[i] * t[i] / 2.0) * cos(5 * t[i]); }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "cwtmath.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void meyer(const int N, const double lb, const double ub, double* phi, double* psi, double* tgrid);
|
||||
void gauss(int N, int p, double lb, double ub, double* psi, double* t);
|
||||
void mexhat(int N, double lb, double ub, double* psi, double* t);
|
||||
void morlet(int N, double lb, double ub, double* psi, double* t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
Copyright (c) 2014, Rafat Hussain
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "wtmath.h"
|
||||
#include "cwt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable : 4200)
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
#ifndef cplx_type
|
||||
#define cplx_type double
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct cplx_t
|
||||
{
|
||||
cplx_type re;
|
||||
cplx_type im;
|
||||
} cplx_data;
|
||||
|
||||
typedef struct wave_set* wave_object;
|
||||
|
||||
wave_object wave_init(char* wname);
|
||||
|
||||
struct wave_set
|
||||
{
|
||||
char wname[50];
|
||||
int filtlength;// When all filters are of the same length. [Matlab uses zero-padding to make all filters of the same length]
|
||||
int lpd_len;// Default filtlength = lpd_len = lpr_len = hpd_len = hpr_len
|
||||
int hpd_len;
|
||||
int lpr_len;
|
||||
int hpr_len;
|
||||
double* lpd;
|
||||
double* hpd;
|
||||
double* lpr;
|
||||
double* hpr;
|
||||
double params[0];
|
||||
};
|
||||
|
||||
typedef struct wt_set* wt_object;
|
||||
|
||||
wt_object wt_init(wave_object wave, char* method, int siglength, int J);
|
||||
|
||||
struct wt_set
|
||||
{
|
||||
wave_object wave;
|
||||
conv_object cobj;
|
||||
char method[10];
|
||||
int siglength;// Length of the original signal.
|
||||
int outlength;// Length of the output DWT vector
|
||||
int lenlength;// Length of the Output Dimension Vector "length"
|
||||
int J; // Number of decomposition Levels
|
||||
int MaxIter;// Maximum Iterations J <= MaxIter
|
||||
int even;// even = 1 if signal is of even length. even = 0 otherwise
|
||||
char ext[10];// Type of Extension used - "per" or "sym"
|
||||
char cmethod[10]; // Convolution Method - "direct" or "FFT"
|
||||
|
||||
int N; //
|
||||
int cfftset;
|
||||
int zpad;
|
||||
int length[102];
|
||||
double* output;
|
||||
double params[0];
|
||||
};
|
||||
|
||||
typedef struct wtree_set* wtree_object;
|
||||
|
||||
wtree_object wtree_init(wave_object wave, int siglength, int J);
|
||||
|
||||
struct wtree_set
|
||||
{
|
||||
wave_object wave;
|
||||
conv_object cobj;
|
||||
char method[10];
|
||||
int siglength;// Length of the original signal.
|
||||
int outlength;// Length of the output DWT vector
|
||||
int lenlength;// Length of the Output Dimension Vector "length"
|
||||
int J; // Number of decomposition Levels
|
||||
int MaxIter;// Maximum Iterations J <= MaxIter
|
||||
int even;// even = 1 if signal is of even length. even = 0 otherwise
|
||||
char ext[10];// Type of Extension used - "per" or "sym"
|
||||
|
||||
int N; //
|
||||
int nodes;
|
||||
int cfftset;
|
||||
int zpad;
|
||||
int length[102];
|
||||
double* output;
|
||||
int* nodelength;
|
||||
int* coeflength;
|
||||
double params[0];
|
||||
};
|
||||
|
||||
typedef struct wpt_set* wpt_object;
|
||||
|
||||
wpt_object wpt_init(wave_object wave, int siglength, int J);
|
||||
|
||||
struct wpt_set
|
||||
{
|
||||
wave_object wave;
|
||||
conv_object cobj;
|
||||
int siglength;// Length of the original signal.
|
||||
int outlength;// Length of the output DWT vector
|
||||
int lenlength;// Length of the Output Dimension Vector "length"
|
||||
int J; // Number of decomposition Levels
|
||||
int MaxIter;// Maximum Iterations J <= MaxIter
|
||||
int even;// even = 1 if signal is of even length. even = 0 otherwise
|
||||
char ext[10];// Type of Extension used - "per" or "sym"
|
||||
char entropy[20];
|
||||
double eparam;
|
||||
|
||||
int N; //
|
||||
int nodes;
|
||||
int length[102];
|
||||
double* output;
|
||||
double* costvalues;
|
||||
double* basisvector;
|
||||
int* nodeindex;
|
||||
int* numnodeslevel;
|
||||
int* coeflength;
|
||||
double params[0];
|
||||
};
|
||||
|
||||
typedef struct cwt_set* cwt_object;
|
||||
|
||||
cwt_object cwt_init(char* wave, double param, int siglength, double dt, int J);
|
||||
|
||||
struct cwt_set
|
||||
{
|
||||
char wave[10];// Wavelet - morl/morlet,paul,dog/dgauss
|
||||
int siglength;// Length of Input Data
|
||||
int J;// Total Number of Scales
|
||||
double s0;// Smallest scale. It depends on the sampling rate. s0 <= 2 * dt for most wavelets
|
||||
double dt;// Sampling Rate
|
||||
double dj;// Separation between scales. eg., scale = s0 * 2 ^ ( [0:N-1] *dj ) or scale = s0 *[0:N-1] * dj
|
||||
char type[10];// Scale Type - Power or Linear
|
||||
int pow;// Base of Power in case type = pow. Typical value is pow = 2
|
||||
int sflag;
|
||||
int pflag;
|
||||
int npad;
|
||||
int mother;
|
||||
double m;// Wavelet parameter param
|
||||
double smean;// Input Signal mean
|
||||
|
||||
cplx_data* output;
|
||||
double* scale;
|
||||
double* period;
|
||||
double* coi;
|
||||
double params[0];
|
||||
};
|
||||
|
||||
|
||||
void dwt(wt_object wt, double* inp);
|
||||
void idwt(wt_object wt, double* dwtop);
|
||||
void wtree(wtree_object wt, double* inp);
|
||||
void dwpt(wpt_object wt, double* inp);
|
||||
void idwpt(wpt_object wt, double* dwtop);
|
||||
void swt(wt_object wt, double* inp);
|
||||
void iswt(wt_object wt, double* swtop);
|
||||
void modwt(wt_object wt, double* inp);
|
||||
void imodwt(wt_object wt, double* dwtop);
|
||||
void setDWTExtension(wt_object wt, char* extension);
|
||||
void setWTREEExtension(wtree_object wt, char* extension);
|
||||
void setDWPTExtension(wpt_object wt, char* extension);
|
||||
void setDWPTEntropy(wpt_object wt, char* entropy, double eparam);
|
||||
void setWTConv(wt_object wt, char* cmethod);
|
||||
int getWTREENodelength(wtree_object wt, int X);
|
||||
void getWTREECoeffs(wtree_object wt, int X, int Y, double* coeffs, int N);
|
||||
int getDWPTNodelength(wpt_object wt, int X);
|
||||
void getDWPTCoeffs(wpt_object wt, int X, int Y, double* coeffs, int N);
|
||||
int setCWTScales(cwt_object wt, double s0, double dj, char* type, int power);
|
||||
void setCWTScaleVector(cwt_object wt, double* scale, int J, double s0, double dj);
|
||||
void setCWTPadding(cwt_object wt, int pad);
|
||||
int cwt(cwt_object wt, double* inp);
|
||||
void icwt(cwt_object wt, double* cwtop);
|
||||
int getCWTScaleLength(int N);
|
||||
void wave_summary(wave_object obj);
|
||||
void wt_summary(wt_object wt);
|
||||
void wtree_summary(wtree_object wt);
|
||||
void wpt_summary(wpt_object wt);
|
||||
void cwt_summary(cwt_object wt);
|
||||
void wave_free(wave_object object);
|
||||
void wt_free(wt_object object);
|
||||
void wtree_free(wtree_object object);
|
||||
void wpt_free(wpt_object object);
|
||||
void cwt_free(cwt_object object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
Copyright (c) 2014, Rafat Hussain
|
||||
*/
|
||||
#include "wtmath.h"
|
||||
|
||||
int upsamp(double* x, int lenx, int M, double* y)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (M < 0) { return -1; }
|
||||
|
||||
if (M == 0)
|
||||
{
|
||||
for (i = 0; i < lenx; ++i) { y[i] = x[i]; }
|
||||
return lenx;
|
||||
}
|
||||
|
||||
const int N = M * (lenx - 1) + 1;
|
||||
int j = 1;
|
||||
int k = 0;
|
||||
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
j--;
|
||||
y[i] = 0.0;
|
||||
if (j == 0)
|
||||
{
|
||||
y[i] = x[k];
|
||||
k++;
|
||||
j = M;
|
||||
}
|
||||
}
|
||||
|
||||
return N;
|
||||
}
|
||||
|
||||
int upsamp2(double* x, int lenx, int M, double* y)
|
||||
{
|
||||
int i;
|
||||
// upsamp2 returns even numbered output. Last value is set to zero
|
||||
if (M < 0) { return -1; }
|
||||
|
||||
if (M == 0)
|
||||
{
|
||||
for (i = 0; i < lenx; ++i) { y[i] = x[i]; }
|
||||
return lenx;
|
||||
}
|
||||
|
||||
const int N = M * lenx;
|
||||
int j = 1;
|
||||
int k = 0;
|
||||
|
||||
for (i = 0; i < N; ++i)
|
||||
{
|
||||
j--;
|
||||
y[i] = 0.0;
|
||||
if (j == 0)
|
||||
{
|
||||
y[i] = x[k];
|
||||
k++;
|
||||
j = M;
|
||||
}
|
||||
}
|
||||
|
||||
return N;
|
||||
}
|
||||
|
||||
int downsamp(double* x, int lenx, int M, double* y)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (M < 0) { return -1; }
|
||||
if (M == 0)
|
||||
{
|
||||
for (i = 0; i < lenx; ++i) { y[i] = x[i]; }
|
||||
return lenx;
|
||||
}
|
||||
|
||||
const int N = (lenx - 1) / M + 1;
|
||||
|
||||
for (i = 0; i < N; ++i) { y[i] = x[i * M]; }
|
||||
|
||||
return N;
|
||||
}
|
||||
/*
|
||||
int per_ext(double *sig, int len, int a,double *oup) {
|
||||
int i,len2;
|
||||
// oup is of length len + (len%2) + 2 * a
|
||||
for (i = 0; i < len; ++i) {
|
||||
oup[a + i] = sig[i];
|
||||
}
|
||||
len2 = len;
|
||||
if ((len % 2) != 0) {
|
||||
len2 = len + 1;
|
||||
oup[a + len] = sig[len - 1];
|
||||
}
|
||||
for (i = 0; i < a; ++i) {
|
||||
oup[a-1-i] = sig[len - 1 - i];
|
||||
oup[len2 + a + i] = sig[i];
|
||||
}
|
||||
|
||||
return len2;
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
int per_ext(double* sig, int len, int a, double* oup)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; ++i) { oup[a + i] = sig[i]; }
|
||||
int len2 = len;
|
||||
if ((len % 2) != 0)
|
||||
{
|
||||
len2 = len + 1;
|
||||
oup[a + len] = sig[len - 1];
|
||||
}
|
||||
for (i = 0; i < a; ++i)
|
||||
{
|
||||
const double temp1 = oup[a + i];
|
||||
const double temp2 = oup[a + len2 - 1 - i];
|
||||
oup[a - 1 - i] = temp2;
|
||||
oup[len2 + a + i] = temp1;
|
||||
}
|
||||
return len2;
|
||||
}
|
||||
/*
|
||||
int symm_ext(double *sig, int len, int a, double *oup) {
|
||||
int i, len2;
|
||||
// oup is of length len + 2 * a
|
||||
for (i = 0; i < len; ++i) {
|
||||
oup[a + i] = sig[i];
|
||||
}
|
||||
len2 = len;
|
||||
for (i = 0; i < a; ++i) {
|
||||
oup[a - 1 - i] = sig[i];
|
||||
oup[len2 + a + i] = sig[len - 1 - i];
|
||||
}
|
||||
|
||||
return len2;
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
int symm_ext(double* sig, int len, int a, double* oup)
|
||||
{
|
||||
int i;
|
||||
// oup is of length len + 2 * a
|
||||
for (i = 0; i < len; ++i) { oup[a + i] = sig[i]; }
|
||||
const int len2 = len;
|
||||
for (i = 0; i < a; ++i)
|
||||
{
|
||||
const double temp1 = oup[a + i];
|
||||
const double temp2 = oup[a + len2 - 1 - i];
|
||||
oup[a - 1 - i] = temp1;
|
||||
oup[len2 + a + i] = temp2;
|
||||
}
|
||||
|
||||
return len2;
|
||||
}
|
||||
|
||||
static int isign(int N)
|
||||
{
|
||||
int M;
|
||||
if (N >= 0) { M = 1; }
|
||||
else { M = -1; }
|
||||
|
||||
return M;
|
||||
}
|
||||
|
||||
static int iabs(int N)
|
||||
{
|
||||
if (N >= 0) { return N; }
|
||||
return -N;
|
||||
}
|
||||
|
||||
void circshift(double* array, int N, int L)
|
||||
{
|
||||
int i;
|
||||
if (iabs(L) > N) { L = isign(L) * (iabs(L) % N); }
|
||||
if (L < 0) { L = (N + L) % N; }
|
||||
|
||||
double* temp = (double*)malloc(sizeof(double) * L);
|
||||
|
||||
for (i = 0; i < L; ++i) { temp[i] = array[i]; }
|
||||
|
||||
for (i = 0; i < N - L; ++i) { array[i] = array[i + L]; }
|
||||
|
||||
for (i = 0; i < L; ++i) { array[N - L + i] = temp[i]; }
|
||||
|
||||
free(temp);
|
||||
}
|
||||
|
||||
int testSWTlength(int N, int J)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
int div = 1;
|
||||
for (int i = 0; i < J; ++i) { div *= 2; }
|
||||
|
||||
if (N % div) { ret = 0; }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wmaxiter(int sig_len, int filt_len)
|
||||
{
|
||||
const double temp = log((double)sig_len / ((double)filt_len - 1.0)) / log(2.0);
|
||||
const int lev = (int)temp;
|
||||
|
||||
return lev;
|
||||
}
|
||||
|
||||
static double entropy_s(double* x, int N)
|
||||
{
|
||||
double val = 0.0;
|
||||
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
if (x[i] != 0)
|
||||
{
|
||||
const double x2 = x[i] * x[i];
|
||||
val -= x2 * log(x2);
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
static double entropy_t(double* x, int N, double t)
|
||||
{
|
||||
if (t < 0)
|
||||
{
|
||||
printf("Threshold value must be >= 0");
|
||||
exit(1);
|
||||
}
|
||||
double val = 0.0;
|
||||
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
const double x2 = fabs(x[i]);
|
||||
if (x2 > t) { val += 1; }
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static double entropy_n(double* x, int N, double p)
|
||||
{
|
||||
if (p < 1)
|
||||
{
|
||||
printf("Norm power value must be >= 1");
|
||||
exit(1);
|
||||
}
|
||||
double val = 0.0;
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
const double x2 = fabs(x[i]);
|
||||
val += pow(x2, p);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static double entropy_l(double* x, int N)
|
||||
{
|
||||
double val = 0.0;
|
||||
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
if (x[i] != 0)
|
||||
{
|
||||
const double x2 = x[i] * x[i];
|
||||
val += log(x2);
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
double costfunc(double* x, int N, char* entropy, double p)
|
||||
{
|
||||
double val;
|
||||
|
||||
if (!strcmp(entropy, "shannon")) { val = entropy_s(x, N); }
|
||||
else if (!strcmp(entropy, "threshold")) { val = entropy_t(x, N, p); }
|
||||
else if (!strcmp(entropy, "norm")) { val = entropy_n(x, N, p); }
|
||||
else if (!strcmp(entropy, "logenergy") || !strcmp(entropy, "log energy") || !strcmp(entropy, "energy")) { val = entropy_l(x, N); }
|
||||
else
|
||||
{
|
||||
printf("Entropy must be one of shannon, threshold, norm or energy");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
Copyright (c) 2014, Rafat Hussain
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "wavefilt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int upsamp(double* x, int lenx, int M, double* y);
|
||||
int upsamp2(double* x, int lenx, int M, double* y);
|
||||
int downsamp(double* x, int lenx, int M, double* y);
|
||||
int per_ext(double* sig, int len, int a, double* oup);
|
||||
int symm_ext(double* sig, int len, int a, double* oup);
|
||||
void circshift(double* array, int N, int L);
|
||||
int testSWTlength(int N, int J);
|
||||
int wmaxiter(int sig_len, int filt_len);
|
||||
double costfunc(double* x, int N, char* entropy, double p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user