【问题标题】:solving an exponential equation in Raku在 Raku 中求解指数方程
【发布时间】:2020-04-05 21:34:03
【问题描述】:

我正在尝试像这样求解这个指数方程:

my ($l,$r);

for (1 .. 100) -> $x {
    $l = $x * e ** $x;
    $r = 5 * (e ** $x - 1);
    say $x if $l == $r;
    }

但它不起作用。如何以一种简单而全面的方式解决它?

【问题讨论】:

  • 对这个方程求微分,然后求解二次方程。我不确定 Raku 是否可以直接帮助您。你希望 Raku 分析这个代数表达式还是给你一个数值解?您是在寻找现有的库还是想自己编程?只针对这个特定的方程式?
  • 试试Math::Symbolic。看起来 .new.isolate 可能会成功。
  • @Sebastian 我想知道是否有一个简洁明了的解决方案。
  • 我认为目前 Raku 中的任何指数方程都没有通用解。 Math::Symbolic 具有标记为 NYI 的对数(尚未实现)。如果您要求的不仅仅是兴趣,还需要解决这个或一组类似方程,一个人可以手动完成第一步,让 Raku 完成其余的,这是可能的。然后你应该说明,什么可以改变,例如哪些系数是可变的。如果您只需要求解这个特定方程,那么您也可以在 Raku 之外进行(例如 Wolfram Alpha)。
  • 您寻求代数解还是数值解?

标签: equation raku solver equation-solving


【解决方案1】:

抱歉重复回答。
但这是在 Raku 中解决的完全不同的更简单的方法。
(它可能可以表述得更优雅。)

#!/usr/bin/env raku

sub solver ($equ, $acc, $lower0, $upper0) {
    my Real $lower = $lower0;
    my Real $upper = $upper0;
    my Real $middle = ($lower + $upper) / 2;

    # zero must be in between
    sign($equ($lower)) != sign($equ($upper)) || die 'Bad interval!';

    for ^$acc {                                          # accuracy steps
        if sign($equ($lower)) != sign($equ($middle))
            { $upper = $middle }
        else
            { $lower = $middle }
        $middle = ($upper + $lower) / 2;
    }
    return $middle;
}

my $equ = -> $x { $x * e ** $x  -  5 * (e ** $x - 1) };  # left side - right side
my $acc = 64;                                            # 64 bit accuracy
my Real $lower = 1;                                      # start search here
my Real $upper = 100;                                    # end search here

my $solution = solver $equ, $acc, $lower, $upper;

say 'result is ', $solution;
say 'Inserted in equation calculates to ', $equ($solution), ' (hopefully nearly zero)'

【讨论】:

    【解决方案2】:

    对于 Perl 5,有 Math::GSL::Roots - 查找任意一维函数的根

    https://metacpan.org/pod/Math::GSL::Roots

    Raku 支持使用 Perl 5 代码或者可以直接访问 GSL C 库,不是吗?

    $fspec = sub {
           my ( $x ) = shift;
    
           # here the function has to be inserted in the format 
           # return leftside - rightside;
    
           return  ($x + $x**2) - 4;
    
    
         };
    
    gsl_root_fsolver_alloc($T); # where T is the solver algorithm, see link for the 6 type constants, e.g. $$gsl_root_fsolver_brent
    gsl_root_fsolver_set( $s, $fspec, $x_lower, $x_upper ); # [$x_lower; $x_upper] is search interval
    gsl_root_fsolver_iterate($s);
    gsl_root_fsolver_iterate($s);
    gsl_root_fsolver_iterate($s);
    gsl_root_fsolver_iterate($s);
    gsl_root_fsolver_iterate($s);
    my $result = gsl_root_fsolver_root($s);
    gsl_root_fsolver_free (s);
    

    如果函数的导数可用,则可以使用增强算法 (gsl_root_fdfsolver_*)。

    有关一般用法,另请参阅https://www.gnu.org/software/gsl/doc/html/roots.html#examples

    【讨论】:

      猜你喜欢
      • 2017-08-23
      • 2022-07-06
      • 1970-01-01
      • 1970-01-01
      • 2016-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多