Пример #1
0
        /// <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);
            }
        }
Пример #2
0
        /// <summary>
        /// Gets the Debauchies scaling function
        /// </summary>
        /// <param name="levels">Levels of approximatation</param>
        /// <param name="waveletKind">Wavelet kind to calculate</param>
        /// <returns>The wavelet function at the specified level of approximation</returns>
        public Vector2[] GetWaveletFunction(int levels, WaveletKind waveletKind)
        {
            if (levels < 0)
            {
                throw new ArgumentOutOfRangeException($"{nameof(GetScalingFunction)} parameter {nameof(levels)} ({levels}) must be 0 or larger");
            }

            var scaling      = GetScalingFunction(levels, waveletKind).Last().ToArray();
            var coefficients = WaveletCoefficients.GetWaveletCoefficients(waveletKind).ToArray();

            return(GetWaveletLevel(scaling, coefficients));

            Vector2[] GetWaveletLevel(Vector2[] scaling, float[] waveletCoefs)
            {
                var wavelet = new Vector2[scaling.Length];

                float maxRange         = waveletCoefs.Length - 1f;
                float distancePerPoint = maxRange / (wavelet.Length - 1);

                for (int n = 0; n < wavelet.Length; n++)
                {
                    float sum = 0;
                    float r   = n * distancePerPoint;

                    for (int k = 0; k < waveletCoefs.Length; k++)
                    {
                        float rPrevious = 2 * r - k;
                        int   rIndex    = (int)MathF.Round(rPrevious / distancePerPoint);

                        if (rPrevious >= 0 && rPrevious <= maxRange)
                        {
                            sum += waveletCoefs[k] * scaling[rIndex].Y;
                        }
                    }
                    wavelet[n] = new Vector2(r, sum);
                }

                return(wavelet);
            }
        }
Пример #3
0
 public int GetMaxRange(WaveletKind waveletKind) =>
 WaveletCoefficients.GetScalingCoefficients(waveletKind).Length - 1;