<commit_before>#include <iostream>
#include <vector>
#include <map>
#include <node.h>

#include "PSATResult.h"
#include "calculator/EstimateFLA.h"

using namespace v8;
using namespace std;

Isolate* iso;
Local<Object> inp;

double Get(const char *nm) {
  auto r = inp->ToObject()->Get(String::NewFromUtf8(iso,nm))->NumberValue();
  if (isnan(r)) {
    cout << nm;
    assert(!"number");
  }
  return r;
}

void Results(const FunctionCallbackInfo<Value>& args) {
  iso = args.GetIsolate();
  inp = args[0]->ToObject();
  auto r = Object::New(iso);

  auto drive = (Pump::Drive)(int)Get("drive");
  auto effCls = (Motor::EfficiencyClass)(int)Get("efficiency_class");
  Pump pump((Pump::Style)(int)Get("pump_style"),Get("pump_rated_speed"),drive,
      Get("viscosity"),Get("specific_gravity"),Get("stages"),(Pump::Speed)(int)(!Get("fixed_speed")));
  Motor motor((Motor::LineFrequency)(int)(!Get("line")),Get("motor_rated_power"),Get("motor_rated_speed"),
      effCls,Get("efficiency"),Get("motor_rated_voltage"),Get("motor_rated_flc"),Get("margin"));
  Financial fin(Get("fraction"),Get("cost"));
  FieldData fd(Get("flow"),Get("head"),(FieldData::LoadEstimationMethod)(Get("motor_field_power")>0?0:1),
      Get("motor_field_power"),Get("motor_field_current"),Get("motor_field_voltage"));
  PSATResult psat(pump,motor,fin,fd);
  psat.calculateExisting();
  auto ex = psat.getExisting();

  map<const char *,vector<double>> out = {
    {"Pump Efficiency",{ex.pumpEfficiency_*100,0}},
    {"Motor Rated Power",{ex.motorRatedPower_,0}},
    {"Motor Shaft Power",{ex.motorShaftPower_,0}},
    {"Pump Shaft Power",{ex.pumpShaftPower_,0}},
    {"Motor Efficiency",{ex.motorEfficiency_,0}},
    {"Motor Power Factor",{ex.motorPowerFactor_,0}},
    {"Motor Current",{ex.motorCurrent_,0}},
    {"Motor Power", {ex.motorPower_,0}},
    {"Annual Energy", {ex.annualEnergy_,0}},
    {"Annual Cost", {ex.annualCost_*1000,0}},
    {"Savings Potential", {psat.getAnnualSavingsPotential(),0}},
    {"Optimization Rating", {psat.getOptimizationRating(),0}}
  };
  for(auto p: out) {
    auto a = Array::New(iso);
    a->Set(0,Number::New(iso,p.second[0]));
    a->Set(1,Number::New(iso,p.second[1]));
    r->Set(String::NewFromUtf8(iso,p.first),a);
  }
  args.GetReturnValue().Set(r);
}

void EstFLA(const FunctionCallbackInfo<Value>& args) {
  iso = args.GetIsolate();
  inp = args[0]->ToObject();

  EstimateFLA fla(Get("motor_rated_power"),Get("motor_rated_speed"),(Motor::LineFrequency)(int)(!Get("line")),(Motor::EfficiencyClass)(int)Get("efficiency_class"),
    Get("efficiency"),Get("motor_rated_voltage"));
  fla.calculate();
  args.GetReturnValue().Set(fla.getEstimatedFLA());
}

void Check(double exp, double act, const char* nm="") {
  //cout << "e " << exp << "; a " << act << endl;
  if (isnan(act) || (abs(exp-act)>.01*exp)) {
    printf("\"%s\" TEST FAILED: %f %f\n",nm,exp,act);
    assert(!"equal");
  }
}

void Check100(double exp, double act, const char* nm="") {
  Check(exp,act*100,nm);
}

void Test(const FunctionCallbackInfo<Value>& args) {
  EstimateFLA fla(200,1780,(Motor::LineFrequency)1,(Motor::EfficiencyClass)(1),0,460);
  fla.calculate();
  Check(225.8,fla.getEstimatedFLA());

  #define BASE \
    Pump pump(Pump::Style::END_SUCTION_ANSI_API,1780,Pump::Drive::DIRECT_DRIVE,\
      1,1,1,Pump::Speed::NOT_FIXED_SPEED);\
    Motor motor(Motor::LineFrequency::FREQ60,200,1780,\
        Motor::EfficiencyClass::ENERGY_EFFICIENT,0,460,225.8,0);\
    Financial fin(1,.05);\
    FieldData fd(2000,277,FieldData::LoadEstimationMethod::POWER,\
        150,0,460);

  #define CALC \
    PSATResult psat(pump,motor,fin,fd);\
    psat.calculateExisting();\
    auto ex = psat.getExisting();

  for (int i=1; i<=10000; i=i+2) {
    BASE
    CALC
    Check(ex.motorShaftPower_,ex.motorShaftPower_,"SAME");
  }

  {
    BASE
    motor.setMotorRpm(1786);
    fd.setMotorPower(80);
    CALC
    Check(101.9,ex.motorShaftPower_);
    Check100(95,ex.motorEfficiency_);
    Check100(79.1,ex.motorPowerFactor_);
    Check(127,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(80);
    motor.setMotorRatedPower(100);
    motor.setFullLoadAmps(113.8);
    CALC
    Check(101.8,ex.motorShaftPower_);
    Check100(94.9,ex.motorEfficiency_);
    Check100(86.7,ex.motorPowerFactor_);
    Check(115.8,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(80);
    fd.setVoltage(260);
    CALC
    Check(101.9,ex.motorShaftPower_);
    Check100(95,ex.motorEfficiency_);
    Check100(138.8,ex.motorPowerFactor_);
    Check(128,ex.motorCurrent_);
  }
  {
    BASE
    motor.setMotorRpm(1200);
    fd.setMotorPower(80);
    motor.setFullLoadAmps(235.3);
    CALC
    Check(101.4,ex.motorShaftPower_);
    Check100(94.5,ex.motorEfficiency_);
    Check100(74.3,ex.motorPowerFactor_);
    Check(135.1,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(111.855);
    CALC
    Check(143.4,ex.motorShaftPower_);
    Check100(95.6,ex.motorEfficiency_);
    Check100(84.3,ex.motorPowerFactor_);
    Check(166.5,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(80);
    motor.setMotorRatedVoltage(200);
    motor.setFullLoadAmps(519.3);
    CALC
    Check(101.9,ex.motorShaftPower_);
    Check100(95,ex.motorEfficiency_);
    Check100(35.2,ex.motorPowerFactor_);
    Check(285,ex.motorCurrent_);
  }
  {
    BASE
    CALC
    Check(217.1,ex.motorCurrent_);
  }
  {
    BASE
    fd.setLoadEstimationMethod(FieldData::LoadEstimationMethod::CURRENT);
    fd.setMotorAmps(218);
    fd.setMotorPower(0);
    CALC
    Check(150.7,ex.motorPower_);
    Check100(72.5,ex.pumpEfficiency_);
  }
  {
    BASE
    fd.setMotorPower(80);
    CALC
    Check(700.8,ex.annualEnergy_);
  }
  {
    BASE
    fin.setOperatingFraction(.25);
    CALC
    Check(328.5,ex.annualEnergy_);
    Check(16.4,ex.annualCost_);
  }
  {
    BASE
    motor.setFullLoadAmps(300);
    CALC
    Check(288.9,ex.motorCurrent_);
  }
  {
    BASE
    motor.setEfficiencyClass(Motor::EfficiencyClass(0));
    CALC
    Check(213.7,ex.motorCurrent_);
  }
}

void Wtf(const FunctionCallbackInfo<Value>& args) {
}

void Init(Local<Object> exports) {
  NODE_SET_METHOD(exports, "results", Results);
  NODE_SET_METHOD(exports, "estFLA", EstFLA);
  NODE_SET_METHOD(exports, "test", Test);
  NODE_SET_METHOD(exports, "wtf", Wtf);
}

NODE_MODULE(bridge, Init)

<commit_msg>no message<commit_after>#include <iostream>
#include <vector>
#include <map>
#include <node.h>

#include "PSATResult.h"
#include "calculator/EstimateFLA.h"

using namespace v8;
using namespace std;

Isolate* iso;
Local<Object> inp;

double Get(const char *nm) {
  auto r = inp->ToObject()->Get(String::NewFromUtf8(iso,nm))->NumberValue();
  if (isnan(r)) {
    cout << nm;
    assert(!"number");
  }
  return r;
}

void Results(const FunctionCallbackInfo<Value>& args) {
  iso = args.GetIsolate();
  inp = args[0]->ToObject();
  auto r = Object::New(iso);

  auto drive = (Pump::Drive)(int)Get("drive");
  auto effCls = (Motor::EfficiencyClass)(int)Get("efficiency_class");
  Pump pump((Pump::Style)(int)Get("pump_style"),Get("pump_rated_speed"),drive,
      Get("viscosity"),Get("specific_gravity"),Get("stages"),(Pump::Speed)(int)(!Get("fixed_speed")));
  Motor motor((Motor::LineFrequency)(int)(!Get("line")),Get("motor_rated_power"),Get("motor_rated_speed"),
      effCls,Get("efficiency"),Get("motor_rated_voltage"),Get("motor_rated_flc"),Get("margin"));
  Financial fin(Get("fraction"),Get("cost"));
  FieldData fd(Get("flow"),Get("head"),(FieldData::LoadEstimationMethod)(Get("motor_field_power")>0?0:1),
      Get("motor_field_power"),Get("motor_field_current"),Get("motor_field_voltage"));
  PSATResult psat(pump,motor,fin,fd);
  psat.calculateExisting();
  auto ex = psat.getExisting();

  map<const char *,vector<double>> out = {
    {"Pump Efficiency",{ex.pumpEfficiency_*100,0}},
    {"Motor Rated Power",{ex.motorRatedPower_,0}},
    {"Motor Shaft Power",{ex.motorShaftPower_,0}},
    {"Pump Shaft Power",{ex.pumpShaftPower_,0}},
    {"Motor Efficiency",{ex.motorEfficiency_,0}},
    {"Motor Power Factor",{ex.motorPowerFactor_,0}},
    {"Motor Current",{ex.motorCurrent_,0}},
    {"Motor Power", {ex.motorPower_,0}},
    {"Annual Energy", {ex.annualEnergy_,0}},
    {"Annual Cost", {ex.annualCost_*1000,0}},
    {"Savings Potential", {psat.getAnnualSavingsPotential(),0}},
    {"Optimization Rating", {psat.getOptimizationRating(),0}}
  };
  for(auto p: out) {
    auto a = Array::New(iso);
    a->Set(0,Number::New(iso,p.second[0]));
    a->Set(1,Number::New(iso,p.second[1]));
    r->Set(String::NewFromUtf8(iso,p.first),a);
  }
  args.GetReturnValue().Set(r);
}

void EstFLA(const FunctionCallbackInfo<Value>& args) {
  iso = args.GetIsolate();
  inp = args[0]->ToObject();

  EstimateFLA fla(Get("motor_rated_power"),Get("motor_rated_speed"),(Motor::LineFrequency)(int)(!Get("line")),(Motor::EfficiencyClass)(int)Get("efficiency_class"),
    Get("efficiency"),Get("motor_rated_voltage"));
  fla.calculate();
  args.GetReturnValue().Set(fla.getEstimatedFLA());
}

void Check(double exp, double act, const char* nm="") {
  //cout << "e " << exp << "; a " << act << endl;
  // if (isnan(act) || (abs(exp-act)>.01*exp)) {
  if (isnan(act) || ( (round(exp*10)/10)!=round(act*10)/10)) {

    printf("\"%s\" TEST FAILED: %f %f\n",nm,exp,act);
    assert(!"equal");
  }
}

void Check100(double exp, double act, const char* nm="") {
  Check(exp,act*100,nm);
}

void Test(const FunctionCallbackInfo<Value>& args) {
  EstimateFLA fla(200,1780,(Motor::LineFrequency)1,(Motor::EfficiencyClass)(1),0,460);
  fla.calculate();
  Check(225.8,fla.getEstimatedFLA());

  #define BASE \
    Pump pump(Pump::Style::END_SUCTION_ANSI_API,1780,Pump::Drive::DIRECT_DRIVE,\
      1,1,1,Pump::Speed::NOT_FIXED_SPEED);\
    Motor motor(Motor::LineFrequency::FREQ60,200,1780,\
        Motor::EfficiencyClass::ENERGY_EFFICIENT,0,460,225.8,0);\
    Financial fin(1,.05);\
    FieldData fd(2000,277,FieldData::LoadEstimationMethod::POWER,\
        150,0,460);

  #define CALC \
    PSATResult psat(pump,motor,fin,fd);\
    psat.calculateExisting();\
    auto ex = psat.getExisting();

  for (int i=1; i<=10000; i=i+2) {
    BASE
    CALC
    Check(ex.motorShaftPower_,ex.motorShaftPower_,"SAME");
  }

  {
    BASE
    motor.setMotorRpm(1786);
    fd.setMotorPower(80);
    CALC
    Check(101.9,ex.motorShaftPower_);
    Check100(95,ex.motorEfficiency_);
    Check100(79.1,ex.motorPowerFactor_);
    Check(127,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(80);
    motor.setMotorRatedPower(100);
    motor.setFullLoadAmps(113.8);
    CALC
    Check(101.8,ex.motorShaftPower_);
    Check100(94.9,ex.motorEfficiency_);
    Check100(86.7,ex.motorPowerFactor_);
    Check(115.8,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(80);
    fd.setVoltage(260);
    CALC
    Check(101.9,ex.motorShaftPower_);
    Check100(95,ex.motorEfficiency_);
    Check100(138.8,ex.motorPowerFactor_);
    Check(128,ex.motorCurrent_);
  }
  {
    BASE
    motor.setMotorRpm(1200);
    fd.setMotorPower(80);
    motor.setFullLoadAmps(235.3);
    CALC
    Check(101.4,ex.motorShaftPower_);
    Check100(94.5,ex.motorEfficiency_);
    Check100(74.3,ex.motorPowerFactor_);
    Check(135.1,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(111.855);
    CALC
    Check(143.4,ex.motorShaftPower_);
    Check100(95.6,ex.motorEfficiency_);
    Check100(84.3,ex.motorPowerFactor_);
    Check(166.5,ex.motorCurrent_);
  }
  {
    BASE
    fd.setMotorPower(80);
    motor.setMotorRatedVoltage(200);
    motor.setFullLoadAmps(519.3);
    CALC
    Check(101.9,ex.motorShaftPower_);
    Check100(95,ex.motorEfficiency_);
    Check100(35.2,ex.motorPowerFactor_);
    Check(285,ex.motorCurrent_);
  }
  {
    BASE
    CALC
    Check(217.1,ex.motorCurrent_);
  }
  {
    BASE
    fd.setLoadEstimationMethod(FieldData::LoadEstimationMethod::CURRENT);
    fd.setMotorAmps(218);
    fd.setMotorPower(0);
    CALC
    Check(150.7,ex.motorPower_);
    Check100(72.5,ex.pumpEfficiency_);
  }
  {
    BASE
    fd.setMotorPower(80);
    CALC
    Check(700.8,ex.annualEnergy_);
  }
  {
    BASE
    fin.setOperatingFraction(.25);
    CALC
    Check(328.5,ex.annualEnergy_);
    Check(16.4,ex.annualCost_);
  }
  {
    BASE
    motor.setFullLoadAmps(300);
    CALC
    Check(288.9,ex.motorCurrent_);
  }
  {
    BASE
    motor.setEfficiencyClass(Motor::EfficiencyClass(0));
    CALC
    Check(213.7,ex.motorCurrent_);
  }
  {
    BASE
    motor.setEfficiencyClass(Motor::EfficiencyClass(2));
    motor.setSpecifiedEfficiency(75);
    CALC
    Check(173.7,ex.motorCurrent_);
  }
}

void Wtf(const FunctionCallbackInfo<Value>& args) {
}

void Init(Local<Object> exports) {
  NODE_SET_METHOD(exports, "results", Results);
  NODE_SET_METHOD(exports, "estFLA", EstFLA);
  NODE_SET_METHOD(exports, "test", Test);
  NODE_SET_METHOD(exports, "wtf", Wtf);
}

NODE_MODULE(bridge, Init)

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2013 Jolla Ltd.
** Contact: Raine Makelainen <raine.makelainen@jollamobile.com>
**
****************************************************************************/

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "declarativewebcontainer.h"
#include "declarativetab.h"
#include "declarativetabmodel.h"
#include "dbmanager.h"

#include <QPointer>
#include <QTimerEvent>
#include <QQuickWindow>
#include <quickmozview.h>
#include <QDir>
#include <QTransform>
#include <QStandardPaths>
#include <QtConcurrentRun>
#include <QGuiApplication>
#include <QScreen>

#include <QMetaMethod>

DeclarativeWebContainer::DeclarativeWebContainer(QQuickItem *parent)
    : QQuickItem(parent)
    , m_webView(0)
    , m_model(0)
    , m_currentTab(new DeclarativeTab(this))
    , m_foreground(true)
    , m_background(false)
    , m_windowVisible(false)
    , m_backgroundTimer(0)
    , m_active(false)
    , m_popupActive(false)
    , m_portrait(true)
    , m_fullScreenMode(false)
    , m_inputPanelVisible(false)
    , m_inputPanelHeight(0.0)
    , m_inputPanelOpenHeight(0.0)
    , m_toolbarHeight(0.0)
    , m_canGoForward(false)
    , m_canGoBack(false)
    , m_realNavigation(false)
    , m_firstFrameRendered(false)
{
    setFlag(QQuickItem::ItemHasContents, true);
    connect(m_currentTab, SIGNAL(titleChanged()), this, SIGNAL(titleChanged()));
    connect(m_currentTab, SIGNAL(urlChanged()), this, SIGNAL(urlChanged()));
    connect(m_currentTab, SIGNAL(urlChanged()), this, SLOT(triggerLoad()));
    if (!window()) {
        connect(this, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(handleWindowChanged(QQuickWindow*)));
    } else {
        connect(window(), SIGNAL(visibleChanged(bool)), this, SLOT(windowVisibleChanged(bool)));
    }

    connect(&m_screenCapturer, SIGNAL(finished()), this, SLOT(screenCaptureReady()));

    QString cacheLocation = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
    QDir dir(cacheLocation);
    if(!dir.exists() && !dir.mkpath(cacheLocation)) {
        qWarning() << "Can't create directory "+ cacheLocation;
        return;
    }
}

DeclarativeWebContainer::~DeclarativeWebContainer()
{
    // Disconnect all signal slot connections
    if (m_webView) {
        disconnect(m_webView, 0, 0, 0);
    }

    m_screenCapturer.cancel();
    m_screenCapturer.waitForFinished();
}

QuickMozView *DeclarativeWebContainer::webView() const
{
    return m_webView;
}

void DeclarativeWebContainer::setWebView(QuickMozView *webView)
{
    if (m_webView != webView) {
        if (m_webView) {
            disconnect(m_webView);
        }

        if (webView) {
            connect(webView, SIGNAL(imeNotification(int,bool,int,int,QString)),
                    this, SLOT(imeNotificationChanged(int,bool,int,int,QString)));
            connect(webView, SIGNAL(contentHeightChanged()), this, SLOT(resetHeight()));
            connect(webView, SIGNAL(scrollableOffsetChanged()), this, SLOT(resetHeight()));
            connect(this, SIGNAL(heightChanged()), this, SLOT(resetHeight()));
        }
        m_webView = webView;
        emit contentItemChanged();
    }
}

bool DeclarativeWebContainer::foreground() const
{
    return m_foreground;
}

void DeclarativeWebContainer::setForeground(bool active)
{
    if (m_foreground != active) {
        m_foreground = active;

        if (!m_foreground) {
            // Respect content height when browser brought back from home
            resetHeight(true);
        }
        emit foregroundChanged();
    }
}

bool DeclarativeWebContainer::background() const
{
    return m_background;
}

bool DeclarativeWebContainer::active() const
{
    return m_active;
}

void DeclarativeWebContainer::setActive(bool active)
{
    if (m_active != active) {
        m_active = active;
        emit activeChanged();

        // If dialog has been opened, we need to verify that input panel is not visible.
        // This might happen when the user fills in login details to a form and
        // presses enter to accept the form after which PasswordManagerDialog is pushed to pagestack
        // on top the BrowserPage. Once PassowordManagerDialog is accepted/rejected
        // this condition can be met. If active changes to true before keyboard is fully closed,
        // then the inputPanelVisibleChanged() signal is emitted by setInputPanelHeight.
        if (m_active && m_inputPanelHeight == 0 && m_inputPanelVisible) {
            m_inputPanelVisible = false;
            emit inputPanelVisibleChanged();
        }
    }
}

bool DeclarativeWebContainer::inputPanelVisible() const
{
    return m_inputPanelVisible;
}

qreal DeclarativeWebContainer::inputPanelHeight() const
{
    return m_inputPanelHeight;
}

void DeclarativeWebContainer::setInputPanelHeight(qreal height)
{
    if (m_inputPanelHeight != height) {
        bool imVisibleChanged = false;
        m_inputPanelHeight = height;
        if (m_active) {
            if (m_inputPanelHeight == 0) {
                if (m_inputPanelVisible) {
                    m_inputPanelVisible = false;
                    imVisibleChanged = true;
                }
            } else if (m_inputPanelHeight == m_inputPanelOpenHeight) {
                if (!m_inputPanelVisible) {
                    m_inputPanelVisible = true;
                    imVisibleChanged = true;
                }
            }
        }

        if (imVisibleChanged) {
            emit inputPanelVisibleChanged();
        }

        emit inputPanelHeightChanged();
    }
}

bool DeclarativeWebContainer::canGoForward() const
{
    return m_canGoForward;
}

bool DeclarativeWebContainer::canGoBack() const
{
    return m_canGoBack;
}

QString DeclarativeWebContainer::title() const
{
    return m_currentTab->title();
}

QString DeclarativeWebContainer::url() const
{
    return m_currentTab->url();
}

DeclarativeTab *DeclarativeWebContainer::currentTab() const
{
    return m_currentTab;
}

void DeclarativeWebContainer::goForward()
{
    if (m_canGoForward && m_currentTab->valid()) {
        m_currentTab->activateNextLink();
        if (m_webView && m_webView->canGoForward()) {
            m_realNavigation = true;
            m_webView->goForward();
        } else {
            m_realNavigation = false;
        }

        m_model->setBackForwardNavigation(true);
        DBManager::instance()->goForward(m_model->currentTabId());
    }
}

void DeclarativeWebContainer::goBack()
{
    if (m_canGoBack && m_currentTab->valid()) {
        m_currentTab->activatePreviousLink();
        if (m_webView && m_webView->canGoBack()) {
            m_realNavigation = true;
            m_webView->goBack();
        } else {
            m_realNavigation = false;
        }

        m_model->setBackForwardNavigation(true);
        DBManager::instance()->goBack(m_model->currentTabId());
    }
}

void DeclarativeWebContainer::captureScreen()
{
    if (!m_webView) {
        return;
    }

    if (m_active && m_firstFrameRendered && !m_popupActive) {
        int size = QGuiApplication::primaryScreen()->size().width();
        if (!m_portrait && !m_fullScreenMode) {
            size -= m_toolbarHeight;
        }

        qreal rotation = parentItem() ? parentItem()->rotation() : 0;
        captureScreen(url(), size, rotation);
    }
}

void DeclarativeWebContainer::resetHeight(bool respectContentHeight)
{
    if (!m_webView || !m_webView->state().isEmpty()) {
        return;
    }

    qreal fullHeight = height();

    // Application active
    if (respectContentHeight) {
        // Handle webView height over here, BrowserPage.qml loading
        // reset might be redundant as we have also loaded trigger
        // reset. However, I'd leave it there for safety reasons.
        // We need to reset height always back to short height when loading starts
        // so that after tab change there is always initial short composited height.
        // Height may expand when content is moved.
        if (contentHeight() > fullHeight + m_toolbarHeight) {
            m_webView->setHeight(fullHeight);
        } else {
            m_webView->setHeight(fullHeight - m_toolbarHeight);
        }
    } else {
        m_webView->setHeight(fullHeight - m_toolbarHeight);
    }
}

void DeclarativeWebContainer::imeNotificationChanged(int state, bool open, int cause, int focusChange, const QString &type)
{
    Q_UNUSED(open)
    Q_UNUSED(cause)
    Q_UNUSED(focusChange)
    Q_UNUSED(type)

    // QmlMozView's input context open is actually intention (0 closed, 1 opened).
    // cause 3 equals InputContextAction::CAUSE_MOUSE nsIWidget.h
    if (state == 1 && cause == 3) {
        // For safety reset height based on contentHeight before going to "boundHeightControl" state
        // so that when vkb is closed we get correctly reset height back.
        resetHeight(true);
        if (!m_inputPanelVisible) {
            m_inputPanelVisible = true;
            emit inputPanelVisibleChanged();
        }
    }
}

qreal DeclarativeWebContainer::contentHeight() const
{
    if (m_webView) {
        return m_webView->contentHeight();
    } else {
        return 0.0;
    }
}

DeclarativeWebContainer::ScreenCapture DeclarativeWebContainer::saveToFile(QString url, QImage image, QRect cropBounds, int tabId, qreal rotate)
{
    QString path = QString("%1/tab-%2-thumb.png").arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)).arg(tabId);
    QTransform transform;
    transform.rotate(360 - rotate);
    image = image.transformed(transform);
    image = image.copy(cropBounds);

    ScreenCapture capture;
    if(image.save(path)) {
        capture.tabId = tabId;
        capture.path = path;
        capture.url = url;
    } else {
        capture.tabId = -1;
        qWarning() << Q_FUNC_INFO << "failed to save image" << path;
    }
    return capture;
}

void DeclarativeWebContainer::timerEvent(QTimerEvent *event)
{
    if (m_backgroundTimer == event->timerId()) {
        if (window()) {
            // Guard window visibility change was not cancelled after timer triggered.
            bool tmpVisible = window()->isVisible();
            // m_windowVisible == m_background visibility changed
            if (tmpVisible == m_windowVisible && m_windowVisible == m_background) {
                m_background = !m_windowVisible;
                emit backgroundChanged();
            }
        }
        killTimer(m_backgroundTimer);
    }
}

void DeclarativeWebContainer::componentComplete()
{
    QQuickItem::componentComplete();
    QVariant var = property("tabModel");
    m_model = qobject_cast<DeclarativeTabModel *>(qvariant_cast<QObject*>(var));
    m_model->setCurrentTab(m_currentTab);
    connect(m_model, SIGNAL(_activeTabChanged(const Tab&)), this, SLOT(updateTabData(const Tab&)));
    connect(m_model, SIGNAL(_activeTabInvalidated()), this, SLOT(invalidateTabData()));
}

void DeclarativeWebContainer::windowVisibleChanged(bool visible)
{
    Q_UNUSED(visible);
    if (window()) {
        m_windowVisible = window()->isVisible();
        m_backgroundTimer = startTimer(1000);
    }
}

void DeclarativeWebContainer::handleWindowChanged(QQuickWindow *window)
{
    if (window) {
        connect(window, SIGNAL(visibleChanged(bool)), this, SLOT(windowVisibleChanged(bool)));
    }
}

void DeclarativeWebContainer::updateTabData(const Tab &tab)
{
    m_currentTab->updateTabData(tab);

#ifdef DEBUG_LOGS
    qDebug() << "canGoBack = " << m_canGoBack << "canGoForward = " << m_canGoForward << &tab;
#endif
    if (m_canGoForward != (tab.nextLink() > 0)) {
        m_canGoForward = tab.nextLink() > 0;
        emit canGoForwardChanged();
    }

    if (m_canGoBack != (tab.previousLink() > 0)) {
        m_canGoBack = tab.previousLink() > 0;
        emit canGoBackChanged();
    }
}

void DeclarativeWebContainer::invalidateTabData()
{
    m_currentTab->invalidateTabData();
    if (m_canGoForward) {
        m_canGoForward = false;
        emit canGoForwardChanged();
    }

    if (m_canGoBack) {
        m_canGoBack = false;
        emit canGoBack();
    }
}

void DeclarativeWebContainer::screenCaptureReady()
{
    ScreenCapture capture = m_screenCapturer.result();
#ifdef DEBUG_LOGS
    qDebug() << capture.tabId << capture.path << capture.url;
#endif
    if (capture.tabId != -1) {
        // Update immediately without dbworker round trip.
        if (capture.tabId == m_currentTab->tabId()) {
            m_currentTab->setThumbnailPath(capture.path);
        }
        // TODO: Cleanup url.
        DBManager::instance()->updateThumbPath(capture.url, capture.path, capture.tabId);
    }
}

void DeclarativeWebContainer::triggerLoad()
{
    bool realNavigation = m_realNavigation;
    m_realNavigation = false;
    if (m_webView && m_currentTab->valid() && !realNavigation && url() != "about:blank") {
        QMetaObject::invokeMethod(this, "load", Qt::DirectConnection,
                                  Q_ARG(QVariant, url()),
                                  Q_ARG(QVariant, title()),
                                  Q_ARG(QVariant, false));
    }
}

/**
 * @brief DeclarativeTab::captureScreen
 * Rotation transformation is applied first, then geometry values on top of it.
 * @param url
 * @param size
 * @param rotate clockwise rotation of the image in degrees
 */
void DeclarativeWebContainer::captureScreen(QString url, int size, qreal rotate)
{
    if (!window() || !window()->isActive() || !m_currentTab->valid()) {
        return;
    }

    // Cleanup old thumb.
    m_currentTab->setThumbnailPath("");

    QImage image = window()->grabWindow();
    QRect cropBounds(0, 0, size, size);

#ifdef DEBUG_LOGS
    qDebug() << "about to set future";
#endif
    // asynchronous save to avoid the slow I/O
    m_screenCapturer.setFuture(QtConcurrent::run(this, &DeclarativeWebContainer::saveToFile, url, image, cropBounds, m_currentTab->tabId(), rotate));
}
<commit_msg>Fix back / forward navigation error to not trigger load when not needed<commit_after>/****************************************************************************
**
** Copyright (C) 2013 Jolla Ltd.
** Contact: Raine Makelainen <raine.makelainen@jollamobile.com>
**
****************************************************************************/

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "declarativewebcontainer.h"
#include "declarativetab.h"
#include "declarativetabmodel.h"
#include "dbmanager.h"

#include <QPointer>
#include <QTimerEvent>
#include <QQuickWindow>
#include <quickmozview.h>
#include <QDir>
#include <QTransform>
#include <QStandardPaths>
#include <QtConcurrentRun>
#include <QGuiApplication>
#include <QScreen>

#include <QMetaMethod>

DeclarativeWebContainer::DeclarativeWebContainer(QQuickItem *parent)
    : QQuickItem(parent)
    , m_webView(0)
    , m_model(0)
    , m_currentTab(new DeclarativeTab(this))
    , m_foreground(true)
    , m_background(false)
    , m_windowVisible(false)
    , m_backgroundTimer(0)
    , m_active(false)
    , m_popupActive(false)
    , m_portrait(true)
    , m_fullScreenMode(false)
    , m_inputPanelVisible(false)
    , m_inputPanelHeight(0.0)
    , m_inputPanelOpenHeight(0.0)
    , m_toolbarHeight(0.0)
    , m_canGoForward(false)
    , m_canGoBack(false)
    , m_realNavigation(false)
    , m_firstFrameRendered(false)
{
    setFlag(QQuickItem::ItemHasContents, true);
    connect(m_currentTab, SIGNAL(titleChanged()), this, SIGNAL(titleChanged()));
    connect(m_currentTab, SIGNAL(urlChanged()), this, SIGNAL(urlChanged()));
    connect(m_currentTab, SIGNAL(urlChanged()), this, SLOT(triggerLoad()));
    if (!window()) {
        connect(this, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(handleWindowChanged(QQuickWindow*)));
    } else {
        connect(window(), SIGNAL(visibleChanged(bool)), this, SLOT(windowVisibleChanged(bool)));
    }

    connect(&m_screenCapturer, SIGNAL(finished()), this, SLOT(screenCaptureReady()));

    QString cacheLocation = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
    QDir dir(cacheLocation);
    if(!dir.exists() && !dir.mkpath(cacheLocation)) {
        qWarning() << "Can't create directory "+ cacheLocation;
        return;
    }
}

DeclarativeWebContainer::~DeclarativeWebContainer()
{
    // Disconnect all signal slot connections
    if (m_webView) {
        disconnect(m_webView, 0, 0, 0);
    }

    m_screenCapturer.cancel();
    m_screenCapturer.waitForFinished();
}

QuickMozView *DeclarativeWebContainer::webView() const
{
    return m_webView;
}

void DeclarativeWebContainer::setWebView(QuickMozView *webView)
{
    if (m_webView != webView) {
        if (m_webView) {
            disconnect(m_webView);
        }

        if (webView) {
            connect(webView, SIGNAL(imeNotification(int,bool,int,int,QString)),
                    this, SLOT(imeNotificationChanged(int,bool,int,int,QString)));
            connect(webView, SIGNAL(contentHeightChanged()), this, SLOT(resetHeight()));
            connect(webView, SIGNAL(scrollableOffsetChanged()), this, SLOT(resetHeight()));
            connect(this, SIGNAL(heightChanged()), this, SLOT(resetHeight()));
        }
        m_webView = webView;
        emit contentItemChanged();
    }
}

bool DeclarativeWebContainer::foreground() const
{
    return m_foreground;
}

void DeclarativeWebContainer::setForeground(bool active)
{
    if (m_foreground != active) {
        m_foreground = active;

        if (!m_foreground) {
            // Respect content height when browser brought back from home
            resetHeight(true);
        }
        emit foregroundChanged();
    }
}

bool DeclarativeWebContainer::background() const
{
    return m_background;
}

bool DeclarativeWebContainer::active() const
{
    return m_active;
}

void DeclarativeWebContainer::setActive(bool active)
{
    if (m_active != active) {
        m_active = active;
        emit activeChanged();

        // If dialog has been opened, we need to verify that input panel is not visible.
        // This might happen when the user fills in login details to a form and
        // presses enter to accept the form after which PasswordManagerDialog is pushed to pagestack
        // on top the BrowserPage. Once PassowordManagerDialog is accepted/rejected
        // this condition can be met. If active changes to true before keyboard is fully closed,
        // then the inputPanelVisibleChanged() signal is emitted by setInputPanelHeight.
        if (m_active && m_inputPanelHeight == 0 && m_inputPanelVisible) {
            m_inputPanelVisible = false;
            emit inputPanelVisibleChanged();
        }
    }
}

bool DeclarativeWebContainer::inputPanelVisible() const
{
    return m_inputPanelVisible;
}

qreal DeclarativeWebContainer::inputPanelHeight() const
{
    return m_inputPanelHeight;
}

void DeclarativeWebContainer::setInputPanelHeight(qreal height)
{
    if (m_inputPanelHeight != height) {
        bool imVisibleChanged = false;
        m_inputPanelHeight = height;
        if (m_active) {
            if (m_inputPanelHeight == 0) {
                if (m_inputPanelVisible) {
                    m_inputPanelVisible = false;
                    imVisibleChanged = true;
                }
            } else if (m_inputPanelHeight == m_inputPanelOpenHeight) {
                if (!m_inputPanelVisible) {
                    m_inputPanelVisible = true;
                    imVisibleChanged = true;
                }
            }
        }

        if (imVisibleChanged) {
            emit inputPanelVisibleChanged();
        }

        emit inputPanelHeightChanged();
    }
}

bool DeclarativeWebContainer::canGoForward() const
{
    return m_canGoForward;
}

bool DeclarativeWebContainer::canGoBack() const
{
    return m_canGoBack;
}

QString DeclarativeWebContainer::title() const
{
    return m_currentTab->title();
}

QString DeclarativeWebContainer::url() const
{
    return m_currentTab->url();
}

DeclarativeTab *DeclarativeWebContainer::currentTab() const
{
    return m_currentTab;
}

void DeclarativeWebContainer::goForward()
{
    if (m_canGoForward && m_currentTab->valid()) {
        m_currentTab->activateNextLink();
        if (m_webView && m_webView->canGoForward()) {
            m_realNavigation = true;
            m_webView->goForward();
        } else {
            m_realNavigation = false;
        }

        m_model->setBackForwardNavigation(true);
        DBManager::instance()->goForward(m_model->currentTabId());
    }
}

void DeclarativeWebContainer::goBack()
{
    if (m_canGoBack && m_currentTab->valid()) {
        m_currentTab->activatePreviousLink();
        if (m_webView && m_webView->canGoBack()) {
            m_realNavigation = true;
            m_webView->goBack();
        } else {
            m_realNavigation = false;
        }

        m_model->setBackForwardNavigation(true);
        DBManager::instance()->goBack(m_model->currentTabId());
    }
}

void DeclarativeWebContainer::captureScreen()
{
    if (!m_webView) {
        return;
    }

    if (m_active && m_firstFrameRendered && !m_popupActive) {
        int size = QGuiApplication::primaryScreen()->size().width();
        if (!m_portrait && !m_fullScreenMode) {
            size -= m_toolbarHeight;
        }

        qreal rotation = parentItem() ? parentItem()->rotation() : 0;
        captureScreen(url(), size, rotation);
    }
}

void DeclarativeWebContainer::resetHeight(bool respectContentHeight)
{
    if (!m_webView || !m_webView->state().isEmpty()) {
        return;
    }

    qreal fullHeight = height();

    // Application active
    if (respectContentHeight) {
        // Handle webView height over here, BrowserPage.qml loading
        // reset might be redundant as we have also loaded trigger
        // reset. However, I'd leave it there for safety reasons.
        // We need to reset height always back to short height when loading starts
        // so that after tab change there is always initial short composited height.
        // Height may expand when content is moved.
        if (contentHeight() > fullHeight + m_toolbarHeight) {
            m_webView->setHeight(fullHeight);
        } else {
            m_webView->setHeight(fullHeight - m_toolbarHeight);
        }
    } else {
        m_webView->setHeight(fullHeight - m_toolbarHeight);
    }
}

void DeclarativeWebContainer::imeNotificationChanged(int state, bool open, int cause, int focusChange, const QString &type)
{
    Q_UNUSED(open)
    Q_UNUSED(cause)
    Q_UNUSED(focusChange)
    Q_UNUSED(type)

    // QmlMozView's input context open is actually intention (0 closed, 1 opened).
    // cause 3 equals InputContextAction::CAUSE_MOUSE nsIWidget.h
    if (state == 1 && cause == 3) {
        // For safety reset height based on contentHeight before going to "boundHeightControl" state
        // so that when vkb is closed we get correctly reset height back.
        resetHeight(true);
        if (!m_inputPanelVisible) {
            m_inputPanelVisible = true;
            emit inputPanelVisibleChanged();
        }
    }
}

qreal DeclarativeWebContainer::contentHeight() const
{
    if (m_webView) {
        return m_webView->contentHeight();
    } else {
        return 0.0;
    }
}

DeclarativeWebContainer::ScreenCapture DeclarativeWebContainer::saveToFile(QString url, QImage image, QRect cropBounds, int tabId, qreal rotate)
{
    QString path = QString("%1/tab-%2-thumb.png").arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)).arg(tabId);
    QTransform transform;
    transform.rotate(360 - rotate);
    image = image.transformed(transform);
    image = image.copy(cropBounds);

    ScreenCapture capture;
    if(image.save(path)) {
        capture.tabId = tabId;
        capture.path = path;
        capture.url = url;
    } else {
        capture.tabId = -1;
        qWarning() << Q_FUNC_INFO << "failed to save image" << path;
    }
    return capture;
}

void DeclarativeWebContainer::timerEvent(QTimerEvent *event)
{
    if (m_backgroundTimer == event->timerId()) {
        if (window()) {
            // Guard window visibility change was not cancelled after timer triggered.
            bool tmpVisible = window()->isVisible();
            // m_windowVisible == m_background visibility changed
            if (tmpVisible == m_windowVisible && m_windowVisible == m_background) {
                m_background = !m_windowVisible;
                emit backgroundChanged();
            }
        }
        killTimer(m_backgroundTimer);
    }
}

void DeclarativeWebContainer::componentComplete()
{
    QQuickItem::componentComplete();
    QVariant var = property("tabModel");
    m_model = qobject_cast<DeclarativeTabModel *>(qvariant_cast<QObject*>(var));
    m_model->setCurrentTab(m_currentTab);
    connect(m_model, SIGNAL(_activeTabChanged(const Tab&)), this, SLOT(updateTabData(const Tab&)));
    connect(m_model, SIGNAL(_activeTabInvalidated()), this, SLOT(invalidateTabData()));
}

void DeclarativeWebContainer::windowVisibleChanged(bool visible)
{
    Q_UNUSED(visible);
    if (window()) {
        m_windowVisible = window()->isVisible();
        m_backgroundTimer = startTimer(1000);
    }
}

void DeclarativeWebContainer::handleWindowChanged(QQuickWindow *window)
{
    if (window) {
        connect(window, SIGNAL(visibleChanged(bool)), this, SLOT(windowVisibleChanged(bool)));
    }
}

void DeclarativeWebContainer::updateTabData(const Tab &tab)
{
    m_currentTab->updateTabData(tab);

#ifdef DEBUG_LOGS
    qDebug() << "canGoBack = " << m_canGoBack << "canGoForward = " << m_canGoForward << &tab;
#endif
    if (m_canGoForward != (tab.nextLink() > 0)) {
        m_canGoForward = tab.nextLink() > 0;
        emit canGoForwardChanged();
    }

    if (m_canGoBack != (tab.previousLink() > 0)) {
        m_canGoBack = tab.previousLink() > 0;
        emit canGoBackChanged();
    }
}

void DeclarativeWebContainer::invalidateTabData()
{
    m_currentTab->invalidateTabData();
    if (m_canGoForward) {
        m_canGoForward = false;
        emit canGoForwardChanged();
    }

    if (m_canGoBack) {
        m_canGoBack = false;
        emit canGoBack();
    }
}

void DeclarativeWebContainer::screenCaptureReady()
{
    ScreenCapture capture = m_screenCapturer.result();
#ifdef DEBUG_LOGS
    qDebug() << capture.tabId << capture.path << capture.url;
#endif
    if (capture.tabId != -1) {
        // Update immediately without dbworker round trip.
        if (capture.tabId == m_currentTab->tabId()) {
            m_currentTab->setThumbnailPath(capture.path);
        }
        // TODO: Cleanup url.
        DBManager::instance()->updateThumbPath(capture.url, capture.path, capture.tabId);
    }
}

void DeclarativeWebContainer::triggerLoad()
{
    bool realNavigation = m_realNavigation;
    m_realNavigation = false;
    // Back / forward navigation activated and MozView instance cannot be used.
    if (m_webView && m_currentTab->valid() && m_model->backForwardNavigation() && !realNavigation && url() != "about:blank") {
        QMetaObject::invokeMethod(this, "load", Qt::DirectConnection,
                                  Q_ARG(QVariant, url()),
                                  Q_ARG(QVariant, title()),
                                  Q_ARG(QVariant, false));
    }
}

/**
 * @brief DeclarativeTab::captureScreen
 * Rotation transformation is applied first, then geometry values on top of it.
 * @param url
 * @param size
 * @param rotate clockwise rotation of the image in degrees
 */
void DeclarativeWebContainer::captureScreen(QString url, int size, qreal rotate)
{
    if (!window() || !window()->isActive() || !m_currentTab->valid()) {
        return;
    }

    // Cleanup old thumb.
    m_currentTab->setThumbnailPath("");

    QImage image = window()->grabWindow();
    QRect cropBounds(0, 0, size, size);

#ifdef DEBUG_LOGS
    qDebug() << "about to set future";
#endif
    // asynchronous save to avoid the slow I/O
    m_screenCapturer.setFuture(QtConcurrent::run(this, &DeclarativeWebContainer::saveToFile, url, image, cropBounds, m_currentTab->tabId(), rotate));
}
<|endoftext|>


<commit_before>#include "ghost/densemat_rm.h"
#include "ghost/util.h"
#include "ghost/locality.h"
#include <complex>

#define ROWMAJOR
#include "ghost/densemat_iter_macros.h"

//TODO fix this- for some reasons broken

template<typename T>
static ghost_error ghost_densemat_rm_averagehalo_tmpl(ghost_densemat *vec, ghost_context *ctx)
{
#ifdef GHOST_HAVE_MPI
    GHOST_FUNC_ENTER(GHOST_FUNCTYPE_COMMUNICATION);
    ghost_error ret = GHOST_SUCCESS;

    int rank, nrank, i, j,  ctr, start, d, acc_dues = 0;
    T *work = NULL, *curwork = NULL;
    MPI_Request *req = NULL;
    T *sum = NULL;

/*    if (vec->traits.ncols > 1) {
        ERROR_LOG("Multi-vec case not yet implemented");
        ret = GHOST_ERR_NOT_IMPLEMENTED;
        goto err;
    }
*/

    if (ctx == NULL) {
        WARNING_LOG("Trying to average the halos of a densemat which has no context!");
        goto out;
    }

    GHOST_CALL_GOTO(ghost_rank(&rank,ctx->mpicomm),err,ret);
    GHOST_CALL_GOTO(ghost_nrank(&nrank,ctx->mpicomm),err,ret);

  if(nrank > 1) {
    for (i=0; i<nrank; i++) {
       acc_dues += ctx->dues[i];
    }

    GHOST_CALL_GOTO(ghost_malloc((void **)&work, vec->traits.ncols*acc_dues*sizeof(T)),err,ret);
    GHOST_CALL_GOTO(ghost_malloc((void **)&req, 2*nrank*sizeof(MPI_Request)),err,ret);

    for (i=0; i<2*nrank; i++) {
        req[i] = MPI_REQUEST_NULL;
    }

   /* if(ctx->perm_local && ctx->flags & GHOST_PERM_NO_DISTINCTION){
    	for (int to_PE=0; to_PE<nrank; to_PE++) {
		T* packed_data;
		GHOST_CALL_GOTO(ghost_malloc((void **)&packed_data, ctx->wishes[to_PE]*vec->traits.ncols*vec->elSize),err,ret);

    //   printf("packed data\n");
		for (int i=0; i<ctx->wishes[to_PE]; i++){
                    for (int c=0; c<vec->traits.ncols; c++) {
                       memcpy(&packed_data[(c*ctx->wishes[to_PE]+i)],DENSEMAT_VALPTR(vec,ctx->perm_local->colPerm[ctx->hput_pos[to_PE]+i],c),vec->elSize);
//			printf("%f\n",packed_data[(c*ctx->wishes[to_PE]+i)]);

                    }
                }
               //TODO blocking and delete packed_data
               MPI_CALL_GOTO(MPI_Isend(packed_data,ctx->wishes[to_PE]*vec->traits.ncols,vec->mpidt,to_PE,rank,ctx->mpicomm,&req[to_PE]),err,ret);

   	}

    } else {*/
    for (i=0; i<nrank; i++) {
      MPI_CALL_GOTO(MPI_Isend(&((T *)vec->val)[ctx->hput_pos[i]*vec->traits.ncols],ctx->wishes[i]*vec->traits.ncols,vec->mpidt,i,rank,ctx->mpicomm,&req[i]),err,ret);
    }
   // }

    curwork = work;
    for (i=0; i<nrank; i++) {
        MPI_CALL_GOTO(MPI_Irecv(curwork,ctx->dues[i]*vec->traits.ncols,vec->mpidt,i,i,ctx->mpicomm,&req[nrank+i]),err,ret);
        curwork += ctx->dues[i];
    }

    MPI_CALL_GOTO(MPI_Waitall(2*nrank,req,MPI_STATUSES_IGNORE),err,ret);
    GHOST_CALL_GOTO(ghost_malloc((void **)&sum,vec->traits.ncols*ctx->nElemAvg*sizeof(T)),err,ret);

  #pragma omp parallel for schedule(runtime)   //which one to parallelise(inner or outer) depends on the matrix
   for(int i=0 ; i<ctx->nChunkAvg; ++i) {
  // #pragma omp parallel for schedule(runtime) private(j,k,ctr)
      for(int j=ctx->avg_ptr[2*i]; j<ctx->avg_ptr[2*i+1]; ++j) {
        int ctr = ctx->mapAvg[j];
        if(ctx->perm_local && ctx->perm_local->colInvPerm[j]<ctx->lnrows[rank]) {
          if(ctx->entsInCol[ctx->perm_local->colInvPerm[j]] != 0) {//this is necessary since there can be cases where only halos are present
            for(int k=0; k<vec->traits.ncols; ++k) {
              sum[ctr*vec->traits.ncols+k] = ((T *)vec->val)[j*vec->traits.ncols+k];
            }
          } else {
          for(int k=0; k<vec->traits.ncols; ++k) {
            sum[ctr*vec->traits.ncols+k] = 0;
          }
        }
      } else {
          if(ctx->entsInCol[j] != 0) {//this is necessary since there can be cases where only halos are present
            for(int k=0; k<vec->traits.ncols; ++k) {
              sum[ctr*vec->traits.ncols+k] = ((T *)vec->val)[j*vec->traits.ncols+k];
            }
          } else {
          for(int k=0; k<vec->traits.ncols; ++k) {
            sum[ctr*vec->traits.ncols+k] = 0;
          }
        }
      }
    }
  }

    curwork = work;

start = 0;
for (i=0; i<nrank; i++) {
  start += (i==0?0:ctx->dues[i-1]);
  #pragma omp parallel for schedule(static) private(d,j,ctr)
  for (d=0 ;d < ctx->dues[i]; d++) {
    ctr = start + d;
	  for(j=0 ; j<vec->traits.ncols; ++j) {
     // printf("idx = %d\tsum=%f\n",(ctx->mappedDuelist[ctr])*vec->traits.ncols+j,sum[(ctx->mappedDuelist[ctr])*vec->traits.ncols+j]);
      sum[(ctx->mappedDuelist[ctr])*vec->traits.ncols+j] += curwork[d*vec->traits.ncols+j];
    }
  }
  curwork += ctx->dues[i]*vec->traits.ncols;
}

#pragma omp parallel for schedule(runtime)
for(int i=0 ; i<ctx->nChunkAvg; ++i) {
//  #pragma omp parallel for schedule(runtime) private(j,k,ctr)
  for(int j=ctx->avg_ptr[2*i]; j<ctx->avg_ptr[2*i+1]; ++j) {
    int ctr = ctx->mapAvg[j];
    for(int k=0; k<vec->traits.ncols; ++k) {
      ((T *)vec->val)[j*vec->traits.ncols+k] = sum[ctr*vec->traits.ncols+k]/(T)ctx->nrankspresent[ctr];
    }
  }
}

    goto out;
err:

out:
    free(sum);
    free(work);
    free(req);
    GHOST_FUNC_EXIT(GHOST_FUNCTYPE_COMMUNICATION);
    return ret;

  } else {
   return ret;
  }

#else
    UNUSED(vec);
    ERROR_LOG("MPI is required!");
    return GHOST_ERR_MPI;
#endif
}

ghost_error ghost_densemat_rm_averagehalo_selector(ghost_densemat *vec, ghost_context *ctx)
{
    GHOST_FUNC_ENTER(GHOST_FUNCTYPE_COMMUNICATION);
    ghost_error ret = GHOST_SUCCESS;

    SELECT_TMPL_1DATATYPE(vec->traits.datatype,std::complex,ret,ghost_densemat_rm_averagehalo_tmpl,vec,ctx);

    GHOST_FUNC_EXIT(GHOST_FUNCTYPE_COMMUNICATION);
    return ret;
}
<commit_msg>Fix densemat_rm_average for block vector<commit_after>#include "ghost/densemat_rm.h"
#include "ghost/util.h"
#include "ghost/locality.h"
#include <complex>

#define ROWMAJOR
#include "ghost/densemat_iter_macros.h"

template<typename T>
static ghost_error ghost_densemat_rm_averagehalo_tmpl(ghost_densemat *vec, ghost_context *ctx)
{
#ifdef GHOST_HAVE_MPI
    GHOST_FUNC_ENTER(GHOST_FUNCTYPE_COMMUNICATION);
    ghost_error ret = GHOST_SUCCESS;

    int rank, nrank, i, j,  ctr, start, d, acc_dues = 0;
    T *work = NULL, *curwork = NULL;
    MPI_Request *req = NULL;
    T *sum = NULL;

/*    if (vec->traits.ncols > 1) {
        ERROR_LOG("Multi-vec case not yet implemented");
        ret = GHOST_ERR_NOT_IMPLEMENTED;
        goto err;
    }
*/

    if (ctx == NULL) {
        WARNING_LOG("Trying to average the halos of a densemat which has no context!");
        goto out;
    }

    GHOST_CALL_GOTO(ghost_rank(&rank,ctx->mpicomm),err,ret);
    GHOST_CALL_GOTO(ghost_nrank(&nrank,ctx->mpicomm),err,ret);

  if(nrank > 1) {
    for (i=0; i<nrank; i++) {
       acc_dues += ctx->dues[i];
    }

    GHOST_CALL_GOTO(ghost_malloc((void **)&work, vec->traits.ncols*acc_dues*sizeof(T)),err,ret);
    GHOST_CALL_GOTO(ghost_malloc((void **)&req, 2*nrank*sizeof(MPI_Request)),err,ret);

    for (i=0; i<2*nrank; i++) {
        req[i] = MPI_REQUEST_NULL;
    }

   /* if(ctx->perm_local && ctx->flags & GHOST_PERM_NO_DISTINCTION){
    	for (int to_PE=0; to_PE<nrank; to_PE++) {
		T* packed_data;
		GHOST_CALL_GOTO(ghost_malloc((void **)&packed_data, ctx->wishes[to_PE]*vec->traits.ncols*vec->elSize),err,ret);

    //   printf("packed data\n");
		for (int i=0; i<ctx->wishes[to_PE]; i++){
                    for (int c=0; c<vec->traits.ncols; c++) {
                       memcpy(&packed_data[(c*ctx->wishes[to_PE]+i)],DENSEMAT_VALPTR(vec,ctx->perm_local->colPerm[ctx->hput_pos[to_PE]+i],c),vec->elSize);
//			printf("%f\n",packed_data[(c*ctx->wishes[to_PE]+i)]);

                    }
                }
               //TODO blocking and delete packed_data
               MPI_CALL_GOTO(MPI_Isend(packed_data,ctx->wishes[to_PE]*vec->traits.ncols,vec->mpidt,to_PE,rank,ctx->mpicomm,&req[to_PE]),err,ret);

   	}

    } else {*/
    for (i=0; i<nrank; i++) {
      MPI_CALL_GOTO(MPI_Isend(&((T *)vec->val)[ctx->hput_pos[i]*vec->traits.ncols],ctx->wishes[i]*vec->traits.ncols,vec->mpidt,i,rank,ctx->mpicomm,&req[i]),err,ret);
    }
   // }

    curwork = work;
    for (i=0; i<nrank; i++) {
        MPI_CALL_GOTO(MPI_Irecv(curwork,ctx->dues[i]*vec->traits.ncols,vec->mpidt,i,i,ctx->mpicomm,&req[nrank+i]),err,ret);
        curwork += ctx->dues[i]*vec->traits.ncols;
    }

    MPI_CALL_GOTO(MPI_Waitall(2*nrank,req,MPI_STATUSES_IGNORE),err,ret);
    GHOST_CALL_GOTO(ghost_malloc((void **)&sum,vec->traits.ncols*ctx->nElemAvg*sizeof(T)),err,ret);

  #pragma omp parallel for schedule(runtime)   //which one to parallelise(inner or outer) depends on the matrix
   for(int i=0 ; i<ctx->nChunkAvg; ++i) {
  // #pragma omp parallel for schedule(runtime) private(j,k,ctr)
      for(int j=ctx->avg_ptr[2*i]; j<ctx->avg_ptr[2*i+1]; ++j) {
        int ctr = ctx->mapAvg[j];
        if(ctx->perm_local && ctx->perm_local->colInvPerm[j]<ctx->lnrows[rank]) {
          if(ctx->entsInCol[ctx->perm_local->colInvPerm[j]] != 0) {//this is necessary since there can be cases where only halos are present
            for(int k=0; k<vec->traits.ncols; ++k) {
              sum[ctr*vec->traits.ncols+k] = ((T *)vec->val)[j*vec->traits.ncols+k];
            }
          } else {
          for(int k=0; k<vec->traits.ncols; ++k) {
            sum[ctr*vec->traits.ncols+k] = 0;
          }
        }
      } else {
          if(ctx->entsInCol[j] != 0) {//this is necessary since there can be cases where only halos are present
            for(int k=0; k<vec->traits.ncols; ++k) {
              sum[ctr*vec->traits.ncols+k] = ((T *)vec->val)[j*vec->traits.ncols+k];
            }
          } else {
          for(int k=0; k<vec->traits.ncols; ++k) {
            sum[ctr*vec->traits.ncols+k] = 0;
          }
        }
      }
    }
  }

 curwork = work;

start = 0;
for (i=0; i<nrank; i++) {
  start += (i==0?0:ctx->dues[i-1]);
  #pragma omp parallel for schedule(static) private(d,j,ctr)
  for (d=0 ;d < ctx->dues[i]; d++) {
    ctr = start + d;
	  for(j=0 ; j<vec->traits.ncols; ++j) {
     // printf("idx = %d\tsum=%f\n",(ctx->mappedDuelist[ctr])*vec->traits.ncols+j,sum[(ctx->mappedDuelist[ctr])*vec->traits.ncols+j]);
      sum[(ctx->mappedDuelist[ctr])*vec->traits.ncols+j] += curwork[d*vec->traits.ncols+j];
    }
  }
  curwork += ctx->dues[i]*vec->traits.ncols;
}

#pragma omp parallel for schedule(runtime)
for(int i=0 ; i<ctx->nChunkAvg; ++i) {
//  #pragma omp parallel for schedule(runtime) private(j,k,ctr)
  for(int j=ctx->avg_ptr[2*i]; j<ctx->avg_ptr[2*i+1]; ++j) {
    int ctr = ctx->mapAvg[j];
    for(int k=0; k<vec->traits.ncols; ++k) {
      ((T *)vec->val)[j*vec->traits.ncols+k] = sum[ctr*vec->traits.ncols+k]/(T)ctx->nrankspresent[ctr];
    }
  }
}

    goto out;
err:

out:
    free(sum);
    free(work);
    free(req);
    GHOST_FUNC_EXIT(GHOST_FUNCTYPE_COMMUNICATION);
    return ret;

  } else {
   return ret;
  }

#else
    UNUSED(vec);
    ERROR_LOG("MPI is required!");
    return GHOST_ERR_MPI;
#endif
}

ghost_error ghost_densemat_rm_averagehalo_selector(ghost_densemat *vec, ghost_context *ctx)
{
    GHOST_FUNC_ENTER(GHOST_FUNCTYPE_COMMUNICATION);
    ghost_error ret = GHOST_SUCCESS;

    SELECT_TMPL_1DATATYPE(vec->traits.datatype,std::complex,ret,ghost_densemat_rm_averagehalo_tmpl,vec,ctx);

    GHOST_FUNC_EXIT(GHOST_FUNCTYPE_COMMUNICATION);
    return ret;
}
<|endoftext|>


<commit_before>#include "./platform/UnitTestSupport.hpp"

#include <PluginFactory/PluginFactory.hpp>
#include <PluginFactory/Exceptions.hpp>

#include <vector>

namespace {

    class PluginInterface
    {
    public:
        virtual ~PluginInterface(){}
        virtual void foo() = 0;
    };

    struct PluginFactoryFixture
    {
        using PluginFactory = PluginFactory::PluginFactory<PluginInterface>;

        PluginFactoryFixture()
            : factory("./")
        {
        }

        PluginFactory factory;
    };

    TEST_FIXTURE(PluginFactoryFixture, verifyPluginFactoryInstantiation)
    {
    }

    TEST(verifyPluginFactoryInstantiationThrowsOnPathDoesntExist)
    {
        CHECK_THROW(PluginFactory::PluginFactory<PluginInterface> factory("/ThisPath/Doesnt/Exist"), PluginFactory::PluginPathDoesntExist);
    }

    TEST(verifyPluginFactoryInstantiationThrowsOnAPathWhichIsntDirectory)
    {
        CHECK_THROW(PluginFactory::PluginFactory<PluginInterface> factory("./cmake_install.cmake"), PluginFactory::PluginPathIsntDirectory);
    }

    TEST_FIXTURE(PluginFactoryFixture, verifyLoad)
    {
        auto plugins = factory.availablePlugins();
        CHECK_EQUAL(0U, plugins.size());
    }

    /////////////////////////////////////////////////////
    //
    // The tests below here don't proove anything, merely
    // ensure the class template methods are instantiated.
    //

    TEST_FIXTURE(PluginFactoryFixture, callLoadWithPath)
    {
        factory.load("path/to/plugin");
    }

    TEST_FIXTURE(PluginFactoryFixture, callUnloadWithPath)
    {
        factory.unload("path/to/plugin");
    }

    TEST_FIXTURE(PluginFactoryFixture, callCreatePlugin)
    {
        auto plugin = factory.instance("something");
    }

    TEST_FIXTURE(PluginFactoryFixture, callCreatePluginWithCreateShared)
    {
        auto plugin = factory.instance("something", PluginFactory::PluginFactory::create_shared);
    }
}
<commit_msg>Extending UT coverage to ensure more of PluginFactory class template is instantiated.<commit_after>#include "./platform/UnitTestSupport.hpp"

#include <PluginFactory/PluginFactory.hpp>
#include <PluginFactory/Exceptions.hpp>

#include <vector>

namespace {

    class PluginInterface
    {
    public:
        virtual ~PluginInterface(){}
        virtual void foo() = 0;
    };

    struct PluginFactoryFixture
    {
        using PluginFactory = PluginFactory::PluginFactory<PluginInterface>;

        PluginFactoryFixture()
            : factory("./")
        {
        }

        PluginFactory factory;
    };

    TEST_FIXTURE(PluginFactoryFixture, verifyPluginFactoryInstantiation)
    {
    }

    TEST(verifyPluginFactoryInstantiationThrowsOnPathDoesntExist)
    {
        CHECK_THROW(PluginFactory::PluginFactory<PluginInterface> factory("/ThisPath/Doesnt/Exist"), PluginFactory::PluginPathDoesntExist);
    }

    TEST(verifyPluginFactoryInstantiationThrowsOnAPathWhichIsntDirectory)
    {
        CHECK_THROW(PluginFactory::PluginFactory<PluginInterface> factory("./cmake_install.cmake"), PluginFactory::PluginPathIsntDirectory);
    }

    TEST(verifyPluginFactoryConstructionWithArguments)
    {
        PluginFactory::PluginFactory<PluginInterface> factory("./", 1, "abc", 0.0f);
    }

    TEST_FIXTURE(PluginFactoryFixture, verifyLoad)
    {
        auto plugins = factory.availablePlugins();
        CHECK_EQUAL(0U, plugins.size());
    }

    /////////////////////////////////////////////////////
    //
    // The tests below here don't proove anything, merely
    // ensure the class template methods are instantiated.
    //

    TEST_FIXTURE(PluginFactoryFixture, callLoad)
    {
        factory.load();
    }

    TEST_FIXTURE(PluginFactoryFixture, callLoadWithPath)
    {
        factory.load("path/to/plugin");
    }

    TEST_FIXTURE(PluginFactoryFixture, callUnload)
    {
        factory.unload();
    }

    TEST_FIXTURE(PluginFactoryFixture, callUnloadWithPath)
    {
        factory.unload("path/to/plugin");
    }

    TEST_FIXTURE(PluginFactoryFixture, callCreatePlugin)
    {
        auto plugin = factory.instance("something");
    }

    TEST_FIXTURE(PluginFactoryFixture, callCreatePluginWithCreateShared)
    {
        auto plugin = factory.instance("something", PluginFactory::PluginFactory::create_shared);
    }
}
<|endoftext|>


<commit_before>// $Id$
//
// Macro for loading libraries for mapping in AliRoot.
// It sets also the environment variable used to find mapping data.

void mlibs()
{
  // add include path
  // gSystem->SetIncludePath(" -I$MINSTALL/include");

  // load Root libraries
  gSystem->Load("libPhysics");

  // load mapping library
  gSystem->Load("libMUONmapping");

  // set path to mapping data
  if (! gSystem->Getenv("MINSTALL")) {
    TString dirPath = gSystem->Getenv("ALICE_ROOT");
    dirPath += "/MUON/mapping";
    AliMpFiles::SetTopPath(dirPath);
    gSystem->Setenv("MINSTALL", dirPath.Data());
    // cout << "AliMpFiles top path set to " << dirPath << endl;
  }
}
<commit_msg>Set include path to allow AClic compilation (Laurent)<commit_after>// $Id$
//
// Macro for loading libraries for mapping in AliRoot.
// It sets also the environment variable used to find mapping data.

void mlibs()
{
  // add include path
  // gSystem->SetIncludePath(" -I$MINSTALL/include");
  gSystem->SetIncludePath("-I$ALICE_ROOT/include -I$ALICE_ROOT/MUON/mapping");

  // load Root libraries
  gSystem->Load("libPhysics");

  // load mapping library
  gSystem->Load("libMUONmapping");

  // set path to mapping data
  if (! gSystem->Getenv("MINSTALL")) {
    TString dirPath = gSystem->Getenv("ALICE_ROOT");
    dirPath += "/MUON/mapping";
    AliMpFiles::SetTopPath(dirPath);
    gSystem->Setenv("MINSTALL", dirPath.Data());
    // cout << "AliMpFiles top path set to " << dirPath << endl;
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 Nickolas Pohilets
//
// This file is a part of the benchmarking suit for the CppEvents library and
// its analogues.
//
// 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 <ctime>
#include <stdio.h>

#include <set>
#include <list>
#include <windows.h>

#define MAKE_NS_1(X) namespace_##X
#define MAKE_NS_2(X) MAKE_NS_1(X)
#define MAKE_NS(X) MAKE_NS_2(X)

namespace MAKE_NS(SIGSLOT_DEFAULT_MT_POLICY) {

#include "sigslot.h"

class MyReciever : public sigslot::has_slots<>
{
public:
	void processFloat(float x) {}
	void processDouble(float x) {}
};

void test(unsigned N)
{
	sigslot::signal1<float> s1;
	MyReciever rcv;

	unsigned X1 = 0, X2 = 0, X3 = 0;

	for(int j=0; j<8; ++j)
	{
		clock_t c0 = clock();

		for(unsigned i = 0; i< N; ++i)
		{
			s1.connect(&rcv, &MyReciever::processFloat);
		}

		clock_t c1 = clock();

		for(int k=0; k<100; ++k)
		{
			s1(3.14f);
		}

		clock_t c2 = clock();

		s1.disconnect_all();

		clock_t c3 = clock();

		X1 += (unsigned)(c1 - c0);
		X2 += (unsigned)(c2 - c1);
		X3 += (unsigned)(c3 - c2);
	}
	printf("%8u\t%06u\t%06u\t%06u\n", N, X1, X2, X3);
}

#define XX_1(X) #X
#define XX_2(X) XX_1(X)
#define XX(X) XX_2(X)

void runTest()
{
	printf("SigSlot.%s speed test\n", XX(SIGSLOT_DEFAULT_MT_POLICY));
	printf("  Repetitions   Connect Invoke Disconnect\n");
	for(unsigned a = 1000; a < 100000; )
	{
		unsigned x = a;
		for(unsigned i=0; i<9; ++i)
		{
			test(x);
			x += a;
		}
		a = x;
	}
}

} // namespace MAKE_NS(SIGSLOT_DEFAULT_MT_POLICY)

using namespace MAKE_NS(SIGSLOT_DEFAULT_MT_POLICY);

<commit_msg>-: #include <Windows.h> removed SigSlot test<commit_after>// Copyright (c) 2010 Nickolas Pohilets
//
// This file is a part of the benchmarking suit for the CppEvents library and
// its analogues.
//
// 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 <ctime>
#include <stdio.h>

#include <set>
#include <list>

#define MAKE_NS_1(X) namespace_##X
#define MAKE_NS_2(X) MAKE_NS_1(X)
#define MAKE_NS(X) MAKE_NS_2(X)

namespace MAKE_NS(SIGSLOT_DEFAULT_MT_POLICY) {

#include "sigslot.h"

class MyReciever : public sigslot::has_slots<>
{
public:
	void processFloat(float x) {}
	void processDouble(float x) {}
};

void test(unsigned N)
{
	sigslot::signal1<float> s1;
	MyReciever rcv;

	unsigned X1 = 0, X2 = 0, X3 = 0;

	for(int j=0; j<8; ++j)
	{
		clock_t c0 = clock();

		for(unsigned i = 0; i< N; ++i)
		{
			s1.connect(&rcv, &MyReciever::processFloat);
		}

		clock_t c1 = clock();

		for(int k=0; k<100; ++k)
		{
			s1(3.14f);
		}

		clock_t c2 = clock();

		s1.disconnect_all();

		clock_t c3 = clock();

		X1 += (unsigned)(c1 - c0);
		X2 += (unsigned)(c2 - c1);
		X3 += (unsigned)(c3 - c2);
	}
	printf("%8u\t%06u\t%06u\t%06u\n", N, X1, X2, X3);
}

#define XX_1(X) #X
#define XX_2(X) XX_1(X)
#define XX(X) XX_2(X)

void runTest()
{
	printf("SigSlot.%s speed test\n", XX(SIGSLOT_DEFAULT_MT_POLICY));
	printf("  Repetitions   Connect Invoke Disconnect\n");
	for(unsigned a = 1000; a < 100000; )
	{
		unsigned x = a;
		for(unsigned i=0; i<9; ++i)
		{
			test(x);
			x += a;
		}
		a = x;
	}
}

} // namespace MAKE_NS(SIGSLOT_DEFAULT_MT_POLICY)

using namespace MAKE_NS(SIGSLOT_DEFAULT_MT_POLICY);

<|endoftext|>


<commit_before>/**
 * Copyright (c) 2017 Darius Rückert
 * Licensed under the MIT License.
 * See LICENSE file for more information.
 */

#include "saiga/vision/imu/Solver.h"
#include "saiga/vision/util/Random.h"

#include "gtest/gtest.h"

#include "compare_numbers.h"
#include "numeric_derivative.h"
namespace Saiga
{
// Generates smooth imu measurements
std::vector<Imu::ImuSequence> GenerateRandomSequence(int N, int K, double dt)
{
    std::vector<Imu::ImuSequence> data;
    double t = 0;

    data.push_back(Imu::ImuSequence());
    data.front().time_end = t;

    Vec3 o   = Vec3::Random() * 0.02;
    Vec3 acc = Vec3::Random() * 0.2;

    for (int i = 0; i < N - 1; ++i)
    {
        Imu::ImuSequence seq;
        seq.time_begin = t;

        int this_K = Random::uniformInt(K / 2, K * 10);
        for (int k = 0; k < this_K; ++k)
        {
            Imu::Data id;
            o += Vec3::Random() * 0.01 * dt;
            acc += Vec3::Random() * 0.1 * dt;
            id.omega        = o;
            id.acceleration = acc;  // Vec3::Random() * 0.1;
            id.timestamp    = t;
            seq.data.push_back(id);
            t += dt;
        }
        seq.time_end = t;

        data.push_back(seq);
    }
    Imu::InterpolateMissingValues(data);

    return data;
}

namespace Imu
{
Vec9 ImuError(const ImuSequence& s, const VelocityAndBias& vb_i, const SE3& pose_i, const VelocityAndBias& vb_j,
              const SE3& pose_j, const Vec3& g, Matrix<double, 9, 3>* J_P_biasa = nullptr,
              Matrix<double, 9, 3>* J_R_biasg = nullptr)
{
    Vec9 residual = Vec9::Zero();

    auto Pi = pose_i.translation();
    auto Pj = pose_j.translation();

    auto Vi = vb_i.velocity;
    auto Vj = vb_j.velocity;

    auto Ri = pose_i.so3();
    auto Rj = pose_j.so3();

    auto RiT = Ri.inverse();
    auto RjT = Rj.inverse();

    Preintegration preint(vb_i);
    preint.IntegrateMidPoint(s);

    double dTij = preint.delta_t;
    double dT2  = dTij * dTij;

    Vec3 dPij = preint.delta_x;
    Vec3 dVij = preint.delta_v;

    //    auto prediction = preint.Predict(pose_i, vb_i.velocity, g);

    // residual error of Delta Position measurement
    Vec3 rPij = RiT * (Pj - Pi - Vi * dTij - 0.5 * g * dT2) - dPij;
    // - (dPij + M.getJPBiasg() * dBgi + M.getJPBiasa() * dBai);  // this line includes correction term of bias change.
    // residual error of Delta Velocity measurement
    Vec3 rVij = RiT * (Vj - Vi - g * dTij) - dVij;
    // - (dVij + M.getJVBiasg() * dBgi + M.getJVBiasa() * dBai);  // this line includes correction term of bias change

    // Rotation
    Sophus::SO3 dRij = Sophus::SO3(preint.delta_R);

    Sophus::SO3 rRij = (dRij).inverse() * RiT * Rj;
    Vec3 rPhiij      = rRij.log();

    residual.segment<3>(0) = rPij;    // position error
    residual.segment<3>(3) = rVij;    // velocity error
    residual.segment<3>(6) = rPhiij;  // rotation phi error

    if (J_R_biasg)
    {
        J_R_biasg->setZero();

        Mat3 JrInv_rPhi;
        Sophus::rightJacobianInvSO3(rPhiij, JrInv_rPhi);

        Mat3 ExprPhiijTrans = Sophus::SO3d::exp(rPhiij).inverse().matrix();

        //        Mat3 JrBiasGCorr = Sophus::rightJacobianSO3(J_rPhi_dbg * dBgi);

        //          Matrix3d J_rPhi_dbg = M.getJRBiasg();

        J_R_biasg->block<3, 3>(0, 0) = -preint.J_P_Biasg;
        J_R_biasg->block<3, 3>(3, 0) = -preint.J_V_Biasg;

        J_R_biasg->block<3, 3>(6, 0) = -JrInv_rPhi * ExprPhiijTrans /** JrBiasGCorr*/ * preint.J_R_Biasg;
        //        J_R_biasg -
        //        std::cout << preint.J_P_Biasg << std::endl;
        //        std::cout << preint.J_V_Biasg << std::endl;
    }

    return residual;
}
}  // namespace Imu

TEST(Imu, SaveLoad)
{
    Random::setSeed(95665);
    auto s = GenerateRandomSequence(10, 5, 0.1)[1];

    Imu::VelocityAndBias vb_i, vb_j;
    vb_i.velocity  = Vec3::Random();
    vb_i.gyro_bias = Vec3::Random();
    vb_i.acc_bias  = Vec3::Random();

    vb_j = vb_i;

    Vec3 g = Vec3::Random().normalized() * 9.81;

    SE3 pose_i = SE3();  // Random::randomSE3();

    SE3 pose_j;

    {
        Imu::Preintegration preint(vb_i.gyro_bias, vb_i.acc_bias);
        preint.IntegrateMidPoint(s);
        auto p_v      = preint.Predict(pose_i, vb_i.velocity, g);
        pose_j        = Sophus::se3_expd(Sophus::Vector6d::Random() * 0.2) * p_v.first;
        vb_j.velocity = p_v.second + Vec3::Random() * 0.01;
    }

    Vec9 res1, res2;
    Matrix<double, 9, 3> J_P_biasa, J_P_biasa_2;
    Matrix<double, 9, 3> J_R_biasg, J_R_biasg_2;

    res1 = Imu::ImuError(s, vb_i, pose_i, vb_j, pose_j, g, &J_P_biasa, &J_R_biasg);

    {
        res2 = EvaluateNumeric(
            [=](auto p) {
                Imu::VelocityAndBias vb = vb_i;
                vb.acc_bias             = p;
                return Imu::ImuError(s, vb, pose_i, vb_j, pose_j, g);
            },
            vb_i.acc_bias, &J_P_biasa_2);
    }

    {
        res2 = EvaluateNumeric(
            [=](auto p) {
                Imu::VelocityAndBias vb = vb_i;
                vb.gyro_bias            = p;
                return Imu::ImuError(s, vb, pose_i, vb_j, pose_j, g);
            },
            vb_i.gyro_bias, &J_R_biasg_2);
    }

    //    J_R_biasg_2.block<3, 3>(3, 0).setZero();
    //    J_R_biasg_2.block<3, 3>(6, 0).setZero();

    ExpectCloseRelative(res1, res2, 1e-5);
    //        ExpectCloseRelative(J_P_biasa, J_P_biasa_2, 1e-5);
    ExpectCloseRelative(J_R_biasg, J_R_biasg_2, 1e-5);
}

}  // namespace Saiga
<commit_msg>imu derivatives working<commit_after>/**
 * Copyright (c) 2017 Darius Rückert
 * Licensed under the MIT License.
 * See LICENSE file for more information.
 */

#include "saiga/vision/imu/Solver.h"
#include "saiga/vision/util/Random.h"

#include "gtest/gtest.h"

#include "compare_numbers.h"
#include "numeric_derivative.h"
namespace Saiga
{
// Generates smooth imu measurements
std::vector<Imu::ImuSequence> GenerateRandomSequence(int N, int K, double dt)
{
    std::vector<Imu::ImuSequence> data;
    double t = 0;

    data.push_back(Imu::ImuSequence());
    data.front().time_end = t;

    Vec3 o   = Vec3::Random() * 0.02;
    Vec3 acc = Vec3::Random() * 0.2;

    for (int i = 0; i < N - 1; ++i)
    {
        Imu::ImuSequence seq;
        seq.time_begin = t;

        int this_K = Random::uniformInt(K / 2, K * 10);
        for (int k = 0; k < this_K; ++k)
        {
            Imu::Data id;
            o += Vec3::Random() * 0.01 * dt;
            acc += Vec3::Random() * 0.1 * dt;
            id.omega        = o;
            id.acceleration = acc;  // Vec3::Random() * 0.1;
            id.timestamp    = t;
            seq.data.push_back(id);
            t += dt;
        }
        seq.time_end = t;

        data.push_back(seq);
    }
    Imu::InterpolateMissingValues(data);

    return data;
}

namespace Imu
{
Vec9 ImuError(const ImuSequence& s, const VelocityAndBias& vb_i, const SE3& pose_i, const VelocityAndBias& vb_j,
              const SE3& pose_j, const Vec3& g, Matrix<double, 9, 3>* J_biasa = nullptr,
              Matrix<double, 9, 3>* J_biasg = nullptr, Matrix<double, 9, 3>* J_v1 = nullptr,
              Matrix<double, 9, 3>* J_v2 = nullptr, Matrix<double, 9, 6>* J_p1 = nullptr,
              Matrix<double, 9, 6>* J_p2 = nullptr)
{
    Vec9 residual = Vec9::Zero();

    auto Pi = pose_i.translation();
    auto Pj = pose_j.translation();

    auto Vi = vb_i.velocity;
    auto Vj = vb_j.velocity;

    auto Ri = pose_i.so3();
    auto Rj = pose_j.so3();

    auto RiT = Ri.inverse();
    auto RjT = Rj.inverse();

    SE3 rel_ji = pose_i.inverse() * pose_j;

    Vec3 vel_Vij = pose_i.inverse().so3() * Vj;

    Preintegration preint(vb_i);
    preint.IntegrateMidPoint(s);

    SE3 preint_Pj;
    Vec3 preint_Vj;
    std::tie(preint_Pj, preint_Vj) = preint.Predict(pose_i, Vi, g);

    SE3 preint_ji   = pose_i.inverse() * preint_Pj;
    Vec3 preint_Vji = pose_i.inverse().so3() * preint_Vj;

    //    double dTij = preint.delta_t;
    //    double dT2  = dTij * dTij;

    //    Vec3 dPij = preint.delta_x;
    //    Vec3 dVij = preint.delta_v;

    //    auto prediction = preint.Predict(pose_i, vb_i.velocity, g);

    // residual error of Delta Position measurement
    //    Vec3 rPij = RiT * (-Pj + Pi + Vi * dTij + 0.5 * g * dT2) + dPij;
    //    Vec3 rPij = RiT * (Pi + Vi * dTij + 0.5 * g * dT2 - Pj) + dPij;
    //    Vec3 rPij = RiT * (Pi + Vi * dTij + 0.5 * g * dT2) + dPij - RiT * Pj;
    Vec3 rPij = preint_ji.translation() - rel_ji.translation();  // RiT * Pj;
    // - (dPij + M.getJPBiasg() * dBgi + M.getJPBiasa() * dBai);  // this line includes correction term of bias change.
    // residual error of Delta Velocity measurement
    //    Vec3 rVij = RiT * (Vi + g * dTij) + dVij - RiT * Vj;
    Vec3 rVij = preint_Vji - vel_Vij;

    //= (dRij).inverse() * RiT * Rj;
    Sophus::SO3 rRij = preint_ji.so3().inverse() * rel_ji.so3();
    Vec3 rPhiij      = rRij.log();

    residual.segment<3>(0) = rPij;    // position error
    residual.segment<3>(3) = rVij;    // velocity error
    residual.segment<3>(6) = rPhiij;  // rotation phi error

    if (J_biasg)
    {
        Mat3 JrInv_rPhi;
        Sophus::rightJacobianInvSO3(rPhiij, JrInv_rPhi);

        Mat3 ExprPhiijTrans = Sophus::SO3d::exp(rPhiij).inverse().matrix();

        //        Mat3 JrBiasGCorr = Sophus::rightJacobianSO3(J_rPhi_dbg * dBgi);

        //          Matrix3d J_rPhi_dbg = M.getJRBiasg();

        J_biasg->block<3, 3>(0, 0) = preint.J_P_Biasg;
        J_biasg->block<3, 3>(3, 0) = preint.J_V_Biasg;

        J_biasg->block<3, 3>(6, 0) = -JrInv_rPhi * ExprPhiijTrans /** JrBiasGCorr*/ * preint.J_R_Biasg;
        //        J_R_biasg -
        //        std::cout << preint.J_P_Biasg << std::endl;
        //        std::cout << preint.J_V_Biasg << std::endl;
    }

    if (J_biasa)
    {
        J_biasa->block<3, 3>(0, 0) = preint.J_P_Biasa;
        J_biasa->block<3, 3>(3, 0) = preint.J_V_Biasa;
        J_biasa->block<3, 3>(6, 0).setZero();
    }

    if (J_v1)
    {
        J_v1->block<3, 3>(0, 0) = RiT.matrix() * preint.delta_t;
        J_v1->block<3, 3>(3, 0) = RiT.matrix();
        J_v1->block<3, 3>(6, 0).setZero();
    }

    if (J_v2)
    {
        J_v2->block<3, 3>(0, 0).setZero();
        J_v2->block<3, 3>(3, 0) = -RiT.matrix();
        J_v2->block<3, 3>(6, 0).setZero();
    }

    if (J_p1)
    {
        Mat3 JrInv_rPhi;
        Sophus::rightJacobianInvSO3(rPhiij, JrInv_rPhi);

        J_p1->block<3, 3>(0, 0).setIdentity();
        J_p1->block<3, 3>(3, 0).setZero();
        J_p1->block<3, 3>(6, 0).setZero();

        J_p1->block<3, 3>(0, 3) =
            skew(RiT * (Pi + Vi * preint.delta_t + 0.5 * g * preint.delta_t * preint.delta_t - Pj));
        J_p1->block<3, 3>(3, 3) = skew(RiT * (Vi + g * preint.delta_t - Vj));
        J_p1->block<3, 3>(6, 3) = -JrInv_rPhi * RjT.matrix() * Ri.matrix();
    }

    if (J_p2)
    {
        Mat3 JrInv_rPhi;
        Sophus::rightJacobianInvSO3(rPhiij, JrInv_rPhi);

        J_p2->block<3, 3>(0, 0) = -(RiT * Rj).matrix();
        J_p2->block<3, 3>(3, 0).setZero();
        J_p2->block<3, 3>(6, 0).setZero();

        J_p2->block<3, 3>(0, 3).setZero();
        J_p2->block<3, 3>(3, 3).setZero();
        J_p2->block<3, 3>(6, 3) = JrInv_rPhi;
    }

    return residual;
}
}  // namespace Imu

struct ImuDerivTest
{
    ImuDerivTest()
    {
        // Random::setSeed(95665);
        s              = GenerateRandomSequence(10, 5, 0.1)[1];
        vb_i.velocity  = Vec3::Random();
        vb_i.gyro_bias = Vec3::Random();
        vb_i.acc_bias  = Vec3::Random();
        vb_j           = vb_i;
        g              = Vec3::Random().normalized() * 9.81;
        pose_i         = Random::randomSE3();
        {
            Imu::Preintegration preint(vb_i.gyro_bias, vb_i.acc_bias);
            preint.IntegrateMidPoint(s);
            auto p_v      = preint.Predict(pose_i, vb_i.velocity, g);
            pose_j        = Sophus::se3_expd(Sophus::Vector6d::Random() * 0.2) * p_v.first;
            vb_j.velocity = p_v.second + Vec3::Random() * 0.01;
        }
    }
    Imu::ImuSequence s;
    Vec3 g;
    SE3 pose_i, pose_j;
    Imu::VelocityAndBias vb_i, vb_j;
};

TEST(ImuDerivatives, BiasGyro)
{
    ImuDerivTest data;

    Vec9 res1, res2;
    Matrix<double, 9, 3> J_biasg, J_biasg_numeric;

    res1 = Imu::ImuError(data.s, data.vb_i, data.pose_i, data.vb_j, data.pose_j, data.g, nullptr, &J_biasg);
    {
        res2 = EvaluateNumeric(
            [=](auto p) {
                Imu::VelocityAndBias vb = data.vb_i;
                vb.gyro_bias            = p;
                return Imu::ImuError(data.s, vb, data.pose_i, data.vb_j, data.pose_j, data.g);
            },
            data.vb_i.gyro_bias, &J_biasg_numeric);
    }

    ExpectCloseRelative(res1, res2, 1e-5);
    ExpectCloseRelative(J_biasg, J_biasg_numeric, 1e-5);
}

TEST(ImuDerivatives, BiasAcc)
{
    ImuDerivTest data;

    Vec9 res1, res2;
    Matrix<double, 9, 3> J_biasa, J_biasa_numeric;

    res1 = Imu::ImuError(data.s, data.vb_i, data.pose_i, data.vb_j, data.pose_j, data.g, &J_biasa);

    {
        res2 = EvaluateNumeric(
            [=](auto p) {
                Imu::VelocityAndBias vb = data.vb_i;
                vb.acc_bias             = p;
                return Imu::ImuError(data.s, vb, data.pose_i, data.vb_j, data.pose_j, data.g);
            },
            data.vb_i.acc_bias, &J_biasa_numeric);
    }

    ExpectCloseRelative(res1, res2, 1e-5);
    ExpectCloseRelative(J_biasa, J_biasa_numeric, 1e-5);
}

TEST(ImuDerivatives, Velocity)
{
    ImuDerivTest data;

    Vec9 res1, res2;
    Matrix<double, 9, 3> J_v1, J_v2;
    Matrix<double, 9, 3> J_v1_numeric, J_v2_numeric;

    res1 =
        Imu::ImuError(data.s, data.vb_i, data.pose_i, data.vb_j, data.pose_j, data.g, nullptr, nullptr, &J_v1, &J_v2);

    {
        res2 = EvaluateNumeric(
            [=](auto p) {
                Imu::VelocityAndBias vb = data.vb_i;
                vb.velocity             = p;
                return Imu::ImuError(data.s, vb, data.pose_i, data.vb_j, data.pose_j, data.g);
            },
            data.vb_i.velocity, &J_v1_numeric);
    }

    ExpectCloseRelative(res1, res2, 1e-5);
    ExpectCloseRelative(J_v1, J_v1_numeric, 1e-5);
    {
        res2 = EvaluateNumeric(
            [=](auto p) {
                Imu::VelocityAndBias vb = data.vb_j;
                vb.velocity             = p;
                return Imu::ImuError(data.s, data.vb_i, data.pose_i, vb, data.pose_j, data.g);
            },
            data.vb_j.velocity, &J_v2_numeric);
    }

    ExpectCloseRelative(res1, res2, 1e-5);
    ExpectCloseRelative(J_v2, J_v2_numeric, 1e-5);
}

TEST(ImuDerivatives, Pose)
{
    ImuDerivTest data;

    Vec9 res1, res2;
    Matrix<double, 9, 6> J_p1, J_p2;
    Matrix<double, 9, 6> J_p1_numeric, J_p2_numeric;

    res1 = Imu::ImuError(data.s, data.vb_i, data.pose_i, data.vb_j, data.pose_j, data.g, nullptr, nullptr, nullptr,
                         nullptr, &J_p1, &J_p2);

    {
        Vec6 eps = Vec6::Zero();
        res2     = EvaluateNumeric(
            [=](auto p) {
                auto pose_w_i_new = data.pose_i * Sophus::se3_expd(p);
                //                auto pose_w_i_new = data.pose_i * Sophus::SE3d::exp(p);

                return Imu::ImuError(data.s, data.vb_i, pose_w_i_new, data.vb_j, data.pose_j, data.g);
            },
            eps, &J_p1_numeric);
    }

    ExpectCloseRelative(res1, res2, 1e-5);
    ExpectCloseRelative(J_p1, J_p1_numeric, 1e-5);

    {
        Vec6 eps = Vec6::Zero();
        res2     = EvaluateNumeric(
            [=](auto p) {
                auto pose_w_j_new = data.pose_j * Sophus::se3_expd(p);
                //                auto pose_w_i_new = data.pose_i * Sophus::SE3d::exp(p);

                return Imu::ImuError(data.s, data.vb_i, data.pose_i, data.vb_j, pose_w_j_new, data.g);
            },
            eps, &J_p2_numeric);
    }

    ExpectCloseRelative(res1, res2, 1e-5);
    ExpectCloseRelative(J_p2, J_p2_numeric, 1e-5);
}

}  // namespace Saiga
<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2013 Heiko Strathmann
 */

#include <shogun/base/Parameter.h>
#include <shogun/labels/BinaryLabels.h>
#include <shogun/labels/RegressionLabels.h>
#include <gtest/gtest.h>

using namespace shogun;

TEST(TParameter,equals_null)
{
	TSGDataType type(CT_SCALAR, ST_NONE, PT_BOOL);
	TParameter* param=new TParameter(&type, NULL, "", "");

	EXPECT_FALSE(param->equals(NULL));

	delete param;
}

TEST(TParameter,equals_different_name)
{
	TSGDataType type(CT_SCALAR, ST_NONE, PT_BOOL);
	TParameter* param=new TParameter(&type, NULL, "a", "");
	TParameter* param2=new TParameter(&type, NULL, "b", "");

	EXPECT_FALSE(param->equals(param2));

	delete param;
	delete param2;
}

TEST(TSGDataType,equals_different_PT)
{
	TSGDataType type1(CT_SCALAR, ST_NONE, PT_BOOL);
	TSGDataType type2(CT_SCALAR, ST_NONE, PT_FLOAT64);

	EXPECT_FALSE(type1.equals(type2));
}

TEST(TSGDataType,equals_different_ST)
{
	TSGDataType type1(CT_SCALAR, ST_NONE, PT_BOOL);
	TSGDataType type2(CT_SCALAR, ST_STRING, PT_BOOL);

	EXPECT_FALSE(type1.equals(type2));
}

TEST(TSGDataType,equals_different_CT)
{
	TSGDataType type1(CT_SCALAR, ST_NONE, PT_BOOL);
	TSGDataType type2(CT_SGVECTOR, ST_NONE, PT_BOOL);

	EXPECT_FALSE(type1.equals(type2));
}

TEST(TSGDataType,equals_different_leny_value)
{
	index_t len_a=1;
	index_t len_b=2;

	TSGDataType type1(CT_SCALAR, ST_NONE, PT_BOOL, &len_a);
	TSGDataType type2(CT_SCALAR, ST_NONE, PT_BOOL, &len_b);

	EXPECT_FALSE(type1.equals(type2));
}

TEST(TSGDataType,equals_different_len_y_null1)
{
	index_t len_a=1;

	TSGDataType type1(CT_SCALAR, ST_NONE, PT_BOOL, NULL);
	TSGDataType type2(CT_SCALAR, ST_NONE, PT_BOOL, &len_a);

	EXPECT_FALSE(type1.equals(type2));
}

TEST(TSGDataType,equals_different_len_y_null2)
{
	index_t len_a=1;

	TSGDataType type1(CT_SCALAR, ST_NONE, PT_BOOL, &len_a);
	TSGDataType type2(CT_SCALAR, ST_NONE, PT_BOOL, NULL);

	EXPECT_FALSE(type1.equals(type2));
}

TEST(TSGDataType,equals_different_len_xy_values)
{
	index_t len_y_a=1;
	index_t len_x_a=2;

	index_t len_y_b=1;
	index_t len_x_b=4;

	TSGDataType type1(CT_SCALAR, ST_NONE, PT_BOOL, &len_y_a, &len_x_a);
	TSGDataType type2(CT_SCALAR, ST_NONE, PT_BOOL, &len_y_b, &len_x_b);

	EXPECT_FALSE(type1.equals(type2));
}

TEST(TParameter,compare_ptype_null1)
{
	int a=1;
	EXPECT_FALSE(TParameter::compare_ptype(PT_FLOAT64, NULL, &a));
}

TEST(TParameter,compare_ptype_null2)
{
	int a=1;
	EXPECT_FALSE(TParameter::compare_ptype(PT_FLOAT64, &a, NULL));
}

TEST(TParameter,compare_ptype_BOOL)
{
	bool a=true;
	bool b=false;
	EXPECT_FALSE(TParameter::compare_ptype(PT_BOOL, &a, &b));
}

TEST(TParameter,compare_ptype_CHAR)
{
	char a='a';
	char b='b';
	EXPECT_FALSE(TParameter::compare_ptype(PT_CHAR, &a, &b));
}

TEST(TParameter,compare_ptype_INT8)
{
	int8_t a=1;
	int8_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_INT8, &a, &b));
}

TEST(TParameter,compare_ptype_UINT8)
{
	uint8_t a=1;
	uint8_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_UINT8, &a, &b));
}

TEST(TParameter,compare_ptype_INT16)
{
	int16_t a=1;
	int16_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_INT16, &a, &b));
}

TEST(TParameter,compare_ptype_UINT16)
{
	uint16_t a=1;
	uint16_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_UINT16, &a, &b));
}

TEST(TParameter,compare_ptype_INT32)
{
	int32_t a=1;
	int32_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_INT32, &a, &b));
}

TEST(TParameter,compare_ptype_UINT32)
{
	uint32_t a=1;
	uint32_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_UINT32, &a, &b));
}

TEST(TParameter,compare_ptype_INT64)
{
	int64_t a=1;
	int64_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_INT64, &a, &b));
}

TEST(TParameter,compare_ptype_UINT64)
{
	uint64_t a=1;
	uint64_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_UINT64, &a, &b));
}

TEST(TParameter,compare_ptype_FLOAT32)
{
	float32_t a=1;
	float32_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_FLOAT32, &a, &b));
}

TEST(TParameter,compare_ptype_FLOAT64)
{
	float64_t a=1;
	float64_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_FLOAT64, &a, &b));
}

TEST(TParameter,compare_ptype_FLOATMAX)
{
	floatmax_t a=1;
	floatmax_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_FLOATMAX, &a, &b));
}

TEST(TParameter,compare_ptype_SGOBJECT)
{
	CBinaryLabels* a=new CBinaryLabels(10);
	CRegressionLabels* b=new CRegressionLabels(10);

	EXPECT_FALSE(TParameter::compare_ptype(PT_SGOBJECT, &a, &b));

	SG_UNREF(a);
	SG_UNREF(b);
}

TEST(TParameter,equals_scalar_different1)
{
	int32_t a=1;
	int32_t b=2;

	TSGDataType type(CT_SCALAR, ST_NONE, PT_INT32);
	TParameter* param1=new TParameter(&type, &a, "", "");
	TParameter* param2=new TParameter(&type, &b, "", "");

	EXPECT_FALSE(param1->equals(param2));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_scalar_different2)
{
	float64_t a=1.0;
	float64_t b=1.5;
	float64_t accuracy=0.2;

	TSGDataType type(CT_SCALAR, ST_NONE, PT_FLOAT64);
	TParameter* param1=new TParameter(&type, &a, "", "");
	TParameter* param2=new TParameter(&type, &b, "", "");

	EXPECT_FALSE(param1->equals(param2, accuracy));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_scalar_equal1)
{
	int32_t a=1;
	int32_t b=1;

	TSGDataType type(CT_SCALAR, ST_NONE, PT_INT32);
	TParameter* param1=new TParameter(&type, &a, "", "");
	TParameter* param2=new TParameter(&type, &b, "", "");

	EXPECT_TRUE(param1->equals(param2));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_scalar_equal2)
{
	float64_t a=1.0;
	float64_t b=1.2;
	float64_t accuracy=0.2;

	TSGDataType type(CT_SCALAR, ST_NONE, PT_FLOAT64);
	TParameter* param1=new TParameter(&type, &a, "", "");
	TParameter* param2=new TParameter(&type, &b, "", "");

	EXPECT_TRUE(param1->equals(param2, accuracy));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_vector_different)
{
	SGVector<float64_t> a(2);
	SGVector<float64_t> b(2);
	float64_t accuracy=0.1;

	a[0]=1;
	b[0]=1;
	a[1]=1;
	b[1]=1.11;

	TSGDataType type(CT_SGVECTOR, ST_NONE, PT_FLOAT64, &a.vlen);
	TParameter* param1=new TParameter(&type, &a.vector, "", "");
	TParameter* param2=new TParameter(&type, &b.vector, "", "");

	EXPECT_FALSE(param1->equals(param2, accuracy));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_vector_equal)
{
	SGVector<float64_t> a(2);
	SGVector<float64_t> b(2);
	float64_t accuracy=0.1;

	a[0]=1;
	b[0]=1;
	a[1]=1;
	b[1]=1.01;

	TSGDataType type(CT_SGVECTOR, ST_NONE, PT_FLOAT64, &a.vlen);
	TParameter* param1=new TParameter(&type, &a.vector, "", "");
	TParameter* param2=new TParameter(&type, &b.vector, "", "");

	EXPECT_TRUE(param1->equals(param2, accuracy));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_matrix_different)
{
	SGMatrix<float64_t> a(2,2);
	SGMatrix<float64_t> b(2,2);
	float64_t accuracy=0.1;

	a.set_const(1);
	b.set_const(1);
	b(1,1)=1.11;

	TSGDataType type(CT_SGMATRIX, ST_NONE, PT_FLOAT64, &a.num_rows, &a.num_cols);
	TParameter* param1=new TParameter(&type, &a.matrix, "", "");
	TParameter* param2=new TParameter(&type, &b.matrix, "", "");

	EXPECT_FALSE(param1->equals(param2, accuracy));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_matrix_equal)
{
	SGMatrix<float64_t> a(2,2);
	SGMatrix<float64_t> b(2,2);
	float64_t accuracy=0.1;

	a.set_const(1);
	b.set_const(1);
	b(1,1)=1.01;

	TSGDataType type(CT_SGMATRIX, ST_NONE, PT_FLOAT64, &a.num_rows, &a.num_cols);
	TParameter* param1=new TParameter(&type, &a.matrix, "", "");
	TParameter* param2=new TParameter(&type, &b.matrix, "", "");

	EXPECT_TRUE(param1->equals(param2, accuracy));

	delete param1;
	delete param2;
}
<commit_msg>new unit test for equal and string based types<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2013 Heiko Strathmann
 */

#include <shogun/base/Parameter.h>
#include <shogun/labels/BinaryLabels.h>
#include <shogun/labels/RegressionLabels.h>
#include <gtest/gtest.h>

using namespace shogun;

TEST(TParameter,equals_null)
{
	TSGDataType type(CT_SCALAR, ST_NONE, PT_BOOL);
	TParameter* param=new TParameter(&type, NULL, "", "");

	EXPECT_FALSE(param->equals(NULL));

	delete param;
}

TEST(TParameter,equals_different_name)
{
	TSGDataType type(CT_SCALAR, ST_NONE, PT_BOOL);
	TParameter* param=new TParameter(&type, NULL, "a", "");
	TParameter* param2=new TParameter(&type, NULL, "b", "");

	EXPECT_FALSE(param->equals(param2));

	delete param;
	delete param2;
}

TEST(TSGDataType,equals_different_PT)
{
	TSGDataType type1(CT_SCALAR, ST_NONE, PT_BOOL);
	TSGDataType type2(CT_SCALAR, ST_NONE, PT_FLOAT64);

	EXPECT_FALSE(type1.equals(type2));
}

TEST(TSGDataType,equals_different_ST)
{
	TSGDataType type1(CT_SCALAR, ST_NONE, PT_BOOL);
	TSGDataType type2(CT_SCALAR, ST_STRING, PT_BOOL);

	EXPECT_FALSE(type1.equals(type2));
}

TEST(TSGDataType,equals_different_CT)
{
	TSGDataType type1(CT_SCALAR, ST_NONE, PT_BOOL);
	TSGDataType type2(CT_SGVECTOR, ST_NONE, PT_BOOL);

	EXPECT_FALSE(type1.equals(type2));
}

TEST(TSGDataType,equals_different_leny_value)
{
	index_t len_a=1;
	index_t len_b=2;

	TSGDataType type1(CT_SCALAR, ST_NONE, PT_BOOL, &len_a);
	TSGDataType type2(CT_SCALAR, ST_NONE, PT_BOOL, &len_b);

	EXPECT_FALSE(type1.equals(type2));
}

TEST(TSGDataType,equals_different_len_y_null1)
{
	index_t len_a=1;

	TSGDataType type1(CT_SCALAR, ST_NONE, PT_BOOL, NULL);
	TSGDataType type2(CT_SCALAR, ST_NONE, PT_BOOL, &len_a);

	EXPECT_FALSE(type1.equals(type2));
}

TEST(TSGDataType,equals_different_len_y_null2)
{
	index_t len_a=1;

	TSGDataType type1(CT_SCALAR, ST_NONE, PT_BOOL, &len_a);
	TSGDataType type2(CT_SCALAR, ST_NONE, PT_BOOL, NULL);

	EXPECT_FALSE(type1.equals(type2));
}

TEST(TSGDataType,equals_different_len_xy_values)
{
	index_t len_y_a=1;
	index_t len_x_a=2;

	index_t len_y_b=1;
	index_t len_x_b=4;

	TSGDataType type1(CT_SCALAR, ST_NONE, PT_BOOL, &len_y_a, &len_x_a);
	TSGDataType type2(CT_SCALAR, ST_NONE, PT_BOOL, &len_y_b, &len_x_b);

	EXPECT_FALSE(type1.equals(type2));
}

TEST(TParameter,compare_ptype_null1)
{
	int a=1;
	EXPECT_FALSE(TParameter::compare_ptype(PT_FLOAT64, NULL, &a));
}

TEST(TParameter,compare_ptype_null2)
{
	int a=1;
	EXPECT_FALSE(TParameter::compare_ptype(PT_FLOAT64, &a, NULL));
}

TEST(TParameter,compare_ptype_BOOL)
{
	bool a=true;
	bool b=false;
	EXPECT_FALSE(TParameter::compare_ptype(PT_BOOL, &a, &b));
}

TEST(TParameter,compare_ptype_CHAR)
{
	char a='a';
	char b='b';
	EXPECT_FALSE(TParameter::compare_ptype(PT_CHAR, &a, &b));
}

TEST(TParameter,compare_ptype_INT8)
{
	int8_t a=1;
	int8_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_INT8, &a, &b));
}

TEST(TParameter,compare_ptype_UINT8)
{
	uint8_t a=1;
	uint8_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_UINT8, &a, &b));
}

TEST(TParameter,compare_ptype_INT16)
{
	int16_t a=1;
	int16_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_INT16, &a, &b));
}

TEST(TParameter,compare_ptype_UINT16)
{
	uint16_t a=1;
	uint16_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_UINT16, &a, &b));
}

TEST(TParameter,compare_ptype_INT32)
{
	int32_t a=1;
	int32_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_INT32, &a, &b));
}

TEST(TParameter,compare_ptype_UINT32)
{
	uint32_t a=1;
	uint32_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_UINT32, &a, &b));
}

TEST(TParameter,compare_ptype_INT64)
{
	int64_t a=1;
	int64_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_INT64, &a, &b));
}

TEST(TParameter,compare_ptype_UINT64)
{
	uint64_t a=1;
	uint64_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_UINT64, &a, &b));
}

TEST(TParameter,compare_ptype_FLOAT32)
{
	float32_t a=1;
	float32_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_FLOAT32, &a, &b));
}

TEST(TParameter,compare_ptype_FLOAT64)
{
	float64_t a=1;
	float64_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_FLOAT64, &a, &b));
}

TEST(TParameter,compare_ptype_FLOATMAX)
{
	floatmax_t a=1;
	floatmax_t b=2;
	EXPECT_FALSE(TParameter::compare_ptype(PT_FLOATMAX, &a, &b));
}

TEST(TParameter,compare_ptype_SGOBJECT)
{
	CBinaryLabels* a=new CBinaryLabels(10);
	CRegressionLabels* b=new CRegressionLabels(10);

	EXPECT_FALSE(TParameter::compare_ptype(PT_SGOBJECT, &a, &b));

	SG_UNREF(a);
	SG_UNREF(b);
}

TEST(TParameter,equals_scalar_different1)
{
	int32_t a=1;
	int32_t b=2;

	TSGDataType type(CT_SCALAR, ST_NONE, PT_INT32);
	TParameter* param1=new TParameter(&type, &a, "", "");
	TParameter* param2=new TParameter(&type, &b, "", "");

	EXPECT_FALSE(param1->equals(param2));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_scalar_different2)
{
	float64_t a=1.0;
	float64_t b=1.5;
	float64_t accuracy=0.2;

	TSGDataType type(CT_SCALAR, ST_NONE, PT_FLOAT64);
	TParameter* param1=new TParameter(&type, &a, "", "");
	TParameter* param2=new TParameter(&type, &b, "", "");

	EXPECT_FALSE(param1->equals(param2, accuracy));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_scalar_equal1)
{
	int32_t a=1;
	int32_t b=1;

	TSGDataType type(CT_SCALAR, ST_NONE, PT_INT32);
	TParameter* param1=new TParameter(&type, &a, "", "");
	TParameter* param2=new TParameter(&type, &b, "", "");

	EXPECT_TRUE(param1->equals(param2));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_scalar_equal2)
{
	float64_t a=1.0;
	float64_t b=1.2;
	float64_t accuracy=0.2;

	TSGDataType type(CT_SCALAR, ST_NONE, PT_FLOAT64);
	TParameter* param1=new TParameter(&type, &a, "", "");
	TParameter* param2=new TParameter(&type, &b, "", "");

	EXPECT_TRUE(param1->equals(param2, accuracy));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_vector_different)
{
	SGVector<float64_t> a(2);
	SGVector<float64_t> b(2);
	float64_t accuracy=0.1;

	a[0]=1;
	b[0]=1;
	a[1]=1;
	b[1]=1.11;

	TSGDataType type(CT_SGVECTOR, ST_NONE, PT_FLOAT64, &a.vlen);
	TParameter* param1=new TParameter(&type, &a.vector, "", "");
	TParameter* param2=new TParameter(&type, &b.vector, "", "");

	EXPECT_FALSE(param1->equals(param2, accuracy));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_vector_equal)
{
	SGVector<float64_t> a(2);
	SGVector<float64_t> b(2);
	float64_t accuracy=0.1;

	a[0]=1;
	b[0]=1;
	a[1]=1;
	b[1]=1.01;

	TSGDataType type(CT_SGVECTOR, ST_NONE, PT_FLOAT64, &a.vlen);
	TParameter* param1=new TParameter(&type, &a.vector, "", "");
	TParameter* param2=new TParameter(&type, &b.vector, "", "");

	EXPECT_TRUE(param1->equals(param2, accuracy));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_matrix_different)
{
	SGMatrix<float64_t> a(2,2);
	SGMatrix<float64_t> b(2,2);
	float64_t accuracy=0.1;

	a.set_const(1);
	b.set_const(1);
	b(1,1)=1.11;

	TSGDataType type(CT_SGMATRIX, ST_NONE, PT_FLOAT64, &a.num_rows, &a.num_cols);
	TParameter* param1=new TParameter(&type, &a.matrix, "", "");
	TParameter* param2=new TParameter(&type, &b.matrix, "", "");

	EXPECT_FALSE(param1->equals(param2, accuracy));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_matrix_equal)
{
	SGMatrix<float64_t> a(2,2);
	SGMatrix<float64_t> b(2,2);
	float64_t accuracy=0.1;

	a.set_const(1);
	b.set_const(1);
	b(1,1)=1.01;

	TSGDataType type(CT_SGMATRIX, ST_NONE, PT_FLOAT64, &a.num_rows, &a.num_cols);
	TParameter* param1=new TParameter(&type, &a.matrix, "", "");
	TParameter* param2=new TParameter(&type, &b.matrix, "", "");

	EXPECT_TRUE(param1->equals(param2, accuracy));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_string_scalar_different)
{
	SGVector<float64_t> a(2);
	SGVector<float64_t> b(2);
	float64_t accuracy=0.1;

	a.set_const(1);
	b.set_const(1);
	b[1]=1.11;

	SGString<float64_t> str1(a);
	SGString<float64_t> str2(b);

	TSGDataType type(CT_SCALAR, ST_STRING, PT_FLOAT64);
	TParameter* param1=new TParameter(&type, &str1.string, "", "");
	TParameter* param2=new TParameter(&type, &str2.string, "", "");

	EXPECT_FALSE(param1->equals(param2, accuracy));

	delete param1;
	delete param2;
}

TEST(TParameter,equals_string_scalar_equal)
{
	SGVector<float64_t> a(2);
	SGVector<float64_t> b(2);
	float64_t accuracy=0.1;

	a.set_const(1);
	b.set_const(1);
	b[1]=1.01;

	SGString<float64_t> str1(a);
	SGString<float64_t> str2(b);

	TSGDataType type(CT_SCALAR, ST_STRING, PT_FLOAT64);
	TParameter* param1=new TParameter(&type, &str1.string, "", "");
	TParameter* param2=new TParameter(&type, &str2.string, "", "");

	EXPECT_TRUE(param1->equals(param2, accuracy));

	delete param1;
	delete param2;
}
<|endoftext|>