Trouble converting floating decimal into integer - matlab

I have created a user-defined function in which the inputs are j =indices, new_loc = a 51x2 matrix of cell locations, and the size of my first col of the 51x2 matrix = 51.
function [x,y,w,z] = check_location(j,new_loc,size)
disp(j);
a = j / size + 1; %Finds 1st element of compared array
b = mod(j,size); %Finds 1st element of comparing array
int8(a) %Must be whole integer
int8(b) %" "
fprintf('a = %g',a)
if b == 0 %1st element cannot be 0
b = b + 1;
else
;
end
fprintf('b = %g',b)
x = new_loc(a,1); % [x y]
y = new_loc(a,2);
w = new_loc(b,1); % [w z]
z = new_loc(b,2);
I am confused as I have tested my output with a fprintf function, and fprintf('a = %g',a) is showing a decimal number, while a = j / size + 1 is evaluating an integer. Also, I am getting the error: Subscript indices must either be real positive integers or logicals.
for j = 1:numel(D)
if D(j) < 8 & D(j) ~= 0
[x1,y1,x2,y2] = check_location(j,new_location,numel(new_location(:,1)));
% smallest_int = check_intensity(x1,y1,x2,y2,B);
% [row,col] = find(B == smallest_int) %Convert smallest_int vals w/ it's location
% new_location(row,col) = []; %Check new_location w/ smallest_int vals and delete
end
end
Here is the for loop in which I am testing my function.

These lines:
int8(a) %Must be whole integer
int8(b) %" "
both return int8 values, but they're not stored anywhere, so they're lost. You need to assign the integer value back to the original variable.
a = int8(a) %Must be whole integer
b = int8(b) %" "

Related

How to divide a 2D shape in patches of approx equal size in matlab?

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);

MATLAB Morse Code diff and find functions

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];

Have to convert Integer to binary

I'm writing a user-defined function to convert integers to binary. The largest number that could be converted with the function should be a binary number with
16 1 s. If a larger number is entered as d, the function should display an error
message. With my code, I'm trying to add the numbers 0 or 1 to my vector x based on the remainder, then I want to reverse my final vector to display a number in binary. Here's what I have:
function [b] = bina(d)
% Bina is a function that converts integers to binary
x = [];
y = 2;
in = d/2;
if d >=(2^16 -1)
fprintf('This number is too big')
else
while in > 1
if in >= 1
r = rem(in,y);
x = [x r]
end
end
end
end
As you insist on a loop:
x = [];
y = 2;
in = d;
if d >=(2^16 -1)
fprintf('This number is too big')
else
ii = 1;
while in > 0
r = logical(rem(in,y^ii));
x = [r x];
in = in - r*2^(ii-1);
ii = ii+1;
end
end
b = x;
You had the right ideas, but you need to update the variables in your while-loop with every iteration. This is mainly in, where you need to subtract the remainder. And just store the binary remainders in your variable x.
You can check your result with
x = double( dec2bin(d, 16) ) - 48
You could also use a for loop, by pre-calculating the number of iterations with
find( d < 2.^(1:16),1)
and then
if d >=(2^16 -1)
fprintf('This number is too big')
else
for ii = 1:find( d < 2.^(1:16),1)
r = logical(rem(in,y^ii));
x = [r x];
in = in - r*2^(ii-1)
end
end

How to do a ~= vector operation in matlab

I'm trying to write my own program to sort vectors in matlab. I know you can use the sort(A) on a vector, but I'm trying to code this on my own. My goal is to also sort it in the fewest amount of swaps which is kept track of by the ctr variable. I find and sort the min and max elements first, and then have a loop that looks at the ii minimum vector value and swaps it accordingly.
This is where I start to run into problems, I'm trying to remove all the ii minimum values from my starting vector but I'm not sure how to use the ~= on a vector. Is there a way do this this with a loop? Thanks!
clc;
a = [8 9 13 3 2 8 74 3 1] %random vector, will be function a once I get this to work
[one, len] = size(a);
[mx, posmx] = max(a);
ctr = 0; %counter set to zero to start
%setting min and max at first and last elements
if a(1,len) ~= mx
b = mx;
c = a(1,len);
a(1,len) = b;
a(1,posmx) = c;
ctr = ctr + 1;
end
[mn, posmn] = min(a);
if a(1,1) ~= mn
b = mn;
c = a(1,1);
a(1,1) = b;
a(1,posmn) = c;
ctr = ctr + 1;
end
ii = 2; %starting at 2 since first element already sorted
mini = [mn];
posmini = [];
while a(1,ii) < mx
[mini(ii), posmini(ii - 1)] = min(a(a~=mini))
if a(1,ii) ~= mini(ii)
b = mini(ii)
c = a(1,ii)
a(1,ii) = b
a(1,ii) = c
ctr = ctr + 1;
end
ii = ii + 1;
end

Store data in a row matrix

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.