<commit_before>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * 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.
 *
 */

#include <votca/csg/topology.h>
#include <votca/csg/interaction.h>
#include <votca/tools/rangeparser.h>
#include <stdexcept>

namespace votca { namespace csg {

Topology::~Topology()
{
    Cleanup();
    if(_bc)
        delete (_bc);
    _bc = NULL;
}

void Topology::Cleanup()
{
    // cleanup beads
    {
        BeadContainer::iterator i;
        for(i=_beads.begin();i<_beads.end();++i)
            delete *i;
        _beads.clear();
    }
    // cleanup molecules
    {
        MoleculeContainer::iterator i;
        for(i=_molecules.begin();i<_molecules.end();++i)
            delete *i;
        _molecules.clear();
    }
    // cleanup residues
    {
        ResidueContainer::iterator i;
        for(i=_residues.begin();i<_residues.end();++i)
            delete (*i);
        _residues.clear();
    }
    // cleanup interactions
    {
        InteractionContainer::iterator i;
        for(i=_interactions.begin();i<_interactions.end();++i)
            delete (*i);
        _interactions.clear();
    }
    // cleanup _bc object
    if(_bc)
        delete (_bc);
    _bc = new OpenBox();
}

/// \todo implement checking!!
void Topology::CreateMoleculesByRange(string name, int first, int nbeads, int nmolecules)
{
    Molecule *mol = CreateMolecule(name);
    int beadcount=0;

    BeadContainer::iterator bead;
    for(bead=_beads.begin(); bead!=_beads.end(); ++bead) {
        if(first-- > 0) continue;
        string bname = //lexical_cast<string>(mol->getId()) + ":"
                      //lexical_cast<string>(bead->Residue()) + ":"
                      //+
                      (*bead)->getName();
        mol->AddBead((*bead), bname);
        if(++beadcount == nbeads) {
            if(--nmolecules <= 0) break;
            mol = CreateMolecule(name);
            beadcount = 0;
        }
    }
}

/// \todo clean up CreateMoleculesByResidue!
void Topology::CreateMoleculesByResidue()
{
    // first create a molecule for each residue
    ResidueContainer::iterator res;
    for(res=_residues.begin(); res!=_residues.end(); ++res) {
        CreateMolecule((*res)->getName());
    }

    // add the beads to the corresponding molecules based on their resid
    BeadContainer::iterator bead;
    for(bead=_beads.begin(); bead!=_beads.end(); ++bead) {
        //MoleculeByIndex((*bead)->getResnr())->AddBead((*bead)->getId(), (*bead)->getName());

        MoleculeByIndex((*bead)->getResnr())->AddBead((*bead), string("1:TRI:") + (*bead)->getName());
    }

    /// \todo sort beads in molecules that all beads are stored in the same order. This is needed for the mapping!
}

void Topology::CreateOneBigMolecule(string name)
{
    Molecule *mi = CreateMolecule(name);

    BeadContainer::iterator bead;

    for(bead=_beads.begin(); bead!=_beads.end(); ++bead) {
        stringstream n("");
        n << (*bead)->getResnr() +1 << ":" <<  _residues[(*bead)->getResnr()]->getName() << ":" << (*bead)->getName();
        //cout << n.str() << endl;
        mi->AddBead((*bead), n.str());
    }
}

void Topology::Add(Topology *top)
{
    BeadContainer::iterator bead;
    ResidueContainer::iterator res;
    MoleculeContainer::iterator mol;

    int res0=ResidueCount();

    for(bead=top->_beads.begin(); bead!=top->_beads.end(); ++bead) {
        Bead *bi = *bead;
        BeadType *type =  GetOrCreateBeadType(bi->getType()->getName());
        CreateBead(bi->getSymmetry(), bi->getName(), type, bi->getResnr()+res0, bi->getM(), bi->getQ());
    }

    for(res=top->_residues.begin();res!=top->_residues.end(); ++res) {
        CreateResidue((*res)->getName());
    }

    // \todo beadnames in molecules!!
    for(mol=top->_molecules.begin();mol!=top->_molecules.end(); ++mol) {
        Molecule *mi = CreateMolecule((*mol)->getName());
        for(int i=0; i<mi->BeadCount(); i++) {
            mi->AddBead(mi->getBead(i), "invalid");
        }
    }
}

void Topology::CopyTopologyData(Topology *top)
{
    BeadContainer::iterator it_bead;
    ResidueContainer::iterator it_res;
    MoleculeContainer::iterator it_mol;
    InteractionContainer::iterator it_ia;

    _bc->setBox(top->getBox());
    _time = top->_time;
    _step = top->_step;

    // cleanup old data
    Cleanup();

    // copy all residues
    for(it_res=top->_residues.begin();it_res!=top->_residues.end(); ++it_res) {
        CreateResidue((*it_res)->getName());
    }

    // create all beads
    for(it_bead=top->_beads.begin(); it_bead!=top->_beads.end(); ++it_bead) {
        Bead *bi = *it_bead;
        BeadType *type =  GetOrCreateBeadType(bi->getType()->getName());
        Bead *bn = CreateBead(bi->getSymmetry(), bi->getName(), type, bi->getResnr(), bi->getM(), bi->getQ());
        bn->setOptions(bi->Options());
    }

    // copy all molecules
    for(it_mol=top->_molecules.begin();it_mol!=top->_molecules.end(); ++it_mol) {
        Molecule *mi = CreateMolecule((*it_mol)->getName());
        for(int i=0; i<(*it_mol)->BeadCount(); i++) {
            int beadid = (*it_mol)->getBead(i)->getId();
            mi->AddBead(_beads[beadid], (*it_mol)->getBeadName(i));
        }
    }
    // TODO: copy interactions
    //for(it_ia=top->_interaction.begin();it_ia=top->_interactions.end();++it_ia) {

    //}
}

void Topology::RenameMolecules(string range, string name)
{
    RangeParser rp;
    RangeParser::iterator i;

    rp.Parse(range);
    for(i=rp.begin();i!=rp.end();++i) {
        if((unsigned int)*i > _molecules.size())
            throw runtime_error(string("RenameMolecules: num molecules smaller than"));
        getMolecule(*i-1)->setName(name);
    }
}

void Topology::CheckMoleculeNaming(void)
{
    map<string,int> nbeads;

    for(MoleculeContainer::iterator iter = _molecules.begin(); iter!=_molecules.end(); ++iter) {
        map<string,int>::iterator entry = nbeads.find((*iter)->getName());
        if(entry != nbeads.end()) {
            if(entry->second != (*iter)->BeadCount())
                throw runtime_error("There are molecules which have the same name but different number of bead "
                        "please check the section manual topology handling in the votca manual");
            continue;
        }
        nbeads[(*iter)->getName()] = (*iter)->BeadCount();
    }
}

void Topology::AddBondedInteraction(Interaction *ic)
{
    map<string,int>::iterator iter;
    iter = _interaction_groups.find(ic->getGroup());
    if(iter!=_interaction_groups.end())
        ic->setGroupId((*iter).second);
    else {
        int i= _interaction_groups.size();
        _interaction_groups[ic->getGroup()] = i;
        ic->setGroupId(i);
    }
    _interactions.push_back(ic);
    _interactions_by_group[ic->getGroup()].push_back(ic);
}

std::list<Interaction *> Topology::InteractionsInGroup(const string &group)
{
    map<string, list<Interaction*> >::iterator iter;
    iter = _interactions_by_group.find(group);
    if(iter == _interactions_by_group.end())
        return list<Interaction *>();
    return iter->second;
}

BeadType *Topology::GetOrCreateBeadType(string name)
{
    map<string, int>::iterator iter;

    iter = _beadtype_map.find(name);
    if(iter == _beadtype_map.end()) {
        BeadType *bt = new BeadType(this, _beadtypes.size(), name);
        _beadtypes.push_back(bt);
        _beadtype_map[name] = bt->getId();
        return bt;
    }
    else {
        return _beadtypes[(*iter).second];
    }
    return NULL;
}

vec Topology::BCShortestConnection(const vec &r_i, const vec &r_j) const
{
    return _bc->BCShortestConnection(r_i, r_j);
}

vec Topology::getDist(int bead1, int bead2) const
{
    return BCShortestConnection(
            getBead(bead1)->getPos(),
            getBead(bead2)->getPos());
}

double Topology::BoxVolume()
{
    return _bc->BoxVolume();
}

void Topology::RebuildExclusions()
{
    _exclusions.CreateExclusions(this);
}

BoundaryCondition::eBoxtype Topology::autoDetectBoxType(const matrix &box) {
    // set the box type to OpenBox in case "box" is the zero matrix,
    // to OrthorhombicBox in case "box" is a diagonal matrix,
    // or to TriclinicBox otherwise
    if(box.get(0,0)==0 && box.get(0,1)==0 && box.get(0,2)==0 &&
       box.get(1,0)==0 && box.get(1,1)==0 && box.get(1,2)==0 &&
       box.get(2,0)==0 && box.get(2,1)==0 && box.get(2,2)==0) {
        //cout << "box open\n";
        return BoundaryCondition::typeOpen;
    }
    else
    if(box.get(0,1)==0 && box.get(0,2)==0 &&
       box.get(1,0)==0 && box.get(1,2)==0 &&
       box.get(2,0)==0 && box.get(2,1)==0) {
        //cout << "box orth\n";
        return BoundaryCondition::typeOrthorhombic;
    }
    else {
        //cout << "box tric\n";
        return BoundaryCondition::typeTriclinic;
    }
    return BoundaryCondition::typeOpen;
}

double Topology::ShortestBoxSize()
{
    vec _box_a = getBox().getCol(0);
    vec _box_b = getBox().getCol(1);
    vec _box_c = getBox().getCol(2);

    // create plane normals
    vec _norm_a = _box_b ^ _box_c;
    vec _norm_b = _box_c ^ _box_a;
    vec _norm_c = _box_a ^ _box_b;

    _norm_a.normalize();
    _norm_b.normalize();
    _norm_c.normalize();

    double la = _box_a * _norm_a;
    double lb = _box_b * _norm_b;
    double lc = _box_c * _norm_c;

    return min(la, min(lb, lc));
}

}}
<commit_msg>CreateMoleculesByRange: first should >=1<commit_after>/*
 * Copyright 2009-2011 The VOTCA Development Team (http://www.votca.org)
 *
 * 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.
 *
 */

#include <votca/csg/topology.h>
#include <votca/csg/interaction.h>
#include <votca/tools/rangeparser.h>
#include <stdexcept>

namespace votca { namespace csg {

Topology::~Topology()
{
    Cleanup();
    if(_bc)
        delete (_bc);
    _bc = NULL;
}

void Topology::Cleanup()
{
    // cleanup beads
    {
        BeadContainer::iterator i;
        for(i=_beads.begin();i<_beads.end();++i)
            delete *i;
        _beads.clear();
    }
    // cleanup molecules
    {
        MoleculeContainer::iterator i;
        for(i=_molecules.begin();i<_molecules.end();++i)
            delete *i;
        _molecules.clear();
    }
    // cleanup residues
    {
        ResidueContainer::iterator i;
        for(i=_residues.begin();i<_residues.end();++i)
            delete (*i);
        _residues.clear();
    }
    // cleanup interactions
    {
        InteractionContainer::iterator i;
        for(i=_interactions.begin();i<_interactions.end();++i)
            delete (*i);
        _interactions.clear();
    }
    // cleanup _bc object
    if(_bc)
        delete (_bc);
    _bc = new OpenBox();
}

/// \todo implement checking!!
void Topology::CreateMoleculesByRange(string name, int first, int nbeads, int nmolecules)
{
    Molecule *mol = CreateMolecule(name);
    int beadcount=0;

    BeadContainer::iterator bead;
    for(bead=_beads.begin(); bead!=_beads.end(); ++bead) {
	//xml numbering starts with 1
        if(--first > 0) continue;
        string bname = //lexical_cast<string>(mol->getId()) + ":"
                      //lexical_cast<string>(bead->Residue()) + ":"
                      //+
                      (*bead)->getName();
        mol->AddBead((*bead), bname);
        if(++beadcount == nbeads) {
            if(--nmolecules <= 0) break;
            mol = CreateMolecule(name);
            beadcount = 0;
        }
    }
}

/// \todo clean up CreateMoleculesByResidue!
void Topology::CreateMoleculesByResidue()
{
    // first create a molecule for each residue
    ResidueContainer::iterator res;
    for(res=_residues.begin(); res!=_residues.end(); ++res) {
        CreateMolecule((*res)->getName());
    }

    // add the beads to the corresponding molecules based on their resid
    BeadContainer::iterator bead;
    for(bead=_beads.begin(); bead!=_beads.end(); ++bead) {
        //MoleculeByIndex((*bead)->getResnr())->AddBead((*bead)->getId(), (*bead)->getName());

        MoleculeByIndex((*bead)->getResnr())->AddBead((*bead), string("1:TRI:") + (*bead)->getName());
    }

    /// \todo sort beads in molecules that all beads are stored in the same order. This is needed for the mapping!
}

void Topology::CreateOneBigMolecule(string name)
{
    Molecule *mi = CreateMolecule(name);

    BeadContainer::iterator bead;

    for(bead=_beads.begin(); bead!=_beads.end(); ++bead) {
        stringstream n("");
        n << (*bead)->getResnr() +1 << ":" <<  _residues[(*bead)->getResnr()]->getName() << ":" << (*bead)->getName();
        //cout << n.str() << endl;
        mi->AddBead((*bead), n.str());
    }
}

void Topology::Add(Topology *top)
{
    BeadContainer::iterator bead;
    ResidueContainer::iterator res;
    MoleculeContainer::iterator mol;

    int res0=ResidueCount();

    for(bead=top->_beads.begin(); bead!=top->_beads.end(); ++bead) {
        Bead *bi = *bead;
        BeadType *type =  GetOrCreateBeadType(bi->getType()->getName());
        CreateBead(bi->getSymmetry(), bi->getName(), type, bi->getResnr()+res0, bi->getM(), bi->getQ());
    }

    for(res=top->_residues.begin();res!=top->_residues.end(); ++res) {
        CreateResidue((*res)->getName());
    }

    // \todo beadnames in molecules!!
    for(mol=top->_molecules.begin();mol!=top->_molecules.end(); ++mol) {
        Molecule *mi = CreateMolecule((*mol)->getName());
        for(int i=0; i<mi->BeadCount(); i++) {
            mi->AddBead(mi->getBead(i), "invalid");
        }
    }
}

void Topology::CopyTopologyData(Topology *top)
{
    BeadContainer::iterator it_bead;
    ResidueContainer::iterator it_res;
    MoleculeContainer::iterator it_mol;
    InteractionContainer::iterator it_ia;

    _bc->setBox(top->getBox());
    _time = top->_time;
    _step = top->_step;

    // cleanup old data
    Cleanup();

    // copy all residues
    for(it_res=top->_residues.begin();it_res!=top->_residues.end(); ++it_res) {
        CreateResidue((*it_res)->getName());
    }

    // create all beads
    for(it_bead=top->_beads.begin(); it_bead!=top->_beads.end(); ++it_bead) {
        Bead *bi = *it_bead;
        BeadType *type =  GetOrCreateBeadType(bi->getType()->getName());
        Bead *bn = CreateBead(bi->getSymmetry(), bi->getName(), type, bi->getResnr(), bi->getM(), bi->getQ());
        bn->setOptions(bi->Options());
    }

    // copy all molecules
    for(it_mol=top->_molecules.begin();it_mol!=top->_molecules.end(); ++it_mol) {
        Molecule *mi = CreateMolecule((*it_mol)->getName());
        for(int i=0; i<(*it_mol)->BeadCount(); i++) {
            int beadid = (*it_mol)->getBead(i)->getId();
            mi->AddBead(_beads[beadid], (*it_mol)->getBeadName(i));
        }
    }
    // TODO: copy interactions
    //for(it_ia=top->_interaction.begin();it_ia=top->_interactions.end();++it_ia) {

    //}
}

void Topology::RenameMolecules(string range, string name)
{
    RangeParser rp;
    RangeParser::iterator i;

    rp.Parse(range);
    for(i=rp.begin();i!=rp.end();++i) {
        if((unsigned int)*i > _molecules.size())
            throw runtime_error(string("RenameMolecules: num molecules smaller than"));
        getMolecule(*i-1)->setName(name);
    }
}

void Topology::CheckMoleculeNaming(void)
{
    map<string,int> nbeads;

    for(MoleculeContainer::iterator iter = _molecules.begin(); iter!=_molecules.end(); ++iter) {
        map<string,int>::iterator entry = nbeads.find((*iter)->getName());
        if(entry != nbeads.end()) {
            if(entry->second != (*iter)->BeadCount())
                throw runtime_error("There are molecules which have the same name but different number of bead "
                        "please check the section manual topology handling in the votca manual");
            continue;
        }
        nbeads[(*iter)->getName()] = (*iter)->BeadCount();
    }
}

void Topology::AddBondedInteraction(Interaction *ic)
{
    map<string,int>::iterator iter;
    iter = _interaction_groups.find(ic->getGroup());
    if(iter!=_interaction_groups.end())
        ic->setGroupId((*iter).second);
    else {
        int i= _interaction_groups.size();
        _interaction_groups[ic->getGroup()] = i;
        ic->setGroupId(i);
    }
    _interactions.push_back(ic);
    _interactions_by_group[ic->getGroup()].push_back(ic);
}

std::list<Interaction *> Topology::InteractionsInGroup(const string &group)
{
    map<string, list<Interaction*> >::iterator iter;
    iter = _interactions_by_group.find(group);
    if(iter == _interactions_by_group.end())
        return list<Interaction *>();
    return iter->second;
}

BeadType *Topology::GetOrCreateBeadType(string name)
{
    map<string, int>::iterator iter;

    iter = _beadtype_map.find(name);
    if(iter == _beadtype_map.end()) {
        BeadType *bt = new BeadType(this, _beadtypes.size(), name);
        _beadtypes.push_back(bt);
        _beadtype_map[name] = bt->getId();
        return bt;
    }
    else {
        return _beadtypes[(*iter).second];
    }
    return NULL;
}

vec Topology::BCShortestConnection(const vec &r_i, const vec &r_j) const
{
    return _bc->BCShortestConnection(r_i, r_j);
}

vec Topology::getDist(int bead1, int bead2) const
{
    return BCShortestConnection(
            getBead(bead1)->getPos(),
            getBead(bead2)->getPos());
}

double Topology::BoxVolume()
{
    return _bc->BoxVolume();
}

void Topology::RebuildExclusions()
{
    _exclusions.CreateExclusions(this);
}

BoundaryCondition::eBoxtype Topology::autoDetectBoxType(const matrix &box) {
    // set the box type to OpenBox in case "box" is the zero matrix,
    // to OrthorhombicBox in case "box" is a diagonal matrix,
    // or to TriclinicBox otherwise
    if(box.get(0,0)==0 && box.get(0,1)==0 && box.get(0,2)==0 &&
       box.get(1,0)==0 && box.get(1,1)==0 && box.get(1,2)==0 &&
       box.get(2,0)==0 && box.get(2,1)==0 && box.get(2,2)==0) {
        //cout << "box open\n";
        return BoundaryCondition::typeOpen;
    }
    else
    if(box.get(0,1)==0 && box.get(0,2)==0 &&
       box.get(1,0)==0 && box.get(1,2)==0 &&
       box.get(2,0)==0 && box.get(2,1)==0) {
        //cout << "box orth\n";
        return BoundaryCondition::typeOrthorhombic;
    }
    else {
        //cout << "box tric\n";
        return BoundaryCondition::typeTriclinic;
    }
    return BoundaryCondition::typeOpen;
}

double Topology::ShortestBoxSize()
{
    vec _box_a = getBox().getCol(0);
    vec _box_b = getBox().getCol(1);
    vec _box_c = getBox().getCol(2);

    // create plane normals
    vec _norm_a = _box_b ^ _box_c;
    vec _norm_b = _box_c ^ _box_a;
    vec _norm_c = _box_a ^ _box_b;

    _norm_a.normalize();
    _norm_b.normalize();
    _norm_c.normalize();

    double la = _box_a * _norm_a;
    double lb = _box_b * _norm_b;
    double lc = _box_c * _norm_c;

    return min(la, min(lb, lc));
}

}}
<|endoftext|>


<commit_before>#include "qmpair.h"
#include "qmtopology.h"

QMPair::QMPair(QMCrgUnit *crg1, QMCrgUnit *crg2, QMTopology * top):std::pair<QMCrgUnit *, QMCrgUnit *>(crg1,crg2)
{
    QMPair();
    vec crg1nm,crg2nm;
    crg1nm =  crg1->GetCom();
    crg2nm =  crg2->GetCom();
    _r = top->BCShortestConnection(crg1nm, crg2nm);
    _crg2 = second;

    // check if PBC:
    vec d = crg2nm - crg1nm;
    if (abs(d - _r) > 1e-8) {
        _ghost = new QMCrgUnit();
	_ghost->copyCrgUnit(*crg2);
        vec displ = (_r - d);
        _ghost->shift(displ);
        _crg2 = _ghost;
    }
    else {
        _ghost=NULL;
    }
}

double QMPair::calcJeff2(){
    vector<double>::iterator itj=_Js.begin();
    double j=0.;
    for (;itj!= _Js.end(); itj++){
        j+=(*itj)*(*itj);
    }
    j/= double(_Js.size());
    return j;
}<commit_msg>fixed constructor delegation<commit_after>#include "qmpair.h"
#include "qmtopology.h"

QMPair::QMPair(QMCrgUnit *crg1, QMCrgUnit *crg2, QMTopology * top):std::pair<QMCrgUnit *, QMCrgUnit *>(crg1,crg2)
, _rate_12(0.),_rate_21(0.),_lambda_outer(0.)
{
    vec crg1nm,crg2nm;
    crg1nm =  crg1->GetCom();
    crg2nm =  crg2->GetCom();
    _r = top->BCShortestConnection(crg1nm, crg2nm);
    _crg2 = second;

    // check if PBC:
    vec d = crg2nm - crg1nm;
    if (abs(d - _r) > 1e-8) {
        _ghost = new QMCrgUnit();
	_ghost->copyCrgUnit(*crg2);
        vec displ = (_r - d);
        _ghost->shift(displ);
        _crg2 = _ghost;
    }
    else {
        _ghost=NULL;
    }
}

double QMPair::calcJeff2(){
    vector<double>::iterator itj=_Js.begin();
    double j=0.;
    for (;itj!= _Js.end(); itj++){
        j+=(*itj)*(*itj);
    }
    j/= double(_Js.size());
    return j;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2001-2003 Peter J Jones (pjones@pmade.org)
 * All Rights Reserved
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name of the Author nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "utility.h"
#include <cstdarg>
#include <cstdlib>
#include <cstring>
#include <string>

// hack to pull in vsnprintf for MSVC6
#if defined(_MSC_VER) && _MSC_VER <= 1200
#  undef vsnprintf
#  define vsnprintf _vsnprintf
#endif

namespace xml {

    //####################################################################
    void printf2string (std::string &s, const char *message, va_list ap) {
	char buffer[512];

	std::memset(buffer, 0, sizeof(buffer));

	// XXX vsnprintf is non-standard
	if (vsnprintf(buffer, sizeof(buffer), message, ap) > 0) {
	    std::string::size_type size = std::strlen(buffer);

	    if (buffer[size-1] == '\n') --size;
	    s.assign(buffer, size);
	}
    }
    //####################################################################

} // end xml namespace
<commit_msg>compilation fix for Comeau C++ on Windows (patch by Greg Chicares)<commit_after>/*
 * Copyright (C) 2001-2003 Peter J Jones (pjones@pmade.org)
 * All Rights Reserved
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name of the Author nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "utility.h"
#include <cstdarg>
#include <cstdlib>
#include <cstring>
#include <string>

// hack to pull in vsnprintf for MSVC6
#if (defined(_MSC_VER) && _MSC_VER <= 1200) || (defined(__COMO__) && defined(__WIN32__))
#  undef vsnprintf
#  define vsnprintf _vsnprintf
#endif

namespace xml {

    //####################################################################
    void printf2string (std::string &s, const char *message, va_list ap) {
	char buffer[512];

	std::memset(buffer, 0, sizeof(buffer));

	// XXX vsnprintf is non-standard
	if (vsnprintf(buffer, sizeof(buffer), message, ap) > 0) {
	    std::string::size_type size = std::strlen(buffer);

	    if (buffer[size-1] == '\n') --size;
	    s.assign(buffer, size);
	}
    }
    //####################################################################

} // end xml namespace
<|endoftext|>


<commit_before>// ComplexCi.cpp : ̨Ӧóڵ㡣
//

//#include "stdafx.h"

#include <iostream>
#include <vector>
#include <set>
#include <fstream>
#include <string>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <sstream>
#include <iterator>
#include <queue>
#include <algorithm>

using namespace std;

template<typename Out>
void split(const std::string &s, char delim, Out result) {
	std::stringstream ss;
	ss.str(s);
	std::string item;
	while (std::getline(ss, item, delim)) {
		*(result++) = item;
	}
}

std::vector<std::string> split(const std::string &s, char delim) {
	std::vector<std::string> elems;
	split(s, delim, std::back_inserter(elems));
	return elems;
}

void getNeighbourFrontierAndScope(const vector<vector<int> > &adjListGraph, int scope, int currentNode, unordered_set<int> &currentSet, unordered_set<int>& alreadyAccess)
{
	//alreadyAccess.reserve(100000);

	currentSet.insert(currentNode);
	alreadyAccess.insert(currentNode);

	for (int i = 0; i < scope; i++)
	{
		unordered_set<int> nextSet;
		//nextSet.reserve(30000);

		for (const auto& node : currentSet)
		{
			const vector<int>& neighbourNodeList = adjListGraph[node];

			for (const auto& eachNeighbour : neighbourNodeList)
			{
				if (alreadyAccess.find(eachNeighbour) == alreadyAccess.end())
				{
					nextSet.insert(eachNeighbour);
					alreadyAccess.insert(eachNeighbour);
				}
			}

		}

		currentSet = move(nextSet);
	}
}

long long basicCi(const vector<vector<int> > &adjListGraph, int ballRadius, int currentNode)
{
	if (adjListGraph[currentNode].size() == 0)
	{
		return -1;
	}

	unordered_set<int> currentFrontier;
	unordered_set<int> dummyValue;

	getNeighbourFrontierAndScope(adjListGraph, ballRadius, currentNode, currentFrontier, dummyValue);

	long long ci = 0;

	for (auto node : currentFrontier)
	{
		ci += (adjListGraph[node].size() - 1);
	}

	ci *= (adjListGraph[currentNode].size() - 1);

	/*
	if (currentNode % 500 == 0)
	{
		cout << currentNode << " currentFrontier size :" << currentFrontier.size() << endl;
	}
	*/

	/*
	if (currentNode == 1715132 && (ci == 0 || ci == 2))
	{
		cout << "currentNode: " << currentNode << " adjListGraph[currentNode].size(): " << adjListGraph[currentNode].size() << "/ ";

		for (auto node : adjListGraph[currentNode])
		{
			cout << node << " " ;
		}

		cout << endl;

		cout << "ci: " << ci << endl;

		cout << "currentFrontier: " << endl;

		for (auto node : currentFrontier)
		{
			cout << node << " " << adjListGraph[node].size() << endl;
		}

		cout << "dummyValue: " << endl;

		for (auto node : dummyValue)
		{
			cout << node << " node1: ";

			for (auto node1 : adjListGraph[node])
			{
				cout <<  node1 << " ";
			}
			cout << endl;
		}
		cout << endl;

	}
	*/

	return ci;
}

void deleteNode(vector<vector<int> > &adjListGraph, int node)
{
	/*
	if (adjListGraph[node].size() == 0)
	{
	return;
	} // not must here
	*/

	for (auto neighbour : adjListGraph[node])
	{
		adjListGraph[neighbour].erase(remove(adjListGraph[neighbour].begin(), adjListGraph[neighbour].end(), node), adjListGraph[neighbour].end());
	}

	adjListGraph[node].clear();

}

int main(int argc, char* argv[])
{
	unsigned int ballRadius = 1;
	unsigned int updateBatch = 1;
	unsigned int outputNumBatch = 1;

	string path = "";
	string output = "";

	if (argc > 4)
	{
		path = argv[1];
		output = path + "_out";

		ballRadius = stoi(argv[2]);
		updateBatch = stoi(argv[3]);
		outputNumBatch = stoi(argv[4]);

	}
	else
	{
		cout << "at least 3 parameters for csv path" << endl;
		cout << "e.g. 'C:/Users/zhfkt/Documents/Visual Studio 2013/Projects/ComplexCi/Release/karate.txt' 2 500 500" << endl;
		return 0;
	}

	string modelID = "";

	{
		vector<string> fileName = split(path, '/');
		modelID = split(fileName[fileName.size() - 1], '.')[0];
	}

	std::cout << "path: " << path << endl;
	std::cout << "output: " << output << endl;
	std::cout << "modelID: " << modelID << endl;

	std::cout << "ballRadius: " << ballRadius << endl;
	std::cout << "updateBatch: " << updateBatch << endl;
	std::cout << "outputNumBatch: " << outputNumBatch << endl;

	std::cout << "First Read Start" << endl;

	unordered_set<int> allVex;
	string eachLine;
	ifstream is;
	is.open(path);

	while (is >> eachLine)
	{
		vector<string> csvEachLine = split(eachLine, ',');

		allVex.insert(stoi(csvEachLine[0]));
		allVex.insert(stoi(csvEachLine[1]));

	}
	is.close();
	int totalSize = allVex.size();

	std::cout << "First Read End/Second Read Start" << endl;

	vector<vector<int> > adjListGraph(totalSize);
	is.open(path);
	while (is >> eachLine)
	{
		vector<string> csvEachLine = split(eachLine, ',');

		adjListGraph[stoi(csvEachLine[0])].push_back(stoi(csvEachLine[1]));
		adjListGraph[stoi(csvEachLine[1])].push_back(stoi(csvEachLine[0]));
	}

	std::cout << "Second Read End" << endl;

	//--------------

	set<pair<long long, int> > allPQ; //ci/currentNode --- long is 32 bit on the win and long long is 64 bit / and long long can be multiple
	vector<long long> revereseLoopUpAllPQ(totalSize);
	cout << "modelID: " << modelID << " First Cal CI" << endl;

	for (int i = 0; i < adjListGraph.size(); i++)
	{
		int currentNode = i;
		// core_ci
		long long ci = basicCi(adjListGraph, ballRadius, currentNode);

		allPQ.insert(make_pair(ci, currentNode));
		revereseLoopUpAllPQ[currentNode] = ci;
	}

	vector<int> finalOutput;
	int loopCount = 0;
	while (true)
	{
		cout << "modelID: " << modelID << " loopCount: " << loopCount << " totalSize: " << totalSize << " maxCi: " << allPQ.rbegin()->first << " node: " << allPQ.rbegin()->second << endl;
		loopCount += updateBatch;

		vector<int> batchList;
		unsigned int batchLimiti = 0;

		pair<long long, int> debugPreviousMax = *(allPQ.rbegin());

		for (auto rit = allPQ.rbegin(); batchLimiti < updateBatch && (rit != allPQ.rend()); rit++, batchLimiti++)
		{
			batchList.push_back(rit->second);
			finalOutput.push_back(rit->second);
			allVex.erase(rit->second);  //remove key

			if (rit->first <= 0)
			{
				// ci algorithm ends
				goto CIEND;
			}
		}

		/*
		if (loopCount == 600000)
		{
			cout << " revereseLoopUpAllPQ[1715132] " << revereseLoopUpAllPQ[1715132] << endl;
		}
		*/

		//cout << "monitor 1" << endl;

		//int debugCount = 0;

		unordered_set<int> candidateUpdateNodes;
		for (int i : batchList)
		{
			unordered_set<int> allScopeInBallRadiusPlusOne;
			unordered_set<int> dummyValue;
			getNeighbourFrontierAndScope(adjListGraph, ballRadius + 1, i, dummyValue, allScopeInBallRadiusPlusOne);
			candidateUpdateNodes.insert(allScopeInBallRadiusPlusOne.begin(), allScopeInBallRadiusPlusOne.end());

			//cout << "monitor 1_2: " << debugCount++ << " " << batchList.size() << " " << candidateUpdateNodes.size() << endl;

		}

		//cout << "monitor 2" << endl;

		for (int i : batchList)
		{
			deleteNode(adjListGraph, i);
			//candidateUpdateNodesWithCi.insert(make_pair(i, -1));// no need to because self will be included in the candidateUpdateNodes and updated in the below
		}

		//cout << "monitor 3" << endl;
		//debugCount = 0;

		for (int i : candidateUpdateNodes)
		{
			long long updatedCi = basicCi(adjListGraph, ballRadius, i);

			long long olderCi = revereseLoopUpAllPQ[i];

			allPQ.erase(make_pair(olderCi, i));
			allPQ.insert(make_pair(updatedCi, i));

			revereseLoopUpAllPQ[i] = updatedCi;

			//cout << "monitor 3_4: " << debugCount++ << " " << candidateUpdateNodes.size() << endl;
		}
		//cout << "monitor 4" << endl;

		/*if ((debugPreviousMax.first) < (allPQ.rbegin()->first))
		{
			cout << "monitor 5: " << debugPreviousMax.first << " " << allPQ.rbegin()->first << endl;;
		}
		*/

	}

CIEND:

	//add left random

	cout << "Before Random adding the left CI equals zero: " << finalOutput.size() << endl;
	for (auto leftVex : allVex)
	{
		finalOutput.push_back(leftVex);
	}
	cout << "After Random adding the left CI equals zero: " << finalOutput.size() << endl;

	while (true)
	{
		if (finalOutput.size() % outputNumBatch == 0)
		{
			break;
		}
		else
		{
			finalOutput.push_back(-1);
		}
	}

	//--------------

	std::cout << "Outputing Start.." << endl;

	ofstream os(output);

	string output500 = "";
	for (unsigned int i = 0; i < finalOutput.size(); i++)
	{
		if (i % outputNumBatch == 0)
		{
			output500 = modelID;
		}

		if (finalOutput[i] != -1)
		{
			output500 += (',' + std::to_string(finalOutput[i]));
		}
		else
		{
			output500 += ',';
		}

		if (i % outputNumBatch == (outputNumBatch - 1) || i == (finalOutput.size() - 1))
		{
			os << output500 << endl;
			//std::cout << "output500: " << output500 << endl;
			output500.clear();
		}

	}

	os.close();

	std::cout << "Outputing End.." << endl;

	system("pause");
	return 0;
}

<commit_msg>Add useless Vector bool code<commit_after>// ComplexCi.cpp : ̨Ӧóڵ㡣
//

//#include "stdafx.h"

#include <iostream>
#include <vector>
#include <set>
#include <fstream>
#include <string>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <sstream>
#include <iterator>
#include <queue>
#include <algorithm>

using namespace std;

template<typename Out>
void split(const std::string &s, char delim, Out result) {
	std::stringstream ss;
	ss.str(s);
	std::string item;
	while (std::getline(ss, item, delim)) {
		*(result++) = item;
	}
}

std::vector<std::string> split(const std::string &s, char delim) {
	std::vector<std::string> elems;
	split(s, delim, std::back_inserter(elems));
	return elems;
}

void getNeighbourFrontierAndScope(const vector<vector<int> > &adjListGraph, int scope, int currentNode, unordered_set<int> &currentSet, unordered_set<int>& alreadyAccess)
{
	//alreadyAccess.reserve(100000);

	currentSet.insert(currentNode);
	alreadyAccess.insert(currentNode);

	for (int i = 0; i < scope; i++)
	{
		unordered_set<int> nextSet;
		//nextSet.reserve(30000);

		for (const auto& node : currentSet)
		{
			const vector<int>& neighbourNodeList = adjListGraph[node];

			for (const auto& eachNeighbour : neighbourNodeList)
			{
				if (alreadyAccess.find(eachNeighbour) == alreadyAccess.end())
				{
					nextSet.insert(eachNeighbour);
					alreadyAccess.insert(eachNeighbour);
				}
			}

		}

		currentSet = move(nextSet);
	}
}

/*
void getNeighbourFrontierAndScope(const vector<vector<int> > &adjListGraph, int scope, int currentNode, unordered_set<int> &currentUnorderedSet, unordered_set<int>& alreadyUnorderedAccess)
{
	vector<bool> currentSetVector(adjListGraph.size());
	vector<bool> alreadyAccessVector(adjListGraph.size());

	currentSetVector[currentNode] = true;
	alreadyAccessVector[currentNode] = true;

	for (int i = 0; i < scope; i++)
	{
		vector<bool> nextSetVector(adjListGraph.size());

		for (int j = 0; j < currentSetVector.size(); j++)
		{
			if (currentSetVector[j])
			{
				const vector<int>& neighbourNodeList = adjListGraph[j];

				for (const auto& eachNeighbour : neighbourNodeList)
				{

					if (!alreadyAccessVector[eachNeighbour])
					{
						nextSetVector[eachNeighbour] = true;
						alreadyAccessVector[eachNeighbour] = true;
					}
				}
			}
		}

		currentSetVector = move(nextSetVector);
	}

	for (int i = 0; i < adjListGraph.size(); i++)
	{
		if (currentSetVector[i])
		{
			currentUnorderedSet.insert(i);
		}
		if (alreadyAccessVector[i])
		{
			alreadyUnorderedAccess.insert(i);
		}

	}
}*/

long long basicCi(const vector<vector<int> > &adjListGraph, int ballRadius, int currentNode)
{
	if (adjListGraph[currentNode].size() == 0)
	{
		return -1;
	}

	unordered_set<int> currentFrontier;
	unordered_set<int> dummyValue;

	getNeighbourFrontierAndScope(adjListGraph, ballRadius, currentNode, currentFrontier, dummyValue);

	long long ci = 0;

	for (auto node : currentFrontier)
	{
		ci += (adjListGraph[node].size() - 1);
	}

	ci *= (adjListGraph[currentNode].size() - 1);

	/*
	if (currentNode % 500 == 0)
	{
		cout << currentNode << " currentFrontier size :" << currentFrontier.size() << endl;
	}
	*/

	/*
	if (currentNode == 1715132 && (ci == 0 || ci == 2))
	{
		cout << "currentNode: " << currentNode << " adjListGraph[currentNode].size(): " << adjListGraph[currentNode].size() << "/ ";

		for (auto node : adjListGraph[currentNode])
		{
			cout << node << " " ;
		}

		cout << endl;

		cout << "ci: " << ci << endl;

		cout << "currentFrontier: " << endl;

		for (auto node : currentFrontier)
		{
			cout << node << " " << adjListGraph[node].size() << endl;
		}

		cout << "dummyValue: " << endl;

		for (auto node : dummyValue)
		{
			cout << node << " node1: ";

			for (auto node1 : adjListGraph[node])
			{
				cout <<  node1 << " ";
			}
			cout << endl;
		}
		cout << endl;

	}
	*/

	return ci;
}

void deleteNode(vector<vector<int> > &adjListGraph, int node)
{
	/*
	if (adjListGraph[node].size() == 0)
	{
	return;
	} // not must here
	*/

	for (auto neighbour : adjListGraph[node])
	{
		adjListGraph[neighbour].erase(remove(adjListGraph[neighbour].begin(), adjListGraph[neighbour].end(), node), adjListGraph[neighbour].end());
	}

	adjListGraph[node].clear();

}

int main(int argc, char* argv[])
{
	unsigned int ballRadius = 1;
	unsigned int updateBatch = 1;
	unsigned int outputNumBatch = 1;

	string path = "";
	string output = "";

	if (argc > 4)
	{
		path = argv[1];
		output = path + "_out";

		ballRadius = stoi(argv[2]);
		updateBatch = stoi(argv[3]);
		outputNumBatch = stoi(argv[4]);

	}
	else
	{
		cout << "at least 3 parameters for csv path" << endl;
		cout << "e.g. 'C:/Users/zhfkt/Documents/Visual Studio 2013/Projects/ComplexCi/Release/karate.txt' 2 500 500" << endl;
		return 0;
	}

	string modelID = "";

	{
		vector<string> fileName = split(path, '/');
		modelID = split(fileName[fileName.size() - 1], '.')[0];
	}

	std::cout << "path: " << path << endl;
	std::cout << "output: " << output << endl;
	std::cout << "modelID: " << modelID << endl;

	std::cout << "ballRadius: " << ballRadius << endl;
	std::cout << "updateBatch: " << updateBatch << endl;
	std::cout << "outputNumBatch: " << outputNumBatch << endl;

	std::cout << "First Read Start" << endl;

	unordered_set<int> allVex;
	string eachLine;
	ifstream is;
	is.open(path);

	while (is >> eachLine)
	{
		vector<string> csvEachLine = split(eachLine, ',');

		allVex.insert(stoi(csvEachLine[0]));
		allVex.insert(stoi(csvEachLine[1]));

	}
	is.close();
	int totalSize = allVex.size();

	std::cout << "First Read End/Second Read Start" << endl;

	vector<vector<int> > adjListGraph(totalSize);
	is.open(path);
	while (is >> eachLine)
	{
		vector<string> csvEachLine = split(eachLine, ',');

		adjListGraph[stoi(csvEachLine[0])].push_back(stoi(csvEachLine[1]));
		adjListGraph[stoi(csvEachLine[1])].push_back(stoi(csvEachLine[0]));
	}

	std::cout << "Second Read End" << endl;

	//--------------

	set<pair<long long, int> > allPQ; //ci/currentNode --- long is 32 bit on the win and long long is 64 bit / and long long can be multiple
	vector<long long> revereseLoopUpAllPQ(totalSize);
	cout << "modelID: " << modelID << " First Cal CI" << endl;

	for (int i = 0; i < adjListGraph.size(); i++)
	{
		int currentNode = i;
		// core_ci
		long long ci = basicCi(adjListGraph, ballRadius, currentNode);

		allPQ.insert(make_pair(ci, currentNode));
		revereseLoopUpAllPQ[currentNode] = ci;
	}

	vector<int> finalOutput;
	int loopCount = 0;
	while (true)
	{
		cout << "modelID: " << modelID << " loopCount: " << loopCount << " totalSize: " << totalSize << " maxCi: " << allPQ.rbegin()->first << " node: " << allPQ.rbegin()->second << endl;
		loopCount += updateBatch;

		vector<int> batchList;
		unsigned int batchLimiti = 0;

		pair<long long, int> debugPreviousMax = *(allPQ.rbegin());

		for (auto rit = allPQ.rbegin(); batchLimiti < updateBatch && (rit != allPQ.rend()); rit++, batchLimiti++)
		{
			batchList.push_back(rit->second);
			finalOutput.push_back(rit->second);
			allVex.erase(rit->second);  //remove key

			if (rit->first <= 0)
			{
				// ci algorithm ends
				goto CIEND;
			}
		}

		/*
		if (loopCount == 600000)
		{
			cout << " revereseLoopUpAllPQ[1715132] " << revereseLoopUpAllPQ[1715132] << endl;
		}
		*/

		//cout << "monitor 1" << endl;

		//int debugCount = 0;

		unordered_set<int> candidateUpdateNodes;
		for (int i : batchList)
		{
			unordered_set<int> allScopeInBallRadiusPlusOne;
			unordered_set<int> dummyValue;
			getNeighbourFrontierAndScope(adjListGraph, ballRadius + 1, i, dummyValue, allScopeInBallRadiusPlusOne);
			candidateUpdateNodes.insert(allScopeInBallRadiusPlusOne.begin(), allScopeInBallRadiusPlusOne.end());

			//cout << "monitor 1_2: " << debugCount++ << " " << batchList.size() << " " << candidateUpdateNodes.size() << endl;

		}

		//cout << "monitor 2" << endl;

		for (int i : batchList)
		{
			deleteNode(adjListGraph, i);
			//candidateUpdateNodesWithCi.insert(make_pair(i, -1));// no need to because self will be included in the candidateUpdateNodes and updated in the below
		}

		//cout << "monitor 3" << endl;
		//debugCount = 0;

		for (int i : candidateUpdateNodes)
		{
			long long updatedCi = basicCi(adjListGraph, ballRadius, i);

			long long olderCi = revereseLoopUpAllPQ[i];

			allPQ.erase(make_pair(olderCi, i));
			allPQ.insert(make_pair(updatedCi, i));

			revereseLoopUpAllPQ[i] = updatedCi;

			//cout << "monitor 3_4: " << debugCount++ << " " << candidateUpdateNodes.size() << endl;
		}
		//cout << "monitor 4" << endl;

		/*if ((debugPreviousMax.first) < (allPQ.rbegin()->first))
		{
			cout << "monitor 5: " << debugPreviousMax.first << " " << allPQ.rbegin()->first << endl;;
		}
		*/

	}

CIEND:

	//add left random

	cout << "Before Random adding the left CI equals zero: " << finalOutput.size() << endl;
	for (auto leftVex : allVex)
	{
		finalOutput.push_back(leftVex);
	}
	cout << "After Random adding the left CI equals zero: " << finalOutput.size() << endl;

	while (true)
	{
		if (finalOutput.size() % outputNumBatch == 0)
		{
			break;
		}
		else
		{
			finalOutput.push_back(-1);
		}
	}

	//--------------

	std::cout << "Outputing Start.." << endl;

	ofstream os(output);

	string output500 = "";
	for (unsigned int i = 0; i < finalOutput.size(); i++)
	{
		if (i % outputNumBatch == 0)
		{
			output500 = modelID;
		}

		if (finalOutput[i] != -1)
		{
			output500 += (',' + std::to_string(finalOutput[i]));
		}
		else
		{
			output500 += ',';
		}

		if (i % outputNumBatch == (outputNumBatch - 1) || i == (finalOutput.size() - 1))
		{
			os << output500 << endl;
			//std::cout << "output500: " << output500 << endl;
			output500.clear();
		}

	}

	os.close();

	std::cout << "Outputing End.." << endl;

	system("pause");
	return 0;
}

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <language/scriptengine.h>
#include <logging/translator.h>
#include <tools/fileinfo.h>
#include <tools/stringconstants.h>

#include <QtCore/qdir.h>
#include <QtCore/qfileinfo.h>

#include <QtScript/qscriptable.h>
#include <QtScript/qscriptengine.h>

#include <regex>

namespace qbs {
namespace Internal {

class FileInfoExtension : public QObject, QScriptable
{
    Q_OBJECT
public:
    static QScriptValue js_ctor(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_path(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_fileName(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_baseName(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_suffix(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_completeSuffix(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_canonicalPath(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_cleanPath(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_completeBaseName(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_relativePath(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_resolvePath(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_isAbsolutePath(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_toWindowsSeparators(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_fromWindowsSeparators(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_toNativeSeparators(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_fromNativeSeparators(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_joinPaths(QScriptContext *context, QScriptEngine *engine);
};

QScriptValue FileInfoExtension::js_ctor(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    return context->throwError(Tr::tr("'FileInfo' cannot be instantiated."));
}

QScriptValue FileInfoExtension::js_path(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("path expects 1 argument"));
    }
    HostOsInfo::HostOs hostOs = HostOsInfo::hostOs();
    if (context->argumentCount() > 1) {
        hostOs = context->argument(1).toVariant().toStringList().contains(QLatin1String("windows"))
                ? HostOsInfo::HostOsWindows : HostOsInfo::HostOsOtherUnix;
    }
    return FileInfo::path(context->argument(0).toString(), hostOs);
}

QScriptValue FileInfoExtension::js_fileName(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("fileName expects 1 argument"));
    }
    return FileInfo::fileName(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_baseName(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("baseName expects 1 argument"));
    }
    return FileInfo::baseName(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_suffix(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("suffix expects 1 argument"));
    }
    return FileInfo::suffix(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_completeSuffix(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("completeSuffix expects 1 argument"));
    }
    return FileInfo::completeSuffix(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_canonicalPath(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("canonicalPath expects 1 argument"));
    }
    return QFileInfo(context->argument(0).toString()).canonicalFilePath();
}

QScriptValue FileInfoExtension::js_cleanPath(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("cleanPath expects 1 argument"));
    }
    return QDir::cleanPath(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_completeBaseName(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("completeBaseName expects 1 argument"));
    }
    return FileInfo::completeBaseName(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_relativePath(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("relativePath expects 2 arguments"));
    }
    const QString baseDir = context->argument(0).toString();
    const QString filePath = context->argument(1).toString();
    if (!FileInfo::isAbsolute(baseDir)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("FileInfo.relativePath() expects an absolute path as "
                                          "its first argument, but it is '%1'.").arg(baseDir));
    }
    if (!FileInfo::isAbsolute(filePath)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("FileInfo.relativePath() expects an absolute path as "
                                          "its second argument, but it is '%1'.").arg(filePath));
    }
    return QDir(baseDir).relativeFilePath(filePath);
}

QScriptValue FileInfoExtension::js_resolvePath(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("resolvePath expects 2 arguments"));
    }
    const QString base = context->argument(0).toString();
    const QString rel = context->argument(1).toString();
    return FileInfo::resolvePath(base, rel);
}

QScriptValue FileInfoExtension::js_isAbsolutePath(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("isAbsolutePath expects 1 argument"));
    }
    HostOsInfo::HostOs hostOs = HostOsInfo::hostOs();
    if (context->argumentCount() > 1) {
        hostOs = context->argument(1).toVariant().toStringList().contains(QLatin1String("windows"))
                ? HostOsInfo::HostOsWindows : HostOsInfo::HostOsOtherUnix;
    }
    return FileInfo::isAbsolute(context->argument(0).toString(), hostOs);
}

QScriptValue FileInfoExtension::js_toWindowsSeparators(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("toWindowsSeparators expects 1 argument"));
    }
    return context->argument(0).toString().replace(QLatin1Char('/'), QLatin1Char('\\'));
}

QScriptValue FileInfoExtension::js_fromWindowsSeparators(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("fromWindowsSeparators expects 1 argument"));
    }
    return context->argument(0).toString().replace(QLatin1Char('\\'), QLatin1Char('/'));
}

QScriptValue FileInfoExtension::js_toNativeSeparators(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("toNativeSeparators expects 1 argument"));
    }
    return QDir::toNativeSeparators(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_fromNativeSeparators(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("fromNativeSeparators expects 1 argument"));
    }
    return QDir::fromNativeSeparators(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_joinPaths(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    QStringList paths;
    for (int i = 0; i < context->argumentCount(); ++i) {
        const QScriptValue value = context->argument(i);
        if (!value.isUndefined() && !value.isNull()) {
            const QString arg = value.toString();
            if (!arg.isEmpty())
                paths.push_back(arg);
        }
    }
    return engine->toScriptValue(QString::fromStdString(
                                     std::regex_replace(paths.join(QLatin1Char('/')).toStdString(),
                                                        std::regex("/{2,}"), std::string("/"))));
}

} // namespace Internal
} // namespace qbs

void initializeJsExtensionFileInfo(QScriptValue extensionObject)
{
    using namespace qbs::Internal;
    QScriptEngine *engine = extensionObject.engine();
    QScriptValue fileInfoObj = engine->newQMetaObject(&FileInfoExtension::staticMetaObject,
                                                  engine->newFunction(&FileInfoExtension::js_ctor));
    fileInfoObj.setProperty(StringConstants::fileInfoPath(),
                            engine->newFunction(FileInfoExtension::js_path));
    fileInfoObj.setProperty(StringConstants::fileInfoFileName(),
                            engine->newFunction(FileInfoExtension::js_fileName));
    fileInfoObj.setProperty(StringConstants::baseNameProperty(),
                            engine->newFunction(FileInfoExtension::js_baseName));
    fileInfoObj.setProperty(QStringLiteral("suffix"),
                            engine->newFunction(FileInfoExtension::js_suffix));
    fileInfoObj.setProperty(QStringLiteral("completeSuffix"),
                            engine->newFunction(FileInfoExtension::js_completeSuffix));
    fileInfoObj.setProperty(QStringLiteral("canonicalPath"),
                            engine->newFunction(FileInfoExtension::js_canonicalPath));
    fileInfoObj.setProperty(QStringLiteral("cleanPath"),
                            engine->newFunction(FileInfoExtension::js_cleanPath));
    fileInfoObj.setProperty(StringConstants::completeBaseNameProperty(),
                            engine->newFunction(FileInfoExtension::js_completeBaseName));
    fileInfoObj.setProperty(QStringLiteral("relativePath"),
                            engine->newFunction(FileInfoExtension::js_relativePath));
    fileInfoObj.setProperty(QStringLiteral("resolvePath"),
                            engine->newFunction(FileInfoExtension::js_resolvePath));
    fileInfoObj.setProperty(QStringLiteral("isAbsolutePath"),
                            engine->newFunction(FileInfoExtension::js_isAbsolutePath));
    fileInfoObj.setProperty(QStringLiteral("toWindowsSeparators"),
                            engine->newFunction(FileInfoExtension::js_toWindowsSeparators));
    fileInfoObj.setProperty(QStringLiteral("fromWindowsSeparators"),
                            engine->newFunction(FileInfoExtension::js_fromWindowsSeparators));
    fileInfoObj.setProperty(QStringLiteral("toNativeSeparators"),
                            engine->newFunction(FileInfoExtension::js_toNativeSeparators));
    fileInfoObj.setProperty(QStringLiteral("fromNativeSeparators"),
                            engine->newFunction(FileInfoExtension::js_fromNativeSeparators));
    fileInfoObj.setProperty(QStringLiteral("joinPaths"),
                            engine->newFunction(FileInfoExtension::js_joinPaths));
    extensionObject.setProperty(QStringLiteral("FileInfo"), fileInfoObj);
}

Q_DECLARE_METATYPE(qbs::Internal::FileInfoExtension *)

#include "fileinfoextension.moc"
<commit_msg>Speedup FileInfoExtension::js_joinPaths<commit_after>/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qbs.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <language/scriptengine.h>
#include <logging/translator.h>
#include <tools/fileinfo.h>
#include <tools/stringconstants.h>

#include <QtCore/qdir.h>
#include <QtCore/qfileinfo.h>

#include <QtScript/qscriptable.h>
#include <QtScript/qscriptengine.h>

#include <regex>

namespace qbs {
namespace Internal {

// removes duplicate separators from the path
static QString uniqueSeparators(QString path)
{
    const auto it = std::unique(path.begin(), path.end(), [](QChar c1, QChar c2) {
        return c1 == c2 && c1 == QLatin1Char('/');
    });
    path.resize(it - path.begin());
    return path;
}

class FileInfoExtension : public QObject, QScriptable
{
    Q_OBJECT
public:
    static QScriptValue js_ctor(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_path(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_fileName(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_baseName(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_suffix(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_completeSuffix(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_canonicalPath(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_cleanPath(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_completeBaseName(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_relativePath(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_resolvePath(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_isAbsolutePath(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_toWindowsSeparators(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_fromWindowsSeparators(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_toNativeSeparators(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_fromNativeSeparators(QScriptContext *context, QScriptEngine *engine);
    static QScriptValue js_joinPaths(QScriptContext *context, QScriptEngine *engine);
};

QScriptValue FileInfoExtension::js_ctor(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    return context->throwError(Tr::tr("'FileInfo' cannot be instantiated."));
}

QScriptValue FileInfoExtension::js_path(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("path expects 1 argument"));
    }
    HostOsInfo::HostOs hostOs = HostOsInfo::hostOs();
    if (context->argumentCount() > 1) {
        hostOs = context->argument(1).toVariant().toStringList().contains(QLatin1String("windows"))
                ? HostOsInfo::HostOsWindows : HostOsInfo::HostOsOtherUnix;
    }
    return FileInfo::path(context->argument(0).toString(), hostOs);
}

QScriptValue FileInfoExtension::js_fileName(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("fileName expects 1 argument"));
    }
    return FileInfo::fileName(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_baseName(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("baseName expects 1 argument"));
    }
    return FileInfo::baseName(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_suffix(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("suffix expects 1 argument"));
    }
    return FileInfo::suffix(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_completeSuffix(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("completeSuffix expects 1 argument"));
    }
    return FileInfo::completeSuffix(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_canonicalPath(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("canonicalPath expects 1 argument"));
    }
    return QFileInfo(context->argument(0).toString()).canonicalFilePath();
}

QScriptValue FileInfoExtension::js_cleanPath(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("cleanPath expects 1 argument"));
    }
    return QDir::cleanPath(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_completeBaseName(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("completeBaseName expects 1 argument"));
    }
    return FileInfo::completeBaseName(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_relativePath(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("relativePath expects 2 arguments"));
    }
    const QString baseDir = context->argument(0).toString();
    const QString filePath = context->argument(1).toString();
    if (!FileInfo::isAbsolute(baseDir)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("FileInfo.relativePath() expects an absolute path as "
                                          "its first argument, but it is '%1'.").arg(baseDir));
    }
    if (!FileInfo::isAbsolute(filePath)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("FileInfo.relativePath() expects an absolute path as "
                                          "its second argument, but it is '%1'.").arg(filePath));
    }
    return QDir(baseDir).relativeFilePath(filePath);
}

QScriptValue FileInfoExtension::js_resolvePath(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("resolvePath expects 2 arguments"));
    }
    const QString base = context->argument(0).toString();
    const QString rel = context->argument(1).toString();
    return FileInfo::resolvePath(base, rel);
}

QScriptValue FileInfoExtension::js_isAbsolutePath(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("isAbsolutePath expects 1 argument"));
    }
    HostOsInfo::HostOs hostOs = HostOsInfo::hostOs();
    if (context->argumentCount() > 1) {
        hostOs = context->argument(1).toVariant().toStringList().contains(QLatin1String("windows"))
                ? HostOsInfo::HostOsWindows : HostOsInfo::HostOsOtherUnix;
    }
    return FileInfo::isAbsolute(context->argument(0).toString(), hostOs);
}

QScriptValue FileInfoExtension::js_toWindowsSeparators(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("toWindowsSeparators expects 1 argument"));
    }
    return context->argument(0).toString().replace(QLatin1Char('/'), QLatin1Char('\\'));
}

QScriptValue FileInfoExtension::js_fromWindowsSeparators(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("fromWindowsSeparators expects 1 argument"));
    }
    return context->argument(0).toString().replace(QLatin1Char('\\'), QLatin1Char('/'));
}

QScriptValue FileInfoExtension::js_toNativeSeparators(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("toNativeSeparators expects 1 argument"));
    }
    return QDir::toNativeSeparators(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_fromNativeSeparators(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    if (Q_UNLIKELY(context->argumentCount() < 1)) {
        return context->throwError(QScriptContext::SyntaxError,
                                   Tr::tr("fromNativeSeparators expects 1 argument"));
    }
    return QDir::fromNativeSeparators(context->argument(0).toString());
}

QScriptValue FileInfoExtension::js_joinPaths(QScriptContext *context, QScriptEngine *engine)
{
    Q_UNUSED(engine);
    QStringList paths;
    for (int i = 0; i < context->argumentCount(); ++i) {
        const QScriptValue value = context->argument(i);
        if (!value.isUndefined() && !value.isNull()) {
            const QString arg = value.toString();
            if (!arg.isEmpty())
                paths.push_back(arg);
        }
    }
    return engine->toScriptValue(uniqueSeparators(paths.join(QLatin1Char('/'))));
}

} // namespace Internal
} // namespace qbs

void initializeJsExtensionFileInfo(QScriptValue extensionObject)
{
    using namespace qbs::Internal;
    QScriptEngine *engine = extensionObject.engine();
    QScriptValue fileInfoObj = engine->newQMetaObject(&FileInfoExtension::staticMetaObject,
                                                  engine->newFunction(&FileInfoExtension::js_ctor));
    fileInfoObj.setProperty(StringConstants::fileInfoPath(),
                            engine->newFunction(FileInfoExtension::js_path));
    fileInfoObj.setProperty(StringConstants::fileInfoFileName(),
                            engine->newFunction(FileInfoExtension::js_fileName));
    fileInfoObj.setProperty(StringConstants::baseNameProperty(),
                            engine->newFunction(FileInfoExtension::js_baseName));
    fileInfoObj.setProperty(QStringLiteral("suffix"),
                            engine->newFunction(FileInfoExtension::js_suffix));
    fileInfoObj.setProperty(QStringLiteral("completeSuffix"),
                            engine->newFunction(FileInfoExtension::js_completeSuffix));
    fileInfoObj.setProperty(QStringLiteral("canonicalPath"),
                            engine->newFunction(FileInfoExtension::js_canonicalPath));
    fileInfoObj.setProperty(QStringLiteral("cleanPath"),
                            engine->newFunction(FileInfoExtension::js_cleanPath));
    fileInfoObj.setProperty(StringConstants::completeBaseNameProperty(),
                            engine->newFunction(FileInfoExtension::js_completeBaseName));
    fileInfoObj.setProperty(QStringLiteral("relativePath"),
                            engine->newFunction(FileInfoExtension::js_relativePath));
    fileInfoObj.setProperty(QStringLiteral("resolvePath"),
                            engine->newFunction(FileInfoExtension::js_resolvePath));
    fileInfoObj.setProperty(QStringLiteral("isAbsolutePath"),
                            engine->newFunction(FileInfoExtension::js_isAbsolutePath));
    fileInfoObj.setProperty(QStringLiteral("toWindowsSeparators"),
                            engine->newFunction(FileInfoExtension::js_toWindowsSeparators));
    fileInfoObj.setProperty(QStringLiteral("fromWindowsSeparators"),
                            engine->newFunction(FileInfoExtension::js_fromWindowsSeparators));
    fileInfoObj.setProperty(QStringLiteral("toNativeSeparators"),
                            engine->newFunction(FileInfoExtension::js_toNativeSeparators));
    fileInfoObj.setProperty(QStringLiteral("fromNativeSeparators"),
                            engine->newFunction(FileInfoExtension::js_fromNativeSeparators));
    fileInfoObj.setProperty(QStringLiteral("joinPaths"),
                            engine->newFunction(FileInfoExtension::js_joinPaths));
    extensionObject.setProperty(QStringLiteral("FileInfo"), fileInfoObj);
}

Q_DECLARE_METATYPE(qbs::Internal::FileInfoExtension *)

#include "fileinfoextension.moc"
<|endoftext|>


<commit_before>/**
 * Copyright 2014, Planet Labs, Inc.
 *
 * 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.
 */

#include <algorithm>
#include "compositor.h"

// used to sort for median.
class InputQualityPair {
public:
    int inputFile;
    float quality;

    bool operator< (const InputQualityPair &rhs) const {
        return this->quality > rhs.quality;
    }
};

/************************************************************************/
/*                           LineCompositor()                           */
/************************************************************************/

/**
 * \brief Line compositor.
 *
 * Composite one scanline.  The "quality_percentile" value determines what
 * input pixel to use based on a review of qualities - 100 means highest
 * quality, and 50 would be median.
 */

void LineCompositor(PLCContext *plContext, int line, PLCLine *lineObj)

{
    std::vector<PLCLine *> inputLines;
    unsigned int i, iPixel, width=lineObj->getWidth();
    std::vector<float*> inputQualities;

/* -------------------------------------------------------------------- */
/*      Read inputs.                                                    */
/* -------------------------------------------------------------------- */
    for(i = 0; i < plContext->inputFiles.size(); i++ )
        inputLines.push_back(plContext->inputFiles[i]->getLine(line));

/* -------------------------------------------------------------------- */
/*      Compute qualities.                                              */
/* -------------------------------------------------------------------- */
    for(unsigned int iQM = 0; iQM < plContext->qualityMethods.size(); iQM++ )
    {
        // TODO(check result status)
        plContext->qualityMethods[iQM]->computeStackQuality(
            plContext, inputLines);

        if( plContext->isDebugLine(line) )
        {
            for(iPixel=0; iPixel < width; iPixel++)
            {
                if( plContext->isDebugPixel(iPixel, line) )
                {
                    for( i=0; i < inputLines.size(); i++ )
                    {
                        printf( "Input %d quality is %.5f @ %dx%d for "
                                "quality phase %d.\n",
                                i+1,
                                inputLines[i]->getNewQuality()[iPixel],
                                iPixel, line, iQM );
                    }
                }
            }
        }

        // opportunity here to save intermediate "New" quality measures.
        // merge "newQuality()" back into "quality", and reset new Quality.
        for(i = 0; i < inputLines.size(); i++)
        {
            plContext->qualityMethods[iQM]->mergeQuality(
                plContext->inputFiles[i], inputLines[i]);
        }

        if( plContext->isDebugLine(line) )
        {
            for(iPixel=0; iPixel < width; iPixel++)
            {
                if( plContext->isDebugPixel(iPixel, line) )
                {
                    for( i=0; i < inputLines.size(); i++ )
                    {
                        printf( "Input %d quality is %.5f @ %dx%d after merge "
                                "for quality phase %d.\n",
                                i+1,
                                inputLines[i]->getQuality()[iPixel],
                                iPixel, line, iQM );
                    }
                }
            }
        }

    }

    for(i = 0; i < plContext->inputFiles.size(); i++ )
        inputQualities.push_back(inputLines[i]->getQuality());

/* -------------------------------------------------------------------- */
/*      Establish which is the best source for each pixel.              */
/* -------------------------------------------------------------------- */
    std::vector<InputQualityPair> candidates;
    candidates.resize(plContext->inputFiles.size());
    unsigned short *bestInput = lineObj->getSource();
    float *bestQuality = lineObj->getQuality();

    for(iPixel=0; iPixel < width; iPixel++)
    {
        int activeCandidates = 0;

        for(i = 0; i < plContext->inputFiles.size(); i++ )
        {
            if( inputQualities[i][iPixel] > 0.0 )
            {
                candidates[activeCandidates].inputFile = i;
                candidates[activeCandidates].quality =
                    inputQualities[i][iPixel];
                activeCandidates++;
            }
        }

        if( activeCandidates > 1 )
            std::sort(candidates.begin(),
                      candidates.begin() + activeCandidates);

        if( activeCandidates == 0 )
        {
            bestQuality[iPixel] = 0.0;
            bestInput[iPixel] = 0;
        }
        else
        {
            bestQuality[iPixel] = candidates[0].quality;
            bestInput[iPixel] = candidates[0].inputFile+1;
        }

        if( bestInput[iPixel] != 0 )
        {
            if( plContext->isDebugPixel(iPixel, line) )
                printf("No active candidates @ %d,%d\n",
                       iPixel, line );
        }
        else
        {
            if( plContext->isDebugPixel(iPixel, line) )
                printf("Best quality for %d,%d is %.5f from input %d.\n",
                       iPixel, line, bestQuality[iPixel], bestInput[iPixel]);
        }

/* -------------------------------------------------------------------- */
/*      Build output with best pixel source(s) for each pixel.          */
/* -------------------------------------------------------------------- */
        GByte *dst_alpha = lineObj->getAlpha();
        int averageCount = (int) floor(activeCandidates * plContext->averageBestRatio);

        if( averageCount == 0 && activeCandidates > 0 )
            averageCount = 1;

        if( averageCount == 0 )
            dst_alpha[iPixel] = 0;
        else
        {
            for(int iBand=0; iBand < lineObj->getBandCount(); iBand++)
            {
                float *dst_pixels = lineObj->getBand(iBand);

                dst_pixels[iPixel] = 0.0;

                for(int i=0; i < averageCount; i++)
                {
                    dst_pixels[iPixel] +=
                        inputLines[candidates[i].inputFile]->getBand(iBand)[iPixel];
                }
                if( averageCount > 0 )
                    dst_pixels[iPixel] /= averageCount;
            }
            dst_alpha[iPixel] = 255;
        }
    }

    plContext->qualityHistogram.accumulate(bestQuality, width);

/* -------------------------------------------------------------------- */
/*      Consider writing input qualities.                               */
/* -------------------------------------------------------------------- */
    if( plContext->qualityDS != NULL )
    {
        for(i = 0; i < plContext->inputFiles.size(); i++ )
            plContext->qualityDS->GetRasterBand(i+2)->
                RasterIO(GF_Write, 0, line, width, 1,
                         inputLines[i]->getQuality(), width, 1, GDT_Float32,
                         0, 0);
    }

/* -------------------------------------------------------------------- */
/*      Cleanup input buffers.                                          */
/* -------------------------------------------------------------------- */
    for(i = 0; i < plContext->inputFiles.size(); i++ )
        delete inputLines[i];
}
<commit_msg>add error checking when writing quality<commit_after>/**
 * Copyright 2014, Planet Labs, Inc.
 *
 * 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.
 */

#include <algorithm>
#include "compositor.h"

// used to sort for median.
class InputQualityPair {
public:
    int inputFile;
    float quality;

    bool operator< (const InputQualityPair &rhs) const {
        return this->quality > rhs.quality;
    }
};

/************************************************************************/
/*                           LineCompositor()                           */
/************************************************************************/

/**
 * \brief Line compositor.
 *
 * Composite one scanline.  The "quality_percentile" value determines what
 * input pixel to use based on a review of qualities - 100 means highest
 * quality, and 50 would be median.
 */

void LineCompositor(PLCContext *plContext, int line, PLCLine *lineObj)

{
    std::vector<PLCLine *> inputLines;
    unsigned int i, iPixel, width=lineObj->getWidth();
    std::vector<float*> inputQualities;

/* -------------------------------------------------------------------- */
/*      Read inputs.                                                    */
/* -------------------------------------------------------------------- */
    for(i = 0; i < plContext->inputFiles.size(); i++ )
        inputLines.push_back(plContext->inputFiles[i]->getLine(line));

/* -------------------------------------------------------------------- */
/*      Compute qualities.                                              */
/* -------------------------------------------------------------------- */
    for(unsigned int iQM = 0; iQM < plContext->qualityMethods.size(); iQM++ )
    {
        // TODO(check result status)
        plContext->qualityMethods[iQM]->computeStackQuality(
            plContext, inputLines);

        if( plContext->isDebugLine(line) )
        {
            for(iPixel=0; iPixel < width; iPixel++)
            {
                if( plContext->isDebugPixel(iPixel, line) )
                {
                    for( i=0; i < inputLines.size(); i++ )
                    {
                        printf( "Input %d quality is %.5f @ %dx%d for "
                                "quality phase %d.\n",
                                i+1,
                                inputLines[i]->getNewQuality()[iPixel],
                                iPixel, line, iQM );
                    }
                }
            }
        }

        // opportunity here to save intermediate "New" quality measures.
        // merge "newQuality()" back into "quality", and reset new Quality.
        for(i = 0; i < inputLines.size(); i++)
        {
            plContext->qualityMethods[iQM]->mergeQuality(
                plContext->inputFiles[i], inputLines[i]);
        }

        if( plContext->isDebugLine(line) )
        {
            for(iPixel=0; iPixel < width; iPixel++)
            {
                if( plContext->isDebugPixel(iPixel, line) )
                {
                    for( i=0; i < inputLines.size(); i++ )
                    {
                        printf( "Input %d quality is %.5f @ %dx%d after merge "
                                "for quality phase %d.\n",
                                i+1,
                                inputLines[i]->getQuality()[iPixel],
                                iPixel, line, iQM );
                    }
                }
            }
        }

    }

    for(i = 0; i < plContext->inputFiles.size(); i++ )
        inputQualities.push_back(inputLines[i]->getQuality());

/* -------------------------------------------------------------------- */
/*      Establish which is the best source for each pixel.              */
/* -------------------------------------------------------------------- */
    std::vector<InputQualityPair> candidates;
    candidates.resize(plContext->inputFiles.size());
    unsigned short *bestInput = lineObj->getSource();
    float *bestQuality = lineObj->getQuality();

    for(iPixel=0; iPixel < width; iPixel++)
    {
        int activeCandidates = 0;

        for(i = 0; i < plContext->inputFiles.size(); i++ )
        {
            if( inputQualities[i][iPixel] > 0.0 )
            {
                candidates[activeCandidates].inputFile = i;
                candidates[activeCandidates].quality =
                    inputQualities[i][iPixel];
                activeCandidates++;
            }
        }

        if( activeCandidates > 1 )
            std::sort(candidates.begin(),
                      candidates.begin() + activeCandidates);

        if( activeCandidates == 0 )
        {
            bestQuality[iPixel] = 0.0;
            bestInput[iPixel] = 0;
        }
        else
        {
            bestQuality[iPixel] = candidates[0].quality;
            bestInput[iPixel] = candidates[0].inputFile+1;
        }

        if( bestInput[iPixel] != 0 )
        {
            if( plContext->isDebugPixel(iPixel, line) )
                printf("No active candidates @ %d,%d\n",
                       iPixel, line );
        }
        else
        {
            if( plContext->isDebugPixel(iPixel, line) )
                printf("Best quality for %d,%d is %.5f from input %d.\n",
                       iPixel, line, bestQuality[iPixel], bestInput[iPixel]);
        }

/* -------------------------------------------------------------------- */
/*      Build output with best pixel source(s) for each pixel.          */
/* -------------------------------------------------------------------- */
        GByte *dst_alpha = lineObj->getAlpha();
        int averageCount = (int) floor(activeCandidates * plContext->averageBestRatio);

        if( averageCount == 0 && activeCandidates > 0 )
            averageCount = 1;

        if( averageCount == 0 )
            dst_alpha[iPixel] = 0;
        else
        {
            for(int iBand=0; iBand < lineObj->getBandCount(); iBand++)
            {
                float *dst_pixels = lineObj->getBand(iBand);

                dst_pixels[iPixel] = 0.0;

                for(int i=0; i < averageCount; i++)
                {
                    dst_pixels[iPixel] +=
                        inputLines[candidates[i].inputFile]->getBand(iBand)[iPixel];
                }
                if( averageCount > 0 )
                    dst_pixels[iPixel] /= averageCount;
            }
            dst_alpha[iPixel] = 255;
        }
    }

    plContext->qualityHistogram.accumulate(bestQuality, width);

/* -------------------------------------------------------------------- */
/*      Consider writing input qualities.                               */
/* -------------------------------------------------------------------- */
    if( plContext->qualityDS != NULL )
    {
        for(i = 0; i < plContext->inputFiles.size(); i++ )
        {
            CPLErr eErr = plContext->qualityDS->GetRasterBand(i+2)->
                RasterIO(GF_Write, 0, line, width, 1,
                         inputLines[i]->getQuality(), width, 1, GDT_Float32,
                         0, 0);
            if( eErr != CE_None )
                exit(1);
        }
    }

/* -------------------------------------------------------------------- */
/*      Cleanup input buffers.                                          */
/* -------------------------------------------------------------------- */
    for(i = 0; i < plContext->inputFiles.size(); i++ )
        delete inputLines[i];
}
<|endoftext|>