Jerry wrote:
Ladislav,
I am impressed by your recursive fib. In fact it inspired me to write a
zero finding routine in a similar manner. If I am not imposing too much,
can you tell me if it is functional programming?
Jerry
- Actually, this version of FIB is twice as fast (and twice as simple):
fib2: func [first second n] [
either n = 1 [first] [
fib2 second first + second n - 1
]
]
>> x: binsrch "x - exp - x" 'x 0 1
== 0.567143290409784
>> exp - x
== 0.567143290409784
>>
xeq: func [f v x] [do join v [": " x] do f]
binsrch: func [f v b e] [
if ((xeq f v b) * (xeq f v e)) > 0
[print "binsrch: f must have different signs at endpoints"
return none]
either (xeq f v b) < 0
[binsrch0 f v b e 50]
[binsrch0 f v e b 50]
]
binsrch0: function [f v b e n] [x] [
x: b + e / 2
if n = 0 [return x]
either (xeq f v x) < 0
[binsrch0 f v x e n - 1]
[binsrch0 f v b x n - 1]
]
- Well, some purists may have some objections against IF (they'd prefer
EITHER
probably) and RETURN, I don't see anything wrong regarding
"functional-ness".
(I am not an expert, to be honest)
What I would suggest is to write it like this:
binsrch2: func [fn start end n /local fs] [
either (fs: fn start) * (fn end) > 0 [
print "binsrch: f must have different signs at endpoints"
none
] [
either fs < 0 [
bsrch :fn start end n
] [
bsrch :fn end start n
]
]
]
bsrch: func [fn start end n /local x] [
x: start + end / 2.0
either n = 0 [x] [
either (fn x) < 0 [
bsrch :fn x end n - 1
] [
bsrch :fn start x n - 1
]
]
]
binsrch2 func [x] [x - exp - x] 0 1 50
- This version is about 8 times faster (measured on the given example) and
more readable
Ladislav