static void Main()
 {
     SimpleMath simple = new SimpleMath();
     int sum = simple.Add(2, 2);
     Console.WriteLine("2 + 2 = {0}", sum);
     ComplexMath complex = new ComplexMath();
     int square = complex.Square(3);
     Console.WriteLine("3 squared = {0}", square);
 }
示例#2
0
        ///<summary>Computes the algorithm.</summary>
        protected override void InternalCompute()
        {
            rows = matrix.RowLength;
            cols = matrix.ColumnLength;
            int mm = System.Math.Min(rows + 1, cols);

            s = new FloatVector(mm); // singular values

#if MANAGED
            // Derived from LINPACK code.
            // Initialize.

            u = new FloatMatrix(rows, rows); // left vectors
            v = new FloatMatrix(cols, cols); // right vectors
            var e    = new FloatVector(cols);
            var work = new FloatVector(rows);

            int   i, iter, j, k, kase, l, lp1, ls = 0, lu, m, nct, nctp1, ncu, nrt, nrtp1;
            float b, c, cs = 0.0f, el, emm1, f, g, scale, shift, sl,
                  sm, sn = 0.0f, smm1, t1, test, ztest, xnorm, enorm;
            float t, r;

            ncu = rows;

            //   reduce matrix to bidiagonal form, storing the diagonal elements
            //   in s and the super-diagonal elements in e.
            int info = 0;
            nct = System.Math.Min(rows - 1, cols);
            nrt = System.Math.Max(0, System.Math.Min(cols - 2, rows));
            lu  = System.Math.Max(nct, nrt);

            for (l = 0; l < lu; l++)
            {
                lp1 = l + 1;
                if (l < nct)
                {
                    // compute the transformation for the l-th column and
                    // place the l-th diagonal in s[l].
                    xnorm = dnrm2Column(matrix, l, l);
                    s[l]  = xnorm;
                    if (s[l] != 0.0f)
                    {
                        if (matrix[l, l] != 0.0f)
                        {
                            s[l] = dsign(s[l], matrix[l, l]);
                        }
                        dscalColumn(matrix, l, l, 1.0f / s[l]);
                        matrix[l, l] = 1.0f + matrix[l, l];
                    }

                    s[l] = -s[l];
                }

                for (j = lp1; j < cols; j++)
                {
                    if (l < nct)
                    {
                        if (s[l] != 0.0f)
                        {
                            // apply the transformation.
                            t = -ddot(matrix, l, j, l) / matrix[l, l];
                            for (int ii = l; ii < matrix.RowLength; ii++)
                            {
                                matrix[ii, j] += t * matrix[ii, l];
                            }
                        }
                    }

                    //place the l-th row of matrix into  e for the
                    //subsequent calculation of the row transformation.
                    e[j] = matrix[l, j];
                }

                if (computeVectors && l < nct)
                {
                    // place the transformation in u for subsequent back multiplication.
                    for (i = l; i < rows; i++)
                    {
                        u[i, l] = matrix[i, l];
                    }
                }

                if (l < nrt)
                {
                    // compute the l-th row transformation and place the l-th super-diagonal in e(l).
                    enorm = dnrm2Vector(e, lp1);
                    e[l]  = enorm;
                    if (e[l] != 0.0f)
                    {
                        if (e[lp1] != 0.0f)
                        {
                            e[l] = dsign(e[l], e[lp1]);
                        }
                        dscalVector(e, lp1, 1.0f / e[l]);
                        e[lp1] = 1.0f + e[lp1];
                    }
                    e[l] = -e[l];

                    if (lp1 < rows && e[l] != 0.0f)
                    {
                        // apply the transformation.
                        for (i = lp1; i < rows; i++)
                        {
                            work[i] = 0.0f;
                        }

                        for (j = lp1; j < cols; j++)
                        {
                            for (int ii = lp1; ii < matrix.RowLength; ii++)
                            {
                                work[ii] += e[j] * matrix[ii, j];
                            }
                        }

                        for (j = lp1; j < cols; j++)
                        {
                            float ww = -e[j] / e[lp1];
                            for (int ii = lp1; ii < matrix.RowLength; ii++)
                            {
                                matrix[ii, j] += ww * work[ii];
                            }
                        }
                    }

                    if (computeVectors)
                    {
                        // place the transformation in v for subsequent back multiplication.
                        for (i = lp1; i < cols; i++)
                        {
                            v[i, l] = e[i];
                        }
                    }
                }
            }

            //   set up the final bidiagonal matrix or order m.
            m     = System.Math.Min(cols, rows + 1);
            nctp1 = nct + 1;
            nrtp1 = nrt + 1;
            if (nct < cols)
            {
                s[nctp1 - 1] = matrix[nctp1 - 1, nctp1 - 1];
            }
            if (rows < m)
            {
                s[m - 1] = 0.0f;
            }
            if (nrtp1 < m)
            {
                e[nrtp1 - 1] = matrix[nrtp1 - 1, m - 1];
            }
            e[m - 1] = 0.0f;

            //   if required, generate u.
            if (computeVectors)
            {
                for (j = nctp1 - 1; j < ncu; j++)
                {
                    for (i = 0; i < rows; i++)
                    {
                        u[i, j] = 0.0f;
                    }
                    u[j, j] = 1.0f;
                }

                for (l = nct - 1; l >= 0; l--)
                {
                    if (s[l] != 0.0f)
                    {
                        for (j = l + 1; j < ncu; j++)
                        {
                            t = -ddot(u, l, j, l) / u[l, l];
                            for (int ii = l; ii < u.RowLength; ii++)
                            {
                                u[ii, j] += t * u[ii, l];
                            }
                        }
                        dscalColumn(u, l, l, -1.0f);
                        u[l, l] = 1.0f + u[l, l];
                        for (i = 0; i < l; i++)
                        {
                            u[i, l] = 0.0f;
                        }
                    }
                    else
                    {
                        for (i = 0; i < rows; i++)
                        {
                            u[i, l] = 0.0f;
                        }
                        u[l, l] = 1.0f;
                    }
                }
            }

            //   if it is required, generate v.
            if (computeVectors)
            {
                for (l = cols - 1; l >= 0; l--)
                {
                    lp1 = l + 1;
                    if (l < nrt)
                    {
                        if (e[l] != 0.0f)
                        {
                            for (j = lp1; j < cols; j++)
                            {
                                t = -ddot(v, l, j, lp1) / v[lp1, l];
                                for (int ii = l; ii < v.RowLength; ii++)
                                {
                                    v[ii, j] += t * v[ii, l];
                                }
                            }
                        }
                    }
                    for (i = 0; i < cols; i++)
                    {
                        v[i, l] = 0.0f;
                    }
                    v[l, l] = 1.0f;
                }
            }

            //   transform s and e so that they are  float .
            for (i = 0; i < m; i++)
            {
                if (s[i] != 0.0f)
                {
                    t    = s[i];
                    r    = s[i] / t;
                    s[i] = t;
                    if (i < m - 1)
                    {
                        e[i] = e[i] / r;
                    }
                    if (computeVectors)
                    {
                        dscalColumn(u, i, 0, r);
                    }
                }
                //   ...exit
                if (i == m - 1)
                {
                    break;
                }
                if (e[i] != 0.0)
                {
                    t        = e[i];
                    r        = t / e[i];
                    e[i]     = t;
                    s[i + 1] = s[i + 1] * r;
                    if (computeVectors)
                    {
                        dscalColumn(v, i + 1, 0, r);
                    }
                }
            }

            //   main iteration loop for the singular values.
            mm   = m;
            iter = 0;

            while (m > 0)
            { // quit if all the singular values have been found.
              // if too many iterations have been performed, set
              //      flag and return.
                if (iter >= MAXITER)
                {
                    info = m;
                    //   ......exit
                    break;
                }

                //      this section of the program inspects for
                //      negligible elements in the s and e arrays.  on
                //      completion the variables kase and l are set as follows.

                //         kase = 1     if s[m] and e[l-1] are negligible and l < m
                //         kase = 2     if s[l] is negligible and l < m
                //         kase = 3     if e[l-1] is negligible, l < m, and
                //                      s[l, ..., s[m] are not negligible (qr step).
                //         kase = 4     if e[m-1] is negligible (convergence).

                for (l = m - 2; l >= 0; l--)
                {
                    test  = ComplexMath.Absolute(s[l]) + ComplexMath.Absolute(s[l + 1]);
                    ztest = test + ComplexMath.Absolute(e[l]);
                    if (ztest == test)
                    {
                        e[l] = 0.0f;
                        break;
                    }
                }

                if (l == m - 2)
                {
                    kase = 4;
                }
                else
                {
                    for (ls = m - 1; ls > l; ls--)
                    {
                        test = 0.0f;
                        if (ls != m - 1)
                        {
                            test = test + ComplexMath.Absolute(e[ls]);
                        }
                        if (ls != l + 1)
                        {
                            test = test + ComplexMath.Absolute(e[ls - 1]);
                        }
                        ztest = test + ComplexMath.Absolute(s[ls]);
                        if (ztest == test)
                        {
                            s[ls] = 0.0f;
                            break;
                        }
                    }

                    if (ls == l)
                    {
                        kase = 3;
                    }
                    else if (ls == m - 1)
                    {
                        kase = 1;
                    }
                    else
                    {
                        kase = 2;
                        l    = ls;
                    }
                }

                l = l + 1;

                //      perform the task indicated by kase.
                switch (kase)
                {
                // deflate negligible s[m].
                case 1:
                    f        = e[m - 2];
                    e[m - 2] = 0.0f;
                    for (k = m - 2; k >= 0; k--)
                    {
                        t1 = s[k];
                        drotg(ref t1, ref f, ref cs, ref sn);
                        s[k] = t1;
                        if (k != l)
                        {
                            f        = -sn * e[k - 1];
                            e[k - 1] = cs * e[k - 1];
                        }
                        if (computeVectors)
                        {
                            drot(v, k, m - 1, cs, sn);
                        }
                    }
                    break;

                // split at negligible s[l].
                case 2:
                    f        = e[l - 1];
                    e[l - 1] = 0.0f;
                    for (k = l; k < m; k++)
                    {
                        t1 = s[k];
                        drotg(ref t1, ref f, ref cs, ref sn);
                        s[k] = t1;
                        f    = -sn * e[k];
                        e[k] = cs * e[k];
                        if (computeVectors)
                        {
                            drot(u, k, l - 1, cs, sn);
                        }
                    }
                    break;

                // perform one qr step.
                case 3:
                    // calculate the shift.
                    scale = 0.0f;
                    scale = System.Math.Max(scale, ComplexMath.Absolute(s[m - 1]));
                    scale = System.Math.Max(scale, ComplexMath.Absolute(s[m - 2]));
                    scale = System.Math.Max(scale, ComplexMath.Absolute(e[m - 2]));
                    scale = System.Math.Max(scale, ComplexMath.Absolute(s[l]));
                    scale = System.Math.Max(scale, ComplexMath.Absolute(e[l]));
                    sm    = s[m - 1] / scale;
                    smm1  = s[m - 2] / scale;
                    emm1  = e[m - 2] / scale;
                    sl    = s[l] / scale;
                    el    = e[l] / scale;
                    b     = ((smm1 + sm) * (smm1 - sm) + emm1 * emm1) / 2.0f;
                    c     = (sm * emm1) * (sm * emm1);
                    shift = 0.0f;
                    if (b != 0.0f || c != 0.0f)
                    {
                        shift = (float)System.Math.Sqrt(b * b + c);
                        if (b < 0.0f)
                        {
                            shift = -shift;
                        }
                        shift = c / (b + shift);
                    }
                    f = (sl + sm) * (sl - sm) + shift;
                    g = sl * el;

                    // chase zeros.
                    for (k = l; k < m - 1; k++)
                    {
                        drotg(ref f, ref g, ref cs, ref sn);
                        if (k != l)
                        {
                            e[k - 1] = f;
                        }
                        f        = cs * s[k] + sn * e[k];
                        e[k]     = cs * e[k] - sn * s[k];
                        g        = sn * s[k + 1];
                        s[k + 1] = cs * s[k + 1];
                        if (computeVectors)
                        {
                            drot(v, k, k + 1, cs, sn);
                        }
                        drotg(ref f, ref g, ref cs, ref sn);
                        s[k]     = f;
                        f        = cs * e[k] + sn * s[k + 1];
                        s[k + 1] = -sn * e[k] + cs * s[k + 1];
                        g        = sn * e[k + 1];
                        e[k + 1] = cs * e[k + 1];
                        if (computeVectors && k < rows)
                        {
                            drot(u, k, k + 1, cs, sn);
                        }
                    }
                    e[m - 2] = f;
                    iter     = iter + 1;
                    break;

                // convergence.
                case 4:
                    // make the singular value  positive
                    if (s[l] < 0.0f)
                    {
                        s[l] = -s[l];
                        if (computeVectors)
                        {
                            dscalColumn(v, l, 0, -1.0f);
                        }
                    }

                    // order the singular value.
                    while (l != mm - 1)
                    {
                        if (s[l] >= s[l + 1])
                        {
                            break;
                        }
                        t        = s[l];
                        s[l]     = s[l + 1];
                        s[l + 1] = t;
                        if (computeVectors && l < cols)
                        {
                            dswap(v, l, l + 1);
                        }
                        if (computeVectors && l < rows)
                        {
                            dswap(u, l, l + 1);
                        }
                        l = l + 1;
                    }
                    iter = 0;
                    m    = m - 1;
                    break;
                }
            }

            // make matrix w from vector s
            // there is no constructor, creating diagonal matrix from vector
            // doing it ourselves
            mm = System.Math.Min(matrix.RowLength, matrix.ColumnLength);
#else
            u = new FloatMatrix(rows);
            v = new FloatMatrix(cols);
            float[] a = new float[matrix.data.Length];
            Array.Copy(matrix.data, a, matrix.data.Length);
            Lapack.Gesvd.Compute(rows, cols, a, s.data, u.data, v.data);
            v.Transpose();
#endif
            w = new FloatMatrix(matrix.RowLength, matrix.ColumnLength);
            for (int ii = 0; ii < matrix.RowLength; ii++)
            {
                for (int jj = 0; jj < matrix.ColumnLength; jj++)
                {
                    if (ii == jj)
                    {
                        w[ii, ii] = s[ii];
                    }
                }
            }

            float eps = (float)System.Math.Pow(2.0, -52.0);
            float tol = System.Math.Max(matrix.RowLength, matrix.ColumnLength) * s[0] * eps;
            rank = 0;

            for (int h = 0; h < mm; h++)
            {
                if (s[h] > tol)
                {
                    rank++;
                }
            }

            if (!computeVectors)
            {
                u = null;
                v = null;
            }
            matrix = null;
        }
示例#3
0
        public static Complex Psi(Complex z)
        {
            Complex t = z + LanczosGP;

            return(ComplexMath.Log(t) - LanczosG / t + LogSumPrime(z));
        }
示例#4
0
        private static ComplexFloat csign(ComplexFloat z1, ComplexFloat z2)
        {
            ComplexFloat ret = ComplexMath.Absolute(z1) * (z2 / ComplexMath.Absolute(z2));

            return(ret);
        }
        private static void Main(string[] args)
        {
            // define squares
            BoardSpace[] spaces = new BoardSpace[] {
                new BoardSpace("Go", 0.0, Double.PositiveInfinity),
                new BoardSpace("Mediterranean Avenue", 2.0, 60.0),
                new BoardSpace("Community Chest", 0.0, Double.PositiveInfinity),
                new BoardSpace("Baltic Avenue", 4.0, 60.0),
                new BoardSpace("Income Tax", 0.0, Double.PositiveInfinity),
                new BoardSpace("Reading Railroad", 25.0, 200.0),
                new BoardSpace("Oriental Avenue", 6.0, 100.0),
                new BoardSpace("Chance", 0.0, Double.PositiveInfinity),
                new BoardSpace("Vermont Avenue", 6.0, 100.0),
                new BoardSpace("Connecticut Avenue", 8.0, 120.0),
                new BoardSpace("Jail", 0.0, Double.PositiveInfinity),
                new BoardSpace("St. Charles Place", 10.0, 140.0),
                new BoardSpace("Electric Company", 4.0 * 6.0, 150.0),
                new BoardSpace("States Avenue", 10.0, 140.0),
                new BoardSpace("Virginia Avenue", 12.0, 160.0),
                new BoardSpace("Pennsylvania Railroad", 25.0, 200.0),
                new BoardSpace("St. James Place", 14.0, 180.0),
                new BoardSpace("Community Chest", 0.0, Double.PositiveInfinity),
                new BoardSpace("Tennessee Avenue", 14.0, 180.0),
                new BoardSpace("New York Avenue", 16.0, 200.0),
                new BoardSpace("Free Parking", 0.0, Double.PositiveInfinity),
                new BoardSpace("Kentucky Avenue", 18.0, 220.0),
                new BoardSpace("Chance", 0.0, Double.PositiveInfinity),
                new BoardSpace("Indiana Avenue", 18.0, 220.0),
                new BoardSpace("Illinois Avenue", 20.0, 240.0),
                new BoardSpace("B & O Railroad", 25.0, 200.0),
                new BoardSpace("Atlantic Avenue", 22.0, 260.0),
                new BoardSpace("Ventnor Avenue", 22.0, 260.0),
                new BoardSpace("Water Works", 4.0 * 6.0, 150.0),
                new BoardSpace("Marvin Gardens", 24.0, 280.0),
                new BoardSpace("Go To Jail", 0.0, Double.PositiveInfinity),
                new BoardSpace("Pacific Avenue", 26.0, 300.0),
                new BoardSpace("North Carolina Avenue", 26.0, 300.0),
                new BoardSpace("Community Chest", 0.0, Double.PositiveInfinity),
                new BoardSpace("Pennsylvania Avenue", 28.0, 320.0),
                new BoardSpace("Short Line", 25.0, 200.0),
                new BoardSpace("Chance", 0.0, Double.PositiveInfinity),
                new BoardSpace("Park Place", 35.0, 350.0),
                new BoardSpace("Luxury Tax", 0.0, Double.PositiveInfinity),
                new BoardSpace("Boardwalk", 50.0, 400.0)
            };

            // number of squares
            int n = spaces.Length;

            // compute the transition matrix which takes the dice roll
            // into account: Moves us ahead by two spaces with
            // probability 1/36 (“snake-eyes”), three spaces with
            // probability 2/36, and so on up to twelve spaces with
            // probability 1/36 (“double-sixes”), etc.
            SquareMatrix R = new SquareMatrix(n);

            for (int c = 0; c < n; c++)
            {
                R[(c + 2) % n, c]  = 1.0 / 36.0;
                R[(c + 3) % n, c]  = 2.0 / 36.0;
                R[(c + 4) % n, c]  = 3.0 / 36.0;
                R[(c + 5) % n, c]  = 4.0 / 36.0;
                R[(c + 6) % n, c]  = 5.0 / 36.0;
                R[(c + 7) % n, c]  = 6.0 / 36.0;
                R[(c + 8) % n, c]  = 5.0 / 36.0;
                R[(c + 9) % n, c]  = 4.0 / 36.0;
                R[(c + 10) % n, c] = 3.0 / 36.0;
                R[(c + 11) % n, c] = 2.0 / 36.0;
                R[(c + 12) % n, c] = 1.0 / 36.0;
            }

            // compute the special matrix, which takes board into account:
            // The column for space 30, “Go To Jail”, transitions with
            // certainty to space 10, the jail.
            // A token that lands on a community chest space sometimes
            // transitions to go and sometimes transitions to jail, but
            // most often just stays put
            SquareMatrix S = new SquareMatrix(n);

            for (int c = 0; c < n; c++)
            {
                if (c == 30)
                {
                    // go to jail
                    S[10, 30] = 1.0;
                }
                else if ((c == 7) || (c == 22) || (c == 36))
                {
                    // chance
                    // advance to go
                    S[0, c] = 1.0 / 16.0;
                    // advance to illinois avenue
                    S[24, c] = 1.0 / 16.0;
                    // take a walk on the boardwalk
                    S[39, c] = 1.0 / 16.0;
                    // go to jail
                    S[10, c] = 1.0 / 16.0;
                    // take a ride on the reading
                    S[5, c] = 1.0 / 16.0;
                    // advance to St. Charles place
                    S[11, c] = 1.0 / 16.0;
                    // go back 3 spaces
                    S[(c - 3) % S.Dimension, c] = 1.0 / 16.0;
                    // advance token to the nearest utility
                    if ((c < 12) || (c > 28))
                    {
                        S[12, c] = 1.0 / 16.0;
                    }
                    else
                    {
                        S[28, c] = 1.0 / 16.0;
                    }
                    // advance token to the nearest railroad
                    if (c < 5)
                    {
                        S[5, c] += 1.0 / 16.0;
                    }
                    else if (c < 15)
                    {
                        S[15, c] = 1.0 / 16.0;
                    }
                    else if (c < 25)
                    {
                        S[25, c] = 1.0 / 16.0;
                    }
                    else if (c < 35)
                    {
                        S[35, c] = 1.0 / 16.0;
                    }
                    else
                    {
                        S[5, c] += 1.0 / 16.0;
                    }
                    // stay put
                    S[c, c] = 7.0 / 16.0;
                }
                else if ((c == 2) || (c == 17) || (c == 33))
                {
                    // community chest
                    // advance to go
                    S[0, c] = 1.0 / 16.0;
                    // go to jail
                    S[10, c] = 1.0 / 16.0;
                    // stay put
                    S[c, c] = 14.0 / 16.0;
                }
                else
                {
                    // all other spaces are no-ops
                    S[c, c] = 1.0;
                }
            }

            // compute the complete transition matrix
            SquareMatrix P = S * R;

            // verify Markov conditions
            for (int c = 0; c < P.Dimension; c++)
            {
                double sr = 0.0;
                for (int r = 0; r < P.Dimension; r++)
                {
                    sr += P[r, c];
                }
                Debug.Assert(Math.Abs(sr - 1.0) < 1.0e-15);
            }

            // An alternative now is to begin with some initial state vector
            // guess, and repeatedly apply P until the resultant vector
            // no longer changes. The resultant vector will be the dominant
            // eigenvector. That's how PageRank is evaluated by Google,
            // using MapReduce.

            // Another alternative is to compute the eigenvalues and
            // eigenvectors of the transition matrix
            ComplexEigensystem E = P.Eigensystem();

            // get the dominant eigenvector: The one with the largest
            // eigenvalue
            Complex         e = -1.0;
            IList <Complex> v = null;

            for (int i = 0; i < E.Dimension; i++)
            {
                Complex ei = E.Eigenvalue(i);
                if (ComplexMath.Abs(ei) > ComplexMath.Abs(e))
                {
                    e = ei;
                    v = E.Eigenvector(i);
                }
            }

            // verify that it has eigenvalue 1 and is real
            Debug.Assert(Math.Abs(e.Re - 1.0) < 1.0e-15);
            Debug.Assert(e.Im == 0.0);
            for (int i = 0; i < n; i++)
            {
                Debug.Assert(v[i].Im == 0.0);
            }

            // normalize the probabilities
            double sv = 0.0;

            for (int i = 0; i < E.Dimension; i++)
            {
                sv += v[i].Re;
            }
            double[] p = new double[E.Dimension];
            for (int i = 0; i < E.Dimension; i++)
            {
                p[i] = v[i].Re / sv;
            }

            // Having found the dominant eigenvector, we can examine its components
            // to find the long-run relative probabilities of a token landing on each
            // space.
            // Print the probabilities

            // First column: Which rent-generating properties are most landed upon

            // Second column: A rent-seeking player would be willing to accept a slightly
            // less frequently landed upon space, if it generates a much higher rent when
            // landed upon --> Multiply the landing probability per turn by the rent per landing

            // Third column: A clever investor cares not only about cash flow, but
            // also about the return on his investment (ROI), that is the rent generated
            // per dollar paid --> Divide the rent per turn by the property price

            for (int i = 0; i < n; i++)
            {
                Console.WriteLine("{0,-24} {1:f4} {2:f4} {3:f4}", spaces[i].Name, p[i], p[i] * spaces[i].Rent, p[i] * spaces[i].Rent / spaces[i].Price);
            }

            // First column: Which rent-generating properties are most landed upon:
            // Illinois Avenue (3.2%) and New York Avenue (3.1%), followed by Tennessee, the Reading, and the B & O (2.9% each).

            // Second column: A rent-seeking player would be willing to accept a slightly less frequently landed upon space,
            // if it generates a much higher rent when landed upon. To know which spaces maximize rent per turn,
            // we need to multiply the landing probability per turn by the rent per landing.
            // Boardwalk ($1.32/turn) is far and away the most rent-generating property to own

            // Third column: Finally, a clever investor cares not only about cash flow, but also about the return on his
            // investment (ROI), that is the rent generated per dollar paid. Dividing the rent per turn by
            // the property price changes the picture yet again. By this metric, the best values on the board
            // are the utilities, followed by the railways.

            Console.ReadLine();
        }
示例#6
0
        /// <summary>Finds the least squares solution of <c>A*X = B</c>, where <c>m &gt;= n</c></summary>
        /// <param name="B">A matrix with as many rows as A and any number of columns.</param>
        /// <returns>X that minimizes the two norm of <c>Q*R*X-B</c>.</returns>
        /// <exception cref="ArgumentException">Matrix row dimensions must agree.</exception>
        /// <exception cref="InvalidOperationException">Matrix is rank deficient or <c>m &lt; n</c>.</exception>
        public ComplexDoubleMatrix Solve(ComplexDoubleMatrix B)
        {
            if (B.RowLength != matrix.Rows)
            {
                throw new ArgumentException("Matrix row dimensions must agree.");
            }
            if (matrix.Rows < matrix.Columns)
            {
                throw new System.InvalidOperationException("A must have at lest as a many rows as columns.");
            }
            Compute();
            if (!isFullRank)
            {
                throw new System.InvalidOperationException("Matrix is rank deficient.");
            }

            // Copy right hand side
            int m   = matrix.Rows;
            int n   = matrix.Columns;
            int nx  = B.ColumnLength;
            var ret = new ComplexDoubleMatrix(n, nx);

#if MANAGED
            var X = new ComplexDoubleMatrix(B);
            // Compute Y = transpose(Q)*B
            var column = new Complex[q_.RowLength];
            for (int j = 0; j < nx; j++)
            {
                for (int k = 0; k < m; k++)
                {
                    column[k] = X.data[k][j];
                }
                for (int i = 0; i < m; i++)
                {
                    Complex s = Complex.Zero;
                    for (int k = 0; k < m; k++)
                    {
                        s += ComplexMath.Conjugate(q_.data[k][i]) * column[k];
                    }
                    X.data[i][j] = s;
                }
            }

            // Solve R*X = Y;
            for (int k = n - 1; k >= 0; k--)
            {
                for (int j = 0; j < nx; j++)
                {
                    X.data[k][j] /= r_.data[k][k];
                }
                for (int i = 0; i < k; i++)
                {
                    for (int j = 0; j < nx; j++)
                    {
                        X.data[i][j] -= X.data[k][j] * r_.data[i][k];
                    }
                }
            }
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < nx; j++)
                {
                    ret.data[i][j] = X.data[i][j];
                }
            }
#else
            Complex[] c = new Complex[B.data.Length];
            Array.Copy(B.data, 0, c, 0, B.data.Length);
            Lapack.Unmqr.Compute(Lapack.Side.Left, Lapack.Transpose.ConjTrans, m, nx, n, qr, m, tau, c, m);
            Blas.Trsm.Compute(Blas.Order.ColumnMajor, Blas.Side.Left, Blas.UpLo.Upper, Blas.Transpose.NoTrans, Blas.Diag.NonUnit,
                              n, nx, 1, qr, m, c, m);

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < nx; j++)
                {
                    ret.data[j * n + i] = c[j * m + (jpvt[i] - 1)];
                }
            }
#endif
            return(ret);
        }
示例#7
0
文件: Form1.cs 项目: samotnij/holo
            public bool MakeSnaps(int _snapsize, int _snapcount, string _path, int smooth_size)
            {
                try
                {
                    using (Mp3FileReader pcm = new Mp3FileReader(_path))
                    {
                        int samplesDesired = _snapsize;
                        int blockscount    = _snapcount;

                        snap_size     = _snapsize;
                        snap_count    = _snapcount;
                        total_samples = pcm.Length;
                        length        = pcm.TotalTime.Seconds;
                        path          = _path;

                        if ((pcm.WaveFormat.SampleRate != 44100) || (pcm.WaveFormat.BitsPerSample != 16))
                        {
                            return(false);
                        }

                        for (int i = 0; i < blockscount; i++)
                        {
                            byte[]   buffer = new byte[samplesDesired * 4];
                            short[]  left   = new short[samplesDesired];
                            short[]  right  = new short[samplesDesired];
                            double[] leftd  = new double[samplesDesired];
                            double[] rightd = new double[samplesDesired];

                            int bytesRead = 0;

                            //for (int j = 0; j < 1; j++) ///////////
                            int seek_counter = 0;
                            seek : pcm.Seek((i + 1) * (i + 1) * (i + 1) * blockscount * samplesDesired % (total_samples - samplesDesired), SeekOrigin.Begin);
                            seek_counter++;

                            bytesRead = pcm.Read(buffer, 0, 4 * samplesDesired);

                            int index = 0;
                            for (int sample = 0; sample < bytesRead / 4; sample++)
                            {
                                left[sample]  = BitConverter.ToInt16(buffer, index); index += 2;
                                right[sample] = BitConverter.ToInt16(buffer, index); index += 2;
                            }

                            if (left.Average(t => Math.Abs(t)) == 0)
                            {
                                if (seek_counter > 5)
                                {
                                    return(false);
                                }
                                else
                                {
                                    goto seek;
                                }
                            }

                            //snap_log10_energy.Add(Math.Log10(left.Average(t => Math.Abs(t))));

                            leftd  = Normalize(left, left.Length);
                            rightd = Normalize(right, right.Length);

                            //alglib.complex[] fl;
                            //alglib.fftr1d(leftd, out fl);
                            //fl[0].x;

                            FourierTransformer ft = new FourierTransformer(samplesDesired);
                            var xxa = new Complex[leftd.Length];

                            for (int j = 0; j < leftd.Length; j++)
                            {
                                xxa[j] = new Complex(leftd[j], rightd[j]);
                            }

                            var ftt = ft.Transform(xxa);

                            List <double> pow_re_im = new List <double>();
                            //List<double> arg_re_im = new List<double>();

                            ftt.ToList().ForEach(t => pow_re_im.Add(ComplexMath.Abs(t)));
                            //ftt.ToList().ForEach(t => arg_re_im.Add(ComplexMath.Arg(t)));

                            /*if (Double.IsNaN(MC_Log10_Energy(pow_re_im)))
                             *  if (seek_counter > 5)
                             *      return false;
                             *  else
                             *      goto seek;*/

                            fft_snaps.Add(pow_re_im);
                            //fft_smoothed_snaps.Add(Smoothen(pow_re_im, smooth_size));

                            //pow_re_im = Normalize(pow_re_im);

                            /*
                             * var f_pwri = pow_re_im.Average(t => Math.Abs(t));
                             * for (int k = 0; k < pow_re_im.Count; k++)
                             *  pow_re_im[k] = (Math.Abs(pow_re_im[k]) >= f_pwri * 1.5) ? pow_re_im[k] : 0;
                             */

                            /*
                             * FourierTransformer ft2 = new FourierTransformer(samplesDesired);
                             * var xx2 = new List<Complex>();
                             * for (int j = 0; j < pow_re_im.Count; j++)
                             * {
                             *  xx2.Add(new Complex(pow_re_im[j], arg_re_im[j]));
                             * }
                             * var ftt2 = ft2.Transform(xx2);
                             * //var ftt2 = ft2.Transform(ftt);
                             *
                             * List<double> pow_re_im2 = new List<double>();
                             * ftt2.ToList().ForEach(t => pow_re_im2.Add(ComplexMath.Abs(t)));
                             * pow_re_im2 = Normalize(pow_re_im2);
                             * fft2_snaps.Add(pow_re_im2);
                             * fft2_smoothed_snaps.Add(Smoothen(pow_re_im2, smooth_size));
                             */
                        }
                        pcm.Close();
                    }
                }
                catch (Exception e)
                {
                    return(false);
                }

                return(true);
            }
 private static Complex ComplexTestFunction(
     double x
     )
 {
     return(ComplexMath.Exp(new Complex(-x, -x)));
 }
示例#9
0
        /// <summary>
        /// Wyznacza pierwiastek Z wielomianu stopnia N o współczynnikach
        /// zapisanych w wektorze FW[i]
        /// </summary>
        /// <param name="N">Stopień wielomianu </param>
        /// <param name="FW">Wektor współczynników wielomianu</param>
        /// <param name="Z">Pierwiastek wielomianu</param>
        /// <param name="eps"> dokładność bezwzględna iteracji  np. eps=1E-16</param>
        /// <param name="maxit">ustalona maksymalna liczba iteracji kończąca obliczenia</param>
        /// <returns>return - nr błędu; 0 - brak błędu.</returns>
        private static int Laguerre(int N, double[] FW, ref Complex.Complex Z, double eps, int maxit)
        {
            Complex.Complex B, C, D, S, H, M1, M2;
            double          MM1, MM2, Alfa, Nx, LL, MM;
            int             N1, i, k, Blad;

            Blad = 0;
            if (FW[0] == 0)
            {
                Blad = 1;
            }
            else
            {
                if (FW[N] == 0)
                {
                    Z = new Complex.Complex(0, 0);
                }
                else
                {
                    N1 = N - 1;   k = 0;
                    do
                    {  //Wyznaczanie wartości wielomianu i ich pochodnych pierwszego
                       // i drugiego rodzaju wg algorytmu Hornera (4.76)
                        B = new Complex.Complex(FW[0], 0);
                        C = B; D = B;
                        for (i = 1; i <= N; i++)
                        {
                            if (i <= N - 2)
                            {
                                S  = B * Z;   S += FW[i];    B = S;
                                C *= Z;  C += B;
                                D *= Z;  D += C;
                            }
                            else
                            {
                                if (i <= N - 1)
                                {
                                    S  = B * Z;  S += FW[i];  B = S;
                                    C *= Z;   C += B;
                                }
                                else
                                {
                                    S = B * Z;   S += FW[i];  B = S;
                                }
                            }
                        }
                        D *= 2.0;
                        //Konstukcja wzoru rekurencyjnego (4.74)
                        Nx = N1;
                        H  = C * C;  H *= Nx;
                        Nx = N;
                        S  = B * D; S *= Nx;
                        // H - wg wzoru (4.75)
                        Nx  = N1;
                        H  -= S;  H *= Nx;
                        H   = ComplexMath.Sqrt(H);
                        M1  = B / (C + H);  M2 = B / (C - H);
                        MM1 = ComplexMath.Abs(M1); MM2 = ComplexMath.Abs(M2); Nx = N;
                        if (MM1 > MM2)
                        {
                            H = M2 * Nx;
                        }
                        else
                        {
                            H = M1 * Nx;
                        }
                        Z   -= H;   k++;
                        LL   = ComplexMath.Abs(H); MM = ComplexMath.Abs(Z);
                        Alfa = LL / MM;
                    }while (!(Alfa < eps || k > maxit));
                    if (k > maxit)
                    {
                        Blad = 3;
                    }
                }
            }
            return(Blad);
        }//Laguerre
示例#10
0
 public void PowerOfTwoRoundDown()
 {
     Assert.AreEqual(512, ComplexMath.RoundDownP2(600));
 }
示例#11
0
 public void PowerOfTwoRoundDown1024()
 {
     Assert.AreEqual(1024, ComplexMath.RoundDownP2(1024));
 }
示例#12
0
 public void PowerOfTwoRoundDown0()
 {
     Assert.AreEqual(0, ComplexMath.RoundDownP2(0));
 }
示例#13
0
 public static Complex LogGamma(Complex z)
 {
     return((z - 0.5) * ComplexMath.Log(z) - z + halfLogTwoPi + Sum(z));
 }
示例#14
0
        /// <summary>Performs the LU factorization.</summary>
        protected override void InternalCompute()
        {
#if MANAGED
            factor = new ComplexFloatMatrix(matrix).data;
            int m = matrix.RowLength;
            int n = matrix.ColumnLength;
            pivots = new int[m];
            for (int i = 0; i < m; i++)
            {
                pivots[i] = i;
            }
            sign = 1;
            ComplexFloat[] LUrowi;
            ComplexFloat[] LUcolj = new ComplexFloat[m];

            // Outer loop.
            for (int j = 0; j < n; j++)
            {
                // Make a copy of the j-th column to localize references.
                for (int i = 0; i < m; i++)
                {
                    LUcolj[i] = factor[i][j];
                }

                // Apply previous transformations.
                for (int i = 0; i < m; i++)
                {
                    LUrowi = factor[i];

                    // Most of the time is spent in the following dot product.
                    int          kmax = System.Math.Min(i, j);
                    ComplexFloat s    = ComplexFloat.Zero;
                    for (int k = 0; k < kmax; k++)
                    {
                        s += LUrowi[k] * LUcolj[k];
                    }

                    LUrowi[j] = LUcolj[i] -= s;
                }

                // Find pivot and exchange if necessary.
                int p = j;
                for (int i = j + 1; i < m; i++)
                {
                    if (ComplexMath.Absolute(LUcolj[i]) > ComplexMath.Absolute(LUcolj[p]))
                    {
                        p = i;
                    }
                }
                if (p != j)
                {
                    for (int k = 0; k < n; k++)
                    {
                        ComplexFloat t = factor[p][k];
                        factor[p][k] = factor[j][k];
                        factor[j][k] = t;
                    }
                    int r = pivots[p];
                    pivots[p] = pivots[j];
                    pivots[j] = r;
                    sign      = -sign;
                }

                // Compute multipliers.

                if (j < m & factor[j][j] != ComplexFloat.Zero)
                {
                    for (int i = j + 1; i < m; i++)
                    {
                        factor[i][j] /= factor[j][j];
                    }
                }
            }
#else
            factor = new ComplexFloat[matrix.data.Length];
            Array.Copy(matrix.data, factor, matrix.data.Length);
            Lapack.Getrf.Compute(order, order, factor, order, out pivots);
            GetSign();
#endif
            SetLU();

            this.singular = false;
            for (int j = 0; j < u.RowLength; j++)
            {
                if (u[j, j] == 0)
                {
                    this.singular = true;
                    break;
                }
            }
        }
示例#15
0
        private static Complex csign(Complex z1, Complex z2)
        {
            Complex ret = ComplexMath.Absolute(z1) * (z2 / ComplexMath.Absolute(z2));

            return(ret);
        }
示例#16
0
        internal static void Compute(Order order, Transpose transA, int m, int n, Complex alpha, Complex[] A, int lda, Complex[] X, int incx, Complex beta, Complex[] Y, int incy)
        {
            ArgumentCheck(order, transA, m, n, A, A.Length, lda, X, X.Length, ref incx, Y, Y.Length, ref incy);

#if MANAGED
            int lenX = m;
            int lenY = n;

            if (transA == Transpose.NoTrans)
            {
                lenX = n;
                lenY = m;
            }
            if (beta == Complex.Zero)
            {
                for (int i = 0, iy = 0; i < lenY; ++i, iy += incy)
                {
                    Y[iy] = 0;
                }
            }
            else if (beta != Complex.One)
            {
                for (int i = 0, iy = 0; i < lenY; ++i, iy += incy)
                {
                    Y[iy] *= beta;
                }
            }
            if (alpha == Complex.Zero)
            {
                return;
            }
            Complex add_val = new Complex(0);
            if ((order == Order.RowMajor && transA == Transpose.NoTrans) ||
                (order == Order.ColumnMajor && transA == Transpose.Trans))
            {
                for (int i = 0, iy = 0; i < lenY; ++i, iy += incy)
                {
                    add_val = 0;
                    for (int j = 0, jx = 0; j < lenX; ++j, jx += incx)
                    {
                        add_val += X[jx] * A[i * lda + j];
                    }
                    Y[iy] += alpha * add_val;
                }
            }
            else if ((order == Order.RowMajor && transA == Transpose.Trans) ||
                     (order == Order.ColumnMajor && transA == Transpose.NoTrans))
            {
                for (int j = 0, jx = 0; j < lenX; ++j, jx += incx)
                {
                    add_val = alpha * X[jx];
                    if (add_val != Complex.Zero)
                    {
                        for (int i = 0, iy = 0; i < lenY; ++i, iy += incy)
                        {
                            Y[iy] += add_val * A[j * lda + i];
                        }
                    }
                }
            }
            else if (order == Order.RowMajor && transA == Transpose.ConjTrans)
            {
                for (int j = 0, jx = 0; j < lenX; ++j, jx += incx)
                {
                    add_val = alpha * X[jx];
                    if (add_val != Complex.Zero)
                    {
                        for (int i = 0, iy = 0; i < lenY; ++i, iy += incy)
                        {
                            Y[iy] += add_val * ComplexMath.Conjugate(A[j * lda + i]);
                        }
                    }
                }
            }
            else
            {
                for (int i = 0, iy = 0; i < lenY; ++i, iy += incy)
                {
                    add_val = 0;
                    for (int j = 0, jx = 0; j < lenX; ++j, jx += incx)
                    {
                        add_val += X[jx] * ComplexMath.Conjugate(A[i * lda + j]);
                    }
                    Y[iy] += alpha * add_val;
                }
            }
#else
            dna_blas_zgemv(order, transA, m, n, ref alpha, A, lda, X, incx, ref beta, Y, incy);
#endif
        }
示例#17
0
        static void Main(string[] args)
        {
            SquareMatrix T = new SquareMatrix(3);

            // Construct the transition matrix for the weather.
            T[0, 0] = 0.5; // sunny to sunny
            T[1, 0] = 0.4; // sunny to rainy
            T[2, 0] = 0.1; // sunny to cloudy

            T[0, 1] = 0.3; // rainy to sunny
            T[1, 1] = 0.4; // rainy to rainy
            T[2, 1] = 0.3; // rainy to cloudy

            T[0, 2] = 0.2; // cloudy to sunny
            T[1, 2] = 0.3; // cloudy to rainy
            T[2, 2] = 0.5; // cloudy to cloudy

            // verify Markov conditions
            for (int c = 0; c < T.Dimension; c++)
            {
                double sr = 0.0;
                for (int r = 0; r < T.Dimension; r++)
                {
                    sr += T[r, c];
                }
                Debug.Assert(Math.Abs(sr - 1.0) < 1.0e-15);
            }

            // Begin with some initial state vector, and repeatedly
            // apply P until the resultant vector no longer changes.
            // The resultant vector will be the dominant eigenvector.
            ComplexEigensystem E = T.Eigensystem();

            Complex         e     = -1.0;
            IList <Complex> v     = null;
            Complex         maxEI = E.Eigenvalue(0);

            v = E.Eigenvector(0);

            // Find the dominant eigenvector
            for (int i = 1; i < E.Dimension; i++)
            {
                Complex ei = E.Eigenvalue(i);
                if (ComplexMath.Abs(ei) > ComplexMath.Abs(maxEI))
                {
                    maxEI = ei;
                    v     = E.Eigenvector(i);
                }
            }

            // verify that it has eigenvalue 1 and is real
            Debug.Assert(Math.Abs(maxEI.Re - 1.0) < 1.0e-15);
            Debug.Assert(maxEI.Im == 0.0);
            for (int i = 0; i < 3; i++)
            {
                Debug.Assert(v[i].Im == 0.0);
            }

            // normalize the probabilities
            double sv = 0.0;

            for (int i = 0; i < E.Dimension; i++)
            {
                sv += v[i].Re;
            }
            double[] p = new double[E.Dimension];
            for (int i = 0; i < E.Dimension; i++)
            {
                p[i] = v[i].Re / sv;
            }

            // print the probabilities (steady state of the weather)
            Console.Write("Sunny = ");
            Console.WriteLine(p[0]);
            Console.Write("Rainy = ");
            Console.WriteLine(p[1]);
            Console.Write("Cloudy = ");
            Console.WriteLine(p[2]);
            Console.ReadLine();
        }