Integer array to binary array - arrays

I have an integer array:
a=[3,4,5,6,7];
I want to convert it to a binary array with four bits each. For the above integer array I would like get the following binary array:
abinary=[0,0,1,1, 0,1,0,0, 0,1,0,1, 0,1,1,0, 0,1,1,1];
Is there any fast way to do it?

Matlab has the built-in function DEC2BIN. It creates a character array, but it's easy to turn that back to numbers.
%# create binary string - the 4 forces at least 4 bits
bstr = dec2bin([3,4,5,6,7],4)
%# convert back to numbers (reshape so that zeros are preserved)
out = str2num(reshape(bstr',[],1))'

You can use the BITGET function:
abinary = [bitget(a,4); ... %# Get bit 4 for each number
bitget(a,3); ... %# Get bit 3 for each number
bitget(a,2); ... %# Get bit 2 for each number
bitget(a,1)]; %# Get bit 1 for each number
abinary = abinary(:)'; %'# Make it a 1-by-20 array

A late answer I know, but MATLAB has a function to do this directly de2bi
out = de2bi([3,4,5,6,7], 4, 'left-msb');

Related

How to convert bytes back to a list of integers when it has been packed using 2 bytes per int and 'big' order?

I am using converting a list of integers into bytes using the to_bytes function. As some numbers in my list are greater than 255 and can get pretty large; I arbitrarily decided to store them using 3 bytes.
So in my loop I do the following:-
for number in original_array:
byte_file_writer_delta.write(number.to_bytes(3, byteorder='big'))
So for example if I have a numbers like [1900, 1901] in my original array. When I convert it back using the following code, I get something like
[0, 7, 108, 0, 7, 109] in my output. I am trying to see the numbers 1900 and 1901 when I read them back from the file. The code I use to read back the numbers is:
byte_file_reader= open('byte_file_inverted_index.txt', 'rb')
byte_file_reader.seek(byte_offset)
mybytes=byte_file_reader.read(byte_size)
print(list(mybytes))
See if the following script may somehow help you... I believe the bytes_to_int function will do just fine for you!
i've used a few numbers for testing (original_array)
original_array = [1,2,3,4,5,6,7,10,1500,2999,50000,789456,9999999]
def bytes_to_int(bytes):
result = 0
for b in bytes:
result = result * 256 + int(b)
return result
for number in original_array:
enc = number.to_bytes(3, byteorder='big')
print(enc)
dec = bytes_to_int(enc)
print(dec)

Using binary strings on storing ordered items in database

In this post, #boisvert mentioned that if using string as the order field's value, it is best shown for a binary string, and then gave an algorithm to calculate the average of two binary strings as follows:
Avalue = 1+0*(1/2)+1*(1/4)+1*(1/8)
Bvalue = 1+1*(1/2)+0*(1/4)+0*(1/8)
average, new value = 1+0*(1/2)+1*(1/4)+1*(1/8)+1*(1/16) new string = "10111"
content order
--------------------
A '1011'
new! '10111'
B '1100'
C '1101'
I couldn't understand these very well, what's the value of the first item putting into the DB and the items inserting before/after it? How to calculate the average between '1011' and the new value '10111', or between '111' and '1000'?
Any help is much appreciated.
The binary strings are fractions, not integers; the decimal point is always at the beginning (or after the first digit, in #boisvert's answer; it doesn't make any difference as long as the position of the decimal point is fixed. Of course, it's actually a binary point since these are binary numbers.)
To find the average:
If the strings differ in length, put enough 0s at the end of the shorter string so that it is the same length as the longer string.
Add the two strings together, using binary addition, always putting the last carry at the beginning, even if it is ยด0'. [See algorithm below].
Remove any 0s at the end.
Example 1: 1011 and 10111
Extend the first string with a 0: 10110 and 10111
Find the sum:
A: 10110
B: 10111
Carry: 101100
Sum: 101101
No trailing zeros, so the result is 101101
Example 2: 111 and 1000
1. 1110 1000
2. 10110
3. 1011
Starting off and insertion at the end:
The first item put into the database has the label 1. If at any point you need to add an item at the very beginning, use the first label with a 0 before it. Similarly, if you need to add an item at the end, use the first label with a 1 before it.
Binary addition:
Since the strings are the same length, this is easy; set Carry to 0, and scan both strings from back to front. (The output is also produced back-to-front.)
At each position:
* If the sum of Carry and the two digits is 1 or 3, output a 1, otherwise output a 0.
* If the sum of Carry and the two digits is 2 or 3, set Carry to 1, otherwise set it to 0.
When you've finished all the digits, output the value of Carry.
Practical implementation:
In practice, you wouldn't use binary strings; you'd use some fairly large base, the only requirement being that it is even. But the algorithms are the same. When constructing the representation of your numbers, you need to assign digits to characters in alphabetical order, so that the resulting strings can be sorted alphabetically without converting them to numbers; the database doesn't know how to convert to numbers, but it knows how to sort strings alphabetically.

Breaking up a string and then converting to a vector?

If I have three strings, such as 'Y20194', '219Y42', and '12345' how do I break these up into a vector like [Y 2 0 1 9 4], [1 2 3 4 5], and [2 1 9 Y 4 2]? I am using str2num, but I think I am missing a step (separating the individual numbers in the strings first) before I convert to numerical values. Also, the characters aren't reading correctly and using str2num gives me [].
I have a file with lines of strings such as the one above. I used fgetl to read each line of my file into strings but am kind of stuck beyond that.
You cannot have both characters and numbers in a numerical vector.
You can do the following:
s = 'Y20194';
c = cellstr(s')';
v = str2double(c);
Cell array c will have all the characters from s separated in to individual cells. Notice that you have to transpose the string s first.
In vector v the first value will be NaN since it's a character.
The char will be kept. and the numbers will be converted to double type.
If the input is not from reading a file, the code is as follows. The result1 is the cell containing the array you want:
If the input is one file, let's take this file as example: demo1.txt, which content as follows:
the codes to convert each line to what you want as follows. the code converts each line into what you want and then display it.
If you want to replace the 'Y' or other alphabets with zero, then the code will be as follows
Maybe STRSPLIT will help.
ts = strsplit('Y20194');
% ts <- {'Y', '2', '0', '1', '9', '4'}
And now you can try to convert each element in the vector individually to a number using str2num.
N = size(ts, 1);
str = cell(1, N);
for i=1:N;
str{i} = str2num(ts{i, 1});
end
But since some of the characters in the string aren't numbers (e.g., 'Y'), I wouldn't expect this to work perfectly.
(Its been a while, some of my indexes may be switched.)
If you want to change the Y into 0 a very simple solution is available:
str = 'Y20194';
str(str==Y)='0';
str - '0'

Storing integers in cell arrays in Matlab

I have a problem when using cell arrays in an m-file. I create a number of cell arrays using the function given in here. What I store on each of these arrays is numerical values being read from a text file (I convert them to string before I put them into the arrays). The problem is that the some numbers doesn't seem to be strored in the arrays correctly:
The text file contains that:
1976787196
8
1976945848
8
1977105448
8
And the contents of a cell array in which the above is store are the following:
Columns 1 through 3
1976787196 681405151445000 1976945848
Columns 4 through 6
685476780441608 1977105448 685476780441608
As you can see, instead of stroring 8, I get a very big integer.
Actually, I want all the contents of the cell arrays that I create to contain only 32-bit integers. Can I specify that requirement somehow? Thanks in advance!
It depends how you read the data from text file. Try using TEXTSCAN function. Format string '%u32' specifies that you want to read unsigned 32-bit integer data.
filename = 'test.txt';
fid = fopen(filename,'r');
x = textscan(fid,'%u32','delimiter','\t','CollectOutput',1);
x = x{1};
fclose(fid);

MATLAB: comparing all elements in three arrays

I have three 1-d arrays where elements are some values and I want to compare every element in one array to all elements in other two.
For example:
a=[2,4,6,8,12]
b=[1,3,5,9,10]
c=[3,5,8,11,15]
I want to know if there are same values in different arrays (in this case there are 3,5,8)
The answer given by AB is correct, but it is specific for the case when you have 3 arrays that you are comparing. There is another alternative that will easily scale to any number of arrays of arbitrary size. The only assumption is that each individual array contains unique (i.e. non-repeated) values:
>> allValues = sort([a(:); b(:); c(:)]); %# Collect all of the arrays
>> repeatedValues = allValues(diff(allValues) == 0) %# Find repeated values
repeatedValues =
3
5
8
If the arrays contains repeated values, you will need to call UNIQUE on each of them before using the above solution.
Leo is almost right, should be
unique([intersect(a,[b,c]), intersect(b,c)])
c(ismember(c,a)|ismember(c,b)),
ans =
3 5 8
I think this works for all matrices.
Define what you mean by compare. If the arrays are of the same length, and you are comparing equality then you can just do foo == bar -- it's vectorized. If you need to compare in the less than/greater than sense, you can do sign(foo-bar). If the arrays are not the same length and/or you aren't comparing element-wise -- please clarify what you'd like the output of the comparison to be. For instance,
foo = 1:3;
bar = [1,2,4];
baz = 1:2;
sign(repmat(foo',1,length([bar,baz])) - repmat([bar, baz],length(foo),1))
# or, more concisely:
bsxfun(#(x,y)sign(x-y),foo',[bar,baz])
does what you ask for, but there is probably a better way depending on what you want as an output.
EDIT (OP clarified question):
To find common elements in the 3 arrays, you can simply do:
>> [intersect(a,[b,c]), intersect(b,c)]
ans =
8 3 5

Resources