Merge pull request #2 from holgern/master

Commit : Holgern branch. Missing Coefficients added
This commit is contained in:
Rafat Hussain 2016-03-08 06:32:33 +05:30
commit 1c0644364a
12 changed files with 84350 additions and 3036 deletions

View File

@ -1,4 +1,5 @@
Copyright (c) 2014, Rafat Hussain
Copyright (c) 2016, Holger Nahrstaedt
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

View File

@ -5,6 +5,11 @@
extern "C" {
#endif
#if defined(_MSC_VER)
#pragma warning(disable : 4200)
#pragma warning(disable : 4996)
#endif
#ifndef fft_type
#define fft_type double
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,28 @@
/*
Copyright (c) 2014, Rafat Hussain
Copyright (c) 2016, Holger Nahrstaedt
*/
#ifndef WAVEFILT_H_
#define WAVEFILT_H_
#include <stdio.h>
#include "conv.h"
#define _USE_MATH_DEFINES
#include "math.h"
#ifdef __cplusplus
extern "C" {
#endif
int filtlength(char* name);
int filtcoef(char* name, double *lp1, double *hp1, double *lp2, double *hp2);
int filtlength(const char* name);
int filtcoef(const char* name, double *lp1, double *hp1, double *lp2, double *hp2);
void copy_reverse(const double *in, int N, double *out);
void qmf_even(const double *in, int N, double *out);
void qmf_wrev(const double *in, int N, double *out);
void copy(const double *in, int N, double *out);
#ifdef __cplusplus
}
#endif

View File

@ -15,7 +15,7 @@ wave_object wave_init(char* wname) {
//strcopy(obj->wname, wname);
}
obj = (wave_object)malloc(sizeof(struct wave_set) + sizeof(double)* 4 * retval);
obj = (wave_object)malloc(sizeof(struct wave_set) + sizeof(double) * 4 * retval);
obj->filtlength = retval;
obj->lpd_len = obj->hpd_len = obj->lpr_len = obj->hpr_len = obj->filtlength;
@ -49,12 +49,12 @@ wt_object wt_init(wave_object wave,char* method, int siglength,int J) {
}
if (method == NULL) {
obj = (wt_object)malloc(sizeof(struct wt_set) + sizeof(double)* (siglength + 2 * J * (size+1)));
obj = (wt_object)malloc(sizeof(struct wt_set) + sizeof(double)* (siglength + 2 * J * (size + 1)));
obj->outlength = siglength + 2 * J * (size + 1); // Default
strcpy(obj->ext, "sym"); // Default
}
else if (!strcmp(method, "dwt") || !strcmp(method, "DWT")) {
obj = (wt_object)malloc(sizeof(struct wt_set) + sizeof(double)* (siglength + 2 * J * (size + 1)));
obj = (wt_object)malloc(sizeof(struct wt_set) + sizeof(double)* (siglength + 2 * J * (size + 1)));
obj->outlength = siglength + 2 * J * (size + 1); // Default
strcpy(obj->ext, "sym"); // Default
}
@ -64,7 +64,7 @@ wt_object wt_init(wave_object wave,char* method, int siglength,int J) {
exit(-1);
}
obj = (wt_object)malloc(sizeof(struct wt_set) + sizeof(double)* (siglength * (J + 1)));
obj = (wt_object)malloc(sizeof(struct wt_set) + sizeof(double)* (siglength * (J + 1)));
obj->outlength = siglength * (J + 1); // Default
strcpy(obj->ext, "per"); // Default
}
@ -79,7 +79,7 @@ wt_object wt_init(wave_object wave,char* method, int siglength,int J) {
}
}
obj = (wt_object)malloc(sizeof(struct wt_set) + sizeof(double)* (siglength * (J + 1)));
obj = (wt_object)malloc(sizeof(struct wt_set) + sizeof(double)* (siglength * (J + 1)));
obj->outlength = siglength * (J + 1); // Default
strcpy(obj->ext, "per"); // Default
}
@ -145,7 +145,7 @@ wtree_object wtree_init(wave_object wave, int siglength,int J) {
elength += temp2;
}
obj = (wtree_object)malloc(sizeof(struct wtree_set) + sizeof(double)* (siglength * (J + 1) + elength + nodes + J + 1));
obj = (wtree_object)malloc(sizeof(struct wtree_set) + sizeof(double)* (siglength * (J + 1) + elength + nodes + J + 1));
obj->outlength = siglength * (J + 1) + elength;
strcpy(obj->ext, "sym");
@ -218,7 +218,7 @@ wpt_object wpt_init(wave_object wave, int siglength, int J) {
}
//printf("elength %d", elength);
obj = (wpt_object)malloc(sizeof(struct wpt_set) + sizeof(double)* (elength + 4 * nodes + 2 * J + 6));
obj = (wpt_object)malloc(sizeof(struct wpt_set) + sizeof(double)* (elength + 4 * nodes + 2 * J + 6));
obj->outlength = siglength + 2 * (J + 1) * (size + 1);
strcpy(obj->ext, "sym");
strcpy(obj->entropy, "shannon");

View File

@ -1,3 +1,6 @@
/*
Copyright (c) 2014, Rafat Hussain
*/
#ifndef WAVELIB_H_
#define WAVELIB_H_
@ -7,6 +10,11 @@
extern "C" {
#endif
#if defined(_MSC_VER)
#pragma warning(disable : 4200)
#pragma warning(disable : 4996)
#endif
typedef struct wave_set* wave_object;
wave_object wave_init(char* wname);
@ -22,7 +30,7 @@ struct wave_set{
double *hpd;
double *lpr;
double *hpr;
double params[0];
double params[0];
};
typedef struct wt_set* wt_object;
@ -47,7 +55,7 @@ struct wt_set{
int zpad;
int length[102];
double *output;
double params[0];
double params[0];
};
typedef struct wtree_set* wtree_object;
@ -74,7 +82,7 @@ struct wtree_set{
double *output;
int *nodelength;
int *coeflength;
double params[0];
double params[0];
};
typedef struct wpt_set* wpt_object;
@ -103,7 +111,7 @@ struct wpt_set{
int *nodeindex;
int *numnodeslevel;
int *coeflength;
double params[0];
double params[0];
};

View File

@ -1,3 +1,6 @@
/*
Copyright (c) 2014, Rafat Hussain
*/
#include "wtmath.h"
int upsamp(double *x, int lenx, int M, double *y) {

View File

@ -1,3 +1,6 @@
/*
Copyright (c) 2014, Rafat Hussain
*/
#ifndef WTMATH_H_
#define WTMATH_H_

79926
test/s1.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
#define BOOST_TEST_MODULE WaveLibTests
#include <boost/test/included/unit_test.hpp>

View File

@ -0,0 +1,10 @@
#ifndef SWALLOWING_BOOSTTEST_H_
#define SWALLOWING_BOOSTTEST_H_
// we use the header only version of boost unit test
#define BOOST_TEST_NO_LIB
#include <boost/test/unit_test.hpp>
#endif // SWALLOWING_BOOSTTEST_H_

View File

@ -0,0 +1,370 @@
/*
* Copyright (c) 2016 Holger Nahrstaedt (TU Berlin)
*/
#include "BoostTest.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "../../src/wavelib.h"
#include<vector>
double absmax(double *array, int N) {
double max;
int i;
max = 0.0;
for (i = 0; i < N; ++i) {
if (fabs(array[i]) >= max) {
max = fabs(array[i]);
}
}
return max;
}
double sum1(double *array, int N) {
double sum;
int i;
sum = 0.0;
for (i = 0; i < N; ++i) {
sum += array[i];
}
return sum;
}
double sum2(double *array, int N) {
double sum;
int i;
sum = 0.0;
for (i = 0; i < N; i+=2) {
sum += array[i];
}
return sum;
}
double sum3(double *array, int N) {
double sum;
int i;
sum = 0.0;
for (i = 1; i < N; i += 2) {
sum += array[i];
}
return sum;
}
//np.sum(w[2*m:(2*N+2*m)]*w[0:2*N])
double sum4(double *array, int N) {
double sum;
int i;
sum = 0.0;
for (i = 0; i < N; i += 1) {
sum += array[i] * array[i];
}
return sum;
}
//np.sum(w[2 * m:(2 * N)] * w[0:2 * N - 2 * m])
double sum5(double *array, int N,int m) {
double sum;
int i;
sum = 0.0;
for (i = 2*m; i < N; i += 1) {
sum += array[i] * array[i-2*m];
}
return sum;
}
double RMS_Error(double *data, double *rec, int N) {
int i;
double sum = 0;
for (i = 0; i < N; ++i) {
sum += (data[i] - rec[i])*(data[i] - rec[i]);
}
return sqrt(sum/((double)N-1));
}
BOOST_AUTO_TEST_SUITE(DWTTests)
BOOST_AUTO_TEST_CASE(ReconstructionTest)
{
wave_object obj;
wt_object wt;
double *inp,*out,*diff;
int N, i,J;
double epsilon = 1e-15;
FILE *ifp;
double temp[79926];
ifp = fopen("s1.txt", "r");
//ifp = fopen("signal.txt", "r");
i = 0;
BOOST_REQUIRE(ifp);
while (!feof(ifp)) {
fscanf(ifp, "%lf \n", &temp[i]);
i++;
}
N = 79926;
//N = 256;
inp = (double*)malloc(sizeof(double)* N);
out = (double*)malloc(sizeof(double)* N);
//wmean = mean(temp, N);
for (i = 0; i < N; ++i) {
inp[i] = temp[i];
}
std::vector<std::string > waveletNames;
for (unsigned int j = 0; j < 36; j++)
{
waveletNames.push_back(std::string("db") + std::to_string(j + 1));
}
for (unsigned int j = 0; j < 17; j++)
{
waveletNames.push_back(std::string("coif") + std::to_string(j + 1));
}
for (unsigned int j = 1; j < 20; j++)
{
waveletNames.push_back(std::string("sym") + std::to_string(j + 1));
}
waveletNames.push_back("bior1.1");
waveletNames.push_back("bior1.3");
waveletNames.push_back("bior1.5");
waveletNames.push_back("bior2.2");
waveletNames.push_back("bior2.4");
waveletNames.push_back("bior2.6");
waveletNames.push_back("bior2.8");
waveletNames.push_back("bior3.1");
waveletNames.push_back("bior3.3");
waveletNames.push_back("bior3.5");
waveletNames.push_back("bior3.7");
waveletNames.push_back("bior3.9");
waveletNames.push_back("bior4.4");
waveletNames.push_back("bior5.5");
waveletNames.push_back("bior6.8");
waveletNames.push_back("rbior1.1");
waveletNames.push_back("rbior1.3");
waveletNames.push_back("rbior1.5");
waveletNames.push_back("rbior2.2");
waveletNames.push_back("rbior2.4");
waveletNames.push_back("rbior2.6");
waveletNames.push_back("rbior2.8");
waveletNames.push_back("rbior3.1");
waveletNames.push_back("rbior3.3");
waveletNames.push_back("rbior3.5");
waveletNames.push_back("rbior3.7");
waveletNames.push_back("rbior3.9");
waveletNames.push_back("rbior4.4");
waveletNames.push_back("rbior5.5");
waveletNames.push_back("rbior6.8");
for (unsigned int direct_fft = 0; direct_fft < 2; direct_fft++)
{
for (unsigned int sym_per = 0; sym_per < 2; sym_per++)
{
for (unsigned int j = 0; j < waveletNames.size(); j++)
{
char * name = new char[waveletNames[j].size() + 1];
memcpy(name, waveletNames[j].c_str(), waveletNames[j].size() + 1);
obj = wave_init(name);// Initialize the wavelet
for (J = 1; J < 2; J++)
{
//J = 3;
wt = wt_init(obj, "dwt", N, J);// Initialize the wavelet transform object
if (sym_per == 0)
setDWTExtension(wt, "sym");// Options are "per" and "sym". Symmetric is the default option
else
setDWTExtension(wt, "per");
if (direct_fft == 0)
setWTConv(wt, "direct");
else
setWTConv(wt, "fft");
dwt(wt, inp);// Perform DWT
idwt(wt, out);// Perform IDWT (if needed)
// Test Reconstruction
if (direct_fft == 0)
epsilon = 1e-8;
else
epsilon = 1e-10;
BOOST_CHECK_SMALL(RMS_Error(out, inp, wt->siglength), epsilon); // If Reconstruction succeeded then the output should be a small value.
wt_free(wt);
}
wave_free(obj);
}
}
}
free(out);
free(inp);
}
BOOST_AUTO_TEST_CASE(DBCoefTests)
{
wave_object obj;
double epsilon = 1e-15;
std::vector<std::string > waveletNames;
waveletNames.resize(38);
for (unsigned int i = 0; i < waveletNames.size();i++)
{
waveletNames[i] = std::string("db") + std::to_string(i+1);
}
for (unsigned int j = 0; j < waveletNames.size(); j++)
{
char * name = new char[waveletNames[j].size() + 1];
memcpy(name, waveletNames[j].c_str(), waveletNames[j].size() + 1);
obj = wave_init(name);// Initialize the wavelet
BOOST_CHECK_SMALL(sum1(obj->lpr, obj->lpr_len) - std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum2(obj->lpr, obj->lpr_len) - 1. / std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum3(obj->lpr, obj->lpr_len) - 1. / std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum4(obj->lpr, obj->lpr_len) - 1., epsilon);
for (int m = 1; m < (obj->lpr_len / 2) - 1;m++)
BOOST_CHECK_SMALL(sum5(obj->lpr, obj->lpr_len, m), epsilon);
wave_free(obj);
}
}
BOOST_AUTO_TEST_CASE(CoifCoefTests)
{
wave_object obj;
double epsilon = 1e-15;
std::vector<std::string > waveletNames;
waveletNames.resize(17);
for (unsigned int i = 0; i < waveletNames.size(); i++)
{
waveletNames[i] = std::string("coif") + std::to_string(i + 1);
}
for (unsigned int j = 0; j < waveletNames.size(); j++)
{
char * name = new char[waveletNames[j].size() + 1];
memcpy(name, waveletNames[j].c_str(), waveletNames[j].size() + 1);
obj = wave_init(name);// Initialize the wavelet
BOOST_CHECK_SMALL(sum1(obj->lpr, obj->lpr_len) - std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum2(obj->lpr, obj->lpr_len) - 1. / std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum3(obj->lpr, obj->lpr_len) - 1. / std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum4(obj->lpr, obj->lpr_len) - 1., epsilon);
for (int m = 1; m < (obj->lpr_len / 2) - 1; m++)
BOOST_CHECK_SMALL(sum5(obj->lpr, obj->lpr_len, m), epsilon);
wave_free(obj);
}
}
BOOST_AUTO_TEST_CASE(SymCoefTests)
{
wave_object obj;
double epsilon = 1e-10;
std::vector<std::string > waveletNames;
for (unsigned int i = 1; i < 20; i++)
{
waveletNames.push_back(std::string("sym") + std::to_string(i + 1));
}
for (unsigned int j = 0; j < waveletNames.size(); j++)
{
char * name = new char[waveletNames[j].size() + 1];
memcpy(name, waveletNames[j].c_str(), waveletNames[j].size() + 1);
obj = wave_init(name);// Initialize the wavelet
BOOST_CHECK_SMALL(sum1(obj->lpr, obj->lpr_len) - std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum2(obj->lpr, obj->lpr_len) - 1. / std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum3(obj->lpr, obj->lpr_len) - 1. / std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum4(obj->lpr, obj->lpr_len) - 1., epsilon);
for (int m = 1; m < (obj->lpr_len / 2) - 1; m++)
BOOST_CHECK_SMALL(sum5(obj->lpr, obj->lpr_len, m), epsilon);
wave_free(obj);
}
}
BOOST_AUTO_TEST_CASE(BiorCoefTests)
{
wave_object obj;
double epsilon = 1e-10;
std::vector<std::string > waveletNames;
waveletNames.push_back("bior1.1");
waveletNames.push_back("bior1.3");
waveletNames.push_back("bior1.5");
waveletNames.push_back("bior2.2");
waveletNames.push_back("bior2.4");
waveletNames.push_back("bior2.6");
waveletNames.push_back("bior2.8");
waveletNames.push_back("bior3.1");
waveletNames.push_back("bior3.3");
waveletNames.push_back("bior3.5");
waveletNames.push_back("bior3.7");
waveletNames.push_back("bior3.9");
waveletNames.push_back("bior4.4");
waveletNames.push_back("bior5.5");
waveletNames.push_back("bior6.8");
for (unsigned int j = 0; j < waveletNames.size(); j++)
{
char * name = new char[waveletNames[j].size() + 1];
memcpy(name, waveletNames[j].c_str(), waveletNames[j].size() + 1);
obj = wave_init(name);// Initialize the wavelet
BOOST_CHECK_SMALL(sum1(obj->lpr, obj->lpr_len) - std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum1(obj->lpd, obj->lpd_len) - std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum2(obj->lpr, obj->lpr_len) - 1. / std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum2(obj->lpd, obj->lpd_len) - 1. / std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum3(obj->lpr, obj->lpr_len) - 1. / std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum3(obj->lpd, obj->lpd_len) - 1. / std::sqrt(2.0), epsilon);
wave_free(obj);
}
}
BOOST_AUTO_TEST_CASE(RBiorCoefTests)
{
wave_object obj;
double epsilon = 1e-10;
std::vector<std::string > waveletNames;
waveletNames.push_back("rbior1.1");
waveletNames.push_back("rbior1.3");
waveletNames.push_back("rbior1.5");
waveletNames.push_back("rbior2.2");
waveletNames.push_back("rbior2.4");
waveletNames.push_back("rbior2.6");
waveletNames.push_back("rbior2.8");
waveletNames.push_back("rbior3.1");
waveletNames.push_back("rbior3.3");
waveletNames.push_back("rbior3.5");
waveletNames.push_back("rbior3.7");
waveletNames.push_back("rbior3.9");
waveletNames.push_back("rbior4.4");
waveletNames.push_back("rbior5.5");
waveletNames.push_back("rbior6.8");
for (unsigned int j = 0; j < waveletNames.size(); j++)
{
char * name = new char[waveletNames[j].size() + 1];
memcpy(name, waveletNames[j].c_str(), waveletNames[j].size() + 1);
obj = wave_init(name);// Initialize the wavelet
BOOST_CHECK_SMALL(sum1(obj->lpr, obj->lpr_len) - std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum1(obj->lpd, obj->lpd_len) - std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum2(obj->lpr, obj->lpr_len) - 1. / std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum2(obj->lpd, obj->lpd_len) - 1. / std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum3(obj->lpr, obj->lpr_len) - 1. / std::sqrt(2.0), epsilon);
BOOST_CHECK_SMALL(sum3(obj->lpd, obj->lpd_len) - 1. / std::sqrt(2.0), epsilon);
wave_free(obj);
}
}
BOOST_AUTO_TEST_SUITE_END()