summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Lima <rafael.palma.lima@gmail.com>2024-03-04 19:01:40 +0100
committerXisco Fauli <xiscofauli@libreoffice.org>2024-03-07 12:11:37 +0100
commitfa8351c50bd8f14830a461c09805e43c6fdb065d (patch)
treecc6612e24e8d09c55f2fd2dc7fa7e50de19d1138
parentRelated: tdf#150408 DOC filter: handle legal numbering (diff)
downloadcore-fa8351c50bd8f14830a461c09805e43c6fdb065d.tar.gz
core-fa8351c50bd8f14830a461c09805e43c6fdb065d.zip
tdf#158735 Save solver settings for DEPS and SCO as well
When bug tdf#38948 was originally fixed, the solvers DEPS and SCO were not considered. This caused a regression, because setting engine options for these solvers made them never be saved, even in its own sheet. This patch fixes that by incorporating the engine options for DEPS and SCO. Change-Id: I93af712f91da2f7b1ac57ed74f6c2c2d7d411bba Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164376 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> (cherry picked from commit 04d884cc99eb66679fb254129b54488bd40e5abf) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164385 Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
-rw-r--r--sc/inc/SolverSettings.hxx117
-rw-r--r--sc/qa/unit/data/ods/tdf158735.odsbin0 -> 21112 bytes
-rw-r--r--sc/qa/unit/ucalc_solver.cxx29
-rw-r--r--sc/source/core/data/SolverSettings.cxx220
4 files changed, 356 insertions, 10 deletions
diff --git a/sc/inc/SolverSettings.hxx b/sc/inc/SolverSettings.hxx
index ec1ef994a7b8..985e8d30f796 100644
--- a/sc/inc/SolverSettings.hxx
+++ b/sc/inc/SolverSettings.hxx
@@ -39,11 +39,34 @@ enum SolverParameter
SP_LO_ENGINE, // Engine name used in LO
SP_MS_ENGINE, // Engine ID used in MSO
SP_INTEGER, // Assume all variables are integer (0: no, 1: yes)
+ // LpSolve, CoinMP and SwarmSolver
SP_NON_NEGATIVE, // Assume non negativity (1: yes, 2: no)
SP_EPSILON_LEVEL, // Epsilon level
SP_LIMIT_BBDEPTH, // Branch and bound depth
SP_TIMEOUT, // Time limit to return a solution
- SP_ALGORITHM // Algorithm used by the SwarmSolver (1, 2 or 3)
+ SP_ALGORITHM, // Algorithm used by the SwarmSolver (1, 2 or 3)
+ // Engine options common for DEPS and SCO
+ SP_SWARM_SIZE, // Size of Swarm
+ SP_LEARNING_CYCLES, // Learning Cycles
+ SP_GUESS_VARIABLE_RANGE, // Variable Bounds Guessing
+ SP_VARIABLE_RANGE_THRESHOLD, // Variable Bounds Threshold (when guessing)
+ SP_ACR_COMPARATOR, // Use ACR Comparator (instead of BCH)
+ SP_RND_STARTING_POINT, // Use Random starting point
+ SP_STRONGER_PRNG, // Use a stronger random generator (slower)
+ SP_STAGNATION_LIMIT, // Stagnation Limit
+ SP_STAGNATION_TOLERANCE, // Stagnation Tolerance
+ SP_ENHANCED_STATUS, // Show enhanced solver status
+ // DEPS Options
+ SP_AGENT_SWITCH_RATE, // Agent Switch Rate (DE Probability)
+ SP_SCALING_MIN, // DE: Min Scaling Factor (0-1.2)
+ SP_SCALING_MAX, // DE: Max Scaling Factor (0-1.2)
+ SP_CROSSOVER_PROB, // DE: Crossover Probability (0-1)
+ SP_COGNITIVE_CONST, // Cognitive Constant
+ SP_SOCIAL_CONST, // Social Constant
+ SP_CONSTRICTION_COEFF, // PS: Constriction Coefficient
+ SP_MUTATION_PROB, // Mutation Probability (0-0.005)
+ // SCO Options
+ SP_LIBRARY_SIZE, // Size of library
};
// Starts at 1 to maintain MS compatibility
@@ -123,6 +146,28 @@ private:
OUString m_sLimitBBDepth;
OUString m_sTimeout;
OUString m_sAlgorithm;
+ // DEPS and SCO
+ OUString m_sSwarmSize;
+ OUString m_sLearningCycles;
+ OUString m_sGuessVariableRange;
+ OUString m_sVariableRangeThreshold;
+ OUString m_sUseACRComparator;
+ OUString m_sUseRandomStartingPoint;
+ OUString m_sUseStrongerPRNG;
+ OUString m_sStagnationLimit;
+ OUString m_sTolerance;
+ OUString m_sEnhancedSolverStatus;
+ // DEPS only
+ OUString m_sAgentSwitchRate;
+ OUString m_sScalingFactorMin;
+ OUString m_sScalingFactorMax;
+ OUString m_sCrossoverProbability;
+ OUString m_sCognitiveConstant;
+ OUString m_sSocialConstant;
+ OUString m_sConstrictionCoeff;
+ OUString m_sMutationProbability;
+ OUString m_sLibrarySize;
+
css::uno::Sequence<css::beans::PropertyValue> m_aEngineOptions;
std::vector<ModelConstraint> m_aConstraints;
@@ -131,7 +176,9 @@ private:
// Used to create or read a single solver parameter based on its named range
bool ReadParamValue(SolverParameter eParam, OUString& rValue, bool bRemoveQuotes = false);
+ bool ReadDoubleParamValue(SolverParameter eParam, OUString& rValue);
void WriteParamValue(SolverParameter eParam, OUString sValue, bool bQuoted = false);
+ void WriteDoubleParamValue(SolverParameter eParam, std::u16string_view sValue);
// Creates or reads all constraints stored in named ranges
void ReadConstraints();
@@ -149,19 +196,46 @@ private:
// Maps solver parameters to named ranges
std::map<SolverParameter, OUString> m_mNamedRanges
- = { { SP_OBJ_CELL, "solver_opt" }, { SP_OBJ_TYPE, "solver_typ" },
- { SP_OBJ_VAL, "solver_val" }, { SP_VAR_CELLS, "solver_adj" },
- { SP_CONSTR_COUNT, "solver_num" }, { SP_LO_ENGINE, "solver_lo_eng" },
- { SP_MS_ENGINE, "solver_eng" }, { SP_INTEGER, "solver_int" },
- { SP_NON_NEGATIVE, "solver_neg" }, { SP_EPSILON_LEVEL, "solver_eps" },
- { SP_LIMIT_BBDEPTH, "solver_bbd" }, { SP_TIMEOUT, "solver_tim" },
- { SP_ALGORITHM, "solver_alg" } };
+ = { { SP_OBJ_CELL, "solver_opt" },
+ { SP_OBJ_TYPE, "solver_typ" },
+ { SP_OBJ_VAL, "solver_val" },
+ { SP_VAR_CELLS, "solver_adj" },
+ { SP_CONSTR_COUNT, "solver_num" },
+ { SP_LO_ENGINE, "solver_lo_eng" },
+ { SP_MS_ENGINE, "solver_eng" },
+ { SP_INTEGER, "solver_int" },
+ { SP_NON_NEGATIVE, "solver_neg" },
+ { SP_EPSILON_LEVEL, "solver_eps" },
+ { SP_LIMIT_BBDEPTH, "solver_bbd" },
+ { SP_TIMEOUT, "solver_tim" },
+ { SP_ALGORITHM, "solver_alg" },
+ { SP_SWARM_SIZE, "solver_ssz" },
+ { SP_LEARNING_CYCLES, "solver_lcy" },
+ { SP_GUESS_VARIABLE_RANGE, "solver_gvr" },
+ { SP_VARIABLE_RANGE_THRESHOLD, "solver_vrt" },
+ { SP_ACR_COMPARATOR, "solver_acr" },
+ { SP_RND_STARTING_POINT, "solver_rsp" },
+ { SP_STRONGER_PRNG, "solver_prng" },
+ { SP_STAGNATION_LIMIT, "solver_slim" },
+ { SP_STAGNATION_TOLERANCE, "solver_stol" },
+ { SP_ENHANCED_STATUS, "solver_enst" },
+ { SP_AGENT_SWITCH_RATE, "solver_asr" },
+ { SP_SCALING_MIN, "solver_smin" },
+ { SP_SCALING_MAX, "solver_smax" },
+ { SP_CROSSOVER_PROB, "solver_crpb" },
+ { SP_COGNITIVE_CONST, "solver_cog" },
+ { SP_SOCIAL_CONST, "solver_soc" },
+ { SP_CONSTRICTION_COEFF, "solver_ccoeff" },
+ { SP_MUTATION_PROB, "solver_mtpb" },
+ { SP_LIBRARY_SIZE, "solver_lbsz" } };
// Maps LO solver implementation names to MS engine codes
std::map<OUString, OUString> SolverNamesToExcelEngines = {
{ "com.sun.star.comp.Calc.CoinMPSolver", "2" }, // Simplex LP
{ "com.sun.star.comp.Calc.LpsolveSolver", "2" }, // Simplex LP
- { "com.sun.star.comp.Calc.SwarmSolver", "1" } // GRG Nonlinear
+ { "com.sun.star.comp.Calc.SwarmSolver", "1" }, // GRG Nonlinear
+ { "com.sun.star.comp.Calc.NLPSolver.DEPSSolverImpl", "3" }, // DEPS
+ { "com.sun.star.comp.Calc.NLPSolver.SCOSolverImpl", "3" } // SCO
};
// Maps MS solver engine codes to LO solver implementation names
@@ -180,7 +254,30 @@ private:
{ "EpsilonLevel", { SP_EPSILON_LEVEL, "solver_eps", "int" } },
{ "LimitBBDepth", { SP_LIMIT_BBDEPTH, "solver_bbd", "bool" } },
{ "Timeout", { SP_TIMEOUT, "solver_tim", "int" } },
- { "Algorithm", { SP_ALGORITHM, "solver_alg", "int" } } };
+ { "Algorithm", { SP_ALGORITHM, "solver_alg", "int" } },
+ // SCO and DEPS
+ { "AssumeNonNegative", { SP_NON_NEGATIVE, "solver_neg", "bool" } },
+ { "SwarmSize", { SP_SWARM_SIZE, "solver_ssz", "int" } },
+ { "LearningCycles", { SP_LEARNING_CYCLES, "solver_lcy", "int" } },
+ { "GuessVariableRange", { SP_GUESS_VARIABLE_RANGE, "solver_gvr", "bool" } },
+ { "VariableRangeThreshold", { SP_VARIABLE_RANGE_THRESHOLD, "solver_vrt", "double" } },
+ { "UseACRComparator", { SP_ACR_COMPARATOR, "solver_acr", "bool" } },
+ { "UseRandomStartingPoint", { SP_RND_STARTING_POINT, "solver_rsp", "bool" } },
+ { "UseStrongerPRNG", { SP_STRONGER_PRNG, "solver_prng", "bool" } },
+ { "StagnationLimit", { SP_STAGNATION_LIMIT, "solver_slim", "int" } },
+ { "Tolerance", { SP_STAGNATION_TOLERANCE, "solver_stol", "double" } },
+ { "EnhancedSolverStatus", { SP_ENHANCED_STATUS, "solver_enst", "bool" } },
+ // DEPS only
+ { "AgentSwitchRate", { SP_AGENT_SWITCH_RATE, "solver_asr", "double" } },
+ { "DEFactorMin", { SP_SCALING_MIN, "solver_smin", "double" } },
+ { "DEFactorMax", { SP_SCALING_MAX, "solver_smax", "double" } },
+ { "DECR", { SP_CROSSOVER_PROB, "solver_crpb", "double" } },
+ { "PSC1", { SP_COGNITIVE_CONST, "solver_cog", "double" } },
+ { "PSC2", { SP_SOCIAL_CONST, "solver_soc", "double" } },
+ { "PSWeight", { SP_CONSTRICTION_COEFF, "solver_ccoeff", "double" } },
+ { "PSCL", { SP_MUTATION_PROB, "solver_mtpb", "double" } },
+ // SCO only
+ { "LibrarySize", { SP_LIBRARY_SIZE, "solver_lbsz", "int" } } };
// Stores the roots used for named ranges of constraint parts
// Items here must be in the same order as in ConstraintPart enum
diff --git a/sc/qa/unit/data/ods/tdf158735.ods b/sc/qa/unit/data/ods/tdf158735.ods
new file mode 100644
index 000000000000..6003f29bf38a
--- /dev/null
+++ b/sc/qa/unit/data/ods/tdf158735.ods
Binary files differ
diff --git a/sc/qa/unit/ucalc_solver.cxx b/sc/qa/unit/ucalc_solver.cxx
index 47770ec0c0e5..7834597e9c07 100644
--- a/sc/qa/unit/ucalc_solver.cxx
+++ b/sc/qa/unit/ucalc_solver.cxx
@@ -163,4 +163,33 @@ CPPUNIT_TEST_FIXTURE(SolverTest, tdf156815)
CPPUNIT_ASSERT_EQUAL(OUString("$NewName.$B$2"), aConstraints[0].aRightStr);
}
+// Tests if settings for the DEPS and SCO solvers are kept in the file
+CPPUNIT_TEST_FIXTURE(SolverTest, tdf158735)
+{
+ createScDoc("ods/tdf158735.ods");
+ ScDocument* pDoc = getScDoc();
+
+ // Test the non-default values of the DEPS model
+ ScTable* pTable = pDoc->FetchTable(0);
+ std::shared_ptr<sc::SolverSettings> pSettings = pTable->GetSolverSettings();
+ CPPUNIT_ASSERT(pSettings);
+ CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.comp.Calc.NLPSolver.DEPSSolverImpl"),
+ pSettings->GetParameter(SP_LO_ENGINE));
+ CPPUNIT_ASSERT_EQUAL(OUString("0.45"), pSettings->GetParameter(SP_AGENT_SWITCH_RATE));
+ CPPUNIT_ASSERT_EQUAL(OUString("0.85"), pSettings->GetParameter(SP_CROSSOVER_PROB));
+ CPPUNIT_ASSERT_EQUAL(OUString("1500"), pSettings->GetParameter(SP_LEARNING_CYCLES));
+ CPPUNIT_ASSERT_EQUAL(OUString("0"), pSettings->GetParameter(SP_ENHANCED_STATUS));
+
+ // Test the non-default values of the SCO model
+ pTable = pDoc->FetchTable(1);
+ pSettings = pTable->GetSolverSettings();
+ CPPUNIT_ASSERT(pSettings);
+ CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.comp.Calc.NLPSolver.SCOSolverImpl"),
+ pSettings->GetParameter(SP_LO_ENGINE));
+ CPPUNIT_ASSERT_EQUAL(OUString("180"), pSettings->GetParameter(SP_LIBRARY_SIZE));
+ CPPUNIT_ASSERT_EQUAL(OUString("0.00055"), pSettings->GetParameter(SP_STAGNATION_TOLERANCE));
+ CPPUNIT_ASSERT_EQUAL(OUString("1"), pSettings->GetParameter(SP_RND_STARTING_POINT));
+ CPPUNIT_ASSERT_EQUAL(OUString("80"), pSettings->GetParameter(SP_STAGNATION_LIMIT));
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/core/data/SolverSettings.cxx b/sc/source/core/data/SolverSettings.cxx
index 60eb747f55f5..64badb8c2790 100644
--- a/sc/source/core/data/SolverSettings.cxx
+++ b/sc/source/core/data/SolverSettings.cxx
@@ -11,6 +11,7 @@
#include <global.hxx>
#include <table.hxx>
#include <docsh.hxx>
+#include <rtl/math.hxx>
#include <solverutil.hxx>
#include <unotools/charclass.hxx>
#include <SolverSettings.hxx>
@@ -73,6 +74,28 @@ void SolverSettings::Initialize()
ReadParamValue(SP_LIMIT_BBDEPTH, m_sLimitBBDepth);
ReadParamValue(SP_TIMEOUT, m_sTimeout);
ReadParamValue(SP_ALGORITHM, m_sAlgorithm);
+ // Engine options common for DEPS and SCO
+ ReadParamValue(SP_SWARM_SIZE, m_sSwarmSize);
+ ReadParamValue(SP_LEARNING_CYCLES, m_sLearningCycles);
+ ReadParamValue(SP_GUESS_VARIABLE_RANGE, m_sGuessVariableRange);
+ ReadDoubleParamValue(SP_VARIABLE_RANGE_THRESHOLD, m_sVariableRangeThreshold);
+ ReadParamValue(SP_ACR_COMPARATOR, m_sUseACRComparator);
+ ReadParamValue(SP_RND_STARTING_POINT, m_sUseRandomStartingPoint);
+ ReadParamValue(SP_STRONGER_PRNG, m_sUseStrongerPRNG);
+ ReadParamValue(SP_STAGNATION_LIMIT, m_sStagnationLimit);
+ ReadDoubleParamValue(SP_STAGNATION_TOLERANCE, m_sTolerance);
+ ReadParamValue(SP_ENHANCED_STATUS, m_sEnhancedSolverStatus);
+ // DEPS Options
+ ReadDoubleParamValue(SP_AGENT_SWITCH_RATE, m_sAgentSwitchRate);
+ ReadDoubleParamValue(SP_SCALING_MIN, m_sScalingFactorMin);
+ ReadDoubleParamValue(SP_SCALING_MAX, m_sScalingFactorMax);
+ ReadDoubleParamValue(SP_CROSSOVER_PROB, m_sCrossoverProbability);
+ ReadDoubleParamValue(SP_COGNITIVE_CONST, m_sCognitiveConstant);
+ ReadDoubleParamValue(SP_SOCIAL_CONST, m_sSocialConstant);
+ ReadDoubleParamValue(SP_CONSTRICTION_COEFF, m_sConstrictionCoeff);
+ ReadDoubleParamValue(SP_MUTATION_PROB, m_sMutationProbability);
+ // SCO Options
+ ReadParamValue(SP_LIBRARY_SIZE, m_sLibrarySize);
}
// Returns the current value of the parameter in the object as a string
@@ -119,6 +142,63 @@ OUString SolverSettings::GetParameter(SolverParameter eParam)
case SP_ALGORITHM:
return m_sAlgorithm;
break;
+ case SP_SWARM_SIZE:
+ return m_sSwarmSize;
+ break;
+ case SP_LEARNING_CYCLES:
+ return m_sLearningCycles;
+ break;
+ case SP_GUESS_VARIABLE_RANGE:
+ return m_sGuessVariableRange;
+ break;
+ case SP_VARIABLE_RANGE_THRESHOLD:
+ return m_sVariableRangeThreshold;
+ break;
+ case SP_ACR_COMPARATOR:
+ return m_sUseACRComparator;
+ break;
+ case SP_RND_STARTING_POINT:
+ return m_sUseRandomStartingPoint;
+ break;
+ case SP_STRONGER_PRNG:
+ return m_sUseStrongerPRNG;
+ break;
+ case SP_STAGNATION_LIMIT:
+ return m_sStagnationLimit;
+ break;
+ case SP_STAGNATION_TOLERANCE:
+ return m_sTolerance;
+ break;
+ case SP_ENHANCED_STATUS:
+ return m_sEnhancedSolverStatus;
+ break;
+ case SP_AGENT_SWITCH_RATE:
+ return m_sAgentSwitchRate;
+ break;
+ case SP_SCALING_MIN:
+ return m_sScalingFactorMin;
+ break;
+ case SP_SCALING_MAX:
+ return m_sScalingFactorMax;
+ break;
+ case SP_CROSSOVER_PROB:
+ return m_sCrossoverProbability;
+ break;
+ case SP_COGNITIVE_CONST:
+ return m_sCognitiveConstant;
+ break;
+ case SP_SOCIAL_CONST:
+ return m_sSocialConstant;
+ break;
+ case SP_CONSTRICTION_COEFF:
+ return m_sConstrictionCoeff;
+ break;
+ case SP_MUTATION_PROB:
+ return m_sMutationProbability;
+ break;
+ case SP_LIBRARY_SIZE:
+ return m_sLibrarySize;
+ break;
default:
return "";
}
@@ -188,6 +268,75 @@ void SolverSettings::SetParameter(SolverParameter eParam, OUString sValue)
m_sAlgorithm = sValue;
}
break;
+ case SP_SWARM_SIZE:
+ m_sSwarmSize = sValue;
+ break;
+ case SP_LEARNING_CYCLES:
+ m_sLearningCycles = sValue;
+ break;
+ case SP_GUESS_VARIABLE_RANGE:
+ m_sGuessVariableRange = sValue;
+ break;
+ case SP_VARIABLE_RANGE_THRESHOLD:
+ m_sVariableRangeThreshold = sValue;
+ break;
+ case SP_ACR_COMPARATOR:
+ {
+ if (sValue == "0" || sValue == "1")
+ m_sUseACRComparator = sValue;
+ }
+ break;
+ case SP_RND_STARTING_POINT:
+ {
+ if (sValue == "0" || sValue == "1")
+ m_sUseRandomStartingPoint = sValue;
+ }
+ break;
+ case SP_STRONGER_PRNG:
+ {
+ if (sValue == "0" || sValue == "1")
+ m_sUseStrongerPRNG = sValue;
+ }
+ break;
+ case SP_STAGNATION_LIMIT:
+ m_sStagnationLimit = sValue;
+ break;
+ case SP_STAGNATION_TOLERANCE:
+ m_sTolerance = sValue;
+ break;
+ case SP_ENHANCED_STATUS:
+ {
+ if (sValue == "0" || sValue == "1")
+ m_sEnhancedSolverStatus = sValue;
+ }
+ break;
+ case SP_AGENT_SWITCH_RATE:
+ m_sAgentSwitchRate = sValue;
+ break;
+ case SP_SCALING_MIN:
+ m_sScalingFactorMin = sValue;
+ break;
+ case SP_SCALING_MAX:
+ m_sScalingFactorMax = sValue;
+ break;
+ case SP_CROSSOVER_PROB:
+ m_sCrossoverProbability = sValue;
+ break;
+ case SP_COGNITIVE_CONST:
+ m_sCognitiveConstant = sValue;
+ break;
+ case SP_SOCIAL_CONST:
+ m_sSocialConstant = sValue;
+ break;
+ case SP_CONSTRICTION_COEFF:
+ m_sConstrictionCoeff = sValue;
+ break;
+ case SP_MUTATION_PROB:
+ m_sMutationProbability = sValue;
+ break;
+ case SP_LIBRARY_SIZE:
+ m_sLibrarySize = sValue;
+ break;
default:
break;
}
@@ -321,12 +470,35 @@ void SolverSettings::SaveSolverSettings()
sal_Int32 nConstrCount = m_aConstraints.size();
WriteParamValue(SP_CONSTR_COUNT, OUString::number(nConstrCount));
+ // Solver engine options
WriteParamValue(SP_INTEGER, m_sInteger);
WriteParamValue(SP_NON_NEGATIVE, m_sNonNegative);
WriteParamValue(SP_EPSILON_LEVEL, m_sEpsilonLevel);
WriteParamValue(SP_LIMIT_BBDEPTH, m_sLimitBBDepth);
WriteParamValue(SP_TIMEOUT, m_sTimeout);
WriteParamValue(SP_ALGORITHM, m_sAlgorithm);
+ // Engine options common for DEPS and SCO
+ WriteParamValue(SP_SWARM_SIZE, m_sSwarmSize);
+ WriteParamValue(SP_LEARNING_CYCLES, m_sLearningCycles);
+ WriteParamValue(SP_GUESS_VARIABLE_RANGE, m_sGuessVariableRange);
+ WriteDoubleParamValue(SP_VARIABLE_RANGE_THRESHOLD, m_sVariableRangeThreshold);
+ WriteParamValue(SP_ACR_COMPARATOR, m_sUseACRComparator);
+ WriteParamValue(SP_RND_STARTING_POINT, m_sUseRandomStartingPoint);
+ WriteParamValue(SP_STRONGER_PRNG, m_sUseStrongerPRNG);
+ WriteParamValue(SP_STAGNATION_LIMIT, m_sStagnationLimit);
+ WriteDoubleParamValue(SP_STAGNATION_TOLERANCE, m_sTolerance);
+ WriteParamValue(SP_ENHANCED_STATUS, m_sEnhancedSolverStatus);
+ // DEPS Options
+ WriteDoubleParamValue(SP_AGENT_SWITCH_RATE, m_sAgentSwitchRate);
+ WriteDoubleParamValue(SP_SCALING_MIN, m_sScalingFactorMin);
+ WriteDoubleParamValue(SP_SCALING_MAX, m_sScalingFactorMax);
+ WriteDoubleParamValue(SP_CROSSOVER_PROB, m_sCrossoverProbability);
+ WriteDoubleParamValue(SP_COGNITIVE_CONST, m_sCognitiveConstant);
+ WriteDoubleParamValue(SP_SOCIAL_CONST, m_sSocialConstant);
+ WriteDoubleParamValue(SP_CONSTRICTION_COEFF, m_sConstrictionCoeff);
+ WriteDoubleParamValue(SP_MUTATION_PROB, m_sMutationProbability);
+ // SCO Options
+ WriteParamValue(SP_LIBRARY_SIZE, m_sLibrarySize);
if (m_pDocShell)
m_pDocShell->SetDocumentModified();
@@ -354,6 +526,26 @@ bool SolverSettings::ReadParamValue(SolverParameter eParam, OUString& rValue, bo
return false;
}
+// Reads a parameter value of type 'double' from the named range and into rValue
+bool SolverSettings::ReadDoubleParamValue(SolverParameter eParam, OUString& rValue)
+{
+ const auto iter = m_mNamedRanges.find(eParam);
+ assert(iter != m_mNamedRanges.end());
+ OUString sRange = iter->second;
+ ScRangeData* pRangeData
+ = m_pRangeName->findByUpperName(ScGlobal::getCharClass().uppercase(sRange));
+ if (pRangeData)
+ {
+ OUString sLocalizedValue = pRangeData->GetSymbol();
+ double fValue = rtl::math::stringToDouble(sLocalizedValue,
+ ScGlobal::getLocaleData().getNumDecimalSep()[0],
+ ScGlobal::getLocaleData().getNumThousandSep()[0]);
+ rValue = OUString::number(fValue);
+ return true;
+ }
+ return false;
+}
+
/* Writes a parameter value to the file as a named range.
* Argument bQuoted indicates whether the value should be enclosed with quotes or not (used
* for string expressions that must be enclosed with quotes)
@@ -375,6 +567,22 @@ void SolverSettings::WriteParamValue(SolverParameter eParam, OUString sValue, bo
m_pRangeName->insert(pNewEntry);
}
+// Writes a parameter value of type 'double' to the file as a named range
+// The argument 'sValue' uses dot as decimal separator and needs to be localized before
+// being written to the file
+void SolverSettings::WriteDoubleParamValue(SolverParameter eParam, std::u16string_view sValue)
+{
+ const auto iter = m_mNamedRanges.find(eParam);
+ assert(iter != m_mNamedRanges.end());
+ OUString sRange = iter->second;
+ double fValue = rtl::math::stringToDouble(sValue, '.', ',');
+ OUString sLocalizedValue = rtl::math::doubleToUString(
+ fValue, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
+ ScGlobal::getLocaleData().getNumDecimalSep()[0], true);
+ ScRangeData* pNewEntry = new ScRangeData(m_rDoc, sRange, sLocalizedValue);
+ m_pRangeName->insert(pNewEntry);
+}
+
void SolverSettings::GetEngineOptions(css::uno::Sequence<css::beans::PropertyValue>& aOptions)
{
sal_Int32 nOptionsSize = aOptions.getLength();
@@ -398,6 +606,12 @@ void SolverSettings::GetEngineOptions(css::uno::Sequence<css::beans::PropertyVal
pParamValues[i] = css::beans::PropertyValue(sLOParamName, -1, nValue,
css::beans::PropertyState_DIRECT_VALUE);
}
+ if (sParamType == "double")
+ {
+ css::uno::Any fValue(sParamValue.toDouble());
+ pParamValues[i] = css::beans::PropertyValue(sLOParamName, -1, fValue,
+ css::beans::PropertyState_DIRECT_VALUE);
+ }
if (sParamType == "bool")
{
// The parameter NonNegative is a special case for MS compatibility
@@ -438,6 +652,12 @@ void SolverSettings::SetEngineOptions(css::uno::Sequence<css::beans::PropertyVal
aProp.Value >>= nValue;
SetParameter(eParamId, OUString::number(nValue));
}
+ if (sParamType == "double")
+ {
+ double fValue = 0;
+ aProp.Value >>= fValue;
+ SetParameter(eParamId, OUString::number(fValue));
+ }
if (sParamType == "bool")
{
bool bValue = false;