Squared vs pow(2)

Can anyone explain why these two examples produce different signals? (macOS 10.14.6, SC 3.11.1)

s.boot;

{SinOsc.ar(220).pow(2) * 0.1!2}.play;
{SinOsc.ar(220).squared * 0.1!2}.play;

I’m vaguely guessing it’s an order-of-operations thing, e.g.

(-1).pow(2);
1.pow(2).neg;

But I don’t understand why pow(2) and squared might cause this discrepancy.

Eli

yikes - result for square is wrong here as well. bug. but where?

edit (whoops I mean pos! brain not working)

Actually, I’m thinking about this a bit more…

In my two sine examples, I’m pretty sure squared is the correct one (all values ≥ 0), and pow is behaving unexpectedly.

I recall diving into exprand awhile back, attempting to figure out why it fails when min/max don’t have the same sign, and the result was that the source code implementation would involve raising a negative number to a non-integer power, which is undefined/nonsensical (I think).

So my guess is that, at some point, pow was defined for UGens in a special way, in order to preserve sign, so that n can be smoothly swept from 1 to inf in {SinOsc.ar(220).pow(n) * 0.1!2}.play;, without causing weird waveform discontinuities or blowing something up.

Can anyone confirm this?

raising a negative number to a non-integer power, which is undefined/nonsensical (I think).

it is defined, but will produce a non-real result. the imaginary number i is defined as (-1)^0.5 for instance. so pow could, for instance, produce a 2 channel signal representing a complex number, but i think in general this is not what most people want from it, even though it would be more mathematically sound, i think.

If a.pow(e) is defined to be sign(a)*(absolutevalue(a).pow(e)) - that just seems bad to me - maybe whats wanted is a seperate “bipolar pow” - .bpow.

common functions shouldn’t produce unexpected values!

I think you can evaluate pow with complex range and subtract the imaginary coefficient from the real one to get current behavior -1^(0.5) -> (0+1i) -> 0-1 -> -1

pow is sign(a) * pow(abs(a), b) as a BinaryOpUGen, it’s documented here: http://doc.sccode.org/Overviews/Operators.html#.pow

1 Like

Yes, that clears it up. Thanks!

on the contrary, i dont think most people would find a “correctly defined” pow useful here, whether that would be one returning NaNs or complex numbers. we are always striking a balance between conceptual purity and forgiveness when designing languages like SC. this is a reasonable choice.

1 Like