I have a MATLAB program like this
for m = 1:2
%# Some code to calculate a matrix (Ytotale)
%# Size of Ytotale is (1200 * 144) %%
%#...
Yfinal = Ytotale;
for l = 1:1200
i = l;
j = retard(l,1);
if Yfinal(i,j) == 0
Yfinal(i,j:end) = circshift(Yfinal(i,j:end),[retard(l,2) retard(l,2)]);
for j = retard(l,1):retard(l,1)+retard(l,2)-1
Yfinal(i,j) = 1;
end
else
Yfinal(i,j:end) = circshift(Yfinal(i,j:end),[retard(l,2) retard(l,2)]);
for j = retard(l,1):retard(l,1)+retard(l,2)-1
Yfinal(i,j) = 0;
end
end
end
%# ( Here i , j are index of matrix Ytotale , and l is the index
%# of matrix retard of size (1200 * 2)
for i =1:1200
not_char(i,1) = sum(Yfinal(i,1:144));
req(i,1) = sum(Ytotale(i,1:144));
end
final = req - not_char;
ve_delay = sum(Yfinal(:,1:144))';
end
The total process will iterate from m = 1 to 2 and two Ytotale matrix will form, hence I want to store the value of ve_delay and final in a row matrix for each Ytotale , but my code overwrites the matrix values .
please help...
This answer is adapted from the comment by macduf
Try final{m} = req - not_char; and ve_delay{m} = sum(Yfinal(:,1:144)); . These values are now stored in a cell matrix (the curly bracket notation). You can convert the cell array into a regular array afterward.
Related
I have a 2D matrix of zeros and ones, where the ones indicate a convex figure
I now want to divide this figure (that is the elements of value 1) in nonoverlapping patches of equally the same size, as in this figure
Do you have any suggestion? I could go for mat2cell and have just rectangles, and keep the rectangles with at least one value 1 in them, but I would prefer a more equal division.
For similar problems, I often use a method called 'orthogonal recursive bisection'.
An example of what it does with your circle is in the picture.
As the name suggests, the method divides subdomains into two smaller subdomains,
until the total number of subdomains is the desired value.
My implementation for your case is
function array = ORB(array,nparts)
%
% array = ORB(array,nparts)
%
% Divide the nonzeros of array into nparts equally large,
% approximately square parts.
%
% convert true/false array into 0/1:
ar = array; array = zeros(size(ar)); array(ar) = 1;
% initialize subdivision-admin
istart = 1; iend = nparts; values = 1;
last_value = max(values);
% Divide up the parts that need dividing up
while length(values) < nparts
new_istart = []; new_iend = []; new_values = [];
for i = 1:length(values)
if iend(i) > istart(i)
disp(sprintf('Current values %d should eventually be split into domains %d-%d',values(i),istart(i),iend(i)))
last_value = last_value + 1;
new_istart = [new_istart, istart(i), istart(i) + floor((iend(i)-istart(i)+1)/2)];
new_iend = [new_iend, istart(i) + floor((iend(i)-istart(i)+1)/2)-1, iend(i)];
new_values = [new_values, values(i), last_value];
n = length(new_values);
disp(sprintf('Current values %d should now be split into domains %d and %d, in ratio %d:%d\n', ...
values(i), new_values(n-1:n),new_iend(n-1:n)-new_istart(n-1:n)+1));
array = Split(array,new_values(n-1:n),new_iend(n-1:n)-new_istart(n-1:n)+1);
else
disp(sprintf('Domain %d is done\n',values(i)))
new_istart = [new_istart, istart(i)];
new_iend = [new_iend, iend(i)];
new_values = [new_values, values(i)];
end
end
iend = new_iend; istart = new_istart; values = new_values;
end
for i = 1:nparts
disp(sprintf('Part %d has %d points',i,length(find(array==i))))
end
close all
pcolor(array)
which needs the function Split:
function array = Split(array,parts,sizes)
%
% array = Split(array,parts,sizes)
%
% Change some of the values of array which are now equal to parts(1) into the value parts(2).
% At the end, the ratio
% length(find(array==parts(1))) : length(find(array==parts(2)))
% should be
% sizes(1) : sizes(2)
%
% Calculate sizes of each patch
[i,j] = find(array==parts(1));
npoints = size(i,1); sizes = npoints * sizes/(sizes(1)+sizes(2));
imin = min(i); imax = max(i); jmin = min(j); jmax = max(j);
nmin = 0; nmax = npoints;
if jmax-jmin>imax-imin
% divide domain in (j < jmid) and (jmid <= j)
while jmax > jmin + 1
jmid = (jmax + jmin)/2; n_this = size(find(j<jmid));
if n_this < sizes(1)
jmin = jmid; nmin = n_this;
else
jmax = jmid; nmax = n_this;
end
end
i = i(j>=jmid); j = j(j>=jmid);
else
% divide domain in (i < imid) and (imid <= i)
while imax > imin + 1
imid = (imax + imin)/2; n_this = size(find(i<imid));
if n_this < sizes(1)
imin = imid; nmin = n_this;
else
imax = imid; nmax = n_this;
end
end
j = j(i>=imid); i = i(i>=imid);
end
% Change the values in array
array(sub2ind(size(array),i,j)) = parts(2);
We are trying to write a function that takes arr and counts how many 0's and 1's appear in sequence. The output should be a 2D array where column 1 is how many appear in sequence and column 2 is which token it is (0 or 1). Our function below
function [token] = tokenizeSignal(arr)
matA = diff(find(diff([log_vector;-1])));
addA = zeros(size(matA, 1),1);
matA = [matA, addA];
matB = diff(find(diff([log_vector;0])));
addB = ones(size(matB, 1), 1);
matB = [matB, addB];
[nRowsA, nCols] = size(matA);
nRowsB = size(matB, 1);
AB = zeros(nRowsA + nRowsB, nCols);
AB(1:2:end, :) = matA;
AB(2:2:end, :) = matB;
token = AB;
works with
arr = [0; 0; 0; 1; 1; 1; 0];
but nothing else because it adds random integers into the matrix. Why does it do this and how can I fix it?
Here is code that takes any array arr and produces what you want:
% input checking/processing
% ... convert the input into a column vector
arr = arr(:);
% ... check that the input is nonempty and numeric
if ~isnumeric(arr), error('Bad input'); end
if isempty(arr), error('Bad input'); end
% determine the starting indices of each sequence in arr
I = [1 ; find(diff(arr)) + 1];
% determine the values of each of these sequences
values = arr(I);
% determine the length of each of these sequences
value_counts = [diff(I) ; length(arr) - max(I) + 1];
% produce the output
token = [value_counts, values];
How I make a script that check that my matrix do this condition? Also, how I get back the numbers of the rows and columns that do the condition?
Tnx
With n do you mean the row number? In that case if A is your matrix of size N by M, you could do it by
%initialize vectors for the indices you want to return
rows = nan(N*M);
cols = nan(N*M);
counter = 0
for i = 3:N
for j = 1:M
if A(i,j) == A(n-1, j) + A(n-2, j)
counter = counter + 1;
rows(counter) = i;
cols(counter) = j;
end
end
end
% remove nans from end
inds = find(~isnan(rows));
rows = rows(ind);
cols = cols(ind);
I have a vector named signal consisting of 300001 values. In each iteration of the for loop, I want to pick up 2000 consecutive values from this vector and store it in another vector X (X is 1*2000 vector)
The code is as follows:
D = 1:300001;
A = zeros(1,2000);
r=1;
n=0;
m=1;
for i=1:300001
for p = (1+(2000*n)):(r*2000)
while m<2000
A(1,m)= signal(1,p);
%disp (m);
m = m+1;
end
end
r = r+1;
n = n+1;
m = 1;
end
But it gives me the error "Index exceeds matrix dimensions.
Can somebody help me out with a better way to do it?
this would work
signal = ones(1,30000);
index1= 1:2000:length(signal);
index2= 2000:2000:length(signal);
for i=1:length(index1)
A = signal(index1(i):index2(i));
end
or this
signal = ones(1,30000);
temp = reshape(signal,2000,[]);
for i = 1:size(temp,2)
A=temp(:,i);
end
I am writing a graphical representation of numerical stability of differential operators and I am having trouble removing a nested for loop. The code loops through all entries in the X,Y, plane and calculates the stability value for each point. This is done by finding the roots of a polynomial of a size dependent on an input variable (length of input vector results in a polynomial 3d matrix of size(m,n,(lenght of input vector)). The main nested for loop is as follows.
for m = 1:length(z2)
for n = 1:length(z1)
pointpoly(1,:) = p(m,n,:);
r = roots(pointpoly);
if isempty(r),r=1e10;end
z(m,n) = max(abs(r));
end
end
The full code of an example numerical method (Trapezoidal Rule) is as follows. Any and all help is appreciated.
alpha = [-1 1];
beta = [.5 .5];
Wind = 2;
Wsize = 500;
if numel(Wind) == 1
Wind(4) = Wind(1);
Wind(3) = -Wind(1);
Wind(2) = Wind(4);
Wind(1) = Wind(3);
end
if numel(Wsize) == 1
Wsize(2) = Wsize;
end
z1 = linspace(Wind(1),Wind(2),Wsize(1));
z2 = linspace(Wind(3),Wind(4),Wsize(2));
[Z1,Z2] = meshgrid(z1,z2);
z = Z1+1i*Z2;
p = zeros(Wsize(2),Wsize(1),length(alpha));
for n = length(alpha):-1:1
p(:,:,(length(alpha)-n+1)) = alpha(n)-z*beta(n);
end
for m = 1:length(z2)
for n = 1:length(z1)
pointpoly(1,:) = p(m,n,:);
r = roots(pointpoly);
if isempty(r),r=1e10;end
z(m,n) = max(abs(r));
end
end
figure()
surf(Z1,Z2,z,'EdgeColor','None');
caxis([0 2])
cmap = jet(255);
cmap((127:129),:) = 0;
colormap(cmap)
view(2);
title(['Alpha Values (',num2str(alpha),') Beta Values (',num2str(beta),')'])
EDIT::
I was able to remove one of the for loops using the reshape command. So;
for m = 1:length(z2)
for n = 1:length(z1)
pointpoly(1,:) = p(m,n,:);
r = roots(pointpoly);
if isempty(r),r=1e10;end
z(m,n) = max(abs(r));
end
end
has now become
gg = reshape(p,[numel(p)/length(alpha) length(alpha)]);
r = zeros(numel(p)/length(alpha),1);
for n = 1:numel(p)/length(alpha)
temp = roots(gg(n,:));
if isempty(temp),temp = 0;end
r(n,1) = max(abs(temp));
end
z = reshape(r,[Wsize(2),Wsize(1)]);
This might be one for loop, but I am still going through the same number of elements. Is there a way to use the roots command on all of my rows at the same time?