LCOV - code coverage report
Current view: top level - synthesis/MeasurementComponents - SteepestDescentSolver.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 225 0.0 %
Date: 2024-10-09 13:55:54 Functions: 0 5 0.0 %

          Line data    Source code
       1             : //# ConjugateGradientSolver.cc: Implementation of an iterative ConjugateGradientSolver
       2             : //# Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003
       3             : //# Associated Universities, Inc. Washington DC, USA.
       4             : //#
       5             : //# This library is free software; you can redistribute it and/or modify it
       6             : //# under the terms of the GNU Library General Public License as published by
       7             : //# the Free Software Foundation; either version 2 of the License, or (at your
       8             : //# option) any later version.
       9             : //#
      10             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      11             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      13             : //# License for more details.
      14             : //#
      15             : //# You should have received a copy of the GNU Library General Public License
      16             : //# along with this library; if not, write to the Free Software Foundation,
      17             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      18             : //#
      19             : //# Correspondence concerning AIPS++ should be adressed as follows:
      20             : //#        Internet email: casa-feedback@nrao.edu.
      21             : //#        Postal address: AIPS++ Project Office
      22             : //#                        National Radio Astronomy Observatory
      23             : //#                        520 Edgemont Road
      24             : //#                        Charlottesville, VA 22903-2475 USA
      25             : //#
      26             : //#
      27             : //# $Id: ConjugateGradientSolver.cc,v 1.4 2006/05/02 15:59:22 sbhatnag Exp $
      28             : 
      29             : #include <synthesis/MeasurementComponents/SteepestDescentSolver.h>
      30             : #include <synthesis/TransformMachines/Utils.h>
      31             : #include <casacore/casa/Arrays/MatrixMath.h>
      32             : #include <limits>
      33             : 
      34             : using namespace casacore;
      35             : namespace casa {
      36             : 
      37           0 :   SteepestDescentSolver::SteepestDescentSolver(Int nParams,Vector<Int> polMap,
      38           0 :                                                Int nIter, Double tol):
      39           0 :     Iterate(), polMap_p(polMap)
      40             :   {
      41           0 :     setNumberIterations(nIter);
      42           0 :     setTolerance(tol);
      43           0 :     setMaxParams(nParams);
      44           0 :   };
      45             :   //
      46             :   //---------------------------------------------------------------------------
      47             :   // Get a vector of visibilities from all baselines with antenna
      48             :   // whichAnt.  It returns N-1 values (fills in the complex conjugate
      49             :   // part as well).
      50             :   //
      51           0 :   Vector<Complex> SteepestDescentSolver::getVj(const VisBuffer& vb, Int NAnt, Int whichAnt,
      52             :                                                Int whichPol,
      53             :                                                Double& sumWt,Int negate,Int weighted)
      54             :   {
      55           0 :     Vector<Int> ant1, ant2;
      56           0 :     Vector<Complex> Vj;
      57           0 :     Vector<Int> nPoints;
      58           0 :     ant1 = vb.antenna1();
      59           0 :     ant2 = vb.antenna2();
      60           0 :     Vj.resize(NAnt);
      61           0 :     nPoints.resize(NAnt);
      62           0 :     Int J=0,N;
      63           0 :     IPosition ndx(3,0);
      64           0 :     Vj = 0;
      65           0 :     nPoints = 0;
      66           0 :     N = vb.nRow();
      67             :     Double wt;
      68           0 :     sumWt = 0;
      69             :     //
      70             :     // It will be most useful to use
      71             :     // both RR and LL, and both cases are useful: (1) compute joind RR
      72             :     // and LL chisq, and (2) compute separate Chisq for RR and LL.
      73             :     // The CalTable stuff below all this is however not yet capable of
      74             :     // writing a caltable with 2 real parameters for 2 polarizations.
      75             :     //
      76             :     // Currently computing chisq for only the first polarization in
      77             :     // vis. ArrayColumn from the MS.
      78             :     //
      79           0 :     ndx=0;ndx(0)=whichPol;
      80             :     Int i;
      81             :     //#pragma omp parallel default(shared) private(i)
      82             :     {
      83             :       //#pragma omp for 
      84             :       //      for(ndx(2);ndx(2)<N;ndx(2)++)
      85           0 :       for(i=ndx(2);i<N;i++)
      86             :         {
      87           0 :           ndx(2)=i;
      88           0 :           if ((!vb.flagRow()(ndx(2)))     && 
      89           0 :               (!vb.flag()(0,ndx(2)))    &&
      90             :               //          (!vb.flagCube()(ndx))   &&
      91           0 :               ((ant1[ndx(2)] != ant2[ndx(2)]) && 
      92           0 :                ((ant1[ndx(2)] == whichAnt)     || 
      93           0 :                 (ant2[ndx(2)] == whichAnt))
      94             :                ))
      95             :             {
      96           0 :               wt = vb.weight()(ndx(2));
      97           0 :               sumWt += wt;
      98             :             
      99           0 :               if (!weighted) wt = 1.0;
     100             : 
     101           0 :               J=(ant1[ndx[2]]!=whichAnt)?ant1[ndx(2)]:ant2[ndx(2)];
     102           0 :               nPoints[J]++;
     103           0 :               if (ant1[ndx(2)] > ant2[ndx(2)])  
     104           0 :                 Vj[J] += Complex(wt,0)*vb.modelVisCube()(ndx);
     105             :               else
     106           0 :                 if (negate)
     107           0 :                   Vj[J] += -Complex(wt,0)*(vb.modelVisCube()(ndx));
     108             :                 else
     109           0 :                   Vj[J] += Complex(wt,0)*conj(vb.modelVisCube()(ndx));
     110           0 :               J++;
     111             :             }
     112             :         }
     113             :     }
     114             :     //#pragma omp parallel default(shared) private(i)
     115             :     //#pragma omp for 
     116           0 :     for(i=0;i<NAnt;i++) 
     117           0 :       if (nPoints[i] <= 0) Vj[i] = 0.0;
     118             :         
     119           0 :     return Vj;
     120           0 :   }
     121             :   //
     122             :   //---------------------------------------------------------------------------
     123             :   // Compute the penalty function (also called the Goodness-of-fit criteria).
     124             :   // For us, its the Chi-square function.
     125             :   //
     126           0 :   Double SteepestDescentSolver::getGOF(const VisBuffer& residual, Int& whichPol, Double& sumWt, const char* /*msg*/)
     127             :   {
     128           0 :     Double Chisq=0.0;
     129           0 :     Int nRow=residual.nRow();
     130           0 :     IPosition vbShape(residual.modelVisCube().shape());
     131             :     //Int nPoints;
     132             :     //nPoints=0;
     133           0 :     sumWt=0.0;
     134             : 
     135           0 :     IPosition ndx(3,0);
     136           0 :     ndx(0)=whichPol;
     137           0 :     for (ndx(2)=0;ndx(2)<nRow;ndx(2)++)
     138             :       {
     139           0 :         if (
     140             : //          (!residual.flagCube()(ndx))   && 
     141           0 :             (!residual.flag()(0,ndx(2)))  &&
     142           0 :             (!residual.flagRow()(ndx(2))) &&
     143           0 :             (residual.antenna1()(ndx(2)) != residual.antenna2()(ndx(2)))
     144             :             )
     145             :           {
     146           0 :             DComplex Vis;
     147             :             Float wt;
     148             :             
     149           0 :             Vis = residual.modelVisCube()(ndx);
     150           0 :             wt  = residual.weight()(ndx(2));
     151             : /*
     152             :             cout << ndx(2)                      << " " 
     153             :                  << Vis     << " " 
     154             :                  << wt                          << " " 
     155             :                  << residual.antenna1()(ndx(2)) << "-" << residual.antenna2()(ndx(2)) << " "
     156             :                  << residual.flagCube()(ndx)    << " " 
     157             :                  << residual.flag()(0,ndx(2))   << " "
     158             :                  << residual.flagRow()(ndx(2))  << " "
     159             :                  << endl;
     160             : */
     161           0 :             sumWt += Double(wt);
     162           0 :             Chisq += Double(wt*real(Vis*conj(Vis)));
     163             :            // nPoints++;
     164             :             /*
     165             :             if (isnan(Chisq)) 
     166             :               {
     167             :                 ostringstream os;
     168             :                 os << "###Error: Chisq evaluates to a NaN.  SumWt = " << sumWt 
     169             :                    << ndx(2) << " " << Vis << " " << wt << " " 
     170             :                    << residual.antenna1()(ndx(2)) << " " << residual.antenna2()(ndx(2));
     171             :                 cout << residual.modelVisCube() << endl;
     172             :                 throw(AipsError(os.str().c_str()));
     173             :               }
     174             :             */
     175             :           }
     176             :       }
     177             :     //    exit(0);
     178             :     //    if (nPoints>0) sumWt /= nPoints;
     179             :     //cout << "CHISQ CHISQ = " << Chisq/sumWt << " " << Chisq << " " << sumWt << endl;
     180             :     /*
     181             :     ndx(0)=whichPol;
     182             :     for (ndx(2)=0;ndx(2)<nRow;ndx(2)++)
     183             :       //    for (ndx(2)=0;ndx(2)<2;ndx(2)++)
     184             :       {
     185             :         Int i = ndx(2),p=ndx(0);
     186             :           if (
     187             :               (!residual.flagRow()(ndx(2)))   && 
     188             :               (!residual.flag()(0,ndx(2)))  &&
     189             :               //              (!residual.flagCube()(ndx)) &&
     190             :               (residual.antenna1()(ndx(2)) != residual.antenna2()(ndx(2)))
     191             :               )
     192             :             cout << "SDS: Residual: " << msg << " " << i << " " << whichPol
     193             :                  << " " << getCurrentTimeStamp(residual)-4.46635e9
     194             :                  << " " << residual.modelVisCube()(0,0,i)
     195             :                  << " " << residual.modelVisCube()(1,0,i)
     196             :                  << " " << residual.visCube()(0,0,i)
     197             :                  << " " << residual.visCube()(1,0,i)
     198             :                  << " " << residual.antenna1()(i)<< "-" << residual.antenna2()(i) 
     199             :                  << " " << residual.flag()(0,i) 
     200             :                  << " " << residual.flagRow()(i) 
     201             :                  << " " << residual.flagCube()(p,0,i) 
     202             :                  << " " << residual.weight()(i)
     203             :                  << endl;
     204             :       }
     205             :     cout << "Chisq = " << Chisq << " " << sumWt << " " << Chisq/sumWt << endl;
     206             :     */
     207             :     //    exit(0);
     208           0 :     if (sumWt > 0) return Chisq/sumWt;
     209           0 :     else return 0.0;
     210           0 :   }
     211             :   //
     212             :   //---------------------------------------------------------------------------
     213             :   //Given the VisEquation, this iteratively sovles for the parameters
     214             :   //of the supplied VisJones for the time-stamp given by SlotNo.  nAnt
     215             :   //is the number of antennas per time stamp.
     216             :   //
     217           0 :   Double SteepestDescentSolver::solve(VisEquation& ve, EPJones& epj, VisBuffer& vb, 
     218             :                                       Int nAnt, Int SlotNo)
     219             :   {
     220           0 :     Cube<Float> oldOffsets;
     221           0 :     Vector<Complex> ResidualVj, dAzVj, dElVj;
     222             :     Double Chisq0,Chisq,sumWt;
     223             :     //Double Time;
     224             :     //static Double Time0;
     225             :     Double AzHDiag,ElHDiag;
     226           0 :     Timer timer;
     227             :     Double localGain;
     228           0 :     Int iPol=0;
     229           0 :     IPosition ndx(2,2,nAnt);
     230             : 
     231           0 :     localGain = gain();
     232           0 :     ResidualVj.resize(nAnt);
     233           0 :     dAzVj.resize(nAnt);
     234           0 :     dElVj.resize(nAnt);
     235             : 
     236           0 :     ndx(0)=1;
     237           0 :     Chisq0=0.0;
     238           0 :     epj.guessPar(vb);
     239           0 :     epj.solveRPar() = -0.0001;
     240           0 :     residual_p=vb;
     241           0 :     residual_p.visCube().resize(vb.visCube().shape());
     242           0 :     residual_p.modelVisCube().resize(vb.modelVisCube().shape());
     243             : 
     244           0 :     residual_p.visCube() = vb.visCube();
     245             : 
     246           0 :     ve.diffResiduals(residual_p, gradient0_p, gradient1_p,flags);
     247             : 
     248             :     try
     249             :       {
     250           0 :         Chisq = getGOF(residual_p,iPol,sumWt);
     251             :       }
     252           0 :     catch (AipsError &x)
     253             :       {
     254           0 :         cout << x.getMesg() << endl;
     255           0 :         return -1;
     256           0 :       }
     257             : 
     258           0 :     if (sumWt == 0) return -Chisq;
     259             : 
     260             :     //Time = getCurrentTimeStamp(residual_p);
     261             :     //if (SlotNo == 0) Time0 = Time;
     262             : 
     263           0 :     timer.mark();
     264             :     Int iter;
     265             :     //Bool Converged=false;
     266           0 :     Vector<Bool> antFlagged;
     267           0 :     antFlagged.resize(nAnt);
     268           0 :     logIO() << LogOrigin("PointingCal","SDS::solve()") 
     269             :             << "Solution interval = " << SlotNo 
     270             :             << " Initial Chisq = " << Chisq 
     271           0 :             << " SumOfWt = " << sumWt << LogIO::NORMAL3 << LogIO::POST;
     272             :     
     273           0 :     for (iter=0;iter<numberIterations();iter++)
     274             :       {
     275           0 :         oldOffsets = epj.solveRPar();//Guess;
     276             :           {
     277           0 :             for(Int ant=0;ant<nAnt;ant++)
     278             :               {
     279           0 :                 ResidualVj = getVj(residual_p, nAnt,ant,iPol,sumWt,0,0);//Get a weighted list
     280           0 :                 dAzVj      = getVj(gradient0_p,nAnt,ant,iPol,sumWt,0,1);// Get an un-weighted list
     281           0 :                 dElVj      = getVj(gradient1_p,nAnt,ant,iPol,sumWt, 0,1);
     282             : 
     283           0 :                 antFlagged[ant]=false;
     284           0 :                 if (sumWt > 0)
     285             :                   {
     286           0 :                     ndx(1)=ant;
     287             : 
     288             :                     Double coVar1, coVar2;
     289           0 :                     coVar1 = coVar2 = 0;
     290           0 :                     if (sumWt > 0) coVar1 = real(innerProduct(dAzVj,dAzVj))/(sumWt*sumWt);
     291           0 :                     if (sumWt > 0) coVar2 = real(innerProduct(dElVj,dElVj))/(sumWt*sumWt);
     292             : //                  if (sumWt > 0) coVar1 = real(innerProduct(dAzVj,dAzVj));
     293             : //                  if (sumWt > 0) coVar2 = real(innerProduct(dElVj,dElVj));
     294           0 :                     AzHDiag = ElHDiag = 0;
     295           0 :                     AzHDiag = 1.0/coVar1;
     296           0 :                     ElHDiag = 1.0/coVar2;
     297             : 
     298           0 :                     epj.solveRPar()(0,iPol,ant) = epj.solveRPar()(0,iPol,ant)-2*AzHDiag*localGain*
     299           0 :                       real(innerProduct(ResidualVj,dAzVj))/sumWt;
     300           0 :                     epj.solveRPar()(1,iPol,ant) = epj.solveRPar()(1,iPol,ant)-2*ElHDiag*localGain*
     301           0 :                       real(innerProduct(ResidualVj,dElVj))/sumWt;
     302             : 
     303             : //                  epj.solveRPar()(0,0,ant) = epj.solveRPar()(0,0,ant)-2*AzHDiag*localGain*
     304             : //                    real(innerProduct(ResidualVj,dAzVj));
     305             : //                  epj.solveRPar()(1,0,ant) = epj.solveRPar()(1,0,ant)-2*ElHDiag*localGain*
     306             : //                    real(innerProduct(ResidualVj,dElVj));
     307             :                   }
     308             :                 else
     309           0 :                   antFlagged[ant]=true;
     310             : 
     311             :               }
     312             :             //
     313             :             // Compute the residuals and the gradients with the
     314             :             // updated solutions and check for convergence.
     315             :             //
     316             :             //      epj.setAntPar(SlotNo,Guess);
     317           0 :             ve.diffResiduals(residual_p,gradient0_p,gradient1_p,flags);
     318           0 :             Chisq0 = Chisq;
     319             :             //      Chisq  = getGOF(residual,iPol,sumWt)/sumWt;
     320             :             try
     321             :               {
     322           0 :                 Chisq  = getGOF(residual_p,iPol,sumWt);
     323             :               }
     324           0 :             catch (AipsError &x)
     325             :               {
     326           0 :                 logIO() << LogOrigin("PointingCal","SDS::solve()") 
     327             :                         << x.getMesg() 
     328           0 :                         << LogIO::POST;
     329           0 :                 return -1;
     330           0 :               }
     331             :           }
     332             :           Double dChisq;
     333           0 :           dChisq = (Chisq0-Chisq);
     334             :           //      cout << iter << " " << Chisq0 << " " << Chisq << " " << dChisq << endl;
     335           0 :           if ((fabs(dChisq) < tolerance()))
     336             :             {
     337             :               //Converged=true;
     338           0 :               break;
     339             :             }
     340           0 :           if ((dChisq < tolerance()))// && (iter > 0))
     341             :             {
     342           0 :               localGain /= 2.0;
     343           0 :               epj.solveRPar() = oldOffsets;
     344           0 :               ve.diffResiduals(residual_p,gradient0_p,gradient1_p,flags);
     345             :               //              Chisq  = getGOF(residual,iPol,sumWt)/sumWt;
     346             :               try
     347             :                 {
     348           0 :                   Chisq  = getGOF(residual_p,iPol,sumWt);
     349             :                 }
     350           0 :               catch (AipsError &x)
     351             :                 {
     352           0 :                   logIO() << LogOrigin("PointingCal","SDS::solve") 
     353             :                           << x.getMesg() 
     354           0 :                           << LogIO::POST;
     355           0 :                   return -1;
     356           0 :                 }
     357           0 :               Chisq0 = Chisq;
     358             :             }
     359             :           else
     360             :             {
     361           0 :               oldOffsets = epj.solveRPar();
     362             :             }
     363             :       }
     364             : //     logIO() << LogOrigin("PointingCal","SDS::solve") 
     365             : //          << "Solution interval = " << SlotNo << " Final Chisq = " << Chisq 
     366             : //          << LogIO::NORMAL3 << LogIO::POST;
     367             : 
     368             :     //
     369             :     // Finalize the solutions in VisJones internal cache.
     370             :     //
     371           0 :     Chisq = fabs(Chisq0-Chisq);
     372             : 
     373             :     logIO() << LogIO::NORMAL3 << "No. of iterations used: " 
     374             :             << iter
     375             :             << " Time total, per iteration:  " 
     376           0 :             << timer.all() << ", " << timer.all()/(iter+1) << " sec" << LogIO::POST;
     377             : 
     378             : 
     379           0 :     return (Chisq < tolerance()? Chisq:-Chisq);
     380           0 :   }
     381             : 
     382           0 :   Double SteepestDescentSolver::solve2(VisEquation& ve, VisIter& vi, EPJones& epj, 
     383             :                                        Int nAnt, Int SlotNo)
     384             :   {
     385           0 :     Cube<Float> bestSolution;
     386           0 :     Vector<Complex> ResidualVj, dAzVj, dElVj;
     387           0 :     Vector<Bool> antFlagged;
     388           0 :     Double Chisq = std::numeric_limits<float>::max( );
     389             :     Double dChisq, bestChisq, sumWt, /*Time,*/ AzHDiag, ElHDiag,localGain, coVar1, coVar2, 
     390             :       stepSize0,stepSize1;
     391           0 :     Int iPol=0, nPol, iter, axis0=0,axis1=0, iCorr;
     392           0 :     Bool Converged=false;
     393           0 :     Timer timer;
     394             : 
     395           0 :     nPol=polMap_p.nelements();
     396             : 
     397           0 :     ResidualVj.resize(nAnt);
     398           0 :     dAzVj.resize(nAnt);
     399           0 :     dElVj.resize(nAnt);
     400             :         
     401           0 :     epj.guessPar();
     402           0 :     for(Int ia=0;ia<nAnt;ia++)
     403             :       {
     404             : 
     405             :         // epj.solveRPar()(0,0,ia) = -0.001;
     406             :         // epj.solveRPar()(2,0,ia) =  0.001;
     407             :         // epj.solveRPar()(1,0,ia) =  0.001;
     408             :         // epj.solveRPar()(3,0,ia) = -0.001;
     409             :         //
     410             :         // Solved values for the squint
     411             :         //
     412             :         // epj.solveRPar()(0,0,ia) = -0.000139;
     413             :         // epj.solveRPar()(2,0,ia) =  5.25e-6;
     414             :         // epj.solveRPar()(1,0,ia) =  4.96e-5;
     415             :         // epj.solveRPar()(3,0,ia) = -0.000139;
     416             :       }
     417           0 :     for(Int ip=0;ip<nPol;ip++)
     418             :       {
     419           0 :         Converged=false;
     420           0 :         localGain = gain();
     421             : 
     422           0 :         iPol=polMap_p[ip];
     423           0 :         if (iPol >= 0) 
     424             :           {
     425           0 :             iCorr=iPol;
     426           0 :             iCorr=iPol=ip;
     427             :             //@#$%@#$%@#%@#%@#%@#%@#%
     428             :             // iPol = ip;
     429             :             //@#$%@#$%@#%@#%@#%@#%@#%
     430             :             
     431           0 :             epj.diffResiduals(vi,ve,residual_p, gradient0_p, gradient1_p, flags);
     432           0 :             Chisq = getGOF(residual_p,iCorr,sumWt,"Init");
     433           0 :             if (sumWt == 0) return -Chisq;
     434             :             
     435           0 :             bestChisq = Chisq;
     436           0 :             bestSolution.resize(epj.solveRPar().shape());
     437           0 :             bestSolution = epj.solveRPar();     
     438             :             //epj.guessPar();
     439             :             //Time = getCurrentTimeStamp(residual_p);
     440           0 :             timer.mark();
     441           0 :             antFlagged.resize(nAnt);
     442           0 :             logIO() << LogOrigin("PointingCal","SDS::solve2") 
     443             :                     << "Solution interval = " << SlotNo 
     444             :                     << " Initial Chisq = " << Chisq 
     445             :                     << " Polarization = " << iPol 
     446             :                     << " SumOfWt = " << sumWt 
     447           0 :                     << LogIO::NORMAL << LogIO::POST;
     448           0 :             if (iPol==0) {axis0=0;axis1=2;}
     449           0 :             else {axis0=1; axis1=3;}
     450           0 :             if (iPol==0) {axis0=1;axis1=3;}
     451           0 :             else {axis0=0; axis1=2;}
     452           0 :             iter=-1;
     453           0 :             for (iter=0;iter<numberIterations();iter++)
     454             :               {
     455             :                 //
     456             :                 // Update the current position
     457             :                 //
     458           0 :                 for(Int ant=0;ant<nAnt;ant++)
     459             :                   {
     460             :                     // cerr << "Init: " << ant << " " 
     461             :                     //   << epj.solveRPar()(axis0,0,ant) << "  "
     462             :                     //   << epj.solveRPar()(axis1,0,ant) << endl;
     463           0 :                     ResidualVj = getVj(residual_p, nAnt,ant,iCorr,sumWt,0,0);
     464           0 :                     dAzVj      = getVj(gradient0_p,nAnt,ant,iCorr,sumWt,0,1);
     465           0 :                     dElVj      = getVj(gradient1_p,nAnt,ant,iCorr,sumWt,0,1);
     466             :                     
     467           0 :                     antFlagged[ant]=false;
     468           0 :                     if (sumWt > 0)
     469             :                       {
     470           0 :                         stepSize0 = stepSize1 = coVar1 = coVar2 = 0;
     471           0 :                         if (sumWt > 0) 
     472             :                           {
     473           0 :                             coVar1 = real(innerProduct(dAzVj,dAzVj))/(sumWt*sumWt);
     474           0 :                             coVar2 = real(innerProduct(dElVj,dElVj))/(sumWt*sumWt);
     475             :                           }
     476           0 :                         AzHDiag = ElHDiag = 0;
     477             :                         
     478           0 :                         if (coVar1 > 0)
     479             :                           {
     480           0 :                             AzHDiag  = 1.0/coVar1;
     481           0 :                             stepSize0 = real(innerProduct(ResidualVj,dAzVj))/sumWt;
     482             :                             //                      cerr << "Ant:"  << ant << " " << stepSize0 << " ";
     483           0 :                             stepSize0 *= -2*AzHDiag*localGain;
     484             :                             //                      cerr << stepSize0 << "    ";
     485           0 :                             epj.solveRPar()(axis0,0,ant) = epj.solveRPar()(axis0,0,ant) + stepSize0;
     486             :                             //                  epj.solveRPar()(axis0,0,ant) = 0.001;
     487             :                           }
     488           0 :                         if (coVar2 > 0)
     489             :                           {
     490           0 :                             ElHDiag  = 1.0/coVar2;
     491           0 :                             stepSize1 = real(innerProduct(ResidualVj,dElVj))/sumWt;
     492             :                             //                      cerr << stepSize1 << " ";
     493           0 :                             stepSize1 *= -2*ElHDiag*localGain;
     494           0 :                             epj.solveRPar()(axis1,0,ant) = epj.solveRPar()(axis1,0,ant) + stepSize1;
     495             :                             // cerr << stepSize1 << "     " 
     496             :                             //   << epj.solveRPar()(axis0,0,ant) << "  "
     497             :                             //   << epj.solveRPar()(axis1,0,ant) << endl;
     498             :                             //                  epj.solveRPar()(axis1,0,ant) = -0.001;
     499             :                           }
     500             :                         /*
     501             :                           cout << "SDS Sol Loop = " 
     502             :                           << iPol << " " << iter << " " << ant << " " << axis0 << " " << axis1 << " " 
     503             :                           << epj.solveRPar()(axis0,0,ant) << " "
     504             :                           << epj.solveRPar()(axis1,0,ant) << " "
     505             :                           << stepSize0 << " " << stepSize1 << " "
     506             :                           << endl;
     507             :                         */
     508             :                       }
     509             :                     else
     510             :                       {
     511           0 :                         antFlagged[ant]=true;
     512           0 :                         epj.solveRPar()(axis0,0,ant)=0.0;//0.001;
     513           0 :                         epj.solveRPar()(axis1,0,ant)=0.0;//-0.001;
     514             :                       }
     515             :                     //epj.solveRPar()(axis0,0,ant)=0.001;
     516             :                     //epj.solveRPar()(axis1,0,ant)=-0.001;
     517             :                     
     518             :                   }
     519             :                 //
     520             :                 // Compute the residuals and the gradients with the
     521             :                 // updated solutions and check for convergence.
     522             :                 //
     523           0 :                 epj.diffResiduals(vi,ve,residual_p, gradient0_p, gradient1_p, flags);
     524           0 :                 Chisq  = getGOF(residual_p,iCorr,sumWt,"Final");
     525             :                 /*
     526             :                   for(Int kk=0;kk<nAnt;kk++)
     527             :                   cout << "SDS Sol Iter = " 
     528             :                   << iPol << " " << iter << " " << axis0 << " " << axis1 << " " << kk << " "
     529             :                   << epj.solveRPar()(axis0,0,kk) << " "
     530             :                   << epj.solveRPar()(axis1,0,kk) 
     531             :                   << Chisq << " " << bestChisq
     532             :                   << endl;
     533             :                 */
     534           0 :                 dChisq = (bestChisq-Chisq);
     535             :                 /*
     536             :                   cout << iter << " " << iPol << " " << Chisq << " " << bestChisq
     537             :                   << " " << dChisq << " " << " " << bestChisq << " " << localGain << endl;
     538             :                 */
     539             :                 
     540           0 :                 if ((fabs(dChisq) < tolerance()))
     541             :                   {
     542           0 :                     Converged=true;
     543           0 :                     epj.setRPar(bestSolution);
     544           0 :                     Chisq = bestChisq;
     545           0 :                     break;
     546             :                   }
     547           0 :                 if (Chisq >= bestChisq)
     548             :                   {
     549             :                     // Backtracking....
     550           0 :                     localGain /= 2.0;
     551           0 :                     epj.setRPar(bestSolution); //oldOffsets;
     552             :                     
     553             :                     //          IPosition shp(bestSolution.shape());
     554             :                     //          for(Int ii=0;ii<shp(2);ii++)
     555             :                     //            for(Int jj=0;jj<shp(0);jj++)
     556             :                     //              cout << "BT: " << bestSolution(jj,0,ii) << " " 
     557             :                     //                   << epj.solveRPar()(jj,0,ii) << endl;
     558             :                     
     559           0 :                     epj.diffResiduals(vi,ve,residual_p, gradient0_p, gradient1_p, flags);
     560             :                     
     561           0 :                     Chisq  = getGOF(residual_p,iCorr,sumWt,"BACK");
     562             :                     
     563             :                     //          cout << "BT Chisq: " << Chisq << " " 
     564             :                     //               << sum(bestSolution-epj.solveRPar()) 
     565             :                     //               << " " << residual.nRow() << endl;
     566             :                     //          if (Chisq != bestChisq)
     567             :                     //            {
     568             :                     //              IPosition ndx(3,0);
     569             :                     
     570             :                     //              for(Int i=0;i<residual.nRow();i++)
     571             :                     //                {
     572             :                     //                  ndx(2)=i;
     573             :                     //                  //        if (residual.flag()(0,i) == 0)
     574             :                     //                  for(Int xx=0;xx<2;xx++)
     575             :                     //                    {
     576             :                     //                      ndx(0)=xx;
     577             :                     //                      if (
     578             :                     //                          (!residual.flagCube()(ndx))   &&
     579             :                     //                          (!residual.flag()(xx,ndx(2)))  &&
     580             :                     //                          (!residual.flagRow()(ndx(2))) &&
     581             :                     //                          (residual.antenna1()(ndx(2)) != residual.antenna2()(ndx(2)))
     582             :                     //                          )
     583             :                     //                        cout << xx<<"*";
     584             :                     //                    }
     585             :                     
     586             :                     //                  cout << "SDS: Residual: " << i    
     587             :                     //                       << " " << residual.modelVisCube()(0,0,i) 
     588             :                     //                       << " " << residual.modelVisCube()(1,0,i)
     589             :                     //                       << " " << residual.visCube()(0,0,i) 
     590             :                     //                       << " " << residual.visCube()(1,0,i)
     591             :                     //                       << " " << residual.flagRow()(i) 
     592             :                     //                       << " " << residual.flag()(0,i) 
     593             :                     //                       << " " << residual.flag()(1,i) 
     594             :                     //                       << " " << residual.flagCube()(0,0,i) 
     595             :                     //                       << " " << residual.flagCube()(1,0,i) 
     596             :                     //                       << " " << residual.antenna1()(i) 
     597             :                     //                       << " " << residual.antenna2()(i) 
     598             :                     //                       << endl;
     599             :                     //                }
     600             :                     //              exit(0);
     601             :                     //            }
     602             :                   }
     603             :                 else
     604             :                   {
     605           0 :                     bestSolution = epj.solveRPar();
     606           0 :                     bestChisq = Chisq;
     607             :                   }
     608           0 :                 if (localGain < 1e-20) {Converged = true; break;};
     609             :               }
     610             :             //         epj.solveRPar() = bestSolution;  
     611             :             //  {
     612             :             //    IPosition shp(bestSolution.shape());
     613             :             //    cout << "-------------------------------------------------------------------------" << endl;
     614             :             //    for(Int ii=0;ii<shp(2);ii++)
     615             :             //      {
     616             :             //        cout << "Sol: ";
     617             :             //        for(Int jj=0;jj<shp(0);jj++)
     618             :             //          cout << ii << " " << jj << " " << bestSolution(jj,0,ii);
     619             :             //        cout << " " << endl;
     620             :             //      }
     621             :             //  }
     622           0 :             epj.diffResiduals(vi,ve,residual_p,gradient0_p,gradient1_p,flags);
     623           0 :             Chisq = getGOF(residual_p,iCorr,sumWt);
     624           0 :             logIO() << LogOrigin("PointingCal","SDS::solve2") 
     625             :                     << "Solution interval = " << SlotNo 
     626             :                     << " Final Chisq = " << Chisq 
     627             :                     << " Polarization = " << iPol 
     628             :                     << " NIter = " << iter
     629           0 :                     << LogIO::NORMAL << LogIO::POST;
     630             :             logIO() << LogIO::NORMAL3 << "No. of iterations used: " 
     631             :                     << iter
     632             :                     << " Time total, per iteration:  " 
     633           0 :                     << timer.all() << ", " << timer.all()/(iter+1) << " sec" << LogIO::POST;
     634             :             
     635             :           } // if (iPol >= 0)
     636             :       } // for(Int ip=0; ip<nPol; ip++)
     637             :     //    return (Chisq < tolerance()? Chisq:-Chisq);
     638           0 :     return (Converged ? Chisq: -Chisq);
     639           0 :   }
     640             :   
     641             : };

Generated by: LCOV version 1.16