Well founded induction on trees - math

I have an exam (Functional Programming in SML) coming up in a week. I have become fairly confident in the programming language SML and the functional paradigm, but I have a quite big problem with proves.
I am trying to solve the following question which was a part of the last year exam:
Consider the following declarations of a datatype for trees and of two functions:
datatype tree = Lf | Br of int * tree * tree;
fun size Lf = 0
| size(Br(i,t1,t2)) = 1 + size t1 + size t2;
fun sizeI Lf k = k
| sizeI (Br(i,t1,t2)) k = sizeI t1 (1 + sizeI t2 k);
Prove that
sizeI tr k = k + size tr
holds for all trees tr and all integers k.
I want to solve the above question by using Well Founded Induction. To start, I have solved the base case:
k = 0 & tr = Lf
sizeI Lf 0 = 0+size Lf
0 = 0
Then I have tried solving the inductive step, but got stuck:
sizeI tr k = k + size tr
sizeI Br(k,t1,t2) k = k + size Br (k,t1,t2)
size t1 (1+ sizeI t2 k) = k+1+size t1 + size t2
.... STUUUUCK
I would REALLY appreciate ANY help here. If you have any links or tips with induction in general (please don't point me at the evil "Well-founded relation" article on Wikipedia), I would be really happy. Also, if you can help me with this one question...
THANKS! :-)

To do well-found induction, first you need to define a well-found relation on trees:
Binary relation c where (t1, k1) c (t,k) if t1 is a subtree of t is a well-found relation.
Second, state your induction hypothesis:
t1 and t2 are subtrees of t, we have:
sizeI t1 k1 = k1 + size t1 (1)
sizeI t2 k2 = k2 + size t2 (2)
We must establish:
sizeI Br(i,t1,t2) k = k + size Br(i,t1,t2)
You have already done the base case.
Induction case:
Notice that:
sizeI Br(i,t1,t2) k
= sizeI t1 (1 + sizeI t2 k) // definition of sizeI
= 1 + sizeI t2 k + size t1 // induction hypothesis (1)
= 1 + k + size t2 + size t1 // induction hypothesis (2)
= k + size Br(i, t1, t2) // definition of size
We completed the proof.

Related

why 1 is subtracted from mod where mod =1000000007 in calculation

link of question
http://codeforces.com/contest/615/problem/D
link of solution is
http://codeforces.com/contest/615/submission/15260890
In below code i am not able to understand why 1 is subtracted from mod
where mod=1000000007
ll d = 1;
ll ans = 1;
for (auto x : cnt) {
ll cnt = x.se;
ll p = x.fi;
ll fp = binPow(p, (cnt + 1) * cnt / 2, MOD);
ans = binPow(ans, (cnt + 1), MOD) * binPow(fp, d, MOD) % MOD;
d = d * (x.se + 1) % (MOD - 1);//why ??
}
Apart from the fact that there is the code does not make much sense as out of context as it is, there is the little theorem of Fermat:
Whenever MOD is a prime number, as 10^9+7 is, one can reduce exponents by multiples of (MOD-1) as for any a not a multiple of MOD
a ^ (MOD-1) == 1 mod MOD.
Which means that
a^b == a ^ (b mod (MOD-1)) mod MOD.
As to the code, which is efficient for its task, consider n=m*p^e where m is composed of primes smaller than p.
Then for each factor f of m there are factors 1*f, p*f, p^2*f,...,p^e*f of n. The product over all factors of n thus is the product over
p^(0+1+2+...+e) * f^(e+1) = p^( e*(e+1)/2 ) * f^(e+1)
over all factors f of m. Putting the numbers of factors as d and the product of factors of m as ans results in the combined formula
ans = ans^( e+1 ) * p^( d*e*(e+1)/2 )
d = d*(e+1)
which can now be recursively applied to the list of prime factors and their multiplicities.

How can i find a running time of a recurrence relation?

The running time for this recurrence relation is O(nlogn). Since I am new to algorithm how would I show that mathematically?
T(n) = 2⋅T(n/2) + O(n)
T(n) = 2 ( 2⋅T(n/4) + O(n) ) + O(n) // since T(n/2) = 2⋅T(n/4) + O(n)
So far I can see that if I suppose n to be a power of 2 like n = 2m, then may be I can show that, but I am not getting the clear picture. Can anyone help me?
If you use the master theorem, you get the result you expected.
If you want to proof this "by hand", you can see this easily by supposing n = 2m is a power of 2 (as you already said). This leads you to
T(n) = 2⋅T(n/2) + O(n)
= 2⋅(2⋅T(n/4) + O(n/2)) + O(n)
= 4⋅T(n/4) + 2⋅O(n/2) + O(n)
= 4⋅(2⋅T(n/8) + O(n/4)) + 2⋅O(n/2) + O(n)
= Σk=1,...,m 2k⋅O(n/2k)
= Σk=1,...,m O(n)
= m⋅O(n)
Since m = log₂(n), you can write this as O(n log n).
At the end it doesn't matter if n is a power of 2 or not.
To see this, you can think about this: You have an input of n (which is not a power of 2) and you add more elements to the input until it contains n' = 2m Elements with m ∈ ℕ and log(n) ≤ m ≤ log(n) + 1, i.e. n' is the smalest power of 2 that is greater than n. Obviously T(n) ≤ T(n') holds and we know T(n') is in
O(n'⋅log(n')) = O(c⋅n⋅log(c⋅n)) = O(n⋅log(n) + n⋅log(c)) = O(n⋅log(n))
where c is a constant between 1 and 2.
You can do the same with the greatest power of 2 that is smaller than n. This gives leads you to T(n) ≥ T(n'') and we know T(n'') is in
O(n''⋅log(n'')) = O(c⋅n⋅log(c⋅n)) = O(n⋅log(n))
where c is a constant between 1/2 and 1.
In total you get, that the complexity of T(n) is bounded by the complexitys of T(n'') and T(n') wich are both O(n⋅log(n))and so T(n) is also in O(n⋅log(n)), even if it is not a power of 2.

Unclassified statement at (1) in a mathematical expression

My first Fortran lesson is to plot the probability density function of the radial Sturmian functions. In case you are interested, the radial Sturmian functions are used to graph the momentum space eigenfunctions for the hydrogen atom.
In order to produce these radial functions, one needs to first produce some polynomials called the Gegenbauer polynomials, denoted
Cba(x),
where a and b should be stacked atop each other. One needs these polynomials because the Sturmians (let's call them R_n,l) are defined like so,
R_n,l(p) = N pl⁄(p2 + k2)l+2 Cn - l - 1l + 1(p2 - k2⁄p2 + k2),
where N is a normalisation constant, p is the momentum, n is the principle quantum number, l is the angular momentum and k is a constant. The normalisation constant is there so that when I come to square this function, it will produce a probability distribution for the momentum of the electron in a hydrogen atom.
Gegenbauer polynomials are generated using the following recurrence relation:
Cnl(x) = 1⁄n[2(l + n - 1) x Cn - 1l(x) - (2l + n - 2)Cn - 2l(x)],
with C0l(x) = 1 and C1l(x) = 2lx, as you may have noticed, l is fixed but n is not. At the start of my program, I will specify both l and n and work out the Gegenbauer polynomial I need for the radial function I wish to plot.
The problems I am having with my code at the moment are all in my subroutine for working out the value of the Gegenbauer polynomial Cn-l-1l+1(p2 - k2⁄p2 + k2) for incremental values of p between 0 and 3. I keep getting the error
Unclassified statement at (1)
but I cannot see what the issue is.
program Radial_Plot
implicit none
real, parameter :: pi = 4*atan(1.0)
integer, parameter :: top = 1000, l = 50, n = 100
real, dimension(1:top) :: x, y
real increment
real :: a=0.0, b = 2.5, k = 0.3
integer :: i
real, dimension(1:top) :: C
increment = (b-a)/(real(top)-1)
x(1) = 0.0
do i = 2, top
x(i) = x(i-1) + increment
end do
Call Gegenbauer(top, n, l, k, C)
y = x*C
! y is the function that I shall be plotting between values a and b.
end program Radial_Plot
Subroutine Gegenbauer(top1, n1, l1, k1, CSub)
! This subroutine is my attempt to calculate the Gegenbauer polynomials evaluated at a certain number of values between c and d.
implicit none
integer :: top1, i, j, n1, l1
real :: k1, increment1, c, d
real, dimension(1:top1) :: x1
real, dimension(1:n1 - l1, 1:top1) :: C1
real, dimension(1:n1 - l1) :: CSub
c = 0.0
d = 3.0
k1 = 0.3
n1 = 50
l1 = 25
top1 = 1000
increment1 = (d - c)/(real(top1) - 1)
x1(1) = 0.0
do i = 2, top1
x1(i) = x1(i-1) + increment1
end do
do j = 1, top1
C1(1,j) = 1
C1(2,j) = 2(l1 + 1)(x1(i)^2 - k1^2)/(x1(i)^2 + k1^2)
! All the errors occurring here are all due to, and I quote, 'Unclassifiable statement at (1)', I can't see what the heck I have done wrong.
do i = 3, n1 - l1
C1(i,j) = 2(((l1 + 1)/n1) + 1)(x1(i)^2 - k1^2)/(x1(i)^2 + k1^2)C1(i,j-1) - ((2(l1+1)/n1) + 1)C1(i,j-2)
end do
CSub(j) = Cn(n1 - l1,j)^2
end do
return
end Subroutine Gegenbauer
As francesalus correctly pointed out, the problem is because you use ^ instead of ** for exponentiation. Additionally, you do not put * between the terms you are multiplying.
C1(1,j) = 1
C1(2,j) = 2*(l1 + 1)*(x1(i)**2 - k1**2)/(x1(i)**2 + k1**2)
do i = 3, n1 - l1
C1(i,j) = 2 * (((l1 + 1)/n1) + 1) * (x1(i)**2 - k1**2) / &
(x1(i)**2 + k1**2)*C1(i,j-1) - ((2(l1+1)/n1) + 1) * &
C1(i,j-2)
end do
CSub(j) = Cn(n1 - l1,j)**2
Since you are beginning I have some advice. Learn to put all subroutines and functions to modules (unless they are internal). There is no reason for the return statement at the and of the subroutine, similarly as a stop statement isn't necessary at the and of the program.

Using the masters method

On my midterm I had the problem:
T(n) = 8T(n/2) + n^3
and I am supposed to find its big theta notation using either the masters or alternative method. So what I did was
a = 8, b = 2 k = 3
log28 = 3 = k
therefore, T(n) is big theta n3. I got 1/3 points so I must be wrong. What did I do wrong?
T(n) = aT(n/b) + f(n)
You applied the version when f(n) = O(n^(log_b(a) - e)) for some e > 0.
This is important, you need this to be true for some e > 0.
For f(n) = n^3, b = 2 and a = 8,
n^3 = O(n^(3-e)) is not true for any e > 0.
So your picked the wrong version of the Master theorem.
You need to apply a different version of Master theorem:
if f(n) = Theta ((log n)^k * n^log_b(a)) for some k >= 0,
then
T(n) = Theta((log n)^(k+1) * n^log_b(a))
In your problem, you can apply this case, and that gives T(n) = Theta(n^3 log n).
An alternative way to solve your problem would be:
T(n) = 8 T(n/2) + n^3.
Let g(n) = T(n)/n^3.
Then
n^3 *g(n) = 8 * (n/2)^3 * g(n/2)+ n^3
i.e g(n) = g(n/2) + 1.
This implies g(n) = Theta(logn) and so T(n) = Theta(n^3 logn).

Can someone explain Mathematical Induction (to prove a recursive method)

Can someone explain mathematical induction to prove a recursive method? I am a freshmen computer science student and I have not yet taken Calculus (I have had up through Trig). I kind of understand it but I have trouble when asked to write out an induction proof for a recursive method.
Here is a explanation by example:
Let's say you have the following formula that you want to prove:
sum(i | i <- [1, n]) = n * (n + 1) / 2
This formula provides a closed form for the sum of all integers between 1 and n.
We will start by proving the formula for the simple base case of n = 1. In this case, both sides of the formula reduce to 1. This in turn means that the formula holds for n = 1.
Next, we will prove that if the formula holds for a value n, then it holds for the next value of n (or n + 1). In other words, if the following is true:
sum(i | i <- [1, n]) = n * (n + 1) / 2
Then the following is also true:
sum(i | i <- [1, n + 1]) = (n + 1) * (n + 2) / 2
To do so, let's start with the first side of the last formula:
s1 = sum(i | i <- [1, n + 1]) = sum(i | i <- [1, n]) + (n + 1)
That is, the sum of all integers between 1 and n + 1 is equal to the sum of integers between 1 and n, plus the last term n + 1.
Since we are basing this proof on the condition that the formula holds for n, we can write:
s1 = n * (n + 1) / 2 + (n + 1) = (n + 1) * (n + 2) / 2 = s2
As you can see, we have arrived at the second side of the formula we are trying to prove, which means that the formula does indeed hold.
This finishes the inductive proof, but what does it actually mean?
The formula is correct for n = 0.
If the formula is correct for n, then it is correct for n + 1.
From 1 and 2, we can say: if the formula is correct for n = 0, then it is correct for 0 + 1 = 1. Since we proved the case of n = 0, then the case of n = 1 is indeed correct.
We can repeat this above process again. The case of n = 1 is correct, then the case of n = 2 is correct. This reasoning can go ad infinitum; the formula is correct for all integer values of n >= 1.
induction != Calc!!!
I can get N guys drunk with 10*N beers.
Base Case: 1 guy
I can get one guy drunk with 10 beers
Inductive step, given p(n) prove p(n + 1)
I can get i guys drunk with 10 * i beers, if I add another guy, I can get him drunk with 10 more beers. Therefore, I can get i + 1 guys drunk with 10 * (i + 1) beers.
p(1) -> p(i + 1) -> p(i + 2) ... p(inf)
Discrete Math is easy!
First, you need a base case. Then you need an inductive step that holds true for some step n. In your inductive step, you will need an inductive hypothesis. That hypothesis is the assumption that you needed to have made. Finally, use that assumption to prove step n+1

Resources