使用胡克定律逼近 F

Approximation of F using Hooke's Law

这道题在练习试卷上,我看不懂代码

Recall Hooke's law, that states that for a given spring, there is a constant k such that when the spring is in equilibrium F = kx where F is the force pulling at the free end, and x is the displacement of the end from its original position.

Assume that you want to estimate the constant k for a given spring, and that you have two Python lists, forces and displacements where the ith entries correspond to each other. Write a Python program that:

  1. Plots the force on the y-axis and the displacement on the x-axis.

  2. Calculates a linear approximation of F as a function of x and plots the approximation.

到目前为止我有:

import pylab
pylab.plot(displacements, forces, "bo")
pylab.xlabel("Displacement")
pylab.ylabel("Force")
pylab.show()

第一部分我认为是正确的。

对于第二部分,我有:

avgF = sum(forces)/len(forces)
avgX = sum(displacements)/len(displacements)
K = avgF/avgX
pylab.plot(displacements,K*displacements)

我真的不确定,我无法检查这些值,因为我没有列表来尝试代码。

是的,我认为你的代码很好。您总是可以生成一些随机样本数据并对其进行测试:

import matplotlib.pyplot as plt
import numpy as np

# Generate random sample data
N = 20
k_theoretical = 3
displacement = np.arange(N)
force = k_theoretical * displacement + np.random.normal(size=N)

# Calculate constant for Hooke's law
avgF = sum(force) / len(force)
avgX = sum(displacement) / len(displacement)
k_calculated = avgF / avgX

# Plot data points and line
plt.plot(displacement, force, "bx")
plt.plot(displacement, k_calculated * displacement, "r-",
    label="k = {:.2f}".format(k_calculated))
plt.xlabel("Displacement")
plt.ylabel("Force")
plt.legend()
plt.show()

顺便说一下,如果您对数据使用 NumPy 数组,则可以使用

计算平均值
avgF = force.mean()
avgX = displacement.mean()

最小二乘拟合

您有 N 个读数,fₙdₙ n = 1, …, N,力和位移,你没有 k,spring 常数......理想关系是 k dₙ = fₙ 但我们知道,由于测量的不确定性,理想关系永远不会得到准确验证,我们有一个错误,eₙ = k dₙ - fₙ 。我们能做的最好的事情就是尽量减少一些误差...

在提到另一个流行的选择是最小化误差绝对值的最大值之后,让我们看看当我们尝试最小化误差平方和时会发生什么(或者,从另一个角度来看, N维space中误差向量的长度:

    S = sum((k dₙ - fₙ)²) = sum(k²dₙ² - 2 k dₙ fₙ + fₙ²) =
      = k² sum(dₙ²) - 2 k sum(dₙ fₙ) + sum(fₙ²).

在这个表达式中,唯一的变量是 k,所以为了找到最小值,我们只需要将 S 的导数归零即可到 k。使用一点代数

    S' = 2 k sum(dₙ²) - 2 sum(dₙ fₙ) =0 ⇒ k = sum(dₙ fₙ)/sum(dₙ²)

(请记住,k 不是 spring 常数,而是 我们对 spring 的最佳估计常数)。

在Python

f, d = [...], [...]
...
k = sum(dn*fn for dn,fn in zip(d,f) / sum(dn**2 for dn in d)