Matlab Function and Input - matlab

function area = traparea(a,b,h)
% traparea(a,b,h) Computes the area of a trapezoid given
% the dimensions a, b and h, where a and b
% are the lengths of the parallel sides and
% h is the distance between these sides
% Compute the area, but suppress printing of the result
area = 0.5*(a+b)*h;
This is just an example. I would like to know how to declare the values suppose a=5,b=4,h=8 in a seperate .m file and calling it into original function ie, traparea, using .in statement?
for example
.in a=5
like that
Please help

If I understand, you want to create a script file. Create a filename called "myscript.m" (pick any name you like), and place it in the same folder as "traparea.m" is located. Then, in the file "myscript.m", put the following:
a = 5;
b = 4;
h = 8;
result = traparea(a,b,h) % this is one way to show the result
fprintf('my result is %f\n', result); % this is another way to display the result
Once you have created the two files "myscript.m", and "traparea.m", you just type "myscript" at the command line.

Related

How can I loop through and process files from a directory individually?

I'm trying to write a function that iteratively loops through a bunch of .txt files in a directory and processes them individually. After a file has been processed I would like to plot output variables, then on the next iteration plot the new variables on the same graph. My code is shown below however does not seem to be working, it returns a 'output argument 'output1' (and maybe others) not assigned during call to function2.
Currently my code looks something like this:
function [output1, output2, fig] = Processing(Folder_1,Folder_2,Folder_3)
%% Read in all the Data
% Initialise Loop to process each file independently
for i = 1 : length(Text_Files1)
Sorted_Index1 = Indices1(i);
Path1 = fullfile(Folder_1,Text_Files1(Sorted_Index1).name);
Table1 = readtable(Path1);
Sorted_Index2 = Indices2(i);
Path2 = fullfile(Folder_2,Text_Files2(Sorted_Index2).name);
Table2 = readtable(Path2);
Sorted_Index3 = Indices3(i);
Path3 = fullfile(Folder_3,Text_Files3(Sorted_Index3).name);
Table3 = readtable(Path3,'Delimiter',';');
%% Process Data through the Loop
[HR] = function1(processed_data)
[output1 output2] = function2(HR, Time);
hold on
fig = figure('Visible', false);
subplot(10,10,1:90)
plot(output2, output1, 'Color', [0.92 0.47 0.44], 'LineWidth', 1.5);
end
end
%% Function 2:
function [output1, output2] = function2(t, y, z)
segment = 1:z:max(y);
% Iterate through each time segment and calculate average t value
for x = 1:length(segment)-1
SegmentScores = find(y > segment(x) & ...
y < segment(x+1));
output1(x) = mean(y(SegmentScores));
output2(x) = Segment(x+1);
end
end
The problem is that you're calling function2(HR, Time) with two inputs, while it needs three function2(t, y, z).
For that reason, I'm assuming that inside function2 segment is an empty array, and thus the loop for x = 1:length(segment) - 1 is not entered at all.
Since the definition of output1 and output2 is only inside the loop, they will never be created and thus the error.
If you provide three inputs to your function2, the problem will be solved. Just pay attention to the order in which you provide them (for example, I'm assuming your Time input should be the same as t in the function, so it should be the first input to be passed).

How can I pass char values as double values in any matlab function provided I have the double variable of the same name as char(please see detail)?

%% I want to pass the values of char (here var_name{1})as that of double(here x) in histogram function. How can I do that?
% var_name could be much bigger
h={'h1','h2'}
var_name ={'x','y'}
time_step=100;
for i =1:time_step
x=%code that extract x from some data file %
y= %get y from some other file (actually using find command)
%the time loop will overwrite the x and y values
` for k=1:length(var_name)
%figure h
h{k}=histogram(var_name{k}) % I have been suggested to avoid eval %
%lot of procees to do here for every variable say x y than save the
%saveas(h{k},sprintf(...))
end
end
You have to use eval to evaluate the variable name, giving you the vector of data that variable contains:
histogram(eval(var_name{1}));
However, I'm guessing there's a better way to approach your problem, since using dynamically named variables is general not good practice.
Based on your updated example, one non-eval way you could do this is using structures and dynamic field names:
for i = 1:time_step
data.(var_name{1}) = % code that extract xs from some data file
data.(var_name{2}) = % get y from some other file (actually using find command)
for k = 1:length(var_name)
h{k} = histogram(data.(var_name{k}));
...
end
...
end

Memory-Allocation for function calls of form x = f(x) in MATLAB

In my code, I have lots of places where I invoke functions of the form
X = f(X)
and X can be a rather large matrix. In my special case, I have mostly calls like
X = feval(somefunc, X)
or
X = obj.myfunc(X)
It would be bad if, every time the function is called, there is new space allocated for X. Is MATLAB smart enough to deal with such function calls? Is there a way to tell?
The answer to this question helps would help very much with a design descision. I like to program in object oriented style and if MATLAB is not smart enough for this, it might pay off for me to add another member for X in the class, although I would rather not do this otherwise.
Whether a copy is made of the input arguments or not when calling a function in MATLAB depends upon what happens inside of the function.
MATLAB uses a system referred to as copy-on-write. This means that if you pass a large variable to a function as an input, as long as you do not modify the variable within that function, the variable will not be copied into the workspace of the function and the function will instead read the data from it's current location in memory.
function Y = func(X)
Y = X + 1;
end
If you are modifying the variable within the function, then a copy of the input variable is made and placed into the local workspace of the function.
function X = func(X)
X = X + 1;
end
There is more information on Loren's Mathworks blog.
An easy way to determine if a copy of the data is made or not is to use the undocumented format debug mode which will show you where the data for a given variable is stored in memory.
format debug
%// Create a variable a and show where debug info
a = [1,2]
%// Structure address = 141f567f0
%// m = 1
%// n = 2
%// pr = 7f9540b85e20
%// pi = 0
%// 1 2
%// Assign b = a but don't modify
b = a
%// Structure address = 141f567f0
%// m = 1
%// n = 2
%// pr = 7f9540b85e20 <= POINTER TO DATA REMAINED UNCHANGED
%// pi = 0
%// 1 2
%// Modify (Will create a new copy)
b = b + 1
%// Structure address = 141f55b40
%// m = 1
%// n = 2
%// pr = 7f953bcf1a20 <= POINTER TO DATA CHANGED (COPY)
%// pi = 0
%// 2 3
If you prefer you can use this little anonymous function I've created to inspect the memory location of any particular variable.
memoryLocation = #(x)regexp(evalc('disp(x)'), '(?<=pr\s*=\s*)[a-z0-9]*', 'match')
a = [1,2];
memoryLocation(a)
%// 7f9540b85e20
b = a;
memoryLocation(b)
%// 7f9540b85e20
b = b + 1;
memoryLocation(b)
%// 7f953bcf1a20
As a bit of a side-note, I would recommend against using feval throughout your code and instead just use the function names directly.

Update a M.file variables from command windows in Matlab?

I have a simple but interesting question. i tired hard to google it but my google got upset and giving me the same results...
i wanted to know is it possible to Update a constant variable form workspace command..
A Simple Example:
function y =StupidQuestion
a = 10; % some value
b =[5,6,7;1,2,8]; % some value
y = b*a % some operation
I forget to tell you that we can do it with simulink block by using below command
set_param('obj', 'parameter1', value1, 'parameter2', value2, ...)
i Want to use the assigned value for 3 weeks and without any reason i wants to change my values [a,b] to other but through command windows. any Idea. Waiting for your interesting Reply...................
You can set defaults for the inputs:
function y = foo(a,b)
if nargin < 1 || isempty(a), a = 10; end
if nargin < 2 || isempty(b), b = [5,6,7;1,2,8]; end
y = b*a
end
You can call foo() without inputs (and it will use the defaults for a and b) or supply your own values as: foo(12), foo(12,[10,20]), foo([],[23,23]), etc...
A possible way is to save some variables in an external file. Note that in this case a and b are only in the function workspace (you won't see their values unless you load the contents of test.mat separately). I'm passing the filename in rather than hard-coding it in case you need to switch between multiple settings.
Personally I would prefer to have a human-readable data file, but the concept remains the same (you'd just need some parser function which returned values for a and b given a file).
a = 10; % some value
b =[5,6,7;1,2,8]; % some value
save('test.mat','a','b');
clear a b;
function y = savedvariables(filename)
load(filename);
y = b*a; % some operation
end
y = savedvariables('test.mat');

Pass function as argument to function

So I have these two made up .m files. This is an example of the problem I'm having and the math is pseudo-math
rectangle.m:
function [vol, surfArea] = rectangle(side1, side2, side3)
vol = ...;
surfArea = ...;
end
ratio.m:
function r = ratio(f,constant)
% r should return a scaled value of the volume to surface area ratio
% based on the constant provided.
% This line doesn't work but shows what I'm intending to do.
[vol,surfArea] = f
r = constant*vol*surfArea;
end
What I'm unsure how to do is pass the rectangle function as f and then access vol and surfArea from within the ratio function. I've read and the Mathworks page on function handles and function functions and have come up empty handed on figuring out how to do this. I'm new to MATLAB so that doesn't help either.
Let me know if you need anymore info.
Thanks!
The correct way of passing the function rectangle as and argument of ratio is
r = ratio( #recangle, constant )
You can then call [vol,surfArea] = f(s1,s2,s3) from within ratio, but it requires the sideX arguments to be known.
If ratio should not require to know these arguments, then you could create an object function and pass this as a reference argument. Or better, you could create a rectangle class altogether:
classdef Rectangle < handle
properties
side1, side2, side3;
end
methods
% Constructor
function self = Rectangle(s1,s2,s3)
if nargin == 3
self.set_sides(s1,s2,s3);
end
end
% Set sides in one call
function set_sides(self,s1,s2,s3)
self.side1 = s1;
self.side2 = s2;
self.side3 = s3;
end
function v = volume(self)
% compute volume
end
function s = surface_area(self)
% compute surface area
end
function r = ratio(self)
r = self.volume() / self.surface_area();
end
function r = scaled_ratio(self,constant)
r = constant * self.ratio();
end
end
end
While I didn't bring this up in my question above, this is what I was searching for.
So what I wanted to do was pass some of rectangles arguments to ratio while being able to manipulate any chosen number of rectangles arguments from within the ratio function. Given my .m files that above, a third .m would look something like this. This solution ended up using MATLAB's anonymous functions.
CalcRatio.m:
function cr = calcRatio(length)
% Calculates different volume to surface area ratios given
% given different lengths of side2 of the rectangle.
cr = ratio(#(x) rectangle(4,x,7); %<-- allows the 2nd argument to be
% manipulated by ratio function
end
ratio.m:
function r = ratio(f,constant)
% r should return a scaled value of the volume to surface area ratio
% based on the constant provided.
% Uses constant as length for side2 -
% again, math doesnt make any sense, just showing what I wanted to do.
[vol,surfArea] = f(constant);
r = constant*vol*surfArea;
end