Imports BV.Core
Imports BV.Math
Imports MidRange
'Imports IMidRange
Imports System.Drawing
Imports System.ComponentModel
Imports System.Collections.Generic
Imports System.Text
Imports BV.TopLevel.Parsing
''' <summary>
''' Almacena polos, ceros y la constante K.
''' Devuelve un valor con el metodo Calc
''' </summary>
''' <remarks>29/7/04</remarks>
<RealVariableIsMain(False), _
CLSCompliant(True), _
Serializable()> _
Public Class LaplaceFunction
Inherits FunctionBase
Public Enum EConstantForm
Form1
Form2
End Enum
Protected ArrSing As List(Of Singularity)
'Protected intNameSpace As SpaceableDescribible
Protected Shared LTools As LaplaceTools
Protected ConstantForm As EConstantForm
Protected intPoleCounter As Integer 'contador de polos, los ceros salen por la diferencia
Protected intAngleType As EAngleType
'margen de error, radio donde buscar una singularidad para saber si es igual a otra
#Region "Constructor"
Public Sub New(ByVal BaseName As String)
MyBase.New("LaplaceSystems", BaseName & intCounter.Increment)
CommonInitilize()
End Sub
Public Sub New()
MyBase.New("LaplaceSystems", "System" & intCounter.Increment)
CommonInitilize()
End Sub
Private Sub CommonInitilize()
ArrSing = New List(Of Singularity)
If LTools Is Nothing Then
LTools = New LaplaceTools
End If
intSpaceDec.BriefDescription = "Laplace System"
intSpaceDec.Description = "Laplace System"
intPoleCounter = 0
LTools.ErrorMarginIsPorcentual = True
LTools.ErrorMargin = 5 '%
Me.intValue.Real = 1
Me.intValue.Imaginary = 0
intAngleType = EAngleType.Degree
ConstantForm = EConstantForm.Form1
End Sub
#End Region
#Region "Properties"
#Region "TypeOfGraph"
<Browsable(False)> _
Public Property AngleType() As EAngleType
Get
Return EAngleType.Radians 'intAngleType
End Get
Set(ByVal Value As EAngleType)
intAngleType = Value
End Set
End Property
#End Region
#Region "Singularities Properties"
''' <summary>
''' DC Gain, if available
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
<Browsable(True), Description("DC Gain, if available")> _
Public Property KDC() As ComplexUndefinied
Get
Return Me.intValue
End Get
Set(ByVal value As ComplexUndefinied)
Me.Value = value
End Set
End Property
''' <summary>
''' K de la Forma Factorizada con singularidades tipo (S-Si)
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public ReadOnly Property K() As ComplexUndefinied
Get
K = Me.intValue 'KDC
For Each sng As Singularity In Me.ArrSing
If sng.IsAtOrigin = False Then
If sng.SingularitieType = SingType.Polo Then
'K = BVMathFunctions.Not(K * sng.Value)
K = -(K * sng.Value)
Else 'zero
K = -(K / sng.Value)
End If
End If
Next
End Get
End Property
''' <summary>
''' Realiza y devuelve el producto de los valores de las
''' singularidades del array indicado
''' </summary>
''' <param name="Sngs">Array de Singularidades</param>
''' <returns>
''' =(0,0) ;si el array no contiene singularidades
''' =-S1*(-S2)*(-S3)....*(-Sn); siempre y cuando Si no est� en el origen
''' </returns>
''' <remarks></remarks>
Public Shared Function SingsProduct(ByVal Sngs() As Singularity) As ComplexUndefinied
If Sngs Is Nothing Then
Exit Function
End If
SingsProduct = New ComplexUndefinied(1, 0)
For Each sng As Singularity In Sngs
If sng.IsAtOrigin = False Then
If sng.SingularitieType = SingType.Polo Then
SingsProduct = -(SingsProduct * sng.Value)
Else 'zero
SingsProduct = -(SingsProduct / sng.Value)
End If
End If
Next
End Function
<Browsable(False)> _
Public ReadOnly Property Singularities() As Singularity()
Get
If ArrSing.Count = 0 Then
Return Nothing
End If
Return ArrSing.ToArray()
End Get
End Property
<Browsable(False)> _
Public ReadOnly Property SingCount() As Integer
Get
Return ArrSing.Count
End Get
End Property
<Browsable(True)> _
Public ReadOnly Property PoleCount() As Integer
Get
Return intPoleCounter
End Get
End Property
<Browsable(True)> _
Public ReadOnly Property ZeroCount() As Integer
Get
Return Me.ArrSing.Count - intPoleCounter
End Get
End Property
#End Region
#Region "Other"
Public Overrides ReadOnly Property IsConstant() As Boolean
Get
Return Me.ArrSing.Count = 0
End Get
End Property
<Browsable(False)> _
Public Property ErrorMargin() As Double
Get
Return LTools.ErrorMargin
End Get
Set(ByVal Value As Double)
LTools.ErrorMargin = Value
End Set
End Property
<Browsable(False)> _
Public Property ErrorMarginIsPorcentual() As Boolean
Get
Return LTools.ErrorMarginIsPorcentual
End Get
Set(ByVal Value As Boolean)
LTools.ErrorMarginIsPorcentual = Value
End Set
End Property
#End Region
#End Region
#Region "Add, Remove, Update"
''' <summary>
''' agrega una singularidad
''' </summary>
''' <param name="SingValue"></param>
''' <returns>
''' devuelve la singularidad que realmente esta almacenada
''' en el sistema
''' </returns>
''' <remarks>
''' verifica que no esta ya ingresada, entonces se le
''' incrementa el orden y descarta la nueva si existe
''' el conjugado lo asocia
''' </remarks>
Public Function Add(ByVal SingValue As Singularity) As Singularity
If ArrSing.Contains(SingValue) Then
Return Nothing
End If
Dim i As Integer
Dim R As LaplaceTools.ESingCompareResult
'verifico primero que no haya iguales
For i = 0 To ArrSing.Count - 1
R = LTools.CompareSings(ArrSing.Item(i), SingValue)
If R = LaplaceTools.ESingCompareResult.Equal OrElse _
R = LaplaceTools.ESingCompareResult.ConjugatedAndApareated Then
'son iguales, incremento el orden
CType(ArrSing.Item(i), Singularity).IncrementOrder()
RaiseDataChanged(New EventArgs)
Return ArrSing.Item(i)
End If
Next
'si encontro uno igual, verifico entonces que no haya dos desapareados y
'conjugados en valor
For i = 0 To ArrSing.Count - 1
R = LTools.CompareSings(ArrSing.Item(i), SingValue)
If R = LaplaceTools.ESingCompareResult.Conjugated Then
'si se cumple, asigno uno conjugado del otro
CType(ArrSing.Item(i), Singularity).Conjugate = SingValue
Exit For
End If
Next
AddSing(SingValue, True)
If SingValue.IsConjugated Then
AddSing(SingValue.Conjugate, False)
End If
RaiseDataChanged(New EventArgs)
Return SingValue
End Function
'solo para uso interno
Private Sub AddSing(ByVal SingValue As Singularity, ByVal [AddHandler] As Boolean)
ArrSing.Add(SingValue)
If SingValue.SingularitieType = SingType.Polo Then
intPoleCounter += 1
End If
SingValue.NameSpace = Me.NameSpace
If [AddHandler] Then
AddHandler SingValue.DataChange, AddressOf OnParamChange
End If
End Sub
''' <summary>
''' remueve la singularidad especificada, retorna true si fue encontrada
''' y removida
''' </summary>
''' <param name="SingValue"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function Remove(ByVal SingValue As Singularity) As Boolean
If ArrSing.Contains(SingValue) Then
RemoveHandler SingValue.DataChange, AddressOf OnParamChange
'If Not SingValue.Conjugate Is Nothing Then
' RemoveHandler SingValue.Conjugate.DataChange, AddressOf RaiseDataChanged
'End If
ArrSing.Remove(SingValue)
intPoleCounter -= 1
RaiseDataChanged(New EventArgs)
Return True
Else
If LTools.ErrorMargin > 0 Then
Dim i As Integer
Dim S As Singularity
For i = 0 To ArrSing.Count - 1
S = ArrSing(i)
If LTools.CompareRange(S, SingValue) Then
RemoveHandler S.DataChange, AddressOf OnParamChange
'If Not S.Conjugate Is Nothing Then
' RemoveHandler S.Conjugate.DataChange, AddressOf OnParamChange
'End If
ArrSing.Remove(S)
intPoleCounter -= 1
RaiseDataChanged(New EventArgs)
Return True
End If
Next
End If
Return False
End If
End Function
''' <summary>
''' reemplaza una dada singularidad por otra nueva
''' </summary>
''' <param name="OldSing"></param>
''' <param name="NewSing"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function Replace(ByVal OldSing As Singularity, ByVal NewSing As Singularity) As Boolean
If ArrSing.Contains(OldSing) Then
RemoveHandler OldSing.DataChange, AddressOf OnParamChange
ArrSing.Remove(OldSing)
Me.ArrSing.Add(NewSing)
AddHandler NewSing.DataChange, AddressOf OnParamChange
RaiseDataChanged(New EventArgs)
Return True
Else
If LTools.ErrorMargin > 0 Then
Dim i As Integer
Dim S As Singularity
For i = 0 To ArrSing.Count - 1
S = ArrSing(i)
If LTools.CompareRange(S, OldSing) Then
RemoveHandler S.DataChange, AddressOf OnParamChange
ArrSing.Remove(S)
Me.ArrSing.Add(NewSing)
AddHandler NewSing.DataChange, AddressOf OnParamChange
RaiseDataChanged(New EventArgs)
Return True
End If
Next
End If
Return False
End If
End Function
Public Sub Clear()
For Each sing As Singularity In Me.ArrSing
RemoveHandler sing.DataChange, AddressOf OnParamChange
Next
Me.ArrSing.Clear()
End Sub
Public Function Contains(ByVal SingValue As Singularity) As Boolean
Return ArrSing.Contains(SingValue)
End Function
#End Region
#Region "Calc Methods"
''' <summary>
''' Calcula el valor de la funcion para un dado punto del plano complejo
''' </summary>
''' <param name="z"></param>
''' <returns></returns>
''' <remarks>
''' hay que probarlo
''' 15/7/04
''' </remarks>
Public Overrides Function Calc(ByVal z As ComplexUndefinied) As ComplexUndefinied 'Implements ICalcU.Calc
Static LastValue, LastZ As ComplexUndefinied
If Me.intChanged = Wchanged.None AndAlso LastZ = z Then
Return LastValue
End If
If ArrSing.Count = 0 Then
'calcular para 0 singularidades y salir
LastValue = Me.intValue
'LastZ = z
Else
Dim i As Integer
Dim total As ComplexPolar
Dim tmpP As ComplexPolar
Dim sng As Singularity
Dim Arr() As Singularity
Arr = Me.Singularities
total.Modulo = 1
total.Angulo = 0
If ConstantForm = EConstantForm.Form1 Then
Dim k As ComplexUndefinied
k = Me.intValue
'k = BVMathFunctions.ComplexInverse(Me.ctek)
For i = 0 To Arr.GetUpperBound(0)
If Arr(i) Is Nothing Then
Stop
End If
sng = Arr(i)
'saca el modulo
If sng.IsAtOrigin Then
tmpP = z.Polar
Else
tmpP = BVMathFunctions.BinomicToPolar(z.Real - sng.Value.Real, z.Imaginary - sng.Value.Imaginary)
End If
If sng.SingularitieType = SingType.Zero Then
If Not sng.IsAtOrigin Then
If sng.Order = 1 Then
k = BVMathFunctions.Division(k, BVMathFunctions.[Not](sng.Value))
Else
k = BVMathFunctions.Division(k, BVMathFunctions.Power(BVMathFunctions.[Not](sng.Value), New ComplexUndefinied(sng.Order, 0)))
End If
End If
If sng.Order > 1 Then
total.Modulo = tmpP.Modulo * total.Modulo
total.Angulo = tmpP.Angulo + total.Angulo
Else
total.Modulo = (tmpP.Modulo ^ sng.Order) * total.Modulo
total.Angulo = tmpP.Angulo * sng.Order + total.Angulo
End If
Else
If sng.Order = 1 Then
If tmpP.Modulo <> 0 Then
total.Modulo = total.Modulo / tmpP.Modulo
Else
total.Modulo = Double.PositiveInfinity
End If
total.Angulo = total.Angulo - tmpP.Angulo
Else
total.Modulo = total.Modulo / (tmpP.Modulo ^ sng.Order)
total.Angulo = total.Angulo - tmpP.Angulo * sng.Order
End If
If Not sng.IsAtOrigin Then
If sng.Order = 1 Then
k = BVMathFunctions.Product(k, BVMathFunctions.[Not](sng.Value))
Else
k = BVMathFunctions.Product(k, BVMathFunctions.Power(BVMathFunctions.[Not](sng.Value), New ComplexUndefinied(sng.Order, 0)))
End If
End If
End If
Next
LastValue = BVMathFunctions.Product(New ComplexUndefinied(total), k)
Else
For i = 0 To Arr.GetUpperBound(0)
sng = CType(Arr(i), Singularity) ' ComplexBinomical)
'saca el modulo
tmpP = BVMathFunctions.BinomicToPolar(z.Real - sng.Value.Real, z.Imaginary - sng.Value.Imaginary)
If sng.SingularitieType = SingType.Zero Then
total.Modulo = (tmpP.Modulo) * total.Modulo '^tmpP.
total.Angulo = tmpP.Angulo + total.Angulo
Else
If tmpP.Modulo <> 0 Then
total.Modulo = total.Modulo / tmpP.Modulo
Else
total.Modulo = BVMathFunctions.intOverflow
End If
total.Angulo = total.Angulo - tmpP.Angulo
End If
Next
LastValue = BVMathFunctions.Product(New ComplexUndefinied(total), intValue)
End If
End If
LastZ = z
Me.intChanged = Wchanged.None
Return LastValue
'If intETypeOfComplex = ETypeOfComplex.Polar Then
' Calc.ConvertTo(ETypeOfComplex.Polar, True)
'End If
'If intAngleType = EAngleType.Degree Then
' Calc.Angulo = Me.BVMathFunctions.Rad2Degree(Calc.Angulo, True)
'End If
End Function
Public Overrides Function Calc(ByVal s As Double) As ComplexUndefinied 'Implements ICalcSC.Calc
Return Calc(New ComplexUndefinied(s, 0))
End Function
#End Region
#Region "Clone Methods"
''' <summary>
''' crea una copia superficial
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function Clone() As Object
Dim L As LaplaceFunction
L = New LaplaceFunction
For Each s As Singularity In Me.ArrSing.ToArray
L.Add(s)
Next
L.ConstantForm = Me.ConstantForm
L.intValue = Me.intValue
L.intAngleType = Me.intAngleType
Return L
End Function
Public Function DeepClone() As Object
Dim L As LaplaceFunction
Dim a As Array
Dim i As Integer
L = New LaplaceFunction
a = Me.Singularities
For i = 0 To a.GetUpperBound(0)
L.Add(CType(a(i), ICloneable).Clone)
Next
L.ConstantForm = Me.ConstantForm
L.intValue = Me.intValue
L.intAngleType = Me.intAngleType
Return L
End Function
#End Region
'Protected Overridable Sub OnK_Change(ByVal sender As Object, ByVal e As EventArgs)
' RaiseDataChanged(Me, New EventArgs)
'End Sub
End Class