public AbstractFloatNode(int inlets)
 {
     Gradients = new float[inlets];
     Inputs    = new IFloatNode[inlets];
     Output    = new Outlet();
     Id        = Count++;
 }
        public LossNode(IFloatNode result, IFloatNode target) : base(2)
        {
            Inputs[0] = result;
            Inputs[1] = target;

            result.Output.Connect(this, 0);
            target.Output.Connect(this, 1);
        }
        public MultiplyNode(IFloatNode a, IFloatNode b) : base(2)
        {
            Inputs[0] = a;
            Inputs[1] = b;

            a.Output.Connect(this, 0);
            b.Output.Connect(this, 1);
        }
        private static void Optimize(IFloatNode node)
        {
            const float rate = 0.01f;

            for (int i = 0; i < 100; i++)
            {
                ForwardPass(node);
                BackwardPass(node);
                ParameterUpdate(node, rate);
            }
        }
        private static void BackwardPass(IFloatNode node)
        {
            Debug.Log("Backwards pass: " + node);

            TraverseInputsBF(node, n => {
                float gradient = n.Output.IsConnected ? n.Output.Node.Gradients[n.Output.Inlet] : 1f;
                n.Backward(gradient);
            });

            var stack = new Stack <IFloatNode>();

            stack.Push(node);
        }
        private static void ParameterUpdate(IFloatNode node, float rate)
        {
            Debug.Log("Parameter Update");

            TraverseInputsBF(node, n => {
                if (n is ConstNode)
                {
                    var cNode = n as ConstNode;
                    if (cNode.IsLearnable)
                    {
                        cNode.Value += n.Output.Node.Gradients[node.Output.Inlet] * rate;
                    }
                }
            });
        }
        private static void ForwardPass(IFloatNode node)
        {
            // Create ordered lists of ops, burst-ready

            Debug.Log("Forward pas: "******": " + evalOrder[i].ToString());
            }
        }
        // Traverse graph from a given node up through its inputs, in breadth-first order
        private static void TraverseInputsBF(IFloatNode node, System.Action <IFloatNode> visit)
        {
            var stack = new Stack <IFloatNode>();

            stack.Push(node);

            while (stack.Count > 0)
            {
                node = stack.Pop();

                visit(node);

                for (int i = 0; i < node.Inputs.Count; i++)
                {
                    stack.Push(node.Inputs[i]);
                }
            }
        }
 public void Connect(IFloatNode node, int inlet)
 {
     Node  = node;
     Inlet = inlet;
 }