Esempio n. 1
0
        internal static List <fsValue> SolveC1Xp1C2Xp2C3Xp3C4(fsValue c1, fsValue p1, fsValue c2, fsValue p2, fsValue c3, fsValue p3, fsValue c4)
        {
            List <fsValue> breakPoints = SolveC1Xp1C2Xp2C3(c1 * p1, p1 - p3, c2 * p2, p2 - p3, c3 * p3, Infinity);

            while (breakPoints.Count > 0 && breakPoints[0] == Zero)
            {
                breakPoints.RemoveAt(0);
            }
            breakPoints.Insert(0, Zero);
            breakPoints.Add(Infinity);

            const int interations = 100;  // precision is 1e20 / 2^100 ~~ 1e-11

            var result = new List <fsValue>();

            for (int i = 1; i < breakPoints.Count; ++i)
            {
                fsValue localRoot = fsBisectionMethod.FindRoot(
                    new fsFunctionC1Xp1C2Xp2C3P3C4(c1, p1, c2, p2, c3, p3, c4),
                    breakPoints[i - 1], breakPoints[i], interations);
                if (localRoot.Defined)
                {
                    result.Add(localRoot);
                }
            }

            result.Sort();
            return(result);
        }
Esempio n. 2
0
        static public List <fsValue> SolvePowerSumEquation(fsValue freeCoeff, fsValue[,] coeffsAndPowers)
        {
            var compressing = new SortedList <fsValue, fsValue>();

            for (int i = 0; i < coeffsAndPowers.GetLength(0); ++i)
            {
                fsValue c = coeffsAndPowers[i, 0];
                fsValue p = coeffsAndPowers[i, 1];
                if (!compressing.ContainsKey(p))
                {
                    compressing.Add(p, Zero);
                }

                compressing[p] += c;
            }

            var compressing2 = new SortedList <fsValue, fsValue>();

            foreach (KeyValuePair <fsValue, fsValue> cp in compressing)
            {
                if (cp.Value != Zero)
                {
                    compressing2.Add(cp.Key, cp.Value);
                }
            }
            compressing = compressing2;

            {
                var compressedCoeffsAndPowers = new fsValue[compressing.Count - (compressing.ContainsKey(Zero) ? 1 : 0), 2];
                int i = 0;
                foreach (KeyValuePair <fsValue, fsValue> cp in compressing)
                {
                    if (cp.Key == Zero)
                    {
                        freeCoeff += cp.Value;
                    }
                    else
                    {
                        compressedCoeffsAndPowers[i, 0] = cp.Value;
                        compressedCoeffsAndPowers[i, 1] = cp.Key;
                        ++i;
                    }
                }

                coeffsAndPowers = compressedCoeffsAndPowers;
            }

            var result = new List <fsValue>();

            for (int i = 0; i < coeffsAndPowers.GetLength(0); ++i)
            {
                if (coeffsAndPowers[i, 1] == new fsValue(0))
                {
                    throw new Exception(
                              "SolvePowerSumEquation: Powers must be non-zero values. Move such elemets to freeCoeff");
                }
            }

            for (int i = 1; i < coeffsAndPowers.GetLength(0); ++i)
            {
                if (coeffsAndPowers[i - 1, 1] >= coeffsAndPowers[i, 1])
                {
                    throw new Exception("SolvePowerSumEquation: Powers must be sorted in increasing order");
                }
            }

            if (coeffsAndPowers.GetLength(0) == 0)
            {
                return(result);
            }
            if (coeffsAndPowers.GetLength(0) == 1)
            {
                fsValue resVal = fsValue.Pow(-freeCoeff / coeffsAndPowers[0, 0], 1 / coeffsAndPowers[0, 1]);
                if (resVal.Defined)
                {
                    result.Add(resVal);
                }
                return(result);
            }
            if (freeCoeff == Zero)
            {
                result.Add(Zero);
            }

            var newFreeCoeff       = new fsValue(coeffsAndPowers[0, 0] * coeffsAndPowers[0, 1]);
            var newCoeffsAndPowers = new fsValue[coeffsAndPowers.GetLength(0) - 1, 2];

            for (int i = 0; i < newCoeffsAndPowers.GetLength(0); ++i)
            {
                newCoeffsAndPowers[i, 0] = coeffsAndPowers[i + 1, 0] * coeffsAndPowers[i + 1, 1];
                newCoeffsAndPowers[i, 1] = coeffsAndPowers[i + 1, 1] - coeffsAndPowers[0, 1];
            }

            var changingPoints = new List <fsValue> {
                Zero
            };

            changingPoints.AddRange(SolvePowerSumEquation(newFreeCoeff, newCoeffsAndPowers));
            changingPoints.Add(Infinity);

            const int iterations = 100;  // precision is 1e20 / 2^100 ~~ 1e-11

            for (int i = 1; i < changingPoints.Count; ++i)
            {
                fsValue localSolution = fsBisectionMethod.FindRoot(new fsFunctionPowerSum(freeCoeff, coeffsAndPowers),
                                                                   changingPoints[i - 1],
                                                                   changingPoints[i], iterations);
                if (localSolution.Defined)
                {
                    result.Add(localSolution);
                }
            }

            var eps = new fsValue(1e-12);

            result.Sort();
            for (int i = result.Count - 1; i > 0; --i)
            {
                if (result[i] <= (1 + eps) * result[i - 1] ||
                    result[i] - result[i - 1] <= eps)
                {
                    result.RemoveAt(i);
                }
            }

            return(result);
        }
Esempio n. 3
0
 public abstract fsValue Eval(fsValue x);
Esempio n. 4
0
 public fsFunctionPowerSum(fsValue freeCoeff, fsValue[,] coeffsAndPowers)
 {
     m_freeCoeff       = freeCoeff;
     m_coeffsAndPowers = coeffsAndPowers;
 }
Esempio n. 5
0
 public fsJustValueParameter(fsJustValueParameter other)
 {
     Value = other.Value;
 }
Esempio n. 6
0
 public fsJustValueParameter(fsValue value)
 {
     Value = value;
 }
Esempio n. 7
0
        public static bool FindMinimum(fsFunction function, fsValue beginArg, fsValue endArg, int iterationsCount, out fsValue beginRes, out fsValue endRes)
        {
            beginRes = new fsValue();
            endRes   = new fsValue();

            if (beginArg.Defined == false || endArg.Defined == false)
            {
                return(false);
            }

            fsValue len = endArg - beginArg;

            if (len <= new fsValue(0))
            {
                throw new Exception("Wrong interval for ternary search");
            }

            var eps = new fsValue(1e-8);

            fsValue left  = beginArg;
            fsValue right = endArg;

            for (int i = 0; i < iterationsCount; ++i)
            {
                fsValue middle = 0.5 * (left + right);
                fsValue mid1   = middle - eps * (right - left);
                fsValue mid2   = middle + eps * (right - left);
                fsValue val1   = function.Eval(mid1);
                fsValue val2   = function.Eval(mid2);

                if (!val1.Defined)
                {
                    throw new Exception("Function given to TernaryMethod not defind in point " + mid1.Value);
                }
                if (!val2.Defined)
                {
                    throw new Exception("Function given to TernaryMethod not defind in point " + mid2.Value);
                }

                if (val1 > val2)
                {
                    left = mid1;
                }
                else
                {
                    right = mid2;
                }
            }

            beginRes = left;
            endRes   = right;
            return(true);
        }
Esempio n. 8
0
 public fsJustValueParameter()
 {
     Value = new fsValue();
 }
Esempio n. 9
0
        public static fsValue Calculate(fsFunction function, fsValue beginArg, fsValue endArg, fsValue tolerance)
        {
            if (beginArg > endArg)
            {
                throw new Exception("fsDefiniteIntegral: provided limits are: beginAng > endArg");
            }

            if (beginArg == endArg)
            {
                return(fsValue.Zero);
            }

            fsValue kronrodValue, gaussValue;

            EvalIntegrals(function, beginArg, endArg, out kronrodValue, out gaussValue);
            fsValue kronrodResult = kronrodValue;
            fsValue gaussResult   = gaussValue;

            var queue = new SortedDictionary <fsIntegrationSegment, int>
            {
                { new fsIntegrationSegment(kronrodValue, gaussValue, beginArg, endArg), 0 }
            };
            int iterationsCount = 0;

            while (fsValue.Abs(kronrodResult - gaussResult) > tolerance ||
                   fsValue.Abs(kronrodResult / gaussResult - 1) > tolerance)
            {
                if (++iterationsCount >= 1000)  // If we made too many iterations
                {                               // and still don't have proper precision
                    break;                      // then just return not precise answer.
                }

                fsIntegrationSegment currentSegment = queue.Last().Key;
                queue.Remove(currentSegment);

                beginArg = currentSegment.BeginArg;
                endArg   = currentSegment.EndArg;
                if (IsNeighbouringNumbers(beginArg, endArg))
                {
                    continue;
                }

                kronrodResult -= currentSegment.KronrodIntergralValue;
                gaussResult   -= currentSegment.GaussIntergralValue;

                EvalIntegrals(function, beginArg, 0.5 * (beginArg + endArg), out kronrodValue, out gaussValue);
                kronrodResult += kronrodValue;
                gaussResult   += gaussValue;
                queue.Add(new fsIntegrationSegment(kronrodValue, gaussValue, beginArg, 0.5 * (beginArg + endArg)), 0);

                EvalIntegrals(function, 0.5 * (beginArg + endArg), endArg, out kronrodValue, out gaussValue);
                kronrodResult += kronrodValue;
                gaussResult   += gaussValue;
                queue.Add(new fsIntegrationSegment(kronrodValue, gaussValue, 0.5 * (beginArg + endArg), endArg), 0);
            }

            return((kronrodResult + gaussResult) / 2);
        }
Esempio n. 10
0
 public fsIntegrationSegment(fsValue kronrodIntergralValue, fsValue gaussIntergralValue, fsValue beginArg, fsValue endArg)
 {
     KronrodIntergralValue = kronrodIntergralValue;
     GaussIntergralValue   = gaussIntergralValue;
     BeginArg = beginArg;
     EndArg   = endArg;
 }
Esempio n. 11
0
        private static bool IsNeighbouringNumbers(fsValue a, fsValue b)
        {
            double mid = (a.Value + b.Value) / 2;

            return(a.Value == mid || b.Value == mid);
        }
Esempio n. 12
0
        static private void EvalIntegrals(fsFunction function, fsValue beginArg, fsValue endArg, out fsValue kronrodResult, out fsValue gaussResult)
        {
            fsValue c0 = 0.5 * (endArg + beginArg);
            fsValue c1 = 0.5 * (endArg - beginArg);

            kronrodResult = fsValue.Zero;
            gaussResult   = fsValue.Zero;

            for (int i = 0; i <= 60; ++i)
            {
                fsValue fValue = function.Eval(c0 + c1 * X[i]);
                kronrodResult += WKronrod[i] * fValue;
                gaussResult   += WGauss[i] * fValue;
            }
            kronrodResult *= c1;
            gaussResult   *= c1;
        }
Esempio n. 13
0
 private static int Compare(fsValue first, fsValue second)
 {
     return(first.Value <second.Value ? -1 : first.Value> second.Value ? 1 : 0);
 }