2012-11-08 41 views
7

Tôi yêu cầu triển khai nội suy và ngoại suy trong biểu đồ Ms trong ứng dụng Windows.Thực hiện nội suy trong Biểu đồ MS

Đối với nội suy, tôi đang sử dụng Thư viện "MathNet". nhưng tôi vẫn không biết thực hiện điều này.

Tôi đã cố gắng triển khai Nội suy như bên dưới.

using MathNet.Numerics.Interpolation.Algorithms; 

NevillePolynomialInterpolation objIterpolate = new NevillePolynomialInterpolation(Xpoints, Ypoints); 

    double NewYValue; 
    NewYValue = Math.Abs(objIterpolate.Interpolate(newValue); 

tôi đi qua trong XPoints trong NevillePolynomialInterpolation() như một tham số đầu tiên là XValues ​​mảng của biểu đồ của tôi. và Ypoints như một mảng YValues ​​của biểu đồ của tôi.

Tôi đang chuyển newValue làm XValue để nhận giá trị nội suy.

Ai cũng có thể đề xuất, Có đúng cách hay đề xuất cách chính xác để triển khai Nội suy.

+0

Theo như tôi có thể thấy bạn đang làm đúng, mặc dù tôi không chắc chắn lý do tại sao bạn cần phải có giá trị tuyệt đối của kết quả nội suy? Bạn có thể xây dựng trên * tại sao * bạn quan tâm đến cách tiếp cận này? –

+0

Tôi không chắc mình đã làm gì đúng hay sai. Tôi đã ghi lại đề xuất của bạn. thanks ... –

+0

Có lẽ bạn có thể chèn một vùng màn hình hiển thị một ví dụ về các điểm dữ liệu thô và nội suy của bạn? –

Trả lời

0

Tôi đã tạo một ví dụ ngắn để cho tôi biết nếu mã tôi dán dưới đây có hiệu quả cho bạn hay không.

Tôi không thực sự được sử dụng để thư viện MathDotNet tuy nhiên tài liệu XML là khá đủ để đường cong học tập không thực sự dốc chỉ là một thư viện NET trong số rất nhiều người khác. Nếu không, bạn vẫn có thể truy cập trang web thư viện để xem tài liệu của họ, ngoài một vài ví dụ mà tôi không chắc chắn bao gồm nội suy, bạn có thể sẽ tìm thấy điều tương tự như bạn đã đọc bằng XML tài liệu. Bạn cũng có thể kiểm tra github và xem thực hiện nội suy mà bạn đang tìm cách giải quyết.

Tất nhiên bạn cũng có thể cố gắng thực hiện từ đầu nếu bạn dính vào các thuật toán được mô tả ngay tại đây: http://en.wikipedia.org/wiki/Neville%27s_algorithm

Dù sao tôi phải bạn muốn tận dụng thư viện MathDotNet để thực hiện một phép nội suy đa thức Neville và hiển thị các liệu và nội suy dữ liệu trên cùng một Vùng Biểu đồ.

Về biết thêm chi tiết một số có thể được tìm thấy ở đây (vẫn không hy vọng rằng nhiều):

Về Chart MS, nó là tất cả về như đối phó với bất kỳ điều khiển Winforms khác, chỉ cần kiểm tra tài liệu, nếu có cái gì đó khó khăn điểm ra những gì là khó khăn cho bạn và tôi sẽ cố gắng để làm cho nó rõ ràng cho bạn.

Cho đến nay và hoàn toàn trung thực tôi đang đấu tranh một chút về những gì bạn không hiểu, đó có phải là Biểu đồ MS, MathDotNet, cả hai? Cái nào là một vấn đề cho bạn?

Dù sao thì không có gì thực sự ưa thích, chỉ cần chuyển điểm X và Y của bạn đến thư viện MathDotNet (miễn là triển khai cơ bản của X và Y đang triển khai IEnumerable<T> như mảng T[] thì tốt).

Sau đó, thư viện đang thực hiện tất cả các phép toán cho bạn và bạn chỉ cần sử dụng phương pháp nội suy được đưa ra (bạn phải hiểu rằng Nội suy ở đây có nghĩa là một loại Công cụ nội suy, loại).

Tôi cho rằng trong đoạn mã của bạn: XPointsYPoints đều IEnumerable<T> bộ sưu tập (kể từ khi bạn mentionned họ là mảng), nơi T là một loại Double, Single hoặc bất cứ loại NET Số nguyên thủy phù hợp với bạn tốt.

// 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, @"X", @"Y", 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, Double>(x, 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, IFormattable, IConvertible, 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; 
      } 
     } 
    } 
} 

Hãy đặt thêm câu hỏi.

Các vấn đề liên quan