Ejemplo n.º 1
0
        // this algorithm is very inefficient
        public static decimal Ln(decimal v)
        {
            if (v <= 0M)
            {
                throw new ArgumentOutOfRangeException("v");
            }

            // algorithm is based on area hyperbolic tangent
            // https://en.wikipedia.org/wiki/Logarithm

            decimal x = 0;

            decimal t    = (v - 1M) / (v + 1M);
            decimal tMul = t * t;

            for (int i = 0; i < 1000 * 1000 * 1000; ++i)
            {
                decimal diff = 2M / (i * 2 + 1M) * t;
                if (WWDecimalMath.IsExtremelySmall(diff))
                {
                    break;
                }
                x += diff;
                t *= tMul;

                //Console.WriteLine("    {0} {1}", i, x);
            }

            return(x);
        }
Ejemplo n.º 2
0
 public override string ToString()
 {
     if (WWDecimalMath.IsExtremelySmall(imaginary))
     {
         return(string.Format("{0:0.#######}", real));
     }
     if (WWDecimalMath.IsExtremelySmall(real))
     {
         return(string.Format("{0:0.#######}i", imaginary));
     }
     return(string.Format("{0:0.#######} {1:+0.#######;-0.#######}i", real, imaginary));
 }
Ejemplo n.º 3
0
        private void FftStageN(int stageNr, WWDecimalComplex[] x, WWDecimalComplex[] y)
        {
            /*
             * stage0: 2つの入力データにバタフライ演算 (length=8の時) 4回 (nRepeat=4, nSubRepeat=2)
             * y[0] = x[0] + w_n^(0*4) * x[1]
             * y[1] = x[0] + w_n^(1*4) * x[1]
             *
             * y[2] = x[2] + w_n^(0*4) * x[3]
             * y[3] = x[2] + w_n^(1*4) * x[3]
             *
             * y[4] = x[4] + w_n^(0*4) * x[5]
             * y[5] = x[4] + w_n^(1*4) * x[5]
             *
             * y[6] = x[6] + w_n^(0*4) * x[7]
             * y[7] = x[6] + w_n^(1*4) * x[7]
             */

            /*
             * stage1: 4つの入力データにバタフライ演算 (length=8の時) 2回 (nRepeat=2, nSubRepeat=4)
             * y[0] = x[0] + w_n^(0*2) * x[2]
             * y[1] = x[1] + w_n^(1*2) * x[3]
             * y[2] = x[0] + w_n^(2*2) * x[2]
             * y[3] = x[1] + w_n^(3*2) * x[3]
             *
             * y[4] = x[4] + w_n^(0*2) * x[6]
             * y[5] = x[5] + w_n^(1*2) * x[7]
             * y[6] = x[4] + w_n^(2*2) * x[6]
             * y[7] = x[5] + w_n^(3*2) * x[7]
             */

            /*
             * stage2: 8つの入力データにバタフライ演算 (length=8の時) 1回 (nRepeat=1, nSubRepeat=8)
             * y[0] = x[0] + w_n^(0*1) * x[4]
             * y[1] = x[1] + w_n^(1*1) * x[5]
             * y[2] = x[2] + w_n^(2*1) * x[6]
             * y[3] = x[3] + w_n^(3*1) * x[7]
             * y[4] = x[0] + w_n^(4*1) * x[4]
             * y[5] = x[1] + w_n^(5*1) * x[5]
             * y[6] = x[2] + w_n^(6*1) * x[6]
             * y[7] = x[3] + w_n^(7*1) * x[7]
             */

            /*
             * stageN:
             */

            int nRepeat    = Pow2(mNumStage - stageNr - 1);
            int nSubRepeat = mNumPoints / nRepeat;
            var t          = new WWDecimalComplex();

            for (int i = 0; i < nRepeat; ++i)
            {
                int offsBase = i * nSubRepeat;

                bool allZero = true;
                for (int j = 0; j < nSubRepeat / 2; ++j)
                {
                    int offs = offsBase + (j % (nSubRepeat / 2));
                    if (!WWDecimalMath.IsExtremelySmall(x[offs].Magnitude()))
                    {
                        allZero = false;
                        break;
                    }
                    if (!WWDecimalMath.IsExtremelySmall(x[offs + nSubRepeat / 2].Magnitude()))
                    {
                        allZero = false;
                        break;
                    }
                }

                if (allZero)
                {
                    for (int j = 0; j < nSubRepeat / 2; ++j)
                    {
                        y[j + offsBase].Set(0, 0);
                    }
                }
                else
                {
                    for (int j = 0; j < nSubRepeat; ++j)
                    {
                        int offs = offsBase + (j % (nSubRepeat / 2));
                        y[j + offsBase].CopyFrom(x[offs]);

                        t.CopyFrom(mWn[j * nRepeat]);
                        t.Mul(x[offs + nSubRepeat / 2]);

                        y[j + offsBase].Add(t);
                    }
                }
            }
        }