// $Id: analyzer.h,v 1.34 2018/01/03 21:33:02 mkkuhner Exp $

/*
Copyright 2002-2005 Mary K. Kuhner, Peter Beerli, and Joseph Felsenstein

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

/* Authors: Peter Beerli, Mary Kuhner, Jon Yamato and Joseph Felsenstein */


// analyzer.h
//
// the analyzer generates
// - profiles  [code will be in profile.cpp]
//
// Peter Beerli November 2000
//

#ifndef ANALYZER_H
#define ANALYZER_H

#include <fstream>
#include <vector>

#include "likelihood.h"
#include "maximizer.h"
#include "parameter.h"
#include "plotstat.h"
#include "vectorx.h"

typedef std::map<double, double> DoublesMap;
typedef std::map<double, double>::iterator DoublesMapiter;
typedef std::map<double, double>::reverse_iterator DoublesMapReviter;

typedef std::map<double, DoubleVec1d> DoubleToVecMap;
typedef std::map<double, DoubleVec1d>::iterator DoubleToVecMapiter;

typedef std::map<double, string> DoubleToStringMap;
typedef std::map<double, string>::iterator DoubleToStringiter;

class ForceSummary;

long int difference(DoubleVec1d param1, DoubleVec1d param2);

class Analyzer
{
  public:
    // Instantiate the Analyzer
    // using the "last" postlike object or "last" maximizer object,
    // the Analyzer assumes that the
    // Prob(G|parameter_0) are already computed
    // [in likelihood.h:....PostLike::Setup()
    Analyzer (ForceSummary &fs, const ParamVector &params,
              Maximizer * thismaximizer);
    ~Analyzer ();

    void SetMLEs(DoubleVec1d newMLEs);
    //Debug function:
    void PrintMLEs();

    // Calculate the profiles and put them into class variable profiles.
    void CalcProfiles (const DoubleVec1d MLEs, double likelihood, long int region);

  private:
    DoubleVec1d  m_MLEparams;     // holds MLE parameters
    DoubleVec1d  m_MLElparams;    // holds the log(m_MLEparam)
    Maximizer *m_maximizer;       // holds the maximizer [for profiles]
    PostLike *m_postlikelihood;   // pointer to the PostLike [for plots]
    double m_likelihood;          // holds the L of the last maximization
    const ForceSummary &m_forcesummary;
    vector < double > m_modifiers;    // for calculation of percentiles or fixed

    // Temporary variables as an optimization
    DoubleVec1d m_newparams;

    // Calculates a single Profile table
    void CalcProfile (ParamVector::iterator guide, long int pnum, long int region);
    void CalcProfileFixed (ParamVector::iterator guide, long int pnum, long int region);
    void CalcProfilePercentile (ParamVector::iterator guide, long int pnum, long int region);
    void DoHalfTheProfile(bool high, DoubleVec1d& targetLikes,
                          DoublesMap& percsForLikes, long int pnum, long int region,
                          vector<ProfileLineStruct>& localprofiles,
                          ParamVector::iterator guide);

    bool AddMoreExtremeValue(DoublesMap& foundLikesForVals,
                             DoubleToVecMap& foundVecsForVals,
                             DoubleToStringMap& messagesForVals,
                             bool high, long int pnum);
    // returns fairly high and low values for specific forces
    DoublesMapiter GetLastHigher(DoublesMap& foundLikesForVals,
                                 double targetLike, bool high);
    DoublesMapiter GetFirstLower(DoublesMap& foundLikesForVals,
                                 double targetLike, bool high);
    bool ExpandSearch(DoublesMap& foundLikesForVals,
                      DoubleToVecMap& foundVecsForVals,
                      DoublesMapiter& lowValAndLike,
                      DoublesMapiter& highValAndLike,
                      DoubleToStringMap& messagesForVals,
                      long int pnum, double targetlike);
    double LowParameter(long int pnum, double currentLow);
    double HighParameter(long int pnum, double currentHigh);
    DoublesMapiter ClosestFoundFor(DoublesMap& foundLikesForVals,
                                   double targetLike);
    double GetNewValFromBracket(DoublesMapiter& highValAndLike,
                                DoublesMapiter& lowValAndLike,
                                double targetLike);
    void AddBlankProfileForModifier(double modifier,
                                    vector<ProfileLineStruct>& localprofiles);
    void   CheckForMultipleMaxima(DoublesMap& foundLikesForVals, bool high);
    void   PrintDoublesMap(DoublesMap& printme);
    void   PrintDoublesIter(DoublesMapiter& printme);
    void   PrintDoubleToStringMap(DoubleToStringMap& printme);
    void   PrintDoubleToStringIter(DoubleToStringiter& printme);
};

#endif // ANALYZER_H

//____________________________________________________________________________________
