protected synchronized ArrayAccess implGetTransposedArray(
      int mode, int startColumn, int columns, int rows) throws ApfloatRuntimeException {
    int width = (int) (getSize() / rows);

    if (columns != (columns & -columns)
        || rows != (rows & -rows)
        || startColumn + columns > width) {
      throw new ApfloatInternalException("Invalid size");
    }

    int blockSize = columns * rows, b = columns;
    ArrayAccess arrayAccess =
        new TransposedMemoryArrayAccess(mode, new double[blockSize], startColumn, columns, rows);

    if ((mode & READ) != 0) {
      // Read the data from the input file in b x b blocks

      long readPosition = startColumn;
      for (int i = 0; i < rows; i += b) {
        int writePosition = i;

        for (int j = 0; j < b; j++) {
          readToArray(readPosition, arrayAccess, writePosition, b);

          readPosition += width;
          writePosition += rows;
        }

        // Transpose the b x b block

        ArrayAccess subArrayAccess = arrayAccess.subsequence(i, blockSize - i);
        DoubleMatrix.transposeSquare(subArrayAccess, b, rows);
      }
    }

    return arrayAccess;
  }
  // Write the data back to the same location in file as retrieved with getTransposedArray()
  private synchronized void setTransposedArray(
      ArrayAccess arrayAccess, int startColumn, int columns, int rows)
      throws ApfloatRuntimeException {
    int width = (int) (getSize() / rows);

    int blockSize = arrayAccess.getLength(), b = columns;

    long writePosition = startColumn;
    for (int i = 0; i < rows; i += b) {
      int readPosition = i;

      // Transpose the b x b block

      ArrayAccess subArrayAccess = arrayAccess.subsequence(i, blockSize - i);
      DoubleMatrix.transposeSquare(subArrayAccess, b, rows);

      for (int j = 0; j < b; j++) {
        writeFromArray(arrayAccess, readPosition, writePosition, b);

        readPosition += rows;
        writePosition += width;
      }
    }
  }
 private void writeFromArray(
     ArrayAccess arrayAccess, int readPosition, long writePosition, int length)
     throws ApfloatRuntimeException {
   ArrayAccess writeArrayAccess = getArray(WRITE, writePosition, length);
   System.arraycopy(
       arrayAccess.getData(),
       arrayAccess.getOffset() + readPosition,
       writeArrayAccess.getData(),
       writeArrayAccess.getOffset(),
       length);
   writeArrayAccess.close();
 }
 private void readToArray(
     long readPosition, ArrayAccess arrayAccess, int writePosition, int length)
     throws ApfloatRuntimeException {
   ArrayAccess readArrayAccess = getArray(READ, readPosition, length);
   System.arraycopy(
       readArrayAccess.getData(),
       readArrayAccess.getOffset(),
       arrayAccess.getData(),
       arrayAccess.getOffset() + writePosition,
       length);
   readArrayAccess.close();
 }