Unpredictable program behavior ..

A

Andrew

Hi all , i am supposed to create a program that performs a specific
operation to a 2-D matrix whose elements are positive (or zero ).
This operation is repeated T times on the matrix and only the final
matix is needed . The operation to be perormed is
V(t,x,y)=1/2*(sqrt(V(t-1,x-1,y))+sqrt(V(t-1,x-1,y))) . The problem iis
that i have (or i think i have ) created a correct program that
performs this operation but something happens that i cannot understand
.. The final matrix is the same regardless the value of T . That means
that the final matrix is the same for T=10 and T=1000 !!! The code i
have managed to write so far is the following :

/********** VERSION FOR ONE PROCESSOR *****/

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>

#define T 2000
#define X 10
#define Y 10

/* TODO ... to pass these values from the command line ... */

double **CreateMatrix(int,int);
void DestroyMatrix(double **,int);
void InitializeMatrix(double **,int,int);
void CopyMatrix(double **,double **,int,int);

/* The following function is for DEBUG purposes only */

void PrintMatrix(double **,int,int);

int main(void)
{
double **currentMatrix; // Initialization ??? cast to NULL
???
double **tempMatrix; // Initialization ???
double tempValue;
int t,x,y;
for(t=1; t<T; t++)
{
currentMatrix=CreateMatrix(X,Y);
InitializeMatrix(currentMatrix,X,Y);
/* printf("Matrix Created .... \n"); */
if(t==1)
{
tempMatrix=CreateMatrix(X,Y);
InitializeMatrix(tempMatrix,X,Y);
}
for(x=1; x<X; x++)
{
for(y=1; y<Y; y++)
{
if((x==1) && (y==1))
{
tempValue=(double)1;
}
if((x==1) && (y>1))
{

tempValue=(double)1+(double)sqrt(tempMatrix[y-1][x]);
}
if((y==1) && (x>1))
{

tempValue=(double)sqrt(tempMatrix[y][x-1]);
}
if((x>1) && (y>1))
{

tempValue=(double)sqrt(tempMatrix[y][x-1])+(double)sqrt(tempMatrix[y-1][x]);
}

currentMatrix[y][x]=((double)tempValue)/((double)2);
}
}
/* printf("After changing the matrix ..... \n"); */
/* PrintMatrix(currentMatrix,Y,X); */
if(t!= T-1)
{
/* printf("You reached so far .... !!\n"); */
CopyMatrix(tempMatrix,currentMatrix,Y,X);
/* printf("Now printing the old matrix..... \n");
*/
/* PrintMatrix(tempMatrix,Y,X); */
DestroyMatrix(currentMatrix,Y);
}
} /* end of the triple loop ... */
for(int tempi=0; tempi<Y ; tempi++)
{
for(int tempj=0; tempj<X; tempj++)
{
printf(" %f ",currentMatrix[tempi][tempj]);
}
printf("\n");
}

DestroyMatrix(currentMatrix,Y);
DestroyMatrix(tempMatrix,Y);
return 0;
}


double ** CreateMatrix(int X_dim,int Y_dim)
{
double **retdouble=malloc(Y_dim*(sizeof(double *)));
if(retdouble == NULL)
{
printf("Error Allocating memory ..... \n");
exit(EXIT_FAILURE);
}
for (int k=0; k<Y_dim; k++)
{
retdouble[k]=malloc(X_dim*(sizeof(double)));
if(retdouble[k]==NULL)
{
printf("Error Allocating memory ... \n");
exit(EXIT_FAILURE);
}
}
return retdouble;
}



void DestroyMatrix(double ** matrix,int Y_dim)
{
for(int i=0; i<Y_dim; i++)
{
free(matrix);
}
free(matrix);
}

void InitializeMatrix(double **matrix,int X_dim,int Y_dim)
{
for(int i=0; i<Y_dim; i++)
{
for(int j=0; j<X_dim; j++)
{
matrix[j]=0;
}
}
}

void CopyMatrix(double **target,double **source,int Y_dim,int X_dim)
{
for (int i=0; i<Y_dim; i++)
{
for(int j=0; j<X_dim; j++)
{
target[j]=source[j];
}
}
}


void PrintMatrix(double **dest,int Y_dim,int X_dim)
{
for(int tempi=0; tempi<Y_dim ; tempi++)
{
for(unsigned short tempj=0; tempj<X_dim; tempj++)
{
printf(" %f ",dest[tempi][tempj]);
}
printf("\n");
}
}

The program simply creates two matrices dynamically , currentMartix
for the current operation and tempMatrix for the last operation ...
After all the elements of the current matrix have changed according to
the mathematical formula i wrote before they are going to be copied
to the tempMatrix and then the currentMatrix is going to be erased ...
This is performed T times ..

(Sorry for my english )
 
B

Barry Schwarz

Hi all , i am supposed to create a program that performs a specific
operation to a 2-D matrix whose elements are positive (or zero ).
This operation is repeated T times on the matrix and only the final
matix is needed . The operation to be perormed is
V(t,x,y)=1/2*(sqrt(V(t-1,x-1,y))+sqrt(V(t-1,x-1,y))) . The problem iis
that i have (or i think i have ) created a correct program that
performs this operation but something happens that i cannot understand
. The final matrix is the same regardless the value of T . That means

I ran your code with T defined as 5 and determined from the debugger
that tempMatrix[1] had three non-zero values. Ran it again with T
defined as 100 and tempMatrix had nine non-zero values. Something
else must be the problem. Keep reading.
that the final matrix is the same for T=10 and T=1000 !!! The code i
have managed to write so far is the following :

/********** VERSION FOR ONE PROCESSOR *****/

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>

#define T 2000
#define X 10
#define Y 10

/* TODO ... to pass these values from the command line ... */

double **CreateMatrix(int,int);
void DestroyMatrix(double **,int);
void InitializeMatrix(double **,int,int);
void CopyMatrix(double **,double **,int,int);

/* The following function is for DEBUG purposes only */

void PrintMatrix(double **,int,int);

int main(void)
{
double **currentMatrix; // Initialization ??? cast to NULL
???

There is no need since you initialize it immediately during execution.
Some like to do it as a matter of style.
double **tempMatrix; // Initialization ???
double tempValue;
int t,x,y;
for(t=1; t<T; t++)

You are aware that this will only execute the loop T-1 times, not T?
{
currentMatrix=CreateMatrix(X,Y);

It is a little confusing that you pass the parameters as X and Y when
you reference the matrix as y and x.
InitializeMatrix(currentMatrix,X,Y);
/* printf("Matrix Created .... \n"); */
if(t==1)
{
tempMatrix=CreateMatrix(X,Y);
InitializeMatrix(tempMatrix,X,Y);
}
for(x=1; x<X; x++)
{
for(y=1; y<Y; y++)
{
if((x==1) && (y==1))

You seem to be ignoring row and column 0 here.
{
tempValue=(double)1;

The cast is irrelevant. 1 is an int and would be converted to double
automatically. If you want an indication in the source line that you
are not dealing with integers, 1.0 would be preferable.
}
if((x==1) && (y>1))
{

tempValue=(double)1+(double)sqrt(tempMatrix[y-1][x]);

sqrt returns a double so that cast is completely superfluous.
}
if((y==1) && (x>1))
{

tempValue=(double)sqrt(tempMatrix[y][x-1]);
}
if((x>1) && (y>1))
{

tempValue=(double)sqrt(tempMatrix[y][x-1])+(double)sqrt(tempMatrix[y-1][x]);
}

currentMatrix[y][x]=((double)tempValue)/((double)2);

You really are in love with casts, aren't you? Why? What do you
think they accomplish?
}
}
/* printf("After changing the matrix ..... \n"); */
/* PrintMatrix(currentMatrix,Y,X); */
if(t!= T-1)
{
/* printf("You reached so far .... !!\n"); */
CopyMatrix(tempMatrix,currentMatrix,Y,X);

This copies currentMatrix to tempMatrix.
/* printf("Now printing the old matrix..... \n");
*/
/* PrintMatrix(tempMatrix,Y,X); */
DestroyMatrix(currentMatrix,Y);

This completely frees currentMatrix in preparation for reallocating it
during the next iteration through the loop.

It would have been simpler to merely reinitialize currentMatrix.
}
} /* end of the triple loop ... */
for(int tempi=0; tempi<Y ; tempi++)
{
for(int tempj=0; tempj<X; tempj++)
{
printf(" %f ",currentMatrix[tempi][tempj]);

Can you guess which parameter above no longer exists. You are
invoking undefined behavior.
}
printf("\n");
}

DestroyMatrix(currentMatrix,Y);

You cannot free memory that has already been freed. More undefined
behavior.
DestroyMatrix(tempMatrix,Y);
return 0;
}


double ** CreateMatrix(int X_dim,int Y_dim)
{
double **retdouble=malloc(Y_dim*(sizeof(double *)));
if(retdouble == NULL)
{
printf("Error Allocating memory ..... \n");
exit(EXIT_FAILURE);
}
for (int k=0; k<Y_dim; k++)

Unless you happen to have a C99 compiler, declaring variables inside
the for statement is a non-standard extension.
{
retdouble[k]=malloc(X_dim*(sizeof(double)));
if(retdouble[k]==NULL)
{
printf("Error Allocating memory ... \n");

A different error message would be nice to distinguish between the two
different allocations.
exit(EXIT_FAILURE);
}
}
return retdouble;
}



void DestroyMatrix(double ** matrix,int Y_dim)
{
for(int i=0; i<Y_dim; i++)
{
free(matrix);
}
free(matrix);
}

void InitializeMatrix(double **matrix,int X_dim,int Y_dim)
{
for(int i=0; i<Y_dim; i++)
{
for(int j=0; j<X_dim; j++)
{
matrix[j]=0;
}
}
}

void CopyMatrix(double **target,double **source,int Y_dim,int X_dim)
{
for (int i=0; i<Y_dim; i++)
{
for(int j=0; j<X_dim; j++)
{
target[j]=source[j];
}
}
}


void PrintMatrix(double **dest,int Y_dim,int X_dim)
{
for(int tempi=0; tempi<Y_dim ; tempi++)
{
for(unsigned short tempj=0; tempj<X_dim; tempj++)


I give up. Why is this index different from all other indices?
{
printf(" %f ",dest[tempi][tempj]);

Since your values are doubles, wouldn't you like to print them as
doubles instead of floats?
}
printf("\n");
}
}

The program simply creates two matrices dynamically , currentMartix
for the current operation and tempMatrix for the last operation ...
After all the elements of the current matrix have changed according to
the mathematical formula i wrote before they are going to be copied
to the tempMatrix and then the currentMatrix is going to be erased ...
This is performed T times ..

(Sorry for my english )

Why? It was understandable.


<<Remove the del for email>>
 
K

Kevin Goodsell

Additional comment: <malloc.h> is not a standard header. Use <stdlib.h>
for all your mallocing needs.

-Kevin
 
A

Andrew

Mr. Schwarz thank you very-very much for reading/commenting/executing
my code . I can now remove all the unnecessary operations and make it
run faster . It doesn't matter if the loop(s) are executed T or T-1
times because i am creating a parallel version of the program ( for
more than one processors , actually 16 ) and I must ensure that the
final matrix is the same with that calculated from the one processor
program . We even ignore the boundary conditions (for X=0 and Y=0 )
we need them only to compute the V(t,1,y) and V(t,x,1) values...

Anyway a friend of mine is getting the same results with this program
so I think I don't make something wrong with the algorithm ... I will
optimize my code to get faster execution times following your remakrs
..
Thanks again !!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top