The Origin Forum
File Exchange
Try Origin for Free
The Origin Forum
Home | Profile | Register | Active Topics | Members | Search | FAQ | Send File to Tech support
 All Forums
 Origin Forum
 Origin Forum
 faster code

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

Screensize:
UserName:
Password:
Anti-Spam Code:
Format Mode:
Format: BoldItalicizedUnderlineStrikethrough Align LeftCenteredAlign Right Horizontal Rule Insert HyperlinkUpload FileInsert Image Insert CodeInsert QuoteInsert List
   
Message:

* HTML is OFF
* Forum Code is ON
Smilies
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Clown [:o)]
Black Eye [B)] Eight Ball [8] Frown [:(] Shy [8)]
Shocked [:0] Angry [:(!] Dead [xx(] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
bjorn Posted - 07/05/2000 : 8:24:00 PM
Iīm trying to speed up my calculations by converting to vector notation. Unfortunately I canīt think of any way to work around nested expressions like when in a for-loop, adding the difference between two adjacent cells to another column. Eg.
for(ii=1;ii<1000;ii++)
{
dt=col(1)[ii]-col(1)[ii-1]; col(3)=col(2)[ii]*dt;
}

By the way a useful function would be some sort of "code-optimizer", automatically giving a suggestion for faster code!

Thanks,
bjorn

5   L A T E S T    R E P L I E S    (Newest First)
Jose Posted - 02/06/2002 : 07:59:41 AM
Thank you for your suggestion!

andreas1 Posted - 02/06/2002 : 04:39:38 AM
Hi,

you should be able to use an approach similar to Mike and a temporary dataset.
For an example see below. I have increased the counter so that the difference in time is more apparent.

// Initialize data1_a with row numbers
for (n=1;n<2000;n++)
{ data1_a[n]=n; };
// Calculation using loop
sec -e;
for (n=1;n<1000;n++)
{ data1_b[n]=data1_a[n]; };
for (n=1000;n<2000;n++)
{
data1_b[n]=data1_a[n]^2; };
sec -e elapsed;
type "Elapsed time for loop: $(elapsed,.5) seconds";
// Calculation using vector
sec;
// Create temp vector of size 1000
create tmpvec -n 1000;
// Copy first interval into tmpvec;
copy -b 1 data1_a tmpvec -b 1 -e 999;
tmpvec *= 1; // Perform some calculation (not really needed here)
// Copy tmpvec into data1_b starting at 1
copy -b 1 tmpvec data1_b -b 1 -e 999;
// Copy second interval into tmpvec
copy -b 1000 data1_a tmpvec -b 1 -e 1000;
tmpvec *= tmpvec; // Perform calculation
// Copy tmpvec to data1_b starting at 1000
copy -b 1 tmpvec data1_b -b 1000 -e 1999;
// delete tmpvec
del tmpvec;
sec -e elapsed;
type "Elapsed time for vector: $(elapsed,.5) seconds";

Elapsed time for loop: 0.85100 seconds
Elapsed time for vector: 0.0100 seconds

Cheers,

Andreas


Jose Posted - 02/05/2002 : 2:28:27 PM
Is there any way to use vector notation only applied to a selected range of datasets?

Or equivalently, how would you do this in vector notation?


for (n=1;n<20;n++) {
data1_a[n]=n; data1_b[n]=data1_a[n];
}

for (n=20;n<40;n++) {
data1_a[n]=n; data1_b[n]=data1_a[n]^2;
}


One way could be calculating the datasets in another column, then copying the results to the desired position in the final dataset. But one would be able to use the 'set' command somehow to define aplication range...
Mike Buess Posted - 07/05/2000 : 8:50:00 PM
To convert your example to vector notation, first move the multiplication operation outside of the for-loop:

for(ii=1;ii<1000;ii++)
{
col(3)[ii]=col(1)[ii]-col(1)[ii-1];
};
col(3)*=col(2);

Then eliminate the for-loop entirely by using the copy command:

copy -b 1 col(1) col(3) -b 2 -e 999;
// col(3) will be a copy of col(1) with the cells offset by one row
// and the subtractions can now be performed using vector notation
col(3)*=-1; col(3)+=col(1);
col(3)*=col(2);

Hope that helps,
Mike

greg Posted - 07/05/2000 : 8:11:00 PM
Mike does a good job of illustrating how vector notation (operating on an entire dataset) can speed up scripts, but there are some problems with bjorn's script that should be pointed out.

The notation:

col(3)=col(2)(ii)*dt;

is referred to as 'mixed notation' because we are using vector notation on the left side and scalar notation on the right side. This would be very slow because Origin would assign the scalar value calculated on the right to every member of the vector (array) on the left with each pass through the loop - resulting in both the wrong answer and long delays. The correct notation should be:

col(3)[ii]=col(2)[ii]*dt;

Comparing all scripts:


sec;
for(ii=1;ii<1000;ii++)
{
dt=col(1)[ii]-col(1)[ii-1];
col(3)=col(2)[ii]*dt;
}
sec -e elapsed;
type Bjorn's Script takes $(elapsed) seconds;
type;
sec;
for(ii=1;ii<1000;ii++)
{
dt=col(1)[ii]-col(1)[ii-1];
col(3)[ii]=col(2)[ii]*dt;
}
sec -e elapsed;
type Bjorn's corrected script takes $(elapsed) seconds;
type;
sec;
copy -b 1 col(1) col(3) -b 2 -e 999;
col(3)*=-1;
col(3)+=col(1);
col(3)*=col(2);
sec -e elapsed;
type Mike's script takes $(elapsed) seconds;
type;

results in:


Bjorn's Script takes 2.319 seconds

Bjorn's corrected script takes 1.723 seconds

Mike's script takes 0.006 seconds



I should point out that Origin has a built-in function that finds the differences between rows of data, but since it offsets the results by one row it would yield a different result and since it internally creates a temporary dataset it doesn't have as much speed advantage as Mike's use of operator assignment notation which works 'in-place' on the data without the overhead of new memory allocation. Here is an example of the DIFF() function in use:


sec;
col(3)=diff(col(1));
col(3)*=col(2);
sec -e elapsed;
type My script takes $(elapsed) seconds;
type;

which results in:


My script takes 0.006 seconds

(See Note)


Again, I am not calculating the same values as Bjorn or Mike, and I only mean to illustrate the DIFF() function.



Note: Times on PII -233 system.

The Origin Forum © 2020 Originlab Corporation Go To Top Of Page
Snitz Forums 2000