Как передать функцию в функцию? функторы / функциональные объекты доступны в VB2010? - PullRequest
8 голосов
/ 12 октября 2011

Я хочу создать метод численного интегрирования с использованием аналитической функции и интегрировать ее через определенный интервал. Для процедуры численного интегрирования я хочу использовать некоторые процедуры в nr.com . Проблема в том, что они запрограммированы на C ++ и используют функторы для передачи функции в метод интеграции. Как я могу сделать это в VB 2010?

Я хочу инициализировать функцию (т.е. установить a = 1, b = 0 для функции y (x) = a * x + b) и затем передать функцию методу интегрирования. Затем, когда метод интеграции вызывает функцию, он вызывает функцию только с одним параметром (то есть x, поскольку a, b уже установлены)

Каков наилучший способ сделать это в VB2010? Я хочу создать общий метод интеграции, в котором я могу передать любую однозначную функцию и пределы интеграции.

Я только начал использовать VB, и из того, что я нашел до сих пор, кажется, что инструменты, которые у вас есть, - нам делегат на функцию - использовать лямбда-выражение для функции - отправить указатель / адрес - создать класс / структуру функции и передать ее в функцию

На данный момент я наиболее склонен к созданию класса функций. Но я не совсем уверен, как. F.ex. Я делаю разные классы для каждой «уникальной функции», которую я хочу интегрировать, но как я могу передать их в функцию интеграции, когда мне нужно указать тип аргумента в вызове функции интеграции?

Это кажется основной проблемой, которая относится ко многим математическим операциям, поэтому я думаю, что было бы очень полезно прояснить это.

Ответы [ 2 ]

11 голосов
/ 30 апреля 2012

Извините за более длинные фрагменты кода, но я хотел продемонстрировать различные опции, доступные вам с лямбдами и анонимными функциями.

Сначала мы создадим несколько основных функций, с которыми можно играть ...

'Solves a basic linear equation y(x) = ax + b, given a, b, and x.
Function Linear(a As Double, b As Double, x As Double) As Double
    Return a * x + b
End Function

'Return the inverse of a number (i.e. y(x) = -x)
Function Inverse(x As Double) As Double
    Return -x
End Function

И функция, которая принимает функцию.

'To help differentiate the type of the parameter from the return type,
'I'm being generic with the return type. This function takes any function 
'that takes a double and returns some generic type, T.
Public Function EvalEquation(Of T)(x As Double, equation As Func(Of Double, T)) As T
    Return equation(x)
End Function

И, наконец, мы будем использовать ее!

'The closest thing to a functor is probably the AddressOf keyword.
For x = 0 To 10
    Dim answer = EvalEquation(x, AddressOf Inverse)
    'Do something
Next

Но у AddressOf есть некоторые ограничения ... EvalEquationForXожидает функцию, которая принимает только один параметр, поэтому я не могу просто использовать AddressOf, так как не могу передать дополнительные параметры.Однако я могу динамически создать функцию, которая может сделать это для меня.

For x = 0 To 10
  Dim answer = EvalEquation(x, Function(x)
                                   Dim a = 1
                                   Dim b = 0
                                   Return Linear(a, b, x)
                               End Function)
  'Do something
Next

Я должен отметить, что вы можете определить Func(Of T1, T2, T3, T4,... TResult), чтобы вы могли создать функцию, которая могла бы принимать два параметра и использовать этовместо этого.

Public Function EvalEquationWithTwoParameters(Of T)(
    a As Double, b As Double, x As Double,
    equation As Func(Of Double, Double, Double, T)) As T

    Return equation(a, b, x)
End Function

И используйте это так:

For x = 0 To 10
    Dim answer = EvalEquationWithTwoParameters(1, 0, x, AddressOf Linear)
    'Do something
Next

Надеюсь, это поможет!

4 голосов
/ 02 декабря 2011

Оформить delegates.

Вы должны определить делегата с подписью функции, которую вы хотите вызвать.Функция «которая принимает другую функцию» должна иметь параметр типа делегата, который вы определили.Затем вы можете создать экземпляр делегата, передав addressof фактическую функцию, и передать экземпляр делегата в функцию через параметр.

Быстрый и грязный пример.

Public Class Test
    Public Delegate Function MyDelegate(Param1 As Integer) As Integer

    Public Function DoSomethingWithParam1(Param1 As Integer) As Integer
        Return Param1 + 1
    End Function

    Public Sub ThisFunctionTakesADelegate(f As MyDelegate)
        Dim result As Integer = f.Invoke(2)
    End Sub

    Public Sub main()
        Dim f As New MyDelegate(AddressOf DoSomethingWithParam1)

        ThisFunctionTakesADelegate(f)'pass the function "DoSomethingWithParam1" as a parameter to "ThisFunctionTakesADelegate"
    End Sub

End Class

Вы также должны проверить Lambdas или Anonymous functions в качестве альтернативного способа определения вызова функции без использования выделенной именованной функции.

...