I tried to move the matlab to scilab syntax for genetic algorithms, but the selection function had an error. like this - scilab

function [best1, best2] = selection(population)
fitness = zeros(1,length(population));
for i=1:length(population)
fitness(i) = population(i).fitness;
end
[~,index] = max(fitness);
best1 = population(index);
population(index) = [];
fitness(index) = [];
[~,index] = max(fitness);
best2 = population(index);
endfunction

[~,index] = max(fitness);
^
Error: syntax error, unexpected ","

The syntax using "~" when you don't want to assign an output parameter is not available in Scilab. You have to use a dummy variable, e.g.
[dummy,index] = max(fitness)

Related

scilab, passing parameters to the function and changing variable type

I'm trying to build a GUI to output plots for control system design when input parameters of transfer function.I got some problems on passing parameters to the function and changing variable type.
I've got a stucture with examples of simulation parameters:
param = [];
param.parameter = "s";
param.dom = "c"; //domain(c for continuous, d for discrete)
param.num = 1; //numerator of transfer function
param.den = "(s+1)^3"; //denominator
param.fmin = 0.01; //min freq of the plot
param.fmax = 100; //max freq
and a function to plot the graphs:
// display function
function displayProblem(param)
parameter = param.parameter;
dom = param.dom;
num = param.num;
den = param.den;
fmin = param.fmin;
fmax = param.fmax;
s = poly(0,parameter.string);
h = syslin(dom.string,num,den);
// Plotting of model data
delete(gca());
//bode(h,fmin1,fmax1);
gain_axes = newaxes();
gain_axes.title.font_size = 3;
gainplot(h,fmin,fmax);
gain_axes.axes_bounds = [1/3,0,1/3,1/2];
gain_axes.title.text = "Gain Plot";
phase_axes = newaxes();
gain_axes.title.font_size = 3;
phaseplot(h,fmin,fmax);
phase_axes.axes_bounds = [1/3,1/2,1/3,1/2];
phase_axes.title.text = "Phase Plot";
phase_axes = newaxes();
gain_axes.title.font_size = 3;
nyquist(h);
phase_axes.axes_bounds = [2/3,0,1/3,1/2];
phase_axes.title.text = "Nyquist Plot";
endfunction
There's something wrong when passing numerator and denominator to the function. The variable type doesn't match what syslin required. If I replace 'num' and 'den' with '1' and '(s+1)^3', everything worked quite well. Also if I try this line-by-line in control panel, it works, but not in SciNotes. What's the proper way to deal with this? Any suggestion will be greatly appreaciated.
There are 3 errors in your code: Replace
param.den = "(s+1)^3"; //denominator
with
param.den = (%s+1)^3;
Indeed, Scilab has a built-in polynomial type. Polynomials are not defined as a string nor as a vector of coefficients. The predefined constant %s is the monomial s.
In addition,
s = poly(0,parameter.string);
is useless (and incorrect: parameter would work, while parameter.string won't since parameter has no string field: It IS the string). Just remove the line.
As well, replace
h = syslin(dom.string,num,den);
with simply
h = syslin(dom, num,den);
Finally, although the figure's layout is not simple, you can use bode() in the function in the following way:
// delete(gca());
subplot(1,3,2)
bode(h, fmin, fmax)
subplot(2,3,3)
nyquist(h)
gcf().children.title.text=["Nyquist Plot" "Phase Plot" "Gain Plot"]
All in one, the code of your function may resume to
function displayProblem(param)
[dom, num, den] = (param.dom, param.num, param.den);
[fmin, fmax] = (param.fmin, param.fmax);
h = syslin(dom, num,den);
// Plotting of model data
subplot(1,3,2)
bode(h,fmin,fmax);
subplot(2,3,3)
nyquist(h);
gcf().children.title.text=["Nyquist Plot" "Phase Plot" "Gain Plot"];
endfunction
Best regards

Defining a function with the solution of a differential equation in Julia

I want to use the solution of a differential equation into a piecewise function, but when plotting the result Julia returns the error MethodError: no method matching Float64(::LinearAlgebra.Transpose{Float64, Vector{Float64}}). With the code below, you can see the plot works fine until r=50, and that the error shows up for r>50. How can I use the result of the differential equation in a function?
using Plots, DifferentialEquations
const global Ωₘ = 0.23
const global Ωᵣ = 0.0001
const global Ωl = 0.67
const global H₀ = 70.
function lum(du,u,p,z)
du[1] = -u[1]/(1+z) + ((1/H(z))-1/H₀)/(1+z)
end
da0 = [0.]
zspan = (0.,10.)
lumprob = ODEProblem(lum,da0,zspan)
lumsol = solve(lumprob)
α1(r) = π- asin(3*sqrt(3)*sqrt(1-2/r)/r)
α2(r) = asin(3*sqrt(3)*sqrt(1-2/r)/r)
α3(r) = 3*sqrt(3)/r
α4(r) = 3*sqrt(3)/lumsol(r)
function αtot(r)
if 1.99<r<3.0
α1(r)
elseif 3.0<r<=10.0
α2(r)
elseif 10.0<r<=50.0
α3(r)
elseif 50.0<r
α4(r)
end
end
p2=plot(αtot,xlims=(2.0,51.0),xaxis=:log,xlabel="Rₒ/m",label="α")
In your case lumsol returns a 1-element vector but not a number, thus you need to change line
α4(r) = 3*sqrt(3)/lumsol(r)
to the
α4(r) = 3*sqrt(3)/lumsol(r)[1]
(or refactor the code to take into account that fact)
The function plot should take a function that takes a number and returns a number for the case, your αtot function returns a vector if 50 < r.

Iterating over different functions with different number of parameters in Julia

I'm trying to run a loop over different functions with different number of arguments. The variables are created at runtime inside the loop, and I want to use eval at each iteration to instantiate a Struct using the variable :symbol. However, I can't do this since eval only works in the global scope. This is the MWE for the case that works:
function f1(x); return x; end
function f2(x1,x2); return x1+x2; end
handles = [f1,f2]
args =[:(x1),:(x1,x2)]
x1 = 1; x2 = 1;
for (i,f) in enumerate(handles)
params = eval(args[i])
#show f(params...)
end
f(params...) = 1
f(params...) = 2
However, if I move the variable definitions inside the loop, which is what I actually want, it doesn't work after restarting Julia to clear the workspace.
function f1(x); return x; end
function f2(x1,x2); return x1+x2; end
handles = [f1,f2]
args =[:(x1),:(x1,x2)]
for (i,f) in enumerate(handles)
x1 = 1; x2 = 1;
params = eval(args[i])
#show f(params...)
end
ERROR: UndefVarError: x1 not defined
I've tried several of the answers, such as this one, but I can't seem to make it work. I could write a custom dispatch function that takes[x1,x2] and calls f1 or f2 with the correct arguments. But still, is there any way to do this with eval or with an alternative elegant solution?
EDIT: here are more details as to what I'm trying to do in my code. I have a config struct for each algorithm, and in this I want to define beforehand the arguments it takes
KMF_config = AlgConfig(
name = "KMF",
constructor = KMC.KMF,
parameters = :(mu,N,L,p),
fit = KMC.fit!)
MF_config = AlgConfig(
name = "MF",
constructor = KMC.MF,
parameters = :(mu,N,L),
fit = KMC.fit!)
alg_config_list = [KMF_config, MF_config]
for (i,alg_config) in enumerate(alg_config_list)
mu,N,L,p,A,B,C,D,data = gen_vars() #this returns a bunch of variables that are used in different algorithms
method = alg_config.constructor(eval(method.parameters)...)
method.fit(data)
end
One possible solution is to have a function take all the variables and method, and return a tuple with a subset of variables according to method.name. But I'm not sure if it's the best way to do it.
Here's an approach using multiple dispatch rather than eval:
run_a(x, y) = x + 10*y
run_b(x, y, z) = x + 10*y + 100*z
extract(p, ::typeof(run_a)) = (p.x, p.y)
extract(p, ::typeof(run_b)) = (p.x, p.y, p.z)
genvars() = (x=1, y=2, z=3)
function doall()
todo = [
run_a,
run_b,
]
for runalg in todo
v = genvars()
p = extract(v, runalg)
#show runalg(p...)
end
end
In your example you would replace run_a and run_b with KMC.KMF and KMC.MF.
Edit: Cleaned up example to avoid structs that don't exist in your example.

Catching the print of the function

I am using package fda in particular function fRegress. This function includes another function that is called eigchk and checks if coeffients matrix is singular.
Here is the function as the package owners (J. O. Ramsay, Giles Hooker, and Spencer Graves) wrote it.
eigchk <- function(Cmat) {
# check Cmat for singularity
eigval <- eigen(Cmat)$values
ncoef <- length(eigval)
if (eigval[ncoef] < 0) {
neig <- min(length(eigval),10)
cat("\nSmallest eigenvalues:\n")
print(eigval[(ncoef-neig+1):ncoef])
cat("\nLargest eigenvalues:\n")
print(eigval[1:neig])
stop("Negative eigenvalue of coefficient matrix.")
}
if (eigval[ncoef] == 0) stop("Zero eigenvalue of coefficient matrix.")
logcondition <- log10(eigval[1]) - log10(eigval[ncoef])
if (logcondition > 12) {
warning("Near singularity in coefficient matrix.")
cat(paste("\nLog10 Eigenvalues range from\n",
log10(eigval[ncoef])," to ",log10(eigval[1]),"\n"))
}
}
As you can see last if condition checks if logcondition is bigger than 12 and prints then the ranges of eigenvalues.
The following code implements the useage of regularization with roughness pennalty. The code is taken from the book "Functional data analysis with R and Matlab".
annualprec = log10(apply(daily$precav,2,sum))
tempbasis =create.fourier.basis(c(0,365),65)
tempSmooth=smooth.basis(day.5,daily$tempav,tempbasis)
tempfd =tempSmooth$fd
templist = vector("list",2)
templist[[1]] = rep(1,35)
templist[[2]] = tempfd
conbasis = create.constant.basis(c(0,365))
betalist = vector("list",2)
betalist[[1]] = conbasis
SSE = sum((annualprec - mean(annualprec))^2)
Lcoef = c(0,(2*pi/365)^2,0)
harmaccelLfd = vec2Lfd(Lcoef, c(0,365))
betabasis = create.fourier.basis(c(0, 365), 35)
lambda = 10^12.5
betafdPar = fdPar(betabasis, harmaccelLfd, lambda)
betalist[[2]] = betafdPar
annPrecTemp = fRegress(annualprec, templist, betalist)
betaestlist2 = annPrecTemp$betaestlist
annualprechat2 = annPrecTemp$yhatfdobj
SSE1.2 = sum((annualprec-annualprechat2)^2)
RSQ2 = (SSE - SSE1.2)/SSE
Fratio2 = ((SSE-SSE1.2)/3.7)/(SSE1/30.3)
resid = annualprec - annualprechat2
SigmaE. = sum(resid^2)/(35-annPrecTemp$df)
SigmaE = SigmaE.*diag(rep(1,35))
y2cMap = tempSmooth$y2cMap
stderrList = fRegress.stderr(annPrecTemp, y2cMap, SigmaE)
betafdPar = betaestlist2[[2]]
betafd = betafdPar$fd
betastderrList = stderrList$betastderrlist
betastderrfd = betastderrList[[2]]
As penalty factor the authors use certain lambda.
The following code implements the search for the appropriate `lambda.
loglam = seq(5,15,0.5)
nlam = length(loglam)
SSE.CV = matrix(0,nlam,1)
for (ilam in 1:nlam) {
lambda = 10ˆloglam[ilam]
betalisti = betalist
betafdPar2 = betalisti[[2]]
betafdPar2$lambda = lambda
betalisti[[2]] = betafdPar2
fRegi = fRegress.CV(annualprec, templist,
betalisti)
SSE.CV[ilam] = fRegi$SSE.CV
}
By changing the value of the loglam and cross validation I suppose to equaire the best lambda, yet if the length of the loglam is to big or its values lead the coefficient matrix to singulrity. I recieve the following message:
Log10 Eigenvalues range from
-5.44495317739048 to 6.78194912518214
Created by the function eigchk as I already have mentioned above.
Now my question is, are there any way to catch this so called warning? By catch I mean some function or method that warns me when this has happened and I could adjust the values of the loglam. Since there is no actual warning definition in the function beside this print of the message I ran out of ideas.
Thank you all a lot for your suggestions.
By "catch the warning", if you mean, will alert you that there is a potential problem with loglam, then you might want to look at try and tryCatch functions. Then you can define the behavior you want implemented if any warning condition is satisfied.
If you just want to store the output of the warning (which might be assumed from the question title, but may not be what you want), then try looking into capture.output.

How to print a complex number without percent sign in Scilab?

I tried this
a = 1+3*%i;
disp("a = "+string(a))
I got a = 1+%i*3 , but what I want is a = 1. + 3.i
So is there any method in Scilab to print a complex number without the percent sign?
Similarly to Matlab, you can format the output string by including the real and imaginary parts separately.
mprintf('%g + %gi\n', real(a) , imag(a))
However, that looks pretty ugly when the imaginary part is negative. I suggest writing a formatting function:
function s = complexstring(a)
if imag(a)>=0 then
s = sprintf('%g+%gi', real(a) , imag(a))
else
s = sprintf('%g%gi', real(a) , imag(a))
end
endfunction
Examples:
disp('a = '+complexstring(1+3*%i))
disp('b = '+complexstring(1-3*%i))
Output:
a = 1+3i
b = 1-3i

Resources