Fibonacci Matrix - fibonacci

For calculating a fibonacci sequence in O(logn) we use matrix exponential since the term
fn = fn-1 + fn-2 is linear but what is the matrix required if we want to find nth term of
fn = fn-1 + fn-2 + a0 + a1*n + a2*n^2 + ... an*n^n
which is a dependent on polynomial???
Here a0,a1,... an are constants

Look here for implementation in Erlang which uses formula
. It shows nice linear resulting behavior because in O(M(n) log n) part M(n) is exponential for big numbers. It calculates fib of one million in 2s where result has 208988 digits. The trick is that you can compute exponentiation in O(log n) multiplications using (tail) recursive formula (tail means with O(1) space when used proper compiler or rewrite to cycle):
% compute X^N
power(X, N) when is_integer(N), N >= 0 ->
power(N, X, 1).
power(0, _, Acc) ->
Acc;
power(N, X, Acc) ->
if N rem 2 =:= 1 ->
power(N - 1, X, Acc * X);
true ->
power(N div 2, X * X, Acc)
end.
where X and Acc you substitute with matrices. X will be initiated with and Acc with identity I equals to .

Related

Taylor series via F#

I'm trying to write Taylor series in F#.
Have a look at my code
let rec iter a b f i =
if a > b then i;
else f a (iter (a+1) b f i)
let sum a b = iter a b (+) 0 // from 0
// e^x = 1 + x + (x^2)/2 + ... (x^n)/n! + ...
let fact n = iter 1 n (*) 1 // factorial
let pow x n = iter 1 n (fun n acc -> acc * x) 1
let exp x =
iter 0 x
(fun n acc ->
acc + (pow x n) / float (fact n)) 0
In the last row I am trying cast int fact n to float, but seems like I'm wrong because this code isn't compileable :(
Am I doing the right algorithm?
Can I call my code functional-first?
The code doesn't compile, because:
You're trying to divide an integer pow x n by a float. Division has to have operands of the same type.
You're specifying the terminal case of the wrong type. Literal 0 is integer. If you want float zero, use 0.0 or abbreviated 0.
Try this:
let exp x =
iter 0 x
(fun n acc ->
acc + float (pow x n) / float (fact n)) 0.
P.S. In the future, please provide the exact error messages and/or unexpected results that you're getting. Simply saying "doesn't work" is not a good description of a problem.

Logarithm of Gaussian converting from zero

I have a vector V of 256 position. For each position in the vector I want to calculate the density from a Gaussian distribution:
V[0] -> p(V[0])
V[1] -> p(V[1])
...
V[255] -> p(V[255])
After that I want to multiply all the probabilities together:
p(V[0]) * p(V[1]) * ... * p(V[255])
The problem with this method in my implementation is that each probability is high (around ~400), so I cannot multiply everything together.
A workaround for that would be taking the log of each Gaussian and then adding all together:
V[0] -> log(p(V[0]))
V[1] -> log(p(V[1]))
...
V[255] -> log(p(V[255]))
log(p(V[0])) + log(p(V[1])) + ... + log(p(V[255]))
But when I try to do that I get an error when the Gaussian results in zero.
Having this in mind, is there any workaround the log(0) problem? Would be an accurate representation replace log(0)for 0?
EDIT:
So, for the record, If I try the normal method (multiplying), the error that I get is this one:
iex(6)> Naive.CLI.main(["~/data/usps.csv", "~/indices/17.csv"])
** (ArithmeticError) bad argument in arithmetic expression
:erlang.*(417.62100246853674, 6.504406716503509e307)
From what I understand the numbers are too high for the multiplication take effect.
Here is what I did (and I think should be the right idea):
def gaussian(vector, mean, variance) do
vector
|> Enum.zip(mean)
|> Enum.zip(variance)
|> Enum.map(fn {{e, m}, v} -> {e, m, v} end)
|> Enum.map(fn {e, m, v} -> calculate(e, m, v) end)
|> Enum.map(fn e ->
if e == 0.0 do
0.0
else
:math.log10(e)
end
end)
end
defp calculate(elem, mean, variance) do
(1/:math.sqrt(2*:math.pi*variance)) *
:math.exp(-0.5*(((elem - mean)*(elem - mean)) / variance))
end
Basically if the Gaussian results in zero, I return zero as well.

F# Pattern matching and functions

I tried to implement the fibonacci sequence in F# using pattern matching like this:
let fibonacci m=
let rec fib = function
| (0, _, z) -> z
| (n, y, z) -> fib (n-1) z (y+z)
fib m 0 1
Here I expect the first argument to fib to keep track of how far along in the sequence we are, and the next two arguments to be successive terms in the sequence.
However, I'm getting a compile-time error on fib (n-1) z (y+z):
Type mismatch. Expecting a
'a -> 'b -> 'c
but given a
'c
The resulting type would be infinite when unifying ''a' and ''b -> 'c -> 'a'
I tried specifying types like so:
let fibonacci m=
let rec fib = function
| (0, _, z:int) -> z
| (n:int, y:int, z:int) -> fib (n-1) z (y+z)
fib m 0 1
And then I get a different compile error on fib (n-1):
This value is not a function and cannot be applied
I'm still trying to get my head around functional programming. I think the problem might be my lack of understanding in what the first pattern actually means. I want it mean that when the position argument is zero, it returns the second argument term.
Could someone help me with this problem which is obviously due to some basic misunderstanding on my part
The problem is you're calling the function with curried arguments when in fact is defined as expecting tupled arguments:
let fibonacci m =
let rec fib = function
| (0, _, z) -> z
| (n, y, z) -> fib (n-1, z, y+z)
fib (m, 0, 1)
This is because you are using function which pattern match a single argument, in your case against a tuple. The alternative is to use match
let fibonacci m =
let rec fib a b c =
match (a, b, c) with
| (0, _, z) -> z
| (n, y, z) -> fib (n-1) z (y+z)
fib m 0 1
You can think of function as a shorthand for a single argument function followed by a match over that argument.

How to get an random integer with limit length?

I want to create a function get_id(max_length). At first want to math:pow/2, but it return float data type. It seems not a good idea.
with code as follows, but only support max length=20, as it is hardcoded, any good idea?
seed()->
{M_a,M_b,M_c} = now(),
random:seed(M_a,M_b,M_c),
ok.
get_id(1)-> random:uniform(1);
get_id(2) -> random:uniform(10);
get_id(3) -> random:uniform(100);
get_id(4) -> random:uniform(1000);
get_id(5) -> random:uniform(10000);
get_id(6) -> random:uniform(100000);
get_id(7) -> random:uniform(1000000);
get_id(8) -> random:uniform(10000000);
get_id(9) -> random:uniform(100000000);
get_id(10) -> random:uniform(1000000000);
get_id(11) -> random:uniform(10000000000);
get_id(12) -> random:uniform(100000000000);
get_id(13) -> random:uniform(1000000000000);
get_id(14) -> random:uniform(10000000000000);
get_id(15) -> random:uniform(100000000000000);
get_id(16) -> random:uniform(1000000000000000);
get_id(17) -> random:uniform(10000000000000000);
get_id(18) -> random:uniform(100000000000000000);
get_id(19) -> random:uniform(1000000000000000000);
get_id(20) -> random:uniform(10000000000000000000).
Your approach, unfortunately, doesn't work. Indeed, while random:uniform/1 accepts any positive integer as its argument, it does not deliver a random integer uniformly distributed between 1 and N for very large values of N (in spite of what documentation claims).
The reason is that random:uniform/1 is actually truncating the product of its argument by the value of random:uniform/0 (and adding 1 for [1-N] range instead of [0-(N-1)]).
See source code: https://github.com/erlang/otp/blob/maint/lib/stdlib/src/random.erl#L112
And floats are IEEE 754 doubles with 53 bits mantissa, which means that get_id/1 will not return all possible values for input from 17 to 20 (with 16 or more digits).
random:uniform/0,1 is known as a poor random generator, mostly suitable if you want to generate reproductible pseudo-random series (a given seed value will always generate the same series). For this reason, I would suggest using crypto:rand_uniform/2.
A simple solution would be to compute 10^(N-1) using integer arithmetics (to avoid the 53 bits mantissa issue) and then call crypto:rand_uniform/2. You can perform this with a naive recursive implementation (pow1/1 below), or use binary exponentiation (pow2/1 below).
-define(BASE, 10).
-spec pow1(non_neg_integer()) -> pos_integer().
pow1(N) when N >= 0 ->
pow1(N, 1).
pow1(0, Acc) -> Acc;
pow1(N, Acc) ->
pow1(N - 1, Acc * ?BASE).
-spec pow2(non_neg_integer()) -> pos_integer().
pow2(N) when N >= 0 ->
pow2(?BASE, N, 1).
pow2(_X, 0, Acc) ->
Acc;
pow2(X, N, Acc) when N rem 2 =:= 0 ->
pow2(X * X, N div 2, Acc);
pow2(X, N, Acc) ->
pow2(X * X, N div 2, Acc * X).
Your function could simply be written as:
-spec get_id2(pos_integer()) -> non_neg_integer().
get_id2(N) ->
1 + crypto:rand_uniform(0, pow2(N - 1)).
Alternatively, you could use a combination of uniform random variables, one per digit (while the sum of two random uniform variables is generally not a uniform random variable, it is if combined like this) or for several digits in the case of the binary exponentiation.
With the naive exponentiation:
-spec get_id3(pos_integer()) -> pos_integer().
get_id3(N) when N > 0 ->
get_id3(N - 1, 0).
get_id3(0, Acc) -> 1 + Acc;
get_id3(N, Acc) ->
Acc1 = crypto:rand_uniform(0, ?BASE) + (Acc * ?BASE),
get_id3(N - 1, Acc1).
With the binary exponentiation:
-spec get_id4(pos_integer()) -> pos_integer().
get_id4(N) when N > 0 ->
get_id4(?BASE, N - 1, 0).
get_id4(_X, 0, Acc) ->
1 + Acc;
get_id4(X, N, Acc) when N rem 2 =:= 0 ->
get_id4(X * X, N div 2, Acc);
get_id4(X, N, Acc) ->
Acc1 = crypto:rand_uniform(0, X) + (Acc * X),
get_id4(X * X, N div 2, Acc1).
Why not use trunc/1 to cast the floats returned by math:pow/2 to integers? http://www.erlang.org/doc/man/erlang.html#trunc-1
like in any language, you can get a power of 2 by shifting left the number 1:
1> 1 bsl 3.
8
2> 1 bsl 8.
256
3> 1 bsl 852.
30030067315218800919884630782037027445247038374198014146711597563050526250476926831789640794321325523394216076738821850476730762665208973047045843626559620640158907690363610309346513399556581649279919071671610504617321356178738468477058455548958390664298496
4>
As you can see, the size of integer is not limited in erlang. It is both good and bad since small integer (that is integer represented as a single worg like in most languages) are limited depending on the architecture:
On 32-bit architectures: -134217729 < i < 134217728 (28 bits)
On 64-bit architectures: -576460752303423489 < i < 576460752303423488 (60 bits)
for bigger integer, another representation is used: big integer, that takes more space in memory and take longer to compute.

How to make this simple recurrence relationship (difference equation) tail recursive?

let rec f n =
match n with
| 0 | 1 | 2 -> 1
| _ -> f (n - 2) + f (n - 3)
Without CPS or Memoization, how could it be made tail recursive?
let f n = Seq.unfold (fun (x, y, z) -> Some(x, (y, z, x + y))) (1I, 1I, 1I)
|> Seq.nth n
Or even nicer:
let lambda (x, y, z) = x, (y, z, x + y)
let combinator = Seq.unfold (lambda >> Some) (1I, 1I, 1I)
let f n = combinator |> Seq.nth n
To get what's going on here, refer this snippet. It defines Fibonacci algorithm, and yours is very similar.
UPD There are three components here:
The lambda which gets i-th element;
The combinator which runs recursion over i; and
The wrapper that initiates the whole run and then picks up the value (from a triple, like in #Tomas' code).
You have asked for a tail-recursive code, and there are actually two ways for that: make your own combinator, like #Tomas did, or utilize the existing one, Seq.unfold, which is certainly tail-recursive. I preferred the second approach as I can split the entire code into a group of let statements.
The solution by #bytebuster is nice, but he does not explain how he created it, so it will only help if you're solving this specific problem. By the way, your formula looks a bit like Fibonacci (but not quite) which can be calculated analytically without any looping (even without looping hidden in Seq.unfold).
You started with the following function:
let rec f0 n =
match n with
| 0 | 1 | 2 -> 1
| _ -> f0 (n - 2) + f0 (n - 3)
The function calls f0 for arguments n - 2 and n - 3, so we need to know these values. The trick is to use dynamic programming (which can be done using memoization), but since you did not want to use memoization, we can write that by hand.
We can write f1 n which returns a three-element tuple with the current and two past values values of f0. This means f1 n = (f0 (n - 2), f0 (n - 1), f0 n):
let rec f1 n =
match n with
| 0 -> (0, 0, 1)
| 1 -> (0, 1, 1)
| 2 -> (1, 1, 1)
| _ ->
// Here we call `f1 (n - 1)` so we get values
// f0 (n - 3), f0 (n - 2), f0 (n - 1)
let fm3, fm2, fm1 = (f1 (n - 1))
(fm2, fm1, fm2 + fm3)
This function is not tail recurisve, but it only calls itself recursively once, which means that we can use the accumulator parameter pattern:
let f2 n =
let rec loop (fm3, fm2, fm1) n =
match n with
| 2 -> (fm3, fm2, fm1)
| _ -> loop (fm2, fm1, fm2 + fm3) (n - 1)
match n with
| 0 -> (0, 0, 1)
| 1 -> (0, 1, 1)
| n -> loop (1, 1, 1) n
We need to handle arguments 0 and 1 specially in the body of fc. For any other input, we start with initial three values (that is (f0 0, f0 1, f0 2) = (1, 1, 1)) and then loop n-times performing the given recursive step until we reach 2. The recursive loop function is what #bytebuster's solution implements using Seq.unfold.
So, there is a tail-recursive version of your function, but only because we could simply keep the past three values in a tuple. In general, this might not be possible if the code that calculates which previous values you need does something more complicated.
Better even than a tail recursive approach, you can take advantage of matrix multiplication to reduce any recurrence like that to a solution that uses O(log n) operations. I leave the proof of correctness as an exercise for the reader.
module NumericLiteralG =
let inline FromZero() = LanguagePrimitives.GenericZero
let inline FromOne() = LanguagePrimitives.GenericOne
// these operators keep the inferred types from getting out of hand
let inline ( + ) (x:^a) (y:^a) : ^a = x + y
let inline ( * ) (x:^a) (y:^a) : ^a = x * y
let inline dot (a,b,c) (d,e,f) = a*d+b*e+c*f
let trans ((a,b,c),(d,e,f),(g,h,i)) = (a,d,g),(b,e,h),(c,f,i)
let map f (x,y,z) = f x, f y, f z
type 'a triple = 'a * 'a * 'a
// 3x3 matrix type
type 'a Mat3 = Mat3 of 'a triple triple with
static member inline ( * )(Mat3 M, Mat3 N) =
let N' = trans N
map (fun x -> map (dot x) N') M
|> Mat3
static member inline get_One() = Mat3((1G,0G,0G),(0G,1G,0G),(0G,0G,1G))
static member (/)(Mat3 M, Mat3 N) = failwith "Needed for pown, but not supported"
let inline f n =
// use pown to get O(log n) time
let (Mat3((a,b,c),(_,_,_),(_,_,_))) = pown (Mat3 ((0G,1G,0G),(0G,0G,1G),(1G,1G,0G))) n
a + b + c
// this will take a while...
let bigResult : bigint = f 1000000

Resources