I would like to extend "univariate bootstrapping" to "multivariate bootsrapping", meaning in a first step I draw randomly with replacement out of a one-dimensional vector using this code:
s = RandStream.getGlobalStream();
reset(s)
n = 100000; % # of independent random trials
h = 52; % horizon
T = size(Resid_standard, 1);
Resid_bootstrapped = Resid_standard(unidrnd(T, h, n));
Now, the basic vector Resid_standard is not a uni-dimensional vector but a Tx2 matrix and I want to not only draw random numbers but random pairs.
How do I have to modify my code to achieve this?
The output in the univariate case is a 100000x50 matrix. The output for the two-dimensional case would be three-dimensional. How could I store my results?
One solution is to store the index vector, make use of linear indexing, and concatenate the results:
r_ind = unidrnd(T, h, n);
Resid_bootstrapped = cat(3, Resid_standard(r_ind), Resid_standard(r_ind + T));
Resid_bootstrapped will then be a h×n×2 matrix.
This can even be shortened into a one-liner:
Resid_bootstrapped = reshape(Resid_standard(unidrnd(T, h, n), [1,2]), h, n, 2);
Related
I have an 8x8 matrix, e.g. A=rand(8,8). What I need to do is subset all 2x2 matrices along the diagonal. That means that I need to save matrices A(1:2,1:2), A(3:4,3:4), A(5:6,5:6), A(7:8,7:8). To better explain myself, the current version that I am using is the following:
AA = rand(8,8);
BB = zeros(8,2);
for i = 1:4
BB(2*i-1:2*i,:) = AA(2*i-1:2*i,2*i-1:2*i);
end
This works fine for small AA matrices and small AA submatrices, however as the size grows significantly (it can get up to even 50,000x50,000) using a for loop like the one above in not viable. Is there a way to achieve the above without the loop? I've thought of other approaches that could perhaps utilize upper and lower triangular matrices, however even these seem to need a loop at some point. Any help is appreciated!!
Here's a way:
AA = rand(8,8); % example matrix. Assumed square
n = 2; % submatrix size. Assumed to divide the size of A
mask = repelem(logical(eye(size(AA,1)/n)), n, n);
BB = reshape(permute(reshape(AA(mask), n, n, []), [1 3 2]), [], n);
This generates a logical mask that selects the required elements, and then rearranges them as desired using reshape and permute.
Here is an alternative that doesn't generate a full matrix to select the block diagonals, as in Luis Mendo' answer but instead directly generates the indices to these elements. It is likely that this will be faster for very large matrices, as creating the indexing matrix will be expensive in that case.
AA = rand(8,8); % example matrix. Assumed square
n = 2; % submatrix size. Assumed to divide the size of A
m=size(AA,1);
bi = (1:n)+(0:m:n*m-1).'; % indices for elements of one block
bi = bi(:); % turn into column vector
di = 1:n*(m+1):m*m; % indices for first element of each block
BB = AA(di+bi-1); % extract the relevant elements
BB = reshape(BB,n,[]).' % put these elements in the desired order
Benchmark
AA = rand(5000); % couldn't do 50000x50000 because that's too large!
n = 2;
BB1 = method1(AA,n);
BB2 = method2(AA,n);
BB3 = method3(AA,n);
assert(isequal(BB1,BB2))
assert(isequal(BB1,BB3))
timeit(#()method1(AA,n))
timeit(#()method2(AA,n))
timeit(#()method3(AA,n))
% OP's loop
function BB = method1(AA,n)
m = size(AA,1);
BB = zeros(m,n);
for i = 1:m/n
BB(n*(i-1)+1:n*i,:) = AA(n*(i-1)+1:n*i,n*(i-1)+1:n*i);
end
end
% Luis' mask matrix
function BB = method2(AA,n)
mask = repelem(logical(eye(size(AA,1)/n)), n, n);
BB = reshape(permute(reshape(AA(mask), n, n, []), [1 3 2]), [], n);
end
% Cris' indices
function BB = method3(AA,n)
m = size(AA,1);
bi = (1:n)+(0:m:n*m-1).';
bi = bi(:);
di = 0:n*(m+1):m*m-1;
BB = reshape(AA(di+bi),n,[]).';
end
On my computer, with MATLAB R2017a I get:
method1 (OP's loop): 0.0034 s
method2 (Luis' mask matrix): 0.0599 s
method3 (Cris' indices): 1.5617e-04 s
Note how, for a 5000x5000 array, the method in this answer is ~20x faster than a loop, whereas the loop is ~20 faster than Luis' solution.
For smaller matrices things are slightly different, Luis' method is almost twice as fast as the loop code for a 50x50 matrix (though this method still beats it by ~3x).
I have a matrix, c, and I want to search many times for the index of the positive minimum element
d = min(c(c>0));
[x,y] = find(c == d);
but in the next search I want it to skip the old y.
how to do it?
I want to use x and y in some other calculation.
also I want to find this d minimum just within specific columns in the matrix c like:
j from m+1 to n-1
please help
Define mask = zeros(size(c)); before the loop.
And before finding the minimum use,
newc = c + mask;
d = min(newc(newc>0));
[x,y] = find(newc == d);
mask(:,y) = NaN;
I think you can update the c matrix. I mean:
% In the loop, use it:
[x,y]=find(c==d);
c(:, y) = [];
If c matrix is important, you can use a temporary variable equals to c, instead of using c.
Imagine for instance we have the following functions:
f = #(n) sin((0:1e-3:1) .* n * pi);
g = #(n, t) cos(n .^ 2 * pi ^2 / 2 .* t);
h = #(n) f(n) * g(n, 0);
Now, I would like to be able to enter an array of values for n into h and return a sum of the results for each value of n.
I am trying to be efficient, so I am avoiding the novice for-loop method of just filling out a pre-allocated matrix and summing down the columns. I also tried using arrayfun and converting the cell to a matrix then summing that, but it ended up being a slower process than the for-loop.
Does anyone know how I might do this?
The fact is the "novice" for-loop is going to be competitively as fast as any other vectorized solution thanks to improvements in JIT compilation in recent versions of MATLAB.
% array of values of n
len = 500;
n = rand(len,1);
% preallocate matrix
X = zeros(len,1001);
% fill rows
for i=1:len
X(i,:) = h(n(i)); % call function handle
end
out = sum(X,1);
The above is as fast as (maybe even faster):
XX = cell2mat(arrayfun(h, n, 'UniformOutput',false));
out = sum(XX,1);
EDIT:
Here it is computed directly without function handles in a single vectorized call:
n = rand(len,1);
t = 0; % or any other value
out = sum(bsxfun(#times, ...
sin(bsxfun(#times, n, (0:1e-3:1)*pi)), ...
cos(n.^2 * t * pi^2/2)), 1);
By "practically equivalent", I mean that their distances are of order epsilon apart (or 0.000001). Equality in MATLAB often doesn't really work for long floating numbers.
If I simply do abs(A1 - A2) < 0.000001, it's not going to work since size(A1) != size(A2)
You can get the answer by calculating distance between two vectors using MATLAB's pdist2 function.
dist=pdist2(A1,A2);
minDist=min(dist,[],2);
indices_A1=minDist<=0.000001;
desired_A1=A1(indices_A1);
Not tested, but should work.
Since you care about a distance from any element to any element, you can create a distance matrix from the vectorized matrices and probe that for the distance threshold. Example:
A = rand(10, 4); % (example) matrix A
B = rand(3, 5); % matrix B of different size
minDist = 0.005;
Solution: Repeat vectorized matrices, column- and row-wise to get same size matrices and apply matrix-based distance estimation:
Da = repmat(A(:), 1, length(B(:))); % size 40 x 15
Db = repmat(B(:)', length(A(:)), 1); % size 40 x 15
DD = Da - Db;
indA = any(abs(DD) < minDist, 2);
The use of any() will give you logical indices to any value of A that is close to any value of B). You can directly index/return the elements of A using indA.
The matrix DD (as #Shai also points out) can be equivalently estimated through bsxfun
DD = bsxfun(#minus, A(:), B(:)');
In addition: you can map from row-index (corresponding to A elements) back to matrix A indices using:
[iA, jA] = ind2sub(size(A), indA);
Assert/test that all the returned values are less than minDist,e.g. using:
for k = 1:length(iA);
d(k) = min(min(abs(A(iA(k), jA(k)) - B)));
end
all(d < minDist)
(tested in Octave 3.6.2)
I want to store data coming from for-loops in an array. How can I do that?
sample output:
for x=1:100
for y=1:100
Diff(x,y) = B(x,y)-C(x,y);
if (Diff(x,y) ~= 0)
% I want to store these values of coordinates in array
% and find x-max,x-min,y-max,y-min
fprintf('(%d,%d)\n',x,y);
end
end
end
Can anybody please tell me how can i do that. Thanks
Marry
So you want lists of the x and y (or row and column) coordinates at which B and C are different. I assume B and C are matrices. First, you should vectorize your code to get rid of the loops, and second, use the find() function:
Diff = B - C; % vectorized, loops over indices automatically
[list_x, list_y] = find(Diff~=0);
% finds the row and column indices at which Diff~=0 is true
Or, even shorter,
[list_x, list_y] = find(B~=C);
Remember that the first index in matlab is the row of the matrix, and the second index is the column; if you tried to visualize your matrices B or C or Diff by using imagesc, say, what you're calling the X coordinate would actually be displayed in the vertical direction, and what you're calling the Y coordinate would be displayed in the horizontal direction. To be a little more clear, you could say instead
[list_rows, list_cols] = find(B~=C);
To then find the maximum and minimum, use
maxrow = max(list_rows);
minrow = min(list_rows);
and likewise for list_cols.
If B(x,y) and C(x,y) are functions that accept matrix input, then instead of the double-for loop you can do
[x,y] = meshgrid(1:100);
Diff = B(x,y)-C(x,y);
mins = min(Diff);
maxs = max(Diff);
min_x = mins(1); min_y = mins(2);
max_x = maxs(1); max_y = maxs(2);
If B and C are just matrices holding data, then you can do
Diff = B-C;
But really, I need more detail before I can answer this completely.
So: are B and C functions, matrices? You want to find min_x, max_x, but in the example you give that's just 1 and 100, respectively, so...what do you mean?