Dynamic Naming of Matlab Function - function

I currently have a MATLAB function that looks like this:
function outfile=multi_read(modelfrom,modelto,type)
models=[modelfrom:1:modelto];
num_models=length(models);
model_path='../MODELS/GRADIENT/'
for id=1:num_models
fn=[model_path num2str(models(id)) '/']; %Location of file to be read
outfile=model_read(fn,type); %model_read is a separate function
end
end
The idea of this function is to execute another function model_read for a series of files, and output these files to the workspace (not to disk). Note that the output from model_read is a structure! I want the function to save the file to the workspace using sequential names, similar to typing:
file1=multi_read(1,1,x)
file2=multi_read(2,2,x)
file3=multi_read(3,3,x)
etc.
which would give file1, file2 and file3 in the workspace, but instead by recalling the command only once, something like:
multi_read(1,3,x)
which would give the same workspace output.
Essentially my questions is, how do I get a function to output variables with multiple names without having to recall the function multiple times.

As suggested in the comment I would try this approach which is more robust, at least IMHO:
N = tot_num_of_your_files; %whatever it is
file = cellfun(#(i)multi_read(i,i,x),mat2cell(1:N,1,ones(1,N)),...
'UniformOutput' , false); %(x needs to be defined)
You will recover objects by doing file{i}.

Here is code to do what you ask:
for i = 1:3
istr=num2str(i)
line = ['file' istr '= multi_read(' istr ', ' istr ', x)']
eval(line)
end
Alternatively, here is code to do what you should want:
for i = 1:3
file{i} = multi_read(i,i,x)
end

Related

Rerun the program after it ends automatically in octave

Using OCTAVE only...
How can I rerun the code automatically after it ends. Like I want to make a program in which if the input is incorrect value it will end the program and rerun again.
I tried that by writting there a file name and it works but this will only work until I change my file name.
You can wrap your main script in a wrapper script which performs the loop.
% In main.m
disp( 'Hello from main' );
Question = "Do you want to rerun? ";
Response = input( Question, 's');
% in wrapper.m
Response = 'yes';
while strcmp( Response, 'yes' )
main
end

Error : 'x' undefined

I got a problem with running Octave function (ODE), I've tried already present solutions for this problem but nothing is working. I've also tried by saving my filename as egzamin.m but it too not worked.
Code from octave :
function dx=egzamin(x,t)
dx=zeros(4,1);
b=0;
g=9.81;
x1=x(1);
y1=x(2);
Vx=x(3);
Vy=x(4);
dx(1)=Vx;
dx(2)=Vy;
dx(3)=-b*Vx*sqrt(Vx.^2+Vy.^2);
dx(4)=-b*Vy*sqrt(Vx.^2+Vy.^2)-g;
endfunction
N=mod(291813,100);
x1=0;
y1=0;
Vx=20+N;
Vy=20+N;
t=0:0.01:500;
sol=lsode("egzamin",[x1,y1,Vx,Vy],t);
plot(sol(:,1),sol(:,2))
The error is :
error: 'x' undefined near line 5 column 4
error: called from
egzamin at line 5 column 3
Since the file starts with function, it is not a script file,
as explained in the doc:
Unlike a function file, a script file must not begin with the keyword
function
Add any statement (even dummy like 1;) before the function line to get a script file.
# dummy statement to get a script file instead of a function file
1;
function dx=egzamin(x,t)
g = 9.81;
Vx = x(3);
Vy = x(4);
dx = [Vx, Vy, 0, -g];
endfunction
N=mod(291813,100);
x1=0;
y1=0;
Vx=20+N;
Vy=20+N;
t=0:0.01:500;
sol=lsode("egzamin",[x1,y1,Vx,Vy],t);
plot(sol(:,1),sol(:,2))
A very clear explanation of what's going on is given here.
You need to save the function (thus from function to endfunction and naught else) as egzamin.m, and then execute the rest of the code in a script or at the command line. Alternatively, provided Octave does that the same as what MATLAB does nowadays, first put your script (N=(..) to plot()) and then the function.
This is necessary since you are defining your function first, so it doesn't have any inputs yet, as you don't define them until later. The function needs to have its inputs defined before it executes, hence you need to save your function separately.
You can of course save your "script" bit, thus everything which is currently below your function declaration, as a function as well, simply don't give it in- and outputs, or, set all the input parameters here as well. (Which I wouldn't do as it's the same as your
egzamin then.) e.g.
function []=MyFunc()
N=mod(291813,100);
x1=0;
y1=0;
Vx=20+N;
Vy=20+N;
t=0:0.01:500;
sol=lsode("egzamin",[x1,y1,Vx,Vy],t);
plot(sol(:,1),sol(:,2))
endfunction

How do I set a function to a variable in MATLAB

As a homework assignment, I'm writing a code that uses the bisection method to calculate the root of a function with one variable within a range. I created a user function that does the calculations, but one of the inputs of the function is supposed to be "fun" which is supposed to be set equal to the function.
Here is my code, before I go on:
function [ Ts ] = BisectionRoot( fun,a,b,TolMax )
%This function finds the value of Ts by finding the root of a given function within a given range to a given
%tolerance, using the Bisection Method.
Fa = fun(a);
Fb = fun(b);
if Fa * Fb > 0
disp('Error: The function has no roots in between the given bounds')
else
xNS = (a + b)/2;
toli = abs((b-a)/2);
FxNS = fun(xns);
if FxNS == 0
Ts = xNS;
break
end
if toli , TolMax
Ts = xNS;
break
end
if fun(a) * FxNS < 0
b = xNS;
else
a = xNS;
end
end
Ts
end
The input arguments are defined by our teacher, so I can't mess with them. We're supposed to set those variables in the command window before running the function. That way, we can use the program later on for other things. (Even though I think fzero() can be used to do this)
My problem is that I'm not sure how to set fun to something, and then use that in a way that I can do fun(a) or fun(b). In our book they do something they call defining f(x) as an anonymous function. They do this for an example problem:
F = # (x) 8-4.5*(x-sin(x))
But when I try doing that, I get the error, Error: Unexpected MATLAB operator.
If you guys want to try running the program to test your solutions before posting (hopefully my program works!) you can use these variables from an example in the book:
fun = 8 - 4.5*(x - sin(x))
a = 2
b = 3
TolMax = .001
The answer the get in the book for using those is 2.430664.
I'm sure the answer to this is incredibly easy and straightforward, but for some reason, I can't find a way to do it! Thank you for your help.
To get you going, it looks like your example is missing some syntax. Instead of either of these (from your question):
fun = 8 - 4.5*(x - sin(x)) % Missing function handle declaration symbol "#"
F = # (x) 8-4.5*(x-sin9(x)) %Unless you have defined it, there is no function "sin9"
Use
fun = #(x) 8 - 4.5*(x - sin(x))
Then you would call your function like this:
fun = #(x) 8 - 4.5*(x - sin(x));
a = 2;
b = 3;
TolMax = .001;
root = BisectionRoot( fun,a,b,TolMax );
To debug (which you will need to do), use the debugger.
The command dbstop if error stops execution and opens the file at the point of the problem, letting you examine the variable values and function stack.
Clicking on the "-" marks in the editor creates a break point, forcing the function to pause execution at that point, again so that you can examine the contents. Note that you can step through the code line by line using the debug buttons at the top of the editor.
dbquit quits debug mode
dbclear all clears all break points

MATLAB How to pass an Array from my base workspace to a function

I have been on a few forum posts now reading through trying to figure this out but I can't seem to crack it. To summarise my function I have 2 arrays searchDates and searchIds. Now all I want to do is do a comparison on the size of one of the elements to the other array and this is the code I have so far but I don't know how to carry over searchDates and searchIds
function a = compare(userNum)
if size(searchDates{1,userNum},2) == size(searchIds{1,userNum},2)
x = true
else x = false
end
TL;DR I just need to know how to pass from my BASE WORKSPACE to my FUNCTION WORKSPACE the two arrays from above.
Cheers!
You can rewrite your function so that you can directly pass the arrays:
function a = compare(userNum,searchDates,searchIds)
if size(searchDates{1,userNum},2) == size(searchIds{1,userNum},2)
x = true
else x = false
end
then call compare with your workspace variables in the 2nd and 3rd argument.
If for some reason you need compare to only have one argument, you can create an anonymous function in your workspace by using the above function compare and writing:
anon_compare = #(userNum) compare(userNum,searchDates,searchIds)
Provided searchDAtes and searchIds are in your workspace, you will now have the function anon_compare, which you can use directly as anon_compare(foo).
For more on anonymous functions (an important aspect of several MATLAB programming techniques) you can read this post.

Lua - How do I use a function from another script?

I've been looking around and I have not been able to find anything that has worked for me. I'm starting to learn more Lua and to start off I'm making a simple calculator. I was able to get each individual operation onto separate programs, but when I try to combine them I just can't get it to work. My script as it is now is
require "io"
require "operations.lua"
do
print ("Please enter the first number in your problem.")
x = io.read()
print ("Please enter the second number in your problem.")
y = io.read()
print ("Please choose the operation you wish to perform.")
print ("Use 1 for addition, 2 for subtraction, 3 for multiplication, and 4 for division.")
op = io.read()
op = 1 then
function addition
op = 2 then
function subtraction
op = 3 then
function multiplication
op = 4 then
function division
print (answer)
io.read()
end
and my operations.lua script is
function addition
return answer = x+y
end
function subtraction
return answer = x-y
end
function multiplication
return answer = x*y
end
function division
return answer = x/y
end
I've tried using
if op = 1 then
answer = x+y
print(answer)
if op = 2 then
answer = x-y
print(answer)
and I did that completing each operation. But it doesn't work. I can't even get the error code that it's returning because it closes so fast. What should I do?
In your example, make these changes: You require operations.lua without the extension. Include parameters in your operations function definitions. Return the operation expression directly versus returning a statement like answer = x+y.
All together:
Code for operations.lua
function addition(x,y)
return x + y
end
--more functions go here...
function division(x,y)
return x / y
end
Code for your hosting Lua script:
require "operations"
result = addition(5,7)
print(result)
result = division(9,3)
print(result)
Once you get that working, try re-adding your io logic.
Keep in mind that as it's coded, your functions will be defined globally. To avoid polluting the global table, consider defining operations.lua as a module. Take a look at the lua-users.org Modules Tutorial.
The right if-then-else syntax:
if op==1 then
answer = a+b
elseif op==2 then
answer = a*b
end
print(answer)
After: please check the correct function-declaration syntax.
After: return answer=x+y is incorrect. If you want set answer's value, set without return. If you want return the sum, please use return x+y.
And I think you should check Programming in Lua.
First of all, learn to use the command line so you can see the errors (on Windows that would be cmd.exe).
Second, change the second line to require("operations"). The way you did it the interpreter expects a directory operations with an underlying script lua.lua.