By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,635 Members | 2,188 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,635 IT Pros & Developers. It's quick & easy.

running multiple codes

P: n/a
vj
Hi all,
I am using C++Builder-5. I want to run multiple cpp files at the same
time.

If I use the C++Builder for running a cpp file (i.e., I just double
click the cpp file, it then opens in the C++Builder, where I have the
option to 'Run' it), I can't run multiple files, since the Run option
is grayed out if one cpp file is already running.
I have another option of running the multiple files: from the command
prompt (i.e. opening a separate command prompt window for each file to
be run). This works in principle, however, I can't use this option,
since I am using large arrays in the code, and a 'StackOverflow' error
message is generated, so I have to run the cpp file from the C++
Builder where I can change the stack size limit of the Project
(Project>Options>Linker>MaxStackSize) and the code runs fine there. But
I can't run multiple codes or projects as mentioned in the beginning.
Is there a way out?

Thanks in advance.

Nov 25 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a

"vj" <ee***@nottingham.ac.uk> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com...
Hi all,
I am using C++Builder-5. I want to run multiple cpp files at the same
time.

If I use the C++Builder for running a cpp file (i.e., I just double
click the cpp file, it then opens in the C++Builder, where I have the


Off-topic. What you have is not really a C++ *language* issue. Please see:
http://www.parashift.com/c++-faq-lit...t.html#faq-5.9

Regards,
Sumit.
--
Sumit Rajan <su****@msdc.hcltech.com>
Nov 25 '05 #2

P: n/a
In message <11**********************@g44g2000cwa.googlegroups .com>, vj
<ee***@nottingham.ac.uk> writes
Hi all,
I am using C++Builder-5. I want to run multiple cpp files at the same
time.

If I use the C++Builder for running a cpp file (i.e., I just double
click the cpp file, it then opens in the C++Builder, where I have the
option to 'Run' it),
OK,. this is technically off-topic, but it's not really a question about
a particular development environment, more about a misunderstanding of
the program translation process, and (from the sound of it) some bad
program design:

You can't "run" a C++ source file. The compilation environment compiles
the C++ source into an object file and links that with the necessary
libraries to make an executable file. It then runs the executable file.
I can't run multiple files,
Why do you want to?
since the Run option
is grayed out if one cpp file is already running.
I have another option of running the multiple files: from the command
prompt (i.e. opening a separate command prompt window for each file to
be run). This works in principle, however, I can't use this option,
since I am using large arrays in the code,
Why? std::vector is a much more error-proof way of dealing with large
arrays, and isn't subject to the problems you appear to be experiencing.
If you post real code, people here may be able to suggest way to improve
it.
and a 'StackOverflow' error
message is generated, so I have to run the cpp file from the C++
Builder where I can change the stack size limit of the Project
(Project>Options>Linker>MaxStackSize) and the code runs fine there. But
I can't run multiple codes or projects as mentioned in the beginning.
Is there a way out?


--
Richard Herring
Nov 25 '05 #3

P: n/a
vj
Thankyou for the reply.
I can't run multiple files,
Why do you want to?
I wish to run multiple files at the same time, since the run times are
long, and I want to leave multiple files running overnight so as to get
multiple results in the morning.
Why? std::vector is a much more error-proof way of dealing with large
arrays, and isn't subject to the problems you appear to be experiencing.
If you post real code, people here may be able to suggest way to improve
it.


I am posting (a part of) real code below: you will see I am not a very
good programmer ( it is better to say that I am a rather novice/bad
programmer! ). The variables NX, NY and NT are the ones with large
values, and I get a message ~"stack overflow error" when running these
files, unless I change the project settings (as explained in my
original post). I have never used the std::vector option as suggested
by you. Any suggestions are welcome, and easy-to-understand or
step-by-step would be highly appreciated.
Thanks

Here is the code:

#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <stddef.h>
#include <complex.h>
#include <fstream>
#include <time.h>
#define PI 3.14159265
#define c 3.0
#define dX 50.0
#define dT (dX/c)

#define NX 10000
#define NY 200
//#define NT 20000
#define NM 4

class D2{
public:
int NT;

double **V4, **V5, **V2, **V3, **Vy, **Vx, **I;

double **Sey;
double **Sex;
double **pey, **pex, **X1y, **X1x, **X2y, **X2x;
double ALPHA[NM], d[NM], w0[NM];
double Tp0[NM], b0, b1[NM], b2[NM], b3[NM], Tp1[NM], Te2[NM],
Te1[NM];

double *h1, *h2, *h3, *h4;
int X, Y, N;

D2( );
~D2( );
void iterate( );
};

main(){
D2 A;
A.iterate();

getchar();
}

D2 :: D2(){
int array_counter;
V4 = new double *[NX];
V5 = new double *[NX];
V2 = new double *[NX];
V3 = new double *[NX];
Vy = new double *[NX];
Vx = new double *[NX];
I = new double *[NX];
Sey = new double *[NX];
Sex = new double *[NX];
pex = new double *[NX];
pey = new double *[NX];
X1x = new double *[NX];
X1y = new double *[NX];
X2x = new double *[NX];
X2y = new double *[NX];

for (array_counter = 0; array_counter < NX; array_counter++)
{
V4[array_counter] = new double [NY];
V5[array_counter] = new double [NY];
V2[array_counter] = new double [NY];
V3[array_counter] = new double [NY];
Vy[array_counter] = new double [NY];
Vx[array_counter] = new double [NY];
I[array_counter] = new double [NY];
Sey[array_counter] = new double [NY];
Sex[array_counter] = new double [NY];
pex[array_counter] = new double [NY];
pey[array_counter] = new double [NY];
X1x[array_counter] = new double [NY];
X1y[array_counter] = new double [NY];
X2x[array_counter] = new double [NY];
X2y[array_counter] = new double [NY];
}

cin >> NT;
h1=new double [NT];
h2=new double [NT];
h3=new double [NT];
h4=new double [NT];
}

D2 :: ~D2(){
int array_counter;
for (array_counter = 0; array_counter < NX; array_counter++)
{
delete [] V4[array_counter];
delete [] V5[array_counter];
delete [] V2[array_counter];
delete [] V3[array_counter];
delete [] Vy[array_counter];
delete [] Vx[array_counter];
delete [] I[array_counter];
delete [] Sey[array_counter];
delete [] Sex[array_counter];
delete [] pex[array_counter];
delete [] pey[array_counter];
delete [] X1x[array_counter];
delete [] X1y[array_counter];
delete [] X2x[array_counter];
delete [] X2y[array_counter];
}
delete [] V4;
delete [] V5;
delete [] V2;
delete [] V3;
delete [] Vy;
delete [] Vx;
delete [] I;
delete [] Sey;
delete [] Sex;
delete [] pex;
delete [] pey;
delete [] X1x;
delete [] X1y;
delete [] X2x;
delete [] X2y;

delete []h1;
delete []h2;
delete []h3;
delete []h4;

}
void D2 :: iterate(){

ofstream outfile1("Space_Vx_NL.out");
//ofstream outfile1_ENV("Space_Vx_NL_Envelope.out");
ofstream outfile2A("FFT_Vx_NL.out");
ofstream outfile2B("FFT_Vy_NL.out");
ofstream outfile2C("FFT_I_NL.out");
ofstream outfile2D("FFT_P_NL.out");
ofstream outfile3("TimeData_NL.out");

int MatP[NX][NY];

int NL_Boundary = NX-100;
int StripStY_LEFT = (NY/2)-11;
int StripEnY_LEFT = (NY/2)+11;

int StripStY_RIGHT = StripStY_LEFT;
int StripEnY_RIGHT = StripEnY_LEFT;
for (X=0; X<NX; X++)
{
for (Y=0; Y<NY; Y++)
{
if (X<=NL_Boundary)
{
if (Y>=StripStartY_LEFT && Y<=StripEndY_LEFT) MatP[X][Y] =1;
else MatP[X][Y]=0;

}
if (X>NL_Boundary)
{
if (Y>=StripStartY_RIGHT && Y<=StripEndY_RIGHT) MatP[X][Y] =2;
else MatP[X][Y]=3;
}

outfileMatProfile<<MatP[X][Y];

}
outfileMatProfile<<endl;
}

double CHIe[NM];
double T1[NM];

CHIe[0] = (1.4 * 1.4) ;
CHIe[1] = (1.5 * 1.5) - 1.0;
CHIe[2] = (1.5 * 1.5);
CHIe[3] = (1.4 * 1.4) - 1.0;
double n0_0=1.4, n0_1=1.5, n0_2=1.5, n0_3=1.4, n2=2.5e-16;
double e0 = 8.854e-12;
double Z0=376.7;
double dCHIe_0 = n0_0*n0_0 - 1.0;
double dCHIe_1 = n0_1*n0_1 - 1.0;
double dCHIe_2 = n0_2*n0_2 - 1.0;
double dCHIe_3 = n0_3*n0_3 - 1.0;

double alpha_value_0 = (e0*e0*dCHIe_0*dCHIe_0*dCHIe_0) ;
double alpha_value_1 = (e0*e0*dCHIe_1*dCHIe_1*dCHIe_1) ;
double alpha_value_2 = (e0*e0*dCHIe_2*dCHIe_2*dCHIe_2) ;
double alpha_value_3 = (e0*e0*dCHIe_3*dCHIe_3*dCHIe_3*20.0*Z0) ;

ALPHA[0] = 0*alpha_value_0;
ALPHA[1] = alpha_value_1;
ALPHA[2] = 0*6.1*alpha_value_2;
ALPHA[3] = 0*6.1*alpha_value_3;

w0[0] = 1500e12;
w0[1] = 2.0 * 1500e12;
w0[2] = 2.0 * 1500e12;
w0[3] = 2.0 * 1500e12;

d[0] = w0[0] ;
d[1] = w0[1] * 1e-3;
d[2] = w0[2] * 1e-3;
d[3] = w0[3] ;

//NORMALISATION
ALPHA[0] = ALPHA[0] * (e0*e0/dX/dX);
ALPHA[1] = ALPHA[1] * (e0*e0/dX/dX);
ALPHA[2] = ALPHA[2] * (e0*e0/dX/dX);
ALPHA[3] = ALPHA[3] * (e0*e0/dX/dX);

w0[0] = w0[0] * (dT);
w0[1] = w0[1] * (dT);
w0[2] = w0[2] * (dT);
w0[3] = w0[3] * (dT);

double Convergence_x = 1.5e-9;
double Convergence_y = 1.5e-9;

Tp0[0] = 1.0 / (4.0);
Tp0[1] = 1.0 / (d[1]);
Tp0[2] = 1.0 / (d[2]);
Tp0[3] = 1.0 / (4.0 + 4.0*d[3]);

b0 = 8.0;

b1[0] = -2.0 * w0[0];
b1[1] = -2.0 * w0[1];
b1[2] = -2.0 * w0[2] * w0[2];
b1[3] = -2.0 * w0[3] * w0[3];

b2[0] = 2.0 * w0[0] * w0[0];
b2[1] = 2.0 * w0[1] * w0[1];
b2[2] = 2.0 * w0[2];
b2[3] = 2.0 * w0[3] * w0[3];

b3[0] = -(4.0 - 4.0 * d[0]);
b3[1] = -(4.0 - 4.0 * d[1]);
b3[2] = -(4.0 - 4.0 * d[2]);
b3[3] = -4.0 ;

double Te = 0.5;
double Ke = -2.0;
Tp1[0] = 1.0 / (1.0 + 2.0 * CHIe[0] * w0[0] * w0[0] * Tp0[0] * Te);
Tp1[1] = 1.0 / (1.0 + 2.0 * CHIe[1] * w0[1] * w0[1] * Tp0[1] * Te);
Tp1[2] = 1.0 / (1.0 + 2.0 * CHIe[2] * w0[2] * w0[2] * Tp0[2] * Te);
Tp1[3] = 1.0 / (1.0 + 2.0 * CHIe[3] * w0[3] * w0[3] * Tp0[3] * Te);

Te2[0] = Tp0[0] * Tp1[0];
Te2[1] = Tp0[1] * Tp1[1];
Te2[2] = Tp0[2] * Tp1[2];
Te2[3] = Tp0[3] * Tp1[3];

Te1[0] = CHIe[0] * w0[0] * w0[0];
Te1[1] = CHIe[1] * w0[1] * w0[1];
Te1[2] = CHIe[2] * w0[2] * w0[2];
Te1[3] = CHIe[3] * w0[3] * w0[3];
//double r_Abs = (sqrt(2.0) - sqrt(CHIe[0] + 1.0)) / (sqrt(2.0) +
sqrt(CHIe[0] + 1.0));
double r_Abs_LEFT, r_Abs_RIGHT, r_Abs_TOP, r_Abs_BOTTOM;
double r_Metal = -1.0;
int Noff=400;
for (X=0; X<NX; X++)
{
for (Y=0; Y<NY; Y++)
{
V4[X][Y] = V5[X][Y] = V2[X][Y] = V3[X][Y]
=Vy[X][Y]=Vx[X][Y]=I[X][Y]=Sey[X][Y]=Sex[X][Y]=0.0;
pex[X][Y] = pey[X][Y] = X1x[X][Y] = X1y[X][Y] = X2x[X][Y] = X2y[X][Y]
= 0.0;
}
}


for (N=0; N<NT; N++)
{
if (N%200==0) cout << "N= "<<N<<endl;
{
if (N<Noff)

{

Y=NY/2;//=150;

{
double ModG = (N-double(Noff);
V4[300][Y]+= ModG;
V5[300][Y]+= -ModG;
V2[300][Y]+= -ModG;
V3[300][Y]+= ModG;

}
}
}
int Xout =20 ;
int Yout =25;

h1[N] = Vx[Xout][Yout];
h2[N] = Vy[Xout][Yout];
h3[N] = I[Xout][Yout];
h4[N] = Vx[Xout][Yout] * Vx[Xout][Yout] + Vy[Xout][Yout] *
Vy[Xout][Yout];
//outfile3<<N<<" "<<h1[N]<<endl;
for (X=0; X<NX; X++)
{
for (Y=0; Y<NY; Y++)
{
double v2 = V2[X][Y];
double v3 = V3[X][Y];
double v4 = V4[X][Y];
double v5 = V5[X][Y];

{....}

//Vx[X][Y] = V2[X][Y] + V3[X][Y];
V4[X][Y] = Vy[X][Y] - I[X][Y] - v5;
V5[X][Y] = Vy[X][Y] + I[X][Y] - v4;
V2[X][Y] = Vx[X][Y] + I[X][Y] - v3;
V3[X][Y] = Vx[X][Y] - I[X][Y] - v2;
}
}


for (X=0; X<NX; X++)
{
for (Y=0; Y<NY-1; Y++)
{
double temp;
temp = V3[X][Y];
V3[X][Y] = V2[X][Y+1];
V2[X][Y+1] = temp;
}
}

//outfile1<<"N= "<<N;
for (Y=NY-1;Y>=0; Y--)
{
// for (X=0; X<NX; X++)

{

outfile3<<N<<"\t"<<Y<<"\t"<<Vy[150][Y]<<endl;
}
// outfile3<<endl<<endl;;
}

outfile3<<endl<<endl<<endl;
if (N==2000)

{
for (X=0; X<NX; X++)
{
for (Y=NY-1;Y>=0; Y--)
{
outfile4A<<X<<"\t"<<Y<<"\t"<<Vy[X][Y]<<endl;

}

outfile4A<<endl;

}
}
if (N==5000)

{
for (X=0; X<NX; X++)
{
for (Y=NY-1;Y>=0; Y--)
{
outfile4B<<X<<"\t"<<Y<<"\t"<<Vy[X][Y]<<endl;

}

outfile4B<<endl;

}
}
if (N==8000)

{
for (X=0; X<NX; X++)
{
for (Y=NY-1;Y>=0; Y--)
{
outfile4C<<X<<"\t"<<Y<<"\t"<<Vy[X][Y]<<endl;

}

outfile4C<<endl;

}
}

}
}

Nov 27 '05 #4

P: n/a
In message <11**********************@z14g2000cwz.googlegroups .com>, vj
<ee***@nottingham.ac.uk> writes
Thankyou for the reply.
I can't run multiple files,
Why do you want to?


I wish to run multiple files at the same time, since the run times are
long, and I want to leave multiple files running overnight so as to get
multiple results in the morning.
Why? std::vector is a much more error-proof way of dealing with large
arrays, and isn't subject to the problems you appear to be experiencing.
If you post real code, people here may be able to suggest way to improve
it.


I am posting (a part of) real code below: you will see I am not a very
good programmer ( it is better to say that I am a rather novice/bad
programmer! ). The variables NX, NY and NT are the ones with large
values, and I get a message ~"stack overflow error" when running these
files, unless I change the project settings (as explained in my
original post).


Then the short-term solution is to change the project settings, compile
the source and run multiple instances of the resulting compiled
application. I can't see any reason why you have to run the application
from within the compiler IDE.
I have never used the std::vector option as suggested
by you. Any suggestions are welcome, and easy-to-understand or
step-by-step would be highly appreciated.
Thanks

Here is the code:

#include <iostream.h>
#include <fstream.h> You also include <fstream> below#include <stdio.h> Not used.#include <math.h>
#include <stdlib.h>
#include <stddef.h>
#include <complex.h> Not used.#include <fstream>
#include <time.h>
#define PI 3.14159265 Not used.#define c 3.0
#define dX 50.0
#define dT (dX/c)

#define NX 10000
#define NY 200
//#define NT 20000
#define NM 4

class D2{
Shouldn't the name of this class give some idea of what it represents?
public:
int NT;
Setting yourself up for confusion ;-) This all-caps object is a member
variable; NX and NY are macros. Consider a better naming convention.

double **V4, **V5, **V2, **V3, **Vy, **Vx, **I;

double **Sey;
double **Sex;
double **pey, **pex, **X1y, **X1x, **X2y, **X2x;
It seems that these things are all two-dimensional rectangular matrices
represented by arrays of pointers to arrays. I'd start by designing a
class to represent a matrix, using std::vector internally to hold the
data.
double ALPHA[NM], d[NM], w0[NM];
double Tp0[NM], b0, b1[NM], b2[NM], b3[NM], Tp1[NM], Te2[NM],
Te1[NM];
And these represent 1-D vectors.
double *h1, *h2, *h3, *h4;
int X, Y, N;
And these could be anything.

Also, all these data members are public. You might want to reconsider
that - encapsulation and data hiding reduces unnecessary coupling
between this class and its customers.


D2( );
~D2( );
void iterate( );
};

main(){
D2 A;
A.iterate();

getchar();
}

D2 :: D2(){
int array_counter;
Don't declare this until it's needed, inside the for statement.
V4 = new double *[NX];
V5 = new double *[NX];
V2 = new double *[NX];
V3 = new double *[NX];
Vy = new double *[NX];
Vx = new double *[NX];
I = new double *[NX];
Sey = new double *[NX];
Sex = new double *[NX];
pex = new double *[NX];
pey = new double *[NX];
X1x = new double *[NX];
X1y = new double *[NX];
X2x = new double *[NX];
X2y = new double *[NX];

for (array_counter = 0; array_counter < NX; array_counter++)
{
V4[array_counter] = new double [NY];
V5[array_counter] = new double [NY];
V2[array_counter] = new double [NY];
V3[array_counter] = new double [NY];
Vy[array_counter] = new double [NY];
Vx[array_counter] = new double [NY];
I[array_counter] = new double [NY];
Sey[array_counter] = new double [NY];
Sex[array_counter] = new double [NY];
pex[array_counter] = new double [NY];
pey[array_counter] = new double [NY];
X1x[array_counter] = new double [NY];
X1y[array_counter] = new double [NY];
X2x[array_counter] = new double [NY];
X2y[array_counter] = new double [NY];
}
All the above is just allocating memory for your matrices. If you had a
Matrix class, it would take care of that for you. You might also
consider making NX and NY arguments to the constructor, rather than
picking up global data from macros.
cin >> NT;
Having a constructor read data from a fixed stream is not a good idea.
What if you construct more objects of this type? What if you want to
change the stream?

Pass this number as an argument to the constructor.
h1=new double [NT];
h2=new double [NT];
h3=new double [NT];
h4=new double [NT];
}

D2 :: ~D2(){
int array_counter;
for (array_counter = 0; array_counter < NX; array_counter++)
{
delete [] V4[array_counter];
delete [] V5[array_counter];
delete [] V2[array_counter];
delete [] V3[array_counter];
delete [] Vy[array_counter];
delete [] Vx[array_counter];
delete [] I[array_counter];
delete [] Sey[array_counter];
delete [] Sex[array_counter];
delete [] pex[array_counter];
delete [] pey[array_counter];
delete [] X1x[array_counter];
delete [] X1y[array_counter];
delete [] X2x[array_counter];
delete [] X2y[array_counter];
}
delete [] V4;
delete [] V5;
delete [] V2;
delete [] V3;
delete [] Vy;
delete [] Vx;
delete [] I;
delete [] Sey;
delete [] Sex;
delete [] pex;
delete [] pey;
delete [] X1x;
delete [] X1y;
delete [] X2x;
delete [] X2y;

delete []h1;
delete []h2;
delete []h3;
delete []h4;

} OK. The destructor just deletes all the arrays. But it's error-prone. If
you add new members, you have to remember to modify the constructor and
the destructor to match. If you had a Matrix class, its destructor would
take care of this for you.

You have a default constructor and a destructor which manage pointers
representing ownership of memry. The compiler will automatically
generate a copy constructor and assignment operator which, if invoked,
will cause undefined behaviour. You should either define your own or at
least declare them to be inaccessible. If instead you used std::vector
to manage the underlying storage, it would automatically deal with
copy-construction and assignment and this problem wouldn't arise.
void D2 :: iterate(){

ofstream outfile1("Space_Vx_NL.out");
//ofstream outfile1_ENV("Space_Vx_NL_Envelope.out");
ofstream outfile2A("FFT_Vx_NL.out");
ofstream outfile2B("FFT_Vy_NL.out");
ofstream outfile2C("FFT_I_NL.out");
ofstream outfile2D("FFT_P_NL.out");
ofstream outfile3("TimeData_NL.out");
Why does a function called "iterate" open files? And so many of them?
And fixed names? Consider splitting this code into smaller functions,
each of which does one thing you can describe in the name of the
function.

If you're writing something to a stream, can that "something" be
abstracted as a class together with an operator<< to write it to a
generic stream?

int MatP[NX][NY];
This is apparently the only large array created on the stack, so it's
this which is probably the source of your problem. AFAICS you don't
actually use the array as such - you just calculate each element in turn
and write it to a file.
int NL_Boundary = NX-100;
int StripStY_LEFT = (NY/2)-11;
int StripEnY_LEFT = (NY/2)+11;
Magic numbers?
int StripStY_RIGHT = StripStY_LEFT;
int StripEnY_RIGHT = StripEnY_LEFT;
for (X=0; X<NX; X++)
{
for (Y=0; Y<NY; Y++)
{
if (X<=NL_Boundary)
{
if (Y>=StripStartY_LEFT && Y<=StripEndY_LEFT) MatP[X][Y] =1;
else MatP[X][Y]=0;

}
if (X>NL_Boundary)
{
if (Y>=StripStartY_RIGHT && Y<=StripEndY_RIGHT) MatP[X][Y] =2;
else MatP[X][Y]=3;
}

outfileMatProfile<<MatP[X][Y];
Having assigned a value to MatP[X][Y], this is the only place where you
use it.
}
outfileMatProfile<<endl;
}

double CHIe[NM];
double T1[NM];

CHIe[0] = (1.4 * 1.4) ;
CHIe[1] = (1.5 * 1.5) - 1.0;
CHIe[2] = (1.5 * 1.5);
CHIe[3] = (1.4 * 1.4) - 1.0;
double n0_0=1.4, n0_1=1.5, n0_2=1.5, n0_3=1.4, n2=2.5e-16;
More magic numbers
double e0 = 8.854e-12;
double Z0=376.7;
double dCHIe_0 = n0_0*n0_0 - 1.0;
double dCHIe_1 = n0_1*n0_1 - 1.0;
double dCHIe_2 = n0_2*n0_2 - 1.0;
double dCHIe_3 = n0_3*n0_3 - 1.0;

double alpha_value_0 = (e0*e0*dCHIe_0*dCHIe_0*dCHIe_0) ;
double alpha_value_1 = (e0*e0*dCHIe_1*dCHIe_1*dCHIe_1) ;
double alpha_value_2 = (e0*e0*dCHIe_2*dCHIe_2*dCHIe_2) ;
double alpha_value_3 = (e0*e0*dCHIe_3*dCHIe_3*dCHIe_3*20.0*Z0) ;

ALPHA[0] = 0*alpha_value_0;
ALPHA[1] = alpha_value_1;
ALPHA[2] = 0*6.1*alpha_value_2;
ALPHA[3] = 0*6.1*alpha_value_3;

w0[0] = 1500e12;
w0[1] = 2.0 * 1500e12;
w0[2] = 2.0 * 1500e12;
w0[3] = 2.0 * 1500e12;
More magic numbers
d[0] = w0[0] ;
d[1] = w0[1] * 1e-3;
d[2] = w0[2] * 1e-3;
d[3] = w0[3] ;

//NORMALISATION
ALPHA[0] = ALPHA[0] * (e0*e0/dX/dX);
ALPHA[1] = ALPHA[1] * (e0*e0/dX/dX);
ALPHA[2] = ALPHA[2] * (e0*e0/dX/dX);
ALPHA[3] = ALPHA[3] * (e0*e0/dX/dX);
This looks like a 4-vector being multiplied by a scalar. Perhaps it
should be represented by a class with an operator *=(double) ?
w0[0] = w0[0] * (dT);
w0[1] = w0[1] * (dT);
w0[2] = w0[2] * (dT);
w0[3] = w0[3] * (dT);
Likewise. And the same goes for some of the following code, too.

double Convergence_x = 1.5e-9;
double Convergence_y = 1.5e-9;

Tp0[0] = 1.0 / (4.0);
Tp0[1] = 1.0 / (d[1]);
Tp0[2] = 1.0 / (d[2]);
Tp0[3] = 1.0 / (4.0 + 4.0*d[3]);

b0 = 8.0;

b1[0] = -2.0 * w0[0];
b1[1] = -2.0 * w0[1];
b1[2] = -2.0 * w0[2] * w0[2];
b1[3] = -2.0 * w0[3] * w0[3];

b2[0] = 2.0 * w0[0] * w0[0];
b2[1] = 2.0 * w0[1] * w0[1];
b2[2] = 2.0 * w0[2];
b2[3] = 2.0 * w0[3] * w0[3];

b3[0] = -(4.0 - 4.0 * d[0]);
b3[1] = -(4.0 - 4.0 * d[1]);
b3[2] = -(4.0 - 4.0 * d[2]);
b3[3] = -4.0 ;

double Te = 0.5;
double Ke = -2.0;
Tp1[0] = 1.0 / (1.0 + 2.0 * CHIe[0] * w0[0] * w0[0] * Tp0[0] * Te);
Tp1[1] = 1.0 / (1.0 + 2.0 * CHIe[1] * w0[1] * w0[1] * Tp0[1] * Te);
Tp1[2] = 1.0 / (1.0 + 2.0 * CHIe[2] * w0[2] * w0[2] * Tp0[2] * Te);
Tp1[3] = 1.0 / (1.0 + 2.0 * CHIe[3] * w0[3] * w0[3] * Tp0[3] * Te);

Te2[0] = Tp0[0] * Tp1[0];
Te2[1] = Tp0[1] * Tp1[1];
Te2[2] = Tp0[2] * Tp1[2];
Te2[3] = Tp0[3] * Tp1[3];

Te1[0] = CHIe[0] * w0[0] * w0[0];
Te1[1] = CHIe[1] * w0[1] * w0[1];
Te1[2] = CHIe[2] * w0[2] * w0[2];
Te1[3] = CHIe[3] * w0[3] * w0[3];
//double r_Abs = (sqrt(2.0) - sqrt(CHIe[0] + 1.0)) / (sqrt(2.0) +
sqrt(CHIe[0] + 1.0));
double r_Abs_LEFT, r_Abs_RIGHT, r_Abs_TOP, r_Abs_BOTTOM;
double r_Metal = -1.0;
int Noff=400;
for (X=0; X<NX; X++)
{
for (Y=0; Y<NY; Y++)
{
V4[X][Y] = V5[X][Y] = V2[X][Y] = V3[X][Y]
=Vy[X][Y]=Vx[X][Y]=I[X][Y]=Sey[X][Y]=Sex[X][Y]=0.0;
pex[X][Y] = pey[X][Y] = X1x[X][Y] = X1y[X][Y] = X2x[X][Y] = X2y[X][Y]
= 0.0;
}
}

A long-winded way of zeroing some matrices.

[snip the rest]

There's much more which could be said, but it's a start.

I'd suggest starting by designing (or cribbing from elsewhere!) - and
*testing* - some small classes which encapsulate the behaviour of your
numerical primitives, using std::vector to store the data and providing
whatever operations you need to perform on the data, and writing the
rest in terms of those.

--
Richard Herring
Nov 28 '05 #5

P: n/a
vj
Richard, Thanks a lot for your patient and detailed reply. I will go
through these suggestions one by one to improve my code.
Richard Herring wrote:
In message <11**********************@z14g2000cwz.googlegroups .com>, vj
<ee***@nottingham.ac.uk> writes
Thankyou for the reply.
I can't run multiple files,

Why do you want to?


I wish to run multiple files at the same time, since the run times are
long, and I want to leave multiple files running overnight so as to get
multiple results in the morning.
Why? std::vector is a much more error-proof way of dealing with large
arrays, and isn't subject to the problems you appear to be experiencing.
If you post real code, people here may be able to suggest way to improve
it.


I am posting (a part of) real code below: you will see I am not a very
good programmer ( it is better to say that I am a rather novice/bad
programmer! ). The variables NX, NY and NT are the ones with large
values, and I get a message ~"stack overflow error" when running these
files, unless I change the project settings (as explained in my
original post).


Then the short-term solution is to change the project settings, compile
the source and run multiple instances of the resulting compiled
application. I can't see any reason why you have to run the application
from within the compiler IDE.
I have never used the std::vector option as suggested
by you. Any suggestions are welcome, and easy-to-understand or
step-by-step would be highly appreciated.
Thanks

Here is the code:

#include <iostream.h>
#include <fstream.h>

You also include <fstream> below
#include <stdio.h>

Not used.
#include <math.h>
#include <stdlib.h>
#include <stddef.h>
#include <complex.h>

Not used.
#include <fstream>
#include <time.h>
#define PI 3.14159265

Not used.
#define c 3.0
#define dX 50.0
#define dT (dX/c)

#define NX 10000
#define NY 200
//#define NT 20000
#define NM 4

class D2{


Shouldn't the name of this class give some idea of what it represents?
public:
int NT;


Setting yourself up for confusion ;-) This all-caps object is a member
variable; NX and NY are macros. Consider a better naming convention.

double **V4, **V5, **V2, **V3, **Vy, **Vx, **I;

double **Sey;
double **Sex;
double **pey, **pex, **X1y, **X1x, **X2y, **X2x;


It seems that these things are all two-dimensional rectangular matrices
represented by arrays of pointers to arrays. I'd start by designing a
class to represent a matrix, using std::vector internally to hold the
data.
double ALPHA[NM], d[NM], w0[NM];
double Tp0[NM], b0, b1[NM], b2[NM], b3[NM], Tp1[NM], Te2[NM],
Te1[NM];


And these represent 1-D vectors.

double *h1, *h2, *h3, *h4;
int X, Y, N;


And these could be anything.

Also, all these data members are public. You might want to reconsider
that - encapsulation and data hiding reduces unnecessary coupling
between this class and its customers.


D2( );
~D2( );
void iterate( );
};

main(){
D2 A;
A.iterate();

getchar();
}

D2 :: D2(){
int array_counter;


Don't declare this until it's needed, inside the for statement.
V4 = new double *[NX];
V5 = new double *[NX];
V2 = new double *[NX];
V3 = new double *[NX];
Vy = new double *[NX];
Vx = new double *[NX];
I = new double *[NX];
Sey = new double *[NX];
Sex = new double *[NX];
pex = new double *[NX];
pey = new double *[NX];
X1x = new double *[NX];
X1y = new double *[NX];
X2x = new double *[NX];
X2y = new double *[NX];

for (array_counter = 0; array_counter < NX; array_counter++)
{
V4[array_counter] = new double [NY];
V5[array_counter] = new double [NY];
V2[array_counter] = new double [NY];
V3[array_counter] = new double [NY];
Vy[array_counter] = new double [NY];
Vx[array_counter] = new double [NY];
I[array_counter] = new double [NY];
Sey[array_counter] = new double [NY];
Sex[array_counter] = new double [NY];
pex[array_counter] = new double [NY];
pey[array_counter] = new double [NY];
X1x[array_counter] = new double [NY];
X1y[array_counter] = new double [NY];
X2x[array_counter] = new double [NY];
X2y[array_counter] = new double [NY];
}


All the above is just allocating memory for your matrices. If you had a
Matrix class, it would take care of that for you. You might also
consider making NX and NY arguments to the constructor, rather than
picking up global data from macros.

cin >> NT;


Having a constructor read data from a fixed stream is not a good idea.
What if you construct more objects of this type? What if you want to
change the stream?

Pass this number as an argument to the constructor.
h1=new double [NT];
h2=new double [NT];
h3=new double [NT];
h4=new double [NT];
}

D2 :: ~D2(){
int array_counter;
for (array_counter = 0; array_counter < NX; array_counter++)
{
delete [] V4[array_counter];
delete [] V5[array_counter];
delete [] V2[array_counter];
delete [] V3[array_counter];
delete [] Vy[array_counter];
delete [] Vx[array_counter];
delete [] I[array_counter];
delete [] Sey[array_counter];
delete [] Sex[array_counter];
delete [] pex[array_counter];
delete [] pey[array_counter];
delete [] X1x[array_counter];
delete [] X1y[array_counter];
delete [] X2x[array_counter];
delete [] X2y[array_counter];
}
delete [] V4;
delete [] V5;
delete [] V2;
delete [] V3;
delete [] Vy;
delete [] Vx;
delete [] I;
delete [] Sey;
delete [] Sex;
delete [] pex;
delete [] pey;
delete [] X1x;
delete [] X1y;
delete [] X2x;
delete [] X2y;

delete []h1;
delete []h2;
delete []h3;
delete []h4;

}

OK. The destructor just deletes all the arrays. But it's error-prone. If
you add new members, you have to remember to modify the constructor and
the destructor to match. If you had a Matrix class, its destructor would
take care of this for you.

You have a default constructor and a destructor which manage pointers
representing ownership of memry. The compiler will automatically
generate a copy constructor and assignment operator which, if invoked,
will cause undefined behaviour. You should either define your own or at
least declare them to be inaccessible. If instead you used std::vector
to manage the underlying storage, it would automatically deal with
copy-construction and assignment and this problem wouldn't arise.
void D2 :: iterate(){

ofstream outfile1("Space_Vx_NL.out");
//ofstream outfile1_ENV("Space_Vx_NL_Envelope.out");
ofstream outfile2A("FFT_Vx_NL.out");
ofstream outfile2B("FFT_Vy_NL.out");
ofstream outfile2C("FFT_I_NL.out");
ofstream outfile2D("FFT_P_NL.out");
ofstream outfile3("TimeData_NL.out");


Why does a function called "iterate" open files? And so many of them?
And fixed names? Consider splitting this code into smaller functions,
each of which does one thing you can describe in the name of the
function.

If you're writing something to a stream, can that "something" be
abstracted as a class together with an operator<< to write it to a
generic stream?

int MatP[NX][NY];


This is apparently the only large array created on the stack, so it's
this which is probably the source of your problem. AFAICS you don't
actually use the array as such - you just calculate each element in turn
and write it to a file.
int NL_Boundary = NX-100;
int StripStY_LEFT = (NY/2)-11;
int StripEnY_LEFT = (NY/2)+11;


Magic numbers?

int StripStY_RIGHT = StripStY_LEFT;
int StripEnY_RIGHT = StripEnY_LEFT;
for (X=0; X<NX; X++)
{
for (Y=0; Y<NY; Y++)
{
if (X<=NL_Boundary)
{
if (Y>=StripStartY_LEFT && Y<=StripEndY_LEFT) MatP[X][Y] =1;
else MatP[X][Y]=0;

}
if (X>NL_Boundary)
{
if (Y>=StripStartY_RIGHT && Y<=StripEndY_RIGHT) MatP[X][Y] =2;
else MatP[X][Y]=3;
}

outfileMatProfile<<MatP[X][Y];


Having assigned a value to MatP[X][Y], this is the only place where you
use it.

}
outfileMatProfile<<endl;
}

double CHIe[NM];
double T1[NM];

CHIe[0] = (1.4 * 1.4) ;
CHIe[1] = (1.5 * 1.5) - 1.0;
CHIe[2] = (1.5 * 1.5);
CHIe[3] = (1.4 * 1.4) - 1.0;
double n0_0=1.4, n0_1=1.5, n0_2=1.5, n0_3=1.4, n2=2.5e-16;


More magic numbers
double e0 = 8.854e-12;
double Z0=376.7;
double dCHIe_0 = n0_0*n0_0 - 1.0;
double dCHIe_1 = n0_1*n0_1 - 1.0;
double dCHIe_2 = n0_2*n0_2 - 1.0;
double dCHIe_3 = n0_3*n0_3 - 1.0;

double alpha_value_0 = (e0*e0*dCHIe_0*dCHIe_0*dCHIe_0) ;
double alpha_value_1 = (e0*e0*dCHIe_1*dCHIe_1*dCHIe_1) ;
double alpha_value_2 = (e0*e0*dCHIe_2*dCHIe_2*dCHIe_2) ;
double alpha_value_3 = (e0*e0*dCHIe_3*dCHIe_3*dCHIe_3*20.0*Z0) ;

ALPHA[0] = 0*alpha_value_0;
ALPHA[1] = alpha_value_1;
ALPHA[2] = 0*6.1*alpha_value_2;
ALPHA[3] = 0*6.1*alpha_value_3;

w0[0] = 1500e12;
w0[1] = 2.0 * 1500e12;
w0[2] = 2.0 * 1500e12;
w0[3] = 2.0 * 1500e12;


More magic numbers

d[0] = w0[0] ;
d[1] = w0[1] * 1e-3;
d[2] = w0[2] * 1e-3;
d[3] = w0[3] ;

//NORMALISATION
ALPHA[0] = ALPHA[0] * (e0*e0/dX/dX);
ALPHA[1] = ALPHA[1] * (e0*e0/dX/dX);
ALPHA[2] = ALPHA[2] * (e0*e0/dX/dX);
ALPHA[3] = ALPHA[3] * (e0*e0/dX/dX);


This looks like a 4-vector being multiplied by a scalar. Perhaps it
should be represented by a class with an operator *=(double) ?

w0[0] = w0[0] * (dT);
w0[1] = w0[1] * (dT);
w0[2] = w0[2] * (dT);
w0[3] = w0[3] * (dT);


Likewise. And the same goes for some of the following code, too.

double Convergence_x = 1.5e-9;
double Convergence_y = 1.5e-9;

Tp0[0] = 1.0 / (4.0);
Tp0[1] = 1.0 / (d[1]);
Tp0[2] = 1.0 / (d[2]);
Tp0[3] = 1.0 / (4.0 + 4.0*d[3]);

b0 = 8.0;

b1[0] = -2.0 * w0[0];
b1[1] = -2.0 * w0[1];
b1[2] = -2.0 * w0[2] * w0[2];
b1[3] = -2.0 * w0[3] * w0[3];

b2[0] = 2.0 * w0[0] * w0[0];
b2[1] = 2.0 * w0[1] * w0[1];
b2[2] = 2.0 * w0[2];
b2[3] = 2.0 * w0[3] * w0[3];

b3[0] = -(4.0 - 4.0 * d[0]);
b3[1] = -(4.0 - 4.0 * d[1]);
b3[2] = -(4.0 - 4.0 * d[2]);
b3[3] = -4.0 ;

double Te = 0.5;
double Ke = -2.0;
Tp1[0] = 1.0 / (1.0 + 2.0 * CHIe[0] * w0[0] * w0[0] * Tp0[0] * Te);
Tp1[1] = 1.0 / (1.0 + 2.0 * CHIe[1] * w0[1] * w0[1] * Tp0[1] * Te);
Tp1[2] = 1.0 / (1.0 + 2.0 * CHIe[2] * w0[2] * w0[2] * Tp0[2] * Te);
Tp1[3] = 1.0 / (1.0 + 2.0 * CHIe[3] * w0[3] * w0[3] * Tp0[3] * Te);

Te2[0] = Tp0[0] * Tp1[0];
Te2[1] = Tp0[1] * Tp1[1];
Te2[2] = Tp0[2] * Tp1[2];
Te2[3] = Tp0[3] * Tp1[3];

Te1[0] = CHIe[0] * w0[0] * w0[0];
Te1[1] = CHIe[1] * w0[1] * w0[1];
Te1[2] = CHIe[2] * w0[2] * w0[2];
Te1[3] = CHIe[3] * w0[3] * w0[3];
//double r_Abs = (sqrt(2.0) - sqrt(CHIe[0] + 1.0)) / (sqrt(2.0) +
sqrt(CHIe[0] + 1.0));
double r_Abs_LEFT, r_Abs_RIGHT, r_Abs_TOP, r_Abs_BOTTOM;
double r_Metal = -1.0;
int Noff=400;
for (X=0; X<NX; X++)
{
for (Y=0; Y<NY; Y++)
{
V4[X][Y] = V5[X][Y] = V2[X][Y] = V3[X][Y]
=Vy[X][Y]=Vx[X][Y]=I[X][Y]=Sey[X][Y]=Sex[X][Y]=0.0;
pex[X][Y] = pey[X][Y] = X1x[X][Y] = X1y[X][Y] = X2x[X][Y] = X2y[X][Y]
= 0.0;
}
}

A long-winded way of zeroing some matrices.

[snip the rest]

There's much more which could be said, but it's a start.

I'd suggest starting by designing (or cribbing from elsewhere!) - and
*testing* - some small classes which encapsulate the behaviour of your
numerical primitives, using std::vector to store the data and providing
whatever operations you need to perform on the data, and writing the
rest in terms of those.

--
Richard Herring


Nov 29 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.