Advertisement
nullpainter

Derivative of expression

Apr 17th, 2024 (edited)
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. // Derivative of expresssions
  3. //
  4.  
  5. let cases2=[
  6.     [1],
  7.     [X],
  8.     [mul,X,3],
  9.     [add,X,3],
  10.     [power,X,3],
  11.     [add, [power,X,3], [add, [power,X,2], X]],
  12.     [add, 2, 3],
  13.     [mul, 2, 3],
  14.     [power, 2, 3],
  15.     [add, [add, -3,5], 3],
  16.     [power, 2,
  17.             [mul, 1,  
  18.                 [add,1,2]]]
  19. ];
  20. for(let i=0;i<cases2.length;i++){
  21.     let F=cases2[i];
  22.     console.log("-".repeat(30));
  23.     console.log("For expression " + print(F) + ":");
  24.     console.log("Value is       " + print(evaluate(F)));
  25.     console.log("Derivative is  " + print(derivative(F)));
  26. }
  27.  
  28. /////////////////////////////////////////
  29.  
  30. function derivative(F) {    
  31.     let result = "?";
  32.  
  33.     // It is useful to simplify expressions to numbers now,
  34.     // because for example derivation of power doesn't test if base has variable; so (2 ^ 3)' would be != 0, which is wrong.
  35.     if(is_variable(evaluate(F))) {
  36.         result = 1;
  37.     } else if(is_number(evaluate(F))) {
  38.         result = 0;
  39.     } else if(is_array(F)) {
  40.         // func call [F F F] [F X Y] or boxed value?
  41.         if(is_function(F[0])) {
  42.             if(F[0]==mul){
  43.                 result = add([
  44.                     mul([evaluate(F[1]),derivative(F[2])]),
  45.                     mul([evaluate(F[2]),derivative(F[1])]),
  46.                 ]);
  47.                
  48.                 //F[1]*derivative(F[2])+ derivative(F[1])*F[2]                
  49.             }else if(F[0]==add){
  50.                 result = add([
  51.                     derivative(F[1]),
  52.                     derivative(F[2]),
  53.                 ]);                
  54.             }else if(F[0]==power){
  55.                 result= mul([
  56.                     evaluate(F[2]),
  57.                         power([
  58.                             evaluate(F[1]),
  59.                             add([evaluate(F[2]),-1])
  60.                         ])
  61.                 ]);
  62.             }
  63.         } else {
  64.            return derivative(F[0]);
  65.         }    
  66.     } else {
  67.         debugger;
  68.         result = "@"; // error!
  69.     }
  70.     return result;
  71. }
  72.  
  73.  
  74. // assumption: args are evaluated to numbers
  75. function assert(cond) {
  76.     if(!cond) {
  77.         debugger;
  78.     }
  79. }
  80.  
  81. function evaluate(F) {
  82.     let result;
  83.     if(is_variable(F)) {
  84.         result = F;
  85.     } else if(is_number(F)) {
  86.         result = F;
  87.     } else if(is_function(F)) {
  88.         result = F;
  89.     } else if(is_array(F)){ // func call [F] [F x] [F x y] ... [F F F ...]
  90.         let f=evaluate(F[0]);
  91.         if(is_function(f)){
  92.             let args = [];
  93.             for(let i=1;i<F.length;i++){
  94.                 let arg = evaluate(F[i]);
  95.                 args.push(arg);
  96.             }
  97.             result = f(args);
  98.         } else {
  99.             result = f;
  100.         }
  101.     }
  102.     return result;
  103. }
  104.  
  105. function add(args) {
  106.     assert(is_array(args) && args.length==2);
  107.  
  108.     // numeric
  109.     if(is_number(args[0])&&is_number(args[1])){
  110.         return args[0]+args[1];    
  111.     }
  112.  
  113.     // symbolic
  114.     let x = evaluate(args[0]);
  115.     let y = evaluate(args[1]);
  116.  
  117.     // simplify
  118.     if(x===0&&y==0){
  119.         return 0;
  120.     }
  121.     else if(x===0){
  122.         return y;
  123.     }
  124.     else if(y===0){
  125.         return x;
  126.     }
  127.    
  128.     return [add,x,y];
  129. }
  130.  
  131. function mul(args) {
  132.     assert(is_array(args) && args.length==2);
  133.  
  134.     // numeric
  135.     if(is_number(args[0])&&is_number(args[1])){
  136.         return args[0]*args[1];    
  137.     }
  138.    
  139.     // symbolic
  140.     let x = evaluate(args[0]);
  141.     let y = evaluate(args[1]);
  142.  
  143.     // simplify
  144.     if(x===1&&y==1){
  145.         return 1;
  146.     }
  147.     else if(x===1){
  148.         return y;
  149.     }
  150.     else if(y===1){
  151.         return x;
  152.     }
  153.     //
  154.     if(x===0||y==0){
  155.         return 0;
  156.     }
  157.  
  158.     return [mul,x,y];
  159. }
  160.  
  161. function power(args) {
  162.     assert(is_array(args) && args.length==2);
  163.     if(is_number(args[0])&&is_number(args[1])) {
  164.         return Math.pow(args[0],args[1]);
  165.     }
  166.    
  167.     // symbolic
  168.     let x = evaluate(args[0]);
  169.     let y = evaluate(args[1]);
  170.  
  171.     // simplify
  172.     if(y==1){
  173.         return x;
  174.     }
  175.     if(y===0){
  176.         return 1;
  177.     }
  178.  
  179.     return [power,x,y];
  180. }
  181.  
  182. function is_number(x){ return Number.isInteger(x)||Number.isFinite(x);}
  183. function is_array(x){ return Array.isArray(x);}
  184. function is_function(x) { return typeof x === "function" && !is_variable(x);}
  185.  
  186. // symbol
  187. function X() {return "x"}
  188. function Y() {return "y"}
  189. function Z() {return "z"}
  190. function is_variable(v) { return v===X || v===Y || v===Z; }
  191.  
  192. ///////////////////////////////////////////////////////////////////////////////////
  193.  
  194. // -> string
  195. function print(F,level=0) {
  196.     let result;
  197.     if(is_variable(F)) {
  198.         result = F();
  199.     } else if(is_function(F)) {
  200.         result=F.name;
  201.     } else if(is_number(F)) { // [666]
  202.         result = String(F);
  203.     } else if(is_array(F)) {
  204.         // [F F F]
  205.         let f = print(F[0],level+1);
  206.  
  207.         let arity=0;
  208.         let x="";
  209.         let y="";
  210.         if(F[1] !== undefined){
  211.             x = print(F[1],level+1);
  212.             arity++;
  213.         }
  214.         if(F[2] !== undefined){
  215.             y = print(F[2],level+1);
  216.             arity++;
  217.         }
  218.  
  219.         let inline={
  220.             "mul": "*",
  221.             "power": "^",
  222.             "add": "+"
  223.         };
  224.        
  225.         if(inline[f]) {
  226.             result = `(${x} ${inline[f]} ${y})`;
  227.         } else {
  228.             if(arity==0){
  229.                 if(is_function(F[0])) {            
  230.                     result = `(${f}())`;
  231.                 } else {
  232.                     result = `(${f})`;
  233.                 }
  234.             }else if(arity==1){
  235.                 result = `(${f}(${x}))`;
  236.             }else { //2
  237.                  result = `(${f}(${x},${y}))`;
  238.             }      
  239.         }
  240.     } else {
  241.         result = "???";
  242.     }
  243.  
  244.     assert(typeof result == "string");
  245.     return result;
  246. }
  247.  
  248.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement