Struct bulwark_decision::Decision

source ·
pub struct Decision {
    pub accept: f64,
    pub restrict: f64,
    pub unknown: f64,
}
Expand description

A Decision represents evidence in favor of either accepting or restricting an operation under consideration.

It is composed of three values: accept, restrict and unknown. Each must be between 0.0 and 1.0 inclusive and the sum of all three must equal 1.0. The unknown value represents uncertainty about the evidence, with a 1.0 unknown value indicating total uncertainty or a “no opinion” verdict. Similarly, a 1.0 accept or restrict value indicates total certainty that the verdict should be to accept or to restrict, respectively.

This representation allows for a fairly intuitive way of characterizing evidence in favor of or against blocking an operation, while still capturing any uncertainty. Limiting to two states rather than a wider range of classification possibilities allows for better performance optimizations, simplifies code readability, and enables useful transformations like reweighting a Decision.

This data structure is a two-state Dempster-Shafer mass function, with the power set represented by the unknown value. This enables the use of combination rules to aggregate decisions from multiple sources. However, knowledge of Dempster-Shafer theory should not be necessary.

Fields§

§accept: f64§restrict: f64§unknown: f64

Implementations§

source§

impl Decision

source

pub fn accepted(accept: f64) -> Self

Converts a simple scalar value into a Decision using the value as the accept component.

This function is sugar for Decision { accept, 0.0, 0.0 }.scale()).

§Arguments
  • accept - The accept value to set.
§Examples
use approx::assert_relative_eq;
use bulwark_decision::Decision;

assert_relative_eq!(Decision::accepted(1.0), Decision { accept: 1.0, restrict: 0.0, unknown: 0.0 });
assert_relative_eq!(Decision::accepted(0.5), Decision { accept: 0.5, restrict: 0.0, unknown: 0.5 });
assert_relative_eq!(Decision::accepted(0.0), Decision { accept: 0.0, restrict: 0.0, unknown: 1.0 });
source

pub fn restricted(restrict: f64) -> Self

Converts a simple scalar value into a Decision using the value as the restrict component.

This function is sugar for Decision { 0.0, restrict, 0.0 }.scale()).

§Arguments
  • restrict - The restrict value to set.
§Examples
use approx::assert_relative_eq;
use bulwark_decision::Decision;

assert_relative_eq!(Decision::restricted(1.0), Decision { accept: 0.0, restrict: 1.0, unknown: 0.0 });
assert_relative_eq!(Decision::restricted(0.5), Decision { accept: 0.0, restrict: 0.5, unknown: 0.5 });
assert_relative_eq!(Decision::restricted(0.0), Decision { accept: 0.0, restrict: 0.0, unknown: 1.0 });
source

pub fn pignistic(&self) -> Self

Reassigns unknown mass evenly to accept and restrict.

This function is used to convert to a form that is useful in producing a final outcome.

source

pub fn is_accepted(&self, threshold: f64) -> bool

Checks the accept value after pignistic transformation against a threshold value. true if above the threshold.

§Arguments
  • threshold - The minimum value required to accept a Decision.
source

pub fn is_unknown(&self) -> bool

Checks that the unknown value is non-zero while accept and restrict are both zero.

source

pub fn outcome( &self, trust: f64, suspicious: f64, restrict: f64, ) -> Result<Outcome, ThresholdError>

Checks the restrict value after pignistic transformation against several threshold values.

The Outcomes are arranged in ascending order: Trusted < Accepted < Suspected < Restricted

Does not take an accept threshold to simplify validation. Returns ThresholdError if threshold values are either out-of-order or out-of-range. Thresholds must be between 0.0 and 1.0.

§Arguments
  • trust - The trust threshold is an upper-bound threshold. If the restrict value is below it, the operation is Trusted.
  • suspicious - The suspicious threshold is a lower-bound threshold that also defines the accepted range. If the restrict value is above the trust threshold and below the suspicious threshold, the operation is Accepted. If the restrict value is above the suspicious threshold but below the restrict threshold, the operation is Suspected.
  • restrict - The restricted threshold is a lower-bound threshold. If the restrict value is above it, the operation is Restricted.
source

pub fn clamp(&self) -> Self

Clamps all values to the 0.0 to 1.0 range.

Does not guarantee that values will sum to 1.0.

source

pub fn clamp_min_unknown(&self, min: f64) -> Self

Clamps all values to the 0.0 to 1.0 range, guaranteeing that the unknown value will be at least min.

Does not guarantee that values will sum to 1.0.

§Arguments
source

pub fn fill_unknown(&self) -> Self

If the component values sum to less than 1.0, assigns the remainder to the unknown value.

source

pub fn scale(&self) -> Self

Rescales a Decision to ensure all component values are in the 0.0-1.0 range and sum to 1.0.

It will preserve the relative relationship between accept and restrict.

source

pub fn scale_min_unknown(&self, min: f64) -> Self

Rescales a Decision to ensure all component values are in the 0.0-1.0 range and sum to 1.0 while ensuring that the unknown value is at least min.

It will preserve the relative relationship between accept and restrict.

§Arguments
source

pub fn weight(&self, factor: f64) -> Self

Multiplies the accept and restrict by the factor parameter, replacing the unknown value with the remainder.

Weights below 1.0 will reduce the weight of a Decision, while weights above 1.0 will increase it. A 1.0 weight has no effect on the result, aside from scaling it to a valid range if necessary.

§Arguments
  • factor - A scale factor used to multiply the accept and restrict values.
source

pub fn combine_conjunctive<'a, I>(decisions: I) -> Self
where Self: 'a, I: IntoIterator<Item = &'a Self>,

Calculates the conjunctive combination of a set of decisions, returning a new Decision as the result.

Unlike combine_murphy, combine_conjunctive will produce a NaN result under high conflict.

§Arguments
  • decisions - The Decisions to be combined.
source

pub fn combine_murphy<'a, I>(decisions: I) -> Self
where Self: 'a, I: IntoIterator<Item = &'a Self>,

Calculates the Murphy average of a set of decisions, returning a new Decision as the result.

The Murphy average rule1 takes the mean value of each focal element across all mass functions to create a new mass function. This new mass function is then combined conjunctively with itself N times where N is the total number of functions that were averaged together.

§Arguments
  • decisions - The Decisions to be combined.

  1. Catherine K. Murphy. 2000. Combining belief functions when evidence conflicts. Decision Support Systems 29, 1 (2000), 1-9. DOI:https://doi.org/10.1016/s0167-9236(99)00084-6 

source

pub fn conflict<'a, I>(decisions: I) -> f64
where Self: 'a, I: IntoIterator<Item = &'a Self>,

Calculates the degree of conflict between a set of Decisions.

§Arguments
  • decisions - The Decisions to measure conflict for.

Trait Implementations§

source§

impl AbsDiffEq for Decision

§

type Epsilon = <f64 as AbsDiffEq>::Epsilon

Used for specifying relative comparisons.
source§

fn default_epsilon() -> Self::Epsilon

The default tolerance to use when testing values that are close together. Read more
source§

fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool

A test for equality that uses the absolute difference to compute the approximate equality of two numbers.
source§

fn abs_diff_ne(&self, other: &Rhs, epsilon: Self::Epsilon) -> bool

The inverse of AbsDiffEq::abs_diff_eq.
source§

impl Clone for Decision

source§

fn clone(&self) -> Decision

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Decision

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Decision

source§

fn default() -> Self

The default Decision assigns nothing to the accept and restrict components and everything to the unknown component.

source§

impl PartialEq for Decision

source§

fn eq(&self, other: &Decision) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl RelativeEq for Decision

source§

fn default_max_relative() -> Self::Epsilon

The default relative tolerance for testing values that are far-apart. Read more
source§

fn relative_eq( &self, other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon, ) -> bool

A test for equality that uses a relative comparison if the values are far apart.
source§

fn relative_ne( &self, other: &Rhs, epsilon: Self::Epsilon, max_relative: Self::Epsilon, ) -> bool

The inverse of RelativeEq::relative_eq.
source§

impl UlpsEq for Decision

source§

fn default_max_ulps() -> u32

The default ULPs to tolerate when testing values that are far-apart. Read more
source§

fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool

A test for equality that uses units in the last place (ULP) if the values are far apart.
source§

fn ulps_ne(&self, other: &Rhs, epsilon: Self::Epsilon, max_ulps: u32) -> bool

The inverse of UlpsEq::ulps_eq.
source§

impl Validate for Decision

source§

impl<'v_a> ValidateArgs<'v_a> for Decision

§

type Args = ()

source§

fn validate_args(&self, args: Self::Args) -> Result<(), ValidationErrors>

source§

impl Copy for Decision

source§

impl StructuralPartialEq for Decision

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> CloneToUninit for T
where T: Copy,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
source§

impl<T> CloneToUninit for T
where T: Clone,

source§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.