-
-
Notifications
You must be signed in to change notification settings - Fork 342
Add- simpson's rule #246
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
Add- simpson's rule #246
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
265ee4f
Add- simpson's rule
Erennn7 5852147
Update mathematics/simpson_rule.r
Erennn7 1817c7e
Update mathematics/simpson_rule.r
Erennn7 1d2ca15
Update mathematics/simpson_rule.r
Erennn7 3d1d182
Merge branch 'master' into Add_simpson_rule
siriak 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,231 @@ | ||
| # Simpson's Rule for Numerical Integration | ||
| # | ||
| # Simpson's Rule is a method for numerical integration that approximates | ||
| # the definite integral of a function using quadratic polynomials. | ||
| # It provides better accuracy than the trapezoidal rule by using parabolic | ||
| # arcs instead of straight line segments. | ||
| # | ||
| # Time Complexity: O(n) where n is the number of subintervals | ||
| # Space Complexity: O(n) for storing the x values | ||
| # | ||
| # Applications: | ||
| # - Numerical integration in scientific computing | ||
| # - Physics and engineering calculations | ||
| # - Signal processing and data analysis | ||
| # - Probability and statistics (computing areas under curves) | ||
| # - Computer graphics and visualization | ||
| # | ||
| # Formula: ∫[a,b] f(x)dx ≈ (h/3)[f(x₀) + 4f(x₁) + 2f(x₂) + 4f(x₃) + ... + f(xₙ)] | ||
| # where h = (b-a)/n and n must be even | ||
|
|
||
| simpson_rule <- function(f, a, b, n) { | ||
| #' Approximate the definite integral of f(x) from a to b using Simpson's Rule | ||
| #' @param f: Function to integrate | ||
| #' @param a: Lower limit of integration (numeric) | ||
| #' @param b: Upper limit of integration (numeric) | ||
| #' @param n: Number of subintervals (must be even) | ||
| #' @return: Approximation of the integral (numeric) | ||
| #' @details Simpson's Rule uses parabolic approximations to estimate the | ||
| #' area under a curve. The interval [a,b] is divided into n | ||
| #' subintervals, and quadratic interpolation is applied. | ||
| #' @references https://en.wikipedia.org/wiki/Simpson%27s_rule | ||
|
|
||
| # Validate that n is even | ||
| if (n %% 2 != 0) { | ||
| stop("Error: Number of subintervals n must be even for Simpson's Rule.") | ||
| } | ||
|
|
||
| # Validate inputs | ||
| if (!is.numeric(a) || !is.numeric(b) || !is.numeric(n)) { | ||
| stop("Error: a, b, and n must be numeric values.") | ||
| } | ||
|
|
||
| if (n <= 0) { | ||
| stop("Error: Number of subintervals n must be positive.") | ||
| } | ||
|
|
||
| if (a >= b) { | ||
| stop("Error: Lower limit a must be less than upper limit b.") | ||
| } | ||
|
|
||
| # Calculate step size | ||
| h <- (b - a) / n | ||
|
|
||
| # Generate x values | ||
| x <- seq(a, b, by = h) | ||
|
|
||
| # Initialize result with endpoints | ||
| result <- f(x[1]) + f(x[n + 1]) | ||
|
|
||
| # Apply Simpson's coefficients | ||
| # Odd indices (i = 3, 5, 7, ...) get coefficient 4 | ||
| # Even indices (i = 2, 4, 6, ...) get coefficient 2 | ||
| for (i in 2:n) { | ||
| if (i %% 2 != 0) { | ||
| # Odd index: multiply by 4 | ||
| result <- result + 4 * f(x[i]) | ||
| } else { | ||
| # Even index: multiply by 2 | ||
| result <- result + 2 * f(x[i]) | ||
| } | ||
| } | ||
|
|
||
| # Multiply by h/3 | ||
| result <- result * h / 3 | ||
|
|
||
| return(result) | ||
| } | ||
|
|
||
| # Vectorized version for better performance | ||
| simpson_rule_vectorized <- function(f, a, b, n) { | ||
| #' Vectorized implementation of Simpson's Rule | ||
| #' @param f: Function to integrate (must support vectorized input) | ||
| #' @param a: Lower limit of integration | ||
| #' @param b: Upper limit of integration | ||
| #' @param n: Number of subintervals (must be even) | ||
| #' @return: Approximation of the integral | ||
|
|
||
| if (n %% 2 != 0) { | ||
| stop("Error: Number of subintervals n must be even.") | ||
| } | ||
|
|
||
| h <- (b - a) / n | ||
| x <- seq(a, b, by = h) | ||
| y <- f(x) | ||
|
|
||
| # Create coefficient vector: [1, 4, 2, 4, 2, ..., 2, 4, 1] | ||
| coefficients <- rep(2, n + 1) | ||
| coefficients[1] <- 1 | ||
| coefficients[n + 1] <- 1 | ||
| coefficients[seq(2, n, by = 2)] <- 4 | ||
|
|
||
| result <- sum(coefficients * y) * h / 3 | ||
| return(result) | ||
| } | ||
|
|
||
| # Helper function to print integration results | ||
| print_integration_result <- function(f, a, b, n, result, exact = NULL) { | ||
| #' Print formatted integration results | ||
| #' @param f: Function that was integrated | ||
| #' @param a: Lower limit | ||
| #' @param b: Upper limit | ||
| #' @param n: Number of subintervals | ||
| #' @param result: Computed integral value | ||
| #' @param exact: Exact value if known (optional) | ||
|
|
||
| cat("Simpson's Rule Integration:\n") | ||
| cat(sprintf(" Interval: [%.4f, %.4f]\n", a, b)) | ||
| cat(sprintf(" Subintervals: %d\n", n)) | ||
| cat(sprintf(" Approximate integral: %.10f\n", result)) | ||
|
|
||
| if (!is.null(exact)) { | ||
| error <- abs(result - exact) | ||
| rel_error <- error / abs(exact) * 100 | ||
| cat(sprintf(" Exact value: %.10f\n", exact)) | ||
| cat(sprintf(" Absolute error: %.2e\n", error)) | ||
| cat(sprintf(" Relative error: %.4f%%\n", rel_error)) | ||
| } | ||
| cat("\n") | ||
| } | ||
|
|
||
| # ========== Example Usage ========== | ||
|
|
||
| cat("========== Example 1: Integral of sin(x) from 0 to π ==========\n\n") | ||
|
|
||
| # Define the function to integrate | ||
| func1 <- function(x) sin(x) | ||
|
|
||
| # Integration limits | ||
| a1 <- 0 | ||
| b1 <- pi | ||
|
|
||
| # Number of subintervals (must be even) | ||
| n1 <- 10 | ||
|
|
||
| # Calculate integral | ||
| integral1 <- simpson_rule(func1, a1, b1, n1) | ||
| exact1 <- 2.0 # Exact value of ∫sin(x)dx from 0 to π is 2 | ||
|
|
||
| print_integration_result(func1, a1, b1, n1, integral1, exact1) | ||
|
|
||
| # ========== Example 2: Integral of x² from 0 to 1 ========== | ||
|
|
||
| cat("========== Example 2: Integral of x² from 0 to 1 ==========\n\n") | ||
|
|
||
| func2 <- function(x) x^2 | ||
| a2 <- 0 | ||
| b2 <- 1 | ||
| n2 <- 20 | ||
|
|
||
| integral2 <- simpson_rule(func2, a2, b2, n2) | ||
| exact2 <- 1/3 # Exact value is 1/3 | ||
|
|
||
| print_integration_result(func2, a2, b2, n2, integral2, exact2) | ||
|
|
||
| # ========== Example 3: Integral of e^x from 0 to 1 ========== | ||
|
|
||
| cat("========== Example 3: Integral of e^x from 0 to 1 ==========\n\n") | ||
|
|
||
| func3 <- function(x) exp(x) | ||
| a3 <- 0 | ||
| b3 <- 1 | ||
| n3 <- 10 | ||
|
|
||
| integral3 <- simpson_rule(func3, a3, b3, n3) | ||
| exact3 <- exp(1) - 1 # Exact value is e - 1 | ||
|
|
||
| print_integration_result(func3, a3, b3, n3, integral3, exact3) | ||
|
|
||
| # ========== Example 4: Comparison with different n values ========== | ||
|
|
||
| cat("========== Example 4: Convergence study for sin(x) ==========\n\n") | ||
|
|
||
| n_values <- c(10, 20, 50, 100, 200) | ||
| cat("Convergence of Simpson's Rule with increasing subintervals:\n") | ||
| cat(sprintf("%-15s %-20s %-15s\n", "Subintervals", "Approximate", "Error")) | ||
| cat(strrep("-", 50), "\n") | ||
|
|
||
| for (n in n_values) { | ||
| result <- simpson_rule(sin, 0, pi, n) | ||
| error <- abs(result - 2.0) | ||
| cat(sprintf("%-15d %-20.12f %.4e\n", n, result, error)) | ||
| } | ||
| cat("\n") | ||
|
|
||
| # ========== Example 5: Using vectorized version ========== | ||
|
|
||
| cat("========== Example 5: Vectorized implementation ==========\n\n") | ||
|
|
||
| func5 <- function(x) 1 / (1 + x^2) # Arctangent derivative | ||
| a5 <- 0 | ||
| b5 <- 1 | ||
| n5 <- 100 | ||
|
|
||
| integral5 <- simpson_rule_vectorized(func5, a5, b5, n5) | ||
| exact5 <- pi / 4 # ∫[0,1] 1/(1+x²)dx = arctan(1) - arctan(0) = π/4 | ||
|
|
||
| print_integration_result(func5, a5, b5, n5, integral5, exact5) | ||
|
|
||
| # ========== Example 6: Gaussian function ========== | ||
|
|
||
| cat("========== Example 6: Gaussian (Normal) distribution PDF ==========\n\n") | ||
|
|
||
| # Standard normal distribution PDF from -3 to 3 | ||
| gaussian <- function(x) (1 / sqrt(2 * pi)) * exp(-x^2 / 2) | ||
| a6 <- -3 | ||
| b6 <- 3 | ||
| n6 <- 100 | ||
|
|
||
| integral6 <- simpson_rule(gaussian, a6, b6, n6) | ||
| # Exact value is approximately 0.9973 (99.73% within 3 standard deviations) | ||
|
|
||
| cat(sprintf("Integral of standard normal PDF from %.1f to %.1f: %.6f\n", a6, b6, integral6)) | ||
| cat(sprintf("This represents %.2f%% of the total area under the curve.\n\n", integral6 * 100)) | ||
|
|
||
| # ========== Notes ========== | ||
| cat("========== Important Notes ==========\n") | ||
| cat("1. Simpson's Rule requires an EVEN number of subintervals.\n") | ||
| cat("2. It provides O(h⁴) accuracy (fourth-order accurate).\n") | ||
| cat("3. More accurate than Trapezoidal Rule for smooth functions.\n") | ||
| cat("4. Works best for continuous, smooth functions.\n") | ||
| cat("5. For higher accuracy, increase the number of subintervals.\n") | ||
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.