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
Username:
Password:
Save Password
Forgot your Password? | Admin Options

 All Forums
 Origin Forum for Programming
 LabTalk Forum
 to optimize this small part of code.
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic

tlab

Japan
34 Posts

Posted - 01/14/2005 :  5:23:41 PM  Show Profile  Edit Topic  Reply with Quote  View user's IP address  Delete Topic
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

Mike Buess

USA
3037 Posts

Posted - 01/14/2005 :  5:49:21 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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
Go to Top of Page

tlab

Japan
34 Posts

Posted - 01/14/2005 :  7:08:05 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Thanks Mike. I will wait for your good solution.

Regards.

tlab

Go to Top of Page

cpyang

USA
1407 Posts

Posted - 01/14/2005 :  11:32:19 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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


Go to Top of Page

rlewis

Canada
253 Posts

Posted - 01/16/2005 :  7:32:51 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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);
}
Go to Top of Page

tlab

Japan
34 Posts

Posted - 01/17/2005 :  11:48:41 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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
Go to Top of Page

easwar

USA
1965 Posts

Posted - 01/17/2005 :  12:13:06 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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.


Go to Top of Page

tlab

Japan
34 Posts

Posted - 01/17/2005 :  12:46:07 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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

Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 01/17/2005 :  12:50:23 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Have you installed Service Release 4?

Mike Buess
Origin WebRing Member
Go to Top of Page

tlab

Japan
34 Posts

Posted - 01/17/2005 :  12:56:34 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
Yes, I did. My Origin version is Origin 7 SR4, v7.0552.

tlab

Go to Top of Page

Mike Buess

USA
3037 Posts

Posted - 01/17/2005 :  1:02:44 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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
Go to Top of Page

Hideo Fujii

USA
1582 Posts

Posted - 01/17/2005 :  1:49:16 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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

Go to Top of Page

easwar

USA
1965 Posts

Posted - 01/17/2005 :  1:55:30 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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

Go to Top of Page

tlab

Japan
34 Posts

Posted - 01/17/2005 :  4:54:59 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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

Go to Top of Page

easwar

USA
1965 Posts

Posted - 01/17/2005 :  4:59:59 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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

Go to Top of Page

tlab

Japan
34 Posts

Posted - 01/17/2005 :  6:38:31 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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

Go to Top of Page

cpyang

USA
1407 Posts

Posted - 01/18/2005 :  05:05:16 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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


Go to Top of Page

tlab

Japan
34 Posts

Posted - 01/18/2005 :  11:18:35 AM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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

Go to Top of Page

easwar

USA
1965 Posts

Posted - 01/18/2005 :  12:30:00 PM  Show Profile  Edit Reply  Reply with Quote  View user's IP address  Delete Reply
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

Go to Top of Page
  Previous Topic Topic Next Topic Lock Topic Edit Topic Delete Topic New Topic Reply to Topic
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
The Origin Forum © 2020 Originlab Corporation Go To Top Of Page
Snitz Forums 2000