Tue 19 May 2015 07:15:58 PM UTC, comment #11:
I documented that fplot requires a user-defined function which accepts vector inputs (http://hg.savannah.gnu.org/hgweb/octave/rev/59911f536b07). This seems like enough of a fix since we now match Matlab's stated behavior.
|
Fri 04 Apr 2014 08:41:46 PM UTC, comment #10:
I like John's idea.
|
Fri 04 Apr 2014 08:29:15 PM UTC, comment #9:
Matlab may allow functions that only work properly with scalar arguments, but it is not documented. So you are asking us to implement undocumented Matlab behavior.
I suggest we only do this if there is a way to also preserve calling the function with array arguments if possible, for example by doing a few test calls to see what happens if the function is called with a vector argument and whether the size of the result is as expected.
Note again that this is not just a vector of the same size as the input to the function.
|
Fri 04 Apr 2014 08:17:35 PM UTC, comment #8:
Looks like the behvaior of fplo is not consistent with documentation.
I did a few experiment on Matlab and Octave.
foo.m:
function y=foo(x)
y=1/x;
end
fplot('foo',[1 10]); % Works in Matlab. Fails in Octave
h=@foo;
fplot(h,[1 10]); %Works in Matlab. Fails in Octave.
|
Fri 04 Apr 2014 07:58:24 PM UTC, comment #7:
Jordi, I don't think arrayfun is the right thing to do.
First, it will be slower (much so for functions that require many evaluations to make good looking plots) and the expectation for Matlab is that the function accepts an array argument. I think we should just give an error if the result from the function does not have the expected size. Note that "expected size" is not simply a vector of the same size as the input. It may also be a matrix with the same number of rows as the number of elements in the input array.
Second, I think using arrayfun may actually break compatibility. Please take a look at what the Matlab docs say about how the function that is passed to fplot is supposed to behave.
|
Fri 04 Apr 2014 07:40:54 PM UTC, comment #6:
I'm working on an arrayfun solution. It's not that difficult.
|
Fri 04 Apr 2014 05:08:14 PM UTC, comment #5:
I completely agree, the Matlab documentation makes it clear that the function or function handle passed in to fplot must accept a vector and return a vector of the same length which is the result of evaluating the function elementwise. Therefore @(x)1/x is an invalid argument for fplot, undefined behavior ensues.
What I would recommend (I haven't looked into fplot yet) is perhaps an error if the size of the output obtained from calling the given function is not what is expected. That could make the problem clearer than a generic "nonconformant arguments" error.
|
Fri 04 Apr 2014 04:49:54 PM UTC, comment #4:
Hmm, the documentation for Matlab's fplot clearly states that the function passed to fplot should accept vectors.
I still think the "vectorize" feature is not a really good idea and should be deprecated and removed...
|
Fri 04 Apr 2014 04:44:44 PM UTC, comment #3:
Looking at fplot, I see that it applies a "vectorize" function to function arguments that are "inline" or simply character strings representing the expression to plot. I guess we could try to extend that concept to function handles, but it seems a bit messy since functions given by name are not vectorized, and I see no reasonable way to do so.
Maybe that feature should be deprecated and eventually removed and we should just evaluate the function with arrayfun instead?
|
Fri 04 Apr 2014 04:38:13 PM UTC, comment #2:
I'm not sure about 3.2.4, but in 3.8.1, the problem is that fplot is passing a vector to the function instead of calling it N times with a scalar value each time. So when you write 1/x, you're finding some minimum norm solution to an underdetermined linear equation, not finding the reciprocal for each value in the vector X.
If this works in Matlab, then I guess they are calling the function N times in a loop (maybe with arrayfun?). In any case, it will be slower to call the function for each element of the vector, but maybe it's what we have to do.
You can avoid the problem by defining your function so that it works properly for vector inputs:
That should work properly in Matlab or Octave.
|
Fri 04 Apr 2014 04:17:26 PM UTC, comment #1:
Confirmed at 3.8.1
|
Fri 04 Apr 2014 03:50:26 PM UTC, original submission:
>>> h=@(x)1/x
h =
@(x) 1 / x
>>> fplot(h,[1 10])
error: operator -: nonconformant arguments (op1 is 8x1, op2 is 1x8)
error: evaluating argument list element number 1
error: evaluating argument list element number 1
error: evaluating argument list element number 1
>>>error: evaluating argument list element number 1
error: called from:
error: fplot at line 44, column 11
>>>
The same statements work on Matlab.
This works however, where sin(x) is a built-in function.
>>> h=@(x)sin(x)
h =
@(x) sin (x)
>>> fplot(h,[1 10])
Below is the version info. I am using the latest distribution on ubuntu.
GNU Octave Version 3.2.4
GNU Octave License: GNU General Public License
Operating System: Linux 3.11.0-18-generic #32~precise1-Ubuntu SMP Thu Feb 20 17
:52:10 UTC 2014 x86_64
----------------------------------------------------------------------
Package Name | Version | Installation directory
-------------------+---------+-----------------------
control *| 1.0.11 | /usr/share/octave/packages/3.2/control-1.0.11
io *| 1.0.14 | /usr/share/octave/packages/3.2/io-1.0.14
linear-algebra *| 2.1.0 | .../octave/packages/3.2/linear-algebra-2.1.0
miscellaneous *| 1.0.11 | .../octave/packages/3.2/miscellaneous-1.0.11
missing-functions *| 1.0.2 | .../octave/packages/3.2/missing-functions-1.0.2
odepkg *| 0.6.12 | /usr/share/octave/packages/3.2/odepkg-0.6.12
optim *| 1.0.17 | /usr/share/octave/packages/3.2/optim-1.0.17
signal *| 1.0.11 | /usr/share/octave/packages/3.2/signal-1.0.11
specfun *| 1.0.9 | /usr/share/octave/packages/3.2/specfun-1.0.9
struct *| 1.0.9 | /usr/share/octave/packages/3.2/struct-1.0.9
symbolic *| 1.0.9 | /usr/share/octave/packages/3.2/symbolic-1.0.9
|