Working with tridimensional arrays

Pages: 123
I replace tabs with space in my editors, may want to think about that. There are pros & cons, but it will do the same thing in all editors with spaces. Tab sizes vary too much for me.
Last edited on
Salem C
If you mix and match, then at some point, something somewhere will reduce your nicely formatted code to dog food.


Yeah, I just realize how many times I mix tabs and spaces in order to look neat, but in a different editor doesn't look so good.

jonnin
I replace tabs with space in my editors, may want to think about that. There are pros & cons, but it will do the same thing in all editors with spaces. Tab sizes vary too much for me.


Mmmm, you might be right, however, I use a lot of tabs to keep track of the different levels of all the loops I use
Are you absolutely certain it doesn't go out of bounds in these lines?
1
2
3
4
5
6
7
			        frac=alpha*M[Z][X][Y]; 
				M[Z][X-1][Y]=M[Z][X-1][Y]+frac;
			 	M[Z][X+1][Y]=M[Z][X+1][Y]+frac;
			 	M[Z][X][Y-1]=M[Z][X][Y-1]+frac;
			 	M[Z][X][Y+1]=M[Z][X][Y+1]+frac;
			 	M[Z-1][X][Y]=M[Z-1][X][Y]+frac;
			 	M[Z+1][X][Y]=M[Z+1][X][Y]+frac;


Apropos of nothing, why is alpha=0.15 and not 1/6 ?
lastchance
Are you absolutely certain it doesn't go out of bounds in these lines?

Yes, I'm certain! 'cause I have reserved 300x300 and in the case of 150 it should be in the boundaries.

Apropos of nothing, why is alpha=0.15 and not 1/6 ?

Teoretically the ideal value should be 1/6, however, the idea is to try values between 0.1 to 0.18 in order to check the correlation between the coeficient b (of an equation I obtain after processing this data), in other words, it makes no sense to use 1/6 (0.16) since the energy doesn't propagate in the ideal form, besides, it depends on the age of the tectonic plate (This code is for artificial seismicity).
I hope that responds your question
Hi, asmatrix.
I really think you should split your code into functions.

I’ve tried to rewrite your code focusing on readability.
I followed keskiverto’s technique, which I think is the safest.

So far, I could only deal with the first part – the second is a real mystery for me.
I don’t get any error, not even in the debugger.

I hope it could be an example of what you could do to isolate your issue and make the code maintainable.

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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#include <chrono>
#include <fstream>
#include <iostream>
#include <random>
#include <vector>


struct Coord3d {
    int x {};
    int y {};
    int z {};

    Coord3d() = default;
    constexpr Coord3d(int x_arg, int y_arg, int z_arg);
};


constexpr Coord3d::Coord3d(int x_arg, int y_arg, int z_arg)
    : x { x_arg }
    , y { y_arg }
    , z { z_arg }
{
}


// ============================================================================
// For debugging:
void print3dArrOnFile(const double * const arr3d, const Coord3d& coord);
void insertCriticalElem(double *& arr3d,
                        const Coord3d& arr_coord,
                        double critical,
                        const Coord3d& crit_coord);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

inline void clearScreen();
const double* fillArrWithInitValues(double *& arr3d, const Coord3d& coord);
double getRndDouble(double min, double max);
const double* fillArrWithRndDouble(double *& arr3d, const Coord3d& coord);
const double* divideAllElemsBy100(double *& arr3d, const Coord3d& coord);
Coord3d findCriticalElem(const double * const arr3d,
                         double critical,
                         const Coord3d& coord);


int main()
{
    constexpr Coord3d coord(10, 300, 300);
    double * arr3d { new double[coord.x * coord.y * coord.z] };

    // ========================================================================
    //                               Step - 1 -
    // Give arr3d initial values:
    fillArrWithInitValues(arr3d, coord);
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    // print3dArrOnFile(arr3d, Side_x, Side_y, Side_z); // just debug
    // clearScreen();

    // ========================================================================
    //                               Step - 2 -
    // Discard the freshly given initial values in favor of random values:
    fillArrWithRndDouble(arr3d, coord);
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    // ========================================================================
    //                               Step - 3 -
    // Divide the freshly given random values by 100:
    divideAllElemsBy100(arr3d, coord);
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    // Debug: insert critical element:
    // insertCriticalElem(arr3d, coord, 7.0, Coord3d(5, 150, 150));

    // ========================================================================
    //                               Step - 3 -
    // Verify if any element is beyond value 6:
    constexpr double vcrit { 6.0 };
    Coord3d found { findCriticalElem(arr3d, vcrit, coord) };
    if (found.x != -1) {
        std::cout << "Critical element found at position ("
                  << found.x << ", "
                  << found.y << ", "
                  << found.z << "). Value: "
                  << arr3d[  found.z * coord.x * coord.y
                           + found.y * coord.x
                           + found.x]
                  << '\n';
    }
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}


void print3dArrOnFile(const double * const arr3d, const Coord3d& coord)
{
    // Debugging!
    // TODO: delete when finished:
    std::ofstream fout("mydebug.txt");
    if (!fout) {
        std::cerr << "Cannot open 'mydebug.txt' fro writing.\nExiting now.\n";
        return;
    }

    for (int z {}; z < coord.z; ++z) {
        for (int y {}; y < coord.y; ++y) {
            fout << "- - -\n";
            for (int x {}; x < coord.x; ++x) {
                fout << arr3d[  z * coord.x * coord.y
                              + y * coord.x
                              + x]
                     << ' ';
            }
            fout << '\n';
        }
        fout << '\n';
    }
    fout << '\n';
}


void insertCriticalElem(double *& arr3d,
                        const Coord3d& arr_coord,
                        double critical,
                        const Coord3d& crit_coord)
{
    arr3d[  crit_coord.z * arr_coord.x * arr_coord.y
          + crit_coord.y * arr_coord.x
          + crit_coord.x]
        = critical;
}


void clearScreen()
{
    for (int i{}; i < 50; ++i) { std::cout << '\n'; }
}


const double* fillArrWithInitValues(double *& arr3d, const Coord3d& coord)
{
    for (int z {}; z < coord.z; ++z) {
        for (int y {}; y < coord.y; ++y) {
            for (int x {}; x < coord.x; ++x) {
                arr3d[  z * coord.x * coord.y
                      + y * coord.x
                      + x]
                    = 0.1 * x + 0.1 * y + 0.01 * z;
            }
        }
    }
    return arr3d;
}


double getRndDouble(double min, double max)
{
    static std::mt19937 eng {
        static_cast<unsigned>(
            std::chrono::high_resolution_clock::now().time_since_epoch().count()
        )
    };

    std::uniform_real_distribution<> dst(min, max);
    return dst(eng);
}


const double* fillArrWithRndDouble(double *& arr3d, const Coord3d& coord)
{
    for (int z {}; z < coord.z; ++z) {
        for (int y {}; y < coord.y; ++y) {
            for (int x {}; x < coord.x; ++x) {
                arr3d[  z * coord.x * coord.y
                      + y * coord.x
                      + x]
                    = getRndDouble(0.0, 5.99);
            }
        }
    }
    return arr3d;
}


const double* divideAllElemsBy100(double *& arr3d, const Coord3d& coord)
{
    for (int z {}; z < coord.z; ++z) {
        for (int y {}; y < coord.y; ++y) {
            for (int x {}; x < coord.x; ++x) {
                arr3d[  z * coord.x * coord.y
                      + y * coord.x
                      + x]
                    /= 100;
            }
        }
    }
    return arr3d;
}


Coord3d findCriticalElem(const double * const arr3d,
                         double critical,
                         const Coord3d& coord)
{
    Coord3d found(-1, -1, -1);
    for (int z {}; z < coord.z; ++z) {
        for (int y {}; y < coord.y; ++y) {
            for (int x {}; x < coord.x; ++x) {
                // For readability:
                int index { z * coord.x * coord.y + y * coord.x + x };
                if ( arr3d[index] >= critical ) {
                    found.x = x;
                    found.y = y;
                    found.z = z;
                    return found;
                }
            }
        }
    }
    return found;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
	flag=0;
		cont=0;
		for(i=1;i<f;i++)
			for(j=1;j<f;j++)
				for(k=1;k<z;k++)
					if(M[k][i][j]>=vcrit)
						{cont++;
						Cx[cont]=i;
						Cy[cont]=j;	
						Cz[cont]=k;
						flag=1;
						if(cont>cmax)cmax=cont;
						}


In the worst case, cont can reach 4*100*100 = 40,000, but there is space for just 100 items in Cx, Cy and Cz.
Last edited on
Also, what hardware are you running this on? Does you actually have enough space for these arrays??
@asmatrix,

@dhayden is right. It will - on occasion (because you are using rand()) - overflow the specified size of Cx[], Cy[] and Cz[].

Change f to 150. Then modify that part (your lines 101 to 108) to
1
2
3
4
5
6
7
8
9
10
11
12
13
                                        if(M[k][i][j]>=vcrit)
                                                {cont++;
                                                 if ( cont == 100 )
                                                 {
                                                     cout << "HELP!!";
                                                     string dummy;    getline( cin, dummy );
                                                 }
                                                Cx[cont]=i;                     //El arreglo Cx[] y Cy[] son unicamente para almacenar coordenadas locales, 
                                                Cy[cont]=j;                     //se sobreescriben en cada vuelta
                                                Cz[cont]=k;                     //Cuenta cuantos 6's se generaron y guarda las coordenadas de este evento
                                                flag=1;                         //Bandera que avisa que hubo un desborde
                                                if(cont>cmax)cmax=cont;
                                                }



It doesn't always crash (because you have random input). However, you can see from the value of cmax reported at the end that you are very close to 100 (often in the 90's).

The bigger the size of the array, the more likely this is to happen.

You could make Cx, Cy and Cz into vectors and use push_back() to increase the size safely.
Last edited on
It’s clear that Enoizat is on the right track.

This unending string of tangled spaghetti code from OP should be rewritten by somebody who knows how to write code. I hope nothing of importance is being worked on using it, because its an un-manageable un-controlled and un-verifiable pile of rubbish.

I wouldn’t be surprised if the hardware is a Trash80 or Commodore 64 or even an original Bombe
This unending string of tangled spaghetti code from OP should be rewritten by somebody who knows how to write code. I hope nothing of importance is being worked on using it, because its an un-manageable un-controlled and un-verifiable pile of rubbish.
Keep in mind that this is the beginners forum. Beautiful code is the exception here. In this case, it isn't tangled, it's straight line, simple numeric computation. It even has comments! It isn't unmanageable: the different parts appear pretty clear, especially if you format it better. Uncontrolled? I don't know what that means here. Unverifiable? I don't see why it would be unverifiable. Pile of rubbish? Nah. Maybe it could use some functions but to my taste, the comments are far more important.
The first problem is OP is not a beginner. This code is the result of years of never. even trying to be a beginner. Like the hospital risk software we saw recently this type of quackery, and that’s what it is, should be called out for what it is.

It’s not too much of a stretch to see this sort of pollution getting into the next generation of an airplane control system you or I might be flying on.

Genuine students and beginners are the exception here and they are to be encouraged and helped.

Its sad that you, who claim to be a professional, want to argue with me about basic principles of software engineering and quality. I was mistaken about that. By all means perpetuate the carbohydrate monstrosity.
@againtry If you want to troll successfully, you'll need to be a little less obvious. Subtlety is the name of the game, and you apparently haven't got there yet.
Last edited on
@mbozzi Since when do you and your 2394 pile of unproductive naive rubbish give you any say in what my contributions are? Your attempt at censoring me from stating the obvious about OP's 'program's just the work of a snowflake with no intellect.

What's next from you - you're outraged, or will you stamp your club foot?

Let's see you write 5 lines of clear C++ code that works. You haven't done it yet in all the time you've ponced around here.

"All tip and no iceberg" fits you to a tee.
Looks like you didn't get the message, LOL. Maybe it will sink in the next time.

Enjoy having the last word.
Last edited on
There aren't any second prizes, malakia. Spend your time on writing workable code.
Enoizat
I really think you should split your code into functions.


I agree, I will try to re write my code using functions!

In a following post I will explain the entire code.

dhayden
In the worst case, cont can reach 4*100*100 = 40,000, but there is space for just 100 items in Cx, Cy and Cz.


I used to have 1000 items for Cx, Cy and Cz, however I will make it bigger, just to discard all the options.

Also, what hardware are you running this on? Does you actually have enough space for these arrays??


I work on a PC with a Core i7-4770@3.4 Ghz and 8Gb RAM and 128 GB SSD and 1 TB HDD.

The size of the output file is aprox 19Mb for 1 million iterations; 200 MB for 10 Million and 1.89 Gb for 100 Million iterations.

lastchance
Change f to 150. Then modify that part (your lines 101 to 108) to

Ok, I"ll try it and Ilet you know

You could make Cx, Cy and Cz into vectors and use push_back() to increase the size safely.

Well I need to learn to use vectors.

againtry
You are absolutely right, I'm not even a begginer, all I know I have learnt it by myself.

And this is the only and last time I will waste my time responding to you, if it really hurts you so bad reading my code here, a piece of advice: DON'T READ IT!!.
Just keep looking for beautiful lines of code that satisfy your enormous ego and let the people that are actually helping alone.


for the rest of you guys, thank you one more time.
You're beautiful when you're angry.

Better you get the honest truth from me and go on a freebie course instead of telling everybody else what to do getting drip fed. Believe me most of these people here won't help.

Stamp your foot and shout as much as you like. Your bruised ego is the problem.

You're not working on a PC ... you're just wasting electricity.

Try a spell checker too.
I must say I missed tha main point of keskiverto’s method: when you need to apply something to all array elements, regardless their position, since they lay in successive memory cells, you can use a single big loop.

In a following post I will explain the entire code.

Yes, please! :-)
And please consider taking advantage of standard library facilities.
You should also avoid declaring your variables in big bunches here and there. Do declare only the variables you need and only when you really need them (usually, when you have got a good value to initialize them by).

Here’s an example of how a std::valarray can help saving a lot of time and keeping things clear:
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#include <chrono>
#include <fstream>
#include <iostream>
#include <random>
#include <valarray>


struct Coord3d {
    int x {};
    int y {};
    int z {};

    Coord3d() = default;
    constexpr Coord3d(int x_arg, int y_arg, int z_arg);

    /*explicit*/ operator int() const;

    int getIndex(int x_arg, int y_arg, int z_arg) const;
    int getIndex(const Coord3d& rhs) const;
};


// TODO: check if negative values
constexpr Coord3d::Coord3d(int x_arg, int y_arg, int z_arg)
    : x { x_arg }
    , y { y_arg }
    , z { z_arg }
{
}


int Coord3d::getIndex(int x_arg, int y_arg, int z_arg) const
{
    return z_arg * x * y + y_arg * x + x_arg;
}


int Coord3d::getIndex(const Coord3d& rhs) const
{
    return getIndex(rhs.x, rhs.y, rhs.z);
}


Coord3d::operator int() const
{
    return x * y * z;
}


// ============================================================================
// For debugging:
void print3dArrOnFile(const std::valarray<double>& arr3d, const Coord3d& coord);
void insertCriticalElem( std::valarray<double>& arr3d,
                         const Coord3d& arr_coord,
                         double critical,
                         const Coord3d& crit_coord );
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

inline void clearScreen();
void fillArrWithInitValues( std::valarray<double>& arr3d,
                            const Coord3d& coord );
double getRndDouble(double min, double max);
void fillArrWithRndDouble(std::valarray<double>& arr3d);
void divideAllElemsBy100(std::valarray<double>& arr3d);
Coord3d findCriticalElem( const std::valarray<double>& arr3d,
                          double critical,
                          const Coord3d& coord );


int main()
{
    constexpr Coord3d coord(10, 300, 300);
    std::valarray<double> arr3d( coord );

    // ========================================================================
    //                               Step - 1 -
    // Give arr3d initial values:
    fillArrWithInitValues(arr3d, coord);
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    // print3dArrOnFile(arr3d, Side_x, Side_y, Side_z); // just debug
    // clearScreen();

    // ========================================================================
    //                               Step - 2 -
    // Discard the freshly given initial values in favor of random values:
    fillArrWithRndDouble(arr3d);
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    // ========================================================================
    //                               Step - 3 -
    // Divide the freshly given random values by 100:
    divideAllElemsBy100(arr3d);
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    // Debug: insert critical element on purpose:
    // REMOVE WHEN DEBUGGED!!
    insertCriticalElem(arr3d, coord, 7.0, Coord3d(5, 150, 150));

    // ========================================================================
    //                               Step - 3 -
    // Verify if any element is beyond value 6:
    constexpr double vcrit { 6.0 };
    Coord3d found { findCriticalElem(arr3d, vcrit, coord) };
    if (found.x != -1) {
        std::cout << "Critical element found at position ("
                  << found.x << ", "
                  << found.y << ", "
                  << found.z << "). Value: "
                  << arr3d[  found.z * coord.x * coord.y
                           + found.y * coord.x
                           + found.x]
                  << '\n';
    }
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    // do {} while (ite < itMax); is hard to read
    constexpr int Max_Iterations { 100 };
    for(int loop {}; loop < Max_Iterations; ++loop) {
        // ...
    }
}


void print3dArrOnFile(const std::valarray<double>& arr3d, const Coord3d& coord)
{
    std::ofstream fout("mydebug.txt");
    if (!fout) {
        std::cerr << "Cannot open 'mydebug.txt' fro writing.\nExiting now.\n";
        return;
    }

    for (int z {}; z < coord.z; ++z) {
        for (int y {}; y < coord.y; ++y) {
            fout << "- - -\n";
            for (int x {}; x < coord.x; ++x) {
                fout << arr3d[coord.getIndex(x, y, z)] << ' ';
            }
            fout << '\n';
        }
        fout << '\n';
    }
    fout << '\n';
}


void insertCriticalElem( std::valarray<double>& arr3d,
                         const Coord3d& arr_coord,
                         double critical,
                         const Coord3d& crit_coord )
{
    arr3d[arr_coord.getIndex(crit_coord)] = critical;
}


void clearScreen()
{
    for (int i{}; i < 50; ++i) { std::cout << '\n'; }
}


void fillArrWithInitValues( std::valarray<double>& arr3d,
                            const Coord3d& coord )
{
    for (int z {}; z < coord.z; ++z) {
        for (int y {}; y < coord.y; ++y) {
            for (int x {}; x < coord.x; ++x) {
                arr3d[coord.getIndex(x, y, z)] = 0.1 * x + 0.1 * y + 0.01 * z;
            }
        }
    }
}


double getRndDouble(double min, double max)
{
    static std::mt19937 eng {
        static_cast<unsigned>(
            std::chrono::high_resolution_clock::now().time_since_epoch().count()
        )
    };

    std::uniform_real_distribution<> dst(min, max);
    return dst(eng);
}


void fillArrWithRndDouble(std::valarray<double>& arr3d)
{
    arr3d.apply( [](double) {
        return getRndDouble(0.0, 5.99);
    } );
}


void divideAllElemsBy100(std::valarray<double>& arr3d)
{
    arr3d /= 100;
}


Coord3d findCriticalElem( const std::valarray<double>& arr3d,
                          double critical,
                          const Coord3d& coord )
{
    Coord3d found(-1, -1, -1);
    for (int z {}; z < coord.z; ++z) {
        for (int y {}; y < coord.y; ++y) {
            for (int x {}; x < coord.x; ++x) {
                // For readability:
                int index { coord.getIndex(x, y, z) };
                if ( arr3d[index] >= critical ) {
                    found.x = x;
                    found.y = y;
                    found.z = z;
                    return found;
                }
            }
        }
    }
    return found;
}

againtry wrote:
Better you get the honest truth from me and go on a freebie course instead of telling everybody else what to do getting drip fed. Believe me most of these people here won't help.

Stamp your foot and shout as much as you like. Your bruised ego is the problem.


We get it. You're a hard man, saying the difficult things for our own good.

We're all so impressed with your machismo. No, really, we are.

:rolleyes:
Last edited on
There he is the pommy wanker whose only contribution ever, like a few others here, never touches on workable code or giving genuine help.

He's a 'disciplinarian' - and we all know what poms of that psycho-profile do for kicks.

You would be impressed by me little one, anyone with authority. Bad luck though, I'd just call the cops if I met you in the street.
Pages: 123