Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 符号微分算法_Algorithm_Math - Fatal编程技术网

Algorithm 符号微分算法

Algorithm 符号微分算法,algorithm,math,Algorithm,Math,所以我试图创建一个算法来执行符号微分,以得到给定函数的精确导数。我选择了反向波兰符号来存储表达式,因为它节省了我构建实际表达式树的空间和时间。 我将用一个具体的例子来说明我的问题,我将用手来简化我的算法;因此,如果你期待一个简单的问题或者对答案一无所知,请停止阅读,走开(我不需要在这个问题上盲目地投反对票) 因此,如果我的想法是正确的,我有以下堆栈:[2 | x | 2 | 1 |-| ^ |]用于第一个操作数,而[2]用于第二个操作数。现在我必须执行[2 | x | 2 | 1 |-| ^ |

所以我试图创建一个算法来执行符号微分,以得到给定函数的精确导数。我选择了反向波兰符号来存储表达式,因为它节省了我构建实际表达式树的空间和时间。 我将用一个具体的例子来说明我的问题,我将用手来简化我的算法;因此,如果你期待一个简单的问题或者对答案一无所知,请停止阅读,走开(我不需要在这个问题上盲目地投反对票)

因此,如果我的想法是正确的,我有以下堆栈:[2 | x | 2 | 1 |-| ^ |]用于第一个操作数,而[2]用于第二个操作数。现在我必须执行[2 | x | 2 | 1 |-| ^ |][[2],这要求我递归这个函数。因为现在我还要对[2 | x | 2 | 1 |-| ^ |]进行求导。在本例中,我还必须将每个操作符节点的结果存储在不同的堆栈中,并按正确的顺序合并它们


任何人都可以推荐一种更有效的方法吗?

对于简单多项式,我喜欢找到一个非常短的正则表达式解决方案,但结果比我希望的要长…(JavaScript示例):

输出:

"3*x^2 + 4*x + 1"
"12"
"0"

好问题。事实上,这里有一个向上的投票:)让我们看看我是否正确理解你-你是在问波兰语符号(堆栈)形式是否可以用于应用符号微分,或者在这样做之前应该将其转换为其他表示形式?有趣:)好吧,假设你想做(ab)'=a'*b+ab',这是RPN中的ab*。那么,如果我错了,请纠正我,你必须,没有特定的顺序:
pop*pop a将导数应用于a,将结果存储在“pop b将导数应用于b,将结果存储在b”push+push*push a“push b push*push a push b”
可以更有效地完成吗?不确定。在这种情况下,RPN值得吗,还是应该只使用表达式树?好问题。但是,如果表达式中的所有(或几乎所有)操作都是+和-,则不需要执行所有的推送和弹出操作。有趣的部分是如何存储初始结果,因为正如您在示例中看到的,它们必须是可恢复的,但也可以访问。对于[*]运算符,我必须使用[^]运算符的结果。这使我认识到,将结果直接存储在输出流中不是一个好主意。否则,我将如何为[^]的结果重复调用函数?但是,再一次,我需要找到一种方法来有效地访问那些我真正需要的。这不就是多项式的微分吗?这是一个非常简单的处理方法吗?是的,这个例子。加上这些要实现的功能:sin、cos、tan、ctg、ln、exp、sqrt
function dx(dt){
  dt = dt.replace(/\s+/g,"");

  var signs = dt.match(/[+-]/g) ? dt.match(/[+-]/g) : [],
      dts = dt.split(/[+-]/).map(function(x){
        return x.replace(/([0-9]+)?(\*)?([a-zA-Z])?(\^)?([0-9]+)?/,
          function(z,a,b,c,d,e){
            if (!c){
              return "0";
            }
            a = a ? Number(a) : 1;
            if (!e){
              return "" + a;
            }
            e = Number(e);
            return "" + (e*a) + "*" + c 
                      + (e - 1 > 1 ? d + (e - 1) : "");
        });
      });

    return dts.map(function(v,i){ 
             return v + (signs[i] ? " " + signs[i] : "");
           }).join(" ").replace(/\s\+\s0|0\s\+\s/g,"");
}

console.log(dx("x^3+2*x^2+x"));
console.log(dx("12x"));
console.log(dx("6"));
"3*x^2 + 4*x + 1"
"12"
"0"