📄 func.h
字号:
/** * @file func.h * @brief Function representation * * @author Makino, Takaki <t-makino-punnets01@snowelm.com> * @date 2003-05-01 * @version $Id: func.h,v 1.2 2003/05/02 09:13:05 t Exp $ * * Copyright (C) 2003 Makino, Takaki. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#ifndef __func_h#define __func_h#include <math.h>#include <string>#include <iostream>#include <sstream>#include <mak/infinity.h>#include "punnets_base.h"#define USE_DYNAMICnamespace punnets_common {//////////////////////////////////////////////////////////////////////////// Base class of a message to a function/// /// A message is used to deliver a change to a function. Usually an event/// is delivered to a neuron, but a neuron has several functions. Moreover,/// we don't make neuron to handle correspondence of a specific event to /// a specific function. For this purpose a message is used, as every function/// knows which message has correspondence to itself.class message_base{public: message_base() { } virtual ~message_base() { } /// Returns the pointer of a string that represents the class. /// The pointer must be same for any instance of a given class. /// A function can check the type of the message by comparing the pointer. virtual const char *getMessageId() const = 0;}; //////////////////////////////////////////////////////////////////////////// Abstract base class of a function.////// A base class that represents a numerical function./// Some functions needs a reference point to be calculated based on differential/// equation. Such a function is derived from func_deriveq_base, but func_base/// contains interface for such a function.class func_base{protected: /// An entrance to recalculate coefficient at the value change caused by some external factor. /// In func_base this function do nothing. This function will be defined in the /// derived classes with the requirement of the recalculation. virtual void valueChange() { } public: func_base() { } virtual ~func_base() { } /// Return true if the function will return only zeros after the specified time. virtual bool shouldDelete(ntime_t /*current*/) { return false; } /// Process the specified message at the specified time. Return true if the message is processed. /// In func_base, this function always returns false (processes no message). virtual bool processMessage(ntime_t, const message_base &) { return false; } /// Change leak value on a leaky integrate function. Redefined in func_deriveq_base. virtual void setLambda(real /*new_lambda*/) { } /// Change zero point on a leaky integrate function. Redefined in func_deriveq_base. virtual void setZeroPoint(real /*new_zeropoint*/) { } /// A pure virtual function that returns the max gradient of the function after the time t. virtual real getMaxGradient( ntime_t t ) const = 0; /// A virtual function that returns the next incontinuity point after the time t. /// In func_base, the function always returns infinity. virtual ntime_t getNextIncontinuity( ntime_t /*from*/ ) const { return mak::Infinity; }; /// A pure virtual function that returns f(t). virtual real getValue( ntime_t t ) const = 0; /// A pure virtual function that returns df(t)/dt. virtual real get1stDeriv( ntime_t t ) const = 0; /// A pure virtual function that returns d<sup>2</sup>f(t)/dt<sup>2</sup>. virtual real get2ndDeriv( ntime_t t ) const = 0; /// Obtains a zeroth-order linear envelope of the function. floor < f(t+α) < ceil, f(t)+αdownslope < f(t+α) < f(t)+αupslope virtual void getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const = 0; /// Obtains a first--order linear envelope of the function. floor < f(t+α) < ceil, f(t)+αdownslope < f(t+α) < f(t)+αupslope virtual void get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const = 0; /// Obtains a second-order linear envelope of the function. floor < f(t+α) < ceil, f(t)+αdownslope < f(t+α) < f(t)+αupslope virtual void get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const = 0; /// Allocates and returns another instance of this function. virtual func_base * clone() = 0; /// Obtains a human-readable description string of this function. virtual std::string getDescription() = 0;}; //////////////////////////////////////////////////////////////////////////// Abstract base class of a leaky integration function.////// The function has a form of the following differential equation./// <nobr>d<var>x</var>/d<var>t</var> = f(<var>t</var>)-λ<var>x</var></nobr>/// The integration constant C is determined as f(zerop)=0 stands.class func_deriveq_base : public func_base{protected: real lambda; ntime_t zerop; /// An entrance to recalculate coefficient at the zero-pointer change. /// In func_base this function do nothing. This function will be defined in the /// derived classes with the requirement of the recalculation. virtual void zeropChange() { } public: func_deriveq_base() : func_base(), lambda(1.0), zerop(-10000000.0) { } virtual ~func_deriveq_base() { } /// Change leak value on a leaky integrate function. virtual void setLambda(real new_lambda) { assert( new_lambda > 0.0 ); lambda = new_lambda; valueChange(); } /// Change zero point on a leaky integrate function. virtual void setZeroPoint(real new_zeropoint) { zerop = new_zeropoint; zeropChange(); } /// A message that changes lambda (leak value). class message_set_lambda : public message_base { real lambda;public: message_set_lambda(real newlambda) : message_base() { lambda = newlambda; } static const char * const messageId; virtual const char *getMessageId() const { return messageId; } real getLambda() const { return lambda; } }; /// A message that changes zero point. class message_set_zero_point : public message_base { real zerop;public: message_set_zero_point(real newzerop) : message_base() { zerop = newzerop; } static const char * const messageId; virtual const char *getMessageId() const { return messageId; } real getZeroPoint() const { return zerop; } }; /// Processes message_set_lambda and message_set_zero_point messages. virtual bool processMessage(ntime_t t, const message_base &m) { #ifdef USE_DYNAMIC if( const message_set_lambda *mm = dynamic_cast<const message_set_lambda *>(&m) ) { setLambda( mm->getLambda() ); return true; }#else if( m.getMessageId() == message_set_lambda::messageId ) { setLambda( dynamic_cast<const message_set_lambda &>(m).getLambda() ); return true; }#endif#ifdef USE_DYNAMIC if( const message_set_zero_point *mm = dynamic_cast<const message_set_zero_point *>(&m) ) { setZeroPoint( mm->getZeroPoint() ); return true; }#else if( m.getMessageId() == message_set_zero_point::messageId ) { setZeroPoint( dynamic_cast<const message_set_zero_point &>(m).getZeroPoint() ); return true; }#endif return func_base::processMessage(t,m); }}; /// </body></classdef>//////////////////////////////////////////////////////////////////////////// A constant function.////// This class represents a constant function f(<var>t</var>) = c.class func_const : public func_base{ real c;public: /// constructs a func_const with the constant c. func_const(real ic) : func_base(), c(ic) { } virtual real getMaxGradient( ntime_t /*t*/ ) const { return 0; }; virtual real getValue( ntime_t /*t*/ ) const { return c; } virtual real get1stDeriv( ntime_t /*t*/ ) const { return 0; } virtual real get2ndDeriv( ntime_t /*t*/ ) const { return 0; } virtual void getValueDomain( ntime_t /*t*/, real &upslope, real &ceil, real &downslope, real &floor ) const { upslope = downslope = 0; ceil = floor = c; } virtual void get1stDerivDomain( ntime_t /*t*/, real &upslope, real &ceil, real &downslope, real &floor ) const { upslope = downslope = 0; ceil = floor = 0; } virtual void get2ndDerivDomain( ntime_t /*t*/, real &upslope, real &ceil, real &downslope, real &floor ) const { upslope = downslope = 0; ceil = floor = 0; } virtual func_const * clone() { return new func_const(*this); } virtual std::string getDescription() { std::ostringstream oss; oss << "func_const c=" << c; return oss.str(); }};//////////////////////////////////////////////////////////////////////////// An integration of a constant function.////// The result of solving dx/dt = c - λ x. That is,/// x = c/λ + C e^-λ t, where C is an integration constant.class func_const_int : public func_deriveq_base{ real c; real limit; /// When lambda is changed, the converging value at the limit of infinity will be also changed. virtual void valueChange() { limit = c / lambda; }public: /// Constructs a func_const_int with the constant c. func_const_int(real ic) : func_deriveq_base(), c(ic) { valueChange(); } virtual real getMaxGradient( ntime_t /*t*/ ) const { return limit < 0 ? 0 : c; }; virtual real getValue( ntime_t t ) const { return limit * (1 - exp(- lambda * (t - zerop))); } virtual real get1stDeriv( ntime_t t ) const { return limit * lambda * exp(- lambda * (t - zerop)); } virtual real get2ndDeriv( ntime_t t ) const { return - limit * lambda * lambda * exp(- lambda * (t - zerop)); } virtual real get3rdDeriv( ntime_t t ) const { return limit * lambda * lambda * lambda * exp(- lambda * (t - zerop)); } virtual void getValueDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const; virtual void get1stDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const; virtual void get2ndDerivDomain( ntime_t t, real &upslope, real &ceil, real &downslope, real &floor ) const; virtual func_const_int * clone() { return new func_const_int(*this); } virtual std::string getDescription() { std::ostringstream oss; oss << "func_const_int c=" << c << ", lambda=" << lambda << ", zerop=" << zerop; return oss.str(); }};/// </body></classdef>//////////////////////////////////////////////////////////////////////////// A step function.////// This class represents a step function, f(<var>t</var>) = r s(t - t<sub>0</sub>).class func_step : public func_base{ real r; ntime_t t0;public: func_step(real ir, ntime_t it0) : func_base(), r(ir), t0(it0) { } virtual real getMaxGradient( ntime_t /*t*/ ) const { return 0; }; virtual real getValue( ntime_t t ) const { return (t0 < t ? r : 0.0); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -