I am coding a simple value function iteration in Julia. I posted the code below.
# ................................
# Solving the model
function Solver(P,uf,hf)
#unpack r, σrisk, ρ, η, β, θ, nx, m, μ, fhat, ub, lb, tol, maxite, ne = P;
# ..................................................
# Tauchen discretization
ly, Π = mytauch(μ, ρ, η, nx, m); # it is a tauchen discretization
# ..................................................
# states
y = exp.(ly);
b = [LinRange(lb,ub, ne)...];
yb = b .+ y';
p0 = findfirst(x-> x ==0, b);
uhy = uf.(hf(y, fhat));
# ..................................................
# Initial guess for value functions
vr0 = 1 / (1 - β) * uf.((r / (1 + r)) * b .+ y');
vd0 = (1 / (1 - β) * uhy)';
myup(vr,vd) = updateVF(vr, vd, b, yb, uhy, Π, p0, uf, P);
# ..................................................
# Convergence algorithm
dif = 1
ite = 1
vr1, vd1, bopt = (nothing,nothing, nothing);
while dif>tol && ite < maxite
vr1, bopt, vd1 = myup(vr0,vd0)
dif = max(maximum(abs.(vr1-vr0)), maximum(abs.(vd1-vd0)));
ite+=1;
vr0, vd0 = (vr1, vd1);
end
# ..................................................
# Policies functions
vf1, D, δ, q = postVR(vr1,vd1,Π,r)
#bb = repeat(b,1,nx);
vd1 = repeat(vd1,ne,1);
bprime = b[bopt];
PolFun = (vf=vf1 , vr=vr1, vd=vd1, bprime = bprime, q=q,D=D, δ=δ);
out2 = (b= b, y= y,ydef=hf(y, fhat),Π=Π, uhy = uhy, p0 = p0);
return PolFun, out2;
end
function updateVF(vr0, vd0,b,yb,uhy,Π, p0, uf, P)
#unpack r , β, θ, nx,ne = P;
# ..................................................
# Preliminaries
vf0, D0, δ0, q0 = postVR(vr0,vd0,Π,r)
evf0 = vf0*Π';
evd0 = vd0*Π';
qb = q0 .* b;
βevf0 = β*evf0;
# ..................................................
# Value and debt policy function update
# Value of Default
vd1 = uhy' + β*(θ*evf0[p0,:]'+(1-θ)*evd0);
# Value of Repayment
# Method 2: by column
vr1 = Array{Float32,2}(undef, ne, nx);
bopt = Array{CartesianIndex{2},2}(undef, ne, nx);
upvr1!(vr1,bopt,yb,qb,βevf0,nx)
return vr1, map(ii -> ii[1],bopt), vd1
end
function postVR(vr,vd,Π,r)
vf = max.(vr,vd);
D = 1*(vd .> vr);
δ = D*Π';
q = (1/(1+r)) * (1 .- δ);
return vf, D, δ, q;
end
function upvr1!(vr1,bopt,yb,qb,βevf0,nx)
#fastmath #inbounds Threads.#threads for i in 1:nx
vr1[:,i], bopt[:,i] = #views findmax(uf.(max.(0,yb[:,i] .- qb[:,i]')) .+ βevf0[:,i], dims=1);
end
end
The master code is:
P = ( r = 0.017, σrisk = 2.0, ρ = 0.945, η = 0.025, β = 0.953,
θ = 0.282,nx = 21, m = 3, μ = 0.0,fhat = 0.969,
ub = 0, lb = -0.4, tol = 1e-6, maxite = 2000, ne = 251);
uf(x) = -1/x;
hf(y::Array, fhat::Float64) = min.(y, fhat * mean(y));
#time polfun, o2 = Solver(P,uf,hf);
The running tipe after first compilation is ~1 second. How can I speed-up this code? I am asking it because in previous versions of Matlab, in my experience, Julia was 10x faster but with the last version (Matlab 2020, that I tried last week) its performance was close to Julia but as I increase the number of grid-points (ne > 1000) Matlab reported faster. So I suppose that I am not taking advantage of all functionalities of Julia.
Note: The loop for upvr1! overperforms that a broadcasting version
yb = reshape(yb,(ne,nx,1));
βevf01 = PermutedDimsArray(reshape(βevf0,(ne,nx,1)),[3,2,1]);
qb1 = PermutedDimsArray(reshape(qb,(ne,nx,1)),[3,2,1]);
vr1, bopt = #views findmax(uf.(yb .- qb1) .+ βevf01, dims=3)
return vr1[:,:,1], map(ii -> ii[3], bopt)[:,:,1], vd1
Related
*[I found that the error occurred at line 57, z2 = w12.a1 + b12; with incompatible array size,
May I know how to fix it? Basically the data is from the simulation on MATLAB Simulink, so the size of the array changes as we increase the inputs from the original code which only have 1 input type][1]
%% load training data (use training_data.mat attached file)
% initialize number of nodes, weights, biases, errors and gradients.
%epochs and mini-batch size
clc
data = [out.dutycycle out.voltage out.current]
sample=1000;
labels = data(1:sample,1);
y = labels'; %output vector
images = data(1:sample,2:3);
images(:,1) = images(:,1)/400;
images(:,2) = images(:,2)/100;
images = images'; %Input vectors
hn1 = 80; %Number of neurons in the first hidden layer
hn2 = 60; %Number of neurons in the second hidden layer
%Initializing weights and biases
w12 = randn(hn1,1000).*sqrt(2/1000);
w23 = randn(hn2,hn1)*sqrt(2/hn1);
w34 = randn(1,hn2)*sqrt(2/hn2);
b12 = randn(hn1,1);
b23 = randn(hn2,1);
b34 = randn(1,1);
%learning rate
eta = 0.0058;
%Initializing errors and gradients
error4 = zeros(1,1);
error3 = zeros(hn2,1);
error2 = zeros(hn1,1);
errortot4 = zeros(1,1);
errortot3 = zeros(hn2,1);
errortot2 = zeros(hn1,1);
grad4 = zeros(1,1);
grad3 = zeros(hn2,1);
grad2 = zeros(hn1,1);
epochs = 50;
m = 10; %Minibatch size
%% Training phase
for k = 1:epochs %Outer epoch loop
batches = 1;
for j = 1:sample/m
error4 = zeros(1,1);
error3 = zeros(hn2,1);
error2 = zeros(hn1,1);
errortot4 = zeros(1,1);
errortot3 = zeros(hn2,1);
errortot2 = zeros(hn1,1);
grad4 = zeros(1,1);
grad3 = zeros(hn2,1);
grad2 = zeros(hn1,1);
for i = batches:batches+m-1 %Loop over each minibatch
%Feed forward
a1 = images(:,i);
z2 = w12.*a1 + b12;
a2 = elu(z2);
z3 = w23*a2 + b23;
a3 = elu(z3);
z4 = w34*a3 + b34;
a4 = elu(z4); %Output vector
%backpropagation
error4 = (a4-y(:,i)).*elup(z4);
error3 = (w34'*error4).*elup(z3);
error2 = (w23'*error3).*elup(z2);
errortot4 = errortot4 + error4;
errortot3 = errortot3 + error3;
errortot2 = errortot2 + error2;
grad4 = grad4 + error4*a3';
grad3 = grad3 + error3*a2';
grad2 = grad2 + error2*a1';
end
%Gradient descent
w34 = w34 - eta/m*grad4;
w23 = w23 - eta/m*grad3;
w12 = w12 - eta/m*grad2;
b34 = b34 - eta/m*errortot4;
b23 = b23 - eta/m*errortot3;
b12 = b12 - eta/m*errortot2;
batches = batches + m;
end
fprintf('Epochs:');
disp(k) %Track number of epochs
[images,y] = shuffle(images,y); %Shuffles order of the images for next epoch
end
disp('Training done!')
%note : create folder for this experiment and save the parameters.
% don't forget to keep the folder in matlab path!
save('wfour.mat','w34');
save('wthree.mat','w23');
save('wtwo.mat','w12');
save('bfour.mat','b34');
save('bthree.mat','b23');
save('btwo.mat','b12');
%% Testing phase
% load testing data with labels ... (use testing_data.mat attached file)
testsample = 100;
labels = test(1:testsample,1);
y = labels';
images = test(1:testsample,2:3);
images(:,1) = images(:,1)/400;
images(:,2) = images(:,2)/100;%copy
images = images';
we34 = matfile('wfour.mat');
w4 = we34.w34;
we23 = matfile('wthree.mat');
w3 = we23.w23;
we12 = matfile('wtwo.mat');
w2 = we12.w12;
bi34 = matfile('bfour.mat');
b4 = bi34.b34;
bi23 = matfile('bthree.mat');
b3 = bi23.b23;
bi12 = matfile('btwo.mat');
b2 = bi12.b12;
success = 0;
n = testsample;
for i = 1:n
out2 = elu(w2*images(:,i)+b2);
out3 = elu(w3*out2+b3);
out = elu(w4*out3+b4);
big = 0;
num = 0;
for k = 1:10
if out(k) > big
num = k-1;
big = out(k);
end
end
if labels(i) == num
success = success + 1;
end
end
fprintf('Accuracy: ');
fprintf('%f',success/n*100);
disp(' %');
%% ELU activation function
function fr = elu(x)
f = zeros(length(x),1);
for i = 1:length(x)
if x(i)>=0
f(i) = x(i);
else
f(i) = 0.2*(exp(x(i))-1);
end
end
fr = f;
end
%% derivative of the ELU activation function
function fr = elup(x)
f = zeros(length(x),1);
for i = 1:length(x)
if x(i)>=0
f(i) = 1;
else
f(i) = 0.2*exp(x(i));
end
end
fr = f;
end
%% SHuffle function
function [B,v] = shuffle(A,y)
cols = size(A,2);
P = randperm(cols);
B = A(:,P);
v = y(:,P);
end
Your help is much appreciated, thank you
MATLAB Error :
Arrays have incompatible sizes for this operation.
Error in ANN_PV_Array (line 57)
z2 = w12.*a1 + b12;
I am trying to solve a system with differential equations using odeint. I have 4 txt files (that look like the picture below). I read them and I save them in numpy arrays (length:8000) (maby not with the most effective way, but anyway...). I want to pass these 4 arrays as arguments in my odeint and solve the system. For example, at every time step the odeint takes (one from the 8000) to solve the system, I want it to use a different value from these arrays. Is there any way to do it automatically without getting lost in for loops? I tried to do it like this (see code below) but I get the error:
if g2>0: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
g2 supposed to be 1x1 size at every loop of odeint. So it has to be something with the way I use the 4 arrays (xdot,ydot,xdotdot,ydotdot).
I am new to python and I use python 2.7.12 on Ubuntu 16.04 LTS.
Thank you in advance.
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
added_mass_x = 0.03 # kg
added_mass_y = 0.04
mb = 0.3 # kg
m1 = mb-added_mass_x
m2 = mb-added_mass_y
l1 = 0.07 # m
l2 = 0.05 # m
J = 0.00050797 # kgm^2
Sa = 0.0110 # m^2
Cd = 2.44
Cl = 3.41
Kd = 0.000655 # kgm^2
r = 1000 # kg/m^3
c1 = 0.5*r*Sa*Cd
c2 = 0.5*r*Sa*Cl
c3 = 0.5*mb*(l1**2)
c4 = Kd/J
c5 = (1/(2*J))*(l1**2)*mb*l2
c6 = (1/(3*J))*(l1**3)*mb
theta_0 = 10*(np.pi/180) # rad
theta_A = 20*(np.pi/180) # rad
f = 2 # Hz
###################################################################
t = np.linspace(0,100,8000) # s
###################################################################
# Save data from txt files into numpy arrays
xdot_list = []
ydot_list = []
xdotdot_list = []
ydotdot_list = []
with open('xdot.txt', 'r') as filehandle:
filecontents = filehandle.readlines()
for line in filecontents:
current_place = line[:-1]
xdot_list.append(current_place)
xdot = np.array(xdot_list, dtype=np.float32)
with open('ydot.txt', 'r') as filehandle:
filecontents = filehandle.readlines()
for line in filecontents:
current_place = line[:-1]
ydot_list.append(current_place)
ydot = np.array(ydot_list, dtype=np.float32)
with open('xdotdot.txt', 'r') as filehandle:
filecontents = filehandle.readlines()
for line in filecontents:
current_place = line[:-1]
xdotdot_list.append(current_place)
xdotdot = np.array(xdotdot_list, dtype=np.float32)
with open('ydotdot.txt', 'r') as filehandle:
filecontents = filehandle.readlines()
for line in filecontents:
current_place = line[:-1]
ydotdot_list.append(current_place)
ydotdot = np.array(ydotdot_list, dtype=np.float32)
def inverse(k,t,xdot,ydot,xdotdot,ydotdot):
vcx_i = k[0]
vcy_i = k[1]
psi_i = k[2]
wz_i = k[3]
theta_i = k[4]
theta_deg_i = k[5]
# Subsystem 4
vcx_i = xdot*np.cos(psi_i)-ydot*np.sin(psi_i)
vcy_i = ydot*np.cos(psi_i)+xdot*np.sin(psi_i)
psidot_i = wz_i
vcxdot_i = xdotdot*np.cos(psi_i)-xdot*np.sin(psi_i)*psidot_i-ydotdot*np.sin(psi_i)-ydot*np.cos(psi_i)*psidot_i
vcydot_i = ydotdot*np.cos(psi_i)-ydot*np.sin(psi_i)*psidot_i+xdotdot*np.sin(psi_i)+xdot*np.cos(psi_i)*psidot_i
g1 = -(m1/c3)*vcxdot_i+(m2/c3)*vcy_i*wz_i-(c1/c3)*vcx_i*np.sqrt((vcx_i**2)+(vcy_i**2))+(c2/c3)*vcy_i*np.sqrt((vcx_i**2)+(vcy_i**2))*np.arctan2(vcy_i,vcx_i)
g2 = (m2/c3)*vcydot_i+(m1/c3)*vcx_i*wz_i+(c1/c3)*vcy_i*np.sqrt((vcx_i**2)+(vcy_i**2))+(c2/c3)*vcx_i*np.sqrt((vcx_i**2)+(vcy_i**2))*np.arctan2(vcy_i,vcx_i)
A = 12*np.sin(2*np.pi*f*t+np.pi) # eksiswsi tail_frequency apo simulink
if A>=0.1:
wzdot_i = ((m1-m2)/J)*vcx_i*vcy_i-c4*wz_i**2*np.sign(wz_i)-c5*g2-c6*np.sqrt((g1**2)+(g2**2))
elif A<-0.1:
wzdot_i = ((m1-m2)/J)*vcx_i*vcy_i-c4*wz_i**2*np.sign(wz_i)-c5*g2+c6*np.sqrt((g1**2)+(g2**2))
else:
wzdot_i = ((m1-m2)/J)*vcx_i*vcy_i-c4*wz_i**2*np.sign(wz_i)-c5*g2
# Subsystem 5
if g2>0:
theta_i = np.arctan2(g1,g2)
elif g2<0 and g1>=0:
theta_i = np.arctan2(g1,g2)-np.pi
elif g2<0 and g1<0:
theta_i = np.arctan2(g1,g2)+np.pi
elif g2==0 and g1>0:
theta_i = -np.pi/2
elif g2==0 and g1<0:
theta_i = np.pi/2
elif g1==0 and g2==0:
theta_i = 0
theta_deg_i = (theta_i*180)/np.pi
return [vcxdot_i, vcydot_i, psidot_i, wzdot_i, theta_i, theta_deg_i]
# initial conditions
vcx_i_0 = 0.1257
vcy_i_0 = 0
psi_i_0 = 0
wz_i_0 = 0
theta_i_0 = 0
theta_deg_i_0 = 0
#theta_i_0 = 0.1745
#theta_deg_i_0 = 9.866
k0 = [vcx_i_0, vcy_i_0, psi_i_0, wz_i_0, theta_i_0, theta_deg_i_0]
# epilysi systimatos diaforikwn
k = odeint(inverse, k0, t, args=(xdot,ydot,xdotdot,ydotdot), tfirst=False)
# apothikeysi apotelesmatwn
vcx_i = k[:,0]
vcy_i = k[:,1]
psi_i = k[:,2]
wz_i = k[:,3]
theta_i = k[:,4]
theta_deg_i = k[:,5]
# Epanalipsi tu Subsystem 5 gia na mporun na plotaristun ta theta_i, theta_deg_i
theta_i = [inverse(k_i, t_i)[4] for t_i, k_i in zip(t, k)]
theta_deg_i = [inverse(k_i, t_i)[5] for t_i, k_i in zip(t, k)]
# Ypologismos mesis gwnias theta kai platus talantwsis
mesi_gwnia = sum(theta_i)/len(theta_i) # rad
platos = (max(theta_i)-min(theta_i))/2
UPDATE:
The most relevant solution I found so far is this:
Solving a system of odes (with changing constant!) using scipy.integrate.odeint?
But since I have only values of my variables in arrays and not the equation of the variables that depend on time (e.g. xdot=f(t)), I tried to aply an interpolation between the values in my arrays, as shown here: ODEINT with multiple parameters (time-dependent)
I managed to make the code running without errors, but the total time increased dramatically and the results of the system solved are completely wrong. I tried any possible type of interpolation that I found here: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html but still wring outcome. That means that my interpolation isn't the best possible, or my points in the arrays (8000 values) are too much to interpolate between them and solve the system correctly.
I have two cell arrays of size [1X5]
K= {} {O1,O2,O3,O4} {O1,O3} {O1,O2,O3,O4} {O1,O2,O3,O4}
W= {O3}{O2}{O2,O3}{O2,O4}{O4}
I want to get as a result a cell array named S of size [1X4] as follows :
I put the contents of K{i} in every S{j} where j are the indices of the contents of W{i} (for example the cell W{3} has as content O2 and O3 so j=2,3. I put the content of K{3} in the cells S{2} and S{3} ).
After that I add in every S{i} a content Oi and I eliminate redundancy in S.
The expected result is the following :
S={O1}{O1,O2,O3,O4}{O1,O3}{O1,O2,O3,O4}
You can use the union function for this as well as several loops:
function S = q47140074(K,W)
if nargin < 2
% Input data:
K = {"", ("O"+(1:4).').', ("O"+[1;3]).', ("O"+(1:4).').', ("O"+(1:4).').'};
W = {"O3", "O2", ("O"+(2:3).').', ("O"+[2;4]).', "O4"};
end
% Preprocess data:
Wn = cellfun(#stripO,W,'UniformOutput',false);
% Preallocation:
S = num2cell(strings(1, max(cellfun(#max,Wn))));
% Computation:
for ind1 = 1:numel(Wn)
tmpW = Wn{ind1};
for ind2 = 1:numel(tmpW)
S{tmpW(ind2)} = union(S{tmpW(ind2)}, K{tmpW(ind2)});
end
end
for ind1 = 1:numel(S)
S{ind1} = setdiff(union(S{ind1},"O" + ind1),"");
end
end
function out = stripO(in)
out = str2double(strip(in,'left','O'));
end
Result:
Here is a solution using accumarray and unique:
K= {{} ,{'O1','O2','O3','O4'} ,{'O1','O3'} ,{'O1','O2','O3','O4'} ,{'O1','O2','O3','O4'}};
W= {{'O3'},{'O2'},{'O2','O3'},{'O2','O4'},{'O4'}};
subs = sscanf(cell2mat([W{:}]),'O%d');
m = max(subs);
subs = [subs;(1:m).'];
vals = repelem(1:numel(W),cellfun(#numel,W));
vals = [vals numel(K)+1:numel(K)+m]
K = [K num2cell(cellstr(num2str((1:m).','O%d'))).'];
%If your data are string scalars use the following K
%K = [K num2cell(string(cellstr(num2str((1:m).','O%d')))).']
result = accumarray(subs,vals,[],#(x){unique([K{x}])})
result =
{
[1,1] =
{
[1,1] = O1
}
[2,1] =
{
[1,1] = O1
[1,2] = O2
[1,3] = O3
[1,4] = O4
}
[3,1] =
{
[1,1] = O1
[1,2] = O3
}
[4,1] =
{
[1,1] = O1
[1,2] = O2
[1,3] = O3
[1,4] = O4
}
}
This question already has an answer here:
MATLAB : What is the mistake in my Ramachandran plot?
(1 answer)
Closed 8 years ago.
I am trying matlab to plot ramachandran plot, without using built in command. I have succeeded too. Now I wanted to spot the GLYCINEs alone in the scatter array. Any ideas how to do this? (link to 1UBQ.pdb file : http://www.rcsb.org/pdb/download/downloadFile.do?fileFormat=pdb&compression=NO&structureId=1UBQ)
% Program to plot Ramanchandran plot of Ubiquitin
close all; clear ; clc; % close all figure windows, clear variables, clear screen
pdb1 ='/home/devanandt/Documents/VMD/1UBQ.pdb';
p=pdbread(pdb1); % read pdb file corresponding to ubiquitin protein
atom={p.Model.Atom.AtomName};
n_i=find(strcmp(atom,'N')); % Find indices of atoms
ca_i=find(strcmp(atom,'CA'));
c_i=find(strcmp(atom,'C'));
X = [p.Model.Atom.X];
Y = [p.Model.Atom.Y];
Z = [p.Model.Atom.Z];
X_n = X(n_i(2:end)); % X Y Z coordinates of atoms
Y_n = Y(n_i(2:end));
Z_n = Z(n_i(2:end));
X_ca = X(ca_i(2:end));
Y_ca = Y(ca_i(2:end));
Z_ca = Z(ca_i(2:end));
X_c = X(c_i(2:end));
Y_c = Y(c_i(2:end));
Z_c = Z(c_i(2:end));
X_c_ = X(c_i(1:end-1)); % the n-1 th C (C of cabonyl)
Y_c_ = Y(c_i(1:end-1));
Z_c_ = Z(c_i(1:end-1));
V_c_ = [X_c_' Y_c_' Z_c_'];
V_n = [X_n' Y_n' Z_n'];
V_ca = [X_ca' Y_ca' Z_ca'];
V_c = [X_c' Y_c' Z_c'];
V_ab = V_n - V_c_;
V_bc = V_ca - V_n;
V_cd = V_c - V_ca;
phi=0;
for k=1:numel(X_c)
n1=cross(V_ab(k,:),V_bc(k,:))/norm(cross(V_ab(k,:),V_bc(k,:)));
n2=cross(V_bc(k,:),V_cd(k,:))/norm(cross(V_bc(k,:),V_cd(k,:)));
x=dot(n1,n2);
m1=cross(n1,(V_bc(k,:)/norm(V_bc(k,:))));
y=dot(m1,n2);
phi=cat(2,phi,-atan2d(y,x));
end
phi=phi(1,2:end);
X_n_ = X(n_i(2:end)); % (n+1) nitrogens
Y_n_ = Y(n_i(2:end));
Z_n_ = Z(n_i(2:end));
X_ca = X(ca_i(1:end-1));
Y_ca = Y(ca_i(1:end-1));
Z_ca = Z(ca_i(1:end-1));
X_n = X(n_i(1:end-1));
Y_n = Y(n_i(1:end-1));
Z_n = Z(n_i(1:end-1));
X_c = X(c_i(1:end-1));
Y_c = Y(c_i(1:end-1));
Z_c = Z(c_i(1:end-1));
V_n_ = [X_n_' Y_n_' Z_n_'];
V_n = [X_n' Y_n' Z_n'];
V_ca = [X_ca' Y_ca' Z_ca'];
V_c = [X_c' Y_c' Z_c'];
V_ab = V_ca - V_n;
V_bc = V_c - V_ca;
V_cd = V_n_ - V_c;
psi=0;
for k=1:numel(X_c)
n1=cross(V_ab(k,:),V_bc(k,:))/norm(cross(V_ab(k,:),V_bc(k,:)));
n2=cross(V_bc(k,:),V_cd(k,:))/norm(cross(V_bc(k,:),V_cd(k,:)));
x=dot(n1,n2);
m1=cross(n1,(V_bc(k,:)/norm(V_bc(k,:))));
y=dot(m1,n2);
psi=cat(2,psi,-atan2d(y,x));
end
psi=psi(1,2:end);
scatter(phi,psi)
box on
axis([-180 180 -180 180])
title('Ramachandran Plot for Ubiquitn Protein','FontSize',16)
xlabel('\Phi^o','FontSize',20)
ylabel('\Psi^o','FontSize',20)
grid
The output is :
EDIT : Is my plot correct? Biopython: How to avoid particular amino acid sequences from a protein so as to plot Ramachandran plot? has an answer which has slightly different plot.
The modified code is as below :
% Program to plot Ramanchandran plot of Ubiquitin with no glycines
close all; clear ; clc; % close all figure windows, clear variables, clear screen
pdb1 ='/home/devanandt/Documents/VMD/1UBQ.pdb';
p=pdbread(pdb1); % read pdb file corresponding to ubiquitin protein
atom={p.Model.Atom.AtomName};
n_i=find(strcmp(atom,'N')); % Find indices of atoms
ca_i=find(strcmp(atom,'CA'));
c_i=find(strcmp(atom,'C'));
X = [p.Model.Atom.X];
Y = [p.Model.Atom.Y];
Z = [p.Model.Atom.Z];
X_n = X(n_i(2:end)); % X Y Z coordinates of atoms
Y_n = Y(n_i(2:end));
Z_n = Z(n_i(2:end));
X_ca = X(ca_i(2:end));
Y_ca = Y(ca_i(2:end));
Z_ca = Z(ca_i(2:end));
X_c = X(c_i(2:end));
Y_c = Y(c_i(2:end));
Z_c = Z(c_i(2:end));
X_c_ = X(c_i(1:end-1)); % the n-1 th C (C of cabonyl)
Y_c_ = Y(c_i(1:end-1));
Z_c_ = Z(c_i(1:end-1));
V_c_ = [X_c_' Y_c_' Z_c_'];
V_n = [X_n' Y_n' Z_n'];
V_ca = [X_ca' Y_ca' Z_ca'];
V_c = [X_c' Y_c' Z_c'];
V_ab = V_n - V_c_;
V_bc = V_ca - V_n;
V_cd = V_c - V_ca;
phi=0;
for k=1:numel(X_c)
n1=cross(V_ab(k,:),V_bc(k,:))/norm(cross(V_ab(k,:),V_bc(k,:)));
n2=cross(V_bc(k,:),V_cd(k,:))/norm(cross(V_bc(k,:),V_cd(k,:)));
x=dot(n1,n2);
m1=cross(n1,(V_bc(k,:)/norm(V_bc(k,:))));
y=dot(m1,n2);
phi=cat(2,phi,-atan2d(y,x));
end
phi=phi(1,2:end);
X_n_ = X(n_i(2:end)); % (n+1) nitrogens
Y_n_ = Y(n_i(2:end));
Z_n_ = Z(n_i(2:end));
X_ca = X(ca_i(1:end-1));
Y_ca = Y(ca_i(1:end-1));
Z_ca = Z(ca_i(1:end-1));
X_n = X(n_i(1:end-1));
Y_n = Y(n_i(1:end-1));
Z_n = Z(n_i(1:end-1));
X_c = X(c_i(1:end-1));
Y_c = Y(c_i(1:end-1));
Z_c = Z(c_i(1:end-1));
V_n_ = [X_n_' Y_n_' Z_n_'];
V_n = [X_n' Y_n' Z_n'];
V_ca = [X_ca' Y_ca' Z_ca'];
V_c = [X_c' Y_c' Z_c'];
V_ab = V_ca - V_n;
V_bc = V_c - V_ca;
V_cd = V_n_ - V_c;
psi=0;
for k=1:numel(X_c)
n1=cross(V_ab(k,:),V_bc(k,:))/norm(cross(V_ab(k,:),V_bc(k,:)));
n2=cross(V_bc(k,:),V_cd(k,:))/norm(cross(V_bc(k,:),V_cd(k,:)));
x=dot(n1,n2);
m1=cross(n1,(V_bc(k,:)/norm(V_bc(k,:))));
y=dot(m1,n2);
psi=cat(2,psi,-atan2d(y,x));
end
psi=psi(1,2:end);
res=strsplit(p.Sequence.ResidueNames,' ');
angle =[phi;psi];
angle(:,find(strcmp(res,'GLY'))-1)=[];
scatter(angle(1,:),angle(2,:))
box on
axis([-180 180 -180 180])
title('Ramachandran Plot for Ubiquitn Protein','FontSize',16)
xlabel('\Phi^o','FontSize',20)
ylabel('\Psi^o','FontSize',20)
grid
which gives output (with no GLY) as below :
I would change this code block to use logical indexing
res=strsplit(p.Sequence.ResidueNames,' ');
angle =[phi;psi];
angle(:,find(strcmp(res,'GLY'))-1)=[];
Instead:
residues = strsplit(p.Sequency.ResidueNames,' ');
glycine = ismember(residues,'GLY');
angle = [phi;psi];
angleNoGLY= angle(:,~glycine);
Doing it this way, if you wanted to highlight glycine (or any other residue) you can easily call it out:
angleGLY = angle(:,glycine);
plot(angleNoGLY(1,:),angleNoGLY(2,:),'ob')
line(angleGLY(1,:),angleGLY(2,:),'Marker','o','Color','r','LineStyle','none')
Below is a section for my code.
The user inputs a value for Energy, if the value is on the array ARRDAT(1,x), then I want it to assign the related variables ARRDAT(2,x), ARRDAT(3,x), and ARRDAT(4,x).
If the data is not on the array, I will interpolate (note: only values between two of my given points will be inputted).
I am able to compile it with a warning
warning 179 - Comparning floating point quantities for equality may give misleading results
and as soon as I input any value, whether it's in the table or not I get
error 11, array subscript(s) out of bounds
The error occurs on the line
IF (ARRDAT(1,x) == Energy) THEN
I haven't been able to fix it.
IMPLICIT NONE
REAL :: Dose, Energy, Source, FeAtt, PbAtt, Resp, Distance, Mu, Thickness
INTEGER :: x, y, upp, low
CHARACTER(LEN=4) :: Material
REAL, PARAMETER :: PI = 3.1415926
real, dimension(1:4,1:25) :: ARRDAT
!Energy MeV
ARRDAT(1,1) = 0.01
ARRDAT(1,2) = 0.015
ARRDAT(1,3) = 0.02
ARRDAT(1,4) = 0.03
ARRDAT(1,5) = 0.04
ARRDAT(1,6) = 0.05
ARRDAT(1,7) = 0.06
ARRDAT(1,8) = 0.08
ARRDAT(1,9) = 0.10
ARRDAT(1,10) = 0.15
ARRDAT(1,11) = 0.20
ARRDAT(1,12) = 0.30
ARRDAT(1,13) = 0.40
ARRDAT(1,14) = 0.50
ARRDAT(1,15) = 0.60
ARRDAT(1,16) = 0.80
ARRDAT(1,17) = 1.0
ARRDAT(1,18) = 1.5
ARRDAT(1,19) = 2.0
ARRDAT(1,20) = 3.0
ARRDAT(1,21) = 4.0
ARRDAT(1,22) = 5.0
ARRDAT(1,23) = 6.0
ARRDAT(1,24) = 8.0
ARRDAT(1,25) = 10.0
!Response Function Sv*cm2
ARRDAT(2,1) = 0.062
ARRDAT(2,2) = 0.157
ARRDAT(2,3) = 0.238
ARRDAT(2,4) = 0.329
ARRDAT(2,5) = 0.365
ARRDAT(2,6) = 0.384
ARRDAT(2,7) = 0.400
ARRDAT(2,8) = 0.451
ARRDAT(2,9) = 0.533
ARRDAT(2,10) = 0.777
ARRDAT(2,11) = 1.03
ARRDAT(2,12) = 1.56
ARRDAT(2,13) = 2.06
ARRDAT(2,14) = 2.54
ARRDAT(2,15) = 2.99
ARRDAT(2,16) = 3.83
ARRDAT(2,17) = 4.60
ARRDAT(2,18) = 6.24
ARRDAT(2,19) = 7.66
ARRDAT(2,20) = 10.2
ARRDAT(2,21) = 12.5
ARRDAT(2,22) = 14.7
ARRDAT(2,23) = 16.7
ARRDAT(2,24) = 20.8
ARRDAT(2,25) = 24.7
!mu/rho for iron cm2/g
ARRDAT(3,1) = 169.4
ARRDAT(3,2) = 56.33
ARRDAT(3,3) = 25.16
ARRDAT(3,4) = 7.891
ARRDAT(3,5) = 3.450
ARRDAT(3,6) = 1.833
ARRDAT(3,7) = 1.113
ARRDAT(3,8) = 0.5391
ARRDAT(3,9) = 0.3340
ARRDAT(3,10) = 0.1786
ARRDAT(3,11) = 0.1357
ARRDAT(3,12) = 0.1051
ARRDAT(3,13) = 0.09131
ARRDAT(3,14) = 0.08241
ARRDAT(3,15) = 0.07583
ARRDAT(3,16) = 0.06631
ARRDAT(3,17) = 0.05951
ARRDAT(3,18) = 0.04863
ARRDAT(3,19) = 0.04254
ARRDAT(3,20) = 0.03616
ARRDAT(3,21) = 0.03309
ARRDAT(3,22) = 0.03144
ARRDAT(3,23) = 0.03056
ARRDAT(3,24) = 0.02991
ARRDAT(3,25) = 0.02994
!mu/rho for lead cm2/g
ARRDAT(4,1) = 125.7
ARRDAT(4,2) = 108.3
ARRDAT(4,3) = 84.02
ARRDAT(4,4) = 28.94
ARRDAT(4,5) = 13.44
ARRDAT(4,6) = 7.386
ARRDAT(4,7) = 4.531
ARRDAT(4,8) = 2.112
ARRDAT(4,9) = 5.337
ARRDAT(4,10) = 1.910
ARRDAT(4,11) = 0.9359
ARRDAT(4,12) = 0.3732
ARRDAT(4,13) = 0.2148
ARRDAT(4,14) = 0.1499
ARRDAT(4,15) = 0.1167
ARRDAT(4,16) = 0.08408
ARRDAT(4,17) = 0.06803
ARRDAT(4,18) = 0.05087
ARRDAT(4,19) = 0.04530
ARRDAT(4,20) = 0.04200
ARRDAT(4,21) = 0.04178
ARRDAT(4,22) = 0.04260
ARRDAT(4,23) = 0.04382
ARRDAT(4,24) = 0.04670
ARRDAT(4,25) = 0.04969
WRITE(*,*) 'Please input the particle energy in MeV'
READ(*,*) Energy
x=0
DO x = 0, 25, 1
IF (ARRDAT(1,x) == Energy) THEN !if the data is already on our table
ARRDAT(2,x) = Resp
ARRDAT(3,x) = FeAtt
ARRDAT(4,x) = PbAtt
WRITE(*,*) 'CHECK 1'
ELSE IF (ARRDAT(1,x) < Energy) THEN !if the data is between two points
upp = x
low = x - 1
Energy = ((ARRDAT(1,upp) + ARRDAT(1,low))/2)
WRITE(*,*) Energy
ELSE
WRITE(*,*) 'Invalid Entry'
END IF
END DO
You declare your array to be 1-indexed with real, dimension(1:4,1:25) :: ARRDAT, but your DO loop begins with x = 0, so the first iteration of the loop looks for ARRDAT(1,0) == Energy, which is out of bounds. Start your DO loop with x = 1 and you should be fine.
Side note: Fortran automatically indexes arrays beginning with 1, so you can declare your array as real, dimension(4,25) :: ARRDAT, and it will have the same effect.
EDIT: As mentioned by #user5713492 in the comments, this code will still crash if the input Energy is greater than ARRDAT(1,1). You will either have to fix the lower bound of the linear interpolation or skip the interpolation entirely in the first iteration of the loop. For example:
DO x = 1, 25
IF (ARRDAT(1,x) == Energy) THEN
! ...
ELSE IF (ARRDAT(1,x) < Energy) THEN
upp = x
low = x - 1
IF (low < 1) low = 1 ! <-- make sure we don't go out of bounds on the array
! ...
END IF
END DO
... or ...
DO x = 1, 25
IF (ARRDAT(1,x) == Energy) THEN
! ...
ELSE IF (x > 1 .AND. ARRDAT(1,x) < Energy) THEN ! <-- don't interpolate for the first iteration
! ...
END IF
END DO
Now, about that warning concerning comparison of floating point numbers for equality: please read this and try to avoid ==, >=, and <= operators when comparing reals.