How do I resolve error "Operator '>' is not supported for operands of type 'function_handle'" in Matlab? - matlab

The purpose of this iterative function is to update two parameters of my function to keep output values within a desired range (19 to 21)
Here is what I have so far
for i = 2:tw
T1f(i) = dT1(i,T1(i-1),T2(i-1))+T1(i-1);
T2f(i) = dT2(i,T1(i-1),T2(i-1))+T2(i-1);
if ((T1f(i) > 21) | (T2f(i) > 21)) && dT1f > 0
k2f(i:(i+1799)) = k2f(i)-2;
Qfin(i:(i+1799)) = Qfin(i)-500;
N = N+1;
elseif ((19 > T1f(i)) | (19 > T2f(i))) && 0 > dT1f
k2f(i:i+1799) = k2f(i)+2;
Qfin(i:(i+1799)) = Qfin(i)+500;
N = N+1;
end
k2f = max(k2f,10);
k2f = min(k2f,1);
Qfin = max(Qfin,2500);
Qfin = max(Qfin,0);
end
I keep receiving the error Operator '>' is not supported for operands of type 'function_handle for the elseif line, but not at the if line. Why is this and how to I remedy it? Any suggestions about a better way to acheive this would also be appreciated.
Full file will be below.
k1 = 0.2; %W/m^2
k2 = 1750; % W/m^2, constant
k3 = 0.5; %W/m^2
Ain = 0.5; %m^2
Cair = 1005; %J/kg*K
Pair = 1.2; %kg/m^3
Qin = 2500; %W/m^2 constant
L = 5; %m
W = 6; %m
H = 3; %m H1 = H2 = H
T1o = 5; %C
T2o = 7; %C
N = 1;
% Calculating Areas and volumes
Awalls = 2*((L*H)+(W*H)); %m^2
Aceiling = W*L; %m^2
Aroof = sqrt((W*L)^2+(L*H*2)^2)+W*H; %
Vup = W*H*L/2; %m^3
Vdown = W*H*L; %m^3
%Initializing Arrays and Values
tw = 86400*2; %number of seconds in two days
t = [1:1:tw]; %array with integers 1-tw
n = length(t);
T = zeros(1,n);
T1 = zeros(1,n);
T2 = zeros(1,n);
T1f = zeros(1,n);
T2f = zeros(1,n);
T1(1) = T1o;
T2(1) = T2o;
T1f(1) = T1o;
T2f(1) = T2o;
%% Setting Q values
Qfin = zeros(1,n); %Qin for fluctuation
Qfin(1) = 2500;
%% Setting k2 values
k2f = zeros(1,n); %k3 for fluctuation
kf(1) = 10;
%% Defining Functions
Tout = #(t,T) -10*sin(2*pi*t/86400);
%Constant k2/Qin
dT1 = #(t,T1,T2) ((Ain*Qin)-(Aceiling*k2*(T1-T2-5))-(Awalls*k1*(T1-
Tout(t))))/(Cair*Pair*Vdown);
dT2 = #(t,T1,T2) ((Aceiling*k2*(T1-T2-5))-(Aroof*k3*(T2-Tout(t))))/(Cair*Pair*Vup);
%Fluctuating k2/Qin
dT1f = #(t,T1,T2) ((Ain*Qfin(t))-(Aceiling*k2f(t)*(T1-T2-5))-(Awalls*k1*(T1-
Tout(t))))/(Cair*Pair*Vdown);
dT2f = #(t,T1,T2) ((Aceiling*k2f(t)*(T1-T2-5))-(Aroof*k3*(T2-Tout(t))))/(Cair*Pair*Vdown);
%% Iterate for constant k2/Qin with Euler's
for i = 2:tw
T1(i) = dT1(i,T1(i-1),T2(i-1))+T1(i-1);
T2(i) = dT2(i,T1(i-1),T2(i-1))+T2(i-1);
end
%% Iteratre for fluctuation
for i = 2:tw
T1f(i) = dT1(i,T1(i-1),T2(i-1))+T1(i-1);
T2f(i) = dT2(i,T1(i-1),T2(i-1))+T2(i-1);
if ((T1f(i) > 21) | (T2f(i) > 21)) && dT1f > 0
k2f(i:(i+1799)) = k2f(i)-2;
Qfin(i:(i+1799)) = Qfin(i)-500;
N = N+1;
elseif ((19 > T1f(i)) | (19 > T2f(i))) && 0 > dT1f
k2f(i:i+1799) = k2f(i)+2;
Qfin(i:(i+1799)) = Qfin(i)+500;
N = N+1;
end
k2f = max(k2f,10);
k2f = min(k2f,1);
Qfin = max(Qfin,2500);
Qfin = max(Qfin,0);
end

Related

My approximate entropy script for MATLAB isn't working

This is my Approximate entropy Calculator in MATLAB. https://en.wikipedia.org/wiki/Approximate_entropy
I'm not sure why it isn't working. It's returning a negative value.Can anyone help me with this? R1 being the data.
FindSize = size(R1);
N = FindSize(1);
% N = input ('insert number of data values');
%if you want to put your own N in, take away the % from the line above
and
%insert the % before the N = FindSize(1)
%m = input ('insert m: integer representing length of data, embedding
dimension ');
m = 2;
%r = input ('insert r: positive real number for filtering, threshold
');
r = 0.2*std(R1);
for x1= R1(1:N-m+1,1)
D1 = pdist2(x1,x1);
C11 = (D1 <= r)/(N-m+1);
c1 = C11(1);
end
for i1 = 1:N-m+1
s1 = sum(log(c1));
end
phi1 = (s1/(N-m+1));
for x2= R1(1:N-m+2,1)
D2 = pdist2(x2,x2);
C21 = (D2 <= r)/(N-m+2);
c2 = C21(1);
end
for i2 = 1:N-m+2
s2 = sum(log(c2));
end
phi2 = (s2/(N-m+2));
Ap = phi1 - phi2;
Apen = Ap(1)
Following the documentation provided by the Wikipedia article, I developed this small function that calculates the approximate entropy:
function res = approximate_entropy(U,m,r)
N = numel(U);
res = zeros(1,2);
for i = [1 2]
off = m + i - 1;
off_N = N - off;
off_N1 = off_N + 1;
x = zeros(off_N1,off);
for j = 1:off
x(:,j) = U(j:off_N+j);
end
C = zeros(off_N1,1);
for j = 1:off_N1
dist = abs(x - repmat(x(j,:),off_N1,1));
C(j) = sum(~any((dist > r),2)) / off_N1;
end
res(i) = sum(log(C)) / off_N1;
end
res = res(1) - res(2);
end
I first tried to replicate the computation shown the article, and the result I obtain matches the result shown in the example:
U = repmat([85 80 89],1,17);
approximate_entropy(U,2,3)
ans =
-1.09965411068114e-05
Then I created another example that shows a case in which approximate entropy produces a meaningful result (the entropy of the first sample is always less than the entropy of the second one):
% starting variables...
s1 = repmat([10 20],1,10);
s1_m = mean(s1);
s1_s = std(s1);
s2_m = 0;
s2_s = 0;
% datasample will not always return a perfect M and S match
% so let's repeat this until equality is achieved...
while ((s1_m ~= s2_m) && (s1_s ~= s2_s))
s2 = datasample([10 20],20,'Replace',true,'Weights',[0.5 0.5]);
s2_m = mean(s2);
s2_s = std(s2);
end
m = 2;
r = 3;
ae1 = approximate_entropy(s1,m,r)
ae2 = approximate_entropy(s2,m,r)
ae1 =
0.00138568170752751
ae2 =
0.680090884817465
Finally, I tried with your sample data:
fid = fopen('O1.txt','r');
U = cell2mat(textscan(fid,'%f'));
fclose(fid);
m = 2;
r = 0.2 * std(U);
approximate_entropy(U,m,r)
ans =
1.08567461184858

MATLAB 'parfor' Loops Very Slow When Compared With 'for' loop

I have a script that I'm running, and at one point I have a loop over n objects, where I want n to be fairly large.
I have access to a server, so I put in a parfor loop. However, this is incredibly slow compared with a standard for loops.
For example, running a certain configuration ( the one below ) with the parfor loop on 35 workers took 68 seconds, whereas the for loop took 2.3 seconds.
I know there's stuff to do with array-broadcasting that can cause issues, but I don't know a lot about this.
n = 20;
r = 1/30;
tic
X = rand([2,n-1]);
X = [X,[0.5;0.5]];
D = sq_distance(X,X);
A = sparse((D < r) - eye(n));
% Infected set I
I = n;
[S,C] = graphconncomp(A);
compnum = C(I);
I_new = find(C == compnum);
I = I_new;
figure%('visible','off')
gplot(A,X')
hold on
plot(X(1,I),X(2,I),'r.')
hold off
title('time = 0')
axis([0,1,0,1])
time = 0;
t_max = 10; t_int = 1/100;
TIME = 1; T_plot = t_int^(-1) /100;
loops = t_max / T_plot;
F(loops) = struct('cdata',[],'colormap',[]);
F(1) = getframe;
% Probability of healing in interval of length t_int
heal_rate = 1/3; % (higher number is faster heal)
p_heal = t_int * heal_rate;
numhealed = 0;
while time < t_max
time = time+t_int;
steps = poissrnd(t_int,[n,1]);
parfor k = 1:n
for s = 1:steps(k)
unit_vec = unif_unitvector;
X_new = X(:,k) + unit_vec*t_int;
if ( X_new < 1 == ones(2,1) ) ...
& ( X_new > 0 == ones(2,1) )
X(:,k) = X_new;
end
end
end
D = sq_distance(X,X);
A = sparse((D < r) - eye(n));
[S,C] = graphconncomp(A);
particles_healed = binornd(ones(length(I),1),p_heal);
still_infected = find(particles_healed == 0);
I = I(still_infected);
numhealed = numhealed + sum(particles_healed);
I_new = I;
% compnum = zeros(length(I),1);
for i = 1:length(I)
compnum = C(I(i));
I_new = union(I_new,find(C == compnum));
end
I = I_new;
if time >= T_plot*TIME
gplot(A,X')
hold on
plot(X(1,I),X(2,I),'r.')
hold off
title(sprintf('time = %1g',time))
axis([0,1,0,1])
% fprintf('number healed = %1g\n',numhealed)
numhealed = 0;
F(TIME) = getframe;
TIME = TIME + 1;
end
end
toc

how to Improve the speed matlab

This is my matlab code. It runs too slow and I had no clue how to improve it.
Could you help me to improve the speed?
What I would like to do is to create some random points and then remove the random points to make them similar to my target points.
syms Dx Dy p q;
a = 0;
num = 10;
x = rand(1,num);
y = rand(1,num);
figure(1)
scatter(x,y,'.','g')
%num_x = xlsread('F:\bin\test_2');% num 1024
%figure(2)
%scatter(num_x(:,1),num_x(:,2),'.','r');
q = 0;
num_q = 10;
x_q = randn(1,num_q);
y_q = randn(1,num_q);
%figure(2)
hold on;
scatter(x_q,y_q,'.','r')
for i = 1:num_q;
for j = 1:num_q;
qx(i,j) = x_q(i) - x_q(j);
qy(i,j) = y_q(i) - y_q(j);
%qx(i,j) = num_x(i,1) - num_x(j,1);
%qy(i,j) = num_x(i,2) - num_x(j,2);
%d~(s(i),s(j))
if ((qx(i,j))^2+(qy(i,j)^2))> 0.01 % find neighbours
qx(i,j) = 0;
qy(i,j) = 0;
end
end
end
for i = 1:num_q;
for j = 1:num_q;
if qx(i,j)>0&&qy(i,j)>0
q = q + exp(-(((Dx - qx(i,j))^2)+((Dy - qy(i,j))^2))/4);%exp(-(((Dx - qx(i,j))^2)+((Dy - qy(i,j))^2))/4);
end
end
end
%I = ones(num,num); % I(s) should from a grayscale image
%r = 1./sqrt(I);
for s = 1:100;
for i = 1:num;
for j = 1:num;
dx(i,j) = x(i) - x(j);
dy(i,j) = y(i) - y(j);
%d~(s(i),s(j))
if ((dx(i,j))^2+(dy(i,j)^2))> 0.05 % delta p, find neighbours
dx(i,j) = 0;
dy(i,j) = 0;
end
end
end
p = 0;
for i = 1:num;
for j = 1:num;
if dx(i,j)>0&&dy(i,j)>0
p = p + exp(-(((Dx - dx(i,j))^2)+((Dy - dy(i,j))^2))/4);
end
end
end
p = p - q;
sum = 0;
for i = 1:num;
for j = 1:num;
if dx(i,j)>0&&dy(i,j)>0;
kx(i,j) = (1/2)*(Dx-dx(i,j))*exp((-(Dx-dx(i,j))^2+(Dy-dy(i,j))^2)/4);
ky(i,j) = (1/2)*(Dy-dy(i,j))*exp((-(Dx-dx(i,j))^2+(Dy-dy(i,j))^2)/4);
end
end
end
sum_x = ones(1,num);% 1行N列0矩阵
sum_y = ones(1,num);
%fx = zeros(1,num);
for i = 1:num;
for j = 1:num;
if dx(i,j)>0&&dy(i,j)>0;
fx(i) = p*kx(i,j);% j is neighbour to i
fy(i) = p*ky(i,j);
%fx(i) = matlabFunction(fx(i));
%fy(i) = matlabFunction(fy(i));
%P =quad2d(#(Dx,Dy) fx,0,0.01,0,0.01);
%fx =quad(#(Dx) fx,0,0.01);
%fx(i) =quad(#(Dy) fx(i),0,0.01);
%Q =quad2d(#(Dx,Dy) fy,0,0.01,0,0.01);
fx(i) = double(int(int(fx(i),Dx,0,0.01),Dy,0,0.01));
fy(i) = double(int(int(fy(i),Dx,0,0.01),Dy,0,0.01));
%fx(i) = vpa(p*kx(i,j));
%fy(i) = vpa(p*ky(i,j));
%fx(i) = dblquad(#(Dx,Dy)fx(i),0,0.01,0,0.01);
%fy(i) = dblquad(#(Dx,Dy)fy(i),0,0.01,0,0.01);
sum_x(i) = sum_x(i) + fx(i);
sum_y(i) = sum_y(i) + fy(i);
end
end
end
for i = 1:num;
sum_x = 4.*sum_x./num;
sum_y = 4.*sum_y./num;
x(i) = x(i) - 0.05*sum_x(i);
y(i) = y(i) - 0.05*sum_y(i);
end
a = a+1
end
hold on;
scatter(x,y,'.','b')
The fast version of your loop should be something like:
qx = bsxfun(#minus, x_q.', x_q);
qy = bsxfun(#minus, y_q.', y_q);
il = (qx.^2 + qy.^2 >= 0.01);
qx(il) = 0;
qy(il) = 0;
il = qx>0 && qy>0;
q = sum(exp(-((Dx-qx(il)).^2 + (Dy-qy(il)).^2)/4));
%// etc. for vectorization of the inner loops

Vectorizing 4 nested for loops

I'm trying to vectorize the 2 inner nested for loops, but I can't come up with a way to do this. The FS1 and FS2 functions have been written to accept argument for N_theta and N_e, which is what the loops are iterating over
%% generate regions
for raw_r=1:visual_field_width
for raw_c=1:visual_field_width
r = raw_r - center_r;
c = raw_c - center_c;
% convert (r,c) to polar: (eccentricity, angle)
e = sqrt(r^2+c^2)*deg_per_pixel;
a = mod(atan2(r,c),2*pi);
for nt=1:N_theta
for ne=1:N_e
regions(raw_r, raw_c, nt, ne) = ...
FS_1(nt-1,a,N_theta) * ...
FS_2(ne-1,e,N_e,e0_in_deg, e_max);
end
end
end
end
Ideally, I could replace the two inner nested for loops by:
regions(raw_r,raw_c,:,:) = FS_1(:,a,N_theta) * FS_2(:,N_e,e0_in_deg,e_max);
But this isn't possible. Maybe I'm missing an easy fix or vectorization technique? e0_in_deg and e_max are parameters.
The FS_1 function is
function h = FS_1(n,theta,N,t)
if nargin==2
N = 9;
t=1/2;
elseif nargin==3
t=1/2;
end
w = (2*pi)/N;
theta = theta + w/4;
if n==0 && theta>(3/2)*pi
theta = theta - 2*pi;
end
h = FS_f((theta - (w*n + 0.5*w*(1-t)))/w);
the FS_2 function is
function g = FS_gne(n,e,N,e0, e_max)
if nargin==2
N = 10;
e0 = .5;
elseif nargin==3
e0 = .5;
end
w = (log(e_max) - log(e0))/N;
g = FS_f((log(e)-log(e0)-w*(n+1))/w);
and the FS_f function is
function f = FS_f(x, t)
if nargin<2
t = 0.5;
end
f = zeros(size(x));
% case 1
idx = x>-(1+t)/2 & x<=(t-1)/2;
f(idx) = (cos(0.5*pi*((x(idx)-(t-1)/2)/t))).^2;
% case 2
idx = x>(t-1)/2 & x<=(1-t)/2;
f(idx) = 1;
% case 3
idx = x>(1-t)/2 & x<=(1+t)/2;
f(idx) = -(cos(0.5*pi*((x(idx)-(1+t)/2)/t))).^2+1;
I had to assume values for the constants, and then used ndgrid to find the possible configurations and sub2ind to get the indices. Doing this I removed all loops. Let me know if this produced the correct values.
function RunningFunction
%% generate regions
visual_field_width = 10;
center_r = 2;
center_c = 3;
deg_per_pixel = 17;
N_theta = 2;
N_e = 5;
e0_in_deg = 35;
e_max = 17;
[raw_r, raw_c, nt, ne] = ndgrid(1:visual_field_width, 1:visual_field_width, 1:N_theta, 1:N_e);
ind = sub2ind(size(raw_r), raw_r, raw_c, nt, ne);
r = raw_r - center_r;
c = raw_c - center_c;
% convert (r,c) to polar: (eccentricity, angle)
e = sqrt(r.^2+c.^2)*deg_per_pixel;
a = mod(atan2(r,c),2*pi);
regions(ind) = ...
FS_1(nt-1,a,N_theta) .* ...
FS_2(ne-1,e,N_e,e0_in_deg, e_max);
regions = reshape(regions, size(raw_r));
end
function h = FS_1(n,theta,N,t)
if nargin==2
N = 9;
t=1/2;
elseif nargin==3
t=1/2;
end
w = (2*pi)./N;
theta = theta + w/4;
theta(n==0 & theta>(3/2)*pi) = theta(n==0 & theta>(3/2)*pi) - 2*pi;
h = FS_f((theta - (w*n + 0.5*w*(1-t)))/w);
end
function g = FS_2(n,e,N,e0, e_max)
if nargin==2
N = 10;
e0 = .5;
elseif nargin==3
e0 = .5;
end
w = (log(e_max) - log(e0))/N;
g = FS_f((log(e)-log(e0)-w*(n+1))/w);
end
function f = FS_f(x, t)
if nargin<2
t = 0.5;
end
f = zeros(size(x));
% case 1
idx = x>-(1+t)/2 & x<=(t-1)/2;
f(idx) = (cos(0.5*pi*((x(idx)-(t-1)/2)/t))).^2;
% case 2
idx = x>(t-1)/2 & x<=(1-t)/2;
f(idx) = 1;
% case 3
idx = x>(1-t)/2 & x<=(1+t)/2;
f(idx) = -(cos(0.5*pi*((x(idx)-(1+t)/2)/t))).^2+1;
end

Subscripted assignment dimension mismatch in matlab

I executed this code using Feature Matrix 517*11 and Label Matrix 517*1. But once the dimensions of matrices change the code cant be run. How can I fix this?
The error is:
Subscripted assignment dimension mismatch.
in this line :
edges(k,j) = quantlevels(a);
Here is my code:
function [features,weights] = MI(features,labels,Q)
if nargin <3
Q = 12;
end
edges = zeros(size(features,2),Q+1);
for k = 1:size(features,2)
minval = min(features(:,k));
maxval = max(features(:,k));
if minval==maxval
continue;
end
quantlevels = minval:(maxval-minval)/500:maxval;
N = histc(features(:,k),quantlevels);
totsamples = size(features,1);
N_cum = cumsum(N);
edges(k,1) = -Inf;
stepsize = totsamples/Q;
for j = 1:Q-1
a = find(N_cum > j.*stepsize,1);
edges(k,j) = quantlevels(a);
end
edges(k,j+2) = Inf;
end
S = zeros(size(features));
for k = 1:size(S,2)
S(:,k) = quantize(features(:,k),edges(k,:))+1;
end
I = zeros(size(features,2),1);
for k = 1:size(features,2)
I(k) = computeMI(S(:,k),labels,0);
end
[weights,features] = sort(I,'descend');
%% EOF
function [I,M,SP] = computeMI(seq1,seq2,lag)
if nargin <3
lag = 0;
end
if(length(seq1) ~= length(seq2))
error('Input sequences are of different length');
end
lambda1 = max(seq1);
symbol_count1 = zeros(lambda1,1);
for k = 1:lambda1
symbol_count1(k) = sum(seq1 == k);
end
symbol_prob1 = symbol_count1./sum(symbol_count1)+0.000001;
lambda2 = max(seq2);
symbol_count2 = zeros(lambda2,1);
for k = 1:lambda2
symbol_count2(k) = sum(seq2 == k);
end
symbol_prob2 = symbol_count2./sum(symbol_count2)+0.000001;
M = zeros(lambda1,lambda2);
if(lag > 0)
for k = 1:length(seq1)-lag
loc1 = seq1(k);
loc2 = seq2(k+lag);
M(loc1,loc2) = M(loc1,loc2)+1;
end
else
for k = abs(lag)+1:length(seq1)
loc1 = seq1(k);
loc2 = seq2(k+lag);
M(loc1,loc2) = M(loc1,loc2)+1;
end
end
SP = symbol_prob1*symbol_prob2';
M = M./sum(M(:))+0.000001;
I = sum(sum(M.*log2(M./SP)));
function y = quantize(x, q)
x = x(:);
nx = length(x);
nq = length(q);
y = sum(repmat(x,1,nq)>repmat(q,nx,1),2);
I've run the function several times without getting any error.
I've used as input for "seq1" and "seq2" arrays such as 1:10 and 11:20
Possible error might rise in the loops
for k = 1:lambda1
symbol_count1(k) = sum(seq1 == k);
end
if "seq1" and "seq2" are defined as matrices since sum will return an array while
symbol_count1(k)
is expected to be single value.
Another possible error might rise if seq1 and seq2 are not of type integer since they are used as indexes in
M(loc1,loc2) = M(loc1,loc2)+1;
Hope this helps.