diff --git a/README.md b/README.md index 74d00b6..536fe98 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![CI](https://github.com/Leedehai/typst-physics/actions/workflows/ci.yml/badge.svg)](https://github.com/Leedehai/typst-physics/actions/workflows/ci.yml) [![Latest release](https://img.shields.io/github/v/release/Leedehai/typst-physics.svg?color=gold)][latest-release] -Available in the collection of [Typst packages](https://typst.app/docs/packages/): `#import "@preview/physica:0.9.0": *` +Available in the collection of [Typst packages](https://typst.app/docs/packages/): `#import "@preview/physica:0.9.1": *` > physica _noun_. > * Latin, study of nature @@ -17,7 +17,8 @@ This [Typst](https://typst.app) package provides handy typesetting utilities for natural sciences, including: * Braces, * Vectors and vector fields, -* Matrices, including Jacobian and Hessian, interpreting `..^T` as transpose, +* Matrices, including Jacobian and Hessian, +* Smartly render `..^T` as transpose and `..^+` as dagger (conjugate transpose), * Dirac braket notations, * Common math functions, * Differentials and derivatives, including partial derivatives of mixed orders with automatic order summation, @@ -32,7 +33,7 @@ See the [manual](https://github.com/Leedehai/typst-physics/blob/master/physica-m A larger [demo.typ](https://github.com/Leedehai/typst-physics/blob/master/demo.typ): -![demo-larger](https://github.com/Leedehai/typst-physics/assets/18319900/af4fcf6c-5da3-48d1-a7a7-59053f808db5) +![demo-larger](https://github.com/Leedehai/typst-physics/assets/18319900/75b94ef8-cc98-434f-be5f-bfac1ef6aef9) ## Using physica in your Typst document @@ -49,21 +50,21 @@ compiler locally, it downloads packages on-demand and caches them on-disk, see ```typst // Style 1 -#import "@preview/physica:0.9.0": * +#import "@preview/physica:0.9.1": * $ curl (grad f), tensor(T, -mu, +nu), pdv(f,x,y,[1,2]) $ ``` ```typst // Style 2 -#import "@preview/physica:0.9.0": curl, grad, tensor, pdv +#import "@preview/physica:0.9.1": curl, grad, tensor, pdv $ curl (grad f), tensor(T, -mu, +nu), pdv(f,x,y,[1,2]) $ ``` ```typst // Style 3 -#import "@preview/physica:0.9.0" +#import "@preview/physica:0.9.1" $ physica.curl (physica.grad f), physica.tensor(T, -mu, +nu), physica.pdv(f,x,y,[1,2]) $ ``` diff --git a/demo.typ b/demo.typ index f5b38f0..bbf1856 100644 --- a/demo.typ +++ b/demo.typ @@ -11,7 +11,7 @@ A^T, curl vb(E) = - pdv(vb(B), t), quad tensor(Lambda,+mu,-nu) = dmat(1,RR), quad -dd(x,y), +f(x,y) dd(x,y), quad dd(vb(x),y,[3]), quad diff --git a/physica-manual.pdf b/physica-manual.pdf index 55daa9b..e9adc21 100644 Binary files a/physica-manual.pdf and b/physica-manual.pdf differ diff --git a/physica-manual.typ b/physica-manual.typ index 45cbad2..1740625 100644 --- a/physica-manual.typ +++ b/physica-manual.typ @@ -2,7 +2,7 @@ // This document is shared under the Creative Commons BY-ND 4.0 license. #import "physica.typ": * -#let version = "0.9.0" +#let version = "0.9.1" #set document( title: [physica-manual.typ], @@ -61,7 +61,7 @@ This manual itself was generated using the Typst CLI and the `physica` package, With `typst`'s #linkurl("package management", "https://github.com/typst/packages"): ```typst -#import "@preview/physica:0.9.0": * +#import "@preview/physica:0.9.1": * $ curl (grad f), pdv(,x,y,z,[2,k]), tensor(Gamma,+k,-i,-j) = pdv(vb(e_i),x^j)vb(e^k) $ ``` @@ -165,7 +165,7 @@ All symbols need to be used in *math mode* `$...$`. [`TT`], [], [`v^TT, A^TT` #sym.arrow $v^TT, A^TT$], - [transpose, also see\ @matrix-tranpose], + [transpose, also see\ @matrix-transpose], [`vectorbold(`_content_`)`], [`vb`], @@ -234,7 +234,7 @@ All symbols need to be used in *math mode* `$...$`. [`TT`], [], [`v^TT, A^TT` #sym.arrow $v^TT, A^TT$], - [transpose, also see\ @matrix-tranpose], + [transpose, also see\ @matrix-transpose], [#builtin([`mat(`...`)`])], [], @@ -591,6 +591,15 @@ Functions: `differential(`\*_args_, \*\*_kwargs_`)`, abbreviated as `dd(`...`)`. - named _kwargs_: - `d`: the differential symbol [default: `upright(d)`]. - `p`: the product symbol connecting the components [default: `none`]. + - `compact`: only effective if `p` is `none`. If `#true`, will remove the TeXBook-advised thin spaces between the d-units [default: `#false`]. + +TeXBook advises _[f]ormulas involving calculus look best when an extra thin space +appears before dx or dy or d whatever_ (Chapter 18 p.168), and this package +heeds this advice. If you don't want the spaces between the d-units, you may +pass a `compact:#true` argument: $dd(r,theta) "vs." dd(r,theta,compact:#true)$ (compact). +// https://github.com/typst/typst/issues/147 advocates for set rules for +// non built-in functions. When that's implemented, user can do a +// #set dd(compact: true) to set this param for all dd() invocations. *Order assignment algorithm:* - If there is no order number or order array, all variables has order 1. @@ -607,8 +616,8 @@ Functions: `differential(`\*_args_, \*\*_kwargs_`)`, abbreviated as `dd(`...`)`. column-gutter: 2em, [ - *(1)* #hl(`dd(f), dd(x,y)`) \ - $ dd(f), dd(x,y) $ + *(1)* #hl(`dd(f), f(r,theta) dd(r,theta)`) \ + $ dd(f), f(r,theta) dd(r,theta) $ ], [ *(2)* #hl(`dd(x,3), dd(f,[k]), dd(f,[k],d:delta)`) \ @@ -619,8 +628,8 @@ Functions: `differential(`\*_args_, \*\*_kwargs_`)`, abbreviated as `dd(`...`)`. $ dd(f,2), dd(vb(x),t,[3,]) $ ], [ - *(4)* #hl(`dd(x,y,[2,3]), dd(x,y,z,[2,3])`) \ - $ dd(x,y,[2,3]), dd(x,y,z,[2,3]) $ + *(4)* #hl(`dd(x,y), dd(x,y,[2,3]), dd(x,y,z,[2,3])`) \ + $ dd(x,y), dd(x,y,[2,3]), dd(x,y,z,[2,3]) $ ], [ *(5)* #hl(`dd(x, y, z, [[1,1],rho+1,n_1])`) \ @@ -756,68 +765,157 @@ Function: `partialderivative(`_f_, \*_args_, \*\*_kwargs_`)`, abbreviated as `pd *(11)* #hl(`integral_V dd(V) (pdv(cal(L), phi) - diff_mu (pdv(cal(L), (diff_mu phi)))) = 0`) \ $ integral_V dd(V) (pdv(cal(L), phi) - diff_mu (pdv(cal(L), (diff_mu phi)))) = 0 $ -== Miscellaneous +== Special show rules #v(1em) -=== Reduced Planck constant (hbar) +=== Matrix transpose with superscript T #v(1em) -In the default font, the Typst built-in symbol `planck.reduce` $planck.reduce$ looks a bit off: on letter "h" there is a slash instead of a horizontal bar, contrary to the symbol's colloquial name "h-bar". This package offers `hbar` to render the symbol in the familiar form: $hbar$. Contrast: +Matrix transposition can be simply written as `..^T`, just like handwriting, +and the only superscript `T` will be formatted properly to represent +transposition instead of a normal capital letter $T$. -#table( - columns: (auto, auto, auto, auto, auto), - align: horizon, - column-gutter: 1em, - stroke: none, +This $square.stroked.dotted^T => square.stroked.dotted^TT$ +conversion is disabled if the base is either +- a `limits(...)` or `scripts(...)` element, or +- an integration symbol $integral$ or vertical bar $|$, or +- an equation or `lr(...)` element whose last child is one of the above. - [Typst's `planck.reduce`], - [$ E = planck.reduce omega $], - [$ (pi G^2) / (planck.reduce c^4) $], - [$ A e^(frac(i(p x - E t), planck.reduce)) $], - [$ i planck.reduce pdv(,t) psi = -frac(planck.reduce^2, 2m) laplacian psi $], +If you really want to: +- print a transpose explicitly: use symbol `TT`: `A^TT` $=> A^TT$; +- print a superscript letter $T$: use `scripts(T)`: `2^scripts(T)` $=> 2^scripts(T)$. - [this package's `hbar`], - [$ E = hbar omega $], - [$ (pi G^2) / (hbar c^4) $], - [$ A e^(frac(i(p x - E t), hbar)) $], - [$ i hbar pdv(,t) psi = -frac(hbar^2, 2m) laplacian psi $], +This feature needs to be enabled explicitly through a _show rule_. +```typ +#show: super-T-as-transpose +(A B)^T = B^T A^T +``` + +If you only want to enable it within a content block's scope, you may do +```typ +#[ + #show: super-T-as-transpose // Enabled from here till the end of block. + (A B)^T = B^T A^T +] +``` + +#align(center, [*Examples*]) + +#show: super-T-as-transpose // Necessary! + +#grid( + columns: (auto, auto), + row-gutter: 1em, + column-gutter: 2em, + + [ + *(1)* #hl(`(U V_n W')^T = W'^T V_n^T U^T`) \ + $ (U V_n W')^T = W'^T V_n^T U^T $ + ], + [ + *(2)* #hl(`vec(a, b)^T, mat(a, b; c, d)^T`) \ + $ vec(a, b)^T, mat(a, b; c, d)^T $ + ], + [ + *(3)* #hl(`limits(sum)^T, scripts(e)^T`) \ + $ limits(sum)^T, scripts(e)^T $ + ], + [ + *(4)* #hl(`integral_0^T, abs(a)^T, eval(F(t))^T_0`) \ + $ integral_0^T, abs(a)^T, eval(F(t))^T_0 $ + ], ) -=== Matrix transpose +=== Matrix dagger with superscript + -#v(1em) +The conjugate transpose, also known as the Hermitian transpose, transjugate, or +adjoint, of a complex matrix $A$ is performed by first transposing and then +complex-conjugating each matrix element. It is often denoted as $A^*$, +$A^upright(sans(H))$, and sometimes with a dagger symbol: +`A^dagger` $=> A^dagger$. + +Writing `..^dagger` often visually clutters an equation in the source code form. +Therefore, the package offers the ability to write `..^+` instead. -Matrix transposition can be simply written as `..^T`, where the `T` will be -formatted properly to represent transposition instead of a normal letter $T$. -This conversion is disabled if the base is integral symbol. +This $square.stroked.dotted^+ => square.stroked.dotted^dagger$ conversion is +disabled if the base is either +- a `limits(...)` or `scripts(...)` element, or +- an equation or `lr(...)` element whose last child is one of the above. -To enable this feature, users need to first import this and call +This feature needs to be enabled explicitly through a _show rule_. ```typ -#import "...(this physica package)...": super-T-as-transpose -#show: super-T-as-transpose +#show: super-plus-as-dagger +U^+U = U U^+ = I +``` + +If you only want to enable it within a content block's scope (e.g. you want +to have $square.stroked.dotted^+$ for ions or Moore–Penrose inverse outside the +block), you may do +```typ +#[ + #show: super-plus-as-dagger // Enabled from here till the end of block. + U^+U = U U^+ = I +] ``` #align(center, [*Examples*]) -#show: super-T-as-transpose // Necessary! +#show: super-plus-as-dagger // Necessary! #grid( - columns: (50%, 50%), + columns: (auto, auto), row-gutter: 1em, column-gutter: 2em, [ - *(1)* #hl(`(A_n B_n)^T = B_n^T A_n^T`) \ - $ (A_n B_n)^T = B_n^T A_n^T $ + *(1)* #hl(`U^+U = U U^+ = I`) \ + $ U^+U = U U^+ = I $ + ], + [ + *(2)* #hl(`mat(1+i,1;2-i,1)^+ = mat(1-i,2+i;1,1)`) \ + $ mat(1+i,1;2-i,1)^+ = mat(1-i,2+i;1,1) $ + ], + [ + *(3)* #hl(`limits(N)^+, scripts(N)^+`) \ + $ limits(N)^+, scripts(N)^+ $ ], [ - *(2)* #hl(`integral_0^T A^T f(x) dif x`) \ - $ integral_0^T A^T f(x) dif x $ + *(4)* #hl(`#let eq = $scripts(N)$; eq^+`) \ + $ #let eq = $scripts(N)$; eq^+ $ ], ) +== Miscellaneous + +#v(1em) + +=== Reduced Planck constant (hbar) + +#v(1em) + +In the default font, the Typst built-in symbol `planck.reduce` $planck.reduce$ looks a bit off: on letter "h" there is a slash instead of a horizontal bar, contrary to the symbol's colloquial name "h-bar". This package offers `hbar` to render the symbol in the familiar form: $hbar$. Contrast: + +#table( + columns: (auto, auto, auto, auto, auto), + align: horizon, + column-gutter: 1em, + stroke: none, + + [Typst's `planck.reduce`], + [$ E = planck.reduce omega $], + [$ (pi G^2) / (planck.reduce c^4) $], + [$ A e^(frac(i(p x - E t), planck.reduce)) $], + [$ i planck.reduce pdv(,t) psi = -frac(planck.reduce^2, 2m) laplacian psi $], + + [this package's `hbar`], + [$ E = hbar omega $], + [$ (pi G^2) / (hbar c^4) $], + [$ A e^(frac(i(p x - E t), hbar)) $], + [$ i hbar pdv(,t) psi = -frac(hbar^2, 2m) laplacian psi $], +) + === Tensors #v(1em) @@ -1054,6 +1152,8 @@ Function: `BMEsymadd([`...`])`. [$BMEsymadd([2a+1,xi,b+1,a xi + 2b+a,2b+1])$], ) +#pagebreak() + = Acknowledgement #v(1em) @@ -1063,10 +1163,13 @@ Huge thanks to these LATEX packages, for lighting the way of physics typesetting - `derivatives` by Simon Jensen, - `tensor` by Philip G. Ratcliffe et al. -#v(2em) +#pagebreak() -#align(bottom, text(8pt)[ += License -#sym.copyright Copyright 2023 Leedehai. The document is shared under Creative Commons Attribution-NoDerivatives 4.0 license (#linkurl("CC BY-ND 4.0", "https://creativecommons.org/licenses/by-nd/4.0/legalcode")). +Source code: +#sym.copyright Copyright 2023 Leedehai. See the license +#linkurl("here", "https://github.com/Leedehai/typst-physics/blob/master/LICENSE.txt"). -]) +The document: +Creative Commons Attribution-NoDerivatives 4.0 license (#linkurl("CC BY-ND 4.0", "https://creativecommons.org/licenses/by-nd/4.0/legalcode")). diff --git a/physica.typ b/physica.typ index ebc798a..4b78249 100644 --- a/physica.typ +++ b/physica.typ @@ -151,7 +151,11 @@ #let vecrow(..content) = $lr(( #content.pos().join([,]) ))$ -// Prefer using super-T-as-transpose() +// Prefer using super-T-as-transpose() found below. +// +// Note Unicode U+1D40 (#str.from-unicode(7488)) is kinda ugly, and that +// glyph is in the superscript position already so users could not write +// the habitual "A^TT". #let TT = $sans(upright(T))$ #let __vector(a, accent, be_bold) = { @@ -461,7 +465,12 @@ } let dsym = kwargs.at("d", default: $upright(d)$) - let prod = kwargs.at("p", default: none) + let compact = kwargs.at("compact", default: false) + // Why a very thin space is the default joiner: see TeXBook, Chapter 18. + // math.thin (1/6 em, thinspace in typography) is used to separate the + // differential with the preceding function, so to keep visual cohesion, the + // width of this joiner inside the differential shall be smaller. + let prod = kwargs.at("p", default: if compact { none } else { h(0.09em) }) let difference = var_num - orders.len() while difference > 0 { @@ -478,7 +487,8 @@ arr.push($dsym#var$) } } - $#arr.join(prod)$ + // Smart spacing, like Typst's built-in "dif" symbol. See TeXBook, Chapter 18. + $op(#arr.join(prod))$ } #let dd = differential @@ -635,9 +645,29 @@ // Credit: Enivex in https://github.com/typst/typst/issues/355 was very helpful. #let hbar = (sym.wj, move(dy: -0.08em, strike(offset: -0.55em, extent: -0.05em, sym.planck)), sym.wj).join() +// A show rule, should be used like: +// #show: super-T-as-transpose +// (A B)^T = B^T A^T +// or in scope: +// #[ +// #show: super-T-as-transpose +// (A B)^T = B^T A^T +// ] #let super-T-as-transpose(document) = { show math.attach: elem => { - if elem.base != [∫] and elem.at("t", default: none) == [T] { + let __eligible(e) = { + if e.func() == math.limits or e.func() == math.scripts { return false } + if e.func() == math.lr { + let last = e.at("body").at("children").at(-1) + return __eligible(last) + } + if e.func() == math.equation { + return __eligible(e.at("body")) + } + (e != [∫]) and (e != [|]) and (e != sym.bar.v.double) + } + + if __eligible(elem.base) and elem.at("t", default: none) == [T] { $attach(elem.base, t: TT, b: elem.at("b", default: #none))$ } else { elem @@ -647,6 +677,38 @@ document } +// A show rule, should be used like: +// #show: super-plus-as-dagger +// U^+U = U U^+ = I +// or in scope: +// #[ +// #show: super-plus-as-dagger +// U^+U = U U^+ = I +// ] +#let super-plus-as-dagger(document) = { + show math.attach: elem => { + let __eligible(e) = { + if e.func() == math.limits or e.func() == math.scripts { return false } + if e.func() == math.lr { + let last = e.at("body").at("children").at(-1) + return __eligible(last) + } + if e.func() == math.equation { + return __eligible(e.at("body")) + } + true + } + + if __eligible(elem.base) and elem.at("t", default: none) == [+] { + $attach(elem.base, t: dagger, b: elem.at("b", default: #none))$ + } else { + elem + } + } + + document +} + #let tensor(T, ..sink) = { let args = sink.pos() diff --git a/typst.toml b/typst.toml index 45259ff..c666474 100644 --- a/typst.toml +++ b/typst.toml @@ -1,6 +1,6 @@ [package] name = "physica" -version = "0.9.0" +version = "0.9.1" description = "Neat derivative, differential, field, matrix, braket, tensor, hbar, etc." authors = ["Leedehai"] repository = "https://github.com/Leedehai/typst-physics" @@ -8,9 +8,10 @@ keywords = [ "physics", "mathematics", "brace", "set", "product", "evaluate", "restrict", "integral", "gradient", "divergence", "curl", "vector", "field", "laplacian", "matrix", "determinant", "diagonal", "identity", "Jacobian", "Hessian", - "Dirac", "braket", "differential", "derivative", "partial", "dv", "odv", - "pdv", "Planck", "hbar", "tensor", "isotope", "signal", "electromagnetism", - "mechanics", "quantum", "relativity", "imaginary", "notation", + "transpose", "Dirac", "braket", "differential", "derivative", "partial", + "dv", "odv", "pdv", "Planck", "hbar", "tensor", "isotope", "signal", + "electromagnetism", "mechanics", "quantum", "relativity", "imaginary", + "notation", ] compiler = "0.10.0" exclude = ["*.pdf", "*.py"]