Skip to content

packages/engine/scram-node/src/importance_analysis.h

Contains functionality to do numerical analysis of importance factors.

Namespaces

Name
scram
scram::mef
scram::core

Classes

Name
structscram::core::ImportanceFactors <br>Collection of importance factors for variables.
structscram::core::ImportanceRecord <br>Mapping of an event and its importance.
classscram::core::ImportanceAnalysis <br>Analysis of importance factors of risk model variables.
classscram::core::ImportanceAnalyzerBase <br>Base class for analyzers of importance factors with the help from probability analyzers.
classscram::core::ImportanceAnalyzer <br>Analyzer of importance factors with the help from probability analyzers.
classscram::core::ImportanceAnalyzer< Bdd > <br>Specialization of importance analyzer with Binary Decision Diagrams.

Source code

cpp
/*
 * Copyright (C) 2014-2018 Olzhas Rakhimov
 * Copyright (C) 2023 OpenPRA ORG Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#pragma once

#include <vector>

#include "bdd.h"
#include "probability_analysis.h"
#include "settings.h"

namespace scram::mef {  // Decouple from the analysis code header.
class BasicEvent;
}  // namespace scram::mef

namespace scram::core {

struct ImportanceFactors {
  int occurrence;  
  double mif;  
  double cif;  
  double dif;  
  double raw;  
  double rrw;  
};

struct ImportanceRecord {
  const mef::BasicEvent& event;  
  const ImportanceFactors factors;  
};

class Zbdd;  // The container of products to be queries for important events.

class ImportanceAnalysis : public Analysis {
 public:
  explicit ImportanceAnalysis(const ProbabilityAnalysis* prob_analysis);

  virtual ~ImportanceAnalysis() = default;

  void Analyze() noexcept;

  const std::vector<ImportanceRecord>& importance() const {
    return importance_;
  }

 private:
  virtual double p_total() noexcept = 0;
  virtual const std::vector<const mef::BasicEvent*>&
  basic_events() noexcept = 0;
  virtual std::vector<int> occurrences() noexcept = 0;

  virtual double CalculateMif(int index) noexcept = 0;

  std::vector<ImportanceRecord> importance_;
};

class ImportanceAnalyzerBase : public ImportanceAnalysis {
 public:
  explicit ImportanceAnalyzerBase(ProbabilityAnalyzerBase* prob_analyzer)
      : ImportanceAnalysis(prob_analyzer), prob_analyzer_(prob_analyzer) {}

 protected:
  virtual ~ImportanceAnalyzerBase() = default;

  ProbabilityAnalyzerBase* prob_analyzer() { return prob_analyzer_; }

 private:
  double p_total() noexcept override { return prob_analyzer_->p_total(); }
  const std::vector<const mef::BasicEvent*>& basic_events() noexcept override {
    return prob_analyzer_->graph()->basic_events();
  }
  std::vector<int> occurrences() noexcept override;

  ProbabilityAnalyzerBase* prob_analyzer_;
};

template <class Calculator>
class ImportanceAnalyzer : public ImportanceAnalyzerBase {
 public:
  explicit ImportanceAnalyzer(ProbabilityAnalyzer<Calculator>* prob_analyzer)
      : ImportanceAnalyzerBase(prob_analyzer),
        p_vars_(prob_analyzer->p_vars()) {}

 private:
  double CalculateMif(int index) noexcept override;
  Pdag::IndexMap<double> p_vars_;  
};

template <class Calculator>
double ImportanceAnalyzer<Calculator>::CalculateMif(int index) noexcept {
  index += Pdag::kVariableStartIndex;
  auto p_conditional = [index, this](bool state) {
    p_vars_[index] = state;
    return static_cast<ProbabilityAnalyzer<Calculator>*>(prob_analyzer())
        ->CalculateTotalProbability(p_vars_);
  };
  double p_store = p_vars_[index];  // Save the original value for restoring.
  double mif = p_conditional(true) - p_conditional(false);
  p_vars_[index] = p_store;  // Restore the probability for next calculation.
  return mif;
}

template <>
class ImportanceAnalyzer<Bdd> : public ImportanceAnalyzerBase {
 public:
  explicit ImportanceAnalyzer(ProbabilityAnalyzer<Bdd>* prob_analyzer)
      : ImportanceAnalyzerBase(prob_analyzer),
        bdd_graph_(prob_analyzer->bdd_graph()) {}

 private:
  double CalculateMif(int index) noexcept override;

  double CalculateMif(const Bdd::VertexPtr& vertex, int order,
                      bool mark) noexcept;

  double RetrieveProbability(const Bdd::VertexPtr& vertex) noexcept;

  Bdd* bdd_graph_;  
};

}  // namespace scram::core

Updated on 2025-11-11 at 16:51:08 +0000