对于插值我使用的是“MathNet”库.但我仍然没有意识到这一点.
我试着实现插值如下.
using MathNet.Numerics.Interpolation.Algorithms; NevillePolynomialInterpolation objIterpolate = new NevillePolynomialInterpolation(Xpoints,Ypoints); double NewYValue; NewYValue = Math.Abs(objIterpolate.Interpolate(newValue);
我在NevillePolynomialInterpolation()中传递XPoints作为第一个参数,它是我的图表的XValues数组.和Ypoints作为我的图表的YValues数组.
我传递newValue作为XValue获取插值.
解决方法
我并不习惯MathDotNet库,但是XML文档已经足够了,所以学习曲线并不像其他许多.NET库那样陡峭.
否则你仍然可以去图书馆网站查看他们的文档,除了几个我不确定涵盖插值的例子之外,你可能会发现通过阅读XML文档得到的相同的东西.您还可以检查github以及您要处理的插值的实现.
当然,如果你坚持这里描述的算法,你也可以尝试从头开始实现:http://en.wikipedia.org/wiki/Neville%27s_algorithm
无论如何,我认为你想利用MathDotNet库来执行Neville多项式插值,并在同一图表区域上显示原始和插值数据.
关于其他信息可以在这里找到(仍然不要指望那么多):
> MS图表:
> http://www.4guysfromrolla.com/articles/072209-1.aspx
> https://code.msdn.microsoft.com/Samples-Environments-for-b01e9c61
> @L_502_4@
> MathDotNet:http://numerics.mathdotnet.com/Regression.html
关于MS Chart,它就像处理任何其他Winforms控件一样,只需检查文档,如果有一些棘手的问题指出对你来说有什么困难,我会尽力为你说清楚.
到目前为止,并且完全诚实,我正在努力解决你不理解的问题,它是MS Chart,MathDotNet,两者兼而有之?哪一个对你有问题?
无论如何,没有什么真正的花哨,只是将你的X和Y点传递给MathDotNet库(只要Xs和Ys的底层实现正在实现IEnumerable< T>就像数组T []一样好).
然后库正在为你做所有的数学运算,你只需要使用插值的插值(…)方法(你必须理解插值这里的插值是一种插值引擎).
我假设在你的代码片段中:XPoints和YPoints都是IEnumerable< T>集合(因为你提到它们是数组),其中T是Double,Single或任何适合你的.NET Number Primitive类型.
// Copyright: Nothing At All License using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; using MathNet.Numerics.Random; namespace HelpSO { public static class Program { [STAThread] public static void Main(params String[] arguments) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); var mainForm = new MainForm(); Application.Run(mainForm); } } /// <summary> /// Main Form. /// </summary> public class MainForm : Form { /// <summary> /// Initializes the chart and cosmetics,make-up,glamour,etc.. /// </summary> /// <returns>The chart.</returns> private static Chart InitializeChart() { var chart = new Chart() { Dock = DockStyle.Fill,}; const String defaultChartAreaName = @"Default"; const String defaultLegendName = @"Default"; const String defaultTitleName = @"Default"; var chartArea = chart.ChartAreas.Add(defaultChartAreaName); var labelFont = new Font(@"Tahoma",8f); var axisX = chartArea.AxisX; var axisY = chartArea.AxisY; axisX.Title = @"X"; axisY.Title = @"Y"; axisX.LabelStyle.Format = axisX.LabelStyle.Format = "F4"; axisX.TitleFont = axisY.TitleFont = labelFont; axisX.LabelStyle.Font = axisY.LabelStyle.Font = labelFont; axisX.TitleAlignment = axisY.TitleAlignment = StringAlignment.Far; axisX.MajorGrid.Enabled = axisY.MajorGrid.Enabled = true; axisX.MinorGrid.Enabled = axisY.MinorGrid.Enabled = true; axisX.MinorGrid.LineDashStyle = axisY.MinorGrid.LineDashStyle = ChartDashStyle.Dash; axisX.MinorGrid.LineColor = axisY.MinorGrid.LineColor = Color.Gainsboro; var legend = chart.Legends.Add(defaultLegendName); legend.TitleSeparator = LegendSeparatorStyle.ThickGradientLine; legend.BorderColor = Color.Black; legend.Title = "Legend"; var title = chart.Titles.Add(defaultTitleName); title.Text = @"My Awesome interpolated data"; title.Font = new Font(title.Font.FontFamily,12f); MainForm.InitializeChartSeries(chart); return chart; } /// <summary> /// Initializes the chart series and related data (raw and interpolated). /// </summary> /// <param name="chart">Chart.</param> private static void InitializeChartSeries(Chart chart) { const String rawDataSeriesName = @"Raw Data"; const String interpolatedDataSeriesName = @"Interpolated Data"; var rawDataSeries = chart.Series.Add(rawDataSeriesName); var interpolatedDataSeriesSeries = chart.Series.Add(interpolatedDataSeriesName); rawDataSeries.ChartType = SeriesChartType.FastLine; interpolatedDataSeriesSeries.ChartType = SeriesChartType.Spline; rawDataSeries.BorderWidth = interpolatedDataSeriesSeries.BorderWidth = 2; var rawDataPoints = DataFactory.GenerateDummySine(10,1,0.25); var interpolatedDataPoints = DataFactory.Interpolate(rawDataPoints,10); rawDataSeries.Points.DataBind(rawDataPoints,@"X",@"Y",String.Empty); interpolatedDataSeriesSeries.Points.DataBind(interpolatedDataPoints,String.Empty); } /// <summary> /// Initializes a new instance of the <see cref="HelpSO.MainForm"/> class. /// </summary> public MainForm() { this.StartPosition = FormStartPosition.CenterScreen; var chart = MainForm.InitializeChart(); this.Controls.Add(chart); } } /// <summary> /// Data Factory. /// </summary> public static class DataFactory { /// <summary> /// Generates a dummy sine. /// </summary> /// <returns>The dummy sine.</returns> /// <param name="count">Count.</param> /// <param name="amplitude">Amplitude.</param> /// <param name="noiseAmplitude">Noise amplitude.</param> public static IList<Point2D<Double,Double>> GenerateDummySine(UInt16 count,Double amplitude,Double noiseAmplitude) { if (count < 2) { throw new ArgumentOutOfRangeException(@"count"); } else { var dummySinePoints = new List<Point2D<Double,Double>>(); var random = new Random(); var xStep = 1.0 / count; for (var x = 0.0; x < 1.0; x += xStep) { var y = amplitude * Math.Sin(2f * Math.PI * x) + random.NextDouble() * noiseAmplitude; var dummySinePoint = new Point2D<Double,Double>(x,y); dummySinePoints.Add(dummySinePoint); } return dummySinePoints; } } /// <summary> /// Interpolate the specified source. /// </summary> /// <param name="source">Source.</param> /// <param name="countRatio">Count ratio.</param> public static IList<Point2D<Double,Double>> Interpolate(IList<Point2D<Double,Double>> source,UInt16 countRatio) { if (countRatio == 0) { throw new ArgumentOutOfRangeException(@"countRatio"); } else if (source.Count < 2) { throw new ArgumentOutOfRangeException(@"source"); } else { var rawDataPointsX = source.Select(item => item.X); var rawDataPointsY = source.Select(item => item.Y); // Could be done within one loop only... so far I'm pretty busy will update that example later var xMin = rawDataPointsX.Min(); var xMax = rawDataPointsX.Max(); // Different Kinds of interpolation here... it's all up to you o pick up the one that's gonna match your own situation // var interpolation = MathNet.Numerics.Interpolation.NevillePolynomialInterpolation.Interpolate(rawDataPointsX,rawDataPointsY); var interpolation = MathNet.Numerics.Interpolation.CubicSpline.InterpolateNatural(rawDataPointsX,rawDataPointsY); var listCopy = source.ToList(); var xStep = (xMax - xMin) / (source.Count * countRatio); for (var x = xMin; x <= xMax; x += xStep) { var y = interpolation.Interpolate(x); var point2D = new Point2D<Double,y); listCopy.Add(point2D); } return listCopy; } } } // C# lacks,for ***now***,generic constraints for primitive "numbers" public struct Point2D<TX,TY> where TX : struct,IComparable,IFormattable,IConvertible,IComparable<TX>,IEquatable<TX> where TY : struct,IComparable<TY>,IEquatable<TY> { public static Point2D<TX,TY> Empty = new Point2D<TX,TY>(); public Point2D(TX x,TY y) { this._x = x; this._y = y; } // C# 6 I miss you here: sad private readonly TY _y; public TY Y { get { return this._y; } } // and there too :-( private readonly TX _x; public TX X { get { return this._x; } } } }
随意提出更多相关问题.