/// <summary> /// Applies the chain rule on a function. /// </summary> /// <param name="function">The function definition.</param> /// <param name="dargs">The derivatives of the arguments.</param> /// <param name="format">The format of the new function. {0} denotes the old name, while {1} will hold the index to which the function should be derived.</param> /// <returns></returns> public static Node ChainRule(FunctionNode function, IReadOnlyList <Node> dargs, string format) { Node result = null; for (var i = 0; i < dargs.Count; i++) { if (dargs[i] == null) { break; } var b = Node.Function(format.FormatString(function.Name, i), function.Arguments) * dargs[i]; result = result == null ? b : Node.Add(result, b); } return(result); }
private static Node DPwr(FunctionNode f, IReadOnlyList <Node> dargs) { dargs.Check(2); Node result = null; if (dargs[0] != null) { result = Node.Function("sgn", f.Arguments[0]) * f.Arguments[1] * dargs[0] * Node.Function(f.Name, f.Arguments[0], f.Arguments[1] - 1.0); } if (dargs[1] != null) { result += dargs[1] * Node.Function("log", f.Arguments[0]) * f; } return(result); }
private static Node Limit(FunctionNode f, IReadOnlyList <Node> dargs) { dargs.Check(3); var x = f.Arguments[0]; var y = f.Arguments[1]; var z = f.Arguments[2]; Node result = null; if (dargs[0] != null) { result = Node.Conditional( Node.And( Node.GreaterThan(x, Node.Function("min", y, z)), Node.LessThan(x, Node.Function("max", y, z))), dargs[0], Node.Zero); } if (dargs[1] != null) { result += Node.Conditional( Node.And( Node.LessThanOrEqual(y, z), Node.LessThanOrEqual(x, Node.Function("min", y, z))), dargs[1], Node.Zero); } if (dargs[2] != null) { result += Node.Conditional( Node.And( Node.LessThan(y, z), Node.GreaterThanOrEqual(x, Node.Function("max", y, z))), dargs[2], Node.Zero); } return(result); }
private static Node DHypot(FunctionNode f, IReadOnlyList <Node> dargs) { dargs.Check(2); if (dargs[1] == null) { if (dargs[0] == null) { return(null); } return(0.5 * f.Arguments[0] * dargs[0] / f); } else if (dargs[0] == null) { return(0.5 * f.Arguments[1] * dargs[1] / f); } else { return(0.5 * (f.Arguments[0] * dargs[0] + f.Arguments[1] * dargs[1]) / f); } }
private static Node DAtan2(FunctionNode f, IReadOnlyList <Node> dargs) { dargs.Check(2); if (dargs[1] == null) { if (dargs[0] == null) { return(null); } return(f.Arguments[1] * dargs[0] / (Node.Function("square", f.Arguments[0]) + Node.Function("square", f.Arguments[1]))); } else if (dargs[0] == null) { return(-f.Arguments[0] * dargs[1] / (Node.Function("square", f.Arguments[0]) + Node.Function("square", f.Arguments[1]))); } else { return((f.Arguments[1] * dargs[0] - f.Arguments[0] * dargs[1]) / (Node.Function("square", f.Arguments[0]) + Node.Function("square", f.Arguments[1]))); } }
private static Node DAtan(FunctionNode f, IReadOnlyList <Node> dargs) => dargs.Check(1)[0] / (Node.One + Node.Power(f.Arguments[0], Node.Two));
private static Node DAsin(FunctionNode f, IReadOnlyList <Node> dargs) => dargs.Check(1)[0] / Node.Function("sqrt", Node.One - Node.Power(f.Arguments[0], Node.Two));
private static Node Zero(FunctionNode f, IReadOnlyList <Node> dargs) => null;
private static Node DPassThrough(FunctionNode f, IReadOnlyList <Node> dargs) => Node.Function(f.Name, dargs);
private static Node DAtanh(FunctionNode f, IReadOnlyList <Node> dargs) => dargs.Check(1)[0] / (1 - Node.Function("square", f.Arguments[0]));
/// <include file='docs.xml' path='docs/members/Function/*'/> public static FunctionNode Function(string name, params Node[] arguments) => FunctionNode.Function(name, arguments);
/// <include file='docs.xml' path='docs/members/Function/*'/> public static FunctionNode Function(string name, IReadOnlyList <Node> arguments) => FunctionNode.Function(name, arguments);