<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
// Copyright (c) 2008 Roberto Raggi <roberto.raggi@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "CheckName.h"
#include "Semantic.h"
#include "AST.h"
#include "Control.h"
#include "TranslationUnit.h"
#include "Literals.h"
#include "Names.h"
#include "CoreTypes.h"
#include "Symbols.h"
#include "Scope.h"
#include <cassert>

using namespace CPlusPlus;

CheckName::CheckName(Semantic *semantic)
    : SemanticCheck(semantic),
      _name(0),
      _scope(0)
{ }

CheckName::~CheckName()
{ }

const Name *CheckName::check(NameAST *name, Scope *scope)
{
    const Name *previousName = switchName(0);
    Scope *previousScope = switchScope(scope);
    accept(name);

    if (_name && name)
        name->name = _name;

    (void) switchScope(previousScope);
    return switchName(previousName);
}

const Name *CheckName::check(NestedNameSpecifierListAST *nested_name_specifier_list, Scope *scope)
{
    const Name *previousName = switchName(0);
    Scope *previousScope = switchScope(scope);

    std::vector<const Name *> names;
    for (NestedNameSpecifierListAST *it = nested_name_specifier_list; it; it = it->next) {
        NestedNameSpecifierAST *nested_name_specifier = it->value;
        names.push_back(semantic()->check(nested_name_specifier->class_or_namespace_name, _scope));
    }

    if (! names.empty())
        _name = control()->qualifiedNameId(&names[0], names.size());

    (void) switchScope(previousScope);
    return switchName(previousName);
}

void CheckName::check(ObjCMessageArgumentDeclarationAST *arg, Scope *scope)
{
    const Name *previousName = switchName(0);
    Scope *previousScope = switchScope(scope);

    accept(arg);

    (void) switchScope(previousScope);
    (void) switchName(previousName);
}

const Name *CheckName::switchName(const Name *name)
{
    const Name *previousName = _name;
    _name = name;
    return previousName;
}

Scope *CheckName::switchScope(Scope *scope)
{
    Scope *previousScope = _scope;
    _scope = scope;
    return previousScope;
}

bool CheckName::visit(QualifiedNameAST *ast)
{
    std::vector<const Name *> names;
    for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next) {
        NestedNameSpecifierAST *nested_name_specifier = it->value;
        names.push_back(semantic()->check(nested_name_specifier->class_or_namespace_name, _scope));
    }
    names.push_back(semantic()->check(ast->unqualified_name, _scope));
    _name = control()->qualifiedNameId(&names[0], names.size(), ast->global_scope_token != 0);

    ast->name = _name;
    return false;
}

bool CheckName::visit(OperatorFunctionIdAST *ast)
{
    assert(ast->op != 0);

    OperatorNameId::Kind kind = OperatorNameId::InvalidOp;

    switch (tokenKind(ast->op->op_token)) {
    case T_NEW:
        if (ast->op->open_token)
            kind = OperatorNameId::NewArrayOp;
        else
            kind = OperatorNameId::NewOp;
        break;

    case T_DELETE:
        if (ast->op->open_token)
            kind = OperatorNameId::DeleteArrayOp;
        else
            kind = OperatorNameId::DeleteOp;
        break;

    case T_PLUS:
        kind = OperatorNameId::PlusOp;
        break;

    case T_MINUS:
        kind = OperatorNameId::MinusOp;
        break;

    case T_STAR:
        kind = OperatorNameId::StarOp;
        break;

    case T_SLASH:
        kind = OperatorNameId::SlashOp;
        break;

    case T_PERCENT:
        kind = OperatorNameId::PercentOp;
        break;

    case T_CARET:
        kind = OperatorNameId::CaretOp;
        break;

    case T_AMPER:
        kind = OperatorNameId::AmpOp;
        break;

    case T_PIPE:
        kind = OperatorNameId::PipeOp;
        break;

    case T_TILDE:
        kind = OperatorNameId::TildeOp;
        break;

    case T_EXCLAIM:
        kind = OperatorNameId::ExclaimOp;
        break;

    case T_EQUAL:
        kind = OperatorNameId::EqualOp;
        break;

    case T_LESS:
        kind = OperatorNameId::LessOp;
        break;

    case T_GREATER:
        kind = OperatorNameId::GreaterOp;
        break;

    case T_PLUS_EQUAL:
        kind = OperatorNameId::PlusEqualOp;
        break;

    case T_MINUS_EQUAL:
        kind = OperatorNameId::MinusEqualOp;
        break;

    case T_STAR_EQUAL:
        kind = OperatorNameId::StarEqualOp;
        break;

    case T_SLASH_EQUAL:
        kind = OperatorNameId::SlashEqualOp;
        break;

    case T_PERCENT_EQUAL:
        kind = OperatorNameId::PercentEqualOp;
        break;

    case T_CARET_EQUAL:
        kind = OperatorNameId::CaretEqualOp;
        break;

    case T_AMPER_EQUAL:
        kind = OperatorNameId::AmpEqualOp;
        break;

    case T_PIPE_EQUAL:
        kind = OperatorNameId::PipeEqualOp;
        break;

    case T_LESS_LESS:
        kind = OperatorNameId::LessLessOp;
        break;

    case T_GREATER_GREATER:
        kind = OperatorNameId::GreaterGreaterOp;
        break;

    case T_LESS_LESS_EQUAL:
        kind = OperatorNameId::LessLessEqualOp;
        break;

    case T_GREATER_GREATER_EQUAL:
        kind = OperatorNameId::GreaterGreaterEqualOp;
        break;

    case T_EQUAL_EQUAL:
        kind = OperatorNameId::EqualEqualOp;
        break;

    case T_EXCLAIM_EQUAL:
        kind = OperatorNameId::ExclaimEqualOp;
        break;

    case T_LESS_EQUAL:
        kind = OperatorNameId::LessEqualOp;
        break;

    case T_GREATER_EQUAL:
        kind = OperatorNameId::GreaterEqualOp;
        break;

    case T_AMPER_AMPER:
        kind = OperatorNameId::AmpAmpOp;
        break;

    case T_PIPE_PIPE:
        kind = OperatorNameId::PipePipeOp;
        break;

    case T_PLUS_PLUS:
        kind = OperatorNameId::PlusPlusOp;
        break;

    case T_MINUS_MINUS:
        kind = OperatorNameId::MinusMinusOp;
        break;

    case T_COMMA:
        kind = OperatorNameId::CommaOp;
        break;

    case T_ARROW_STAR:
        kind = OperatorNameId::ArrowStarOp;
        break;

    case T_ARROW:
        kind = OperatorNameId::ArrowOp;
        break;

    case T_LPAREN:
        kind = OperatorNameId::FunctionCallOp;
        break;

    case T_LBRACKET:
        kind = OperatorNameId::ArrayAccessOp;
        break;

    default:
        kind = OperatorNameId::InvalidOp;
    } // switch

    _name = control()->operatorNameId(kind);
    ast->name = _name;
    return false;
}

bool CheckName::visit(ConversionFunctionIdAST *ast)
{
    FullySpecifiedType ty = semantic()->check(ast->type_specifier_list, _scope);
    ty = semantic()->check(ast->ptr_operator_list, ty, _scope);
    _name = control()->conversionNameId(ty);
    return false;
}

bool CheckName::visit(SimpleNameAST *ast)
{
    const Identifier *id = identifier(ast->identifier_token);
    _name = control()->nameId(id);
    ast->name = _name;
    return false;
}

bool CheckName::visit(DestructorNameAST *ast)
{
    const Identifier *id = identifier(ast->identifier_token);
    _name = control()->destructorNameId(id);
    ast->name = _name;
    return false;
}

bool CheckName::visit(TemplateIdAST *ast)
{
    const Identifier *id = identifier(ast->identifier_token);
    std::vector<FullySpecifiedType> templateArguments;
    for (TemplateArgumentListAST *it = ast->template_argument_list; it;
            it = it->next) {
        ExpressionAST *arg = it->value;
        FullySpecifiedType exprTy = semantic()->check(arg, _scope);
        templateArguments.push_back(exprTy);
    }
    if (templateArguments.empty())
        _name = control()->templateNameId(id);
    else
        _name = control()->templateNameId(id, &templateArguments[0],
                                          templateArguments.size());
    ast->name = _name;
    return false;
}

bool CheckName::visit(ObjCSelectorAST *ast)
{
    std::vector<const Name *> names;
    for (ObjCSelectorArgumentListAST *it = ast->selector_argument_list; it; it = it->next) {
        if (it->value->name_token) {
            const Identifier *id = control()->findOrInsertIdentifier(spell(it->value->name_token));
            const NameId *nameId = control()->nameId(id);
            names.push_back(nameId);
        } else {
            // we have an incomplete name due, probably due to error recovery. So, back out completely
            return false;
        }
    }

    if (!names.empty()) {
        _name = control()->selectorNameId(&names[0], names.size(), true);
        ast->name = _name;
    }

    return false;
}

bool CheckName::visit(ObjCMessageArgumentDeclarationAST *ast)
{
    FullySpecifiedType type;

    if (ast->type_name)
        type = semantic()->check(ast->type_name, _scope);

    if (ast->param_name) {
        accept(ast->param_name);

        Argument *arg = control()->newArgument(ast->param_name->firstToken(),
                                               ast->param_name->name);
        ast->argument = arg;
        arg->setType(type);
        arg->setInitializer(0);
        _scope->enterSymbol(arg);
    }

    return false;
}
<commit_msg>Fixed ObjC selector name creation.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
// Copyright (c) 2008 Roberto Raggi <roberto.raggi@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "CheckName.h"
#include "Semantic.h"
#include "AST.h"
#include "Control.h"
#include "TranslationUnit.h"
#include "Literals.h"
#include "Names.h"
#include "CoreTypes.h"
#include "Symbols.h"
#include "Scope.h"
#include <cassert>

using namespace CPlusPlus;

CheckName::CheckName(Semantic *semantic)
    : SemanticCheck(semantic),
      _name(0),
      _scope(0)
{ }

CheckName::~CheckName()
{ }

const Name *CheckName::check(NameAST *name, Scope *scope)
{
    const Name *previousName = switchName(0);
    Scope *previousScope = switchScope(scope);
    accept(name);

    if (_name && name)
        name->name = _name;

    (void) switchScope(previousScope);
    return switchName(previousName);
}

const Name *CheckName::check(NestedNameSpecifierListAST *nested_name_specifier_list, Scope *scope)
{
    const Name *previousName = switchName(0);
    Scope *previousScope = switchScope(scope);

    std::vector<const Name *> names;
    for (NestedNameSpecifierListAST *it = nested_name_specifier_list; it; it = it->next) {
        NestedNameSpecifierAST *nested_name_specifier = it->value;
        names.push_back(semantic()->check(nested_name_specifier->class_or_namespace_name, _scope));
    }

    if (! names.empty())
        _name = control()->qualifiedNameId(&names[0], names.size());

    (void) switchScope(previousScope);
    return switchName(previousName);
}

void CheckName::check(ObjCMessageArgumentDeclarationAST *arg, Scope *scope)
{
    const Name *previousName = switchName(0);
    Scope *previousScope = switchScope(scope);

    accept(arg);

    (void) switchScope(previousScope);
    (void) switchName(previousName);
}

const Name *CheckName::switchName(const Name *name)
{
    const Name *previousName = _name;
    _name = name;
    return previousName;
}

Scope *CheckName::switchScope(Scope *scope)
{
    Scope *previousScope = _scope;
    _scope = scope;
    return previousScope;
}

bool CheckName::visit(QualifiedNameAST *ast)
{
    std::vector<const Name *> names;
    for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next) {
        NestedNameSpecifierAST *nested_name_specifier = it->value;
        names.push_back(semantic()->check(nested_name_specifier->class_or_namespace_name, _scope));
    }
    names.push_back(semantic()->check(ast->unqualified_name, _scope));
    _name = control()->qualifiedNameId(&names[0], names.size(), ast->global_scope_token != 0);

    ast->name = _name;
    return false;
}

bool CheckName::visit(OperatorFunctionIdAST *ast)
{
    assert(ast->op != 0);

    OperatorNameId::Kind kind = OperatorNameId::InvalidOp;

    switch (tokenKind(ast->op->op_token)) {
    case T_NEW:
        if (ast->op->open_token)
            kind = OperatorNameId::NewArrayOp;
        else
            kind = OperatorNameId::NewOp;
        break;

    case T_DELETE:
        if (ast->op->open_token)
            kind = OperatorNameId::DeleteArrayOp;
        else
            kind = OperatorNameId::DeleteOp;
        break;

    case T_PLUS:
        kind = OperatorNameId::PlusOp;
        break;

    case T_MINUS:
        kind = OperatorNameId::MinusOp;
        break;

    case T_STAR:
        kind = OperatorNameId::StarOp;
        break;

    case T_SLASH:
        kind = OperatorNameId::SlashOp;
        break;

    case T_PERCENT:
        kind = OperatorNameId::PercentOp;
        break;

    case T_CARET:
        kind = OperatorNameId::CaretOp;
        break;

    case T_AMPER:
        kind = OperatorNameId::AmpOp;
        break;

    case T_PIPE:
        kind = OperatorNameId::PipeOp;
        break;

    case T_TILDE:
        kind = OperatorNameId::TildeOp;
        break;

    case T_EXCLAIM:
        kind = OperatorNameId::ExclaimOp;
        break;

    case T_EQUAL:
        kind = OperatorNameId::EqualOp;
        break;

    case T_LESS:
        kind = OperatorNameId::LessOp;
        break;

    case T_GREATER:
        kind = OperatorNameId::GreaterOp;
        break;

    case T_PLUS_EQUAL:
        kind = OperatorNameId::PlusEqualOp;
        break;

    case T_MINUS_EQUAL:
        kind = OperatorNameId::MinusEqualOp;
        break;

    case T_STAR_EQUAL:
        kind = OperatorNameId::StarEqualOp;
        break;

    case T_SLASH_EQUAL:
        kind = OperatorNameId::SlashEqualOp;
        break;

    case T_PERCENT_EQUAL:
        kind = OperatorNameId::PercentEqualOp;
        break;

    case T_CARET_EQUAL:
        kind = OperatorNameId::CaretEqualOp;
        break;

    case T_AMPER_EQUAL:
        kind = OperatorNameId::AmpEqualOp;
        break;

    case T_PIPE_EQUAL:
        kind = OperatorNameId::PipeEqualOp;
        break;

    case T_LESS_LESS:
        kind = OperatorNameId::LessLessOp;
        break;

    case T_GREATER_GREATER:
        kind = OperatorNameId::GreaterGreaterOp;
        break;

    case T_LESS_LESS_EQUAL:
        kind = OperatorNameId::LessLessEqualOp;
        break;

    case T_GREATER_GREATER_EQUAL:
        kind = OperatorNameId::GreaterGreaterEqualOp;
        break;

    case T_EQUAL_EQUAL:
        kind = OperatorNameId::EqualEqualOp;
        break;

    case T_EXCLAIM_EQUAL:
        kind = OperatorNameId::ExclaimEqualOp;
        break;

    case T_LESS_EQUAL:
        kind = OperatorNameId::LessEqualOp;
        break;

    case T_GREATER_EQUAL:
        kind = OperatorNameId::GreaterEqualOp;
        break;

    case T_AMPER_AMPER:
        kind = OperatorNameId::AmpAmpOp;
        break;

    case T_PIPE_PIPE:
        kind = OperatorNameId::PipePipeOp;
        break;

    case T_PLUS_PLUS:
        kind = OperatorNameId::PlusPlusOp;
        break;

    case T_MINUS_MINUS:
        kind = OperatorNameId::MinusMinusOp;
        break;

    case T_COMMA:
        kind = OperatorNameId::CommaOp;
        break;

    case T_ARROW_STAR:
        kind = OperatorNameId::ArrowStarOp;
        break;

    case T_ARROW:
        kind = OperatorNameId::ArrowOp;
        break;

    case T_LPAREN:
        kind = OperatorNameId::FunctionCallOp;
        break;

    case T_LBRACKET:
        kind = OperatorNameId::ArrayAccessOp;
        break;

    default:
        kind = OperatorNameId::InvalidOp;
    } // switch

    _name = control()->operatorNameId(kind);
    ast->name = _name;
    return false;
}

bool CheckName::visit(ConversionFunctionIdAST *ast)
{
    FullySpecifiedType ty = semantic()->check(ast->type_specifier_list, _scope);
    ty = semantic()->check(ast->ptr_operator_list, ty, _scope);
    _name = control()->conversionNameId(ty);
    return false;
}

bool CheckName::visit(SimpleNameAST *ast)
{
    const Identifier *id = identifier(ast->identifier_token);
    _name = control()->nameId(id);
    ast->name = _name;
    return false;
}

bool CheckName::visit(DestructorNameAST *ast)
{
    const Identifier *id = identifier(ast->identifier_token);
    _name = control()->destructorNameId(id);
    ast->name = _name;
    return false;
}

bool CheckName::visit(TemplateIdAST *ast)
{
    const Identifier *id = identifier(ast->identifier_token);
    std::vector<FullySpecifiedType> templateArguments;
    for (TemplateArgumentListAST *it = ast->template_argument_list; it;
            it = it->next) {
        ExpressionAST *arg = it->value;
        FullySpecifiedType exprTy = semantic()->check(arg, _scope);
        templateArguments.push_back(exprTy);
    }
    if (templateArguments.empty())
        _name = control()->templateNameId(id);
    else
        _name = control()->templateNameId(id, &templateArguments[0],
                                          templateArguments.size());
    ast->name = _name;
    return false;
}

bool CheckName::visit(ObjCSelectorAST *ast)
{
    std::vector<const Name *> names;
    bool hasArgs = false;
    for (ObjCSelectorArgumentListAST *it = ast->selector_argument_list; it; it = it->next) {
        if (it->value->name_token) {
            const Identifier *id = control()->findOrInsertIdentifier(spell(it->value->name_token));
            const NameId *nameId = control()->nameId(id);
            names.push_back(nameId);

            if (!hasArgs && it->value->colon_token)
                hasArgs = true;
        } else {
            // we have an incomplete name due, probably due to error recovery. So, back out completely
            return false;
        }
    }

    if (!names.empty()) {
        _name = control()->selectorNameId(&names[0], names.size(), hasArgs);
        ast->name = _name;
    }

    return false;
}

bool CheckName::visit(ObjCMessageArgumentDeclarationAST *ast)
{
    FullySpecifiedType type;

    if (ast->type_name)
        type = semantic()->check(ast->type_name, _scope);

    if (ast->param_name) {
        accept(ast->param_name);

        Argument *arg = control()->newArgument(ast->param_name->firstToken(),
                                               ast->param_name->name);
        ast->argument = arg;
        arg->setType(type);
        arg->setInitializer(0);
        _scope->enterSymbol(arg);
    }

    return false;
}
<|endoftext|>


<commit_before>//
// Created by salmon on 17-9-18.
//
#include "MPIUpdater.h"
#include <mpi.h>
#include "MPIComm.h"
#include "simpla/SIMPLA_config.h"
#include "simpla/utilities/macro.h"

namespace simpla {
namespace parallel {

struct MPIUpdater::pimpl_s {
    bool m_is_setup_ = false;
    MPI_Comm comm;
    int ndims = 3;
    int mpi_topology_ndims = 0;
    int mpi_dims[3], mpi_periods[3], mpi_coords[3];
    index_box_type local_box_;
    index_box_type send_box[6];
    index_box_type recv_box[6];
    index_tuple m_gw_{2, 2, 2};

    MPI_Datatype ele_type;
    int tag;
    void *send_buffer[6];
    void *recv_buffer[6];
    int send_size[6];
    int recv_size[6];
};
MPIUpdater::MPIUpdater() : m_pimpl_(new pimpl_s) {
    if (GLOBAL_COMM.comm() == MPI_COMM_NULL) { return; }

    m_pimpl_->comm = GLOBAL_COMM.comm();
    if (GLOBAL_COMM.comm() == MPI_COMM_NULL) { return; }
    int tope_type = MPI_CART;
    MPI_CALL(MPI_Topo_test(GLOBAL_COMM.comm(), &tope_type));
    if (tope_type != MPI_CART) { return; }
    int tag = 0;
    MPI_CALL(MPI_Cartdim_get(GLOBAL_COMM.comm(), &m_pimpl_->mpi_topology_ndims));
};
MPIUpdater::~MPIUpdater() { TearDown(); };
void MPIUpdater::SetGhostWidth(index_tuple const &gw) { m_pimpl_->m_gw_ = gw; }
index_tuple MPIUpdater::GetGhostWidth() const { return m_pimpl_->m_gw_; }
void MPIUpdater::SetIndexBox(index_box_type const &idx_box) { m_pimpl_->local_box_ = idx_box; }
index_box_type MPIUpdater::GetIndexBox() const { return m_pimpl_->local_box_; }

bool MPIUpdater::isSetUp() const { return m_pimpl_->m_is_setup_; }
bool MPIUpdater::isEnable() const { return m_pimpl_->comm != MPI_COMM_NULL && GLOBAL_COMM.size() > 1; }

void MPIUpdater::SetUp() {
    m_pimpl_->m_is_setup_ = true;
    int topo_type = MPI_CART;

    MPI_CALL(MPI_Topo_test(m_pimpl_->comm, &topo_type));

    ASSERT(topo_type == MPI_CART);

    MPI_CALL(MPI_Cartdim_get(m_pimpl_->comm, &m_pimpl_->mpi_topology_ndims));

    ASSERT(m_pimpl_->mpi_topology_ndims <= m_pimpl_->ndims);

    MPI_CALL(MPI_Cart_get(m_pimpl_->comm, 3, m_pimpl_->mpi_dims, m_pimpl_->mpi_periods, m_pimpl_->mpi_coords));
    for (int i = 0; i < 6; ++i) {
        m_pimpl_->send_box[i] = m_pimpl_->local_box_;
        m_pimpl_->recv_box[i] = m_pimpl_->local_box_;
    }

    for (int d = 0; d < m_pimpl_->mpi_topology_ndims; ++d) {
        if (m_pimpl_->mpi_dims[d] == 1) {
            std::get<0>(m_pimpl_->send_box[2 * d + 0]) = 0;
            std::get<0>(m_pimpl_->send_box[2 * d + 1]) = 0;
            std::get<0>(m_pimpl_->recv_box[2 * d + 0]) = 0;
            std::get<0>(m_pimpl_->recv_box[2 * d + 1]) = 0;
            std::get<1>(m_pimpl_->send_box[2 * d + 0]) = 0;
            std::get<1>(m_pimpl_->send_box[2 * d + 1]) = 0;
            std::get<1>(m_pimpl_->recv_box[2 * d + 0]) = 0;
            std::get<1>(m_pimpl_->recv_box[2 * d + 1]) = 0;
            continue;
        }

        std::get<0>(m_pimpl_->send_box[2 * d + 0])[d] = std::get<0>(m_pimpl_->local_box_)[d];
        std::get<1>(m_pimpl_->send_box[2 * d + 0])[d] = std::get<0>(m_pimpl_->local_box_)[d] + m_pimpl_->m_gw_[d];

        std::get<0>(m_pimpl_->recv_box[2 * d + 0])[d] = std::get<0>(m_pimpl_->local_box_)[d] - m_pimpl_->m_gw_[d];
        std::get<1>(m_pimpl_->recv_box[2 * d + 0])[d] = std::get<0>(m_pimpl_->local_box_)[d];

        std::get<0>(m_pimpl_->send_box[2 * d + 1])[d] = std::get<1>(m_pimpl_->local_box_)[d] - m_pimpl_->m_gw_[d];
        std::get<1>(m_pimpl_->send_box[2 * d + 1])[d] = std::get<1>(m_pimpl_->local_box_)[d];

        std::get<0>(m_pimpl_->recv_box[2 * d + 1])[d] = std::get<1>(m_pimpl_->local_box_)[d];
        std::get<1>(m_pimpl_->recv_box[2 * d + 1])[d] = std::get<1>(m_pimpl_->local_box_)[d] + m_pimpl_->m_gw_[d];

        //        for (int i = 0; i < d; ++i) {
        //            std::get<0>(m_pimpl_->send_box[2 * d + 0])[i] = std::get<0>(m_pimpl_->local_box_)[i] -
        //            m_pimpl_->m_gw_[i];
        //            std::get<1>(m_pimpl_->send_box[2 * d + 0])[i] = std::get<0>(m_pimpl_->local_box_)[i] +
        //            m_pimpl_->m_gw_[i];
        //
        //            std::get<0>(m_pimpl_->recv_box[2 * d + 0])[i] = std::get<0>(m_pimpl_->local_box_)[i] -
        //            m_pimpl_->m_gw_[i];
        //            std::get<1>(m_pimpl_->recv_box[2 * d + 0])[i] = std::get<0>(m_pimpl_->local_box_)[i] +
        //            m_pimpl_->m_gw_[i];
        //
        //            std::get<0>(m_pimpl_->send_box[2 * d + 1])[i] = std::get<1>(m_pimpl_->local_box_)[i] -
        //            m_pimpl_->m_gw_[i];
        //            std::get<1>(m_pimpl_->send_box[2 * d + 1])[i] = std::get<1>(m_pimpl_->local_box_)[i] +
        //            m_pimpl_->m_gw_[i];
        //
        //            std::get<0>(m_pimpl_->recv_box[2 * d + 1])[i] = std::get<1>(m_pimpl_->local_box_)[i] -
        //            m_pimpl_->m_gw_[i];
        //            std::get<1>(m_pimpl_->recv_box[2 * d + 1])[i] = std::get<1>(m_pimpl_->local_box_)[i] +
        //            m_pimpl_->m_gw_[i];
        //        }
    }

    size_type ele_size = 0;
    if (value_type_info() == typeid(int)) {
        ele_size = sizeof(int);
        m_pimpl_->ele_type = MPI_INT;
    } else if (value_type_info() == typeid(double)) {
        ele_size = sizeof(double);
        m_pimpl_->ele_type = MPI_DOUBLE;
    } else if (value_type_info() == typeid(float)) {
        ele_size = sizeof(float);
        m_pimpl_->ele_type = MPI_FLOAT;
    } else if (value_type_info() == typeid(long)) {
        ele_size = sizeof(long);
        m_pimpl_->ele_type = MPI_LONG;
    } else if (value_type_info() == typeid(unsigned long)) {
        ele_size = sizeof(unsigned long);
        m_pimpl_->ele_type = MPI_UNSIGNED_LONG;
    } else {
        UNIMPLEMENTED;
    }

    for (int i = 0; i < 6; ++i) {
        m_pimpl_->send_size[i] =
            static_cast<int>(std::get<1>(m_pimpl_->send_box[i])[0] - std::get<0>(m_pimpl_->send_box[i])[0]) *
            static_cast<int>(std::get<1>(m_pimpl_->send_box[i])[1] - std::get<0>(m_pimpl_->send_box[i])[1]) *
            static_cast<int>(std::get<1>(m_pimpl_->send_box[i])[2] - std::get<0>(m_pimpl_->send_box[i])[2]);

        m_pimpl_->recv_size[i] =
            static_cast<int>(std::get<1>(m_pimpl_->recv_box[i])[0] - std::get<0>(m_pimpl_->recv_box[i])[0]) *
            static_cast<int>(std::get<1>(m_pimpl_->recv_box[i])[1] - std::get<0>(m_pimpl_->recv_box[i])[1]) *
            static_cast<int>(std::get<1>(m_pimpl_->recv_box[i])[2] - std::get<0>(m_pimpl_->recv_box[i])[2]);

        if (m_pimpl_->send_buffer[i] != nullptr) { delete m_pimpl_->send_buffer[i]; }
        if (m_pimpl_->recv_buffer[i] != nullptr) { delete m_pimpl_->recv_buffer[i]; }

        if (m_pimpl_->send_size[i] > 0) m_pimpl_->send_buffer[i] = operator new(m_pimpl_->send_size[i] * ele_size);
        if (m_pimpl_->recv_size[i] > 0) m_pimpl_->recv_buffer[i] = operator new(m_pimpl_->recv_size[i] * ele_size);
    }

    for (int i = 0; i < 6; ++i) {
        GetSendBuffer(i).reset(m_pimpl_->send_buffer[i], &std::get<0>(m_pimpl_->send_box[i])[0],
                               &std::get<1>(m_pimpl_->send_box[i])[0]);
        GetRecvBuffer(i).reset(m_pimpl_->recv_buffer[i], &std::get<0>(m_pimpl_->recv_box[i])[0],
                               &std::get<1>(m_pimpl_->recv_box[i])[0]);
        GetSendBuffer(i).Clear();
        GetRecvBuffer(i).Clear();
    }
}

void MPIUpdater::TearDown() {
    for (auto *v : m_pimpl_->send_buffer) { delete v; }
    for (auto *v : m_pimpl_->recv_buffer) { delete v; }
    m_pimpl_->m_is_setup_ = false;
}

void MPIUpdater::SetTag(int tag) { m_pimpl_->tag = tag; }

void MPIUpdater::Update(ArrayBase &d) {
    if (!isSetUp()) { return; }
    for (int dir = 0; dir < 3; ++dir) {
        Push(d, dir);
        SendRecv(dir);
        Pop(d, dir);
    }
}

void MPIUpdater::Push(ArrayBase const &d, int direction) {
    if (!isSetUp()) { return; }
    CHECK(GetSendBuffer(2 * direction + 0).CopyIn(d));
    GetSendBuffer(2 * direction + 1).CopyIn(d);
}
void MPIUpdater::Pop(ArrayBase &d, int direction) const {
    if (!isSetUp()) { return; }
    CHECK(d.CopyIn(GetRecvBuffer(2 * direction + 0)));
    d.CopyIn(GetRecvBuffer(2 * direction + 1));
}

void MPIUpdater::SendRecv(int d) {
    if (!isSetUp()) { return; }

    //    for (int d = 0; d < m_pimpl_->mpi_topology_ndims; ++d) {
    int left, right;

    MPI_CALL(MPI_Cart_shift(m_pimpl_->comm, d, 1, &left, &right));

    GLOBAL_COMM.barrier();
    MPI_CALL(MPI_Sendrecv(m_pimpl_->send_buffer[d * 2 + 0], m_pimpl_->send_size[d * 2 + 0], m_pimpl_->ele_type, left,
                          m_pimpl_->tag, m_pimpl_->recv_buffer[d * 2 + 1], m_pimpl_->recv_size[d * 2 + 1],
                          m_pimpl_->ele_type, right, m_pimpl_->tag, m_pimpl_->comm, MPI_STATUS_IGNORE));
    GLOBAL_COMM.barrier();
    MPI_CALL(MPI_Sendrecv(m_pimpl_->send_buffer[d * 2 + 1], m_pimpl_->send_size[d * 2 + 1], m_pimpl_->ele_type, right,
                          m_pimpl_->tag, m_pimpl_->recv_buffer[d * 2 + 0], m_pimpl_->recv_size[d * 2 + 0],
                          m_pimpl_->ele_type, left, m_pimpl_->tag, m_pimpl_->comm, MPI_STATUS_IGNORE));
    GLOBAL_COMM.barrier();
    //    }
}

}  // namespace parallel {
}  // namespace simpla {<commit_msg>MPIUpdater<commit_after>//
// Created by salmon on 17-9-18.
//
#include "MPIUpdater.h"
#include <mpi.h>
#include "MPIComm.h"
#include "simpla/SIMPLA_config.h"
#include "simpla/utilities/macro.h"

namespace simpla {
namespace parallel {

struct MPIUpdater::pimpl_s {
    bool m_is_setup_ = false;
    MPI_Comm comm;
    int ndims = 3;
    int mpi_topology_ndims = 0;
    int mpi_dims[3], mpi_periods[3], mpi_coords[3];
    index_box_type local_box_;
    index_box_type send_box[6];
    index_box_type recv_box[6];
    index_tuple m_gw_{2, 2, 2};

    MPI_Datatype ele_type;
    int tag;
    void *send_buffer[6];
    void *recv_buffer[6];
    int send_size[6];
    int recv_size[6];
};
MPIUpdater::MPIUpdater() : m_pimpl_(new pimpl_s) {
    if (GLOBAL_COMM.comm() == MPI_COMM_NULL) { return; }

    m_pimpl_->comm = GLOBAL_COMM.comm();
    if (GLOBAL_COMM.comm() == MPI_COMM_NULL) { return; }
    int tope_type = MPI_CART;
    MPI_CALL(MPI_Topo_test(GLOBAL_COMM.comm(), &tope_type));
    if (tope_type != MPI_CART) { return; }
    int tag = 0;
    MPI_CALL(MPI_Cartdim_get(GLOBAL_COMM.comm(), &m_pimpl_->mpi_topology_ndims));
};
MPIUpdater::~MPIUpdater() { TearDown(); };
void MPIUpdater::SetGhostWidth(index_tuple const &gw) { m_pimpl_->m_gw_ = gw; }
index_tuple MPIUpdater::GetGhostWidth() const { return m_pimpl_->m_gw_; }
void MPIUpdater::SetIndexBox(index_box_type const &idx_box) { m_pimpl_->local_box_ = idx_box; }
index_box_type MPIUpdater::GetIndexBox() const { return m_pimpl_->local_box_; }

bool MPIUpdater::isSetUp() const { return m_pimpl_->m_is_setup_; }
bool MPIUpdater::isEnable() const { return m_pimpl_->comm != MPI_COMM_NULL && GLOBAL_COMM.size() > 1; }

void MPIUpdater::SetUp() {
    m_pimpl_->m_is_setup_ = true;
    int topo_type = MPI_CART;

    MPI_CALL(MPI_Topo_test(m_pimpl_->comm, &topo_type));

    ASSERT(topo_type == MPI_CART);

    MPI_CALL(MPI_Cartdim_get(m_pimpl_->comm, &m_pimpl_->mpi_topology_ndims));

    ASSERT(m_pimpl_->mpi_topology_ndims <= m_pimpl_->ndims);

    MPI_CALL(MPI_Cart_get(m_pimpl_->comm, 3, m_pimpl_->mpi_dims, m_pimpl_->mpi_periods, m_pimpl_->mpi_coords));
    for (int i = 0; i < 6; ++i) {
        m_pimpl_->send_box[i] = m_pimpl_->local_box_;
        m_pimpl_->recv_box[i] = m_pimpl_->local_box_;
    }

    for (int d = 0; d < m_pimpl_->mpi_topology_ndims; ++d) {
        if (m_pimpl_->mpi_dims[d] == 1) {
            std::get<0>(m_pimpl_->send_box[2 * d + 0]) = 0;
            std::get<0>(m_pimpl_->send_box[2 * d + 1]) = 0;
            std::get<0>(m_pimpl_->recv_box[2 * d + 0]) = 0;
            std::get<0>(m_pimpl_->recv_box[2 * d + 1]) = 0;
            std::get<1>(m_pimpl_->send_box[2 * d + 0]) = 0;
            std::get<1>(m_pimpl_->send_box[2 * d + 1]) = 0;
            std::get<1>(m_pimpl_->recv_box[2 * d + 0]) = 0;
            std::get<1>(m_pimpl_->recv_box[2 * d + 1]) = 0;
            continue;
        }

        std::get<0>(m_pimpl_->send_box[2 * d + 0])[d] = std::get<0>(m_pimpl_->local_box_)[d];
        std::get<1>(m_pimpl_->send_box[2 * d + 0])[d] = std::get<0>(m_pimpl_->local_box_)[d] + m_pimpl_->m_gw_[d];

        std::get<0>(m_pimpl_->recv_box[2 * d + 0])[d] = std::get<0>(m_pimpl_->local_box_)[d] - m_pimpl_->m_gw_[d];
        std::get<1>(m_pimpl_->recv_box[2 * d + 0])[d] = std::get<0>(m_pimpl_->local_box_)[d];

        std::get<0>(m_pimpl_->send_box[2 * d + 1])[d] = std::get<1>(m_pimpl_->local_box_)[d] - m_pimpl_->m_gw_[d];
        std::get<1>(m_pimpl_->send_box[2 * d + 1])[d] = std::get<1>(m_pimpl_->local_box_)[d];

        std::get<0>(m_pimpl_->recv_box[2 * d + 1])[d] = std::get<1>(m_pimpl_->local_box_)[d];
        std::get<1>(m_pimpl_->recv_box[2 * d + 1])[d] = std::get<1>(m_pimpl_->local_box_)[d] + m_pimpl_->m_gw_[d];

        for (int i = 0; i < d; ++i) {
            std::get<0>(m_pimpl_->send_box[2 * d + 0])[i] = std::get<0>(m_pimpl_->local_box_)[i] - m_pimpl_->m_gw_[i];
            std::get<1>(m_pimpl_->send_box[2 * d + 0])[i] = std::get<1>(m_pimpl_->local_box_)[i] + m_pimpl_->m_gw_[i];

            std::get<0>(m_pimpl_->recv_box[2 * d + 0])[i] = std::get<0>(m_pimpl_->local_box_)[i] - m_pimpl_->m_gw_[i];
            std::get<1>(m_pimpl_->recv_box[2 * d + 0])[i] = std::get<1>(m_pimpl_->local_box_)[i] + m_pimpl_->m_gw_[i];

            std::get<0>(m_pimpl_->send_box[2 * d + 1])[i] = std::get<0>(m_pimpl_->local_box_)[i] - m_pimpl_->m_gw_[i];
            std::get<1>(m_pimpl_->send_box[2 * d + 1])[i] = std::get<1>(m_pimpl_->local_box_)[i] + m_pimpl_->m_gw_[i];

            std::get<0>(m_pimpl_->recv_box[2 * d + 1])[i] = std::get<0>(m_pimpl_->local_box_)[i] - m_pimpl_->m_gw_[i];
            std::get<1>(m_pimpl_->recv_box[2 * d + 1])[i] = std::get<1>(m_pimpl_->local_box_)[i] + m_pimpl_->m_gw_[i];
        }
    }

    size_type ele_size = 0;
    if (value_type_info() == typeid(int)) {
        ele_size = sizeof(int);
        m_pimpl_->ele_type = MPI_INT;
    } else if (value_type_info() == typeid(double)) {
        ele_size = sizeof(double);
        m_pimpl_->ele_type = MPI_DOUBLE;
    } else if (value_type_info() == typeid(float)) {
        ele_size = sizeof(float);
        m_pimpl_->ele_type = MPI_FLOAT;
    } else if (value_type_info() == typeid(long)) {
        ele_size = sizeof(long);
        m_pimpl_->ele_type = MPI_LONG;
    } else if (value_type_info() == typeid(unsigned long)) {
        ele_size = sizeof(unsigned long);
        m_pimpl_->ele_type = MPI_UNSIGNED_LONG;
    } else {
        UNIMPLEMENTED;
    }

    for (int i = 0; i < 6; ++i) {
        m_pimpl_->send_size[i] =
            static_cast<int>(std::get<1>(m_pimpl_->send_box[i])[0] - std::get<0>(m_pimpl_->send_box[i])[0]) *
            static_cast<int>(std::get<1>(m_pimpl_->send_box[i])[1] - std::get<0>(m_pimpl_->send_box[i])[1]) *
            static_cast<int>(std::get<1>(m_pimpl_->send_box[i])[2] - std::get<0>(m_pimpl_->send_box[i])[2]);

        m_pimpl_->recv_size[i] =
            static_cast<int>(std::get<1>(m_pimpl_->recv_box[i])[0] - std::get<0>(m_pimpl_->recv_box[i])[0]) *
            static_cast<int>(std::get<1>(m_pimpl_->recv_box[i])[1] - std::get<0>(m_pimpl_->recv_box[i])[1]) *
            static_cast<int>(std::get<1>(m_pimpl_->recv_box[i])[2] - std::get<0>(m_pimpl_->recv_box[i])[2]);

        if (m_pimpl_->send_buffer[i] != nullptr) { delete m_pimpl_->send_buffer[i]; }
        if (m_pimpl_->recv_buffer[i] != nullptr) { delete m_pimpl_->recv_buffer[i]; }

        if (m_pimpl_->send_size[i] > 0) m_pimpl_->send_buffer[i] = operator new(m_pimpl_->send_size[i] * ele_size);
        if (m_pimpl_->recv_size[i] > 0) m_pimpl_->recv_buffer[i] = operator new(m_pimpl_->recv_size[i] * ele_size);
    }

    for (int i = 0; i < 6; ++i) {
        GetSendBuffer(i).reset(m_pimpl_->send_buffer[i], &std::get<0>(m_pimpl_->send_box[i])[0],
                               &std::get<1>(m_pimpl_->send_box[i])[0]);
        GetRecvBuffer(i).reset(m_pimpl_->recv_buffer[i], &std::get<0>(m_pimpl_->recv_box[i])[0],
                               &std::get<1>(m_pimpl_->recv_box[i])[0]);
        GetSendBuffer(i).Clear();
        GetRecvBuffer(i).Clear();
    }
}

void MPIUpdater::TearDown() {
    for (auto *v : m_pimpl_->send_buffer) { delete v; }
    for (auto *v : m_pimpl_->recv_buffer) { delete v; }
    m_pimpl_->m_is_setup_ = false;
}

void MPIUpdater::SetTag(int tag) { m_pimpl_->tag = tag; }

void MPIUpdater::Update(ArrayBase &d) {
    if (!isSetUp()) { return; }
    for (int dir = 0; dir < 3; ++dir) {
        Push(d, dir);
        SendRecv(dir);
        Pop(d, dir);
    }
}

void MPIUpdater::Push(ArrayBase const &d, int direction) {
    if (!isSetUp()) { return; }
    CHECK(GetSendBuffer(2 * direction + 0).CopyIn(d));
    GetSendBuffer(2 * direction + 1).CopyIn(d);
}
void MPIUpdater::Pop(ArrayBase &d, int direction) const {
    if (!isSetUp()) { return; }
    CHECK(d.CopyIn(GetRecvBuffer(2 * direction + 0)));
    d.CopyIn(GetRecvBuffer(2 * direction + 1));
}

void MPIUpdater::SendRecv(int d) {
    if (!isSetUp()) { return; }

    //    for (int d = 0; d < m_pimpl_->mpi_topology_ndims; ++d) {
    int left, right;

    MPI_CALL(MPI_Cart_shift(m_pimpl_->comm, d, 1, &left, &right));

    GLOBAL_COMM.barrier();
    MPI_CALL(MPI_Sendrecv(m_pimpl_->send_buffer[d * 2 + 0], m_pimpl_->send_size[d * 2 + 0], m_pimpl_->ele_type, left,
                          m_pimpl_->tag, m_pimpl_->recv_buffer[d * 2 + 1], m_pimpl_->recv_size[d * 2 + 1],
                          m_pimpl_->ele_type, right, m_pimpl_->tag, m_pimpl_->comm, MPI_STATUS_IGNORE));
    GLOBAL_COMM.barrier();
    MPI_CALL(MPI_Sendrecv(m_pimpl_->send_buffer[d * 2 + 1], m_pimpl_->send_size[d * 2 + 1], m_pimpl_->ele_type, right,
                          m_pimpl_->tag, m_pimpl_->recv_buffer[d * 2 + 0], m_pimpl_->recv_size[d * 2 + 0],
                          m_pimpl_->ele_type, left, m_pimpl_->tag, m_pimpl_->comm, MPI_STATUS_IGNORE));
    GLOBAL_COMM.barrier();
    //    }
}

}  // namespace parallel {
}  // namespace simpla {<|endoftext|>


<commit_before>#include <hop_bits/optimisationAlgorithm/covarianceMatrixAdaptationEvolutionStrategy.hpp>

namespace hop {
  CovarianceMatrixAdaptationEvolutionStrategy::CovarianceMatrixAdaptationEvolutionStrategy(const std::shared_ptr<OptimisationProblem> optimisationProblem) : OptimisationAlgorithm(optimisationProblem) {
    // init input parameters
    // TODO: iteration number gets multiplied with dimensions² on wiki, also do that here?
  }

  void CovarianceMatrixAdaptationEvolutionStrategy::optimiseImplementation() {
    unsigned int numberOfDimensions = optimisationProblem_->getNumberOfDimensions();

    arma::Col<double> objectiveValues = arma::randu<arma::vec>(numberOfDimensions);
    double sigma = 0.3;
    double stopValue = 1e-10;
    //init selection parameters
    unsigned int lambda = 4 + std::floor(3 * std::log(numberOfDimensions));
    double mu = lambda / 2;
    arma::Col<double> weights = arma::Col<double>(mu);

    for(std::size_t n = 0; n < weights.n_elem; ++n) {
      weights.at(n) = std::log(mu + 0.5) - std::log(n);
    }

    mu = std::floor(mu);
    weights = weights / arma::sum(weights);
    double mueff = std::pow(arma::sum(weights), 2) / arma::sum(arma::square(weights));
    //init adaptation parameters
    double cc = (4 + mueff / numberOfDimensions) / (numberOfDimensions + 4 + 2 * mueff / numberOfDimensions);
    double cs = (mueff+2) / (numberOfDimensions + mueff + 5);
    double c1 = 2 / (std::pow(numberOfDimensions + 1.3, 2) + mueff);
    double cmu = std::min(1 - c1, 2 * (mueff - 2 + 1 / mueff) / (std::pow(numberOfDimensions + 2, 2) + mueff));
    double damps = 1 + 2 * std::max(0.0, std::sqrt((mueff - 1) / (numberOfDimensions + 1)) - 1) + cs;
    //init dynamic parameters and constants
    arma::Col<double> pc(numberOfDimensions, arma::fill::zeros);
    arma::Col<double> ps(numberOfDimensions, arma::fill::zeros);
    arma::Mat<double> B(numberOfDimensions, numberOfDimensions, arma::fill::eye);
    arma::Col<double> D(numberOfDimensions, arma::fill::ones);
    arma::Mat<double> C(numberOfDimensions, numberOfDimensions, arma::fill::eye);
    arma::Mat<double> invsqrtC(numberOfDimensions, numberOfDimensions, arma::fill::eye);
    double eigeneval = 0;
    double chiN = std::sqrt(numberOfDimensions) * (1 - 1 / (4 * numberOfDimensions) + 1 / (21 * std::pow(numberOfDimensions, 2)));

    while(!isFinished() && !isTerminated()) {
      //generate and evaluate lambda offspring
      arma::Col<double> arfitness = arma::Col<double>(lambda);
      arma::Mat<double> arx = arma::Mat<double>(numberOfDimensions, lambda);
      for(std::size_t n = 0; n < lambda; ++n) {
        arx.col(n) = objectiveValues + sigma * B * (D % arma::randn<arma::Col<double>>(numberOfDimensions));
        arfitness(n) = optimisationProblem_->getObjectiveValue(arx.col(n));
        ++numberOfIterations_;
      }
      //sort by fitness and compute weighted mean into objectiveValues
      arma::Col<arma::uword> arindex = arma::sort_index(arfitness);
      arma::Col<double> oldObjectiveValues = objectiveValues;
      //next line should be unnecessary, depending on if arma returns a copy or not in the line after that
      objectiveValues = arma::Col<double>(numberOfDimensions);
      //TODO: xmean = arx(:,arindex(1:mu))*weights;
      //is the actual matlab syntax for the following line, not a 100% sure if this is correct
      objectiveValues = arx.cols(arindex) * weights;

      //cumulation: update evolution paths
      ps = (1 - cs) * ps + std::sqrt(cs * (2 - cs) * mueff) * invsqrtC * (objectiveValues - oldObjectiveValues) / sigma;
      int hsig = arma::norm(ps) / std::sqrt(std::pow(1 - (1 - cs), 2 * numberOfIterations_ / lambda)) / chiN < 1.4 + 2 / (numberOfDimensions + 1);
      pc = (1 - cc) * pc + hsig * std::sqrt(cc * (2-cc) * mueff) * (objectiveValues - oldObjectiveValues) / sigma;

      //adapt covariance matrix C
      arma::Mat<double> artmp = (1 / sigma) * arx.cols(arindex) - arma::repmat(oldObjectiveValues, 1, mu);
      C = (1-c1-cmu) * C + //old matrix
              c1 * (pc*pc.t() + //rank one update
                     (1-hsig) * cc * (2-cc) * C) + //correction for hsig==0
              cmu * artmp * arma::diagmat(weights) * artmp.t(); // rank mu update

      //adapt step size sigma
      sigma = sigma * std::exp((cs / damps) * (arma::norm(ps) / chiN - 1));

      //decomposition of C into B*diag(D.^2)*B' (diagonalization)
      if((numberOfIterations_ - eigeneval) > (lambda / (c1 + cmu) / numberOfIterations_ / 10)) {
        eigeneval = numberOfIterations_;
        //TODO: C = triu(C) + triu(C,1)';
        //is the actual matlab syntax for the next lines, unfortunately arma doesn't have triu with a second parameter (yet)
        arma::Mat<double> tempC = arma::trimatu(C);
        tempC.diag().zeros();
        C = arma::trimatu(C) + tempC.t(); //enforce symmetry
        //matlab code is [B,D] = eig(C); arma uses switched arguments according to API
        arma::Col<double> tempD = arma::Col<double>();
        arma::eig_sym(tempD, B, C);
        D = arma::sqrt(arma::diagmat(tempD)); // TODO: From wiki "D is a vector of standard deviations now" which it obviously isn't here.
                                              // also not sure what the point of that is, since it's going to be used as a matrix in the next line anyway.
        invsqrtC = B * arma::diagmat(1 / D) * B.t();
      }

        //break, if fitness is good enough or condition exceeds 1e14, better termination methods are advisable
      if(arfitness.at(1) <= stopValue || D.max() / D.min() > 1e7) {
        break;
      }
    }
    //while loop has ended

    //TODO: matlab returns xmin = arx(:, arindex(1));
    //not sure where to safe our return value?
  }

  std::string CovarianceMatrixAdaptationEvolutionStrategy::to_string() const {
    return "CovarianceMatrixAdaptationEvolutionStrategy";
  }
}
<commit_msg>devel: Removed extra stop condition<commit_after>#include <hop_bits/optimisationAlgorithm/covarianceMatrixAdaptationEvolutionStrategy.hpp>

namespace hop {
  CovarianceMatrixAdaptationEvolutionStrategy::CovarianceMatrixAdaptationEvolutionStrategy(const std::shared_ptr<OptimisationProblem> optimisationProblem) : OptimisationAlgorithm(optimisationProblem) {
    // init input parameters
    // TODO: iteration number gets multiplied with dimensions² on wiki, also do that here?
  }

  void CovarianceMatrixAdaptationEvolutionStrategy::optimiseImplementation() {
    unsigned int numberOfDimensions = optimisationProblem_->getNumberOfDimensions();

    arma::Col<double> objectiveValues = arma::randu<arma::vec>(numberOfDimensions);
    double sigma = 0.3;
    //init selection parameters
    unsigned int lambda = 4 + std::floor(3 * std::log(numberOfDimensions));
    double mu = lambda / 2;
    arma::Col<double> weights = arma::Col<double>(mu);

    for(std::size_t n = 0; n < weights.n_elem; ++n) {
      weights.at(n) = std::log(mu + 0.5) - std::log(n);
    }

    mu = std::floor(mu);
    weights = weights / arma::sum(weights);
    double mueff = std::pow(arma::sum(weights), 2) / arma::sum(arma::square(weights));
    //init adaptation parameters
    double cc = (4 + mueff / numberOfDimensions) / (numberOfDimensions + 4 + 2 * mueff / numberOfDimensions);
    double cs = (mueff+2) / (numberOfDimensions + mueff + 5);
    double c1 = 2 / (std::pow(numberOfDimensions + 1.3, 2) + mueff);
    double cmu = std::min(1 - c1, 2 * (mueff - 2 + 1 / mueff) / (std::pow(numberOfDimensions + 2, 2) + mueff));
    double damps = 1 + 2 * std::max(0.0, std::sqrt((mueff - 1) / (numberOfDimensions + 1)) - 1) + cs;
    //init dynamic parameters and constants
    arma::Col<double> pc(numberOfDimensions, arma::fill::zeros);
    arma::Col<double> ps(numberOfDimensions, arma::fill::zeros);
    arma::Mat<double> B(numberOfDimensions, numberOfDimensions, arma::fill::eye);
    arma::Col<double> D(numberOfDimensions, arma::fill::ones);
    arma::Mat<double> C(numberOfDimensions, numberOfDimensions, arma::fill::eye);
    arma::Mat<double> invsqrtC(numberOfDimensions, numberOfDimensions, arma::fill::eye);
    double eigeneval = 0;
    double chiN = std::sqrt(numberOfDimensions) * (1 - 1 / (4 * numberOfDimensions) + 1 / (21 * std::pow(numberOfDimensions, 2)));

    while(!isFinished() && !isTerminated()) {
      //generate and evaluate lambda offspring
      arma::Col<double> arfitness = arma::Col<double>(lambda);
      arma::Mat<double> arx = arma::Mat<double>(numberOfDimensions, lambda);
      for(std::size_t n = 0; n < lambda; ++n) {
        arx.col(n) = objectiveValues + sigma * B * (D % arma::randn<arma::Col<double>>(numberOfDimensions));
        arfitness(n) = optimisationProblem_->getObjectiveValue(arx.col(n));
        ++numberOfIterations_;
      }
      //sort by fitness and compute weighted mean into objectiveValues
      arma::Col<arma::uword> arindex = arma::sort_index(arfitness);
      arma::Col<double> oldObjectiveValues = objectiveValues;
      //next line should be unnecessary, depending on if arma returns a copy or not in the line after that
      objectiveValues = arma::Col<double>(numberOfDimensions);
      //TODO: xmean = arx(:,arindex(1:mu))*weights;
      //is the actual matlab syntax for the following line, not a 100% sure if this is correct
      objectiveValues = arx.cols(arindex) * weights;

      //cumulation: update evolution paths
      ps = (1 - cs) * ps + std::sqrt(cs * (2 - cs) * mueff) * invsqrtC * (objectiveValues - oldObjectiveValues) / sigma;
      int hsig = arma::norm(ps) / std::sqrt(std::pow(1 - (1 - cs), 2 * numberOfIterations_ / lambda)) / chiN < 1.4 + 2 / (numberOfDimensions + 1);
      pc = (1 - cc) * pc + hsig * std::sqrt(cc * (2-cc) * mueff) * (objectiveValues - oldObjectiveValues) / sigma;

      //adapt covariance matrix C
      arma::Mat<double> artmp = (1 / sigma) * arx.cols(arindex) - arma::repmat(oldObjectiveValues, 1, mu);
      C = (1-c1-cmu) * C + //old matrix
              c1 * (pc*pc.t() + //rank one update
                     (1-hsig) * cc * (2-cc) * C) + //correction for hsig==0
              cmu * artmp * arma::diagmat(weights) * artmp.t(); // rank mu update

      //adapt step size sigma
      sigma = sigma * std::exp((cs / damps) * (arma::norm(ps) / chiN - 1));

      //decomposition of C into B*diag(D.^2)*B' (diagonalization)
      if((numberOfIterations_ - eigeneval) > (lambda / (c1 + cmu) / numberOfIterations_ / 10)) {
        eigeneval = numberOfIterations_;
        //TODO: C = triu(C) + triu(C,1)';
        //is the actual matlab syntax for the next lines, unfortunately arma doesn't have triu with a second parameter (yet)
        arma::Mat<double> tempC = arma::trimatu(C);
        tempC.diag().zeros();
        C = arma::trimatu(C) + tempC.t(); //enforce symmetry
        //matlab code is [B,D] = eig(C); arma uses switched arguments according to API
        arma::Col<double> tempD = arma::Col<double>();
        arma::eig_sym(tempD, B, C);
        D = arma::sqrt(arma::diagmat(tempD)); // TODO: From wiki "D is a vector of standard deviations now" which it obviously isn't here.
                                              // also not sure what the point of that is, since it's going to be used as a matrix in the next line anyway.
        invsqrtC = B * arma::diagmat(1 / D) * B.t();
      }
    }
    //while loop has ended

    //TODO: matlab returns xmin = arx(:, arindex(1));
    //not sure where to safe our return value?
  }

  std::string CovarianceMatrixAdaptationEvolutionStrategy::to_string() const {
    return "CovarianceMatrixAdaptationEvolutionStrategy";
  }
}
<|endoftext|>


<commit_before>#include <QtTest>
#include <QtJsonSerializer>

#include "typeconvertertestbase.h"

#include <QtJsonSerializer/private/datetimeconverter_p.h>
using namespace QtJsonSerializer;
using namespace QtJsonSerializer::TypeConverters;

class DateTimeConverterTest : public TypeConverterTestBase
{
	Q_OBJECT

protected:
	TypeConverter *converter() override;
	void addConverterData() override;
	void addMetaData() override;
	void addCommonSerData() override;
	void addSerData() override;
	void addDeserData() override;

private:
	DateTimeConverter _converter;
};

TypeConverter *DateTimeConverterTest::converter()
{
	return &_converter;
}

void DateTimeConverterTest::addConverterData()
{
	QTest::newRow("datetime") << static_cast<int>(TypeConverter::Standard);
}

void DateTimeConverterTest::addMetaData()
{
	QTest::newRow("dt.string") << static_cast<int>(QMetaType::QDateTime)
							   << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
							   << QCborValue::String
							   << true
							   << TypeConverter::DeserializationCapabilityResult::Positive;
	QTest::newRow("dt.string.guessed") << static_cast<int>(QMetaType::UnknownType)
									   << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
									   << QCborValue::String
									   << false
									   << TypeConverter::DeserializationCapabilityResult::Guessed;
	QTest::newRow("dt.string.invalid") << static_cast<int>(QMetaType::QDateTime)
									   << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
									   << QCborValue::Integer
									   << true
									   << TypeConverter::DeserializationCapabilityResult::Negative;

	QTest::newRow("dt.tstamp") << static_cast<int>(QMetaType::QDateTime)
							   << static_cast<QCborTag>(QCborKnownTags::UnixTime_t)
							   << QCborValue::Integer
							   << true
							   << TypeConverter::DeserializationCapabilityResult::Positive;
	QTest::newRow("dt.tstamp.guessed") << static_cast<int>(QMetaType::UnknownType)
									   << static_cast<QCborTag>(QCborKnownTags::UnixTime_t)
									   << QCborValue::Integer
									   << false
									   << TypeConverter::DeserializationCapabilityResult::Guessed;
	QTest::newRow("dt.tstamp.invalid") << static_cast<int>(QMetaType::QDateTime)
									   << static_cast<QCborTag>(QCborKnownTags::UnixTime_t)
									   << QCborValue::String
									   << true
									   << TypeConverter::DeserializationCapabilityResult::Negative;

	QTest::newRow("date.date") << static_cast<int>(QMetaType::QDate)
							   << static_cast<QCborTag>(CborSerializer::Date)
							   << QCborValue::String
							   << true
							   << TypeConverter::DeserializationCapabilityResult::Positive;
	QTest::newRow("date.date.guessed") << static_cast<int>(QMetaType::UnknownType)
									   << static_cast<QCborTag>(CborSerializer::Date)
									   << QCborValue::String
									   << false
									   << TypeConverter::DeserializationCapabilityResult::Guessed;
	QTest::newRow("date.date.invalid") << static_cast<int>(QMetaType::QDate)
									   << static_cast<QCborTag>(CborSerializer::Date)
									   << QCborValue::Integer
									   << true
									   << TypeConverter::DeserializationCapabilityResult::Negative;
	QTest::newRow("date.dt") << static_cast<int>(QMetaType::QDate)
							 << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
							 << QCborValue::String
							 << true
							 << TypeConverter::DeserializationCapabilityResult::Positive;
	QTest::newRow("date.dt.invalid") << static_cast<int>(QMetaType::QDate)
									 << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
									 << QCborValue::Integer
									 << true
									 << TypeConverter::DeserializationCapabilityResult::Negative;

	QTest::newRow("time.time") << static_cast<int>(QMetaType::QTime)
							   << static_cast<QCborTag>(CborSerializer::Time)
							   << QCborValue::String
							   << true
							   << TypeConverter::DeserializationCapabilityResult::Positive;
	QTest::newRow("time.time.guessed") << static_cast<int>(QMetaType::UnknownType)
									   << static_cast<QCborTag>(CborSerializer::Time)
									   << QCborValue::String
									   << false
									   << TypeConverter::DeserializationCapabilityResult::Guessed;
	QTest::newRow("time.time.invalid") << static_cast<int>(QMetaType::QTime)
									   << static_cast<QCborTag>(CborSerializer::Time)
									   << QCborValue::Integer
									   << true
									   << TypeConverter::DeserializationCapabilityResult::Negative;
	QTest::newRow("time.dt") << static_cast<int>(QMetaType::QTime)
							 << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
							 << QCborValue::String
							 << true
							 << TypeConverter::DeserializationCapabilityResult::Positive;
	QTest::newRow("time.dt.invalid") << static_cast<int>(QMetaType::QTime)
									 << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
									 << QCborValue::Integer
									 << true
									 << TypeConverter::DeserializationCapabilityResult::Negative;

	QTest::newRow("invalid.type") << static_cast<int>(QMetaType::QString)
								  << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
								  << QCborValue::String
								  << false
								  << TypeConverter::DeserializationCapabilityResult::Negative;
	QTest::newRow("invalid.tag.dt") << static_cast<int>(QMetaType::QDateTime)
									<< static_cast<QCborTag>(CborSerializer::Date)
									<< QCborValue::String
									<< true
									<< TypeConverter::DeserializationCapabilityResult::WrongTag;
	QTest::newRow("invalid.tag.date") << static_cast<int>(QMetaType::QDate)
									  << static_cast<QCborTag>(CborSerializer::Time)
									  << QCborValue::String
									  << true
									  << TypeConverter::DeserializationCapabilityResult::WrongTag;
	QTest::newRow("invalid.tag.time") << static_cast<int>(QMetaType::QTime)
									  << static_cast<QCborTag>(CborSerializer::Date)
									  << QCborValue::String
									  << true
									  << TypeConverter::DeserializationCapabilityResult::WrongTag;

}

void DateTimeConverterTest::addCommonSerData()
{
	QTest::newRow("datetime.string") << QVariantHash{}
									 << TestQ{}
									 << static_cast<QObject*>(nullptr)
									 << static_cast<int>(QMetaType::QDateTime)
									 << QVariant{QDateTime{{2019, 1, 3}, {13, 42, 15, 563}}}
									 << QCborValue{QDateTime{{2019, 1, 3}, {13, 42, 15, 563}}}
									 << QJsonValue{QStringLiteral("2019-01-03T13:42:15.563")};
	QTest::newRow("datetime.string.empty") << QVariantHash{}
										   << TestQ{}
										   << static_cast<QObject*>(nullptr)
										   << static_cast<int>(QMetaType::QDateTime)
										   << QVariant{QDateTime{}}
										   << QCborValue{QDateTime{}}
										   << QJsonValue{QString{}};
	QTest::newRow("datetime.string.tag") << QVariantHash{}
										 << TestQ{}
										 << static_cast<QObject*>(nullptr)
										 << static_cast<int>(QMetaType::QDateTime)
										 << QVariant{QDateTime{{2019, 1, 3}, {13, 42, 15, 563}}}
										 << QCborValue{QCborKnownTags::DateTimeString, QStringLiteral("2019-01-03T13:42:15.563")}
										 << QJsonValue{QJsonValue::Undefined};
	QTest::newRow("datetime.tstamp") << QVariantHash{{QStringLiteral("dateAsTimeStamp"), true}}
									 << TestQ{}
									 << static_cast<QObject*>(nullptr)
									 << static_cast<int>(QMetaType::QDateTime)
									 << QVariant{QDateTime{{2019, 1, 3}, {13, 42, 15}}}
									 << QCborValue{QCborKnownTags::UnixTime_t, 1546519335ll}
									 << QJsonValue{1546519335ll};

	QTest::newRow("date.datestr") << QVariantHash{}
								  << TestQ{}
								  << static_cast<QObject*>(nullptr)
								  << static_cast<int>(QMetaType::QDate)
								  << QVariant{QDate{2019, 1, 3}}
								  << QCborValue{static_cast<QCborTag>(CborSerializer::Date), QStringLiteral("2019-01-03")}
								  << QJsonValue{QStringLiteral("2019-01-03")};
	QTest::newRow("date.datestr.empty") << QVariantHash{}
										<< TestQ{}
										<< static_cast<QObject*>(nullptr)
										<< static_cast<int>(QMetaType::QDate)
										<< QVariant{QDate{}}
										<< QCborValue{static_cast<QCborTag>(CborSerializer::Date), QString{}}
										<< QJsonValue{QString{}};

	QTest::newRow("time.timestr") << QVariantHash{}
								  << TestQ{}
								  << static_cast<QObject*>(nullptr)
								  << static_cast<int>(QMetaType::QTime)
								  << QVariant{QTime{13, 42, 15, 563}}
								  << QCborValue{static_cast<QCborTag>(CborSerializer::Time), QStringLiteral("13:42:15.563")}
								  << QJsonValue{QStringLiteral("13:42:15.563")};
	QTest::newRow("time.timestr.empty") << QVariantHash{}
										<< TestQ{}
										<< static_cast<QObject*>(nullptr)
										<< static_cast<int>(QMetaType::QTime)
										<< QVariant{QTime{}}
										<< QCborValue{static_cast<QCborTag>(CborSerializer::Time), QString{}}
										<< QJsonValue{QString{}};
}

void DateTimeConverterTest::addSerData()
{
	QTest::newRow("datetime.tstamp.empty") << QVariantHash{{QStringLiteral("dateAsTimeStamp"), true}}
										   << TestQ{}
										   << static_cast<QObject*>(nullptr)
										   << static_cast<int>(QMetaType::QDateTime)
										   << QVariant{QDateTime{}}
										   << QCborValue{QCborKnownTags::UnixTime_t, 0ll}
										   << QJsonValue{0ll};
}

void DateTimeConverterTest::addDeserData()
{
	QTest::newRow("datetime.tstamp.empty") << QVariantHash{{QStringLiteral("dateAsTimeStamp"), true}}
										   << TestQ{}
										   << static_cast<QObject*>(nullptr)
										   << static_cast<int>(QMetaType::QDateTime)
										   << QVariant{QDateTime::fromMSecsSinceEpoch(0, Qt::UTC).toLocalTime()}
										   << QCborValue{QCborKnownTags::UnixTime_t, 0ll}
										   << QJsonValue{0ll};

	QTest::newRow("date.dtstr") << QVariantHash{}
								<< TestQ{}
								<< static_cast<QObject*>(nullptr)
								<< static_cast<int>(QMetaType::QDate)
								<< QVariant{QDate{2019, 1, 3}}
								<< QCborValue{QCborKnownTags::DateTimeString, QStringLiteral("2019-01-03T00:00:00.000")}
								<< QJsonValue{QJsonValue::Undefined};

	QTest::newRow("time.dtstr") << QVariantHash{}
								<< TestQ{}
								<< static_cast<QObject*>(nullptr)
								<< static_cast<int>(QMetaType::QTime)
								<< QVariant{QTime{13, 42, 15, 563}}
								<< QCborValue{QCborKnownTags::DateTimeString, QStringLiteral("1970-01-01T13:42:15.563")}
								<< QJsonValue{QJsonValue::Undefined};
}

QTEST_MAIN(DateTimeConverterTest)

#include "tst_datetimeconverter.moc"
<commit_msg>use utc for timestamp comparison<commit_after>#include <QtTest>
#include <QtJsonSerializer>

#include "typeconvertertestbase.h"

#include <QtJsonSerializer/private/datetimeconverter_p.h>
using namespace QtJsonSerializer;
using namespace QtJsonSerializer::TypeConverters;

class DateTimeConverterTest : public TypeConverterTestBase
{
	Q_OBJECT

protected:
	TypeConverter *converter() override;
	void addConverterData() override;
	void addMetaData() override;
	void addCommonSerData() override;
	void addSerData() override;
	void addDeserData() override;

private:
	DateTimeConverter _converter;
};

TypeConverter *DateTimeConverterTest::converter()
{
	return &_converter;
}

void DateTimeConverterTest::addConverterData()
{
	QTest::newRow("datetime") << static_cast<int>(TypeConverter::Standard);
}

void DateTimeConverterTest::addMetaData()
{
	QTest::newRow("dt.string") << static_cast<int>(QMetaType::QDateTime)
							   << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
							   << QCborValue::String
							   << true
							   << TypeConverter::DeserializationCapabilityResult::Positive;
	QTest::newRow("dt.string.guessed") << static_cast<int>(QMetaType::UnknownType)
									   << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
									   << QCborValue::String
									   << false
									   << TypeConverter::DeserializationCapabilityResult::Guessed;
	QTest::newRow("dt.string.invalid") << static_cast<int>(QMetaType::QDateTime)
									   << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
									   << QCborValue::Integer
									   << true
									   << TypeConverter::DeserializationCapabilityResult::Negative;

	QTest::newRow("dt.tstamp") << static_cast<int>(QMetaType::QDateTime)
							   << static_cast<QCborTag>(QCborKnownTags::UnixTime_t)
							   << QCborValue::Integer
							   << true
							   << TypeConverter::DeserializationCapabilityResult::Positive;
	QTest::newRow("dt.tstamp.guessed") << static_cast<int>(QMetaType::UnknownType)
									   << static_cast<QCborTag>(QCborKnownTags::UnixTime_t)
									   << QCborValue::Integer
									   << false
									   << TypeConverter::DeserializationCapabilityResult::Guessed;
	QTest::newRow("dt.tstamp.invalid") << static_cast<int>(QMetaType::QDateTime)
									   << static_cast<QCborTag>(QCborKnownTags::UnixTime_t)
									   << QCborValue::String
									   << true
									   << TypeConverter::DeserializationCapabilityResult::Negative;

	QTest::newRow("date.date") << static_cast<int>(QMetaType::QDate)
							   << static_cast<QCborTag>(CborSerializer::Date)
							   << QCborValue::String
							   << true
							   << TypeConverter::DeserializationCapabilityResult::Positive;
	QTest::newRow("date.date.guessed") << static_cast<int>(QMetaType::UnknownType)
									   << static_cast<QCborTag>(CborSerializer::Date)
									   << QCborValue::String
									   << false
									   << TypeConverter::DeserializationCapabilityResult::Guessed;
	QTest::newRow("date.date.invalid") << static_cast<int>(QMetaType::QDate)
									   << static_cast<QCborTag>(CborSerializer::Date)
									   << QCborValue::Integer
									   << true
									   << TypeConverter::DeserializationCapabilityResult::Negative;
	QTest::newRow("date.dt") << static_cast<int>(QMetaType::QDate)
							 << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
							 << QCborValue::String
							 << true
							 << TypeConverter::DeserializationCapabilityResult::Positive;
	QTest::newRow("date.dt.invalid") << static_cast<int>(QMetaType::QDate)
									 << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
									 << QCborValue::Integer
									 << true
									 << TypeConverter::DeserializationCapabilityResult::Negative;

	QTest::newRow("time.time") << static_cast<int>(QMetaType::QTime)
							   << static_cast<QCborTag>(CborSerializer::Time)
							   << QCborValue::String
							   << true
							   << TypeConverter::DeserializationCapabilityResult::Positive;
	QTest::newRow("time.time.guessed") << static_cast<int>(QMetaType::UnknownType)
									   << static_cast<QCborTag>(CborSerializer::Time)
									   << QCborValue::String
									   << false
									   << TypeConverter::DeserializationCapabilityResult::Guessed;
	QTest::newRow("time.time.invalid") << static_cast<int>(QMetaType::QTime)
									   << static_cast<QCborTag>(CborSerializer::Time)
									   << QCborValue::Integer
									   << true
									   << TypeConverter::DeserializationCapabilityResult::Negative;
	QTest::newRow("time.dt") << static_cast<int>(QMetaType::QTime)
							 << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
							 << QCborValue::String
							 << true
							 << TypeConverter::DeserializationCapabilityResult::Positive;
	QTest::newRow("time.dt.invalid") << static_cast<int>(QMetaType::QTime)
									 << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
									 << QCborValue::Integer
									 << true
									 << TypeConverter::DeserializationCapabilityResult::Negative;

	QTest::newRow("invalid.type") << static_cast<int>(QMetaType::QString)
								  << static_cast<QCborTag>(QCborKnownTags::DateTimeString)
								  << QCborValue::String
								  << false
								  << TypeConverter::DeserializationCapabilityResult::Negative;
	QTest::newRow("invalid.tag.dt") << static_cast<int>(QMetaType::QDateTime)
									<< static_cast<QCborTag>(CborSerializer::Date)
									<< QCborValue::String
									<< true
									<< TypeConverter::DeserializationCapabilityResult::WrongTag;
	QTest::newRow("invalid.tag.date") << static_cast<int>(QMetaType::QDate)
									  << static_cast<QCborTag>(CborSerializer::Time)
									  << QCborValue::String
									  << true
									  << TypeConverter::DeserializationCapabilityResult::WrongTag;
	QTest::newRow("invalid.tag.time") << static_cast<int>(QMetaType::QTime)
									  << static_cast<QCborTag>(CborSerializer::Date)
									  << QCborValue::String
									  << true
									  << TypeConverter::DeserializationCapabilityResult::WrongTag;

}

void DateTimeConverterTest::addCommonSerData()
{
	QTest::newRow("datetime.string") << QVariantHash{}
									 << TestQ{}
									 << static_cast<QObject*>(nullptr)
									 << static_cast<int>(QMetaType::QDateTime)
									 << QVariant{QDateTime{{2019, 1, 3}, {13, 42, 15, 563}}}
									 << QCborValue{QDateTime{{2019, 1, 3}, {13, 42, 15, 563}}}
									 << QJsonValue{QStringLiteral("2019-01-03T13:42:15.563")};
	QTest::newRow("datetime.string.empty") << QVariantHash{}
										   << TestQ{}
										   << static_cast<QObject*>(nullptr)
										   << static_cast<int>(QMetaType::QDateTime)
										   << QVariant{QDateTime{}}
										   << QCborValue{QDateTime{}}
										   << QJsonValue{QString{}};
	QTest::newRow("datetime.string.tag") << QVariantHash{}
										 << TestQ{}
										 << static_cast<QObject*>(nullptr)
										 << static_cast<int>(QMetaType::QDateTime)
										 << QVariant{QDateTime{{2019, 1, 3}, {13, 42, 15, 563}}}
										 << QCborValue{QCborKnownTags::DateTimeString, QStringLiteral("2019-01-03T13:42:15.563")}
										 << QJsonValue{QJsonValue::Undefined};
	QTest::newRow("datetime.tstamp") << QVariantHash{{QStringLiteral("dateAsTimeStamp"), true}}
									 << TestQ{}
									 << static_cast<QObject*>(nullptr)
									 << static_cast<int>(QMetaType::QDateTime)
									 << QVariant{QDateTime{{2019, 1, 3}, {13, 42, 15}, Qt::UTC}}
									 << QCborValue{QCborKnownTags::UnixTime_t, 1546522935ll}
									 << QJsonValue{1546522935ll};

	QTest::newRow("date.datestr") << QVariantHash{}
								  << TestQ{}
								  << static_cast<QObject*>(nullptr)
								  << static_cast<int>(QMetaType::QDate)
								  << QVariant{QDate{2019, 1, 3}}
								  << QCborValue{static_cast<QCborTag>(CborSerializer::Date), QStringLiteral("2019-01-03")}
								  << QJsonValue{QStringLiteral("2019-01-03")};
	QTest::newRow("date.datestr.empty") << QVariantHash{}
										<< TestQ{}
										<< static_cast<QObject*>(nullptr)
										<< static_cast<int>(QMetaType::QDate)
										<< QVariant{QDate{}}
										<< QCborValue{static_cast<QCborTag>(CborSerializer::Date), QString{}}
										<< QJsonValue{QString{}};

	QTest::newRow("time.timestr") << QVariantHash{}
								  << TestQ{}
								  << static_cast<QObject*>(nullptr)
								  << static_cast<int>(QMetaType::QTime)
								  << QVariant{QTime{13, 42, 15, 563}}
								  << QCborValue{static_cast<QCborTag>(CborSerializer::Time), QStringLiteral("13:42:15.563")}
								  << QJsonValue{QStringLiteral("13:42:15.563")};
	QTest::newRow("time.timestr.empty") << QVariantHash{}
										<< TestQ{}
										<< static_cast<QObject*>(nullptr)
										<< static_cast<int>(QMetaType::QTime)
										<< QVariant{QTime{}}
										<< QCborValue{static_cast<QCborTag>(CborSerializer::Time), QString{}}
										<< QJsonValue{QString{}};
}

void DateTimeConverterTest::addSerData()
{
	QTest::newRow("datetime.tstamp.empty") << QVariantHash{{QStringLiteral("dateAsTimeStamp"), true}}
										   << TestQ{}
										   << static_cast<QObject*>(nullptr)
										   << static_cast<int>(QMetaType::QDateTime)
										   << QVariant{QDateTime{}}
										   << QCborValue{QCborKnownTags::UnixTime_t, 0ll}
										   << QJsonValue{0ll};
}

void DateTimeConverterTest::addDeserData()
{
	QTest::newRow("datetime.tstamp.empty") << QVariantHash{{QStringLiteral("dateAsTimeStamp"), true}}
										   << TestQ{}
										   << static_cast<QObject*>(nullptr)
										   << static_cast<int>(QMetaType::QDateTime)
										   << QVariant{QDateTime::fromMSecsSinceEpoch(0, Qt::UTC).toLocalTime()}
										   << QCborValue{QCborKnownTags::UnixTime_t, 0ll}
										   << QJsonValue{0ll};

	QTest::newRow("date.dtstr") << QVariantHash{}
								<< TestQ{}
								<< static_cast<QObject*>(nullptr)
								<< static_cast<int>(QMetaType::QDate)
								<< QVariant{QDate{2019, 1, 3}}
								<< QCborValue{QCborKnownTags::DateTimeString, QStringLiteral("2019-01-03T00:00:00.000")}
								<< QJsonValue{QJsonValue::Undefined};

	QTest::newRow("time.dtstr") << QVariantHash{}
								<< TestQ{}
								<< static_cast<QObject*>(nullptr)
								<< static_cast<int>(QMetaType::QTime)
								<< QVariant{QTime{13, 42, 15, 563}}
								<< QCborValue{QCborKnownTags::DateTimeString, QStringLiteral("1970-01-01T13:42:15.563")}
								<< QJsonValue{QJsonValue::Undefined};
}

QTEST_MAIN(DateTimeConverterTest)

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


<commit_before>#include <catch2/catch.hpp>

#include "manipulator/manipulators/mouse_motion_to_scroll/count_converter.hpp"

TEST_CASE("count_converter::update") {
  krbn::manipulator::manipulators::mouse_motion_to_scroll::count_converter c(8);

  REQUIRE(c.update(0) == 0);
  REQUIRE(c.update(8) == 1);
  REQUIRE(c.update(16) == 2);

  for (int i = 0; i < 10; ++i) {
    for (int j = 0; j < 7; ++j) {
      REQUIRE(c.update(1) == 0);
    }
    REQUIRE(c.update(1) == 1);
  }
}

TEST_CASE("count_converter::make_momentum_value") {
  krbn::manipulator::manipulators::mouse_motion_to_scroll::count_converter c(8);

  REQUIRE(c.make_momentum_value() == 0);

  {
    c.reset();
    c.update(16);

    std::vector<int> values{8, 6, 5, 4, 3, 3, 3, 3, 2, 1, 1, 1, 1, 0};
    for (const auto v : values) {
      REQUIRE(c.make_momentum_value() == v);
      c.update(c.make_momentum_value());
    }
  }

  // Fill zero before update

  {
    c.reset();
    for (int i = 0; i < 8; ++i) {
      c.update(0);
    }

    c.update(8);
    REQUIRE(c.make_momentum_value() == 0);

    c.update(8);
    REQUIRE(c.make_momentum_value() == 1);

    c.update(8);
    REQUIRE(c.make_momentum_value() == 1);

    c.update(8);
    REQUIRE(c.make_momentum_value() == 2);
  }
}
<commit_msg>update tests<commit_after>#include <catch2/catch.hpp>

#include "manipulator/manipulators/mouse_motion_to_scroll/count_converter.hpp"

TEST_CASE("count_converter::update") {
  krbn::manipulator::manipulators::mouse_motion_to_scroll::count_converter c(8);

  REQUIRE(c.update(0) == 0);
  REQUIRE(c.update(8) == 1);
  REQUIRE(c.update(16) == 2);

  for (int i = 0; i < 10; ++i) {
    for (int j = 0; j < 7; ++j) {
      REQUIRE(c.update(1) == 0);
    }
    REQUIRE(c.update(1) == 1);
  }

  c.reset();

  REQUIRE(c.update(-8) == -1);
  REQUIRE(c.update(-16) == -2);

  for (int i = 0; i < 10; ++i) {
    for (int j = 0; j < 7; ++j) {
      REQUIRE(c.update(-1) == 0);
    }
    REQUIRE(c.update(-1) == -1);
  }
}

TEST_CASE("count_converter::make_momentum_value") {
  krbn::manipulator::manipulators::mouse_motion_to_scroll::count_converter c(8);

  REQUIRE(c.make_momentum_value() == 0);

  {
    c.reset();
    c.update(16);

    std::vector<int> values{8, 6, 5, 4, 3, 3, 3, 3, 2, 1, 1, 1, 1, 0};
    for (const auto v : values) {
      REQUIRE(c.make_momentum_value() == v);
      c.update(c.make_momentum_value());
    }
  }

  // Fill zero before update

  {
    c.reset();
    for (int i = 0; i < 8; ++i) {
      c.update(0);
    }

    c.update(8);
    REQUIRE(c.make_momentum_value() == 0);

    c.update(8);
    REQUIRE(c.make_momentum_value() == 1);

    c.update(8);
    REQUIRE(c.make_momentum_value() == 1);

    c.update(8);
    REQUIRE(c.make_momentum_value() == 2);
  }
}
<|endoftext|>


<commit_before>#include "UASQuickViewTextItem.h"
#include "QsLog.h"
#include <QVBoxLayout>

UASQuickViewTextItem::UASQuickViewTextItem(QWidget *parent) : UASQuickViewItem(parent)
{
    QVBoxLayout *layout = new QVBoxLayout();
    this->setLayout(layout);
    layout->setSpacing(0);
    layout->setMargin(0);
    titleLabel = new QLabel(this);
   //titleLabel->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored);
    titleLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
    this->layout()->addWidget(titleLabel);
    valueLabel = new QLabel(this);
    //valueLabel->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored);
    valueLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
    valueLabel->setText("0.00");
    this->layout()->addWidget(valueLabel);
    //spacerItem = new QSpacerItem(20,40,QSizePolicy::Minimum,QSizePolicy::Ignored);
    //layout->addSpacerItem(spacerItem);
    QFont valuefont = valueLabel->font();
    QFont titlefont = titleLabel->font();
    valuefont.setPixelSize(this->height() / 2.0);
    titlefont.setPixelSize(this->height() / 4.0);
    valueLabel->setFont(valuefont);
    titleLabel->setFont(titlefont);
}
QString UASQuickViewTextItem::value()
{
    return valueLabel->text();
}

QString UASQuickViewTextItem::title()
{
    return titleLabel->text();
}

void UASQuickViewTextItem::setValue(double value)
{
    if (value < 10 && value > -10)
    {
        valueLabel->setText(QString::number(value,'f',2));
    }
    else if (value < 100 && value > -100)
    {
        valueLabel->setText(QString::number(value,'f',2));
    }
    else if (value < 1000 && value > -1000)
    {
        valueLabel->setText(QString::number(value,'f',1));
    }
    else if (value < 10000 && value > -10000)
    {
        valueLabel->setText(QString::number(value,'f',1));
    }
    else if (value >= 100000 || value <= -100000)
    {
        valueLabel->setText(QString::number(value,'f',0));
    }
}

void UASQuickViewTextItem::setTitle(QString title)
{
    if (title.indexOf(".") != -1 && title.indexOf(":") != -1)
    {
        titleLabel->setText(title.mid(title.indexOf(".")+1));
    }
    else
    {
        titleLabel->setText(title);
    }
}
int UASQuickViewTextItem::minValuePixelSize()
{
    QFont valuefont = valueLabel->font();
    QFont titlefont = titleLabel->font();
    valuefont.setPixelSize(this->height());
    titlefont.setPixelSize(valuefont.pixelSize() / 1.3);
    //spacerItem->setGeometry(QRect(0,0,20,this->height()/10.0));

    QFontMetrics metrics(valuefont);
    //valuefont.setPixelSize(this->height() / 2.0);
    bool fit = false;
    while (!fit)
    {

        QFontMetrics valfm( valuefont );
        QRect valbound = valfm.boundingRect(0,0, valueLabel->width(), valueLabel->height(), Qt::TextWordWrap | Qt::AlignLeft, "45678.00"/*valueLabel->text()*/);
        //QFontMetrics titlefm( titlefont );
        //QRect titlebound = titlefm.boundingRect(0,0, titleLabel->width(), titleLabel->height(), Qt::TextWordWrap | Qt::AlignLeft, titleLabel->text());

        if ((valbound.width() <= valueLabel->width() && valbound.height() <= valueLabel->height()))// && (titlebound.width() <= titleLabel->width() && titlebound.height() <= titleLabel->height()))
            fit = true;
        else
        {
            if (valuefont.pixelSize()-5 <= 0)
            {
                fit = true;
                valuefont.setPixelSize(5);
            }
            else
            {
                valuefont.setPixelSize(valuefont.pixelSize() - 5);
            }
            //titlefont.setPixelSize(valuefont.pixelSize() / 2.0);
            QLOG_TRACE() << "Point size:" << valuefont.pixelSize() << valueLabel->width() << valueLabel->height();
        }
    }
    return valuefont.pixelSize();
}
void UASQuickViewTextItem::setValuePixelSize(int size)
{
    QFont valuefont = valueLabel->font();
    QFont titlefont = titleLabel->font();
    valuefont.setPixelSize(size);
    titlefont.setPixelSize(valuefont.pixelSize() / 1.3);
    valueLabel->setFont(valuefont);
    titleLabel->setFont(titlefont);
    update();
}

void UASQuickViewTextItem::resizeEvent(QResizeEvent *event)
{
    return;
    QFont valuefont = valueLabel->font();
    QFont titlefont = titleLabel->font();
    valuefont.setPixelSize(this->height());
    titlefont.setPixelSize(valuefont.pixelSize() / 1.6);
    //spacerItem->setGeometry(QRect(0,0,20,this->height()/10.0));

    QFontMetrics metrics(valuefont);
    //valuefont.setPixelSize(this->height() / 2.0);
    bool fit = false;
    while (!fit)
    {

        QFontMetrics valfm( valuefont );
        QRect valbound = valfm.boundingRect(0,0, valueLabel->width(), valueLabel->height(), Qt::TextWordWrap | Qt::AlignLeft, valueLabel->text());
        //QFontMetrics titlefm( titlefont );
        //QRect titlebound = titlefm.boundingRect(0,0, titleLabel->width(), titleLabel->height(), Qt::TextWordWrap | Qt::AlignLeft, titleLabel->text());

        if ((valbound.width() <= valueLabel->width() && valbound.height() <= valueLabel->height()))// && (titlebound.width() <= titleLabel->width() && titlebound.height() <= titleLabel->height()))
            fit = true;
        else
        {
            if (valuefont.pixelSize()-5 <= 0)
            {
                fit = true;
                valuefont.setPixelSize(5);
            }
            else
            {
                valuefont.setPixelSize(valuefont.pixelSize() - 5);
            }
            //titlefont.setPixelSize(valuefont.pixelSize() / 2.0);
            QLOG_TRACE() << "Point size:" << valuefont.pixelSize() << valueLabel->width() << valueLabel->height();
        }
    }
titlefont.setPixelSize(valuefont.pixelSize() / 1.6);
    valueLabel->setFont(valuefont);
    titleLabel->setFont(titlefont);
    update();
}
<commit_msg>Fixed values being 0.00 if they are over 10,000 in UASQuickView text items<commit_after>#include "UASQuickViewTextItem.h"
#include "QsLog.h"
#include <QVBoxLayout>

UASQuickViewTextItem::UASQuickViewTextItem(QWidget *parent) : UASQuickViewItem(parent)
{
    QVBoxLayout *layout = new QVBoxLayout();
    this->setLayout(layout);
    layout->setSpacing(0);
    layout->setMargin(0);
    titleLabel = new QLabel(this);
   //titleLabel->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored);
    titleLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
    this->layout()->addWidget(titleLabel);
    valueLabel = new QLabel(this);
    //valueLabel->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored);
    valueLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
    valueLabel->setText("0.00");
    this->layout()->addWidget(valueLabel);
    //spacerItem = new QSpacerItem(20,40,QSizePolicy::Minimum,QSizePolicy::Ignored);
    //layout->addSpacerItem(spacerItem);
    QFont valuefont = valueLabel->font();
    QFont titlefont = titleLabel->font();
    valuefont.setPixelSize(this->height() / 2.0);
    titlefont.setPixelSize(this->height() / 4.0);
    valueLabel->setFont(valuefont);
    titleLabel->setFont(titlefont);
}
QString UASQuickViewTextItem::value()
{
    return valueLabel->text();
}

QString UASQuickViewTextItem::title()
{
    return titleLabel->text();
}

void UASQuickViewTextItem::setValue(double value)
{
    if (value < 10 && value > -10)
    {
        valueLabel->setText(QString::number(value,'f',2));
    }
    else if (value < 100 && value > -100)
    {
        valueLabel->setText(QString::number(value,'f',2));
    }
    else if (value < 1000 && value > -1000)
    {
        valueLabel->setText(QString::number(value,'f',1));
    }
    else if (value < 10000 && value > -10000)
    {
        valueLabel->setText(QString::number(value,'f',1));
    }
    else
    {
        valueLabel->setText(QString::number(value,'f',0));
    }
}

void UASQuickViewTextItem::setTitle(QString title)
{
    if (title.indexOf(".") != -1 && title.indexOf(":") != -1)
    {
        titleLabel->setText(title.mid(title.indexOf(".")+1));
    }
    else
    {
        titleLabel->setText(title);
    }
}
int UASQuickViewTextItem::minValuePixelSize()
{
    QFont valuefont = valueLabel->font();
    QFont titlefont = titleLabel->font();
    valuefont.setPixelSize(this->height());
    titlefont.setPixelSize(valuefont.pixelSize() / 1.3);
    //spacerItem->setGeometry(QRect(0,0,20,this->height()/10.0));

    QFontMetrics metrics(valuefont);
    //valuefont.setPixelSize(this->height() / 2.0);
    bool fit = false;
    while (!fit)
    {

        QFontMetrics valfm( valuefont );
        QRect valbound = valfm.boundingRect(0,0, valueLabel->width(), valueLabel->height(), Qt::TextWordWrap | Qt::AlignLeft, "45678.00"/*valueLabel->text()*/);
        //QFontMetrics titlefm( titlefont );
        //QRect titlebound = titlefm.boundingRect(0,0, titleLabel->width(), titleLabel->height(), Qt::TextWordWrap | Qt::AlignLeft, titleLabel->text());

        if ((valbound.width() <= valueLabel->width() && valbound.height() <= valueLabel->height()))// && (titlebound.width() <= titleLabel->width() && titlebound.height() <= titleLabel->height()))
            fit = true;
        else
        {
            if (valuefont.pixelSize()-5 <= 0)
            {
                fit = true;
                valuefont.setPixelSize(5);
            }
            else
            {
                valuefont.setPixelSize(valuefont.pixelSize() - 5);
            }
            //titlefont.setPixelSize(valuefont.pixelSize() / 2.0);
            QLOG_TRACE() << "Point size:" << valuefont.pixelSize() << valueLabel->width() << valueLabel->height();
        }
    }
    return valuefont.pixelSize();
}
void UASQuickViewTextItem::setValuePixelSize(int size)
{
    QFont valuefont = valueLabel->font();
    QFont titlefont = titleLabel->font();
    valuefont.setPixelSize(size);
    titlefont.setPixelSize(valuefont.pixelSize() / 1.3);
    valueLabel->setFont(valuefont);
    titleLabel->setFont(titlefont);
    update();
}

void UASQuickViewTextItem::resizeEvent(QResizeEvent *event)
{
    return;
    QFont valuefont = valueLabel->font();
    QFont titlefont = titleLabel->font();
    valuefont.setPixelSize(this->height());
    titlefont.setPixelSize(valuefont.pixelSize() / 1.6);
    //spacerItem->setGeometry(QRect(0,0,20,this->height()/10.0));

    QFontMetrics metrics(valuefont);
    //valuefont.setPixelSize(this->height() / 2.0);
    bool fit = false;
    while (!fit)
    {

        QFontMetrics valfm( valuefont );
        QRect valbound = valfm.boundingRect(0,0, valueLabel->width(), valueLabel->height(), Qt::TextWordWrap | Qt::AlignLeft, valueLabel->text());
        //QFontMetrics titlefm( titlefont );
        //QRect titlebound = titlefm.boundingRect(0,0, titleLabel->width(), titleLabel->height(), Qt::TextWordWrap | Qt::AlignLeft, titleLabel->text());

        if ((valbound.width() <= valueLabel->width() && valbound.height() <= valueLabel->height()))// && (titlebound.width() <= titleLabel->width() && titlebound.height() <= titleLabel->height()))
            fit = true;
        else
        {
            if (valuefont.pixelSize()-5 <= 0)
            {
                fit = true;
                valuefont.setPixelSize(5);
            }
            else
            {
                valuefont.setPixelSize(valuefont.pixelSize() - 5);
            }
            //titlefont.setPixelSize(valuefont.pixelSize() / 2.0);
            QLOG_TRACE() << "Point size:" << valuefont.pixelSize() << valueLabel->width() << valueLabel->height();
        }
    }
titlefont.setPixelSize(valuefont.pixelSize() / 1.6);
    valueLabel->setFont(valuefont);
    titleLabel->setFont(titlefont);
    update();
}
<|endoftext|>