protected virtual void Initialize(int p, int N, double alpha) { _fibonacciSequence = FibonacciSequence.GetSequence(p, N); this.alpha = alpha; var cacheMatrices = Cache.TryGetFHTMatrix(new Tuple <int, int>(p, N)); if (cacheMatrices != null) { _fhtMatrix = cacheMatrices.Item1; _fhtMatrixInverse = cacheMatrices.Item2; } else { _fhtMatrix = FibonacciHaarTransformationMatrix(p, N); _fhtMatrixInverse = new SparseMatrix(_fhtMatrix.RowCount); _fhtMatrix.Transpose(_fhtMatrixInverse); _fhtMatrix.Multiply(0.5, _fhtMatrix); Cache.AddFHTMatrix(new Tuple <int, int>(p, N), new Tuple <Matrix, Matrix>(_fhtMatrix, _fhtMatrixInverse)); } }
/// <summary> /// Populates the FHT matrix according to reccurent formulae and returns it as MathNet SparseMatrix /// </summary> /// <param name="p">p-sequence to use</param> /// <param name="N">Matrix dimension</param> /// <returns></returns> protected static Matrix FibonacciHaarTransformationMatrix(int p, int N) { double[,] pnMatrix = { { Math.Sqrt(2) } }; double[,] pp1Matrix = { { 1, 1 }, { 1, -1 } }; var fibonacci = FibonacciSequence.GetSequence(p, N); var n = fibonacci.IndexOfElement(N); double[,] pprev, prev, current = new double[0, 0]; Queue <double[, ]> intermediate = new Queue <double[, ]>(); for (int i = 0; i <= p; i++) { intermediate.Enqueue(pnMatrix); } intermediate.Enqueue(pp1Matrix); for (int i = p + 2; i <= n; i++) { int size = fibonacci.GetElementByIndex(i); int pSize = fibonacci.GetElementByIndex(i - 1); int ppSize = fibonacci.GetElementByIndex(i - p - 1); int pUpperSize = fibonacci.GetElementByIndex(i - 2); int pLowerSize = fibonacci.GetElementByIndex(i - p - 2); int ppUpperSize = pLowerSize; int ppLowerSize = fibonacci.GetElementByIndex(i - 2 * p - 2); prev = intermediate.Last(); pprev = intermediate.ElementAt(intermediate.Count - p - 1); current = new double[size, size]; for (int j = 0; j < pUpperSize; j++) { for (int k = 0; k < pSize; k++) { current[j, k] = prev[j, k]; } } for (int j = pUpperSize; j < pSize; j++) { for (int k = 0; k < pSize; k++) { current[j + pLowerSize, k] = prev[j, k]; } } for (int j = 0; j < ppUpperSize; j++) { for (int k = 0; k < ppSize; k++) { current[j + pUpperSize, k + pSize] = pprev[j, k]; } } for (int j = ppUpperSize; j < ppSize; j++) { for (int k = 0; k < ppSize; k++) { current[j + pSize, k + pSize] = pprev[j, k]; } } intermediate.Enqueue(current); intermediate.Dequeue(); } var fhtMatrix = SparseMatrix.OfArray(current); fhtMatrix.Multiply(0.5, fhtMatrix); return(fhtMatrix); }