@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 @SuppressWarnings("unchecked") protected boolean doCompute( final ElementsSupplier<N> aStore, final boolean singularValuesOnly, final boolean fullSize) { final int tmpMinDim = (int) Math.min(aStore.countRows(), aStore.countColumns()); this.computeBidiagonal(aStore, fullSize); final DecompositionStore<N> tmpSimilar = this.copy(this.getBidiagonalAccessD()); this.setD(tmpSimilar); this.setSingularValues(Array1D.PRIMITIVE.makeZero(tmpMinDim)); Rotation<N>[] tmpRotations = new Rotation[2]; // [Givens - Jacobi, Jacobi] // int iter = 0; // BasicLogger.logDebug(this.getClass().toString()); // BasicLogger.logDebug("Init D", myD); final N tmpZero = this.scalar().zero().getNumber(); boolean tmpNotAllZeros = true; for (int l = 0; tmpNotAllZeros && (l < tmpMinDim); l++) { tmpNotAllZeros = false; int i; // for (int i0 = tmpMinDim - 1; i0 > 0; i0--) { // Performs much slower for (int i0 = 1; i0 < tmpMinDim; i0++) { for (int j = 0; j < (tmpMinDim - i0); j++) { i = i0 + j; if (!tmpSimilar.isZero(i, j) || !tmpSimilar.isZero(j, i)) { tmpNotAllZeros = true; tmpRotations = this.rotations(tmpSimilar, j, i, tmpRotations); tmpSimilar.transformLeft(tmpRotations[0]); tmpSimilar.transformRight(tmpRotations[1]); myQ1Rotations.add(tmpRotations[0].invert()); myQ2Rotations.add(tmpRotations[1]); // BasicLogger.logDebug("Iter-" + ++iter + " D", myD); } tmpSimilar.set(i, j, tmpZero); tmpSimilar.set(j, i, tmpZero); } } } double tmpSingularValue; for (int ij = 0; ij < tmpMinDim; ij++) { if (tmpSimilar.isZero(ij, ij)) { tmpSingularValue = PrimitiveMath.ZERO; } else if (tmpSimilar.isAbsolute(ij, ij)) { tmpSingularValue = tmpSimilar.doubleValue(ij, ij); } else { final Scalar<N> tmpDiagSclr = tmpSimilar.toScalar(ij, ij); final N tmpSignum = tmpDiagSclr.signum().getNumber(); tmpSingularValue = tmpDiagSclr.divide(tmpSignum).norm(); tmpSimilar.set(ij, ij, tmpSingularValue); myQ2Rotations.add(this.makeRotation(ij, ij, tmpSignum, tmpSignum)); } this.getSingularValues().set(ij, tmpSingularValue); } this.getSingularValues().sortDescending(); myFutureQ1 = DaemonPoolExecutor.invoke( new Callable<PhysicalStore<N>>() { public PhysicalStore<N> call() throws Exception { final PhysicalStore<N> retVal = SVDold30.this.getBidiagonalQ1(); final List<Rotation<N>> tmpRotations = myQ1Rotations; final int tmpLimit = tmpRotations.size(); for (int r = 0; r < tmpLimit; r++) { retVal.transformRight(tmpRotations.get(r)); } return retVal; } }); myFutureQ2 = DaemonPoolExecutor.invoke( new Callable<PhysicalStore<N>>() { public PhysicalStore<N> call() throws Exception { final PhysicalStore<N> retVal = SVDold30.this.getBidiagonalQ2(); final List<Rotation<N>> tmpRotations = myQ2Rotations; final int tmpLimit = tmpRotations.size(); for (int r = 0; r < tmpLimit; r++) { retVal.transformRight(tmpRotations.get(r)); } return retVal; } }); return this.computed(true); }