I have the following code and i am trying to understand what is its time complexity:
for (int i = 1 ; i <= n ; i = i*2)
for (int j = 1 ; j <= n ; j = j*2)
for (int k = 1 ; k <= j ; k++)
What I did was:
the first loop runs log n times, the second loop also runs log n times and the third loop is a geometric series
so overall I have the running time will be: n*(log(n))^2
Is this correct?
thank you!
By theory you are correct the complexity is n*(log(n))^2.
For Practical Lets iterate for n=1000:
i = 1; n= 1000; j= 1;k =1; result = 0
while i<=n:
j=1
while j<=n:
k=1
while k<=j:
result = result+1
k = k+1
j = j*2
i = i*2
print(result)
and we get result = 10230
so the actual value of result we get using the floor(logn)+1) * (2 ^ floor(logn)+1) - 1) formula. For n=1000 it is 10*(2^10-1)
For n=2^25
we get result 1744830438 which also satisfies using the formula= 26*((2^26)-1) = 1744830438.
Related
I am new in coding , the Code is shown below , currently it sets all M(i)variables as 10 when i run the code.
I want for each variable it should increase from 0 to 10 (1 2 3 4 5 .) each number change in one second and when 10 is reached then move to next variable M(i).
function M = fcn(time)
M =zeros(84,1);
for i=1:84
for j = 1:10
M(i) = j*1;
end
end
end
Hope this helps you:
int[] m = new int[84];
int j = 0;
for (int i = 0; i < 84; i++)
{
if (j % 10 == 0)
{
j = 0;
}
m[i] = j * 1;
j++;
}
Let's say I have 3 arrays image, blur and out, all of dimensions M×N×3.
I want to compute the bilateral gradient of each pixel in the array image (current_pixel - (previous_previous + next_pixel) / 2) over x and y dimensions, divide it by some floats, then add the value of the corresponding pixel from the array blur and finally put the result into the array out.
My question is, in C, what is the most efficient way to do it (regarding the memory access speed and computing efficiency) :
One loop indexing the 3 arrays at once :
for (i = 0, j = 0, k = 0 ; i < M-1, j < N-1, k < 3 ; i++, j++, k++):
out[i][j][k] = (2 * image[i][j][k] - image[i+1][j][k] - image[i][j+1][k]) / 2. + lambda * blur[i][j][k]
Two loops indexing only two arrays :
for (i = 0, j = 0, k = 0 ; i < M-1, j < N-1, k < 3 ; i++, j++, k++):
out[i][j][k] = (2 * image[i][j][k] - image[i+1][j][k] - image[i][j+1][k]) / 2.
for (i = 0, j = 0, k = 0 ; i < M-1, j < N-1, k < 3 ; i++, j++, k++):
out[i][j][k] += lambda * blur[i][j][k]
(for readability, I only wrote a simple forward gradient, but the complete formula is given above).
Or is there another faster way ? I'm programming for x86_64 CPUs.
One loop indexing the 3 arrays at once will be slightly easier for compiler to optimize. But you can quite likely check it and tested it.
This question already has answers here:
Asymptotic analysis
(2 answers)
Closed 8 years ago.
I dont get the part where T(n) of the second for loop is log(n). Both loops are connected by
i and it is confusing.How is T(n) of the code O(nlog(n)) using fundamental product rule?
for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; j = j + i)
{
printf("Hi");
}
}
For i=1 inner loop executes n times. For i=2 inner loop executes n/2 times and so on. The running time is T(n) = n + n/2 + n/3 + ... + n/n. This is equal to n(1 + 1/2 + 1/3 + ...+ 1/n) = nH(n) where H(n) is the nth harmonic number. H(n) ~ lg n hence the running time of O(n lg n).
for(i = 1; i <= n; i++) // Executes n times
{
for(j = 1; j <= n; j = j + i)
{ // This loop executes j times with j increases by rate of i
printf(“Hi”);
}
}
The inner loop executes n/i times for each value of i. Its running time is nxSum(n/i) for all i in [1,n]
=> O(nlogn)
Very similar complexity examples. I am trying to understand as to how these questions vary. Exam coming up tomorrow :( Any shortcuts for find the complexities here.
CASE 1:
void doit(int N) {
while (N) {
for (int j = 0; j < N; j += 1) {}
N = N / 2;
}
}
CASE 2:
void doit(int N) {
while (N) {
for (int j = 0; j < N; j *= 4) {}
N = N / 2;
}
}
CASE 3:
void doit(int N) {
while (N) {
for (int j = 0; j < N; j *= 2) {}
N = N / 2;
}
}
Thank you so much!
void doit(int N) {
while (N) {
for (int j = 0; j < N; j += 1) {}
N = N / 2;
}
}
To find the O() of this, notice that we are dividing N by 2 each iteration. So, (not to insult your intelligence, but for completeness) the final non-zero iteration through the loop we will have N=1. The time before that we will have N=a(2), then before that N=a(4)... where 0< a < N (note those are non-inclusive bounds). So, this loop will execute a total of log(N) times, meaning the first iteration we see that N=a2^(floor(log(N))).
Why do we care about that? Well, it's a geometric series which has a nice closed form:
Sum = \sum_{k=0}^{\log(N)} a2^k = a*\frac{1-2^{\log N +1}}{1-2} = 2aN-a = O(N).
If someone can figure out how to get that latexy notation to display correctly for me I would really appreciate it.
You already have the answer to number 1 - O(n), as given by #NickO, here is an alternative explanation.
Denote the number of outer repeats of inner loop by T(N), and let the number of outer loops be h. Note that h = log_2(N)
T(N) = N + N/2 + ... + N / (2^i) + ... + 2 + 1
< 2N (sum of geometric series)
in O(N)
Number 3: is O((logN)^2)
Denote the number of outer repeats of inner loop by T(N), and let the number of outer loops be h. Note that h = log_2(N)
T(N) = log(N) + log(N/2) + log(N/4) + ... + log(1) (because log(a*b) = log(a) + log(b)
= log(N * (N/2) * (N/4) * ... * 1)
= log(N^h * (1 * 1/2 * 1/4 * .... * 1/N))
= log(N^h) + log(1 * 1/2 * 1/4 * .... * 1/N) (because log(a*b) = log(a) + log(b))
< log(N^h) + log(1)
= log(N^h) (log(1) = 0)
= h * log(N) (log(a^b) = b*log(a))
= (log(N))^2 (because h=log_2(N))
Number 2 is almost identical to number 3.
(In 2,3: assuming j starts from 1, not from 0, if this is not the case #WhozCraig giving the reason why it never breaks)
for (i = 0; i < n; i++)
{
x[i] = (float) (i * step);
k = 5;
sum = 0;
while(k > 0)
{
sum = sum + (1/k) * sin((k*PI*x[i])/5);
k = k - 2;
}
y1[i] = (4/PI)*sum;
y2[i] = 0*(4/PI)*sin((PI*x[i])/5);
}
When debugging for each value of k other than 1 the sum shows as being equal to 0, am I implementing the loop correctly?
EDIT 1:
int k;
double sum;
Since both 1 and k are ints -- 1/k is integer division, its always going to be 0 if k > 1. Therefore nothing is added to sum. You want 1/k to perform floating point division. Try 1.0 / k instead of 1/k.
1/k will give 0. Since it is Integer Division.
You will have to give 1.0/k or 1/(float)k