1

I'm used to working with Python's arrays where I can access array elements straight after a computation, without defining the result as a separate array. (I know this is 100% confusing, here's an example:) I can do:

>>> x = np.array([1,2,3], dtype=np.double)
>>> y = np.array([4,0,6], dtype=np.double)
>>> x/y
array([ 0.25,  inf,  0.5 ])
>>> (x/y)[np.isfinite(x/y)]
array([ 0.25, 0.5 ])

I know it's not as clear as defining a new variable (say z = x/y), but it's usefull when I create lambda functions.

I would like to do the same in Matlab, to use inside an anonymous function (@ functions), but I can't find a way to do it. The equivalent (x./y)(isfinite(x./y)) obviously doesn't work, but is there another way to get elements from an array? I do not want to use x(isfinite(x))./y(isfinite(y)) because it won't catch elements where y is null.

PhilMacKay
  • 865
  • 2
  • 10
  • 22
  • Is there a MATLAB equivalent to `.__getitem__`? Edit: apparently it's the subsref function in yuk's comment. – askewchan Apr 03 '13 at 15:24
  • yuk's comment seems to be the way to go, in general. I'll add a more specific example of what I want to do, as I'm not sure how to use `subsref()` in my case. – PhilMacKay Apr 03 '13 at 15:37

1 Answers1

1

As yuk has already pointed out in the comments, subsref is the way to solve the actual question. This solves the problem, but implementations using are usually very difficult to write, read, and modify.

What you actually probably want to do is use a quickie helper function. Below is example code demonstrating all these approaches.

%Setup
x = [1 2 3];
y = [4 0 6];

%Raw computation
x./y

%Temporary variable filtering
temp = x./y;
example1 = temp(isfinite(temp))

%Filtering using subsref call, using "struct" to construct the needed
%referencing operation.  This is equivalent to  
%    "(x./y)(isfinite(x./y)", 
%if that were legal
example2 = subsref(x./y, ...
    struct('type','()','subs',{{isfinite(x./y)}})    )

%More readable implementation, using a quickie helper
keepFinite = @(x) x(isfinite(x));
example3 = keepFinite(x./y)

Using the example above, the keepFinite function can be used in further construction of lambda functions. For example: fn = @(x,y)someotherOperation(keepFinite(x./y));.

Pursuit
  • 12,285
  • 1
  • 25
  • 41
  • Thanks for the detailed examples! I can't believe how complicated it has to be to fit in one line... Too bad I'm limited by professional contraints to use Matlab! I think I'll opt for a 2 lines solutions instead of something as ugly as `nanSumOfQuotient = @(x,y) subsref(x./y, struct('type','()','subs',{{isfinite(x./y)}}) )`... (My real operation is much longer than a simple quotient!) – PhilMacKay Apr 03 '13 at 16:17
  • I think that the Mathworks is hampered by the legacy syntax where `()` is used for both array access and function calls, making some syntax combinations difficult to interpret efficiently. Another example is that you cannot put multiple function handles into an array, since that makes the syntax `fnArray(1)` difficult to interpret. – Pursuit Apr 03 '13 at 16:27
  • Is using a temporary variable really that bad? – JustinBlaber Apr 03 '13 at 16:43
  • 1
    By itself, not really. But anonymous functions are really useful, and can only contain a single line. So sometimes there is a desire to avoid constructs which require multiple lines, such as temp variables and `if` statements. This could also be address by the addition of a multi-line anonymous function syntax, but that seems unlikely. – Pursuit Apr 03 '13 at 16:56