private static (bool, bool) DistrSigns(PiecewiseFunction function)
        {
            var fNeg = function.Segments.Any(s => s.A < 0);
            var fPos = function.Segments.Any(s => s.B > 0);

            return(fPos, fNeg);
        }
Пример #2
0
        private static List <double> GetResultBreakPoints(PiecewiseFunction f, PiecewiseFunction g)
        {
            // добавить обработку полюсов
            var fBreaks = f.GetBreakPoints();
            var gBreaks = g.GetBreakPoints();

            // вычисляем произведения точек разрыва, оставляем только уникальные
            var breakPointProducts = new List <double>();

            foreach (var fBreak in fBreaks)
            {
                foreach (var gBreak in gBreaks)
                {
                    var product = fBreak * gBreak;
                    if (!double.IsNaN(product) && !breakPointProducts.Contains(product)) // добавить проверку на мин. значение произведения
                    {
                        breakPointProducts.Add(product);
                    }
                }
            }

            breakPointProducts.Sort();

            return(breakPointProducts);
        }
Пример #3
0
        public static CircularFunction FromCartesianPoints(IEnumerable <Vector2> points)
        {
            // convert to polar coordinates
            var polarPoints = from p in points
                              select new Vector2(p.AngleFromXAxis, p.Length);

            var function = new PiecewiseFunction(2 * Math.PI, polarPoints);

            return(new CircularFunction(function));
        }
        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));
        }
Пример #5
0
        protected override void Initialize()
        {
            for (int i = 0; i < DataSet.Count() - 1; ++i)
            {
                Point point1 = DataSet[i];
                Point point2 = DataSet[i + 1];

                double slope = (point2.Y - point1.Y) / (point2.X - point1.X);

                var function = new PiecewiseFunction(new Domain(point1.X, point2.X), (ExpressionBase)slope * new Subtract("X", point1.X) + point1.Y);

                _functions.Add(function);
            }
        }
        private static List <double> GetResultBreakPoints(PiecewiseFunction f, PiecewiseFunction g)
        {
            var breakPointProducts = GetBreakPointsProducts(f, g);

            //breakPointProducts.Sort();

            var resultBreaks = new List <double>();

            resultBreaks.AddRange(breakPointProducts);

            var(fPos, fNeg) = DistrSigns(f);
            var(gZero, gZeroPos, gZeroNeg) = DistrZeroSigns(g);

            if (gZero)
            {
                if ((fPos && gZeroNeg) || (fNeg && gZeroPos))
                {
                    if (!resultBreaks.Contains(double.NegativeInfinity))
                    {
                        resultBreaks.Add(double.NegativeInfinity);
                    }
                }
                if ((fPos && gZeroPos) || (fNeg && gZeroNeg))
                {
                    if (!resultBreaks.Contains(double.PositiveInfinity))
                    {
                        resultBreaks.Add(double.PositiveInfinity);
                    }
                }
            }

            resultBreaks.Sort();

            var index = resultBreaks.IndexOf(0);

            if (index < resultBreaks.Count - 1)
            {
                if (double.IsInfinity(resultBreaks[index + 1]) && !resultBreaks.Contains(1))
                {
                    resultBreaks.Add(1);
                }
            }

            resultBreaks.Sort();

            return(resultBreaks);
        }
Пример #7
0
        private static List <Tuple <Segment, Segment> > FindSegments(PiecewiseFunction f, PiecewiseFunction g, double z)
        {
            var segmentTuplesList = new List <Tuple <Segment, Segment> >();

            foreach (var fseg in f.Segments)
            {
                foreach (var gseg in g.Segments)
                {
                    if (fseg.A + gseg.A < z && fseg.B + gseg.B > z)
                    {
                        segmentTuplesList.Add(new Tuple <Segment, Segment>(fseg, gseg));
                    }
                }
            }

            return(segmentTuplesList);
        }
Пример #8
0
 public void Setup()
 {
     this.stepUpIncludeUpper = new PiecewiseFunction {
         { 1.0, 1.0 }, { double.MaxValue, 2.0 }
     };
     this.stepUpIncludeLower = new PiecewiseFunction {
         { 1.0, false, 1.0 }, { double.MaxValue, 2.0 }
     };
     this.stepDownIncludeUpper = new PiecewiseFunction {
         { 1.0, 2.0 }, { double.MaxValue, 1.0 }
     };
     this.stepDownIncludeLower = new PiecewiseFunction {
         { 1.0, false, 2.0 }, { double.MaxValue, 1.0 }
     };
     this.constantOne = new PiecewiseFunction {
         { double.MaxValue, 1.0 }
     };
 }
        private static List <Tuple <Segment, Segment> > FindSegments(PiecewiseFunction f, PiecewiseFunction g, double z)
        {
            var segmentTuplesList = new List <Tuple <Segment, Segment> >();

            foreach (var fseg in f.Segments)
            {
                foreach (var gseg in g.Segments)
                {
                    // does x*z intersect the rectangular segment?
                    var yl = z * gseg.A;
                    var yr = z * gseg.B;

                    if ((yl > fseg.A && yr < fseg.B) || (yl < fseg.B && yr > fseg.A))
                    {
                        segmentTuplesList.Add(new Tuple <Segment, Segment>(fseg, gseg));
                    }
                }
            }

            return(segmentTuplesList);
        }
Пример #10
0
        private static List <Tuple <Segment, Segment> > FindSegments(PiecewiseFunction f, PiecewiseFunction g, double z)
        {
            var segmentTuplesList = new List <Tuple <Segment, Segment> >();

            foreach (var fseg in f.Segments)
            {
                foreach (var gseg in g.Segments)
                {
                    //var products = new List<double>
                    //{
                    //    fseg.A * gseg.A,
                    //    fseg.A * gseg.B,
                    //    fseg.B * gseg.A,
                    //    fseg.B * gseg.B,
                    //};

                    var products = new List <double>
                    {
                        fseg.A *gseg.A,
                        fseg.B *gseg.B,
                        fseg.A *gseg.B,
                        fseg.B *gseg.A,
                    };
                    var uniqueProducts = products.Where(p => !double.IsNaN(p)).Distinct();
                    var minP           = uniqueProducts.Min();
                    var maxP           = uniqueProducts.Max();

                    if (minP < z && z < maxP)
                    {
                        segmentTuplesList.Add(new Tuple <Segment, Segment>(fseg, gseg));
                    }
                    //if (fseg.A + gseg.A < z && fseg.B + gseg.B > z)
                    //{
                    //    segmentTuplesList.Add(new Tuple<Segment, Segment>(fseg, gseg));
                    //}
                }
            }

            return(segmentTuplesList);
        }
        private void InitPiecewisePDF()
        {
            PiecewisePDF = new PiecewiseFunction();

            Func <double, double> probabilityFunction = (x) => GetProbabilityFunctionValueAtPoint(x);

            if (MinValue < 0)
            {
                if (MaxValue <= 0)
                {
                    PiecewisePDF.AddSegment(new Segment(MinValue, MaxValue, probabilityFunction));
                }
                else
                {
                    PiecewisePDF.AddSegment(new Segment(MinValue, 0, probabilityFunction));
                    PiecewisePDF.AddSegment(new Segment(0, MaxValue, probabilityFunction));
                }
            }
            else
            {
                PiecewisePDF.AddSegment(new Segment(MinValue, MaxValue, probabilityFunction));
            }
        }
        private static (bool, bool, bool) DistrZeroSigns(PiecewiseFunction function)
        {
            var gZero    = false;
            var gZeroPos = false;
            var gZeroNeg = false;

            foreach (var segment in function.Segments)
            {
                if (segment.A <= 0 && 0 <= segment.B)
                {
                    gZero = true;
                    if (segment.A < 0)
                    {
                        gZeroNeg = true;
                    }
                    if (segment.B > 0)
                    {
                        gZeroPos = true;
                    }
                }
            }

            return(gZero, gZeroPos, gZeroNeg);
        }
Пример #13
0
        private static List <BreakPoint> GetResultBreaks(PiecewiseFunction f, PiecewiseFunction g)
        {
            var resultBreaks = new List <BreakPoint>();

            var fbreaks = f.GetBreakPointsExtended();
            var gbreaks = g.GetBreakPointsExtended();

            var hasMinusInfinity = false;
            var hasPlusInfinity  = false;

            // Проходим по точкам функции f
            foreach (var fbreak in fbreaks)
            {
                if (double.IsNegativeInfinity(fbreak.X))
                {
                    hasMinusInfinity = true;
                    continue;
                }
                if (double.IsPositiveInfinity(fbreak.X))
                {
                    hasPlusInfinity = true;
                    continue;
                }

                // Проходим по точкам функции g
                foreach (var gbreak in gbreaks)
                {
                    if (double.IsNegativeInfinity(gbreak.X))
                    {
                        hasMinusInfinity = true;
                        continue;
                    }
                    if (double.IsPositiveInfinity(gbreak.X))
                    {
                        hasPlusInfinity = true;
                        continue;
                    }
                    // здесь будет добавлена обработка функций Дирака

                    var newBreak = new BreakPoint(fbreak.X + gbreak.X, false, false);
                    resultBreaks.Add(newBreak);
                }
            }

            // нужно возвращать уникальные и отсортированные точки
            resultBreaks.Sort(delegate(BreakPoint b1, BreakPoint b2)
            {
                return(b1.X.CompareTo(b2.X));
            });

            if (hasMinusInfinity)
            {
                resultBreaks = resultBreaks.Prepend(new BreakPoint(double.NegativeInfinity, false, false)).ToList();
            }

            if (hasPlusInfinity)
            {
                resultBreaks = resultBreaks.Append(new BreakPoint(double.PositiveInfinity, false, false)).ToList();
            }

            var uniqueBreakPoints = GetUniqueBreakPoints(resultBreaks);

            return(uniqueBreakPoints);
        }
Пример #14
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);
        }
Пример #15
0
        public static PiecewiseFunction Calculate(PiecewiseFunction f, PiecewiseFunction g)
        {
            var breaks = GetResultBreaks(f, g);

            var resultPiecewiseFunction = new PiecewiseFunction();

            if (breaks.Count > 1 && double.IsNegativeInfinity(breaks[0].X))
            {
                //var appropriateSegments = FindSegments(f, g, breaks[1].X - 1);
                var appropriateSegments = double.IsPositiveInfinity(breaks[1].X)
                    ? FindSegments(f, g, Math.Pow(10, 20))
                    : FindSegments(f, g, breaks[1].X - 1);

                var convRunner = new ConvolutionRunner(appropriateSegments);

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

                if (double.IsPositiveInfinity(breaks[1].X))
                {
                    var fromInfToInfSegment = new FromInfinityToInfinitySegment(probabilityFunction);
                    resultPiecewiseFunction.AddSegment(fromInfToInfSegment);
                }
                else
                {
                    var minusInfSegment = new MinusInfinitySegment(breaks[1].X, probabilityFunction);
                    resultPiecewiseFunction.AddSegment(minusInfSegment);
                }

                breaks.RemoveAt(0);
            }

            if (breaks.Count > 1 && double.IsPositiveInfinity(breaks[breaks.Count - 1].X))
            {
                var appropriateSegments = FindSegments(f, g, breaks[breaks.Count - 2].X + 1);
                var convRunner          = new ConvolutionRunner(appropriateSegments);

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

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

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

            for (var i = 0; i < breaks.Count - 1; i++)
            {
                #region Comment
                //if (i == 0 && double.IsNegativeInfinity(breaks[0].X))
                //{
                //    var appropriateSegments = FindSegments(f, g, breaks[1].X - 1);
                //    var convRunner = new ConvolutionRunner(appropriateSegments);

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

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

                //    continue;
                //}

                //if (i == breaksCount - 1 && double.IsPositiveInfinity(breaks[breaksCount - 1].X))
                //{
                //    var appropriateSegments = FindSegments(f, g, breaks[breaksCount - 2].X + 1);
                //    var convRunner = new ConvolutionRunner(appropriateSegments);

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

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

                //    continue;
                //}
                #endregion

                var segments = FindSegments(f, g, (breaks[i].X + breaks[i + 1].X) / 2);
                var runner   = new ConvolutionRunner(segments);

                Func <double, double> func = (x) => runner.GetConvolutionValueAtPoint(x);
                var newSegment             = new Segment(breaks[i].X, breaks[i + 1].X, func);

                resultPiecewiseFunction.AddSegment(newSegment);
            }

            return(resultPiecewiseFunction);
        }
        public static PiecewiseFunction Calculate(PiecewiseFunction f, PiecewiseFunction g)
        {
            var resultPiecewiseFunction = new PiecewiseFunction();

            var fSplitted = GetSplittedPiecewiseFunction(f);
            var gSplitted = GetSplittedPiecewiseFunction(g);

            var breaks = GetResultBreakPoints(fSplitted, gSplitted);

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

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

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

                breaks.RemoveAt(0);
            }

            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.GetConvolutionValueAtPointQuotient(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.GetConvolutionValueAtPointQuotient(x);

                //Segment newSegment = null;

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

                //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);
        }
Пример #17
0
 private CircularFunction(PiecewiseFunction pointsInPolarCoordinates)
 {
     _function = pointsInPolarCoordinates;
 }