I'm new to Matlab and I have a function and I need to display a variable from running the main file (but the main file does access the function)...
I have tried to use fprintf(n);
Thanks :)
MATLAB function fprintf() is very similar to fprintf() in C. If your variable n is an integer, then you should do
fprintf('%d\n', n);
An interesting feature is that you can also print multiple numeric values and literal text to the screen. For example
A1 = [9.9, 9900];
A2 = [8.8, 7.7 ; ...
8800, 7700];
fprintf('X is %4.2f meters or %8.3f mm\n', A1, A2);
where %4.2f takes the element at the first column of A1 and %8.3f takes the second. In the sequence, it repeats for A2 printing its first line and later its second line. The output is
X is 9.90 meters or 9900.000 mm
X is 8.80 meters or 8800.000 mm
X is 7.70 meters or 7700.000 mm
If you want more details about the specifiers you can use with fprintf(), you should give a look at the MathWorks docs.
Related
I have found the following Matlab code to simulate a Non-homogeneous Poisson Process
function x = nonhomopp(intens,T)
% example of generating a
% nonhomogeneousl poisson process on [0,T] with intensity function intens
x = 0:.1:T;
m = eval([intens 'x']);
m2 = max(m); % generate homogeneouos poisson process
u = rand(1,ceil(1.5*T*m2));
y = cumsum(-(1/m2)*log(u)); %points of homogeneous pp
y = y(y<T); n=length(y); % select those points less than T
m = eval([intens 'y']); % evaluates intensity function
y = y(rand(1,n)<m/m2); % filter out some points
hist(y,10)
% then run
% t = 7 + nonhomopp('100-10*',5)
I am new to Matlab and having trouble understanding how this works. I have read the Mathworks pages on all of these functions and am confused in four places:
1) Why is the function defined as x and then the intervals also called x? Like is this an abuse of notation?
2) How does the square brackets affect eval,
eval([intens 'x'])
and why is x in single quotations?
3) Why do they use cumsum instead of sum?
4) The given intensity function is \lambda (t) = 100 - 10*(t-7) with 7 \leq t \leq 12 How does t = 7 + nonhomopp('100-10*',5) represent this?
Sorry if this is so much, thank you!
To answer 2). That's a unnecessary complicated piece of code. To understand it, evaluate only the squared brackets and it's content. It results in the string 100-10*x which is then evaluated. Here is a version without eval, using an anonymous function instead. This is how it should have been implemented.
function x = nonhomopp(intens,T)
% example of generating a
% nonhomogeneousl poisson process on [0,T] with intensity function intens
x = 0:.1:T;
m = intens(x);
m2 = max(m); % generate homogeneouos poisson process
u = rand(1,ceil(1.5*T*m2));
y = cumsum(-(1/m2)*log(u)); %points of homogeneous pp
y = y(y<T); n=length(y); % select those points less than T
m = intens(y); % evaluates intensity function
y = y(rand(1,n)<m/m2); % filter out some points
hist(y,10)
Which can be called like this
t = 7 + honhomopp(#(x)(100-10*x),5)
the function is not defined as x: x is just the output variable. In Matlab functions are declared as function [output variable(s)] = <function name>(input variables). If the function has only one output, the square brackets can be omitted (like in your case). The brackets around the input arguments are, as instead, mandatory, no matter how many input arguments there are. It is also good practice to end the body of a function with end, just like you do with loops and if/else.
eval works with a string as input and the square brackets apprently are concatenating the string 'intens' with the string 'x'. x is in quotes because, again, eval works with input in string format even if it's referring to variables.
cumsum and sum act differently. sum returns a scalar that is the sum of all the elements of the array whereas cumsum returns another array which contains the cumulative sum. If our array is [1:5], sum([1:5]) will return 15 because it's 1+2+3+4+5. As instead cumsum([1:5]) will return [1 3 6 10 15], where every element of the output array is the sum of the previous elements (itself included) from the input array.
what the command t = 7 + nonhomopp('100-10*',5) returns is simply the value of time t and not the value of lambda, indeed by looking at t the minimum value is 7 and the maximum value is 12. The Poisson distribution itself is returned via the histogram.
I am trying to extract the lowest value for V from the table produced for each force (F) in order to establish the optimum result, e.g. for F=5000, V=0.06575 is the optimum result.
I want to be able to display this for each instance of F. I'm not quite sure where I am going wrong.
%===========================================
%This Script calculates
%===========================================
%Parameter Values
%F:force (N)
%L1: Length of beam 1 (m)
%L2: Length of beam 2 (m)
%H: Height of beam 1 (m)
%h: Height of beam 2 (m)
%b: Cross section width (m)
%S: Yield strength (Pa)
%N: Factor of safety
%V:Volume of the beam (m^2)
%=========================================
clc %clear command window
clear all %clear all variables previously generated and stored in Matlab
format short g
L1=2;
L2=3;
b=0.05;
S=248;
K=1.42;
results=[];
optimalresults=[];
nd=3.6; %desired factor of safety calculated by group number
for F=5000:100:6000
for h=0.2:0.005:0.3 %loop of h
for H=0.2:0.005:0.3 % loop of H
M1=F*(L1+L2);
M2=F*L2;
I1=b*H^3/12;
I2=b*h^3/12;
Y1=H/2;
Y2=h/2;
Max_stress_1=M1*Y1/I1;
Max_stress_2=K*(M2*Y2/I2);
Max_total_stress=max(Max_stress_1,Max_stress_2);
Max_total_stress=Max_total_stress/1e6;
N=0.577*S/Max_total_stress;
%if N is greater than desired factor of safety then display results
if N >= nd
V=(b*L1*H)+(b*L2*h);
results=[results; F,V,N];sort(F);
end
end
end
results_sorted=sortrows(results,1); %sorts factor of safety from min to max
disp(' F V N');
disp(results_sorted);
optimum=results_sorted(1,:)
end
What do I have to change to display the minimal value of V for each F?
My guess is that you probably want this bit outside of the 3 for loops:
results_sorted=sortrows(results,1); %sorts factor of safety from min to max
disp(' F V N');
disp(results_sorted);
optimum=results_sorted(1,:)
Also, I am not sure what you achieve with sort(F); inside the loop.
I think your code needs two changes before you can get the minimal value of V for each F:
Where you use sortrows, you should sort the table using the second column (V), so that the lowest V gets placed in the top row. results_sorted=sortrows(results,2);
You should sort only the results for the current F, so either you clear the variable "results" for each F iteration results=[]; or you use a new variable. Be sure to check if "results" is not empty before sorting the rows.
The variable "optimum" has now the lowest V for each F iteration.
How solve a system of ordinary differential equation ..an initial value problem ....with parameters dependent on time or independent variable?
say the equation I have
Dy(1)/dt=a(t)*y(1)+b(t)*y(2);
Dy(2)/dt=-a(t)*y(3)+b(t)*y(1);
Dy(3)/dt=a(t)*y(2);
where a(t) is a vector and b(t) =c*a(t); where the value of a and b are changing with time not in monotone way and each time step.
I tried to solve this using this post....but when I applied the same principle ...I got the error message
"Error using griddedInterpolant The point coordinates are not
sequenced in strict monotonic order."
Can someone please help me out?
Please read until the end to see whether the first part or second part of the answer is relevant to you:
Part 1:
First create an .m file with a function that describe your calculation and functions that will give a and b. For example: create a file called fun_name.m that will contain the following code:
function Dy = fun_name(t,y)
Dy=[ a(t)*y(1)+b(t)*y(2); ...
-a(t)*y(3)+b(t)*y(1); ...
a(t)*y(2)] ;
end
function fa=a(t);
fa=cos(t); % or place whatever you want to place for a(t)..
end
function fb=b(t);
fb=sin(t); % or place whatever you want to place for b(t)..
end
Then use a second file with the following code:
t_values=linspace(0,10,101); % the time vector you want to use, or use tspan type vector, [0 10]
initial_cond=[1 ; 0 ; 0];
[tv,Yv]=ode45('fun_name',t_values,initial_cond);
plot(tv,Yv(:,1),'+',tv,Yv(:,2),'x',tv,Yv(:,3),'o');
legend('y1','y2','y3');
Of course for the fun_name.m case I wrote you need not use sub functions for a(t) and b(t), you can just use the explicit functional form in Dy if that is possible (like cos(t) etc).
Part 2: If a(t) , b(t) are just vectors of numbers you happen to have that cannot be expressed as a function of t (as in part 1), then you'll need to have also a time vector for which each of them happens, this can be of course the same time you'll use for the ODE, but it need not be, as long as an interpolation will work. I'll treat the general case, when they have different time spans or resolutions. Then you can do something of the following, create the fun_name.m file:
function Dy = fun_name(t, y, at, a, bt, b)
a = interp1(at, a, t); % Interpolate the data set (at, a) at times t
b = interp1(at, b, t); % Interpolate the data set (bt, b) at times t
Dy=[ a*y(1)+b*y(2); ...
-a*y(3)+b*y(1); ...
a*y(2)] ;
In order to use it, see the following script:
%generate bogus `a` ad `b` function vectors with different time vectors `at` and `bt`
at= linspace(-1, 11, 74); % Generate t for a in a generic case where their time span and sampling can be different
bt= linspace(-3, 33, 122); % Generate t for b
a=rand(numel(at,1));
b=rand(numel(bt,1));
% or use those you have, but you also need to pass their time info...
t_values=linspace(0,10,101); % the time vector you want to use
initial_cond=[1 ; 0 ; 0];
[tv,Yv]= ode45(#(t,y) fun_name(t, y, at, a, bt, b), t_values, initial_cond); %
plot(tv,Yv(:,1),'+',tv,Yv(:,2),'x',tv,Yv(:,3),'o');
legend('y1','y2','y3');
I am new to Matlab. I was reading this code snippet, but in some parts (marked with asterisks) I don't understand what it means, so if anybody could help would be very much appreciated
function [A1nmb] = moran(initsize, popsize)
% MORAN generates a trajectory of a Moran type process
% which gives the number of genes of allelic type A1 in a population
% of haploid individuals that can exist in either type A1 or type A2.
% The population size is popsize and the initial number of type A1
% individuals os initsize.
% Inputs: initsize - initial number of A1 genes
% popsize - the total population size (preserved)
if (nargin==0)
initsize=10;
popsize=30;
end
A1nmb=zeros(1,popsize);
A1nmb(1)=initsize;
**lambda = inline('(x-1).*(1-(x-1)./N)', 'x', 'N');
mu = inline('(x-1).*(1-(x-1)./N)', 'x', 'N');**
x=initsize;
i=1;
while (x>1 & x<popsize+1)
if (lambda(x,popsize)/(lambda(x,popsize)+mu(x,popsize))>rand)
x=x+1;
A1nmb(i)=x;
else
x=x-1;
A1nmb(i)=x;
end;
i=i+1;
end;
nmbsteps=length(A1nmb);
***rate = lambda(A1nmb(1:nmbsteps-1),popsize) ...
+mu(A1nmb(1:nmbsteps-1),popsize);***
**jumptimes=cumsum(-log(rand(1,nmbsteps-1))./rate);**
jumptimes=[0 jumptimes];
stairs(jumptimes,A1nmb);
axis([0 jumptimes(nmbsteps) 0 popsize+1]);
The first line you marked
lambda = inline('(x-1).*(1-(x-1)./N)', 'x', 'N');
creates something called an inline function. It is equivalent to defining a mathematical function. Example:
y = inline('x^2')
would allow you to do
>> y(2)
4
This immediately explains the second line you marked.
rate = lambda(A1nmb(1:nmbsteps-1),popsize) ...
+mu(A1nmb(1:nmbsteps-1),popsize);
will compute the value of the function lambda(x,N) at x = A1nmb(1:nmbsteps-1) and N = popsize.
I will say immediately here that you should take a look at anonymous functions, a different format used to accomplish the same as inline. Only, anonymous functions are generally better supported, and usually a lot faster than inline functions.
Then, for the final line,
jumptimes = cumsum(-log(rand(1,nmbsteps-1))./rate);
is a nested command. rand will create a matrix containing pseudorandom numbers, log is the natural logarithm ("ln"), and cumsum creates a new matrix, where all the elements in the new matrix are the cumulative sum of the elements in the input matrix.
You will find the commands doc and help very useful. Try typing
doc cumsum
or
help inline
on the Matlab command prompt. Try that again with the commands forming the previous statement.
As a general word of advice: spend an insane lot of time reading through the documentation. Really, for each new command you encounter, read about it and play with it in a sandbox until you feel you understand it. Matlab only becomes powerful if you know all its commands, and there are a lot to get to know.
It defines an inline function object. For example this
lambda = inline('(x-1).*(1-(x-1)./N)', 'x', 'N')
defines lambda as a function with 2 variables. When you call lambda(A,n) Matlab simply expands the function you define in the first string. Thus lambda(A,n) using the variables you provide in the function call. lambda(A,n) would will evaluate to:
(A-1).*(1-(A-1)./n)
it just expands the function using the parameters you supply. Take a look at this link for more specific details http://www.mathworks.co.uk/help/techdoc/ref/inline.html
The cumsum function just returns the cumulative sum of a matrix along a particular dimension. Say we call cumsum on a vector X, then the value at element i in the result is equal to the sum of elements in X from index 1 to i. For example X = [1 2 1 3] we would get
AA = cumsum(X);
we would have
AA = [1 3 5 8]
See this link for more details and examples http://www.mathworks.co.uk/help/techdoc/ref/cumsum.html
I used nlfilter for a test function of mine as follows:
function funct
clear all;
clc;
I = rand(11,11);
ld = input('Enter the lag = ') % prompt for lag distance
A = nlfilter(I, [7 7], #dirvar);
% Subfunction
function [h] = dirvar(I)
c = (size(I)+1)/2
EW = I(c(1),c(2):end)
h = length(EW) - ld
end
end
The function works fine but it is expected that nlfilter progresses element by element, but in first two iterations the values of EW will be same 0.2089 0.4162 0.9398 0.1058. But then onwards for all iterations the next element is selected, for 3rd it is 0.4162 0.9398 0.1058 0.1920, for 4th it is 0.9398 0.1058 0.1920 0.5201 and so on. Why is it so?
This is nothing to worry about. It happens because nlfilter needs to evaluate your function to know what kind of output to create. So it uses feval once before starting to move across the image. The output from this feval call is what you see the first time.
From the nlfilter code:
% Find out what output type to make.
rows = 0:(nhood(1)-1);
cols = 0:(nhood(2)-1);
b = mkconstarray(class(feval(fun,aa(1+rows,1+cols),params{:})), 0, size(a));
% Apply fun to each neighborhood of a
f = waitbar(0,'Applying neighborhood operation...');
for i=1:ma,
for j=1:na,
x = aa(i+rows,j+cols);
b(i,j) = feval(fun,x,params{:});
end
waitbar(i/ma)
end
The 4th line call to eval is what you observe as the first output from EW, but it is not used to anything other than making the b matrix the right class. All the proper iterations happen in the for loop below. This means that the "duplicate" values you observe does not affect your final output matrix, and you need not worry.
I hope you know what the length function does? It does not give you the Euclidean length of a vector, but rather the largest dimension of a vector (so in your case, that should be 4). If you want the Euclidean length (or 2-norm), use the function norm instead. If your code does the right thing, you might want to use something like:
sz = size(I,2);
h = sz - (sz+1)/2 - ld;
In your example, this means that depending on the lag you provide, the output should be constant. Also note that you might want to put semicolons after each line in your subfunction and that using clear all as the first line of a function is useless since a function will always be executed in its own workspace (that will however clear persistent or global variables, but you don't use them in your code).