I am trying to make pairs of letters from two different input strings.
This is my code so far:
clear all
signal = input('Please enter text to be scrambled:\n ', 's');
signal = signal(randperm(numel(signal)))
noise = input ('Please enter text of the same length:\n ','s');
noise = noise(randperm(numel(noise)))
This is some kind of a game I am trying to develop, and I was investigating the math involved.
Imagine the game of Reversi, where one has to flip and move coins around in order to "match colors".
I was thinking it would be great if we tried to "match letters" instead, for the purpose of recreating the original message, in this case, the Signal.
Let's say, you have 100 coins, and you place them randomly on a table (either head or tail, it doesn't matter).
Then, you write a message on the coins, one letter for each coin. This is the Signal.
Then, you flip all the coins to the other side, and move them around a bit.
Then, you insert "the noise" following the same procedure.
We now have 100 coins, but 200 letters in the game, one letter for each side of the coins. If we flip and move coins around in order to insert the "noise", we don't know what's on the other side of each coin.
The purpose of the game is to flip and move coins around until the original message (the Signal) is recreated. This is some kind of an encrypting technique that no computer algorithm should be able to crack.
So, please help me understand how to make pairs of letters from the two input strings.
There are lots of ways you could do this, but here's one. For two character vectors as input, the output is a cell array of two-letter character vectors in which each pair contains one letter from each input, no letter is used twice, and the pairs are reversed at random.
% 'signal' and 'noise' are two character vectors of equal length
numChars = strlength(signal);
% randomly permute signal and noise
left = signal(randperm(numChars));
right = noise(randperm(numChars));
% make a cell array of 2-letter pairs
pairs = arrayfun(#strcat, left, right, 'UniformOutput', false);
% select half of the pairs at random and reverse them
sel = logical(randi([0, 1], 1, numChars));
pairs(sel) = cellfun(#fliplr, pairs(sel), 'UniformOutput', false);
Now pairs{1} will contain the first pair, pairs{2} the second, and so on.
nekomatic's solution is one option, but will fail when a space is included in the string, and makes it a little cumbersome to recover the current message on the coins. I would simply stick the signal and noise into one larger character matrix, e.g.
coins = [noise; signal]';
where the first dimension represents the coins, and the second dimension their sides. As such, flipping the fifth coin could look like coins(5,:) = fliplr(coins(5,:)); and coins(:,1)' will show you the currently visible letters.
Related
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
Now first off, I am not even sure this is called a matrix, and I am new to MATLAB. But let's say I have a "matrix" that looks like this:
for n=1:10
...
someImage = mat(:,:,n) %The "matrix"
...
end
where n could be the frames in a video, for example, and the first 2 ':' are the row and column data for the 2D image (the frame).
If I only wanted the first ':' of data (the row? column? element?), how would I access only that?
Intuitively, I think something like:
row1 = mat(:,0,0)
row2 = mat(0,:,0)
row3 = mat(0,0,:)
but that doesn't seem to be working.
P.S. I know that these aren't really rows, the terminology for all this would also be greatly appreciated
Also, it may not have anything to do with this, but I am using a MATLAB GUI as well, and the "matrix" is stored like this:
handles.mat(:,:,n)
I don't think it has anything to do with my actual question, but it might so I will put it here
-Thanks!
One point I would like to make before starting: MATLAB starts indexing at 1, and not 0. This is a common mistake that most people who have a C/Java/Python programming background make going into MATLAB.
Also, by doing:
row1 = mat(:,1,1);
This accesses all of the rows for the first column and the first frame of your video. Be aware that this will produce a M x 1 vector, where M denotes the number of rows for a frame in your video.
Also:
row2 = mat(1,:,1);
This accesses all of the columns in the first row of the first frame. Be aware that this will produce a 1 x N vector, where N denotes the number of columns for a frame in your video.
Also:
row3 = mat(1,1,:);
This accesses all of the pixels in the entire video sequence at row 1 and column 1. You can think of this as a temporal slice at the top left corner of your video sequence. Be aware that this will produce a 1 x 1 x T vector, where T is the number of frames in your video. If you access just a single pixel location in your video, the first two dimensions are superfluous, and so you can use the squeeze command to shrink all of the singleton dimensions so that it simplifies to a T x 1 vector. In other words, do this:
row3 = squeeze(mat(1,1,:));
FWIW, you do have the right terminology. Rows and columns are used in image / video processing all the time. As for the "matrix", you can call this a temporal sequence or a frame sequence in terms of video processing. It certainly is a 3D matrix, but people in this domain denote it as either one of the two as it is really a sequence of images / frames stacked on top of each other.
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!
I want to sum up several vectors of different size in an array. Each time one of the vectors drops out of my program, I want to append it to my array. Like this:
array = [array, vector];
In the end I want to let this array be the output of a function. But it gives me wrong results. Is this possible with MATLAB?
Thanks and kind regards,
Damian
Okay, given that we're dealing with column vectors of different size, you can't put them all in a numerical array, since a numerical array has to be rectangular. If you really wanted to put them in the numerical array, then the column length of the array will need to be the length of the longest vector, and you'll have to pad out the shorter vectors with NaNs.
Given this, a better solution would be, as chaohuang hinted at in the comments, to use a cell array, and store one vector in each cell. The problem is that you don't know beforehand how many vectors there will be. The usual approach that I'm aware of for this problem is as follows (but if someone has a better idea, I'm keen to learn!):
UpperBound = SomeLargeNumber;
Array = cell(1, UpperBound);
Counter = 0;
while SomeCondition
Counter = Counter + 1;
if Counter > UpperBound
error('You did not choose a large enough upper bound!');
end
%#Create your vector here
Array{1, Counter} = YourVectorHere;
end
Array = Array(1, 1:Counter);
In other words, choose some upper bound beforehand that you are sure you won't go above in the loop, and then cut your cell array down to size once the loop is finished. Also, I've put in an error trap in case you're choice of upper bound turns out to be too small!
Oh, by the way, I just noted in your question the words "sum up several vectors". Was this a figure of speech or did you actually want to perform a sum operation somewhere?
I would like to use a for loop within a for loop (I think) to produce a number of vectors which I can use separately to use polyfit with.
I have a 768x768 matrix and I have split this into 768 separate cell vectors. However I want to split each 1x768 matrix into sections of 16 points - i.e. 48 new vectors which are 16 values in length. I want then to do some curve fitting with this information.
I want to name each of the 48 vectors something different however I want to do this for each of the 768 columns. I can easily do this for either separately but I was hoping that there was a way to combine them. I tried to do this as a for statement within a for statement however it doesn't work, I wondered if anyone could give me some hints on how to produce what I want. I have attached the code.
Qne is my 768*768 matrix with all the points.
N1=768;
x=cell(N,1);
for ii=1:N1;
x{ii}=Qnew(1:N1,ii);
end
for iii = 1:768;
x2{iii}=x{iii};
for iv = 1:39
N2=20;
x3{iii}=x2{iii}(1,(1+N2*iv:N2+N2*iv));
%Gx{iv}=(x3{iv});
end
end
Use a normal 2D matrix for your inner split. Why? It's easy to reshape, and many of the fitting operations you'll likely use will operate on columns of a matrix already.
for ii=1:N1
x{ii} = reshape(Qnew(:, ii), 16, 48);
end
Now x{ii} is a 2D matrix, size 16x48. If you want to address the jj'th split window separately, you can say x{ii}(:, jj). But often you won't have to. If, for example, you want the mean of each window, you can just say mean(x{ii}), which will take the mean of each column, and give you a 48-element row vector back out.
Extra reference for the unasked question: If you ever want overlapping windows of a vector instead of abutting, see buffer in the signal processing toolbox.
Editing my answer:
Going one step further, a 3D matrix is probably the best representation for equal-sized vectors. Remembering that reshape() reads out columnwise, and fills the new matrix columnwise, this can be done with a single reshape:
x = reshape(Qnew, 16, 48, N1);
x is now a 16x48x768 3D array, and the jj'th window of the ii'th vector is now x(:, jj, ii).