0
votes

I have an array (let's call it ElmInfo) of size Nx2 representing a geometry. In that array the element number and element volume are on the column 1 and column 2 respectively. The volume of elements largely vary. The sum of the volume of all elements leads to a value V which can be obtained in MATLAB as:

V=sum(ElmInfo(:,2));

I want to randomly sample elements from the array ElmInfo in such a way that the volume of sampled elements (with no repetition) will lead to a target volume V1. Note: V1 is less than V. So I don't know the number of elements to be sampled. I am giving an example. For a sampling case number of sampled element can be '10' whereas in other sampling number of sampled element can be '15'.

There is no straightforward MATLAB in-built function to meet the target condition. How can I implement the code in MATLAB?

1
Does it need to be exactly V1? Or do you want to sample until you pick the first sample that would make the volume exceed V1? - Cris Luengo
I want to sample until the sum of the volume of sampled elements is V1 with some tolerance. Numerically I am presenting the problem. Suppose I have 300 elements and the total volume, V, is 2. I want to sample randomly 'n' number of elements such that the sum of the element volume be 0.15. During each sampling the value of 'n' can be 12 or 20. But the sum of those elements is to be 0.15. It is sometimes difficult to achieve numerically. So I want to have a tolerance,e.g. 1e-3. Numerically it should be (V1_target-V1_actual)<= tolerance and I need to run it in a while loop. - LarCos

1 Answers

0
votes

Finally I got the answer of my question. Here is the solution I got from a contributor at MATLAB central. For the convenience of the stack overflow community I am posting the answer here.

TotVol=sum(ElmInfo(:,2));
DefVf = 1.5;            % This is the volume fraction I want to sample
% Target sample volume
DefVolm_target = TotVol*(DefVf/100);
% **************************************
n = 300;
v = ElmInfo(:,2);   
tol = 1e-6;
sample = [];
maxits = 10000;
for count = 1:maxits
    p = randperm(n);
    s = cumsum(v(p));
    k = find(abs(s - DefVolm_target) < tol);
    if ~isempty(k)
        sample_indices = p(1:k(1));
        sample = v(sample_indices);
        fprintf('Sample found after %d iterations\n', count);
        break
    end
end
DefVol_sim=sum(sample);
sampled_Elm=sort(sample_indices);