Hi Jens —
BinaryFloatingPoint is very deliberately limited to the arithmetic operations
required by IEEE 754. This is the minimal set of operations that a binary
floating point type should provide, but it's already a really large
implementation burden for someone who wants to implement their own conforming
type.
I agree that there should eventually be either a refinement or orthogonal
protocol[s] with the semantics “type implements [a subset of] the standard math
functions”, but those shouldn’t get bolted onto
BinaryFloatingPoint—implementing these functions for an arbitrary
BinaryFloatingPoint type is highly non-trivial, and would make the
implementation burden for a new floating point type unreasonably high. This is
also out-of-scope for the current phase of Swift evolution.
In the short term for your immediate problem at hand, I’ve been doing something
like:
import Darwin
public protocol Math: BinaryFloatingPoint {
func _exp() -> Self
func _log() -> Self
func _sin() -> Self
func _cos() -> Self
}
extension Double: Math {
public func _exp() -> Double { return exp(self) }
public func _log() -> Double { return log(self) }
public func _sin() -> Double { return sin(self) }
public func _cos() -> Double { return cos(self) }
}
extension Float: Math {
public func _exp() -> Float { return exp(self) }
public func _log() -> Float { return log(self) }
public func _sin() -> Float { return sin(self) }
public func _cos() -> Float { return cos(self) }
}
func exp<T: Math>(_ x: T) -> T { return x._exp() }
func log<T: Math>(_ x: T) -> T { return x._log() }
func sin<T: Math>(_ x: T) -> T { return x._sin() }
func cos<T: Math>(_ x: T) -> T { return x._cos() }
extension Math {
func sigmoid() -> Self {
return 1.0 / (1.0 + exp(-self))
}
}
let x = 1.0
x.sigmoid()
Someone else might have a more clever solution.
– Steve
> On Jan 5, 2017, at 8:22 AM, Jens Persson via swift-users
> <[email protected]> wrote:
>
> The code below doesn't compile since there is no exponential function (exp)
> that works on all FloatingPoint or BinaryFloatingPoint types, also no
> protocol seems to define the power function or the constant e, although they
> do define for example: basic arithmetic operators, squareRoot() and pi.
>
> extension BinaryFloatingPoint {
> func sigmoid() -> Self {
> return 1.0 / (1.0 + exp(-self))
> }
> }
>
> I could, but don't want to write two free funcs sigmoid(Float) -> Float and
> sigmoid(Double) -> Double, because I need to use x.sigmoid() in several
> places where x is of a generic type (a BinaryFloatingPoint).
>
> More generally: I would have the same problem if I needed eg sin or cos. Are
> there any particular reason why, given a generic BinaryFloatingPoint, I
> cannot use sin or cos, while I can use pi and squareRoot()? It does seem a
> bit arbitrary.
>
> Any ideas on how to implement a sigmoid() that works for all
> BinaryFloatingPoint types?
>
> /Jens
> _______________________________________________
> swift-users mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________
swift-users mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-users