explainer-env / a.html
kgdrathan's picture
Upload folder using huggingface_hub
1eaaf1d verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/favicon.ico" />
<!-- Preload is necessary because we show these images when we disconnect from the server,
but at that point we cannot load these images from the server -->
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/gradient-yHQUC_QB.png" as="image" />
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/noise-60BoTA8O.png" as="image" />
<!-- Preload the fonts -->
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/Lora-VariableFont_wght-CZceb_kH.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/PTSans-Regular-Bam3NpBI.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/PTSans-Bold-C_DwAp7Z.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/FiraMono-Regular-CEsLFVD9.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/FiraMono-Medium-D5MAsWEG.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/FiraMono-Bold-C6PDArdf.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="a marimo app" />
<link rel="apple-touch-icon" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/apple-touch-icon.png" />
<link rel="manifest" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/manifest.json" />
<script data-marimo="true">
function __resizeIframe(obj) {
const scrollbarHeight = 20; // Max between windows, mac, and linux
function setHeight() {
// Guard against race condition where iframe isn't ready
if (!obj.contentWindow?.document?.documentElement) {
return;
}
const element = obj.contentWindow.document.documentElement;
// If there is no vertical scrollbar, we don't need to resize the iframe
if (element.scrollHeight === element.clientHeight) {
return;
}
// Create a new height that includes the scrollbar height if it's visible
const hasHorizontalScrollbar = element.scrollWidth > element.clientWidth;
const newHeight = element.scrollHeight + (hasHorizontalScrollbar ? scrollbarHeight : 0);
// Only update the height if it's different from the current height
if (obj.style.height !== `${newHeight}px`) {
obj.style.height = `${newHeight}px`;
}
}
// Resize the iframe to the height of the content and bottom scrollbar height
setHeight();
// Resize the iframe when the content changes
const resizeObserver = new ResizeObserver((_entries) => {
setHeight();
});
// Only observe if iframe content is ready
if (obj.contentWindow?.document?.body) {
resizeObserver.observe(obj.contentWindow.document.body);
}
}
</script>
<marimo-filename hidden>a.py</marimo-filename>
<!-- TODO(Trevor): Legacy, required by VS Code plugin. Remove when plugin is updated (see marimo/server/_templates/template.py) -->
<marimo-version data-version="{{ version }}" hidden></marimo-version>
<marimo-user-config data-config="{{ user_config }}" hidden></marimo-user-config>
<marimo-server-token data-token="{{ server_token }}" hidden></marimo-server-token>
<!-- /TODO -->
<title>a</title>
<script type="module" crossorigin crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/index-BjiE1T38.js"></script>
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/preload-helper-D2MJg03u.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/chunk-LvLJmgfZ.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/react-Bj1aDYRI.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/compiler-runtime-B3qBwwSJ.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/jsx-runtime-BqBOg78p.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useEventListener-BR0C1MaI.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/defaultLocale-JieDVWC_.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/precisionRound-CU2C3Vxx.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/defaultLocale-BLne0bXb.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/vega-loader.browser-DXARUlxo.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/utils-Bq5kLQ87.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/clsx-Dz_KRrWq.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/cn-DCUzRj2J.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/badge-ChrPsdTW.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/button-D9nb17Rw.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/react-dom-CSu739Rf.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/fullscreen-BDxedMYP.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/menu-items-CwUpDHG7.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/dist-BoOh2kN5.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/createLucideIcon-D5guW7EU.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/check-BH35Ndha.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/x-C-6liIBr.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/select-5i7URBEn.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/tooltip-Gcwqb_SK.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/use-toast-BDYuj3zG.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useEvent-D91BmmQi.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/invariant-BUdrueMv.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/isObject-DvLSfCY5.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/_baseFor-DKD1r8uL.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/merge-_9WLTEyt.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/zod-H_cgTO0M.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/utils-DIGrmLDO.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/Deferred-DxQeE5uh.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/uuid-DXdzqzcr.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/DeferredRequestRegistry-DjHgMr3S.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/constants-DMpttj8Q.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/session-nmTRerwF.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/config-ChCHm539.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/requests-DIwGYs0l.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useLifecycle-DieWOfXE.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useNonce-DfoVjkkH.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useTheme-DEcgJENn.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/arrays-DYDL-3-i.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/strings-md4mFbOQ.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/once-DRroIaBz.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/capabilities-C_FLIcjP.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/createReducer-1ePoj7v6.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/paths-CXng2XQv.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/dist-BrR4M-k3.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/dist-HlsDto3K.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/dist-CHcznzB-.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/dist-DGxytjtv.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/dist-DZ2qbK2N.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/dist-CEysMnMQ.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/dist-Ds4ite_2.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/dist-CRPTyqAT.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/dist-C9ZB41s2.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/stex-jWatZkll.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/toDate-B5A0DFEz.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/purify.es-DC4RGS9t.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/cjs-BRGiG41H.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/isSymbol-BT6B8Bon.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/now-CsYTPAhW.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/debounce-DhnxH9Rh.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/database-zap-BUVn5HoR.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/main-B0OX4z33.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/cells-CJlo_hG2.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/ErrorBoundary-DzYV_VeY.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/kbd-CGShmG7L.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useInstallPackage-afgh7PwB.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/alert-dialog-BGBdrcqJ.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/dialog-EekxpBBM.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useDebounce-BDIglWmG.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/numbers-OHL_xBiC.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/SSRProvider-D3zWcDme.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/context-DGqo1TbK.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useNumberFormatter-wQU1z0W_.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/usePress-CtfZXGno.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/input-DyPS_GiK.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/ImperativeModal-BBqcKmmk.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/cell-link-BA7Demf0.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/multi-map-rafH3cg3.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/alert-cDholnQq.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/chevron-right-CG5QYXYk.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/dropdown-menu-D1A3cFC8.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/links-C-rLiK3d.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useRunCells-B531RIUE.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/copy-B5qyZn5s.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/copy-Dk_3y0H-.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/copy-icon-C67c9EwB.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/RenderHTML-BT9obKLc.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/datasource-BKDU-4D5.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/state-C5AUgyZT.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/sparkles-CZ5WmLPA.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/MarimoErrorOutput-BBD405a6.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/spinner-Bhir8k53.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/html-to-image-Cz8lDF-Y.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/focus-BX3gXJxx.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useAsyncData-dS4Ne6pU.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/LazyAnyLanguageCodeMirror-0gZO1asr.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/micromark-factory-space-WzovnJik.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/chunk-5FQGJX7Z-B4RvNAGm.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/markdown-renderer-CeHY2KoQ.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/command-DbT_zkRP.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/popover-UExmgBsf.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/errors-CZb6hI2x.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/download-mzsKQgiy.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/table-23NNA1s9.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useIframeCapabilities-CryCjoyY.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/error-banner-CTBwdcdk.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/formats-BvyJSIqk.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/en-US-BqRooSzc.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/isValid-bmSEa3HX.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/dates-DhByPWH5.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/maps-C48Oksn0.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/extends-Co37_JfG.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/emotion-is-prop-valid.esm-DYxi7n2b.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useDateFormatter-BEz9SEXo.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/react-icons.esm-BUYTQ32a.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/table-6NxtGaCm.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/ellipsis-pk06Lq82.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/message-circle-CWm2KnSx.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/react-resizable-panels.browser.esm-Bcm5njwd.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/JsonOutput-DXnOS_Hk.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/chart-no-axes-column-nqk474t8.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/square-function-D1dlJvD8.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/spec-Cq8FVoTf.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/ellipsis-vertical-gxgNyR5G.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/refresh-cw-DHwG4Mac.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/tree-actions-oMCx6WNc.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/components-BiBOcq1x.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/column-preview-DzN2QumC.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/icons-BRopQwI3.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/floating-outline-BMB4_phA.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useAddCell-CqBbGhrY.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/objectWithoutPropertiesLoose-smPWkHxB.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/esm-G1JMtvxe.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/eye-off-BT-KOYV5.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/plus-BgB18UzY.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/readonly-python-code-Ccd8HM-7.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/file-headphone-B3fuktN0.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/file-HTLbeC2b.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/image-DQHXdEQn.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/file-icons-BNrh8MRG.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/switch-DlgpDZMk.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/events-Qeh-bHlj.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/globals-xVhZei_S.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/share-BXN2Sd1t.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/blob-CTort_or.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/memoize-Tp7rARFe.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/get-C-qh_et5.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/_baseSet-CxV9N1bc.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/state-DHlRrwyY.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/label-DTR8T0AE.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/textarea-BXPC1-kb.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/radio-group-BtBoRbGH.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/refresh-ccw-C-n2VFP5.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/trash-2-D280Xiwg.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/form-CPDlIjdV.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/renderShortcut-CkNNAheg.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/field-B8kJgr2A.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/RSPContexts-BeHIgT4C.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useBoolean-CLFdHewv.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/useDeepCompareMemoize-D0WTlCXt.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/types-W8WWuumF.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/fileToBase64-Bzn96tYq.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/pathUtils-CSrNy17a.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/prop-types-BFRDxSKF.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/es-YQvzKo5h.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/hasIn-DiS_ryrS.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/flatten-Dl4V1ub3.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/pick-DqWUNly1.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/code-xml-CZN6vNxu.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/square-Dj2Cf4ne.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/triangle-alert-DBoAWWKA.js">
<link rel="modulepreload" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/bundle.esm-DU-4isVC.js">
<link rel="stylesheet" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/cells-jmgGt1lS.css">
<link rel="stylesheet" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/markdown-renderer-DdDKmWlR.css">
<link rel="stylesheet" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/JsonOutput-B7vuddcd.css">
<link rel="stylesheet" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.23.3/dist/assets/index-BYLYJcAY.css">
<script data-marimo="true">
Object.defineProperty(window, "__MARIMO_STATIC__", {
value: Object.freeze({
files: Object.freeze({}),
modelNotifications: Object.freeze([]),
}),
writable: false,
configurable: false,
});
</script>
<script data-marimo="true">
Object.defineProperty(window, "__MARIMO_EXPORT_CONTEXT__", {
value: Object.freeze({
trusted: true,
notebookCode: "import marimo\n\n__generated_with = \"0.23.3\"\napp = marimo.App()\n\n\n@app.cell\ndef _():\n import marimo as mo\n import numpy as np\n import matplotlib.pyplot as plt\n\n # Matrix Multiplication as Linear Transformations\n mo.md(\"\"\"\n # Matrix Multiplication as Linear Transformations\n\n In this interactive exploration, we'll understand how matrix multiplication relates to linear transformations.\n\n ## Key Concepts\n - **Linear Transformation**: A function that maps vectors to vectors while preserving vector addition and scalar multiplication\n - **Matrix Multiplication**: Represents the composition of linear transformations\n - **Basis Vectors**: Standard vectors that span a vector space\n - **Determinant**: Measures how much a transformation scales area/volume\n \"\"\")\n\n # Show basic matrix-vector multiplication\n _A = np.array([[2, 1], [1, 2]])\n _x = np.array([1, 0])\n\n # Apply transformation\n _Ax = _A @ _x\n\n # Create visualization\n _fig, _ax = plt.subplots(figsize=(8, 6))\n\n # Plot original basis vectors\n _ax.arrow(0, 0, 1, 0, head_width=0.05, head_length=0.05, fc=\"blue\", ec=\"blue\", label=\"e\u2081\")\n _ax.arrow(0, 0, 0, 1, head_width=0.05, head_length=0.05, fc=\"green\", ec=\"green\", label=\"e\u2082\")\n\n # Plot transformed basis vectors\n _ax.arrow(0, 0, _A[0, 0], _A[1, 0], head_width=0.05, head_length=0.05, fc=\"red\", ec=\"red\", label=\"A\u00b7e\u2081\")\n _ax.arrow(0, 0, _A[0, 1], _A[1, 1], head_width=0.05, head_length=0.05, fc=\"orange\", ec=\"orange\", label=\"A\u00b7e\u2082\")\n\n # Plot input vector\n _ax.arrow(0, 0, _x[0], _x[1], head_width=0.05, head_length=0.05, fc=\"purple\", ec=\"purple\", label=\"x\")\n\n # Plot output vector\n _ax.arrow(0, 0, _Ax[0], _Ax[1], head_width=0.05, head_length=0.05, fc=\"brown\", ec=\"brown\", label=\"Ax\")\n\n _ax.set_xlim(-1, 4)\n _ax.set_ylim(-1, 4)\n _ax.grid(True)\n _ax.legend()\n _ax.set_aspect(\"equal\")\n _ax.set_title(\"Linear Transformation: Matrix A applied to Vector x\")\n return mo, np, plt\n\n\n@app.cell\ndef _(mo):\n # Demonstrate matrix multiplication as transformation\n mo.md(\"\"\"\n ## Understanding Linear Transformations Through Matrices\n\n Consider a 2\u00d72 matrix $A$:\n $$A = \begin{bmatrix} 2 \u0026 1 \\ 1 \u0026 2 \\end{bmatrix}$$\n\n This matrix transforms the standard basis vectors:\n - $e_1 = \begin{bmatrix} 1 \\ 0 \\end{bmatrix}$ becomes $A \\cdot e_1 = \begin{bmatrix} 2 \\ 1 \\end{bmatrix}$\n - $e_2 = \begin{bmatrix} 0 \\ 1 \\end{bmatrix}$ becomes $A \\cdot e_2 = \begin{bmatrix} 1 \\ 2 \\end{bmatrix}$\n\n The columns of $A$ represent where the basis vectors land after transformation.\n\n Let's see how this applies to a specific vector $x$:\n $$x = \begin{bmatrix} 1 \\ 0 \\end{bmatrix}$$\n\n Applying our transformation:\n $$Ax = \begin{bmatrix} 2 \u0026 1 \\ 1 \u0026 2 \\end{bmatrix} \begin{bmatrix} 1 \\ 0 \\end{bmatrix} = \begin{bmatrix} 2 \\ 1 \\end{bmatrix}$$\n \"\"\")\n return\n\n\n@app.cell\ndef _(mo, np):\n # Interactive demonstration of composition\n mo.md(\"\"\"\n ## Composition of Transformations\n\n Matrix multiplication corresponds to applying transformations in sequence.\n\n If we have two transformations:\n - $A = \\begin{bmatrix} 2 \u0026 1 \\\\ 1 \u0026 2 \\end{bmatrix}$\n - $B = \\begin{bmatrix} 1 \u0026 0 \\\\ 0 \u0026 3 \\end{bmatrix}$\n\n Applying $B$ after $A$ is equivalent to multiplying matrices $BA$:\n\n $$(BA)x = B(Ax)$$\n \"\"\")\n\n # Example of composition\n _A = np.array([[2, 1], [1, 2]])\n _B = np.array([[1, 0], [0, 3]])\n\n # Calculate BA\n _BA = _B @ _A\n\n # Test with a vector\n _x = np.array([1, 1])\n\n # Apply transformations sequentially\n _Ax = _A @ _x\n _BAx = _BA @ _x\n\n # Compare with direct multiplication\n _result_direct = _B @ _Ax\n\n print(f\"Original vector: {_x}\")\n print(f\"A(x): {_Ax}\")\n print(f\"B(A(x)): {_result_direct}\")\n print(f\"(BA)(x): {_BAx}\")\n print(f\"Are they equal? {np.allclose(_result_direct, _BAx)}\")\n return\n\n\n@app.cell\ndef _(mo, np):\n # Introduce determinant\n mo.md(\"\"\"\n ## Determinant: Measuring Scaling Factor\n\n The determinant of a transformation matrix tells us how much area (in 2D) or volume (in 3D) is scaled.\n\n For a 2\u00d72 matrix:\n $$\\text{det}(A) = \\begin{vmatrix} a \u0026 b \\\\ c \u0026 d \\end{vmatrix} = ad - bc$$\n\n Example with our matrix:\n $$A = \\begin{bmatrix} 2 \u0026 1 \\\\ 1 \u0026 2 \\end{bmatrix}$$\n\n $$\\text{det}(A) = 2 \\cdot 2 - 1 \\cdot 1 = 4 - 1 = 3$$\n\n This means the transformation scales the area by a factor of 3.\n \"\"\")\n\n # Calculate determinant\n _A = np.array([[2, 1], [1, 2]])\n _det_A = np.linalg.det(_A)\n\n print(f\"Matrix A: {_A}\")\n print(f\"Determinant of A: {_det_A}\")\n return\n\n\n@app.cell\ndef _(mo, np, plt):\n # Visualize how determinant affects area\n mo.md(\"\"\"\n ## Visualizing the Effect of Determinants\n\n The determinant tells us how the transformation changes the area of shapes.\n\n Let's consider a unit square with corners at (0,0), (1,0), (1,1), (0,1).\n\n After applying transformation $A$, we get a parallelogram.\n\n With determinant = 3, the area is multiplied by 3.\n \"\"\")\n\n # Define unit square corners\n _square = np.array([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]) # Closing the shape\n\n # Apply transformation\n _A = np.array([[2, 1], [1, 2]])\n _transformed_square = _square @ _A.T\n\n # Plot\n _fig, _ax = plt.subplots(figsize=(8, 6))\n\n # Plot original square\n _ax.plot(_square[:, 0], _square[:, 1], \"b-\", linewidth=2, label=\"Original Square\")\n\n # Plot transformed square\n _ax.plot(_transformed_square[:, 0], _transformed_square[:, 1], \"r-\", linewidth=2, label=\"Transformed Square\")\n\n # Add grid and labels\n _ax.grid(True)\n _ax.legend()\n _ax.set_aspect(\"equal\")\n _ax.set_title(\"Effect of Linear Transformation on a Unit Square\")\n _ax.set_xlabel(\"X\")\n _ax.set_ylabel(\"Y\")\n return\n\n\n@app.cell\ndef _():\n return\n\n\nif __name__ == \"__main__\":\n app.run()\n",
}),
writable: false,
configurable: false,
});
</script>
</head>
<body>
<div id="root"></div>
<!-- This is a portal for the data editor to render in -->
<div id="portal" data-testid="glide-portal" style="position: fixed; left: 0; top: 0; z-index: 9999"></div>
<script data-marimo="true">
Object.defineProperty(window, "__MARIMO_MOUNT_CONFIG__", {
value: Object.freeze({
"filename": "a.py",
"cwd": "",
"lspWorkspace": null,
"mode": "read",
"version": "0.23.3",
"serverToken": "static",
"config": {"ai": {"custom_providers": {}, "models": {"custom_models": [], "displayed_models": []}}, "completion": {"activate_on_typing": true, "copilot": false, "signature_hint_on_typing": false}, "diagnostics": {"sql_linter": true}, "display": {"cell_output": "below", "code_editor_font_size": 14, "dataframes": "rich", "default_table_max_columns": 50, "default_table_page_size": 10, "default_width": "medium", "reference_highlighting": true, "theme": "light"}, "formatting": {"line_length": 79}, "keymap": {"overrides": {}, "preset": "default"}, "language_servers": {"pylsp": {"enable_flake8": false, "enable_mypy": true, "enable_pydocstyle": false, "enable_pyflakes": false, "enable_pylint": false, "enable_ruff": true, "enabled": false}}, "mcp": {"mcpServers": {}, "presets": []}, "package_management": {"manager": "uv"}, "runtime": {"auto_instantiate": false, "auto_reload": "off", "default_csv_encoding": "utf-8", "default_sql_output": "auto", "on_cell_change": "autorun", "output_max_bytes": 8000000, "reactive_tests": true, "show_tracebacks": false, "std_stream_max_bytes": 1000000, "watcher_on_save": "lazy"}, "save": {"autosave": "after_delay", "autosave_delay": 1000, "format_on_save": false}, "server": {"browser": "default", "follow_symlink": false}, "snippets": {"custom_paths": [], "include_default_snippets": true}},
"configOverrides": {},
"appConfig": {"sql_output": "auto", "width": "compact"},
"view": {"showAppCode": true},
"notebook": {"cells": [{"code": "import marimo as mo\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# Matrix Multiplication as Linear Transformations\nmo.md(\"\"\"\n# Matrix Multiplication as Linear Transformations\n\nIn this interactive exploration, we'll understand how matrix multiplication relates to linear transformations.\n\n## Key Concepts\n- **Linear Transformation**: A function that maps vectors to vectors while preserving vector addition and scalar multiplication\n- **Matrix Multiplication**: Represents the composition of linear transformations\n- **Basis Vectors**: Standard vectors that span a vector space\n- **Determinant**: Measures how much a transformation scales area/volume\n\"\"\")\n\n# Show basic matrix-vector multiplication\n_A = np.array([[2, 1], [1, 2]])\n_x = np.array([1, 0])\n\n# Apply transformation\n_Ax = _A @ _x\n\n# Create visualization\n_fig, _ax = plt.subplots(figsize=(8, 6))\n\n# Plot original basis vectors\n_ax.arrow(0, 0, 1, 0, head_width=0.05, head_length=0.05, fc=\"blue\", ec=\"blue\", label=\"e\u2081\")\n_ax.arrow(0, 0, 0, 1, head_width=0.05, head_length=0.05, fc=\"green\", ec=\"green\", label=\"e\u2082\")\n\n# Plot transformed basis vectors\n_ax.arrow(0, 0, _A[0, 0], _A[1, 0], head_width=0.05, head_length=0.05, fc=\"red\", ec=\"red\", label=\"A\u00b7e\u2081\")\n_ax.arrow(0, 0, _A[0, 1], _A[1, 1], head_width=0.05, head_length=0.05, fc=\"orange\", ec=\"orange\", label=\"A\u00b7e\u2082\")\n\n# Plot input vector\n_ax.arrow(0, 0, _x[0], _x[1], head_width=0.05, head_length=0.05, fc=\"purple\", ec=\"purple\", label=\"x\")\n\n# Plot output vector\n_ax.arrow(0, 0, _Ax[0], _Ax[1], head_width=0.05, head_length=0.05, fc=\"brown\", ec=\"brown\", label=\"Ax\")\n\n_ax.set_xlim(-1, 4)\n_ax.set_ylim(-1, 4)\n_ax.grid(True)\n_ax.legend()\n_ax.set_aspect(\"equal\")\n_ax.set_title(\"Linear Transformation: Matrix A applied to Vector x\")", "code_hash": "4de3ab86ee417aee23a92bb6071adef8", "config": {"column": null, "disabled": false, "hide_code": false}, "id": "Hbol", "name": "_"}, {"code": "# Demonstrate matrix multiplication as transformation\nmo.md(\"\"\"\n## Understanding Linear Transformations Through Matrices\n\nConsider a 2\u00d72 matrix $A$:\n$$A = \begin{bmatrix} 2 \u0026 1 \\ 1 \u0026 2 \\end{bmatrix}$$\n\nThis matrix transforms the standard basis vectors:\n- $e_1 = \begin{bmatrix} 1 \\ 0 \\end{bmatrix}$ becomes $A \\cdot e_1 = \begin{bmatrix} 2 \\ 1 \\end{bmatrix}$\n- $e_2 = \begin{bmatrix} 0 \\ 1 \\end{bmatrix}$ becomes $A \\cdot e_2 = \begin{bmatrix} 1 \\ 2 \\end{bmatrix}$\n\nThe columns of $A$ represent where the basis vectors land after transformation.\n\nLet's see how this applies to a specific vector $x$:\n$$x = \begin{bmatrix} 1 \\ 0 \\end{bmatrix}$$\n\nApplying our transformation:\n$$Ax = \begin{bmatrix} 2 \u0026 1 \\ 1 \u0026 2 \\end{bmatrix} \begin{bmatrix} 1 \\ 0 \\end{bmatrix} = \begin{bmatrix} 2 \\ 1 \\end{bmatrix}$$\n\"\"\")", "code_hash": "8322b0c7aaa842391144fc9c12faf32e", "config": {"column": null, "disabled": false, "hide_code": false}, "id": "MJUe", "name": "_"}, {"code": "# Interactive demonstration of composition\nmo.md(\"\"\"\n## Composition of Transformations\n\nMatrix multiplication corresponds to applying transformations in sequence.\n\nIf we have two transformations:\n- $A = \\begin{bmatrix} 2 \u0026 1 \\\\ 1 \u0026 2 \\end{bmatrix}$\n- $B = \\begin{bmatrix} 1 \u0026 0 \\\\ 0 \u0026 3 \\end{bmatrix}$\n\nApplying $B$ after $A$ is equivalent to multiplying matrices $BA$:\n\n$$(BA)x = B(Ax)$$\n\"\"\")\n\n# Example of composition\n_A = np.array([[2, 1], [1, 2]])\n_B = np.array([[1, 0], [0, 3]])\n\n# Calculate BA\n_BA = _B @ _A\n\n# Test with a vector\n_x = np.array([1, 1])\n\n# Apply transformations sequentially\n_Ax = _A @ _x\n_BAx = _BA @ _x\n\n# Compare with direct multiplication\n_result_direct = _B @ _Ax\n\nprint(f\"Original vector: {_x}\")\nprint(f\"A(x): {_Ax}\")\nprint(f\"B(A(x)): {_result_direct}\")\nprint(f\"(BA)(x): {_BAx}\")\nprint(f\"Are they equal? {np.allclose(_result_direct, _BAx)}\")", "code_hash": "80cfde1afbe2aff8909f846263aef8ae", "config": {"column": null, "disabled": false, "hide_code": false}, "id": "vblA", "name": "_"}, {"code": "# Introduce determinant\nmo.md(\"\"\"\n## Determinant: Measuring Scaling Factor\n\nThe determinant of a transformation matrix tells us how much area (in 2D) or volume (in 3D) is scaled.\n\nFor a 2\u00d72 matrix:\n$$\\text{det}(A) = \\begin{vmatrix} a \u0026 b \\\\ c \u0026 d \\end{vmatrix} = ad - bc$$\n\nExample with our matrix:\n$$A = \\begin{bmatrix} 2 \u0026 1 \\\\ 1 \u0026 2 \\end{bmatrix}$$\n\n$$\\text{det}(A) = 2 \\cdot 2 - 1 \\cdot 1 = 4 - 1 = 3$$\n\nThis means the transformation scales the area by a factor of 3.\n\"\"\")\n\n# Calculate determinant\n_A = np.array([[2, 1], [1, 2]])\n_det_A = np.linalg.det(_A)\n\nprint(f\"Matrix A: {_A}\")\nprint(f\"Determinant of A: {_det_A}\")", "code_hash": "1a5b5ebd430135bb72ec3679e4657802", "config": {"column": null, "disabled": false, "hide_code": false}, "id": "bkHC", "name": "_"}, {"code": "# Visualize how determinant affects area\nmo.md(\"\"\"\n## Visualizing the Effect of Determinants\n\nThe determinant tells us how the transformation changes the area of shapes.\n\nLet's consider a unit square with corners at (0,0), (1,0), (1,1), (0,1).\n\nAfter applying transformation $A$, we get a parallelogram.\n\nWith determinant = 3, the area is multiplied by 3.\n\"\"\")\n\n# Define unit square corners\n_square = np.array([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]) # Closing the shape\n\n# Apply transformation\n_A = np.array([[2, 1], [1, 2]])\n_transformed_square = _square @ _A.T\n\n# Plot\n_fig, _ax = plt.subplots(figsize=(8, 6))\n\n# Plot original square\n_ax.plot(_square[:, 0], _square[:, 1], \"b-\", linewidth=2, label=\"Original Square\")\n\n# Plot transformed square\n_ax.plot(_transformed_square[:, 0], _transformed_square[:, 1], \"r-\", linewidth=2, label=\"Transformed Square\")\n\n# Add grid and labels\n_ax.grid(True)\n_ax.legend()\n_ax.set_aspect(\"equal\")\n_ax.set_title(\"Effect of Linear Transformation on a Unit Square\")\n_ax.set_xlabel(\"X\")\n_ax.set_ylabel(\"Y\")", "code_hash": "5d75f5daca220d202aa977523901ae91", "config": {"column": null, "disabled": false, "hide_code": false}, "id": "lEQa", "name": "_"}, {"code": "", "code_hash": null, "config": {"column": null, "disabled": false, "hide_code": false}, "id": "PKri", "name": "_"}], "metadata": {"marimo_version": "0.23.3"}, "version": "1"},
"session": {"cells": [{"code_hash": "4de3ab86ee417aee23a92bb6071adef8", "console": [], "id": "Hbol", "outputs": [{"data": {"application/vnd.marimo+mimebundle": "{\"image/png\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgQAAAIQCAYAAAD+RXYbAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjksIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvJkbTWQAAAAlwSFlzAAAPYQAAD2EBqD+naQAAPElJREFUeJzt3QmcU9Xd//HfsMzAsCqLLIKAIBQtiAuIdQEFRBFFrfURURTcqCC4VdEWQYtoq9YFRaqyKAqoj2gFFZEHGBeQxWqpC3UtWkAE2ccZBsj/9T30zj8TMkMyzE1uks/79YrjZEJyc3KXb373nHOzQqFQyAAAQEarlOwFAAAAyUcgAAAABAIAAEAgAAAABAIAAEAgAAAADp0KAQAAgQAAABAIAAAAgaB03377rWVlZdmUKVNYURLkzTfftKOPPtqqVavm2n7z5s1p0/Z6P6NHj072YgReixYt7PLLL0/2YgSC9j1ab7Qv8nTr1s3dKhLrJjK6D4G3oS1fvtzSNcjEcgvf0STbxo0b7Te/+Y1Vr17dHnvsMXv22WetRo0alkpef/31lDno66CidaBNmzZR/z5v3rzi9eSll16K+/k//fRT1xZBWcc+++wz914UNtMpaCbKmjVr3Of50UcfVdhzXn/99e4z+fLLL0t9zB133OEe849//MMq0uOPP86XvSiqRLsTZocddpj9/PPPVrVq1ZRqjgYNGriDabgHHnjAvv/+e/vLX/6yz2ODYtmyZbZt2za7++67rUePHpaKFAgUZqKFAq1LVaoEa3PTwVE746VLl1rnzp1L/O25555zfy8oKCjXcysQjBkzxgUPfeuP1apVq6xSpYr/njJt2jRr1KiRbdq0yQWcK6+80lLRW2+9lbRAoM9Tn6WqeBXhkksusUcffdSef/55GzVqVNTHTJ8+3X75y19ahw4drKIDQf369alGRQjWHipAvG8TQZafn2+5ubkl7tO36gEDBpS4b8aMGW5HGHl/OF3jSjt/fUNPhvXr17ufdevWrbDn3LFjR2CqDEFclw4//HDbtWuX2+mGBwKtB7NmzbI+ffrY//7v//q+HOHrXk5Oji/Pr4NO//797ZtvvnFhJ1UDQXZ2tqWLLl26WOvWrd36Fy0QLF682H1e9957r6WCgoIC9/n4EWgTJXWXPAl9CHRus2bNmvaf//zH+vXr5/5f37Jvvvlm2717d4l/v2fPHnvooYfsyCOPdAeDQw45xK655hp3YA736quvuh1vkyZN3M5QO2l9S458Pn3TOuqoo2zFihV2yimnuCBw++23l/v9KemfffbZNnfuXDvuuOPcznjixInub5MnT7bTTjvNGjZs6Japffv2NmHChFKf491333UHFL3PVq1a2TPPPFPicUVFRe7bhcrTeky9evXspJNOcmVp770NHDjQ/f/xxx/v2j38PPKLL75oxx57rFtGpXoFG30G4bzP5quvvrKzzjrLatWq5b6BiJ5v6NCh7nn0XvQ8Xbt2tZUrV7q/631rx6Rl07JElrnfeecdu/DCC6158+auPZo1a2Y33HCD+9Yf/vqqDniv593KOk/797//3c4880yrXbu2W/bTTz/dlixZEvX01nvvvWc33nijW98Ucs477zz78ccfSzx2y5Yt9vnnn7ufsbr44ott5syZbn31vPbaay5s6hROpH//+9/229/+1tq2bevaUZ+l2ia8zbTMuk+6d+9e3BYLFy7c77oX3odAB3L9e71nLzDKzp073bdGbSsKffujttPy/c///I+75eXluYpZLFSq1vJovdb6oSrDoEGD3CmucPps9R7V/mo3faZqm+HDh+9TZfHWRwUTtaOeV+u3lmt/ovUhKCwstDvvvNOtw976+bvf/c7dH/k4rbdqT20f55xzTkztoM9N26VcccUVxZ9n+L4xlm00Gm2jarMPP/xwn78pxOl1tI7G8z69ipD2SdpPHnTQQW6f6VVXtI598skntmjRouL3Et6mX3/9tVt/Dz74YPfvTzjhBJszZ84+baJ/py9bv//9761p06busVu3bo36PrXcCgrz588vcf/VV1/tQsTHH39sgRDKQJMnT9Yln0PLli0r9THffPONe4we6xk4cGCoWrVqoSOPPDI0aNCg0IQJE0IXXHCBe9zjjz9e4t9feeWVoSpVqoSuuuqq0BNPPBG69dZbQzVq1Agdf/zxoZ07dxY/rl+/fqHf/OY3oT//+c/u+S688EL3fDfffHOJ5zv11FNDjRo1CjVo0CA0bNiw0MSJE0OvvPJKTO+3T58+ocMOO6zEffq9devWoYMOOih02223uWVcsGCB+5uW8fLLLw/95S9/CT366KOhXr16uWUaP378Ps/Rtm3b0CGHHBK6/fbb3d+POeaYUFZWVuif//xn8eP0N92ntnjyySdDDzzwQOjiiy8O3Xvvve7vb731Vujqq692r3HXXXeFnn322dD7779f4rPSMml5tKzVq1cPtWjRIrRp06YSn01OTk7o8MMPd/+v9/PMM8+4v+nfd+jQIdSsWTP3mrrVqVMn1Lx5c7fM7du3d8v0+9//PpSdnR3q3r17ifep9j7rrLNC99xzj2v3wYMHhypXrhz69a9/XfwYLW/Pnj3da2n5vZtH9995553Fv6t9tD40btw4dPfdd7tlatmypXsPS5YsKX6c9/47deoUOu2009zncdNNN7nX13oTznts+DpbGq1PWo//9a9/uX8zf/78EuvkGWec4dYH/e3FF18s/pv+v2PHjqFRo0aF/vrXv7rPVuuQ1oUdO3a4x3z11Veh66+/3v1b/d1ri3Xr1u133dPf9Pl5vv7661DNmjVD5513XvF9+jdanxYtWhSKxbXXXuvWC8nPz3fP96c//Smmf3v//feHTj75ZLde6v0OHz7crX+dO3cO7dmzp/hx+mz1fn/5y1+G+vbt69arAQMGuPsuvfTSEs+p+4466qhQ/fr13fPed9997n3reVeuXLnP56l9Ufjnpptn9+7dbvvMzc0NjRgxwq2fQ4cOdfuec889t8TresvTv39/t3znn3++2y4i181I+ty0nHqctlPv89TnHM82Go23/mmdDrdr165Qw4YNQ6ecckrc73P06NHuOU888US3X3344Yfde9Y+WGbNmhU69NBDQ+3atSt+L9oHee9V+7NatWqF7rjjjtCDDz7o1vdKlSqFXn755ZDH2za07zj66KPd48aNG1e8DUTSPl/bsD7nrVu3uvvefPNN9xza/oOCQBBnIPAOWuH0QR977LHFv7/zzjvucc8991yJx3krQPj92kFFuuaaa9yKX1BQUHyfdgL6t9p5xqu0QKDn0zJFirZMOkC0atUq6nPk5eUV37d+/Xp3UAvfwLVBaRniDWnaiLRT0M7z559/Lr5/9uzZ7rE6KEV+NtoZRdL9WqbwHat2KLpfIcvbQGXkyJH77ISjtYc2fh2U/v3vfxffd91117l/G03kTlcHXYUPb6cqa9ascTsibycY3i49evQocQC64YYbXCjYvHnzAQUCOe6441zIEe3AtVxTp06NGgiitcXixYvd47wAJvo3us870Me67kUGgvDPatq0aS4s6X3roBALrUP16tVzO3ePDg5aJ2MR7f1Onz59n/XeCwTnnHNOicf+9re/dfd//PHHxffpd92WL19efJ/WI33ZCA8+sQQCHcx0sNI+J5z2E/q37733nvv9o48+cr9recKpLfYXCETbZbR1K55ttDQKEjpA66Afua/UZx/P+/ziiy/c49SO4c8n4duP1v3wdvSMGDHCPV/462zbts2FdQUc7zm9bUP7xGjrSDQKe9q29GVR21nTpk3dtldUVBQKCk4ZlMO1115b4veTTz7ZlZnCy2d16tSxnj172oYNG4pvKqmpNLxgwYLix4afs1enOj1Oz6eSrUpp4VQmU8muorRs2dLOOOOMfe4PXyaVn7VMp556qnuPkeVoleC1vB6VI1UGDW8P9QtQie6LL76Ia/k0CkSlYpWow8/B6xRLu3bt9injyZAhQ6I+l8rx4Z3bdP5SLrjgAlc+jbw/fPnD20MlarXHiSee6EraKvvHS6eDVL7UaSeVoj2NGzd257l1Ciay9KjSYvgpCLW5nkclfI9K21qmeIft6TVffvllV4pXh7vKlSu7UxLRhLeFTgWpdK4Srj7jaGXfeNe9aPTe9dhhw4bZpZde6k4V3HPPPTH92zfeeMMto1d2Fv2/SrRaJ/cn/P2q9K/PXiVkifZ+r7vuuhK/a5m9DqfhdMpK+wOPTkede+657jRK5OnCsmhf84tf/MJtD+H7Gp3yE29f472+evaHGzFihB2I8myjkXR6Qacuwk+Z6HSBSuneqadY3+crr7ziTn+pT0Lkufzw7ac0r7/+ujvVoFOaHu2ztQ7qtJM6y4bTqc5Y+13plK9OnT711FNufdbyT506NVCdjQkEcdJKH9k7X+eowvsG6MCnA6fOweux4bft27eXOB+qnZJ2vgoQOu+ox3id/yIPvjpPVZGdirRTLu2cq3r661y1dvRaJq+/QuQyaUcWKbI97rrrLjfU64gjjnDnfm+55ZaYhhF5BzsFjEjaMYQfDEUb1qGHHhr1uSKXU+0tOg8Z7f7w5V+9erU7yOqcotdvRAFJ4jlf79G5fwW+aO9LOz3t0L777rsyl19tHLmc5aXz6nofOnjqvLbO74eHpHDqN6GdrdpNAVXni9Ue+nzjaYvS1r3SPP30067NtG3p3HWsO2GdS9ZraVk1okI3BQqd79V73Z+ffvrJ9QNQHyC9pt6rt+zR3m/kME69lg5Mkf1Sog331Pah9xjZN6Qsag/tQyL3M3ou8fY12la0HFqecNHWwXjEu42Wtv4phCoEhHdqVf8abz2P9X2qD5Hep76olPf9tC1luwx/v+Vdj7Xv69ixoxvZo34F5V1OvwQnmqQIrbj7ox26wkBpOxwvUGgnqgOLgoAOmtpYFTj0zePWW28t0dFLKnoEQLTn0walb9PamB988EG341cIUXLWsMXIZSqtPfZWRvdShx49rzpQ6puxErKe64knnqjQ3t7a6ZfWw7e05dzf8uvbmio9OjDoM1G7KCipw5RCQmR7+CWWdi4vVSbUqUrDUxUGyxpZoG+86nSqb5b6lqsApW9e2qnH0xbxrsvqxOV1HlNnUL32/qjKog6SOsBEOwDrADR27Ngyvzmqg+D777/vduQabqdAqPfZu3fvmN5vLN9KD4SWQSFb22o0kYE3iLSv1Dam9U4dc/WZqVrqdQoO8vusHud6rMqjVyn1OjUHCYHABzqwv/322/arX/2qzBVGOzmVM1Wu1UHTo6E2yaKNUTvev/3tbyW+lYaf5igPfbvW6Q7dVCXR+1XP7LICgeaC8Mame6VBj+7z/u4nbbT/+te/XGnvsssuK77fGyFRnp2/AqG+oeo9RNJpIoWaRO/gdNpAn4UqQhqlURqdUlCZVOHBowNu5GQ/FXkgXLt2rQsivXr1cuFUo3pUct3f56/tSsumETKqZIRT26t3uAJQeHk4nKov6hWuMm/4sLiyTn3pb+HfGlWR0MEsci6GaM+h9UzrRTzzg2hfo9MfCvFltbnaSsuhYB7+DTjaOhhNac9dUduoDv6aqVRVKgU1fUnq27dv3O9Tj9P7VGm/rPkSyno/q0rZLr2/l5eWS18i9N4UqHXa69e//rWdf/75FhScMvCBvlXom6WGD0bSuG9v5+l96wv/lqfzuJo0I1miLZNKo/pWWF6RQ7T0LUvnnaMNFwqnIWn69qBKQvhjtdPQzHM6T5mM9tD/P/zww/s81pvzYH8z4ek5dXBTxSS8lPzDDz+4naEOUNppxKs8ww492jGphKl1r6zTUlr2yKqEJpeJPO8da1vE4qqrrnI7U502+Otf/+pODQ0ePHi/1RGdLlAfDfX50fsLvylUaD0s67RBtM9eNJy4NN7Q0/C2EZW/I8fYh/dB0CkirQ9aL2KpQobva1StevLJJ6Oe3vGGZXqv/8gjj8T8XmL5PCtqG1V/GoUhrX/6tzpIhvdJiPV96nkUqFVxjazghH+Oej/R1s2zzjrLlfP1+Xj03FrvFOoOpMSv6oaqTXouHRvUD0l9ntSXICgyukIwadIkl0oj6ZzhgdBpAM05MG7cODfVpzZyzXiobwXqHKODiXZKWiF0jkzfuLxpPDXLYEWUgcvL+xamdK73oG/z2gi10eubWnloI1JJWp2oVClQRyR909RY7LKoze677z5XVVCbqjOYDppqP22cGlPtN50i0LcOHUC0Q9KBWqXNaOfuvU5i+iz1DVY7dpXSo/njH//oqgw6+KtDlg5yGouvneqf/vSnci2rzruqrRTe4u1YqNJ/LNMuq3+B1lE9Xp+rdpyqhmnMfTh9O9P71+engKLTOd7cFvHQe1HHNPUb8PqH6CCrfjb65q+2K21mPVW1IjvRebQ8+oy0PeogGW1GUn3WqmTp81AHSvXh0Smvsip4+pvG9+uUgtpGoUTVF503juxgptfX8mlZvC8BqkbEQ50sX3jhBRd69H5VlVQ4UzDU/d5cD/o8tP3odfR5aN+j6kdZ0waH0zag6pEO/OpfogOqOuCqGlIR26jCmQ7mXj+C8NMF8bxPfdHQdMc64KrjrYKF2lczoWquF+2TvW1V64+2Q/0brZennXaa3XbbbW6iJAUofTbaX6k6qM9V2315Jx1SOPrDH/7gtkuv8qF1Wp+L1mG9h0AIZSBvOE9pt++++67UYYcaOx7JG3IUSeOWNRxRY3I1nExjlH/3u9+54WUeDZc54YQT3GOaNGni/j537tx9hmyFDxOrqGGHpQ0F/Nvf/ubGJ2sYlIbaaJz0pEmT9hkCVdpzRA6N+uMf/+jGbdetW9e9T43/HTt2bIn5GMqaG2LmzJluaKeGDh588MGhSy65JPT999+XeExpn43oeTUkMJz3+WqccrhoQ+0+/fRTN+xP49c1dlzzKWgYWeT6obHTmrNAc0VoSGL4OhFtaNeHH37ohnPqeTXMVPMfePMv7K9dvOUMX0fKO+ywNNHaQsOlrrjiCtcOWm4t/+effx51uKDmnNCwLA0TDF/Wsta98OfRdqj5IjSuP5KGlenz1jwF0Wheicj5FSJNmTLFPebVV18t9TFaz/RaWne1LJonRNtv5Ofp7QO0rmh+Cm3vmmdBY+XDh+OFr48aRtmmTRu3Xmv9jhyiGcuwQ9F2pG1Un6eeS6+r/c6YMWNCW7ZsKX6clkPzQ2gYptpO7ao2jmXYoaidNO5eY/8j17NYttH9mTNnjntezc0ROWQwnvcp2l95y6PHqc3mzZtX/HfNN6B1UJ+TXjO8Tb/66iv3Geoz1z5Q+y4No9zftlEa7Re8oZXhw4RFcyToedR+QZCl/yQ7lABAKlN1Rd/uNUIgsr9CJFUCNTxx/PjxCVs+IBb0IQAAAAQCAABAIAAAADqdlag+BLqE5ciRI10P/liHugAAgDTqQ6AhHxpS1aFDh0S8HAAACFog0Dh2jSnVWHZvXmoAABAsvk9MpOE1mq1KF8vRJBBl0aQs4bNdaaYpzSGvSU/8nhMcAIBUp14AuhaEJmKKdyIlXwPBjBkz3PScOmUQC80iFe9MXQAAoCRNh13a1V8THgi0MOpAqOlZw+ekLos6Hd54443Fv2uKTV1gRxf90BSS8J+maNXUoN27d486nSto71TG+k2bp7uffvrJXRa6tEuYJyUQrFixwl2j+phjjim+T3NP5+XluRm6dGog8iIemnNat0gKA5FzpcO/HaYuMqL2JhD4j/ZOLNo78Wjz5CjPaXbfAoEuUxl5vWddAEMXi9F15eO5ohcAAPCXb4FA5Qpd0SucrpClb56R9wMAgOTiWgYAAMD/YYfhFi5cSJMDAPahPmbqb4D9y87OjntIYeACAQAAkePm161bZ5s3b6ZhYqQw0LJlSxcMKhKBAACQNF4YaNiwoRvhxCR0ZdOEfWvWrLG1a9e6YfkV2V4EAgBA0k4TeGGAoeWxa9CggQsFu3btqtDh4XQqBAAkhddnQJUBxM47VaBAVZEIBACApOI0QTDai0AAAADoQwAACJ7Vq802bEjc69Wvb9a8uWU0OhUCAAIXBtq2NSsoSNxrVqtmtmpVZocCThkAAAJFlYFEhgEpKEhsRSKICAQAAJRjPoBx48a5CYKqV69uHTt2tJdeeslSGacMAACIk8LAtGnT7IknnrA2bdpYXl6eDRgwwM0R8O2339qoUaNs9erVbibGVEEgAAAgDoWFhXbPPffY22+/bV27dnX3tWrVyt59912bOHGijR071pYvX+4mXEolBAIAAOLw5ZdfWn5+vvXs2bPE/Tt37rROnTq50wipiEAAAEActm/f7n7OmTPHmjZtWuJvOTk5lqoIBAAAxKF9+/buwK8+AqeeeqqlCwIBAABxqFWrlt188812ww03uNEGJ510km3ZssXee+89q127tg0cONBSEcMOAQCI0913321/+MMf3GiDX/ziF9a7d293CkH9B15++WVr3bq1e5x+vvjii5YKqBAAAAJF0whr5sBEz1RYv358FxgaPny4u0Vz/vnnW6ohEAAAAkXTB2saYa5lkFgEAgBAIENBJl9XIBnoQwAAAAgEAACAQAAAAAgEAACAQAAAABw6FQIAAAIBAABgHgIAQACt3rLaNuRvSNjr1c+tb83rZPbEB0xMBAAIXBhoO76tFexK3NzF1apUs1VDV2V0KKAPAQAgUFQZSGQYkIJdBQmtSAQRgQAAgDjpsse60qGubli9enXr2LGjvfTSS5bKOGUAAECcFAamTZtmTzzxhLVp08by8vJswIAB1qBBA3vuuefsk08+sW3bttmIESNs0KBBlgoIBAAAxKGwsNDuuecee/vtt61r167uvlatWtm7775rEydOtLFjx7rKwcaNG+3www+3iy++2FURgo5AAABAHL788kvLz8+3nj17lrh/586d1qlTJxcGpFKlvWflQ6GQpQICAQAAcdi+fbv7OWfOHGvatGmJv+Xk5BT//2233WaDBw+23NxcSwUEAgAA4tC+fXt34F+9erWdeuqpUR8zffp0++CDD2zx4sWWKggEAADEoVatWnbzzTfbDTfc4EYbnHTSSbZlyxZ77733rHbt2tauXTsbNWqULViwICX6DngIBAAAxOnuu+92Iwo02uDrr7+2unXr2jHHHGO33367XXnlle4xGnUgkydPLu5XEGQEAgBAoGgaYc0cmOiZCuvn1o/58VlZWTZ8+HB3i7Ry5UpLRQQCAECgaPpgTSPMtQwSi0AAAAhkKMjk6wokA1MXAwAAAgEAACAQAAAAAgEAACAQAAAAh06FAACAQAAAAJiHAAAQRKtXm23YkLjXq1/frHlmz3vAxEQAgOCFgbZtzQoSN3WxVatmtmpV3KFAVzPUxY169+7tLoecyuhDAAAIFlUGEhkGpKCgXBWJp59+2oYNG2Z5eXm2Zs0aS2UEAgAAymH79u02c+ZMGzJkiPXp08emTJlS5uMLCwvdZZObNm1qNWrUsC5dutjChQstKAgEAACUwwsvvGDt2rWztm3buksdT5o0yUKhUKmPHzp0qDvFMGPGDPvHP/5hF154oTvV8MUXX7i/61LKjRo1shYtWlgyEAgA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\", \"__metadata__\": {\"image/png\": {\"width\": 516, \"height\": 528}}}"}, "type": "data"}]}, {"code_hash": "8322b0c7aaa842391144fc9c12faf32e", "console": [], "id": "MJUe", "outputs": [{"data": {"text/markdown": "\u003Cspan class=\"markdown prose dark:prose-invert contents\"\u003E\u003Ch2 id=\"understanding-linear-transformations-through-matrices\"\u003EUnderstanding Linear Transformations Through Matrices\u003C/h2\u003E\n\u003Cspan class=\"paragraph\"\u003EConsider a 2\u00d72 matrix \u003Cmarimo-tex class=\"arithmatex\"\u003E||(A||)\u003C/marimo-tex\u003E:\u003C/span\u003E\n\u003Cmarimo-tex class=\"arithmatex\"\u003E||[A = \begin{bmatrix} 2 \u0026amp; 1 \\ 1 \u0026amp; 2 \\end{bmatrix}||]\u003C/marimo-tex\u003E\u003Cspan class=\"paragraph\"\u003EThis matrix transforms the standard basis vectors:\u003C/span\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cmarimo-tex class=\"arithmatex\"\u003E||(e_1 = \begin{bmatrix} 1 \\ 0 \\end{bmatrix}||)\u003C/marimo-tex\u003E becomes \u003Cmarimo-tex class=\"arithmatex\"\u003E||(A \\cdot e_1 = \begin{bmatrix} 2 \\ 1 \\end{bmatrix}||)\u003C/marimo-tex\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Cmarimo-tex class=\"arithmatex\"\u003E||(e_2 = \begin{bmatrix} 0 \\ 1 \\end{bmatrix}||)\u003C/marimo-tex\u003E becomes \u003Cmarimo-tex class=\"arithmatex\"\u003E||(A \\cdot e_2 = \begin{bmatrix} 1 \\ 2 \\end{bmatrix}||)\u003C/marimo-tex\u003E\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cspan class=\"paragraph\"\u003EThe columns of \u003Cmarimo-tex class=\"arithmatex\"\u003E||(A||)\u003C/marimo-tex\u003E represent where the basis vectors land after transformation.\u003C/span\u003E\n\u003Cspan class=\"paragraph\"\u003ELet's see how this applies to a specific vector \u003Cmarimo-tex class=\"arithmatex\"\u003E||(x||)\u003C/marimo-tex\u003E:\u003C/span\u003E\n\u003Cmarimo-tex class=\"arithmatex\"\u003E||[x = \begin{bmatrix} 1 \\ 0 \\end{bmatrix}||]\u003C/marimo-tex\u003E\u003Cspan class=\"paragraph\"\u003EApplying our transformation:\u003C/span\u003E\n\u003Cmarimo-tex class=\"arithmatex\"\u003E||[Ax = \begin{bmatrix} 2 \u0026amp; 1 \\ 1 \u0026amp; 2 \\end{bmatrix} \begin{bmatrix} 1 \\ 0 \\end{bmatrix} = \begin{bmatrix} 2 \\ 1 \\end{bmatrix}||]\u003C/marimo-tex\u003E\u003C/span\u003E"}, "type": "data"}]}, {"code_hash": "80cfde1afbe2aff8909f846263aef8ae", "console": [{"mimetype": "text/plain", "name": "stdout", "text": "Original vector: [1 1]\nA(x): [3 3]\nB(A(x)): [3 9]\n(BA)(x): [3 9]\nAre they equal? True\n", "type": "stream"}], "id": "vblA", "outputs": [{"data": {"text/plain": ""}, "type": "data"}]}, {"code_hash": "1a5b5ebd430135bb72ec3679e4657802", "console": [{"mimetype": "text/plain", "name": "stdout", "text": "Matrix A: [[2 1]\n [1 2]]\nDeterminant of A: 2.9999999999999996\n", "type": "stream"}], "id": "bkHC", "outputs": [{"data": {"text/plain": ""}, "type": "data"}]}, {"code_hash": "5d75f5daca220d202aa977523901ae91", "console": [], "id": "lEQa", "outputs": [{"data": {"application/vnd.marimo+mimebundle": "{\"image/png\": \"data:image/png;base64,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tmyZtGzZ0syrtpGOB9HvVpcHdeyxxxbY9toPNBzpyl4/80cffSRjx46VL7/8UqZNmxYzrX5+nU77V58+feTZZ581baA/NvrDXxANDueee675EdLn6rzqj5z+sGp/Hj9+fMz0Glz0e9Hl4qCDDpJ///vfcsEFF8iGDRvM+qMgybSR0zQ86OufcMIJ5sdUd0doINT1iX4Piej3ouHy5ZdfNp/d3h1c0LpCg4GGYB1Toct59PIUT5fV008/3bTVP//5T9N3dbmeN29esT9jqu36XILlP9l1kefpmAqUreeee043PRLeKlSoEDNt/fr1re7du+/3GjrttddeG/PY6NGjrQMOOMD66quvYh6//fbbrYyMDGvDhg3m/rx588zz//nPf+73uvn5+ZH/62v16dMnqc/00EMPmdd88cUXI4/t3r3bateunXXggQda27dvL/IzJZLMtDqPOp1t3bp1Zl4OO+ww6+eff448/sYbb5jH33rrrchjp59+utW8eXPrt99+i2mD9u3bW0cddVTkMf37vn37Yt5X30e/r1GjRkUee//99817NGzY0MrNzbVS8fHHH5vn6vIRv6ycfPLJ1t69e2OmT/T6S5YsMdM///zz+71G586dY77fG2+80SwXW7duNfenTZtmptP5SPU7Sfb7t7+bKlWqWJs3b455jeHDh5u/XX311ZHH9DPXrVvXSktLs+65557I47/88otVqVKlmOVTp83Ly4t5TZ2uRo0aVt++fSOP/fTTT+Z99P3i2fNg+/TTT839/v37x0x38803m8e1L0W3iz62cOHCyGP6GXUZuemmmwppUcuaPn26ee5dd90V8/iFF15oPvvatWsjj+l05cuXj3nss88+M48//PDDhb5Psm1UnP6YaPnV70cfi+4jqlWrVtZxxx0X81j8d3L//febx3SZScawYcPM9LreOvPMM60xY8ZYK1as2G86e1mdMmVK5LFdu3ZZjRo1Mo9rH47+vInWgR06dDC3VNt1XSHLf7LrIq9j94eLdPfF3LlzY24zZ84s9uvplqGW3HRrVCsg9k0HdOrWwsKFC810mnp1y123WOMV93C6GTNmmJK0JnWbVgN0S0APQdTyfVnTLV5tC5s9+FGrDvYuDd060dHhumVht9f//d//mS2Mr7/+2mwlKt2asMdEaFvqNFrK1RL1ypUr93tv3UrVLSen6NZP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WF5KomXLllKrVi3p0qWLfPjhhxJk27ZtM/8eeuihBU4TxuUlmXYJ2/pl37598sorr5jqje4G8cqyQqgowpYtW8yXV6NGjZjH9X5B+3b18VSmD0u7NG7cWJ599ll544035MUXXzRXjG3fvr18//33EmYFLS96tcFff/1VwkqDxMSJE+W1114zN/2h6Nixo9nVFkTaH3TX10knnSTNmjUrcLowrF+K0y5hWb9kZWXJgQceaMZfXXPNNTJt2jQ55phjPLOshO4qpXCPpunoRK0dvkmTJvLEE0/I6NGj+Wqw34+E3qKXl2+++UbGjx8vL7zwQuBaS8cQ6L7uRYsWuT0rvmyXsKxfGjdubMZeafXm1VdflT59+pgxKAUFi7JGpaII1apVk4yMDMnJyYl5XO/XrFkz4XP08VSmD0u7xMvMzJRWrVrJ2rVrJcwKWl500FmlSpVcmy8vatu2bSCXl0GDBsnbb78t77//vhmMV5gwrF+K0y5hWb+UL1/eHCF23HHHmaNkdPDzhAkTPLOsECqS+AL1y3vvvfcij2lZTe8XtB9LH4+eXukI5oKmD0u7xNPdJ1rK0zJ3mIVheXGKbqEFaXnRMav6w6kl7Hnz5kmDBg2KfE4YlpfitEtY1y/5+fmSl5fnnWWl1IaABsgrr7xiVahQwZo0aZL1xRdfWFdffbV18MEHW5s2bTJ/v/zyy63bb789Mv2HH35olStXzho3bpz15ZdfWsOHD7cyMzOtrKwsK8ztMnLkSGv27NnWN998Y61YscL6+9//blWsWNFatWqVFSQ7duywPvnkE3PTLvbggw+a/69fv978XdtE28b27bffWpUrV7ZuueUWs7w8+uijVkZGhjVr1iwrzO0yfvx4a/r06dbXX39t+s71119vpaenW++++64VFAMHDjRHLMyfP9/auHFj5JabmxuZJozrl+K0SxjWL7fffrs5AmbdunXW559/bu6npaVZc+bM8cyyQqhI0sMPP2wdccQRVvny5c2hlEuXLo38rUOHDlafPn1ipp8yZYr117/+1Uyvhwu+8847Vtjb5YYbbohMW6NGDeuss86yVq5caQWNfShk/M1uC/1X2yb+OS1btjRt07BhQ3N4XNjb5d5777X+8pe/mB+GQw891OrYsaM1b948K0gStYfeor//MK5fitMuYVi/9O3b16pfv775jIcffrh1+umnRwKFV5YVLn0OAAAcwZgKAADgCEIFAABwBKECAAA4glABAAAcQagAAACOIFQAAABHECoAAIAjCBUAAMARhAoAAOAIQgUA1+hFn/QS1eeff37M43pZ53r16smdd97p2rwBSB2n6Qbgqq+++kpatmwpTz31lFx66aXmsd69e8tnn30mH3/8sbkiLgB/IFQAcN2///1vGTFihKxatUqWLVsmPXv2NIGiRYsWbs8agBQQKgC4Ti9Medppp0lGRoZkZWXJddddJ0OHDnV7tgCkiFABwBNWr14tTZo0kebNm8vKlSulXLlybs8SgBQxUBOAJzz77LNSuXJlWbdunXz//fduzw6AYqBSAcB1ixcvlg4dOsicOXPkrrvuMo+9++67kpaW5vasAUgBlQoArsrNzZUrrrhCBg4cKJ06dZJnnnnGDNacOHEi3wzgM1QqALjq+uuvlxkzZphDSHX3h3riiSfk5ptvNoM2jzzySL4hwCcIFQBcs2DBAjn99NNl/vz5cvLJJ8f8rVu3brJ37152gwA+QqgAAACOYEwFAABwBKECAAA4glABAAAcQagAAACOIFQAAABHECoAAIAjCBUAAMARhAoAAOAIQgUAAHAEoQIAADiCUAEAAMQJ/w+IUohuahbjeAAAAABJRU5ErkJggg==\", \"__metadata__\": {\"image/png\": {\"width\": 533, \"height\": 547}}}"}, "type": "data"}]}, {"code_hash": null, "console": [], "id": "PKri", "outputs": [{"data": {"text/plain": ""}, "type": "data"}]}], "metadata": {"marimo_version": "0.23.3", "script_metadata_hash": null}, "version": "1"},
"runtimeConfig": null,
}),
writable: false,
configurable: false,
});
</script>
<marimo-code hidden="">
import%20marimo%0A%0A__generated_with%20%3D%20%220.23.3%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%0A%20%20%20%20%23%20Matrix%20Multiplication%20as%20Linear%20Transformations%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%20Matrix%20Multiplication%20as%20Linear%20Transformations%0A%0A%20%20%20%20In%20this%20interactive%20exploration%2C%20we'll%20understand%20how%20matrix%20multiplication%20relates%20to%20linear%20transformations.%0A%0A%20%20%20%20%23%23%20Key%20Concepts%0A%20%20%20%20-%20**Linear%20Transformation**%3A%20A%20function%20that%20maps%20vectors%20to%20vectors%20while%20preserving%20vector%20addition%20and%20scalar%20multiplication%0A%20%20%20%20-%20**Matrix%20Multiplication**%3A%20Represents%20the%20composition%20of%20linear%20transformations%0A%20%20%20%20-%20**Basis%20Vectors**%3A%20Standard%20vectors%20that%20span%20a%20vector%20space%0A%20%20%20%20-%20**Determinant**%3A%20Measures%20how%20much%20a%20transformation%20scales%20area%2Fvolume%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20%23%20Show%20basic%20matrix-vector%20multiplication%0A%20%20%20%20_A%20%3D%20np.array(%5B%5B2%2C%201%5D%2C%20%5B1%2C%202%5D%5D)%0A%20%20%20%20_x%20%3D%20np.array(%5B1%2C%200%5D)%0A%0A%20%20%20%20%23%20Apply%20transformation%0A%20%20%20%20_Ax%20%3D%20_A%20%40%20_x%0A%0A%20%20%20%20%23%20Create%20visualization%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots(figsize%3D(8%2C%206))%0A%0A%20%20%20%20%23%20Plot%20original%20basis%20vectors%0A%20%20%20%20_ax.arrow(0%2C%200%2C%201%2C%200%2C%20head_width%3D0.05%2C%20head_length%3D0.05%2C%20fc%3D%22blue%22%2C%20ec%3D%22blue%22%2C%20label%3D%22e%E2%82%81%22)%0A%20%20%20%20_ax.arrow(0%2C%200%2C%200%2C%201%2C%20head_width%3D0.05%2C%20head_length%3D0.05%2C%20fc%3D%22green%22%2C%20ec%3D%22green%22%2C%20label%3D%22e%E2%82%82%22)%0A%0A%20%20%20%20%23%20Plot%20transformed%20basis%20vectors%0A%20%20%20%20_ax.arrow(0%2C%200%2C%20_A%5B0%2C%200%5D%2C%20_A%5B1%2C%200%5D%2C%20head_width%3D0.05%2C%20head_length%3D0.05%2C%20fc%3D%22red%22%2C%20ec%3D%22red%22%2C%20label%3D%22A%C2%B7e%E2%82%81%22)%0A%20%20%20%20_ax.arrow(0%2C%200%2C%20_A%5B0%2C%201%5D%2C%20_A%5B1%2C%201%5D%2C%20head_width%3D0.05%2C%20head_length%3D0.05%2C%20fc%3D%22orange%22%2C%20ec%3D%22orange%22%2C%20label%3D%22A%C2%B7e%E2%82%82%22)%0A%0A%20%20%20%20%23%20Plot%20input%20vector%0A%20%20%20%20_ax.arrow(0%2C%200%2C%20_x%5B0%5D%2C%20_x%5B1%5D%2C%20head_width%3D0.05%2C%20head_length%3D0.05%2C%20fc%3D%22purple%22%2C%20ec%3D%22purple%22%2C%20label%3D%22x%22)%0A%0A%20%20%20%20%23%20Plot%20output%20vector%0A%20%20%20%20_ax.arrow(0%2C%200%2C%20_Ax%5B0%5D%2C%20_Ax%5B1%5D%2C%20head_width%3D0.05%2C%20head_length%3D0.05%2C%20fc%3D%22brown%22%2C%20ec%3D%22brown%22%2C%20label%3D%22Ax%22)%0A%0A%20%20%20%20_ax.set_xlim(-1%2C%204)%0A%20%20%20%20_ax.set_ylim(-1%2C%204)%0A%20%20%20%20_ax.grid(True)%0A%20%20%20%20_ax.legend()%0A%20%20%20%20_ax.set_aspect(%22equal%22)%0A%20%20%20%20_ax.set_title(%22Linear%20Transformation%3A%20Matrix%20A%20applied%20to%20Vector%20x%22)%0A%20%20%20%20return%20mo%2C%20np%2C%20plt%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20%23%20Demonstrate%20matrix%20multiplication%20as%20transformation%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Understanding%20Linear%20Transformations%20Through%20Matrices%0A%0A%20%20%20%20Consider%20a%202%C3%972%20matrix%20%24A%24%3A%0A%20%20%20%20%24%24A%20%3D%20%08egin%7Bbmatrix%7D%202%20%26%201%20%5C%201%20%26%202%20%5Cend%7Bbmatrix%7D%24%24%0A%0A%20%20%20%20This%20matrix%20transforms%20the%20standard%20basis%20vectors%3A%0A%20%20%20%20-%20%24e_1%20%3D%20%08egin%7Bbmatrix%7D%201%20%5C%200%20%5Cend%7Bbmatrix%7D%24%20becomes%20%24A%20%5Ccdot%20e_1%20%3D%20%08egin%7Bbmatrix%7D%202%20%5C%201%20%5Cend%7Bbmatrix%7D%24%0A%20%20%20%20-%20%24e_2%20%3D%20%08egin%7Bbmatrix%7D%200%20%5C%201%20%5Cend%7Bbmatrix%7D%24%20becomes%20%24A%20%5Ccdot%20e_2%20%3D%20%08egin%7Bbmatrix%7D%201%20%5C%202%20%5Cend%7Bbmatrix%7D%24%0A%0A%20%20%20%20The%20columns%20of%20%24A%24%20represent%20where%20the%20basis%20vectors%20land%20after%20transformation.%0A%0A%20%20%20%20Let's%20see%20how%20this%20applies%20to%20a%20specific%20vector%20%24x%24%3A%0A%20%20%20%20%24%24x%20%3D%20%08egin%7Bbmatrix%7D%201%20%5C%200%20%5Cend%7Bbmatrix%7D%24%24%0A%0A%20%20%20%20Applying%20our%20transformation%3A%0A%20%20%20%20%24%24Ax%20%3D%20%08egin%7Bbmatrix%7D%202%20%26%201%20%5C%201%20%26%202%20%5Cend%7Bbmatrix%7D%20%08egin%7Bbmatrix%7D%201%20%5C%200%20%5Cend%7Bbmatrix%7D%20%3D%20%08egin%7Bbmatrix%7D%202%20%5C%201%20%5Cend%7Bbmatrix%7D%24%24%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20np)%3A%0A%20%20%20%20%23%20Interactive%20demonstration%20of%20composition%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Composition%20of%20Transformations%0A%0A%20%20%20%20Matrix%20multiplication%20corresponds%20to%20applying%20transformations%20in%20sequence.%0A%0A%20%20%20%20If%20we%20have%20two%20transformations%3A%0A%20%20%20%20-%20%24A%20%3D%20%5Cbegin%7Bbmatrix%7D%202%20%26%201%20%5C%5C%201%20%26%202%20%5Cend%7Bbmatrix%7D%24%0A%20%20%20%20-%20%24B%20%3D%20%5Cbegin%7Bbmatrix%7D%201%20%26%200%20%5C%5C%200%20%26%203%20%5Cend%7Bbmatrix%7D%24%0A%0A%20%20%20%20Applying%20%24B%24%20after%20%24A%24%20is%20equivalent%20to%20multiplying%20matrices%20%24BA%24%3A%0A%0A%20%20%20%20%24%24(BA)x%20%3D%20B(Ax)%24%24%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20%23%20Example%20of%20composition%0A%20%20%20%20_A%20%3D%20np.array(%5B%5B2%2C%201%5D%2C%20%5B1%2C%202%5D%5D)%0A%20%20%20%20_B%20%3D%20np.array(%5B%5B1%2C%200%5D%2C%20%5B0%2C%203%5D%5D)%0A%0A%20%20%20%20%23%20Calculate%20BA%0A%20%20%20%20_BA%20%3D%20_B%20%40%20_A%0A%0A%20%20%20%20%23%20Test%20with%20a%20vector%0A%20%20%20%20_x%20%3D%20np.array(%5B1%2C%201%5D)%0A%0A%20%20%20%20%23%20Apply%20transformations%20sequentially%0A%20%20%20%20_Ax%20%3D%20_A%20%40%20_x%0A%20%20%20%20_BAx%20%3D%20_BA%20%40%20_x%0A%0A%20%20%20%20%23%20Compare%20with%20direct%20multiplication%0A%20%20%20%20_result_direct%20%3D%20_B%20%40%20_Ax%0A%0A%20%20%20%20print(f%22Original%20vector%3A%20%7B_x%7D%22)%0A%20%20%20%20print(f%22A(x)%3A%20%7B_Ax%7D%22)%0A%20%20%20%20print(f%22B(A(x))%3A%20%7B_result_direct%7D%22)%0A%20%20%20%20print(f%22(BA)(x)%3A%20%7B_BAx%7D%22)%0A%20%20%20%20print(f%22Are%20they%20equal%3F%20%7Bnp.allclose(_result_direct%2C%20_BAx)%7D%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20np)%3A%0A%20%20%20%20%23%20Introduce%20determinant%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Determinant%3A%20Measuring%20Scaling%20Factor%0A%0A%20%20%20%20The%20determinant%20of%20a%20transformation%20matrix%20tells%20us%20how%20much%20area%20(in%202D)%20or%20volume%20(in%203D)%20is%20scaled.%0A%0A%20%20%20%20For%20a%202%C3%972%20matrix%3A%0A%20%20%20%20%24%24%5Ctext%7Bdet%7D(A)%20%3D%20%5Cbegin%7Bvmatrix%7D%20a%20%26%20b%20%5C%5C%20c%20%26%20d%20%5Cend%7Bvmatrix%7D%20%3D%20ad%20-%20bc%24%24%0A%0A%20%20%20%20Example%20with%20our%20matrix%3A%0A%20%20%20%20%24%24A%20%3D%20%5Cbegin%7Bbmatrix%7D%202%20%26%201%20%5C%5C%201%20%26%202%20%5Cend%7Bbmatrix%7D%24%24%0A%0A%20%20%20%20%24%24%5Ctext%7Bdet%7D(A)%20%3D%202%20%5Ccdot%202%20-%201%20%5Ccdot%201%20%3D%204%20-%201%20%3D%203%24%24%0A%0A%20%20%20%20This%20means%20the%20transformation%20scales%20the%20area%20by%20a%20factor%20of%203.%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20%23%20Calculate%20determinant%0A%20%20%20%20_A%20%3D%20np.array(%5B%5B2%2C%201%5D%2C%20%5B1%2C%202%5D%5D)%0A%20%20%20%20_det_A%20%3D%20np.linalg.det(_A)%0A%0A%20%20%20%20print(f%22Matrix%20A%3A%20%7B_A%7D%22)%0A%20%20%20%20print(f%22Determinant%20of%20A%3A%20%7B_det_A%7D%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20np%2C%20plt)%3A%0A%20%20%20%20%23%20Visualize%20how%20determinant%20affects%20area%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Visualizing%20the%20Effect%20of%20Determinants%0A%0A%20%20%20%20The%20determinant%20tells%20us%20how%20the%20transformation%20changes%20the%20area%20of%20shapes.%0A%0A%20%20%20%20Let's%20consider%20a%20unit%20square%20with%20corners%20at%20(0%2C0)%2C%20(1%2C0)%2C%20(1%2C1)%2C%20(0%2C1).%0A%0A%20%20%20%20After%20applying%20transformation%20%24A%24%2C%20we%20get%20a%20parallelogram.%0A%0A%20%20%20%20With%20determinant%20%3D%203%2C%20the%20area%20is%20multiplied%20by%203.%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20%23%20Define%20unit%20square%20corners%0A%20%20%20%20_square%20%3D%20np.array(%5B%5B0%2C%200%5D%2C%20%5B1%2C%200%5D%2C%20%5B1%2C%201%5D%2C%20%5B0%2C%201%5D%2C%20%5B0%2C%200%5D%5D)%20%20%23%20Closing%20the%20shape%0A%0A%20%20%20%20%23%20Apply%20transformation%0A%20%20%20%20_A%20%3D%20np.array(%5B%5B2%2C%201%5D%2C%20%5B1%2C%202%5D%5D)%0A%20%20%20%20_transformed_square%20%3D%20_square%20%40%20_A.T%0A%0A%20%20%20%20%23%20Plot%0A%20%20%20%20_fig%2C%20_ax%20%3D%20plt.subplots(figsize%3D(8%2C%206))%0A%0A%20%20%20%20%23%20Plot%20original%20square%0A%20%20%20%20_ax.plot(_square%5B%3A%2C%200%5D%2C%20_square%5B%3A%2C%201%5D%2C%20%22b-%22%2C%20linewidth%3D2%2C%20label%3D%22Original%20Square%22)%0A%0A%20%20%20%20%23%20Plot%20transformed%20square%0A%20%20%20%20_ax.plot(_transformed_square%5B%3A%2C%200%5D%2C%20_transformed_square%5B%3A%2C%201%5D%2C%20%22r-%22%2C%20linewidth%3D2%2C%20label%3D%22Transformed%20Square%22)%0A%0A%20%20%20%20%23%20Add%20grid%20and%20labels%0A%20%20%20%20_ax.grid(True)%0A%20%20%20%20_ax.legend()%0A%20%20%20%20_ax.set_aspect(%22equal%22)%0A%20%20%20%20_ax.set_title(%22Effect%20of%20Linear%20Transformation%20on%20a%20Unit%20Square%22)%0A%20%20%20%20_ax.set_xlabel(%22X%22)%0A%20%20%20%20_ax.set_ylabel(%22Y%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
</marimo-code>
<marimo-code-hash hidden="">15d7e87338fe5141226560929c452f0f</marimo-code-hash>
</body>
</html>