private static PiecewiseFunction GetSplittedPiecewiseFunction(PiecewiseFunction function)
        {
            var breaks = function.GetBreakPoints();

            // непонятное условие
            //if (breaks.First() > 0 || breaks.Last() < 0)
            //{
            //    return function;
            //}

            if (!breaks.Contains(0))
            {
                breaks.Add(0);
            }

            breaks.Sort();

            var index = breaks.IndexOf(0);

            if (index == breaks.Count - 2) // предпоследний
            {
                if (double.IsInfinity(breaks[index + 1]) && !breaks.Contains(-1))
                {
                    breaks.Add(-1);
                }
                else
                {
                    var valueToInsert = breaks[index + 1] / 2;
                    if (!breaks.Contains(valueToInsert))
                    {
                        breaks.Add(valueToInsert);
                    }
                }
            }

            if (index == 1) // второй
            {
                if (double.IsInfinity(breaks[index - 1]) && !breaks.Contains(-1))
                {
                    breaks.Add(-1);
                }
                else
                {
                    var valueToInsert = breaks[index - 1] / 2;
                    if (!breaks.Contains(valueToInsert))
                    {
                        breaks.Add(valueToInsert);
                    }
                }
            }

            breaks.Sort();

            return(function.SplitByPoints(breaks));
        }
Ejemplo n.º 2
0
        public static PiecewiseFunction Calculate(PiecewiseFunction f, PiecewiseFunction g)
        {
            //var breaks = GetResultBreaks(f, g);

            var fSplitted = f.SplitByPoints(new List <double> {
                -1, 0, 1
            });
            var gSplitted = g.SplitByPoints(new List <double> {
                -1, 0, 1
            });

            var f_0        = fSplitted[0];
            var g_0        = gSplitted[0];
            var poleAtZero = f_0 > 0 && g_0 > 0;

            var breaks = GetResultBreakPoints(fSplitted, gSplitted);

            Func <double, double, double> operation = (a, b) => a * b;

            var resultPiecewiseFunction = new PiecewiseFunction();

            //if (breaks.Count > 1 && double.IsNegativeInfinity(breaks[0]))
            if (double.IsInfinity(breaks[0]))
            {
                var appropriateSegments = FindSegments(fSplitted, gSplitted, breaks[1] - 1);
                var convRunner          = new ConvolutionRunner(appropriateSegments);

                Func <double, double> probabilityFunction = (x) => convRunner.GetConvolutionValueAtPointProduct(x);

                var minusInfSegment = new MinusInfinitySegment(breaks[1], probabilityFunction);
                resultPiecewiseFunction.AddSegment(minusInfSegment);

                breaks.RemoveAt(0);
            }

            //if (breaks.Count > 1 && double.IsPositiveInfinity(breaks[breaks.Count - 1]))
            if (double.IsInfinity(breaks[breaks.Count - 1]))
            {
                var appropriateSegments = FindSegments(fSplitted, gSplitted, breaks[breaks.Count - 2] + 1);
                var convRunner          = new ConvolutionRunner(appropriateSegments);

                Func <double, double> probabilityFunction = (x) => convRunner.GetConvolutionValueAtPointProduct(x);

                var plusInfSegment = new PlusInfinitySegment(breaks[breaks.Count - 2], probabilityFunction);
                resultPiecewiseFunction.AddSegment(plusInfSegment);

                breaks.RemoveAt(breaks.Count - 1);
            }

            for (var i = 0; i < breaks.Count - 1; i++)
            {
                var segments = FindSegments(fSplitted, gSplitted, (breaks[i] + breaks[i + 1]) / 2);
                var runner   = new ConvolutionRunner(segments);
                Func <double, double> func = (x) => runner.GetConvolutionValueAtPointProduct(x);

                Segment newSegment = null;

                if (breaks[i] == 0)
                {
                    if (poleAtZero)
                    {
                        newSegment = new SegmentWithPole(breaks[i], breaks[i + 1], func, true);
                        //var segmentWithPole = new SegmentWithPole(breaks[i], breaks[i + 1], func, true);
                        //newSegment = segmentWithPole.ToInterpolatedSegment();
                    }
                    else
                    {
                        newSegment = new Segment(breaks[i], breaks[i + 1], func);
                    }
                }
                else if (breaks[i + 1] == 0)
                {
                    if (poleAtZero)
                    {
                        newSegment = new SegmentWithPole(breaks[i], breaks[i + 1], func, false);
                    }
                    else
                    {
                        newSegment = new Segment(breaks[i], breaks[i + 1], func);
                    }
                }
                else
                {
                    newSegment = new Segment(breaks[i], breaks[i + 1], func);
                }

                //var newSegment = new Segment(breaks[i], breaks[i + 1], func);

                resultPiecewiseFunction.AddSegment(newSegment);
            }


            return(resultPiecewiseFunction);
        }