Function, in MATLAB dna replication - matlab

I'm trying to figure out the function command in Matlab and im having some difficulties.
I'm trying to write a Matlab function named dna_replicate. It will replicate a given strand and return its partner strand
For example if the user enters ATGCATGCAHGCAGTC, it should return TACGTACGT CGTCAG
A-->T
G-->C if the user enters other than these 4 letters, there should be blank in the partner strand. Thank you for your help

This implementation should be faster, involving only a simple table look-up. Note that the table t is constructed only once when the function is first called.
function out = dna_replicate(in)
persistent t
if isempty(t)
t = blanks(256);
t('ATGC') = 'TACG';
end
out = t(in);
end

How about:
function out = dna_replicate(in)
in = upper(in); % Ensures all same case
A = in=='A';
T = in=='T';
C = in=='C';
G = in=='G';
out = in;
out(A) = 'T';
out(T) = 'A';
out(C) = 'G';
out(G) = 'C';
out(~(A|T|C|G)) = ' ';
while #Jirka cigler answer works, it uses a for loop as well as dynamically growing vector 'out'. As matlab is optimized for vector operations, this answer should perform better.

You can create a simple vectorized solution using the function ISMEMBER:
function outString = dna_replicate(inString)
[~,index] = ismember(upper(inString),'ACGT'); %# Find the indices of inStrings
%# letters in string `ACGT`
outString = 'ACGT '; %# Initialize outString to `ACGT` and a blank
outString = outString(5-index); %# Use inverted and shifted index to expand
%# outString to the size of inString
end
And here's a test:
>> dna_replicate('ATGCATGCAHGCAGTC')
ans =
TACGTACGT CGTCAG

I think it can be implemented as follows:
function out=dna_replicate(in)
for i=1:numel(in)
switch in(i)
case 'A'
out(i)= 'T';
case 'G'
out(i)= 'C';
case 'T'
out(i)='A';
case 'C'
out(i)='G';
otherwise
out(i)=' ';
end
end
this function has argument of type char
in='ATGCATGCAHGCAGTC'
and you can run
out=dna_replicate(in)
to get the same result as you want :-)

Related

Is there an Octave equivalent of Matlab's `contains` function?

Is there an equivalent of MATLAB's contains function in Octave? Or, is there a simpler solution than writing my own function in Octave to replicate this functionality? I am in the process of switching to Octave from MATLAB and I use contains throughout my MATLAB scripts.
Let's stick to the example from the documentation on contains: In Octave, there are no (double-quoted) strings as introduced in MATLAB R2017a. So, we need to switch to plain, old (single-quoted) char arrays. In the see also section, we get a link to strfind. We'll use this function, which is also implemented in Octave to create an anonymous function mimicking the behaviour of contains. Also, we will need cellfun, which is available in Octave, too. Please see the following code snippet:
% Example adapted from https://www.mathworks.com/help/matlab/ref/contains.html
% Names; char arrays ("strings") in cell array
str = {'Mary Ann Jones', 'Paul Jay Burns', 'John Paul Smith'}
% Search pattern; char array ("string")
pattern = 'Paul';
% Anonymous function mimicking contains
contains = #(str, pattern) ~cellfun('isempty', strfind(str, pattern));
% contains = #(str, pattern) ~cellfun(#isempty, strfind(str, pattern));
TF = contains(str, pattern)
The output is as follows:
str =
{
[1,1] = Mary Ann Jones
[1,2] = Paul Jay Burns
[1,3] = John Paul Smith
}
TF =
0 1 1
That should resemble the output of MATLAB's contains.
So, in the end - yes, you need to replicate the functionality by yourself, since strfind is no exact replacement.
Hope that helps!
EDIT: Use 'isempty' instead of #isempty in the cellfun call to get a faster in-built implementation (see carandraug's comment below).
I'm not too familiar with MuPad functions, but it looks like this is reinventing the ismember function (which exists in both Matlab and Octave).
E.g.
ismember( {'jim', 'stan'}, {'greta', 'george', 'jim', 'jenny'} )
% ans = 1 0
i.e. 'jim' is a member of {'greta', 'george', 'jim', 'jenny'}, whereas 'stan' is not.
Furthermore, ismember also supports finding the index of the matched element:
[BoolVal, Idx] = ismember( {'jim', 'stan'}, {'greta', 'george', 'jim', 'jenny'} )
% BoolVal = 1 0
% Idx = 3 0
Personally I use my own implementation, which returns 1 if a string str contains entire substring sub:
function res = containsStr(str, sub)
res = 0;
strCharsCount = length(str);
subCharsCount = length(sub);
startCharSub = sub(1);
% loop over character of main straing
for ic = 1:strCharsCount
currentChar = str(ic);
% if a substring starts from current character
if (currentChar == startCharSub)
%fprintf('Match! %s = %s\n', currentChar, startCharSub);
matchedCharsCount = 1;
% loop over characters of substring
for ics = 2:subCharsCount
nextCharIndex = ic + (ics - 1);
% if there's enough chars in the main string
if (nextCharIndex <= strCharsCount)
nextChar = str(nextCharIndex);
nextCharSub = sub(ics);
if (nextChar == nextCharSub)
matchedCharsCount = matchedCharsCount + 1;
end
end
end
%fprintf('Matched chars = %d / %d\n', matchedCharsCount, subCharsCount);
% the substring is inside the main one
if (matchedCharsCount == subCharsCount)
res = 1;
end
end
end
end

Parallelizing MATLAB code

Hello I want to use parallelize my MATLAB code to run High computing server. It is code to make image database for Deep learning. To parallelize the code I found the I have to for parfor loop. But I used that with the first loop or with the second loop it shows me error parfor cannot be run due to the variable imdb and image_counter. Anyone please help me to change the code to work with parfor
for i = 1:length(cur_images)
X = sprintf('image Numb: %d ',i);
disp(X)
cur_image = load(cur_images{i,:});
cur_image=(cur_image.Image.crop);
%----------------------------------------------
cur_image = imresize(cur_image, image_size);
if(rgb < 1)
imdb.images.data(:,:,1,image_counter) = cur_image;
else
imdb.images.data(:,:,1,image_counter) = cur_image(:,:,1);
imdb.images.data(:,:,2,image_counter) = cur_image(:,:,2);
imdb.images.data(:,:,3,image_counter) = cur_image(:,:,3);
imdb.images.data(:,:,4,image_counter) = cur_image(:,:,4);
imdb.images.data(:,:,5,image_counter) = cur_image(:,:,5);
imdb.images.data(:,:,6,image_counter) = cur_image(:,:,6);
imdb.images.data(:,:,7,image_counter) = cur_image(:,:,7);
imdb.images.data(:,:,8,image_counter) = cur_image(:,:,8);
imdb.images.data(:,:,9,image_counter) = cur_image(:,:,9);
imdb.images.data(:,:,10,image_counter) = cur_image(:,:,10);
end
imdb.images.set( 1,image_counter) = set;
image_counter = image_counter + 1;
end
The main problem here is that you can't assign to fields of a structure inside parfor in the way that you're trying to do. Also, your outputs need to be indexed by the loop variable to qualify as "sliced" - i.e. don't use image_counter. Putting this together, you need something more like:
% Make a numeric array to store the output.
data_out = zeros([image_size, 10, length(cur_images)]);
parfor i = 1:length(cur_images)
cur_image = load(cur_images{i, :});
cur_image=(cur_image.Image.crop);
cur_image = imresize(cur_image, image_size);
% Now, assign into 'data_out'. A little care needed
% here.
if rgb < 1
data_tmp = zeros([image_size, 10]);
data_tmp(:, :, 1) = cur_image;
else
data_tmp = cur_image;
end
data_out(:, :, :, i) = data_tmp;
end
imdb.images.data = data_out;

Generate random matrix with eigenvalues

I am doing the following to generate random matrices with eigenvalues in a specific range:
function mat = randEig(dim, rReal)
D=diff(rReal).*rand(dim,1)+rReal(1);
P=rand(dim);
mat=P*diag(D)/P;
end
But I also want to be able to generate random real matrices with complex (conjugate) eigenvalues. How would one do that? The similarity transformation trick would return complex matrices.
EDIT: Okay I managed to do it by piggybacking on MATLAB's cdf2rdf function (which is basically the second function below).
function mat = randEig(dim, rangeEig, nComplex)
if 2*nComplex > dim
error('Cannot happen');
end
if nComplex
cMat=diff(rangeEig).*rand(dim-2*nComplex,1)+rangeEig(1);
for k=1:nComplex
rpart=(diff(rangeEig).*rand(1,1)+rangeEig(1))*ones(2,1);
ipart=(diff(rangeEig).*rand(1,1)+rangeEig(1))*i;
ipart=[ipart; -ipart];
cMat=[cMat; rpart+ipart];
end
else
cMat=diff(rangeEig).*rand(dim,1)+rangeEig(1);
end
D=cMat;
realDform = comp2rdf(diag(D));
P=rand(dim);
mat=P*realDform/P;
end
function dd = comp2rdf(d)
i = find(imag(diag(d))');
index = i(1:2:length(i));
if isempty(index)
dd=d;
else
if (max(index)==size(d,1)) | any(conj(d(index,index))~=d(index+1,index+1))
error(message('Complex conjugacy not satisfied'));
end
j = sqrt(-1);
t = eye(length(d));
twobytwo = [1 1;j -j];
for i=index
t(i:i+1,i:i+1) = twobytwo;
end
dd=t*d/t;
end
end
But the code is ugly, mainly the way rand is called multiple times is annoying). If someone wants to post an answer that calls rand once and manages to do the trick I will surely accept and upvote.
I made it either a single call or two calls with this:
function mat = randEig(dim, rangeEig, nComplex)
if 2*nComplex > dim
error('Cannot happen');
end
if nComplex
cMat=diff(rangeEig).*rand(2*nComplex,1)+rangeEig(1);
cPart=cMat(1:nComplex)*i;
cMat(1:nComplex)=[];
cPart=upsample(cPart,2);
cPart=cPart+circshift(-cPart,1);
cMat=upsample(cMat,2);
cMat=cMat+circshift(cMat,1);
cMat=cMat+cPart;
cMat=[diff(rangeEig).*rand(dim-2*nComplex,1)+rangeEig(1); cMat];
else
cMat=diff(rangeEig).*rand(dim,1)+rangeEig(1);
end
D=cMat;
realDform = comp2rdf(diag(D));
P=rand(dim);
mat=P*realDform/P;
end
function dd = comp2rdf(d)
i = find(imag(diag(d))');
index = i(1:2:length(i));
if isempty(index)
dd=d;
else
if (max(index)==size(d,1)) | any(conj(d(index,index))~=d(index+1,index+1))
error(message('Complex conjugacy not satisfied'));
end
j = sqrt(-1);
t = eye(length(d));
twobytwo = [1 1;j -j];
for i=index
t(i:i+1,i:i+1) = twobytwo;
end
dd=t*d/t;
end
end
If someone can make it a single call or shorter/more elegant code they are welcome to post an answer.

Matlab function return value

I have one program that has function and the problem, return value, it has too many output.
Like exempley: y = text the answer comes up
Error in text (line 2)
if nargin == 0
Output argument "array" (and maybe others) not assigned during call to "
C:\Users\name\Documents\MATLAB\text.m>text".
The program text.m reads a txt file that contains a couple of names and numbers like
exemple:
John doughlas 15986
Filip duch 357852
and so on. The program convert them to 15986 Doughlas John and so on.
function array = text(~)
if nargin == 0
dirr = '.';
end
answer = dir(dirr);
k=1;
while k <= length(answer)
if answer(k).isdir
answer(k)=[];
else
filename{k}=answer(k).name;
k=k+1;
end
end
chose=menu( 'choose file',filename);
namn = char(filename(chose));
fid = fopen(namn, 'r');
R = textscan(fid,'%s %s %s');
x=-1;
k=0;
while x <= 24
x = k + 1;
All = [R{3}{x},' ',R{1}{x},' ',R{2}{x}];
disp(All)
k = k + 1;
end
fclose(fid);
Is there anyway to fix the problem without starting over from scratch?
Grateful for all the answers!
You specify the function output argument in the definition, but you don't assign anything to it in the function body.
For example, in
function y = student(j)
your output is y. So you have to assign something to y.
Read more about functions in MATLAB.
Here is a working example.
The first part is to create a function called 'functionA' in a filename 'functionA.m'. Then put the following code inside:
function result = functionA(N,alpha)
result = 5;
return
end
The second part is to create another Matlab file(i.e. upto you to name it) or you can use the Matlab command window even. Then run the following code:
getresult = functionA(100,10);
getresult
After running you get the following answer:
ans =
5

Need help on clarification of input dialog of matlab

Suppose I have the following code:
%%input dialog box%%%
prompt = {'Enter gain:','Enter range:'};
dlg_title = 'Enter values';
num_lines= 1;
def = {'20','256'}; %default
answer = inputdlg(prompt,dlg_title,num_lines,def);
%%%to get the two entered values%%%%
A = getfield(answer,{1}); %first input field
A = str2double(A);
B = getfield(answer,{2}); %second input field
B = str2double(B);
What does it mean to use "dynamic field names with structures instead of getfield"?
How can I use a loop for the input values that are complex and smaller than zero, in the sense to request the user for another compatible input?
I've tried the following loop but it does not work. Why?
while isnan(A) || ~isreal(A) || A<0
prompt = {'Enter gain:'%'Enter range:'};
dlg_title = {'undefine!!'};
num_lines= 1;
def = {'',''}%{'20','256'}; %default
answer = inputdlg(prompt, dlg_title, num_lines, def);
A = getfield(answer,{1}); %first input field
A = str2double(A);
%A = str2double(input('Enter the value of module(mm) : ', 's'));
end
The calls to getfield aren't required and frankly don't make any sense. The variable answer is a cell array not a struct so you don't need to use getfield The second half of the pasted code could be replaced with:
A = str2double( answer{1} );
B = str2dobule( answer{2} );
With regards to looping until you get valid input. You can use a boolean flag, a while, loop and a function (lets call it areInputsValid()) that returns true if the inputs are valid
validInput = false;
while (~validInput)
% input dialog box
% code here
% get the two entered values
& code here
validInput = areInputsValid(A, B);
end