/// <summary> /// Creates a MacLaurien series based off the function /// </summary> /// <param name="mcLaurienRoot">Where the McLaurien Series will be outputted</param> /// <param name="order">Nth order of a series</param> public void CreateMcLaurienSeries(out BaseNode mcLaurienRoot, int order = 5) { if (derivativeRoot == null) { CreateDerivativeTree(); derivativeRoot.Simplify(); } // we made sure that there is a derivative BaseNode myDerivative = Plotter.CloneTree(derivativeRoot); myDerivative.derivativeRoot = myDerivative; double[] values = new double[order + 1]; // values for functions (f(0), derivative of f(0), second derivative of f(0), etc..) values[0] = root.Calculate(0); // set up a value for f(0) if (values.Length >= 2) { values[1] = derivativeRoot.Calculate(0); // set up a value of the first derivative of f(0) } if (values.Length >= 3) { for (int i = 2; i < values.Length; i++) { myDerivative.CreateDerivativeTree(null); values[i] = myDerivative.derivativeRoot.Calculate(0); myDerivative = myDerivative.derivativeRoot; } } List <BaseNode> mcLaurienItems = new List <BaseNode> (); SumNode result = new SumNode(null, null, null); result.left = new NumberNode(null, values[0]); for (int i = 1; i < values.Length; i++) { DivisionNode item = new DivisionNode(null, null, null); FactorialNode denominator = new FactorialNode(new NumberNode(null, i), null); // not sure about this line MultiplicationNode numerator = new MultiplicationNode( new NumberNode(null, values[i]), new PowerNode(new BasicFunctionXNode("", null), new NumberNode(null, i), null), null ); item.left = numerator; item.right = denominator; mcLaurienItems.Add(item); } foreach (var item in mcLaurienItems) { result.PutToRightNode(item); } mcLaurienRoot = result; }
public void PutToRightNode(BaseNode node) { if (this.right == null) { this.right = node; } else { SumNode sum = new SumNode(this.right, node, null); this.right = sum; } }
public override void CreateDerivativeTree(BaseNode parent, bool isLeft = true) { SumNode node = new SumNode(Plotter.CloneTree(this.left), Plotter.CloneTree(this.right), parent); if (parent != null) { if (isLeft) { parent.left = node; } else { parent.right = node; } } node.left.CreateDerivativeTree(node); node.right.CreateDerivativeTree(node, false); //Plotter.SetDerivativeRoot (node); SetDerivativeRoot(node); }
public override void CreateDerivativeTree(BaseNode parent, bool isLeft = true) { SumNode sum = new SumNode(Plotter.CloneTree(this), Plotter.CloneTree(this), this.parent); if (parent != null) { if (isLeft) { parent.left = sum; } else { parent.right = sum; } } sum.left.left.CreateDerivativeTree(sum.left); sum.right.right.CreateDerivativeTree(sum.right, false); //Plotter.SetDerivativeRoot (sum); SetDerivativeRoot(sum); }
/// <summary> /// Get the McLaurien series based off already given values for derivatives /// </summary> /// <param name="mcLaurienRoot">Where the McLaurien series will be outputted</param> /// <param name="order">Order of the McLaurien</param> public void CreateMcLaurienSeriesByLimits(out BaseNode mcLaurienRoot, int order) { List <double> values = new List <double> (); for (int i = 0; i <= order; i++) { var value = ProcessNthDerivative_Quotient(0, i, root); values.Add(value); } List <BaseNode> mcLaurienItems = new List <BaseNode> (); SumNode result = new SumNode(null, null, null); result.left = new NumberNode(null, values[0]); for (int i = 1; i < values.Count; i++) { DivisionNode item = new DivisionNode(null, null, null); FactorialNode denominator = new FactorialNode(new NumberNode(null, i), null); // not sure about this line MultiplicationNode numerator = new MultiplicationNode( new NumberNode(null, values[i]), new PowerNode(new BasicFunctionXNode("", null), new NumberNode(null, i), null), null ); item.left = numerator; item.right = denominator; mcLaurienItems.Add(item); } foreach (var item in mcLaurienItems) { result.PutToRightNode(item); } mcLaurienRoot = result; }
public BaseNode CreatePolynomialThroughPoints(DataPoint[] points) { /* Let X be the number of points user has selected * Then the polynomial is going to be of the degree (X - 1) * * Example: X = 5 => ax^4 + bx^3 + cx^2 + dx + e */ SumNode polynomial = new SumNode(null, null, null); var firstDivision = ProduceLagrange(points, 0); var firstMultiplication = new MultiplicationNode(firstDivision, new NumberNode(null, points[0].Y), null); polynomial.left = firstMultiplication; for (int j = 1; j < points.Length; j++) { var division = ProduceLagrange(points, j); MultiplicationNode node = new MultiplicationNode(division, new NumberNode(null, points[j].Y), null); polynomial.PutToRightNode(node); } return(polynomial); }
/// <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); } }