<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
  <title></title>
</head>
<body text="#000000" bgcolor="#ffffff">
Pablo,<br>
<br>
The code is small enough that I will just include it here, after my
signature. <br>
There are mods to adjust.c and optimise.c.&nbsp; In adjust.c, I replace
fcnPano and<br>
introduce a function newDistSphere, logically replacing the old
distSphere.<br>
In optimise.C, I allocate o-&gt;numData*2 function slots instead of
o-&gt;numData.<br>
<br>
Replies to your other comments interspersed below...<br>
<br>
Pablo d'Angelo wrote:<br>
<blockquote type="cite" cite="mid20040426212017.GA873@svalbart">
  <pre wrap="">On Mon, 26 Apr 2004, Littlefields - Rik, Janis, Kyle &amp; Peter wrote:

  </pre>
  <blockquote type="cite">
    <pre wrap="">Briefly, I have working prototype code that changes the way that the 
lmdif optimizer is called.  The original code seeks to optimize distance 
squared, where distance is what lmdif sees.  My mods also seek to 
optimize distance squared, but the formulation is to optimize dx^2 + 
dy^2, where dx and dy are what lmdif sees.

The change in formulation gives lmdif better information about how to 
change the parameters, leading to faster and more accurate convergence.

But of course there are wrinkles dealing with wraparound and near-polar 
points, and I would like to tap into whatever other people know about 
the optimizer, to be sure that I don't mess things up..
    </pre>
  </blockquote>
  <pre wrap=""><!---->
I think panotools uses angular differences (for normal control points), and
its probably a not good idea to split the spherical coordinates and use them
like they where normal cartesian coordinates, at least near the poles.
  </pre>
</blockquote>
Yes, it appears to be using latitude/longitude style coordinates.&nbsp;
These can be<br>
handled by scaling longitude by sin(latitude) [in 0..pi], then treating
as normal cartesian.<br>
See the code for details.<br>
<blockquote type="cite" cite="mid20040426212017.GA873@svalbart">
  <blockquote type="cite">
    <pre wrap="">If you have experience with the guts of adjust.c and are willing to 
share it, please chime in.
    </pre>
  </blockquote>
  <pre wrap=""><!---->
Sounds very interesting. I'm still thinking about adding a (optional)
penalty for the HFOV optimisation, so that it becomes possible to optimise
it for partial panos as well.
  </pre>
</blockquote>
I regularly use HFOV optimization for partial panos, but yes, there are
lots<br>
of pits to fall into.&nbsp; We should split this topic off to a separate
thread.<br>
<blockquote type="cite" cite="mid20040426212017.GA873@svalbart">
  <pre wrap="">
Can you post you code, or the patches, so that we can see exactly what you
modified.

ciao
  Pablo 
  </pre>
</blockquote>
Current code follows, in Textpad Compare Files format.<br>
<br>
Best regards,<br>
--Rik<br>
<br>
Compare: (&lt;)C:\Rik\PanoramaTools2.6.ML12\PanoTools\Sources\adjust.c
(59753 bytes)<br>
&nbsp;&nbsp; with:
(&gt;)C:\Rik\PanoramaTools2.6.ML12_beforeHacking\PanoTools\Sources\adjust.c
(55785 bytes)<br>
<br>
1246d1246<br>
&lt; #if 0 // old version, replaced by Rik Littlefield<br>
1323,1484d1322<br>
&lt; #endif<br>
&lt; <br>
&lt; /* ---- Revision history ----<br>
&lt; <br>
&lt;&nbsp;&nbsp;&nbsp; 04/26/2004, Rik Littlefield, reworked fcnPano and newDistSphere
to expose dx and dy<br>
&lt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; separately to the optimizer (e.g.lmdif).<br>
&lt; */<br>
&lt; <br>
&lt; // Angular Distance of Control point "num"<br>
&lt; <br>
&lt; void newDistSphere (int num, double cdiff[2]) {<br>
&lt; &nbsp;&nbsp;&nbsp; double &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; x, y ; &nbsp;&nbsp;&nbsp; // Coordinates of control point in
panorama<br>
&lt; &nbsp;&nbsp;&nbsp; double&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; w2, h2;<br>
&lt; &nbsp;&nbsp;&nbsp; int j;<br>
&lt; &nbsp;&nbsp;&nbsp; Image sph;<br>
&lt; &nbsp;&nbsp;&nbsp; int n[2];<br>
&lt; &nbsp;&nbsp;&nbsp; struct &nbsp;&nbsp;&nbsp; MakeParams&nbsp;&nbsp;&nbsp; mp;<br>
&lt; &nbsp;&nbsp;&nbsp; struct&nbsp; fDesc &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; stack[15];<br>
&lt; &nbsp;&nbsp;&nbsp; double lat[2], lon[2];&nbsp; // latitude &amp; longitude, in degrees<br>
&lt; &nbsp;&nbsp;&nbsp; double dlon;<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; // Get image position in imaginary spherical image<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; SetImageDefaults( &amp;sph );<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; sph.width &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; = 360;<br>
&lt; &nbsp;&nbsp;&nbsp; sph.height &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; = 180;<br>
&lt; &nbsp;&nbsp;&nbsp; sph.format&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; = _equirectangular;<br>
&lt; &nbsp;&nbsp;&nbsp; sph.hfov&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; = 360.0;<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; n[0] = g-&gt;cpt[num].num[0];<br>
&lt; &nbsp;&nbsp;&nbsp; n[1] = g-&gt;cpt[num].num[1];<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; // Calculate coordinates x/y in panorama<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; for(j=0; j&lt;2; j++){<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; SetInvMakeParams( stack, &amp;mp, &amp;g-&gt;im[ n[j] ],
&amp;sph, 0 );<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; h2 &nbsp;&nbsp;&nbsp; = (double)g-&gt;im[ n[j] ].height / 2.0 - 0.5;<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; w2&nbsp;&nbsp;&nbsp; = (double)g-&gt;im[ n[j] ].width&nbsp; / 2.0 - 0.5;<br>
&lt; <br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; execute_stack( &nbsp;&nbsp;&nbsp; (double)g-&gt;cpt[num].x[j] - w2,&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; // cartesian x-coordinate src<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (double)g-&gt;cpt[num].y[j] - h2,&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
// cartesian y-coordinate src<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &amp;x, &amp;y, stack);<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; x = DEG_TO_RAD( x );<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; y = DEG_TO_RAD( y ) + PI/2.0;<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // x is now in the range -PI to +PI, and y is 0 to PI<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lat[j] = y;<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lon[j] = x;<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; }<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; dlon = lon[0]-lon[1];<br>
&lt; &nbsp;&nbsp;&nbsp; if (dlon &lt;= -PI) dlon += PI;<br>
&lt; &nbsp;&nbsp;&nbsp; if (dlon &gt;= PI) dlon -= PI;<br>
&lt; &nbsp;&nbsp;&nbsp; cdiff[0] = (dlon*sin(0.5*(lat[0]+lat[1]))) * g-&gt;pano.width
/ ( 2.0 * PI );<br>
&lt; &nbsp;&nbsp;&nbsp; cdiff[1] = (lat[0]-lat[1]) * g-&gt;pano.width / ( 2.0 * PI );<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; return;<br>
&lt; <br>
&lt; }<br>
&lt; <br>
&lt; <br>
&lt; // Levenberg-Marquardt function measuring the quality of the fit
in fvec[]<br>
&lt; <br>
&lt; int fcnPano(m,n,x,fvec,iflag)<br>
&lt; int m,n;<br>
&lt; int *iflag;<br>
&lt; double x[],fvec[];<br>
&lt; {<br>
&lt; #pragma unused(n)<br>
&lt; &nbsp;&nbsp;&nbsp; int i;<br>
&lt; &nbsp;&nbsp;&nbsp; static int numIt;<br>
&lt; &nbsp;&nbsp;&nbsp; double result;<br>
&lt; &nbsp;&nbsp;&nbsp; int iresult;<br>
&lt; &nbsp;&nbsp;&nbsp; double cdiff[2];<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; if( *iflag == -100 ){ // reset<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; numIt = 0;<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; infoDlg ( _initProgress, "Optimizing Variables" );<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&lt; &nbsp;&nbsp;&nbsp; }<br>
&lt; &nbsp;&nbsp;&nbsp; if( *iflag == -99 ){ //<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; infoDlg ( _disposeProgress, "" );<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&lt; &nbsp;&nbsp;&nbsp; }<br>
&lt; <br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; if( *iflag == 0 )<br>
&lt; &nbsp;&nbsp;&nbsp; {<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; char message[256];<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result = 0.0;<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for( i=0; i &lt; m; i++)<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result += fvec[i]*fvec[i] ;<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result = sqrt( result/ (double)m );<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sprintf( message, "Average Difference between
Controlpoints \nafter %d iteration(s): %25.15g pixels",
numIt,result);//average);<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; numIt += 10;<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if( !infoDlg ( _setProgress,message ) )<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *iflag = -1;<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return 0;<br>
&lt; &nbsp;&nbsp;&nbsp; }<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; // Set Parameters<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; SetAlignParams( x ) ;<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; // Calculate distances<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; iresult = 0;<br>
&lt; &nbsp;&nbsp;&nbsp; for( i=0; i &lt; g-&gt;numPts; i++){<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int j;<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; switch(g-&gt;cpt[i].type){<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // For ordinary control points, return the x- and
y-errors<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // separately.<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; case 0: newDistSphere(i,cdiff);<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fvec[iresult] = cdiff[0];<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fvec[iresult+1] = cdiff[1];<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // For horizontal, vertical, and line control points,<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // include two copies of the single distance result.<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Note that we return distance, not distance squared.<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // The optimizer will handle the squaring.<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; case 1:<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; case 2: fvec[iresult] = sqrt(distSquared(i));<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fvec[iresult+1] = fvec[iresult];<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; default:for(j=0; j&lt;g-&gt;numPts; j++){<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(j!=i &amp;&amp; g-&gt;cpt[i].type ==
g-&gt;cpt[j].type){<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fvec[iresult] = sqrt(distLine(i,j));<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fvec[iresult+1] = fvec[iresult];<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; iresult += 2;<br>
&lt; &nbsp;&nbsp;&nbsp; }<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; // If not enough control points are provided, then fill out<br>
&lt; &nbsp;&nbsp;&nbsp; // the function vector with copies of the average error<br>
&lt; &nbsp;&nbsp;&nbsp; // for the actual control points.&nbsp; This is really just staving<br>
&lt; &nbsp;&nbsp;&nbsp; // off disaster, since we have an underdetermined system,<br>
&lt; &nbsp;&nbsp;&nbsp; // but if we've gotten this far down, it's really about all<br>
&lt; &nbsp;&nbsp;&nbsp; // we can do.<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; result = 0.0;<br>
&lt; &nbsp;&nbsp;&nbsp; for (i=0; i &lt; iresult; i++) {<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; result += fvec[i]*fvec[i];<br>
&lt; &nbsp;&nbsp;&nbsp; }<br>
&lt; &nbsp;&nbsp;&nbsp; result = sqrt(result/(double)iresult);<br>
&lt; &nbsp;&nbsp;&nbsp; for (i=iresult; i &lt; m; i++) {<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fvec[i] = result;<br>
&lt; &nbsp;&nbsp;&nbsp; }<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; return 0;<br>
&lt; }<br>
<br>
Compare:
(&lt;)C:\Rik\PanoramaTools2.6.ML12\PanoTools\Sources\optimize.c (9861
bytes)<br>
&nbsp;&nbsp; with:
(&gt;)C:\Rik\PanoramaTools2.6.ML12_beforeHacking\PanoTools\Sources\optimize.c
(9414 bytes)<br>
<br>
33,42c33,36<br>
&lt; &nbsp;&nbsp;&nbsp; // PrintError("RunLMOptimizer");<br>
&lt; &nbsp;&nbsp;&nbsp; LM.n = o-&gt;numVars;<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; // We assume here that each control point contributes two
functions to be optimized.<br>
&lt; &nbsp;&nbsp;&nbsp; // For ordinary control points, these functions are the X- and
Y-coordinate errors.<br>
&lt; &nbsp;&nbsp;&nbsp; // Horizontal, vertical, and line control points each
contribute only a single<br>
&lt; &nbsp;&nbsp;&nbsp; // function logically, but fcnPano (in adjust.c) replicates
these to consistently<br>
&lt; &nbsp;&nbsp;&nbsp; // provide two functions per control point.<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; if( o-&gt;numData*2 &lt; LM.n )<br>
---<br>
&gt; <br>
&gt; &nbsp;&nbsp;&nbsp; LM.n = o-&gt;numVars;<br>
&gt; &nbsp;&nbsp;&nbsp; <br>
&gt; &nbsp;&nbsp;&nbsp; if( o-&gt;numData &lt; LM.n )<br>
46d40<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PrintError("You have too few control points or too many
parameters.&nbsp; Expect strange values!");<br>
50c43<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; LM.m &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; = o-&gt;numData*2;<br>
---<br>
&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; LM.m &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; = o-&gt;numData;<br>
134,137c127,129<br>
&lt; &nbsp;&nbsp;&nbsp; // PrintError("RunBROptimizer");<br>
&lt; &nbsp;&nbsp;&nbsp; LM.n = o-&gt;numVars;<br>
&lt; <br>
&lt; &nbsp;&nbsp;&nbsp; if( o-&gt;numData*2 &lt; LM.n )<br>
---<br>
&gt; &nbsp;&nbsp;&nbsp; LM.n = o-&gt;numVars;<br>
&gt; &nbsp;&nbsp;&nbsp; <br>
&gt; &nbsp;&nbsp;&nbsp; if( o-&gt;numData &lt; LM.n )<br>
143c135<br>
&lt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; LM.m &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; = o-&gt;numData*2;<br>
---<br>
&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; LM.m &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; = o-&gt;numData;<br>
<br>
<br>
</body>
</html>