Matlab: Making code for coinflip - matlab

I'm having trouble with this problem since I'm new to matlab
"Use help to learn about the built in function ‘rand’. Write a script to use the rand function to generate a sequence of ‘head’ or ‘tail’ where one is head and zero is tail. The other function that you need to use is ‘round’ to convert the output of the ‘rand’ function to an integer. When we run your function it should display something like this: “T H T T H H H…..”.
I've used the help function and searched online but I still don't understand the random function.
I've used
flip = random('norm',1:10,1)
flip =
1.0774 0.7859 1.8865 3.9932 6.5326 5.2303 7.3714 7.7744 10.1174 8.9109
As you can see, it keeps giving me random numbers. I want my numbers to be either 0 or 1.
I know the 10 in 1:10 will display 10 values, but what does the two 1's mean?
I'd appreciate any help, thanks!

For completeness, there's also the randi function (at least from 2011b onwards):
faceId = randi(2,1,10) % generates random integers between 1 and 2 (inclusively)
faceId =
2 2 2 1 1 2 2 1 1 2
That avoids the need for the < 0.5 comparison and the +1

You can do as follow:
faceId=rand(1,10)<0.5
faceId =
1 1 0 0 1 1 1 0 0 0
faceName='TH';
faceName(faceId+1)
ans =
THHHHTTHTH

Related

Output a matrix size n x m, 1 when the sum of the indices is even, 0 otherwise

I'm attempting the following as a hobby, not as homework. In Computer Programming with MATLAB: J. Michael Fitpatrick and Akos Ledeczi, there is a practice problem that asks this:
Write a function called alternate that takes two positive integers, n and m, as input arguments (the function does not have to check the format of the input) and returns one matrix as an output argument. Each element of the n-by-m output matrix for which the sum of its indices is even is 1.
All other elements are zero.
A previous problem was similar, and I wrote a very simple function that does what it asks:
function A = alternate(n,m)
A(1:n,1:m)=0;
A(2:2:n,2:2:m)=1;
A(1:2:n,1:2:m)=1;
end
Now my question is, is that good enough? It outputs exactly what it asks for, but it's not checking for the sum. So far we haven't discussed nested if statements or anything of that sort, we just started going over very basic functions. I feel like giving it more functionality would allow it to be recycled better for future use.
Great to see you're learning, step 1 in learning any programming language should be to ensure you always add relevant comments! This helps you, and anyone reading your code. So the first improvement would be this:
function A = alternate(n,m)
% Function to return an n*m matrix, which is 1 when the sum of the indices is even
A(1:n,1:m)=0; % Create the n*m array of zeros
A(2:2:n,2:2:m)=1; % All elements with even row and col indices: even+even=even
A(1:2:n,1:2:m)=1; % All elements with odd row and col indicies: odd+odd=even
end
You can, however, make this more concise (discounting comments), and perhaps more clearly relate to the brief:
function A = alternate(n,m)
% Function to return an n*m matrix, which is 1 when the sum of the indices is even
% Sum of row and col indices. Uses implicit expansion (R2016b+) to form
% a matrix from a row and column array
idx = (1:n).' + (1:m);
% We want 1 when x is even, 0 when odd. mod(x,2) is the opposite, so 1-mod(x,2) works:
A = 1 - mod( idx, 2 );
end
Both functions do the same thing, and it's personal preference (and performance related for large problems) which you should use.
I'd argue that, even without comments, the alternative I've written more clearly does what it says on the tin. You don't have to know the brief to understand you're looking for the even index sums, since I've done the sum and tested if even. Your code requires interpretation.
It can also be written as a one-liner, whereas the indexing approach can't be (as you've done it).
A = 1 - mod( (1:n).' + (1:m), 2 ); % 1 when row + column index is even
Your function works fine and output the desired result, let me propose you an alternative:
function A = alternate(n,m)
A = zeros( n , m ) ; % pre-allocate result (all elements at 0)
[x,y] = meshgrid(1:m,1:n) ; % define a grid of indices
A(mod(x+y,2)==0) = 1 ; % modify elements of "A" whose indices verify the condition
end
Which returns:
>> alternate(4,5)
ans =
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
initialisation:
The first line is the equivalent to your first line, but it is the cannonical MATLAB way of creating a new matrix.
It uses the function zeros(n,m).
Note that MATLAB has similar functions to create and preallocate matrices for different types, for examples:
ones(n,m) Create
a matrix of double, size [n,m] with all elements set to 1
nan(n,m) Create a
matrix of double, size [n,m] with all elements set to NaN
false(n,m) Create a
matrix of boolean size [n,m] with all elements set to false
There are several other matrix construction predefined function, some more specialised (like eye), so before trying hard to generate your initial matrix, you can look in the documentation if a specialised function exist for your case.
indices
The second line generate 2 matrices x and y which will be the indices of A. It uses the function meshgrid. For example in the case shown above, x and y look like:
| x = | y = |
| 1 2 3 4 5 | 1 1 1 1 1 |
| 1 2 3 4 5 | 2 2 2 2 2 |
| 1 2 3 4 5 | 3 3 3 3 3 |
| 1 2 3 4 5 | 4 4 4 4 4 |
odd/even indices
To calculate the sum of the indices, it is now trivial in MATLAB, as easy as:
>> x+y
ans =
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
Now we just need to know which ones are even. For this we'll use the modulo operator (mod) on this summed matrix:
>> mod(x+y,2)==0
ans =
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
This result logical matrix is the same size as A and contain 1 where the sum of the indices is even, and 0 otherwise. We can use this logical matrix to modify only the elements of A which satisfied the condition:
>> A(mod(x+y,2)==0) = 1
A =
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
Note that in this case the logical matrix found in the previous step would have been ok since the value to assign to the special indices is 1, which is the same as the numeric representation of true for MATLAB. In case you wanted to assign a different value, but the same indices condition, simply replace the last assignment:
A(mod(x+y,2)==0) = your_target_value ;
I don't like spoiling the learning. So let me just give you some hints.
Matlab is very efficient if you do operations on vectors, not on individual elements. So, why not creating two matrices (e.g. N, M) that holds all the indices? Have a look at the meshgrid() function.
Than you might be able find all positions with an even sum of indices in one line.
Second hint is that the outputs of a logic operation, e.g. B = A==4, yields a logic matrix. You can convert this to a matrix of zeros by using B = double(B).
Have fun!

Splitting a series in two with zeros and the series value

I have the following in table in matlab
k ak
0 1
1 -0.166666667
2 0.008333333
... ...
where ak = (-1)^k/(2k+1)! but that's not really important, all that is important is that ak is a function of k and the (-1)^k.
I am trying to generate a new set of columns as below
i ai
0 1
1 0
2 -0.166666667
3 0
4 0.008333333
... ...
So far I've figured out that by stretching my indices (incrementing by 2 instead of 1) and applying the ak function it gets pretty close to what I want but it returns the absolute value.
if mod(i,2)=0
ai=(-1)^i/factorial(2*(i/2)+1);
else
ai=0;
end
How can I change this to be what I want?
You should be using this:
ai = (-1)^(ii/2)/factorial(2*(ii/2)+1);
% Notice ----^
Your if-else statements can be given a vector input and written in one-line as:
ai = ~mod(ii,2) .* (-1).^(ii/2)./factorial(2*(ii/2)+1);
%I used ii instead of i since i is for imaginary numbers in MATLAB

How to randomly generate a matrix with n 0s and m 1s in Matlab? [duplicate]

This question already has an answer here:
How do I generate a random vector (0,1) with a known probability in MATLAB
(1 answer)
Closed 7 years ago.
For example, how to randomly generate a 1-by-12 matrix that contains 8 0s and 4 1s?
Like this matrix [1 0 0 1 0 0 0 1 0 0 1 0]
And if I generate again, it returns a different matrix [0 0 1 0 0 1 1 0 1 0 0 0]
Create a vector that starts with the desired number of 1s followed by the desired number of 0s and the use randperm to shuffle it around:
n = 8;
m = 4;
M = [ones(m,1), zeros(n,1)];
M = M(randperm(numel(M)))
Or you can do it slightly differently: http://www.mathworks.com/matlabcentral/answers/83289-how-can-i-create-a-random-binary-matrix-with-a-specified-number-of-1-s-and-0-s
You can make a vector containing 12 zeros and use randsample to pick four numbers that you make one:
a = zeros(1,12);
a(randsample(12,4)) = 1;
Note: This requires the 'Statistics and Machine Learning Toolbox'.
If you do not have this, you will not be able to use randsample.
This one may work as well.
x = zeros(12,1);
tmp = rand(12,1);
[~,ind] = sort(tmp);
x(ind(1:4)) = 1;
Not sure if is better than the other examples, but it is one way to do it. I would say it is a similar solution as the one by fhdrsdg, but this one does not requires statistics toolbox. It mat also be possible that this solution may not have the same elegance as matlabs solutions may have though and randsample have more features than this example.

MATLAB syntax length

I'm reading some MATLAB trying to pick it up. The line below is probably rather simple but I do not understand it.
I understand length will give me the length of a vector, in this case a vector which is part of a struct, index_struct.data_incl.
The actual value of index_stuct.data_incl at run time is simply 1. What is confusing me is what is inside the brackets i.e. (index_struct.data_incl == 1)? I can't work out what this line is trying to do as simple as it may be!
int_var = length(index_struct.data_incl(index_struct.data_incl == 1));
try this (but think of x as your index_struct.data_incl:):
x = [1 4 5 13 1 1]
length(x(x==1))
ans =
3
It's just counting the number of elements of your x vector that are equal to 1
because x==1 evaluates to [1 0 0 0 1 1] and then using logical indexing x(x==1) evaluates to [1 1 1] whose length is 3;
It could have been written more simply as sum(index_struct.data_incl == 1)
If I dont see the code I can only guess..., but I guess that index_struc.data_incl should be a vector, with length n meaning that you have the option to read until n files, and all the values of the array should be 0 at the begining, and when you read a file you change the corresponding position in the vector index_struc.data_incl from 0 to 1. After some time you can see how many of these files you have read using
int_var = length(index_struct.data_incl(index_struct.data_incl == 1));
because it will give to you the number of 1 in the vector index_struct.data_incl.

I Need help Numeric Comparison in matlab

I have one matrix called targets (1X4000); column 1 to 2000 contains double value 0 and column 2001 to 4000 contains double value 1
a)
i want to create a matrix called targets_1 where i want to check if the value is 0 then make the entry 1 so at the end of the day i must have a matrix with :column 1 to 2000 with value 1 and column 2001:4000 with value zero
b)
Same situation as above but this time i want to check if the value is 1 then make the entry 1 and if it is zero then make the entry zero; at the end; my new matrix targets_2 contains values: column 1 to 2000 with value zero and column 2001:4000 with value 1
i know how to use the strcmp function to make such checking with strings, but problem is that my original matrix is double and i dont know if there is such function like
setosaCmp = strcmp('setosa',species);
which could work with double (numbers); any help would be appreciated
Your question isn't very clear. It sounds like the following would satisfy your description:
targets_1 = 1 - targets;
targets_2 = targets;
targets1 = double(targets == 0);
targets2 = targets;
I'm basing this answer purely on the fact that you've mentioned setosaCmp = strcmp('setosa', species);. From this I'm guessing that
You have Statistics Toolbox, as setosa is a species of iris from the Fisher Iris dataset widely used in Statistics Toolbox demos, and
You have a variable containing class labels, and you'd like to construct some class indicator variables (i.e. a new variable for each class label, each of which is 1 when the item is in that class, and 0 when it's not).
Is that right? If not, please ignore me.
If I'm right, then I think the command you're looking for is dummyvar from Statistics Toolbox. Try this:
>> classLabels = [1, 2, 1, 2, 3, 1, 3];
>> dummyvar(classLabels)
ans =
1 0 0
0 1 0
1 0 0
0 1 0
0 0 1
1 0 0
0 0 1