All Downloads are FREE. Search and download functionalities are using the official Maven repository.

core.be.tarsos.dsp.wavelet.HaarWaveletTransform Maven / Gradle / Ivy

The newest version!
/*
*      _______                       _____   _____ _____  
*     |__   __|                     |  __ \ / ____|  __ \ 
*        | | __ _ _ __ ___  ___  ___| |  | | (___ | |__) |
*        | |/ _` | '__/ __|/ _ \/ __| |  | |\___ \|  ___/ 
*        | | (_| | |  \__ \ (_) \__ \ |__| |____) | |     
*        |_|\__,_|_|  |___/\___/|___/_____/|_____/|_|     
*                                                         
* -------------------------------------------------------------
*
* TarsosDSP is developed by Joren Six at IPEM, University Ghent
*  
* -------------------------------------------------------------
*
*  Info: http://0110.be/tag/TarsosDSP
*  Github: https://github.com/JorenSix/TarsosDSP
*  Releases: http://0110.be/releases/TarsosDSP/
*  
*  TarsosDSP includes modified source code by various authors,
*  for credits and info, see README.
* 
*/

package be.tarsos.dsp.wavelet;

public class HaarWaveletTransform {
		
	private final boolean preserveEnergy;
	private final float sqrtTwo = (float) Math.sqrt(2.0);
	
	public HaarWaveletTransform(boolean preserveEnergy){
		this.preserveEnergy = preserveEnergy;
	}
	
	public HaarWaveletTransform(){
		this(false);
	}
	
	/**
	 * Does an in-place HaarWavelet wavelet transform. The
	 * length of data needs to be a power of two.
	 * It is based on the algorithm found in "Wavelets Made Easy" by Yves Nivergelt, page 24.
	 * @param s The data to transform.
	 */
	public void transform(float[] s){
		int m = s.length;
		assert isPowerOfTwo(m);
		int n = log2(m);
		int j = 2;
		int i = 1;
		for(int l = 0 ; l < n ; l++ ){
			m = m/2;
			for(int k=0; k < m;k++){
				float a = (s[j*k]+s[j*k + i])/2.0f;
				float c = (s[j*k]-s[j*k + i])/2.0f;
				if(preserveEnergy){
					a = a/sqrtTwo;
					c = c/sqrtTwo;
				}
				s[j*k] = a;
				s[j*k+i] = c;
			}
			i = j;
			j = j * 2;
		}
	}
	
    /**
     * Does an in-place inverse HaarWavelet Wavelet Transform. The data needs to be a power of two.
     * It is based on the algorithm found in "Wavelets Made Easy" by Yves Nivergelt, page 29.
     * @param data The data to transform.
     */
    public void inverseTransform(float[] data){
    	int m = data.length;
		assert isPowerOfTwo(m);
		int n = log2(m);
		int i = pow2(n-1);
		int j = 2 * i;
		m = 1;
		for(int l = n ; l >= 1; l--){
			for(int k = 0; k < m ; k++){
				float a = data[j*k]+data[j*k+i];
				float a1 = data[j*k]-data[j*k+i];
				if(preserveEnergy){
					a = a*sqrtTwo;
					a1 = a1*sqrtTwo;
				}
				data[j*k] = a;
				data[j*k+i] = a1;
			}
			j = i;
			i = i /2;
			m = 2*m;
		}
	}
    
    
	   
	/**
	 * Checks if the number is a power of two. For performance it uses bit shift
	 * operators. e.g. 4 in binary format is
	 * "0000 0000 0000 0000 0000 0000 0000 0100"; and -4 is
	 * "1111 1111 1111 1111 1111 1111 1111 1100"; and 4&-4 will be
	 * "0000 0000 0000 0000 0000 0000 0000 0100";
	 * 
	 * @param number
	 *            The number to check.
	 * @return True if the number is a power of two, false otherwise.
	 */
	public static boolean isPowerOfTwo(int number) {
		if (number <= 0) {
			throw new IllegalArgumentException("number: " + number);
		}
		if ((number & -number) == number) {
			return true;
		}
		return false;
	}

	/**
	 * A quick and simple way to calculate log2 of integers.
	 * 
	 * @param bits
	 *            the integer
	 * @return log2(bits)
	 */
	public static int log2(int bits) {
		if (bits == 0) {
			return 0;
		}
		return 31 - Integer.numberOfLeadingZeros(bits);
	}
	
	/**
	 * A quick way to calculate the power of two (2^power), by using bit shifts.
	 * @param power The power.
	 * @return 2^power
	 */
	public static int pow2(int power) {
		return 1<




© 2015 - 2024 Weber Informatics LLC | Privacy Policy