// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3) space 
// Source File Name:   Function.java

package lt.monarch.function;

import lt.monarch.function.node.ConstantNode;

// Referenced classes of package lt.monarch.function:
//            AbstractIdentifier, Variable, Node, Identifier, 
//            NodeCompiler, CompiledFunctionSet

public class Function extends AbstractIdentifier
{

    public int parameterCount()
    {
        return params.length;
    }

    public Variable[] parameters()
    {
        return params;
    }

    public boolean isConstant()
    {
        return body instanceof ConstantNode;
    }

    public Node body()
    {
        return body;
    }

    public double evaluate(double ad[])
    {
        for (int i = 0; i < params.length; i++)
            params[i].setValue(ad[i]);

        return body.evaluate();
    }

    public Identifier derivative(int i)
    {
        return (Identifier)new Function(name() + "'" + (i + 1), params, body.derivative(params[i]));
    }

    public String javaFunctionName()
    {
        return name().replace('\'', '_');
    }

    public String javaFunctionDescriptor()
    {
        StringBuffer stringbuffer = new StringBuffer();
        for (int i = 0; i < params.length; i++)
            stringbuffer.append('D');

        return "(" + stringbuffer.toString() + ")D";
    }

    public void compile(NodeCompiler nodecompiler)
    {
        nodecompiler.setParameters(params);
        nodecompiler.compile(body);
    }

    public void compileRef(NodeCompiler nodecompiler, Node anode[])
    {
        if (!nodecompiler.functionSet().hasMethod(javaFunctionName(), javaFunctionDescriptor()))
        {
            NodeCompiler nodecompiler1 = new NodeCompiler(nodecompiler.functionSet(), javaFunctionName());
            nodecompiler1.setParameters(true, javaFunctionDescriptor(), params);
            nodecompiler1.compile(body);
            nodecompiler.functionSet().addMethod(nodecompiler1);
        }
        for (int i = 0; i < anode.length; i++)
            anode[i].compile(nodecompiler);

        nodecompiler.appendStaticCall(null, javaFunctionName(), javaFunctionDescriptor());
        nodecompiler.freeStack(2 * (params.length - 1));
    }

    public Function(String s, Variable avariable[], Node node)
    {
        super(s);
        body = node.simplify();
        params = avariable;
    }

    protected Node body;
    protected Variable params[];
}
