/// <summary> /// Gets the Debauchies scaling function /// </summary> /// <param name="x">Array of x-coordinates to map to scaling function</param> /// <param name="levels">Levels of approximatation</param> /// <returns>The scaling function at successive levels of approximation</returns> public IEnumerable <Vector2[]> GetScalingFunction(int levels, WaveletKind wavelet) { if (levels < 0) { throw new ArgumentOutOfRangeException($"{nameof(GetScalingFunction)} parameter {nameof(levels)} ({levels}) must be 0 or larger"); } var coefficients = WaveletCoefficients.GetScalingCoefficients(wavelet).ToArray(); var previous = WaveletCoefficients.GetInitialScalingValues(wavelet).ToArray().Select((x, index) => new Vector2(index, x)).ToArray(); float maxRange = coefficients.Length - 1f; var current = previous; yield return(previous); for (int level = 1; level <= levels; level++) { current = GetScalingLevel(level, previous, coefficients); yield return(current); previous = current; } Vector2[] GetScalingLevel(int level, Vector2[] previous, float[] scalingCoefs) { var scaling = new Vector2[PointsAtLevel(scalingCoefs.Length, level)]; float maxRange = scalingCoefs.Length - 1f; float distancePerIndex = maxRange / (scaling.Length - 1); for (int n = 0; n < scaling.Length; n += 2) { scaling[n] = previous[n / 2]; } for (int n = 1; n < scaling.Length; n += 2) { float sum = 0; float r = n / (float)(1 << level); for (int k = 0; k < scalingCoefs.Length; k++) { float rPrevious = 2 * r - k; int rIndex = (int)MathF.Round(rPrevious / distancePerIndex); if (rPrevious >= 0 && rPrevious <= maxRange) { sum += scalingCoefs[k] * scaling[rIndex].Y; } } scaling[n] = new Vector2(r, sum); } return(scaling); } }
public int GetMaxRange(WaveletKind waveletKind) => WaveletCoefficients.GetScalingCoefficients(waveletKind).Length - 1;