【问题标题】:Ryacas substitute but don't simplify or evaluateRyacas 替代但不简化或评估
【发布时间】:2022-01-14 09:09:49
【问题描述】:

我在 R 中使用 Ryacas 包,并试图用变量代替值,但不简化或求解方程以显示结果。我搜索了 Stackoverflow,阅读了 Ryacas 文档,并试图在 Yacas 手册中找到它,但到目前为止还不够。我想我希望关闭简化以获得替代方程,然后再次打开以提供最终结果。

这是一个仅提供结果而不提供工作的示例:

library(Ryacas)
# a <- 2
# b <- 3
# c <- 4
eq <- ysym(('(a * b) / c'))

solution <- with_value(with_value(with_value(eq, 'a', 2), 'b', 3), 'c', 4)
tex(solution)
# "\\frac{3}{2}"

我想要得到的输出是:

# working out
# "\\frac{2 \times 3}{4}

以及实际的解决方案:

# solution
# "\\frac{3}{2}"

有谁知道是否有解决此问题的方法,例如通过yac_str 或类似方法将命令传递给 yacas。我尝试使用tex() 命令翻译成乳胶,然后在删除乘法运算符后进行替换,这意味着我需要找到并替换它们,这在处理符号时变得很讨厌:

tex(eq)
# "\\frac{a b}{c}"

# substituting string values using stringi requires additional  
# work to deal with the missing `*` between `a` and `b`
# "\\frac{2 3}{4}"

虽然这可以用于简单的表达式,但有许多例外情况,例如 \\frac 中存在变量 a 和 c 等。

我也尝试过各种形式的TexForm 命令和substitute,但仍然无法捕捉到未简化和未计算的方程:

y_fn(substitute(with_value(eq, 'a', 2)), "TeXForm")
# "\\frac{2 b}{c}"

eval(substitute(with_value(eval(substitute(with_value(eq, 'a', 2))), 'b', 3)))
# y: 6/c

任何帮助表示赞赏。

【问题讨论】:

    标签: r eval substitution yacas


    【解决方案1】:

    您可能需要对此进行更多自定义,但如果您愿意,这种通用方法也可以使用。

    我们使用 gsubfn 将单词翻译成它们的值,并使用 gsub 处理末尾的 \times 部分。请注意, frac 没有被修改,因为我们正在匹配单词并且 frac 它不是 gsubfn 的第二个 arg 中给出的列表中的单词。

    library(magrittr)
    library(gsubfn)
    library(Ryacas)
    
    eq <- ysym(('(a * b) / c'))
    
    eq %>%
      tex %>%
      gsubfn("(\\w+)", list(a = 2, b = 3, c = 4), .) %>%
      gsub("(\\d) (\\d)", "\\1 \\\\times \\2", .)
    ## [1] "\\frac{2 \\times 3}{4}"
    

    添加

    在 stackoverflow 中搜索 [r] Ryacas 时,以前三个代码示例为例,它对所有这些示例都有效。请注意,这些使用的是 Ryacas 的原始版本,目前称为 Ryacas0,所以我使用了它。

    library(Ryacas0)
    library(gsubfn)
    library(magrittr)
    
    tex_sub <- function(.x, ...) {
      .x %>%
        gsubfn("(\\w+)", list(...), .) %>%
        gsub("(\\d) (\\d)", "\\1 \\\\times \\2", .)
    }
    
    # https://stackoverflow.com/questions/21858668/symbolic-matrix-multiplication-by-ryacas
    x <- Sym("x")
    mat1 <- List(
      List(x, 2),
      List(x^3, x))
    
    mat2 <- List(
      List(x, x),
      List(3, 6 * x))
    
    tt <- TeXForm(mat1 * mat2)
    tex_sub(tt, x = 1)
    
    ###
    
    # https://stackoverflow.com/questions/22739173/matrix-transpose-in-ryacas
    u=Sym("u")
    v=Sym("v")
    w=Sym("w")
    DG=List(List(w-v), List(u-w), List(v-u))
    tt2 <- TeXForm(DG)
    tex_sub(tt2, u = 2, v = 3, w = 4)
    
    ###
    
    # https://stackoverflow.com/questions/49572184/how-to-derivate-using-ryacas
    
    x <- Sym("x")
    P <- Sym(1)
    for (k in 1:3) {
      P <- Simplify((1+k*x)*P + x*(1-x)*deriv(P, x))
      print(P)
    }
    tt3 <- TeXForm(P)
    tex_sub(tt3, x = 10)
    

    【讨论】:

    • 真的不可能暂停ryacas、@G.Grothendieck 中表达式的求值吗?那将是一种更通用的方法。
    • 如果不可能,也许可以通过reticulate(甚至R::caracas)使用sympy(Python)。函数sympy::sympify 有一个标志evaluate=False。
    • @G。 Grothendieck,感谢您提供的代码确实回答了所提出的具体问题。正如@Paul Smith 所提到的,这不是一种适用于更复杂方程的通用方法。我想我需要检查caracas 包
    • 我认为你低估了一般性。我从 stackoverflow 中获取了前三个代码示例(请参阅添加的部分),其中包括相当复杂的公式,并且它适用于所有这些。此外,我认为您高估了您所建议的方法的普遍性,因为例如,您希望 \times 在替代版本中而不是在非替代版本中,因此它并不是那么普遍。
    • @G。格洛腾迪克,感谢您的附加帖子。我相信您的解决方案完全解决了我一开始没有完全理解的问题
    猜你喜欢
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    相关资源
    最近更新 更多