Vectors as function arguments

My problem concerns calling vectors and other parameters into a function as arguments to the function. My current code which has as arguments some 1D vectors is not working and I am getting error messages all over the place. I show my code and explain what it attempts to do following it:

1
2
3
4
5
6
int main(){
.
.
.
for (unsigned int i3=0; y2[i3]>2e7 && R_pl[0].size()>3 && (y3[i3]/y3[0])>0.002 && y3_TA[i3]>0 && y5[i3]>LB; i3++){
    runge_kutta_evl(i3,dt,&t, &y1,&y2, &y3, &y5, &r_range, &m_range, &rho_range);


and where the runge_kutta_evl function is defined by:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void runge_kutta_evl(unsigned int I3, double Dt, vector<double>* T, vector<double>* Y1, vector<double>* Y2, vector<double>* Y3, vector<double>* Y5, vector<double>* r_range, vector<double>* m_range,vector<double>* rho_range){
    unsigned int pp_size=r_range.size();
    double m_int_0=Linear_once(pp_size,r_range, m_range,(*Y2)[I3]);
    double rho_int_0=Linear_once(pp_size,r_range, rho_range,(*Y2)[I3]);
    double a0_y1 = Dt*dy1_dt((*Y1)[I3], (*Y2)[I3], (*Y3)[I3], (*Y5)[I3], m_int_0, rho_int_0);
    double b0_y2=Dt*dy2_dt((*Y1)[I3]);
    double c0_y3=Dt*dy3_dt((*Y1)[I3], (*Y2)[I3], (*Y5)[I3], rho_int_0);
    double e0_y5=Dt*dy5_dt((*Y1)[I3], (*Y2)[I3], (*Y3)[I3], (*Y5)[I3], rho_int_0);

    double m_int_1=Linear_once(pp_size,r_range, m_range,(*Y2)[I3]+0.5*b0_y2);
    double rho_int_1=Linear_once(pp_size,r_range, rho_range,(*Y2)[I3]+0.5*b0_y2);
    double a1_y1 = Dt*dy1_dt((*Y1)[I3]+0.5*a0_y1, (*Y2)[I3]+0.5*b0_y2, (*Y3)[I3]+0.5*c0_y3, (*Y5)[I3]+0.5*e0_y5,  m_int_1, rho_int_1);
    double b1_y2 = Dt*dy2_dt((*Y1)[I3]+0.5*a0_y1);
    double c1_y3 = Dt*dy3_dt((*Y1)[I3]+0.5*a0_y1, (*Y2)[I3]+0.5*b0_y2, (*Y5)[I3]+0.5*e0_y5, rho_int_1);
    double e1_y5 = Dt*dy5_dt((*Y1)[I3]+0.5*a0_y1, (*Y2)[I3]+0.5*b0_y2, (*Y3)[I3]+0.5*c0_y3, (*Y5)[I3]+0.5*e0_y5, rho_int_1);

    double m_int_2=Linear_once(pp_size,r_range, m_range,(*Y2)[I3]+0.5*b1_y2);
    double rho_int_2=Linear_once(pp_size,r_range, rho_range, (*Y2)[I3]+0.5*b1_y2);
    double a2_y1 = Dt*dy1_dt((*Y1)[I3]+0.5*a1_y1, (*Y2)[I3]+0.5*b1_y2, (*Y3)[I3]+0.5*c1_y3, (*Y5)[I3]+0.5*e1_y5, m_int_2, rho_int_2);
    double b2_y2 = Dt*dy2_dt((*Y1)[I3]+0.5*a1_y1);
    double c2_y3 = Dt*dy3_dt((*Y1)[I3]+0.5*a1_y1, (*Y2)[I3]+0.5*b1_y2, (*Y5)[I3]+0.5*e1_y5, rho_int_2);
    double e2_y5 = Dt*dy5_dt((*Y1)[I3]+0.5*a1_y1, (*Y2)[I3]+0.5*b1_y2, (*Y3)[I3]+0.5*c1_y3, (*Y5)[I3]+0.5*e1_y5, rho_int_2);

    double m_int_3=Linear_once(pp_size, r_range, m_range, (*Y2)[I3]+b2_y2);
    double rho_int_3=Linear_once(pp_size,r_range, rho_range, (*Y2)[I3]+b2_y2);
    double a3_y1 = Dt*dy1_dt((*Y1)[I3]+a2_y1, (*Y2)[I3]+b2_y2, (*Y3)[I3]+c2_y3, (*Y5)[I3]+e2_y5,  m_int_3, rho_int_3);
    double b3_y2 = Dt*dy2_dt((*Y1)[I3]+a2_y1);
    double c3_y3 = Dt*dy3_dt((*Y1)[I3]+a2_y1, (*Y2)[I3]+b2_y2, (*Y5)[I3]+e2_y5, rho_int_3);
    double e3_y5 = Dt*dy5_dt((*Y1)[I3]+a2_y1, (*Y2)[I3]+b2_y2, (*Y3)[I3]+c2_y3, (*Y5)[I3]+e2_y5, rho_int_3);

    *T.push_back((*T)[0] + Dt);
    (*Y1).push_back((*Y1)[I3] + (a0_y1 + 2*a1_y1 + 2*a2_y1 + a3_y1)/6);
    (*Y2).push_back((*Y2)[I3] + (b0_y2 + 2*b1_y2 + 2*b2_y2 + b3_y2)/6);
    (*Y3).push_back((*Y3)[I3] + (c0_y3 + 2*c1_y3 + 2*c2_y3 + c3_y3)/6);
    (*Y5).push_back((*Y5)[I3] + (e0_y5 + 2*e1_y5 + 2*e2_y5 + e3_y5)/6);

}



Prior to calling the function, there are defintions I have not shown for the purpose of not cluttering this discussion. But y1,y2,y3,y5,t, m_range,r_range, and rho_range are defined as vectors of double types before calling the function. The errors which are output by running the function with reference calls using '&'s and arguments of pointers outputs some of the following errors for this first block of code:

1
2
3
4
5
6
7
8
9
error: ‘r_range’ was not declared in this scope
error: ‘m_range’ was not declared in this scope
error: ‘Y2’ was not declared in this scope
error: ‘Linear_once’ was not declared in this scope
error: ‘rho_range’ was not declared in this scope
error: ‘Y1’ was not declared in this scope
error: ‘Y3’ was not declared in this scope
error: ‘Y5’ was not declared in this scope

for
1
2
3
4
5
6
7
    unsigned int pp_size=r_range.size();
    double m_int_0=Linear_once(pp_size,r_range, m_range,(*Y2)[I3]);
    double rho_int_0=Linear_once(pp_size,r_range, rho_range,(*Y2)[I3]);
    double a0_y1 = Dt*dy1_dt((*Y1)[I3], (*Y2)[I3], (*Y3)[I3], (*Y5)[I3], m_int_0, rho_int_0);
    double b0_y2=Dt*dy2_dt((*Y1)[I3]);
    double c0_y3=Dt*dy3_dt((*Y1)[I3], (*Y2)[I3], (*Y5)[I3], rho_int_0);
    double e0_y5=Dt*dy5_dt((*Y1)[I3], (*Y2)[I3], (*Y3)[I3], (*Y5)[I3], rho_int_0);


The question is: why is this method not working, and what is the concept I may be missing to fix things?
Last edited on
That is some hard-to-read code.

unsigned int I3, double Dt, vector<double>* T, vector<double>* Y1, vector<double>* Y2, vector<double>* Y3, vector<double>* Y5, vector<double>* r_range, vector<double>* m_range,vector<double>* rho_range)

Try passing your vectors by reference rather than pointer, use & instead of *.
But if I want to call the actual vector values by using []s inside the function, don't I need a call to address given by runge_kutta_evl(i3,dt,&t, &y1,&y2, &y3, &y5, &r_range, &m_range, &rho_range); and pointers in the function definition, as I have now?
No you don't. You can use the vector by [] inside the function when passing by reference.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <vector>

void change(std::vector<int>& hello);

int main()
{
    std::vector<int> hello;
    change(hello);
    std::cout << "Number: " << hello[0] << std::endl;
}

void change(std::vector<int>& hello)
{
    hello.push_back(5);
}


Output:

Number: 5
Last edited on
I appreciate your kind help. I am still getting the same error messages as before even with these changes. That is, if I change the call to the function to runge_kutta_evl(i3,dt,t, y1,y2, y3, y5, r_range, m_range, rho_range); and then have the function defined as the following, showing only the first few lines,
1
2
3
4
5
6
7
8
void runge_kutta_evl(unsigned int i3, double dt, vector<double>& t, vector<double>& y1, vector<double>& y2, vector<double>& y3, vector<double>& y5, vector<double>& r_range, vector<double>& m_range,vector<double>& rho_range){
    unsigned int pp_size=r_range.size();
    double m_int_0=Linear_once(pp_size,r_range, m_range,y2[i3]);       
    double rho_int_0=Linear_once(pp_size,r_range, rho_range,y2[i3]);
    double a0_y1 = dt*dy1_dt(y1[i3], y2[i3], y3[i3], y5[i3], m_int_0, rho_int_0);
    double b0_y2=dt*dy2_dt(y1[i3]);
    double c0_y3=dt*dy3_dt(y1[i3], y2[i3], y5[i3], rho_int_0);
    double e0_y5=dt*dy5_dt(y1[i3], Y2[i3], y3[i3], y5[i3], rho_int_0);


I get the following errors for these first few lines that are shown:
1
2
3
4
5
6
7
8
9
cpp_iron_functions.h:37: error: r_range was not declared in this scope
cpp_iron_functions.h:38: error: m_range was not declared in this scope
cpp_iron_functions.h:38: error: y2 was not declared in this scope
cpp_iron_functions.h:38: error: Linear_once was not declared in this scope
cpp_iron_functions.h:39: error: rho_range was not declared in this scope
cpp_iron_functions.h:40: warning: pointer to a function used in arithmetic
cpp_iron_functions.h:40: error: y3 was not declared in this scope
cpp_iron_functions.h:40: error: y5 was not declared in this scope

, where the line 37 refers to the line unsigned int pp_size=r_range.size();. I get disenchanted by the fact that none of this works.
Well, your error means that you're using those vectors somewhere in which they are not recognized. You have to find that place. Are you using them somewhere else?
They are initialized and things are well with them prior to the function call. As the errors note, the problem lies either in the method of incall or something similar. I am at a complete loss. I cannot make any progress.
Well, I dont think youve given us enough code to see what the problem is. If the project is not too huge you could zip it and upload it somewhere like http://tinyupload.com/ and post the link
I have uploaded the relevant files.

The main c++ function can be gotten at:
http://s000.tinyupload.com/index.php?file_id=32553424246973561536

The functions which I have constructed and which are called in the above by #include "" are at the link:

http://s000.tinyupload.com/index.php?del_id=02705713468328026623

The second included function is borrowed from Codecogs to perform linear interpolation:

http://s000.tinyupload.com/?file_id=07987688744292887980

Perhaps another individual may be able to offer progressive advice where I have failed.
You could have just zipped the project up so you dont have to upload each individual file, and others download each individual file. But I'll take a look at it.
Last edited on
Thank you Tarik. The ""_range vectors which are pushed back from a file can be initialised with some dummy elements since I have not provided the source text file. If you think you may find it helpful, I can provide it. By the by, is there any way in which I can give you credit for your kind help? Is there a points system on here as there is on Stackexchange whereby I can give the helper credit for their effort?
Regarding runge_kutta_evl function:

The problem is this - double dt You can't pass a macro as an argument, you already have access to it, so there is no need for it to be there. Just remove that from the paranthesis.

Also, You are calling a function called Linear_once, but what is that? Linear_Once is in the linear.h, and you haven't included it in cpp_iron_functions.h

Also, You've put Linear_once in 2 different namespaces , so if you want to reach it you would have to do Maths::Interpolation::Linear_once()

Oh and btw, to use vector, you have to #include <vector> which you forget to do, also a vector is part of the c++ standard library, so either using namespace std; (dont do this) or std::vector

Linear_Once according to your function, takes an int, double pointer, double pointer, and a double. But you are giving it an unsigned integer, a vector of double, and another vector of double, and then a double. You need to change the Linear_Once function so it takes vector, and change it from pointers to references like we talked about.

double Linear_once(int N, std::vector<double>& x, std::vector<double>& y, double a )

And since Linear_Once calls the constructor, don't forget to change the constructor arguments so it matches what you're giving it - Maths::Interpolation:: Linear A(N, x, y);

Edit 3:

Back to your runge_kutta_evl function -

You are using Y1, Y2, Y3, Y5, DT, I3, in that function, those don't exist. Look at the arguments, they are called y1, y2, i3 etc, without the capital letters.

Edit 4: heatFTCS function is also wrong, the curly braces is in the wrong place, the function ends before the "else" statement, which is obviously not what you want.
Remove the first curly bracy thingy above the else statement.

1
2
3
4
5
      return last_Rpl_before_ablation, last_Rpl_after_ablation
        }
        } // This one

    else{


Also it's a void function. You can't return anything like you do here - return last_Rpl_before_ablation, last_Rpl_after_ablation And on the subject of returning things, you can't return multiple things like youre doing here, not in this way.
Last edited on
Hi,

Just some style related things:

There is a sort of a rule that code shouldn't be wider than 80 char - so it fits on one screen.

If you have lots of arguments, or a long list of anything, you can format it like below to make it easier to read:

1
2
3
4
5
6
7
8
9
10
11
12
void runge_kutta_evl (
        unsigned int i3, 
        double dt, 
        std::vector<double>& t,   // comments here if needed
        std::vector<double>& y1, 
        std::vector<double>& y2, 
        std::vector<double>& y3, 
        std::vector<double>& y5, 
        std::vector<double>& r_range, 
        std::vector<double>& m_range, 
        std::vector<double>& rho_range)
  {}


When posting code, one can use [ code firstline=37] so that the line numbers are labelled correctly.

If referring to the size of a standard container, use std::size_t as the type.

You could re-factor the code by splitting up the function into smaller parts. At the moment each line is dependent on the previous line, you could make each of these a function of their own that returns a value to be used for the next function call. Then you won't have lots of arguments. You can still have the runge_kutta_evl function, just that it will call each of the other functions in turn. That way the functions comply with the "A function does one thing" rule.

With namespaces, one can use a namespace alias:

1
2
3
namespace mi = Maths::Interpolation;

mi::Linear A(N, x, y);


using can also be used as a typedef:

using /* Whatever */ = mi::Linear;


I noticed that you had T as a variable name (you fixed it later), I just wanted to mention that T is a convention for types in a template, so isn't a good choice for a variable name.

Anyway, Happy New Year & Good Luck with your coding :+)
I must thank the both of you for your kind help and advice.

Tarik, thank you especially for your help.
I have made the following corrections to my code based on your observations:
1. The double dt marco is now fixed.
2 Edit 3 is now corrected.
3. Edit 4 is corrected for the additional brace. How can one return multiple things from a function, however, in the simplest of ways?

But I am still confused by your commentary on the Linear_once function.
You say "Linear_Once is in the linear.h, and you haven't included it in cpp_iron_functions.h". If you look at my main function, however, I do include linear.h into my code:

1
2
3
//user-defined functions: //this starts at line 24
#include "linear.h"
#include "cpp_iron_functions.h" 


Must I also include linear.h in my cpp_iron_functions.h header file even though I call it seperately in as above? Still in connection with this, you say I forget to include #include <vector> . But I do include this in my main source code. So to where/what does your comment refer? Because it has only been one week since my start of learning C++, I do not understand your explanation of the Linear_once function. What is a constructor? Can you try to make your explanation of this more accessible if you have time? Your kind help is much appreciated.
If you want to return 2 things, you can use std::pair.

https://www.youtube.com/watch?v=xWTYXFfdirY

If you want to return 3 things There is a way but I havent used it.

You can look up what a constructor is on google, there are tons of videos about it on youtube too if you learn by watching.

It's very clear that you're not the one that has written this code. In the linear.h file, there is a comment saying //! Class Constructor

As for the include things. I was thinking, since you are using a vector and the linear function in your cpp_iron_functions.h, wouldnt that file need to know of the existance of linear.h? I mean, including it in main makes main.cpp know about it, but that doesnt make any other file know about it. You know what I mean?

Edit: But I could be wrong about my last point, since It is still possible to use linear.h functions even without including it, although I cannot explain why, hopefully someone else can.
Last edited on
Hi,

In terms of returning multiple things, you can make a std::tuple and return that, but it is probably easier to make some of the function parameters references, and alter those. Those variables (with their new values) will be available in the scope where the function was called from.

Hope that helps a bit :+)
Topic archived. No new replies allowed.