数学分析基础可视化

极限定义中N的不唯一性

围绕极限定义中N的不唯一性,观察epsilon-N 定义、数列极限、证明中的 N 不唯一之间的关系与推理路径。

打开原视频

n_uniqueness_demo.py
1from manim import *2import numpy as np3 4class NUniquenessDemo(Scene):5    def construct(self):6        # Set default font7        Text.set_default(font="SimSun")8        9        # Title10        title = Text("极限定义中N的不唯一性", font="SimSun").scale(0.5)  # 缩小标题11        title.to_edge(UP, buff=0.3)12        self.play(Write(title))13        self.wait(1)14        15        # Problem statement16        problem = MathTex(r"\lim_{n \to \infty} \frac{3n^2}{n^2 - 3} = 3").scale(0.8)  # 缩小题目17        problem.next_to(title, DOWN, buff=0.3)  # 上移一点18        19        self.play(Write(problem))20        self.wait(2)21        22        # Create axes for visualization23        axes = Axes(24            x_range=[0, 30, 5],25            y_range=[2, 4, 0.5],26            axis_config={"include_tip": True},27            x_length=8,  # 缩小图像28            y_length=4   # 缩小图像29        )30        axes.next_to(problem, DOWN, buff=0.3).shift(RIGHT * 1.5)  # 上移一点并右移一些31        32        # Labels for axes33        x_label = MathTex("n").next_to(axes.x_axis, RIGHT, buff=0.3)34        y_label = MathTex("f(n)").next_to(axes.y_axis, UP, buff=0.3)35        36        self.play(Create(axes), Write(x_label), Write(y_label))37        self.wait(1)38        39        # Function to plot40        def func(x):41            return 3 * x**2 / (x**2 - 3)42        43        # Plot points on the graph44        points = VGroup()45        x_values = range(2, 31)  # 正整数n从2到3046        for x in x_values:47            y = func(x)48            point = Dot(axes.c2p(x, y), color=BLUE, radius=0.05)49            points.add(point)50        51        graph_label = MathTex(r"f(n) = \frac{3n^2}{n^2 - 3}").next_to(axes.c2p(25, func(25)), UP, buff=0.2).scale(0.7).shift(LEFT * 1.5)  # 左移一些52        graph_label.set_color(BLUE)53        54        # Plot the limit line y = 355        limit_line = axes.plot(lambda x: 3, x_range=[0, 30], color=GREEN)56        limit_label = MathTex("y = 3").next_to(limit_line.get_end(), DOWN, buff=0.2).scale(0.7)57        limit_label.set_color(GREEN)58        59        self.play(Create(points), Write(graph_label))60        self.play(Create(limit_line), Write(limit_label))61        self.wait(2)62        63        # Show epsilon band64        epsilon = 0.265        upper_epsilon_line = axes.plot(lambda x: 3 + epsilon, x_range=[0, 30], color=RED)66        lower_epsilon_line = axes.plot(lambda x: 3 - epsilon, x_range=[0, 30], color=RED)67        68        upper_epsilon_label = MathTex(f"y = 3 + \\varepsilon = {3 + epsilon}").next_to(upper_epsilon_line.get_end(), UP, buff=0.1).scale(0.6)69        upper_epsilon_label.set_color(RED)70        lower_epsilon_label = MathTex(f"y = 3 - \\varepsilon = {3 - epsilon}").next_to(lower_epsilon_line.get_end(), DOWN, buff=0.1).scale(0.6)71        lower_epsilon_label.set_color(RED)72        73        # 显示epsilon值右移一个单位74        epsilon_label = MathTex(f"\\varepsilon = {epsilon}").next_to(axes, DOWN, buff=0.1).shift(UP*1.5 + LEFT*3)75        epsilon_label.set_color(RED)76        77        self.play(Create(upper_epsilon_line), Create(lower_epsilon_line))78        self.play(Write(upper_epsilon_label), Write(lower_epsilon_label), Write(epsilon_label))79        self.wait(2)80        81        # Calculate different N values 82        # Method 1: Standard calculation (N = ceil(sqrt(9/ε + 3)))83        N1_float = np.sqrt(9/epsilon + 3)84        N1 = int(np.ceil(N1_float))85        86        # Method 2: More conservative estimation87        N2_float = np.sqrt(18/epsilon)88        N2 = int(np.ceil(N2_float))89        # But we also need n ≥ 4 for our approximation, so take max(4, N2)90        N2 = max(4, N2)91        92        # Method 3: Even more conservative estimation93        N3_float = np.sqrt(13.5/epsilon)94        N3 = int(np.ceil(N3_float))95        # But we also need n ≥ 3 for our approximation, so take max(3, N3)96        N3 = max(3, N3)97        98        # Display derivation methods title99        derivation_title = Text("不同的N推导方法:", font="SimSun").scale(0.5)100        derivation_title.to_corner(UL, buff=0.5).shift(RIGHT*0.1)  # 整体左移0.4个单位(从0.5到0.1)101        102        self.play(Write(derivation_title))103        self.wait(1)104        105        # Method 1106        method1_title = Text("方法1: 基本方法", font="SimSun").scale(0.4)107        method1_derivation = MathTex(108            r"|f(n)-3| = \left|\frac{9}{n^2-3}\right| < \varepsilon \Rightarrow n > \sqrt{\frac{9}{\varepsilon}+3}"109        ).scale(0.5)110        method1_result = MathTex("N_1 = \\left\\lceil \\sqrt{\\frac{9}{\\varepsilon}+3} \\right\\rceil = ").scale(0.6)111        112        method1_group = VGroup(method1_title, method1_derivation, method1_result).arrange(DOWN, aligned_edge=LEFT, buff=0.2)113        method1_group.next_to(derivation_title, DOWN, buff=0.3).scale(0.8).shift(RIGHT*0.1)  # 整体左移0.4个单位114        115        self.play(Write(method1_title))116        self.play(Write(method1_derivation))117        self.wait(2)118        119        # Show N1 result120        method1_result_N = MathTex(str(N1)).scale(0.6).next_to(method1_result, RIGHT, buff=0.1)121        122        self.play(Write(method1_result))123        self.wait(1)124        self.play(Write(method1_result_N))  # N1结果晚1秒显示125        self.wait(1)126        127        # Show N1 on graph128        n1_line = axes.get_vertical_line(129            axes.c2p(N1, 0),130            line_config={"color": YELLOW, "stroke_width": 4}131        )132        133        n1_label = MathTex(f"N_1 = {N1}").next_to(n1_line, UP, buff=0.1).scale(0.6)134        n1_label.set_color(YELLOW)135        136        # Create a dotted vertical line spanning the entire y-range137        n1_dotted_line = DashedLine(138            start=axes.c2p(N1, axes.get_y_range()[0]),139            end=axes.c2p(N1, axes.get_y_range()[1]),140            color=YELLOW,141            stroke_width=2,142            dash_length=0.1143        )144        145        self.play(Create(n1_dotted_line), run_time=0.5)146        self.play(Create(n1_line), Write(n1_label), run_time=0.5)147        self.wait(1)148        149        # Highlight points for N1150        highlight_points1 = VGroup()151        for x in x_values:152            if x > N1:153                y = func(x)154                point = Dot(axes.c2p(x, y), color=YELLOW, radius=0.07)155                highlight_points1.add(point)156        157        self.play(Create(highlight_points1), run_time=1.5)158        self.wait(2)159        160        # Method 2: Different estimation technique161        method2_title = Text("方法2: 不同放大技巧(n>3时)", font="SimSun").scale(0.4)162        method2_derivation = MathTex(163            r"n^2-3 \geq \frac{n^2}{2} \Rightarrow |f(n)-3| \leq \frac{18}{n^2} < \varepsilon \Rightarrow n > \sqrt{\frac{18}{\varepsilon}}"164        ).scale(0.5)165        166        method2_group = VGroup(method2_title, method2_derivation).arrange(DOWN, aligned_edge=LEFT, buff=0.2)167        method2_group.next_to(method1_group, DOWN, buff=0.3).scale(0.8).shift(RIGHT*0.2)  # 整体右移0.1个单位(从0.1到0.2)168        169        self.play(Write(method2_title))170        self.play(Write(method2_derivation))171        self.wait(2)172        173        # Show N2 result174        method2_result = MathTex("N_2 = \\max(3, \\left\\lceil \\sqrt{\\frac{18}{\\varepsilon}} \\right\\rceil) = ").scale(0.6)175        method2_result_N = MathTex(str(N2)).scale(0.6).next_to(method2_result, RIGHT, buff=0.1)176        method2_result.next_to(method2_group, DOWN, buff=0.2).shift(RIGHT*0.2)  # 整体右移0.1个单位177        method2_result_N.next_to(method2_result, RIGHT, buff=0.1)178        179        self.play(Write(method2_result))180        self.wait(1)181        self.play(Write(method2_result_N))  # N2结果晚1秒显示182        self.wait(0.5)183        184        # Show N2 on graph185        n2_line = axes.get_vertical_line(186            axes.c2p(N2, 0),187            line_config={"color": ORANGE, "stroke_width": 4}188        )189        190        n2_label = MathTex(f"N_2 = {N2}").next_to(n2_line, UP, buff=0.1).scale(0.6).shift(DOWN*0.3)  # N2标签下移191        n2_label.set_color(ORANGE)192        193        # Create a dotted vertical line spanning the entire y-range194        n2_dotted_line = DashedLine(195            start=axes.c2p(N2, axes.get_y_range()[0]),196            end=axes.c2p(N2, axes.get_y_range()[1]),197            color=ORANGE,198            stroke_width=2,199            dash_length=0.1200        )201        202        self.play(Create(n2_dotted_line), run_time=0.5)203        self.play(Create(n2_line), Write(n2_label), run_time=0.5)204        self.wait(0.5)205        206        # Highlight points for N2207        highlight_points2 = VGroup()208        for x in x_values:209            if x > N2:210                y = func(x)211                point = Dot(axes.c2p(x, y), color=ORANGE, radius=0.07)212                highlight_points2.add(point)213        214        self.play(Create(highlight_points2), run_time=1.5)215        self.wait(2)216        217        # Method 3: Another estimation technique218        method3_title = Text("方法3: 另一种放大技巧(n>3时)", font="SimSun").scale(0.4)219        method3_derivation = MathTex(220            r"n^2-3 \geq \frac{2n^2}{3} \Rightarrow |f(n)-3| \leq \frac{13.5}{n^2} < \varepsilon \Rightarrow n > \sqrt{\frac{13.5}{\varepsilon}}"221        ).scale(0.5)222        223        method3_group = VGroup(method3_title, method3_derivation).arrange(DOWN, aligned_edge=LEFT, buff=0.2)224        method3_group.next_to(method2_result, DOWN, buff=0.3).scale(0.8).shift(RIGHT*0.2)  # 整体右移0.1个单位(从0.1到0.2)225        226        self.play(Write(method3_title))227        self.play(Write(method3_derivation))228        self.wait(2)229        230        # Show N3 result231        method3_result = MathTex("N_3 = \\max(3, \\left\\lceil \\sqrt{\\frac{13.5}{\\varepsilon}} \\right\\rceil) = ").scale(0.6)232        method3_result_N = MathTex(str(N3)).scale(0.6).next_to(method3_result, RIGHT, buff=0.1)233        method3_result.next_to(method3_group, DOWN, buff=0.2).shift(RIGHT*0.2)  # 整体右移0.1个单位234        method3_result_N.next_to(method3_result, RIGHT, buff=0.1)235        236        self.play(Write(method3_result))237        self.wait(1)238        self.play(Write(method3_result_N))  # N3结果晚1秒显示239        self.wait(0.5)240        241        # Show N3 on graph242        n3_line = axes.get_vertical_line(243            axes.c2p(N3, 0),244            line_config={"color": PURPLE, "stroke_width": 4}245        )246        247        n3_label = MathTex(f"N_3 = {N3}").next_to(n3_line, UP, buff=0.1).scale(0.6).shift(DOWN*0.5)  # N3标签进一步下移248        249        n3_label.set_color(PURPLE)250        251        # Create a dotted vertical line spanning the entire y-range252        n3_dotted_line = DashedLine(253            start=axes.c2p(N3, axes.get_y_range()[0]),254            end=axes.c2p(N3, axes.get_y_range()[1]),255            color=PURPLE,256            stroke_width=2,257            dash_length=0.1258        )259        260        self.play(Create(n3_dotted_line), run_time=0.5)261        self.play(Create(n3_line), Write(n3_label), run_time=0.5)262        self.wait(1)263        264        # Highlight points for N3265        highlight_points3 = VGroup()266        for x in x_values:267            if x > N3:268                y = func(x)269                point = Dot(axes.c2p(x, y), color=PURPLE, radius=0.07)270                highlight_points3.add(point)271        272        self.play(Create(highlight_points3), run_time=1.5)273        self.wait(2)274        275        # Conclusion text at the bottom center276        conclusion = Text(277            "通过不同的不等式放大技巧,可以得到不同的N值",278            font="SimSun"279        ).scale(0.6).to_edge(DOWN, buff=0.5).shift(RIGHT*2)  # 结论右移两个单位280        281        self.play(Write(conclusion))282        self.wait(3)283 284def main():285    scene = NUniquenessDemo()286    scene.render()287 288if __name__ == "__main__":289    main()

讲解

这个视频围绕「极限定义中N的不唯一性」展开。画面把问题、图像和公式放在同一条理解路径中,让抽象关系先被看见。

开头先建立问题背景和主要对象,让观察从标题、坐标或第一组关系进入。

画面中出现的文字「极限定义中N的不唯一性」给出视觉入口。随后画面通过对象创建、移动、淡入淡出和高亮,把抽象命题拆成可以跟随的步骤。

随后出现更具体的图像或公式提示,动画会把局部对象和整体结论联系起来。这里可以重点观察变量、曲线、区域或向量如何随镜头推进而变化。

核心公式可以写成:

limn3n2n23=3\lim_{n \to \infty} \frac{3n^2}{n^2 - 3} = 3

这类公式可以和画面中的符号一一对应。

观察路径

观察路径可以分三步:先锁定「极限定义中N的不唯一性」中的核心对象,尤其留意epsilon-N 定义、数列极限、证明中的 N 不唯一之间的联系;再跟随画面中变量、图像或向量的变化;最后回到公式或结论,判断局部变化如何支撑整体关系。

本页可以从epsilon-N 定义、数列极限、证明中的 N 不唯一这些概念进入,继续沿相邻问题观察同一类数学结构。