I would like to know what are the commands to create a LHS design and then augment it with more points later on if the model is not good enough? For example, I will first create a 50 points LHS design, then add more points (perhaps in batches of 20) incrementally until the model is accurate enough.
For example:
Set1=lhsdesign(5,5); %5x5 matrix
%Use of set 1, then determine more points are needed
Set2=%some command that adds 20 points to Set1 to make it a 25x5 matrix
The difficulty in running lhsdesign again for the 20 new points do not take account of the original points. There is also work done using the original points and so by generating a new set of points from scratch wastes this work as the new points are not included in the new set.
I was able to make a function that solves this problem. I am not sure the final matrix is a true latin hypercube, but it adds the required number of points to the given points and moves them to the closest available open 'channel' (Sub range where no point exists) if need be.
Usage is as follows:
x1=lhsdesign(200,17);
xF=lhsaugment(x1,200);
Which adds 200 points to the x1 set of points, resulting in xF being a 400x17 matrix. Function is as follows:
function xF = lhsaugment(x1,nPoi)
%function xF = lhsaugment(x1,nPoi)
%Function to augment a given latin hypercube x1 by a number of points,
%nPoi. Only the length is changed, i.e. points are added to the length.
%The original points are left unctouched and appear first in the output
%xF. Thus the size of xF is [size(x1,1)+nPoi size(x1,2)].
x2=lhsdesign(nPoi,size(x1,2));
nPoi=size(x2,1);
oPoi=size(x1,1);
tPoi=nPoi+oPoi;
fInt=1/tPoi;
for i=1:tPoi
cBound(i,:)=[(i-1)*fInt i*fInt];
end
xF=zeros(tPoi,size(x1,2));
bX1=zeros(size(x1));
bX2=zeros(size(x2));
bF=zeros(tPoi,size(x1,2));
iF=zeros(1,size(x1,2));
iMove=0;
for i=1:oPoi
for j=1:size(cBound,1)
for l=1:size(x1,2)
if (x1(i,l)>cBound(j,1))&&(x1(i,l)<=cBound(j,2))&&(bF(j,l)==0)
iF(1,l)=iF(1,l)+1;
xF(iF(1,l),l)=x1(i,l);
bX1(i,l)=1;
bF(j,l)=1;
elseif (x1(i,l)>cBound(j,1))&&(x1(i,l)<=cBound(j,2))&&(bF(j,l)~=0)
iMin=size(cBound,1);
pMin=size(cBound,1);
for m=j:-1:1
if (bF(m,l)==0)
iMin=m;
pMin=j-m;
break
end
end
for m=j:size(cBound,1)
if (bF(m,l)==0)&&(m-j<pMin)
iMin=m;
pMin=j+m;
break
end
end
iF(1,l)=iF(1,l)+1;
xF(iF(1,l),l)=x1(i,l);
bX1(i,l)=1;
bF(iMin,l)=1;
end
end
end
end
for i=1:nPoi
for j=1:size(cBound,1)
for l=1:size(x2,2)
if (x2(i,l)>cBound(j,1))&&(x2(i,l)<=cBound(j,2))&&(bF(j,l)==0)
iF(1,l)=iF(1,l)+1;
xF(iF(1,l),l)=x2(i,l);
bX2(i,l)=1;
bF(j,l)=1;
elseif (x2(i,l)>cBound(j,1))&&(x2(i,l)<=cBound(j,2))&&(bF(j,l)~=0)
iMin=size(cBound,1);
pMin=size(cBound,1);
for m=j:-1:1
if (bF(m,l)==0)
iMin=m;
pMin=j-m;
break
end
end
for m=j:size(cBound,1)
if (bF(m,l)==0)&&(m-j<pMin)
iMin=m;
pMin=j+m;
break
end
end
iF(1,l)=iF(1,l)+1;
xF(iF(1,l),l)=(x2(i,l)-(floor(x2(i,l)/fInt)*fInt))+((iMin-1)*fInt);
bX2(i,l)=1;
bF(iMin,l)=1;
if l==1
iMove=iMove+1;
end
end
end
end
end
Related
The workspace is given as:
limits=[-1 4; -1 4; -1 4];
And in this workspace, there is a spherical obstacle which is defined as:
obstacle.origin_x=1.6;
obstacle.origin_y=0.8;
obstacle.origin_z=0.2;
obstacle.radius_obs=0.2;
save('obstacle.mat', 'obstacle');
I would like to create random point in the area of lim. I created random points using the code below:
function a=rndmpnt(lim, numofpoints)
x=lim(1,1)+(lim(1,2)-lim(1,1))*rand(1,numofpoint);
y=lim(2,1)+(lim(2,2)-lim(2,1))*rand(1,numofpoint);
z=lim(3,1)+(lim(3,2)-lim(3,1))*rand(1,numofpoint);
a=[x y z];
Now I would like to eliminate the points in the area of limits-obstacle. how can I do that?
You want to reject the points within the obstacle. Naturally, after rejection you will probably end up with fewer points than numofpoint. So the process will need to be repeated until enough points are generated. A while loop is appropriate here.
Rejection is done by finding ix (indices of acceptable points) and appending only those points to matrix a. The loop repeats until there are enough of those, and returns exactly the number requested.
function a = rndmpnt(lim, numofpoints)
a = zeros(3,0); % begin with empty matrix
while size(a,2) < numofpoint % not enough points yet
x=lim(1,1)+(lim(1,2)-lim(1,1))*rand(1,numofpoint);
y=lim(2,1)+(lim(2,2)-lim(2,1))*rand(1,numofpoint);
z=lim(3,1)+(lim(3,2)-lim(3,1))*rand(1,numofpoint);
ix = (x - obstacle.origin_x).^2 + (y - obstacle.origin_y).^2 + (z - obstacle.origin_z).^2 > obstacle.radius_obs^2;
a = [a, [x(ix); y(ix); z(ix)]];
end
a = a(:, 1:numofpoint);
end
You may want to add a safeguard against infinite loop (some limit on the number of cycles) in case the user passes in the values such that there are no acceptable points.
I have a matrices 25x600 and some columns contains positive and negative values. I want the output like this [+ + - -] (four values 2 positive and 2 negative). I am guaranteed to always have two positive values immediately before the transition and two negative values immediately after. my attempting was as follow :
My attempt was as follows:
clc;
clear all;
close all;
%%
data=[-0.0059972;-0.004994;-0.0029881;2.0868e-05;
0.0030299;0.013059;0.033115;0.063196;0.093273;0.1935;0.39385;0.69423;0.99448;1.9950;3.99550;6.99550;9.9957;19.9961;39.99620;69.9960;
99.99530;199.99810;399.99140;699.98860;1000.03130]
for r=1:600
lam=data(:,r);
N_lam = length(lam);
%%
for j=1:N_lam
kk=0;
r1=0;
if(sign(lam(j))==1)
kk=kk+1;
lampos(kk)=lam(j);
if (length(lampos(kk))>3 &length(lamneg(r1))>2)
break
end
else
r1=r1+1;
lamneg(r1)=lam(j);
end
end
cc{r}=[lampos lamneg];
end
Any help would be greatly appreciated.
The find function may be useful here, as it can help you to locate the locations where the function changes from positive to negative. The following locates the index ind of the last negative value of data (assumed here to be a 1D vector) before it rises above zero:
num_rises = 1;
ind = find(data(1:end-1)<=0 & data(2:end)>0, num_dips, 'first')
As such, for each column, you would be interested in the values of ind-1,ind, negative values, and ind+1,ind+2 for the positive values.
It was also unclear to me how many sets of these 4 values were of interest to you. To find more regions where the data dips below the origin, change the value of num_dips to suit your needs.
I am having a problem, I have a function popmesh1 that calculates a matrix P( , ). I then use sens_analysis to store a element of that matrix and continue. How do I output P( , ) so that it is kept track of? I keep getting that the matrix is size (0,0). Also, how do I pass the matrix into another function? Sorry to post whole code, I want to concrete and clear, I'm pretty new to MATLAB
function pdemeshpop(varargin)
global par;
global re;
global P;
global par_n;
global a1;
clc
clear
%INIITIALIZE MESH:- Can change time and age for refining of mesh
time=linspace(0,800,4000);
age=linspace(0,time(end),4000);
dt=time(2)-time(1);
dtao=dt;
P=zeros(length(time),9); % State matrix over time.
P1=zeros(length(time),length(age)); % Mesh for population of P1mod.
prodrev=zeros(length(time),length(age));
p1tot=zeros(length(time));
p2tot=zeros(length(time));
f=zeros(length(time));
A_1=zeros(length(time),1);
%Parameters
G=log(2)/30; %This growth rate had been set to nthroot(2,20), but I think it should be log(2)/20 for a doubling time of 20 mins. Units 1/min
R=.75; %Reduction in growth rate due to viral production, range from 0.5-0.75
global A_s; %Number of virus produced each minute from one cell? Units 1/min
A_s = 35; %Source for this?
global re;
re = varargin(1); %Reduction in efficiency of virus production in P1mod
c=1.5e9; %Concentration of cells in saturated culture. Units 1/cm^3 Source: http://bionumbers.hms.harvard.edu/bionumber.aspx?&id=100984&ver=2
K=3e-11; %Adsorption rate. Units cm^3/min. Source: Tzagoloff, H., and D. Pratt. 1964. The initial steps in infection with coliphage M13. Virology 24:372?380.
i = 1; %Is flipping of switch induced or not induced? if i==1 then switch is induced.
if i==1
S_i=0.5; %S_i is probability that a switch will flip during a timestep in a p1ori cell. Units pure number (a probablility). Ranges from 0 to 1.
elseif i==0
S_i= 0.005;
end
%IC and BC implementation for the 9 dependent variables <<<10?
P0=zeros(9,1);
P0(1)=100; %Initial concentration of senders. Units: cells/ml.
P0(2)=10000; %Initial concentration of primary receivers. Units: cells/ml.
P0(3)=10000; %Initial concentration of secondary receivers. Units: cells/ml.
%The loop below covers the initial conditions and BC of t=0,all ages
for i=1:9
P(1,i)=P0(i);
end
%Iterative solution
for m=1:length(time)-1 % m is timestep
%Simplifications
p1tot(m)=P(m,2)+P(m,4)+P(m,6);
p2tot(m)=P(m,3)+P(m,5)+P(m,7);
f(m)=1-(P(m,1)+p1tot(m)+p2tot(m))/c;
%Senders
P(m+1,1)=dt*(P(m,1)*G*R*f(m))+P(m,1);
%Primary Receivers
P(m+1,2)=dt*((P(m,2)*G*f(m))-K*(P(m,8)+P(m,9))*P(m,2))+P(m,2);
%Secondary Receivers
P(m+1,3)=dt*((P(m,3)*G*f(m))-K*(P(m,8)+P(m,9))*P(m,3))+P(m,3);
%Primary Original
P(m+1,4)=dt*((P(m,4)*G*f(m))+K*P(m,8)*P(m,2)-S_i*P(m,4))+P(m,4);
%Secondary Original
P(m+1,5)=dt*((P(m,5)*G*f(m))+K*P(m,8)*P(m,3))+P(m,5);
for n=1:m
t=(m-1)*dt; %Why not t=m*dt?
tao=(n-1)*(dtao);%Determines current age basket
prodrev(m,n)=rate(t-tao); %Calculates corresponding rate of production of phage (reversed)
%Primary Modified
if n==1
P1(m+1,n)=dt*(K*P(m,2)*P(m,9)+S_i*P(m,4)); %Left hand side boundary (New cells at age zero)
else
P1(m+1,n)=dt*(-((P1(m,n)-P1(m,n-1))/dtao)+P1(m,n)*G*R*f(m))+P1(m,n);
end
end
P(m+1,6)=sum(P1(m+1,:)); %phi1mod
%Secondary Modified
P(m+1,7)=dt*((P(m,7)*G*f(m))+K*P(m,9)*P(m,3))+P(m,7);
%Original
P(m+1,8)=dt*(A_s*P(m,1))+P(m,8);
if m<2
A_1(m)=0;
else
convolution(m,:)=prodrev(m,:).*P1(m,:);
%A_1(m)=dtao*trapz(conv(prod1(m,:), P1(m,:)));
A_1(m)=dtao*trapz([convolution(m,:) 0]);
%A_1 obtained by convolving the discrete vectors of P1 and prod1
%then finding the area under the curve
end
%Modified
P(m+1,9)=dt*A_1(m)+P(m,9);
end
P1;
end
function prod=rate(tao)
%Function generates production rate values of the infected cells based on their age
global A_s;
global re;
a=re*A_s; %Max production rate
ageofcell=tao;
if ageofcell<=10
prod=0;
elseif ageofcell<=50
prod=(a/40)*(ageofcell-10);
else
prod=a;
end
end
and my other code that calls the above function, and that I want to pass P(time(length),7) to:
function sens_analysis
global par;
global re;
global par_n;
global P;
time=linspace(0,800,4000);
pdemeshpop_final_re_sens;
re_0 = re;
par = re;
s_nom_ss = a1;
delta = 0.05;
par_n = par*(1+delta);
pdemeshpop_final_re_sens_par(par_n); % similar to pdemeshpop_final_re_sens
s_pert_ss = P(length(time),7);
abs_sens = (s_pert_ss - s_nom_ss)/(delta*re_0);
rel_sens = abs_sens*(re_value/s_nom_ss);
end
Again, sorry to post whole code, felt it was a necessary evil. The global variables might also be unnecessary. Could be something obvious. I might need to store P first somehow. Can someone please explain this carefully? Thank you!
At the beginning of function pdemeshpop you have a clear statement which is erasing from your workspace the variables declared by the global statements. Comment out that clear statement and you'll circumvent that problem.
The first thing I noticed in your code is that you use global variables. In general this is not recommended if it can be avoided. Consider giving them as input to your functions instead, either separately or in a struct.
Of course the clear is removing your variables, but in general if you want to see what is happening, try placing some breakpoints in your code. That allows you to inspect all existing variables. With f10 you can then step through the code and see how everything goes on.
Furthermore, I would always recommend you to use dbstop if error, this way you can efficiently deal with the errors that you will encounter.
I am not very sure how the hist function in MATLAB works. I seem to have few problems with it.
Bascially, in the code below, i am trying to run the rotation invariant Uniform Local Binary Pattern(LBP) code. I have no problem with the LBP code but the problem is with hist function(indicated in the code below).
The problem is that the range i should get is from 0:9 but when i apply the histogram function i get values greater than 9 such as 35, 27 and even values such as 178114.Not very sure how to correct it.
I2 = imread('test.png');
RIUniformHist=[];
m=size(I2,1);
n=size(I2,2);
for i=1:10:m
for j=1:10:n
for k=i+1:i+8
for l=j+1:j+8
J0=I2(k,l);
I3(k-1,l-1)=I2(k-1,l-1)>J0;
I3(k-1,l)=I2(k-1,l)>J0;
I3(k-1,l+1)=I2(k-1,l+1)>J0;
I3(k,l+1)=I2(k,l+1)>J0;
I3(k+1,l+1)=I2(k+1,l+1)>J0;
I3(k+1,l)=I2(k+1,l)>J0;
I3(k+1,l-1)=I2(k+1,l-1)>J0;
I3(k,l-1)=I2(k,l-1)>J0;
LBP=I3(k-1,l-1)*2^7+I3(k-1,l)*2^6+I3(k-1,l+1)*2^5+I3(k,l+1)*2^4+I3(k+1,l+1)*2^3+I3(k+1,l)*2^2+I3(k+1,l-1)*2^1+I3(k,l-1)*2^0;
bits = bitand(LBP, 2.^(7:-1:0))>0;
if nnz(diff(bits([1:end, 1]))) <= 2
RIULBP(k,l)=abs(I3(k-1,l-1)-I3(k-1,l))+ abs(I3(k-1,l)-I3(k-1,l+1))+ abs(I3(k-1,l+1)-I3(k,l+1))+ abs(I3(k,l+1)-I3(k+1,l+1))+abs(I3(k+1,l+1)-I3(k+1,l))+abs(I3(k+1,l)-I3(k+1,l-1))+abs(I3(k+1,l-1)-I3(k,l-1));
else
RIULBP(k,l)=9;
end
end
end
RIULBP=uint8(RIULBP);
RIULBPv=reshape(RIULBP,1,size(RIULBP,1)*size(RIULBP,2));
RIUHist=hist(RIULBPv,0:9); % problem
RIUniformHist = [RIUniformHist RIUHist];
end
end
The vector returned by
RIUHist=hist(data, bins)
is the count of how many elements of data are nearest the point identified by the bins vector. So if you have a value of 178114, that juts means that there were 178114 elements of data that were nearest to the matching index in bins.
You can use
[RIUHist, binsOut] = hist(data)
to let Matlab choose the bins (I believe it uses 20 bins) or
[RIUHist, binsOut] = hist(data, binCount)
To let Matlab choose the bins, but force a certain number of bins (I often use 100 or 200).
i have a piece of metropolis algorithm:
mB=5.79*10^(-9); %Bohr magnetone in eV*G^-1
kB=0.86*10^(-4); %Boltzmann in eV*K^-1
%system parameters
L=60; %side square grid
L2=L*L; % total number grid position
Tstep=5; %step in temperature change (K)
Maxstep=10; %max number of steps
nmcs=5; % cycle numberof Metropolis algorithm
magnet=NaN(1,Maxstep);%store magnetization in "monte carlo images" of sample
%Creation initial point arrangement of magnetic spins
%Outer parameters
H=100000; %Gauss
T=20; % Kelvin
%Energy alteration in spin-reverse
de =# (i,j) (2*mB*H).*mlat(i,j);
%Metropolis probability
pmetro=# (i,j) exp(-de(i,j)./(kB*T));
%Creation and display of initial lattice
mlat=2*round(rand(L,L))-1;
mtotal=sum(mlat(:))./L2
% Alteration of system with time
for ii=1:Maxstep
for imc=1:nmcs
for i=1:L
for j=1:L
if pmetro(i,j)>=1
mlat(i,j)=-mlat(i,j);
elseif rand<pmetro(i,j)
mlat(i,j)=-mlat(i,j);
end
end
end
end
magnet(:,ii)=sum(mlat(:))./L2;
%figure(ii);
%pcolor(mlat);
% shading interp;
end
m1=mean(magnet)
error=std(magnet) ./sqrt(numel(magnet))
fprintf('Temperature = %d K',T)
figure(13)
plot(magnet(1,:),'b.')
axis([0 10 0 0.5])
grid on
xlabel('i (Configuration) ')
ylabel('M/(N*mB)')
Now,the problem is in figure(13).The values it gives me are around zero (0.05,0.02..).It supposes to give me values around 0.3..
Generally,the graph its ok,It gives me the right "shape"(it has points) but as i said around zero.
I really don't know how to put this post in order to be understood.Maybe i have some mistake in the "magnet"matrix ,i don't know.
Anyway,i don't demand from anybody to check it thoroughly ,i am just asking if with a quick look anyone can help.
ΕDIT--->> Also,sometimes when i run the program ,it gives me :
Undefined function or method 'mlat'
for input arguments of type 'double'.
Error in ==> #(i,j)(2*mB*H).*mlat(i,j)
Error in ==>
#(i,j)exp(-de(i,j)./(kB*T))
Error in ==> metropolis at 39
if pmetro(i,j)>=1
EDIT--->>> I found the "mistake" .In my code in the loops where i have the function "pmetro" i replaced it with the "exp(-(2*mB*H).*mlat(i,j)./(kB*T))" and the program worked just fine!!!
Why it didn't work with calling the "pmetro"??How can i overcome this?Is there a problem with function handles in loops?
Blockquote
I very strongly suggest that you try writing code without using any function handles until you're really familiar with Matlab.
The line
de =# (i,j) (2*mB*H).*mlat(i,j);
is what causes your problems. In Matlab, when you define a function handle that refers to, say, an array, the function handle will use the array as it was at the time of definition. In other words, even though mlat changes inside your loop, mlat(i,j) inside the function de is always the same. In fact, you cannot even run this code unless you have previously defined mlat in the workspace.
You should therefore rewrite the main loop as follows
for iStep = 1:maxStep
for imc = 1:mcs
pmetro = $some function of mlat - this can be calculated using the
entire array as input
%# for each element in mlat (and thus pmetro), decide whether
%# you have to switch the spin
switchIdx = pmetro > 1 | pmetro < rand(size(mlat));
mlat(switchIdx) = -mlat(switchIdx);
end
$calculate magnetization$
end
Also, note that there is a command mean to take the average. No need to sum and then divide by the number of elements.