Passing Array Into Function

I'm trying to pass an array into a function file in order to solve a simple tridiagonal matrix. I keep getting an error that says 'Error: Incompatible types in assignment of 'double' to 'double [15]''. I'm not sure what is causing this. I double checked tutorials on how to pass an array into a function, and it seems like they're doing it very similar to how I am. Any help is much appreciated!

- Ali

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
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <fstream>
#include <cmath>

using namespace std;


const int N = 15;
double a = 0;
double b = 3;
double dX = (b - a)/(N - 1);
double x [N];
double Fp [N];

double func(double x)
{
    return cos(4*x);
}

double pade(double x[], double dX, int N)
{
    double a [N];
    double b [N];
    double c [N];
    double d [N];

    a[0] = 0;
    b[0] = 1;
    c[0] = 2;
    d[0] = (1/dX)*(-2.5*func(x[0]) + 2*func(x[1]) + 0.5*func(x[2]));
    for (int i = 0; i < N - 1; i++)
    {
        a[i] = 1;
        b[i] = 4;
        c[i] = 1;
        d[i] = (3/dX)*(func(x[i+1]) - func(x[i-1]));
    }
    a[N-1] = 2;
    b[N-1] = 1;
    c[N-1] = 0;
    d[N-1] = (1/dX)*(2.5*func(x[N-1]) - 2*func(x[N-2]) - 0.5*func(x[N-3]));

    for (int i = 1; i < N; i++)
    {
        b[i] = b[i] - c[i-1]*a[i]/b[i-1];
        d[i] = d[i] - d[i-1]*a[i]/b[i-1];
    }

    d[N-1] = d[N-1]/b[N-1];
    for (int i = N-2; i >= 0; i--)
    {
        d[i] = (1/b[i])*(d[i] - c[i]*d[i+1]);
    }

    return d;
}

int main ()
{
    //Compute X-vector from a to b with N points
    x[0] = a;
    for (int i = 1; i < N; i++)
    {
        x[i] = x[i-1] + dX;
    }

    Fp = pade(x, dX, N);

    //Output data into text file
    ofstream outputdata("output.txt");
    for (int j = 0; j<N; j++)
    {
        outputdata << x[j] << "    " << Fp[j] << endl;
    }
    outputdata.close();

    return 0;
}
The function pade claims to return a double, but you're trying to return d, which is not a double.
But aren't I declaring d to be a double on line 27?
d is an array of double
But aren't I declaring d to be a double on line 27?


To reiterate Peter87; no, you are not declaring d to be a double on line 27.
d is an array of double
To reiterate Peter87; no, you are not declaring d to be a double on line 27.


Well, my goal is to return an array from the function. Essentially I want to output 'd' with N elements. Is there something different I have to do in C++ in order to output an array?
I just read something online about outputting arrays from functions in C++. They mentioned something about the fact that since 'd' is a local variable, it more than likely that it will get deleted by the time the function is over. I'm fairly new to C++, so I'm not sure exactly how to address this. Any suggestions?

Any suggestions?


If you want an object to exist beyond the scope of its creation, make it using new. Don't forget to delete it at some point. Alternatively, create it at the higher scope, and pass it around.

Well, my goal is to return an array from the function. Essentially I want to output 'd' with N elements. Is there something different I have to do in C++ in order to output an array?



The better answer is stop using arrays and use a proper C++ container like a vector.

If you don't want to do that, you can make this much easier on yourself by passing pointers instead of thrashing around with arrays.


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
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <fstream>
#include <cmath>

using namespace std;


const int N = 15;
double a = 0;
double b = 3;
double dX = (b - a)/(N - 1);
double x [N];
double* Fp;

double func(double x)
{
    return cos(4*x);
}

double* pade(double x[], double dX, int N)
{
    double a [N];
    double b [N];
    double c [N];
    double* d = new double[N];

    a[0] = 0;
    b[0] = 1;
    c[0] = 2;
    d[0] = (1/dX)*(-2.5*func(x[0]) + 2*func(x[1]) + 0.5*func(x[2]));
    for (int i = 0; i < N - 1; i++)
    {
        a[i] = 1;
        b[i] = 4;
        c[i] = 1;
        d[i] = (3/dX)*(func(x[i+1]) - func(x[i-1]));
    }
    a[N-1] = 2;
    b[N-1] = 1;
    c[N-1] = 0;
    d[N-1] = (1/dX)*(2.5*func(x[N-1]) - 2*func(x[N-2]) - 0.5*func(x[N-3]));

    for (int i = 1; i < N; i++)
    {
        b[i] = b[i] - c[i-1]*a[i]/b[i-1];
        d[i] = d[i] - d[i-1]*a[i]/b[i-1];
    }

    d[N-1] = d[N-1]/b[N-1];
    for (int i = N-2; i >= 0; i--)
    {
        d[i] = (1/b[i])*(d[i] - c[i]*d[i+1]);
    }

    return d;
}

int main ()
{
    //Compute X-vector from a to b with N points
    x[0] = a;
    for (int i = 1; i < N; i++)
    {
        x[i] = x[i-1] + dX;
    }

    Fp = pade(x, dX, N);

    //Output data into text file
    ofstream outputdata("output.txt");
    for (int j = 0; j<N; j++)
    {
        outputdata << x[j] << "    " << Fp[j] << endl;
    }
    outputdata.close();

    delete[] Fp;
    return 0;
}

Last edited on
I made the changes you recommended, but I get the same exact error. Could it perhaps be the fact that in the pade function I'm calling on the 'func' function? Do I need to change the 'func' function as well? I don't see why I would though because I'm not passing an array into it.
When I compile the code I posted, there is no error.

Do I need to change the 'func' function as well?

No.
I see what my error was. It's working now. Thanks!

In general, is it better to use arrays or vectors? I've read a lot about their comparison, and it seems like it has mixed reviews.
Vectors are easier to use, look after their own size, come with a large number of useful class functions and can have many other functions applied to them (for example, see the <algorithms> header).

Arrays are faster. When you need the speed, you'll know. Otherwise, use a vector (or other such C++ container)
Last edited on
Awesome. Thank you for your help! I've started to read both about vectors and points in order to understand them better. Switching to C++ from MATLAB has brought me to a whole new world of coding, haha.
AliMoradi wrote:
In general, is it better to use arrays or vectors?

Vectors are the default containers in C++*. Always begin with vectors, then specialize if needed.

[*] C++ Coding Standards by Herb Sutter and Andrei Alexandrescu, chapter 76

Moschops wrote:
Arrays are faster. When you need the speed, you'll know. Otherwise, use a vector

No, there is no difference (except where on purpose, such as in Debug Mode of VC++)
Last edited on
No, there is no difference


I disagree. Here is some code that I used to test:


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
#include <sys/time.h>
#include <vector>
#include <iostream>
#include <algorithm>
#include <numeric>


int main()
{
  static size_t const size = 7e6;

  timeval start, end;
  int sum;

  gettimeofday(&start, 0);
  {
    std::vector<int> v(size, 1);
    sum = std::accumulate(v.begin(), v.end(), 0);
  }
  gettimeofday(&end, 0);

  std::cout << "= vector =" << std::endl
        << "(" << end.tv_sec - start.tv_sec
        << " s, " << end.tv_usec - start.tv_usec
        << " us)" << std::endl
        << "sum = " << sum << std::endl << std::endl;

  gettimeofday(&start, 0);
  int * const arr =  new int[size];
  std::fill(arr, arr + size, 1);
  sum = std::accumulate(arr, arr + size, 0);
  delete [] arr;
  gettimeofday(&end, 0);

  std::cout << "= Simple array =" << std::endl
        << "(" << end.tv_sec - start.tv_sec
        << " s, " << end.tv_usec - start.tv_usec
        << " us)" << std::endl
        << "sum = " << sum << std::endl << std::endl;
}



Here are some results, using two different compilers:

j@j-desktop:~/badCode$ g++ -O2 063.cpp 
j@j-desktop:~/badCode$ ./a.out 
= vector =
(0 s, 34996 us)
sum = 7000000

= Simple array =
(0 s, 26245 us)
sum = 7000000

j@j-desktop:~/badCode$ clang++ -O2 063.cpp
j@j-desktop:~/badCode$ ./a.out 
= vector =
(0 s, 37609 us)
sum = 7000000

= Simple array =
(0 s, 29038 us)
sum = 7000000



Obviously it'll be difficult to generate code in which the sole difference is vector/array, so this is by no means definitive. Without the optimisations, the results are considerably further apart.
Last edited on
Here is some code that I used to test:


My first try, g++ 4.6.2 on 64 bit linux -O3 -march=native

 ~ $ ./test
= vector =
(0 s, 8036 us)
sum = 7000000

= Simple array =
(0 s, 10231 us)
sum = 7000000

 ~ $ ./test
= vector =
(0 s, 10338 us)
sum = 7000000

= Simple array =
(0 s, 9962 us)
sum = 7000000

 ~ $ ./test
= vector =
(0 s, 9428 us)
sum = 7000000

= Simple array =
(0 s, 15967 us)
sum = 7000000



But really, they are the same exact thing:

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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
gettimeofday(&start, 0);
  {
    std::vector<int> v(size, 1);
    sum = std::accumulate(v.begin(), v.end(), 0);
  }
  gettimeofday(&end, 0);

        call    gettimeofday
        movl    $28000000, %edi
        call    _Znwm
        movq    %rax, %r9
        movq    %rax, %rcx
        andl    $15, %r9d
        shrq    $2, %r9
        negq    %r9
        andl    $3, %r9d
        sete    %bl
        je      .L33
        movl    $7000000, %esi
        movl    $7000001, %r8d
        jmp     .L3
        .p2align 4,,10
        .p2align 3
.L34:
        movq    %rdx, %rsi
.L3:
        movl    $1, (%rcx)
        movq    %r8, %rdi
        addq    $4, %rcx
        leaq    -1(%rsi), %rdx
        subq    %rsi, %rdi
        cmpq    %rdi, %r9
        ja      .L34
.L2:
        movl    $7000000, %ebp
        subq    %r9, %rbp
        movq    %rbp, %r10
        shrq    $2, %r10
        leaq    0(,%r10,4), %r11
        testq   %r11, %r11
        sete    %dil
        je      .L7
        movdqa  .LC0(%rip), %xmm0
        leaq    (%rax,%r9,4), %r8
        xorl    %esi, %esi
        .p2align 4,,10
        .p2align 3
.L5:
        addq    $1, %rsi
        movdqa  %xmm0, (%r8)
        addq    $16, %r8
        cmpq    %r10, %rsi
        jb      .L5
        leaq    (%rcx,%r11,4), %rcx
        subq    %r11, %rdx
        cmpq    %r11, %rbp
        je      .L6
        .p2align 4,,10
        .p2align 3
.L7:
        movl    $1, (%rcx)
        addq    $4, %rcx
        subq    $1, %rdx
        jne     .L7
.L6:
        testb   %bl, %bl
        movq    %rax, %rcx
        jne     .L35
        movl    $7000000, %esi
        xorl    %ebx, %ebx
        movl    $7000001, %r8d
        jmp     .L9
        .p2align 4,,10
        .p2align 3
.L36:
        movq    %rdx, %rsi
.L9:
        addl    (%rcx), %ebx
        movq    %r8, %r12
        addq    $4, %rcx
        subq    %rsi, %r12
        leaq    -1(%rsi), %rdx
        cmpq    %r9, %r12
        jb      .L36
.L8:
        testb   %dil, %dil
        jne     .L14
        leaq    (%rax,%r9,4), %rdi
        xorl    %esi, %esi
        pxor    %xmm0, %xmm0
        .p2align 4,,10
        .p2align 3
.L12:
        addq    $1, %rsi
        paddd   (%rdi), %xmm0
        addq    $16, %rdi
        cmpq    %r10, %rsi
        jb      .L12
        leaq    (%rcx,%r11,4), %rcx
        movdqa  %xmm0, %xmm1
        subq    %r11, %rdx
        psrldq  $8, %xmm1
        paddd   %xmm1, %xmm0
        movdqa  %xmm0, %xmm1
        psrldq  $4, %xmm1
        paddd   %xmm1, %xmm0
        movd    %xmm0, %esi
        addl    %esi, %ebx
        cmpq    %r11, %rbp
        je      .L13
        .p2align 4,,10
        .p2align 3
.L14:
        addl    (%rcx), %ebx
        addq    $4, %rcx
        subq    $1, %rdx
        jne     .L14
.L13:
        testq   %rax, %rax
        je      .L19
        movq    %rax, %rdi
        call    _ZdlPv
.L19:
        leaq    16(%rsp), %rdi
        xorl    %esi, %esi
        call    gettimeofday
gettimeofday(&start, 0);
  int * const arr =  new int[size];
  std::fill(arr, arr + size, 1);
  sum = std::accumulate(arr, arr + size, 0);
  delete [] arr;
  gettimeofday(&end, 0);

        call    gettimeofday
        movl    $28000000, %edi
        call    _Znam
        movq    %rax, %r9
        movq    %rax, %rdx
        andl    $15, %r9d
        shrq    $2, %r9
        negq    %r9
        andl    $3, %r9d
        sete    %bl
        je      .L37
        movl    $7000000, %esi
        movl    $7000001, %edi
        jmp     .L21
        .p2align 4,,10
        .p2align 3
.L38:
        movq    %rcx, %rsi
.L21:
        movl    $1, (%rdx)
        movq    %rdi, %r8
        addq    $4, %rdx
        leaq    -1(%rsi), %rcx
        subq    %rsi, %r8
        cmpq    %r8, %r9
        ja      .L38
.L20:
        movl    $7000000, %r11d
        subq    %r9, %r11
        movq    %r11, %r10
        shrq    $2, %r10
        leaq    0(,%r10,4), %rdi
        testq   %rdi, %rdi
        sete    %bpl
        je      .L42
        movdqa  .LC0(%rip), %xmm0
        leaq    (%rax,%r9,4), %r8
        xorl    %esi, %esi
        .p2align 4,,10
        .p2align 3
.L23:
        addq    $1, %rsi
        movdqa  %xmm0, (%r8)
        addq    $16, %r8
        cmpq    %r10, %rsi
        jb      .L23
        leaq    (%rdx,%rdi,4), %rdx
        subq    %rdi, %rcx
        cmpq    %rdi, %r11
        je      .L24
        .p2align 4,,10
        .p2align 3
.L42:
        movl    $1, (%rdx)
        addq    $4, %rdx
        subq    $1, %rcx
        jne     .L42
.L24:
        testb   %bl, %bl
        movq    %rax, %rdx
        jne     .L39
        movl    $7000000, %esi
        xorl    %ebx, %ebx
        movl    $7000001, %r8d
        jmp     .L27
        .p2align 4,,10
        .p2align 3
.L40:
        movq    %rcx, %rsi
.L27:
        addl    (%rdx), %ebx
        movq    %r8, %r12
        addq    $4, %rdx
        subq    %rsi, %r12
        leaq    -1(%rsi), %rcx
        cmpq    %r9, %r12
        jb      .L40
.L26:
        testb   %bpl, %bpl
        jne     .L41
        leaq    (%rax,%r9,4), %r8
        xorl    %esi, %esi
        pxor    %xmm0, %xmm0
        .p2align 4,,10
        .p2align 3
.L29:
        addq    $1, %rsi
        paddd   (%r8), %xmm0
        addq    $16, %r8
        cmpq    %r10, %rsi
        jb      .L29
        leaq    (%rdx,%rdi,4), %rdx
        movdqa  %xmm0, %xmm1
        subq    %rdi, %rcx
        psrldq  $8, %xmm1
        paddd   %xmm1, %xmm0
        movdqa  %xmm0, %xmm1
        psrldq  $4, %xmm1
        paddd   %xmm1, %xmm0
        movd    %xmm0, %esi
        addl    %esi, %ebx
        cmpq    %rdi, %r11
        je      .L30
        .p2align 4,,10
        .p2align 3
.L41:
        addl    (%rdx), %ebx
        addq    $4, %rdx
        subq    $1, %rcx
        jne     .L41
.L30:
        testq   %rax, %rax
        je      .L32
        movq    %rax, %rdi
        call    _ZdaPv
.L32:
        leaq    16(%rsp), %rdi
        xorl    %esi, %esi
        call    gettimeofday
Last edited on
Topic archived. No new replies allowed.