Measuring CPU time using Scilab - scilab

I'm new to working with Scilab, and I'm trying to run the code below, but when I try it keeps showing me this error::
test3(1000) //Line that I type to run the code
!--error 4 //First error
Undefined variable: cputime
at line 2 of function test3 called by:
I ran it using MATLAB, and it worked, but I can't figure out how to make it run using Scilab.
For sample code when typed using the Scilab editor, see below.
function test3(n)
t = cputime;
for (j = 1:n)
x(j) = sin(j);
end
disp(cputime - t);

Typing help cputime in the Scilab console will reveal that this is not a Scilab function. The near-equivalent Scilab function is timer(), but its behavior is a bit different:
cputime in Matlab measures time since Matlab started
timer() measures time since the last call to timer()
Here is your function rewritten in Scilab:
function test3(n)
timer()
for j = 1:n
x(j) = sin(j)
end
disp(timer())
endfunction
Note that Scilab functions must end with endfunction, and that semicolons are optional: line-by-line output is suppressed in Scilab by default.
For completeness, I'll mention tic() and toc(), which work just like Matlab's tic and toc, measuring real-world time of computation.

Related

Why is the FOR loop in my program producing empty matrices?

I am having a problem running a spiking-neuron simulator. I keep getting the error message, "operation +: Warning adding a matrix with the empty matrix will give an empty matrix result." Now I'm writing this program in "Scilab," but I'm hoping the problem I am having will be clear for the educated eye regardess. What I am doing is converting an existing MATLAB program to Scilab. The original MATLAB program and an explanation can be found here: https://www.izhikevich.org/publications/spikes.pdf
What happens in my Scilab version is that the first pass through the loop produces all the expected values. I Know this becuase I hit pause at the end of the first run, right before "end," and check all the values and matrix elements. However, if I run the program proper, which includes a loop of 20 iterations, I get the error message above, and all of the matrix values are empty! I cannot figure out what the problem is. I am fairly new to programming so the answer may be very simple as far as I know. Here is the Scilab version of the program:
Ne=8; Ni=2;
re=rand(Ne,1); ri=rand(Ni,1);
a=[0.02*ones(Ne,1); 0.02+0.08*ri];
b=[0.2*ones(Ne,1); 0.25-0.05*ri];
c=[-65+15*re.^2; -65*ones(Ni,1)];
d=[8-6*re.^2; 2*ones(Ni,1)];
S=[0.5*rand(Ne+Ni,Ne), -rand(Ne+Ni,Ni)];
v=60*rand(10,1)
v2=v
u=b.*v;
firings=[];
for t=1:20
I=[5*rand(Ne,1,"normal");2*rand(Ni,1,"normal")];
fired=find(v>=30);
j = length(fired);
h = t*ones(j,1);
k=[h,fired'];
firings=[firings;k];
v(fired)=c(fired);
u(fired)=u(fired)+d(fired);
I=I+sum(S(:,fired),"c");
v=v+0.5*(0.04*v.^2+5*v+140-u+I);
v=v+0.5*(0.04*v.^2+5*v+140-u+I);
u=u+a.*(b.*v-u);
end
plot(firings(:,1), firings(:,2),".");
I tried everything to no avail. The program should run through 20 iterations and produce a "raster plot" of dots representing the fired neurons at each of the 20 time steps.
You can add the following line
oldEmptyBehaviour("on")
at the beginning of your script in order to prevent the default Scilab rule (any algebraic operation with an empty matrix yields an empty matrix). However you will still have some warnings (despite the result will be OK). As a definitive fix I recommend testing the emptyness of fired in your code, like this:
Ne=8; Ni=2;
re=rand(Ne,1); ri=rand(Ni,1);
a=[0.02*ones(Ne,1); 0.02+0.08*ri];
b=[0.2*ones(Ne,1); 0.25-0.05*ri];
c=[-65+15*re.^2; -65*ones(Ni,1)];
d=[8-6*re.^2; 2*ones(Ni,1)];
S=[0.5*rand(Ne+Ni,Ne), -rand(Ne+Ni,Ni)];
v=60*rand(10,1)
v2=v
u=b.*v;
firings=[];
for t=1:20
I=[5*rand(Ne,1,"normal");2*rand(Ni,1,"normal")];
fired=find(v>=30);
if ~isempty(fired)
j = length(fired);
h = t*ones(j,1);
k=[h,fired'];
firings=[firings;k];
v(fired)=c(fired);
u(fired)=u(fired)+d(fired);
I=I+sum(S(:,fired),"c");
end
v=v+0.5*(0.04*v.^2+5*v+140-u+I);
v=v+0.5*(0.04*v.^2+5*v+140-u+I);
u=u+a.*(b.*v-u);
end
plot(firings(:,1), firings(:,2),".");
The [] + 1 is not really defined in a mathematical sense. The operation might fail or produce different results depending on the software you use. For example:
Scilab 5 [] + 1 produces 1
Scilab 6 [] + 1 produces [] and a warning
Julia 1.8 [] .+ 1 produces [] but [] + 1 an error.
Python+Numpy 1.23 np.zeros((0,0)) + 1 produces [].
I suggest checking with size() or a comparison to the empty matrix to avoid such strange behaviour.

writing into shared arrays within a distributed for loop in JULIA

I have an ODE that I need to solver over a wide range of parameters.
Previously I have used MATLAB's parfor to divide the parameter ranges between multiple threads. I am new to Julia and need to do the same thing in Julia now. Here is the code that I am using
using DifferentialEquations, SharedArrays, Distributed, Plots
function SingleBubble(du,u,p,t)
du[1]=#. u[2]
du[2]=#. ((-0.5*u[2]^2)*(3-u[2]/(p[4]))+(1+(1-3*p[7])*u[2]/p[4])*((p[6]-p[5])/p[2]+2*p[1]/(p[2]*p[8]))*(p[8]/u[1])^(3*p[7])-2*p[1]/(p[2]*u[1])-4*p[3]*u[2]/(p[2]*u[1])-(1+u[2]/p[4])*(p[6]-p[5]+p[10]*sin(2*pi*p[9]*t))/p[2]-p[10]*u[1]*cos(2*pi*p[9]*t)*2*pi*p[9]/(p[2]*p[4]))/((1-u[2]/p[4])*u[1]+4*p[3]/(p[2]*p[4]))
end
R0=2e-6
f=2e6
u0=[R0,0]
LN=1000
RS = SharedArray(zeros(LN))
P = SharedArray(zeros(LN))
bif = SharedArray(zeros(LN,6))
#distributed for i= 1:LN
ps=1e3+i*1e3
tspan=(0,60/f)
p=[0.0725,998,1e-3,1481,0,1.01e5,7/5,R0,f,ps]
prob = ODEProblem(SingleBubble,u0,tspan,p)
sol=solve(prob,Tsit5(),alg_hints=:stiff,saveat=0.01/f,reltol=1e-8,abstol=1e-8)
RS[i]=maximum((sol[1,5000:6000])/R0)
P[i]=ps
for j=1:6
nn=5500+(j-1)*100;
bif[i,j]=(sol[1,nn]/R0);
end
end
plotly()
scatter(P/1e3,bif,shape=:circle,ms=0.5,label="")#,ma=0.6,mc=:black,mz=1,label="")
When using one worker, the for loop is basically executed as a normal single threaded loop and it works fine. However, when I am using addprocs(n) to add n more workers, nothing gets written into the SharedArrays RS, P and bif. I appreciate any guidance anyone may provide.
These changes are required to make your program work with multiple workers and display the results you need:
Whatever packages and functions are used under #distributed loop must be made available in all the processes using #everywhere as explained here. So, in your case it would be DifferentialEquations and SharedArrays packages as well as the SingleBubble() function.
You need to draw the plot only after all the workers have finished their tasks. For this, you would need to use #sync along with #distributed.
With these changes, your code would look like:
using Distributed, Plots
#everywhere using DifferentialEquations, SharedArrays
#everywhere function SingleBubble(du,u,p,t)
du[1]=#. u[2]
du[2]=#. ((-0.5*u[2]^2)*(3-u[2]/(p[4]))+(1+(1-3*p[7])*u[2]/p[4])*((p[6]-p[5])/p[2]+2*p[1]/(p[2]*p[8]))*(p[8]/u[1])^(3*p[7])-2*p[1]/(p[2]*u[1])-4*p[3]*u[2]/(p[2]*u[1])-(1+u[2]/p[4])*(p[6]-p[5]+p[10]*sin(2*pi*p[9]*t))/p[2]-p[10]*u[1]*cos(2*pi*p[9]*t)*2*pi*p[9]/(p[2]*p[4]))/((1-u[2]/p[4])*u[1]+4*p[3]/(p[2]*p[4]))
end
R0=2e-6
f=2e6
u0=[R0,0]
LN=1000
RS = SharedArray(zeros(LN))
P = SharedArray(zeros(LN))
bif = SharedArray(zeros(LN,6))
#sync #distributed for i= 1:LN
ps=1e3+i*1e3
tspan=(0,60/f)
p=[0.0725,998,1e-3,1481,0,1.01e5,7/5,R0,f,ps]
prob = ODEProblem(SingleBubble,u0,tspan,p)
sol=solve(prob,Tsit5(),alg_hints=:stiff,saveat=0.01/f,reltol=1e-8,abstol=1e-8)
RS[i]=maximum((sol[1,5000:6000])/R0)
P[i]=ps
for j=1:6
nn=5500+(j-1)*100;
bif[i,j]=(sol[1,nn]/R0);
end
end
plotly()
scatter(P/1e3,bif,shape=:circle,ms=0.5,label="")#,ma=0.6,mc=:black,mz=1,label="")
Output using multiple workers:

Parallel processing using DataFrames in Julia

I am referring to the example in the documentation for processing Parallel loops and trying to adapt it for my use case. In each independent iteration in my case, I get a DataFrame as a result which I need to finally combine across all iterations using vcat(). This is a simplified version of my attempt so far:
using DataFrames, Distributed
function test()
if length(workers()) < length(Sys.cpu_info())
addprocs(length(Sys.cpu_info()); exeflags="--project=" * Base.active_project())
end
nheads = #distributed (vcat) for i = 1:20
DataFrame(a=[Int(rand(Bool))])
end
end
But on running test(), I get the error:
ERROR: On worker 2: UndefVarError: DataFrame not defined
What do I need to do to correct this?
Your using DataFrames ... statement on the first line only applies to the main "thread". So your worker threads didn't import the required libraries.
To fix this, you should add the keyword #everywhere on the first line. That would ask all the processes to import those libraries.
Edit
Just noticed that you did addprocs in the function. Then my suggestion wouldn't work. Here's a working version:
using Distributed
addprocs(length(Sys.cpu_info()))
#everywhere using DataFrames
function test()
nheads = #distributed (vcat) for i = 1:20
DataFrame(a=[Int(rand(Bool))])
end
end
test()

Scilab 5.5.2 function as a block in xcos : Variable returned by scilab argument function is incorrect [

I have been trying to get the ultrasonic data from an arduino using serial communication toolbox in scilab to be brought in the xcos simulation. To do this I followed Include a Scilab function/script as a block in xcos/scicos and created my own function. Is there a way to plot the serialread data in xcos scope? or i think my implementation is wrong in the scilab function. Iam Using Windows 10 64bit
SCILAB function
function y = serialREAD(a)
h = openserial(7, "9600,n,8,1") // open COM7
for ii = 1:a
y = strtod(part(readserialline(h), [1,2,3])) * (a/a)
end
closeserial(h)
endfunction
endfunction
XCOS block diagram
The ERROR [ This error has been solved converted the string to a double using the strtod ]
The Data in CMscope but not in realtime only after the simulation my final integration time is 100.

Scilab pointer function

I am working on converting code from MATLAB to scilab included here.
The # symbol is used as a memory pointer in MATLAB pointing to the location of the function tst_callback.
Scilab does not like this however. Is there a scilab equivalent for the #?
function test
sysIDgui(#tst_callback)
end
function tst_callback()
disp("Hello Ron")
endfunction
What you are trying to do is to pass a function as argument to another function. In Scilab, you don't need any special syntax.
Try it yourself. Define these two functions:
function y = applyFunction(f,x)
y = f(x);
endfunction
function y = double(x)
y = x * 2;
endfunction
Then test it on the console:
--> applyFunction(double,7)
ans =
14.
Note: the main usage of # in MATLAB, is to create anonymous functions (see documentation), ones that are not defined in a separate file. As for Scilab, there is no way to create anonymous functions.

Resources