[<<][meta][>>][..]
Thu Jan 13 08:57:14 EST 2011

Update equations

The basic functionality allows one to express difference/update
equations in state space form.  This should be general enough to allow
for further symbolic manipulation.

z x = a * x


From what I've learned in the past, it is usually better to express
structure in terms of type classes, instead of algebraic data types.
It seems always possible to write the ADT version as one
implementation of the interface, and write i.e. a code generator as
another one.

So the problem is then, what do the different symbols mean?  How to
mesh the concept of equation (constraint) with Haskell function
definitions?  Will it be possible to use the function-definition-style
above, or will it need ugly things like [1].

One problem with implicit definitions is that it is going to be hard
to write a full set of interpretations.  The conflict between on one
hand linear operations and z-transforms, and the other hand nonlinear
ones is already quite a limitation.

Let's rephrase: When using a typeclass interface, will we need
introspection to determine whether something falls in the linear or
nonlinear class?

Problems:

   - The '*' operator is typed (Num a) => a -> a -> a.  This means it
     can't distinguish between the nonlinear variable multiplication
     and the linear scaling operation.

     Moreover, we want to be able to express "parameterized linear"
     expressions, i.e. a knob-controlled low-pass filter.  One of the
     controls will have slow dynamics compared to the other one.

     Conclusion: when we write down an equation, we don't even know if
     it's linear or not.  It depends on the interpretation of the
     variables.


It seems that the simplest approach at least for the arithmetic
operators is to use the standard Num classes and encode the parameter
vs. stream information in an abstract type.

So that really only leaves Z, which is necessarily defined on a
stream.  Can it be eliminated?  Can we use lists of update functions
instead?  I.e. in the "z x = a * x" example, the representation could
be (x, a * x).

So, this leaves:

   * Variable declarations
   * Static Equations
   * Update equations

What form should they take?  Static equations can just be Haskell
equations in let expresssions.

Really, I see no other way than to use functions of the form
(S,I)->(S,O) where S,I,O are vectors.  Such a function then would be
the base of analysis.  If it is linear (which can be checked by
evaluating it over a specific data type) one can make a certain
analysis.  What remains is to find combinators for the functions.
This all seems relatively straightforward.

So where is the problem?  Combinators.  All the crap from the other
dataflow code shows up here again: 

  * NOTATION. Picking nodes and connecting them is a nontrivial
    problem wrt. notation.

  * SHARING. An essential problem in dataflow is to manage the sharing
    of data.  Using an implicit Num type class approach makes things
    more difficult as the sharing information is lost (it has a
    global, non-functional nature).


I suppose the notation problem requires some insight that can only
come through experimentation.  The sharing problem however is really
essential.  The core of question seems to be: "Can sharing be combined
with abstract Num classes?".  

I solve it in the Ai code through an equality relation (lacking object
identity).  Is there an other way?  It is my impression that I am
not seeing something that is right in front of my nose.

From what I read (Kiselyov et al.) there seem to be two ways to do
this: Monads in pure languages, and state & partial continuations in
impure languages, but some form of state to keep track of the
dependency graph and not just the values is essential.


[1] http://overtond.blogspot.com/2008/07/pre.html



[Reply][About]
[<<][meta][>>][..]