How does one overload / redefine binary operators in Julia? - operator-overloading

I keep losing my reference on how to redefine say the || ("or") or && ("and") binary operators. I read somewhere that one has to first do importall Base . Then I tried
Base.||( x::MyType, y::MyType ) = dosomething( x, y )
and also
Base.or( x::MyType, y::MyType ) = dosomething( x, y )
But none of these worked. I would appreciate if somebody could give a reference explaining the basics of how to do this... I was unable to find one with queries such as "redefine binary operator in Julia"...

As && and || are short circuit operations, they can't be overloaded, without adding a special construction separate from functions. To call a function, you need to evaluate all the arguments, and that would not be a short circuit evaluation.
You might be able to overload & and | instead, but it is hard to tell without an example use case.

Related

ILNumerics: compund test for ILLogical: AND two logical conditions

I am trying to create an ILLogical array that selects data between upper and lower limits like this:
ILLogical ix = a > limit[0] & a < limit[1]
where a and limit are ILArray< double >. I get an ILArgumentException about "Nonscalar logical to bool conversion" asking me to see ILSettings.LogicalArrayToBoolConversion. Changing the '&' to '&&' doesn't help. Is there no way to set up a compound test resulting in an ILLogical? What are my alternatives?
There is no (convenient) way to overload the binary logical operators as & in C# in the way required here. Also, if such way would exist it would badly act against common intuition and likely cause more confusion than convenience.
Instead use the functional interface with ILMath.and() & Co:
ILLogical ix = ILMath.and(a > limit[0], a < limit[1]);
See: API class documentation on and

how to handle subsref at the left of '=' in matlab

how to handle subsref at the left of '=' in matlab?
I have a line in my matlab function like this.
s1.type = '{}';
s1.subs = {5};
s2.type = '()';
index = 4 + (day - 1) * 4 + action;
s2.subs = {index};
subsref(subsref(pair(key),s1),s2) = subsref(subsref(pair(key),s1),s2) + 1;
pair is a container.map and key is the key of the map
because of the disgusting syntax, I have to use subsref to put '()' before '{}' of cell.
Here comes the error:
"subsref" previously appeared to be used as a function or command, conflicting with its use here as the name of a variable.
A possible cause of this error is that you forgot to initialize the variable, or you have initialized it implicitly using load or
eval.
How can I put subsref at the left of '=' or how can this expression +1 itself?
subsref is called when you use A(i), A{i} or A.i on the right-hand side (i.e. when you're indexing into an expression).
When you use them on the left-hand side for assignment - in other words, when you use A(i) = B, A{i} = B or A.i = B, MATLAB instead calls subsasgn (pronounced "subs assign") .
I'm not sure exactly what your example code is trying to do, but whatever it is I would think you'll need to call subsasgn, rather than just subsref.
In addition, I note that you're doing this on a variable that is a containers.Map. Note that containers.Map, because of its unusual syntaxes, overloads both subsref and subsasgn, and you are likely to find it very difficult to do what you're trying to do. See my answer here for further information on that topic.
PS: you may like to post a separate question asking how to approach the underlying problem you're trying to solve. Whatever it is, I cannot believe that this level of complexity with subsref and subsasgn is really necessary.

Is the uplus function useful?

This is a rhetorical question about the uplus function in MATLAB, or its corresponding operator, the unary plus +.
Is there a case where this operator is useful? Even better, is there a case where this operator is necessary?
It is not necessary, a language without a unary plus does not allow to write +1. Obviously you could also write 1 but when importing data which always writes the + or - it's very nice to have.
Searching some source codes, I found a curious use of +
A=+A
which replaced the code:
if ~isnumeric(A)
A=double(A);
end
It casts chars and logicals to double, but all numeric data types remain untouched.
It can be useful when defining new numeric types.
Suppose you define quaternion and overload uplus:
classdef quaternion
...
end
Then in your code you can write:
x = quaternion(...);
y = [+x, -x];
z = +quaternion.Inf;
t = -quaternion.Inf;
If you don't you cannot have same syntax as for other numeric.
PS: To the question "is it useful" (in the sence mandatory for some syntaxes) ... well I can't find any reason ... but sometimes writting '+x' make things clearer when reading back the code.
I'm not sure if this fully constitutes "useful" or if it's the best programming practice, but in some cases, one may wish to use the unary + for symmetry/clarity reasons. There's probably a better example, but I'm thinking of something like this:
A = [+1 -1 +1;
-1 +1 -1;
+1 -1 +1];
As for the uplus function, it's kind of a NOOP for numeric operations. If one writes a function that requires a function handle input to specify an operation to perform, it might be useful to have do nothing option.
Lastly, numeric operators can be overloaded for other classes. The uplus function could have more use in other built-in classes or even one you might want write yourself.

What is the correct way to select real solutions?

Suppose one needs to select the real solutions after solving some equation.
Is this the correct and optimal way to do it, or is there a better one?
restart;
mu := 3.986*10^5; T:= 8*60*60:
eq := T = 2*Pi*sqrt(a^3/mu):
sol := solve(eq,a);
select(x->type(x,'realcons'),[sol]);
I could not find real as type. So I used realcons. At first I did this:
select(x->not(type(x,'complex')),[sol]);
which did not work, since in Maple 5 is considered complex! So ended up with no solutions.
type(5,'complex');
(* true *)
Also I could not find an isreal() type of function. (unless I missed one)
Is there a better way to do this that one should use?
update:
To answer the comment below about 5 not supposed to be complex in maple.
restart;
type(5,complex);
true
type(5,'complex');
true
interface(version);
Standard Worksheet Interface, Maple 18.00, Windows 7, February
From help
The type(x, complex) function returns true if x is an expression of the form
a + I b, where a (if present) and b (if present) are finite and of type realcons.
Your solutions sol are all of type complex(numeric). You can select only the real ones with type,numeric, ie.
restart;
mu := 3.986*10^5: T:= 8*60*60:
eq := T = 2*Pi*sqrt(a^3/mu):
sol := solve(eq,a);
20307.39319, -10153.69659 + 17586.71839 I, -10153.69659 - 17586.71839 I
select( type, [sol], numeric );
[20307.39319]
By using the multiple argument calling form of the select command we here can avoid using a custom operator as the first argument. You won't notice it for your small example, but it should be more efficient to do so. Other commands such as map perform similarly, to avoid having to make an additional function call for each individual test.
The types numeric and complex(numeric) cover real and complex integers, rationals, and floats.
The types realcons and complex(realcons) includes the previous, but also allow for an application of evalf done during the test. So Int(sin(x),x=1..3) and Pi and sqrt(2) are all of type realcons since following an application of evalf they become floats of type numeric.
The above is about types. There are also properties to consider. Types are properties, but not necessarily vice versa. There is a real property, but no real type. The is command can test for a property, and while it is often used for mixed numeric-symbolic tests under assumptions (on the symbols) it can also be used in tests like yours.
select( is, [sol], real );
[20307.39319]
It is less efficient to use is for your example. If you know that you have a collection of (possibly non-real) floats then type,numeric should be an efficient test.
And, just to muddy the waters... there is a type nonreal.
remove( type, [sol], nonreal );
[20307.39319]
The one possibility is to restrict the domain before the calculation takes place.
Here is an explanation on the Maplesoft website regarding restricting the domain:
4 Basic Computation
UPD: Basically, according to this and that, 5 is NOT considered complex in Maple, so there might be some bug/error/mistake (try checking what may be wrong there).
For instance, try putting complex without quotes.
Your way seems very logical according to this.
UPD2: According to the Maplesoft Website, all the type checks are done with type() function, so there is rather no isreal() function.

How can I make the value of an expression equal to a second return value of another expression

Is there an idiomatic way in Matlab to bind the value of an expression to the nth return value of another expression?
For example, say I want an array of indices corresponding to the maximum value of a number of vectors stored in a cell array. I can do that by
function I = max_index(varargin)
[~,I]=max(varargin{:});
cellfun(#max_index, my_data);
But this requires one to define a function (max_index) specific for each case one wants to select a particular return value in an expression. I can of course define a generic function that does what I want:
function y = nth_return(n,fun,varargin)
[vals{1:n}] = fun(varargin{:});
y = vals{n};
And call it like:
cellfun(#(x) nth_return(2,#max,x), my_data)
Adding such functions, however, makes code snippets less portable and harder to understand. Is there an idiomatic to achieve the same result without having to rely on the custom nth_return function?
This is as far as I know not possible in another way as with the solutions you mention. So just use the syntax:
[~,I]=max(var);
Or indeed create an extra function. But I would also suggest against this. Just write the extra line of code, in case you want to use the output in another function. I found two earlier questions on stackoverflow, which adress the same topic, and seem to confirm that this is not possible.
Skipping outputs with anonymous function in MATLAB
How to elegantly ignore some return values of a MATLAB function?
The reason why the ~ operator was added to MATLAB some versions ago was to prevent you from saving variables you do not need. If there would be a syntax like the one you are searching for, this would not have been necessary.