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

#include "parser.h"

#include <ThreadWeaver/ThreadWeaver>
#include <KFormat>
#include <KLocalizedString>

#include <QTextStream>

#include "../accumulatedtracedata.h"

#include <vector>

using namespace std;

namespace {
struct ParserData final : public AccumulatedTraceData
{
    ParserData()
    {
    }

    void handleTimeStamp(size_t /*newStamp*/, size_t oldStamp)
    {
        chartData.push_back({oldStamp, timestampData.leaked, totalAllocations, totalAllocated});
        timestampData = {};
    }

    void handleAllocation()
    {
        timestampData.leaked = max(timestampData.leaked, leaked);
    }

    void handleDebuggee(const char* command)
    {
        debuggee = command;
    }

    string debuggee;

    ChartData chartData;
    struct TimestampData {
        size_t leaked = 0;
    };
    TimestampData timestampData;
};

QString generateSummary(const ParserData& data)
{
    QString ret;
    KFormat format;
    QTextStream stream(&ret);
    const double totalTimeS = 0.001 * data.totalTime;
    stream << "<qt>"
           << i18n("debuggee: %1", QString::fromStdString(data.debuggee)) << "
"
           << i18n("total runtime: %1s", totalTimeS) << "
"
           << i18n("bytes allocated in total (ignoring deallocations): %1 (%2/s)",
                   format.formatByteSize(data.totalAllocated, 2), format.formatByteSize(data.totalAllocated / totalTimeS)) << "
"
           << i18n("calls to allocation functions: %1 (%2/s)",
                   data.totalAllocations, quint64(data.totalAllocations / totalTimeS)) << "
"
           << i18n("peak heap memory consumption: %1", format.formatByteSize(data.peak)) << "
"
           << i18n("total memory leaked: %1", format.formatByteSize(data.leaked)) << "
";
    stream << "</qt>";
    return ret;
}

struct StringCache
{
    StringCache(const AccumulatedTraceData& data)
    {
        m_strings.resize(data.strings.size());
        transform(data.strings.begin(), data.strings.end(),
                  m_strings.begin(), [] (const string& str) { return QString::fromStdString(str); });
    }

    QString func(const InstructionPointer& ip) const
    {
        if (ip.functionIndex) {
            // TODO: support removal of template arguments
            return stringify(ip.functionIndex);
        } else {
            return static_cast<QString>(QLatin1String("0x") + QString::number(ip.instructionPointer, 16));
        }
    }

    QString file(const InstructionPointer& ip) const
    {
        if (ip.fileIndex) {
            auto file = stringify(ip.fileIndex);
            return file + QLatin1Char(':') + QString::number(ip.line);
        } else {
            return {};
        }
    }

    QString module(const InstructionPointer& ip) const
    {
        return stringify(ip.moduleIndex);
    }

    QString stringify(const StringIndex index) const
    {
        if (!index || index.index > m_strings.size()) {
            return {};
        } else {
            return m_strings.at(index.index - 1);
        }
    }

    LocationData location(const InstructionPointer& ip) const
    {
        return {func(ip), file(ip), module(ip)};
    }

    vector<QString> m_strings;
};

void setParents(QVector<RowData>& children, const RowData* parent)
{
    for (auto& row: children) {
        row.parent = parent;
        setParents(row.children, &row);
    }
}

QVector<RowData> mergeAllocations(const AccumulatedTraceData& data)
{
    QVector<RowData> topRows;
    StringCache strings(data);
    // merge allocations, leave parent pointers invalid (their location may change)
    for (const auto& allocation : data.allocations) {
        auto traceIndex = allocation.traceIndex;
        auto rows = &topRows;
        while (traceIndex) {
            const auto& trace = data.findTrace(traceIndex);
            const auto& ip = data.findIp(trace.ipIndex);
            // TODO: only store the IpIndex and use that
            auto location = strings.location(ip);
            auto it = lower_bound(rows->begin(), rows->end(), location);
            if (it != rows->end() && it->location == location) {
                it->allocated += allocation.allocated;
                it->allocations += allocation.allocations;
                it->leaked += allocation.leaked;
                it->peak = max(it->peak, static_cast<quint64>(allocation.peak));
            } else {
                it = rows->insert(it, {allocation.allocations, allocation.allocated, allocation.leaked, allocation.peak,
                                        location, nullptr, {}});
            }
            traceIndex = trace.parentIndex;
            rows = &it->children;
        }
    }
    // now set the parents, the data is constant from here on
    setParents(topRows, nullptr);
    return topRows;
}
}

Parser::Parser(QObject* parent)
    : QObject(parent)
{}

Parser::~Parser() = default;

void Parser::parse(const QString& path)
{
    using namespace ThreadWeaver;
    stream() << make_job([=]() {
        ParserData data;
        data.read(path.toStdString());
        emit summaryAvailable(generateSummary(data));
        emit bottomUpDataAvailable(mergeAllocations(data));
        emit chartDataAvailable(data.chartData);
        emit finished();
    });
}
<commit_msg>Include 0 as first chart datapoint.<commit_after>/*
 * Copyright 2015 Milian Wolff <mail@milianw.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Library General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "parser.h"

#include <ThreadWeaver/ThreadWeaver>
#include <KFormat>
#include <KLocalizedString>

#include <QTextStream>

#include "../accumulatedtracedata.h"

#include <vector>

using namespace std;

namespace {
struct ParserData final : public AccumulatedTraceData
{
    ParserData()
    {
        chartData.push_back({0, 0, 0, 0});
    }

    void handleTimeStamp(size_t /*newStamp*/, size_t oldStamp)
    {
        chartData.push_back({oldStamp, timestampData.leaked, totalAllocations, totalAllocated});
        timestampData = {};
    }

    void handleAllocation()
    {
        timestampData.leaked = max(timestampData.leaked, leaked);
    }

    void handleDebuggee(const char* command)
    {
        debuggee = command;
    }

    string debuggee;

    ChartData chartData;
    struct TimestampData {
        size_t leaked = 0;
    };
    TimestampData timestampData;
};

QString generateSummary(const ParserData& data)
{
    QString ret;
    KFormat format;
    QTextStream stream(&ret);
    const double totalTimeS = 0.001 * data.totalTime;
    stream << "<qt>"
           << i18n("debuggee: %1", QString::fromStdString(data.debuggee)) << "
"
           << i18n("total runtime: %1s", totalTimeS) << "
"
           << i18n("bytes allocated in total (ignoring deallocations): %1 (%2/s)",
                   format.formatByteSize(data.totalAllocated, 2), format.formatByteSize(data.totalAllocated / totalTimeS)) << "
"
           << i18n("calls to allocation functions: %1 (%2/s)",
                   data.totalAllocations, quint64(data.totalAllocations / totalTimeS)) << "
"
           << i18n("peak heap memory consumption: %1", format.formatByteSize(data.peak)) << "
"
           << i18n("total memory leaked: %1", format.formatByteSize(data.leaked)) << "
";
    stream << "</qt>";
    return ret;
}

struct StringCache
{
    StringCache(const AccumulatedTraceData& data)
    {
        m_strings.resize(data.strings.size());
        transform(data.strings.begin(), data.strings.end(),
                  m_strings.begin(), [] (const string& str) { return QString::fromStdString(str); });
    }

    QString func(const InstructionPointer& ip) const
    {
        if (ip.functionIndex) {
            // TODO: support removal of template arguments
            return stringify(ip.functionIndex);
        } else {
            return static_cast<QString>(QLatin1String("0x") + QString::number(ip.instructionPointer, 16));
        }
    }

    QString file(const InstructionPointer& ip) const
    {
        if (ip.fileIndex) {
            auto file = stringify(ip.fileIndex);
            return file + QLatin1Char(':') + QString::number(ip.line);
        } else {
            return {};
        }
    }

    QString module(const InstructionPointer& ip) const
    {
        return stringify(ip.moduleIndex);
    }

    QString stringify(const StringIndex index) const
    {
        if (!index || index.index > m_strings.size()) {
            return {};
        } else {
            return m_strings.at(index.index - 1);
        }
    }

    LocationData location(const InstructionPointer& ip) const
    {
        return {func(ip), file(ip), module(ip)};
    }

    vector<QString> m_strings;
};

void setParents(QVector<RowData>& children, const RowData* parent)
{
    for (auto& row: children) {
        row.parent = parent;
        setParents(row.children, &row);
    }
}

QVector<RowData> mergeAllocations(const AccumulatedTraceData& data)
{
    QVector<RowData> topRows;
    StringCache strings(data);
    // merge allocations, leave parent pointers invalid (their location may change)
    for (const auto& allocation : data.allocations) {
        auto traceIndex = allocation.traceIndex;
        auto rows = &topRows;
        while (traceIndex) {
            const auto& trace = data.findTrace(traceIndex);
            const auto& ip = data.findIp(trace.ipIndex);
            // TODO: only store the IpIndex and use that
            auto location = strings.location(ip);
            auto it = lower_bound(rows->begin(), rows->end(), location);
            if (it != rows->end() && it->location == location) {
                it->allocated += allocation.allocated;
                it->allocations += allocation.allocations;
                it->leaked += allocation.leaked;
                it->peak = max(it->peak, static_cast<quint64>(allocation.peak));
            } else {
                it = rows->insert(it, {allocation.allocations, allocation.allocated, allocation.leaked, allocation.peak,
                                        location, nullptr, {}});
            }
            traceIndex = trace.parentIndex;
            rows = &it->children;
        }
    }
    // now set the parents, the data is constant from here on
    setParents(topRows, nullptr);
    return topRows;
}
}

Parser::Parser(QObject* parent)
    : QObject(parent)
{}

Parser::~Parser() = default;

void Parser::parse(const QString& path)
{
    using namespace ThreadWeaver;
    stream() << make_job([=]() {
        ParserData data;
        data.read(path.toStdString());
        emit summaryAvailable(generateSummary(data));
        emit bottomUpDataAvailable(mergeAllocations(data));
        emit chartDataAvailable(data.chartData);
        emit finished();
    });
}
<|endoftext|>


<commit_before>#include "RankFourTensor.h"

// Any other includes here
#include <vector>
#include "tensor_value.h"
#include "MaterialProperty.h"
#include "libmesh.h"
#include <ostream>

RankFourTensor::RankFourTensor()
{
  for (unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          _vals[i][j][k][l] = 0.0;
}

RankFourTensor::RankFourTensor(const RankFourTensor &a)
{
  *this = a;
}

Real &
RankFourTensor::operator()(unsigned int i, unsigned int j, unsigned int k, unsigned int l)
{
  return _vals[i][j][k][l];
}

Real
RankFourTensor::operator()(unsigned int i, unsigned int j, unsigned int k, unsigned int l) const
{
  return _vals[i][j][k][l];
}

void
RankFourTensor::setValue(Real val, unsigned int i, unsigned int j, unsigned int k, unsigned int l)
{
  _vals[i-1][j-1][k-1][l-1] = val; //Note, indcies go from 1 to 3
}

Real
RankFourTensor::getValue(unsigned int i, unsigned int j, unsigned int k, unsigned int l) const
{
  return _vals[i-1][j-1][k-1][l-1];//Note, indcies go from 1 to 3
}

void
RankFourTensor::zero()
{
  for (unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          _vals[i][j][k][l] = 0.0;
}

RankFourTensor &
RankFourTensor::operator= (const RankFourTensor &a)
{
  for (unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          _vals[i][j][k][l] = a._vals[i][j][k][l];

  return *this;
}

RealTensorValue
RankFourTensor::operator*(const RankTwoTensor &a)
{
  RealTensorValue result;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          result(i,j) += _vals[i][j][k][l]*a(k,l);

  return result;
}

RealTensorValue
RankFourTensor::operator*(const RealTensorValue &a)
{
  RealTensorValue result;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          result(i,j) += _vals[i][j][k][l]*a(k,l);

  return result;
}

RankFourTensor
RankFourTensor::operator*(const Real &a)
{
  RankFourTensor result;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          result(i,j,k,l) = _vals[i][j][k][l]*a;

return result;
}

RankFourTensor &
RankFourTensor::operator*=(const Real &a)
{
  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          _vals[i][j][k][l] = _vals[i][j][k][l]*a;

  return *this;
}
RankFourTensor
RankFourTensor::operator/(const Real &a)
{
  RankFourTensor result;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          result(i,j,k,l) = _vals[i][j][k][l]/a;

return result;
}

RankFourTensor &
RankFourTensor::operator/=(const Real &a)
{
  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          _vals[i][j][k][l] = _vals[i][j][k][l]/a;

  return *this;
}

RankFourTensor &
RankFourTensor::operator+=(const RankFourTensor &a)
{
  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          _vals[i][j][k][l] = _vals[i][j][k][l] + a(i,j,k,l);

  return *this;
}

RankFourTensor
RankFourTensor::operator+(const RankFourTensor &a) const
{
  RankFourTensor result;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          result(i,j,k,l) = _vals[i][j][k][l] + a(i,j,k,l);

  return result;
}

RankFourTensor &
RankFourTensor::operator-=(const RankFourTensor &a)
{
  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          _vals[i][j][k][l] = _vals[i][j][k][l] - a(i,j,k,l);

  return *this;
}

RankFourTensor
RankFourTensor::operator-(const RankFourTensor &a) const
{
  RankFourTensor result;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          result(i,j,k,l) = _vals[i][j][k][l] - a(i,j,k,l);

  return result;
}

RankFourTensor
RankFourTensor::operator - () const
{
  RankFourTensor result;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          result(i,j,k,l) = -_vals[i][j][k][l];

  return result;
}

void
RankFourTensor::rotate(RealTensorValue &R)
{
  Real temp;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
        {
          temp = 0.0;
          for(unsigned int m(0); m<N; m++)
            for(unsigned int n(0); n<N; n++)
              for(unsigned int o(0); o<N; o++)
                for(unsigned int p(0); p<N; p++)
                  temp += R(i,m)*R(j,n)*R(k,o)*R(l,p)*_vals[m][n][o][p];

          _vals[i][j][k][l] = temp;
        }

  std::cout << std::endl;

}

void
RankFourTensor::print()
{
  RankFourTensor & s = (*this);

  for(unsigned int i=0; i<N; i++)
    for(unsigned int j=0; j<N; j++)
    {
      std::cout << "i = " << i << " j = " << j << std::endl;
      for(unsigned int k=0; k<N; k++)
      {
        for(unsigned int l=0; l<N; l++)
          std::cout << std::setw(15) <<s(i,j,k,l)<<" ";

        std::cout <<std::endl;
      }
    }

}
<commit_msg>fix the rotation of RankFourTensor<commit_after>#include "RankFourTensor.h"

// Any other includes here
#include <vector>
#include "tensor_value.h"
#include "MaterialProperty.h"
#include "libmesh.h"
#include <ostream>

RankFourTensor::RankFourTensor()
{
  for (unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          _vals[i][j][k][l] = 0.0;
}

RankFourTensor::RankFourTensor(const RankFourTensor &a)
{
  *this = a;
}

Real &
RankFourTensor::operator()(unsigned int i, unsigned int j, unsigned int k, unsigned int l)
{
  return _vals[i][j][k][l];
}

Real
RankFourTensor::operator()(unsigned int i, unsigned int j, unsigned int k, unsigned int l) const
{
  return _vals[i][j][k][l];
}

void
RankFourTensor::setValue(Real val, unsigned int i, unsigned int j, unsigned int k, unsigned int l)
{
  _vals[i-1][j-1][k-1][l-1] = val; //Note, indcies go from 1 to 3
}

Real
RankFourTensor::getValue(unsigned int i, unsigned int j, unsigned int k, unsigned int l) const
{
  return _vals[i-1][j-1][k-1][l-1];//Note, indcies go from 1 to 3
}

void
RankFourTensor::zero()
{
  for (unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          _vals[i][j][k][l] = 0.0;
}

RankFourTensor &
RankFourTensor::operator= (const RankFourTensor &a)
{
  for (unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          _vals[i][j][k][l] = a._vals[i][j][k][l];

  return *this;
}

RealTensorValue
RankFourTensor::operator*(const RankTwoTensor &a)
{
  RealTensorValue result;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          result(i,j) += _vals[i][j][k][l]*a(k,l);

  return result;
}

RealTensorValue
RankFourTensor::operator*(const RealTensorValue &a)
{
  RealTensorValue result;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          result(i,j) += _vals[i][j][k][l]*a(k,l);

  return result;
}

RankFourTensor
RankFourTensor::operator*(const Real &a)
{
  RankFourTensor result;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          result(i,j,k,l) = _vals[i][j][k][l]*a;

return result;
}

RankFourTensor &
RankFourTensor::operator*=(const Real &a)
{
  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          _vals[i][j][k][l] = _vals[i][j][k][l]*a;

  return *this;
}
RankFourTensor
RankFourTensor::operator/(const Real &a)
{
  RankFourTensor result;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          result(i,j,k,l) = _vals[i][j][k][l]/a;

return result;
}

RankFourTensor &
RankFourTensor::operator/=(const Real &a)
{
  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          _vals[i][j][k][l] = _vals[i][j][k][l]/a;

  return *this;
}

RankFourTensor &
RankFourTensor::operator+=(const RankFourTensor &a)
{
  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          _vals[i][j][k][l] = _vals[i][j][k][l] + a(i,j,k,l);

  return *this;
}

RankFourTensor
RankFourTensor::operator+(const RankFourTensor &a) const
{
  RankFourTensor result;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          result(i,j,k,l) = _vals[i][j][k][l] + a(i,j,k,l);

  return result;
}

RankFourTensor &
RankFourTensor::operator-=(const RankFourTensor &a)
{
  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          _vals[i][j][k][l] = _vals[i][j][k][l] - a(i,j,k,l);

  return *this;
}

RankFourTensor
RankFourTensor::operator-(const RankFourTensor &a) const
{
  RankFourTensor result;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          result(i,j,k,l) = _vals[i][j][k][l] - a(i,j,k,l);

  return result;
}

RankFourTensor
RankFourTensor::operator - () const
{
  RankFourTensor result;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
          result(i,j,k,l) = -_vals[i][j][k][l];

  return result;
}

void
RankFourTensor::rotate(RealTensorValue &R)
{
  Real temp;
  RankFourTensor old;
  old=*this;

  for(unsigned int i(0); i<N; i++)
    for(unsigned int j(0); j<N; j++)
      for(unsigned int k(0); k<N; k++)
        for(unsigned int l(0); l<N; l++)
        {
          temp = 0.0;
          for(unsigned int m(0); m<N; m++)
            for(unsigned int n(0); n<N; n++)
              for(unsigned int o(0); o<N; o++)
                for(unsigned int p(0); p<N; p++)
                  temp += R(i,m)*R(j,n)*R(k,o)*R(l,p)*old._vals[m][n][o][p];

          _vals[i][j][k][l] = temp;
        }

  std::cout << std::endl;

}

void
RankFourTensor::print()
{
  RankFourTensor & s = (*this);

  for(unsigned int i=0; i<N; i++)
    for(unsigned int j=0; j<N; j++)
    {
      std::cout << "i = " << i << " j = " << j << std::endl;
      for(unsigned int k=0; k<N; k++)
      {
        for(unsigned int l=0; l<N; l++)
          std::cout << std::setw(15) <<s(i,j,k,l)<<" ";

        std::cout <<std::endl;
      }
    }

}
<|endoftext|>


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

/* Author: Ioan Sucan */

#include <gtest/gtest.h>
#include <moveit/planning_scene/planning_scene.h>
#include <urdf_parser/urdf_parser.h>
#include <fstream>
#include <boost/filesystem/path.hpp>
#include <moveit_resources/config.h>

// This function needs to return void so the gtest FAIL() macro inside
// it works right.
void loadRobotModel(urdf::ModelInterfaceSharedPtr& robot_model_out)
{
  boost::filesystem::path res_path(MOVEIT_TEST_RESOURCES_DIR);

  std::string xml_string;
  std::fstream xml_file((res_path / "pr2_description/urdf/robot.xml").string().c_str(), std::fstream::in);
  EXPECT_TRUE(xml_file.is_open());
  while (xml_file.good())
  {
    std::string line;
    std::getline(xml_file, line);
    xml_string += (line + "\n");
  }
  xml_file.close();
  robot_model_out = urdf::parseURDF(xml_string);
}

TEST(PlanningScene, LoadRestore)
{
  urdf::ModelInterfaceSharedPtr urdf_model;
  loadRobotModel(urdf_model);
  srdf::ModelSharedPtr srdf_model(new srdf::Model());
  planning_scene::PlanningScene ps(urdf_model, srdf_model);
  moveit_msgs::PlanningScene ps_msg;
  ps.getPlanningSceneMsg(ps_msg);
  ps.setPlanningSceneMsg(ps_msg);
}

TEST(PlanningScene, LoadRestoreDiff)
{
  urdf::ModelInterfaceSharedPtr urdf_model;
  loadRobotModel(urdf_model);
  srdf::ModelSharedPtr srdf_model(new srdf::Model());

  planning_scene::PlanningScenePtr ps(new planning_scene::PlanningScene(urdf_model, srdf_model));

  collision_detection::World& world = *ps->getWorldNonConst();
  Eigen::Affine3d id = Eigen::Affine3d::Identity();
  world.addToObject("sphere", shapes::ShapeConstPtr(new shapes::Sphere(0.4)), id);

  moveit_msgs::PlanningScene ps_msg;
  ps_msg.robot_state.is_diff = true;
  EXPECT_TRUE(planning_scene::PlanningScene::isEmpty(ps_msg));
  ps->getPlanningSceneMsg(ps_msg);
  ps->setPlanningSceneMsg(ps_msg);
  EXPECT_FALSE(planning_scene::PlanningScene::isEmpty(ps_msg));
  EXPECT_TRUE(world.hasObject("sphere"));

  planning_scene::PlanningScenePtr next = ps->diff();
  EXPECT_TRUE(next->getWorld()->hasObject("sphere"));
  next->getWorldNonConst()->addToObject("sphere2", shapes::ShapeConstPtr(new shapes::Sphere(0.5)), id);
  EXPECT_EQ(next->getWorld()->size(), 2);
  EXPECT_EQ(ps->getWorld()->size(), 1);
  next->getPlanningSceneDiffMsg(ps_msg);
  EXPECT_EQ(ps_msg.world.collision_objects.size(), 1);
  next->decoupleParent();
  moveit_msgs::PlanningScene ps_msg2;
  next->getPlanningSceneDiffMsg(ps_msg2);
  EXPECT_EQ(ps_msg2.world.collision_objects.size(), 0);
  next->getPlanningSceneMsg(ps_msg);
  EXPECT_EQ(ps_msg.world.collision_objects.size(), 2);
  ps->setPlanningSceneMsg(ps_msg);
  EXPECT_EQ(ps->getWorld()->size(), 2);
}

TEST(PlanningScene, MakeAttachedDiff)
{
  srdf::ModelSharedPtr srdf_model(new srdf::Model());
  urdf::ModelInterfaceSharedPtr urdf_model;
  loadRobotModel(urdf_model);

  planning_scene::PlanningScenePtr ps(new planning_scene::PlanningScene(urdf_model, srdf_model));

  collision_detection::World& world = *ps->getWorldNonConst();
  Eigen::Affine3d id = Eigen::Affine3d::Identity();
  world.addToObject("sphere", shapes::ShapeConstPtr(new shapes::Sphere(0.4)), id);

  planning_scene::PlanningScenePtr attached_object_diff_scene = ps->diff();

  moveit_msgs::AttachedCollisionObject att_obj;
  att_obj.link_name = "r_wrist_roll_link";
  att_obj.object.operation = moveit_msgs::CollisionObject::ADD;
  att_obj.object.id = "sphere";

  collision_detection::CollisionRequest req;
  collision_detection::CollisionResult res;

  attached_object_diff_scene->processAttachedCollisionObjectMsg(att_obj);
  attached_object_diff_scene->checkCollision(req, res);
  ps->checkCollision(req, res);
}

int main(int argc, char** argv)
{
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>Improve planning scene tests (#667)<commit_after>/*********************************************************************
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *********************************************************************/

/* Author: Ioan Sucan */

#include <gtest/gtest.h>
#include <moveit/planning_scene/planning_scene.h>
#include <urdf_parser/urdf_parser.h>
#include <fstream>
#include <string>
#include <boost/filesystem/path.hpp>
#include <moveit_resources/config.h>

// This function needs to return void so the gtest FAIL() macro inside
// it works right.
void loadModelFile(std::string filename, std::string& file_content)
{
  boost::filesystem::path res_path(MOVEIT_TEST_RESOURCES_DIR);
  std::string xml_string;
  std::fstream xml_file((res_path / filename).string().c_str(), std::fstream::in);
  EXPECT_TRUE(xml_file.is_open());
  while (xml_file.good())
  {
    std::string line;
    std::getline(xml_file, line);
    xml_string += (line + "\n");
  }
  xml_file.close();
  file_content = xml_string;
}

void loadRobotModel(urdf::ModelInterfaceSharedPtr& robot_model_out)
{
  std::string xml_string;
  loadModelFile("pr2_description/urdf/robot.xml", xml_string);
  robot_model_out = urdf::parseURDF(xml_string);
}
void loadRobotModels(urdf::ModelInterfaceSharedPtr& robot_model_out, srdf::ModelSharedPtr& srdf_model_out)
{
  loadRobotModel(robot_model_out);
  std::string xml_string;
  loadModelFile("pr2_description/srdf/robot.xml", xml_string);
  srdf_model_out->initString(*robot_model_out, xml_string);
}

TEST(PlanningScene, LoadRestore)
{
  urdf::ModelInterfaceSharedPtr urdf_model;
  loadRobotModel(urdf_model);
  srdf::ModelSharedPtr srdf_model(new srdf::Model());
  planning_scene::PlanningScene ps(urdf_model, srdf_model);
  moveit_msgs::PlanningScene ps_msg;
  ps.getPlanningSceneMsg(ps_msg);
  EXPECT_EQ(ps.getName(), ps_msg.name);
  EXPECT_EQ(ps.getRobotModel()->getName(), ps_msg.robot_model_name);
  ps.setPlanningSceneMsg(ps_msg);
  EXPECT_EQ(ps.getName(), ps_msg.name);
  EXPECT_EQ(ps.getRobotModel()->getName(), ps_msg.robot_model_name);
}

TEST(PlanningScene, LoadRestoreDiff)
{
  urdf::ModelInterfaceSharedPtr urdf_model;
  loadRobotModel(urdf_model);
  srdf::ModelSharedPtr srdf_model(new srdf::Model());

  planning_scene::PlanningScenePtr ps(new planning_scene::PlanningScene(urdf_model, srdf_model));

  collision_detection::World& world = *ps->getWorldNonConst();
  Eigen::Affine3d id = Eigen::Affine3d::Identity();
  world.addToObject("sphere", shapes::ShapeConstPtr(new shapes::Sphere(0.4)), id);

  moveit_msgs::PlanningScene ps_msg;
  ps_msg.robot_state.is_diff = true;
  EXPECT_TRUE(planning_scene::PlanningScene::isEmpty(ps_msg));
  ps->getPlanningSceneMsg(ps_msg);
  ps->setPlanningSceneMsg(ps_msg);
  EXPECT_FALSE(planning_scene::PlanningScene::isEmpty(ps_msg));
  EXPECT_TRUE(world.hasObject("sphere"));

  planning_scene::PlanningScenePtr next = ps->diff();
  EXPECT_TRUE(next->getWorld()->hasObject("sphere"));
  next->getWorldNonConst()->addToObject("sphere2", shapes::ShapeConstPtr(new shapes::Sphere(0.5)), id);
  EXPECT_EQ(next->getWorld()->size(), 2);
  EXPECT_EQ(ps->getWorld()->size(), 1);
  next->getPlanningSceneDiffMsg(ps_msg);
  EXPECT_EQ(ps_msg.world.collision_objects.size(), 1);
  next->decoupleParent();
  moveit_msgs::PlanningScene ps_msg2;
  next->getPlanningSceneDiffMsg(ps_msg2);
  EXPECT_EQ(ps_msg2.world.collision_objects.size(), 0);
  next->getPlanningSceneMsg(ps_msg);
  EXPECT_EQ(ps_msg.world.collision_objects.size(), 2);
  ps->setPlanningSceneMsg(ps_msg);
  EXPECT_EQ(ps->getWorld()->size(), 2);
}

TEST(PlanningScene, MakeAttachedDiff)
{
  srdf::ModelSharedPtr srdf_model(new srdf::Model());
  urdf::ModelInterfaceSharedPtr urdf_model;
  loadRobotModel(urdf_model);

  planning_scene::PlanningScenePtr ps(new planning_scene::PlanningScene(urdf_model, srdf_model));

  collision_detection::World& world = *ps->getWorldNonConst();
  Eigen::Affine3d id = Eigen::Affine3d::Identity();
  world.addToObject("sphere", shapes::ShapeConstPtr(new shapes::Sphere(0.4)), id);

  planning_scene::PlanningScenePtr attached_object_diff_scene = ps->diff();

  moveit_msgs::AttachedCollisionObject att_obj;
  att_obj.link_name = "r_wrist_roll_link";
  att_obj.object.operation = moveit_msgs::CollisionObject::ADD;
  att_obj.object.id = "sphere";

  collision_detection::CollisionRequest req;
  collision_detection::CollisionResult res;

  attached_object_diff_scene->processAttachedCollisionObjectMsg(att_obj);
  attached_object_diff_scene->checkCollision(req, res);
  ps->checkCollision(req, res);
}

TEST(PlanningScene, isStateValid)
{
  srdf::ModelSharedPtr srdf_model(new srdf::Model());
  urdf::ModelInterfaceSharedPtr urdf_model;
  loadRobotModels(urdf_model, srdf_model);

  planning_scene::PlanningScenePtr ps(new planning_scene::PlanningScene(urdf_model, srdf_model));
  robot_state::RobotState current_state = ps->getCurrentState();
  if (ps->isStateColliding(current_state, "left_arm"))
  {
    EXPECT_FALSE(ps->isStateValid(current_state, "left_arm"));
  }
}

int main(int argc, char** argv)
{
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before><commit_msg>Run https://gist.github.com/thlorenz/7e9d8ad15566c99fd116 on source files<commit_after><|endoftext|>


<commit_before>
#include "DuktapeScriptBackend.h"

#include <cppassist/logging/logging.h>

#include <cppexpose/reflection/Object.h>
#include <cppexpose/scripting/ScriptContext.h>

#include "DuktapeScriptFunction.h"
#include "DuktapeObjectWrapper.h"

using namespace cppassist;

namespace cppexpose
{

const char * s_duktapeScriptBackendKey   = "duktapeScriptBackend";
const char * s_duktapeNextStashIndexKey  = "duktapeNextStashFunctionIndex";
const char * s_duktapeFunctionPointerKey = "duktapeFunctionPointer";
const char * s_duktapeObjectPointerKey   = "duktapeObjectPointer";
const char * s_duktapePropertyNameKey    = "duktapePropertyName";

DuktapeScriptBackend::DuktapeScriptBackend()
: m_context(nullptr)
{
    // Create duktape script context
    m_context = duk_create_heap_default();
}

DuktapeScriptBackend::~DuktapeScriptBackend()
{
    // Disconnect from Object::beforeDestroy signals
    for (auto & objectWrapper : m_objectWrappers)
    {
        objectWrapper.second.second.disconnect();
    }

    // Destroy duktape script context
    duk_destroy_heap(m_context);
}

void DuktapeScriptBackend::initialize(ScriptContext * scriptContext)
{
    // Store script context
    m_scriptContext = scriptContext;

    // Get stash
    duk_push_global_stash(m_context);

    // Save pointer to script backend in global stash
    void * context_ptr = static_cast<void *>(this);
    duk_push_pointer(m_context, context_ptr);
    duk_put_prop_string(m_context, -2, s_duktapeScriptBackendKey);

    // Initialize next index for storing functions and objects in the stash
    duk_push_int(m_context, 0);
    duk_put_prop_string(m_context, -2, s_duktapeNextStashIndexKey);

    // Release stash
    duk_pop(m_context);
}

void DuktapeScriptBackend::addGlobalObject(Object * obj)
{
    // Wrap object in javascript object
    const auto objWrapper = getOrCreateObjectWrapper(obj);

    // Get global object
    duk_push_global_object(m_context);
    const auto parentIndex = duk_get_top_index(m_context);

    // Push wrapper object
    objWrapper->pushToDukStack();

    // Register object in the global object
    duk_put_prop_string(m_context, parentIndex, obj->name().c_str());

    // Pop global object from stack
    duk_pop(m_context);
}

void DuktapeScriptBackend::removeGlobalObject(Object * obj)
{
    // Remove property in the global object
    duk_push_global_object(m_context);
    duk_del_prop_string(m_context, duk_get_top_index(m_context), obj->name().c_str());
    duk_pop(m_context);
}

Variant DuktapeScriptBackend::evaluate(const std::string & code)
{
    // Execute code
    duk_int_t error = duk_peval_string(m_context, code.c_str());

    // Check for errors
    if (error)
    {
        // Raise exception
        m_scriptContext->scriptException(std::string(duk_safe_to_string(m_context, -1)));

        // Abort and return undefined value
        duk_pop(m_context);
        return Variant();
    }

    // Convert return value to variant
    Variant value = fromDukStack();
    duk_pop(m_context);
    return value;
}

DuktapeScriptBackend * DuktapeScriptBackend::getScriptBackend(duk_context * context)
{
    // Get stash object
    duk_push_global_stash(context);

    // Get pointer to duktape scripting backend
    duk_get_prop_string(context, -1, s_duktapeScriptBackendKey);
    void * ptr = duk_get_pointer(context, -1);
    duk_pop_2(context);

    // Return duktape scripting backend
    return static_cast<DuktapeScriptBackend *>(ptr);
}

Variant DuktapeScriptBackend::fromDukStack(duk_idx_t index)
{
    // Wrapped object function
    if (duk_is_c_function(m_context, index))
    {
        // Get pointer to wrapped function
        duk_get_prop_string(m_context, index, s_duktapeFunctionPointerKey);
        Function * func = reinterpret_cast<Function *>( duk_get_pointer(m_context, -1) );
        duk_pop(m_context);

        // Return wrapped function
        return Variant::fromValue<Function>(*func);
    }

    // Javascript function - will be stored in global stash for access from C++ later
    else if (duk_is_ecmascript_function(m_context, index))
    {
        // Get stash object
        duk_push_global_stash(m_context);

        // Get next free index in global stash
        int funcIndex = getNextStashIndex();
        duk_push_int(m_context, funcIndex);

        // Copy function object to the top and put it as property into global stash
        duk_dup(m_context, -3);
        duk_put_prop(m_context, -3);

        // Close stash
        duk_pop(m_context);

        // Return callable function
        Function function(cppassist::make_unique<DuktapeScriptFunction>(this, funcIndex));
        return Variant::fromValue<Function>(function);
    }

    // Number
    else if (duk_is_number(m_context, index))
    {
        double value = duk_get_number(m_context, index);
        return Variant(value);
    }

    // Boolean
    else if (duk_is_boolean(m_context, index))
    {
        bool value = duk_get_boolean(m_context, index) > 0;
        return Variant(value);
    }

    // String
    else if (duk_is_string(m_context, index))
    {
        const char *str = duk_get_string(m_context, index);
        return Variant(str);
    }

    // Array
    else if (duk_is_array(m_context, index))
    {
        VariantArray array;

        for (unsigned int i = 0; i < duk_get_length(m_context, index); ++i)
        {
            duk_get_prop_index(m_context, index, i);
            array.push_back(fromDukStack());
            duk_pop(m_context);
        }

        return array;
    }

    // Object
    else if (duk_is_object(m_context, index))
    {
        VariantMap map;
        Object * object = nullptr;

        duk_enum(m_context, index, 0);
        while (duk_next(m_context, -1, 1))
        {
            // If a property s_duktapeObjectPointerKey exists, the object is a cppexpose::Object.
            // In this case, extract the pointer and return that below
            // Otherwise, continue to build a key-value map of the object's properties
            if (duk_is_pointer(m_context, -1) && fromDukStack(-2).value<std::string>() == s_duktapeObjectPointerKey)
            {
                const auto objWrapper = static_cast<DuktapeObjectWrapper *>(duk_get_pointer(m_context, -1));
                object = objWrapper->object();

                // no break/return here to avoid duplicating stack clean-up code
            }
            else
            {
                map.insert({fromDukStack(-2).value<std::string>(), fromDukStack(-1)});
            }

            duk_pop_2(m_context);
        }

        duk_pop(m_context);

        // Return either the cppexpose::Object pointer (if exists) or the key-value map
        return object != nullptr ? Variant::fromValue(object) : Variant(map);
    }

    // Pointer
    else if (duk_is_pointer(m_context, index))
    {
        return Variant::fromValue<void *>(duk_get_pointer(m_context, index));
    }

    // Undefined
    else if (duk_is_undefined(m_context, index))
    {
        return Variant();
    }

    // Unknown type
    warning() << "Unknown type found: " << duk_get_type(m_context, index) << std::endl;
    warning() << "Duktape stack dump:" << std::endl;
    duk_dump_context_stderr(m_context);
    return Variant();
}

void DuktapeScriptBackend::pushToDukStack(const Variant & value)
{
    if (value.isBool()) {
        duk_push_boolean(m_context, value.toBool());
    }

    else if (value.isUnsignedIntegral()) {
        duk_push_number(m_context, value.toULongLong());
    }

    else if (value.isSignedIntegral() || value.isIntegral()) {
        duk_push_number(m_context, value.toLongLong());
    }

    else if (value.isFloatingPoint()) {
        duk_push_number(m_context, value.toDouble());
    }

    else if (value.isString()) {
        duk_push_string(m_context, value.toString().c_str());
    }

    else if (value.hasType<char*>()) {
        duk_push_string(m_context, value.value<char*>());
    }

    else if (value.isVariantArray())
    {
        VariantArray variantArray = value.value<VariantArray>();
        duk_idx_t arr_idx = duk_push_array(m_context);

        for (unsigned int i=0; i<variantArray.size(); i++) {
            pushToDukStack(variantArray.at(i));
            duk_put_prop_index(m_context, arr_idx, i);
        }
    }

    else if (value.isVariantMap())
    {
        VariantMap variantMap = value.value<VariantMap>();
        duk_push_object(m_context);

        for (const std::pair<std::string, Variant> & pair : variantMap)
        {
            pushToDukStack(pair.second);
            duk_put_prop_string(m_context, -2, pair.first.c_str());
        }
    }

    else if (value.hasType<cppexpose::Object *>())
    {
        const auto object = value.value<cppexpose::Object *>();
        const auto objWrapper = getOrCreateObjectWrapper(object);
        objWrapper->pushToDukStack();
    }

    else
    {
        warning() << "Unknown variant type found: " << value.type().name();
        duk_push_undefined(m_context);
    }
}

DuktapeObjectWrapper * DuktapeScriptBackend::getOrCreateObjectWrapper(cppexpose::Object * object)
{
    // Check if wrapper exists
    const auto itr = m_objectWrappers.find(object);
    if (itr != m_objectWrappers.end())
    {
        return itr->second.first.get();
    }

    // Wrap object
    auto wrapper = cppassist::make_unique<DuktapeObjectWrapper>(this, object);

    // Delete wrapper when object is destroyed
    // The connection will be deleted when this backend is destroyed
    const auto beforeDestroy = object->beforeDestroy.connect([this, object](AbstractProperty *)
    {
        m_objectWrappers.erase(object);
    });

    // Save wrapper for later
    m_objectWrappers[object] = {std::move(wrapper), beforeDestroy};

    // Return object wrapper
    return m_objectWrappers[object].first.get();
}

int DuktapeScriptBackend::getNextStashIndex()
{
    // Get stash object
    duk_push_global_stash(m_context);

    // Get next free index for functions or objects in global stash
    duk_get_prop_string(m_context, -1, s_duktapeNextStashIndexKey);
    int index = duk_get_int(m_context, -1);

    // Increment next free index
    duk_push_int(m_context, index + 1);
    duk_put_prop_string(m_context, -3, s_duktapeNextStashIndexKey);

    // Clean up stack
    duk_pop(m_context);
    duk_pop(m_context);

    // Return index
    return index;
}

} // namespace cppexpose
<commit_msg>Use duk_has_prop_string to check if an object is a cppexpose::Object<commit_after>
#include "DuktapeScriptBackend.h"

#include <cppassist/logging/logging.h>

#include <cppexpose/reflection/Object.h>
#include <cppexpose/scripting/ScriptContext.h>

#include "DuktapeScriptFunction.h"
#include "DuktapeObjectWrapper.h"

using namespace cppassist;

namespace cppexpose
{

const char * s_duktapeScriptBackendKey   = "duktapeScriptBackend";
const char * s_duktapeNextStashIndexKey  = "duktapeNextStashFunctionIndex";
const char * s_duktapeFunctionPointerKey = "duktapeFunctionPointer";
const char * s_duktapeObjectPointerKey   = "duktapeObjectPointer";
const char * s_duktapePropertyNameKey    = "duktapePropertyName";

DuktapeScriptBackend::DuktapeScriptBackend()
: m_context(nullptr)
{
    // Create duktape script context
    m_context = duk_create_heap_default();
}

DuktapeScriptBackend::~DuktapeScriptBackend()
{
    // Disconnect from Object::beforeDestroy signals
    for (auto & objectWrapper : m_objectWrappers)
    {
        objectWrapper.second.second.disconnect();
    }

    // Destroy duktape script context
    duk_destroy_heap(m_context);
}

void DuktapeScriptBackend::initialize(ScriptContext * scriptContext)
{
    // Store script context
    m_scriptContext = scriptContext;

    // Get stash
    duk_push_global_stash(m_context);

    // Save pointer to script backend in global stash
    void * context_ptr = static_cast<void *>(this);
    duk_push_pointer(m_context, context_ptr);
    duk_put_prop_string(m_context, -2, s_duktapeScriptBackendKey);

    // Initialize next index for storing functions and objects in the stash
    duk_push_int(m_context, 0);
    duk_put_prop_string(m_context, -2, s_duktapeNextStashIndexKey);

    // Release stash
    duk_pop(m_context);
}

void DuktapeScriptBackend::addGlobalObject(Object * obj)
{
    // Wrap object in javascript object
    const auto objWrapper = getOrCreateObjectWrapper(obj);

    // Get global object
    duk_push_global_object(m_context);
    const auto parentIndex = duk_get_top_index(m_context);

    // Push wrapper object
    objWrapper->pushToDukStack();

    // Register object in the global object
    duk_put_prop_string(m_context, parentIndex, obj->name().c_str());

    // Pop global object from stack
    duk_pop(m_context);
}

void DuktapeScriptBackend::removeGlobalObject(Object * obj)
{
    // Remove property in the global object
    duk_push_global_object(m_context);
    duk_del_prop_string(m_context, duk_get_top_index(m_context), obj->name().c_str());
    duk_pop(m_context);
}

Variant DuktapeScriptBackend::evaluate(const std::string & code)
{
    // Execute code
    duk_int_t error = duk_peval_string(m_context, code.c_str());

    // Check for errors
    if (error)
    {
        // Raise exception
        m_scriptContext->scriptException(std::string(duk_safe_to_string(m_context, -1)));

        // Abort and return undefined value
        duk_pop(m_context);
        return Variant();
    }

    // Convert return value to variant
    Variant value = fromDukStack();
    duk_pop(m_context);
    return value;
}

DuktapeScriptBackend * DuktapeScriptBackend::getScriptBackend(duk_context * context)
{
    // Get stash object
    duk_push_global_stash(context);

    // Get pointer to duktape scripting backend
    duk_get_prop_string(context, -1, s_duktapeScriptBackendKey);
    void * ptr = duk_get_pointer(context, -1);
    duk_pop_2(context);

    // Return duktape scripting backend
    return static_cast<DuktapeScriptBackend *>(ptr);
}

Variant DuktapeScriptBackend::fromDukStack(duk_idx_t index)
{
    // Wrapped object function
    if (duk_is_c_function(m_context, index))
    {
        // Get pointer to wrapped function
        duk_get_prop_string(m_context, index, s_duktapeFunctionPointerKey);
        Function * func = reinterpret_cast<Function *>( duk_get_pointer(m_context, -1) );
        duk_pop(m_context);

        // Return wrapped function
        return Variant::fromValue<Function>(*func);
    }

    // Javascript function - will be stored in global stash for access from C++ later
    else if (duk_is_ecmascript_function(m_context, index))
    {
        // Get stash object
        duk_push_global_stash(m_context);

        // Get next free index in global stash
        int funcIndex = getNextStashIndex();
        duk_push_int(m_context, funcIndex);

        // Copy function object to the top and put it as property into global stash
        duk_dup(m_context, -3);
        duk_put_prop(m_context, -3);

        // Close stash
        duk_pop(m_context);

        // Return callable function
        Function function(cppassist::make_unique<DuktapeScriptFunction>(this, funcIndex));
        return Variant::fromValue<Function>(function);
    }

    // Number
    else if (duk_is_number(m_context, index))
    {
        double value = duk_get_number(m_context, index);
        return Variant(value);
    }

    // Boolean
    else if (duk_is_boolean(m_context, index))
    {
        bool value = duk_get_boolean(m_context, index) > 0;
        return Variant(value);
    }

    // String
    else if (duk_is_string(m_context, index))
    {
        const char *str = duk_get_string(m_context, index);
        return Variant(str);
    }

    // Array
    else if (duk_is_array(m_context, index))
    {
        VariantArray array;

        for (unsigned int i = 0; i < duk_get_length(m_context, index); ++i)
        {
            duk_get_prop_index(m_context, index, i);
            array.push_back(fromDukStack());
            duk_pop(m_context);
        }

        return array;
    }

    // Object
    else if (duk_is_object(m_context, index))
    {
        // If a property s_duktapeObjectPointerKey exists, the object is a cppexpose::Object.
        // In this case, extract the pointer and return that
        if (duk_has_prop_string(m_context, index, s_duktapeObjectPointerKey))
        {
            // Push property value
            duk_get_prop_string(m_context, index, s_duktapeObjectPointerKey);

            // Get pointer to wrapper object
            const auto objWrapper = static_cast<DuktapeObjectWrapper *>(duk_require_pointer(m_context, -1));

            // Pop property value
            duk_pop(m_context);

            return Variant::fromValue(objWrapper->object());
        }

        // Otherwise, build a key-value map of the object's properties
        VariantMap map;

        // Push enumerator
        duk_enum(m_context, index, 0);
        while (duk_next(m_context, -1, 1)) // Push next key (-2) & value (-1)
        {
            map.insert({fromDukStack(-2).value<std::string>(), fromDukStack(-1)});

            // Pop key & value
            duk_pop_2(m_context);
        }

        // Pop enumerator
        duk_pop(m_context);

        return Variant(map);
    }

    // Pointer
    else if (duk_is_pointer(m_context, index))
    {
        return Variant::fromValue<void *>(duk_get_pointer(m_context, index));
    }

    // Undefined
    else if (duk_is_undefined(m_context, index))
    {
        return Variant();
    }

    // Unknown type
    warning() << "Unknown type found: " << duk_get_type(m_context, index) << std::endl;
    warning() << "Duktape stack dump:" << std::endl;
    duk_dump_context_stderr(m_context);
    return Variant();
}

void DuktapeScriptBackend::pushToDukStack(const Variant & value)
{
    if (value.isBool()) {
        duk_push_boolean(m_context, value.toBool());
    }

    else if (value.isUnsignedIntegral()) {
        duk_push_number(m_context, value.toULongLong());
    }

    else if (value.isSignedIntegral() || value.isIntegral()) {
        duk_push_number(m_context, value.toLongLong());
    }

    else if (value.isFloatingPoint()) {
        duk_push_number(m_context, value.toDouble());
    }

    else if (value.isString()) {
        duk_push_string(m_context, value.toString().c_str());
    }

    else if (value.hasType<char*>()) {
        duk_push_string(m_context, value.value<char*>());
    }

    else if (value.isVariantArray())
    {
        VariantArray variantArray = value.value<VariantArray>();
        duk_idx_t arr_idx = duk_push_array(m_context);

        for (unsigned int i=0; i<variantArray.size(); i++) {
            pushToDukStack(variantArray.at(i));
            duk_put_prop_index(m_context, arr_idx, i);
        }
    }

    else if (value.isVariantMap())
    {
        VariantMap variantMap = value.value<VariantMap>();
        duk_push_object(m_context);

        for (const std::pair<std::string, Variant> & pair : variantMap)
        {
            pushToDukStack(pair.second);
            duk_put_prop_string(m_context, -2, pair.first.c_str());
        }
    }

    else if (value.hasType<cppexpose::Object *>())
    {
        const auto object = value.value<cppexpose::Object *>();
        const auto objWrapper = getOrCreateObjectWrapper(object);
        objWrapper->pushToDukStack();
    }

    else
    {
        warning() << "Unknown variant type found: " << value.type().name();
        duk_push_undefined(m_context);
    }
}

DuktapeObjectWrapper * DuktapeScriptBackend::getOrCreateObjectWrapper(cppexpose::Object * object)
{
    // Check if wrapper exists
    const auto itr = m_objectWrappers.find(object);
    if (itr != m_objectWrappers.end())
    {
        return itr->second.first.get();
    }

    // Wrap object
    auto wrapper = cppassist::make_unique<DuktapeObjectWrapper>(this, object);

    // Delete wrapper when object is destroyed
    // The connection will be deleted when this backend is destroyed
    const auto beforeDestroy = object->beforeDestroy.connect([this, object](AbstractProperty *)
    {
        m_objectWrappers.erase(object);
    });

    // Save wrapper for later
    m_objectWrappers[object] = {std::move(wrapper), beforeDestroy};

    // Return object wrapper
    return m_objectWrappers[object].first.get();
}

int DuktapeScriptBackend::getNextStashIndex()
{
    // Get stash object
    duk_push_global_stash(m_context);

    // Get next free index for functions or objects in global stash
    duk_get_prop_string(m_context, -1, s_duktapeNextStashIndexKey);
    int index = duk_get_int(m_context, -1);

    // Increment next free index
    duk_push_int(m_context, index + 1);
    duk_put_prop_string(m_context, -3, s_duktapeNextStashIndexKey);

    // Clean up stack
    duk_pop(m_context);
    duk_pop(m_context);

    // Return index
    return index;
}

} // namespace cppexpose
<|endoftext|>


<commit_before>#ifndef ENGINE_UTIL_MATH_HPP
#define ENGINE_UTIL_MATH_HPP

#include <SFML/System.hpp>
#include <Box2D/Box2D.h>

namespace engine {
	const float fPI = 3.141592654f;

	float b2AngleDeg(b2Vec2 from, b2Vec2 to);

	inline bool floatEqual(float a, float b, float epsilon) {
		return fabsf(a - b) < epsilon;
	}

	inline bool floatEqual(const b2Vec2& a, const b2Vec2& b, float epsilon) {
		return floatEqual(a.x, b.x, epsilon) && floatEqual(a.y, b.y, epsilon);
	}

	inline float b2Angle(b2Vec2 from, b2Vec2 to) {
		to -= from;
		return atan2f(to.y, to.x);
	}

	inline float b2Angle(sf::Vector2f from, sf::Vector2f to) {
		to -= from;
		return atan2f(to.y, to.x);
	}

	template<typename T>
	inline float distance(sf::Vector2<T> from, sf::Vector2<T> to) {
		return static_cast<T>(sqrt(
				static_cast<double>(
						(to.x - from.x) * (to.x - from.x) +
						(to.y - from.y) * (to.y - from.y)
				)
		));
	}
}

#endif

<commit_msg>Degree normalize helper<commit_after>#ifndef ENGINE_UTIL_MATH_HPP
#define ENGINE_UTIL_MATH_HPP

#include <SFML/System.hpp>
#include <Box2D/Box2D.h>

namespace engine {
	const float fPI = 3.141592654f;

	float b2AngleDeg(b2Vec2 from, b2Vec2 to);

	inline bool floatEqual(float a, float b, float epsilon) {
		return fabsf(a - b) < epsilon;
	}

	inline bool floatEqual(const b2Vec2& a, const b2Vec2& b, float epsilon) {
		return floatEqual(a.x, b.x, epsilon) && floatEqual(a.y, b.y, epsilon);
	}

	inline float b2Angle(b2Vec2 from, b2Vec2 to) {
		to -= from;
		return atan2f(to.y, to.x);
	}

	inline float b2Angle(sf::Vector2f from, sf::Vector2f to) {
		to -= from;
		return atan2f(to.y, to.x);
	}

	template<typename T>
	inline float distance(sf::Vector2<T> from, sf::Vector2<T> to) {
		return static_cast<T>(sqrt(
				static_cast<double>(
						(to.x - from.x) * (to.x - from.x) +
						(to.y - from.y) * (to.y - from.y)
				)
		));
	}

	inline float NormalizeAngleDeg(float deg) {
		while (deg < 0) {
			deg += 360;
		}
		while (deg > 360) {
			deg -= 360;
		}
		return deg;
	}
}

#endif

<|endoftext|>


<commit_before>// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - 3D Module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#pragma once

#ifndef NAZARA_CAMERA_HPP
#define NAZARA_CAMERA_HPP

#include <Nazara/Prerequesites.hpp>
#include <Nazara/3D/SceneNode.hpp>
#include <Nazara/Math/Frustum.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Math/Rect.hpp>
#include <Nazara/Math/Vector3.hpp>

class NzRenderTarget;

class NAZARA_API NzCamera : public NzSceneNode
{
	public:
		NzCamera();
		~NzCamera();

		void Activate() const;

		void EnsureFrustumUpdate() const;
		void EnsureProjectionMatrixUpdate() const;
		void EnsureViewMatrixUpdate() const;

		float GetAspectRatio() const;
		const NzBoundingBoxf& GetBoundingBox() const override;
		float GetFOV() const;
		const NzFrustumf& GetFrustum() const;
		const NzMatrix4f& GetProjectionMatrix() const;
		nzSceneNodeType GetSceneNodeType() const override;
		const NzRenderTarget* GetTarget() const;
		const NzVector3f& GetUpVector() const;
		const NzMatrix4f& GetViewMatrix() const;
		const NzRectf& GetViewport() const;
		float GetZFar() const;
		float GetZNear() const;

		void SetFOV(float fov);
		void SetTarget(const NzRenderTarget* renderTarget);
		void SetTarget(const NzRenderTarget& renderTarget);
		void SetUpVector(const NzVector3f& upVector);
		void SetViewport(const NzRectf& viewport);
		void SetZFar(float zFar);
		void SetZNear(float zNear);

	private:
		void AddToRenderQueue(NzRenderQueue& renderQueue) const;
		void Invalidate();
		void Register();
		void Unregister();
		void UpdateFrustum() const;
		void UpdateProjectionMatrix() const;
		void UpdateViewMatrix() const;
 		bool VisibilityTest(const NzFrustumf& frustum) override;

		mutable NzFrustumf m_frustum;
		mutable NzMatrix4f m_projectionMatrix;
		mutable NzMatrix4f m_viewMatrix;
		NzRectf m_viewport;
		NzVector3f m_upVector;
		const NzRenderTarget* m_target;
		mutable bool m_frustumUpdated;
		mutable bool m_projectionMatrixUpdated;
		mutable bool m_viewMatrixUpdated;
		mutable float m_aspectRatio;
		float m_fov;
		float m_zFar;
		float m_zNear;
};

#endif // NAZARA_CAMERA_HPP
<commit_msg>Fixed space<commit_after>// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - 3D Module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#pragma once

#ifndef NAZARA_CAMERA_HPP
#define NAZARA_CAMERA_HPP

#include <Nazara/Prerequesites.hpp>
#include <Nazara/3D/SceneNode.hpp>
#include <Nazara/Math/Frustum.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Math/Rect.hpp>
#include <Nazara/Math/Vector3.hpp>

class NzRenderTarget;

class NAZARA_API NzCamera : public NzSceneNode
{
	public:
		NzCamera();
		~NzCamera();

		void Activate() const;

		void EnsureFrustumUpdate() const;
		void EnsureProjectionMatrixUpdate() const;
		void EnsureViewMatrixUpdate() const;

		float GetAspectRatio() const;
		const NzBoundingBoxf& GetBoundingBox() const override;
		float GetFOV() const;
		const NzFrustumf& GetFrustum() const;
		const NzMatrix4f& GetProjectionMatrix() const;
		nzSceneNodeType GetSceneNodeType() const override;
		const NzRenderTarget* GetTarget() const;
		const NzVector3f& GetUpVector() const;
		const NzMatrix4f& GetViewMatrix() const;
		const NzRectf& GetViewport() const;
		float GetZFar() const;
		float GetZNear() const;

		void SetFOV(float fov);
		void SetTarget(const NzRenderTarget* renderTarget);
		void SetTarget(const NzRenderTarget& renderTarget);
		void SetUpVector(const NzVector3f& upVector);
		void SetViewport(const NzRectf& viewport);
		void SetZFar(float zFar);
		void SetZNear(float zNear);

	private:
		void AddToRenderQueue(NzRenderQueue& renderQueue) const;
		void Invalidate();
		void Register();
		void Unregister();
		void UpdateFrustum() const;
		void UpdateProjectionMatrix() const;
		void UpdateViewMatrix() const;
		bool VisibilityTest(const NzFrustumf& frustum) override;

		mutable NzFrustumf m_frustum;
		mutable NzMatrix4f m_projectionMatrix;
		mutable NzMatrix4f m_viewMatrix;
		NzRectf m_viewport;
		NzVector3f m_upVector;
		const NzRenderTarget* m_target;
		mutable bool m_frustumUpdated;
		mutable bool m_projectionMatrixUpdated;
		mutable bool m_viewMatrixUpdated;
		mutable float m_aspectRatio;
		float m_fov;
		float m_zFar;
		float m_zNear;
};

#endif // NAZARA_CAMERA_HPP
<|endoftext|>


<commit_before>/// Gets a shared vector for a row
SHAREDVECTORN row(unsigned i)
{
  // get the starting offset
  const unsigned OFFSET = data() - _data.get();

  SHAREDVECTORN v;
  v._data = _data;
  v._start = OFFSET + i;
  v._inc = leading_dim();
  v._len = _columns;
  return v;
}

/// Gets a constant shared vector for a row
CONST_SHAREDVECTORN row(unsigned i) const
{
  // get the starting offset
  const unsigned OFFSET = data() - _data.get();

  CONST_SHAREDVECTORN v;
  v._data = _data;
  v._start = OFFSET + i;
  v._inc = leading_dim();
  v._len = _columns;
  return v;
}

/// Gets a shared vector for a column
SHAREDVECTORN column(unsigned i)
{
  // get the starting offset
  const unsigned OFFSET = data() - _data.get();

  SHAREDVECTORN v;
  v._data = _data;
  v._start = OFFSET + leading_dim() * i;
  v._inc = 1;
  v._len = _rows;
  return v;
}

/// Gets a shared vector for a column
CONST_SHAREDVECTORN column(unsigned i) const
{
  // get the starting offset
  const unsigned OFFSET = data() - _data.get();

  CONST_SHAREDVECTORN v;
  v._data = _data;
  v._start = OFFSET + leading_dim() * i;
  v._inc = 1;
  v._len = _rows;
  return v;
}

/// Gets a block as a shared matrix
SHAREDMATRIXN block(unsigned row_start, unsigned row_end, unsigned col_start, unsigned col_end)
{
  #ifndef NEXCEPT
  if (row_end < row_start || row_end > _rows || col_end < col_start || col_end > _columns)
    throw InvalidIndexException();
  #endif

  // determine the offset
  const unsigned OFFSET = data() - _data.get();

  SHAREDMATRIXN m;
  m._data = _data;
  m._rows = row_end - row_start;
  m._columns = col_end - col_start;
  m._ld = leading_dim();
  m._start = OFFSET + m._ld * col_start + row_start;
  return m;
}

/// Gets a block as a constant shared matrix
CONST_SHAREDMATRIXN block(unsigned row_start, unsigned row_end, unsigned col_start, unsigned col_end) const
{
  #ifndef NEXCEPT
  if (row_end < row_start || row_end > _rows || col_end < col_start || col_end > _columns)
    throw InvalidIndexException();
  #endif

  // determine the offset
  const unsigned OFFSET = data() - _data.get();

  CONST_SHAREDMATRIXN m;
  m._data = _data;
  m._rows = row_end - row_start;
  m._columns = col_end - col_start;
  m._ld = leading_dim();
  m._start = OFFSET + m._ld * col_start + row_start;
  return m;
}

/// Get an iterator to the beginning
ITERATOR begin()
{
  ITERATOR i;
  i._count = 0;
  i._sz = _rows*_columns;
  i._ld = leading_dim();
  i._rows = _rows;
  i._columns = _columns;
  i._data_start = i._current_data = data();
  return i;
}

/// Get an iterator to the end
ITERATOR end()
{
  ITERATOR i;
  i._sz = _rows*_columns;
  i._count = i._sz;
  i._ld = leading_dim();
  i._rows = _rows;
  i._columns = _columns;
  i._data_start = data();
  i._current_data = data() + i._ld*i._columns;
  return i;
}

/// Get an iterator to the beginning
CONST_ITERATOR begin() const
{
  CONST_ITERATOR i;
  i._count = 0;
  i._sz = _rows*_columns;
  i._ld = leading_dim();
  i._rows = _rows;
  i._columns = _columns;
  i._data_start = i._current_data = data();
  return i;
}

/// Get an iterator to the end
CONST_ITERATOR end() const
{
  CONST_ITERATOR i;
  i._sz = _rows*_columns;
  i._count = i._sz;
  i._ld = leading_dim();
  i._rows = _rows;
  i._columns = _columns;
  i._data_start = data();
  i._current_data = data() + i._ld*i._columns;
  return i;
}

/// Sets a matrix from a vector
template <class V>
XMATRIXN& set(const V& v, Transposition trans)
{
  #ifndef NEXCEPT
  if (sizeof(data()) != sizeof(v.data()))
    throw DataMismatchException();
  #endif

  // resize the matrix
  if (trans == eNoTranspose)
    resize(v.size(), 1);
  else
    resize(1, v.size());

  if (_rows > 0 && _columns > 0)
    CBLAS::copy(v.size(), v.data(), 1, _data.get(), 1);

  return *this;
}

/// Determines the transpose of a matrix and stores the result in a given matrix
template <class M>
static M& transpose(const XMATRIXN& m, M& result)
{
  #ifndef NEXCEPT
  if (sizeof(m.data()) != sizeof(result.data()))
    throw DataMismatchException();
  #endif

  // resize the result
  result.resize(m.columns(), m.rows());

  const REAL* mdata = m.data();
  REAL* rdata = result.data();
  for  (unsigned i=0; i< m.rows(); i++)
    for (unsigned j=0; j< m.columns(); j++)
      rdata[i*result.leading_dim()+j] = mdata[j*m.leading_dim()+i];

  return result;
}

/// Adds m to *this in place
template <class M>
XMATRIXN& operator+=(const M& m)
{
  #ifndef NEXCEPT
  if (_rows != m.rows() || _columns != m.columns())
    throw MissizeException();
  if (sizeof(data()) != sizeof(m.data()))
    throw DataMismatchException();
  #endif

  if (_rows > 0 && _columns > 0)
    std::transform(begin(), end(), m.begin(), begin(), std::plus<REAL>());
  return *this;
}

/// Subtracts m from *this in place
template <class M>
XMATRIXN& operator-=(const M& m)
{
  #ifndef NEXCEPT
  if (_rows != m.rows() || _columns != m.columns())
    throw MissizeException();
  if (sizeof(data()) != sizeof(m.data()))
    throw DataMismatchException();
  #endif

  if (_rows > 0 && _columns > 0)
    std::transform(begin(), end(), m.begin(), begin(), std::minus<REAL>());
  return *this;
}

/// Multiplies the diagonal matrix formed from d by the matrix m
template <class V, class W>
static W& diag_mult(const V& d, const XMATRIXN& m, W& result)
{
  #ifndef NEXCEPT
  if (d.size() != m.rows())
    throw MissizeException();
  if (sizeof(d.data()) != sizeof(m.data()))
    throw DataMismatchException();
  #endif

  result.resize(d.size(), m.columns());
  for (unsigned i=0; i< m.columns(); i++)
    std::transform(d.begin(), d.end(), m.begin()+m.rows()*i, result.begin()+result.rows()*i, std::multiplies<REAL>());

  return result;
}

/// Multiplies the diagonal matrix formed from d by the matrix transpose(m)
template <class V, class W>
static W& diag_mult_transpose(const V& d, const XMATRIXN& m, W& result)
{
  #ifndef NEXCEPT
  if (d.size() != m.columns())
    throw MissizeException();
  if (sizeof(d.data()) != sizeof(m.data()))
    throw DataMismatchException();
  #endif

  // copy the transpose of m to the result
  XMATRIXN::transpose(m, result);

  // do the specified number of times
  for (unsigned i=0; i< m.rows(); i++)
    CBLAS::scal(d.size(), d[i], result.data()+i, result.lda());

  return result;
}

/// Multiplies the diagonal matrix formed from d by the vector v
template <class V, class U, class W>
static W& diag_mult(const V& d, const U& v, W& result)
{
  #ifndef NEXCEPT
  if (d.size() != v.size())
    throw MissizeException();
  if (sizeof(d.data()) != sizeof(v.data()))
    throw DataMismatchException();
  if (sizeof(d.data()) != sizeof(result.data()))
    throw DataMismatchException();
  #endif

  result.resize(d.size());
  std::transform(d.begin(), d.end(), v.begin(), result.begin(), std::multiplies<REAL>());
  return result;
}

<commit_msg>Fixed compile bug in MatrixN::diag_mult_transpose()?<commit_after>/// Gets a shared vector for a row
SHAREDVECTORN row(unsigned i)
{
  // get the starting offset
  const unsigned OFFSET = data() - _data.get();

  SHAREDVECTORN v;
  v._data = _data;
  v._start = OFFSET + i;
  v._inc = leading_dim();
  v._len = _columns;
  return v;
}

/// Gets a constant shared vector for a row
CONST_SHAREDVECTORN row(unsigned i) const
{
  // get the starting offset
  const unsigned OFFSET = data() - _data.get();

  CONST_SHAREDVECTORN v;
  v._data = _data;
  v._start = OFFSET + i;
  v._inc = leading_dim();
  v._len = _columns;
  return v;
}

/// Gets a shared vector for a column
SHAREDVECTORN column(unsigned i)
{
  // get the starting offset
  const unsigned OFFSET = data() - _data.get();

  SHAREDVECTORN v;
  v._data = _data;
  v._start = OFFSET + leading_dim() * i;
  v._inc = 1;
  v._len = _rows;
  return v;
}

/// Gets a shared vector for a column
CONST_SHAREDVECTORN column(unsigned i) const
{
  // get the starting offset
  const unsigned OFFSET = data() - _data.get();

  CONST_SHAREDVECTORN v;
  v._data = _data;
  v._start = OFFSET + leading_dim() * i;
  v._inc = 1;
  v._len = _rows;
  return v;
}

/// Gets a block as a shared matrix
SHAREDMATRIXN block(unsigned row_start, unsigned row_end, unsigned col_start, unsigned col_end)
{
  #ifndef NEXCEPT
  if (row_end < row_start || row_end > _rows || col_end < col_start || col_end > _columns)
    throw InvalidIndexException();
  #endif

  // determine the offset
  const unsigned OFFSET = data() - _data.get();

  SHAREDMATRIXN m;
  m._data = _data;
  m._rows = row_end - row_start;
  m._columns = col_end - col_start;
  m._ld = leading_dim();
  m._start = OFFSET + m._ld * col_start + row_start;
  return m;
}

/// Gets a block as a constant shared matrix
CONST_SHAREDMATRIXN block(unsigned row_start, unsigned row_end, unsigned col_start, unsigned col_end) const
{
  #ifndef NEXCEPT
  if (row_end < row_start || row_end > _rows || col_end < col_start || col_end > _columns)
    throw InvalidIndexException();
  #endif

  // determine the offset
  const unsigned OFFSET = data() - _data.get();

  CONST_SHAREDMATRIXN m;
  m._data = _data;
  m._rows = row_end - row_start;
  m._columns = col_end - col_start;
  m._ld = leading_dim();
  m._start = OFFSET + m._ld * col_start + row_start;
  return m;
}

/// Get an iterator to the beginning
ITERATOR begin()
{
  ITERATOR i;
  i._count = 0;
  i._sz = _rows*_columns;
  i._ld = leading_dim();
  i._rows = _rows;
  i._columns = _columns;
  i._data_start = i._current_data = data();
  return i;
}

/// Get an iterator to the end
ITERATOR end()
{
  ITERATOR i;
  i._sz = _rows*_columns;
  i._count = i._sz;
  i._ld = leading_dim();
  i._rows = _rows;
  i._columns = _columns;
  i._data_start = data();
  i._current_data = data() + i._ld*i._columns;
  return i;
}

/// Get an iterator to the beginning
CONST_ITERATOR begin() const
{
  CONST_ITERATOR i;
  i._count = 0;
  i._sz = _rows*_columns;
  i._ld = leading_dim();
  i._rows = _rows;
  i._columns = _columns;
  i._data_start = i._current_data = data();
  return i;
}

/// Get an iterator to the end
CONST_ITERATOR end() const
{
  CONST_ITERATOR i;
  i._sz = _rows*_columns;
  i._count = i._sz;
  i._ld = leading_dim();
  i._rows = _rows;
  i._columns = _columns;
  i._data_start = data();
  i._current_data = data() + i._ld*i._columns;
  return i;
}

/// Sets a matrix from a vector
template <class V>
XMATRIXN& set(const V& v, Transposition trans)
{
  #ifndef NEXCEPT
  if (sizeof(data()) != sizeof(v.data()))
    throw DataMismatchException();
  #endif

  // resize the matrix
  if (trans == eNoTranspose)
    resize(v.size(), 1);
  else
    resize(1, v.size());

  if (_rows > 0 && _columns > 0)
    CBLAS::copy(v.size(), v.data(), 1, _data.get(), 1);

  return *this;
}

/// Determines the transpose of a matrix and stores the result in a given matrix
template <class M>
static M& transpose(const XMATRIXN& m, M& result)
{
  #ifndef NEXCEPT
  if (sizeof(m.data()) != sizeof(result.data()))
    throw DataMismatchException();
  #endif

  // resize the result
  result.resize(m.columns(), m.rows());

  const REAL* mdata = m.data();
  REAL* rdata = result.data();
  for  (unsigned i=0; i< m.rows(); i++)
    for (unsigned j=0; j< m.columns(); j++)
      rdata[i*result.leading_dim()+j] = mdata[j*m.leading_dim()+i];

  return result;
}

/// Adds m to *this in place
template <class M>
XMATRIXN& operator+=(const M& m)
{
  #ifndef NEXCEPT
  if (_rows != m.rows() || _columns != m.columns())
    throw MissizeException();
  if (sizeof(data()) != sizeof(m.data()))
    throw DataMismatchException();
  #endif

  if (_rows > 0 && _columns > 0)
    std::transform(begin(), end(), m.begin(), begin(), std::plus<REAL>());
  return *this;
}

/// Subtracts m from *this in place
template <class M>
XMATRIXN& operator-=(const M& m)
{
  #ifndef NEXCEPT
  if (_rows != m.rows() || _columns != m.columns())
    throw MissizeException();
  if (sizeof(data()) != sizeof(m.data()))
    throw DataMismatchException();
  #endif

  if (_rows > 0 && _columns > 0)
    std::transform(begin(), end(), m.begin(), begin(), std::minus<REAL>());
  return *this;
}

/// Multiplies the diagonal matrix formed from d by the matrix m
template <class V, class W>
static W& diag_mult(const V& d, const XMATRIXN& m, W& result)
{
  #ifndef NEXCEPT
  if (d.size() != m.rows())
    throw MissizeException();
  if (sizeof(d.data()) != sizeof(m.data()))
    throw DataMismatchException();
  #endif

  result.resize(d.size(), m.columns());
  for (unsigned i=0; i< m.columns(); i++)
    std::transform(d.begin(), d.end(), m.begin()+m.rows()*i, result.begin()+result.rows()*i, std::multiplies<REAL>());

  return result;
}

/// Multiplies the diagonal matrix formed from d by the matrix transpose(m)
template <class V, class W>
static W& diag_mult_transpose(const V& d, const XMATRIXN& m, W& result)
{
  #ifndef NEXCEPT
  if (d.size() != m.columns())
    throw MissizeException();
  if (sizeof(d.data()) != sizeof(m.data()))
    throw DataMismatchException();
  #endif

  // copy the transpose of m to the result
  XMATRIXN::transpose(m, result);

  // do the specified number of times
  for (unsigned i=0; i< m.rows(); i++)
    CBLAS::scal(d.size(), d[i], result.data()+i, result.leading_dim());

  return result;
}

/// Multiplies the diagonal matrix formed from d by the vector v
template <class V, class U, class W>
static W& diag_mult(const V& d, const U& v, W& result)
{
  #ifndef NEXCEPT
  if (d.size() != v.size())
    throw MissizeException();
  if (sizeof(d.data()) != sizeof(v.data()))
    throw DataMismatchException();
  if (sizeof(d.data()) != sizeof(result.data()))
    throw DataMismatchException();
  #endif

  result.resize(d.size());
  std::transform(d.begin(), d.end(), v.begin(), result.begin(), std::multiplies<REAL>());
  return result;
}

<|endoftext|>