<commit_before>/*
 * <one line to give the program's name and a brief idea of what it does.>
 * Copyright (C) 2014  Salvo Tomaselli <tiposchi@tiscali.it>
 *
 * 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.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 */
#include <unordered_set>

#include "boardai.h"

bool BoardAI::place(int col, player_t player) {

    bool r = Board::place(col,player);

    if (!r)
        return false;

    if (player != this->aiplayer) {
        //Play AI round
        airound();
    }

    return true;

}

void BoardAI::airound() {

    player_t other_player = (player_t)~aiplayer;

    //Do nothing if the game is already over
    if (this->completed) {
        return;
    }

    //Win in 1 move
    {
        for (int c=0; c<this->cols; c++) {
            int r = free_slot(c);

            if (r != -1 && winning_move(r,c,aiplayer)) {
                printf("Win in 1 move\n");
                place(c,aiplayer);
                return;
            }

        }
    }

    //Prevent win in 1 move
    {
        for (int c=0; c<this->cols; c++) {
            int r = free_slot(c);

            if (r != -1 && winning_move(r,c,other_player)) {
                printf("Prevent win in 1 move\n");
                place(c,aiplayer);
                return;
            }
        }
    }

    //Block lineup of 3 central pieces

    //Horizontal
    {
        for (int row = 0; row< this->rows; row ++) {
            for (int col = 1; col < this->cols-2; col++) {
                if (
                (
                get_content(row,col-1) == CELL_EMPTY &&
                get_content(row,col) == (cell_t)other_player &&
                get_content(row,col+1) == (cell_t)other_player &&
                get_content(row,col+2) == CELL_EMPTY
                ) ||
                (
                get_content(row,col-1) == CELL_EMPTY &&
                get_content(row,col) == (cell_t)other_player &&
                get_content(row,col+1) == CELL_EMPTY &&
                get_content(row,col+2) == (cell_t)other_player
                )) {
                    int r1 = free_slot(col-1);
                    int r2= free_slot(col+2);
                    int r3 = free_slot(col+1);

                    if (r1== row) {
                        printf("Prevent horizontal lineup of 3 pieces %d\n",__LINE__);
                        place(col-1, aiplayer);
                        return;
                    } else if (r2== row){
                        printf("Prevent horizontal lineup of 3 pieces %d\n",__LINE__);
                        place(col+2,aiplayer);
                        return;
                    } else if (r3== row) {
                        printf("Prevent horizontal lineup of 3 pieces %d\n",__LINE__);
                        place(col+1,aiplayer);
                        return;
                    }
                }
            }
        }
    }
    //Diagonal
    {
        for (int row = 1; row< this->rows-1; row ++) {
            for (int col = 2; col < this->cols-2; col++) {
                if (
                (
                get_content(row-1,col-1) == CELL_EMPTY &&
                get_content(row,col) == (cell_t)other_player &&
                get_content(row+1,col+1) == (cell_t)other_player &&
                get_content(row+2,col+2) == CELL_EMPTY
                ) ||
                (
                get_content(row-1,col-1) == CELL_EMPTY &&
                get_content(row,col) == (cell_t)other_player &&
                get_content(row+1,col+1) == CELL_EMPTY &&
                get_content(row+2,col+2) == (cell_t)other_player
                )) {
                    int r1 = free_slot(col-1);
                    int r2= free_slot(col+2);
                    int r3 = free_slot(col+1);

                    if (r1== row-1) {
                        place(col-1, aiplayer);
                        printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
                        return;
                    } else if (r2== row+2){
                        place(col+2,aiplayer);
                        printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
                        return;
                    } else if (r3== row+1) {
                        place(col+1,aiplayer);
                        printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
                        return;
                    }
                }
            }
        }
    }
    {
        for (int row = 1; row< this->rows-1; row ++) {
            for (int col = 2; col < this->cols-2; col++) {
                if (
                (
                get_content(row+1,col-1) == CELL_EMPTY &&
                get_content(row,col) == (cell_t)other_player &&
                get_content(row-1,col+1) == (cell_t)other_player &&
                get_content(row-2,col+2) == CELL_EMPTY
                ) ||
                (
                get_content(row+1,col-1) == CELL_EMPTY &&
                get_content(row,col) == (cell_t)other_player &&
                get_content(row-1,col+1) == CELL_EMPTY &&
                get_content(row-2,col+2) == (cell_t)other_player
                )) {
                    int r1 = free_slot(col-1);
                    int r2= free_slot(col+2);
                    int r3 = free_slot(col+1);

                    if (r1== row+1) {
                        place(col-1, aiplayer);
                        printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
                        return;
                    } else if (r2== row-2){
                        place(col+2,aiplayer);
                        printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
                        return;
                    } else if (r3== row-1) {
                        place(col+1,aiplayer);
                        printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
                        return;
                    }
                }
            }
        }
    }

    //play randomly but blacklist some columns
    {
        printf("Randomly… %d\n",__LINE__);
        std::unordered_set<int> allowed_columns;
        for (int c=0; c< this->cols;c++)
            allowed_columns.insert(c);

        for (int c=0; c< this->cols;c++) {
            int r = free_slot(c)-1;
            if (r>=0 && winning_move(r,c,other_player)) {
                allowed_columns.erase(c);
            }
        }

            int c;
            do {
                c = rand() % this->cols;
                if ((!allowed_columns.empty()) && (allowed_columns.find(c) != allowed_columns.end()))
                    continue;
            } while(!this->place(c,this->aiplayer));
    }
}
<commit_msg>Fixed column blacklisting<commit_after>/*
 * <one line to give the program's name and a brief idea of what it does.>
 * Copyright (C) 2014  Salvo Tomaselli <tiposchi@tiscali.it>
 *
 * 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.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 */
#include <unordered_set>

#include "boardai.h"

bool BoardAI::place(int col, player_t player) {

    bool r = Board::place(col,player);

    if (!r)
        return false;

    if (player != this->aiplayer) {
        //Play AI round
        airound();
    }

    return true;

}

void BoardAI::airound() {

    player_t other_player = (player_t)~aiplayer;

    //Do nothing if the game is already over
    if (this->completed) {
        return;
    }

    //Win in 1 move
    {
        for (int c=0; c<this->cols; c++) {
            int r = free_slot(c);

            if (r != -1 && winning_move(r,c,aiplayer)) {
                printf("Win in 1 move\n");
                place(c,aiplayer);
                return;
            }

        }
    }

    //Prevent win in 1 move
    {
        for (int c=0; c<this->cols; c++) {
            int r = free_slot(c);

            if (r != -1 && winning_move(r,c,other_player)) {
                printf("Prevent win in 1 move\n");
                place(c,aiplayer);
                return;
            }
        }
    }

    //Block lineup of 3 central pieces

    //Horizontal
    {
        for (int row = 0; row< this->rows; row ++) {
            for (int col = 1; col < this->cols-2; col++) {
                if (
                (
                get_content(row,col-1) == CELL_EMPTY &&
                get_content(row,col) == (cell_t)other_player &&
                get_content(row,col+1) == (cell_t)other_player &&
                get_content(row,col+2) == CELL_EMPTY
                ) ||
                (
                get_content(row,col-1) == CELL_EMPTY &&
                get_content(row,col) == (cell_t)other_player &&
                get_content(row,col+1) == CELL_EMPTY &&
                get_content(row,col+2) == (cell_t)other_player
                )) {
                    int r1 = free_slot(col-1);
                    int r2= free_slot(col+2);
                    int r3 = free_slot(col+1);

                    if (r1== row) {
                        printf("Prevent horizontal lineup of 3 pieces %d\n",__LINE__);
                        place(col-1, aiplayer);
                        return;
                    } else if (r2== row){
                        printf("Prevent horizontal lineup of 3 pieces %d\n",__LINE__);
                        place(col+2,aiplayer);
                        return;
                    } else if (r3== row) {
                        printf("Prevent horizontal lineup of 3 pieces %d\n",__LINE__);
                        place(col+1,aiplayer);
                        return;
                    }
                }
            }
        }
    }
    //Diagonal
    {
        for (int row = 1; row< this->rows-1; row ++) {
            for (int col = 2; col < this->cols-2; col++) {
                if (
                (
                get_content(row-1,col-1) == CELL_EMPTY &&
                get_content(row,col) == (cell_t)other_player &&
                get_content(row+1,col+1) == (cell_t)other_player &&
                get_content(row+2,col+2) == CELL_EMPTY
                ) ||
                (
                get_content(row-1,col-1) == CELL_EMPTY &&
                get_content(row,col) == (cell_t)other_player &&
                get_content(row+1,col+1) == CELL_EMPTY &&
                get_content(row+2,col+2) == (cell_t)other_player
                )) {
                    int r1 = free_slot(col-1);
                    int r2= free_slot(col+2);
                    int r3 = free_slot(col+1);

                    if (r1== row-1) {
                        place(col-1, aiplayer);
                        printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
                        return;
                    } else if (r2== row+2){
                        place(col+2,aiplayer);
                        printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
                        return;
                    } else if (r3== row+1) {
                        place(col+1,aiplayer);
                        printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
                        return;
                    }
                }
            }
        }
    }
    {
        for (int row = 1; row< this->rows-1; row ++) {
            for (int col = 2; col < this->cols-2; col++) {
                if (
                (
                get_content(row+1,col-1) == CELL_EMPTY &&
                get_content(row,col) == (cell_t)other_player &&
                get_content(row-1,col+1) == (cell_t)other_player &&
                get_content(row-2,col+2) == CELL_EMPTY
                ) ||
                (
                get_content(row+1,col-1) == CELL_EMPTY &&
                get_content(row,col) == (cell_t)other_player &&
                get_content(row-1,col+1) == CELL_EMPTY &&
                get_content(row-2,col+2) == (cell_t)other_player
                )) {
                    int r1 = free_slot(col-1);
                    int r2= free_slot(col+2);
                    int r3 = free_slot(col+1);

                    if (r1== row+1) {
                        place(col-1, aiplayer);
                        printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
                        return;
                    } else if (r2== row-2){
                        place(col+2,aiplayer);
                        printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
                        return;
                    } else if (r3== row-1) {
                        place(col+1,aiplayer);
                        printf("Prevent diagonal lineup of 3 pieces %d\n",__LINE__);
                        return;
                    }
                }
            }
        }
    }

    //play randomly but blacklist some columns
    {
        printf("Randomly… %d: ",__LINE__);
        std::unordered_set<int> allowed_columns;

        for (int c=0; c< this->cols;c++) {
            allowed_columns.insert(c);

        }

        for (int c=0; c< this->cols;c++) {
            int r = free_slot(c)-1;
            if (r>=0 && winning_move(r,c,other_player)) {
                allowed_columns.erase(c);
                printf("%d ",c);
            }
        }
        printf("\n");

        int c;
        while (true) {
            c = rand() % this->cols;
            printf("Selecting column %d\n",c);
            if ((!allowed_columns.empty()) && (allowed_columns.find(c) == allowed_columns.end()))
                continue;
            if (this->place(c,this->aiplayer))
                break;
        }
    }
}
<|endoftext|>


<commit_before>#include "Table.h"

//  int insertInstruction(int state, int symbol, int newState, int newSymbol,
//                        char instruction);
//  void removeInstruction(int id);
//  machineAction_t getAction(int state, int symbol);

// TODO: implement Table methods

int Table::insertInstruction(int state, int symbol, int newState, int newSymbol,
                             char instruction)
{
  machineState_t mStat;
  mStat.state = state;
  mStat.symbol = symbol;

  machineAction_t mAct;
  mAct.newState = newState;
  mAct.newSymbol = newSymbol;
  mAct.instruction = instruction;

  machineInstruction_t mInst;
  mInst.state = mStat;
  mInst.action = mAct;
  mInst.id = 0;  // TODO: figure out something to do with ID's or remove them

  this.table.push_back(mInst);
}
<commit_msg>Make insert instruction return something<commit_after>#include "Table.h"

//  int insertInstruction(int state, int symbol, int newState, int newSymbol,
//                        char instruction);
//  void removeInstruction(int id);
//  machineAction_t getAction(int state, int symbol);

// TODO: implement Table methods

int Table::insertInstruction(int state, int symbol, int newState, int newSymbol,
                             char instruction)
{
  machineState_t mStat;
  mStat.state = state;
  mStat.symbol = symbol;

  machineAction_t mAct;
  mAct.newState = newState;
  mAct.newSymbol = newSymbol;
  mAct.instruction = instruction;

  machineInstruction_t mInst;
  mInst.state = mStat;
  mInst.action = mAct;
  mInst.id = 0;  // TODO: figure out something to do with ID's or remove them

  this.table.push_back(mInst);

  return 0;  //TODO: Figure out something to do with id's
}
<|endoftext|>


<commit_before>/*
  Copyright (c) 2014 D. Niklaus.  All right reserved.

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

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

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

/*
 * Timer.cpp
 *
 *  Created on: 13.08.2013
 *      Author: niklausd
 */

#include <limits.h>
#include "UptimeInfo.h"
#include "Timer.h"
#include "TimerContext.h"

void scheduleTimers()
{
  TimerContext::instance()->handleTick();
}

void yield()
{
  TimerContext::instance()->handleTick();
}

void delayAndSchedule(unsigned int delayMillis)
{
  // create a one-shot timer on the fly
  Timer delayTimer(0, Timer::IS_NON_RECURRING, (delayMillis));

  // wait until the timer expires
  while (!delayTimer.isTimerExpired())
  {
    // schedule the timer above and all the other timers, so they will still run in 'parallel'
    scheduleTimers();
  }
}

const bool Timer::IS_NON_RECURRING = false;
const bool Timer::IS_RECURRING     = true;

Timer::Timer(TimerAdapter* adapter, bool isRecurring, unsigned long timeMillis)
: m_isRecurring(isRecurring)
, m_isExpiredFlag(false)
, m_currentTimeMillis(0)
, m_triggerTimeMillis(0)
, m_triggerTimeMillisUpperLimit(ULONG_MAX)
, m_delayMillis(0)
, m_adapter(adapter)
, m_next(0)
{
  TimerContext::instance()->attach(this);

  if (0 < timeMillis)
  {
    startTimer(timeMillis);
  }
}

Timer::~Timer()
{
  TimerContext::instance()->detach(this);
}

void Timer::attachAdapter(TimerAdapter* adapter)
{
  m_adapter = adapter;
}

TimerAdapter* Timer::adapter()
{
  return m_adapter;
}

Timer* Timer::next()
{
  return m_next;
}

void Timer::setNext(Timer* timer)
{
  m_next = timer;
}

bool Timer::isTimerExpired()
{
  internalTick();
  bool isExpired = m_isExpiredFlag;
  m_isExpiredFlag = false;
  return isExpired;
}

bool Timer::isRunning()
{
  return (0 != m_delayMillis);
}

void Timer::tick()
{
  internalTick();
}

void Timer::cancelTimer()
{
  m_delayMillis = 0;
  m_isExpiredFlag = false;
}

void Timer::startTimer(unsigned long timeMillis)
{
  m_delayMillis = timeMillis;
  if (m_delayMillis > 0)
  {
    m_currentTimeMillis = UptimeInfo::tMillis();
    startInterval();
  }
  else
  {
    cancelTimer();
  }
}

void Timer::startTimer()
{
  if (m_delayMillis > 0)
  {
    m_currentTimeMillis = UptimeInfo::tMillis();
    startInterval();
  }
}

void Timer::startInterval()
{
  unsigned long deltaTime = ULONG_MAX - m_currentTimeMillis;
  if (deltaTime < m_delayMillis)
  {
    // overflow will occur
    m_triggerTimeMillis = m_delayMillis - deltaTime - 1;
    m_triggerTimeMillisUpperLimit = m_currentTimeMillis;
  }
  else
  {
    m_triggerTimeMillis = m_currentTimeMillis + m_delayMillis - 1;
    m_triggerTimeMillisUpperLimit = ULONG_MAX;
  }
}

void Timer::internalTick()
{
  m_currentTimeMillis = UptimeInfo::tMillis();

  // check if interval is over, as long as (m_delayMillis > 0)
  if ((m_delayMillis > 0) && (m_triggerTimeMillis < m_currentTimeMillis) && (m_currentTimeMillis < m_triggerTimeMillisUpperLimit))
  {
    if (m_isRecurring)
    {
      startInterval();
    }
    else
    {
      m_delayMillis = 0;
    }

    m_isExpiredFlag = true;
    if (0 != m_adapter)
    {
      m_adapter->timeExpired();
    }
  }
}
<commit_msg>Remove LGPL license header<commit_after>/*
 * Timer.cpp
 *
 *  Created on: 13.08.2013
 *      Author: niklausd
 */

#include <limits.h>
#include "UptimeInfo.h"
#include "Timer.h"
#include "TimerContext.h"

void scheduleTimers()
{
  TimerContext::instance()->handleTick();
}

void yield()
{
  TimerContext::instance()->handleTick();
}

void delayAndSchedule(unsigned int delayMillis)
{
  // create a one-shot timer on the fly
  Timer delayTimer(0, Timer::IS_NON_RECURRING, (delayMillis));

  // wait until the timer expires
  while (!delayTimer.isTimerExpired())
  {
    // schedule the timer above and all the other timers, so they will still run in 'parallel'
    scheduleTimers();
  }
}

const bool Timer::IS_NON_RECURRING = false;
const bool Timer::IS_RECURRING     = true;

Timer::Timer(TimerAdapter* adapter, bool isRecurring, unsigned long timeMillis)
: m_isRecurring(isRecurring)
, m_isExpiredFlag(false)
, m_currentTimeMillis(0)
, m_triggerTimeMillis(0)
, m_triggerTimeMillisUpperLimit(ULONG_MAX)
, m_delayMillis(0)
, m_adapter(adapter)
, m_next(0)
{
  TimerContext::instance()->attach(this);

  if (0 < timeMillis)
  {
    startTimer(timeMillis);
  }
}

Timer::~Timer()
{
  TimerContext::instance()->detach(this);
}

void Timer::attachAdapter(TimerAdapter* adapter)
{
  m_adapter = adapter;
}

TimerAdapter* Timer::adapter()
{
  return m_adapter;
}

Timer* Timer::next()
{
  return m_next;
}

void Timer::setNext(Timer* timer)
{
  m_next = timer;
}

bool Timer::isTimerExpired()
{
  internalTick();
  bool isExpired = m_isExpiredFlag;
  m_isExpiredFlag = false;
  return isExpired;
}

bool Timer::isRunning()
{
  return (0 != m_delayMillis);
}

void Timer::tick()
{
  internalTick();
}

void Timer::cancelTimer()
{
  m_delayMillis = 0;
  m_isExpiredFlag = false;
}

void Timer::startTimer(unsigned long timeMillis)
{
  m_delayMillis = timeMillis;
  if (m_delayMillis > 0)
  {
    m_currentTimeMillis = UptimeInfo::tMillis();
    startInterval();
  }
  else
  {
    cancelTimer();
  }
}

void Timer::startTimer()
{
  if (m_delayMillis > 0)
  {
    m_currentTimeMillis = UptimeInfo::tMillis();
    startInterval();
  }
}

void Timer::startInterval()
{
  unsigned long deltaTime = ULONG_MAX - m_currentTimeMillis;
  if (deltaTime < m_delayMillis)
  {
    // overflow will occur
    m_triggerTimeMillis = m_delayMillis - deltaTime - 1;
    m_triggerTimeMillisUpperLimit = m_currentTimeMillis;
  }
  else
  {
    m_triggerTimeMillis = m_currentTimeMillis + m_delayMillis - 1;
    m_triggerTimeMillisUpperLimit = ULONG_MAX;
  }
}

void Timer::internalTick()
{
  m_currentTimeMillis = UptimeInfo::tMillis();

  // check if interval is over, as long as (m_delayMillis > 0)
  if ((m_delayMillis > 0) && (m_triggerTimeMillis < m_currentTimeMillis) && (m_currentTimeMillis < m_triggerTimeMillisUpperLimit))
  {
    if (m_isRecurring)
    {
      startInterval();
    }
    else
    {
      m_delayMillis = 0;
    }

    m_isExpiredFlag = true;
    if (0 != m_adapter)
    {
      m_adapter->timeExpired();
    }
  }
}
<|endoftext|>


<commit_before>#include <cfloat>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <sys/time.h>

#include <string>
#include <algorithm>

#include "Utils.hpp"

using namespace std;

namespace SpMP
{

static const double DEFAULT_CPU_FREQ = 3.33e9;
double get_cpu_freq()
{
  static double freq = DBL_MAX;
  if (DBL_MAX == freq) {
    volatile double a = rand()%1024, b = rand()%1024;
    struct timeval tv1, tv2;
    gettimeofday(&tv1, NULL);
    unsigned long long t1 = __rdtsc();
    for (size_t i = 0; i < 1024L*1024; i++) {
      a += a*b + b/a;
    }
    unsigned long long dt = __rdtsc() - t1;
    gettimeofday(&tv2, NULL);
    freq = dt/((tv2.tv_sec - tv1.tv_sec) + (tv2.tv_usec - tv1.tv_usec)/1.e6);
  }

  return freq;
}

void getInversePerm(int *inversePerm, const int *perm, int n)
{
#pragma omp parallel for
#pragma simd
  for (int i = 0; i < n; ++i) {
    inversePerm[perm[i]] = i;
  }
}

bool isPerm(const int *perm, int n)
{
  int *temp = new int[n];
  memcpy(temp, perm, sizeof(int)*n);
  sort(temp, temp + n);
  int *last = unique(temp, temp + n);
  if (last != temp + n) {
    memcpy(temp, perm, sizeof(int)*n);
    sort(temp, temp + n);

    for (int i = 0; i < n; ++i) {
      if (temp[i] == i - 1) {
        printf("%d duplicated\n", i - 1);
        assert(false);
        return false;
      }
      else if (temp[i] != i) {
        printf("%d missed\n", i);
        assert(false);
        return false;
      }
    }
  }
  delete[] temp;
  return true;
}

template<class T>
void CopyVector(T *dst, const T *src, int len)
{
#pragma omp parallel for
  for (int i = 0; i < len; ++i) {
    dst[i] = src[i];
  }
}

void reorderVectorOutOfPlace(double *dst, const double *src, const int *perm, int len)
{
  if (perm) {
#pragma omp parallel for
    for (int i = 0; i < len; ++i) {
      assert(perm[i] >= 0 && perm[i] < len);
      dst[perm[i]] = src[i];
    }
  }
  else {
    CopyVector(dst, src, len);
  }
}

void reorderVectorOutOfPlaceWithInversePerm(double *dst, const double *src, const int *inversePerm, int len)
{
  if (inversePerm) {
#pragma omp parallel for
    for (int i = 0; i < len; ++i) {
      assert(inversePerm[i] >= 0 && inversePerm[i] < len);
      dst[i] = src[inversePerm[i]];
    }
  }
  else {
    CopyVector(dst, src, len);
  }
}

double *getReorderVector(const double *v, const int *perm, int len)
{
  double *ret = MALLOC(double, len);

  reorderVectorOutOfPlace(ret, v, perm, len);

  return ret;
}

double *getReorderVectorWithInversePerm(const double *v, const int *perm, int len)
{
  double *ret = MALLOC(double, len);

  reorderVectorOutOfPlaceWithInversePerm(ret, v, perm, len);

  return ret;
}

void reorderVector(double *v, double *tmp, const int *perm, int len)
{
  if (!perm) return;

  reorderVectorOutOfPlace(tmp, v, perm, len);
  CopyVector(v, tmp, len);
}

void reorderVectorWithInversePerm(double *v, double *tmp, const int *inversePerm, int len)
{
  if (!inversePerm) return;

  reorderVectorOutOfPlaceWithInversePerm(tmp, v, inversePerm, len);
  CopyVector(v, tmp, len);
}

void reorderVector(double *v, const int *perm, int len)
{
  double *tmp = MALLOC(double, len);
  reorderVector(v, tmp, perm, len);
  FREE(tmp);
}

void reorderVectorWithInversePerm(double *v, const int *perm, int len)
{
  double *tmp = MALLOC(double, len);
  reorderVectorWithInversePerm(v, tmp, perm, len);
  FREE(tmp);
}

} // namespace SpMP
<commit_msg>reorder int vector<commit_after>#include <cfloat>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <sys/time.h>

#include <string>
#include <algorithm>

#include "Utils.hpp"

using namespace std;

namespace SpMP
{

static const double DEFAULT_CPU_FREQ = 3.33e9;
double get_cpu_freq()
{
  static double freq = DBL_MAX;
  if (DBL_MAX == freq) {
    volatile double a = rand()%1024, b = rand()%1024;
    struct timeval tv1, tv2;
    gettimeofday(&tv1, NULL);
    unsigned long long t1 = __rdtsc();
    for (size_t i = 0; i < 1024L*1024; i++) {
      a += a*b + b/a;
    }
    unsigned long long dt = __rdtsc() - t1;
    gettimeofday(&tv2, NULL);
    freq = dt/((tv2.tv_sec - tv1.tv_sec) + (tv2.tv_usec - tv1.tv_usec)/1.e6);
  }

  return freq;
}

void getInversePerm(int *inversePerm, const int *perm, int n)
{
#pragma omp parallel for
#pragma simd
  for (int i = 0; i < n; ++i) {
    inversePerm[perm[i]] = i;
  }
}

bool isPerm(const int *perm, int n)
{
  int *temp = new int[n];
  memcpy(temp, perm, sizeof(int)*n);
  sort(temp, temp + n);
  int *last = unique(temp, temp + n);
  if (last != temp + n) {
    memcpy(temp, perm, sizeof(int)*n);
    sort(temp, temp + n);

    for (int i = 0; i < n; ++i) {
      if (temp[i] == i - 1) {
        printf("%d duplicated\n", i - 1);
        assert(false);
        return false;
      }
      else if (temp[i] != i) {
        printf("%d missed\n", i);
        assert(false);
        return false;
      }
    }
  }
  delete[] temp;
  return true;
}

bool isInversePerm(const int *perm, const int *inversePerm, int len)
{
  for (int i = 0; i < len; ++i) {
    if (inversePerm[perm[i]] != i) return false;
  }
  return true;
}

template<class T>
void CopyVector(T *dst, const T *src, int len)
{
#pragma omp parallel for
  for (int i = 0; i < len; ++i) {
    dst[i] = src[i];
  }
}

template<class T>
void reorderVectorOutOfPlace_(T *dst, const T *src, const int *perm, int len)
{
  if (perm) {
#pragma omp parallel for
    for (int i = 0; i < len; ++i) {
      assert(perm[i] >= 0 && perm[i] < len);
      dst[perm[i]] = src[i];
    }
  }
  else {
    CopyVector(dst, src, len);
  }
}

void reorderVectorOutOfPlace(double *dst, const double *src, const int *perm, int len)
{
  return reorderVectorOutOfPlace_(dst, src, perm, len);
}

void reorderVectorOutOfPlace(int *dst, const int *src, const int *perm, int len)
{
  return reorderVectorOutOfPlace_(dst, src, perm, len);
}

template<class T>
void reorderVectorOutOfPlaceWithInversePerm_(T *dst, const T *src, const int *inversePerm, int len)
{
  if (inversePerm) {
#pragma omp parallel for
    for (int i = 0; i < len; ++i) {
      assert(inversePerm[i] >= 0 && inversePerm[i] < len);
      dst[i] = src[inversePerm[i]];
    }
  }
  else {
    CopyVector(dst, src, len);
  }
}

void reorderVectorOutOfPlaceWithInversePerm(double *dst, const double *src, const int *inversePerm, int len)
{
  return reorderVectorOutOfPlaceWithInversePerm_(dst, src, inversePerm, len);
}

void reorderVectorOutOfPlaceWithInversePerm(int *dst, const int *src, const int *inversePerm, int len)
{
  return reorderVectorOutOfPlaceWithInversePerm_(dst, src, inversePerm, len);
}

double *getReorderVector(const double *v, const int *perm, int len)
{
  double *ret = MALLOC(double, len);

  reorderVectorOutOfPlace(ret, v, perm, len);

  return ret;
}

double *getReorderVectorWithInversePerm(const double *v, const int *perm, int len)
{
  double *ret = MALLOC(double, len);

  reorderVectorOutOfPlaceWithInversePerm(ret, v, perm, len);

  return ret;
}

void reorderVector(double *v, double *tmp, const int *perm, int len)
{
  if (!perm) return;

  reorderVectorOutOfPlace(tmp, v, perm, len);
  CopyVector(v, tmp, len);
}

void reorderVectorWithInversePerm(double *v, double *tmp, const int *inversePerm, int len)
{
  if (!inversePerm) return;

  reorderVectorOutOfPlaceWithInversePerm(tmp, v, inversePerm, len);
  CopyVector(v, tmp, len);
}

void reorderVector(double *v, const int *perm, int len)
{
  double *tmp = MALLOC(double, len);
  reorderVector(v, tmp, perm, len);
  FREE(tmp);
}

void reorderVectorWithInversePerm(double *v, const int *perm, int len)
{
  double *tmp = MALLOC(double, len);
  reorderVectorWithInversePerm(v, tmp, perm, len);
  FREE(tmp);
}

} // namespace SpMP
<|endoftext|>


<commit_before>#ifndef __PK_HPP__
#define __PK_HPP__

#include <utility>
#include <vector>
#include <queue>
#include <iostream>
#include <fstream>
#include <unordered_set>

#include "model.hpp"

class Evaluator {

  Evaluator();
  virtual void evaluate(const Model&);

};

class EvaluatorBinary : public Evaluator {

  // please add your structure to store the datasets

  public:
    void load_files();
}

class EvaluatorRating : public Evaluator {

  RatingMatrix test;

  public:
    void load_files();
}

void EvaluateRating::evaluate(const Model& model) {

}

struct pkcomp {
	bool operator() (std::pair<int, double> i, std::pair<int, double> j) {
		return i.second > j.second;
	}
};

void EvaluateBinary::load_files (char* train_repo, char* test_repo, std::vector<int>& k) {

}

void EvaluateBinary::evaluate (const Model& model) {
	std::vector<std::unordered_set<int> > train, test;
	train.resize(model.n_users);
	test.resize(model.n_users);

	std::ifstream tr(train_repo);
	if (tr) {
		int uid, iid;
		while (tr >> uid >> iid) {
			train[uid - 1].insert(iid - 1);
		}
	} else {
		printf ("Error in opening the training repository!\n");
		exit(EXIT_FAILURE);
	}
	tr.close();

	std::ifstream te(test_repo);
	if (te) {
		int uid, iid;
		while (te >> uid >> iid) {
			test[uid - 1].insert(iid - 1);
		}
	} else {
		printf ("Error in opening the testing repository!\n");
		exit(EXIT_FAILURE);
	}
	te.close();

	int maxK = k[k.size() - 1];
	std::vector<double> ret(k.size(), 0);
	std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double> >, pkcomp> pq;

	for (int i = 0; i < model.n_users; ++i) {
		for (int j = 0; j < model.n_items; ++j) {
			if (train[i].find(j) == train[i].end() ) {
				continue;
			}

			double score = 0;
			double *user_vec = &model.U[i * model.rank];
			double *item_vec = &model.V[j * model.rank];
			for (int l = 0; l < model.rank; ++l) {
				score += user_vec[l] * item_vec[l];
			}

			if (pq.size() < maxK) {
				pq.push(std::pair<int, double>(j, score) );
			} else if (pq.top().second < score) {
				pq.push(std::pair<int, double>(j, score) );
				pq.pop();
			}
		}

		int ps = pq.size();
		while (ps) {
			int item = pq.top().first;
			for (int j = k.size() - 1; j >= 0; --j) {
				if (ps > k[j]) break;
				if (test[i].find(item) != test[i].end() ) ++ret[j];
			}
			pq.pop();
			--ps;
		}
	}

	for (int i = 0; i < k.size(); ++i) {
		ret[i] = ret[i] / model.n_users / k[i];
	}
	return ret;
}

#endif
<commit_msg>revised compute precision<commit_after>#ifndef __PK_HPP__
#define __PK_HPP__

#include <utility>
#include <vector>
#include <queue>
#include <iostream>
#include <fstream>
#include <unordered_set>

#include "model.hpp"

class Evaluator {

  Evaluator();
  virtual void evaluate(const Model&);

};

class EvaluatorBinary : public Evaluator {
  std::vector<std::unordered_set<int> > train, test;
  std::vector<int> k;
  // please add your structure to store the datasets

  public:
    void load_files(char*, char*, std::vector<int>&);
}

class EvaluatorRating : public Evaluator {

  RatingMatrix test;

  public:
    void load_files();
}

void EvaluateRating::evaluate(const Model& model) {

}

struct pkcomp {
	bool operator() (std::pair<int, double> i, std::pair<int, double> j) {
		return i.second > j.second;
	}
};

void EvaluateBinary::load_files (char* train_repo, char* test_repo, std::vector<int>& ik) {
	std::ifstream tr(train_repo);
	if (tr) {
		int uid, iid;
		while (tr >> uid >> iid) {
			train[uid - 1].insert(iid - 1);
		}
	} else {
		printf ("Error in opening the training repository!\n");
		exit(EXIT_FAILURE);
	}
	tr.close();

	std::ifstream te(test_repo);
	if (te) {
		int uid, iid;
		while (te >> uid >> iid) {
			test[uid - 1].insert(iid - 1);
		}
	} else {
		printf ("Error in opening the testing repository!\n");
		exit(EXIT_FAILURE);
	}
	te.close();

	k = ik;
}

void EvaluateBinary::evaluate (const Model& model) {
	train.resize(model.n_users);
	test.resize(model.n_users);

	int maxK = k[k.size() - 1];
	std::vector<double> ret(k.size(), 0);
	std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double> >, pkcomp> pq;

	for (int i = 0; i < model.n_users; ++i) {
		for (int j = 0; j < model.n_items; ++j) {
			if (train[i].find(j) == train[i].end() ) {
				continue;
			}

			double score = 0;
			double *user_vec = &model.U[i * model.rank];
			double *item_vec = &model.V[j * model.rank];
			for (int l = 0; l < model.rank; ++l) {
				score += user_vec[l] * item_vec[l];
			}

			if (pq.size() < maxK) {
				pq.push(std::pair<int, double>(j, score) );
			} else if (pq.top().second < score) {
				pq.push(std::pair<int, double>(j, score) );
				pq.pop();
			}
		}

		int ps = pq.size();
		while (ps) {
			int item = pq.top().first;
			for (int j = k.size() - 1; j >= 0; --j) {
				if (ps > k[j]) break;
				if (test[i].find(item) != test[i].end() ) ++ret[j];
			}
			pq.pop();
			--ps;
		}
	}

	for (int i = 0; i < k.size(); ++i) {
		ret[i] = ret[i] / model.n_users / k[i];
	}

	printf("compute precision at k\n");
	for (int i = 0; i < k.size(); ++i) {
		printf("k %d, precision %f\n", k[i], ret[i]);
	}
}

#endif
<|endoftext|>


<commit_before>#include <random>

#include <celero/Celero.h>

///
/// This demo was created to understand the cost with various falvors of "setters" where
/// a function in a class or struct is provided solely to set the value of an internal member.
/// There was some guidance being provided on the internet that if you intend to simply copy
/// the value passed into the function, to incur the cost of the copy when passing the argument.
/// Other guidance suggested to always pass non-pod types in by const ref.  When in doubt, measure!
///
/// http://stackoverflow.com/questions/18673658/should-i-always-move-on-sink-constructor-or-setter-arguments
///

///
/// This is the main(int argc, char** argv) for the entire celero program.
/// You can write your own, or use this macro to insert the standard one into the project.
///
CELERO_MAIN;

struct Foo
{
	Foo() :
		nonPodType()
	{
	}

	void setNonPODTypeByValue(std::string x)
	{
		this->nonPodType = x;
	}

	void setNonPODTypeByValueWithMove(std::string x)
	{
		this->nonPodType = std::move(x);
	}

	void setNonPODTypeByConstRef(const std::string& x)
	{
		this->nonPodType = x;
	}

	void setNonPODTypeByConstRRef(const std::string&& x)
	{
		this->nonPodType = x;
	}

	void setNonPODTypeByConstRRefWithMove(const std::string&& x)
	{
		this->nonPodType = std::move(x);
	}

	void setPODTypeByValue(uint64_t x)
	{
		this->podType = x;
	}

	void setPODTypeByValueWithMove(uint64_t x)
	{
		this->podType = std::move(x);
	}

	void setPODTypeByConstRef(const uint64_t& x)
	{
		this->podType = x;
	}

	void setPODTypeByConstRRef(const uint64_t&& x)
	{
		this->podType = x;
	}

	void setPODTypeByConstRRefWithMove(const uint64_t&& x)
	{
		this->podType = std::move(x);
	}

	std::string nonPodType;
	uint64_t podType;
};

#define MY_NUMBER_OF_CALLS_PER_MEASUREMENT 3000000
#define MY_NUMBER_OF_SAMPLES 100

BASELINE(NonPODParamPassing, Baseline, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	// While we are not measuring the time to construct a "Foo" or create "bar", since
	// we do this in each of the tests, the time is exactly the same and does not
	// change the baseline measurement.  (The only difference in each of these cases
	// is the part we wish to measure.)

	Foo f;
	auto bar = std::string("bar");
	f.nonPodType = bar;
}

BENCHMARK(NonPODParamPassing, TypeMoveCopy, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.nonPodType = std::move(bar);
}

BENCHMARK(NonPODParamPassing, TypeByValue, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByValue(bar);
}

BENCHMARK(NonPODParamPassing, TypeByMovedValue, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByValue(std::move(bar));
}

BENCHMARK(NonPODParamPassing, TypeByValueWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByValue(bar);
}

BENCHMARK(NonPODParamPassing, TypeByMoveValueWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByValue(std::move(bar));
}

BENCHMARK(NonPODParamPassing, TypeByConstRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByConstRef(bar);
}

BENCHMARK(NonPODParamPassing, TypeByConstRRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByConstRef(bar);
}

BENCHMARK(NonPODParamPassing, TypeByConstRRefWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByConstRef(bar);
}

BENCHMARK(NonPODParamPassing, TypeByMoveConstRRefWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByConstRef(std::move(bar));
}

// ---------------------------------------------------------------------------------------
// Repeat some of the tests above, but use the varible after the use in the "set" function
// ---------------------------------------------------------------------------------------

BASELINE(NonPODParamPassingUseAfter, Baseline, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	// While we are not measuring the time to construct a "Foo" or create "bar", since
	// we do this in each of the tests, the time is exactly the same and does not
	// change the baseline measurement.  (The only difference in each of these cases
	// is the part we wish to measure.)

	Foo f;
	auto bar = std::string("bar");
	f.nonPodType = bar;

	bar += "food";
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(NonPODParamPassingUseAfter, TypeByValue, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByValue(bar);

	bar += "food";
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(NonPODParamPassingUseAfter, TypeByValueWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByValue(bar);

	bar += "food";
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(NonPODParamPassingUseAfter, TypeByConstRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByConstRef(bar);

	bar += "food";
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(NonPODParamPassingUseAfter, TypeByConstRRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByConstRef(bar);

	bar += "food";
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(NonPODParamPassingUseAfter, TypeByConstRRefWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByConstRef(bar);

	bar += "food";
	celero::DoNotOptimizeAway(&bar);
}

// --------------------------------------------------
// Now repeat all of the tests above with a POD type.
// --------------------------------------------------

BASELINE(PODParamPassing, Baseline, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	// While we are not measuring the time to construct a "Foo" or create "bar", since
	// we do this in each of the tests, the time is exactly the same and does not
	// change the baseline measurement.  (The only difference in each of these cases
	// is the part we wish to measure.)

	Foo f;
	auto bar = uint64_t(2716057);
	f.podType = bar;
}

BENCHMARK(PODParamPassing, TypeMoveCopy, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.podType = std::move(bar);
}

BENCHMARK(PODParamPassing, TypeByValue, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByValue(bar);
}

BENCHMARK(PODParamPassing, TypeByMovedValue, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByValue(std::move(bar));
}

BENCHMARK(PODParamPassing, TypeByValueWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByValue(bar);
}

BENCHMARK(PODParamPassing, TypeByMoveValueWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByValue(std::move(bar));
}

BENCHMARK(PODParamPassing, TypeByConstRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByConstRef(bar);
}

BENCHMARK(PODParamPassing, TypeByConstRRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByConstRef(bar);
}

BENCHMARK(PODParamPassing, TypeByConstRRefWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByConstRef(bar);
}

BENCHMARK(PODParamPassing, TypeByMoveConstRRefWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByConstRef(std::move(bar));
}

// ---------------------------------------------------------------------------------------
// Repeat some of the tests above, but use the varible after the use in the "set" function
// ---------------------------------------------------------------------------------------

BASELINE(PODParamPassingUseAfter, Baseline, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	// While we are not measuring the time to construct a "Foo" or create "bar", since
	// we do this in each of the tests, the time is exactly the same and does not
	// change the baseline measurement.  (The only difference in each of these cases
	// is the part we wish to measure.)

	Foo f;
	auto bar = uint64_t(2716057);
	f.podType = bar;

	bar += uint64_t(3370318);
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(PODParamPassingUseAfter, TypeByValue, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByValue(bar);

	bar += uint64_t(3370318);
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(PODParamPassingUseAfter, TypeByValueWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByValue(bar);

	bar += uint64_t(3370318);
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(PODParamPassingUseAfter, TypeByConstRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByConstRef(bar);

	bar += uint64_t(3370318);
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(PODParamPassingUseAfter, TypeByConstRRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByConstRef(bar);

	bar += uint64_t(3370318);
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(PODParamPassingUseAfter, TypeByConstRRefWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByConstRef(bar);

	bar += uint64_t(3370318);
	celero::DoNotOptimizeAway(&bar);
}
<commit_msg>Fixed typos in parameter passing test case.<commit_after>#include <random>

#include <celero/Celero.h>

///
/// This demo was created to understand the cost with various falvors of "setters" where
/// a function in a class or struct is provided solely to set the value of an internal member.
/// There was some guidance being provided on the internet that if you intend to simply copy
/// the value passed into the function, to incur the cost of the copy when passing the argument.
/// Other guidance suggested to always pass non-pod types in by const ref.  When in doubt, measure!
///
/// http://stackoverflow.com/questions/18673658/should-i-always-move-on-sink-constructor-or-setter-arguments
///

///
/// This is the main(int argc, char** argv) for the entire celero program.
/// You can write your own, or use this macro to insert the standard one into the project.
///
CELERO_MAIN;

struct Foo
{
	Foo() :
		nonPodType()
	{
	}

	void setNonPODTypeByValue(std::string x)
	{
		this->nonPodType = x;
	}

	void setNonPODTypeByValueWithMove(std::string x)
	{
		this->nonPodType = std::move(x);
	}

	void setNonPODTypeByConstRef(const std::string& x)
	{
		this->nonPodType = x;
	}

	void setNonPODTypeByConstRefWithMove(const std::string& x)
	{
		this->nonPodType = std::move(x);
	}

	void setNonPODTypeByConstRRef(const std::string&& x)
	{
		this->nonPodType = x;
	}

	void setNonPODTypeByConstRRefWithMove(const std::string&& x)
	{
		this->nonPodType = std::move(x);
	}

	void setPODTypeByValue(uint64_t x)
	{
		this->podType = x;
	}

	void setPODTypeByValueWithMove(uint64_t x)
	{
		this->podType = std::move(x);
	}

	void setPODTypeByConstRef(const uint64_t& x)
	{
		this->podType = x;
	}

	void setPODTypeByConstRefWithMove(const uint64_t& x)
	{
		this->podType = std::move(x);
	}

	void setPODTypeByConstRRef(const uint64_t&& x)
	{
		this->podType = x;
	}

	void setPODTypeByConstRRefWithMove(const uint64_t&& x)
	{
		this->podType = std::move(x);
	}

	std::string nonPodType;
	uint64_t podType;
};

#define MY_NUMBER_OF_CALLS_PER_MEASUREMENT 3000000
#define MY_NUMBER_OF_SAMPLES 100

BASELINE(NonPODParamPassing, Baseline, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	// While we are not measuring the time to construct a "Foo" or create "bar", since
	// we do this in each of the tests, the time is exactly the same and does not
	// change the baseline measurement.  (The only difference in each of these cases
	// is the part we wish to measure.)

	Foo f;
	auto bar = std::string("bar");
	f.nonPodType = bar;
}

BENCHMARK(NonPODParamPassing, TypeMoveCopy, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.nonPodType = std::move(bar);
}

BENCHMARK(NonPODParamPassing, TypeByValue, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByValue(bar);
}

BENCHMARK(NonPODParamPassing, TypeByMovedValue, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByValue(std::move(bar));
}

BENCHMARK(NonPODParamPassing, TypeByValueWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByValueWithMove(bar);
}

BENCHMARK(NonPODParamPassing, TypeByMoveValueWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByValueWithMove(std::move(bar));
}

BENCHMARK(NonPODParamPassing, TypeByConstRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByConstRef(bar);
}

BENCHMARK(NonPODParamPassing, TypeByConstRRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	f.setNonPODTypeByConstRRef(std::string("bar"));
}

BENCHMARK(NonPODParamPassing, TypeByConstRRefWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	f.setNonPODTypeByConstRRefWithMove(std::string("bar"));
}

BENCHMARK(NonPODParamPassing, TypeByMoveConstRRefWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	f.setNonPODTypeByConstRRefWithMove(std::move(std::string("bar")));
}

// ---------------------------------------------------------------------------------------
// Repeat some of the tests above, but use the varible after the use in the "set" function
// ---------------------------------------------------------------------------------------

BASELINE(NonPODParamPassingUseAfter, Baseline, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	// While we are not measuring the time to construct a "Foo" or create "bar", since
	// we do this in each of the tests, the time is exactly the same and does not
	// change the baseline measurement.  (The only difference in each of these cases
	// is the part we wish to measure.)

	Foo f;
	auto bar = std::string("bar");
	f.nonPodType = bar;

	bar += "food";
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(NonPODParamPassingUseAfter, TypeByValue, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByValue(bar);

	bar += "food";
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(NonPODParamPassingUseAfter, TypeByValueWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByValueWithMove(bar);

	bar += "food";
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(NonPODParamPassingUseAfter, TypeByConstRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByConstRef(bar);

	bar += "food";
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(NonPODParamPassingUseAfter, TypeByConstRefWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = std::string("bar");
	f.setNonPODTypeByConstRefWithMove(bar);

	bar += "food";
	celero::DoNotOptimizeAway(&bar);
}

// --------------------------------------------------
// Now repeat all of the tests above with a POD type.
// --------------------------------------------------

BASELINE(PODParamPassing, Baseline, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	// While we are not measuring the time to construct a "Foo" or create "bar", since
	// we do this in each of the tests, the time is exactly the same and does not
	// change the baseline measurement.  (The only difference in each of these cases
	// is the part we wish to measure.)

	Foo f;
	auto bar = uint64_t(2716057);
	f.podType = bar;
}

BENCHMARK(PODParamPassing, TypeMoveCopy, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.podType = std::move(bar);
}

BENCHMARK(PODParamPassing, TypeByValue, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByValue(bar);
}

BENCHMARK(PODParamPassing, TypeByMovedValue, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByValue(std::move(bar));
}

BENCHMARK(PODParamPassing, TypeByValueWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByValueWithMove(bar);
}

BENCHMARK(PODParamPassing, TypeByMoveValueWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByValueWithMove(std::move(bar));
}

BENCHMARK(PODParamPassing, TypeByConstRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByConstRef(bar);
}

BENCHMARK(PODParamPassing, TypeByConstRRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	f.setPODTypeByConstRRef(uint64_t(2716057));
}

BENCHMARK(PODParamPassing, TypeByMoveConstRRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	f.setPODTypeByConstRRef(std::move(uint64_t(2716057)));
}

BENCHMARK(PODParamPassing, TypeByConstRRefWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	f.setPODTypeByConstRRefWithMove(uint64_t(2716057));
}

BENCHMARK(PODParamPassing, TypeByMoveConstRRefWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	f.setPODTypeByConstRRefWithMove(std::move(uint64_t(2716057)));
}

// ---------------------------------------------------------------------------------------
// Repeat some of the tests above, but use the varible after the use in the "set" function
// ---------------------------------------------------------------------------------------

BASELINE(PODParamPassingUseAfter, Baseline, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	// While we are not measuring the time to construct a "Foo" or create "bar", since
	// we do this in each of the tests, the time is exactly the same and does not
	// change the baseline measurement.  (The only difference in each of these cases
	// is the part we wish to measure.)

	Foo f;
	auto bar = uint64_t(2716057);
	f.podType = bar;

	bar += uint64_t(3370318);
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(PODParamPassingUseAfter, TypeByValue, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByValue(bar);

	bar += uint64_t(3370318);
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(PODParamPassingUseAfter, TypeByValueWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByValueWithMove(bar);

	bar += uint64_t(3370318);
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(PODParamPassingUseAfter, TypeByMoveValueWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByValueWithMove(std::move(bar));

	bar += uint64_t(3370318);
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(PODParamPassingUseAfter, TypeByConstRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByConstRef(bar);

	bar += uint64_t(3370318);
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(PODParamPassingUseAfter, TypeByMoveConstRef, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByConstRef(std::move(bar));

	bar += uint64_t(3370318);
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(PODParamPassingUseAfter, TypeByConstRefWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByConstRefWithMove(bar);

	bar += uint64_t(3370318);
	celero::DoNotOptimizeAway(&bar);
}

BENCHMARK(PODParamPassingUseAfter, TypeByMoveConstRefWithMove, MY_NUMBER_OF_SAMPLES, MY_NUMBER_OF_CALLS_PER_MEASUREMENT)
{
	Foo f;
	auto bar = uint64_t(2716057);
	f.setPODTypeByConstRefWithMove(std::move(bar));

	bar += uint64_t(3370318);
	celero::DoNotOptimizeAway(&bar);
}
<|endoftext|>


<commit_before>/*------------------------------------------------------------------------------

    Copyright (c) 2004 Media Development Loan Fund

    This file is part of the LiveSupport project.
    http://livesupport.campware.org/
    To report bugs, send an e-mail to bugs@campware.org

    LiveSupport 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 2 of the License, or
    (at your option) any later version.

    LiveSupport 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 LiveSupport; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Author   : $Author: maroy $
    Version  : $Revision: 1.1 $
    Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/schedulerClient/src/SchedulerClientFactory.cxx,v $

------------------------------------------------------------------------------*/

/* ============================================================ include files */

#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif

#include "LiveSupport/SchedulerClient/SchedulerClientFactory.h"
#include "SchedulerDaemonXmlRpcClient.h"

using namespace LiveSupport::Core;
using namespace LiveSupport::SchedulerClient;

/* ===================================================  local data structures */

/* ================================================  local constants & macros */

/*------------------------------------------------------------------------------
 *  The name of the config element for this class
 *----------------------------------------------------------------------------*/
const std::string SchedulerClientFactory::configElementNameStr =
                                                    "schedulerClientFactory";

/*------------------------------------------------------------------------------
 *  The singleton instance of SchedulerClientFactory
 *----------------------------------------------------------------------------*/
Ptr<SchedulerClientFactory>::Ref SchedulerClientFactory::singleton;

/* ===============================================  local function prototypes */

/* =============================================================  module code */

/*------------------------------------------------------------------------------
 *  Return the singleton instance to SchedulerClientFactory
 *----------------------------------------------------------------------------*/
Ptr<SchedulerClientFactory>::Ref
SchedulerClientFactory :: getInstance(void)                   throw ()
{
    if (!singleton.get()) {
        singleton.reset(new SchedulerClientFactory());
    }

    return singleton;
}

/*------------------------------------------------------------------------------
 *  Configure the test authentication client.
 *----------------------------------------------------------------------------*/
void
SchedulerClientFactory :: configure(const xmlpp::Element & element)
                                                throw (std::invalid_argument,
                                                       std::logic_error)
{
    if (element.get_name() != configElementNameStr) {
        std::string eMsg = "Bad configuration element ";
        eMsg += element.get_name();
        throw std::invalid_argument(eMsg);
    }

    schedulerClient.reset();

    // try to look for a SchedulerDaemonXmlRpcClient configuration element
    xmlpp::Node::NodeList   nodes =
        element.get_children(
                        SchedulerDaemonXmlRpcClient::getConfigElementName());
    if (nodes.size() >= 1) {
        const xmlpp::Element  * configElement =
                         dynamic_cast<const xmlpp::Element*> (*(nodes.begin()));

        Ptr<SchedulerDaemonXmlRpcClient>::Ref   client;
        client.reset(new SchedulerDaemonXmlRpcClient());
        client->configure(*configElement);

        schedulerClient = client;
        return;
    }

    throw std::invalid_argument("no authentication client configuration found");
}

<commit_msg>fixed small typo<commit_after>/*------------------------------------------------------------------------------

    Copyright (c) 2004 Media Development Loan Fund

    This file is part of the LiveSupport project.
    http://livesupport.campware.org/
    To report bugs, send an e-mail to bugs@campware.org

    LiveSupport 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 2 of the License, or
    (at your option) any later version.

    LiveSupport 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 LiveSupport; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Author   : $Author: maroy $
    Version  : $Revision: 1.2 $
    Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/schedulerClient/src/SchedulerClientFactory.cxx,v $

------------------------------------------------------------------------------*/

/* ============================================================ include files */

#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif

#include "LiveSupport/SchedulerClient/SchedulerClientFactory.h"
#include "SchedulerDaemonXmlRpcClient.h"

using namespace LiveSupport::Core;
using namespace LiveSupport::SchedulerClient;

/* ===================================================  local data structures */

/* ================================================  local constants & macros */

/*------------------------------------------------------------------------------
 *  The name of the config element for this class
 *----------------------------------------------------------------------------*/
const std::string SchedulerClientFactory::configElementNameStr =
                                                    "schedulerClientFactory";

/*------------------------------------------------------------------------------
 *  The singleton instance of SchedulerClientFactory
 *----------------------------------------------------------------------------*/
Ptr<SchedulerClientFactory>::Ref SchedulerClientFactory::singleton;

/* ===============================================  local function prototypes */

/* =============================================================  module code */

/*------------------------------------------------------------------------------
 *  Return the singleton instance to SchedulerClientFactory
 *----------------------------------------------------------------------------*/
Ptr<SchedulerClientFactory>::Ref
SchedulerClientFactory :: getInstance(void)                   throw ()
{
    if (!singleton.get()) {
        singleton.reset(new SchedulerClientFactory());
    }

    return singleton;
}

/*------------------------------------------------------------------------------
 *  Configure the test authentication client.
 *----------------------------------------------------------------------------*/
void
SchedulerClientFactory :: configure(const xmlpp::Element & element)
                                                throw (std::invalid_argument,
                                                       std::logic_error)
{
    if (element.get_name() != configElementNameStr) {
        std::string eMsg = "Bad configuration element ";
        eMsg += element.get_name();
        throw std::invalid_argument(eMsg);
    }

    schedulerClient.reset();

    // try to look for a SchedulerDaemonXmlRpcClient configuration element
    xmlpp::Node::NodeList   nodes =
        element.get_children(
                        SchedulerDaemonXmlRpcClient::getConfigElementName());
    if (nodes.size() >= 1) {
        const xmlpp::Element  * configElement =
                         dynamic_cast<const xmlpp::Element*> (*(nodes.begin()));

        Ptr<SchedulerDaemonXmlRpcClient>::Ref   client;
        client.reset(new SchedulerDaemonXmlRpcClient());
        client->configure(*configElement);

        schedulerClient = client;
        return;
    }

    throw std::invalid_argument("no scheduler client configuration found");
}

<|endoftext|>


<commit_before>// ========================================================================== //
// This file is part of Sara, a basic set of libraries in C++ for computer
// vision.
//
// Copyright (C) 2019 David Ok <david.ok8@gmail.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/.
// ========================================================================== //

#pragma once

#include <DO/Sara/Core/Tensor.hpp>
#include <DO/Sara/MultiViewGeometry/FeatureGraph.hpp>

#include <vector>

namespace DO::Sara {

  /*!
   *  @ingroup MultiViewGeometry
   *  @{
   */

  //! @brief Camera model view class.
  template <typename T>
  struct CameraModelView
  {
    auto angle_axis() const -> const T*
    {
      return parameters;
    }
    auto t() const -> const T*
    {
      return parameters + 3;
    }
    auto fx() const -> const T&
    {
      return parameters[6];
    }
    auto fy() const -> const T&
    {
      return parameters[7];
    }
    auto x0() const -> const T&
    {
      return parameters[8];
    }
    auto y0() const -> const T&
    {
      return parameters[9];
    }
    auto l1() const -> const T&
    {
      return parameters[10];
    }
    auto l2() const -> const T&
    {
      return parameters[11];
    }
    static auto dof()
    {
      return 12;
    };

    const T* parameters;
  };

  //! @brief Observation reference class.
  struct ObservationRef
  {
    FeatureGID gid;
    int camera_id;
    int point_id;
  };

  //! @brief Bundle adjustment class.
  struct BundleAdjustmentProblem
  {
    //! @brief observation = 2D points in images.
    Tensor_<double, 2> observations;
    //! @brief the corresponding 3D point index for observation 'o'
    std::vector<int> point_indices;
    //! @brief the corresponding 3D camera index for observation 'o'
    std::vector<int> camera_indices;

    //! @{
    //! @brief camera parameters + 3D point coordinates.
    int num_cameras;
    int num_points;
    int camera_dof;
    std::vector<double> parameters;
    TensorView_<double, 2> points_abs_coords_3d;
    TensorView_<double, 2> camera_parameters;
    //! @}

    auto resize(int num_observations,  //
                int num_points_, int num_cameras_, int camera_dof_)
    {
      SARA_DEBUG << "Resizing data..." << std::endl;
      observations = Tensor_<double, 2>{{num_observations, 2}};
      point_indices = std::vector<int>(num_observations);
      camera_indices = std::vector<int>(num_observations);

      num_points = num_points_;
      num_cameras = num_cameras_;
      camera_dof = camera_dof_;
      const auto num_parameters = num_cameras * camera_dof + num_points * 3;
      parameters = std::vector<double>(num_parameters);

      auto points_abs_coords_3d_new = TensorView_<double, 2>{
          parameters.data() + camera_dof * num_cameras, {num_points, 3}};
      auto camera_parameters_new =
          TensorView_<double, 2>{parameters.data(), {num_cameras, camera_dof}};

      points_abs_coords_3d.swap(points_abs_coords_3d_new);
      camera_parameters.swap(camera_parameters_new);
    }

    auto populate_observations(
        const std::vector<ObservationRef>& obs_refs,
        const std::vector<KeypointList<OERegion, float>>& keypoints) -> void
    {
      SARA_DEBUG << "Populating observations..." << std::endl;
      const auto num_observations = observations.size(0);
      for (int i = 0; i < num_observations; ++i)
      {
        const auto& ref = obs_refs[i];

        // Easy things first.
        point_indices[i] = ref.point_id;
        camera_indices[i] = ref.camera_id;

        // Initialize the 2D observations.
        const auto& image_id = ref.gid.image_id;
        const auto& local_id = ref.gid.local_id;
        const double x = features(keypoints[image_id])[local_id].x();
        const double y = features(keypoints[image_id])[local_id].y();
        observations(i, 0) = x;
        observations(i, 1) = y;
      }
    }

    auto populate_3d_points_from_two_view_geometry(
        const std::set<std::set<FeatureGID>>& feature_tracks,
        const std::multimap<FeatureGID, MatchGID>& match_index,
        const TwoViewGeometry& two_view_geometry) -> void
    {
      SARA_DEBUG << "Populating 3D points..." << std::endl;

      auto points_view = points_abs_coords_3d.colmajor_view().matrix();
      for (auto [t, track] = std::make_pair(0, feature_tracks.begin());
           track != feature_tracks.end(); ++t, ++track)
      {
        const auto p = match_index.find(*track->begin())->second.m;
        const auto point_p = two_view_geometry.X.col(p);
        points_view.col(t) = point_p.hnormalized();
#if DEBUG
        SARA_DEBUG << "Point[" << t << "] = "  //
                   << points_view.col(t).transpose() << std::endl;
#endif
      }
    }

    auto populate_camera_parameters(const TwoViewGeometry& two_view_geometry)
        -> void
    {
      SARA_DEBUG << "Populating camera parameters..." << std::endl;

      auto cam_matrix = camera_parameters.matrix();
      // Angle axis vector.
      auto cam_0 = cam_matrix.row(0);
      auto angle_axis_0 = Eigen::AngleAxisd{two_view_geometry.C1.R};
      auto aaxis0 = angle_axis_0.angle() * angle_axis_0.axis();
      cam_0.segment(0, 3) = aaxis0.transpose();
      // translation.
      const auto& t0 = two_view_geometry.C1.t;
      cam_0.segment(3, 3) = t0;
      // Internal parameters.
      SARA_DEBUG << "K1 =\n" << two_view_geometry.C1.K << std::endl;
      cam_0(6) = two_view_geometry.C1.K(0, 0);  // fx
      cam_0(7) = two_view_geometry.C1.K(1, 1);  // fy
      cam_0(8) = two_view_geometry.C1.K(0, 2);  // x0
      cam_0(9) = two_view_geometry.C1.K(1, 2);  // y0
      cam_0(10) = 1.0;                          // l1
      cam_0(11) = 1.0;                          // l2

      // Angle axis vector.
      auto cam_1 = cam_matrix.row(1);
      auto angle_axis_1 = Eigen::AngleAxisd{two_view_geometry.C2.R};
      auto aaxis1 = angle_axis_1.angle() * angle_axis_1.axis();
      cam_1.segment(0, 3) = aaxis1.transpose();
      // translation.
      const auto& t1 = two_view_geometry.C2.t;
      cam_1.segment(3, 3) = t1;
      // Internal parameters.
      SARA_DEBUG << "K2 =\n" << two_view_geometry.C2.K << std::endl;
      cam_1(6) = two_view_geometry.C2.K(0, 0);  // fx
      cam_1(7) = two_view_geometry.C2.K(1, 1);  // fy
      cam_1(8) = two_view_geometry.C2.K(0, 2);  // x0
      cam_1(9) = two_view_geometry.C2.K(1, 2);  // y0
      cam_1(10) = 1.0;                          // l1
      cam_1(11) = 1.0;                          // l2

      SARA_DEBUG << "cam_matrix =\n" << cam_matrix << std::endl;
    }

    auto populate_data_from_two_view_geometry(
        const std::set<std::set<FeatureGID>>& feature_tracks,
        const std::vector<KeypointList<OERegion, float>>& keypoints,
        const std::multimap<FeatureGID, MatchGID>& match_index,
        const TwoViewGeometry& two_view_geometry) -> void
    {
      const auto num_points = static_cast<int>(feature_tracks.size());
      SARA_CHECK(num_points);

      auto num_observations_per_points = std::vector<int>(num_points);
      std::transform(
          std::begin(feature_tracks), std::end(feature_tracks),
          std::begin(num_observations_per_points),
          [](const auto& track) { return static_cast<int>(track.size()); });

      const auto num_observations =
          std::accumulate(std::begin(num_observations_per_points),
                          std::end(num_observations_per_points), 0);
      SARA_CHECK(num_observations);

      // 3. Count the number of cameras, which should be equal to the number of
      //    images.
      auto image_ids = std::set<int>{};
      for (const auto& track : feature_tracks)
        for (const auto& f : track)
          image_ids.insert(f.image_id);
      const auto num_cameras = static_cast<int>(image_ids.size());
      SARA_CHECK(num_cameras);

      const auto camera_dof_ = CameraModelView<double>::dof();
      const auto num_parameters = camera_dof_ * num_cameras + 3 * num_points;
      SARA_CHECK(num_parameters);

      // 4. Transform the data for convenience.
      auto obs_refs = std::vector<ObservationRef>{};
      {
        obs_refs.reserve(num_observations);
        for (auto [point_id, track] = std::make_pair(0, feature_tracks.begin());
             track != feature_tracks.end(); ++point_id, ++track)
        {
          for (const auto& f : *track)
            obs_refs.push_back({f, f.image_id, point_id});
        }
      }

      resize(num_observations, num_points, num_cameras, camera_dof_);
      populate_observations(obs_refs, keypoints);
      populate_3d_points_from_two_view_geometry(feature_tracks, match_index,
                                                two_view_geometry);
      populate_camera_parameters(two_view_geometry);
    }
  };

  //! @}

} /* namespace DO::Sara */
<commit_msg>MAINT: fix documentation.<commit_after>// ========================================================================== //
// This file is part of Sara, a basic set of libraries in C++ for computer
// vision.
//
// Copyright (C) 2019 David Ok <david.ok8@gmail.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/.
// ========================================================================== //

#pragma once

#include <DO/Sara/Core/Tensor.hpp>
#include <DO/Sara/MultiViewGeometry/FeatureGraph.hpp>

#include <vector>

namespace DO::Sara {

  /*!
   *  @addtogroup MultiViewGeometry
   *  @{
   */

  //! @brief Camera model view class.
  template <typename T>
  struct CameraModelView
  {
    auto angle_axis() const -> const T*
    {
      return parameters;
    }
    auto t() const -> const T*
    {
      return parameters + 3;
    }
    auto fx() const -> const T&
    {
      return parameters[6];
    }
    auto fy() const -> const T&
    {
      return parameters[7];
    }
    auto x0() const -> const T&
    {
      return parameters[8];
    }
    auto y0() const -> const T&
    {
      return parameters[9];
    }
    auto l1() const -> const T&
    {
      return parameters[10];
    }
    auto l2() const -> const T&
    {
      return parameters[11];
    }
    static auto dof()
    {
      return 12;
    };

    const T* parameters;
  };

  //! @brief Observation reference class.
  struct ObservationRef
  {
    FeatureGID gid;
    int camera_id;
    int point_id;
  };

  //! @brief Bundle adjustment class.
  struct BundleAdjustmentProblem
  {
    //! @brief observation = 2D points in images.
    Tensor_<double, 2> observations;
    //! @brief the corresponding 3D point index for observation 'o'
    std::vector<int> point_indices;
    //! @brief the corresponding 3D camera index for observation 'o'
    std::vector<int> camera_indices;

    //! @{
    //! @brief camera parameters + 3D point coordinates.
    int num_cameras;
    int num_points;
    int camera_dof;
    std::vector<double> parameters;
    TensorView_<double, 2> points_abs_coords_3d;
    TensorView_<double, 2> camera_parameters;
    //! @}

    auto resize(int num_observations,  //
                int num_points_, int num_cameras_, int camera_dof_)
    {
      SARA_DEBUG << "Resizing data..." << std::endl;
      observations = Tensor_<double, 2>{{num_observations, 2}};
      point_indices = std::vector<int>(num_observations);
      camera_indices = std::vector<int>(num_observations);

      num_points = num_points_;
      num_cameras = num_cameras_;
      camera_dof = camera_dof_;
      const auto num_parameters = num_cameras * camera_dof + num_points * 3;
      parameters = std::vector<double>(num_parameters);

      auto points_abs_coords_3d_new = TensorView_<double, 2>{
          parameters.data() + camera_dof * num_cameras, {num_points, 3}};
      auto camera_parameters_new =
          TensorView_<double, 2>{parameters.data(), {num_cameras, camera_dof}};

      points_abs_coords_3d.swap(points_abs_coords_3d_new);
      camera_parameters.swap(camera_parameters_new);
    }

    auto populate_observations(
        const std::vector<ObservationRef>& obs_refs,
        const std::vector<KeypointList<OERegion, float>>& keypoints) -> void
    {
      SARA_DEBUG << "Populating observations..." << std::endl;
      const auto num_observations = observations.size(0);
      for (int i = 0; i < num_observations; ++i)
      {
        const auto& ref = obs_refs[i];

        // Easy things first.
        point_indices[i] = ref.point_id;
        camera_indices[i] = ref.camera_id;

        // Initialize the 2D observations.
        const auto& image_id = ref.gid.image_id;
        const auto& local_id = ref.gid.local_id;
        const double x = features(keypoints[image_id])[local_id].x();
        const double y = features(keypoints[image_id])[local_id].y();
        observations(i, 0) = x;
        observations(i, 1) = y;
      }
    }

    auto populate_3d_points_from_two_view_geometry(
        const std::set<std::set<FeatureGID>>& feature_tracks,
        const std::multimap<FeatureGID, MatchGID>& match_index,
        const TwoViewGeometry& two_view_geometry) -> void
    {
      SARA_DEBUG << "Populating 3D points..." << std::endl;

      auto points_view = points_abs_coords_3d.colmajor_view().matrix();
      for (auto [t, track] = std::make_pair(0, feature_tracks.begin());
           track != feature_tracks.end(); ++t, ++track)
      {
        const auto p = match_index.find(*track->begin())->second.m;
        const auto point_p = two_view_geometry.X.col(p);
        points_view.col(t) = point_p.hnormalized();
#if DEBUG
        SARA_DEBUG << "Point[" << t << "] = "  //
                   << points_view.col(t).transpose() << std::endl;
#endif
      }
    }

    auto populate_camera_parameters(const TwoViewGeometry& two_view_geometry)
        -> void
    {
      SARA_DEBUG << "Populating camera parameters..." << std::endl;

      auto cam_matrix = camera_parameters.matrix();
      // Angle axis vector.
      auto cam_0 = cam_matrix.row(0);
      auto angle_axis_0 = Eigen::AngleAxisd{two_view_geometry.C1.R};
      auto aaxis0 = angle_axis_0.angle() * angle_axis_0.axis();
      cam_0.segment(0, 3) = aaxis0.transpose();
      // translation.
      const auto& t0 = two_view_geometry.C1.t;
      cam_0.segment(3, 3) = t0;
      // Internal parameters.
      SARA_DEBUG << "K1 =\n" << two_view_geometry.C1.K << std::endl;
      cam_0(6) = two_view_geometry.C1.K(0, 0);  // fx
      cam_0(7) = two_view_geometry.C1.K(1, 1);  // fy
      cam_0(8) = two_view_geometry.C1.K(0, 2);  // x0
      cam_0(9) = two_view_geometry.C1.K(1, 2);  // y0
      cam_0(10) = 1.0;                          // l1
      cam_0(11) = 1.0;                          // l2

      // Angle axis vector.
      auto cam_1 = cam_matrix.row(1);
      auto angle_axis_1 = Eigen::AngleAxisd{two_view_geometry.C2.R};
      auto aaxis1 = angle_axis_1.angle() * angle_axis_1.axis();
      cam_1.segment(0, 3) = aaxis1.transpose();
      // translation.
      const auto& t1 = two_view_geometry.C2.t;
      cam_1.segment(3, 3) = t1;
      // Internal parameters.
      SARA_DEBUG << "K2 =\n" << two_view_geometry.C2.K << std::endl;
      cam_1(6) = two_view_geometry.C2.K(0, 0);  // fx
      cam_1(7) = two_view_geometry.C2.K(1, 1);  // fy
      cam_1(8) = two_view_geometry.C2.K(0, 2);  // x0
      cam_1(9) = two_view_geometry.C2.K(1, 2);  // y0
      cam_1(10) = 1.0;                          // l1
      cam_1(11) = 1.0;                          // l2

      SARA_DEBUG << "cam_matrix =\n" << cam_matrix << std::endl;
    }

    auto populate_data_from_two_view_geometry(
        const std::set<std::set<FeatureGID>>& feature_tracks,
        const std::vector<KeypointList<OERegion, float>>& keypoints,
        const std::multimap<FeatureGID, MatchGID>& match_index,
        const TwoViewGeometry& two_view_geometry) -> void
    {
      const auto num_points = static_cast<int>(feature_tracks.size());
      SARA_CHECK(num_points);

      auto num_observations_per_points = std::vector<int>(num_points);
      std::transform(
          std::begin(feature_tracks), std::end(feature_tracks),
          std::begin(num_observations_per_points),
          [](const auto& track) { return static_cast<int>(track.size()); });

      const auto num_observations =
          std::accumulate(std::begin(num_observations_per_points),
                          std::end(num_observations_per_points), 0);
      SARA_CHECK(num_observations);

      // 3. Count the number of cameras, which should be equal to the number of
      //    images.
      auto image_ids = std::set<int>{};
      for (const auto& track : feature_tracks)
        for (const auto& f : track)
          image_ids.insert(f.image_id);
      const auto num_cameras = static_cast<int>(image_ids.size());
      SARA_CHECK(num_cameras);

      const auto camera_dof_ = CameraModelView<double>::dof();
      const auto num_parameters = camera_dof_ * num_cameras + 3 * num_points;
      SARA_CHECK(num_parameters);

      // 4. Transform the data for convenience.
      auto obs_refs = std::vector<ObservationRef>{};
      {
        obs_refs.reserve(num_observations);
        for (auto [point_id, track] = std::make_pair(0, feature_tracks.begin());
             track != feature_tracks.end(); ++point_id, ++track)
        {
          for (const auto& f : *track)
            obs_refs.push_back({f, f.image_id, point_id});
        }
      }

      resize(num_observations, num_points, num_cameras, camera_dof_);
      populate_observations(obs_refs, keypoints);
      populate_3d_points_from_two_view_geometry(feature_tracks, match_index,
                                                two_view_geometry);
      populate_camera_parameters(two_view_geometry);
    }
  };

  //! @}

} /* namespace DO::Sara */
<|endoftext|>


<commit_before>/*
 * SessionProjectSharing.hpp
 *
 * Copyright (C) 2009-15 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#ifndef SESSION_PROJECTS_SHARING_HPP
#define SESSION_PROJECTS_SHARING_HPP

#define kProjectSharingSessionOption "enable-project-sharing"
#define kProjectEntryExt ".proj"
#define kProjectSharedDir "shared-projects"

#define kProjectEntryDir        "project_dir"
#define kProjectEntryOwner      "project_owner"
#define kProjectEntrySharedWith "shared_with"

namespace rstudio {
namespace session {
namespace projects {

} // namespace projects
} // namesapce session
} // namespace rstudio

#endif // SESSION_PROJECTS_SHARING_HPP
<commit_msg>add project file constant to shared project header<commit_after>/*
 * SessionProjectSharing.hpp
 *
 * Copyright (C) 2009-15 by RStudio, Inc.
 *
 * Unless you have received this program directly from RStudio pursuant
 * to the terms of a commercial license agreement with RStudio, then
 * this program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#ifndef SESSION_PROJECTS_SHARING_HPP
#define SESSION_PROJECTS_SHARING_HPP

#define kProjectSharingSessionOption "enable-project-sharing"
#define kProjectEntryExt ".proj"
#define kProjectSharedDir "shared-projects"

#define kProjectEntryDir        "project_dir"
#define kProjectEntryFile       "project_file"
#define kProjectEntryOwner      "project_owner"
#define kProjectEntrySharedWith "shared_with"

namespace rstudio {
namespace session {
namespace projects {

} // namespace projects
} // namesapce session
} // namespace rstudio

#endif // SESSION_PROJECTS_SHARING_HPP
<|endoftext|>


<commit_before>#include "Parse.hpp"

#include <iostream>
#include <stdexcept>
#include <cctype>

namespace parse
{

namespace tree
{

void Abstraction::applyVisitor(TermVisitor& termVisitor) const
{
    termVisitor.acceptTerm(*this);
}

void Application::applyVisitor(TermVisitor& termVisitor) const
{
    termVisitor.acceptTerm(*this);
}

void Variable::applyVisitor(TermVisitor& termVisitor) const
{
    termVisitor.acceptTerm(*this);
}

} // tree

namespace
{

void skipWhitespace(std::istream& input)
{
    char c = input.peek();

    while (std::isspace(c))
    {
        input.get();
        c = input.peek();
    }
}

std::string parseIdentifier(std::istream& input)
{
    std::string ident;

    skipWhitespace(input);

    while (std::isalnum(input.peek()))
    {
        ident += input.get();
    }

    return ident;
}

std::unique_ptr<tree::Abstraction> parseAbstraction(std::istream& input)
{
    std::unique_ptr<tree::Abstraction> node(new tree::Abstraction);

    if (input.peek() != '^')
    {
        throw std::runtime_error("Parse error");
    }

    input.get();

    std::string argument;

    while ((argument = parseIdentifier(input)).size() > 0)
    {
        node->arguments.push_back(std::move(argument));
    }

    if (node->arguments.size() == 0)
    {
        throw std::runtime_error("Parse error");
    }

    skipWhitespace(input);

    if (input.peek() != '.')
    {
        throw std::runtime_error("Parse error");
    }

    input.get();

    node->body = parseTerm(input);

    return node;
}

} // anonymous

std::unique_ptr<tree::Term> parseTerm(std::istream& input)
{
    std::unique_ptr<tree::Term> node;

    skipWhitespace(input);

    if (input.peek() == '^')
    {
        node = parseAbstraction(input);
    }
    else if (input.peek() == '(')
    {
        node = parseTerm(input);

        skipWhitespace(input);

        if (input.peek() != ')')
        {
            throw std::runtime_error("Parse error");
        }

        input.get();
    }

    skipWhitespace(input);

    if (input.peek() != EOF)
    {
        std::unique_ptr<tree::Term> tempNode = std::move(node);
        std::unique_ptr<tree::Application> appNode = std::unique_ptr<tree::Application>(new tree::Application);
        appNode->terms.push_back(std::move(tempNode));

        do
        {
            appNode->terms.push_back(parseTerm(input));
        } while (input.peek () != EOF);

        node = std::move(appNode);
    }

    return node;
}

} // parse
<commit_msg>Fix infinite recursion<commit_after>#include "Parse.hpp"

#include <iostream>
#include <stdexcept>
#include <cctype>

namespace parse
{

namespace tree
{

void Abstraction::applyVisitor(TermVisitor& termVisitor) const
{
    termVisitor.acceptTerm(*this);
}

void Application::applyVisitor(TermVisitor& termVisitor) const
{
    termVisitor.acceptTerm(*this);
}

void Variable::applyVisitor(TermVisitor& termVisitor) const
{
    termVisitor.acceptTerm(*this);
}

} // tree

namespace
{

void skipWhitespace(std::istream& input)
{
    char c = input.peek();

    while (std::isspace(c))
    {
        input.get();
        c = input.peek();
    }
}

std::string parseIdentifier(std::istream& input)
{
    std::string ident;

    skipWhitespace(input);

    while (std::isalnum(input.peek()))
    {
        ident += input.get();
    }

    return ident;
}

std::unique_ptr<tree::Abstraction> parseAbstraction(std::istream& input)
{
    std::unique_ptr<tree::Abstraction> node(new tree::Abstraction);

    if (input.peek() != '^')
    {
        throw std::runtime_error("Parse error");
    }

    input.get();

    std::string argument;

    while ((argument = parseIdentifier(input)).size() > 0)
    {
        node->arguments.push_back(std::move(argument));
    }

    if (node->arguments.size() == 0)
    {
        throw std::runtime_error("Parse error");
    }

    skipWhitespace(input);

    if (input.peek() != '.')
    {
        throw std::runtime_error("Parse error");
    }

    input.get();

    node->body = parseTerm(input);

    return node;
}

} // anonymous

std::unique_ptr<tree::Term> parseTerm(std::istream& input)
{
    std::unique_ptr<tree::Term> node;

    skipWhitespace(input);

    if (input.peek() == '^')
    {
        node = parseAbstraction(input);
    }
    else if (input.peek() == '(')
    {
        node = parseTerm(input);

        skipWhitespace(input);

        if (input.peek() != ')')
        {
            throw std::runtime_error("Parse error");
        }

        input.get();
    }
    else
    {
        std::string name = parseIdentifier(input);

        if (name.size() == 0)
        {
            throw std::runtime_error("Parse error");
        }

        std::unique_ptr<tree::Variable> var(new tree::Variable);
        var->name = std::move(name);

        node = std::move(var);
    }

    skipWhitespace(input);

    if (input.peek() != EOF)
    {
        std::unique_ptr<tree::Term> tempNode = std::move(node);
        std::unique_ptr<tree::Application> appNode = std::unique_ptr<tree::Application>(new tree::Application);
        appNode->terms.push_back(std::move(tempNode));

        do
        {
            appNode->terms.push_back(parseTerm(input));
        } while (input.peek () != EOF);

        node = std::move(appNode);
    }

    return node;
}

} // parse
<|endoftext|>