Phương pháp số có lẽ là tốt nhất cho bạn, nhưng nếu bạn quan tâm đến các phương pháp phân tích, nó rất đơn giản cho các dẫn xuất:
Hãy khai báo những gì một chức năng là (chúng ta giả sử chúng ta có chức năng với một tham số):
protocol Function {
func evaluate(value: Double) -> Double
func derivative() -> Function
}
Bây giờ chúng ta hãy tuyên bố chức năng cơ bản:
struct Constant : Function {
let constant: Double
func evaluate(value: Double) -> Double {
return constant
}
func derivative() -> Function {
return Constant(constant: 0)
}
}
struct Parameter : Function {
func evaluate(value: Double) -> Double {
return value
}
func derivative() -> Function {
return Constant(constant: 1)
}
}
struct Negate : Function {
let operand: Function
func evaluate(value: Double) -> Double {
return -operand.evaluate(value)
}
func derivative() -> Function {
return Negate(operand: operand.derivative())
}
}
struct Add : Function {
let operand1: Function
let operand2: Function
func evaluate(value: Double) -> Double {
return operand1.evaluate(value) + operand2.evaluate(value)
}
func derivative() -> Function {
return Add(operand1: operand1.derivative(), operand2: operand2.derivative())
}
}
struct Multiply : Function {
let operand1: Function
let operand2: Function
func evaluate(value: Double) -> Double {
return operand1.evaluate(value) * operand2.evaluate(value)
}
func derivative() -> Function {
// f'(x) * g(x) + f(x) * g'(x)
return Add(
operand1: Multiply(operand1: operand1.derivative(), operand2: operand2),
operand2: Multiply(operand1: operand1, operand2: operand2.derivative())
)
}
}
struct Divide : Function {
let operand1: Function
let operand2: Function
func evaluate(value: Double) -> Double {
return operand1.evaluate(value)/operand2.evaluate(value)
}
func derivative() -> Function {
// (f'(x) * g(x) - f(x) * g'(x))/(g(x))^2
return Divide(
operand1: Add(
operand1: Multiply(operand1: operand1.derivative(), operand2: operand2),
operand2: Negate(operand: Multiply(operand1: operand1, operand2: operand2.derivative()))
),
operand2: Power(operand1: operand2, operand2: Constant(constant: 2))
)
}
}
struct Exponential : Function {
let operand: Function
func evaluate(value: Double) -> Double {
return exp(operand.evaluate(value))
}
func derivative() -> Function {
return Multiply(
operand1: Exponential(operand: operand),
operand2: operand.derivative()
)
}
}
struct NaturalLogarithm : Function {
let operand: Function
func evaluate(value: Double) -> Double {
return log(operand.evaluate(value))
}
func derivative() -> Function {
return Multiply(
operand1: Divide(operand1: Constant(constant: 1), operand2: operand),
operand2: operand.derivative()
)
}
}
struct Power : Function {
let operand1: Function
let operand2: Function
func evaluate(value: Double) -> Double {
return pow(operand1.evaluate(value), operand2.evaluate(value))
}
func derivative() -> Function {
// x^y = e^ln (x^y) = e^(y * ln x)
let powerFn = Exponential(
operand: Multiply (
operand1: operand2,
operand2: NaturalLogarithm(operand: operand1)
)
)
return powerFn.derivative()
}
}
struct Sin: Function {
let operand: Function
func evaluate(value: Double) -> Double {
return sin(operand.evaluate(value))
}
func derivative() -> Function {
// cos(f(x)) * f'(x)
return Multiply(operand1: Cos(operand: operand), operand2: operand.derivative())
}
}
struct Cos: Function {
let operand: Function
func evaluate(value: Double) -> Double {
return cos(operand.evaluate(value))
}
func derivative() -> Function {
// - sin(f(x)) * f'(x)
return Multiply(operand1: Negate(operand: Sin(operand: operand)), operand2: operand.derivative())
}
}
Việc kê khai của một hàm không phải là rất tốt đẹp:
let xSquared = Power(operand1: Parameter(), operand2: Constant(constant: 2))
nhưng chúng ta có thể evaluate
với đệ quy:
print(xSquared.evaluate(15)) // f(15) = 225
print(xSquared.derivative().evaluate(15)) // f'(15) = 2 * 15 = 30
print(xSquared.derivative().derivative().evaluate(15)) // f''(15) = 2
print(xSquared.derivative().derivative().derivative().evaluate(15)) // f'''(15) = 0
Bước 1: Tìm một cách để đại diện cho chức năng gốc trong mã. Bước 2: Đảm bảo bạn biết tất cả các quy tắc tính toán cần thiết để lấy đạo hàm của * bất kỳ * chức năng nào. Bước 3: Nếu bạn nhận được bước 1 và bước 2 xuống và bạn vẫn còn bị mắc kẹt ... có lẽ sau đó bạn có thể trở lại Stack Overflow. – nhgrif
Bạn đã thử những gì? Ngoài ra, bạn có thực sự muốn tính đạo hàm thực sự hay chỉ đơn giản là xấp xỉ nó bằng cách sử dụng thuật toán giới hạn đó với một giá trị 'h' rất nhỏ? Cái thứ hai là tầm thường. Cái cũ là không tầm thường. – Rob
Lý tưởng nhất, đạo hàm thực tế sẽ được tính toán. Thuật toán giới hạn sẽ dễ dàng hơn nhiều. – modesitt