/** Multiply arguments element by element. Returns result. */
  public Object mul(Object param1, Object param2) throws ParseException {

    if (param1 instanceof MatrixValueI && param2 instanceof MatrixValueI) {
      return mul((MatrixValueI) param1, (MatrixValueI) param2);
    } else if (param1 instanceof MatrixValueI) {
      MatrixValueI l = (MatrixValueI) param1;
      MatrixValueI res = Tensor.getInstance(l.getDim());
      for (int i = 0; i < res.getNumEles(); ++i) res.setEle(i, super.mul(l.getEle(i), param2));
      return res;
    } else if (param2 instanceof MatrixValueI) {
      MatrixValueI r = (MatrixValueI) param2;
      MatrixValueI res = Tensor.getInstance(r.getDim());
      for (int i = 0; i < res.getNumEles(); ++i) res.setEle(i, super.mul(param1, r.getEle(i)));
      return res;
    }
    return super.mul(param1, param2);
  }
  /** Multiply the inputs element by element putting the results in res. */
  public MatrixValueI calcValue(MatrixValueI res, MatrixValueI[] inputs) throws ParseException {

    int numArgs = inputs.length;
    int len = res.getNumEles();
    for (int i = 0; i < len; ++i) {
      Object ele = inputs[0].getEle(i);
      for (int j = 1; j < numArgs; ++j) ele = super.mul(ele, inputs[j].getEle(i));
      res.setEle(i, ele);
    }
    return res;
  }