/// <summary> /// Produces a Lagrange Item, which looks like this: (x-Xj)/(Xterm - Xj), where term != j /// Example: ((x-X1)(x-X2)...(x-Xn)) / ((Xterm - x1)(Xterm - x2)...(Xterm - Xn)) /// /// </summary> /// <param name="points">Given set of points</param> /// <param name="term">For which term you want to create a so-called Lagrange item</param> /// <returns>Lagrange item of the type MultiplicationNode</returns> public static MultiplicationNode ProduceLagrange(DataPoint[] points, int term) { MultiplicationNode item = new MultiplicationNode(null, null, null); item.left = new NumberNode(null, 1); for (int i = 0; i < points.Length; i++) { if (i == term) { continue; } SubstractionNode enumerator = new SubstractionNode( new BasicFunctionXNode(""), // left new NumberNode(null, points[i].X), // right null // parent ); NumberNode denominator = new NumberNode(null, points[term].X - points[i].X); DivisionNode division = new DivisionNode(enumerator, denominator, null); item.LagrangePutToRightNode(division); } return(item); }
public override void CreateDerivativeTree(BaseNode parent, bool isLeft = true) { NumberNode node = new NumberNode(parent, 1); if (parent != null) { if (isLeft) { parent.left = node; } else { parent.right = node; } } //Plotter.SetDerivativeRoot (node); SetDerivativeRoot(node); return; }
/// <summary> /// Clones a specified tree based on a given node 'root' /// </summary> /// <param name="root"></param> /// <returns></returns> public static BaseNode CloneTree(BaseNode root) { if (root == null) { return(null); } BaseNode newNode = null; if (root is SubstractionNode) { newNode = new SubstractionNode(root.value); } else if (root is MultiplicationNode) { newNode = new MultiplicationNode(root.value); } else if (root is SumNode) { newNode = new SumNode(root.value); } else if (root is DivisionNode) { newNode = new DivisionNode(root.value); } else if (root is NumberNode) { newNode = new NumberNode(null, (root as NumberNode).RealValue); } else if (root is BasicFunctionXNode) { newNode = new BasicFunctionXNode(root.value); } else if (root is SinNode) { newNode = new SinNode(root.value); } else if (root is CosNode) { newNode = new CosNode(root.value); } else if (root is PowerNode) { newNode = new PowerNode(root.value); } else if (root is ExponentNode) { newNode = new ExponentNode(root.value); } else if (root is LnNode) { newNode = new LnNode(root.value); } else if (root is FactorialNode) { newNode = new FactorialNode(root.value); } newNode.left = CloneTree(root.left); newNode.right = CloneTree(root.right); return(newNode); }
/// <summary> /// Creates tree based on an input string and root node /// </summary> /// <param name="s"></param> /// <param name="baseNode"></param> public void CreateTree(string s, BaseNode baseNode) { // if the string is empty, we don't do anything. This is the base case to leave the recursion if (s == string.Empty) { return; } // if it's 's', or '+', or whatever, we create a dedicated class (watch first case to see the logic) if (s[0] == 's') { SinNode node = new SinNode(s, baseNode); // dedicated class baseNode.Insert(node); // we insert it to the current head node CreateTree(node.value, node); // we change the head node to the newly created one } else if (s[0] == 'c') { CosNode node = new CosNode(s, baseNode); baseNode.Insert(node); CreateTree(node.value, node); } else if (s[0] == '*') { // same as in the first 'if' MultiplicationNode node = new MultiplicationNode(s, baseNode); baseNode.Insert(node); CreateTree(node.value, node); } else if (s[0] == '+') { // same as in the first 'if' SumNode node = new SumNode(s, baseNode); baseNode.Insert(node); CreateTree(node.value, node); } else if (s[0] == '/') { DivisionNode node = new DivisionNode(s, baseNode); baseNode.Insert(node); CreateTree(node.value, node); } else if (s[0] == '-' && !(s[1] >= '0' && s[1] <= '9')) { SubstractionNode node = new SubstractionNode(s, baseNode); baseNode.Insert(node); CreateTree(node.value, node); } else if (s[0] == 'l') { LnNode node = new LnNode(s, baseNode); baseNode.Insert(node); CreateTree(node.value, node); } else if (s[0] == '^') { PowerNode node = new PowerNode(s, baseNode); baseNode.Insert(node); CreateTree(node.value, node); } else if (s[0] == 'e') { ExponentNode node = new ExponentNode(s, baseNode); baseNode.Insert(node); CreateTree(node.value, node); } else if (s[0] == '!') { FactorialNode node = new FactorialNode(s, baseNode); baseNode.Insert(node); CreateTree(node.value, node); } else if (s[0] == 'p' || (s[0] >= '0' && s[0] <= '9')) { // stuff below just parses number string toParseIntoNumber = string.Empty; int counter = 0; if (s[0] == 'p') { toParseIntoNumber = "p"; } else { while ((s[counter] >= '0' && s[counter] <= '9') || s[counter] == '.') { toParseIntoNumber += s[counter]; counter++; } } if (toParseIntoNumber.Contains('.')) { toParseIntoNumber = toParseIntoNumber.Replace('.', ','); } string @newS = string.Empty; for (int i = (s[0] == 'p' ? 1 : counter); i < s.Length; i++) { newS += s[i]; } // same stuff as in the first 'if' NumberNode node = new NumberNode(newS, baseNode, toParseIntoNumber); baseNode.Insert(node); CreateTree(node.value, node); } else if (s[0] == '-' && (s[1] >= '0' && s[1] <= '9')) { // negative number s = Plotter.GetStringFromIndex(s, 1); string toParseIntoNumber = string.Empty; int counter = 0; if (s[0] == 'p') { toParseIntoNumber = "p"; } else { do { toParseIntoNumber += s[counter]; counter++; } while (counter < s.Length && ((s[counter] >= '0' && s[counter] <= '9') || s[counter] == '.')); } if (toParseIntoNumber.Contains('.')) { toParseIntoNumber = toParseIntoNumber.Replace('.', ','); } string @newS = string.Empty; for (int i = (s[0] == 'p' ? 1 : counter); i < s.Length; i++) { newS += s[i]; } NumberNode node = new NumberNode(newS, baseNode, "-" + toParseIntoNumber); baseNode.Insert(node); CreateTree(node.value, node); } else if (s[0] == 'x') { // same as in the first 'if' BasicFunctionXNode node = new BasicFunctionXNode(s, baseNode); baseNode.Insert(node); CreateTree(node.value, node); } else if (s[0] == '(' || s[0] == ' ') { s = GetStringFromIndex(s, 1); // practically delete that ( or ' ' CreateTree(s, baseNode); } else if (s[0] == ')') { // count how many times ')' appears, let this number be 'i', then our head node is gonna go 'i' levels up int i = 0; while (s[i] == ')' && (s[i] != ',' || s[i] != ' ')) { i++; if (i == s.Length) { break; } } for (int j = 0; j < i; j++) { if (baseNode.parent != null) { baseNode = baseNode.parent; } else { throw new Exception("Eror in your input"); } } s = GetStringFromIndex(s, i); CreateTree(s, baseNode); } else if (s[0] == ',') { if (baseNode.parent == null) { throw new Exception("Error in your input"); } // go one level up baseNode = baseNode.parent; s = GetStringFromIndex(s, 1); CreateTree(s, baseNode); } }
public override BaseNode Simplify() { if (!(left is NumberNode || right is NumberNode)) // if neither left nor right guy is a number { this.left = this.left.Simplify(); // tell the left guy to get simple this.right = this.right.Simplify(); // right guy also has to get simple if (left is NumberNode && right is NumberNode) { if ((right as NumberNode).RealValue != 0) { NumberNode division = new NumberNode( null, ((left as NumberNode).RealValue / (right as NumberNode).RealValue) ); return(division); } return(this); } else if (left is NumberNode && !(right is NumberNode)) { var value = (left as NumberNode).RealValue; if (value == 0) { return(new NumberNode(null, 0)); } this.right = this.right.Simplify(); return(this); } else if (!(left is NumberNode) && right is NumberNode) { if ((right as NumberNode).RealValue == 1) { return(this.left.Simplify()); } this.left = this.left.Simplify(); return(this); } else { return(this); } } else // if one of them IS actually a number { if (left is NumberNode && right is NumberNode) { if ((right as NumberNode).RealValue != 0) { NumberNode division = new NumberNode( null, ((left as NumberNode).RealValue / (right as NumberNode).RealValue) ); return(division); } return(this); } else if (left is NumberNode && !(right is NumberNode)) { var value = (left as NumberNode).RealValue; if (value == 0) { return(new NumberNode(null, 0)); } this.right = this.right.Simplify(); return(this); } else if (!(left is NumberNode) && right is NumberNode) { if ((right as NumberNode).RealValue == 1) { return(this.left.Simplify()); } this.left = this.left.Simplify(); return(this); } else { return(null); } } }
public override BaseNode Simplify() { if (!(left is NumberNode || right is NumberNode)) // if neither left nor right guy is a number { this.left = this.left.Simplify(); // tell the left guy to get simple this.right = this.right.Simplify(); // right guy also has to get simple if (left is NumberNode && right is NumberNode) { NumberNode substraction = new NumberNode( null, ((left as NumberNode).RealValue - (right as NumberNode).RealValue) ); return(substraction); } else if (left is NumberNode && !(right is NumberNode)) { this.right = this.right.Simplify(); return(this); } else if (!(left is NumberNode) && right is NumberNode) { var value = (right as NumberNode).RealValue; this.left = this.left.Simplify(); if (value == 0) { return(this.left); } return(this); } else { return(this); } } else // if one of them IS actually a number // we go over all the possibilities { if (left is NumberNode && right is NumberNode) { NumberNode substraction = new NumberNode( null, ((left as NumberNode).RealValue - (right as NumberNode).RealValue) ); return(substraction); } else if (left is NumberNode && !(right is NumberNode)) { this.right = this.right.Simplify(); return(this); } else if (!(left is NumberNode) && right is NumberNode) { var value = (right as NumberNode).RealValue; this.left = this.left.Simplify(); if (value == 0) { return(this.left); } return(this); } else { return(null); } } }
public override BaseNode Simplify() { if (!(left is NumberNode || right is NumberNode)) // if neither left nor right guy is a number { this.left = this.left.Simplify(); // tell the left guy to get simple this.right = this.right.Simplify(); // right guy also has to get simple if (left is NumberNode && right is NumberNode) { NumberNode power = new NumberNode( null, Math.Pow((left as NumberNode).RealValue, (right as NumberNode).RealValue) ); return(power); } else if (left is NumberNode && !(right is NumberNode)) { var value = (left as NumberNode).RealValue; if (value == 0) { return(new NumberNode(null, 0)); } // MIGHT BE CAUSING PROBLEMS (CHECK IT LATER) else if (value == 1) { return(new NumberNode(null, 1)); } this.right = this.right.Simplify(); return(this); } else if (!(left is NumberNode) && right is NumberNode) { var value = (right as NumberNode).RealValue; if (value == 0) { return(new NumberNode(null, 1)); } else if (value == 1) { return(this.left.Simplify()); } this.left = this.left.Simplify(); return(this); } else { return(this); } } else // if one of them IS actually a number { if (left is NumberNode && right is NumberNode) { NumberNode power = new NumberNode( null, Math.Pow((left as NumberNode).RealValue, (right as NumberNode).RealValue) ); return(power); } else if (left is NumberNode && !(right is NumberNode)) { var value = (left as NumberNode).RealValue; if (value == 0) { return(new NumberNode(null, 0)); } else if (value == 1) { return(new NumberNode(null, 1)); } this.right = this.right.Simplify(); return(this); } else if (!(left is NumberNode) && right is NumberNode) { var value = (right as NumberNode).RealValue; if (value == 0) { return(new NumberNode(null, 1)); } // MIGHT BE CAUSING PROBLEMS (CHECK IT LATER) else if (value == 1) { return(this.left.Simplify()); } this.left = this.left.Simplify(); return(this); } else { return(null); } } }
public override void CreateDerivativeTree(BaseNode parent, bool isLeft = true) { if (this.right is NumberNode && this.left is BasicFunctionXNode) { var lesser = (right as NumberNode).RealValue - 1; BasicFunctionXNode x = new BasicFunctionXNode("", null); MultiplicationNode multiplication = new MultiplicationNode(new NumberNode(null, (right as NumberNode).RealValue), new PowerNode(x, new NumberNode(null, lesser), null), null); if (parent != null) { if (isLeft) { parent.left = multiplication; } else { parent.right = multiplication; } } SetDerivativeRoot(multiplication); return; } else { if (this.right is NumberNode && this.left is NumberNode) { // if both this.left and this.right are numbers, return 0 for its just a number and it's anyway gon be 0 NumberNode node = new NumberNode(parent, 0); if (parent != null) { if (isLeft) { parent.left = node; } else { parent.right = node; } } //Plotter.SetDerivativeRoot (node); SetDerivativeRoot(node); return; } else if (this.right is NumberNode && !(this.left is NumberNode)) { // f(x) ^ (some number) // if left one some function double nMinus1 = ((NumberNode)this.right).RealValue - 1; var value = ((NumberNode)this.right).RealValue; if (value == 1) { var node = Plotter.CloneTree(this); if (parent != null) { if (isLeft) { parent.left = node; } else { parent.right = node; } } node.left.CreateDerivativeTree(node); SetDerivativeRoot(node); return; } PowerNode power = new PowerNode(Plotter.CloneTree(this.left), new NumberNode(null, nMinus1), null); MultiplicationNode multiplication = new MultiplicationNode(new NumberNode(null, value), Plotter.CloneTree(this.left), null); // if the f(x) is more complicated than just 'x', we do additional calculation if (!(multiplication.right is BasicFunctionXNode)) { MultiplicationNode node = new MultiplicationNode(multiplication, Plotter.CloneTree(this.left), parent); node.right.CreateDerivativeTree(multiplication, false); if (parent != null) { if (isLeft) { parent.left = node; } else { parent.right = node; } } //Plotter.SetDerivativeRoot (node); SetDerivativeRoot(node); return; } multiplication.parent = parent; if (parent != null) { if (isLeft) { parent.left = multiplication; } else { parent.right = multiplication; } } //Plotter.SetDerivativeRoot (multiplication); SetDerivativeRoot(multiplication); return; } else if (!(this.right is NumberNode) && (this.left is NumberNode)) { // (some number) ^ f(x) var value = ((NumberNode)this.left).RealValue; if (this.right is BasicFunctionXNode) { // simple function PowerNode power = new PowerNode(new NumberNode(null, value), new BasicFunctionXNode(""), null); LnNode ln = new LnNode(new NumberNode(null, value), null); MultiplicationNode node = new MultiplicationNode(power, ln, parent); if (parent != null) { if (isLeft) { parent.left = node; } else { parent.right = node; } } //Plotter.SetDerivativeRoot (node); SetDerivativeRoot(node); return; } else { // function is more complicated PowerNode power = new PowerNode(new NumberNode(null, value), this.right, null); LnNode ln = new LnNode(new NumberNode(null, value), null); MultiplicationNode multiplication = new MultiplicationNode(power, ln, parent); MultiplicationNode node = new MultiplicationNode(multiplication, Plotter.CloneTree(this.right), parent); node.right.CreateDerivativeTree(node, false); if (parent != null) { if (isLeft) { parent.left = node; } else { parent.right = node; } } //Plotter.SetDerivativeRoot (node); SetDerivativeRoot(node); return; } } else if (!(this.right is NumberNode) && !(this.left is NumberNode)) { // neither is a number // CASE: f(x) ^ g(x) // d(f(x) ^ g(x))/dx = e^(g(x)*ln(f(x)) * d((g(x)*f(x)))/dx ) // this.left = f(x), this.right = g(x) LnNode lnFx = new LnNode(Plotter.CloneTree(this.left), null); // create ln(f(x)) MultiplicationNode multiplication = new MultiplicationNode(Plotter.CloneTree(this.right), lnFx, null); // create g(x)*ln(f(x)) PowerNode ePower = new PowerNode(new NumberNode(null, Math.E), multiplication, null); // create e^(g(x)*ln(f(x))) MultiplicationNode derivativeOfMultiplication = new MultiplicationNode(Plotter.CloneTree(multiplication.left), Plotter.CloneTree(multiplication.right), null); // do the derivative of g(x)*ln(f(x)) MultiplicationNode node = new MultiplicationNode(ePower, derivativeOfMultiplication, parent); // put it all together node.right.CreateDerivativeTree(node, false); // take a derivative if (parent != null) { if (isLeft) { parent.left = node; } else { parent.right = node; } } //Plotter.SetDerivativeRoot (node); SetDerivativeRoot(node); return; } } }