diff --git a/notebooks/eigen_demo/eigen_demo.ipynb b/notebooks/eigen_demo/eigen_demo.ipynb index 5846f9ed..0df61ead 100644 --- a/notebooks/eigen_demo/eigen_demo.ipynb +++ b/notebooks/eigen_demo/eigen_demo.ipynb @@ -1,15 +1,34 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "6c9eda5c-bf2f-4bcd-8dee-bc7db08dd801", + "metadata": {}, + "source": [ + "### Here we include the **conda** installed library using Cppyy" + ] + }, { "cell_type": "code", "execution_count": 1, - "id": "75b390f9-3dc5-46b8-a1da-64e25730737e", + "id": "610a5fef-82f3-487e-8ec7-53f3c5276505", "metadata": {}, "outputs": [], "source": [ - "#include\n", - "#include\n", - "#include \"eigen-3.4.0/Eigen/Dense\"" + "%%python\n", + "\n", + "import py, os, sys\n", + "from pytest import mark, raises\n", + "\n", + "cppyy.include('/opt/conda/envs/.venv/include/eigen3/Eigen/Dense')" + ] + }, + { + "cell_type": "markdown", + "id": "22e7b3ed-747e-4bd5-8b89-4a6e5661dfbf", + "metadata": {}, + "source": [ + "### We are immediately able to use the `Eigen::Dense` namespaces in our C++ code cell" ] }, { @@ -26,6 +45,14 @@ "Eigen::Vector4d c;" ] }, + { + "cell_type": "markdown", + "id": "0766e5c0-2d3b-4ae4-96bd-4a78f3b02cc2", + "metadata": {}, + "source": [ + "### We can define a templated class with a set of vector operations offered by Eigen " + ] + }, { "cell_type": "code", "execution_count": 3, @@ -38,18 +65,17 @@ "public:\n", " static VectorType PerformOperations(const VectorType& v) {\n", " VectorType result = v;\n", + " \n", + " // Using Eigen::Dense object methods\n", + " \n", + " result.normalize(); // eigen vector normalisation\n", "\n", - " // Normalize the vector\n", - " result.normalize();\n", - "\n", - " // Add the dot product with itself\n", - " double dot = v.dot(v);\n", + " double dot = v.dot(v); // dot product\n", " for (int i = 0; i < result.size(); i++) {\n", " result[i] += dot;\n", " }\n", - "\n", - " // Subtract the squared norm\n", - " double squaredNorm = v.squaredNorm();\n", + " \n", + " double squaredNorm = v.squaredNorm(); // vector squared norm \n", " for (int i = 0; i < result.size(); i++) {\n", " result[i] -= squaredNorm;\n", " }\n", @@ -59,6 +85,14 @@ "};\n" ] }, + { + "cell_type": "markdown", + "id": "de00d39d-8156-4ecb-a932-924661e7b80e", + "metadata": {}, + "source": [ + "### Accessing the declared Eigen vectors on the Python side using Cppyy" + ] + }, { "cell_type": "code", "execution_count": 4, @@ -70,20 +104,27 @@ "\n", "import cppyy\n", "\n", + "a = cppyy.gbl.a\n", + "b = cppyy.gbl.b\n", + "c = cppyy.gbl.c\n", + "\n", "def display_eigen(vec, name):\n", " print(\"Vector : \", name, \", Dimensions : \", len(vec))\n", " for x in vec:\n", - " print(x)\n", - "\n", - "dynamic = cppyy.gbl.MatrixXd\n", - "a = cppyy.gbl.a\n", - "b = cppyy.gbl.b\n", - "c = cppyy.gbl.c" + " print(x)" + ] + }, + { + "cell_type": "markdown", + "id": "07cfc277-4202-47b6-9859-dd4a651bd4a1", + "metadata": {}, + "source": [ + "#### Setting values to the C++ Eigen Vector" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "3775e315-652d-4dea-8729-e36549524b62", "metadata": {}, "outputs": [], @@ -91,18 +132,18 @@ "%%python\n", "\n", "for i in range(len(a)):\n", - " a[i] = i + 1\n", + " a[i] = i -1\n", "\n", "for i in range(len(b)):\n", " b[i] = i + 1\n", "\n", "for i in range(len(c)):\n", - " c[i] = i + 1" + " c[i] = i - 1" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "ca77d6ff-3428-4977-9072-9f2f2a904973", "metadata": {}, "outputs": [ @@ -111,17 +152,17 @@ "output_type": "stream", "text": [ "Vector : A , Dimensions : 2\n", - "1.0\n", - "2.0\n", + "-1.0\n", + "0.0\n", "Vector : B , Dimensions : 3\n", "1.0\n", "2.0\n", "3.0\n", "Vector : C , Dimensions : 4\n", + "-1.0\n", + "0.0\n", "1.0\n", - "2.0\n", - "3.0\n", - "4.0\n" + "2.0\n" ] } ], @@ -133,9 +174,17 @@ "display_eigen(c, \"C\")" ] }, + { + "cell_type": "markdown", + "id": "e8c29a51-9897-4e16-9f6e-bacf918129cb", + "metadata": {}, + "source": [ + "### Calling the Templated method of the C++ class from the Python side" + ] + }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "id": "a01b4c6d-88ea-4cb1-a17e-716e1d813b1b", "metadata": {}, "outputs": [], @@ -147,9 +196,67 @@ "res4d = cppyy.gbl.EigenOperations[\"Eigen::Vector4d\"].PerformOperations(c)" ] }, + { + "cell_type": "code", + "execution_count": 8, + "id": "239c40e4-7b92-40be-bd86-336779f88946", + "metadata": {}, + "outputs": [], + "source": [ + "// fig = plt.figure()\n", + "// ax = fig.add_subplot(111, projection='3d')\n", + "// ax.quiver(X, Y)\n", + "// ax.set_xlim([-1, 0.5])\n", + "// ax.set_ylim([-1, 1.5])\n", + "// ax.set_zlim([-1, 8])\n", + "// plt.show()" + ] + }, { "cell_type": "code", "execution_count": 9, + "id": "876beb2f-113e-4889-bd10-3e460d17181e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1.0, 2.0, 3.0, 4.0)\n", + "(1.0, 1.0, 2.0, 0.5)\n" + ] + } + ], + "source": [ + "%%python\n", + "\n", + "import matplotlib.pyplot as plt\n", + "from mpl_toolkits.mplot3d import Axes3D\n", + "import numpy as np\n", + "\n", + "origin = [0, 0]\n", + "\n", + "np_res2 = np.array(list(res2d))\n", + "np_res3 = np.array(list(res3d)) \n", + "np_res4 = np.array(list(res4d)) \n", + "\n", + "X, Y = np_res2, np_res3\n", + "\n", + "\n", + " \n", + "ax.quiver(X, Y, Z, U, V, W)\n", + "ax.set_xlim([-1, 0.5])\n", + "ax.set_ylim([-1, 1.5])\n", + "ax.set_zlim([-1, 8])\n", + "\n", + "plt.show()\n", + "\n", + " \n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, "id": "4078ec69-0b4d-4350-8e6b-2d793bc27491", "metadata": {}, "outputs": [ @@ -158,17 +265,17 @@ "output_type": "stream", "text": [ "Vector : A , Dimensions : 2\n", - "0.4472135954999583\n", - "0.8944271909999157\n", + "-1.0\n", + "0.0\n", "Vector : B , Dimensions : 3\n", "0.26726124191242384\n", "0.5345224838248495\n", "0.8017837257372733\n", "Vector : C , Dimensions : 4\n", - "0.1825741858350547\n", - "0.3651483716701094\n", - "0.5477225575051676\n", - "0.7302967433402223\n" + "-0.40824829046386313\n", + "0.0\n", + "0.40824829046386313\n", + "0.8164965809277263\n" ] } ],