public void estimate(final Access1D<?> x, final Access1D<?> y) { final int tmpRowDim = (int) Math.min(x.count(), y.count()); final int tmpColDim = this.size(); final PhysicalStore<ComplexNumber> tmpBody = ComplexDenseStore.FACTORY.makeZero(tmpRowDim, tmpColDim); final PhysicalStore<ComplexNumber> tmpRHS = ComplexDenseStore.FACTORY.makeZero(tmpRowDim, 1); for (int i = 0; i < tmpRowDim; i++) { ComplexNumber tmpX = ComplexNumber.ONE; final ComplexNumber tmpXfactor = ComplexNumber.valueOf((Number) x.get(i)); final ComplexNumber tmpY = ComplexNumber.valueOf((Number) y.get(i)); for (int j = 0; j < tmpColDim; j++) { tmpBody.set(i, j, tmpX); tmpX = tmpX.multiply(tmpXfactor); } tmpRHS.set(i, 0, tmpY); } final QR<ComplexNumber> tmpQR = QR.makeComplex(); tmpQR.decompose(tmpBody); this.set(tmpQR.solve(tmpRHS)); }
@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; }
@Override protected Rotation<Double>[] rotations( final PhysicalStore<Double> aStore, final int aLowInd, final int aHighInd, final Rotation<Double>[] retVal) { final double a00 = aStore.doubleValue(aLowInd, aLowInd); final double a01 = aStore.doubleValue(aLowInd, aHighInd); final double a10 = aStore.doubleValue(aHighInd, aLowInd); final double a11 = aStore.doubleValue(aHighInd, aHighInd); final double x = a00 + a11; final double y = a10 - a01; double t; // tan, cot or something temporary // Symmetrise - Givens final double cg; // cos Givens final double sg; // sin Givens if (TypeUtils.isZero(y)) { cg = Math.signum(x); sg = PrimitiveMath.ZERO; } else if (TypeUtils.isZero(x)) { sg = Math.signum(y); cg = PrimitiveMath.ZERO; } else if (Math.abs(y) > Math.abs(x)) { t = x / y; // cot sg = Math.signum(y) / PrimitiveFunction.SQRT1PX2.invoke(t); cg = sg * t; } else { t = y / x; // tan cg = Math.signum(x) / PrimitiveFunction.SQRT1PX2.invoke(t); sg = cg * t; } final double b00 = (cg * a00) + (sg * a10); final double b11 = (cg * a11) - (sg * a01); final double b2 = (cg * (a01 + a10)) + (sg * (a11 - a00)); // b01 + b10 t = (b11 - b00) / b2; t = Math.signum(t) / (PrimitiveFunction.SQRT1PX2.invoke(t) + Math.abs(t)); // tan Jacobi // Annihilate - Jacobi final double cj = PrimitiveMath.ONE / PrimitiveFunction.SQRT1PX2.invoke(t); // cos Jacobi final double sj = cj * t; // sin Jacobi retVal[1] = new Rotation.Primitive(aLowInd, aHighInd, cj, sj); // Jacobi retVal[0] = new Rotation.Primitive( aLowInd, aHighInd, ((cj * cg) + (sj * sg)), ((cj * sg) - (sj * cg))); // Givens - Jacobi return retVal; }
private QuadraticSolver buildIterationSolver(final boolean addSmallDiagonal) { MatrixStore<Double> tmpQ = this.getQ(); final MatrixStore<Double> tmpC = this.getC(); if (addSmallDiagonal) { final PhysicalStore<Double> tmpCopyQ = tmpQ.copy(); final double tmpLargest = tmpCopyQ.aggregateAll(Aggregator.LARGEST); final double tmpRelativelySmall = MACHINE_DOUBLE_ERROR * tmpLargest; final double tmpPracticalLimit = MACHINE_DOUBLE_ERROR + IS_ZERO; final double tmpSmallToAdd = Math.max(tmpRelativelySmall, tmpPracticalLimit); final UnaryFunction<Double> tmpFunc = ADD.second(tmpSmallToAdd); tmpCopyQ.modifyDiagonal(0, 0, tmpFunc); tmpQ = tmpCopyQ; } if (this.hasEqualityConstraints()) { final MatrixStore<Double> tmpAE = this.getAE(); final MatrixStore<Double> tmpBE = this.getBE(); final int tmpZeroSize = tmpAE.getRowDim(); final MatrixStore<Double> tmpUpperLeftAE = tmpQ; final MatrixStore<Double> tmpUpperRightAE = tmpAE.builder().transpose().build(); final MatrixStore<Double> tmpLowerLefAE = tmpAE; final MatrixStore<Double> tmpLowerRightAE = ZeroStore.makePrimitive(tmpZeroSize, tmpZeroSize); final MatrixStore<Double> tmpSubAE = new AboveBelowStore<Double>( new LeftRightStore<Double>(tmpUpperLeftAE, tmpUpperRightAE), new LeftRightStore<Double>(tmpLowerLefAE, tmpLowerRightAE)); final MatrixStore<Double> tmpUpperBE = tmpC; final MatrixStore<Double> tmpLowerBE = tmpBE; final MatrixStore<Double> tmpSubBE = new AboveBelowStore<Double>(tmpUpperBE, tmpLowerBE); return new Builder().equalities(tmpSubAE, tmpSubBE).build(options); } else { return new Builder().equalities(tmpQ, tmpC).build(options); } }
@SuppressWarnings("unchecked") static void copy( final ExpressionsBasedModel sourceModel, final QuadraticSolver.Builder destinationBuilder) { final List<Variable> tmpFreeVariables = sourceModel.getFreeVariables(); final Set<Index> tmpFixedVariables = sourceModel.getFixedVariables(); final int tmpFreeVarDim = tmpFreeVariables.size(); final Array1D<Double> tmpCurrentSolution = Array1D.PRIMITIVE.makeZero(tmpFreeVarDim); for (int i = 0; i < tmpFreeVariables.size(); i++) { final BigDecimal tmpValue = tmpFreeVariables.get(i).getValue(); if (tmpValue != null) { tmpCurrentSolution.set(i, tmpValue.doubleValue()); } } final Optimisation.Result tmpKickStarter = new Optimisation.Result(Optimisation.State.UNEXPLORED, Double.NaN, tmpCurrentSolution); // AE & BE final List<Expression> tmpEqExpr = sourceModel.selectExpressionsLinearEquality(); final int tmpEqExprDim = tmpEqExpr.size(); if (tmpEqExprDim > 0) { final PhysicalStore<Double> tmpAE = FACTORY.makeZero(tmpEqExprDim, tmpFreeVarDim); final PhysicalStore<Double> tmpBE = FACTORY.makeZero(tmpEqExprDim, 1); for (int i = 0; i < tmpEqExprDim; i++) { final Expression tmpExpression = tmpEqExpr.get(i); for (final Expression.Index tmpKey : tmpExpression.getLinearFactorKeys()) { final int tmpIndex = sourceModel.indexOfFreeVariable(tmpKey.index); if (tmpIndex >= 0) { tmpAE.set(i, tmpIndex, tmpExpression.getAdjustedLinearFactor(tmpKey)); } } tmpBE.set(i, 0, tmpExpression.getCompensatedUpperLimit(tmpFixedVariables)); } destinationBuilder.equalities(tmpAE, tmpBE); } // Q & C final Expression tmpObjExpr = sourceModel.getObjectiveExpression(); PhysicalStore<Double> tmpQ = null; if (tmpObjExpr.isAnyQuadraticFactorNonZero()) { tmpQ = FACTORY.makeZero(tmpFreeVarDim, tmpFreeVarDim); final BinaryFunction<Double> tmpBaseFunc = sourceModel.isMaximisation() ? SUBTRACT : ADD; UnaryFunction<Double> tmpModifier; for (final Expression.RowColumn tmpKey : tmpObjExpr.getQuadraticFactorKeys()) { final int tmpRow = sourceModel.indexOfFreeVariable(tmpKey.row); final int tmpColumn = sourceModel.indexOfFreeVariable(tmpKey.column); if ((tmpRow >= 0) && (tmpColumn >= 0)) { tmpModifier = tmpBaseFunc.second(tmpObjExpr.getAdjustedQuadraticFactor(tmpKey)); tmpQ.modifyOne(tmpRow, tmpColumn, tmpModifier); tmpQ.modifyOne(tmpColumn, tmpRow, tmpModifier); } } } PhysicalStore<Double> tmpC = null; if (tmpObjExpr.isAnyLinearFactorNonZero()) { tmpC = FACTORY.makeZero(tmpFreeVarDim, 1); if (sourceModel.isMinimisation()) { for (final Expression.Index tmpKey : tmpObjExpr.getLinearFactorKeys()) { final int tmpIndex = sourceModel.indexOfFreeVariable(tmpKey.index); if (tmpIndex >= 0) { tmpC.set(tmpIndex, 0, -tmpObjExpr.getAdjustedLinearFactor(tmpKey)); } } } else { for (final Expression.Index tmpKey : tmpObjExpr.getLinearFactorKeys()) { final int tmpIndex = sourceModel.indexOfFreeVariable(tmpKey.index); if (tmpIndex >= 0) { tmpC.set(tmpIndex, 0, tmpObjExpr.getAdjustedLinearFactor(tmpKey)); } } } } destinationBuilder.objective(tmpQ, tmpC); // AI & BI final List<Expression> tmpUpExpr = sourceModel.selectExpressionsLinearUpper(); final int tmpUpExprDim = tmpUpExpr.size(); final List<Variable> tmpUpVar = sourceModel.selectVariablesFreeUpper(); final int tmpUpVarDim = tmpUpVar.size(); final List<Expression> tmpLoExpr = sourceModel.selectExpressionsLinearLower(); final int tmpLoExprDim = tmpLoExpr.size(); final List<Variable> tmpLoVar = sourceModel.selectVariablesFreeLower(); final int tmpLoVarDim = tmpLoVar.size(); if ((tmpUpExprDim + tmpUpVarDim + tmpLoExprDim + tmpLoVarDim) > 0) { final ModelEntity<?>[] tmpEntities = new ModelEntity<?>[tmpUpExprDim + tmpUpVarDim + tmpLoExprDim + tmpLoVarDim]; final PhysicalStore<Double> tmpUAI = FACTORY.makeZero(tmpUpExprDim + tmpUpVarDim, tmpFreeVarDim); final PhysicalStore<Double> tmpUBI = FACTORY.makeZero(tmpUpExprDim + tmpUpVarDim, 1); if (tmpUpExprDim > 0) { for (int i = 0; i < tmpUpExprDim; i++) { final Expression tmpExpression = tmpUpExpr.get(i); for (final Expression.Index tmpKey : tmpExpression.getLinearFactorKeys()) { final int tmpIndex = sourceModel.indexOfFreeVariable(tmpKey.index); if (tmpIndex >= 0) { tmpUAI.set(i, tmpIndex, tmpExpression.getAdjustedLinearFactor(tmpKey)); } } tmpUBI.set(i, 0, tmpExpression.getCompensatedUpperLimit(tmpFixedVariables)); tmpEntities[i] = tmpExpression; } } if (tmpUpVarDim > 0) { for (int i = 0; i < tmpUpVarDim; i++) { final Variable tmpVariable = tmpUpVar.get(i); tmpUAI.set( tmpUpExprDim + i, sourceModel.indexOfFreeVariable(tmpVariable), tmpVariable.getAdjustmentFactor()); tmpUBI.set(tmpUpExprDim + i, 0, tmpVariable.getAdjustedUpperLimit()); tmpEntities[tmpUpExprDim + i] = tmpVariable; } } final PhysicalStore<Double> tmpLAI = FACTORY.makeZero(tmpLoExprDim + tmpLoVarDim, tmpFreeVarDim); final PhysicalStore<Double> tmpLBI = FACTORY.makeZero(tmpLoExprDim + tmpLoVarDim, 1); if (tmpLoExprDim > 0) { for (int i = 0; i < tmpLoExprDim; i++) { final Expression tmpExpression = tmpLoExpr.get(i); for (final Expression.Index tmpKey : tmpExpression.getLinearFactorKeys()) { final int tmpIndex = sourceModel.indexOfFreeVariable(tmpKey.index); if (tmpIndex >= 0) { tmpLAI.set(i, tmpIndex, -tmpExpression.getAdjustedLinearFactor(tmpKey)); } } tmpLBI.set(i, 0, -tmpExpression.getCompensatedLowerLimit(tmpFixedVariables)); tmpEntities[tmpUpExprDim + tmpUpVarDim + i] = tmpExpression; } } if (tmpLoVarDim > 0) { for (int i = 0; i < tmpLoVarDim; i++) { final Variable tmpVariable = tmpLoVar.get(i); tmpLAI.set( tmpLoExprDim + i, sourceModel.indexOfFreeVariable(tmpVariable), -tmpVariable.getAdjustmentFactor()); tmpLBI.set(tmpLoExprDim + i, 0, -tmpVariable.getAdjustedLowerLimit()); tmpEntities[tmpUpExprDim + tmpUpVarDim + tmpLoExprDim + i] = tmpVariable; } } final MatrixStore<Double> tmpAI = tmpLAI.builder().above(tmpUAI).build(); final MatrixStore<Double> tmpBI = tmpLBI.builder().above(tmpUBI).build(); destinationBuilder.inequalities(tmpAI, tmpBI, tmpEntities); final IndexSelector tmpSelector = new IndexSelector(tmpEntities.length); for (int i = 0; i < tmpEntities.length; i++) { if (tmpEntities[i].isActiveInequalityConstraint()) { tmpSelector.include(i); } } tmpKickStarter.activeSet(tmpSelector.getIncluded()); } destinationBuilder.setKickStarter(tmpKickStarter); }
@Override protected Rotation<BigDecimal>[] rotations( final PhysicalStore<BigDecimal> aStore, final int aLowInd, final int aHighInd, final Rotation<BigDecimal>[] retVal) { final BigDecimal a00 = aStore.get(aLowInd, aLowInd); final BigDecimal a01 = aStore.get(aLowInd, aHighInd); final BigDecimal a10 = aStore.get(aHighInd, aLowInd); final BigDecimal a11 = aStore.get(aHighInd, aHighInd); final BigDecimal x = a00.add(a11); final BigDecimal y = a10.subtract(a01); BigDecimal t; // tan, cot or something temporary // Symmetrise - Givens final BigDecimal cg; // cos Givens final BigDecimal sg; // sin Givens if (y.signum() == 0) { cg = BigFunction.SIGNUM.invoke(x); sg = BigMath.ZERO; } else if (x.signum() == 0) { sg = BigFunction.SIGNUM.invoke(y); cg = BigMath.ZERO; } else if (y.abs().compareTo(x.abs()) == 1) { t = BigFunction.DIVIDE.invoke(x, y); // cot sg = BigFunction.DIVIDE.invoke(BigFunction.SIGNUM.invoke(y), BigFunction.SQRT1PX2.invoke(t)); cg = sg.multiply(t); } else { t = BigFunction.DIVIDE.invoke(y, x); // tan cg = BigFunction.DIVIDE.invoke(BigFunction.SIGNUM.invoke(x), BigFunction.SQRT1PX2.invoke(t)); sg = cg.multiply(t); } final BigDecimal b00 = cg.multiply(a00).add(sg.multiply(a10)); final BigDecimal b11 = cg.multiply(a11).subtract(sg.multiply(a01)); final BigDecimal b2 = cg.multiply(a01.add(a10)).add(sg.multiply(a11.subtract(a00))); // b01 + b10 t = BigFunction.DIVIDE.invoke(b11.subtract(b00), b2); t = BigFunction.DIVIDE.invoke( BigFunction.SIGNUM.invoke(t), BigFunction.SQRT1PX2.invoke(t).add(t.abs())); // Annihilate - Jacobi final BigDecimal cj = BigFunction.DIVIDE.invoke(BigMath.ONE, BigFunction.SQRT1PX2.invoke(t)); // Cos Jacobi final BigDecimal sj = cj.multiply(t); // Sin Jacobi retVal[1] = new Rotation.Big(aLowInd, aHighInd, cj, sj); // Jacobi retVal[0] = new Rotation.Big( aLowInd, aHighInd, cj.multiply(cg).add(sj.multiply(sg)), cj.multiply(sg).subtract(sj.multiply(cg))); // Givens - Jacobi return retVal; }