Repository navigation
feat[probability]: add conditional probability algorithm #3235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
ff3f45f
add conditional probability algorithm
SomrajBanik dc93726
Merge branch 'master' into master
realstealthninja 670a058
test: assert error messages, add new line at end of file, improve doc…
SomrajBanik 4d45631
Merge branch 'master' of https://github.com/SomrajBanik/C-Plus-Plus
SomrajBanik d48b50b
Apply self test comment
SomrajBanik 96769d1
docs: use proper latex syntax probability/conditional_probability.cpp
realstealthninja File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,162 @@ | ||
| /** | ||
| * @file | ||
| * @brief [Conditional | ||
| * Probability](https://en.wikipedia.org/wiki/Conditional_probability) | ||
| * @details | ||
| * In probability theory, conditional probability is a measure of the | ||
| * probability of an event occurring, given that another event (by assumption, | ||
| * presumption, assertion, or evidence) is already known to have occurred. | ||
| * | ||
| * This particular method relies on event A occurring with some sort of | ||
| * relationship with another event B. In this situation, the event A can be | ||
| * analyzed by a conditional probability with respect to B. | ||
| * | ||
| * If the event of interest is A and the event B is known or assumed to have | ||
| * occurred, "the conditional probability of A given B", or "the probability of | ||
| * A under the condition B" is given by the formula: | ||
| * | ||
| * \f[P(A \mid B) = \frac{P(A \cap B)}{P(B)}\f] | ||
| * where: \f$P(B) > 0\f$. | ||
| * | ||
| * | ||
| * @author [SomrajBanik](https://github.com/SomrajBanik) | ||
| */ | ||
|
|
||
| #include <cassert> /// for assert | ||
| #include <cmath> /// for std::fabs | ||
| #include <iostream> /// for IO operations | ||
| #include <stdexcept> /// for std::invalid_argument | ||
| #include <string> /// for std::string | ||
|
|
||
| /** | ||
| * @namespace probability | ||
| * @brief Probability algorithms | ||
| */ | ||
| namespace probability { | ||
| /** | ||
| * @namespace conditional_probability | ||
| * @brief Functions for the [Conditional | ||
| * Probability](https://en.wikipedia.org/wiki/Conditional_probability) algorithm | ||
| * implementation | ||
| */ | ||
| namespace conditional_probability { | ||
| /** | ||
| * @brief Computes the conditional probability P(X|Y) | ||
| * @param p_intersect probability that both X and Y occur, in [0, P(Y)] | ||
| * @param p_given probability of the event that is given (Y), in (0, 1] | ||
| * @returns P(X|Y) | ||
| * @throws std::invalid_argument if p_given is not in (0, 1], or if | ||
| * p_intersect is not in [0, p_given] | ||
| */ | ||
| double conditional_compute(double p_intersect, double p_given) { | ||
| if (p_given <= 0.0 || p_given > 1.0) { | ||
| throw std::invalid_argument("The given probability must be in (0, 1]."); | ||
| } | ||
| if (p_intersect < 0.0 || p_intersect > p_given) { | ||
| throw std::invalid_argument( | ||
| "P(intersection) must be between 0 and the given probability."); | ||
| } | ||
|
|
||
| return p_intersect / p_given; | ||
| } | ||
|
|
||
| } // namespace conditional_probability | ||
| } // namespace probability | ||
|
|
||
| /** | ||
| * @brief Self-test implementations | ||
| * @returns void | ||
| */ | ||
| static void test() { | ||
| using probability::conditional_probability::conditional_compute; | ||
|
|
||
| const double epsilon = 1e-9; /// tolerance for double comparison | ||
|
|
||
| std::cout << "\n\n"; | ||
| std::cout << "Testing conditional probability...\n\n"; | ||
|
|
||
| // Test case 1 | ||
| std::cout << "Test 1: P(A and B) = 0.2, P(B) = 0.5\n"; | ||
| std::cout << "Expected: P(A|B) = 0.4\n"; | ||
| std::cout << "Result: P(A|B) = " << conditional_compute(0.2, 0.5) << "\n"; | ||
| assert(std::fabs(conditional_compute(0.2, 0.5) - 0.4) < epsilon); | ||
| std::cout << "--PASSED--\n\n"; | ||
|
|
||
| // Test case 2 | ||
| std::cout << "Test 2: A always happens when B does (B is a subset of A)\n"; | ||
| std::cout << "Expected: P(A|B) = 1.0\n"; | ||
| std::cout << "Result: P(A|B) = " << conditional_compute(0.5, 0.5) << "\n"; | ||
| assert(std::fabs(conditional_compute(0.5, 0.5) - 1.0) < epsilon); | ||
| std::cout << "--PASSED--\n\n"; | ||
|
|
||
| // Test case 3 | ||
| std::cout << "Test 3: A and B never happen together (mutually exclusive " | ||
| "events)\n"; | ||
| std::cout << "Expected: P(A|B) = 0.0\n"; | ||
| std::cout << "Result: P(A|B) = " << conditional_compute(0.0, 0.3) << "\n"; | ||
| assert(std::fabs(conditional_compute(0.0, 0.3) - 0.0) < epsilon); | ||
| std::cout << "--PASSED--\n\n"; | ||
|
|
||
| // Test case 4 | ||
| std::cout << "Test 4: One die, A = 'roll is 2', B = 'roll is even'\n"; | ||
| std::cout << "Expected: P(A|B) = 1/3 or 0.333333(approx)\n"; | ||
| std::cout << "Result: P(A|B) = " | ||
| << conditional_compute(1.0 / 6.0, 1.0 / 2.0) << " (approx) " | ||
| << "\n"; | ||
| assert(std::fabs(conditional_compute(1.0 / 6.0, 1.0 / 2.0) - 1.0 / 3.0) < | ||
| epsilon); | ||
| std::cout << "--PASSED--\n\n"; | ||
|
|
||
| // Error handling test 1 (Test case 5) | ||
| std::cout << "Test 5: Error handling - P(B) = 0 (invalid)\n"; | ||
| bool thrown = false; | ||
| try { | ||
| conditional_compute(0.2, 0.0); | ||
| } catch (const std::invalid_argument &e) { | ||
| std::cout << "Error caught: " << e.what() << "\n"; | ||
| assert(std::string(e.what()) == | ||
| "The given probability must be in (0, 1]."); | ||
| thrown = true; | ||
| } | ||
| assert(thrown); | ||
| std::cout << "--PASSED--\n\n"; | ||
|
|
||
| // Error handling test 2 (Test case 6) | ||
| std::cout << "Test 6: Error handling - P(A and B) < 0 (invalid)\n"; | ||
| thrown = false; | ||
| try { | ||
| conditional_compute(-0.1, 0.5); | ||
| } catch (const std::invalid_argument &e) { | ||
| std::cout << "Error caught: " << e.what() << "\n"; | ||
| assert(std::string(e.what()) == | ||
| "P(intersection) must be between 0 and the given probability."); | ||
| thrown = true; | ||
| } | ||
| assert(thrown); | ||
| std::cout << "--PASSED--\n\n"; | ||
|
|
||
| // Error handling test 3 (Test case 7) | ||
| std::cout << "Test 7: Error handling - P(B) > 1 (invalid)\n"; | ||
| thrown = false; | ||
| try { | ||
| conditional_compute(0.2, 1.5); | ||
| } catch (const std::invalid_argument &e) { | ||
| std::cout << "Error caught: " << e.what() << "\n"; | ||
|
SomrajBanik marked this conversation as resolved.
|
||
| assert(std::string(e.what()) == | ||
| "The given probability must be in (0, 1]."); | ||
| thrown = true; | ||
| } | ||
| assert(thrown); | ||
| std::cout << "--PASSED--\n\n"; | ||
|
|
||
| std::cout << "All tests have successfully passed!\n"; | ||
| } | ||
|
|
||
| /** | ||
| * @brief Main function | ||
| * @returns 0 on exit | ||
| */ | ||
| int main() { | ||
| test(); // run self test implementations | ||
| return 0; | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.