<commit_before>#include "orbit_mpi.hh"
#include "pyORBIT_Object.hh"
#
#include "wrap_lspacechargecalc.hh"
#include "wrap_bunch.hh"

#include <iostream>

#include "LSpaceChargeCalc.hh"

using namespace OrbitUtils;

namespace wrap_LSpaceChargeCalc{

#ifdef __cplusplus
extern "C" {
#endif

	//---------------------------------------------------------
	//Python LSpaceChargeCalc class definition
	//---------------------------------------------------------

	//constructor for python class wrapping LSpaceChargeCalc instance
	//It never will be called directly

	static PyObject* LSpaceChargeCalc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
	{
		pyORBIT_Object* self;
		self = (pyORBIT_Object *) type->tp_alloc(type, 0);
		self->cpp_obj = NULL;
		//std::cerr<<"The LSpaceChargeCalc new has been called!"<<std::endl;
		return (PyObject *) self;
	}

  //initializator for python LSpaceChargeCalc class
  //this is implementation of the __init__ method LSpaceChargeCalc(double b_a, double length, int nMacrosMin, int useSpaceCharge, int nBins)
  static int LSpaceChargeCalc_init(pyORBIT_Object *self, PyObject *args, PyObject *kwds){

		pyORBIT_Object* pyLSpaceChargeCalc = (pyORBIT_Object*) self;
		LSpaceChargeCalc* cpp_LSpaceChargeCalc = (LSpaceChargeCalc*) pyLSpaceChargeCalc->cpp_obj;

		double b_a = 1.0;
		double length = 1.0;
		int nMacrosMin;
		int useSpaceCharge;
		int nBins;

		if(!PyArg_ParseTuple(args,"ddiii:arguments",&b_a,&length,&nMacrosMin,&useSpaceCharge,&nBins)){
			ORBIT_MPI_Finalize("PyLSpaceChargeCalc - LSpaceChargeCalc(b_a, length, nMacrosMin, useSpaceCharge, nBins) - constructor needs parameters.");
		}

		self->cpp_obj = new LSpaceChargeCalc(b_a, length, nMacrosMin, useSpaceCharge, nBins);

		((LSpaceChargeCalc*) self->cpp_obj)->setPyWrapper((PyObject*) self);

		return 0;
	}

	//assignImpedance  A routine to import a python complex tuple and convert to c++ impedance array
	static PyObject* assignImpedance(PyObject *self, PyObject *args){

		cout<<"Getting here \n";
		pyORBIT_Object* pyLSpaceChargeCalc = (pyORBIT_Object*) self;
		LSpaceChargeCalc* cpp_LSpaceChargeCalc = (LSpaceChargeCalc*) pyLSpaceChargeCalc->cpp_obj;
		PyObject* py_cmplx_arr;

		if(!PyArg_ParseTuple(args,"O:get_complex_arr",&py_cmplx_arr)){
			ORBIT_MPI_Finalize("ERROR! You have to specify a parameter - array of complex numbers!");
		}
		if(PySequence_Check(py_cmplx_arr) != 1){
			ORBIT_MPI_Finalize("ERROR! You have to specify a parameter - array of complex numbers!");
		}
		int size = PySequence_Size(py_cmplx_arr);
		Py_complex cmplx;
		PyObject* py_cmplx;
		double real,imag;
		for(int i = 0; i < size; i++){
			py_cmplx = PySequence_Fast_GET_ITEM(py_cmplx_arr, i);
			if(!PyComplex_Check(py_cmplx)){
				ORBIT_MPI_Finalize("ERROR! No complex numbers!");
			}
			cmplx = PyComplex_AsCComplex(py_cmplx);
			real = cmplx.real;
			imag = cmplx.imag;
			cpp_LSpaceChargeCalc->assignImpedanceValue(i,real,imag);
		}

		Py_INCREF(Py_None);
		return Py_None;

	}

	//assignImpedanceValue(int, real, real).  Wraps the LongSpaceChargeCalc routine assigning an impedance mode
	static PyObject* LSpaceChargeCalc_assignImpedanceValue(PyObject *self, PyObject *args){

		pyORBIT_Object* pyLSpaceChargeCalc = (pyORBIT_Object*) self;
		LSpaceChargeCalc* cpp_LSpaceChargeCalc = (LSpaceChargeCalc*) pyLSpaceChargeCalc->cpp_obj;

		int i = 0;
		double real= 0.0;
		double imag = 0.0;

		if(!PyArg_ParseTuple(args,"idd:arguments",&i,&real,&imag)){
			ORBIT_MPI_Finalize("PyLSpaceChargeCalc - assignImpedanceValue(i, real,imag) - constructor needs parameters.");
		}
		cpp_LSpaceChargeCalc->assignImpedanceValue(i,real,imag);

		Py_INCREF(Py_None);
		return Py_None;
	}

//trackBunchBunch(Bunch* bunch)
  static PyObject* LSpaceChargeCalc_trackBunch(PyObject *self, PyObject *args){
		int nVars = PyTuple_Size(args);
		pyORBIT_Object* pyLSpaceChargeCalc = (pyORBIT_Object*) self;
		LSpaceChargeCalc* cpp_LSpaceChargeCalc = (LSpaceChargeCalc*) pyLSpaceChargeCalc->cpp_obj;
		PyObject* pyBunch;

		if(!PyArg_ParseTuple(args,"O:trackBunch",&pyBunch)){
			ORBIT_MPI_Finalize("PyLSpaceChargeCalc.trackBunch(pyBunch) - method needs parameters.");
		}

		PyObject* pyORBIT_Bunch_Type = wrap_orbit_bunch::getBunchType("Bunch");
		if(!PyObject_IsInstance(pyBunch,pyORBIT_Bunch_Type)){
			ORBIT_MPI_Finalize("PyLSpaceChargeCalc.trackBunch(pyBunch) - pyBunch is not Bunch.");
		}
		Bunch* cpp_bunch = (Bunch*) ((pyORBIT_Object*)pyBunch)->cpp_obj;
		cpp_LSpaceChargeCalc->trackBunch(cpp_bunch);

		Py_INCREF(Py_None);
		return Py_None;
  }

  //-----------------------------------------------------
  //destructor for python LSpaceChargeCalc class (__del__ method).
  //-----------------------------------------------------
  static void LSpaceChargeCalc_del(pyORBIT_Object* self){
		LSpaceChargeCalc* cpp_LSpaceChargeCalc = (LSpaceChargeCalc*) self->cpp_obj;
		if(cpp_LSpaceChargeCalc != NULL){
			delete cpp_LSpaceChargeCalc;
		}
		self->ob_type->tp_free((PyObject*)self);
  }

  // defenition of the methods of the python LSpaceChargeCalc wrapper class
  // they will be vailable from python level
  static PyMethodDef LSpaceChargeCalcClassMethods[] = {
		{ "trackBunch",  LSpaceChargeCalc_trackBunch, METH_VARARGS,"trackBunch the bunch - trackBunch(pyBunch)"},
		{ "assignImpedanceValue",  LSpaceChargeCalc_assignImpedanceValue, METH_VARARGS,"assigne the impedance for the ith mode - assignImpedanceValue(i,real,imag)"},
		{ "assignImpedance",  assignImpedance, METH_VARARGS,"assigne the impedance for the ith mode - assignImpedance(Z))"},
		{NULL}
  };

  // defenition of the members of the python LSpaceChargeCalc wrapper class
  // they will be vailable from python level
  static PyMemberDef LSpaceChargeCalcClassMembers [] = {
		{NULL}
  };

	//new python LSpaceChargeCalc wrapper type definition
	static PyTypeObject pyORBIT_LSpaceChargeCalc_Type = {
		PyObject_HEAD_INIT(NULL)
		0, /*ob_size*/
		"LSpaceChargeCalc", /*tp_name*/
		sizeof(pyORBIT_Object), /*tp_basicsize*/
		0, /*tp_itemsize*/
		(destructor) LSpaceChargeCalc_del , /*tp_dealloc*/
		0, /*tp_print*/
		0, /*tp_getattr*/
		0, /*tp_setattr*/
		0, /*tp_compare*/
		0, /*tp_repr*/
		0, /*tp_as_number*/
		0, /*tp_as_sequence*/
		0, /*tp_as_mapping*/
		0, /*tp_hash */
		0, /*tp_call*/
		0, /*tp_str*/
		0, /*tp_getattro*/
		0, /*tp_setattro*/
		0, /*tp_as_buffer*/
		Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
		"The LSpaceChargeCalc python wrapper", /* tp_doc */
		0, /* tp_traverse */
		0, /* tp_clear */
		0, /* tp_richcompare */
		0, /* tp_weaklistoffset */
		0, /* tp_iter */
		0, /* tp_iternext */
		LSpaceChargeCalcClassMethods, /* tp_methods */
		LSpaceChargeCalcClassMembers, /* tp_members */
		0, /* tp_getset */
		0, /* tp_base */
		0, /* tp_dict */
		0, /* tp_descr_get */
		0, /* tp_descr_set */
		0, /* tp_dictoffset */
		(initproc) LSpaceChargeCalc_init, /* tp_init */
		0, /* tp_alloc */
		LSpaceChargeCalc_new, /* tp_new */
	};

	//--------------------------------------------------
	//Initialization function of the pyLSpaceChargeCalc class
	//It will be called from SpaceCharge wrapper initialization
	//--------------------------------------------------
  void initLSpaceChargeCalc(PyObject* module){
		if (PyType_Ready(&pyORBIT_LSpaceChargeCalc_Type) < 0) return;
		Py_INCREF(&pyORBIT_LSpaceChargeCalc_Type);
		PyModule_AddObject(module, "LSpaceChargeCalc", (PyObject *)&pyORBIT_LSpaceChargeCalc_Type);
	}

#ifdef __cplusplus
}
#endif

//end of namespace wrap_spacecharge
}
<commit_msg>Took out comment<commit_after>#include "orbit_mpi.hh"
#include "pyORBIT_Object.hh"
#
#include "wrap_lspacechargecalc.hh"
#include "wrap_bunch.hh"

#include <iostream>

#include "LSpaceChargeCalc.hh"

using namespace OrbitUtils;

namespace wrap_LSpaceChargeCalc{

#ifdef __cplusplus
extern "C" {
#endif

	//---------------------------------------------------------
	//Python LSpaceChargeCalc class definition
	//---------------------------------------------------------

	//constructor for python class wrapping LSpaceChargeCalc instance
	//It never will be called directly

	static PyObject* LSpaceChargeCalc_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
	{
		pyORBIT_Object* self;
		self = (pyORBIT_Object *) type->tp_alloc(type, 0);
		self->cpp_obj = NULL;
		//std::cerr<<"The LSpaceChargeCalc new has been called!"<<std::endl;
		return (PyObject *) self;
	}

  //initializator for python LSpaceChargeCalc class
  //this is implementation of the __init__ method LSpaceChargeCalc(double b_a, double length, int nMacrosMin, int useSpaceCharge, int nBins)
  static int LSpaceChargeCalc_init(pyORBIT_Object *self, PyObject *args, PyObject *kwds){

		pyORBIT_Object* pyLSpaceChargeCalc = (pyORBIT_Object*) self;
		LSpaceChargeCalc* cpp_LSpaceChargeCalc = (LSpaceChargeCalc*) pyLSpaceChargeCalc->cpp_obj;

		double b_a = 1.0;
		double length = 1.0;
		int nMacrosMin;
		int useSpaceCharge;
		int nBins;

		if(!PyArg_ParseTuple(args,"ddiii:arguments",&b_a,&length,&nMacrosMin,&useSpaceCharge,&nBins)){
			ORBIT_MPI_Finalize("PyLSpaceChargeCalc - LSpaceChargeCalc(b_a, length, nMacrosMin, useSpaceCharge, nBins) - constructor needs parameters.");
		}

		self->cpp_obj = new LSpaceChargeCalc(b_a, length, nMacrosMin, useSpaceCharge, nBins);

		((LSpaceChargeCalc*) self->cpp_obj)->setPyWrapper((PyObject*) self);

		return 0;
	}

	//assignImpedance  A routine to import a python complex tuple and convert to c++ impedance array
	static PyObject* assignImpedance(PyObject *self, PyObject *args){

		pyORBIT_Object* pyLSpaceChargeCalc = (pyORBIT_Object*) self;
		LSpaceChargeCalc* cpp_LSpaceChargeCalc = (LSpaceChargeCalc*) pyLSpaceChargeCalc->cpp_obj;
		PyObject* py_cmplx_arr;

		if(!PyArg_ParseTuple(args,"O:get_complex_arr",&py_cmplx_arr)){
			ORBIT_MPI_Finalize("ERROR! You have to specify a parameter - array of complex numbers!");
		}
		if(PySequence_Check(py_cmplx_arr) != 1){
			ORBIT_MPI_Finalize("ERROR! You have to specify a parameter - array of complex numbers!");
		}
		int size = PySequence_Size(py_cmplx_arr);
		Py_complex cmplx;
		PyObject* py_cmplx;
		double real,imag;
		for(int i = 0; i < size; i++){
			py_cmplx = PySequence_Fast_GET_ITEM(py_cmplx_arr, i);
			if(!PyComplex_Check(py_cmplx)){
				ORBIT_MPI_Finalize("ERROR! No complex numbers!");
			}
			cmplx = PyComplex_AsCComplex(py_cmplx);
			real = cmplx.real;
			imag = cmplx.imag;
			cpp_LSpaceChargeCalc->assignImpedanceValue(i,real,imag);
		}

		Py_INCREF(Py_None);
		return Py_None;

	}

	//assignImpedanceValue(int, real, real).  Wraps the LongSpaceChargeCalc routine assigning an impedance mode
	static PyObject* LSpaceChargeCalc_assignImpedanceValue(PyObject *self, PyObject *args){

		pyORBIT_Object* pyLSpaceChargeCalc = (pyORBIT_Object*) self;
		LSpaceChargeCalc* cpp_LSpaceChargeCalc = (LSpaceChargeCalc*) pyLSpaceChargeCalc->cpp_obj;

		int i = 0;
		double real= 0.0;
		double imag = 0.0;

		if(!PyArg_ParseTuple(args,"idd:arguments",&i,&real,&imag)){
			ORBIT_MPI_Finalize("PyLSpaceChargeCalc - assignImpedanceValue(i, real,imag) - constructor needs parameters.");
		}
		cpp_LSpaceChargeCalc->assignImpedanceValue(i,real,imag);

		Py_INCREF(Py_None);
		return Py_None;
	}

//trackBunchBunch(Bunch* bunch)
  static PyObject* LSpaceChargeCalc_trackBunch(PyObject *self, PyObject *args){
		int nVars = PyTuple_Size(args);
		pyORBIT_Object* pyLSpaceChargeCalc = (pyORBIT_Object*) self;
		LSpaceChargeCalc* cpp_LSpaceChargeCalc = (LSpaceChargeCalc*) pyLSpaceChargeCalc->cpp_obj;
		PyObject* pyBunch;

		if(!PyArg_ParseTuple(args,"O:trackBunch",&pyBunch)){
			ORBIT_MPI_Finalize("PyLSpaceChargeCalc.trackBunch(pyBunch) - method needs parameters.");
		}

		PyObject* pyORBIT_Bunch_Type = wrap_orbit_bunch::getBunchType("Bunch");
		if(!PyObject_IsInstance(pyBunch,pyORBIT_Bunch_Type)){
			ORBIT_MPI_Finalize("PyLSpaceChargeCalc.trackBunch(pyBunch) - pyBunch is not Bunch.");
		}
		Bunch* cpp_bunch = (Bunch*) ((pyORBIT_Object*)pyBunch)->cpp_obj;
		cpp_LSpaceChargeCalc->trackBunch(cpp_bunch);

		Py_INCREF(Py_None);
		return Py_None;
  }

  //-----------------------------------------------------
  //destructor for python LSpaceChargeCalc class (__del__ method).
  //-----------------------------------------------------
  static void LSpaceChargeCalc_del(pyORBIT_Object* self){
		LSpaceChargeCalc* cpp_LSpaceChargeCalc = (LSpaceChargeCalc*) self->cpp_obj;
		if(cpp_LSpaceChargeCalc != NULL){
			delete cpp_LSpaceChargeCalc;
		}
		self->ob_type->tp_free((PyObject*)self);
  }

  // defenition of the methods of the python LSpaceChargeCalc wrapper class
  // they will be vailable from python level
  static PyMethodDef LSpaceChargeCalcClassMethods[] = {
		{ "trackBunch",  LSpaceChargeCalc_trackBunch, METH_VARARGS,"trackBunch the bunch - trackBunch(pyBunch)"},
		{ "assignImpedanceValue",  LSpaceChargeCalc_assignImpedanceValue, METH_VARARGS,"assigne the impedance for the ith mode - assignImpedanceValue(i,real,imag)"},
		{ "assignImpedance",  assignImpedance, METH_VARARGS,"assigne the impedance for the ith mode - assignImpedance(Z))"},
		{NULL}
  };

  // defenition of the members of the python LSpaceChargeCalc wrapper class
  // they will be vailable from python level
  static PyMemberDef LSpaceChargeCalcClassMembers [] = {
		{NULL}
  };

	//new python LSpaceChargeCalc wrapper type definition
	static PyTypeObject pyORBIT_LSpaceChargeCalc_Type = {
		PyObject_HEAD_INIT(NULL)
		0, /*ob_size*/
		"LSpaceChargeCalc", /*tp_name*/
		sizeof(pyORBIT_Object), /*tp_basicsize*/
		0, /*tp_itemsize*/
		(destructor) LSpaceChargeCalc_del , /*tp_dealloc*/
		0, /*tp_print*/
		0, /*tp_getattr*/
		0, /*tp_setattr*/
		0, /*tp_compare*/
		0, /*tp_repr*/
		0, /*tp_as_number*/
		0, /*tp_as_sequence*/
		0, /*tp_as_mapping*/
		0, /*tp_hash */
		0, /*tp_call*/
		0, /*tp_str*/
		0, /*tp_getattro*/
		0, /*tp_setattro*/
		0, /*tp_as_buffer*/
		Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
		"The LSpaceChargeCalc python wrapper", /* tp_doc */
		0, /* tp_traverse */
		0, /* tp_clear */
		0, /* tp_richcompare */
		0, /* tp_weaklistoffset */
		0, /* tp_iter */
		0, /* tp_iternext */
		LSpaceChargeCalcClassMethods, /* tp_methods */
		LSpaceChargeCalcClassMembers, /* tp_members */
		0, /* tp_getset */
		0, /* tp_base */
		0, /* tp_dict */
		0, /* tp_descr_get */
		0, /* tp_descr_set */
		0, /* tp_dictoffset */
		(initproc) LSpaceChargeCalc_init, /* tp_init */
		0, /* tp_alloc */
		LSpaceChargeCalc_new, /* tp_new */
	};

	//--------------------------------------------------
	//Initialization function of the pyLSpaceChargeCalc class
	//It will be called from SpaceCharge wrapper initialization
	//--------------------------------------------------
  void initLSpaceChargeCalc(PyObject* module){
		if (PyType_Ready(&pyORBIT_LSpaceChargeCalc_Type) < 0) return;
		Py_INCREF(&pyORBIT_LSpaceChargeCalc_Type);
		PyModule_AddObject(module, "LSpaceChargeCalc", (PyObject *)&pyORBIT_LSpaceChargeCalc_Type);
	}

#ifdef __cplusplus
}
#endif

//end of namespace wrap_spacecharge
}
<|endoftext|>


<commit_before>/* This file is part of the KDE project
 * Copyright (C) 2001, 2002 Rolf Magnus <ramagnus@kde.org>
 * Copyright (C) 2007 Tim Beaulen <tbscope@gmail.com>
 *
 * 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 version 2.
 *
 * 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; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 *  $Id$
 */

#include "m3ustreamanalyzer.h"
#include <string.h>
#include <fieldtypes.h>
#include <analysisresult.h>
#include <streamlineanalyzer.h>
#include <string>

// AnalyzerFactory
void M3uLineAnalyzerFactory::registerFields(Strigi::FieldRegister& reg)
{
// track list length is easily obtained via API
//    tracksField = reg.registerField();
    trackPathField = reg.registerField("http://freedesktop.org/standards/xesam/1.0/core#links");
    m3uTypeField = reg.registerField("http://freedesktop.org/standards/xesam/1.0/core#formatSubtype");

    typeField = reg.typeField;
}

// Analyzer
void M3uLineAnalyzer::startAnalysis(Strigi::AnalysisResult* i)
{
    extensionOk = i->extension() == "m3u" || i->extension() == "M3U";

    analysisResult = i;
    line = 0;
    count = 0;
}

void M3uLineAnalyzer::handleLine(const char* data, uint32_t length)
{
    if (!extensionOk)
        return;

    ++line;

    if (length == 0)
        return;

    if (*data != '#') {

        if (line == 1)
            analysisResult->addValue(factory->m3uTypeField, "simple");

        // TODO: Check for a valid url with QUrl
        analysisResult->addValue(factory->trackPathField, std::string(data, length));

        ++count;
    } else if (line == 1 && strncmp(data, "#EXTM3U", 7) == 0) {
        analysisResult->addValue(factory->m3uTypeField, "extended");
    }
}

bool M3uLineAnalyzer::isReadyWithStream()
{
    // we can analyze each line and are only done if the extension is not ok
    return !extensionOk;
}

void M3uLineAnalyzer::endAnalysis(bool complete)
{
    // tracksField has not been initialized, so don't use it
    //if (complete && extensionOk)
        //analysisResult->addValue(factory->tracksField, count);
    if (complete && extensionOk)
        analysisResult->addValue(factory->typeField, "http://freedesktop.org/standards/xesam/1.0/core#AudioList");

}

<commit_msg>add the field to the factory list of fields.<commit_after>/* This file is part of the KDE project
 * Copyright (C) 2001, 2002 Rolf Magnus <ramagnus@kde.org>
 * Copyright (C) 2007 Tim Beaulen <tbscope@gmail.com>
 *
 * 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 version 2.
 *
 * 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; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 *  $Id$
 */

#include "m3ustreamanalyzer.h"
#include <string.h>
#include <fieldtypes.h>
#include <analysisresult.h>
#include <streamlineanalyzer.h>
#include <string>

// AnalyzerFactory
void M3uLineAnalyzerFactory::registerFields(Strigi::FieldRegister& reg)
{
// track list length is easily obtained via API
//    tracksField = reg.registerField();
    trackPathField = reg.registerField(
        "http://freedesktop.org/standards/xesam/1.0/core#links");
    m3uTypeField = reg.registerField(
        "http://freedesktop.org/standards/xesam/1.0/core#formatSubtype");
    typeField = reg.typeField;

    addField(trackPathField);
    addField(m3uTypeField);
    addField(typeField);
}

// Analyzer
void M3uLineAnalyzer::startAnalysis(Strigi::AnalysisResult* i)
{
    extensionOk = i->extension() == "m3u" || i->extension() == "M3U";

    analysisResult = i;
    line = 0;
    count = 0;
}

void M3uLineAnalyzer::handleLine(const char* data, uint32_t length)
{
    if (!extensionOk)
        return;

    ++line;

    if (length == 0)
        return;

    if (*data != '#') {

        if (line == 1)
            analysisResult->addValue(factory->m3uTypeField, "simple");

        // TODO: Check for a valid url with QUrl
        analysisResult->addValue(factory->trackPathField, std::string(data, length));

        ++count;
    } else if (line == 1 && strncmp(data, "#EXTM3U", 7) == 0) {
        analysisResult->addValue(factory->m3uTypeField, "extended");
    }
}

bool M3uLineAnalyzer::isReadyWithStream()
{
    // we can analyze each line and are only done if the extension is not ok
    return !extensionOk;
}

void M3uLineAnalyzer::endAnalysis(bool complete)
{
    // tracksField has not been initialized, so don't use it
    //if (complete && extensionOk)
        //analysisResult->addValue(factory->tracksField, count);
    if (complete && extensionOk)
        analysisResult->addValue(factory->typeField, "http://freedesktop.org/standards/xesam/1.0/core#AudioList");

}

<|endoftext|>


<commit_before>/****************************************************************************
 *
 *   Copyright (c) 2019 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. Neither the name PX4 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.
 *
 ****************************************************************************/

/**
 * @file ObstacleAvoidance.hpp
 * This class is used to inject the setpoints of an obstacle avoidance system
 * into the FlightTasks
 *
 * @author Martina Rivizzigno
 */

#pragma once

#include <px4_defines.h>
#include <px4_module_params.h>
#include <commander/px4_custom_mode.h>
#include <drivers/drv_hrt.h>

#include <uORB/topics/position_controller_status.h>
#include <uORB/topics/vehicle_command.h>
#include <uORB/topics/vehicle_status.h>
#include <uORB/topics/vehicle_trajectory_waypoint.h>
#include <uORB/topics/position_setpoint.h>

#include <matrix/matrix/math.hpp>

#include <SubscriptionArray.hpp>

class ObstacleAvoidance : public ModuleParams
{
public:
	ObstacleAvoidance(ModuleParams *parent);
	~ObstacleAvoidance();

	bool initializeSubscriptions(SubscriptionArray &subscription_array);

	/**
	 * Inject setpoints from obstacle avoidance system into FlightTasks.
	 * @param pos_sp, position setpoint
	 * @param vel_sp, velocity setpoint
	 * @param yaw_sp, yaw setpoint
	 * @param yaw_speed_sp, yaw speed setpoint
	 */
	void injectAvoidanceSetpoints(matrix::Vector3f &pos_sp, matrix::Vector3f &vel_sp, float &yaw_sp, float &yaw_speed_sp);

	/**
	 * Updates the desired waypoints to send to the obstacle avoidance system. These messages don't have any direct impact on the flight.
	 * @param curr_wp, current position triplet
	 * @param curr_yaw, current yaw triplet
	 * @param curr_yawspeed, current yaw speed triplet
	 * @param next_wp, next position triplet
	 * @param next_yaw, next yaw triplet
	 * @param next_yawspeed, next yaw speed triplet
	 */
	void updateAvoidanceDesiredWaypoints(const matrix::Vector3f &curr_wp, const float curr_yaw, const float curr_yawspeed,
					     const matrix::Vector3f &next_wp, const float next_yaw, const float next_yawspeed, const bool ext_yaw_active);
	/**
	 * Updates the desired setpoints to send to the obstacle avoidance system.
	 * @param pos_sp, desired position setpoint computed by the active FlightTask
	 * @param vel_sp, desired velocity setpoint computed by the active FlightTask
	 */
	void updateAvoidanceDesiredSetpoints(const matrix::Vector3f &pos_sp, const matrix::Vector3f &vel_sp);

	/**
	 * Checks the vehicle progress between previous and current position waypoint of the triplet.
	 * @param pos, vehicle position
	 * @param prev_wp, previous position triplet
	 * @param target_acceptance_radius, current position triplet xy acceptance radius
	 * @param closest_pt, closest point to the vehicle on the line previous-current position triplet
	 * @param
	 */
	void checkAvoidanceProgress(const matrix::Vector3f &pos, const matrix::Vector3f &prev_wp,
				    float target_acceptance_radius, const matrix::Vector2f &closest_pt,  const int wp_type);

private:

	uORB::Subscription<vehicle_trajectory_waypoint_s> *_sub_vehicle_trajectory_waypoint{nullptr}; /**< vehicle trajectory waypoint subscription */
	uORB::Subscription<vehicle_status_s> *_sub_vehicle_status{nullptr}; /**< vehicle status subscription */

	DEFINE_PARAMETERS(
		(ParamFloat<px4::params::NAV_MC_ALT_RAD>) _param_nav_mc_alt_rad    /**< Acceptance radius for multicopter altitude */
	);

	vehicle_trajectory_waypoint_s _desired_waypoint = {};  /**< desired vehicle trajectory waypoint to be sent to OA */
	orb_advert_t _pub_traj_wp_avoidance_desired{nullptr}; /**< trajectory waypoint desired publication */
	orb_advert_t _pub_pos_control_status{nullptr}; /**< position controller status publication */
	orb_advert_t _pub_vehicle_command{nullptr}; /**< vehicle command do publication */

	matrix::Vector3f _curr_wp = {}; /**< current position triplet */
	matrix::Vector3f _position = {}; /**< current vehicle position */
	matrix::Vector3f _failsafe_position = {}; /**< vehicle position when entered in failsafe */

	bool _ext_yaw_active = false; /**< true, if external yaw handling is active */

	/**
	 * Publishes vehicle trajectory waypoint desired.
	 */
	void _publishAvoidanceDesiredWaypoint();

	/**
	 * Publishes vehicle command.
	 */
	void _publishVehicleCmdDoLoiter();

};
<commit_msg>ObstacleAvoidance: fix comment<commit_after>/****************************************************************************
 *
 *   Copyright (c) 2019 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 * 3. Neither the name PX4 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.
 *
 ****************************************************************************/

/**
 * @file ObstacleAvoidance.hpp
 * This class is used to inject the setpoints of an obstacle avoidance system
 * into the FlightTasks
 *
 * @author Martina Rivizzigno
 */

#pragma once

#include <px4_defines.h>
#include <px4_module_params.h>
#include <commander/px4_custom_mode.h>
#include <drivers/drv_hrt.h>

#include <uORB/topics/position_controller_status.h>
#include <uORB/topics/vehicle_command.h>
#include <uORB/topics/vehicle_status.h>
#include <uORB/topics/vehicle_trajectory_waypoint.h>
#include <uORB/topics/position_setpoint.h>

#include <matrix/matrix/math.hpp>

#include <SubscriptionArray.hpp>

class ObstacleAvoidance : public ModuleParams
{
public:
	ObstacleAvoidance(ModuleParams *parent);
	~ObstacleAvoidance();

	bool initializeSubscriptions(SubscriptionArray &subscription_array);

	/**
	 * Inject setpoints from obstacle avoidance system into FlightTasks.
	 * @param pos_sp, position setpoint
	 * @param vel_sp, velocity setpoint
	 * @param yaw_sp, yaw setpoint
	 * @param yaw_speed_sp, yaw speed setpoint
	 */
	void injectAvoidanceSetpoints(matrix::Vector3f &pos_sp, matrix::Vector3f &vel_sp, float &yaw_sp, float &yaw_speed_sp);

	/**
	 * Updates the desired waypoints to send to the obstacle avoidance system. These messages don't have any direct impact on the flight.
	 * @param curr_wp, current position triplet
	 * @param curr_yaw, current yaw triplet
	 * @param curr_yawspeed, current yaw speed triplet
	 * @param next_wp, next position triplet
	 * @param next_yaw, next yaw triplet
	 * @param next_yawspeed, next yaw speed triplet
	 */
	void updateAvoidanceDesiredWaypoints(const matrix::Vector3f &curr_wp, const float curr_yaw, const float curr_yawspeed,
					     const matrix::Vector3f &next_wp, const float next_yaw, const float next_yawspeed, const bool ext_yaw_active);
	/**
	 * Updates the desired setpoints to send to the obstacle avoidance system.
	 * @param pos_sp, desired position setpoint computed by the active FlightTask
	 * @param vel_sp, desired velocity setpoint computed by the active FlightTask
	 */
	void updateAvoidanceDesiredSetpoints(const matrix::Vector3f &pos_sp, const matrix::Vector3f &vel_sp);

	/**
	 * Checks the vehicle progress between previous and current position waypoint of the triplet.
	 * @param pos, vehicle position
	 * @param prev_wp, previous position triplet
	 * @param target_acceptance_radius, current position triplet xy acceptance radius
	 * @param closest_pt, closest point to the vehicle on the line previous-current position triplet
	 * @param wp_type, current triplet type
	 */
	void checkAvoidanceProgress(const matrix::Vector3f &pos, const matrix::Vector3f &prev_wp,
				    float target_acceptance_radius, const matrix::Vector2f &closest_pt, const int wp_type);

private:

	uORB::Subscription<vehicle_trajectory_waypoint_s> *_sub_vehicle_trajectory_waypoint{nullptr}; /**< vehicle trajectory waypoint subscription */
	uORB::Subscription<vehicle_status_s> *_sub_vehicle_status{nullptr}; /**< vehicle status subscription */

	DEFINE_PARAMETERS(
		(ParamFloat<px4::params::NAV_MC_ALT_RAD>) _param_nav_mc_alt_rad    /**< Acceptance radius for multicopter altitude */
	);

	vehicle_trajectory_waypoint_s _desired_waypoint = {};  /**< desired vehicle trajectory waypoint to be sent to OA */
	orb_advert_t _pub_traj_wp_avoidance_desired{nullptr}; /**< trajectory waypoint desired publication */
	orb_advert_t _pub_pos_control_status{nullptr}; /**< position controller status publication */
	orb_advert_t _pub_vehicle_command{nullptr}; /**< vehicle command do publication */

	matrix::Vector3f _curr_wp = {}; /**< current position triplet */
	matrix::Vector3f _position = {}; /**< current vehicle position */
	matrix::Vector3f _failsafe_position = {}; /**< vehicle position when entered in failsafe */

	bool _ext_yaw_active = false; /**< true, if external yaw handling is active */

	/**
	 * Publishes vehicle trajectory waypoint desired.
	 */
	void _publishAvoidanceDesiredWaypoint();

	/**
	 * Publishes vehicle command.
	 */
	void _publishVehicleCmdDoLoiter();

};
<|endoftext|>


<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011      Konstantin Oblaukhov <oblaukhov.konstantin@gmail.com>
//

#include "GeoPolygonGraphicsItem.h"

#include "GeoDataLinearRing.h"
#include "GeoDataPolygon.h"
#include "GeoPainter.h"
#include "ViewportParams.h"
#include "GeoDataStyle.h"

namespace Marble
{

GeoPolygonGraphicsItem::GeoPolygonGraphicsItem( const GeoDataFeature *feature, const GeoDataPolygon* polygon )
        : GeoGraphicsItem( feature ),
          m_polygon( polygon ),
          m_ring( 0 )
{
}

GeoPolygonGraphicsItem::GeoPolygonGraphicsItem( const GeoDataFeature *feature, const GeoDataLinearRing* ring )
        : GeoGraphicsItem( feature ),
          m_polygon( 0 ),
          m_ring( ring )
{
}

const GeoDataLatLonAltBox& GeoPolygonGraphicsItem::latLonAltBox() const
{
    if( m_polygon ) {
        return m_polygon->latLonAltBox();
    } else if ( m_ring ) {
        return m_ring->latLonAltBox();
    } else {
        return GeoGraphicsItem::latLonAltBox();
    }
}

void GeoPolygonGraphicsItem::paint( GeoPainter* painter, const ViewportParams* viewport )
{
    Q_UNUSED( viewport );

    if ( !style() )
    {
        painter->save();
        painter->setPen( QPen() );
        if ( m_polygon ) {
            painter->drawPolygon( *m_polygon );
        } else if ( m_ring ) {
            painter->drawPolygon( *m_ring );
        }
        painter->restore();
        return;
    }

    painter->save();
    QPen currentPen = painter->pen();

    if ( !style()->polyStyle().outline() )
    {
        currentPen.setColor( Qt::transparent );
    }
    else
    {
        if ( currentPen.color() != style()->lineStyle().paintedColor() ||
                currentPen.widthF() != style()->lineStyle().width() )
        {
            currentPen.setColor( style()->lineStyle().paintedColor() );
            currentPen.setWidthF( style()->lineStyle().width() );
        }

        if ( currentPen.capStyle() != style()->lineStyle().capStyle() )
            currentPen.setCapStyle( style()->lineStyle().capStyle() );

        if ( currentPen.style() != style()->lineStyle().penStyle() )
            currentPen.setStyle( style()->lineStyle().penStyle() );

        if ( painter->mapQuality() != Marble::HighQuality
                && painter->mapQuality() != Marble::PrintQuality )
        {
            QColor penColor = currentPen.color();
            penColor.setAlpha( 255 );
            currentPen.setColor( penColor );
        }
    }
    if ( painter->pen() != currentPen ) painter->setPen( currentPen );

    if ( !style()->polyStyle().fill() )
    {
        if ( painter->brush().color() != Qt::transparent )
            painter->setBrush( QColor( Qt::transparent ) );
    }
    else
    {
        if ( painter->brush().color() != style()->polyStyle().paintedColor() )
        {
            painter->setBrush( style()->polyStyle().paintedColor() );
        }
    }

    if ( m_polygon ) {
        painter->drawPolygon( *m_polygon );
    } else if ( m_ring ) {
        painter->drawPolygon( *m_ring );
    }
    painter->restore();
}

}
<commit_msg>resolve some code duplication<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011      Konstantin Oblaukhov <oblaukhov.konstantin@gmail.com>
//

#include "GeoPolygonGraphicsItem.h"

#include "GeoDataLinearRing.h"
#include "GeoDataPolygon.h"
#include "GeoPainter.h"
#include "ViewportParams.h"
#include "GeoDataStyle.h"

namespace Marble
{

GeoPolygonGraphicsItem::GeoPolygonGraphicsItem( const GeoDataFeature *feature, const GeoDataPolygon* polygon )
        : GeoGraphicsItem( feature ),
          m_polygon( polygon ),
          m_ring( 0 )
{
}

GeoPolygonGraphicsItem::GeoPolygonGraphicsItem( const GeoDataFeature *feature, const GeoDataLinearRing* ring )
        : GeoGraphicsItem( feature ),
          m_polygon( 0 ),
          m_ring( ring )
{
}

const GeoDataLatLonAltBox& GeoPolygonGraphicsItem::latLonAltBox() const
{
    if( m_polygon ) {
        return m_polygon->latLonAltBox();
    } else if ( m_ring ) {
        return m_ring->latLonAltBox();
    } else {
        return GeoGraphicsItem::latLonAltBox();
    }
}

void GeoPolygonGraphicsItem::paint( GeoPainter* painter, const ViewportParams* viewport )
{
    Q_UNUSED( viewport );

    painter->save();

    if ( !style() ) {
        painter->setPen( QPen() );
    }
    else {
        QPen currentPen = painter->pen();

        if ( !style()->polyStyle().outline() ) {
            currentPen.setColor( Qt::transparent );
        }
        else {
            if ( currentPen.color() != style()->lineStyle().paintedColor() ||
                    currentPen.widthF() != style()->lineStyle().width() ) {
                currentPen.setColor( style()->lineStyle().paintedColor() );
                currentPen.setWidthF( style()->lineStyle().width() );
            }

            if ( currentPen.capStyle() != style()->lineStyle().capStyle() )
                currentPen.setCapStyle( style()->lineStyle().capStyle() );

            if ( currentPen.style() != style()->lineStyle().penStyle() )
                currentPen.setStyle( style()->lineStyle().penStyle() );

            if ( painter->mapQuality() != Marble::HighQuality
                    && painter->mapQuality() != Marble::PrintQuality ) {
                QColor penColor = currentPen.color();
                penColor.setAlpha( 255 );
                currentPen.setColor( penColor );
            }
        }

        if ( painter->pen() != currentPen )
            painter->setPen( currentPen );

        if ( !style()->polyStyle().fill() ) {
            if ( painter->brush().color() != Qt::transparent )
                painter->setBrush( QColor( Qt::transparent ) );
        }
        else {
            if ( painter->brush().color() != style()->polyStyle().paintedColor() ) {
                painter->setBrush( style()->polyStyle().paintedColor() );
            }
        }
    }

    if ( m_polygon ) {
        painter->drawPolygon( *m_polygon );
    } else if ( m_ring ) {
        painter->drawPolygon( *m_ring );
    }

    painter->restore();
}

}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2014, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <cmake.h>
#include <algorithm>
// If <iostream> is included, put it after <stdio.h>, because it includes
// <stdio.h>, and therefore would ignore the _WITH_GETLINE.
#ifdef FREEBSD
#define _WITH_GETLINE
#endif
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <Context.h>
#include <Hooks.h>
#include <text.h>
#include <util.h>

extern Context context;

////////////////////////////////////////////////////////////////////////////////
Hooks::Hooks ()
: _enabled (true)
{
}

////////////////////////////////////////////////////////////////////////////////
Hooks::~Hooks ()
{
}

////////////////////////////////////////////////////////////////////////////////
void Hooks::initialize ()
{
  // Scan <rc.data.location>/hooks
  Directory d (context.config.get ("data.location"));
  d += "hooks";
  if (d.is_directory () &&
      d.readable ())
  {
    _scripts = d.list ();
    std::sort (_scripts.begin (), _scripts.end ());
  }

  _enabled = context.config.getBoolean ("hooks");
}

////////////////////////////////////////////////////////////////////////////////
bool Hooks::enable (bool value)
{
  bool old_value = _enabled;
  _enabled = value;
  return old_value;
}

////////////////////////////////////////////////////////////////////////////////
// The on-launch event is triggered once, after initialization, before any
// processing occurs, i.e first
//
// Input:
// - none
//
// Output:
// - all emitted JSON lines are added/modified as tasks, if the exit code is
//   zero, otherwise ignored.
// - minimal new task:  {"description":"Buy milk"}
// - to modify a task include complete JSON
// - all emitted non-JSON lines are considered feedback messages if the exit
//   code is zero, otherwise they are considered errors.
//
void Hooks::onLaunch ()
{
  context.timer_hooks.start ();
  if (! _enabled)
    return;

  std::vector <std::string> matchingScripts = scripts ("on-launch");
  std::vector <std::string>::iterator i;
  for (i = matchingScripts.begin (); i != matchingScripts.end (); ++i)
  {
    std::string output;
    std::vector <std::string> args;
    int status = execute (*i, args, "", output);

    std::vector <std::string> lines;
    split (lines, output, '\n');
    std::vector <std::string>::iterator line;

    if (status == 0)
    {
      for (line = lines.begin (); line != lines.end (); ++line)
      {
        if (line->length () && (*line)[0] == '{')
        {
          // Only 'add' is possible.
          Task newTask (*line);
          context.tdb2.add (newTask);
        }
        else
          context.header (*line);
      }
    }
    else
    {
      for (line = lines.begin (); line != lines.end (); ++line)
        if (line->length () && (*line)[0] != '{')
          context.error (*line);

      throw 0;  // This is how hooks silently terminate processing.
    }
  }

  context.timer_hooks.stop ();
}

////////////////////////////////////////////////////////////////////////////////
// The on-exit event is triggered once, after all processing is complete, i.e.
// last
//
// Input:
// - read-only line of JSON for each task added/modified
//
// Output:
// - any emitted JSON is ignored
// - all emitted non-JSON lines are considered feedback messages if the exit
//   code is zero, otherwise they are considered errors.
//
void Hooks::onExit ()
{
  context.timer_hooks.start ();
  if (! _enabled)
    return;

  std::vector <std::string> matchingScripts = scripts ("on-exit");
  std::vector <std::string>::iterator i;
  for (i = matchingScripts.begin (); i != matchingScripts.end (); ++i)
  {
    std::string input;
    std::string output;
    std::vector <std::string> args;
    int status = execute (*i, args, input, output);

    std::vector <std::string> lines;
    split (lines, output, '\n');
    std::vector <std::string>::iterator line;

    for (line = lines.begin (); line != lines.end (); ++line)
    {
      if (line->length () && (*line)[0] != '{')
      {
        if (status == 0)
          context.footnote (*line);
        else
          context.error (*line);
      }
    }
  }

  context.timer_hooks.stop ();
}

////////////////////////////////////////////////////////////////////////////////
// The on-add event is triggered separately for each task added
//
// Input:
// - line of JSON for the task added
//
// Output:
// - all emitted JSON lines are added/modified as tasks, if the exit code is
//   zero, otherwise ignored.
// - minimal new task:  {"description":"Buy milk"}
// - to modify a task include complete JSON
// - all emitted non-JSON lines are considered feedback messages if the exit
//   code is zero, otherwise they are considered errors.
//
void Hooks::onAdd (std::vector <Task>& changes)
{
/*
  context.timer_hooks.start ();
  if (! _enabled)
    return;

  std::vector <std::string> matchingScripts = scripts ("on-add");
  std::vector <std::string>::iterator i;
  for (i = matchingScripts.begin (); i != matchingScripts.end (); ++i)
  {
    std::string input = after.composeJSON () + "\n";
    std::string output;
    std::vector <std::string> args;
    int status = execute (*i, args, input, output);

    std::vector <std::string> lines;
    split (lines, output, '\n');
    std::vector <std::string>::iterator line;

    if (status == 0)
    {
      bool first = true;
      for (line = lines.begin (); line != lines.end (); ++line)
      {
        if (line->length () && (*line)[0] == '{')
        {
          Task newTask (*line);

          // TODO Not sure if this first/!first thing is good.
          if (first)
          {
            after = newTask;
            first = false;
          }
          else
            context.tdb2.add (newTask);
        }
        else
          context.footnote (*line);
      }
    }
    else
    {
      for (line = lines.begin (); line != lines.end (); ++line)
        if (line->length () && (*line)[0] != '{')
          context.error (*line);

      throw 0;  // This is how hooks silently terminate processing.
    }
  }

  context.timer_hooks.stop ();
*/
}

////////////////////////////////////////////////////////////////////////////////
// The on-modify event is triggered separately for each task added or modified
//
// Input:
// - line of JSON for the original task
// - line of JSON for the modified task, the diff being the modification
//
// Output:
// - all emitted JSON lines are added/modified as tasks, if the exit code is
//   zero, otherwise ignored.
// - minimal new task:  {"description":"Buy milk"}
// - to modify a task include complete JSON
// - all emitted non-JSON lines are considered feedback messages if the exit
//   code is zero, otherwise they are considered errors.
//
void Hooks::onModify (const Task& before, std::vector <Task>& changes)
{
/*
  context.timer_hooks.start ();
  if (! _enabled)
    return;

  std::vector <std::string> matchingScripts = scripts ("on-modify");
  std::vector <std::string>::iterator i;
  for (i = matchingScripts.begin (); i != matchingScripts.end (); ++i)
  {
    std::string afterJSON = after.composeJSON ();
    std::string input = before.composeJSON ()
                      + "\n"
                      + afterJSON
                      + "\n";
    std::string output;
    std::vector <std::string> args;
    int status = execute (*i, args, input, output);

    std::vector <std::string> lines;
    split (lines, output, '\n');
    std::vector <std::string>::iterator line;

    if (status == 0)
    {
      bool first = true;
      for (line = lines.begin (); line != lines.end (); ++line)
      {
        if (line->length () && (*line)[0] == '{')
        {
          Task newTask (*line);

          // TODO Not sure if this first/!first thing is good.
          if (first)
          {
            after = newTask;
            first = false;
          }
          else
            context.tdb2.modify (newTask);
        }
        else
          context.footnote (*line);
      }
    }
    else
    {
      for (line = lines.begin (); line != lines.end (); ++line)
        if (line->length () && (*line)[0] != '{')
          context.error (*line);

      throw 0;  // This is how hooks silently terminate processing.
    }
  }

  context.timer_hooks.stop ();
*/
}

////////////////////////////////////////////////////////////////////////////////
std::vector <std::string> Hooks::list ()
{
  return _scripts;
}

////////////////////////////////////////////////////////////////////////////////
std::vector <std::string> Hooks::scripts (const std::string& event)
{
  std::vector <std::string> matching;
  std::vector <std::string>::iterator i;
  for (i = _scripts.begin (); i != _scripts.end (); ++i)
  {
    if (i->find ("/" + event) != std::string::npos)
    {
      File script (*i);
      if (script.executable ())
        matching.push_back (*i);
    }
  }

  return matching;
}

////////////////////////////////////////////////////////////////////////////////
<commit_msg>Hooks<commit_after>////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2014, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <cmake.h>
#include <algorithm>
// If <iostream> is included, put it after <stdio.h>, because it includes
// <stdio.h>, and therefore would ignore the _WITH_GETLINE.
#ifdef FREEBSD
#define _WITH_GETLINE
#endif
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <Context.h>
#include <Hooks.h>
#include <text.h>
#include <util.h>

extern Context context;

////////////////////////////////////////////////////////////////////////////////
Hooks::Hooks ()
: _enabled (true)
{
}

////////////////////////////////////////////////////////////////////////////////
Hooks::~Hooks ()
{
}

////////////////////////////////////////////////////////////////////////////////
void Hooks::initialize ()
{
  // Scan <rc.data.location>/hooks
  Directory d (context.config.get ("data.location"));
  d += "hooks";
  if (d.is_directory () &&
      d.readable ())
  {
    _scripts = d.list ();
    std::sort (_scripts.begin (), _scripts.end ());
  }

  _enabled = context.config.getBoolean ("hooks");
}

////////////////////////////////////////////////////////////////////////////////
bool Hooks::enable (bool value)
{
  bool old_value = _enabled;
  _enabled = value;
  return old_value;
}

////////////////////////////////////////////////////////////////////////////////
// The on-launch event is triggered once, after initialization, before any
// processing occurs, i.e first
//
// Input:
// - none
//
// Output:
// - all emitted JSON lines are added/modified as tasks, if the exit code is
//   zero, otherwise ignored.
// - minimal new task:  {"description":"Buy milk"}
// - to modify a task include complete JSON
// - all emitted non-JSON lines are considered feedback messages if the exit
//   code is zero, otherwise they are considered errors.
//
void Hooks::onLaunch ()
{
  if (! _enabled)
    return;

  context.timer_hooks.start ();

  std::vector <std::string> matchingScripts = scripts ("on-launch");
  std::vector <std::string>::iterator i;
  for (i = matchingScripts.begin (); i != matchingScripts.end (); ++i)
  {
    std::string output;
    std::vector <std::string> args;
    int status = execute (*i, args, "", output);

    std::vector <std::string> lines;
    split (lines, output, '\n');
    std::vector <std::string>::iterator line;

    if (status == 0)
    {
      for (line = lines.begin (); line != lines.end (); ++line)
      {
        if (line->length () && (*line)[0] == '{')
        {
          // Only 'add' is possible.
          Task newTask (*line);
          context.tdb2.add (newTask);
        }
        else
          context.header (*line);
      }
    }
    else
    {
      for (line = lines.begin (); line != lines.end (); ++line)
        if (line->length () && (*line)[0] != '{')
          context.error (*line);

      throw 0;  // This is how hooks silently terminate processing.
    }
  }

  context.timer_hooks.stop ();
}

////////////////////////////////////////////////////////////////////////////////
// The on-exit event is triggered once, after all processing is complete, i.e.
// last
//
// Input:
// - read-only line of JSON for each task added/modified
//
// Output:
// - any emitted JSON is ignored
// - all emitted non-JSON lines are considered feedback messages if the exit
//   code is zero, otherwise they are considered errors.
//
void Hooks::onExit ()
{
  if (! _enabled)
    return;

  context.timer_hooks.start ();

  std::vector <std::string> matchingScripts = scripts ("on-exit");
  std::vector <std::string>::iterator i;
  for (i = matchingScripts.begin (); i != matchingScripts.end (); ++i)
  {
    std::string input;
    std::string output;
    std::vector <std::string> args;
    int status = execute (*i, args, input, output);

    std::vector <std::string> lines;
    split (lines, output, '\n');
    std::vector <std::string>::iterator line;

    for (line = lines.begin (); line != lines.end (); ++line)
    {
      if (line->length () && (*line)[0] != '{')
      {
        if (status == 0)
          context.footnote (*line);
        else
          context.error (*line);
      }
    }
  }

  context.timer_hooks.stop ();
}

////////////////////////////////////////////////////////////////////////////////
// The on-add event is triggered separately for each task added
//
// Input:
// - line of JSON for the task added
//
// Output:
// - all emitted JSON lines are added/modified as tasks, if the exit code is
//   zero, otherwise ignored.
// - minimal new task:  {"description":"Buy milk"}
// - to modify a task include complete JSON
// - all emitted non-JSON lines are considered feedback messages if the exit
//   code is zero, otherwise they are considered errors.
//
void Hooks::onAdd (std::vector <Task>& changes)
{
  if (! _enabled)
    return;

  context.timer_hooks.start ();

  std::vector <std::string> matchingScripts = scripts ("on-add");
  std::vector <std::string>::iterator i;
  for (i = matchingScripts.begin (); i != matchingScripts.end (); ++i)
  {
    std::string input = changes[0].composeJSON () + "\n";
    std::string output;
    std::vector <std::string> args;
    int status = execute (*i, args, input, output);

    std::vector <std::string> lines;
    split (lines, output, '\n');
    std::vector <std::string>::iterator line;

    if (status == 0)
    {
      changes.clear ();
      for (line = lines.begin (); line != lines.end (); ++line)
      {
        if (line->length () && (*line)[0] == '{')
          changes.push_back (Task (*line));
        else
          context.footnote (*line);
      }
    }
    else
    {
      for (line = lines.begin (); line != lines.end (); ++line)
        if (line->length () && (*line)[0] != '{')
          context.error (*line);

      throw 0;  // This is how hooks silently terminate processing.
    }
  }

  context.timer_hooks.stop ();
}

////////////////////////////////////////////////////////////////////////////////
// The on-modify event is triggered separately for each task added or modified
//
// Input:
// - line of JSON for the original task
// - line of JSON for the modified task, the diff being the modification
//
// Output:
// - all emitted JSON lines are added/modified as tasks, if the exit code is
//   zero, otherwise ignored.
// - minimal new task:  {"description":"Buy milk"}
// - to modify a task include complete JSON
// - all emitted non-JSON lines are considered feedback messages if the exit
//   code is zero, otherwise they are considered errors.
//
void Hooks::onModify (const Task& before, std::vector <Task>& changes)
{
  if (! _enabled)
    return;

  context.timer_hooks.start ();

  std::vector <std::string> matchingScripts = scripts ("on-modify");
  std::vector <std::string>::iterator i;
  for (i = matchingScripts.begin (); i != matchingScripts.end (); ++i)
  {
    std::string afterJSON = changes[0].composeJSON ();
    std::string input = before.composeJSON ()
                      + "\n"
                      + afterJSON
                      + "\n";
    std::string output;
    std::vector <std::string> args;
    int status = execute (*i, args, input, output);

    std::vector <std::string> lines;
    split (lines, output, '\n');
    std::vector <std::string>::iterator line;

    if (status == 0)
    {
      changes.clear ();
      for (line = lines.begin (); line != lines.end (); ++line)
      {
        if (line->length () && (*line)[0] == '{')
          changes.push_back (Task (*line));
        else
          context.footnote (*line);
      }
    }
    else
    {
      for (line = lines.begin (); line != lines.end (); ++line)
        if (line->length () && (*line)[0] != '{')
          context.error (*line);

      throw 0;  // This is how hooks silently terminate processing.
    }
  }

  context.timer_hooks.stop ();
}

////////////////////////////////////////////////////////////////////////////////
std::vector <std::string> Hooks::list ()
{
  return _scripts;
}

////////////////////////////////////////////////////////////////////////////////
std::vector <std::string> Hooks::scripts (const std::string& event)
{
  std::vector <std::string> matching;
  std::vector <std::string>::iterator i;
  for (i = _scripts.begin (); i != _scripts.end (); ++i)
  {
    if (i->find ("/" + event) != std::string::npos)
    {
      File script (*i);
      if (script.executable ())
        matching.push_back (*i);
    }
  }

  return matching;
}

////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>#include "stan/math/functions/modified_bessel_second_kind.hpp"
#include <gtest/gtest.h>

TEST(MathFunctions, modified_bessel_second_kind) {
  using stan::math::modified_bessel_second_kind;

  EXPECT_FLOAT_EQ(0.011159676085853024269745195979833489225,
                  modified_bessel_second_kind(0,4.0));
  EXPECT_THROW(modified_bessel_second_kind(1,-3.0), std::domain_error);
  EXPECT_THROW(modified_bessel_second_kind(-1,-3.0), std::domain_error);
}
<commit_msg>added NaN test for modified_bessel_second_kind<commit_after>#include <stan/math/functions/modified_bessel_second_kind.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <gtest/gtest.h>

TEST(MathFunctions, modified_bessel_second_kind) {
  using stan::math::modified_bessel_second_kind;

  EXPECT_FLOAT_EQ(0.011159676085853024269745195979833489225,
                  modified_bessel_second_kind(0,4.0));
  EXPECT_THROW(modified_bessel_second_kind(1,-3.0), std::domain_error);
  EXPECT_THROW(modified_bessel_second_kind(-1,-3.0), std::domain_error);
}

TEST(MathFunctions, modified_bessel_second_kind_nan) {
  double nan = std::numeric_limits<double>::quiet_NaN();

  EXPECT_PRED1(boost::math::isnan<double>,
               stan::math::modified_bessel_second_kind(0, nan));
}
<|endoftext|>


<commit_before>#ifndef __TRAINING_CORE_HPP
#define __TRAINING_CORE_HPP

#include <cmath>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>

#include "nanopolish_eventalign.h"
#include "nanopolish_squiggle_read.h"

// The state training data comes in two different
// sizes Full and Minimal. The model training functions
// only actually need the Minimal data but for exploration
// the Full data is useful so left as an option.

struct MinimalStateTrainingData
{
    //
    // Functions
    //
    MinimalStateTrainingData(const SquiggleRead& sr,
                             const EventAlignment& ea,
                             uint32_t,
                             const std::string&,
                             const std::string&)
    {
        // scale the observation to the expected pore model
        this->level_mean = sr.get_fully_scaled_level(ea.event_idx, ea.strand_idx);
        this->log_level_mean = std::log(this->level_mean);
        this->level_stdv = sr.get_scaled_stdv(ea.event_idx, ea.strand_idx);
        this->log_level_stdv = std::log(this->level_stdv);
        this->read_var = sr.pore_model[ea.strand_idx].var;
        this->log_read_var = std::log(this->read_var);
        this->read_scale_sd = sr.pore_model[ea.strand_idx].scale_sd;
        this->log_read_scale_sd = std::log(this->read_scale_sd);
        this->read_var_sd = sr.pore_model[ea.strand_idx].var_sd;
        this->log_read_var_sd = std::log(this->read_var_sd);
    }

    static void write_header(std::ostream& os)
    {
        os << "model\tmodel_kmer\tlevel_mean\tlevel_stdv\tread_var\tread_scale_sd\tread_var_sd";
    }

    void write_tsv(std::ostream& os, const std::string& model_name, const std::string& kmer) const
    {
        os << model_name << '\t'
           << kmer << '\t'
           << std::fixed << std::setprecision(2) << level_mean << '\t'
           << level_stdv << '\t'
           << read_var << '\t'
           << read_scale_sd << '\t'
           << read_var_sd;
    }

    //
    // Data
    //
    float level_mean;
    float log_level_mean;
    float level_stdv;
    float log_level_stdv;
    float read_var;
    float log_read_var;
    float read_scale_sd;
    float log_read_scale_sd;
    float read_var_sd;
    float log_read_var_sd;
}; // struct MinimalStateTrainingData

struct FullStateTrainingData
    : public MinimalStateTrainingData
{
    //
    // Functions
    //
    FullStateTrainingData(const SquiggleRead& sr,
                          const EventAlignment& ea,
                          uint32_t rank,
                          const std::string& prev_kmer,
                          const std::string& next_kmer)
        : MinimalStateTrainingData(sr, ea, rank, prev_kmer, next_kmer)
    {
        this->duration = sr.events[ea.strand_idx][ea.event_idx].duration;
        this->ref_position = ea.ref_position;
        this->ref_strand = ea.rc;
        GaussianParameters model = sr.pore_model[ea.strand_idx].get_scaled_parameters(rank);
        this->z = (sr.get_drift_corrected_level(ea.event_idx, ea.strand_idx) -  model.mean ) / model.stdv;
        this->prev_kmer = prev_kmer;
        this->next_kmer = next_kmer;
    }

    static void write_header(std::ostream& os)
    {
        MinimalStateTrainingData::write_header(os);
        os << "duration\tref_pos\tref_strand\tz\tprev_kmer\tnext_kmer";
    }

    void write_tsv(std::ostream& os, const std::string& model_name, const std::string& kmer) const
    {
        MinimalStateTrainingData::write_tsv(os, model_name, kmer);
        os << duration << '\t'
           << ref_position << '\t'
           << ref_strand << '\t'
           << z << '\t'
           << prev_kmer << '\t'
           << next_kmer;
    }

    //
    // Data
    //
    float duration;
    int ref_position;
    int ref_strand;
    float z;
    std::string prev_kmer;
    std::string next_kmer;
}; // struct FullStateTrainingData

typedef MinimalStateTrainingData StateTrainingData;
//typedef FullStateTrainingData StateTrainingData;

struct GaussianMixture
{
    std::vector< float > log_weights;
    std::vector< PoreModelStateParams > params;
}; // struct GaussianMixture

struct InvGaussianMixture
{
    std::vector< float > log_weights;
    std::vector< PoreModelStateParams > params;
}; // struct InvGaussianMixture

// training functions
GaussianMixture    train_gaussian_mixture   (const std::vector< StateTrainingData >& data, const GaussianMixture&    input_mixture);
InvGaussianMixture train_invgaussian_mixture(const std::vector< StateTrainingData >& data, const InvGaussianMixture& input_mixture);

#endif
<commit_msg>fix: allow default construction in order to resize vectors<commit_after>#ifndef __TRAINING_CORE_HPP
#define __TRAINING_CORE_HPP

#include <cmath>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>

#include "nanopolish_eventalign.h"
#include "nanopolish_squiggle_read.h"

// The state training data comes in two different
// sizes Full and Minimal. The model training functions
// only actually need the Minimal data but for exploration
// the Full data is useful so left as an option.

struct MinimalStateTrainingData
{
    //
    // Functions
    //
    MinimalStateTrainingData() = default;
    MinimalStateTrainingData(const SquiggleRead& sr,
                             const EventAlignment& ea,
                             uint32_t,
                             const std::string&,
                             const std::string&)
    {
        // scale the observation to the expected pore model
        this->level_mean = sr.get_fully_scaled_level(ea.event_idx, ea.strand_idx);
        this->log_level_mean = std::log(this->level_mean);
        this->level_stdv = sr.get_scaled_stdv(ea.event_idx, ea.strand_idx);
        this->log_level_stdv = std::log(this->level_stdv);
        this->read_var = sr.pore_model[ea.strand_idx].var;
        this->log_read_var = std::log(this->read_var);
        this->read_scale_sd = sr.pore_model[ea.strand_idx].scale_sd;
        this->log_read_scale_sd = std::log(this->read_scale_sd);
        this->read_var_sd = sr.pore_model[ea.strand_idx].var_sd;
        this->log_read_var_sd = std::log(this->read_var_sd);
    }

    static void write_header(std::ostream& os)
    {
        os << "model\tmodel_kmer\tlevel_mean\tlevel_stdv\tread_var\tread_scale_sd\tread_var_sd";
    }

    void write_tsv(std::ostream& os, const std::string& model_name, const std::string& kmer) const
    {
        os << model_name << '\t'
           << kmer << '\t'
           << std::fixed << std::setprecision(2) << level_mean << '\t'
           << level_stdv << '\t'
           << read_var << '\t'
           << read_scale_sd << '\t'
           << read_var_sd;
    }

    //
    // Data
    //
    float level_mean;
    float log_level_mean;
    float level_stdv;
    float log_level_stdv;
    float read_var;
    float log_read_var;
    float read_scale_sd;
    float log_read_scale_sd;
    float read_var_sd;
    float log_read_var_sd;
}; // struct MinimalStateTrainingData

struct FullStateTrainingData
    : public MinimalStateTrainingData
{
    //
    // Functions
    //
    FullStateTrainingData() = default;
    FullStateTrainingData(const SquiggleRead& sr,
                          const EventAlignment& ea,
                          uint32_t rank,
                          const std::string& prev_kmer,
                          const std::string& next_kmer)
        : MinimalStateTrainingData(sr, ea, rank, prev_kmer, next_kmer)
    {
        this->duration = sr.events[ea.strand_idx][ea.event_idx].duration;
        this->ref_position = ea.ref_position;
        this->ref_strand = ea.rc;
        GaussianParameters model = sr.pore_model[ea.strand_idx].get_scaled_parameters(rank);
        this->z = (sr.get_drift_corrected_level(ea.event_idx, ea.strand_idx) -  model.mean ) / model.stdv;
        this->prev_kmer = prev_kmer;
        this->next_kmer = next_kmer;
    }

    static void write_header(std::ostream& os)
    {
        MinimalStateTrainingData::write_header(os);
        os << "duration\tref_pos\tref_strand\tz\tprev_kmer\tnext_kmer";
    }

    void write_tsv(std::ostream& os, const std::string& model_name, const std::string& kmer) const
    {
        MinimalStateTrainingData::write_tsv(os, model_name, kmer);
        os << duration << '\t'
           << ref_position << '\t'
           << ref_strand << '\t'
           << z << '\t'
           << prev_kmer << '\t'
           << next_kmer;
    }

    //
    // Data
    //
    float duration;
    int ref_position;
    int ref_strand;
    float z;
    std::string prev_kmer;
    std::string next_kmer;
}; // struct FullStateTrainingData

typedef MinimalStateTrainingData StateTrainingData;
//typedef FullStateTrainingData StateTrainingData;

struct GaussianMixture
{
    std::vector< float > log_weights;
    std::vector< PoreModelStateParams > params;
}; // struct GaussianMixture

struct InvGaussianMixture
{
    std::vector< float > log_weights;
    std::vector< PoreModelStateParams > params;
}; // struct InvGaussianMixture

// training functions
GaussianMixture    train_gaussian_mixture   (const std::vector< StateTrainingData >& data, const GaussianMixture&    input_mixture);
InvGaussianMixture train_invgaussian_mixture(const std::vector< StateTrainingData >& data, const InvGaussianMixture& input_mixture);

#endif
<|endoftext|>


<commit_before>// -*- mode: c++ , coding: utf-8 -*-
/**
 * tbrpg – Text based roll playing game
 *
 * Copyright © 2012, 2013  Mattias Andrée (maandree@kth.se)
 *
 * 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 "Object.hpp"

/**
 * Text based roll playing game
 *
 * DD2387 Program construction with C++
 * Laboration 3
 *
 * @author  Mattias Andrée <maandree@kth.se>
 */
namespace tbrpg
{
  /**
   * Constructor
   */
  Object::Object()
  {
    this->class_inheritance = std::vector<short>();
    this->class_inheritance.push_back(0);
    this->actual_instance = (void*)this;
    this->interface_inheritance = std::vector<std::string>();
    this->event_handler = nullptr;
  }

  /**
   * Copy constructor
   *
   * @param  original  The object to clone
   */
  Object::Object(const Object& original)
  {
    this->class_inheritance = original.class_inheritance;
    this->actual_instance = original.actual_instance;
    this->event_handler = original.event_handler;
  }

  /**
   * Copy constructor
   *
   * @param  original  The object to clone
   */
  Object::Object(Object& original)
  {
    this->class_inheritance = original.class_inheritance;
    this->actual_instance = original.actual_instance;
    this->event_handler = original.event_handler;
  }

  /**
   * Move constructor
   *
   * @param  original  The object to clone
   */
  Object::Object(Object&& original)
  {
    std::swap(this->class_inheritance, original.class_inheritance);
    std::swap(this->actual_instance, original.actual_instance);
    std::swap(this->event_handler, original.event_handler);
  }

  /**
   * Fork the object
   *
   * @return  A fork of the object
   */
  Object* Object::fork() const
  {
    return (Object*)(new Object(*this));
  }

  /**
   * Destructor
   */
  Object::~Object()
  {
    // do nothing
  }

  /**
   * Assignment operator
   *
   * @param   original  The reference object
   * @return            The invoked object
   */
  Object& Object::operator =(const Object& original)
  {
    this->class_inheritance = original.class_inheritance;
    this->actual_instance = original.actual_instance;
    this->event_handler = original.event_handler;
    return *this;
  }

  /**
   * Assignment operator
   *
   * @param   original  The reference object
   * @return            The invoked object
   */
  Object& Object::operator =(Object& original)
  {
    this->class_inheritance = original.class_inheritance;
    this->actual_instance = original.actual_instance;
    this->event_handler = original.event_handler;
    return *this;
  }

  /**
   * Move operator
   *
   * @param   original  The moved object, its resourced will be moved
   * @return            The invoked object
   */
  Object& Object::operator =(Object&& original)
  {
    std::swap(this->class_inheritance, original.class_inheritance);
    std::swap(this->actual_instance, original.actual_instance);
    std::swap(this->event_handler, original.event_handler);
    return *this;
  }

  /**
   * Equality evaluator
   *
   * @param   other  The other comparand
   * @return         Whether the instances are equal
   */
  bool Object::operator ==(const Object& other) const
  {
    return this == &other;
  }

  /**
   * Inequality evaluator
   *
   * @param   other  The other comparand
   * @return         Whether the instances are not equal
   */
  bool Object::operator !=(const Object& other) const
  {
    return (*this == other) == false;
  }

  /**
   * 'Instance of' evaluator
   *
   * @param   other  The other comparand
   * @return         Whether the left comparand is an instance of the right comparand's class
   */
  bool Object::operator >=(const Object& other) const
  {
    if (this->class_inheritance.size() < other.class_inheritance.size())
      return false;

    for (size_t i = 0, n = other.class_inheritance.size(); i < n; i++)
      if (this->class_inheritance[i] != other.class_inheritance[i])
	return false;

    return true;
  }

  /**
   * Reversed 'instance of' evaluator
   *
   * @param   other  The other comparand
   * @return         Whether the right comparand is an instance of the left comparand's class
   */
  bool Object::operator <=(const Object& other) const
  {
    return other >= *this;
  }

  /**
   * Checks whether the class implements a specific interface
   *
   * @param   interface  The interface
   * @return             Whether the class implements a specific interface
   */
  bool Object::implements(const std::string& interface) const
  {
    for (const std::string& elem : this->interface_inheritance)
      if (elem == interface)
	return true;
    return false;
  }

  /**
   * Gets the actual instance of this object
   *
   * @return  The actual instance of this object
   */
  void* Object::getActual() const
  {
    return this->actual_instance;
  }

  /**
   * Invoked on a custom event
   *
   * @param  action  The action name
   * @param  args    The action parameters
   */
  void Object::event(const std::string& action, void* args)
  {
    if ((this->event_handler))
      (*(this->event_handler))(this, action, args);
  }

  /**
   * Copy method
   *
   * @param  self      The object to modify
   * @param  original  The reference object
   */
  void Object::__copy__(Object& self, const Object& original)
  {
    self = original;
  }

  /**
   * Hash method
   *
   * @return  The object's hash code
   */
  size_t Object::hash() const
  {
    return (size_t)this;
  }

}

<commit_msg>interface_inheritance in copying and moving<commit_after>// -*- mode: c++ , coding: utf-8 -*-
/**
 * tbrpg – Text based roll playing game
 *
 * Copyright © 2012, 2013  Mattias Andrée (maandree@kth.se)
 *
 * 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 "Object.hpp"

/**
 * Text based roll playing game
 *
 * DD2387 Program construction with C++
 * Laboration 3
 *
 * @author  Mattias Andrée <maandree@kth.se>
 */
namespace tbrpg
{
  /**
   * Constructor
   */
  Object::Object()
  {
    this->class_inheritance = std::vector<short>();
    this->class_inheritance.push_back(0);
    this->actual_instance = (void*)this;
    this->interface_inheritance = std::vector<std::string>();
    this->event_handler = nullptr;
  }

  /**
   * Copy constructor
   *
   * @param  original  The object to clone
   */
  Object::Object(const Object& original)
  {
    this->class_inheritance = original.class_inheritance;
    this->actual_instance = original.actual_instance;
    this->interface_inheritance = original.interface_inheritance;
    this->event_handler = original.event_handler;
  }

  /**
   * Copy constructor
   *
   * @param  original  The object to clone
   */
  Object::Object(Object& original)
  {
    this->class_inheritance = original.class_inheritance;
    this->actual_instance = original.actual_instance;
    this->interface_inheritance = original.interface_inheritance;
    this->event_handler = original.event_handler;
  }

  /**
   * Move constructor
   *
   * @param  original  The object to clone
   */
  Object::Object(Object&& original)
  {
    std::swap(this->class_inheritance, original.class_inheritance);
    std::swap(this->actual_instance, original.actual_instance);
    std::swap(this->interface_inheritance, original.interface_inheritance);
    std::swap(this->event_handler, original.event_handler);
  }

  /**
   * Fork the object
   *
   * @return  A fork of the object
   */
  Object* Object::fork() const
  {
    return (Object*)(new Object(*this));
  }

  /**
   * Destructor
   */
  Object::~Object()
  {
    // do nothing
  }

  /**
   * Assignment operator
   *
   * @param   original  The reference object
   * @return            The invoked object
   */
  Object& Object::operator =(const Object& original)
  {
    this->class_inheritance = original.class_inheritance;
    this->actual_instance = original.actual_instance;
    this->interface_inheritance = original.interface_inheritance;
    this->event_handler = original.event_handler;
    return *this;
  }

  /**
   * Assignment operator
   *
   * @param   original  The reference object
   * @return            The invoked object
   */
  Object& Object::operator =(Object& original)
  {
    this->class_inheritance = original.class_inheritance;
    this->actual_instance = original.actual_instance;
    this->interface_inheritance = original.interface_inheritance;
    this->event_handler = original.event_handler;
    return *this;
  }

  /**
   * Move operator
   *
   * @param   original  The moved object, its resourced will be moved
   * @return            The invoked object
   */
  Object& Object::operator =(Object&& original)
  {
    std::swap(this->class_inheritance, original.class_inheritance);
    std::swap(this->actual_instance, original.actual_instance);
    std::swap(this->interface_inheritance, original.interface_inheritance);
    std::swap(this->event_handler, original.event_handler);
    return *this;
  }

  /**
   * Equality evaluator
   *
   * @param   other  The other comparand
   * @return         Whether the instances are equal
   */
  bool Object::operator ==(const Object& other) const
  {
    return this == &other;
  }

  /**
   * Inequality evaluator
   *
   * @param   other  The other comparand
   * @return         Whether the instances are not equal
   */
  bool Object::operator !=(const Object& other) const
  {
    return (*this == other) == false;
  }

  /**
   * 'Instance of' evaluator
   *
   * @param   other  The other comparand
   * @return         Whether the left comparand is an instance of the right comparand's class
   */
  bool Object::operator >=(const Object& other) const
  {
    if (this->class_inheritance.size() < other.class_inheritance.size())
      return false;

    for (size_t i = 0, n = other.class_inheritance.size(); i < n; i++)
      if (this->class_inheritance[i] != other.class_inheritance[i])
	return false;

    return true;
  }

  /**
   * Reversed 'instance of' evaluator
   *
   * @param   other  The other comparand
   * @return         Whether the right comparand is an instance of the left comparand's class
   */
  bool Object::operator <=(const Object& other) const
  {
    return other >= *this;
  }

  /**
   * Checks whether the class implements a specific interface
   *
   * @param   interface  The interface
   * @return             Whether the class implements a specific interface
   */
  bool Object::implements(const std::string& interface) const
  {
    for (const std::string& elem : this->interface_inheritance)
      if (elem == interface)
	return true;
    return false;
  }

  /**
   * Gets the actual instance of this object
   *
   * @return  The actual instance of this object
   */
  void* Object::getActual() const
  {
    return this->actual_instance;
  }

  /**
   * Invoked on a custom event
   *
   * @param  action  The action name
   * @param  args    The action parameters
   */
  void Object::event(const std::string& action, void* args)
  {
    if ((this->event_handler))
      (*(this->event_handler))(this, action, args);
  }

  /**
   * Copy method
   *
   * @param  self      The object to modify
   * @param  original  The reference object
   */
  void Object::__copy__(Object& self, const Object& original)
  {
    self = original;
  }

  /**
   * Hash method
   *
   * @return  The object's hash code
   */
  size_t Object::hash() const
  {
    return (size_t)this;
  }

}

<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <set>

#include "Search.h"
#include "Utils.h"

using namespace std;

//
// Static Variables
//
uint64_t nextId = 1;

// TODO(gabor) this is not threadsafe
inline uint64_t generateUniqueId() {
  nextId++;
}

//
// Class Path
//
Path::Path(const uint64_t id, const uint64_t source, const word* fact, const uint8_t factLength, const edge_type& edgeType)
    : edgeType(edgeType), sourceId(source), id(id),
      factLength(factLength)
    {
  for (int i = 0; i < factLength; ++i) {
    this->fact[i] = fact[i];
  }
};

Path::Path(const uint64_t source, const word* fact, const uint8_t factLength, const edge_type& edgeType)
    : edgeType(edgeType), sourceId(source),
      id(generateUniqueId()),
      factLength(factLength)
    {
  for (int i = 0; i < factLength; ++i) {
    this->fact[i] = fact[i];
  }
};

Path::Path(const Path& source, const word* fact, const uint8_t factLength, const edge_type& edgeType)
    : edgeType(edgeType), sourceId(source.id),
      id(generateUniqueId()),
      factLength(factLength)
    {
  for (int i = 0; i < factLength; ++i) {
    this->fact[i] = fact[i];
  }
};

Path::Path(const word* fact, const uint8_t factLength)
    : edgeType(255), sourceId(0),
      id(generateUniqueId()),
      factLength(factLength)
    {
  for (int i = 0; i < factLength; ++i) {
    this->fact[i] = fact[i];
  }
};

Path::Path(const Path& copy)
    : id(copy.id), sourceId(copy.sourceId), edgeType(copy.edgeType),
      factLength(copy.factLength)
    {
  for (int i = 0; i < copy.factLength; ++i) {
    this->fact[i] = copy.fact[i];
  }
};

Path::~Path() {
};

bool Path::operator==(const Path& other) const {
  // Check metadata
  if ( !( id == other.id && sourceId == other.sourceId &&
          edgeType == other.edgeType && factLength == other.factLength ) ) {
    return false;
  }
  // Check fact content
  for (int i = 0; i < factLength; ++i) {
    if (other.fact[i] != fact[i]) {
      return false;
    }
  }
  // Return true
  return true;
}

void Path::operator=(const Path& copy) {
  this->id = copy.id;
  this->sourceId = copy.sourceId;
  this->edgeType = copy.edgeType;
  this->factLength = copy.factLength;
  for (int i = 0; i < copy.factLength; ++i) {
    this->fact[i] = copy.fact[i];
  }
}

Path* Path::source(SearchType& queue) const {
  if (sourceId == 0) {
    return NULL;
  } else {
    return queue.findPathById(sourceId);
  }
}

//
// Class SearchType
//

//
// Class BreadthFirstSearch
//
BreadthFirstSearch::BreadthFirstSearch() {
  this->impl = new queue<Path>();
}

BreadthFirstSearch::~BreadthFirstSearch() {
  delete impl;
}

void BreadthFirstSearch::push(const Path& toAdd) {
  while (id2path.size() <= toAdd.id) {
    id2path.push_back(toAdd);
  }
  id2path[toAdd.id] = toAdd;
  impl->push(toAdd);
}

const Path BreadthFirstSearch::pop() {
  const Path frontElement = impl->front();
  impl->pop();
  return frontElement;
}

bool BreadthFirstSearch::isEmpty() {
  return impl->empty();
}

Path* BreadthFirstSearch::findPathById(uint64_t id) {
  return &id2path[id];
}

//
// Class UCSSearch
//
UCSSearch::UCSSearch() {
  this->impl = new priority_queue<Path, vector<Path>, PathCompare>();  // TODO(gabor) binomial_heap_tag
}

UCSSearch::~UCSSearch() {
  delete impl;
}

void UCSSearch::push(const Path& toAdd) {
  while (id2path.size() <= toAdd.id) {
    id2path.push_back(toAdd);
  }
  id2path[toAdd.id] = toAdd;
  impl->push(toAdd);
}

const Path UCSSearch::pop() {
  const Path frontElement = impl->top();
  impl->pop();
  return frontElement;
}

bool UCSSearch::isEmpty() {
  return impl->empty();
}

Path* UCSSearch::findPathById(uint64_t id) {
  return &id2path[id];
}

//
// Class CacheStrategy
//

//
// Class CacheStrategyNone
//
bool CacheStrategyNone::isSeen(const Path&) {
  return false;
}

void CacheStrategyNone::add(const Path&) { }

//
// Function search()
//
vector<Path*> Search(Graph* graph, FactDB* knownFacts,
                     const word* queryFact, const uint8_t queryFactLength,
                     SearchType* fringe, CacheStrategy* cache,
                     const uint64_t timeout) {
  //
  // Setup
  //
  // Create a vector for the return value to occupy
  vector<Path*> responses;
  // Add start state to the fringe
  fringe->push(Path(queryFact, queryFactLength));  // I need the memory to not go away
  // Initialize timer (number of elements popped from the fringe)
  uint64_t time = 0;
  const uint32_t tickTime = 1000;
  printf("started search.\n");

  //
  // Search
  //
  while (!fringe->isEmpty() && time < timeout) {
    // Get the next element from the fringe
    if (fringe->isEmpty()) {
      printf("IMPOSSIBLE: the search fringe is empty. This means (a) there are leaf nodes in the graph, and (b) this would have caused a memory leak.\n");
      std::exit(1);
    }
    const Path parent = fringe->pop();
    // Update time
    time += 1;
    printf("search tick %lu; popped %s\n", time, toString(*graph, *fringe, &parent).c_str());
    if (time % tickTime == 0) {
      const uint32_t tickOOM
        = tickTime < 1000 ? 1 : (tickTime < 1000000 ? 1000 : (tickTime  < 1000000000 ? 1000000 : 1) );
      printf("[%lu / %lu%s] search tick; %lu paths found\n",
             time / tickOOM, timeout / tickOOM,
             tickTime < 1000 ? "" : (tickTime < 1000000 ? "k" : (tickTime  < 1000000000 ? "m" : "") ),
             responses.size());
    }
    // Add the element to the cache
    cache->add(parent);

    // -- Check If Valid --
    if (knownFacts->contains(parent.fact, parent.factLength)) {
      Path* result = new Path(parent);
      printf("> %s\n", toString(*graph, *fringe, result).c_str());
      responses.push_back(result);
    }

    // -- Mutations --
    for (int indexToMutate = 0;
         indexToMutate < parent.factLength;
         ++indexToMutate) {  // for each index to mutate...
      const vector<edge>& mutations
        = graph->outgoingEdges(parent.fact[indexToMutate]);
      printf("  mutating index %d; %lu children\n", indexToMutate, mutations.size());
      for(vector<edge>::const_iterator it = mutations.begin();
          it != mutations.end();
          ++it) {  // for each possible mutation on that index...
        if (it->type == 9) { continue; } // TODO(gabor) don't ignore nearest neighbors
        // ... create the mutated fact
        word mutated[parent.factLength];
        for (int i = 0; i < indexToMutate; ++i) {
          mutated[i] = parent.fact[i];
        }
        mutated[indexToMutate] = it->sink;
        for (int i = indexToMutate + 1; i < parent.factLength; ++i) {
          mutated[i] = parent.fact[i];
        }
        // Create the corresponding search state
        Path child(parent, mutated, parent.factLength, it->type);
        // Add the state to the fringe
        if (!cache->isSeen(child)) {
          fringe->push(child);
        }
      }
    }

  }

  printf("Search complete; %lu paths found\n", responses.size());
  return responses;
}

<commit_msg>Limit search to wordnet jumps<commit_after>#include <cstdio>
#include <cstdlib>
#include <set>

#include "Search.h"
#include "Utils.h"

using namespace std;

//
// Static Variables
//
uint64_t nextId = 1;

// TODO(gabor) this is not threadsafe
inline uint64_t generateUniqueId() {
  nextId++;
}

//
// Class Path
//
Path::Path(const uint64_t id, const uint64_t source, const word* fact, const uint8_t factLength, const edge_type& edgeType)
    : edgeType(edgeType), sourceId(source), id(id),
      factLength(factLength)
    {
  for (int i = 0; i < factLength; ++i) {
    this->fact[i] = fact[i];
  }
};

Path::Path(const uint64_t source, const word* fact, const uint8_t factLength, const edge_type& edgeType)
    : edgeType(edgeType), sourceId(source),
      id(generateUniqueId()),
      factLength(factLength)
    {
  for (int i = 0; i < factLength; ++i) {
    this->fact[i] = fact[i];
  }
};

Path::Path(const Path& source, const word* fact, const uint8_t factLength, const edge_type& edgeType)
    : edgeType(edgeType), sourceId(source.id),
      id(generateUniqueId()),
      factLength(factLength)
    {
  for (int i = 0; i < factLength; ++i) {
    this->fact[i] = fact[i];
  }
};

Path::Path(const word* fact, const uint8_t factLength)
    : edgeType(255), sourceId(0),
      id(generateUniqueId()),
      factLength(factLength)
    {
  for (int i = 0; i < factLength; ++i) {
    this->fact[i] = fact[i];
  }
};

Path::Path(const Path& copy)
    : id(copy.id), sourceId(copy.sourceId), edgeType(copy.edgeType),
      factLength(copy.factLength)
    {
  for (int i = 0; i < copy.factLength; ++i) {
    this->fact[i] = copy.fact[i];
  }
};

Path::~Path() {
};

bool Path::operator==(const Path& other) const {
  // Check metadata
  if ( !( id == other.id && sourceId == other.sourceId &&
          edgeType == other.edgeType && factLength == other.factLength ) ) {
    return false;
  }
  // Check fact content
  for (int i = 0; i < factLength; ++i) {
    if (other.fact[i] != fact[i]) {
      return false;
    }
  }
  // Return true
  return true;
}

void Path::operator=(const Path& copy) {
  this->id = copy.id;
  this->sourceId = copy.sourceId;
  this->edgeType = copy.edgeType;
  this->factLength = copy.factLength;
  for (int i = 0; i < copy.factLength; ++i) {
    this->fact[i] = copy.fact[i];
  }
}

Path* Path::source(SearchType& queue) const {
  if (sourceId == 0) {
    return NULL;
  } else {
    return queue.findPathById(sourceId);
  }
}

//
// Class SearchType
//

//
// Class BreadthFirstSearch
//
BreadthFirstSearch::BreadthFirstSearch() {
  this->impl = new queue<Path>();
}

BreadthFirstSearch::~BreadthFirstSearch() {
  delete impl;
}

void BreadthFirstSearch::push(const Path& toAdd) {
  while (id2path.size() <= toAdd.id) {
    id2path.push_back(toAdd);
  }
  id2path[toAdd.id] = toAdd;
  impl->push(toAdd);
}

const Path BreadthFirstSearch::pop() {
  const Path frontElement = impl->front();
  impl->pop();
  return frontElement;
}

bool BreadthFirstSearch::isEmpty() {
  return impl->empty();
}

Path* BreadthFirstSearch::findPathById(uint64_t id) {
  return &id2path[id];
}

//
// Class UCSSearch
//
UCSSearch::UCSSearch() {
  this->impl = new priority_queue<Path, vector<Path>, PathCompare>();  // TODO(gabor) binomial_heap_tag
}

UCSSearch::~UCSSearch() {
  delete impl;
}

void UCSSearch::push(const Path& toAdd) {
  while (id2path.size() <= toAdd.id) {
    id2path.push_back(toAdd);
  }
  id2path[toAdd.id] = toAdd;
  impl->push(toAdd);
}

const Path UCSSearch::pop() {
  const Path frontElement = impl->top();
  impl->pop();
  return frontElement;
}

bool UCSSearch::isEmpty() {
  return impl->empty();
}

Path* UCSSearch::findPathById(uint64_t id) {
  return &id2path[id];
}

//
// Class CacheStrategy
//

//
// Class CacheStrategyNone
//
bool CacheStrategyNone::isSeen(const Path&) {
  return false;
}

void CacheStrategyNone::add(const Path&) { }

//
// Function search()
//
vector<Path*> Search(Graph* graph, FactDB* knownFacts,
                     const word* queryFact, const uint8_t queryFactLength,
                     SearchType* fringe, CacheStrategy* cache,
                     const uint64_t timeout) {
  //
  // Setup
  //
  // Create a vector for the return value to occupy
  vector<Path*> responses;
  // Add start state to the fringe
  fringe->push(Path(queryFact, queryFactLength));  // I need the memory to not go away
  // Initialize timer (number of elements popped from the fringe)
  uint64_t time = 0;
  const uint32_t tickTime = 1000;
  printf("started search.\n");

  //
  // Search
  //
  while (!fringe->isEmpty() && time < timeout) {
    // Get the next element from the fringe
    if (fringe->isEmpty()) {
      printf("IMPOSSIBLE: the search fringe is empty. This means (a) there are leaf nodes in the graph, and (b) this would have caused a memory leak.\n");
      std::exit(1);
    }
    const Path parent = fringe->pop();
    // Update time
    time += 1;
    printf("search tick %lu; popped %s\n", time, toString(*graph, *fringe, &parent).c_str());
    if (time % tickTime == 0) {
      const uint32_t tickOOM
        = tickTime < 1000 ? 1 : (tickTime < 1000000 ? 1000 : (tickTime  < 1000000000 ? 1000000 : 1) );
      printf("[%lu / %lu%s] search tick; %lu paths found\n",
             time / tickOOM, timeout / tickOOM,
             tickTime < 1000 ? "" : (tickTime < 1000000 ? "k" : (tickTime  < 1000000000 ? "m" : "") ),
             responses.size());
    }
    // Add the element to the cache
    cache->add(parent);

    // -- Check If Valid --
    if (knownFacts->contains(parent.fact, parent.factLength)) {
      Path* result = new Path(parent);
      printf("> %s\n", toString(*graph, *fringe, result).c_str());
      responses.push_back(result);
    }

    // -- Mutations --
    for (int indexToMutate = 0;
         indexToMutate < parent.factLength;
         ++indexToMutate) {  // for each index to mutate...
      const vector<edge>& mutations
        = graph->outgoingEdges(parent.fact[indexToMutate]);
      printf("  mutating index %d; %lu children\n", indexToMutate, mutations.size());
      for(vector<edge>::const_iterator it = mutations.begin();
          it != mutations.end();
          ++it) {  // for each possible mutation on that index...
        if (it->type > 1) { continue; } // TODO(gabor) don't only do WordNet jumps
        // ... create the mutated fact
        word mutated[parent.factLength];
        for (int i = 0; i < indexToMutate; ++i) {
          mutated[i] = parent.fact[i];
        }
        mutated[indexToMutate] = it->sink;
        for (int i = indexToMutate + 1; i < parent.factLength; ++i) {
          mutated[i] = parent.fact[i];
        }
        // Create the corresponding search state
        Path child(parent, mutated, parent.factLength, it->type);
        // Add the state to the fringe
        if (!cache->isSeen(child)) {
          fringe->push(child);
        }
      }
    }

  }

  printf("Search complete; %lu paths found\n", responses.size());
  return responses;
}

<|endoftext|>