Maxima:创建作用于字符串部分的函数

Maxima: creating a function that acts on parts of a string

上下文: 我在一个也使用 KaTeX 的平台上使用 Maxima。由于与内容管理相关的各种原因,这意味着我们经常使用 Maxima 函数来生成必要的 KaTeX 命令。

我目前正在尝试开发一组函数,这些函数将有助于为与矢量相关的各种符号生成与 KaTeX 命令相对应的不同字符串集。


问题

我写了下面的函数makeKatexVector(x),它接受一个字符串、列表或列表列表和returns相同类型的对象,每个字符串都包含在[=13中=](即 makeKatexVector(string) returns \vec{string}makeKatexVector(["a","b"]) returns ["\vec{a}", "\vec{b}"] etc).

/* Flexible Make KaTeX Vector Version of List Items */
makeKatexVector(x):= block([ placeHolderList : x ],
            if stringp(x)   /* Special Handling if x is Just a String */
            then placeHolderList : concat("\vec{", x, "}")
            else        if listp(x[1])   /* check to see if it is a list of lists */
                    then        for j:1 thru length(x) 
                            do placeHolderList[j] : makelist(concat("\vec{", k ,"}"), k, x[j] ) 
                        else        if  listp(x)   /* check to see if it is just a list */
                            then  placeHolderList    : makelist(concat("\vec{", k, "}"), k, x) 
                            else    placeHolderList : "makeKatexVector error: not a list-of-lists, a list or a string", 
        return(placeHolderList));

虽然我对上面代码的效率或优雅有疑问,但它似乎 return 了我想要的表达方式;但是,我想修改这个函数,让它可以区分单字符串和多字符串。

特别是,我希望像 x_1 这样的多字符字符串被 return 编辑为 \vec{x}_1 而不是 \vec{x_1}.

事实上,我只想修改上面的代码,使 \vec{} 环绕在字符串的第一个字符周围,而不管可能有多少个字符。


我的尝试

我准备用蛮力解决这个问题(例如将字符串的每个字符转录到列表中,然后重新组合);然而,该项目的 real 程序员建议我查看“正则表达式”。在探索了那个无尽的兔子洞之后,我找到了命令 regex_subst;但是,我找不到它的任何 Maxima 文档,并且正在努力重现相关文档中的示例 here

一旦我可以计算出合适的正则表达式来使用,我打算在上面的代码中使用 if 语句来实现它,例如:

if slength(x) >1 
then {regex command}
else {regular treatment}

如果有人知道任何这些方面的有用资源,我将不胜感激。

虽然我没想到我会自己解决这个问题,但几个小时后,我取得了一些进展,所以我想我会在这里分享,以防其他人可以从我投入的时间中受益英寸

  1. 要在 wxMaxima 中加载正则表达式,至少在 MacOS 版本上,只需键入 load("sregex");。我没有加载这个,并试图通过我们的自定义平台工作,这花了我几个小时。

  2. 请注意,Dorai Sitaram linked documentation 中的许多论点都是相反的,或者与相应的 Maxima 版本中的顺序不同。

  3. 并非所有“pregexp”函数都存在于 Maxima 中;

除此之外,转义特殊字符在 wxMaxima、内联 Maxima 编译器(运行 在 Ace 编辑器中)和我们平台上的实际渲染版本之间存在重要差异;特别是,内联编译器经常 returned false 用于在 wxMaxima 和平台上正确编译的表达式。因为我从一开始就没有sregex加载到wxMaxima上,所以我为此浪费了很多时间。

最后,在我的例子中,实现所需替换的正则表达式是:

regex_subst("\vec{\1}", "([[:alpha:]])", "v_1");

which returns vec{v}_1 in wxMaxima (N.B. none 我试图让 wxMaxima 达到 return \vec{v}_1 成功;转义反斜杠似乎不起作用;幸运的是,通常的转义版本 \vec{\1} 可以 return 所需的形式)。

我还没有为函数的其余部分调整代码,但我怀疑这对其他人有用,并且想确保 post 在其他人使用之前更新这里是时候帮助我了。

总是对更好的方法/实践或任何其他指示/反馈感兴趣。

看起来你的正则表达式方法起作用了,太棒了。然而,我关于在 TeX 中处理下标表达式的建议是避免在 Maxima 中使用包含下划线的名称,而是使用带有索引的 Maxima 表达式,例如foo[k] 而不是 foo_k。虽然在 Maxima 中写 foo_k 是一个小小的便利,但您很快就会 运行 遇到问题,为了理顺它,您最终可能会把一个复杂的问题叠加到另一个问题上。

例如Maxima 不知道 foofoo_1foo_k 之间有任何关系——它们的共同点不比 fooabcxyz。如果有 2 个索引怎么办? foo_j_k 将通过前面的方法变成类似 foo_{j_k} 的东西——如果您想要 foo_{j, k} 怎么办? (顺便说一句,当用下标表示时,这两个是 foo[j[k]]foo[j, k]。)另一个有问题的表达式是 foo_bar_baz。这是否意味着 foo_bar[baz]foo[bar_baz]foo_bar_baz

在 TeX 中 tex(x_y) 产生 x_y 的代码很旧,所以它不太可能消失,但多年来我越来越觉得应该避免它。然而,上次它出现时我提议禁用它,有足够多的人支持它,我们最终保留了它。

可能会有帮助,有一个函数 texput 允许您指定符号在 TeX 输出中的显示方式。例如:

(%i1) texput (v, "\vec{v}");
(%o1)                       "\vec{v}"
(%i2) tex ([v, v[1], v[k], v[j[k]], v[j, k]]);
$$\left[ \vec{v} , \vec{v}_{1} , \vec{v}_{k} , \vec{v}_{j_{k}} , 
 \vec{v}_{j,k} \right] $$
(%o2)                         false

texput 可以修改 TeX 输出的各个方面;您可以查看文档(参见 ? texput)。