in reply to How to smooth values of an x,y,z array using Math::Spline

Did you try following the approach shown in the synopsis or example sections of the Math::Spline docs? What happened when you tried it?

I'll take a wild guess that the triples in your "toy data" represent 3D (x, y, z) values, at regular time intervals (t0, t1, t2, t3). I'm not sure what results you're hoping for, but my guess is extrapolated 3D positions at interpolated times, in which case I expect you're going to need to instantiate three Math::Spline evaluators, one each for (t -> x), (t -> y) and (t -> z).

  • Comment on Re: How to smooth values of an x,y,z array using Math::Spline

Replies are listed 'Best First'.
Re^2: How to smooth values of an x,y,z array using Math::Spline
by pryrt (Abbot) on May 10, 2023 at 17:27 UTC
    Great idea, hv.

    Updating my code to implement three splines relative to t rather than two splines relative to x, there isn't a divide-by-zero problem:

    use warnings; use strict; use feature ':5.10'; my @accel = ([-0.7437,0.1118,-0.5367], [-0.5471,0.0062,-0.6338], [-0.6437,0.1216,-0.5255], [-0.4437,0.3216,-0.3255], ); # note: I changed from an array whose only element is an arrayref +of arrayrefs to an array who has n arrayrefs, to be a simple 2D array use Math::Spline; my (@x,@y,@z,@t); # generate x, y, and z arrays, and a t array my $pt = 0; for my $xyz (@accel) { push @t, $pt++; push @x, $xyz->[0]; push @y, $xyz->[1]; push @z, $xyz->[2]; } # create spline calculators for x&y and x&z my $spline_tx = eval { Math::Spline::->new(\@t, \@x) } or do { die "ty +: $@" }; my $spline_ty = eval { Math::Spline::->new(\@t, \@y) } or do { die "ty +: $@" }; my $spline_tz = eval { Math::Spline::->new(\@t, \@z) } or do { die "tz +: $@" }; my @interp_accel = (); my $NSTEPS = 200; my $dt = $pt/$NSTEPS; # $NSTEPS+1 values from xmin to xmax, inclusive for my $i (0..$NSTEPS) { my $t = $i * $dt; my $x = $spline_tx->evaluate($t); my $y = $spline_ty->evaluate($t); my $z = $spline_tz->evaluate($t); push @interp_accel, [$x,$y,$z]; # store for later printf "interpolate # %d => t=%.2f => [%s,%s,%s]\n", $i, map {$_// +'<undef>'} $t, $x, $y, $z; # debug print }

    I then get the four fixed points at t=0, t=1, t=2, and t=3, with interpolated values everywhere else (I snipped intermediate values, except near the fixed points)

    interpolate # 0 => t=0.00 => [-0.7437,0.1118,-0.5367] interpolate # 1 => t=0.02 => [-0.73780958368,0.10862255968,-0.53961481 +072] interpolate # 2 => t=0.04 => [-0.73192386944,0.10544767744,-0.54252728 +576] ... interpolate # 48 => t=0.96 => [-0.54759113856,0.00641293056,-0.6335783 +4624] interpolate # 49 => t=0.98 => [-0.54723036832,0.00624379232,-0.6337463 +9728] interpolate # 50 => t=1.00 => [-0.5471,0.0062,-0.6338] interpolate # 51 => t=1.02 => [-0.5472023792,0.0062833216,-0.633737511 +2] interpolate # 52 => t=1.04 => [-0.5475304256,0.00649236480000001,-0.63 +35600576] ... interpolate # 98 => t=1.96 => [-0.6433479104,0.1142666112,-0.532585126 +4] interpolate # 99 => t=1.98 => [-0.6436376048,0.1179228224,-0.529056384 +8] interpolate # 100 => t=2.00 => [-0.6437,0.1216,-0.5255] interpolate # 101 => t=2.02 => [-0.64352802112,0.12529626272,-0.521917 +57408] interpolate # 102 => t=2.04 => [-0.64312404096,0.12901093376,-0.518309 +84064] ... interpolate # 148 => t=2.96 => [-0.45563928704,0.31328743424,-0.333929 +71136] interpolate # 149 => t=2.98 => [-0.44967201088,0.31744352928,-0.329715 +11392] interpolate # 150 => t=3.00 => [-0.4437,0.3216,-0.3255] interpolate # 151 => t=3.02 => [-0.43772798912,0.32575647072,-0.321284 +88608] interpolate # 152 => t=3.04 => [-0.43176071296,0.32991256576,-0.317070 +28864] ... interpolate # 198 => t=3.96 => [-0.24427595904,0.51418906624,-0.132690 +15936] interpolate # 199 => t=3.98 => [-0.24387197888,0.51790373728,-0.129082 +42592] interpolate # 200 => t=4.00 => [-0.2437,0.5216,-0.1255]
Re^2: How to smooth values of an x,y,z array using Math::Spline
by cormanaz (Deacon) on May 10, 2023 at 17:33 UTC
    Gah...sorry! I thought I had defined the array. Yes, it's accelerator x,y,z values (columns) for four observations (rows).