function [Outmatrix, OutFact] = Sampling_Function_2(p, k, r, UB, LB, GroupMat) %[Outmatrix, OutFact] = Sampling_Function_2(p, k, r, UB, LB, GroupMat) % Inputs: % k (1,1) := number of factors examined or number of groups examined. % In case the groups are chosen the number of factors is stores in NumFact and % sizea becomes the number of created groups. % NumFact (1,1) := number of factors examined in the case when groups are chosen % r (1,1) := sample size % p (1,1) := number of intervals considered in [0, 1] % UB(sizea,1) := Upper Bound for each factor % LB(sizea,1) := Lower Bound for each factor % GroupNumber(1,1) := Number of groups (eventually 0) % GroupMat(NumFact,GroupNumber):= Matrix which describes the chosen groups. Each column represents a group and its elements % are set to 1 in correspondence of the factors that belong to the fixed group. All % the other elements are zero. % Local Variables: % sizeb (1,1) := sizea+1 % sizec (1,1) := 1 % randmult (sizea,1) := vector of random +1 and -1 % perm_e(1,sizea) := vector of sizea random permutated indeces % fact(sizea) := vector containing the factor varied within each traj % DDo(sizea,sizea) := D* in Morris, 1991 % A(sizeb,sizea) := Jk+1,k in Morris, 1991 % B(sizeb,sizea) := B in Morris, 1991 % Po(sizea,sizea) := P* in Morris, 1991 % Bo(sizeb,sizea) := B* in Morris, 1991 % Ao(sizeb,sizec) := Jk+1,1 in Morris, 1991 % xo(sizec,sizea) := x* in Morris, 1991 (starting point for the trajectory) % In(sizeb,sizea) := for each loop orientation matrix. It corresponds to a trajectory % of k step in the parameter space and it provides a single elementary % effect per factor % MyInt() % Fact(sizea,1) := for each loop vector indicating which factor or group of factors has been changed % in each step of the trajectory % AuxMat(sizeb,sizea) := Delta*0.5*((2*B - A) * DD0 + A) in Morris, 1991. The AuxMat is used as in Morris design % for single factor analysis, while it constitutes an intermediate step for the group analysis. % % Outputs: % Outmatrix(sizeb*r, sizea) := for the entire sample size computed In(i,j) matrices % OutFact(sizea*r,1) := for the entire sample size computed Fact(i,1) vectors % % Note: B0 is constructed as in Morris design when groups are not considered. When groups are considered the routine % follows the following steps: % 1- Creation of P0 and DD0 matrices defined in Morris for the groups. This means that the dimensions of these % 2 matrices are (GroupNumber,GroupNumber). % 2- Creation of AuxMat matrix with (GroupNumber+1,GroupNumber) elements. % 3- Definition of GroupB0 starting from AuxMat, GroupMat and P0. % 4- The final B0 for groups is obtained as [ones(sizeb,1)*x0' + GroupB0]. The P0 permutation is present in GroupB0 % and it's not necessary to permute the matrix (ones(sizeb,1)*x0') because it's already randomly created. % Reference: % A. Saltelli, K. Chan, E.M. Scott, "Sensitivity Analysis" on page 68 ss % % F. Campolongo, J. Cariboni, JRC - IPSC Ispra, Varese, IT % Last Update: 15 November 2005 by J.Cariboni % % Written by Jessica Cariboni and Francesca Campolongo % Joint Research Centre, The European Commission, % % Copyright © 2005 European Commission % Copyright © 2012-2023 Dynare Team % % This file is part of Dynare. % % Dynare is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % Dynare is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . % Parameters and initialisation of the output matrix sizea = k; Delta = p/(2*p-2); %Delta = 1/3 NumFact = sizea; GroupNumber = size(GroupMat,2); if GroupNumber ~= 0 sizea = size(GroupMat,2); end sizeb = sizea + 1; Outmatrix = []; OutFact = []; % For each i generate a trajectory for i=1:r % Construct DD0 - OLD VERSION - it does not need communication toolbox % RAND(N,M) is an NXM matrix with random entries, chosen from a uniform distribution on the interval (0.0,1.0). % Note that DD0 tells if the factor have to be increased or ddecreased % by Delta. randmult = ones(k,1); v = rand(k,1); randmult (v < 0.5)=-1; randmult = repmat(randmult,1,k); DD0 = randmult .* eye(k); % Construct DD0 - NEW VERSION - it needs communication toolbox % randsrc(m) generates an m-by-m matrix, each of whose entries independently takes the value -1 with probability 1/2, % and 1 with probability 1/2. % DD0 = randsrc(NumFact) .* eye(NumFact); % Construct B (lower triangular) B = ones(sizeb,sizea); for j = 1:sizea B(1:j,j)=0; end % Construct A0, A A0 = ones(sizeb,1); A = ones(sizeb,NumFact); % Construct the permutation matrix P0. In each column of P0 one randomly chosen element equals 1 % while all the others equal zero. % P0 tells the order in which order factors are changed in each % trajectory. P0 is created as it follows: % 1) All the elements of P0 are set equal to zero ==> P0 = zeros (sizea, sizea); % 2) The function randperm create a random permutation of integer 1:sizea, without repetitions ==> perm_e; % 3) In each column of P0 the element indicated in perm_e is set equal to one. % Note that P0 is then used reading it by rows. P0 = zeros (sizea, sizea); perm_e = randperm(sizea); % RANDPERM(n) is a random permutation of the integers from 1 to n. for j = 1:sizea P0(perm_e(j),j) = 1; end % When groups are present the random permutation is done only on B. The effect is the same since % the added part (A0*x0') is completely random. if GroupNumber ~= 0 B = B * (GroupMat*P0')'; end % Compute AuxMat both for single factors and groups analysis. For Single factors analysis % AuxMat is added to (A0*X0) and then permutated through P0. When groups are active AuxMat is % used to build GroupB0. AuxMat is created considering DD0. If the element on DD0 diagonal % is 1 then AuxMat will start with zero and add Delta. If the element on DD0 diagonal is -1 % then DD0 will start Delta and goes to zero. AuxMat = Delta*0.5*((2*B - A) * DD0 + A); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % a --> Define the random vector x0 for the factors. Note that x0 takes value in the hypercube % [0,...,1-Delta]*[0,...,1-Delta]*[0,...,1-Delta]*[0,...,1-Delta] MyInt = repmat(0:(1/(p-1)):(1-Delta),NumFact,1); % Construct all possible values of the factors % OLD VERSION - it needs communication toolbox % w = randint(NumFact,1,[1,size(MyInt,2)]); % NEW VERSION - construct a version of random integers % 1) create a vector of random integers % 2) divide [0,1] into the needed steps % 3) check in which interval the random numbers fall % 4) generate the corresponding integer v = repmat(rand(NumFact,1),1,size(MyInt,2)+1); % 1) IntUsed = repmat(0:1/size(MyInt,2):1,NumFact,1); % 2) DiffAuxVec = IntUsed - v; % 3) w=NaN(1,size(DiffAuxVec,1)); for ii = 1:size(DiffAuxVec,1) w(1,ii) = max(find(DiffAuxVec(ii,:)<0)); % 4) end x0 = MyInt(1,w)'; % Define x0 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % b --> Compute the matrix B*, here indicated as B0. Each row in B0 is a % trajectory for Morris Calculations. The dimension of B0 is (Numfactors+1,Numfactors) if GroupNumber ~= 0 B0 = (A0*x0' + AuxMat); else B0 = (A0*x0' + AuxMat)*P0; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % c --> Compute values in the original intervals % B0 has values x(i,j) in [0, 1/(p -1), 2/(p -1), ... , 1]. % To obtain values in the original intervals [LB, UB] we compute % LB(j) + x(i,j)*(UB(j)-LB(j)) In = repmat(LB,1,sizeb)' + B0 .* repmat((UB-LB),1,sizeb)'; % Create the Factor vector. Each component of this vector indicate which factor or group of factor % has been changed in each step of the trajectory. Fact=NaN(1,sizea); for j=1:sizea Fact(1,j) = find(P0(j,:)); end Fact(1,sizea+1) = 0; Outmatrix = [Outmatrix; In]; OutFact = [OutFact; Fact']; end