I'm beginning to learn Matlab and having trouble with a routine exercise which reads as follows
set ff to a null set, set x to equal 10,000 random numbers between 0 and 1 (make sure the numbers are rounded to the nearest integer)
{Think of 1’s as Heads and 0’s at Tails}
start a for loop where n goes to 9,999 coin flips (starting with the 4th flip) check if the nth flip == Heads and if the previous three flips were also Heads if so, save the result of the very next flip in your expanding vector ff end the if statement
end the for loop develop a way to check if half (or more than half) of those “fifth-flips” are tails.
so far I have managed to get the beginning of the code seen below
clear
ff=[]
x=round(rand(1,10000)
for n=4:9999
if n==1
not sure where to go from here, hoping for code with a thorough description of the reasoning behind command choices
Related
Just a quick question that is driving me mad due to its slowness.
I have a cell (300x2), the first column corresponds to the parallel intensity values, and the second one to the perpendicular intensity values. Each cell contains a 128x128 matrix.
So, what I want to do is summing all the intensities of all the matrixes, per pixel. I have the following code but it takes ages to be executed:
%Intensity_cell_par_per is the 300x2 cell
%a=128;
%b=128;
%numfiles=300;
I_matrix_par=zeros(128,128);
I_matrix_per=zeros(128,128);
for i=1:a
for j=1:b
I_par=0;
I_per=0;
for k=1:numfiles
I_par=I_par+sum(Image_cell_par_per{k,1}(i,j,1:end));
I_per=I_per+sum(Image_cell_par_per{k,2}(i,j,1:end));
end
I_matrix_par(i,j)=I_par;
I_matrix_per(i,j)=I_per;
end
end
Any idea of how I can do it in a fast way?
Thanks!
I am assuming here that the code you posted gives the result you want. This is an easy way of speeding it up:
You can call sum as sum( _ , 3) to take the whole matrix and sum its 3rd dimension, so you avoid 2 loops. The following code, run with a=100,b=100 and numfiles=20 runs in 0.0031 seconds as opposed to 5.17 seconds with your code, which is about 1660x faster. I hope this is fast enough.
I_matrix_par=zeros(a,b);
I_matrix_per=zeros(a,b);
for k=1:numfiles
I_matrix_par=I_matrix_par+sum(Image_cell_par_per{k,1},3);
I_matrix_per=I_matrix_per+sum(Image_cell_par_per{k,2},3);
end
The code is meant to draw a line with each click of the mouse made within the figure. Here is my code;
b=1
while b>0;
axis([-10, 10, -10, 10])
b=b+1
[x(b),y(b)]=ginput(1)
plot(x,y,x,y)
end
However I cant get my head around how I can add the vectors seeing as some are + and some are -, I need to turn the negatives into positives. I need to add code that will give me an overall combined length after all the mouse clicks. Maybe I am just thinking about it completely wrong.
I have tried;
length=(sqrt(x.^2)+(y.^2))
I was hoping this would give me the correct vector length accept unless I click an exact straight line.
So assuming that x and y are vectors of sequential points, if you want to get the total distance then you need to take the sum of the distance between each point i.e.
Σi(sqrt((xi-xi-1)2+(yi-yi-1)2))
in Matlab we can calculate all the x (and y) differences in one step using the diff function so in the end we get
length = sum(sqrt(diff(x).^2 + diff(y).^2))
Your problem is twofold: there's a typo, I think instead of
length=(sqrt(x.^2)+(y.^2))
you mean
length=sqrt((x.^2)+(y.^2))
The second problem is, that this does not actually calculate the length of your path, instead, you probably want something like
clear all
b=1;
radius = 3;
while b>0;
axis([-10, 10, -10, 10])
b=b+1;
[x(b),y(b)]=ginput(1);
plot(x,y,x,y);
length(b)=sqrt((x(b)-x(b-1))^2+(y(b)-y(b-1))^2);
if sqrt(x(b)^2 + y(b)^2) < radius; break; end
end
sum(length)
which calculates the length for each new piece you add and sums them all up.
As soon as you click within "radius" distance of 0 the while loop breaks.
Also, generally it's good practice to preallocate variables, no big deal here, cause your arrays are small, just saying.
Note: Dan's solution gives you a vectorized way of calculating the total length in one step, so in case you don't need the individual path lengths this is the more concise way to go.
I am trying to code a program to shuffle the dna sequence as much as
possible to destroy the order in the sequence. i have written matlab
code but its too slow. Also i was looking into hamming distance
measure or levenstein measure, also how can i incorporate those measure to
ensure proper shuffling. the rules I followed in shuffling
rule 1: the ith residue should not be near i-1,i-2,i-3,i+1,i+2,i+3
rule 2: in next arrangement i's new position and old position must be at 20 place difference. i.e. if A had 1st position in the string in
shuffled string it must be more than equal to 21st position.
function seq=shuffling(str)
len=length(str);
t1=0.4;
seqlen=1:len;
if(len>150)
t1=0.90;
elseif(len>=100)
t1=0.7;
end
while 1
shufseq=randperm(len);
temp1=diff([seqlen;shufseq]);%differences between order indices of original and shuffled arrangement
if(isempty(find(temp1==0)) && isempty(find(diff(shufseq)==1|diff(shufseq)==2 |diff(shufseq)==3 |diff(shufseq)==4 |diff(shufseq)==-1|diff(shufseq)==-2 |diff(shufseq)==-3 |diff(shufseq)==-4)))% rule 1
if((length(find(temp1>20|temp1<-20))/len)>t1)%rule 2 if ratio of (counts of arrangements/length of the string) should be more than one after certain length threshhold(=t1)
break
else
continue
end
else
continue
end
end
seq=str(shufseq);
i came up with one alternative. i.e. knowing the composition or counts of unique alphabets in the string. then choosing randomly among these alphabets and reducing their count by 1 in each iteration. this iteration is over the length of the sequence.
function seq=newshuffle(str)
%#codegen
len=length(str);
seq=[];
ndict= ['A';'C';'G';'T'];
ncomp=struct2array(count(str))';
for l=1:len
while 1
x=randi(4,1,1);
if ncomp(x)~=0
break;
end
end
seq=[seq,ndict(x)];
ncomp(x)=ncomp(x)-1;
end
end
It's some time I was thinking about solving this problem. I have a registration of angular data (Angle(~20000,1)) variating between 0 and 355 (a potentiometer attached to a rotary testing machine), and I wanted to convert it in an incremental form, since I want the final total angular displacement. The main issue is that between 355 and the next 0 there are no jumps but a fast decrement (with strongly negative slope in time vs angle space). I've tried 2 ways up to now:
Calculate the Angslope=diff(Angle), extract with find the indexes j1=find(Angslope>0.2 & Angslope<0.2) to avoid the negative slopes due to the inversion of angular signal, then try to apply those indexes to the original Angle(n,1), as Angle2=Angle(j1). The trouble is the n-1 length of Angslope and the fact that somehow there is not a simple shift of my indexes of one position.
For cycles and logical, wanting to exclude data if the previous one is < the current value,etc
Angle2=zeros(size(Angle,1),1);
for i=2:size(Angle,1)
if Angle(i,1)<Angle(i-1,1)
Angle2(i,1)=NaN;
else Angle2(i,1)=Angle(i,1);
end
end
Which works good, but I don't know how to "match up" the single increment steps I obtain!
Any help or simple comment would be of great help!!
You are probably looking for the unwrap function. For this you have to convert your angles into radians, but that's not a big deal.
You can get the increments in one line:
Inc = diff(unwrap(Angle*pi/180))*180/pi;
and your total angular displacement:
Tot = sum(Inc);
Best,
I am recording voltage changes over a small circuit- this records mouse feeding. When the mouse is eating, the circuit voltage changes, I convert that into ones and zeroes, all is well.
BUT- I want to calculate the number and duration of 'bursts' of feeding- that is, instances of circuit closing that occur within 250 ms (75 samples) of one another. If the gap between closings is larger than 250ms I want to count it as a new 'burst'
I guess I am looking for help in asking matlab to compare the sample number of each 1 in the digital file with the sample number of the next 1 down- if the difference is more than 75, call the first 1 the end of one bout and the second one the start of another bout, classifying the difference as a gap, but if it is NOT, keep the sample number of the first 1 and compare it against the next and next and next until there is a 75-sample difference
I can compare each 1 to the next 1 down:
n=1; m=2;
for i = 1:length(bouts4)-1
if bouts4(i+1) - bouts4(i) >= 75 %250 msec gap at a sample rate of 300
boutend4(n) = bouts4(i);
boutstart4(m)= bouts4(i+1);
m = m+1;
n = n+1;
end
I don't really want to iterate through i for both variables though...
any ideas??
-DB
You can try the following code
time_diff = diff(bouts4);
new_feeding = time_diff > 75;
boutend4 = bouts4(new_feeding);
boutstart4 = [0; bouts4(find(new_feeding) + 1)];
That's actually not too bad. We can actually make this completely vectorized. First, let's start with two signals:
A version of your voltages untouched
A version of your voltages that is shifted in time by 1 step (i.e. it starts at time index = 2).
Now the basic algorithm is really:
Go through each element and see if the difference is above a threshold (in your case 75).
Enumerate the locations of each one in separate arrays
Now onto the code!
%// Make those signals
bout4a = bouts4(1:end-1);
bout4b = bouts4(2:end);
%// Ensure column vectors - you'll see why soon
bout4a = bout4a(:);
bout4b = bout4b(:);
% // Step #1
loc = find(bouts4b - bouts4a >= 75);
% // Step #2
boutend4 = [bouts4(loc); 0];
boutstart4 = [0; bouts4(loc + 1)];
Aside:
Thanks to tail.b.lo, you can also use diff. It basically performs that difference operation with the copying of those vectors like I did before. diff basically works the same way. However, I decided not to use it so you can see how exactly your code that you wrote translates over in a vectorized way. Only way to learn, right?
Back to it!
Let's step through this slowly. The first two lines of code make those signals I was talking about. An original one (up to length(bouts) - 1) and another one that is the same length but shifted over by one time index. Next, we use find to find those time slots where the time index was >= 75. After, we use these locations to access the bouts array. The ending array accesses the original array while the starting array accesses the same locations but moved over by one time index.
The reason why we need to make these two signals column vector is the way I am appending information to the starting vector. I am not sure whether your data comes in rows or columns, so to make this completely independent of orientation, I'm going to make sure that your data is in columns. This is because if I try to append a 0, if I do it to a row vector I have to use a space to denote that I'm going to the next column. If I do it for a column vector, I have to use a semi-colon to go to the next row. To completely avoid checking to see whether it's a row or column vector, I'm going to make sure that it's a column vector no matter what.
By looking at your code m=2. This means that when you start writing into this array, the first location is 0. As such, I've artificially placed a 0 at the beginning of this array and followed that up with the rest of the values.
Hope this helps!