/// <summary> /// Computes the influence of all configuration options based on the measurements of the given result db. It uses linear programming (simplex) and is an exact algorithm. /// </summary> /// <param name="nfp">The non-funcitonal property for which the influences of configuration options are to be computed. If null, we use the property of the global model.</param> /// <param name="infModel">The influence model containing options and interactions. The state of the model will be changed by the result of the process</param> /// <param name="db">The result database containing the measurements.</param> /// <returns>A map of binary options to their computed influences.</returns> public Dictionary<BinaryOption, double> computeOptionInfluences(NFProperty nfp, InfluenceModel infModel, ResultDB db) { List<BinaryOption> variables = infModel.Vm.BinaryOptions; List<double> results = new List<double>(); List<List<BinaryOption>> configurations = new List<List<BinaryOption>>(); foreach (Configuration c in db.Configurations) { configurations.Add(c.getBinaryOptions(BinaryOption.BinaryValue.Selected)); if (nfp != null) results.Add(c.GetNFPValue(nfp)); else results.Add(c.GetNFPValue()); } List<String> errorEqs = new List<string>(); Dictionary<String, double> faultRates = new Dictionary<string, double>(); List<int> indexOfErrorMeasurements = new List<int>(); Dictionary<String, double> featureValuedAsStrings = solve(variables, results, configurations, infModel.InteractionInfluence.Keys.ToList()); foreach (String current in featureValuedAsStrings.Keys) { BinaryOption temp = infModel.Vm.getBinaryOption(current); this.featureValues[temp] = featureValuedAsStrings[current]; InfluenceFunction influence = new InfluenceFunction(temp.Name + " + " + featureValuedAsStrings[current].ToString(),infModel.Vm); if (infModel.BinaryOptionsInfluence.Keys.Contains(temp)) infModel.BinaryOptionsInfluence[temp] = influence; else infModel.BinaryOptionsInfluence.Add(temp, influence); } return this.featureValues; }
/// <summary> /// Returns the of list of non function properties (nfps) measured for the configurations of the given file. To tune up performance, /// we consider only the first configurtion of the file and assume that all configurations have the same nfps. /// </summary> /// <param name="file">The xml file consisting of configurations.</param> /// <returns>The list of nfps the configurations have measurements.</returns> public static List<NFProperty> propertiesOfConfigurations(string file) { List<NFProperty> properties = new List<NFProperty>(); XmlDocument dat = new System.Xml.XmlDocument(); dat.Load(file); XmlElement currentElemt = dat.DocumentElement; XmlNode node = currentElemt.ChildNodes[0]; foreach (XmlNode childNode in node.ChildNodes) { switch (childNode.Attributes[0].Value) { // TODO we use this to support result files of the old structure case "Configuration": break; case "Variable Features": break; case "BinaryOptions": break; case "NumericOptions": break; default: NFProperty property = new NFProperty(childNode.Attributes[0].Value); properties.Add(property); break; } } return properties; }
public Distribution(string name, string prop, DistributionType type) { Name = name; SelectedNfProperty = GlobalState.getOrCreateProperty(prop); DistType = type; Scaled = false; }
public void TestNFProperty() { NFProperty created = GlobalState.getOrCreateProperty("testProperty"); Assert.AreEqual(created, GlobalState.getOrCreateProperty(created.Name)); GlobalState.setDefaultProperty(created.Name); Assert.AreEqual(created, GlobalState.currentNFP); }
/// <summary> /// Clears the global state. This mehtod should be used after performing all experiments of one case study. /// </summary> public static void clear() { varModel = null; currentNFP = null; allMeasurements = new ResultDB(); evalutionSet = new ResultDB(); infModel = null; nfProperties = new Dictionary<string,NFProperty>(); optionOrder = new List<ConfigurationOption>(); }
public void SetVariabilityModel(VariabilityModel model) { _vm = model; var prop = new NFProperty("NFP"); GlobalState.currentNFP = prop; _influenceModel = new InfluenceModel(_vm, prop); GlobalState.infModel = _influenceModel; GlobalState.varModel = _vm; }
/// <summary> /// This method searches for a corresponding methods in the dynamically loadeda assemblies and calls it if found. It prefers due to performance reasons the Microsoft Solver Foundation implementation. /// </summary> /// <param name="nfp">The non-funcitonal property for which the influences of configuration options are to be computed. If null, we use the property of the global model.</param> /// <param name="infModel">The influence model containing options and interactions. The state of the model will be changed by the result of the process</param> /// <param name="db">The result database containing the measurements.</param> /// <returns>A map of binary options to their computed influences.</returns> public Dictionary<BinaryOption, double> computeOptionInfluences(NFProperty nfp, InfluenceModel infModel, ResultDB db) { foreach (Lazy<ISolverLP, ISolverType> solver in solvers) { if (solver.Metadata.SolverType.Equals("MSSolverFoundation")) return solver.Value.computeOptionInfluences(nfp, infModel, db); } //If not MS Solver, take any solver. Should be changed when supporting more than 2 solvers here foreach (Lazy<ISolverLP, ISolverType> solver in solvers) { return solver.Value.computeOptionInfluences(nfp, infModel, db); } return null; }
/// <summary> /// This method searches for a corresponding methods in the dynamically loadeda assemblies and calls it if found. It prefers due to performance reasons the Microsoft Solver Foundation implementation. /// </summary> /// <param name="nfp">The non-funcitonal property for which the influences of configuration options are to be computed. If null, we use the property of the global model.</param> /// <param name="infModel">The influence model containing the variability model, all configuration options and interactions.</param> /// <param name="db">The result database containing the measurements.</param> /// <param name="evaluateFeatureInteractionsOnly">Only interactions are learned.</param> /// <param name="withDeviation">(Not used) We can specifiy whether learned influences must be greater than a certain value (e.g., greater than measurement bias).</param> /// <param name="deviation">(Not used) We can specifiy whether learned influences must be greater than a certain value (e.g., greater than measurement bias).</param> /// <returns>Returns the learned infleunces of each option in a map whereas the String (Key) is the name of the option / interaction.</returns> public Dictionary <string, double> computeOptionInfluences(NFProperty nfp, InfluenceModel infModel, ResultDB db, bool evaluateFeatureInteractionsOnly, bool withDeviation, double deviation) { foreach (Lazy <ISolverLP, ISolverType> solver in solvers) { if (solver.Metadata.SolverType.Equals("MSSolverFoundation")) { return(solver.Value.computeOptionInfluences(nfp, infModel, db, evaluateFeatureInteractionsOnly, withDeviation, deviation)); } } //If not MS Solver, take any solver. Should be changed when supporting more than 2 solvers here foreach (Lazy <ISolverLP, ISolverType> solver in solvers) { return(solver.Value.computeOptionInfluences(nfp, infModel, db, evaluateFeatureInteractionsOnly, withDeviation, deviation)); } return(null); }
/// <summary> /// This method searches for a corresponding methods in the dynamically loadeda assemblies and calls it if found. It prefers due to performance reasons the Microsoft Solver Foundation implementation. /// </summary> /// <param name="nfp">The non-funcitonal property for which the influences of configuration options are to be computed. If null, we use the property of the global model.</param> /// <param name="infModel">The influence model containing options and interactions. The state of the model will be changed by the result of the process</param> /// <param name="db">The result database containing the measurements.</param> /// <returns>A map of binary options to their computed influences.</returns> public Dictionary <BinaryOption, double> computeOptionInfluences(NFProperty nfp, InfluenceModel infModel, ResultDB db) { foreach (Lazy <ISolverLP, ISolverType> solver in solvers) { if (solver.Metadata.SolverType.Equals("MSSolverFoundation")) { return(solver.Value.computeOptionInfluences(nfp, infModel, db)); } } //If not MS Solver, take any solver. Should be changed when supporting more than 2 solvers here foreach (Lazy <ISolverLP, ISolverType> solver in solvers) { return(solver.Value.computeOptionInfluences(nfp, infModel, db)); } return(null); }
/// <summary> /// Creates attributed variability model with interactions, reports progress to GUI BackgroundWorker <param>worker</param> /// </summary> /// <param name="varModel"></param> /// <param name="features"></param> /// <param name="interactions"></param> /// <param name="worker"></param> public void CreateFromVarModel(VariabilityModel varModel, Distribution features, Distribution interactions, BackgroundWorker worker) { _varModel = varModel; var prop = new NFProperty("NFP"); GlobalState.currentNFP = prop; _influenceModel = new InfluenceModel(varModel, prop); GlobalState.infModel = _influenceModel; GlobalState.varModel = varModel; FeatureValues = features.Values; interactions = ScaleInteractionValuesToFeature(features, interactions); InteractionValues = interactions.Values.OrderBy(x => _rand.Next()).ToArray(); AddAttributesToModel(); AddInteractions(_model.Setting.InteractionOrderPercent, worker); _influenceModel.printModelAsFunction("ivmodel.txt"); }
/// <summary> /// Computes the influence of all configuration options based on the measurements of the given result db. It uses linear programming (simplex) and is an exact algorithm. /// </summary> /// <param name="nfp">The non-functional property for which the influences of configuration options are to be computed. If null, we use the property of the global model.</param> /// <param name="infModel">The influence model containing options and interactions. The state of the model will be changed by the result of the process</param> /// <param name="db">The result database containing the measurements.</param> /// <returns>A map of binary options to their computed influences.</returns> public Dictionary <BinaryOption, double> computeOptionInfluences(NFProperty nfp, InfluenceModel infModel, ResultDB db) { List <BinaryOption> variables = infModel.Vm.BinaryOptions; List <double> results = new List <double>(); List <List <BinaryOption> > configurations = new List <List <BinaryOption> >(); foreach (Configuration c in db.Configurations) { configurations.Add(c.getBinaryOptions(BinaryOption.BinaryValue.Selected)); if (nfp != null) { results.Add(c.GetNFPValue(nfp)); } else { results.Add(c.GetNFPValue()); } } List <String> errorEqs = new List <string>(); Dictionary <String, double> faultRates = new Dictionary <string, double>(); List <int> indexOfErrorMeasurements = new List <int>(); Dictionary <String, double> featureValuedAsStrings = solve(variables, results, configurations, infModel.InteractionInfluence.Keys.ToList()); foreach (String current in featureValuedAsStrings.Keys) { BinaryOption temp = infModel.Vm.getBinaryOption(current); this.featureValues[temp] = featureValuedAsStrings[current]; InfluenceFunction influence = new InfluenceFunction(temp.Name + " + " + featureValuedAsStrings[current].ToString(), infModel.Vm); if (infModel.BinaryOptionsInfluence.Keys.Contains(temp)) { infModel.BinaryOptionsInfluence[temp] = influence; } else { infModel.BinaryOptionsInfluence.Add(temp, influence); } } return(this.featureValues); }
/// <summary> /// The mehtod returns non function property with the given name. If there is no property with the name, a new property is created. /// </summary> /// <param name="name">Name of the property</param> /// <returns>A non functional property with the specified name.</returns> public static NFProperty getOrCreateProperty(string name) { if(nfProperties.Keys.Contains(name)) return nfProperties[name]; else{ NFProperty newProp = new NFProperty(name); nfProperties.Add(name, newProp); return newProp; } }
public InfluenceModel(VariabilityModel vm, NFProperty nfp) { this.vm = vm; this.nfp = nfp; }
/// <summary> /// Performs the functionality of one command. If no functionality is found for the command, the command is retuned by this method. /// </summary> /// <param name="line">One command with its parameters.</param> /// <returns>Returns an empty string if the command could be performed by the method. If the command could not be performed by the method, the original command is returned.</returns> public string performOneCommand(string line) { GlobalState.logInfo.logLine(COMMAND + line); // remove comment part of the line (the comment starts with an #) line = line.Split(new Char[] { '#' }, 2)[0]; if (line.Length == 0) return ""; // split line in command and parameters of the command string[] components = line.Split(new Char[] { ' ' }, 2); string command = components[0]; string task = ""; if (components.Length > 1) task = components[1]; string[] taskAsParameter = task.Split(new Char[] { ' ' }); switch (command.ToLower()) { case COMMAND_START_ALLMEASUREMENTS: { InfluenceModel infMod = new InfluenceModel(GlobalState.varModel, GlobalState.currentNFP); List<Configuration> configurations_Learning = new List<Configuration>(); foreach (Configuration config in GlobalState.allMeasurements.Configurations) { if (config.nfpValues.ContainsKey(GlobalState.currentNFP)) configurations_Learning.Add(config); } if (configurations_Learning.Count == 0) { GlobalState.logInfo.logLine("The learning set is empty! Cannot start learning!"); break; } GlobalState.logInfo.logLine("Learning: " + "NumberOfConfigurationsLearning:" + configurations_Learning.Count); // prepare the machine learning exp = new MachineLearning.Learning.Regression.Learning(configurations_Learning, configurations_Learning); exp.metaModel = infMod; exp.mLsettings = this.mlSettings; exp.learn(); } break; case COMMAND_TRUEMODEL: StreamReader readModel = new StreamReader(task); String model = readModel.ReadLine().Trim(); readModel.Close(); this.trueModel = new InfluenceFunction(model.Replace(',', '.'), GlobalState.varModel); NFProperty artificalProp = new NFProperty("artificial"); GlobalState.currentNFP = artificalProp; //computeEvaluationDataSetBasedOnTrueModel(); break; case COMMAND_SUBSCRIPT: { FileInfo fi = new FileInfo(task); StreamReader reader = null; if (!fi.Exists) throw new FileNotFoundException(@"Automation script not found. ", fi.ToString()); reader = fi.OpenText(); Commands co = new Commands(); co.exp = this.exp; while (!reader.EndOfStream) { String oneLine = reader.ReadLine().Trim(); co.performOneCommand(oneLine); } } break; case COMMAND_EVALUATION_SET: { GlobalState.evalutionSet.Configurations = ConfigurationReader.readConfigurations(task, GlobalState.varModel); GlobalState.logInfo.logLine("Evaluation set loaded."); } break; case COMMAND_CLEAR_GLOBAL: SPLConqueror_Core.GlobalState.clear(); toSample.Clear(); toSampleValidation.Clear(); break; case COMMAND_CLEAR_SAMPLING: exp.clearSampling(); toSample.Clear(); toSampleValidation.Clear(); break; case COMMAND_CLEAR_LEARNING: exp.clear(); toSample.Clear(); toSampleValidation.Clear(); break; case COMMAND_LOAD_CONFIGURATIONS: GlobalState.allMeasurements.Configurations = (GlobalState.allMeasurements.Configurations.Union(ConfigurationReader.readConfigurations(task, GlobalState.varModel))).ToList(); GlobalState.logInfo.logLine(GlobalState.allMeasurements.Configurations.Count + " configurations loaded."); break; case COMMAND_SAMPLE_ALLBINARY: { if (taskAsParameter.Contains(COMMAND_VALIDATION)) { this.toSampleValidation.Add(SamplingStrategies.ALLBINARY); this.exp.info.binarySamplings_Validation = "ALLBINARY"; } else { this.toSample.Add(SamplingStrategies.ALLBINARY); this.exp.info.binarySamplings_Learning = "ALLBINARY"; } break; } case COMMAND_ANALYZE_LEARNING: {//TODO: Analyzation is not supported in the case of bagging GlobalState.logInfo.logLine("Models:"); if (this.mlSettings.bagging) { for (int i = 0; i < this.exp.models.Count; i++) { FeatureSubsetSelection learnedModel = exp.models[i]; if (learnedModel == null) { GlobalState.logError.logLine("Error... learning was not performed!"); break; } GlobalState.logInfo.logLine("Termination reason: " + learnedModel.LearningHistory.Last().terminationReason); foreach (LearningRound lr in learnedModel.LearningHistory) { double relativeError = 0; if (GlobalState.evalutionSet.Configurations.Count > 0) { double relativeErro2r = learnedModel.computeError(lr.FeatureSet, GlobalState.evalutionSet.Configurations, out relativeError); } else { double relativeErro2r = learnedModel.computeError(lr.FeatureSet, GlobalState.allMeasurements.Configurations, out relativeError); } GlobalState.logInfo.logLine(lr.ToString() + relativeError); } } } else { FeatureSubsetSelection learnedModel = exp.models[0]; if (learnedModel == null) { GlobalState.logError.logLine("Error... learning was not performed!"); break; } GlobalState.logInfo.logLine("Termination reason: " + learnedModel.LearningHistory.Last().terminationReason); foreach (LearningRound lr in learnedModel.LearningHistory) { double relativeError = 0; if (GlobalState.evalutionSet.Configurations.Count > 0) { double relativeErro2r = learnedModel.computeError(lr.FeatureSet, GlobalState.evalutionSet.Configurations, out relativeError); } else { double relativeErro2r = learnedModel.computeError(lr.FeatureSet, GlobalState.allMeasurements.Configurations, out relativeError); } GlobalState.logInfo.logLine(lr.ToString() + relativeError); } } break; } case COMMAND_EXERIMENTALDESIGN: performOneCommand_ExpDesign(task); break; case COMMAND_SAMPLING_OPTIONORDER: parseOptionOrder(task); break; case COMMAND_VARIABILITYMODEL: GlobalState.varModel = VariabilityModel.loadFromXML(task); if (GlobalState.varModel == null) GlobalState.logError.logLine("No variability model found at " + task); break; case COMMAND_SET_NFP: GlobalState.currentNFP = GlobalState.getOrCreateProperty(task.Trim()); break; case COMMAND_SAMPLE_OPTIONWISE: if (taskAsParameter.Contains(COMMAND_VALIDATION)) { this.toSampleValidation.Add(SamplingStrategies.OPTIONWISE); this.exp.info.binarySamplings_Validation = "OPTIONSWISE"; } else { this.toSample.Add(SamplingStrategies.OPTIONWISE); this.exp.info.binarySamplings_Learning = "OPTIONSWISE"; } break; case COMMAND_LOG: string location = task.Trim(); GlobalState.logInfo.close(); GlobalState.logInfo = new InfoLogger(location); GlobalState.logError.close(); GlobalState.logError = new ErrorLogger(location + "_error"); break; case COMMAND_SET_MLSETTING: this.mlSettings = ML_Settings.readSettings(task); break; case COMMAND_LOAD_MLSETTINGS: this.mlSettings = ML_Settings.readSettingsFromFile(task); break; case COMMAND_SAMPLE_PAIRWISE: if (taskAsParameter.Contains(COMMAND_VALIDATION)) { this.toSampleValidation.Add(SamplingStrategies.PAIRWISE); this.exp.info.binarySamplings_Validation = "PAIRWISE"; } else { this.toSample.Add(SamplingStrategies.PAIRWISE); this.exp.info.binarySamplings_Learning = "PAIRWISE"; } break; case COMMAND_PRINT_MLSETTINGS: GlobalState.logInfo.logLine(this.mlSettings.ToString()); break; case COMMAND_PRINT_CONFIGURATIONS: { /* List<Dictionary<NumericOption, double>> numericSampling = exp.NumericSelection_Learning; List<List<BinaryOption>> binarySampling = exp.BinarySelections_Learning; List<Configuration> configurations = new List<Configuration>(); foreach (Dictionary<NumericOption, double> numeric in numericSampling) { foreach (List<BinaryOption> binary in binarySampling) { Configuration config = Configuration.getConfiguration(binary, numeric); if (!configurations.Contains(config) && GlobalState.varModel.configurationIsValid(config)) { configurations.Add(config); } } }*/ var configs = ConfigurationBuilder.buildConfigs(GlobalState.varModel, this.toSample); string[] para = task.Split(new char[] { ' ' }); // TODO very error prone.. ConfigurationPrinter printer = new ConfigurationPrinter(para[0], para[1], para[2], GlobalState.optionOrder); printer.print(configs); break; } case COMMAND_SAMPLE_BINARY_RANDOM: { string[] para = task.Split(new char[] { ' ' }); ConfigurationBuilder.binaryThreshold = Convert.ToInt32(para[0]); ConfigurationBuilder.binaryModulu = Convert.ToInt32(para[1]); VariantGenerator vg = new VariantGenerator(null); if (taskAsParameter.Contains(COMMAND_VALIDATION)) { this.toSampleValidation.Add(SamplingStrategies.BINARY_RANDOM); this.exp.info.binarySamplings_Validation = "BINARY_RANDOM"; } else { this.toSample.Add(SamplingStrategies.BINARY_RANDOM); this.exp.info.binarySamplings_Learning = "BINARY_RANDOM " + task; } break; } case COMMAND_START_LEARNING: { InfluenceModel infMod = new InfluenceModel(GlobalState.varModel, GlobalState.currentNFP); List<Configuration> configurationsLearning = buildSet(this.toSample); List<Configuration> configurationsValidation = buildSet(this.toSampleValidation); if (configurationsLearning.Count == 0) { configurationsLearning = configurationsValidation; } if (configurationsLearning.Count == 0) { GlobalState.logInfo.logLine("The learning set is empty! Cannot start learning!"); break; } if (configurationsValidation.Count == 0) { configurationsValidation = configurationsLearning; } GlobalState.logInfo.logLine("Learning: " + "NumberOfConfigurationsLearning:" + configurationsLearning.Count + " NumberOfConfigurationsValidation:" + configurationsValidation.Count); //+ " UnionNumberOfConfigurations:" + (configurationsLearning.Union(configurationsValidation)).Count()); too costly to compute // We have to reuse the list of models because of NotifyCollectionChangedEventHandlers that might be attached to the list of models. exp.models.Clear(); var mod = exp.models; exp = new MachineLearning.Learning.Regression.Learning(configurationsLearning, configurationsValidation); exp.models = mod; exp.metaModel = infMod; exp.mLsettings = this.mlSettings; exp.learn(); GlobalState.logInfo.logLine("Average model: \n" + exp.metaModel.printModelAsFunction()); double relativeError = 0; if (GlobalState.evalutionSet.Configurations.Count > 0) { relativeError = FeatureSubsetSelection.computeError(exp.metaModel, GlobalState.evalutionSet.Configurations, ML_Settings.LossFunction.RELATIVE); } else { relativeError = FeatureSubsetSelection.computeError(exp.metaModel, GlobalState.allMeasurements.Configurations, ML_Settings.LossFunction.RELATIVE); } GlobalState.logInfo.logLine("Error :" + relativeError); } break; case COMMAND_SAMPLE_NEGATIVE_OPTIONWISE: // TODO there are two different variants in generating NegFW configurations. if (taskAsParameter.Contains(COMMAND_VALIDATION)) { this.toSampleValidation.Add(SamplingStrategies.NEGATIVE_OPTIONWISE); this.exp.info.binarySamplings_Validation = "NEGATIVE_OPTIONWISE"; } else { this.toSample.Add(SamplingStrategies.NEGATIVE_OPTIONWISE); this.exp.info.binarySamplings_Learning = "NEGATIVE_OPTIONWISE"; } break; default: return command; } return ""; }
/// <summary> /// Performs the functionality of one command. If no functionality is found for the command, the command is retuned by this method. /// </summary> /// <param name="line">One command with its parameters.</param> /// <returns>Returns an empty string if the command could be performed by the method. If the command could not be performed by the method, the original command is returned.</returns> public string performOneCommand(string line) { GlobalState.logInfo.log(COMMAND + line); // remove comment part of the line (the comment starts with an #) line = line.Split(new Char[] { '#' }, 2)[0]; if (line.Length == 0) return ""; // split line in command and parameters of the command string[] components = line.Split(new Char[] { ' ' }, 2); string command = components[0]; string task = ""; if (components.Length > 1) task = components[1]; string[] taskAsParameter = task.Split(new Char[] { ' ' }); switch (command.ToLower()) { case COMMAND_TRUEMODEL: StreamReader readModel = new StreamReader(task); String model = readModel.ReadLine().Trim(); readModel.Close(); exp.TrueModel = new InfluenceFunction(model.Replace(',','.'), GlobalState.varModel); NFProperty artificalProp = new NFProperty("artificial"); GlobalState.currentNFP = artificalProp; computeEvaluationDataSetBasedOnTrueModel(); break; case COMMAND_SUBSCRIPT: { FileInfo fi = new FileInfo(task); StreamReader reader = null; if (!fi.Exists) throw new FileNotFoundException(@"Automation script not found. ", fi.ToString()); reader = fi.OpenText(); Commands co = new Commands(); co.exp = this.exp; while (!reader.EndOfStream) { String oneLine = reader.ReadLine().Trim(); co.performOneCommand(oneLine); } } break; case COMMAND_EVALUATION_SET: { GlobalState.evalutionSet.Configurations = ConfigurationReader.readConfigurations(task, GlobalState.varModel); GlobalState.logInfo.log("Evaluation set loaded."); } break; case COMMAND_CLEAR_GLOBAL: SPLConqueror_Core.GlobalState.clear(); break; case COMMAND_CLEAR_SAMPLING: exp.clearSampling(); break; case COMMAND_CLEAR_LEARNING: exp.clear(); break; case COMMAND_LOAD_CONFIGURATIONS: GlobalState.allMeasurements.Configurations = (GlobalState.allMeasurements.Configurations.Union(ConfigurationReader.readConfigurations(task, GlobalState.varModel))).ToList(); GlobalState.logInfo.log(GlobalState.allMeasurements.Configurations.Count + " configurations loaded."); break; case COMMAND_SAMPLE_ALLBINARY: { VariantGenerator vg = new VariantGenerator(null); if (taskAsParameter.Contains(COMMAND_VALIDATION)) { exp.addBinarySelection_Validation(vg.generateAllVariantsFast(GlobalState.varModel)); exp.addBinarySampling_Validation(COMMAND_SAMPLE_ALLBINARY); } else { exp.addBinarySelection_Learning(vg.generateAllVariantsFast(GlobalState.varModel)); exp.addBinarySampling_Learning(COMMAND_SAMPLE_ALLBINARY); } break; } case COMMAND_ANALYZE_LEARNING: { GlobalState.logInfo.log("Models:"); FeatureSubsetSelection learning = exp.learning; if (learning == null) { GlobalState.logError.log("Error... learning was not performed!"); break; } foreach (LearningRound lr in learning.LearningHistory) { double relativeError = 0; if (GlobalState.evalutionSet.Configurations.Count > 0) { double relativeErro2r = exp.learning.computeError(lr.FeatureSet, GlobalState.evalutionSet.Configurations, out relativeError); } else { double relativeErro2r = exp.learning.computeError(lr.FeatureSet, GlobalState.allMeasurements.Configurations, out relativeError); } GlobalState.logInfo.log(lr.ToString() + relativeError); } break; } case COMMAND_EXERIMENTALDESIGN: performOneCommand_ExpDesign(task); break; case COMMAND_SAMPLING_OPTIONORDER: parseOptionOrder(task); break; case COMMAND_VARIABILITYMODEL: GlobalState.varModel = VariabilityModel.loadFromXML(task); if (GlobalState.varModel == null) GlobalState.logError.log("No variability model found at " + task); break; case COMMAND_SET_NFP: GlobalState.currentNFP = GlobalState.getOrCreateProperty(task.Trim()); break; case COMMAND_SAMPLE_OPTIONWISE: FeatureWise fw = new FeatureWise(); if (taskAsParameter.Contains(COMMAND_VALIDATION)) { exp.addBinarySelection_Validation(fw.generateFeatureWiseConfigsCSP(GlobalState.varModel)); exp.addBinarySampling_Validation("FW"); } else { //exp.addBinarySelection_Learning(fw.generateFeatureWiseConfigsCSP(GlobalState.varModel)); exp.addBinarySelection_Learning(fw.generateFeatureWiseConfigurations(GlobalState.varModel)); exp.addBinarySampling_Learning("FW"); } break; case COMMAND_LOG: string location = task.Trim(); GlobalState.logInfo.close(); GlobalState.logInfo = new InfoLogger(location); GlobalState.logError.close(); GlobalState.logError = new ErrorLogger(location + "_error"); break; case COMMAND_SET_MLSETTING: exp.mlSettings = ML_Settings.readSettings(task); break; case COMMAND_LOAD_MLSETTINGS: exp.mlSettings = ML_Settings.readSettingsFromFile(task); break; case COMMAND_SAMPLE_PAIRWISE: PairWise pw = new PairWise(); if (taskAsParameter.Contains(COMMAND_VALIDATION)) { exp.addBinarySelection_Validation(pw.generatePairWiseVariants(GlobalState.varModel)); exp.addBinarySampling_Validation("PW"); } else { exp.addBinarySelection_Learning(pw.generatePairWiseVariants(GlobalState.varModel)); exp.addBinarySampling_Learning("PW"); } break; case COMMAND_PRINT_MLSETTINGS: GlobalState.logInfo.log(exp.mlSettings.ToString()); break; case COMMAND_PRINT_CONFIGURATIONS: { List<Dictionary<NumericOption, double>> numericSampling = exp.NumericSelection_Learning; List<List<BinaryOption>> binarySampling = exp.BinarySelections_Learning; List<Configuration> configurations = new List<Configuration>(); foreach (Dictionary<NumericOption, double> numeric in numericSampling) { foreach (List<BinaryOption> binary in binarySampling) { Configuration config = Configuration.getConfiguration(binary, numeric); if (!configurations.Contains(config) && GlobalState.varModel.configurationIsValid(config)) { configurations.Add(config); } } } string[] para = task.Split(new char[] { ' ' }); // TODO very error prune.. ConfigurationPrinter printer = new ConfigurationPrinter(para[0], para[1], para[2], GlobalState.optionOrder); printer.print(configurations); break; } case COMMAND_SAMPLE_BINARY_RANDOM: { string[] para = task.Split(new char[] { ' ' }); int treshold = Convert.ToInt32(para[0]); int modulu = Convert.ToInt32(para[1]); VariantGenerator vg = new VariantGenerator(null); if (taskAsParameter.Contains(COMMAND_VALIDATION)) { exp.addBinarySelection_Validation(vg.generateRandomVariants(GlobalState.varModel, treshold, modulu)); exp.addBinarySampling_Validation("random " + task); } else { exp.addBinarySelection_Learning(vg.generateRandomVariants(GlobalState.varModel, treshold, modulu)); exp.addBinarySampling_Learning("random " + task); } break; } case COMMAND_START_LEARNING: { InfluenceModel infMod = new InfluenceModel(GlobalState.varModel, GlobalState.currentNFP); List<Configuration> configurations_Learning = new List<Configuration>(); List<Configuration> configurations_Validation = new List<Configuration>(); if (exp.TrueModel == null) { //List<List<BinaryOption>> availableBinary //configurations_Learning = GlobalState.getMeasuredConfigs(exp.BinarySelections_Learning, exp.NumericSelection_Learning); configurations_Learning = GlobalState.getMeasuredConfigs(Configuration.getConfigurations(exp.BinarySelections_Learning, exp.NumericSelection_Learning)); configurations_Learning = configurations_Learning.Distinct().ToList(); configurations_Validation = GlobalState.getMeasuredConfigs(Configuration.getConfigurations(exp.BinarySelections_Validation, exp.NumericSelection_Validation)); configurations_Validation = configurations_Validation.Distinct().ToList(); //break;//todo only to get the configurations that we haven't measured } else { foreach (List<BinaryOption> binConfig in exp.BinarySelections_Learning) { if (exp.NumericSelection_Learning.Count == 0) { Configuration c = new Configuration(binConfig); c.setMeasuredValue(GlobalState.currentNFP, exp.TrueModel.eval(c)); if (!configurations_Learning.Contains(c)) configurations_Learning.Add(c); continue; } foreach (Dictionary<NumericOption, double> numConf in exp.NumericSelection_Learning) { Configuration c = new Configuration(binConfig, numConf); c.setMeasuredValue(GlobalState.currentNFP, exp.TrueModel.eval(c)); if(GlobalState.varModel.configurationIsValid(c)) // if (!configurations_Learning.Contains(c)) configurations_Learning.Add(c); } } } if (configurations_Learning.Count == 0) { configurations_Learning = configurations_Validation; } if (configurations_Learning.Count == 0) { GlobalState.logInfo.log("The learning set is empty! Cannot start learning!"); break; } if (configurations_Validation.Count == 0) { configurations_Validation = configurations_Learning; } //break; GlobalState.logInfo.log("Learning: " + "NumberOfConfigurationsLearning:" + configurations_Learning.Count + " NumberOfConfigurationsValidation:" + configurations_Validation.Count + " UnionNumberOfConfigurations:" + (configurations_Learning.Union(configurations_Validation)).Count()); // prepare the machine learning exp.learning.init(infMod, exp.mlSettings); exp.learning.setLearningSet(configurations_Learning); exp.learning.setValidationSet(configurations_Validation); exp.learning.learn(); } break; case COMMAND_SAMPLE_NEGATIVE_OPTIONWISE: // TODO there are two different variants in generating NegFW configurations. NegFeatureWise neg = new NegFeatureWise(); if (taskAsParameter.Contains(COMMAND_VALIDATION)) { exp.addBinarySelection_Validation(neg.generateNegativeFW(GlobalState.varModel)); exp.addBinarySampling_Validation("newFW"); } else { exp.addBinarySelection_Learning(neg.generateNegativeFW(GlobalState.varModel));//neg.generateNegativeFWAllCombinations(GlobalState.varModel)); exp.addBinarySampling_Learning("newFW"); } break; default: return command; } return ""; }
/// <summary> /// This method searches for a corresponding methods in the dynamically loadeda assemblies and calls it if found. It prefers due to performance reasons the Microsoft Solver Foundation implementation. /// </summary> /// <param name="nfp">The non-funcitonal property for which the influences of configuration options are to be computed. If null, we use the property of the global model.</param> /// <param name="infModel">The influence model containing the variability model, all configuration options and interactions.</param> /// <param name="db">The result database containing the measurements.</param> /// <param name="evaluateFeatureInteractionsOnly">Only interactions are learned.</param> /// <param name="withDeviation">(Not used) We can specifiy whether learned influences must be greater than a certain value (e.g., greater than measurement bias).</param> /// <param name="deviation">(Not used) We can specifiy whether learned influences must be greater than a certain value (e.g., greater than measurement bias).</param> /// <returns>Returns the learned infleunces of each option in a map whereas the String (Key) is the name of the option / interaction.</returns> public Dictionary<string, double> computeOptionInfluences(NFProperty nfp, InfluenceModel infModel, ResultDB db, bool evaluateFeatureInteractionsOnly, bool withDeviation, double deviation) { foreach (Lazy<ISolverLP, ISolverType> solver in solvers) { if (solver.Metadata.SolverType.Equals("MSSolverFoundation")) return solver.Value.computeOptionInfluences(nfp, infModel, db, evaluateFeatureInteractionsOnly, withDeviation, deviation); } //If not MS Solver, take any solver. Should be changed when supporting more than 2 solvers here foreach (Lazy<ISolverLP, ISolverType> solver in solvers) { return solver.Value.computeOptionInfluences(nfp, infModel, db, evaluateFeatureInteractionsOnly, withDeviation, deviation); } return null; }
/// <summary> /// Computes the influence of all configuration options and interactions based on the measurements of the given result db. It uses linear programming (simplex) and is an exact algorithm. /// </summary> /// <param name="nfp">The non-funcitonal property for which the influences of configuration options are to be computed. If null, we use the property of the global model.</param> /// <param name="infModel">The influence model containing the variability model, all configuration options and interactions.</param> /// <param name="db">The result database containing the measurements.</param> /// <param name="evaluateFeatureInteractionsOnly">Only interactions are learned.</param> /// <param name="withDeviation">(Not used) We can specifiy whether learned influences must be greater than a certain value (e.g., greater than measurement bias).</param> /// <param name="deviation">(Not used) We can specifiy whether learned influences must be greater than a certain value (e.g., greater than measurement bias).</param> /// <returns>Returns the learned infleunces of each option in a map whereas the String (Key) is the name of the option / interaction.</returns> public Dictionary <String, double> computeOptionInfluences(NFProperty nfp, InfluenceModel infModel, ResultDB db, bool evaluateFeatureInteractionsOnly, bool withDeviation, double deviation) { //Initialization List <List <BinaryOption> > configurations = new List <List <BinaryOption> >(); this.evaluateInteractionsOnly = evaluateFeatureInteractionsOnly; this.withStandardDeviation = withDeviation; this.standardDeviation = deviation; List <double> results = new List <double>(); foreach (Configuration c in db.Configurations) { configurations.Add(c.getBinaryOptions(BinaryOption.BinaryValue.Selected)); if (nfp != null) { results.Add(c.GetNFPValue(nfp)); } else { results.Add(c.GetNFPValue()); } } List <BinaryOption> variables = new List <BinaryOption>(); Dictionary <String, double> featureValues = new Dictionary <string, double>(); Dictionary <String, double> faultRates = new Dictionary <string, double>(); List <int> indexOfErrorMeasurements = new List <int>(); if (configurations.Count == 0) { return(null); } //For the case there is an empty base if (configurations.Count != 0) { if (configurations[0].Count == 0) {//Should never occur that we get a configuration with no option selected... at least the root must be there BinaryOption root = infModel.Vm.Root; //Element baseElement = new Element("base_gen", infModel.getID(), infModel); //variables.Add(baseElement); // featureValues.Add(baseElement.getName(), 0); foreach (List <BinaryOption> config in configurations) { if (!config.Contains(root)) { config.Insert(0, root); } } } } //Building the variable list foreach (var elem in infModel.Vm.BinaryOptions) { variables.Add(elem); featureValues.Add(elem.Name, 0); } //First run featureValues = solve(variables, results, configurations, null); //if (evaluateFeatureInteractionsOnly == false) return(featureValues); /* * //We might have some interactions here and cannot compute all values * //1. identify options that are only present in these equations * Dictionary<Element, int> featureCounter = new Dictionary<Element, int>(); * for (int i = 0; i < indexOfErrorMeasurements.Count; i++) * { * * } * */ /*Todo: get compute interactins from deviations / errors of the LP results * if (errorEqs != null) * { * foreach (string eq in errorEqs) * { * double value = Double.Parse(eq.Substring(eq.IndexOf("==") + 2)); * * StringBuilder sb = new StringBuilder(); * List<Element> derivativeParents = new List<Element>(); * sb.Append("derivate_"); * string[] splittedEQ = eq.Split('+'); * foreach (string element in splittedEQ) * { * string name = element; * if (name.Contains("==")) * name = name.Substring(0, name.IndexOf("==")); * if (name.Contains("yp") && name.Contains("-yn")) * continue; * // string featureName = name.Substring(0, name.IndexOf("_p-")); * Element elem = infModel.getElementByNameUnsafe(name); * if (elem == null) * continue; * sb.Append("_" + name); * derivativeParents.Add(elem); * } * Element interaction = new Element(sb.ToString(), infModel.getID(), infModel); * interaction.setType("derivative"); * interaction.addDerivativeParents(derivativeParents); * infModel.addElement(interaction); * this.featureValues.Add(interaction, value); * } * } * return featureValues;*/ }
/// <summary> /// variability model /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void generateScript(List <MachineLearning.Learning.ML_Settings> mlSettings, Dictionary <string, List <ScriptGenerator.Container> > runs) { if (mlSettings.Count == 0 && splconqueror_learner) { informatioLabel.Text = "No mlSettings specified!"; return; } StringBuilder scriptContent = new StringBuilder(); List <StringBuilder> subscripts = new List <StringBuilder>(); if (splconqueror_learner) { foreach (Container c in addedElementsList.Items) { switch (c.Type.Trim()) { case CONTAINERKEY_LOGFILE: scriptContent.Append(CommandLine.Commands.COMMAND_LOG + " " + (c.Content) + "\n"); break; case Commands.COMMAND_SUBSCRIPT: scriptContent.Append(Commands.COMMAND_SUBSCRIPT + " " + c.Content + System.Environment.NewLine); if (clearGlobalAfterSubscript.Checked) { scriptContent.Append(Commands.COMMAND_CLEAR_GLOBAL + System.Environment.NewLine); } break; } } } if (subscriptEachVM.Checked) { int i = 0; foreach (ML_Settings setting in mlSettings) { foreach (Container varModelContainer in runs["variabilityModel"]) { // Placeholder variable scriptContent.Append("$" + i + System.Environment.NewLine); i++; StringBuilder subscript = new StringBuilder(); if (logForEachSubscript.Checked) { foreach (Container c in addedElementsList.Items) { switch (c.Type.Trim()) { case CONTAINERKEY_LOGFILE: subscript.Append(CommandLine.Commands.COMMAND_LOG + " " + (c.Content).ToString().Split(new char[] { '.' })[0] + "_subscript" + (i - 1) + ".log" + "\n"); break; } } } subscript.Append(mlSettingsContent(setting)); if (!splconqueror_learner && !(interpreter_Path == null || interpreter_Path.Equals(""))) { subscript.Append("define-python-path " + interpreter_Path + System.Environment.NewLine); } foreach (Container measurementContainer in varModelContainer.AdditionalInformation) { List <Container> nfpContainer = measurementContainer.AdditionalInformation; foreach (Container nfp in nfpContainer) { List <NFProperty> prop = (List <NFProperty>)nfp.Content; foreach (NFProperty pro in prop) { System.IO.FileInfo varModel = (System.IO.FileInfo)varModelContainer.Content; System.IO.FileInfo measurement = (System.IO.FileInfo)measurementContainer.Content; NFProperty nfpName = (NFProperty)pro; subscript.Append(Commands.COMMAND_VARIABILITYMODEL + " " + varModel + System.Environment.NewLine); subscript.Append(Commands.COMMAND_LOAD_CONFIGURATIONS + " " + measurement + System.Environment.NewLine); subscript.Append(Commands.COMMAND_SET_NFP + " " + pro.Name + System.Environment.NewLine); subscript.Append(samplingsToConsider(runs, varModel.Directory.FullName)); } } if (cleanGlobalAfterVM.Checked) { subscript.Append(Commands.COMMAND_CLEAR_GLOBAL + System.Environment.NewLine); } } if (clearGlobalAfterSubscript.Checked) { subscript.Append(Commands.COMMAND_CLEAR_GLOBAL + System.Environment.NewLine); } subscripts.Add(subscript); } } scriptContent.Append(Commands.COMMAND_CLEAR_LEARNING + System.Environment.NewLine); } else if (subscriptEachNfp.Checked) { int i = 0; foreach (ML_Settings setting in mlSettings) { foreach (Container varModelContainer in runs["variabilityModel"]) { foreach (Container measurementContainer in varModelContainer.AdditionalInformation) { List <Container> nfpContainer = measurementContainer.AdditionalInformation; foreach (Container nfp in nfpContainer) { List <NFProperty> prop = (List <NFProperty>)nfp.Content; foreach (NFProperty pro in prop) { // Placeholder variable scriptContent.Append("$" + i + System.Environment.NewLine); i++; StringBuilder subscript = new StringBuilder(); if (!splconqueror_learner && !(interpreter_Path == null || interpreter_Path.Equals(""))) { subscript.Append("define-python-path " + interpreter_Path + System.Environment.NewLine); } if (logForEachSubscript.Checked) { foreach (Container c in addedElementsList.Items) { switch (c.Type.Trim()) { case CONTAINERKEY_LOGFILE: subscript.Append(CommandLine.Commands.COMMAND_LOG + " " + (c.Content).ToString().Split(new char[] { '.' })[0] + "_subscript" + (i - 1) + ".log" + "\n"); break; } } } subscript.Append(mlSettingsContent(setting)); System.IO.FileInfo varModel = (System.IO.FileInfo)varModelContainer.Content; System.IO.FileInfo measurement = (System.IO.FileInfo)measurementContainer.Content; NFProperty nfpName = (NFProperty)pro; subscript.Append(Commands.COMMAND_VARIABILITYMODEL + " " + varModel + System.Environment.NewLine); subscript.Append(Commands.COMMAND_LOAD_CONFIGURATIONS + " " + measurement + System.Environment.NewLine); subscript.Append(Commands.COMMAND_SET_NFP + " " + pro.Name + System.Environment.NewLine); subscript.Append(samplingsToConsider(runs, varModel.Directory.FullName)); if (clearGlobalAfterSubscript.Checked) { subscript.Append(Commands.COMMAND_CLEAR_GLOBAL + System.Environment.NewLine); } subscripts.Add(subscript); } } if (cleanGlobalAfterVM.Checked) { scriptContent.Append(Commands.COMMAND_CLEAR_GLOBAL + System.Environment.NewLine); } } } } scriptContent.Append(Commands.COMMAND_CLEAR_LEARNING + System.Environment.NewLine); } else { foreach (ML_Settings setting in mlSettings) { scriptContent.Append(mlSettingsContent(setting)); if (!splconqueror_learner && !(interpreter_Path == null || interpreter_Path.Equals(""))) { scriptContent.Append("define-python-path " + interpreter_Path + System.Environment.NewLine); } foreach (Container varModelContainer in runs["variabilityModel"]) { foreach (Container measurementContainer in varModelContainer.AdditionalInformation) { List <Container> nfpContainer = measurementContainer.AdditionalInformation; foreach (Container nfp in nfpContainer) { List <NFProperty> prop = (List <NFProperty>)nfp.Content; foreach (NFProperty pro in prop) { System.IO.FileInfo varModel = (System.IO.FileInfo)varModelContainer.Content; System.IO.FileInfo measurement = (System.IO.FileInfo)measurementContainer.Content; NFProperty nfpName = (NFProperty)pro; scriptContent.Append(Commands.COMMAND_VARIABILITYMODEL + " " + varModel + System.Environment.NewLine); scriptContent.Append(Commands.COMMAND_LOAD_CONFIGURATIONS + " " + measurement + System.Environment.NewLine); scriptContent.Append(Commands.COMMAND_SET_NFP + " " + pro.Name + System.Environment.NewLine); scriptContent.Append(samplingsToConsider(runs, varModel.Directory.FullName)); } } if (cleanGlobalAfterVM.Checked) { scriptContent.Append(Commands.COMMAND_CLEAR_GLOBAL + System.Environment.NewLine); scriptContent.Append(mlSettingsContent(setting)); } } } } scriptContent.Append(Commands.COMMAND_CLEAR_LEARNING + System.Environment.NewLine); } SaveFileDialog saveFileDialog1 = new SaveFileDialog(); saveFileDialog1.Title = "Save Script"; saveFileDialog1.ShowDialog(); if (saveFileDialog1.FileName != "") { System.IO.FileStream fs = (System.IO.FileStream)saveFileDialog1.OpenFile(); if (subscriptEachVM.Checked || subscriptEachNfp.Checked) { string filepathWithoutEnding = saveFileDialog1.FileName; string ending = ""; string mainScriptAsString = scriptContent.ToString(); if (saveFileDialog1.FileName.Contains(".")) { ending = saveFileDialog1.FileName.Split(new char[] { '.' }).Last(); filepathWithoutEnding = saveFileDialog1.FileName.Replace("." + ending, ""); } for (int i = 0; i < subscripts.Count; ++i) { string currentLocation = filepathWithoutEnding + "_subscript_" + i + "." + ending; StreamWriter sw = new StreamWriter(currentLocation); sw.WriteLine(subscripts.ElementAt(i).ToString()); sw.Flush(); sw.Close(); mainScriptAsString = mainScriptAsString.Replace("$" + i, Commands.COMMAND_SUBSCRIPT + " " + currentLocation); } StreamWriter s = new StreamWriter(fs); s.WriteLine(mainScriptAsString); s.Flush(); fs.Close(); } else { StreamWriter s = new StreamWriter(fs); s.WriteLine(scriptContent.ToString()); s.Flush(); fs.Close(); } } }
/// <summary> /// Updates the measurement tab of the application. /// /// The method will check, if the preconditions are fulfilled (for example: Are there any /// loaded measurements?). Is not, an error message will be displayed. Is all preconditions /// are fulfilled, each IlPanel in the measurment tab will be recalculated and redrawn. /// </summary> private void updateMeasurementTab() { // Check if measurements are loaded if (!measurementsLoaded) { overviewPanel.Visible = false; bothGraphsPanel.Visible = false; measurementsOnlyPanel.Visible = false; absoluteDifferencePanel.Visible = false; relativeDifferencePanel.Visible = false; nfpValueCombobox.Enabled = false; measurementViewCombobox.Enabled = false; measurementErrorLabel.Visible = true; measurementErrorLabel.Text = ERROR_NO_MEASUREMENTS_LOADED; return; } // Check if a graph has been calculated before if (configurationForCalculation == null) { overviewPanel.Visible = false; bothGraphsPanel.Visible = false; measurementsOnlyPanel.Visible = false; absoluteDifferencePanel.Visible = false; relativeDifferencePanel.Visible = false; nfpValueCombobox.Enabled = false; measurementViewCombobox.Enabled = false; measurementErrorLabel.Visible = true; measurementErrorLabel.Text = ERROR_NO_PERFORMANCES; return; } // Check if the current configuration is possible if (!sat.checkConfigurationSAT(configurationForCalculation.BinaryOptions.Keys.ToList(), currentModel, true)) { overviewPanel.Visible = false; bothGraphsPanel.Visible = false; measurementsOnlyPanel.Visible = false; absoluteDifferencePanel.Visible = false; relativeDifferencePanel.Visible = false; nfpValueCombobox.Enabled = false; measurementViewCombobox.Enabled = false; measurementErrorLabel.Visible = true; measurementErrorLabel.Text = ERROR_ILLEGAL_CONFIGURATION; return; } // Calculating all measured configurations that can be used List<Configuration> neededConfigurations = new List<Configuration>(); foreach (Configuration conf in GlobalState.allMeasurements.Configurations) { bool insert = true; foreach (KeyValuePair<BinaryOption, BinaryOption.BinaryValue> entry in conf.BinaryOptions.ToList()) insert = insert && configurationForCalculation.BinaryOptions.ContainsKey(entry.Key); if (insert) { foreach (KeyValuePair<NumericOption, double> pair in configurationForCalculation.NumericOptions.ToList()) { double val; if (conf.NumericOptions.TryGetValue(pair.Key, out val)) insert = insert && val == pair.Value; } } if (insert) neededConfigurations.Add(conf); } // Check if there are no measurements for the current settings if (neededConfigurations.Count == 0) { overviewPerformanceIlPanel.Scene = new ILScene(); overviewMeasurementIlPanel.Scene = new ILScene(); overviewAbsoluteDifferenceIlPanel.Scene = new ILScene(); overviewRelativeDifferenceIlPanel.Scene = new ILScene(); bothGraphsIlPanel.Scene = new ILScene(); measurementsOnlyIlPanel.Scene = new ILScene(); absoluteDifferenceIlPanel.Scene = new ILScene(); relativeDifferenceIlPanel.Scene = new ILScene(); overviewPerformanceIlPanel.Refresh(); overviewMeasurementIlPanel.Refresh(); overviewAbsoluteDifferenceIlPanel.Refresh(); overviewRelativeDifferenceIlPanel.Refresh(); bothGraphsIlPanel.Refresh(); measurementsOnlyIlPanel.Refresh(); absoluteDifferenceIlPanel.Refresh(); relativeDifferenceIlPanel.Refresh(); overviewPanel.Visible = false; bothGraphsPanel.Visible = false; measurementsOnlyPanel.Visible = false; absoluteDifferencePanel.Visible = false; relativeDifferencePanel.Visible = false; nfpValueCombobox.Enabled = false; measurementViewCombobox.Enabled = false; measurementErrorLabel.Visible = true; measurementErrorLabel.Text = ERROR_NO_MEASUREMENTS_AVAILABLE; return; } if (nfpValueCombobox.Items.Count == 0) { foreach (KeyValuePair<string, NFProperty> entry in GlobalState.nfProperties.ToList()) nfpValueCombobox.Items.Add(entry.Key); nfpValueCombobox.SelectedIndex = 0; } NFProperty prop = new NFProperty(nfpValueCombobox.SelectedItem.ToString()); // Check if at least one configuration contains the current nfp value if(neededConfigurations.All(x => !x.nfpValues.Keys.Contains(prop))) { overviewPerformanceIlPanel.Scene = new ILScene(); overviewMeasurementIlPanel.Scene = new ILScene(); overviewAbsoluteDifferenceIlPanel.Scene = new ILScene(); overviewRelativeDifferenceIlPanel.Scene = new ILScene(); bothGraphsIlPanel.Scene = new ILScene(); measurementsOnlyIlPanel.Scene = new ILScene(); absoluteDifferenceIlPanel.Scene = new ILScene(); relativeDifferenceIlPanel.Scene = new ILScene(); overviewPerformanceIlPanel.Refresh(); overviewMeasurementIlPanel.Refresh(); overviewAbsoluteDifferenceIlPanel.Refresh(); overviewRelativeDifferenceIlPanel.Refresh(); bothGraphsIlPanel.Refresh(); measurementsOnlyIlPanel.Refresh(); absoluteDifferenceIlPanel.Refresh(); relativeDifferenceIlPanel.Refresh(); overviewPanel.Visible = false; bothGraphsPanel.Visible = false; measurementsOnlyPanel.Visible = false; absoluteDifferencePanel.Visible = false; relativeDifferencePanel.Visible = false; nfpValueCombobox.Enabled = true; measurementViewCombobox.Enabled = false; measurementErrorLabel.Visible = true; measurementErrorLabel.Text = ERROR_NO_MEASUREMENTS_NFP; return; } measurementErrorLabel.Visible = false; measurementViewCombobox.Enabled = true; nfpValueCombobox.Enabled = true; ILPlotCube bothGraphsCube, measurementsOnlyCube, absoluteDifferenceCube, relativeDifferenceCube, overviewPerformanceCube, overviewMeasurementsCube, overviewAbsoluteDifferenceCube, overviewRelativeDifferenceCube; // Decide if there has to be a 2D or 3D shape if (chosenOptions.Item2 == null) { // Define plot cubes bothGraphsCube = new ILPlotCube(twoDMode: true); measurementsOnlyCube = new ILPlotCube(twoDMode: true); absoluteDifferenceCube = new ILPlotCube(twoDMode: true); relativeDifferenceCube = new ILPlotCube(twoDMode: true); overviewPerformanceCube = new ILPlotCube(twoDMode: true); overviewMeasurementsCube = new ILPlotCube(twoDMode: true); overviewAbsoluteDifferenceCube = new ILPlotCube(twoDMode: true); overviewRelativeDifferenceCube = new ILPlotCube(twoDMode: true); bothGraphsCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; bothGraphsCube.Axes.YAxis.Label.Text = CORRESPONDING_VALUES_LABEL; measurementsOnlyCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; measurementsOnlyCube.Axes.YAxis.Label.Text = MEASURED_VALUE_LABEL; absoluteDifferenceCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; absoluteDifferenceCube.Axes.YAxis.Label.Text = ABSOLUTE_DIFFERENCE_LABEL; relativeDifferenceCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; relativeDifferenceCube.Axes.YAxis.Label.Text = RELATIVE_DIFFERENCE_LABEL; overviewPerformanceCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; overviewPerformanceCube.Axes.YAxis.Label.Text = PERFORMANCE_AXIS_LABEL; overviewMeasurementsCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; overviewMeasurementsCube.Axes.YAxis.Label.Text = MEASURED_VALUE_LABEL; overviewAbsoluteDifferenceCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; overviewAbsoluteDifferenceCube.Axes.YAxis.Label.Text = ABSOLUTE_DIFFERENCE_LABEL; overviewRelativeDifferenceCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; overviewRelativeDifferenceCube.Axes.YAxis.Label.Text = RELATIVE_DIFFERENCE_LABEL; // Add all values into the array ILArray<float> XY = ILMath.zeros<float>(0, 0); ILArray<float> absoluteDifferences = ILMath.zeros<float>(0, 0); ILArray<float> relativeDifferences = ILMath.zeros<float>(0, 0); List<double> values = chosenOptions.Item1.getAllValues(); values.Sort(); int pos = 0; foreach (double value in values) { Configuration c = null; double d; // Get the measurement for the current settings for (int j = 0; j < neededConfigurations.Count && c == null; j++) { neededConfigurations[j].NumericOptions.TryGetValue(chosenOptions.Item1, out d); if (d == value) c = neededConfigurations[j]; } if (c == null || !c.nfpValues.TryGetValue(prop, out d)) { // If there are no measurements for this specific setting, the line plots // have to be drawn up to this point. if (XY.Size[0] > 0) { bothGraphsCube.Add(new ILLinePlot(XY) { ColorOverride = measurementColor }); measurementsOnlyCube.Add(new ILLinePlot(XY) { ColorOverride = measurementColor }); absoluteDifferenceCube.Add(new ILLinePlot(absoluteDifferences)); relativeDifferenceCube.Add(new ILLinePlot(relativeDifferences)); overviewMeasurementsCube.Add(new ILLinePlot(XY) { ColorOverride = measurementColor }); overviewAbsoluteDifferenceCube.Add(new ILLinePlot(absoluteDifferences)); overviewRelativeDifferenceCube.Add(new ILLinePlot(relativeDifferences)); XY = ILMath.zeros<float>(0, 0); absoluteDifferences = ILMath.zeros<float>(0, 0); relativeDifferences = ILMath.zeros<float>(0, 0); pos = 0; } } else { // Calculate all values for the corresponding line plots. XY[0, pos] = (float)value; XY[1, pos] = (float)d; absoluteDifferences[0, pos] = (float)value; absoluteDifferences[1, pos] = ILMath.abs((float)d - calculatedPerformances[1, values.IndexOf(value)]); relativeDifferences[0, pos] = (float)value; if (ILMath.abs(XY[1, pos]) < 1) relativeDifferences[1, pos] = absoluteDifferences[1, pos] == XY[1, pos] ? 0 : 100; else relativeDifferences[1, pos] = absoluteDifferences[1, pos] >= 1 ? absoluteDifferences[1, pos]/XY[1, pos] * 100 : 0; ILPoints point = createPoint(XY[0, pos], XY[1, pos], 0, measurementPointLabel); // Adding events to the point to display its coordinates on the screen point.MouseMove += (s, a) => { Vector3 coor = point.GetPosition(); measurementPointLabel.Text = chosenOptions.Item1.Name + ": " + coor.X.ToString() + ", " + PERFORMANCE_AXIS_LABEL + ": " + coor.Y.ToString(); measurementPointLabel.Visible = true; }; pos++; bothGraphsCube.Add(point); measurementsOnlyCube.Add(point); } } // Insert all remaining line plot parts into the corresponding cubes. bothGraphsCube.Add(new ILLinePlot(XY) { ColorOverride = measurementColor }); bothGraphsCube.Add(new ILLinePlot(drawnPerformances) { Line = { Color = calculatedColor, DashStyle = DashStyle.Dashed } }); measurementsOnlyCube.Add(new ILLinePlot(XY) { ColorOverride = measurementColor }); absoluteDifferenceCube.Add(new ILLinePlot(absoluteDifferences)); absoluteDifferenceCube.Add(new ILLinePlot(ILMath.zeros<float>(1, 1))); relativeDifferenceCube.Add(new ILLinePlot(relativeDifferences)); relativeDifferenceCube.Add(new ILLinePlot(ILMath.zeros<float>(1, 1))); overviewPerformanceCube.Add(new ILLinePlot(drawnPerformances) { ColorOverride = calculatedColor }); overviewMeasurementsCube.Add(new ILLinePlot(XY) { ColorOverride = measurementColor }); overviewAbsoluteDifferenceCube.Add(new ILLinePlot(absoluteDifferences)); overviewAbsoluteDifferenceCube.Add(new ILLinePlot(ILMath.zeros<float>(1, 1))); overviewRelativeDifferenceCube.Add(new ILLinePlot(relativeDifferences)); overviewRelativeDifferenceCube.Add(new ILLinePlot(ILMath.zeros<float>(1, 1))); } else { ILArray<float> measurements, X, Y, absoluteDifferences, relativeDifferences; // Define all plot cubes bothGraphsCube = new ILPlotCube(twoDMode: false); measurementsOnlyCube = new ILPlotCube(twoDMode: false); absoluteDifferenceCube = new ILPlotCube(twoDMode: false); relativeDifferenceCube = new ILPlotCube(twoDMode: false); overviewPerformanceCube = new ILPlotCube(twoDMode: false); overviewMeasurementsCube = new ILPlotCube(twoDMode: false); overviewAbsoluteDifferenceCube = new ILPlotCube(twoDMode: false); overviewRelativeDifferenceCube = new ILPlotCube(twoDMode: false); bothGraphsCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; bothGraphsCube.Axes.YAxis.Label.Text = chosenOptions.Item2.Name; bothGraphsCube.Axes.ZAxis.Label.Text = CORRESPONDING_VALUES_LABEL; measurementsOnlyCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; measurementsOnlyCube.Axes.YAxis.Label.Text = chosenOptions.Item2.Name; measurementsOnlyCube.Axes.ZAxis.Label.Text = MEASURED_VALUE_LABEL; absoluteDifferenceCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; absoluteDifferenceCube.Axes.YAxis.Label.Text = chosenOptions.Item2.Name; absoluteDifferenceCube.Axes.ZAxis.Label.Text = ABSOLUTE_DIFFERENCE_LABEL; relativeDifferenceCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; relativeDifferenceCube.Axes.YAxis.Label.Text = chosenOptions.Item2.Name; relativeDifferenceCube.Axes.ZAxis.Label.Text = RELATIVE_DIFFERENCE_LABEL; overviewPerformanceCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; overviewPerformanceCube.Axes.YAxis.Label.Text = chosenOptions.Item2.Name; overviewPerformanceCube.Axes.ZAxis.Label.Text = PERFORMANCE_AXIS_LABEL; overviewMeasurementsCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; overviewMeasurementsCube.Axes.YAxis.Label.Text = chosenOptions.Item2.Name; overviewMeasurementsCube.Axes.ZAxis.Label.Text = MEASURED_VALUE_LABEL; overviewAbsoluteDifferenceCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; overviewAbsoluteDifferenceCube.Axes.YAxis.Label.Text = chosenOptions.Item2.Name; overviewAbsoluteDifferenceCube.Axes.ZAxis.Label.Text = ABSOLUTE_DIFFERENCE_LABEL; overviewRelativeDifferenceCube.Axes.XAxis.Label.Text = chosenOptions.Item1.Name; overviewRelativeDifferenceCube.Axes.YAxis.Label.Text = chosenOptions.Item2.Name; overviewRelativeDifferenceCube.Axes.ZAxis.Label.Text = RELATIVE_DIFFERENCE_LABEL; // Initialize and fill all arrays X = Array.ConvertAll(chosenOptions.Item1.getAllValues().ToArray(), x => (float)x); Y = Array.ConvertAll(chosenOptions.Item2.getAllValues().ToArray(), y => (float)y); ILArray<float> XMat = 1; ILArray<float> YMat = ILMath.meshgrid(Y, X, XMat); measurements = ILMath.zeros<float>(X.Length, Y.Length, 3); absoluteDifferences = ILMath.zeros<float>(X.Length, Y.Length, 3); relativeDifferences = ILMath.zeros<float>(X.Length, Y.Length, 3); measurements[":;:;1"] = XMat; measurements[":;:;2"] = YMat; List<double> valuesX = chosenOptions.Item1.getAllValues(); List<double> valuesY = chosenOptions.Item2.getAllValues(); valuesX.Sort(); valuesY.Sort(); // Read every possible measurement value. If there is none, the corresponding value will /// be set to negative infinity. for (int i = 0; i < valuesX.Count; i++) { for(int j = 0; j < valuesY.Count; j++) { Configuration c = null; double d1, d2; for (int k = 0; k < neededConfigurations.Count && c == null; k++) { neededConfigurations[k].NumericOptions.TryGetValue(chosenOptions.Item1, out d1); neededConfigurations[k].NumericOptions.TryGetValue(chosenOptions.Item2, out d2); if (d1 == valuesX[i] && d2 == valuesY[j]) c = neededConfigurations[k]; } if (c == null || !c.nfpValues.TryGetValue(prop, out d1)) measurements[i, j, 0] = float.NegativeInfinity; else { measurements[i, j, 0] = (float)d1; ILPoints point = createPoint(measurements[i, j, 1], measurements[i, j, 2], measurements[i, j, 0], measurementPointLabel); // Adding events to the point to display its coordinates on the screen point.MouseMove += (s, a) => { Vector3 coor = point.GetPosition(); measurementPointLabel.Text = chosenOptions.Item1.Name + ": " + coor.X.ToString() + ", " + chosenOptions.Item2.Name + ": " + coor.Y.ToString() + ", " + PERFORMANCE_AXIS_LABEL + ": " + coor.Z.ToString(); measurementPointLabel.Visible = true; }; bothGraphsCube.Add(point); measurementsOnlyCube.Add(point); } } } // Calculate all absolute and relative differences. for (int i = 0; i < measurements.Size[0]; i++) { for (int j = 0; j < measurements.Size[1]; j++) { absoluteDifferences[i, j, 0] = measurements[i, j, 0] == float.NegativeInfinity ? float.NegativeInfinity : Math.Abs(measurements[i, j, 0].GetArrayForRead()[0] - calculatedPerformances[i, j, 0].GetArrayForRead()[0]); absoluteDifferences[i, j, 1] = measurements[i, j, 1].GetArrayForRead()[0]; absoluteDifferences[i, j, 2] = measurements[i, j, 2].GetArrayForRead()[0]; if (measurements[i, j, 0] == float.NegativeInfinity) relativeDifferences[i, j, 0] = float.NegativeInfinity; else if (measurements[i, j, 0] == 0) relativeDifferences[i, j, 0] = absoluteDifferences[i, j, 0] == 0 ? 0 : 100; else relativeDifferences[i, j, 0] = absoluteDifferences[i, j, 0] >= 1 ? absoluteDifferences[i, j, 0] / measurements[i, j, 0] * 100 : 0; relativeDifferences[i, j, 1] = measurements[i, j, 1].GetArrayForRead()[0]; relativeDifferences[i, j, 2] = measurements[i, j, 2].GetArrayForRead()[0]; } } // Insert all information into the cubes bothGraphsCube.Add(new ILSurface(measurements) { ColorMode = ILSurface.ColorModes.Solid } ); bothGraphsCube.Add(new ILSurface(calculatedPerformances)); measurementsOnlyCube.Add(new ILSurface(measurements) { ColorMode = ILSurface.ColorModes.Solid } ); absoluteDifferenceCube.Add(new ILSurface(absoluteDifferences) { Children = { new ILColorbar() } }); absoluteDifferenceCube.Add(new ILSurface(ILMath.zeros<float>(3, 3, 3))); relativeDifferenceCube.Add(new ILSurface(relativeDifferences) { Children = { new ILColorbar() } }); relativeDifferenceCube.Add(new ILSurface(ILMath.zeros<float>(3, 3, 3))); overviewPerformanceCube.Add(new ILSurface(calculatedPerformances)); overviewMeasurementsCube.Add(new ILSurface(measurements) { ColorMode = ILSurface.ColorModes.Solid }); overviewMeasurementsCube.Add(new ILSurface(ILMath.zeros<float>(3, 3, 3))); overviewAbsoluteDifferenceCube.Add(new ILSurface(absoluteDifferences)); overviewAbsoluteDifferenceCube.Add(new ILSurface(ILMath.zeros<float>(3, 3, 3))); overviewRelativeDifferenceCube.Add(new ILSurface(relativeDifferences)); overviewRelativeDifferenceCube.Add(new ILSurface(ILMath.zeros<float>(3, 3, 3))); // Adding events for a synchronized rotation of the overview cubes overviewPerformanceCube.MouseMove += (s, e) => { ILPlotCube cube = overviewPerformanceIlPanel.GetCurrentScene().First<ILPlotCube>(); Matrix4 matrix = cube.Rotation; overviewMeasurementsCube.Rotation = matrix; overviewAbsoluteDifferenceCube.Rotation = matrix; overviewRelativeDifferenceCube.Rotation = matrix; overviewMeasurementIlPanel.Refresh(); overviewAbsoluteDifferenceIlPanel.Refresh(); overviewRelativeDifferenceIlPanel.Refresh(); }; overviewMeasurementsCube.MouseMove += (s, e) => { ILPlotCube cube = overviewMeasurementIlPanel.GetCurrentScene().First<ILPlotCube>(); Matrix4 matrix = cube.Rotation; overviewPerformanceCube.Rotation = matrix; overviewAbsoluteDifferenceCube.Rotation = matrix; overviewRelativeDifferenceCube.Rotation = matrix; overviewPerformanceIlPanel.Refresh(); overviewAbsoluteDifferenceIlPanel.Refresh(); overviewRelativeDifferenceIlPanel.Refresh(); }; overviewAbsoluteDifferenceCube.MouseMove += (s, e) => { ILPlotCube cube = overviewAbsoluteDifferenceIlPanel.GetCurrentScene().First<ILPlotCube>(); Matrix4 matrix = cube.Rotation; overviewPerformanceCube.Rotation = matrix; overviewMeasurementsCube.Rotation = matrix; overviewRelativeDifferenceCube.Rotation = matrix; overviewPerformanceIlPanel.Refresh(); overviewMeasurementIlPanel.Refresh(); overviewRelativeDifferenceIlPanel.Refresh(); }; overviewRelativeDifferenceCube.MouseMove += (s, e) => { ILPlotCube cube = overviewRelativeDifferenceIlPanel.GetCurrentScene().First<ILPlotCube>(); Matrix4 matrix = cube.Rotation; overviewPerformanceCube.Rotation = matrix; overviewMeasurementsCube.Rotation = matrix; overviewAbsoluteDifferenceCube.Rotation = matrix; overviewPerformanceIlPanel.Refresh(); overviewMeasurementIlPanel.Refresh(); overviewAbsoluteDifferenceIlPanel.Refresh(); }; } overviewPerformanceIlPanel.Scene = new ILScene { overviewPerformanceCube }; overviewMeasurementIlPanel.Scene = new ILScene { overviewMeasurementsCube }; overviewAbsoluteDifferenceIlPanel.Scene = new ILScene { overviewAbsoluteDifferenceCube }; overviewRelativeDifferenceIlPanel.Scene = new ILScene { overviewRelativeDifferenceCube }; bothGraphsIlPanel.Scene = new ILScene { bothGraphsCube }; measurementsOnlyIlPanel.Scene = new ILScene { measurementsOnlyCube }; absoluteDifferenceIlPanel.Scene = new ILScene { absoluteDifferenceCube }; relativeDifferenceIlPanel.Scene = new ILScene { relativeDifferenceCube }; overviewPerformanceIlPanel.Refresh(); overviewMeasurementIlPanel.Refresh(); overviewAbsoluteDifferenceIlPanel.Refresh(); overviewRelativeDifferenceIlPanel.Refresh(); bothGraphsIlPanel.Refresh(); measurementsOnlyIlPanel.Refresh(); absoluteDifferenceIlPanel.Refresh(); relativeDifferenceIlPanel.Refresh(); updateMeasurementPanel(); }
/// <summary> /// /// </summary> /// <param name="property"></param> public static void setDefaultProperty(NFProperty property) { GlobalState.currentNFP = property; }
/// <summary> /// Computes the influence of all configuration options and interactions based on the measurements of the given result db. It uses linear programming (simplex) and is an exact algorithm. /// </summary> /// <param name="nfp">The non-functional property for which the influences of configuration options are to be computed. If null, we use the property of the global model.</param> /// <param name="infModel">The influence model containing the variability model, all configuration options and interactions.</param> /// <param name="db">The result database containing the measurements.</param> /// <param name="evaluateFeatureInteractionsOnly">Only interactions are learned.</param> /// <param name="withDeviation">(Not used) We can specify whether learned influences must be greater than a certain value (e.g., greater than measurement bias).</param> /// <param name="deviation">(Not used) We can specify whether learned influences must be greater than a certain value (e.g., greater than measurement bias).</param> /// <returns>Returns the learned influences of each option in a map whereas the String (Key) is the name of the option / interaction.</returns> public Dictionary <String, double> computeOptionInfluences(NFProperty nfp, InfluenceModel infModel, ResultDB db, bool evaluateFeatureInteractionsOnly, bool withDeviation, double deviation) { //Initialization List <List <BinaryOption> > configurations = new List <List <BinaryOption> >(); this.evaluateInteractionsOnly = evaluateFeatureInteractionsOnly; this.withStandardDeviation = withDeviation; this.standardDeviation = deviation; List <double> results = new List <double>(); foreach (Configuration c in db.Configurations) { configurations.Add(c.getBinaryOptions(BinaryOption.BinaryValue.Selected)); if (nfp != null) { results.Add(c.GetNFPValue(nfp)); } else { results.Add(c.GetNFPValue()); } } List <BinaryOption> variables = new List <BinaryOption>(); Dictionary <String, double> featureValues = new Dictionary <string, double>(); Dictionary <String, double> faultRates = new Dictionary <string, double>(); List <int> indexOfErrorMeasurements = new List <int>(); if (configurations.Count == 0) { return(null); } //For the case there is an empty base if (configurations.Count != 0) { if (configurations[0].Count == 0) {//Should never occur that we get a configuration with no option selected... at least the root must be there BinaryOption root = infModel.Vm.Root; //Element baseElement = new Element("base_gen", infModel.getID(), infModel); //variables.Add(baseElement); // featureValues.Add(baseElement.getName(), 0); foreach (List <BinaryOption> config in configurations) { if (!config.Contains(root)) { config.Insert(0, root); } } } } //Building the variable list foreach (var elem in infModel.Vm.BinaryOptions) { variables.Add(elem); featureValues.Add(elem.Name, 0); } featureValues = solve(variables, results, configurations, null); return(featureValues); }
/// <summary> /// Computes the influence of all configuration options and interactions based on the measurements of the given result db. It uses linear programming (simplex) and is an exact algorithm. /// </summary> /// <param name="nfp">The non-funcitonal property for which the influences of configuration options are to be computed. If null, we use the property of the global model.</param> /// <param name="infModel">The influence model containing the variability model, all configuration options and interactions.</param> /// <param name="db">The result database containing the measurements.</param> /// <param name="evaluateFeatureInteractionsOnly">Only interactions are learned.</param> /// <param name="withDeviation">(Not used) We can specifiy whether learned influences must be greater than a certain value (e.g., greater than measurement bias).</param> /// <param name="deviation">(Not used) We can specifiy whether learned influences must be greater than a certain value (e.g., greater than measurement bias).</param> /// <returns>Returns the learned infleunces of each option in a map whereas the String (Key) is the name of the option / interaction.</returns> public Dictionary<String, double> computeOptionInfluences(NFProperty nfp, InfluenceModel infModel, ResultDB db, bool evaluateFeatureInteractionsOnly, bool withDeviation, double deviation) { //Initialization List<List<BinaryOption>> configurations = new List<List<BinaryOption>>(); this.evaluateInteractionsOnly = evaluateFeatureInteractionsOnly; this.withStandardDeviation = withDeviation; this.standardDeviation = deviation; List<double> results = new List<double>(); foreach (Configuration c in db.Configurations) { configurations.Add(c.getBinaryOptions(BinaryOption.BinaryValue.Selected)); if (nfp != null) results.Add(c.GetNFPValue(nfp)); else results.Add(c.GetNFPValue()); } List<BinaryOption> variables = new List<BinaryOption>(); Dictionary<String, double> featureValues = new Dictionary<string, double>(); Dictionary<String, double> faultRates = new Dictionary<string, double>(); List<int> indexOfErrorMeasurements = new List<int>(); if (configurations.Count == 0) return null; //For the case there is an empty base if (configurations.Count != 0) { if (configurations[0].Count == 0) {//Should never occur that we get a configuration with no option selected... at least the root must be there BinaryOption root = infModel.Vm.Root; //Element baseElement = new Element("base_gen", infModel.getID(), infModel); //variables.Add(baseElement); // featureValues.Add(baseElement.getName(), 0); foreach (List<BinaryOption> config in configurations) if(!config.Contains(root)) config.Insert(0, root); } } //Building the variable list foreach (var elem in infModel.Vm.BinaryOptions) { variables.Add(elem); featureValues.Add(elem.Name, 0); } //First run featureValues = solve(variables, results, configurations, null); //if (evaluateFeatureInteractionsOnly == false) return featureValues; /* //We might have some interactions here and cannot compute all values //1. identify options that are only present in these equations Dictionary<Element, int> featureCounter = new Dictionary<Element, int>(); for (int i = 0; i < indexOfErrorMeasurements.Count; i++) { } */ /*Todo: get compute interactins from deviations / errors of the LP results if (errorEqs != null) { foreach (string eq in errorEqs) { double value = Double.Parse(eq.Substring(eq.IndexOf("==") + 2)); StringBuilder sb = new StringBuilder(); List<Element> derivativeParents = new List<Element>(); sb.Append("derivate_"); string[] splittedEQ = eq.Split('+'); foreach (string element in splittedEQ) { string name = element; if (name.Contains("==")) name = name.Substring(0, name.IndexOf("==")); if (name.Contains("yp") && name.Contains("-yn")) continue; // string featureName = name.Substring(0, name.IndexOf("_p-")); Element elem = infModel.getElementByNameUnsafe(name); if (elem == null) continue; sb.Append("_" + name); derivativeParents.Add(elem); } Element interaction = new Element(sb.ToString(), infModel.getID(), infModel); interaction.setType("derivative"); interaction.addDerivativeParents(derivativeParents); infModel.addElement(interaction); this.featureValues.Add(interaction, value); } } return featureValues;*/ }
/// <summary> /// /// </summary> /// <param name="propertyName">Name of the property.</param> public static void setDefaultProperty(String propertyName) { GlobalState.currentNFP = GlobalState.nfProperties[propertyName]; }