Program Listing for File Tran_Mat_Cell.hpp
↰ Return to documentation for file (lib/Tran_Mat_Cell.hpp
)
#pragma once
#include <iostream>
#include <numeric>
#include <map>
#include <vector>
#include "DiGraph.hpp"
class Tran_Mat_Cell {
private:
typedef std::multimap<std::pair<int, int>, double*>::iterator MMAPIterator;
// All the directed paths in the CAG that starts at source vertex and ends
// at target vertex decides the value of the transition matrix cell
// A[ 2 * source ][ 2 * target + 1 ]
int source;
int target;
// Records all the directed paths in the CAG that
// starts at source vertex and ends at target vertex.
// Each path informs how to calculate one product in the calculation of the
// value of this transition matrix cell, which is a sum of products.
// We multiply all the βs along a path to compute a product. Then we add all
// the products to compute the value of the cell.
// TODO: βs can be very small numbers. Multiplying a bunch of them could
// run into floating point underflow. Can we store log( β )s instead of
// βs and add them and then take the exp of the addition?
std::vector<std::vector<int>> paths;
// Keeps the value of each product. There is an entry for each path here.
// So, there is a 1-1 mapping between the two std::vectors paths and products.
std::vector<double> products;
// Maps each β to all the products where that β is a factor. This mapping
// is needed to quickly update the products and the cell value upon
// perturbing one β.
std::multimap<std::pair<int, int>, double*> beta2product;
public:
Tran_Mat_Cell(int source, int target);
// Add a path that starts with the start vertex and ends with the end vertex.
bool add_path(std::vector<int>& path);
// Allocates the product std::vector with the same length as the paths
// std::vector Populates the beta2product multimap linking each β (edge - A
// pair) to all the products that depend on it. This **MUST** be called after
// adding all the paths using add_path(). After populating the beta2product
// multimap, the length of the products std::vector **MUST NOT** be changed.
// If it is changes, we run into the danger of OS moving the products
// std::vector into a different location in memory and pointers kept in
// beta2product multimap becoming dangling pointer.
void allocate_datastructures();
// Computes the value of this cell from scratch.
// Should be called after adding all the paths using add_path()
// and calling allocate_datastructures()
double compute_cell(const DiGraph& CAG);
void print_products();
void print_beta2product();
// Given an edge (source, target vertex ids - a β=∂target/∂source),
// print all the products that are dependent on it.
void print(int source, int target);
void print_paths();
void get_paths_shorter_than_or_equal_to(int length, bool from_beginning);
std::unordered_set<int> get_vertices_within_hops(int hops,
bool from_beginning);
std::unordered_set<int>
get_vertices_on_paths_shorter_than_or_equal_to(int hops);
bool has_multiple_paths_longer_than_or_equal_to(int length);
};