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
cljc
namespaces with macros; this removes the need for:include-macros true
or:refer-macros
and 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
IHash
implementations forjs/BigInt
,goog.math.Long
,goog.map.Integer
andRatio
types
-
-
#514:
-
Modifies
sicmutils.calculus.derivative/taylor-series
to return a properPowerSeries
instance, which the user can call with somedx
to 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 yourdx
components 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-series
is a port ofTaylor-series-coefficients
fromscmutils
. 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
1
as theone-like
andidentity-like
return 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,1
is a fine choice and matches thescmutils
implementation. -
new
sicmutils.differential/map-coefficients
, which makessimplify
slightly 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/substitute
now works for properLiteral
instances. 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-state
andRouthian-state->Lagrangian-state
. -
adds missing
sicmutils.mechanics.{routhian,time-evolution,noether}
tosicmutils.env.sci
-
-
#509:
-
Fixes a bug with
down*Matrix
multiplication, and adds tests for correctness. -
Adds
sicmutils.matrix.{symmetric?,antisymmetric?}
predicates -
The mechanics port continues with
sicmutils.mechanics.rigid
:-
T-rigid-body
moves toT-body-Euler
with an alias back to its original name. Same situation forEuler-state->L-body
=>L-body-Euler
andEuler-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-sq
andmagnitude
are 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/Lagrangian
for building function signatures of Lagrangians. -
adds the
sicmutils.mechanics.time-evolution
namespace -
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->CH
moves toF->CT
(F->CT
is now an alias) -
Legendre-transform-fn
becomesLegendre-transform-procedure
and gains more correctness tests, toggled on and off by the*validate-Legendre-transform?*
dynamic variable.
-
-
-
#508 adds
sicmutils.mechanics.noether
namespace, 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
mechanics
package over the Clojure. This PR focuses onsicmutils.mechanics.lagrange
, which contains functions from many files in the originalmechanics
folder.-
momentum-tuple
moves 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-state
path->state-path
(alias for the existingGamma
),Rayleigh-dissipation
,qv->local-path
,Lagrange-equations-first-order
, (withLagrange-equations-1
alias),Lagrangian->power-loss
,T3-spherical
,L3-central
,Dt-procedure
and the wrapping operatorDt
,Euler-lagrange-operator
(withLagrange-equations-operator
andLE
aliases),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-derivative
now take a dissipation function -
local-state-derivative
aliases the 1-arity version ofLagrangian->state-derivative
-
New
rectangular->polar
,polar->rectangular
,spherical->rectangular
andrectangular->spherical
that operate on coordinates, with associatedr->p
(new),p->r
,s->r
andr->s
(new).
-
-
#501 moves
elliptic-integrals
fromsicmutils.special.elliptical-test
sicmutils.special.elliptical
, as it's needed by the upcomingsicmutils.mechanics.pendulum
namespace.
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-subexpressions
withdoall
-
Adds type hints to all remaining
Complex
calls in js, to fix issues with advanced compilation (thanks to @mhuebert for finding this) -
#515:
-
-
tidies up the
square
andcube
speedups thanks to a tip from GJS -
Converts more
(mul x x)
tosquare
in the derivatives of thesicmutils.generic
namespace. -
fixes a bug in the
numeric-zero?
check of exponent's derivative. -
#503:
-
Changes the default implementation of
square
andcube
for 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
simplify
call I added, this change dropped the runtime of thesicmutils.sicm.ch3-test
suite down by 6x. After the simplify change insicmutils.examples.top
the tests were still 40% faster in that namespace. -
Fixes a bug where the
RationalFunction
cube implementation actually calledsquare
.
-
Misc
-
#532:
-
Removes the
potemkin
dependency by importing only what we need directly intosicmutils.util.def
. This makes sense since our versions add afork
call so that they work for ClojureScript as well. -
Moves all
examples
into the tests so that we don't ship them with the library. These will eventually be converted to Clerk notebooks. -
Removes the
hiccup
dependency. -
Upgrades
test.chuck
and removes all:include-macros true
calls for that library. Onlysame/ish
requires them now! -
Capitalizes the "Script" in ClojureScript everywhere it appears.
-
-
#531:
- Drops cljsjs dependencies in favor of
deps.cljs
entries
- 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.compile
with 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
double
on the JVM orjs/Number
in javascript; this way noBigInt
values 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-fn
and its non-memoized version can now take an explicit:mode
argument; this will override the dynamically bound*mode*
. Invalid modes supplied via:mode
will causecompile-state-fn
to throw an exception. -
#496,
sicmutils.expression.compile
:-
gains a new, validating
compiler-mode
function for fetching the compiler function. -
set-compiler-mode!
now actually works. It never did! -
New
:source
compile mode that returns a source code form. You can either calleval
on this or callsci-eval
to get an SCI-evaluated function with all proper bindings in place. -
compile-state-fn
now 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 includedcljs
version to1.11.4
.sicmutils.collection
properly handles the new cljsIntegerRange
class.
- Bumps the shadow-cljs dependency to version
-
sicmutils.polynomial.factor
now memoizespoly->factored-expression
by default. If polynomial GCD fails inside that function the computation now proceeds with a warning instead of failing. -
#492 updates the
clj-kondo
linters to emit custom warnings with all metadata from the original token, not just:row
and:col
. This fixes the ability to override or ignore individual warnings. -
#490 adds
sicmutils.numerical.roots.bisect
with implementations of bisection search, secant search and a mixed method found inscmutils
. These all live under abisect
function.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/log
andg/exp
forjs/BigInt
instances, enablingg/log2
andg/log10
in 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
up
anddown
were 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-kondo
linter via an exported clj-kondo configuration in theresources
directory. 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.md
for 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
test
andsrc
directories. -
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-degree
argument 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.chuck
dev dependency upgraded to0.2.13
to grab its clj-kondo exported config. -
pattern.rule
patterns 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-test
around palindromic polynomials -
#480:
sicmutils.numerical.quadrature/definite-integral
now coerces the result of non-compiled integrands in cljs to double. This prevents the @kloimhardt bug where certain paths would produceBigInt
instances 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/->JavaScript
not using the second argument toremainder
. -
deleted
sicmutils.numerical.quadrature.common
in 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-upper
was not actually using its input function! -
unused
simplify
argument 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/template
will 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,
up
anddown
structures androw
andcolumn
matrices. -
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/quaternion
takes 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:
exp
log
,cos
,sin
,tan
sinh
,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?
returningfalse
for literal numbers and symbols. This was required to getg/abs
working for polynomials and rational functions with symbolic coefficients.
- Default implementation of
-
#448:
- new
g/infinite?
generic with implementations for all numeric types, complex numbers,differential
instances. Defaults tofalse
for all other types. (Also aliased intosicmutils.env/infinite?
).
- new
-
#449:
-
All missing trigonometric functions have been filled in
sicmutils.generic
and aliased insicmutils.env
:- Inverse cotangent:
acot
- inverse secant:
asec
- inverse cosecant:
acsc
- hyperbolic (inverse hyperbolic) cotangent:
coth
andacoth
- hyperbolic (and inverse hyperbolic) secant:
sech
andasech
- hyperbolic (and inverse hyperbolic) cosecant:
csch
andacsch
All of these have default implementations and derivatives defined. They'll work out of the box for all types with
atan
defined (and potentiallyexp
,sqrt
andlog
.)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:
-
expt
gains a new default implementation for non-native-integral powers, makingexpt
work for any type withexp
,log
andmul
defined. -
sqrt
gains a default implementation for all types implementingexp
,mul
andlog
. -
All trig functions now have derivatives and docstrings.
-
New
sinc
,tanc
,sinhc
,tanhc
functions live insicmutils.generic
and are aliased intosicmutils.env
. These are generically defined as(/ (sin x) x)
,(/ (tan x) x)
(and similar withsinh
andtanh
), with correct definitions for 0 and infinite-valued inputs.These functions all support derivatives as well.
-
New default
acot
implementation insicmutils.series
.
-
Matrix / Structure / Tensors
-
#469:
-
sicmutils.matrix
gains:-
literal-column-matrix
,literal-row-matrix
for generating slightly tidier matrices of literal entries. (Seeliteral-matrix
for the prior option.) -
structure->matrix
converts 2 tensors into explicit matrices. -
s:solve-linear-left
,s:solve-linear-right
,s:divide-by-structure
act on 2 tensors. These live in the matrix namespace since they depend on conversions to and from tensors and matrices. -
make-diagonal
for generating diagonal matrices with a constant element along the diagonal. -
s->m
,s:transpose
ands:inverse
all gain new 2-arities that provides a sane default forls
. -
More efficient matrix
invert
anddeterminant
routines, plus functions to generate type specific custom matrix inversion and determinant routines viaclassical-adjoint-formula
,general-determinant
. -
Linear equation solving via
solve
,rsolve
andcramers-rule
.
-
-
sicmutils.structure
gainsdown-of-ups?
,up-of-downs?
,two-up?
,two-down?
,two-tensor?
andtwo-tensor-info
for 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 scalarc
is converted(* c I)
, whereI
is an identity matrix of the same dimension as the square matrix. -
(g/acot M)
now expands the matrixM
into a nice power series, more efficient than the previous default. -
Thanks to
solve
andcramers-rule
, the followingg/div
combinations 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-linear
implementations between square matrices andup
down
, row and column matrices, and between structures and scalars. -
new
solve-linear-right
between 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.richardson
discusses this; the namespaces gainsrichardson-fold
,richardson-sum
andrichardson-scan
.
- Richardson extrapolation is now implemented as a functional fold. The exposition in
-
#451:
-
new
sicmutils.algebra.fold
namespace:-
New folds:
kahan-babushka-neumaier
(aliased askbn
),kahan-babushka-klein
and andkbk-n
macro for generating higher-orderkahan-babushka-klein
variants.generic-sum-fold
folds usingsicmutils.generic/+
. -
sicmutils.util.aggregate/kahan-fold
now lives here, namedkahan
. -
fold->sum-fn
andfold->scan-fn
generate 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
join
allows compound folds to be built out of primitive folds.
-
-
Upgrades to
sicmutils.util.aggregate
:-
scanning-sum
renamed toscan
-
halt-at
deleted in favor of the built-inhalt-when
that I didn't know about! -
scan
andsum
now 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
sum
now uses transducers, saving a pass over the input range. -
pairwise-sum
implements pairwise summation, an error-limiting technique for summing vectors. Use the dynamic binding*cutoff*
to set wherepairwise-sum
bails 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
present
implementation would return the best estimate so far. Then you could build ascan
from 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
:-
fold
interface upgraded, similar to the polynomial interpolation notes. -
New
bulirsch-stoer-fold
,bulirsch-stoer-sum
andbulirsch-stoer-scan
functions. These are similar to themodified-**
versions but use thebulirsch-stoer
algorithm, instead ofmodified-bulirsch-stoer
. -
modified-bulirsch-stoer-fold-fn
renamed tomodified-bulirsch-stoer-fold
, to match the naming scheme of other "folds" in the library. -
modified-bulirsch-stoer-fold
renamed 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-coordinates
which didn't allow
any rebinding of manifolds. -
Removes the
bindings
key fromsicmutils.env.sci/context-opts
.
babashka/sci#637 is a bug with variable rebinding
that occurs when:bindings
is 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-coordinates
macro - 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/complex
reader 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.6i
A 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/complex
can 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 ifup
is not present in the environment. Previously this syntax was valid, but only ifup
had been imported. -
Adds the
sicmutils.calculus.coordinate/define-coordinates
macro, 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.fdg
test namespaces to use the newdefine-coordinates
macro, making for a presentation closer to the book's. -
Fixes a Clojurescript warning in
sicmutils.util
warning due to redefinition ofclojure.core/uuid
-
#381:
same.ish/Approximate
implemented forsicmutils.structure/Structure
, allowingish?
comparison ofup
anddown
structures with approximate entries. Requiresicmutils.generator
for 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 anup
and should NOT equal adown
. Do an explicit conversion toup
usingsicmutils.structure/vector->up
if 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-test
now 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.env
andsicmutils.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-derivative
intosicmutils.env
, and addssicmutils.sr.frames/base-frame-maker
. The latter function makes it easier to write reference frames likethe-ether
, as with thehome
variable 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/generate
moves 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 liket
instead 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
:type
key. 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 adefrecord
instead of a map and implementingsicmutils.differential/IPerturbed
.)
#381:
-
same.ish/Approximate
now defers tosicmutils.value/=
for equality betweenSymbol
and other types. This letsish?
handle equality between symbols like'x
and literal expressions that happen to wrap a single symbol. -
Cartan->Cartan-over-map
now 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
name
argument tosicmutils.operator/make-operator
optional.name
now defaults to'???
.
- Makes the
-
#384:
-
in
sicmutils.calculus.indexed
,with-argument-types
andwith-index-types
now both correctly set the arity of the returned function, in addition to the argument types or indices.sicmutils.function/arity
will now work correctly with indexed or typed functions. -
The
sicmutils.calculus.manifold/ICoordinateSystem
now has auuid
function, 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/manifold
acts as identity on manifolds now. Previously it only worked on coordinate systems.
-
-
#376 adds more type hints to the
ratio.cljc
namespace. 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.js
dependency 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-unmap
call, so it has to go. -
Many unary functions on
Operator
,Structure
,Series
,PowerSeries
,Polynomial
andRationalFunction
now 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.polynomial
andsicmutils.rational-function
are 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
factor
function insicmutils.env
lets you factor expressions, overriding this default. -
The rule-based simplifier is now based on a powerful pattern matching engine, implemented in
pattern.match
andpattern.rule
.sicmutils.simplify.rules
now 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-simplify
procedure insimplify/rules.scm
of 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.rules
now use the new syntax offered by the library. Some notes:-
pattern.match
defines 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
,segment
andsequence
. -
Additionally, any combinator that takes another combinator can ALSO take a pattern form like
'?x
. Seepattern.syntax
for 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/matcher
to generate a matcher object. This is a function from somedata
input to a map of bindings on success, or an explicitpattern.match/failure
object 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
nil
orfalse
. (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.rule
gives 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-point
andtrace
. -
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-up
anditerated-top-down
.ruleset*
,ruleset
,rule-simplifier
andterm-rewriting
capture 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.rules
for 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.polynomial
andsicmutils.rational-function
are 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/kind
now works forsorted-map
instances. -
GCD in Clojurescript is now fast and efficient between all combinations of
js/BigInt
andjs/Number
, and in Clojure between all combinations ofclojure.lang.BigInt
,BigInteger
,Long
andInteger
. -
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-divide
now succeeds for all non-exact::v/scalar
types (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/lcm
protects against overflow by dividing only a single one of its argumentsa
andb
by(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
lcm
andgcd
implementations for symbolic expressions appropriately handle0
and1
on either side, as well as the case where both arguments are equal. -
In the
sicmutils.numsymb
namespace, thanks tomonoid
andgroup
, the'*
,'/
,'-
,'+
,'or
,'and
,'gcd
,'lcm
and'=
operations now have efficient multi-arity implementations that stop computing when they receive an annihilator, like0
for multiplication ortrue
foror
. Access these via(sicmutils.numsymb/symbolic-operator <symbol>)
. -
sicmutils.series/PowerSeries
gainsarg-scale
andarg-shift
functions; these are identical tosicmutils.function/arg-{scale,shift}
, but preserve thePowerSeries
type. (#367 proposes making these functions generic.) -
New
sicmutils.ratio/IRational
protocol, withnumerator
anddenominator
functions implemented for ratios and for theRationalFunction
data type. These two are now exposed insicmutils.env
. -
sicmutils.simplify.rules/*divide-numbers-through-simplify?*
is nowtrue
by 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.analyze
can now act on both bare, unwrapped expressions (raw lists etc) and onsicmutils.expression.Literal
instances. 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.factor
got a major rewrite, and now exposes a few functions likepoly->factored-expression
,factor-expression
andfactor
.factor
is 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.Literal
instances now compare their contained expression viasicmutils.value/=
. -
sicmutils.rules/constant-elimination
can now eliminate constants from expressions with any arity, not just binary forms.
Now, the three big namespaces...
sicmutils.polynomial
,sicmutils.rational-function
andsicmutils.polynomial.gcd
all got a big overhaul.-
sicmutils.polynomial
notes:-
Polynomial
uses 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). -
Polynomial
instances implement many more Clojure(script) protocols. They can hold metadata; they can be evaluated as functions of their indeterminates, andseq
now returns a sequence of terms. -
Polynomial
extendssicmutils.function/IArity
anddifferential/IPerturbed
, so you can usesicmutils.function/arity
, and take derivatives of functions that return polynomials. -
In their arithmetic,
Polynomial
instances 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:
-
Operator
instances are slightly more efficient with their addition and multiplication, handlingzero?
andone?
cases appropriately -
Structure
s 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. -
ModInt
instances are now correctly equal to numbers (when those numbers mod down to theModInt
instance'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-D
can compute the Lie derivative for coordinates. -
sicmutils.calculus.frame
lets 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-owner
andframe-maker
. -
sicmutils.calculus.hodge-star
implements 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
,orthonormalize
andHodge-star
. -
sicmutils.calculus.indexed
ports 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-product
andi:contract
. -
sicmutils.calculus.manifold
gainscoordinate-system?
, which (predictably) returns true if its argument is a coordinate system, false otherwise.chart
andpoint
also 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
,Curl
andLap
move fromsicmutils.calculus.derivative
tosicmutils.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
,gradient
andLaplacian
(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.boost
describes 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-boost2
andextended-rotation
. -
sicmutils.sr.frames
implements 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:cs
andadd-velocities
.
-
-
From #338:
-
sicmutils.fdg.bianchi-test
verifies 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-derivative
now properly handles the case of functions with argument types attached. -
added
covariant-differential
tosicmutils.calculus.covariant
. -
aliased all functions from various namespaces in
sicmutils.calculus
intosicmutils.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/invert
is exposed asmetric:invert
to 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
,torsion
andcurvature-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-like
by returning
proper vector fields.
-
-
form fields, in
sicmutils.calculus.vector-field
:-
new functions:
nform-field?
,basis-components->oneform-field
,oneform-field->basis-components
andfunction->oneform-field
(aliased asdifferential-of-function
) -
Alt
,alt-wedge
provide alternate wedge product definitions -
form fields now implement
v/zero?
andv/zero-like
by 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
-
differential
becomesdifferential-of-map
, aliased back asdifferential
-
-
sicmutils.calculus.covariant
gains 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-derivative
can now handle structural inputs.
-
New Functions, Functionality
-
From #342:
-
Added
sicmutils.calculus.derivative/D-as-matrix
andsicmutils.matrix/as-matrix
, ported from scmutils. -
converted
sicmutils.modint.ModInt
to adeftype
; this allowsModInt
instances to be=
to non-ModInt
numbers 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, andModInt
on the right.- This change means that
:i
and:m
won't return the residue and modulus anymore.sicmutils.modint
gains newresidue
andmodulus
functions to access these attributes.
- This change means that
-
The JVM version of sicmutils gains more efficient
gcd
implementations forInteger
andLong
(in addition to the existing nativeBigInteger
gcd
), thanks to our existing Apache Commons-Math dependency. -
sicmutils.structure/dual-zero
aliasescompatible-zero
to match the scmutils interface. Both are now aliased intosicmutils.env
. -
Structure
instances can now hold metadata (#339).
-
-
From #339:
-
In
sicmutils.mechanics.rotation
:-
gains aliases for
R{xyz}
inrotate-x
,rotate-y
androtate-z
. -
R{x,y,z}-matrix
now aliasrotate-{x,y,z}-matrix
. -
Added new functions
angle-axis->rotation-matrix
and the mysterious,
undocumentedwcross->w
from scmutils -
rotate-{x,y,z}-tuple
are now aliased intosicmutils.env
.
-
-
Operator
instances 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-contract
ruleset 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-roots
that handles roots of exponents with odd powers.
- Added a missing rule in
-
sicmutils.matrix
changes:-
generate
has 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
...
-