MultiScaleArrays.jl: High-Performance Matrix Exponentiation and Products
MultiScaleArrays.jl allows you to easily build multiple-scale models that are fully compatible with native Julia scientific computing packages like DifferentialEquations.jl or Optim.jl. These models utilize a tree structure to describe phenomena on multiple scales, but the interface allows you to describe equations on different levels, using aggregations from lower levels to describe complex systems. Their structure allows for complex and dynamic models to be developed with only a small performance difference. In the end, they present themselves as an AbstractArray to standard solvers, allowing them to be used in place of a Vector in any appropriately made Julia package.
Installation
To install MultiScaleArrays.jl, use the Julia package manager:
using Pkg
Pkg.add("MultiScaleArrays")Example
The usage is best described by an example. Here we build a hierarchy where Embryos contain Tissues which contain Populations which contain Cells, and the cells contain proteins whose concentrations are modeled as simply a vector of numbers (it can be anything linearly indexable).
using MultiScaleArrays
struct Cell{B} <: AbstractMultiScaleArrayLeaf{B}
values::Vector{B}
end
struct Population{T <: AbstractMultiScaleArray, B <: Number} <: AbstractMultiScaleArray{B}
nodes::Vector{T}
values::Vector{B}
end_idxs::Vector{Int}
end
struct Tissue{T <: AbstractMultiScaleArray, B <: Number} <: AbstractMultiScaleArray{B}
nodes::Vector{T}
values::Vector{B}
end_idxs::Vector{Int}
end
struct Embryo{T <: AbstractMultiScaleArray, B <: Number} <: AbstractMultiScaleArrayHead{B}
nodes::Vector{T}
values::Vector{B}
end_idxs::Vector{Int}
endThis setup defines a type structure that is both a tree and an array. A picture of a possible version is the following:
Let's build a version of this. Using the constructors, we can directly construct leaf types:
cell1 = Cell([1.0; 2.0; 3.0])
cell2 = Cell([4.0; 5.0])and build types higher up in the hierarchy by using the construct method. The method is construct(T::AbstractMultiScaleArray, nodes, values), though, if values is not given, it's taken to be empty.
cell3 = Cell([3.0; 2.0; 5.0])
cell4 = Cell([4.0; 6.0])
population = construct(Population, deepcopy([cell1, cell3, cell4]))
population2 = construct(Population, deepcopy([cell1, cell3, cell4]))
population3 = construct(Population, deepcopy([cell1, cell3, cell4]))
tissue1 = construct(Tissue, deepcopy([population, population2, population3])) # Make a Tissue from Populations
tissue2 = construct(Tissue, deepcopy([population2, population, population3]))
embryo = construct(Embryo, deepcopy([tissue1, tissue2])) # Make an embryo from TissuesIdea
The idea behind MultiScaleArrays is simple. The *DiffEq solvers (OrdinaryDiffEq.jl, StochasticDiffEq.jl, DelayDiffEq.jl, etc.) and native optimization packages like Optim.jl in their efficient in-place form all work with any Julia-defined AbstractArray which has a linear index. Thus, to define our multiscale model, we develop a type which has an efficient linear index. One can think of representing cells with proteins as each being an array with values for each protein. The linear index of the multiscale model would be indexing through each protein of each cell. With proper index overloads, one can define a type such that a[i] does just that, and thus it will work in the differential equation solvers. MultiScaleArrays.jl takes that further by allowing one to recursively define an arbitrary n-level hierarchical model which has efficient indexing structures. The result is a type which models complex behavior, but the standard differential equation solvers will work directly and efficiently on this type, making it easy to develop novel models without having to re-develop advanced adaptive/stiff/stochastic/etc. solving techniques for each new model.
Contributing
Please refer to the SciML ColPrac: Contributor's Guide on Collaborative Practices for Community Packages for guidance on PRs, issues, and other matters relating to contributing to SciML.
See the SciML Style Guide for common coding practices and other style decisions.
There are a few community forums:
- The #diffeq-bridged and #sciml-bridged channels in the Julia Slack
- The #diffeq-bridged and #sciml-bridged channels in the Julia Zulip
- On the Julia Discourse forums
- See also SciML Community page
Reproducibility
The documentation of this SciML package was built using these direct dependencies,
Status `~/work/MultiScaleArrays.jl/MultiScaleArrays.jl/docs/Project.toml`
[e30172f5] Documenter v1.17.0
[f9640e96] MultiScaleArrays v1.24.0 `~/work/MultiScaleArrays.jl/MultiScaleArrays.jl`and using this machine and Julia version.
Julia Version 1.12.6
Commit 15346901f00 (2026-04-09 19:20 UTC)
Build Info:
Official https://julialang.org release
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: 4 × AMD EPYC 9V74 80-Core Processor
WORD_SIZE: 64
LLVM: libLLVM-18.1.7 (ORCJIT, znver4)
GC: Built with stock GC
Threads: 1 default, 1 interactive, 1 GC (on 4 virtual cores)A more complete overview of all dependencies and their versions is also provided.
Status `~/work/MultiScaleArrays.jl/MultiScaleArrays.jl/docs/Manifest.toml`
[47edcb42] ADTypes v1.22.0
[a4c015fc] ANSIColoredPrinters v0.0.1
[1520ce14] AbstractTrees v0.4.5
[7d9f7c33] Accessors v0.1.44
[79e6a3ab] Adapt v4.5.2
[66dad0bd] AliasTables v1.1.3
[ec485272] ArnoldiMethod v0.4.0
[4fba245c] ArrayInterface v7.24.0
[70df07ce] BracketingNonlinearSolve v1.12.1
[944b1d66] CodecZlib v0.7.8
[38540f10] CommonSolve v0.2.6
[bbf7d656] CommonSubexpressions v0.3.1
[34da2185] Compat v4.18.1
[a33af91c] CompositionsBase v0.1.2
[2569d6c7] ConcreteStructs v0.2.3
[187b0558] ConstructionBase v1.6.0
[9a962f9c] DataAPI v1.16.0
[864edb3b] DataStructures v0.19.4
[2b5f629d] DiffEqBase v7.0.0
[459566f4] DiffEqCallbacks v4.17.0
[77a26b50] DiffEqNoiseProcess v5.31.0
[163ba53b] DiffResults v1.1.0
[b552c78f] DiffRules v1.15.1
[a0c0ee7d] DifferentiationInterface v0.7.16
[31c24e10] Distributions v0.25.125
[ffbed154] DocStringExtensions v0.9.5
[e30172f5] Documenter v1.17.0
[4e289a0a] EnumX v1.0.7
[f151be2c] EnzymeCore v0.8.19
[e2ba6199] ExprTools v0.1.10
[7034ab61] FastBroadcast v1.3.2
[9aa1b823] FastClosures v0.3.2
[a4df4552] FastPower v1.3.1
[1a297f60] FillArrays v1.16.0
[6a86dc24] FiniteDiff v2.30.0
[f6369f11] ForwardDiff v1.3.3
[069b7b12] FunctionWrappers v1.1.3
[77dc65aa] FunctionWrappersWrappers v1.8.0
[46192b85] GPUArraysCore v0.2.0
[d7ba0133] Git v1.5.0
[86223c79] Graphs v1.14.0
[34004b35] HypergeometricFunctions v0.3.28
[b5f81e59] IOCapture v1.0.0
[d25df0c9] Inflate v0.1.5
[3587e190] InverseFunctions v0.1.17
[92d709cd] IrrationalConstants v0.2.6
[82899510] IteratorInterfaceExtensions v1.0.0
[692b3bcd] JLLWrappers v1.7.1
[682c06a0] JSON v1.5.0
[ccbc3e58] JumpProcesses v9.26.0
[ba0b0d4f] Krylov v0.10.6
[0e77f7df] LazilyInitializedFields v1.3.0
[87fe0de2] LineSearch v0.1.8
[7ed4a6bd] LinearSolve v3.75.0
[2ab3a3ac] LogExpFunctions v0.3.29
[e6f89c97] LoggingExtras v1.2.0
[1914dd2f] MacroTools v0.5.16
[d0879d2d] MarkdownAST v0.1.3
[bb5d69b7] MaybeInplace v0.1.4
[e1d29d7a] Missings v1.2.0
[46d2c3a1] MuladdMacro v0.2.4
[f9640e96] MultiScaleArrays v1.24.0 `~/work/MultiScaleArrays.jl/MultiScaleArrays.jl`
[77ba4419] NaNMath v1.1.3
[8913a72c] NonlinearSolve v4.19.0
[be0214bd] NonlinearSolveBase v2.25.0
[5959db7a] NonlinearSolveFirstOrder v2.1.1
[9a2c21bd] NonlinearSolveQuasiNewton v1.13.1
[26075421] NonlinearSolveSpectralMethods v1.7.1
[bac558e1] OrderedCollections v1.8.1
[1dea7af3] OrdinaryDiffEq v7.0.0
[6ad6398a] OrdinaryDiffEqBDF v2.0.0
⌅ [bbf590c4] OrdinaryDiffEqCore v4.0.0
[50262376] OrdinaryDiffEqDefault v2.0.0
[4302a76b] OrdinaryDiffEqDifferentiation v3.0.0
[127b3ac7] OrdinaryDiffEqNonlinearSolve v2.0.0
[43230ef6] OrdinaryDiffEqRosenbrock v2.0.0
[b4bd8bb3] OrdinaryDiffEqRosenbrockTableaus v2.0.0
[2d112036] OrdinaryDiffEqSDIRK v2.0.0
[b1df2697] OrdinaryDiffEqTsit5 v2.0.0
[79d7bb75] OrdinaryDiffEqVerner v2.0.0
[90014a1f] PDMats v0.11.37
[69de0a69] Parsers v2.8.3
[e409e4f3] PoissonRandom v0.4.7
[d236fae5] PreallocationTools v1.2.0
[aea7be01] PrecompileTools v1.3.3
[21216c6a] Preferences v1.5.2
[43287f4e] PtrArrays v1.4.0
[1fd47b50] QuadGK v2.11.3
[3cdcf5f2] RecipesBase v1.3.4
[731186ca] RecursiveArrayTools v4.2.0
[189a3867] Reexport v1.2.2
[2792f1a3] RegistryInstances v0.1.0
[ae029012] Requires v1.3.1
[ae5879a3] ResettableStacks v1.2.0
[79098fc4] Rmath v0.9.0
[7e49a35a] RuntimeGeneratedFunctions v0.5.18
[0bca4576] SciMLBase v3.6.0
[19f34311] SciMLJacobianOperators v0.1.13
[a6db7da4] SciMLLogging v1.9.1
[c0aeaf25] SciMLOperators v1.17.0
[431bcebd] SciMLPublic v1.0.1
[53ae85a6] SciMLStructures v1.10.0
[efcf1570] Setfield v1.1.2
[727e6d20] SimpleNonlinearSolve v2.11.1
[699a6c99] SimpleTraits v0.9.5
[a2af1166] SortingAlgorithms v1.2.2
[0a514795] SparseMatrixColorings v0.4.27
[276daf66] SpecialFunctions v2.7.2
[90137ffa] StaticArrays v1.9.18
[1e83bf80] StaticArraysCore v1.4.4
[10745b16] Statistics v1.11.1
[82ae8749] StatsAPI v1.8.0
[2913bbd2] StatsBase v0.34.10
[4c63d2b9] StatsFuns v1.5.2
[789caeaf] StochasticDiffEq v7.0.0
[19c5a474] StochasticDiffEqCore v2.0.0
[0520c28c] StochasticDiffEqHighOrder v2.0.0
[ebf54054] StochasticDiffEqIIF v2.0.0
[5080b986] StochasticDiffEqImplicit v2.0.0
[aefaaa88] StochasticDiffEqLeaping v2.0.0
[90dbc90e] StochasticDiffEqLevyArea v2.0.0
[d15fe365] StochasticDiffEqLowOrder v2.0.0
[8c95a807] StochasticDiffEqMilstein v2.0.0
[db241ea8] StochasticDiffEqROCK v2.0.0
[49714585] StochasticDiffEqRODE v2.0.0
[af2a2fcd] StochasticDiffEqWeak v2.0.0
[ec057cc2] StructUtils v2.8.0
[2efcf032] SymbolicIndexingInterface v0.3.46
[a759f4b9] TimerOutputs v0.5.29
[3bb67fe8] TranscodingStreams v0.11.3
[781d530d] TruncatedStacktraces v1.4.0
[2e619515] Expat_jll v2.7.5+0
[020c3dae] Git_LFS_jll v3.7.0+0
[f8c6e375] Git_jll v2.54.0+0
[1d5cc7b8] IntelOpenMP_jll v2025.2.0+0
[94ce4f54] Libiconv_jll v1.18.0+0
[856f044c] MKL_jll v2025.2.0+0
[9bd350c2] OpenSSH_jll v10.3.1+0
[efe28fd5] OpenSpecFun_jll v0.5.6+0
[f50d1b31] Rmath_jll v0.5.1+0
[1317d2d5] oneTBB_jll v2022.0.0+1
[0dad84c5] ArgTools v1.1.2
[56f22d72] Artifacts v1.11.0
[2a0f44e3] Base64 v1.11.0
[ade2ca70] Dates v1.11.0
[8ba89e20] Distributed v1.11.0
[f43a241f] Downloads v1.7.0
[7b1f6079] FileWatching v1.11.0
[9fa8497b] Future v1.11.0
[b77e0a4c] InteractiveUtils v1.11.0
[ac6e5ff7] JuliaSyntaxHighlighting v1.12.0
[4af54fe1] LazyArtifacts v1.11.0
[b27032c2] LibCURL v0.6.4
[76f85450] LibGit2 v1.11.0
[8f399da3] Libdl v1.11.0
[37e2e46d] LinearAlgebra v1.12.0
[56ddb016] Logging v1.11.0
[d6f4376e] Markdown v1.11.0
[ca575930] NetworkOptions v1.3.0
[44cfe95a] Pkg v1.12.1
[de0858da] Printf v1.11.0
[3fa0cd96] REPL v1.11.0
[9a3f8284] Random v1.11.0
[ea8e919c] SHA v0.7.0
[9e88b42a] Serialization v1.11.0
[6462fe0b] Sockets v1.11.0
[2f01184e] SparseArrays v1.12.0
[f489334b] StyledStrings v1.11.0
[4607b0f0] SuiteSparse
[fa267f1f] TOML v1.0.3
[a4e569a6] Tar v1.10.0
[8dfed614] Test v1.11.0
[cf7118a7] UUIDs v1.11.0
[4ec0a83e] Unicode v1.11.0
[e66e0078] CompilerSupportLibraries_jll v1.3.0+1
[deac9b47] LibCURL_jll v8.15.0+0
[e37daf67] LibGit2_jll v1.9.0+0
[29816b5a] LibSSH2_jll v1.11.3+1
[14a3606d] MozillaCACerts_jll v2025.11.4
[4536629a] OpenBLAS_jll v0.3.29+0
[05823500] OpenLibm_jll v0.8.7+0
[458c3c95] OpenSSL_jll v3.5.4+0
[efcefdf7] PCRE2_jll v10.44.0+1
[bea87d4a] SuiteSparse_jll v7.8.3+2
[83775a58] Zlib_jll v1.3.1+2
[8e850b90] libblastrampoline_jll v5.15.0+0
[8e850ede] nghttp2_jll v1.64.0+1
[3f19e933] p7zip_jll v17.7.0+0
Info Packages marked with ⌅ have new versions available but compatibility constraints restrict them from upgrading. To see why use `status --outdated -m`You can also download the manifest file and the project file.