Random fucntion with a twist

A

alphaLaura

Hi all - I'm just new to the group and I hope nobody minds me asking
for some help.

I currently have an assignment which deals with matrices (more
specifically, Gauss-Seidel solving of matrices). One of the side tasks
we have is to generate an NxN matrix of random numbers using the rand()
function, but subject to the constraint that the absolute value of the
diagonal element (a) must be greater than the sum of the absolute
values of all the other elements in that row. That is -

fabs(a) > sum {from j to n} of (fabs(a[j])

For some reason, I have major brain block over this. My initial
thoughts were to use a do{}-while() loop, but I have since tried
everything and gotten nowhere. My random matrix-filler function
currently looks like this -

void fill_random(matrix m)
{
int i, j;
double summation = 0;

for(i = 0; i < n; ++i)
{
for(j = 0; j < n; ++j)
{
m[j] = 2.0 * rand() / RAND_MAX - 1; // Fills element with random
number

do
{
summation += m[j];
break;
}
while ((i!=j) && (fabs(summation) < fabs(m)));

}
}
}


Any suggestions on this are enormously appreciated! I reckon I've just
been thinking about this for too long...
 
A

alphaLaura


Aha, couldn't find an FAQ anywhere - thanks for the link. Sorry if my
topic has violated some obvious rules. I'm aware of the controversy
over asking for homework help - and I'm not after a quick solution so
I don't have to do any work!

Well, basically, runing this program gives me the following output
(bearing in mind that it is different every time due to rand());


-0.950662 0.220462 -0.696894
-0.696521 -0.43253 0.466966
0.298691 0.104779 -0.981414

For row 1, the absolute value of -0.950662 is definitely NOT greater
than the absolute values of 0.220462 and -0.696894 added together.
For row 2, the absolute value of -0.43253 is also not greater than
-0.696521 and 0.466966 added together.
For row 3, only by coincidence, is the absolute value of -0.981414
greater than 0.298691 + 0.104779.

Does that make any more sense?
 
T

Tobias Blomkvist

(e-mail address removed) skrev:
Hi all - I'm just new to the group and I hope nobody minds me asking
for some help.

I currently have an assignment which deals with matrices (more
specifically, Gauss-Seidel solving of matrices). One of the side tasks
we have is to generate an NxN matrix of random numbers using the rand()
function, but subject to the constraint that the absolute value of the
diagonal element (a) must be greater than the sum of the absolute
values of all the other elements in that row. That is -

fabs(a) > sum {from j to n} of (fabs(a[j])

For some reason, I have major brain block over this. My initial
thoughts were to use a do{}-while() loop, but I have since tried
everything and gotten nowhere. My random matrix-filler function
currently looks like this -

<snip>

You mean like:

void fill_random(matrix & m) {
for(unsigned row = 0; row < m.size(); ++row) {
double rowtot = 0;
for(unsigned col = 0; col < m.size(); ++col) {
m[row][col] = 2.0 * std::rand() / RAND_MAX - 1;
if(row != col) {
rowtot += std::fabs(m[row][col]);
}
}
do {
double sup = rowtot + 2.0 * std::rand() / RAND_MAX - 1;
double acc = 2.0 * sup * std::rand() / RAND_MAX - sup;
if(std::fabs(acc) > rowtot) {
m[row][row] = acc;
break;
}
} while(true);
}
}

/TB
 
G

Grizlyk

-0.950662 0.220462 -0.696894
-0.696521 -0.43253 0.466966
0.298691 0.104779 -0.981414

For row 1, the absolute value of -0.950662 is definitely NOT greater
than the absolute values of 0.220462 and -0.696894 added together.
For row 2, the absolute value of -0.43253 is also not greater than
-0.696521 and 0.466966 added together.
For row 3, only by coincidence, is the absolute value of -0.981414
greater than 0.298691 + 0.104779.

- trace your program,
- print output on each for() step,
- setup matrix with concrete values instead of random values

Your code example can not be compiled and does not look like obviouse C++
error, because it is hard to understand what must be in result. Anyway,
algorithmes are offtopic here.
 
A

alphaLaura

(e-mail address removed) skrev:
Hi all - I'm just new to the group and I hope nobody minds me asking
for some help.
I currently have an assignment which deals with matrices (more
specifically, Gauss-Seidel solving of matrices). One of the side tasks
we have is to generate an NxN matrix of random numbers using the rand()
function, but subject to the constraint that the absolute value of the
diagonal element (a) must be greater than the sum of the absolute
values of all the other elements in that row. That is -

fabs(a) > sum {from j to n} of (fabs(a[j])

For some reason, I have major brain block over this. My initial
thoughts were to use a do{}-while() loop, but I have since tried
everything and gotten nowhere. My random matrix-filler function
currently looks like this -<snip>

You mean like:

void fill_random(matrix & m) {
for(unsigned row = 0; row < m.size(); ++row) {
double rowtot = 0;
for(unsigned col = 0; col < m.size(); ++col) {
m[row][col] = 2.0 * std::rand() / RAND_MAX - 1;
if(row != col) {
rowtot += std::fabs(m[row][col]);
}
}
do {
double sup = rowtot + 2.0 * std::rand() / RAND_MAX - 1;
double acc = 2.0 * sup * std::rand() / RAND_MAX - sup;
if(std::fabs(acc) > rowtot) {
m[row][row] = acc;
break;
}
} while(true);
}

}/TB



Wow, that works great! Thanks :D But I'm afraid I'm lost with the two
most important lines of the function -

double sup = rowtot + 2.0 * std::rand() / RAND_MAX - 1;
double acc = 2.0 * sup * std::rand() / RAND_MAX - sup;

Well, more particularly, the double sup declaration. Im not sure why
we're multiplying sup and subtracting sup from acc. Is the subtraction
of sub to ensure the fabs() is not zero?
 
T

Tobias Blomkvist

(e-mail address removed) skrev:
(e-mail address removed) skrev:
Hi all - I'm just new to the group and I hope nobody minds me asking
for some help.
I currently have an assignment which deals with matrices (more
specifically, Gauss-Seidel solving of matrices). One of the side tasks
we have is to generate an NxN matrix of random numbers using the rand()
function, but subject to the constraint that the absolute value of the
diagonal element (a) must be greater than the sum of the absolute
values of all the other elements in that row. That is -
fabs(a) > sum {from j to n} of (fabs(a[j])
For some reason, I have major brain block over this. My initial
thoughts were to use a do{}-while() loop, but I have since tried
everything and gotten nowhere. My random matrix-filler function
currently looks like this -<snip>

You mean like:

void fill_random(matrix & m) {
for(unsigned row = 0; row < m.size(); ++row) {
double rowtot = 0;
for(unsigned col = 0; col < m.size(); ++col) {
m[row][col] = 2.0 * std::rand() / RAND_MAX - 1;
if(row != col) {
rowtot += std::fabs(m[row][col]);
}
}
do {
double sup = rowtot + 2.0 * std::rand() / RAND_MAX - 1;
double acc = 2.0 * sup * std::rand() / RAND_MAX - sup;
if(std::fabs(acc) > rowtot) {
m[row][row] = acc;
break;
}
} while(true);
}

}/TB



Wow, that works great! Thanks :D But I'm afraid I'm lost with the two
most important lines of the function -

double sup = rowtot + 2.0 * std::rand() / RAND_MAX - 1;
double acc = 2.0 * sup * std::rand() / RAND_MAX - sup;

Well, more particularly, the double sup declaration. Im not sure why
we're multiplying sup and subtracting sup from acc. Is the subtraction
of sub to ensure the fabs() is not zero?


A clearer way of writing it would probably be:

// Extension range [-1,1] to make acc greater than rowtot
// Any value would do as long as it isn't zero, even
// a static value like
// double sup = 0.333; or
// double sup = 1777;
// although then we'd loose the negative range, and vice versa
// It all depends on how greater you want acc to be compared to rowtot
double sup = 2.0 * std::rand() / RAND_MAX - 1;
// Determine sign, ie -1 or +1
double sig = std::floor(sup) + std::ceil(sup);
// Calculte
double acc = (rowtot + std::fabs(sup)) * sig;

/TB
 
A

akaustav

I am also new to this group and I'm just trying to help. Your problem
can be solved using the following function:

void fill_random(matrix m)
{
int i, j;
double summation = 0;

for(i = 0; i < n; ++i)
{
for(j = 0; j < n; ++j)
{
if(i!=j)
{
// Generating the random number
m[j] = 2.0 * rand() / RAND_MAX -
1; // I can't understand why is this line so complicated.

// Finding the sum of all the genereated
numbers
summation += fabs(m[j]);
}
}
// Generate the random number for the diagonal element
over here
do
{
m = 2.0 * rand() / RAND_MAX -
1; // Your random generation line over here.
}
while( fabs(m) <= summation);
}
}

I hope this function works as I haven't tested it in C++. Do tell me
if this works out. I still advice
you to review your random number generator line as I don't think that
line will be able to generate
a number greater than the summation. Therefore I would suggest you to
add a random number to
your summation and write the resultant value in place of the do..while
loop.
 

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,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top