Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // Derivative of expresssions
- //
- let cases2=[
- [1],
- [X],
- [mul,X,3],
- [add,X,3],
- [power,X,3],
- [add, [power,X,3], [add, [power,X,2], X]],
- [add, 2, 3],
- [mul, 2, 3],
- [power, 2, 3],
- [add, [add, -3,5], 3],
- [power, 2,
- [mul, 1,
- [add,1,2]]]
- ];
- for(let i=0;i<cases2.length;i++){
- let F=cases2[i];
- console.log("-".repeat(30));
- console.log("For expression " + print(F) + ":");
- console.log("Value is " + print(evaluate(F)));
- console.log("Derivative is " + print(derivative(F)));
- }
- /////////////////////////////////////////
- function derivative(F) {
- let result = "?";
- // It is useful to simplify expressions to numbers now,
- // because for example derivation of power doesn't test if base has variable; so (2 ^ 3)' would be != 0, which is wrong.
- if(is_variable(evaluate(F))) {
- result = 1;
- } else if(is_number(evaluate(F))) {
- result = 0;
- } else if(is_array(F)) {
- // func call [F F F] [F X Y] or boxed value?
- if(is_function(F[0])) {
- if(F[0]==mul){
- result = add([
- mul([evaluate(F[1]),derivative(F[2])]),
- mul([evaluate(F[2]),derivative(F[1])]),
- ]);
- //F[1]*derivative(F[2])+ derivative(F[1])*F[2]
- }else if(F[0]==add){
- result = add([
- derivative(F[1]),
- derivative(F[2]),
- ]);
- }else if(F[0]==power){
- result= mul([
- evaluate(F[2]),
- power([
- evaluate(F[1]),
- add([evaluate(F[2]),-1])
- ])
- ]);
- }
- } else {
- return derivative(F[0]);
- }
- } else {
- debugger;
- result = "@"; // error!
- }
- return result;
- }
- // assumption: args are evaluated to numbers
- function assert(cond) {
- if(!cond) {
- debugger;
- }
- }
- function evaluate(F) {
- let result;
- if(is_variable(F)) {
- result = F;
- } else if(is_number(F)) {
- result = F;
- } else if(is_function(F)) {
- result = F;
- } else if(is_array(F)){ // func call [F] [F x] [F x y] ... [F F F ...]
- let f=evaluate(F[0]);
- if(is_function(f)){
- let args = [];
- for(let i=1;i<F.length;i++){
- let arg = evaluate(F[i]);
- args.push(arg);
- }
- result = f(args);
- } else {
- result = f;
- }
- }
- return result;
- }
- function add(args) {
- assert(is_array(args) && args.length==2);
- // numeric
- if(is_number(args[0])&&is_number(args[1])){
- return args[0]+args[1];
- }
- // symbolic
- let x = evaluate(args[0]);
- let y = evaluate(args[1]);
- // simplify
- if(x===0&&y==0){
- return 0;
- }
- else if(x===0){
- return y;
- }
- else if(y===0){
- return x;
- }
- return [add,x,y];
- }
- function mul(args) {
- assert(is_array(args) && args.length==2);
- // numeric
- if(is_number(args[0])&&is_number(args[1])){
- return args[0]*args[1];
- }
- // symbolic
- let x = evaluate(args[0]);
- let y = evaluate(args[1]);
- // simplify
- if(x===1&&y==1){
- return 1;
- }
- else if(x===1){
- return y;
- }
- else if(y===1){
- return x;
- }
- //
- if(x===0||y==0){
- return 0;
- }
- return [mul,x,y];
- }
- function power(args) {
- assert(is_array(args) && args.length==2);
- if(is_number(args[0])&&is_number(args[1])) {
- return Math.pow(args[0],args[1]);
- }
- // symbolic
- let x = evaluate(args[0]);
- let y = evaluate(args[1]);
- // simplify
- if(y==1){
- return x;
- }
- if(y===0){
- return 1;
- }
- return [power,x,y];
- }
- function is_number(x){ return Number.isInteger(x)||Number.isFinite(x);}
- function is_array(x){ return Array.isArray(x);}
- function is_function(x) { return typeof x === "function" && !is_variable(x);}
- // symbol
- function X() {return "x"}
- function Y() {return "y"}
- function Z() {return "z"}
- function is_variable(v) { return v===X || v===Y || v===Z; }
- ///////////////////////////////////////////////////////////////////////////////////
- // -> string
- function print(F,level=0) {
- let result;
- if(is_variable(F)) {
- result = F();
- } else if(is_function(F)) {
- result=F.name;
- } else if(is_number(F)) { // [666]
- result = String(F);
- } else if(is_array(F)) {
- // [F F F]
- let f = print(F[0],level+1);
- let arity=0;
- let x="";
- let y="";
- if(F[1] !== undefined){
- x = print(F[1],level+1);
- arity++;
- }
- if(F[2] !== undefined){
- y = print(F[2],level+1);
- arity++;
- }
- let inline={
- "mul": "*",
- "power": "^",
- "add": "+"
- };
- if(inline[f]) {
- result = `(${x} ${inline[f]} ${y})`;
- } else {
- if(arity==0){
- if(is_function(F[0])) {
- result = `(${f}())`;
- } else {
- result = `(${f})`;
- }
- }else if(arity==1){
- result = `(${f}(${x}))`;
- }else { //2
- result = `(${f}(${x},${y}))`;
- }
- }
- } else {
- result = "???";
- }
- assert(typeof result == "string");
- return result;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement