<commit_before>/*
 * This file is part of the statismo library.
 *
 * Author: Marcel Luethi (marcel.luethi@unibas.ch)
 *
 * Copyright (c) 2011 University of Basel
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 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.
 *
 * Neither the name of the project's 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 COPYRIGHT HOLDERS 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 COPYRIGHT
 * HOLDER 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 <sys/types.h>
#include <errno.h>
#include <iostream>

#include <itkDirectory.h>
#include <itkImageFileReader.h>

#include "itkDataManager.h"
#include "itkPCAModelBuilder.h"
#include "itkStandardImageRepresenter.h"
#include "itkStatisticalModel.h"

/*
 * This example shows the ITK Wrapping of statismo can be used to build a deformation model.
 */

typedef itk::Image<float, 3> ImageType3D;
typedef itk::Image< itk::Vector<float, 3> ,3 > VectorImageType3D;
typedef itk::StandardImageRepresenter<itk::Vector<float, 3>, 3> RepresenterType3D;

typedef itk::Image<float, 2> ImageType2D;
typedef itk::Image< itk::Vector<float, 2> ,2 > VectorImageType2D;
typedef itk::StandardImageRepresenter<itk::Vector<float, 2>, 2> RepresenterType2D;

int getdir (std::string dir, std::vector<std::string> &files, const std::string& extension=".*") {
    itk::Directory::Pointer directory = itk::Directory::New();
    directory->Load(dir.c_str());

    for (unsigned i = 0; i < directory->GetNumberOfFiles(); i++) {
        const char* filename = directory->GetFile(i);
        if (extension == ".*" || std::string(filename).find(extension) != std::string::npos)
            files.push_back(filename);
    }

    return 0;
}

template <class RepresenterType, class ImageType>
void itkExample(const char* dir, const char* modelname) {

    typedef itk::PCAModelBuilder<ImageType> ModelBuilderType;
    typedef itk::StatisticalModel<ImageType> StatisticalModelType;
    typedef std::vector<std::string> StringVectorType;
    typedef itk::DataManager<ImageType> DataManagerType;
    typedef itk::ImageFileReader<ImageType> ImageFileReaderType;

    StringVectorType filenames;
    getdir(dir, filenames, ".vtk");

    // we take an arbitrary dataset as the reference, as they have all the same resolution anyway
    std::string referenceFilename = (std::string(dir) + "/" + filenames[0]);
    typename ImageFileReaderType::Pointer refReader = ImageFileReaderType::New();
    refReader->SetFileName(referenceFilename);
    refReader->Update();

    typename RepresenterType::Pointer representer = RepresenterType::New();
    representer->SetReference(refReader->GetOutput());

    typename DataManagerType::Pointer dataManager = DataManagerType::New();
    dataManager->SetRepresenter(representer);

    for (StringVectorType::const_iterator it = filenames.begin(); it != filenames.end(); it++) {

        std::string fullpath = (std::string(dir) + "/") + *it;
        typename ImageFileReaderType::Pointer reader = ImageFileReaderType::New();
        reader->SetFileName(fullpath);
        reader->Update();
        typename ImageType::Pointer df = reader->GetOutput();

        dataManager->AddDataset(df, fullpath.c_str());
    }

    typename ModelBuilderType::Pointer pcaModelBuilder = ModelBuilderType::New();
    typename StatisticalModelType::Pointer model = pcaModelBuilder->BuildNewModel(dataManager->GetData(), 0);
    model->Save(modelname);

}

int main(int argc, char* argv[]) {

    if (argc < 4) {
        std::cout << "usage " << argv[0] << " dimension deformationFieldDir modelname" << std::endl;
        exit(-1);
    }

    unsigned int dimension = atoi(argv[1]);
    const char* dir = argv[2];
    const char* modelname = argv[3];

    if (dimension==2) {
        itkExample<RepresenterType2D, VectorImageType2D>(dir, modelname);
    } else if (dimension==3) {
        itkExample<RepresenterType3D, VectorImageType3D>(dir, modelname);
    } else {
        assert(0);
    }

    std::cout << "Model building is completed successfully." << std::endl;
}

<commit_msg>added command line argument to itkBuildDeformationModel<commit_after>/*
 * This file is part of the statismo library.
 *
 * Author: Marcel Luethi (marcel.luethi@unibas.ch)
 *
 * Copyright (c) 2011 University of Basel
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 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.
 *
 * Neither the name of the project's 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 COPYRIGHT HOLDERS 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 COPYRIGHT
 * HOLDER 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 <sys/types.h>
#include <errno.h>
#include <iostream>

#include <itkDirectory.h>
#include <itkImageFileReader.h>

#include "itkDataManager.h"
#include "itkPCAModelBuilder.h"
#include "itkStandardImageRepresenter.h"
#include "itkStatisticalModel.h"

/*
 * This example shows the ITK Wrapping of statismo can be used to build a deformation model.
 */

typedef itk::Image<float, 3> ImageType3D;
typedef itk::Image< itk::Vector<float, 3> ,3 > VectorImageType3D;
typedef itk::StandardImageRepresenter<itk::Vector<float, 3>, 3> RepresenterType3D;

typedef itk::Image<float, 2> ImageType2D;
typedef itk::Image< itk::Vector<float, 2> ,2 > VectorImageType2D;
typedef itk::StandardImageRepresenter<itk::Vector<float, 2>, 2> RepresenterType2D;

int getdir (std::string dir, std::vector<std::string> &files, const std::string& extension=".*") {
    itk::Directory::Pointer directory = itk::Directory::New();
    directory->Load(dir.c_str());

    for (unsigned i = 0; i < directory->GetNumberOfFiles(); i++) {
        const char* filename = directory->GetFile(i);
        if (extension == ".*" || std::string(filename).find(extension) != std::string::npos)
            files.push_back(filename);
    }

    return 0;
}

template <class RepresenterType, class ImageType>
void itkExample(const char* dir, const char* modelname, double noiseVariance) {

    typedef itk::PCAModelBuilder<ImageType> ModelBuilderType;
    typedef itk::StatisticalModel<ImageType> StatisticalModelType;
    typedef std::vector<std::string> StringVectorType;
    typedef itk::DataManager<ImageType> DataManagerType;
    typedef itk::ImageFileReader<ImageType> ImageFileReaderType;

    StringVectorType filenames;
    getdir(dir, filenames, ".vtk");

    // we take an arbitrary dataset as the reference, as they have all the same resolution anyway
    std::string referenceFilename = (std::string(dir) + "/" + filenames[0]);
    typename ImageFileReaderType::Pointer refReader = ImageFileReaderType::New();
    refReader->SetFileName(referenceFilename);
    refReader->Update();

    typename RepresenterType::Pointer representer = RepresenterType::New();
    representer->SetReference(refReader->GetOutput());

    typename DataManagerType::Pointer dataManager = DataManagerType::New();
    dataManager->SetRepresenter(representer);

    for (StringVectorType::const_iterator it = filenames.begin(); it != filenames.end(); it++) {

        std::string fullpath = (std::string(dir) + "/") + *it;
        typename ImageFileReaderType::Pointer reader = ImageFileReaderType::New();
        reader->SetFileName(fullpath);
        reader->Update();
        typename ImageType::Pointer df = reader->GetOutput();

        dataManager->AddDataset(df, fullpath.c_str());
    }

    typename ModelBuilderType::Pointer pcaModelBuilder = ModelBuilderType::New();
    typename StatisticalModelType::Pointer model = pcaModelBuilder->BuildNewModel(dataManager->GetData(), noiseVariance);
    model->Save(modelname);

}

int main(int argc, char* argv[]) {

    if (argc < 4) {
        std::cout << "usage " << argv[0] << " dimension deformationFieldDir modelname [noiseVariance = 0]" << std::endl;
        exit(-1);
    }

    unsigned int dimension = atoi(argv[1]);
    const char* dir = argv[2];
    const char* modelname = argv[3];

    double noiseVariance = 0;
    if (argc > 4) {
      noiseVariance = atof(argv[4]);
    }

    if (dimension==2) {
        itkExample<RepresenterType2D, VectorImageType2D>(dir, modelname, noiseVariance);
    } else if (dimension==3) {
        itkExample<RepresenterType3D, VectorImageType3D>(dir, modelname, noiseVariance);
    } else {
        assert(0);
    }

    std::cout << "Model building is completed successfully with a noise variance of " << noiseVariance << "." << std::endl;
}

<|endoftext|>


<commit_before>#include "evaluator.h"
#include "mugen_exception.h"
#include "character.h"
#include "mugen_animation.h"
#include "ast/all.h"
#include <math.h>

/* TODO:
 * 1. Change RuntimeValue into an object that stores pointers so that the
 * overhead of copying values is not so high.
 * 2. 1 necessitates garbage collection. Implement precise mark/sweep.
 * 3. Convert interpreter into a compiler. Refresher
 *   (define intepreter (lambda (env) (lambda (input) (eval env input))))
 *   (define compiler (lambda (input) (let ([compiled (compile input)])
 *                       (lambda (env) (eval env compiled)))))
 * 4. Implement simple optimizations: constant folding, dead code elimintation.
 */

using namespace std;

namespace Mugen{

string toString(const RuntimeValue & value){
    if (value.isString()){
        return value.getStringValue();
    }
    throw MugenException("Not a string");
}

double toNumber(const RuntimeValue & value){
    if (value.isDouble()){
        return value.getDoubleValue();
    }
    throw MugenException("Not a number");
}

bool toBool(const RuntimeValue & value){
    if (value.isBool()){
        return value.getBoolValue();
    }
    if (value.isDouble()){
        return value.getDoubleValue() != 0;
    }
    throw MugenException("Not a bool");
}

/* a meta-circular evaluator! */
class Evaluator: public Ast::Walker {
public:
    Evaluator(const Environment & environment):
        environment(environment){
        }

    const Environment & environment;
    RuntimeValue result;

    /* value1 == value2 */
    RuntimeValue same(const RuntimeValue & value1, const RuntimeValue & value2){
        switch (value1.type){
            case RuntimeValue::ListOfString : {
                switch (value2.type){
                    case RuntimeValue::String : {
                        const vector<string> & strings = value1.strings_value;
                        for (vector<string>::const_iterator it = strings.begin(); it != strings.end(); it++){
                            const string & check = *it;
                            if (check == value2.string_value){
                                return RuntimeValue(true);
                            }
                        }
                        return RuntimeValue(false);
                    }
                }
                break;
            }
            case RuntimeValue::String : {
                switch (value2.type){
                    case RuntimeValue::ListOfString : {
                        return same(value2, value1);
                    }
                    case RuntimeValue::String : {
                        return toString(value1) == toString(value2);
                    }
                }
                break;
            }
            case RuntimeValue::Double : {
                switch (value2.type){
                    case RuntimeValue::Double : {
                        double epsilon = 0.0000001;
                        return RuntimeValue(fabs(value1.getDoubleValue() - value2.getDoubleValue()) < epsilon);
                    }
                }
                break;
            }
        }

        return RuntimeValue(false);
    }

    RuntimeValue evaluate(const Ast::Value * value){
        return Mugen::evaluate(value, environment);
    }

    RuntimeValue evalIdentifier(const Ast::Identifier & identifier){
        if (identifier == "command"){
            return RuntimeValue(environment.getCommands());
        }

        if (identifier == "anim"){
            return RuntimeValue(environment.getCharacter().getAnimation());
        }

        if (identifier == "alive"){
            /* FIXME */
            return RuntimeValue(true);
        }

        if (identifier == "p2statetype"){
            /* FIXME */
            return RuntimeValue(0);
        }

        if (identifier == "animtime"){
            return RuntimeValue(environment.getCharacter().getCurrentAnimation()->animationTime());
        }

        if (identifier == "animelem"){
            /* FIXME! */
            return RuntimeValue(0);
        }

        if (identifier == "time"){
            return RuntimeValue(environment.getCharacter().getStateTime());
        }

        if (identifier == "A"){
            /* FIXME */
            return RuntimeValue(string("A"));
        }

        if (identifier == "S"){
            /* FIXME */
            return RuntimeValue(string("S"));
        }

        if (identifier == "C"){
            /* FIXME */
            return RuntimeValue(string("C"));
        }

        if (identifier == "statetype"){
            /* FIXME */
            return RuntimeValue(string("S"));
        }

        /* true if the player has control */
        if (identifier == "ctrl"){
            return RuntimeValue(environment.getCharacter().hasControl());
        }

        if (identifier == "stateno"){
            return RuntimeValue(environment.getCharacter().getCurrentState());
        }

        if (identifier == "power"){
            return RuntimeValue(environment.getCharacter().getPower());
        }

        if (identifier == "velocity.walk.back.x"){
            return RuntimeValue(environment.getCharacter().getWalkBackX());
        }

        if (identifier == "velocity.walk.fwd.x"){
            return RuntimeValue(environment.getCharacter().getWalkForwardX());
        }

        if (identifier == "velocity.run.fwd.x"){
            return RuntimeValue(environment.getCharacter().getRunForwardX());
        }

        if (identifier == "velocity.jump.neu.x"){
            return RuntimeValue(environment.getCharacter().getNeutralJumpingX());
        }

        if (identifier == "velocity.jump.y"){
            return RuntimeValue(environment.getCharacter().getNeutralJumpingY());
        }

        if (identifier == "prevstateno"){
            return RuntimeValue(environment.getCharacter().getPreviousState());
        }

        if (identifier == "velocity.run.back.x"){
            return RuntimeValue(environment.getCharacter().getRunBackX());
        }

        if (identifier == "velocity.run.back.y"){
            return RuntimeValue(environment.getCharacter().getRunBackY());
        }

        if (identifier == "velocity.jump.back.x"){
            return RuntimeValue(environment.getCharacter().getJumpBack());
        }

        if (identifier == "velocity.jump.fwd.x"){
            return RuntimeValue(environment.getCharacter().getJumpForward());
        }

        if (identifier == "velocity.runjump.fwd.x"){
            return RuntimeValue(environment.getCharacter().getRunJumpForward());
        }

        ostringstream out;
        out << "Unknown identifier '" << identifier.toString() << "'";
        throw MugenException(out.str());
    }

    virtual void onIdenfitier(const Ast::Identifier & identifier){
        result = evalIdentifier(identifier);
    }

    RuntimeValue evalKeyword(const Ast::Keyword & keyword){
        if (keyword == "vel x"){
            return RuntimeValue(environment.getCharacter().getXVelocity());
        }

        if (keyword == "vel y"){
            return RuntimeValue(environment.getCharacter().getYVelocity());
        }

        if (keyword == "pos y"){
            return RuntimeValue(-environment.getCharacter().getYPosition());
        }

        if (keyword == "p2bodydist x"){
            /* FIXME */
            return RuntimeValue(0);
        }

        ostringstream out;
        out << "Unknown keyword '" << keyword.toString() << "'";
        throw MugenException(out.str());
    }

    virtual void onKeyword(const Ast::Keyword & keyword){
        result = evalKeyword(keyword);
    }

    RuntimeValue evalString(const Ast::String & string_value){
        string out;
        string_value >> out;
        return RuntimeValue(out);
    }

    virtual void onString(const Ast::String & string){
        result = evalString(string);
    }

    RuntimeValue evalFunction(const Ast::Function & function){
        if (function == "const"){
            return evaluate(function.getArg1());
        }

        if (function == "abs"){
            return RuntimeValue(fabs(toNumber(evaluate(function.getArg1()))));
        }

        if (function == "var"){
            int index = (int) toNumber(evaluate(function.getArg1()));
            Ast::Value * value = environment.getCharacter().getVariable(index);
            if (value == 0){
                ostringstream out;
                out << "No variable for index " << index;
                throw MugenException(out.str());
            }
            return evaluate(value);
        }

        if (function == "sysvar"){
            int index = (int) toNumber(evaluate(function.getArg1()));
            Ast::Value * value = environment.getCharacter().getSystemVariable(index);
            if (value == 0){
                ostringstream out;
                out << "No system variable for index " << index;
                throw MugenException(out.str());
            }
            return evaluate(value);
        }

        if (function == "ifelse"){
            if (toBool(evaluate(function.getArg1()))){
                return evaluate(function.getArg2());
            } else {
                return evaluate(function.getArg3());
            }
        }

        if (function == "selfanimexist"){
            int animation = (int) toNumber(evaluate(function.getArg1()));
            return RuntimeValue(environment.getCharacter().hasAnimation(animation));
        }

        /* Gets the animation-time elapsed since the start of a specified element
         * of the current animation action. Useful for synchronizing events to
         * elements of an animation action.
         *
         * (reminder: first element of an action is element 1, not 0)
         */
        if (function == "animelemtime"){
            /* FIXME */
            return RuntimeValue(0);
        }

        ostringstream out;
        out << "Unknown function '" << function.toString() << "'";
        throw MugenException(out.str());
    }

    virtual void onFunction(const Ast::Function & string){
        result = evalFunction(string);
    }

    RuntimeValue evalNumber(const Ast::Number & number){
        double x;
        number >> x;
        return RuntimeValue(x);
    }

    virtual void onNumber(const Ast::Number & number){
        result = evalNumber(number);
    }

    virtual RuntimeValue evalExpressionInfix(const Ast::ExpressionInfix & expression){
        Global::debug(1) << "Evaluate expression " << expression.toString() << endl;
        using namespace Ast;
        switch (expression.getExpressionType()){
            case ExpressionInfix::Or : {
                return RuntimeValue(toBool(evaluate(expression.getLeft())) ||
                                    toBool(evaluate(expression.getRight())));
            }
            case ExpressionInfix::XOr : {
                return RuntimeValue(toBool(evaluate(expression.getLeft())) ^
                                    toBool(evaluate(expression.getRight())));
            }
            case ExpressionInfix::And : {
                return RuntimeValue(toBool(evaluate(expression.getLeft())) &&
                                    toBool(evaluate(expression.getRight())));
            }
            case ExpressionInfix::BitwiseOr : {
                return RuntimeValue((int)toNumber(evaluate(expression.getLeft())) |
                                    (int)toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::BitwiseXOr : {
                return RuntimeValue((int)toNumber(evaluate(expression.getLeft())) ^
                                    (int)toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::BitwiseAnd : {
                return RuntimeValue((int)toNumber(evaluate(expression.getLeft())) &
                                    (int)toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::Assignment : {
                /* FIXME: is this needed? */
                break;
            }
            case ExpressionInfix::Equals : {
                return same(evaluate(expression.getLeft()), evaluate(expression.getRight()));
                break;
            }
            case ExpressionInfix::Unequals : {
                return RuntimeValue(!toBool(same(evaluate(expression.getLeft()), evaluate(expression.getRight()))));
            }
            case ExpressionInfix::GreaterThanEquals : {
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) >= toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::GreaterThan : {
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) > toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::LessThanEquals : {
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) <= toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::LessThan : {
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) < toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::Add : {
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) + toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::Subtract : {
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) - toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::Multiply : {
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) * toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::Divide : {
                /* FIXME: catch divide by 0 */
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) / toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::Modulo : {
                return RuntimeValue((int)toNumber(evaluate(expression.getLeft())) % (int)toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::Power : {
                return RuntimeValue(pow(toNumber(evaluate(expression.getLeft())), toNumber(evaluate(expression.getRight()))));
            }
        }

        ostringstream out;
        out << "Unknown expression: " << expression.toString();
        throw MugenException(out.str());
    }

    virtual void onExpressionInfix(const Ast::ExpressionInfix & expression){
        result = evalExpressionInfix(expression);
    }

    RuntimeValue evalExpressionUnary(const Ast::ExpressionUnary & expression){
        switch (expression.getExpressionType()){
            case Ast::ExpressionUnary::Not : {
                return RuntimeValue(!toBool(evaluate(expression.getExpression())));
            }
            case Ast::ExpressionUnary::Minus : {
                return RuntimeValue(-toNumber(evaluate(expression.getExpression())));
            }
            case Ast::ExpressionUnary::Negation : {
                return RuntimeValue(~(int)toNumber(evaluate(expression.getExpression())));
            }
        }

        ostringstream out;
        out << "Unknown expression: " << expression.toString();
        throw MugenException(out.str());
    }

    virtual void onExpressionUnary(const Ast::ExpressionUnary & expression){
        result = evalExpressionUnary(expression);
    }
};

RuntimeValue evaluate(const Ast::Value * value, const Environment & environment){
    try{
        Evaluator eval(environment);
        value->walk(eval);
        return eval.result;
    } catch (const MugenException & e){
        ostringstream out;
        out << "Error while evaluating expression `" << value->toString() << "': " << e.getReason();
        throw MugenException(out.str());
    }
}

}
<commit_msg>treat booleans as numbers<commit_after>#include "evaluator.h"
#include "mugen_exception.h"
#include "character.h"
#include "mugen_animation.h"
#include "ast/all.h"
#include <math.h>

/* TODO:
 * 1. Change RuntimeValue into an object that stores pointers so that the
 * overhead of copying values is not so high.
 * 2. 1 necessitates garbage collection. Implement precise mark/sweep.
 * 3. Convert interpreter into a compiler. Refresher
 *   (define intepreter (lambda (env) (lambda (input) (eval env input))))
 *   (define compiler (lambda (input) (let ([compiled (compile input)])
 *                       (lambda (env) (eval env compiled)))))
 * 4. Implement simple optimizations: constant folding, dead code elimintation.
 */

using namespace std;

namespace Mugen{

string toString(const RuntimeValue & value){
    if (value.isString()){
        return value.getStringValue();
    }
    throw MugenException("Not a string");
}

double toNumber(const RuntimeValue & value){
    if (value.isDouble()){
        return value.getDoubleValue();
    }
    if (value.isBool()){
        if (value.getBoolValue()){
            return 1;
        } else {
            return 0;
        }
    }
    throw MugenException("Not a number");
}

bool toBool(const RuntimeValue & value){
    if (value.isBool()){
        return value.getBoolValue();
    }
    if (value.isDouble()){
        return value.getDoubleValue() != 0;
    }
    throw MugenException("Not a bool");
}

/* a meta-circular evaluator! */
class Evaluator: public Ast::Walker {
public:
    Evaluator(const Environment & environment):
        environment(environment){
        }

    const Environment & environment;
    RuntimeValue result;

    /* value1 == value2 */
    RuntimeValue same(const RuntimeValue & value1, const RuntimeValue & value2){
        switch (value1.type){
            case RuntimeValue::ListOfString : {
                switch (value2.type){
                    case RuntimeValue::String : {
                        const vector<string> & strings = value1.strings_value;
                        for (vector<string>::const_iterator it = strings.begin(); it != strings.end(); it++){
                            const string & check = *it;
                            if (check == value2.string_value){
                                return RuntimeValue(true);
                            }
                        }
                        return RuntimeValue(false);
                    }
                }
                break;
            }
            case RuntimeValue::String : {
                switch (value2.type){
                    case RuntimeValue::ListOfString : {
                        return same(value2, value1);
                    }
                    case RuntimeValue::String : {
                        return toString(value1) == toString(value2);
                    }
                }
                break;
            }
            case RuntimeValue::Double : {
                switch (value2.type){
                    case RuntimeValue::Double : {
                        double epsilon = 0.0000001;
                        return RuntimeValue(fabs(value1.getDoubleValue() - value2.getDoubleValue()) < epsilon);
                    }
                }
                break;
            }
        }

        return RuntimeValue(false);
    }

    RuntimeValue evaluate(const Ast::Value * value){
        return Mugen::evaluate(value, environment);
    }

    RuntimeValue evalIdentifier(const Ast::Identifier & identifier){
        if (identifier == "command"){
            return RuntimeValue(environment.getCommands());
        }

        if (identifier == "anim"){
            return RuntimeValue(environment.getCharacter().getAnimation());
        }

        if (identifier == "alive"){
            /* FIXME */
            return RuntimeValue(true);
        }

        if (identifier == "p2statetype"){
            /* FIXME */
            return RuntimeValue(0);
        }

        if (identifier == "animtime"){
            return RuntimeValue(environment.getCharacter().getCurrentAnimation()->animationTime());
        }

        if (identifier == "animelem"){
            /* FIXME! */
            return RuntimeValue(0);
        }

        if (identifier == "time"){
            return RuntimeValue(environment.getCharacter().getStateTime());
        }

        if (identifier == "A"){
            /* FIXME */
            return RuntimeValue(string("A"));
        }

        if (identifier == "S"){
            /* FIXME */
            return RuntimeValue(string("S"));
        }

        if (identifier == "C"){
            /* FIXME */
            return RuntimeValue(string("C"));
        }

        if (identifier == "statetype"){
            /* FIXME */
            return RuntimeValue(string("S"));
        }

        /* true if the player has control */
        if (identifier == "ctrl"){
            return RuntimeValue(environment.getCharacter().hasControl());
        }

        if (identifier == "stateno"){
            return RuntimeValue(environment.getCharacter().getCurrentState());
        }

        if (identifier == "power"){
            return RuntimeValue(environment.getCharacter().getPower());
        }

        if (identifier == "velocity.walk.back.x"){
            return RuntimeValue(environment.getCharacter().getWalkBackX());
        }

        if (identifier == "velocity.walk.fwd.x"){
            return RuntimeValue(environment.getCharacter().getWalkForwardX());
        }

        if (identifier == "velocity.run.fwd.x"){
            return RuntimeValue(environment.getCharacter().getRunForwardX());
        }

        if (identifier == "velocity.jump.neu.x"){
            return RuntimeValue(environment.getCharacter().getNeutralJumpingX());
        }

        if (identifier == "velocity.jump.y"){
            return RuntimeValue(environment.getCharacter().getNeutralJumpingY());
        }

        if (identifier == "prevstateno"){
            return RuntimeValue(environment.getCharacter().getPreviousState());
        }

        if (identifier == "velocity.run.back.x"){
            return RuntimeValue(environment.getCharacter().getRunBackX());
        }

        if (identifier == "velocity.run.back.y"){
            return RuntimeValue(environment.getCharacter().getRunBackY());
        }

        if (identifier == "velocity.jump.back.x"){
            return RuntimeValue(environment.getCharacter().getJumpBack());
        }

        if (identifier == "velocity.jump.fwd.x"){
            return RuntimeValue(environment.getCharacter().getJumpForward());
        }

        if (identifier == "velocity.runjump.fwd.x"){
            return RuntimeValue(environment.getCharacter().getRunJumpForward());
        }

        ostringstream out;
        out << "Unknown identifier '" << identifier.toString() << "'";
        throw MugenException(out.str());
    }

    virtual void onIdenfitier(const Ast::Identifier & identifier){
        result = evalIdentifier(identifier);
    }

    RuntimeValue evalKeyword(const Ast::Keyword & keyword){
        if (keyword == "vel x"){
            return RuntimeValue(environment.getCharacter().getXVelocity());
        }

        if (keyword == "vel y"){
            return RuntimeValue(environment.getCharacter().getYVelocity());
        }

        if (keyword == "pos y"){
            return RuntimeValue(-environment.getCharacter().getYPosition());
        }

        if (keyword == "p2bodydist x"){
            /* FIXME */
            return RuntimeValue(0);
        }

        ostringstream out;
        out << "Unknown keyword '" << keyword.toString() << "'";
        throw MugenException(out.str());
    }

    virtual void onKeyword(const Ast::Keyword & keyword){
        result = evalKeyword(keyword);
    }

    RuntimeValue evalString(const Ast::String & string_value){
        string out;
        string_value >> out;
        return RuntimeValue(out);
    }

    virtual void onString(const Ast::String & string){
        result = evalString(string);
    }

    RuntimeValue evalFunction(const Ast::Function & function){
        if (function == "const"){
            return evaluate(function.getArg1());
        }

        if (function == "abs"){
            return RuntimeValue(fabs(toNumber(evaluate(function.getArg1()))));
        }

        if (function == "var"){
            int index = (int) toNumber(evaluate(function.getArg1()));
            Ast::Value * value = environment.getCharacter().getVariable(index);
            if (value == 0){
                ostringstream out;
                out << "No variable for index " << index;
                throw MugenException(out.str());
            }
            return evaluate(value);
        }

        if (function == "sysvar"){
            int index = (int) toNumber(evaluate(function.getArg1()));
            Ast::Value * value = environment.getCharacter().getSystemVariable(index);
            if (value == 0){
                ostringstream out;
                out << "No system variable for index " << index;
                throw MugenException(out.str());
            }
            return evaluate(value);
        }

        if (function == "ifelse"){
            if (toBool(evaluate(function.getArg1()))){
                return evaluate(function.getArg2());
            } else {
                return evaluate(function.getArg3());
            }
        }

        if (function == "selfanimexist"){
            int animation = (int) toNumber(evaluate(function.getArg1()));
            return RuntimeValue(environment.getCharacter().hasAnimation(animation));
        }

        /* Gets the animation-time elapsed since the start of a specified element
         * of the current animation action. Useful for synchronizing events to
         * elements of an animation action.
         *
         * (reminder: first element of an action is element 1, not 0)
         */
        if (function == "animelemtime"){
            /* FIXME */
            return RuntimeValue(0);
        }

        ostringstream out;
        out << "Unknown function '" << function.toString() << "'";
        throw MugenException(out.str());
    }

    virtual void onFunction(const Ast::Function & string){
        result = evalFunction(string);
    }

    RuntimeValue evalNumber(const Ast::Number & number){
        double x;
        number >> x;
        return RuntimeValue(x);
    }

    virtual void onNumber(const Ast::Number & number){
        result = evalNumber(number);
    }

    virtual RuntimeValue evalExpressionInfix(const Ast::ExpressionInfix & expression){
        Global::debug(1) << "Evaluate expression " << expression.toString() << endl;
        using namespace Ast;
        switch (expression.getExpressionType()){
            case ExpressionInfix::Or : {
                return RuntimeValue(toBool(evaluate(expression.getLeft())) ||
                                    toBool(evaluate(expression.getRight())));
            }
            case ExpressionInfix::XOr : {
                return RuntimeValue(toBool(evaluate(expression.getLeft())) ^
                                    toBool(evaluate(expression.getRight())));
            }
            case ExpressionInfix::And : {
                return RuntimeValue(toBool(evaluate(expression.getLeft())) &&
                                    toBool(evaluate(expression.getRight())));
            }
            case ExpressionInfix::BitwiseOr : {
                return RuntimeValue((int)toNumber(evaluate(expression.getLeft())) |
                                    (int)toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::BitwiseXOr : {
                return RuntimeValue((int)toNumber(evaluate(expression.getLeft())) ^
                                    (int)toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::BitwiseAnd : {
                return RuntimeValue((int)toNumber(evaluate(expression.getLeft())) &
                                    (int)toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::Assignment : {
                /* FIXME: is this needed? */
                break;
            }
            case ExpressionInfix::Equals : {
                return same(evaluate(expression.getLeft()), evaluate(expression.getRight()));
                break;
            }
            case ExpressionInfix::Unequals : {
                return RuntimeValue(!toBool(same(evaluate(expression.getLeft()), evaluate(expression.getRight()))));
            }
            case ExpressionInfix::GreaterThanEquals : {
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) >= toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::GreaterThan : {
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) > toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::LessThanEquals : {
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) <= toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::LessThan : {
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) < toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::Add : {
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) + toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::Subtract : {
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) - toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::Multiply : {
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) * toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::Divide : {
                /* FIXME: catch divide by 0 */
                return RuntimeValue(toNumber(evaluate(expression.getLeft())) / toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::Modulo : {
                return RuntimeValue((int)toNumber(evaluate(expression.getLeft())) % (int)toNumber(evaluate(expression.getRight())));
            }
            case ExpressionInfix::Power : {
                return RuntimeValue(pow(toNumber(evaluate(expression.getLeft())), toNumber(evaluate(expression.getRight()))));
            }
        }

        ostringstream out;
        out << "Unknown expression: " << expression.toString();
        throw MugenException(out.str());
    }

    virtual void onExpressionInfix(const Ast::ExpressionInfix & expression){
        result = evalExpressionInfix(expression);
    }

    RuntimeValue evalExpressionUnary(const Ast::ExpressionUnary & expression){
        switch (expression.getExpressionType()){
            case Ast::ExpressionUnary::Not : {
                return RuntimeValue(!toBool(evaluate(expression.getExpression())));
            }
            case Ast::ExpressionUnary::Minus : {
                return RuntimeValue(-toNumber(evaluate(expression.getExpression())));
            }
            case Ast::ExpressionUnary::Negation : {
                return RuntimeValue(~(int)toNumber(evaluate(expression.getExpression())));
            }
        }

        ostringstream out;
        out << "Unknown expression: " << expression.toString();
        throw MugenException(out.str());
    }

    virtual void onExpressionUnary(const Ast::ExpressionUnary & expression){
        result = evalExpressionUnary(expression);
    }
};

RuntimeValue evaluate(const Ast::Value * value, const Environment & environment){
    try{
        Evaluator eval(environment);
        value->walk(eval);
        return eval.result;
    } catch (const MugenException & e){
        ostringstream out;
        out << "Error while evaluating expression `" << value->toString() << "': " << e.getReason();
        throw MugenException(out.str());
    }
}

}
<|endoftext|>


<commit_before>#include "ex14_18_String.h"
#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>

void foo(String x)
{
    std::cout << x << std::endl;
}

void bar(const String& x)
{
    std::cout << x.c_str() << std::endl;
}

String baz()
{
    String ret("world");
    return ret;
}

int main()
{
    char text[] = "world";

    String s0;
    String s1("hello");
    String s2(std::move(s0));
    String s3 = s1;
    String s4(text);
    s2 = s1;

    if (s2 == s1) std::cout << "s2 == s1" << std::endl;

    foo(s1);
    bar(s1);
    foo("temporary");
    bar("temporary");
    String s5 = baz();

    std::vector<String> svec;
    // svec.push_back(s0);
    svec.push_back(s1);
    svec.push_back(s2);
    svec.push_back(s3);
    svec.push_back(s4);
    svec.push_back(baz());
    svec.push_back("good job");

    for (const auto& s : svec) {
        std::cout << s << std::endl;
    }

    std::cout << "Input a string: ";
    String s6;
    std::cin >> s6;
    std::cout << s6 << std::endl;

    if (s6 > s1) std::cout << "s6 > s1" << std::endl;
}
<commit_msg>Update ex14_18_StringMain.cpp<commit_after>#include <iostream>
#include <vector>
#include "ex14_18_String.h"
using namespace std;

void foo(String x)
{
    cout << x << endl;
}

void bar(const String& x)
{
    cout << x.c_str() << endl;
}

String baz()
{
    String ret("world");
    return ret;
}

int main()
{
    char text[] = "world";

    String s0;
    String s1("hello");
    String s2(std::move(s0));
    String s3 = s1;
    String s4(text);
    s2 = s1;

    if (s2 == s1)
        cout << "s2 == s1" << endl;

    foo(s1);
    bar(s1);
    foo("temporary");
    bar("temporary");
    String s5 = baz();

    vector<String> svec;
    //svec.push_back(s0);
    svec.push_back(s1);
    svec.push_back(s2);
    svec.push_back(s3);
    svec.push_back(s4);
    svec.push_back(baz());
    svec.push_back("good job");

    for (const auto& s : svec)
    {
        cout << s << endl;
    }

    cout << "Input a string: ";
    String s6;
    cin >> s6;
    cout << s6 << endl;

    if (s6 > s1)
        cout << "s6 > s1" << endl;
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <set>

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>

#define OMPI_SKIP_MPICXX 1
#include <mpi.h>

#include "phIO.h"

char read_solution(double** solutiono, int* size, int* nshgo, int* ndofo,
		int nump, int rank, int timestep, int nSyncFiles, char* casedir);
std::set<int>* find_timesteps(char* casedir, int nSyncFiles);
double compare_solution(char* lpath, char* rpath,
    int timestep, int nump, int nSyncFiles);
const char* getRestartName(int nSyncFiles);

int main(int argc, char** argv)
{
       	int rank;
	int size;
	MPI_Init(&argc, &argv);

	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	MPI_Comm_size(MPI_COMM_WORLD, &size);

	if(argc != 4) {
          fprintf(stderr, "argc %d\n", argc);
          fprintf(stderr,
              "Usage: %s <left> <right> <numSyncFiles>\n"
              "where <left> and <right> are different"
              "N-procs_case directories\n", argv[0]);
          MPI_Finalize();
          return 1;
        }
	char* lpath = argv[1];
	char* rpath = argv[2];
        int nSyncFiles = atoi(argv[3]);

	int ndof;
	int nshg;
	int solsize;
	double* solution;

	std::set<int>* l_timesteps = find_timesteps(lpath, nSyncFiles);
	std::set<int>* r_timesteps = find_timesteps(rpath, nSyncFiles);
	std::set<int>* timesteps_to_check = new std::set<int>;
	std::set_intersection(l_timesteps->begin(), l_timesteps->end(),
			r_timesteps->begin(), r_timesteps->end(),
			std::inserter(*timesteps_to_check, timesteps_to_check->begin()));
        delete l_timesteps;
        delete r_timesteps;
	if(rank == 0)
		printf("Found %d common timesteps\n",
			       	timesteps_to_check->size());
#ifdef DBGONLY
	read_solution(&solution, &solsize, &nshg, &ndof,
            size, rank, 0, numSyncFiles, "./");
	printf("nshg: %d, ndof: %d\n", nshg, ndof);
	assert(solsize == ndof*nshg);
#endif
	double maxerror = 0.0;
	double error;
	double gblmaxerror;
	for(std::set<int>::iterator i = timesteps_to_check->begin();
			i!=timesteps_to_check->end();i++)
	{
		error = compare_solution(lpath, rpath, *i, size, nSyncFiles);
		if(error>maxerror) maxerror = error;
	}
        delete timesteps_to_check;
	MPI_Barrier(MPI_COMM_WORLD);
	MPI_Reduce(&maxerror, &gblmaxerror, 1, MPI_DOUBLE, MPI_MAX, 0,
		MPI_COMM_WORLD);
	if(rank == 0) printf("Maximum difference across all timesteps: %e\n",
			gblmaxerror);
	MPI_Finalize();
}
double compare_solution(char* lpath, char* rpath, int timestep, int nump, int nSyncFiles)
{
	int rank;
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	double* lsol;
	double* rsol;
	int lsize;
	int rsize;

	read_solution(&lsol, &lsize, NULL, NULL,
            nump, rank, timestep, nSyncFiles, lpath);
	read_solution(&rsol, &rsize, NULL, NULL,
            nump, rank, timestep, nSyncFiles, rpath);

	double maxdiff=0.0;
	double gblmaxdiff;
	if(lsize != rsize)
	{
		printf("Error: Solution sizes different: %d, %d\n",
				lsize, rsize);
		assert(lsize == rsize);
	}
	for(int i=0;i<lsize;i++)
	{
		double diff = fabs(lsol[i]-rsol[i]);
		if(diff > maxdiff) maxdiff = diff;
	}
        free(lsol);
        free(rsol);
	MPI_Reduce(&maxdiff, &gblmaxdiff, 1, MPI_DOUBLE, MPI_MAX, 0,
		       	MPI_COMM_WORLD);
	MPI_Barrier(MPI_COMM_WORLD); //TODO: debugging only
	if(rank == 0)
	printf("Timestep: %d, maximum difference: %e\n", timestep, gblmaxdiff);
	return gblmaxdiff;

}
char read_solution(double** solutiono, int* size, int* nshgo, int* ndofo,
		int nump, int rank, int timestep, int nSyncFiles, char* casedir)
{
	int iarray[10];
        const char* iformat = "binary";
        int ithree=3;
        int igeombc;
        char* fn;
	int nshg;
	int ndof;
	double* solution;
        const char* rname = getRestartName(nSyncFiles);
        asprintf(&fn,"%s/%s.%d.",casedir,rname,timestep);
        phio_fp fp;
        phio_openfile_read(fn,&nSyncFiles,&fp);
	phio_readheader(fp, "solution", (void*) iarray, &ithree, "integer", iformat);
	nshg = iarray[0];
	ndof = iarray[1];
	if(size != NULL)
		*size = nshg*ndof;
	solution = (double*) malloc(sizeof(double)*nshg*ndof);
	phio_readdatablock(fp, "solution", solution, size, "double", iformat);
	phio_closefile_read(fp);
	if(solutiono != NULL)
		*solutiono = solution;
	if(nshgo != NULL)
		*nshgo = nshg;
	if(ndofo != NULL)
		*ndofo = ndof;
	free(fn);
	return(0);
}

std::set<int>* find_timesteps(char* casedir, int nSyncFiles)
{
	char* path;
	DIR* dir;
	struct dirent* d;
	int part, ts;
	std::set<int>* step_list = new std::set<int>;

        asprintf(&path, "%s", casedir);
	dir = opendir(path);
	if(!dir)
	{
		perror("Error opening case: ");
		MPI_Abort(MPI_COMM_WORLD,1);
	}
        const char* rname = getRestartName(nSyncFiles);
        char* fmt;
        asprintf(&fmt, "%s.%%d.%%d", rname);
	while((d=readdir(dir)))
	{
		if(sscanf(d->d_name, fmt, &ts, &part)==2)
		{
			step_list->insert(ts);
		}
	}
        free(fmt);
	free(path);
	return(step_list);
}

const char* getRestartName(int nSyncFiles) {
  if(0 == nSyncFiles)
    return "restart";
  else if(nSyncFiles > 0)
    return "restart-dat";
  else {
    fprintf(stderr,
        "ERROR: the number of sync-io files must be"
        "greater than or equal to zero\n");
    MPI_Abort(MPI_COMM_WORLD, 1);
    return NULL;
  }
}
<commit_msg>compare against user defined tolerance<commit_after>#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <set>

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>

#define OMPI_SKIP_MPICXX 1
#include <mpi.h>

#include "phIO.h"

char read_solution(double** solutiono, int* size, int* nshgo, int* ndofo,
		int nump, int rank, int timestep, int nSyncFiles, char* casedir);
std::set<int>* find_timesteps(char* casedir, int nSyncFiles);
double compare_solution(char* lpath, char* rpath,
    int timestep, int nump, int nSyncFiles);
const char* getRestartName(int nSyncFiles);

int main(int argc, char** argv)
{
       	int rank;
	int size;
	MPI_Init(&argc, &argv);

	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	MPI_Comm_size(MPI_COMM_WORLD, &size);

	if(argc != 5) {
          fprintf(stderr, "argc %d\n", argc);
          fprintf(stderr,
              "Usage: %s <left> <right> <numSyncFiles> <tolerance>\n"
              "where <left> and <right> are different"
              "N-procs_case directories\n", argv[0]);
          MPI_Finalize();
          return 1;
        }
	char* lpath = argv[1];
	char* rpath = argv[2];
        int nSyncFiles = atoi(argv[3]);
        double tolerance = atof(argv[4]);

	int ndof;
	int nshg;
	int solsize;
	double* solution;

	std::set<int>* l_timesteps = find_timesteps(lpath, nSyncFiles);
	std::set<int>* r_timesteps = find_timesteps(rpath, nSyncFiles);
	std::set<int>* timesteps_to_check = new std::set<int>;
	std::set_intersection(l_timesteps->begin(), l_timesteps->end(),
			r_timesteps->begin(), r_timesteps->end(),
			std::inserter(*timesteps_to_check, timesteps_to_check->begin()));
        delete l_timesteps;
        delete r_timesteps;
	if(rank == 0)
		printf("Found %d common timesteps\n",
			       	timesteps_to_check->size());
#ifdef DBGONLY
	read_solution(&solution, &solsize, &nshg, &ndof,
            size, rank, 0, numSyncFiles, "./");
	printf("nshg: %d, ndof: %d\n", nshg, ndof);
	assert(solsize == ndof*nshg);
#endif
	double maxerror = 0.0;
	double error;
	double gblmaxerror;
	for(std::set<int>::iterator i = timesteps_to_check->begin();
			i!=timesteps_to_check->end();i++)
	{
		error = compare_solution(lpath, rpath, *i, size, nSyncFiles);
		if(error>maxerror) maxerror = error;
	}
        delete timesteps_to_check;
	MPI_Barrier(MPI_COMM_WORLD);
	MPI_Reduce(&maxerror, &gblmaxerror, 1, MPI_DOUBLE, MPI_MAX, 0,
		MPI_COMM_WORLD);
	if(rank == 0) printf("Maximum difference across all timesteps: %e\n",
			gblmaxerror);
	MPI_Finalize();
        return (gblmaxerror > tolerance);
}
double compare_solution(char* lpath, char* rpath, int timestep, int nump, int nSyncFiles)
{
	int rank;
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	double* lsol;
	double* rsol;
	int lsize;
	int rsize;

	read_solution(&lsol, &lsize, NULL, NULL,
            nump, rank, timestep, nSyncFiles, lpath);
	read_solution(&rsol, &rsize, NULL, NULL,
            nump, rank, timestep, nSyncFiles, rpath);

	double maxdiff=0.0;
	double gblmaxdiff;
	if(lsize != rsize)
	{
		printf("Error: Solution sizes different: %d, %d\n",
				lsize, rsize);
		assert(lsize == rsize);
	}
	for(int i=0;i<lsize;i++)
	{
		double diff = fabs(lsol[i]-rsol[i]);
		if(diff > maxdiff) maxdiff = diff;
	}
        free(lsol);
        free(rsol);
	MPI_Reduce(&maxdiff, &gblmaxdiff, 1, MPI_DOUBLE, MPI_MAX, 0,
		       	MPI_COMM_WORLD);
	MPI_Barrier(MPI_COMM_WORLD); //TODO: debugging only
	if(rank == 0)
	printf("Timestep: %d, maximum difference: %e\n", timestep, gblmaxdiff);
	return gblmaxdiff;

}
char read_solution(double** solutiono, int* size, int* nshgo, int* ndofo,
		int nump, int rank, int timestep, int nSyncFiles, char* casedir)
{
	int iarray[10];
        const char* iformat = "binary";
        int ithree=3;
        int igeombc;
        char* fn;
	int nshg;
	int ndof;
	double* solution;
        const char* rname = getRestartName(nSyncFiles);
        asprintf(&fn,"%s/%s.%d.",casedir,rname,timestep);
        phio_fp fp;
        phio_openfile_read(fn,&nSyncFiles,&fp);
	phio_readheader(fp, "solution", (void*) iarray, &ithree, "integer", iformat);
	nshg = iarray[0];
	ndof = iarray[1];
	if(size != NULL)
		*size = nshg*ndof;
	solution = (double*) malloc(sizeof(double)*nshg*ndof);
	phio_readdatablock(fp, "solution", solution, size, "double", iformat);
	phio_closefile_read(fp);
	if(solutiono != NULL)
		*solutiono = solution;
	if(nshgo != NULL)
		*nshgo = nshg;
	if(ndofo != NULL)
		*ndofo = ndof;
	free(fn);
	return(0);
}

std::set<int>* find_timesteps(char* casedir, int nSyncFiles)
{
	char* path;
	DIR* dir;
	struct dirent* d;
	int part, ts;
	std::set<int>* step_list = new std::set<int>;

        asprintf(&path, "%s", casedir);
	dir = opendir(path);
	if(!dir)
	{
		perror("Error opening case: ");
		MPI_Abort(MPI_COMM_WORLD,1);
	}
        const char* rname = getRestartName(nSyncFiles);
        char* fmt;
        asprintf(&fmt, "%s.%%d.%%d", rname);
	while((d=readdir(dir)))
	{
		if(sscanf(d->d_name, fmt, &ts, &part)==2)
		{
			step_list->insert(ts);
		}
	}
        free(fmt);
	free(path);
	return(step_list);
}

const char* getRestartName(int nSyncFiles) {
  if(0 == nSyncFiles)
    return "restart";
  else if(nSyncFiles > 0)
    return "restart-dat";
  else {
    fprintf(stderr,
        "ERROR: the number of sync-io files must be"
        "greater than or equal to zero\n");
    MPI_Abort(MPI_COMM_WORLD, 1);
    return NULL;
  }
}
<|endoftext|>


<commit_before>// @(#)root/base:$Id$
// Author: Rene Brun 29/10/09

/*************************************************************************
 * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TTreePerfStats                                                       //
//                                                                      //
// TTree I/O performance measurement                                    //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TTreePerfStats.h"
#include "TFile.h"
#include "TTree.h"
#include "TAxis.h"
#include "TPaveText.h"
#include "TGraphErrors.h"
#include "TStopwatch.h"

ClassImp(TTreePerfStats)

//______________________________________________________________________________
TTreePerfStats::TTreePerfStats(TTree *T) : TVirtualPerfStats()
{
   // Return the name of the event type.

   fTree = T;
   fFile = T->GetCurrentFile();
   fGraph = new TGraphErrors(0);
   fGraph->SetName("ioperf");
   fGraph->SetTitle(Form("%s/%s",fFile->GetName(),T->GetName()));
   fGraph->SetUniqueID(999999999);
   fWatch  = new TStopwatch();
   fWatch->Start();
   gPerfStats = this;
}

//______________________________________________________________________________
void TTreePerfStats::Draw(Option_t * /*option*/)
{
   // Draw the graph

   fGraph->Draw("ap");
   fGraph->GetXaxis()->SetTitle("Tree entry number");
   fGraph->GetYaxis()->SetTitle("file position");
   Double_t extra = 100.*fFile->GetBytesReadExtra()/fFile->GetBytesRead();
   TPaveText *pv = new TPaveText(.2,.55,.5,.88,"brNDC");
   pv->SetTextAlign(12);
   pv->AddText(Form("TreeCache = %d MBytes",fTree->GetCacheSize()/1000000));
   pv->AddText(Form("ReadTotal = %g MBytes",1e-6*fFile->GetBytesRead()));
   pv->AddText(Form("ReadCalls = %d",fFile->GetReadCalls()));
   pv->AddText(Form("ReadSize  = %g KBytes/read",0.001*fFile->GetBytesRead()/fFile->GetReadCalls()));
   pv->AddText(Form("Readahead = %d KBytes",TFile::GetReadaheadSize()/1000));
   pv->AddText(Form("Readextra = %5.2f per cent",extra));
   pv->AddText(Form("Real Time = %7.3f seconds",fWatch->RealTime()));
   pv->AddText(Form("CPU  Time = %7.3f seconds",fWatch->CpuTime()));
   pv->AddText(Form("ReadRT    = %7.3f MBytes/s",1e-6*fFile->GetBytesRead()/fWatch->RealTime()));
   pv->AddText(Form("ReadCP    = %7.3f MBytes/s",1e-6*fFile->GetBytesRead()/fWatch->CpuTime()));
   pv->Draw();
}

//______________________________________________________________________________
void TTreePerfStats::FileReadEvent(TFile *file, Int_t len, Double_t /*proctime*/)
{
   // Return the name of the event type.

   Long64_t offset = file->GetRelOffset();
   Int_t np = fGraph->GetN();
   Int_t entry = fTree->GetReadEntry();
   Double_t err = len/2.;
   fGraph->SetPoint(np,entry,offset-err);
   fGraph->SetPointError(np,0.01,len);
}

//______________________________________________________________________________
void TTreePerfStats::Print(Option_t * /*option*/) const
{
   // Draw the graph

   Double_t extra = 100.*fFile->GetBytesReadExtra()/fFile->GetBytesRead();
   printf("TreeCache = %d MBytes\n",Int_t(fTree->GetCacheSize()/1000000));
   printf("ReadTotal = %g MBytes\n",1e-6*fFile->GetBytesRead());
   printf("ReadCalls = %d\n",fFile->GetReadCalls());
   printf("ReadSize  = %g KBytes/read\n",0.001*fFile->GetBytesRead()/fFile->GetReadCalls());
   printf("Readahead = %d KBytes\n",TFile::GetReadaheadSize()/1000);
   printf("Readextra = %5.2f per cent\n",extra);
   printf("Real Time = %7.3f seconds\n",fWatch->RealTime());
   printf("CPU  Time = %7.3f seconds\n",fWatch->CpuTime());
   printf("ReadRT    = %7.3f MBytes/s\n",1e-6*fFile->GetBytesRead()/fWatch->RealTime());
   printf("ReadCP    = %7.3f MBytes/s\n",1e-6*fFile->GetBytesRead()/fWatch->CpuTime());
}
<commit_msg>Add a grid to the performance graph<commit_after>// @(#)root/base:$Id$
// Author: Rene Brun 29/10/09

/*************************************************************************
 * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TTreePerfStats                                                       //
//                                                                      //
// TTree I/O performance measurement                                    //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TTreePerfStats.h"
#include "TFile.h"
#include "TTree.h"
#include "TAxis.h"
#include "TVirtualPad.h"
#include "TPaveText.h"
#include "TGraphErrors.h"
#include "TStopwatch.h"

ClassImp(TTreePerfStats)

//______________________________________________________________________________
TTreePerfStats::TTreePerfStats(TTree *T) : TVirtualPerfStats()
{
   // Return the name of the event type.

   fTree = T;
   fFile = T->GetCurrentFile();
   fGraph = new TGraphErrors(0);
   fGraph->SetName("ioperf");
   fGraph->SetTitle(Form("%s/%s",fFile->GetName(),T->GetName()));
   fGraph->SetUniqueID(999999999);
   fWatch  = new TStopwatch();
   fWatch->Start();
   gPerfStats = this;
}

//______________________________________________________________________________
void TTreePerfStats::Draw(Option_t * /*option*/)
{
   // Draw the graph

   fGraph->Draw("ap");
   gPad->SetGridx();
   gPad->SetGridy();
   fGraph->GetXaxis()->SetTitle("Tree entry number");
   fGraph->GetYaxis()->SetTitle("file position");
   Double_t extra = 100.*fFile->GetBytesReadExtra()/fFile->GetBytesRead();
   TPaveText *pv = new TPaveText(.2,.55,.5,.88,"brNDC");
   pv->SetTextAlign(12);
   pv->AddText(Form("TreeCache = %d MBytes",fTree->GetCacheSize()/1000000));
   pv->AddText(Form("ReadTotal = %g MBytes",1e-6*fFile->GetBytesRead()));
   pv->AddText(Form("ReadCalls = %d",fFile->GetReadCalls()));
   pv->AddText(Form("ReadSize  = %g KBytes/read",0.001*fFile->GetBytesRead()/fFile->GetReadCalls()));
   pv->AddText(Form("Readahead = %d KBytes",TFile::GetReadaheadSize()/1000));
   pv->AddText(Form("Readextra = %5.2f per cent",extra));
   pv->AddText(Form("Real Time = %7.3f seconds",fWatch->RealTime()));
   pv->AddText(Form("CPU  Time = %7.3f seconds",fWatch->CpuTime()));
   pv->AddText(Form("ReadRT    = %7.3f MBytes/s",1e-6*fFile->GetBytesRead()/fWatch->RealTime()));
   pv->AddText(Form("ReadCP    = %7.3f MBytes/s",1e-6*fFile->GetBytesRead()/fWatch->CpuTime()));
   pv->Draw();
}

//______________________________________________________________________________
void TTreePerfStats::FileReadEvent(TFile *file, Int_t len, Double_t /*proctime*/)
{
   // Return the name of the event type.

   Long64_t offset = file->GetRelOffset();
   Int_t np = fGraph->GetN();
   Int_t entry = fTree->GetReadEntry();
   Double_t err = len/2.;
   fGraph->SetPoint(np,entry,offset-err);
   fGraph->SetPointError(np,0.01,len);
}

//______________________________________________________________________________
void TTreePerfStats::Print(Option_t * /*option*/) const
{
   // Draw the graph

   Double_t extra = 100.*fFile->GetBytesReadExtra()/fFile->GetBytesRead();
   printf("TreeCache = %d MBytes\n",Int_t(fTree->GetCacheSize()/1000000));
   printf("ReadTotal = %g MBytes\n",1e-6*fFile->GetBytesRead());
   printf("ReadCalls = %d\n",fFile->GetReadCalls());
   printf("ReadSize  = %g KBytes/read\n",0.001*fFile->GetBytesRead()/fFile->GetReadCalls());
   printf("Readahead = %d KBytes\n",TFile::GetReadaheadSize()/1000);
   printf("Readextra = %5.2f per cent\n",extra);
   printf("Real Time = %7.3f seconds\n",fWatch->RealTime());
   printf("CPU  Time = %7.3f seconds\n",fWatch->CpuTime());
   printf("ReadRT    = %7.3f MBytes/s\n",1e-6*fFile->GetBytesRead()/fWatch->RealTime());
   printf("ReadCP    = %7.3f MBytes/s\n",1e-6*fFile->GetBytesRead()/fWatch->CpuTime());
}
<|endoftext|>


<commit_before>#include <net/VRNetClient.h>
#include <main/VRLog.h>
#include <main/VRError.h>

#include <iostream>
#include <sstream>

namespace MinVR {

// get sockaddr, IPv4 or IPv6:
void *get_in_addr2(struct sockaddr *sa) {
  if (sa->sa_family == AF_INET) {
    return &(((struct sockaddr_in*)sa)->sin_addr);
  }
  return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

VRNetClient::VRNetClient(const std::string &serverIP, const std::string &serverPort)
{
  VRLOG_STATUS("VRNetClient connecting...");

#ifdef WIN32  // WinSock implementation

  WSADATA wsaData;
  SOCKET sockfd = INVALID_SOCKET;
  struct addrinfo hints, *servinfo, *p;
  int rv;

  rv = WSAStartup(MAKEWORD(2,2), &wsaData);
  if (rv != 0) {
    stringstream s;
    s << "WSAStartup failed with error: " << rv;
    VRERROR(s, "Check for a problem with Windows networking.");
    exit(1);
  }

  ZeroMemory(&hints, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_protocol = IPPROTO_TCP;

  if ((rv = getaddrinfo(serverIP.c_str(), serverPort.c_str(), &hints, &servinfo)) != 0) {
    stringstream s;
    s << "getaddrinfo() failed with error: " << rv;
    VRERROR(s.str(), "Check for a problem with Windows networking.");
    WSACleanup();
    exit(1);
  }

  //This is a temporary fix to ensure the client can connect and that the connection is not refused
  p = NULL;
  while(p == NULL){
    // loop through all the results and connect to the first we can
    for (p = servinfo; p != NULL; p = p->ai_next) {
      if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == INVALID_SOCKET) {
	      stringstream s;
        s << "socket() failed with error " << WSAGetLastError() << "; will retry.";
        VRLOG_STATUS(s.str());
        continue;
      }

      if (connect(sockfd, p->ai_addr, (int)p->ai_addrlen) == SOCKET_ERROR) {
        closesocket(sockfd);
        sockfd = INVALID_SOCKET;
	      stringstream s;
        s << "connect() to server socket failed; will retry.";
        VRLOG_STATUS(s.str());
        continue;
      }

      break;
    }
  }

  if (p == NULL) {
    VRERROR("VRNetClient failed to connect -- exiting.", "Check for a problem with Windows networking.");
    exit(2);
  }

  //inet_ntop(p->ai_family, get_in_addr2((struct sockaddr *)p->ai_addr), s, sizeof s);
  //printf("client: connecting to %s\n", s);
  VRLOG_STATUS("VRNetClient connected.");

  freeaddrinfo(servinfo); // all done with this structure

  // Disable Nagle's algorithm
  char value = 1;
  setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value));

  _socketFD = sockfd;

#else  // BSD sockets implementation

  int sockfd;
  struct addrinfo hints, *servinfo, *p;
  int rv;
  char s[INET6_ADDRSTRLEN];
  char problemString[50];

  memset(&hints, 0, sizeof hints);
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;

  if ((rv = getaddrinfo(serverIP.c_str(), serverPort.c_str(), &hints, &servinfo)) != 0) {
    stringstream s;
    s << "getaddrinfo() failed with error: " << rv;
    VRERROR(s.str(), "Check for a problem with networking.");
    exit(1);
  }

  //This is a temporary fix to ensure the client can connect and that the connection is not refused
  p = NULL;
  while(p == NULL){
    // loop through all the results and connect to the first we can
    for (p = servinfo; p != NULL; p = p->ai_next) {
      if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
        stringstream s;
        s << "socket() failed; will retry.";
        VRLOG_STATUS(s.str());
        continue;
      }

      if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
        close(sockfd);
        stringstream s;
        s << "client (pid=" << getpid() << "): connect() to server socket failed; will retry.";
        VRLOG_STATUS(s.str());
        continue;
      }

      break;
    }
  }
  if (p == NULL) {
    VRERROR("VRNetClient failed to connect -- exiting.", "Check for a problem with networking.");
    exit(2);
  }

  inet_ntop(p->ai_family, get_in_addr2((struct sockaddr *)p->ai_addr), s, sizeof(s));
  VRLOG_STATUS("VRNetClient connected to " + std::string(s));

  freeaddrinfo(servinfo); // all done with this structure

  // Disable Nagle's algorithm
  char value = 1;
  setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value));

  _socketFD = sockfd;

#endif

}

VRNetClient::~VRNetClient()
{
  VRLOG_STATUS("VRNetClient closing socket.");
#ifdef WIN32
  closesocket(_socketFD);
  WSACleanup();
#else
  close(_socketFD);
#endif
}

VRDataQueue VRNetClient::syncEventDataAcrossAllNodes(VRDataQueue eventQueue) {

  // 1. send inputEvents to server
  sendEventData(_socketFD, eventQueue.serialize());

  // 2. receive all events from the server
  VRDataQueue::serialData allEventData = waitForAndReceiveEventData(_socketFD);

  return VRDataQueue(allEventData);
}

void
VRNetClient::syncSwapBuffersAcrossAllNodes()
{
  // 1. send a swap_buffers_request message to the server
  sendSwapBuffersRequest(_socketFD);

  // 2. wait for and receive a swap_buffers_now message from the server
  waitForAndReceiveSwapBuffersNow(_socketFD);
}

} // end namespace MinVR
<commit_msg>Update VRNetClient.cpp<commit_after>#include <net/VRNetClient.h>
#include <main/VRLog.h>
#include <main/VRError.h>

#include <iostream>
#include <sstream>

namespace MinVR {

// get sockaddr, IPv4 or IPv6:
void *get_in_addr2(struct sockaddr *sa) {
  if (sa->sa_family == AF_INET) {
    return &(((struct sockaddr_in*)sa)->sin_addr);
  }
  return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

VRNetClient::VRNetClient(const std::string &serverIP, const std::string &serverPort)
{
  VRLOG_STATUS("VRNetClient connecting...");

#ifdef WIN32  // WinSock implementation

  WSADATA wsaData;
  SOCKET sockfd = INVALID_SOCKET;
  struct addrinfo hints, *servinfo, *p;
  int rv;

  rv = WSAStartup(MAKEWORD(2,2), &wsaData);
  if (rv != 0) {
    stringstream s;
    s << "WSAStartup failed with error: " << rv;
    VRERROR(s.str(), "Check for a problem with Windows networking.");
    exit(1);
  }

  ZeroMemory(&hints, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_protocol = IPPROTO_TCP;

  if ((rv = getaddrinfo(serverIP.c_str(), serverPort.c_str(), &hints, &servinfo)) != 0) {
    stringstream s;
    s << "getaddrinfo() failed with error: " << rv;
    VRERROR(s.str(), "Check for a problem with Windows networking.");
    WSACleanup();
    exit(1);
  }

  //This is a temporary fix to ensure the client can connect and that the connection is not refused
  p = NULL;
  while(p == NULL){
    // loop through all the results and connect to the first we can
    for (p = servinfo; p != NULL; p = p->ai_next) {
      if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == INVALID_SOCKET) {
	      stringstream s;
        s << "socket() failed with error " << WSAGetLastError() << "; will retry.";
        VRLOG_STATUS(s.str());
        continue;
      }

      if (connect(sockfd, p->ai_addr, (int)p->ai_addrlen) == SOCKET_ERROR) {
        closesocket(sockfd);
        sockfd = INVALID_SOCKET;
	      stringstream s;
        s << "connect() to server socket failed; will retry.";
        VRLOG_STATUS(s.str());
        continue;
      }

      break;
    }
  }

  if (p == NULL) {
    VRERROR("VRNetClient failed to connect -- exiting.", "Check for a problem with Windows networking.");
    exit(2);
  }

  //inet_ntop(p->ai_family, get_in_addr2((struct sockaddr *)p->ai_addr), s, sizeof s);
  //printf("client: connecting to %s\n", s);
  VRLOG_STATUS("VRNetClient connected.");

  freeaddrinfo(servinfo); // all done with this structure

  // Disable Nagle's algorithm
  char value = 1;
  setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value));

  _socketFD = sockfd;

#else  // BSD sockets implementation

  int sockfd;
  struct addrinfo hints, *servinfo, *p;
  int rv;
  char s[INET6_ADDRSTRLEN];
  char problemString[50];

  memset(&hints, 0, sizeof hints);
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;

  if ((rv = getaddrinfo(serverIP.c_str(), serverPort.c_str(), &hints, &servinfo)) != 0) {
    stringstream s;
    s << "getaddrinfo() failed with error: " << rv;
    VRERROR(s.str(), "Check for a problem with networking.");
    exit(1);
  }

  //This is a temporary fix to ensure the client can connect and that the connection is not refused
  p = NULL;
  while(p == NULL){
    // loop through all the results and connect to the first we can
    for (p = servinfo; p != NULL; p = p->ai_next) {
      if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
        stringstream s;
        s << "socket() failed; will retry.";
        VRLOG_STATUS(s.str());
        continue;
      }

      if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
        close(sockfd);
        stringstream s;
        s << "client (pid=" << getpid() << "): connect() to server socket failed; will retry.";
        VRLOG_STATUS(s.str());
        continue;
      }

      break;
    }
  }
  if (p == NULL) {
    VRERROR("VRNetClient failed to connect -- exiting.", "Check for a problem with networking.");
    exit(2);
  }

  inet_ntop(p->ai_family, get_in_addr2((struct sockaddr *)p->ai_addr), s, sizeof(s));
  VRLOG_STATUS("VRNetClient connected to " + std::string(s));

  freeaddrinfo(servinfo); // all done with this structure

  // Disable Nagle's algorithm
  char value = 1;
  setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value));

  _socketFD = sockfd;

#endif

}

VRNetClient::~VRNetClient()
{
  VRLOG_STATUS("VRNetClient closing socket.");
#ifdef WIN32
  closesocket(_socketFD);
  WSACleanup();
#else
  close(_socketFD);
#endif
}

VRDataQueue VRNetClient::syncEventDataAcrossAllNodes(VRDataQueue eventQueue) {

  // 1. send inputEvents to server
  sendEventData(_socketFD, eventQueue.serialize());

  // 2. receive all events from the server
  VRDataQueue::serialData allEventData = waitForAndReceiveEventData(_socketFD);

  return VRDataQueue(allEventData);
}

void
VRNetClient::syncSwapBuffersAcrossAllNodes()
{
  // 1. send a swap_buffers_request message to the server
  sendSwapBuffersRequest(_socketFD);

  // 2. wait for and receive a swap_buffers_now message from the server
  waitForAndReceiveSwapBuffersNow(_socketFD);
}

} // end namespace MinVR
<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes
#include <limits>

// Local includes
#include "libmesh/elem.h"
#include "libmesh/error_vector.h"
#include "libmesh/libmesh_logging.h"

#include "libmesh/dof_map.h"
#include "libmesh/equation_systems.h"
#include "libmesh/explicit_system.h"
#include "libmesh/mesh_base.h"
#include "libmesh/numeric_vector.h"
#include "libmesh/gmv_io.h"
#include "libmesh/tecplot_io.h"
#include "libmesh/exodusII_io.h"

namespace libMesh
{

// ------------------------------------------------------------
// ErrorVector class member functions
ErrorVectorReal ErrorVector::minimum() const
{
  START_LOG ("minimum()", "ErrorVector");

  const unsigned int n = this->size();
  ErrorVectorReal min = std::numeric_limits<ErrorVectorReal>::max();

  for (unsigned int i=0; i<n; i++)
    {
      // Only positive (or zero) values in the error vector
      libmesh_assert_greater_equal ((*this)[i], 0.);
      if (this->is_active_elem(i))
        min = std::min (min, (*this)[i]);
    }
  STOP_LOG ("minimum()", "ErrorVector");

  // ErrorVectors are for positive values
  libmesh_assert_greater_equal (min, 0.);

  return min;
}

Real ErrorVector::mean() const
{
  START_LOG ("mean()", "ErrorVector");

  const unsigned int n = this->size();

  Real mean  = 0;
  unsigned int nnz = 0;

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	mean += ( static_cast<Real>((*this)[i]) - mean ) / (nnz + 1);

	nnz++;
      }

  STOP_LOG ("mean()", "ErrorVector");

  return mean;
}

Real ErrorVector::median()
{
  const unsigned int n   = this->size();

  if (n == 0)
    return 0.;

  // Build a StatisticsVector<ErrorVectorReal> containing
  // only our active entries and take its mean
  StatisticsVector<ErrorVectorReal> sv;

  sv.reserve (n);

  for (unsigned int i=0; i<n; i++)
    if(this->is_active_elem(i))
      sv.push_back((*this)[i]);

  return sv.median();
}

Real ErrorVector::median() const
{
  ErrorVector ev = (*this);

  return ev.median();
}

Real ErrorVector::variance(const Real mean) const
{
  const unsigned int n   = this->size();

  START_LOG ("variance()", "ErrorVector");

  Real variance = 0;
  unsigned int nnz = 0;

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	const Real delta = ( static_cast<Real>((*this)[i]) - mean );
	variance += (delta * delta - variance) / (nnz + 1);

	nnz++;
      }

  STOP_LOG ("variance()", "ErrorVector");

  return variance;
}

std::vector<unsigned int> ErrorVector::cut_below(Real cut) const
{
  START_LOG ("cut_below()", "ErrorVector");

  const unsigned int n = this->size();

  std::vector<unsigned int> cut_indices;
  cut_indices.reserve(n/2);  // Arbitrary

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	if ((*this)[i] < cut)
	  {
	    cut_indices.push_back(i);
	  }
      }

  STOP_LOG ("cut_below()", "ErrorVector");

  return cut_indices;
}

std::vector<unsigned int> ErrorVector::cut_above(Real cut) const
{
  START_LOG ("cut_above()", "ErrorVector");

  const unsigned int n   = this->size();

  std::vector<unsigned int> cut_indices;
  cut_indices.reserve(n/2);  // Arbitrary

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	if ((*this)[i] > cut)
	  {
	    cut_indices.push_back(i);
	  }
      }

  STOP_LOG ("cut_above()", "ErrorVector");

  return cut_indices;
}

bool ErrorVector::is_active_elem (unsigned int i) const
{
  libmesh_assert_less (i, this->size());

  if (_mesh)
    {
      libmesh_assert(_mesh->elem(i));
      return _mesh->elem(i)->active();
    }
  else
    return ((*this)[i] != 0.);
}

void ErrorVector::plot_error(const std::string& filename,
                             const MeshBase& oldmesh) const
{
  AutoPtr<MeshBase> meshptr = oldmesh.clone();
  MeshBase &mesh = *meshptr;
  mesh.all_first_order();
  EquationSystems temp_es (mesh);
  ExplicitSystem& error_system
    = temp_es.add_system<ExplicitSystem> ("Error");
  error_system.add_variable("error", CONSTANT, MONOMIAL);
  temp_es.init();

  const DofMap& error_dof_map = error_system.get_dof_map();

  MeshBase::const_element_iterator       el     =
    mesh.active_local_elements_begin();
  const MeshBase::const_element_iterator end_el =
    mesh.active_local_elements_end();
  std::vector<unsigned int> dof_indices;

  for ( ; el != end_el; ++el)
  {
    const Elem* elem = *el;

    error_dof_map.dof_indices(elem, dof_indices);

    const unsigned int elem_id = elem->id();

    //0 for the monomial basis
    const unsigned int solution_index = dof_indices[0];
    // libMesh::out << "elem_number=" << elem_number << std::endl;
    libmesh_assert_less (elem_id, (*this).size());
//  We may have zero error values in special circumstances
//    libmesh_assert_greater ((*this)[elem_id], 0.);
    error_system.solution->set(solution_index, (*this)[elem_id]);
  }
  if (filename.rfind(".gmv") < filename.size())
    {
//      GMVIO(mesh).write_equation_systems(filename,
//                                         temp_es);
// write_discontinuous_gmv doesn't work on second order meshes??
// [RHS]
      GMVIO(mesh).write_discontinuous_gmv(filename,
                                          temp_es, false);
    }
  else if (filename.rfind(".plt") < filename.size())
    {
      TecplotIO (mesh).write_equation_systems
        (filename, temp_es);
    }
#ifdef LIBMESH_HAVE_EXODUS_API
  else if( (filename.rfind(".exo") < filename.size()) ||
	   (filename.rfind(".e") < filename.size()) )
    {
      ExodusII_IO io(mesh);
      io.write(filename);
      io.write_element_data(temp_es);
    }
#endif
  else
    {
      libmesh_here();
      libMesh::err << "Warning: ErrorVector::plot_error currently only"
                    << " supports .gmv and .plt and .exo/.e (if enabled) output;" << std::endl;
      libMesh::err << "Could not recognize filename: " << filename
                    << std::endl;
    }
}

} // namespace libMesh

<commit_msg>We can safely renumber if necessary to plot an error vector on a non-contiguously-numbered mesh.<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// C++ includes
#include <limits>

// Local includes
#include "libmesh/elem.h"
#include "libmesh/error_vector.h"
#include "libmesh/libmesh_logging.h"

#include "libmesh/dof_map.h"
#include "libmesh/equation_systems.h"
#include "libmesh/explicit_system.h"
#include "libmesh/mesh_base.h"
#include "libmesh/numeric_vector.h"
#include "libmesh/gmv_io.h"
#include "libmesh/tecplot_io.h"
#include "libmesh/exodusII_io.h"

namespace libMesh
{

// ------------------------------------------------------------
// ErrorVector class member functions
ErrorVectorReal ErrorVector::minimum() const
{
  START_LOG ("minimum()", "ErrorVector");

  const unsigned int n = this->size();
  ErrorVectorReal min = std::numeric_limits<ErrorVectorReal>::max();

  for (unsigned int i=0; i<n; i++)
    {
      // Only positive (or zero) values in the error vector
      libmesh_assert_greater_equal ((*this)[i], 0.);
      if (this->is_active_elem(i))
        min = std::min (min, (*this)[i]);
    }
  STOP_LOG ("minimum()", "ErrorVector");

  // ErrorVectors are for positive values
  libmesh_assert_greater_equal (min, 0.);

  return min;
}

Real ErrorVector::mean() const
{
  START_LOG ("mean()", "ErrorVector");

  const unsigned int n = this->size();

  Real mean  = 0;
  unsigned int nnz = 0;

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	mean += ( static_cast<Real>((*this)[i]) - mean ) / (nnz + 1);

	nnz++;
      }

  STOP_LOG ("mean()", "ErrorVector");

  return mean;
}

Real ErrorVector::median()
{
  const unsigned int n   = this->size();

  if (n == 0)
    return 0.;

  // Build a StatisticsVector<ErrorVectorReal> containing
  // only our active entries and take its mean
  StatisticsVector<ErrorVectorReal> sv;

  sv.reserve (n);

  for (unsigned int i=0; i<n; i++)
    if(this->is_active_elem(i))
      sv.push_back((*this)[i]);

  return sv.median();
}

Real ErrorVector::median() const
{
  ErrorVector ev = (*this);

  return ev.median();
}

Real ErrorVector::variance(const Real mean) const
{
  const unsigned int n   = this->size();

  START_LOG ("variance()", "ErrorVector");

  Real variance = 0;
  unsigned int nnz = 0;

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	const Real delta = ( static_cast<Real>((*this)[i]) - mean );
	variance += (delta * delta - variance) / (nnz + 1);

	nnz++;
      }

  STOP_LOG ("variance()", "ErrorVector");

  return variance;
}

std::vector<unsigned int> ErrorVector::cut_below(Real cut) const
{
  START_LOG ("cut_below()", "ErrorVector");

  const unsigned int n = this->size();

  std::vector<unsigned int> cut_indices;
  cut_indices.reserve(n/2);  // Arbitrary

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	if ((*this)[i] < cut)
	  {
	    cut_indices.push_back(i);
	  }
      }

  STOP_LOG ("cut_below()", "ErrorVector");

  return cut_indices;
}

std::vector<unsigned int> ErrorVector::cut_above(Real cut) const
{
  START_LOG ("cut_above()", "ErrorVector");

  const unsigned int n   = this->size();

  std::vector<unsigned int> cut_indices;
  cut_indices.reserve(n/2);  // Arbitrary

  for (unsigned int i=0; i<n; i++)
    if (this->is_active_elem(i))
      {
	if ((*this)[i] > cut)
	  {
	    cut_indices.push_back(i);
	  }
      }

  STOP_LOG ("cut_above()", "ErrorVector");

  return cut_indices;
}

bool ErrorVector::is_active_elem (unsigned int i) const
{
  libmesh_assert_less (i, this->size());

  if (_mesh)
    {
      libmesh_assert(_mesh->elem(i));
      return _mesh->elem(i)->active();
    }
  else
    return ((*this)[i] != 0.);
}

void ErrorVector::plot_error(const std::string& filename,
                             const MeshBase& oldmesh) const
{
  AutoPtr<MeshBase> meshptr = oldmesh.clone();
  MeshBase &mesh = *meshptr;
  mesh.all_first_order();
  EquationSystems temp_es (mesh);
  ExplicitSystem& error_system
    = temp_es.add_system<ExplicitSystem> ("Error");
  error_system.add_variable("error", CONSTANT, MONOMIAL);
  temp_es.init();

  const DofMap& error_dof_map = error_system.get_dof_map();

  MeshBase::const_element_iterator       el     =
    mesh.active_local_elements_begin();
  const MeshBase::const_element_iterator end_el =
    mesh.active_local_elements_end();
  std::vector<unsigned int> dof_indices;

  for ( ; el != end_el; ++el)
  {
    const Elem* elem = *el;

    error_dof_map.dof_indices(elem, dof_indices);

    const unsigned int elem_id = elem->id();

    //0 for the monomial basis
    const unsigned int solution_index = dof_indices[0];

    // libMesh::out << "elem_number=" << elem_number << std::endl;
    libmesh_assert_less (elem_id, (*this).size());

    // We may have zero error values in special circumstances
    // libmesh_assert_greater ((*this)[elem_id], 0.);
    error_system.solution->set(solution_index, (*this)[elem_id]);
  }

  // We may have to renumber if the original numbering was not
  // contiguous.  Since this is just a temporary mesh, that's probably
  // fine.
  if (mesh.max_elem_id() != mesh.n_elem() ||
      mesh.max_node_id() != mesh.n_nodes())
    {
      mesh.allow_renumbering(true);
      mesh.renumber_nodes_and_elements();
    }

  if (filename.rfind(".gmv") < filename.size())
    {
      GMVIO(mesh).write_discontinuous_gmv(filename,
                                          temp_es, false);
    }
  else if (filename.rfind(".plt") < filename.size())
    {
      TecplotIO (mesh).write_equation_systems
        (filename, temp_es);
    }
#ifdef LIBMESH_HAVE_EXODUS_API
  else if( (filename.rfind(".exo") < filename.size()) ||
	   (filename.rfind(".e") < filename.size()) )
    {
      ExodusII_IO io(mesh);
      io.write(filename);
      io.write_element_data(temp_es);
    }
#endif
  else
    {
      libmesh_here();
      libMesh::err << "Warning: ErrorVector::plot_error currently only"
                    << " supports .gmv and .plt and .exo/.e (if enabled) output;" << std::endl;
      libMesh::err << "Could not recognize filename: " << filename
                    << std::endl;
    }
}

} // namespace libMesh

<|endoftext|>


<commit_before>/*
 * This file is part of the kfeed library
 *
 * Copyright (C) 2007 Frank Osterfeld <osterfeld@kde.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "enclosure.h"

#include <QString>

struct KFeed::EnclosurePrivate
{
public:
    EnclosurePrivate() : length( 0 ), duration( 0 )
    {
    }

    bool operator==( const EnclosurePrivate& other ) const
    {
        return url == other.url && title == other.title && type == other.type && length == other.length && duration == other.duration;
    }

    bool operator!=( const EnclosurePrivate& other ) const
    {
        return url != other.url && title != other.title && type != other.type && length != other.length && duration != other.duration;
    }

    QString url;
    QString title;
    QString type;
    uint length;
    uint duration;
};

KFeed::Enclosure::Enclosure() : d( new EnclosurePrivate )
{
}

KFeed::Enclosure::Enclosure( const Enclosure& other) : d( new EnclosurePrivate )
{
    *d = *(other.d);
}

KFeed::Enclosure::~Enclosure()
{
    delete d;
}

KFeed::Enclosure& KFeed::Enclosure::operator=( const KFeed::Enclosure& other )
{
    *d = *(other.d);
    return *this;
}

bool KFeed::Enclosure::operator==( const KFeed::Enclosure& other ) const
{
    return *d == *(other.d);
}

bool KFeed::Enclosure::operator!=( const KFeed::Enclosure& other ) const
{
    return *d != *(other.d);
}

QString KFeed::Enclosure::url() const
{
    return d->url;
}

void KFeed::Enclosure::setUrl( const QString& url )
{
    d->url = url;
}

QString KFeed::Enclosure::title() const
{
    return d->title;
}

void KFeed::Enclosure::setTitle( const QString& title )
{
    d->title = title;
}

QString KFeed::Enclosure::type() const
{
    return d->type;
}

void KFeed::Enclosure::setType( const QString& type )
{
    d->type = type;
}

uint KFeed::Enclosure::length() const
{
    return d->length;
}

void KFeed::Enclosure::setLength( uint length )
{
    d->length = length;
}

uint KFeed::Enclosure::duration() const
{
    return d->duration;
}

void KFeed::Enclosure::setDuration( uint duration )
{
    d->duration = duration;
}

<commit_msg>msvc warning--<commit_after>/*
 * This file is part of the kfeed library
 *
 * Copyright (C) 2007 Frank Osterfeld <osterfeld@kde.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "enclosure.h"

#include <QString>

class KFeed::EnclosurePrivate
{
public:
    EnclosurePrivate() : length( 0 ), duration( 0 )
    {
    }

    bool operator==( const EnclosurePrivate& other ) const
    {
        return url == other.url && title == other.title && type == other.type && length == other.length && duration == other.duration;
    }

    bool operator!=( const EnclosurePrivate& other ) const
    {
        return url != other.url && title != other.title && type != other.type && length != other.length && duration != other.duration;
    }

    QString url;
    QString title;
    QString type;
    uint length;
    uint duration;
};

KFeed::Enclosure::Enclosure() : d( new EnclosurePrivate )
{
}

KFeed::Enclosure::Enclosure( const Enclosure& other) : d( new EnclosurePrivate )
{
    *d = *(other.d);
}

KFeed::Enclosure::~Enclosure()
{
    delete d;
}

KFeed::Enclosure& KFeed::Enclosure::operator=( const KFeed::Enclosure& other )
{
    *d = *(other.d);
    return *this;
}

bool KFeed::Enclosure::operator==( const KFeed::Enclosure& other ) const
{
    return *d == *(other.d);
}

bool KFeed::Enclosure::operator!=( const KFeed::Enclosure& other ) const
{
    return *d != *(other.d);
}

QString KFeed::Enclosure::url() const
{
    return d->url;
}

void KFeed::Enclosure::setUrl( const QString& url )
{
    d->url = url;
}

QString KFeed::Enclosure::title() const
{
    return d->title;
}

void KFeed::Enclosure::setTitle( const QString& title )
{
    d->title = title;
}

QString KFeed::Enclosure::type() const
{
    return d->type;
}

void KFeed::Enclosure::setType( const QString& type )
{
    d->type = type;
}

uint KFeed::Enclosure::length() const
{
    return d->length;
}

void KFeed::Enclosure::setLength( uint length )
{
    d->length = length;
}

uint KFeed::Enclosure::duration() const
{
    return d->duration;
}

void KFeed::Enclosure::setDuration( uint duration )
{
    d->duration = duration;
}

<|endoftext|>