{-#LANGUAGE TemplateHaskell#-} {-#LANGUAGE QuasiQuotes#-} module Algebra.CAS.Diff where import Algebra.CAS.Base -- | Partial derivative -- -- >>> let [x,y] = map V ["x","y"] -- >>> diff (x*y) x -- y -- >>> diff (sin(x)*y) x -- y*(cos(x)) -- >>> diff (x^3) x -- 3*(x^2) diff :: Formula -> Formula -> Formula diff (V x') (V y') | x' == y' = C One | otherwise = C Zero diff (x :+: y) z = (diff x z) + (diff y z) diff (x :*: y) z = (diff x z) * y + x * (diff y z) diff (x :/: y) z = ((diff x z) * y - x * (diff y z)) / (y * y) diff (x :^: C One) z = diff x z diff (x :^: C (CI 1)) z = diff x z diff (x :^: C (CI 2)) z = 2 * x * (diff x z) diff (x :^: C (CI n)) z = (fromIntegral n) * (x ** (fromIntegral (n-1))) * (diff x z) diff (S (Sin x')) y' = (S (Cos x')) * (diff x' y') diff (S (Cos x')) y' = - ((S (Sin x')) * (diff x' y')) diff (S (Exp x')) y' = (S (Exp x')) * (diff x' y') diff a@(S (Tan x')) y' = ( a**2 + 1 )* (diff x' y') diff (C _) _ = C Zero diff Pi _ = C Zero diff (CV _) _ = C Zero diff (S (Log x')) y' = recip x' * diff x' y' diff a b = error $ "diff // can not parse : " ++ show a ++ " ## " ++ show b diffn :: Integer -> Formula -> Formula -> Formula diffn 0 a _ = a diffn 1 a b = diff a b diffn n a b | n < 0 = error $ "diffn can not do negative diff. n:" ++ show n | otherwise = diffn (n-1) (diff a b) b