why does it take forever?

G

greenflame

I have the following function. It is supposed to multiply all the
elements of a row of a matrix my a certain factor. I make a matrix with
a list of lists. with each of the inner lists represents a row of a
matrix. So the matrix:

[1 2 3]
[4 5 6]
[7 8 9]

is coded as:

A = [
[1,2,3],
[4,5,6],
[7,8,9]
];

OK now heres the function:

function create2darr(rows,cols) {
output = new Array(rows);
for (i=0;i<rows;i++) {
output = new Array(cols);
}
return output;
}
function copy2darr(input) {
output = create2darr(input.length,input[0].length);
for (i=0;i<input.length;i++) {
for (j=0;j<input[0].length;j++) {
output[j] = input[j];
}
}
return output;
}
function xrow(input,row,factor) {
output = copy2darr(input);
for (i=0;output[row-1].length;i++) {
output[row-1] *= factor;
}
return output;
}
 
R

RobG

greenflame said:
I have the following function. It is supposed to multiply all the
elements of a row of a matrix my a certain factor. I make a matrix with
a list of lists. with each of the inner lists represents a row of a
matrix. So the matrix:

[1 2 3]
[4 5 6]
[7 8 9]

is coded as:

A = [
[1,2,3],
[4,5,6],
[7,8,9]
];

OK now heres the function:

function create2darr(rows,cols) {
output = new Array(rows);
for (i=0;i<rows;i++) {
output = new Array(cols);
}
return output;
}
function copy2darr(input) {
output = create2darr(input.length,input[0].length);
for (i=0;i<input.length;i++) {
for (j=0;j<input[0].length;j++) {
output[j] = input[j];
}
}
return output;
}
function xrow(input,row,factor) {
output = copy2darr(input);
for (i=0;output[row-1].length;i++) {
output[row-1] *= factor;
}
return output;
}


You create matrix A. You create a reference to it called 'input'
when calling the function xrow().

You then create a global variable 'output' that references a row of
A. You then do things with 'output' in other functions that are all
manipulating the same row of A - creating more references so that my
browser runs out of memory and never finishes.

There is no need to be so complex. If all you want to do is multiply
a row of A by some factor, then the following will do the job (note
that I have adjusted the index for rows to start from 1 rather than
zero, that seems to be what you were doing):

function xrow(input,row,factor) {
var j, r = row-1; // Adjust row index
// Make sure matrix and row exist and have length > 0
if ( !input || !input.length
|| !input[r] || !(j = input[r].length) ) {
return;
}
for (var i=0; i<j; i++) {
input[r] *= factor;
}
}

A = [
[1,2,3],
[4,5,6],
[7,8,9]
];

alert(A.join('\n'));
xrow(A,1,5);
alert(A.join('\n'));


Note that when you create A as a global object like this, if you
create a reference to some part of A and change it, then is it A
that is actually being changed.

It's the same as when you use:

x = document.getElementById('blah');

x is a reference to the element with id 'blah'. When you modify x,
you are actually modifying 'blah'.
 
J

Jc

greenflame said:
function xrow(input,row,factor) {
output = copy2darr(input);
for (i=0;output[row-1].length;i++) {
output[row-1] *= factor;
}
return output;
}


So I assume you are seeing the code perform slower than you expect?

Well, JavaScript isn't exactly a speed demon for mathematical
operations, but if you show how you are actually using xrow in an
actual working example, maybe someone can point out some optimizations.

I should also mention that you are likely not intending to create
global var's i and j (among others) in your for loops, which is what
happens when you use a var in a fuction without declaring it using the
var keyword (this does not apply to function parameter names of course).
 
G

greenflame

RobG said:
You create matrix A. You create a reference to it called 'input'
when calling the function xrow().

You then create a global variable 'output' that references a row of
A. You then do things with 'output' in other functions that are all
manipulating the same row of A - creating more references so that my
browser runs out of memory and never finishes.

There is no need to be so complex. If all you want to do is multiply
a row of A by some factor, then the following will do the job (note
that I have adjusted the index for rows to start from 1 rather than
zero, that seems to be what you were doing):

function xrow(input,row,factor) {
var j, r = row-1; // Adjust row index
// Make sure matrix and row exist and have length > 0
if ( !input || !input.length
|| !input[r] || !(j = input[r].length) ) {
return;
}
for (var i=0; i<j; i++) {
input[r] *= factor;
}
}

A = [
[1,2,3],
[4,5,6],
[7,8,9]
];

alert(A.join('\n'));
xrow(A,1,5);
alert(A.join('\n'));


Note that when you create A as a global object like this, if you
create a reference to some part of A and change it, then is it A
that is actually being changed.

It's the same as when you use:

x = document.getElementById('blah');

x is a reference to the element with id 'blah'. When you modify x,
you are actually modifying 'blah'.


ok but I want the function to return a new matrix and leave the
original untouched.
 
R

RobG

greenflame said:
[...]

ok but I want the function to return a new matrix and leave the
original untouched.

Then copy the matrix to a new object first:

function copyMatrix(A){
var j, i=A.length, B = [];
while (i--) {
B= [];
j = A.length;
while ( j-- ){
B[j] = A[j];
}
}
return B;
}

function xrow(input,row,factor) {
var j, r = row-1; // Adjust row index
// Make sure matrix and row exist and have length > 0
if ( !input || !input.length
|| !input[r] || !(j = input[r].length) ) {
return;
}
for (var i=0; i<j; i++) {
input[r] *= factor;
}
}

A = [
[1,2,3],
[4,5,6],
[7,8,9]
];

B = copyMatrix(A);
xrow(B, 1, 5);
alert(A.join('\n'));
alert(B.join('\n'));
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top