/// <summary>
        /// Computes the Riemann zeta function for complex values.
        /// </summary>
        /// <param name="z">The argument.</param>
        /// <returns>The value of &#x3B6;(z).</returns>
        /// <remarks>
        /// <para>As the imaginary part of the argument increases, the computation of the zeta function becomes slower and more difficult.
        /// The computation time is approximately proprotional to the imaginary part of z. The result also slowly looses accuracy for arguments with
        /// very large imaginary parts; for arguments with z.Im of order 10^d, approximately the last d digits of the result are suspect.</para>
        /// <para>The image below shows the complex &#x393; function near the origin using domain coloring. You can see the first non-trivial
        /// zeros at (1/2, &#177;14.13...) as well as the trivial zeros along the negative real axis.</para>
        /// <img src="../images/ComplexRiemannZetaPlot.png" />
        /// </remarks>
        public static Complex RiemannZeta(Complex z)
        {
            // Use conjugation and reflection symmetry to move to the first quadrant.
            if (z.Im < 0.0)
            {
                return(RiemannZeta(z.Conjugate).Conjugate);
            }
            if (z.Re < 0.0)
            {
                Complex zp = Complex.One - z;
                return(2.0 * ComplexMath.Pow(Global.TwoPI, -zp) * ComplexMath.Cos(Global.HalfPI * zp) * AdvancedComplexMath.Gamma(zp) * RiemannZeta(zp));
            }

            // Close to pole, use Laurent series.
            Complex zm1 = z - Complex.One;

            if (ComplexMath.Abs(zm1) < 0.50)
            {
                return(RiemannZeta_LaurentSeries(zm1));
            }

            // Fall back to Euler-Maclaurin summation.
            int n = RiemannZeta_EulerMaclaurin_N(z.Re, z.Im);

            return(RiemannZeta_EulerMaclaurin(z, n));
        }
Esempio n. 2
0
        private static double GetMaxDeviation(
            double[] xValues,
            Complex[] yValues,
            Complex[] analyticValues
            )
        {
            double maxDeviation = 0;
            double currentDeviation;

            for (int i = 0; i < yValues.Length; i++)
            {
                currentDeviation = ComplexMath.Abs(yValues[i] - analyticValues[i]);

                if (double.IsNaN(currentDeviation) ||
                    double.IsInfinity(currentDeviation))
                {
                    return(currentDeviation);
                }

                if (currentDeviation > maxDeviation)
                {
                    maxDeviation = currentDeviation;
                }
            }

            return(maxDeviation);
        }
        private static void AssertMaxDeviationBelow(
            double accuracy,
            double[] xValues,
            Complex[] yValues,
            Complex[] analyticValues
            )
        {
            double deviation;

            for (int i = 0; i < yValues.Length; i++)
            {
                deviation = ComplexMath.Abs(yValues[i] - analyticValues[i]);

                if (double.IsNaN(deviation) ||
                    double.IsInfinity(deviation))
                {
                    Assert.Fail();
                }

                Assert.IsTrue(deviation < accuracy,
                              string.Format("Max. tolerated deviation: {0}" + Environment.NewLine
                                            + "Actual deviation: {1}." + Environment.NewLine
                                            + "This occurred at position x = {2}",
                                            accuracy, deviation, xValues[i]));
            }
        }
Esempio n. 4
0
        private bool IsConverging()
        {
            double[]  radius       = Solver.PositionValues;
            Complex[] waveFunction = Solver.SolutionValues;

            double lastValue    = ComplexMath.Abs(waveFunction[0]);
            double currentValue = ComplexMath.Abs(waveFunction[1]);
            double nextValue    = 0;

            for (int j = 1; j < waveFunction.Length - 1; j++)
            {
                nextValue = ComplexMath.Abs(waveFunction[j]);
                if (currentValue >= lastValue &&
                    currentValue >= nextValue)
                {
                    LastMaximum    = CurrentMaximum;
                    CurrentMaximum = FindExtremum(radius[j - 1], radius[j], radius[j + 1],
                                                  lastValue, currentValue, nextValue);

                    DegreeOfConvergence = Math.Abs(CurrentMaximum / LastMaximum - 1.0);
                    if (DegreeOfConvergence <= DesiredDegreeOfConvergence)
                    {
                        return(true);
                    }
                }
                lastValue    = currentValue;
                currentValue = nextValue;
            }

            return(false);
        }
Esempio n. 5
0
        /********************************************************************************************
        * Private/protected static members, functions and properties
        ********************************************************************************************/

        // utility function to get the norm |z|^2 of an arbitrary complex number z
        protected static double Norm(
            Complex z
            )
        {
            double abs = ComplexMath.Abs(z);

            return(abs * abs);
        }
 private void InitShootingSolver_SolutionConstraintViolated()
 {
     InitShootingSolver_ComplexEigenvalueProblem();
     ShootingSolver.SolutionConstraint = () =>
     {
         return(ComplexMath.Abs(ShootingSolver.Eigenvalue) < 1.999);
     };
 }
Esempio n. 7
0
        /// <summary>
        /// Computes the complex dilogarithm function, also called Spence's function.
        /// </summary>
        /// <param name="z">The complex argument.</param>
        /// <returns>The value Li<sub>2</sub>(z).</returns>
        /// <remarks>
        /// <para>This function is the analytic continuation of the dilogarithm function (<see cref="AdvancedMath.DiLog"/>) into the complex plane.</para>
        /// <para>The image below shows the complex dilogarithm function near the origin, using domain coloring.</para>
        /// <img src="../images/ComplexDiLogPlot.png" />
        /// </remarks>
        /// <seealso cref="AdvancedMath.DiLog"/>
        /// <seealso href="http://mathworld.wolfram.com/Dilogarithm.html" />
        public static Complex DiLog(Complex z)
        {
            Complex f;
            double  a0 = ComplexMath.Abs(z);

            if (a0 > 1.0)
            {
                // outside the unit disk, reflect into the unit disk
                Complex ln = ComplexMath.Log(-z);
                f = -Math.PI * Math.PI / 6.0 - ln * ln / 2.0 - DiLog(1.0 / z);
            }
            else
            {
                // inside the unit disk...
                if (a0 < 0.75)
                {
                    // close to 0, use the expansion about zero
                    f = DiLog_Series_0(z);
                }
                else
                {
                    // we are in the annulus near the edge of the unit disk
                    if (z.Re < 0.0)
                    {
                        // reflect negative into positive half-disk
                        // this avoids problems with the log expansion near -1
                        f = DiLog(z * z) / 2.0 - DiLog(-z);
                    }
                    else
                    {
                        // figure out whether we are close to 1
                        Complex e = 1.0 - z;
                        if (ComplexMath.Abs(e) < 0.5)
                        {
                            // close to 1, use the expansion about 1
                            f = DiLog_Series_1(e);
                        }
                        else
                        {
                            // otherwise, use the log expansion, which is good
                            // near the unit circle but not too close to 1 or -1
                            f = DiLog_Log_Series(z);
                        }
                    }
                }
            }

            if ((z.Re > 1.0) && (Math.Sign(f.Im) != Math.Sign(z.Im)))
            {
                f = f.Conjugate;
            }

            return(f);
        }
 private static void AssertDeviationBelow(
     double DesiredAccuracy,
     Complex complex1,
     Complex complex2
     )
 {
     Assert.IsTrue(ComplexMath.Abs(complex1 - complex2) < DesiredAccuracy,
                   string.Format("Calculated eigenvalue: {0}" + Environment.NewLine
                                 + "Expected eigenvalue: {1}" + Environment.NewLine
                                 + "Max. tolerated deviation: {2}",
                                 complex1, complex2, DesiredAccuracy));
 }
Esempio n. 9
0
        private double PotentialExpectationValue_fm()
        {
            Complex expectationValue = 0;

            for (int j = 1; j < Param.StepNumber; j++)
            {
                expectationValue += WaveFunctionNorm[j] * Potential_fm.Value(Radius_fm[j]);
            }
            expectationValue += 0.5 * WaveFunctionNorm[Param.StepNumber]
                                * Potential_fm.Value(Radius_fm[Param.StepNumber]);

            return(StepSize_fm * ComplexMath.Abs(expectationValue));
        }
Esempio n. 10
0
 protected void UpdateStatusValues()
 {
     if (StatusValues != null)
     {
         StatusValues[0] = Trials.ToString();
         StatusValues[1] = BoundMass_MeV.ToString("G12");
         StatusValues[2] = Param.SoftScale_MeV.ToString("G12");
         StatusValues[3] = Param.Energy_MeV.ToString("G12");
         StatusValues[4] = Param.GammaDamp_MeV.ToString("G12");
         StatusValues[5] = ComplexMath.Abs(WaveFunction_fm[0])
                           .ToString("G4");
         StatusValues[6] = NumberExtrema.ToString();
     }
 }
Esempio n. 11
0
 /// <summary>
 /// Compute the complex log Gamma function.
 /// </summary>
 /// <param name="z">The complex argument, which must have a non-negative real part.</param>
 /// <returns>The complex value ln(&#x393;(z)).</returns>
 /// <exception cref="ArgumentOutOfRangeException">The real part of <paramref name="z"/> is negative.</exception>
 /// <seealso cref="AdvancedMath.LogGamma" />
 public static Complex LogGamma(Complex z)
 {
     if (z.Re < 0.0)
     {
         throw new ArgumentOutOfRangeException("z");
     }
     else if (ComplexMath.Abs(z) < 16.0)
     {
         return(Lanczos.LogGamma(z));
     }
     else
     {
         return(LogGamma_Stirling(z));
     }
 }
        private void InitShootingSolver_SinExactInput()
        {
            DesiredAccuracy   = 1e-7;
            Aggressiveness    = 1;
            MaxShootingTrials = 1;

            InitRseSolver_SinExactInput();

            ShootingSolver = new RseShootingSolver
            {
                Solver                  = Solver,
                DesiredAccuracy         = DesiredAccuracy,
                Aggressiveness          = Aggressiveness,
                SolutionAccuracyMeasure = () => ComplexMath.Abs(Solver.SolutionValues[5000])
            };
        }
Esempio n. 13
0
 /// <summary>
 /// Computes the complex Gamma function.
 /// </summary>
 /// <param name="z">The complex argument.</param>
 /// <returns>The complex value of &#x393;(z).</returns>
 /// <remarks>
 /// <para>The image below shows the complex &#x393; function near the origin using domain coloring.</para>
 /// <img src="../images/ComplexGammaPlot.png" />
 /// </remarks>
 /// <seealso cref="AdvancedMath.Gamma(double)"/>
 /// <seealso href="http://en.wikipedia.org/wiki/Gamma_function" />
 /// <seealso href="http://mathworld.wolfram.com/GammaFunction.html" />
 public static Complex Gamma(Complex z)
 {
     if (z.Re < 0.5)
     {
         // 1-z form
         return(Math.PI / Gamma(1.0 - z) / ComplexMath.SinPi(z));
     }
     else if (ComplexMath.Abs(z) < 16.0)
     {
         return(Lanczos.Gamma(z));
     }
     else
     {
         // Add flag to do z-reduction
         return(ComplexMath.Exp(LogGamma_Stirling(z)));
     }
 }
Esempio n. 14
0
        // in fm^3
        private double RadialOverlapIntegral(
            double energy_MeV
            )
        {
            int l = BoundParam.QuantumNumberL;

            if (l == 0)
            {
                return(Math.Pow(ComplexMath.Abs(RadialOverlapIntegral(energy_MeV, 1)), 2));
            }
            else
            {
                return(((l + 1) * Math.Pow(ComplexMath.Abs(RadialOverlapIntegral(energy_MeV, l + 1)), 2)
                        + l * Math.Pow(ComplexMath.Abs(RadialOverlapIntegral(energy_MeV, l - 1)), 2))
                       / (2 * l + 1.0));
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Computes the complex Faddeeva function.
        /// </summary>
        /// <param name="z">The complex argument.</param>
        /// <returns>The complex value of w(z).</returns>
        /// <remarks>
        /// <para>The Faddeeva function w(z) is related to the error function with a complex argument.</para>
        /// <img src="../images/FaddeevaErfcRelation.png" />
        /// <para>It also has an integral representation.</para>
        /// <img src="../images/FaddeevaIntegral.png" />
        /// <para>For purely imaginary values, it reduces to the complementary error function (<see cref="AdvancedMath.Erfc"/>).
        /// For purely real values, it reduces to Dawson's integral (<see cref="AdvancedMath.Dawson"/>).</para>
        /// <para>It appears in the computation of the Voigt line profile function V(x;&#x3C3;,&#x3B3;).</para>
        /// <img src="../images/Voigt.png" />
        /// <para>Near the origin, w(z) &#x2248; 1. To accurately determine w(z) - 1 in this region, use the <see cref="Erf"/>
        /// function. Away from the origin near the large negative imaginary axis, the magnitude w(z) increases rapidly and
        /// may overflow.</para>
        /// <para>The image below shows the complex Faddeeva function near the origin, using domain coloring.</para>
        /// <img src="../images/ComplexFaddeevaPlot.png" />
        /// </remarks>
        /// <seealso cref="AdvancedComplexMath.Erf"/>
        /// <seealso cref="AdvancedMath.Erf" />
        /// <seealso cref="AdvancedMath.Erfc" />
        /// <seealso cref="AdvancedMath.Dawson"/>
        /// <seealso href="http://en.wikipedia.org/wiki/Voigt_profile" />
        public static Complex Faddeeva(Complex z)
        {
            // use reflection formulae to ensure that we are in the first quadrant
            if (z.Im < 0.0)
            {
                return(2.0 * ComplexMath.Exp(-z * z) - Faddeeva(-z));
            }
            if (z.Re < 0.0)
            {
                return(Faddeeva(-z.Conjugate).Conjugate);
            }

            double r = ComplexMath.Abs(z);

            if (r < 2.0)
            {
                // use series for small z
                return(ComplexMath.Exp(-z * z) * (1.0 - Erf_Series(-ComplexMath.I * z)));
                //return (Faddeeva_Series(z));
            }
            else if ((z.Im < 0.1) && (z.Re < 30.0))
            {
                // this is a special, awkward region
                // along the real axis, Re{w(x)} ~ e^{-x^2}; the Weideman algorthm doesen't compute this small number
                // well and the Laplace continued fraction misses it entirely; therefore very close to the real axis
                // we will use an analytic result on the real axis and Taylor expand to where we need to go.
                // unfortunately the Taylor expansion converges poorly for large x, so we drop this work-arround near x~30,
                // when this real part becomes too small to represent as a double anyway
                double x = z.Re;
                double y = z.Im;
                return(Faddeeva_Taylor(new Complex(x, 0.0),
                                       Math.Exp(-x * x) + 2.0 * AdvancedMath.Dawson(x) / Global.SqrtPI * ComplexMath.I,
                                       new Complex(0.0, y)));
            }
            else if (r > 7.0)
            {
                // use Laplace continued fraction for large z
                return(Faddeeva_ContinuedFraction(z));
            }
            else
            {
                // use Weideman algorithm for intermediate region
                return(Faddeeva_Weideman(z));
            }
        }
        private void InitShootingSolver_ComplexEigenvalueProblem()
        {
            DesiredAccuracy   = 1e-7;
            Aggressiveness    = 0.2;
            MaxShootingTrials = 100;

            InitRseSolver_ComplexEigenvalueProblem();

            ShootingSolver = new RseShootingSolver
            {
                Solver                  = Solver,
                DesiredAccuracy         = DesiredAccuracy,
                Aggressiveness          = Aggressiveness,
                MaxTrials               = MaxShootingTrials,
                Eigenvalue              = new Complex(0.3, -1.5),
                SolutionAccuracyMeasure = () => ComplexMath.Abs(Solver.SolutionValues[10000] - ComplexTestFunction(Math.PI))
            };
        }
Esempio n. 17
0
 private void InitShootingSolver()
 {
     ShootingSolver = new RseShootingSolver
     {
         Solver                  = Solver,
         DesiredAccuracy         = DesiredAccuracyWaveFunction,
         Aggressiveness          = Param.AggressivenessEnergy,
         MaxTrials               = Param.MaxShootingTrials - Trials,
         Eigenvalue              = GetEigenvalue(),
         CancellationToken       = CalculationCancelToken,
         SolutionConstraint      = () => NumberExtrema == QuantumNumberN - Param.QuantumNumberL,
         SolutionAccuracyMeasure = () => ComplexMath.Abs(WaveFunction_fm[0]),
         ActionAfterIteration    = () =>
         {
             Trials++;
             UpdateWaveFunction();
             UpdateEigenvalue();
             UpdateStatusValues();
         }
     };
 }
Esempio n. 18
0
        public static Complex AiryAi_Asymptotic(Complex z)
        {
            Debug.Assert(ComplexMath.Abs(z) >= 9.0);

            if (z.Re >= 0.0)
            {
                Complex xi = 2.0 / 3.0 * ComplexMath.Pow(z, 3.0 / 2.0);
                Airy_Asymptotic_Subseries(xi, out Complex u0, out Complex v0, out Complex u1, out Complex v1);
                Complex e = ComplexMath.Exp(xi);
                Complex q = ComplexMath.Pow(z, 1.0 / 4.0);
                return(0.5 / Global.SqrtPI / q / e * u1);
            }
            else
            {
                z = -z;
                Complex xi = 2.0 / 3.0 * ComplexMath.Pow(z, 3.0 / 2.0);
                Airy_Asymptotic_Subseries(xi, out Complex u0, out Complex v0, out Complex u1, out Complex v1);
                Complex c = ComplexMath.Cos(xi);
                Complex s = ComplexMath.Sin(xi);

                throw new NotImplementedException();
            }
        }
Esempio n. 19
0
        private void Normalize(
            Complex[] solution,
            double stepSize,
            double n
            )
        {
            double integral = 0;
            int    maxIndex = solution.Length - 1;

            for (int i = 1; i < maxIndex; i++)
            {
                integral += ComplexMath.Abs(solution[i]) * ComplexMath.Abs(solution[i]);
            }
            integral += 0.5 * (ComplexMath.Abs(solution[0]) * ComplexMath.Abs(solution[0])
                               + ComplexMath.Abs(solution[maxIndex]) * ComplexMath.Abs(solution[maxIndex]));
            integral *= stepSize * n / 2.0;             // xn = 2*C1*r/n

            double sqrtIntegral = Math.Sqrt(integral);

            for (int j = 0; j <= maxIndex; j++)
            {
                solution[j] /= sqrtIntegral;
            }
        }
Esempio n. 20
0
        /// <summary>
        /// Computes the complex error function.
        /// </summary>
        /// <param name="z">The complex argument.</param>
        /// <returns>The value of erf(z).</returns>
        /// <remarks>
        /// <para>This function is the analytic continuation of the error function (<see cref="AdvancedMath.Erf"/>) to the complex plane.</para>
        /// <para>The image below shows the complex error function near the origin, using domain coloring.</para>
        /// <img src="../images/ComplexErfPlot.png" />
        /// <para>The complex error function is entire: it has no poles, cuts, or discontinuities anywhere in the complex plane.</para>
        /// <para>For pure imaginary arguments, erf(z) reduces to the Dawson integral (<see cref="AdvancedMath.Dawson"/>).</para>
        /// <para>Away from the origin near the real axis, the real part of erf(z) quickly approaches &#x0b1;1. To accurately determine
        /// the small difference erf(z) &#8723; 1 in this region, use the <see cref="Faddeeva"/> function. Away from the origin near
        /// the imaginary axis, the magnitude of erf(z) increases very quickly. Although erf(z) may overflow in this region, you
        /// can still accurately determine the value of the product erf(z) exp(z<sup>2</sup>) using the <see cref="Faddeeva"/>
        /// function.</para>
        /// </remarks>
        /// <seealso cref="AdvancedMath.Erf"/>
        /// <seealso cref="AdvancedMath.Dawson"/>
        /// <seealso cref="AdvancedComplexMath.Faddeeva"/>
        public static Complex Erf(Complex z)
        {
            double r = ComplexMath.Abs(z);

            if (r < 4.0)
            {
                // near the origin, use the series
                return(Erf_Series(z));
            }
            else
            {
                // otherwise, just compute from Faddeva
                if (z.Re < 0.0)
                {
                    // since Fadddeeva blows up for negative z.Re, use erf(z) = -erf(-z)
                    return(ComplexMath.Exp(-z * z) * Faddeeva(-ComplexMath.I * z) - 1.0);
                }
                else
                {
                    return(1.0 - ComplexMath.Exp(-z * z) * Faddeeva(ComplexMath.I * z));
                }
                // we don't do this near the origin beause we would loose accuracy in the very small real parts there by subtracting from 1
            }
        }
Esempio n. 21
0
        }// PRW2

        //----------------------------------------------------------------------------

        /// <summary>
        /// Przestawianie pierwiastków wg wzrastajacych modułów
        /// </summary>
        /// <param name="FZ">Wektor zespolony zer wielomianu</param>
        /// <param name="N">Stopień wielomianu</param>
        public static void PrzestawPierwiastki(Complex.Complex[] FZ, int N)
        {
            int    i, j, k;
            double X1, X;

            Complex.Complex Z;
            for (i = 1; i <= N; i++)
            {
                X = ComplexMath.Abs(FZ[i]); k = i;
                for (j = i + 1; j <= N; j++)
                {
                    X1 = ComplexMath.Abs(FZ[j]);
                    if (X1 < X)
                    {
                        X = X1; k = j;
                    }
                }
                if (k != i)
                {
                    Z = FZ[i]; FZ[i] = FZ[k]; FZ[k] = Z;
                }
                //swap(FZ[i],FZ[k]);
            }
        }//PrzestawPierwiastki
Esempio n. 22
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();
        }
Esempio n. 23
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
Esempio n. 24
0
        public bool MakeSnaps(int snapsize, int snapcount, string path)
        {
            try
            {
                SnapSize  = snapsize;
                SnapCount = snapcount;
                Path      = path;

                using (var pcm = new Mp3FileReader(path))
                {
                    Length       = pcm.TotalTime.Seconds;
                    TotalSamples = pcm.Length;

                    int samplesDesired = snapsize;
                    int blockscount    = snapcount;

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

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

                        int seekCounter = 0;

                        while (seekCounter <= 5)
                        {
                            pcm.Seek((i + 1) * (i + 1) * (i + 1) * blockscount * samplesDesired % (TotalSamples - samplesDesired), SeekOrigin.Begin);
                            seekCounter++;

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

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

                            if (left.Average(t => Math.Abs(t)) != 0)
                            {
                                break;
                            }
                        }

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

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

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

                        var ftt       = ft.Transform(xxa);
                        var pow_re_im = new List <double>(ftt.Length);
                        for (int j = 0; j < ftt.Length; ++j)
                        {
                            pow_re_im.Add(ComplexMath.Abs(ftt[j]));
                        }
                        fft_snaps.Add(pow_re_im);
                    }
                    pcm.Close();
                }
            }
            catch (Exception)
            {
                return(false);
            }

            return(true);
        }
Esempio n. 25
0
            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 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();
        }