From 49fdf351f067c2f9289a9ab0581553bb3c169c1b Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Tue, 6 Aug 2024 22:20:54 +0000 Subject: [PATCH] build based on d4ef9a8 --- dev/.documenter-siteinfo.json | 2 +- dev/assets/Manifest.toml | 44 +- dev/comparison/index.html | 2 +- dev/examples/perturbation/index.html | 2 +- dev/getting_started/index.html | 18 +- dev/index.html | 17 +- dev/manual/arrays/index.html | 2 +- dev/manual/build_function/index.html | 10 +- dev/manual/derivatives/index.html | 22 +- dev/manual/expression_manipulation/index.html | 16 +- dev/manual/faq/index.html | 2 +- dev/manual/functions/index.html | 12 +- dev/manual/groebner/index.html | 2 +- dev/manual/io/index.html | 2 +- dev/manual/limits/index.html | 2 +- dev/manual/parsing/index.html | 2 +- dev/manual/sparsity_detection/index.html | 12 +- dev/manual/types/index.html | 2 +- dev/manual/variables/index.html | 10 +- .../{22047751.svg => 3e96ca63.svg} | 26414 ++++++++-------- dev/tutorials/auto_parallel/index.html | 4 +- dev/tutorials/converting_to_C/index.html | 4 +- 22 files changed, 13312 insertions(+), 13291 deletions(-) rename dev/tutorials/auto_parallel/{22047751.svg => 3e96ca63.svg} (58%) diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 166f9f32f..27c17cc12 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-08-02T13:03:36","documenter_version":"1.5.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-08-06T22:20:46","documenter_version":"1.5.0"}} \ No newline at end of file diff --git a/dev/assets/Manifest.toml b/dev/assets/Manifest.toml index 7858a4811..1403f7eb9 100644 --- a/dev/assets/Manifest.toml +++ b/dev/assets/Manifest.toml @@ -5,9 +5,9 @@ manifest_format = "2.0" project_hash = "5e803325a5424b2919bdb1e5af7e23565ad91898" [[deps.ADTypes]] -git-tree-sha1 = "aa4d425271a914d8c4af6ad9fccb6eb3aec662c7" +git-tree-sha1 = "6778bcc27496dae5723ff37ee30af451db8b35fe" uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" -version = "1.6.1" +version = "1.6.2" weakdeps = ["ChainRulesCore", "EnzymeCore"] [deps.ADTypes.extensions] @@ -316,6 +316,12 @@ version = "1.0.0" deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +[[deps.Dbus_jll]] +deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "fc173b380865f70627d7dd1190dc2fce6cc105af" +uuid = "ee1fde0b-3d02-5ea6-8484-8dfef6360eab" +version = "1.14.10+0" + [[deps.DelimitedFiles]] deps = ["Mmap"] git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" @@ -370,9 +376,9 @@ version = "1.15.1" [[deps.DifferentiationInterface]] deps = ["ADTypes", "Compat", "DocStringExtensions", "FillArrays", "LinearAlgebra", "PackageExtensionCompat", "SparseArrays", "SparseMatrixColorings"] -git-tree-sha1 = "33cf7b202a00a233c5b24cb3aae9b523a527a5a1" +git-tree-sha1 = "6bd550abccb7aa156141e10d5367c580af9128af" uuid = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" -version = "0.5.10" +version = "0.5.11" [deps.DifferentiationInterface.extensions] DifferentiationInterfaceChainRulesCoreExt = "ChainRulesCore" @@ -629,10 +635,10 @@ deps = ["Random"] uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" [[deps.GLFW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] -git-tree-sha1 = "3f74912a156096bd8fdbef211eff66ab446e7297" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "libdecor_jll", "xkbcommon_jll"] +git-tree-sha1 = "532f9126ad901533af1d4f5c198867227a7bb077" uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" -version = "3.4.0+0" +version = "3.4.0+1" [[deps.GPUArraysCore]] deps = ["Adapt"] @@ -980,9 +986,9 @@ version = "2.40.1+0" [[deps.LineSearches]] deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] -git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" +git-tree-sha1 = "e4c3be53733db1051cc15ecf573b1042b3a712a1" uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.2.0" +version = "7.3.0" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] @@ -990,9 +996,9 @@ uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[deps.LinearSolve]] deps = ["ArrayInterface", "ChainRulesCore", "ConcreteStructs", "CpuId", "DocStringExtensions", "EnumX", "FastLapackInterface", "GPUArraysCore", "InteractiveUtils", "KLU", "Krylov", "LazyArrays", "Libdl", "LinearAlgebra", "MKL_jll", "Markdown", "PrecompileTools", "Preferences", "RecursiveFactorization", "Reexport", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Sparspak", "StaticArraysCore", "UnPack"] -git-tree-sha1 = "bae39cec701960d14dc7d3c05491c1bfd922fa1d" +git-tree-sha1 = "00d9dc2ef7abb0575ec2b59fedbbc5685127e6ea" uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -version = "2.31.1" +version = "2.31.2" [deps.LinearSolve.extensions] LinearSolveBandedMatricesExt = "BandedMatrices" @@ -1270,6 +1276,12 @@ uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" version = "1.0.2" weakdeps = ["Requires", "TOML"] +[[deps.Pango_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "cb5a2ab6763464ae0f19c86c56c63d4a2b0f5bda" +uuid = "36c8627f-9965-5494-a995-c6b170f724f3" +version = "1.52.2+0" + [[deps.Parameters]] deps = ["OrderedCollections", "UnPack"] git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" @@ -1548,9 +1560,9 @@ version = "0.3.8" [[deps.SciMLStructures]] deps = ["ArrayInterface"] -git-tree-sha1 = "cfdd1200d150df1d3c055cc72ee6850742e982d7" +git-tree-sha1 = "20ad3e7c137156c50c93c888d0f2bc5b7883c729" uuid = "53ae85a6-f571-4167-b2af-e1d143709226" -version = "1.4.1" +version = "1.4.2" [[deps.Scratch]] deps = ["Dates"] @@ -2143,6 +2155,12 @@ deps = ["Artifacts", "Libdl"] uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" version = "5.8.0+1" +[[deps.libdecor_jll]] +deps = ["Artifacts", "Dbus_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pango_jll", "Wayland_jll", "xkbcommon_jll"] +git-tree-sha1 = "9bf7903af251d2050b467f76bdbe57ce541f7f4f" +uuid = "1183f4f0-6f2a-5f1a-908b-139f9cdfea6f" +version = "0.2.2+0" + [[deps.libevdev_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "141fe65dc3efabb0b1d5ba74e91f6ad26f84cc22" diff --git a/dev/comparison/index.html b/dev/comparison/index.html index fbafbb5f7..c2e78eb52 100644 --- a/dev/comparison/index.html +++ b/dev/comparison/index.html @@ -1,2 +1,2 @@ -Comparison Against SymPy · Symbolics.jl

Comparison of Julia's Symbolics.jl vs SymPy for Symbolic Computation

Symbolics.jl is a symbolic modeling language for Julia, built in Julia. Its goal is very different from Sympy: it was made to support symbolic-numerics, the combination of symbolic computing with numerical methods to allow for extreme performance computing that would not be possible without modifying the model. Because of this, Symbolics.jl excels in many areas due to purposeful design decisions:

  • Performance: Symbolics.jl is built in Julia, whereas SymPy was built in Python. Thus, the performance bar for Symbolics.jl is much higher. Symbolics.jl started because SymPy was far too slow and SymEngine was far too inflexible for the projects they were doing. Performance is key to Symbolics.jl. If you find any performance issues, please file an issue.
  • build_function: lambdify is “fine” for some people, but if you're building a super fast MPI-enabled Julia/C/Fortran simulation code, having a function that hits the Python interpreter is less than optimal. By default, build_function builds fast JIT-compiled functions due to being in Julia. However, it has support for things like static arrays, non-allocating functions via mutation, fast functions on sparse matrices and arrays of arrays, etc.: all core details of doing high performance computing.
  • Parallelism: Symbolics.jl has pervasive parallelism. The symbolic simplification via SymbolicUtils.jl has built-in parallelism, Symbolics.jl builds functions that parallelize across threads. Symbolics.jl is compatible with GPU libraries like CUDA.jl.
  • Extensible: Symbolics.jl and its underlying tools are written in pure Julia. Want to add new or better simplification rules? Add some Julia code! Need to add new derivatives? Add some Julia code! You get the picture. Breaking down these barriers makes it easier for the user to tailor the program to their needs and accelerates the development of the library.
  • Deep integration with the Julia ecosystem: Symbolics.jl's integration with neural networks is not the only thing that's deep. Symbolics.jl is built with the same philosophy as other SciML packages, eschewing “monorepos” for a distributed development approach that ties together the work of many developers. The differentiation parts utilize tools from automatic differentiation libraries, all linear algebra functionality comes from tracing Julia Base itself, symbolic rewriting (simplification and substitution) comes from SymbolicUtils.jl, parallelism comes from Julia Base libraries, Dagger.jl, etc. SciML Tools like DataDrivenDiffEq.jl can reconstruct symbolic expressions from neural networks and data, while NeuralPDE.jl can automatically solve partial differential equations from symbolic descriptions using physics-informed neural networks. The list keeps going. All told, by design Symbolics.jl's development moves fast because it's effectively using the work of hundreds of Julia developers, allowing it to grow fast.
  • While Symbolics.jl has many features missing from SymPy, it does not superset SymPy's functionality. For a list of missing features, see this issue.
+Comparison Against SymPy · Symbolics.jl

Comparison of Julia's Symbolics.jl vs SymPy for Symbolic Computation

Symbolics.jl is a symbolic modeling language for Julia, built in Julia. Its goal is very different from Sympy: it was made to support symbolic-numerics, the combination of symbolic computing with numerical methods to allow for extreme performance computing that would not be possible without modifying the model. Because of this, Symbolics.jl excels in many areas due to purposeful design decisions:

  • Performance: Symbolics.jl is built in Julia, whereas SymPy was built in Python. Thus, the performance bar for Symbolics.jl is much higher. Symbolics.jl started because SymPy was far too slow and SymEngine was far too inflexible for the projects they were doing. Performance is key to Symbolics.jl. If you find any performance issues, please file an issue.
  • build_function: lambdify is “fine” for some people, but if you're building a super fast MPI-enabled Julia/C/Fortran simulation code, having a function that hits the Python interpreter is less than optimal. By default, build_function builds fast JIT-compiled functions due to being in Julia. However, it has support for things like static arrays, non-allocating functions via mutation, fast functions on sparse matrices and arrays of arrays, etc.: all core details of doing high performance computing.
  • Parallelism: Symbolics.jl has pervasive parallelism. The symbolic simplification via SymbolicUtils.jl has built-in parallelism, Symbolics.jl builds functions that parallelize across threads. Symbolics.jl is compatible with GPU libraries like CUDA.jl.
  • Extensible: Symbolics.jl and its underlying tools are written in pure Julia. Want to add new or better simplification rules? Add some Julia code! Need to add new derivatives? Add some Julia code! You get the picture. Breaking down these barriers makes it easier for the user to tailor the program to their needs and accelerates the development of the library.
  • Deep integration with the Julia ecosystem: Symbolics.jl's integration with neural networks is not the only thing that's deep. Symbolics.jl is built with the same philosophy as other SciML packages, eschewing “monorepos” for a distributed development approach that ties together the work of many developers. The differentiation parts utilize tools from automatic differentiation libraries, all linear algebra functionality comes from tracing Julia Base itself, symbolic rewriting (simplification and substitution) comes from SymbolicUtils.jl, parallelism comes from Julia Base libraries, Dagger.jl, etc. SciML Tools like DataDrivenDiffEq.jl can reconstruct symbolic expressions from neural networks and data, while NeuralPDE.jl can automatically solve partial differential equations from symbolic descriptions using physics-informed neural networks. The list keeps going. All told, by design Symbolics.jl's development moves fast because it's effectively using the work of hundreds of Julia developers, allowing it to grow fast.
  • While Symbolics.jl has many features missing from SymPy, it does not superset SymPy's functionality. For a list of missing features, see this issue.
diff --git a/dev/examples/perturbation/index.html b/dev/examples/perturbation/index.html index dfe8112f2..110da47df 100644 --- a/dev/examples/perturbation/index.html +++ b/dev/examples/perturbation/index.html @@ -83,4 +83,4 @@ - (𝜀 + 4*𝜀^2 + 10*𝜀^3)*𝑀^3/6 + (𝜀 + 16*𝜀^2 + 91*𝜀^3)*𝑀^5/120

Comparing the formula to the one for 𝐸 in the Wikipedia article on the Kepler's equation:

\[ E = \frac{1}{1-\epsilon}M -\frac{\epsilon}{(1-\epsilon)^4} \frac{M^3}{3!} + \frac{(9\epsilon^2 - + \epsilon)}{(1-\epsilon)^7}\frac{M^5}{5!}\cdots\]

The first deviation is in the coefficient of $\epsilon^3 M^5$.

+ + \epsilon)}{(1-\epsilon)^7}\frac{M^5}{5!}\cdots\]

The first deviation is in the coefficient of $\epsilon^3 M^5$.

diff --git a/dev/getting_started/index.html b/dev/getting_started/index.html index 28228a569..069239816 100644 --- a/dev/getting_started/index.html +++ b/dev/getting_started/index.html @@ -103,10 +103,10 @@ \]

Where we can reference the values via:

Symbolics.value.(V)
2×2 Matrix{Float64}:
  40.0  24.0
  16.0   9.0

Non-Interactive Development

Note that the macros are for the high-level case where you're doing symbolic computation on your own code. If you want to do symbolic computation on someone else's code, like in a macro, you may not want to do @variables x because you might want the name “x” to come from the user's code. For these cases, you can use the interpolation operator to interpolate the runtime value of x, i.e. @variables $x. Check the documentation of @variables for more details.

a, b, c = :runtime_symbol_value, :value_b, :value_c
(:runtime_symbol_value, :value_b, :value_c)
vars = @variables t $a $b(t) $c(t)[1:3]
4-element Vector{Any}:
-      t
+                    t
  runtime_symbol_value
-   value_b(t)
-       (value_c(t))[1:3]
(t, a, b, c)
(t, :runtime_symbol_value, :value_b, :value_c)

One could also use variable and variables. Read their documentation for more details.

If we need to use this to generate new Julia code, we can simply convert the output to an Expr:

Symbolics.toexpr(x + y^2)
:((+)(x, (^)(y, 2)))

Syms and callable Syms

In the definition

@variables t x(t) y(t)

\[ \begin{equation} + value_b(t) + (value_c(t))[1:3]

(t, a, b, c)
(t, :runtime_symbol_value, :value_b, :value_c)

One could also use variable and variables. Read their documentation for more details.

If we need to use this to generate new Julia code, we can simply convert the output to an Expr:

Symbolics.toexpr(x + y^2)
:((+)(x, (^)(y, 2)))

Syms and callable Syms

In the definition

@variables t x(t) y(t)

\[ \begin{equation} \left[ \begin{array}{c} t \\ @@ -220,9 +220,9 @@ out = sparse(rows, cols, zeros(length(cols)), size(sj)...) # pre-allocate, and correct structure myf = eval(last(f_expr)) myf(out, rand(N)) # note that out matches the sparsity structure of sj -out

20×10 SparseArrays.SparseMatrixCSC{Float64, Int64} with 18 stored entries:
-⎡⠀⡠⠀⠀⠄⎤
-⎢⠠⠀⠀⠈⠀⎥
-⎢⠀⠄⠘⠡⠄⎥
-⎢⡀⠀⢀⠑⢀⎥
-⎣⠀⠀⠘⠀⠀⎦
+out
20×10 SparseArrays.SparseMatrixCSC{Float64, Int64} with 16 stored entries:
+⎡⠢⠀⠀⠀⡄⎤
+⎢⠄⠀⠠⠀⠀⎥
+⎢⠀⠀⡀⢈⠀⎥
+⎢⠀⠀⠈⠃⠄⎥
+⎣⠈⠀⡀⠀⠁⎦
diff --git a/dev/index.html b/dev/index.html index 30b282c42..e679e8de1 100644 --- a/dev/index.html +++ b/dev/index.html @@ -27,7 +27,7 @@ Threads: 1 default, 0 interactive, 1 GC (on 4 virtual cores) Environment: JULIA_DEBUG = Documenter
A more complete overview of all dependencies and their versions is also provided.
Status `~/work/Symbolics.jl/Symbolics.jl/docs/Manifest.toml`
-  [47edcb42] ADTypes v1.6.1
+  [47edcb42] ADTypes v1.6.2
   [a4c015fc] ANSIColoredPrinters v0.0.1
   [1520ce14] AbstractTrees v0.4.5
   [7d9f7c33] Accessors v0.1.37
@@ -68,7 +68,7 @@
   [2b5f629d] DiffEqBase v6.152.2
   [163ba53b] DiffResults v1.1.0
   [b552c78f] DiffRules v1.15.1
-  [a0c0ee7d] DifferentiationInterface v0.5.10
+  [a0c0ee7d] DifferentiationInterface v0.5.11
   [31c24e10] Distributions v0.25.109
   [ffbed154] DocStringExtensions v0.9.3
   [e30172f5] Documenter v1.5.0
@@ -120,8 +120,8 @@
   [10f19ff3] LayoutPointers v0.1.17
   [0e77f7df] LazilyInitializedFields v1.2.2
   [5078a376] LazyArrays v2.1.9
-  [d3d80556] LineSearches v7.2.0
-  [7ed4a6bd] LinearSolve v2.31.1
+  [d3d80556] LineSearches v7.3.0
+  [7ed4a6bd] LinearSolve v2.31.2
   [2ab3a3ac] LogExpFunctions v0.3.28
   [e6f89c97] LoggingExtras v1.0.3
   [bdcacae8] LoopVectorization v0.12.171
@@ -172,7 +172,7 @@
   [476501e8] SLEEFPirates v0.6.43
   [0bca4576] SciMLBase v2.48.1
   [c0aeaf25] SciMLOperators v0.3.8
-  [53ae85a6] SciMLStructures v1.4.1
+  [53ae85a6] SciMLStructures v1.4.2
   [6c6a2e73] Scratch v1.2.1
   [efcf1570] Setfield v1.1.1
   [992d4aef] Showoff v1.0.3
@@ -218,13 +218,14 @@
   [19fa3120] VertexSafeGraphs v0.2.0
   [6e34b625] Bzip2_jll v1.0.8+1
   [83423d85] Cairo_jll v1.18.0+2
+  [ee1fde0b] Dbus_jll v1.14.10+0
   [2702e6a9] EpollShim_jll v0.0.20230411+0
   [2e619515] Expat_jll v2.6.2+0
 ⌅ [b22a6f82] FFMPEG_jll v4.4.4+1
   [a3f928ae] Fontconfig_jll v2.13.96+0
   [d7e528f0] FreeType2_jll v2.13.2+0
   [559328eb] FriBidi_jll v1.0.14+0
-  [0656b61e] GLFW_jll v3.4.0+0
+  [0656b61e] GLFW_jll v3.4.0+1
   [d2c73de3] GR_jll v0.73.7+0
   [78b55507] Gettext_jll v0.21.0+0
   [f8c6e375] Git_jll v2.44.0+2
@@ -250,6 +251,7 @@
   [458c3c95] OpenSSL_jll v3.0.14+0
   [efe28fd5] OpenSpecFun_jll v0.5.5+0
   [91d4177d] Opus_jll v1.3.2+0
+  [36c8627f] Pango_jll v1.52.2+0
   [30392449] Pixman_jll v0.43.4+0
   [c0090381] Qt6Base_jll v6.7.1+1
   [629bc702] Qt6Declarative_jll v6.7.1+2
@@ -292,6 +294,7 @@
   [1a1c6b14] gperf_jll v3.1.1+0
   [a4ae2306] libaom_jll v3.9.0+0
   [0ac62f75] libass_jll v0.15.1+0
+  [1183f4f0] libdecor_jll v0.2.2+0
   [2db6ffa8] libevdev_jll v1.11.0+0
   [f638f0a6] libfdk_aac_jll v2.0.2+0
   [36db933b] libinput_jll v1.18.0+0
@@ -351,4 +354,4 @@
   [8e850b90] libblastrampoline_jll v5.8.0+1
   [8e850ede] nghttp2_jll v1.52.0+1
   [3f19e933] p7zip_jll v17.4.0+2
-Info Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated -m`

You can also download the manifest file and the project file.

+Info Packages marked with ⌃ and ⌅ have new versions available. Those with ⌃ may be upgradable, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated -m`

You can also download the manifest file and the project file.

diff --git a/dev/manual/arrays/index.html b/dev/manual/arrays/index.html index a23eae828..498185f0c 100644 --- a/dev/manual/arrays/index.html +++ b/dev/manual/arrays/index.html @@ -64,4 +64,4 @@ A_{2,1} A_{3,1} + A_{2,2} A_{3,2} + A_{2,3} A_{3,3} \end{equation} \]

@syms i::Int j::Int
-Symbolics.scalarize(AAt[i,j])

In general, any scalar expression which is derived from array expressions can be scalarized.

#sum(A[:,1]) + sum(A[2,:])#latexify not working
Symbolics.scalarize(sum(A[:,1]) + sum(A[2,:]))
+Symbolics.scalarize(AAt[i,j])

In general, any scalar expression which is derived from array expressions can be scalarized.

#sum(A[:,1]) + sum(A[2,:])#latexify not working
Symbolics.scalarize(sum(A[:,1]) + sum(A[2,:]))
diff --git a/dev/manual/build_function/index.html b/dev/manual/build_function/index.html index 4785b39ab..b13a4cc2f 100644 --- a/dev/manual/build_function/index.html +++ b/dev/manual/build_function/index.html @@ -3,7 +3,7 @@ expression = Val{true}, target = JuliaTarget(), parallel=nothing, - kwargs...)

Arguments:

Keyword Arguments:

Note that not all build targets support the full compilation interface. Check the individual target documentation for details.

source

Target-Specific Definitions

Symbolics._build_functionMethod
_build_function(target::JuliaTarget, rhss::AbstractArray, args...;
+               kwargs...)

Arguments:

  • ex: The Num to compile
  • args: The arguments of the function
  • expression: Whether to generate code or whether to generate the compiled form. By default, expression = Val{true}, which means that the code for the function is returned. If Val{false}, then the returned value is compiled.

Keyword Arguments:

  • target: The output target of the compilation process. Possible options are:
    • JuliaTarget: Generates a Julia function
    • CTarget: Generates a C function
    • StanTarget: Generates a function for compiling with the Stan probabilistic programming language
    • MATLABTarget: Generates an anonymous function for use in MATLAB and Octave environments
  • parallel: The kind of parallelism to use in the generated function. Defaults to SerialForm(), i.e. no parallelism, if ex is a single expression or an array containing <= 1500 non-zero expressions. If ex is an array of > 1500 non-zero expressions, then ShardedForm(80, 4) is used. See below for more on ShardedForm. Note that the parallel forms are not exported and thus need to be chosen like Symbolics.SerialForm(). The choices are:
    • SerialForm(): Serial execution.
    • ShardedForm(cutoff, ncalls): splits the output function into sub-functions which contain at most cutoff number of output rhss. These sub-functions are called by the top-level function that buildfunction returns. This helps in reducing the compile time of the generated function.
    • MultithreadedForm(): Multithreaded execution with a static split, evenly splitting the number of expressions per thread.
  • fname: Used by some targets for the name of the function in the target space.

Note that not all build targets support the full compilation interface. Check the individual target documentation for details.

source

Target-Specific Definitions

Symbolics._build_functionMethod
_build_function(target::JuliaTarget, rhss::AbstractArray, args...;
                    conv=toexpr,
                    expression = Val{true},
                    expression_module = @__MODULE__(),
@@ -26,14 +26,14 @@
                          convert_oop = true, force_SA = false,
                          skipzeros = outputidxs===nothing,
                          fillzeros = skipzeros && !(typeof(rhss)<:SparseMatrixCSC),
-                         parallel=SerialForm(), kwargs...)

Generates a Julia function which can then be utilized for further evaluations. If expression=Val{false}, the return is a Julia function which utilizes RuntimeGeneratedFunctions.jl to be free of world-age issues.

If the rhss is a scalar, the generated function is a function with a scalar output. Otherwise, if it's an AbstractArray, the output is two functions, one for out-of-place AbstractArray output and a second which is a mutating function. The outputted functions match the given argument order, i.e., f(u,p,args...) for the out-of-place and scalar functions and f!(du,u,p,args..) for the in-place version.

Special Keyword Arguments:

  • parallel: The kind of parallelism to use in the generated function. Defaults to SerialForm(), i.e. no parallelism. Note that the parallel forms are not exported and thus need to be chosen like Symbolics.SerialForm(). The choices are:
    • SerialForm(): Serial execution.
    • ShardedForm(cutoff, ncalls): splits the output function into sub-functions which contain at most cutoff number of output rhss. These sub-functions are called by the top-level function that buildfunction returns.
    • MultithreadedForm(): Multithreaded execution with a static split, evenly splitting the number of expressions per thread.
  • conv: The conversion function of symbolic types to Expr. By default, this uses the toexpr function.
  • checkbounds: For whether to enable bounds checking inside the generated function. Defaults to false, meaning that @inbounds is applied.
  • linenumbers: Determines whether the generated function expression retains the line numbers. Defaults to true.
  • convert_oop: Determines whether the OOP version should try to convert the output to match the type of the first input. This is useful for cases like LabelledArrays or other array types that carry extra information. Defaults to true.
  • force_SA: Forces the output of the OOP version to be a StaticArray. Defaults to false, and outputs a static array when the first argument is a static array.
  • skipzeros: Whether to skip filling zeros in the in-place version if the filling function is 0.
  • fillzeros: Whether to perform fill(out,0) before the calculations to ensure safety with skipzeros.
source
Symbolics._build_functionMethod

Build function target: CTarget

function _build_function(target::CTarget, eqs::Array{<:Equation}, args...;
+                         parallel=SerialForm(), kwargs...)

Generates a Julia function which can then be utilized for further evaluations. If expression=Val{false}, the return is a Julia function which utilizes RuntimeGeneratedFunctions.jl to be free of world-age issues.

If the rhss is a scalar, the generated function is a function with a scalar output. Otherwise, if it's an AbstractArray, the output is two functions, one for out-of-place AbstractArray output and a second which is a mutating function. The outputted functions match the given argument order, i.e., f(u,p,args...) for the out-of-place and scalar functions and f!(du,u,p,args..) for the in-place version.

Special Keyword Arguments:

  • parallel: The kind of parallelism to use in the generated function. Defaults to SerialForm(), i.e. no parallelism. Note that the parallel forms are not exported and thus need to be chosen like Symbolics.SerialForm(). The choices are:
    • SerialForm(): Serial execution.
    • ShardedForm(cutoff, ncalls): splits the output function into sub-functions which contain at most cutoff number of output rhss. These sub-functions are called by the top-level function that buildfunction returns.
    • MultithreadedForm(): Multithreaded execution with a static split, evenly splitting the number of expressions per thread.
  • conv: The conversion function of symbolic types to Expr. By default, this uses the toexpr function.
  • checkbounds: For whether to enable bounds checking inside the generated function. Defaults to false, meaning that @inbounds is applied.
  • linenumbers: Determines whether the generated function expression retains the line numbers. Defaults to true.
  • convert_oop: Determines whether the OOP version should try to convert the output to match the type of the first input. This is useful for cases like LabelledArrays or other array types that carry extra information. Defaults to true.
  • force_SA: Forces the output of the OOP version to be a StaticArray. Defaults to false, and outputs a static array when the first argument is a static array.
  • skipzeros: Whether to skip filling zeros in the in-place version if the filling function is 0.
  • fillzeros: Whether to perform fill(out,0) before the calculations to ensure safety with skipzeros.
source
Symbolics._build_functionMethod

Build function target: CTarget

function _build_function(target::CTarget, eqs::Array{<:Equation}, args...;
                          conv = toexpr, expression = Val{true},
                          fname = :diffeqf,
                          lhsname=:du,rhsnames=[Symbol("RHS$i") for i in 1:length(args)],
-                         libpath=tempname(),compiler=:gcc)

This builds an in-place C function. Only works on arrays of equations. If expression == Val{false}, then this builds a function in C, compiles it, and returns a lambda to that compiled function. These special keyword arguments control the compilation:

  • libpath: the path to store the binary. Defaults to a temporary path.
  • compiler: which C compiler to use. Defaults to :gcc, which is currently the only available option.
source
Symbolics._build_functionMethod

Build function target: StanTarget

function _build_function(target::StanTarget, eqs::Array{<:Equation}, vs, ps, iv;
+                         libpath=tempname(),compiler=:gcc)

This builds an in-place C function. Only works on arrays of equations. If expression == Val{false}, then this builds a function in C, compiles it, and returns a lambda to that compiled function. These special keyword arguments control the compilation:

  • libpath: the path to store the binary. Defaults to a temporary path.
  • compiler: which C compiler to use. Defaults to :gcc, which is currently the only available option.
source
Symbolics._build_functionMethod

Build function target: StanTarget

function _build_function(target::StanTarget, eqs::Array{<:Equation}, vs, ps, iv;
                          conv = toexpr, expression = Val{true},
                          fname = :diffeqf, lhsname=:internal_var___du,
-                         rhsnames=[:internal_var___u,:internal_var___p,:internal_var___t])

This builds an in-place Stan function compatible with the Stan differential equation solvers. Unlike other build targets, this one requires (vs, ps, iv) as the function arguments. Only allowed on arrays of equations.

source
Symbolics._build_functionMethod

Build function target: MATLABTarget

function _build_function(target::MATLABTarget, eqs::Array{<:Equation}, args...;
+                         rhsnames=[:internal_var___u,:internal_var___p,:internal_var___t])

This builds an in-place Stan function compatible with the Stan differential equation solvers. Unlike other build targets, this one requires (vs, ps, iv) as the function arguments. Only allowed on arrays of equations.

source
Symbolics._build_functionMethod

Build function target: MATLABTarget

function _build_function(target::MATLABTarget, eqs::Array{<:Equation}, args...;
                          conv = toexpr, expression = Val{true},
                          lhsname=:internal_var___du,
-                         rhsnames=[:internal_var___u,:internal_var___p,:internal_var___t])

This builds an out of place anonymous function @(t,rhsnames[1]) to be used in MATLAB. Compatible with the MATLAB differential equation solvers. Only allowed on expressions, and arrays of expressions.

source

Limitations

build_function

+ rhsnames=[:internal_var___u,:internal_var___p,:internal_var___t])

This builds an out of place anonymous function @(t,rhsnames[1]) to be used in MATLAB. Compatible with the MATLAB differential equation solvers. Only allowed on expressions, and arrays of expressions.

source

Limitations

build_function

diff --git a/dev/manual/derivatives/index.html b/dev/manual/derivatives/index.html index 75afec95c..47570cbc7 100644 --- a/dev/manual/derivatives/index.html +++ b/dev/manual/derivatives/index.html @@ -13,7 +13,7 @@ (D'~x(t)) ∘ (D'~y(t)) julia> D3 = Differential(x)^3 # 3rd order differential operator -(D'~x(t)) ∘ (D'~x(t)) ∘ (D'~x(t))source
Symbolics.expand_derivativesFunction
expand_derivatives(O; ...)
+(D'~x(t)) ∘ (D'~x(t)) ∘ (D'~x(t))
source
Symbolics.expand_derivativesFunction
expand_derivatives(O; ...)
 expand_derivatives(O, simplify; occurrences)
 

Expands derivatives within a symbolic expression O.

This function recursively traverses a symbolic expression, applying the chain rule and other derivative rules to expand any derivatives it encounters.

Arguments

  • O::Symbolic: The symbolic expression to expand.
  • simplify::Bool=false: Whether to simplify the resulting expression using SymbolicUtils.simplify.
  • occurrences=nothing: Information about the occurrences of the independent variable in the argument of the derivative. This is used internally for optimization purposes.

Examples

julia> @variables x y z k;
 
@@ -24,15 +24,15 @@
 (::Differential) (generic function with 2 methods)
 
 julia> dfx=expand_derivatives(Dx(f))
-(k*((2abs(x - y)) / y - 2z)*IfElse.ifelse(signbit(x - y), -1, 1)) / y
source
Missing docstring.

Missing docstring for is_derivative. Check Documenter's build log for details.

Note

For symbolic differentiation, all registered functions in the symbolic expression need a registered derivative. For more information, see the function registration page.

High-Level Differentiation Functions

The following functions are not exported and thus must be accessed in a namespaced way, i.e. Symbolics.jacobian.

Symbolics.derivativeFunction
derivative(O, var; simplify)
-

A helper function for computing the derivative of the expression O with respect to var.

source
Symbolics.jacobianFunction
jacobian(ops, vars; simplify, scalarize)
-

A helper function for computing the Jacobian of an array of expressions with respect to an array of variable expressions.

source
Symbolics.sparsejacobianFunction
sparsejacobian(ops, vars; simplify)
-

A helper function for computing the sparse Jacobian of an array of expressions with respect to an array of variable expressions.

source
Symbolics.sparsejacobian_valsFunction
sparsejacobian_vals(ops, vars, I, J; simplify)
-

A helper function for computing the values of the sparse Jacobian of an array of expressions with respect to an array of variable expressions given the sparsity structure.

source
Symbolics.gradientFunction
gradient(O, vars; simplify)
-

A helper function for computing the gradient of the expression O with respect to an array of variable expressions.

source
Symbolics.hessianFunction
hessian(O, vars; simplify)
-

A helper function for computing the Hessian of the expression O with respect to an array of variable expressions.

source
Symbolics.sparsehessianFunction
sparsehessian(op, vars; simplify, full)
-

A helper function for computing the sparse Hessian of an expression with respect to an array of variable expressions.

source
Symbolics.sparsehessian_valsFunction
sparsehessian_vals(op, vars, I, J; simplify)
-

A helper function for computing the values of the sparse Hessian of an expression with respect to an array of variable expressions given the sparsity structure.

source

Adding Analytical Derivatives

There are many derivatives pre-defined by DiffRules.jl. For example,

using Symbolics
+(k*((2abs(x - y)) / y - 2z)*IfElse.ifelse(signbit(x - y), -1, 1)) / y
source
Missing docstring.

Missing docstring for is_derivative. Check Documenter's build log for details.

Note

For symbolic differentiation, all registered functions in the symbolic expression need a registered derivative. For more information, see the function registration page.

High-Level Differentiation Functions

The following functions are not exported and thus must be accessed in a namespaced way, i.e. Symbolics.jacobian.

Symbolics.derivativeFunction
derivative(O, var; simplify)
+

A helper function for computing the derivative of the expression O with respect to var.

source
Symbolics.jacobianFunction
jacobian(ops, vars; simplify, scalarize)
+

A helper function for computing the Jacobian of an array of expressions with respect to an array of variable expressions.

source
Symbolics.sparsejacobianFunction
sparsejacobian(ops, vars; simplify)
+

A helper function for computing the sparse Jacobian of an array of expressions with respect to an array of variable expressions.

source
Symbolics.sparsejacobian_valsFunction
sparsejacobian_vals(ops, vars, I, J; simplify)
+

A helper function for computing the values of the sparse Jacobian of an array of expressions with respect to an array of variable expressions given the sparsity structure.

source
Symbolics.gradientFunction
gradient(O, vars; simplify)
+

A helper function for computing the gradient of the expression O with respect to an array of variable expressions.

source
Symbolics.hessianFunction
hessian(O, vars; simplify)
+

A helper function for computing the Hessian of the expression O with respect to an array of variable expressions.

source
Symbolics.sparsehessianFunction
sparsehessian(op, vars; simplify, full)
+

A helper function for computing the sparse Hessian of an expression with respect to an array of variable expressions.

source
Symbolics.sparsehessian_valsFunction
sparsehessian_vals(op, vars, I, J; simplify)
+

A helper function for computing the values of the sparse Hessian of an expression with respect to an array of variable expressions given the sparsity structure.

source

Adding Analytical Derivatives

There are many derivatives pre-defined by DiffRules.jl. For example,

using Symbolics
 @variables x y z
 f(x,y,z) = x^2 + sin(x+y) - z
f (generic function with 1 method)

f automatically has the derivatives defined via the tracing mechanism. It will do this by directly building the internals of your function and differentiating that.

However, often you may want to define your own derivatives so that way automatic Jacobian etc. calculations can utilize this information. This can allow for more succinct versions of the derivatives to be calculated to scale to larger systems. You can define derivatives for your function via the dispatch:

# `N` arguments are accepted by the relevant method of `my_function`
-Symbolics.derivative(::typeof(my_function), args::NTuple{N,Any}, ::Val{i})

where i means that it's the derivative with respect to the ith argument. args is the array of arguments, so, for example, if your function is f(x,t), then args = [x,t]. You should return an Term for the derivative of your function.

For example, sin(t)'s derivative (by t) is given by the following:

Symbolics.derivative(::typeof(sin), args::NTuple{1,Any}, ::Val{1}) = cos(args[1])
+Symbolics.derivative(::typeof(my_function), args::NTuple{N,Any}, ::Val{i})

where i means that it's the derivative with respect to the ith argument. args is the array of arguments, so, for example, if your function is f(x,t), then args = [x,t]. You should return an Term for the derivative of your function.

For example, sin(t)'s derivative (by t) is given by the following:

Symbolics.derivative(::typeof(sin), args::NTuple{1,Any}, ::Val{1}) = cos(args[1])
diff --git a/dev/manual/expression_manipulation/index.html b/dev/manual/expression_manipulation/index.html index 1708592a8..bdd5a2a17 100644 --- a/dev/manual/expression_manipulation/index.html +++ b/dev/manual/expression_manipulation/index.html @@ -8,7 +8,7 @@ julia> ex = x + y + sin(z) (x + y) + sin(z(t)) julia> substitute(ex, Dict([x => z, sin(z) => z^2])) -(z(t) + y) + (z(t) ^ 2)source
SymbolicUtils.simplifyFunction
simplify(x; expand=false,
+(z(t) + y) + (z(t) ^ 2)
source
SymbolicUtils.simplifyFunction
simplify(x; expand=false,
             threaded=false,
             thread_subtree_cutoff=100,
             rewriter=nothing)

Simplify an expression (x) by applying rewriter until there are no changes. expand=true applies expand in the beginning of each fixpoint iteration.

By default, simplify will assume denominators are not zero and allow cancellation in fractions. Pass simplify_fractions=false to prevent this.

source

Documentation for rewriter can be found here, using the @rule macro or the @acrule macro from SymbolicUtils.jl.

Additional Manipulation Functions

Other additional manipulation functions are given below.

Symbolics.get_variablesFunction
get_variables(O) -> Vector{BasicSymbolic}

Returns the variables in the expression. Note that the returned variables are not wrapped in the Num type.

Examples

julia> @variables t x y z(t)
@@ -25,7 +25,7 @@
 3-element Vector{Any}:
  x
  y
- z(t)
source
Symbolics.tosymbolFunction
tosymbol(x::Union{Num,Symbolic}; states=nothing, escape=true) -> Symbol

Convert x to a symbol. states are the states of a system, and escape means if the target has escapes like val"y(t)". If escape is false, then it will only output y instead of y(t).

Examples

julia> @variables t z(t)
+ z(t)
source
Symbolics.tosymbolFunction
tosymbol(x::Union{Num,Symbolic}; states=nothing, escape=true) -> Symbol

Convert x to a symbol. states are the states of a system, and escape means if the target has escapes like val"y(t)". If escape is false, then it will only output y instead of y(t).

Examples

julia> @variables t z(t)
 2-element Vector{Num}:
     t
  z(t)
@@ -34,13 +34,13 @@
 Symbol("z(t)")
 
 julia> Symbolics.tosymbol(z; escape=false)
-:z
source
Symbolics.diff2termFunction
diff2term(x, x_metadata::Dict{Datatype, Any}) -> Symbolic

Convert a differential variable to a Term. Note that it only takes a Term not a Num. Any upstream metadata can be passed via x_metadata

julia> @variables x t u(x, t) z(t)[1:2]; Dt = Differential(t); Dx = Differential(x);
+:z
source
Symbolics.diff2termFunction
diff2term(x, x_metadata::Dict{Datatype, Any}) -> Symbolic

Convert a differential variable to a Term. Note that it only takes a Term not a Num. Any upstream metadata can be passed via x_metadata

julia> @variables x t u(x, t) z(t)[1:2]; Dt = Differential(t); Dx = Differential(x);
 
 julia> Symbolics.diff2term(Symbolics.value(Dx(Dt(u))))
 uˍtx(x, t)
 
 julia> Symbolics.diff2term(Symbolics.value(Dt(z[1])))
-var"z(t)[1]ˍt"
source
Symbolics.solve_forFunction
solve_for(eq, var; simplify, check) -> Any
+var"z(t)[1]ˍt"
source
Symbolics.solve_forFunction
solve_for(eq, var; simplify, check) -> Any
 

Solve equation(s) eqs for a set of variables vars.

Assumes length(eqs) == length(vars)

Currently only works if all equations are linear. check if the expr is linear w.r.t vars.

Examples

julia> @variables x y
 2-element Vector{Num}:
  x
@@ -52,7 +52,7 @@
 julia> Symbolics.solve_for([x + y ~ 0, x - y ~ 2], [x, y])
 2-element Vector{Float64}:
   1.0
- -1.0
source
Symbolics.degreeFunction
degree(p, sym=nothing)

Extract the degree of p with respect to sym.

Examples

julia> @variables x;
+ -1.0
source
Symbolics.degreeFunction
degree(p, sym=nothing)

Extract the degree of p with respect to sym.

Examples

julia> @variables x;
 
 julia> Symbolics.degree(x^0)
 0
@@ -61,7 +61,7 @@
 1
 
 julia> Symbolics.degree(x^2)
-2
source
Symbolics.coeffFunction
coeff(p, sym=nothing)

Extract the coefficient of p with respect to sym. Note that p might need to be expanded and/or simplified with expand and/or simplify.

Examples

julia> @variables a x y;
+2
source
Symbolics.coeffFunction
coeff(p, sym=nothing)

Extract the coefficient of p with respect to sym. Note that p might need to be expanded and/or simplified with expand and/or simplify.

Examples

julia> @variables a x y;
 
 julia> Symbolics.coeff(2a, x)
 0
@@ -70,7 +70,7 @@
 2
 
 julia> Symbolics.coeff(x^2 + y, x^2)
-1
source
Missing docstring.

Missing docstring for Symbolics.replace. Check Documenter's build log for details.

Base.occursinFunction
occursin(needle::Symbolic, haystack::Symbolic)

Determine whether the second argument contains the first argument. Note that this function doesn't handle associativity, commutativity, or distributivity.

source
Symbolics.filterchildrenFunction

filterchildren(c, x) Returns all parts of x that fufills the condition given in c. c can be a function or an expression. If it is a function, returns everything for which the function is true. If c is an expression, returns all expressions that matches it.

Examples:

@syms x
+1
source
Missing docstring.

Missing docstring for Symbolics.replace. Check Documenter's build log for details.

Base.occursinFunction
occursin(needle::Symbolic, haystack::Symbolic)

Determine whether the second argument contains the first argument. Note that this function doesn't handle associativity, commutativity, or distributivity.

source
Symbolics.filterchildrenFunction

filterchildren(c, x) Returns all parts of x that fufills the condition given in c. c can be a function or an expression. If it is a function, returns everything for which the function is true. If c is an expression, returns all expressions that matches it.

Examples:

@syms x
 Symbolics.filterchildren(x, log(x) + x + 1)

returns [x, x]

@variables t X(t)
 D = Differential(t)
-Symbolics.filterchildren(Symbolics.is_derivative, X + D(X) + D(X^2))

returns [Differential(t)(X(t)^2), Differential(t)(X(t))]

source
Symbolics.fixpoint_subFunction
fixpoint_sub(expr, dict; operator = Nothing)

Given a symbolic expression, equation or inequality expr perform the substitutions in dict recursively until the expression does not change. Substitutions that depend on one another will thus be recursively expanded. For example, fixpoint_sub(x, Dict(x => y, y => 3)) will return 3. The operator keyword can be specified to prevent substitution of expressions inside operators of the given type.

See also: fast_substitute.

source
Symbolics.fast_substituteFunction
fast_substitute(expr, dict; operator = Nothing)

Given a symbolic expression, equation or inequality expr perform the substitutions in dict. This only performs the substitutions once. For example, fast_substitute(x, Dict(x => y, y => 3)) will return y. The operator keyword can be specified to prevent substitution of expressions inside operators of the given type.

See also: fixpoint_sub.

source
+Symbolics.filterchildren(Symbolics.is_derivative, X + D(X) + D(X^2))

returns [Differential(t)(X(t)^2), Differential(t)(X(t))]

source
Symbolics.fixpoint_subFunction
fixpoint_sub(expr, dict; operator = Nothing)

Given a symbolic expression, equation or inequality expr perform the substitutions in dict recursively until the expression does not change. Substitutions that depend on one another will thus be recursively expanded. For example, fixpoint_sub(x, Dict(x => y, y => 3)) will return 3. The operator keyword can be specified to prevent substitution of expressions inside operators of the given type.

See also: fast_substitute.

source
Symbolics.fast_substituteFunction
fast_substitute(expr, dict; operator = Nothing)

Given a symbolic expression, equation or inequality expr perform the substitutions in dict. This only performs the substitutions once. For example, fast_substitute(x, Dict(x => y, y => 3)) will return y. The operator keyword can be specified to prevent substitution of expressions inside operators of the given type.

See also: fixpoint_sub.

source
diff --git a/dev/manual/faq/index.html b/dev/manual/faq/index.html index 07827af52..9504dcf72 100644 --- a/dev/manual/faq/index.html +++ b/dev/manual/faq/index.html @@ -16,4 +16,4 @@ x in [x] catch e e -end
TypeError(:if, "", Bool, x == x)
x in Set([x])
true
any(isequal(x), [x])
true

If == is used instead, you will receive TypeError: non-boolean (Num) used in boolean context. What this error is telling you is that the symbolic x == y expression is being used where a Bool is required, such as if x == y, and since the symbolic expression is held lazily this will error because the appropriate branch cannot be selected (since x == y is unknown for arbitrary symbolic values!). This is why the check isequal(x,y) is required, since this is a non-lazy check of whether the symbol x is always equal to the symbol y, rather than an expression of whether x and y currently have the same value.

+end
TypeError(:if, "", Bool, x == x)
x in Set([x])
true
any(isequal(x), [x])
true

If == is used instead, you will receive TypeError: non-boolean (Num) used in boolean context. What this error is telling you is that the symbolic x == y expression is being used where a Bool is required, such as if x == y, and since the symbolic expression is held lazily this will error because the appropriate branch cannot be selected (since x == y is unknown for arbitrary symbolic values!). This is why the check isequal(x,y) is required, since this is a non-lazy check of whether the symbol x is always equal to the symbol y, rather than an expression of whether x and y currently have the same value.

diff --git a/dev/manual/functions/index.html b/dev/manual/functions/index.html index 1863cb232..9b2738ec5 100644 --- a/dev/manual/functions/index.html +++ b/dev/manual/functions/index.html @@ -9,9 +9,9 @@ du = Array{Any}(undef, 3) lorenz(du,u,p,t) du
3-element Vector{Any}:
-                         10.0(-(u(t))[1] + (u(t))[2])
- -(u(t))[2] + (u(t))[1]*(28.0 - (u(t))[3])
-                         -2.6666666666666665(u(t))[3] + (u(t))[1]*(u(t))[2]

Or similarly:

@variables t x(t) y(t) z(t) dx(t) dy(t) dz(t) σ ρ β
+                       10.0(-(u(t))[1] + (u(t))[2])
+          -(u(t))[2] + (u(t))[1]*(28.0 - (u(t))[3])
+ -2.6666666666666665(u(t))[3] + (u(t))[1]*(u(t))[2]

Or similarly:

@variables t x(t) y(t) z(t) dx(t) dy(t) dz(t) σ ρ β
 du = [dx,dy,dz]
 u = [x,y,z]
 p = [σ,ρ,β]
@@ -41,14 +41,14 @@
  \]

Note that at this time array derivatives cannot be defined.

Registration API

Symbolics.@register_symbolicMacro
@register_symbolic(expr, define_promotion = true, Ts = [Real])

Overload appropriate methods so that Symbolics can stop tracing into the registered function. If define_promotion is true, then a promotion method in the form of

SymbolicUtils.promote_symtype(::typeof(f_registered), args...) = Real # or the annotated return type

is defined for the register function. Note that when defining multiple register overloads for one function, all the rest of the registers must set define_promotion to false except for the first one, to avoid method overwriting.

Examples

@register_symbolic foo(x, y)
 @register_symbolic foo(x, y::Bool) false # do not overload a duplicate promotion rule
 @register_symbolic goo(x, y::Int) # `y` is not overloaded to take symbolic objects
-@register_symbolic hoo(x, y)::Int # `hoo` returns `Int`

See @register_array_symbolic to register functions which return arrays.

source
Symbolics.@register_array_symbolicMacro
@register_array_symbolic(expr, define_promotion = true)

Example:

# Let's say vandermonde takes an n-vector and returns an n x n matrix
+@register_symbolic hoo(x, y)::Int # `hoo` returns `Int`

See @register_array_symbolic to register functions which return arrays.

source
Symbolics.@register_array_symbolicMacro
@register_array_symbolic(expr, define_promotion = true)

Example:

# Let's say vandermonde takes an n-vector and returns an n x n matrix
 @register_array_symbolic vandermonde(x::AbstractVector) begin
     size=(length(x), length(x))
     eltype=eltype(x) # optional, will default to the promoted eltypes of x
 end

You can also register calls on callable structs:

@register_array_symbolic (c::Conv)(x::AbstractMatrix) begin
     size=size(x) .- size(c.kernel) .+ 1
     eltype=promote_type(eltype(x), eltype(c))
-end

If define_promotion = true then a promotion method in the form of

SymbolicUtils.promote_symtype(::typeof(f_registered), args...) = # inferred or annotated return type

is defined for the register function. Note that when defining multiple register overloads for one function, all the rest of the registers must set define_promotion to false except for the first one, to avoid method overwriting.

source

Direct Registration API (Advanced, Experimental)

Warn

This is a lower level API which is not as stable as the macro APIs.

In some circumstances you may need to use the direct API in order to define registration on functions or types without using the macro. This is done by directly defining dispatches on symbolic objects.

A good example of this is DataInterpolations.jl's interpolations object. On an interpolation by a symbolic variable, we generate the symbolic function (the term) for the interpolation function. This looks like:

using DataInterpolations, Symbolics, SymbolicUtils
+end

If define_promotion = true then a promotion method in the form of

SymbolicUtils.promote_symtype(::typeof(f_registered), args...) = # inferred or annotated return type

is defined for the register function. Note that when defining multiple register overloads for one function, all the rest of the registers must set define_promotion to false except for the first one, to avoid method overwriting.

source

Direct Registration API (Advanced, Experimental)

Warn

This is a lower level API which is not as stable as the macro APIs.

In some circumstances you may need to use the direct API in order to define registration on functions or types without using the macro. This is done by directly defining dispatches on symbolic objects.

A good example of this is DataInterpolations.jl's interpolations object. On an interpolation by a symbolic variable, we generate the symbolic function (the term) for the interpolation function. This looks like:

using DataInterpolations, Symbolics, SymbolicUtils
 (interp::AbstractInterpolation)(t::Num) = SymbolicUtils.term(interp, unwrap(t))

In order for this to work, it is required that we define the symtype for the symbolic type inference. This is done via:

SymbolicUtils.promote_symtype(t::AbstractInterpolation, args...) = Real

Additionally a symbolic name is required:

Base.nameof(interp::AbstractInterpolation) = :Interpolation

The derivative is defined similarly to the macro case:

function Symbolics.derivative(interp::AbstractInterpolation, args::NTuple{1, Any}, ::Val{1})
     Symbolics.unwrap(derivative(interp, Symbolics.wrap(args[1])))
-end
+end
diff --git a/dev/manual/groebner/index.html b/dev/manual/groebner/index.html index 331a54a96..0e2710896 100644 --- a/dev/manual/groebner/index.html +++ b/dev/manual/groebner/index.html @@ -1,2 +1,2 @@ -Groebner bases · Symbolics.jl

Groebner bases

Groebner bases use the implementation of the F4 algorithm from Groebner.jl package as its backend. We refer to the documentation of Groebner.jl, which lists some implementations details and possible use-cases of Groebner bases.

Symbolics.groebner_basisFunction
groebner_basis(polynomials)

Computes a Groebner basis of the ideal generated by the given polynomials.

This function requires a Groebner bases backend (such as Groebner.jl) to be loaded.

source
+Groebner bases · Symbolics.jl

Groebner bases

Groebner bases use the implementation of the F4 algorithm from Groebner.jl package as its backend. We refer to the documentation of Groebner.jl, which lists some implementations details and possible use-cases of Groebner bases.

Symbolics.groebner_basisFunction
groebner_basis(polynomials)

Computes a Groebner basis of the ideal generated by the given polynomials.

This function requires a Groebner bases backend (such as Groebner.jl) to be loaded.

source
diff --git a/dev/manual/io/index.html b/dev/manual/io/index.html index 63af1a4b4..28c9743ff 100644 --- a/dev/manual/io/index.html +++ b/dev/manual/io/index.html @@ -6,4 +6,4 @@ end ex1, ex2 = build_function(f(u),u) write("function.jl", string(ex2))
898

Now we can do something like:

g = include("function.jl")
#1 (generic function with 1 method)

and that will load the function back in. Note that this can be done to save the transformation results of Symbolics.jl so that they can be stored and used in a precompiled Julia package.

Latexification

Symbolics.jl's expressions support Latexify.jl, and thus

using Latexify
-latexify(ex)

will produce LaTeX output from Symbolics models and expressions. This works on basics like Term all the way to higher primitives like ODESystem and ReactionSystem.

+latexify(ex)

will produce LaTeX output from Symbolics models and expressions. This works on basics like Term all the way to higher primitives like ODESystem and ReactionSystem.

diff --git a/dev/manual/limits/index.html b/dev/manual/limits/index.html index f656817a8..51c40f7e4 100644 --- a/dev/manual/limits/index.html +++ b/dev/manual/limits/index.html @@ -1,2 +1,2 @@ -Symbolic Limits · Symbolics.jl

Symbolic Limits

Experimental symbolic limit support is provided by the limit function, documented below. See SymbolicLimits.jl for more information and implementation details.

Symbolics.limitFunction
limit(expr, var, h[, side::Symbol])

Compute the limit of expr as var approaches h.

side indicates the direction from which var approaches h. It may be one of :left, :right, or :both. If side is :both and the two sides do not align, an error is thrown. Side defaults to :both for finite h, :left for h = Inf, and :right for h = -Inf.

expr must be composed of log, exp, constants, and the rational operators +, -, *, and /. This limitation may eventually be relaxed.

Warning

Because symbolic limit computation is undecidable, this function necessarily employs heuristics and may occasionally return wrong answers. Nevertheless, please report wrong answers as issues as we aim to have heuristics that produce correct answers in all practical cases.

source
+Symbolic Limits · Symbolics.jl

Symbolic Limits

Experimental symbolic limit support is provided by the limit function, documented below. See SymbolicLimits.jl for more information and implementation details.

Symbolics.limitFunction
limit(expr, var, h[, side::Symbol])

Compute the limit of expr as var approaches h.

side indicates the direction from which var approaches h. It may be one of :left, :right, or :both. If side is :both and the two sides do not align, an error is thrown. Side defaults to :both for finite h, :left for h = Inf, and :right for h = -Inf.

expr must be composed of log, exp, constants, and the rational operators +, -, *, and /. This limitation may eventually be relaxed.

Warning

Because symbolic limit computation is undecidable, this function necessarily employs heuristics and may occasionally return wrong answers. Nevertheless, please report wrong answers as issues as we aim to have heuristics that produce correct answers in all practical cases.

source
diff --git a/dev/manual/parsing/index.html b/dev/manual/parsing/index.html index a231e2586..4ac58aebf 100644 --- a/dev/manual/parsing/index.html +++ b/dev/manual/parsing/index.html @@ -15,4 +15,4 @@ z ~ 2] all(isequal.(eqs,ex)) # true

Limitations

Symbolic-ness Tied to Environment Definitions

The parsing to a symbolic expression has to be able to recognize the difference between functions, numbers, and globals defined within one's Julia environment and those that are to be made symbolic. The way this functionality handles this problem is that it does not define anything as symbolic that is already defined in the chosen mod module. For example, f(x,y) will have f as non-symbolic if the function f (named f) is defined in mod, i.e. if isdefined(mod,:f) is true. When the symbol is defined, it will be replaced by its value. Notably, this means that the parsing behavior changes depending on the environment that it is applied.

For example:

parse_expr_to_symbolic(:(x - y),@__MODULE__) # x - y
 x = 2.0
-parse_expr_to_symbolic(:(x - y),@__MODULE__) # 2.0 - y

This is required to detect that standard functions like - are functions instead of symbolic symbols. For safety, one should create anonymous modules or other sub-environments to ensure no stray variables are defined.

Metadata is Blank

Because all the variables defined by the expressions are not defined with the standard @variables, there is no metadata that is or can be associated with any of the generated variables. Instead, they all have blank metadata, but are defined in the Real domain. Thus, the variables which come out of this parsing may not evaluate as equal to a symbolic variable defined elsewhere.

source
Missing docstring.

Missing docstring for @parse_expr_to_symbolic. Check Documenter's build log for details.

+parse_expr_to_symbolic(:(x - y),@__MODULE__) # 2.0 - y

This is required to detect that standard functions like - are functions instead of symbolic symbols. For safety, one should create anonymous modules or other sub-environments to ensure no stray variables are defined.

Metadata is Blank

Because all the variables defined by the expressions are not defined with the standard @variables, there is no metadata that is or can be associated with any of the generated variables. Instead, they all have blank metadata, but are defined in the Real domain. Thus, the variables which come out of this parsing may not evaluate as equal to a symbolic variable defined elsewhere.

source
Missing docstring.

Missing docstring for @parse_expr_to_symbolic. Check Documenter's build log for details.

diff --git a/dev/manual/sparsity_detection/index.html b/dev/manual/sparsity_detection/index.html index 6d70735cd..1aae3a878 100644 --- a/dev/manual/sparsity_detection/index.html +++ b/dev/manual/sparsity_detection/index.html @@ -17,7 +17,7 @@ 3×2 SparseArrays.SparseMatrixCSC{Bool, Int64} with 4 stored entries: 1 ⋅ ⋅ 1 - 1 1source
jacobian_sparsity(
+ 1  1
source
jacobian_sparsity(
     f!::Function,
     output::AbstractArray,
     input::AbstractArray,
@@ -36,7 +36,7 @@
 3×2 SparseArrays.SparseMatrixCSC{Bool, Int64} with 4 stored entries:
  ⋅  1
  1  ⋅
- 1  1
source
Symbolics.hessian_sparsityFunction
hessian_sparsity(
+ 1  1
source
Symbolics.hessian_sparsityFunction
hessian_sparsity(
     expr,
     vars::AbstractVector;
     full
@@ -50,7 +50,7 @@
 julia> Symbolics.hessian_sparsity(expr, vars)
 2×2 SparseArrays.SparseMatrixCSC{Bool, Int64} with 3 stored entries:
  1  1
- 1  ⋅
source
hessian_sparsity(
+ 1  ⋅
source
hessian_sparsity(
     f::Function,
     input::AbstractVector,
     args...;
@@ -66,6 +66,6 @@
 julia> Symbolics.hessian_sparsity(f, input)
 2×2 SparseArrays.SparseMatrixCSC{Bool, Int64} with 3 stored entries:
  ⋅  1
- 1  1
source

Structure Detection

Symbolics.islinearFunction
islinear(ex, u)
-

Check if an expression is linear with respect to a list of variable expressions.

source
Symbolics.isaffineFunction
isaffine(ex, u)
-

Check if an expression is affine with respect to a list of variable expressions.

source

ADTypes.jl interface

Symbolics.SymbolicsSparsityDetectorType
SymbolicsSparsityDetector <: ADTypes.AbstractSparsityDetector

Sparsity detection algorithm based on the Symbolics.jl tracing system.

This type makes Symbolics.jl compatible with the ADTypes.jl sparsity detection framework. The following functions are implemented:

Reference

Sparsity Programming: Automated Sparsity-Aware Optimizations in Differentiable Programming, Gowda et al. (2019)

source
+ 1 1source

Structure Detection

Symbolics.islinearFunction
islinear(ex, u)
+

Check if an expression is linear with respect to a list of variable expressions.

source
Symbolics.isaffineFunction
isaffine(ex, u)
+

Check if an expression is affine with respect to a list of variable expressions.

source

ADTypes.jl interface

Symbolics.SymbolicsSparsityDetectorType
SymbolicsSparsityDetector <: ADTypes.AbstractSparsityDetector

Sparsity detection algorithm based on the Symbolics.jl tracing system.

This type makes Symbolics.jl compatible with the ADTypes.jl sparsity detection framework. The following functions are implemented:

Reference

Sparsity Programming: Automated Sparsity-Aware Optimizations in Differentiable Programming, Gowda et al. (2019)

source
diff --git a/dev/manual/types/index.html b/dev/manual/types/index.html index 726870759..077b1b978 100644 --- a/dev/manual/types/index.html +++ b/dev/manual/types/index.html @@ -5,4 +5,4 @@ z X[1:10,1:10] Z[1:10] - s
typeof(x)
Num
typeof(z)
Complex{Num}
typeof(X)
Symbolics.Arr{Num, 2}
typeof(Z)
Symbolics.Arr{Complex{Num}, 1}
typeof(s)
SymbolicUtils.BasicSymbolic{String}
+ s
typeof(x)
Num
typeof(z)
Complex{Num}
typeof(X)
Symbolics.Arr{Num, 2}
typeof(Z)
Symbolics.Arr{Complex{Num}, 1}
typeof(s)
SymbolicUtils.BasicSymbolic{String}
diff --git a/dev/manual/variables/index.html b/dev/manual/variables/index.html index aa7e8286a..0defb878c 100644 --- a/dev/manual/variables/index.html +++ b/dev/manual/variables/index.html @@ -28,15 +28,15 @@ (value_c(t))[1:3] julia> (t, a, b, c) -(t, :runtime_symbol_value, :value_b, :value_c)source
Symbolics.variableFunction
variable(name::Symbol, idx::Integer...; T=Real)

Create a variable with the given name along with subscripted indices with the symtype=T. When T=FnType, it creates a symbolic function.

julia> Symbolics.variable(:x, 4, 2, 0)
+(t, :runtime_symbol_value, :value_b, :value_c)
source
Symbolics.variableFunction
variable(name::Symbol, idx::Integer...; T=Real)

Create a variable with the given name along with subscripted indices with the symtype=T. When T=FnType, it creates a symbolic function.

julia> Symbolics.variable(:x, 4, 2, 0)
 x₄ˏ₂ˏ₀
 
 julia> Symbolics.variable(:x, 4, 2, 0, T=Symbolics.FnType)
-x₄ˏ₂ˏ₀⋆

Also see variables.

source
Symbolics.variablesFunction
variables(name::Symbol, indices...)

Create a multi-dimensional array of individual variables named with subscript notation. Use @variables instead to create symbolic array variables (as opposed to array of variables). See variable to create one variable with subscripts.

julia> Symbolics.variables(:x, 1:3, 3:6)
+x₄ˏ₂ˏ₀⋆

Also see variables.

source
Symbolics.variablesFunction
variables(name::Symbol, indices...)

Create a multi-dimensional array of individual variables named with subscript notation. Use @variables instead to create symbolic array variables (as opposed to array of variables). See variable to create one variable with subscripts.

julia> Symbolics.variables(:x, 1:3, 3:6)
 3×4 Matrix{Num}:
  x₁ˏ₃  x₁ˏ₄  x₁ˏ₅  x₁ˏ₆
  x₂ˏ₃  x₂ˏ₄  x₂ˏ₅  x₂ˏ₆
- x₃ˏ₃  x₃ˏ₄  x₃ˏ₅  x₃ˏ₆
source
Symbolics.EquationType
struct Equation

An equality relationship between two expressions.

Fields

  • lhs: The expression on the left-hand side of the equation.

  • rhs: The expression on the right-hand side of the equation.

source
Base.:~Method
~(lhs, rhs) -> Any
+ x₃ˏ₃  x₃ˏ₄  x₃ˏ₅  x₃ˏ₆
source
Symbolics.EquationType
struct Equation

An equality relationship between two expressions.

Fields

  • lhs: The expression on the left-hand side of the equation.

  • rhs: The expression on the right-hand side of the equation.

source
Base.:~Method
~(lhs, rhs) -> Any
 

Create an Equation out of two Num instances, or an Num and a Number.

Examples

julia> using Symbolics
 
 julia> @variables x y;
@@ -53,7 +53,7 @@
 (broadcast(~, A, B))[1:3,1:3]
 
 julia> A .~ 3x
-(broadcast(~, A, 3x))[1:3,1:3]
source

A note about functions restricted to Numbers

Sym and Term objects are NOT subtypes of Number. Symbolics provides a simple wrapper type called Num which is a subtype of Real. Num wraps either a Sym or a Term or any other object, defines the same set of operations as symbolic expressions and forwards those to the values it wraps. You can use Symbolics.value function to unwrap a Num.

By default, the @variables macros return Num-wrapped objects to allow calling functions which are restricted to Number or Real.

using Symbolics
+(broadcast(~, A, 3x))[1:3,1:3]
source

A note about functions restricted to Numbers

Sym and Term objects are NOT subtypes of Number. Symbolics provides a simple wrapper type called Num which is a subtype of Real. Num wraps either a Sym or a Term or any other object, defines the same set of operations as symbolic expressions and forwards those to the values it wraps. You can use Symbolics.value function to unwrap a Num.

By default, the @variables macros return Num-wrapped objects to allow calling functions which are restricted to Number or Real.

using Symbolics
 @variables t x y z(t);
 Symbolics.operation(Symbolics.value(x + y))
+ (generic function with 482 methods)
Symbolics.operation(Symbolics.value(z))

\[ \begin{equation} z @@ -68,4 +68,4 @@ f(t)

\[ \begin{equation} 1 + t \left( \frac{2}{3} + \frac{4}{5} \mathrm{identity}\left( \pi \right) \right) \end{equation} - \]

This will work for any floating-point input, as well as symbolic input.

Symbolic Control Flow

Control flow can be expressed in Symbolics.jl in the following ways:

Inspection Functions

Missing docstring.

Missing docstring for SymbolicUtils.iscall. Check Documenter's build log for details.

Missing docstring.

Missing docstring for SymbolicUtils.operation. Check Documenter's build log for details.

Missing docstring.

Missing docstring for SymbolicUtils.arguments. Check Documenter's build log for details.

+ \]

This will work for any floating-point input, as well as symbolic input.

Symbolic Control Flow

Control flow can be expressed in Symbolics.jl in the following ways:

Inspection Functions

Missing docstring.

Missing docstring for SymbolicUtils.iscall. Check Documenter's build log for details.

Missing docstring.

Missing docstring for SymbolicUtils.operation. Check Documenter's build log for details.

Missing docstring.

Missing docstring for SymbolicUtils.arguments. Check Documenter's build log for details.

diff --git a/dev/tutorials/auto_parallel/22047751.svg b/dev/tutorials/auto_parallel/3e96ca63.svg similarity index 58% rename from dev/tutorials/auto_parallel/22047751.svg rename to dev/tutorials/auto_parallel/3e96ca63.svg index 3de686789..2aebd8731 100644 --- a/dev/tutorials/auto_parallel/22047751.svg +++ b/dev/tutorials/auto_parallel/3e96ca63.svg @@ -1,13222 +1,13222 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/tutorials/auto_parallel/index.html b/dev/tutorials/auto_parallel/index.html index 119a9cd67..ebbfcdaf2 100644 --- a/dev/tutorials/auto_parallel/index.html +++ b/dev/tutorials/auto_parallel/index.html @@ -59,7 +59,7 @@ \]

The output, here the in-place modified du, is a symbolic representation of each output of the function. We can then utilize this in the Symbolics functionality. For example, let's build a parallel version of f first:

fastf = eval(Symbolics.build_function(du,u,
             parallel=Symbolics.MultithreadedForm())[2])
#13 (generic function with 1 method)

Now let's compute the sparse Jacobian function and compile a fast multithreaded version:

jac = Symbolics.sparsejacobian(vec(du), vec(u))
 row,col,val = findnz(jac)
-scatter(row,col,legend=false,ms=1,c=:black)
Example block output
fjac = eval(Symbolics.build_function(jac,u,
+scatter(row,col,legend=false,ms=1,c=:black)
Example block output
fjac = eval(Symbolics.build_function(jac,u,
             parallel=Symbolics.MultithreadedForm())[2])
#15 (generic function with 1 method)

It takes awhile for this to generate, but the results will be worth it! Now let's set up the parabolic PDE to be solved by DifferentialEquations.jl. We will set up the vanilla version and the sparse multithreaded version:

using OrdinaryDiffEq
 u0 = zeros(N, N, 3)
 MyA = zeros(N, N);
@@ -139,4 +139,4 @@
  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0

Let's see the timing difference:

using BenchmarkTools
 #@btime solve(prob, TRBDF2()); # 33.073 s (895404 allocations: 23.87 GiB)
 #warning the following solve takes a long time to compile, but afterwards is very fast.
-#@btime solve(fastprob, TRBDF2()); # 209.670 ms (8208 allocations: 109.25 MiB)

Boom, an automatic 157x acceleration that grows as the size of the problem increases!

+#@btime solve(fastprob, TRBDF2()); # 209.670 ms (8208 allocations: 109.25 MiB)

Boom, an automatic 157x acceleration that grows as the size of the problem increases!

diff --git a/dev/tutorials/converting_to_C/index.html b/dev/tutorials/converting_to_C/index.html index b4cfa8bc9..e65d515c7 100644 --- a/dev/tutorials/converting_to_C/index.html +++ b/dev/tutorials/converting_to_C/index.html @@ -18,11 +18,11 @@ \end{equation} \]

and then we build the function:

build_function(du, u, p, t, target=Symbolics.CTarget())
"#include <math.h>\nvoid diffeqf(double* du, const double* RHS1, const double* RHS2, const double RHS3) {\n  du[0] = RHS2[0] * RHS1[0] + -1 * RHS2[1] * RHS1[0] * RHS1[1];\n  du[1] = -1 * RHS2[2] * RHS1[1] + RHS2[3] * RHS1[0] * RHS1[1];\n}\n"

If we want to compile this, we do expression=Val{false}:

f = build_function(du, u, p, t, target=Symbolics.CTarget(), expression=Val{false})
RuntimeGeneratedFunction(#=in Symbolics=#, #=using Symbolics=#, :((du, u, p, t)->begin
           #= /home/runner/work/Symbolics.jl/Symbolics.jl/src/build_function.jl:809 =#
-          ccall(("diffeqf", "/tmp/jl_4DKrEHEXoL"), Cvoid, (Ptr{Float64}, Ptr{Float64}, Ptr{Float64}, Float64), du, u, p, t)
+          ccall(("diffeqf", "/tmp/jl_sfqHmrWVYj"), Cvoid, (Ptr{Float64}, Ptr{Float64}, Ptr{Float64}, Float64), du, u, p, t)
       end))

now we check it computes the same thing:

du = rand(2); du2 = rand(2)
 u = rand(2)
 p = rand(4)
 t = rand()
 f(du, u, p, t)
 lotka_volterra!(du2, u, p, t)
-du == du2 # true!
true
+du == du2 # true!
true