runge-kutta 4 problem

I am trying to get a runge-kutta program to work, but I keep getting the following error message: error: cannot convert `double' to `double (*)[1]' for argument `2' to `double function(double, double (*)[1])'. I have a feeling it's a pointer problem. I am kind of new to C/C++ coding and I have only a little knowledge about pointers. Can someone help me point out my problems please? Thanks.

Here is my code:

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <cmath>

double function(double t, double u[2][1])
{
	double dudt[2][1];
	dudt[0][0] = 3 * u[0][0] + 2 * u[1][0] - (2 * pow(t,2) + 1) * exp(2 * t);
	dudt[1][0] = 4 * u[0][0] + u[1][0] + (pow(t,2) + 2 * t - 4) * exp(2 * t);
	return dudt[2][1];
}

int main()
{
	using namespace std;
	double function(double t, double u[2][1]);
	
	double h, t0, u1_0, u2_0;
	int nos, i, j;
	
	h = 0.1;
	nos = 10;
	t0 = 0.0;
	u1_0 = 1.0;
	u2_0 = 1.0;
	
	double t[nos + 1];
	double u[2][nos + 1];
	
	t[0] = t0;
	u[0][0] = u1_0;
	u[1][0] = u2_0;
	
	for(i = 0; i < nos; i++)
	{
		t[i + 1] = t[i] + h;
		
		double u_n[2][1];
		u_n[0][0] = u[0][i];
		u_n[1][0] = u[1][i];
		
		double k1[2], k2[2], k3[2], k4[2];
		double u_npl[2][1];
		
		for(j = 0; j < 2; j++)
		{
			k1[j] = h * function(t[i],u_n[j][0]);
			k2[j] = h * function(t[i] + 0.5 * h, u_n[j][0] + 0.5 * k1[j]);
			k3[j] = h * function(t[i] + 0.5 * h, u_n[j][0] + 0.5 * k2[j]);
			k4[j] = h * function(t[i] + h, u_n[j][0] + k3[j]);
			
			u_npl[j][0] = u_n[j][0] + ((k1[j] + 2 * k2[j] + 2 * k3[j] + k4[j]) / 6);
		}
		
		u[0][i + 1] = u_npl[0][0];
		u[1][i + 1] = u_npl[1][0];
		
		cout << "u[0][" << i + 1 << "] is: " << u[0][i + 1] << endl;
		cout << "u[1][" << i + 1 << "] is: " << u[1][i + 1] << endl;
	}
	
	return 0;
}
1
2
	double t[nos + 1];
	double u[2][nos + 1];

This is illegal. nos+1 isn't a compile time constant.


In:
function(t[i], u_n[j][0]);

u_n[j][0] is of type double, not double[][1].

It is not an array. It is a single double... just like the error message says.

function(t[i], u_n) would be a correct way to call the function.

In:
1
2
3
4
	double dudt[2][1];
	dudt[0][0] = 3 * u[0][0] + 2 * u[1][0] - (2 * pow(t,2) + 1) * exp(2 * t);
	dudt[1][0] = 4 * u[0][0] + u[1][0] + (pow(t,2) + 2 * t - 4) * exp(2 * t);
	return dudt[2][1];


dud[2][1] is out of the bounds of the array. And you are not, as I suspect you meant to do, returning an array. You are returning a single double value as the function prototype specifies you will.
How do I state that I am returning an array from my function?
You can't easily return an array, in the sense of returning a copy of the array as if it was an object. You can return a pointer to the first item in the array, but (a) you need to be sure the memory is still valid (which it won't be if you're returning a pointer to a local variable on the stack) and (b) the calling code won't know the size of the array.

Why are you using C-style arrays anyway? You're much better off using std::vector.
Last edited on
I didn't think about vectors
OK, so I looked into vectors and now wondering: how do I use a vector to return the values within the multidimensional array? I know that the code:

 
k1[j] = h * function(t[i],u_n);		


is suppose to put dudt[0][0] into k1[0] and dudt[1][0] is suppose to go into k1[1]. I just don't know how to do that correctly.
Ok, so I changed my code around to look like this:

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <iostream>
#include <cmath>

double dudt[2];

void function(double t, double u[])
{
	double dudt[2];
	dudt[0] = 3 * u[0] + 2 * u[1] - (2 * pow(t,2) + 1) * exp(2 * t);
	dudt[1] = 4 * u[0] + u[1] + (pow(t,2) + 2 * t - 4) * exp(2 * t);
}

int main()
{
	using namespace std;
	double function(double t, double u[]);
	
	double h, t0, u1_0, u2_0;
	int i, j;
	const int nos = 10;
	
	h = 0.1;
	// nos = 10;
	t0 = 0.0;
	u1_0 = 1.0;
	u2_0 = 1.0;
	
	double t[nos + 1];
	double u[2];
	
	t[0] = t0;
	u[0] = u1_0;
	u[1] = u2_0;
		
	double u_n[2];
	u_n[0] = u[0];
	u_n[1] = u[1];
		
	for(i = 0; i < nos; i++)
	{
		t[i + 1] = t[i] + h;

		
		double k1[2], k2[2], k3[2], k4[2];
		double u_npl[2];
		
		function(t[i],u_n);
		for(j = 0; j < 2; j++)
		{
			cout << "dudt = " << dudt[j] << endl;
			k1[j] = h * dudt[j];
			cout << "k1 = " << k1[j] << endl;
		}
		
		function(t[i] + 0.5 * h, u_n + 0.5 * k1);
		for(j = 0; j < 2; j++)
		{
			k2[j] = h * dudt[j];
		}
		
		function(t[i] + 0.5 * h, u_n + 0.5 * k2);
		for(j = 0; j < 2; j++)
		{
			k3[j] = h * dudt[j];
		}
		
		function(t[i] + h, u_n + k3);
		for(j = 0; j < 2; j++)
		{
			k4[j] = h * dudt[j];
		}
			
		for(j = 0; j < 2; j++)
		{
			u_npl[j] = u_n[j] + ((k1[j] + 2 * k2[j] + 2 * k3[j] + k4[j]) / 6);
			cout << k1[j] << endl;
		}
		
		u[0] = u_npl[0];
		u[1] = u_npl[1];
		
		cout << "u[" << 0 << "] is: " << u[0] << endl;
		cout << "u[" << 1 << "] is: " << u[1] << endl;
	}
	
	return 0;
}


and I get the following errors:


runge-kutta_practice.cc: In function `int main()':
runge-kutta_practice.cc:55: error: invalid operands of types `double' and `double[2]' to binary `operator*'
runge-kutta_practice.cc:61: error: invalid operands of types `double' and `double[2]' to binary `operator*'
runge-kutta_practice.cc:67: error: invalid operands of types `double[2]' and `double[2]' to binary `operator+'



Any advice on how to fix these errors?
The compiler message give you a good hint as to what's going on, and where.

For example, in line 55, you are trying to multiply a double, 0.5, by a pointer, k1. You can't do this because there is no operator * that takes a double and a pointer.

Did you actually intend to multiply it by one of the members of the k1 array?

The same thing is happening in line 61, only with k2. Similarly, at line 67 you are trying to add two pointers, but there is no operator + defined that will do this.
ok, I got my program to work. I will be posting the final code on here soon
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <iostream>
#include <cmath>

double dudt[2];

void function(double t, double u[2])
{
	// double dudt[2];
	dudt[0] = 3 * u[0] + 2 * u[1] - (2 * pow(t,2) + 1) * exp(2 * t);
	dudt[1] = 4 * u[0] + u[1] + (pow(t,2) + 2 * t - 4) * exp(2 * t);

}

int main()
{
	using namespace std;
	double function(double t, double u[2]);
	
	double h, t0, u1_0, u2_0;
	int i, j;
	const int nos = 10;
	
	h = 0.1;
	// nos = 10;
	t0 = 0.0;
	u1_0 = 0.0; 
	u2_0 = 0.0; 
	
	double t[nos + 1];
	double u[2];
	
	t[0] = t0;
	u[0] = u1_0;
	u[1] = u2_0;
		
	double u_n[2];
	// u_n[0] = u[0];
	// u_n[1] = u[1];
		
	for(i = 0; i < nos; i++)
	{
		t[i + 1] = t[i] + h;
		
		u_n[0] = u[0];
		u_n[1] = u[1];
		
		double half_k1[2];
		double added[2];

		
		double k1[2], k2[2], k3[2], k4[2];
		double u_npl[2];
		
		function(t[i],u_n);
		for(j = 0; j < 2; j++)
		{
			//cout << "dudt = " << dudt[j] << endl;
			k1[j] = h * dudt[j];
			half_k1[j] = 0.5*k1[j];
			added[j] = u_n[j] + half_k1[j];
			//cout << "k1 = " << k1[j] << endl;
		}
		
		function(t[i] + 0.5 * h, added);
		for(j = 0; j < 2; j++)
		{
			k2[j] = h * dudt[j];
			added[j] = u_n[j] + (0.5 * k2[j]);
		}
		
		function(t[i] + 0.5 * h, added);
		for(j = 0; j < 2; j++)
		{
			k3[j] = h * dudt[j];
			added[j] = u_n[j] + k3[j];
		}
		
		function(t[i] + h, added);
		for(j = 0; j < 2; j++)
		{
			k4[j] = h * dudt[j];
		}
			
		for(j = 0; j < 2; j++)
		{
			u_npl[j] = u_n[j] + ((k1[j] + 2 * k2[j] + 2 * k3[j] + k4[j]) / 6.0);
			//cout << k1[j] << endl;
		}
		
		u[0] = u_npl[0];
		u[1] = u_npl[1];
		
		cout << "u[" << 0 << "] is: " << u[0] << endl;
		cout << "u[" << 1 << "] is: " << u[1] << endl << endl;
	}
	
	return 0;
}
Last edited on
1
2
3
4
5
6
7
8
9
10
double dudt[2];

void function(double t, double u[2])
{
	// double dudt[2];
	dudt[0] = u[1];/*3 * u[0] + 2 * u[1] - (2 * pow(t,2) + 1) * exp(2 * t);*/ dx/dt = vx
	dudt[1] = -9.8;/*4 * u[0] + u[1] + (pow(t,2) + 2 * t - 4) * exp(2 * t);*/ dy/dt = vy
	dudt[2]  = blah dvx/dt = 0
	dudt[3] = blah dvy/dt = -g
}


Valid indices for dudt are 0 and 1.
can you explain this to me?

s C++\cplusplus2\main.cpp||In function 'void function(double, double*)':|
s C++\cplusplus2\main.cpp|9|error: 'dx' was not declared in this scope|
s C++\cplusplus2\main.cpp|9|error: 'dt' was not declared in this scope|
s C++\cplusplus2\main.cpp|9|error: 'vx' was not declared in this scope|
s C++\cplusplus2\main.cpp|10|error: expected ';' before 'dudt'|
s C++\cplusplus2\main.cpp|10|error: 'dy' was not declared in this scope|
s C++\cplusplus2\main.cpp|10|error: 'vy' was not declared in this scope|
s C++\cplusplus2\main.cpp|11|error: expected ';' before 'dudt'|
s C++\cplusplus2\main.cpp|14|error: expected declaration before '}' token|
||=== Build finished: 8 errors, 0 warnings (0 minutes, 0 seconds) ===|
oh sorry, I was for my next runge-kutta problem, I'll edit that out sorry
There, now try it that way and it should work. =D
Topic archived. No new replies allowed.