The script below runs fine in SciLab 5.5.2. In 6.0.0 it crashes when the csim() function is executed (line 21).
For this test set x0 = [1 1.5 .25 .125];
The error reads as;
lsode-- caution... t (=r1) and h (=r2) are
such that t + h = t at next step
(h = step). integration continues
where r1 is : 0.0000000000000D+00 and r2 : 0.0000000000000D+00
lsode-- at t (=r1) with step h (=r2),
corrector does not converge
with abs(h) = hmin
where r1 is : 0.0000000000000D+00 and r2 : 0.0000000000000D+00
Repeated convergence failures (perhaps bad jacobian supplied or wrong choice of jacobian type or tolerances).
at line 6 of function optimbase_checkstatus ( C:\Program Files\scilab-6.0.0\modules\optimization\macros\optimbase\optimbase_checkcostfun.sci line 121 )
at line 14 of function optimbase_checkcostfun ( C:\Program Files\scilab-6.0.0\modules\optimization\macros\optimbase\optimbase_checkcostfun.sci line 33 )
at line 7 of function neldermead_startup ( C:\Program Files\scilab-6.0.0\modules\optimization\macros\neldermead\neldermead_search.sci line 951 )
at line 23 of function neldermead_search ( C:\Program Files\scilab-6.0.0\modules\optimization\macros\neldermead\neldermead_search.sci line 65 )
at line 129 of executed file C:\Users\wensrl\Documents\SciLab\Reference Documentation\pidOptimizer.sce
optimbase_checkcostfun: Cannot evaluate cost function with "[f,index]=costf(x0,1)": ode: lsode exit with state -5.
This errors occurs when the csim function is executed.
I searched for changes to the csim() function between versions 5.5.2 and 6.0.0 and did not find any. Is there a solution that I am missing here?
function [J, index] = costf(x0, index)
global J C oL cL itae OS Ms y u t wgts iteration cost
[lhs, rhs] = argn(0)
if rhs < 1 then
error("x0 is required")
end
kc = x0(1);
ti = x0(2);
td = x0(3);
alpha = x0(4);
// stdDeltaV PID formula
pidFormula = kc * (1 + (1/(ti * %s)) + ...
((td * %s)/(alpha * td * %s + 1)))
// pidFormula = pidCTRL(1, pidParam)
C = syslin('c', pidFormula)
oL = Pd * C
cL = oL /. 1
[y] = csim(u', t, cL)
for i = 1:totalTelements
e(i) = abs(y(i) - u(i)) * dt
end
itae = sum(e)
OS = max(y) - 1
[Se, Re, Te] = sensi(Pd, C);
Ms = norm (Se, %inf);
J = wgts(1) * itae + wgts(2) * OS + wgts(3) * Ms;
endfunction
Related
I'm making value function iteration code for economics study, using python and numba package.
Here's simple description of my problem:
I want to solve maximization problem using brent_max,(similar to scipy.optimization) for kp, given k, v while it converges.
kp is 'next state of k', and it is used for upper bound of maximization problem. so after brent_max calculate the value of kp, I want to save and use it again. That's why I used global option.
Here's my code for the problem and error message.
opt_growth_data = [('α', float64),
('β', float64),
('γ', float64),
('δ', float64),
('grid', float64[:])]
#jitclass(opt_growth_data)
class OptimalGrowth_VI:
def __init__(self, α=0.4, β=0.96, γ=2.0, δ=0.1, grid_max=10, grid_size=500):
self.α, self.β, self.γ, self.δ = α, β, γ, δ
self.grid = np.linspace(0.1, grid_max, grid_size)
def f(self, k):
return k**self.α
def u(self, c):
return c**(1-self.γ) / (1-self.γ)
def objective(self, k, kp, v_array):
f, u, β, δ = self.f, self.u, self.β, self.δ
v = lambda x: interp(self.grid, v_array, x)
return u(f(k) + (1-δ)*k -kp) + β*v(kp)
#njit
def T(v, og_VI):
k0 = og_VI.grid
v_greedy = np.empty_like(v)
v_new = np.empty_like(v)
f, δ = og_VI.f, og_VI.δ
for i in range(len(og_VI.grid)):
if i == 1:
k = k0[i]
else:
k = kp[i]
lower = 1e-10
upper = f(k) + (1-δ)*k
result = brent_max(og_VI.objective, lower, upper, args=(k,v))
v_greedy, v_new = result[0], result[1]
return v_greedy, v_new
def solve_model_VI(og_VI, tol=1e-4, max_iter=1000, print_skip=20):
v = og_VI.grid
i = 0
error = tol + 1
while i < max_iter and error > tol:
v_greedy, v_new = T(v, og_VI)
error = np.max(np.abs(v - v_new))
i += 1
if i % print_skip == 0:
print(f"Error at iteration {i} is {error}.")
global kp
kp = v_greedy
v = v_new
if i == max_iter:
print("Failed to converge!")
if i < max_iter:
print(f"\nConverged in {i} iterations.")
return v_greedy, v_new
og_VI = OptimalGrowth_VI()
k_opt_VI, k_solution = solve_model_VI(og_VI)
TypingError Traceback (most recent call last)
Input In [51], in <module>
1 og_VI = OptimalGrowth_VI()
----> 2 k_opt_VI, k_solution = solve_model_VI(og_VI)
Input In [49], in solve_model_VI(og_VI, tol, max_iter, print_skip)
4 error = tol + 1
6 while i < max_iter and error > tol:
----> 7 v_greedy, v_new = T(v, og_VI)
8 error = np.max(np.abs(v - v_new))
9 i += 1
TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Cannot unify array(float64, 1d, C) and float64 for 'v_new.2', defined at /var/folders/yl/t420gknx17d8ppt9jgws8v700000gn/T/ipykernel_19631/2325054440.py (21)
File "../../../../../var/folders/yl/t420gknx17d8ppt9jgws8v700000gn/T/ipykernel_19631/2325054440.py", line 21:
<source missing, REPL/exec in use?>
During: typing of assignment at /var/folders/yl/t420gknx17d8ppt9jgws8v700000gn/T/ipykernel_19631/2325054440.py (21)
File "../../../../../var/folders/yl/t420gknx17d8ppt9jgws8v700000gn/T/ipykernel_19631/2325054440.py", line 21:
<source missing, REPL/exec in use?>
I don't know what is incorrect in my code. Is it related to numba, or do I made completely incorrect code?
It's related to economic problem, so I made a question to economics stack exchange but could not get an answer. I would be very grateful if you could help even if it bothers you.
I refer to
https://python.quantecon.org/optgrowth.html and
https://python.quantecon.org/optgrowth_fast.html
. thank you for your help.
If a run a program written in julia as
sachin#localhost:$ julia mettis.jl then it runs sucessfully, without printing anything, though one print statement is in it.
And Secondly If run it as by going in julia:
sachin#localhost:$ julia
julia> include("mettis.jl")
main (generic function with 1 method)`
julia> main()
Then It gives some error.
I am puzzled why two style of executing is giving different result ?
Here is my code:
using ITensors
using Printf
function ITensors.op(::OpName"expτSS", ::SiteType"S=1/2", s1::Index, s2::Index; τ)
h =
1 / 2 * op("S+", s1) * op("S-", s2) +
1 / 2 * op("S-", s1) * op("S+", s2) +
op("Sz", s1) * op("Sz", s2)
return exp(τ * h)
end
function main(; N=10, cutoff=1E-8, δτ=0.1, beta_max=2.0)
# Make an array of 'site' indices
s = siteinds("S=1/2", N; conserve_qns=true)
# #show s
# Make gates (1,2),(2,3),(3,4),...
gates = ops([("expτSS", (n, n + 1), (τ=-δτ / 2,)) for n in 1:(N - 1)], s)
# Include gates in reverse order to complete Trotter formula
append!(gates, reverse(gates))
# Initial state is infinite-temperature mixed state
rho = MPO(s, "Id") ./ √2
#show inner(rho, H)
# Make H for measuring the energy
terms = OpSum()
for j in 1:(N - 1)
terms += 1 / 2, "S+", j, "S-", j + 1
terms += 1 / 2, "S-", j, "S+", j + 1
terms += "Sz", j, "Sz", j + 1
end
H = MPO(terms, s)
# Do the time evolution by applying the gates
# for Nsteps steps
for β in 0:δτ:beta_max
energy = inner(rho, H)
#printf("β = %.2f energy = %.8f\n", β, energy)
rho = apply(gates, rho; cutoff)main
rho = rho / tr(rho)
end
# #show energy
return nothing
end
There is nothing special about a function called main in Julia and defining a function is different from calling it. Consequently a file mettis.jl with the following code:
function main()
println("Hello, World!")
end
will not "do" anything when run (julia mettis.jl). However if you actually call the function at the end:
function main()
println("Hello, World!")
end
main()
you get the expected result
$ julia mettis.jl
Hello, World!
I want to model a thermodynamic system.
This is what I have tried:
model IdealGas
// Natural Constants
parameter Real R(unit="J/molK") = 8.31446261815324 "Gas Constant J/molK";
// Values of Air used
parameter Real f = 5 "Degrees of Freedom";
parameter Modelica.Units.SI.MolarMass MG = 28.949e-3 "kg/mol";
// Variables
Modelica.Units.SI.Temperature T(start=273.15) "Temperature (K)";
Modelica.Units.SI.AbsolutePressure p(start=1.015e5) "Absolut Pressure (Pa)";
Modelica.Units.SI.SpecificEnthalpy u "spezific energy (J/mol)";
Modelica.Units.SI.SpecificEnthalpy h "spezific Enthalpy (J/mol)";
Modelica.Units.SI.Density rho "Density (kg/m3)";
Modelica.Units.SI.Concentration c "mol/m3";
equation
rho = MG * p / (R * T);
c = p / (R * T);
u = 0.5 * f * R * T;
h = u + R * T;
end IdealGas;
model OpenGasVolume
import Modelica.Units.SI;
parameter SI.Temperature T0=273.15+55 "Start Temperature (K)";
parameter SI.Pressure p0=5e5 "Start pressure (Pa)";
parameter SI.Volume V=1 "Volume (m3)";
SI.Mass m(min = 0.0, start = 1) "Mass in Volume (kg)";
SI.Energy H(min = 0.0) "Enthalpie in Volume (J)";
IdealGas media;
initial equation
media.T = T0;
media.p = p0;
H = media.h * media.c * V; // <--- Somehow this initialization does not work as i intend
equation
H = media.h * media.c * V;
media.rho = m / V;
der(m) = 0; // No Mass transfer
der(H) = 0; // No energy transfer
end OpenGasVolume;
Somehow I do not get the initialization right.
It is mandatory that 'H' is set to a proper start value in 'OpenGasVolume'. Part of the equations are captured in the Model 'media'.
My desired result would be media.T == T0 and media.p=p0 over the whole simulation time.
However I get:
Code:
Simulation process failed. Exited with code 255.
Matrix singular!
The initialization problem is inconsistent due to the following equation: 0 != 55 = T0 - media.T
Error in initialization. Storing results and exiting.
Use -lv=LOG_INIT -w for more information.
How to init the model correctly?
Thanks, Bernd
I could solve it. Now I understand the meaning of `fixed=true'.
Solution is:
model OpenGasVolume
import Modelica.Units.SI;
parameter SI.Temperature T0=273.15+55 "Start Temperature (K)";
parameter SI.Pressure p0=5e5 "Start pressure (Pa)";
parameter SI.Volume V=1 "Volume (m3)";
SI.Mass m(min = 0.0, start = 1) "Mass in Volume (kg)";
SI.Energy H(min = 0.0) "Enthalpie in Volume (J)";
IdealGas media(T(start = T0, fixed=true), p(start=p0, fixed=true)); <<<=== Correction done here.
initial equation
H = media.h * media.c * V;
does not work as i intend
equation
H = media.h * media.c * V;
media.rho = m / V;
der(m) = 0; // No Mass transfer
der(H) = 0; // No energy transfer
end OpenGasVolume;
I'm trying to emulate a system of ODEs (Fig3 B in Tilman, 1994.Ecology, Vol.75,No1,pp-2-16) but Julia Integration method failed to give a solution.
The error is dt <= dtmin. Aborting.
using DifferentialEquations
TFour = #ode_def TilmanFour begin
dp1 = c1*p1*(1-p1) - m*p1
dp2 = c2*p2*(1-p1-p2) -m*p2 -c1*p1*p2
dp3 = c3*p3*(1-p1-p2-p3) -m*p3 -c1*p1*p2 -c2*p2*p3
dp4 = c4*p4*(1-p1-p2-p3-p4) -m*p4 -c1*p1*p2 -c2*p2*p3 -c3*p3*p4
end c1 c2 c3 c4 m
u0 = [0.05,0.05,0.05,0.05]
p = (0.333,3.700,41.150,457.200,0.100)
tspan = (0.0,300.0)
prob = ODEProblem(TFour,u0,tspan,p)
sol = solve(prob,alg_hints=[:stiff])
I think that you read the equations wrong. The last term in the paper is
sum(c[j]*p[j]*p[i] for j<i)
Note that every term in the equation for dp[i] has a factor p[i].
Thus your equations should read
dp1 = p1 * (c1*(1-p1) - m)
dp2 = p2 * (c2*(1-p1-p2) - m - c1*p1)
dp3 = p3 * (c3*(1-p1-p2-p3) - m - c1*p1 -c2*p2)
dp4 = p4 * (c4*(1-p1-p2-p3-p4) - m - c1*p1 - c2*p2 - c3*p3)
where I also made explicit that dpk is a multiple of pk. This is necessary as it ensures that the dynamic stays in the octand of positive variables.
Using python the plot looks like in the paper
def p_ode(p,c,m):
return [ p[i]*(c[i]*(1-sum(p[j] for j in range(i+1))) - m[i] - sum(c[j]*p[j] for j in range(i))) for i in range(len(p)) ]
c = [0.333,3.700,41.150,457.200]; m=4*[0.100]
u0 = [0.05,0.05,0.05,0.05]
t = np.linspace(0,60,601)
p = odeint(lambda u,t: p_ode(u,c,m), u0, t)
for k in range(4): plt.plot(t,p[:,k], label='$p_%d$'%(k+1));
plt.grid(); plt.legend(); plt.show()
in Scilab v5.5.2 this code executes without issue.
In Scilab v6.0.0 or higher I get the following error,
lsode-- at t (=r1), mxstep (=i1) steps
necessary before reaching tout
where i1 is : 500
where r1 is : 0.1202764106130D-05
Excessive work done on this call (perhaps wrong jacobian type).
at line 159 of function csim ( C:\Program Files\scilab-6.0.1\modules\cacsd\macros\csim.sci line 170 )
at line 39 of executed file C:\Users\wensrl\Documents\SciLab\Control\optTest2.sce
ode: lsode exit with state -1.
Here is the code,
clear
clc
t = linspace(1, 520, 5200)
for i = 1:5200
if (i > 15) then
if (i < (5200 / 2)) then
u(i) = 1;
else
u(i) = 0;
end
else
u(i) = 0;
end
end
P = syslin('c', 0.72, 1 + 11 * %s);
n = 4 // order of the delay function
delay = 1 / (( 1 + ((%s * 3) / n)) ^n); // make into a function
Pd = P * delay;
x0=[7.1373457 6.6467066 1.0393701 0.125];
kc = x0(1);
ki = x0(2);
kd = x0(3);
alpha = x0(4);
// stdDeltaV PID formula
pidFormula = kc * (1 + (1/(ki * %s)) + ...
((kd * %s)/(alpha * kd * %s + 1)));
C = syslin('c', pidFormula);
oL = Pd * C;
cL = oL /. 1;
[y] = csim(u', t, cL)
For me it works similarily with scilab-5.5.2and scilab-6.0.1.
But note that ode solvers are supposed to get continuous systems. Here your input is discontinuous, so the solver has difficulties to integrate it and the result may be wrong.
In fact you should make 3 successives integrations for each continuous part
[y1,x1]=csim(u(1:15)',t(1:15),cL);
[y2,x2]=csim(u(15:2599)',t(15:2599)-t(15),cL,x1(:,$));
[y3,x3]=csim(u(2599:$)',t(2599:$)-t(2599),cL,x2(:,$));
clf(),plot([t(1:15) t(15:2599) t(2599:$)],[y1 y2 y3])