Post Reply 
NEIGHBOR function in RPL
06-05-2015, 09:03 PM
Post: #1
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-
Visit this user's website Find all posts by this user
Quote this message in a reply
06-05-2015, 10:04 PM
Post: #2
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 *
\>>
Visit this user's website Find all posts by this user
Quote this message in a reply
06-05-2015, 11:35 PM (This post was last modified: 06-06-2015 09:49 AM by Didier Lachieze.)
Post: #3
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.
Find all posts by this user
Quote this message in a reply
06-06-2015, 09:17 AM
Post: #4
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.
Find all posts by this user
Quote this message in a reply
06-06-2015, 12:55 PM
Post: #5
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

41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L,12C,16CE
Find all posts by this user
Quote this message in a reply
06-06-2015, 03:03 PM
Post: #6
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.
Find all posts by this user
Quote this message in a reply
06-06-2015, 03:30 PM
Post: #7
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

41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L,12C,16CE
Find all posts by this user
Quote this message in a reply
06-06-2015, 03:41 PM (This post was last modified: 06-06-2015 05:45 PM by Gerald H.)
Post: #8
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 - *
»
Find all posts by this user
Quote this message in a reply
06-06-2015, 03:45 PM
Post: #9
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.
Find all posts by this user
Quote this message in a reply
06-06-2015, 03:50 PM (This post was last modified: 06-06-2015 03:51 PM by Gerald H.)
Post: #10
RE: NEIGHBOR function in RPL
Please ignore this posting.
Find all posts by this user
Quote this message in a reply
06-06-2015, 10:57 PM
Post: #11
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;
Find all posts by this user
Quote this message in a reply
Post Reply 




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