0

Working on a 1-d Harmonic oscillator using recursive functions, code works in fortran and trying to convert to C++ in order to learn the new syntax.

I have fixed all the notified errors so far searching through google, but still not getting a result. The program just runs seemingly forever without posting results.

I think the likely answer is maybe its not being calculated at all or there some some infinit loop because of a syntax problem in my for loop or called functions? but I am not seeing it and it is not identifying an error with them.

Any advice on why this program is not working properly?

//
//  main.cpp
//  1-d HO
//
//  Created by Grant Metheny on 3/2/16.
//  Copyright (c) 2016 Grant Metheny C++ Codes. All rights reserved.
//

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <cmath>
#include <math.h>

using namespace std;

int i = 0;
int n = 0;
double x = 1.;
double xmax = 5;
double imax = 1000;
double wavefunc = 0;
double fact = 1;
double hpol = 1;
double wf0 = 1;
double wf1 = 1;
double wf2 = 1;
double wf3 = 1;
double wf4 = 1;
double wf5 = 1;
double wf6 = 1;

double wavefunction(int n, double x)
{
    return wavefunc = pow(2.0,-(n*.5)) * pow(M_PI,.25) * exp(-(.5*pow(x,2.0)));
}

double factorial(int n)
{
    for (i = 0; i <= n; i++)
        
        if (i == 0)
             fact = 1.;
        else
             fact = fact * i;
    
    return fact;
}

double hermite(int n, double x)
{
    for (i = 0; i <= n; i++)
        if (i==1)
            hpol = 1.0;
        else if (n==1)
            hpol = 2*x;
        else
            hpol = 2*x*hermite(n-1,x) - 2*(n-1)*hermite(n-2,x);
    
    return hpol;
}

double dx = 2*xmax/imax;


int main(int argc, const char * argv[]) {
    
    
    for (i=0; i <= imax; i++) {
    
    x =  5. - dx*i;
    
    n = 0;
    wf0 = hermite(n,x) * wavefunction(n,x) * pow(factorial(n),(-(.5)));
    
    n = 1;
    wf1 = hermite(n,x) * wavefunction(n,x) * pow(factorial(n),(-(.5)));
    
    n = 2;
    wf2 = hermite(n,x) * wavefunction(n,x) * pow(factorial(n),(-(.5)));
    
    n = 3;
    wf3 = hermite(n,x) * wavefunction(n,x) * pow(factorial(n),(-(.5)));
    
    n = 4;
    wf4 = hermite(n,x) * wavefunction(n,x) * pow(factorial(n),(-(.5)));
    
    n = 5;
    wf5 = hermite(n,x) * wavefunction(n,x) * pow(factorial(n),(-(.5)));
    
    n = 6;
    wf6 = hermite(n,x) * wavefunction(n,x) * pow(factorial(n),(-(.5)));
    
    cout <<"I="<< i <<"X="<< x <<"WF0="<< wf0<<"WF1=" << wf1;  // wf2, wf3, wf4, wf5, wf6
    
}
    return 0;
}
g-metheny
  • 1
  • 2
  • If you want to learn C++ I recommend you find a good beginners book instead, for example from [The Definitive C++ Book Guide and List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Some programmer dude Mar 03 '16 at 08:36

1 Answers1

1

Your for loops are not terminating. Instead of this:

for (i = 0; n; i++)

(which is clearly Fortran-inspired), you need to do this:

for (i = 0; i < n; i++)

The idea is that the second part of the for loop is not a limit; it is a predicate that should evaluate to true (to keep the loop going one more iteration) or false (to exit the loop). Because C/C++ treats non-zero integer values as true whenever a true/false value is expected, the loops just keep on going.

You need to make that correction in several places in your code.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • made the changes but still getting a long run time with no results. so far have allowed like 5 min run time. – g-metheny Mar 03 '16 at 08:43
  • @g-metheny - You sure you changed them all? The loop in `main` involving `i` and `imax` also needs to be changed. – Ted Hopp Mar 03 '16 at 08:44
  • just updated the code in the question, changed 3 for loops including the one in main, factorial, and hermite. – g-metheny Mar 03 '16 at 08:44
  • @g-metheny - Okay. That's probably not a good idea because the original question is now lost. It would be better to at least leave a comment in the code about what it used to be. But at least I see that you did catch all the `for` loops. Some of your calculations are inefficient, but with the small values of `n`, I don't see anything that should be taking 5 minutes. Can you tell by using a debugger where it's spending its time? Or perhaps add in some logging statements. – Ted Hopp Mar 03 '16 at 08:48
  • @g-metheny - Hm. The recursion in the `hermite()` function looks suspicious. Won't that recurse forever if `n != 1`? The `if` tests look suspicious to me. – Ted Hopp Mar 03 '16 at 08:52
  • fixed it!!! the hermit function didn't need to be in a "for" loop at all. the recursive nature of the function worked by the nature of calling itself within the "if" statement – g-metheny Mar 03 '16 at 08:52
  • @g-metheny - Cool. I thought that looked wrong. By the way, some of those loop conditions look like they should perhaps be `<` instead of `<=`. – Ted Hopp Mar 03 '16 at 08:53
  • how would i use the debugger to check where it is spending its time? this could be useful in the future – g-metheny Mar 03 '16 at 08:53
  • @g-metheny - You could step through and watch the pattern of code execution. Presumably it would take an unexpected branch fairly early on. Or you could set conditional break points for unexpected conditions (like negative argument values). – Ted Hopp Mar 03 '16 at 08:54
  • I will keep that in mind. Thank you very much for the help. Darn code is freezing up my comp now, so its still got some bugs, but it pumped out results which is a start. I will try to use those debug techniques to find the inefficiencies. – g-metheny Mar 03 '16 at 09:02
  • Just for completeness sake: because the for loop in main and the for loop in factorial both use the same variable i, the program ends up using i=7 infinitely many times in main. Essentially it changes the value of i after it calculates factorial to 6, and does this every iteration thus it never moves on in the code. changing one of them to ii or j or whatever corrected the problem. once this error was corrected to code runs in about a second. – g-metheny Mar 03 '16 at 09:29
  • @g-metheny - The solution there is to eliminate most of the global variables and declare local variables in each method. So get rid of the global declaration of `i` (for instance) and change each loop involving `i` to `for (int i = 0 ...`. – Ted Hopp Mar 03 '16 at 15:07