from big_ol_pile_of_manim_imports import * class WorkOutNumerically(Scene): CONFIG = { "M1_COLOR": TEAL, "M2_COLOR": PINK, } def construct(self): self.add_question() self.add_example() self.compute_rhs() self.compute_lhs() def add_question(self): equation = self.original_equation = TexMobject( "\\det(", "M_1", "M_2", ")", "=", "\\det(", "M_1", ")", "\\det(", "M_2", ")", ) equation.set_color_by_tex_to_color_map({ "M_1": self.M1_COLOR, "M_2": self.M2_COLOR, }) challenge = TextMobject("Explain in one sentence") challenge.set_color(YELLOW) group = VGroup(challenge, equation) group.arrange_submobjects(DOWN) group.to_edge(UP) self.add(equation) self.play(Write(challenge)) self.wait() def add_example(self): M1 = self.M1 = Matrix([[2, -1], [1, 1]]) M1.set_color(self.M1_COLOR) self.M1_copy = M1.copy() M2 = self.M2 = Matrix([[-1, 4], [1, 1]]) M2.set_color(self.M2_COLOR) self.M2_copy = M2.copy() eq_parts = TexMobject( "\\det", "\\big(", "\\big)", "=", "\\det", "\\big(", "\\big)", "\\det", "\\big(", "\\big)", ) for part in eq_parts.get_parts_by_tex("\\big"): part.scale(2) part.stretch(1.5, 1) i1, i2, i3 = [ eq_parts.index_of_part(part) + 1 for part in eq_parts.get_parts_by_tex("\\big(") ] equation = self.equation_with_numbers = VGroup(*it.chain( eq_parts[:i1], [M1, M2], eq_parts[i1:i2], [self.M1_copy], eq_parts[i2:i3], [self.M2_copy], eq_parts[i3:], )) equation.arrange_submobjects(RIGHT, buff=SMALL_BUFF) eq_parts.get_part_by_tex("=").shift(0.2 * SMALL_BUFF * DOWN) equation.scale_to_fit_width(FRAME_WIDTH - 2 * LARGE_BUFF) equation.next_to(self.original_equation, DOWN, MED_LARGE_BUFF) self.play(LaggedStart(FadeIn, equation)) def compute_rhs(self): M1, M2 = self.M1_copy, self.M2_copy line1 = VGroup( TexMobject( "\\big(", "2", "\\cdot", "2", "-", "(-1)", "\\cdot", "1", "\\big)" ), TexMobject( "\\big(", "-1", "\\cdot", "1", "-", "4", "\\cdot", "1", "\\big)" ), ) line1.arrange_submobjects(RIGHT, buff=SMALL_BUFF) line1[0].set_color(self.M1_COLOR) line1[1].set_color(self.M2_COLOR) indices = [1, 3, 5, 7] line2 = TexMobject("(3)", "(-5)") line2.match_style(line1) line3 = TexMobject("-15") arrows = [TexMobject("\\downarrow") for x in range(2)] lines = VGroup(line1, arrows[0], line2, arrows[1], line3) lines.arrange_submobjects(DOWN, buff=MED_SMALL_BUFF) lines.next_to(self.equation_with_numbers, DOWN, buff=MED_LARGE_BUFF) lines.to_edge(RIGHT) for matrix, det in zip([M1, M2], line1): numbers = VGroup(*[det[i] for i in indices]) numbers_iter = iter(numbers) non_numbers = VGroup(*filter( lambda m: m not in numbers, det )) matrix_numbers = VGroup(*[ matrix.mob_matrix[i][j].copy() for i, j in (0, 0), (1, 1), (0, 1), (1, 0) ]) self.play( LaggedStart(FadeIn, non_numbers, run_time=1), LaggedStart( ReplacementTransform, matrix_numbers, lambda m: (m, numbers_iter.next()), path_arc=TAU / 6 ), ) self.play(LaggedStart(FadeIn, lines[1:], run_time=3)) def compute_lhs(self): matrix = Matrix([[-3, 7], [0, 5]]) matrix.set_color(BLUE) matrix.scale(0.8) empty_det_tex = TexMobject("\\det", "\\big(", "\\big)") empty_det_tex[1:].scale(1.5) empty_det_tex[1:].match_height(matrix, stretch=True) det_tex = VGroup(empty_det_tex[:2], matrix, *empty_det_tex[2:]) det_tex.arrange_submobjects(RIGHT, buff=SMALL_BUFF) group = VGroup( det_tex, TexMobject("\\downarrow"), TexMobject("(-3)(5) - (7)(0)").scale(0.8), TexMobject("\\downarrow"), TexMobject("-15"), ) group.arrange_submobjects(DOWN, buff=2 * SMALL_BUFF) # group.scale_to_fit_height(0.4*FRAME_HEIGHT) group.next_to(self.equation_with_numbers, DOWN) group.shift(FRAME_WIDTH * LEFT / 4) self.play(FadeIn(empty_det_tex)) self.play(*[ ReplacementTransform(M.copy(), matrix) for M in self.M1, self.M2 ]) self.play(LaggedStart(FadeIn, group[1:])) self.wait() class LetsGoInOneSentence(TeacherStudentsScene): def construct(self): self.teacher_says( "Here we go, \\\\", "one sentence!" ) self.change_all_student_modes("hooray") self.teacher_says( "Or three...", "", target_mode="guilty" ) self.change_all_student_modes("sassy") self.wait(4) class SuccessiveLinearTransformations(LinearTransformationScene): CONFIG = { "matrix_2": [[3, -1], [0, 1]], "matrix_1": [[2, 3], [-1. / 3, 2]], } def construct(self): self.create_product_and_inverse() self.scale_area_successively() self.apply_transformations_successively() self.scale_area_successively( "\\det(M_2)", "\\det(M_1)", "\\det(M_1 M_2)", reset=False ) # self.show_det_as_scaling_factor() def create_product_and_inverse(self): self.matrix_product = np.dot(self.matrix_1, self.matrix_2) self.matrix_product_inverse = np.linalg.inv(self.matrix_product) def scale_area_successively(self, tex2="3", tex1="5", tex_prod="15", reset=True): self.add_unit_square() t1 = "$%s \\, \\cdot $" % tex1 t2 = "$%s \\, \\cdot $" % tex2 t3 = "Area" areas = VGroup( TextMobject("", "", t3), TextMobject("", t2, t3), TextMobject(t1, t2, t3), ) areas.scale(0.8) areas.move_to(self.square) area = areas[0] self.add_moving_mobject(area, areas[1]) self.play( FadeIn(self.square), Write(area), Animation(self.basis_vectors) ) self.apply_matrix(self.matrix_2) self.wait() self.add_moving_mobject(area, areas[2]) self.apply_matrix(self.matrix_1) self.wait() product = VGroup(area[:2]) brace = Brace(product, DOWN, buff=SMALL_BUFF) brace_tex = brace.get_tex(tex_prod, buff=SMALL_BUFF) brace_tex.scale(0.8, about_edge=UP) self.play( GrowFromCenter(brace), Write(brace_tex) ) self.wait() if reset: self.play( FadeOut(VGroup(self.square, area, brace, brace_tex)), Animation(self.plane), Animation(self.basis_vectors) ) self.transformable_mobjects.remove(self.square) self.moving_mobjects = [] self.reset_plane() self.wait() def apply_transformations_successively(self): M1, M2, all_space = expression = TexMobject( "M_1", "M_2", "\\text{(All 2d space)}" ) expression.set_color_by_tex_to_color_map({ "M_1": TEAL, "M_2": PINK, }) expression.shift(FRAME_WIDTH * LEFT / 4) expression.to_edge(UP) for part in expression: part.add_background_rectangle() part.background_rectangle.stretch(1.05, 0) M1.save_state() M1.move_to(ORIGIN) M1.fade(1) # Apply one after the other self.play( FocusOn(M2, run_time=1), FadeIn(VGroup(M2, all_space)) ) self.add_foreground_mobjects(M2, all_space) self.apply_matrix(self.matrix_2) self.wait() self.play(M1.restore) self.add_foreground_mobjects(M1) self.apply_matrix(self.matrix_1) self.wait() # Show full composition rp, lp = parens = TexMobject("()") matrices = VGroup(M1, M2) matrices.generate_target() parens.match_height(matrices) lp.move_to(matrices, RIGHT) matrices.target.next_to(lp, LEFT, SMALL_BUFF) rp.next_to(matrices.target, LEFT, SMALL_BUFF) self.reset_plane() self.play( MoveToTarget(matrices), *map(GrowFromCenter, parens) ) self.apply_matrix(self.matrix_product) self.wait() self.reset_plane() def show_det_as_scaling_factor(self): pass ### def reset_plane(self): plane_and_bases = VGroup(self.plane, self.basis_vectors) self.play(FadeOut(plane_and_bases)) self.apply_matrix(self.matrix_product_inverse, run_time=0) self.play(FadeIn(plane_and_bases))