[chronojump] Added interpolate cosine and interpolate cubic, (and tests)
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] Added interpolate cosine and interpolate cubic, (and tests)
- Date: Thu, 6 May 2021 12:23:01 +0000 (UTC)
commit c46f1f0f5d064f21627f7bd6f9a7f713a7c21fb3
Author: Xavier de Blas <xaviblas gmail com>
Date: Thu May 6 14:22:36 2021 +0200
Added interpolate cosine and interpolate cubic, (and tests)
src/gui/app1/chronojump.cs | 3 +
src/utilMath.cs | 146 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 149 insertions(+)
---
diff --git a/src/gui/app1/chronojump.cs b/src/gui/app1/chronojump.cs
index 21c79d66..42e55f8a 100644
--- a/src/gui/app1/chronojump.cs
+++ b/src/gui/app1/chronojump.cs
@@ -939,6 +939,9 @@ public partial class ChronoJumpWindow
//Test ForceSensor GetVariabilityAndAccuracy: getVariabilityCVRMSSD
ForceSensorCapturePoints.TestVariabilityCVRMSSD();
+
+ //InterpolateSignal.TestInterpolateBetween();
+ InterpolateSignal.TestCosineAndCubicInterpolate();
}
diff --git a/src/utilMath.cs b/src/utilMath.cs
index ac9ef2ca..ff1cf456 100644
--- a/src/utilMath.cs
+++ b/src/utilMath.cs
@@ -20,6 +20,7 @@
*/
using System;
+using System.IO; //for detect OS //TextWriter
using System.Collections.Generic; //List<T>
//note this has doubles. For ints can use Gdk.Point
@@ -387,3 +388,148 @@ public static class MathUtil
}
}
+
+public class InterpolateSignal
+{
+ private List<PointF> point_l;
+ private enum types { COSINE, CUBIC };
+
+ public InterpolateSignal (List<PointF> point_l)
+ {
+ this.point_l = point_l;
+ }
+
+ //thanks to: http://paulbourke.net/miscellaneous/interpolation/
+ public double CosineInterpolate(double y1, double y2, double mu)
+ {
+ double mu2;
+
+ mu2 = (1-Math.Cos(mu*Math.PI))/2;
+
+ return(y1*(1-mu2)+y2*mu2);
+ }
+ //thanks to: http://paulbourke.net/miscellaneous/interpolation/
+ public double CubicInterpolate(double y0,double y1, double y2,double y3, double mu)
+ {
+ double a0, a1, a2, a3, mu2;
+
+ mu2 = mu * mu;
+ a0 = y3 - y2 - y0 + y1;
+ a1 = y0 - y1 - a0;
+ a2 = y2 - y0;
+ a3 = y1;
+
+ return(a0*mu*mu2+a1*mu2+a2*mu+a3);
+ }
+
+ public static void TestCosineAndCubicInterpolate()
+ {
+ Random random = new Random();
+ List<PointF> l = new List<PointF>();
+
+ for(int i = 0; i < 100; i += 10)
+ l.Add(new PointF(i, random.NextDouble() * 10));
+
+ InterpolateSignal fsp = new InterpolateSignal(l);
+ fsp.testCosineCubicInterpolateDo(types.COSINE);
+ fsp.testCosineCubicInterpolateDo(types.CUBIC);
+ }
+
+ private void testCosineCubicInterpolateDo(types type)
+ {
+ TextWriter writer = File.CreateText(
+ Path.Combine(Path.GetTempPath(),
string.Format("chronojump_testinterpolate_{0}.csv", type.ToString())));
+ writer.WriteLine("X;Y;color;cex");
+
+ for(int i = 0; i < point_l.Count -1; i ++) //each known point
+ {
+ writer.WriteLine(string.Format("{0};{1};{2};{3}",
+ point_l[i].X, point_l[i].Y, "red", 2));
+ for(double d = 0; d < 1 ; d += .1) //each interpolated value
+ {
+ if (type == types.COSINE)
+ writer.WriteLine(string.Format("{0};{1};{2};{3}",
+ point_l[i].X + d*(point_l[i+1].X -
point_l[i].X),
+ CosineInterpolate(point_l[i].Y,
point_l[i+1].Y, d),
+ "black", 1));
+ //else if(type == types.CUBIC && i > 0 && i < point_l.Count -2)
+ else if(type == types.CUBIC)
+ {
+ //for cubic we need two extra points
+ double pre2Y = 0;
+ double post2Y = 0;
+ if(i == 0) {
+ pre2Y = point_l[point_l.Count -1].Y;
+ post2Y = point_l[i+2].Y;
+ } else if(i == point_l.Count -2) {
+ pre2Y = point_l[i-1].Y;
+ post2Y = point_l[0].Y;
+ } else {
+ pre2Y = point_l[i-1].Y;
+ post2Y = point_l[i+2].Y;
+ }
+
+ writer.WriteLine(string.Format("{0};{1};{2};{3}",
+ point_l[i].X + d*(point_l[i+1].X -
point_l[i].X),
+ //CubicInterpolate(point_l[i-1].Y,
point_l[i].Y, point_l[i+1].Y, point_l[i+2].Y, d),
+ CubicInterpolate(pre2Y, point_l[i].Y,
point_l[i+1].Y, post2Y, d),
+ "green", 1));
+ }
+ }
+ }
+ //write the last known point
+ writer.WriteLine(string.Format("{0};{1};{2};{3}",
+ point_l[point_l.Count -1].X, point_l[point_l.Count -1].Y, "red", 2));
+
+ writer.Flush();
+ writer.Close();
+ ((IDisposable)writer).Dispose();
+
+ /*
+ test it with R:
+ d=read.csv2("/tmp/chronojump_testinterpolate_COSINE.csv")
+ plot(d$X, d$Y, col=d$color, cex=d$cex, type="b", xlim=c(0,90), ylim=c(0,10))
+ par(new=T)
+ d=read.csv2("/tmp/chronojump_testinterpolate_CUBIC.csv")
+ plot(d$X, d$Y, col=d$color, cex=d$cex, type="b", xlim=c(0,90), ylim=c(0,10))
+ */
+ }
+
+ /* unused
+ //n: number of points between should be at least 1
+ public List<PointF> InterpolateBetween (int posFrom, int posTo, int n)
+ {
+ PointF pointFrom = point_l[posFrom];
+ PointF pointTo = point_l[posTo];
+
+ List<PointF> interpolated_l = new List<PointF>();
+ for(int i = 1; i < n + 1; i ++)
+ interpolated_l.Add(
+ new PointF(
+ pointFrom.X + UtilAll.DivideSafe((pointTo.X - pointFrom.X) *
i, (n + 1)),
+ pointFrom.Y + UtilAll.DivideSafe((pointTo.Y - pointFrom.Y) *
i, (n + 1))
+ ));
+
+ return interpolated_l;
+ }
+
+ public static void TestInterpolateBetween()
+ {
+ InterpolateSignal fsp = new InterpolateSignal(new List<PointF>{
+ new PointF(5.5, 8),
+ new PointF(7.5, 12),
+ new PointF(14, 13.2)
+ });
+
+ //List<PointF> interpolated_l = fsp.InterpolateBetween(0, 1, 3);
+ //List<PointF> interpolated_l = fsp.InterpolateBetween(1, 2, 1);
+ List<PointF> interpolated_l = fsp.InterpolateBetween(1, 2, 7);
+
+ //print list
+ LogB.Information("Printing interpolates");
+ foreach(PointF point in interpolated_l)
+ LogB.Information(point.ToString());
+ }
+ */
+
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]