/*-------------------------------------------------------
* Package: Wavelet Analysis Tool
* File name: wgauss.cc
*-------------------------------------------------------
*/
//_______________________________________________________
// WaveletG is a class for a continious wavelet
// transform that uses the family of Gaussian wavelets.
//
#ifndef _STREAM_H
#include <stream.h>
#define _STREAM_H
#endif
/* minimum scale value */
#define ZERO 1e-5
/* minimum value of unused relative square */
#define ZEROUNUSED 1e-10
#include "wgauss.h"
#include "gsbmp.h"
#include <stddef.h>
#include <math.h>
double gauss (double x)
{
return exp (- x * x / 2);
}
/* Gaussian wavelet g1 (x) */
double g1wavelet (double x)
{
return - x * exp (- x * x / 2);
}
/* Gaussian wavelet g2 (x) */
double g2wavelet (double x)
{
double xsqr = x * x;
return (1 - xsqr) * exp (- xsqr / 2);
}
/* Gaussian wavelet g3 (x) */
double g3wavelet (double x)
{
double xsqr = x * x;
return (3 - xsqr) * x * exp (- xsqr / 2);
}
/* Gaussian wavelet g4 (x) */
double g4wavelet (double x)
{
double xsqr = x * x;
return ((6 - xsqr) * xsqr - 3) * exp (- xsqr / 2);
}
/* Gaussian wavelet g5 (x) */
double g5wavelet (double x)
{
double xsqr = x * x;
return ((10 - xsqr) * xsqr - 15) * x * exp (- xsqr / 2);
}
/* Gaussian wavelet g6 (x) */
double g6wavelet (double x)
{
double xsqr = x * x;
return (((15 - xsqr) * xsqr - 45) * xsqr + 15) * exp (- xsqr /2);
}
WaveletG::WaveletG(int ngw)
{
// Constructor. Create wavelet with ngw vanishing moment.
pWDC = new WSeries(1);
pWDC->N =1;
switch (ngw)
{
case 1: wavenum = wg1; _TrFunc = g1waveletFast; break;
case 2: wavenum = wg2; _TrFunc = g2waveletFast; break;
case 3: wavenum = wg3; _TrFunc = g3waveletFast; break;
case 4: wavenum = wg4; _TrFunc = g4waveletFast; break;
case 5: wavenum = wg5; _TrFunc = g5waveletFast; break;
case 6: wavenum = wg6; _TrFunc = g6waveletFast; break;
default: wavenum = wg2; _TrFunc = g2waveletFast; break;
}
/* Initial values of information tables */
histTrInfo.Left=0; // left margin
histTrInfo.Right=0; // right margin
histTrInfo.Delta=0; // step == (Right - Left) / Bins
histTrInfo.Bins=0; // number of samples
histTrInfo.Points=0; // == Bins + 1
shiftTrInfo.Left=0; // left margin
shiftTrInfo.Right=0; // right margin
shiftTrInfo.Delta=0; // step == (Right - Left) / Bins
shiftTrInfo.Bins=0; // number of samples
shiftTrInfo.Points=0; // == Bins + 1
scaleTrInfo.Left=0; // left margin
scaleTrInfo.Right=0; // right margin
scaleTrInfo.Delta=0; // step == (Right - Left) / Bins
scaleTrInfo.Bins=0; // number of samples
scaleTrInfo.Points=0; // == Bins + 1
/* Initial value of auxiliary table */
_TrTable.Min=0; // minimum value of index
_TrTable.Max=0; // maximum number of index
_TrTable.Size=0; // range of it
_TrTable.Rate=0; // how many shift steps per sample
_TrTable.Hist=NULL; // source data samples
_TrTable.Wave=NULL; // table of wavelet values
/* Used relative square of the wavelet */
RelSquare = 0.95;
/* Half-width of transformation window */
halfwindow = 1;
scaleN=0;
scale0=scale1=0.;
}
WaveletG::~WaveletG()
{
// Dectructor.
//
delete pWDC;
}
/* Clears information table */
TR_INFO& WaveletG::clearTrInfo (TR_INFO& ti)
{
// Clears information table.
//
ti.Left = 0;
ti.Right = 0;
ti.Delta = 0;
ti.Bins = 0;
ti.Points = 0;
return ti;
}
/* Creates information table for the histogram of samples */
TR_INFO& WaveletG::buildHistTrInfo()
{
// Creates information table for the histogram of samples.
//
if (!histTrInfo.Bins) histTrInfo.Bins = histTrInfo.Points - 1;
else histTrInfo.Points = histTrInfo.Bins + 1;
histTrInfo.Delta = (histTrInfo.Right - histTrInfo.Left) / histTrInfo.Bins;
return histTrInfo;
}
/* Builds the table for shift selecting */
TR_INFO& WaveletG::buildShiftTrInfo()
{
// Builds the table for shift selecting.
//
if (!shiftTrInfo.Bins) shiftTrInfo.Bins = shiftTrInfo.Points - 1;
else shiftTrInfo.Points = shiftTrInfo.Bins + 1;
shiftTrInfo.Right = shiftTrInfo.Left + shiftTrInfo.Delta * shiftTrInfo.Bins;
return shiftTrInfo;
}
/* Native algorithm. Computes single wavelet coefficient. */
wavereal WaveletG::nativeTr (wavereal shift, wavereal scale)
{
// "Native" algorithm. Computes single wavelet coefficient.
//
/* return value */
wavereal ret = 0;
/* current point */
wavereal x = histTrInfo.Left;
/* step */
wavereal width = histTrInfo.Delta;
/* for all data samples */
for (unsigned int bin = 0; bin < histTrInfo.Bins; bin++, x += width)
ret += (_TrHist[bin] * (_TrFunc ((x - shift) / scale) -
_TrFunc ((x + width - shift) / scale)));
return scale * ret;
}
/* Conventional algorithm. Computes single wavelet coefficient. */
wavereal WaveletG::convTr (wavereal shift, wavereal scale)
{
// Conventional algorithm. Computes single wavelet coefficient.
//
wavereal beta = (histTrInfo.Left - shift) / scale;
/* Return value. */
/* The first and the last samples are involved. */
wavereal ret = _TrHist [0] * _TrFunc (beta) -
_TrHist [histTrInfo.Bins - 1] *
_TrFunc ((histTrInfo.Right - shift) / scale);
wavereal delta = histTrInfo.Delta / scale;
/* starting point */
wavereal x = beta + delta;
/* for all other cells of the histogram */
for (unsigned int bin = 0; bin < histTrInfo.Bins - 1; bin++, x += delta)
{
ret += (_TrHist [bin + 1] - _TrHist [bin]) * _TrFunc (x);
}
return scale * ret;
}
/* Fast algorithm. Computes single wavelet coefficient. */
wavereal WaveletG::fastTr (int shiftj, wavereal scale)
{
// Fast algorithm. Computes single wavelet coefficient.
//
/* return value */
wavereal ret = 0;
/* starting point in the auxiliary table */
int index = -shiftj - _TrTable.Min;
/* compute the convolution */
for (unsigned int c = 0; c < histTrInfo.Points; c++, index += _TrTable.Rate)
ret += _TrTable.Hist[c] * _TrTable.Wave[index];
return scale * ret;
}
/* Ultra method. Computes single wavelet coefficient. */
wavereal WaveletG::ultrafastTr (int shiftj, wavereal scale)
{
// Ultra method. Computes single wavelet coefficient.
//
/* return value */
wavereal ret = 0;
/* first index in the table of values of the wavelet */
int k = (int)(bxdelta + shiftj / _TrTable.Rate);
/* selecting boundaries according to window width */
int binmin = k - halfwindow;
int binmax = k + halfwindow;
if (binmin < 0) binmin = 0;
if (binmax > (int)histTrInfo.Points) binmax = histTrInfo.Points;
int index = binmin * _TrTable.Rate - shiftj - _TrTable.Min;
/* evaluating the convolution */
for (int c = binmin; c < binmax; c++, index += _TrTable.Rate)
ret += _TrTable.Hist[c] * _TrTable.Wave[index];
return scale * ret;
}
/* Native algorithm for evaluating the line in wavelet spectrum. */
void WaveletG::nativeTr (wavereal* result, wavereal scale)
{
// Native algorithm. Computes a line in wavelet spectrum.
//
/* initial value of shift */
wavereal shift = shiftTrInfo.Left;
/* computing single coefficients at all shifts */
for (unsigned int point = 0; point < shiftTrInfo.Points;
point++, shift += shiftTrInfo.Delta)
result[point] = nativeTr (shift, scale);
}
/* Conventional algorithm for evaluating the line in wavelet spectrum. */
void WaveletG::convTr (wavereal* result, wavereal scale)
{
// Conventional algorithm. Computes a line in wavelet spectrum.
//
/* starting (minimum) shift */
wavereal shift = shiftTrInfo.Left;
/* run over all shifts */
for (unsigned int point = 0; point < shiftTrInfo.Points;
point++, shift += shiftTrInfo.Delta)
result[point] = convTr (shift, scale);
}
/* Fast algorithm for evaluating the line in wavelet spectrum. */
void WaveletG::fastTr (wavereal* result, wavereal scale)
{
// Fast algorithm. Computes a the line in wavelet spectrum.
//
/* just go through all points in the array */
for (unsigned int point = 0; point < shiftTrInfo.Points; point++)
result[point] = fastTr (point, scale);
}
/* Ultra algorithm for evaluating the line in wavelet spectrum. */
void WaveletG::ultrafastTr (wavereal* result, wavereal scale)
{
// Ultra algorithm for evaluating the line in wavelet spectrum.
//
/* run over all shifts */
for (unsigned int point = 0; point < shiftTrInfo.Points; point++)
result[point] = ultrafastTr (point, scale);
}
/* Builds the transformation tables for given parameters */
int WaveletG::buildTrTableFast (wavereal scale, wavereal rate)
{
// Builds the transformation tables for given parameters.
//
_TrTable.Rate = (int)rate;
/* filling the table of differences */
_TrTable.Hist = new wavereal[histTrInfo.Points];
if (!_TrTable.Hist) return 0;
_TrTable.Hist[0] = _TrHist[0];
_TrTable.Hist[histTrInfo.Bins] = -_TrHist[histTrInfo.Bins - 1];
for (unsigned bin = 1; bin < histTrInfo.Bins; bin++)
_TrTable.Hist[bin] = _TrHist[bin] - _TrHist[bin - 1];
_TrTable.Min = -shiftTrInfo.Bins;
_TrTable.Max = (int)(histTrInfo.Bins * rate);
_TrTable.Size = _TrTable.Max - _TrTable.Min + 1;
_TrTable.Wave = new wavereal [_TrTable.Size];
if (!_TrTable.Wave)
{
delete _TrTable.Hist;
return 0;
}
wavereal coef = shiftTrInfo.Delta / scale;
wavereal add = (histTrInfo.Left - shiftTrInfo.Left) / scale;
/* creating the table of values of the wavelet */
int id = _TrTable.Min;
//cout<<"id="<<id<<endl;
for (int index = 0; index < (int)_TrTable.Size; index++)
{
wavereal x = coef * (index + id) + add;
_TrTable.Wave[index] = _TrFunc (x);
}
return 1;
}
void WaveletG::t2w(WaveData &t, int _scaleN, wavereal _scale0, wavereal _scale1, int method, int norm, wavereal unused)
{
// Time domain to Wavelet domain transform.
// Given parameters t - data for transformation.
// scale - Width of analizing wavelet.
// method - should be 0,1,2,or 3.
// 0 - Ultra method,
// 1 - Fast method,
// 2 - Conventional method,
// 3 - Native method.
// norm - should be equal 1, if normalization is needed.
// unused - for Ultra method. Shows what relative square of wavelet you don't want to use.
//
scaleN=_scaleN;
scale0=_scale0;
scale1=_scale1;
if(method<0 || method>3) method=0;
if (unused < ZEROUNUSED) unused = ZEROUNUSED;
if (unused > 1) unused = 1.0 - ZEROUNUSED;
RelSquare = 1 - unused;
int size=t.N;
setTrHist (t.data);
wavereal rate=1.;
wavereal shiftmin=0.;
histTrInfo.Left = 0;
histTrInfo.Right = size;
histTrInfo.Bins = size;
buildHistTrInfo();
shiftTrInfo.Left = shiftmin;
shiftTrInfo.Delta = histTrInfo.Delta / rate;
shiftTrInfo.Points = (int) (size * rate);
buildShiftTrInfo();
int wpoints=(int)(shiftTrInfo.Points)*scaleN;
if(pWDC->N!=wpoints) pWDC->Resize(wpoints);
wavereal *wdata;
wavereal scale;
for(int iscale=0;iscale<scaleN;iscale++)
{
wdata=pWDC->data+shiftTrInfo.Points*iscale;
scale=scale0+iscale*(scale1-scale0)/scaleN;
/* Select which method to use */
if (method == 3)
{
/* Native */
/* the transformation itself */
nativeTr(wdata, scale);
}
if (method == 2)
{
/* Conventional */
/* transform */
convTr(wdata, scale);
}
if (method == 1)
{
/* Fast */
/* build auxilary tables */
buildTrTableFast (scale, rate);
/* transform */
fastTr (wdata, scale);
destroyTrTable();
}
if (method == 0)
{
/* Ultra */
buildTrTableFast (scale, rate);
/* select window width according to given unused relative square */
bxdelta = (shiftTrInfo.Left - histTrInfo.Left) / histTrInfo.Delta;
wavereal halfv = scale * sqrt (-2 * log (1 - RelSquare));
halfwindow = (int) ((wavereal) ((wavereal) halfv / histTrInfo.Delta) + 1.0);
/* transform */
ultrafastTr (wdata, scale);
destroyTrTable();
}
/* normalize if necessary */
if (norm)
{
wavereal wavecoef=g2coefsq;
switch (wavenum)
{
case wg1: wavecoef = g1coefsq; break;
case wg2: wavecoef = g2coefsq; break;
case wg3: wavecoef = g3coefsq; break;
case wg4: wavecoef = g4coefsq; break;
case wg5: wavecoef = g5coefsq; break;
case wg6: wavecoef = g6coefsq; break;
case wempty: break;
}
wavereal ncoef = 1.0 / (wavecoef * sqrt (fabs (scale)));
for (unsigned int c = 0; c < shiftTrInfo.Points; c++)
wdata[c]*=ncoef;
}
}
}
void WaveletG::DumpWTAsBitmap(const char* fn,int palette)
{
if(scaleN==0){ cout<<"DumpWTAsBitmap(const char*,int=0) warning: Nothing to do.n"; return; }
unsigned char *bits=new unsigned char[pWDC->N];
wavereal mx,mn;
mx=mn=pWDC->data[0];
for(long i=1;i<pWDC->N;i++)
{
if(pWDC->data[i]<mn)mn=pWDC->data[i];
if(pWDC->data[i]>mx)mx=pWDC->data[i];
}
mx=255./(mx-mn);
for(long i=0;i<pWDC->N;i++)bits[i]=(unsigned char)(mx*(pWDC->data[i]-mn));
gs_bm_write(fn,bits,shiftTrInfo.Points,scaleN,palette);
delete bits;
}
#ifdef _USE_ROOT
ClassImp(WaveletG)
#endif
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.