How to read in user input as binary data in MATLAB? - matlab

I am working on a program for class and we need to read in a 4-bit input (e.x. 1101) from a user and treat is as a 4-bit digital data. We then need to plot this input data and use it later to calculate the Cyclic Code base on a generator polynomial we are given.
However, after looking into MATLAB input, I'm not sure how to read in the users input as a "binary input", what would be the best way to accomplish this?
Thank you!
Here is the exact part of the instructions I am having trouble with:
Ask the user for a 4-bit input digital data and plot the user given digital data
We then use that input to do the following, which I think I should be able to do once I figure out how to get the user input!
Using the polynomial P(X) = 1 + X + X3, generate the valid codeword and transmit
the codeword

You can use the input function to ask the user to insert the digit.
b4_in = input('Insert 4-bit input: ' ,'s');
The "0" "1" sequence is stored in the output variable b4_in as a string.
In MatLab binary numbers are actually string of char; you can use, for example, bin2dec to convert binary number string to decimal number).
Then you can make some check on the input validy:
length must be equal to 4
the string must contain only "0" and "1" (you can use regexp.
The whole code could be:
% Prompt for User input
b4_in = input('Insert 4-bit input: ' ,'s');
% Get the number of input digit
n_c=length(b4_in);
% Check the number of input digit
if(n_c < 4)
disp([num2str(n_c) ': Not enough input digit. 4 digits are required'])
elseif(n_c > 4)
disp([num2str(n_c) ': Too many input digit. 4 digits are required'])
else
% Check if all the input digit are valid
inv_c=regexp(b4_in,'[a-z_A-Z2-9]');
if(~isempty(inv_c))
disp(['Invalid char: ' b4_in(inv_c) ' idx= ' num2str(inv_c)])
else
% Valid input: 4 digit, only "0" or "1"
disp([b4_in ' Valid input'])
end
end
Hope this helps.
Qapla'

Related

How to restrict input string in length,symbols, char and numbers in MATLAB

I am developing an app where the user inputs a string which need several restrictions. How can I check that the input is in the format 'LLL-NN-NNN' where L is lettes (A-Z) and N is numbers (0-9), and the string have to be exactly 10 characters in total.
if ~isempty(regexp(your_string, '^[A-Z]{3}-\d{2}-\d{3}$', 'match', 'once'))
% your code
end

Converting a .txt file with 1 million digits of "e" into a vector in matlab

I have a text file with 1 million decimal digits of "e" number with 80 digits on each line excluding the first and the last line which have 76 and 4 digits and the file has 12501 lines. I want to convert it into a vector in matlab with each digit on each row. I tried num2str function, but the problem is that it gets converted like for example '7.1828e79' (13 characters). What can I do?
P.S.1: The first two lines of the text file (76 and 80 digits) are:
7182818284590452353602874713526624977572470936999595749669676277240766303535 47594571382178525166427427466391932003059921817413596629043572900334295260595630
P.S.2: I used "dlmread" and got a 12501x1 vector, with the first and second row of 7.18281828459045e+75 and 4.75945713821785e+79 and the problem is that when I use num2str for example for the first row value, I get: '7.182818284590453e+75' as a string and not the whole 76 digits. My aim was to do something like this:
e1=dlmread('e.txt');
es1=num2str(e1);
for i=1:12501
for j=1:length(es1(1,:))
a1((i-1)*length(es1(1,:))+j)=es1(i,j);
end
end
e_digits=a1.';
but I get a string like this:
a1='7.182818284590453e+754.759457138217852e+797.381323286279435e+799.244761460668082e+796.133138458300076e+791.416928368190255e+79 5...'
with 262521 characters instead of 1 million digits.
P.S.3: I think the problem might be solved if I can manipulate the text file in a way that I have one digit on each line and simply use dlmread.
Well, this is not hard, there are many ways to do it.
So first you want to load in your file as a Char Array using something simple like (you want a Char Array so that you can easily manipulate it to forget about the lines breaks) :
C = fileread('yourfile.txt'); %loads file as Char Array
D = C(~isspace(C)); %Removes SPACES which are line-breaks
Next, you want to actually append a SPACE between each char (this is because you want to use the num2str transform - and matlab needs to see the space), you can do this using a RESHAPE, a STRTRIM or simply a REGEX:
E = strtrim(regexprep(D, '.{1}', '$0 ')); %Add a SPACE after each Numeric Digit
Now you can transform it using str2num into a Vector:
str2num(E)'; %Converts the Char Array back to Vector
which will give you a single digit each row.
Using your example, I get a vector of 156 x 1, with 1 digit each row as you required.
You can get a digit per row like this
fid = fopen('e.txt','r');
c = textscan(fid,'%s');
c=cat(1,c{:});
c = cellfun(#(x) str2num(reshape(x,[],1)),c,'un',0);
c=cat(1,c{:});
And it is not the only possible way.
Could you please tell what is the final task, how do you plan using the array of e digits?

Regexp equivalent for floating number in matlab

I'd like to know how regexp is used for floating numbers or is there any other function to do this.
For example, the following returns {'2', '5'} rather than {'2.5'}.
nums= regexp('2.5','\d+','match')
Regular expressions are a tool for low-level text parsing and they have no concept of numeric datatypes. If you will want to parse decimals, you need to consider what characters compose a decimal number and design a regexp to explicitly match all of those characters.
Your example only returns the '2' and '5' because your pattern only matches characters that are digits (\d). To handle the decimal numbers, you need to explicitly include the . in your pattern. The following will match any number of digits followed by 0 or 1 radix points and 0 or more numbers after the radix point.
regexp('2.5', '\d+\.?\d*', 'match')
This assumes that you'll always have a leading digit (i.e. not '.5')
Alternately, you may consider using something like textscan or sscanf instead to parse your string which is going to be more robust than a custom regex since they are aware of different numeric datatypes.
C = textscan('2.5', '%f');
C = sscanf('2.5', '%f');
If your string only contains this floating point number, you can just use str2double
val = str2double('2.5');
#Suever answer has already been accepted, anyway here is some more complete one that should accept all sorts of floating points syntaxes (including NaN and +/-Inf by default):
% Regular expression for capturing a double value
function [s] = cdouble(supportPositiveInfinity, supportNegativeInfinity,
supportNotANumber)
%[
if (nargin < 3), supportNotANumber = true; end
if (nargin < 2), supportNegativeInfinity = true; end
if (nargin < 1), supportPositiveInfinity = true; end
% A double
s = '[+\-]?(?:(?:\d+\.\d*)|(?:\.\d+)|(?:\d+))(?:[eE][+\-]?\d+)?'; %% This means a numeric double
% Extra for nan or [+/-]inf
extra = '';
if (supportNotANumber), extra = ['nan|' extra]; end
if (supportNegativeInfinity), extra = ['-inf|' extra]; end
if (supportPositiveInfinity), extra = ['inf|\+inf|' extra]; end
% Adding capture
if (~isempty(extra))
s = ['((?i)(?:', extra, s, '))']; % (?i) => Locally case-insensitive for captured group
else
s = ['(', s, ')'];
end
%]
end
Basically above pattern says:
Eventually start with '+' or '-' sign
Then followed by either
One or more digits followed by a dot and eventually zero to many digits
A dot followed by one or more digits
One or more digits only
Then followed by exponant pattern, that is:
'e' or 'E' (eventually followed with '+' or '-') and one or more digits
Pattern is later completed with support of Inf, +Inf, -Inf and NaN in case insensitive way. Finally everthing is enclosed between ( and ) for capturing purpose.
Here is some online test example: https://regex101.com/r/K87z6e/1
Or you can test in matlab:
>> regexp('Hello 1.235 how .2e-7 are INF you +.7 doing ?', cdouble(), 'match')
ans =
'1.235' '.2e-7' 'INF' '+.7'

How to convert a string of numbers from an input into an array/vector?

Inputting a number, e.g.
StudentNo = input('Please input your student number: ')
so that
StudentNo = 54456842
Putting this in and then making it into individual numbers
StudentNo = [5,4,4,5,6,8,4,2]
in order to find the avg or other stats from the digits without getting NaN?
You can break it up into digits with the following approach
str2num(num2str(StudentNo).')
This first converts StudentNo to a string, then takes the transpose such that each character is on it's own line, and then we call str2num to convert each row to a separate number.
Another option would be to convert to a string and then subtract off the ASCII value of '0' to convert each character to a numeric digit
num2str(StudentNo) - '0'
Suever's approach is a neat way to do this. However, if you don't need the actual number as a number, and you only need the separate digits, then you can specify directly that you want the numbers as a string in the input-call.
StudentNo = input('Please input student number: ', 's')
Here, the 's' specifies that the input is a string. This way you can input the StudentNo without having apostrophes.
StudentNo = input('Please input student number: ', 's')
Please input student number: 54456842
StudentNo =
54456842
You can now use any of the two approaches in Suever's answer to convert this to separate numbers. Another option is to simply do the subtraction by '0' in the call itself:
StudentNo = input('Please input student number: ', 's')-'0'
Please input student number: 54456842
StudentNo =
5 4 4 5 6 8 4 2
Since this is a bit hard to read, you can also have this as an anonymous function:
stid = #() input('Please input student number: ', 's')-'0';
And call it like this:
stid()
Please input student number: 123456
ans =
1 2 3 4 5 6
Input captures a single number. It would be hard to know how many digits each of the student numbers is so I would suggest getting them one by one:
StudentNo = input('Please input your student number one by one (end with -1): ');
while StudentNo(end)~= -1
StudentNo = [StudentNo, input('Please input the next student number (end with -1): ')];
end
% remove the -1
StudentNo = StudentNo(1:end-1);
EDIT
Based on #StewieGriffin: comment if you have multi-digit student number you could just do this:
StudentNo = input('Please input the next student number: ')];
[1 2 12 13]
This will detect each number as separate entry in a vector of your student numbers.

Matlab: Function that returns a string with the first n characters of the alphabet

I'd like to have a function generate(n) that generates the first n lowercase characters of the alphabet appended in a string (therefore: 1<=n<=26)
For example:
generate(3) --> 'abc'
generate(5) --> 'abcde'
generate(9) --> 'abcdefghi'
I'm new to Matlab and I'd be happy if someone could show me an approach of how to write the function. For sure this will involve doing arithmetic with the ASCII-codes of the characters - but I've no idea how to do this and which types that Matlab provides to do this.
I would rely on ASCII codes for this. You can convert an integer to a character using char.
So for example if we want an "e", we could look up the ASCII code for "e" (101) and write:
char(101)
'e'
This also works for arrays:
char([101, 102])
'ef'
The nice thing in your case is that in ASCII, the lowercase letters are all the numbers between 97 ("a") and 122 ("z"). Thus the following code works by taking ASCII "a" (97) and creating an array of length n starting at 97. These numbers are then converted using char to strings. As an added bonus, the version below ensures that the array can only go to 122 (ASCII for "z").
function output = generate(n)
output = char(97:min(96 + n, 122));
end
Note: For the upper limit we use 96 + n because if n were 1, then we want 97:97 rather than 97:98 as the second would return "ab". This could be written as 97:(97 + n - 1) but the way I've written it, I've simply pulled the "-1" into the constant.
You could also make this a simple anonymous function.
generate = #(n)char(97:min(96 + n, 122));
generate(3)
'abc'
To write the most portable and robust code, I would probably not want those hard-coded ASCII codes, so I would use something like the following:
output = 'a':char(min('a' + n - 1, 'z'));
...or, you can just generate the entire alphabet and take the part you want:
function str = generate(n)
alphabet = 'a':'z';
str = alphabet(1:n);
end
Note that this will fail with an index out of bounds error for n > 26, so you might want to check for that.
You can use the char built-in function which converts an interger value (or array) into a character array.
EDIT
Bug fixed (ref. Suever's comment)
function [str]=generate(n)
a=97;
% str=char(a:a+n)
str=char(a:a+n-1)
Hope this helps.
Qapla'