Here's another solution. It assumes zeroes are missing values and replaces
them with interpolated values
fill
3 : 0^:(*@#)
b=. 1 (0 _1)} 0~:y
x=. b#y
n=. 2 -~/\ I. b
({:x) ,~ (n#}:x) + ; (i.&.>n) *&.> n %~ 2 -~/\ x
)
fill 3 5 7 0 9 12 14 0 0 8
3 5 7 8 9 12 14 12 10 8
On Fri, May 7, 2021 at 4:20 PM 'Rudolf Sykora' via Programming <
[email protected]> wrote:
>
> > The task is to go from (as an example)
> >
> > X: 0 5 6 26
> > Y: 10 _10 80 100
> >
> > to, say:
> >
> > U: 0 5 10 15 20 25 30 NB. Equidistant mesh.
> > V: 10 _10 84 90 94 99 104 NB. Linear interpolation and extrapolation
> when needed.
> > NB. The numbers with U>5 are rounded here
> for readability.
> > NB. If U=26 were, by chance, in the mesh,
> > NB. the value would be (exactly) 100.
> >
> > (This is not what the data look like in reality, but as an example it
> > could suffice.)
>
> I came up with this:
>
> interpolate =. 4 : 0
> u =. x
> 'x y' =. y
> v =. (#u) # 0
> ux =. x I. u
> for_uj. u do.
> l =. uj_index { ux
> if. l = 0 do. l =. 1 end.
> if. l = #x do. l =. l - 1 end.
> xl =. l { x
> xlm =. (l - 1) { x
> yl =. l { y
> ylm =. (l - 1) { y
> vv =. (xl - xlm) %~ (yl*(uj - xlm)) + ylm*(xl - uj)
> v =. vv uj_index } v
> end.
> v
> )
>
> then
>
>
> x =. 0 5 6 26
> y =. 10 _10 80 100
> xy =. x,:y
>
> u =. 0 5 10 15 20 25 30
> +v =. u interpolate xy
>
> results in the wanted
>
> 10 _10 84 89 94 99 104
>
> .
>
> It does what I need, though the code is probably not nice. I would assume
> a J
> programmer would probably avoid the ifs, and perhaps the whole loop
> altogether. If anybody can comment, please do.
>
> (The code actually does not rely on the u-mesh to be equidistant, after
> all.)
>
>
> Thanks!
> Ruda
>
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm