Octave function variable undefined - octave

This Octave code says that 'y' is undefined
However, if I use a short anonymous function, it will be good.
What is the reason?
function fun= f(t,y)
myu=398600.4418E+9;
J2=1.08262668E-3;
req=6378137;
r2=(y(1)**2 + y(2)**2 + y(3)**2);
r3=r2**(3/2);
w=1+1.5*J2*(req*req/r2)*(1-5*y(2)*y(2)/r2);
fun=[y(4),y(5),y(6),-myu*y(1)*w/r3,-myu*y(2)*w/r3,-myu*y(3)*w/r3];
endfunction
t0=86400*2.3567000000000000E+04;
tN= 86400*2.3567250000000000E+04;
t = linspace(t0,tN);
y0 = [-9.0656779992979474E+05, -4.8397431127596954E+06, -5.0408120071376814E+06, -7.6805804020022015E+02, 5.4710987127502622E+03, -5.1022193482389539E+03];
x = ode23s (f, t, y0 );
disp(x);

Related

Octave, The secant method

I am trying to implement the secant method using Octave, and in particular I made a function called secant("function","x0","x1","tolerance"). I used the while-loop for calculate the root of a function and I think the problem is in the loop.
But the result that I get, it is not what I expect. The correct answer is x=0,49438.
My code is the following:
tol = 10.^(-5); # tolerance
x0 = 0.4; # initial point
x1 = 0.6; # initial point
syms x;
fun = #(x) exp(sin(x)) - 2/(1+x.^2); # f(x) = exp(sin(x)) - 2/(1+x^2)
fprintf("Function f(x)\n");
fun
fprintf("\n");
fprintf("initial points: %f\n",x0,x1);
function[raiz,errel,niter] = secant(fun,x0,x1,tol)
niter = 0; # steps number
errel = []; # the vector of relative errors
y0 = fun(x0); # f(x0)
y1 = fun(x1); # f(x1)
ra = 0.0; # ra is the variable of the function's root
while abs(ra-x1)>= tol
niter += 1;
ra = x1 - ((x1-x0)./(y1-y0)).*y0; # formula of the secant method
if abs((ra-x1))<tol
raiz = ra;
return;
endif
x0 = x1; y0 = y1; x1 = ra;
y1 = fun(ra);
errel(niter) = abs(ra-x1)/abs(ra); # Calcule of relative error
endwhile
if abs((ra-x1)/ra)<tol
fprintf ('The method is over\n');
fprintf ('\n');
endif
raiz = ra;
endfunction
[r,er,tot] = secant(fun,x0,x1,tol)
I appreciate the help you can give me
It makes little sense to use the secant root in the loop condition. At first it is not defined, and inside the loop it is shifted into the support points for the next secant. Note that at the end ra and x1 contain the same value, making the loop condition trivial, in a wrong way.
Next, the secant has the equation
y(x) = y1 + (y1-y0)/(x1-x0)*(x-x_1)
check that with this formula y(x0)=y0 and y(x1)=y1. Thus the secant root is to be found at
x = x1 - (x1-x0)/(y1-y0)*y1
Finally, at no point are symbolic expressions used, defining x as symbolic variable is superfluous.
The break-out test inside the loop is also redundant and prevents a coherent state after the loop. Just remove it and remember that x1 contains the last approximation.
With all this I get an execution log as follows:
Function f(x)
fun =
#(x) exp (sin (x)) - 2 / (1 + x .^ 2)
initial points: 0.400000
initial points: 0.600000
The method is over
r = 0.494379048216965
er =
2.182723270633349e-01 3.747373180587413e-03 5.220701832080676e-05 1.899377363987941e-08
tot = 4

How to fix: "anonymous function bodies must be single expressions" error on Octave

I am trying to make a function in Octave where you give octave a function f(x,y) as a string, a change in X, a change in Y, a starting point, and the size of a matrix, the function will create a matrix populated with the values of f(x,y) at each point in the matrix.
This is for an application that displays a 3d graph, using the matrix to map each value to a block
# funcStr: The function whose Z values are being calculated
# dx: the change in x that each block in the x direction represents
# dy: the change in y that each block in the y direction represents
# startPt: the point (in an array of x, y) that center block represents
# res: the side length (in blocks) of the plane
pkg load symbolic
syms x y
function[zValues] = calculateZValues(funcStr, dx, dy, startPt, res)
zValues = zeros(res);
eqn = #(x, y) inline(funcStr);
startX = startPt{1};
startY = startPt{2};
for yOffset = 1:res
for xOffset = 1:res
xCoord = startX + dx * xOffset;
yCoord = startY + dy * yOffset;
zValues(res * yOffset + xOffset) = double(subs(eqn, #(x, y), {xCoord, yCoord}));
endfor
endfor
endfunction
The error I am getting is:
>> calculateZValues("x*y", 1, 1, {0,0}, 10)
parse error near line 20 of file /home/rahul/Documents/3dGraph/graph/calculateZValues.m
anonymous function bodies must be single expressions
>>> zValues(res * yOffset + xOffset) = double(subs(eqn, #(x, y), {xCoord, yCoord}));
I have no idea what the issue is. I have replaced the #(x,y) part with {x,y} in the line referenced by the error but it says nothing or it raises an error about the function subs not being declared. I have also tried moving the pkg and syms lines above the function header

Pass external variable to function to sove with lsode in octave

I have a function that I want to solve with lsode, like that:
function f = fcn(x,t)
% Set spring stiffness and mass
k = 500;
m = 5;
% Assign function
f1 = x(2);
f2 = -(k/m)*x(1);
f = [f1; f2];
endfunction
And this is the script that call this function:
% Initial value
x0 = [0.2, 0];
%time
t = linspace(0,1,500);
[X] = lsode (#fcn, x0, t);
plot(t,X(:,1));
Now, I want to loop this script, but every time I want a different value of "k". The function to be solved with lsode must accept only "x" and "t" as argument, then I can't put "k" on the argument-list.
I can't use an anonymous function, because the real function that I'm studying is more complicated (not just a linear oscillator).

How to pass variadic arguments in Octave

I would like to implement a function duration = timer(n, f, arguments_of_f) that would measure how much time does a method f with arguments arguments_of_f need to run n times. My attempt was the following:
function duration = timer(n, f, arguments_of_f)
duration = 0;
for i=1:n
t0 = cputime;
f(arguments_of_f);
t1 = cputime;
duration += t1 - t0;
end
In another file, I have
function y = f(x)
y = x + 1;
end
The call d1 = timer(100, #f, 3); works as expected.
In another file, I have
function y = g(x1, x2)
y = x1 + x2;
end
but the call d2 = timer(100, #g, 1, 2); gives an error about undefined
argument x2, which is, when I look back, somehow expected, since I pass only
1 to g and 2 is never used.
So, how to implement the function timer in Octave, so that the call like
timer(4, #g, x1, ... , xK) would work? How can one pack the xs together?
So, I am looking for the analogue of Pythons *args trick:
def use_f(f, *args):
f(*args)
works if we define def f(x, y): return x + y and call use_f(f, 3, 4).
You don't need to pack all the arguments together, you just need to tell Octave that there is more than one argument coming and that they are all necessary. This is very easy to do using variadic arguments.
Your original implementation is nearly spot on: the necessary change is minimal. You need to change the variable arguments_to_f to the special name varargin, which is a magical cell array containing all your arbitrary undeclared arguments, and pass it with expansion instead of directly:
function duration = timer(n, f, varargin)
duration = 0;
for i=1:n
t0 = cputime;
f(varargin{:});
t1 = cputime;
duration += t1 - t0;
end
That's it. None of the other functions need to change.

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.