converting c for loop to fortran do loop - c++

I am converting a cpp prog (from another author) to a Fortran prog, my C is not too strong. I came across for-loop constructs starting with
for (int n = 1; 1; ++n) {
...
I would have expected this to convert to a Fortran Do as per
Do n=1, 1, 2
...
... at least that is my guess based on my understanding of what ++n will do.
Is my translation correct? If so, the loop will cycle at most once, so what am I missing ???
I understand that in some ways c for-loops have a "do-while" aspect, and hence wrinkles porting to Fortran Do's.
Anyway ... a clarification would be much appreciated.
EDITED: after some prompt responses, and I think I see where this is going
First, the exact C code copy/paste but "trimming" a little, is
for (int n = 1; 1; ++n) {
const double coef = exp(-a2*(n*n)) * expx2 / (a2*(n*n) + y*y);
prod2ax *= exp2ax;
prodm2ax *= expm2ax;
sum1 += coef;
sum2 += coef * prodm2ax;
sum4 += (coef * prodm2ax) * (a*n);
sum3 += coef * prod2ax;
sum5 += (coef * prod2ax) * (a*n);
// test convergence via sum5, since this sum has the slowest decay
if ((coef * prod2ax) * (a*n) < relerr * sum5) break;
}
So yes, there is a "break" in the loop, which on the Fortran side is replaced with an "Exit".
I think the key seems to be from the answers below that the original code's author created the
for (int n=1; 1 ; ++n )
precisely to create a an infinite loop, and I had not guessed that this for construct would create an infinite loop.
Anyway, I can certainly create an infinite loop with an "Exit" in Fortran (though I expect I might "do" it a bit more judiciously)
Many thanks to all.
It seems the Mr Gregory's response was the one that imediately lead to a solution for me, so I will mark his correct. As for the Fortran side, there are a number of alternatives such as:
Do While
:
If( something ) Exit
End Do
but being old fashioned I would probably use a construct with a "limit" such as
Do i=1, MaxIter
:
If( something ) Exit
End Do
For slightly fancier applications I might include a return flag in case it did not converge in MaxIter's etc.

It's difficult to be definitive without seeing how the C++ program breaks out of that loop, but a straightforward Fortran equivalent would be
n = 1
do
! code, including an exit under some condition, presumably on the value of n
n = n+1
end do
If the loop is terminated when n reaches a critical value then the equivalent might be
do n = 1, critical_value ! no need to indicate step size if it is 1
! code
end do

Are you sure you wrote the C code correctly? Typically loops in C/C++ are done like this:
for (int n = 1; n < 10; ++n) {
// ...
}
Note the "n < 10" test condition. Your code's test condition is simply 1, which will always evaluate to Boolean "true". This means the code will loop infinitely, unless there's a break inside the loop, which you haven't shown.
++n means "increment n".
So if the code you've shown is indeed correct, the FORTRAN equivalent would be:
n = 1
do
[Body of the loop, which you haven't shown]
n = n + 1
enddo

Here's what
for (int n = 1; 1; ++n)
does:
It sets n to 1, then loops infinitely, incrementing n by 1 at the end of each loop iteration. The loop will never terminate unless something inside the loop breaks out.
It's been a long time since I wrote Fortran but as I recall the do loop you translated it to is not correct.

I don't think you can translate
for (int n = 1; 1; ++n)
to a FORTRAN DO loop. From what I recall, the notion of the generic conditional in C/C++ cannot be emulated in a FORTRAN DO loop.
The equivalent of
Do n=1, 1, 2
in C/C++ is
for ( int n = 1; n <= 1; n += 2 )

A few notes in addition to CareyGregory’s answer.
++n means ‘increment n by one (before n is evaluated)’
In C and C++, a for loop has three clauses, much like in FORTRAN:
for (init; condition; increment)
The difference is that each of the clauses must be a complete expression, whereas in FORTRAN the clauses are just values. It is just a ‘short’ way of writing an equivalent while loop:
int n = 1; │ for (int n = 1; 1; ++n) │ n = 1
while (1) │ { │ do
{ │ ... │ ...
... │ } │ n = n + 1
++n; │ │ enddo
} │ │

Related

ZIMPL: 2D variable declaration not recognized in constraint

I'm having a real challenge declaring a 2D variable in Zimpl. (Parameters seem to work fine.)
The following is my MWE:
set I := {1 to 10};
set J := {1 to 5};
param A[I*J] := read InputFile as "n+";
var x[I] binary;
var s[J] binary; # this works but doesn't do what I need
var s2[I*J] binary; # this does what I need but doesn't work
minimize sum<i,j> in I*J with A[i,j] < 5: (s2[i,j] - x[i]) * A[i,j];
# this constraint compiles
subto constraint1:
forall <j> in J do sum <i> in I with A[i,j] < 5: x[i] <= 1 + s[j];
# this constraint does not compile
subto constraint2:
forall <j> in J do sum <i> in I with A[i,j] < 5: x[i] <= 1 + s2[i,j];
When try to create my lp file, I get
Error 133: Unknown symbol "i"
Does anyone have any insights into how I can get the second constraint to work? As far as I can tell this is identical to the implementation of the capacitated facility problem (Section 6.3) in the Zimpl user's manual.
Thanks in advance.
You have the sum over i on the left-hand side of the constraint, but then reference i on the right-hand side as well. Which value of i do you expect there?
What would work is
forall <j> in J do sum <i> in I with A[i,j] < 5: (x[i] - s2[i,j]) <= 1;
but I am not sure this is what you want to achieve.
Adding Leon's comment to make a more complete answer:
To add to what Gerald wrote, in ZIMPL sums always only consider the next variable, so you have to put parenthesis to make it work.
To add to what Gerald wrote, in ZIMPL sums always only consider the next variable, so you have to put parenthesis to make it work.
at minimize there is the name missing.
It should be minimize obj: sum ...

One simple 'if' statement in Julia increases the run-time of my prime sieve by a factor of 15 – why?

I've been experimenting with various prime sieves in Julia with a view to finding the fastest. This is my simplest, if not my fastest, and it runs in around 5-6 ms on my 1.80 GHz processor for n = 1 million. However, when I add a simple 'if' statement to take care of the cases where n <= 1 or s (the start number) > n, the run-time increases by a factor of 15 to around 80-90 ms.
using BenchmarkTools
function get_primes_1(n::Int64, s::Int64=2)::Vector{Int64}
#=if n <= 1 || s > n
return []
end=#
sieve = fill(true, n)
for i = 3:2:isqrt(n) + 1
if sieve[i]
for j = i ^ 2:i:n
sieve[j]= false
end
end
end
pl = [i for i in s - s % 2 + 1:2:n if sieve[i]]
return s == 2 ? unshift!(pl, 2) : pl
end
#btime get_primes_1(1_000_000)
Output with the 'if' statement commented out, as above, is:
5.752 ms (25 allocations: 2.95 MiB)
Output with the 'if' statement included is:
86.496 ms (2121646 allocations: 35.55 MiB)
I'm probably embarrassingly ignorant or being terminally stupid, but if someone could point out what I'm doing wrong it would be very much appreciated.
The problem of this function is with Julia compiler having problems with type inference when closures appear in your function. In this case the closure is a comprehension and the problem is that if statement makes sieve to be only conditionally defined.
You can see this by moving sieve up:
function get_primes_1(n::Int64, s::Int64=2)::Vector{Int64}
sieve = fill(true, n)
if n <= 1 || s > n
return Int[]
end
for i = 3:2:isqrt(n) + 1
if sieve[i]
for j = i ^ 2:i:n
sieve[j]= false
end
end
end
pl = [i for i in s - s % 2 + 1:2:n if sieve[i]]
return s == 2 ? unshift!(pl, 2) : pl
end
However, this makes sieve to be created also when n<1 which you want to avoid I guess :).
You can solve this problem by wrapping sieve in let block like this:
function get_primes_1(n::Int64, s::Int64=2)::Vector{Int64}
if n <= 1 || s > n
return Int[]
end
sieve = fill(true, n)
for i = 3:2:isqrt(n) + 1
if sieve[i]
for j = i ^ 2:i:n
sieve[j]= false
end
end
end
let sieve = sieve
pl = [i for i in s - s % 2 + 1:2:n if sieve[i]]
return s == 2 ? unshift!(pl, 2) : pl
end
end
or avoiding an inner closure for example like this:
function get_primes_1(n::Int64, s::Int64=2)::Vector{Int64}
if n <= 1 || s > n
return Int[]
end
sieve = fill(true, n)
for i = 3:2:isqrt(n) + 1
if sieve[i]
for j = i ^ 2:i:n
sieve[j]= false
end
end
end
pl = Int[]
for i in s - s %2 +1:2:n
sieve[i] && push!(pl, i)
end
s == 2 ? unshift!(pl, 2) : pl
end
Now you might ask how can you detect such problems and make sure that some solution solves them? The answer is to use #code_warntype on a function. In your original function you will notice that sieve is Core.Box which is an indication of the problem.
See https://github.com/JuliaLang/julia/issues/15276 for details. In general this is in my perception the most important issue with performance of Julia code which is easy to miss. Hopefully in the future the compiler will be smarter with this.
Edit: My suggestion actually doesn't seem to help. I missed your output annotation, so the return type appears to be correctly inferred after all. I am stumped, for the moment.
Original answer:
The problem isn't that there is an if statement, but that you introduce a type instability inside that if statement. You can read about type instabilities in the performance section of the Julia manual here.
An empty array defined like this: [], has a different type than a vector of integers:
> typeof([1,2,3])
Array{Int64,1}
> typeof([])
Array{Any,1}
The compiler cannot predict what the output type of the function will be, and therefore produces defensive, slow code.
Try to change
return []
to
return Int[]

OpenMP reduction into array of C++ template-specified size causes undefined behaviour

I'm new to OpenMP, but am trying to use it to accelerate some operations on entries of a 2D array with a large number of rows and a small number of columns. At the same time, I am using a reduction to calculate the sum of all the array values in each column. The code looks something like this (I will explain the weird bits in a moment):
template <unsigned int NColumns>
void Function(int n_rows, double** X, double* Y)
{
#pragma omp parallel for reduction(+:Y[:NColumns])
for (int r = 0; r < n_rows; ++r)
{
for (int c = 0; c < NColumns; ++c)
{
X[r][c] = some_complicated_stuff(X[r], X[r][c]);
Y[c] += X[r][c];
}
}
}
To clarify, X is a n_rows x NColumns-sized 2D array allocated on the heap, and Y is a NColumns-sized 1D array. some_complicated_stuff isn't actually implemented as a separate function, but what I do to X[r][c] in that line only depends on X[r][c] and other values in the 1D array X[r].
The reason that NColumns is passed in as a template parameter rather than as a regular argument (like n_rows) is that when NColumns is known at compile-time, the compiler can more aggressively optimise the inner loop in the above function. I know that NColumns is going to be one of a small number of values when the program runs, so later on I have something like this code:
cin >> n_cols;
double** X;
double Y[n_cols];
// initialise X and Y, etc. . .
for (int i = 0; i < n_iterations; ++i)
{
switch (n_cols)
{
case 2: Function< 2>(X, Y); break;
case 10: Function<10>(X, Y); break;
case 60: Function<60>(X, Y); break;
default: throw "Unsupported n_cols."; break;
}
// . . .
Report(i, Y); // see GDB output below
}
Through testing, I have found that having this NColumns "argument" to Update as a template parameter rather than a normal function parameter actually makes for an appreciable performance increase. However, I have also found that, once in a blue moon (say, about every 10^7 calls to Function), the program hangs—and even worse, that its behaviour sometimes changes from one run of the program to the next. This happens rarely enough that I have been having a lot of trouble isolating the bug, but I'm now wondering whether it's because I am using this NColumns template parameter in my OpenMP reduction.
I note that a similar StackOverflow question asks about using template types in reductions, which apparently causes unspecified behaviour - the OpenMP 3.0 spec says
If a variable referenced in a data-sharing attribute clause has a type
derived from a template, and there are no other references to that
variable in the program, then any behavior related to that variable is
unspecified.
In this case, it's not a template type per se that is being used, but I'm sort of in the same ballpark. Have I messed up here, or is the bug more likely to be in some other part of the code?
I am using GCC 6.3.0.
If it is more helpful, here's the real code from inside Function. X is actually a flattened 2D array; ww and min_x are defined elsewhere:
#pragma omp parallel for reduction(+:Y[:NColumns])
for (int i = 0; i < NColumns * n_rows; i += NColumns)
{
double total = 0;
for (int c = 0; c < NColumns; ++c)
if (X[i + c] > 0)
total += X[i + c] *= ww[c];
if (total > 0)
for (int c = 0; c < NColumns; ++c)
if (X[i + c] > 0)
Y[c] += X[i + c] = (X[i + c] < min_x * total ? 0 : X[i + c] / total);
}
Just to thicken the plot a bit, I attached gdb to a running process of the program which hanged, and here's what the backtrace shows me:
#0 0x00007fff8f62a136 in __psynch_cvwait () from /usr/lib/system/libsystem_kernel.dylib
#1 0x00007fff8e65b560 in _pthread_cond_wait () from /usr/lib/system/libsystem_pthread.dylib
#2 0x000000010a4caafb in omp_get_num_procs () from /opt/local/lib/libgcc/libgomp.1.dylib
#3 0x000000010a4cad05 in omp_get_num_procs () from /opt/local/lib/libgcc/libgomp.1.dylib
#4 0x000000010a4ca2a7 in omp_in_final () from /opt/local/lib/libgcc/libgomp.1.dylib
#5 0x000000010a31b4e9 in Report(int, double*) ()
#6 0x3030303030323100 in ?? ()
[snipped traces 7-129, which are all ?? ()]
#130 0x0000000000000000 in ?? ()
Report() is a function that gets called inside the program's main loop but not within Function() (I've added it to the middle code snippet above), and Report() does not contain any OpenMP pragmas. Does this illuminate what's happening at all?
Note that the executable changed between when the process started running and when I attached GDB to it, which required referring to the new (changed) executable. So that could mean that the symbol table is messed up.
I have managed to partly work this out.
One of the problems was with the program behaving nondeterministically. This is just because (1) OpenMP performs reductions in thread-completion order, which is non-deterministic, and (2) floating-point addition is non-associative. I assumed that the reductions would be performed in thread-number order, but this is not the case. So any OpenMP for construct that reduces using floating-point operations will be potentially non-deterministic even if the number of threads is the same from one run to the next, so long as the number of threads is greater than 2. Some relevant StackOverflow questions on this matter are here and here.
The other problem was that the program occasionally hangs. I have not been able to resolve this issue. Running gdb on the hung process always yields __psynch_cvwait () at the top of the stack trace. It hangs around every 10^8 executions of the parallelised for loop.
Hope this helps a little.

Multiply numbers which are divisible by 3 and less than 10 with a while loop in c++?

In C++, I should write a program where the app detects which numbers are divisible by 3 from 1 till 10 and then multiply all of them and print the result. That means that I should multiply 3,6,9 and print only the result, which is 162, but I should do it by using a "While" loop, not just multiplying the 3 numbers with each other. How should I write the code of this? I attached my attempt to code the problem below. Thanks
#include <iostream>
using namespace std;
int main() {
int x, r;
int l;
x = 1;
r = 0;
while (x < 10 && x%3==0) {
r = (3 * x) + 3;
cout << r;
}
cin >> l;
}
Firstly your checking the condition x%3 == 0 brings you out of your while - loop right in the first iteration where x is 1. You need to check the condition inside the loop.
Since you wish to store your answer in variable r you must initialize it to 1 since the product of anything with 0 would give you 0.
Another important thing is you need to increment the value of x at each iteration i.e. to check if each number in the range of 1 to 10 is divisible by 3 or not .
int main()
{
int x, r;
int l;
x = 1;
r = 1;
while (x < 10)
{
if(x%3 == 0)
r = r*x ;
x = x + 1; //incrementing the value of x
}
cout<<r;
}
Lastly I have no idea why you have written the last cin>>l statement . Omit it if not required.
Ok so here are a few hints that hopefully help you solving this:
Your approach with two variables (x and r) outside the loop is a good starting point for this.
Like I wrote in the comments you should use *= instead of your formula (I still don't understand how it is related to the problem)
Don't check if x is dividable by 3 inside the while-check because it would lead to an too early breaking of the loop
You can delete your l variable because it has no affect at the moment ;)
Your output should also happen outside the loop, else it is done everytime the loop runs (in your case this would be 10 times)
I hope I can help ;)
EDIT: Forget about No.4. I didn't saw your comment about the non-closing console.
int main()
{
int result = 1; // "result" is better than "r"
for (int x=1; x < 10; ++x)
{
if (x%3 == 0)
result = result * x;
}
cout << result;
}
or the loop in short with some additional knowledge:
for (int x=3; x < 10; x += 3) // i know that 3 is dividable
result *= x;
or, as it is c++, and for learning purposes, you could do:
vector<int> values; // a container holding integers that will get the multiples of 3
for (int x=1; x < 10; ++x) // as usual
if ( ! x%3 ) // same as x%3 == 0
values.push_back(x); // put the newly found number in the container
// now use a function that multiplies all numbers of the container (1 is start value)
result = std::accumulate(values.begin(), values.end(), 1, multiplies<int>());
// so much fun, also get the sum (0 is the start value, no function needed as add is standard)
int sum = std::accumulate(values.begin(), values.end(), 0);
It's important to remember the difference between = and ==. = sets something to a value while == compares something to a value. You're on the right track with incrementing x and using x as a condition to check your range of numbers. When writing code I usually try and write a "pseudocode" in English to organize my steps and get my logic down. It's also wise to consider using variables that tell you what they are as opposed to just random letters. Imagine if you were coding a game and you just had letters as variables; it would be impossible to remember what is what. When you are first learning to code this really helps a lot. So with that in mind:
/*
- While x is less than 10
- check value to see if it's mod 3
- if it's mod 3 add it to a sum
- if not's mod 3 bump a counter
- After my condition is met
- print to screen pause screen
*/
Now if we flesh out that pseudocode a little more we'll get a skeletal structure.
int main()
{
int x=1//value we'll use as a counter
int sum=0//value we'll use as a sum to print out at the end
while(x<10)//condition we'll check against
{
if (x mod 3 is zero)
{
sum=x*1;
increment x
}
else
{
increment x
}
}
//screen output the sum the sum
//system pause or cin.get() use whatever your teacher gave you.
I've given you a lot to work with here you should be able to figure out what you need from this. Computer Science and programming is hard and will require a lot of work. It's important to develop good coding habits and form now as it will help you in the future. Coding is a skill like welding; the more you do it the better you'll get. I often refer to it as the "Blue Collar Science" because it's really a skillset and not just raw knowledge. It's not like studying history or Biology (minus Biology labs) because those require you to learn things and loosely apply them whereas programming requires you to actually build something. It's like welding or plumbing in my opinion.
Additionally when you come to sites like these try and read up how things should be posted and try and seek the "logic" behind the answer and come up with it on your own as opposed to asking for the answer. People will be more inclined to help you if they think you're working for something instead of asking for a handout (not saying you are, just some advice). Additionally take the attitude these guys give you with a grain of salt, Computer Scientists aren't known to be the worlds most personable people. =) Good luck.

How to fix this to write a program that uses while loops to calculate the first n Fibonacci numbers

I am new to C++ programming and I am a bit lost. Here is what I am suppose to do and my code. Any ideas on what to do?
Write a program that uses while loops to calculate the first n Fibonacci numbers. Recall from math the following definition of the Fibonacci sequence:
The Fibonacci numbers Fn are defined as follows. F0 is 1, F1 is 1 and Fi+2 = Fi + Fi+1 for i = 0, 1, 2, ... . In other words, each number is the sum of the previous two numbers. The first few Fibonacci numbers are 1, 1, 2, 3, 5, 8, and 13.
The program should prompt the user for n (the number of Fibonacci numbers) and print the result to the screen. If the user enters an invalid value for n (n <= 0), print an error message and ask the user to re-enter n (an input validation loop for n). This MUST be a loop, not an if statement like Lab 2.
The output should be similar to the following:
Enter the number of Fibonacci numbers to compute: 3
The first 3 Fibonacci numbers are:
1 1 2
#include <iostream>
using namespace std;
int main()
{
int f0 = 0, f1 = 1,f2= 2, i = 0, n;
cout << "Enter the number of Fibonacci numbers to compute: ";
cin >> n;
if ( n <= 0)
{
cout <<"Error: Enter a positive number: ";
return 1;
}
while ( i < n){
f2 = f0 + f1;
i++;
}
cout << "The first " << n << " Fibonacci numbers are: " << endl;
cin >> n;
return 0;
}
while ( i < n){
f2 = f0 + f1;
i++;
}
See this loop, this is where the problem is, since this is homework, i'll not tell exactly what the problem is, take a pen and paper, and start executing your statements, specially this loop, you'll find your error. Just a hint, Fibonacci number is the sum of previous two fibonacci numbers.
You got the f2=f0+f1 right. However, you should note that when you increment i, then f2 becomes f1 and f1 becomes f0.
If you name them like this, it would make more sense:
int f_i_minus_2 = 0, f_i_minus_1 = 1, f_i;
and you would have
f_i = f_i_minus_1+f_i_minus_2;
Now, imagine i is 3. You have written:
f[3] = f[2]+f[1]
When you increment i, you must have:
f[4] = f[3]+f[2]
That is f_i is put in the place of f_i_minus_1 and f_i_minus_1 is put in the place of f_i_minus_2.
(Look at this:
f[3] = f[2] + f[1]
| |
\_____ \____
\ \
f[4] = f[3] + f[2]
)
So you need two assignments after computing f_i:
f_i_minus_2 = f_i_minus_1;
f_i_minus_1 = f_i;
Note that I first changed f_i_minus_2 to f_i_minus_1 because the second assignment destroys the value of f_i_minus_1.
According to wikipedia, your definition is off. F0=0, F1=1, F2=1, F3=2, ...
http://en.wikipedia.org/wiki/Fibonacci_number
Assuming wikipedia is right your loop is basically
int i = 0, f, fprev;
while( i < n )
{
if( i == 0 )
{
f = 0;
fprev = 0;
}
else if( i == 1 )
{
f = 1;
}
else
{
int fnew = f + fprev;
fprev = f;
f = fnew;
}
i++;
}
As others have pointed out, since you never modify f0 and f1 in the
loop, f2 isn't going to depend on the number of times through the
loop. Since you have to output all of the numbers at the end anyway,
why not try keeping them in an array. I'd initialize the first two
values manually, then loop until I had enough values.
(This can be done quite nicely using the STL:
// After having read n...
std::vector<int> results( 2, 1 );
while ( results.size() < n )
results.push_back( *(results.end() - 1) + *(results.end() - 2));
I'm not sure that this is what your instructor is looking for, however.
I rather suspect that he wants you to to some indexing yourself. Just
remember that if you initialize the first two values manually, your
index must start at 2, not at 0.)
Another thing: the specification you post says that you should loop if
the user enters an illegal value. This is actually a little tricky: if
the user enters something that isn't an int (say "abc"), then 1)
std::cin will remain in error state (and all further input will fail)
until cleared (by calling std::cin.clear()), and the illegal
characters will not be extracted from the stream, so your next attempt
will fail until you remove them. (I'd suggest >>ing into an
std::string for this; that will remove everything until the next white
space.) And don't ever access the variable you >>ed into until
you've checked the stream for failure—if the input fails. If the
input fails, the variable being input is not modified. If, as here, you
haven't initialized it, then anything can happen.
Finally (and I'm sure this goes beyond your assignment), you really do
need to do something to check for overflow. Beyond a certain point,
your output will become more or less random; it's better to stop and
output that you're giving up in this case.
If you are interested, there are better ways to calculate it.