Skip to content

flip el-wise-op#21

Merged
sigilante merged 1 commit into
urbit:mainfrom
yapishu:reid/el-wise-op-fix
May 30, 2026
Merged

flip el-wise-op#21
sigilante merged 1 commit into
urbit:mainfrom
yapishu:reid/el-wise-op-fix

Conversation

@yapishu
Copy link
Copy Markdown
Contributor

@yapishu yapishu commented Apr 17, 2026

++el-wise-op in lagoon returns a ray whose elements are in reverse order. every hoon-only transcendental that uses it (exp, sin, cos, tan, abs) gives a flipped vector back on any input with n>1 elements

in lagoon/desk/lib/lagoon.hoon:

++  el-wise-op
  |=  [a=ray fun=$-(@ @)]
  ^-  ray
  ?>  (check a)
  %-  spac
  :-  meta.a
  =/  ali  (flop (ravel a))  :: compensate for LSB
  %+  rep  bloq.meta.a
  %+  turn
    ali
  |=(e=@ (fun e))

ravel already delivers scalars in index order (element 0 at the head of the list), and rep packs the head of the list into the lsb, which is also element 0's slot. the head after flop is the old last element, rep puts it at LSB, and the output's element 0 is the input's element n-1. bin-op is laid out the same way but does not flop, which is why add/sub/mul/div on rays work and exp/abs/etc. don't.

this wasn't picked up by tests because lagoon/desk/tests/lib/ has no tests for for any transcendental and el-wise-op is used only by those arms

urbit -F zod
> |new-desk %lagoon
> |mount %lagoon
git clone https://github.com/urbit/numerics
cp -Lr numerics/lagoon/desk/* zod/lagoon/
echo '[%zuse 409]' > zod/lagoon/sys.kelvin

in zod/lagoon/gen/test-el-wise.hoon:

/-  ls=lagoon
/+  *lagoon
:-  %say
|=  *
:-  %noun
=/  la  (lake %n)
=/  meta=meta:ls  [~[4] 5 %i754 ~]
::  build [1.0 2.0 3.0 4.0] — ordered so any reversal is unambiguous
=/  r  (zeros:la meta)
=/  r  (set-item:la r ~[0] .1)
=/  r  (set-item:la r ~[1] .2)
=/  r  (set-item:la r ~[2] .3)
=/  r  (set-item:la r ~[3] .4)
::  call el-wise-op directly with identity so no jet can mask the bug
=/  out  (el-wise-op:la r |=(x=@ x))
=/  vals
  :~  `@rs`(get-item:la out ~[0])
      `@rs`(get-item:la out ~[1])
      `@rs`(get-item:la out ~[2])
      `@rs`(get-item:la out ~[3])
  ==
~&  >  ['el-wise-op id [1 2 3 4]' vals]
~&  >  ?:  =(vals ~[`@rs`.1 `@rs`.2 `@rs`.3 `@rs`.4])
         'PASS — [1 2 3 4]'
       ?:  =(vals ~[`@rs`.4 `@rs`.3 `@rs`.2 `@rs`.1])
         'FAIL — reversed to [4 3 2 1]'
       'FAIL — other'
~
> |commit %lagoon
> +lagoon!test-el-wise

Output:

>   ['el-wise-op id [1 2 3 4]' ~[.4 .3 .2 .1]]
>   'FAIL — reversed to [4 3 2 1]'

fix is ez

    =/  ali  (ravel a)

after which the same generator returns ~[.1 .2 .3 .4] as expected

@sigilante sigilante merged commit 9dc7bd7 into urbit:main May 30, 2026
@sigilante
Copy link
Copy Markdown
Collaborator

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants