mirror of
https://github.com/3b1b/manim.git
synced 2025-08-03 04:04:36 +08:00
75% of Chapter 6
This commit is contained in:
343
eola/chapter6.py
343
eola/chapter6.py
@ -234,6 +234,24 @@ class MachineLearningNetwork(Scene):
|
||||
self.play(Write(mob), run_time = 2)
|
||||
self.dither()
|
||||
|
||||
class ComplicatedSystem(Scene):
|
||||
def construct(self):
|
||||
system = TexMobject("""
|
||||
\\begin{align*}
|
||||
\\dfrac{1}{1-e^{2x-3y+4z}} &= 1 \\\\ \\\\
|
||||
\\sin(xy) + z^2 &= \\sqrt{y} \\\\ \\\\
|
||||
x^2 + y^2 &= e^{-z}
|
||||
\\end{align*}
|
||||
""")
|
||||
system.to_edge(UP)
|
||||
randy = Randolph().to_corner(DOWN+LEFT)
|
||||
|
||||
self.add(randy)
|
||||
self.play(Write(system, run_time = 1))
|
||||
self.play(randy.change_mode, "sassy")
|
||||
self.play(Blink(randy))
|
||||
self.dither()
|
||||
|
||||
class SystemOfEquations(Scene):
|
||||
def construct(self):
|
||||
equations = self.get_equations()
|
||||
@ -671,7 +689,6 @@ class LabeledExample(LinearSystemTransformationScene):
|
||||
self.title = title
|
||||
|
||||
def construct(self):
|
||||
self.setup()
|
||||
self.dither()
|
||||
self.apply_transposed_matrix(self.t_matrix)
|
||||
self.dither()
|
||||
@ -714,26 +731,42 @@ class PlayInReverse(FullRankExmapleDet):
|
||||
|
||||
class DescribeInverse(LinearTransformationScene):
|
||||
CONFIG = {
|
||||
"show_matrix" : False
|
||||
"show_actual_inverse" : False,
|
||||
"matrix_label" : "$A$",
|
||||
"inv_label" : "$A^{-1}$",
|
||||
}
|
||||
def construct(self):
|
||||
self.setup()
|
||||
title = TextMobject("Transformation:")
|
||||
new_title = TextMobject("Inverse transformation:")
|
||||
if self.show_matrix:
|
||||
matrix = Matrix(self.t_matrix.T)
|
||||
inv_matrix = Matrix(np.linalg.inv(self.t_matrix.T).astype('int'))
|
||||
matrix = Matrix(self.t_matrix.T)
|
||||
if not self.show_actual_inverse:
|
||||
inv_matrix = matrix.copy()
|
||||
neg_1 = TexMobject("-1")
|
||||
neg_1.move_to(
|
||||
inv_matrix.get_corner(UP+RIGHT),
|
||||
side_to_align = LEFT
|
||||
)
|
||||
neg_1.shift(0.1*RIGHT)
|
||||
inv_matrix.add(neg_1)
|
||||
matrix.add(VectorizedPoint(matrix.get_corner(UP+RIGHT)))
|
||||
else:
|
||||
matrix, inv_matrix = map(TexMobject, ["A", "A^{-1}"])
|
||||
inv_matrix = Matrix(np.linalg.inv(self.t_matrix.T).astype('int'))
|
||||
matrix.label = self.matrix_label
|
||||
inv_matrix.label = self.inv_label
|
||||
for m, text in (matrix, title), (inv_matrix, new_title):
|
||||
m.rect = BackgroundRectangle(m)
|
||||
m = VMobject(m.rect, m)
|
||||
m.add_to_back(BackgroundRectangle(m))
|
||||
text.add_background_rectangle()
|
||||
m.next_to(text, RIGHT)
|
||||
brace = Brace(m)
|
||||
label_mob = brace.get_text(m.label)
|
||||
label_mob.add_background_rectangle()
|
||||
m.add(brace, label_mob)
|
||||
text.add(m)
|
||||
if text.get_width() > 2*SPACE_WIDTH-1:
|
||||
text.scale_to_fit_width(2*SPACE_WIDTH-1)
|
||||
text.center().to_edge(UP)
|
||||
text.center().to_corner(UP+RIGHT)
|
||||
matrix.highlight(PINK)
|
||||
inv_matrix.highlight(YELLOW)
|
||||
|
||||
self.add_foreground_mobject(title)
|
||||
self.apply_transposed_matrix(self.t_matrix)
|
||||
@ -745,13 +778,17 @@ class DescribeInverse(LinearTransformationScene):
|
||||
class ClockwiseCounterclockwise(DescribeInverse):
|
||||
CONFIG = {
|
||||
"t_matrix" : [[0, 1], [-1, 0]],
|
||||
"show_matrix" : True,
|
||||
"show_actual_inverse" : True,
|
||||
"matrix_label" : "$90^\\circ$ Couterclockwise",
|
||||
"inv_label" : "$90^\\circ$ Clockwise",
|
||||
}
|
||||
|
||||
class ShearInverseShear(DescribeInverse):
|
||||
CONFIG = {
|
||||
"t_matrix" : [[1, 0], [1, 1]],
|
||||
"show_matrix" : True,
|
||||
"show_actual_inverse" : True,
|
||||
"matrix_label" : "Rightward shear",
|
||||
"inv_label" : "Leftward shear",
|
||||
}
|
||||
|
||||
class MultiplyToIdentity(LinearTransformationScene):
|
||||
@ -810,18 +847,276 @@ class MultiplyToIdentity(LinearTransformationScene):
|
||||
self.play(Write(col2))
|
||||
self.dither()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TwoDInverseFormula(Scene):
|
||||
def construct(self):
|
||||
title = TextMobject("If you're curious...")
|
||||
title.highlight(YELLOW)
|
||||
title.to_edge(UP)
|
||||
morty = Mortimer().to_corner(DOWN+RIGHT)
|
||||
self.add(title, morty)
|
||||
matrix = [["a", "b"], ["c", "d"]]
|
||||
scaled_inv = [["d", "-b"], ["-c", "a"]]
|
||||
formula = TexMobject("""
|
||||
%s^{-1} = \\dfrac{1}{ad-bc} %s
|
||||
"""%(
|
||||
matrix_to_tex_string(matrix),
|
||||
matrix_to_tex_string(scaled_inv)
|
||||
))
|
||||
self.play(Write(formula))
|
||||
self.play(morty.change_mode, "confused")
|
||||
self.play(Blink(morty))
|
||||
|
||||
class SymbolicInversion(Scene):
|
||||
def construct(self):
|
||||
vec = lambda s : "\\vec{\\textbf{%s}}"%s
|
||||
|
||||
words = TextMobject("Once you have this:")
|
||||
words.to_edge(UP, buff = 2)
|
||||
inv = TexMobject("A^{-1}")
|
||||
inv.highlight(GREEN)
|
||||
inv.next_to(words.split()[-1], RIGHT, aligned_edge = DOWN)
|
||||
inv2 = inv.copy()
|
||||
|
||||
start = TexMobject("A", vec("x"), "=", vec("v"))
|
||||
interim = TexMobject("A^{-1}", "A", vec("x"), "=", "A^{-1}", vec("v"))
|
||||
end = TexMobject(vec("x"), "=", "A^{-1}", vec("v"))
|
||||
|
||||
A, x, eq, v = start.split()
|
||||
x.highlight(PINK)
|
||||
v.highlight(YELLOW)
|
||||
interim_mobs = [inv, A, x, eq, inv2, v]
|
||||
for i, mob in enumerate(interim_mobs):
|
||||
mob.interim = mob.copy().move_to(interim.split()[i])
|
||||
|
||||
self.add(start)
|
||||
self.play(Write(words), FadeIn(inv), run_time = 1)
|
||||
self.dither()
|
||||
self.play(
|
||||
FadeOut(words),
|
||||
*[Transform(m, m.interim) for m in interim_mobs]
|
||||
)
|
||||
self.dither()
|
||||
|
||||
product = VMobject(A, inv)
|
||||
product.brace = Brace(product)
|
||||
product.words = product.brace.get_text(
|
||||
"The ``do nothing'' matrix"
|
||||
)
|
||||
product.words.highlight(BLUE)
|
||||
self.play(
|
||||
GrowFromCenter(product.brace),
|
||||
Write(product.words, run_time = 1),
|
||||
product.highlight, BLUE
|
||||
)
|
||||
self.dither()
|
||||
self.play(*[
|
||||
ApplyMethod(m.highlight, BLACK)
|
||||
for m in product, product.brace, product.words
|
||||
])
|
||||
self.dither()
|
||||
self.play(ApplyFunction(
|
||||
lambda m : m.center().to_edge(UP),
|
||||
VMobject(x, eq, inv2, v)
|
||||
))
|
||||
self.dither()
|
||||
|
||||
class PlayInReverseWithSolution(PlayInReverse):
|
||||
def setup(self):
|
||||
LinearTransformationScene.setup(self)
|
||||
equation = TexMobject([
|
||||
"\\vec{\\textbf{x}}",
|
||||
"=",
|
||||
"A^{-1}",
|
||||
"\\vec{\\textbf{v}}",
|
||||
])
|
||||
equation.to_edge(UP)
|
||||
equation.add_background_rectangle()
|
||||
self.add_foreground_mobject(equation)
|
||||
self.equation = equation
|
||||
self.x, eq, self.inv, self.v = equation.split()[1].split()
|
||||
self.x.highlight(PINK)
|
||||
self.v.highlight(YELLOW)
|
||||
self.inv.highlight(GREEN)
|
||||
|
||||
class OneUniqueSolution(Scene):
|
||||
def construct(self):
|
||||
system = TexMobject("""
|
||||
\\begin{align*}
|
||||
ax + cy &= e \\\\
|
||||
bx + dy &= f
|
||||
\\end{align*}
|
||||
""")
|
||||
VMobject(*np.array(system.split())[[1, 8]]).highlight(X_COLOR)
|
||||
VMobject(*np.array(system.split())[[4, 11]]).highlight(Y_COLOR)
|
||||
brace = Brace(system, UP)
|
||||
brace.highlight(YELLOW)
|
||||
words = brace.get_text("One unique solution \\dots", "probably")
|
||||
words.highlight(YELLOW)
|
||||
words.split()[1].highlight(GREEN)
|
||||
|
||||
self.add(system)
|
||||
self.dither()
|
||||
self.play(
|
||||
GrowFromCenter(brace),
|
||||
Write(words.split()[0])
|
||||
)
|
||||
self.dither()
|
||||
self.play(Write(words.split()[1], run_time = 1))
|
||||
self.dither()
|
||||
|
||||
class ThreeDTransformAndReverse(Scene):
|
||||
pass
|
||||
|
||||
class InversesDontAlwaysExist(TeacherStudentsScene):
|
||||
def construct(self):
|
||||
self.teacher_says("$A^{-1}$ doesn't always exist")
|
||||
self.random_blink()
|
||||
self.dither()
|
||||
self.random_blink()
|
||||
|
||||
class InvertNonInvertable(LinearTransformationScene):
|
||||
CONFIG = {
|
||||
"t_matrix" : [[2, 1], [-2, -1]]
|
||||
}
|
||||
def setup(self):
|
||||
LinearTransformationScene.setup(self)
|
||||
det_text = TexMobject("\\det(A) = 0")
|
||||
det_text.scale(1.5)
|
||||
det_text.to_corner(UP+LEFT)
|
||||
det_text.add_background_rectangle()
|
||||
self.add_foreground_mobject(det_text)
|
||||
|
||||
def construct(self):
|
||||
no_func = TextMobject("No function does this")
|
||||
no_func.shift(2*UP)
|
||||
no_func.highlight(RED)
|
||||
no_func.add_background_rectangle()
|
||||
grid = VMobject(self.plane, self.i_hat, self.j_hat)
|
||||
grid.save_state()
|
||||
self.apply_transposed_matrix(self.t_matrix, path_arc = 0)
|
||||
self.dither()
|
||||
self.play(Write(no_func, run_time = 1))
|
||||
self.add_foreground_mobject(no_func)
|
||||
self.play(
|
||||
grid.restore,
|
||||
*map(Animation, self.foreground_mobjects),
|
||||
run_time = 3
|
||||
)
|
||||
self.dither()
|
||||
|
||||
class OneInputMultipleOutputs(InvertNonInvertable):
|
||||
def construct(self):
|
||||
input_vectors = VMobject(*[
|
||||
Vector([x+2, x]) for x in np.arange(-4, 4.5, 0.5)
|
||||
])
|
||||
input_vectors.submobject_gradient_highlight(PINK, YELLOW)
|
||||
output_vector = Vector([4, 2], color = YELLOW)
|
||||
|
||||
grid = VMobject(self.plane, self.i_hat, self.j_hat)
|
||||
grid.save_state()
|
||||
|
||||
self.apply_transposed_matrix(self.t_matrix, path_arc = 0)
|
||||
self.play(ShowCreation(output_vector))
|
||||
single_input = TextMobject("Single vector")
|
||||
single_input.add_background_rectangle()
|
||||
single_input.next_to(output_vector.get_end(), UP)
|
||||
single_input.highlight(YELLOW)
|
||||
self.play(Write(single_input))
|
||||
self.dither()
|
||||
self.remove(single_input, output_vector)
|
||||
self.play(
|
||||
grid.restore,
|
||||
*[
|
||||
Transform(output_vector.copy(), input_vector)
|
||||
for input_vector in input_vectors.split()
|
||||
] + map(Animation, self.foreground_mobjects),
|
||||
run_time = 3
|
||||
)
|
||||
multiple_outputs = TextMobject(
|
||||
"Must map to \\\\",
|
||||
"multiple vectors"
|
||||
)
|
||||
multiple_outputs.split()[1].submobject_gradient_highlight(YELLOW, PINK)
|
||||
multiple_outputs.next_to(ORIGIN, DOWN).to_edge(RIGHT)
|
||||
multiple_outputs.add_background_rectangle()
|
||||
self.play(Write(multiple_outputs, run_time = 2))
|
||||
self.dither()
|
||||
|
||||
class ThreeDOntoPlane(Scene):
|
||||
pass
|
||||
|
||||
class ThreeDOntoLine(Scene):
|
||||
pass
|
||||
|
||||
class ThreeDOntoPoint(Scene):
|
||||
pass
|
||||
|
||||
class TowDColumnsDontSpan(LinearTransformationScene):
|
||||
CONFIG = {
|
||||
"t_matrix" : [[2, 1], [-2, -1]]
|
||||
}
|
||||
def construct(self):
|
||||
matrix = Matrix(self.t_matrix.T)
|
||||
matrix.highlight_columns(X_COLOR, Y_COLOR)
|
||||
matrix.add_to_back(BackgroundRectangle(matrix))
|
||||
self.add_foreground_mobject(matrix)
|
||||
brace = Brace(matrix)
|
||||
words = brace.get_text(
|
||||
"Columns don't",
|
||||
"span \\\\",
|
||||
"full output space"
|
||||
)
|
||||
words[1].highlight(PINK)
|
||||
words.add_background_rectangle()
|
||||
VMobject(matrix, brace, words).to_corner(UP+LEFT)
|
||||
|
||||
self.apply_transposed_matrix(self.t_matrix, path_arc = 0)
|
||||
self.play(
|
||||
GrowFromCenter(brace),
|
||||
Write(words, run_time = 2)
|
||||
)
|
||||
self.dither()
|
||||
self.play(ApplyFunction(
|
||||
lambda m : m.scale(-1).shift(self.i_hat.get_end()),
|
||||
self.j_hat
|
||||
))
|
||||
for x in range(5):
|
||||
i_target, j_target = [
|
||||
m.copy().scale(random.uniform(-1.2, 1.2))
|
||||
for m in self.i_hat, self.j_hat
|
||||
]
|
||||
j_target.shift(-j_target.get_start()+i_target.get_end())
|
||||
self.play(Transform(
|
||||
VMobject(self.i_hat, j_hat, VectorizedPoint()),
|
||||
VMobject(i_target, j_target, VectorizedPoint()),
|
||||
submobject_mode = "lagged_start"
|
||||
))
|
||||
self.dither()
|
||||
if x == 2:
|
||||
self.play(ShowCreation(Vector([2, -1])))
|
||||
|
||||
class ThreeDColumnsDontSpan(Scene):
|
||||
def construct(self):
|
||||
matrix = Matrix(np.array([
|
||||
[1, 1, 0],
|
||||
[0, 1, 1],
|
||||
[-1, -2, -1],
|
||||
]).T)
|
||||
matrix.highlight_columns(X_COLOR, Y_COLOR, Z_COLOR)
|
||||
brace = Brace(matrix)
|
||||
words = brace.get_text(
|
||||
"Columns don't",
|
||||
"span \\\\",
|
||||
"full output space"
|
||||
)
|
||||
words[1].highlight(PINK)
|
||||
|
||||
self.add(matrix)
|
||||
self.play(
|
||||
GrowFromCenter(brace),
|
||||
Write(words, run_time = 2)
|
||||
)
|
||||
self.dither()
|
||||
|
||||
|
||||
|
||||
|
@ -260,6 +260,10 @@ class LinearTransformationScene(VectorScene):
|
||||
"t_matrix" : np.array([[3, 0], [1, 2]]),
|
||||
}
|
||||
def setup(self):
|
||||
if hasattr(self, "has_setup"):
|
||||
return
|
||||
self.has_setup = True
|
||||
##^This is to not break all the old Scenes
|
||||
self.background_mobjects = []
|
||||
self.foreground_mobjects = []
|
||||
self.transformable_mobjects = []
|
||||
|
@ -454,7 +454,13 @@ class Mobject(object):
|
||||
raise Exception("Not implemented")
|
||||
|
||||
|
||||
## Family matters
|
||||
## Family matters
|
||||
|
||||
def __getitem__(self, index):
|
||||
return self.split()[index]
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.split())
|
||||
|
||||
def split(self):
|
||||
result = [self] if len(self.points) > 0 else []
|
||||
|
@ -43,9 +43,9 @@ class TexMobject(SVGMobject):
|
||||
digest_config(self, kwargs, locals())
|
||||
##TODO, Eventually remove this
|
||||
if len(args) == 1 and isinstance(args[0], list):
|
||||
args = args[0]
|
||||
self.args = args[0]
|
||||
##
|
||||
assert(all([isinstance(a, str) for a in args]))
|
||||
assert(all([isinstance(a, str) for a in self.args]))
|
||||
VMobject.__init__(self, **kwargs)
|
||||
self.move_into_position()
|
||||
if self.organize_left_to_right:
|
||||
@ -133,8 +133,8 @@ class Brace(TexMobject):
|
||||
mob.next_to(self, self.direction, **kwargs)
|
||||
return self
|
||||
|
||||
def get_text(self, text, **kwargs):
|
||||
text_mob = TextMobject(text)
|
||||
def get_text(self, *text, **kwargs):
|
||||
text_mob = TextMobject(*text)
|
||||
self.put_at_tip(text_mob, **kwargs)
|
||||
return text_mob
|
||||
|
||||
|
@ -31,8 +31,12 @@ class Scene(object):
|
||||
self.mobjects = []
|
||||
self.num_plays = 0
|
||||
|
||||
self.setup()
|
||||
self.construct(*self.construct_args)
|
||||
|
||||
def setup(self):
|
||||
pass #For any common super classes to set up.
|
||||
|
||||
def construct(self):
|
||||
pass #To be implemented in subclasses
|
||||
|
||||
|
Reference in New Issue
Block a user