compareIntegration ::
  forall x p n deg
  . (Vectorize x, Vectorize p, KnownNat n, KnownNat deg)
  => Proxy n -> Proxy deg
  -> DirCollOptions
  -> (forall a . Floating a => x a -> p a -> a -> x a)
  -> x Double -> p Double -> Double -> HUnit.Assertion
compareIntegration pn pdeg dirCollOpts ode x0 p tf = HUnit.assert $ do
  x' <- runIntegration pn pdeg dirCollOpts ode x0 p tf
  let xGsl = rk45 ode tf p x0

      ret :: HUnit.Assertion
      ret = case x' of
        Left err -> HUnit.assertString $ "failed with: " ++ show err
        Right x
          | worstErr <= 1e-6 -> HUnit.assert True
          | otherwise -> HUnit.assertString $ "insufficient accuracy: " ++ show worstErr
          where
            worstErr :: Double
            worstErr = V.maximum $ V.map abs $ vectorize $ x `minus` xGsl

  return ret :: IO HUnit.Assertion
compareIntegration ::
  forall x p n deg
  . (Vectorize x, Vectorize p, KnownNat n, KnownNat deg)
  => Proxy n -> Proxy deg
  -> DirCollOptions
  -> (forall a . Floating a => x a -> p a -> a -> x a)
  -> x Double -> p Double -> Double -> HUnit.Assertion
compareIntegration pn pdeg dirCollOpts ode x0 p tf = HUnit.assert $ do
  x' <- runIntegration pn pdeg dirCollOpts ode x0 p tf
  let xGsl = rk45 ode tf p x0

      ret :: HUnit.Assertion
      ret = case x' of
        Left err -> HUnit.assertString $ "failed with: " ++ show err
        Right x
          | worstErr <= 1e-6 -> HUnit.assert True
          | otherwise -> HUnit.assertString $ "insufficient accuracy: " ++ show worstErr
          where
            worstErr :: Double
            worstErr = V.maximum $ V.map abs $ vectorize $ x `minus` xGsl

  return ret :: IO HUnit.Assertion
compareIntegration pn pdeg dirCollOpts ode x0 p tf = HUnit.assert $ do
  x' <- runIntegration pn pdeg dirCollOpts ode x0 p tf
  let xGsl = rk45 ode tf p x0

      ret :: HUnit.Assertion
      ret = case x' of
        Left err -> HUnit.assertString $ "failed with: " ++ show err
        Right x
          | worstErr <= 1e-6 -> HUnit.assert True
          | otherwise -> HUnit.assertString $ "insufficient accuracy: " ++ show worstErr
          where
            worstErr :: Double
            worstErr = V.maximum $ V.map abs $ vectorize $ x `minus` xGsl

  return ret :: IO HUnit.Assertion