Calling functions & scripts in Matlab/Octave - matlab

How do call a script to a function and vica versa in Matlab/Octave?
function mean_DNA_Microarray = Calc_mean_DNA_Microarray(M)
M = DNA_Microarray
mean_DNA_Microarray = M - ones(5,25)*mean(M(:,25))
end
The response is
error: invalid call to script
C:\Users\Nacho\Documents\Matlab\DNA_Microarray.m error: called from:
error: C:\Users\Nacho\Documents\Matlab\Calc_mean_DNA_Microarray.m at
line 3, column 3
Now this will work if I call DNA_Microarray a function, but the problem requires that it remain as a script.

First of all, you are not defining your function correctly, as the function does not know what M is (unless it is a global vairable, but I doubt so).
In ANY programming language, you need to tell a function which variables it is going to work with. This is not Matlab specific. In Matlab you will do it so:
function mean_DNA_Microarray = Calc_mean_DNA_Microarray(M) % Look! we are telling him what M is!
mean_DNA_Microarray = M - ones(5,25)*mean(M(:,25))
end
Then you want to all the function from somewhere else you would need to just type its name and pass in the arguments, in this case what inside the function is going to be called M
clear;
clc;
% Test code
Mnameoutofthefunction=rand(100,100);
DNAmean = DNA_Microarray(Mnameoutofthefunction); % here we are calling it!
Remember to save the function as functionname.m , in your case DNA_Microarray.m , else Matlab wont know which one it is.
But I HIGHLY recommend you to read a book about Matlab or just about programming in general, as it seems like you could benefit from some basic introduction.
Following #am304 suggestion, here you can find nice tutorials:
http://www.mathworks.co.uk/academia/student_center/tutorials/
EDIT What you want to do is create a function as follows:
function mean_DNA_Microarray = Calc_mean_DNA_Microarray(M) % Look! we are telling him what M is!
mean_DNA_Microarray = M - ones(5,25)*mean(M(:,25))
end
And then, inside your function DNA_Microarray call Calc_mean_DNA_Microarray with the input M

Related

Write recursive sub-functions and non-recursive sub-functions in Matlab

I'm newbie to Matlab
I have an assignment :
Legendre polynomial Pn(x), n=0,1,2,. . . The recursive formula of is
Write recursive sub-functions and non-recursive sub-functions separately to find the value of the Legendre polynomial function
This is my code :
function P =Legendre(n,x)
syms x;
n = input('n=');
if n==0
P=1;
elseif n==1
P=x;
elseif n>=2
P=((2*n-1)/n)*x*Legendre(n-1)-((n-1)/n)*Legendre(n-2);
end
end
But I get an error message:
Unrecognized function or variable 'Legendre'.
Error in ti4 (line 9)
P=((2*n-1)/n)*x*Legendre(n-1)-((n-1)/n)*Legendre(n-2);
Sorry for the stupid question. Can anyone help me? Thank u so much
A few things are probably going on here.
File name needs to match function name (for the primary function)
In your case, the filename needs to be Legendre.m.
Symbolic toolbox OR do you want an answer
for most uses of this function, I would leave two full inputs, just as you have them. Bur I would remove the first two lines completely.
As it is, the first two lines will break your inputs. The value for n is reset by the input function. I'm actually not sure what happens when you declare an existing variable x, to a sym.
Input consistency
You are setting up a function with two inputs, named n and x. But when you maek your recursive calls you only pass in one variable. The easiest thing to do here is simply keep passing n in as the first input.
(Right now, you are trying to pass in x in the recursive calls, but it will be interpreted as n.)

"Undefined" error for rewriting but not redefining an already defined function

This works (plots an "empty" figure):
function testme
plot(1)
This works (returns 1):
function testme
plot = #(x)x;
plot(1)
This does not (Error: "Undefined function or variable 'plot'."):
function testme
if 0
plot = #(x)x;
end
plot(1)
What's going on here? Why does rewriting but not redefining an already defined function render the function undefined?
Note 1: this is not specific for builtin functions; the following code returns the same error:
function testme
if 0
myfun = #(x)x;
end
myfun(1)
function x=myfun(x)
x=x*2;
Note 2: the error occurs in a function environment, not in a script; the following code does not return an error (and plots the same empty figure as in the first example):
if 0
plot = #(x)x;
end
plot(1)
Update: For the interested reader, here is some background information
on my original problem. The above examples are just minimum working
samples to illustrate the main issue (which indeed feature dead end if
statements). In practice, I was trying to make a function useable for
colleagues who did not have certain library/toolbox functions
available, by overwriting those functions for simplified custom ones
if they did not exist, as a quick fix. In particular, it concerned
imdilate (and imerode). The function looked something like the
following:
function [myoutputs] = myfunction(myinputs)
% if the images toolbox is not available, use the following simplified
% replacement function
if ~exist('imdilate','file')
imdilate = #(IM,SE)vecdilate(IM,SE);
end
%% The original function goes here, which uses a lot of imdilate(IM,SE).
%% local functions
function M = vecdilate(IM,SE)
% simplified version of imdilate (can only process 1-D vertical arrays)
nSE = size(SE);
nIM = size(IM);
SE = logical(SE); % make logical if it isn't yet
% copy and shift xth column x down. new border entries are 0:
M = repmat([IM;zeros(nSE)],nSE);
M = M(1:end-nSE(1));
M = reshape(M,[size(M,1)/nSE(1) nSE(1)]);
% shrink back to column by taking max of every row:
M = max(M(:,SE),[],2);
M = M(ceil(nSE(1)/2)-1+(1:nIM(1))); % clip to obtain correct size
You might see that the replacement function covers some
functionality of imdilate, but not all, and it might not be as
efficient. The purpose simply was to use function A if it was available, and
function B if it was not. To my surprise however, the former case
returned an error, which eventually resulted in this question. For your interest, I solved the practical problem by renaming the function in the
original code, and by using an if/else statement:
function [myoutputs] = myfunction(myinputs)
% if the images toolbox is not available, use the following simplified
% replacement function
if ~exist('imdilate','file')
mydilate = #(IM,SE)vecdilate(IM,SE);
else
mydilate = #(IM,SE)imdilate(IM,SE);
end
%% The original function goes here, which uses a lot of mydilate(IM,SE).
%% local functions
function M = vecdilate(IM,SE)
etc. etc. etc.
Just-in-time-compilation (JIT) does not mean that there is no compilation and that every line is interpreted separately, so you can still mess with the code;)
The error would also appear if you use a not-defined function, where you woun't even expect the code to run, like
function [] = test()
if false
a = #(x)x;
end
a(1)
end
Scripts are stored command line entries, i.e. the compiler has no choice but to handle every line separately (you may want to think of it as a keyboard macro).
Functions in contrast are encapsulated pieces of code. The compiler (in general) does not expect anything unknown + it thinks that this encapsulated piece of code might be reused. Therefore, it makes sure to do a proper job compile all code once beforehand (if the compile would do this all the time, it is called ahead-of-time compilation).
This becomes in particular obvious when your clear the variables in between:
function [] = test()
if false
plot = #(x)x;
else
clear all % clear vs clear all
end
plot(1)
end
(Note that clear clears all variables but clear all would also clear excising code (see MATLAB Execution Engine))
Have a look at this interesting blog post from Loren
MATLAB provides the best of both worlds by compiling MATLAB code on-the-fly, or just-in-time. MATLAB code is compiled whether it be in classes, functions, scripts, or simply at the command line. There is no explicit compile step for the user to initiate and MATLAB code can be executed in blocks as small as one line at a time. The MATLAB JIT compiler generates native machine level code that is optimized for the MATLAB code being executed and for the specific hardware platform.
Anyway, you should not write dead ends in your code or overwrite (native) functions. It is good to use function handles to overcome this problem, but make sure that you define it for all cases
function [] = test()
if false % dead end definition
fnc = #(x)x;
else
fnc = #plot;
end
fnc(1)
end

General Newton Method Function File Matlab

I have very limited knowledge on Matlab and I'm trying to make a general Newton Raphson function but every time it comes up with an error saying there are not enough input arguments. My code needs three inputs, f (the function), c0 (the initial guess) and n (the number of steps). This is my code so far:
function [c] = Q3(f,c0,n)
for i=1:n
c(0)=c0;
f=f(x);
fp=diff(f,x);
c(i)=c(i-1)-subs(f,x,c(i-1))/subs(fp,c(i-1));
end
disp(c)
I have this function written in a script file
g=#(x)(sin((pi.*x)/2)+(1/x)-(10.*x));
I then put this into the command window [c]=Q3(g(x),1,n) hoping it would work but obviously my code needs work.
Thanks
This should do the trick, the function g is defined as you stated:
g=#(x)(sin((pi.*x)/2)+(1/x)-(10.*x));
but also you should define n and c0, for example:
clearvars
g=#(x)(sin((pi.*x)/2)+(1/x)-(10.*x));
n=10
c0=1
c=Q3(g,c0,n)
And in another file you write the function for NR:
function [c] = Q3(f,c0,n)
h=1e-4;
c(1)=c0;
for i=1:n
g=f(c(i));
gp=(f(c(i)+h)-f(c(i)-h))/(2*h)
c(i+1)=c(i)-g/gp
end
disp(c)
In this case I choose h=1e-4 for the numerical derivative approximation, but you can change it. I suggest h<1e-2.

MATLAB Using fzero - returns error

I'm trying to use the MATLAB function fzero properly but my program keeps returning an error message. This is my code (made up of two m-files):
friction_zero.m
function fric_zero = friction_zero(reynolds)
fric_zero = 0.25*power(log10(5.74/(power(reynolds,0.9))),-2);
flow.m
function f = flow(fric)
f = 1/(sqrt(fric))-1.873*log10(reynolds*sqrt(fric))-233/((reynolds*sqrt(fric))^0.9)-0.2361;
f_initial = friction_zero(power(10,4));
z = fzero(#flow,f_initial)
The goal is to return z as the root for the equation specified by f when flow.m is run.
I believe I have the correct syntax as I have spent a couple of hours online looking at examples. What happens is that it returns the following error message:
"Undefined function or variable 'fric'."
(Of course it's undefined, it's the variable I'm trying to solve!)
Can someone point out to me what I've done wrong? Thanks
EDIT
Thanks to all who helped! You have assisted me to eventually figure out my problem.
I had to add another file. Here is a full summary of the completed code with output.
friction_zero.m
function fric_zero = friction_zero(re)
fric_zero = 0.25*power(log10(5.74/(power(re,0.9))),-2); %starting value for fric
flow.m
function z = flow(fric)
re = power(10,4);
z = 1/(sqrt(fric))-1.873*log10(re*sqrt(fric))-233/((re*sqrt(fric))^0.9)-0.2361;
flow2.m
f_initial = friction_zero(re); %arbitrary starting value (Reynolds)
x = #flow;
fric_root = fzero(x,f_initial)
This returns an output of:
fric_root = 0.0235
Which seems to be the correct answer (phew!)
I realised that (1) I didn't define reynolds (which is now just re) in the right place, and (2) I was trying to do too much and thus skipped out on the line x = #flow;, for some reason when I added the extra line in, MATLAB stopped complaining. Not sure why it wouldn't have just taken #flow straight into fzero().
Once again, thanks :)
You need to make sure that f is a function in your code. This is simply an expression with reynolds being a constant when it isn't defined. As such, wrap this as an anonymous function with fric as the input variable. Also, you need to make sure the output variable from your function is z, not f. Since you're solving for fric, you don't need to specify this as the input variable into flow. Also, you need to specify f as the input into fzero, not flow. flow is the name of your main function. In addition, reynolds in flow is not defined, so I'm going to assume that it's the same as what you specified to friction_zero. With these edits, try doing this:
function z = flow()
reynolds = power(10,4);
f = #(fric) 1/(sqrt(fric))-1.873*log10(reynolds*sqrt(fric))-233/((reynolds*sqrt(fric))^0.9)-0.2361;
f_initial = friction_zero(reynolds);
z = fzero(#f, f_initial); %// You're solving for `f`, not flow. flow is your function name
The reason that you have a problem is because flow is called without argument I think. You should read a little more about matlab functions. By the way, reynolds is not defined either.
I am afraid I cannot help you completely since I have not been doing fluid mechanics. However, I can tell you about functions.
A matlab function definition looks something like this:
function x0 = f(xGuess)
a = 2;
fcn =#(t) a*t.^3+t; % t must not be an input to f.
disp(fcn);
a = 3;
disp(fcn);
x0 = fsolve(fcn1,xGuess); % x0 is calculated here
The function can then ne called as myX0 = f(myGuess). When you define a matlab function with arguments and return values, you must tell matlab what to do with them. Matlab cannot guess that. In this function you tell matlab to use xGuess as an initial guess to fsolve, when solving the anonymous function fcn. Notice also that matlab does not assume that an undefined variable is an independent variable. You need to tell matlab that now I want to create an anonymous function fcn which have an independent variable t.
Observation 1: I use .^. This is since the function will take an argument an evaluate it and this argument can also be a vector. In this particulat case I want pointwise evaluation. This is not really necessary when using fsolve but it is good practice if f is not a matrix equation, since "vectorization" is often used in matlab.
Observation 2: notice that even if a changes its value the function does not change. This is since matlab passes the value of a variable when defining a function and not the variable itself. A c programmer would say that a variable is passed by its value and not by a pointer. This means that fcn is really defined as fcn = #(x) 2*t.^3+t;. Using the variable a is just a conveniance (constants can may also be complicated to find, but when found they are just a value).
Armed with this knowledge, you should be able to tackle the problem in front of you. Also, the recursive call to flow in your function will eventuallt cause a crash. When you write a function that calls itself like this you must have a stopping criterium, something to tell the program when to stop. As it is now, flow will call ifself in the last row, like z = fzero(#flow,f_initial) for 500 times and then crash. Alos it is possible as well to define functions with zero inputs:
function plancksConstant = h()
plancksConstant = 6.62606957e−34;
Where the call h or h() will return Plancks constant.
Good luck!

MATLAB symbolic variables couldn't be used in nested function

I have a MATLAB function to solve a Inertia Tensor , and I have a nested function in my program . All the variables in it are symbolics but it told me
“Error using assignin: Attempt to add ”x“ to a static workspace”
and I don't understand why this happens . Here is my test.m code:
function test
syms x y z
f=x
f1=f+1
f2=f1^2
function r=test2
r=f2^3;
end
f3=test2
end
After searching this web-forum I have found some answers . But at the same time I just don't understand it
Andrew Janke explianed it like this : While syms A may look like a static variable declaration, it isn't. It's just a regular function call. It's using Matlab's "command" invocation style to look like syntax, but it's really equivalent to syms('a', 'b', 'c').
on this page : Matlab: "Error using assignin: Attempt to add "c" to a static workspace"
what does static variable mean ?
I also search the HELP doc and it said :In functions and scripts, do not use syms to create symbolic variables with the same names as MATLAB® functions. For these names MATLAB does not create symbolic variables, but keeps the names assigned to the functions.
I only know syms x to create a symbolic variable in the workspace but why does the documentation say MATLAB does not create ?
'Static' means fixed, 'workspace' is what Matlab calls the places where all of its variables are stored. For non-nested functions the workspace starts off as empty when Matlab is at the beginning of the function; as Matlab continues through function's lines of code it continuously add more variables to the workspace.
For functions with a nested function, Matlab first parses the function to see what variable will be created (it specifically looks for x = type lines), then it creates all of these variables (with value as 'unassigned'), and then only does it start to run through the code; but while running through the code, it can never create a new variable.
This is why the code
function TestNestedFunction
syms x;
function Nested()
end
end
generates an error, there is no x = to tell it to pre-create the unassigned variable x at the start of the code. It fails at syms x;, as that line tries to create a new variable x, which fails as it may not.
This is also why the following code runs
function TestNestedFunction
syms x;
x = x;
function Nested()
end
end
it sees the x = and then pre-creates x. (This is why your example of adding [x, y, z] = deal([]); also works).
You can test this with a break point at the beginning of simple non-nested function and a simple nested function. Just run it step by step.
This code works:
function test
x=sym('x')
y=sym('y')
z=sym('z')
f=x
f1=f+1
f2=f1^2
function r=test2
r=f2^3;
end
f3=test2
end
I think the pages you found are quite clear.
You need to declare the variables one by one and use:
x = sym('x')
Otherwise syms will try to assign the values into a workspace where this is not allowed.