CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 22
  1. #1
    Join Date
    Oct 2010
    Posts
    8

    Returning vectors from functions

    I am developing some code to run some basic CFD calculations for a class project. I am still learning C++ as I go. What I am trying to do specifically with this code is return a vector from a function. When I try to compile the code, I get a compiler error from Dev-C++. My code is

    Code:
    /* ME7310 Project 2: Diffusion - Combustion Equation
    
    Due: 11-1-2010 
    P2diffusionconvection.cpp
    */
    
    #include <fstream>
    #include <iostream>
    #include <vector>
    #include <math.h>
    using namespace std;
    
    const long double a = 2.5;
    const long double alpha = .005;
    const long double xmax = 1;
    const long double tf = .2;
    
    long double uinit(long double del_x, int num_x) {
         long double ui[num_x];
         long double x[num_x];
         for (int i = 0; i <= num_x; i++) {
             x[i] = i * del_x;
             if (x[i] == .2){
                ui[i] = .5;}
             else if (x[i] != .2){
                  if (x[i] < .2)
                     ui[i] = 1;
                  if (x[i] > .2)
                     ui[i] = 0;
             }
         }
         return ui;   //(line 32)
    }     
    
    long double fvftcs(long double t, long double del_t, long double del_x) {
         return 'd';
    }
    
    long double fvfouwc(long double t, long double del_t, long double del_x) {
         return 'b';
    }
    
    long double fdftcs(long double t, long double del_t, long double del_x) {
         return 'c';
    }
    
    long double fdfouwc(long double t, long double del_t, long double del_x) {
         return 'v';
    }
    
    long double fdlwc(long double t, long double del_t, long double del_x) {
         return 'x';
    }
    
    long double fdmcc(long double t, long double del_t, long double del_x) {
         return 'z';
    }
    
    int main() {
        long double t; //end time 
        long double del_t; //change in time
        long double dnum_t; //dummy number of time steps
        long int num_t; //number of time steps
        long double del_x; //change in x
        long double dnum_x; //dummy number of steps on x
        long int num_x; //number of steps on x
        int choose; 
        char file_name[32];
        
        cout << "********************************************" << endl;
        cout << "*ME7310 Project 2: Diffusion-Convection PDE*" << endl;
        cout << "*                  Due: 11-1-2010*" << endl;
        cout << "********************************************" << endl;
        
        //input file name
        cout << "\nEnter the file name: ";
        cin >> file_name;
        ofstream outputfile(file_name, ios::out);
        
        //input parameters
        cout << "Enter time (s): ";
        cin >> t;
        outputfile << "Time:," << t << "\n";
        
        cout << "Enter delta t (s): ";
        cin >> del_t;
        outputfile << "Delta t:," << del_t << "\n";
        
        cout << "Enter delta x (m): ";
        cin >> del_x;
        outputfile << "Delta x:," << del_x << "\n";
        
        //find num_t and num_x
        dnum_t = t / del_t;
        num_t = static_cast<int>(dnum_t);
        cout << "\nNumber of time steps: " << num_t << endl;
        outputfile << "Time steps:," << num_t << "\n";
        
        dnum_x = xmax / del_x;
        num_x = static_cast<int>(dnum_x);
        cout << "Number of x steps" << num_x << endl;
        outputfile << "X steps:," << num_x << "\n";
        
        long double x[num_x];
        
        outputfile << "\nInitial Condition:" << "\n" << "\n";
        
        for (int i = 0; i <= num_x; i++) {
            x[i] = i * del_x;
            outputfile << x[i] << ",";
        }
        
        outputfile << "\n";
        
        long double ui[num_x];
        ui = uinit(del_x, num_x); //(line 116)
                
        for (int i = 0; i <= num_x; i++) {
            outputfile << ui[i] << ",";
        }
        
        outputfile << "\n";
        
        cout << "\n";
        cout << "Choose explicit scheme to use." << endl;
        cout << "1: Finite Volume: FTCS for both convection and diffusion" << endl;
        cout << "2: Finite Volume: First order upwind for convection, FTCS for diffusion" << endl;
        cout << "3: Finite Difference: FTCS for both convection and diffusion" << endl;
        cout << "4: Finite Difference: First order upwind for convection, FTCS for diffusion" << endl;
        cout << "5: Finite Difference: Lax-Wendroff for convection, FTCS for diffusion" << endl;
        cout << "6: Finite Difference: MacCormack for convection, FTCS for diffusion" << endl;
        cout << "7: Exit" << endl;
        while (choose != 7){
              cin >> choose;
        
              if (choose == 1) {
                 outputfile << "\nFinite Volume: FTCS for both convection and diffusion.";
                 outputfile << "\n" << fvftcs(t, del_t, del_x) << "\n";
              }
        
              if (choose == 2) {
                 outputfile << "\nFinite Volume: First order upwind for convection, FTCS for diffusion.";
                 outputfile << "\n" << fvfouwc(t, del_t, del_x) << "\n";
              }
        
              if (choose == 3) {
                 outputfile << "\nFinite Difference: FTCS for both convection and diffusion.";
                 outputfile << "\n" << fdftcs(t, del_t, del_x) << "\n";
              }
        
              if (choose == 4) {
                 outputfile << "\nFinite Difference: First order upwind for convection, FTCS for diffusion.";
                 outputfile << "\n" << fdfouwc(t, del_t, del_x) << "\n"; 
              }
              
              if (choose == 5) {
                 outputfile << "\nLax-Wendroff for convection, FTCS for diffusion.";
                 outputfile << "\n" << fdlwc(t, del_t, del_x) << "\n"; 
              }
              
              if (choose == 6) {
                 outputfile << "\nFinite Difference: MacCormack for convection, FTCS for diffusion.";
                 outputfile << "\n" << fdmcc(t, del_t, del_x) << "\n"; 
              }
              
              if (choose == 7) {
                   system("PAUSE");
                   return EXIT_SUCCESS;
              }
        }
    }
    The compiler errors occur on line 32 and line 116.

    The error for line 32 is " In function `long double uinit(long double, int)': cannot convert `long double*' to `long double' in return "

    The error for line 116 is " In function `int main()': incompatible types in assignment of `long double' to `long double[((unsigned int)((int)num_x))]' "

    I have not been able to tell what these errors mean, let alone fix them.

    In essence, what this function, and the other as of yet undefined functions, need to do is take the stated inputs and return a vector as the output after performing the required mathematical operations.

    Can anyone tell me what I did wrong and possibly how to fix it?

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Returning vectors from functions

    I notice that you #include <vector>, but you never actually use say, std::vector<long double>. Instead, you use variable length arrays, which are non-standard, and declare your functions as returning a long double even though you talk about getting them to return a vector.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Join Date
    Oct 2010
    Posts
    8

    Re: Returning vectors from functions

    I may be getting my terminology mixed up, but what I want to return is the variable length array I created. I may not even need the #include <vector> tag for this program.

  4. #4
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Returning vectors from functions

    Quote Originally Posted by hobbes543
    what I want to return is the variable length array I created.
    You cannot return an array, but you can return a pointer to the first element of the array. Unfortunately, the array is local to the function.

    You may well be better off actually using std::vector, unless you want to create the variable length array in the caller and pass a pointer to the first element of the array to the function. (Even then, the fact that VLAs are non-standard may be undesirable in the long run.)
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  5. #5
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: Returning vectors from functions

    You may want to pass in an output parameter rather than trying to return an array.

  6. #6
    Join Date
    Dec 2009
    Posts
    596

    Re: Returning vectors from functions

    If we pass a pointer to the first element of the array will all of the elements in the array be available?

  7. #7
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Returning vectors from functions

    Quote Originally Posted by viperbyte
    If we pass a pointer to the first element of the array will all of the elements in the array be available?
    Yes. GCDEF's suggestion in post #5 is a generalisation of this.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  8. #8
    Join Date
    Oct 2010
    Posts
    8

    Re: Returning vectors from functions

    Thanks for the help. The compiler no longer crashes now that I am using std::vector<...>.

    Of course, considering my inexperience, it is out of one fire into another. The code now compiles fine, but when I run it, it crashes when it gets to the point where it is supposed to assign the vector created by the the uinit function to a vector within the main function.

    Here is my updated code.

    Code:
    /* ME7310 Project 2: Diffusion - Combustion Equation
    
    Due: 11-1-2010 
    P2diffusionconvection.cpp
    */
    
    #include <fstream>
    #include <iostream>
    #include <vector>
    #include <math.h>
    using namespace std;
    
    const long double a = 2.5;
    const long double alpha = .005;
    const long double xmax = 1;
    const long double tf = .2;
    
    std::vector<long double> uinit(long double del_x, int num_x) {
         std::vector<long double> ui;
         long double x[num_x];
         for (int i = 0; i <= num_x; i++) {
             x[i] = i * del_x;
             long double v;
             if (x[i] == .2){
                ui[i] = .5;}
             else if (x[i] != .2){
                  if (x[i] < .2)
                     ui[i] = 1;
                  if (x[i] > .2)
                     ui[i] = 0;
             }
         }
         return ui;
    }     
    
    long double fvftcs(long double t, long double del_t, long double del_x) {
         return 'd';
    }
    
    long double fvfouwc(long double t, long double del_t, long double del_x) {
         return 'b';
    }
    
    long double fdftcs(long double t, long double del_t, long double del_x) {
         return 'c';
    }
    
    long double fdfouwc(long double t, long double del_t, long double del_x) {
         return 'v';
    }
    
    long double fdlwc(long double t, long double del_t, long double del_x) {
         return 'x';
    }
    
    long double fdmcc(long double t, long double del_t, long double del_x) {
         return 'z';
    }
    
    int main() {
        long double t; //end time 
        long double del_t; //change in time
        long double dnum_t; //dummy number of time steps
        long int num_t; //number of time steps
        long double del_x; //change in x
        long double dnum_x; //dummy number of steps on x
        long int num_x; //number of steps on x
        int choose; 
        char file_name[32];
        
        cout << "********************************************" << endl;
        cout << "*ME7310 Project 2: Diffusion-Convection PDE*" << endl;
        cout << "*             Due: 11-1-2010*" << endl;
        cout << "********************************************" << endl;
        
        //input file name
        cout << "\nEnter the file name: ";
        cin >> file_name;
        ofstream outputfile(file_name, ios::out);
        
        //input parameters
        cout << "Enter time (s): ";
        cin >> t;
        outputfile << "Time:," << t << "\n";
        
        cout << "Enter delta t (s): ";
        cin >> del_t;
        outputfile << "Delta t:," << del_t << "\n";
        
        cout << "Enter delta x (m): ";
        cin >> del_x;
        outputfile << "Delta x:," << del_x << "\n";
        
        //find num_t and num_x
        dnum_t = t / del_t;
        num_t = static_cast<int>(dnum_t);
        cout << "\nNumber of time steps: " << num_t << endl;
        outputfile << "Time steps:," << num_t << "\n";
        
        dnum_x = xmax / del_x;
        num_x = static_cast<int>(dnum_x);
        cout << "Number of x steps" << num_x << endl;
        outputfile << "X steps:," << num_x << "\n";
        
        long double x[num_x];
        
        outputfile << "\nInitial Condition:" << "\n" << "\n";
        
        for (int i = 0; i <= num_x; i++) {
            x[i] = i * del_x;
            outputfile << x[i] << ",";
        }
        
        outputfile << "\n";
        
        std::vector<long double> vi;
        
        vi = uinit(del_x, num_x);
                          
        for (int i = 0; i <= vi.size(); i++) {
            outputfile << vi[i] << ",";
        }
        
        outputfile << "\n";
        
        cout << "\n";
        cout << "Choose explicit scheme to use." << endl;
        cout << "1: Finite Volume: FTCS for both convection and diffusion" << endl;
        cout << "2: Finite Volume: First order upwind for convection, FTCS for diffusion" << endl;
        cout << "3: Finite Difference: FTCS for both convection and diffusion" << endl;
        cout << "4: Finite Difference: First order upwind for convection, FTCS for diffusion" << endl;
        cout << "5: Finite Difference: Lax-Wendroff for convection, FTCS for diffusion" << endl;
        cout << "6: Finite Difference: MacCormack for convection, FTCS for diffusion" << endl;
        cout << "7: Exit" << endl;
        while (choose != 7){
              cin >> choose;
        
              if (choose == 1) {
                 outputfile << "\nFinite Volume: FTCS for both convection and diffusion.";
                 outputfile << "\n" << fvftcs(t, del_t, del_x) << "\n";
              }
        
              if (choose == 2) {
                 outputfile << "\nFinite Volume: First order upwind for convection, FTCS for diffusion.";
                 outputfile << "\n" << fvfouwc(t, del_t, del_x) << "\n";
              }
        
              if (choose == 3) {
                 outputfile << "\nFinite Difference: FTCS for both convection and diffusion.";
                 outputfile << "\n" << fdftcs(t, del_t, del_x) << "\n";
              }
        
              if (choose == 4) {
                 outputfile << "\nFinite Difference: First order upwind for convection, FTCS for diffusion.";
                 outputfile << "\n" << fdfouwc(t, del_t, del_x) << "\n"; 
              }
              
              if (choose == 5) {
                 outputfile << "\nLax-Wendroff for convection, FTCS for diffusion.";
                 outputfile << "\n" << fdlwc(t, del_t, del_x) << "\n"; 
              }
              
              if (choose == 6) {
                 outputfile << "\nFinite Difference: MacCormack for convection, FTCS for diffusion.";
                 outputfile << "\n" << fdmcc(t, del_t, del_x) << "\n"; 
              }
              
              if (choose == 7) {
                   system("PAUSE");
                   return EXIT_SUCCESS;
              }
        }
    }

  9. #9
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    Re: Returning vectors from functions

    First, this is illegal code
    Code:
    long double x[num_x];
    An array declared like that has to have a constant length. Also, you don't need that array at all. Get rid of it and just use a single local double as calculation variable used for finding the value to assign the vector elements with.

    Floating point variables are not as precise as you expect. Your equality test will not be equal for the value you expect. See this http://en.wikipedia.org/wiki/IEEE_754-1985 and http://en.wikipedia.org/wiki/IEEE_754-2008
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Returning vectors from functions

    Quote Originally Posted by hobbes543 View Post
    Thanks for the help. The compiler no longer crashes now that I am using std::vector<...>.
    Code:
    if (x[i] == .2
    Behaviour is implementation defined. There is no guarantee that floating point variables are exactly the value you're testing, unless the value is a sum of an inverse power of 2.

    See S_M_A's links to this info.

    Regards,

    Paul McKenzie

  11. #11
    Join Date
    Oct 2010
    Posts
    8

    Re: Returning vectors from functions

    Even using x as a local variable doesn't prevent the code from crashing.

    My code does everything before this line, so my problem I am think is uinit or something to do with how it is called.


    Code:
        std::vector<long double> vi;
        
        vi = uinit(del_x, num_x);
                          
        for (int i = 0; i <= vi.size(); i++) {
            outputfile << vi[i] << ",";
        }
        
        outputfile << "\n";
        
        cout << "\n";
        cout << "Choose explicit scheme to use." << endl;
        cout << "1: Finite Volume: FTCS for both convection and diffusion" << endl;
        cout << "2: Finite Volume: First order upwind for convection, FTCS for diffusion" << endl;
        cout << "3: Finite Difference: FTCS for both convection and diffusion" << endl;
        cout << "4: Finite Difference: First order upwind for convection, FTCS for diffusion" << endl;
        cout << "5: Finite Difference: Lax-Wendroff for convection, FTCS for diffusion" << endl;
        cout << "6: Finite Difference: MacCormack for convection, FTCS for diffusion" << endl;
        cout << "7: Exit" << endl;
        while (choose != 7){
              cin >> choose;
        
              if (choose == 1) {
                 outputfile << "\nFinite Volume: FTCS for both convection and diffusion.";
                 outputfile << "\n" << fvftcs(t, del_t, del_x) << "\n";
              }
        
              if (choose == 2) {
                 outputfile << "\nFinite Volume: First order upwind for convection, FTCS for diffusion.";
                 outputfile << "\n" << fvfouwc(t, del_t, del_x) << "\n";
              }
        
              if (choose == 3) {
                 outputfile << "\nFinite Difference: FTCS for both convection and diffusion.";
                 outputfile << "\n" << fdftcs(t, del_t, del_x) << "\n";
              }
        
              if (choose == 4) {
                 outputfile << "\nFinite Difference: First order upwind for convection, FTCS for diffusion.";
                 outputfile << "\n" << fdfouwc(t, del_t, del_x) << "\n"; 
              }
              
              if (choose == 5) {
                 outputfile << "\nLax-Wendroff for convection, FTCS for diffusion.";
                 outputfile << "\n" << fdlwc(t, del_t, del_x) << "\n"; 
              }
              
              if (choose == 6) {
                 outputfile << "\nFinite Difference: MacCormack for convection, FTCS for diffusion.";
                 outputfile << "\n" << fdmcc(t, del_t, del_x) << "\n"; 
              }
              
              if (choose == 7) {
                   system("PAUSE");
                   return EXIT_SUCCESS;
              }
        }
    }
    Also, here is the updated uinit function

    Code:
    std::vector<long double> uinit(long double del_x, int num_x) {
         std::vector<long double> ui;
         float x;
         for (int i = 0; i <= num_x; i++) {
             x = i * del_x;
             if (x == .2){
                ui[i] = .5;}
             else if (x != .2){
                  if (x < .2)
                     ui[i] = 1;
                  if (x > .2)
                     ui[i] = 0;
             }
         }
         return ui;
    }

  12. #12
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Returning vectors from functions

    Quote Originally Posted by hobbes543 View Post
    Also, here is the updated uinit function
    Code:
    std::vector<long double> uinit(long double del_x, int num_x) 
    {
         std::vector<long double> ui;  // a vector that has size 0
         float x;
         for (int i = 0; i <= num_x; i++) {
             x = i * del_x;
             if (x == .2)   // Yeah, sure!
            {
                ui[i] = .5;   // There is no u[i] element, since the vector is empty.
    When you declare a vector, it has no elements. So the problem is obvious -- you are trying to write to an element in the vector that doesn't exist.

    Since you are passing num_x, your vector has to have at least num_x elements.
    Code:
         std::vector<long double> ui(num_x);  // a vector that has size num_x
    That is how you declare a vector with num_x elements.

    Secondly, the "yeah sure" comment means exactly that. You can't test for equality, as your program as it stands now will run differently depending on compiler settings, compiler, etc. In other words, it is greatly flawed. I'll ask this question: How many times is this loop performed:
    Code:
    for (double i = 0.0 i < =100.0; i += 0.1)
    The answer to that question is -- there is no answer. When you add 0.1 to a double, you're not incrementing by 0.1 -- you're incrementing by some number that is not exactly 0.1, so the loop may run 1000 times, or maybe 999 times or some other number of times.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; October 20th, 2010 at 02:55 PM.

  13. #13
    Join Date
    Oct 2010
    Posts
    8

    Re: Returning vectors from functions

    Ok, so the question is, how do you get it so that you can use that condition.

    For the problem I have to solve the initial condition is given as u(x,0) = {1.0 at x < .2, 0.5 at x = .2, 0.0 at x > .2}

    And that is what this function is supposed to be doing. Calculating the u vector at the initial condition of the problem.

    When I include this for loop

    Code:
    for (int i = 0; i <= num_x; i++) {
             x = i * del_x;
             if (x < .2){
                ui[i] = 1;}
             if (x > .2){
                ui[i] = 0;}
         }
    The code crashes, but if it is commented out, the code works fine, albiet writing zero to ever element of ui.

    So... I guess what I am missing is how to properly assign the values to ui with these conditions.
    Last edited by hobbes543; October 20th, 2010 at 03:25 PM. Reason: updating problem

  14. #14
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Returning vectors from functions

    Quote Originally Posted by hobbes543 View Post
    Ok, so the question is, how do you get it so that you can use that condition.
    http://www.parashift.com/c++-faq/newbie.html#faq-29.16
    http://www.parashift.com/c++-faq/newbie.html#faq-29.17
    http://www.parashift.com/c++-faq/newbie.html#faq-29.18
    And that is what this function is supposed to be doing. Calculating the u vector at the initial condition of the problem.
    Secondly, as one of the links mentioned, for many "book" math formulas, translating that book formula to something the computer will use is not sometimes obvious. That's why many algebra formulas you see have both a "math book" version, and a version that is meant to be used by a binary computing machine (i.e. your computer).

    So you can't just take something verbatim out of the book that uses real numbers and assume it will work if you write the program as you see in the book. So you have to adjust the specs so that it will work reliably.

    Regards,

    Paul McKenzie

  15. #15
    Join Date
    Oct 2010
    Posts
    8

    Re: Returning vectors from functions

    Thank you for all the help so far.

    One last question, I think. What is happening now, is when the vector is returned and printed to the output, it is putting num_x - 1 0s in front of the vector and then assigning the values as per my function.

    First I tried assigning the value using this for the function
    Code:
    std::vector<long double> uinit(long double del_x, int num_x) {
         std::vector<long double> ui(num_x);
         double x;
         int y;
         for (int i = 0; i <= num_x; i++) {
             x = i * del_x * 100;
             y = static_cast<int>(x);
             if (y < 20){
                ui[i] = 1;}
             if (y > 20){
                ui[i] = 0;}
         }
         return ui;
    }
    And the program crashes when it gets to the part where the function is called

    I changed the function to this

    Code:
    std::vector<long double> uinit(long double del_x, int num_x) {
         std::vector<long double> ui(num_x);
         double x;
         int y;
         for (int i = 0; i <= num_x; i++) {
             x = i * del_x * 100;
             y = static_cast<int>(x);
             if (y < 20){
                ui.push_back(1);}
             if (y > 20){
                ui.push_back(0);}
         }
         return ui;
    }
    And it worked, but I got the above problem

    The section of my main function that calls the function and prints it to the file is

    Code:
    std::vector<long double> vi(uinit(del_x, num_x)); 
        
        vi = uinit(del_x, num_x);
                                
        for (int i = 0; i <= vi.size(); i++) {
            outputfile << vi[i] << ",";
        }
    Last edited by hobbes543; October 20th, 2010 at 04:14 PM. Reason: fixing typo in code. No effect on problem

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured