public INumberTable Transform(INumberTable inTable) { INumberTable rMatrix = matrixReal.SelectColumns(selectReal); INumberTable iMatrix = matrixImg.SelectColumns(selectImg); IList <IColumnSpec> cs = iMatrix.ColumnSpecList; for (int i = 0; i < cs.Count; i++) { cs[i].Id += "_i"; } return(MatrixProduct(inTable, rMatrix.AppendColumns(iMatrix))); }
public static INumberTable Filter(INumberTable inTable, double lowFreq, double highFreq, int dimension, INumberTable baseTable) { int lowIdx = (int)(lowFreq * dimension); int hiIdx = (int)(highFreq * dimension); List <int> columns = new List <int>(); for (int i = 0; i < dimension; i++) { if ((i >= lowIdx) && (i <= hiIdx)) { columns.Add(i); } } INumberTable B = baseTable.SelectColumns(columns); INumberTable Bt = B.Transpose2(); int b = B.Columns; int r = inTable.Rows; int m = inTable.Columns; INumberTable outTable = null; //Depending on the size of m relative to r and b, we can //optimize the calculation by arrange the matrix multiplication. if (2 * r * b < m * (r + b)) { // The complexity in this arrangement is 2*m*r*b. outTable = FourierTransform.MatrixProduct(FourierTransform.MatrixProduct(inTable, B), Bt); } else { // The complexity in this arrangement is m*m*(r+b). outTable = FourierTransform.MatrixProduct(inTable, FourierTransform.MatrixProduct(B, Bt)); } IList <IColumnSpec> oSpecList = outTable.ColumnSpecList; IList <IColumnSpec> iSpecList = inTable.ColumnSpecList; for (int col = 0; col < outTable.Columns; col++) { oSpecList[col].CopyFrom(iSpecList[col]); } return(outTable); }
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); }