TurboWavelets.Net
Compact C# Implementation for very fast and flexible wavelet transformations
TurboWavelets/Biorthogonal53Wavelet1DStatic.cs
00001 // 
00002 // Biorthogonal53Wavelet1DStatic.cs
00003 //  
00004 // Author:
00005 //       Stefan Moebius
00006 // Date:
00007 //       2016-04-09
00008 // 
00009 // Copyright (c) 2016 Stefan Moebius
00010 // 
00011 // Permission is hereby granted, free of charge, to any person obtaining a copy
00012 // of this software and associated documentation files (the "Software"), to deal
00013 // in the Software without restriction, including without limitation the rights
00014 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00015 // copies of the Software, and to permit persons to whom the Software is
00016 // furnished to do so, subject to the following conditions:
00017 // 
00018 // The above copyright notice and this permission notice shall be included in
00019 // all copies or substantial portions of the Software.
00020 // 
00021 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00022 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00023 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00024 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00025 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00026 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00027 // THE SOFTWARE.
00028 
00029 using System;
00030 
00031 namespace TurboWavelets
00032 {
00033     public class Biorthogonal53Wavelet1DStatic
00034     {
00043         public static void wavelet53_1d (float[] src, float[] dst, int length)
00044         {
00045             if (length >= 3) {
00046                 int half = length >> 1;
00047                 //if the length is even then subtract 1 from "half"
00048                 //as there is the same number of low and high frequency values
00049                 //(Note that "num_lf_values" is equal to "half+1") 
00050                 //For a odd length there is one additional low frequency value (so do not subtract 1)
00051                 //"half" is one less than "num_lf_values" as we cannot directly
00052                 //calculate the last value in the for-loop (array bounds)
00053                 if ((length & 1) == 0)
00054                     half--;
00055                 int offsrc = 0;
00056                 // starting offset for high frequency values (= number of low frequency values)
00057                 int offdst = half + 1; 
00058                 int num_lf_values = offdst;
00059 
00060                 float last_hf = 0.0f;
00061                 for (int i = 0; i < half; i++) {
00062                     //calculate the high frequency value by
00063                     //subtracting the mean of the immediate neighbors for every second value
00064                     float hf = src [offsrc + 1] - (src [offsrc] + src [offsrc + 2]) * 0.5f;
00065                     //smoothing the low frequency value, scale by factor 2 
00066                     //(instead of scaling low frequencies by factor sqrt(2) and
00067                     //shrinking high frequencies by factor sqrt(2)
00068                     //and reposition to have all low frequencies on the left side
00069                     dst [i] = 2.0f * (src [offsrc] + (last_hf + hf) * 0.25f);
00070                     dst [offdst++] = hf;
00071                     last_hf = hf;
00072                     offsrc += 2; 
00073                 } 
00074                 if ((length & 1) == 0) {
00075                     //the secound last value in the array is our last low frequency value
00076                     dst [num_lf_values - 1] = src [length - 2]; 
00077                     //the last value is a high frequency value
00078                     //however here we just subtract the previos value (so not really a
00079                     //biorthogonal 5/3 transformation)
00080                     //This is done because the 5/3 wavelet cannot be calculated at the boundary
00081                     dst [length - 1] = src [length - 1] - src [length - 2];
00082                 } else {
00083                     dst [num_lf_values - 1] = src [length - 1]; 
00084                 }
00085             } else {
00086                 //We cannot perform the biorthogonal 5/3 wavelet transformation
00087                 //for lengths smaller than 3. We could do a simpler transformation...
00088                 //Here however, we just copy the values from the source to the destination array  
00089                 for (int i = 0; i < length; i++)
00090                     dst [i] = src [i];
00091             }
00092         }
00093 
00102         public static void wavelet53_1d_inverse (float[] src, float[] dst, int length)
00103         {
00104             if (length >= 3) {
00105                 int half = length >> 1;
00106                 //if the length is even then subtract 1 from "half"
00107                 //as there is the same number of low and high frequency values
00108                 //(Note that "num_lf_values" is equal to "half+1") 
00109                 //For a odd length there is one additional low frequency value (so do not subtract 1)
00110                 //"half" is one less than "num_lf_values" as we cannot directly
00111                 //calculate the last value in the for-loop (array bounds)
00112                 if ((length & 1) == 0)
00113                     half--;
00114                 // number of low frequency values
00115                 int num_lf_values = half + 1;
00116 
00117                 float last_lf = 0.5f * src [0] - src [num_lf_values] * 0.25f;
00118                 float last_hf = src [num_lf_values];
00119                 //Calculate the first two values outside the for loop (array bounds)
00120                 dst [0] = last_lf;
00121                 dst [1] = last_hf + last_lf * 0.5f;
00122                 for (int i = 1; i < half; i++) {
00123                     float hf = src [num_lf_values + i];
00124                     float lf = 0.5f * src [i];
00125                     //reconstruct the original value by removing the "smoothing" 
00126                     float lf_reconst = lf - (hf + last_hf) * 0.25f;
00127                     dst [2 * i] = lf_reconst;
00128                     //add reconstructed low frequency value (left side) and high frequency value
00129                     dst [2 * i + 1] = lf_reconst * 0.5f + hf;
00130                     //add other low frequency value (right side)
00131                     //This must be done one iteration later, as the
00132                     //reconstructed values is not known earlier
00133                     dst [2 * i - 1] += lf_reconst * 0.5f;
00134                     last_hf = hf;
00135                     last_lf = lf_reconst;
00136                 }
00137 
00138                 if ((length & 1) == 0) {
00139                     //restore the last 3 values outside the for loop
00140                     //adding the missing low frequency value (right side)
00141                     dst [length - 3] += src [num_lf_values - 1] * 0.5f;
00142                     //copy the last low frequency value
00143                     dst [length - 2] = src [num_lf_values - 1];
00144                     //restore the last value by adding last low frequency value
00145                     dst [length - 1] = src [length - 1] + src [num_lf_values - 1]; 
00146                 } else {
00147                     //restore the last 2 values outside the for loop
00148                     //adding the missing low frequency value (right side)
00149                     dst [length - 2] += src [num_lf_values - 1] * 0.5f;
00150                     //copy the last low frequency value
00151                     dst [length - 1] = src [num_lf_values - 1];
00152                 }
00153             } else {
00154                 //We cannot perform the biorthogonal 5/3 wavelet transformation
00155                 //for lengths smaller than 3. We could do a simpler transformation...
00156                 //Here however, we just copy the values from the source to the destination array  
00157                 for (int i = 0; i < length; i++)
00158                     dst [i] = src [i];              
00159             }
00160         }
00161     }
00162 }
00163 
 All Classes Namespaces Functions Variables Properties