Source code for qwak.ProbabilityDistribution

from __future__ import annotations
from typing import Union

import numpy as np
from qwak.State import State
from qwak.Errors import MissingNodeInput
import json
from utils.jsonTools import json_matrix_to_complex, complex_matrix_to_json
from functools import reduce


[docs] class ProbabilityDistribution: def __init__(self, state: State) -> None: """The dimension of the probability vector will then be loaded from the state inputted by the user. The vector containing the probabilities will be initialized full of zeros with the dimension obtained from the state. Parameters ---------- state : State State to be converted into a probability. """ self._state = state self._stateVec = self._state.getStateVec() self._n = state.getDim() self._probVec = np.zeros(self._n, dtype=float)
[docs] def resetProbDist(self) -> None: """Resets the ProbabilityDistribution object.""" self._stateVec = np.zeros((self._n, 1), dtype=complex) self._probVec = np.zeros(self._n, dtype=float)
[docs] def buildProbDist(self, state: State = None) -> None: """Builds the probability vector by multiplying the user inputted amplitude state by its conjugate. Parameters ---------- state : State, optional State to be converted into a probability, by default None """ if state is not None: self._n = state.getDim() self._state.setState(state) self._stateVec = self._state.getStateVec() self._probVec = np.array( [((state.item(0) * np.conj(state.item(0))).real) for state in self._stateVec])
[docs] def setProbDist(self, newProbDist: ProbabilityDistribution) -> None: """Sets the current probability distribution to a user inputted one. Parameters ---------- newProbDist : ProbabilityDistribution New probability distribution for the object. """ self._n = newProbDist.getDim() self._state.setState(newProbDist.getState()) self._stateVec = newProbDist.getStateVec() self._probVec = newProbDist.getProbVec()
[docs] def getStateVec(self) -> State: """Gets the state vector associated with a distribution. Returns ------- State Returns the state vector of the ProbabilityDistribution object. """ return self._stateVec
[docs] def getState(self) -> State: """Gets the state associated with a distribution. Returns ------- State Returns the state of the ProbabilityDistribution object. """ return self._state
[docs] def setState(self, newState: State) -> None: """Sets the current state to a user inputted one. Parameters ---------- newState : State New state for the distribution. """ self._state.setState(newState)
[docs] def setDim(self, newDim: int) -> None: """Sets the current dimension to a user inputted one. Parameters ---------- newDim : int New dimension for the distribution. """ self._n = newDim self._probVec = np.zeros(self._n, dtype=float)
[docs] def getDim(self) -> int: """Gets the dimension associated with a distribution. Returns ------- int Returns the dimension of the ProbabilityDistribution object. """ return self._n
[docs] def setProbVec(self, newProbVec: np.ndarray) -> None: """Sets the current probability vector to a user inputted one. Parameters ---------- newProbVec : np.ndarray New probability vector for the distribution. """ self._probVec = newProbVec
[docs] def getProbVec(self) -> np.ndarray: """Gets the probability vector associated with a distribution. Returns ------- np.ndarray Returns the array of the ProbabilityDistribution object. """ return self._probVec
def searchNodeProbability(self, searchNode: int) -> float: """Searches and gets the probability associated with a given node. Parameters ---------- searchNode : int User inputted node for the search. Returns ------- float Probability of the searched node. """ return self._probVec.item(searchNode)
[docs] def moment(self, k: int) -> float: """Calculates the kth moment of the probability distribution. Parameters ---------- k : int User inputted moment. Returns ------- float kth moment of the probability distribution. """ pos = np.arange(0, self._n) m = 0 for x in range(self._n): m += (pos[x] ** k) * self._probVec[x] return float(m)
[docs] def invPartRatio(self) -> float: """Calculates the inverse participation ratio of the probability distribution. Returns ------- float Inverse participation ratio of the probability distribution. """ return 1 / (np.sum(np.absolute(self._probVec)**2))
[docs] def stDev(self) -> float: """Calculates the standard deviation of the probability distribution. Returns ------- float Standard deviation of the probability distribution. """ stDev = self.moment(2) - self.moment(1) ** 2 return np.sqrt(stDev) if (stDev > 0) else 0
[docs] def survivalProb(self, fromNode, toNode) -> float: """Calculates the survival probability of the probability distribution. Parameters ---------- fromNode : _type_ Starting Node. toNode : _type_ Ending node. Returns ------- float Survival probability of the probability distribution. """ survProb = 0 try: if fromNode == toNode: return self._probVec[int(fromNode)][0] else: for i in range(int(fromNode), int(toNode) + 1): survProb += self._probVec[i] return survProb except ValueError: raise MissingNodeInput( f"A node number is missing: fromNode = {fromNode}; toNode={toNode}")
[docs] def searchNodeProbability(self, searchNode: int) -> float: """Searches and gets the probability associated with a given node. Parameters ---------- searchNode : int User inputted node for the search. Returns ------- float Probability of the searched node. """ return self._probVec.item(searchNode)
[docs] def to_json(self) -> str: """ Converts the ProbabilityDistribution object to a JSON string. Returns ------- str JSON string of the ProbabilityDistribution object. """ return json.dumps({ 'state': json.loads(self._state.to_json()), 'dim': self._n, 'prob_vec': self._probVec.tolist() })
[docs] @classmethod def from_json(cls, json_var: Union[str, dict]) -> ProbabilityDistribution: """Converts a JSON string to a ProbabilityDistribution object. Parameters ---------- json_var : Union[str, dict] JSON string or dictionary to be converted to a ProbabilityDistribution object. Returns ------- ProbabilityDistribution ProbabilityDistribution object converted from JSON. """ if isinstance(json_var, str): json_dict = json.loads(json_var) elif isinstance(json_var, dict): json_dict = json_var state = State.from_json(json_dict['state']) prob_vec = np.array(json_dict['prob_vec']) probDist = cls(state) probDist.setProbVec(prob_vec) return probDist
def __str__(self) -> str: """String representation of the ProbabilityDistribution object. Returns ------- str String of the ProbabilityDistribution object. """ return f"{self._probVec}" def __repr__(self) -> str: """Representation of the ProbabilityDistribution object. Returns ------- str String of the ProbabilityDistribution object. """ return f"N: {self._n}\n" \ f"State:\n\t{self._stateVec}\n" \ f"ProbDist:\n\t{self._probVec}"