/// <inheritdoc/> public override ExpNode Execute(VectorProjOperNode node) { if (node.LeftChild.AreEqualSizeVectors(node.RightChild, out TensorNode a, out TensorNode b)) { VectorProductOperNode adotb = QuickOpers.DotProduct(a, (TensorNode)b.Clone()); BOperNode bdotb = QuickOpers.DotProduct((TensorNode)b.Clone(), (TensorNode)b.Clone()); return(QuickOpers.Multiply(b, adotb, QuickOpers.Reciprical(bdotb)).Execute(this)); } return(HandleError(new CannotVectorProject(this, node))); }
/// <inheritdoc/> public override ExpNode Execute(SineOperNode node) { if (node.IsConstantBy(_variable)) { return(ConstantRule(node)); } Differentiator diff = new(_variable); // Apply ChainRule var coefficient = node.Child.Execute(diff); // Apply table var sinFunc = SineTable(node); return(QuickOpers.Multiply(QuickOpers.Reciprical(coefficient), sinFunc)); }
/// <inheritdoc/> public override ExpNode Execute(PowOperNode node) { // TODO: Handle variable in exponent if (node.IsConstantBy(_variable)) { return(ConstantRule(node)); } // Increment exponent, divide by exponent AdditionOperNode exponent = QuickOpers.Add(1, node.RightChild); RecipricalOperNode coefficient = QuickOpers.Reciprical(exponent.Clone()); PowOperNode @base = QuickOpers.Pow(node.LeftChild, exponent); return(QuickOpers.Multiply(coefficient, @base)); }
/// <inheritdoc/> public override ExpNode Execute(RowElimOperNode node) { // Ensure matrix. if (node.Child is TensorNode tensorNode && tensorNode.TensorType == TensorType.Matrix) { MatrixByRow matrix = new MatrixByRow(tensorNode); int[] leadingPositions = RefHelpers.GetLeadingColumns(matrix); // Put in row-echelon form for (int i = 0; i < matrix.Height; i++) { int leftMostCol = RefHelpers.GetLeftMostColumn(leadingPositions, i); matrix.SwapRows(i, leftMostCol); Common.Swap(ref leadingPositions[i], ref leadingPositions[leftMostCol]); if (leadingPositions[i] == -1) { continue; } matrix[i].MultiplyRow(QuickOpers.Reciprical(matrix[i][leadingPositions[i]])); for (int j = i + 1; j < matrix.Height; j++) { matrix[j].AddRowToRow(matrix[i], QuickOpers.Negative(matrix[j][leadingPositions[i]])); leadingPositions[j] = RefHelpers.GetLeadingColumn(matrix[j]); } } if (node.EliminationMethod == RowElimMethod.GaussJordan) { // Put in reduced row-echelon form for (int i = matrix.Height - 1; i > 0; i--) { for (int j = i - 1; j >= 0; j--) { matrix[j].AddRowToRow(matrix[i], QuickOpers.Negative(matrix[j][leadingPositions[i]])); leadingPositions[j] = RefHelpers.GetLeadingColumn(matrix[j]); } } } return(matrix.AsExpNode()); } return(HandleError(new CannotReduceNonMatrix(this, node.Child))); }