Search in sources :

Example 11 with EquationSet

use of gov.sandia.n2a.eqset.EquationSet in project n2a by frothga.

the class Part method finish.

public boolean finish(Simulator simulator) {
    InternalBackendData bed = (InternalBackendData) equations.backendData;
    int populations = equations.parts.size();
    for (int i = 0; i < populations; i++) ((Population) valuesObject[i]).finish(simulator);
    if (bed.liveStorage == InternalBackendData.LIVE_STORED) {
        // early-out if we are already dead, to avoid another call to die()
        if (((Scalar) get(bed.live)).value == 0)
            return false;
    }
    // Events
    for (EventSource es : bed.eventSources) {
        @SuppressWarnings("unchecked") List<Instance> monitors = (ArrayList<Instance>) valuesObject[es.monitorIndex];
        if (monitors.size() == 0)
            continue;
        EventTarget eventType = es.target;
        if (es.testEach) {
            for (Instance i : monitors) {
                if (i == null)
                    continue;
                double delay = eventType.test(i, simulator);
                // the trigger condition was not satisfied
                if (delay < -1)
                    continue;
                EventSpikeSingle spike;
                if (// event was triggered, but timing is no-care
                delay < 0) {
                    spike = new EventSpikeSingleLatch();
                    // queue immediately after current cycle, so latches get set for next full cycle
                    spike.t = simulator.currentEvent.t;
                } else if (// process as close to current cycle as possible
                delay == 0) {
                    // fully execute the event (not latch it)
                    spike = new EventSpikeSingle();
                    // queue immediately
                    spike.t = simulator.currentEvent.t;
                } else {
                    // Is delay an quantum number of $t' steps?
                    double ratio = delay / event.dt;
                    int step = (int) Math.round(ratio);
                    if (Math.abs(ratio - step) < 1e-3) {
                        if (simulator.eventMode == Simulator.DURING)
                            spike = new EventSpikeSingleLatch();
                        else
                            spike = new EventSpikeSingle();
                        if (simulator.eventMode == Simulator.AFTER)
                            delay = (step + 1e-6) * event.dt;
                        else
                            delay = (step - 1e-6) * event.dt;
                    } else {
                        spike = new EventSpikeSingle();
                    }
                    spike.t = simulator.currentEvent.t + delay;
                }
                spike.eventType = eventType;
                spike.target = i;
                simulator.queueEvent.add(spike);
            }
        } else // All monitors share same condition, so only test one.
        {
            double delay = -2;
            for (Instance i : monitors) {
                if (i == null)
                    continue;
                delay = eventType.test(i, simulator);
                break;
            }
            // the trigger condition was not satisfied
            if (delay < -1)
                continue;
            if (// Each target instance may require a different delay.
            es.delayEach) {
                for (Instance i : monitors) {
                    if (i == null)
                        continue;
                    // This results in one redundant eval, of first entry in monitors. Not clear if it's worth the work to avoid this.
                    delay = eventType.delay(i, simulator);
                    EventSpikeSingle spike;
                    if (delay < 0) {
                        spike = new EventSpikeSingleLatch();
                        spike.t = simulator.currentEvent.t;
                    } else if (delay == 0) {
                        spike = new EventSpikeSingle();
                        spike.t = simulator.currentEvent.t;
                    } else {
                        double ratio = delay / event.dt;
                        int step = (int) Math.round(ratio);
                        if (Math.abs(ratio - step) < 1e-3) {
                            if (simulator.eventMode == Simulator.DURING)
                                spike = new EventSpikeSingleLatch();
                            else
                                spike = new EventSpikeSingle();
                            if (simulator.eventMode == Simulator.AFTER)
                                delay = (step + 1e-6) * event.dt;
                            else
                                delay = (step - 1e-6) * event.dt;
                        } else {
                            spike = new EventSpikeSingle();
                        }
                        spike.t = simulator.currentEvent.t + delay;
                    }
                    spike.eventType = eventType;
                    spike.target = i;
                    simulator.queueEvent.add(spike);
                }
            } else // All delays are the same.
            {
                EventSpikeMulti spike;
                if (delay < 0) {
                    spike = new EventSpikeMultiLatch();
                    spike.t = simulator.currentEvent.t;
                } else if (delay == 0) {
                    spike = new EventSpikeMulti();
                    spike.t = simulator.currentEvent.t;
                } else {
                    double ratio = delay / event.dt;
                    int step = (int) Math.round(ratio);
                    if (Math.abs(ratio - step) < 1e-3) {
                        if (simulator.eventMode == Simulator.DURING)
                            spike = new EventSpikeMultiLatch();
                        else
                            spike = new EventSpikeMulti();
                        if (simulator.eventMode == Simulator.AFTER)
                            delay = (step + 1e-6) * event.dt;
                        else
                            delay = (step - 1e-6) * event.dt;
                    } else {
                        spike = new EventSpikeMulti();
                    }
                    spike.t = simulator.currentEvent.t + delay;
                }
                spike.eventType = eventType;
                // We don't copy the array, just keep a reference to it. What could go wrong with this?
                // If a part dies and tries to remove itself from the list while it is being used to deliver spikes,
                // then we could get a null pointer exception. Solution is to synchronize access to the list.
                // If a connection is born while the spike is in flight, one could argue that it shouldn't
                // receive it, but one could also argue that it should. In nature these two things (spikes
                // and synapse creation) occur at vastly different timescales. Wouldn't a nascent synapse
                // receive spikes even as it is forming?
                spike.targets = monitors;
                simulator.queueEvent.add(spike);
            }
        }
    }
    // Other stuff
    if (bed.lastT != null)
        setFinal(bed.lastT, new Scalar(simulator.currentEvent.t));
    for (Variable v : bed.localBufferedExternal) setFinal(v, getFinal(v));
    for (Integer i : bed.eventLatches) valuesFloat[i] = 0;
    for (Variable v : bed.localBufferedExternalWrite) {
        switch(v.assignment) {
            case Variable.ADD:
                // initial value is zero-equivalent (additive identity)
                set(v, v.type);
                break;
            case Variable.MULTIPLY:
            case Variable.DIVIDE:
                // multiplicative identity
                if (v.type instanceof Matrix)
                    set(v, ((Matrix) v.type).identity());
                else
                    set(v, new Scalar(1));
                break;
            case Variable.MIN:
                if (v.type instanceof Matrix)
                    set(v, ((Matrix) v.type).clear(Double.POSITIVE_INFINITY));
                else
                    set(v, new Scalar(Double.POSITIVE_INFINITY));
                break;
            case Variable.MAX:
                if (v.type instanceof Matrix)
                    set(v, ((Matrix) v.type).clear(Double.NEGATIVE_INFINITY));
                else
                    set(v, new Scalar(Double.NEGATIVE_INFINITY));
                break;
        }
    }
    if (bed.type != null) {
        int type = (int) ((Scalar) get(bed.type)).value;
        if (type > 0) {
            ArrayList<EquationSet> split = equations.splits.get(type - 1);
            if (// Make sure $type != me. Otherwise it's a null operation
            split.size() > 1 || split.get(0) != equations) {
                // indicates that this instance is one of the resulting parts
                boolean used = false;
                int countParts = split.size();
                for (int i = 0; i < countParts; i++) {
                    EquationSet other = split.get(i);
                    Scalar splitPosition = new Scalar(i + 1);
                    if (other == equations && !used) {
                        used = true;
                        setFinal(bed.type, splitPosition);
                    } else {
                        InternalBackendData otherBed = (InternalBackendData) other.backendData;
                        Part p = new Part(other, (Part) container);
                        // If this is a connection, keep the same bindings
                        Conversion conversion = bed.conversions.get(other);
                        if (conversion.bindings != null) {
                            for (int j = 0; j < conversion.bindings.length; j++) {
                                p.valuesObject[otherBed.endpoints + conversion.bindings[j]] = valuesObject[bed.endpoints + j];
                            }
                        }
                        event.enqueue(p);
                        p.resolve();
                        // accountable connections are updated here
                        p.init(simulator);
                        // Copy over variables
                        int count = conversion.from.size();
                        for (int v = 0; v < count; v++) {
                            Variable from = conversion.from.get(v);
                            Variable to = conversion.to.get(v);
                            p.setFinal(to, get(from));
                        }
                        // Set $type to be our position in the split
                        p.setFinal(otherBed.type, splitPosition);
                    }
                }
                if (!used) {
                    die();
                    return false;
                }
            }
        }
    }
    if (equations.lethalP) {
        double p;
        if (bed.p.hasAttribute("temporary")) {
            InstanceTemporaries temp = new InstanceTemporaries(this, simulator, false);
            for (Variable v : bed.Pdependencies) {
                Type result = v.eval(temp);
                if (result != null && v.writeIndex >= 0)
                    temp.set(v, result);
            }
            Type result = bed.p.eval(temp);
            if (result == null)
                p = 1;
            else
                p = ((Scalar) result).value;
        } else {
            p = ((Scalar) get(bed.p)).value;
        }
        if (p == 0 || p < 1 && p < simulator.random.nextDouble()) {
            die();
            return false;
        }
    }
    if (equations.lethalConnection) {
        int count = equations.connectionBindings.size();
        for (int i = 0; i < count; i++) {
            if (!getPart(i).getLive()) {
                die();
                return false;
            }
        }
    }
    if (equations.lethalContainer) {
        if (!((Part) container).getLive()) {
            die();
            return false;
        }
    }
    return true;
}
Also used : EquationSet(gov.sandia.n2a.eqset.EquationSet) Variable(gov.sandia.n2a.eqset.Variable) Instance(gov.sandia.n2a.language.type.Instance) ArrayList(java.util.ArrayList) Conversion(gov.sandia.n2a.backend.internal.InternalBackendData.Conversion) Scalar(gov.sandia.n2a.language.type.Scalar) EventSource(gov.sandia.n2a.backend.internal.InternalBackendData.EventSource) Type(gov.sandia.n2a.language.Type) Matrix(gov.sandia.n2a.language.type.Matrix) EventTarget(gov.sandia.n2a.backend.internal.InternalBackendData.EventTarget)

Example 12 with EquationSet

use of gov.sandia.n2a.eqset.EquationSet in project n2a by frothga.

the class ExportJob method getEquations.

public EquationSet getEquations(MPart p) {
    List<String> path = new ArrayList<String>();
    MPart parent = p;
    while (parent != null) {
        path.add(parent.key());
        parent = parent.getParent();
    }
    EquationSet result = equations;
    for (int i = path.size() - 2; i >= 0; i--) {
        String name = path.get(i);
        result = result.findPart(name);
        if (result == null)
            return null;
        if (!result.name.equals(name))
            return null;
    }
    return result;
}
Also used : EquationSet(gov.sandia.n2a.eqset.EquationSet) MPart(gov.sandia.n2a.eqset.MPart) ArrayList(java.util.ArrayList)

Example 13 with EquationSet

use of gov.sandia.n2a.eqset.EquationSet in project n2a by frothga.

the class ExportJob method process.

public void process(MNode source, File destination) {
    try {
        MPart mpart = new MPart((MPersistent) source);
        modelName = source.key();
        equations = new EquationSet(mpart);
        // Make eqset minimally executable ...
        try {
            equations.resolveConnectionBindings();
        }// Still try to finish rest of compilation. Maybe only one or two minor parts were affected.
         catch (Exception e) {
        }
        try {
            equations.addGlobalConstants();
            // $index, $init, $live, $n, $t, $t', $type
            equations.addSpecials();
            equations.fillIntegratedVariables();
            equations.findIntegrated();
            equations.resolveLHS();
            equations.resolveRHS();
            // This could hurt the analysis. It simplifies expressions and substitutes constants, breaking some dependency chains.
            equations.findConstants();
            equations.determineTypes();
            equations.clearVariables();
        }// It may still be possible to complete the export.
         catch (Exception e) {
        }
        analyze(equations);
        DocumentBuilderFactory factoryBuilder = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factoryBuilder.newDocumentBuilder();
        doc = builder.newDocument();
        // Convert top-level N2A part into top-level NeuroML elements
        process(mpart);
        DOMSource dom = new DOMSource(doc);
        StreamResult stream = new StreamResult(new OutputStreamWriter(new FileOutputStream(destination), "UTF-8"));
        TransformerFactory factoryXform = TransformerFactory.newInstance();
        factoryXform.setAttribute("indent-number", 4);
        Transformer xform = factoryXform.newTransformer();
        xform.setOutputProperty(OutputKeys.INDENT, "yes");
        xform.transform(dom, stream);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Also used : EquationSet(gov.sandia.n2a.eqset.EquationSet) MPart(gov.sandia.n2a.eqset.MPart) DOMSource(javax.xml.transform.dom.DOMSource) DocumentBuilderFactory(javax.xml.parsers.DocumentBuilderFactory) TransformerFactory(javax.xml.transform.TransformerFactory) Transformer(javax.xml.transform.Transformer) StreamResult(javax.xml.transform.stream.StreamResult) DocumentBuilder(javax.xml.parsers.DocumentBuilder) FileOutputStream(java.io.FileOutputStream) OutputStreamWriter(java.io.OutputStreamWriter) IncommensurableException(javax.measure.IncommensurableException) UnconvertibleException(javax.measure.UnconvertibleException) ParseException(gov.sandia.n2a.language.ParseException)

Example 14 with EquationSet

use of gov.sandia.n2a.eqset.EquationSet in project n2a by frothga.

the class Output method determineVariableName.

// This method should be called by analysis, with v set to the variable that holds this equation.
public void determineVariableName(Variable v) {
    // Ensure that the first operand is a file name.
    // If no file name is specified, stdout is used. We get the same effect by specifying the empty string, so insert it here.
    // This makes parameter processing much simpler elsewhere.
    int length = operands.length;
    if (length > 0 && !isStringExpression(v, operands[0])) {
        variableName = variableName0;
        Operator[] newOperands = new Operator[length + 1];
        for (int i = 0; i < length; i++) newOperands[i + 1] = operands[i];
        newOperands[0] = new Constant(new Text());
        operands = newOperands;
    } else {
        variableName = variableName1;
    }
    if (// Column name not specified
    length < 3) {
        if (variableName == null)
            variableName = v.nameString();
        EquationSet container = v.container;
        if (// regular part
        container.connectionBindings == null) {
            dependOnIndex(v, container);
        } else // connection
        {
            // depend on all endpoints
            for (ConnectionBinding c : container.connectionBindings) {
                dependOnIndex(v, c.endpoint);
            }
        }
    }
}
Also used : Operator(gov.sandia.n2a.language.Operator) EquationSet(gov.sandia.n2a.eqset.EquationSet) Constant(gov.sandia.n2a.language.Constant) ConnectionBinding(gov.sandia.n2a.eqset.EquationSet.ConnectionBinding) Text(gov.sandia.n2a.language.type.Text)

Example 15 with EquationSet

use of gov.sandia.n2a.eqset.EquationSet in project n2a by frothga.

the class BackendDataC method setGlobalNeedPath.

/**
 *        @param s The equation set directly associated with this backend data.
 */
public void setGlobalNeedPath(EquationSet s) {
    EquationSet c = s.container;
    // Don't set flag, because we know that path() will return "".
    if (c == null)
        return;
    needGlobalPath = true;
    setParentNeedPath(s);
}
Also used : EquationSet(gov.sandia.n2a.eqset.EquationSet)

Aggregations

EquationSet (gov.sandia.n2a.eqset.EquationSet)34 Variable (gov.sandia.n2a.eqset.Variable)10 AccessVariable (gov.sandia.n2a.language.AccessVariable)9 ConnectionBinding (gov.sandia.n2a.eqset.EquationSet.ConnectionBinding)7 ArrayList (java.util.ArrayList)7 Operator (gov.sandia.n2a.language.Operator)6 Scalar (gov.sandia.n2a.language.type.Scalar)6 MPart (gov.sandia.n2a.eqset.MPart)5 VariableReference (gov.sandia.n2a.eqset.VariableReference)4 Constant (gov.sandia.n2a.language.Constant)4 Type (gov.sandia.n2a.language.Type)4 Visitor (gov.sandia.n2a.language.Visitor)4 TreeSet (java.util.TreeSet)4 EventSource (gov.sandia.n2a.backend.internal.InternalBackendData.EventSource)3 EventTarget (gov.sandia.n2a.backend.internal.InternalBackendData.EventTarget)3 MNode (gov.sandia.n2a.db.MNode)3 ParseException (gov.sandia.n2a.language.ParseException)3 Text (gov.sandia.n2a.language.type.Text)3 AbortRun (gov.sandia.n2a.plugins.extpoints.Backend.AbortRun)3 FileNotFoundException (java.io.FileNotFoundException)3