@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; }