Index exceeds matrix dimensions on an empty function - function

I am having this issue with a function that I have created in matlab. I have variables h = 0.2 and x = (0:h:1)'. 'x' is a row vector with 5 elements. I am using the following function in matlab
function d = dplus(fstring, x, h)
d=0;
end
whenever I plug the following into matlab
dplus('prob4Func',x,h)
I get this error "??? Index exceeds matrix dimensions." This makes absolutely no sense since I am not even using the vector 'x' anywhere in the function. Is there some subtlety to matlab I am missing?

I just needed to use 'clearvars dplus' to get it working. Thanks Navan!

Related

A question regarding the nuances of functions within MatLab

When I run this piece of code:
dx = 4/(nx-1);
dy = 2/(ny-1);
phinew(2:ny-1,2:nx-1) = ((dy^2*(phiold(1:ny-2,2:nx-1)+phiold(3:ny,2:nx-1))+dx^2*(phiold(2:ny-1,1:nx-2)+phiold(2:ny-1,3:nx)))/(2*(dx^2+dy^2))-poissonf);
Within my code, the piece of code operates correctly, taking an input of an nx by ny matrix and outputting a nx by ny matrix. When I run the following code in the exact same position however:
phinew = Smoothing(phiold,poissonf,nx,ny)
Where the function "Smoothing" is defined as:
function [phinew,dx,dy] = Smoothing(phiold,poissonf,nx,ny)
dx = 4/(nx-1);
dy = 2/(ny-1);
phinew(2:ny-1,2:nx-1) = ((dy^2*(phiold(1:ny-2,2:nx-1)+phiold(3:ny,2:nx-1))+dx^2*(phiold(2:ny-1,1:nx-2)+phiold(2:ny-1,3:nx)))/(2*(dx^2+dy^2))-poissonf);
end
The function returns a nx-1 by ny-1 matrix for an nx by ny input.
I cannot wrap my head around why this is occurring at all. The output matrix is the exact same as it should be, except the last column and row are missing entirely. My code is iterative and so requires these to be of the same size, so I cannot move on until this issue is resolved.
Thank you for your time and your help. You people are life-savers.
When you run your code in the command window, phinew already exists. In your command window, do clear phinew before you pasting in those three lines, and you'll find that phinew is then nx-1 by ny-1, as you get from your function.
If you want to force your function to return nx by ny, put phinew = zeros(nx,ny); at the start of the function, or set the last column and row to whatever you want them to be.
EDIT: Responding you your comment "why [does the RHS of the main assignment output] a 48x48 matrix? Directly before the command is run phiold, phinew and poissonf are all 50x50."
I don't think poissonf is 50x50: that would lead to the error Matrix dimensions must agree, because poissonf is being added to the rest of the expression which is part of phiold, so I'll ignore poissonf in the following.
The RHS is always ny-2 by nx-2, even on the first iteration. You can see this by assigning the RHS to an intermediate variable, e.g. phipiece = ... and checking size(phipiece). The reason phinew (if created anew) is 49x49 is because it is assigned to (2:ny-1,2:nx-1), which will create a ny-1 by nx-1 matrix and leave the first row and column as zero.
If you use phinew = zeros(nx,ny); first, then the first and last rows and columns are left as zero.

In octave, error: for x^A, A must be a square matrix. Use .^ for elementwise power

In Octave I defined a function in a separate file square.m
function y = square(x)
y = x^2;
endfunction
In other file script.m I have
disp("Hello World 2");
fplot( #(x) square(x),[-1 1])
And I get
error: for x^A, A must be a square matrix. Use .^ for elementwise power.
Also if I try
y = x.^2;
inside the function I get the exact same message
The reason you're getting that error is because fplot is passing the range you specified all at once as a vector, treating your function as a vectorised function, expecting a vector input and returning a vector output.
You can confirm this by turning "debug on error" to true, by doing debug_on_error(true), run the offending line, and inspect x.
Therefore, inside your function, things go wrong, because you're trying to get the square of a vector, which is an illegal operation (mathematically speaking).
Converting your function to y = x.^2 should work in this case, because you'd be converting each element of the vector to its square, which is what you want. But obviously, simply changing ^ to .^ might not work for every problem.
In general, it's better to create your own 'range' and 'outputs' and plot them directly using plot; this gives you far more control, and you can inspect the inputs and outputs first to ensure you're plotting what you think you're plotting.
Welcome to StackOverflow!
I have just tried your code on https://octave-online.net/ (no need to create an account nor even the files).
The second version works "as expected": y = x .^ 2; inside the function.
Make sure you saved the file after the modification?

error: 'y' undefined near line 8 column 12 error: called from computeCost at line 8 column 3

error: 'y' undefined near line 8 column 12
error: called from computeCost at line 8 column 3
Here is my code:
1;
function J = computeCost(X, y, theta)
%COMPUTECOST Compute cost for linear regression
% J = COMPUTECOST(X, y, theta) computes the cost of using theta as the
% parameter for linear regression to fit the data points in X and y
% Initialize some useful values
m = length(y); % number of training examples
% You need to return the following variables correctly
J = 0;
% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost of a particular choice of theta
% You should set J to the cost.
J = sum(( X * theta - y ) .^2 )/( 2 * m );
% =========================================================================
end
I am guessing it's an error from Coursera ML course assignment. I think you are trying to run the file which contains the implementation of function computeCost(X, y, theta), not the file which calls the computeCost(,,) function with values of X, y, theta. This is why you are getting the error as you aren't providing y.
Run the file which is calling computeCost() function, not the file which contains the implementation of computeCost() function.
That is:
For Week2 Assignment 1: Run ex1.m file
For Week3 Assignment 2: Run ex2.m file
There are two things happening here. First you are defining your function dynamically as opposed to in its own file; not sure why you would prefer that.
Second, after having defined this computeCost function, you are calling it from a context where you did not pass a y argument (or presumably, you didn't pass any arguments to it, and y happens to be the first one detected as missing inside the function).
Since this is a cost function and your code looks suspiciously like code from Andrew Ng's Machine Learning course on Coursera, I am going to go out on a limb here and guess that you called computeCost from something else that was supposed to use it as a cost function to be optimised, e.g. fminunc. Typically functions like fminunc expect a function handle as an argument, but they expect a very specific function handle too. If you look at the help of fminunc, it states that:
FCN should accept a vector (array) defining the unknown variables,
and return the objective function value, optionally with gradient.
Therefore, if you want to pass a function that is to be computed with three arguments, you need to "wrap" it into your own handle, which you can define on the spot, e.g. #(x) computeCost(x, y, t) (assuming 'y' and 't' exist already).
So, I'm guessing that instead of calling fminunc like so: fminunc( #(x) computeCost(x, y, t),
you probably called it like so: fminunc( #computeCost )
or even like so: fminunc( computeCost ) (which evaluates the function first, rather than pass a function handle as an argument).
Basically, go back to the code given to you by coursera, or read the notes carefully. You're calling things the wrong way.
Actually, you are trying to run a function and you can't run it until you provide the desired no. of parameters. Doing so, you may encounter the following error:
computeCost error: 'y' undefined near line 7 column 12
error: called from computeCost at line 7 column 3
As you see, here I'm calling this function without passing any argument.
SOLUTION:
You can test your code by running 'ex1' script. After that submit your work by calling 'submit' script.

input element 1 by 1 from other function w/o for loop

I have a function that calculates an array of numbers (randparam) that I want to input element by element into another function that does a simulation.
For example
function [randparam] = arraycode
code
randparam = results of code
% randparam is now a 1x1001 vector.
end
next I want to input randparam 1 by 1 into my simulation function
function simulation
x = constant + constant * randparam + constant
return
end
What makes this difficult for me is because of the return command in the simulation function, it only calculates one step of the equation x above, returns the result into another function, call it integrator, and then the integrator function will call simulation function again to calculate x.
so the integrator function might look like
function integrator (x)
y = simulation(x) * 5
u = y+10
yy = simulation(x) * 10 + u
end
As you can see, integrator function calls the simulation function twice. which creates two problems for me:
If I create a for loop in the simulation function where I input element by element using something like:
for i = 1:100
x = constant + constant * randparam(i) + constant
return
end
then every time my integrator function calls my simulation function again, my for loop starts at 1 all over again.
2.If I some how kept i in my base workspace so that my for loop in my simulation function would know to step up from 1, then my y and yy functions would have different x inputs because as soon as it would be called the second time for yy, then i would now be i+1 thanks to the call due to y.
Is there a way to avoid for loops in this scenario? One potential solution to problem number two is to duplicate the script but with a different name, and have my for loop use a different variable, but that seems rather inefficient.
Hope I made this clear.
thanks.
First, if you generically want to apply the same function to each element of an array and there isn't already a built in vectorized way to do it, you could use arrayfun (although often a simple for loop is faster and more readable):
%# randparam is a 1x1001 vector.
%#next I want to input randparam 1 by 1 into my simulation function
function simulation
x = constant + constant * randparam + constant
return
end
(Note: ask yourself what this function can possibly be doing, since it isn't returning a value and MATLAB doesn't pass by reference.) This is what arrayfun is for: applying a function to each element of an array (or vector, in this case). Again, you should make sure in your case that it makes sense to do this, rather than an explicit loop.
function simulation(input_val)
#% your stuff
end
sim_results = arrayfun( #simulation, randparam);
Of course, the way you've written it, the line
x = constant + constant*randparam + constant;
can (and will) be done vectorized - if you give it a vector or matrix, a vector or matrix will be the result.
Second it seems that you're not clear on the "scope" of function variables in MATLAB. If you call a function, a clean workspace is created. So x from one function isn't automatically available within another function you call. Variables also go out of scope at the end of a function, so using x within a function doesn't change/overwrite a variable x that exists outside that function. And multiple invocations of a function each have their own workspace.
What's wrong with a loop at the integrator level?
function integrator (x)
for i=1:length(x)
y = simulation(x(i)) * 5
u = y+10
yy = simulation(x(i)) * 10 + u
end
And pass your entire randparm into integrator? It's not clear from your question whether you want simulation to return the same value when given the same input, or whether you want it step twice with the same input, or whether you want a fresh input on every call. It is also not clear if simulation keeps any internal state. The way you've written the example, simulation depends only on the input value, not on any previous inputs or outputs, which would make it trivial to vectorize. If we're all missing the boat, please edit your question with more refined example code.

matlab function which is a function of an intergral

I need to write my own function which has the form f(x,y)=Integrate(g(x,y,z),z from 0 to inf). so the code I used was:
function y=f(x,y)
g=#(z)exp(-z.^2)./(z.^x).*(z.^2+y.^2).^(x/2);% as a function of x,y and z
y=quadgk(g,0,inf)
and if I call it for a single value like f(x0,y0), it works but if I try to calculate something like f([1:10],y0), then the error message says that there is something wrong with the times and dimension. In principle I can use for loops but then my code slows down and takes forever. Is there any help I can get from you guys? or references?
I'm trying to avoid the for loop since in matlab it's much faster to use matrix computation than to use for loop. I wonder if there is any trick that I can take advantage of this feature.
Thanks for any help in advance,
Lynn
Perhaps you can try to transpose the interval, creating row based values instead of column based f([1:10]',y0). Otherwise something in your function might be wrong, for example to get x^y to work with lists as input, you have to prefix with a dot x.^y. The same for mulitply and division I think..
If loop is no problem for you, you should do something like:
function y2=f(x,y)
y2=zeros(size(x));
for n=1:numel(x)
g=#(z)exp(-z.^2)./(z.^x(n)).*(z.^2+y.^2).^(x(n)/2);% as a function of x,y and z
y2(n)=quadgk(g,0,inf)
end
The problem here is that quadk itself uses vectors as argument for g. Then you have in g somethink like z.^x, which is the power of two vectors that is only defined if z and x have the same dimension. But this is not what you want.
I assume that you want to evaluate the function for all arguments in x and that the output vector has the same dimension as x. But this does not seem to be possible since even this simple example
g=#(x)[x;x.^2]
quad(g,0,1)
does not work:
Error using quad (line 79)
The integrand function must return an output vector of the same length as the
input vector.
A similar error shows when using quadgk. The documentation also says that this routine works only for scalar functions and this is not surprising since an adaptive quadrature rule would in general use different points for each function to evaluate the integral.
You have to use quadvinstead, which can integrate vector valued functions. But this gives wrong results since your function is integrated in the interval [0,\infty).