<commit_before>/*
Copyright libCellML Contributors

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

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

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

#include "libcellml/generator.h"

namespace libcellml{

using namespace libcellml::operators;

const std::unordered_map<CXX::types, std::string, EnumClassHash> CXX::returnTypes = {
    {types::void_t,"void "},
    {types::double_t, "double "},
    {types::double_ct, "const double "},
    {types::double_pt, "double* "},
    {types::double_rt, "double& "}
};

const std::unordered_map<CXX::types, std::string, EnumClassHash> CXX::argTypes = {
    {types::void_t,"void "},
    {types::double_t, "double "},
    {types::double_ct, "const double "},
    {types::double_pt, "double* "},
    {types::double_rt, "double& "},
};

template<typename L>
std::string Generator::generateStateAliases()
{
    std::string s;
    std::ostringstream oss(s);
    for (size_t i = 0; i < states.size(); i++)
    {
        oss << "    "
            << L::argType(L::types::double_rt) << states[i] << " = " << L::dereferenceOp() << "(states + " << i
            << ")" << L::instructionDelimiter() << std::endl;
    }
    oss << std::endl;
    return oss.str();
}

template<typename L>
std::string Generator::generateVoiAlias()
{
    std::string s;
    std::ostringstream oss(s);
    oss << "    "
        << L::argType(L::types::double_ct) << voi << " = voi" << L::instructionDelimiter() << std::endl;
    oss << std::endl;
    return oss.str();
}

template<typename L>
std::string Generator::generateInitConsts()
{
    std::string s;
    std::ostringstream oss(s);
    oss << L::returnType(L::types::void_t) << "initConsts"
        << L::argListOp()
        << L::argType(L::types::double_pt)
        << "constants, "
        << L::argType(L::types::double_pt)
        << "rates, "
        << L::argType(L::types::double_pt)
        << "states"
        << L::argListCl() << std::endl
        << L::funBodyOp() << std::endl;

    oss << generateStateAliases() << std::endl;
    for (auto s : initialValues)
    {
        oss << "    " << s.first << " = "
            << std::setprecision(16) << s.second << L::instructionDelimiter() << std::endl;
    }
    oss << std::endl << L::funBodyCl();
    return oss.str();
}

template<typename L>
std::string Generator::generateComputeRates(std::shared_ptr<Representable> r)
{
    std::string s;
    std::ostringstream oss(s);
    oss << L::returnType(L::types::void_t) << "computeRates"
        << L::argListOp()
        << L::argType(L::types::double_t)
        << "voi, "
        << L::argType(L::types::double_pt)
        << "constants, "
        << L::argType(L::types::double_pt)
        << "rates, "
        << L::argType(L::types::double_pt)
        << "states, "
        << L::argType(L::types::double_pt)
        << "algebraic"
        << L::argListCl() << std::endl
        << L::funBodyOp() << std::endl;

    oss << generateVoiAlias() << std::endl;
    oss << generateStateAliases() << std::endl;

    oss << "    rates[0] = "
        << r->repr() << ";" << std::endl;

    oss << std::endl
        << L::funBodyCl();
    return oss.str();
}

template<typename L>
std::string Generator::generateComputeVariables()
{
    std::string s;
    std::ostringstream oss(s);
    oss << L::returnType(L::types::void_t) << "computeVariables"
        << L::argListOp()
        << L::argType(L::types::double_t)
        << "voi, "
        << L::argType(L::types::double_pt)
        << "constants, "
        << L::argType(L::types::double_pt)
        << "rates, "
        << L::argType(L::types::double_pt)
        << "states, "
        << L::argType(L::types::double_pt)
        << "algebraic"
        << L::argListCl()  << std::endl
        << L::funBodyOp() << std::endl
        << L::funBodyCl();
    return oss.str();
}

void Generator::findInitialValues(ComponentPtr c)
{
    for (std::size_t i = 0; i < c->variableCount(); i++)
    {
        auto v = c->getVariable(i);
        if (v->getName() != voi)
        {
            initialValues[v->getName()] = std::stod(v->getInitialValue());
        }
    }
}

template<typename L>
std::string Generator::generateCode(ModelPtr m)
{
    ComponentPtr c = m->getComponent(0);

    findVOI(c->getMath());
    findInitialValues(c);
    auto r = parseMathML(c->getMath());

    std::string generatedCode;
    std::ostringstream oss(generatedCode);
    oss << generateInitConsts<L>() << std::endl;
    oss << generateComputeRates<L>(r) << std::endl;
    oss << generateComputeVariables<L>() << std::endl;

    code = oss.str();
    return code;
}

void Generator::writeCodeToFile(std::string filename)
{
    if (code == "")
    {
        ErrorPtr err = std::make_shared<Error>();
        err->setDescription("No code was generated yet, you should call "
                "Generator::generateCode before calling this method.");
        addError(err);
        throw CodeNotGenerated();
    }

    std::ofstream output(filename);
    output << code;
    output.close();
}

std::shared_ptr<Representable> Generator::parseNode(XmlNodePtr node)
{
    if (node->isType("apply"))
    {
        return parseNode(node->getFirstChild());
    }
    else if (node->isType("plus"))
    {
        auto c = std::make_shared<Addition>();
        auto s = node->getNext();
        c->setArg1(parseNode(s));
        s = s->getNext();
        if (!s->getNext())
        {
            c->setArg2(parseNode(s));
        }
        else
        {
            auto pointer0 = c;
            while (s->getNext())
            {
                auto pointer1 = std::make_shared<Addition>();
                pointer1->setArg1(parseNode(s));
                pointer0->setArg2(pointer1);
                s = s->getNext();
                pointer0 = pointer1;
            }
            pointer0->setArg2(parseNode(s));
        }
        return c;
    }
    else if (node->isType("minus"))
    {
        auto c = std::make_shared<Subtraction>();
        auto s1 = node->getNext();
        c->setArg1(parseNode(s1));
        c->setArg2(parseNode(s1->getNext()));
        return c;
    }
    else if (node->isType("times"))
    {
        auto c = std::make_shared<Multiplication>();
        auto s = node->getNext();
        c->setArg1(parseNode(s));
        s = s->getNext();
        if (!s->getNext())
        {
            c->setArg2(parseNode(s));
        }
        else
        {
            auto pointer0 = c;
            while (s->getNext())
            {
                auto pointer1 = std::make_shared<Multiplication>();
                pointer1->setArg1(parseNode(s));
                pointer0->setArg2(pointer1);
                s = s->getNext();
                pointer0 = pointer1;
            }
            pointer0->setArg2(parseNode(s));
        }
        return c;
    }
    else if (node->isType("divide"))
    {
        auto c = std::make_shared<Division>();
        auto s1 = node->getNext();
        c->setArg1(parseNode(s1));
        c->setArg2(parseNode(s1->getNext()));
        return c;
    }
    else if (node->isType("power"))
    {
        auto c = std::make_shared<Power>();
        auto s1 = node->getNext();
        c->setArg1(parseNode(s1));
        c->setArg2(parseNode(s1->getNext()));
        return c;
    }
    else if (node->isType("sin"))
    {
        auto c = std::make_shared<Sine>();
        c->setArg(parseNode(node->getNext()));
        return c;
    }
    else if (node->isType("cos"))
    {
        auto c = std::make_shared<Cosine>();
        c->setArg(parseNode(node->getNext()));
        return c;
    }
    else if (node->isType("abs"))
    {
        auto c = std::make_shared<AbsoluteValue>();
        c->setArg(parseNode(node->getNext()));
        return c;
    }
    else if (node->isType("ci"))
    {
        auto name = node->getFirstChild()->convertToString();
        auto c = std::make_shared<libcellml::operators::Variable>(name);
        if (name != voi &&
                std::find(states.begin(), states.end(), name) == states.end())
        {
            states.push_back(name);
        }
        return c;
    }
    else if (node->isType("cn"))
    {
        double value;
        std::istringstream iss(node->getFirstChild()->convertToString());
        iss >> value;
        auto c = std::make_shared<Constant>(value);
        return c;
    }
    else
    {
        ErrorPtr err = std::make_shared<Error>();
        err->setDescription("Found node of type "
                + node->getType() +
                " which is currently not supported by the Generator class.");
        addError(err);
        throw UnknownNode();

        return std::make_shared<Constant>(0);
    }
}

std::shared_ptr<Representable> Generator::parseMathML(std::string math)
{
    XmlDocPtr mathDoc = std::make_shared<XmlDoc>();
    mathDoc->parse(math);

    const XmlNodePtr root = mathDoc->getRootNode();

    XmlNodePtr childNode = root->getFirstChild();
    childNode = childNode->getFirstChild();
    childNode = childNode->getNext();
    childNode = childNode->getNext();

    return parseNode(childNode);
}

void Generator::findVOIHelper(XmlNodePtr node)
{
    if (node->isType("bvar"))
    {
        voi = node->getFirstChild()->getFirstChild()->convertToString();
        return;
    }
    else
    {
        if (node->getFirstChild())
        {
            findVOIHelper(node->getFirstChild());
        }
        if (node->getNext())
        {
            findVOIHelper(node->getNext());
        }
    }
}

void Generator::findVOI(std::string math)
{
    XmlDocPtr mathDoc = std::make_shared<XmlDoc>();
    mathDoc->parse(math);

    const XmlNodePtr root = mathDoc->getRootNode();
    XmlNodePtr node = root->getFirstChild();

    findVOIHelper(node);
}

const char * CodeNotGenerated::what () const throw ()
{
    return "No code was generated yet, you should call "
        "Generator::generateCode before calling this method.";
}

const char * UnknownNode::what () const throw ()
{
    return "Found node of unknown type";
}

template std::string Generator::generateCode<CXX>(ModelPtr m);

}
<commit_msg>Adhering to current code rules<commit_after>/*
Copyright libCellML Contributors

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

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

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

#include "libcellml/generator.h"

namespace libcellml{

using namespace libcellml::operators;

const std::unordered_map<CXX::types, std::string, EnumClassHash> CXX::returnTypes = {
    {types::void_t,"void "},
    {types::double_t, "double "},
    {types::double_ct, "const double "},
    {types::double_pt, "double *"},
    {types::double_rt, "double &"}
};

const std::unordered_map<CXX::types, std::string, EnumClassHash> CXX::argTypes = {
    {types::void_t,"void "},
    {types::double_t, "double "},
    {types::double_ct, "const double "},
    {types::double_pt, "double *"},
    {types::double_rt, "double &"},
};

template<typename L>
std::string Generator::generateStateAliases()
{
    std::string s;
    std::ostringstream oss(s);
    for (size_t i = 0; i < states.size(); i++)
    {
        oss << "    "
            << L::argType(L::types::double_rt) << states[i] << " = " << L::dereferenceOp() << "(states + " << i
            << ")" << L::instructionDelimiter() << std::endl;
    }
    oss << std::endl;
    return oss.str();
}

template<typename L>
std::string Generator::generateVoiAlias()
{
    std::string s;
    std::ostringstream oss(s);
    oss << "    "
        << L::argType(L::types::double_ct) << voi << " = voi" << L::instructionDelimiter() << std::endl;
    oss << std::endl;
    return oss.str();
}

template<typename L>
std::string Generator::generateInitConsts()
{
    std::string s;
    std::ostringstream oss(s);
    oss << L::returnType(L::types::void_t) << "initConsts"
        << L::argListOp()
        << L::argType(L::types::double_pt)
        << "constants, "
        << L::argType(L::types::double_pt)
        << "rates, "
        << L::argType(L::types::double_pt)
        << "states"
        << L::argListCl() << std::endl
        << L::funBodyOp() << std::endl;

    oss << generateStateAliases() << std::endl;
    for (auto s : initialValues)
    {
        oss << "    " << s.first << " = "
            << std::setprecision(16) << s.second << L::instructionDelimiter() << std::endl;
    }
    oss << std::endl << L::funBodyCl();
    return oss.str();
}

template<typename L>
std::string Generator::generateComputeRates(std::shared_ptr<Representable> r)
{
    std::string s;
    std::ostringstream oss(s);
    oss << L::returnType(L::types::void_t) << "computeRates"
        << L::argListOp()
        << L::argType(L::types::double_t)
        << "voi, "
        << L::argType(L::types::double_pt)
        << "constants, "
        << L::argType(L::types::double_pt)
        << "rates, "
        << L::argType(L::types::double_pt)
        << "states, "
        << L::argType(L::types::double_pt)
        << "algebraic"
        << L::argListCl() << std::endl
        << L::funBodyOp() << std::endl;

    oss << generateVoiAlias() << std::endl;
    oss << generateStateAliases() << std::endl;

    oss << "    rates[0] = "
        << r->repr() << ";" << std::endl;

    oss << std::endl
        << L::funBodyCl();
    return oss.str();
}

template<typename L>
std::string Generator::generateComputeVariables()
{
    std::string s;
    std::ostringstream oss(s);
    oss << L::returnType(L::types::void_t) << "computeVariables"
        << L::argListOp()
        << L::argType(L::types::double_t)
        << "voi, "
        << L::argType(L::types::double_pt)
        << "constants, "
        << L::argType(L::types::double_pt)
        << "rates, "
        << L::argType(L::types::double_pt)
        << "states, "
        << L::argType(L::types::double_pt)
        << "algebraic"
        << L::argListCl()  << std::endl
        << L::funBodyOp() << std::endl
        << L::funBodyCl();
    return oss.str();
}

void Generator::findInitialValues(ComponentPtr c)
{
    for (std::size_t i = 0; i < c->variableCount(); i++)
    {
        auto v = c->getVariable(i);
        if (v->getName() != voi)
        {
            initialValues[v->getName()] = std::stod(v->getInitialValue());
        }
    }
}

template<typename L>
std::string Generator::generateCode(ModelPtr m)
{
    ComponentPtr c = m->getComponent(0);

    findVOI(c->getMath());
    findInitialValues(c);
    auto r = parseMathML(c->getMath());

    std::string generatedCode;
    std::ostringstream oss(generatedCode);
    oss << generateInitConsts<L>() << std::endl;
    oss << generateComputeRates<L>(r) << std::endl;
    oss << generateComputeVariables<L>() << std::endl;

    code = oss.str();
    return code;
}

void Generator::writeCodeToFile(std::string filename)
{
    if (code == "")
    {
        ErrorPtr err = std::make_shared<Error>();
        err->setDescription("No code was generated yet, you should call "
                "Generator::generateCode before calling this method.");
        addError(err);
        throw CodeNotGenerated();
    }

    std::ofstream output(filename);
    output << code;
    output.close();
}

std::shared_ptr<Representable> Generator::parseNode(XmlNodePtr node)
{
    if (node->isType("apply"))
    {
        return parseNode(node->getFirstChild());
    }
    else if (node->isType("plus"))
    {
        auto c = std::make_shared<Addition>();
        auto s = node->getNext();
        c->setArg1(parseNode(s));
        s = s->getNext();
        if (!s->getNext())
        {
            c->setArg2(parseNode(s));
        }
        else
        {
            auto pointer0 = c;
            while (s->getNext())
            {
                auto pointer1 = std::make_shared<Addition>();
                pointer1->setArg1(parseNode(s));
                pointer0->setArg2(pointer1);
                s = s->getNext();
                pointer0 = pointer1;
            }
            pointer0->setArg2(parseNode(s));
        }
        return c;
    }
    else if (node->isType("minus"))
    {
        auto c = std::make_shared<Subtraction>();
        auto s1 = node->getNext();
        c->setArg1(parseNode(s1));
        c->setArg2(parseNode(s1->getNext()));
        return c;
    }
    else if (node->isType("times"))
    {
        auto c = std::make_shared<Multiplication>();
        auto s = node->getNext();
        c->setArg1(parseNode(s));
        s = s->getNext();
        if (!s->getNext())
        {
            c->setArg2(parseNode(s));
        }
        else
        {
            auto pointer0 = c;
            while (s->getNext())
            {
                auto pointer1 = std::make_shared<Multiplication>();
                pointer1->setArg1(parseNode(s));
                pointer0->setArg2(pointer1);
                s = s->getNext();
                pointer0 = pointer1;
            }
            pointer0->setArg2(parseNode(s));
        }
        return c;
    }
    else if (node->isType("divide"))
    {
        auto c = std::make_shared<Division>();
        auto s1 = node->getNext();
        c->setArg1(parseNode(s1));
        c->setArg2(parseNode(s1->getNext()));
        return c;
    }
    else if (node->isType("power"))
    {
        auto c = std::make_shared<Power>();
        auto s1 = node->getNext();
        c->setArg1(parseNode(s1));
        c->setArg2(parseNode(s1->getNext()));
        return c;
    }
    else if (node->isType("sin"))
    {
        auto c = std::make_shared<Sine>();
        c->setArg(parseNode(node->getNext()));
        return c;
    }
    else if (node->isType("cos"))
    {
        auto c = std::make_shared<Cosine>();
        c->setArg(parseNode(node->getNext()));
        return c;
    }
    else if (node->isType("abs"))
    {
        auto c = std::make_shared<AbsoluteValue>();
        c->setArg(parseNode(node->getNext()));
        return c;
    }
    else if (node->isType("ci"))
    {
        auto name = node->getFirstChild()->convertToString();
        auto c = std::make_shared<libcellml::operators::Variable>(name);
        if (name != voi &&
                std::find(states.begin(), states.end(), name) == states.end())
        {
            states.push_back(name);
        }
        return c;
    }
    else if (node->isType("cn"))
    {
        double value;
        std::istringstream iss(node->getFirstChild()->convertToString());
        iss >> value;
        auto c = std::make_shared<Constant>(value);
        return c;
    }
    else
    {
        ErrorPtr err = std::make_shared<Error>();
        err->setDescription("Found node of type "
                + node->getType() +
                " which is currently not supported by the Generator class.");
        addError(err);
        throw UnknownNode();

        return std::make_shared<Constant>(0);
    }
}

std::shared_ptr<Representable> Generator::parseMathML(std::string math)
{
    XmlDocPtr mathDoc = std::make_shared<XmlDoc>();
    mathDoc->parse(math);

    const XmlNodePtr root = mathDoc->getRootNode();

    XmlNodePtr childNode = root->getFirstChild();
    childNode = childNode->getFirstChild();
    childNode = childNode->getNext();
    childNode = childNode->getNext();

    return parseNode(childNode);
}

void Generator::findVOIHelper(XmlNodePtr node)
{
    if (node->isType("bvar"))
    {
        voi = node->getFirstChild()->getFirstChild()->convertToString();
        return;
    }
    else
    {
        if (node->getFirstChild())
        {
            findVOIHelper(node->getFirstChild());
        }
        if (node->getNext())
        {
            findVOIHelper(node->getNext());
        }
    }
}

void Generator::findVOI(std::string math)
{
    XmlDocPtr mathDoc = std::make_shared<XmlDoc>();
    mathDoc->parse(math);

    const XmlNodePtr root = mathDoc->getRootNode();
    XmlNodePtr node = root->getFirstChild();

    findVOIHelper(node);
}

const char * CodeNotGenerated::what () const throw ()
{
    return "No code was generated yet, you should call "
        "Generator::generateCode before calling this method.";
}

const char * UnknownNode::what () const throw ()
{
    return "Found node of unknown type";
}

template std::string Generator::generateCode<CXX>(ModelPtr m);

}
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   https://github.com/dune-community/dune-gdt
// Copyright 2010-2018 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
//          with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
//   Felix Schindler (2015 - 2017)
//   Rene Milk       (2016)

#ifndef DUNE_GDT_DISCRETEFUNCTION_REINTERPRET_HH
#define DUNE_GDT_DISCRETEFUNCTION_REINTERPRET_HH

#include <dune/xt/grid/type_traits.hh>
#include <dune/xt/functions/reinterpret.hh>

#include "default.hh"

namespace Dune {
namespace GDT {

/**
 * \sa XT::Functions::ReinterpretLocalizableFunction
 * \sa XT::Functions::reinterpret
 */
template <class TargetElement, class SGV, size_t r, size_t rC, class R, class V>
XT::Functions::ReinterpretLocalizableFunction<SGV, TargetElement, r, rC, R>
reinterpret(const DiscreteFunction<V, SGV, r, rC, R>& source)
{
  return XT::Functions::ReinterpretLocalizableFunction<SGV, TargetElement, r, rC, R>(source,
                                                                                source.space().grid_view());
}

/**
 * \sa XT::Functions::ReinterpretLocalizableFunction
 * \sa XT::Functions::reinterpret
 */
template <class SGV, size_t r, size_t rC, class R, class V, class TargetGridView>
std::enable_if_t<XT::Grid::is_layer<TargetGridView>::value,
                 XT::Functions::
                     ReinterpretLocalizableFunction<SGV, XT::Grid::extract_entity_t<TargetGridView>, r, rC, R>>
reinterpret(const DiscreteFunction<V, SGV, r, rC, R>& source, const TargetGridView& /*target_grid_view*/)
{
  return XT::Functions::ReinterpretLocalizableFunction<SGV, XT::Grid::extract_entity_t<TargetGridView>, r, rC, R>(
      source, source.space().grid_view());
}

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_DISCRETEFUNCTION_REINTERPRET_HH
<commit_msg>[discretefunction.reinterpret] fix include<commit_after>// This file is part of the dune-gdt project:
//   https://github.com/dune-community/dune-gdt
// Copyright 2010-2018 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
//          with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
//   Felix Schindler (2015 - 2017)
//   Rene Milk       (2016)

#ifndef DUNE_GDT_DISCRETEFUNCTION_REINTERPRET_HH
#define DUNE_GDT_DISCRETEFUNCTION_REINTERPRET_HH

#include <dune/xt/grid/type_traits.hh>
#include <dune/xt/functions/base/reinterpret.hh>

#include "default.hh"

namespace Dune {
namespace GDT {

/**
 * \sa XT::Functions::ReinterpretLocalizableFunction
 * \sa XT::Functions::reinterpret
 */
template <class TargetElement, class SGV, size_t r, size_t rC, class R, class V>
XT::Functions::ReinterpretLocalizableFunction<SGV, TargetElement, r, rC, R>
reinterpret(const DiscreteFunction<V, SGV, r, rC, R>& source)
{
  return XT::Functions::ReinterpretLocalizableFunction<SGV, TargetElement, r, rC, R>(source,
                                                                                source.space().grid_view());
}

/**
 * \sa XT::Functions::ReinterpretLocalizableFunction
 * \sa XT::Functions::reinterpret
 */
template <class SGV, size_t r, size_t rC, class R, class V, class TargetGridView>
std::enable_if_t<XT::Grid::is_layer<TargetGridView>::value,
                 XT::Functions::
                     ReinterpretLocalizableFunction<SGV, XT::Grid::extract_entity_t<TargetGridView>, r, rC, R>>
reinterpret(const DiscreteFunction<V, SGV, r, rC, R>& source, const TargetGridView& /*target_grid_view*/)
{
  return XT::Functions::ReinterpretLocalizableFunction<SGV, XT::Grid::extract_entity_t<TargetGridView>, r, rC, R>(
      source, source.space().grid_view());
}

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_DISCRETEFUNCTION_REINTERPRET_HH
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   https://github.com/dune-community/dune-gdt
// Copyright 2010-2018 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
//          with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
//   Felix Schindler (2019)

#ifndef DUNE_GDT_TOOLS_GRID_QUALITY_ESTIMATES_HH
#define DUNE_GDT_TOOLS_GRID_QUALITY_ESTIMATES_HH

#include <limits>
#include <vector>

#include <dune/grid/common/rangegenerators.hh>

#include <dune/xt/common/exceptions.hh>
#include <dune/xt/la/container/common.hh>
#include <dune/xt/la/container/conversion.hh>
#include <dune/xt/la/generalized-eigen-solver.hh>
#include <dune/xt/grid/entity.hh>
#include <dune/xt/grid/intersection.hh>
#include <dune/xt/grid/type_traits.hh>

#include <dune/gdt/local/bilinear-forms/integrals.hh>
#include <dune/gdt/local/integrands/laplace.hh>
#include <dune/gdt/local/integrands/product.hh>
#include <dune/gdt/spaces/interface.hh>

namespace Dune {
namespace GDT {

template <class GV, size_t r>
double estimate_inverse_inequality_constant(const SpaceInterface<GV, r>& space)
{
  DUNE_THROW_IF(!XT::Common::Lapacke::available(), XT::Common::Exceptions::dependency_missing, "lapacke");
  using E = XT::Grid::extract_entity_t<GV>;
  double result = std::numeric_limits<double>::min();
  auto basis = space.basis().localize();
  for (auto&& element : elements(space.grid_view())) {
    basis->bind(element);
    const double h = XT::Grid::diameter(element);
    auto H1_product_matrix = XT::LA::convert_to<XT::LA::CommonDenseMatrix<double>>(
        LocalElementIntegralBilinearForm<E, r>(LocalLaplaceIntegrand<E, r>()).apply2(*basis, *basis));
    auto L2_product_matrix = XT::LA::convert_to<XT::LA::CommonDenseMatrix<double>>(
        LocalElementIntegralBilinearForm<E, r>(LocalElementProductIntegrand<E, r>()).apply2(*basis, *basis));
    auto evs =
        XT::LA::make_generalized_eigen_solver(H1_product_matrix,
                                              L2_product_matrix,
                                              {{"type", XT::LA::generalized_eigen_solver_types(H1_product_matrix)[0]},
                                               {"compute_eigenvectors", "false"},
                                               {"assert_real_eigenvalues", "1e-15"}})
            .real_eigenvalues();
    double min_ev = std::numeric_limits<double>::max();
    for (auto&& ev : evs)
      if (std::abs(ev) > 1e-7) // TODO: find a better tolerance here!
        min_ev = std::min(min_ev, ev);
    // the smalles nonzero eigenvalue is (C_I / h)^2
    result = std::max(result, h * std::sqrt(min_ev));
  }
  return result;
} // ... estimate_inverse_inequality_constant(...)

template <class GV, size_t r>
double estimate_combined_inverse_trace_inequality_constant(const SpaceInterface<GV, r>& space)
{
  DUNE_THROW_IF(!XT::Common::Lapacke::available(), XT::Common::Exceptions::dependency_missing, "lapacke");
  using E = XT::Grid::extract_entity_t<GV>;
  using I = XT::Grid::extract_intersection_t<GV>;
  double result = std::numeric_limits<double>::min();
  auto basis = space.basis().localize();
  for (auto&& element : elements(space.grid_view())) {
    basis->bind(element);
    const double h = XT::Grid::diameter(element);
    XT::LA::CommonDenseMatrix<double> L2_face_product_matrix(basis->size(), basis->size(), 0.);
    DynamicMatrix<double> tmp_L2_face_product_matrix(basis->size(), basis->size(), 0.);
    for (auto&& intersection : intersections(space.grid_view(), element)) {
      LocalIntersectionIntegralBilinearForm<I, r>(LocalIntersectionProductIntegrand<I, r>(1.))
          .apply2(intersection, *basis, *basis, tmp_L2_face_product_matrix);
      for (size_t ii = 0; ii < basis->size(); ++ii)
        for (size_t jj = 0; jj < basis->size(); ++jj)
          L2_face_product_matrix.add_to_entry(ii, jj, tmp_L2_face_product_matrix[ii][jj]);
    }
    auto L2_element_product_matrix = XT::LA::convert_to<XT::LA::CommonDenseMatrix<double>>(
        LocalElementIntegralBilinearForm<E, r>(LocalElementProductIntegrand<E, r>(1.)).apply2(*basis, *basis));
    auto evs = XT::LA::make_generalized_eigen_solver(
                   L2_face_product_matrix,
                   L2_element_product_matrix,
                   {{"type", XT::LA::generalized_eigen_solver_types(L2_face_product_matrix)[0]},
                    {"compute_eigenvectors", "false"},
                    {"assert_real_eigenvalues", "1e-15"}})
                   .real_eigenvalues();
    double min_ev = std::numeric_limits<double>::max();
    for (auto&& ev : evs)
      if (std::abs(ev) > 1e-7) // TODO: find a better tolerance here!
        min_ev = std::min(min_ev, ev);
    // the smalles nonzero eigenvalue is (C_M (1 + C_I)) / h
    result = std::max(result, h * min_ev);
  }
  return result;
} // ... estimate_combined_inverse_trace_inequality_constant(...)

template <class GV>
double estimate_element_to_intersection_equivalence_constant(
    const GridView<GV>& grid_view,
    const std::function<double(const XT::Grid::extract_intersection_t<GridView<GV>>&)>& intersection_diameter =
        [](const auto& intersection) {
          if (GridView<GV>::dimension == 1) {
            if (intersection.neighbor())
              return 0.5 * (XT::Grid::diameter(intersection.inside()) + XT::Grid::diameter(intersection.outside()));
            else
              return XT::Grid::diameter(intersection.inside());
          } else
            return XT::Grid::diameter(intersection);
        })
{
  auto result = std::numeric_limits<double>::min();
  for (auto&& element : elements(grid_view)) {
    const double h = XT::Grid::diameter(element);
    for (auto&& intersection : intersections(grid_view, element))
      result = std::max(result, intersection_diameter(intersection) / h);
    return result;
  }
} // ... estimate_element_to_intersection_equivalence_constant(...)

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_TOOLS_GRID_QUALITY_ESTIMATES_HH
<commit_msg>[tools] fix too early return<commit_after>// This file is part of the dune-gdt project:
//   https://github.com/dune-community/dune-gdt
// Copyright 2010-2018 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
//          with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
//   Felix Schindler (2019)

#ifndef DUNE_GDT_TOOLS_GRID_QUALITY_ESTIMATES_HH
#define DUNE_GDT_TOOLS_GRID_QUALITY_ESTIMATES_HH

#include <limits>
#include <vector>

#include <dune/grid/common/rangegenerators.hh>

#include <dune/xt/common/exceptions.hh>
#include <dune/xt/la/container/common.hh>
#include <dune/xt/la/container/conversion.hh>
#include <dune/xt/la/generalized-eigen-solver.hh>
#include <dune/xt/grid/entity.hh>
#include <dune/xt/grid/intersection.hh>
#include <dune/xt/grid/type_traits.hh>

#include <dune/gdt/local/bilinear-forms/integrals.hh>
#include <dune/gdt/local/integrands/laplace.hh>
#include <dune/gdt/local/integrands/product.hh>
#include <dune/gdt/spaces/interface.hh>

namespace Dune {
namespace GDT {

template <class GV, size_t r>
double estimate_inverse_inequality_constant(const SpaceInterface<GV, r>& space)
{
  DUNE_THROW_IF(!XT::Common::Lapacke::available(), XT::Common::Exceptions::dependency_missing, "lapacke");
  using E = XT::Grid::extract_entity_t<GV>;
  double result = std::numeric_limits<double>::min();
  auto basis = space.basis().localize();
  for (auto&& element : elements(space.grid_view())) {
    basis->bind(element);
    const double h = XT::Grid::diameter(element);
    auto H1_product_matrix = XT::LA::convert_to<XT::LA::CommonDenseMatrix<double>>(
        LocalElementIntegralBilinearForm<E, r>(LocalLaplaceIntegrand<E, r>()).apply2(*basis, *basis));
    auto L2_product_matrix = XT::LA::convert_to<XT::LA::CommonDenseMatrix<double>>(
        LocalElementIntegralBilinearForm<E, r>(LocalElementProductIntegrand<E, r>()).apply2(*basis, *basis));
    auto evs =
        XT::LA::make_generalized_eigen_solver(H1_product_matrix,
                                              L2_product_matrix,
                                              {{"type", XT::LA::generalized_eigen_solver_types(H1_product_matrix)[0]},
                                               {"compute_eigenvectors", "false"},
                                               {"assert_real_eigenvalues", "1e-15"}})
            .real_eigenvalues();
    double min_ev = std::numeric_limits<double>::max();
    for (auto&& ev : evs)
      if (std::abs(ev) > 1e-7) // TODO: find a better tolerance here!
        min_ev = std::min(min_ev, ev);
    // the smalles nonzero eigenvalue is (C_I / h)^2
    result = std::max(result, h * std::sqrt(min_ev));
  }
  return result;
} // ... estimate_inverse_inequality_constant(...)

template <class GV, size_t r>
double estimate_combined_inverse_trace_inequality_constant(const SpaceInterface<GV, r>& space)
{
  DUNE_THROW_IF(!XT::Common::Lapacke::available(), XT::Common::Exceptions::dependency_missing, "lapacke");
  using E = XT::Grid::extract_entity_t<GV>;
  using I = XT::Grid::extract_intersection_t<GV>;
  double result = std::numeric_limits<double>::min();
  auto basis = space.basis().localize();
  for (auto&& element : elements(space.grid_view())) {
    basis->bind(element);
    const double h = XT::Grid::diameter(element);
    XT::LA::CommonDenseMatrix<double> L2_face_product_matrix(basis->size(), basis->size(), 0.);
    DynamicMatrix<double> tmp_L2_face_product_matrix(basis->size(), basis->size(), 0.);
    for (auto&& intersection : intersections(space.grid_view(), element)) {
      LocalIntersectionIntegralBilinearForm<I, r>(LocalIntersectionProductIntegrand<I, r>(1.))
          .apply2(intersection, *basis, *basis, tmp_L2_face_product_matrix);
      for (size_t ii = 0; ii < basis->size(); ++ii)
        for (size_t jj = 0; jj < basis->size(); ++jj)
          L2_face_product_matrix.add_to_entry(ii, jj, tmp_L2_face_product_matrix[ii][jj]);
    }
    auto L2_element_product_matrix = XT::LA::convert_to<XT::LA::CommonDenseMatrix<double>>(
        LocalElementIntegralBilinearForm<E, r>(LocalElementProductIntegrand<E, r>(1.)).apply2(*basis, *basis));
    auto evs = XT::LA::make_generalized_eigen_solver(
                   L2_face_product_matrix,
                   L2_element_product_matrix,
                   {{"type", XT::LA::generalized_eigen_solver_types(L2_face_product_matrix)[0]},
                    {"compute_eigenvectors", "false"},
                    {"assert_real_eigenvalues", "1e-15"}})
                   .real_eigenvalues();
    double min_ev = std::numeric_limits<double>::max();
    for (auto&& ev : evs)
      if (std::abs(ev) > 1e-7) // TODO: find a better tolerance here!
        min_ev = std::min(min_ev, ev);
    // the smalles nonzero eigenvalue is (C_M (1 + C_I)) / h
    result = std::max(result, h * min_ev);
  }
  return result;
} // ... estimate_combined_inverse_trace_inequality_constant(...)

template <class GV>
double estimate_element_to_intersection_equivalence_constant(
    const GridView<GV>& grid_view,
    const std::function<double(const XT::Grid::extract_intersection_t<GridView<GV>>&)>& intersection_diameter =
        [](const auto& intersection) {
          if (GridView<GV>::dimension == 1) {
            if (intersection.neighbor())
              return 0.5 * (XT::Grid::diameter(intersection.inside()) + XT::Grid::diameter(intersection.outside()));
            else
              return XT::Grid::diameter(intersection.inside());
          } else
            return XT::Grid::diameter(intersection);
        })
{
  auto result = std::numeric_limits<double>::min();
  for (auto&& element : elements(grid_view)) {
    const double h = XT::Grid::diameter(element);
    for (auto&& intersection : intersections(grid_view, element))
      result = std::max(result, intersection_diameter(intersection) / h);
  }
  return result;
} // ... estimate_element_to_intersection_equivalence_constant(...)

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_TOOLS_GRID_QUALITY_ESTIMATES_HH
<|endoftext|>


<commit_before><commit_msg>Fixed an infinite loop when the paste destination has only one sheet.<commit_after><|endoftext|>


<commit_before>#include <iostream>
#include <cstdio>
#include <algorithm>
#include <utility>
#include <string>
#include <vector>
#include <cmath>
#include <set>
#include <stack>
#include <queue>
#include <map>
#include <sstream>
#include <ctime>
#include <numeric>
#include <cstring>
#include <functional>

using namespace std;

typedef vector<int> VI;
typedef pair<int, int> PII;
typedef vector<PII> VPII;
typedef vector<string> VS;
typedef map<string, int> MSI;
typedef long long int LL;
typedef unsigned long long int ULL;

#define REP(i, n) for (int i = 0; i < n; ++i)
#define FOR(i, a, b) for (int i = a; i < b; ++i)
#define FORD(i, a, b) for (int i = a-1; i >= b; --i)
#define ALL(x) x.begin(), x.end()
#define SIZE(x) (int)x.size()
#define FOREACH(it, c) for (__typeof(c.begin()) it = c.begin(); it != c.end(); ++it)
#define INF 1023456789
#define PB push_back
#define MP make_pair
#define DEBUG(x) cerr<<#x<<": "<<x<<endl;
#define ERR(...) fprintf(stderr, __VA_ARGS__);
#define EPS 1e-9

int main(void) {
    srand(time(NULL));
    cout << rand()%2134 << endl;
    double first = 1.4;
    DEBUG(first);

    return 0;
}

----------Extended GCD algorithm----------
struct ans {
    int x, y, gcd;
};

//To find an inverse of a mod n, a must be coprime with n and we sould run
//extGcd(a, n) and take the x value of the result - this is the inverse
//a * x + b * y = gcd(a,b)
ans extGcd(int a, int b) {
    //PRE: a > b ??? seems to work without it
    ans res;
    if (b == 0) {res.x=1; res.y=0; res.gcd=a;}
    else {
	ans prev = extGcd(b, a % b);
	res.x = prev.y; res.y = prev.x - (a / b) * prev.y; res.gcd = prev.gcd;
    }
    return res;
}

----------Online LCA O(n log n)----------
#include <vector>
#include <algorithm>

using namespace std;

#define MAX_N 1001
#define MAX_LOG 10

struct interval {
    int in, out;
};

vector<int> graph[MAX_N];
int pred[MAX_N][MAX_LOG];
int depth[MAX_N];
interval processTimes[MAX_N];
int n; //number of vertices in the tree

int dfs(int v, int time) {
    processTimes[v].in = ++time;
    for (int i=0; i<graph[v].size(); i++) {
	int cand = graph[v][i];
	if (depth[cand] == -1) {
	    depth[cand] = depth[v] + 1;
	    pred[cand][0] = v;
	    time = dfs(cand, time);
	}
    }
    processTimes[v].out = ++time;
    return time;
}

void calcPredTable(void) {
    int maxDepth = 0;
    for (int i=1; i<=n; i++) maxDepth = max(depth[i], maxDepth);
    for (int dist=2, j=1; dist <= maxDepth; j++, dist*=2) {
	for (int i=1; i<=n; i++) pred[i][j] = pred[pred[i][j-1]][j-1];
    }
}

void preprocess(int root) {
    for (int i=1; i<=n; i++) depth[i] = -1;
    depth[root] = 0; pred[root][0] = 0;
    dfs(root, 0);
    calcPredTable();
}

bool contains(interval a, interval b) {
    return (a.in < b.in && a.out > b.out);
}

int reachDepth(int v, int d) {
    if (depth[v] == d) return v;
    int i=0;
    while (depth[pred[v][i+1]] >= d) i++;
    return reachDepth(pred[v][i], d);
}

int lca(int va, int vb) {
    if (va == vb || contains(processTimes[va], processTimes[vb])) return va;
    if (contains(processTimes[vb], processTimes[va])) return vb;
    if (depth[va] > depth[vb]) va = reachDepth(va, depth[vb]);
    if (depth[va] < depth[vb]) vb = reachDepth(vb, depth[va]);
    while(va != vb) {
	int i=0;
	for (; pred[va][i+1] != pred[vb][i+1]; i++)
	    ;
	va = pred[va][i]; vb = pred[vb][i];
    }
    return va;
}

----------Maximum Flow in a directed graph (derivation of the Dinic's method)
O(n^4) with a VERY small const----------

#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

#define MAX_N 5001
const int inf = 2000000000;

int begin[MAX_N];
int dist[MAX_N];
vector<int> graph[MAX_N];
int c[MAX_N][MAX_N];
bool vis[MAX_N];
queue<int> q;

void bfsIn(int v) {
    for (int i=0; i<graph[v].size(); i++) {
	int cand = graph[v][i];
	if (!vis[cand] && c[v][cand] > 0) {
	    vis[cand] = true; dist[cand] = dist[v] + 1;
	    q.push(cand);
	}
    }
}

bool bfs(int s, int t) {
    for (int i=s+1; i<=t; i++) {
	dist[i] = 0; vis[i] = false;
    }
    vis[s]=true; dist[s]=0; q.push(s);
    while(!q.empty()) {
	int v = q.front(); q.pop();
	bfsIn(v);
    }
    return vis[t];
}

int dfs(int v, int t, int min_cap) {
    int res = 0;
    if (v == t || min_cap == 0) return min_cap;
    for (int& i=begin[v]; i<graph[v].size(); i++) {
	int cand = graph[v][i];
	if (dist[cand] == dist[v]+1 && c[v][cand] > 0) {
	    int newFlow = dfs(cand, t, min(min_cap, c[v][cand]));
	    c[v][cand] -= newFlow;
	    c[cand][v] += newFlow;
	    min_cap -= newFlow;
	    res += newFlow;
	    if (min_cap == 0) break;
	}
    }
    return res;
}

int maxFlow(int s, int t) {
    long long result = 0;
    while (bfs(s,t)) {
        for (int i=s; i<=t; i++) begin[i] = 0;
        int init_cap = inf;
	result += dfs(s,t,init_cap);
    }
    return result;
}

----------Maximum matching in the bipartite graph O(n^2.5)----------
#include <algorithm>
using namespace std;
#define MAX_X 201
#define MAX_Y 401

vector<int> graph[MAX_X];
bool vis[MAX_X];
int matchX[MAX_X];
int matchY[MAX_Y];
int sizeX, sizeY;

int dfs(int x) {
    vis[x] = true;
    for (int i=0; i<graph[x].size(); i++) {
	int y = graph[x][i];
	if (matchY[y] == -1 || (!vis[matchY[y]] && dfs(matchY[y]))) {
	    matchY[y] = x;
	    matchX[x] = y;
	    return 1;
	}
    }
    return 0;
}

int maxMatching(void) {
    for (int i=1; i<=sizeX; i++) random_shuffle(graph[i].begin(), graph[i].end());
    for (int i=1; i<=sizeX; i++) matchX[i] = -1;
    for (int i=1; i<=sizeY; i++) matchY[i] = -1;
    int res = 0; bool change = true;
    while(change) {
	change = false;
	for (int i=1; i<=sizeX; i++) vis[i] = false;
	for (int i=1; i<=sizeX; i++) {
	    if (matchX[i] == -1 && !vis[i] && dfs(i)) {
		res++; change = true;
	    }
	}
    }
    return res;
}

----------KMP O(n + m)-------------
#include<string>
#include<cstdio>

#define MAX_M 1001

int prefixes[MAX_M];
std::string t, p;

//compute longest prefixes of P which are proper suffixes of P_q
int prefix() {
    prefixes[1] = 0;
    int k = 0;
    for(int q = 2; q <= p.length(); q++) {
        while (k > 0 && p[k] != p[q-1]) k = prefixes[k];
        if (p[k] == p[q-1]) k++;
        prefixes[q] = k;
    }
}
//print out shifts for which pattern occurs in target
void kmp(){
    prefix();
    int q = 0;
    for (int i = 1; i <= t.length(); i++) {
        while(q > 0 && p[q] != t[i-1]) q = prefixes[q];
        if (p[q] == t[i-1]) q++;
        if (q == p.length()) {
            printf("valid shift: %d\n", i - (int) p.length()); q = prefixes[q];
        }
    }
}

<commit_msg>Added implementation of KMP<commit_after>#include <iostream>
#include <cstdio>
#include <algorithm>
#include <utility>
#include <string>
#include <vector>
#include <cmath>
#include <set>
#include <stack>
#include <queue>
#include <map>
#include <sstream>
#include <ctime>
#include <numeric>
#include <cstring>
#include <functional>

using namespace std;

typedef vector<int> VI;
typedef pair<int, int> PII;
typedef vector<PII> VPII;
typedef vector<string> VS;
typedef map<string, int> MSI;
typedef long long int LL;
typedef unsigned long long int ULL;

#define REP(i, n) for (int i = 0; i < n; ++i)
#define FOR(i, a, b) for (int i = a; i < b; ++i)
#define FORD(i, a, b) for (int i = a-1; i >= b; --i)
#define ALL(x) x.begin(), x.end()
#define SIZE(x) (int)x.size()
#define FOREACH(it, c) for (__typeof(c.begin()) it = c.begin(); it != c.end(); ++it)
#define INF 1023456789
#define PB push_back
#define MP make_pair
#define DEBUG(x) cerr<<#x<<": "<<x<<endl;
#define ERR(...) fprintf(stderr, __VA_ARGS__);
#define EPS 1e-9

int main(void) {
    srand(time(NULL));
    cout << rand()%2134 << endl;
    double first = 1.4;
    DEBUG(first);

    return 0;
}

----------Extended GCD algorithm----------
struct ans {
    int x, y, gcd;
};

//To find an inverse of a mod n, a must be coprime with n and we sould run
//extGcd(a, n) and take the x value of the result - this is the inverse
//a * x + b * y = gcd(a,b)
ans extGcd(int a, int b) {
    //PRE: a > b ??? seems to work without it
    ans res;
    if (b == 0) {res.x=1; res.y=0; res.gcd=a;}
    else {
	ans prev = extGcd(b, a % b);
	res.x = prev.y; res.y = prev.x - (a / b) * prev.y; res.gcd = prev.gcd;
    }
    return res;
}

----------Union Find algorithm with the heuristics(path compression and joining
according to rank) O(m alpha(n))----------
#define MAX_N 10001
int rank[MAX_N];//upper bound on the length of the path from the root to a leaf
int rep[MAX_N];

void makeSet(int x) {
    rank[x] = 0;
    rep[x] = x;
}

int findSet(int x) {
    if (x != rep[x]) rep[x] = findSet(rep[x]); //path compression
    return rep[x];
}

void link(int x, int y) {
    if (rank[x] > rank[y]) rep[y] = x;//join according to rang
    else {
	if (rank[x] == rank[y]) rank[y]++;
	rep[x] = y;
    }
}

void unionSet(int x, int y) {
    link(findSet(x), findSet(y));
}

----------Online LCA O(n log n)----------
#include <vector>
#include <algorithm>

using namespace std;

#define MAX_N 1001
#define MAX_LOG 10

struct interval {
    int in, out;
};

vector<int> graph[MAX_N];
int pred[MAX_N][MAX_LOG];
int depth[MAX_N];
interval processTimes[MAX_N];
int n; //number of vertices in the tree

int dfs(int v, int time) {
    processTimes[v].in = ++time;
    for (int i=0; i<graph[v].size(); i++) {
	int cand = graph[v][i];
	if (depth[cand] == -1) {
	    depth[cand] = depth[v] + 1;
	    pred[cand][0] = v;
	    time = dfs(cand, time);
	}
    }
    processTimes[v].out = ++time;
    return time;
}

void calcPredTable(void) {
    int maxDepth = 0;
    for (int i=1; i<=n; i++) maxDepth = max(depth[i], maxDepth);
    for (int dist=2, j=1; dist <= maxDepth; j++, dist*=2) {
	for (int i=1; i<=n; i++) pred[i][j] = pred[pred[i][j-1]][j-1];
    }
}

void preprocess(int root) {
    for (int i=1; i<=n; i++) depth[i] = -1;
    depth[root] = 0; pred[root][0] = 0;
    dfs(root, 0);
    calcPredTable();
}

bool contains(interval a, interval b) {
    return (a.in < b.in && a.out > b.out);
}

int reachDepth(int v, int d) {
    if (depth[v] == d) return v;
    int i=0;
    while (depth[pred[v][i+1]] >= d) i++;
    return reachDepth(pred[v][i], d);
}

int lca(int va, int vb) {
    if (va == vb || contains(processTimes[va], processTimes[vb])) return va;
    if (contains(processTimes[vb], processTimes[va])) return vb;
    if (depth[va] > depth[vb]) va = reachDepth(va, depth[vb]);
    if (depth[va] < depth[vb]) vb = reachDepth(vb, depth[va]);
    while(va != vb) {
	int i=0;
	for (; pred[va][i+1] != pred[vb][i+1]; i++)
	    ;
	va = pred[va][i]; vb = pred[vb][i];
    }
    return va;
}

----------Maximum Flow in a directed graph (derivation of the Dinic's method)
O(n^4) with a VERY small const----------

#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

#define MAX_N 5001
const int inf = 2000000000;

int begin[MAX_N];
int dist[MAX_N];
vector<int> graph[MAX_N];
int c[MAX_N][MAX_N];
bool vis[MAX_N];
queue<int> q;

void bfsIn(int v) {
    for (int i=0; i<graph[v].size(); i++) {
	int cand = graph[v][i];
	if (!vis[cand] && c[v][cand] > 0) {
	    vis[cand] = true; dist[cand] = dist[v] + 1;
	    q.push(cand);
	}
    }
}

bool bfs(int s, int t) {
    for (int i=s+1; i<=t; i++) {
	dist[i] = 0; vis[i] = false;
    }
    vis[s]=true; dist[s]=0; q.push(s);
    while(!q.empty()) {
	int v = q.front(); q.pop();
	bfsIn(v);
    }
    return vis[t];
}

int dfs(int v, int t, int min_cap) {
    int res = 0;
    if (v == t || min_cap == 0) return min_cap;
    for (int& i=begin[v]; i<graph[v].size(); i++) {
	int cand = graph[v][i];
	if (dist[cand] == dist[v]+1 && c[v][cand] > 0) {
	    int newFlow = dfs(cand, t, min(min_cap, c[v][cand]));
	    c[v][cand] -= newFlow;
	    c[cand][v] += newFlow;
	    min_cap -= newFlow;
	    res += newFlow;
	    if (min_cap == 0) break;
	}
    }
    return res;
}

int maxFlow(int s, int t) {
    long long result = 0;
    while (bfs(s,t)) {
        for (int i=s; i<=t; i++) begin[i] = 0;
        int init_cap = inf;
	result += dfs(s,t,init_cap);
    }
    return result;
}

----------Maximum matching in the bipartite graph O(n^2.5)----------
#include <algorithm>
using namespace std;
#define MAX_X 201
#define MAX_Y 401

vector<int> graph[MAX_X];
bool vis[MAX_X];
int matchX[MAX_X];
int matchY[MAX_Y];
int sizeX, sizeY;

int dfs(int x) {
    vis[x] = true;
    for (int i=0; i<graph[x].size(); i++) {
	int y = graph[x][i];
	if (matchY[y] == -1 || (!vis[matchY[y]] && dfs(matchY[y]))) {
	    matchY[y] = x;
	    matchX[x] = y;
	    return 1;
	}
    }
    return 0;
}

int maxMatching(void) {
    for (int i=1; i<=sizeX; i++) random_shuffle(graph[i].begin(), graph[i].end());
    for (int i=1; i<=sizeX; i++) matchX[i] = -1;
    for (int i=1; i<=sizeY; i++) matchY[i] = -1;
    int res = 0; bool change = true;
    while(change) {
	change = false;
	for (int i=1; i<=sizeX; i++) vis[i] = false;
	for (int i=1; i<=sizeX; i++) {
	    if (matchX[i] == -1 && !vis[i] && dfs(i)) {
		res++; change = true;
	    }
	}
    }
    return res;
}

----------KMP O(n + m)-------------
#include<string>
#include<cstdio>

#define MAX_M 1001

int prefixes[MAX_M];
std::string t, p;

//compute longest prefixes of P which are proper suffixes of P_q
int prefix() {
    prefixes[1] = 0;
    int k = 0;
    for(int q = 2; q <= p.length(); q++) {
        while (k > 0 && p[k] != p[q-1]) k = prefixes[k];
        if (p[k] == p[q-1]) k++;
        prefixes[q] = k;
    }
}
//print out shifts for which pattern occurs in target
void kmp(){
    prefix();
    int q = 0;
    for (int i = 1; i <= t.length(); i++) {
        while(q > 0 && p[q] != t[i-1]) q = prefixes[q];
        if (p[q] == t[i-1]) q++;
        if (q == p.length()) {
            printf("valid shift: %d\n", i - (int) p.length()); q = prefixes[q];
        }
    }
}

----------Shortest distance between all pairs of points O(n log n)----------
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;

#define MAX_N 50000
#define MIN(a,b) ((a)<(b)) ? a : b
#define MAX(a,b) ((a)>(b)) ? a : b

struct point {
    int x, y, nr;
};

struct ans {
    long long dist;
    int index1, index2;
    void operator=(const ans& val) {
	dist = val.dist;
	index1 = val.index1;
	index2 = val.index2;
    }
    bool operator<(const ans& val) const {
	return dist < val.dist;
    }
};

bool compX(const point pA, const point pB) {
    return pA.x < pB.x;
}

bool compY(const point pA, const point pB) {
    return pA.y < pB.y;
}

inline long long dist(const point pA, const point pB) {
    long long aX = static_cast<long long>(pA.x);
    long long bX = static_cast<long long>(pB.x);
    long long aY = static_cast<long long>(pA.y);
    long long bY = static_cast<long long>(pB.y);
    return ((aX - bX) * (aX - bX) + (aY - bY) * (aY - bY));
}

ans minDist(point *tab, int n) {
    if (n >= 2) {
	ans res = {dist(tab[0], tab[1]), tab[0].nr, tab[1].nr};
	if (n == 3) {
	    ans cand1 = {dist(tab[0], tab[2]), tab[0].nr, tab[2].nr};
	    res = MIN(res, cand1);
	    ans cand2 = {dist(tab[1], tab[2]), tab[1].nr, tab[2].nr};
	    res = MIN(res, cand2);
	}
	return res;
    }
}

ans closestPair(point *tabX, point *tabY, int n) {
    if (n <= 3) {
	return minDist(tabX, n);
    }
    int m = n/2;
    ans ansL = closestPair(tabX, tabY, m);
    ans ansR = closestPair(tabX + m, tabY + m, n - m);
    ans res = MIN(ansL, ansR);
    long long distMin = res.dist;
    vector<point> temp;
    for (int i=0; i<n; i++) {
	if (abs(tabY[m].x - tabY[i].x) < distMin) {
	    temp.push_back(tabY[i]);
	}
    }
    for (int i=0; i<temp.size(); i++) {
	for (int k=i+1; k<temp.size() && dist(temp[i],temp[k])<distMin; k++) {
	    ans candRes = { dist(temp[i],temp[k]), temp[i].nr, temp[k].nr};
	    res = MIN(res, candRes);
	}
    }
    return res;
}

ans calcRes(point *tabX, point *tabY, int n) {
    sort(tabX, tabX + n, compX);
    sort(tabY, tabY + n, compY);
    return closestPair(tabX, tabY, n);
}

<|endoftext|>


<commit_before><commit_msg>fdo#77806: Check the boundaries before accessing an array....<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: addonstoolboxfactory.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: ihi $ $Date: 2007-08-17 13:33:47 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_framework.hxx"

#ifndef __FRAMEWORK_UIFACTORY_ADDONSTOOLBOXFACTORY_HXX_
#include <uifactory/addonstoolboxfactory.hxx>
#endif

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_UIELEMENT_ADDONSTOOLBARWRAPPER_HXX_
#include <uielement/addonstoolbarwrapper.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_RESETABLEGUARD_HXX_
#include <threadhelp/resetableguard.hxx>
#endif

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________

#ifndef _COM_SUN_STAR_UTIL_XURLTRANSFORMER_HPP_
#include <com/sun/star/util/XURLTransformer.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif

#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif

#ifndef _COM_SUN_STAR_UI_XMODULEUICONFIGURATIONMANAGERSUPPLIER_HPP_
#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
#endif

#ifndef _COM_SUN_STAR_UI_XUICONFIGURATIONMANAGERSUPLLIER_HPP_
#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
#endif

//_________________________________________________________________________________________________________________
//  includes of other projects
//_________________________________________________________________________________________________________________

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif

//_________________________________________________________________________________________________________________
//  Defines
//_________________________________________________________________________________________________________________
//

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::frame;
using namespace com::sun::star::beans;
using namespace com::sun::star::util;
using namespace ::com::sun::star::ui;

namespace framework
{

//*****************************************************************************************************************
//  XInterface, XTypeProvider, XServiceInfo
//*****************************************************************************************************************
DEFINE_XINTERFACE_3                    (    AddonsToolBoxFactory                                            ,
                                            OWeakObject                                                     ,
                                            DIRECT_INTERFACE( css::lang::XTypeProvider                      ),
                                            DIRECT_INTERFACE( css::lang::XServiceInfo                       ),
                                            DIRECT_INTERFACE( ::com::sun::star::ui::XUIElementFactory )
                                        )

DEFINE_XTYPEPROVIDER_3                  (   AddonsToolBoxFactory                            ,
                                            css::lang::XTypeProvider                        ,
                                            css::lang::XServiceInfo                         ,
                                            ::com::sun::star::ui::XUIElementFactory
                                        )

DEFINE_XSERVICEINFO_ONEINSTANCESERVICE  (   AddonsToolBoxFactory                            ,
                                            ::cppu::OWeakObject                             ,
                                            SERVICENAME_TOOLBARFACTORY                      ,
                                            IMPLEMENTATIONNAME_ADDONSTOOLBARFACTORY
                                        )

DEFINE_INIT_SERVICE                     (   AddonsToolBoxFactory, {} )

AddonsToolBoxFactory::AddonsToolBoxFactory(
    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
    ThreadHelpBase( &Application::GetSolarMutex() )
    , m_xServiceManager( xServiceManager )
    , m_xModuleManager( xServiceManager->createInstance(
                            OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ))),
                        UNO_QUERY )
{
}

AddonsToolBoxFactory::~AddonsToolBoxFactory()
{
}

static sal_Bool IsCorrectContext( const ::rtl::OUString& rModuleIdentifier, const rtl::OUString& aContextList )
{
    if ( aContextList.getLength() == 0 )
        return sal_True;

    if ( rModuleIdentifier.getLength() > 0 )
    {
        sal_Int32 nIndex = aContextList.indexOf( rModuleIdentifier );
        return ( nIndex >= 0 );
    }

    return sal_False;
}

sal_Bool AddonsToolBoxFactory::hasButtonsInContext(
    const Sequence< Sequence< PropertyValue > >& rPropSeqSeq,
    const Reference< XFrame >& rFrame )
{
    ::rtl::OUString aModuleIdentifier;
    try
    {
        aModuleIdentifier = m_xModuleManager->identify( rFrame );
    }
    catch ( RuntimeException& )
    {
        throw;
    }
    catch ( Exception& )
    {
    }

    // Check before we create a toolbar that we have at least one button in
    // the current frame context.
    for ( sal_uInt32 i = 0; i < (sal_uInt32)rPropSeqSeq.getLength(); i++ )
    {
        sal_Bool    bIsButton( sal_True );
        sal_Bool    bIsCorrectContext( sal_False );
        sal_uInt32  nPropChecked( 0 );

        const Sequence< PropertyValue >& rPropSeq = rPropSeqSeq[i];
        for ( sal_uInt32 j = 0; j < (sal_uInt32)rPropSeq.getLength(); j++ )
        {
            if ( rPropSeq[j].Name.equalsAsciiL( "Context", 7 ))
            {
                OUString aContextList;
                if ( rPropSeq[j].Value >>= aContextList )
                    bIsCorrectContext = IsCorrectContext( aModuleIdentifier, aContextList );
                nPropChecked++;
            }
            else if ( rPropSeq[j].Name.equalsAsciiL( "URL", 3 ))
            {
                OUString aURL;
                rPropSeq[j].Value >>= aURL;
                bIsButton = !aURL.equalsAsciiL( "private:separator", 17 );
                nPropChecked++;
            }

            if ( nPropChecked == 2 )
                break;
        }

        if ( bIsButton && bIsCorrectContext )
            return sal_True;
    }

    return sal_False;
}

// XUIElementFactory
Reference< XUIElement > SAL_CALL AddonsToolBoxFactory::createUIElement(
    const ::rtl::OUString& ResourceURL,
    const Sequence< PropertyValue >& Args )
throw ( ::com::sun::star::container::NoSuchElementException,
        ::com::sun::star::lang::IllegalArgumentException,
        ::com::sun::star::uno::RuntimeException )
{
    // SAFE
    ResetableGuard aLock( m_aLock );

    Sequence< Sequence< PropertyValue > >   aConfigData;
    Reference< XFrame >                     xFrame;
    rtl::OUString                           aResourceURL( ResourceURL );

    for ( sal_Int32 n = 0; n < Args.getLength(); n++ )
    {
        if ( Args[n].Name.equalsAscii( "ConfigurationData" ))
            Args[n].Value >>= aConfigData;
        else if ( Args[n].Name.equalsAscii( "Frame" ))
            Args[n].Value >>= xFrame;
        else if ( Args[n].Name.equalsAscii( "ResourceURL" ))
            Args[n].Value >>= aResourceURL;
    }

    if ( aResourceURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/addon_" ))) != 0 )
        throw IllegalArgumentException();

    // Identify frame and determine module identifier to look for context based buttons
    Reference< ::com::sun::star::ui::XUIElement > xToolBar;
    if ( xFrame.is() &&
         ( aConfigData.getLength()> 0 ) &&
         hasButtonsInContext( aConfigData, xFrame ))
    {
        PropertyValue aPropValue;
        Sequence< Any > aPropSeq( 3 );
        aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
        aPropValue.Value <<= xFrame;
        aPropSeq[0] <<= aPropValue;
        aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationData" ));
        aPropValue.Value <<= aConfigData;
        aPropSeq[1] <<= aPropValue;
        aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ));
        aPropValue.Value <<= aResourceURL;
        aPropSeq[2] <<= aPropValue;

        vos::OGuard aGuard( Application::GetSolarMutex() );
        AddonsToolBarWrapper* pToolBarWrapper = new AddonsToolBarWrapper( m_xServiceManager );
        xToolBar = Reference< ::com::sun::star::ui::XUIElement >( (OWeakObject *)pToolBarWrapper, UNO_QUERY );
        Reference< XInitialization > xInit( xToolBar, UNO_QUERY );
        xInit->initialize( aPropSeq );
    }

    return xToolBar;
}

}
<commit_msg>INTEGRATION: CWS changefileheader (1.8.96); FILE MERGED 2008/04/01 15:18:51 thb 1.8.96.3: #i85898# Stripping all external header guards 2008/04/01 10:58:17 thb 1.8.96.2: #i85898# Stripping all external header guards 2008/03/28 15:35:38 rt 1.8.96.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: addonstoolboxfactory.cxx,v $
 * $Revision: 1.9 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_framework.hxx"
#include <uifactory/addonstoolboxfactory.hxx>

//_________________________________________________________________________________________________________________
//  my own includes
//_________________________________________________________________________________________________________________
#include <uielement/addonstoolbarwrapper.hxx>
#include <threadhelp/resetableguard.hxx>

//_________________________________________________________________________________________________________________
//  interface includes
//_________________________________________________________________________________________________________________
#include <com/sun/star/util/XURLTransformer.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>

#ifndef _COM_SUN_STAR_UI_XUICONFIGURATIONMANAGERSUPLLIER_HPP_
#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
#endif

//_________________________________________________________________________________________________________________
//  includes of other projects
//_________________________________________________________________________________________________________________
#include <vcl/svapp.hxx>
#include <tools/urlobj.hxx>
#include <rtl/ustrbuf.hxx>

//_________________________________________________________________________________________________________________
//  Defines
//_________________________________________________________________________________________________________________
//

using namespace rtl;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::frame;
using namespace com::sun::star::beans;
using namespace com::sun::star::util;
using namespace ::com::sun::star::ui;

namespace framework
{

//*****************************************************************************************************************
//  XInterface, XTypeProvider, XServiceInfo
//*****************************************************************************************************************
DEFINE_XINTERFACE_3                    (    AddonsToolBoxFactory                                            ,
                                            OWeakObject                                                     ,
                                            DIRECT_INTERFACE( css::lang::XTypeProvider                      ),
                                            DIRECT_INTERFACE( css::lang::XServiceInfo                       ),
                                            DIRECT_INTERFACE( ::com::sun::star::ui::XUIElementFactory )
                                        )

DEFINE_XTYPEPROVIDER_3                  (   AddonsToolBoxFactory                            ,
                                            css::lang::XTypeProvider                        ,
                                            css::lang::XServiceInfo                         ,
                                            ::com::sun::star::ui::XUIElementFactory
                                        )

DEFINE_XSERVICEINFO_ONEINSTANCESERVICE  (   AddonsToolBoxFactory                            ,
                                            ::cppu::OWeakObject                             ,
                                            SERVICENAME_TOOLBARFACTORY                      ,
                                            IMPLEMENTATIONNAME_ADDONSTOOLBARFACTORY
                                        )

DEFINE_INIT_SERVICE                     (   AddonsToolBoxFactory, {} )

AddonsToolBoxFactory::AddonsToolBoxFactory(
    const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
    ThreadHelpBase( &Application::GetSolarMutex() )
    , m_xServiceManager( xServiceManager )
    , m_xModuleManager( xServiceManager->createInstance(
                            OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ))),
                        UNO_QUERY )
{
}

AddonsToolBoxFactory::~AddonsToolBoxFactory()
{
}

static sal_Bool IsCorrectContext( const ::rtl::OUString& rModuleIdentifier, const rtl::OUString& aContextList )
{
    if ( aContextList.getLength() == 0 )
        return sal_True;

    if ( rModuleIdentifier.getLength() > 0 )
    {
        sal_Int32 nIndex = aContextList.indexOf( rModuleIdentifier );
        return ( nIndex >= 0 );
    }

    return sal_False;
}

sal_Bool AddonsToolBoxFactory::hasButtonsInContext(
    const Sequence< Sequence< PropertyValue > >& rPropSeqSeq,
    const Reference< XFrame >& rFrame )
{
    ::rtl::OUString aModuleIdentifier;
    try
    {
        aModuleIdentifier = m_xModuleManager->identify( rFrame );
    }
    catch ( RuntimeException& )
    {
        throw;
    }
    catch ( Exception& )
    {
    }

    // Check before we create a toolbar that we have at least one button in
    // the current frame context.
    for ( sal_uInt32 i = 0; i < (sal_uInt32)rPropSeqSeq.getLength(); i++ )
    {
        sal_Bool    bIsButton( sal_True );
        sal_Bool    bIsCorrectContext( sal_False );
        sal_uInt32  nPropChecked( 0 );

        const Sequence< PropertyValue >& rPropSeq = rPropSeqSeq[i];
        for ( sal_uInt32 j = 0; j < (sal_uInt32)rPropSeq.getLength(); j++ )
        {
            if ( rPropSeq[j].Name.equalsAsciiL( "Context", 7 ))
            {
                OUString aContextList;
                if ( rPropSeq[j].Value >>= aContextList )
                    bIsCorrectContext = IsCorrectContext( aModuleIdentifier, aContextList );
                nPropChecked++;
            }
            else if ( rPropSeq[j].Name.equalsAsciiL( "URL", 3 ))
            {
                OUString aURL;
                rPropSeq[j].Value >>= aURL;
                bIsButton = !aURL.equalsAsciiL( "private:separator", 17 );
                nPropChecked++;
            }

            if ( nPropChecked == 2 )
                break;
        }

        if ( bIsButton && bIsCorrectContext )
            return sal_True;
    }

    return sal_False;
}

// XUIElementFactory
Reference< XUIElement > SAL_CALL AddonsToolBoxFactory::createUIElement(
    const ::rtl::OUString& ResourceURL,
    const Sequence< PropertyValue >& Args )
throw ( ::com::sun::star::container::NoSuchElementException,
        ::com::sun::star::lang::IllegalArgumentException,
        ::com::sun::star::uno::RuntimeException )
{
    // SAFE
    ResetableGuard aLock( m_aLock );

    Sequence< Sequence< PropertyValue > >   aConfigData;
    Reference< XFrame >                     xFrame;
    rtl::OUString                           aResourceURL( ResourceURL );

    for ( sal_Int32 n = 0; n < Args.getLength(); n++ )
    {
        if ( Args[n].Name.equalsAscii( "ConfigurationData" ))
            Args[n].Value >>= aConfigData;
        else if ( Args[n].Name.equalsAscii( "Frame" ))
            Args[n].Value >>= xFrame;
        else if ( Args[n].Name.equalsAscii( "ResourceURL" ))
            Args[n].Value >>= aResourceURL;
    }

    if ( aResourceURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/addon_" ))) != 0 )
        throw IllegalArgumentException();

    // Identify frame and determine module identifier to look for context based buttons
    Reference< ::com::sun::star::ui::XUIElement > xToolBar;
    if ( xFrame.is() &&
         ( aConfigData.getLength()> 0 ) &&
         hasButtonsInContext( aConfigData, xFrame ))
    {
        PropertyValue aPropValue;
        Sequence< Any > aPropSeq( 3 );
        aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
        aPropValue.Value <<= xFrame;
        aPropSeq[0] <<= aPropValue;
        aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationData" ));
        aPropValue.Value <<= aConfigData;
        aPropSeq[1] <<= aPropValue;
        aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ));
        aPropValue.Value <<= aResourceURL;
        aPropSeq[2] <<= aPropValue;

        vos::OGuard aGuard( Application::GetSolarMutex() );
        AddonsToolBarWrapper* pToolBarWrapper = new AddonsToolBarWrapper( m_xServiceManager );
        xToolBar = Reference< ::com::sun::star::ui::XUIElement >( (OWeakObject *)pToolBarWrapper, UNO_QUERY );
        Reference< XInitialization > xInit( xToolBar, UNO_QUERY );
        xInit->initialize( aPropSeq );
    }

    return xToolBar;
}

}
<|endoftext|>


<commit_before>/*
Highly Optimized Object-Oriented Molecular Dynamics (HOOMD) Open
Source Software License
Copyright (c) 2008 Ames Laboratory Iowa State University
All rights reserved.

Redistribution and use of HOOMD, 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 copyright holder nor the names HOOMD's
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER 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.
*/

// conditionally compile in only if boost is 1.35 or later
#include <boost/version.hpp>
#if (BOOST_VERSION >= 103500)

#include <iostream>

//! Name the unit test module
#define BOOST_TEST_MODULE ElectrostaticShortRangeTests
#include "boost_utf_configure.h"

#include <boost/test/floating_point_comparison.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/math/special_functions/erf.hpp>

#include "ElectrostaticShortRange.h"

#include "BinnedNeighborList.h"
#include "Initializers.h"

#include <math.h>

#define EWALD_F  1.128379167
using namespace std;
using namespace boost;

/*! \file ElectrostaticShortRange_force_test.cc
	\brief Implements unit tests for ElectrostaticShortRange and descendants
	\ingroup unit_tests
*/

//! Helper macro for testing if two numbers are close
#define MY_BOOST_CHECK_CLOSE(a,b,c) BOOST_CHECK_CLOSE(a,Scalar(b),Scalar(c))
//! Helper macro for testing if a number is small
#define MY_BOOST_CHECK_SMALL(a,c) BOOST_CHECK_SMALL(a,Scalar(c))

//! Tolerance in percent to use for comparing various ElectrostaticShortRange to each other

const Scalar tol = Scalar(1);

//! Typedef'd ElectrostaticShortRange factory
typedef boost::function<shared_ptr<ElectrostaticShortRange> (shared_ptr<ParticleData> pdata, shared_ptr<NeighborList> nlist, Scalar r_cut, Scalar alpha, Scalar delta, Scalar min_value)> ElectrostaticShortRange_force_creator;

//! Test the ability of the Short Range Electrostatic force compute to actually calculate forces
/*!
	\note With the creator as a parameter, the same code can be used to test any derived child
		of ElectrostaticShortRange
*/
void ElectrostaticShortRange_force_accuracy_test(ElectrostaticShortRange_force_creator Elstatics_ShortRange_creator)
	{
	cout << "Testing the accuracy of the look up table in ElectrostaticShortRange" << endl;
	// Simple test to check the accuracy of the look up table
	shared_ptr<ParticleData> pdata_2(new ParticleData(2, BoxDim(1000.0), 1));
	ParticleDataArrays arrays = pdata_2->acquireReadWrite();
	arrays.x[0] = arrays.y[0] = arrays.z[0] = 0.0; arrays.charge[0]=1.0;
	// A positively charged particle is located at the origin
	arrays.x[1] = 1.0; arrays.y[1] = arrays.z[1] = 0.0; arrays.charge[1]=1.0;
	// Another positive charge is located at distance 1 in the x axis
	pdata_2->release();
	shared_ptr<NeighborList> nlist_2(new NeighborList(pdata_2, Scalar(3.0), Scalar(5.0)));
	// The cut-off is set to 3 while the buffer size is 5
	Scalar r_cut=Scalar(3.0);

	Scalar delta=Scalar(0.1);
	Scalar min_value=Scalar(0.41);

	for(int k1=0;k1<4;k1++){

	Scalar alpha=Scalar(0.3+k1);
    //Test different values of alpha as well
	shared_ptr<ElectrostaticShortRange> fc_2=Elstatics_ShortRange_creator(pdata_2,nlist_2,r_cut,alpha,delta,min_value);
	// An ElectrostaticShortRange object with specified value of cut_off, alpha, delta and min_value is instantiated
	// now let us check how much the force differs from the exact calculation for N_p**3 points within the cut_off;

	int N_p=7;
	Scalar delta_test= (r_cut-min_value)/(sqrt(r_cut)*N_p);
	int j_count=0;

	for(int jx=0;jx<N_p;jx++){
		for(int jy=0;jy<N_p;jy++){
			for(int jz=0;jz<N_p;jz++){

	arrays.x[1]=min_value+Scalar((static_cast<double>(jx))*delta_test);
	arrays.y[1]=min_value+Scalar((static_cast<double>(jy))*delta_test);
    arrays.z[1]=min_value+Scalar((static_cast<double>(jz))*delta_test);

	Scalar dx = arrays.x[1]-arrays.x[0];
	Scalar dy = arrays.y[1]-arrays.y[0];
	Scalar dz = arrays.z[1]-arrays.z[0];

	Scalar rsq = sqrt(dx*dx + dy*dy + dz*dz);
	Scalar al_rsq=alpha*rsq;

	Scalar erfc_al=boost::math::erfc(al_rsq);

	Scalar fExactx=-dx*(Scalar(EWALD_F)*alpha*exp(-al_rsq*al_rsq)+erfc_al/rsq)/pow(rsq,2);
    Scalar fExacty=-dy*(Scalar(EWALD_F)*alpha*exp(-al_rsq*al_rsq)+erfc_al/rsq)/pow(rsq,2);
	Scalar fExactz=-dz*(Scalar(EWALD_F)*alpha*exp(-al_rsq*al_rsq)+erfc_al/rsq)/pow(rsq,2);
	Scalar fExactE=Scalar(0.5)*erfc_al/rsq;

	fc_2->compute(j_count);
	j_count++;

	ForceDataArrays force_arrays=fc_2->acquire();

	MY_BOOST_CHECK_CLOSE(force_arrays.fx[0],fExactx,tol);
    MY_BOOST_CHECK_CLOSE(force_arrays.fy[0],fExacty,tol);
    MY_BOOST_CHECK_CLOSE(force_arrays.fz[0],fExactz,tol);
	MY_BOOST_CHECK_CLOSE(force_arrays.pe[0],fExactE,tol);

	MY_BOOST_CHECK_CLOSE(force_arrays.fx[1],-fExactx,tol);
    MY_BOOST_CHECK_CLOSE(force_arrays.fy[1],-fExacty,tol);
    MY_BOOST_CHECK_CLOSE(force_arrays.fz[1],-fExactz,tol);
	MY_BOOST_CHECK_CLOSE(force_arrays.pe[1],fExactE,tol);
			}
		}
	}
	}
	}

//! ElectrostaticShortRange creator for unit tests
shared_ptr<ElectrostaticShortRange> base_class_ShortRangeElectrostatic_creator(shared_ptr<ParticleData> pdata, shared_ptr<NeighborList> nlist, Scalar r_cut, Scalar alpha, Scalar delta, Scalar min_value)
	{
	return shared_ptr<ElectrostaticShortRange>(new ElectrostaticShortRange(pdata, nlist, r_cut, alpha, delta,min_value));
	}

//! boost test case for particle test on CPU
BOOST_AUTO_TEST_CASE(ElectrostaticShortRange_force_accuracy)
	{
	ElectrostaticShortRange_force_creator ElectrostaticShortRange_creator_base = bind(base_class_ShortRangeElectrostatic_creator, _1, _2, _3, _4, _5,_6);
	ElectrostaticShortRange_force_accuracy_test(ElectrostaticShortRange_creator_base);
}

#undef EWALD_F
#else
// We can't have the unit test passing if the code wasn't even compiled!
BOOST_AUTO_TEST_CASE(dummy_test)
	{
	BOOST_FAIL("ElectrostaticShortRange not compiled");
	}

#endif

<commit_msg>Unit test now compiles and fails when boost < 1.35 is installed. ticket #79<commit_after>/*
Highly Optimized Object-Oriented Molecular Dynamics (HOOMD) Open
Source Software License
Copyright (c) 2008 Ames Laboratory Iowa State University
All rights reserved.

Redistribution and use of HOOMD, 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 copyright holder nor the names HOOMD's
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER 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 <iostream>

//! Name the unit test module
#define BOOST_TEST_MODULE ElectrostaticShortRangeTests
#include "boost_utf_configure.h"

// conditionally compile in only if boost is 1.35 or later
#include <boost/version.hpp>
#if (BOOST_VERSION >= 103500)

#include <boost/test/floating_point_comparison.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/math/special_functions/erf.hpp>

#include "ElectrostaticShortRange.h"

#include "BinnedNeighborList.h"
#include "Initializers.h"

#include <math.h>

#define EWALD_F  1.128379167
using namespace std;
using namespace boost;

/*! \file ElectrostaticShortRange_force_test.cc
	\brief Implements unit tests for ElectrostaticShortRange and descendants
	\ingroup unit_tests
*/

//! Helper macro for testing if two numbers are close
#define MY_BOOST_CHECK_CLOSE(a,b,c) BOOST_CHECK_CLOSE(a,Scalar(b),Scalar(c))
//! Helper macro for testing if a number is small
#define MY_BOOST_CHECK_SMALL(a,c) BOOST_CHECK_SMALL(a,Scalar(c))

//! Tolerance in percent to use for comparing various ElectrostaticShortRange to each other

const Scalar tol = Scalar(1);

//! Typedef'd ElectrostaticShortRange factory
typedef boost::function<shared_ptr<ElectrostaticShortRange> (shared_ptr<ParticleData> pdata, shared_ptr<NeighborList> nlist, Scalar r_cut, Scalar alpha, Scalar delta, Scalar min_value)> ElectrostaticShortRange_force_creator;

//! Test the ability of the Short Range Electrostatic force compute to actually calculate forces
/*!
	\note With the creator as a parameter, the same code can be used to test any derived child
		of ElectrostaticShortRange
*/
void ElectrostaticShortRange_force_accuracy_test(ElectrostaticShortRange_force_creator Elstatics_ShortRange_creator)
	{
	cout << "Testing the accuracy of the look up table in ElectrostaticShortRange" << endl;
	// Simple test to check the accuracy of the look up table
	shared_ptr<ParticleData> pdata_2(new ParticleData(2, BoxDim(1000.0), 1));
	ParticleDataArrays arrays = pdata_2->acquireReadWrite();
	arrays.x[0] = arrays.y[0] = arrays.z[0] = 0.0; arrays.charge[0]=1.0;
	// A positively charged particle is located at the origin
	arrays.x[1] = 1.0; arrays.y[1] = arrays.z[1] = 0.0; arrays.charge[1]=1.0;
	// Another positive charge is located at distance 1 in the x axis
	pdata_2->release();
	shared_ptr<NeighborList> nlist_2(new NeighborList(pdata_2, Scalar(3.0), Scalar(5.0)));
	// The cut-off is set to 3 while the buffer size is 5
	Scalar r_cut=Scalar(3.0);

	Scalar delta=Scalar(0.1);
	Scalar min_value=Scalar(0.41);

	for(int k1=0;k1<4;k1++){

	Scalar alpha=Scalar(0.3+k1);
    //Test different values of alpha as well
	shared_ptr<ElectrostaticShortRange> fc_2=Elstatics_ShortRange_creator(pdata_2,nlist_2,r_cut,alpha,delta,min_value);
	// An ElectrostaticShortRange object with specified value of cut_off, alpha, delta and min_value is instantiated
	// now let us check how much the force differs from the exact calculation for N_p**3 points within the cut_off;

	int N_p=7;
	Scalar delta_test= (r_cut-min_value)/(sqrt(r_cut)*N_p);
	int j_count=0;

	for(int jx=0;jx<N_p;jx++){
		for(int jy=0;jy<N_p;jy++){
			for(int jz=0;jz<N_p;jz++){

	arrays.x[1]=min_value+Scalar((static_cast<double>(jx))*delta_test);
	arrays.y[1]=min_value+Scalar((static_cast<double>(jy))*delta_test);
    arrays.z[1]=min_value+Scalar((static_cast<double>(jz))*delta_test);

	Scalar dx = arrays.x[1]-arrays.x[0];
	Scalar dy = arrays.y[1]-arrays.y[0];
	Scalar dz = arrays.z[1]-arrays.z[0];

	Scalar rsq = sqrt(dx*dx + dy*dy + dz*dz);
	Scalar al_rsq=alpha*rsq;

	Scalar erfc_al=boost::math::erfc(al_rsq);

	Scalar fExactx=-dx*(Scalar(EWALD_F)*alpha*exp(-al_rsq*al_rsq)+erfc_al/rsq)/pow(rsq,2);
    Scalar fExacty=-dy*(Scalar(EWALD_F)*alpha*exp(-al_rsq*al_rsq)+erfc_al/rsq)/pow(rsq,2);
	Scalar fExactz=-dz*(Scalar(EWALD_F)*alpha*exp(-al_rsq*al_rsq)+erfc_al/rsq)/pow(rsq,2);
	Scalar fExactE=Scalar(0.5)*erfc_al/rsq;

	fc_2->compute(j_count);
	j_count++;

	ForceDataArrays force_arrays=fc_2->acquire();

	MY_BOOST_CHECK_CLOSE(force_arrays.fx[0],fExactx,tol);
    MY_BOOST_CHECK_CLOSE(force_arrays.fy[0],fExacty,tol);
    MY_BOOST_CHECK_CLOSE(force_arrays.fz[0],fExactz,tol);
	MY_BOOST_CHECK_CLOSE(force_arrays.pe[0],fExactE,tol);

	MY_BOOST_CHECK_CLOSE(force_arrays.fx[1],-fExactx,tol);
    MY_BOOST_CHECK_CLOSE(force_arrays.fy[1],-fExacty,tol);
    MY_BOOST_CHECK_CLOSE(force_arrays.fz[1],-fExactz,tol);
	MY_BOOST_CHECK_CLOSE(force_arrays.pe[1],fExactE,tol);
			}
		}
	}
	}
	}

//! ElectrostaticShortRange creator for unit tests
shared_ptr<ElectrostaticShortRange> base_class_ShortRangeElectrostatic_creator(shared_ptr<ParticleData> pdata, shared_ptr<NeighborList> nlist, Scalar r_cut, Scalar alpha, Scalar delta, Scalar min_value)
	{
	return shared_ptr<ElectrostaticShortRange>(new ElectrostaticShortRange(pdata, nlist, r_cut, alpha, delta,min_value));
	}

//! boost test case for particle test on CPU
BOOST_AUTO_TEST_CASE(ElectrostaticShortRange_force_accuracy)
	{
	ElectrostaticShortRange_force_creator ElectrostaticShortRange_creator_base = bind(base_class_ShortRangeElectrostatic_creator, _1, _2, _3, _4, _5,_6);
	ElectrostaticShortRange_force_accuracy_test(ElectrostaticShortRange_creator_base);
}

#undef EWALD_F
#else
// We can't have the unit test passing if the code wasn't even compiled!
BOOST_AUTO_TEST_CASE(dummy_test)
	{
	BOOST_FAIL("ElectrostaticShortRange not compiled");
	}

#endif

<|endoftext|>