Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

why matrix needs to have a numerical value? #132

Open
telephon opened this issue Aug 14, 2022 · 4 comments
Open

why matrix needs to have a numerical value? #132

telephon opened this issue Aug 14, 2022 · 4 comments

Comments

@telephon
Copy link
Contributor

telephon commented Aug 14, 2022

Let's relax the constraint in the Matrix class (MathLib) that values must be numbers:

// just this commenting out
put { arg row, col, val;
		super.at(row).put(col, val)
		/*if( val.isNumber,{
			super.at(row).put(col, val)
		},{
			error("not a number in Matrix-put");this.halt
		});*/
	// put an Array of elements
	}

I can write the following, and to my impression it works correctly.

// prepare
~decoder = FoaDecoderKernel.newUHJ;


(

Ndef(\foa_scene, {
	var sound, angle, azimuth, bformat;
	sound = Decay.ar(Impulse.ar(2.3), 0.05, PinkNoise.ar(1));
	// azimuth -> hard left     = back
    //          centre     = centre
    //          hard right     = back
	azimuth = MouseX.kr(-pi, pi);
	// angle ---> top         = push to plane wave
    //            bottom        = omni-directional
	angle = MouseY.kr(pi/2, 0);
	bformat = FoaEncode.ar(sound, FoaEncoderMatrix.newDirection(azimuth, angle));
});

Ndef(\foa_transformer, {
	var in = Ndef.ar(\foa_scene);
	in // for now, just play out the b-format input
});


Ndef(\foa_decoder, {
	var in = Ndef.ar(\foa_transformer);
	var sound = FoaDecode.ar(in, ~decoder);
	Limiter.ar(sound)
});

Ndef(\foa_decoder).play
);

Should we relax the constraint? Since sclang automatically lifts math operations to UGens, it seems overly narrow.

EDIT: I've made a ticklist for methods that work with UGens, Arrays, and Functions as matrix entries, from inspecting the code. See: supercollider-quarks/MathLib#38

@joslloand
Copy link
Contributor

Hello @telephon,

Hmm... at first I'm surprised that this (quote below) works:

Ndef(\foa_scene, {
	var sound, angle, azimuth, bformat;
	sound = Decay.ar(Impulse.ar(2.3), 0.05, PinkNoise.ar(1));
	// azimuth -> hard left     = back
    //          centre     = centre
    //          hard right     = back
	azimuth = MouseX.kr(-pi, pi);
	// angle ---> top         = push to plane wave
    //            bottom        = omni-directional
	angle = MouseY.kr(pi/2, 0);
	bformat = FoaEncode.ar(sound, FoaEncoderMatrix.newDirection(azimuth, angle));
});

Looking closer at FoaEncoderMatrix:*newDirection, I can see why the above would work given relaxing the Matrix restraint in MathLib.

I'm not sure we could expect this to be the case across the board for all FOA and HOA matrix operations. As you know, for (most) relevant operations we have both matrix and corresponding (p-)UGen implementations.

Just thinking aloud here... two interesting spaces that opening up Matrix could offer:

  • matrix operations on kr, ar streams
  • matrix operations on Signal collections

The latter could be nice, in that MATLAB / SciPy type functionality could be introduced. (@mtmccrea and I have been looking at writing new classes to offer this possibility.) The former could imply refactoring / reducing / replacing current (p-)UGen implementations.

I think we'd want to carefully review the use cases and resulting performance. I am suspicious that there will be a variety of Matrix methods that just won't work... but, I could be wrong.

@mtmccrea, @dyfer, @dmartinp, @joshpar, do you have any thoughts / opinions on the matter?

@telephon
Copy link
Contributor Author

There are probably some adjustments that will have to be made if all methods should work.

An example:

* { arg that; // return matrix A(m,n) * B(n,r) = AB(m,r)
		var result;

		if ( that.isNumber, {
			^this.mulNumber(that);
		},{
			^this.mulMatrix(that);
		});
	}

would have to become:

* { arg that; // return matrix A(m,n) * B(n,r) = AB(m,r)
		var result;

		if ( that.isKindOf(this), {
			^this.mulMatrix(that);
		},{
			^this.mulNumber(that);
		});
	}

But this is better anyhow.

The optimal approach would be to write tests (which would be a good idea anyhow for a class so central), and then vary the tests, replacing numbers with their UGen and Signal counterparts.

@dyfer
Copy link
Contributor

dyfer commented Aug 19, 2022

Without having worked with Matrix very closely, I'd say that I'd be in favor of removing the number check, since it's better not to have preemptive constrains.

The optimal approach would be to write tests (which would be a good idea anyhow for a class so central), and then vary the tests, replacing numbers with their UGen and Signal counterparts.

This would be ideal, IMO.

Also... I understand this was raised in the context of Atk matrices, but do I understand correctly that we are discussing MathLib's methods here? If so, the discussion should probably be moved there eventually...

@telephon
Copy link
Contributor Author

Also... I understand this was raised in the context of Atk matrices, but do I understand correctly that we are discussing MathLib's methods here? If so, the discussion should probably be moved there eventually...

Yes. If we get it working correctly with Atk, it is a good start. But discussion should be here: supercollider-quarks/MathLib#38

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants