I'm trying to implement an oscilloscope for a digital input and send it over a serial port for debugging. I have the scope software sending Matlab a string like "000000111111111000000001111111000000". I'd like to plot this. Is there any way for me to split this string into a vector. It doesn't seem Matlab allows you to use strsplit() without a delimiter. I'd rather not bog up the communications with a delimiter between each byte.
With MATLAB's weak typing, this is actually quite easy:
>> str = '000000111111111000000001111111000000'
str = 000000111111111000000001111111000000
>> class(str)
ans = char
>> vec = str - '0'
vec =
Columns 1 through 22:
0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0
Columns 23 through 36:
0 1 1 1 1 1 1 1 0 0 0 0 0 0
>> class(vec)
ans = double
This subtracts the ordinal value of the character '0' from each character in the string, leaving the numerical values 0 or 1.
You can use sscanf with a single value width:
a = '000000111111111000000001111111000000'
b = sscanf(a, '%1d');
Which returns:
>> b.'
ans =
Columns 1 through 18
0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0
Columns 19 through 36
0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0
A quick and fast solution is:
data = '000001111111110000000000111111111110000000';
vec = str2double(cellstr(data.').');
It will produce a column vector of numeric values. If you want a row vector as output, just use a single transpose:
vec = str2double(cellstr(data.'));
I'm surprised how difficult this is to do. But here's what I came up with:
str = '000001111111110000000000111111111110000000'; %test string
y = cellfun(#(x) str2num(x), regexp(str,'\d','match'));
plot(y);
regexp() seems to be the only way to go. By default, it return indexes of matches so you need to specify 'match'. Then you end up with a cell array of strings. The only good way to convert this into a numerical array is one item at a time with str2num().
I hope this helps someone else out who is assuming there is a straight forward function as I assumed. And if anyone knows a way to do this without converting my "01...01....01....01....00....00....00....00" stream of bytes into the ascii representations of the binary numbers: "49.....49.....49....49....48....48....48....48", I'd love to hear it.
Related
I want to count the number of 'noncure' occurrences across different columns with some condition, at different position dates. How do I search for the occurrence of 12 '1's across columns.
[UPDATE]
I've modified my dataset and think this is the best way to populate out my desired results.
This is a sample of my raw data
data have;
input acct flg1 flg2 flg3 flg4 flg5 flg6 flg7 flg8 flg9 flg10 flg11 flg12 flg13 flg14 flg15 flg16 flg17 flg18 flg19 flg20 flg21 flg22 flg23 flg24 flg25;
datalines;
AA 0 0 0 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
run;
The numbers on flg represent months - eg flg1 = jan10, flg2 = feb10 & so on.
To get noncure, certain conditions have to be fulfilled.
flg(i) has to be 0
noncure only happens if there is a minimum of 12 consecutive flg of '1' in the future
an account can have more than 1 noncure incidents
The computation of noncure should look like this (Refer to image for a better view - highlighted in green)
AA 1 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
noncure1 is 1 because flg1 is 0 and the next 12 1 is at flg9
noncure2 is 1 because flg2 is 0 and the next 12 1 is at flg9
noncure4 is 0 because flg4 is not 0
noncure23 is 0 because even though flg23 is 0, there is no following consecutive 12 at flg25 (only one count of '1')
I'm having problems searching for my first instance of consecutive 12 '1' at flg(i).
I was thinking of doing an array to populate out position of consecutive 12 (eg nc_pos) then do i to nc_pos - something along the lines of
nc_pos = <search for 12 consecutive occurrence of '1' from flg(i)> **I don't know the code for this**
if flg(i) = 0 then do i to nc_pos;
noncure_tag = 1;
obs_pos = i;
FYI I have few hundred thousand accounts with a total of 84 months and their starting positions are different (eg flg1 could be null and the first 0 or 1 may appear at flg3).
My final output should look something like the image file labelled TARGET highlighted in yellow.
This is my code:
Program Arrays
Implicit none
Integer::i
Integer,parameter,dimension(3,4)::Fir_array=0,Sec_array=1
Open(Unit=15,File='Output.txt',Status='Unknown',Action='Readwrite')
Do concurrent(i=1:3)
Write(15,'(1x,i0,".",4(2x,i0,1x,i0))') i,Fir_array(i,:),Sec_array(i,:)
End Do
Close(Unit=15,Status='Keep')
End Program Arrays
The content of Output.txt is:
1. 0 0 0 0 1 1 1 1
2. 0 0 0 0 1 1 1 1
3. 0 0 0 0 1 1 1 1
My intention with this code is to get this content in Output.txt:
1. 0 1 0 1 0 1 0 1
2. 0 1 0 1 0 1 0 1
3. 0 1 0 1 0 1 0 1
How to do that with do loops or implied do?
As usual, there is more than one way of going about this, but the first thing that came to my mind would be to place the desired components of fir_array and sec_array into a temporary array, in the desired order, and then print it.
! Add the following variables to your code:
integer, dimension(8) :: temp
integer :: d1
! Begin:
d1 = size(fir_array, dim=1)
do i = 1, d1
temp([1,3,5,7]) = fir_array(i,:) !! If you're clever you can create a scheme to
temp([2,4,6,8]) = sec_array(i,:) !! obtain the proper indices for arrays of any size.
write(15, '(1x,i0,".",4(2x,i0,1x,i0))') i, temp
enddo
You get the output desired:
0 1 0 1 0 1 0 1
0 1 0 1 0 1 0 1
0 1 0 1 0 1 0 1
I need to write a program which reads the statistics of n League A football teams and prints the teams name which fall in League B.
A team falls in League B, if it has less than k points after having played m weeks where m is between 1 and 150. Each team gets three points for a win, one point for draw and zero points when lost.
Input Specification: In the first line, you will be given the number of teams 0 < n ≤ 500 and the points 0 < k ≤ 300 needed to stay in league A. Then in the following n lines, there will be the team name and its results. Semicolon indicates the end of input series.
Number 2 represents win, number one represents draw and number zero represents loss.
Output specification:
Sample Input I
4 19
Team_A 1 1 1 1 1 1 1 1 1 0 1 1 1 0 2 1 0 ;
Team_B 0 1 0 2 2 1 1 0 1 1 0 2 0 1 0 0 2 ;
Team_C 0 0 1 0 2 2 2 1 1 1 1 1 0 0 2 1 2 ;
Team_D 0 1 0 1 2 1 2 1 0 0 0 2 2 2 0 0 0 ;
Sample Output I
Team_A 16
Team_B 18
This is the code I came up with, but the output is wrong and I don't know why,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int n,points,sum=0,i,value;
char name[15];
char p;
scanf("%d %d",&n,&points);
for(i=1;i<=n;i++)
{
scanf("%s",&name);
do
{
scanf("%c ",&p);
if(p!=';')
{
value=p-48;
sum=sum+value;
}
}while(p!=';');
if(sum<=points)
printf("%s %d",name,sum);
}
return 0;
}
You might look for problems by stuffing the program with output statements.
If you add after scanf("%c ",&p); an output statement to show the value of p, you will find that the first value for p is a space character, which spoils your calculation.
In the same way, if you trace the value of value, you will find that you forgot to initialize this variable to zero for each team.
I am trying to access the sparse mlf with the keys such as BEpos and BEneg where one key per line. Now the problem is that most commands are not meant to deal with too large input: bin2dec requires clean binary numbers without spaces but the regexp hack fails to too many rows -- and so on.
How to work with sparse keys to access sparse data?
Example
K>> mlf=sparse([],[],[],2^31,1);
BEpos=Cg(pos,:)
BEpos =
(1,1) 1
(2,3) 1
(2,4) 1
K>> mlf(bin2dec(num2str(BEpos)))=1
Error using bin2dec (line 36)
Binary string must be 52 bits or less.
K>> num2str(BEpos)
ans =
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
K>> bin2dec(num2str('1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'))
Error using bin2dec (line 36)
Binary string must be 52 bits or less.
K>> regexprep(num2str(BEpos),'[^\w'']','')
Error using regexprep
The 'STRING' input must be a one-dimensional array
of char or cell arrays of strings.
Manually works
K>> mlf(bin2dec('1000000000000000000000000000000'))
ans =
All zero sparse: 1-by-1
Consider a different approach using manual binary to decimal conversions:
pows = pow2(size(BEpos,2)-1 : -1 : 0);
inds = uint32(BEpos*pows.')
I haven't benchmarked this, but it might work faster than bin2dec and cell arrays.
How it works
This is pretty simple: the powers of 2 are calculated and stored in pows (assuming the MSB is in the leftmost position). Then they are multiplied by the bits in the matching positions and summed to produce the corresponding decimal values.
Try to index with this:
inds = uint32( bin2dec(cellstr(num2str(BEpos,'%d'))) );
i want to generate a pseudo-random bool stream based on a modulo operation on another stream of integers (say X), so the operation would be
return ( X % 2);
The only problem is that X is a stream of integers that always ends in 1, so for instance would be somehing like 1211, 1221, 1231, 1241 .... is there a way for me to disregard the last bit (without using string manip) so the test doesnt always pass or always fail?
How about (X / 10) % 2 then?
If you'd otherwise be happy to use the last bits, use the penultimate bits instead:
return (x & 0x2) >> 1;
So say the next number from your stream is 23:
1 0 1 1 1 // 23 in binary
& 0 0 0 1 0 // 0x2 in binary
-----------
0 0 0 1 0
Shifting that right by one bit (>> 1) gives 1. With 25, the answer would be 0:
1 1 0 0 1
& 0 0 0 1 0
-----------
0 0 0 0 0
return ( x%20/10 );