Related
I am trying to parallelize the code below in matlab:
%reduce the size of A if necessary.
A=rand(100,60);
B=int8(rand(size(A,1),size(A,2))>0.5);
N=10;
G=15;
lambda_tol_vector= zeros(G,1);
conto = 1;
for h=-G:0.1:G
lambda_tol_vector(conto)=2^(h);
conto = conto+1;
end
M=4;
tol = 1e-9;
CompletedMat_nopar1={};
tic
for RIPETIZIONE = 1:10
%using normal for loop CompletedMat is saved
for k = 1:size(lambda_tol_vector,1)
%fprintf('Completion using nuclear norm regularization... \n');
%sequential code:
[CompletedMat34,flag] = matrix_completion_nuclear_GG_vec(A.*double(B),double(B),N,lambda_tol_vector(k),tol);
%parallel code thread-based:
if flag==1
CompletedMat_nopar1{RIPETIZIONE,k}=zeros(size(A));
end
CompletedMat_nopar1{RIPETIZIONE,k}=CompletedMat34;
end
end
toc
After having vectorized whereby possible I ended up with the following code:
A = parallel.pool.Constant(A);
lambda_tol_vector=parallel.pool.Constant(lambda_tol_vector);
R=10;
K=size(lambda_tol_vector.Value,1);
CompletedMat_parvec=cell(R,K);
idx=cellfun('isempty', CompletedMat_parvec);
CompletedMat_parvec(idx)={zeros(size(A.Value))};
B=double(B);
tic
parfor n=1:R*K
[~,k]=ind2sub([R,K],n);
%fprintf('Completion using nuclear norm regularization... \n');
[CompletedMat,flag] = matrix_completion_nuclear_GG_vec( ...
A.Value.*B,B, N, lambda_tol_vector.Value(k), tol);
if flag~=0
CompletedMat_parvec{n}=CompletedMat;
end
end
toc
The problem here is that CompletedMat_parvec and CompletedMat_nopar1 provide totally different results while they are expected to give the same result.
How is this possible?
For the sake of completeness I will provide matrix_completion_nuclear_GG_vec below:
%%
% We need a functional environment so that the MAtimesVec subfunction can
% access variables in workspace
function [Anew,objective,flag,iteration] = matrix_completion_nuclear_GG_vec(A,B,N,lambda_tol,tol)
%%
%This code ttries to vectorize and make more efficient the code in
%matrix_completion_nuclear_GG_alt
%% Singular value thresholding for structured (sparse + low rank) matrix
%clear;
%tol=10^-7;
%lambda_tol=0.5;
%%
% Read in sparse matrices downloaded from The University of Florida Sparse
% Matrix Collection
%data = load('mhd4800b.mat');
%A = data.mhd4800b;
%A=A(1:100,1:100);
%A=rand(100,5)*rand(5,100);
%[sA,vA,dA]=svd(A)
%%
% initialization
%B = rand(size(A))<0.3; % remove 10% of the entries
mat=A.*B;
m = size(mat,1);
n = size(mat,2);
L = zeros(m,1);
R = zeros(n,1);
iteration=0;
criterion=0;
flag=0;
Anew=L*R';
objective=zeros();
while (criterion==0 && iteration<N && flag==0)
Aold=Anew;
iteration=iteration+1;
%iteration
%%
% Generation of structured matrix (sparse plus low rank)
%LR = L*R'; % generation of low rank matrix
%Amat = mat + LR; % sparse + low rank
%%
% Find all singular values >= lambda_tol by svt (deflation method). Function
% MAtimesVec is defined at end of this file.
%tic;
%[u,s,v] = svt(#MAtimesVec,'m',m,'n',n,'lambda',lambda_tol);
[u,s,v] = svd(mat+Anew);
%toc;
%display(size(s));
if size(s,1)==0
Anew=NaN*A;
objective=NaN;
flag=1;
return
elseif max(max(s))<=lambda_tol
Anew=NaN*A;
objective=NaN;
flag=1;
return
else
for k=1:min(size(s,1),size(s,2))
if s(k,k)<lambda_tol
s(k,k)=0;
else
s(k,k)=s(k,k)-lambda_tol;
end
end
%size(s,1)
%s=s-lambda_tol*eye(size(s,1));
L=u*s;
R=v;
mat=(A-u*s*v').*B;
Anew=L*R';
objective(iteration)=1/2*(norm(mat,'Fro'))^2+lambda_tol*(sum(diag(s)));
%objective(iteration)
if (norm(Anew-Aold,'Fro')^2/(norm(Aold,'Fro')^2))<tol
criterion=1;
end
%norm(A-Anew,'Fro')
end
end
if flag==1
Anew=[];
objective=[];
end
%%
% Subfunction for exploiting matrix structure of sparse plus low rank
%function MAvec = MAtimesVec(vec, trans)
% if trans
% MAvec = (vec'*mat)' + R*(vec'*L)';
% else
% MAvec = mat*vec + L*(R'*vec);
% end
%end
end
The most interesting aspect of the problem is that it is not always that I get the error on running the code (I get it 3 out of 5 times). The exact error message is given below
" Attempted to access para(2); index out of bounds because numel(para)=1.
Error in sofunc2 (line 6)
r2 = para(2)
Error in sosmc_sch1_c2 (line 55)
obj_value(i)=sofunc2(current_position{:,i}); "
The code is given below
tic
clear all
close all
clc
% Initializing variables
S=10; % no of swarm particles
d=3; % dimension of swarm particles
c1=2; % self confidence parameter
c2=1; % swarm confidence parameter
C=1; % constriction factor
LB=[0 0 0]; %lower bounds of variables
UB=[2 2 2]; %upper bounds of variables
wmax=0.9; % maximum inertia weight
wmin=0.4; % minimum inertia weight
Xmax=1; % maximum position
iter=1; % initial iteration
R1=rand();
R2=rand();
tolerance=1;
Maxiter=40; % maximum number of iteration
maxrun=5;
dt=1;
particle_best=cell(1,S);
particle_best_value=ones(1,S)*1E10;
global_best_value=1E10;
global_best=zeros(1,d);
obj_value=zeros(1,S); % Objective function value of particles
%%%%%%%%
current_position=cell(1,S); % particle position
velocity=cell(1,S); % particle velocity
dummy=zeros(1,length(d)); % dummy list
% Initialize particle position and velocity
for run=1:maxrun
run
for i=1:S
for j=1:d
dummy(j)=round(LB(j)+rand()*(UB(j)-LB(j)));
end
current_position{i}=dummy;
velocity{i}=current_position{i}/dt;
end
while iter <= Maxiter && tolerance > 0.01
for i=1:S
for j=1:d
if current_position{i}<LB(j) %%handling boundary conditions
current_position{i}=LB(j);
elseif current_position{i}>UB(j)
current_position{i}=UB(j);
end
end
end
for i=1:S
obj_value(i)=sofunc2(current_position{:,i});
end
for i=1:S
if obj_value(i) < particle_best_value(i) % finding best local
particle_best{i}= current_position{i};
particle_best_value(i)=obj_value(i);
end
end
[fmin,index]=min(obj_value); % finding out the best particle
ffmin(iter,run)=fmin; % storing best fitness
ffite(run)=iter; % storing iteration count
if min(obj_value)< global_best_value % finding best global
global_best=current_position{obj_value==min(obj_value)}; % updating gbest and best fitness
global_best_value=min(obj_value);
fmin0=global_best_value;
end
for i=1:S
w=wmax-((wmax-wmin)/Maxiter)*iter;
velocity{i}=C*(w*velocity{i}+c1*R1*(particle_best{i}-current_position{i})+c2*R2*(global_best-current_position{i}));
current_position{i}=current_position{i}+velocity{i};
end
% calculating tolerance
if iter>20;
tolerance=abs(ffmin(iter-20,run)-fmin0)
end
% displaying iterative results
if iter==1
disp(fprintf('Iteration Best particle Objective fun'));
end
disp(fprintf('%8g %8g %8.4f',iter,index,fmin0));
iter=iter+1;
subplot(1,2,1);
plot(current_position{i}(1),'rO')
xlim([-5*Xmax 5*Xmax])
ylim([-5*Xmax 5*Xmax])
title('Particles instant location')
grid on
hold on;
hold off;
subplot(1,2,2);
plot(iter,global_best_value,'bO')
grid on
hold on
xlim([0 Maxiter]);
title('Best Particle value histogram');
xlabel('iteration no')
ylabel('global best value')
% pause(0.05)
% disp(['BEST PARTICLE VALUE >> ' num2str(global_best_value)])
end
% pso algorithm-----------------------------------------------------end
global_best;
fvalue=10*(global_best(1)-1)^2+20*(global_best(2)-2)^2+30*(global_best(3)-3)^2;
fff(run)=fvalue;
rgbest(run,:)=global_best;
disp(sprintf('--------------------------------------'));
% disp(['BEST PARTICLE POSITION >> ' num2str(global_best)])
end
% pso main program------------------------------------------------------end
disp(sprintf('\n'));
disp(sprintf('*********************************************************'));
disp(sprintf('Final Results-----------------------------'));
[bestfun,bestrun]=min(fff)
best_variables=rgbest(bestrun,:)
disp(sprintf('*********************************************************'));
toc
% PSO convergence characteristic
plot(ffmin(1:ffite(bestrun),bestrun),'-k');
xlabel('Iteration');
ylabel('Fitness function value');
title('PSO convergence characteristic')
%##########################################################################
function F = sofunc2(para)
% Track the output of optsim to a signal of 1
% Variables a1 and a2 are shared with RUNTRACKLSQ
c2 = para(1)
r2 = para(2)
W2 = para(3)
disp(sprintf('The value of parameters c2= %3.0f, r2= %3.0f, W2= %3.0f', para(1),para(2),para(3)));
% Compute function value
simopt = simset('solver','ode1','SrcWorkspace','current','DstWorkspace','current'); % Initialize sim options
[tout,xout,yout] = sim('sosmc_c2',[0 200],simopt);
% e=yout-1 ; % compute the error
% sys_overshoot=max(yout)-2 % compute the overshoot
if para(1)<0 || para(1)>5
penalty=500;
elseif para(2)<0 || para(2)>5
penalty=500;
elseif para(3)<0 || para(3)>5
penalty=500;
else
penalty=0;
end
A=5; %B=1;C=5;
F=int_abs_error*A+penalty
end
The code has another part which involves a simulink block named 'sosmc_c2'. However, there is no issue with that block diagram and runs smoothly with other instances of the same program. I would like to know what exactly is causing the error in this particular case and how should I solve it.
here is the error :-|
for i=1:S
for j=1:d
if current_position{i}<LB(j) %%handling boundary conditions
current_position{i}=LB(j);
elseif current_position{i}>UB(j)
current_position{i}=UB(j);
end
end
end
you are comparing current position which is a 1x3 matrices with LB(j) which is a "one element matrix"!!!!
I think you might be calling the function, the wrong parameters:
obj_value(i)=sofunc2(current_position{i});
instead of current_position{:,i}.
As far as I can see current_position is a columns vector of cells, not a matrix. I can not run the code fully cause I am missing sim and simset.
Another error, pointed by 'daren shan'
Checking the boundary conditions you are comparing cells and vector.
for i=1:S
for j=1:d
if current_position{i}(j)<LB(j)
current_position{i}(j)=LB(j);
elseif current_position{i}(j)>UB(j)
current_position{i}(j)=UB(j);
end
end
end
What was happening before was that if the whole vector current_position{i} is smaller or larger by LB/UB then the vector is replaced by a single value.
I need to adjust the following algorithm in Matlab because the double loop in step (2) takes to much time when n is large (I should be able to run the algorithm for n=15). Any ideas?
n=3;
% (1) construct A: list of DISPOSITIONS of the elements of the set {0,1} in n
%places (organise 2 elements in n places with possibility of repetitions and the order matters)
A=makeindex(n); %matrix 2^n x n (FAST)
% (2) modify A: it should give the list of COMBINATIONS of the elements of the set
%{0,1} in n-1 places (organise 2 elements in n-1 places with repetitions and the
%order does NOT matter), repeated twice:
% once when the n-th element is 0, the other when the n-th element is 1
Xr=A(:,n);
m=sum(A,2); %vector totalx1
%each element is the total number of ones in the
%corresponding row
drop=false(2^n,1); %logical vector totalx1
for i=1:2^n
parfor j=1:2^n
if j>i
if m(i)==m(j) && Xr(i)==Xr(j) %(VERY SLOW)
drop(j)=true;
end
end
end
end
A(drop,:)=[];
The function makeindex is
function [index]=makeindex(k) %
total=2^k; %
index=zeros(total,k); %
for i=1:k %
ii=1; %
cc=1; %
c=total/(2^i); %
while ii<=total %
if cc <=c %
index(ii,i)=1; %
cc=cc+1; %
ii=ii+1; %
else %
ii=ii+c; %
cc=1; %
end %
end %
end %
%
end
Here my solution if that's what you want:
A=zeros(n,2*n);
A(:,1)=1;
for i=2:2:n*2-1
A(:,i-1)=circshift(A(:,i-1),[-1 0]);
A(:,i)=A(:,i-1);
A(end,i)=0;
A(:,i+1)=A(:,i);
end
A(:,end-1)=circshift(A(:,end-1),[-1 0]);
A=A';
For n = 10:
Elapsed time is 0.000976 seconds.
Old code:
Elapsed time is 32.804602 seconds.
n=15:
Elapsed time is 0.000866 seconds.
Old code:
... still calculating... ;)
I'm a new user of Matlab, can you please help:
I have the following code in an .M file:
`% free vibration of non-prismatic Euler beams with or without axial load
%using differential quadrature method
clc;
ne=50;
n=ne+1;
nn=2*n;
no=4;
m=zeros(n,1);
x=zeros(n,1);
xi=zeros(n,1);
c=zeros(n,n,no);
d=zeros(n+4,n+4);
e=zeros(n+4,n+4);
z=zeros(n+4,1);
f=zeros(n+4,1);
alp=zeros(n,n);
bet=zeros(n,n);
zz=zeros(n,1);
ki=zeros(n,n);
eta=zeros(n,n);
const=1.0;
l=12;
ymod=200e09;
rho=7800;
format long;
for i=1:n
xi(i)=0.5*(1-cos((i-1)*pi/ne));
%mi(i)=0.000038*(1-xi(i)^2/2);
ar(i)=1/rho;
mi(i)=0.000038;
ki(i,i)=ymod*mi(i);
end
c=qquadrature(xi,n,no);
%c = harquadrature(xi,n,no)
for i = 1:n
alp(i,i) = 0;
bet(i,i) = 0;
for j = 1:n
alp(i,i) = alp(i,i)+c(i,j,1)*ki(j,j)/l;
bet(i,i) = bet(i,i)+c(i,j,2)*ki(j,j)/l^2;
end
end
d=zeros(n+4,n+4);
% free vibration of the beam
% axial load on the beam t=+ if it is compressive t=- if it is tensile
% weight of the beam / unit length
t=520895.0;
d(1:n,1:n)=2.0*alp*c(:,:,3)/l^3+bet*c(:,:,2)/l^2+ki*c(:,:,4)/l^4+eta+t*c(:,:,2)/l^2;
% boundary conditions
% clamped - free
% d(n+1,1)=1.0;
% d(n+2:n+2,1:n)=alp(n,n)*c(n,1:n,2)/l^2+ki(n,n)*c(n,1:n,3)/l^3+t*c(n,1:n,1)/l;
% d(n+3:n+3,1:n)=c(1,1:n,1)/l;
% d(n+4:n+4,1:n)=ki(n,n)*c(n,1:n,2)/l^2;
% d(1,n+1)=1.0;
% for i=1:n
% d(i,n+2)=d(n+2,i);
% d(i,n+3)=d(n+3,i);
% d(i,n+4)=d(n+4,i);
% end
% pinned - pinned
d(n+1,1)=1.0;
d(n+2:n+2,1:n)=ki(n,n)*c(n,1:n,2)/l^2;
d(n+3:n+3,1:n)=ki(1,1)*c(1,1:n,2)/l^2;
d(n+4,n)=1.0;
d(n,n+4)=1.0;
d(1,n+1)=1.0;
d(n+4,n)=1.0;
for i = 1:n
d(i,n+2)=d(n+2,i);
d(i,n+3)=d(n+3,i);
end
e=zeros(n+4,n+4);
for i=1:n
e(i,i)=rho*ar(i);
end
z=d\e;
[ev,euv]=eig(z);
for i=1:n
zz(z)=ev(i,5);
end
omega=sqrt(1/euv(5,5));
sprintf(' natural frequency\n')
omega;
figure(1);
plot(xi,zz)
xlabel(' x/L ')
ylabel(' z')
title (' fundamental mode shape ')`
I have stored this file (Untitled.M) in the normal Matlab path, and therefore I'm assuming that Matlab will read the function when it's starting and that this function therefore should be available to use.
Then I am trying to run this single M-files.
But "Undefined function 'qquadrature' for input arguments of type 'double'" message appears..
Can somebody show me where's the problem and how ti fix it?
Thankyou..
I've attempted to look at MatLab documentation here:
http://www.mathworks.com/help/matlab/ref/interp3.html
and then in the
help interp3
section of MatLab, but I'm having trouble figuring out what I want actually and if interp3 is the thing that I'm looking for. But, I may just not be understanding if I'm able to use interp3 with the way I have things laid out as of now. I've attached a figure that I can create from a MatLab program that I wrote. It's taking NOAA lat/long (x/y), U/V directions for wind vectors, and then a Z value for the 2D levels to this field.
Using the format:
quiver3(x,y,z,u,v,w)
with the "W" component set to 0.
This is a very small section of the field, but what I'm trying to do is to interpolate between these 2D vector fields in order to create a 3D field.
Do I have to group U/X , V/Y, and W/Z into their own vectors in order to use interp3 ? I'm still not sure that the 3D function "V" section is in the interp3 syntax of
Vq = interp3(X,Y,Z,V,Xq,Yq,Zq)
This is a very small section of the field, but what I'm trying to do is to interpolate between these 2D vector fields in order to create a 3D field.
My code:
tic
clc
clear all
% You will have to change the directory to wherever you place the read_grib.r4
% file. In addition, It's necessary to have an external compiler connected
% to MatLab in order to build the mex-file that gives you the power to use
% the read_grib decoding. This is really tricky. On OSX I used Xcode as an
% environment and MatLab virtually worked immediately. On Windows, I have
% 2012(b) and had to use the call system('mxvc <BDS_unpack_mex5.c>') which
% utilized Microsoft's C-compiler that I had SOMEWHERE on my computer
% thankfully (may be pre-intalled). There are tutorials online for
% different compilers. In addition, if you're smart about it you can add
% the mex-file build to the start-up operations so you never have to worry
% about it, but my questionably legal MatLab copies seem to make this a
% little more difficult.
cd /Users/Sargent_PC/Downloads/read_grib.r4/
mex BDS_unpack_mex5.c
% ** Inventory doesn't need to be done every iteration **
% ** Uncomment the line below to get a record inventory **
%read_grib('NOAAdata.grb','inv');
% Creating a struct named "grib_struct" for each of the records I'm
% extracting out of the grib file. They exist in pairs with 6 records
% separating them. Should we want to extract ALL of the U and V wind
% components I'll iterate with a simple for-loop.
grib_struct=read_grib('NOAAdata.grb', [60,61,66,67]); %,72,73,78,79,84,85,90,91,96,97]);
UwindVec50mb = grib_struct(1).fltarray; %rec60
VwindVec50mb = grib_struct(2).fltarray; %rec61
UwindVec75mb = grib_struct(3).fltarray; %rec66
VwindVec75mb = grib_struct(4).fltarray; %rec67
% UwindVec100mb = grib_struct(5).fltarray; %rec72
% VwindVec100mb = grib_struct(6).fltarray; %rec73
% UwindVec125mb = grib_struct(7).fltarray; %rec78
% VwindVec125mb = grib_struct(8).fltarray; %rec79
% UwindVec150mb = grib_struct(9).fltarray; %rec84
% VwindVec150mb = grib_struct(10).fltarray; %rec85
% UwindVec175mb = grib_struct(11).fltarray; %rec90
% VwindVec175mb = grib_struct(12).fltarray; %rec91
% UwindVec200mb = grib_struct(13).fltarray; %rec96
% VwindVec200mb = grib_struct(14).fltarray; %rec97
%50mb range has records 60 and 61 for U and V respectively.
%75mb range has records 66 and 67 for U and V respectively.
%100mb range has records 72 and 73 for U and V respectively.
%125mb range has records 78 and 79 for U and V respectively.
%150mb range has records 84 and 85 for U and V respectively.
%175mb range has records 90 and 91 for U and V respectively.
%200mb range has records 96 and 97 for U and V respectively.
%These extracted sections of the grib file will read "extracted" on the
%left-hand side should they be successfully extracted.
load NOAAlatlongdata; % read the data into a matrix
lat_value = NOAAlatlongdata(:,3); % copy first column of NOAAlatlongdata into lat_value
long_value = NOAAlatlongdata(:,4); % and second column of NOAAlatlongdata into long_value
% I was going to add in a pressure to altitude change here, but
% it may be in our best interest to get a list of values for each
% pressure level that correspond to altitude and create our own
% vector of those values in order to simplify the calculations that
% the program has to do.
% z50mb_val = ;
% z75mb_val = ;
% z100mb_val= ;
% z125mb_val= ;
% z150mb_val= ;
% z175mb_val= ;
% z200mb_val= ;
% Creating vectors of the Z-values which are gotten from converting the
% pressure value to altitude. I feel like this is a very bulky way to do
% this, and I've included the tic-toc timing to show that it's ~30seconds
% per vector creation. For each altitude level that we add you'll add
% ~30seconds JUST to the vector creation component of the program.
tic; for i = 1:262792, z50mb_vec=67507*ones(i,1); end; toc;
tic; for i = 1:262792, z75mb_vec=60296*ones(i,1); end; toc;
% tic; for i = 1:262792, z100mb_vec=53084*ones(i,1); end; toc;
%
% tic; for i = 1:262792, z125mb_vec=48865*ones(i,1); end; toc;
%
% tic; for i = 1:262792, z150mb_vec=44646*ones(i,1); end; toc;
%
% tic; for i = 1:262792, z175mb_vec=43763*ones(i,1); end; toc;
%
% tic; for i = 1:262792, z200mb_vec=38661*ones(i,1); end; toc;
%
tic; for i = 1:262792, W_zerovec = 0*ones(i,1); end; toc;
%
% 3D quiver plots format: quiver3(x,y,z,u,v,w) -- Make sure dimensionality
% of all 6 components to that plot match up before plotting.
quiver3((lat_value(1:101)), (long_value(1:25)), ( z50mb_vec(1:25)), (UwindVec50mb(1:25)) ,(VwindVec50mb(1:25)) , W_zerovec(1:25))
hold on
quiver3((lat_value(1:101)), (long_value(1:251)), ( z75mb_vec(1:25)), (UwindVec75mb(1:25)) ,(VwindVec75mb(1:25)) , W_zerovec(1:25))
hold on
% quiver3((lat_value(1:101)), (long_value(1:101)), (z100mb_vec(1:101)), (UwindVec100mb(1:101)),(VwindVec100mb(1:101)), W_zerovec(1:101))
% hold on
% quiver3((lat_value(1:101)), (long_value(1:101)), (z125mb_vec(1:101)), (UwindVec125mb(1:101)),(VwindVec125mb(1:101)), W_zerovec(1:101))
% hold on
% quiver3((lat_value(1:101)), (long_value(1:101)), (z150mb_vec(1:101)), (UwindVec150mb(1:101)),(VwindVec150mb(1:101)), W_zerovec(1:101))
% hold on
% quiver3((lat_value(1:101)), (long_value(1:101)), (z175mb_vec(1:101)), (UwindVec175mb(1:101)),(VwindVec175mb(1:101)), W_zerovec(1:101))
% hold on
% quiver3((lat_value(1:101)), (long_value(1:101)), (z200mb_vec(1:101)), (UwindVec200mb(1:101)),(VwindVec200mb(1:101)), W_zerovec(1:101))
toc
A guy by the name of Failmond is provided me with this, which suitably solves my query! Thanks to all!
zLevels = 5; %number of interpolated points between z50 and z75
nStation = 100; %number of (lat,long) pairs to interpolate
for i = 1:nStation %for nStation different (lat, long) pairs generate interp. values
% generate zQuery points between z50 and z75 for each station
zQuery = ((1:zLevels)/zLevels)*range([z50mb_vec(i) z75mb_vec(i)]) + z75mb_vec(i);
% use interp1 to interpolate about the Z axis for U component
U(i,1:N) = interp1([z50mb_vec(i) z75mb_vec(i)],[UwindVec50mb(i) UwindVec75mb(i)],zQuery);
% and for V component
V(i,1:N) = interp1([z50mb_vec(i) z75mb_vec(i)],[VwindVec50mb(i) VwindVec75mb(i)],zQuery);
end
% defining some color codes for each zLevel, otherwise the plot is a mess
% of colors
colorcode = ['r' 'g' 'b' 'm' 'c' 'r' 'g' 'b' 'm' 'c' 'r'];
for j = 1:nStation
for i = 1:zLevels
quiver3(lat_value(j), long_value(j), zQuery(i), U(j,i), V(j,i), 0, colorcode(i));
hold on;
end
end