I want to plot a function in scilab in order to find the maximum over a range of numbers:
function y=pr(a,b)
m=1/(1/270000+1/a);
n=1/(1/150000+1/a);
y=5*(b/(n+b)-b/(m+b))
endfunction
x=linspace(10,80000,50)
y=linspace(10,200000,50)
z=feval(x,y,pr)
surf(x,y,z);
disp( max(z))
For these values this is the plot:
It's obvious that increasing the X axis
will not increase the maximum but Y axis
will.
However from my tests it seems the two axis are mixed up. Increasing the X axis
will actually double the max Z value
.
For example, this is what happens when I increase the Y axis
by a factor of ten (which intuitively should increase the function value):
It seems to increase the other axis (in the sense that z vector
is calculated for y,x
pair of numbers instead of x,y
)!
What am I doing wrong here?
Stephane's answer is correct, but I thought I'd try to explain better why / what is happening.
From the help surf
page (emphasis mine):
X,Y:
two vectors of real numbers, of lengths nx and ny ; or two real matrices of sizes ny x nx: They define the data grid (horizontal coordinates of the grid nodes). All grid cells are quadrangular but not necessarily rectangular. By default, X = 1:size(Z,2) and Y = 1:size(Z,1) are used.Z:
a real matrix explicitly defining the heights of nodes, of sizes ny x nx.
In other words, think of surf as surf( Col, Row, Z )
From the help feval
page (changed notation for convenience):
z=feval(u,v,f):
returns the matrix z such as z(i,j)=f(u(i),v(j))
In other words, in your z
output, the i
become rows (and therefore u
should represent your rows), and j
becomes your columns (and therefore v
should represent your columns).
Therefore, you can see that you've called feval
with the x
, y
arguments the other way round. In a sense, you should have designed pr
so that it should have expected to be called as pr(y,x) instead, so that when passed to feval
as feval(y,x,pr)
, you would end up with an output whose rows increase with y
, and columns increase with x
.
Then you could have called surf(x, y, z)
normally, knowing that x
corresponds to columns, and y
corresponds to rows.
However, if you don't want to change your whole function just for this, which presumably you don't want to, then you simply have to transpose z in the call to surf, to ensure that you match x to the columns or z'
(i.e, the rows of z
), and y to the rows of z'
(i.e. the columns of z
).
Having said all that, it would probably be much better to make your function vectorized, and just use the surf(x, y, pr)
syntax directly.