/**
* JWave - Java implementation of wavelet transform algorithms
*
* Copyright 2010-2012 Christian Scheiblich
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file FastWaveletTransform.java is part of JWave.
*
* @author Christian Scheiblich
* date 23.02.2010 05:42:23
* contact graetz@mailfish.de
*/
package math.transform.jwave.handlers;
import math.transform.jwave.handlers.wavelets.Wavelet;
import math.transform.jwave.handlers.wavelets.WaveletInterface;
/**
* Base class for the forward and reverse Discret Wavelet Transform in 1-D, 2-D,
* and 3-D using a specified Wavelet by inheriting class.
*
* @date 23 juin 2011 15:55:33
* @author Pol Kennel
*/
public class DiscreteWaveletTransform extends WaveletTransform {
/**
* Constructor receiving a WaveletI object.
*
* @date 23 juin 2011 15:54:54
* @author Pol Kennel
* @param wavelet
*/
public DiscreteWaveletTransform(WaveletInterface wavelet ) {
super(wavelet);
}
/**
* Constructor receiving a WaveletI object and a iteration level for forward reverse methods
*
* @date 23 juin 2011 15:54:54
* @author Pol Kennel
* @param wavelet
*/
public DiscreteWaveletTransform(WaveletInterface wavelet, int iteration ) {
super(wavelet, iteration);
}
/**
* Performs the 1-D forward transform for arrays of dim N from time domain to
* Hilbert domain for the given array using the Discrete Wavelet Transform
* (DWT) algorithm (identical to the Fast Wavelet Transform (FWT) in 1-D).
*
* @date 24 juin 2011 13:16:00
* @author Pol Kennel
* @date 10.02.2010 08:23:24
* @author Christian Scheiblich
* @param arrTime
* coefficients of 1-D Time domain
* @see math.transform.jwave.handlers.BasicTransform#forward(double[])
*/
@Override
public double[ ] forwardWavelet( double[ ] arrTime ) {
double[ ] arrHilb = new double[ arrTime.length ];
for( int i = 0; i < arrTime.length; i++ )
arrHilb[ i ] = arrTime[ i ];
int level = 0;
int h = arrTime.length;
int minWaveLength = _wavelet.getWaveLength( );
if( h >= minWaveLength ) {
while( h >= minWaveLength ) {
double[ ] iBuf = new double[ h ];
for( int i = 0; i < h; i++ )
iBuf[ i ] = arrHilb[ i ];
double[ ] oBuf = _wavelet.forward( iBuf );
for( int i = 0; i < h; i++ )
arrHilb[ i ] = oBuf[ i ];
h = h >> 1;
level++;
} // levels
} // if
return arrHilb;
}
/**
* Performs the 1-D reverse transform for arrays of dim N from Hilbert domain
* to time domain for the given array using the Discrete Wavelet Transform
* (DWT) algorithm and the selected wavelet (identical to the Fast Wavelet
* Transform (FWT) in 1-D).
*
* @date 24 juin 2011 13:16:18
* @author Pol Kennel
* @date 10.02.2010 08:23:24
* @author Christian Scheiblich
* @param arrHilb
* coefficients of 1-D Hilbert domain
* @see math.transform.jwave.handlers.BasicTransform#reverse(double[])
*/
@Override
public double[ ] reverseWavelet( double[ ] arrHilb ) {
double[ ] arrTime = new double[ arrHilb.length ];
for( int i = 0; i < arrHilb.length; i++ )
arrTime[ i ] = arrHilb[ i ];
int level = 0;
int minWaveLength = _wavelet.getWaveLength( );
int h = minWaveLength;
if( arrHilb.length >= minWaveLength ) {
while( h <= arrTime.length && h >= minWaveLength ) {
double[ ] iBuf = new double[ h ];
for( int i = 0; i < h; i++ )
iBuf[ i ] = arrTime[ i ];
double[ ] oBuf = _wavelet.reverse( iBuf );
for( int i = 0; i < h; i++ )
arrTime[ i ] = oBuf[ i ];
h = h << 1;
level++;
} // levels
} // if
return arrTime;
} // reverse
/**
* Performs the 1-D forward transform for arrays of dim N from time domain to
* Hilbert domain for the given array using the Discrete Wavelet Transform
* (DWT) algorithm. The number of transformation levels applied is limited by
* threshold (identical to the Fast Wavelet Transform (FWT) in 1-D).
*
* @date 24 juin 2011 13:18:38
* @author Pol Kennel
* @date 15.07.2010 13:26:26
* @author Thomas Haider
* @date 15.08.2010 00:31:36
* @author Christian Scheiblich
* @param arrTime
* coefficients of 1-D Time domain
* @param toLevel
* iteration number
* @see math.transform.jwave.handlers.BasicTransform#forward(double[], int)
*/
@Override
public double[ ] forwardWavelet( double[ ] arrTime, int toLevel ) {
double[ ] arrHilb = new double[ arrTime.length ];
for( int i = 0; i < arrTime.length; i++ )
arrHilb[ i ] = arrTime[ i ];
int level = 0;
int h = arrTime.length;
int minWaveLength = _wavelet.getWaveLength( );
if( h >= minWaveLength ) {
while( h >= minWaveLength && level < toLevel ) {
double[ ] iBuf = new double[ h ];
for( int i = 0; i < h; i++ )
iBuf[ i ] = arrHilb[ i ];
double[ ] oBuf = _wavelet.forward( iBuf );
for( int i = 0; i < h; i++ )
arrHilb[ i ] = oBuf[ i ];
h = h >> 1;
level++;
} // levels
} // if
return arrHilb;
}
/**
* Performs the 1-D reverse transform for arrays of dim N from Hilbert domain
* to time domain for the given array using the Discrete Wavelet Transform
* (DWT) algorithm and the selected wavelet (identical to the Fast Wavelet
* Transform (FWT) in 1-D). The number of transformation levels applied is
* limited by threshold.
*
* @author Pol Kennel
* @date 24 juin 2011 13:43:05
* @author Thomas Haider
* @date 15.08.2010 00:31:09
* @author Christian Scheiblich
* @date 20.06.2011 13:03:27
* @param arrHilb
* coefficients of 1-D Hilbert domain
* @param fromLevel
* iteration number
* @see math.transform.jwave.handlers.BasicTransform#reverse(double[], int)
*/
@Override
public double[ ] reverseWavelet( double[ ] arrHilb, int fromLevel ) {
double[ ] arrTime = new double[ arrHilb.length ];
for( int i = 0; i < arrHilb.length; i++ )
arrTime[ i ] = arrHilb[ i ];
int level = 0;
int minWaveLength = _wavelet.getWaveLength( );
// int h = minWaveLength; // bug ... 20110620
int h = (int)( arrHilb.length / ( Math.pow( 2, fromLevel - 1 ) ) ); // added by Pol
if( arrHilb.length >= minWaveLength ) {
while( h <= arrTime.length && h >= minWaveLength && level < fromLevel ) {
double[ ] iBuf = new double[ h ];
for( int i = 0; i < h; i++ )
iBuf[ i ] = arrTime[ i ];
double[ ] oBuf = _wavelet.reverse( iBuf );
for( int i = 0; i < h; i++ )
arrTime[ i ] = oBuf[ i ];
h = h << 1;
level++;
} // levels
} // if
return arrTime;
}
/**
* Performs the 2-D forward transform from time domain to frequency or Hilbert
* domain for a given array using the Discrete Wavelet Transform (DWT). It
* corresponds to the non standard decomposition (alternates between
* operations on rows and columns, in opposition of the standard
* decomposition).
*
* @date 24 juin 2011 13:44:51
* @author Pol Kennel
* @param matTime
* coefficients of 2-D time domain
* @see math.transform.jwave.handlers.DiscreteWaveletTransform#forward(double[][])
*/
public double[ ][ ] forwardWavelet( double[ ][ ] matTime ) {
System.out.println("use bad one!");
try {
throw new Exception( "dfd");
} catch( Exception e ) {
// TODO pol should implement this try n catch
e.printStackTrace();
}
int noOfRows = matTime.length;
int noOfCols = matTime[ 0 ].length;
double[ ][ ] matHilb = new double[ noOfRows ][ noOfCols ];
for( int i = 0; i < matHilb[ 0 ].length; i++ )
for( int j = 0; j < matHilb.length; j++ )
matHilb[ i ][ j ] = matTime[ i ][ j ];
int h = Math.min( noOfRows, noOfCols );
int minWaveLength = _wavelet.getWaveLength( );
if( h >= minWaveLength ) {
while( h >= minWaveLength ) { // dimension limit
for( int i = 0; i < h; i++ ) { // rows processing
double[ ] arrTime = new double[ h ];
for( int j = 0; j < h; j++ )
arrTime[ j ] = matHilb[ i ][ j ];
double[ ] arrHilb = _wavelet.forward( arrTime );
for( int j = 0; j < h; j++ )
matHilb[ i ][ j ] = arrHilb[ j ];
}
for( int j = 0; j < h; j++ ) { // columns processing
double[ ] arrTime = new double[ h ];
for( int i = 0; i < h; i++ )
arrTime[ i ] = matHilb[ i ][ j ];
double[ ] arrHilb = _wavelet.forward( arrTime );
for( int i = 0; i < h; i++ )
matHilb[ i ][ j ] = arrHilb[ i ];
}
h = h >> 1;
}
}
return matHilb;
}
/**
* Performs the 2-D reverse transform from frequency or Hilbert or time domain
* to time domain for a given array using the Discrete Wavelet Transform
* (DWT). It corresponds to the non standard decomposition (alternates between
* operations on rows and columns, in opposition of the standard
* decomposition).
*
* @date 24 juin 2011 13:51:05
* @author Pol Kennel
* @param matHilb
* coefficients of 2-D Hilbert domain
* @see math.transform.jwave.handlers.DiscreteWaveletTransform#reverse(double[][])
*/
public double[ ][ ] reverseWavelet( double[ ][ ] matHilb ) {
int noOfRows = matHilb.length;
int noOfCols = matHilb[ 0 ].length;
double[ ][ ] matTime = new double[ noOfRows ][ noOfCols ];
for( int i = 0; i < matHilb[ 0 ].length; i++ )
for( int j = 0; j < matHilb.length; j++ )
matTime[ i ][ j ] = matHilb[ i ][ j ];
int dim = Math.min( noOfRows, noOfCols );
int minWaveLength = _wavelet.getWaveLength( );
int h = minWaveLength;
if( h >= minWaveLength ) {
while( h <= dim && h >= minWaveLength ) { // dimension limit
for( int i = 0; i < h; i++ ) { // rows processing
double[ ] arrHilb = new double[ h ];
for( int j = 0; j < h; j++ )
arrHilb[ j ] = matTime[ i ][ j ];
double[ ] arrTime = _wavelet.reverse( arrHilb );
for( int j = 0; j < h; j++ )
matTime[ i ][ j ] = arrTime[ j ];
}
for( int j = 0; j < h; j++ ) { // columns processing
double[ ] arrHilb = new double[ h ];
for( int i = 0; i < h; i++ )
arrHilb[ i ] = matTime[ i ][ j ];
double[ ] arrTime = _wavelet.reverse( arrHilb );
for( int i = 0; i < h; i++ )
matTime[ i ][ j ] = arrTime[ i ];
}
h = h << 1;
}
}
return matTime;
}
/**
* Performs the 2-D forward transform from time domain to frequency or Hilbert
* domain for a given array using the Discrete Wavelet Transform (DWT). It
* corresponds to the non standard decomposition (alternates between
* operations on rows and columns, in opposition of the standard
* decomposition). The number of transformation levels applied is limited by
* threshold.
*
* @date 24 juin 2011 13:44:51
* @author Pol Kennel
* @param matTime
* coefficients of 2-D time domain
* @param toLevel
* iteration number
* @see math.transform.jwave.handlers.DiscreteWaveletTransform#forward(double[][])
*/
@Override
public double[ ][ ] forwardWavelet( double[ ][ ] matTime, int toLevel ) {
System.out.println("use good one!");
int noOfRows = matTime.length;
int noOfCols = matTime[ 0 ].length;
double[ ][ ] matHilb = new double[ noOfRows ][ noOfCols ];
for( int i = 0; i < matHilb[ 0 ].length; i++ )
for( int j = 0; j < matHilb.length; j++ )
matHilb[ i ][ j ] = matTime[ i ][ j ];
int level = 0;
int h = Math.min( noOfRows, noOfCols );
int minWaveLength = _wavelet.getWaveLength( );
if( h >= minWaveLength ) {
while( h >= minWaveLength && level < toLevel) { // levels
for( int i = 0; i < h; i++ ) { // rows processing
double[ ] arrTime = new double[ h ];
for( int j = 0; j < h; j++ )
arrTime[ j ] = matHilb[ i ][ j ];
double[ ] arrHilb = _wavelet.forward( arrTime );
for( int j = 0; j < h; j++ )
matHilb[ i ][ j ] = arrHilb[ j ];
}
for( int j = 0; j < h; j++ ) { // columns processing
double[ ] arrTime = new double[ h ];
for( int i = 0; i < h; i++ )
arrTime[ i ] = matHilb[ i ][ j ];
double[ ] arrHilb = _wavelet.forward( arrTime );
for( int i = 0; i < h; i++ )
matHilb[ i ][ j ] = arrHilb[ i ];
}
h = h >> 1;
level++;
}
}
return matHilb;
}
/**
* Performs the 2-D reverse transform from frequency or Hilbert or time domain
* to time domain for a given array using the Discrete Wavelet Transform
* (DWT). It corresponds to the non standard decomposition (alternates between
* operations on rows and columns, in opposition of the standard
* decomposition). The number of transformation levels applied is limited by
* threshold.
*
* @date 24 juin 2011 13:51:05
* @author Pol Kennel
* @param matHilb
* coefficients of 2-D Hilbert domain
* @param fromLevel
* iteration number
* @see math.transform.jwave.handlers.DiscreteWaveletTransform#reverse(double[][])
*/
@Override
public double[ ][ ] reverseWavelet( double[ ][ ] matHilb, int fromLevel ) {
int noOfRows = matHilb.length;
int noOfCols = matHilb[ 0 ].length;
double[ ][ ] matTime = new double[ noOfRows ][ noOfCols ];
for( int i = 0; i < matHilb[ 0 ].length; i++ )
for( int j = 0; j < matHilb.length; j++ )
matTime[ i ][ j ] = matHilb[ i ][ j ];
int level = 0;
int dim = Math.min( noOfRows, noOfCols );
int minWaveLength = _wavelet.getWaveLength( );
int h = (int)( dim / Math.pow( 2, fromLevel - 1 ) );
if( h >= minWaveLength ) {
while( h <= dim && h >= minWaveLength && level < fromLevel) { // levels
for( int i = 0; i < h; i++ ) { // rows processing
double[ ] arrHilb = new double[ h ];
for( int j = 0; j < h; j++ )
arrHilb[ j ] = matTime[ i ][ j ];
double[ ] arrTime = _wavelet.reverse( arrHilb );
for( int j = 0; j < h; j++ )
matTime[ i ][ j ] = arrTime[ j ];
}
for( int j = 0; j < h; j++ ) { // columns processing
double[ ] arrHilb = new double[ h ];
for( int i = 0; i < h; i++ )
arrHilb[ i ] = matTime[ i ][ j ];
double[ ] arrTime = _wavelet.reverse( arrHilb );
for( int i = 0; i < h; i++ )
matTime[ i ][ j ] = arrTime[ i ];
}
h = h << 1;
level++;
}
}
return matTime;
}
/**
*
* TODO pol explainMeShortly
*
* @date 24 juin 2011 14:04:00
* @author pol
* @see math.transform.jwave.handlers.BasicTransform#forward(double[][][])
*/
public double[ ][ ][ ] forwardWavelet( double[ ][ ][ ] spcTime ) {
// TODO
return spcTime;
}
/**
*
* TODO pol explainMeShortly
*
* @date 24 juin 2011 14:04:18
* @author pol
* @see math.transform.jwave.handlers.BasicTransform#reverse(double[][][])
*/
public double[ ][ ][ ] reverseWavelet( double[ ][ ][ ] spcHilb ) {
// TODO
return spcHilb;
}
}