Click here to Skip to main content
15,895,084 members
Articles / Programming Languages / Visual Basic

Mathemathics Framework

Rate me:
Please Sign up or sign in to vote.
4.76/5 (56 votes)
16 Sep 2008CPOL6 min read 75.4K   6.2K   171  
.NET Mathematical Framework
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



By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer Universidad Tecnológica Nacional
Argentina Argentina
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions