Please enable JavaScript to view this site.

IBM® SPSS® Amos™ 28

Navigation: Programming with Amos > Additional Programming Examples > Examples using the AmosEngine class

Use the AmosEngine class to evaluate derivatives numerically and display the results with the Amos Debug class

Scroll Prev Top Next More

The following program fits the model of Example 8 and displays derivatives evaluated at the discrepancy function minimum. For purposes of comparison, approximate derivatives based on finite differences are also displayed.

Imports AmosEngineLib
Module MainModule
    Dim Sem As New AmosEngine
    Dim ad As New AmosDebug.AmosDebug
 
    Sub Main()
        Dim Originalparameters() As Double
 
        Sem.BeginGroup(AmosEngine.AmosDir & "Examples\English\UserGuide.xls", "Grnt_fem")
        Sem.AStructure("visperc = (1) spatial + (1) err_v")
        Sem.AStructure("cubes = (a) spatial + (1) err_c")
        Sem.AStructure("lozenges = (b) spatial + (1) err_l")
        Sem.AStructure("paragraph = (1) verbal + (1) err_p")
        Sem.AStructure("sentence = (c) verbal + (1) err_s")
        Sem.AStructure("wordmean = (d) verbal + (1) err_w")
 
        If (Sem.FitModel() = 0) Then
            'Save parameter values so they can be restored
            Sem.ParameterVector(Originalparameters)
            TestDerivatives()
            'Restore the parameter values and display them
            Sem.PutParameterVector(Originalparameters)
            ad.PrintX(Originalparameters, "Parameter values")
        End If
        Sem.Dispose()
    End Sub
 
    Sub TestDerivatives()
        Dim Ind As Integer, F As Double
        Dim G() As Double, GNumeric() As Double
        Dim H() As Double, HNumeric() As Double
        Sem.Evaluate2e(Ind, F, G, H)
        If Ind <> 0 Then
            Throw(New System.exception("Could not evaluate function and derivatives."))
        End If
        NumericDerivatives(Sem, GNumeric, HNumeric)
        ad.DecimalPlaces = 8
        ad.PrintX(G, "1st Derivatives")
        ad.PrintX(GNumeric, "Numerical 1st Derivatives")
        ad.PrintTriangle(H, "2nd Derivatives")
        ad.PrintTriangle(HNumeric, "Numerical 2nd Derivatives")
    End Sub
 
    Sub NumericDerivatives(ByVal Sem As AmosEngine, ByRef GNumeric() As Double, ByRef HNumeric() As Double)
        Const Delta As Double = 0.0001
        Dim NParams As Integer
        Dim FPlus As Double, FMinus As Double
        Dim FPP As Double, FMM As Double
        Dim FPM As Double, FMP As Double
        Dim i As Integer, j As Integer, k As Integer
        Dim DTempi As Double, DTempj As Double
        NParams = Sem.NumberOfParameters
        ReDim GNumeric(NParams - 1)
        ReDim HNumeric(NParams * (NParams + 1) \ 2 - 1)
 
        '1st Derivatives
        For i = 1 To NParams
            DTempi = Sem.ParameterValue(i)
            Sem.PutParameterValue(i, DTempi + Delta)
            FPlus = Evaluate()
            Sem.PutParameterValue(i, DTempi - Delta)
            FMinus = Evaluate()
            Sem.PutParameterValue(i, DTempi)
            GNumeric(i - 1) = (FPlus - FMinus) / (2 * Delta)
        Next
 
        '2nd Derivatives
        k = 0
        For i = 1 To NParams
            For j = 1 To i
                DTempi = Sem.ParameterValue(i)
                DTempj = Sem.ParameterValue(j)
                If i = j Then
                    FPM = Evaluate()
                    FMP = FPM
                    Sem.PutParameterValue(i, DTempi + 2 * Delta)
                    FPP = Evaluate()
                    Sem.PutParameterValue(i, DTempi - 2 * Delta)
                    FMM = Evaluate()
                Else
                    Sem.PutParameterValue(i, DTempi + Delta)
                    Sem.PutParameterValue(j, DTempj + Delta)
                    FPP = Evaluate()
                    Sem.PutParameterValue(j, DTempj - Delta)
                    FPM = Evaluate()
                    Sem.PutParameterValue(i, DTempi - Delta)
                    FMM = Evaluate()
                    Sem.PutParameterValue(j, DTempj + Delta)
                    FMP = Evaluate()
                End If
                Sem.PutParameterValue(i, DTempi)
                Sem.PutParameterValue(j, DTempj)
 
                HNumeric(k) = (FPP + FMM - FPM - FMP) / (4 * Delta ^ 2)
                k = k + 1
            Next
        Next
    End Sub
 
    Function Evaluate() As Double
        Dim Ind As Integer
        Dim F As Double
        Sem.Evaluate0(Ind, F)
        If Ind <> 0 Then
            Throw(New System.Exception("Could not evaluate function."))
        End If
        Evaluate = F
    End Function
End Module

© 2021 Amos Development Corporation