Thanks Chris. I sorted the problem out. It had to do with negative values in the square root computation. I don't see a way to fit a circle using PDL::Fit::LM as it is formulated so that I have to provide y(x) explicitly instead of an objective function. Levmar is probably a better choice.
Thanks Ganesh. -----Original Message----- From: Chris Marshall [mailto:[email protected]] Sent: Friday, September 04, 2009 7:47 PM To: Ganesh Krishnan Cc: [email protected] Subject: Re: [Perldl] 2D circle fitting using PDL::Fit::LM Ganesh Krishnan wrote: > Hey all, > > > > I am trying to use the PDL::Fit::LM module to fit a 2D circle to some > data. The equation of a 2D circle is y=(r^2-(x-x0)^2)^0.5+y0. I am > running into problems. I get my guess parameters back as the optimal > parameters. Is there anything that jumps out at you as wrong? I have > appended the code below. You don't seem to be using a value for $r. Sometimes trying out a *very* simple problem or one of the examples can help sort things out. Good luck. --Chris > > Thanks > > Ganesh. > > > > use PDL; > > use PDL::Fit::LM; > > > > my $xdata=pdl [3,0,5]; > > my $ydata=pdl [4,5,0]; > > my $initp=pdl [1,1,1]; > > my $wt=1; > > my ($yf,$pf,$cf,$if) = lmfit $xdata, $ydata, $wt, \&circlefit, $initp, > {Maxiter => 300, Eps => 1e-3}; > > > > print "Parameters are ",$pf,"\n"; > > > > sub circlefit { > > # leave this line as is > > my ($x,$par,$ym,$dyda) = @_; > > > > # $m and $b are fit parameters, internal to this function > > # call them whatever make sense to you, but replace (0..1) > > # with (0..x) where x is equal to your number of fit parameters > > # minus 1 > > my ($x0, $y0, $r) = map { $par->slice("($_)") } (0..2); > > > > # Write function with dependent variable $ym, > > # independent variable $x, and fit parameters as specified above. > > # Use the .= (dot equals) assignment operator to express the > equality > > # (not just a plain equals) > > $ym .= ($r**2 - ($x - $x0)**2)**0.5 + $y0; > > > > # Edit only the (0..1) part to (0..x) as above > > my (@dy) = map {$dyda -> slice(",($_)") } (0..2); > > > > # Partial derivative of the function with respect to first > > # fit parameter ($m in this case). Again, note .= assignment > > # operator (not just "equals") > > $dy[0] .= ($r**2 - ($x - $x0)**2)**(-0.5)*($x - $x0); > > > > # Partial derivative of the function with respect to next > > # fit parameter ($b in this case) > > $dy[1] .= 1; > > $dy[2] .= $r*($r**2 - ($x - $x0)**2)**(-0.5); > > > > # Add $dy[ ] .= () lines as necessary to supply > > # partial derivatives for all floating paramters. > > } _______________________________________________ Perldl mailing list [email protected] http://mailman.jach.hawaii.edu/mailman/listinfo/perldl
