How to refresh Octave's knowledge of class methods? - octave

I have defined an MCV example class in Octave called myobj. Its constructor is located in the relative path #myobj/myobj.m:
function c = myobj(arg = "hi")
s.arg = arg;
c = class(s, "myobj");
end
When I run octave-cli and construct an instance of this class, Octave doesn't know how to describe/print it:
octave:1> o = myobj()
o = <class myobj>
I am aware of using the display class method to allow this. Now I have added the file #myobj/display.m with the contents:
function display(obj)
printf("%s = <arg = \"%s\">\n", inputname(1), obj.arg);
end
But Octave does not find this new class function. After doing some research, some said that running the command rehash or clear all would cause Octave to find the new function, but they don't:
octave:2> o = myobj()
o = <class myobj>
octave:3> rehash
octave:4> o = myobj()
o = <class myobj>
octave:5> clear all
octave:6> o = myobj()
o = <class myobj>
octave:7> clear -a
octave:8> o = myobj()
o = <class myobj>
octave:9> clear -a *
octave:10> o = myobj()
o = <class myobj>
octave:11> clear -c *
octave:12> o = myobj()
o = <class myobj>
Restarting Octave does solve this:
octave:1> o = myobj()
o = <arg = "hi">
The problem occurs again when this function is removed without restarting Octave:
octave:2> o = myobj()
error: no such file, '/tmp/tmp.6ms6lw2GW0/#myobj/display.m'
octave:2> rehash
octave:3> o = myobj()
error: no such file, '/tmp/tmp.6ms6lw2GW0/#myobj/display.m'
octave:3> clear all
octave:4> o = myobj()
error: no such file, '/tmp/tmp.6ms6lw2GW0/#myobj/display.m'
octave:4> clear all *
octave:5> o = myobj()
error: no such file, '/tmp/tmp.6ms6lw2GW0/#myobj/display.m'
octave:5> clear -a
octave:6> o = myobj()
error: no such file, '/tmp/tmp.6ms6lw2GW0/#myobj/display.m'
octave:6> clear -a *
octave:7> o = myobj()
error: no such file, '/tmp/tmp.6ms6lw2GW0/#myobj/display.m'
octave:7> clear -c *
octave:8> o = myobj()
error: no such file, '/tmp/tmp.6ms6lw2GW0/#myobj/display.m'
octave:9> clear display
octave:10> o = myobj()
error: no such file, '/tmp/tmp.6ms6lw2GW0/#myobj/display.m'
Does anyone know of a command that I can run to cause Octave to become aware of these function changes? This isn't too bad with the CLI of course, but I do like to use the GUI, and restarting it can be tiresome.
Note: I am using v4.2.1, configured for "x86_64-redhat-linux-gnu".
EDIT: I am able to reproduce this on Windows 10 with v4.2.2, configured for "x86_64-w64-mingw32".

I landed on this question when searching for an answer to the same problem. In reality, the latest versions of Octave have this bug fixed already.
The easiest way to activate your edits to the class methods is to use the command clear functions and then create a new object of that class. Any old objects of that class will continue using the old methods.

Related

Plotting function with respect to a keyword argument leads to error in Julia

I have a function which involves bunch of integrals and complicated computations, like the following:
using HCubature
function func(v, x0, y0; rad=1.)
L = hcubature(r->r[1]*v(x0+r[1]*cos(r[2]), y0+r[1]*sin(r[2])), [0., π/2], [rad, π])[1]
R = hcubature(r->r[1]*v(x0+r[1]*cos(r[2]), y0+r[1]*sin(r[2])), [0., 0], [rad, π/2])[1]
return L, R
end
The argument v is a function itself.
When I try to plot the function with respect to the keyword argument rad, I obtain error messages as follows:
x0_, y0_ = 0, 0
rad_ = 0.:0.1:9.
func_array_L = [func(v, x0_, y0_; rad = radius)[1] for radius in rad_]
func_array_R = [func(v, x0_, y0_; rad = radius)[2] for radius in rad_]
plot(rad_, func_array_L)
plot!(rad_, func_array_R)
The error message includes a very long error message: Internal error: encountered unexpected error in runtime: then followed by a long list of directories, and then it comes to the following:
MethodError: no method matching string(::Expr)
The applicable method may be too new: running in world age 3820, while current world is 26290.
Closest candidates are:
string(::Any...) at strings/io.jl:168 (method too new to be called from this world context.)
string(!Matched::String) at strings/substring.jl:152 (method too new to be called from this world context.)
string(!Matched::SubString{String}) at strings/substring.jl:153 (method too new to be called from this world context.)
...
I tried also other methods like declaring another function with rad as the only argument, etc. but none of them worked. How to fix the problem?
Indeed the error message is strange, but the reason is simple. You have not defined the function v. You should define it first, and then all should work as expected.
Additionally note that you have a wrong case in using HCubature (note that u should be lowercase). Also in order for plotting to work you should firs import a plotting package e.g. by using Plots.
EDITS
A basic code that reproduces your problem is:
julia> using HCubature
julia> function func(v, x0, y0; rad=1.)
L = hcubature(r->r[1]*v(x0+r[1]*cos(r[2]), y0+r[1]*sin(r[2])), [0., π/2], [rad, π])[1]
R = hcubature(r->r[1]*v(x0+r[1]*cos(r[2]), y0+r[1]*sin(r[2])), [0., 0], [rad, π/2])[1]
return L, R
end
func (generic function with 1 method)
julia> v = (x,y) -> x
#27 (generic function with 1 method)
julia> x0_, y0_ = 0, 0
(0, 0)
julia> rad_ = 0.:0.1:9.
0.0:0.1:9.0
julia> func_array_L = [func(v, x0_, y0_; rad = radius)[1] for radius in rad_]
Internal error: encountered unexpected error in runtime:
MethodError(f=typeof(Base.string)(), args=(Expr(:<:, :t, :r),), world=0x0000000000000eec)
This seems to be a bug. I reported it here.
A workaround
Now - the way to solve it is to make v type stable. There are three example ways to do it.
Option 1: define it as const:
const v1 = v
and use a comprehension with v1 passed instead of v.
Option 2: wrap it in let block:
func_array_L = let v=v
[func(v, x0_, y0_; rad = radius)[1] for radius in rad_]
end
Option 3: define a function with a name using v:
v2(x,y) = v(x,y)
and use a comprehension with v2 passed instead of v.
Alternatively you could also make x0_ or y0_ to be of constant type (it is enough to fix one of them) to make all work. E.g. this
func_array_L = [func(v, 1, y0_; rad = radius) for radius in rad_]
works as expected.
Additional notes
You have a similar problem if you use map instead of a comprehension if in map you use an anonymous function:
map(radius -> func(v, x0_, y0_; rad = radius)[1], rad_)
and also a normal function that has a name produces the same error:
v3(radius) = func(v, x0_, y0_; rad = radius)[1]
map(v3, rad_)
but it starts to work if you make an internal function that is introduced into a method-table:
v3(radius) = (tmp(x...) = v(x...); func(tmp, x0_, y0_; rad = radius)[1])
and now map(v3, rad_) works as expected.

Solving two non-linear equations in Octave

I am trying to solve the following two equations using Octave:
eqn1 = (wp/Cwc)^(2*N) - (1/10^(0.1*Ap))-1 == 0;
eqn2 = (ws/Cwc)^(2*N) - (1/10^(0.1*As))-1 == 0;
I used the following code:
syms Cwc N
eqn1 = (wp/Cwc)^(2*N) - (1/10^(0.1*Ap))-1 == 0;
eqn2 = (ws/Cwc)^(2*N) - (1/10^(0.1*As))-1 == 0;
sol = solve(eqn1 ,eqn2, Cwc, N)
ws,wp,As, and Ap are given as 1.5708, 0.31416, 0.5, 45 respectively.
But I am getting the following error:
error: Python exception: NotImplementedError: could not solve
126491*(pi*(3*10**N*sqrt(314311)*pi**(-N)/1223)**(1/N)/2)**(2*N) - 126495
occurred at line 7 of the Python code block:
d = sp.solve(eqs, *symbols, dict=True)
What should I do to solve this?
Edit:
I modified the equations a little bit.
pkg load symbolic
clear all
syms Cwc N
wp = 0.31416
ws = 1.5708
As = 45
Ap = 0.5
eqn2 = N - log10(((1/(10^(0.05*As)))^2)-1)/2*log10(ws/Cwc) == 0;
eqn1 = N - log10(((1/(10^(0.05*Ap)))^2)-1)/2*log10(wp/Cwc) == 0;
sol = solve(eqn1,eqn2,Cwc,N)
And now I am getting this error:
error: Python exception: AttributeError: MutableDenseMatrix has no attribute is_Relational.
occurred at line 3 of the Python code block:
if arg.is_Relational:
Looking at the equations, with unknowns in the base and exponent of the same term, highly suggests there is no symbolic solution to be found. I gave a simplified system (2/x)^y = 4, (3/x)^y = 5 to a couple of symbolic solvers, neither of which got anything from it. So, the only way to solve this is numerically (which makes sense because the four known parameters you have are some floating point numbers anyway). Octave's numeric solver for this purpose is fsolve. Example of usage:
function y = f(x)
Cwc = x(1);
N = x(2);
ws = 1.5708;
wp = 0.31416;
As = 0.5;
Ap = 45;
y = [(wp/Cwc)^(2*N) - (1/10^(0.1*Ap))-1; (ws/Cwc)^(2*N) - (1/10^(0.1*As))-1];
endfunction
fsolve(#f, [1; 1])
(Here, [1; 1] is an initial guess.) The output is
0.31413
0.19796

Solving system of ODEs using Octave

I am trying to solve a system of two ODEs using Octave, and in particular the function lsode.
The code is the following:
function xdot = f (x,t)
a1=0.00875;
a2=0.075;
b1=7.5;
b2=2.5;
d1=0.0001;
d2=0.0001;
g=4*10^(-8);
K1=5000;
K2=2500;
n=2;
m=2;
xdot = zeros(2,1);
xdot(1) = a1+b1*x(1)^n/(K1^n+x(1)^n)-g*x(1)*x(2)-d1*x(1);
xdot(2) = a2+b2*x(1)^m/(K2^m+x(1)^m)-d2*x(2);
endfunction
t = linspace(0, 5000, 200)';
x0 = [1000; 1000];
x = lsode ("f", x0, t);
set term dumb;
plot(t,x);
I am getting continuously the same error, that "x" is not defined, and I do not know why. The error is the following:
warning: function name 'f' does not agree with function file name '/home /Simulation 1/sim.m'
error: 'x' undefined near line 17 column 17
error: called from
sim at line 17 column 9
It would we great that any of you could help me with this code.
You have two errors. One, you are not saving your source code with the proper name. Two, variable "x" is a vector, and nothing in your script indicates that. You should add a line "x = zeros(1,2);" right after "xdot = zeros(2,1);".
Try the following code:
function ODEs
t = linspace(0, 5000, 200);
x0 = [1000; 1000];
x = lsode (#f, x0, t);
fprintf('t = %e \t\t x = %e\n',t,x);
endfunction
function xdot = f(x,t)
a1=0.00875;
a2=0.075;
b1=7.5;
b2=2.5;
d1=0.0001;
d2=0.0001;
g=4*10^(-8);
K1=5000;
K2=2500;
n=2;
m=2;
xdot = zeros(2,1);
x = zeros(1,2);
xdot(1) = a1+b1*x(1)^n/(K1^n+x(1)^n)-g*x(1)*x(2)-d1*x(1);
xdot(2) = a2+b2*x(1)^m/(K2^m+x(1)^m)-d2*x(2);
endfunction
Save it as ODEs.m and execute it. It does not plot anything, but gives you an output with the results for the t range you supplied.

After one call to myfun, new parametrization does not affect the result, which conforms to the first call

I am new to Octave although I can say I am an expert Matlab user. I am running Octave on a Linux server (Red Hat) remotely through PuTTY, from a windows machine.
I am observing a very strange behavior in Octave. I call myfun(a) which performs as expected giving the sought results. Now, if I run, say, myfun(b) with b!=a, I get again myfun(a). Clear -f does not solve the problem. I need to reboot octave to change the parameters.
What am I doing wrong?
Thanks a lot
Francesco
This is the code for the function I mentioned:
function [a, v, obj, infos, iter] = mle_garch( p )
#{
% this function estimates the GARCH(1,1) parameters
% it is assumed we pass the adjusted price level p
#}
global y = (diff(log(p))-mean(diff(log(p))))*100;
global h = zeros(size(y));
a0 = [var(y)*0.9; 0.8; 0.1];
[a, obj, infos, iter] = sqp(a0, #loglike_garch, [], #loglike_con, [], [], 1000);
v = sqrt(h * 260);
endfunction
function g = loglike_garch( a )
global y h
n = length(y);
h(1) = var(y);
for i = 2 : n,
h(i) = a(1) + a(2) * h(i-1) + a(3) * y(i-1)^2;
endfor
g = 0.5 * ( sum(log(h)) + sum(y.^2./h) ) / n;
endfunction
function f = loglike_con( a )
f = [1;0;0;0] + [0 -1 -1;eye(3)] * a;
endfunction
I'm assuming the myfun you mentioned is mle_garch. The problem is the way you're initializing the global h and v variables (do you really need them to be global?). When you have a piece of code like this
global y = (diff(log(p))-mean(diff(log(p))))*100;
global h = zeros(size(y));
the values of y and h are defined the first time only. You can change their values later on, but this specific lines will never be ran again. Since your code only uses the input argument to define these two variables, the value which you use to run the function the first time will be used every single other time. If you really want to keep those variables global, replace it with the following:
global y;
global h;
y = (diff(log(p))-mean(diff(log(p))))*100;
h = zeros(size(y));
But I don't see any reason to keep them global so just don't make them global.
Also, you mentioned this code worked fine in Matlab. I was under the impression that you couldn't initialize global and persistent variables in Matlab which would make your code illegal in Matlab.

Printing stack traces

I have a very short test file:
let print_backtrace () = try raise Not_found with
Not_found -> Printexc.print_backtrace stdout;;
let f () = print_backtrace (); Printf.printf "this is to make f non-tail-recursive\n";;
f ();
I compile and run:
% ocamlc -g test.ml
% OCAMLRUNPARAM=b ./a.out
Raised at file "test.ml", line 1, characters 35-44
this is to make f non-tail-recursive
Why isn't f listed in the stack trace? How can I write a function that will print a stack trace of the location it's called from?
The documentation for Printexc.print_backtrace says:
The backtrace lists the program locations where the most-recently raised exception was raised and where it was propagated through function calls.
It actually seems to be doing the right thing. The exception hasn't been propagated back through f.
If I move the call to Printexc.print_backtrace outside the call to f, I see a full backtrace.
$ cat test2.ml
let print_backtrace () = raise Not_found
let f () = let res = print_backtrace () in res ;;
try f () with Not_found -> Printexc.print_backtrace stdout
$ /usr/local/ocaml312/bin/ocamlc -g test2.ml
$ OCAMLRUNPARAM=b a.out
Raised at file "test2.ml", line 1, characters 31-40
Called from file "test2.ml", line 3, characters 21-39
Called from file "test2.ml", line 5, characters 4-8
Here is the code to do what I suggested. I recommend using ocamldebug if at all possible, this code is much too tricky. But it works on my system for this simple example.
let print_backtrace () =
match Unix.fork () with
| 0 -> raise Not_found
| pid -> let _ = Unix.waitpid [] pid in ()
let f () =
begin
print_backtrace ();
Printf.printf "after the backtrace\n";
end
;;
f ()
Here is a test run.
$ /usr/local/ocaml312/bin/ocamlc unix.cma -g test3.ml
$ OCAMLRUNPARAM=b a.out
Fatal error: exception Not_found
Raised at file "test3.ml", line 3, characters 17-26
Called from file "test3.ml", line 8, characters 4-22
Called from file "test3.ml", line 14, characters 0-4
after the backtrace
I realized that because of the uncaught exception, you don't really have any control over the way the child process exits. That's one reason this code is much too tricky. Please don't blame me if it doesn't work for you, but I hope it does prove useful.
I tested the code on Mac OS X 10.6.8 using OCaml 3.12.0.
Best regards,