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 for Programming
 LabTalk Forum
 to optimize this small part of 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
tlab Posted - 01/14/2005 : 5:23:41 PM
Origin Version (Select Help-->About Origin): 7
Operating System:Win2000

I am trying to remove those four corners from a square matrix, and make it a circle. Method is simple, just check if its position satisfies:
(x-x0)^2+(y-y0)^2 <=r^2
but it works really slow. In the case of 300x300 matrix, it will take almost 10min to remove those corners. Is it possible to optimize it further? Here is codes:

[main]

matrix -pg DIM colNo rowNo;

if (colNo<=rowNo) minNo=colNo;
else minNo=rowNo;

radius=minNo/2;
squ=radius^2;
loop(ii, 1, minNo)

{
loop(jj, 1, minNo)

{ if (((ii-radius)^2 + (jj-radius)^2) >= squ)
cell(ii,jj)=0;
};
};


Thank you very much.

tlab

18   L A T E S T    R E P L I E S    (Newest First)
easwar Posted - 01/18/2005 : 12:30:00 PM
quote:

So what else files such as internal.c I should add to that System folder?



Hi tlab,

Include internal.c, matrix.c and sys_utils.c in your System folder. The first two can be found under OriginC\system subfolder and the third one under OriginC\OriginLab subfolder.

What is in temp subfolder is not important. Typically files are added there temporarily when they are loaded and compiled programmatically.

Easwar
OriginLab

tlab Posted - 01/18/2005 : 11:18:35 AM
Thanks, it is cool. After I close codebuilder, it is only 3.8sec in my computer. That is really good enough to me.

Thanks, guys.

tlab

cpyang Posted - 01/18/2005 : 05:05:16 AM
quote:
Now it work. only 8.42s to do so



I think you must have kept Code Builder when executing, as my test showed 2.4 sec. Origin C runs faster if Code Buidler is closed. When Code Builder is open, you can hit ESC key and Origin C will pause at the line being executed, and this debugging trick will slow things down, and thus we turn this ESC checking off if Code Builder is close and as a result, you can control to run Origin C faster by closing Code Builder.

CP


tlab Posted - 01/17/2005 : 6:38:31 PM
haha, you guys are great. Now it work. only 8.42s to do so. Compared with previous 10 min, it is hard to believe :-)

That is my stupid mistake. I deleted all files under
Origin C workspace\Systemand Temporary
So what else files such as internal.c I should add to that System folder?

Thanks again. Now it is time for me to learn these code and OriginC...

tlab

easwar Posted - 01/17/2005 : 4:59:59 PM
Hi tlab,

When you get a message like that it means the compiler found the prototype (header file) for the function, but could not locate the body of the function and so cannot link.

The function min() is located in the file internal.c - this file is usually part of your workspace and should be present in the System branch of Code Builder. For some reason it may be absent in your code builer workspace. So just go to Code Builder, right-click on the System branch, then select Add Files, and then locate the internal.c file from the \OriginC\System subfolder and add it to workspace and then do a Build All.

Easwar
OriginLab

tlab Posted - 01/17/2005 : 4:54:59 PM
yes, you guys are great. Thanks. now it could be compiled. but during linking, I met another problem as below:

----
Linking...
C:\Program Files\OriginLab\Origin70\OriginC\mkcircle.c(12) :Error, Function min@HAHAHA was called, but its body could not be located during linking.
Linking Failed!
----

min@HAHAHA? looks like a virus?

tlab

easwar Posted - 01/17/2005 : 1:55:30 PM
Hi tlab,

I'm pretty sure this is what is going on:

When you started the file, you created a new file with extension .cpp. What happens in this case is you get a blank page with no template information, so there is no #include statement. Then you changed the file name to .c, but the #include statement was still missing, and thus you get the compile error.

So to fix the problem, open your .c file and then add
#include <origin.h>
at the top and compile again, and then it should work.

So in the future, when you add a new file, use the .c and it will automatically have the #include statement in it, which is part of a template used for .c files.

By the way, if the #include is present, even if the file is named .cpp, it will compile. But it is recommended that you use .c instead of .cpp for routine Origin C functions that do not involve user-defined classes etc.

Easwar
OriginLab

Hideo Fujii Posted - 01/17/2005 : 1:49:16 PM
It's just a guessing....

You didn't have:
#include <origin.h>
at the first line of the program. This is the
standard header file for Origin C.

Not that case?

--Hideo
OriginLab

Mike Buess Posted - 01/17/2005 : 1:02:44 PM
Not sure what to suggest then. I copied CP's code into test.c and it compiled fine in 7.0 SR4.

Mike Buess
Origin WebRing Member
tlab Posted - 01/17/2005 : 12:56:34 PM
Yes, I did. My Origin version is Origin 7 SR4, v7.0552.

tlab

Mike Buess Posted - 01/17/2005 : 12:50:23 PM
Have you installed Service Release 4?

Mike Buess
Origin WebRing Member
tlab Posted - 01/17/2005 : 12:46:07 PM
It seems same error in my computer after I changed its name:
-------------
compiling...
mkcircle.c
C:\Program Files\OriginLab\Origin70\OriginC\mkcircle.c(1) :Error, General Error ( ) contact TD.
C:\Program Files\OriginLab\Origin70\OriginC\mkcircle.c(1) :Error, error(s) found in compiling method
C:\Program Files\OriginLab\Origin70\OriginC\mkcircle.c(3) :Error, General Error ( ) contact TD.
C:\Program Files\OriginLab\Origin70\OriginC\mkcircle.c(3) :Error, general compile error
C:\Program Files\OriginLab\Origin70\OriginC\mkcircle.c(1) :Error, error(s) found in compiling function mkcircle

Compiling errors found, linking cannot start!
------------
Anything wrong?

tlab

easwar Posted - 01/17/2005 : 12:13:06 PM
Hi tlab,

Please try again by naming the file as mkcircle.c and not mkcircle.cpp. I tried in version 7SR4 and it compiled and ran file.
I did not try Ruthven's solution yet.

As for finding out how much time it takes to execute, once the function is compiled and linked, you can go to script window and execute it such as below:

sec; mkcircle; watch;

Highlight this entire line and hit Enter. So you just need to place the OC function call/name between a sec and a watch command.

Easwar
OriginLab

P.S.: The .cpp extension should be used only if you are extending the class structure of Origin C, or using Dialog Builder etc.


tlab Posted - 01/17/2005 : 11:48:41 AM
Thanks, guys. It is amazing to see OriginC can do so in only a few seconds. Let me learn and try.

This is first time for me to try OriginC. I just copy your code (cpyang's code) then paste to codebuilder, save as a mkcircle.c. when I try to build it, it gives following error:
------------------
compiling...
mkcircle.cpp
C:\Program Files\OriginLab\Origin70\OriginC\mkcircle.cpp(1) :Error, General Error ( ) contact TD.
C:\Program Files\OriginLab\Origin70\OriginC\mkcircle.cpp(1) :Error, error(s) found in compiling method
C:\Program Files\OriginLab\Origin70\OriginC\mkcircle.cpp(3) :Error, General Error ( ) contact TD.
C:\Program Files\OriginLab\Origin70\OriginC\mkcircle.cpp(3) :Error, general compile error
C:\Program Files\OriginLab\Origin70\OriginC\mkcircle.cpp(1) :Error, error(s) found in compiling function mkcircle

Compiling errors found, linking cannot start!
------------

So anything wrong with me?

By the way, could you please add some code so that I can see how much time it takes?

Thanks a lot.

tlab



Edited by - tlab on 01/17/2005 11:49:21 AM
rlewis Posted - 01/16/2005 : 7:32:51 PM
Here is another OriginC solution ...
The code is lot longer than that posted by CP but it executes about four times as fast ...

 
bool MakeMatrixCircle(Matrix &mMat, double dOutsideVal = 0)
{
if(mMat.IsValid())
{
int nCols=mMat.GetNumCols();
int nRows=mMat.GetNumRows();
int i, nCells;
if(nRows>1 && nCols>1)
{
vector vctCol;
nCells=nCols;
if(nRows!=nCols)
{
if(nRows<nCols)
{
for(i=nRows;i<nCols;i++)
{
if(mMat.GetColumn(vctCol,i)==false) return (false);
vctCol*=0;
vctCol+=dOutsideVal;
if(mMat.SetColumn(vctCol,i)!=0) return (false);
}
nCells=nRows;
}
else
{
for(i=nCols;i<nRows;i++)
{
if(mMat.GetRow(vctCol,i)==false) return (false);
vctCol*=0;
vctCol+=dOutsideVal;
if(mMat.SetRow(vctCol,i)!=0) return (false);
}
nCells=nCols;
}
}
double Radius=nCells-1;
Radius/=2;
double Rsq=Radius^2;
double *RSQ;
RSQ=&Rsq;
int nHalf;
vector vctMaskMult, vctMaskAdd;
if(is_odd(nCells)==true)
{
nHalf=1+((nCells-1)/2);
}
else
{
nHalf=nCells/2;
}
int k=nCols-1;
double *repVal;
double repValue=dOutsideVal;
repVal=&repValue;
progressBox progBox("Modifying Matrix ... ",PBOX_TOPMOST);
progBox.SetRange(0,nHalf);
vctMaskMult.SetSize(nCells);
vctMaskAdd.SetSize(nCells);
double *vctAdd, *vctAdd1, *vctMult, *vctMult1;
for(i=0;i<nHalf;i++)
{
progBox.Set(i);
if(mMat.GetColumn(vctCol,i)==false) return (false);
vctAdd=&vctMaskAdd[0];
vctMult=&vctMaskMult[0];
vctAdd1=&vctMaskAdd[nCells-1];
vctMult1=&vctMaskMult[nCells-1];
double cVal=i+1;
double *RCval, rcVal=(Radius-cVal)^2;
RCval=&rcVal;
for(int j=0;j<nHalf;j++)
{
double rVal=j+1;
if((*RSQ)<=(((Radius-rVal)^2)+(*RCval)))
{
*vctMult=0;
*vctMult1=0;
*vctAdd=*repVal;
*vctAdd1=*repVal;
}
else
{
*vctMult=1;
*vctAdd=0;
*vctMult1=1;
*vctAdd1=0;
}
vctMult++;
vctAdd++;
vctMult1--;
vctAdd1--;
}
vctCol*=vctMaskMult;
vctCol+=vctMaskAdd;
if(mMat.SetColumn(vctCol,i)!=0) return (false);
if(mMat.GetColumn(vctCol,k)==false) return (false);
vctCol*=vctMaskMult;
vctCol+=vctMaskAdd;
if(mMat.SetColumn(vctCol,k)!=0) return (false);
k--;
}
return (true);
}
}
return (false);
}
cpyang Posted - 01/14/2005 : 11:32:19 PM
As Mike might be busy, here is a simple Origin C program that will do the job, I tried in my notebook and it took 2.4 sec with CodeBuilder closed.



void mkcircle(double dOutsideVal = 0)
{
MatrixLayer ml = Project.ActiveLayer();

Matrix mm(ml);
int nRows = mm.GetNumRows();
int nCols = mm.GetNumCols();
int nrc = 0.5 + nRows/2.0; // nearest int
int ncc = 0.5 + nCols/2.0;
double rr = min(nrc, ncc);

for(int nr = 0; nr < nRows; nr++)
{
for(int nc = 0; nc < mm.GetNumCols(); nc++)
{
double xsqr = (nr - nrc)^2;
double ysqr = (nc - ncc)^2;
if(sqrt(xsqr + ysqr) > rr)
{
mm[nr][nc] = dOutsideVal;
}
}
}
}



CP


tlab Posted - 01/14/2005 : 7:08:05 PM
Thanks Mike. I will wait for your good solution.

Regards.

tlab

Mike Buess Posted - 01/14/2005 : 5:49:21 PM
Hi tlab,

Although there is probably some room for improvement in your LabTalk script, Origin C is much better suited for this task. I'll look into it after dinner and will try to post an Origin C solution by tomorrow morning.

Mike Buess
Origin WebRing Member

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