26template<
typename ValueType>
31template<
typename ValueType>
36template<
typename ValueType>
41template<
typename ValueType>
48template<
typename ValueType>
50 localA = std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(A));
51 this->A = localA.get();
55template<
typename ValueType>
58 viOperator = std::make_shared<helper::ValueIterationOperator<ValueType, true>>();
59 viOperator->setMatrixBackwards(*this->A);
63template<
typename ValueType>
64bool NativeLinearEquationSolver<ValueType>::solveEquationsSOR(Environment
const& env, std::vector<ValueType>& x, std::vector<ValueType>
const& b,
65 ValueType
const& omega)
const {
66 STORM_LOG_INFO(
"Solving linear equation system (" << x.size() <<
" rows) with NativeLinearEquationSolver (Gauss-Seidel, SOR omega = " << omega <<
")");
68 if (!this->cachedRowVector) {
69 this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount());
72 ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision());
73 uint64_t maxIter = env.solver().native().getMaximalNumberOfIterations();
74 bool relative = env.solver().native().getRelativeTerminationCriterion();
77 uint_fast64_t iterations = 0;
80 this->startMeasureProgress();
82 A->performSuccessiveOverRelaxationStep(omega, x, b);
85 if (storm::utility::vector::equalModuloPrecision<ValueType>(*this->cachedRowVector, x, precision, relative)) {
90 *this->cachedRowVector = x;
94 this->showProgressIterative(iterations);
102 if (!this->isCachingEnabled()) {
106 this->reportStatus(status, iterations);
111template<
typename ValueType>
114 this->LUMatrix = std::move(decomposition.first);
115 this->DVector = std::move(decomposition.second);
119template<
typename ValueType>
120bool NativeLinearEquationSolver<ValueType>::solveEquationsJacobi(Environment
const& env, std::vector<ValueType>& x, std::vector<ValueType>
const& b)
const {
121 STORM_LOG_INFO(
"Solving linear equation system (" << x.size() <<
" rows) with NativeLinearEquationSolver (Jacobi)");
123 if (!this->cachedRowVector) {
124 this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount());
128 if (!jacobiDecomposition) {
129 jacobiDecomposition = std::make_unique<JacobiDecomposition>(env, *A);
132 ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision());
133 uint64_t maxIter = env.solver().native().getMaximalNumberOfIterations();
134 bool relative = env.solver().native().getRelativeTerminationCriterion();
136 std::vector<ValueType>* currentX = &x;
137 std::vector<ValueType>* nextX = this->cachedRowVector.get();
140 uint_fast64_t iterations = 0;
143 this->startMeasureProgress();
146 jacobiDecomposition->multiplier->multiply(env, *currentX,
nullptr, *nextX);
151 if (storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *nextX, precision, relative)) {
155 std::swap(nextX, currentX);
158 this->showProgressIterative(iterations);
168 if (currentX == this->cachedRowVector.get()) {
169 std::swap(x, *currentX);
172 if (!this->isCachingEnabled()) {
176 this->reportStatus(status, iterations);
181template<
typename ValueType>
183 std::vector<ValueType>
const& originalB)
185 computeWalkerChaeMatrix(originalMatrix);
186 computeNewB(originalB);
187 precomputeAuxiliaryData();
191template<
typename ValueType>
195 for (
auto const& e : originalMatrix) {
196 if (e.getValue() < zero) {
197 columnsWithNegativeEntries.set(e.getColumn());
200 std::vector<uint64_t> columnsWithNegativeEntriesBefore = columnsWithNegativeEntries.getNumberOfSetBitsBeforeIndices();
206 for (; row < originalMatrix.
getRowCount(); ++row) {
207 for (
auto const& entry : originalMatrix.getRow(row)) {
208 if (entry.getValue() < zero) {
209 builder.
addNextValue(row, originalMatrix.
getRowCount() + columnsWithNegativeEntriesBefore[entry.getColumn()], -entry.getValue());
211 builder.
addNextValue(row, entry.getColumn(), entry.getValue());
216 for (
auto column : columnsWithNegativeEntries) {
222 matrix = builder.
build();
225template<
typename ValueType>
226void NativeLinearEquationSolver<ValueType>::WalkerChaeData::computeNewB(std::vector<ValueType>
const& originalB) {
227 b = std::vector<ValueType>(originalB);
228 b.resize(matrix.getRowCount());
231template<
typename ValueType>
232void NativeLinearEquationSolver<ValueType>::WalkerChaeData::precomputeAuxiliaryData() {
233 columnSums = std::vector<ValueType>(matrix.getColumnCount());
234 for (
auto const& e : matrix) {
235 columnSums[e.getColumn()] += e.getValue();
238 newX.resize(matrix.getRowCount());
241template<
typename ValueType>
242bool NativeLinearEquationSolver<ValueType>::solveEquationsWalkerChae(Environment
const& env, std::vector<ValueType>& x, std::vector<ValueType>
const& b)
const {
243 STORM_LOG_INFO(
"Solving linear equation system (" << x.size() <<
" rows) with NativeLinearEquationSolver (WalkerChae)");
246 if (!walkerChaeData) {
247 walkerChaeData = std::make_unique<WalkerChaeData>(env, *this->A, b);
251 x.resize(walkerChaeData->matrix.getRowCount());
257 uint64_t maxIter = env.solver().native().getMaximalNumberOfIterations();
260 std::vector<ValueType>* currentX = &x;
261 std::vector<ValueType>* nextX = &walkerChaeData->newX;
263 std::vector<ValueType> tmp = walkerChaeData->matrix.getRowSumVector();
265 [
this](ValueType
const& first, ValueType
const& second) -> ValueType { return walkerChaeData->t * first + second; });
271 std::vector<ValueType> currentAx(x.size());
272 walkerChaeData->multiplier->multiply(env, *currentX,
nullptr, currentAx);
276 uint64_t iterations = 0;
277 this->startMeasureProgress();
280 walkerChaeData->matrix.performWalkerChaeStep(*currentX, walkerChaeData->columnSums, walkerChaeData->b, currentAx, *nextX);
283 walkerChaeData->multiplier->multiply(env, *nextX,
nullptr, currentAx);
291 std::swap(currentX, nextX);
294 this->showProgressIterative(iterations);
306 if (currentX == &walkerChaeData->newX) {
307 std::swap(x, *currentX);
316 if (!this->isCachingEnabled()) {
320 this->reportStatus(status, iterations);
325template<
typename ValueType>
326typename NativeLinearEquationSolver<ValueType>::PowerIterationResult NativeLinearEquationSolver<ValueType>::performPowerIteration(
327 Environment
const& env, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType>
const& b, ValueType
const& precision,
328 bool relative,
SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maxIterations,
332 uint64_t iterations = currentIterations;
335 if (useGaussSeidelMultiplication) {
337 this->multiplier->multiplyGaussSeidel(env, *newX, &b);
339 this->multiplier->multiply(env, *currentX, &b, *newX);
343 if (storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *newX, precision, relative)) {
348 std::swap(currentX, newX);
351 status = this->updateStatus(status, *currentX, guarantee, iterations, maxIterations);
354 this->showProgressIterative(iterations);
357 return PowerIterationResult(iterations - currentIterations, status);
360template<
typename ValueType>
361bool NativeLinearEquationSolver<ValueType>::solveEquationsPower(Environment
const& env, std::vector<ValueType>& x, std::vector<ValueType>
const& b)
const {
362 STORM_LOG_INFO(
"Solving linear equation system (" << x.size() <<
" rows) with NativeLinearEquationSolver (Power)");
367 if (this->hasCustomTerminationCondition()) {
369 this->createLowerBoundsVector(x);
372 this->createUpperBoundsVector(x);
378 uint64_t numIterations{0};
380 this->showProgressIterative(numIterations);
381 return this->updateStatus(current, x, guarantee, numIterations, env.solver().native().getMaximalNumberOfIterations());
383 this->startMeasureProgress();
384 auto status = viHelper.VI(x, b, numIterations, env.solver().native().getRelativeTerminationCriterion(),
385 storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision()), {}, viCallback,
386 env.solver().native().getPowerMethodMultiplicationStyle());
388 this->reportStatus(status, numIterations);
390 if (!this->isCachingEnabled()) {
397template<
typename ValueType>
402template<
typename ValueType>
404 ValueType result = storm::utility::zero<ValueType>();
405 auto oldValueIt = oldValues.begin();
406 for (
auto value : relevantValues) {
407 result = storm::utility::max<ValueType>(result, storm::utility::abs<ValueType>(allValues[value] - *oldValueIt));
412template<
typename ValueType>
413ValueType
computeMaxAbsDiff(std::vector<ValueType>
const& allOldValues, std::vector<ValueType>
const& allNewValues,
415 ValueType result = storm::utility::zero<ValueType>();
416 for (
auto value : relevantValues) {
417 result = storm::utility::max<ValueType>(result, storm::utility::abs<ValueType>(allNewValues[value] - allOldValues[value]));
422template<
typename ValueType>
423bool NativeLinearEquationSolver<ValueType>::solveEquationsIntervalIteration(
Environment const& env, std::vector<ValueType>& x,
424 std::vector<ValueType>
const& b)
const {
425 STORM_LOG_THROW(this->hasLowerBound(), storm::exceptions::UnmetRequirementException,
"Solver requires lower bound, but none was given.");
426 STORM_LOG_THROW(this->hasUpperBound(), storm::exceptions::UnmetRequirementException,
"Solver requires upper bound, but none was given.");
427 STORM_LOG_INFO(
"Solving linear equation system (" << x.size() <<
" rows) with NativeLinearEquationSolver (IntervalIteration)");
429 helper::IntervalIterationHelper<ValueType, true> iiHelper(viOperator);
431 auto lowerBoundsCallback = [&](std::vector<ValueType>& vector) { this->createLowerBoundsVector(vector); };
432 auto upperBoundsCallback = [&](std::vector<ValueType>& vector) { this->createUpperBoundsVector(vector); };
434 uint64_t numIterations{0};
435 auto iiCallback = [&](helper::IIData<ValueType>
const& data) {
436 this->showProgressIterative(numIterations);
437 bool terminateEarly = this->hasCustomTerminationCondition() && this->getTerminationCondition().terminateNow(data.x,
SolverGuarantee::LessOrEqual) &&
441 std::optional<storm::storage::BitVector> optionalRelevantValues;
442 if (this->hasRelevantValues()) {
443 optionalRelevantValues = this->getRelevantValues();
445 this->startMeasureProgress();
447 iiCallback, optionalRelevantValues);
448 this->reportStatus(status, numIterations);
450 if (!this->isCachingEnabled()) {
457template<
typename ValueType>
458bool NativeLinearEquationSolver<ValueType>::solveEquationsSoundValueIteration(Environment
const& env, std::vector<ValueType>& x,
459 std::vector<ValueType>
const& b)
const {
461 assert(x.size() == this->A->getRowGroupCount());
463 std::optional<ValueType> lowerBound, upperBound;
464 if (this->hasLowerBound()) {
465 lowerBound = this->getLowerBound(
true);
467 if (this->hasUpperBound()) {
468 upperBound = this->getUpperBound(
true);
473 auto precision = storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision());
474 uint64_t numIterations{0};
475 auto sviCallback = [&](
typename helper::SoundValueIterationHelper<ValueType, true>::SVIData
const& current) {
476 this->showProgressIterative(numIterations);
477 return this->updateStatus(current.status,
478 this->hasCustomTerminationCondition() && current.checkCustomTerminationCondition(this->getTerminationCondition()),
479 numIterations, env.solver().native().getMaximalNumberOfIterations());
481 std::optional<storm::storage::BitVector> optionalRelevantValues;
482 if (this->hasRelevantValues()) {
483 optionalRelevantValues = this->getRelevantValues();
485 this->startMeasureProgress();
486 helper::SoundValueIterationHelper<ValueType, true> sviHelper(viOperator);
487 auto status = sviHelper.SVI(x, b, numIterations, env.solver().native().getRelativeTerminationCriterion(), precision, {}, lowerBound, upperBound,
488 sviCallback, optionalRelevantValues);
490 this->reportStatus(status, numIterations);
492 if (!this->isCachingEnabled()) {
499template<
typename ValueType>
500bool NativeLinearEquationSolver<ValueType>::solveEquationsOptimisticValueIteration(Environment
const& env, std::vector<ValueType>& x,
501 std::vector<ValueType>
const& b)
const {
504 x.assign(x.size(), storm::utility::zero<ValueType>());
510 helper::OptimisticValueIterationHelper<ValueType, true> oviHelper(viOperator);
511 auto prec = storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision());
512 std::optional<ValueType> lowerBound, upperBound;
513 if (this->hasLowerBound()) {
514 lowerBound = this->getLowerBound(
true);
516 if (this->hasUpperBound()) {
517 upperBound = this->getUpperBound(
true);
519 uint64_t numIterations{0};
520 auto oviCallback = [&](
SolverStatus const& current, std::vector<ValueType>
const& v) {
521 this->showProgressIterative(numIterations);
522 return this->updateStatus(current, v,
SolverGuarantee::LessOrEqual, numIterations, env.solver().native().getMaximalNumberOfIterations());
524 this->createLowerBoundsVector(x);
525 std::optional<ValueType> guessingFactor;
526 if (env.solver().ovi().getUpperBoundGuessingFactor()) {
527 guessingFactor = storm::utility::convertNumber<ValueType>(*env.solver().ovi().getUpperBoundGuessingFactor());
529 this->startMeasureProgress();
530 auto status = oviHelper.OVI(x, b, env.solver().native().getRelativeTerminationCriterion(), prec, {}, guessingFactor, lowerBound, upperBound, oviCallback);
531 this->reportStatus(status, numIterations);
533 if (!this->isCachingEnabled()) {
540template<
typename ValueType>
541bool NativeLinearEquationSolver<ValueType>::solveEquationsGuessingValueIteration(
const Environment& env, std::vector<ValueType>& x,
542 const std::vector<ValueType>& b)
const {
543 if (!this->cachedRowVector) {
544 this->cachedRowVector = std::make_unique<std::vector<ValueType>>(this->A->
getRowCount());
548 std::vector<ValueType>* lowerX = &x;
549 this->createLowerBoundsVector(*lowerX);
550 this->createUpperBoundsVector(this->cachedRowVector, this->getMatrixRowCount());
551 std::vector<ValueType>* upperX = this->cachedRowVector.get();
555 uint64_t numIterations{0};
556 auto gviCallback = [&](helper::GVIData<ValueType>
const& data) {
557 this->showProgressIterative(numIterations);
558 bool terminateEarly = this->hasCustomTerminationCondition() && this->getTerminationCondition().terminateNow(data.x,
SolverGuarantee::LessOrEqual) &&
560 return this->updateStatus(data.status, terminateEarly, numIterations, env.solver().native().getMaximalNumberOfIterations());
563 this->startMeasureProgress();
564 auto status = helper.solveEquations(*lowerX, *upperX, b, numIterations, storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision()),
567 auto two = storm::utility::convertNumber<ValueType>(2.0);
568 storm::utility::vector::applyPointwise<ValueType, ValueType, ValueType>(
569 *lowerX, *upperX, x, [&two](ValueType
const& a, ValueType
const& b) -> ValueType {
return (a + b) / two; });
570 this->reportStatus(status, numIterations);
572 if (!this->isCachingEnabled()) {
578template<
typename ValueType>
579bool NativeLinearEquationSolver<ValueType>::solveEquationsRationalSearch(Environment
const& env, std::vector<ValueType>& x,
580 std::vector<ValueType>
const& b)
const {
583 std::shared_ptr<helper::ValueIterationOperator<storm::RationalNumber, true>> exactOp;
584 std::shared_ptr<helper::ValueIterationOperator<double, true>> impreciseOp;
586 if constexpr (std::is_same_v<ValueType, storm::RationalNumber>) {
587 exactOp = viOperator;
588 impreciseOp = std::make_shared<helper::ValueIterationOperator<double, true>>();
589 impreciseOp->setMatrixBackwards(this->A->template toValueType<double>());
591 impreciseOp = viOperator;
592 exactOp = std::make_shared<helper::ValueIterationOperator<storm::RationalNumber, true>>();
593 exactOp->setMatrixBackwards(this->A->template toValueType<storm::RationalNumber>());
597 uint64_t numIterations{0};
599 this->showProgressIterative(numIterations);
600 return this->updateStatus(current, x,
SolverGuarantee::None, numIterations, env.solver().native().getMaximalNumberOfIterations());
602 this->startMeasureProgress();
603 auto status = rsHelper.RS(x, b, numIterations, storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision()), {}, rsCallback);
605 this->reportStatus(status, numIterations);
607 if (!this->isCachingEnabled()) {
614template<
typename ValueType>
615NativeLinearEquationSolverMethod NativeLinearEquationSolver<ValueType>::getMethod(Environment
const& env,
bool isExactMode)
const {
617 auto method = env.solver().native().getMethod();
619 if (isExactMode && method != NativeLinearEquationSolverMethod::RationalSearch) {
620 if (env.solver().native().isMethodSetFromDefault()) {
621 method = NativeLinearEquationSolverMethod::RationalSearch;
624 "' as the solution technique to guarantee exact results. If you want to override this, please explicitly specify a different method.");
626 STORM_LOG_WARN(
"The selected solution method does not guarantee exact results.");
628 }
else if (env.solver().isForceSoundness() && method != NativeLinearEquationSolverMethod::SoundValueIteration &&
629 method != NativeLinearEquationSolverMethod::OptimisticValueIteration && method != NativeLinearEquationSolverMethod::IntervalIteration &&
630 method != NativeLinearEquationSolverMethod::RationalSearch) {
631 if (env.solver().native().isMethodSetFromDefault()) {
632 method = NativeLinearEquationSolverMethod::OptimisticValueIteration;
635 "' as the solution technique to guarantee sound results. If you want to override this, please explicitly specify a different method.");
637 STORM_LOG_WARN(
"The selected solution method does not guarantee sound results.");
643template<
typename ValueType>
646 case NativeLinearEquationSolverMethod::SOR:
647 return this->solveEquationsSOR(env, x, b, storm::utility::convertNumber<ValueType>(env.
solver().
native().
getSorOmega()));
648 case NativeLinearEquationSolverMethod::GaussSeidel:
649 return this->solveEquationsSOR(env, x, b, storm::utility::one<ValueType>());
650 case NativeLinearEquationSolverMethod::Jacobi:
651 return this->solveEquationsJacobi(env, x, b);
652 case NativeLinearEquationSolverMethod::WalkerChae:
653 return this->solveEquationsWalkerChae(env, x, b);
654 case NativeLinearEquationSolverMethod::Power:
655 return this->solveEquationsPower(env, x, b);
656 case NativeLinearEquationSolverMethod::SoundValueIteration:
657 return this->solveEquationsSoundValueIteration(env, x, b);
658 case NativeLinearEquationSolverMethod::OptimisticValueIteration:
659 return this->solveEquationsOptimisticValueIteration(env, x, b);
660 case NativeLinearEquationSolverMethod::GuessingValueIteration:
661 return this->solveEquationsGuessingValueIteration(env, x, b);
662 case NativeLinearEquationSolverMethod::IntervalIteration:
663 return this->solveEquationsIntervalIteration(env, x, b);
664 case NativeLinearEquationSolverMethod::RationalSearch:
665 return this->solveEquationsRationalSearch(env, x, b);
667 STORM_LOG_THROW(
false, storm::exceptions::InvalidEnvironmentException,
"Unknown solving technique.");
671template<
typename ValueType>
674 if (method == NativeLinearEquationSolverMethod::Power || method == NativeLinearEquationSolverMethod::SoundValueIteration ||
675 method == NativeLinearEquationSolverMethod::OptimisticValueIteration || method == NativeLinearEquationSolverMethod::RationalSearch ||
676 method == NativeLinearEquationSolverMethod::IntervalIteration || method == NativeLinearEquationSolverMethod::GuessingValueIteration) {
683template<
typename ValueType>
687 if (method == NativeLinearEquationSolverMethod::IntervalIteration || method == NativeLinearEquationSolverMethod::GuessingValueIteration) {
689 }
else if (method == NativeLinearEquationSolverMethod::RationalSearch || method == NativeLinearEquationSolverMethod::OptimisticValueIteration) {
691 }
else if (method == NativeLinearEquationSolverMethod::SoundValueIteration) {
697template<
typename ValueType>
699 jacobiDecomposition.reset();
700 walkerChaeData.reset();
706template<
typename ValueType>
711template<
typename ValueType>
712uint64_t NativeLinearEquationSolver<ValueType>::getMatrixColumnCount()
const {
716template<
typename ValueType>
718 return std::make_unique<storm::solver::NativeLinearEquationSolver<ValueType>>();
721template<
typename ValueType>
723 return std::make_unique<NativeLinearEquationSolverFactory<ValueType>>(*this);
730#ifdef STORM_HAVE_CARL
SolverEnvironment & solver()
storm::RationalNumber const & getPrecision() const
uint64_t const & getMaximalNumberOfIterations() const
bool const & getRelativeTerminationCriterion() const
storm::RationalNumber const & getSorOmega() const
bool isForceExact() const
NativeSolverEnvironment & native()
virtual void clearCache() const
LinearEquationSolverRequirements & requireLowerBounds(bool critical=true)
LinearEquationSolverRequirements & requireBounds(bool critical=true)
std::unique_ptr< Multiplier< ValueType > > create(Environment const &env, storm::storage::SparseMatrix< ValueType > const &matrix)
virtual std::unique_ptr< storm::solver::LinearEquationSolver< ValueType > > create(Environment const &env) const override
Creates an equation solver with the current settings, but without a matrix.
virtual std::unique_ptr< LinearEquationSolverFactory< ValueType > > clone() const override
Creates a copy of this factory.
A class that uses storm's native matrix operations to implement the LinearEquationSolver interface.
virtual LinearEquationSolverProblemFormat getEquationProblemFormat(storm::Environment const &env) const override
Retrieves the format in which this solver expects to solve equations.
friend class NativeLinearEquationSolver
virtual bool internalSolveEquations(storm::Environment const &env, std::vector< ValueType > &x, std::vector< ValueType > const &b) const override
virtual void setMatrix(storm::storage::SparseMatrix< ValueType > const &A) override
virtual void clearCache() const override
virtual LinearEquationSolverRequirements getRequirements(Environment const &env) const override
Retrieves the requirements of the solver under the current settings.
Implements guessing value iteration.
Implements rational search.
A bit vector that is internally represented as a vector of 64-bit values.
A class that can be used to build a sparse matrix by adding value by value.
void addNextValue(index_type row, index_type column, value_type const &value)
Sets the matrix entry at the given row and column to the given value.
SparseMatrix< value_type > build(index_type overriddenRowCount=0, index_type overriddenColumnCount=0, index_type overriddenRowGroupCount=0)
A class that holds a possibly non-square matrix in the compressed row storage format.
index_type getColumnCount() const
Returns the number of columns of the matrix.
std::pair< storm::storage::SparseMatrix< value_type >, std::vector< value_type > > getJacobiDecomposition() const
Calculates the Jacobi decomposition of this sparse matrix.
index_type getRowCount() const
Returns the number of rows of the matrix.
#define STORM_LOG_INFO(message)
#define STORM_LOG_WARN(message)
#define STORM_LOG_THROW(cond, exception, message)
SFTBDDChecker::ValueType ValueType
LinearEquationSolverProblemFormat
void preserveOldRelevantValues(std::vector< ValueType > const &allValues, storm::storage::BitVector const &relevantValues, std::vector< ValueType > &oldValues)
std::string toString(GurobiSolverMethod const &method)
Yields a string representation of the GurobiSolverMethod.
ValueType computeMaxAbsDiff(std::vector< ValueType > const &allValues, storm::storage::BitVector const &relevantValues, std::vector< ValueType > const &oldValues)
bool isTerminate()
Check whether the program should terminate (due to some abort signal).
void selectVectorValues(std::vector< T > &vector, storm::storage::BitVector const &positions, std::vector< T > const &values)
Selects the elements from a vector at the specified positions and writes them consecutively into anot...
T computeSquaredNorm2Difference(std::vector< T > const &b1, std::vector< T > const &b2)
void multiplyVectorsPointwise(std::vector< InValueType1 > const &firstOperand, std::vector< InValueType2 > const &secondOperand, std::vector< OutValueType > &target)
Multiplies the two given vectors (pointwise) and writes the result to the target vector.
void applyPointwise(std::vector< InValueType1 > const &firstOperand, std::vector< InValueType2 > const &secondOperand, std::vector< OutValueType > &target, Operation f=Operation())
Applies the given operation pointwise on the two given vectors and writes the result to the third vec...
void subtractVectors(std::vector< InValueType1 > const &firstOperand, std::vector< InValueType2 > const &secondOperand, std::vector< OutValueType > &target)
Subtracts the two given vectors and writes the result to the target vector.
bool hasNonZeroEntry(std::vector< T > const &v)
ValueType pow(ValueType const &value, int_fast64_t exponent)
TargetType convertNumber(SourceType const &number)