{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TypeFamilies #-}
module Synthesizer.LLVM.Wave where

import qualified Synthesizer.LLVM.Value as Value

import qualified LLVM.Extra.Arithmetic as A

import LLVM.Core (CodeGenFunction)

import qualified Control.Monad.HT as M
import Control.Monad.HT ((<=<))

import NumericPrelude.Numeric
import NumericPrelude.Base hiding (replicate)



saw ::
   (A.PseudoRing a, A.IntegerConstant a) =>
   a -> CodeGenFunction r a
saw :: forall a r.
(PseudoRing a, IntegerConstant a) =>
a -> CodeGenFunction r a
saw =
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
1) (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
2)

square ::
   (A.PseudoRing a, A.IntegerConstant a, A.Fraction a) =>
   a -> CodeGenFunction r a
square :: forall a r.
(PseudoRing a, IntegerConstant a, Fraction a) =>
a -> CodeGenFunction r a
square =
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
1) (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
2) (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> CodeGenFunction r a
forall r. a -> CodeGenFunction r a
forall a r. Fraction a => a -> CodeGenFunction r a
A.truncate (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
2)

{- |
Discrete interpolation between triangle and square wave.
For exponent 1 we get a triangle wave.
The larger the exponent, the more we approach a square wave,
the.more computing is necessary.
-}
triangleSquarePower ::
   (A.PseudoRing a, A.RationalConstant a, A.Real a) =>
   Integer -> a -> CodeGenFunction r a
triangleSquarePower :: forall a r.
(PseudoRing a, RationalConstant a, Real a) =>
Integer -> a -> CodeGenFunction r a
triangleSquarePower Integer
n = (T a -> T a) -> forall r. a -> CodeGenFunction r (Registers (T a))
forall value a.
Flatten value =>
(T a -> value)
-> forall r. a -> CodeGenFunction r (Registers value)
Value.unlift1 ((T a -> T a)
 -> forall r. a -> CodeGenFunction r (Registers (T a)))
-> (T a -> T a)
-> forall r. a -> CodeGenFunction r (Registers (T a))
forall a b. (a -> b) -> a -> b
$ \T a
x ->
   let y :: T a
y = T a
2T a -> T a -> T a
forall a. C a => a -> a -> a
-T a
4T a -> T a -> T a
forall a. C a => a -> a -> a
*T a
x
       z :: T a
z = T a -> T a
forall a. C a => a -> a
abs (T a
1T a -> T a -> T a
forall a. C a => a -> a -> a
-T a -> T a
forall a. C a => a -> a
abs T a
y)
   in  (T a
1T a -> T a -> T a
forall a. C a => a -> a -> a
-T a
zT a -> Integer -> T a
forall a. C a => a -> Integer -> a
^Integer
n)T a -> T a -> T a
forall a. C a => a -> a -> a
*T a -> T a
forall a. C a => a -> a
signum T a
y

{- |
Continuous interpolation between triangle and square wave.
For factor 0 we get a square wave,
for factor 1 we get a triangle wave.
-}
triangleSquareRatio ::
   (A.Field a, A.RationalConstant a, A.Real a) =>
   a -> a -> CodeGenFunction r a
triangleSquareRatio :: forall a r.
(Field a, RationalConstant a, Real a) =>
a -> a -> CodeGenFunction r a
triangleSquareRatio = (T a -> T a -> T a)
-> forall r. a -> a -> CodeGenFunction r (Registers (T a))
forall value a b.
Flatten value =>
(T a -> T b -> value)
-> forall r. a -> b -> CodeGenFunction r (Registers value)
Value.unlift2 ((T a -> T a -> T a)
 -> forall r. a -> a -> CodeGenFunction r (Registers (T a)))
-> (T a -> T a -> T a)
-> forall r. a -> a -> CodeGenFunction r (Registers (T a))
forall a b. (a -> b) -> a -> b
$ \T a
c T a
x ->
   let y :: T a
y = T a
2T a -> T a -> T a
forall a. C a => a -> a -> a
-T a
4T a -> T a -> T a
forall a. C a => a -> a -> a
*T a
x
       z :: T a
z = T a -> T a
forall a. C a => a -> a
abs (T a
1T a -> T a -> T a
forall a. C a => a -> a -> a
-T a -> T a
forall a. C a => a -> a
abs T a
y)
   in  (T a
1T a -> T a -> T a
forall a. C a => a -> a -> a
-T a
z)T a -> T a -> T a
forall a. C a => a -> a -> a
/(T a
1T a -> T a -> T a
forall a. C a => a -> a -> a
+(T a
cT a -> T a -> T a
forall a. C a => a -> a -> a
-T a
1)T a -> T a -> T a
forall a. C a => a -> a -> a
*T a
z)T a -> T a -> T a
forall a. C a => a -> a -> a
*T a -> T a
forall a. C a => a -> a
signum T a
y

triangle ::
   (A.PseudoRing a, A.RationalConstant a, A.Fraction a) =>
   a -> CodeGenFunction r a
triangle :: forall a r.
(PseudoRing a, RationalConstant a, Fraction a) =>
a -> CodeGenFunction r a
triangle =
   (a -> a -> CodeGenFunction r a) -> a -> a -> CodeGenFunction r a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
1) (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> CodeGenFunction r a
forall r. a -> CodeGenFunction r a
forall a r. Real a => a -> CodeGenFunction r a
A.abs (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   (a -> a -> CodeGenFunction r a) -> a -> a -> CodeGenFunction r a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
2) (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
4) (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall a r. Fraction a => a -> a -> CodeGenFunction r a
A.incPhase (Rational -> a
forall a. RationalConstant a => Rational -> a
A.fromRational' Rational
0.75)

approxSine2 ::
   (A.PseudoRing a, A.IntegerConstant a, A.Fraction a) =>
   a -> CodeGenFunction r a
approxSine2 :: forall a r.
(PseudoRing a, IntegerConstant a, Fraction a) =>
a -> CodeGenFunction r a
approxSine2 a
t = do
   a
x <- a -> CodeGenFunction r a
forall a r.
(PseudoRing a, IntegerConstant a) =>
a -> CodeGenFunction r a
saw a
t
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
4) (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul a
x (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
1) (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> CodeGenFunction r a
forall r. a -> CodeGenFunction r a
forall a r. Real a => a -> CodeGenFunction r a
A.abs a
x

approxSine3 ::
   (A.PseudoRing a, A.RationalConstant a, A.Fraction a) =>
   a -> CodeGenFunction r a
approxSine3 :: forall a r.
(PseudoRing a, RationalConstant a, Fraction a) =>
a -> CodeGenFunction r a
approxSine3 a
t = do
   a
x <- a -> CodeGenFunction r a
forall a r.
(PseudoRing a, RationalConstant a, Fraction a) =>
a -> CodeGenFunction r a
triangle a
t
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul (Rational -> a
forall a. RationalConstant a => Rational -> a
A.fromRational' Rational
0.5) (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul a
x (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
3) (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul a
x a
x

approxSine4 ::
   (A.PseudoRing a, A.RationalConstant a, A.Real a) =>
   a -> CodeGenFunction r a
approxSine4 :: forall a r.
(PseudoRing a, RationalConstant a, Real a) =>
a -> CodeGenFunction r a
approxSine4 a
t = do
   a
x <- a -> CodeGenFunction r a
forall a r.
(PseudoRing a, IntegerConstant a) =>
a -> CodeGenFunction r a
saw a
t
   a
ax <- a -> CodeGenFunction r a
forall r. a -> CodeGenFunction r a
forall a r. Real a => a -> CodeGenFunction r a
A.abs a
x
   a
sax <- a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
1) a
ax
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul (Rational -> a
forall a. RationalConstant a => Rational -> a
A.fromRational' (Rational
16Rational -> Rational -> Rational
forall a. C a => a -> a -> a
/Rational
5)) (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul a
x (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul a
sax (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.add (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
1) (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul a
sax a
ax

{- |
For the distortion factor @recip pi@ you get the closest approximation
to an undistorted cosine or sine.
We have chosen this scaling in order to stay with field operations.
-}
rationalApproxCosine1, rationalApproxSine1 ::
   (A.Field a, A.RationalConstant a, A.Real a) =>
   a -> a -> CodeGenFunction r a
rationalApproxCosine1 :: forall a r.
(Field a, RationalConstant a, Real a) =>
a -> a -> CodeGenFunction r a
rationalApproxCosine1 a
k a
t = do
   a
num2 <-
      a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> CodeGenFunction r a
A.square (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul a
k (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.add (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' (-Integer
1)) (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
2) a
t
   a
den2 <-
      a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> CodeGenFunction r a
A.square (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul a
t (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
1) a
t
   (a -> a -> CodeGenFunction r a)
-> CodeGenFunction r a
-> CodeGenFunction r a
-> CodeGenFunction r a
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> m c) -> m a -> m b -> m c
M.liftJoin2 a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Field a => a -> a -> CodeGenFunction r a
A.fdiv
      (a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub a
num2 a
den2)
      (a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.add a
num2 a
den2)

rationalApproxSine1 :: forall a r.
(Field a, RationalConstant a, Real a) =>
a -> a -> CodeGenFunction r a
rationalApproxSine1 a
k a
t = do
   a
num <-
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul a
k (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.add (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' (-Integer
1)) (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
2) a
t
   a
den <-
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul a
t (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
      a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
1) a
t
   (a -> a -> CodeGenFunction r a)
-> CodeGenFunction r a
-> CodeGenFunction r a
-> CodeGenFunction r a
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> m c) -> m a -> m b -> m c
M.liftJoin2 a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Field a => a -> a -> CodeGenFunction r a
A.fdiv
      (a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' (-Integer
2)) (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul a
num a
den)
      ((a -> a -> CodeGenFunction r a)
-> CodeGenFunction r a
-> CodeGenFunction r a
-> CodeGenFunction r a
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> m c) -> m a -> m b -> m c
M.liftJoin2 a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.add (a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> CodeGenFunction r a
A.square a
num) (a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> CodeGenFunction r a
A.square a
den))


trapezoidSkew ::
   (A.Field a, A.RationalConstant a, A.Real a) =>
   a -> a -> CodeGenFunction r a
trapezoidSkew :: forall a r.
(Field a, RationalConstant a, Real a) =>
a -> a -> CodeGenFunction r a
trapezoidSkew a
p =
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Real a => a -> a -> CodeGenFunction r a
A.max (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' (-Integer
1)) (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Real a => a -> a -> CodeGenFunction r a
A.min (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
1) (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   (a -> a -> CodeGenFunction r a) -> a -> a -> CodeGenFunction r a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Field a => a -> a -> CodeGenFunction r a
A.fdiv a
p (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
1) (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
2)

{- |
> trapezoidSlope steepness = trapezoidSkew (recip steepness)
-}
trapezoidSlope ::
   (A.PseudoRing a, A.RationalConstant a, A.Real a) =>
   a -> a -> CodeGenFunction r a
trapezoidSlope :: forall a r.
(PseudoRing a, RationalConstant a, Real a) =>
a -> a -> CodeGenFunction r a
trapezoidSlope a
p =
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Real a => a -> a -> CodeGenFunction r a
A.max (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' (-Integer
1)) (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Real a => a -> a -> CodeGenFunction r a
A.min (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
1) (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul a
p (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
1) (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul (Integer -> a
forall a. IntegerConstant a => Integer -> a
A.fromInteger' Integer
2)

sine ::
   (A.Transcendental a, A.RationalConstant a) =>
   a -> CodeGenFunction r a
sine :: forall a r.
(Transcendental a, RationalConstant a) =>
a -> CodeGenFunction r a
sine a
t =
   a -> CodeGenFunction r a
forall r. a -> CodeGenFunction r a
forall a r. Transcendental a => a -> CodeGenFunction r a
A.sin (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul a
t (a -> CodeGenFunction r a)
-> CodeGenFunction r a -> CodeGenFunction r a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< T a -> forall r. CodeGenFunction r a
forall a. T a -> forall r. CodeGenFunction r a
Value.decons T a
forall a. (Transcendental a, RationalConstant a) => T a
Value.tau



{- |
This can be used for preprocessing the phase
in order to generate locally faster oscillating waves.
For example

> triangle <=< replicate (valueOf 2.5)

shrinks a triangle wave such that 2.5 periods fit into one.
-}
replicate ::
   (A.PseudoRing a, A.RationalConstant a, A.Fraction a) =>
   a -> a -> CodeGenFunction r a
replicate :: forall a r.
(PseudoRing a, RationalConstant a, Fraction a) =>
a -> a -> CodeGenFunction r a
replicate a
k =
   a -> CodeGenFunction r a
forall r. a -> CodeGenFunction r a
forall a r. Fraction a => a -> CodeGenFunction r a
A.fraction (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul a
k (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   (a -> a -> CodeGenFunction r a) -> a -> a -> CodeGenFunction r a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. Additive a => a -> a -> CodeGenFunction r a
A.sub (Rational -> a
forall a. RationalConstant a => Rational -> a
A.fromRational' Rational
0.5) (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall a r. Fraction a => a -> a -> CodeGenFunction r a
A.incPhase (Rational -> a
forall a. RationalConstant a => Rational -> a
A.fromRational' Rational
0.5)

{- |
Preprocess the phase such that the first half of a wave
is expanded to one period and shifted by 90 degree.
E.g.

> sine <=< halfEnvelope

generates a sequence of sine bows that starts and ends with the maximum.
Such a signal can be used to envelope an oscillation
generated using 'replicate'.
-}
halfEnvelope ::
   (A.PseudoRing a, A.RationalConstant a, A.Fraction a) =>
   a -> CodeGenFunction r a
halfEnvelope :: forall a r.
(PseudoRing a, RationalConstant a, Fraction a) =>
a -> CodeGenFunction r a
halfEnvelope =
   a -> a -> CodeGenFunction r a
forall r. a -> a -> CodeGenFunction r a
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul (Rational -> a
forall a. RationalConstant a => Rational -> a
A.fromRational' Rational
0.5) (a -> CodeGenFunction r a)
-> (a -> CodeGenFunction r a) -> a -> CodeGenFunction r a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=<
   a -> a -> CodeGenFunction r a
forall a r. Fraction a => a -> a -> CodeGenFunction r a
A.incPhase (Rational -> a
forall a. RationalConstant a => Rational -> a
A.fromRational' Rational
0.5)

partial ::
   (A.Fraction v, A.PseudoRing v, A.IntegerConstant v) =>
   (v -> CodeGenFunction r v) ->
   Int ->
   (v -> CodeGenFunction r v)
partial :: forall v r.
(Fraction v, PseudoRing v, IntegerConstant v) =>
(v -> CodeGenFunction r v) -> Int -> v -> CodeGenFunction r v
partial v -> CodeGenFunction r v
w Int
n v
t =
   v -> CodeGenFunction r v
w (v -> CodeGenFunction r v)
-> CodeGenFunction r v -> CodeGenFunction r v
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
   v -> CodeGenFunction r v
forall a r. Fraction a => a -> CodeGenFunction r a
A.signedFraction (v -> CodeGenFunction r v)
-> CodeGenFunction r v -> CodeGenFunction r v
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
   v -> v -> CodeGenFunction r v
forall r. v -> v -> CodeGenFunction r v
forall a r. PseudoRing a => a -> a -> CodeGenFunction r a
A.mul v
t (Integer -> v
forall a. IntegerConstant a => Integer -> a
A.fromInteger' (Int -> Integer
forall a b. (C a, C b) => a -> b
fromIntegral Int
n))