Пример #1
0
    @Override
    protected Rotation<ComplexNumber>[] rotations(
        final PhysicalStore<ComplexNumber> aStore,
        final int aLowInd,
        final int aHighInd,
        final Rotation<ComplexNumber>[] retVal) {

      final ComplexNumber a00 = aStore.get(aLowInd, aLowInd);
      final ComplexNumber a01 = aStore.get(aLowInd, aHighInd);
      final ComplexNumber a10 = aStore.get(aHighInd, aLowInd);
      final ComplexNumber a11 = aStore.get(aHighInd, aHighInd);

      final ComplexNumber x = a00.add(a11);
      final ComplexNumber y = a10.subtract(a01);

      ComplexNumber t; // tan, cot or something temporary

      // Symmetrise - Givens
      final ComplexNumber cg; // cos Givens
      final ComplexNumber sg; // sin Givens

      if (ComplexNumber.isSmall(PrimitiveMath.ONE, y)) {
        cg = x.signum();
        sg = ComplexNumber.ZERO;
      } else if (ComplexNumber.isSmall(PrimitiveMath.ONE, x)) {
        sg = y.signum();
        cg = ComplexNumber.ZERO;
      } else if (y.compareTo(x) == 1) {
        t = x.divide(y); // cot
        sg = y.signum().divide(ComplexFunction.SQRT1PX2.invoke(t));
        cg = sg.multiply(t);
      } else {
        t = y.divide(x); // tan
        cg = x.signum().divide(ComplexFunction.SQRT1PX2.invoke(t));
        sg = cg.multiply(t);
      }

      final ComplexNumber b00 = cg.multiply(a00).add(sg.multiply(a10));
      final ComplexNumber b11 = cg.multiply(a11).subtract(sg.multiply(a01));
      final ComplexNumber b2 =
          cg.multiply(a01.add(a10)).add(sg.multiply(a11.subtract(a00))); // b01 + b10

      t = b11.subtract(b00).divide(b2);
      t = t.signum().divide(ComplexFunction.SQRT1PX2.invoke(t).add(t.norm()));

      // Annihilate - Jacobi
      final ComplexNumber cj = ComplexFunction.SQRT1PX2.invoke(t).invert(); // Cos Jacobi
      final ComplexNumber sj = cj.multiply(t); // Sin Jacobi

      retVal[1] = new Rotation.Complex(aLowInd, aHighInd, cj, sj); // Jacobi
      retVal[0] =
          new Rotation.Complex(
              aLowInd,
              aHighInd,
              cj.multiply(cg).add(sj.multiply(sg)),
              cj.multiply(sg).subtract(sj.multiply(cg))); // Givens - Jacobi

      return retVal;
    }