From 7d3242cd105e088a93f2ddd648416147f39ed5b0 Mon Sep 17 00:00:00 2001 From: Rafael Vuijk Date: Sat, 24 Oct 2026 05:05:42 +0000 Subject: [PATCH] Make the Lab's notebooks the sample notebooks AngouriMathLab's try branch had an F# tutorial of 38 code cells -- building and parsing expressions, substitution, calculus with its shortcuts, vectors, matrices, sets, the aggressive operators and a surface plot -- and a C# example, both against the current API, where the samples here had five cells each. The F# tutorial is Interactive.Sample.ipynb now, so the README's links and the Binder button open it, and the C# sample is the Lab's example followed by the three cells of the old sample it did not have. Outputs are stripped, the MyGet feed the Lab used is gone, and the tutorial's Try link builds from here. Executed with nbconvert in the binder/Dockerfile image: every cell of both runs, in 14 and 5 seconds. The F# one's first cell prints the C# compile error of https://github.com/asc-community/AngouriMath/issues/2109 and carries on. Part of https://github.com/asc-community/AngouriMath/issues/1689. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura --- .../Samples/CSharp.Interactive.Sample.ipynb | 235 +++---- Sources/Samples/Interactive.Sample.ipynb | 605 ++++++++++++++++-- binder/Dockerfile | 5 +- 3 files changed, 636 insertions(+), 209 deletions(-) diff --git a/Sources/Samples/CSharp.Interactive.Sample.ipynb b/Sources/Samples/CSharp.Interactive.Sample.ipynb index d16f85576..c720444e7 100644 --- a/Sources/Samples/CSharp.Interactive.Sample.ipynb +++ b/Sources/Samples/CSharp.Interactive.Sample.ipynb @@ -1,169 +1,108 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# C# example for AngouriMath\n", + "\n", + "While [AngouriMath.Interactive](https://www.nuget.org/packages/AngouriMath.Interactive) is recommended for research purposes, you can also use the default AngouriMath package in C# within interactive environment." + ] + }, { "cell_type": "code", - "execution_count": 1, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\r\n", - "
\r\n", - " \r\n", - " \r\n", - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\r\n", - "(1,1): error CS0006: Не удалось найти файл метаданных \"nuget:AngouriMath.Interactive, *-*\".\r\n", - "\r\n" - ] - }, - { - "ename": "Cell not executed", - "evalue": "compilation error", - "output_type": "error", - "traceback": [] - } - ], "source": [ "#r \"nuget:AngouriMath, *-*\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Basics" ] }, { "cell_type": "code", + "metadata": {}, + "source": [ + "Entity expr = \"a2 + sqrt(b) / 6 = 4\";\n", + "expr" + ], "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", "metadata": {}, - "outputs": [], "source": [ - "using AngouriMath.Extensions;\n", - "using AngouriMath;" - ] + "expr.Solve(\"a\")" + ], + "execution_count": null, + "outputs": [] }, { "cell_type": "code", + "metadata": {}, + "source": [ + "\"sin(a x) / sqrt(x)\".ToEntity().Differentiate(\"x\")" + ], "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", "metadata": {}, - "outputs": [], "source": [ - "\"x2 + sin(sqrt(x + 1/2)) + integral(sqrt(x + derivative(sin(y), y)), x)\".ToEntity()" + "\"a + b\".ToEntity().Substitute(\"a\", 5).Substitute(\"b\", 6).Evaled" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "@\"{ 1, 2 } \\/ RR \\/ [3; +oo)\".ToEntity()" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "var system = MathS.Equations(\n", + " \"a + b\",\n", + " \"sin(b) + c\"\n", + ");\n", + "system.Solve(\"a\", \"b\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Expressions, systems and matrices" ] }, { "cell_type": "code", + "metadata": {}, + "source": [ + "\"x2 + sin(sqrt(x + 1/2)) + integral(sqrt(x + derivative(sin(y), y)), x)\".ToEntity()" + ], "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", "metadata": {}, - "outputs": [], "source": [ "var sys = MathS.Equations(\n", " \"x + 2 - y - y2\",\n", @@ -171,19 +110,21 @@ " \"x - sin(z)\"\n", ");\n", "sys" - ] + ], + "execution_count": null, + "outputs": [] }, { "cell_type": "code", - "execution_count": null, "metadata": {}, - "outputs": [], "source": [ "MathS.Matrix(new Entity[,]{\n", "{ \"x / 2\", \"beta - 2^3\", \"e / sqrt(pi)\" },\n", "{ \"epsilon\", \"integral(sin(k), k)\", \"e - pi\" },\n", "})" - ] + ], + "execution_count": null, + "outputs": [] } ], "metadata": { @@ -193,11 +134,7 @@ "name": ".net-csharp" }, "language_info": { - "file_extension": ".cs", - "mimetype": "text/x-csharp", - "name": "C#", - "pygments_lexer": "csharp", - "version": "8.0" + "name": "C#" } }, "nbformat": 4, diff --git a/Sources/Samples/Interactive.Sample.ipynb b/Sources/Samples/Interactive.Sample.ipynb index e3984622d..b2d7bedef 100644 --- a/Sources/Samples/Interactive.Sample.ipynb +++ b/Sources/Samples/Interactive.Sample.ipynb @@ -1,95 +1,584 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "\n", + "
\n", + "\n", + "\n", + "
\n", + "

AngouriMath.Interactive

\n", + "
\n", + "\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook provides an example of using symbol algebra [AngouriMath](https://am.angouri.org) in an interactive notebook. Software, made it possible:\n", + "- [Jupyter](https://jupyter.org) - web-based editor for these notebooks\n", + "- [dotnet/interactive](https://github.com/dotnet/interactive/) - package, which allowed to make formatted values\n", + "- [AngouriMath.Interactive](https://www.nuget.org/packages/AngouriMath.Interactive) - package, wrapping AM to work in Jupyter" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[Try this notebook online](https://mybinder.org/v2/gh/asc-community/AngouriMath/master?labpath=Interactive.Sample.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Check [website](https://am.angouri.org) and [wiki](https://github.com/asc-community/AngouriMath/wiki) for more information." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Setting up" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Last major" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we install the latest package from NuGet." + ] + }, { "cell_type": "code", - "execution_count": 6, "metadata": {}, - "outputs": [], "source": [ "#r \"nuget:AngouriMath.Interactive, *-*\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Open everything" ] }, { "cell_type": "code", - "execution_count": 7, "metadata": {}, - "outputs": [], "source": [ "open AngouriMath.FSharp.Core\n", - "open AngouriMath.FSharp.Functions" + "open AngouriMath.FSharp.Functions\n", + "open AngouriMath.FSharp.Shortcuts" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Building a simple expression" ] }, { "cell_type": "code", - "execution_count": 8, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\r\n", - " \r\n", - " \r\n", - " \\[{x}^{2}+\\sin\\left(\\sqrt{x+\\frac{1}{2}}\\right)+\\int \\left[\\sqrt{x+\\frac{d\\left[\\sin\\left(y\\right)\\right]}{dy}}\\right] dx\\]\r\n", - " " - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } + "source": [ + "let x = symbol \"x\"\n", + "let y = symbol \"y\"\n", + "\n", + "x / y + (sqrt x)" ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, "source": [ - "parsed \"x2 + sin(sqrt(x + 1/2)) + integral(sqrt(x + derivative(sin(y), y)), x)\"" + "### Parsing" ] }, { "cell_type": "code", - "execution_count": 9, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\r\n", - " \r\n", - " \r\n", - " \\[\\frac{1}{2}\\times \\frac{1}{\\sqrt{\\sin\\left(x\\right)+\\frac{1}{x+\\epsilon}}}\\times \\left(\\cos\\left(x\\right)+\\frac{-1}{{\\left(x+\\epsilon\\right)}^{2}}\\right)+{e}^{3\\times {x}^{2}}\\times 2\\times x\\times 3\\]\r\n", - " " - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } + "source": [ + "parsed \"x ^ 2 + 3\"" ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, "source": [ - "derivative \"x\" \"sqrt(sin(x) + 1 / (x + epsilon)) + e^(3x2)\"" + "Because of how F# works, you need to parse numbers when using them along with other expressions" ] }, { "cell_type": "code", - "execution_count": 11, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\r\n", - " \r\n", - " \r\n", - " \\[\\left\\{ 3 \\right\\}\\]\r\n", - " " - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } + "source": [ + "x / (parsed 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "parsed \"Hello + A gamma gamma omicron upsilon rho iota Math!\"" ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, "source": [ - "solutions \"x\" \"x > 0 and x ^ 2 = 9\"" + "### Variable substitution" ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "(\"x\", 3) -|> \"x ^ 2\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + " \"x ^ 2\" <|- (\"x\", 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "\"6 / y + x\" <|- (\"x\", 3)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# I. Calculus" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\\`\\`d/dx\\`\\` is a shortcut, allowing to write expressions even easier" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "``d/dx`` ((sin x) + y ** x)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But if you need differentiating over a custom variable..." + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "derivative y (y ** x + y + (atan y))" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Same way, integrals:" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "``int [dx]`` \"x + 2\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "integral \"x\" \"y + z + zeta\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Limits:" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "``lim x->0`` \"sin(a x) / (b x)\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "``lim x->+oo`` \"(a x2 + b) / (c x2 - c)\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "limit \"x\" \"0\" \"sin(a x) / (b x)\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# II. Algebra" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "open AngouriMath.FSharp.Matrices" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Vectors" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Vector of numbers" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "let v1 = vector [1; 2; 3]\n", + "v1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Vector of expressions, parsed from strings" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "let v2 = vector [\"x + 2\"; \"y\"; \"pi + lambda\"]\n", + "v2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Matrix of numbers" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "let m1 = matrix [[1; 2; 3]; [4; 5; 6]]\n", + "m1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Transposed matrix" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "m1.T" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Matrix of expressions, parsed from strings" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "let m2 = matrix [[\"x_y\"; \"3\"]; [\"gamma + Omega\"; \"2\"]]\n", + "m2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Matrix product" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "m1.T *. m2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Tensor product" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "m1 ***. m2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Matrix power" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "m2 **. 2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "open AngouriMath.FSharp.Constants" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "simplified (m2 - (parsed \"lambda\") * I_2)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sets" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "let int1 = leftInclusive \"3\"\n", + "int1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "let int1 = leftExclusive \"3\"\n", + "int1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "let int1 = leftExclusiveRightInclusive \"3\" \"lambda\"\n", + "int1" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "parsed \"{1, 2, 3} \\/ RR\"" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# III. Aggressive operators\n", + "They will override existing arithmetic operators for `obj` and `obj`" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "open AngouriMath.Interactive.AggressiveOperators" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "16 ** 60" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "e ** (i * pi)" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "1038 - 3.4m" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "(3 > \"x\") <|- (\"x\", \"pi\")" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# IV. Plotting" + ] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "open AngouriMath.Interactive" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": [ + "let f1 = parsed \"sin(x) + sin(2x) + sin(3x) + sin(4x) + sin(5x)\"\n", + "let f2 = parsed \"cos(y) + sin(2y) + cos(3y) + sin(4y) + cos(5y)\"\n", + "let z = f1 * f2\n", + "Plot.surface [ 0.0..0.01..3.5 ] [ 0.0..0.02..3.5 ] z" + ], + "execution_count": null, + "outputs": [] } ], "metadata": { @@ -101,9 +590,9 @@ "language_info": { "file_extension": ".fs", "mimetype": "text/x-fsharp", - "name": "C#", + "name": "F#", "pygments_lexer": "fsharp", - "version": "4.5" + "version": "5.0" } }, "nbformat": 4, diff --git a/binder/Dockerfile b/binder/Dockerfile index 034536f01..5ccd164a8 100644 --- a/binder/Dockerfile +++ b/binder/Dockerfile @@ -1,6 +1,7 @@ # The image mybinder.org builds for the README's "Try" button: Jupyter with the .NET Interactive -# kernels, and the sample notebooks from Sources/Samples. The notebooks install AngouriMath.Interactive -# from NuGet themselves. https://github.com/asc-community/AngouriMath/issues/1689 +# kernels, and the sample notebooks from Sources/Samples. The notebooks install their package from NuGet +# themselves: AngouriMath.Interactive for F#, AngouriMath for C#. +# https://github.com/asc-community/AngouriMath/issues/1689 FROM quay.io/jupyter/base-notebook:2026-10-05 USER root