Would a BSXFUN operator family be a good idea?

1 visualización (últimos 30 días)
Matt J
Matt J el 2 de Jun. de 2013
I don't think the pipe symbol '|' is being used for anything in MATLAB syntax. Would it be a good idea to use it to make a family of BSXFUN operators? For example, instead of
C=bsxfun(@times,A,B)
C=bsxfun(@plus,A,B)
you could do things like
C=A|*B;
C=A|+B;
  4 comentarios
Matt J
Matt J el 2 de Jun. de 2013
Editada: Matt J el 2 de Jun. de 2013
$ and # are still good though, right? And what about my larger point that it would be good to have an abbreviated BSXFUN operator? I know Bruno has a FEX contribution to help abbreviate this
but I'm not entirely comfortable with the idea of changing syntax interpration rules mid-code.
Walter Roberson
Walter Roberson el 2 de Jun. de 2013
Editada: Walter Roberson el 2 de Jun. de 2013
APL referred to this as "Generalized Outer Product", and relates it closely to APL's "Generalized Inner Product".
APL's outer product syntax is
o.OPERATOR
where o is (in APL character set) a raised small circle, and OPERATOR is a dyadic (binary) operator.
APL's inner product syntax is
OPERATOR1.OPERATOR2
where OPERATOR2 is a dyadic (binary) operator, and OPERATOR1 is a "reduction operator" (that is, reduces an array by one dimension, such as by summing along rows.) +.x (raised multiplication) is APL's matrix multiplication: form the outer product and then sum along a dimension.
It would be nice if MATLAB too applied some systematism to the way that it used operators. For example, MATLAB could start by defining "." as prefix that could be applied to any binary operator, so that instead of .^ and .* and ./ being separate operators specially parsed, that instead they became part of a general rule -- that dot could be followed by a function name or an operator (whose formal name was substituted), or perhaps even an anonymous function, to form a new binary operator.
To be consistent with existing MATLAB usage, the formal name of the new binary operator would be formed from the name of the existing operator but with the leading character dropped (mtimes -> times, mpower -> power, mrdivide -> rdivide). My instinct is that that would not be the best practice going forward. I have not yet come up with a good solution that applies to objects as well.
Oh dang, we already have THIS.THAT syntax in place, don't we? THIS being an object and THAT being either a method or property. Sigh, so much for using . as the generalized extension signaler. Maybe # then.. hmmm, that's used for pragmas such as %#function and %#eml but perhaps there is no real syntactical overlap there... unless of course we can define "%" as being an operator :)
"#" is used as the comment introducer in numerous shells, and some other languages.
I thought I remembered encountering "$" in the first column as indicating comments in FORTRAN, but if I did then it must have been non-standard (WATFOR maybe). "c" and "C" and "*" and "!" (Fortran 90) are what it uses. Ummm, maybe my mind has wandered back to JCL again :-(

Iniciar sesión para comentar.

Respuestas (3)

Walter Roberson
Walter Roberson el 2 de Jun. de 2013
Editada: Walter Roberson el 2 de Jun. de 2013
Pipe is "or"
Unused symbols are: back-quote (`), octothorp (#), dollar-sign ($), and question-mark (?). Oh yes, and double-quote (")

Jan
Jan el 2 de Jun. de 2013
Instead of introducing new operators and limit the backward compatibility, you can implement a new class easily, which uses BSXFUN implicitly for the standard operators. See FEX: int64 class as an example. Here the standard arithmetic is implemented for INT64, which was missing in older Matlab versions. The same can be done for DOUBLE or better for a new derived data type to avoid confusions.
  2 comentarios
James Tursa
James Tursa el 2 de Jun. de 2013
Similar to Jan's suggestion would be to have TMW simply redefine the element-wise operators (.* , ./ , etc) to do bsxfun operations automatically. This would be backwards compatible with existing code (unless code somehow depended on getting an error condition for a mismatch in dimensions).
Matt J
Matt J el 2 de Jun. de 2013
Editada: Matt J el 2 de Jun. de 2013
I'm not seeing the backward compatibility issue. Since these operators would be new, there's no reason old code pre-dating these operators would have a problem running. I'm not suggesting they take BSXFUN away, just open new syntaxes for calling it.
The approach of using new classes is one I've tried, see for example,
It's not a graceful solution, though, because you have to overload all stock Matlab functions for them, SORT, SIN, COS, TRIU,... Subclassing built-in classes doesn't help. The output of many builtin MATLAB functions (e.g., TRIU, TRIL) silently convert subclass input back to doubles and it's painful to keep track of this.

Iniciar sesión para comentar.


Knut
Knut el 2 de Jun. de 2013
Editada: Knut el 2 de Jun. de 2013
I occasionally use the kron() function, and I probably should use bsxfun() more. What I seem to be banging my head up against: I saw the light with MATLAB when I grasped the beauty and compactness of regular 2-d oriented array/vectorization. The fact that it tended to make my MATLAB scripts faster did not hurt either.
Recently, I am feeling constrained: for the kind of stuff that I am doing, MATLAB vectorization can only take me so far. I believe that what I am longing for is tensor math. Is this a direction that TMW will/should head for, or is it too exotic/hard to make fast libraries/something else?
I'd like to write:
a = ones(2,4,3);
g = cat(3,1,2,3);
%1. short-hand for:
%for t = 1:3,
% R1(:,:,t)=a(:,:,t)*g(t);
%end
R1 = a.*g;
R1(:,:,1) =
1 1 1 1
1 1 1 1
R1(:,:,2) =
2 2 2 2
2 2 2 2
R1(:,:,3) =
3 3 3 3
3 3 3 3
%2. short-hand for:
%R2 = zeros(2,4);
%for t = 1:3,
% R2=R2+a(:,:,t)*g(t);
%end
R2 = a*g;
R2 =
6 6 6 6
6 6 6 6
  1 comentario
Matt J
Matt J el 2 de Jun. de 2013
Editada: Matt J el 2 de Jun. de 2013
Hi Knut. Yes, I take your point. However, you know, I hope, that your first example is vectorizable via BSXFUN
R1=bsxfun(@times,a,g)
even though, as I've been saying, it would be nice to have a shorter syntax for this.
The second example can be done with KRON, which I guess is what you've been doing. Note that the KronProd class can be a more efficient alternative to kron(), and somewhat approximates the shorter syntax you desire:
>> g=KronProd({1,1,[1,2,3]},[1,2,3],size(a));
>> g*a
ans =
6 6 6 6
6 6 6 6
This is an approach more along the lines of what Jan and James were recommending, using a class capable of tensor operations. I certainly agree that it could be handy to have a built-in operator syntax for this, though.

Iniciar sesión para comentar.

Categorías

Más información sobre Matrix Indexing en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by