# -*- coding: utf-8 -*-
"""
Collection of continuous blocks
"""
#from ..blocks import Block
from bms import Block,np
import math
[docs]class Gain(Block):
"""
output=value* input + offset
"""
def __init__(self,input_variable,output_variable,value,offset=0):
Block.__init__(self,[input_variable],[output_variable],1,0)
self.value=value
self.offset=offset
[docs] def Evaluate(self,it,ts):
return self.value*self.InputValues(it)[0]+self.offset
[docs] def LabelBlock(self):
return str(self.value)
[docs] def LabelConnections(self):
return ['','']
[docs]class Sum(Block):
"""
output=\sum inputs
"""
def __init__(self,inputs,output_variable):
Block.__init__(self,inputs,[output_variable],1,0)
[docs] def Evaluate(self,it,ts):
return np.array([np.sum(self.InputValues(it))])
[docs] def LabelBlock(self):
return '+'
[docs] def LabelConnections(self):
return ['+','+']
[docs]class WeightedSum(Block):
"""
Defines a weighted sum over inputs
output=\sum w_i * input_i
"""
def __init__(self,inputs,output_variable,weights,offset=0):
Block.__init__(self,inputs,[output_variable],1,0)
self.weights=weights
self.offset=offset
[docs] def Evaluate(self,it,ts):
value=np.dot(self.weights,self.InputValues(it))+self.offset
return value
[docs] def LabelBlock(self):
return 'W+'+str(self.weights)
[docs] def LabelConnections(self):
return self.weights
[docs]class Subtraction(Block):
"""
output=input1-input2
"""
def __init__(self,input_variable1,input_variable2,output_variable):
Block.__init__(self,[input_variable1,input_variable2],[output_variable],1,0)
[docs] def Evaluate(self,it,ts):
return np.dot(np.array([1,-1]),self.InputValues(it))
[docs] def LabelBlock(self):
return '-'
[docs] def LabelConnections(self):
return ['+','-']
[docs]class Product(Block):
"""
output=input1*input2
"""
def __init__(self,input_variable1,input_variable2,output_variable):
Block.__init__(self,[input_variable1,input_variable2],[output_variable],1,0)
[docs] def Evaluate(self,it,ts):
value1,value2=self.InputValues(it)
return np.array([value1*value2])
[docs] def LabelBlock(self):
return 'x'
[docs] def LabelConnections(self):
return ['','']
[docs]class Division(Block):
"""
output=input1/input2
"""
def __init__(self,input_variable1,input_variable2,output_variable):
Block.__init__(self,[input_variable1,input_variable2],[output_variable],1,0)
[docs] def Evaluate(self,it,ts):
value1,value2=self.InputValues(it)
return value1/value2
[docs] def LabelBlock(self):
return '/'
[docs] def LabelConnections(self):
return ['','']
[docs]class ODE(Block):
"""
a,b are vectors of coefficients such as H, the transfert function of
the block, may be written as:
H(p)=(a[i]p**i)/(b[j]p**j) (Einstein sum on i,j)
p is Laplace's variable
"""
def __init__(self,input_variable,output_variable,a,b):
Block.__init__(self,[input_variable],[output_variable],len(a),len(b)-1)
# self.AddInput(input_variable)
# self.AddOutput(output_variable)
self.a=a
self.b=b
self._M={}# Output matrices stored for differents time steps
def _get_M(self,delta_t):
n=len(self.a)
A=np.zeros(n)
for i,ai in enumerate(self.a):
Ae=[self.a[i]*(-1)**j*math.factorial(i)/math.factorial(j)/math.factorial(i-j)/((delta_t)**i) for j in range(i+1)]# Elementery A to assemblate in A
for j,aej in enumerate(Ae):
A[j]+=aej
n=len(self.b)
B=np.zeros(n)
for i,ai in enumerate(self.b):
Be=[self.b[i]*(-1)**j*math.factorial(i)/math.factorial(j)/math.factorial(i-j)/((delta_t)**i) for j in range(i+1)]# Elementery A to assemblate in A
for j,bej in enumerate(Be):
B[j]+=bej
Mo=[-x/B[0] for x in B[1:][::-1]]
Mi=[x/B[0] for x in A[::-1]]
return (Mi,Mo)
[docs] def OutputMatrices(self,delta_t):
try:
Mi,Mo=self._M[delta_t]
except KeyError:
Mi,Mo=self._get_M(delta_t)
self._M[delta_t]=(Mi,Mo)
return Mi,Mo
[docs] def Evaluate(self,it,ts):
Mi,Mo=self.OutputMatrices(ts)
# Solve at time t with time step ts
# print(Mi,Mo)
# print(np.dot(Mi,self.InputValues(it).T)+np.dot(Mo,self.OutputValues(it).T))
# if abs(np.dot(Mi,self.InputValues(it).T)+np.dot(Mo,self.OutputValues(it).T))>10000:
# print(Mi,self.InputValues(it),Mo,self.OutputValues(it))
# print(np.dot(Mi,self.InputValues(it).T))
# print(np.dot(Mo,self.OutputValues(it).T))
return np.dot(Mi,self.InputValues(it).T)+np.dot(Mo,self.OutputValues(it).T)
[docs] def LabelBlock(self):
return str(self.a)+'\n'+str(self.b)
[docs] def LabelConnections(self):
return ['','']
[docs]class FunctionBlock(Block):
"""
output=f(input)
"""
def __init__(self,input_variable,output_variable,function):
Block.__init__(self,[input_variable],[output_variable],1,0)
self.function=function
[docs] def Evaluate(self,it,ts):
return np.array([self.function(self.InputValues(it)[0])])
[docs] def LabelBlock(self):
return 'f(t)'
[docs] def LabelConnections(self):
return ['','']
#class Switch(Block):
# def __init__(self,input_variable,output_variable,function):
# """
# output=f(input)
# """
# Block.__init__(self,[input_variable],[output_variable],1,0)
# self.function=function
#
# def Evaluate(self,it,ts):
# self.outputs[0]._values[it]=self.function(self.InputValues(it)[0])
#
# def Label(self):
# return 'f(t)'