1

I am trying to plot the function

f(x, y) = (x – 3).^2 – (y – 2).^2.

x is a vector from 2 to 4, and y is a vector from 1 to 3, both with increments of 0.2. However, I am getting the error:

"Subscript indices must either be real positive integers or logicals".

What do I do to fix this error?

learnvst
  • 15,455
  • 16
  • 74
  • 121
cuabanana
  • 126
  • 1
  • 1
  • 7
  • If you want help with Matlab code, post Matlab code, not some approximation to it. – High Performance Mark Oct 19 '12 at 15:44
  • Also see [this question](http://stackoverflow.com/questions/20054047/subscript-indices-must-either-be-real-positive-integers-or-logicals-generic-sol) for [the generic solution to this problem](http://stackoverflow.com/a/20054048/983722). – Dennis Jaheruddin Nov 27 '13 at 16:06

3 Answers3

4

I (think) I see what you are trying to achieve. You are writing your syntax like a mathematical function definition. Matlab is interpreting f as a 2-dimensional data type and trying to assign the value of the expression to data indexed at x,y. The values of x and y are not integers, so Matlab complains.

If you want to plot the output of the function (we'll call it z) as a function of x and y, you need to define the function quite differently . . .

f = @(x,y)(x-3).^2 - (y-2).^2;
x=2:.2:4;
y=1:.2:3; 
z = f(  repmat(x(:)',numel(y),1)  , repmat(y(:),1,numel(x) ) );

surf(x,y,z); 
xlabel('X'); ylabel('Y'); zlabel('Z');

This will give you an output like this . . . enter image description here

The f = @(x,y) part of the first line states you want to define a function called f taking variables x and y. The rest of the line is the definition of that function.

If you want to plot z as a function of both x and y, then you need to supply all possible combinations in your range. This is what the line containing the repmat commands is for.

EDIT

There is a neat Matlab function meshgrid that can replace the repmat version of the script as suggested by @bas (welcome bas, please scroll to bas' answer and +1 it!) ...

f = @(x,y)(x-3).^2 - (y-2).^2;
x=2:.2:4;
y=1:.2:3;
[X,Y] = meshgrid(x,y);
surf(x,y,f(X,Y)); 
xlabel('x'); ylabel('y'); zlabel('z');
learnvst
  • 15,455
  • 16
  • 74
  • 121
2

I typically use the MESHGRID function. Like so:

x = 2:0.2:4;
y = 1:0.2:3;
[X,Y] = meshgrid(x,y);
F = (X-3).^2-(Y-2).^2;
surf(x,y,F);
xlabel('x');ylabel('y');zlabel('f')

This is identical to the answer by @learnvst. it just does the repmat-ing for you.

bas
  • 209
  • 2
  • 10
1

Your problem is that the function you are using uses integers, and you are trying to assign a double to it. Integers cannot have decimal places. To fix this, you can make it to where it increases in increments of 1, instead of 0.2

Azulflame
  • 1,534
  • 2
  • 15
  • 30