grame-cncm / faustlibraries

The Faust libraries
https://faustlibraries.grame.fr
183 stars 59 forks source link

N dimensional tabulate #151

Closed magnetophon closed 1 year ago

magnetophon commented 1 year ago

I made an N dimensional tabulate. The code is in quite rough shape at the moment, but it works. It can do val,lin and cub, with any number of parameters for the function to tabulate. All the values are stored in one big table with the size being the product of the individual sizes.

Usage example:

process =
    tabulateNd(2,0,twoDfunction,sizeX,sizeY,rx0,ry0,rx1,ry1,x,y)
  , twoDfunction(x,y);

So it's: dimension ,C , expression, sizes, start values, end values, parameters.

I'd like to contribute it to the libraries. Apart from general cleanup, any suggestions? I doubt I can get it in a state where it will be easily understandable. Once https://github.com/grame-cncm/faust/issues/890 is resolved, I can make the code a bit more elegant.

Here's a permalink to the code in it's current state: https://github.com/magnetophon/lamb/blob/bbce0d505c7788282f7de827ba678f50de20bca6/lamb.dsp#L16

josmithiii commented 1 year ago

Hi Bart,

This sounds great, and extremely useful! Thanks!

How about interpolators.lib ? It already has interpolated 1D tables (frdtable, frwtable, and of course other interpolated things).

Cheers, Julius

On Wed, May 3, 2023 at 2:11 PM Bart Brouns @.***> wrote:

I made an N dimensional tabulate. The code is in quite rough shape at the moment, but it works. It can do val,lin and cub, with any number of parameters for the function to tabulate. All the values are stored in one big table with the size being the product of the individual sizes.

Usage example:

process = tabulateNd(2,0,twoDfunction,sizeX,sizeY,rx0,ry0,rx1,ry1,x,y) , twoDfunction(x,y);

So it's: dimension ,C , expression, sizes, start values, end values, parameters.

I'd like to contribute it to the libraries. Apart from general cleanup, any suggestions? I doubt I can get it in a state where it will be easily understandable. Once grame-cncm/faust#890 https://github.com/grame-cncm/faust/issues/890 is resolved, I can make the code a bit more elegant.

Here's a permalink to the code in it's current state:

https://github.com/magnetophon/lamb/blob/bbce0d505c7788282f7de827ba678f50de20bca6/lamb.dsp#L16

— Reply to this email directly, view it on GitHub https://github.com/grame-cncm/faustlibraries/issues/151, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQZKFNBM2NW2LQHM3QHXCTXELCZ7ANCNFSM6AAAAAAXU6EKXM . You are receiving this because you are subscribed to this thread.Message ID: @.***>

-- Julius O. Smith III @.***> Professor Emeritus of Music and by courtesy Electrical Engineering CCRMA, Stanford University http://ccrma.stanford.edu/~jos/

magnetophon commented 1 year ago

I assumed it was going into basics.lib, since that is where tabulator lives, but I don't really care where it ends up.

josmithiii commented 1 year ago

Ok, I didn't know that, so I withdraw my suggestion. Stéphane, what do you think?

On Wed, May 3, 2023 at 3:23 PM Bart Brouns @.***> wrote:

I assumed it was going into basics.lib, since that is where tabulator lives, but I don't really care where it ends up.

— Reply to this email directly, view it on GitHub https://github.com/grame-cncm/faustlibraries/issues/151#issuecomment-1533830402, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQZKFIT5H44D4OYYPC6JYTXELLHDANCNFSM6AAAAAAXU6EKXM . You are receiving this because you commented.Message ID: @.***>

-- Julius O. Smith III @.***> Professor Emeritus of Music and by courtesy Electrical Engineering CCRMA, Stanford University http://ccrma.stanford.edu/~jos/

sletz commented 1 year ago

@josmithiii you actually helped improve the documentation of tabulate and tabulate_chebychev ((-; @magnetophon better add the new tabulateNd in basics.lib and as always better have the cleanest and simplest code that can be written..

magnetophon commented 1 year ago

Currently, the code has (simplified):

process = tabulateNd(params);
tabulateNd(params) =
  calc.lin
with {
  calc =
    environment {
// do the work here
  };
};

When I change it to:

process = tabulateNd(params).lin;
tabulateNd(params) =
  environment {
// do the work here
};

I get: maths.lib : -1 : ERROR : an environment can't be used as a function : closure[environment, genv = {}, lenv = {}].

What does that error mean?

Here is the actual code change: https://github.com/magnetophon/lamb/compare/master...broken

magnetophon commented 1 year ago

I cleaned up the code as far as I could: https://github.com/magnetophon/lamb/blob/eb7c4baabcbf6bb7de5b278811a9b7ae79328122/lamb.dsp#L23-L192 but I still need to get rid of the with mentioned in the above comment.

magnetophon commented 1 year ago

I found a minimal example to reproduce the error:

env = environment {
        part=1+_;
        };

process =
  env(1).part;

I would expect this to output 2. Instead, I get:

lamb.dsp : -1 : ERROR : an environment can't be used as a function : closure[environment, genv = {}, lenv = {}]

Is that a bug or a feature? ;)

This works, but is not applicable to tabulateNd, since the number of parameters should be variable:

env(x) = environment {
        part=1+x;
        };

process =
  env(1).part;
sletz commented 1 year ago

How can the message be more clear ? With the first env(1) syntax you are using the environment as if it where a function, which is not. In the second way env(x), the x parameter is usable in the environment {...} scope.

magnetophon commented 1 year ago

Why can you not use an environment as if it's a function? Does it help the faust user? If yes, how? If no, is it possible to change?

sletz commented 1 year ago

Read: https://faustdoc.grame.fr/manual/syntax/#environment-expressions and https://faustdoc.grame.fr/manual/syntax/#environment-expression

magnetophon commented 1 year ago

I'm sorry, most of that goes over my head. Or, to put it in another way: "I know some of those words!" :rofl:

Faust is a lexically scoped language. The meaning of a Faust expression is determined by its context of definition (its lexical environment) and not by its context of use.

What is lexically scoped? What is meant by "context of definition" and "context of use"? What is a lexical environment?

To keep their original meaning,

What do you mean by an expression "keeping it's meaning"?

Faust expressions are bounded to their lexical environment in structures called closures.

What is bounded? What is a closure?

In any case, I don't think the manual explains why you cannot use an environment as if it's a function. Would it be possible and/or desirable to change the compiler to allow that?

sletz commented 1 year ago

Try to Google that first, like: https://www.techtarget.com/whatis/definition/lexical-scoping-static-scoping#:~:text=Lexical%20scoping%2C%20also%20known%20as,in%20which%20it%20is%20defined. https://en.wikipedia.org/wiki/Closure_(computer_programming)#:~:text=In%20programming%20languages%2C%20a%20closure,function%20together%20with%20an%20environment.

sletz commented 1 year ago

An environment contains a collections of definitions, some of them can be functions:

magnetophon commented 1 year ago

Thanks. I understand how it works and what the constraints are, more or less. The manual explains that you cannot use an environment as if it's a function.

What I would like to know: does it have to be this way? Would it be possible and/or desirable to change the compiler to allow that?

Sorry for repeating the question, but you seem to miss it every time.

sletz commented 1 year ago

We cannot do that: what is the need ?

magnetophon commented 1 year ago

The need is cases like mine: You have a couple of related functions, in this case val, lin and cub, that need a lot of other functions to work, but the functions take a variable amount of paramters.

Why do you ask for the need if you cannot change it though? :)

sletz commented 1 year ago

I still don't understand why it can't be written with the current model...

magnetophon commented 1 year ago

How would you do it? I guess I could make another parameter, 0 for val, 1 for lin and 2 for cub, but ideally it would work the same as regular tabulate.

magnetophon commented 1 year ago

As always, in hindsight it was easy: just declare tabulateNd(N,C,expression,parameters) and put parameters: as the first line of the val, lin and cub functions.

I'll get started on the PR now! :)

Thanks for your patience @sletz!

magnetophon commented 1 year ago

That solution does have the downside that you need to call it with extra brackets around the parameters, so they become one entity. Like so:

tabulateNd(3,1,threeDfunction,   ( sizeX,sizeY,sizeZ,rx0,ry0,rz0,rx1,ry1,rz1,x,y,z ) ).lin

Does anyone know a more elegant solution? Otherwise: How should I explain in the docs of this function why the brackets are needed?

I barely understand it myself, so I'm not in a good position to explain it to others. Ideally we'd have an explanation that is understandable to both computer scientists and audio engineers,. In other words: please do use the proper jargon, but try to also include a simple version.

My best shot at the simple version would be:

In Faust, when you declare an environment, you need to either declare it without specifying any parameters at all, or you need to specify the correct number of parameters. (TODO: explain why this is) Since we need both named parameters and a variable number of parameters, we need to turn the variable number of parameters into one parameter by putting brackets around them in the function call.

Is that more or less correct?

magnetophon commented 1 year ago

I made some docs. They don't explain the whole thing, but at least they give an overview. https://gist.github.com/magnetophon/4b6db0aa32ab6983fa931c6d2454d91f

Please give me feedback.

I particularly hope Julius can have a look, being both a domain expert and a native English speaker.

josmithiii commented 1 year ago

Hi Bart,

It reads very well to me! In general, non-native speakers can use ChatGPT-4 to rewrite their prose as "technical professional English" (or whatever style you want to specify), but your English is fine for me.

I find ChatGPT-4 (even 3.5) to consistently have perfect spelling and grammar, but its signal-processing knowledge leaves a lot to be desired. :-)

Thanks again for super useful ND interpolated table support!

Cheers,

On Sun, May 7, 2023 at 7:38 AM Bart Brouns @.***> wrote:

I made some docs. They don't explain the whole thing, but at least they give an overview. https://gist.github.com/magnetophon/4b6db0aa32ab6983fa931c6d2454d91f

Please give me feedback.

-

Is everything clear?

Is it too much detail, not enough? I imagine it's both depending who is reading and on which part of the docs we are talking about. For example: a computer scientist would have summarized the whole "Storage method" section in a few jargon terms, but then I wouldn't understand it myself, at least not the me before I wrote all this! 😄

Am I using correct English?

I particularly hope Julius can have a look, being both a domain expert and a native English speaker.

— Reply to this email directly, view it on GitHub https://github.com/grame-cncm/faustlibraries/issues/151#issuecomment-1537457384, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQZKFNC2XVQ3HLWH2TZPYTXE6XYDANCNFSM6AAAAAAXU6EKXM . You are receiving this because you were mentioned.Message ID: @.***>

-- Julius O. Smith III @.***> Professor Emeritus of Music and by courtesy Electrical Engineering CCRMA, Stanford University http://ccrma.stanford.edu/~jos/

magnetophon commented 1 year ago

Merged: https://faustlibraries.grame.fr/libs/basics/#batabulatend