implementing an algorithm to transform a real number to a continued fraction in #F - recursion

i am trying to implement a recursive function which takes a float and returns a list of ints representing the continued fraction representation of the float (https://en.wikipedia.org/wiki/Continued_fraction) In general i think i understand how the algorithm is supposed to work. its fairly simply. What i have so far is this:
let rec float2cfrac (x : float) : int list =
let q = int x
let r = x - (float q)
if r = 0.0 then
[]
else
q :: (float2cfrac (1.0 / r ))
the problem is with the base case obviously. It seems the value r never does reduce to 0.0 instead the algorithm keeps on returning values which are the likes of 0.0.....[number]. I am just not sure how to perform the comparison. How exactly should i go about it. The algorithm the function is based on says the base case is 0, so i naturally interpret this as 0.0. I dont see any other way. Also, do note that this is for an assignment where i am explicitly asked to implement the algorithm recursively. Does anyone have some guidance for me? It would be much appreciated

It seems the value r never does reduce to 0.0 instead the algorithm keeps on returning values which are the likes of 0.0.....[number].
This is a classic issue with floating point comparisons. You need to use some epsilon tolerance value for comparisons, because r will never reach exactly 0.0:
let epsilon = 0.0000000001
let rec float2cfrac (x : float) : int list =
let q = int x
let r = x - (float q)
if r < epsilon then
[]
else
q :: (float2cfrac (1.0 / r))
> float2cfrac 4.23
val it : int list = [4; 4; 2; 1]
See this MSDN documentation for more.
You could define a helper function for this:
let withinTolerance (x: float) (y: float) e =
System.Math.Abs(x - y) < e
Also note your original solution isn't tail-recursive, so it consumes stack as it recurses and could overflow the stack. You could refactor it such that a float can be unfolded without recursion:
let float2cfrac (x: float) =
let q = int x
let r = x - (float q)
if withinTolerance r 0.0 epsilon then None
else Some (q, (1.0 / r))
4.23 |> Seq.unfold float2cfrac // seq [4; 4; 2; 1]

Related

imperative programing to functional programming using recursion

I'm very new to functional programming. I'm struggling using recursion instead of for loop. Here's what I have so far.
let max_factor n =
let rec loop k =
if k >= n then []
else
begin
if k < n && n % k = 0 then
k :: loop(k+1)
end
my plan is to insert the ones into a list and then find the largest from the list. But I have a feeling I'm doing it wrong. With functional programming, is it always like "going around" or am I just a bad at this? is my approach way off? Can someone please guide me how I should approach this simple problem...
The equivalent to your java code would be
let max_factor (n : int) : int =
let rec loop i =
if i < 2 then 1
else if n mod i = 0 then i
else loop (i-1)
in loop (n / 2);; (* you don't want to start at n, which would trivially divide n *)

Functionally idiomatic FFT

I've written the this radix-2 FFT with the goal of making it functionally idiomatic without sacrificing too much performance:
let reverse x bits =
let rec reverse' x bits y =
match bits with
| 0 -> y
| _ -> ((y <<< 1) ||| (x &&& 1))
|> reverse' (x >>> 1) (bits - 1)
reverse' x bits 0
let radix2 (vector: Complex[]) (direction: int) =
let z = vector.Length
let depth = floor(Math.Log(double z, 2.0)) |> int
if (1 <<< depth) <> z then failwith "Vector length is not a power of 2"
// Complex roots of unity; "twiddle factors"
let unity: Complex[] =
let xpn = float direction * Math.PI / double z
Array.Parallel.init<Complex> (z/2) (fun i ->
Complex.FromPolarCoordinates(1.0, (float i) * xpn))
// Permutes elements of input vector via bit-reversal permutation
let pvec = Array.Parallel.init z (fun i -> vector.[reverse i depth])
let outerLoop (vec: Complex[]) =
let rec recLoop size =
if size <= z then
let mid, step = size / 2, z / size
let rec inrecLoop i =
if i < z then
let rec bottomLoop idx k =
if idx < i + mid then
let temp = vec.[idx + mid] * unity.[k]
vec.[idx + mid] <- (vec.[idx] - temp)
vec.[idx] <- (vec.[idx] + temp)
bottomLoop (idx + 1) (k + step)
bottomLoop i 0
inrecLoop (i + size)
inrecLoop 0
recLoop (size * 2)
recLoop 2
vec
outerLoop pvec
The outerLoop segment is the biggest nested tail-recursive mess I have ever written. I replicated the algorithm in the Wikipedia article for the Cooley-Tukey algorithm, but the only functional constructs I could think to implement using higher-order functions result in massive hits to both performance and memory efficiency. Are there other solutions that would yield the same results without resulting in massive slow-downs, while still being idiomatic?
I'm not an expert on how the algorithm works, so there might be a nice functional implementation, but it is worth noting that using a localised mutation is perfectly idiomatic in F#.
Your radix2 function is functional from the outside - it takes vector array as an input, never mutates it, creates a new array pvec which it then initializes (using some mutation along the way) and then returns it. This is a similar pattern to what built-in functions like Array.map use (which initializes a new array, mutates it and then returns it). This is often a sensible way of doing things, because some algorithms are better written using mutation.
In this case, it's perfectly reasonable to also use local mutable variables and loops. Doing that will make your code more readable compared to the tail-recursive version. I have not tested this, but my naive translation of your outerLoop function would just be to use three nested loops - something like this:
let mutable size = 2
while size <= z do
let mid, step = size / 2, z / size
let mutable i = 0
while i < z do
for j in 0 .. mid - 1 do
let idx, k = i + j, step * j
let temp = pvec.[idx + mid] * unity.[k]
pvec.[idx + mid] <- (pvec.[idx] - temp)
pvec.[idx] <- (pvec.[idx] + temp)
i <- i + size
size <- size * 2
This might not be exactly right (I did this just be refactoring your code), but I think it's actually more idiomatic than using complex nested tail-recursive functions in this case.

Unexpected output type

I am doing practice with F#. I am trying to create a simple program capable to find me out a couple of prime numbers that, summed together, equal a natural number input. It is the Goldbach conjecture. A single couple of primes will be enough. We will assume the input to be a even number.
I first created a function to check if a number is prime:
let rec isPrime (x: int) (i: int) :bool =
match x % i with
| _ when float i > sqrt (float x) -> true
| 0 -> false
| _ -> isPrime x (i + 1)
Then, I am trying to develop a function that (a) looks for prime numbers, (b) compare their sum with the input 'z' and (c) returns a tuple when it finds the two numbers. The function should not be correct yet, but I would get the reason behind this problem:
let rec sumPrime (z: int) (j: int) (k: int) :int * int =
match isPrime j, isPrime k with
| 0, 0 when j + k > z -> (0, 0)
| 0, 0 -> sumPrime (j + 1) (k + 1)
| _, 0 -> sumPrime j (k + 1)
| 0, _ -> sumPrime (j + 1) k
| _, _ -> if j + k < z then
sumPrime (j + 1) k
elif j + k = z then
(j, k)
The problem: even if I specified that the output should be a tuple :int * int the compiler protests, claiming that the expected output should be of type bool. When in trouble, I usually refer to F# for fun and profit, that i love, but this time I cannot find out the problem. Any suggestion is greatly appreciated.
Your code has three problems that I've spotted:
Your isPrime returns a bool (as you've specified), but your match expression in sumPrime is matching against integers (in F#, the Boolean value false is not the same as the integer value 0). Your match expression should look like:
match isPrime j, isPrime k with
| false, false when j + k > z -> (0, 0)
| false, false -> ...
| true, false -> ...
| false, true -> ...
| true, true -> ...
You have an if...elif expression in your true, true case, but there's no final else. By default, the final else of an if expression returns (), the unit type. So once you fix your first problem, you'll find that F# is complaining about a type mismatch between int * int and unit. You'll need to add an else condition to your final match case to say what to do if j + k > z.
You are repeatedly calling your sumPrime function, which takes three parameters, with just two parameters. That is perfectly legal in F#, since it's a curried language: calling sumPrime with two parameters produces the type int -> int * int: a function that takes a single int and returns a tuple of ints. But that's not what you're actually trying to do. Make sure you specify a value for z in all your recursive calls.
With those three changes, you should probably see your compiler errors go away.

passing a function to a function SML

Below is SML code to compute a definite integral using the trapezoidal method given input f=unary function, a & b=range to take integral under, and n=number of sub-intervals to divide the range into.
fun integrate f a b n =
let val w = (b - a) / (real n)
fun genBlock c = let val BB = f c
val SB = f (c+w)
in (BB + SB) * w / 2.0
end
fun sumSlice 0 c acc = acc
| sumSlice n c acc = sumSlice (n-1) (c+w) (acc + (genBlock c))
in sumSlice n a 0.0
end
Problem is I can't figure out for the life of me how to define a function (say X cubed) and feed it to this function with a,b, and n. Here's a screenshot of me trying and receiving an error:
In this picture I define cube x =xxx and show it works, then try to feed it to the integrate function to no avail.
The error message is pretty specific: integrate is expecting a function of type real -> real but you defined a function, cube, of type int -> int.
There are a couple of things you can do:
1) Add a type annotation to the definition of cube:
- fun cube x:real = x*x*x;
val cube = fn : real -> real
And then:
- integrate cube 0.0 5.0 5;
val it = 162.5 : real
2) You can dispense with defining cube as a named function and just pass the computation as an anonymous function. In this case, SML's type inference mechanism gives the function x => x*x*x the intended type:
- integrate (fn x => x*x*x) 0.0 5.0 5;
val it = 162.5 : real

Stack overflow during evaluation (looping recursion?). OCaml

I'm trying to write a function that accepts an int n and returns a list that runs down from n to 0.
This is what I have
let rec downFrom n =
let m = n+1 in
if m = 0 then
[]
else
(m-1) :: downFrom (m - 1);;
The function compiles ok but when I test it with any int it gives me the error
Stack overflow during evaluation (looping recursion?).
I know it's the local varible that gets in the way but I don't know another way to declare it. Thank you!!!
First, the real thing wrong with your program is that you have an infinite loop. Why, because your inductive base case is 0, but you always stay at n! This is because you recurse on m - 1 which is really n + 1 - 1
I'm surprised as to why this compiles, because it doesn't include the rec keyword, which is necessary on recursive functions. To avoid stack overflows in OCaml, you generally switch to a tail recursive style, such as follows:
let downFrom n =
let rec h n acc =
if n = 0 then List.rev acc else h (n-1) (n::acc)
in
h n []
Someone suggested the following edit:
let downFrom n =
let rec h m acc =
if m > n then acc else h (m + 1) (m::acc)
in
h 0 [];
This saves a call to List.rev, I agree.
The key with recursion is that the recursive call has to be a smaller version of the problem. Your recursive call doesn't create a smaller version of the problem. It just repeats the same problem.
You can try with a filtering parameter
syntax:
let f = function
p1 -> expr1
| p2 -> expr2
| p3 -> ...;;
let rec n_to_one =function
0->[]
|n->n::n_to_one (n-1);;
# n_to_one 3;;
- : int list = [3; 2; 1]

Resources