public static unsafe DwtOutput Forward(double[] input, Wavelet wavelet, Int32 level)
        {
            Int32 Len = wavelet.DecompositionLow.Length;
            Int32 CircleInd;

            double[] output = new Double[input.Length];
            Double[] Buff   = new Double[input.Length];
            Buffer.BlockCopy(input, 0, output, 0, input.Length * 8);
            Double  BufScal = 0;
            Double  BufDet  = 0;
            Double *DecLow  = stackalloc Double[Len];
            Double *DecHigh = stackalloc Double[Len];

            for (int i = 0; i < Len; i++)
            {
                DecLow[i]  = wavelet.DecompositionLow[i];
                DecHigh[i] = wavelet.DecompositionHigh[i];
            }

            fixed(Double *pout = output, pbuf = Buff)
            {
                for (int lvl = 0; lvl < level; lvl++)
                {
                    Int32 Bound      = input.Length >> lvl;
                    Int32 StartIndex = -((Len >> 1) - 1);
                    Buffer.BlockCopy(output, 0, Buff, 0, Bound * 8);

                    for (int i = 0; i < Bound >> 1; i++)
                    {
                        for (int j = StartIndex, k = 0; k < Len; j++, k++)
                        {
                            if ((StartIndex < 0) || j >= Bound)
                            {
                                CircleInd = ((j % Bound) + Bound) % Bound;
                            }
                            else
                            {
                                CircleInd = j;
                            }
                            BufScal += DecLow[k] * pout[CircleInd];
                            BufDet  += DecHigh[k] * pout[CircleInd];
                        }
                        StartIndex            += 2;
                        pbuf[i]                = BufScal;
                        pbuf[i + (Bound >> 1)] = BufDet;
                        BufScal                = 0;
                        BufDet = 0;
                    }
                    Buffer.BlockCopy(Buff, 0, output, 0, Bound * 8);
                }
            }

            DwtOutput res = new DwtOutput(output, level, wavelet);

            return(res);
        }
        public DwtOutput(double[] output, int level, Wavelet wavelet)
        {
            Level   = level;
            Wavelet = wavelet;

            ApproximationCoefficients = new double[output.Length / (level + 1)];
            Array.Copy(output, ApproximationCoefficients, ApproximationCoefficients.Length);
            DetailCoefficients = new double[output.Length - ApproximationCoefficients.Length];
            Array.Copy(output, ApproximationCoefficients.Length, DetailCoefficients, 0, output.Length - ApproximationCoefficients.Length);
            FullVector = output;
        }