Program (programmatically implement) the problem of solving the rigid equation eq = -lambda * (y-sin (x)) using the ode45 solver in the Octave environment.
There is code
lambda=10#Global variable for function
function slv=fi(x)#Equation solution
C=1+(lambda/(1+pow2(lambda)));
slv=C*exp(-lambda*x)-(lambda/(1+pow2(lambda)))*(-lambda*sin(x)+cos(x));
end
#The initial function of the equation
function y=g(t,x)
y=-lambda*(x-sin(t));–1 ERROR
end
%Determination of parameters for controlling the course of the equation
optio=odeset("RelTol",1e-5,"AbsTol",1e-5,'InitialStep',0.025,'MaxStep',0.1);
[XX,YY]=ode45(#g,[0 0.25],2,optio); - 2 ERROR
#Exact solution
x1=0:0.05:0.25;
y1=fi(x1);
%Function solution graph with ode45 and exact solution
plot(x1,y1,'-g:exact solution;',XX,YY,'*b;ode45;');
grid on;
But there are some errors:
lambda = 10
error: 'lambda' undefined near line 11, column 11
error: called from
g at line 11 column 4
runge_kutta_45_dorpri at line 103 column 12
integrate_adaptive at line 135 column 39
ode45 at line 241 column 12
LabWork6 at line 18 column 8
Due to the lambda variable in the function, the error moved to another part of the program.
What did I do wrong when declaring a lambda?
Variables at 'global' scope in a script are not visible from within functions, even if defined on the command-line instead of their own file, as it the proper way.
This makes sense if you think about it, because command-line functions are just convenience syntax, and a file-defined function would have no idea that some other script defines a variable somewhere, unless you use the global keyword to tell it about that variable.
So either declare lambda as global both outside and inside your function, or simply wrap your entire script inside a function, which then allows 'nested' functions to see/inherit parent-function variables.
Related
I want to extract data from a table called cond. As you can see from line 75 in the screenshot shown below, data Diameter corresponding to Drake can be successfully extracted using cond('Drake',:).Diameter.
screenshot
However, when I was trying to write this into a function called findCF(), things went wrong at line 78 with an error message
Invalid syntax for calling function 'cond' on the path. Use a valid
syntax or explicitly initialize 'cond' to make it a variable.
Can anybody tell me how to modify my code?
cond() is the name of a built-in function. Matlab tolerates variables whose names collide with functions, but it can result in weird things like this. In the line that produces the error, Matlab thinks you are trying to call the function cond(), not access the variable cond.
Rename the variable to something else.
So I have been trying to adapt my python codes to Julia instead of fortran mainly because of the fact I have Jupiter to easily test my work on the fly. But in Julia 1, I am unable to find any easy way to redefine a already defined function in another cell to test it out.
For instance
function a(b);return b+4;end
and then in next cell I would like to test instead loose the condition and have it something like
function a(b,c);return b+c;end
But I do not want to change the name because I have other dependent functions in which I call a. The reason to do this is for prototyping the best possible way to define a and obviously this wouldn't be a part of the main code.
Any way how to do this ?
Julia uses multiple dispatch and these are two different functions (or more exactly two different methods of the same function). Hence, no change of name is needed.
julia> function a(b);return b+4;end
a (generic function with 1 method)
julia> function a(b,c);return b+c;end
a (generic function with 2 methods)
julia> methods(a)
# 2 methods for generic function "a":
[1] a(b) in Main at REPL[1]:1
[2] a(b, c) in Main at REPL[2]:1
Basically, rerunning a Jupyter cell will redefine the function (if it is the same set of parameter types) so there is no problem here.
More complicated situation is when you want to change a type of a constants because they go deeper into compiler. Constants cannot change their type.
Functions are constants. Hence, if you try to assign a non-function type it will trow an error.
julia> typeof(a) <: Function
true
julia> a = 5
ERROR: invalid redefinition of constant a
Stacktrace:
[1] top-level scope at REPL[9]:1
I have a function where I want to solve for many variables separately, do I have to write down the function every time in terms of the other variable?
x,xG,xR
y = e.^tan(x.^2)+cos.^2(x);
yG = e.^tan(xG.^2)+cos.^2(xG);
First you cannot write an expression like cos.^2(x). If x is a single variable (ie x=pi) you could write either cos(x)^2 or cos(x^2). If x is a vector (a column vector might be x=[3;4;pi] and a row vector might be x=[3,4,pi], then you might write cos(x).^2 or cos(x.^2). The role of the period (.) in octave is explained here: https://octave.org/doc/v4.0.3/Arithmetic-Ops.html
Another issue has to do with understanding the difference between an expression: x=e^tanh(y); and a function. The later is a separate chunk of code that can be invoked from anywhere in your program.
Consider this simple example
1;
function y=myfunc(x)
y=exp(tanh(x));
endfunction
## main program
xxx=pi/3;
yyy=myfunc(xxx);
printf('%7.3f %7.3f\n',xxx,yyy)
y=exp(tanh(pi/3))
comments: The '1' in the first line tells Octave that there is more to the script than just the following function: the main program has to be interpreted as well. The function line specifies that inside the function, the input will be called x and the output y, so when my function is called from main, the input is xxx(=pi/2) and the output is yyy. The last line in this tiny script is an expression that does the same thing as the function. Note that since I didn't include a semi-colon at the end of that line the result is printed out
I suggest you play with this for a while, then if you have more questions, ask them in a new question.
I'm working with Octave4.2.1 and I have written this function (in the file OctaveFunction.m):
function y = squareNumber(x)
y = x^2;
endfunction
but if I call the function, I get this error:
error: 'squareNumber' undefined near line 1 column 1
and if I try to call the function in this way:
OctaveFunction squareNumber(4)
I get another error:
warning: function name 'squareNumber' does not agree with function filename 'C:\Users\HOME\Desktop\OctaveFunction.m'
error: for x^A, A must be a square matrix. Use .^ for elementwise power.
error: called from
OctaveFunction at line 2 column 7
Where did I go wrong? Thank you!
I think the main problem is that your file name does not match the function name. If you were to match these, this should resolve your first error.
Regarding the elementwise power error: If given the proper input (4) this should not lead to an error, as 4 is obviously a square matrix.
Hence it seems that some undesired input is fed to your function, but again this problem is likely to disappear if you rename the file to match the functionname, and call the function as usual. (so without OctaveFunction).
You Must rename your file such as your function name
for example: your file name is (main.m) and your function name is (main)
If I open Octave and do:
a = 1:10;
sum(a)
ans = 55
But if I then do:
sum = 30;
sum(a)
I get an error:
error: A(I): index out of bounds; value 10 out of bound 1
Octave has allowed me to change where the word "sum" points so now it's at a value not a function. Why is this allowed and shouldn't I be given a warning - is this not incredibly dangerous?
How, if I realise I've done this, do I remove the reference without closing octave and losing my workspace?
Imagine Octave does not allow variables to have the same as a function. You write a program in Octave and you have a variable named total which is not a function. Everything is fine. A new Octave version comes out and adds a function named total. Your program would stop working and you would have to rename your variables. That level of backwards incompatibility would be worse. And the issue wouldn't be limited to new Octave versions. Maybe you later decide that you want to use an Octave package which brings a whole set of new functions, one of which could clash with your variables.
However, in the upcoming release of Octave, out of bounds errors will give a hint that the variable name is shadowing a function. In Octave 4.2.1:
octave-cli-4.2.0:1> a = 1:10;
octave-cli-4.2.0:2> sum = 30;
octave-cli-4.2.0:3> sum (a)
error: sum(10): out of bound 1
While in in 4.3.0+ (which one day will become 4.4):
octave-cli-4.3.0+:1> a = 1:10;
octave-cli-4.3.0+:2> sum = 30;
octave-cli-4.3.0+:3> sum(a)
error: sum(10): out of bound 1 (note: variable 'sum' shadows function)
However, the real problem is not that variables can shadow functions. The real problem is that the syntax does not allow to distinguish between a variable and a function. Both variable indexing and function calling uses the same brackets () (other languages typically use () for functions and [] for index variables). And even if you call a function without any arguments, the parentheses are optional:
foo(1) # 1st element of foo? Or is foo a function?
foo # Is this a variable or a function call without any arguments?
foo() # idem
This syntax is mainly required for Matlab compatibility which is one of the aims of GNU Octave.
To work around this deficiency, Octave coding guidelines (guidelines required for code contributed to Octave. The Octave parser does not really care) requires functions to always use parentheses and to have a space between them and the function name:
foo (x, y); # there is a space after foo so it must be a function
foo(x, y); # there is no space, it is indexing a matrix
foo # this is a variable
foo (); # this is a function
How, if I realise I've done this, do I remove the reference without closing octave and losing my workspace?
Use the command clear sum to clear the user definition of symbol sum, which will revert it to the built-in meaning. (That is, the built-in definition will no longer be shadowed by user definition.)
As for why Octave works this way, one would have to ask the maintainers of this open-source project. Perhaps it's because Matlab works this way, and Octave strives to be as compatible as possible.