<commit_before>
/*********************************************************************
 *                                                                   *
 * ConfigFemtoAnalysis.C - configuration macro for the femtoscopic   *
 * analysis, meant as a QA process for two-particle effects          *
 *                                                                   *
 * Author: Adam Kisiel (Adam.Kisiel@cern.ch)                         *
 *                                                                   *
 *********************************************************************/

#if !defined(__CINT__) || defined(__MAKECINT_)
#include "AliFemtoManager.h"
#include "AliFemtoEventReaderESDChain.h"
#include "AliFemtoEventReaderESDChainKine.h"
#include "AliFemtoEventReaderAODChain.h"
#include "AliFemtoSimpleAnalysis.h"
#include "AliFemtoBasicEventCut.h"
#include "AliFemtoESDTrackCut.h"
#include "AliFemtoCorrFctn.h"
#include "AliFemtoCutMonitorParticleYPt.h"
#include "AliFemtoCutMonitorParticleVertPos.h"
#include "AliFemtoCutMonitorParticleMomRes.h"
#include "AliFemtoCutMonitorParticlePID.h"
#include "AliFemtoCutMonitorEventMult.h"
#include "AliFemtoCutMonitorEventVertex.h"
#include "AliFemtoShareQualityTPCEntranceSepPairCut.h"
#include "AliFemtoPairCutAntiGamma.h"
#include "AliFemtoPairCutRadialDistanceKK.h"
#include "AliFemtoPairCutRadialDistanceLM.h"
#include "AliFemtoQinvCorrFctn.h"
#include "AliFemtoShareQualityCorrFctn.h"
#include "AliFemtoTPCInnerCorrFctn.h"
#include "AliFemtoAnalysisAzimuthalPbPb2Order.h"
#include "AliFemtoCorrFctn3DSpherical.h"
#include "AliFemtoChi2CorrFctn.h"
#include "AliFemtoCorrFctnTPCNcls.h"
#include "AliFemtoBPLCMS3DCorrFctn.h"
#include "AliFemtoCorrFctn3DLCMSSym.h"
#include "AliFemtoModelBPLCMSCorrFctn.h"
#include "AliFemtoModelCorrFctn3DSpherical.h"
#include "AliFemtoModelGausLCMSFreezeOutGenerator.h"
#include "AliFemtoModelGausRinvFreezeOutGenerator.h"
#include "AliFemtoModelManager.h"
#include "AliFemtoModelWeightGeneratorBasic.h"
#include "AliFemtoModelWeightGeneratorLednicky.h"
#include "AliFemtoCorrFctnDirectYlm.h"
#include "AliFemtoModelCorrFctnDirectYlm.h"
#include "AliFemtoModelCorrFctnSource.h"
#include "AliFemtoCutMonitorParticlePtPDG.h"
#include "AliFemtoKTPairCut.h"
#endif

//________________________________________________________________________
AliFemtoManager* ConfigFemtoAnalysis(int CentL=20, int CentH=30, int kTRange=1, int PhiBin=1) {

    double PionMass = 0.13956995;
    double KaonMass = 0.493677;

    if (CentL==0 && CentH==5) {
        int runmults[10] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    }
    if (CentL==5 && CentH==10) {
        int runmults[10] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0};
    }
    if (CentL==10 && CentH==20) {
        int runmults[10] = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0};
    }
    if (CentL==20 && CentH==30) {
        int runmults[10] = {0, 0, 0, 1, 0, 0, 0, 0, 0, 0};
    }
    if (CentL==30 && CentH==40) {
        int runmults[10] = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0};
    }
    if (CentL==40 && CentH==50 ) {
        int runmults[10] = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0};
    }

    int multbins[11] = {0, 50, 100, 200, 300, 400, 500, 700, 800, 900, 990};

    const char *chrgs[2] = { "pip", "pim" };

    int runch[2] = {1, 1};

    int kTmax=1;
    kTmax=kTRange;
    double ktrng[5] = {0.2, 0.3, 0.4, 0.5, 0.7};

    int phimax=9;

    if(PhiBin==1){
        int phirange[10] = {-15, 5, 25, 45, 65, 85, 105, 125, 145, 165};
        phimax=9;
    }
    if (PhiBin==2) {
        int phirange[11] = {-9, 9, 27, 45, 63, 81, 99, 117, 136, 153, 171};
        phimax=10;
    }

    AliFemtoEventReaderAODChain *Reader = new AliFemtoEventReaderAODChain();
    Reader->SetFilterBit(7);
    Reader->SetCentralityPreSelection(0.001, 550);

    AliFemtoManager* Manager=new AliFemtoManager();
    Manager->SetEventReader(Reader);

    AliFemtoAnalysisAzimuthalPbPb2Order    *ana[2][7];
    AliFemtoBasicEventCut         *mecetaphitpc[2][7];
    AliFemtoCutMonitorEventMult   *cutPassEvMetaphitpc[2][7];
    AliFemtoCutMonitorEventMult   *cutFailEvMetaphitpc[2][7];
    AliFemtoCutMonitorEventVertex *cutPassEvVetaphitpc[2][7];
    AliFemtoCutMonitorEventVertex *cutFailEvVetaphitpc[2][7];
    AliFemtoESDTrackCut           *dtc1etaphitpc[2][7];

    AliFemtoPairCutRadialDistanceKK      *sqpcetaphitpc[2][7];
    AliFemtoPairCutRadialDistanceKK      *sqpcetaphitpcRD[2][7];

    AliFemtoKTPairCut             *ktpaircut[2][7][4][11];
    //  AliFemtoQinvCorrFctn            *cqqinv[2][11][3];
    AliFemtoBPLCMS3DCorrFctn     *cq3dlcmskttpc[2][7][4][11];

    for (int imult=0; imult<7; imult++) {
        if (runmults[imult]) {
            for (int ichg=0; ichg<2; ichg++) {
                if (runch[ichg]) {

                    ana[ichg][imult] = new AliFemtoAnalysisAzimuthalPbPb2Order(4, -8.0, 8.0, 5, multbins[imult], multbins[imult+1],phimax);
                    ana[ichg][imult]->SetNumEventsToMix(3);
                    ana[ichg][imult]->SetMinSizePartCollection(4);
                    ana[ichg][imult]->SetEPhistname(Form("hist%i%i",ichg,imult));
                    mecetaphitpc[ichg][imult] = new AliFemtoBasicEventCut();
                    mecetaphitpc[ichg][imult]->SetEventMult(5,100000);//was 0.001
                    mecetaphitpc[ichg][imult]->SetVertZPos(-8,8);

                    cutPassEvMetaphitpc[ichg][imult] = new AliFemtoCutMonitorEventMult(Form("cutPass%stpcM%i", chrgs[ichg], imult));
                    cutFailEvMetaphitpc[ichg][imult] = new AliFemtoCutMonitorEventMult(Form("cutFail%stpcM%i", chrgs[ichg], imult));
                    mecetaphitpc[ichg][imult]->AddCutMonitor(cutPassEvMetaphitpc[ichg][imult], cutFailEvMetaphitpc[ichg][imult]);

                    cutPassEvVetaphitpc[ichg][imult] = new AliFemtoCutMonitorEventVertex(Form("cutPass%stpcM%i", chrgs[ichg], imult));
                    cutFailEvVetaphitpc[ichg][imult] = new AliFemtoCutMonitorEventVertex(Form("cutFail%stpcM%i", chrgs[ichg], imult));
                    mecetaphitpc[ichg][imult]->AddCutMonitor(cutPassEvVetaphitpc[ichg][imult], cutFailEvVetaphitpc[ichg][imult]);

                    dtc1etaphitpc[ichg][imult] = new AliFemtoESDTrackCut();

                    if (ichg == 0)
                        dtc1etaphitpc[ichg][imult]->SetCharge(1.0);
                    else if (ichg == 1)
                        dtc1etaphitpc[ichg][imult]->SetCharge(-1.0);

                    dtc1etaphitpc[ichg][imult]->SetPt(0.15,1.5);
                    dtc1etaphitpc[ichg][imult]->SetEta(-0.8,0.8);
                    dtc1etaphitpc[ichg][imult]->SetMass(PionMass);
                    dtc1etaphitpc[ichg][imult]->SetMostProbablePion();

                    dtc1etaphitpc[ichg][imult]->SetStatus(AliESDtrack::kTPCin);
                    dtc1etaphitpc[ichg][imult]->SetminTPCncls(80);//was 0
                    dtc1etaphitpc[ichg][imult]->SetRemoveKinks(kTRUE);
                    dtc1etaphitpc[ichg][imult]->SetLabel(kFALSE);
                    dtc1etaphitpc[ichg][imult]->SetMaxTPCChiNdof(4.0);
                    dtc1etaphitpc[ichg][imult]->SetMaxImpactXY(2.4);//was 0.2
                    dtc1etaphitpc[ichg][imult]->SetMaxImpactZ(3.0);//0.15

                    sqpcetaphitpc[ichg][imult] = new AliFemtoPairCutRadialDistanceKK();
                    sqpcetaphitpcRD[ichg][imult] = new AliFemtoPairCutRadialDistanceKK();

                    sqpcetaphitpc[ichg][imult]->SetShareQualityMax(1.0);
                    sqpcetaphitpc[ichg][imult]->SetShareFractionMax(1);
                    sqpcetaphitpc[ichg][imult]->SetRemoveSameLabel(kFALSE);
                    sqpcetaphitpc[ichg][imult]->SetMinimumRadius(1.6);
                    sqpcetaphitpc[ichg][imult]->SetPhiStarDifferenceMinimum(0.0);
                    sqpcetaphitpc[ichg][imult]->SetEtaDifferenceMinimum(0.0);

                    sqpcetaphitpcRD[ichg][imult]->SetShareQualityMax(1.0);
                    sqpcetaphitpcRD[ichg][imult]->SetShareFractionMax(0.05);
                    sqpcetaphitpcRD[ichg][imult]->SetRemoveSameLabel(kFALSE);
                    sqpcetaphitpcRD[ichg][imult]->SetMinimumRadius(1.6);
                    sqpcetaphitpcRD[ichg][imult]->SetPhiStarDifferenceMinimum(0.017);
                    sqpcetaphitpcRD[ichg][imult]->SetEtaDifferenceMinimum(0.015);

                    ana[ichg][imult]->SetEventCut(mecetaphitpc[ichg][imult]);
                    ana[ichg][imult]->SetFirstParticleCut(dtc1etaphitpc[ichg][imult]);
                    ana[ichg][imult]->SetSecondParticleCut(dtc1etaphitpc[ichg][imult]);
                    ana[ichg][imult]->SetPairCut(sqpcetaphitpc[ichg][imult]);
                    ana[ichg][imult]->SetPairCutRD(sqpcetaphitpcRD[ichg][imult]);

                    for (int ikt=0; ikt<kTmax; ikt++){   //  kt range

                        //  cqqinv[ichg][imult][ikt] = new AliFemtoQinvCorrFctn(Form("cqqinv%imult%ikT", ichg, imult, ikt),30, 0,0.15);

                        for (int iphi=0; iphi<phimax; iphi++){
                            ktpaircut[ichg][imult][ikt][iphi] = new AliFemtoKTPairCut(ktrng[ikt],ktrng[ikt+1]);
                            ktpaircut[ichg][imult][ikt][iphi]->SetPhiRange(phirange[iphi],phirange[iphi+1]);

                            cq3dlcmskttpc[ichg][imult][ikt][iphi] = new AliFemtoBPLCMS3DCorrFctn(Form("cq3d%imult%ikT%iRP%i", ichg, imult, ikt, iphi),30,-0.15,0.15);
                            cq3dlcmskttpc[ichg][imult][ikt][iphi]->SetPairSelectionCut(ktpaircut[ichg][imult][ikt][iphi]);
                            ana[ichg][imult]->AddCorrFctn(cq3dlcmskttpc[ichg][imult][ikt][iphi]);
                        }
                        // ana[ichg][imult]->AddCorrFctn(cqqinv[ichg][imult][ikt]);

                    }
                    Manager->AddAnalysis(ana[ichg][imult]);
                }
            }
        }
    }
    return Manager;
}
<commit_msg>Update in femto AzHBT Config:MSaleh<commit_after>
/*********************************************************************
 *                                                                   *
 * ConfigFemtoAnalysis.C - configuration macro for the femtoscopic   *
 * analysis, meant as a QA process for two-particle effects          *
 *                                                                   *
 * Author: Adam Kisiel (Adam.Kisiel@cern.ch)                         *
 *                                                                   *
 *********************************************************************/

#if !defined(__CINT__) || defined(__MAKECINT_)
#include "AliFemtoManager.h"
#include "AliFemtoEventReaderESDChain.h"
#include "AliFemtoEventReaderESDChainKine.h"
#include "AliFemtoEventReaderAODChain.h"
#include "AliFemtoSimpleAnalysis.h"
#include "AliFemtoBasicEventCut.h"
#include "AliFemtoESDTrackCut.h"
#include "AliFemtoCorrFctn.h"
#include "AliFemtoCutMonitorParticleYPt.h"
#include "AliFemtoCutMonitorParticleVertPos.h"
#include "AliFemtoCutMonitorParticleMomRes.h"
#include "AliFemtoCutMonitorParticlePID.h"
#include "AliFemtoCutMonitorEventMult.h"
#include "AliFemtoCutMonitorEventVertex.h"
#include "AliFemtoShareQualityTPCEntranceSepPairCut.h"
#include "AliFemtoPairCutAntiGamma.h"
#include "AliFemtoPairCutRadialDistanceKK.h"
#include "AliFemtoPairCutRadialDistanceLM.h"
#include "AliFemtoQinvCorrFctn.h"
#include "AliFemtoShareQualityCorrFctn.h"
#include "AliFemtoTPCInnerCorrFctn.h"
#include "AliFemtoAnalysisAzimuthalPbPb2Order.h"
#include "AliFemtoCorrFctn3DSpherical.h"
#include "AliFemtoChi2CorrFctn.h"
#include "AliFemtoCorrFctnTPCNcls.h"
#include "AliFemtoBPLCMS3DCorrFctn.h"
#include "AliFemtoCorrFctn3DLCMSSym.h"
#include "AliFemtoModelBPLCMSCorrFctn.h"
#include "AliFemtoModelCorrFctn3DSpherical.h"
#include "AliFemtoModelGausLCMSFreezeOutGenerator.h"
#include "AliFemtoModelGausRinvFreezeOutGenerator.h"
#include "AliFemtoModelManager.h"
#include "AliFemtoModelWeightGeneratorBasic.h"
#include "AliFemtoModelWeightGeneratorLednicky.h"
#include "AliFemtoCorrFctnDirectYlm.h"
#include "AliFemtoModelCorrFctnDirectYlm.h"
#include "AliFemtoModelCorrFctnSource.h"
#include "AliFemtoCutMonitorParticlePtPDG.h"
#include "AliFemtoKTPairCut.h"
#endif

//________________________________________________________________________
AliFemtoManager* ConfigFemtoAnalysis(int CentL=20, int CentH=30, int kTRange=1, int PhiBin=1) {

    double PionMass = 0.13956995;
    double KaonMass = 0.493677;

    if (CentL==0 && CentH==5) {
        int runmults[10] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    }
    if (CentL==5 && CentH==10) {
        int runmults[10] = {0, 1, 0, 0, 0, 0, 0, 0, 0, 0};
    }
    if (CentL==10 && CentH==20) {
        int runmults[10] = {0, 0, 1, 0, 0, 0, 0, 0, 0, 0};
    }
    if (CentL==20 && CentH==30) {
        int runmults[10] = {0, 0, 0, 1, 0, 0, 0, 0, 0, 0};
    }
    if (CentL==30 && CentH==40) {
        int runmults[10] = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0};
    }
    if (CentL==40 && CentH==50 ) {
        int runmults[10] = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0};
    }

    int multbins[11] = {0, 50, 100, 200, 300, 400, 500, 700, 800, 900, 990};

    const char *chrgs[2] = { "pip", "pim" };

    int runch[2] = {1, 1};

    int kTmax=1;
    kTmax=kTRange;
    double ktrng[5] = {0.2, 0.3, 0.4, 0.5, 0.7};

    int phimax=9;

    if(PhiBin==1){
        int phirange[10] = {-15, 5, 25, 45, 65, 85, 105, 125, 145, 165};
        phimax=9;
    }
    if (PhiBin==2) {
        int phirange[11] = {-9, 9, 27, 45, 63, 81, 99, 117, 136, 153, 171};
        phimax=9;
    }

    AliFemtoEventReaderAODChain *Reader = new AliFemtoEventReaderAODChain();
    Reader->SetFilterBit(7);
    Reader->SetCentralityPreSelection(0.001, 550);

    AliFemtoManager* Manager=new AliFemtoManager();
    Manager->SetEventReader(Reader);

    AliFemtoAnalysisAzimuthalPbPb2Order    *ana[2][7];
    AliFemtoBasicEventCut         *mecetaphitpc[2][7];
    AliFemtoCutMonitorEventMult   *cutPassEvMetaphitpc[2][7];
    AliFemtoCutMonitorEventMult   *cutFailEvMetaphitpc[2][7];
    AliFemtoCutMonitorEventVertex *cutPassEvVetaphitpc[2][7];
    AliFemtoCutMonitorEventVertex *cutFailEvVetaphitpc[2][7];
    AliFemtoESDTrackCut           *dtc1etaphitpc[2][7];

    AliFemtoPairCutRadialDistanceKK      *sqpcetaphitpc[2][7];
    AliFemtoPairCutRadialDistanceKK      *sqpcetaphitpcRD[2][7];

    AliFemtoKTPairCut             *ktpaircut[2][7][4][11];
    //  AliFemtoQinvCorrFctn            *cqqinv[2][11][3];
    AliFemtoBPLCMS3DCorrFctn     *cq3dlcmskttpc[2][7][4][11];

    for (int imult=0; imult<7; imult++) {
        if (runmults[imult]) {
            for (int ichg=0; ichg<2; ichg++) {
                if (runch[ichg]) {

                    ana[ichg][imult] = new AliFemtoAnalysisAzimuthalPbPb2Order(4, -8.0, 8.0, 5, multbins[imult], multbins[imult+1],phimax);
                    ana[ichg][imult]->SetNumEventsToMix(3);
                    ana[ichg][imult]->SetMinSizePartCollection(4);
                    ana[ichg][imult]->SetEPhistname(Form("hist%i%i",ichg,imult));
                    mecetaphitpc[ichg][imult] = new AliFemtoBasicEventCut();
                    mecetaphitpc[ichg][imult]->SetEventMult(5,100000);//was 0.001
                    mecetaphitpc[ichg][imult]->SetVertZPos(-8,8);

                    cutPassEvMetaphitpc[ichg][imult] = new AliFemtoCutMonitorEventMult(Form("cutPass%stpcM%i", chrgs[ichg], imult));
                    cutFailEvMetaphitpc[ichg][imult] = new AliFemtoCutMonitorEventMult(Form("cutFail%stpcM%i", chrgs[ichg], imult));
                    mecetaphitpc[ichg][imult]->AddCutMonitor(cutPassEvMetaphitpc[ichg][imult], cutFailEvMetaphitpc[ichg][imult]);

                    cutPassEvVetaphitpc[ichg][imult] = new AliFemtoCutMonitorEventVertex(Form("cutPass%stpcM%i", chrgs[ichg], imult));
                    cutFailEvVetaphitpc[ichg][imult] = new AliFemtoCutMonitorEventVertex(Form("cutFail%stpcM%i", chrgs[ichg], imult));
                    mecetaphitpc[ichg][imult]->AddCutMonitor(cutPassEvVetaphitpc[ichg][imult], cutFailEvVetaphitpc[ichg][imult]);

                    dtc1etaphitpc[ichg][imult] = new AliFemtoESDTrackCut();

                    if (ichg == 0)
                        dtc1etaphitpc[ichg][imult]->SetCharge(1.0);
                    else if (ichg == 1)
                        dtc1etaphitpc[ichg][imult]->SetCharge(-1.0);

                    dtc1etaphitpc[ichg][imult]->SetPt(0.15,1.5);
                    dtc1etaphitpc[ichg][imult]->SetEta(-0.8,0.8);
                    dtc1etaphitpc[ichg][imult]->SetMass(PionMass);
                    dtc1etaphitpc[ichg][imult]->SetMostProbablePion();

                    dtc1etaphitpc[ichg][imult]->SetStatus(AliESDtrack::kTPCin);
                    dtc1etaphitpc[ichg][imult]->SetminTPCncls(80);//was 0
                    dtc1etaphitpc[ichg][imult]->SetRemoveKinks(kTRUE);
                    dtc1etaphitpc[ichg][imult]->SetLabel(kFALSE);
                    dtc1etaphitpc[ichg][imult]->SetMaxTPCChiNdof(4.0);
                    dtc1etaphitpc[ichg][imult]->SetMaxImpactXY(2.4);//was 0.2
                    dtc1etaphitpc[ichg][imult]->SetMaxImpactZ(3.0);//0.15

                    sqpcetaphitpc[ichg][imult] = new AliFemtoPairCutRadialDistanceKK();
                    sqpcetaphitpcRD[ichg][imult] = new AliFemtoPairCutRadialDistanceKK();

                    sqpcetaphitpc[ichg][imult]->SetShareQualityMax(1.0);
                    sqpcetaphitpc[ichg][imult]->SetShareFractionMax(1);
                    sqpcetaphitpc[ichg][imult]->SetRemoveSameLabel(kFALSE);
                    sqpcetaphitpc[ichg][imult]->SetMinimumRadius(1.6);
                    sqpcetaphitpc[ichg][imult]->SetPhiStarDifferenceMinimum(0.0);
                    sqpcetaphitpc[ichg][imult]->SetEtaDifferenceMinimum(0.0);

                    sqpcetaphitpcRD[ichg][imult]->SetShareQualityMax(1.0);
                    sqpcetaphitpcRD[ichg][imult]->SetShareFractionMax(0.05);
                    sqpcetaphitpcRD[ichg][imult]->SetRemoveSameLabel(kFALSE);
                    sqpcetaphitpcRD[ichg][imult]->SetMinimumRadius(1.6);
                    sqpcetaphitpcRD[ichg][imult]->SetPhiStarDifferenceMinimum(0.017);
                    sqpcetaphitpcRD[ichg][imult]->SetEtaDifferenceMinimum(0.015);

                    ana[ichg][imult]->SetEventCut(mecetaphitpc[ichg][imult]);
                    ana[ichg][imult]->SetFirstParticleCut(dtc1etaphitpc[ichg][imult]);
                    ana[ichg][imult]->SetSecondParticleCut(dtc1etaphitpc[ichg][imult]);
                    ana[ichg][imult]->SetPairCut(sqpcetaphitpc[ichg][imult]);
                    ana[ichg][imult]->SetPairCutRD(sqpcetaphitpcRD[ichg][imult]);

                    for (int ikt=0; ikt<kTmax; ikt++){   //  kt range

                        //  cqqinv[ichg][imult][ikt] = new AliFemtoQinvCorrFctn(Form("cqqinv%imult%ikT", ichg, imult, ikt),30, 0,0.15);

                        for (int iphi=0; iphi<phimax; iphi++){
                            ktpaircut[ichg][imult][ikt][iphi] = new AliFemtoKTPairCut(ktrng[ikt],ktrng[ikt+1]);
                            ktpaircut[ichg][imult][ikt][iphi]->SetPhiRange(phirange[iphi],phirange[iphi+1]);

                            cq3dlcmskttpc[ichg][imult][ikt][iphi] = new AliFemtoBPLCMS3DCorrFctn(Form("cq3d%imult%ikT%iRP%i", ichg, imult, ikt, iphi),30,-0.15,0.15);
                            cq3dlcmskttpc[ichg][imult][ikt][iphi]->SetPairSelectionCut(ktpaircut[ichg][imult][ikt][iphi]);
                            ana[ichg][imult]->AddCorrFctn(cq3dlcmskttpc[ichg][imult][ikt][iphi]);
                        }
                        // ana[ichg][imult]->AddCorrFctn(cqqinv[ichg][imult][ikt]);

                    }
                    Manager->AddAnalysis(ana[ichg][imult]);
                }
            }
        }
    }
    return Manager;
}

<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "branchdialog.h"
#include "branchadddialog.h"
#include "branchmodel.h"
#include "gitclient.h"
#include "gitplugin.h"
#include "ui_branchdialog.h"
#include "stashdialog.h" // Label helpers

#include <utils/checkablemessagebox.h>
#include <utils/qtcassert.h>
#include <vcsbase/vcsbaseoutputwindow.h>

#include <QItemSelectionModel>
#include <QPushButton>
#include <QMessageBox>

#include <QDebug>

namespace Git {
namespace Internal {

BranchDialog::BranchDialog(QWidget *parent) :
    QDialog(parent),
    m_ui(new Ui::BranchDialog),
    m_model(new BranchModel(GitPlugin::instance()->gitClient(), this))
{
    setModal(false);
    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
    setAttribute(Qt::WA_DeleteOnClose, true); // Do not update unnecessarily

    m_ui->setupUi(this);

    connect(m_ui->refreshButton, SIGNAL(clicked()), this, SLOT(refresh()));
    connect(m_ui->addButton, SIGNAL(clicked()), this, SLOT(add()));
    connect(m_ui->checkoutButton, SIGNAL(clicked()), this, SLOT(checkout()));
    connect(m_ui->removeButton, SIGNAL(clicked()), this, SLOT(remove()));
    connect(m_ui->diffButton, SIGNAL(clicked()), this, SLOT(diff()));
    connect(m_ui->logButton, SIGNAL(clicked()), this, SLOT(log()));

    m_ui->branchView->setModel(m_model);

    connect(m_ui->branchView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
            this, SLOT(enableButtons()));

    enableButtons();
}

BranchDialog::~BranchDialog()
{
    delete m_ui;
    delete m_model;
    m_model = 0;
}

void BranchDialog::refresh(const QString &repository, bool force)
{
    if (m_repository == repository && !force)
        return;

    m_repository = repository;
    m_ui->repositoryLabel->setText(StashDialog::msgRepositoryLabel(m_repository));
    QString errorMessage;
    if (!m_model->refresh(m_repository, &errorMessage))
        VcsBase::VcsBaseOutputWindow::instance()->appendError(errorMessage);

    m_ui->branchView->expandAll();
}

void BranchDialog::enableButtons()
{
    QModelIndex idx = selectedIndex();
    const bool hasSelection = idx.isValid();
    const bool currentSelected = hasSelection && idx == m_model->currentBranch();
    const bool isLocal = m_model->isLocal(idx);
    const bool isLeaf = m_model->isLeaf(idx);

    m_ui->removeButton->setEnabled(hasSelection && !currentSelected && isLocal && isLeaf);
    m_ui->logButton->setEnabled(hasSelection && isLeaf);
    m_ui->diffButton->setEnabled(hasSelection && isLeaf);
    m_ui->checkoutButton->setEnabled(hasSelection && !currentSelected && isLeaf);
}

void BranchDialog::refresh()
{
    refresh(m_repository, true);
}

void BranchDialog::add()
{
    QString trackedBranch = m_model->branchName(selectedIndex());
    bool isLocal = m_model->isLocal(selectedIndex());
    if (trackedBranch.isEmpty()) {
        trackedBranch = m_model->branchName(m_model->currentBranch());
        isLocal = true;
    }

    QStringList localNames = m_model->localBranchNames();

    QString suggestedNameBase = trackedBranch.mid(trackedBranch.lastIndexOf(QLatin1Char('/')) + 1);
    QString suggestedName = suggestedNameBase;
    int i = 2;
    while (localNames.contains(suggestedName)) {
        suggestedName = suggestedNameBase + QString::number(i);
        ++i;
    }

    BranchAddDialog branchAddDialog;
    branchAddDialog.setBranchName(suggestedName);
    branchAddDialog.setTrackedBranchName(trackedBranch, !isLocal);

    if (branchAddDialog.exec() == QDialog::Accepted && m_model) {
        QModelIndex idx = m_model->addBranch(branchAddDialog.branchName(), branchAddDialog.track(), trackedBranch);
        m_ui->branchView->selectionModel()->select(idx, QItemSelectionModel::Clear
                                                        | QItemSelectionModel::Select
                                                        | QItemSelectionModel::Current);
        m_ui->branchView->scrollTo(idx);
    }
}

void BranchDialog::checkout()
{
    QModelIndex idx = selectedIndex();
    QTC_CHECK(m_model->isLocal(idx));

    m_model->checkoutBranch(idx);
    enableButtons();
}

/* Prompt to delete a local branch and do so. */
void BranchDialog::remove()
{
    QModelIndex selected = selectedIndex();
    QTC_CHECK(selected != m_model->currentBranch()); // otherwise the button would not be enabled!

    QString branchName = m_model->branchName(selected);
    if (branchName.isEmpty())
        return;

    QString message = tr("Would you like to delete the branch '%1'?").arg(branchName);
    bool wasMerged = m_model->branchIsMerged(selected);
    if (!wasMerged)
        message = tr("Would you like to delete the unmerged branch '%1'?").arg(branchName);

    if (QMessageBox::question(this, tr("Delete Branch"), message, QMessageBox::Yes|QMessageBox::No,
                              wasMerged ? QMessageBox::Yes : QMessageBox::No) == QMessageBox::Yes)
        m_model->removeBranch(selected);
}

void BranchDialog::diff()
{
    QString branchName = m_model->branchName(selectedIndex());
    if (branchName.isEmpty())
        return;
    GitPlugin::instance()->gitClient()->diffBranch(m_repository, QStringList(), branchName);
}

void BranchDialog::log()
{
    QString branchName = m_model->branchName(selectedIndex());
    if (branchName.isEmpty())
        return;
    GitPlugin::instance()->gitClient()->graphLog(m_repository, branchName);
}

void BranchDialog::changeEvent(QEvent *e)
{
    QDialog::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

QModelIndex BranchDialog::selectedIndex()
{
    QModelIndexList selected = m_ui->branchView->selectionModel()->selectedIndexes();
    if (selected.isEmpty())
        return QModelIndex();
    return selected.at(0);
}

} // namespace Internal
} // namespace Git
<commit_msg>Git: Prompt to checkout after adding a branch<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "branchdialog.h"
#include "branchadddialog.h"
#include "branchmodel.h"
#include "gitclient.h"
#include "gitplugin.h"
#include "ui_branchdialog.h"
#include "stashdialog.h" // Label helpers

#include <utils/checkablemessagebox.h>
#include <utils/qtcassert.h>
#include <vcsbase/vcsbaseoutputwindow.h>

#include <QItemSelectionModel>
#include <QPushButton>
#include <QMessageBox>

#include <QDebug>

namespace Git {
namespace Internal {

BranchDialog::BranchDialog(QWidget *parent) :
    QDialog(parent),
    m_ui(new Ui::BranchDialog),
    m_model(new BranchModel(GitPlugin::instance()->gitClient(), this))
{
    setModal(false);
    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
    setAttribute(Qt::WA_DeleteOnClose, true); // Do not update unnecessarily

    m_ui->setupUi(this);

    connect(m_ui->refreshButton, SIGNAL(clicked()), this, SLOT(refresh()));
    connect(m_ui->addButton, SIGNAL(clicked()), this, SLOT(add()));
    connect(m_ui->checkoutButton, SIGNAL(clicked()), this, SLOT(checkout()));
    connect(m_ui->removeButton, SIGNAL(clicked()), this, SLOT(remove()));
    connect(m_ui->diffButton, SIGNAL(clicked()), this, SLOT(diff()));
    connect(m_ui->logButton, SIGNAL(clicked()), this, SLOT(log()));

    m_ui->branchView->setModel(m_model);

    connect(m_ui->branchView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
            this, SLOT(enableButtons()));

    enableButtons();
}

BranchDialog::~BranchDialog()
{
    delete m_ui;
    delete m_model;
    m_model = 0;
}

void BranchDialog::refresh(const QString &repository, bool force)
{
    if (m_repository == repository && !force)
        return;

    m_repository = repository;
    m_ui->repositoryLabel->setText(StashDialog::msgRepositoryLabel(m_repository));
    QString errorMessage;
    if (!m_model->refresh(m_repository, &errorMessage))
        VcsBase::VcsBaseOutputWindow::instance()->appendError(errorMessage);

    m_ui->branchView->expandAll();
}

void BranchDialog::enableButtons()
{
    QModelIndex idx = selectedIndex();
    const bool hasSelection = idx.isValid();
    const bool currentSelected = hasSelection && idx == m_model->currentBranch();
    const bool isLocal = m_model->isLocal(idx);
    const bool isLeaf = m_model->isLeaf(idx);

    m_ui->removeButton->setEnabled(hasSelection && !currentSelected && isLocal && isLeaf);
    m_ui->logButton->setEnabled(hasSelection && isLeaf);
    m_ui->diffButton->setEnabled(hasSelection && isLeaf);
    m_ui->checkoutButton->setEnabled(hasSelection && !currentSelected && isLeaf);
}

void BranchDialog::refresh()
{
    refresh(m_repository, true);
}

void BranchDialog::add()
{
    QString trackedBranch = m_model->branchName(selectedIndex());
    bool isLocal = m_model->isLocal(selectedIndex());
    if (trackedBranch.isEmpty()) {
        trackedBranch = m_model->branchName(m_model->currentBranch());
        isLocal = true;
    }

    QStringList localNames = m_model->localBranchNames();

    QString suggestedNameBase = trackedBranch.mid(trackedBranch.lastIndexOf(QLatin1Char('/')) + 1);
    QString suggestedName = suggestedNameBase;
    int i = 2;
    while (localNames.contains(suggestedName)) {
        suggestedName = suggestedNameBase + QString::number(i);
        ++i;
    }

    BranchAddDialog branchAddDialog;
    branchAddDialog.setBranchName(suggestedName);
    branchAddDialog.setTrackedBranchName(trackedBranch, !isLocal);

    if (branchAddDialog.exec() == QDialog::Accepted && m_model) {
        QModelIndex idx = m_model->addBranch(branchAddDialog.branchName(), branchAddDialog.track(), trackedBranch);
        m_ui->branchView->selectionModel()->select(idx, QItemSelectionModel::Clear
                                                        | QItemSelectionModel::Select
                                                        | QItemSelectionModel::Current);
        m_ui->branchView->scrollTo(idx);
        if (QMessageBox::question(this, tr("Checkout"), tr("Checkout branch?"),
                                  QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
            checkout();
    }
}

void BranchDialog::checkout()
{
    QModelIndex idx = selectedIndex();
    QTC_CHECK(m_model->isLocal(idx));

    m_model->checkoutBranch(idx);
    enableButtons();
}

/* Prompt to delete a local branch and do so. */
void BranchDialog::remove()
{
    QModelIndex selected = selectedIndex();
    QTC_CHECK(selected != m_model->currentBranch()); // otherwise the button would not be enabled!

    QString branchName = m_model->branchName(selected);
    if (branchName.isEmpty())
        return;

    QString message = tr("Would you like to delete the branch '%1'?").arg(branchName);
    bool wasMerged = m_model->branchIsMerged(selected);
    if (!wasMerged)
        message = tr("Would you like to delete the unmerged branch '%1'?").arg(branchName);

    if (QMessageBox::question(this, tr("Delete Branch"), message, QMessageBox::Yes|QMessageBox::No,
                              wasMerged ? QMessageBox::Yes : QMessageBox::No) == QMessageBox::Yes)
        m_model->removeBranch(selected);
}

void BranchDialog::diff()
{
    QString branchName = m_model->branchName(selectedIndex());
    if (branchName.isEmpty())
        return;
    GitPlugin::instance()->gitClient()->diffBranch(m_repository, QStringList(), branchName);
}

void BranchDialog::log()
{
    QString branchName = m_model->branchName(selectedIndex());
    if (branchName.isEmpty())
        return;
    GitPlugin::instance()->gitClient()->graphLog(m_repository, branchName);
}

void BranchDialog::changeEvent(QEvent *e)
{
    QDialog::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

QModelIndex BranchDialog::selectedIndex()
{
    QModelIndexList selected = m_ui->branchView->selectionModel()->selectedIndexes();
    if (selected.isEmpty())
        return QModelIndex();
    return selected.at(0);
}

} // namespace Internal
} // namespace Git
<|endoftext|>


<commit_before>/*!
 * \file remove.cpp
 * \author Nathan Eloe
 * \brief tests find and findOne functionality of the mongo cxx driver
 */

#include "../connection/mongoclient.h"
#include "../connection/cursor.h"
#include "gtest/gtest.h"
#include "fixture.h"
#include <iostream>
#include <ctime>
#include <cstdlib>

TEST_F(MongoDriverTest, RemoveOne)
{
  int thing = 0;
  while (c.findOne(REMCOLL, {{"a", thing}}).field_names().size() != 0)
    thing ++;
  c.insert(REMCOLL, {{"a", thing}});
  ASSERT_NE(0, c.findOne(REMCOLL, {{"a", thing}}).field_names().size());
  c.remove(REMCOLL, {{"a", thing}});
  ASSERT_EQ(0, c.findOne(REMCOLL, {{"a", thing}}).field_names().size());
}<commit_msg>few more removal tests (remove many, remove one)<commit_after>/*!
 * \file remove.cpp
 * \author Nathan Eloe
 * \brief tests find and findOne functionality of the mongo cxx driver
 */

#include "../connection/mongoclient.h"
#include "../connection/cursor.h"
#include "gtest/gtest.h"
#include "fixture.h"
#include <iostream>
#include <ctime>
#include <cstdlib>

TEST_F(MongoDriverTest, RemoveOne)
{
  int thing = 0;
  while (c.findOne(REMCOLL, {{"a", thing}}).field_names().size() != 0)
    thing ++;
  c.insert(REMCOLL, {{"a", thing}});
  ASSERT_NE(0, c.findOne(REMCOLL, {{"a", thing}}).field_names().size());
  c.remove(REMCOLL, {{"a", thing}});
  ASSERT_EQ(0, c.findOne(REMCOLL, {{"a", thing}}).field_names().size());
}

TEST_F(MongoDriverTest, RemoveOneManyMatch)
{
  int thing = 0;
  while (c.findOne(REMCOLL, {{"a", thing}}).field_names().size() != 0)
    thing ++;
  c.insert(REMCOLL, {{"a", thing}, {"b", 5}});
  c.insert(REMCOLL, {{"a", thing}, {"b", 1}});
  ASSERT_NE(0, c.findOne(REMCOLL, {{"a", thing}}).field_names().size());
  c.remove(REMCOLL, {{"a", thing}});
  ASSERT_NE(0, c.findOne(REMCOLL, {{"a", thing}}).field_names().size());
}

TEST_F(MongoDriverTest, RemoveAllManyMatch)
{
  int thing = 0;
  while (c.findOne(REMCOLL, {{"a", thing}}).field_names().size() != 0)
    thing ++;
  c.insert(REMCOLL, {{"a", thing}, {"b", 5}});
  c.insert(REMCOLL, {{"a", thing}, {"b", 1}});
  ASSERT_NE(0, c.findOne(REMCOLL, {{"a", thing}}).field_names().size());
  c.remove(REMCOLL, {{"a", thing}}, false);
  ASSERT_EQ(0, c.findOne(REMCOLL, {{"a", thing}}).field_names().size());
}<|endoftext|>


<commit_before>/*
 * diagonalize.cc
 */

#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/ADT/ValueMap.h"
#include "llvm/Support/PatternMatch.h"

#include <Eigen/Core>
#include <Eigen/Eigenvalues>

#include <iostream>
#include "llvm/Support/raw_ostream.h"

using namespace llvm;
using namespace PatternMatch;
using namespace Eigen;

#define OP_IN_RANGE(_op, _start, _end) \
    (_op >= Instruction:: _start && _op <= Instruction:: _end)

namespace
{

struct ADPass : public LoopPass
{
private:
    Loop* loop;
    DominatorTree* DT;
    BasicBlock* exit_block;
    std::vector<BasicBlock*> blocks;

    /* Keep track of the loop range. */
    Value* iter_final;
    PHINode* iter_var;

    /* Index and store state variables. */
    ValueMap<PHINode*, size_t> phis;

    /* Track linear combinations of variables. */
    typedef ValueMap<PHINode*, double> Coefficients;

public:
    static char ID;

    ADPass() : LoopPass(ID) {}

    virtual void getAnalysisUsage(AnalysisUsage& AU) const {
        AU.addRequired<DominatorTree>();
    }

    virtual bool runOnLoop(Loop* L, LPPassManager&) {
        loop = L;
        blocks = loop->getBlocks();
        DT = &getAnalysis<DominatorTree>();
        phis.clear();

        if (!loop->isLCSSAForm(*DT)
            || loop->getSubLoops().size()
            || !(exit_block = loop->getUniqueExitBlock()))
        {
            return false;
        }

        /* Filter away loops with unsupported instructions. */
        size_t nr_cmps = 0;
        ICmpInst* icmp = NULL;
        for (auto it = blocks.begin(); it != blocks.end(); ++it) {
            BasicBlock* BB = *it;
            for (auto II = BB->begin(); II != BB->end(); ++II) {
                Instruction* instr = II;
                if (isa<ICmpInst>(instr)) {
                    if (++nr_cmps > 1) {
                        return false;
                    } else {
                        icmp = cast<ICmpInst>(instr);
                    }
                } else if (isa<PHINode>(instr)) {
                    PHINode* PN = cast<PHINode>(instr);
                    if (PN->getNumIncomingValues() != 2
                        || !DT->properlyDominates(PN->getIncomingBlock(0),
                                                  blocks.front()))
                    {
                        return false;
                    }
                    Value* inLhs = PN->getIncomingValue(0);
                    if (!(isa<ConstantInt>(inLhs) || isa<ConstantFP>(inLhs))) {
                        return false;
                    } else {
                        phis[PN] = 0;
                    }
                } else if (isa<BinaryOperator>(instr)) {
                    BinaryOperator* binop = cast<BinaryOperator>(instr);
                    if (!(OP_IN_RANGE(binop->getOpcode(), Add, FDiv))) {
                        return false;
                    }
                } else if (!(isa<BranchInst>(instr)
                            || isa<IndirectBrInst>(instr)))
                {
                    return false;
                }
            }
        }

        /* Extract the loop iterator if possible. */
        if (!icmp || !extractIterator(icmp)) {
            return false;
        } else {
            phis.erase(iter_var);
        }

        size_t phi_index = 0;
        for (auto kv = phis.begin(); kv != phis.end(); ++kv) {
            phis[kv->first] = phi_index++;
        }

        /* Find the initial state and all linear dependence relations. */
        size_t nr_phis = phis.size();
        MatrixXd InitialState(nr_phis, 1);
        MatrixXd TransformationMatrix(nr_phis, nr_phis);
        TransformationMatrix << MatrixXd::Zero(nr_phis, nr_phis);
        for (auto kv = phis.begin(); kv != phis.end(); ++kv) {
            PHINode* PN = kv->first;
            size_t phi_label = phis[PN];
            InitialState(phi_label, 0) = ToDouble(PN->getIncomingValue(0));

            Coefficients coeffs;
            if (!trackUpdates(PN->getIncomingValue(1), coeffs)) {
                return false;
            }
            for (auto ckv = coeffs.begin(); ckv != coeffs.end(); ++ckv) {
                size_t target_phi = phis[ckv->first];
                TransformationMatrix(phi_label, target_phi) = ckv->second;
            }
        }

        /* Diagonalize the transformation matrix. */
        EigenSolver<MatrixXd> EigSolver(TransformationMatrix);
        MatrixXcd P = EigSolver.eigenvectors();
        MatrixXcd D = EigSolver.eigenvalues().asDiagonal();
        MatrixXcd Pinv = P.inverse();
        if (!checkSystem(TransformationMatrix, InitialState, P, D, Pinv)) {
            return false;
        }

        /* Emit instructions to compute the closed form in a new block. */
        LLVMContext& ctx = blocks.front()->getContext();
        Module* mod = exit_block->getParent()->getParent();
        BasicBlock* dgen = BasicBlock::Create(ctx, "dgen", 0);
        Type* numTy = Type::getDoubleTy(ctx);
        std::vector<Type*> powProto(2, numTy);
        FunctionType* powType = FunctionType::get(numTy, powProto, false);
        Function* powf = Function::Create(powType,
            GlobalValue::ExternalLinkage, "llvm.pow.f64", mod);
        powf->setCallingConv(CallingConv::C);

        /* P(D^n) = r * λ^n : ∀(r) ∈ row(P) */
        Value** PDn = new Value*[nr_phis * nr_phis];
        for (size_t j = 0; j < nr_phis; ++j) {
            /* λ[j]^n */
            Value* exptargs[] = {
                ToConstantFP(ctx, std::real(D(j, j))), iter_final
            };
            Value* eigvexpt = CallInst::Create(powf,
                ArrayRef<Value*>(exptargs, 2), "eigvexpt", dgen);

            /* PDn[i][j] = P[i][j] * λ[j]^n */
            for (size_t i = 0; i < nr_phis; ++i) {
                size_t index = i * nr_phis + j;
                PDn[index] = BinaryOperator::Create(Instruction::FMul,
                    ToConstantFP(ctx, std::real(P(i, j))), eigvexpt, "pdn",
                    dgen);
            }
        }

        /* xf = P(D^n) * Pinv * x0 */
        Value** soln = new Value*[nr_phis];
        Value* zero = ToConstantFP(ctx, 0.0);
        for (size_t i = 0; i < nr_phis; ++i) {
            soln[i] = zero;
            for (size_t j = 0; j < nr_phis; ++j) {
                /* inprod = <a, b> : a ∈ row(P(D^n)), b ∈ col(Pinv) */
                Value* inprod = zero;
                for (size_t k = 0; k < nr_phis; ++k) {
                    Value* ik_kj = BinaryOperator::Create(Instruction::FMul,
                        PDn[i * nr_phis + k],
                        ToConstantFP(ctx, std::real(Pinv(k, j))),
                        "ik_kj", dgen);
                    inprod = BinaryOperator::Create(Instruction::FAdd,
                        ik_kj, inprod, "inprod", dgen);
                }

                /* xf[i] = ∑ P(D^n)Pinv[i][j] * x0[j] */
                Value* xj_prod = BinaryOperator::Create(Instruction::FMul,
                    inprod, ToConstantFP(ctx, InitialState(j)), "pdpxj",
                    dgen);
                soln[i] = BinaryOperator::Create(Instruction::FAdd,
                    xj_prod, soln[i], "xf", dgen);
            }
        }

        errs() << *dgen << "\n";

        delete[] PDn;
        delete[] soln;

#if 0
        /*
         * XXX:
         * - Do some analysis on the loop;
         *   1) What is the block we jump out to when we finish the loop?
         *      exit_block
         *   2) Which PHI nodes in this block have incoming values from
         *      our loop? Store these PHI nodes: determine the state variable
         *      they refer to by examining the Value* they have incoming, and
         *      searching for that Value* in our set of PHIs.
         *      Map[OuterPHI] => StateVariable
         *   3) Delete all of the Instructions in our loop.
         *   4) Inject matrix multiplication code into the hollowed BB.
         *   5) Change the incoming values in the OuterPHIs to the final
         *      results produced by the diagonalization process.
         */

        /* Find dependencies on state variables outside of the loop. */
        ValueMap<PHINode*, PHINode*> outerDeps;
        for (auto II = exit_block->begin(); II != exit_block->end(); ++II) {
            Instruction* instr = II;
            if (isa<PHINode>(instr)) {
                PHINode* PN = cast<PHINode>(instr);
                if (PN->getBasicBlockIndex(blocks.back()) != -1) {
                    Value* V = PN->getIncomingValueForBlock(blocks.back());
                    for (auto kv = phis.begin(); kv != phis.end(); ++kv) {
                        if (kv->first->getIncomingValue(1) == V) {
                            outerDeps[PN] = kv->first;
                        }
                    }
                }
            }
        }
#endif

        return false;
    }

private:
    bool extractIterator(ICmpInst* icmp) {
        /* In canonical form, we should get an icmp with the predicate
         * reduced to an equality test. */
        Value *cmpLhs, *cmpRhs;
        ICmpInst::Predicate IPred;
        if (match(icmp, m_ICmp(IPred, m_Value(cmpLhs),
                                      m_Value(cmpRhs)))
            && IPred == CmpInst::Predicate::ICMP_EQ)
        {
            /* We should be comparing against the final iterator value, which
             * should not be found in the loop body. */
            if (isa<Instruction>(cmpRhs)) {
                Instruction* instr = cast<Instruction>(cmpRhs);
                BasicBlock* BB = instr->getParent();
                if (!DT->properlyDominates(BB, blocks.front())) {
                    return false;
                }
                if (isa<Constant>(instr->getOperand(0))
                    || isa<Instruction>(instr->getOperand(0)))
                {
                    return false;
                }
                iter_final = instr->getOperand(0);
            } else {
                iter_final = cmpRhs;
            }

            /* Check if the loop increment is behaving as we expect it to. */
            Value *incrLhs, *incrRhs;
            if (match(cmpLhs, m_Add(m_Value(incrLhs), m_Value(incrRhs)))) {
                if (isa<PHINode>(incrLhs)
                    && isa<ConstantInt>(incrRhs)
                    && cast<ConstantInt>(incrRhs)->isOne())
                {
                    iter_var = cast<PHINode>(incrLhs);
                    Value* iter_initial = iter_var->getIncomingValue(0);
                    if (isa<ConstantInt>(iter_initial)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    bool trackUpdates(Value* parent, Coefficients& coeffs) {
        /* Determine the linear combination that produces 'parent'. */
        if (isa<Constant>(parent)) {
            return true;
        } else if (isa<PHINode>(parent)) {
            /* A PHINode should contribute a single copy of itself. */
            PHINode* PN = cast<PHINode>(parent);
            if (!phis.count(PN)) {
                return false;
            } else {
                coeffs[PN] = 1;
            }
        } else if (isa<BinaryOperator>(parent)) {
            BinaryOperator* binop = cast<BinaryOperator>(parent);
            int opcode = binop->getOpcode();
            Value *LHS = binop->getOperand(0), *RHS = binop->getOperand(1);

            Coefficients lhsCoeffs, rhsCoeffs;
            if (!trackUpdates(LHS, lhsCoeffs)
                || !trackUpdates(RHS, rhsCoeffs))
            {
                return false;
            }

            double scalar;
            if (OP_IN_RANGE(opcode, Add, FSub)) {
                /* Add instructions shouldn't operate on scalars. */
                if (isScalar(lhsCoeffs) || isScalar(rhsCoeffs)) {
                    return false;
                }
            } else {
                /* Mul instructions can only have one scalar operand. */
                if (isScalar(lhsCoeffs) ^ isScalar(rhsCoeffs)) {
                    return false;
                }

                /* Div instructions cannot have scalar numerators. */
                if (OP_IN_RANGE(opcode, UDiv, FDiv) && !isScalar(lhsCoeffs)) {
                    return false;
                }

                scalar = ToDouble(isScalar(lhsCoeffs) ? LHS : RHS);
            }

            /* Merge the two sets of coefficients. */
            for (auto kv = phis.begin(); kv != phis.end(); ++kv) {
                PHINode* PN = kv->first;
                double lcoeff = lhsCoeffs.lookup(PN);
                double rcoeff = rhsCoeffs.lookup(PN);

                /* Adding nil entries to 'coeffs' breaks isScalar(X). */
                if (lcoeff == 0.0 && rcoeff == 0.0) {
                    continue;
                }

                if (OP_IN_RANGE(opcode, Add, FAdd)) {
                    coeffs[PN] = lcoeff + rcoeff;
                } else if (OP_IN_RANGE(opcode, Sub, FSub)) {
                    coeffs[PN] = lcoeff - rcoeff;
                } else if (OP_IN_RANGE(opcode, Mul, FMul)) {
                    coeffs[PN] = scalar * (lcoeff + rcoeff);
                } else {
                    coeffs[PN] = (1 / scalar) * (lcoeff + rcoeff);
                }
            }
        } else return false;
        return true;
    }

    int64_t ToInt(Value* V) {
        return cast<ConstantInt>(V)->getValue().getSExtValue();
    }

    double ToDouble(Value* V) {
        if (isa<ConstantInt>(V)) {
            return double(ToInt(V));
        } else if (isa<ConstantFP>(V)) {
            return cast<ConstantFP>(V)->getValueAPF().convertToDouble();
        }
        return 0.0;
    }

    Value* ToConstantFP(LLVMContext& ctx, double n) {
        return ConstantFP::get(ctx, APFloat(n));
    }

    bool isScalar(Coefficients& coeffs) {
        return coeffs.size() == 0;
    }

    bool checkSystem(MatrixXd& A, MatrixXd& x,
                     MatrixXcd& P, MatrixXcd& D, MatrixXcd& Pinv)
    {
        /* Ensure that there are no complex eigenvectors. */
        for (int i = 0; i < P.rows(); ++i) {
            for (int j = 0; j < P.cols(); ++j) {
                if (std::imag(P(i, j)) != 0.0) {
                    return false;
                }
            }
        }

        /* Check that the diagonalization is reasonably accurate. */
        MatrixXd A3x = A*A*A*x;
        MatrixXcd PD3Px = (P*(D*D*D)*Pinv)*x;
        const double epsilon = 100 * std::numeric_limits<double>::epsilon();
        for (int i = 0; i < x.rows(); ++i) {
            if (epsilon <
                std::abs(std::abs(PD3Px(i, 0)) - std::abs(A3x(i, 0))))
            {
                return false;
            }
        }
        return true;
    }
};

char ADPass::ID = 0;

}

static RegisterPass<ADPass> X("auto-diagonalize",
    "Diagonalize linear dynamical systems", false, false);
<commit_msg>Cleaned up code a little<commit_after>/*
 * diagonalize.cc
 */

#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/ADT/ValueMap.h"
#include "llvm/Support/PatternMatch.h"

#include <Eigen/Core>
#include <Eigen/Eigenvalues>

#include <iostream>
#include "llvm/Support/raw_ostream.h"

using namespace llvm;
using namespace PatternMatch;
using namespace Eigen;

#define OP_IN_RANGE(_op, _start, _end) \
    (_op >= Instruction:: _start && _op <= Instruction:: _end)

namespace
{

struct ADPass : public LoopPass
{
private:
    Loop* loop;
    DominatorTree* DT;
    BasicBlock* exit_block;
    std::vector<BasicBlock*> blocks;

    /* Keep track of the loop range. */
    Value* iter_final;
    PHINode* iter_var;

    /* Index and store state variables. */
    ValueMap<PHINode*, size_t> phis;

    /* Track linear combinations of variables. */
    typedef ValueMap<PHINode*, double> Coefficients;

public:
    static char ID;

    ADPass() : LoopPass(ID) {}

    virtual void getAnalysisUsage(AnalysisUsage& AU) const {
        AU.addRequired<DominatorTree>();
    }

    virtual bool runOnLoop(Loop* L, LPPassManager&) {
        loop = L;
        blocks = loop->getBlocks();
        DT = &getAnalysis<DominatorTree>();
        phis.clear();

        if (!loop->isLCSSAForm(*DT)
            || loop->getSubLoops().size()
            || !(exit_block = loop->getUniqueExitBlock()))
        {
            return false;
        }

        /* Filter away loops with unsupported instructions. */
        size_t nr_cmps = 0;
        ICmpInst* icmp = NULL;
        for (auto it = blocks.begin(); it != blocks.end(); ++it) {
            BasicBlock* BB = *it;
            for (auto II = BB->begin(); II != BB->end(); ++II) {
                Instruction* instr = II;
                if (isa<ICmpInst>(instr)) {
                    if (++nr_cmps > 1) {
                        return false;
                    } else {
                        icmp = cast<ICmpInst>(instr);
                    }
                } else if (isa<PHINode>(instr)) {
                    PHINode* PN = cast<PHINode>(instr);
                    if (PN->getNumIncomingValues() != 2
                        || !DT->properlyDominates(PN->getIncomingBlock(0),
                                                  blocks.front()))
                    {
                        return false;
                    }
                    Value* inLhs = PN->getIncomingValue(0);
                    if (!(isa<ConstantInt>(inLhs) || isa<ConstantFP>(inLhs))) {
                        return false;
                    } else {
                        phis[PN] = 0;
                    }
                } else if (isa<BinaryOperator>(instr)) {
                    BinaryOperator* binop = cast<BinaryOperator>(instr);
                    if (!(OP_IN_RANGE(binop->getOpcode(), Add, FDiv))) {
                        return false;
                    }
                } else if (!(isa<BranchInst>(instr)
                            || isa<IndirectBrInst>(instr)))
                {
                    return false;
                }
            }
        }

        /* Extract the loop iterator if possible. */
        if (!icmp || !extractIterator(icmp)) {
            return false;
        } else {
            phis.erase(iter_var);
        }

        size_t phi_index = 0;
        for (auto kv = phis.begin(); kv != phis.end(); ++kv) {
            phis[kv->first] = phi_index++;
        }

        /* Find the initial state and all linear dependence relations. */
        size_t nr_phis = phis.size();
        MatrixXd InitialState(nr_phis, 1);
        MatrixXd TransformationMatrix(nr_phis, nr_phis);
        TransformationMatrix << MatrixXd::Zero(nr_phis, nr_phis);
        for (auto kv = phis.begin(); kv != phis.end(); ++kv) {
            PHINode* PN = kv->first;
            size_t phi_label = phis[PN];
            InitialState(phi_label, 0) = ToDouble(PN->getIncomingValue(0));

            Coefficients coeffs;
            if (!trackUpdates(PN->getIncomingValue(1), coeffs)) {
                return false;
            }
            for (auto ckv = coeffs.begin(); ckv != coeffs.end(); ++ckv) {
                size_t target_phi = phis[ckv->first];
                TransformationMatrix(phi_label, target_phi) = ckv->second;
            }
        }

        /* Diagonalize the transformation matrix. */
        EigenSolver<MatrixXd> EigSolver(TransformationMatrix);
        MatrixXcd P = EigSolver.eigenvectors();
        MatrixXcd D = EigSolver.eigenvalues().asDiagonal();
        MatrixXcd Pinv = P.inverse();
        if (!checkSystem(TransformationMatrix, InitialState, P, D, Pinv)) {
            return false;
        }

        /* Emit instructions to compute the closed form in a new block. */
        LLVMContext& ctx = blocks.front()->getContext();
        Module* mod = exit_block->getParent()->getParent();
        BasicBlock* dgen = BasicBlock::Create(ctx, "dgen", 0);
        Type* numTy = Type::getDoubleTy(ctx);
        std::vector<Type*> powProto(2, numTy);
        FunctionType* powType = FunctionType::get(numTy, powProto, false);
        Function* powf = Function::Create(powType,
            GlobalValue::ExternalLinkage, "llvm.pow.f64", mod);
        powf->setCallingConv(CallingConv::C);

        /* P(D^n) = r * λ^n : ∀(r) ∈ row(P) */
        Value** PDn = new Value*[nr_phis * nr_phis];
        for (size_t j = 0; j < nr_phis; ++j) {
            /* λ[j]^n */
            Value* exptargs[] = {
                ToConstantFP(ctx, std::real(D(j, j))), iter_final
            };
            Value* eigvexpt = CallInst::Create(powf,
                ArrayRef<Value*>(exptargs, 2), "eigvexpt", dgen);

            /* PDn[i][j] = P[i][j] * λ[j]^n */
            for (size_t i = 0; i < nr_phis; ++i) {
                size_t index = i * nr_phis + j;
                PDn[index] = BinaryOperator::Create(Instruction::FMul,
                    ToConstantFP(ctx, std::real(P(i, j))), eigvexpt, "pdn",
                    dgen);
            }
        }

        /* xf = P(D^n) * Pinv * x0 */
        Value** soln = new Value*[nr_phis];
        Value* zero = ToConstantFP(ctx, 0.0);
        for (size_t i = 0; i < nr_phis; ++i) {
            soln[i] = zero;
            for (size_t j = 0; j < nr_phis; ++j) {
                /* dotp = <a, b> : a ∈ row(P(D^n)), b ∈ col(Pinv) */
                Value* dotp = zero;
                for (size_t k = 0; k < nr_phis; ++k) {
                    Value* ik_kj = BinaryOperator::Create(Instruction::FMul,
                        PDn[i * nr_phis + k],
                        ToConstantFP(ctx, std::real(Pinv(k, j))),
                        "ik_kj", dgen);
                    dotp = BinaryOperator::Create(Instruction::FAdd,
                        ik_kj, dotp, "dotp", dgen);
                }

                /* xf[i] = ∑ P(D^n)Pinv[i][j] * x0[j] */
                Value* xj_prod = BinaryOperator::Create(Instruction::FMul,
                    dotp, ToConstantFP(ctx, InitialState(j)), "pdpxj",
                    dgen);
                soln[i] = BinaryOperator::Create(Instruction::FAdd,
                    xj_prod, soln[i], "xf", dgen);
            }
        }

        delete[] PDn;

        errs() << *dgen << "\n";

        /*
         * XXX:
         * 1) Replace incoming values to PHI nodes in the exit block with
         *    the correct results from dgen.
         * 2) Point outgoing edges from the loop preheader to dgen.
         * 3) Call eraseFromParent() on every BasicBlock in the loop.
         */

        /* Find dependencies on state variables outside of the loop. */
        for (auto II = exit_block->begin(); II != exit_block->end(); ++II) {
            Instruction* instr = II;
            if (isa<PHINode>(instr)) {
                PHINode* PN = cast<PHINode>(instr);
                if (PN->getBasicBlockIndex(blocks.back()) != -1) {
                    Value* V = PN->getIncomingValueForBlock(blocks.back());
                    for (auto kv = phis.begin(); kv != phis.end(); ++kv) {
                        if (kv->first->getIncomingValue(1) == V) {
                            /* We've found the PHI from our loop which
                             * feeds into the exit block. */

                            /* XXX */
                        }
                    }
                }
            }
        }

        delete[] soln;

        return false;
    }

private:
    bool extractIterator(ICmpInst* icmp) {
        /* In canonical form, we should get an icmp with the predicate
         * reduced to an equality test. */
        Value *cmpLhs, *cmpRhs;
        ICmpInst::Predicate IPred;
        if (match(icmp, m_ICmp(IPred, m_Value(cmpLhs),
                                      m_Value(cmpRhs)))
            && IPred == CmpInst::Predicate::ICMP_EQ)
        {
            /* We should be comparing against the final iterator value, which
             * should not be found in the loop body. */
            if (isa<Instruction>(cmpRhs)) {
                Instruction* instr = cast<Instruction>(cmpRhs);
                BasicBlock* BB = instr->getParent();
                if (!DT->properlyDominates(BB, blocks.front())) {
                    return false;
                }
                if (isa<Constant>(instr->getOperand(0))
                    || isa<Instruction>(instr->getOperand(0)))
                {
                    return false;
                }
                iter_final = instr->getOperand(0);
            } else {
                iter_final = cmpRhs;
            }

            /* Check if the loop increment is behaving as we expect it to. */
            Value *incrLhs, *incrRhs;
            if (match(cmpLhs, m_Add(m_Value(incrLhs), m_Value(incrRhs)))) {
                if (isa<PHINode>(incrLhs)
                    && isa<ConstantInt>(incrRhs)
                    && cast<ConstantInt>(incrRhs)->isOne())
                {
                    iter_var = cast<PHINode>(incrLhs);
                    Value* iter_initial = iter_var->getIncomingValue(0);
                    if (isa<ConstantInt>(iter_initial)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    bool trackUpdates(Value* parent, Coefficients& coeffs) {
        /* Determine the linear combination that produces 'parent'. */
        if (isa<Constant>(parent)) {
            return true;
        } else if (isa<PHINode>(parent)) {
            /* A PHINode should contribute a single copy of itself. */
            PHINode* PN = cast<PHINode>(parent);
            if (!phis.count(PN)) {
                return false;
            } else {
                coeffs[PN] = 1;
            }
        } else if (isa<BinaryOperator>(parent)) {
            BinaryOperator* binop = cast<BinaryOperator>(parent);
            int opcode = binop->getOpcode();
            Value *LHS = binop->getOperand(0), *RHS = binop->getOperand(1);

            Coefficients lhsCoeffs, rhsCoeffs;
            if (!trackUpdates(LHS, lhsCoeffs)
                || !trackUpdates(RHS, rhsCoeffs))
            {
                return false;
            }

            double scalar;
            if (OP_IN_RANGE(opcode, Add, FSub)) {
                /* Add instructions shouldn't operate on scalars. */
                if (isScalar(lhsCoeffs) || isScalar(rhsCoeffs)) {
                    return false;
                }
            } else {
                /* Mul instructions can only have one scalar operand. */
                if (isScalar(lhsCoeffs) ^ isScalar(rhsCoeffs)) {
                    return false;
                }

                /* Div instructions cannot have scalar numerators. */
                if (OP_IN_RANGE(opcode, UDiv, FDiv) && !isScalar(lhsCoeffs)) {
                    return false;
                }

                scalar = ToDouble(isScalar(lhsCoeffs) ? LHS : RHS);
            }

            /* Merge the two sets of coefficients. */
            for (auto kv = phis.begin(); kv != phis.end(); ++kv) {
                PHINode* PN = kv->first;
                double lcoeff = lhsCoeffs.lookup(PN);
                double rcoeff = rhsCoeffs.lookup(PN);

                /* Adding nil entries to 'coeffs' breaks isScalar(X). */
                if (lcoeff == 0.0 && rcoeff == 0.0) {
                    continue;
                }

                if (OP_IN_RANGE(opcode, Add, FAdd)) {
                    coeffs[PN] = lcoeff + rcoeff;
                } else if (OP_IN_RANGE(opcode, Sub, FSub)) {
                    coeffs[PN] = lcoeff - rcoeff;
                } else if (OP_IN_RANGE(opcode, Mul, FMul)) {
                    coeffs[PN] = scalar * (lcoeff + rcoeff);
                } else {
                    coeffs[PN] = (1 / scalar) * (lcoeff + rcoeff);
                }
            }
        } else return false;
        return true;
    }

    int64_t ToInt(Value* V) {
        return cast<ConstantInt>(V)->getValue().getSExtValue();
    }

    double ToDouble(Value* V) {
        if (isa<ConstantInt>(V)) {
            return double(ToInt(V));
        } else if (isa<ConstantFP>(V)) {
            return cast<ConstantFP>(V)->getValueAPF().convertToDouble();
        }
        return 0.0;
    }

    Value* ToConstantFP(LLVMContext& ctx, double n) {
        return ConstantFP::get(ctx, APFloat(n));
    }

    bool isScalar(Coefficients& coeffs) {
        return coeffs.size() == 0;
    }

    bool checkSystem(MatrixXd& A, MatrixXd& x,
                     MatrixXcd& P, MatrixXcd& D, MatrixXcd& Pinv)
    {
        /* Ensure that there are no complex eigenvectors. */
        for (int i = 0; i < P.rows(); ++i) {
            for (int j = 0; j < P.cols(); ++j) {
                if (std::imag(P(i, j)) != 0.0) {
                    return false;
                }
            }
        }

        /* Check that the diagonalization is reasonably accurate. */
        MatrixXd A3x = A*A*A*x;
        MatrixXcd PD3Px = (P*(D*D*D)*Pinv)*x;
        const double epsilon = 100 * std::numeric_limits<double>::epsilon();
        for (int i = 0; i < x.rows(); ++i) {
            if (epsilon <
                std::abs(std::abs(PD3Px(i, 0)) - std::abs(A3x(i, 0))))
            {
                return false;
            }
        }
        return true;
    }
};

char ADPass::ID = 0;

}

static RegisterPass<ADPass> X("auto-diagonalize",
    "Diagonalize linear dynamical systems", false, false);
<|endoftext|>


<commit_before>#include "filesystem/PathExt.h"
#include <algorithm>

namespace PathExt
{
	//REFACTOR: Move to StringExt
	std::string Replace(const std::string & source, const std::string & toReplace, const std::string & replacement)
	{
		std::size_t index = 0;
		std::string src = source;

		while (true)
		{
			index = src.find(toReplace, index);
		    if (index == std::string::npos) break;

		    src.replace(index, replacement.size(), replacement);
			index += replacement.size();
		}

		return src;
	}

	std::string Append(const std::string & path, const std::string & pathToAppend)
	{
		auto size = path.size();
		auto appendSize = pathToAppend.size();

		if(size > 0 && appendSize > 0)
		{
			if(path[size-1] == Separator[0] || pathToAppend[0] == Separator[0])
				return path + pathToAppend;
			else
				return path + Separator + pathToAppend;
		}

		return appendSize > 0 ? pathToAppend : path;
	}

	std::string GetFileName(const std::string & path)
	{
		auto pos = path.find_last_of(Separator);

		if(pos == std::string::npos)
			return path;

		return path.substr(pos+1);
	}

	std::string GetExtension(const std::string & path)
	{
		//Note: could avoid creating temp string
		auto name = GetFileName(path);

		if(name.size() > 0)
		{
			auto pos = name.find_last_of(".");

			if(pos != std::string::npos && pos > 0)
			{
				return name.substr(pos);
			}
		}

		return "";
	}

	std::string GetParentDirectory(const std::string & path)
	{
		auto pos = path.find_last_of(Separator);

		if(pos == std::string::npos)
			return path;

		return path.substr(0, pos);
	}

	bool HasFileName(const std::string & path)
	{
		return GetFileName(path).size() > 0;
	}

	std::string ConvertToUnixPath(const std::string & path)
	{
		return Replace(path, WindowsSeparator, Separator);
	}
}<commit_msg>Update PathExt.cpp<commit_after>#include "filesystem/PathExt.h"
#include <algorithm>

namespace PathExt
{
	//REFACTOR: Move to StringExt
	std::string Replace(const std::string & source, const std::string & toReplace, const std::string & replacement)
	{
		std::size_t index = 0;
		std::string src = source;

		while (true)
		{
			ind|ex = src.find(toReplace, index);
		    if (index == std::string::npos) break;

		    src.replace(index, replacement.size(), replacement);
			index += replacement.size();
		}

		return src;
	}

	std::string Append(const std::string & path, const std::string & pathToAppend)
	{
		auto size = path.size();
		auto appendSize = pathToAppend.size();

		if(size > 0 && appendSize > 0)
		{
			if(path[size-1] == Separator[0] || pathToAppend[0] == Separator[0])
				return path + pathToAppend;
			else
				return path + Separator + pathToAppend;
		}

		return appendSize > 0 ? pathToAppend : path;
	}

	std::string GetFileName(const std::string & path)
	{
		auto pos = path.find_last_of(Separator);

		if(pos == std::string::npos)
			return path;

		return path.substr(pos+1);
	}

	std::string GetExtension(const std::string & path)
	{
		//Note: could avoid creating temp string
		auto name = GetFileName(path);

		if(name.size() > 0)
		{
			auto pos = name.find_last_of(".");

			if(pos != std::string::npos && pos > 0)
			{
				return name.substr(pos);
			}
		}

		return "";
	}

	std::string GetParentDirectory(const std::string & path)
	{
		auto pos = path.find_last_of(Separator);

		if(pos == std::string::npos)
			return path;

		return path.substr(0, pos);
	}

	bool HasFileName(const std::string & path)
	{
		return GetFileName(path).size() > 0;
	}

	std::string ConvertToUnixPath(const std::string & path)
	{
		return Replace(path, WindowsSeparator, Separator);
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 Nicholas Corgan (n.corgan@gmail.com)
 *
 * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
 * or copy at http://opensource.org/licenses/MIT)
 */

#include <iostream>
#include <math.h>
#include <stdexcept>
#include <string>
#include <time.h>
#include <vector>

#include <pkmnsim/move.hpp>
#include <pkmnsim/enums.hpp>
#include <pkmnsim/team_pokemon.hpp>
#include <pkmnsim/database/queries.hpp>

#include <sqlitecpp/SQLiteCPP.h>

#include "team_pokemon_impl.hpp"
#include "team_pokemon_gen1impl.hpp"
#include "team_pokemon_gen2impl.hpp"
#include "team_pokemon_gen345impl.hpp"

using namespace std;

namespace pkmnsim
{
    team_pokemon::sptr team_pokemon::make(unsigned int id, unsigned int game, unsigned int level,
                                          unsigned int move1, unsigned int move2,
                                          unsigned int move3, unsigned int move4)
    {
        try
        {
            base_pokemon::sptr base = base_pokemon::make(id, game);

            if(base->get_generation() < 1 or base->get_generation() > 5) throw runtime_error("Gen must be 1-5.");

            switch(base->get_generation())
            {
                case 1:
                    return sptr(new team_pokemon_gen1impl(base, game, level,
                                                       move1, move2, move3, move4));

                case 2:
                    return sptr(new team_pokemon_gen2impl(base, game, level,
                                                       move1, move2, move3, move4));

                default:
                    return sptr(new team_pokemon_gen345impl(base, game, level,
                                                       move1, move2, move3, move4));
            }
        }
        catch(exception &e)
        {
            cout << "Caught exception: " << e.what() << endl;
            exit(EXIT_FAILURE);
        }
    }

    team_pokemon_impl::team_pokemon_impl(base_pokemon::sptr base, unsigned int game, unsigned int lvl,
                                         unsigned int move1, unsigned int move2,
                                         unsigned int move3, unsigned int move4): team_pokemon()
    {
        srand(time(NULL));
        personality = rand();
        trainer_id = rand();

        base_pkmn = base_pkmn;
        nickname = base_pkmn->get_species_name();
        level = lvl;
        from_game = game;
        from_gen = base_pkmn->get_generation();
        held_item = 0;
        ball = PokeBalls::POKE_BALL;

		attributes = dict<string, int>();
        moves = moveset_t(4);
        vla<unsigned int> move_PPs(4);

        icon_path = base_pkmn->get_icon_path(true);

        moves[0] = move::make(move1, from_game);
        move_PPs[0] = moves[0]->get_base_pp();

        moves[1] = move::make(move2, from_game);
        move_PPs[1] = moves[1]->get_base_pp();

        moves[2] = move::make(move3, from_game);
        move_PPs[2] = moves[2]->get_base_pp();

        moves[3] = move::make(move4, from_game);
        move_PPs[3] = moves[3]->get_base_pp();
    }

    base_pokemon::sptr team_pokemon_impl::get_base_pokemon() const {return base_pkmn;}

    string team_pokemon_impl::get_nickname() const {return nickname;}

    void team_pokemon_impl::set_nickname(std::string name)
    {
        if(name.length() == 0) nickname = base_pkmn->get_species_name();
        else if(name.length() <= 10) nickname = name;
    }

    unsigned int team_pokemon_impl::get_level() const {return level;}

    void team_pokemon_impl::set_level(unsigned int lvl)
    {
        if(lvl > 0 and lvl <= 100) level = lvl;
    }

    unsigned int team_pokemon_impl::get_met_level() const {return met_level;}

    void team_pokemon_impl::set_met_level(unsigned int lvl)
    {
        if(lvl > 0 and lvl <= 100) met_level = lvl;
    }

    moveset_t team_pokemon_impl::get_moves() const {return moves;}

    vla<unsigned int> team_pokemon_impl::get_move_PPs() const {return move_PPs;}

    void team_pokemon_impl::set_move(unsigned int move_id, unsigned int pos)
    {
        //Will fail if move is incompatible with this generation
        moves[pos] = move::make(move_id, from_game);
    }

    void team_pokemon_impl::set_move_PP(unsigned int new_PP, unsigned int pos)
    {
        //TODO: implement PP Up stats
        if(new_PP <= moves[pos]->get_base_pp()) move_PPs[pos] = new_PP;
    }

    unsigned int team_pokemon_impl::get_status() const {return nonvolatile_status;}

    void team_pokemon_impl::set_status(unsigned int status)
    {
        if(status >= Statuses::OK and status <= Statuses::SLEEP) nonvolatile_status = status;
        else status = Statuses::OK;
    }

    unsigned int team_pokemon_impl::get_personality() const {return personality;}

    void team_pokemon_impl::set_personality(unsigned int new_personality) {personality = new_personality;}

    unsigned int team_pokemon_impl::get_generation() const {return from_gen;}

    unsigned int team_pokemon_impl::get_held_item() const {return held_item;}

    void team_pokemon_impl::set_held_item(unsigned int item) {held_item = item;}

    unsigned int team_pokemon_impl::get_ball() const {return ball;}

    void team_pokemon_impl::set_ball(unsigned int new_ball) {ball = new_ball;}

    string team_pokemon_impl::get_icon_path() const {return icon_path;}

    string team_pokemon_impl::get_sprite_path() const {return sprite_path;}

	int team_pokemon_impl::get_attribute(string attribute) const {return attributes[attribute];}

    dict<string, int> team_pokemon_impl::get_attributes() const {return attributes;}

    bool team_pokemon_impl::has_attribute(string attribute) const {return attributes.has_key(attribute);}

	void team_pokemon_impl::set_attribute(string attribute, int value) {attributes[attribute] = value;}

    void team_pokemon_impl::set_hidden_ability(bool val) {has_hidden_ability = val;}

    unsigned int team_pokemon_impl::get_trainer_gender() const {return otgender;}

    void team_pokemon_impl::set_trainer_gender(unsigned int new_gender) {otgender = new_gender;}

    unsigned int team_pokemon_impl::get_trainer_id() const {return trainer_id;}

    unsigned short team_pokemon_impl::get_public_trainer_id() const {return tid.public_id;}

    unsigned short team_pokemon_impl::get_secret_trainer_id() const {return tid.secret_id;}

    void team_pokemon_impl::set_trainer_id(unsigned int id) {trainer_id = id;}

    void team_pokemon_impl::set_public_trainer_id(unsigned short id) {tid.public_id = id;}

    void team_pokemon_impl::set_secret_trainer_id(unsigned short id) {tid.secret_id = id;}

    vector<string> team_pokemon_impl::get_egg_group_names() const {return base_pkmn->get_egg_group_names();}

    string team_pokemon_impl::get_game_name() const {return database::get_game_name_from_id(from_game);}

    string team_pokemon_impl::get_species_name() const {return base_pkmn->get_species_name();}

    vector<unsigned int> team_pokemon_impl::get_egg_group_ids() const {return base_pkmn->get_egg_group_ids();}

    unsigned int team_pokemon_impl::get_game_id() const {return from_game;}

    unsigned int team_pokemon_impl::get_pokemon_id() const {return base_pkmn->get_pokemon_id();}

    unsigned int team_pokemon_impl::get_species_id() const {return base_pkmn->get_species_id();}

    dict<unsigned int, unsigned int> team_pokemon_impl::get_types() const {return base_pkmn->get_types();}

    dict<unsigned int, unsigned int> team_pokemon_impl::get_base_stats() const {return base_pkmn->get_base_stats();}

    dict<unsigned , unsigned int> team_pokemon_impl::get_ev_yields() const {return base_pkmn->get_ev_yields();}

    bool team_pokemon_impl::is_fully_evolved() const {return base_pkmn->is_fully_evolved();}
}
<commit_msg>team_pokemon uses PRNG to generate personality and trainer ID<commit_after>/*
 * Copyright (c) 2013 Nicholas Corgan (n.corgan@gmail.com)
 *
 * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
 * or copy at http://opensource.org/licenses/MIT)
 */

#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>

#include <pkmnsim/move.hpp>
#include <pkmnsim/enums.hpp>
#include <pkmnsim/team_pokemon.hpp>
#include <pkmnsim/database/queries.hpp>
#include <pkmnsim/types/prng.hpp>

#include <sqlitecpp/SQLiteCPP.h>

#include "team_pokemon_impl.hpp"
#include "team_pokemon_gen1impl.hpp"
#include "team_pokemon_gen2impl.hpp"
#include "team_pokemon_gen345impl.hpp"

using namespace std;

namespace pkmnsim
{
    team_pokemon::sptr team_pokemon::make(unsigned int id, unsigned int game, unsigned int level,
                                          unsigned int move1, unsigned int move2,
                                          unsigned int move3, unsigned int move4)
    {
        try
        {
            base_pokemon::sptr base = base_pokemon::make(id, game);

            if(base->get_generation() < 1 or base->get_generation() > 5) throw runtime_error("Gen must be 1-5.");

            switch(base->get_generation())
            {
                case 1:
                    return sptr(new team_pokemon_gen1impl(base, game, level,
                                                       move1, move2, move3, move4));

                case 2:
                    return sptr(new team_pokemon_gen2impl(base, game, level,
                                                       move1, move2, move3, move4));

                default:
                    return sptr(new team_pokemon_gen345impl(base, game, level,
                                                       move1, move2, move3, move4));
            }
        }
        catch(exception &e)
        {
            cout << "Caught exception: " << e.what() << endl;
            exit(EXIT_FAILURE);
        }
    }

    team_pokemon_impl::team_pokemon_impl(base_pokemon::sptr base, unsigned int game, unsigned int lvl,
                                         unsigned int move1, unsigned int move2,
                                         unsigned int move3, unsigned int move4): team_pokemon()
    {
        prng rand_gen;
        unsigned int gen = database::get_generation_from_game_id(game);

        personality = rand_gen.lcrng_next(gen);
        trainer_id = rand_gen.lcrng_next(gen);

        base_pkmn = base_pkmn;
        nickname = base_pkmn->get_species_name();
        level = lvl;
        from_game = game;
        from_gen = base_pkmn->get_generation();
        held_item = 0;
        ball = PokeBalls::POKE_BALL;

		attributes = dict<string, int>();
        moves = moveset_t(4);
        vla<unsigned int> move_PPs(4);

        icon_path = base_pkmn->get_icon_path(true);

        moves[0] = move::make(move1, from_game);
        move_PPs[0] = moves[0]->get_base_pp();

        moves[1] = move::make(move2, from_game);
        move_PPs[1] = moves[1]->get_base_pp();

        moves[2] = move::make(move3, from_game);
        move_PPs[2] = moves[2]->get_base_pp();

        moves[3] = move::make(move4, from_game);
        move_PPs[3] = moves[3]->get_base_pp();
    }

    base_pokemon::sptr team_pokemon_impl::get_base_pokemon() const {return base_pkmn;}

    string team_pokemon_impl::get_nickname() const {return nickname;}

    void team_pokemon_impl::set_nickname(std::string name)
    {
        if(name.length() == 0) nickname = base_pkmn->get_species_name();
        else if(name.length() <= 10) nickname = name;
    }

    unsigned int team_pokemon_impl::get_level() const {return level;}

    void team_pokemon_impl::set_level(unsigned int lvl)
    {
        if(lvl > 0 and lvl <= 100) level = lvl;
    }

    unsigned int team_pokemon_impl::get_met_level() const {return met_level;}

    void team_pokemon_impl::set_met_level(unsigned int lvl)
    {
        if(lvl > 0 and lvl <= 100) met_level = lvl;
    }

    moveset_t team_pokemon_impl::get_moves() const {return moves;}

    vla<unsigned int> team_pokemon_impl::get_move_PPs() const {return move_PPs;}

    void team_pokemon_impl::set_move(unsigned int move_id, unsigned int pos)
    {
        //Will fail if move is incompatible with this generation
        moves[pos] = move::make(move_id, from_game);
    }

    void team_pokemon_impl::set_move_PP(unsigned int new_PP, unsigned int pos)
    {
        //TODO: implement PP Up stats
        if(new_PP <= moves[pos]->get_base_pp()) move_PPs[pos] = new_PP;
    }

    unsigned int team_pokemon_impl::get_status() const {return nonvolatile_status;}

    void team_pokemon_impl::set_status(unsigned int status)
    {
        if(status >= Statuses::OK and status <= Statuses::SLEEP) nonvolatile_status = status;
        else status = Statuses::OK;
    }

    unsigned int team_pokemon_impl::get_personality() const {return personality;}

    void team_pokemon_impl::set_personality(unsigned int new_personality) {personality = new_personality;}

    unsigned int team_pokemon_impl::get_generation() const {return from_gen;}

    unsigned int team_pokemon_impl::get_held_item() const {return held_item;}

    void team_pokemon_impl::set_held_item(unsigned int item) {held_item = item;}

    unsigned int team_pokemon_impl::get_ball() const {return ball;}

    void team_pokemon_impl::set_ball(unsigned int new_ball) {ball = new_ball;}

    string team_pokemon_impl::get_icon_path() const {return icon_path;}

    string team_pokemon_impl::get_sprite_path() const {return sprite_path;}

	int team_pokemon_impl::get_attribute(string attribute) const {return attributes[attribute];}

    dict<string, int> team_pokemon_impl::get_attributes() const {return attributes;}

    bool team_pokemon_impl::has_attribute(string attribute) const {return attributes.has_key(attribute);}

	void team_pokemon_impl::set_attribute(string attribute, int value) {attributes[attribute] = value;}

    void team_pokemon_impl::set_hidden_ability(bool val) {has_hidden_ability = val;}

    unsigned int team_pokemon_impl::get_trainer_gender() const {return otgender;}

    void team_pokemon_impl::set_trainer_gender(unsigned int new_gender) {otgender = new_gender;}

    unsigned int team_pokemon_impl::get_trainer_id() const {return trainer_id;}

    unsigned short team_pokemon_impl::get_public_trainer_id() const {return tid.public_id;}

    unsigned short team_pokemon_impl::get_secret_trainer_id() const {return tid.secret_id;}

    void team_pokemon_impl::set_trainer_id(unsigned int id) {trainer_id = id;}

    void team_pokemon_impl::set_public_trainer_id(unsigned short id) {tid.public_id = id;}

    void team_pokemon_impl::set_secret_trainer_id(unsigned short id) {tid.secret_id = id;}

    vector<string> team_pokemon_impl::get_egg_group_names() const {return base_pkmn->get_egg_group_names();}

    string team_pokemon_impl::get_game_name() const {return database::get_game_name_from_id(from_game);}

    string team_pokemon_impl::get_species_name() const {return base_pkmn->get_species_name();}

    vector<unsigned int> team_pokemon_impl::get_egg_group_ids() const {return base_pkmn->get_egg_group_ids();}

    unsigned int team_pokemon_impl::get_game_id() const {return from_game;}

    unsigned int team_pokemon_impl::get_pokemon_id() const {return base_pkmn->get_pokemon_id();}

    unsigned int team_pokemon_impl::get_species_id() const {return base_pkmn->get_species_id();}

    dict<unsigned int, unsigned int> team_pokemon_impl::get_types() const {return base_pkmn->get_types();}

    dict<unsigned int, unsigned int> team_pokemon_impl::get_base_stats() const {return base_pkmn->get_base_stats();}

    dict<unsigned , unsigned int> team_pokemon_impl::get_ev_yields() const {return base_pkmn->get_ev_yields();}

    bool team_pokemon_impl::is_fully_evolved() const {return base_pkmn->is_fully_evolved();}
}
<|endoftext|>