// Divide this matrix by a PhasorMatrix [equivalence of /=]
 public void overEquals(PhasorMatrix bmat) {
   if ((this.nrow != bmat.nrow) || (this.ncol != bmat.ncol)) {
     throw new IllegalArgumentException("Array dimensions do not agree");
   }
   PhasorMatrix cmat = new PhasorMatrix(bmat);
   this.timesEquals(cmat.inverse());
 }
  // Divide this matrix by a Phasor 2-D array.
  public PhasorMatrix over(Phasor[][] bmat) {
    int nr = bmat.length;
    int nc = bmat[0].length;
    if ((this.nrow != nr) || (this.ncol != nc)) {
      throw new IllegalArgumentException("Array dimensions do not agree");
    }

    PhasorMatrix cmat = new PhasorMatrix(bmat);
    return this.times(cmat.inverse());
  }
 // TRANSPOSE
 // Transpose of a Phasor matrix
 public PhasorMatrix transpose() {
   PhasorMatrix tmat = new PhasorMatrix(this.ncol, this.nrow);
   Phasor[][] tarray = tmat.getArrayReference();
   for (int i = 0; i < this.ncol; i++) {
     for (int j = 0; j < this.nrow; j++) {
       tarray[i][j] = Phasor.copy(this.matrix[j][i]);
     }
   }
   return tmat;
 }
 // Converts a phasor matrix (PhasorMatix) to a complex matrix (ComplexMatrix) - static method
 public static ComplexMatrix toComplexMatrix(PhasorMatrix pp) {
   int nr = pp.getNrow();
   int nc = pp.getNcol();
   ComplexMatrix cc = new ComplexMatrix(nr, nc);
   for (int i = 0; i < nr; i++) {
     for (int j = 0; j < nc; i++) {
       cc.setElement(i, j, pp.matrix[i][j].toRectangular());
     }
   }
   return cc;
 }
 // Converts a complex matrix (ComplexMatrix) to a phasor matrix (PhasorMatix)
 public static PhasorMatrix toPhasorMatrix(ComplexMatrix cc) {
   PhasorMatrix pp = new PhasorMatrix(cc.getNrow(), cc.getNcol());
   pp.index = cc.getIndexCopy();
   pp.dswap = cc.getSwap();
   for (int i = 0; i < pp.nrow; i++) {
     for (int j = 0; j < pp.ncol; i++) {
       pp.matrix[i][j] = Phasor.toPhasor(cc.getElementCopy(i, j));
     }
   }
   return pp;
 }
  // Multiply this Phasor matrix by a Phasor constant
  // This matrix remains unaltered
  public PhasorMatrix times(Phasor constant) {
    PhasorMatrix cmat = new PhasorMatrix(this.nrow, this.ncol);
    Phasor[][] carray = cmat.getArrayReference();

    for (int i = 0; i < this.nrow; i++) {
      for (int j = 0; j < this.ncol; j++) {
        carray[i][j] = this.matrix[i][j].times(constant);
      }
    }
    return cmat;
  }
 // Return a sub-matrix
 // row = array of row indices
 // col = array of column indices
 public PhasorMatrix getSubMatrix(int[] row, int[] col) {
   int n = row.length;
   int m = col.length;
   PhasorMatrix subMatrix = new PhasorMatrix(n, m);
   Phasor[][] sarray = subMatrix.getArrayReference();
   for (int i = 0; i < n; i++) {
     for (int j = 0; j < m; j++) {
       sarray[i][j] = Phasor.copy(this.matrix[row[i]][col[j]]);
     }
   }
   return subMatrix;
 }
 // Construct a Phasor scalar matrix
 public static PhasorMatrix scalarMatrix(int nrow, Phasor diagconst) {
   PhasorMatrix u = new PhasorMatrix(nrow, nrow);
   Phasor[][] uarray = u.getArrayReference();
   for (int i = 0; i < nrow; i++) {
     for (int j = i; j < nrow; j++) {
       if (i == j) {
         uarray[i][j] = Phasor.copy(diagconst);
       }
     }
   }
   return u;
 }
 // Construct a Phasor diagonal matrix
 public static PhasorMatrix diagonalMatrix(int nrow, Phasor[] diag) {
   if (diag.length != nrow)
     throw new IllegalArgumentException("matrix dimension differs from diagonal array length");
   PhasorMatrix u = new PhasorMatrix(nrow, nrow);
   Phasor[][] uarray = u.getArrayReference();
   for (int i = 0; i < nrow; i++) {
     for (int j = i; j < nrow; j++) {
       if (i == j) {
         uarray[i][j] = Phasor.copy(diag[i]);
       }
     }
   }
   return u;
 }
 // Subtract  Phasor 2-D array from this matrix.  [instance method]
 public PhasorMatrix minus(Phasor[][] bmat) {
   int nr = bmat.length;
   int nc = bmat[0].length;
   if ((this.nrow != nr) || (this.ncol != nc)) {
     throw new IllegalArgumentException("Array dimensions do not agree");
   }
   PhasorMatrix cmat = new PhasorMatrix(nr, nc);
   Phasor[][] carray = cmat.getArrayReference();
   for (int i = 0; i < nr; i++) {
     for (int j = 0; j < nc; j++) {
       carray[i][j] = this.matrix[i][j].minus(bmat[i][j]);
     }
   }
   return cmat;
 }
  // Return a sub-matrix starting with row index i, column index j
  // and ending with column index k, row index l
  public PhasorMatrix getSubMatrix(int i, int j, int k, int l) {
    if (i + k - 1 >= this.nrow)
      throw new IllegalArgumentException(
          "Sub-matrix position is outside the row bounds of this Matrix");
    if (j + l - 1 >= this.ncol)
      throw new IllegalArgumentException(
          "Sub-matrix position is outside the column bounds of this Matrix");

    int n = k - i + 1, m = l - j + 1;
    PhasorMatrix subMatrix = new PhasorMatrix(n, m);
    Phasor[][] sarray = subMatrix.getArrayReference();
    for (int p = 0; p < n; p++) {
      for (int q = 0; q < m; q++) {
        sarray[p][q] = Phasor.copy(this.matrix[i + p][j + q]);
      }
    }
    return subMatrix;
  }
 // OPPOSITE
 // Opposite of a Phasor matrix
 public PhasorMatrix opposite() {
   PhasorMatrix opp = PhasorMatrix.copy(this);
   for (int i = 0; i < this.nrow; i++) {
     for (int j = 0; j < this.ncol; j++) {
       opp.matrix[i][j] = this.matrix[i][j].times(Phasor.minusOne());
     }
   }
   return opp;
 }
 // COMPLEX CONJUGATE
 // Complex Conjugate of a Phasor matrix
 public PhasorMatrix conjugate() {
   PhasorMatrix conj = PhasorMatrix.copy(this);
   for (int i = 0; i < this.nrow; i++) {
     for (int j = 0; j < this.ncol; j++) {
       conj.matrix[i][j] = this.matrix[i][j].conjugate();
     }
   }
   return conj;
 }
  // INVERSE
  // Inverse of a square Phasor matrix
  public PhasorMatrix inverse() {
    int n = this.nrow;
    if (n != this.ncol) throw new IllegalArgumentException("Matrix is not square");
    Phasor[] col = new Phasor[n];
    Phasor[] xvec = new Phasor[n];
    PhasorMatrix invmat = new PhasorMatrix(n, n);
    Phasor[][] invarray = invmat.getArrayReference();
    PhasorMatrix ludmat;

    ludmat = this.luDecomp();
    for (int j = 0; j < n; j++) {
      for (int i = 0; i < n; i++) col[i] = Phasor.zero();
      col[j] = Phasor.plusOne();
      xvec = ludmat.luBackSub(col);
      for (int i = 0; i < n; i++) invarray[i][j] = Phasor.copy(xvec[i]);
    }
    return invmat;
  }
  // MULTIPLICATION
  // Multiply this Phasor matrix by a Phasor matrix.
  // This matrix remains unaltered.
  public PhasorMatrix times(PhasorMatrix bmat) {
    if (this.ncol != bmat.nrow) throw new IllegalArgumentException("Nonconformable matrices");

    PhasorMatrix cmat = new PhasorMatrix(this.nrow, bmat.ncol);
    Phasor[][] carray = cmat.getArrayReference();
    Phasor sum = new Phasor();

    for (int i = 0; i < this.nrow; i++) {
      for (int j = 0; j < bmat.ncol; j++) {
        sum = Phasor.zero();
        for (int k = 0; k < this.ncol; k++) {
          sum.plusEquals(this.matrix[i][k].times(bmat.matrix[k][j]));
        }
        carray[i][j] = Phasor.copy(sum);
      }
    }
    return cmat;
  }
 // Clone a PhasorMatrix
 public Object clone() {
   if (this == null) {
     return null;
   } else {
     int nr = this.nrow;
     int nc = this.ncol;
     PhasorMatrix b = new PhasorMatrix(nr, nc);
     Phasor[][] barray = b.getArrayReference();
     b.nrow = nr;
     b.ncol = nc;
     for (int i = 0; i < nr; i++) {
       for (int j = 0; j < nc; j++) {
         barray[i][j] = Phasor.copy(this.matrix[i][j]);
       }
     }
     for (int i = 0; i < nr; i++) b.index[i] = this.index[i];
     return (Object) b;
   }
 }
 // COPY
 // Copy a PhasorMatrix [static method]
 public static PhasorMatrix copy(PhasorMatrix a) {
   if (a == null) {
     return null;
   } else {
     int nr = a.getNrow();
     int nc = a.getNcol();
     Phasor[][] aarray = a.getArrayReference();
     PhasorMatrix b = new PhasorMatrix(nr, nc);
     b.nrow = nr;
     b.ncol = nc;
     Phasor[][] barray = b.getArrayReference();
     for (int i = 0; i < nr; i++) {
       for (int j = 0; j < nc; j++) {
         barray[i][j] = Phasor.copy(aarray[i][j]);
       }
     }
     for (int i = 0; i < nr; i++) b.index[i] = a.index[i];
     return b;
   }
 }
 // Subtract a 2D array of complex from this matrix [equivalence of -=]
 public void minusEquals(Complex[][] bmat) {
   PhasorMatrix pmat = PhasorMatrix.toPhasorMatrix(bmat);
   this.minusEquals(pmat);
 }
 // Divide this PhasorMatrix by a 2D array of double.
 public PhasorMatrix over(double[][] bmat) {
   PhasorMatrix pmat = PhasorMatrix.toPhasorMatrix(bmat);
   return this.over(pmat);
 }
 // Divide this PhasorMatrix by a Matrix.
 public PhasorMatrix over(Matrix bmat) {
   PhasorMatrix pmat = PhasorMatrix.toPhasorMatrix(bmat);
   return this.over(pmat);
 }
 // Divide this PhasorMatrix by a 2D array of Complex.
 public PhasorMatrix over(Complex[][] bmat) {
   PhasorMatrix pmat = PhasorMatrix.toPhasorMatrix(bmat);
   return this.over(pmat);
 }
 // DIVISION
 // Divide this PhasorMatrix by a PhasorMatrix.
 public PhasorMatrix over(PhasorMatrix bmat) {
   if ((this.nrow != bmat.nrow) || (this.ncol != bmat.ncol)) {
     throw new IllegalArgumentException("Array dimensions do not agree");
   }
   return this.times(bmat.inverse());
 }
 // Multiply a 2D array of doubles by this matrix [equivalence of *=]
 public void timesEquals(double[][] bmat) {
   PhasorMatrix pmat = PhasorMatrix.toPhasorMatrix(bmat);
   this.timesEquals(pmat);
 }
 // Multiply a ComplexMatrix of complex by this matrix [equivalence of *=]
 public void timesEquals(ComplexMatrix bmat) {
   PhasorMatrix pmat = PhasorMatrix.toPhasorMatrix(bmat);
   this.timesEquals(pmat);
 }
 // Multiply a 2D array of doubles by this PhasorMatrix.
 public PhasorMatrix times(double[][] bmat) {
   PhasorMatrix pmat = PhasorMatrix.toPhasorMatrix(bmat);
   return this.times(pmat);
 }
 // Multiply a Matrix by this PhasorMatrix.
 public PhasorMatrix times(Matrix bmat) {
   PhasorMatrix pmat = PhasorMatrix.toPhasorMatrix(bmat);
   return this.times(pmat);
 }
 // Multiply a 2D array of Complex by this PhasorMatrix.
 public PhasorMatrix times(Complex[][] bmat) {
   PhasorMatrix pmat = PhasorMatrix.toPhasorMatrix(bmat);
   return this.times(pmat);
 }
 // Subtract a Matrix from this phasorMatrix [equivalence of -=]
 public void minusEquals(Matrix bmat) {
   PhasorMatrix pmat = PhasorMatrix.toPhasorMatrix(bmat);
   this.minusEquals(pmat);
 }
 // Subtract a Matrix from this PhasorMatrix.
 public PhasorMatrix minus(Matrix bmat) {
   PhasorMatrix pmat = PhasorMatrix.toPhasorMatrix(bmat);
   return this.minus(pmat);
 }
 // Subtract a 2D array of doubles from this PhasorMatrix.
 public PhasorMatrix minus(double[][] bmat) {
   PhasorMatrix pmat = PhasorMatrix.toPhasorMatrix(bmat);
   return this.minus(pmat);
 }