<commit_before>/* Copyright (c) 2017-2018 Rolf Timmermans */
#include "context.h"
#include "socket.h"

#include "util/callback_scope.h"
#include "util/napi_compat.h"
#include "util/uvwork.h"

#include <unordered_set>

namespace zmq {
/* Create a reference to a single global context that is automatically
   closed on process exit. This is the default context. */
Napi::ObjectReference GlobalContext;

Napi::FunctionReference Context::Constructor;

std::unordered_set<void*> Context::ActivePtrs;

Context::Context(const Napi::CallbackInfo& info) : Napi::ObjectWrap<Context>(info) {
    auto args = {
        Argument{"Options must be an object", &Napi::Value::IsObject,
            &Napi::Value::IsUndefined},
    };

    if (!ValidateArguments(info, args)) return;

    context = zmq_ctx_new();
    if (context != nullptr) {
        ActivePtrs.insert(context);
    } else {
        ErrnoException(Env(), zmq_errno()).ThrowAsJavaScriptException();
        return;
    }

    /* Sealing causes setting/getting invalid options to throw an error.
       Otherwise they would fail silently, which is very confusing. */
    Seal(info.This().As<Napi::Object>());

    if (info[0].IsObject()) {
        Assign(info.This().As<Napi::Object>(), info[0].As<Napi::Object>());
    }
}

Context::~Context() {
    if (context != nullptr) {
        /* Messages may still be in the pipeline, so we only shutdown
           and do not terminate the context just yet. */
        ActivePtrs.erase(context);
        auto err = zmq_ctx_shutdown(context);
        assert(err == 0);

        context = nullptr;
    }
}

template <>
Napi::Value Context::GetCtxOpt<bool>(const Napi::CallbackInfo& info) {
    auto args = {
        Argument{"Identifier must be a number", &Napi::Value::IsNumber},
    };

    if (!ValidateArguments(info, args)) return Env().Undefined();

    uint32_t option = info[0].As<Napi::Number>();

    int32_t value = zmq_ctx_get(context, option);
    if (value < 0) {
        ErrnoException(Env(), zmq_errno()).ThrowAsJavaScriptException();
        return Env().Undefined();
    }

    return Napi::Boolean::New(Env(), value);
}

template <>
void Context::SetCtxOpt<bool>(const Napi::CallbackInfo& info) {
    auto args = {
        Argument{"Identifier must be a number", &Napi::Value::IsNumber},
        Argument{"Option value must be a boolean", &Napi::Value::IsBoolean},
    };

    if (!ValidateArguments(info, args)) return;

    uint32_t option = info[0].As<Napi::Number>();

    int32_t value = info[1].As<Napi::Boolean>();
    if (zmq_ctx_set(context, option, value) < 0) {
        ErrnoException(Env(), zmq_errno()).ThrowAsJavaScriptException();
        return;
    }
}

template <typename T>
Napi::Value Context::GetCtxOpt(const Napi::CallbackInfo& info) {
    auto args = {
        Argument{"Identifier must be a number", &Napi::Value::IsNumber},
    };

    if (!ValidateArguments(info, args)) return Env().Undefined();

    uint32_t option = info[0].As<Napi::Number>();

    T value = zmq_ctx_get(context, option);
    if (value < 0) {
        ErrnoException(Env(), zmq_errno()).ThrowAsJavaScriptException();
        return Env().Undefined();
    }

    return Napi::Number::New(Env(), value);
}

template <typename T>
void Context::SetCtxOpt(const Napi::CallbackInfo& info) {
    auto args = {
        Argument{"Identifier must be a number", &Napi::Value::IsNumber},
        Argument{"Option value must be a number", &Napi::Value::IsNumber},
    };

    if (!ValidateArguments(info, args)) return;

    uint32_t option = info[0].As<Napi::Number>();

    T value = info[1].As<Napi::Number>();
    if (zmq_ctx_set(context, option, value) < 0) {
        ErrnoException(Env(), zmq_errno()).ThrowAsJavaScriptException();
        return;
    }
}

void Context::Initialize(Napi::Env& env, Napi::Object& exports) {
    auto proto = {
        InstanceMethod("getBoolOption", &Context::GetCtxOpt<bool>),
        InstanceMethod("setBoolOption", &Context::SetCtxOpt<bool>),
        InstanceMethod("getInt32Option", &Context::GetCtxOpt<int32_t>),
        InstanceMethod("setInt32Option", &Context::SetCtxOpt<int32_t>),
    };

    auto constructor = DefineClass(env, "Context", proto);

    /* Create global context that is closed on process exit. */
    auto global = constructor.New({});

    GlobalContext = Napi::Persistent(global);
    GlobalContext.SuppressDestruct();

    exports.Set("global", global);

    Constructor = Napi::Persistent(constructor);
    Constructor.SuppressDestruct();

    exports.Set("Context", constructor);

    napi_add_env_cleanup_hook(env,
        [](void*) {
            /* Close all currently open sockets. */
            for (auto socket : Socket::ActivePtrs) {
                auto err = zmq_close(socket);
                assert(err == 0);
            }

            /* Terminate all remaining contexts on process exit. */
            for (auto context : Context::ActivePtrs) {
                auto err = zmq_ctx_term(context);
                assert(err == 0);
            }
        },
        nullptr);
}
}
<commit_msg>Terminate socket later.<commit_after>/* Copyright (c) 2017-2018 Rolf Timmermans */
#include "context.h"
#include "socket.h"

#include "util/callback_scope.h"
#include "util/napi_compat.h"
#include "util/uvwork.h"

#include <unordered_set>

namespace zmq {
/* Create a reference to a single global context that is automatically
   closed on process exit. This is the default context. */
Napi::ObjectReference GlobalContext;

Napi::FunctionReference Context::Constructor;

std::unordered_set<void*> Context::ActivePtrs;

Context::Context(const Napi::CallbackInfo& info) : Napi::ObjectWrap<Context>(info) {
    auto args = {
        Argument{"Options must be an object", &Napi::Value::IsObject,
            &Napi::Value::IsUndefined},
    };

    if (!ValidateArguments(info, args)) return;

    context = zmq_ctx_new();
    if (context != nullptr) {
        ActivePtrs.insert(context);
    } else {
        ErrnoException(Env(), zmq_errno()).ThrowAsJavaScriptException();
        return;
    }

    /* Sealing causes setting/getting invalid options to throw an error.
       Otherwise they would fail silently, which is very confusing. */
    Seal(info.This().As<Napi::Object>());

    if (info[0].IsObject()) {
        Assign(info.This().As<Napi::Object>(), info[0].As<Napi::Object>());
    }
}

Context::~Context() {
    if (context != nullptr) {
        /* Messages may still be in the pipeline, so we only shutdown
           and do not terminate the context just yet. */
        auto err = zmq_ctx_shutdown(context);
        assert(err == 0);

        context = nullptr;
    }
}

template <>
Napi::Value Context::GetCtxOpt<bool>(const Napi::CallbackInfo& info) {
    auto args = {
        Argument{"Identifier must be a number", &Napi::Value::IsNumber},
    };

    if (!ValidateArguments(info, args)) return Env().Undefined();

    uint32_t option = info[0].As<Napi::Number>();

    int32_t value = zmq_ctx_get(context, option);
    if (value < 0) {
        ErrnoException(Env(), zmq_errno()).ThrowAsJavaScriptException();
        return Env().Undefined();
    }

    return Napi::Boolean::New(Env(), value);
}

template <>
void Context::SetCtxOpt<bool>(const Napi::CallbackInfo& info) {
    auto args = {
        Argument{"Identifier must be a number", &Napi::Value::IsNumber},
        Argument{"Option value must be a boolean", &Napi::Value::IsBoolean},
    };

    if (!ValidateArguments(info, args)) return;

    uint32_t option = info[0].As<Napi::Number>();

    int32_t value = info[1].As<Napi::Boolean>();
    if (zmq_ctx_set(context, option, value) < 0) {
        ErrnoException(Env(), zmq_errno()).ThrowAsJavaScriptException();
        return;
    }
}

template <typename T>
Napi::Value Context::GetCtxOpt(const Napi::CallbackInfo& info) {
    auto args = {
        Argument{"Identifier must be a number", &Napi::Value::IsNumber},
    };

    if (!ValidateArguments(info, args)) return Env().Undefined();

    uint32_t option = info[0].As<Napi::Number>();

    T value = zmq_ctx_get(context, option);
    if (value < 0) {
        ErrnoException(Env(), zmq_errno()).ThrowAsJavaScriptException();
        return Env().Undefined();
    }

    return Napi::Number::New(Env(), value);
}

template <typename T>
void Context::SetCtxOpt(const Napi::CallbackInfo& info) {
    auto args = {
        Argument{"Identifier must be a number", &Napi::Value::IsNumber},
        Argument{"Option value must be a number", &Napi::Value::IsNumber},
    };

    if (!ValidateArguments(info, args)) return;

    uint32_t option = info[0].As<Napi::Number>();

    T value = info[1].As<Napi::Number>();
    if (zmq_ctx_set(context, option, value) < 0) {
        ErrnoException(Env(), zmq_errno()).ThrowAsJavaScriptException();
        return;
    }
}

void Context::Initialize(Napi::Env& env, Napi::Object& exports) {
    auto proto = {
        InstanceMethod("getBoolOption", &Context::GetCtxOpt<bool>),
        InstanceMethod("setBoolOption", &Context::SetCtxOpt<bool>),
        InstanceMethod("getInt32Option", &Context::GetCtxOpt<int32_t>),
        InstanceMethod("setInt32Option", &Context::SetCtxOpt<int32_t>),
    };

    auto constructor = DefineClass(env, "Context", proto);

    /* Create global context that is closed on process exit. */
    auto global = constructor.New({});

    GlobalContext = Napi::Persistent(global);
    GlobalContext.SuppressDestruct();

    exports.Set("global", global);

    Constructor = Napi::Persistent(constructor);
    Constructor.SuppressDestruct();

    exports.Set("Context", constructor);

    napi_add_env_cleanup_hook(env,
        [](void*) {
            /* Close all currently open sockets. */
            for (auto socket : Socket::ActivePtrs) {
                auto err = zmq_close(socket);
                assert(err == 0);
            }

            /* Terminate all remaining contexts on process exit. */
            for (auto context : Context::ActivePtrs) {
                auto err = zmq_ctx_term(context);
                assert(err == 0);
            }
        },
        nullptr);
}
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: editsh.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: nn $ $Date: 2001-07-19 19:36:03 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_EDITSH_HXX
#define SC_EDITSH_HXX

#ifndef _SFX_SHELL_HXX //autogen
#include <sfx2/shell.hxx>
#endif
#ifndef _SFXMODULE_HXX //autogen
#include <sfx2/module.hxx>
#endif
#ifndef _LINK_HXX
#include <tools/link.hxx>
#endif

#include "shellids.hxx"

class EditView;
class ScViewData;
class ScInputHandler;
class SvxURLField;
class TransferableDataHelper;
class TransferableClipboardListener;

class ScEditShell : public SfxShell
{
private:
    EditView*   pEditView;
    ScViewData* pViewData;
    TransferableClipboardListener* pClipEvtLstnr;
    BOOL        bPastePossible;
    BOOL        bIsInsertMode;

    const SvxURLField* GetURLField();
    ScInputHandler* GetMyInputHdl();

    DECL_LINK( ClipboardChanged, TransferableDataHelper* );

public:
    TYPEINFO();
    SFX_DECL_INTERFACE(SCID_EDIT_SHELL);

                    ScEditShell(EditView* pView, ScViewData* pData);
                    ~ScEditShell();

    void    SetEditView(EditView* pView);

    void    Execute(SfxRequest& rReq);
    void    ExecuteTrans(SfxRequest& rReq);
    void    GetState(SfxItemSet &rSet);
    void    GetClipState(SfxItemSet& rSet);

    void    ExecuteAttr(SfxRequest& rReq);
    void    GetAttrState(SfxItemSet &rSet);

    void    ExecuteUndo(SfxRequest& rReq);
    void    GetUndoState(SfxItemSet &rSet);

    String  GetSelectionText( BOOL bWholeWord );
};

#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.5.926); FILE MERGED 2005/09/05 15:05:20 rt 1.5.926.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: editsh.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 21:24:16 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *
 ************************************************************************/

#ifndef SC_EDITSH_HXX
#define SC_EDITSH_HXX

#ifndef _SFX_SHELL_HXX //autogen
#include <sfx2/shell.hxx>
#endif
#ifndef _SFXMODULE_HXX //autogen
#include <sfx2/module.hxx>
#endif
#ifndef _LINK_HXX
#include <tools/link.hxx>
#endif

#include "shellids.hxx"

class EditView;
class ScViewData;
class ScInputHandler;
class SvxURLField;
class TransferableDataHelper;
class TransferableClipboardListener;

class ScEditShell : public SfxShell
{
private:
    EditView*   pEditView;
    ScViewData* pViewData;
    TransferableClipboardListener* pClipEvtLstnr;
    BOOL        bPastePossible;
    BOOL        bIsInsertMode;

    const SvxURLField* GetURLField();
    ScInputHandler* GetMyInputHdl();

    DECL_LINK( ClipboardChanged, TransferableDataHelper* );

public:
    TYPEINFO();
    SFX_DECL_INTERFACE(SCID_EDIT_SHELL);

                    ScEditShell(EditView* pView, ScViewData* pData);
                    ~ScEditShell();

    void    SetEditView(EditView* pView);

    void    Execute(SfxRequest& rReq);
    void    ExecuteTrans(SfxRequest& rReq);
    void    GetState(SfxItemSet &rSet);
    void    GetClipState(SfxItemSet& rSet);

    void    ExecuteAttr(SfxRequest& rReq);
    void    GetAttrState(SfxItemSet &rSet);

    void    ExecuteUndo(SfxRequest& rReq);
    void    GetUndoState(SfxItemSet &rSet);

    String  GetSelectionText( BOOL bWholeWord );
};

#endif

<|endoftext|>


<commit_before>#ifndef _RANDOM_HPP
#define _RANDOM_HPP

#include <random>
#include <type_traits>

std::mt19937 & make_random_engine();

template <
        typename T,
        typename = typename std::enable_if<
                std::is_integral<T>::value ||
                std::is_floating_point<T>::value
            >::type
    >
T random_between(T begin, T end) {
    typename std::conditional<
            std::is_integral<T>::value,
            std::uniform_int_distribution<T>,
            std::uniform_real_distribution<T>
        >::type distrib(begin, end);

    auto engine = make_random_engine();

    return distrib(engine);
}

template <typename T>
T random_normal(T mean, T stddev) {
    std::normal_distribution<T> distrib(mean, stddev);
    auto engine = make_random_engine();
    return distrib(engine);
}

#endif
<commit_msg>fixed bug when random generator returned same result all the time<commit_after>#ifndef _RANDOM_HPP
#define _RANDOM_HPP

#include <random>
#include <type_traits>

std::mt19937 & make_random_engine();

template <
        typename T,
        typename = typename std::enable_if<
                std::is_integral<T>::value ||
                std::is_floating_point<T>::value
            >::type
    >
T random_between(T begin, T end) {
    typename std::conditional<
            std::is_integral<T>::value,
            std::uniform_int_distribution<T>,
            std::uniform_real_distribution<T>
        >::type distrib(begin, end);

    auto& engine = make_random_engine();

    return distrib(engine);
}

template <typename T>
T random_normal(T mean, T stddev) {
    std::normal_distribution<T> distrib(mean, stddev);
    auto& engine = make_random_engine();
    return distrib(engine);
}

#endif
<|endoftext|>


<commit_before>#include "reactor.h"

using cyclus::Material;
using cyclus::Composition;
using cyclus::toolkit::ResBuf;
using cyclus::toolkit::MatVec;
using cyclus::KeyError;
using cyclus::ValueError;
using cyclus::Request;

namespace cycamore {

Reactor::Reactor(cyclus::Context* ctx)
    : cyclus::Facility(ctx),
      n_assem_batch(0),
      assem_size(0),
      n_assem_core(0),
      n_assem_spent(0),
      n_assem_fresh(0),
      cycle_time(0),
      refuel_time(0),
      cycle_step(0),
      discharged(false) {
  cyclus::Warn<cyclus::EXPERIMENTAL_WARNING>("the Reactor archetype "
                                             "is experimental");
}

void Reactor::Tick() {
  int t = context()->time();

  // update preferences
  for (int i = 0; i < pref_change_times.size(); i++) {
    int change_t = pref_change_times[i];
    if (t != change_t) {
      continue;
    }

    std::string incommod = pref_change_commods[i];
    for (int j = 0; j < fuel_incommods.size(); j++) {
      if (fuel_incommods[j] == incommod) {
        fuel_prefs[j] = pref_change_values[i];
        break;
      }
    }
  }

  // update recipes
  for (int i = 0; i < recipe_change_times.size(); i++) {
    int change_t = recipe_change_times[i];
    if (t != change_t) {
      continue;
    }

    std::string incommod = recipe_change_commods[i];
    for (int j = 0; j < fuel_incommods.size(); j++) {
      if (fuel_incommods[j] == incommod) {
        fuel_inrecipes[j] = recipe_change_in[i];
        fuel_outrecipes[j] = recipe_change_out[i];
        break;
      }
    }
  }
}

std::set<cyclus::RequestPortfolio<Material>::Ptr>
Reactor::GetMatlRequests() {
  using cyclus::RequestPortfolio;

  std::set<RequestPortfolio<Material>::Ptr> ports;
  RequestPortfolio<Material>::Ptr port(new RequestPortfolio<Material>());
  Material::Ptr m;

  int n_assem_order = n_assem_core - core.count()
                      + n_assem_fresh - fresh.count();
  if (n_assem_order == 0) {
    return ports;
  }

  for (int i = 0; i < n_assem_order; i++) {
    std::vector<Request<Material>*> mreqs;
    for (int j = 0; j < fuel_incommods.size(); j++) {
      std::string commod = fuel_incommods[j];
      double pref = fuel_prefs[j];
      Composition::Ptr recipe = context()->GetRecipe(fuel_inrecipes[j]);
      m = Material::CreateUntracked(assem_size, recipe);
      Request<Material>* r = port->AddRequest(m, this, commod, pref, true);
      mreqs.push_back(r);
    }
    port->AddMutualReqs(mreqs);
  }

  ports.insert(port);
  return ports;
}

void Reactor::AcceptMatlTrades(
    const std::vector< std::pair<cyclus::Trade<Material>,
    Material::Ptr> >& responses) {

  std::vector< std::pair<cyclus::Trade<cyclus::Material>,
                         cyclus::Material::Ptr> >::const_iterator trade;

  std::stringstream ss;
  ss << "LOAD: " << std::min((int)responses.size(), n_assem_core - core.count())
     << " assemblies";
  Record(ss.str());

  for (trade = responses.begin(); trade != responses.end(); ++trade) {
    std::string commod = trade->first.request->commodity();
    Material::Ptr m = trade->second;
    index_res(m, commod);

    if (core.count() < n_assem_core) {
      core.Push(m);
    } else {
      fresh.Push(m);
    }
  }
}

std::set<cyclus::BidPortfolio<Material>::Ptr>
Reactor::GetMatlBids(cyclus::CommodMap<Material>::type&
                          commod_requests) {
  using cyclus::BidPortfolio;

  std::set<BidPortfolio<Material>::Ptr> ports;

  for (int i = 0; i < fuel_outcommods.size(); i++) {
    std::string commod = fuel_outcommods[i];
    MatVec mats = SpentResFor(commod);
    std::vector<Request<Material>*>& reqs = commod_requests[commod];
    if (mats.size() == 0 || reqs.size() == 0) {
      continue;
    }

    BidPortfolio<Material>::Ptr port(new BidPortfolio<Material>());

    for (int j = 0; j < reqs.size(); j++) {
      Request<Material>* req = reqs[j];
      double tot_bid = 0;
      for (int k = 0; k < mats.size(); k++) {
        Material::Ptr m = mats[k];
        tot_bid += m->quantity();
        port->AddBid(req, m, this, true);
        if (tot_bid >= req->target()->quantity()) {
          break;
        }
      }
    }

    double tot_qty = 0;
    for (int j = 0; j < mats.size(); j++) {
      tot_qty += mats[j]->quantity();
    }
    cyclus::CapacityConstraint<Material> cc(tot_qty);
    port->AddConstraint(cc);
    ports.insert(port);
  }

  return ports;
}

void Reactor::GetMatlTrades(
    const std::vector< cyclus::Trade<Material> >& trades,
    std::vector<std::pair<cyclus::Trade<Material>,
    Material::Ptr> >& responses) {
  using cyclus::Trade;

  std::vector< cyclus::Trade<cyclus::Material> >::const_iterator it;
  for (int i = 0; i < trades.size(); i++) {
    std::string commod = trades[i].request->commodity();
    Material::Ptr m = PopSpentRes(commod);
    responses.push_back(std::make_pair(trades[i], m));
    res_indexes.erase(m->obj_id());
  }
}

void Reactor::Tock() {
  if (cycle_step >= cycle_time + refuel_time && core.count() == n_assem_core) {
    discharged = false;
    cycle_step = 0;
  }

  if (cycle_step == 0 && core.count() == n_assem_core) {
    Record("CYCLE: start");
  }

  // "if" prevents starting cycle after initial deployment until core is full
  // even though cycle_step is its initial zero.
  if (cycle_step > 0 || core.count() == n_assem_core) {
    cycle_step++;
  }

  if (cycle_step == cycle_time) {
    Transmute();
    Record("CYCLE: end");
  }
  if (cycle_step >= cycle_time && !discharged) {
    discharged = Discharge();
  }
  if (cycle_step >= cycle_time) {
    Load();
  }
}

void Reactor::Transmute() {
  // safe to assume full core.
  MatVec old = core.PopN(n_assem_batch);
  MatVec tail = core.PopN(core.count());
  core.Push(old);
  core.Push(tail);

  std::stringstream ss;
  ss << "TRANSMUTE: " << old.size() << " assemblies";
  Record(ss.str());

  for (int i = 0; i < old.size(); i++) {
    old[i]->Transmute(context()->GetRecipe(fuel_outrecipe(old[i])));
  }
}

bool Reactor::Discharge() {
  if (n_assem_spent - spent.count() < n_assem_batch) {
    Record("DISCHARGE: failed");
    return false; // not enough room in spent buffer
  }

  int npop = std::min(n_assem_batch, core.count());

  std::stringstream ss;
  ss << "DISCHARGE: " << npop << " assemblies";
  Record(ss.str());

  spent.Push(core.PopN(npop));
  return true;
}

void Reactor::Load() {
  int n = std::min(n_assem_core - core.count(), fresh.count());
  if (n == 0) {
    return;
  }

  std::stringstream ss;
  ss << "LOAD: " << n << " assemblies";
  Record(ss.str());
  core.Push(fresh.PopN(n));
}

std::string Reactor::fuel_incommod(Material::Ptr m) {
  int i = res_indexes[m->obj_id()];
  if (i >= fuel_incommods.size()) {
    throw KeyError("cycamore::Reactor - no incommod for material object");
  }
  return fuel_incommods[i];
}

std::string Reactor::fuel_outcommod(Material::Ptr m) {
  int i = res_indexes[m->obj_id()];
  if (i >= fuel_outcommods.size()) {
    throw KeyError("cycamore::Reactor - no outcommod for material object");
  }
  return fuel_outcommods[i];
}

std::string Reactor::fuel_inrecipe(Material::Ptr m) {
  int i = res_indexes[m->obj_id()];
  if (i >= fuel_inrecipes.size()) {
    throw KeyError("cycamore::Reactor - no inrecipe for material object");
  }
  return fuel_inrecipes[i];
}

std::string Reactor::fuel_outrecipe(Material::Ptr m) {
  int i = res_indexes[m->obj_id()];
  if (i >= fuel_outrecipes.size()) {
    throw KeyError("cycamore::Reactor - no outrecipe for material object");
  }
  return fuel_outrecipes[i];
}

double Reactor::fuel_pref(Material::Ptr m) {
  int i = res_indexes[m->obj_id()];
  if (i >= fuel_prefs.size()) {
    return 0;
  }
  return fuel_prefs[i];
}

void Reactor::index_res(cyclus::Resource::Ptr m, std::string incommod) {
  for (int i = 0; i < fuel_incommods.size(); i++) {
    if (fuel_incommods[i] == incommod) {
      res_indexes[m->obj_id()] = i;
      return;
    }
  }
  throw ValueError("cycamore::Reactor - received unsupported incommod material");
}

Material::Ptr Reactor::PopSpentRes(std::string outcommod) {
  MatVec mats = spent.PopN(spent.count());
  Material::Ptr m;
  bool found = false;
  for (int i = 0; i < mats.size(); i++) {
    std::string commod = fuel_outcommod(mats[i]);
    if (!found && commod == outcommod) {
      m = mats[i];
      found = true;
    } else {
      spent.Push(mats[i]);
    }
  }
  return m;
}

MatVec Reactor::SpentResFor(std::string outcommod) {
  MatVec mats = spent.PopN(spent.count());
  MatVec found;
  spent.Push(mats);
  for (int i = 0; i < mats.size(); i++) {
    std::string commod = fuel_outcommod(mats[i]);
    if (commod == outcommod) {
      found.push_back(mats[i]);
    }
  }
  return found;
}

void Reactor::Record(std::string name) {
  context()->NewDatum("ReactorEvents")
    ->AddVal("AgentId", id())
    ->AddVal("Time", context()->time())
    ->AddVal("Event", name)
    ->Record();
}

extern "C" cyclus::Agent* ConstructReactor(cyclus::Context* ctx) {
  return new Reactor(ctx);
}

} // namespace cycamore

<commit_msg>work around DRE bug<commit_after>#include "reactor.h"

using cyclus::Material;
using cyclus::Composition;
using cyclus::toolkit::ResBuf;
using cyclus::toolkit::MatVec;
using cyclus::KeyError;
using cyclus::ValueError;
using cyclus::Request;

namespace cycamore {

Reactor::Reactor(cyclus::Context* ctx)
    : cyclus::Facility(ctx),
      n_assem_batch(0),
      assem_size(0),
      n_assem_core(0),
      n_assem_spent(0),
      n_assem_fresh(0),
      cycle_time(0),
      refuel_time(0),
      cycle_step(0),
      discharged(false) {
  cyclus::Warn<cyclus::EXPERIMENTAL_WARNING>("the Reactor archetype "
                                             "is experimental");
}

void Reactor::Tick() {
  int t = context()->time();

  // update preferences
  for (int i = 0; i < pref_change_times.size(); i++) {
    int change_t = pref_change_times[i];
    if (t != change_t) {
      continue;
    }

    std::string incommod = pref_change_commods[i];
    for (int j = 0; j < fuel_incommods.size(); j++) {
      if (fuel_incommods[j] == incommod) {
        fuel_prefs[j] = pref_change_values[i];
        break;
      }
    }
  }

  // update recipes
  for (int i = 0; i < recipe_change_times.size(); i++) {
    int change_t = recipe_change_times[i];
    if (t != change_t) {
      continue;
    }

    std::string incommod = recipe_change_commods[i];
    for (int j = 0; j < fuel_incommods.size(); j++) {
      if (fuel_incommods[j] == incommod) {
        fuel_inrecipes[j] = recipe_change_in[i];
        fuel_outrecipes[j] = recipe_change_out[i];
        break;
      }
    }
  }
}

std::set<cyclus::RequestPortfolio<Material>::Ptr>
Reactor::GetMatlRequests() {
  using cyclus::RequestPortfolio;

  std::set<RequestPortfolio<Material>::Ptr> ports;
  Material::Ptr m;

  int n_assem_order = n_assem_core - core.count()
                      + n_assem_fresh - fresh.count();
  if (n_assem_order == 0) {
    return ports;
  }

  for (int i = 0; i < n_assem_order; i++) {
    RequestPortfolio<Material>::Ptr port(new RequestPortfolio<Material>());
    std::vector<Request<Material>*> mreqs;
    for (int j = 0; j < fuel_incommods.size(); j++) {
      std::string commod = fuel_incommods[j];
      double pref = fuel_prefs[j];
      Composition::Ptr recipe = context()->GetRecipe(fuel_inrecipes[j]);
      m = Material::CreateUntracked(assem_size, recipe);
      Request<Material>* r = port->AddRequest(m, this, commod, pref, true);
      mreqs.push_back(r);
    }
    port->AddMutualReqs(mreqs);
    ports.insert(port);
  }

  return ports;
}

void Reactor::AcceptMatlTrades(
    const std::vector< std::pair<cyclus::Trade<Material>,
    Material::Ptr> >& responses) {

  std::vector< std::pair<cyclus::Trade<cyclus::Material>,
                         cyclus::Material::Ptr> >::const_iterator trade;

  std::stringstream ss;
  ss << "LOAD: " << std::min((int)responses.size(), n_assem_core - core.count())
     << " assemblies";
  Record(ss.str());

  for (trade = responses.begin(); trade != responses.end(); ++trade) {
    std::string commod = trade->first.request->commodity();
    Material::Ptr m = trade->second;
    index_res(m, commod);

    if (core.count() < n_assem_core) {
      core.Push(m);
    } else {
      fresh.Push(m);
    }
  }
}

std::set<cyclus::BidPortfolio<Material>::Ptr>
Reactor::GetMatlBids(cyclus::CommodMap<Material>::type&
                          commod_requests) {
  using cyclus::BidPortfolio;

  std::set<BidPortfolio<Material>::Ptr> ports;

  for (int i = 0; i < fuel_outcommods.size(); i++) {
    std::string commod = fuel_outcommods[i];
    MatVec mats = SpentResFor(commod);
    std::vector<Request<Material>*>& reqs = commod_requests[commod];
    if (mats.size() == 0 || reqs.size() == 0) {
      continue;
    }

    BidPortfolio<Material>::Ptr port(new BidPortfolio<Material>());

    for (int j = 0; j < reqs.size(); j++) {
      Request<Material>* req = reqs[j];
      double tot_bid = 0;
      for (int k = 0; k < mats.size(); k++) {
        Material::Ptr m = mats[k];
        tot_bid += m->quantity();
        port->AddBid(req, m, this, true);
        if (tot_bid >= req->target()->quantity()) {
          break;
        }
      }
    }

    double tot_qty = 0;
    for (int j = 0; j < mats.size(); j++) {
      tot_qty += mats[j]->quantity();
    }
    cyclus::CapacityConstraint<Material> cc(tot_qty);
    port->AddConstraint(cc);
    ports.insert(port);
  }

  return ports;
}

void Reactor::GetMatlTrades(
    const std::vector< cyclus::Trade<Material> >& trades,
    std::vector<std::pair<cyclus::Trade<Material>,
    Material::Ptr> >& responses) {
  using cyclus::Trade;

  std::vector< cyclus::Trade<cyclus::Material> >::const_iterator it;
  for (int i = 0; i < trades.size(); i++) {
    std::string commod = trades[i].request->commodity();
    Material::Ptr m = PopSpentRes(commod);
    responses.push_back(std::make_pair(trades[i], m));
    res_indexes.erase(m->obj_id());
  }
}

void Reactor::Tock() {
  if (cycle_step >= cycle_time + refuel_time && core.count() == n_assem_core) {
    discharged = false;
    cycle_step = 0;
  }

  if (cycle_step == 0 && core.count() == n_assem_core) {
    Record("CYCLE: start");
  }

  // "if" prevents starting cycle after initial deployment until core is full
  // even though cycle_step is its initial zero.
  if (cycle_step > 0 || core.count() == n_assem_core) {
    cycle_step++;
  }

  if (cycle_step == cycle_time) {
    Transmute();
    Record("CYCLE: end");
  }
  if (cycle_step >= cycle_time && !discharged) {
    discharged = Discharge();
  }
  if (cycle_step >= cycle_time) {
    Load();
  }
}

void Reactor::Transmute() {
  // safe to assume full core.
  MatVec old = core.PopN(n_assem_batch);
  MatVec tail = core.PopN(core.count());
  core.Push(old);
  core.Push(tail);

  std::stringstream ss;
  ss << "TRANSMUTE: " << old.size() << " assemblies";
  Record(ss.str());

  for (int i = 0; i < old.size(); i++) {
    old[i]->Transmute(context()->GetRecipe(fuel_outrecipe(old[i])));
  }
}

bool Reactor::Discharge() {
  if (n_assem_spent - spent.count() < n_assem_batch) {
    Record("DISCHARGE: failed");
    return false; // not enough room in spent buffer
  }

  int npop = std::min(n_assem_batch, core.count());

  std::stringstream ss;
  ss << "DISCHARGE: " << npop << " assemblies";
  Record(ss.str());

  spent.Push(core.PopN(npop));
  return true;
}

void Reactor::Load() {
  int n = std::min(n_assem_core - core.count(), fresh.count());
  if (n == 0) {
    return;
  }

  std::stringstream ss;
  ss << "LOAD: " << n << " assemblies";
  Record(ss.str());
  core.Push(fresh.PopN(n));
}

std::string Reactor::fuel_incommod(Material::Ptr m) {
  int i = res_indexes[m->obj_id()];
  if (i >= fuel_incommods.size()) {
    throw KeyError("cycamore::Reactor - no incommod for material object");
  }
  return fuel_incommods[i];
}

std::string Reactor::fuel_outcommod(Material::Ptr m) {
  int i = res_indexes[m->obj_id()];
  if (i >= fuel_outcommods.size()) {
    throw KeyError("cycamore::Reactor - no outcommod for material object");
  }
  return fuel_outcommods[i];
}

std::string Reactor::fuel_inrecipe(Material::Ptr m) {
  int i = res_indexes[m->obj_id()];
  if (i >= fuel_inrecipes.size()) {
    throw KeyError("cycamore::Reactor - no inrecipe for material object");
  }
  return fuel_inrecipes[i];
}

std::string Reactor::fuel_outrecipe(Material::Ptr m) {
  int i = res_indexes[m->obj_id()];
  if (i >= fuel_outrecipes.size()) {
    throw KeyError("cycamore::Reactor - no outrecipe for material object");
  }
  return fuel_outrecipes[i];
}

double Reactor::fuel_pref(Material::Ptr m) {
  int i = res_indexes[m->obj_id()];
  if (i >= fuel_prefs.size()) {
    return 0;
  }
  return fuel_prefs[i];
}

void Reactor::index_res(cyclus::Resource::Ptr m, std::string incommod) {
  for (int i = 0; i < fuel_incommods.size(); i++) {
    if (fuel_incommods[i] == incommod) {
      res_indexes[m->obj_id()] = i;
      return;
    }
  }
  throw ValueError("cycamore::Reactor - received unsupported incommod material");
}

Material::Ptr Reactor::PopSpentRes(std::string outcommod) {
  MatVec mats = spent.PopN(spent.count());
  Material::Ptr m;
  bool found = false;
  for (int i = 0; i < mats.size(); i++) {
    std::string commod = fuel_outcommod(mats[i]);
    if (!found && commod == outcommod) {
      m = mats[i];
      found = true;
    } else {
      spent.Push(mats[i]);
    }
  }
  return m;
}

MatVec Reactor::SpentResFor(std::string outcommod) {
  MatVec mats = spent.PopN(spent.count());
  MatVec found;
  spent.Push(mats);
  for (int i = 0; i < mats.size(); i++) {
    std::string commod = fuel_outcommod(mats[i]);
    if (commod == outcommod) {
      found.push_back(mats[i]);
    }
  }
  return found;
}

void Reactor::Record(std::string name) {
  context()->NewDatum("ReactorEvents")
    ->AddVal("AgentId", id())
    ->AddVal("Time", context()->time())
    ->AddVal("Event", name)
    ->Record();
}

extern "C" cyclus::Agent* ConstructReactor(cyclus::Context* ctx) {
  return new Reactor(ctx);
}

} // namespace cycamore

<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <math.h>
#include <vector>
#include <iostream>
#include <math.h>
#include <array>

/************************************************************
This is a simple isend/ireceive program in MPI
************************************************************/
using namespace std;

vector <vector <char>> create_environment(int dimention){
	vector <vector <char>> env;

	for (int i = 0; i < dimention; ++i){
		vector <char> row;
		for (int j = 0; j < dimention; ++j){
			row.push_back(0);
		}
		env.push_back(row);
	}

	return env;
}

vector <vector <char>> set_diagonal(vector <vector <char>> env){
	for (unsigned int i = 0; i < env.size(); ++i){
		for (unsigned int j = 0; j < env.at(i).size(); ++j){
			if (i == j){
				env[i][j] = 1;
			}
		}
	}
	for (unsigned int i = 0; i < env.size(); ++i){
		for (unsigned int j = 0; j < env.at(i).size(); ++j){
			if (j == (env.size() - i - 1)){
				env[i][j] = 1;
			}
		}
	}
	return env;
}

char * vector_to_array(vector<vector<char>> env, int dimention){
	char * arr = new char[dimention * dimention];
	int index = 0;
	for (unsigned int i = 0; i < env.size(); ++i){
		for (unsigned int j = 0; j < env[0].size(); ++j){
			arr[index] = env[i][j];
			++index;
		}
	}
	env.clear();
	return arr;
}

void print_array(char arr[], int full_dimention){
	// PRINTING ARRAY
	cout << endl;
	for (int i = 0; i < full_dimention; ++i){
		cout << (int)arr[i];
		if (((i + 1) % (int)sqrt(full_dimention)) == 0 && i / 1 != 0){
			cout << endl;
		}
	}
}

void print_division_array(char arr[], int full_size, int dimention){
	// PRINTING ARRAY
	cout << endl;
	for (int i = 0; i < full_size; ++i){
		cout << (int)arr[i];
		if (((i + 1) % dimention) == 0 && i / 1 != 0){
			cout << endl;
		}
	}
}

char * array_copy(char arr[], int full_dimention){
	char * new_arr = new char[full_dimention];
	copy(arr, arr + (full_dimention), new_arr);
	return new_arr;
}

int check_neighbours(char arr[], int dimention, int x){
	int count = 0;
	char a, b, c, d, e, f, g, h = 0;
	a = b = c = d = e = f = g = h;

	if ((x - dimention - 1) > -1 && ((int)((x - dimention - 1) / dimention)) == ((int)((x - dimention) / dimention))){
		a = arr[x - dimention - 1];
	}

	if (x - dimention > -1){
		b = arr[x - dimention];
	}

	if ((x - dimention + 1 > 0) && ((int)((x - dimention + 1) / dimention)) == ((int)((x - dimention) / dimention))){
		c = arr[x - dimention + 1];
	}

	if (x - 1 > -1 && ((int)((x - 1) / dimention)) == ((int)(x / dimention))){
		d = arr[x - 1];
	}

	if (x + 1 < dimention*dimention && ((int)((x + 1) / dimention)) == ((int)(x / dimention))){
		e = arr[x + 1];
	}

	if ((x + dimention - 1) < dimention*dimention && ((int)((x + dimention - 1) / dimention)) == ((int)((x + dimention) / dimention))){
		f = arr[x + dimention - 1];
	}

	if ((x + dimention) < dimention*dimention ){
		g = arr[x + dimention];
	}

	if ((x + dimention + 1) < dimention*dimention && ((int)((x + dimention + 1) / dimention)) == ((int)((x + dimention) / dimention))){
		h = arr[x + dimention + 1];
	}

	count = a + b + c + d + e + f + g + h;

	return count;
}

int main(int argc, char *argv[])
{

	int tag = 7;
	int array_broadcast = 9;
	int calculation = 8;
	int count = 10;
	int dimention = 10;
	int full_dimention = 100;

	//MPI_Status status;
	//MPI_Request request;
	MPI_Request request;
    MPI_Status status;
	request = MPI_REQUEST_NULL;

	MPI_Request	send_request,recv_request;

	const int size = 10;

 	char buffi[100] = {};
 	char buffo[100] = {};
 	char buffc[100];

 	for (int i = 0; i < 100; ++i){
 		buffc[i] = 0;
 	}

 	//print_array(buffo, 100);

 	vector< vector<char>> env = create_environment(dimention);
	env = set_diagonal(env);

	char * arr = vector_to_array(env, dimention);
	char * b_arr = array_copy(arr, full_dimention);

	int	        buffsize = 100;
	char       *sendbuff,*recvbuff;
	sendbuff=(char *)malloc(sizeof(char)*buffsize);
	recvbuff=(char *)malloc(sizeof(char)*buffsize);

	for(int i=0;i<buffsize;i++){
     sendbuff[i]=0;
   	}

	//print_array(arr, full_dimention);

	// int test = 0;
	// if (test == 1){

	// 	cout << "ITERATIONS TEST" << endl;

	// 	int iterations = 13;

	// 	char * b_arr = array_copy(arr, full_dimention);

	// 	while (iterations > 0){

	// 		char * c_arr = array_copy(b_arr, full_dimention);

	// 		for (int i = 0; i < full_dimention; ++i){

	// 			int neighbours = check_neighbours(b_arr, dimention, i);

	// 			if (b_arr[i] == 0){
	// 				if (neighbours == 1 || neighbours == 2){
	// 					c_arr[i] = 1;
	// 				}
	// 			}
	// 			else {
	// 				if (neighbours > 2 || neighbours < 1){
	// 					c_arr[i] = 0;
	// 				}
	// 			}
	// 		}
	// 		cout << iterations << endl;
	// 	 	print_array(c_arr, full_dimention);

	// 	 	copy(c_arr, c_arr + (full_dimention), b_arr);
	// 	 	--iterations;
	// 	 	free(c_arr);

	// 	}
	// }

	// CORRECT ABOVE

	// MPI INIT
	MPI_Init(&argc,&argv);

	int numprocs;
	MPI_Comm_size(MPI_COMM_WORLD,&numprocs);

	int id;
	MPI_Comm_rank(MPI_COMM_WORLD,&id);

	int iterations = 2;

	//while (iterations > 0){
		if (id == 1){

			//MPI_Irecv(&buffc,full_dimention,MPI_CHAR,0,tag,MPI_COMM_WORLD,&request);
			int ierr=MPI_Irecv(b_arr,buffsize,MPI_CHAR,0,array_broadcast,MPI_COMM_WORLD,&recv_request);
			ierr=MPI_Wait(&recv_request,&status);
			//print_array(recvbuff, full_dimention);
			cout << "Buff received" << endl;

		}
		if (id == 0){

			//MPI_Isend(&arr,full_dimention,MPI_CHAR,1,tag,MPI_COMM_WORLD,&request);
			int ierr=MPI_Isend(arr,buffsize,MPI_CHAR, 1,array_broadcast,MPI_COMM_WORLD,&send_request);
			//print_array(arr, full_dimention);
			ierr=MPI_Wait(&send_request,&status);
			cout << "Buff sent" << endl;
		}

		//MPI_Wait(&request,&status);

		if (id == 1){
			--iterations;

			print_array(b_arr, full_dimention);
			// for (int i = id; i < full_dimention/dimention; i+=numprocs){
			// 	cout << "P1 Checking " << i << endl;
			// 	for (int j = 0; j < dimention; ++j){
			// 		cout << "\t -> " << (i*dimention)+j << endl;
			// 	}
			// }
			int division = full_dimention/numprocs;
			cout << division << endl;
			char * local_arr = new char[division];
			char l_arr[division];
			int index = 0;
			for (int i = id * division; i < ((id + 1)*division); ++i){
				int neighbours = check_neighbours(b_arr, dimention, i);
				cout << i << " -> "<< neighbours << endl;
				cout << "\t -> "<< (int)b_arr[i] << endl;
				local_arr[index] = 0;
				if (b_arr[i] == 0){
					cout << "\t\t- 0 "<< endl;
					if (neighbours == 1 || neighbours == 2){
						cout << "\t\t\t setting to 1 "<< endl;
						local_arr[index] = 1;
					}
				}
				else {
					cout << "\t\t- 1 "<< endl;
					if (neighbours > 2 || neighbours < 1){
						cout << "\t\t\t setting to 0 "<< endl;
						local_arr[index] = 0;
					}
				}
				++index;
			}
			for (int i = 0; i < division; ++i){
				cout << (int)local_arr[i] << " ";
			}
			print_division_array(local_arr, division, dimention);

		}
		if (id == 0){
			--iterations;

			// for (int i = id; i < full_dimention/dimention; i+=numprocs){
			// 	cout << "P0 Checking " << i << endl;
			// 	for (int j = 0; j < dimention; ++j){
			// 		cout << "\t -> " << (i*dimention)+j << endl;
			// 	}
			// }

		}

		//--iterations;
	//}

	MPI_Finalize();

	return 0;

 	// MPI INIT
	MPI_Init(&argc,&argv);

	//int numprocs;
	MPI_Comm_size(MPI_COMM_WORLD,&numprocs);

	//int id;
	MPI_Comm_rank(MPI_COMM_WORLD,&id);

	if(id == 0){
		//MPI_Isend(&buffi,count,MPI_CHAR,0,tag,MPI_COMM_WORLD,&request);
		//MPI_Isend(&buffi,count,MPI_CHAR,1,tag,MPI_COMM_WORLD,&request);
		//MPI_Isend(&buffi,count,MPI_CHAR,2,tag,MPI_COMM_WORLD,&request);
		//MPI_Isend(&buffi,count,MPI_CHAR,3,tag,MPI_COMM_WORLD,&request);
	}
	if(id == 0){
		//MPI_Irecv(&buffo,count,MPI_CHAR,0,tag,MPI_COMM_WORLD,&request);
	}
	if(id == 1){
		//MPI_Irecv(&buffo,count,MPI_CHAR,0,tag,MPI_COMM_WORLD,&request);
	}
	if(id == 2){
		//MPI_Irecv(&buffo,count,MPI_CHAR,0,tag,MPI_COMM_WORLD,&request);
	}
	if(id == 3){
		//MPI_Irecv(&buffo,count,MPI_CHAR,0,tag,MPI_COMM_WORLD,&request);
	}

	//MPI_Wait(&request,&status);
	if(id == 0){
		printf("processor %d sent %d\n",id,(int)buffi[0]);
		printf("processor %d sent %d\n",id,(int)buffi[0]);
		printf("processor %d sent %d\n",id,(int)buffi[0]);
		printf("processor %d sent %d\n",id,(int)buffi[0]);
	}
	if(id == 0){
		for (unsigned int i = 0; i < count; ++i){
			printf("processor %d got %d - %d\n",id,i,(int)buffo[i]);
		}
	}
	if(id == 1){
		for (unsigned int i = 0; i < count; ++i){
			printf("processor %d got %d - %d\n",id,i,(int)buffo[i]);
		}
	}
	if(id == 2){
		for (unsigned int i = 0; i < count; ++i){
			printf("processor %d got %d - %d\n",id,i,(int)buffo[i]);
		}
	}
	if(id == 3){
		for (unsigned int i = 0; i < count; ++i){
			printf("processor %d got %d - %d\n",id,i,(int)buffo[i]);
		}
	}

	MPI_Finalize();

	return 0;
}<commit_msg>Motherfucker! Finally it works, although most of the stuff is hardcoded..<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <math.h>
#include <vector>
#include <iostream>
#include <math.h>
#include <array>

/************************************************************
This is a simple isend/ireceive program in MPI
************************************************************/
using namespace std;

vector <vector <char>> create_environment(int dimention){
	vector <vector <char>> env;

	for (int i = 0; i < dimention; ++i){
		vector <char> row;
		for (int j = 0; j < dimention; ++j){
			row.push_back(0);
		}
		env.push_back(row);
	}

	return env;
}

vector <vector <char>> set_diagonal(vector <vector <char>> env){
	for (unsigned int i = 0; i < env.size(); ++i){
		for (unsigned int j = 0; j < env.at(i).size(); ++j){
			if (i == j){
				env[i][j] = 1;
			}
		}
	}
	for (unsigned int i = 0; i < env.size(); ++i){
		for (unsigned int j = 0; j < env.at(i).size(); ++j){
			if (j == (env.size() - i - 1)){
				env[i][j] = 1;
			}
		}
	}
	return env;
}

char * vector_to_array(vector<vector<char>> env, int dimention){
	char * arr = new char[dimention * dimention];
	int index = 0;
	for (unsigned int i = 0; i < env.size(); ++i){
		for (unsigned int j = 0; j < env[0].size(); ++j){
			arr[index] = env[i][j];
			++index;
		}
	}
	env.clear();
	return arr;
}

void print_array(char arr[], int full_dimention){
	// PRINTING ARRAY
	cout << endl;
	for (int i = 0; i < full_dimention; ++i){
		cout << (int)arr[i];
		if (((i + 1) % (int)sqrt(full_dimention)) == 0 && i / 1 != 0){
			cout << endl;
		}
	}
}

void print_division_array(char arr[], int full_size, int dimention){
	// PRINTING ARRAY
	cout << endl;
	for (int i = 0; i < full_size; ++i){
		cout << (int)arr[i];
		if (((i + 1) % dimention) == 0 && i / 1 != 0){
			cout << endl;
		}
	}
}

char * array_copy(char arr[], int full_dimention){
	char * new_arr = new char[full_dimention];
	copy(arr, arr + (full_dimention), new_arr);
	return new_arr;
}

int check_neighbours(char arr[], int dimention, int x){
	int count = 0;
	char a, b, c, d, e, f, g, h = 0;
	a = b = c = d = e = f = g = h;

	if ((x - dimention - 1) > -1 && ((int)((x - dimention - 1) / dimention)) == ((int)((x - dimention) / dimention))){
		a = arr[x - dimention - 1];
	}

	if (x - dimention > -1){
		b = arr[x - dimention];
	}

	if ((x - dimention + 1 > 0) && ((int)((x - dimention + 1) / dimention)) == ((int)((x - dimention) / dimention))){
		c = arr[x - dimention + 1];
	}

	if (x - 1 > -1 && ((int)((x - 1) / dimention)) == ((int)(x / dimention))){
		d = arr[x - 1];
	}

	if (x + 1 < dimention*dimention && ((int)((x + 1) / dimention)) == ((int)(x / dimention))){
		e = arr[x + 1];
	}

	if ((x + dimention - 1) < dimention*dimention && ((int)((x + dimention - 1) / dimention)) == ((int)((x + dimention) / dimention))){
		f = arr[x + dimention - 1];
	}

	if ((x + dimention) < dimention*dimention ){
		g = arr[x + dimention];
	}

	if ((x + dimention + 1) < dimention*dimention && ((int)((x + dimention + 1) / dimention)) == ((int)((x + dimention) / dimention))){
		h = arr[x + dimention + 1];
	}

	count = a + b + c + d + e + f + g + h;

	return count;
}

int main(int argc, char *argv[])
{

	int tag = 7;
	int array_broadcast = 9;
	int calculation = 8;
	int count = 100;
	int dimention = 100;
	int full_dimention = 10000;

	//MPI_Status status;
	//MPI_Request request;
	MPI_Request request;
    MPI_Status status;
	request = MPI_REQUEST_NULL;

	MPI_Request	send_request,recv_request;

	const int size = 100;

 	char buffi[10000] = {};
 	char buffo[10000] = {};
 	char buffc[10000];

 	for (int i = 0; i < 10000; ++i){
 		buffc[i] = 0;
 	}

 	//print_array(buffo, 100);

 	vector< vector<char>> env = create_environment(dimention);
	env = set_diagonal(env);

	char * arr = vector_to_array(env, dimention);
	char * b_arr = array_copy(arr, full_dimention);

	int	        buffsize = 10000;
	char       *sendbuff,*recvbuff;
	sendbuff=(char *)malloc(sizeof(char)*buffsize);
	recvbuff=(char *)malloc(sizeof(char)*buffsize);

	for(int i=0;i<buffsize;i++){
     sendbuff[i]=0;
   	}

	//print_array(arr, full_dimention);

	// int test = 0;
	// if (test == 1){

	// 	cout << "ITERATIONS TEST" << endl;

	// 	int iterations = 13;

	// 	char * b_arr = array_copy(arr, full_dimention);

	// 	while (iterations > 0){

	// 		char * c_arr = array_copy(b_arr, full_dimention);

	// 		for (int i = 0; i < full_dimention; ++i){

	// 			int neighbours = check_neighbours(b_arr, dimention, i);

	// 			if (b_arr[i] == 0){
	// 				if (neighbours == 1 || neighbours == 2){
	// 					c_arr[i] = 1;
	// 				}
	// 			}
	// 			else {
	// 				if (neighbours > 2 || neighbours < 1){
	// 					c_arr[i] = 0;
	// 				}
	// 			}
	// 		}
	// 		cout << iterations << endl;
	// 	 	print_array(c_arr, full_dimention);

	// 	 	copy(c_arr, c_arr + (full_dimention), b_arr);
	// 	 	--iterations;
	// 	 	free(c_arr);

	// 	}
	// }

	// CORRECT ABOVE

	// MPI INIT
	MPI_Init(&argc,&argv);

	int numprocs;
	MPI_Comm_size(MPI_COMM_WORLD,&numprocs);

	int id;
	MPI_Comm_rank(MPI_COMM_WORLD,&id);

	int iterations = 200;

	while (iterations > 0){
		if (id == 1){

			//MPI_Irecv(&buffc,full_dimention,MPI_CHAR,0,tag,MPI_COMM_WORLD,&request);
			int ierr=MPI_Irecv(b_arr,buffsize,MPI_CHAR,0,array_broadcast,MPI_COMM_WORLD,&recv_request);
			ierr=MPI_Wait(&recv_request,&status);
			//print_array(recvbuff, full_dimention);
			//cout << "Buff received" << endl;

		}
		if (id == 0){

			//MPI_Isend(&arr,full_dimention,MPI_CHAR,1,tag,MPI_COMM_WORLD,&request);
			int ierr=MPI_Isend(arr,buffsize,MPI_CHAR, 1,array_broadcast,MPI_COMM_WORLD,&send_request);
			//print_array(arr, full_dimention);
			ierr=MPI_Wait(&send_request,&status);
			//cout << "Buff sent" << endl;
		}

		//MPI_Wait(&request,&status);

		if (id == 1){
			--iterations;

			//print_array(b_arr, full_dimention);
			// for (int i = id; i < full_dimention/dimention; i+=numprocs){
			// 	cout << "P1 Checking " << i << endl;
			// 	for (int j = 0; j < dimention; ++j){
			// 		cout << "\t -> " << (i*dimention)+j << endl;
			// 	}
			// }
			int division = full_dimention/numprocs;

			char * local_arr = new char[division];

			int index = 0;
			for (int i = id * division; i < ((id + 1)*division); ++i){
				int neighbours = check_neighbours(b_arr, dimention, i);
				local_arr[index] = 0;
				if (b_arr[i] == 0){
					if (neighbours == 1 || neighbours == 2){
						local_arr[index] = 1;
					}
				}
				else {
					if (neighbours > 2 || neighbours < 1){
						local_arr[index] = 0;
					}
				}
				++index;
			}
			//cout << "Process 1" << endl;
			//print_division_array(local_arr, division, dimention);

			int ierr=MPI_Isend(local_arr,division,MPI_CHAR, 0,calculation,MPI_COMM_WORLD,&send_request);
			ierr=MPI_Wait(&send_request,&status);
			//cout << "Buff sent" << endl;

		}
		if (id == 0){
			--iterations;

			//print_array(arr, full_dimention);
			// for (int i = id; i < full_dimention/dimention; i+=numprocs){
			// 	cout << "P0 Checking " << i << endl;
			// 	for (int j = 0; j < dimention; ++j){
			// 		cout << "\t -> " << (i*dimention)+j << endl;
			// 	}
			// }
			int division = full_dimention/numprocs;

			char * local_arr = new char[division];

			int index = 0;
			for (int i = id * division; i < ((id + 1)*division); ++i){
				int neighbours = check_neighbours(arr, dimention, i);
				local_arr[index] = 0;
				if (arr[i] == 0){
					if (neighbours == 1 || neighbours == 2){
						local_arr[index] = 1;
					}
				}
				else {
					if (neighbours > 2 || neighbours < 1){
						local_arr[index] = 0;
					}
				}
				++index;
			}
			//cout << "Process 0" << endl;

			char * received_arr = new char[division];

			int ierr=MPI_Irecv(received_arr,division,MPI_CHAR,1,calculation,MPI_COMM_WORLD,&recv_request);

			ierr=MPI_Wait(&recv_request,&status);

			//cout << 0 << endl;
			//print_division_array(local_arr, division, dimention);
			//cout << 1 << endl;
			//print_division_array(received_arr, division, dimention);

			char * next_arr = new char[full_dimention];
			for (int i = 0; i < full_dimention; ++i){
				next_arr[i] = -1;
			}

			for (int i = 0; i < division; ++i){
				next_arr[i] = local_arr[i];
			}
			for (int i = 5000,j=0; i < division+5000; ++i,++j){
				next_arr[i] = received_arr[j];
			}

			print_array(next_arr, full_dimention);

			arr = array_copy(next_arr, full_dimention);

		}

		//--iterations;
	}

	MPI_Finalize();

	return 0;

 	// MPI INIT
	MPI_Init(&argc,&argv);

	//int numprocs;
	MPI_Comm_size(MPI_COMM_WORLD,&numprocs);

	//int id;
	MPI_Comm_rank(MPI_COMM_WORLD,&id);

	if(id == 0){
		//MPI_Isend(&buffi,count,MPI_CHAR,0,tag,MPI_COMM_WORLD,&request);
		//MPI_Isend(&buffi,count,MPI_CHAR,1,tag,MPI_COMM_WORLD,&request);
		//MPI_Isend(&buffi,count,MPI_CHAR,2,tag,MPI_COMM_WORLD,&request);
		//MPI_Isend(&buffi,count,MPI_CHAR,3,tag,MPI_COMM_WORLD,&request);
	}
	if(id == 0){
		//MPI_Irecv(&buffo,count,MPI_CHAR,0,tag,MPI_COMM_WORLD,&request);
	}
	if(id == 1){
		//MPI_Irecv(&buffo,count,MPI_CHAR,0,tag,MPI_COMM_WORLD,&request);
	}
	if(id == 2){
		//MPI_Irecv(&buffo,count,MPI_CHAR,0,tag,MPI_COMM_WORLD,&request);
	}
	if(id == 3){
		//MPI_Irecv(&buffo,count,MPI_CHAR,0,tag,MPI_COMM_WORLD,&request);
	}

	//MPI_Wait(&request,&status);
	if(id == 0){
		printf("processor %d sent %d\n",id,(int)buffi[0]);
		printf("processor %d sent %d\n",id,(int)buffi[0]);
		printf("processor %d sent %d\n",id,(int)buffi[0]);
		printf("processor %d sent %d\n",id,(int)buffi[0]);
	}
	if(id == 0){
		for (unsigned int i = 0; i < count; ++i){
			printf("processor %d got %d - %d\n",id,i,(int)buffo[i]);
		}
	}
	if(id == 1){
		for (unsigned int i = 0; i < count; ++i){
			printf("processor %d got %d - %d\n",id,i,(int)buffo[i]);
		}
	}
	if(id == 2){
		for (unsigned int i = 0; i < count; ++i){
			printf("processor %d got %d - %d\n",id,i,(int)buffo[i]);
		}
	}
	if(id == 3){
		for (unsigned int i = 0; i < count; ++i){
			printf("processor %d got %d - %d\n",id,i,(int)buffo[i]);
		}
	}

	MPI_Finalize();

	return 0;
}<|endoftext|>


<commit_before>// main.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Utilities.h"

#include <tesseract\baseapi.h>
#include <leptonica\allheaders.h>

using namespace std;
using namespace cv;
using namespace tesseract;

// Functions to load in a single image or all images
Mat loadImage(char* location, char* file);
Mat* loadImages(int numberOfImages, char* location, char** files);

// A function which temporarily resizes images before showing them
void showImage(char* name, Mat image);

// "Sign" functions - used to detect bus stop signs
Mat findSign(Mat image);
Mat binaryImage(Mat image);
Mat backProjection(Mat image, Mat yellow);
Mat getHue(Mat image);
Mat templateMatching(Mat image, Mat templateImage);

// "Number" function - used to detect the stop number from the sign
int digitRecognition(Mat image, Mat* numbers);

int _tmain(int argc, _TCHAR* argv[])
{
	cout << "Using OpenCV " << CV_VERSION << endl;
	char* testLocation = "Media/Test Images/";  // Location of bus stop sign images

	// Bus stop sign images
	char* testFiles[] = {
		"2809 a.jpg",
		"2809 b.jpg",
		"2830 a.jpg",
		"2830 b.jpg",
		"2838 a.jpg",
		"2838 b.jpg",
		"2838 c.jpg",
		"2838 d.jpg",
		"2839 a.jpg",
		"2839 b.jpg",
		"2839 c.jpg",
		"2839 d.jpg",
		"bus stop.png"
	};

	char* numberLocation = "Media/Numbers/";

	char* numberFiles[] = {
		"0.png",
		"1.png",
		"2.png",
		"3.png",
		"4.png",
		"5.png",
		"6.png",
		"7.png",
		"8.png",
		"9.png"
	};

	char* templateLocation = "Media/Templates/";    // Location of sample stop sign images

	// Sample stop sign images
	char* templateFiles[] = {
		"stop.png",
		"stop&no.png",
		"stop2.png",
		"stop&no2.png",
		"yellow.png"
	};

	int numberOfNumbers = sizeof(numberFiles) / sizeof(numberFiles[0]);
	Mat* numbers = loadImages(numberOfNumbers, numberLocation, numberFiles);

	Mat sign = loadImage(testLocation, testFiles[12]);
	Mat templateSign = loadImage(templateLocation, templateFiles[2]);
	Mat yellow = loadImage(templateLocation, templateFiles[4]);

	showImage("Bus Stop Sign", sign);
	Mat backProjSign = backProjection(sign, yellow);

	erode(backProjSign, backProjSign, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
	dilate(backProjSign, backProjSign, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));

	//int stopNumber = digitRecognition(backProjSign, numbers);

	showImage("Back Projection", backProjSign);
	waitKey(0);

	/*Mat hsvSign = findSign(sign);
	Mat binary = binaryImage(sign);
	Mat backProjSign = backProjection(sign, yellow);
	//Mat templateMatch = templateMatching(sign, templateSign);
	Mat templateMatch = templateMatching(sign, yellow);

	showImage("HSV", hsvSign);
	showImage("Binary", binary);
	showImage("Back Projection", backProjSign);
	showImage("Template Matching", templateMatch);
	waitKey(0);*/

	/*int numberOfTestImages = sizeof(testFiles) / sizeof(testFiles[0]);
	Mat* busStops = loadImages(numberOfTestImages, testLocation, testFiles);
	int numberOfTemplateImages = sizeof(templateFiles) / sizeof(templateFiles[0]);
	Mat* templates = loadImages(numberOfTemplateImages, templateLocation, templateFiles);

	for (int i = 0; i < numberOfTestImages; i++) {
	cout << "Processing image " << (i + 1) << endl;
	showImage("Sign", busStops[i]);
	Mat hsvSign = findSign(busStops[i]);
	Mat binary = binaryImage(busStops[i]);
	Mat backProjSign = backProjection(busStops[i], templates[4]);
	Mat templateMatch;
	if (i == 0 || i == 1) {
	// templates[0] or templates[1]
	templateMatch = templateMatching(busStops[i], templates[0]);

	}
	else {
	// templates[2] or templates[3]
	templateMatch = templateMatching(busStops[i], templates[2]);

	}

	showImage("HSV", hsvSign);
	showImage("Binary", binary);
	showImage("Back Projection", backProjSign);
	showImage("Template Matching", templateMatch);

	waitKey(0);
	}*/

	return 0;
}

void multipleFiles() {
	int numberOfTestImages = sizeof(testFiles) / sizeof(testFiles[0]);
	Mat* busStops = loadImages(numberOfTestImages, testLocation, testFiles);
	int numberOfTemplateImages = sizeof(templateFiles) / sizeof(templateFiles[0]);
	Mat* templates = loadImages(numberOfTemplateImages, templateLocation, templateFiles);

	for (int i = 0; i < numberOfTestImages; i++) {
		cout << "Processing image " << (i + 1) << endl;
		showImage("Sign", busStops[i]);
		Mat hsvSign = findSign(busStops[i]);
		Mat binary = binaryImage(busStops[i]);
		Mat backProjSign = backProjection(busStops[i], templates[4]);
		Mat templateMatch;
		if (i == 0 || i == 1) {
			// templates[0] or templates[1]
			templateMatch = templateMatching(busStops[i], templates[0]);

		}
		else {
			// templates[2] or templates[3]
			templateMatch = templateMatching(busStops[i], templates[2]);

		}

		showImage("HSV", hsvSign);
		showImage("Binary", binary);
		showImage("Back Projection", backProjSign);
		showImage("Template Matching", templateMatch);

		waitKey(0);
	}
}

Mat loadImage(char* location, char* file) {
	string filename(location);
	filename.append(file);
	Mat image = imread(filename, 1);

	return image;
}

Mat* loadImages(int numberOfImages, char* location, char** files) {
	Mat* images = new Mat[numberOfImages];
	for (int i = 0; i < numberOfImages; i++) {
		string filename(location);
		filename.append(files[i]);
		cout << "Loading image " << (i + 1) << ": " << filename << endl;
		images[i] = imread(filename, 1);
	}
	return images;
}

void showImage(char* name, Mat image) {
	resize(image, image, Size(image.cols / 4, image.rows / 4));
	imshow(name, image);

	return;
}

Mat findSign(Mat image) {
	Mat hsv;
	cvtColor(image, hsv, CV_BGR2HSV);
	inRange(hsv, Scalar(15, 135, 140), Scalar(30, 255, 255), hsv);

	return hsv;
}

Mat binaryImage(Mat image) {
	Mat greyImage, binaryResult;
	cvtColor(image, greyImage, CV_BGR2GRAY);
	threshold(greyImage, binaryResult, 200, 255, THRESH_BINARY);

	return binaryResult;
}

Mat backProjection(Mat image, Mat yellow) {
	Mat imageHue = getHue(image);
	Mat yellowHue = getHue(yellow);

	Mat hist;
	int histSize = 180;
	float hueRange[] = { 0, 180 };
	const float* ranges = { hueRange };

	calcHist(&yellowHue, 1, 0, Mat(), hist, 1, &histSize, &ranges, true, false);
	normalize(hist, hist, 0, 255, NORM_MINMAX, -1, Mat());

	Mat backProject;
	calcBackProject(&imageHue, 1, 0, hist, backProject, &ranges, 1, true);

	return backProject;
}

Mat getHue(Mat image) {
	Mat hsv, hue;
	cvtColor(image, hsv, CV_BGR2HSV);

	hue.create(hsv.size(), hsv.depth());
	int ch[] = { 0, 0 };
	mixChannels(&hsv, 1, &hue, 1, ch, 1);

	return hue;
}

Mat templateMatching(Mat image, Mat templateImage) {
	Mat result;

	Mat imageDisplay;
	image.copyTo(imageDisplay);

	int rows = image.rows - templateImage.rows + 1;
	int cols = image.cols - templateImage.cols + 1;

	result.create(rows, cols, CV_32FC1);

	matchTemplate(image, templateImage, result, CV_TM_SQDIFF);
	normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());

	double minVal, maxVal;
	Point minLoc, maxLoc, matchLoc;

	minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());

	matchLoc = minLoc;

	rectangle(imageDisplay, matchLoc, Point(matchLoc.x + templateImage.cols, matchLoc.y + templateImage.rows), Scalar::all(0), 2, 8, 0);
	rectangle(result, matchLoc, Point(matchLoc.x + templateImage.cols, matchLoc.y + templateImage.rows), Scalar::all(0), 2, 8, 0);

	/*showImage("Image", imageDisplay);
	showImage("Result", result);
	waitKey(0);*/

	//return result;
	return imageDisplay;
}

int digitRecognition(Mat image, Mat* numbers) {
	// TODO: recognise numbers from sign
	// Statistical Pattern Recognition
	// Scene Text Recognition - OCRTesseract
	// Template Matching
	// Chamfer Matching
	// Haar Classifiers

	//TessBaseAPI tess;
	/*tess.Init(NULL, "eng", tesseract::OEM_DEFAULT);
	tess.SetVariable("tessedit_char_whitelist", "0123456789");
	tess.SetPageSegMode(tesseract::PSM_SINGLE_BLOCK);
	tess.SetImage((uchar*)image.data, image.cols, image.rows, 1, image.cols);*/

	showImage("Sign", image);
	waitKey(0);

	return 0;
}<commit_msg>removed accidental 'multipleFile' function<commit_after>// main.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Utilities.h"

#include <tesseract\baseapi.h>
#include <leptonica\allheaders.h>

using namespace std;
using namespace cv;
using namespace tesseract;

// Functions to load in a single image or all images
Mat loadImage(char* location, char* file);
Mat* loadImages(int numberOfImages, char* location, char** files);

// A function which temporarily resizes images before showing them
void showImage(char* name, Mat image);

// "Sign" functions - used to detect bus stop signs
Mat findSign(Mat image);
Mat binaryImage(Mat image);
Mat backProjection(Mat image, Mat yellow);
Mat getHue(Mat image);
Mat templateMatching(Mat image, Mat templateImage);

// "Number" function - used to detect the stop number from the sign
int digitRecognition(Mat image, Mat* numbers);

int _tmain(int argc, _TCHAR* argv[])
{
	cout << "Using OpenCV " << CV_VERSION << endl;
	char* testLocation = "Media/Test Images/";  // Location of bus stop sign images

	// Bus stop sign images
	char* testFiles[] = {
		"2809 a.jpg",
		"2809 b.jpg",
		"2830 a.jpg",
		"2830 b.jpg",
		"2838 a.jpg",
		"2838 b.jpg",
		"2838 c.jpg",
		"2838 d.jpg",
		"2839 a.jpg",
		"2839 b.jpg",
		"2839 c.jpg",
		"2839 d.jpg",
		"bus stop.png"
	};

	char* numberLocation = "Media/Numbers/";

	char* numberFiles[] = {
		"0.png",
		"1.png",
		"2.png",
		"3.png",
		"4.png",
		"5.png",
		"6.png",
		"7.png",
		"8.png",
		"9.png"
	};

	char* templateLocation = "Media/Templates/";    // Location of sample stop sign images

	// Sample stop sign images
	char* templateFiles[] = {
		"stop.png",
		"stop&no.png",
		"stop2.png",
		"stop&no2.png",
		"yellow.png"
	};

	int numberOfNumbers = sizeof(numberFiles) / sizeof(numberFiles[0]);
	Mat* numbers = loadImages(numberOfNumbers, numberLocation, numberFiles);

	Mat sign = loadImage(testLocation, testFiles[12]);
	Mat templateSign = loadImage(templateLocation, templateFiles[2]);
	Mat yellow = loadImage(templateLocation, templateFiles[4]);

	showImage("Bus Stop Sign", sign);
	Mat backProjSign = backProjection(sign, yellow);

	/*erode(backProjSign, backProjSign, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
	dilate(backProjSign, backProjSign, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));*/

	//int stopNumber = digitRecognition(backProjSign, numbers);

	showImage("Back Projection", backProjSign);
	waitKey(0);

	/*Mat hsvSign = findSign(sign);
	Mat binary = binaryImage(sign);
	Mat backProjSign = backProjection(sign, yellow);
	//Mat templateMatch = templateMatching(sign, templateSign);
	Mat templateMatch = templateMatching(sign, yellow);

	showImage("HSV", hsvSign);
	showImage("Binary", binary);
	showImage("Back Projection", backProjSign);
	showImage("Template Matching", templateMatch);
	waitKey(0);*/

	/*int numberOfTestImages = sizeof(testFiles) / sizeof(testFiles[0]);
	Mat* busStops = loadImages(numberOfTestImages, testLocation, testFiles);
	int numberOfTemplateImages = sizeof(templateFiles) / sizeof(templateFiles[0]);
	Mat* templates = loadImages(numberOfTemplateImages, templateLocation, templateFiles);

	for (int i = 0; i < numberOfTestImages; i++) {
	cout << "Processing image " << (i + 1) << endl;
	showImage("Sign", busStops[i]);
	Mat hsvSign = findSign(busStops[i]);
	Mat binary = binaryImage(busStops[i]);
	Mat backProjSign = backProjection(busStops[i], templates[4]);
	Mat templateMatch;
	if (i == 0 || i == 1) {
	// templates[0] or templates[1]
	templateMatch = templateMatching(busStops[i], templates[0]);

	}
	else {
	// templates[2] or templates[3]
	templateMatch = templateMatching(busStops[i], templates[2]);

	}

	showImage("HSV", hsvSign);
	showImage("Binary", binary);
	showImage("Back Projection", backProjSign);
	showImage("Template Matching", templateMatch);

	waitKey(0);
	}*/

	return 0;
}

Mat loadImage(char* location, char* file) {
	string filename(location);
	filename.append(file);
	Mat image = imread(filename, 1);

	return image;
}

Mat* loadImages(int numberOfImages, char* location, char** files) {
	Mat* images = new Mat[numberOfImages];
	for (int i = 0; i < numberOfImages; i++) {
		string filename(location);
		filename.append(files[i]);
		cout << "Loading image " << (i + 1) << ": " << filename << endl;
		images[i] = imread(filename, 1);
	}
	return images;
}

void showImage(char* name, Mat image) {
	resize(image, image, Size(image.cols / 4, image.rows / 4));
	imshow(name, image);

	return;
}

Mat findSign(Mat image) {
	Mat hsv;
	cvtColor(image, hsv, CV_BGR2HSV);
	inRange(hsv, Scalar(15, 135, 140), Scalar(30, 255, 255), hsv);

	return hsv;
}

Mat binaryImage(Mat image) {
	Mat greyImage, binaryResult;
	cvtColor(image, greyImage, CV_BGR2GRAY);
	threshold(greyImage, binaryResult, 200, 255, THRESH_BINARY);

	return binaryResult;
}

Mat backProjection(Mat image, Mat yellow) {
	Mat imageHue = getHue(image);
	Mat yellowHue = getHue(yellow);

	Mat hist;
	int histSize = 180;
	float hueRange[] = { 0, 180 };
	const float* ranges = { hueRange };

	calcHist(&yellowHue, 1, 0, Mat(), hist, 1, &histSize, &ranges, true, false);
	normalize(hist, hist, 0, 255, NORM_MINMAX, -1, Mat());

	Mat backProject;
	calcBackProject(&imageHue, 1, 0, hist, backProject, &ranges, 1, true);

	return backProject;
}

Mat getHue(Mat image) {
	Mat hsv, hue;
	cvtColor(image, hsv, CV_BGR2HSV);

	hue.create(hsv.size(), hsv.depth());
	int ch[] = { 0, 0 };
	mixChannels(&hsv, 1, &hue, 1, ch, 1);

	return hue;
}

Mat templateMatching(Mat image, Mat templateImage) {
	Mat result;

	Mat imageDisplay;
	image.copyTo(imageDisplay);

	int rows = image.rows - templateImage.rows + 1;
	int cols = image.cols - templateImage.cols + 1;

	result.create(rows, cols, CV_32FC1);

	matchTemplate(image, templateImage, result, CV_TM_SQDIFF);
	normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());

	double minVal, maxVal;
	Point minLoc, maxLoc, matchLoc;

	minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());

	matchLoc = minLoc;

	rectangle(imageDisplay, matchLoc, Point(matchLoc.x + templateImage.cols, matchLoc.y + templateImage.rows), Scalar::all(0), 2, 8, 0);
	rectangle(result, matchLoc, Point(matchLoc.x + templateImage.cols, matchLoc.y + templateImage.rows), Scalar::all(0), 2, 8, 0);

	/*showImage("Image", imageDisplay);
	showImage("Result", result);
	waitKey(0);*/

	//return result;
	return imageDisplay;
}

int digitRecognition(Mat image, Mat* numbers) {
	// TODO: recognise numbers from sign
	// Statistical Pattern Recognition
	// Scene Text Recognition - OCRTesseract
	// Template Matching
	// Chamfer Matching
	// Haar Classifiers

	//TessBaseAPI tess;
	/*tess.Init(NULL, "eng", tesseract::OEM_DEFAULT);
	tess.SetVariable("tessedit_char_whitelist", "0123456789");
	tess.SetPageSegMode(tesseract::PSM_SINGLE_BLOCK);
	tess.SetImage((uchar*)image.data, image.cols, image.rows, 1, image.cols);*/

	showImage("Sign", image);
	waitKey(0);

	return 0;
}<|endoftext|>