How to replace values within for loop?
2 次查看(过去 30 天)
显示 更早的评论
Hi all,
I'm randomly generating Fsim by indexing through each bin a and c, which are defined by ExtSurgeBinEdges.
I want to implement that when Fsim is less than the installation height, then Fsim should be replaced by 0. I labeled my solution with %%%%%%% However, I'm concerned that I'm not getting it as I index through a and c because my P_DM are not accurately reflective of what I should be getting
In plain terms, when Fsim is less than or equal to the installation height n_ins, then Fsim should be 0. This should be reflected in the P_DM equations and I should obtain:
P_DM(1,iCombFGH)=1
P_DM(2,iCombFGH)=0
P_DM(2,iCombFGH)=0
otherwise it should be
P_DM(1,iCombFGH) = 1-F_DM1; %Prob damage state 1
P_DM(2,iCombFGH) = F_DM1-F_DM2; %Prob damage state 2
P_DM(3,iCombFGH) = F_DM3; %Prob damage state 3
Thanks
%% PS1 CPT Generation
% P(frag state 1|EFH, eps123, Predeg)
% Defining parent node distributions and bin edges
% External flood height
ExtSurgeBinEdges = [0 1E-17:0.5:5 20];
ExtSurgeBinEdges_Lo=ExtSurgeBinEdges(1:end-1);
ExtSurgeBinEdges_Hi=ExtSurgeBinEdges(2:end);
ExtSurgeBinEdges_Md=ExtSurgeBinEdges_Lo+(diff(ExtSurgeBinEdges)/2);
%Should produce 11*11*3*3=1089 values or a 3x363 CPT
IndF= [1:length(PreDeg_Edges_Md)]'; % 3 states
IndG= [1:length(eps123BinEdges_Md)]'; %11 states
IndH= [1:length(ExtSurgeBinEdges_Md)]'; %12 states
temp1=[]; temp2=[]; temp3=[]; [temp1,temp2,temp3]=ndgrid(IndF,IndG, IndH);
IndMatFGH=[temp1(:),temp2(:),temp3(:)];
% col1: Pre-existing deg state
% col2: eps123
% col3: EFH
%MC simulation for CPT of PS1 State
for iCombFGH=1:size(IndMatFGH,1) % loop over number of combos of parent nodes of PS1 frag state
% External Flood Height simulation (nominal, not elevation)
a=[];
c=[];
pdFsim=[];
Fsim=[];
% Define distribution of external flood height within bin
a=ExtSurgeBinEdges_Lo(IndMatFGH(iCombFGH,3));
c=ExtSurgeBinEdges_Hi(IndMatFGH(iCombFGH,3));
pdFsim=makedist('Uniform',a,c);
Fsim=random(pdFsim,[Nsim,1]); %simulate external flood heights within bin (Uniform)
Fsim=Fsim.*(Fsim>0); % ensure positivity
Fsim(Fsim<n_ins)=0; % Replace Fsim with 0 if less than installation height %%%%%%%%%%%%%%%%%%%%
% Limit state function
G_DM1=[]; G_DM1=LamDM1+eps123sim-log(Fsim-n_ins);
G_DM2=[]; G_DM2=LamDM2+eps123sim-log(Fsim-n_ins);
G_DM3=[]; G_DM3=LamDM3+eps123sim-log(Fsim-n_ins);
% Fail probs
F_DM1=[]; F_DM1=sum(G_DM1<0)/Nsim;
F_DM2=[]; F_DM2=sum(G_DM2<0)/Nsim;
F_DM3=[]; F_DM3=sum(G_DM3<0)/Nsim;
% Bin probs
P_DM(1,iCombFGH) = 1-F_DM1; %Prob damage state 1
P_DM(2,iCombFGH) = F_DM1-F_DM2; %Prob damage state 2
P_DM(3,iCombFGH) = F_DM3; %Prob damage state 3
end
1 个评论
Voss
2023-8-23
This comment doesn't address your question, but, for what it's worth, there is no need to initialize a variable to an empty array and then immediately overwrite it, as you are doing here:
% Limit state function
G_DM1=[]; G_DM1=LamDM1+eps123sim-log(Fsim-n_ins);
G_DM2=[]; G_DM2=LamDM2+eps123sim-log(Fsim-n_ins);
G_DM3=[]; G_DM3=LamDM3+eps123sim-log(Fsim-n_ins);
% Fail probs
F_DM1=[]; F_DM1=sum(G_DM1<0)/Nsim;
F_DM2=[]; F_DM2=sum(G_DM2<0)/Nsim;
F_DM3=[]; F_DM3=sum(G_DM3<0)/Nsim;
You can eliminate all the empty assignments and just set the variables to what you want:
% Limit state function
G_DM1=LamDM1+eps123sim-log(Fsim-n_ins);
G_DM2=LamDM2+eps123sim-log(Fsim-n_ins);
G_DM3=LamDM3+eps123sim-log(Fsim-n_ins);
% Fail probs
F_DM1=sum(G_DM1<0)/Nsim;
F_DM2=sum(G_DM2<0)/Nsim;
F_DM3=sum(G_DM3<0)/Nsim;
It would be a different story if you were assigning parts of an array, say, in a loop, but that's not the case here. Here, you are overwriting the whole variable, so you only need to assign it once.
采纳的回答
Voss
2023-8-23
编辑:Voss
2023-8-23
The line
Fsim(Fsim<n_ins)=0; % Replace Fsim with 0 if less than installation height %%%%%%%%%%%%%%%%%%%%
does what you intend, i.e., replaces elements of Fsim that are less than n_ins with 0. However, I don't think that's what you should be doing.
Consider what happens when you calculate G_DM1, etc., and Fsim has some elements that are 0. You'll be taking log() of a negative number (assuming n_ins is positive), which results in a complex number.
G_DM1=LamDM1+eps123sim-log(Fsim-n_ins);
Then you'll compare those possibly complex numbers to 0 here:
F_DM1=sum(G_DM1<0)/Nsim;
The way complex comparison works in MATLAB is that the real parts are compared. I don't think that's what you intended.
Instead of 0, you can set them to NaN:
Fsim(Fsim<n_ins)=NaN;
then log(NaN-n_ins) is NaN, then NaN<0 is false, so those elements won't count toward F_DM1, etc.
1 个评论
Voss
2023-8-23
编辑:Voss
2023-8-23
Another option would be to adjust the G_DM1, etc., values after the fact, as in:
% don't replace elements of Fsim, just keep track of which elements are < n_ins:
bad_idx = Fsim<n_ins;
% Limit state function
G_DM1=LamDM1+eps123sim-log(Fsim-n_ins);
G_DM2=LamDM2+eps123sim-log(Fsim-n_ins);
G_DM3=LamDM3+eps123sim-log(Fsim-n_ins);
% then adjust G_DM1,2,3 as appropriate:
G_DM1(bad_idx) = 0;
G_DM2(bad_idx) = 0;
G_DM3(bad_idx) = 0;
更多回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!