<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "RectNode.h"

#include "NodeDefinition.h"

#include "../graphics/VertexArray.h"
#include "../base/Exception.h"
#include "../base/MathHelper.h"

#include <iostream>
#include <sstream>

using namespace std;

namespace avg {

NodeDefinition RectNode::createDefinition()
{
    return NodeDefinition("rect", Node::buildNode<RectNode>)
        .extendDefinition(VectorNode::createDefinition())
        .addArg(Arg<double>("x", 0, false, offsetof(RectNode, m_Rect.tl.x)))
        .addArg(Arg<double>("y", 0, false, offsetof(RectNode, m_Rect.tl.y)))
        .addArg(Arg<double>("width", 0))
        .addArg(Arg<double>("height", 0))
        .addArg(Arg<double>("angle", 0.0, false, offsetof(RectNode, m_Angle)))
        .addArg(Arg<double>("fillopacity", 0, false,
                offsetof(RectNode, m_FillOpacity)))
        .addArg(Arg<string>("fillcolor", "FFFFFF", false,
                offsetof(RectNode, m_sFillColorName)));
}

RectNode::RectNode(const ArgList& Args, bool bFromXML)
    : VectorNode(Args)
{
    Args.setMembers(this);
    m_Rect.setWidth(Args.getArgVal<double>("width"));
    m_Rect.setHeight(Args.getArgVal<double>("height"));
    m_FillColor = colorStringToColor(m_sFillColorName);
}

RectNode::~RectNode()
{
}

double RectNode::getX() const
{
    return m_Rect.tl.x;
}

void RectNode::setX(double x)
{
    double w = m_Rect.width();
    m_Rect.tl.x = x;
    m_Rect.setWidth(w);
    setDrawNeeded(true);
}

double RectNode::getY() const
{
    return m_Rect.tl.y;
}

void RectNode::setY(double y)
{
    double h = m_Rect.height();
    m_Rect.tl.y = y;
    m_Rect.setHeight(h);
    setDrawNeeded(true);
}

const DPoint& RectNode::getPos() const
{
    return m_Rect.tl;
}

void RectNode::setPos(const DPoint& pt)
{
    double w = m_Rect.width();
    double h = m_Rect.height();
    m_Rect.tl = pt;
    m_Rect.setHeight(w);
    m_Rect.setHeight(h);
    setDrawNeeded(true);
}

double RectNode::getWidth() const
{
    return m_Rect.width();
}

void RectNode::setWidth(double w)
{
    m_Rect.setWidth(w);
    setDrawNeeded(true);
}

double RectNode::getHeight() const
{
    return m_Rect.height();
}

void RectNode::setHeight(double h)
{
    m_Rect.setHeight(h);
    setDrawNeeded(true);
}

DPoint RectNode::getSize() const
{
    return m_Rect.size();
}

void RectNode::setSize(const DPoint& pt)
{
    m_Rect.setWidth(pt.x);
    m_Rect.setHeight(pt.y);
    setDrawNeeded(true);
}

double RectNode::getAngle() const
{
    return m_Angle;
}

void RectNode::setAngle(double angle)
{
    m_Angle = fmod(angle, 2*PI);
    setDrawNeeded(true);
}

double RectNode::getFillOpacity() const
{
    return m_FillOpacity;
}

void RectNode::setFillOpacity(double opacity)
{
    m_FillOpacity = opacity;
    setDrawNeeded(true);
}

void RectNode::setFillColor(const string& sFillColor)
{
    if (m_sFillColorName != sFillColor) {
        m_sFillColorName = sFillColor;
        m_FillColor = colorStringToColor(m_sFillColorName);
        setDrawNeeded(true);
    }
}

const string& RectNode::getFillColor() const
{
    return m_sFillColorName;
}

int RectNode::getNumVertexes()
{
    return 4*5;
}

int RectNode::getNumIndexes()
{
    return 6*5;
}

void RectNode::updateData(VertexArrayPtr& pVertexArray, int curVertex, int curIndex,
        double opacity, bool bParentDrawNeeded)
{
    if (isDrawNeeded() || bParentDrawNeeded) {
        double curOpacity = opacity*m_FillOpacity;
        Pixel32 color = m_FillColor;
        color.setA((unsigned char)(curOpacity*255));

        DPoint pivot = m_Rect.tl+m_Rect.size()/2;

        DPoint p1 = m_Rect.tl;
        DPoint p2(m_Rect.tl.x, m_Rect.br.y);
        DPoint p3 = m_Rect.br;
        DPoint p4(m_Rect.br.x, m_Rect.tl.y);
        DPoint rp1 = rotate(p1, m_Angle, pivot);
        DPoint rp2 = rotate(p2, m_Angle, pivot);
        DPoint rp3 = rotate(p3, m_Angle, pivot);
        DPoint rp4 = rotate(p4, m_Angle, pivot);
        pVertexArray->setPos(curVertex, rp1, DPoint(0,0), color);
        pVertexArray->setPos(curVertex+1, rp2, DPoint(0,0), color);
        pVertexArray->setPos(curVertex+2, rp3, DPoint(0,0), color);
        pVertexArray->setPos(curVertex+3, rp4, DPoint(0,0), color);
        pVertexArray->setIndex(curIndex, curVertex);
        pVertexArray->setIndex(curIndex+1, curVertex+1);
        pVertexArray->setIndex(curIndex+2, curVertex+2);
        pVertexArray->setIndex(curIndex+3, curVertex);
        pVertexArray->setIndex(curIndex+4, curVertex+2);
        pVertexArray->setIndex(curIndex+5, curVertex+3);

        updateLineData(pVertexArray, curVertex+4, curIndex+6, opacity, rp1, rp2);
        updateLineData(pVertexArray, curVertex+8, curIndex+12, opacity, rp3, rp4);
        p1.x -= getStrokeWidth()/2;
        p2.x -= getStrokeWidth()/2;
        p3.x += getStrokeWidth()/2;
        p4.x += getStrokeWidth()/2;
        rp1 = rotate(p1, m_Angle, pivot);
        rp2 = rotate(p2, m_Angle, pivot);
        rp3 = rotate(p3, m_Angle, pivot);
        rp4 = rotate(p4, m_Angle, pivot);
        updateLineData(pVertexArray, curVertex+12, curIndex+18, opacity, rp2, rp3);
        updateLineData(pVertexArray, curVertex+16, curIndex+24, opacity, rp4, rp1);
    }
    setDrawNeeded(false);
}

}
<commit_msg>bugfix: rectnode setPos()<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2008 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "RectNode.h"

#include "NodeDefinition.h"

#include "../graphics/VertexArray.h"
#include "../base/Exception.h"
#include "../base/MathHelper.h"

#include <iostream>
#include <sstream>

using namespace std;

namespace avg {

NodeDefinition RectNode::createDefinition()
{
    return NodeDefinition("rect", Node::buildNode<RectNode>)
        .extendDefinition(VectorNode::createDefinition())
        .addArg(Arg<double>("x", 0, false, offsetof(RectNode, m_Rect.tl.x)))
        .addArg(Arg<double>("y", 0, false, offsetof(RectNode, m_Rect.tl.y)))
        .addArg(Arg<double>("width", 0))
        .addArg(Arg<double>("height", 0))
        .addArg(Arg<double>("angle", 0.0, false, offsetof(RectNode, m_Angle)))
        .addArg(Arg<double>("fillopacity", 0, false,
                offsetof(RectNode, m_FillOpacity)))
        .addArg(Arg<string>("fillcolor", "FFFFFF", false,
                offsetof(RectNode, m_sFillColorName)));
}

RectNode::RectNode(const ArgList& Args, bool bFromXML)
    : VectorNode(Args)
{
    Args.setMembers(this);
    m_Rect.setWidth(Args.getArgVal<double>("width"));
    m_Rect.setHeight(Args.getArgVal<double>("height"));
    m_FillColor = colorStringToColor(m_sFillColorName);
}

RectNode::~RectNode()
{
}

double RectNode::getX() const
{
    return m_Rect.tl.x;
}

void RectNode::setX(double x)
{
    double w = m_Rect.width();
    m_Rect.tl.x = x;
    m_Rect.setWidth(w);
    setDrawNeeded(true);
}

double RectNode::getY() const
{
    return m_Rect.tl.y;
}

void RectNode::setY(double y)
{
    double h = m_Rect.height();
    m_Rect.tl.y = y;
    m_Rect.setHeight(h);
    setDrawNeeded(true);
}

const DPoint& RectNode::getPos() const
{
    return m_Rect.tl;
}

void RectNode::setPos(const DPoint& pt)
{
    double w = m_Rect.width();
    double h = m_Rect.height();
    m_Rect.tl = pt;
    m_Rect.setWidth(w);
    m_Rect.setHeight(h);
    setDrawNeeded(true);
}

double RectNode::getWidth() const
{
    return m_Rect.width();
}

void RectNode::setWidth(double w)
{
    m_Rect.setWidth(w);
    setDrawNeeded(true);
}

double RectNode::getHeight() const
{
    return m_Rect.height();
}

void RectNode::setHeight(double h)
{
    m_Rect.setHeight(h);
    setDrawNeeded(true);
}

DPoint RectNode::getSize() const
{
    return m_Rect.size();
}

void RectNode::setSize(const DPoint& pt)
{
    m_Rect.setWidth(pt.x);
    m_Rect.setHeight(pt.y);
    setDrawNeeded(true);
}

double RectNode::getAngle() const
{
    return m_Angle;
}

void RectNode::setAngle(double angle)
{
    m_Angle = fmod(angle, 2*PI);
    setDrawNeeded(true);
}

double RectNode::getFillOpacity() const
{
    return m_FillOpacity;
}

void RectNode::setFillOpacity(double opacity)
{
    m_FillOpacity = opacity;
    setDrawNeeded(true);
}

void RectNode::setFillColor(const string& sFillColor)
{
    if (m_sFillColorName != sFillColor) {
        m_sFillColorName = sFillColor;
        m_FillColor = colorStringToColor(m_sFillColorName);
        setDrawNeeded(true);
    }
}

const string& RectNode::getFillColor() const
{
    return m_sFillColorName;
}

int RectNode::getNumVertexes()
{
    return 4*5;
}

int RectNode::getNumIndexes()
{
    return 6*5;
}

void RectNode::updateData(VertexArrayPtr& pVertexArray, int curVertex, int curIndex,
        double opacity, bool bParentDrawNeeded)
{
    if (isDrawNeeded() || bParentDrawNeeded) {
        double curOpacity = opacity*m_FillOpacity;
        Pixel32 color = m_FillColor;
        color.setA((unsigned char)(curOpacity*255));

        DPoint pivot = m_Rect.tl+m_Rect.size()/2;

        DPoint p1 = m_Rect.tl;
        DPoint p2(m_Rect.tl.x, m_Rect.br.y);
        DPoint p3 = m_Rect.br;
        DPoint p4(m_Rect.br.x, m_Rect.tl.y);
        DPoint rp1 = rotate(p1, m_Angle, pivot);
        DPoint rp2 = rotate(p2, m_Angle, pivot);
        DPoint rp3 = rotate(p3, m_Angle, pivot);
        DPoint rp4 = rotate(p4, m_Angle, pivot);
        pVertexArray->setPos(curVertex, rp1, DPoint(0,0), color);
        pVertexArray->setPos(curVertex+1, rp2, DPoint(0,0), color);
        pVertexArray->setPos(curVertex+2, rp3, DPoint(0,0), color);
        pVertexArray->setPos(curVertex+3, rp4, DPoint(0,0), color);
        pVertexArray->setIndex(curIndex, curVertex);
        pVertexArray->setIndex(curIndex+1, curVertex+1);
        pVertexArray->setIndex(curIndex+2, curVertex+2);
        pVertexArray->setIndex(curIndex+3, curVertex);
        pVertexArray->setIndex(curIndex+4, curVertex+2);
        pVertexArray->setIndex(curIndex+5, curVertex+3);

        updateLineData(pVertexArray, curVertex+4, curIndex+6, opacity, rp1, rp2);
        updateLineData(pVertexArray, curVertex+8, curIndex+12, opacity, rp3, rp4);
        p1.x -= getStrokeWidth()/2;
        p2.x -= getStrokeWidth()/2;
        p3.x += getStrokeWidth()/2;
        p4.x += getStrokeWidth()/2;
        rp1 = rotate(p1, m_Angle, pivot);
        rp2 = rotate(p2, m_Angle, pivot);
        rp3 = rotate(p3, m_Angle, pivot);
        rp4 = rotate(p4, m_Angle, pivot);
        updateLineData(pVertexArray, curVertex+12, curIndex+18, opacity, rp2, rp3);
        updateLineData(pVertexArray, curVertex+16, curIndex+24, opacity, rp4, rp1);
    }
    setDrawNeeded(false);
}

}
<|endoftext|>


<commit_before>/*!
  \copyright (c) RDO-Team, 2012
  \file      simulator/compiler/parser/rdo_logic_base.cpp
  \authors     (rdo@rk9.bmstu.ru)
  \authors     (impus@hotbox.ru)
  \date      5.02.2012
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "simulator/compiler/parser/pch.h"
// ----------------------------------------------------------------------- INCLUDES
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/compiler/parser/rdoparser.h"
#include "simulator/compiler/parser/rdo_logic_base.h"
#include "simulator/runtime/rdo_priority.h"
// --------------------------------------------------------------------------------

OPEN_RDO_PARSER_NAMESPACE

// --------------------------------------------------------------------------------
// -------------------- RDOLogicBase
// --------------------------------------------------------------------------------
RDOLogicBase::RDOLogicBase(CREF(RDOParserSrcInfo) src_info)
	: RDOParserSrcInfo(src_info)
{}

RDOLogicBase::~RDOLogicBase()
{}

CREF(tstring) RDOLogicBase::name() const
{
	return src_info().src_text();
}

rbool RDOLogicBase::setPrior(REF(LPRDOFUNArithm) pPrior)
{
	LPIPriority pPriority = m_pRuntimeLogic;
	if (pPriority)
	{
		return pPriority->setPrior(pPrior->createCalc());
	}
	return false;
}

rbool RDOLogicBase::getMultithreading() const
{
	return m_multithreading;
}

void RDOLogicBase::setMultithreading(rbool multithreading)
{
	m_multithreading = multithreading;
}

void RDOLogicBase::setCondition(CREF(LPRDOFUNLogic) pConditon)
{
	m_pConditon = pConditon;
}

LPRDOFUNLogic RDOLogicBase::getConditon() const
{
	return m_pConditon;
}

LPILogic RDOLogicBase::getLogic() const
{
	return m_pRuntimeLogic;
}

void RDOLogicBase::end()
{
	if (getConditon())
	{
		m_pRuntimeLogic->setCondition(getConditon()->getCalc());
	}
	m_pRuntimeLogic->setMultithreading(m_multithreading);
	RDOParser::s_parser()->contextStack()->pop();
}

CLOSE_RDO_PARSER_NAMESPACE
<commit_msg> - добавлена инициализация<commit_after>/*!
  \copyright (c) RDO-Team, 2012
  \file      simulator/compiler/parser/rdo_logic_base.cpp
  \authors     (rdo@rk9.bmstu.ru)
  \authors     (impus@hotbox.ru)
  \date      5.02.2012
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
#include "simulator/compiler/parser/pch.h"
// ----------------------------------------------------------------------- INCLUDES
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/compiler/parser/rdoparser.h"
#include "simulator/compiler/parser/rdo_logic_base.h"
#include "simulator/runtime/rdo_priority.h"
// --------------------------------------------------------------------------------

OPEN_RDO_PARSER_NAMESPACE

// --------------------------------------------------------------------------------
// -------------------- RDOLogicBase
// --------------------------------------------------------------------------------
RDOLogicBase::RDOLogicBase(CREF(RDOParserSrcInfo) src_info)
	: RDOParserSrcInfo(src_info)
	, m_multithreading(false   )
{}

RDOLogicBase::~RDOLogicBase()
{}

CREF(tstring) RDOLogicBase::name() const
{
	return src_info().src_text();
}

rbool RDOLogicBase::setPrior(REF(LPRDOFUNArithm) pPrior)
{
	LPIPriority pPriority = m_pRuntimeLogic;
	if (pPriority)
	{
		return pPriority->setPrior(pPrior->createCalc());
	}
	return false;
}

rbool RDOLogicBase::getMultithreading() const
{
	return m_multithreading;
}

void RDOLogicBase::setMultithreading(rbool multithreading)
{
	m_multithreading = multithreading;
}

void RDOLogicBase::setCondition(CREF(LPRDOFUNLogic) pConditon)
{
	m_pConditon = pConditon;
}

LPRDOFUNLogic RDOLogicBase::getConditon() const
{
	return m_pConditon;
}

LPILogic RDOLogicBase::getLogic() const
{
	return m_pRuntimeLogic;
}

void RDOLogicBase::end()
{
	if (getConditon())
	{
		m_pRuntimeLogic->setCondition(getConditon()->getCalc());
	}
	m_pRuntimeLogic->setMultithreading(m_multithreading);
	RDOParser::s_parser()->contextStack()->pop();
}

CLOSE_RDO_PARSER_NAMESPACE
<|endoftext|>


<commit_before>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Rüdiger Sonderfeld

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "flusspferd/class.hpp"
#include "flusspferd/create.hpp"
#include "flusspferd/security.hpp"
#include "flusspferd/modules.hpp"
#include <gmpxx.h>

using namespace flusspferd;

namespace {

namespace multi_precission {
struct Integer : public flusspferd::native_object_base {
  struct class_info : flusspferd::class_info {
    static char const *constructor_name() {
      return "Integer";
    }

    static char const *full_name() {
      return "Integer";
    }

    static object create_prototype() {
      flusspferd::object proto = flusspferd::create_object();
      create_native_method(proto, "fits_int", &Integer::fits_int);
      create_native_method(proto, "get_int", &Integer::get_int);
      create_native_method(proto, "get_double", &Integer::get_double);
      create_native_method(proto, "get_string", &Integer::get_string);
      create_native_method(proto, "get_string_base", &Integer::get_string_base);
      create_native_method(proto, "sqrt", &Integer::sqrt);
      create_native_method(proto, "sgn", &Integer::sgn);
      create_native_method(proto, "abs", &Integer::abs);
      return proto;
    }
  };
  mpz_class mp;

  Integer(flusspferd::object const &self, mpz_class const &mp)
    : flusspferd::native_object_base(self), mp(mp)
  { }

  Integer(flusspferd::object const &self, flusspferd::call_context &x)
    : flusspferd::native_object_base(self)
  {
    if(x.arg.size() == 1) {
      value v = x.arg.front();
      if(v.is_double())
        mp = v.get_double();
      else if(v.is_int())
        mp = v.get_int();
      else if(v.is_string())
        mp = v.to_std_string();
      else
        mp = flusspferd::get_native<Integer>(v.get_object()).mp;
    }
    else if(x.arg.size() == 2) {
      value v = x.arg.front();
      value u = x.arg.back();
      if(v.is_string() && u.is_int())
        mp.set_str(v.to_std_string(), u.get_int());
      else
        throw flusspferd::exception("Wrong arguments! (string, int) expected.");
    }
    else
      throw flusspferd::exception("Wrong number of arguments!");
  }

  bool fits_int() /*const*/ {
    return mp.fits_sint_p();
  }
  int get_int() /*const*/ {
    assert(fits_int());
    return mp.get_si();
  }
  double get_double() /*const*/ {
    return mp.get_d();
  }
  std::string get_string() /*const*/ {
    return mp.get_str();
  }
  std::string get_string_base(int base) /*const*/ {
    return mp.get_str(base);
  }

  template<typename T>
  Integer &create_integer(T mp) /*const*/ {
    return create_native_object<Integer>(object(), mpz_class(mp));
  }

  // this should be external but js doesn't support overloading!
  Integer &sqrt() /*const*/ {
    return create_integer(::sqrt(mp));
  }

  int sgn() /*const*/ {
    return ::sgn(mp);
  }

  Integer &abs() /*const*/ {
    return create_integer(::abs(mp));
  }
};

struct Float : public flusspferd::native_object_base {
  struct class_info : flusspferd::class_info {
    static char const *constructor_name() {
      return "Float";
    }

    static char const *full_name() {
      return "Float";
    }

    static object create_prototype() {
      flusspferd::object proto = flusspferd::create_object();
      create_native_method(proto, "fits_int", &Float::fits_int);
      create_native_method(proto, "get_int", &Float::get_int);
      create_native_method(proto, "get_double", &Float::get_double);
      create_native_method(proto, "get_string", &Float::get_string);
      create_native_method(proto, "get_string_base", &Float::get_string_base);
      create_native_method(proto, "get_prec", &Float::get_prec);
      create_native_method(proto, "set_prec", &Float::set_prec);
      create_native_method(proto, "sqrt", &Float::sqrt);
      create_native_method(proto, "sgn", &Float::sgn);
      create_native_method(proto, "abs", &Float::abs);
      create_native_method(proto, "ceil", &Float::ceil);
      create_native_method(proto, "floor", &Float::floor);
      create_native_method(proto, "trunc", &Float::trunc);
      create_native_method(proto, "cmp", &Float::cmp);
      create_native_method(proto, "add", &Float::add);
      create_native_method(proto, "sub", &Float::sub);
      create_native_method(proto, "mul", &Float::mul);
      create_native_method(proto, "div", &Float::div);
      return proto;
    }
  };
  mpf_class mp;

  Float(flusspferd::object const &self, mpf_class const &mp)
    : flusspferd::native_object_base(self), mp(mp)
  { }

  void init_with_value(value v) {
    if(v.is_double())
      mp = v.get_double();
    else if(v.is_int())
      mp = v.get_int();
    else if(v.is_string())
      mp = v.to_std_string();
    else
      mp = flusspferd::get_native<Float>(v.get_object()).mp;
  }

  Float(flusspferd::object const &self, flusspferd::call_context &x)
    : flusspferd::native_object_base(self)
  {
    if(x.arg.size() == 1) {
      init_with_value(x.arg.front());
    }
    else if(x.arg.size() == 2) {
      value v = x.arg.front();
      value u = x.arg.back();
      if(v.is_string() && u.is_int())
        mp.set_str(v.to_std_string(), u.get_int());
      else {
        mp.set_prec(u.get_int());
        init_with_value(v);
      }
    }
    else if(x.arg.size() == 3) {
      value v = x.arg[0];
      value u = x.arg[1];
      value w = x.arg[2];
      if(v.is_string() && u.is_int() && w.is_int()) {
        mp.set_prec(u.get_int());
        mp.set_str(v.to_std_string(), w.get_int());
      }
      else
        throw flusspferd::exception("Wrong arguments! (string, int, int) expected.");
    }
    else
      throw flusspferd::exception("Wrong number of arguments!");
  }

  bool fits_int() /*const*/ {
    return mp.fits_sint_p();
  }
  int get_int() /*const*/ {
    assert(fits_int());
    return mp.get_si();
  }
  double get_double() /*const*/ {
    return mp.get_d();
  }
  std::string get_string() /*const*/ {
    mp_exp_t expo; // TODO handle expo
    return mp.get_str(expo);
  }
  std::string get_string_base(int base) /*const*/ {
    mp_exp_t expo; // TODO handle expo
    return mp.get_str(expo, base);
  }
  int get_prec() /*const*/ {
    return mp.get_prec();
  }
  void set_prec(int p) {
    mp.set_prec(p);
  }

  template<typename T>
  Float &create_float(T mp) /*const*/ {
    return create_native_object<Float>(object(), mpf_class(mp));
  }

  // this should be external but js doesn't support overloading!
  Float &sqrt() /*const*/ {
    return create_float(::sqrt(mp));
  }

  int sgn() /*const*/ {
    return ::sgn(mp);
  }

  Float &abs() /*const*/ {
    return create_float(::abs(mp));
  }

  Float &ceil() /*const*/ {
    return create_float(::ceil(mp));
  }

  Float &floor() /*const*/ {
    return create_float(::floor(mp));
  }

  // hypot

  Float &trunc() /*const*/ {
    return create_float(::trunc(mp));
  }

  // operators
  void cmp(flusspferd::call_context &x) {
    if(x.arg.empty() || x.arg.size() > 1)
      throw flusspferd::exception("Expected one parameter!");
    value v = x.arg.front();
    if(v.is_int())
      x.result = ::cmp(v.get_int(), mp);
    else if(v.is_double())
      x.result = ::cmp(v.get_double(), mp);
    else
      x.result = ::cmp(flusspferd::get_native<Float>(v.get_object()).mp, mp);
  }

  Float &add(Float const &f) { // TODO Integer
    return create_float(mp + f.mp);
  }

  Float &sub(Float const &f) { // TODO Integer
    return create_float(mp - f.mp);
  }

  Float &mul(Float const &f) { // TODO Integer
    return create_float(mp * f.mp);
  }

  Float &div(Float const &f) { // TODO Integer
    return create_float(mp / f.mp);
  }
};
}

}/*namespace*/

FLUSSPFERD_LOADER(gmp) {
  load_class<multi_precission::Integer>(gmp);
  // TODO Rational
  load_class<multi_precission::Float>(gmp);
}
<commit_msg>plugins.gmp: fixed cmp<commit_after>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Rüdiger Sonderfeld

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "flusspferd/class.hpp"
#include "flusspferd/create.hpp"
#include "flusspferd/security.hpp"
#include "flusspferd/modules.hpp"
#include <gmpxx.h>

using namespace flusspferd;

namespace {

namespace multi_precission {
struct Integer : public flusspferd::native_object_base {
  struct class_info : flusspferd::class_info {
    static char const *constructor_name() {
      return "Integer";
    }

    static char const *full_name() {
      return "Integer";
    }

    static object create_prototype() {
      flusspferd::object proto = flusspferd::create_object();
      create_native_method(proto, "fits_int", &Integer::fits_int);
      create_native_method(proto, "get_int", &Integer::get_int);
      create_native_method(proto, "get_double", &Integer::get_double);
      create_native_method(proto, "get_string", &Integer::get_string);
      create_native_method(proto, "get_string_base", &Integer::get_string_base);
      create_native_method(proto, "sqrt", &Integer::sqrt);
      create_native_method(proto, "sgn", &Integer::sgn);
      create_native_method(proto, "abs", &Integer::abs);
      return proto;
    }
  };
  mpz_class mp;

  Integer(flusspferd::object const &self, mpz_class const &mp)
    : flusspferd::native_object_base(self), mp(mp)
  { }

  Integer(flusspferd::object const &self, flusspferd::call_context &x)
    : flusspferd::native_object_base(self)
  {
    if(x.arg.size() == 1) {
      value v = x.arg.front();
      if(v.is_double())
        mp = v.get_double();
      else if(v.is_int())
        mp = v.get_int();
      else if(v.is_string())
        mp = v.to_std_string();
      else
        mp = flusspferd::get_native<Integer>(v.get_object()).mp;
    }
    else if(x.arg.size() == 2) {
      value v = x.arg.front();
      value u = x.arg.back();
      if(v.is_string() && u.is_int())
        mp.set_str(v.to_std_string(), u.get_int());
      else
        throw flusspferd::exception("Wrong arguments! (string, int) expected.");
    }
    else
      throw flusspferd::exception("Wrong number of arguments!");
  }

  bool fits_int() /*const*/ {
    return mp.fits_sint_p();
  }
  int get_int() /*const*/ {
    assert(fits_int());
    return mp.get_si();
  }
  double get_double() /*const*/ {
    return mp.get_d();
  }
  std::string get_string() /*const*/ {
    return mp.get_str();
  }
  std::string get_string_base(int base) /*const*/ {
    return mp.get_str(base);
  }

  template<typename T>
  Integer &create_integer(T mp) /*const*/ {
    return create_native_object<Integer>(object(), mpz_class(mp));
  }

  // this should be external but js doesn't support overloading!
  Integer &sqrt() /*const*/ {
    return create_integer(::sqrt(mp));
  }

  int sgn() /*const*/ {
    return ::sgn(mp);
  }

  Integer &abs() /*const*/ {
    return create_integer(::abs(mp));
  }
};

struct Float : public flusspferd::native_object_base {
  struct class_info : flusspferd::class_info {
    static char const *constructor_name() {
      return "Float";
    }

    static char const *full_name() {
      return "Float";
    }

    static object create_prototype() {
      flusspferd::object proto = flusspferd::create_object();
      create_native_method(proto, "fits_int", &Float::fits_int);
      create_native_method(proto, "get_int", &Float::get_int);
      create_native_method(proto, "get_double", &Float::get_double);
      create_native_method(proto, "get_string", &Float::get_string);
      create_native_method(proto, "get_string_base", &Float::get_string_base);
      create_native_method(proto, "get_prec", &Float::get_prec);
      create_native_method(proto, "set_prec", &Float::set_prec);
      create_native_method(proto, "sqrt", &Float::sqrt);
      create_native_method(proto, "sgn", &Float::sgn);
      create_native_method(proto, "abs", &Float::abs);
      create_native_method(proto, "ceil", &Float::ceil);
      create_native_method(proto, "floor", &Float::floor);
      create_native_method(proto, "trunc", &Float::trunc);
      create_native_method(proto, "cmp", &Float::cmp);
      create_native_method(proto, "add", &Float::add);
      create_native_method(proto, "sub", &Float::sub);
      create_native_method(proto, "mul", &Float::mul);
      create_native_method(proto, "div", &Float::div);
      return proto;
    }
  };
  mpf_class mp;

  Float(flusspferd::object const &self, mpf_class const &mp)
    : flusspferd::native_object_base(self), mp(mp)
  { }

  void init_with_value(value v) {
    if(v.is_double())
      mp = v.get_double();
    else if(v.is_int())
      mp = v.get_int();
    else if(v.is_string())
      mp = v.to_std_string();
    else
      mp = flusspferd::get_native<Float>(v.get_object()).mp;
  }

  Float(flusspferd::object const &self, flusspferd::call_context &x)
    : flusspferd::native_object_base(self)
  {
    if(x.arg.size() == 1) {
      init_with_value(x.arg.front());
    }
    else if(x.arg.size() == 2) {
      value v = x.arg.front();
      value u = x.arg.back();
      if(v.is_string() && u.is_int())
        mp.set_str(v.to_std_string(), u.get_int());
      else {
        mp.set_prec(u.get_int());
        init_with_value(v);
      }
    }
    else if(x.arg.size() == 3) {
      value v = x.arg[0];
      value u = x.arg[1];
      value w = x.arg[2];
      if(v.is_string() && u.is_int() && w.is_int()) {
        mp.set_prec(u.get_int());
        mp.set_str(v.to_std_string(), w.get_int());
      }
      else
        throw flusspferd::exception("Wrong arguments! (string, int, int) expected.");
    }
    else
      throw flusspferd::exception("Wrong number of arguments!");
  }

  bool fits_int() /*const*/ {
    return mp.fits_sint_p();
  }
  int get_int() /*const*/ {
    assert(fits_int());
    return mp.get_si();
  }
  double get_double() /*const*/ {
    return mp.get_d();
  }
  std::string get_string() /*const*/ {
    mp_exp_t expo; // TODO handle expo
    return mp.get_str(expo);
  }
  std::string get_string_base(int base) /*const*/ {
    mp_exp_t expo; // TODO handle expo
    return mp.get_str(expo, base);
  }
  int get_prec() /*const*/ {
    return mp.get_prec();
  }
  void set_prec(int p) {
    mp.set_prec(p);
  }

  template<typename T>
  Float &create_float(T mp) /*const*/ {
    return create_native_object<Float>(object(), mpf_class(mp));
  }

  // this should be external but js doesn't support overloading!
  Float &sqrt() /*const*/ {
    return create_float(::sqrt(mp));
  }

  int sgn() /*const*/ {
    return ::sgn(mp);
  }

  Float &abs() /*const*/ {
    return create_float(::abs(mp));
  }

  Float &ceil() /*const*/ {
    return create_float(::ceil(mp));
  }

  Float &floor() /*const*/ {
    return create_float(::floor(mp));
  }

  // hypot

  Float &trunc() /*const*/ {
    return create_float(::trunc(mp));
  }

  // operators
  void cmp(flusspferd::call_context &x) {
    if(x.arg.empty() || x.arg.size() > 1)
      throw flusspferd::exception("Expected one parameter!");
    value v = x.arg.front();
    if(v.is_int())
      x.result = ::cmp(mp, v.get_int());
    else if(v.is_double())
      x.result = ::cmp(mp, v.get_double());
    else
      x.result = ::cmp(mp, flusspferd::get_native<Float>(v.get_object()).mp);
  }

  Float &add(Float const &f) { // TODO Integer
    return create_float(mp + f.mp);
  }

  Float &sub(Float const &f) { // TODO Integer
    return create_float(mp - f.mp);
  }

  Float &mul(Float const &f) { // TODO Integer
    return create_float(mp * f.mp);
  }

  Float &div(Float const &f) { // TODO Integer
    return create_float(mp / f.mp);
  }
};
}

}/*namespace*/

FLUSSPFERD_LOADER(gmp) {
  load_class<multi_precission::Integer>(gmp);
  // TODO Rational
  load_class<multi_precission::Float>(gmp);
}
<|endoftext|>


<commit_before>/**
 *  @file server.cpp
 *  @author Shae Bolt, CS3800 Section A
 *  @author Jordan Giacone, CS3800 Section B
 *  @date Apr 25, 2016
 *  @brief Description: The server file to handle multiple
 *  clients sending messages to one another
 *  @details Details:
 */

#include <string.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>
#include <signal.h>

//server port
#define SERVER_PORT 9993
//max number of clients
#define MAX_CLIENT 100

//handles clients on a per client basis and is responsible for sending messages out to all clients
//these threads are removed if a client disconnects or the server is shutdown
void *client_messenger(void* arg);

//handles signal processing for cntrlc which closes the entire server given a message
void cntrlc_signal_handle(int signal);

//mutex for stop variable
pthread_mutex_t stop_lock;
//mutex for file descriptor array
pthread_mutex_t file_descriptor_lock;
//stop variable to end the server
bool stop = false;
//stream_socket = socket,
//temp_fd = temporaray file descriptor
//k = temporary size variable for write and
//reads for the amount written
int stream_socket, temp_fd, k;
//server address
struct sockaddr_in server_addr;
//client address
struct sockaddr_in client_addr;
//client length
unsigned int client_len;
//host pointer
char *host;
//file descriptor arrays for client connections
int file_descriptor_array[MAX_CLIENT]; /* allocate as many file descriptors
 as the number of clients  */
pthread_t client_handlers[100];
//counter for the number of current connections
int counter;

int main()
{
  //signals cntrlc quit
  signal(SIGINT, cntrlc_signal_handle);
  server_addr =
  { AF_INET, htons( SERVER_PORT)};
  client_addr =
  { AF_INET};
  client_len = sizeof(client_addr);

  counter = 0;

  /* create a stream socket */
  if ((stream_socket = socket( AF_INET, SOCK_STREAM, 0)) == -1)
  {
    perror("server: socket failed");
    exit(1);
  }
  int enable = 1;
  /* setting socket to be resuable incase of previous runt */
  if (setsockopt(stream_socket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))
      < 0)
  {
    perror("setsockopt(SO_REUSEADDR) failed");
  }

  /* bind the socket to an internet port */
  if (bind(stream_socket, (struct sockaddr*) &server_addr, sizeof(server_addr))
      == -1)
  {
    perror("server: bind failed");
    exit(1);
  }

  //listening for the server
  if (listen(stream_socket, 10) == -1)
  {
    perror("server: listen failed");
    exit(1);
  }
  //checking for client connections to accept
  printf("SERVER is listening for clients to establish a connection\n");
  while (((temp_fd = accept(stream_socket, (struct sockaddr*) &client_addr,
      &client_len)) > 0) && !stop)
  {
    pthread_mutex_lock(&file_descriptor_lock);
    if (counter < MAX_CLIENT)
    {
      file_descriptor_array[counter] = temp_fd;
      pthread_create(&client_handlers[counter], NULL, client_messenger,
          (void*) &file_descriptor_array[counter]);
      pthread_mutex_unlock(&file_descriptor_lock);
      counter++;
    }
    else
    {
      std::cerr << "Error too many threads" << std::endl;
    }
  }

  close(stream_socket);
  unlink((const char*) &server_addr.sin_addr);

  return (0);
}

void cntrlc_signal_handle(int signal)
{
  std::cout << "\nCNTRLC detected" << std::endl;

  char message_buffer[512] =
      "WARNING: The server will shut down in 10 seconds\n";
  char quit_msg[32] = "/quit";
  for (int i = 0; i < counter; i++)
  {

    write(file_descriptor_array[i], message_buffer, sizeof(message_buffer));

  }
  for (int i = 0; i < counter; i++)
  {

    write(file_descriptor_array[i], quit_msg, sizeof(quit_msg));
  }
  sleep(10);
  pthread_mutex_lock(&stop_lock);
  stop = true;
  pthread_mutex_unlock(&stop_lock);

  for (int i = 0; i < counter; i++)
  {

    pthread_cancel(client_handlers[i]);

  }
  close(stream_socket);
  unlink((const char*) &server_addr.sin_addr);

}

void *client_messenger(void* arg) /* what does 'bob' do ? */
{
  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
  printf(
      "Child accept() successful.. a client has connected to child ! waiting for a message\n");
  //buffer for read in messages
  char buf[512];
  //this is FD, fd, or file descriptor
  int some_fd = *(int*) arg;

  char host_name[100];
  gethostname(host_name, 100);
  char client_name[512];
  char message_buffer[100 + 512];
  char server_message[100];

  while ((k = read(some_fd, buf, sizeof(buf))) != 0)
  {
    strcpy(message_buffer, "User ");
    strcpy(client_name, buf);
    strncat(message_buffer, client_name, 512);
    strncat(message_buffer, " has joined the channel\n", 3);
    //printf("GIVEN MESSAGE: %s\n", buf);

    pthread_mutex_lock(&file_descriptor_lock);
    for (int i = 0; i < counter; i++)
    {
      if (file_descriptor_array[i] != some_fd)
      {

        write(file_descriptor_array[i], message_buffer, sizeof(message_buffer));
      }
    }
    pthread_mutex_unlock(&file_descriptor_lock);
    break;
  }
  while ((k = read(some_fd, buf, sizeof(buf))) != 0 && !stop)
  {
    bzero(message_buffer, 512 + 100);
    printf("SERVER RECEIVED: %s\n", buf);
    if (strcmp(buf, "/quit") == 0)
    {
      break;
    }

    strcpy(message_buffer, ">> ");
    strncat(message_buffer, client_name, sizeof(client_name));
    strncat(message_buffer, ": ", 8);
    strncat(message_buffer, buf, 512);
    strncat(message_buffer, "\n", 3);

    pthread_mutex_lock(&file_descriptor_lock);

    for (int i = 0; i < counter; i++)
    {
      if (file_descriptor_array[i] != some_fd)
      {

        write(file_descriptor_array[i], message_buffer, sizeof(message_buffer));
      }
    }

    pthread_mutex_unlock(&file_descriptor_lock);
    pthread_yield();
  }

  pthread_mutex_lock(&file_descriptor_lock);
  bzero(message_buffer, 512 + 100);
  strcpy(message_buffer, "User ");
  strncat(message_buffer, client_name, sizeof(client_name));
  strncat(message_buffer, " has disconnected.", 24);
  for (int i = 0; i < counter; i++)
  {
    if (file_descriptor_array[i] != some_fd)
    {

      write(file_descriptor_array[i], message_buffer, sizeof(message_buffer));
    }
  }
  int i = 0;
  while ((file_descriptor_array[i] != some_fd))
  {
    i++;
  }
  counter--;
  for (int j = i; j < counter; j++)
  {
    file_descriptor_array[j] = file_descriptor_array[j - 1];
  }
  pthread_mutex_unlock(&file_descriptor_lock);
  close(some_fd);
  std::cout << "\n EXITING THREAD" << std::endl;
  pthread_exit(0);
}
<commit_msg>asdfa<commit_after>/**
 *  @file server.cpp
 *  @author Shae Bolt, CS3800 Section A
 *  @author Jordan Giacone, CS3800 Section B
 *  @date Apr 25, 2016
 *  @brief Description: The server file to handle multiple
 *  clients sending messages to one another
 *  @details Details:
 */

#include <string.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pthread.h>
#include <signal.h>

//server port
#define SERVER_PORT 9993
//max number of clients
#define MAX_CLIENT 100

//handles clients on a per client basis and is responsible for sending messages out to all clients
//these threads are removed if a client disconnects or the server is shutdown
void *client_messenger(void* arg);

//handles signal processing for cntrlc which closes the entire server given a message
void cntrlc_signal_handle(int signal);

//mutex for stop variable
pthread_mutex_t stop_lock;
//mutex for file descriptor array
pthread_mutex_t file_descriptor_lock;
//stop variable to end the server
bool stop = false;
//stream_socket = socket,
//temp_fd = temporaray file descriptor
//k = temporary size variable for write and
//reads for the amount written
int stream_socket, temp_fd, k;
//server address
struct sockaddr_in server_addr;
//client address
struct sockaddr_in client_addr;
//client length
unsigned int client_len;
//host pointer
char *host;
//file descriptor arrays for client connections
int file_descriptor_array[MAX_CLIENT]; /* allocate as many file descriptors
 as the number of clients  */
pthread_t client_handlers[100];
//counter for the number of current connections
int counter;

int main()
{
  //signals cntrlc quit
  signal(SIGINT, cntrlc_signal_handle);
  server_addr =
  { AF_INET, htons( SERVER_PORT)};
  client_addr =
  { AF_INET};
  client_len = sizeof(client_addr);

  counter = 0;

  /* create a stream socket */
  if ((stream_socket = socket( AF_INET, SOCK_STREAM, 0)) == -1)
  {
    perror("server: socket failed");
    exit(1);
  }
  int enable = 1;
  /* setting socket to be resuable incase of previous runt */
  if (setsockopt(stream_socket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))
      < 0)
  {
    perror("setsockopt(SO_REUSEADDR) failed");
  }

  /* bind the socket to an internet port */
  if (bind(stream_socket, (struct sockaddr*) &server_addr, sizeof(server_addr))
      == -1)
  {
    perror("server: bind failed");
    exit(1);
  }

  //listening for the server
  if (listen(stream_socket, 10) == -1)
  {
    perror("server: listen failed");
    exit(1);
  }
  //checking for client connections to accept
  printf("SERVER is listening for clients to establish a connection\n");
  while (((temp_fd = accept(stream_socket, (struct sockaddr*) &client_addr,
      &client_len)) > 0) && !stop)
  {
    pthread_mutex_lock(&file_descriptor_lock);
    if (counter < MAX_CLIENT)
    {
      file_descriptor_array[counter] = temp_fd;
      pthread_create(&client_handlers[counter], NULL, client_messenger,
          (void*) &file_descriptor_array[counter]);
      pthread_mutex_unlock(&file_descriptor_lock);
      counter++;
    }
    else
    {
      std::cerr << "Error too many threads" << std::endl;
    }
  }

  close(stream_socket);
  unlink((const char*) &server_addr.sin_addr);

  return (0);
}

void cntrlc_signal_handle(int signal)
{
  std::cout << "\nCNTRLC detected" << std::endl;

  char message_buffer[512] =
      "WARNING: The server will shut down in 10 seconds\n";
  char quit_msg[32] = "/quit";
  for (int i = 0; i < counter; i++)
  {

    write(file_descriptor_array[i], message_buffer, sizeof(message_buffer));

  }
  for (int i = 0; i < counter; i++)
  {

    write(file_descriptor_array[i], quit_msg, sizeof(quit_msg));
  }
  sleep(10);
  pthread_mutex_lock(&stop_lock);
  stop = true;
  pthread_mutex_unlock(&stop_lock);

  for (int i = 0; i < counter; i++)
  {

    pthread_cancel(client_handlers[i]);

  }
  close(stream_socket);
  unlink((const char*) &server_addr.sin_addr);

}

void *client_messenger(void* arg) /* what does 'bob' do ? */
{
  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
  printf(
      "Child accept() successful.. a client has connected to child ! waiting for a message\n");
  //buffer for read in messages
  char buf[512];
  //this is FD, fd, or file descriptor
  int some_fd = *(int*) arg;

  char host_name[100];
  gethostname(host_name, 100);
  char client_name[512];
  char message_buffer[100 + 512];
  char server_message[100];

  while ((k = read(some_fd, buf, sizeof(buf))) != 0)
  {
    strcpy(message_buffer, "User ");
    strcpy(client_name, buf);
    strncat(message_buffer, client_name, 512);
    strncat(message_buffer, " has joined the channel\n", 512);
    //printf("GIVEN MESSAGE: %s\n", buf);

    pthread_mutex_lock(&file_descriptor_lock);
    for (int i = 0; i < counter; i++)
    {
      if (file_descriptor_array[i] != some_fd)
      {

        write(file_descriptor_array[i], message_buffer, sizeof(message_buffer));
      }
    }
    pthread_mutex_unlock(&file_descriptor_lock);
    break;
  }
  while ((k = read(some_fd, buf, sizeof(buf))) != 0 && !stop)
  {
    bzero(message_buffer, 512 + 100);
    printf("SERVER RECEIVED: %s\n", buf);
    if (strcmp(buf, "/quit") == 0)
    {
      break;
    }

    strcpy(message_buffer, ">> ");
    strncat(message_buffer, client_name, sizeof(client_name));
    strncat(message_buffer, ": ", 8);
    strncat(message_buffer, buf, 512);
    strncat(message_buffer, "\n", 3);

    pthread_mutex_lock(&file_descriptor_lock);

    for (int i = 0; i < counter; i++)
    {
      if (file_descriptor_array[i] != some_fd)
      {

        write(file_descriptor_array[i], message_buffer, sizeof(message_buffer));
      }
    }

    pthread_mutex_unlock(&file_descriptor_lock);
    pthread_yield();
  }

  pthread_mutex_lock(&file_descriptor_lock);
  bzero(message_buffer, 512 + 100);
  strcpy(message_buffer, "User ");
  strncat(message_buffer, client_name, sizeof(client_name));
  strncat(message_buffer, " has disconnected.", 24);
  for (int i = 0; i < counter; i++)
  {
    if (file_descriptor_array[i] != some_fd)
    {

      write(file_descriptor_array[i], message_buffer, sizeof(message_buffer));
    }
  }
  int i = 0;
  while ((file_descriptor_array[i] != some_fd))
  {
    i++;
  }
  counter--;
  for (int j = i; j < counter; j++)
  {
    file_descriptor_array[j] = file_descriptor_array[j - 1];
  }
  pthread_mutex_unlock(&file_descriptor_lock);
  close(some_fd);
  std::cout << "\n EXITING THREAD" << std::endl;
  pthread_exit(0);
}
<|endoftext|>


<commit_before>#include "state.h"
#include "math.h"

namespace gparse {

const std::string State::OP_G1   = "G1";
const std::string State::OP_G20  = "G20";
const std::string State::OP_G21  = "G21";
const std::string State::OP_G90  = "G90";
const std::string State::OP_G91  = "G91";
const std::string State::OP_M21  = "M21";
const std::string State::OP_M105 = "M105";
const std::string State::OP_M110 = "M110";

State::State(const drv::Driver &drv) {
	this->positionMode = POS_ABSOLUTE;
	this->unitMode = UNIT_MM;
	this->_destXPrimitive = 0;
	this->_destYPrimitive = 0;
	this->_destZPrimitive = 0;
	this->_destEPrimitive = 0;
	this->setDestMoveRatePrimitive(drv.defaultMoveRate());
	this->setDestFeedRatePrimitive(drv.defaultFeedRate());
}

void State::setPositionMode(PositionMode mode) {
	this->positionMode = mode;
}

void State::setUnitMode(LengthUnit mode) {
	this->unitMode = mode;
}

float State::xUnitToAbsolute(float posUnit) const {
	switch (this->positionMode) {
		case POS_RELATIVE:
			posUnit += this->_destXPrimitive;
			break;
		case POS_ABSOLUTE:
		default:
			break; //no transformation needed.
	}
	return posUnit;
}
float State::yUnitToAbsolute(float posUnit) const {
	switch (this->positionMode) {
		case POS_RELATIVE:
			posUnit += this->_destYPrimitive;
			break;
		case POS_ABSOLUTE:
		default:
			break; //no transformation needed.
	}
	return posUnit;
}
float State::zUnitToAbsolute(float posUnit) const {
	switch (this->positionMode) {
		case POS_RELATIVE:
			posUnit += this->_destZPrimitive;
			break;
		case POS_ABSOLUTE:
		default:
			break; //no transformation needed.
	}
	return posUnit;
}
float State::eUnitToAbsolute(float posUnit) const {
	switch (this->positionMode) {
		case POS_RELATIVE:
			posUnit += this->_destEPrimitive;
			break;
		case POS_ABSOLUTE:
		default:
			break; //no transformation needed.
	}
	return posUnit;
}
float State::posUnitToMM(float posUnit) const {
	switch (this->unitMode) {
		case UNIT_IN:
			return gparse::math::MM_PER_IN * posUnit;
		case UNIT_MM:
		default: //impossible case.
			return posUnit;
	}
}

float State::xUnitToPrimitive(float posUnit) const {
	return posUnitToMM(xUnitToAbsolute(posUnit));
}
float State::yUnitToPrimitive(float posUnit) const {
	return posUnitToMM(yUnitToAbsolute(posUnit));
}
float State::zUnitToPrimitive(float posUnit) const {
	return posUnitToMM(zUnitToAbsolute(posUnit));
}
float State::eUnitToPrimitive(float posUnit) const {
	return posUnitToMM(eUnitToAbsolute(posUnit));
}
float State::fUnitToPrimitive(float posUnit) const {
	return posUnitToMM(posUnit); //feed rate is always relative, so no need to call toAbsolute
}

float State::destXPrimitive() const {
	return this->_destXPrimitive;
}
float State::destYPrimitive() const {
	return this->_destYPrimitive;
}
float State::destZPrimitive() const {
	return this->_destZPrimitive;
}
float State::destEPrimitive() const {
	return this->_destEPrimitive;
}
float State::destMoveRatePrimitive() const {
	return this->_destMoveRatePrimitive;
}
void State::setDestMoveRatePrimitive(float f) {
	this->_destMoveRatePrimitive = f;
}
float State::destFeedRatePrimitive() const {
	return this->_destFeedRatePrimitive;
}
void State::setDestFeedRatePrimitive(float f) {
	this->_destFeedRatePrimitive = f;
}

}
<commit_msg>Use initialization list<commit_after>#include "state.h"
#include "math.h"

namespace gparse {

const std::string State::OP_G1   = "G1";
const std::string State::OP_G20  = "G20";
const std::string State::OP_G21  = "G21";
const std::string State::OP_G90  = "G90";
const std::string State::OP_G91  = "G91";
const std::string State::OP_M21  = "M21";
const std::string State::OP_M105 = "M105";
const std::string State::OP_M110 = "M110";

State::State(const drv::Driver &drv) : positionMode(POS_ABSOLUTE), unitMode(UNIT_MM),
	_destXPrimitive(0), _destYPrimitive(0), _destZPrimitive(0), _destEPrimitive(0) {
	this->setDestMoveRatePrimitive(drv.defaultMoveRate());
	this->setDestFeedRatePrimitive(drv.defaultFeedRate());
}

void State::setPositionMode(PositionMode mode) {
	this->positionMode = mode;
}

void State::setUnitMode(LengthUnit mode) {
	this->unitMode = mode;
}

float State::xUnitToAbsolute(float posUnit) const {
	switch (this->positionMode) {
		case POS_RELATIVE:
			posUnit += this->_destXPrimitive;
			break;
		case POS_ABSOLUTE:
		default:
			break; //no transformation needed.
	}
	return posUnit;
}
float State::yUnitToAbsolute(float posUnit) const {
	switch (this->positionMode) {
		case POS_RELATIVE:
			posUnit += this->_destYPrimitive;
			break;
		case POS_ABSOLUTE:
		default:
			break; //no transformation needed.
	}
	return posUnit;
}
float State::zUnitToAbsolute(float posUnit) const {
	switch (this->positionMode) {
		case POS_RELATIVE:
			posUnit += this->_destZPrimitive;
			break;
		case POS_ABSOLUTE:
		default:
			break; //no transformation needed.
	}
	return posUnit;
}
float State::eUnitToAbsolute(float posUnit) const {
	switch (this->positionMode) {
		case POS_RELATIVE:
			posUnit += this->_destEPrimitive;
			break;
		case POS_ABSOLUTE:
		default:
			break; //no transformation needed.
	}
	return posUnit;
}
float State::posUnitToMM(float posUnit) const {
	switch (this->unitMode) {
		case UNIT_IN:
			return gparse::math::MM_PER_IN * posUnit;
		case UNIT_MM:
		default: //impossible case.
			return posUnit;
	}
}

float State::xUnitToPrimitive(float posUnit) const {
	return posUnitToMM(xUnitToAbsolute(posUnit));
}
float State::yUnitToPrimitive(float posUnit) const {
	return posUnitToMM(yUnitToAbsolute(posUnit));
}
float State::zUnitToPrimitive(float posUnit) const {
	return posUnitToMM(zUnitToAbsolute(posUnit));
}
float State::eUnitToPrimitive(float posUnit) const {
	return posUnitToMM(eUnitToAbsolute(posUnit));
}
float State::fUnitToPrimitive(float posUnit) const {
	return posUnitToMM(posUnit); //feed rate is always relative, so no need to call toAbsolute
}

float State::destXPrimitive() const {
	return this->_destXPrimitive;
}
float State::destYPrimitive() const {
	return this->_destYPrimitive;
}
float State::destZPrimitive() const {
	return this->_destZPrimitive;
}
float State::destEPrimitive() const {
	return this->_destEPrimitive;
}
float State::destMoveRatePrimitive() const {
	return this->_destMoveRatePrimitive;
}
void State::setDestMoveRatePrimitive(float f) {
	this->_destMoveRatePrimitive = f;
}
float State::destFeedRatePrimitive() const {
	return this->_destFeedRatePrimitive;
}
void State::setDestFeedRatePrimitive(float f) {
	this->_destFeedRatePrimitive = f;
}

}
<|endoftext|>


<commit_before>#include <Arduino.h>
#include <roboteqMC.h>

AX2550::AX2550(HardwareSerial& serial_port):uart(serial_port)
{
   uart.begin(9600,SERIAL_7E1);
}

void AX2550::init(uint8_t x,uint8_t y){
   x_key = x;
   y_key = y;
}

void AX2550::set_report(uint8_t v,uint8_t l,uint8_t r){
   volt_key = v;
   amps_left_key = l;
   amps_right_key = r;
}

bool AX2550::move(int Steering,int Throttle, bool check)
{
   int8_t Dir1 = 0;
   int8_t Dir2 = 0;
   while(uart.available()>0)
   {
      uart.read();
   }
   if(Throttle>=0)
   {
      Dir1 = 0x41;
   }
   if(Throttle<0)
   {
      Dir1 = 0x61;
   }
   if(Steering>=0)
   {
      Dir2 = 0x42;
   }
   if(Steering<0)
   {
      Dir2 = 0x62;
   }

   Throttle = map(abs(Throttle),0,100,0,126);

   Steering = map(abs(Steering),0,100,0,126);

   char command[12];
   sprintf(command,"!%c%02x\r\n!%c%02x\r\n",Dir1,abs(Throttle),Dir2,abs(Steering));
   uart.print(command);

   if(check){
      delay(10);

      bool chk_throttle = chkResponse();
      bool chk_steering = chkResponse();

      while(uart.available()>0){
         uart.read();
      }
      return chk_throttle & chk_steering;
   }

   return true;
}

bool AX2550::move(Message inp, bool check){
   if(inp.new_data(y_key) || inp.new_data(x_key)){
      return move(int16_t(inp.get_data(y_key)),int16_t(inp.get_data(x_key)),check);
   }
   return false;
}

bool AX2550::chkResponse()
{
   char status;
   uint8_t counter=0;
   while(1)
   {
      status = uart.read();
      //Serial.print(status);
      if(status == '+')
      {
         return true;
      }
      else if(status == '-')
      {
         //Serial.println("Command Fails!");
         return false;
      }
      else if(counter == 20)
      {
         Serial3.println("Chk response Timeout");
         return false;
      }
      else
      {
         counter+=1;
         delay(1);
      }
   }
}

float AX2550::volt()
{
   while(uart.available())
   {
      uart.read();
   }
   char command[2];
   sprintf(command,"?e");
   if(sendChk(command))
   {
      char inp[4];
/*
      while(uart.available()){
         Serial.println(char(uart.read()));
      }

      uart.read();
      uart.read();
      uart.read();
      uart.read();

      inp[0] = '0';
      inp[1] = 'x';
      inp[2] = char(uart.read());
      inp[3] = char(uart.read());

      // Serial.println(inp[0]);
      // Serial.println(inp[1]);
      // Serial.println(inp[2]);
      // Serial.println(inp[3]);

*/
      uart.read();

      inp[0] = '0';
      inp[1] = 'x';
      inp[2] = char(uart.read());
      inp[3] = char(uart.read());

      uart.read();
      uart.read();
      uart.read();

      uint16_t conv = strtoul(inp,0,16);

      Serial.println(conv);

      float volt = 55 * conv/256.0;

      Serial.println(volt);

      delay(10);

      while(uart.available())
      {
         uart.read();
      }

      return volt;
   }
   return 0.0;
}

int AX2550::amps(uint8_t channel)
{
   while(uart.available())
   {
      uart.read();
   }

   char command[2];
   sprintf(command,"?a");

   if(sendChk(command))
   {
      char inp[2];

     if(channel == 1)
     {
         uart.read();

         inp[0] = '0';
         inp[1] = 'x';
         inp[2] = char(uart.read());
         inp[3] = char(uart.read());
      }

     if(channel == 2)
     {
         uart.read();
         uart.read();
         uart.read();
         uart.read();

         inp[0] = '0';
         inp[1] = 'x';
         inp[2] = char(uart.read());
         inp[3] = char(uart.read());
      }

      // Serial.println(inp[0]);
      // Serial.println(inp[1]);
      // Serial.println(inp[2]);
      // Serial.println(inp[3]);

      int amps = strtoul(inp,0,16);

      // Serial.println(volt);

      delay(10);

      while(uart.available())
      {
         uart.read();
      }
      return amps;
   }
   // Serial.println("Fail!");
   return 0;
}

bool AX2550::sendChk(char buff[])
{
   uint8_t lenght = strlen(buff);
   char input_buff[lenght];
   uart.println(buff);

   uint8_t counter=0;
   uint8_t timeout=100;

   delay(10);

   while(1)
   {
      if(uart.available()>0)
      {
         for(int i=0;i<lenght;i++)
         {
            input_buff[i]=uart.read();
            if(input_buff[i]!=buff[i])
            {
               //Echo Condition
               // Serial.println("Echo Error!");
               return false;
            }
         }
         return true;
      }
      else if(counter == timeout)
      {
         //Timeout condition
         // Serial.println("Timeout Error!");
         return false;
      }
      else
      {
         counter+=1;
         delay(1);
      }
   }
}

Message AX2550::report(){
   Message output;
   output.add_data(amps_left_key,uint16_t(amps(1)));
   output.add_data(amps_right_key,uint16_t(amps(2)));
   output.add_data(volt_key,uint16_t(volt()));
   return output;
}<commit_msg>Update<commit_after>#include <Arduino.h>
#include <roboteqMC.h>

AX2550::AX2550(HardwareSerial& serial_port):uart(serial_port)
{
   uart.begin(9600,SERIAL_7E1);
}

void AX2550::init(uint8_t x,uint8_t y){
   x_key = x;
   y_key = y;
}

void AX2550::set_report(uint8_t v,uint8_t l,uint8_t r){
   volt_key = v;
   amps_left_key = l;
   amps_right_key = r;
}

bool AX2550::move(int Steering,int Throttle, bool check)
{
   int8_t Dir1 = 0;
   int8_t Dir2 = 0;
   while(uart.available()>0)
   {
      uart.read();
   }
   if(Throttle>=0)
   {
      Dir1 = 0x41;
   }
   if(Throttle<0)
   {
      Dir1 = 0x61;
   }
   if(Steering>=0)
   {
      Dir2 = 0x42;
   }
   if(Steering<0)
   {
      Dir2 = 0x62;
   }

   Throttle = map(abs(Throttle),0,100,0,126);

   Steering = map(abs(Steering),0,100,0,126);

   char command[12];
   sprintf(command,"!%c%02x\r\n!%c%02x\r\n",Dir1,abs(Throttle),Dir2,abs(Steering));
   uart.print(command);

   if(check){
      delay(10);

      bool chk_throttle = chkResponse();
      bool chk_steering = chkResponse();

      while(uart.available()>0){
         uart.read();
      }
      return chk_throttle & chk_steering;
   }

   return true;
}

bool AX2550::move(Message inp, bool check){
   if(inp.new_data(y_key) || inp.new_data(x_key)){
      return move(int16_t(inp.get_data(y_key)),int16_t(inp.get_data(x_key)),check);
   }
   return false;
}

bool AX2550::chkResponse()
{
   char status;
   uint8_t counter=0;
   while(1)
   {
      status = uart.read();
      //Serial.print(status);
      if(status == '+')
      {
         return true;
      }
      else if(status == '-')
      {
         //Serial.println("Command Fails!");
         return false;
      }
      else if(counter == 20)
      {
         Serial3.println("Chk response Timeout");
         return false;
      }
      else
      {
         counter+=1;
         delay(1);
      }
   }
}

float AX2550::volt()
{
   while(uart.available())
   {
      uart.read();
   }
   char command[2];
   sprintf(command,"?e");
   if(sendChk(command))
   {
      char convert[4];
/*
      while(uart.available()){
         Serial.println(char(uart.read()));
      }

      uart.read();
      uart.read();
      uart.read();
      uart.read();

      inp[0] = '0';
      inp[1] = 'x';
      inp[2] = char(uart.read());
      inp[3] = char(uart.read());

      // Serial.println(inp[0]);
      // Serial.println(inp[1]);
      // Serial.println(inp[2]);
      // Serial.println(inp[3]);

*/
      uart.read();

      convert[0] = '0';
      convert[1] = 'x';
      convert[2] = char(uart.read());
      convert[3] = char(uart.read());

      uart.read();
      uart.read();
      uart.read();

/*

      Serial.println("--- ---");
      Serial.println(convert[0]);
      Serial.println(convert[1]);
      Serial.println(convert[2]);
      Serial.println(convert[3]);
      Serial.println("--- ---");

*/

      uint16_t conv = strtoul(convert,NULL,16);

      //Serial.println(conv);
      //Serial.println("--- ---");
      float volt = 55 * (conv/256.0);
      //Serial.println(volt);

      delay(10);

      while(uart.available())
      {
         uart.read();
      }

      return volt;
   }
   return 0.0;
}

int AX2550::amps(uint8_t channel)
{
   while(uart.available())
   {
      uart.read();
   }

   char command[2];
   sprintf(command,"?a");

   if(sendChk(command))
   {
      char inp[2];

     if(channel == 1)
     {
         uart.read();

         inp[0] = '0';
         inp[1] = 'x';
         inp[2] = char(uart.read());
         inp[3] = char(uart.read());
      }

     if(channel == 2)
     {
         uart.read();
         uart.read();
         uart.read();
         uart.read();

         inp[0] = '0';
         inp[1] = 'x';
         inp[2] = char(uart.read());
         inp[3] = char(uart.read());
      }

      // Serial.println(inp[0]);
      // Serial.println(inp[1]);
      // Serial.println(inp[2]);
      // Serial.println(inp[3]);

      int amps = strtoul(inp,0,16);

      // Serial.println(volt);

      delay(10);

      while(uart.available())
      {
         uart.read();
      }
      return amps;
   }
   // Serial.println("Fail!");
   return 0;
}

bool AX2550::sendChk(char buff[])
{
   uint8_t lenght = strlen(buff);
   char input_buff[lenght];
   uart.println(buff);

   uint8_t counter=0;
   uint8_t timeout=100;

   delay(10);

   while(1)
   {
      if(uart.available()>0)
      {
         for(int i=0;i<lenght;i++)
         {
            input_buff[i]=uart.read();
            if(input_buff[i]!=buff[i])
            {
               //Echo Condition
               // Serial.println("Echo Error!");
               return false;
            }
         }
         return true;
      }
      else if(counter == timeout)
      {
         //Timeout condition
         // Serial.println("Timeout Error!");
         return false;
      }
      else
      {
         counter+=1;
         delay(1);
      }
   }
}

Message AX2550::report(){
   Message output;
   output.add_data(amps_left_key,uint16_t(amps(1)));
   output.add_data(amps_right_key,uint16_t(amps(2)));
   output.add_data(volt_key,uint16_t(volt()));
   return output;
}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2008 James Molloy, Jörg Pfähler, Matthew Iselin
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "BootstrapInfo.h"

#ifdef DEBUGGER
    #include <Debugger.h>
    #include <LocksCommand.h>
#endif

#include <linker/KernelElf.h>             // KernelElf::initialise()
#include <Version.h>
#include <Log.h>
#include <panic.h>
#include <Archive.h>

#include "cppsupport.h"                   // initialiseConstructors()

#include <processor/Processor.h>          // Processor::initialise1(), Processor::initialise2()
#include <processor/PhysicalMemoryManager.h>
#include <processor/KernelCoreSyscallManager.h>

#include <machine/Machine.h>              // Machine::initialise()
#include <LocalIO.h>
#include <SerialIO.h>
#include <DebuggerIO.h>
#include "BootIO.h"

#include <process/initialiseMultitasking.h>
#include <process/Thread.h>
#include <process/Scheduler.h>
#include <process/SchedulingAlgorithm.h>

#include <machine/Device.h>

#ifdef OPENFIRMWARE
    #include <machine/openfirmware/Device.h>
#endif

#include <utilities/List.h>
#include <utilities/RadixTree.h>
#include <utilities/StaticString.h>

#include <machine/InputManager.h>

#ifdef THREADS
#include <utilities/ZombieQueue.h>
#endif

void apmm()
{
}
/** Output device for boot-time information. */
BootIO bootIO;

/** Global copy of the bootstrap information. */
BootstrapStruct_t *g_pBootstrapInfo;

/** Kernel entry point for application processors (after processor/machine has been initialised
    on the particular processor */
void apMain()
{
  NOTICE("Processor #" << Processor::id() << " started.");

  Processor::setInterrupts(true);
  for (;;)
  {
#ifdef THREADS
    Scheduler::instance().yield();
#endif
  }
}

/** A processor idle function. */
/*int idle(void *)
{
  NOTICE("Idle " << Processor::information().getCurrentThread()->getId());
  Processor::setInterrupts(true);
  for (;;)
  {
    Scheduler::instance().yield();
  }
  return 0;
}*/

/** Loads all kernel modules */
int loadModules(void *inf)
{
    BootstrapStruct_t bsInf = *static_cast<BootstrapStruct_t*>(inf);

    /// \note We have to do this before we call Processor::initialisationDone() otherwise the
    ///       BootstrapStruct_t might already be unmapped
    Archive initrd(bsInf.getInitrdAddress(), bsInf.getInitrdSize());

    size_t nFiles = initrd.getNumFiles();
    g_BootProgressTotal = nFiles*2; // Each file has to be preloaded and executed.
    for (size_t i = 0; i < nFiles; i++)
    {
        // Load file.
        KernelElf::instance().loadModule(reinterpret_cast<uint8_t*> (initrd.getFile(i)),
                                         initrd.getFileSize(i));
    }

    // The initialisation is done here, unmap/free the .init section and on x86/64 the identity
    // mapping of 0-4MB
    // NOTE: BootstrapStruct_t unusable after this point
    #ifdef X86_COMMON
        Processor::initialisationDone();
    #endif

    return 0;
}

/** Kernel entry point. */
extern "C" void _main(BootstrapStruct_t &bsInf)
{
  // Firstly call the constructors of all global objects.
  initialiseConstructors();

  g_pBootstrapInfo = &bsInf;

  // Initialise the processor-specific interface
  Processor::initialise1(bsInf);

  // Initialise the machine-specific interface
  Machine &machine = Machine::instance();

#if defined(X86_COMMON) || defined(PPC_COMMON)
  Machine::instance().initialiseDeviceTree();
#endif

  machine.initialise();

#if defined(DEBUGGER)
  Debugger::instance().initialise();
#endif

  // Initialise the kernel log.
  Log::instance().initialise();

#ifndef ARM_BEAGLE
  // Initialise the Kernel Elf class
  if (KernelElf::instance().initialise(bsInf) == false)
    panic("KernelElf::initialise() failed");
#endif

#ifndef ARM_COMMON
  if (bsInf.isInitrdLoaded() == false)
    panic("Initrd module not loaded!");

  KernelCoreSyscallManager::instance().initialise();
#endif

  // Initialise the processor-specific interface
  // Bootup of the other Application Processors and related tasks
  Processor::initialise2(bsInf);

#ifdef THREADS
  ZombieQueue::instance().initialise();
#endif

#ifndef ARM_COMMON // No ARM port is ready for interrupts yet.
  Processor::setInterrupts(true);

  // Initialise the input manager
  InputManager::instance().initialise();
#endif

  // Initialise the boot output.
  bootIO.initialise();

  // Spew out a starting string.
  HugeStaticString str;
  str += "Pedigree - revision ";
  str += g_pBuildRevision;
  str += "\n=======================\n";
  bootIO.write(str, BootIO::White, BootIO::Black);

  str.clear();
  str += "Built at ";
  str += g_pBuildTime;
  str += " by ";
  str += g_pBuildUser;
  str += " on ";
  str += g_pBuildMachine;
  str += "\n";
  bootIO.write(str, BootIO::LightGrey, BootIO::Black);

  str.clear();
  str += "Build flags: ";
  str += g_pBuildFlags;
  str += "\n";
  bootIO.write(str, BootIO::LightGrey, BootIO::Black);

#ifdef ARM_COMMON
  NOTICE("ARM build now boots properly. Now hanging forever...");
  while(1);
#endif

#ifdef TRACK_LOCKS
  g_LocksCommand.setReady();
#endif

#ifdef THREADS
  new Thread(Processor::information().getCurrentThread()->getParent(), &loadModules, static_cast<void*>(&bsInf), 0);
#else
  loadModules(&bsInf);
#endif

#ifdef DEBUGGER_RUN_AT_START
  //Processor::breakpoint();
#endif

#ifdef THREADS
  Processor::information().getCurrentThread()->setPriority(MAX_PRIORITIES-1);
#endif

  // This will run when nothing else is available to run
  for (;;)
  {
    // Kernel idle thread.
    Processor::setInterrupts(true);

    asm volatile ("hlt");

#ifdef THREADS
    Scheduler::instance().yield();
#endif
  }
}

void system_reset()
{
    NOTICE("Resetting...");
    KernelElf::instance().unloadModules();
    Processor::reset();
}
<commit_msg>More of the same - adding carriage returns where needed.<commit_after>/*
 * Copyright (c) 2010 James Molloy, Jörg Pfähler, Matthew Iselin
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "BootstrapInfo.h"

#ifdef DEBUGGER
    #include <Debugger.h>
    #include <LocksCommand.h>
#endif

#include <linker/KernelElf.h>             // KernelElf::initialise()
#include <Version.h>
#include <Log.h>
#include <panic.h>
#include <Archive.h>

#include "cppsupport.h"                   // initialiseConstructors()

#include <processor/Processor.h>          // Processor::initialise1(), Processor::initialise2()
#include <processor/PhysicalMemoryManager.h>
#include <processor/KernelCoreSyscallManager.h>

#include <machine/Machine.h>              // Machine::initialise()
#include <LocalIO.h>
#include <SerialIO.h>
#include <DebuggerIO.h>
#include "BootIO.h"

#include <process/initialiseMultitasking.h>
#include <process/Thread.h>
#include <process/Scheduler.h>
#include <process/SchedulingAlgorithm.h>

#include <machine/Device.h>

#ifdef OPENFIRMWARE
    #include <machine/openfirmware/Device.h>
#endif

#include <utilities/List.h>
#include <utilities/RadixTree.h>
#include <utilities/StaticString.h>

#include <machine/InputManager.h>

#ifdef THREADS
#include <utilities/ZombieQueue.h>
#endif

void apmm()
{
}
/** Output device for boot-time information. */
BootIO bootIO;

/** Global copy of the bootstrap information. */
BootstrapStruct_t *g_pBootstrapInfo;

/** Kernel entry point for application processors (after processor/machine has been initialised
    on the particular processor */
void apMain()
{
  NOTICE("Processor #" << Processor::id() << " started.");

  Processor::setInterrupts(true);
  for (;;)
  {
#ifdef THREADS
    Scheduler::instance().yield();
#endif
  }
}

/** A processor idle function. */
/*int idle(void *)
{
  NOTICE("Idle " << Processor::information().getCurrentThread()->getId());
  Processor::setInterrupts(true);
  for (;;)
  {
    Scheduler::instance().yield();
  }
  return 0;
}*/

/** Loads all kernel modules */
int loadModules(void *inf)
{
    BootstrapStruct_t bsInf = *static_cast<BootstrapStruct_t*>(inf);

    /// \note We have to do this before we call Processor::initialisationDone() otherwise the
    ///       BootstrapStruct_t might already be unmapped
    Archive initrd(bsInf.getInitrdAddress(), bsInf.getInitrdSize());

    size_t nFiles = initrd.getNumFiles();
    g_BootProgressTotal = nFiles*2; // Each file has to be preloaded and executed.
    for (size_t i = 0; i < nFiles; i++)
    {
        // Load file.
        KernelElf::instance().loadModule(reinterpret_cast<uint8_t*> (initrd.getFile(i)),
                                         initrd.getFileSize(i));
    }

    // The initialisation is done here, unmap/free the .init section and on x86/64 the identity
    // mapping of 0-4MB
    // NOTE: BootstrapStruct_t unusable after this point
    #ifdef X86_COMMON
        Processor::initialisationDone();
    #endif

    return 0;
}

/** Kernel entry point. */
extern "C" void _main(BootstrapStruct_t &bsInf)
{
  // Firstly call the constructors of all global objects.
  initialiseConstructors();

  g_pBootstrapInfo = &bsInf;

  // Initialise the processor-specific interface
  Processor::initialise1(bsInf);

  // Initialise the machine-specific interface
  Machine &machine = Machine::instance();

#if defined(X86_COMMON) || defined(PPC_COMMON)
  Machine::instance().initialiseDeviceTree();
#endif

  machine.initialise();

#if defined(DEBUGGER)
  Debugger::instance().initialise();
#endif

  // Initialise the kernel log.
  Log::instance().initialise();

#ifndef ARM_BEAGLE
  // Initialise the Kernel Elf class
  if (KernelElf::instance().initialise(bsInf) == false)
    panic("KernelElf::initialise() failed");
#endif

#ifndef ARM_COMMON
  if (bsInf.isInitrdLoaded() == false)
    panic("Initrd module not loaded!");

  KernelCoreSyscallManager::instance().initialise();
#endif

  // Initialise the processor-specific interface
  // Bootup of the other Application Processors and related tasks
  Processor::initialise2(bsInf);

#ifdef THREADS
  ZombieQueue::instance().initialise();
#endif

#ifndef ARM_COMMON // No ARM port is ready for interrupts yet.
  Processor::setInterrupts(true);

  // Initialise the input manager
  InputManager::instance().initialise();
#endif

  // Initialise the boot output.
  bootIO.initialise();

  // Spew out a starting string.
  HugeStaticString str;
  str += "Pedigree - revision ";
  str += g_pBuildRevision;
#ifndef DONT_LOG_TO_SERIAL
  str += "\r\n=======================\r\n";
#else
  str += "\n=======================\n";
#endif
  bootIO.write(str, BootIO::White, BootIO::Black);

  str.clear();
  str += "Built at ";
  str += g_pBuildTime;
  str += " by ";
  str += g_pBuildUser;
  str += " on ";
  str += g_pBuildMachine;
#ifndef DONT_LOG_TO_SERIAL
  str += "\r\n";
#else
  str += "\n";
#endif
  bootIO.write(str, BootIO::LightGrey, BootIO::Black);

  str.clear();
  str += "Build flags: ";
  str += g_pBuildFlags;
#ifndef DONT_LOG_TO_SERIAL
  str += "\r\n";
#else
  str += "\n";
#endif
  bootIO.write(str, BootIO::LightGrey, BootIO::Black);

#ifdef ARM_COMMON
  NOTICE("ARM build now boots properly. Now hanging forever...");
  while(1);
#endif

#ifdef TRACK_LOCKS
  g_LocksCommand.setReady();
#endif

#ifdef THREADS
  new Thread(Processor::information().getCurrentThread()->getParent(), &loadModules, static_cast<void*>(&bsInf), 0);
#else
  loadModules(&bsInf);
#endif

#ifdef DEBUGGER_RUN_AT_START
  //Processor::breakpoint();
#endif

#ifdef THREADS
  Processor::information().getCurrentThread()->setPriority(MAX_PRIORITIES-1);
#endif

  // This will run when nothing else is available to run
  for (;;)
  {
    // Kernel idle thread.
    Processor::setInterrupts(true);

    asm volatile ("hlt");

#ifdef THREADS
    Scheduler::instance().yield();
#endif
  }
}

void system_reset()
{
    NOTICE("Resetting...");
    KernelElf::instance().unloadModules();
    Processor::reset();
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"
#include <Eigen/LU>

template<typename MatrixType> void lu_non_invertible()
{
  /* this test covers the following files:
     LU.h
  */
  int rows = ei_random<int>(20,200), cols = ei_random<int>(20,200), cols2 = ei_random<int>(20,200);
  int rank = ei_random<int>(1, std::min(rows, cols)-1);

  MatrixType m1(rows, cols), m2(cols, cols2), m3(rows, cols2), k(1,1);
  createRandomMatrixOfRank(rank, rows, cols, m1);

  LU<MatrixType> lu(m1);
  typename LU<MatrixType>::KernelResultType m1kernel = lu.kernel();
  typename LU<MatrixType>::ImageResultType m1image = lu.image();

  VERIFY(rank == lu.rank());
  VERIFY(cols - lu.rank() == lu.dimensionOfKernel());
  VERIFY(!lu.isInjective());
  VERIFY(!lu.isInvertible());
  VERIFY(lu.isSurjective() == (lu.rank() == rows));
  VERIFY((m1 * m1kernel).isMuchSmallerThan(m1));
  VERIFY(m1image.lu().rank() == rank);
  MatrixType sidebyside(m1.rows(), m1.cols() + m1image.cols());
  sidebyside << m1, m1image;
  VERIFY(sidebyside.lu().rank() == rank);
  m2 = MatrixType::Random(cols,cols2);
  m3 = m1*m2;
  m2 = MatrixType::Random(cols,cols2);
  lu.solve(m3, &m2);
  VERIFY_IS_APPROX(m3, m1*m2);
  m3 = MatrixType::Random(rows,cols2);
  VERIFY(!lu.solve(m3, &m2));

  typedef Matrix<typename MatrixType::Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
  SquareMatrixType m4(rows, rows), m5(rows, rows);
  createRandomMatrixOfRank(rows/2, rows, rows, m4);
  VERIFY(!m4.computeInverseWithCheck(&m5));
}

template<typename MatrixType> void lu_invertible()
{
  /* this test covers the following files:
     LU.h
  */
  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
  int size = ei_random<int>(10,200);

  MatrixType m1(size, size), m2(size, size), m3(size, size);
  m1 = MatrixType::Random(size,size);

  if (ei_is_same_type<RealScalar,float>::ret)
  {
    // let's build a matrix more stable to inverse
    MatrixType a = MatrixType::Random(size,size*2);
    m1 += a * a.adjoint();
  }

  LU<MatrixType> lu(m1);
  VERIFY(0 == lu.dimensionOfKernel());
  VERIFY(size == lu.rank());
  VERIFY(lu.isInjective());
  VERIFY(lu.isSurjective());
  VERIFY(lu.isInvertible());
  VERIFY(lu.image().lu().isInvertible());
  m3 = MatrixType::Random(size,size);
  lu.solve(m3, &m2);
  VERIFY_IS_APPROX(m3, m1*m2);
  VERIFY_IS_APPROX(m2, lu.inverse()*m3);
  m3 = MatrixType::Random(size,size);
  VERIFY(lu.solve(m3, &m2));
}

template<typename MatrixType> void lu_verify_assert()
{
  MatrixType tmp;

  LU<MatrixType> lu;
  VERIFY_RAISES_ASSERT(lu.matrixLU())
  VERIFY_RAISES_ASSERT(lu.permutationP())
  VERIFY_RAISES_ASSERT(lu.permutationQ())
  VERIFY_RAISES_ASSERT(lu.computeKernel(&tmp))
  VERIFY_RAISES_ASSERT(lu.computeImage(&tmp))
  VERIFY_RAISES_ASSERT(lu.kernel())
  VERIFY_RAISES_ASSERT(lu.image())
  VERIFY_RAISES_ASSERT(lu.solve(tmp,&tmp))
  VERIFY_RAISES_ASSERT(lu.determinant())
  VERIFY_RAISES_ASSERT(lu.rank())
  VERIFY_RAISES_ASSERT(lu.dimensionOfKernel())
  VERIFY_RAISES_ASSERT(lu.isInjective())
  VERIFY_RAISES_ASSERT(lu.isSurjective())
  VERIFY_RAISES_ASSERT(lu.isInvertible())
  VERIFY_RAISES_ASSERT(lu.computeInverse(&tmp))
  VERIFY_RAISES_ASSERT(lu.inverse())

  PartialLU<MatrixType> plu;
  VERIFY_RAISES_ASSERT(plu.matrixLU())
  VERIFY_RAISES_ASSERT(plu.permutationP())
  VERIFY_RAISES_ASSERT(plu.solve(tmp,&tmp))
  VERIFY_RAISES_ASSERT(plu.determinant())
  VERIFY_RAISES_ASSERT(plu.computeInverse(&tmp))
  VERIFY_RAISES_ASSERT(plu.inverse())
}

void test_lu()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST( lu_non_invertible<MatrixXf>() );
    CALL_SUBTEST( lu_non_invertible<MatrixXd>() );
    CALL_SUBTEST( lu_non_invertible<MatrixXcf>() );
    CALL_SUBTEST( lu_non_invertible<MatrixXcd>() );
    CALL_SUBTEST( lu_invertible<MatrixXf>() );
    CALL_SUBTEST( lu_invertible<MatrixXd>() );
    CALL_SUBTEST( lu_invertible<MatrixXcf>() );
    CALL_SUBTEST( lu_invertible<MatrixXcd>() );
  }

  CALL_SUBTEST( lu_verify_assert<Matrix3f>() );
  CALL_SUBTEST( lu_verify_assert<Matrix3d>() );
  CALL_SUBTEST( lu_verify_assert<MatrixXf>() );
  CALL_SUBTEST( lu_verify_assert<MatrixXd>() );
  CALL_SUBTEST( lu_verify_assert<MatrixXcf>() );
  CALL_SUBTEST( lu_verify_assert<MatrixXcd>() );
}
<commit_msg>small improvements<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"
#include <Eigen/LU>

template<typename MatrixType> void lu_non_invertible()
{
  /* this test covers the following files:
     LU.h
  */
  int rows = ei_random<int>(20,200), cols = ei_random<int>(20,200), cols2 = ei_random<int>(20,200);
  int rank = ei_random<int>(1, std::min(rows, cols)-1);

  MatrixType m1(rows, cols), m2(cols, cols2), m3(rows, cols2), k(1,1);
  createRandomMatrixOfRank(rank, rows, cols, m1);

  LU<MatrixType> lu(m1);
  typename LU<MatrixType>::KernelResultType m1kernel = lu.kernel();
  typename LU<MatrixType>::ImageResultType m1image = lu.image();

  VERIFY(rank == lu.rank());
  VERIFY(cols - lu.rank() == lu.dimensionOfKernel());
  VERIFY(!lu.isInjective());
  VERIFY(!lu.isInvertible());
  VERIFY(!lu.isSurjective());
  VERIFY((m1 * m1kernel).isMuchSmallerThan(m1));
  VERIFY(m1image.lu().rank() == rank);
  MatrixType sidebyside(m1.rows(), m1.cols() + m1image.cols());
  sidebyside << m1, m1image;
  VERIFY(sidebyside.lu().rank() == rank);
  m2 = MatrixType::Random(cols,cols2);
  m3 = m1*m2;
  m2 = MatrixType::Random(cols,cols2);
  VERIFY(lu.solve(m3, &m2));
  VERIFY_IS_APPROX(m3, m1*m2);
  m3 = MatrixType::Random(rows,cols2);
  VERIFY(!lu.solve(m3, &m2));

  typedef Matrix<typename MatrixType::Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
  SquareMatrixType m4(rows, rows), m5(rows, rows);
  createRandomMatrixOfRank(rows/2, rows, rows, m4);
  VERIFY(!m4.computeInverseWithCheck(&m5));
}

template<typename MatrixType> void lu_invertible()
{
  /* this test covers the following files:
     LU.h
  */
  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
  int size = ei_random<int>(10,200);

  MatrixType m1(size, size), m2(size, size), m3(size, size);
  m1 = MatrixType::Random(size,size);

  if (ei_is_same_type<RealScalar,float>::ret)
  {
    // let's build a matrix more stable to inverse
    MatrixType a = MatrixType::Random(size,size*2);
    m1 += a * a.adjoint();
  }

  LU<MatrixType> lu(m1);
  VERIFY(0 == lu.dimensionOfKernel());
  VERIFY(size == lu.rank());
  VERIFY(lu.isInjective());
  VERIFY(lu.isSurjective());
  VERIFY(lu.isInvertible());
  VERIFY(lu.image().lu().isInvertible());
  m3 = MatrixType::Random(size,size);
  lu.solve(m3, &m2);
  VERIFY_IS_APPROX(m3, m1*m2);
  VERIFY_IS_APPROX(m2, lu.inverse()*m3);
  m3 = MatrixType::Random(size,size);
  VERIFY(lu.solve(m3, &m2));
}

template<typename MatrixType> void lu_verify_assert()
{
  MatrixType tmp;

  LU<MatrixType> lu;
  VERIFY_RAISES_ASSERT(lu.matrixLU())
  VERIFY_RAISES_ASSERT(lu.permutationP())
  VERIFY_RAISES_ASSERT(lu.permutationQ())
  VERIFY_RAISES_ASSERT(lu.computeKernel(&tmp))
  VERIFY_RAISES_ASSERT(lu.computeImage(&tmp))
  VERIFY_RAISES_ASSERT(lu.kernel())
  VERIFY_RAISES_ASSERT(lu.image())
  VERIFY_RAISES_ASSERT(lu.solve(tmp,&tmp))
  VERIFY_RAISES_ASSERT(lu.determinant())
  VERIFY_RAISES_ASSERT(lu.rank())
  VERIFY_RAISES_ASSERT(lu.dimensionOfKernel())
  VERIFY_RAISES_ASSERT(lu.isInjective())
  VERIFY_RAISES_ASSERT(lu.isSurjective())
  VERIFY_RAISES_ASSERT(lu.isInvertible())
  VERIFY_RAISES_ASSERT(lu.computeInverse(&tmp))
  VERIFY_RAISES_ASSERT(lu.inverse())

  PartialLU<MatrixType> plu;
  VERIFY_RAISES_ASSERT(plu.matrixLU())
  VERIFY_RAISES_ASSERT(plu.permutationP())
  VERIFY_RAISES_ASSERT(plu.solve(tmp,&tmp))
  VERIFY_RAISES_ASSERT(plu.determinant())
  VERIFY_RAISES_ASSERT(plu.computeInverse(&tmp))
  VERIFY_RAISES_ASSERT(plu.inverse())
}

void test_lu()
{
  for(int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST( lu_non_invertible<MatrixXf>() );
    CALL_SUBTEST( lu_non_invertible<MatrixXd>() );
    CALL_SUBTEST( lu_non_invertible<MatrixXcf>() );
    CALL_SUBTEST( lu_non_invertible<MatrixXcd>() );
    CALL_SUBTEST( lu_invertible<MatrixXf>() );
    CALL_SUBTEST( lu_invertible<MatrixXd>() );
    CALL_SUBTEST( lu_invertible<MatrixXcf>() );
    CALL_SUBTEST( lu_invertible<MatrixXcd>() );
  }

  CALL_SUBTEST( lu_verify_assert<Matrix3f>() );
  CALL_SUBTEST( lu_verify_assert<Matrix3d>() );
  CALL_SUBTEST( lu_verify_assert<MatrixXf>() );
  CALL_SUBTEST( lu_verify_assert<MatrixXd>() );
  CALL_SUBTEST( lu_verify_assert<MatrixXcf>() );
  CALL_SUBTEST( lu_verify_assert<MatrixXcd>() );
}
<|endoftext|>


<commit_before>#include <complex>

namespace meep_math{
	//TODO: cache this somewhere or we're gonna be slow
	double binomial_cdf(int successes, int trials, long double p){
		long double cdf = 0.0;
		for(int i = 0; i < k; i++){
			cdf += meep_math::binomial_pdf(i, trials, p);
		}
		return cdf;
	}

	double binomial_pdf(int successes, int trials, long double p){
		return (double)meep_math::binomial_coeff(trials, successes) * (p ** successes) * (1 - p) ** (trials - successes);
	}

	//n choose k
	int binomial_coeff(int n, int k){
		if (k > n){
			throw std::runtime_error("error calculating binomial with n = " << n << " and k = " << k << std::endl);
		}
		int product = 1;
		for(int i=1; i <= k; i++){
			product *= ((n + 1 - i) / i);
		}
		return product;
	}

	std::array<double,2> solve_quadratic(double a, double b, double c){
		std::array<double,2> x = {0.0,0.0};
		x[0] = (-b - sqrt(std::pow(b,2) - 4 * a * c))/(2 * a);
		x[1] = (-b + sqrt(std::pow(b,2) - 4 * a * c))/(2 * a);
	}

	//https://en.wikipedia.org/wiki/Quartic_function#Solving_a_quartic_equation
	std::array<double,4> solve_quartic(double a, double b, double c, double d, double e){
		std::array<double,4> x = {0.0,0.0,0.0,0.0};
		double p = (8.0 * a * c - 3 * b^2)/(8.0 * a^2);
		double q = (b^3 - 4.0 * a * b * c + 8.0 * a^2 * d)/(8.0 * a^3);
		double disc = 256 * a^3 * e^3 - 192 * a^2 * b * d * e^2 - 128 * a^2 * c^2 * e^2 + 144 * a^2 * c * d^2 * e - 27 * a^2 * d^4
						+ 144 * a * b^2 * c * e^2 - 6 * a * b^2 * d^2 * e - 80 * a * b * c^2 * d * e + 18 * a * b * c * d^3
						+ 16 * a * c^4 * e - 4 * a * c^3 * d^2 - 27 * b^4 * e^2 + 18 * b^3 * c * d * e - 4 * b^3 * d^3
						- 4 * b^2 * c^3 * e + b^2 * c^2 * d^2;
		double disc0 = c^2 - 3.0 * b * d + 12.0 * a * e;
		double disc1 = 2.0 * c^3 - 9 * b * c * d + 27 * b^2 * e + 27 * a * d^2 - 72 * a * c * e;
		std::complex<double> Q = std::pow((disc1 + std::sqrt(-27 * disc))/2,1/3);
		double S = 0.5 * std::sqrt(-(2.0/3.0)*p + 1.0/(3.0*a) * (Q + disc0/Q));

		//check special cases
		if(disc != 0 && disc0 == 0){
			Q = std::pow(disc1,1/3);
		}
		if(S == 0){
			Q = Q * std::complex<double>(-0.5,std::sqrt(3)/2);
			S = 0.5 * std::sqrt(-(2.0/3.0)*p + 1.0/(3.0*a) * (Q + disc0/Q));
			if (S == 0){
				Q = Q * std::complex<double>(-0.5,-std::sqrt(3)/2);
				S = 0.5 * std::sqrt(-(2.0/3.0)*p + 1.0/(3.0*a) * (Q + disc0/Q));
				if (S == 0){
					std::array<double,2> z = meep_math::solve_quadratic(a,c,e);
					x[0] = std::sqrt(z[0]);
					x[1] = -std::sqrt(z[0]);
					x[2] = std::sqrt(z[1]);
					x[3] = -std::sqrt(z[2]);
				}
			}
		}

		//compute roots
		x[0] = -b / (4.0 * a) - S - 0.5 * std::sqrt(-4.0 * S^2 - 2*p + q/S);
		x[1] = -b / (4.0 * a) - S + 0.5 * std::sqrt(-4.0 * S^2 - 2*p + q/S);
		x[2] = -b / (4.0 * a) + S - 0.5 * std::sqrt(-4.0 * S^2 - 2*p + q/S);
		x[3] = -b / (4.0 * a) + S + 0.5 * std::sqrt(-4.0 * S^2 - 2*p + q/S);
		return x;
	}
}<commit_msg>shore up the quartic solver<commit_after>#include <complex>

namespace meep_math{
	//TODO: cache this somewhere or we're gonna be slow
	double binomial_cdf(int successes, int trials, long double p){
		long double cdf = 0.0;
		for(int i = 0; i < k; i++){
			cdf += meep_math::binomial_pdf(i, trials, p);
		}
		return cdf;
	}

	double binomial_pdf(int successes, int trials, long double p){
		return (double)meep_math::binomial_coeff(trials, successes) * (p ** successes) * (1 - p) ** (trials - successes);
	}

	//n choose k
	int binomial_coeff(int n, int k){
		if (k > n){
			throw std::runtime_error("error calculating binomial with n = " << n << " and k = " << k << std::endl);
		}
		int product = 1;
		for(int i=1; i <= k; i++){
			product *= ((n + 1 - i) / i);
		}
		return product;
	}

	std::array<double,2> solve_quadratic(double a, double b, double c){
		std::array<double,2> x = {0.0,0.0};
		x[0] = (-b - sqrt(std::pow(b,2) - 4 * a * c))/(2 * a);
		x[1] = (-b + sqrt(std::pow(b,2) - 4 * a * c))/(2 * a);
	}

	//https://en.wikipedia.org/wiki/Quartic_function#Solving_a_quartic_equation
	std::array<double,4> solve_quartic(double a, double b, double c, double d, double e){
		std::array<double,4> x = {0.0,0.0,0.0,0.0};
		double p = (8.0 * a * c - 3 * b^2)/(8.0 * a^2);
		double q = (b^3 - 4.0 * a * b * c + 8.0 * a^2 * d)/(8.0 * a^3);
		double disc = 256 * a^3 * e^3 - 192 * a^2 * b * d * e^2 - 128 * a^2 * c^2 * e^2 + 144 * a^2 * c * d^2 * e - 27 * a^2 * d^4
						+ 144 * a * b^2 * c * e^2 - 6 * a * b^2 * d^2 * e - 80 * a * b * c^2 * d * e + 18 * a * b * c * d^3
						+ 16 * a * c^4 * e - 4 * a * c^3 * d^2 - 27 * b^4 * e^2 + 18 * b^3 * c * d * e - 4 * b^3 * d^3
						- 4 * b^2 * c^3 * e + b^2 * c^2 * d^2;
		double disc0 = c^2 - 3.0 * b * d + 12.0 * a * e;
		double disc1 = 2.0 * c^3 - 9 * b * c * d + 27 * b^2 * e + 27 * a * d^2 - 72 * a * c * e;
		std::complex<double> Q;
		if(disc != 0 && disc0 == 0){
			Q = std::pow(disc1,1/3); //special case
		}
		else{
			Q = std::pow((disc1 + std::sqrt(-27 * disc))/2,1/3);
		}
		double S = 0.5 * std::sqrt(-(2.0/3.0)*p + 1.0/(3.0*a) * (Q + disc0/Q));

		//special case. when S == 0 we try other cube roots.
		//see https://en.wikipedia.org/wiki/Cube_root
		//if none of them work, it's because the depressed quartic is biquadratic
		if(S == 0){
			std::complex<double> old_Q = Q;
			Q = old_Q * std::complex<double>(-0.5,std::sqrt(3)/2);
			S = 0.5 * std::sqrt(-(2.0/3.0)*p + 1.0/(3.0*a) * (Q + disc0/Q));
			if (S == 0){
				Q = old_Q * std::complex<double>(-0.5,-std::sqrt(3)/2);
				S = 0.5 * std::sqrt(-(2.0/3.0)*p + 1.0/(3.0*a) * (Q + disc0/Q));
				if (S == 0){
					std::array<double,2> z = meep_math::solve_quadratic(a,c,e);
					x[0] = std::sqrt(z[0]);
					x[1] = -std::sqrt(z[0]);
					x[2] = std::sqrt(z[1]);
					x[3] = -std::sqrt(z[2]);
					return x;
				}
			}
		}
		//compute roots
		x[0] = -b / (4.0 * a) - S - 0.5 * std::sqrt(-4.0 * S^2 - 2*p + q/S);
		x[1] = -b / (4.0 * a) - S + 0.5 * std::sqrt(-4.0 * S^2 - 2*p + q/S);
		x[2] = -b / (4.0 * a) + S - 0.5 * std::sqrt(-4.0 * S^2 - 2*p + q/S);
		x[3] = -b / (4.0 * a) + S + 0.5 * std::sqrt(-4.0 * S^2 - 2*p + q/S);
		return x;
	}
}<|endoftext|>