Search in sources :

Example 16 with Text

use of gov.sandia.n2a.language.type.Text in project n2a by frothga.

the class BuildMatrix method simplify.

public Operator simplify(Variable from, boolean evalOnly) {
    int cols = operands.length;
    if (cols == 0)
        return this;
    int rows = operands[0].length;
    if (rows == 0)
        return this;
    // potential constant to replace us
    Matrix A = new MatrixDense(rows, cols);
    // any element that is not constant will change this to false
    boolean isConstant = true;
    // for fixed-point analysis
    int cent = 0;
    int pow = 0;
    int count = 0;
    for (int c = 0; c < cols; c++) {
        for (int r = 0; r < rows; r++) {
            if (operands[c][r] == null) {
                A.set(r, c, 0);
            } else {
                operands[c][r] = operands[c][r].simplify(from, evalOnly);
                // stop building A if we already know we are not constant
                if (!isConstant)
                    continue;
                if (operands[c][r] instanceof Constant) {
                    Constant op = (Constant) operands[c][r];
                    Type o = op.value;
                    if (o instanceof Scalar) {
                        double v = ((Scalar) o).value;
                        A.set(r, c, v);
                        if (v != 0) {
                            int tempCent = MSB / 2;
                            if (op.unitValue != null) {
                                int bits = (int) Math.ceil(op.unitValue.digits * Math.log(10) / Math.log(2));
                                tempCent = Math.max(tempCent, bits - 1);
                                tempCent = Math.min(tempCent, MSB);
                            }
                            cent += tempCent;
                            pow += Math.getExponent(v);
                            count++;
                        }
                    } else if (o instanceof Text)
                        A.set(r, c, Double.valueOf(((Text) o).value));
                    else if (o instanceof Matrix)
                        A.set(r, c, ((Matrix) o).get(0, 0));
                    else
                        throw new EvaluationException("Can't construct matrix element from the given type.");
                } else {
                    isConstant = false;
                }
            }
        }
    }
    if (isConstant) {
        from.changed = true;
        Constant result = new Constant(A);
        result.parent = parent;
        if (count > 0) {
            cent /= count;
            pow /= count;
            result.center = cent;
            result.exponent = pow + MSB - cent;
        } else {
            result.center = MSB / 2;
            result.exponent = MSB - result.center;
        }
        return result;
    }
    return this;
}
Also used : Matrix(gov.sandia.n2a.language.type.Matrix) ASTConstant(gov.sandia.n2a.language.parse.ASTConstant) MatrixDense(gov.sandia.n2a.linear.MatrixDense) Text(gov.sandia.n2a.language.type.Text) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 17 with Text

use of gov.sandia.n2a.language.type.Text in project n2a by frothga.

the class Input method eval.

public Type eval(Instance context) {
    double line = Double.NEGATIVE_INFINITY;
    Type op1 = null;
    if (operands.length > 1)
        op1 = operands[1].eval(context);
    if (op1 instanceof Scalar)
        line = ((Scalar) op1).value;
    Holder H = getRow(context, line);
    if (H == null)
        return getType();
    int c = -1;
    boolean namedColumn = false;
    if (operands.length > 2) {
        Type columnSpec = operands[2].eval(context);
        if (columnSpec instanceof Text) {
            Integer columnMapping = H.columnMap.get(((Text) columnSpec).value);
            if (columnMapping == null)
                return new Scalar(0);
            c = columnMapping;
            namedColumn = true;
        } else // Otherwise, just assume it is a Scalar
        {
            c = (int) Math.round(((Scalar) columnSpec).value);
        }
    }
    int columns = H.currentValues.length;
    int lastColumn = columns - 1;
    if (H.smooth && line >= H.currentLine && Double.isFinite(H.currentLine) && !Double.isNaN(H.nextLine)) {
        // This should still work, even if line < H.currentLine.
        double b = (line - H.currentLine) / (H.nextLine - H.currentLine);
        double b1 = 1 - b;
        if (c >= 0) {
            // time column is not included in raw index
            if (H.time && !namedColumn && c >= H.timeColumn)
                c++;
            if (c >= columns)
                c = lastColumn;
            return new Scalar(b * H.nextValues[c] + b1 * H.currentValues[c]);
        } else {
            if (H.Alast == line)
                return H.A;
            // Create a new matrix
            if (columns > 1) {
                columns--;
                H.A = new MatrixDense(1, columns);
                int from = 0;
                for (int to = 0; to < columns; to++) {
                    if (from == H.timeColumn)
                        from++;
                    H.A.set(0, to, b * H.nextValues[from] + b1 * H.currentValues[from]);
                    from++;
                }
            } else // There is always at least 1 column, enforced by Holder.
            {
                H.A = new MatrixDense(1, 1);
                H.A.set(0, 0, b * H.nextValues[0] + b1 * H.currentValues[0]);
            }
            H.Alast = line;
            return H.A;
        }
    } else {
        if (c >= 0) {
            // time column is not included in raw index
            if (H.time && !namedColumn && c >= H.timeColumn)
                c++;
            if (c >= columns)
                c = lastColumn;
            return new Scalar(H.currentValues[c]);
        } else {
            if (H.Alast == H.currentLine)
                return H.A;
            // Create a new matrix
            if (H.time && columns > 1) {
                columns--;
                H.A = new MatrixDense(1, columns);
                int from = 0;
                for (int to = 0; to < columns; to++) {
                    if (from == H.timeColumn)
                        from++;
                    H.A.set(0, to, H.currentValues[from++]);
                }
            } else {
                H.A = new MatrixDense(H.currentValues, 0, 1, columns, columns, 1);
            }
            H.Alast = H.currentLine;
            return H.A;
        }
    }
}
Also used : Type(gov.sandia.n2a.language.Type) MatrixDense(gov.sandia.n2a.linear.MatrixDense) Text(gov.sandia.n2a.language.type.Text) Scalar(gov.sandia.n2a.language.type.Scalar)

Example 18 with Text

use of gov.sandia.n2a.language.type.Text in project n2a by frothga.

the class RendererPython method render.

public boolean render(Operator op) {
    if (op instanceof Add) {
        Add a = (Add) op;
        // Check if this is a string expression
        if (a.name != null) {
            result.append(a.name);
            return true;
        }
        return false;
    }
    if (op instanceof AccessElement) {
        AccessElement ae = (AccessElement) op;
        ae.operands[0].render(this);
        if (ae.operands.length >= 2) {
            result.append("[");
            ae.operands[1].render(this);
            if (ae.operands.length >= 3) {
                result.append(",");
                ae.operands[2].render(this);
            }
            result.append("]");
        }
        return true;
    }
    if (op instanceof AccessVariable) {
        AccessVariable av = (AccessVariable) op;
        result.append(job.resolve(av.reference, this, false));
        return true;
    }
    if (op instanceof AND) {
        AND and = (AND) op;
        and.render(this, " and ");
        return true;
    }
    if (op instanceof BuildMatrix) {
        BuildMatrix b = (BuildMatrix) op;
        result.append(b.name);
        return true;
    }
    if (op instanceof Constant) {
        Constant c = (Constant) op;
        Type o = c.value;
        if (o instanceof Scalar) {
            result.append(print(((Scalar) o).value));
            return true;
        }
        if (o instanceof Text) {
            result.append("\"" + o.toString() + "\"");
            return true;
        }
        if (o instanceof Matrix) {
            result.append(c.name);
            return true;
        }
        return false;
    }
    if (op instanceof Event) {
        Event e = (Event) op;
        // The cast to bool gets rid of the specific numeric value from flags.
        // If used in a numeric expression, it will convert to either 1 or 0.
        result.append("bool (flags & 0x1 << " + e.eventType.valueIndex + ")");
        return true;
    }
    if (op instanceof Exp) {
        Exp e = (Exp) op;
        Operator a = e.operands[0];
        result.append("exp(");
        a.render(this);
        result.append(")");
        return true;
    }
    if (op instanceof Gaussian) {
        Gaussian g = (Gaussian) op;
        result.append("gaussian(");
        if (g.operands.length > 0) {
            g.operands[0].render(this);
        }
        result.append(")");
        return true;
    }
    if (op instanceof Grid) {
        // TODO: needs library implementation
        Grid g = (Grid) op;
        boolean raw = g.operands.length >= 5 && g.operands[4].getString().contains("raw");
        result.append("grid");
        if (raw)
            result.append("Raw");
        result.append("(");
        int count = Math.min(4, g.operands.length);
        if (count > 0)
            g.operands[0].render(this);
        for (int i = 1; i < count; i++) {
            result.append(", ");
            g.operands[i].render(this);
        }
        result.append(")");
        return true;
    }
    if (op instanceof Input) {
        // TODO: needs library implementation
        Input i = (Input) op;
        String mode = "";
        if (i.operands.length == 2)
            mode = i.operands[1].getString();
        else if (i.operands.length >= 4)
            mode = i.operands[3].getString();
        if (mode.contains("columns")) {
            result.append(i.name + "->getColumns ()");
        } else {
            Operator op1 = i.operands[1];
            Operator op2 = i.operands[2];
            result.append(i.name + ".get");
            if (mode.contains("raw"))
                result.append("Raw");
            result.append("(");
            op1.render(this);
            result.append(", ");
            op2.render(this);
            result.append(")");
        }
        return true;
    }
    if (op instanceof Log) {
        Log l = (Log) op;
        Operator a = l.operands[0];
        result.append("log(");
        a.render(this);
        return true;
    }
    if (op instanceof Modulo) {
        Modulo m = (Modulo) op;
        Operator a = m.operand0;
        Operator b = m.operand1;
        a.render(this);
        result.append(" % ");
        b.render(this);
        return true;
    }
    if (op instanceof Norm) {
        Norm n = (Norm) op;
        Operator A = n.operands[0];
        result.append("numpy.linalg.norm(");
        A.render(this);
        result.append(", ");
        n.operands[1].render(this);
        result.append(")");
        return true;
    }
    if (op instanceof OR) {
        OR or = (OR) op;
        or.render(this, " or ");
        return true;
    }
    if (op instanceof Output) {
        Output o = (Output) op;
        result.append(o.name + "->trace (Simulator::instance.currentEvent->t, ");
        if (// column name is explicit
        o.hasColumnName) {
            o.operands[2].render(this);
        } else // column name is generated, so use prepared string value
        {
            result.append(o.columnName);
        }
        result.append(", ");
        o.operands[1].render(this);
        result.append(")");
        return true;
    }
    if (op instanceof Power) {
        Power p = (Power) op;
        Operator a = p.operand0;
        Operator b = p.operand1;
        result.append("pow(");
        a.render(this);
        result.append(", ");
        b.render(this);
        result.append(")");
        return true;
    }
    if (op instanceof ReadMatrix) {
        ReadMatrix r = (ReadMatrix) op;
        String mode = "";
        int lastParm = r.operands.length - 1;
        if (lastParm > 0) {
            if (r.operands[lastParm] instanceof Constant) {
                Constant c = (Constant) r.operands[lastParm];
                if (c.value instanceof Text) {
                    mode = ((Text) c.value).value;
                }
            }
        }
        if (mode.equals("rows")) {
            result.append(r.name + "->rows ()");
        } else if (mode.equals("columns")) {
            result.append(r.name + "->columns ()");
        } else {
            result.append(r.name + "->get");
            if (mode.equals("raw"))
                result.append("Raw");
            result.append("(");
            r.operands[1].render(this);
            result.append(", ");
            r.operands[2].render(this);
            result.append(")");
        }
        return true;
    }
    if (op instanceof SquareRoot) {
        SquareRoot s = (SquareRoot) op;
        Operator a = s.operands[0];
        result.append("sqrt(");
        a.render(this);
        return true;
    }
    if (op instanceof Tangent) {
        Tangent t = (Tangent) op;
        Operator a = t.operands[0];
        result.append("tan(");
        a.render(this);
        result.append(")");
        return true;
    }
    if (op instanceof Uniform) {
        Uniform u = (Uniform) op;
        result.append("uniform(");
        if (u.operands.length > 0) {
            u.operands[0].render(this);
        }
        result.append(")");
        return true;
    }
    return super.render(op);
}
Also used : Add(gov.sandia.n2a.language.operator.Add) Operator(gov.sandia.n2a.language.Operator) Constant(gov.sandia.n2a.language.Constant) Grid(gov.sandia.n2a.language.function.Grid) Uniform(gov.sandia.n2a.language.function.Uniform) Scalar(gov.sandia.n2a.language.type.Scalar) Input(gov.sandia.n2a.language.function.Input) ReadMatrix(gov.sandia.n2a.language.function.ReadMatrix) BuildMatrix(gov.sandia.n2a.language.BuildMatrix) Matrix(gov.sandia.n2a.language.type.Matrix) SquareRoot(gov.sandia.n2a.language.function.SquareRoot) BuildMatrix(gov.sandia.n2a.language.BuildMatrix) Output(gov.sandia.n2a.language.function.Output) OR(gov.sandia.n2a.language.operator.OR) AccessVariable(gov.sandia.n2a.language.AccessVariable) Log(gov.sandia.n2a.language.function.Log) Modulo(gov.sandia.n2a.language.operator.Modulo) Text(gov.sandia.n2a.language.type.Text) Tangent(gov.sandia.n2a.language.function.Tangent) ReadMatrix(gov.sandia.n2a.language.function.ReadMatrix) Type(gov.sandia.n2a.language.Type) AND(gov.sandia.n2a.language.operator.AND) Event(gov.sandia.n2a.language.function.Event) Norm(gov.sandia.n2a.language.function.Norm) Gaussian(gov.sandia.n2a.language.function.Gaussian) AccessElement(gov.sandia.n2a.language.AccessElement) Exp(gov.sandia.n2a.language.function.Exp) Power(gov.sandia.n2a.language.operator.Power)

Example 19 with Text

use of gov.sandia.n2a.language.type.Text in project n2a by frothga.

the class RendererC method render.

public boolean render(Operator op) {
    for (ProvideOperator po : job.extensions) {
        Boolean result = po.render(this, op);
        if (result != null)
            return result;
    }
    if (op instanceof Add) {
        Add a = (Add) op;
        // Check if this is a string expression
        if (a.name != null) {
            result.append(a.name);
            return true;
        }
        return false;
    }
    if (op instanceof AccessElement) {
        AccessElement ae = (AccessElement) op;
        ae.operands[0].render(this);
        if (ae.operands.length == 2) {
            result.append("[");
            ae.operands[1].render(this);
            result.append("]");
        } else if (ae.operands.length == 3) {
            result.append("(");
            ae.operands[1].render(this);
            result.append(",");
            ae.operands[2].render(this);
            result.append(")");
        }
        return true;
    }
    if (op instanceof AccessVariable) {
        AccessVariable av = (AccessVariable) op;
        result.append(job.resolve(av.reference, this, false));
        return true;
    }
    if (op instanceof Atan) {
        Atan atan = (Atan) op;
        int shift = atan.exponent - atan.exponentNext;
        if (useExponent && shift != 0)
            result.append("(");
        if (atan.operands.length > 1 || useExponent)
            result.append("atan2 (");
        else
            result.append("atan (");
        Operator y = atan.operands[0];
        if (y.getType() instanceof Matrix) {
            y.render(this);
            result.append("[1], ");
            y.render(this);
            result.append("[0]");
        } else {
            y.render(this);
            if (atan.operands.length > 1) {
                result.append(", ");
                // x
                atan.operands[1].render(this);
            } else if (useExponent) {
                int shiftX = Operator.MSB - y.exponent;
                int x = shiftX >= 0 ? 0x1 << shiftX : 0;
                result.append(", " + x);
            }
        }
        result.append(")");
        if (useExponent && shift != 0)
            result.append(printShift(shift) + ")");
        return true;
    }
    if (op instanceof BuildMatrix) {
        BuildMatrix b = (BuildMatrix) op;
        result.append(b.name);
        return true;
    }
    if (op instanceof Columns) {
        Columns c = (Columns) op;
        c.operands[0].render(this);
        result.append(".columns ()");
        return true;
    }
    if (op instanceof Constant) {
        Constant c = (Constant) op;
        Type o = c.value;
        if (o instanceof Scalar) {
            result.append(print(((Scalar) o).value, c.exponentNext));
            return true;
        }
        if (o instanceof Text) {
            result.append("\"" + o.toString() + "\"");
            return true;
        }
        if (o instanceof Matrix) {
            result.append(c.name);
            return true;
        }
        return false;
    }
    if (op instanceof Delay) {
        Delay d = (Delay) op;
        if (d.operands.length == 1) {
            result.append("(");
            d.operands[0].render(this);
            result.append(")");
            return true;
        }
        result.append("delay" + d.index + ".step (Simulator<" + job.T + ">::instance.currentEvent->t, ");
        d.operands[1].render(this);
        result.append(", ");
        d.operands[0].render(this);
        result.append(", ");
        if (d.operands.length > 2)
            d.operands[2].render(this);
        else
            result.append("0");
        result.append(")");
        return true;
    }
    if (op instanceof Event) {
        Event e = (Event) op;
        // The cast to bool gets rid of the specific numeric value from flags.
        // If used in a numeric expression, it should convert to either 1 or 0.
        result.append("((bool) (flags & (" + bed.localFlagType + ") 0x1 << " + e.eventType.valueIndex + "))");
        return true;
    }
    if (op instanceof Exp) {
        Exp e = (Exp) op;
        Operator a = e.operands[0];
        result.append("exp (");
        a.render(this);
        if (useExponent)
            result.append(", " + e.exponentNext);
        result.append(")");
        return true;
    }
    if (op instanceof Gaussian) {
        Gaussian g = (Gaussian) op;
        result.append("gaussian<" + job.T + "> (");
        if (g.operands.length > 0) {
            g.operands[0].render(this);
        }
        result.append(")");
        return true;
    }
    if (op instanceof Grid) {
        Grid g = (Grid) op;
        boolean raw = g.operands.length >= 5 && g.operands[4].getString().contains("raw");
        int shift = g.exponent - g.exponentNext;
        if (useExponent && shift != 0)
            result.append("(");
        result.append("grid");
        if (raw)
            result.append("Raw");
        result.append("<" + job.T + "> (");
        int count = Math.min(4, g.operands.length);
        if (count > 0)
            g.operands[0].render(this);
        for (int i = 1; i < count; i++) {
            result.append(", ");
            g.operands[i].render(this);
        }
        result.append(")");
        if (useExponent && shift != 0)
            result.append(printShift(shift) + ")");
        return true;
    }
    if (op instanceof HyperbolicTangent) {
        HyperbolicTangent t = (HyperbolicTangent) op;
        Operator a = t.operands[0];
        result.append("tanh (");
        a.render(this);
        result.append(")");
        return true;
    }
    if (op instanceof Input) {
        Input i = (Input) op;
        result.append(i.name + "->get (");
        if (// return matrix
        i.operands.length < 3 || i.operands[2].getDouble() < 0) {
            boolean time = i.getMode().contains("time");
            String defaultLine = time ? "-INFINITY" : "0";
            if (i.operands.length > 1) {
                Operator op1 = i.operands[1];
                if (// expression for line
                op1.getType() instanceof Scalar)
                    // expression for line
                    op1.render(this);
                else
                    // op1 is probably the mode flag
                    result.append(defaultLine);
            } else // line is not specified. We're probably just retrieving a dummy matrix to get column count.
            {
                result.append(defaultLine);
            }
        } else // return scalar
        {
            i.operands[1].render(this);
            result.append(", ");
            i.operands[2].render(this);
        }
        result.append(")");
        return true;
    }
    if (op instanceof Log) {
        Log l = (Log) op;
        Operator a = l.operands[0];
        result.append("log (");
        a.render(this);
        if (useExponent)
            result.append(", " + a.exponentNext + ", " + l.exponentNext);
        result.append(")");
        return true;
    }
    if (op instanceof Max) {
        Max m = (Max) op;
        for (int i = 0; i < m.operands.length - 1; i++) {
            Operator a = m.operands[i];
            result.append("max (");
            renderType(a);
            result.append(", ");
        }
        Operator b = m.operands[m.operands.length - 1];
        renderType(b);
        for (int i = 0; i < m.operands.length - 1; i++) result.append(")");
        return true;
    }
    if (op instanceof Min) {
        Min m = (Min) op;
        for (int i = 0; i < m.operands.length - 1; i++) {
            Operator a = m.operands[i];
            result.append("min (");
            renderType(a);
            result.append(", ");
        }
        Operator b = m.operands[m.operands.length - 1];
        renderType(b);
        for (int i = 0; i < m.operands.length - 1; i++) result.append(")");
        return true;
    }
    if (op instanceof Modulo) {
        Modulo m = (Modulo) op;
        Operator a = m.operand0;
        Operator b = m.operand1;
        result.append("modFloor (");
        moduloParam(a);
        result.append(", ");
        moduloParam(b);
        result.append(")");
        return true;
    }
    if (op instanceof Norm) {
        Norm n = (Norm) op;
        Operator A = n.operands[0];
        result.append("norm (");
        A.render(this);
        result.append(", ");
        n.operands[1].render(this);
        if (useExponent)
            result.append(", " + A.exponentNext + ", " + n.exponentNext);
        result.append(")");
        return true;
    }
    if (op instanceof Output) {
        Output o = (Output) op;
        result.append(o.name + "->trace (Simulator<" + job.T + ">::instance.currentEvent->t, ");
        if (// column name is explicit
        o.hasColumnName) {
            o.operands[2].render(this);
        } else // column name is generated, so use prepared string value
        {
            result.append(o.columnName);
        }
        result.append(", ");
        o.operands[1].render(this);
        if (useExponent)
            result.append(", " + o.operands[1].exponentNext);
        result.append(", ");
        if (// No mode string
        o.operands.length < 4) {
            // null
            result.append("0");
        } else if (// Mode string is constant
        o.operands[3] instanceof Constant) {
            result.append("\"" + o.operands[3] + "\"");
        } else if (// Mode string is calculated
        o.operands[3] instanceof Add) {
            Add a = (Add) o.operands[3];
            // No need for cast or call c_str()
            result.append(a.name);
        }
        // else badness
        result.append(")");
        return true;
    }
    if (op instanceof Power) {
        Power p = (Power) op;
        Operator a = p.operand0;
        Operator b = p.operand1;
        result.append("pow (");
        a.render(this);
        result.append(", ");
        b.render(this);
        if (useExponent)
            result.append(", " + a.exponentNext + ", " + p.exponentNext);
        result.append(")");
        return true;
    }
    if (op instanceof Pulse) {
        Pulse p = (Pulse) op;
        Operator t = p.operands[0];
        result.append("pulse (");
        renderType(t);
        for (int i = 1; i < p.operands.length; i++) {
            result.append(", ");
            renderType(p.operands[i]);
        }
        result.append(")");
        return true;
    }
    if (op instanceof ReadMatrix) {
        ReadMatrix r = (ReadMatrix) op;
        // Currently, ReadMatrix sets its exponent = exponentNext, so we will never do a shift here.
        // Any shifting should be handled by matrixHelper while loading and converting the matrix to integer.
        // matrices are held in pointers, so need to dereference
        result.append("*" + r.name + "->A");
        return true;
    }
    if (op instanceof Rows) {
        Rows r = (Rows) op;
        r.operands[0].render(this);
        result.append(".rows ()");
        return true;
    }
    if (op instanceof Sat) {
        Sat s = (Sat) op;
        Operator a = s.operands[0];
        Operator lower = s.operands[1];
        Operator upper;
        if (s.operands.length >= 3)
            upper = s.operands[2];
        else
            upper = lower;
        result.append("max (");
        if (s.operands.length == 2)
            result.append("-1 * (");
        renderType(lower);
        if (s.operands.length == 2)
            result.append(")");
        result.append(", min (");
        renderType(upper);
        result.append(", ");
        renderType(a);
        result.append("))");
        return true;
    }
    if (op instanceof SquareRoot) {
        SquareRoot s = (SquareRoot) op;
        Operator a = s.operands[0];
        result.append("sqrt (");
        a.render(this);
        if (useExponent)
            result.append(", " + a.exponentNext + ", " + s.exponentNext);
        result.append(")");
        return true;
    }
    if (op instanceof SumSquares) {
        SumSquares ss = (SumSquares) op;
        Operator A = ss.operands[0];
        result.append("sumSquares (");
        A.render(this);
        if (useExponent)
            result.append(", " + A.exponentNext + ", " + ss.exponentNext);
        result.append(")");
        return true;
    }
    if (op instanceof Tangent) {
        Tangent t = (Tangent) op;
        Operator a = t.operands[0];
        result.append("tan (");
        a.render(this);
        if (useExponent)
            result.append(", " + a.exponentNext + ", " + t.exponentNext);
        result.append(")");
        return true;
    }
    if (op instanceof Uniform) {
        Uniform u = (Uniform) op;
        result.append("uniform<" + job.T + "> (");
        for (int i = 0; i < u.operands.length; i++) {
            if (i > 0)
                result.append(", ");
            u.operands[i].render(this);
        }
        result.append(")");
        return true;
    }
    return super.render(op);
}
Also used : Add(gov.sandia.n2a.language.operator.Add) Operator(gov.sandia.n2a.language.Operator) Max(gov.sandia.n2a.language.function.Max) Constant(gov.sandia.n2a.language.Constant) SumSquares(gov.sandia.n2a.language.function.SumSquares) Grid(gov.sandia.n2a.language.function.Grid) Sat(gov.sandia.n2a.language.function.Sat) Uniform(gov.sandia.n2a.language.function.Uniform) Delay(gov.sandia.n2a.language.function.Delay) Scalar(gov.sandia.n2a.language.type.Scalar) Input(gov.sandia.n2a.language.function.Input) ReadMatrix(gov.sandia.n2a.language.function.ReadMatrix) BuildMatrix(gov.sandia.n2a.language.BuildMatrix) Matrix(gov.sandia.n2a.language.type.Matrix) HyperbolicTangent(gov.sandia.n2a.language.function.HyperbolicTangent) SquareRoot(gov.sandia.n2a.language.function.SquareRoot) BuildMatrix(gov.sandia.n2a.language.BuildMatrix) Output(gov.sandia.n2a.language.function.Output) Atan(gov.sandia.n2a.language.function.Atan) Rows(gov.sandia.n2a.language.function.Rows) AccessVariable(gov.sandia.n2a.language.AccessVariable) Log(gov.sandia.n2a.language.function.Log) Modulo(gov.sandia.n2a.language.operator.Modulo) Pulse(gov.sandia.n2a.language.function.Pulse) Columns(gov.sandia.n2a.language.function.Columns) Text(gov.sandia.n2a.language.type.Text) Tangent(gov.sandia.n2a.language.function.Tangent) HyperbolicTangent(gov.sandia.n2a.language.function.HyperbolicTangent) ReadMatrix(gov.sandia.n2a.language.function.ReadMatrix) Type(gov.sandia.n2a.language.Type) Min(gov.sandia.n2a.language.function.Min) Event(gov.sandia.n2a.language.function.Event) Norm(gov.sandia.n2a.language.function.Norm) Gaussian(gov.sandia.n2a.language.function.Gaussian) AccessElement(gov.sandia.n2a.language.AccessElement) Exp(gov.sandia.n2a.language.function.Exp) Power(gov.sandia.n2a.language.operator.Power)

Example 20 with Text

use of gov.sandia.n2a.language.type.Text in project n2a by frothga.

the class InternalBackendData method analyzeEvents.

public static void analyzeEvents(EquationSet s, List<EventTarget> eventTargets, List<Variable> eventReferences, List<Delay> delays) {
    class EventVisitor implements Visitor {

        public boolean found;

        public boolean visit(Operator op) {
            if (op instanceof Delay) {
                delays.add((Delay) op);
            } else if (op instanceof Event) {
                found = true;
                Event de = (Event) op;
                if (// this event has not yet been analyzed
                de.eventType == null) {
                    final EventTarget et = new EventTarget(de);
                    int targetIndex = eventTargets.indexOf(et);
                    if (// event target already exists
                    targetIndex >= 0) {
                        de.eventType = eventTargets.get(targetIndex);
                    } else // we must create a new event target, or more properly, fill in the event target we just used as a query object
                    {
                        // Create an entry and save the index
                        targetIndex = eventTargets.size();
                        eventTargets.add(et);
                        de.eventType = et;
                        et.container = s;
                        // Determine edge type
                        if (de.operands.length < 3) {
                            et.edge = EventTarget.RISE;
                        } else if (de.operands[2] instanceof Constant) {
                            Constant c = (Constant) de.operands[2];
                            if (c.value instanceof Text) {
                                Text t = (Text) c.value;
                                if (t.value.equalsIgnoreCase("nonzero"))
                                    et.edge = EventTarget.NONZERO;
                                else if (t.value.equalsIgnoreCase("change"))
                                    et.edge = EventTarget.CHANGE;
                                else if (t.value.equalsIgnoreCase("fall"))
                                    et.edge = EventTarget.FALL;
                                else
                                    et.edge = EventTarget.RISE;
                            } else {
                                Backend.err.get().println("ERROR: event() edge type must be a string.");
                                throw new Backend.AbortRun();
                            }
                        } else {
                            Backend.err.get().println("ERROR: event() edge type must be constant.");
                            throw new Backend.AbortRun();
                        }
                        // Allocate auxiliary variable
                        if (de.operands[0] instanceof AccessVariable) {
                            AccessVariable av = (AccessVariable) de.operands[0];
                            VariableReference reference = av.reference;
                            Variable v = reference.variable;
                            // then the user has broken the rule that we can't see temporaries in other parts.
                            if (v.hasAttribute("temporary") && v.container != s) {
                                Backend.err.get().println("WARNING: Cannot be temporary due to event monitor: " + v.fullName() + " from " + s.name);
                                v.removeAttribute("temporary");
                            }
                            // so fall through to the !trackOne case below.
                            if (!v.hasAttribute("temporary")) {
                                // ensure it's buffered, so we can detect change
                                v.addAttribute("externalRead");
                                et.trackOne = true;
                                // just a holder for the reference
                                et.track = new Variable("");
                                et.track.reference = reference;
                            }
                        }
                        if (// Expression, so create auxiliary variable. Aux not needed for NONZERO, because no change detection.
                        !et.trackOne && et.edge != EventTarget.NONZERO) {
                            et.track = new Variable("$eventAux" + targetIndex);
                            et.track.container = s;
                            et.track.type = new Scalar(0);
                            et.track.reference = new VariableReference();
                            et.track.reference.variable = et.track;
                            // Make executable so it can be directly evaluated during the init cycle.
                            et.track.equations = new TreeSet<EquationEntry>();
                            EquationEntry ee = new EquationEntry(et.track, "");
                            et.track.equations.add(ee);
                            ee.expression = et.event.operands[0].deepCopy();
                            ee.expression.addDependencies(et.track);
                        }
                        // Locate any temporaries for evaluation.
                        // Tie into the dependency graph using a phantom variable (which can go away afterward without damaging the graph).
                        // TODO: for more efficiency, we could have separate lists of temporaries for the condition and delay operands
                        // TODO: for more efficiency, cut off search for temporaries along a given branch of the tree at the first non-temporary.
                        final Variable phantom = new Variable("event");
                        phantom.uses = new IdentityHashMap<Variable, Integer>();
                        phantom.container = s;
                        et.event.visit(new Visitor() {

                            public boolean visit(Operator op) {
                                if (op instanceof AccessVariable) {
                                    AccessVariable av = (AccessVariable) op;
                                    Variable v = av.reference.variable;
                                    if (v.hasAttribute("temporary") && !phantom.uses.containsKey(v))
                                        phantom.uses.put(v, 1);
                                    return false;
                                }
                                return true;
                            }
                        });
                        // Scan all variables in equation set to see if we need them
                        for (Variable t : s.ordered) {
                            if (t.hasAttribute("temporary") && phantom.dependsOn(t) != null)
                                et.dependencies.add(t);
                        }
                        // Note the default is already set to -1 (no care)
                        class DelayVisitor implements Visitor {

                            TreeSet<EquationSet> containers = new TreeSet<EquationSet>();

                            public boolean visit(Operator op) {
                                if (op instanceof AccessVariable) {
                                    AccessVariable av = (AccessVariable) op;
                                    // could include the target part itself, if in fact we use local variables
                                    containers.add(av.reference.variable.container);
                                    return false;
                                }
                                return true;
                            }
                        }
                        DelayVisitor dv = new DelayVisitor();
                        if (de.operands.length >= 2) {
                            if (de.operands[1] instanceof Constant) {
                                Constant c = (Constant) de.operands[1];
                                et.delay = (float) ((Scalar) c.value).value;
                                if (et.delay < 0)
                                    et.delay = -1;
                            } else {
                                // indicates that we need to evaluate delay at run time
                                et.delay = -2;
                                de.operands[1].visit(dv);
                            }
                        }
                        // Set up monitors in source parts
                        class ConditionVisitor implements Visitor {

                            TreeSet<EquationSet> containers = new TreeSet<EquationSet>();

                            public boolean visit(Operator op) {
                                if (op instanceof AccessVariable) {
                                    AccessVariable av = (AccessVariable) op;
                                    Variable v = av.reference.variable;
                                    EquationSet sourceContainer = v.container;
                                    containers.add(sourceContainer);
                                    // Set up monitors for values that can vary during update.
                                    if (!v.hasAttribute("constant") && !v.hasAttribute("initOnly") && !et.monitors(sourceContainer)) {
                                        EventSource es = new EventSource(sourceContainer, et);
                                        // null means self-reference, a special case handled in Part
                                        if (sourceContainer != s)
                                            es.reference = av.reference;
                                        et.sources.add(es);
                                    }
                                    return false;
                                }
                                return true;
                            }
                        }
                        ConditionVisitor cv = new ConditionVisitor();
                        de.operands[0].visit(cv);
                        // Special case for event with no references that vary
                        if (et.sources.isEmpty()) {
                            // We can avoid creating a self monitor if we know for certain that the event will never fire
                            boolean neverFires = false;
                            if (de.operands[0] instanceof Constant) {
                                if (et.edge == EventTarget.NONZERO) {
                                    Type op0 = ((Constant) de.operands[0]).value;
                                    if (op0 instanceof Scalar) {
                                        neverFires = ((Scalar) op0).value == 0;
                                    } else {
                                        Backend.err.get().println("ERROR: Condition for event() must resolve to a number.");
                                        throw new Backend.AbortRun();
                                    }
                                } else {
                                    neverFires = true;
                                }
                            }
                            if (!neverFires) {
                                EventSource es = new EventSource(s, et);
                                // This is a self-reference, so es.reference should be null.
                                et.sources.add(es);
                            }
                        }
                        // Determine if monitor needs to test every target, or if one representative target is sufficient
                        for (EventSource source : et.sources) {
                            // associated with any given source instance, so every target must be evaluated separately.
                            if (cv.containers.size() > 1)
                                source.testEach = true;
                            if (dv.containers.size() > 1 || (dv.containers.size() == 1 && dv.containers.first() != source.container))
                                source.delayEach = true;
                        }
                    }
                }
            }
            return true;
        }
    }
    EventVisitor eventVisitor = new EventVisitor();
    for (Variable v : s.variables) {
        eventVisitor.found = false;
        v.visit(eventVisitor);
        if ((eventVisitor.found || v.dependsOnEvent()) && v.reference.variable != v)
            eventReferences.add(v);
    }
}
Also used : Operator(gov.sandia.n2a.language.Operator) EquationSet(gov.sandia.n2a.eqset.EquationSet) AccessVariable(gov.sandia.n2a.language.AccessVariable) Variable(gov.sandia.n2a.eqset.Variable) AccessVariable(gov.sandia.n2a.language.AccessVariable) VariableReference(gov.sandia.n2a.eqset.VariableReference) Visitor(gov.sandia.n2a.language.Visitor) Constant(gov.sandia.n2a.language.Constant) IdentityHashMap(java.util.IdentityHashMap) Text(gov.sandia.n2a.language.type.Text) Delay(gov.sandia.n2a.language.function.Delay) Scalar(gov.sandia.n2a.language.type.Scalar) Type(gov.sandia.n2a.language.Type) Backend(gov.sandia.n2a.plugins.extpoints.Backend) TreeSet(java.util.TreeSet) Event(gov.sandia.n2a.language.function.Event) EquationEntry(gov.sandia.n2a.eqset.EquationEntry)

Aggregations

Text (gov.sandia.n2a.language.type.Text)21 Matrix (gov.sandia.n2a.language.type.Matrix)12 Scalar (gov.sandia.n2a.language.type.Scalar)12 Constant (gov.sandia.n2a.language.Constant)10 Operator (gov.sandia.n2a.language.Operator)10 Type (gov.sandia.n2a.language.Type)10 AccessVariable (gov.sandia.n2a.language.AccessVariable)7 Visitor (gov.sandia.n2a.language.Visitor)7 BuildMatrix (gov.sandia.n2a.language.BuildMatrix)6 Input (gov.sandia.n2a.language.function.Input)6 Output (gov.sandia.n2a.language.function.Output)6 ReadMatrix (gov.sandia.n2a.language.function.ReadMatrix)6 Simulator (gov.sandia.n2a.backend.internal.Simulator)5 EquationSet (gov.sandia.n2a.eqset.EquationSet)5 Variable (gov.sandia.n2a.eqset.Variable)5 Add (gov.sandia.n2a.language.operator.Add)5 Event (gov.sandia.n2a.language.function.Event)4 MatrixDense (gov.sandia.n2a.linear.MatrixDense)4 Backend (gov.sandia.n2a.plugins.extpoints.Backend)3 ConnectionMatrix (gov.sandia.n2a.eqset.EquationSet.ConnectionMatrix)2