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); }
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); }
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)); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
private CircularFunction(PiecewiseFunction pointsInPolarCoordinates) { _function = pointsInPolarCoordinates; }