How to implement this fast doubling Fibonacci algorithm in Clojure? - clojure

Here is my way of finding the nth Fibonacci number:
(defn fib-pair [[a b]]
"Return the next Fibonacci pair number based on input pair."
[b (+' a b)]) ; Use +' for automatic handle large numbers (Long -> BigInt).
(defn fib-nth [x]
"Return the nth Fibonacci number."
(nth (map first (iterate fib-pair [0 1])) x))
I know this may be not the most efficient way, and I found the fast doubling algorithms.
The algorithm contains matrix and math equations, I don't know how to set them in Stack Overflow, please visit:
https://www.nayuki.io/page/fast-fibonacci-algorithms
I tried the Python implementation provided by that website, it is really fast. How to implement it in Clojure?
Edit: Python implementation provided by that website:
# Returns F(n)
def fibonacci(n):
if n < 0:
raise ValueError("Negative arguments not implemented")
return _fib(n)[0]
# Returns a tuple (F(n), F(n+1))
def _fib(n):
if n == 0:
return (0, 1)
else:
a, b = _fib(n // 2)
c = a * (2 * b - a)
d = b * b + a * a
if n % 2 == 0:
return (c, d)
else:
return (d, c + d)

I haven't checked for performance, but this appears to be a faithful implementation in Clojure:
(defn fib [n]
(letfn [(fib* [n]
(if (zero? n)
[0 1]
(let [[a b] (fib* (quot n 2))
c (*' a (-' (*' 2 b) a))
d (+' (*' b b) (*' a a))]
(if (even? n)
[c d]
[d (+' c d)]))))]
(first (fib* n))))

Related

Factorial iterative illegal argument - clojure

(defn fac [n]
(def result 1)
(loop [i n c 1]
(if (<= c 5)
result
(recur (* c i) (inc c))
)
)
(println result)
)
(fac 5)
Error:Exception in thread "main" java.lang.IllegalArgumentException: loop requires a vector for its binding.
I am trying to write a function that evaluates a numbers factorial. Where is my mistake? It gives me 1 as answer
At first sight:
Don't use a def inside a defn.
The REPL will print the result of evaluating a function. Use it.
This gets us to
(defn fac [n]
(loop [i n c 1]
(if (<= c 5)
result
(recur (* c i) (inc c)))))
... which doesn't compile, because result is floating.
There are a few corrections required:
Return i, not result.
Start i at 1, not n.
Turn the test around: > instead of <=.
We end up with
(defn fac [n]
(loop [i 1, c 1]
(if (> c n)
i
(recur (* c i) (inc c)))))
... which works:
(fac 5)
=> 120
Edited to correct one-off error and improve explanation.

Storing fibonacci values

I did a very simple solution to fibonacci:
(defn fib [n]
(if (or (zero? n) (= n 1))
1
(+ (fib (dec n)) (fib (- n 2)))))
but instead of returning the value, for example
(fib 6) ; 13
I would return the sequence 0, 1, 1, 2, 3, 5, 8, 13... I was thinking about store the values in a sequence, but where should I return the sequence? I mean, verifying if I'm at the last call of fib does not sound much nice.
ps: I'm trying to solve this exercise: https://www.4clojure.com/problem/26
Clojure functions return the result of the last evaluated form. You could accumulate your Fibonacci numbers in a vector.
A nice lazy version of fibonacci is:
(def lazy-fib
"Lazy sequence of fibonacci numbers"
((fn rfib [a b]
(lazy-seq (cons a (rfib b (+' a b)))))
0 1))
Then you can use it with:
(fn [n] (take n lazy-fib))
Which gives, after some formatting for this problem:
(fn[n]
(drop 1 (take (inc n) ((fn rfib [a b]
(lazy-seq (cons a (rfib b (+' a b)))))
0 1))))

How to check whether a number is Fibonacci number in Clojure?

Input: a positive integer.
Output: true / false based on test.
Here is my attempt:
(defn is-a-fib? [x]
"Check whether x is a fibonacci number.
Algorithm: test whether 5x^2+4 or 5x^2-4 is a perfect square."
(let [a (+' (*' (Math/pow x 2) 5) 4) ; 5x^2+4
b (-' (*' (Math/pow x 2) 5) 4) ; 5x^2-4
sqrt-a (Math/sqrt a)
sqrt-b (Math/sqrt b)]
(or (== (*' sqrt-a sqrt-a)
(*' (Math/floor sqrt-a) (Math/floor sqrt-a))) ; Test whether n is a perfect square
(== (*' sqrt-b sqrt-b)
(*' (Math/floor sqrt-b) (Math/floor sqrt-b))))))
The problem is: this code doesn't work for a large number. I think it may cause stack overflow.
Is there a better way?
The Math/pow, Math/sqrt, and Math/floor operations work on doubles which have a limited range of precision, and operations on them will have rounding errors.
If you look at it in this light, things may derail simply owing to rounding, but they will really go wrong when you've exhausted the precision (15–17 decimal digits).
This first nth Fibonnacci where this algorithm gives a false positive for the subsequent integer is for the 16-digit integer associated with n = 74.
(is-a-fib? 1304969544928657)
=> true
(is-a-fib? 1304969544928658)
=> true
Edit: Adding arbitrary precision solution that avoids doubles:
The main difficulty is the lack of an integer square root algorithm.
This Java implementation can be translated to Clojure:
(defn integer-sqrt [n]
(let [n (biginteger n)]
(loop [a BigInteger/ONE
b (-> n (.shiftRight 5) (.add (biginteger 8)))]
(if (>= (.compareTo b a) 0)
(let [mid (-> a (.add b) (.shiftRight 1))]
(if (pos? (-> mid (.multiply mid) (.compareTo n)))
(recur a (.subtract mid BigInteger/ONE))
(recur (.add mid BigInteger/ONE) b)))
(dec a)))))
With that in place, you can define an arbitrary-precision perfect square test:
(defn perfect-square? [n]
(let [x (integer-sqrt n)]
(= (*' x x) n)))
And update your implementation to use it:
(defn is-a-fib? [x]
"Check whether x is a fibonacci number.
Algorithm: test whether 5x^2+4 or 5x^2-4 is a perfect square."
(let [a (+' (*' (*' x x) 5) 4) ; 5x^2+4
b (-' (*' (*' x x) 5) 4)] ; 5x^2-4
(or (perfect-square? a)
(perfect-square? b))))

if I have the public and private keys of an rsa key, how do I calculate seeds p and q?

This is a repeat of this question: Calculate primes p and q from private exponent (d), public exponent (e) and the modulus (n)
I'm just explicitly stating the problem and asking for a solution - hopefully in clojure:
public key (n):
8251765078168273332294927113607583143463818063169334570141974734622347615608759376136539680924724436167734207457819985975399290886224386172465730576481018297063
private key (d):
3208816897586377860956958931447720469523710321495803767643746679156057326148423456475670861779003305999429436586281847824835615918694834568426186408938023979073
exponent (e): 65537
and I want to get the seeds: p and q
p: 87270901711217520502010198833502882703085386146216514793775433152756453168234183
q: 87270901711217520502010198833502882703085386146216514793775433152756453168234183
To get n and d in the first place is not too hard:
(defn egcd [a b]
(if (= a 0)
[b, 0, 1]
(let [[g y x] (egcd (mod b a) a)]
[g (- x (* y (quot b a))) y])))
(defn modinv [a m]
(let [[g y x] (egcd a m)]
(if (not= 1 g)
(throw (Exception. "Modular Inverse Does Not Exist"))
y)))
(def n (* p q))
(def d (modinv e (* (dec p) (dec q)))
Now I require a reverse transform.
The algorithm Thomas Pornin posted in response to the question you link to works perfectly. Transcribed into Clojure, it looks like this:
;; using math.numeric-tower 0.0.4
(require '[clojure.math.numeric-tower :as num])
(defn find-ks [e d n]
(let [m (num/round (/ (*' e d) n))]
((juxt dec' identity inc') m)))
(defn phi-of-n [e d k]
(/ (dec' (*' e d)) k))
(defn p-and-q [p+q pq]
[(/ (+' p+q (num/sqrt (-' (*' p+q p+q) (*' 4 pq)))) 2)
(/ (-' p+q (num/sqrt (-' (*' p+q p+q) (*' 4 pq)))) 2)])
(defn verify [n p q]
(== n (*' p q)))
(defn solve [e d n]
(first
(for [k (find-ks e d n)
:let [phi (phi-of-n e d k)
p+q (inc' (-' n phi))
[p q] (p-and-q p+q n)]
:when (verify n p q)]
[p q])))
Applying this to your e, d and n we get
(solve 65537N 3208816897586377860956958931447720469523710321495803767643746679156057326148423456475670861779003305999429436586281847824835615918694834568426186408938023979073N 8251765078168273332294927113607583143463818063169334570141974734622347615608759376136539680924724436167734207457819985975399290886224386172465730576481018297063N)
;= [94553452712951836476229946322137980113539561829760409872047377997530344849179361N
87270901711217520502010198833502882703085386146216514793775433152756453168234183N]
You posted the same number as p and q, by the way -- the second one in the result vector above -- but it's easy to verify that these are the correct numbers by using the pair to rederive n and d.

Why am I getting a cast error when trying to use Simpson's rule in Clojure?

I'm trying to work through some of the exercises in SICP using Clojure, but am getting an error with my current method of executing Simpson's rule (ex. 1-29). Does this have to do with lazy/eager evalution? Any ideas on how to fix this? Error and code are below:
java.lang.ClassCastException: user$simpson$h__1445 cannot be cast to java.lang.Number
at clojure.lang.Numbers.divide (Numbers.java:139)
Here is the code:
(defn simpson [f a b n]
(defn h [] (/ (- b a) n))
(defn simpson-term [k]
(defn y [] (f (+ a (* k h))))
(cond
(= k 0) y
(= k n) y
(even? k) (* 2 y)
:else (* 4 y)))
(* (/ h 3)
(sum simpson-term 0 inc n)))
You define h as a function of no arguments, and then try to use it as though it were a number. I'm also not sure what you're getting at with (sum simpson-term 0 inc n); I'll just assume that sum is some magic you got from SICP and that the arguments you're passing to it are right (I vaguely recall them defining a generic sum of some kind).
The other thing is, it's almost always a terrible idea to have a def or defn nested within a defn. You probably want either let (for something temporary or local) or another top-level defn.
Bearing in mind that I haven't written a simpson function for years, and haven't inspected this one for algorithmic correctness at all, here's a sketch that is closer to the "right shape" than yours:
(defn simpson [f a b n]
(let [h (/ (- b a) n)
simpson-term (fn [k]
(let [y (f (+ a (* k h)))]
(cond
(= k 0) y
(= k n) y
(even? k) (* 2 y)
:else (* 4 y))))]
(* (/ h 3)
(sum simpson-term 0 inc n))))