Exemple #1
0
  public Matrix createVector(BitVector selector) {
    int rows = selector != null ? selector.countOnBits() : frame.size();
    Matrix m = new Matrix(rows, 1);

    for (int i = 0, j = 0; j < frame.size(); j++) {
      if (selector == null || selector.isOn(j)) {
        M rowValue = frame.object(j);

        try {
          Number numValue = (Number) numericField.get(rowValue);
          m.set(i, 0, numValue.doubleValue());

        } catch (IllegalAccessException e) {
          e.printStackTrace();
          throw new IllegalStateException(
              String.format(
                  "Couldn't access field %s: %s", numericField.getName(), e.getMessage()));
        }

        i++;
      }
    }

    return m;
  }
  public Matrix matrixAbjoint() { // 求伴随矩阵
    int i, j;
    Matrix matrix = new Matrix();

    matrix = Matrix.matrixCopy(this);
    matrix = matrix.matrixReverse().matrixNumMultiply(matrix.determinantValue());
    return matrix;
  }
  public Matrix matrixNumMultiply(double x) { // 矩阵乘以一个数
    int i, j;
    Matrix matrix = new Matrix(this);

    for (i = 0; i < matrix.getLine(); i++)
      for (j = 0; j < matrix.getRow(); j++) matrix.setElement(i, j, x * matrix.getElement(i, j));
    return matrix;
  }
  static void calculateEigenvector(String file, String chr, int binsize) throws IOException {
    if (!file.endsWith("hic")) {
      System.err.println("Only 'hic' files are supported");
      System.exit(-1);
    }
    // Load the expected density function, if it exists.
    Map<Integer, DensityFunction> zoomToDensityMap = null;
    String densityFile = file + ".densities";
    if (FileUtils.resourceExists(densityFile)) {
      InputStream is = null;
      try {
        is = ParsingUtils.openInputStream(densityFile);
        zoomToDensityMap = DensityUtil.readDensities(is);

      } finally {
        if (is != null) is.close();
      }
    } else {
      System.err.println("Densities file doesn't exist");
      System.exit(-1);
    }

    SeekableStream ss = IGVSeekableStreamFactory.getStreamFor(file);
    Dataset dataset = (new DatasetReader(ss)).read();
    Chromosome[] tmp = dataset.getChromosomes();

    Map<String, Chromosome> chromosomeMap = new HashMap<String, Chromosome>();
    for (Chromosome c : tmp) {
      chromosomeMap.put(c.getName(), c);
    }

    if (!chromosomeMap.containsKey(chr)) {
      System.err.println("Unknown chromosome: " + chr);
      System.exit(-1);
    }
    int zoomIdx = 0;
    boolean found = false;
    for (; zoomIdx < HiCGlobals.zoomBinSizes.length; zoomIdx++) {
      if (HiCGlobals.zoomBinSizes[zoomIdx] == binsize) {
        found = true;
        break;
      }
    }

    if (!found) {
      System.err.println("Unknown bin size: " + binsize);
      System.exit(-1);
    }

    Matrix matrix = dataset.getMatrix(chromosomeMap.get(chr), chromosomeMap.get(chr));
    MatrixZoomData zd = matrix.getObservedMatrix(zoomIdx);
    final DensityFunction df = zoomToDensityMap.get(zd.getZoom());
    double[] eigenvector = zd.computeEigenvector(df, 0);
    for (double ev : eigenvector) System.out.print(ev + " ");
    System.out.println();
  }
 public static Matrix panelToMatrix(JTextField[] jtfMatrix, int line, int row, double accuracy) {
   int i, j;
   Matrix matrix = new Matrix(line, row, accuracy);
   for (i = 0; i < line; i++)
     for (j = 0; j < row; j++) {
       if (jtfMatrix[i * row + j].getText().equals("")) return null;
       matrix.setElement(i, j, Double.parseDouble(jtfMatrix[i * row + j].getText()));
     }
   return matrix;
 }
  public static void matrixToPanel(JTextField[] jtfMatrix, Matrix matrix) {
    int i, j;
    DecimalFormat df = new DecimalFormat(String.valueOf(matrix.getAccuracy()).replace('1', '0'));

    for (i = 0; i < matrix.getLine(); i++)
      for (j = 0; j < matrix.getRow(); j++) {
        jtfMatrix[i * matrix.getRow() + j].setText(
            String.valueOf(df.format(matrix.getElement(i, j))));
      }
  }
  public double[][] Eigenvectors(Matrix m) {
    EigenvalueDecomposition decomposition = m.eig();
    Matrix eigenVectorsMatrix = decomposition.getV();
    double[][] eigenvectors = eigenVectorsMatrix.getArray();

    //	   	System.out.println("eigenvectors matrix");
    //	   	eigenVectorsMatrix.print(2,2);

    return eigenvectors;
  }
  private void getnegphase() {
    /*
     * It does the negative phase of unsupervised RBM training algorithm
     *
     * For details, please refer to Dr. Hinton's paper:
     * Reducing the dimensionality of data with neural networks. Science, Vol. 313. no. 5786, pp. 504 - 507, 28 July 2006.
     */

    // start calculate the negative phase
    // calculate the curved value of v1,h1
    // find the vector of v1
    Matrix negdata = poshidstates.times(vishid.transpose());
    // (1 * numhid) * (numhid * numdims) = (1 * numdims)
    negdata.plusEquals(visbiases);
    // poshidstates*vishid' + visbiases
    double[][] tmp1 = negdata.getArray();
    int i1 = 0;
    while (i1 < numdims) {
      tmp1[0][i1] = 1 / (1 + Math.exp(-tmp1[0][i1]));
      i1++;
    }

    // find the vector of h1
    neghidprobs = negdata.times(vishid);
    // (1 * numdims) * (numdims * numhid) = (1 * numhid)
    neghidprobs.plusEquals(hidbiases);
    double[][] tmp2 = neghidprobs.getArray();
    int i2 = 0;
    while (i2 < numhid) {
      tmp2[0][i2] = 1 / (1 + Math.exp(-tmp2[0][i2]));
      i2++;
    }
    negprods = negdata.transpose().times(neghidprobs);
    // (numdims * 1) *(1 * numhid) = (numdims * numhid)
  }
  public Matrix matrixTranspose() { // 矩阵转置
    int i, j;
    Matrix trans_matrix = new Matrix();

    for (i = 0; i < getLine(); i++)
      for (j = 0; j < getRow(); j++) trans_matrix.setElement(j, i, this.getElement(i, j));
    trans_matrix.setLine(getLine());
    trans_matrix.setRow(getRow());
    trans_matrix.setAccuracy(getAccuracy());
    return trans_matrix;
  }
  private void prepareMatrices(String statusMatrixFile) {
    wrs = new WeightedRandomSelection<Id<Zone>>();
    Matrix avestatus = MatrixUtils.readMatrices(statusMatrixFile).getMatrix("avg");

    for (Map.Entry<String, ArrayList<Entry>> fromLOR : avestatus.getFromLocations().entrySet()) {
      if (BerlinZoneUtils.isInBerlin(fromLOR.getKey())) {
        wrs.add(
            Id.create(fromLOR.getKey(), Zone.class),
            MatrixUtils.calculateTotalValue(fromLOR.getValue()));
      }
    }
  }
  public int matrixRank() // 矩阵的秩
      {
    int rank = 0, i, j;
    Matrix matrix = new Matrix();

    matrix = matrixLineSimplify();
    for (i = 0; i < matrix.getLine(); i++)
      for (j = 0; j < matrix.getRow(); j++)
        if (Math.abs(matrix.getElement(i, j)) > matrix.getAccuracy()) {
          rank++;
          break;
        }
    return rank;
  }
  public void map(
      LongWritable key,
      Text value,
      OutputCollector<IntWritable, DoubleWritable> output,
      Reporter reporter)
      throws IOException {
    /*
     * It implements the mapper. It outputs the numbers of weight and updated weights.
     *
     * Note that the format of intermediate output is <IntWritable, DoubleWritable>,
     * because the key is the number of weight (an integer), and the value is the weight's value (double)
     */
    inputData = value.toString();

    // go through the process
    initialize();
    getposphase();
    getnegphase();
    update();

    // output the intermediate data
    // The <key, value> pairs are <weightID, weightUpdate>
    double[][] vishidinc_array = vishidinc.getArray();
    for (int i = 0; i < numdims; i++) {
      for (int j = 0; j < numhid; j++) {
        weightPos.set(i * numhid + j);
        weightValue.set(vishidinc_array[i][j]);
        output.collect(weightPos, weightValue);
      }
    }
  }
Exemple #13
0
 long[][] initMatrix(int n, int start) {
   long[][] m = Matrix.unit(n);
   for (int i = 0; i < start; i++) {
     m[i][start] = 1;
   }
   return m;
 }
 public Matrix(double[][] matrixArray, int line, int row, double accuracy, String name) {
   this.matrixArray = Matrix.matrixArrayCopy(matrixArray);
   this.line = line;
   this.row = row;
   this.accuracy = accuracy;
   this.name = name;
 }
  public Matrix matrixPower(int n) { // 矩阵的幂
    int i;
    Matrix matrix = new Matrix(this);

    for (i = 2; i <= n; i++) matrix = Matrix.matrixMultiply(matrix, this);
    return matrix;
  }
  private void prop2nextLayer() {
    /*
     * It computes the forward propagation algorithm.
     */
    poshidprobs = data.times(vishid);
    // (1 * numdims) * (numdims * numhid)
    poshidprobs.plusEquals(hidbiases);
    // data*vishid + hidbiases
    double[][] product_tmp2 = poshidprobs.getArray();

    for (int i2 = 0; i2 < numhid; i2++) {
      /*
       * compute the updated input, and write them to newinput
       */
      product_tmp2[0][i2] = 1 / (1 + Math.exp(-product_tmp2[0][i2]));
      newinput[i2] = (int) (product_tmp2[0][i2] * 255.0);
    }
  }
Exemple #17
0
  /** toy example */
  public static void test2() {
    int N = 500;
    double[][] m1 = new double[N][N];
    double[][] m2 = new double[N][N];
    double[][] m3 = new double[N][N];

    // init
    Random rand = new Random();
    for (int i = 0; i < N; i++)
      for (int j = 0; j < N; j++) {
        m1[i][j] = 10 * (rand.nextDouble() - 0.2);
        m2[i][j] = 20 * (rand.nextDouble() - 0.8);
      }

    // inverse
    System.out.println("Start");
    Matrix mat1 = new Matrix(m1);
    Matrix mat2 = mat1.inverse();
    Matrix mat3 = mat1.times(mat2);
    double[][] m4 = mat3.getArray();
    /*
       for (int i = 0; i < m4.length; i++) {
         int ss = 10;
         for (int j = 0; j < ss; j++) {
    System.out.printf("%f ", m4[i][j]);
         }
         System.out.print("\n");
       }
       */
    System.out.println("Done");

    /*
        // matrix *
        System.out.println("Start");
        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {
          double cell = 0;
          for (int k = 0; k < N; k++)
    	cell += m1[i][k] * m2[k][j];
    //      System.out.printf("%f ", cell);
          m3[i][j] = cell;
        }
        System.out.println("Done");
        */
  }
Exemple #18
0
  public Matrix createVector() {
    int rows = frame.size();
    Matrix m = new Matrix(rows, 1);

    for (int i = 0; i < rows; i++) {
      M rowValue = frame.object(i);
      try {
        Number numValue = (Number) numericField.get(rowValue);
        m.set(i, 0, numValue.doubleValue());

      } catch (IllegalAccessException e) {
        e.printStackTrace();
        throw new IllegalStateException(
            String.format("Couldn't access field %s: %s", numericField.getName(), e.getMessage()));
      }
    }

    return m;
  }
  public double[] Eigenvalues(Matrix m) {
    EigenvalueDecomposition decomposition = m.eig();
    double[] eigenvalues = decomposition.getRealEigenvalues();

    //		System.out.println("eigenvalues: ");
    //		for(int i=0;i<eigenvalues.length;i++)
    //			System.out.println(""+eigenvalues[i]);

    return eigenvalues;
  }
  private void getposphase() {
    /*
     * It does the positive phase of unsupervised RBM training algorithm
     *
     * For details, please refer to Dr. Hinton's paper:
     * Reducing the dimensionality of data with neural networks. Science, Vol. 313. no. 5786, pp. 504 - 507, 28 July 2006.
     */

    // Start calculate the positive phase
    // calculate the cured value of h0
    poshidprobs = data.times(vishid);
    // (1 * numdims) * (numdims * numhid)
    poshidprobs.plusEquals(hidbiases);
    // data*vishid + hidbiases
    double[][] product_tmp2 = poshidprobs.getArray();
    int i2 = 0;
    while (i2 < numhid) {
      product_tmp2[0][i2] = 1 / (1 + Math.exp(-product_tmp2[0][i2]));
      i2++;
    }
    posprods = data.transpose().times(poshidprobs);
    // (numdims * 1) * (1 * numhid)

    // end of the positive phase calculation, find the binary presentation of h0
    int i3 = 0;
    double[][] tmp1 = poshidprobs.getArray();
    double[][] tmp2 = new double[1][numhid];
    Random randomgenerator = new Random();
    while (i3 < numhid) {
      /*
       * a sampling according to possiblity given by poshidprobs
       */
      if (tmp1[0][i3] > randomgenerator.nextDouble()) tmp2[0][i3] = 1;
      else tmp2[0][i3] = 0;
      i3++;
    }

    // poshidstates is a binary sampling according to possiblity given by poshidprobs
    poshidstates = new Matrix(tmp2);
  }
  /**
   * Transition function. Currently, we only get the list of probabilities of each item.
   *
   * @param current - The current state
   * @param action - The action
   * @param possible - The possible state
   * @return The list of probabilities where each index refers to the probability of that item
   */
  private List<Double> transition(State current, Action action, State possible) {
    List<Double> probs = new ArrayList<Double>(); // Probabilities
    Map<Integer, Integer> currentStock, purchase, possibleStock; // Maps
    double currentProb; // The current probability
    Matrix currentMatrix; // The current probability matrix
    int row, column; // The row and column

    for (int i = 0; i < current.getState().size(); ++i) {
      currentProb = 0.0;
      currentStock = current.getState();
      purchase = action.getPurchases();
      possibleStock = possible.getState();
      row = currentStock.get(i) + purchase.get(i);
      column = row - possible.getState().get(i);
      currentMatrix = this.probabilities.get(i);
      if (column < 0
          || column >= currentMatrix.getNumCols()
          || row >= currentMatrix.getNumRows()) { // Invalid state
        probs.add(0.0);
        continue;
      }
      if (possibleStock.get(i) > 0
          || (possibleStock.get(i) == 0 && column == 0)) { // Sufficiently provided
        currentProb = currentMatrix.get(row, column);
      } else if (possibleStock.get(i) == 0 && column > 0) {
        // Range of probabilities because user could have eaten plenty
        for (int j = column; j < currentMatrix.getNumCols(); ++j) {
          currentProb += currentMatrix.get(row, j);
        }
      }
      probs.add(currentProb);
    }
    return probs;
  }
  double calculateMSEOnValidationSet(Matrix featuresValidationSet, Matrix labelsValidationSet)
      throws Exception {

    double sumSquaredError = 0;

    for (int instance = 0; instance < featuresValidationSet.rows(); instance++) {
      double errorAcrossOutputNodes = 0;
      double[] predictedLabel = labelsValidationSet.row(instance); // this is the target
      predict(featuresValidationSet.row(instance), labelsValidationSet.row(instance));
      for (int col = 0; col < globalStoredOutputNodeFNetValues.length; col++) {
        errorAcrossOutputNodes +=
            (globalStoredOutputNodeTargetValues[col] - globalStoredOutputNodeFNetValues[col]);
      }
      sumSquaredError += (errorAcrossOutputNodes * errorAcrossOutputNodes);
    }

    double MSE =
        (sumSquaredError
            / (featuresValidationSet.rows() * globalStoredOutputNodeFNetValues.length));

    return MSE;
  }
  public Matrix matrixAccuralize() { // 精确化矩阵
    int i, j;
    Matrix matrix = new Matrix(this);

    for (i = 0; i < matrix.getLine(); i++)
      for (j = 0; j < matrix.getRow(); j++)
        if (Math.abs(matrix.getElement(i, j)) <= matrix.getAccuracy()) matrix.setElement(i, j, 0.0);
    return matrix;
  }
  public static Matrix scanMatrix() { // 输入矩阵
    int i, j;
    Matrix matrix = new Matrix();
    Scanner scanner = new Scanner(System.in);

    matrix.setLine(scanner.nextInt());
    matrix.setRow(scanner.nextInt());
    matrix.setAccuracy(scanner.nextDouble());
    for (i = 0; i < matrix.getLine(); i++) {
      for (j = 0; j < matrix.getRow(); j++) matrix.setElement(i, j, scanner.nextDouble());
    }
    return matrix;
  }
  // update the weights and biases
  // This serves as a reducer
  private void update() {
    /*
     * It computes the update of weights using previous results and parameters
     *
     * For details, please refer to Dr. Hinton's paper:
     * Reducing the dimensionality of data with neural networks. Science, Vol. 313. no. 5786, pp. 504 - 507, 28 July 2006.
     */
    double momentum;
    // if (epoch > 5)
    //        momentum = finalmomentum;
    // else
    //        momentum = initialmomentum;
    // vishidinc = momentum*vishidinc + epsilonw*( (posprods-negprods)/numcases -
    // weightcost*vishid);
    // vishidinc.timesEquals(momentum);
    Matrix temp1 = posprods.minus(negprods);
    Matrix temp2 = vishid.times(weightcost);
    temp1.minusEquals(temp2);
    temp1.timesEquals(epsilonw);

    // the final updates of weights are written in vishidinc
    vishidinc.plusEquals(temp1);
  }
Exemple #26
0
  public int solve(long coins_sum, long[] values) {
    int n = values.length;
    long[][][] step = new long[n][][];

    step[0] = Matrix.unit(n);
    for (int i = 1; i < n; i++) {
      long div = values[i] / values[i - 1];
      step[i] = Matrix.mul(initMatrix(n, i), Matrix.pow(step[i - 1], div, MOD), MOD);
    }

    long[][] total = Matrix.unit(n);
    for (int i = n - 1; i >= 0; i--) {
      long length = coins_sum / values[i];
      coins_sum %= values[i];
      total = Matrix.mul(Matrix.pow(step[i], length, MOD), total, MOD);
    }

    long res = 0;
    for (int i = 0; i < n; i++) {
      res += total[0][i];
    }

    return (int) (res % MOD);
  }
Exemple #27
0
 public static void main(String[] args) {
   Scanner scanner = new Scanner(System.in);
   Matrix o = Matrix.load(scanner);
   System.out.println(o.solve());
 }
 public void initFrame(double time) { // add animation here!!!!!!
   boolean rotate = false;
   rotate = true;
   // fundation
   m.identity();
   if (rotate) m.rotateY(time * speed);
   m.translate(0, foundPosition, 0);
   m.scale(foundW, foundH, foundW);
   m.rotateX(-Math.PI / 2);
   m.transform(g[0], t[0]);
   // largest ball
   m.identity();
   if (rotate) m.rotateY(time * speed);
   m.translate(ballLX, ballLPosition, ballLZ);
   m.scale(ballLR, ballLR, ballLR);
   m.rotateX(Math.PI / 2);
   m.transform(g[1], t[1]);
   // middle ball
   m.identity();
   if (rotate) m.rotateY(time * speed);
   m.translate(ballLX, ballMPosition, ballLZ);
   m.scale(ballMR, ballMR, ballMR);
   m.rotateX(Math.PI / 2);
   m.transform(g[2], t[2]);
   // head ball
   m.identity();
   if (rotate) m.rotateY(time * speed);
   m.translate(ballLX, ballHPosition, ballLZ);
   m.scale(ballHR, ballHR, ballHR);
   m.rotateX(Math.PI / 2);
   m.transform(g[3], t[3]);
   // hat
   m.identity();
   if (rotate) m.rotateY(time * speed);
   m.translate(ballLX, ballHPosition, ballLZ);
   m.rotateZ(-Math.PI / 18);
   m.translate(0, hatPosition - ballHPosition, 0);
   m.scale(hatR, hatR, hatR);
   m.rotateX(Math.PI / 2);
   m.transform(g[4], t[4]);
   // hat bottom
   m.identity();
   if (rotate) m.rotateY(time * speed);
   m.translate(ballLX, ballHPosition, ballLZ);
   m.rotateZ(-Math.PI / 18);
   m.translate(0, hatBPosition - ballHPosition, 0);
   m.scale(hatBR, hatBH, hatBR);
   m.rotateX(Math.PI / 2);
   m.transform(g[5], t[5]);
   // eye
   m.identity();
   if (rotate) m.rotateY(time * speed);
   m.translate(eyeX, eyeY, Math.sqrt(Math.pow(ballHR, 2) - Math.pow(eyeX, 2) - Math.pow(eyeY, 2)));
   m.translate(ballLX, ballHPosition, ballLZ);
   m.scale(eyeW, eyeH, eyeT);
   m.rotateZ(Math.PI / 18);
   m.rotateX(Math.PI / 2);
   m.transform(g[6], t[6]);
   // eye
   m.identity();
   if (rotate) m.rotateY(time * speed);
   m.translate(
       -eyeX, eyeY, Math.sqrt(Math.pow(ballHR, 2) - Math.pow(eyeX, 2) - Math.pow(eyeY, 2)));
   m.translate(ballLX, ballHPosition, ballLZ);
   m.scale(eyeW, eyeH, eyeT);
   m.rotateZ(-Math.PI / 18);
   m.rotateX(Math.PI / 2);
   m.transform(g[7], t[7]);
   // nose
   m.identity();
   if (rotate) m.rotateY(time * speed);
   m.translate(ballLX, ballHPosition, ballLZ + ballHR);
   m.scale(noseR, noseR, noseL);
   m.transform(g[8], t[8]);
   // botton 1
   m.identity();
   if (rotate) m.rotateY(time * speed);
   m.translate(0, bottonY, Math.sqrt(Math.pow(ballMR, 2) - Math.pow(bottonY, 2)));
   m.translate(ballLX, ballMPosition, ballLZ);
   m.scale(bottonR, bottonR, bottonT);
   m.rotateX(Math.PI / 2);
   m.transform(g[9], t[9]);
   // botton 2
   m.identity();
   if (rotate) m.rotateY(time * speed);
   m.translate(0, -bottonY / 2, Math.sqrt(Math.pow(ballMR, 2) - Math.pow(bottonY / 2, 2)));
   m.translate(ballLX, ballMPosition, ballLZ);
   m.scale(bottonR, bottonR, bottonT);
   m.rotateX(Math.PI / 2);
   m.transform(g[10], t[10]);
   // botton 3
   m.identity();
   if (rotate) m.rotateY(time * speed);
   m.translate(0, bottonY, Math.sqrt(Math.pow(ballLR, 2) - Math.pow(bottonY, 2)));
   m.translate(ballLX, ballLPosition, ballLZ);
   m.scale(bottonR, bottonR, bottonT);
   m.rotateX(Math.PI / 2);
   m.transform(g[11], t[11]);
 }
 @Override
 protected void applyModelviewTransform(DrawContext dc, SurfaceTileDrawContext sdc) {
   // Apply the geographic to surface tile coordinate transform.
   Matrix modelview = sdc.getModelviewMatrix();
   dc.getGL().glMultMatrixd(modelview.toArray(new double[16], 0, false), 0);
 }
  protected int computeCartesianPolygon(
      Globe globe,
      List<? extends LatLon> locations,
      List<Boolean> edgeFlags,
      Vec4[] points,
      Boolean[] edgeFlagArray,
      Matrix[] transform) {
    if (globe == null) {
      String message = Logging.getMessage("nullValue.GlobeIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (locations == null) {
      String message = "nullValue.LocationsIsNull";
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (points == null) {
      String message = "nullValue.LocationsIsNull";
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (points.length < (1 + locations.size())) {
      String message =
          Logging.getMessage(
              "generic.ArrayInvalidLength", "points.length < " + (1 + locations.size()));
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (transform == null) {
      String message = "nullValue.TransformIsNull";
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (transform.length < 1) {
      String message = Logging.getMessage("generic.ArrayInvalidLength", "transform.length < 1");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    // Allocate space to hold the list of locations and location vertices.
    int locationCount = locations.size();

    // Compute the cartesian points for each location.
    for (int i = 0; i < locationCount; i++) {
      LatLon ll = locations.get(i);
      points[i] = globe.computePointFromPosition(ll.getLatitude(), ll.getLongitude(), 0.0);

      if (edgeFlagArray != null) edgeFlagArray[i] = (edgeFlags != null) ? edgeFlags.get(i) : true;
    }

    // Compute the average of the cartesian points.
    Vec4 centerPoint = Vec4.computeAveragePoint(Arrays.asList(points));

    // Test whether the polygon is closed. If it is not closed, repeat the first vertex.
    if (!points[0].equals(points[locationCount - 1])) {
      points[locationCount] = points[0];
      if (edgeFlagArray != null) edgeFlagArray[locationCount] = edgeFlagArray[0];

      locationCount++;
    }

    // Compute a transform that will map the cartesian points to a local coordinate system centered
    // at the average
    // of the points and oriented with the globe surface.
    Position centerPos = globe.computePositionFromPoint(centerPoint);
    Matrix tx = globe.computeSurfaceOrientationAtPosition(centerPos);
    Matrix txInv = tx.getInverse();
    // Map the cartesian points to a local coordinate space.
    for (int i = 0; i < locationCount; i++) {
      points[i] = points[i].transformBy4(txInv);
    }

    transform[0] = tx;

    return locationCount;
  }