From 669d63212749e8f3b35051090e3e505e1506eb51 Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Sun, 29 Oct 2023 15:32:14 +0000 Subject: [PATCH] build based on 43f93d0 --- dev/.documenter-siteinfo.json | 2 +- dev/assets/Manifest.toml | 94 +- dev/comparison/index.html | 2 +- dev/examples/perturbation/index.html | 2 +- dev/getting_started/index.html | 12 +- dev/index.html | 44 +- 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 | 14 +- dev/manual/faq/index.html | 2 +- dev/manual/functions/index.html | 2 +- dev/manual/groebner/index.html | 2 +- dev/manual/io/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 | 6 +- .../{9bde950c.svg => 05553dca.svg} | 26414 ++++++++-------- dev/tutorials/auto_parallel/index.html | 4 +- dev/tutorials/converting_to_C/index.html | 4 +- 21 files changed, 13336 insertions(+), 13320 deletions(-) rename dev/tutorials/auto_parallel/{9bde950c.svg => 05553dca.svg} (58%) diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index f11a1c54b..6b086e464 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.9.3","generation_timestamp":"2023-10-18T09:05:39","documenter_version":"1.1.1"}} \ No newline at end of file +{"documenter":{"julia_version":"1.9.3","generation_timestamp":"2023-10-29T15:32:03","documenter_version":"1.1.2"}} \ No newline at end of file diff --git a/dev/assets/Manifest.toml b/dev/assets/Manifest.toml index 34d3c2da2..0ccb872a4 100644 --- a/dev/assets/Manifest.toml +++ b/dev/assets/Manifest.toml @@ -16,9 +16,9 @@ version = "0.0.1" [[deps.AbstractAlgebra]] deps = ["GroupsCore", "InteractiveUtils", "LinearAlgebra", "MacroTools", "Preferences", "Random", "RandomExtensions", "SparseArrays", "Test"] -git-tree-sha1 = "c3c29bf6363b3ac3e421dc8b2ba8e33bdacbd245" +git-tree-sha1 = "ce0cb2804273e9147a765501c719038247d7ccd9" uuid = "c3fe647b-3220-5bb0-a1ea-a7954cac585d" -version = "0.32.5" +version = "0.33.0" [[deps.AbstractTrees]] git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" @@ -27,9 +27,9 @@ version = "0.4.4" [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "76289dc51920fdc6e0013c872ba9551d54961c24" +git-tree-sha1 = "02f731463748db57cc2ebfbd9fbc9ce8280d3433" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "3.6.2" +version = "3.7.1" weakdeps = ["StaticArrays"] [deps.Adapt.extensions] @@ -47,9 +47,9 @@ version = "0.2.0" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "f83ec24f76d4c8f525099b2ac475fc098138ec31" +git-tree-sha1 = "eba0af42241f0cb648806604222bab1e064edb67" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.4.11" +version = "7.5.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -86,9 +86,9 @@ uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" version = "1.3.2" [[deps.Bijections]] -git-tree-sha1 = "71281c0c28f97e0adeed24fdaa6bf7d37177f297" +git-tree-sha1 = "c9b163bd832e023571e86d0b90d9de92a9879088" uuid = "e2ed5e7c-b2de-5872-ae92-c73ca462fb04" -version = "0.1.5" +version = "0.1.6" [[deps.BitFlags]] git-tree-sha1 = "43b1a4a8f797c1cddadf60499a8a077d4af2cd2d" @@ -272,9 +272,9 @@ version = "1.9.1" [[deps.DiffEqBase]] deps = ["ArrayInterface", "ChainRulesCore", "DataStructures", "DocStringExtensions", "EnumX", "EnzymeCore", "FastBroadcast", "ForwardDiff", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "Parameters", "PreallocationTools", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Static", "StaticArraysCore", "Statistics", "Tricks", "TruncatedStacktraces", "ZygoteRules"] -git-tree-sha1 = "95b6df71e218379a831874215b0effaac791d7d7" +git-tree-sha1 = "59842b690c2ed12428a741c1334f3c68d1377fb6" uuid = "2b5f629d-d688-5b77-993f-72d75c75574e" -version = "6.133.1" +version = "6.135.0" [deps.DiffEqBase.extensions] DiffEqBaseDistributionsExt = "Distributions" @@ -349,9 +349,9 @@ version = "0.9.3" [[deps.Documenter]] deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "Dates", "DocStringExtensions", "Downloads", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "Test", "Unicode"] -git-tree-sha1 = "147a3cbb6ddcd9448fe5e6c426b347efc68f9c86" +git-tree-sha1 = "662fb21ae7fad33e044c2b59ece832fdce32c171" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.1.1" +version = "1.1.2" [[deps.DomainSets]] deps = ["CompositeTypes", "IntervalSets", "LinearAlgebra", "Random", "StaticArrays", "Statistics"] @@ -383,9 +383,9 @@ version = "1.0.4" [[deps.EnzymeCore]] deps = ["Adapt"] -git-tree-sha1 = "d8701002a745c450c03b890f10d53636d1a8a7ea" +git-tree-sha1 = "ab81396e4e7b61f5590db02fa1c17fae4f16d7ab" uuid = "f151be2c-9106-41f4-ab19-57ee4f262869" -version = "0.6.2" +version = "0.6.3" [[deps.EpollShim_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -450,9 +450,9 @@ uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[deps.FillArrays]] deps = ["LinearAlgebra", "Random"] -git-tree-sha1 = "a20eaa3ad64254c61eeb5f230d9306e937405434" +git-tree-sha1 = "35f0c0f345bff2c6d636f95fdb136323b5a796ef" uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.6.1" +version = "1.7.0" weakdeps = ["SparseArrays", "Statistics"] [deps.FillArrays.extensions] @@ -590,10 +590,10 @@ uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" version = "1.0.2" [[deps.Groebner]] -deps = ["AbstractAlgebra", "Combinatorics", "ExprTools", "Logging", "MultivariatePolynomials", "Primes", "Random", "SIMD", "SnoopPrecompile"] -git-tree-sha1 = "44f595de4f6485ab5ba71fe257b5eadaa3cf161e" +deps = ["AbstractAlgebra", "Combinatorics", "ExprTools", "Logging", "MultivariatePolynomials", "PrecompileTools", "Primes", "Printf", "Random", "SIMD", "TimerOutputs"] +git-tree-sha1 = "909ce267252dde0d10cccad539021c245fcfa20f" uuid = "0b43b601-686d-58a3-8a1c-6623616c7cd4" -version = "0.4.4" +version = "0.5.0" [[deps.GroupsCore]] deps = ["Markdown", "Random"] @@ -658,9 +658,9 @@ uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" [[deps.IntervalSets]] deps = ["Dates", "Random"] -git-tree-sha1 = "8e59ea773deee525c99a8018409f64f19fb719e6" +git-tree-sha1 = "3d8866c029dd6b16e69e0d4a939c4dfcb98fac47" uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.7.7" +version = "0.7.8" weakdeps = ["Statistics"] [deps.IntervalSets.extensions] @@ -869,11 +869,12 @@ uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[deps.LinearSolve]] deps = ["ArrayInterface", "ConcreteStructs", "DocStringExtensions", "EnumX", "EnzymeCore", "FastLapackInterface", "GPUArraysCore", "InteractiveUtils", "KLU", "Krylov", "Libdl", "LinearAlgebra", "MKL_jll", "PrecompileTools", "Preferences", "RecursiveFactorization", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Sparspak", "SuiteSparse", "UnPack"] -git-tree-sha1 = "9f27ba34f5821a0495efb09ea3a465c31326495a" +git-tree-sha1 = "a563cd835c9ed5295c35a7d140e0bf0a514bb10a" uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -version = "2.10.0" +version = "2.13.0" [deps.LinearSolve.extensions] + LinearSolveBandedMatricesExt = "BandedMatrices" LinearSolveBlockDiagonalsExt = "BlockDiagonals" LinearSolveCUDAExt = "CUDA" LinearSolveEnzymeExt = "Enzyme" @@ -883,8 +884,10 @@ version = "2.10.0" LinearSolveKrylovKitExt = "KrylovKit" LinearSolveMetalExt = "Metal" LinearSolvePardisoExt = "Pardiso" + LinearSolveRecursiveArrayToolsExt = "RecursiveArrayTools" [deps.LinearSolve.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" BlockDiagonals = "0a1fb500-61f7-11e9-3c65-f5ef3456f9f0" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" @@ -894,6 +897,7 @@ version = "2.10.0" KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" Metal = "dde4c033-4e86-420c-a63e-0dd931031962" Pardiso = "46dd5b70-b6fb-5a00-ae2d-e8fea33afaf2" + RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] @@ -1028,9 +1032,19 @@ version = "1.2.0" [[deps.NonlinearSolve]] deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "DiffEqBase", "EnumX", "FiniteDiff", "ForwardDiff", "LineSearches", "LinearAlgebra", "LinearSolve", "PrecompileTools", "RecursiveArrayTools", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "SparseArrays", "SparseDiffTools", "StaticArraysCore", "UnPack"] -git-tree-sha1 = "a5f1f836da05d513c4143576af8f5d8e51b759f5" +git-tree-sha1 = "adbde57261effaa44b4d3d5942651a4bb22aefc3" uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" -version = "2.2.1" +version = "2.5.0" + + [deps.NonlinearSolve.extensions] + NonlinearSolveBandedMatricesExt = "BandedMatrices" + NonlinearSolveFastLevenbergMarquardtExt = "FastLevenbergMarquardt" + NonlinearSolveLeastSquaresOptimExt = "LeastSquaresOptim" + + [deps.NonlinearSolve.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + FastLevenbergMarquardt = "7a0df574-e128-4d35-8cbd-3d84502bf7ce" + LeastSquaresOptim = "0fc2ff8b-aaa3-5acd-a817-1944a5e08891" [[deps.OffsetArrays]] deps = ["Adapt"] @@ -1256,9 +1270,9 @@ version = "0.6.12" [[deps.RecursiveArrayTools]] deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "IteratorInterfaceExtensions", "LinearAlgebra", "RecipesBase", "Requires", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "fa453b42ba1623bd2e70260bf44dac850a3430a7" +git-tree-sha1 = "d7087c013e8a496ff396bae843b1e16d9a30ede8" uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" -version = "2.39.0" +version = "2.38.10" [deps.RecursiveArrayTools.extensions] RecursiveArrayToolsMeasurementsExt = "Measurements" @@ -1342,17 +1356,19 @@ version = "0.6.39" [[deps.SciMLBase]] deps = ["ADTypes", "ArrayInterface", "ChainRulesCore", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FillArrays", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables", "TruncatedStacktraces", "ZygoteRules"] -git-tree-sha1 = "317f77cb31f7a0275cdd045aa7b3526ebc15c817" +git-tree-sha1 = "1c2a4e245744dd76b2eb677d3535ffad16d8b989" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.4.0" +version = "2.5.0" [deps.SciMLBase.extensions] + SciMLBasePartialFunctionsExt = "PartialFunctions" SciMLBasePyCallExt = "PyCall" SciMLBasePythonCallExt = "PythonCall" SciMLBaseRCallExt = "RCall" SciMLBaseZygoteExt = "Zygote" [deps.SciMLBase.weakdeps] + PartialFunctions = "570af359-4316-4cb7-8c74-252c00c2016b" PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" RCall = "6f49c342-dc21-5d91-9882-a32aef131414" @@ -1402,9 +1418,9 @@ version = "1.1.0" [[deps.SimpleNonlinearSolve]] deps = ["ArrayInterface", "DiffEqBase", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "PackageExtensionCompat", "PrecompileTools", "Reexport", "SciMLBase", "StaticArraysCore"] -git-tree-sha1 = "e308d089f5d0e733a017b61784c5813e672f760d" +git-tree-sha1 = "15ff97fa4881133caa324dacafe28b5ac47ad8a2" uuid = "727e6d20-b764-4bd8-a329-72de5adea6c7" -version = "0.1.22" +version = "0.1.23" [deps.SimpleNonlinearSolve.extensions] SimpleNonlinearSolveNNlibExt = "NNlib" @@ -1444,9 +1460,9 @@ uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [[deps.SparseDiffTools]] deps = ["ADTypes", "Adapt", "ArrayInterface", "Compat", "DataStructures", "FiniteDiff", "ForwardDiff", "Graphs", "LinearAlgebra", "PackageExtensionCompat", "Random", "Reexport", "SciMLOperators", "Setfield", "SparseArrays", "StaticArrayInterface", "StaticArrays", "Tricks", "UnPack", "VertexSafeGraphs"] -git-tree-sha1 = "336fd944a1bbb8873bfa8171387608ca93317d68" +git-tree-sha1 = "590acc2c3baf98aaff7d2f1990a6f1de6138361e" uuid = "47a9eef4-7e08-11e9-0b38-333d64bd3804" -version = "2.8.0" +version = "2.9.1" [deps.SparseDiffTools.extensions] SparseDiffToolsEnzymeExt = "Enzyme" @@ -1589,9 +1605,9 @@ version = "1.0.1" [[deps.Tables]] deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "a1f34829d5ac0ef499f6d84428bd6b4c71f02ead" +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.11.0" +version = "1.11.1" [[deps.Tar]] deps = ["ArgTools", "SHA"] @@ -1621,9 +1637,9 @@ uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" version = "0.5.23" [[deps.TranscodingStreams]] -git-tree-sha1 = "7c9196c8c83802d7b8ca7a6551a0236edd3bf731" +git-tree-sha1 = "49cbf7c74fafaed4c529d47d48c8f7da6a19eb75" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.10.0" +version = "0.10.1" weakdeps = ["Random", "Test"] [deps.TranscodingStreams.extensions] @@ -1911,9 +1927,9 @@ version = "1.5.5+0" [[deps.ZygoteRules]] deps = ["ChainRulesCore", "MacroTools"] -git-tree-sha1 = "977aed5d006b840e2e40c0b48984f7463109046d" +git-tree-sha1 = "9d749cd449fb448aeca4feee9a2f4186dbb5d184" uuid = "700de1a5-db45-46bc-99cf-38207098b444" -version = "0.2.3" +version = "0.2.4" [[deps.eudev_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "gperf_jll"] diff --git a/dev/comparison/index.html b/dev/comparison/index.html index 760ede49a..b8c49fbeb 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 12d62d5c3..3a614fd9c 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 759fdd2a3..78f46a7bf 100644 --- a/dev/getting_started/index.html +++ b/dev/getting_started/index.html @@ -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 15 stored entries:
-⎡⠀⠀⠈⠀⠀⎤
-⎢⠀⢀⠀⠄⠄⎥
-⎢⠨⠀⠀⠀⠄⎥
-⎢⡁⠀⠠⠀⢀⎥
-⎣⠈⠂⠄⠈⠀⎦
+out
20×10 SparseArrays.SparseMatrixCSC{Float64, Int64} with 20 stored entries:
+⎡⢐⠂⠊⠁⠀⎤
+⎢⠐⢄⠀⡀⠂⎥
+⎢⠂⠀⠀⠀⠀⎥
+⎢⠐⠁⠢⠀⠀⎥
+⎣⠀⠐⠀⠂⣀⎦
diff --git a/dev/index.html b/dev/index.html index cd1bf00a8..144252e09 100644 --- a/dev/index.html +++ b/dev/index.html @@ -7,7 +7,7 @@ year={2021} }

Feature Summary

Because Symbolics.jl is built into the Julia language and works with its dispatches, generic functions in Base Julia will work with symbolic expressions! Make matrices of symbolic expressions and multiply them: it will just work. Take the LU-factorization. Etc. Thus, see the Julia Documentation for a large list of functionality available in Symbolics.jl.

A general list of the features is:

and much more.

Extension Packages

Below is a list of known extension packages. If you would like your package to be listed here, feel free to open a pull request!

Reproducibility

The documentation of this SciML package was built using these direct dependencies,
Status `~/work/Symbolics.jl/Symbolics.jl/docs/Project.toml`
   [6e4b80f9] BenchmarkTools v1.3.2
-  [e30172f5] Documenter v1.1.1
+  [e30172f5] Documenter v1.1.2
   [23fbe1c1] Latexify v0.16.1
   [1dea7af3] OrdinaryDiffEq v6.58.0
   [91a5bcdd] Plots v1.39.0
@@ -19,7 +19,7 @@
   Official https://julialang.org/ release
 Platform Info:
   OS: Linux (x86_64-linux-gnu)
-  CPU: 2 × Intel(R) Xeon(R) Platinum 8171M CPU @ 2.60GHz
+  CPU: 2 × Intel(R) Xeon(R) Platinum 8272CL CPU @ 2.60GHz
   WORD_SIZE: 64
   LIBM: libopenlibm
   LLVM: libLLVM-14.0.6 (ORCJIT, skylake-avx512)
@@ -28,14 +28,14 @@
   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 v0.2.4
   [a4c015fc] ANSIColoredPrinters v0.0.1
-⌅ [c3fe647b] AbstractAlgebra v0.32.5
+  [c3fe647b] AbstractAlgebra v0.33.0
   [1520ce14] AbstractTrees v0.4.4
-  [79e6a3ab] Adapt v3.6.2
+  [79e6a3ab] Adapt v3.7.1
   [ec485272] ArnoldiMethod v0.2.0
-  [4fba245c] ArrayInterface v7.4.11
+  [4fba245c] ArrayInterface v7.5.0
   [30b0a656] ArrayInterfaceCore v0.1.29
   [6e4b80f9] BenchmarkTools v1.3.2
-  [e2ed5e7c] Bijections v0.1.5
+  [e2ed5e7c] Bijections v0.1.6
   [d1d4a3ce] BitFlags v0.1.7
   [62783981] BitTwiddlingConvenienceFunctions v0.1.5
   [2a0fbf3d] CPUSummary v0.2.4
@@ -61,18 +61,18 @@
   [864edb3b] DataStructures v0.18.15
   [e2d170a0] DataValueInterfaces v1.0.0
   [8bb1440f] DelimitedFiles v1.9.1
-  [2b5f629d] DiffEqBase v6.133.1
+  [2b5f629d] DiffEqBase v6.135.0
   [163ba53b] DiffResults v1.1.0
   [b552c78f] DiffRules v1.15.1
   [b4f34e82] Distances v0.10.10
   [31c24e10] Distributions v0.25.102
   [ffbed154] DocStringExtensions v0.9.3
-  [e30172f5] Documenter v1.1.1
+  [e30172f5] Documenter v1.1.2
 ⌅ [5b8099bc] DomainSets v0.6.7
   [fa6b7ba4] DualNumbers v0.6.8
   [7c1d4256] DynamicPolynomials v0.5.3
   [4e289a0a] EnumX v1.0.4
-  [f151be2c] EnzymeCore v0.6.2
+  [f151be2c] EnzymeCore v0.6.3
   [460bff9d] ExceptionUnwrapping v0.1.9
   [d4d017d3] ExponentialUtilities v1.25.0
   [e2ba6199] ExprTools v0.1.10
@@ -80,7 +80,7 @@
   [7034ab61] FastBroadcast v0.2.7
   [9aa1b823] FastClosures v0.3.2
   [29a986be] FastLapackInterface v2.0.0
-  [1a297f60] FillArrays v1.6.1
+  [1a297f60] FillArrays v1.7.0
   [6a86dc24] FiniteDiff v2.21.1
   [53c48c17] FixedPointNumbers v0.8.4
   [59287772] Formatting v0.4.2
@@ -92,7 +92,7 @@
   [c145ed77] GenericSchur v0.5.3
   [86223c79] Graphs v1.9.0
   [42e2da0e] Grisu v1.0.2
-  [0b43b601] Groebner v0.4.4
+  [0b43b601] Groebner v0.5.0
   [d5909c97] GroupsCore v0.4.0
   [cd3eb016] HTTP v1.10.0
   [3e5b6fbb] HostCPUFeatures v0.1.16
@@ -101,7 +101,7 @@
   [615f187c] IfElse v0.1.1
   [d25df0c9] Inflate v0.1.4
   [18e54dd8] IntegerMathUtils v0.1.2
-  [8197267c] IntervalSets v0.7.7
+  [8197267c] IntervalSets v0.7.8
   [92d709cd] IrrationalConstants v0.2.2
   [82899510] IteratorInterfaceExtensions v1.0.0
   [1019f520] JLFzf v0.1.6
@@ -117,7 +117,7 @@
   [0e77f7df] LazilyInitializedFields v1.2.1
   [50d2b5c4] Lazy v0.15.1
   [d3d80556] LineSearches v7.2.0
-  [7ed4a6bd] LinearSolve v2.10.0
+  [7ed4a6bd] LinearSolve v2.13.0
   [2ab3a3ac] LogExpFunctions v0.3.26
   [e6f89c97] LoggingExtras v1.0.3
   [bdcacae8] LoopVectorization v0.12.165
@@ -133,7 +133,7 @@
   [d41bc354] NLSolversBase v7.8.3
   [2774e3e8] NLsolve v4.5.1
   [77ba4419] NaNMath v1.0.2
-  [8913a72c] NonlinearSolve v2.2.1
+  [8913a72c] NonlinearSolve v2.5.0
   [6fe1bfb0] OffsetArrays v1.12.10
   [4d8831e6] OpenSSL v1.4.1
   [bac558e1] OrderedCollections v1.6.2
@@ -156,7 +156,7 @@
   [fb686558] RandomExtensions v0.4.4
   [3cdcf5f2] RecipesBase v1.3.4
   [01d81517] RecipesPipeline v0.6.12
-  [731186ca] RecursiveArrayTools v2.39.0
+  [731186ca] RecursiveArrayTools v2.38.10
   [f2c3362d] RecursiveFactorization v0.2.20
   [189a3867] Reexport v1.2.2
   [2792f1a3] RegistryInstances v0.1.0
@@ -167,19 +167,19 @@
   [fdea26ae] SIMD v3.4.5
   [94e857df] SIMDTypes v0.1.0
   [476501e8] SLEEFPirates v0.6.39
-  [0bca4576] SciMLBase v2.4.0
+  [0bca4576] SciMLBase v2.5.0
   [e9a6253c] SciMLNLSolve v0.1.9
   [c0aeaf25] SciMLOperators v0.3.6
   [6c6a2e73] Scratch v1.2.0
   [efcf1570] Setfield v1.1.1
   [992d4aef] Showoff v1.0.3
   [777ac1f9] SimpleBufferStream v1.1.0
-  [727e6d20] SimpleNonlinearSolve v0.1.22
+  [727e6d20] SimpleNonlinearSolve v0.1.23
   [699a6c99] SimpleTraits v0.9.4
   [ce78b400] SimpleUnPack v1.1.0
   [66db9d55] SnoopPrecompile v1.0.3
   [a2af1166] SortingAlgorithms v1.2.0
-  [47a9eef4] SparseDiffTools v2.8.0
+  [47a9eef4] SparseDiffTools v2.9.1
   [e56a9233] Sparspak v0.3.9
   [276daf66] SpecialFunctions v2.3.1
   [aedffcd0] Static v0.8.8
@@ -194,11 +194,11 @@
   [d1185830] SymbolicUtils v1.4.0
   [0c5d862f] Symbolics v5.10.0 `~/work/Symbolics.jl/Symbolics.jl`
   [3783bdb8] TableTraits v1.0.1
-  [bd369af6] Tables v1.11.0
+  [bd369af6] Tables v1.11.1
   [62fd8b95] TensorCore v0.1.1
   [8290d209] ThreadingUtilities v0.5.2
   [a759f4b9] TimerOutputs v0.5.23
-  [3bb67fe8] TranscodingStreams v0.10.0
+  [3bb67fe8] TranscodingStreams v0.10.1
   [a2a6695c] TreeViews v0.3.0
   [d5829a12] TriangularSolve v0.1.19
   [410a4b4d] Tricks v0.1.8
@@ -212,7 +212,7 @@
   [41fe7b60] Unzip v0.2.0
   [3d5dd08c] VectorizationBase v0.21.64
   [19fa3120] VertexSafeGraphs v0.2.0
-  [700de1a5] ZygoteRules v0.2.3
+  [700de1a5] ZygoteRules v0.2.4
   [6e34b625] Bzip2_jll v1.0.8+0
   [83423d85] Cairo_jll v1.16.1+1
   [2702e6a9] EpollShim_jll v0.0.20230411+0
@@ -342,4 +342,4 @@
   [8e850b90] libblastrampoline_jll v5.8.0+0
   [8e850ede] nghttp2_jll v1.48.0+0
   [3f19e933] p7zip_jll v17.4.0+0
-Info Packages marked with ⌃ and ⌅ have new versions available, 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, 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 f0f4d9f20..7b7857cc5 100644 --- a/dev/manual/arrays/index.html +++ b/dev/manual/arrays/index.html @@ -33,4 +33,4 @@ \]

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,:]))

\[ \begin{equation} A_{1}ˏ_1 + 2 A_{2}ˏ_1 + A_{2}ˏ_2 + A_{2}ˏ_3 + A_{3}ˏ_1 + A_{4}ˏ_1 + A_{5}ˏ_1 \end{equation} - \]

+ \]

diff --git a/dev/manual/build_function/index.html b/dev/manual/build_function/index.html index bbf48bf19..610540dd1 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
+ 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 diff --git a/dev/manual/derivatives/index.html b/dev/manual/derivatives/index.html index 5c9ada4eb..18e7308a7 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)
 

TODO

Examples


 julia> @variables x y z k;
@@ -25,15 +25,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

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, v; simplify)
-

A helper function for computing the derivative of an expression 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 an expression with respect to an array of variable expressions.

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

A helper function for computing the Hessian of an expression 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

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, v; simplify)
+

A helper function for computing the derivative of an expression 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 an expression with respect to an array of variable expressions.

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

A helper function for computing the Hessian of an expression 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 73cbd91b6..70a9dc2d0 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) -> Symbolic

Convert a differential variable to a Term. Note that it only takes a Term not a Num.

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

Convert a differential variable to a Term. Note that it only takes a Term not a Num.

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,4 +70,4 @@
 2
 
 julia> Symbolics.coeff(x^2 + y, x^2)
-1
source
+1source diff --git a/dev/manual/faq/index.html b/dev/manual/faq/index.html index 1f99e7bbf..aa473036c 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 dd58f0ae0..00ac160d9 100644 --- a/dev/manual/functions/index.html +++ b/dev/manual/functions/index.html @@ -28,4 +28,4 @@ \]

Registering Functions

The Symbolics graph only allows registered Julia functions within its type. All other functions are automatically traced down to registered functions. By default, Symbolics.jl pre-registers the common functions utilized in SymbolicUtils.jl and pre-defines their derivatives. However, the user can utilize the @register_symbolic macro to add their function to allowed functions of the computation graph.

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`
source
+@register_symbolic hoo(x, y)::Int # `hoo` returns `Int`source diff --git a/dev/manual/groebner/index.html b/dev/manual/groebner/index.html index 57c36f13b..019971ad8 100644 --- a/dev/manual/groebner/index.html +++ b/dev/manual/groebner/index.html @@ -3,4 +3,4 @@ julia> @variables x y; -julia> groebner_basis([x*y^2 + x, x^2*y + y])

The coefficients in the resulting basis are in the same domain as for input polynomials. Hence, if the coefficient becomes too large to be represented exactly, DomainError is thrown.

The algorithm is randomized, so the basis will be correct with high probability.

source +julia> groebner_basis([x*y^2 + x, x^2*y + y])

The coefficients in the resulting basis are in the same domain as for input polynomials. Hence, if the coefficient becomes too large to be represented exactly, DomainError is thrown.

The algorithm is randomized, so the basis will be correct with high probability.

source diff --git a/dev/manual/io/index.html b/dev/manual/io/index.html index 458418d94..b704f9aa4 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/parsing/index.html b/dev/manual/parsing/index.html index 3a1e43e3b..3bcad0b1f 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 1ac94d0fb..e41aba234 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
+ 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
diff --git a/dev/manual/types/index.html b/dev/manual/types/index.html index d37ece817..58dbff752 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 fd93e1509..8e5813b2f 100644 --- a/dev/manual/variables/index.html +++ b/dev/manual/variables/index.html @@ -28,7 +28,7 @@ (value_c(t))[1:3] julia> (t, a, b, c) -(t, :runtime_symbol_value, :value_b, :value_c)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
+(t, :runtime_symbol_value, :value_b, :value_c)
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;
@@ -45,7 +45,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 562 methods)
Symbolics.operation(Symbolics.value(z))

\[ \begin{equation} z @@ -60,4 +60,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

SymbolicUtils.istreeFunction

istree(x)

Returns true if x is a term. If true, operation, arguments must also be defined for x appropriately.

source
SymbolicUtils.operationFunction

operation(x)

If x is a term as defined by istree(x), operation(x) returns the head of the term if x represents a function call, for example, the head is the function being called.

source
SymbolicUtils.argumentsFunction

arguments(x)

Get the arguments of x, must be defined if istree(x) is true.

source
+ \]

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

SymbolicUtils.istreeFunction

istree(x)

Returns true if x is a term. If true, operation, arguments must also be defined for x appropriately.

source
SymbolicUtils.operationFunction

operation(x)

If x is a term as defined by istree(x), operation(x) returns the head of the term if x represents a function call, for example, the head is the function being called.

source
SymbolicUtils.argumentsFunction

arguments(x)

Get the arguments of x, must be defined if istree(x) is true.

source
diff --git a/dev/tutorials/auto_parallel/9bde950c.svg b/dev/tutorials/auto_parallel/05553dca.svg similarity index 58% rename from dev/tutorials/auto_parallel/9bde950c.svg rename to dev/tutorials/auto_parallel/05553dca.svg index 101f01f54..10f4cf238 100644 --- a/dev/tutorials/auto_parallel/9bde950c.svg +++ b/dev/tutorials/auto_parallel/05553dca.svg @@ -1,13222 +1,13222 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/tutorials/auto_parallel/index.html b/dev/tutorials/auto_parallel/index.html index 41952e5f8..44ef3b47c 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 318a7a090..8d31bdc23 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:801 =#
-          ccall(("diffeqf", "/tmp/jl_L6RkNIzcnK"), Cvoid, (Ptr{Float64}, Ptr{Float64}, Ptr{Float64}, Float64), du, u, p, t)
+          ccall(("diffeqf", "/tmp/jl_tWNmrQROJs"), 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