Releases: sicmutils/sicmutils
0.23.0: Mechanics code, prep for Emmy release
This release adds a number of performance upgrades, and completes the port of all code in the mechanics package of the original scmutils library.
This will also be the final release before extracting most of the code in the library out and giving it a new identity and home as the "Emmy Computer Algebra System", housed at https://github.com/mentat-collective/emmy.
New Code / Upgrades
-
#531:
-
Adds proper self-require forms to all
cljcnamespaces with macros; this removes the need for:include-macros trueor:refer-macrosand makes the life of consumers simpler. -
Upgrades sci, test.check, core.match, timbre, clojurescript, shadow-cljs dependencies to remove various warnings.
-
Adds
sicmutils.structure/symbol-set -
Adds
IHashimplementations forjs/BigInt,goog.math.Long,goog.map.IntegerandRatiotypes
-
-
#514:
-
Modifies
sicmutils.calculus.derivative/taylor-seriesto return a properPowerSeriesinstance, which the user can call with somedxto get back the old behavior.The new version can take any number of arguments in addition to
f.
Supplying no arguments returns the expansion at 0; if you supply many
arguments (totally fine!), you'll need to wrap yourdxcomponents in a
vector before supplying them to the returnedPowerSeries. -
sicmutils.series/function->works the same way now, and functions identically, but with a different implementation. (previously it took a single expansion point under a keyword argument:x0.) -
The new
sicmutils.calculus.derivative/symbolic-taylor-seriesis a port ofTaylor-series-coefficientsfromscmutils. It has the same contract astaylor-series, except that the full expansion is performed symbolically, and the original arguments are substituted in after expansion and simplification. -
Other changes:
-
Installs
1as theone-likeandidentity-likereturn values for structures and vectors. A true identity element would be an identity element compatible with all entries of the structure; but as defined now,1is a fine choice and matches thescmutilsimplementation. -
new
sicmutils.differential/map-coefficients, which makessimplifyslightly more efficient by filtering terms . -
more efficient
sicmutils.expression/variables-in, maybe 30% faster for big expressions; this makes a difference in the simplifier! -
sicmutils.expression/substitutenow works for properLiteralinstances. Before it only worked for unwrapped literals. -
matrix walks made slightly faster by caching a row or column before traversal
-
-
-
#512:
-
adds
sicmutils.mechanics.routhian, with implementations ofLagrangian->Routhian,Routh-equations,Routhian->acceleration,Routhian->state-derivative,Lagrangian-state->Routhian-stateandRouthian-state->Lagrangian-state. -
adds missing
sicmutils.mechanics.{routhian,time-evolution,noether}tosicmutils.env.sci
-
-
#509:
-
Fixes a bug with
down*Matrixmultiplication, and adds tests for correctness. -
Adds
sicmutils.matrix.{symmetric?,antisymmetric?}predicates -
The mechanics port continues with
sicmutils.mechanics.rigid:-
T-rigid-bodymoves toT-body-Eulerwith an alias back to its original name. Same situation forEuler-state->L-body=>L-body-EulerandEuler-state->L-space=>L-space-Euler. -
New functions:
three-vector-components->antisymmetric,T-body,L-body,L-space,Euler->omega,Euler->omega-body,quaternion-state->omega-body,quaternion-state->omega-space,qw-state->L-body,qw-state->L-space,T-quaternion-state
-
-
-
#511 focuses on adding more rotations and efficiency to
sicmutils.quaternion. Specifically:-
magnitude-sqandmagnitudeare now more efficient. -
New functions to get to and from quaternions and various matrix representations:
from-rotation-matrix,->rotation-matrix,from-complex-matrix,->complex-matrix,from-4x4-matrix,->4x4-matrix -
New instances
ONE-matrix,I-matrix,J-matrix,K-matrix, matrix representations of the corresponding quaternion elements. -
Similar to the matrix elements, we also now have
ONE-tensor,I-tensor,J-tensor,K-tensor.
-
-
#503:
-
adds
sicmutils.mechanics.lagrange/Lagrangianfor building function signatures of Lagrangians. -
adds the
sicmutils.mechanics.time-evolutionnamespace -
adds
sicmutils.mechanics.lagrange/L-axisymmetric-top, more efficient than the version insicmutils.examples.top -
Fleshes out
sicmutils.mechanics.hamilton:-
New functions:
H-state?,compatible-H-state?,state->p,momenta,P,literal-Hamiltonian-state,L-state->H-state,H-state->L-state,H-state->matrix,matrix->H-state,make-Hamiltonian,D-phase-space,Hamiltonian->Lagrangian-procedure,Hamiltonian->Lagrangian,flow-derivative,flow-transform,standard-map-inverse,F->K,J-func,T-func,canonical-H?,canonical-K?,linear-function->multiplier,Phi,Phi*,qp-canonical?,polar-canonical-inverse,two-particle-center-of-mass,two-particle-center-of-mass-canonical,transpose-function,multiplicative-transpose,symplectic-two-form,canonical-transform?,J-matrix,symplectic? -
F->CHmoves toF->CT(F->CTis now an alias) -
Legendre-transform-fnbecomesLegendre-transform-procedureand gains more correctness tests, toggled on and off by the*validate-Legendre-transform?*dynamic variable.
-
-
-
#508 adds
sicmutils.mechanics.noethernamespace, withNoether-integral. -
#506 tidies up the build by removing unneeded reader conditionals and replacing renames like
core-=with a proper require ofclojure.core. -
#502 begins the port of the remaining items in the scmutils
mechanicspackage over the Clojure. This PR focuses onsicmutils.mechanics.lagrange, which contains functions from many files in the originalmechanicsfolder.-
momentum-tuplemoves here fromsicmutils.mechanics.hamilton -
New functions
->L-state,->local,->state,state->n-dof,time,state->{q,qdot,qddot},coordinates,velocities,accelerations,Q,Qdot,Qdotdot,literal-Lagrangian-statepath->state-path(alias for the existingGamma),Rayleigh-dissipation,qv->local-path,Lagrange-equations-first-order, (withLagrange-equations-1alias),Lagrangian->power-loss,T3-spherical,L3-central,Dt-procedureand the wrapping operatorDt,Euler-lagrange-operator(withLagrange-equations-operatorandLEaliases),generalized-LE. -
Many of these are aliased into
sicmutils.env. Ask if you think more should be there! -
many new built-in Lagrangians:
L-Kepler-polar,L-coupled-harmonic,L-sliding-pend,L-pendulum,L-two-particle -
Lagrange-equations,Lagrangian->acceleration,Lagrangian->state-derivativenow take a dissipation function -
local-state-derivativealiases the 1-arity version ofLagrangian->state-derivative -
New
rectangular->polar,polar->rectangular,spherical->rectangularandrectangular->sphericalthat operate on coordinates, with associatedr->p(new),p->r,s->randr->s(new).
-
-
#501 moves
elliptic-integralsfromsicmutils.special.elliptical-testsicmutils.special.elliptical, as it's needed by the upcomingsicmutils.mechanics.pendulumnamespace.
Bug Fixes
-
#531:
-
Fixes a typo in one of the rules in
sicmutils.simplify.rules/expand-multiangle, closing #530 -
Forces the subexpression walk in
pattern.rule/try-subexpressionswithdoall -
Adds type hints to all remaining
Complexcalls in js, to fix issues with advanced compilation (thanks to @mhuebert for finding this) -
#515:
-
-
tidies up the
squareandcubespeedups thanks to a tip from GJS -
Converts more
(mul x x)tosquarein the derivatives of thesicmutils.genericnamespace. -
fixes a bug in the
numeric-zero?check of exponent's derivative. -
#503:
-
Changes the default implementation of
squareandcubefor differentials to use(expt <> 2)etc instead of(* <> <>).This is a big deal! For certain expressions there's a huge blowup when you square a big symbolic term, and taking the derivative of it TWICE is very messy.
With this change, differentials use the chain rule to calculuate the derivative of
$x^2$ as$2x*x'$ , instead of using the product rule and achieving a SECOND differentiatation of the same form and another multiplication:$xx' + x'x$ .Before a judicious
simplifycall I added, this change dropped the runtime of thesicmutils.sicm.ch3-testsuite down by 6x. After the simplify change insicmutils.examples.topthe tests were still 40% faster in that namespace. -
Fixes a bug where the
RationalFunctioncube implementation actually calledsquare.
-
Misc
-
#532:
-
Removes the
potemkindependency by importing only what we need directly intosicmutils.util.def. This makes sense since our versions add aforkcall so that they work for ClojureScript as well. -
Moves all
examplesinto the tests so that we don't ship them with the library. These will eventually be converted to Clerk notebooks. -
Removes the
hiccupdependency. -
Upgrades
test.chuckand removes all:include-macros truecalls for that library. Onlysame/ishrequires them now! -
Capitalizes the "Script" in ClojureScript everywhere it appears.
-
-
#531:
- Drops cljsjs dependencies in favor of
deps.cljsentries
- Drops cljsjs dependencies in favor of
0.22.0: Faster compiled fns, Literate Library twitches
The big highlights for this release are:
- Consistently (much) faster compiled function performance (9x faster for 50 seconds on double pendulum simulation)
- The beginnings of the conversion of SICMUtils into a proper Literate Library thanks to a dev dependency on Clerk.
Thanks for @borkdude for PRs and help talking through clj-kondo, SCI etc.
Detailed release notes:
Compiled Function Performance
-
#496:
-
replaces the function values in
sicmutils.expression.compilewith symbols; I hadn't realized before that substituting in symbolicMath/sqrt, for example, was possible, vs a#(Math/sqrt %)function value. Compiled functions are now faster!A simulation run of the double pendulum example in the clerk-demo repository now runs in 350ms vs the former 2.2 seconds, a major win.
-
Function compilation now pre-simplifies numerical forms encountered inside a function, like
(/ 1 2), instead of letting them be evaluated on every fn call. -
All numerical forms encountered in function compilation are now converted to either
doubleon the JVM orjs/Numberin javascript; this way noBigIntvalues etc are left around.
-
Clerk
#485 adds a development dependency on Nextjournal's Clerk library, and begins the process of massaging various namespaces into proper literate essays display-able with Clerk. To run these, start a REPL and follow the instructions in dev/user.clj.
- `sicmutils.calculus.derivative` and `sicmutils.differential` now render as proper literate essays, with TeX bugs fixed.
New
-
#497:
sicmutils.expression.compile/compile-state-fnand its non-memoized version can now take an explicit:modeargument; this will override the dynamically bound*mode*. Invalid modes supplied via:modewill causecompile-state-fnto throw an exception. -
#496,
sicmutils.expression.compile:-
gains a new, validating
compiler-modefunction for fetching the compiler function. -
set-compiler-mode!now actually works. It never did! -
New
:sourcecompile mode that returns a source code form. You can either callevalon this or callsci-evalto get an SCI-evaluated function with all proper bindings in place. -
compile-state-fnnow takes an optional options map, with support for:flatten?and:generic-params?keywords. These can be used to tune the shape of the function returned bycompile-state-fn.
-
-
#485:
- Bumps the shadow-cljs dependency to version
2.17.4, and the includedcljsversion to1.11.4.sicmutils.collectionproperly handles the new cljsIntegerRangeclass.
- Bumps the shadow-cljs dependency to version
-
sicmutils.polynomial.factornow memoizespoly->factored-expressionby default. If polynomial GCD fails inside that function the computation now proceeds with a warning instead of failing. -
#492 updates the
clj-kondolinters to emit custom warnings with all metadata from the original token, not just:rowand:col. This fixes the ability to override or ignore individual warnings. -
#490 adds
sicmutils.numerical.roots.bisectwith implementations of bisection search, secant search and a mixed method found inscmutils. These all live under abisectfunction.The data structure returned is similar to the minimization functions in the
sicmutils.numeric.{unimin, multimin}namespaces. As more root-finding methods come online this should all standardize nicely. -
#491 adds
sicmutils.mechanics.rotation/M->Euler, for converting from a rotation matrix to a triple of Euler angles. Now we can successfully round trip. -
#489:
-
Installs
g/logandg/expforjs/BigIntinstances, enablingg/log2andg/log10in the mix. -
Removes most
js*calls usingcoercive-=andjs-mod. This form is internal and should be avoided.
-
-
#484 adds
sicmutils.polynomial/from-power-series, for generating a polynomial instance from some prefix of a (univariate) power series.
Bug Fixes
- #497 fixes a bug where non-numeric operations
upanddownwere applied at compile time, throwing an error.
Misc
0.21.1: Custom linting via clj-kondo
The big feature of this release is a custom clj-kondo config for sicmutils. All macros in the library (let-coordinates, with-coordinate-functions, all of the pattern matching macros and more) now show proper linter warnings; the pattern matching macros in particular will now show helpful warnings on cases where you've made an easy-to-correct mistake in your pattern syntax.
For example, the following form:
(require '[sicmutils.rule :as r])
(r/rule (+ (? x) (? y)) => (+ (? y odd?) (? x)))Will provide this inline linter warning, appearing as you type:
Restrictions are not allowed in consequence bindings: odd?
See here for the full list of macros handled by the config.
- The exported clj-kondo config lives here
- To install the config into your project, see the Linter instructions here
Linting
-
#477 adds tight integration with the
clj-kondolinter via an exported clj-kondo configuration in theresourcesdirectory. All macros in the library now offer pleasant linting to users. This is especially helpful for the macros inpattern.rule, which now can offer live feedback to pattern-matching authors.See
doc/linting.mdfor details on various warnings reported, and installation instructions for the clj-kondo config.Thanks to @borkdude for all of his help getting this working, and making this amazing project!
-
All linter errors and warnings are now addressed, fixed and silenced for the entire codebase, both
testandsrcdirectories. -
A new Github Action will run the linter for every PR and push to master, and annotate PRs with linter warnings and errors.
-
Additions
-
#481 adds a new
x-degreeargument tosicmutils.polynomial/univariate->dense, for padding the result with zeros in the case that you want to guarantee a certain dense degree in the result. -
#477:
-
com.gfredericks/test.chuckdev dependency upgraded to0.2.13to grab its clj-kondo exported config. -
pattern.rulepatterns can now handle spliced and unquote-spliced inputs in their symbol position.
-
Bug Fixes
-
#481 fixes a long-standing (test-only) bug in
sicmutils.polynomial-testaround palindromic polynomials -
#480:
sicmutils.numerical.quadrature/definite-integralnow coerces the result of non-compiled integrands in cljs to double. This prevents the @kloimhardt bug where certain paths would produceBigIntinstances and fail in quadrature calls. -
in #477, I found the following bugs with the help of the linter:
-
Deleted the unused
sicmutils.differential/d:apply. -
Fixed a bug with
sicmutils.expression.render/->JavaScriptnot using the second argument toremainder. -
deleted
sicmutils.numerical.quadrature.commonin favor ofsicmutils.generic/infinite? -
Fixed a broken integrator in
sicmutils.numerical.quadrature.simpson38, and fixed the tests to actually stress this code. -
Fixed a bug where
sicmutils.numerical.quadrature.substitute/exponential-upperwas not actually using its input function! -
unused
simplifyargument removed fromsicmutils.simplify.rules/non-negative-factors!and all uses. -
Bug fix in
sicmutils.special.elliptic/jacobi-elliptic-functions; deep in the gnarly fn, one of the branches returned nil instead of its required values. Thank you, linter! -
sicmutils.pattern/templatewill no longer error in the 1-arity case when some form contains a binding entry like(? (fn [m] ...)). Instead, the function will be passed an empty map.
-
0.21.0: Quaternions, Folds, Matrices and Tensors
This release takes us a good way toward completing the port of the kernel, the beating heart, of the original scmutils Scheme library. First, the highlights, and then the thematically organized CHANGELOG entries captured in this release.
-
We now have a full Quaternion implementation! The implementation is built out of the best stuff I could find in every Quaternion library out there, well documented and fully generic. In the future we should be able to specialize various methods to native numerics, making this type very fast.
-
Lots of new generics, including all remaining trigonometric functions and their inverses. Thanks to John D Cook's 'Bootstrapping a minimal math library' for his inspiration on the defaults and implementation order of these new functions.
-
The Matrix, Structure and Tensor APIs are now fully ported. This led to some big efficiency boosts, and the ability to solve systems of linear equations with various combinations of matrices,
upanddownstructures androwandcolumnmatrices. -
Functional folds! A big rewrite of the floating-point summation routine code led to some (I think) original discoveries about how to write polynomial interpolation, rational function interpolation and Richardson extrapolation as functional folds.
-
Lots of performance improvements! One of the early examples from SICM involves finding a path that "minimizes action" given some Lagrangian. This example is down from many seconds to 100ms on my machine.
Read on for detailed release notes.
Quaternions
-
#461 adds
sicmutils.quaternion, with a full arithmetic implementation and the beginnings of a rotation API. Quaternions are implemented like vectors of length 4, and implement all appropriate Clojure protocols. All arithmetic is compatible with all scalars and complex numbers.-
Accessors:
get-r,real-part,get-i,get-j,get-k,complex-1,complex-2,->complex-pair,->vector,three-vector -
Predicates:
real?,zero?,one?,pure?,unit? -
Constants:
ZERO,ONE,I,J,K -
Reader literal
#sicm/quaterniontakes a 4-vector or a single entry. -
Constructors:
make,from-complex,spherical,semipolar,multipolar,cylindrospherical,cylindrical -
More:
arity,evaluate,partial-derivative,magnitude-sq,normalize,commutator -
Transcendental functions:
explog,cos,sin,tansinh,cosh,tanh. Many more transcendentals will work, thanks to their default implementations. -
Arithmetic and generics:
+,-,*,/,dot-product,cross-product,conjugate,magnitude,expt,sqrt,simplify,infinite?,solve-linear-right,solve-linear -
Rotation-related:
from-angle-normal-axis,from-angle-axis,pitch,roll,yaw,->angle-axis
-
New Generics
-
#458:
- Default implementation of
g/negative?returningfalsefor literal numbers and symbols. This was required to getg/absworking for polynomials and rational functions with symbolic coefficients.
- Default implementation of
-
#448:
- new
g/infinite?generic with implementations for all numeric types, complex numbers,differentialinstances. Defaults tofalsefor all other types. (Also aliased intosicmutils.env/infinite?).
- new
-
#449:
-
All missing trigonometric functions have been filled in
sicmutils.genericand aliased insicmutils.env:- Inverse cotangent:
acot - inverse secant:
asec - inverse cosecant:
acsc - hyperbolic (inverse hyperbolic) cotangent:
cothandacoth - hyperbolic (and inverse hyperbolic) secant:
sechandasech - hyperbolic (and inverse hyperbolic) cosecant:
cschandacsch
All of these have default implementations and derivatives defined. They'll work out of the box for all types with
atandefined (and potentiallyexp,sqrtandlog.)Thanks to John D Cook's 'Bootstrapping a minimal math library' for his inspiration on the defaults and implementation order of these new functions.
- Inverse cotangent:
-
exptgains a new default implementation for non-native-integral powers, makingexptwork for any type withexp,logandmuldefined. -
sqrtgains a default implementation for all types implementingexp,mulandlog. -
All trig functions now have derivatives and docstrings.
-
New
sinc,tanc,sinhc,tanhcfunctions live insicmutils.genericand are aliased intosicmutils.env. These are generically defined as(/ (sin x) x),(/ (tan x) x)(and similar withsinhandtanh), with correct definitions for 0 and infinite-valued inputs.These functions all support derivatives as well.
-
New default
acotimplementation insicmutils.series.
-
Matrix / Structure / Tensors
-
#469:
-
sicmutils.matrixgains:-
literal-column-matrix,literal-row-matrixfor generating slightly tidier matrices of literal entries. (Seeliteral-matrixfor the prior option.) -
structure->matrixconverts 2 tensors into explicit matrices. -
s:solve-linear-left,s:solve-linear-right,s:divide-by-structureact on 2 tensors. These live in the matrix namespace since they depend on conversions to and from tensors and matrices. -
make-diagonalfor generating diagonal matrices with a constant element along the diagonal. -
s->m,s:transposeands:inverseall gain new 2-arities that provides a sane default forls. -
More efficient matrix
invertanddeterminantroutines, plus functions to generate type specific custom matrix inversion and determinant routines viaclassical-adjoint-formula,general-determinant. -
Linear equation solving via
solve,rsolveandcramers-rule.
-
-
sicmutils.structuregainsdown-of-ups?,up-of-downs?,two-up?,two-down?,two-tensor?andtwo-tensor-infofor working with "2 tensors", ie, structures that contain structural entries of matching orientation and size. -
Implements new generics for matrices and structures:
-
diagonal matrices respond true to
v/=with a scalar if all entries along the diagonal are equal to that scalar. -
square matrices can now
g/+andg/-with scalars; the scalarcis converted(* c I), whereIis an identity matrix of the same dimension as the square matrix. -
(g/acot M)now expands the matrixMinto a nice power series, more efficient than the previous default. -
Thanks to
solveandcramers-rule, the followingg/divcombinations now work:matrix/scalar,scalar/square-matrix,column-matrix/square-matrix,row-matrix/square-matrix,up/square-matrix,down/square-matrix,matrix/square-matrix. -
new
solve-linearimplementations between square matrices andupdown, row and column matrices, and between structures and scalars. -
new
solve-linear-rightbetween row-matrix+square-matrix, down+square-matrix and scalar+structure.
-
-
Folds
-
#456:
- Richardson extrapolation is now implemented as a functional fold. The exposition in
sicmutils.polynomial.richardsondiscusses this; the namespaces gainsrichardson-fold,richardson-sumandrichardson-scan.
- Richardson extrapolation is now implemented as a functional fold. The exposition in
-
#451:
-
new
sicmutils.algebra.foldnamespace:-
New folds:
kahan-babushka-neumaier(aliased askbn),kahan-babushka-kleinand andkbk-nmacro for generating higher-orderkahan-babushka-kleinvariants.generic-sum-foldfolds usingsicmutils.generic/+. -
sicmutils.util.aggregate/kahan-foldnow lives here, namedkahan. -
fold->sum-fnandfold->scan-fngenerate functions likesicmutils.util.aggregate.{sum,scan}specialized to the supplied fold. See the docstrings for the multiple arities supported -
fold primitives:
count,constant,min,max. -
fold combinator
joinallows compound folds to be built out of primitive folds.
-
-
Upgrades to
sicmutils.util.aggregate:-
scanning-sumrenamed toscan -
halt-atdeleted in favor of the built-inhalt-whenthat I didn't know about! -
scanandsumnow both use a dynamic binding,*fold*, to set the fold they use for aggregation. By default, this is set to the newkahan-babushka-neumaier-fold. -
The three-arity version of
sumnow uses transducers, saving a pass over the input range. -
pairwise-sumimplements pairwise summation, an error-limiting technique for summing vectors. Use the dynamic binding*cutoff*to set wherepairwise-sumbails out to normal summation.
-
-
Upgrades to
sicmutils.rational-function.polynomial:-
The folds in this namespace now follow the fold contract laid out in
sicmutils.algebra.fold, implementing all three arities correctly. -
I realized that the fold implementation here should /not/ return a full row every time it processes a previous row; a far better
presentimplementation would return the best estimate so far. Then you could build ascanfrom that fold to see the estimates evolve lazily as new points are added. This has better performance, it turns out, than the original method! -
added a bunch to the exposition to make the advantages clear.
-
-
Upgrades to
sicmutils.rational-function.interpolate:-
foldinterface upgraded, similar to the polynomial interpolation notes. -
New
bulirsch-stoer-fold,bulirsch-stoer-sumandbulirsch-stoer-scanfunctions. These are similar to themodified-**versions but use thebulirsch-stoeralgorithm, instead ofmodified-bulirsch-stoer. -
modified-bulirsch-stoer-fold-fnrenamed tomodified-bulirsch-stoer-fold, to match the naming scheme of other "folds" in the library. -
modified-bulirsch-stoer-foldrenamed to `modi...
-
-
0.20.1: sci bugfix around define-coordinates
Small bugfix release to push out #396 .
-
#396:
-
fixes a bug in the SCI version of
define-coordinateswhich didn't allow
any rebinding of manifolds. -
Removes the
bindingskey fromsicmutils.env.sci/context-opts.
babashka/sci#637 is a bug with variable rebinding
that occurs when:bindingsis in play. Instead of relying on this key,
evaluate(require '[sicmutils.env :refer :all])against your SCI
environment to get all bindings. -
bumps the default version of SCI to 0.2.7.
-
0.20.0: Differential Geometry + Einstein's Field Equations
This release cleans up the differential geometry utilities in SICMUtils and fixes a couple of bugs that prevented the Einstein Field Equations from running. These now work well, and very fast!
Highlights
- A new
define-coordinatesmacro - Einstein's field equations now run as tests: https://github.com/sicmutils/sicmutils/blob/main/test/sicmutils/fdg/einstein_test.cljc#L41
- All code listings from Functional Differential Geometry now work and are implemented as tests in the FDG test directory.
- You can now define complex numbers using the
#sicm/complexreader literal:
#sicm/complex [1.2 3.6] ;; 1.2+3.6i
#sicm/complex [1.2] ;; 1.2
#sicm/complex 1.4 ;; 1.4
#sicm/complex "1.2 + 3.6i" ;; 1.2+3.6iA big thanks to @phasetr for pushing on this in this discussion: #380
New Features
-
#348:
-
Adds a new single arity version of
sicmutils.util.permute/permutation-parity, which returns the parity of a
permutation relative to its sorted version. -
sicmutils.complex/complexcan now take a single string argument in both
Clojure and Clojurescript. -
Expands the complex number literal parser to take these forms, in addition
to the previously-supported string argument:
-
#sicm/complex [1.2 3.6] ;; 1.2+3.6i
#sicm/complex [1.2] ;; 1.2
#sicm/complex 1.4 ;; 1.4
#sicm/complex "1.2 + 3.6i" ;; 1.2+3.6i-
#393:
-
Forms like
(let-coordinates [(up x y) R2-rect] ...)will now work even ifupis not present in the environment. Previously this syntax was valid, but only ifuphad been imported. -
Adds the
sicmutils.calculus.coordinate/define-coordinatesmacro, also aliased intosicmutils.env. This macro allows you to write forms like
-
(define-coordinates (up t x y z) spacetime-rect)
(define-coordinates [r theta] R2-polar)and install a set of bindings for a manifold's coordinate functions, basis vector fields and basis form fields into a namespace. This is used liberally in Functional Differential Geometry. (You might still prefer let-coordinates for temporary binding installation.)
-
Converts many of the
sicmutils.fdgtest namespaces to use the newdefine-coordinatesmacro, making for a presentation closer to the book's. -
Fixes a Clojurescript warning in
sicmutils.utilwarning due to redefinition ofclojure.core/uuid -
#381:
same.ish/Approximateimplemented forsicmutils.structure/Structure, allowingish?comparison ofupanddownstructures with approximate entries. Requiresicmutils.generatorfor this feature. (NOTE: because protocols are implemented for the LEFT argument,(ish? <vector> (down ...))will still return true if the values are approximately equal, even though a<vector>is technically anupand should NOT equal adown. Do an explicit conversion toupusingsicmutils.structure/vector->upif this distinction is important.) -
#381:
-
Section 7.3 of FDG implemented as tests in
sicmutils.fdg.ch7-test. -
#382 adds tests for all code forms in Chapter 8 of FDG.
-
Many new tests and explorations ported over from
covariant-derivative.scm. These live insicmutils.calculus.covariant-test.
-
-
#384:
-
Adds
sicmutils.fdg.ch9-test, with tests for all forms from FDG's 9th chapter. -
Tests from
sicmutils.fdg.einstein-testnow all work, and quite fast. The functions in this namespace comprise some of the exercises from FDG chapter
9. (Einstein's Field Equations hung until this PR... getting these working
is a huge achievement for me, and, in some sense, the final milestone of the
Big Port from scmutils.) -
Adds
sicmutils.function/memoize, a metadata-and-function-arity preserving version ofclojure.core/memoize. -
Adds new
manifold?andmanifold-family?functions insicmutils.envandsicmutils.calculus.manifold. These are enabled by new:type :sicmutils.calculus.manifold/{manifold,manifold-family}keys in the appropriate structures in the manifold namespace. Manifolds and manifold families will now respond with these keywords tosicmutils.value/kind.
-
-
#386:
-
Aliases
sicmutils.mechanics.hamilton/phase-space-derivativeintosicmutils.env, and addssicmutils.sr.frames/base-frame-maker. The latter function makes it easier to write reference frames likethe-ether, as with thehomevariable in chapter 11 of FDG. -
Adds all code listings from chapters 10 and 11 of FDG as
sicmutils.fdg.{ch9,ch10}-test.
-
Functions moves, API changes
- #381:
sicmutils.calculus.coordinate/generatemoves tosicmutils.calculus.manifold/c:generate; this supports a bugfix where 1-dimensional manifolds likeR1-rect, akathe-real-line, return a coordinate prototype of a single element liketinstead of a structure with a single entry, like(up t). Thanks to @phasetr for the bug report that led to this fix, and @gjs for finding and fixing the bug.
Bug Fixes
- #394 fixes a bug with derivatives of functions that returned a map... but where the map was actually meant to represent some other type, by holding a
:typekey. We do this for manifold families and manifold points, as two examples. Now, instead of recursing into the values, the system will correctly throw an error. (You can fix this by using adefrecordinstead of a map and implementingsicmutils.differential/IPerturbed.)
#381:
-
same.ish/Approximatenow defers tosicmutils.value/=for equality betweenSymboland other types. This letsish?handle equality between symbols like'xand literal expressions that happen to wrap a single symbol. -
Cartan->Cartan-over-mapnow does NOT compose(differential map)with its internal Cartan forms. This fixed a bug in a code listing in section 7.3 of FDG. -
timeout exceptions resulting from full GCD are now caught in tests using
sicmutils.simplify/hermetic-simplify-fixture. Previously, setting a low timeout where simplification failed would catch and move on in normal work, but fail in tests where fixtures were applied -
#382:
- Makes the
nameargument tosicmutils.operator/make-operatoroptional.namenow defaults to'???.
- Makes the
-
#384:
-
in
sicmutils.calculus.indexed,with-argument-typesandwith-index-typesnow both correctly set the arity of the returned function, in addition to the argument types or indices.sicmutils.function/aritywill now work correctly with indexed or typed functions. -
The
sicmutils.calculus.manifold/ICoordinateSystemnow has auuidfunction, for internal comparison of coordinate systems. This is here so that points can cache coordinate system representations by UUID. Before this change, changing the coordinate prototype, or attaching metadata to a coordinate system would break its cache entry in manifold points. (This was the killer for the Einstein Field Equations!) -
sicmutils.calculus.manifold/{coordinate-prototype,with-coordinate-prototype}now store and retrieve the coordinate prototype from metadata. This plus the previous change allows manifold points to correctly cache their coordinate representations. -
sicmutils.calculus.manifold/manifoldacts as identity on manifolds now. Previously it only worked on coordinate systems.
-
-
#376 adds more type hints to the
ratio.cljcnamespace. This fully solves the advanced compilation issues we were seeing. -
#374: Demos, thanks to @sigmaxipi!
-
#379 fixes typos in a couple of the equations in
richardson.cljc, closing #377. Thanks to @leifp for the report.
0.19.2: Fraction.js version bump, cljsjs advanced compilation
Incremental release that bumps the Fraction.js dependency to 4.1.1. This includes cljsjs/packages#2190, which makes bigfraction.js compatible with advanced compilation.
- #372 bumps the
Fraction.jsdependency to4.1.1.
0.19.1: Advanced Clojurescript Compilation
This is an incremental bugfix release to get Clojurescript advanced compilation into shape.
-
#371:
-
fixes a subtle bug with extern inference on
fraction.js/bigfraction.js. Thanks to @sigmaxipi for this report! -
removes overridden factory constructors like
->Polynomial. I had originally done this for functions that held a metadata field, so that the user could leave it out and have it default tonil... but advanced Closure compilation can't understand thens-unmapcall, so it has to go. -
Many unary functions on
Operator,Structure,Series,PowerSeries,PolynomialandRationalFunctionnow preserve metadata. Binary functions between two instances of any of these still return a new object with metadata ==nil.
-
0.19.0: Oh-So-Fast Simplification, Quicker Derivatives
(If you have any questions about how to use any of the following, please ask us at our Github Discussions page!)
This release focused on improving the expressiveness and performance of the three simplification engines in SICMUtils:
-
sicmutils.polynomialandsicmutils.rational-functionare now quite well fleshed out, with full polynomial and rational function APIs and many generics. -
The polynomial and rational function simplifiers work by round-tripping expressions through these types, depending on each namespace to emit symbolic expressions in "canonical form". This process is now much faster! On one important Bianchi Identity benchmark in
sicmutils.fdg.bianchi-test, one test that formerly took close to 30 minutes now runs in 30 seconds, and all see a 60-fold improvement. -
By default, these simplifiers emit expressions with all terms multiplied out; the new
factorfunction insicmutils.envlets you factor expressions, overriding this default. -
The rule-based simplifier is now based on a powerful pattern matching engine, implemented in
pattern.matchandpattern.rule.sicmutils.simplify.rulesnow contains every rule and possible customization from the original scmutils codebase.
There is a lot in this release, all motivated by performance. Please read on for the detailed notes, and enjoy version 0.19.0!
Rule-Based Simplifier Overhaul
-
#353 introduces a powerful new simplifier, ported from the
new-simplifyprocedure insimplify/rules.scmof the scmutils library. There are now a BUNCH of new rulesets and rule simplifiers insicmutils.simplify.rules!The next step with these is to massage them into separate bundles of rules that users can mix and match into custom simplifiers for objects like abstract matrices, abstract bra and ket structures, up and down, booleans (for representing equations and inequalities) and so on.
-
#349 introduces a new pattern matching system, built out of matcher combinators. All of the rules in
sicmutils.simplify.rulesnow use the new syntax offered by the library. Some notes:-
pattern.matchdefines a number of "matcher combinators"; these are functions that take a map of bindings, a data input and a success continuation and either succeed by calling their continuation, or fail. Out of the box, the library providesfail,pass,with-frame,update-frame,predicate,frame-predicate,eq,bind,match-when,match-if,or,and,not,segmentandsequence. -
Additionally, any combinator that takes another combinator can ALSO take a pattern form like
'?x. Seepattern.syntaxfor the full, rich range of syntax allowed. These are all functions, so you'll have to quote your symbols at this stage. -
Passing a matcher combinator to
pattern.match/matcherto generate a matcher object. This is a function from somedatainput to a map of bindings on success, or an explicitpattern.match/failureobject on failure. Test for failure withpattern.match/failed?. -
A combination of a matcher and a "consequence function" is called a "rule". A consequence is a function that takes a binding map and either returns a new result or fails by returning
nilorfalse. (Don't worry, you can succeed with these values too by wrapping them insicmutils.rule/succeed.)Rules are the heart of the whole simplification mechanism in sicmutils! To learn about how to build these, see the documentation for
pattern*,pattern,consequence,template,rule*andrule. -
pattern.rulegives you some starter rules, and many combinators you can use to build more and more powerful and complex sets of rules. These arepass,fail,predicate,return,branch,choice*,choice,pipe*,pipe,n-times,attempt,guard,iterated,while,until,fixed-pointandtrace. -
Rules are nice for rewriting entire expressions recursively, from the bottom up or top down. This is called "term rewriting". A big motivation for this rewrite was to make it easy to build custom term rewriters for types like abstract matrices or abstract up and down structures. You can use your rules to rewrite structures recursively with
bottom-up,top-down,iterated-bottom-upanditerated-top-down.ruleset*,ruleset,rule-simplifierandterm-rewritingcapture some common patterns the library uses to go from rules => term rewriters. -
If you want ideas about how to use the pattern matching library to rewrite expressions, see
sicmutils.simplify.rulesfor many examples.
-
-
#354 adds SCI support for all macros and functions in the new pattern matching namespaces, and adds these to the namespaces exposed via
sicmutils.env.sci.
Rational Function, Polynomial Simplifiers
-
#341 takes on a large rewrite of the rational function and polynomial simplfiers. One goal of this project was to improve the performance of the Bianchi Identities in
sicmutils.fdg.bianchi-test, and I'm happy to say that they are now a good bit faster than the original scmutils implementation.sicmutils.polynomialandsicmutils.rational-functionare now solid data structures of their own, with many operations installed into the generic system. These are now valuable and useful outside of their role in the simplifier.This was a large project, and many small improvements and bugfixes snuck in. Here is the full list:
-
v/kindnow works forsorted-mapinstances. -
GCD in Clojurescript is now fast and efficient between all combinations of
js/BigIntandjs/Number, and in Clojure between all combinations ofclojure.lang.BigInt,BigInteger,LongandInteger. -
on the JVM, GCD now works properly with rational numbers. Previously anything non-integral would return
1; now(gcd 1/2 1/3)properly returns1/6. -
g/exact-dividenow succeeds for all non-exact::v/scalartypes (symbols, floats, etc) either if the denominator is zero, or if the two arguments are equal. Else, it throws, just like before. -
A multi-arity call to
sicmutils.generic/*now stops if it encounters a 0, rather than attempting to multiply all remaining items by 0. -
The default function for
sicmutils.generic/lcmprotects against overflow by dividing only a single one of its argumentsaandbby(gcd a b). -
(g/lcm 0 0)now properly returns 0. -
New
sicmutils.util.aggregate/{monoid,group}functions let you build multi-arity aggregations out of binary combination functions, with an option to bail early at "annihilator" values, like 0 for multiplication. -
New multi-arity
lcmandgcdimplementations for symbolic expressions appropriately handle0and1on either side, as well as the case where both arguments are equal. -
In the
sicmutils.numsymbnamespace, thanks tomonoidandgroup, the'*,'/,'-,'+,'or,'and,'gcd,'lcmand'=operations now have efficient multi-arity implementations that stop computing when they receive an annihilator, like0for multiplication ortrueforor. Access these via(sicmutils.numsymb/symbolic-operator <symbol>). -
sicmutils.series/PowerSeriesgainsarg-scaleandarg-shiftfunctions; these are identical tosicmutils.function/arg-{scale,shift}, but preserve thePowerSeriestype. (#367 proposes making these functions generic.) -
New
sicmutils.ratio/IRationalprotocol, withnumeratoranddenominatorfunctions implemented for ratios and for theRationalFunctiondata type. These two are now exposed insicmutils.env. -
sicmutils.simplify.rules/*divide-numbers-through-simplify?*is nowtrueby default; numbers in the denominator will now automatically pull up into the numerator. All tests now reflect this setting. -
Any analyzer generated from
sicmutils.expression.analyzecan now act on both bare, unwrapped expressions (raw lists etc) and onsicmutils.expression.Literalinstances. This means that you can now callsicmutils.simplify/{*rf-simplify*,*poly-simplify*}as functions and canonicalize some form with either simplifier without triggering a full simplification. A small win, but ice. -
sicmutils.polynomial.factorgot a major rewrite, and now exposes a few functions likepoly->factored-expression,factor-expressionandfactor.factoris tremendously useful! Callfactor(it's aliased intosicmutils.env) on any expression to factor out all possible terms. This makes it much easier to see where there is some cancellation lurking, in, say, some expression you know should equal zero (a residual).
-
bugfix:
sicmutils.expression.Literalinstances now compare their contained expression viasicmutils.value/=. -
sicmutils.rules/constant-eliminationcan now eliminate constants from expressions with any arity, not just binary forms.
Now, the three big namespaces...
sicmutils.polynomial,sicmutils.rational-functionandsicmutils.polynomial.gcdall got a big overhaul.-
sicmutils.polynomialnotes:-
Polynomialuses a new sparse representation for its "power product" term; this, plus an arithmetic rewrite, makes the whole system much faster for larger numbers of variables (for all #s, really). -
Polynomialinstances implement many more Clojure(script) protocols. They can hold metadata; they can be evaluated as functions of their indeterminates, andseqnow returns a sequence of terms. -
Polynomialextendssicmutils.function/IArityanddifferential/IPerturbed, so you can usesicmutils.function/arity, and take derivatives of functions that return polynomials. -
In their arithmetic,
Polynomialinstances will drop down to bare coefficients whenever some multiplication or addition removes all indeterminates. All binary arithmetic exposed in the namespace can han...
-
-
0.18.0: Functional Different Geometry complete!
This release focused on porting over all of the material required to run every piece of code from Sussman and Wisdom's "Functional Differential Geometry". The namespaces are lightly documented; the situation is better than the original library, but will only get better as I work through the material and add commentary.
There is a huge amount of functionality and material here! We can run many examples from general and special relativity, and the tests are full of exercises from the classic "Gravitation" book by Misner, Thorne and Wheeler (MTW).
Notable changes from the rest of the library:
-
Operatorinstances are slightly more efficient with their addition and multiplication, handlingzero?andone?cases appropriately -
Structures can now hold metadata -
We've extended the SICMUtils generics to Clojure's Map and Set data structures. These can now combine with
+. Maps are treated as sparse infinite-dimensional vector spaces, and can multiply with symbolic or numeric scalars. -
ModIntinstances are now correctly equal to numbers (when those numbers mod down to theModIntinstance's residue).
What's next?
The next major change will be an overhaul of the simplifier to make it work fast enough to solve Einstein's field equations in a reasonable amount of time, maybe even in the browser. Polynomial GCD is slow, but #341 will make it fast.
On to the detailed notes!
Functional Differential Geometry
-
From #339:
-
The new
sicmutils.calculus.covariant/Lie-Dcan compute the Lie derivative for coordinates. -
sicmutils.calculus.framelets us create relativistic reference frames for investigating special relativity problems. This namespace aliases the following functions intosicmutils.env: 'frame?',make-event,event?,claim,coords->event,event->coords,ancestor-frame,frame-name,frame-ownerandframe-maker. -
sicmutils.calculus.hodge-starimplements the Hodge star operator from chapter 10 of Functional Differential Geometry, plus Gram Schmidt orthonormalization. This namespace aliases the following functions intosicmutils.env:Gram-Schmidt,orthonormalizeandHodge-star. -
sicmutils.calculus.indexedports over the scmutils work on indexed objects and typed functions. This namespace aliases the following functions intosicmutils.env:argument-types,with-argument-types,index-types,with-index-types,typed->indexed,indexed->typed,typed->structure,structure->typed,i:outer-productandi:contract. -
sicmutils.calculus.manifoldgainscoordinate-system?, which (predictably) returns true if its argument is a coordinate system, false otherwise.chartandpointalso take relativistic reference frames in addition to coordinate systems; the returned function converts to and from coordinates and events, rather than coordinates and manifold points. -
Div,Grad,CurlandLapmove fromsicmutils.calculus.derivativetosicmutils.calculus.vector-calculus. This namespace also contains versions of these operators from Functional Differential Geometry. This namespace aliases the following functions intosicmutils.env:divergence,curl,gradientandLaplacian(along with the others mentioned). -
lots of new namespaces available in
sicmutils.env.sci, soon to be deployed to Nextjournal:sicmutils.calculus.{hodge-star, indexed, vector-calculus}, andsicmutils.sr.{boost,frames}. -
sicmutils.sr.boostdescribes boosts from special relativity, covered in chapter 11 of Functional Differential Geometry. This namespace aliases the following functions intosicmutils.env:make-four-tuple,four-tuple->ct,four-tuple->space,proper-time-interval,proper-space-interval,general-boost,general-boost2andextended-rotation. -
sicmutils.sr.framesimplements relativistic reference frames from special relativity, covered in chapter 11 of Functional Differential Geometry. This namespace aliases the following functions intosicmutils.env:make-SR-coordinates,SR-coordinates?,SR-name,make-SR-frame,the-ether,boost-direction,v:c,coordinate-origin,add-v:csandadd-velocities.
-
-
From #338:
-
sicmutils.fdg.bianchi-testverifies the Bianchi identities; this was a challenge posed by GJS, and getting it working exposed a few bugs and triggered the rest of the work in this PR. Thank you, GJS! -
covariant-derivativenow properly handles the case of functions with argument types attached. -
added
covariant-differentialtosicmutils.calculus.covariant. -
aliased all functions from various namespaces in
sicmutils.calculusintosicmutils.env. -
adds
sicmutils.calculus.metric, with the following functions exposed insicmutils.env:-
coordinate-system->metric-components,coordinate-system->metric,coordinate-system->inverse-metric,literal-metric,components->metric,metric->components,metric->inverse-components,metric-over-map,lower,vector-field->oneform-field,drop1,raise,oneform-field->vector-field,raise1,drop2,raise2,trace2down,trace2up,sharpen,S2-metric -
sicmutils.calculus.metric/invertis exposed asmetric:invertto match the scmutils naming scheme.
-
-
adds
sicmutils.calculus.connection, with the following functions exposed insicmutils.env:make-Christoffel-1,metric->Christoffel-1,metric->Christoffel-2,literal-Christoffel-1,literal-Christoffel-2,metric->connection-1,metric->connection-2,literal-Cartan,structure-constant
-
-
#337:
-
adds
sicmutils.calculus.curvature, with these new functions and many tests from the classic "Gravitation" book:Riemann-curvature,Riemann,Ricci,torsion-vector,torsionandcurvature-components -
form fields now have NO identity operator, since they multiply by wedge, not
composition.
-
-
#328 adds many utilities for "Functional Differential Geometry".
-
vector fields, in
sicmutils.calculus.vector-field:-
new functions:
basis-components->vector-field,
vector-field->basis-components -
vector fields now implement
v/zero?andv/zero-likeby returning
proper vector fields.
-
-
form fields, in
sicmutils.calculus.vector-field:-
new functions:
nform-field?,basis-components->oneform-field,oneform-field->basis-componentsandfunction->oneform-field(aliased asdifferential-of-function) -
Alt,alt-wedgeprovide alternate wedge product definitions -
form fields now implement
v/zero?andv/zero-likeby returning proper form fields that retain their rank. -
form fields now correctly multiply via
*by usingsicmutils.calculus.form-field/wedge, instead of composition.
-
-
maps between manifolds, in
sicmutils.calculus.map:-
new function:
pushforward-function -
differentialbecomesdifferential-of-map, aliased back asdifferential
-
-
sicmutils.calculus.covariantgains new functions:Cartan?,Christoffel?,Cartan->Christoffel,symmetrize-Christoffel,symmetrize-Cartan,Cartan->Cartan-over-map,geodesic-equation,parallel-transport-equation. -
sicmutils.calculus.covariant/vector-field-Lie-derivativecan now handle structural inputs.
-
New Functions, Functionality
-
From #342:
-
Added
sicmutils.calculus.derivative/D-as-matrixandsicmutils.matrix/as-matrix, ported from scmutils. -
converted
sicmutils.modint.ModIntto adeftype; this allowsModIntinstances to be=to non-ModIntnumbers on the right, if the right side is equal to the residue plus any integer multiple of the modulus.v/=gives us this behavior with numbers on the LEFT too, andModInton the right.- This change means that
:iand:mwon't return the residue and modulus anymore.sicmutils.modintgains newresidueandmodulusfunctions to access these attributes.
- This change means that
-
The JVM version of sicmutils gains more efficient
gcdimplementations forIntegerandLong(in addition to the existing nativeBigIntegergcd), thanks to our existing Apache Commons-Math dependency. -
sicmutils.structure/dual-zeroaliasescompatible-zeroto match the scmutils interface. Both are now aliased intosicmutils.env. -
Structureinstances can now hold metadata (#339).
-
-
From #339:
-
In
sicmutils.mechanics.rotation:-
gains aliases for
R{xyz}inrotate-x,rotate-yandrotate-z. -
R{x,y,z}-matrixnow aliasrotate-{x,y,z}-matrix. -
Added new functions
angle-axis->rotation-matrixand the mysterious,
undocumentedwcross->wfrom scmutils -
rotate-{x,y,z}-tupleare now aliased intosicmutils.env.
-
-
Operatorinstances now ignore the right operator in operator-operator addition if the left operator passes av/zero?test. Contexts are still appropriately merged. -
in
sicmutils.simplify.rules, thesqrt-contractruleset now takes a simplifier argument and attempts to use it to simplify expressions internal to a square root. As an example, if two square roots in a product simplify to the same expression, we can drop the wrapping square root; otherwise multiplication is pushed under the root as before.- Added a missing rule in
simplify-square-rootsthat handles roots of exponents with odd powers.
- Added a missing rule in
-
sicmutils.matrixchanges:-
generatehas a new 2-arity version; if you supply a single dimension the returned matrix is square. -
diagonal?returns true if its argument is a diagonal matrix, false
otherwise.
-
-
A new namespace,
sicmutils.util.permute...
-