There is no way to do the same with the C for?
I mean put two or more variables as init, and increment
for (i, j, k; i!=100; i++, j*3, k++)
the lua for seems can't do this but maybe I'm wrong and there is a way to do that
for i=0, i~=1000, -1
I guess it's strange lua can't do that since lua has a lot of things to work better and simplify the code
Lua's for syntax is more restrictive than C's. If you want to do something complicated like that in your loops, you have to spell it out with a while loop or use a for loop with other increments done in the loop body.
You could also try to express this complicated sequence with an iterator. But for readability, it's best to avoid complex looping statements of this sort whenever possible.
Related
I want to realize this function:
Do[
expr(1),
expr(2)...
expr(n),
{i,1,j}]
to execute expr(k), the result of expr(k-1) is required, so the function can not realized by simply multiple layer of do loop. How can I execute the function by do loop? Or by other loop in mathematica?(I also notice that both for and while loop can only support one expr just as do loop)
Try separating by semicolon rather than comma. Like:
y = 0
Do[y += x; Print[y], {x, 1, 5}]
Do loops, and many of the other control-flow constructs from imperative programming languages, are almost always not the right answer to Mathematica programming questions.
You don't tell us what expr is supposed to calculate so it's difficult to provide more than a very general answer ... so I'll use the factorial as a simple example of how one might program a function where expr[n] depends on expr[n-1]
fact[0] = 1
fact[n_] := n*fact[n-1]
Here, I've defined the factorial function in two rules; the first establishes the base case, and the second establishes the case for values other than 0. To avoid situations where the function is fed bad data we'd probably prefer a formulation such as
fact[0] = 1
fact[n_Integer /; n > 0] := n*fact[n-1]
In this version the function fact will only operate on positive integers or on 0.
(Note: to those knowledgeable about Mathematica: Yes I know that this is not a good way to program the factorial function, and that there is a built-in function for calculating factorials. But this is supposed to help someone who appears to be a complete novice.)
We know that while and for are the most frequently used loop syntax for many programming and scripting languages. Here I would like to ask some questions regarding convertibility and feasibility of using while vs for loop.
Is for to while and vice versa transformation or conversion always possible? I mean suppose one used while loop for some functionality and I want to replace while with for or say vice-versa, then Is while ⇋ for transformation/conversion always possible (also interested in knowing the feasibility)? It would be helpful of I can refer If any research regarding this carried out.
I'm also interested in getting the general guidance for using while vs for. Also want to know if while has some advantages over for and vice versa.
Note: I've this question for log time, I thought -- being a great programming site, this question can be useful here. If the question is not suitable here. I'm unsure if this question is acceptable here, so requesting to consider it liberal; you can ask me to remove if such question hurts the quality of site :)
I will answer using Java as a reference, though this answer should also be completely valid for C, C#, C++ and many others. If we consider the following for loop:
for (int i=0; i < 10; ++i) {
// do something, maybe involving i
}
We can see that the loop has 3 components:
int i=0; initialization of loop counter
i < 10 criteria for loop to execute
++i increment to loop counter
The following while loop is functionally equivalent to the above for loop:
int i=0;
while (i < 10) {
// do something, maybe involving i
++i;
}
We can see that the main difference between this while loop and the for loop are that the declaration and initialization of the loop counter is outside the loop in the former case. Also, we increment the loop counter inside the actual while loop. The check for the loop continuing is still done inside the loop structure, as with for loops.
So a for loop can be thought of an enhanced while loop of sorts. It frees us from having to create a loop counter outside the loop, and also we can increment/change the loop counter within the loop structure, rather than mixing such logic with the code of the loop body.
So my question is simply, can something like this work:
int size = 100;
for(int i : size)
// bla
And if not, could you briefly explain why?
No, that does not work. A number is not a range. How would you define begin(100) or end(100) (which is what the range-based for loop calls internally)?
My guess is you'd want this as a shorthand for a loop from 0 to 99. But why not one from -2147483648 (or whatever std::numeric_limits<int>::min() is on your implementation) to 99?
No. Range-based for-loop are introduced for iterating through a collection, not some arbitrary range. Running a loop for a range of values can be achieved by using for, while or do-while.
If you need such loop, for regular activities, that can be implemented by simply wring a function, a macro, that may take a function, functor, or lambda.
No this will not work!
Range-based loop works only on collections, which int is not.
Moreover, if you are comparing it with a normalfor loop, where is the initialization (i=0) statement and comparison (i<size) statement for i? The construct does not tell when to start the loop and when to end!
I have two lists:
ActiveExchange = []
ActiveStock = []
My code is very sequential in nature and I'm trying to optimize it:
for exchange in ActiveExchange:
for stock in Activestock:
...
...
...
However, it seems to be highly inefficient due to the for-loop. What can i do to make it run more efficiently?
Does it just seem unefficient or did you run it and it took too long? If you just think its unefficient - test it. And don't uptimize a not existing problem. You can use your time more efficiently.
Anything else will be case-dependent. Like:
if you are searching for one or tow items in ActiveStack for every elemant in ActiveExchange,make the ActiveStack a hash.
If you have if statements, and the statement depends on one variable only, make it the outter one. that way you opyimize brach prediction. This may be done automaticlly by the compiler.
If you want to manipulate/read all pairs - you cannot optimize it.
C/C++ and Python are have row-major arrays. If you are stepping through an array, list, vector, etc, be sure to do this:
for i in range(25):
for j in range(25):
A[j][i] *= 1
rather than:
for i in range(25):
for j in range(25):
A[i][j] *= 1
That can make a difference of 3-6 times in performance.
what is considered best-practice in this case?
for (i=0; i<array.length(); ++i)
or
for (i=array.length()-1; i>=0; --i)
assuming i don't want to iterate from a certain direction, but rather over the bare length of the array. also, i don't plan to alter the array's size in the loop body.
so, will the array.length() become constant during compilation? if not, then the second approach should be the one to go for..
I would do the first method, as that is much more readable, and I can look and see you are iterating over the loop. The second one took me a second :(.
array.length will remain constant so long as you arent modifying the array.
In most cases I would expect array.length() to be implemented in such a way that it is O(1), so it would not really impact on the loop's performance. If you are in doubt, or want to make sure it is a constant, just do so explicitly:
// JavaScript
var l = a.length;
for (var i=0; i<l; i++) {
// do something
}
I consider the reversed notation a "clever hack" that falls into the premature optimization category. It's harder to read, more error-prone and does not really provide a benefit over the alternative I suggest.
But since implementations of compilers/interpreters are vastly different and you do not say what language you refer to, it is hard to make an absolute statement about this. I would say unless this is in an absolutely time-critical section of code or otherwise measurably contributing to code running time, and your benchmark tests show that doing it differently provides a real benefit, I would stick to the code that's easier to understand and maintain.
Version 2 is broken and would iterate from one past end of array to 1. (Now corrected)
Stick with version 1. It's well recognised and doesn't leave the reader doing a double-take.
Version 1 is far more widely used and simpler to understand. Version 2 may occasionally be very slightly faster if the compiler doesn't optimize array.length() into a constant, but...insert your own premature optimization comment here
EDIT: as to whether array.length() will be optimized out, it will depend on the language. If the language uses arrays as "normal" objects or arrays can be dynamically sized, it will be just a method call and the compiler can't assume will return a consistent return value. But for languages in which arrays are a special case or object (or the compiler's just really smart...) the speed difference will probably be eliminated.
for (i=0; i<array.length(); ++i) is better for me, but for (i=array.length()-1; i>=0; --i) is fastest, because common processors fastest checking condition comparing to 0 to condition comparing to two varbiales.
array.lenght() is constant if you dont adding/erasing elements from this array under iterations.
Version 1 is quickest. for (i=0; i
For a for loop in my own code, though it's probably overkill, I got into the habit early on of writing my loops such that the length gets calculated exactly once, but the loop proceeds in the natural way:
int len = array.length();
for (int i=0; i<len; ++i) {
doSomething(array[i]);
}
These days, though, I prefer using "for-each" facilities where they're available and convenient; they make loops easier to read and foolproof. In C++ that would be something like:
std::for_each(array.begin(), array.end(), &doSomething);