public WaveletD4Transform(int dataDim) { dim = HaarTransform.RoundDimension(dataDim); InitializeConstants(); D4 = WaveTransforms.App.ScriptApp.New.NumberTable(dim, dim); // Algorithm adapated from: http://www.bearcave.com/misl/misl_tech/wavelets/daubechies/daub.java for (int row = 0; row < dim; row++) { double[] v = (D4.Matrix as double[][])[row]; Array.Clear(v, 0, v.Length); v[row] = 1.0; for (int n = v.Length; n >= 4; n >>= 1) { TransformD4(v, n); } } int interval = dim / 16; for (int k = 0; k < dim; k++) { D4.RowSpecList[k].Type = D4.ColumnSpecList[k].Group = (short)(k / interval); } List <int> rows = new List <int>(); for (int row = 0; row < dataDim; row++) { rows.Add(row); } D4 = D4.SelectRows(rows); }
public HaarTransform(int dataDim) { dim = RoundDimension(dataDim); haar = WaveTransforms.App.ScriptApp.New.NumberTable(dim, dim); // Algorithm adapated from: http://www.cs.ucf.edu/~mali/haar/. double sqrt2 = 1 / Math.Sqrt(2.0); double[] vp = new double[dim]; for (int row = 0; row < dim; row++) { double[] v = (haar.Matrix as double[][])[row]; Array.Clear(v, 0, v.Length); v[row] = 1.0; Array.Clear(vp, 0, vp.Length); int w = dim; while (w > 1) { w /= 2; for (int i = 0; i < w; i++) { vp[i] = (v[2 * i] + v[2 * i + 1]) * sqrt2; vp[i + w] = (v[2 * i] - v[2 * i + 1]) * sqrt2; } Array.Copy(vp, v, 2 * w); } } int interval = dim / 16; for (int k = 0; k < dim; k++) { haar.RowSpecList[k].Type = haar.ColumnSpecList[k].Group = (short)(k / interval); } List <int> rows = new List <int>(); for (int row = 0; row < dataDim; row++) { rows.Add(row); } haar = haar.SelectRows(rows); }
public INumberTable Filter(INumberTable inTable, double lowFreq, double highFreq) { INumberTable freqTable = Transform(inTable); // // Since the frequency vectors are half vector (the other half are mirred and not stored) // we need to duplicate the vector except the first and, in case n is even, the n/2 th element. // Notice that the Fourier matrixes have the same mirred structure. // for (int row = 0; row < freqTable.Rows; row++) { for (int col = 0; col < freqTable.Columns; col++) { int c = col % tDim; // c is the index within the repeat interval. if (c == 0) { continue; } if ((tDim % 2 == 0) && (c == tDim / 2)) { // In case tDim is even, the n/2-th element is at the centre of the symmetry // and must not be duplciated. continue; } freqTable.Matrix[row][col] *= 2; } } // Calculate the filter indexes to pick up bases vectors // with frequency (stored as column group)falling between give range. int lFreq = (int)(lowFreq * (tDim / 2 + 1)); int hFreq = (int)(highFreq * (tDim / 2 + 1)); List <int> filterReal = new List <int>(); List <int> filterImg = new List <int>(); List <int> filterFreq = new List <int>(); IList <IColumnSpec> mrSpecList = matrixReal.ColumnSpecList; foreach (int idx in selectReal) { int freq = mrSpecList[idx].Group; if ((lFreq <= freq) && (freq <= hFreq)) { filterReal.Add(idx); filterFreq.Add(idx); } } IList <IColumnSpec> miSpecList = matrixImg.ColumnSpecList; foreach (int idx in selectImg) { int freq = miSpecList[idx].Group; if ((lFreq <= freq) && (freq <= hFreq)) { filterImg.Add(idx); filterFreq.Add(tDim / 2 + idx); } } int repeats = freqTable.Columns / tDim; if (repeats > 1) { // the transformation has been repeated. We need to add the repeated coefficient here. for (int r = 1; r < repeats; r++) { for (int n = 0; n < tDim; n++) { filterFreq.Add(r * tDim + filterFreq[n]); } } } freqTable = freqTable.SelectColumns(filterFreq); INumberTable revMatrix = matrixReal.SelectRows(filterReal).Append(matrixImg.SelectRows(filterImg)); INumberTable outTable = MatrixProduct(freqTable, revMatrix); IList <IColumnSpec> oSpecList = outTable.ColumnSpecList; IList <IColumnSpec> iSpecList = inTable.ColumnSpecList; for (int col = 0; col < outTable.Columns; col++) { if (col < inTable.Columns) { oSpecList[col].CopyFrom(iSpecList[col]); } } return(outTable); }
public WalshTransform(int dataDim) { dim = HaarTransform.RoundDimension(dataDim); walsh = WaveTransforms.App.ScriptApp.New.NumberTable(dim, dim); // // The Walsh matrix differs from Hadamard in ordering of the base vectors: // the former uses the sequency order (bit-reversal or Gray code permutation) // while the latter uses nature order resulted // from recursive calculation. // // The following code is adapted from http://www.musicdsp.org/showone.php?id=18. int log2 = Log2(dim); for (int row = 0; row < dim; row++) { double[] v = (walsh.Matrix as double[][])[row]; v[row] = 1.0; for (int i = 0; i < log2; i++) { int i2 = (1 << i); for (int j = 0; j < (1 << log2); j += 2 * i2) { for (int k = 0; k < i2; k++) { int jk = j + k; double a = v[jk] + v[jk + i2]; v[jk + i2] = v[jk] - v[jk + i2]; v[jk] = a; } } } } // // perform the bit-reserve and gray code re-ordering. // int[] order = new int[dim]; int[] grayCode = GrayOrder(log2); for (int i = 0; i < dim; i++) { order[i] = ReverseOrder(log2, grayCode[i]); } // Permutate the rows. double[][] newM = new double[dim][]; double[][] M = walsh.Matrix as double[][]; for (int row = 0; row < dim; row++) { newM[row] = M[order[row]]; } for (int row = 0; row < dim; row++) { M[row] = newM[row]; } int interval = dim / 16; for (int k = 0; k < dim; k++) { walsh.RowSpecList[k].Type = walsh.ColumnSpecList[k].Group = (short)(k / interval); } // Remove the redudant rows. List <int> rows = new List <int>(); for (int row = 0; row < dataDim; row++) { rows.Add(row); } walsh = walsh.SelectRows(rows); // Normalize the matrix. double normFactor = Math.Pow(2, -log2 / 2.0); for (int row = 0; row < walsh.Rows; row++) { for (int col = 0; col < walsh.Columns; col++) { walsh.Matrix[row][col] *= normFactor; } } }