Esempio n. 1
0
  // Converts a matlab engine mxArray (ma) variable to a Ptolemy II Token.
  // @param ma Pointer to the matlab engine variable's mxArray
  // structure as a java long.
  // @return Ptolemy II Token of type that corresponds to ma's type.
  // @exception IllegalActionException If ma cannot be obtained from
  // the matlab engine, or if the mxArray type is not one of
  // 'double', 'struct', 'char' or 'cell', or if not all elements of
  // an ArrayToken to be created are of the same type.
  // @see Engine
  private Token _convertMxArrayToToken(long ma, ConversionParameters par)
      throws IllegalActionException {
    String maClassStr = ptmatlabGetClassName(ma);
    int[] dims = ptmatlabGetDimensions(ma);
    int nRows = dims[0];
    int nCols = dims[1];
    boolean scalarStructs = (nCols == 1) && (nRows == 1);
    boolean scalarMatrices = (nCols == 1) && (nRows == 1) && par.getScalarMatrices;
    Token retval = null;

    if (maClassStr.equals("double")) {
      if (ptmatlabIsComplex(ma)) {
        Complex[][] a = ptmatlabGetComplexMatrix(ma, nRows, nCols);

        if (a == null) {
          throw new IllegalActionException("can't get complex matrix from matlab engine.");
        }

        if (scalarMatrices) {
          retval = new ComplexToken(a[0][0]);
        } else {
          retval = new ComplexMatrixToken(a);
        }
      } else {
        double[][] a = ptmatlabGetDoubleMatrix(ma, nRows, nCols);

        if (a == null) {
          throw new IllegalActionException("can't get double matrix from matlab engine.");
        }

        if (scalarMatrices) {
          double tmp = a[0][0];

          if (_doubleisInteger(tmp)) {
            retval = new IntToken((int) tmp);
          } else {
            retval = new DoubleToken(tmp);
          }
        } else {
          boolean allIntegers = par.getIntMatrices;

          for (int i = 0; allIntegers && (i < a.length); i++) {
            for (int j = 0; allIntegers && (j < a[0].length); j++) {
              allIntegers &= _doubleisInteger(a[i][j]);
            }
          }

          if (allIntegers) {
            int[][] tmp = new int[a.length][a[0].length];

            for (int i = 0; i < a.length; i++) {
              for (int j = 0; j < a[0].length; j++) {
                tmp[i][j] = (int) a[i][j];
              }
            }

            retval = new IntMatrixToken(tmp);
          } else {
            retval = new DoubleMatrixToken(a);
          }
        }
      }
    } else if (maClassStr.equals("logical")) {
      int[][] a = ptmatlabGetLogicalMatrix(ma, nRows, nCols);

      if (a == null) {
        throw new IllegalActionException("can't get logical matrix from matlab engine.");
      }

      if (scalarMatrices) {
        retval = new IntToken(a[0][0]);
      } else {
        retval = new IntMatrixToken(a);
      }
    } else if (maClassStr.equals("struct")) {
      int nfields = ptmatlabGetNumberOfFields(ma);
      Token[] ta = new Token[nCols];
      Token[] tr = new Token[nRows];
      String[] fieldNames = new String[nfields];

      for (int k = 0; k < nfields; k++) {
        fieldNames[k] = ptmatlabGetFieldNameByNumber(ma, k);
      }

      Token[] fieldValues = new Token[nfields];

      for (int n = 0; n < nRows; n++) {
        for (int m = 0; m < nCols; m++) {
          for (int k = 0; k < nfields; k++) {
            long fma = ptmatlabGetFieldByNumber(ma, k, n, m);

            if (fma != 0) {
              fieldValues[k] = _convertMxArrayToToken(fma, par);
            } else {
              throw new IllegalActionException(
                  "can't get field "
                      + fieldNames[k]
                      + "from matlab "
                      + "struct "
                      + nRows
                      + "x"
                      + nCols);
            }
          }

          ta[m] = new RecordToken(fieldNames, fieldValues);
        }

        tr[n] = new ArrayToken(ta);
      }

      if (scalarStructs) {
        retval = ((ArrayToken) tr[0]).getElement(0);
      } else {
        retval = new ArrayToken(tr);
      }
    } else if (maClassStr.equals("cell")) {
      Token[] ta = new Token[nCols];
      Token[] tr = new Token[nRows];

      for (int n = 0; n < nRows; n++) {
        boolean anyIntegers = false;
        boolean anyDoubles = false;

        for (int m = 0; m < nCols; m++) {
          long cma = ptmatlabGetCell(ma, n, m);

          if (cma != 0) {
            ta[m] = _convertMxArrayToToken(cma, par);

            // Track whether we get mixed types back
            if (ta[m] instanceof IntToken) {
              anyIntegers = true;
            } else if (ta[m] instanceof DoubleToken) {
              anyDoubles = true;
            }
          } // else - throw exception?
        }

        if (anyIntegers && anyDoubles) {
          for (int m = 0; m < ta.length; m++) {
            if (ta[m] instanceof IntToken) {
              ta[m] = DoubleToken.convert(ta[m]);
            }
          }
        }

        tr[n] = new ArrayToken(ta);

        // If not all tokens are of the same, this will throw
        // an exception.
      }

      if (nRows == 1) {
        retval = tr[0];
      } else {
        retval = new ArrayToken(tr);
      }
    } else if (maClassStr.equals("char")) {
      if (nRows == 1) {
        retval = new StringToken(ptmatlabGetString(ma, 0));
      } else {
        Token[] ta = new Token[nRows];

        for (int n = 0; n < nRows; n++) {
          ta[n] = new StringToken(ptmatlabGetString(ma, n));
        }

        retval = new ArrayToken(ta);
      }
    } else {
      throw new IllegalActionException(
          "no support for mxArray class " + maClassStr + " " + dims[0] + " x " + dims[1]);
    }

    return retval;
  }