Vectorized mfile-based model with an if statement

Dear UQLab Community

I have a mfile-based model with this if statement that needs to be true so I can evaluate a performance function according to different metamodel previously established.

It is my understanding that the mfile is vectorized, improving the performance of the code by several orders of magnitude, since it allows the evaluation of N different realizations in a single call.

Nevertheless, I notice that the if statement that I am using the mfile is never true, but it should be for some runs. When the mfile was not vectorized I could confirm this.

Is this something that can be done? If so, please let me know what I am missing.
Please find enclosed a short example of the code in the file I am using.
mfilebased_model.m (308 Bytes)

Furthermore, I should say that I am using subset simulation as the reliability analysis method.

I thank you in advance for your time and support
Best Regards,
Neryvaldo GalvĂŁo

Dear Neryvaldo GalvĂŁo,

Since your code is short, I take the liberty of posting it below to make it more convenient for other users.

The fact that your IF statement never evaluates to true after you vectorized your code makes me wonder if your condition is correct. Your current condition is equivalent to:
all(X(:,18) <= X(:,19))
However, you probably wanted the following condition:
any(X(:,18) <= X(:,19))
Can you confirm that your condition is correct?

Best regards,
Styfen

function Y = myHRAEventTree(X)

load(Metamodel_1)
load(Metamodel_2)
load(Metamodel_3)


if  X(:,18)<=X(:,19)
    Y = uq_evalModel(Metamodel_1,X(:,1:16));
elseif X(:,18)<=X(:,19)+X(:,20)
    Y = uq_evalModel(Metamodel_2,X(:,1:16));
else    
    Y = uq_evalModel(Metamodel_3,X(:,1:16));
end

end

Dear Styfen Schaer

Thank you for your support

all(X(:,18) <= X(:,19)) is not what I meant to do :frowning_face:. Nevertheless, I not sure if any(X(:,18) <= X(:,19)) will work as well :thinking:.

What I need is: for any realization N of a single call, if X(18)<=X(19) the Metamodel_1 should be used to get the output of interest i.e., Y for that single realization where the condition “if” is verified.

The non-vectorized code that I had before was something like the following and it was working fine, but the performance was terrible. :hot_face:

function Y = myHRAEventTree(X)

load(Metamodel_1)
load(Metamodel_2)
load(Metamodel_3)

for i=1:size(X,1)
if  X(i,18)<=X(i,19)
    Y(i) = uq_evalModel(Metamodel_1,X(i,1:16));
elseif X(i,18)<=X(i,19)+X(i,20)
    Y(i) = uq_evalModel(Metamodel_2,X(i,1:16));
else   
    Y(i) = uq_evalModel(Metamodel_3,X(i,1:16));
end
end

     
end

How can I convert this code to a vectorized mfile-based model? :pray:

Looking forward to hearing from you.

Thank you in advance for your support.
Best regards,
Neryvaldo GalvĂŁo

Dear Neryvaldo GalvĂŁo;

any() will not work in this case. However, I think you’re looking for something like below:

Best regards,
Styfen

function Y = myHRAEventTree(X)

load(Metamodel_1)
load(Metamodel_2)
load(Metamodel_3)

cond1 = X(:,18) <= X(:,19);
X1 = X(cond1,16);

cond2 = X(:,18) <= X(:,19) + X(:,20);
X2 = X(cond2,16);

cond3 = ~cond1 & ~cond2;
X3 = X(cond3,16);

Y1 = uq_evalModel(Metamodel_1, X1);
Y2 = uq_evalModel(Metamodel_2, X2);
Y3 = uq_evalModel(Metamodel_3, X3);

Y = zeros(size(X,1),1);
Y(cond1) = Y1;
Y(cond2) = Y2;
Y(cond3) = Y3;
     
end
1 Like

Dear Styfen Schaer

Thank you very much :grinning:. It looks like the code you suggested is working fine :+1:.

Nevertheless, I need to understand a little more about it. Where can I read more about the approach you suggesting?

Furthermore, lets say I need to do the following multiplication X(i,6) = X(i,17) * X(i,15) when cond1 = X(:,18) <= X(:,19) is true. How can I do this in this vectorized approach you proposing? I have tried a couple of things, but sadly it is not working.

Many thanks for your support
Best Regards,
Neryvaldo GalvĂŁo

Dear Neryvaldo GalvĂŁo,

I’m glad it worked.
The proposed approach is not directly related to UQLab but to Matlab.
However, the following link shows some examples of how to use logical operators to select submatrizes:

https://ch.mathworks.com/help/matlab/matlab_prog/find-array-elements-that-meet-a-condition.html

Regarding your problem you may have missed to use the elementwise operator.
The following should work:

cond1 = X(:,18) <= X(:,19);
X(cond1,6) = X(cond1,17) .* X(cond1,15);

Best regards,
Styfen

1 Like

Dear Styfen Schaer

Once again thank you very much. Almost everything is working fine :grinning:.

But it seems to me that these lines:

Y(cond1) = Y1;
Y(cond2) = Y2;
Y(cond3) = Y3;

are overwriting each other. At the end Y(cond3)=Y3 overwrites the values provided by Y(cond2) = Y2 and this last one overwrite the Y(cond1) = Y1. Making my efforts to separate the estimation of Y with different metamodel inconsequential :cold_sweat:.

Y1 = uq_evalModel(Metamodel_1, X1);
Y2 = uq_evalModel(Metamodel_2, X2);
Y3 = uq_evalModel(Metamodel_3, X3);

Please let me know what are your thoughts on this.

Best Regards,
Neryvaldo GalvĂŁo

Well, I think that’s a tiny mistake on my part. :wink:
The second condition should read:

cond2 = X(:,18) <= X(:,19) + X(:,20) & ~cond1;

You should double check that all conditions are correct now.

Best regards,
Styfen

1 Like

Great!! Looks like that everything is working fine. I still have to run a few more tests though.

Thank you very much for the super support :muscle: :muscle:. It is great to know I have you on the other side.

Regards,
Neryvaldo GalvĂŁo