NEIGHBOR function in RPL
06-05-2015, 09:03 PM
Post: #1
 Joe Horn Senior Member Posts: 1,454 Joined: Dec 2013
NEIGHBOR function in RPL
The HP-71B Math ROM has a nifty function called NEIGHBOR(X,Y) which returns the nearest machine-representable number to X in the direction towards Y. For example, NEIGHBOR(5,7) returns 5.00000000001, and NEIGHBOR(5,1) returns 4.99999999999.

I'm looking for a User RPL implementation of that function. All my attempts fail when X is a power of 10 and Y<X. For example, NEIGHBOR(1,0) should return 0.999999999999 (twelve 9's), but I'm only getting eleven 9's. It's driving me crazier.

Any and all insights will be greatly appreciated.

BTW, I want to use the NEIGHBOR function in an program to be called "UNROUND", which takes any input J (which contains N digits after the decimal point) and returns the smallest and greatest numbers which round to J when N RND is executed. Example: 0.123 UNROUND should yield 0.1225 and 0.123499999999 because those are the smallest and greatest numbers (respectively) which yield 0.123 when 3 RND is executed. If you already have such a program, I'd love to see that too.

<0|ɸ|0>
-Joe-
06-05-2015, 10:04 PM
Post: #2
 Dave Britten Senior Member Posts: 1,089 Joined: Dec 2013
RE: NEIGHBOR function in RPL
There's probably a more elegant way of doing this, but there's some really weird guard digit stuff going on here.

(Try this: 1 5E-12 + 6E-12 + 5E-12 + 5E-12 +. The results are... peculiar.)

Stupid special cases to the rescue. This seems to be working...

Code:
\<< \-> X Y   \<< X MANT IF DUP 1 SAME Y X < AND THEN -12 ALOG - ELSE     Y X - SIGN -11 ALOG * + END     X XPON ALOG * \>>
06-05-2015, 11:35 PM (This post was last modified: 06-06-2015 09:49 AM by Didier Lachieze.)
Post: #3
 Didier Lachieze Senior Member Posts: 1,135 Joined: Dec 2013
RE: NEIGHBOR function in RPL
I was working on a very similar solution on the Prime, but when I tested your code on the 48GX I found that it was not working for negative X, one of the reasons being that -5 MANT returns 5 on the 48, while on the Prime MANT(-5) returns -5.

So here is my RPL solution which seems to work for positive and negative numbers:

Code:
« → X Y   «  X MANT X SIGN * DUP DUP 1 SAME Y X < *      SWAP -1 SAME X Y < * + 11 + NEG ALOG     Y X - SIGN * + X XPON ALOG *   » »

And the Prime code:

Code:
EXPORT NEIGHBOR(X,Y) BEGIN   LOCAL m,n;   m:=MANT(X);   n:=ALOG(−(11+(m=1)*(X>Y)+(m=−1)*(X<Y)));   RETURN (m+n*SIGN(Y-X))*ALOG(XPON(X)); END;

EDIT: Updated to clean RPL code and remove the '\'s.
06-06-2015, 09:17 AM
Post: #4
 Gerald H Senior Member Posts: 1,409 Joined: May 2014
RE: NEIGHBOR function in RPL
(06-05-2015 10:04 PM)Dave Britten Wrote:  There's probably a more elegant way of doing this, but there's some really weird guard digit stuff going on here.

(Try this: 1 5E-12 + 6E-12 + 5E-12 + 5E-12 +. The results are... peculiar.)

Stupid special cases to the rescue. This seems to be working...

Code:
\<< \-> X Y   \<< X MANT IF DUP 1 SAME Y X < AND THEN -12 ALOG - ELSE     Y X - SIGN -11 ALOG * + END     X XPON ALOG * \>>

Solves the powers of 10 problem, gets signs wrong.
06-06-2015, 12:55 PM
Post: #5
 Werner Senior Member Posts: 349 Joined: Dec 2013
RE: NEIGHBOR function in RPL
and NEIGHBOR(0,1)? Should be 1e-499.

I have these:

Code:
@ NXT @ In: x @ Out: next number larger than x \<<   IF DUP THEN DUP XPON ELSE -488 END   ALOG SWAP OVER /     @ 10^n s*m   1E-11 OVER -1 SAME ALOG / + * \>>    @ PRV @ In: x @ Out: next number smaller than x \<< +/- NXT +/- \>> @ NEIGHBOR @ In: x y @ Out: next x in the direction of y \<< IF OVER < THEN PRV ELSE NXT END \>>

Cheers, Werner
06-06-2015, 03:03 PM
Post: #6
 Gerald H Senior Member Posts: 1,409 Joined: May 2014
RE: NEIGHBOR function in RPL
(06-06-2015 12:55 PM)Werner Wrote:  and NEIGHBOR(0,1)? Should be 1e-499.

I have these:

Code:
@ NXT @ In: x @ Out: next number larger than x \<<   IF DUP THEN DUP XPON ELSE -488 END   ALOG SWAP OVER /     @ 10^n s*m   1E-11 OVER -1 SAME ALOG / + * \>>    @ PRV @ In: x @ Out: next number smaller than x \<< +/- NXT +/- \>> @ NEIGHBOR @ In: x y @ Out: next x in the direction of y \<< IF OVER < THEN PRV ELSE NXT END \>>

Cheers, Werner

Powers of ten lack precision.
06-06-2015, 03:30 PM
Post: #7
 Werner Senior Member Posts: 349 Joined: Dec 2013
RE: NEIGHBOR function in RPL
(06-06-2015 03:03 PM)Gerald H Wrote:  Powers of ten lack precision.

? Do you have an example?
Werner
06-06-2015, 03:41 PM (This post was last modified: 06-06-2015 05:45 PM by Gerald H.)
Post: #8
 Gerald H Senior Member Posts: 1,409 Joined: May 2014
RE: NEIGHBOR function in RPL
Here my attempt, please be critical - just don't use 0 for input.

Input is one real number, output is the two neighbours.

Code:
DCUT « DUP SIGN SWAP DUP NOV 3 PICK * UNROT NUN * » NOV « DUP XPON ALOG SWAP MANT -11. ALOG + * » NUN « DUP XPON ALOG SWAP MANT -11. OVER 1 == - ALOG - * »
06-06-2015, 03:45 PM
Post: #9
 Gerald H Senior Member Posts: 1,409 Joined: May 2014
RE: NEIGHBOR function in RPL
(06-06-2015 03:30 PM)Werner Wrote:
(06-06-2015 03:03 PM)Gerald H Wrote:  Powers of ten lack precision.

? Do you have an example?
Werner

Sorry, I believe I erred - I now believe yours is a complete solution, sadly I realize this too late to obviate my producing my effort above.
06-06-2015, 03:50 PM (This post was last modified: 06-06-2015 03:51 PM by Gerald H.)
Post: #10
 Gerald H Senior Member Posts: 1,409 Joined: May 2014
RE: NEIGHBOR function in RPL
06-06-2015, 10:57 PM
Post: #11
 Didier Lachieze Senior Member Posts: 1,135 Joined: Dec 2013
RE: NEIGHBOR function in RPL
(06-06-2015 12:55 PM)Werner Wrote:  and NEIGHBOR(0,1)? Should be 1e-499.
You're right, I've updated my programs:

RPL code:
Code:
« → X Y   «  X MANT X SIGN * DUP DUP 1 SAME Y X < *      SWAP -1 SAME X Y < * + 11 + NEG ALOG     Y X - SIGN * + X DUP XPON -488 IFTE ALOG *   » »

Prime code:
Code:
EXPORT NEIGHBOR(X,Y) BEGIN   LOCAL m,n;   m:=MANT(X);   n:=ALOG(−(11+(m=1)*(X>Y)+(m=−1)*(X<Y)));   (m+n*SIGN(Y-X))*ALOG(IFTE(X,XPON(X),-488)); END;
 « Next Oldest | Next Newest »

User(s) browsing this thread: 1 Guest(s)