kopia lustrzana https://github.com/dl2alf/AirScout
274 wiersze
6.8 KiB
C#
274 wiersze
6.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms.DataVisualization.Charting;
|
|
|
|
namespace TestMySpline
|
|
{
|
|
class Program
|
|
{
|
|
static void Main(string[] args)
|
|
{
|
|
//TestTdm();
|
|
TestSplineOnWikipediaExample();
|
|
//TestSpline();
|
|
//TestPerf();
|
|
}
|
|
|
|
private static void TestSpline()
|
|
{
|
|
int n = 6;
|
|
|
|
// Create the data to be fitted
|
|
float[] x = new float[n];
|
|
float[] y = new float[n];
|
|
Random rand = new Random(1);
|
|
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
x[i] = i;
|
|
y[i] = (float)rand.NextDouble() * 10;
|
|
}
|
|
|
|
// Compute the x values that we will evaluate the spline at.
|
|
// Upsample the original data by a const factor.
|
|
int upsampleFactor = 10;
|
|
int nInterpolated = n * upsampleFactor;
|
|
float[] xs = new float[nInterpolated];
|
|
|
|
for (int i = 0; i < nInterpolated; i++)
|
|
{
|
|
xs[i] = (float)i * (n - 1) / (float)(nInterpolated - 1);
|
|
}
|
|
|
|
CubicSpline spline = new CubicSpline();
|
|
float[] ys = spline.FitAndEval(x, y, xs, true);
|
|
string path = @"..\..\testSpline.png";
|
|
PlotSplineSolution("Cubic Spline Interpolation - Random Data", x, y, xs, ys, path);
|
|
}
|
|
|
|
private static void TestPerf()
|
|
{
|
|
int n = 10000;
|
|
|
|
// Create the data to be fitted
|
|
float[] x = new float[n];
|
|
float[] y = new float[n];
|
|
Random rand = new Random(1);
|
|
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
x[i] = i;
|
|
y[i] = (float)rand.NextDouble() * 10;
|
|
}
|
|
|
|
// Compute the x values that we will evaluate the spline at.
|
|
// Upsample the original data by a const factor.
|
|
int upsampleFactor = 10;
|
|
int nInterpolate = n * upsampleFactor;
|
|
float[] xs = new float[nInterpolate];
|
|
|
|
for (int i = 0; i < nInterpolate; i++)
|
|
{
|
|
xs[i] = (float)i / upsampleFactor;
|
|
}
|
|
|
|
// For perf, test multiple reps
|
|
int reps = 100;
|
|
DateTime start = DateTime.Now;
|
|
|
|
for (int i = 0; i < reps; i++)
|
|
{
|
|
CubicSpline spline = new CubicSpline();
|
|
float[] ys = spline.FitAndEval(x, y, xs, false);
|
|
}
|
|
|
|
TimeSpan duration = DateTime.Now - start;
|
|
Console.WriteLine("CubicSpline upsample from {0:n0} to {1:n0} points took {2:0.00} ms for {3} iterations ({2:0.000} ms per iteration)",
|
|
n, nInterpolate, duration.TotalMilliseconds, reps, duration.TotalMilliseconds / reps);
|
|
|
|
// Compare to NRinC
|
|
//float[] y2 = new float[n];
|
|
//float[] ys2 = new float[nInterpolate];
|
|
//start = DateTime.Now;
|
|
|
|
//for (int i = 0; i < reps; i++)
|
|
//{
|
|
// CubicSplineNR.Spline(x, y, y2);
|
|
// CubicSplineNR.EvalSpline(x, y, y2, xs, ys2);
|
|
//}
|
|
|
|
//duration = DateTime.Now - start;
|
|
//Console.WriteLine("CubicSplineNR upsample from {0:n0} to {1:n0} points took {2:0.00} ms for {3} iterations ({2:0.000} ms per iteration)",
|
|
// n, nInterpolate, duration.TotalMilliseconds, reps, duration.TotalMilliseconds / reps);
|
|
}
|
|
|
|
/// <summary>
|
|
/// This is the Wikipedia "Spline Interpolation" article example.
|
|
/// </summary>
|
|
private static void TestSplineOnWikipediaExample()
|
|
{
|
|
// Create the test points.
|
|
float[] x = new float[] { -1.0f, 0.0f, 3.0f };
|
|
float[] y = new float[] { 0.5f, 0.0f, 3.0f };
|
|
|
|
Console.WriteLine("x: {0}", ArrayUtil.ToString(x));
|
|
Console.WriteLine("y: {0}", ArrayUtil.ToString(y));
|
|
|
|
// Create the upsampled X values to interpolate
|
|
int n = 20;
|
|
float[] xs = new float[n];
|
|
float stepSize = (x[x.Length - 1] - x[0]) / (n - 1);
|
|
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
xs[i] = x[0] + i * stepSize;
|
|
}
|
|
|
|
// Solve
|
|
CubicSpline spline = new CubicSpline();
|
|
float[] ys = spline.FitAndEval(x, y, xs, false);
|
|
|
|
Console.WriteLine("xs: {0}", ArrayUtil.ToString(xs));
|
|
Console.WriteLine("ys: {0}", ArrayUtil.ToString(ys));
|
|
|
|
// Plot
|
|
string path = @"..\..\spline-wikipedia.png";
|
|
PlotSplineSolution("Cubic Spline Interpolation - Wikipedia Example", x, y, xs, ys, path);
|
|
}
|
|
|
|
private static TriDiagonalMatrixF TestTdm()
|
|
{
|
|
TriDiagonalMatrixF m = new TriDiagonalMatrixF(10);
|
|
|
|
for (int i = 0; i < m.N; i++)
|
|
{
|
|
m.A[i] = 1.111111f;
|
|
m.B[i] = 2.222222f;
|
|
m.C[i] = 3.333333f;
|
|
}
|
|
|
|
Console.WriteLine("Matrix:\n{0}", m.ToDisplayString(",4:0.00", " "));
|
|
|
|
for (int i = 0; i < m.N; i++)
|
|
{
|
|
m[i, i] = 4.4444f;
|
|
}
|
|
|
|
Console.WriteLine("Matrix:\n{0}", m.ToDisplayString(",4:0.00", " "));
|
|
|
|
// Solve
|
|
Random rand = new Random(1);
|
|
float[] d = new float[m.N];
|
|
|
|
for (int i = 0; i < d.Length; i++)
|
|
{
|
|
d[i] = (float)rand.NextDouble();
|
|
}
|
|
|
|
float[] x = m.Solve(d);
|
|
|
|
Console.WriteLine("Solve returned: ");
|
|
|
|
for (int i = 0; i < x.Length; i++)
|
|
{
|
|
Console.Write("{0:0.0000}, ", x[i]);
|
|
}
|
|
|
|
Console.WriteLine();
|
|
return m;
|
|
}
|
|
|
|
#region PlotSplineSolution
|
|
|
|
private static void PlotSplineSolution(string title, float[] x, float[] y, float[] xs, float[] ys, string path)
|
|
{
|
|
List<DataPoint> points = new List<DataPoint>();
|
|
|
|
for (int i = 0; i < x.Length; i++)
|
|
{
|
|
points.Add(new DataPoint(x[i], y[i]));
|
|
}
|
|
|
|
var chart = new Chart();
|
|
chart.Size = new Size(600, 400);
|
|
chart.Titles.Add(title);
|
|
string legendName = "Legend";
|
|
chart.Legends.Add(new Legend(legendName));
|
|
|
|
ChartArea ca = new ChartArea("DefaultChartArea");
|
|
ca.AxisX.Title = "X";
|
|
ca.AxisY.Title = "Y";
|
|
chart.ChartAreas.Add(ca);
|
|
|
|
Series s1 = CreateSeries(chart, "Spline", CreateDataPoints(xs, ys), Color.Blue, MarkerStyle.None);
|
|
Series s2 = CreateSeries(chart, "Original", CreateDataPoints(x, y), Color.Green, MarkerStyle.Diamond);
|
|
|
|
chart.Series.Add(s1);
|
|
chart.Series.Add(s2);
|
|
|
|
ca.RecalculateAxesScale();
|
|
ca.AxisX.Minimum = Math.Round(ca.AxisX.Minimum);
|
|
ca.AxisX.Maximum = Math.Round(ca.AxisX.Maximum);
|
|
int nIntervals = (x.Length - 1);
|
|
nIntervals = Math.Max(4, nIntervals);
|
|
ca.AxisX.Interval = (ca.AxisX.Maximum - ca.AxisX.Minimum) / nIntervals;
|
|
|
|
// Save
|
|
if (File.Exists(path))
|
|
{
|
|
File.Delete(path);
|
|
}
|
|
|
|
using (FileStream fs = new FileStream(path, FileMode.CreateNew))
|
|
{
|
|
chart.SaveImage(fs, ChartImageFormat.Png);
|
|
}
|
|
}
|
|
|
|
private static List<DataPoint> CreateDataPoints(float[] x, float[] y)
|
|
{
|
|
Debug.Assert(x.Length == y.Length);
|
|
List<DataPoint> points = new List<DataPoint>();
|
|
|
|
for (int i = 0; i < x.Length; i++)
|
|
{
|
|
points.Add(new DataPoint(x[i], y[i]));
|
|
}
|
|
|
|
return points;
|
|
}
|
|
|
|
private static Series CreateSeries(Chart chart, string seriesName, IEnumerable<DataPoint> points, Color color, MarkerStyle markerStyle = MarkerStyle.None)
|
|
{
|
|
var s = new Series()
|
|
{
|
|
XValueType = ChartValueType.Double,
|
|
YValueType = ChartValueType.Double,
|
|
Legend = chart.Legends[0].Name,
|
|
IsVisibleInLegend = true,
|
|
ChartType = SeriesChartType.Line,
|
|
Name = seriesName,
|
|
ChartArea = chart.ChartAreas[0].Name,
|
|
MarkerStyle = markerStyle,
|
|
Color = color,
|
|
MarkerSize = 8
|
|
};
|
|
|
|
foreach (var p in points)
|
|
{
|
|
s.Points.Add(p);
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|