comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » faster minimization needed - maybe mpfit?
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
faster minimization needed - maybe mpfit? [message #79653] Mon, 26 March 2012 06:15 Go to next message
rogass is currently offline  rogass
Messages: 200
Registered: April 2008
Senior Member
Hi folks,
the following expression runs successfully with AMOEBA but requires
for large matrices (columns < 512, rows up to 30000), for small
tolerances (e.g. ftol=1e-06) and a high number of iterations
(nmax>=10000) to converge years:

expr = total(abs(convol(im-rebin(p[*],size(im,/dim),/samp),
[-1.,0.,1.])))

where p is the parameter vector (one row) to be found and im is the
matrix.

Is there a way to do it faster? Maybe with mpfit (I don't get an idea
how...)

Thanks for any help

CR
Re: faster minimization needed - maybe mpfit? [message #79722 is a reply to message #79653] Tue, 27 March 2012 06:38 Go to previous messageGo to next message
Craig Markwardt is currently offline  Craig Markwardt
Messages: 1869
Registered: November 1996
Senior Member
On Tuesday, March 27, 2012 8:28:02 AM UTC-4, chris wrote:
> Hi Craig,
> sorry I made several typos. I would also be satisfied with a least
> squares solution as you can see if you compare function test2 with the
> previous posts. The function I want to minimize is test2. It doesnt
> matter for me at this stage whether total(abs(resid)) or
> total(resid^2) is minimized.
>
> function test2,p,xval=x,errval=err
> resid=convol(x-rebin(p[*],size(x,/dim)),[-1.,0.,1.])
> return,total(resid^2)
> end
>
> ENVI> help,im
> IM INT = Array[512, 7237]
> ENVI> sz=size(im,/dim)
> ENVI> im2=im+fix(1000.*rebin((((add=randomn(seed,sz[0])))-mean(add ))/
> stddev(add),sz))
> ENVI> help,im2
> IM2 INT = Array[512, 7237]
> ENVI> p0=((p0=total(im2,2)/float(sz[1])))-smooth(p0,3,/edge_trunc)
> ENVI> help,p0
> P0 FLOAT = Array[512]
> ENVI> st={x:im2,errval:sqrt(p0)}
> &res=mpfit('test2',p0,functargs=st,maxiter=100,status=st atus,errmsg=errmsg)
> &print,status,string(10b),errmsg
> 0
> ERROR: number of parameters must not exceed data

Check out the documentation for MPFIT. It expects your user function to return a 1D array of residuals, not the sum of squares.

Craig
Re: faster minimization needed - maybe mpfit? [message #79727 is a reply to message #79653] Tue, 27 March 2012 05:28 Go to previous messageGo to next message
rogass is currently offline  rogass
Messages: 200
Registered: April 2008
Senior Member
Hi Craig,
sorry I made several typos. I would also be satisfied with a least
squares solution as you can see if you compare function test2 with the
previous posts. The function I want to minimize is test2. It doesnt
matter for me at this stage whether total(abs(resid)) or
total(resid^2) is minimized.

function test2,p,xval=x,errval=err
resid=convol(x-rebin(p[*],size(x,/dim)),[-1.,0.,1.])
return,total(resid^2)
end

ENVI> help,im
IM INT = Array[512, 7237]
ENVI> sz=size(im,/dim)
ENVI> im2=im+fix(1000.*rebin((((add=randomn(seed,sz[0])))-mean(add ))/
stddev(add),sz))
ENVI> help,im2
IM2 INT = Array[512, 7237]
ENVI> p0=((p0=total(im2,2)/float(sz[1])))-smooth(p0,3,/edge_trunc)
ENVI> help,p0
P0 FLOAT = Array[512]
ENVI> st={x:im2,errval:sqrt(p0)}
&res=mpfit('test2',p0,functargs=st,maxiter=100,status=st atus,errmsg=errmsg)
&print,status,string(10b),errmsg
0
ERROR: number of parameters must not exceed data


THANKS in advance

CR
Re: faster minimization needed - maybe mpfit? [message #79735 is a reply to message #79653] Mon, 26 March 2012 15:36 Go to previous messageGo to next message
Craig Markwardt is currently offline  Craig Markwardt
Messages: 1869
Registered: November 1996
Senior Member
On Monday, March 26, 2012 3:59:41 PM UTC-4, chris wrote:
> On 26 Mrz., 21:04, Craig Markwardt <craig.markwa...@gmail.com> wrote:
>> On Monday, March 26, 2012 9:15:30 AM UTC-4, chris wrote:
>>> Hi folks,
>>> the following expression runs successfully with AMOEBA but requires
>>> for large matrices (columns < 512, rows up to 30000), for small
>>> tolerances (e.g. ftol=1e-06) and a high number of iterations
>>> (nmax>=10000) to converge years:
>>
>>> expr = total(abs(convol(im-rebin(p[*],size(im,/dim),/samp),
>>> [-1.,0.,1.])))
>>
>>> where p is the parameter vector (one row) to be found and im is the
>>> matrix.
>>
>>> Is there a way to do it faster? Maybe with mpfit (I don't get an idea
>>> how...)
>>
>> If you can express your problem as minimize{TOTAL(RESID^2)}, then you can use MPFIT, where RESID is signed.  In your case you can do this, but there's a few little tricks.
>>
>> Your problem looks like minimize{TOTAL(ABS(XXX))}.
>>
>> You might want to define RESID=SQRT(ABS(XXX)), and then in principle it looks like an MPFIT problem.  Unfortunately you need to preserve the sign of XXX.  So this is what you do:
>>   RESID = SIGN(XXX)*SQRT(ABS(XXX))
>> where SIGN(XXX) is the sign of XXX (-1 or +1 depending on XXX).
>>
>> Happy equation solving...
>> Craig
>
> Hi Craig,
> thank you. Nevertheless, I don't think that I understood what you
> suggests. So, i tried this:
>
> function test2,p,x=x,err=err
> temp=convol(x,rebin(p[*],size(x,/dim)))
> return,signum(temp)*sqrt(abs(temp))
> end
>
> But what I got is this:
>
> ENVI> st={x:im}&help,mpfit('test2',functargs=st,maxiter=100)
> <Expression> DOUBLE = NaN
>
> What's wrong?

Problem #1. You need to provide starting values, for P, just like for AMOEBA.

Problem #2. You changed the function. Your residual in your original post was of the form convol(im-rebin(p)). Why did you change it?

Issue #3. Error checking. Use the STATUS and ERRMSG keywords to retrieve more error information about what went wrong.

By the way, are you sure you want to solve a least absolute deviation problem? Or would you be satisfied with a least squares solution? Least squares is so much easier, for example you can use MPFITFUN().

Craig
Re: faster minimization needed - maybe mpfit? [message #79737 is a reply to message #79653] Mon, 26 March 2012 12:59 Go to previous messageGo to next message
rogass is currently offline  rogass
Messages: 200
Registered: April 2008
Senior Member
On 26 Mrz., 21:04, Craig Markwardt <craig.markwa...@gmail.com> wrote:
> On Monday, March 26, 2012 9:15:30 AM UTC-4, chris wrote:
>> Hi folks,
>> the following expression runs successfully with AMOEBA but requires
>> for large matrices (columns < 512, rows up to 30000), for small
>> tolerances (e.g. ftol=1e-06) and a high number of iterations
>> (nmax>=10000) to converge years:
>
>> expr = total(abs(convol(im-rebin(p[*],size(im,/dim),/samp),
>> [-1.,0.,1.])))
>
>> where p is the parameter vector (one row) to be found and im is the
>> matrix.
>
>> Is there a way to do it faster? Maybe with mpfit (I don't get an idea
>> how...)
>
> If you can express your problem as minimize{TOTAL(RESID^2)}, then you can use MPFIT, where RESID is signed.  In your case you can do this, but there's a few little tricks.
>
> Your problem looks like minimize{TOTAL(ABS(XXX))}.
>
> You might want to define RESID=SQRT(ABS(XXX)), and then in principle it looks like an MPFIT problem.  Unfortunately you need to preserve the sign of XXX.  So this is what you do:
>   RESID = SIGN(XXX)*SQRT(ABS(XXX))
> where SIGN(XXX) is the sign of XXX (-1 or +1 depending on XXX).
>
> Happy equation solving...
> Craig

Hi Craig,
thank you. Nevertheless, I don't think that I understood what you
suggests. So, i tried this:

function test2,p,x=x,err=err
temp=convol(x,rebin(p[*],size(x,/dim)))
return,signum(temp)*sqrt(abs(temp))
end

But what I got is this:

ENVI> st={x:im}&help,mpfit('test2',functargs=st,maxiter=100)
<Expression> DOUBLE = NaN

What's wrong?

Thank you

Chris
Re: faster minimization needed - maybe mpfit? [message #79740 is a reply to message #79653] Mon, 26 March 2012 12:04 Go to previous messageGo to next message
Craig Markwardt is currently offline  Craig Markwardt
Messages: 1869
Registered: November 1996
Senior Member
On Monday, March 26, 2012 9:15:30 AM UTC-4, chris wrote:
> Hi folks,
> the following expression runs successfully with AMOEBA but requires
> for large matrices (columns < 512, rows up to 30000), for small
> tolerances (e.g. ftol=1e-06) and a high number of iterations
> (nmax>=10000) to converge years:
>
> expr = total(abs(convol(im-rebin(p[*],size(im,/dim),/samp),
> [-1.,0.,1.])))
>
> where p is the parameter vector (one row) to be found and im is the
> matrix.
>
> Is there a way to do it faster? Maybe with mpfit (I don't get an idea
> how...)

If you can express your problem as minimize{TOTAL(RESID^2)}, then you can use MPFIT, where RESID is signed. In your case you can do this, but there's a few little tricks.

Your problem looks like minimize{TOTAL(ABS(XXX))}.

You might want to define RESID=SQRT(ABS(XXX)), and then in principle it looks like an MPFIT problem. Unfortunately you need to preserve the sign of XXX. So this is what you do:
RESID = SIGN(XXX)*SQRT(ABS(XXX))
where SIGN(XXX) is the sign of XXX (-1 or +1 depending on XXX).

Happy equation solving...
Craig
Re: faster minimization needed - maybe mpfit? [message #79801 is a reply to message #79722] Wed, 28 March 2012 23:45 Go to previous message
rogass is currently offline  rogass
Messages: 200
Registered: April 2008
Senior Member
On 27 Mrz., 15:38, Craig Markwardt <craig.markwa...@gmail.com> wrote:
> On Tuesday, March 27, 2012 8:28:02 AM UTC-4, chris wrote:
>> Hi Craig,
>> sorry I made several typos. I would also be satisfied with a least
>> squares solution as you can see if you compare function test2 with the
>> previous posts. The function I want to minimize is test2. It doesnt
>> matter for me at this stage whether total(abs(resid)) or
>> total(resid^2) is minimized.
>
>> function test2,p,xval=x,errval=err
>> resid=convol(x-rebin(p[*],size(x,/dim)),[-1.,0.,1.])
>> return,total(resid^2)
>> end
>
>> ENVI> help,im
>> IM              INT       = Array[512, 7237]
>> ENVI> sz=size(im,/dim)
>> ENVI> im2=im+fix(1000.*rebin((((add=randomn(seed,sz[0])))-mean(add ))/
>> stddev(add),sz))
>> ENVI> help,im2
>> IM2             INT       = Array[512, 7237]
>> ENVI> p0=((p0=total(im2,2)/float(sz[1])))-smooth(p0,3,/edge_trunc)
>> ENVI> help,p0
>> P0              FLOAT     = Array[512]
>> ENVI> st={x:im2,errval:sqrt(p0)}
>> &res=mpfit('test2',p0,functargs=st,maxiter=100,status=st atus,errmsg=errmsg)
>> &print,status,string(10b),errmsg
>>            0
>> ERROR: number of parameters must not exceed data
>
> Check out the documentation for MPFIT.  It expects your user function to return a 1D array of residuals, not the sum of squares.
>
> Craig

Dear Craig,
now it works perfect. Thank you!

CR
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Cellular automata
Next Topic: IDL and PV wave language free

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 15:16:51 PDT 2025

Total time taken to generate the page: 0.00822 seconds