DoubleComplexIntervalMatrix.java

/*
 * Created on 2004/08/24
 *
 * $Id: ComplexIntervalMatrix.java,v 1.62 2008/03/15 00:23:51 koga Exp $
 * Copyright (C) 2004 Koga Laboratory. All rights reserved.
 */
package org.mklab.cga.interval.matrix;

import java.io.Writer;

import org.mklab.cga.interval.scalar.DoubleComplexIntervalNumber;
import org.mklab.cga.interval.scalar.DoubleIntervalNumber;
import org.mklab.cga.interval.scalar.IntervalScalar;
import org.mklab.cga.util.IntervalUtil;
import org.mklab.nfc.eig.BalancedDecomposition;
import org.mklab.nfc.eig.ComplexQZDecomposition;
import org.mklab.nfc.eig.EigenSolution;
import org.mklab.nfc.eig.HessenbergDecomposition;
import org.mklab.nfc.eig.QRDecomposition;
import org.mklab.nfc.eig.SchurDecomposition;
import org.mklab.nfc.leq.LUDecomposition;
import org.mklab.nfc.matrix.BooleanMatrix;
import org.mklab.nfc.matrix.DoubleComplexMatrix;
import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.nfc.matrix.ElementHolder;
import org.mklab.nfc.matrix.Grid;
import org.mklab.nfc.matrix.IndexedMatrix;
import org.mklab.nfc.matrix.IntMatrix;
import org.mklab.nfc.matrix.NormType;
import org.mklab.nfc.scalar.DoubleComplexNumber;
import org.mklab.nfc.scalar.DoubleNumber;
import org.mklab.nfc.svd.SingularValueDecomposition;
import org.mklab.nfc.util.RoundMode;
import org.mklab.nfc.util.RoundModeManager;


/**
 * 複素区間行列を表すクラスです。
 * 
 * @author hiroki
 * @version $Revision: 1.62 $. 2004/08/24
 */
public class DoubleComplexIntervalMatrix extends AbstractIntervalComplexNumericalMatrix<DoubleIntervalNumber,DoubleIntervalMatrix,DoubleComplexIntervalNumber,DoubleComplexIntervalMatrix,DoubleNumber,DoubleMatrix,DoubleComplexNumber,DoubleComplexMatrix> {

  /** シリアル番号 */
  public static final long serialVersionUID = -1953018072192820381L;

  /**
   * 与えられた行列から区間行列を作成します。与えられた行列を区間の中心に設定します。
   * 
   * @param middle 中心の行列
   */
  public DoubleComplexIntervalMatrix(final DoubleComplexMatrix middle) {
    super(middle);
  }

  /**
   * 与えられた行列から区間行列を作成します。与えられた行列を区間の中心と半径に設定します。
   * 
   * @param middle 中心の行列(複素数行列)
   * @param radius 半径の行列(実数行列)
   */
  public DoubleComplexIntervalMatrix(final DoubleComplexMatrix middle, final DoubleMatrix radius) {
    super(middle, radius);
  }
  
  /**
   * 与えられた行列から区間行列を作成します。与えられた行列を区間の中心に設定します。
   * 
   * @param middle 中心の行列
   */
  public DoubleComplexIntervalMatrix(final DoubleComplexIntervalNumber[][] middle) {
    super(middle);
  }

  /**
   * 与えられた行列から区間行列を作成します。与えられた行列を区間の中心に設定します。
   * 
   * @param middle 中心の行列
   */
  public DoubleComplexIntervalMatrix(final DoubleComplexIntervalNumber[] middle) {
    super(middle);
  }


  /**
   * Creates interval matrix with infimum and supremum.
   * 
   * @param inf infimum
   * @param sup supremum
   * @return interval matrix
   */
  public static DoubleComplexIntervalMatrix createInfimumSupremum(DoubleComplexMatrix inf, DoubleComplexMatrix sup) {
    DoubleComplexMatrix mid = middle(inf, sup);
    DoubleMatrix rad = radius(inf, mid);
    return new DoubleComplexIntervalMatrix(mid, rad);
  }
  
  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix createMidRad(DoubleComplexMatrix middle, DoubleMatrix radius) {
    return new DoubleComplexIntervalMatrix(middle, radius);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix create(DoubleComplexMatrix value) {
    return new DoubleComplexIntervalMatrix(value);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix create(DoubleIntervalMatrix rePart) {
    return rePart.toComplex();
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix create(DoubleIntervalMatrix rePart, DoubleIntervalMatrix imPart) {
    final DoubleComplexMatrix inf = new DoubleComplexMatrix(rePart.getInfimum(), imPart.getInfimum());
    final DoubleComplexMatrix sup = new DoubleComplexMatrix(rePart.getSupremum(), imPart.getSupremum());
    return createInfimumSupremum(inf, sup);
  }
  
  /**
   * {@inheritDoc}
   */
  public DoubleIntervalMatrix createInfSup(DoubleMatrix infimum, DoubleMatrix supremum) {
    return new DoubleIntervalMatrix(infimum, supremum);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix createInfSup(DoubleComplexMatrix infimum, DoubleComplexMatrix supremum) {
    return createInfimumSupremum(infimum, supremum);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleIntervalMatrix createMidRad(DoubleMatrix middle, DoubleMatrix radius) {
    return DoubleIntervalMatrix.createMiddleRadius(middle, radius);
  }
  
  /**
   * {@inheritDoc}
   */
  public DoubleMatrix getRadius() {
    return this.radius;
  }
  
  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix createZero(final int rowSize, final int columnSize) {
    return new DoubleComplexIntervalMatrix(this.middle.createZero(rowSize, columnSize));
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix createOnes(final int rowSize, final int columnSize) {
    return new DoubleComplexIntervalMatrix(this.middle.createOnes(rowSize, columnSize));
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix createUnit(final int rowSize, final int columnSize) {
    return new DoubleComplexIntervalMatrix(this.middle.createUnit(rowSize, columnSize));
  }

  /**
   * {@inheritDoc}
   */
  public boolean isZero(final double tolerance) {
    return this.middle.isZero(tolerance) && this.radius.isZero(tolerance);
  }

  /**
   * {@inheritDoc}
   */
  public boolean isUnit(final double tolerance) {
    return this.middle.isUnit(tolerance) && this.radius.isZero(tolerance);
  }

  /**
   * {@inheritDoc}
   */
  public BooleanMatrix isNanElementWise() {
    return (this.middle.isNanElementWise()).orElementWise(this.radius.isNanElementWise());
  }

  /**
   * {@inheritDoc}
   */
  public BooleanMatrix isInfiniteElementWise() {
    return (this.middle.isInfiniteElementWise()).orElementWise(this.radius.isInfiniteElementWise());
  }

  /**
   * {@inheritDoc}
   */
  public BooleanMatrix isFiniteElementWise() {
    return (this.middle.isFiniteElementWise()).andElementWise(this.radius.isFiniteElementWise());
  }

  /**
   * {@inheritDoc}
   */
  public boolean isReal() {
    return false;
  }

  /**
   * {@inheritDoc}
   */
  public boolean isComplex() {
    return true;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix add(final DoubleComplexIntervalMatrix y) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.add(y.getMiddle());

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = this.middle.add(y.getMiddle());
    DoubleMatrix rad = (mid.subtract(c1)).absElementWise().getRealPart();

    if (isPointMatrix() == false) {
      rad = rad.add(this.radius);
    }

    if (y.isPointMatrix() == false) {
      rad = rad.add(y.getRadius());
    }

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);

    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix addElementWise(final DoubleComplexIntervalNumber y) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.addElementWise(y.getMiddle());

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = this.middle.addElementWise(y.getMiddle());
    DoubleMatrix rad = (mid.subtract(c1)).absElementWise().getRealPart();

    if (isPointMatrix() == false) {
      rad = rad.add(this.radius);
    }

    if (y.isPointScalar() == false) {
      rad = rad.addElementWise(y.getRadius());
    }

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

//  /**
//   * @see org.mklab.cga.interval.matrix.IntervalMatrix#add(org.mklab.nfc.matrix.Matrix)
//   */
//  @Override
//  public DoubleComplexIntervalMatrix add(final Matrix y) {
//    if (y instanceof IntervalMatrix) {
//      return add((DoubleComplexIntervalMatrix)y);
//    }
//
//    RoundModeManager manager = RoundModeManager.getManager();
//    RoundMode oldRoundMode = manager.getRoundMode();
//
//    manager.setRoundMode(RoundMode.ROUND_DOWN);
//    DoubleComplexMatrix c1 = this.middle.add(y);
//
//    manager.setRoundMode(RoundMode.ROUND_UP);
//    DoubleComplexMatrix mid = this.middle.add(y);
//    DoubleComplexMatrix rad;
//    if (isPointMatrix()) {
//      rad = (mid.subtract(c1)).absElementWise();
//    } else {
//      rad = (mid.subtract(c1)).absElementWise().add(this.radius);
//    }
//
//    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
//    manager.setRoundMode(oldRoundMode);
//    return ans;
//  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix addElementWise(final int y) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.addElementWise(y);

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = this.middle.addElementWise(y);
    DoubleMatrix rad;
    if (isPointMatrix()) {
      rad = (mid.subtract(c1)).absElementWise().getRealPart();
    } else {
      rad = (mid.subtract(c1)).absElementWise().getRealPart().add(this.radius);
    }

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix addElementWise(final double y) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.addElementWise(y);

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = this.middle.addElementWise(y);
    DoubleMatrix rad;
    if (isPointMatrix()) {
      rad = (mid.subtract(c1)).absElementWise().getRealPart();
    } else {
      rad = (mid.subtract(c1)).absElementWise().getRealPart().add(this.radius);
    }

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix addElementWise(final DoubleComplexNumber y) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.addElementWise(y);

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = this.middle.addElementWise(y);
    DoubleMatrix rad;
    if (isPointMatrix()) {
      rad = (mid.subtract(c1)).absElementWise().getRealPart();
    } else {
      rad = (mid.subtract(c1)).absElementWise().getRealPart().add(this.radius);
    }

    manager.setRoundMode(oldRoundMode);
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix subtract(final DoubleComplexIntervalMatrix y) {// IC-IR,
    // IC-IC,
    // (IR-IC)
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.subtract(y.getMiddle());

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = this.middle.subtract(y.getMiddle());
    DoubleMatrix rad = (mid.subtract(c1)).absElementWise().getRealPart();
    if (isPointMatrix() == false) {
      rad = rad.add(this.radius);
    }
    if (y.isPointMatrix() == false) {
      rad = rad.add(y.getRadius());
    }

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix subtractElementWise(final DoubleComplexIntervalNumber y) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.subtractElementWise(y.getMiddle());

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = this.middle.subtractElementWise(y.getMiddle());
    DoubleMatrix rad = (mid.subtract(c1)).absElementWise().getRealPart();
    if (isPointMatrix() == false) {
      rad = rad.add(this.radius);
    }
    if (y.isPointScalar() == false) {
      rad = rad.addElementWise(y.getRadius());
    }

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

// /**
//   * @see org.mklab.cga.interval.matrix.IntervalMatrix#subtract(org.mklab.nfc.matrix.Matrix)
//   */
//  @Override
//  public DoubleComplexIntervalMatrix subtract(final Matrix y) {
//    if (y instanceof IntervalMatrix) {
//      return subtract((DoubleComplexIntervalMatrix)y);
//    }
//
//    RoundModeManager manager = RoundModeManager.getManager();
//    RoundMode oldRoundMode = manager.getRoundMode();
//
//    manager.setRoundMode(RoundMode.ROUND_DOWN);
//    DoubleComplexMatrix c1 = this.middle.subtract(y);
//
//    manager.setRoundMode(RoundMode.ROUND_UP);
//    DoubleComplexMatrix mid = this.middle.subtract(y);
//    DoubleComplexMatrix rad;
//    if (isPointMatrix()) {
//      rad = (mid.subtract(c1)).absElementWise();
//    } else {
//      rad = (mid.subtract(c1)).absElementWise().add(this.radius);
//    }
//
//    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
//    manager.setRoundMode(oldRoundMode);
//    return ans;
//  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix subtractElementWise(final int y) {// ICM-R
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.subtractElementWise(y);

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = this.middle.subtractElementWise(y);
    DoubleMatrix rad;
    if (isPointMatrix()) {
      rad = (mid.subtract(c1)).absElementWise().getRealPart();
    } else {
      rad = (mid.subtract(c1)).absElementWise().getRealPart().add(this.radius);
    }

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix subtractElementWise(final double y) {// ICM-R
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.subtractElementWise(y);

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = this.middle.subtractElementWise(y);
    DoubleMatrix rad;
    if (isPointMatrix()) {
      rad = (mid.subtract(c1)).absElementWise().getRealPart();
    } else {
      rad = (mid.subtract(c1)).absElementWise().getRealPart().add(this.radius);
    }

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix subtractElementWise(final DoubleComplexNumber y) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.subtractElementWise(y);

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = this.middle.subtractElementWise(y);
    DoubleMatrix rad;
    if (isPointMatrix()) {
      rad = (mid.subtract(c1)).absElementWise().getRealPart();
    } else {
      rad = (mid.subtract(c1)).absElementWise().getRealPart().add(this.radius);
    }

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix multiply(final DoubleComplexIntervalMatrix y) {// IC*IC,
    // IC*IR
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();
    
    DoubleMatrix a_mid_real = this.middle.getRealPart();
    DoubleMatrix a_mid_imag = this.middle.getImaginaryPart();
    
    DoubleMatrix b_mid_real = y.getMiddle().getRealPart();
    DoubleMatrix b_mid_imag = y.getMiddle().getImaginaryPart();
    
    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleMatrix c1_real = a_mid_real.multiply(b_mid_real).add(a_mid_imag.unaryMinus().multiply(b_mid_imag));
    DoubleMatrix c1_imag = a_mid_real.multiply(b_mid_imag).add(a_mid_imag.multiply(b_mid_real));
    DoubleComplexMatrix c1 = this.radius.createComplex(c1_real, c1_imag);
    
    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleMatrix c2_real = a_mid_real.multiply(b_mid_real).add(a_mid_imag.unaryMinus().multiply(b_mid_imag));
    DoubleMatrix c2_imag = a_mid_real.multiply(b_mid_imag).add(a_mid_imag.multiply(b_mid_real));
    DoubleComplexMatrix c2 = this.radius.createComplex(c2_real, c2_imag);

    DoubleComplexMatrix mid = c1.add(c2.subtract(c1).divide(2));
    DoubleMatrix rad;

    if (isPointMatrix()) {
      if (y.isPointMatrix()) {
        rad = (mid.subtract(c1)).absElementWise().getRealPart();
      } else {
        rad = (mid.subtract(c1)).absElementWise().getRealPart().add((this.middle).absElementWise().getRealPart().multiply(y.getRadius()));
      }
    } else if (y.isPointMatrix()) {
      rad = (mid.subtract(c1)).absElementWise().getRealPart().add(this.radius.multiply((y.getMiddle()).absElementWise().getRealPart()));
    } else {
      rad = (mid.subtract(c1)).absElementWise().getRealPart().add(this.radius.multiply((y.getMiddle()).absElementWise().getRealPart().add(y.getRadius())))
          .add((this.middle).absElementWise().getRealPart().multiply(y.getRadius()));
    }

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

//  /**
//   * @see org.mklab.cga.interval.matrix.IntervalMatrix#multiply(org.mklab.nfc.matrix.Matrix)
//   */
//  @Override
//  public DoubleComplexIntervalMatrix multiply(final Matrix y) {// IC*R, IC*C
//    if (y instanceof IntervalMatrix) {
//      return multiply((DoubleComplexIntervalMatrix)y);
//    }
//
//    RoundModeManager manager = RoundModeManager.getManager();
//    RoundMode oldRoundMode = manager.getRoundMode();
//    DoubleComplexMatrix c1, c2;
//
//    if (y.isReal()) {// IC*R
//      manager.setRoundMode(RoundMode.ROUND_DOWN);
//      c1 = this.middle.multiply(y);
//
//      manager.setRoundMode(RoundMode.ROUND_UP);
//      c2 = this.middle.multiply(y);
//    } else {
//      DoubleComplexMatrix a_mid_real = this.middle.getRealPart();
//      DoubleComplexMatrix a_mid_imag = this.middle.getImaginaryPart();
//
//      DoubleComplexMatrix b_real = y.getRealPart();
//      DoubleComplexMatrix b_imag = y.getImaginaryPart();
//
//      manager.setRoundMode(RoundMode.ROUND_DOWN);
//      DoubleComplexMatrix c1_real = a_mid_real.multiply(b_real).add(a_mid_imag.unaryMinus().multiply(b_imag));
//      DoubleComplexMatrix c1_imag = a_mid_real.multiply(b_imag).add(a_mid_imag.multiply(b_real));
//      c1 = this.radius.createComplexMatrix(c1_real, c1_imag);
//
//      manager.setRoundMode(RoundMode.ROUND_UP);
//      DoubleComplexMatrix c2_real = a_mid_real.multiply(b_real).add(a_mid_imag.unaryMinus().multiply(b_imag));
//      DoubleComplexMatrix c2_imag = a_mid_real.multiply(b_imag).add(a_mid_imag.multiply(b_real));
//      c2 = this.radius.createComplexMatrix(c2_real, c2_imag);
//    }
//
//    DoubleComplexMatrix mid = c1.add(c2.subtract(c1).divide(2));
//    DoubleComplexMatrix rad;
//    if (isPointMatrix()) {
//      rad = (mid.subtract(c1)).absElementWise();
//    } else {
//      rad = (mid.subtract(c1)).absElementWise().add(this.radius.multiply((y).absElementWise()));
//    }
//
//    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
//    manager.setRoundMode(oldRoundMode);
//    return ans;
//  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix multiplyElementWise(final DoubleComplexIntervalMatrix b) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();
    
    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleMatrix c1_real = this.middle.getRealPart().multiplyElementWise(b.getMiddle().getRealPart())
        .add(this.middle.getImaginaryPart().unaryMinus().multiplyElementWise(b.getMiddle().getImaginaryPart()));
    DoubleMatrix c1_imag = this.middle.getRealPart().multiplyElementWise(b.getMiddle().getImaginaryPart())
        .add(this.middle.getImaginaryPart().multiplyElementWise(b.getMiddle().getRealPart()));
    DoubleComplexMatrix c1 = this.radius.createComplex(c1_real, c1_imag);
    
    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleMatrix c2_real = this.middle.getRealPart().multiplyElementWise(b.getMiddle().getRealPart())
        .add(this.middle.getImaginaryPart().unaryMinus().multiplyElementWise(b.getMiddle().getImaginaryPart()));
    DoubleMatrix c2_imag = this.middle.getRealPart().multiplyElementWise(b.getMiddle().getImaginaryPart())
        .add(this.middle.getImaginaryPart().multiplyElementWise(b.getMiddle().getRealPart()));
    DoubleComplexMatrix c2 = this.radius.createComplex(c2_real, c2_imag);

    DoubleComplexMatrix mid = c1.add(c2.subtract(c1).divide(2));
    DoubleMatrix rad = (mid.multiply(c1)).absElementWise().getRealPart()
        .add(this.radius.multiplyElementWise((b.getMiddle()).absElementWise().getRealPart().add(b.getRadius())))
        .add((this.middle).absElementWise().getRealPart().multiplyElementWise(b.getRadius()));

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix multiply(final DoubleComplexIntervalNumber b) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleMatrix c1_real = this.middle.getRealPart().multiply(b.getMiddle().getRealPart())
        .add(this.middle.getImaginaryPart().unaryMinus().multiply(b.getMiddle().getImaginaryPart()));
    DoubleMatrix c1_imag = this.middle.getRealPart().multiply(b.getMiddle().getImaginaryPart()).add(this.middle.getImaginaryPart().multiply(b.getMiddle().getRealPart()));
    DoubleComplexMatrix c1 = this.radius.createComplex(c1_real, c1_imag);
    
    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleMatrix c2_real = this.middle.getRealPart().multiply(b.getMiddle().getRealPart())
        .add(this.middle.getImaginaryPart().unaryMinus().multiply(b.getMiddle().getImaginaryPart()));
    DoubleMatrix c2_imag = this.middle.getRealPart().multiply(b.getMiddle().getImaginaryPart()).add(this.middle.getImaginaryPart().multiply(b.getMiddle().getRealPart()));
    DoubleComplexMatrix c2 = this.radius.createComplex(c2_real, c2_imag);

    DoubleComplexMatrix mid = c1.add(c2.subtract(c1).divide(2));
    DoubleMatrix rad = (mid.subtract(c1)).absElementWise().getRealPart().add(this.radius.multiply(b.getMiddle().abs().getRealPart().add(b.getRadius())))
        .add((this.middle).absElementWise().getRealPart().multiply(b.getRadius()));

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

//  /**
//   * @see org.mklab.cga.interval.matrix.IntervalMatrix#multiplyElementWise(org.mklab.nfc.matrix.Matrix)
//   */
//  @Override
//  public DoubleComplexIntervalMatrix multiplyElementWise(final Matrix y) {
//    if (y instanceof IntervalMatrix) {
//      return multiplyElementWise((DoubleComplexIntervalMatrix)y);
//    }
//
//    RoundModeManager manager = RoundModeManager.getManager();
//    RoundMode oldRoundMode = manager.getRoundMode();
//
//    DoubleComplexMatrix c1, c2;
//    if (y.isReal()) {
//      manager.setRoundMode(RoundMode.ROUND_DOWN);
//      c1 = this.middle.multiplyElementWise(y);
//
//      manager.setRoundMode(RoundMode.ROUND_UP);
//      c2 = this.middle.multiplyElementWise(y);
//    } else if (y.isComplex()) {
//      manager.setRoundMode(RoundMode.ROUND_DOWN);
//      DoubleComplexMatrix c1_real = this.middle.getRealPart().multiplyElementWise(y.getRealPart())
//          .add(this.middle.getImaginaryPart().unaryMinus().multiplyElementWise(y.getImaginaryPart()));
//      DoubleComplexMatrix c1_imag = this.middle.getRealPart().multiplyElementWise(y.getImaginaryPart()).add(this.middle.getImaginaryPart().multiplyElementWise(y.getRealPart()));
//
//      c1 = this.radius.createComplexMatrix(c1_real, c1_imag);
//
//      manager.setRoundMode(RoundMode.ROUND_UP);
//      DoubleComplexMatrix c2_real = this.middle.getRealPart().multiplyElementWise(y.getRealPart())
//          .add((this.middle).getImaginaryPart().unaryMinus().multiplyElementWise(y.getImaginaryPart()));
//      DoubleComplexMatrix c2_imag = this.middle.getRealPart().multiplyElementWise(y.getImaginaryPart()).add(this.middle.getImaginaryPart().multiplyElementWise(y.getRealPart()));
//
//      c2 = this.radius.createComplexMatrix(c2_real, c2_imag);
//    } else {
//      manager.setRoundMode(oldRoundMode);
//      throw new RuntimeException("Not implemented."); //$NON-NLS-1$
//    }
//
//    DoubleComplexMatrix mid = c1.add(c2.subtract(c1).divide(2));
//    DoubleComplexMatrix rad = (mid.subtract(c1)).absElementWise().add(this.radius.multiplyElementWise((y).absElementWise()));
//
//    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
//    manager.setRoundMode(oldRoundMode);
//    return ans;
//  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix multiply(final int y) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.multiply(y);

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix c2 = this.middle.multiply(y);

    DoubleComplexMatrix mid = c1.add(c2.subtract(c1).divide(2));
    DoubleMatrix rad = (mid.subtract(c1)).absElementWise().getRealPart().add(this.radius.multiply(Math.abs(y)));

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix multiply(final double value) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.multiply(value);

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix c2 = this.middle.multiply(value);

    DoubleComplexMatrix mid = c1.add(c2.subtract(c1).divide(2));
    DoubleMatrix rad = (mid.subtract(c1)).absElementWise().getRealPart().add(this.radius.multiply(Math.abs(value)));

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix multiply(final DoubleComplexNumber d) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    DoubleMatrix a_mid_real = this.middle.getRealPart();
    DoubleMatrix a_mid_imag = this.middle.getImaginaryPart();

    DoubleNumber b_real = d.getRealPart();
    DoubleNumber b_imag = d.getImaginaryPart();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleMatrix c1_real = a_mid_real.multiply(b_real).add(a_mid_imag.unaryMinus().multiply(b_imag));
    DoubleMatrix c1_imag = a_mid_real.multiply(b_imag).add(a_mid_imag.multiply(b_real));
    DoubleComplexMatrix c1 = this.radius.createComplex(c1_real, c1_imag);

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleMatrix c2_real = a_mid_real.multiply(b_real).add(a_mid_imag.unaryMinus().multiply(b_imag));
    DoubleMatrix c2_imag = a_mid_real.multiply(b_imag).add(a_mid_imag.multiply(b_real));
    DoubleComplexMatrix c2 = this.radius.createComplex(c2_real, c2_imag);

    DoubleComplexMatrix mid = c1.add(c2.subtract(c1).divide(2));
    DoubleMatrix rad = (mid.subtract(c1)).absElementWise().getRealPart().add(this.radius.multiply((d).abs().getRealPart()));

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

//  /**
//   * @see org.mklab.nfc.matrix.MatrixElementWiseOperator#divideElementWise(org.mklab.nfc.matrix.Matrix)
//   */
//  @Override
//  @SuppressWarnings("unchecked")
//  publicDoubleComplexIntervalMatrix divideElementWise(final Matrix b) {
//    RoundModeManager manager = RoundModeManager.getManager();
//    RoundMode oldRoundMode = manager.getRoundMode();
//
//    if (b instanceof DoubleComplexIntervalMatrix) {
//      DoubleComplexIntervalMatrix bb = (DoubleComplexIntervalMatrix)b;
//
//      DoubleComplexMatrix x = bb.getMiddle().getRealPart();
//      DoubleComplexMatrix y = bb.getMiddle().getImaginaryPart();
//
//      manager.setRoundMode(RoundMode.ROUND_DOWN);
//      DoubleComplexMatrix Ninf = x.multiplyElementWise(x).add(y.multiplyElementWise(y)).add(bb.getRadius().unaryMinus().multiplyElementWise(bb.getRadius()));
//
//      manager.setRoundMode(RoundMode.ROUND_UP);
//      DoubleComplexMatrix Nsup = x.multiplyElementWise(x).add(y.multiplyElementWise(y)).add(bb.getRadius().unaryMinus().multiplyElementWise(bb.getRadius()));
//      DoubleComplexMatrix x2 = (x.multiplyElementWise(Ninf)).maxElementWise(x.multiplyElementWise(Nsup));
//      DoubleComplexMatrix y2 = (y.multiplyElementWise(Ninf)).maxElementWise(x.multiplyElementWise(Nsup));
//
//      manager.setRoundMode(RoundMode.ROUND_DOWN);
//      DoubleComplexMatrix x1 = (x.multiplyElementWise(Ninf)).maxElementWise(x.multiplyElementWise(Nsup));
//      DoubleComplexMatrix y1 = (y.multiplyElementWise(Ninf)).maxElementWise(x.multiplyElementWise(Nsup));
//      DoubleComplexMatrix c1 = this.radius.createComplexMatrix(x1, y2.unaryMinus());
//
//      manager.setRoundMode(RoundMode.ROUND_UP);
//      DoubleComplexMatrix c2 = this.radius.createComplexMatrix(x2, y1.unaryMinus());
//
//      DoubleComplexMatrix binvmid = c1.add(c2.subtract(c1).divide(2));
//      DoubleComplexMatrix binvrad = (binvmid.subtract(c1)).absElementWise().add(bb.getRadius().divideElementWise(Ninf));
//      DoubleComplexIntervalMatrix binv = new DoubleComplexIntervalMatrix(binvmid, binvrad);
//      DoubleComplexIntervalMatrix c = this.multiplyElementWise(binv);
//
//      manager.setRoundMode(oldRoundMode);
//      return c;
//    }
//
//    manager.setRoundMode(oldRoundMode);
//    throw new UnsupportedOperationException();
//  }

  /**
   * {@inheritDoc}
   */
  public  DoubleComplexIntervalMatrix sqrtElementWise() {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix inf = this.infimum.sqrtElementWise();

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix sup = this.supremum.sqrtElementWise();

    DoubleComplexIntervalMatrix ans = createInfSup(inf, sup);
    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix diagonalToVector() {
    final DoubleComplexMatrix mid = this.middle.diagonalToVector();
    final DoubleMatrix rad = this.radius.diagonalToVector();
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix vectorToDiagonal() {
    final DoubleComplexMatrix mid = this.middle.vectorToDiagonal();
    final DoubleMatrix rad = this.radius.vectorToDiagonal();
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix reshape(int newRowSize, int newColumnSize) {
    final DoubleComplexMatrix mid = this.middle.reshape(newRowSize, newColumnSize);
    final DoubleMatrix rad = this.radius.reshape(newRowSize, newColumnSize);
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix resize(int newRowSize, int newColumnSize) {
    final DoubleComplexMatrix mid = this.middle.resize(newRowSize, newColumnSize);
    final DoubleMatrix rad = this.radius.resize(newRowSize, newColumnSize);
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexMatrix migElementWise() {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_NEAR);

    DoubleMatrix ans;

    if (isPointMatrix()) {
      ans = (this.middle).absElementWise().getRealPart();
    } else {
      manager.setRoundMode(RoundMode.ROUND_DOWN);
      ans = (this.middle).absElementWise().subtract(this.radius.toComplex()).getRealPart();

      manager.setRoundMode(RoundMode.ROUND_NEAR);
    }

    BooleanMatrix B = ans.compareElementWise(".>=", this.radius.createZero(ans.getRowSize(), ans.getColumnSize())); //$NON-NLS-1$
    IntMatrix zoB = IntervalUtil.toZOMatrix(B);
    DoubleComplexMatrix ans2 = ans.toComplex().multiplyElementWise(new DoubleComplexMatrix(zoB));

    manager.setRoundMode(oldRoundMode);
    return ans2;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexMatrix comparisonMatrix() {
    return IntervalUtil.comparisonMatrix(this);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexMatrix abssElementWise() {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_UP);

    DoubleComplexMatrix ans;
    if (isPointMatrix()) {
      ans = (this.middle).absElementWise();
    } else {
      ans = (this.middle).absElementWise().add(this.radius.toComplex());
    }

    manager.setRoundMode(oldRoundMode);
    return ans;
  }

//  /**
//   * @see org.mklab.cga.interval.matrix.IntervalMatrix#equals(org.mklab.nfc.matrix.Matrix, double)
//   */
//  public boolean equals(Matrix opponent, double tolerance) {
//    if (opponent instanceof IntervalMatrix == false) {
//      return false;
//    }
//    return equals((DoubleComplexIntervalMatrix)opponent, tolerance);
//  }

  /**
   * {@inheritDoc}
   */
  public boolean equals(DoubleComplexIntervalMatrix opponent, double tolerance) {
    return this.middle.equals(opponent.getMiddle(), tolerance) && this.radius.equals(opponent.getRadius(), tolerance);
  }

  //  /**
  //   * @see org.mklab.cga.interval.IntervalMatrix#copy(org.mklab.nfc.matrix.Matrix)
  //   */
  //  public void copy(final Matrix source) {
  //    if (isSameSize(source) == false) {
  //      throw new ConflictionException();
  //    }
  //    
  //    if (source instanceof IntMatrix) {
  //      copy((IntMatrix)source);
  //      return;
  //    }
  //    if (source instanceof DoubleMatrix) {
  //      copy((DoubleMatrix)source);
  //      return;
  //    }
  //    if (source instanceof IntervalMatrix) {
  //      copy((IntervalMatrix)source);
  //      return;
  //    }
  //
  //    throw new RuntimeException("Not Implemented."); //$NON-NLS-1$
  //  }

//  /**
//   * {@inheritDoc}
//   */
//  public void copy(DoubleComplexIntervalMatrix source) {
//    this.middle.copy(source.getMiddle());
//    this.radius.copy(source.getRadius());
//    updateInfinumSupremum();
//  }
//
//  /**
//   * {@inheritDoc}
//   */
//  public void copy(IntMatrix source) {
//    this.middle.copy(source);
//    this.radius.copy(source.createZero());
//    updateInfinumSupremum();
//  }
//
//  /**
//   * {@inheritDoc}
//   */
//  public void copy(DoubleMatrix source) {
//    this.middle.copy(source);
//    this.radius.copy(source.createZero());
//    updateInfinumSupremum();
//  }

  /**
   * {@inheritDoc}
   */
  @Override
  public Object clone() {
    DoubleComplexIntervalMatrix ans = (DoubleComplexIntervalMatrix)super.clone();
    return ans;
    //return new DoubleComplexIntervalMatrix(this.middle.clone(), this.radius.clone());
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexMatrix getError() {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix error = sup(this.middle, this.radius).subtract(inf(this.middle, this.radius));

    manager.setRoundMode(oldRoundMode);
    return error;
  }

  /**
   * 下限を求めます。
   * 
   * @param mid 中心
   * @param rad 半径
   * @return 下限
   */
  public static DoubleComplexMatrix infimum(DoubleComplexMatrix mid, DoubleMatrix rad) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleMatrix real = mid.getRealPart().subtract(rad);
    DoubleMatrix imag = mid.getImaginaryPart().subtract(rad);
    DoubleComplexMatrix inf = rad.createComplex(real, imag);

    manager.setRoundMode(oldRoundMode);
    return inf;
  }

  /**
   * 上限を求めます。
   * 
   * @param mid 中心
   * @param rad 半径
   * @return 上限
   */
  public static DoubleComplexMatrix suppremum(DoubleComplexMatrix mid, DoubleMatrix rad) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleMatrix real = mid.getRealPart().add(rad);
    DoubleMatrix imag = mid.getImaginaryPart().add(rad);
    DoubleComplexMatrix sup = rad.createComplex(real, imag);

    manager.setRoundMode(oldRoundMode);

    return sup;
  }
  
  /**
   * 区間の半径を求めます。
   * 
   * @param inf infimum
   * @param sup supremum
   * @return 区間の半径。
   */
  public static DoubleMatrix radius(DoubleComplexMatrix inf, DoubleComplexMatrix sup) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = middle(inf, sup);
    DoubleMatrix rad = mid.subtract(inf).absElementWise().getRealPart();

    manager.setRoundMode(oldRoundMode);
    return rad;
  }

  /**
   * 区間の中心を求めます。
   * 
   * @param inf infimum
   * @param sup supremum
   * @return 区間の中心。
   */
  public static DoubleComplexMatrix middle(DoubleComplexMatrix inf, DoubleComplexMatrix sup) {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = inf.add(sup.subtract(inf).divide(2));

    manager.setRoundMode(oldRoundMode);
    return mid;
  }

  /**
   * {@inheritDoc}
   */
  public void setColumnVector(final int column, final DoubleComplexIntervalMatrix source) {
    this.middle.setColumnVector(column, source.getMiddle());
    this.radius.setColumnVector(column, source.getRadius());
    updateInfinumSupremum();
  }
  
  /**
   * {@inheritDoc}
   */
  public void setColumnVectors(final int minimum, final int maximum, final DoubleComplexIntervalMatrix source) {
    this.middle.setColumnVectors(minimum, maximum, source.getMiddle());
    this.radius.setColumnVectors(minimum, maximum, source.getRadius());
    updateInfinumSupremum();
  }

  /**
   * {@inheritDoc}
   */
  public void setColumnVectors(final IntMatrix columnIndex, final DoubleComplexIntervalMatrix source) {
    this.middle.setColumnVectors(columnIndex, source.getMiddle());
    this.radius.setColumnVectors(columnIndex, source.getRadius());
    updateInfinumSupremum();
  }

  /**
   * {@inheritDoc}
   */
  public void setRowVector(final int row, final DoubleComplexIntervalMatrix source) {
    this.middle.setRowVector(row, source.getMiddle());
    this.radius.setRowVector(row, source.getRadius());
    updateInfinumSupremum();
  }

  /**
   * {@inheritDoc}
   */
  public void setRowVectors(final IntMatrix rowIndex, final DoubleComplexIntervalMatrix source) {
    this.middle.setRowVectors(rowIndex, source.getMiddle());
    this.radius.setRowVectors(rowIndex, source.getRadius());
    updateInfinumSupremum();
  }

  /**
   * {@inheritDoc}
   */
  public void setRowVectors(final int minimum, final int maximum, final DoubleComplexIntervalMatrix source) {
    this.middle.setRowVectors(minimum, maximum, source.getMiddle());
    this.radius.setRowVectors(minimum, maximum, source.getRadius());
    updateInfinumSupremum();
  }

//  /**
//   * @see org.mklab.cga.interval.matrix.IntervalMatrix#compareElementWise(java.lang.String, org.mklab.nfc.matrix.Matrix)
//   */
//  public BooleanMatrix compareElementWise(String operator, Matrix opponent) {
//    if (opponent instanceof BaseMatrix<?, ?>) {
//      return compareElementWise(operator, (BaseMatrix<?, ?>)opponent);
//    }
//
//    if (opponent instanceof DoubleMatrix) {
//      return compareElementWise(operator, (DoubleMatrix)opponent);
//    }
//
//    if (opponent instanceof IntMatrix) {
//      return compareElementWise(operator, (IntMatrix)opponent);
//    }
//
//    throw new UnsupportedOperationException();
//  }

  /**
   * {@inheritDoc}
   */
  public BooleanMatrix compareElementWise(String operator, DoubleComplexIntervalMatrix opponent) {
    if (operator.equals(".==")) { //$NON-NLS-1$
      return this.middle.compareElementWise(operator, opponent.getMiddle()).andElementWise(this.radius.isZero());
    }

    if (operator.equals(".!=")) { //$NON-NLS-1$
      return this.middle.compareElementWise(operator, opponent.getMiddle()).andElementWise(this.radius.isZero()).notElementWise();
    }

    throw new UnsupportedOperationException();
  }

  /**
   * 行列<code>opponent</code>の各成分と成分毎に<code>operator</code>で指定された演算子で比較し, それぞれの結果を成分とする{@link BooleanMatrix}を生成します。
   * 
   * @param operator 比較演算子(". &lt;", ". &lt;=", ".&gt;", ".&gt;=", ".==", ".!=")
   * @param opponent 比較対象
   * 
   * @return 比較結果を成分とする{@link BooleanMatrix}
   */
  public BooleanMatrix compareElementWise(String operator, IntMatrix opponent) {
    if (operator.equals(".==")) { //$NON-NLS-1$
      return this.middle.compareElementWise(operator, opponent).andElementWise(this.radius.compareElementWise(operator, opponent));
    }

    if (operator.equals(".!=")) { //$NON-NLS-1$
      return this.middle.compareElementWise(operator, opponent).andElementWise(this.radius.compareElementWise(operator, opponent));
    }

    throw new UnsupportedOperationException();
  }

  /**
   * 行列<code>opponent</code>の各成分と成分毎に<code>operator</code>で指定された演算子で比較し, それぞれの結果を成分とする{@link BooleanMatrix}を生成します。
   * 
   * @param operator 比較演算子(". &lt;", ". &lt;=", ".&gt;", ".&gt;=", ".==", ".!=")
   * @param opponent 比較対象
   * 
   * @return 比較結果を成分とする{@link BooleanMatrix}
   */
  public BooleanMatrix compareElementWise(String operator, DoubleMatrix opponent) {
    if (operator.equals(".==")) { //$NON-NLS-1$
      return this.middle.compareElementWise(operator, opponent).andElementWise(this.radius.compareElementWise(operator, opponent));
    }

    if (operator.equals(".!=")) { //$NON-NLS-1$
      return this.middle.compareElementWise(operator, opponent).andElementWise(this.radius.compareElementWise(operator, opponent));
    }

    throw new UnsupportedOperationException();
  }

  /**
   * {@inheritDoc}
   */
  public void setSubMatrix(int rowMinimum, int rowMaximum, int columnMinimum, int columnMaximum,DoubleComplexIntervalMatrix source) {
    this.middle.setSubMatrix(rowMinimum, rowMaximum, columnMinimum, columnMaximum, source.getMiddle());
    this.radius.setSubMatrix(rowMinimum, rowMaximum, columnMinimum, columnMaximum, source.getRadius());
    updateInfinumSupremum();
  }

//  /**
//   * @see org.mklab.cga.interval.matrix.IntervalMatrix#setSubMatrix(int, int, int, int, org.mklab.nfc.matrix.Matrix)
//   */
//  public void setSubMatrix(int rowMinimum, int rowMaximum, int columnMinimum, int columnMaximum, Matrix source) {
//    if (source instanceof IntervalMatrix) {
//      setSubMatrix(rowMinimum, rowMaximum, columnMinimum, columnMaximum, (DoubleComplexIntervalMatrix)source);
//      return;
//    }
//
//    if (source.isComplex() == false) {
//      throw new RuntimeException("Not implemented"); //$NON-NLS-1$
//    }
//
//    this.middle.setSubMatrix(rowMinimum, rowMaximum, columnMinimum, columnMaximum, source);
//    final DoubleComplexMatrix rad = this.radius.createZero(source.getRowSize(), source.getColumnSize());
//    this.radius.setSubMatrix(rowMinimum, rowMaximum, columnMinimum, columnMaximum, rad);
//    updateInfinumSupremum();
//  }

  /**
   * {@inheritDoc}
   */
  public void setSubMatrix(IntMatrix rowIndex, int columnMinimum, int columnMaximum,DoubleComplexIntervalMatrix source) {
    this.middle.setSubMatrix(rowIndex, columnMinimum, columnMaximum, source.getMiddle());
    this.radius.setSubMatrix(rowIndex, columnMinimum, columnMaximum, source.getRadius());
    updateInfinumSupremum();
  }

//  /**
//   * @see org.mklab.cga.interval.matrix.IntervalMatrix#setSubMatrix(org.mklab.nfc.matrix.IntMatrix, int, int, org.mklab.nfc.matrix.Matrix)
//   */
//  public void setSubMatrix(IntMatrix rowIndex, int columnMinimum, int columnMaximum, Matrix source) {
//    if (source instanceof IntervalMatrix) {
//      setSubMatrix(rowIndex, columnMinimum, columnMaximum, (DoubleComplexIntervalMatrix)source);
//      return;
//    }
//
//    if (source.isComplex() == false) {
//      throw new RuntimeException("Not implemented"); //$NON-NLS-1$
//    }
//
//    this.middle.setSubMatrix(rowIndex, columnMinimum, columnMaximum, source);
//    final DoubleComplexMatrix rad = this.radius.createZero(source.getRowSize(), source.getColumnSize());
//    this.radius.setSubMatrix(rowIndex, columnMinimum, columnMaximum, rad);
//    updateInfinumSupremum();
//  }

  /**
   * {@inheritDoc}
   */
  public void setSubMatrix(int row, IntMatrix columnIndex,DoubleComplexIntervalMatrix source) {
    setSubMatrix(row, row, columnIndex, source);
  }

  /**
   * {@inheritDoc}
   */
  public void setSubMatrix(int rowMinimum, int rowMaximum, IntMatrix columnIndex,DoubleComplexIntervalMatrix source) {
    this.middle.setSubMatrix(rowMinimum, rowMaximum, columnIndex, source.getMiddle());
    this.radius.setSubMatrix(rowMinimum, rowMaximum, columnIndex, source.getRadius());
    updateInfinumSupremum();
  }

//  /**
//   * @see org.mklab.cga.interval.matrix.IntervalMatrix#setSubMatrix(int, int, org.mklab.nfc.matrix.IntMatrix, org.mklab.nfc.matrix.Matrix)
//   */
//  public void setSubMatrix(int rowMinimum, int rowMaximum, IntMatrix columnIndex, Matrix source) {
//    if (source instanceof IntervalMatrix) {
//      setSubMatrix(rowMinimum, rowMaximum, columnIndex, (DoubleComplexIntervalMatrix)source);
//      return;
//    }
//
//    if (source.isComplex() == false) {
//      throw new RuntimeException("Not implemented"); //$NON-NLS-1$
//    }
//
//    this.middle.setSubMatrix(rowMinimum, rowMaximum, columnIndex, source);
//    final DoubleComplexMatrix rad = this.radius.createZero(source.getRowSize(), source.getColumnSize());
//    this.radius.setSubMatrix(rowMinimum, rowMaximum, columnIndex, rad);
//    updateInfinumSupremum();
//  }

  /**
   * {@inheritDoc}
   */
  public void setSubMatrix(IntMatrix rowIndex, IntMatrix columnIndex,DoubleComplexIntervalMatrix source) {
    this.middle.setSubMatrix(rowIndex, columnIndex, source.getMiddle());
    this.radius.setSubMatrix(rowIndex, columnIndex, source.getRadius());
    updateInfinumSupremum();
  }

//  /**
//   * @see org.mklab.cga.interval.matrix.IntervalMatrix#setSubMatrix(org.mklab.nfc.matrix.IntMatrix, org.mklab.nfc.matrix.IntMatrix, org.mklab.nfc.matrix.Matrix)
//   */
//  public void setSubMatrix(IntMatrix rowIndex, IntMatrix columnIndex, Matrix source) {
//    if (source instanceof IntervalMatrix) {
//      setSubMatrix(rowIndex, columnIndex, (DoubleComplexIntervalMatrix)source);
//      return;
//    }
//
//    if (source.isComplex() == false) {
//      throw new RuntimeException("Not implemented"); //$NON-NLS-1$
//    }
//
//    this.middle.setSubMatrix(rowIndex, columnIndex, source);
//    final DoubleComplexMatrix rad = this.radius.createZero(source.getRowSize(), source.getColumnSize());
//    this.radius.setSubMatrix(rowIndex, columnIndex, rad);
//    updateInfinumSupremum();
//  }

//  /**
//   * @see org.mklab.cga.interval.matrix.IntervalMatrix#setSubVector(int, int, org.mklab.nfc.matrix.Matrix)
//   */
//  public void setSubVector(int min, int max, Matrix source) {
//    if (source instanceof IntervalMatrix) {
//      setSubVector(min, max, (DoubleComplexIntervalMatrix)source);
//      return;
//    }
//
//    if (source.isComplex() == false) {
//      throw new RuntimeException("Not implemented"); //$NON-NLS-1$
//    }
//
//    this.middle.setSubVector(min, max, source);
//    final DoubleComplexMatrix rad = this.radius.createZero(source.getRowSize(), source.getColumnSize());
//    this.radius.setSubVector(min, max, rad);
//    updateInfinumSupremum();
//  }

  /**
   * {@inheritDoc}
   */
  public void setSubVector(int minimum, int maximum,DoubleComplexIntervalMatrix source) {
    this.middle.setSubVector(minimum, maximum, source.getMiddle());
    this.radius.setSubVector(minimum, maximum, source.getRadius());
    updateInfinumSupremum();
  }

  /**
   * {@inheritDoc}
   */
  public void setSubVector(IntMatrix index,DoubleComplexIntervalMatrix source) {
    this.middle.setSubVector(index, source.getMiddle());
    this.radius.setSubVector(index, source.getRadius());
    updateInfinumSupremum();
  }

//  /**
//   * @see org.mklab.cga.interval.matrix.IntervalMatrix#setSubVector(org.mklab.nfc.matrix.IntMatrix, org.mklab.nfc.matrix.Matrix)
//   */
//  public void setSubVector(IntMatrix index, Matrix source) {
//    if (source instanceof IntervalMatrix) {
//      setSubVector(index, (DoubleComplexIntervalMatrix)source);
//      return;
//    }
//
//    if (source.isComplex() == false) {
//      throw new RuntimeException("Not implemented"); //$NON-NLS-1$
//    }
//
//    this.middle.setSubVector(index, source);
//    final DoubleComplexMatrix rad = this.radius.createZero(source.getRowSize(), source.getColumnSize());
//    this.radius.setSubVector(index, rad);
//    updateInfinumSupremum();
//  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix getSubMatrix(final int rowMinimum, final int rowMaximum, final int columnMinimum, final int columnMaximum) {
    final DoubleComplexMatrix mid = this.middle.getSubMatrix(rowMinimum, rowMaximum, columnMinimum, columnMaximum);
    final DoubleMatrix rad = this.radius.getSubMatrix(rowMinimum, rowMaximum, columnMinimum, columnMaximum);
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix getSubMatrix(int rowMinimum, int rowMaximum, IntMatrix columnIndex) {
    final DoubleComplexMatrix mid = this.middle.getSubMatrix(rowMinimum, rowMaximum, columnIndex);
    final DoubleMatrix rad = this.radius.getSubMatrix(rowMinimum, rowMaximum, columnIndex);
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix getSubMatrix(IntMatrix rowIndex, int columnMinimum, int columnMaximum) {
    final DoubleComplexMatrix mid = this.middle.getSubMatrix(rowIndex, columnMinimum, columnMaximum);
    final DoubleMatrix rad = this.radius.getSubMatrix(rowIndex, columnMinimum, columnMaximum);
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix getSubMatrix(IntMatrix rowIndex, IntMatrix columnIndex) {
    final DoubleComplexMatrix mid = this.middle.getSubMatrix(rowIndex, columnIndex);
    final DoubleMatrix rad = this.radius.getSubMatrix(rowIndex, columnIndex);
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix getSubVector(final IntMatrix index) {
    final DoubleComplexMatrix mid = this.middle.getSubVector(index);
    final DoubleMatrix rad = this.radius.getSubVector(index);
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleIntervalMatrix getRealPart() {
    DoubleMatrix inf = this.infimum.getRealPart();
    DoubleMatrix sup = this.supremum.getRealPart();
    return DoubleIntervalMatrix.createInfimumSupremum(inf, sup);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleIntervalMatrix getImaginaryPart() {
    DoubleMatrix inf = this.infimum.getImaginaryPart();
    DoubleMatrix sup = this.supremum.getImaginaryPart();
    return new DoubleIntervalMatrix(inf, sup);
  }

//  /**
//   * @see org.mklab.cga.interval.matrix.IntervalMatrix#setRealPart(org.mklab.nfc.matrix.Matrix)
//   */
//  public void setRealPart(final Matrix realPart) {
//    this.middle.setRealPart(realPart);
//    updateInfinumSupremum();
//  }

  /**
   * {@inheritDoc}
   */
  public void setRealPart(final IntMatrix realPart) {
    this.middle.setRealPart(realPart);
    updateInfinumSupremum();
  }

  /**
   * @param realPart real part
   */
  public void setRealPart(final DoubleMatrix realPart) {
    this.middle.setRealPart(realPart);
    updateInfinumSupremum();
  }

  /**
   * {@inheritDoc}
   */
  public void setRealPart(final DoubleIntervalMatrix realPart) {
    this.middle.setRealPart(realPart.getMiddle());
    updateInfinumSupremum();
  }

//  /**
//   * @see org.mklab.cga.interval.matrix.IntervalMatrix#setImaginaryPart(org.mklab.nfc.matrix.Matrix)
//   */
//  public void setImaginaryPart(final Matrix imaginaryPart) {
//    this.middle.setImaginaryPart(imaginaryPart);
//    updateInfinumSupremum();
//  }

  /**
   * {@inheritDoc}
   */
  public void setImaginaryPart(final IntMatrix imaginaryPart) {
    this.middle.setImaginaryPart(imaginaryPart);
    updateInfinumSupremum();
  }

  /**
   * @param imaginaryPart imaginary part
   */
  public void setImaginaryPart(final DoubleMatrix imaginaryPart) {
    throw new UnsupportedOperationException(Messages.getString("RealIntervalMatrix.12")); //$NON-NLS-1$
  }

  /**
   * {@inheritDoc}
   */
  public void setImaginaryPart(final DoubleIntervalMatrix imaginaryPart) {
    this.middle.setImaginaryPart(imaginaryPart.getMiddle());
    updateInfinumSupremum();
  }

  /**
   * 下限と上限を更新します。
   */
  private void updateInfinumSupremum() {
    this.infimum = inf(this.middle, this.radius);
    this.supremum = sup(this.middle, this.radius);
  }

//  /**
//   * @see org.mklab.nfc.matrix.FundamentalMatrix#appendDown(org.mklab.nfc.matrix.Matrix)
//   */
//  @Override
//  publicDoubleComplexIntervalMatrix appendDown(Matrix b) {
//    if (b instanceof IntervalMatrix) {
//      return appendDown((DoubleComplexIntervalMatrix)b);
//    }
//
//    return appendDown(new DoubleComplexIntervalMatrix((NumericalMatrix)b));
//  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix appendDown(DoubleComplexIntervalMatrix b) {
    DoubleComplexMatrix mid = this.middle.appendDown(b.getMiddle());
    DoubleMatrix rad = this.radius.appendDown(b.getRadius());
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

//  /**
//   * @see org.mklab.nfc.matrix.FundamentalMatrix#appendRight(org.mklab.nfc.matrix.Matrix)
//   */
//  @Override
//  public DoubleComplexIntervalMatrix appendRight(Matrix b) {
//    if (b instanceof IntervalMatrix) {
//      return appendRight((DoubleComplexIntervalMatrix)b);
//    }
//
//    return appendRight(new DoubleComplexIntervalMatrix((NumericalMatrix)b));
//  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix appendRight(DoubleComplexIntervalMatrix b) {
    DoubleComplexMatrix mid = this.middle.appendRight(b.getMiddle());
    DoubleMatrix rad = this.radius.appendRight(b.getRadius());
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix divide(DoubleComplexIntervalNumber b) {
    throw new UnsupportedOperationException();
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix divide(int b) {
    throw new UnsupportedOperationException();
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix divide(double b) {
    throw new UnsupportedOperationException();
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix inverse(double tolerance, boolean stopIfSingular) {
    throw new UnsupportedOperationException();
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix inverseElementWise() {
    DoubleComplexIntervalMatrix conj = conjugate();
    DoubleIntervalMatrix den = multiplyElementWise(conj).getRealPart();
    DoubleIntervalMatrix real = conj.getRealPart().divideElementWise(den);
    DoubleIntervalMatrix imag = conj.getImaginaryPart().divideElementWise(den);
    DoubleMatrix rad = real.getRadius().maxElementWise(imag.getRadius());
    DoubleMatrix midReal = real.getInfimum().add(real.getSupremum()).divide(2);
    DoubleMatrix midImag = imag.getInfimum().add(imag.getSupremum()).divide(2);
    DoubleComplexMatrix mid = (rad).createComplex(midReal, midImag);
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public void setElement(int index, int value) {
    this.middle.setElement(index, value);
    this.radius.setElement(index, 0);
    updateInfinumSupremum();
  }

  /**
   * {@inheritDoc}
   */
  public void setElement(int index, double value) {
    this.middle.setElement(index, value);
    this.radius.setElement(index, 0);
    updateInfinumSupremum();
  }

  /**
   * {@inheritDoc}
   */
  public void setElement(final int index, final DoubleComplexNumber value) {
    if (value instanceof IntervalScalar) {
      setElement(index, value);
      return;
    }
    this.middle.setElement(index, value);
    this.radius.setElement(index, 0);
    updateInfinumSupremum();
  }

  /**
   * {@inheritDoc}
   */
  public void setElement(final int index, final DoubleComplexIntervalNumber value) {
    this.middle.setElement(index, value.getMiddle());
    this.radius.setElement(index, value.getRadius());
    updateInfinumSupremum();
  }

  /**
   * {@inheritDoc}
   */
  public void setElement(int row, int column, int value) {
    this.middle.setElement(row, column, value);
    this.radius.setElement(row, column, 0);
    updateInfinumSupremum();
  }

  /**
   * {@inheritDoc}
   */
  public void setElement(int row, int column, double value) {
    this.middle.setElement(row, column, value);
    this.radius.setElement(row, column, 0);
    updateInfinumSupremum();
  }

  /**
   * {@inheritDoc}
   */
  public void setElement(int row, int column, DoubleComplexNumber value) {
    if (value instanceof IntervalScalar) {
      setElement(row, column, value);
    }

    this.middle.setElement(row, column, value);
    this.radius.setElement(row, column, 0);
    updateInfinumSupremum();
  }

  /**
   * {@inheritDoc}
   */
  public void setElement(final int row, final int column, DoubleComplexIntervalNumber value) {
    this.middle.setElement(row, column, value.getMiddle());
    this.radius.setElement(row, column, value.getRadius());
    updateInfinumSupremum();
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalNumber getElement(int i) {
    return new DoubleComplexIntervalNumber(this.middle.getElement(i), this.radius.getDoubleElement(i));
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalNumber getElement(int row, int column) {
    return new DoubleComplexIntervalNumber(this.middle.getElement(row, column), this.radius.getDoubleElement(row, column));
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix conjugate() {
    DoubleComplexMatrix mid = this.middle.conjugate();
    DoubleMatrix rad = this.radius.conjugate();
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix conjugateTranspose() {
    DoubleComplexMatrix mid = this.middle.conjugateTranspose();
    DoubleMatrix rad = this.radius.conjugateTranspose();
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix transpose() {
    DoubleComplexMatrix mid = this.infimum.transpose();
    DoubleMatrix rad = this.radius.transpose();
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public void printElements(Writer output) {
    throw new UnsupportedOperationException();
  }

  /**
   * {@inheritDoc}
   */
  public void printElements(Writer output, int maxColumnSize) {
    throw new UnsupportedOperationException();
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix sumRowWise() {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.sumRowWise();

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = this.middle.sumRowWise();
    DoubleMatrix rad = (mid.subtract(c1)).absElementWise().getRealPart();

    if (isPointMatrix() == false) {
      rad = rad.add(this.radius.sumRowWise());
    }

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);

    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix sumColumnWise() {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.sumColumnWise();

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = this.middle.sumColumnWise();
    DoubleMatrix rad = (mid.subtract(c1)).absElementWise().getRealPart();

    if (isPointMatrix() == false) {
      rad = rad.add(this.radius.sumColumnWise());
    }

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);

    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix cumulativeSumRowWise() {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.cumulativeSumRowWise();

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = this.middle.cumulativeSumRowWise();
    DoubleMatrix rad = (mid.subtract(c1)).absElementWise().getRealPart();

    if (isPointMatrix() == false) {
      rad = rad.add(this.radius.cumulativeSumRowWise());
    }

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);

    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix cumulativeSumColumnWise() {
    RoundModeManager manager = RoundModeManager.getManager();
    RoundMode oldRoundMode = manager.getRoundMode();

    manager.setRoundMode(RoundMode.ROUND_DOWN);
    DoubleComplexMatrix c1 = this.middle.cumulativeSumColumnWise();

    manager.setRoundMode(RoundMode.ROUND_UP);
    DoubleComplexMatrix mid = this.middle.cumulativeSumColumnWise();
    DoubleMatrix rad = (mid.subtract(c1)).absElementWise().getRealPart();

    if (isPointMatrix() == false) {
      rad = rad.add(this.radius.cumulativeSumColumnWise());
    }

    DoubleComplexIntervalMatrix ans = new DoubleComplexIntervalMatrix(mid, rad);

    manager.setRoundMode(oldRoundMode);
    return ans;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix floorElementWise() {
    DoubleComplexMatrix mid = this.middle.floorElementWise();
    DoubleMatrix rad = this.radius.createClone();
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix ceilElementWise() {
    DoubleComplexMatrix mid = this.middle.ceilElementWise();
    DoubleMatrix rad = this.radius.createClone();
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix fixElementWise() {
    DoubleComplexMatrix mid = this.middle.fixElementWise();
    DoubleMatrix rad = this.radius.createClone();
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix roundElementWise() {
    DoubleComplexMatrix mid = this.middle.roundElementWise();
    DoubleMatrix rad = this.radius.createClone();
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix roundToZeroElementWise(double tolerance) {
    DoubleComplexMatrix mid = this.middle.roundToZeroElementWise(tolerance);
    DoubleMatrix rad = this.radius.createClone();
    return new DoubleComplexIntervalMatrix(mid, rad);
  }

  /**
   * @param value
   * @return
   */
  public DoubleComplexIntervalMatrix divide(DoubleComplexNumber value) {
    return divide(new DoubleComplexIntervalNumber(value));
  }

  /**
   * {@inheritDoc}
   */
  public BooleanMatrix compareElementWise(String operator, int value) {
    if (operator.equals(".==")) { //$NON-NLS-1$
      return this.middle.compareElementWise(operator, value).andElementWise(this.radius.compareElementWise(operator, value));
    }

    if (operator.equals(".!=")) { //$NON-NLS-1$
      return this.middle.compareElementWise(operator, value).andElementWise(this.radius.compareElementWise(operator, value));
    }

    throw new UnsupportedOperationException();
  }

  /**
   * {@inheritDoc}
   */
  public BooleanMatrix compareElementWise(String operator, double value) {
    if (operator.equals(".==")) { //$NON-NLS-1$
      return this.middle.compareElementWise(operator, value).andElementWise(this.radius.compareElementWise(operator, value));
    }

    if (operator.equals(".!=")) { //$NON-NLS-1$
      return this.middle.compareElementWise(operator, value).andElementWise(this.radius.compareElementWise(operator, value));
    }

    throw new UnsupportedOperationException();
  }

  /**
   * {@inheritDoc}
   */
  public BooleanMatrix compareElementWise(String operator, DoubleComplexNumber value) {
    if (operator.equals(".==")) { //$NON-NLS-1$
      return this.middle.compareElementWise(operator, value).andElementWise(this.radius.isZero());
    }

    if (operator.equals(".!=")) { //$NON-NLS-1$
      return this.middle.compareElementWise(operator, value).andElementWise(this.radius.isZero()).notElementWise();
    }

    throw new UnsupportedOperationException();
  }


  public DoubleComplexNumber norms() {
    return null;
  }

  public QRDecomposition<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> qrDecompose() {
    return null;
  }

  public QRDecomposition<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> qrDecomposeWithPermutation() {
    return null;
  }

  public SchurDecomposition<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> schurDecompose() {
    return null;
  }

  public DoubleComplexIntervalMatrix choleskyDecompose() {
    return null;
  }

  public DoubleComplexIntervalMatrix choleskyDecompose(double tolerance) {
    return null;
  }

  public DoubleComplexIntervalMatrix choleskyDecompose(DoubleComplexIntervalNumber tolerance) {
    return null;
  }

  public BalancedDecomposition<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> balancedDecompose() {
    return null;
  }

  public DoubleComplexIntervalMatrix kernel() {
    return null;
  }

  public DoubleComplexIntervalMatrix kernel(double tolerance) {
    return null;
  }

  public DoubleComplexIntervalMatrix kernel(DoubleComplexIntervalNumber tolerance) {
    return null;
  }

  public HessenbergDecomposition<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> hessenbergDecompose() {
    return null;
  }

  public LUDecomposition<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> luDecompose(double tolerance, boolean stopIfSingular) {
    return null;
  }

  public LUDecomposition<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> luDecompose(DoubleComplexIntervalNumber tolerance, boolean stopIfSingular) {
    return null;
  }

  public LUDecomposition<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> luDecompose(boolean stopIfSingular) {
    return null;
  }

  public LUDecomposition<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> luDecomposeWithPermutation(boolean stopIfSingular) {
    return null;
  }

  public LUDecomposition<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> luDecomposeWithPermutation(double tolerance, boolean stopIfSingular) {
    return null;
  }

  public LUDecomposition<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> luDecomposeWithPermutation(DoubleComplexIntervalNumber tolerance, boolean stopIfSingular) {
    return null;
  }

  public DoubleComplexIntervalMatrix pseudoInverse(double tolerance) {
    return null;
  }

  public DoubleComplexIntervalMatrix pseudoInverse(DoubleComplexIntervalNumber tolerance) {
    return null;
  }

  public DoubleComplexIntervalMatrix pseudoInverse() {
    return null;
  }

  public int rank(double tolerance) {
    return 0;
  }

  public int rank(DoubleComplexIntervalNumber tolerance) {
    return 0;
  }

  public boolean isFullRank() {
    return false;
  }

  public boolean isFullRank(double tolerance) {
    return false;
  }

  public boolean isFullRank(DoubleComplexIntervalNumber tolerance) {
    return false;
  }

  public boolean isZero(DoubleComplexIntervalNumber tolerance) {
    return false;
  }

  public boolean isUnit(DoubleComplexIntervalNumber tolerance) {
    return false;
  }

  public boolean equals(DoubleComplexIntervalMatrix opponent, DoubleComplexIntervalNumber tolerance) {
    return false;
  }

  public SingularValueDecomposition<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> singularValueDecompose() {
    return null;
  }

  public DoubleComplexIntervalNumber maxSingularValue() {
    return null;
  }

  public DoubleComplexIntervalNumber minSingularValue() {
    return null;
  }

  public DoubleComplexIntervalNumber conditionNumber() {
    return null;
  }

  public DoubleComplexIntervalMatrix log() {
    return null;
  }

  public DoubleComplexIntervalMatrix exp() {
    return null;
  }

  public DoubleComplexIntervalMatrix exp(double tolerance) {
    return null;
  }

  public DoubleComplexIntervalMatrix exp(DoubleComplexIntervalNumber tolerance) {
    return null;
  }

  public DoubleComplexIntervalMatrix sinElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix sinhElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix asinElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix asinhElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix cosElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix coshElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix acosElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix acoshElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix tanElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix tanhElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix atanElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix atan2ElementWise(DoubleComplexIntervalMatrix matrix) {
    return null;
  }

  public DoubleComplexIntervalMatrix atan2ElementWise(DoubleComplexIntervalNumber value) {
    return null;
  }

  public DoubleComplexIntervalMatrix atanhElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix expElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix logElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix log10ElementWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix signumElementWise() {
    return null;
  }

  public DoubleComplexIntervalNumber std() {
    return null;
  }

  public DoubleComplexIntervalMatrix stdRowWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix stdColumnWise() {
    return null;
  }

  public IndexedMatrix<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> sort() {
    return null;
  }

  public IndexedMatrix<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> sortRowWise() {
    return null;
  }

  public IndexedMatrix<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> sortColumnWise() {
    return null;
  }

  public DoubleComplexIntervalNumber max() {
    return null;
  }

  public DoubleComplexIntervalMatrix maxRowWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix maxColumnWise() {
    return null;
  }

  public ElementHolder<DoubleComplexIntervalNumber> maximum() {
    return null;
  }

  public IndexedMatrix<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> maximumRowWise() {
    return null;
  }

  public DoubleComplexIntervalNumber min() {
    return null;
  }

  public IndexedMatrix<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> maximumColumnWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix minRowWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix minColumnWise() {
    return null;
  }

  public ElementHolder<DoubleComplexIntervalNumber> minimum() {
    return null;
  }

  public IndexedMatrix<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> minimumRowWise() {
    return null;
  }

  public IndexedMatrix<DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> minimumColumnWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix maxElementWise(DoubleComplexIntervalMatrix opponent) {
    return null;
  }

  public DoubleComplexIntervalMatrix minElementWise(DoubleComplexIntervalMatrix opponent) {
    return null;
  }

  public DoubleComplexIntervalNumber median() {
    return null;
  }

  public DoubleComplexIntervalMatrix medianColumnWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix medianRowWise() {
    return null;
  }

  public DoubleComplexIntervalNumber norm(NormType normType) {
    return null;
  }

  public DoubleComplexIntervalNumber frobNorm() {
    return null;
  }

  public DoubleComplexIntervalMatrix frobNormRowWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix frobNormColumnWise() {
    return null;
  }

  public DoubleComplexIntervalNumber infNorm() {
    return null;
  }

  public DoubleComplexIntervalMatrix powerElementWise(double scalar) {
    return null;
  }

  public DoubleComplexIntervalMatrix powerElementWise(DoubleComplexIntervalNumber scalar) {
    return null;
  }

  public DoubleComplexIntervalMatrix roundToZeroElementWise(DoubleComplexIntervalNumber tolerance) {
    return null;
  }

  public DoubleComplexIntervalMatrix remainderElementWise(DoubleComplexIntervalMatrix matrix) {
    return null;
  }

  public DoubleComplexIntervalMatrix remainderElementWise(DoubleComplexIntervalNumber value) {
    return null;
  }

  public DoubleComplexIntervalMatrix modulusElementWise(DoubleComplexIntervalMatrix matrix) {
    return null;
  }

  public DoubleComplexIntervalMatrix modulusElementWise(DoubleComplexIntervalNumber value) {
    return null;
  }

  public DoubleComplexIntervalMatrix createUniformRandom() {
    return null;
  }

  public DoubleComplexIntervalMatrix createUniformRandom(int rowSize, int columnSize) {
    return null;
  }

  public DoubleComplexIntervalMatrix createUniformRandom(int rowSize, int columnSize, long seed) {
    return null;
  }

  public DoubleComplexIntervalMatrix createUniformRandom(int rowNumber, int columnNumber, Grid block) {
    return null;
  }

  public DoubleComplexIntervalMatrix createNormalRandom() {
    return null;
  }

  public DoubleComplexIntervalMatrix createNormalRandom(int rowSize, int columnSize) {
    return null;
  }

  public DoubleComplexIntervalMatrix createNormalRandom(int rowSize, int columnSize, long seed) {
    return null;
  }

  public DoubleComplexIntervalMatrix createNormalRandom(int rowNumber, int columnNumber, Grid block) {
    return null;
  }

  public DoubleComplexIntervalMatrix inverse(DoubleComplexIntervalNumber tolerance, boolean stopIfSingular) {
    return null;
  }

  public DoubleComplexIntervalMatrix roundToZeroElementWise() {
    return null;
  }

  public BooleanMatrix compareElementWise(String operator, DoubleComplexIntervalNumber value) {
    return null;
  }

//  public DoubleIntervalMatrix getRealPart() {
//    return null;
//  }

  public DoubleIntervalMatrix argumentElementWise() {
    return null;
  }


  public DoubleComplexIntervalMatrix eigenValue() {
    return null;
  }

  public DoubleComplexIntervalMatrix eigenValue(DoubleComplexIntervalMatrix B) {
    return null;
  }

  public DoubleComplexIntervalMatrix eigenVector() {
    return null;
  }

  public DoubleComplexIntervalMatrix eigenVector(DoubleComplexIntervalMatrix B) {
    return null;
  }

  public EigenSolution<DoubleIntervalNumber, DoubleIntervalMatrix, DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> eigenDecompose() {
    return null;
  }

  public EigenSolution<DoubleIntervalNumber, DoubleIntervalMatrix, DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> eigenDecompose(DoubleComplexIntervalMatrix B) {
    return null;
  }

  public DoubleComplexIntervalMatrix fft() {
    return null;
  }

  public DoubleComplexIntervalMatrix fft(int dataSize) {
    return null;
  }

  public DoubleComplexIntervalMatrix fftRowWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix fftRowWise(int dataSize) {
    return null;
  }

  public DoubleComplexIntervalMatrix fftColumnWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix fftColumnWise(int dataSize) {
    return null;
  }

  public DoubleComplexIntervalMatrix ifft() {
    return null;
  }

  public DoubleComplexIntervalMatrix ifft(int dataSize) {
    return null;
  }

  public DoubleComplexIntervalMatrix ifftRowWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix ifftRowWise(int dataSize) {
    return null;
  }

  public DoubleComplexIntervalMatrix ifftColumnWise() {
    return null;
  }

  public DoubleComplexIntervalMatrix ifftColumnWise(int dataSize) {
    return null;
  }

  public ComplexQZDecomposition<DoubleIntervalNumber, DoubleIntervalMatrix, DoubleComplexIntervalNumber, DoubleComplexIntervalMatrix> qzDecompose(DoubleComplexIntervalMatrix B) {
    return null;
  }

  public DoubleComplexIntervalMatrix sqrt() {
    return null;
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix appendDown(DoubleIntervalMatrix value) {
    return appendDown(value.toComplex());
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix appendRight(DoubleIntervalMatrix value) {
    return appendRight(value.toComplex());
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix multiply(DoubleIntervalNumber value) {
    return multiply(value.toComplex());
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix divide(DoubleIntervalNumber value) {
    return divide(value.toComplex());
  }

  /**
   * {@inheritDoc}
   */
  public DoubleComplexIntervalMatrix leftDivide(DoubleIntervalNumber value) {
    return leftDivide(value.toComplex());
  }


}