<commit_before>#include "velar.h"

//Smiðir
velar::velar()
{
    _vNafn = _tegund = "None";
    _byggd = false;
    _bAr = 0;

}

velar::velar(int id, string vNafn, int bAr, string tegund, bool byggd)
{
    _id = id;
    _vNafn = vNafn;
    _bAr = bAr;
    _tegund = tegund;
    _byggd = byggd;
}

//Get föll
int velar::getID() const
{
    return _id;
}

string velar::getVelaNafn() const
{
    return _vNafn;
}

int velar::getByggingarAr() const
{
    return _bAr;
}

string velar::getTegund() const
{
    return _tegund;
}

bool velar::getByggd() const
{
    return _byggd;
}

//Set föll
void velar::uppfVelaNafn(string nyttvNafn)
{
    _vNafn = nyttvNafn;
}

void velar::uppfByggingarAr(int nyttbAr)
{
    _bAr = nyttbAr;
}

void velar::uppfTegund(int nyttTegund)
{
    _tegund = nyttTegund;
}

void velar::uppfByggd(bool nyttByggd)
{
    _byggd = nyttByggd;
}

//ops
ostream& operator <<(ostream& out, const velar& data)
{

    string svar = "";
    if (data.getByggd() == 1)
    {
        svar = "Yes";
    }
    else
    {
        svar = "No";
    }

    //out << "Name of machine: " << data.getVelaNafn() << endl;
    //out << "Year of creation: " << data.getByggingarAr() << endl;
    //out << "Type: " << data.getTegund() << endl;
    //out << "Was it built?: " << data.getByggd() << endl;

    out << "|" << data.getVelaNafn() ;
    if(data.getVelaNafn().size() < 5)
    {
        out << "\t";
    }
    out    << " \t\t |" << data.getByggingarAr() <<  " \t\t   |" << data.getTegund() <<  " \t\t  |";
    out << svar << " \t\t\t |" << endl;

    return out;
}
<commit_msg>tharf ad pulla<commit_after>#include "velar.h"

//Smiðir
velar::velar()
{
    _vNafn = _tegund = "None";
    _byggd = false;
    _bAr = 0;

}

velar::velar(int id, string vNafn, int bAr, string tegund, bool byggd)
{
    _id = id;
    _vNafn = vNafn;
    _bAr = bAr;
    _tegund = tegund;
    _byggd = byggd;
}

//Get föll
int velar::getID() const
{
    return _id;
}

string velar::getVelaNafn() const
{
    return _vNafn;
}

int velar::getByggingarAr() const
{
    return _bAr;
}

string velar::getTegund() const
{
    return _tegund;
}

bool velar::getByggd() const
{
    return _byggd;
}

//Set föll
void velar::uppfVelaNafn(string nyttvNafn)
{
    _vNafn = nyttvNafn;
}

void velar::uppfByggingarAr(int nyttbAr)
{
    _bAr = nyttbAr;
}

void velar::uppfTegund(int nyttTegund)
{
    _tegund = nyttTegund;
}

void velar::uppfByggd(bool nyttByggd)
{
    _byggd = nyttByggd;
}

//ops
ostream& operator <<(ostream& out, const velar& data)
{

    string svar = "";
    if (data.getByggd() == 1)
    {
        svar = "Yes";
    }
    else
    {
        svar = "No";
    }

    //out << "Name of machine: " << data.getVelaNafn() << endl;
    //out << "Year of creation: " << data.getByggingarAr() << endl;
    //out << "Type: " << data.getTegund() << endl;
    //out << "Was it built?: " << data.getByggd() << endl;

    out << "|" << data.getVelaNafn() << " \t\t |" << data.getByggingarAr() <<  " \t\t   |" << data.getTegund() <<  " \t\t  |";
    out << svar << " \t\t\t |" << endl;

    return out;
}
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

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

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file WhisperHost.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 */

#include "WhisperHost.h"

#include <libdevcore/Log.h>
#include <libp2p/All.h>
using namespace std;
using namespace dev;
using namespace dev::p2p;
using namespace dev::shh;

#if defined(clogS)
#undef clogS
#endif
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "

WhisperHost::WhisperHost()
{
}

WhisperHost::~WhisperHost()
{
}

void WhisperHost::streamMessage(h256 _m, RLPStream& _s) const
{
	UpgradableGuard l(x_messages);
	if (m_messages.count(_m))
	{
		UpgradeGuard ll(l);
		m_messages.at(_m).streamOut(_s, true);
	}
}

void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p)
{
	if (_m.expiry() <= time(0))
		return;

	auto h = _m.sha3();
	{
		UpgradableGuard l(x_messages);
		if (m_messages.count(h))
			return;
		UpgradeGuard ll(l);
		m_messages[h] = _m;
		m_expiryQueue[_m.expiry()] = h;
	}

//	if (_p)
	{
		Guard l(m_filterLock);
		for (auto const& f: m_filters)
			if (f.second.filter.matches(_m))
				noteChanged(h, f.first);
	}

	for (auto& i: peers())
		if (i->cap<WhisperPeer>().get() == _p)
			i->addRating(1);
		else
			i->cap<WhisperPeer>()->noteNewMessage(h, _m);
}

void WhisperHost::noteChanged(h256 _messageHash, h256 _filter)
{
	for (auto& i: m_watches)
		if (i.second.id == _filter)
		{
			cwatshh << "!!!" << i.first << i.second.id;
			i.second.changes.push_back(_messageHash);
		}
}

unsigned WhisperHost::installWatchOnId(h256 _h)
{
	auto ret = m_watches.size() ? m_watches.rbegin()->first + 1 : 0;
	m_watches[ret] = ClientWatch(_h);
	cwatshh << "+++" << ret << _h;
	return ret;
}

unsigned WhisperHost::installWatch(shh::TopicFilter const& _f)
{
	Guard l(m_filterLock);

	h256 h = _f.sha3();

	if (!m_filters.count(h))
		m_filters.insert(make_pair(h, _f));

	return installWatchOnId(h);
}

h256s WhisperHost::watchMessages(unsigned _watchId)
{
	cleanup();
	h256s ret;
	auto wit = m_watches.find(_watchId);
	if (wit == m_watches.end())
		return ret;
	TopicFilter f;
	{
		Guard l(m_filterLock);
		auto fit = m_filters.find(wit->second.id);
		if (fit == m_filters.end())
			return ret;
		f = fit->second.filter;
	}
	ReadGuard l(x_messages);
	for (auto const& m: m_messages)
		if (f.matches(m.second))
			ret.push_back(m.first);
	return ret;
}

void WhisperHost::uninstallWatch(unsigned _i)
{
	cwatshh << "XXX" << _i;

	Guard l(m_filterLock);

	auto it = m_watches.find(_i);
	if (it == m_watches.end())
		return;
	auto id = it->second.id;
	m_watches.erase(it);

	auto fit = m_filters.find(id);
	if (fit != m_filters.end())
		if (!--fit->second.refCount)
			m_filters.erase(fit);
}

void WhisperHost::cleanup()
{
	// remove old messages.
	// should be called every now and again.
	auto now = time(0);
	WriteGuard l(x_messages);
	for (auto it = m_expiryQueue.begin(); it != m_expiryQueue.end() && it->first <= now; it = m_expiryQueue.erase(it))
		m_messages.erase(it->second);
}
<commit_msg>Whisperer in AZ. More Whisper fixups.<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

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

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file WhisperHost.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 */

#include "WhisperHost.h"

#include <libdevcore/Log.h>
#include <libp2p/All.h>
using namespace std;
using namespace dev;
using namespace dev::p2p;
using namespace dev::shh;

#if defined(clogS)
#undef clogS
#endif
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "

WhisperHost::WhisperHost()
{
}

WhisperHost::~WhisperHost()
{
}

void WhisperHost::streamMessage(h256 _m, RLPStream& _s) const
{
	UpgradableGuard l(x_messages);
	if (m_messages.count(_m))
	{
		UpgradeGuard ll(l);
		auto const& m = m_messages.at(_m);
		cnote << "streamOut: " << m.expiry() << m.ttl() << m.topic() << toHex(m.data());
		m.streamOut(_s, true);
	}
}

void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p)
{
	cnote << "inject: " << _m.expiry() << _m.ttl() << _m.topic() << toHex(_m.data());

	if (_m.expiry() <= time(0))
		return;

	auto h = _m.sha3();
	{
		UpgradableGuard l(x_messages);
		if (m_messages.count(h))
			return;
		UpgradeGuard ll(l);
		m_messages[h] = _m;
		m_expiryQueue[_m.expiry()] = h;
	}

//	if (_p)
	{
		Guard l(m_filterLock);
		for (auto const& f: m_filters)
			if (f.second.filter.matches(_m))
				noteChanged(h, f.first);
	}

	for (auto& i: peers())
		if (i->cap<WhisperPeer>().get() == _p)
			i->addRating(1);
		else
			i->cap<WhisperPeer>()->noteNewMessage(h, _m);
}

void WhisperHost::noteChanged(h256 _messageHash, h256 _filter)
{
	for (auto& i: m_watches)
		if (i.second.id == _filter)
		{
			cwatshh << "!!!" << i.first << i.second.id;
			i.second.changes.push_back(_messageHash);
		}
}

unsigned WhisperHost::installWatchOnId(h256 _h)
{
	auto ret = m_watches.size() ? m_watches.rbegin()->first + 1 : 0;
	m_watches[ret] = ClientWatch(_h);
	cwatshh << "+++" << ret << _h;
	return ret;
}

unsigned WhisperHost::installWatch(shh::TopicFilter const& _f)
{
	Guard l(m_filterLock);

	h256 h = _f.sha3();

	if (!m_filters.count(h))
		m_filters.insert(make_pair(h, _f));

	return installWatchOnId(h);
}

h256s WhisperHost::watchMessages(unsigned _watchId)
{
	cleanup();
	h256s ret;
	auto wit = m_watches.find(_watchId);
	if (wit == m_watches.end())
		return ret;
	TopicFilter f;
	{
		Guard l(m_filterLock);
		auto fit = m_filters.find(wit->second.id);
		if (fit == m_filters.end())
			return ret;
		f = fit->second.filter;
	}
	ReadGuard l(x_messages);
	for (auto const& m: m_messages)
		if (f.matches(m.second))
			ret.push_back(m.first);
	return ret;
}

void WhisperHost::uninstallWatch(unsigned _i)
{
	cwatshh << "XXX" << _i;

	Guard l(m_filterLock);

	auto it = m_watches.find(_i);
	if (it == m_watches.end())
		return;
	auto id = it->second.id;
	m_watches.erase(it);

	auto fit = m_filters.find(id);
	if (fit != m_filters.end())
		if (!--fit->second.refCount)
			m_filters.erase(fit);
}

void WhisperHost::cleanup()
{
	// remove old messages.
	// should be called every now and again.
	auto now = time(0);
	WriteGuard l(x_messages);
	for (auto it = m_expiryQueue.begin(); it != m_expiryQueue.end() && it->first <= now; it = m_expiryQueue.erase(it))
		m_messages.erase(it->second);
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbStreamingMinMaxImageFilter.h"

#include "otbImageFunctionAdapter.h"

#include "otbFourierMellinDescriptorsImageFunction.h"
#include "otbRealMomentsImageFunction.h"
#include "otbComplexMomentsImageFunction.h"
#include "otbFlusserMomentsImageFunction.h"
#include "otbHuMomentsImageFunction.h"
#include "otbRadiometricMomentsImageFunction.h"
#include "otbLocalHistogramImageFunction.h"

int otbImageFunctionAdapterNew(int argc, char * argv[])
{
  typedef double InputPixelType;
  const unsigned int Dimension = 2;

  typedef otb::Image<InputPixelType,  Dimension>                        InputImageType;

  typedef otb::FourierMellinDescriptorsImageFunction<InputImageType>    FMDFunctionType;
  typedef otb::RealMomentsImageFunction<InputImageType>                 RMFunctionType;
  typedef otb::ComplexMomentsImageFunction<InputImageType>              CMFunctionType;
  typedef otb::FlusserMomentsImageFunction<InputImageType>              FMFunctionType;
  typedef otb::HuMomentsImageFunction<InputImageType>                   HMFunctionType;
  typedef otb::RadiometricMomentsImageFunction<InputImageType>          RaMFunctionType;
  typedef otb::LocalHistogramImageFunction<InputImageType>              LHFunctionType;

  typedef otb::ImageFunctionAdapter<InputImageType,
    FMDFunctionType>                                    FMDImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    RMFunctionType>                                     RMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    CMFunctionType>                                     CMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    FMFunctionType>                                     FMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    HMFunctionType>                                     HMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    RaMFunctionType>                                    RaMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    LHFunctionType>                                     LHImageFunctionAdapterType;

  // Instantiating objects
  FMDImageFunctionAdapterType::Pointer FMDadaptedFunction = FMDImageFunctionAdapterType::New();
  std::cout << FMDadaptedFunction << std::endl;
  RMImageFunctionAdapterType::Pointer RMadaptedFunction = RMImageFunctionAdapterType::New();
  std::cout << RMadaptedFunction << std::endl;
  CMImageFunctionAdapterType::Pointer CMadaptedFunction = CMImageFunctionAdapterType::New();
  std::cout << CMadaptedFunction << std::endl;
  FMImageFunctionAdapterType::Pointer FMadaptedFunction = FMImageFunctionAdapterType::New();
  std::cout << FMadaptedFunction << std::endl;
  HMImageFunctionAdapterType::Pointer HMadaptedFunction = HMImageFunctionAdapterType::New();
  std::cout << HMadaptedFunction << std::endl;
  RaMImageFunctionAdapterType::Pointer RaMadaptedFunction = RaMImageFunctionAdapterType::New();
  std::cout << RaMadaptedFunction << std::endl;
  LHImageFunctionAdapterType::Pointer LHadaptedFunction = LHImageFunctionAdapterType::New();
  std::cout << LHadaptedFunction << std::endl;

  return EXIT_SUCCESS;
}

int otbImageFunctionAdapter(int argc, char * argv[])
{
  const char * inputFilename  = argv[1];

  typedef double InputPixelType;
  const unsigned int Dimension = 2;
  unsigned int rsltIdx = 0;

  typedef otb::Image<InputPixelType,  Dimension>                        InputImageType;
  typedef otb::ImageFileReader<InputImageType>                          ReaderType;
  typedef otb::StreamingMinMaxImageFilter<InputImageType>         MinMaxFilterType;

  typedef otb::FourierMellinDescriptorsImageFunction<InputImageType>    FMDFunctionType;
  typedef otb::RealMomentsImageFunction<InputImageType>                 RMFunctionType;
  typedef otb::ComplexMomentsImageFunction<InputImageType>              CMFunctionType;
  typedef otb::FlusserMomentsImageFunction<InputImageType>              FMFunctionType;
  typedef otb::HuMomentsImageFunction<InputImageType>                   HMFunctionType;
  typedef otb::RadiometricMomentsImageFunction<InputImageType>          RaMFunctionType;
  typedef otb::LocalHistogramImageFunction<InputImageType>              LHFunctionType;

  typedef otb::ImageFunctionAdapter<InputImageType,
    FMDFunctionType>                                    FMDImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    RMFunctionType>                                     RMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    CMFunctionType>                                     CMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    FMFunctionType>                                     FMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    HMFunctionType>                                     HMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    RaMFunctionType>                                    RaMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    LHFunctionType>                                     LHImageFunctionAdapterType;

  // Instantiating objects
  ReaderType::Pointer  reader = ReaderType::New();
  MinMaxFilterType::Pointer filter   = MinMaxFilterType::New();

  FMDFunctionType::Pointer FMDFunction = FMDFunctionType::New();
  RMFunctionType::Pointer  RMFunction  = RMFunctionType::New();
  CMFunctionType::Pointer  CMFunction  = CMFunctionType::New();
  FMFunctionType::Pointer  FMFunction  = FMFunctionType::New();
  HMFunctionType::Pointer  HMFunction  = HMFunctionType::New();
  RaMFunctionType::Pointer RaMFunction = RaMFunctionType::New();
  LHFunctionType::Pointer  LHFunction  = LHFunctionType::New();

  FMDImageFunctionAdapterType::Pointer FMDadaptedFunction = FMDImageFunctionAdapterType::New();
  RMImageFunctionAdapterType::Pointer  RMadaptedFunction  = RMImageFunctionAdapterType::New();
  CMImageFunctionAdapterType::Pointer  CMadaptedFunction  = CMImageFunctionAdapterType::New();
  FMImageFunctionAdapterType::Pointer  FMadaptedFunction  = FMImageFunctionAdapterType::New();
  HMImageFunctionAdapterType::Pointer  HMadaptedFunction  = HMImageFunctionAdapterType::New();
  RaMImageFunctionAdapterType::Pointer RaMadaptedFunction = RaMImageFunctionAdapterType::New();
  LHImageFunctionAdapterType::Pointer  LHadaptedFunction  = LHImageFunctionAdapterType::New();

  reader->SetFileName(inputFilename);
  filter->SetInput(reader->GetOutput());
  filter->Update();

  InputImageType::IndexType index;
  index[0] = 100;
  index[1] = 100;

  // Content testing
  double error = 0.0;

  FMDFunction->SetInputImage(reader->GetOutput());
  FMDFunction->SetNeighborhoodRadius(5);
  FMDFunction->SetPmax(5);
  FMDFunction->SetQmax(5);
  FMDFunctionType::OutputType resultFMD = FMDFunction->EvaluateAtIndex(index);

  FMDadaptedFunction->SetInputImage(reader->GetOutput());
  FMDadaptedFunction->GetImageFunction()->SetNeighborhoodRadius(5);
  FMDadaptedFunction->GetImageFunction()->SetPmax(5);
  FMDadaptedFunction->GetImageFunction()->SetQmax(5);
  FMDImageFunctionAdapterType::OutputType resultAdaptedFMD = FMDadaptedFunction->EvaluateAtIndex(index);

  rsltIdx = 0;
  for (unsigned int i=0; i<=5; i++)
    {
    for (unsigned int j=0; j<=5; j++)
      {
      error += vcl_pow(vcl_abs(resultAdaptedFMD[rsltIdx] - resultFMD.at(i).at(j)), 2);

      std::cout << "resultAdaptedFMD : " << resultAdaptedFMD[rsltIdx]
                << "\t - resultFMD : " << resultFMD.at(i).at(j) << std::endl;
      rsltIdx ++;
      }
    }

  RMFunction->SetInputImage(reader->GetOutput());
  RMFunction->SetNeighborhoodRadius(5);
  RMFunction->SetPmax(5);
  RMFunction->SetQmax(5);
  RMFunctionType::OutputType resultRM = RMFunction->EvaluateAtIndex(index);

  RMadaptedFunction->SetInputImage(reader->GetOutput());
  RMadaptedFunction->GetImageFunction()->SetNeighborhoodRadius(5);
  RMadaptedFunction->GetImageFunction()->SetPmax(5);
  RMadaptedFunction->GetImageFunction()->SetQmax(5);
  RMImageFunctionAdapterType::OutputType resultAdaptedRM = RMadaptedFunction->EvaluateAtIndex(index);

  rsltIdx = 0;
  for (unsigned int i=0; i<=5; i++)
    {
    for (unsigned int j=0; j<=5; j++)
      {
      error += vcl_pow(vcl_abs(resultAdaptedRM[rsltIdx] - resultRM.at(i).at(j)), 2);

      std::cout << "resultAdaptedRM : " << resultAdaptedRM[rsltIdx]
                << "\t - resultRM : " << resultRM.at(i).at(j) << std::endl;
      rsltIdx ++;
      }
    }

  CMFunction->SetInputImage(reader->GetOutput());
  CMFunction->SetNeighborhoodRadius(5);
  CMFunction->SetPmax(5);
  CMFunction->SetQmax(5);
  CMFunctionType::OutputType resultCM = CMFunction->EvaluateAtIndex(index);

  CMadaptedFunction->SetInputImage(reader->GetOutput());
  CMadaptedFunction->GetImageFunction()->SetNeighborhoodRadius(5);
  CMadaptedFunction->GetImageFunction()->SetPmax(5);
  CMadaptedFunction->GetImageFunction()->SetQmax(5);
  CMImageFunctionAdapterType::OutputType resultAdaptedCM = CMadaptedFunction->EvaluateAtIndex(index);

  rsltIdx = 0;
  for (unsigned int i=0; i<=5; i++)
    {
    for (unsigned int j=0; j<=5; j++)
      {
      error += vcl_pow(vcl_abs(resultAdaptedCM[rsltIdx] - resultCM.at(i).at(j).real()), 2);
      std::cout << "resultAdaptedCM : (" << resultAdaptedCM[rsltIdx]
                << "," << resultAdaptedCM[rsltIdx+1] << ")"
                << "\t - resultCM : " << resultCM.at(i).at(j) << std::endl;
      rsltIdx ++;
      error += vcl_pow(vcl_abs(resultAdaptedCM[rsltIdx] - resultCM.at(i).at(j).imag()), 2);
      rsltIdx ++;
      }
    }

  FMFunction->SetInputImage(reader->GetOutput());
  FMFunction->SetNeighborhoodRadius(5);
  FMFunctionType::OutputType resultFM = FMFunction->EvaluateAtIndex(index);

  FMadaptedFunction->SetInputImage(reader->GetOutput());
  FMadaptedFunction->GetImageFunction()->SetNeighborhoodRadius(5);
  FMImageFunctionAdapterType::OutputType resultAdaptedFM = FMadaptedFunction->EvaluateAtIndex(index);

  rsltIdx = 0;
  for (unsigned int i=0; i<11; i++)
    {
      error += vcl_pow(vcl_abs(resultAdaptedFM[rsltIdx] - resultFM[i]), 2);

      std::cout << "resultAdaptedFM : " << resultAdaptedFM[rsltIdx]
                << "\t - resultFM : " << resultFM[i] << std::endl;
      rsltIdx ++;
    }

  HMFunction->SetInputImage(reader->GetOutput());
  HMFunction->SetNeighborhoodRadius(5);
  HMFunctionType::OutputType resultHM = HMFunction->EvaluateAtIndex(index);

  HMadaptedFunction->SetInputImage(reader->GetOutput());
  HMadaptedFunction->GetImageFunction()->SetNeighborhoodRadius(5);
  HMImageFunctionAdapterType::OutputType resultAdaptedHM = HMadaptedFunction->EvaluateAtIndex(index);

  rsltIdx = 0;
  for (unsigned int i=0; i<=7; i++)
    {
    error += vcl_pow(vcl_abs(resultAdaptedHM[rsltIdx] - resultHM[i]), 2);

    std::cout << "resultAdaptedHM : " << resultAdaptedHM[rsltIdx]
              << "\t - resultHM : " << resultHM[i] << std::endl;
    rsltIdx ++;
    }

  RaMFunction->SetInputImage(reader->GetOutput());
  RaMFunction->SetNeighborhoodRadius(5);
  RaMFunctionType::OutputType resultRaM = RaMFunction->EvaluateAtIndex(index);

  RaMadaptedFunction->SetInputImage(reader->GetOutput());
  RaMadaptedFunction->GetImageFunction()->SetNeighborhoodRadius(5);
  RaMImageFunctionAdapterType::OutputType resultAdaptedRaM = RaMadaptedFunction->EvaluateAtIndex(index);

  rsltIdx = 0;
  for (unsigned int i=0; i<4; i++)
    {
    error += vcl_pow(vcl_abs(resultAdaptedRaM[rsltIdx] - resultRaM[i]), 2);

    std::cout << "resultAdaptedRaM : " << resultAdaptedRaM[rsltIdx]
              << "\t - resultRaM : " << resultRaM[i] << std::endl;
    rsltIdx ++;
    }

  LHFunction->SetInputImage(reader->GetOutput());
  LHFunction->SetNeighborhoodRadius(5);
  LHFunction->SetNumberOfHistogramBins(64);
  LHFunction->SetHistogramMin(filter->GetMinimum());
  LHFunction->SetHistogramMax(filter->GetMaximum());
  LHFunctionType::OutputType resultLH = LHFunction->EvaluateAtIndex(index);

  LHadaptedFunction->SetInputImage(reader->GetOutput());
  LHadaptedFunction->GetImageFunction()->SetNeighborhoodRadius(5);
  LHadaptedFunction->GetImageFunction()->SetNumberOfHistogramBins(64);
  LHadaptedFunction->GetImageFunction()->SetHistogramMin(filter->GetMinimum());
  LHadaptedFunction->GetImageFunction()->SetHistogramMax(filter->GetMaximum());
  LHImageFunctionAdapterType::OutputType resultAdaptedLH = LHadaptedFunction->EvaluateAtIndex(index);

  rsltIdx = 0;
  for (unsigned int i=0; i<64; i++)
    {
    error += vcl_pow(vcl_abs( resultAdaptedLH[rsltIdx] - resultLH->GetFrequency(i)), 2);

    std::cout << "resultAdaptedLH : " << resultAdaptedLH[rsltIdx]
              << "\t - resultLH : " << resultLH->GetFrequency(i) << std::endl;
    rsltIdx ++;
    }

  error = vcl_sqrt(error);
  std::cout << std::endl << "Error : " << error << std::endl
            << std::endl;

 if (error > 1E-3)
    {
    itkGenericExceptionMacro( << "Error = " << error
                              << "  > 1E-9     -> TEST FAILLED" << std::endl );
    }

  return EXIT_SUCCESS;
}
<commit_msg>TEST: corrected ImageFunctionAdapter test<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even
  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbStreamingMinMaxImageFilter.h"

#include "otbImageFunctionAdapter.h"

#include "otbFourierMellinDescriptorsImageFunction.h"
#include "otbRealMomentsImageFunction.h"
#include "otbComplexMomentsImageFunction.h"
#include "otbFlusserMomentsImageFunction.h"
#include "otbHuMomentsImageFunction.h"
#include "otbRadiometricMomentsImageFunction.h"
#include "otbLocalHistogramImageFunction.h"

int otbImageFunctionAdapterNew(int argc, char * argv[])
{
  typedef double InputPixelType;
  const unsigned int Dimension = 2;

  typedef otb::Image<InputPixelType,  Dimension>                        InputImageType;

  typedef otb::FourierMellinDescriptorsImageFunction<InputImageType>    FMDFunctionType;
  typedef otb::RealMomentsImageFunction<InputImageType>                 RMFunctionType;
  typedef otb::ComplexMomentsImageFunction<InputImageType>              CMFunctionType;
  typedef otb::FlusserMomentsImageFunction<InputImageType>              FMFunctionType;
  typedef otb::HuMomentsImageFunction<InputImageType>                   HMFunctionType;
  typedef otb::RadiometricMomentsImageFunction<InputImageType>          RaMFunctionType;
  typedef otb::LocalHistogramImageFunction<InputImageType>              LHFunctionType;

  typedef otb::ImageFunctionAdapter<InputImageType,
    FMDFunctionType>                                    FMDImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    RMFunctionType>                                     RMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    CMFunctionType>                                     CMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    FMFunctionType>                                     FMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    HMFunctionType>                                     HMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    RaMFunctionType>                                    RaMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    LHFunctionType>                                     LHImageFunctionAdapterType;

  // Instantiating objects
  FMDImageFunctionAdapterType::Pointer FMDadaptedFunction = FMDImageFunctionAdapterType::New();
  std::cout << FMDadaptedFunction << std::endl;
  RMImageFunctionAdapterType::Pointer RMadaptedFunction = RMImageFunctionAdapterType::New();
  std::cout << RMadaptedFunction << std::endl;
  CMImageFunctionAdapterType::Pointer CMadaptedFunction = CMImageFunctionAdapterType::New();
  std::cout << CMadaptedFunction << std::endl;
  FMImageFunctionAdapterType::Pointer FMadaptedFunction = FMImageFunctionAdapterType::New();
  std::cout << FMadaptedFunction << std::endl;
  HMImageFunctionAdapterType::Pointer HMadaptedFunction = HMImageFunctionAdapterType::New();
  std::cout << HMadaptedFunction << std::endl;
  RaMImageFunctionAdapterType::Pointer RaMadaptedFunction = RaMImageFunctionAdapterType::New();
  std::cout << RaMadaptedFunction << std::endl;
  LHImageFunctionAdapterType::Pointer LHadaptedFunction = LHImageFunctionAdapterType::New();
  std::cout << LHadaptedFunction << std::endl;

  return EXIT_SUCCESS;
}

int otbImageFunctionAdapter(int argc, char * argv[])
{
  const char * inputFilename  = argv[1];

  typedef double InputPixelType;
  const unsigned int Dimension = 2;
  unsigned int rsltIdx = 0;

  typedef otb::Image<InputPixelType,  Dimension>                        InputImageType;
  typedef otb::ImageFileReader<InputImageType>                          ReaderType;
  typedef otb::StreamingMinMaxImageFilter<InputImageType>         MinMaxFilterType;

  typedef otb::FourierMellinDescriptorsImageFunction<InputImageType>    FMDFunctionType;
  typedef otb::RealMomentsImageFunction<InputImageType>                 RMFunctionType;
  typedef otb::ComplexMomentsImageFunction<InputImageType>              CMFunctionType;
  typedef otb::FlusserMomentsImageFunction<InputImageType>              FMFunctionType;
  typedef otb::HuMomentsImageFunction<InputImageType>                   HMFunctionType;
  typedef otb::RadiometricMomentsImageFunction<InputImageType>          RaMFunctionType;
  typedef otb::LocalHistogramImageFunction<InputImageType>              LHFunctionType;

  typedef otb::ImageFunctionAdapter<InputImageType,
    FMDFunctionType>                                    FMDImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    RMFunctionType>                                     RMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    CMFunctionType>                                     CMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    FMFunctionType>                                     FMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    HMFunctionType>                                     HMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    RaMFunctionType>                                    RaMImageFunctionAdapterType;
  typedef otb::ImageFunctionAdapter<InputImageType,
    LHFunctionType>                                     LHImageFunctionAdapterType;

  // Instantiating objects
  ReaderType::Pointer  reader = ReaderType::New();
  MinMaxFilterType::Pointer filter   = MinMaxFilterType::New();

  FMDFunctionType::Pointer FMDFunction = FMDFunctionType::New();
  RMFunctionType::Pointer  RMFunction  = RMFunctionType::New();
  CMFunctionType::Pointer  CMFunction  = CMFunctionType::New();
  FMFunctionType::Pointer  FMFunction  = FMFunctionType::New();
  HMFunctionType::Pointer  HMFunction  = HMFunctionType::New();
  RaMFunctionType::Pointer RaMFunction = RaMFunctionType::New();
  LHFunctionType::Pointer  LHFunction  = LHFunctionType::New();

  FMDImageFunctionAdapterType::Pointer FMDadaptedFunction = FMDImageFunctionAdapterType::New();
  RMImageFunctionAdapterType::Pointer  RMadaptedFunction  = RMImageFunctionAdapterType::New();
  CMImageFunctionAdapterType::Pointer  CMadaptedFunction  = CMImageFunctionAdapterType::New();
  FMImageFunctionAdapterType::Pointer  FMadaptedFunction  = FMImageFunctionAdapterType::New();
  HMImageFunctionAdapterType::Pointer  HMadaptedFunction  = HMImageFunctionAdapterType::New();
  RaMImageFunctionAdapterType::Pointer RaMadaptedFunction = RaMImageFunctionAdapterType::New();
  LHImageFunctionAdapterType::Pointer  LHadaptedFunction  = LHImageFunctionAdapterType::New();

  reader->SetFileName(inputFilename);
  filter->SetInput(reader->GetOutput());
  filter->Update();

  InputImageType::IndexType index;
  index[0] = 100;
  index[1] = 100;

  // Content testing
  double error = 0.0;

  FMDFunction->SetInputImage(reader->GetOutput());
  FMDFunction->SetNeighborhoodRadius(5);
  FMDFunction->SetPmax(5);
  FMDFunction->SetQmax(5);
  FMDFunctionType::OutputType resultFMD = FMDFunction->EvaluateAtIndex(index);

  FMDadaptedFunction->SetInputImage(reader->GetOutput());
  FMDadaptedFunction->GetImageFunction()->SetNeighborhoodRadius(5);
  FMDadaptedFunction->GetImageFunction()->SetPmax(5);
  FMDadaptedFunction->GetImageFunction()->SetQmax(5);
  FMDImageFunctionAdapterType::OutputType resultAdaptedFMD = FMDadaptedFunction->EvaluateAtIndex(index);

  rsltIdx = 0;
  for (unsigned int i=0; i<=5; i++)
    {
    for (unsigned int j=0; j<=5; j++)
      {
      error += vcl_pow(vcl_abs(resultAdaptedFMD[rsltIdx] - resultFMD.at(i).at(j)), 2);

      std::cout << "resultAdaptedFMD : " << resultAdaptedFMD[rsltIdx]
                << "\t - resultFMD : " << resultFMD.at(i).at(j) << std::endl;
      rsltIdx ++;
      }
    }

  RMFunction->SetInputImage(reader->GetOutput());
  RMFunction->SetNeighborhoodRadius(5);
  RMFunction->SetPmax(5);
  RMFunction->SetQmax(5);
  RMFunctionType::OutputType resultRM = RMFunction->EvaluateAtIndex(index);

  RMadaptedFunction->SetInputImage(reader->GetOutput());
  RMadaptedFunction->GetImageFunction()->SetNeighborhoodRadius(5);
  RMadaptedFunction->GetImageFunction()->SetPmax(5);
  RMadaptedFunction->GetImageFunction()->SetQmax(5);
  RMImageFunctionAdapterType::OutputType resultAdaptedRM = RMadaptedFunction->EvaluateAtIndex(index);

  rsltIdx = 0;
  for (unsigned int i=0; i<=5; i++)
    {
    for (unsigned int j=0; j<=5; j++)
      {
      error += vcl_pow(vcl_abs(resultAdaptedRM[rsltIdx] - resultRM.at(i).at(j)), 2);

      std::cout << "resultAdaptedRM : " << resultAdaptedRM[rsltIdx]
                << "\t - resultRM : " << resultRM.at(i).at(j) << std::endl;
      rsltIdx ++;
      }
    }

  CMFunction->SetInputImage(reader->GetOutput());
  CMFunction->SetNeighborhoodRadius(5);
  CMFunction->SetPmax(5);
  CMFunction->SetQmax(5);
  CMFunctionType::OutputType resultCM = CMFunction->EvaluateAtIndex(index);

  CMadaptedFunction->SetInputImage(reader->GetOutput());
  CMadaptedFunction->GetImageFunction()->SetNeighborhoodRadius(5);
  CMadaptedFunction->GetImageFunction()->SetPmax(5);
  CMadaptedFunction->GetImageFunction()->SetQmax(5);
  CMImageFunctionAdapterType::OutputType resultAdaptedCM = CMadaptedFunction->EvaluateAtIndex(index);

  rsltIdx = 0;
  for (unsigned int i=0; i<=5; i++)
    {
    for (unsigned int j=0; j<=5; j++)
      {
      error += vcl_pow(vcl_abs(resultAdaptedCM[rsltIdx] - resultCM.at(i).at(j).real()), 2);
      std::cout << "resultAdaptedCM : (" << resultAdaptedCM[rsltIdx]
                << "," << resultAdaptedCM[rsltIdx+1] << ")"
                << "\t - resultCM : " << resultCM.at(i).at(j) << std::endl;
      rsltIdx ++;
      error += vcl_pow(vcl_abs(resultAdaptedCM[rsltIdx] - resultCM.at(i).at(j).imag()), 2);
      rsltIdx ++;
      }
    }

  FMFunction->SetInputImage(reader->GetOutput());
  FMFunction->SetNeighborhoodRadius(5);
  FMFunctionType::OutputType resultFM = FMFunction->EvaluateAtIndex(index);

  FMadaptedFunction->SetInputImage(reader->GetOutput());
  FMadaptedFunction->GetImageFunction()->SetNeighborhoodRadius(5);
  FMImageFunctionAdapterType::OutputType resultAdaptedFM = FMadaptedFunction->EvaluateAtIndex(index);

  rsltIdx = 0;
  for (unsigned int i=0; i<11; i++)
    {
      error += vcl_pow(vcl_abs(resultAdaptedFM[rsltIdx] - resultFM[i]), 2);

      std::cout << "resultAdaptedFM : " << resultAdaptedFM[rsltIdx]
                << "\t - resultFM : " << resultFM[i] << std::endl;
      rsltIdx ++;
    }

  HMFunction->SetInputImage(reader->GetOutput());
  HMFunction->SetNeighborhoodRadius(5);
  HMFunctionType::OutputType resultHM = HMFunction->EvaluateAtIndex(index);

  HMadaptedFunction->SetInputImage(reader->GetOutput());
  HMadaptedFunction->GetImageFunction()->SetNeighborhoodRadius(5);
  HMImageFunctionAdapterType::OutputType resultAdaptedHM = HMadaptedFunction->EvaluateAtIndex(index);

  rsltIdx = 0;
  for (unsigned int i=0; i<7; i++)
    {
    error += vcl_pow(vcl_abs(resultAdaptedHM[rsltIdx] - resultHM[i]), 2);

    std::cout << "resultAdaptedHM : " << resultAdaptedHM[rsltIdx]
              << "\t - resultHM : " << resultHM[i] << std::endl;
    rsltIdx ++;
    }

  RaMFunction->SetInputImage(reader->GetOutput());
  RaMFunction->SetNeighborhoodRadius(5);
  RaMFunctionType::OutputType resultRaM = RaMFunction->EvaluateAtIndex(index);

  RaMadaptedFunction->SetInputImage(reader->GetOutput());
  RaMadaptedFunction->GetImageFunction()->SetNeighborhoodRadius(5);
  RaMImageFunctionAdapterType::OutputType resultAdaptedRaM = RaMadaptedFunction->EvaluateAtIndex(index);

  rsltIdx = 0;
  for (unsigned int i=0; i<4; i++)
    {
    error += vcl_pow(vcl_abs(resultAdaptedRaM[rsltIdx] - resultRaM[i]), 2);

    std::cout << "resultAdaptedRaM : " << resultAdaptedRaM[rsltIdx]
              << "\t - resultRaM : " << resultRaM[i] << std::endl;
    rsltIdx ++;
    }

  LHFunction->SetInputImage(reader->GetOutput());
  LHFunction->SetNeighborhoodRadius(5);
  LHFunction->SetNumberOfHistogramBins(64);
  LHFunction->SetHistogramMin(filter->GetMinimum());
  LHFunction->SetHistogramMax(filter->GetMaximum());
  LHFunctionType::OutputType resultLH = LHFunction->EvaluateAtIndex(index);

  LHadaptedFunction->SetInputImage(reader->GetOutput());
  LHadaptedFunction->GetImageFunction()->SetNeighborhoodRadius(5);
  LHadaptedFunction->GetImageFunction()->SetNumberOfHistogramBins(64);
  LHadaptedFunction->GetImageFunction()->SetHistogramMin(filter->GetMinimum());
  LHadaptedFunction->GetImageFunction()->SetHistogramMax(filter->GetMaximum());
  LHImageFunctionAdapterType::OutputType resultAdaptedLH = LHadaptedFunction->EvaluateAtIndex(index);

  rsltIdx = 0;
  for (unsigned int i=0; i<64; i++)
    {
    error += vcl_pow(vcl_abs( resultAdaptedLH[rsltIdx] - resultLH->GetFrequency(i)), 2);

    std::cout << "resultAdaptedLH : " << resultAdaptedLH[rsltIdx]
              << "\t - resultLH : " << resultLH->GetFrequency(i) << std::endl;
    rsltIdx ++;
    }

  error = vcl_sqrt(error);
  std::cout << std::endl << "Error : " << error << std::endl
            << std::endl;

 if (error > 1E-3)
    {
    itkGenericExceptionMacro( << "Error = " << error
                              << "  > 1E-9     -> TEST FAILLED" << std::endl );
    }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/**
 * @file cnn_pooling_connection.hpp
 * @author Shangtong Zhang
 *
 * Implementation of the pooling connection between input layer
 * and output layer for CNN.
 */
#ifndef __MLPACK_METHODS_ANN_CONNECTIONS_POOLING_CONNECTION_HPP
#define __MLPACK_METHODS_ANN_CONNECTIONS_POOLING_CONNECTION_HPP

#include <mlpack/core.hpp>
#include <mlpack/methods/ann/init_rules/nguyen_widrow_init.hpp>
#include <mlpack/methods/ann/pooling/max_pooling.hpp>
#include <mlpack/methods/ann/connections/connection_traits.hpp>

namespace mlpack{
namespace ann /** Artificial Neural Network. */ {

/**
 * Implementation of the pooling connection class for CNN.
 * The pooling connection connects
 * input layer with the output layer by pooling.
 * output = factor * pooling_value + bias
 *
 * @tparam InputLayerType Type of the connected input layer.
 * @tparam OutputLayerType Type of the connected output layer.
 * @tparam OptimizerType Type of the optimizer used to update the weights.
 * @tparam PoolingRule Type of pooling strategy.
 * @tparam MatType Type of data (arma::mat or arma::sp_mat).
 */
template<
    typename InputLayerType,
    typename OutputLayerType,
    typename OptimizerType,
    typename PoolingRule = MaxPooling,
    typename MatType = arma::mat
>
class PoolingConnection
{
 public:
  /**
   * Create the PoolingConnection object using the specified input layer, output
   * layer, optimizer, factor, bias and pooling strategy.
   * The factor and bias is stored in @weights.
   *
   * @param InputLayerType The input layer which is connected with the output
   * layer.
   * @param OutputLayerType The output layer which is connected with the input
   * layer.
   * @param OptimizerType The optimizer used to update the weight matrix.
   * @param PoolingRule The strategy of pooling.
   */
  PoolingConnection(InputLayerType& inputLayer,
                    OutputLayerType& outputLayer,
                    OptimizerType& optimizer,
                    double factor = 1.0,
                    double bias = 0,
                    PoolingRule pooling = PoolingRule()) :
      inputLayer(inputLayer), outputLayer(outputLayer), optimizer(optimizer),
      weights(2), pooling(pooling),
      rawOutput(outputLayer.InputActivation().n_rows,
                outputLayer.InputActivation().n_cols)
  {
    delta = arma::zeros<MatType>(inputLayer.InputActivation().n_rows,
                                 inputLayer.InputActivation().n_cols);
    gradient = arma::zeros<arma::colvec>(2);
    weights(0) = factor;
    weights(1) = bias;
  }

  /**
   * Ordinary feed forward pass of a neural network,
   * apply pooling to the neurons in the input layer.
   *
   * @param input Input data used for pooling.
   */
  void FeedForward(const MatType& input)
  {
    size_t r_step = input.n_rows / outputLayer.InputActivation().n_rows;
    size_t c_step = input.n_cols / outputLayer.InputActivation().n_cols;
    for (size_t j = 0; j < input.n_cols; j += c_step)
    {
      for (size_t i = 0; i < input.n_rows; i += r_step)
      {
        double value = 0;
        pooling.pooling(input(arma::span(i, i + r_step -1),
                              arma::span(j, j + c_step - 1)), value);
        rawOutput(i / r_step, j / c_step) = value;
      }
    }
    outputLayer.InputActivation() += rawOutput * weights(0) + weights(1);
  }

  /**
   * Ordinary feed backward pass of a neural network.
   * Apply unsampling to the error in output layer to
   * pass the error to input layer.
   * @param error The backpropagated error.
   */
  void FeedBackward(const MatType& error)
  {
    gradient(1) = arma::sum(arma::sum(error));
    gradient(0) = arma::sum(arma::sum(rawOutput % error));
    MatType weightedError = error * weights(0);
    size_t r_step = inputLayer.InputActivation().n_rows / error.n_rows;
    size_t c_step = inputLayer.InputActivation().n_cols / error.n_cols;
    const MatType& input = inputLayer.InputActivation();
    MatType newError;
    for (size_t j = 0; j < input.n_cols; j += c_step)
    {
      for (size_t i = 0; i < input.n_rows; i += r_step)
      {
        const MatType& inputArea = input(arma::span(i, i + r_step -1),
                                         arma::span(j, j + c_step - 1));
        pooling.unpooling(inputArea,
                          weightedError(i / r_step, j / c_step),
                          newError);
        delta(arma::span(i, i + r_step -1),
              arma::span(j, j + c_step - 1)) = newError;
      }
    }
    inputLayer.Delta() += delta;
  }

  //! Get the weights.
  MatType& Weights() const { return weights; }
  //! Modify the weights.
  MatType& Weights() { return weights; }

  //! Get the input layer.
  InputLayerType& InputLayer() const { return inputLayer; }
  //! Modify the input layer.
  InputLayerType& InputLayer() { return inputLayer; }

  //! Get the output layer.
  OutputLayerType& OutputLayer() const { return outputLayer; }
  //! Modify the output layer.
  OutputLayerType& OutputLayer() { return outputLayer; }

  //! Get the optimizer.
  OptimizerType& Optimzer() const { return optimizer; }
  //! Modify the optimzer.
  OptimizerType& Optimzer() { return optimizer; }

  //! Get the passed error in backward propagation.
  MatType& Delta() const { return delta; }
  //! Modify the passed error in backward propagation.
  MatType& Delta() { return delta; }

  //! Get the gradient of weights.
  MatType& Gradient() const { return gradient; }
  //! Modify the delta of weights.
  MatType& Gradient() { return gradient; }

  //! Get the pooling strategy.
  PoolingRule& Pooling() const { return pooling; }
  //! Modify the pooling strategy.
  PoolingRule& Pooling() { return pooling; }

 private:
  //! Locally-stored input layer.
  InputLayerType& inputLayer;

  //! Locally-stored output layer.
  OutputLayerType& outputLayer;

  //! Locally-stored optimizer.
  OptimizerType& optimizer;

  //! Locally-stored weights, only two value, factor and bias.
  arma::colvec weights;

  //! Locally-stored passed error in backward propagation.
  MatType delta;

  //! Locally-stored pooling strategy.
  PoolingRule pooling;

  //! Locally-stored gradient of weights.
  MatType gradient;

  /**
   * Locally-stored raw result of pooling,
   * before multiplied by factor and added by bias.
   * Cache it to speed up when performing backward propagation.
   */
  MatType rawOutput;
};

}; // namespace ann
}; // namespace mlpack

#endif<commit_msg>Refactor pooling connection to support 3rd order tensors.<commit_after>/**
 * @file cnn_pooling_connection.hpp
 * @author Shangtong Zhang
 * @author Marcus Edel
 *
 * Implementation of the pooling connection between input layer and output layer
 * for the convolutional neural network.
 */
#ifndef __MLPACK_METHODS_ANN_CONNECTIONS_POOLING_CONNECTION_HPP
#define __MLPACK_METHODS_ANN_CONNECTIONS_POOLING_CONNECTION_HPP

#include <mlpack/core.hpp>
#include <mlpack/methods/ann/optimizer/steepest_descent.hpp>
#include <mlpack/methods/ann/init_rules/nguyen_widrow_init.hpp>
#include <mlpack/methods/ann/pooling_rules/max_pooling.hpp>
#include <mlpack/methods/ann/connections/connection_traits.hpp>

namespace mlpack{
namespace ann /** Artificial Neural Network. */ {

/**
 * Implementation of the pooling connection class for the convolutional neural
 * network. The pooling connection connects input layer with the output layer
 * using the specified pooling rule.
 *
 * @tparam InputLayerType Type of the connected input layer.
 * @tparam OutputLayerType Type of the connected output layer.
 * @tparam PoolingRule Type of the pooling strategy.
 * @tparam OptimizerType Type of the optimizer used to update the weights.
 * @tparam DataType Type of data (arma::mat, arma::sp_mat or arma::cube).
 */
template<
    typename InputLayerType,
    typename OutputLayerType,
    typename PoolingRule = MaxPooling,
    template<typename> class OptimizerType = SteepestDescent,
    typename DataType = arma::cube
>
class PoolingConnection
{
 public:
  /**
   * Create the PoolingConnection object using the specified input layer, output
   * layer, optimizer and pooling strategy.
   * The factor and bias is stored in @weights.
   *
   * @param InputLayerType The input layer which is connected with the output
   * layer.
   * @param OutputLayerType The output layer which is connected with the input
   * layer.
   * @param OptimizerType The optimizer used to update the weight matrix.
   * @param PoolingRule The strategy of pooling.
   */
  PoolingConnection(InputLayerType& inputLayer,
                    OutputLayerType& outputLayer,
                    PoolingRule pooling = PoolingRule()) :
      inputLayer(inputLayer),
      outputLayer(outputLayer),
      optimizer(0),
      weights(0),
      pooling(pooling),
      delta(inputLayer.Delta().n_rows, inputLayer.Delta().n_cols,
            inputLayer.Delta().n_slices)
  {
    // Nothing to do here.
  }

  /**
   * Ordinary feed forward pass of a neural network, apply pooling to the
   * neurons (dense matrix) in the input layer.
   *
   * @param input Input data used for pooling.
   */
  template<typename eT>
  void FeedForward(const arma::Mat<eT>& input)
  {
    Pooling(input, outputLayer.InputActivation());
  }

  /**
   * Ordinary feed forward pass of a neural network, apply pooling to the
   * neurons (3rd order tensor) in the input layer.
   *
   * @param input Input data used for pooling.
   */
  template<typename eT>
  void FeedForward(const arma::Cube<eT>& input)
  {
    for (size_t s = 0; s < input.n_slices; s++)
      Pooling(input.slice(s), outputLayer.InputActivation().slice(s));
  }

  /**
   * Ordinary feed backward pass of a neural network. Apply unsampling to the
   * error in output layer (dense matrix) to pass the error to input layer.
   *
   * @param error The backpropagated error.
   */
  template<typename eT>
  void FeedBackward(const arma::Mat<eT>& error)
  {
    Unpooling(inputLayer.InputActivation(), error, inputLayer.Delta());
  }

  /**
   * Ordinary feed backward pass of a neural network. Apply unsampling to the
   * error in output layer (3rd order tensor) to pass the error to input layer.
   *
   * @param error The backpropagated error.
   */
  template<typename eT>
  void FeedBackward(const arma::Cube<eT>& error)
  {
    for (size_t s = 0; s < error.n_slices; s++)
    {
      Unpooling(inputLayer.InputActivation().slice(s), error.slice(s),
          delta.slice(s));
    }
  }

  /*
   * Calculate the gradient using the output delta and the input activation.
   *
   * @param gradient The calculated gradient.
   */
  template<typename GradientType>
  void Gradient(GradientType& /* unused */)
  {
    // Nothing to do here.
  }

  //! Get the weights.
  DataType& Weights() const { return *weights; }
  //! Modify the weights.
  DataType& Weights() { return *weights; }

  //! Get the input layer.
  InputLayerType& InputLayer() const { return inputLayer; }
  //! Modify the input layer.
  InputLayerType& InputLayer() { return inputLayer; }

  //! Get the output layer.
  OutputLayerType& OutputLayer() const { return outputLayer; }
  //! Modify the output layer.
  OutputLayerType& OutputLayer() { return outputLayer; }

  //! Get the optimizer.
  OptimizerType<DataType>& Optimzer() const { return *optimizer; }
  //! Modify the optimzer.
  OptimizerType<DataType>& Optimzer() { return *optimizer; }

  //! Get the passed error in backward propagation.
  DataType& Delta() const { return delta; }
  //! Modify the passed error in backward propagation.
  DataType& Delta() { return delta; }

  //! Get the pooling strategy.
  PoolingRule& Pooling() const { return pooling; }
  //! Modify the pooling strategy.
  PoolingRule& Pooling() { return pooling; }

 private:
  /**
   * Apply pooling to the input and store the results.
   *
   * @param input The input to be apply the pooling rule.
   * @param output The pooled result.
   */
  template<typename eT>
  void Pooling(const arma::Mat<eT>& input, arma::Mat<eT>& output)
  {
    const size_t rStep = input.n_rows / outputLayer.LayerRows();
    const size_t cStep = input.n_cols / outputLayer.LayerCols();

    for (size_t j = 0; j < input.n_cols; j += cStep)
    {
      for (size_t i = 0; i < input.n_rows; i += rStep)
      {
        output(i / rStep, j / cStep) += pooling.Pooling(
            input(arma::span(i, i + rStep -1), arma::span(j, j + cStep - 1)));
      }
    }
  }

  /**
   * Apply unpooling to the input and store the results.
   *
   * @param input The input to be apply the unpooling rule.
   * @param output The pooled result.
   */
  template<typename eT>
  void Unpooling(const arma::Mat<eT>& input,
                 const arma::Mat<eT>& error,
                 arma::Mat<eT>& output)
  {
    const size_t rStep = input.n_rows / error.n_rows;
    const size_t cStep = input.n_cols / error.n_cols;

    arma::Mat<eT> unpooledError;
    for (size_t j = 0; j < input.n_cols; j += cStep)
    {
      for (size_t i = 0; i < input.n_rows; i += rStep)
      {
        const arma::Mat<eT>& inputArea = input(arma::span(i, i + rStep -1),
                                               arma::span(j, j + cStep - 1));

        pooling.Unpooling(inputArea, error(i / rStep, j / cStep),
            unpooledError);

        output(arma::span(i, i + rStep - 1),
            arma::span(j, j + cStep - 1)) += unpooledError;
      }
    }
  }

  //! Locally-stored input layer.
  InputLayerType& inputLayer;

  //! Locally-stored output layer.
  OutputLayerType& outputLayer;

  //! Locally-stored optimizer.
  OptimizerType<DataType>* optimizer;

  //! Locally-stored weight object.
  DataType* weights;

  //! Locally-stored pooling strategy.
  PoolingRule pooling;

  //! Locally-stored passed error in backward propagation.
  DataType delta;
}; // PoolingConnection class.

//! Connection traits for the pooling connection.
template<
    typename InputLayerType,
    typename OutputLayerType,
    typename PoolingRule,
    template<typename> class OptimizerType,
    typename DataType
>
class ConnectionTraits<
    PoolingConnection<InputLayerType, OutputLayerType, PoolingRule,
    OptimizerType, DataType> >
{
 public:
  static const bool IsSelfConnection = false;
  static const bool IsFullselfConnection = false;
  static const bool IsPoolingConnection = true;
};

}; // namespace ann
}; // namespace mlpack

#endif<|endoftext|>


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

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you under
the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

*******************************************************************************/

//==============================================================================
// Editor find/replace widget
//==============================================================================

#include "editorfindreplacewidget.h"
#include "guiutils.h"
#include "i18ninterface.h"

//==============================================================================

#include "ui_editorfindreplacewidget.h"

//==============================================================================

#include <Qt>

//==============================================================================

#include <QAction>
#include <QKeyEvent>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QMenu>
#include <QPainter>
#include <QPixmap>
#include <QSize>
#include <QToolButton>

//==============================================================================

namespace OpenCOR {
namespace Editor {

//==============================================================================

EditorFindReplaceWidget::EditorFindReplaceWidget(QWidget *pParent) :
    Core::Widget(pParent),
    mGui(new Ui::EditorFindReplaceWidget),
    mActive(false)
{
    // Set up the GUI

    mGui->setupUi(this);

#ifdef Q_OS_MAC
    mGui->findEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
    mGui->replaceEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
    // Note: the above remove the focus border since it messes up the look of
    //       our edit widgets...
#endif

    // Create and handle our drop-down menu action

    mDropDownAction = new QAction(this);

    mCaseSensitiveAction = Core::newAction(true, this);
    mWholeWordsOnlyAction = Core::newAction(true, this);
    mRegularExpressionAction = Core::newAction(true, this);

    QMenu *dropDownMenu = new QMenu(this);

    dropDownMenu->addAction(mCaseSensitiveAction);
    dropDownMenu->addAction(mWholeWordsOnlyAction);
    dropDownMenu->addAction(mRegularExpressionAction);

    mDropDownAction->setMenu(dropDownMenu);

    mGui->findEdit->addAction(mDropDownAction, QLineEdit::LeadingPosition);

    connect(mCaseSensitiveAction, SIGNAL(toggled(bool)),
            this, SLOT(searchOptionChanged()));
    connect(mWholeWordsOnlyAction, SIGNAL(toggled(bool)),
            this, SLOT(searchOptionChanged()));
    connect(mRegularExpressionAction, SIGNAL(toggled(bool)),
            this, SLOT(searchOptionChanged()));

    // Create and handle our clear find and replace text actions

    mClearFindTextAction = Core::newAction(QIcon(":/qtCreator/src/plugins/coreplugin/images/editclear.png"), this);
    mClearReplaceTextAction = Core::newAction(QIcon(":/qtCreator/src/plugins/coreplugin/images/editclear.png"), this);

    connect(mClearFindTextAction, SIGNAL(triggered()),
            mGui->findEdit, SLOT(clear()));

    connect(mClearReplaceTextAction, SIGNAL(triggered()),
            mGui->replaceEdit, SLOT(clear()));

    // Make our find edit widget our focus proxy

    setFocusProxy(mGui->findEdit);

    // Some connections for our find-related widgets

    connect(mGui->findEdit, SIGNAL(textChanged(const QString &)),
            this, SLOT(updateClearFindTextAction(const QString &)));

    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->findPreviousButton, SLOT(setEnabled(bool)));
    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->findNextButton, SLOT(setEnabled(bool)));

    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->replaceButton, SLOT(setEnabled(bool)));
    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->replaceAndFindButton, SLOT(setEnabled(bool)));
    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->replaceAllButton, SLOT(setEnabled(bool)));

    // A connection for our replace widget

    connect(mGui->replaceEdit, SIGNAL(textChanged(const QString &)),
            this, SLOT(updateClearReplaceTextAction(const QString &)));

    // A few more things , so that we are properly initialised

    retranslateUi();

    searchOptionChanged();

    setActive(true);

    updateStyleSheet();
    updateHeight();
    // Note: just to be safe, we update our height after updating our style
    //       sheet since we change the size of our tool buttons...

    mGui->findPreviousButton->setEnabled(false);
    mGui->findNextButton->setEnabled(false);

    mGui->replaceButton->setEnabled(false);
    mGui->replaceAndFindButton->setEnabled(false);
    mGui->replaceAllButton->setEnabled(false);
}

//==============================================================================

void EditorFindReplaceWidget::retranslateUi()
{
    // Retranslate our GUI

    mGui->retranslateUi(this);

    // Retranslate our actions

    I18nInterface::retranslateAction(mCaseSensitiveAction, tr("Case Sensitive"),
                                     tr("The search is case sensitive"));
    I18nInterface::retranslateAction(mWholeWordsOnlyAction, tr("Whole Words Only"),
                                     tr("The search is done on whole words only"));
    I18nInterface::retranslateAction(mRegularExpressionAction, tr("Regular Expression"),
                                     tr("The search uses a regular expression"));

    I18nInterface::retranslateAction(mClearFindTextAction, tr("Clear Text"),
                                     tr("Clear the text"));
    I18nInterface::retranslateAction(mClearReplaceTextAction, tr("Clear Text"),
                                     tr("Clear the text"));
}

//==============================================================================

bool EditorFindReplaceWidget::isCaseSensitive() const
{
    // Return whether the search is to be case sensitive

    return mCaseSensitiveAction->isChecked();
}

//==============================================================================

bool EditorFindReplaceWidget::searchWholeWordsOnly() const
{
    // Return whether we search whole words only

    return mWholeWordsOnlyAction->isChecked();
}

//==============================================================================

bool EditorFindReplaceWidget::useRegularExpression() const
{
    // Return whether we use a regular expression

    return mRegularExpressionAction->isChecked();
}

//==============================================================================

void EditorFindReplaceWidget::setReadOnly(const bool &pReadOnly)
{
    // Show/hide our replace-related widgets based on whether we are in
    // read-only mode

    Core::showEnableWidget(mGui->replaceLabel, !pReadOnly);
    Core::showEnableWidget(mGui->replaceEdit, !pReadOnly);
    Core::showEnableWidget(mGui->replaceButton, !pReadOnly);
    Core::showEnableWidget(mGui->replaceAndFindButton, !pReadOnly);
    Core::showEnableWidget(mGui->replaceAllButton, !pReadOnly);

    // Enable/disable our find spacer

    mGui->findLayout->setStretch(2, !pReadOnly);

    // Disable our replace-related buttons, if needed

    if (findText().isEmpty()) {
        mGui->replaceButton->setEnabled(false);
        mGui->replaceAndFindButton->setEnabled(false);
        mGui->replaceAllButton->setEnabled(false);
    }

    // Update our height

    updateHeight();
}

//==============================================================================

bool EditorFindReplaceWidget::isFindPreviousNextAvailable() const
{
    // Return whether the find previous/next actions are available

    return !findText().isEmpty();
}

//==============================================================================

void EditorFindReplaceWidget::selectFindText() const
{
    // Select our find text

    mGui->findEdit->selectAll();
}

//==============================================================================

QString EditorFindReplaceWidget::findText() const
{
    // Return our find text

    return mGui->findEdit->text();
}

//==============================================================================

void EditorFindReplaceWidget::setFindText(const QString &pFindText)
{
    // Set our find text and select it

    mGui->findEdit->setText(pFindText);

    selectFindText();
}

//==============================================================================

QString EditorFindReplaceWidget::replaceText() const
{
    // Return our replace text

    return mGui->replaceEdit->text();
}

//==============================================================================

bool EditorFindReplaceWidget::findEditHasFocus() const
{
    // Return whether our find edit has the focus

    return mGui->findEdit->hasFocus();
}

//==============================================================================

bool EditorFindReplaceWidget::replaceEditHasFocus() const
{
    // Return whether our replace edit has the focus

    return mGui->replaceEdit->hasFocus();
}

//==============================================================================

bool EditorFindReplaceWidget::isActive() const
{
    // Return whether we are active

    return mActive;
}

//==============================================================================

void EditorFindReplaceWidget::setActive(const bool &pActive)
{
    if (pActive == mActive)
        return;

    // Set our active state

    mActive = pActive;

    if (pActive)
        connect(mGui->findEdit, SIGNAL(textChanged(const QString &)),
                this, SIGNAL(findTextChanged(const QString &)));
    else
        disconnect(mGui->findEdit, SIGNAL(textChanged(const QString &)),
                   this, SIGNAL(findTextChanged(const QString &)));
}

//==============================================================================

void EditorFindReplaceWidget::updateFrom(EditorFindReplaceWidget *pFindReplace)
{
    // Update our find and replace texts from the given find/replace widget

    mGui->findEdit->setText(pFindReplace->findText());
    mGui->replaceEdit->setText(pFindReplace->replaceText());
}

//==============================================================================

void EditorFindReplaceWidget::updateHeight()
{
    // Update our layout
    // Note: we shouldn't have to do this, but if the user opens a read-only and
    //       shows ourselves, then the find-related widgets will be too 'low'.
    //       This is because the replace-related widgets get hidden/disabled as
    //       expected, but the layout doesn't get updated before we fix our
    //       height, so we update our layout here and in all cases...

    mGui->layout->update();

    // Update our height

    setFixedHeight(mGui->layout->sizeHint().height());
}

//==============================================================================

void EditorFindReplaceWidget::updateStyleSheet()
{
    // Change the style of our tool buttons

    QColor shadowColor = Core::shadowColor();

    setStyleSheet(QString("QToolButton {"
                          "    border: 0px;"
                          "    border-radius: 3px;"
                          "    padding: 1px;"
                          "}"
                          ""
                          "QToolButton:focus {"
                          "    background: rgba(%1, %2, %3, 0.13);"
                          "    border: 1px solid rgba(%1, %2, %3, 0.39);"
                          "}"
                          ""
                          "QToolButton:hover {"
                          "    background: rgba(%1, %2, %3, 0.39);"
                          "}"
                          ""
                          "QToolButton:pressed {"
                          "    background: rgba(%1, %2, %3, 0.79);"
                          "}").arg(QString::number(shadowColor.red()),
                                   QString::number(shadowColor.green()),
                                   QString::number(shadowColor.blue())));
}

//==============================================================================

void EditorFindReplaceWidget::changeEvent(QEvent *pEvent)
{
    // Check whether the palette has changed and if so then update our style
    // sheet

    if (pEvent->type() == QEvent::PaletteChange)
        updateStyleSheet();
}

//==============================================================================

void EditorFindReplaceWidget::keyPressEvent(QKeyEvent *pEvent)
{
    // Let people know that a key has been pressed

    bool handled = false;

    emit keyPressed(pEvent, handled);

    // Carry on as normal, if the event wasn't handled

    if (handled)
        // Accept the event

        pEvent->accept();
    else
        // Default handling of the event

        Core::Widget::keyPressEvent(pEvent);
}

//==============================================================================

void EditorFindReplaceWidget::resizeEvent(QResizeEvent *pEvent)
{
    // Default handling of the event

    Core::Widget::resizeEvent(pEvent);

    // Update our height

    updateHeight();
}

//==============================================================================

void EditorFindReplaceWidget::on_findPreviousButton_clicked()
{
    // Let people know that we want to find the previous occurrence of the text

    emit findPreviousRequested();
}

//==============================================================================

void EditorFindReplaceWidget::on_findNextButton_clicked()
{
    // Let people know that we want to find the next occurrence of the text

    emit findNextRequested();
}

//==============================================================================

void EditorFindReplaceWidget::on_replaceButton_clicked()
{
    // Let people know that we want to replace the current text

    emit replaceRequested();
}

//==============================================================================

void EditorFindReplaceWidget::on_replaceAndFindButton_clicked()
{
    // Let people know that we want to replace the current text and the find the
    // next occurence of the text

    emit replaceAndFindRequested();
}

//==============================================================================

void EditorFindReplaceWidget::on_replaceAllButton_clicked()
{
    // Let people know that we want to replace all the occurences of the text

    emit replaceAllRequested();
}

//==============================================================================

void EditorFindReplaceWidget::searchOptionChanged()
{
    // Update the icon used for the leading position of our find widget

    int nbOfOptions =  mCaseSensitiveAction->isChecked()
                      +mWholeWordsOnlyAction->isChecked()
                      +mRegularExpressionAction->isChecked();

    if (nbOfOptions) {
        static QIcon caseSensitiveIcon = QIcon(":/qtCreator/src/plugins/coreplugin/find/images/casesensitively.png");
        static QIcon wholeWordsOnlyIcon = QIcon(":/qtCreator/src/plugins/coreplugin/find/images/wholewords.png");
        static QIcon regularExpressionIcon = QIcon(":/qtCreator/src/plugins/coreplugin/find/images/regexp.png");

        static int IconSize = 16;
        static int IconWidth = 6;

        QPixmap dropDownPixmap = QPixmap(nbOfOptions*IconWidth-mRegularExpressionAction->isChecked()-1,
                                         IconSize);
        // Note: IconWidth-1, because regularExpressionIcon is effectively one
        //       pixel narrower than caseSensitiveIcon and wholeWordsOnlyIcon...

        dropDownPixmap.fill(Qt::transparent);

        QPainter dropDownPixmapPainter(&dropDownPixmap);

        int left = -IconWidth;

        if (mCaseSensitiveAction->isChecked()) {
            caseSensitiveIcon.paint(&dropDownPixmapPainter, left, 0, IconSize, IconSize);

            left += IconWidth;
        }

        if (mWholeWordsOnlyAction->isChecked()) {
            wholeWordsOnlyIcon.paint(&dropDownPixmapPainter, left, 0, IconSize, IconSize);

            left += IconWidth;
        }

        if (mRegularExpressionAction->isChecked())
            regularExpressionIcon.paint(&dropDownPixmapPainter, left-1, 0, IconSize, IconSize);

        mDropDownAction->setIcon(dropDownPixmap);
    } else {
        // No options are set, so use our default icon

        static QIcon defaultIcon = QIcon(":/qtCreator/src/plugins/coreplugin/images/magnifier.png");

        mDropDownAction->setIcon(defaultIcon);
    }
}

//==============================================================================

void EditorFindReplaceWidget::updateClearFindTextAction(const QString &pText)
{
    // Show/hide our clear text action, based on whether our find widget
    // contains some text

    if (pText.isEmpty())
        mGui->findEdit->removeAction(mClearFindTextAction);
    else
        mGui->findEdit->addAction(mClearFindTextAction, QLineEdit::TrailingPosition);

    // Let people know whether we can find/replace

    emit canFindReplace(!findText().isEmpty());
}

//==============================================================================

void EditorFindReplaceWidget::updateClearReplaceTextAction(const QString &pText)
{
    // Show/hide our clear text action, based on whether our replace widget
    // contains some text

    if (pText.isEmpty())
        mGui->replaceEdit->removeAction(mClearReplaceTextAction);
    else
        mGui->replaceEdit->addAction(mClearReplaceTextAction, QLineEdit::TrailingPosition);
}

//==============================================================================

}   // namespace Editor
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Minor fix our Editor widget [ci skip].<commit_after>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you under
the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

*******************************************************************************/

//==============================================================================
// Editor find/replace widget
//==============================================================================

#include "editorfindreplacewidget.h"
#include "guiutils.h"
#include "i18ninterface.h"

//==============================================================================

#include "ui_editorfindreplacewidget.h"

//==============================================================================

#include <Qt>

//==============================================================================

#include <QAction>
#include <QKeyEvent>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QMenu>
#include <QPainter>
#include <QPixmap>
#include <QSize>
#include <QToolButton>

//==============================================================================

namespace OpenCOR {
namespace Editor {

//==============================================================================

EditorFindReplaceWidget::EditorFindReplaceWidget(QWidget *pParent) :
    Core::Widget(pParent),
    mGui(new Ui::EditorFindReplaceWidget),
    mActive(false)
{
    // Set up the GUI

    mGui->setupUi(this);

#ifdef Q_OS_MAC
    mGui->findEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
    mGui->replaceEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
    // Note: the above remove the focus border since it messes up the look of
    //       our edit widgets...
#endif

    // Create and handle our drop-down menu action

    mDropDownAction = new QAction(this);

    mCaseSensitiveAction = Core::newAction(true, this);
    mWholeWordsOnlyAction = Core::newAction(true, this);
    mRegularExpressionAction = Core::newAction(true, this);

    QMenu *dropDownMenu = new QMenu(this);

    dropDownMenu->addAction(mCaseSensitiveAction);
    dropDownMenu->addAction(mWholeWordsOnlyAction);
    dropDownMenu->addAction(mRegularExpressionAction);

    mDropDownAction->setMenu(dropDownMenu);

    mGui->findEdit->addAction(mDropDownAction, QLineEdit::LeadingPosition);

    connect(mCaseSensitiveAction, SIGNAL(toggled(bool)),
            this, SLOT(searchOptionChanged()));
    connect(mWholeWordsOnlyAction, SIGNAL(toggled(bool)),
            this, SLOT(searchOptionChanged()));
    connect(mRegularExpressionAction, SIGNAL(toggled(bool)),
            this, SLOT(searchOptionChanged()));

    // Create and handle our clear find and replace text actions

    mClearFindTextAction = Core::newAction(QIcon(":/qtCreator/src/plugins/coreplugin/images/editclear.png"), this);
    mClearReplaceTextAction = Core::newAction(QIcon(":/qtCreator/src/plugins/coreplugin/images/editclear.png"), this);

    connect(mClearFindTextAction, SIGNAL(triggered()),
            mGui->findEdit, SLOT(clear()));

    connect(mClearReplaceTextAction, SIGNAL(triggered()),
            mGui->replaceEdit, SLOT(clear()));

    // Make our find edit widget our focus proxy

    setFocusProxy(mGui->findEdit);

    // Some connections for our find-related widgets

    connect(mGui->findEdit, SIGNAL(textChanged(const QString &)),
            this, SLOT(updateClearFindTextAction(const QString &)));

    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->findPreviousButton, SLOT(setEnabled(bool)));
    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->findNextButton, SLOT(setEnabled(bool)));

    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->replaceButton, SLOT(setEnabled(bool)));
    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->replaceAndFindButton, SLOT(setEnabled(bool)));
    connect(this, SIGNAL(canFindReplace(const bool &)),
            mGui->replaceAllButton, SLOT(setEnabled(bool)));

    // A connection for our replace widget

    connect(mGui->replaceEdit, SIGNAL(textChanged(const QString &)),
            this, SLOT(updateClearReplaceTextAction(const QString &)));

    // A few more things , so that we are properly initialised

    retranslateUi();

    searchOptionChanged();

    setActive(true);

    updateStyleSheet();
    updateHeight();
    // Note: just to be safe, we update our height after updating our style
    //       sheet since we change the size of our tool buttons...

    mGui->findPreviousButton->setEnabled(false);
    mGui->findNextButton->setEnabled(false);

    mGui->replaceButton->setEnabled(false);
    mGui->replaceAndFindButton->setEnabled(false);
    mGui->replaceAllButton->setEnabled(false);
}

//==============================================================================

void EditorFindReplaceWidget::retranslateUi()
{
    // Retranslate our GUI

    mGui->retranslateUi(this);

    // Retranslate our actions

    I18nInterface::retranslateAction(mCaseSensitiveAction, tr("Case Sensitive"),
                                     tr("The search is case sensitive"));
    I18nInterface::retranslateAction(mWholeWordsOnlyAction, tr("Whole Words Only"),
                                     tr("The search is done on whole words only"));
    I18nInterface::retranslateAction(mRegularExpressionAction, tr("Regular Expression"),
                                     tr("The search uses a regular expression"));

    I18nInterface::retranslateAction(mClearFindTextAction, tr("Clear Text"),
                                     tr("Clear the text"));
    I18nInterface::retranslateAction(mClearReplaceTextAction, tr("Clear Text"),
                                     tr("Clear the text"));
}

//==============================================================================

bool EditorFindReplaceWidget::isCaseSensitive() const
{
    // Return whether the search is to be case sensitive

    return mCaseSensitiveAction->isChecked();
}

//==============================================================================

bool EditorFindReplaceWidget::searchWholeWordsOnly() const
{
    // Return whether we search whole words only

    return mWholeWordsOnlyAction->isChecked();
}

//==============================================================================

bool EditorFindReplaceWidget::useRegularExpression() const
{
    // Return whether we use a regular expression

    return mRegularExpressionAction->isChecked();
}

//==============================================================================

void EditorFindReplaceWidget::setReadOnly(const bool &pReadOnly)
{
    // Show/hide our replace-related widgets based on whether we are in
    // read-only mode

    Core::showEnableWidget(mGui->replaceLabel, !pReadOnly);
    Core::showEnableWidget(mGui->replaceEdit, !pReadOnly);
    Core::showEnableWidget(mGui->replaceButton, !pReadOnly);
    Core::showEnableWidget(mGui->replaceAndFindButton, !pReadOnly);
    Core::showEnableWidget(mGui->replaceAllButton, !pReadOnly);

    // Enable/disable our find spacer

    mGui->findLayout->setStretch(2, !pReadOnly);

    // Disable our replace-related buttons, if needed

    if (findText().isEmpty()) {
        mGui->replaceButton->setEnabled(false);
        mGui->replaceAndFindButton->setEnabled(false);
        mGui->replaceAllButton->setEnabled(false);
    }

    // Update our height

    updateHeight();
}

//==============================================================================

bool EditorFindReplaceWidget::isFindPreviousNextAvailable() const
{
    // Return whether the find previous/next actions are available

    return !findText().isEmpty();
}

//==============================================================================

void EditorFindReplaceWidget::selectFindText() const
{
    // Select our find text

    mGui->findEdit->selectAll();
}

//==============================================================================

QString EditorFindReplaceWidget::findText() const
{
    // Return our find text

    return mGui->findEdit->text();
}

//==============================================================================

void EditorFindReplaceWidget::setFindText(const QString &pFindText)
{
    // Set our find text and select it

    mGui->findEdit->setText(pFindText);

    selectFindText();
}

//==============================================================================

QString EditorFindReplaceWidget::replaceText() const
{
    // Return our replace text

    return mGui->replaceEdit->text();
}

//==============================================================================

bool EditorFindReplaceWidget::findEditHasFocus() const
{
    // Return whether our find edit has the focus

    return mGui->findEdit->hasFocus();
}

//==============================================================================

bool EditorFindReplaceWidget::replaceEditHasFocus() const
{
    // Return whether our replace edit has the focus

    return mGui->replaceEdit->hasFocus();
}

//==============================================================================

bool EditorFindReplaceWidget::isActive() const
{
    // Return whether we are active

    return mActive;
}

//==============================================================================

void EditorFindReplaceWidget::setActive(const bool &pActive)
{
    if (pActive == mActive)
        return;

    // Set our active state

    mActive = pActive;

    if (pActive)
        connect(mGui->findEdit, SIGNAL(textChanged(const QString &)),
                this, SIGNAL(findTextChanged(const QString &)));
    else
        disconnect(mGui->findEdit, SIGNAL(textChanged(const QString &)),
                   this, SIGNAL(findTextChanged(const QString &)));
}

//==============================================================================

void EditorFindReplaceWidget::updateFrom(EditorFindReplaceWidget *pFindReplace)
{
    // Update our find and replace texts from the given find/replace widget

    mGui->findEdit->setText(pFindReplace->findText());
    mGui->replaceEdit->setText(pFindReplace->replaceText());
}

//==============================================================================

void EditorFindReplaceWidget::updateHeight()
{
    // Update our layout
    // Note: we shouldn't have to do this, but if the user opens a read-only and
    //       shows ourselves, then the find-related widgets will be too 'low'.
    //       This is because the replace-related widgets get hidden/disabled as
    //       expected, but the layout doesn't get updated before we fix our
    //       height, so we update our layout here and in all cases...

    mGui->layout->update();

    // Update our height

    setFixedHeight(mGui->layout->sizeHint().height());
}

//==============================================================================

void EditorFindReplaceWidget::updateStyleSheet()
{
    // Change the style of our tool buttons

    QColor shadowColor = Core::shadowColor();

    setStyleSheet(QString("QToolButton {"
                          "    border: 0px;"
                          "    border-radius: 3px;"
                          "    padding: 1px;"
                          "}"
                          ""
                          "QToolButton:focus {"
                          "    background: rgba(%1, %2, %3, 0.13);"
                          "    border: 1px solid rgba(%1, %2, %3, 0.39);"
                          "}"
                          ""
                          "QToolButton:hover {"
                          "    background: rgba(%1, %2, %3, 0.39);"
                          "}"
                          ""
                          "QToolButton:pressed {"
                          "    background: rgba(%1, %2, %3, 0.79);"
                          "}").arg(QString::number(shadowColor.red()),
                                   QString::number(shadowColor.green()),
                                   QString::number(shadowColor.blue())));
}

//==============================================================================

void EditorFindReplaceWidget::changeEvent(QEvent *pEvent)
{
    // Check whether the palette has changed and if so then update our style
    // sheet

    if (pEvent->type() == QEvent::PaletteChange)
        updateStyleSheet();
}

//==============================================================================

void EditorFindReplaceWidget::keyPressEvent(QKeyEvent *pEvent)
{
    // Let people know that a key has been pressed

    bool handled = false;

    emit keyPressed(pEvent, handled);

    // Carry on as normal, if the event wasn't handled

    if (handled)
        // Accept the event

        pEvent->accept();
    else
        // Default handling of the event

        Core::Widget::keyPressEvent(pEvent);
}

//==============================================================================

void EditorFindReplaceWidget::resizeEvent(QResizeEvent *pEvent)
{
    // Default handling of the event

    Core::Widget::resizeEvent(pEvent);

    // Update our height

    updateHeight();
}

//==============================================================================

void EditorFindReplaceWidget::on_findPreviousButton_clicked()
{
    // Let people know that we want to find the previous occurrence of the text

    emit findPreviousRequested();
}

//==============================================================================

void EditorFindReplaceWidget::on_findNextButton_clicked()
{
    // Let people know that we want to find the next occurrence of the text

    emit findNextRequested();
}

//==============================================================================

void EditorFindReplaceWidget::on_replaceButton_clicked()
{
    // Let people know that we want to replace the current text

    emit replaceRequested();
}

//==============================================================================

void EditorFindReplaceWidget::on_replaceAndFindButton_clicked()
{
    // Let people know that we want to replace the current text and the find the
    // next occurence of the text

    emit replaceAndFindRequested();
}

//==============================================================================

void EditorFindReplaceWidget::on_replaceAllButton_clicked()
{
    // Let people know that we want to replace all the occurences of the text

    emit replaceAllRequested();
}

//==============================================================================

void EditorFindReplaceWidget::searchOptionChanged()
{
    // Update the icon used for the leading position of our find widget

    int nbOfOptions =  mCaseSensitiveAction->isChecked()
                      +mWholeWordsOnlyAction->isChecked()
                      +mRegularExpressionAction->isChecked();

    if (nbOfOptions) {
        static QIcon caseSensitiveIcon = QIcon(":/qtCreator/src/plugins/coreplugin/find/images/casesensitively.png");
        static QIcon wholeWordsOnlyIcon = QIcon(":/qtCreator/src/plugins/coreplugin/find/images/wholewords.png");
        static QIcon regularExpressionIcon = QIcon(":/qtCreator/src/plugins/coreplugin/find/images/regexp.png");

        static int IconSize = 16;
        static int IconWidth = 6;

        QPixmap dropDownPixmap = QPixmap(nbOfOptions*IconWidth-mRegularExpressionAction->isChecked(),
                                         IconSize);
        // Note: -mRegularExpressionAction->isChecked(), because
        //       regularExpressionIcon is effectively one pixel narrower than
        //       caseSensitiveIcon and wholeWordsOnlyIcon...

        dropDownPixmap.fill(Qt::transparent);

        QPainter dropDownPixmapPainter(&dropDownPixmap);

        int left = -IconWidth;

        if (mCaseSensitiveAction->isChecked()) {
            caseSensitiveIcon.paint(&dropDownPixmapPainter, left, 0, IconSize, IconSize);

            left += IconWidth;
        }

        if (mWholeWordsOnlyAction->isChecked()) {
            wholeWordsOnlyIcon.paint(&dropDownPixmapPainter, left, 0, IconSize, IconSize);

            left += IconWidth;
        }

        if (mRegularExpressionAction->isChecked())
            regularExpressionIcon.paint(&dropDownPixmapPainter, left-1, 0, IconSize, IconSize);

        mDropDownAction->setIcon(dropDownPixmap);
    } else {
        // No options are set, so use our default icon

        static QIcon defaultIcon = QIcon(":/qtCreator/src/plugins/coreplugin/images/magnifier.png");

        mDropDownAction->setIcon(defaultIcon);
    }
}

//==============================================================================

void EditorFindReplaceWidget::updateClearFindTextAction(const QString &pText)
{
    // Show/hide our clear text action, based on whether our find widget
    // contains some text

    if (pText.isEmpty())
        mGui->findEdit->removeAction(mClearFindTextAction);
    else
        mGui->findEdit->addAction(mClearFindTextAction, QLineEdit::TrailingPosition);

    // Let people know whether we can find/replace

    emit canFindReplace(!findText().isEmpty());
}

//==============================================================================

void EditorFindReplaceWidget::updateClearReplaceTextAction(const QString &pText)
{
    // Show/hide our clear text action, based on whether our replace widget
    // contains some text

    if (pText.isEmpty())
        mGui->replaceEdit->removeAction(mClearReplaceTextAction);
    else
        mGui->replaceEdit->addAction(mClearReplaceTextAction, QLineEdit::TrailingPosition);
}

//==============================================================================

}   // namespace Editor
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>