I am trying to use julai as main language for my work. But I find that this plot is different than python (Which outputs the right plot)
Here is the python code and output
import numpy as np
import math
import matplotlib.pyplot as plt
u = 9.27*10**(-21)
k = 1.38*10**(-16)
j2 = 7/2
nrr = 780
h = 1000
na = 6*10**(23)
rho = 7.842
mgd = 157.25
a = mgd
d = na*rho*u/a
m_f = []
igd = 7.0
for t in range(1,401):
while True:
h1 = h+d*nrr*igd
x2 = (7*u*h1)/(k*t)
x4 = 2*j2
q2 = (x4+1)/x4
m = abs(7*(q2*math.tanh(q2*x2)**-1 - (1/x4)*math.tanh(x2/x4)**-1))
if abs(m - igd) < 10**(-12):
break
else:
igd = m
m_f.append(abs(m))
plt.plot(range(1,401), m_f)
plt.savefig("Py_plot.pdf")
and it gives the following right plot
The right plot as expected
But when I do the same calculations in julia it gives different output than python, here is my julia code
using Plots
u = 9.27*10^(-21)
k = 1.38*10^(-16)
j2 = 7/2
nrr = 780
h = 1000
na = 6*10^(23)
rho = 7.842
mgd = 157.25
a = mgd
d = na*rho*u/a
igd = 7.0
m = 0.0
m_f = Float64[]
for t in 1:400
while true
h1 = h+d*nrr*igd
x2 = (7*u*h1)/(k*t)
x4 = 2*j2
q2 = (x4+1)/x4
m = 7*(q2*coth(rad2deg(q2*x2))-(1/x4)*coth(rad2deg(x2/x4)))
if abs(abs(m)-igd) < 10^(-10)
break
else
igd = m
end
end
push!(m_f, abs(m))
end
plot(1:400, m_f)
and this is the unexpected julia output
unexpected wrong output from julia
I wish for help....
Code:
using Plots
const u = 9.27e-21
const k = 1.38e-16
const j2 = 7/2
const nrr = 780
const h = 1000
const na = 6.0e23
const rho = 7.842
const mgd = 157.25
const a = mgd
const d = na*rho*u/a
function plot_graph()
igd = 7.0
m = 0.0
trange = 1:400
m_f = Vector{Float64}(undef, length(trange))
for t in trange
while true
h1 = h+d*nrr*igd
x2 = (7*u*h1)/(k*t)
x4 = 2*j2
q2 = (x4+1)/x4
m = abs(7*(q2*coth(q2*x2)-(1/x4)*coth(x2/x4)))
if isapprox(m, igd, atol = 10^(-10))
break
else
igd = m
end
end
m_f[t] = m
end
plot(trange, m_f)
end
Plot:
Changes for correctness:
Changed na = 6.0*10^(23) to na = 6.0e23.
Since ^ has a higher precedence than *, 10^23 is evaluated first, and since the operands are Int values, the result is also an Int. However, Int (i.e. Int64) can only hold numbers up to approximately 9 * 10^18, so 10^23 overflows and gives a wrong result.
julia> 10^18
1000000000000000000
julia> 10^19 #overflow starts here
-8446744073709551616
julia> 10^23 #and gives a wrong value here too
200376420520689664
6.0e23 avoids this problem by directly using the scientific e-notation to create a literal Float64 value (Float64 can hold this value without overflowing).
Removed the rad2deg calls when calling coth. Julia trigonometric functions by default take radians, so there's no need to make this conversion.
Other changes
Marked all the constants as const, and moved the rest of the code into a function. See Performance tip: Avoid non-constant global variables
Changed the abs(m - igd) < 10^-10 to isapprox(m, igd, atol = 10^-10) which performs basically the same check, but is clearer and more flexible (for eg. if you wanted to change to a relative tolerance rtol later).
Stored the 1:400 as a named variable trange. This is just because it's used multiple times, so it's easier to manage as a variable.
Changed m_f = Float64[] to m_f = Vector{Float64}(undef, length(trange)) (and the push! at the end to an assignment). If the size of the array is known beforehand (as it is in this case), it's better for performance to pre-allocate it with undef values and then assign to it.
Changed u and k also to use the scientific e-notation, for consistency and clarity (thanks to #DNF for suggesting the use of this notation in the comments).
I wrote a Monte Carlo simulation for M/M/1 queuing system since it's deterministic. Now I tried modifying the same code for a G/G/1 queueing system with interarrival times and service times having a triangular distribution. Instead of drawing samples from Poisson and exponential distribution, I am drawing samples from the triangular distribution (for G/G/1). However, I am getting results that are hard to make sense of. The analytical approximation results say that the mean waiting time in the queue is 0.9708 which is kinda off from the result (~0.75) I am getting with the simulation.
clc
clear
tic
Nc = 1008;
Tsys = zeros(1,Nc);
Tia = zeros(1,Nc);
Ta = zeros(1,Nc);
Tsrv = zeros(1,Nc);
Tnsrv = zeros(1,Nc);
Txsys = zeros(1,Nc);
WTqmc = zeros(1,Nc);
MTqmc = zeros(1,Nc);
MTsys = zeros(1,Nc);
Tri1_min = 2;
Tri1_mid = 3;
Tri1_max = 5;
Tri2_min = 1.8;
Tri2_mid = 2.8;
Tri2_max = 4.5;
pdat = makedist('Triangular','a',Tri1_min,'b',Tri1_mid,'c',Tri1_max);
pdser = makedist('Triangular','a',Tri2_min,'b',Tri2_mid,'c',Tri2_max);
Tia(1) = random(pdat);
Ta(1) = Tia(1);
Tsys(1) = Tsrv(1);
Tnsrv(1) = Ta(1);
Tsrv(1) = random(pdser);
Txsys(1) = Ta(1) + Tsrv(1);
WTqmc(1) = 0;
MTqmc(1) = WTqmc(1);
for i = 2:1:Nc
Tia(i) = random(pdat);
Ta(i) = Ta(i-1) + Tia(i);
Tsys(i) = Ta(i);
if Ta(i) < Txsys(i-1)
Tnsrv(i) = Tnsrv(i-1) + Tsrv(i-1);
else
Tnsrv(i) = Ta(i);
end
Tsrv(i) = random(pdser);
Txsys(i) = Tnsrv(i) + Tsrv(i);
WTqmc(i) = Tnsrv(i)-Ta(i);
Tsys(i) = Txsys(i) - Ta(i);
MTqmc(i) = ((i-1)* MTqmc(i-1) + WTqmc(i))/i;
% MTsys(i) = ((i-1)* MTsys(i-1) + Tsys(i))/i;
end
Tend = Txsys(Nc);
Nts = floor(Tend);
dt = 1;
Time = zeros(1,Nts);
Lq = zeros(1,Nts);
Time(1) = 0;
Lq(1) = 0;
for j = 2:1:Nts
Time(j) = Time(j-1)+dt;
Lq(j) = 0;
for i = 1:1:Nc
if (Ta(i) < Time(j) && Txsys(i) > Time(j) && Tnsrv(i) > Time(j))
Lq(j) = Lq(j)+1;
end
end
end
MLqmc = mean(Lq)
MTqmc1 = MTqmc(Nc)
MTqmc_mean = mean(WTqmc)
SDmtamc = std(WTqmc)
SEmtamc = SDmtamc/sqrt(Nc)
toc
mean1= (2+3+5)/3;
mean2=(1.8+2.8+4.5)/3;
var1=(4+9+25-2*3-2*5-3*5)/18;
var2=(1.8*1.8+2.8*2.8+4.5*4.5-1.8*2.8-1.8*4.5-2.8*4.5)/18;
rho= (1/mean1)/(1/mean2);
ca2= var1/mean1^2;
cs2=var2/mean2^2;
Lq=((rho^2)*(1+cs2)*(ca2+(rho^2)*cs2))/(2*(1-rho)*(1+(rho^2)*cs2));
wq=Lq/(1/mean1)
%Plot Outcomes
figure(1)
plot(Ta,MTqmc)
xlabel('Arrivals')
ylabel('Mean Time in Queue')
title('Queue Length vs Time')
I am trying to figure out a way to make a for loop in which I can compare two cells that will give me two different means. One for class char and the other for class double.
This is what I have so far.
V = {2; 'tree'; 3; 'hope'};
W = {2; 'tree'; 3; 'hope'};
for i = 1:length(V);
if isequal(class(V{i}), 'double')
num = V{i}
elseif isequal(class(V{i}), 'char')
str = V{i}
end
end
for i = 1:length(W);
if isequal(class(W{i}), 'double')
acc_n(i) = isequal(V{i}, W{i})
elseif isequal(class(W{i}), 'char')
acc_s(i) = strcmp(V{i}, W{i})
end
end
mean_d = mean(acc_n)
mean_s = mean(acc_s)
The output I get is:
acc_n =
1 0 1
acc_s =
0 1 0 1
mean_d =
0.6667
mean_s =
0.5000
The output I want is:
1 1 for string, mean = 1. 1 1 for double, mean = 1
How can I do a loop where it only takes the numbers of the cell and the words of the cell separately?
Is there any possible way to only loop through the words or the numbers?
You can first extract strings and doubles and treat them separately, that will avoid loops.
V = {2; 'tree'; 3; 'hope'};
W = {2; 'tree'; 3; 'hope'};
VChar=V(cellfun(#ischar,V));
WChar=W(cellfun(#ischar,W));
acc_s=VChar==WChar;
VNum=cell2mat(V(cellfun(#isnumeric,V)));
WNum=cell2mat(W(cellfun(#isnumeric,W)));
acc_n=VNum==WNum;
Loop version: I haven't tested this but it should work.
%Assumes V and W have equal number of elements.
acc_n=[];
acc_s=[];
for i=1:numel(V)
if isequal(class(V{i}), 'double') && isequal(V{i},W{i})
acc_n=[acc_n true];
elseif isequal(class(V{i}), 'char') && strcmp(V{i},W{i})
acc_s=[acc_s true];
end
end
I want to read a 32 bit integer binary file provided by another program. The file contains only integer and no other characters (like spaces or commas). The C code to read this file is as follows:
FILE* pf = fopen("C:/rktemp/filename.dat", "r");
int sz = width*height;
int* vals = new int[sz];
int elread = fread((char*)vals, sizeof(int), sz, pf);
for( int j = 0; j < height; j++ )
{
for( int k = 0; k < width; k++ )
{
int i = j*width+k;
labels[i] = vals[i];
}
}
delete [] vals;
fclose(pf);
But I don't know how to read this file into array using Lua.
I've tried to read this file using io.read, but part of the array looks like this:
~~~~~~xxxxxxxxyyyyyyyyyyyyyyzzzzzzzz{{{{{{{{{|||||||||}}}}}}}}}}}~~~~~~~~~xxxxxxxyyyyyyyyyyyyyyzzzzzz{{{{{{{{{{|||||||||}}}}}}}}}}}~~~~~~~~~xxyyyyyyyyyyyyyzzzzz{{{{{{|||}}}yyyyyyyyyyyz{{{yyyyyyyyÞľūơǿȵɶʢ˺̤̼ͽаҩӱľǿجٴȵɶʢܷݸ˺⼼ӱľǿ
Also the Matlab code to read this file is like this:
row = image_size(1);
colomn = image_size(2);
fid = fopen(data_path,'r');
A = fread(fid, row * colomn, 'uint32')';
A = A + 1;
B = reshape(A,[colomn, row]);
B = B';
fclose(fid);
I've tried a function to convert bytes to integer, my code is like this:
function bytes_to_int(b1, b2, b3, b4)
if not b4 then error("need four bytes to convert to int",2) end
local n = b1 + b2*256 + b3*65536 + b4*16777216
n = (n > 2147483647) and (n - 4294967296) or n
return n
end
local sup_filename = '1.dat'
fid = io.open(sup_filename, "r")
st = bytes_to_int(fid:read("*all"):byte(1,4))
print(st)
fid:close()
But it still not read this file properly.
You are only calling bytes_to_int once. You need to call it for every int you want to read. e.g.
fid = io.open(sup_filename, "rb")
while true do
local bytes = fid:read(4)
if bytes == nil then break end -- EOF
local st = bytes_to_int(bytes:byte(1,4))
print(st)
end
fid:close()
Now you can use the new feature of Lua language by calling string.unpack , which has many conversion options for format string. Following options may be useful:
< sets little endian
> sets big endian
= sets native endian
i[n] a signed int with n bytes (default is native size)
I[n] an unsigned int with n bytes (default is native size)
The arch of your PC is unknown, so I assume the data to read is unsigned and native-endian.
Since you are reading binary data from the file, you should use io.open(sup_filename, "rb").
The following code may be useful:
local fid = io.open(sup_filename, "rb")
local contents = fid:read("a")
local now
while not now or now < #contents do
local n, now = string.unpack("=I4", contents, now)
print(n)
end
fid:close()
see also: Lua 5.4 manual
The following code is a graphic rendering of the Earth globe spinning eastward. I have two push buttons, Spin and Stop. Both share the same callback function, hAnimaCallback. In particular, this latter does not work. I pretend to use the strings (names) of the push buttons to create a switch that stops the movement. However, I can not get to change the string name inside the while loop and I do not understand why my method is wrong.
function example
fh = figure('Menu','none','Toolbar','none','Units','characters');
T = 0:pi/100:2*pi;
Y = zeros(numel(T),3);
Y(:,1) = 7000*cos(T);
Y(:,2) = 7000*sin(T);
hPanAni = uipanel('parent',fh,'Units','characters','Position',...
[22.6 10.4 53 23],'title','Controls','FontSize',11,...
'FontAngle','italic','FontWeight','bold');
hIniAni = uicontrol(hPanAni,'Style','pushbutton','Units','normalized',...
'Position',[0.14 0.64 0.5 0.12],'String','Spin',...
'FontSize',10,'Callback',#hAnimaCallback);
hFinAni = uicontrol(hPanAni,'Style','pushbutton','Units','normalized',...
'Position',[0.14 0.26 0.5 0.12],'String','Stop',...
'FontSize',10,'Callback',#hAnimaCallback);
hPantSim = uipanel('Parent',fh,'Units','characters',...
'Position',[107.87 8 157.447 42],'BorderType','none','title',...
'Screen','FontSize',11,'FontAngle','italic',...
'FontWeight','bold');
hPantSimInt = uipanel('Parent',hPantSim,'Units','normalized','Position',...
[0 0 1 1],'BorderType','line','BackgroundColor','black');
ah4 = axes('Parent',hPantSimInt,'Units','normalized','Position',...
[0 0 1 1],'Color','none','Visible','off','DataAspectRatio',...
[1 1 1],'NextPlot','add');
rotate3d(ah4);
hgrot = hgtransform('Parent',ah4);
Resf = 6378;
maptext = imread('tierra.jpg');
[X, map] = rgb2ind(maptext,128);
[x,y,z] = sphere(50);
x = Resf*x;
y = Resf*y;
z = Resf*z;
props.FaceColor= 'texture';
props.EdgeColor = 'none';
props.Parent = hgrot;
props.Cdata = flipud(X); % it is necesary to do this for getting the
% appropiate image on the sphere
hsurf = surface(x,y,z,props);
colormap(map);
axis equal;
view([71 14]);
set(gcf,'Renderer','opengl')
drawnow;
line('parent',ah4,'XData',Y(:,1),'YData',Y(:,2),'ZData',...
Y(:,3),'Color','red','LineWidth',2);
line('parent',ah4,'XData',Y(end,1),'YData',Y(end,2),...
'ZData',Y(end,3),'Marker','o','MarkerSize',6,'MarkerFaceColor','b');
axis square equal vis3d;
view(3);
handles.XLim = get(ah4,'XLim');
handles.YLim = get(ah4,'YLim');
handles.ZLim = get(ah4,'ZLim');
xmin = handles.XLim(1);
ymin = handles.YLim(1);
zmin = handles.ZLim(1);
xmax = handles.XLim(2);
ymax = handles.YLim(2);
zmax = handles.ZLim(2);
set(ah4, 'XLim', [xmin xmax],'YLim', [ymin ymax],'Zlim',[zmin zmax]);
az = 0;
function hAnimaCallback(hObject,evt)
while (ishandle(fh))
state = get(hObject,'String'), % state should change between the states of
% Spin and Stop but this does not occur
if (strcmp(state,'Stop'))
break;
else
az = az + 0.01745329252;
set(hgrot,'Matrix',makehgtform('zrotate',az));
drawnow;
end
end
end
end
It seems like you are running into some kind of race condition because of the repeated drawnow calls in the while loop. The state changes to Stop, when you press the Stop button, but it is to quick to notice. Basically, the while loop is running as fast as MATLAB can run. Instead of drawnow using a pause(0.1) command seems to work (with a little bit code logic changes):
az = 0;
spin = false;
function hAnimaCallback(hObject,~)
state = get(hObject,'String')
if strcmp(state, 'Spin')
spin = true;
else
spin = false;
end
while (spin)
az = az + 0.01745329252;
set(hgrot,'Matrix',makehgtform('zrotate',az));
pause(0.1);
end
end