Convert vector of numbers to string without removing the zeros at start and end - arrays

I have a vector of integers and I want to convert it into one number.For example:
h = [1 2 4 3]; % after conversion res= 1243
k = [ 0 0 0 0]; % after conversion res=0000
l = [0 0 2 1]; % after conversion res=0021
I tried to use this method
b = [1 2 4 3];
res= str2num(strrep(num2str(b'), ' ', ''))
This method works fine when there is no zeros at start or end of the vector. But when there is zeros at end or start, str2num is removing them. For example, for vector k, res=0. For vector l, res=21.
How can I keep the zeros at the start and end?

At least for Octave, you can use a vectorized sprintf to print each array element into a string.
>> a = sprintf('%d', [0 0 1 2 3 4 0 0])
a = 00123400
very likely the same code would work too for MATLAB. Unfortunately I can't test it right now.

The easiest certainly is to convert your numbers directly to characters by offsetting them according to the ASCII-character table with 48:
char(h + 48)
char(k + 48)
char(l + 48)
If your input is a matrix (what I'd recommend) you additionally need to cellstr to convert the character matrix to a cell array of strings:
h(1,:) = [1 2 4 3];
h(2,:) = [0 0 0 0];
h(3,:) = [0 0 2 1];
out = cellstr( char(h + 48) )

You can make use of num2str() and regular expressions, regexprep(), to achieve the result.
s1 = num2str(h)
s2 = num2str(k)
s3 = num2str(l)
The array is directly converted into a string and results in the following output.
s1 = 1 2 4 3
s2 = 0 0 0 0
s3 = 0 0 2 1
Now, we can use regular expressions to find white spaces and replace it with ''
s1 = regexprep(s1,'\s+', '')
s2 = regexprep(s2,'\s+', '')
s3 = regexprep(s3,'\s+', '')
This produces the following result.
s1 = 1243
s2 = 0000
s3 = 0021

In 16b you can use the new string class. The string constructor will convert the numeric array to a string array of the same dimensions. Join will concatenate the elements together.
>> b = [1 2 4 3];
>> string(b).join('')
ans =
string
"1243"

h = [1 2 4 3];
k = [0 0 0 0];
l = [0 0 2 1];
strrep(num2str(h), ' ', ''); % this will return '1234'
strrep(num2str(k), ' ', ''); % this will return '0000'
strrep(num2str(l), ' ', ''); % this will return '0021'

Related

Using cell arrays and getting too many input arguments error

I'm a beginner in MATLAB. I have my function testnetwork:
function result = TestNetwork(network, input)
result = input;
b= [-1 -1 -1 -1 ];
% Iterate over all the couches
for i=1:length(network.couches)
result = network.activation(matrix_multiplication_same_dimension(network.couches{i} , vertcat ( result , b)));
end
end
and this is my main script:
% initialis a cell of zeros for example output = zeros_quat(zeros(1, 2)) is %equal to [0 0 0 0] [0 0 0 0]
output = zeros_quat(zeros(10, size(testset,2)));
%
for i = 1:size(testset, 2)
%testset is a cell of arrays size (81 * 180)
output {:,i} = TestNetwork(network, testset{:,i});
end
end
I get the error too many input arguments. I don't know what the problem is.
This line is the problem:
output {:,i} = TestNetwork(network, testset{:,i});
When you de-reference the cell array testset using curly braces {} with multiple entries, it takes the individual cells of the cell array and returns all of them as separate arguments:
a = { [ 1 2], [3 4] };
a{1}
ans =
1 2
a{1,:}
ans =
1 2
ans =
3 4
Note the two instances of ans in the second evaluation. I suspect that what you really want is a reference to a single cell on both sides of the equation:
output{i} = TestNetwork(network, testset{i});

Matlab: How do I re-insert elements in an array?

My original array was A = [1 0 2 3 0 7]. I deleted the indexes with a zero in them, and got A = [1 2 3 7]. I stored the indexes of the elements I deleted in an array called DEL = [2 5].
How can I re-insert the zeros in the array to get back the original array?
This will do it for you:
A = [1 2 3 7];
DEL = [2 5];
n = numel(A) + numel(DEL);
B = zeros(1,n);
mask = true(1,n);
mask(DEL) = false;
B(mask) = A;
Alternatively, you can set the mask in one line using:
mask = setdiff(1:n, DEL);
Result:
B =
1 0 2 3 0 7
A = [1 0 2 3 0 7] ;
A_ = [1 2 3 7] ;
[~,i] = find (A) ;
B = zeros (1,length(A)) ;
B(i) = A_ ;
A = [1 2 3 7];
DEL = [2 5];
array_indices = 1:6; % the indices of the original array
array_indices(DEL) = []; % indices of numbers that were not deleted
B = zeros(1,6); % created zeros of the same length as original array
B(array_indices) = A; % replace zeros with non-zero #s at their locations

find specific zeros grouped in an array - matlab

I have an array like this one
a=[0 0 0 1 1 1 1 0 0];
and would like if the community would know an elegant way to find the last occurrence of 0 in the first group and the first occurrence of 0 in the last group of zeros. Please note there is always ones between the two groups of zeros. The answer should look like this
b=[0 0 1 0 0 0 0 1 0];
strfind based approach that works pretty well with numeric arrays to find patterns like these, seems like a good fit to solve it. Here's the implementation -
%// Find indices where we have matches of [0 1] and [1 0] corresponding to
%// the two cases as listed in the question
case1_idx = strfind(a,[0 1])
case2_idx = strfind(a,[1 0])
%// Initialize output array; set those required positions in it as ones
b = zeros(size(a))
b([case1_idx(1) case2_idx(end)+1]) = 1
Sample run -
a =
0 0 0 1 1 1 1 0 0
b =
0 0 1 0 0 0 0 1 0
How about this descriptive solution:
afterA = [a(2:end),nan]
beforeA = [nan,a(1:end-1)]
b = (a==0 & afterA==1) | (a==0 & beforeA==1)
d = diff(a)
res = zeros(size(a))
res(find(d==1)) = 1
res(find(d==-1)+1) = 1
or (assuming that a always starts and ends with a 0), you would not even need to search the entire array
res = zeros(size(a))
res(find(a, 1, 'first')-1) = 1
res(find(a, 1, 'last')+1) = 1
With convolution:
b = zeros(size(a)); %// initiallize
x = conv(2*a-1,[1 -1],'same'); %// convolution
b(find(x==2)) = 1; %// last zero in a run
b(find(x==-2)+1) = 1; %// first zero in a run
Or you could use the same approach with diff instead of conv:
b = zeros(size(a)); %// initiallize
c = diff(a); %// compute differences
b(find(c==1)) = 1; %// last zero in a run
b(find(c==-1)+1) = 1; %// first zero in a run

Create all possible Mx1 vectors from an Nx1 vector in MATLAB

I am trying to create all possible 1xM vectors (word) from a 1xN vector (alphabet) in MATLAB. N is > M. For example, I want to create all possible 2x1 "words" from a 4x1 "alphabet" alphabet = [1 2 3 4];
I expect a result like:
[1 1]
[1 2]
[1 3]
[1 4]
[2 1]
[2 2]
...
I want to make M an input to my routine and I do not know it beforehand. Otherwise, I could easily do this using nested for-loops. Anyway to do this?
Try
[d1 d2] = ndgrid(alphabet);
[d2(:) d1(:)]
To parameterize on M:
d = cell(M, 1);
[d{:}] = ndgrid(alphabet);
for i = 1:M
d{i} = d{i}(:);
end
[d{end:-1:1}]
In general, and in languages that don't have ndgrid in their library, the way to parameterize for-loop nesting is using recursion.
[result] = function cartesian(alphabet, M)
if M <= 1
result = alphabet;
else
recursed = cartesian(alphabet, M-1)
N = size(recursed,1);
result = zeros(M, N * numel(alphabet));
for i=1:numel(alphabet)
result(1,1+(i-1)*N:i*N) = alphabet(i);
result(2:M,1+(i-1)*N:i*N) = recursed; % in MATLAB, this line can be vectorized with repmat... but in MATLAB you'd use ndgrid anyway
end
end
end
To get all k-letter combinations from an arbitrary alphabet, use
n = length(alphabet);
aux = dec2base(0:n^k-1,n)
aux2 = aux-'A';
ind = aux2<0;
aux2(ind) = aux(ind)-'0'
aux2(~ind) = aux2(~ind)+10;
words = alphabet(aux2+1)
The alphabet may consist of up to 36 elements (as per dec2base). Those elements may be numbers or characters.
How this works:
The numbers 0, 1, ... , n^k-1 when expressed in base n give all groups of k numbers taken from 0,...,n-1. dec2base does the conversion to base n, but gives the result in form of strings, so need to convert to the corresponding number (that's part with aux and aux2). We then add 1 to make the numbers 1,..., n. Finally, we index alphabet with that to use the real letters of numbers of the alphabet.
Example with letters:
>> alphabet = 'abc';
>> k = 2;
>> words
words =
aa
ab
ac
ba
bb
bc
ca
cb
cc
Example with numbers:
>> alphabet = [1 3 5 7];
>> k = 2;
>> words
words =
1 1
1 3
1 5
1 7
3 1
3 3
3 5
3 7
5 1
5 3
5 5
5 7
7 1
7 3
7 5
7 7
use ndgrid function in Matlab
[a,b] = ndgrid(alphabet)

Adding Arrays of Digits as if They Represented Numbers

I have the following problem. Suppose I have to arrays X and Y whose entries consist of integers in the range 0 through 9 like
X = [1 2 3]
Y = [7 0 9]
I want to think of these arrays as being the digits of base-10 numbers, so X represents the number 123 and Y represents the number 709. I want to write a program which outputs the digits of the sum of these integers. So in the example given, it should output the array
Z = [8 3 2]
since 123 + 709 = 832. For the sake of this question it suffices to assume that X and Y have the same length, i.e., that the numbers they represent have the same number of digits. While I am doing this, I also want to keep track of carries which were performed during the addition. So in the example, I'd also want to output
C = [0 0 1]
which represents that I had to carry a 1 when I added the digits 9 + 3 = 12, but that the additions of the digits in other positions went through without carries. So my main question is
Does anyone know of a simple way to achieve this goal using MATLAB?
So far, what I've come up with is the following code which is given the two numbers as X and Y
clear all; clc;
C = zeros(1, length(X));
for j=length(X):-1:1
if X(j) + Y(j) > 9
C(j) = 1;
end
Z(j) = mod(X(j) + Y(j), 10);
if j < length(X)
if Z(j) + C(j+1) < 9
Z(j) = Z(j) + C(j+1);
else
Z(j) = mod(Z(j) + C(j+1), 10);
C(j) = 1;
end
end
end
if C(1) == 1
Z = [1 Z];
end
Z
C
The problem is that the code only works sometimes. For example, it has no problem working through the example I gave above, that 123 + 709 = 832 with a "carry array" of [0 0 1]. But the input X = 52514 and Y = 41525 does not yield the correct results. So my follow up question is
Does anyone see the bug in the code above/how can I fix it?
You need to change the line
if Z(j) + C(j+1) < 9
to
if Z(j) + C(j+1) <= 9
Then it should work.
You can take advantage of dec2base, str2num and num2str functions:
function StackOverflow
x = [1 2 3];
y = [4 5 6];
numX = DigitsToNum(x);
numY = DigitsToNum(y);
digits = NumToDigits(numX+numY);
disp(digits);
end
function digits = NumToDigits(x)
digits = double( dec2base(x,10) - '0');
end
function num = DigitsToNum(x)
st = strrep(num2str(x),' ','');
num = str2num(st); %#ok<ST2NM>
end
Another way to implement the two functions above:
function digits = NumToDigits(x)
digits = [];
while x > 0
digits(end+1) = mod(x,10); %#ok<AGROW>
x = floor(x/10);
end
end
function num = DigitsToNum(x)
baseMult = power(10,0: (numel(x)-1));
num = sum( baseMult.*x );
end

Resources