I'd like to write a for loop with a variable upper limit in Mathematica 9. So, instead of
j = 0;
For[n = 1, n <= 3, n++, j = j + n];
j
(*6*)
I'd like to do
N = 3;
j = 0;
For[n = 1, n <= N, n++, j = j + n];
j
n
(*
0
1
*)
. But, as shown, this does not give the right result at all; it would appear from the value of n that the body of the loop was not evaluated at all.
I've looked through the Mathematica docs both on for loops and and on loops and control structures more generally (and also done some DuckDuckGo searches), but there's still something fundamental I'm missing. What is it?
For completeness, I should note that my ultimate goal is to put this in a function:
foo[N] =
Module[{j = 0},
For[n = 1, n <= N, n++, j = j + n;];
j]
foo[3]
Your code shows several common new user's problems. For example:
N is a reserved word
You shouldn't start your identifiers with Upper Case letters
The function foo[] should be defined with SetDelayed (:=) and not
with Set (=)
You need to use patterns (_) in the function definition arguments
For[]loops, and iterations in general should be avoided in
Mathematica
I think you could carefully read all the answers to this post to get a better grip on Mathematica.
Anyway, your code may be rewritten as
foo[k_] := Module[{j = 0}, For[n = 1, n <= k, n++, j = j + n]; j]
foo[3]
(*6*)
But this is horrible Mathematica coding.
The following are much better ways in Mathematica:
foo[j_ , k_] := Fold[Plus, j, Range#k]
foo[j_ , k_] := j + Total#Range#k
foo[j_ , k_] := j + Tr#Range#k
Related
res = 0
for i in range (1,n):
j = i
while j % 2 == 0:
j = j/2
res = res + j
I understand that upper bound is O(nlogn), however I'm wondering if it's possible to find a stronger constraint? I'm stuck with the analysis.
Some ideas that may be helpful:
Could create a function (g(n)) that annotates your function (f(n)) to include how many operations occur when running f(n)
def f(n):
res = 0
for i in range (1,n):
j = i
while j % 2 == 0:
j = j/2
res = res + j
return res
def g(n):
comparisons = 0
operations = 0
assignments = 0
assignments += 1
res = 0
assignments += 1. # i = 1
comparisons += 1. # i < n
for i in range (1,n):
assignments += 1
j = i
operations += 1
comparisons += 1
while j % 2 == 0:
operations += 1
assignments += 1
j = j/2
operations += 1
assignments += 1
res = res + j
operations += 1
comparisons += 1
operations += 1 # i + 1
assignments += 1 # assign to i
comparisons += 1 # i < n ?
return operations + comparisons + assignments
For n = 1, the code runs without hitting any loops: assigning the value of res; assigning i as 1; comparing i to n and skipping the loop as a result.
For n > 1, you get into the for loop, and the for statement is all that is changing the loop varaible, so the complexity of the rest of the code is at least O(n).
Once in the loop:
if i is odd, then you only assign j, perform the mod operation and compare to zero. That will be the case for half the values of i, so each run of the loop from 2 to n will (half the time) add a fixed number of a few operations (including the loop operations). So, that's still O(n), just with a larger constant.
if i is even, then we divide by 2 until it is odd. This is what we need to work out the impact of.
Based on my counting of the different operations, I get:
g_initial_setup = 3 (every time)
g_for_any_i = 6 (half the time, it is just this)
g_for_even_i = 6 for each time we divide by two (the other half of the time)
For a random even i between 2 and n, half the time we will only need to divide by two once, half the remaining time by two again, half the remaining time by two again, etc. So we have an infinite series as n goes to infinity of sum(1/2^i) for 1 < i < n, and multiply that by the 6 operations done for each halving of j.
I would expect from this:
g(n) = 3 + (n * 6) + (n * 6) * sum( 1 / pow(2,m) for m between 1 and n )
Given that the infinite series 1/2^n = 1, we simplify that to:
g(n) = 3 + 12n as n approaches infinity.
That implies that the algorithm is O(n). Huh. I did not expect that.
Let's try out the function g(n) from above, counting all the operations that are occurring as f(n) is computed.
g(1) = 3 operations
g(2) = 9
g(3) = 21
g(4) = 27
g(5) = 45
g(10) = 123
g(100) = 1167
g(1000) = 11943
g(10000) = 119943
g(100000) = 1199931
g(1000000) = 11999919
g(10000000) = 119999907
Okay, unless I've really made a serious error here, it's O(n).
I am use Vb to write for loop,
i=1 to 3
j=1 to 3
how to make the i+j result become 1+1,2+2, 3+3.
I know for C#, it can be for(i=0,j=0;i<10,j<10;i++,j++)
just don't know how to write in VB
Unfortunately, as of March 2022, Microsoft seems to have finally pulled their 25+ year-old VBScript language documentation from their documentation website, however third-party content-mirrors exist with the documentation for VBScript's For Next statement
As per the VBScript documentation...
TL;DR: You can't. VBScript's For Next statement only supports updating a single variable inside.
You can still declare and manually increment your own variables in the loop though, e.g.
Using a single variable:
Option Explicit
Dim i
For i = 0 To 5 Step 1
Call DoStuff
Next
Using multiple variables requires separate Dim declarations and incrementing them inside the For loop body:
Option Explicit
Dim i, j, k
Let j = 0
Let k = 0
For i = 0 To 5 Step 1
Call DoStuff
Let j = j + 1
Let k = k + 1
Next
Dim result As Integer
For i = 1 To 3
For j = i To i
result = i + j
Console.WriteLine(i.ToString + "+" + j.ToString + "=" + result.ToString)
Next
Next
Or you can also write
Dim i, j, result As Integer
i = 0
j = 0
While i < 10 And j < 10
result = i + j
Console.WriteLine(i.ToString + "+" + j.ToString + "=" + result.ToString)
i += 1
j += 1
End While
If you want to achieve the effect you said, I generally like to use two for loops, and I don't like to use while loops (personal preference).
public class complexity {
public int calc(int n) {
int a = 2 * Math.abs(n);
int b = Math.abs(n) - a;
int result = n;
for (int i = 0; i < a; i++) {
result += i;
for (int j = 0; j > b; j--) {
result -= j;
}
for (int j = a/2; j > 1 ; j/=2) {
System.out.println(j);
}
}
int tmp = result;
while (tmp > 0) {
result += tmp;
tmp--;
}
return result;
}
}
I have been given the following program in Java and need to determine the time complexity (Tw(n)).
I checked those site:
Big O, how do you calculate/approximate it?
How to find time complexity of an algorithm
But I have still problem too understand it.
Here is the given solution by the professor.From the for loop on I didn't understand anything how he came up with the different time complexity. Can anybody explain it ?
let's go over it step by step :
before the for loop every instruction is executed in a constant time
then:
for(int i = 0; i < a; i++) is executed 2n + 1 times as a = 2*n so 0=> a = 2n steps and the additional step is when i = 2n the program has to execute that step and when it finds that i = 2n it breaks out of the loop.
Now each instruction in the loop has to be executed 2n times (as we are looping from 0 to 2n - 1) which explains why result += i is done 2n times.
The next instruction is another for loop so we apply the same logic about the line
for (int j = 0; j > b; j--) : as b = -n this instruction will go from 0 down to -n plus the extra step I mentioned in the first for loop which means : 0 -> -n => n steps + 1 = n+1 steps and as this instruction is in the other loop it will be execited 2n times hence 2n * (n+1)
Instructions inside this for loop are done n times and therefore result -= j is done n times and as the loop itself is done 2n times (result -= j) will be done n*2n times
Same goes for the last for loop except here we are going from a/2 which is n as a = 2n to 1 and each time we are dividing by 2, this is a bit complicated so lets do some steps first iteration j = n then j = n/2 then j = n/4 till j is <= 1 so how many steps do we need to reach 1 ?
to reach n/2 we need 1 = log(2) step n => n/2
to reach n/4 we need 2 2 = log(4) steps n => n/2 => n/4
we remark here that to reach n/x we need log(x) steps and as 1 = n/n we need log(n) steps to reach 1
therefore each instruction in this loop is executed log(n) times and as it is in the parent loop it has to be done 2n times => 2n*log(n) times.
for the while loop : result = n + (0 + 1 + 2 + .. + 2n) + (0 + 1 + .. + 2(n^2))
we did this in the for loop and then you do the arithmetic sequence sums it gives
result = n^2 (n+1) and here you go.
I hope this is clear don't hesitate to ask otherwise !
I am willing to clarify i.e. the last while loop. Unfortunately my answer does not match the professor's. And I am not that certain to have not made a grave mistake.
result starts with n
for i from 0 upto 2|n|
result += i
2|n| times done, average i.|n| so result increased by: ~2n.n = 2n².
for j from 0 downto -|n|
result -= j
2|n| times done, result increased by: 2n.n/2 = n²
So result is n + 3n²
The outer for loop remains O(n²) as the inner println-for has only O(log n).
The last while loop would be the same as:
for tmp from n + 3n² downto 0
result += tmp
This is also O(n²) like the outer for loop, so the entire complexity is O(n²).
The result is roughly 3n².3n²/2 or. 4.n4.
I have a doubt regarding the time complexity of a code snippet and didn't quite understand the solution given.
function (n) {
for(int i =0 ; i < n ; i ++){
for(int j = 0 ; j <= n ; j += i){
printf("*");
}
In the above code, it's given that inner loop executes n/i times for each value of i . And , overall time complexity is O(nlogn).
I can't figure out why the inner loop executes n/i times. Can someone please help me.
There are two loops, one incrementing i, and one incrementing j.
Given fixed i, for each pass of the j loop, j increments by i, until j reaches n.
So the values of j in each iteration are:
j
j + i
j + 2i
...
j + (n/i - j/i)i
As you can see, this runs O(n/i) times.
In the book Programming Interviews Exposed it says that the complexity of the program below is O(N), but I don't understand how this is possible. Can someone explain why this is?
int var = 2;
for (int i = 0; i < N; i++) {
for (int j = i+1; j < N; j *= 2) {
var += var;
}
}
You need a bit of math to see that. The inner loop iterates Θ(1 + log [N/(i+1)]) times (the 1 + is necessary since for i >= N/2, [N/(i+1)] = 1 and the logarithm is 0, yet the loop iterates once). j takes the values (i+1)*2^k until it is at least as large as N, and
(i+1)*2^k >= N <=> 2^k >= N/(i+1) <=> k >= log_2 (N/(i+1))
using mathematical division. So the update j *= 2 is called ceiling(log_2 (N/(i+1))) times and the condition is checked 1 + ceiling(log_2 (N/(i+1))) times. Thus we can write the total work
N-1 N
∑ (1 + log (N/(i+1)) = N + N*log N - ∑ log j
i=0 j=1
= N + N*log N - log N!
Now, Stirling's formula tells us
log N! = N*log N - N + O(log N)
so we find the total work done is indeed O(N).
Outer loop runs n times. Now it all depends on the inner loop.
The inner loop now is the tricky one.
Lets follow:
i=0 --> j=1 ---> log(n) iterations
...
...
i=(n/2)-1 --> j=n/2 ---> 1 iteration.
i=(n/2) --> j=(n/2)+1 --->1 iteration.
i > (n/2) ---> 1 iteration
(n/2)-1 >= i > (n/4) ---> 2 iterations
(n/4) >= i > (n/8) ---> 3 iterations
(n/8) >= i > (n/16) ---> 4 iterations
(n/16) >= i > (n/32) ---> 5 iterations
(n/2)*1 + (n/4)*2 + (n/8)*3 + (n/16)*4 + ... + [n/(2^i)]*i
N-1
n*∑ [i/(2^i)] =< 2*n
i=0
--> O(n)
#Daniel Fischer's answer is correct.
I would like to add the fact that this algorithm's exact running time is as follows:
Which means: