static Approximation ApproximatePi(int iterations, bool print) { int coprimes = 0; for (int i = 0; i < iterations; i++) { uint r1 = RandomIntRange(0, 1000); uint r2 = RandomIntRange(0, 1000); if (GCD(new uint[] { r1, r2 }) == 1) { coprimes++; } } double ratio = (double)coprimes / iterations; double approximation = Math.Sqrt((6.0f / ratio)); double error = (Math.Abs(approximation - Math.PI) / Math.PI) * 100; Approximation approx = new Approximation(); approx.iterations = iterations; approx.coprimes = coprimes; approx.ratio = ratio; approx.approximation = approximation; approx.error = error; if (print) { Console.WriteLine(string.Format("{0} -> {1} -> {2}", coprimes, ratio, approximation)); Console.WriteLine(string.Format("{0}% error", error)); } return(approx); }
public void ComputeResultFor_WhenAllArgumentsAreProper(double[] factors, double x, int expectedResult) { var approximation = new Approximation(factors); var result = approximation.ComputeResultFor(x); Assert.That((int)result, Is.EqualTo(expectedResult)); }
public static Vector2 ApproxScaleTo(this Vector2 vector, float magnitude) { float idist = Approximation.InvSqrt(vector.sqrMagnitude); return(new Vector2( vector.x * idist * magnitude, vector.y * idist * magnitude )); }
public void SetUpPlotModelData(Approximation app) { PlotModel.Series.Clear(); _centroids = app.Centroids; _samplePoints = app.SamplePoints; _networkOutput = app.Outputs; _app = app; CreateCentroidLineSerie(); CreateSamplePointsLineSeries(); CreateExpectedPointsLineSeries(); }
private void OnDrawGizmos() { Vector3[] points = CreatePoints3(Points); if (points.Length > 1) { Line3 line = Approximation.LeastsSquaresLineFit3(points); FiguresColor(); DrawPoints(points); ResultsColor(); DrawLine(ref line); } }
public ApproximationViewModel() { _approximation = new Approximation(); OpenTrainFileClick = new RelayCommand(OpenTrainFile); OpenTestFileClick = new RelayCommand(OpenTestFile); OpenInTextEditorClick = new RelayCommand(OpenInTextEditor, () => _pathToFile != null && _pathToFile.Any()); ApproximateClick = new RelayCommand(AproximateAndPlot); DoStuffClick = new RelayCommand(ShowPlotFromDataWithoutLearning); _plotModelViewModel = new PlotViewModel(); _errorPlotModelViewModel = new ErrorPlotViewModel(); GenerateClick = new RelayCommand(Generate); }
private void OnDrawGizmos() { Vector3[] points = CreatePoints3(Points); if (points.Length > 1) { Plane3 plane = Approximation.LeastSquaresPlaneFit3(points); FiguresColor(); DrawPoints(points); ResultsColor(); DrawPlane(ref plane, Points[0]); } }
public void ApproximationResultTest() { double[] arguments = { 0, 0.25, 0.5, 0.75, 1 }; double[] values = { 1, 1.284, 1.6487, 2.117, 2.7183 }; double[] expected = { 1.0051, 0.8647, 0.8432 }; Approximation approximation = new Approximation(); double[] actual = approximation.GetApproximation(2, arguments, values).Polynomial; Assert.AreEqual(expected[0], actual[0], 0.001); Assert.AreEqual(expected[1], actual[1], 0.001); Assert.AreEqual(expected[2], actual[2], 0.001); }
public string AsCsvString() => LoopIndex.ToString() .ConcatCsv(MonitoringScheme.AsString()) .ConcatCsv(VectorLength.ToString()) .ConcatCsv(NumOfNodes.ToString()) .ConcatCsv(Approximation.AsString()) .ConcatCsv(Communication.Bandwidth.ToString()) .ConcatCsv(Communication.UdpBandwidth.ToString()) .ConcatCsv(Communication.Messages.ToString()) .ConcatCsv(Communication.UdpMessages.ToString()) .ConcatCsv(Communication.Latency.ToString()) .ConcatCsv(NumberOfFullSyncs.ToString()) .ConcatCsv(LowerBound.AsCsvString()) .ConcatCsv(FunctionValue.ToString(CultureInfo.InvariantCulture)) .ConcatCsv(UpperBound.AsCsvString()) .ConcatCsv(NodesFunctionValues.Aggregate("", (csv, value) => csv.ConcatCsv(value.ToString(CultureInfo.InvariantCulture))));
public static int[] Build(List <JVector> pointCloud, Approximation factor) { List <int> allIndices = new List <int>(); int iterations = (int)factor; Random rnd = new Random(); for (int i = 0; i < iterations; i++) { for (int e = 0; e < iterations; e++) { for (int k = 0; k < iterations; k++) { JMatrix rot = JMatrix.CreateRotationX(JMath.PiOver2 / iterations * i) * JMatrix.CreateRotationY(JMath.PiOver2 / iterations * e) * JMatrix.CreateRotationZ(JMath.PiOver2 / iterations * k); JVector vec0 = JVector.Transform(JVector.Right, rot); JVector vec1 = JVector.Transform(JVector.Up, rot); JVector vec2 = JVector.Transform(JVector.Forward, rot); int[] indices = FindExtremePoints(pointCloud, ref vec0, ref vec1, ref vec2); allIndices.AddRange(indices); } } } // this, allIndices.Sort(); for (int i = 1; i < allIndices.Count; i++) { if (allIndices[i - 1] == allIndices[i]) { allIndices.RemoveAt(i - 1); i--; } } return(allIndices.ToArray()); // or using 3.5 extensions // return allIndices.Distinct().ToArray(); }
public static int[] Build(List<JVector> pointCloud, Approximation factor) { List<int> allIndices = new List<int>(); int iterations = (int)factor; Random rnd = new Random(); for (int i = 0; i < iterations; i++) { for (int e = 0; e < iterations; e++) { for (int k = 0; k < iterations; k++) { JMatrix rot = JMatrix.CreateRotationX(JMath.PiOver2 / iterations * i) * JMatrix.CreateRotationY(JMath.PiOver2 / iterations * e) * JMatrix.CreateRotationZ(JMath.PiOver2 / iterations * k); JVector vec0 = JVector.Transform(JVector.Right, rot); JVector vec1 = JVector.Transform(JVector.Up, rot); JVector vec2 = JVector.Transform(JVector.Forward, rot); int[] indices = FindExtremePoints(pointCloud, ref vec0, ref vec1, ref vec2); allIndices.AddRange(indices); } } } // this, allIndices.Sort(); for (int i = 1; i < allIndices.Count; i++) { if (allIndices[i - 1] == allIndices[i]) { allIndices.RemoveAt(i - 1); i--; } } return allIndices.ToArray(); // or using 3.5 extensions // return allIndices.Distinct().ToArray(); }
public static int[] Build(List <FPVector> pointCloud, Approximation factor) { List <int> allIndices = new List <int>(); int steps = (int)factor; for (int thetaIndex = 0; thetaIndex < steps; thetaIndex++) { // [0,PI] FP theta = FPMath.Pi / (steps - 1) * thetaIndex; FP sinTheta = FP.Sin(theta); FP cosTheta = FP.Cos(theta); for (int phiIndex = 0; phiIndex < steps; phiIndex++) { // [-PI,PI] FP phi = ((2 * FP.One) * FPMath.Pi) / (steps - 0) * phiIndex - FPMath.Pi; FP sinPhi = FP.Sin(phi); FP cosPhi = FP.Cos(phi); FPVector dir = new FPVector(sinTheta * cosPhi, cosTheta, sinTheta * sinPhi); int index = FindExtremePoint(pointCloud, ref dir); allIndices.Add(index); } } allIndices.Sort(); for (int i = 1; i < allIndices.Count; i++) { if (allIndices[i - 1] == allIndices[i]) { allIndices.RemoveAt(i - 1); i--; } } return(allIndices.ToArray()); // or using 3.5 extensions // return allIndices.Distinct().ToArray(); }
public static int[] Build(List <Vector3> pointCloud, Approximation factor) { List <int> allIndices = new List <int>(); int steps = (int)factor; for (int thetaIndex = 0; thetaIndex < steps; thetaIndex++) { // [0,PI] float theta = JMath.Pi / (steps - 1) * thetaIndex; float sinTheta = (float)Math.Sin(theta); float cosTheta = (float)Math.Cos(theta); for (int phiIndex = 0; phiIndex < steps; phiIndex++) { // [-PI,PI] float phi = (2.0f * JMath.Pi) / (steps - 0) * phiIndex - JMath.Pi; float sinPhi = (float)Math.Sin(phi); float cosPhi = (float)Math.Cos(phi); Vector3 dir = new Vector3(sinTheta * cosPhi, cosTheta, sinTheta * sinPhi); int index = FindExtremePoint(pointCloud, ref dir); allIndices.Add(index); } } allIndices.Sort(); for (int i = 1; i < allIndices.Count; i++) { if (allIndices[i - 1] == allIndices[i]) { allIndices.RemoveAt(i - 1); i--; } } return(allIndices.ToArray()); // or using 3.5 extensions // return allIndices.Distinct().ToArray(); }
/// <summary> /// Moving the obstacle /// </summary> private void Move() { int posCount = positions.Count; if (posCount > 1) { if (currentTargetPosition > posCount - 1) { currentTargetPosition = 0; } if (Approximation.VectorsEqual(transform.position, positions[currentTargetPosition], 0.05f)) { currentTargetPosition++; } else { transform.position = Vector3.MoveTowards(transform.position, positions[currentTargetPosition], Time.fixedDeltaTime * speed); } } }
public static int[] Build(List<JVector> pointCloud, Approximation factor) { List<int> allIndices = new List<int>(); int steps = (int)factor; for (int thetaIndex = 0; thetaIndex < steps; thetaIndex++) { // [0,PI] float theta = JMath.Pi / (steps - 1) * thetaIndex; float sinTheta = (float)Math.Sin(theta); float cosTheta = (float)Math.Cos(theta); for (int phiIndex = 0; phiIndex < steps; phiIndex++) { // [-PI,PI] float phi = (2.0f * JMath.Pi) / (steps - 0) * phiIndex - JMath.Pi; float sinPhi = (float)Math.Sin(phi); float cosPhi = (float)Math.Cos(phi); JVector dir = new JVector(sinTheta * cosPhi, cosTheta, sinTheta * sinPhi); int index = FindExtremePoint(pointCloud, ref dir); allIndices.Add(index); } } allIndices.Sort(); for (int i = 1; i < allIndices.Count; i++) { if (allIndices[i - 1] == allIndices[i]) { allIndices.RemoveAt(i - 1); i--; } } return allIndices.ToArray(); // or using 3.5 extensions // return allIndices.Distinct().ToArray(); }
private void Update() { if (_Renderer.enabled) { if (Approximation.Vector3(_Marker.position, _Transform.position, 0.1f)) { Explode(); } _Rigidbody2D.MovePosition(_Rigidbody2D.position + (Vector2)_Transform.up * (_Speed * Time.deltaTime)); } //If we're currently disabled. else { // And the explosion has ended. if (_Explosion.isActiveAndEnabled == false) { // Then deactivate ourselves for later use. _Transform.parent.gameObject.SetActive(false); } } }
/// <summary> /// Scaling the obstacle /// </summary> private void Scale() { if (scale) { if (Approximation.VectorsEqual(transform.localScale, finalScale, 0.1f)) { isScalingUp = false; } else if (Approximation.VectorsEqual(transform.localScale, initialScale, 0.1f)) { isScalingUp = true; } if (isScalingUp) { transform.localScale = Vector3.MoveTowards(transform.localScale, finalScale, scaleSpeed * Time.fixedDeltaTime); } else { transform.localScale = Vector3.MoveTowards(transform.localScale, initialScale, scaleSpeed * Time.fixedDeltaTime); } } }
public static int[] Build(List <JVector> pointCloud, Approximation factor) { var allIndices = new List <int>(); int steps = (int)factor; for (int thetaIndex = 0; thetaIndex < steps; thetaIndex++) { float theta = JMath.Pi / (steps - 1) * thetaIndex; float sinTheta = (float)Math.Sin(theta); float cosTheta = (float)Math.Cos(theta); for (int phiIndex = 0; phiIndex < steps; phiIndex++) { float phi = (2.0f * JMath.Pi / (steps - 0) * phiIndex) - JMath.Pi; float sinPhi = (float)Math.Sin(phi); float cosPhi = (float)Math.Cos(phi); var dir = new JVector(sinTheta * cosPhi, cosTheta, sinTheta * sinPhi); int index = FindExtremePoint(pointCloud, dir); allIndices.Add(index); } } allIndices.Sort(); for (int i = 1; i < allIndices.Count; i++) { if (allIndices[i - 1] == allIndices[i]) { allIndices.RemoveAt(i - 1); i--; } } return(allIndices.ToArray()); }
/// <summary> /// Player movement /// </summary> /// <param name="posCount"> number of positions there is still to go through</param> private void MovePlayerAndCamera() { if ((Input.touches.Length > 0 || Input.GetMouseButton(0))) { animator.SetBool("isWalking", true); if (Approximation.VectorsEqual(transform.position, positions[nextPositionId], 0.05f)) { nextPositionId++; if (nextPositionId < posCount) { transform.LookAt(positions[nextPositionId]); } } else { transform.position = Vector3.MoveTowards(transform.position, positions[nextPositionId], Time.fixedDeltaTime * speed); } } else { animator.SetBool("isWalking", false); } MoveCamera(); }
public void TimesTest() { /** EXCHANGE SEPARATOR FOR CSV **/ System.Globalization.CultureInfo customCulture = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone(); customCulture.NumberFormat.NumberDecimalSeparator = "."; System.Threading.Thread.CurrentThread.CurrentCulture = customCulture; /** CONFIGURATION **/ int totalAgents = 60; int startAgents = 5; int loopJump = 5; int loopCounter = 0; int maxIterations; double epsilon = Math.Pow(10, -10); Generator generator; Generator ownSparseGenerator; maxIterations = 1000; double[] agents = new double[totalAgents / startAgents]; double[] cases = new double[totalAgents / startAgents]; /** TIMES LISTS **/ List <double> partialGaussTimes = new List <double>(); List <double> sparsePartialGaussTimes = new List <double>(); List <double> gaussSeidelTimes = new List <double>(); List <double> sparseLUTimes = new List <double>(); List <double> ownSparseTimes = new List <double>(); /** X AND F(X) FOR APPROXIMATION **/ Approximation approximation = new Approximation(); double[] arguments = new double[totalAgents - startAgents + 1]; double[] partialGaussValues = new double[totalAgents - startAgents + 1]; double[] sparsePartialGaussValues = new double[totalAgents - startAgents + 1]; double[] gaussSeidelValues = new double[totalAgents - startAgents + 1]; double[] sparseLUValues = new double[totalAgents - startAgents + 1]; double[] ownSparseValues = new double[totalAgents - startAgents + 1]; /** COUNTING TIMES **/ using (var w = new StreamWriter("times.csv")) { var newLine = "Total Agents, Total Cases, Generate Equation, SparseLU, Gauss-Seidel, Sparse Partial Gauss, Partial Gauss, Own Sparse"; w.WriteLine(newLine); w.Flush(); loopCounter = 0; for (int i = startAgents; i <= totalAgents; i += loopJump) { partialGaussTimes.Clear(); sparsePartialGaussTimes.Clear(); gaussSeidelTimes.Clear(); sparseLUTimes.Clear(); ownSparseTimes.Clear(); generator = new Generator(i); ownSparseGenerator = new Generator(i, true); for (int j = 0; j < 100; j++) { GaussSeidel gaussSeidel = new GaussSeidel(generator.TotalCases, generator.OriginalMatrix, generator.OriginalVector, maxIterations, epsilon); PartialGauss partialGauss = new PartialGauss(generator.TotalCases, generator.OriginalMatrix, generator.OriginalVector, false); PartialGauss sparsePartialGauss = new PartialGauss(generator.TotalCases, generator.OriginalMatrix, generator.OriginalVector, true); SparseLUSolver sparseLUSolver = new SparseLUSolver(generator.TotalCases, generator.OriginalMatrix, generator.OriginalVector); OwnSparseSolver ownSparseSolver = new OwnSparseSolver(ownSparseGenerator.GenerateOwnSparseMatrix(), generator.OriginalVector, maxIterations, epsilon); partialGaussTimes.Add(partialGauss.GaussPartialTiming); sparsePartialGaussTimes.Add(sparsePartialGauss.SparseGaussPartialTiming); gaussSeidelTimes.Add(gaussSeidel.GaussSeidelTiming); sparseLUTimes.Add(sparseLUSolver.SparseLUTiming); ownSparseTimes.Add(ownSparseSolver.OwnSparseMatrixTiming); } partialGaussTimes.Sort(); sparsePartialGaussTimes.Sort(); gaussSeidelTimes.Sort(); sparseLUTimes.Sort(); ownSparseTimes.Sort(); partialGaussTimes.Remove(partialGaussTimes.FirstOrDefault()); partialGaussTimes.Remove(partialGaussTimes.LastOrDefault()); sparsePartialGaussTimes.Remove(sparsePartialGaussTimes.FirstOrDefault()); sparsePartialGaussTimes.Remove(sparsePartialGaussTimes.LastOrDefault()); gaussSeidelTimes.Remove(gaussSeidelTimes.FirstOrDefault()); gaussSeidelTimes.Remove(gaussSeidelTimes.LastOrDefault()); sparseLUTimes.Remove(sparseLUTimes.FirstOrDefault()); sparseLUTimes.Remove(sparseLUTimes.LastOrDefault()); ownSparseTimes.Remove(ownSparseTimes.FirstOrDefault()); ownSparseTimes.Remove(ownSparseTimes.LastOrDefault()); newLine = $"{i},{generator.TotalCases},{generator.GenerateEquationTiming},{sparseLUTimes.Average()},{gaussSeidelTimes.Average()},{sparsePartialGaussTimes.Average()}, {partialGaussTimes.Average()}, {ownSparseTimes.Average()}"; w.WriteLine(newLine); w.Flush(); arguments[loopCounter] = generator.TotalCases; partialGaussValues[loopCounter] = partialGaussTimes.Average(); sparsePartialGaussValues[loopCounter] = sparsePartialGaussTimes.Average(); gaussSeidelValues[loopCounter] = gaussSeidelTimes.Average(); sparseLUValues[loopCounter] = sparseLUTimes.Average(); ownSparseValues[loopCounter] = ownSparseTimes.Average(); agents[loopCounter] = generator.TotalAgents; cases[loopCounter] = generator.TotalCases; loopCounter++; } } /** APPROXIMATION **/ var partialGaussApproximationTest = approximation.GetApproximation(3, arguments, partialGaussValues); var sparsePartialGaussApproximationTest = approximation.GetApproximation(2, arguments, sparsePartialGaussValues); var gaussSeidelApproximationTest = approximation.GetApproximation(2, arguments, gaussSeidelValues); var sparseLUApproximationTest = approximation.getLinearRegression(arguments, sparseLUValues); var ownSparseApproximationTest = approximation.GetApproximation(2, arguments, ownSparseValues); /** toString **/ using (var s = new StreamWriter("strings.txt")) { s.WriteLine("PARTIAL GAUSS " + partialGaussApproximationTest.GetString()); s.WriteLine("SPARSE PARTIAL GAUUS " + sparsePartialGaussApproximationTest.GetString()); s.WriteLine("GAUSS SEIDEL " + gaussSeidelApproximationTest.GetString()); s.WriteLine("SPARSE LU " + sparseLUApproximationTest.GetString()); s.WriteLine("OWN SPARSE " + ownSparseApproximationTest.GetString()); s.Flush(); } /** toValue **/ using (var v = new StreamWriter("approximation.csv")) { var line = "Total Agents, Total Cases, SparseLU, Gauss-Seidel, Sparse Partial Gauss, Partial Gauss, Own Sparse"; v.WriteLine(line); v.Flush(); for (int i = 0; i < (totalAgents / startAgents); i++) { line = $"{agents[i]}, {cases[i]}, {sparseLUApproximationTest.GetResult(cases[i])}, {gaussSeidelApproximationTest.GetResult(cases[i])}, {sparsePartialGaussApproximationTest.GetResult(cases[i])}, {partialGaussApproximationTest.GetResult(cases[i])}, {ownSparseApproximationTest.GetResult(cases[i])}"; v.WriteLine(line); v.Flush(); } } /** ERRORS **/ double partialGaussError = 0; double sparsePartialGaussError = 0; double gaussSeidelError = 0; double sparseLUError = 0; double ownSparseError = 0; for (int i = 0; i < (totalAgents / startAgents); i++) { partialGaussError += Math.Sqrt(Math.Pow(partialGaussValues[i] - partialGaussApproximationTest.GetResult(cases[i]), 2)); sparsePartialGaussError += Math.Sqrt(Math.Pow(sparsePartialGaussValues[i] - sparsePartialGaussApproximationTest.GetResult(cases[i]), 2)); gaussSeidelError += Math.Sqrt(Math.Pow(gaussSeidelValues[i] - gaussSeidelApproximationTest.GetResult(cases[i]), 2)); sparseLUError += Math.Sqrt(Math.Pow(sparseLUValues[i] - sparseLUApproximationTest.GetResult(cases[i]), 2)); ownSparseError += Math.Sqrt(Math.Pow(ownSparseValues[i] - ownSparseApproximationTest.GetResult(cases[i]), 2)); } using (var e = new StreamWriter("errors.txt")) { e.WriteLine("PARTIAL GAUSS ERROR " + partialGaussError); e.WriteLine("SPARSE PARTIAL GAUSS ERROR " + sparsePartialGaussError); e.WriteLine("GAUSS SEIDEL ERROR " + gaussSeidelError); e.WriteLine("SPARSE LU ERROR " + sparseLUError); e.WriteLine("OWN SPARSE ERROR " + ownSparseError); e.Flush(); } /** COUNTING TIME FOR 100K */ using (var w = new StreamWriter("100k.txt")) { w.WriteLine("PARTIAL GAUSS 100k " + partialGaussApproximationTest.GetResult(100000) / Math.Pow(10, 6) + " SEKUND"); w.WriteLine("SPARSE PARTIAL 100k " + sparsePartialGaussApproximationTest.GetResult(100000) / Math.Pow(10, 6) + " SEKUND"); w.WriteLine("GAUSS SEIDEL 100k " + gaussSeidelApproximationTest.GetResult(100000) / Math.Pow(10, 6) + " SEKUND"); w.WriteLine("SPARSE LU 100k " + sparseLUApproximationTest.GetResult(100000) + " MIKROSEKUND"); w.WriteLine("OWN SPARSE 100k " + ownSparseApproximationTest.GetResult(100000) / Math.Pow(10, 6) + " SEKUND"); w.Flush(); } }
public static Pine ToPine(this IEnumerable <double?> source, Approximation approximation = Approximation.Linear) { switch (approximation) { case Approximation.Linear: return(LinearApproximation()); case Approximation.Step: return(StepApproximation()); default: return(null); } Pine LinearApproximation() { int countNum = source.Count(x => x != null); // количество имеющих значение в последовательности if (countNum == 0) { return(Enumerable.Range(0, source.Count()).Select(x => 0.0).ToPine()); } if (countNum == 1) { double _value = source.First(x => x != null).Value; return(Enumerable.Range(0, source.Count()).Select(x => _value).ToPine()); } Pine ret = new Pine(); // возвращаемый массив double value1 = 0, value2 = 0, delta = 0; // последние значащие и приращение на каждый шаг IEnumerable <double?> sour = source.SkipWhile(x => x == null); // текущее состояние последовательности = source.SkipWhile(x => x == null); // пропуск первых не значащих int numberCurr; // номер обрабатываемого значения int countNull; // количество незначащих значений в следующем промежутке for ( numberCurr = 1; // номер обрабатываемого значения numberCurr < countNum; sour = sour.SkipWhile(x => x == null), numberCurr++ ) { value1 = sour.First().Value; // первое значащае число ret.Add(value1); sour = sour.Skip(1); value2 = sour.First(x => x != null).Value; // второе значащае число countNull = sour.TakeWhile(x => x == null).Count(); // количество не имеющих значения между первым и вторым числом delta = (value2 - value1) / (countNull + 1); // приращение на каждый шаг for (int ind = 0; ind < countNull; ind++) { ret.Add(value1 += delta); // заполнение последовательности } } // обработка конца последовательности ret.Add(value2); sour = sour.Skip(1); countNull = sour.Count(); // количество последних не имеющих значения for (int ind = 0; ind < countNull; ind++) { ret.Add(value2 += delta); // заполнение последовательности } return(ret); } Pine StepApproximation() { int countNum = source.Count(x => x != null); // количество имеющих значение в последовательности if (countNum == 0) { return(Enumerable.Range(0, source.Count()).Select(x => 0.0).ToPine()); } if (countNum == 1) { double _value = source.First(x => x != null).Value; return(Enumerable.Range(0, source.Count()).Select(x => _value).ToPine()); } Pine ret = new Pine(); // возвращаемый массив double value1 = 0, value2 = 0; // последние значащие и приращение на каждый шаг IEnumerable <double?> sour = source.SkipWhile(x => x == null); // текущее состояние последовательности = source.SkipWhile(x => x == null); // пропуск первых не значащих int numberCurr; // номер обрабатываемого значения int countNull; // количество незначащих значений в следующем промежутке for ( numberCurr = 1; // номер обрабатываемого значения numberCurr < countNum; sour = sour.SkipWhile(x => x == null), numberCurr++ ) { value1 = sour.First().Value; // первое значащае число ret.Add(value1); sour = sour.Skip(1); value2 = sour.First(x => x != null).Value; // второе значащае число countNull = sour.TakeWhile(x => x == null).Count(); // количество не имеющих значения между первым и вторым числом for (int ind = 0; ind < countNull; ind++) { ret.Add(value1); // заполнение последовательности } } // обработка конца последовательности ret.Add(value2); sour = sour.Skip(1); countNull = sour.Count(); // количество последних не имеющих значения for (int ind = 0; ind < countNull; ind++) { ret.Add(value2); // заполнение последовательности } return(ret); } }