# Plotting a mathematical function

Hey community,

beside being hardly able to understand the following term, I am stuck with plotting it:

``````(
var t = 2;
f = { ((10 * cos(2pi * (5 * t))) + (5 * cos(2pi * (40 * t)))) * exp(-pi*t**2) };
f.plot;
)
``````

It always gives a warning that the “keyword arg ‘loop’ [is] not found in call to Meta_Object:new” (same goes with ‘dur’ and ‘doneAction’). But where do I call any of them?
I tried several things with `.plotGraph`, `.sampled` or to convert this term to an array but nothing helped…

Also when breaking down to

``````(
f = { 5 }.plot;
)
``````

the same error occurs.

It’s because the result is just a number

``````(
f = {arg t; ((10 * cos(2pi * (5 * t))) + (5 * cos(2pi * (40 * t)))) * exp(-pi*t**2) };
)

f.(2)
``````

I put it this way to give the Interpreter time to process the function before calling a value on it.

You can’t plot a number. It needs to have a two dimensional value so there is something to plot. A function has specific x and y values, so you can plot that, but a single value is just a value.

``````(
(1..5).collect{arg t; ((10 * cos(2pi * (5 * t))) + (5 * cos(2pi * (40 * t)))) * exp(-pi*t**2) }.plot;
)
``````

Will work because you aren’t looking to get a single value back. You’re asking for a range of values.

You also have to call ‘value’ on a mathematical function for it to return the evaluation of that function.

1 Like

I do not fully understand the error messages, but the issue is you want to plot a function, which needs to be evaluated, moreover, your function output a single value.

1 Like

`{ ... }.plot` does not plot arbitrary functions.

It plots synthesis functions.

You will have to use unit generators inside the function.

hjh

1 Like

Mhh I understand, thanks for clarifying…

And if I am looking for a result like this one?

I should work with `Signal` or converting this into a Buffer and then plot it again?

I think I’m at a loss to how this relates. I’m not good enough at math to really make a connection between the equation and your image. Do you have a source for this?

Nothing special…

Haven’t tested but you might try something like:

``````(
{
var t = Line.ar(0, 2, 0.01);
((10 * cos(2pi * (5 * t))) + (5 * cos(2pi * (40 * t)))) * exp(-pi*t**2)
}.plot;
)
``````

hjh

1 Like

What you want to be doing is to fill an `Array` with interpolated values between your desired domain start and end points (here, `-1.5` and `1.5`) and plot the array. You can do this using `Array.interpolation()` or by creating a number of points and scaling them to the right range using `.linlin`.

Note that because of SuperCollider’s precedence rules, `exp(-pi*t**2)`gives an incorrect result and should be `exp(-pi*(t**2))`.

``````(
var numPlotPoints = 1024;
var from = (-1.5), to = 1.5;
var linspace = (0..numPlotPoints).linlin(0, numPlotPoints, from, to);
linspace.collect { |t|
((10 * cos(2pi * (5 * t))) + (5 * cos(2pi * (40 * t)))) * exp(-pi*(t**2))
}.plot.domainSpecs_([from, to].asSpec);
)
``````

As a shortcut, there’s also `Function`’s `.plotGraph` method, which pretty much does the same thing internally and is what I use when I quickly want to plot a mathematical function:

``````(
var func = { |t|
(10 * cos(2pi * (5 * t))) + (5 * cos(2pi * (40 * t))) * exp(-pi*(t**2))
};
func.plotGraph(n: 1024, from: -1.5, to: 1.5)
)
``````
1 Like

Seems to work exepct that one can only see half of the waveform. Was exploring around with domainSpecs and so but @bovil43810 has got my solution - thank you!

Thank you so much, also for the tipp regarding the precedence rules - will remember that!

There’s a tricky detail that prevents that snippet from producing your desired graph (aside from the precendence bit). Compare the following:

``````(
{
var t = Line.ar(-1.5, 1.5, 0.01);
var pow1, pow2, pow3, pow4;

pow1 = t.pow(2);
pow2 = t ** 2;
pow3 = t.squared;
pow4 = t * t;

[pow1, pow2, pow3, pow4]
}.plot;
)
``````

As you can see, `.pow` and `**` don’t work the way you might think they do inside UGen graph functions. `pow(a, b)` is actually defined as `sign(a) * pow(abs(a), b)` when it is used as a `BinaryOpUGen`, as documented here. There’s also a forum thread that goes into detail on why that implementation actually makes sense. Compare this to the same operation done on the language side:

``````(
var t;
var pow1, pow2, pow3, pow4;

t = (0..1024).linlin(0, 1024, -1.5, 1.5);

pow1 = t.pow(2);
pow2 = t ** 2;
pow3 = t.squared;
pow4 = t * t;

[pow1, pow2, pow3, pow4].plot; // all give same result
)
``````

Here’s a corrected version that produces the desired result:

``````(
{
var t = Line.ar(-1.5, 1.5, 0.01);
((10 * cos(2pi * (5 * t))) + (5 * cos(2pi * (40 * t)))) * exp(-pi*(t.squared))
}.plot;
)
``````
1 Like

Interesting and good to know! This would have taken me ages to find out… Thank you again!

1 Like

That behaviour cost me at least a couple of hours of puzzling and debugging over the course of my SC journey thus far, so I’m glad to spread the word… It’s not like it’s underdocumented really, just a very common beginner pitfall. Apparently it’s pretty much standard in DSP land to define pow that way, though. Just make sure to use `pow(abs(a), b)` to reflect the language-side behaviour when translating math functions into UGen code.

1 Like