X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2FIntegration%2FGaussian.hs;h=c2e4d5f684b7b5a97cb702b0a6049f88f3031b84;hb=b32831b5dde3440b85cbef62f4c47fcce0ee974f;hp=8fcca4f710d4fd918e061f475196ad3c9a2af1e5;hpb=6f237bfcd5890513cd390000c1ac8cdbdbaffb8c;p=numerical-analysis.git diff --git a/src/Integration/Gaussian.hs b/src/Integration/Gaussian.hs index 8fcca4f..c2e4d5f 100644 --- a/src/Integration/Gaussian.hs +++ b/src/Integration/Gaussian.hs @@ -24,15 +24,15 @@ import Linear.Matrix ( Col, Col10, Mat(..), - colzipwith, construct, + element_sum2, fromList, identity_matrix, - matmap, - row', - transpose ) + map2, + row, + transpose, + zipwith2 ) import Linear.QR ( eigenvectors_symmetric ) -import Normed ( Normed(..) ) -- | Compute the Jacobi matrix for the Legendre polynomials over @@ -102,14 +102,12 @@ nodes_and_weights :: forall m a. nodes_and_weights iterations = (nodes, weights) where - jac = jacobi_matrix - -- A shift is needed to make sure the QR algorithm -- converges. Since the roots (and thus eigenvalues) of orthogonal -- polynomials are real and distinct, there does exist a shift -- that will make it work. We guess lambda=1 makes it work. - shifted_jac = jac - identity_matrix + shifted_jac = jacobi_matrix - identity_matrix :: Mat (S m) (S m) a (shifted_nodes, vecs) = eigenvectors_symmetric iterations shifted_jac ones :: Col (S m) a @@ -119,11 +117,11 @@ nodes_and_weights iterations = nodes = shifted_nodes + ones -- unshift the nodes -- Get the first component of each column. - first_components = row' vecs 0 + first_components = row vecs 0 -- Square it and multiply by 2; see the Golub-Welsch paper for -- this magic. - weights_row = matmap (\x -> (fromInteger 2)*x^2) first_components + weights_row = map2 (\x -> (fromInteger 2)*x^2) first_components weights = transpose $ weights_row @@ -147,6 +145,7 @@ gaussian :: forall a. gaussian f = gaussian' f nodes weights where + coerce :: (ToRational.C b) => b -> a coerce = fromRational' . toRational nodes :: Col10 a @@ -187,9 +186,6 @@ gaussian f = -- type level so this function couldn't just compute e.g. @n@ of -- them for you). -- --- The class constraints on @a@ could be loosened significantly if --- we implemented column sum outside of the 1-norm. --- -- Examples: -- -- >>> import Linear.Matrix ( Col5 ) @@ -202,7 +198,7 @@ gaussian f = -- True -- gaussian' :: forall m a. - (Arity m, Absolute.C a, Algebraic.C a, ToRational.C a, Ring.C a) + (Arity m, ToRational.C a, Ring.C a) => (a -> a) -- ^ The function @f@ to integrate. -> Col (S m) a -- ^ Column matrix of nodes -> Col (S m) a -- ^ Column matrix of weights @@ -210,7 +206,7 @@ gaussian' :: forall m a. gaussian' f nodes weights = -- The one norm is just the sum of the entries, which is what we -- want. - norm_p (1::Int) weighted_values + element_sum2 weighted_values where - function_values = matmap f nodes - weighted_values = colzipwith (*) weights function_values + function_values = map2 f nodes + weighted_values = zipwith2 (*) weights function_values