衍生函数在swift?

mod*_*itt 9 calculus ios swift

我想创建一个函数,在我的应用程序的某个部分返回函数的派生.我完全不知道如何做到这一点.显然这是限制的正式定义.但是什么样的函数能够在某一点返回函数的导数?

在此输入图像描述

我完全迷失了.我真的不在乎用户输入什么,因为我可以在某一点计算导数.有任何想法吗?

vac*_*ama 10

这是一个基于上述公式的简单数值方法.你可以改进这个:

derivativeOf取一个函数fn和一个x坐标,x并返回fnat 的导数的数值近似值x:

func derivativeOf(fn: (Double)->Double, atX x: Double) -> Double {
    let h = 0.0000001
    return (fn(x + h) - fn(x))/h
}

func x_squared(x: Double) -> Double {
    return x * x
}

// Ideal answer: derivative of x^2 is 2x, so at point 3 the answer is 6
let d1 = derivativeOf(fn: x_squared, atX: 3)  //  d1 = 6.000000087880153

// Ideal answer: derivative of sin is cos, so at point pi/2 the answer is 0
let d2 = derivativeOf(fn: sin, atX: .pi/2)  // d2 = -4.9960036108132044e-08
Run Code Online (Sandbox Code Playgroud)

如果您打算从用户那里获得功能,那就更难了.你可以给他们一些模板供你选择:

  1. 三阶多项式: y = Ax^3 + Bx^2 + Cx + D
  2. 罪的功能: y = A * sin(B*x + C)
  3. cos功能: y = A * cos(B*x + C)
  4. 第n根: y = x ^ (1/N)

然后你可以让他们给你A,B,C,D或N.

让我们看一下这对于三阶多项式是如何工作的:

// Take coefficients A, B, C, and D and return a function which
// computes f(x) = Ax^3 + Bx^2 + Cx + D
func makeThirdOrderPolynomial(A a: Double, B b: Double, C c: Double, D d: Double) -> ((Double) -> Double) {
    return { x in ((a * x + b) * x + c) * x + d }
}

// Get the coefficients from the user
let a = 5.0
let b = 3.0
let c = 1.0
let d = 23.0

// Use the cofficents to make the function
let f4 = makeThirdOrderPolynomial(A: a, B: b, C: c, D: d)

// Compute the derivative of f(x) = 5x^3 + 3x^2 + x + 23 at x = 5    
// Ideal answer: derivative is f'(x) = 15x^2 + 6x + 1, f'(5) = 406
let d4 = derivativeOf(fn: f4, atX: 5)  // d4 = 406.0000094341376
Run Code Online (Sandbox Code Playgroud)


Sul*_*han 6

数值方法可能是最适合您的,但如果您对分析方法感兴趣,那么对于衍生产品来说非常简单:

让我们声明一个函数是什么(我们假设我们有一个参数的函数):

protocol Function {
    func evaluate(value: Double) -> Double

    func derivative() -> Function
}
Run Code Online (Sandbox Code Playgroud)

现在让我们声明基本功能:

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())
    }
}
Run Code Online (Sandbox Code Playgroud)

函数的声明不是很好:

let xSquared = Power(operand1: Parameter(), operand2: Constant(constant: 2))
Run Code Online (Sandbox Code Playgroud)

但我们可以evaluate用递归:

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
Run Code Online (Sandbox Code Playgroud)


PyP*_*ePi 5

我同意Collin的观点,这是一个巨大的话题,而且可能没有完美的解决方案。但是,对于那些可以采用有效但不完善的解决方案的人,vacawama的答案非常简单。如果您想将派生函数与更多的数学语法一起使用,则可以定义一个运算符,幸运的是,Swift使此操作异常简单。这是我所做的:

我首先定义了一个运算符,仅用于返回派生函数的版本。我个人喜欢吗?衍生字符,但现有的Unicode字符中有很大一部分是有效的Swift标识符。

postfix operator ? {}

postfix func ?(f: Double -> Double) -> (Double -> Double) {
    let h = 0.00000000001
    func de(input: Double) -> Double {
        return (f(input + h) - f(input)) / h
    }
    return de
}
Run Code Online (Sandbox Code Playgroud)

接下来,让我们定义一个我们想要区分的函数:

func f(x: Double) -> Double {
    return x*x + 2*x + 3
}
Run Code Online (Sandbox Code Playgroud)

可以这样使用:f?,它将返回一个匿名函数,该函数将是f的派生类。如果希望在特定点获得f(例如,让x = 2),则可以这样称呼它:(f?)(2)

我决定喜欢这些运算符,因此又做了一个使该语法看起来更好的运算符:

infix operator ? { associativity left precedence 140 }
func ?(left: Double -> Double, right: Double) -> Double {
    return (f?)(right)
}
Run Code Online (Sandbox Code Playgroud)

f?2现在,该表达式将返回相同的结果,因为(f?)(2)它在进行数学运算时会更令人愉快。

很好的问题,每个人都很好的回答,我只是想我可以补充一些额外的内容。如果您有任何疑问,请告诉我!