def errorEstimation(self, errorEstimatorCoordinates=None): """ For an entry of errorEstimators, collect assembledEstimations from all assemblers corresponding to the same entry of assemblersForError. Then, pass this list to the error method of that entry of errorEstimators. """ if errorEstimatorCoordinates is None: errorEstimatorCoordinates = range(len(self.errorEstimators)) # Construct union of assemblers required, as well as corresponding assembler map assembler_union, assembler_union_map = getUnionAndMap( [self.assemblersForError[x] for x in errorEstimatorCoordinates]) # Obtain estimations corresponding to assembler_union assembled_estimations_before_map = self.estimation(assembler_union) # Remap assembled_estimations_before_map onto original assembler data structure assembled_estimation_lists = [] for map_list in assembler_union_map: assembled_estimation_lists.append( [assembled_estimations_before_map[x] for x in map_list]) # Compute errors errors = [] for i in range(len(errorEstimatorCoordinates)): coord = errorEstimatorCoordinates[i] assembled_estimations = assembled_estimation_lists[i] errors.append(self.errorEstimators[coord].error( *unpackedList(assembled_estimations))) return errors
def estimation(self, assemblerCoordinates=None): """ For an entry of assembler, collect estimations from all indices corresponding to the same entry of estimatorsForAssembler. Then, pass this list to the assembleEstimation method of that entry of assembler. """ # If nothing is specified, assemble all estimations if assemblerCoordinates is None: assemblerCoordinates = range(len(self.assemblers)) # Extract current hierarchy from list of indices extracted_hierarchy = self.hierarchy() # Construct union of estimators required, as well as corresponding map estimator_union, estimator_union_map = getUnionAndMap( [self.estimatorsForAssembler[x] for x in assemblerCoordinates]) # Retrieve all index estimations corresponding to each entry of estimator_union index_estimation_union = [] for coordinate_and_args in estimator_union: qoi_estimator_coordinate = coordinate_and_args[0] qoi_estimator_value_arguements = coordinate_and_args[1] # Assemble this quantity across indices index_estimation_for_assembler = self.indexEstimation( qoi_estimator_coordinate, qoi_estimator_value_arguements) index_estimation_union.append(index_estimation_for_assembler) # Remap this union back onto original estimatorsForAssembler list index_estimation_lists = [] for map_list in estimator_union_map: index_estimation_lists.append( [index_estimation_union[x] for x in map_list]) # Run the corresponding estimation methods on this estimations = [] for i in range(len(assemblerCoordinates)): estimations.append( self.assemblers[assemblerCoordinates[i]].assembleEstimation( extracted_hierarchy, *unpackedList(index_estimation_lists[i]))) return estimations
def update(self, samples): """ function updating the power sums given new samples input: self: an instance of the class samples: list containing new samples """ dimension = log2(len(samples[0])) # len(power_sum[0])=2**dimension # Let's unpack the nested list self.powerSums # First all elements in self.powerSums[0], then those in self.powerSums[1], etc. # Idem for samples # TODO is it the order in which we want these lists? power_sums = [item for sublist in self.powerSums for item in sublist] power_sums = self._updatedPowerSums(*power_sums, *unpackedList(samples)) power_sums = list(power_sums) for i in range(len(self.powerSums)): for j in range(len(self.powerSums[i])): self.powerSums[i][j] = power_sums.pop(0) self._sampleCounter = self._sampleCounter + len(samples)
def generate(self, indexValue): """ Generate new QoI instance. Calls randomInput (if no evaluation point is provided), then rawSolutions, then pass the outputs to qoiFromRaw and return its output. """ # Generate the random input necessary for the solver random_inputs = self.randomInput() # Generate the list [[QoI_1^l,...,QoI_N^l],[QoI_1^(l-1),...,QoI_N^(l-1)],...] raw_solutions, times_for_qoi = self.rawSolutions(random_inputs) # Do additional processing list_of_qoi = self.qoiFromRaw(raw_solutions) # Rearrange list to generate [[QoI_1^l, QoI_1^(l-1), ...],...,[QoI_N^l, QoI_N^(l-1), ...]] list_of_qoi = self.rearrangeListOfQoI(list_of_qoi) # Add together times total_time = sum_Task(*unpackedList(times_for_qoi)) return list_of_qoi, total_time
def error(self, *assembledEstimationsList): return self._errorMethod(self.parameters, *unpackedList(assembledEstimationsList))
def updatePredictors(self, predictorCoordinates=None): """ For an entry of qoiPredictor, retrieve all index estimations for the corresponding entry of estimatorsForPredictor and pass to the update method of qoiPredictor. If self.isCostUpdated is True, then do the same for costPredictor as well """ # TODO - The implicit assumption here is that there is a one-to-one map # between levelwise estimations and model built upon that estimation. We # have not yet allowed for a mechanism similar to the assembler mechanism # but at the indexwise quantities. Should we construct such a mechanism? # If nothing is specified, update all qoiPredictors if predictorCoordinates is None: predictorCoordinates = range(len(self.qoiPredictor)) # Extract current hierarchy from list of indices extracted_hierarchy = self.hierarchy() [indices, number_samples] = splitOneListIntoTwo(extracted_hierarchy) # Retrieve all index estimations corresponding to each entry of predictorCooridnates for i in predictorCoordinates: # Extract qoiEstimator coordinates and value arguements from estimatorsForPredictor qoi_estimator_coordinate = self.estimatorsForPredictor[i][0] qoi_estimator_value_arguements = self.estimatorsForPredictor[i][1] value_transform_function = self.estimatorsForPredictor[i][2] # Assemble this quantity across all indices and apply transformation index_estimations_before_transform = self.indexEstimation( qoi_estimator_coordinate, qoi_estimator_value_arguements) # TODO - qoiEstimator.value returns Var(Y_l)/N_l, whereas the model is fit # on Var(Y_l). The following if-else is a hack to multiply by the number of # samples . It is here temporarily until a better mechanism can be found. # Refer the to-do above. if qoi_estimator_value_arguements[-1] is False: index_estimation_for_predictor = [ value_transform_function( index_estimations_before_transform[i]) for i in range(len(index_estimations_before_transform)) ] else: index_estimation_for_predictor = [ value_transform_function( index_estimations_before_transform[i], number_samples[i]) for i in range(len(index_estimations_before_transform)) ] # Extract only the indices for which all of the multi-index components are non-zero data = [] for j in range(len(indices)): index = indices[j] if all([index[i] > 0 for i in range(len(index))]): data.append([index, index_estimation_for_predictor[j]]) else: pass # Run update method of qoiPredictor on these index estimations self.qoiPredictor[i].update(*unpackedList(data)) # Retrieve all index cost estimations and pass them to costPredictor if self.isCostUpdated: index_estimation_for_predictor = self.indexCostEstimation( self.costEstimatorForPredictor) # Extract only the indices for which all of the multi-index components are non-zero data = [] for j in range(len(indices)): index = indices[j] if all([index[i] > 0 for i in range(len(index))]): data.append([index, index_estimation_for_predictor[j]]) else: pass data = mergeTwoListsIntoOne(indices, index_estimation_for_predictor) self.costPredictor.update(*unpackedList(data))