diff --git a/README.md b/README.md index 1d56b19..01bdd1b 100644 --- a/README.md +++ b/README.md @@ -70,10 +70,13 @@ https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm Gauss-Legendre Quadrature approximates an integral over the interval $[-1, 1]$ by approximating the integral as a weighted sum of function evaluations of the nth Legendre polynomial roots, where larger $n$ results in more accurate -approximations. +approximations. See here for more info: +https://en.wikipedia.org/wiki/Gauss%E2%80%93Legendre_quadrature ### Monte-Carlo Integration Monte-Carlo integration refers to techniques which involve randomly sampling from the integration domain, computing the MLE for the expected value of the -function, and then multiplying this mean by the volume of the subset. \ No newline at end of file +function, and then multiplying this mean by the volume of the subset. See here +for more info: +https://en.wikipedia.org/wiki/Monte_Carlo_integration \ No newline at end of file diff --git a/integration/gaussQuad.m b/integration/gaussQuad.m index ca76e80..c317565 100644 --- a/integration/gaussQuad.m +++ b/integration/gaussQuad.m @@ -1,10 +1,10 @@ -function I = gaussQuad(y, a, b, n) +function I = gaussQuad(f, a, b, n) %{ - gaussQuad: This function evalues the integral of y over the bounds + GAUSSQUAD: This function evalues the integral of f over the bounds defined by a and b using n total nodes Parameters: - y: integrand + f: integrand a: lower bounds b: upper bounds n: number of nodes @@ -20,7 +20,7 @@ weights = 2./((1 - roots.^2).*(Pderiv(roots)).^2); % combine weights in multidimensional case - N = nargin(y); + N = nargin(f); all_weights = 1; for i = 1:N all_weights = kron(all_weights, weights); @@ -37,7 +37,7 @@ % evaluate integral diffs = 0.5*(b - a); - I = prod(diffs) .* sum(all_weights .* y(ntuples{:})'); + I = prod(diffs) .* sum(all_weights .* f(ntuples{:})'); end function C = cartesian(varargin) diff --git a/integration/monteCarloIntegral.m b/integration/monteCarloIntegral.m index 4bea83f..9efe5e3 100644 --- a/integration/monteCarloIntegral.m +++ b/integration/monteCarloIntegral.m @@ -1,6 +1,6 @@ function I = monteCarloIntegral(f, a, b, subset, n) %{ - monteCarloIntegral: This function evaluates the integral of f over + MONTECARLOINTEGRAL: This function evaluates the integral of f over the subset using the assumption that the function is enclosed within a rectangular region whose bounds are specified by a and b. A total of n points are sampled to calculate this integral. diff --git a/roots/finding_zeros.m b/roots/finding_zeros.m deleted file mode 100644 index 116bcaa..0000000 --- a/roots/finding_zeros.m +++ /dev/null @@ -1,67 +0,0 @@ -% function to find the zeros of -y = @(x) x^3-3*x-10; - -% examples with Newton-Raphson and Muller -disp("The root found by Newton-Raphson is x = " + ... - newtonRaphson(y, 1.1, eps)); -disp("The root found by Muller's method is x = " + ... - muller(y, -1, -2, -3)); -disp("The 3 roots of y are given by") -disp((find_zeros(y, 3))) - -% example of finding some of the roots for a transcendental expression -z = @(x) x * exp(x) - 10 * x^2; -disp("5 roots of the function z are") -disp((find_zeros(z, 5))) - -% function declarations -function r = newtonRaphson(y, x, threshold) - % calculate y'(x) numerically - deriv = @(x) (y(x + 1e-6) - y(x)) / 1e-6; - while abs(y(x)) > threshold - x = x - y(x)/deriv(x); - end - r = x; -end - -function r = muller(y, x1, x2, x3) - r = muller_rec(y, [x1; x2; x3]); -end - -function r = muller_rec(y, x) - % fit quadratic through three guesses - xmatrix = [(x - x(3)).^2, (x - x(3)), ones(3, 1)]; - yvalues = arrayfun(y, x); - coeff = xmatrix \ yvalues; - discrim = sqrt(coeff(2)^2 - 4 * coeff(1) * coeff(3)); - - % choose sign for denominator that maximizes its magnitude - if abs(coeff(2) + discrim) > abs(coeff(2) - discrim) - xnew = x(3) - 2 * coeff(3) / (coeff(2) + discrim); - else - xnew = x(3) - 2 * coeff(3) / (coeff(2) - discrim); - end - - % if the accuracy threshold is met, return, else recurse with new guess - if abs(y(xnew)) > 1e-5 - r = muller_rec(y, [x(2:3); xnew]); - else - r = xnew; - end -end - -function r = find_zeros(y, n) - r = find_zeros_rec(y, n, []); -end - -function r = find_zeros_rec(y, n, l) - % recursively find all roots - if n == 0 - r = l; - else - root = muller(y, -1.2382394234, 1.23042234, 0.09234234); - y1 = @(x) y(x)/(x - root); - l = [l; root]; - r = find_zeros_rec(y1, n - 1, l); - end -end \ No newline at end of file diff --git a/roots/muller.m b/roots/muller.m new file mode 100644 index 0000000..3cac4d9 --- /dev/null +++ b/roots/muller.m @@ -0,0 +1,39 @@ +function r = muller(y, x1, x2, x3, threshold) + %{ + MULLER: Computes single solution to equation using Muller's method + + Parameters: + y: Equation equal to zero + x1: First guess + x2: Second guess + x3: Third guess + threshold: Margin of error in function evaluation (how close to + zero does the evaluation have to be to stop recursing) + + Returns: + Root computed + %} + r = muller_rec(y, [x1; x2; x3], threshold); +end + +function r = muller_rec(y, x, threshold) + % fit quadratic through three guesses + xmatrix = [(x - x(3)).^2, (x - x(3)), ones(3, 1)]; + yvalues = arrayfun(y, x); + coeff = xmatrix \ yvalues; + discrim = sqrt(coeff(2)^2 - 4 * coeff(1) * coeff(3)); + + % choose sign for denominator that maximizes its magnitude + if abs(coeff(2) + discrim) > abs(coeff(2) - discrim) + xnew = x(3) - 2 * coeff(3) / (coeff(2) + discrim); + else + xnew = x(3) - 2 * coeff(3) / (coeff(2) - discrim); + end + + % if the accuracy threshold is met, return, else recurse with new guess + if abs(y(xnew)) > threshold + r = muller_rec(y, [x(2:3); xnew], threshold); + else + r = xnew; + end +end \ No newline at end of file diff --git a/roots/newtonRaphson.m b/roots/newtonRaphson.m new file mode 100644 index 0000000..6e8a043 --- /dev/null +++ b/roots/newtonRaphson.m @@ -0,0 +1,21 @@ +function r = newtonRaphson(y, x, threshold) + %{ + MULLER: Computes single solution to equation using Newton-Raphson + + Parameters: + y: Equation equal to zero + x: Initial guess + threshold: Margin of error in function evaluation (how close to + zero does the evaluation have to be to stop iterating) + + Returns: + Root computed + %} + + % calculate y'(x) numerically + deriv = @(x) (y(x + 1e-6) - y(x)) / 1e-6; + while abs(y(x)) > threshold + x = x - y(x)/deriv(x); + end + r = x; +end diff --git a/roots/roots.mlx b/roots/roots.mlx new file mode 100644 index 0000000..8f682e3 Binary files /dev/null and b/roots/roots.mlx differ diff --git a/roots/roots.pdf b/roots/roots.pdf new file mode 100644 index 0000000..ce2462c Binary files /dev/null and b/roots/roots.pdf differ