跳转到内容

编程科学/Auld Lang Sine

来自维基教科书,开放世界中的开放书籍

你很可能之前已经接触过正弦和余弦。正弦曲线(包括正弦和余弦)是周期函数。周期函数具有以下性质

   
   

对于所有xp 的某些值。满足上述等式的p 的最小值被称为该函数的周期

如果你不熟悉正弦和余弦函数,这就是正弦波的样子

请注意,对于没有相位和频率偏移的正弦波(如上所示),当x 为零时,正弦波的振幅(y 值)为零(具有上升斜率)。该波在x = 2 再次达到零(具有上升斜率)π. 对比余弦波

与正弦波不同,正弦波在p 的倍数处具有零交叉点π,余弦波在p 的倍数处具有峰值和谷值π. 与正弦波一样,周期或峰值到峰值长度为 2π.

一般正弦波

[编辑 | 编辑源代码]

如果你仔细观察这两个波,你会发现余弦只是正弦波向左移动了 个单位。因此,我们可以用正弦来定义余弦

   

请注意,数学家通常将正弦缩写为sin,将余弦缩写为cos。以上说明了修改正弦波的常见方法之一:移动波的相位,通常使用符号

   

另一种修改是改变正弦波的振幅,或者换句话说,改变峰值的高低范围。变量a 用于表示振幅,因此允许振幅修改的正弦波公式为

   

最后,通常会改变正弦波的频率,或者在给定区域内有多少个峰值(或谷值)。变量通常用于此任务

   

如果我们将 设置为 2,我们将获得给定区域内两倍的峰值(或谷值)。频率的倒数是周期,因此将 设置为 2 将使峰值到峰值距离缩短一半。在频率为 2 的特定情况下,正弦波的周期将为π.

这里有一个巧妙的技巧。如果你想找到这种形式的一般符号波的“第一个”零交叉点的位置,请更改相移和将它与x 相结合的运算符的符号,然后将 提取出来。对于余弦,具有单位振幅和频率加倍,我们有

   
    
   
    
   
    
   

此版本的余弦在 处具有第一个零交叉点。[1] 换句话说,要找到第一个零交叉点,请将相移除以频率并取反(假设相移被添加进去)。

实现一般正弦波

[编辑 | 编辑源代码]

Sway 内置了sincos 函数,但这些函数假设振幅 = 1,频率 = 1 且相移 = 0。[2] 为了实现sinecosine,我们将采用我们通常的对象方法

   function sine(amp,freq,shift)
       {
       function value(x)
           {
           amp * sin(freq * x + shift);
           }
       this;
       }
    
   function cosine(amp,freq,shift)
       {
       sine(amp,freq,shift + (pi() / 2));
       }

请注意,我们如何将余弦包装为正弦,因为余弦只是具有相移的正弦。

让我们利用我们在上一节中学习的关于查找“第一个”零交叉点的技巧,并将其实现

   function sine(amp,freq,shift)
       {
       function value(x) { ... }
       function firstZero()
           {
           // phase shift is added in so just divide and negate
           -(real(shift) / freq);
           }
       this;
       }

让我们看看它是否适用于频率为 2 的余弦

   var w = cose(1,2,0);
    
   sway> -(pi() / 4);
   REAL_NUMBER: -0.7853981634
   
   sway> w . firstZero();
   REAL_NUMBER: -0.7853981634

不错。让我们也检查一下正弦波的值在该点确实为零

   sway> var fz = w . firstZero();
   REAL_NUMBER: -0.7853981634
    
   sway> w . value(fz);
   w . value(fz) is 0.000000e+00

bingo!

正弦和余弦的微分

[编辑 | 编辑源代码]

正如 SPT 在 CMT 的第 XV 章中指出的那样,正弦的导数是余弦,余弦的导数是正弦的负数。

使用第一个规则,我们可以将diff 函数添加到sine 构造函数中。当然,为了符合我们谦逊的微分系统,我们需要根据需要传入自变量和关于变量

   function sine(amp,freq,shift)
       {
       function value(x) { ... }
       function firstZero() { ... }
       function diff()
           {
           cosine(amp,freq,shift);
           }
       this;
       }

当然,此实现假定自变量和关于变量是一样的。它还假定自变量只是一个符号。因此,我们无法构造形式为;

   

为此,我们将不得不像处理项一样,允许自变量成为可微分对象。回想一下项构造函数

   function term(a,iv,n)
       {
       function value(x) { ... }
       function toString() { ... }
       function diff(wrtv)
           {
           if (n == 0)
               {
               constant(0);
               }
           else
               {
               term(a * n,iv,n - 1) times iv . diff(wrtv);
               }
           }
       
       if (iv is :SYMBOL) { iv = variable(iv); }
       this;
       }

还记得diff 函数如何实现链式法则。我们将需要对sine 构造函数采用相同的策略

   function sine(amp,freq,iv,shift)
       {
       function value(x) { ... }
       function firstZero() { ... }
       function diff(wrtv)
           {
           cosine(amp,freq,iv,shift) times iv . diff(wrtv);
           }
        
       if (iv is :SYMBOL,iv = variable(iv));
       this;
       }

我们剩下要做的就是实现sine 的可视化(当然还有测试)

   function toString()
       {
       "" + amp +
           " sin(" + freq +
               "(" + iv . toString() + ")"
               + shift + ")";
       }

-sin 是什么?

[编辑 | 编辑源代码]

根据 CMT,正弦函数的导数是余弦函数,余弦函数的导数是负正弦函数。因此,正弦函数的二阶导数是负正弦函数。

1. 函数 和函数 之间有什么区别?

2. 为什么我们不能将 正弦余弦 构造函数命名为 sincos

3.正弦 构造函数中添加以下简化。如果相移等于或大于 2π,减去 2π.

4. 解释为什么之前的简化在数学上是有效的。

5. 简化正弦对象的构造,以便如果幅度为零,则生成零对象。

6. 简化正弦对象的构造,以便如果频率为零,则生成常数项对象。

7. 简化正弦对象的可视化,以便如果幅度、频率和相移分别为 1、1 和 0,则省略它们。

8. 查找并添加其他可视化调整。提示:如果频率 ≠ 1 但自变量是系数 ≠ 1 的项,你的可视化应该是什么样子?

  1. 将此与具有单位幅度和频率的余弦波(在本章开头显示)进行对比,该余弦波在 处有一个过零点。
  2. 还存在一个广义余弦函数:。当然,这等于


富人越来越富 · 尽你所能

华夏公益教科书