Swift AutoDiff: Как сделать так, чтобы структура имела переменную-член, которая является дифференцируемой функцией более чем одного параметра?

#swift #swift5 #autodiff

Вопрос:

Я хотел бы иметь следующее:

 import _Differentiation

struct S {
    var f: @differentiable(reverse) (Double, Double) -> Double
}
 

но компилятор жалуется Error: Abort trap: 6 , и начало трассировки стека

 Assertion failed: (isa<X>(Val) amp;amp; "cast<Ty>() argument of incompatible type!"), function cast, file Casting.h, line 269.
 

Если переменная-член является функцией одного параметра, программа строит:

 import _Differentiation

struct S {
    var f: @differentiable(reverse) (Double) -> Double
}
 

но два или более параметров не допускаются.

Мы можем написать функцию, которая имеет дифференцируемую функцию двух параметров в качестве параметра:

 import _Differentiation

func g(f: @differentiable(reverse) (Double, Double) -> Double) {
    // function body
}
 

Если функция может иметь параметр такого типа, почему структура не может иметь переменную-член этого типа?

Ответ №1:

Это может быть достигнуто путем создания структуры и/или функции переменной-члена fileprivate или private управления доступом:

 import _Differentiation

struct S {
    fileprivate var f: @differentiable(reverse) (Double, Double, Double) -> Double
}
 

или

 import _Differentiation

fileprivate struct S {
    public var f: @differentiable(reverse) (Double, Double, Double) -> Double
}
 

Обратите внимание, что во втором примере это f может быть public , потому S что ограничено по крайней мере fileprivate .

Обходной путь состоит в том, чтобы сделать f функцию другой дифференцируемой структуры данных, например:

 import _Differentiation

struct S {
    struct Tuple: Differentiable {
        var x: Double
        var y: Double
        @differentiable(reverse)
        init(x: Double, y: Double) {
            self.x = x
            self.y = y
        }
    }
    var f: @differentiable(reverse) (Tuple) -> Double
}