2012-11-08 8 views
7

Ich muss Interpolation und Extrapolation in Ms-Diagramm in Windows-Anwendung implementieren.Interpolation Implementierung in MS-Diagramm

Für die Interpolation verwende ich "MathNet" Bibliothek. aber ich bin mir immer noch nicht bewusst, dies zu implementieren.

Ich habe versucht, die Interpolation wie folgt zu implementieren.

using MathNet.Numerics.Interpolation.Algorithms; 

NevillePolynomialInterpolation objIterpolate = new NevillePolynomialInterpolation(Xpoints, Ypoints); 

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

ich vorbei in xpoints in NevillePolynomialInterpolation() als ersten Parameter, die ist XValues ​​Array meiner Grafik. und Ypoints als YValues-Array meines Diagramms.

Ich übergebe newValue als XValue für interpolierten Wert zu erhalten.

Kann jemand vorschlagen, ist es richtig oder vorschlagen den richtigen Weg, um Interpolation zu implementieren.

+0

Soweit ich sehen kann, machen Sie es richtig, obwohl ich nicht sicher bin, warum Sie den absoluten Wert des interpolierten Ergebnisses nehmen müssen? Könnten Sie näher erläutern, warum Sie sich für diesen Ansatz interessieren? –

+0

Ich bin mir nicht sicher, was ich getan habe, ist richtig oder falsch. Ich habe Ihren Vorschlag notiert. Danke ... –

+0

Vielleicht können Sie einen Screenshot einfügen, der ein Beispiel für Ihre rohen und interpolierten Datenpunkte zeigt. –

Antwort

0

Ich habe es geschafft, ein kurzes Beispiel zu erstellen, also lass mich wissen, ob mein Code, den ich unten eingefügt habe, für dich funktioniert.

Ich bin nicht wirklich an MathDotNet-Bibliothek gewöhnt, aber die XML-Dokumentation ist hübsch genug, so dass die Lernkurve nicht wirklich steil ist nur eine andere .NET-Bibliothek unter so vielen anderen.

Sonst können Sie immer noch auf die Bibliothekswebsite gehen, um sich ihre Dokumentation anzuschauen, abgesehen von einigen Beispielen, von denen ich nicht sicher bin, ob sie die Interpolation abdecken, würden Sie wahrscheinlich dasselbe finden wie beim Lesen der XML Dokumentation. Sie können auch den GitHub und die Implementierung der Interpolation überprüfen, mit der Sie arbeiten möchten.

Natürlich können Sie auch versuchen, von Grund auf neu zu implementieren, wenn Sie auf den Algorithmus-Stick direkt hier beschrieben: http://en.wikipedia.org/wiki/Neville%27s_algorithm

Wie auch immer ich soll Sie MathDotNet Bibliothek nutzen möchten ein Neville Polynom-Interpolation durchzuführen und die rohe anzuzeigen und interpoliert Daten auf demselben Diagrammbereich.

Über zusätzliche Informationen können einige hier (noch nicht erwarten, dass viel):

über das MS-Diagramm, es ist alles über wie bei jeder anderen WinForms Kontrolle zu tun, nur um die Dokumentation überprüfen, ob es etwas heikel Punkt aus ist, was für Sie hart und ich werden versuchen, um es für dich klar zu machen.

Bis jetzt und um ganz ehrlich zu sein, ich kämpfe ein wenig über das, was Sie nicht verstehen, ist es das MS-Diagramm, MathDotNet, beides? Welcher ist ein Problem für dich?

Auf jeden Fall gibt es nichts wirklich Besonderes, nur Ihre X- und Y-Punkte auf die MathDotNet Bibliothek vorbei (solange die zugrunde liegenden Implementierungen von Xs und Ys werden IEnumerable<T> wie die Arrays Implementierung T[] es ist in Ordnung).

Dann macht die Bibliothek die ganze Mathematik für Sie und Sie müssen nur die Interpolate(...) Methoden der Interpolation gegeben (Sie müssen verstehen, dass Interpolation bedeutet hier eine Art von Interpolation Engine, Art von).

ging ich davon aus, dass im Code-Schnipsel: XPoints und YPoints sind beide IEnumerable<T> Sammlungen (da Sie erwähnt sie Arrays sind), wo T ist eine Art von Double, Single oder was auch immer die Art von .NET Anzahl Primitive, die Ihnen gut passt.

// 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; 
      } 
     } 
    } 
} 

Fühlen Sie sich frei, weitere Fragen darüber zu stellen.