{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# APSG tutorial - Part 2" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:58.585253Z", "iopub.status.busy": "2026-05-26T10:13:58.585146Z", "iopub.status.idle": "2026-05-26T10:13:59.185049Z", "shell.execute_reply": "2026-05-26T10:13:59.184367Z" }, "tags": [] }, "outputs": [], "source": [ "from apsg import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Matrix like classes and tensors\n", "**APSG** provides matrix-like classes to work with tensor quantities used commonly in structural geology analysis. It includes `DeformationGradient3` and `VelocityGradient3` for deformation and velocity gradient, `Stress3` for stress tensor, `Ellipsoid` for quadratic forms and `OrientationTensor3` for orientation tensor. All these classes support common matrix mathematical operations and provide basic methods and properties.\n", "\n", "All matrix-like objects could be created either by passing nested list or tuple or providing individual components to class method `from_comp`" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.186512Z", "iopub.status.busy": "2026-05-26T10:13:59.186368Z", "iopub.status.idle": "2026-05-26T10:13:59.189431Z", "shell.execute_reply": "2026-05-26T10:13:59.189129Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "DeformationGradient3\n", "[[2. 0. 1. ]\n", " [0. 1. 0. ]\n", " [0. 0. 0.5]]" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "F = defgrad([[2, 0, 1], [0, 1, 0], [0, 0, 0.5]])\n", "F" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.205367Z", "iopub.status.busy": "2026-05-26T10:13:59.205289Z", "iopub.status.idle": "2026-05-26T10:13:59.207524Z", "shell.execute_reply": "2026-05-26T10:13:59.207184Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "DeformationGradient3\n", "[[2. 0. 1. ]\n", " [0. 1. 0. ]\n", " [0. 0. 0.5]]" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "F = defgrad.from_comp(xx=2, zz=0.5, xz=1)\n", "F" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For multiplications of matrix or vectors we have to use matmul `@` operator" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.208513Z", "iopub.status.busy": "2026-05-26T10:13:59.208446Z", "iopub.status.idle": "2026-05-26T10:13:59.210434Z", "shell.execute_reply": "2026-05-26T10:13:59.210112Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "Vector3(1, 0, 0.5)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v = vec('z') # unit-length vector in direction af axis z\n", "u = F @ v\n", "u" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The ``I`` property returns the inverse matrix" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.211337Z", "iopub.status.busy": "2026-05-26T10:13:59.211273Z", "iopub.status.idle": "2026-05-26T10:13:59.213220Z", "shell.execute_reply": "2026-05-26T10:13:59.212925Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "Vector3(0, 0, 1)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "F.I @ u" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To transpose matrix, we can use `T` property and for multiplication we have to use `@` operator" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.214177Z", "iopub.status.busy": "2026-05-26T10:13:59.214108Z", "iopub.status.idle": "2026-05-26T10:13:59.216068Z", "shell.execute_reply": "2026-05-26T10:13:59.215763Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "DeformationGradient3\n", "[[4. 0. 2. ]\n", " [0. 1. 0. ]\n", " [2. 0. 1.25]]" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "F.T @ F" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.216733Z", "iopub.status.busy": "2026-05-26T10:13:59.216664Z", "iopub.status.idle": "2026-05-26T10:13:59.218551Z", "shell.execute_reply": "2026-05-26T10:13:59.218254Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "1.25" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v @ F.T @ F @ v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Eigenvalues and eigenvectors are obtained with the methods `eigenvalues` and `eigenvectors`. Individual eigenvalues and eigenvectors could be accessed by properties `E1`, `E2`, `E3` and `V1`, `V2`, `V3`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Deformation gradient and rotations\n", "\n", "The deformation gradient `DeformationGradient3` could describe distortion, dilation, and rigid-body rotation. All **APSG** features provide a `transform` method that applies the provided deformation gradient to them.\n", "\n", "The rigid-body rotation `Rotation3` could be either extracted from the deformation gradient using the `R` method:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.219317Z", "iopub.status.busy": "2026-05-26T10:13:59.219253Z", "iopub.status.idle": "2026-05-26T10:13:59.221475Z", "shell.execute_reply": "2026-05-26T10:13:59.221172Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "Rotation3\n", "[[ 0.928 0. 0.371]\n", " [ 0. 1. 0. ]\n", " [-0.371 0. 0.928]]" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R = F.R\n", "R" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or could be created by one of the `Rotation3` class methods like `from_axisangle`, defining axis of rotation and angle:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.222169Z", "iopub.status.busy": "2026-05-26T10:13:59.222100Z", "iopub.status.idle": "2026-05-26T10:13:59.224408Z", "shell.execute_reply": "2026-05-26T10:13:59.224100Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "Rotation3\n", "[[ 0.552 -0.753 0.359]\n", " [ 0.574 0.655 0.492]\n", " [-0.605 -0.065 0.793]]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R = rotation.from_axisangle(lin(120, 50), 60)\n", "R" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`from_two_vectors`, where axis of rotation is perpendicular to both vectors and angle is angle of vectors" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.225125Z", "iopub.status.busy": "2026-05-26T10:13:59.225055Z", "iopub.status.idle": "2026-05-26T10:13:59.227581Z", "shell.execute_reply": "2026-05-26T10:13:59.227201Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "Rotation3\n", "[[ 0.938 0.074 0.339]\n", " [ 0.186 0.718 -0.671]\n", " [-0.294 0.692 0.66 ]]" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R = rotation.from_two_vectors(lin(120, 50), lin(270, 80))\n", "R" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.228297Z", "iopub.status.busy": "2026-05-26T10:13:59.228229Z", "iopub.status.idle": "2026-05-26T10:13:59.229938Z", "shell.execute_reply": "2026-05-26T10:13:59.229648Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "L:270/80" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lin(120, 50).transform(R)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or by `from_vectors_axis`, where `axis` does not need to be perpendicular to vectors. Note that rotation axis needs to be adjusted to provide correct rotation of vector." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.230675Z", "iopub.status.busy": "2026-05-26T10:13:59.230612Z", "iopub.status.idle": "2026-05-26T10:13:59.232675Z", "shell.execute_reply": "2026-05-26T10:13:59.232432Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "Rotation3\n", "[[-0.393 -0.864 0.315]\n", " [ 0.864 -0.23 0.448]\n", " [-0.315 0.448 0.837]]" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R = rotation.from_vectors_axis(lin(45,30), lin(135, 30), lin(90, 70))\n", "R" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.233322Z", "iopub.status.busy": "2026-05-26T10:13:59.233258Z", "iopub.status.idle": "2026-05-26T10:13:59.234862Z", "shell.execute_reply": "2026-05-26T10:13:59.234630Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "L:135/30" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lin(45,30).transform(R)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.235499Z", "iopub.status.busy": "2026-05-26T10:13:59.235433Z", "iopub.status.idle": "2026-05-26T10:13:59.237086Z", "shell.execute_reply": "2026-05-26T10:13:59.236851Z" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "L:90/70 113.11571469196133\n" ] } ], "source": [ "a, ang = R.axisangle()\n", "print(lin(a), ang)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`from_two_pairs` method, to describe rotation between two coordinate systems. Note that pair defines the X axis as lineation vector and Z axis as foliation vector." ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.237757Z", "iopub.status.busy": "2026-05-26T10:13:59.237694Z", "iopub.status.idle": "2026-05-26T10:13:59.240329Z", "shell.execute_reply": "2026-05-26T10:13:59.240075Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "Rotation3\n", "[[-0.071 0.97 0.234]\n", " [-0.874 -0.174 0.453]\n", " [ 0.48 -0.173 0.86 ]]" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p1 = pair(150, 60, 90, 40)\n", "p2 = pair(45, 30, 10, 25)\n", "R = rotation.from_two_pairs(p1, p2)\n", "R" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.240946Z", "iopub.status.busy": "2026-05-26T10:13:59.240880Z", "iopub.status.idle": "2026-05-26T10:13:59.242825Z", "shell.execute_reply": "2026-05-26T10:13:59.242522Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "P:45/30-10/25" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p1.transform(R)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Quaternion and Euler angles representation could be obtained by `quat` and `euler` methods:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.243483Z", "iopub.status.busy": "2026-05-26T10:13:59.243419Z", "iopub.status.idle": "2026-05-26T10:13:59.245147Z", "shell.execute_reply": "2026-05-26T10:13:59.244894Z" } }, "outputs": [ { "data": { "text/plain": [ "array([-0.24628826, -0.09662418, -0.72537752, 0.63547881])" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R.quat()" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.245766Z", "iopub.status.busy": "2026-05-26T10:13:59.245701Z", "iopub.status.idle": "2026-05-26T10:13:59.247499Z", "shell.execute_reply": "2026-05-26T10:13:59.247265Z" } }, "outputs": [ { "data": { "text/plain": [ "array([109.79936603, 30.68210123, 152.64165336])" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R.euler('zxz')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly, rotation could be defined by class methods `from_quat` and `from_euler`:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.248210Z", "iopub.status.busy": "2026-05-26T10:13:59.248144Z", "iopub.status.idle": "2026-05-26T10:13:59.249950Z", "shell.execute_reply": "2026-05-26T10:13:59.249713Z" } }, "outputs": [ { "data": { "text/plain": [ "L:40/30" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R = rotation.from_euler('zxz', [90, -20, -50])\n", "lin(0, 50).transform(R)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.250579Z", "iopub.status.busy": "2026-05-26T10:13:59.250506Z", "iopub.status.idle": "2026-05-26T10:13:59.252296Z", "shell.execute_reply": "2026-05-26T10:13:59.252060Z" } }, "outputs": [ { "data": { "text/plain": [ "L:163/50" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R = rotation.from_quat([0, 0, 1, 0.15])\n", "lin(0, 50).transform(R)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Ellipsoid\n", "\n", "In deformation analysis, the quadratic forms are represented by `Ellipsoid` class. It can be used to represent either ellipsoid objects or finite strain ellipsoid.\n", "\n", "It provides additional methods and properties including ``S1``, ``S2`` and ``S3`` for principal stretches, Woodcock's `shape` and `strength`, `k`, `K`, `d` and `D` for Flinn's and Ramsay symmetries and intensities, `lode` for Lode's parameter etc. For more check documentation. Eigenvectors could be also represented by linear or planar features using properties `eigenlins` and `eigenfols`.\n", "\n", "We can create `Ellipsoid` object similarly to `Matrix3` (note that only components of upper triangular part are available in `from_comp` method due to matrix symmetry), or you can use additional class methods `from_defgrad` and `from_stretch`." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.252935Z", "iopub.status.busy": "2026-05-26T10:13:59.252871Z", "iopub.status.idle": "2026-05-26T10:13:59.254713Z", "shell.execute_reply": "2026-05-26T10:13:59.254483Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "Ellipsoid\n", "[[5. 0. 0.5 ]\n", " [0. 1. 0. ]\n", " [0.5 0. 0.25]]\n", "(S1:2.25, S2:1, S3:0.445)" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "B = ellipsoid.from_defgrad(F) # Finger deformation tensor\n", "B" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the above example, the left Cauchy-Green deformation tensor (Finger tensor) `B` represents finite strain ellipsoid resulting from deformation described by deformation gradient `F`. We can explore several parameters:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.255554Z", "iopub.status.busy": "2026-05-26T10:13:59.255487Z", "iopub.status.idle": "2026-05-26T10:13:59.257495Z", "shell.execute_reply": "2026-05-26T10:13:59.257252Z" }, "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Principal stretches: Sx=2.247679020649623, Sy=1.0, Sz=0.44490338291762865\n", "Principal strain ratios: Rxy=2.247679020649623, Ryz=2.2476790206496235\n", "Flinn's finite strain parameters: d=1.7644845924910784, k=0.9999999999999997\n", "Ramsay's finite strain parameters: d=1.311869986019497, k=0.9999999999999998\n", "Woodcock's parameters: strength=1.6197962748565, shape=0.9999999999999998\n", "Watterson's strain intesity: s3.495358041299246\n", "Nadai's natural octahedral unit shear: 1.3225581202197993\n", "Nadai's natural octahedral unit strain: 1.1453689300917398\n", "Lode's parameter: 1.3708180983729115e-16\n" ] } ], "source": [ "print(f'Principal stretches: Sx={B.S1}, Sy={B.S2}, Sz={B.S3}')\n", "print(f'Principal strain ratios: Rxy={B.Rxy}, Ryz={B.Ryz}')\n", "print(f\"Flinn's finite strain parameters: d={B.d}, k={B.k}\")\n", "print(f\"Ramsay's finite strain parameters: d={B.D}, k={B.K}\")\n", "print(f\"Woodcock's parameters: strength={B.strength}, shape={B.shape}\")\n", "print(f\"Watterson's strain intesity: s{B.r}\")\n", "print(f\"Nadai's natural octahedral unit shear: {B.goct}\")\n", "print(f\"Nadai's natural octahedral unit strain: {B.eoct}\")\n", "print(f\"Lode's parameter: {B.lode}\")" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.258183Z", "iopub.status.busy": "2026-05-26T10:13:59.258118Z", "iopub.status.idle": "2026-05-26T10:13:59.260073Z", "shell.execute_reply": "2026-05-26T10:13:59.259827Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "Ellipsoid\n", "[[4. 0. 2. ]\n", " [0. 1. 0. ]\n", " [2. 0. 1.25]]\n", "(S1:2.25, S2:1, S3:0.445)" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "C = ellipsoid.from_defgrad(F, 'right') # Green's deformation tensor\n", "C" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.260737Z", "iopub.status.busy": "2026-05-26T10:13:59.260668Z", "iopub.status.idle": "2026-05-26T10:13:59.262201Z", "shell.execute_reply": "2026-05-26T10:13:59.261998Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "1.25" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "v @ C @ v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Orientation tensor\n", "`OrientationTensor3` class represents orientation tensor of set of vectors, linear or planar features. In addition to `Ellipsoid` methods and properties, it provides properties to describe orientation distribution, e.g. Vollmer's `P`, `G`, `R` and `B` indexes, `Intensity` for Lisle intensity index and `MAD` for approximate angular deviation." ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.262989Z", "iopub.status.busy": "2026-05-26T10:13:59.262920Z", "iopub.status.idle": "2026-05-26T10:13:59.267405Z", "shell.execute_reply": "2026-05-26T10:13:59.267110Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "OrientationTensor3\n", "[[ 0.192 -0.231 -0.224]\n", " [-0.231 0.419 0.365]\n", " [-0.224 0.365 0.389]]\n", "(S1:0.955, S2:0.221, S3:0.196)" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l = linset.random_fisher(position=lin(120,40))\n", "ot = l.ortensor()\n", "# or\n", "ot = ortensor.from_features(l)\n", "ot" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.268074Z", "iopub.status.busy": "2026-05-26T10:13:59.268007Z", "iopub.status.idle": "2026-05-26T10:13:59.270155Z", "shell.execute_reply": "2026-05-26T10:13:59.269640Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "array([0.91262888, 0.04881445, 0.03855667])" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ot.eigenvalues()" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.270893Z", "iopub.status.busy": "2026-05-26T10:13:59.270827Z", "iopub.status.idle": "2026-05-26T10:13:59.272881Z", "shell.execute_reply": "2026-05-26T10:13:59.272467Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "(Vector3(0.408, -0.658, -0.633),\n", " Vector3(-0.908, -0.367, -0.203),\n", " Vector3(0.099, -0.657, 0.747))" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ot.eigenvectors()" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.273674Z", "iopub.status.busy": "2026-05-26T10:13:59.273556Z", "iopub.status.idle": "2026-05-26T10:13:59.275851Z", "shell.execute_reply": "2026-05-26T10:13:59.275483Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "'L'" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ot.kind" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The instances of `Stress3`, `Ellipsoid` and `OrientationTensor3` also provides `eigenlins` and `eigenfols` properties to represent principal axes and planes" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.276763Z", "iopub.status.busy": "2026-05-26T10:13:59.276653Z", "iopub.status.idle": "2026-05-26T10:13:59.278981Z", "shell.execute_reply": "2026-05-26T10:13:59.278611Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "(L:122/39, L:22/12, L:279/48)" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ot.eigenlins()" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.279737Z", "iopub.status.busy": "2026-05-26T10:13:59.279631Z", "iopub.status.idle": "2026-05-26T10:13:59.281919Z", "shell.execute_reply": "2026-05-26T10:13:59.281553Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "(S:302/51, S:202/78, S:99/42)" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ot.eigenfols()" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.282726Z", "iopub.status.busy": "2026-05-26T10:13:59.282558Z", "iopub.status.idle": "2026-05-26T10:13:59.284736Z", "shell.execute_reply": "2026-05-26T10:13:59.284318Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "(1.5821000767831366, 12.413465963761936)" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ot.strength, ot.shape" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.285729Z", "iopub.status.busy": "2026-05-26T10:13:59.285605Z", "iopub.status.idle": "2026-05-26T10:13:59.288066Z", "shell.execute_reply": "2026-05-26T10:13:59.287652Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "(26.551404126662977, 3.326229198851815)" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ot.k, ot.d" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.288850Z", "iopub.status.busy": "2026-05-26T10:13:59.288741Z", "iopub.status.idle": "2026-05-26T10:13:59.290997Z", "shell.execute_reply": "2026-05-26T10:13:59.290624Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "(12.413465963761936, 2.157651309771469)" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ot.K, ot.D" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.291754Z", "iopub.status.busy": "2026-05-26T10:13:59.291649Z", "iopub.status.idle": "2026-05-26T10:13:59.293871Z", "shell.execute_reply": "2026-05-26T10:13:59.293525Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "(0.8638144222257628, 0.020515562232487156, 0.1156700155417504)" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ot.P, ot.G, ot.R" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "execution": { "iopub.execute_input": "2026-05-26T10:13:59.294727Z", "iopub.status.busy": "2026-05-26T10:13:59.294556Z", "iopub.status.idle": "2026-05-26T10:13:59.296755Z", "shell.execute_reply": "2026-05-26T10:13:59.296384Z" }, "tags": [] }, "outputs": [ { "data": { "text/plain": [ "17.192684016810322" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ot.MAD" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 4 }