Can I call a function to solve for different variables? - octave
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.
Related
Why does Octave allow renaming of functions?
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.
Julia: Testing function in interactive session
I am not sure if it is possible, but I would like to be able to grab the default argument values of a function and test them and the code within my functions without having to remove the commas (this is especially useful in the case when there are many arguments). In effect, I want to be able to have commas when sending arguments into the function but not have those commas if I copy and paste the arguments and run them by themselves. For example: function foo( x=1, y=2, z=3 ) bar(x,y,z) end Now to test pieces of the function outside of the code block, copy and paste x=1, y=2, z=3 bar(x,y,z) But this gives an error because there is a comma after x=1 Perhaps I am not asking the right question. If this is strange, what is the preferred method for debugging functions?
It isn't pretty but if you define your function like: function foo( (x=1), (y=2), (z=3) ) bar(x,y,z) end then it works as you describe.
'Invalid Handle object' when using a timer inside a function in MatLab
I am using a script in MatLab that works perfectly fine by itself, but I need to make a function out of it. The script read a .csv file, extract all values, start a timer, and at each tick displays the corresponding coordinates extracted from the .csv, resulting in a 3D animation of my graph. What I would like is to give it the location of the .csv, so that it starts displaying the graphs for this csv. Here is what I have come up with: function handFig(fileLoc) csv=csvread(fileLoc,1,0); both = csv(:,2:19); ax=axes; set(ax,'NextPlot','replacechildren'); Dt=0.1; %sampling period in secs k=1; hp1=text(both(k,1),both(k,2),both(k,3),'thumb'); %get handle to dot object hold on; hp2=text(both(k,4),both(k,5),both(k,6),'index'); hp3=text(both(k,7),both(k,8),both(k,9),'middle'); hp4=text(both(k,10),both(k,11),both(k,12),'ring'); hp5=text(both(k,13),both(k,14),both(k,15),'pinky'); hp6=text(both(k,16),both(k,17),both(k,18),'HAND'); L1=plot3([both(k,1),both(k,16)],[both(k,2),both(k,17)],[both(k,3),both(k,18)]); L2=plot3([both(k,4),both(k,16)],[both(k,5),both(k,17)],[both(k,6),both(k,18)]); L3=plot3([both(k,7),both(k,16)],[both(k,8),both(k,17)],[both(k,9),both(k,18)]); L4=plot3([both(k,10),both(k,16)],[both(k,11),both(k,17)],[both(k,12),both(k,18)]); L5=plot3([both(k,13),both(k,16)],[both(k,14),both(k,17)],[both(k,15),both(k,18)]); hold off; t1=timer('TimerFcn','k=doPlot(hp1,hp2,hp3,hp4,hp5,hp6,L1,L2,L3,L4,L5,both,t1,k)','Period', Dt,'ExecutionMode','fixedRate'); start(t1); end And the doplot function used: function k=doPlot(hp1,hp2,hp3,hp4,hp5,hp6,L1,L2,L3,L4,L5,pos,t1,k) k=k+1; if k<5000%length(pos) set(hp1,'pos',[pos(k,1),pos(k,2),pos(k,3)]); axis([0 255 0 255 0 255]); set(hp2,'pos',[pos(k,4),pos(k,5),pos(k,6)]); set(hp3,'pos',[pos(k,7),pos(k,8),pos(k,9)]); set(hp4,'pos',[pos(k,10),pos(k,11),pos(k,12)]); set(hp5,'pos',[pos(k,13),pos(k,14),pos(k,15)]); set(hp6,'pos',[pos(k,16),pos(k,17),pos(k,18)]); set(L1,'XData',[pos(k,1),pos(k,16)],'YData',[pos(k,2),pos(k,17)],'ZData',[pos(k,3),pos(k,18)]); set(L2,'XData',[pos(k,4),pos(k,16)],'YData',[pos(k,5),pos(k,17)],'ZData',[pos(k,6),pos(k,18)]); set(L3,'XData',[pos(k,7),pos(k,16)],'YData',[pos(k,8),pos(k,17)],'ZData',[pos(k,9),pos(k,18)]); set(L4,'XData',[pos(k,10),pos(k,16)],'YData',[pos(k,11),pos(k,17)],'ZData',[pos(k,12),pos(k,18)]); set(L5,'XData',[pos(k,13),pos(k,16)],'YData',[pos(k,14),pos(k,17)],'ZData',[pos(k,15),pos(k,18)]); else k=1; set(hp1,'pos',[pos(k,1),pos(k,2),pos(k,3)]); axis([0 255 0 255 0 255]); set(hp2,'pos',[pos(k,4),pos(k,5),pos(k,6)]); set(hp3,'pos',[pos(k,7),pos(k,8),pos(k,9)]); set(hp4,'pos',[pos(k,10),pos(k,11),pos(k,12)]); set(hp5,'pos',[pos(k,13),pos(k,14),pos(k,15)]); set(hp6,'pos',[pos(k,16),pos(k,17),pos(k,18)]); end However, when I run handFig('fileName.csv'), I obtain the same error everytime: ??? Error while evaluating TimerFcn for timer 'timer-7' Invalid handle object. I figured that it might come from the function trying to create a new 'csv' and 'both' everytime, so I tried removing them, and feeding the function the data directly, without results. What is exactly the problem? Is there a solution? Thanks a lot!
I think it's because when you call doPlot in the timer for the first time, you pass in t1 as an argument, and it might not exist the first time. Does doPlot need t1 at all? I'd suggest modifying it so it's not used, and then your call to: t1=timer('TimerFcn','k=doPlot(hp1,hp2,hp3,hp4,hp5,hp6,L1,L2,L3,L4,L5,both,k)','Period', Dt,'ExecutionMode','fixedRate'); Note the missing t1 in the doPlot call. Either that, or initialise your t1 before you create the timer so it has some value to pass in. Update (as an aside, can you use pause(Dct) in a loop instead? seems easier) Actually, now I think it's a problem of scope. It took a bit of digging to get to this, but looking at the Matlab documentation for function callbacks, it says: When MATLAB evaluates function handles, the same variables are in scope as when the function handle was created. (In contrast, callbacks specified as strings are evaluated in the base workspace.) You currently give your TimerFcn argument as a string, so k=doPlot(...) is evaluated in the base workspace. If you were to go to the matlab prompt, run handFig, and then type h1, you'd get an error because h1 is not available in the global workspace -- it's hidden inside handFig. That's the problem you're running into. However, the workaround is to specify your function as a function handle rather than a string (it says function handles are evaluated in the scope in which they are created, ie within handFig). Function handles to TimerFcn have to have two arguments obj and event (see Creating Callback Functions). Also, that help file says you have to put doPlot in its own m-file to have it not evaluate in the base Matlab workspace. In addition to these two required input arguments, your callback function can accept application-specific arguments. To receive these input arguments, you must use a cell array when specifying the name of the function as the value of a callback property. For more information, see Specifying the Value of Callback Function Properties. It goes through an example of what you have to do to get this working. Something like: % create timer t = timer('Period', Dt,'ExecutionMode','fixedRate'); % attach `k` to t so it can be accessed within doPlot set(t,'UserData',k); % specify TimerFcn and its extra arguments: t.TimerFcn = { #doPlot, hp1, hp2, hp3, ...., both }; start(t) Note -- the reason k is set in UserData is because it needs to be somehow saved and modified between calls to doPlot. Then modify your doPlot to have two arguments at the beginning (which aren't used), and not accept the k argument. To extract k you do get(timer_obj,'UserData') from within doPlot: function k=doPlot(timer_obj, event, hp1,hp2,hp3,.....) k = get(timer_obj,'UserData'); .... % rest of code here. % save back k so it's changed for next time! set(timer_obj,'UserData',k); I think that's on the right track - play around with it. I'd highly recommend the mathworks forums for this sort of thing too, those people are whizzes. This thread from the mathworks forum was what got me started and might prove helpful to you. Good luck!
Matlab/Octave function handlers and nargin
I am writing program in Octave and I encountered a problem, I implemented Gauss-Legandre Quadrature and I pass to my Gauss-Legandre function few arguments, and I pass the function to be intergrated in a cell cube, so I can pass few function at a time. I have this piece of code: for weight=1:length(w) temp=1; for fun=1:length(c) %liczenie iloczynu f(x_i)g(x_i), x_i - pieriwastki wielomianu Legandra f=c{fun}; nargin(func2str(c{fun})) if (nargin (func2str(c{fun})) == 1) disp('a'); temp*=c{fun}((b-a)/2 * x(weight) + (a+b)/2); else (b-a)/2 * x(weight) + (a+b)/2; temp*=f((b-a)/2 * x(weight) + (a+b)/2,I,points); end end %mnozenie wyniku przez odpowiedni wspolczynnik - wage temp*=w(weight); result+=temp; end In cell array there are function handlers to functions which I want to integrate. Depending on number of arguments that function takes i want to use two different calls for function. If in cell array there is handler to a function that is written in .m file in the same directory as my Octave working directory everything works fine, but when i define function in Octave running time, for example: function result=a(x) result=x*x end Type c{1}=#a and pass this cell array to my function Kwadratury there is an error of nargin error: nargin: invalid function error: called from: Why is that and how can I solve it, so I can define function not only in .m files but also in Octave.
I suspect I have a solution, but as this is Octave-specific and I'm mostly used to MATLAB, your mileage may vary. You call the nargin function by supplying a string argument, this means that nargin will have to resolve that function and check the number of arguments. When you declare a function in-line, that function is defined within that scope (i.e. your base scope), so resolving the function name will not work from within any function (or it might resolve to a built-in function, which is even worse behavior). The best solution is to use nargin(c{fun}) instead of nargin(func2str(c{fun})). That way you pass the actual function handle along, and there is no need to resolve the function name to the actual function, and hence no possible ambiguity. In general I recommend against using strings to pass functions: that why function handles are included in MATLAB, so anyone reading your code (or a static code analysis tool) will be able to understand you are working with functions. When using strings, everything becomes ambiguous: does a string 'a' refer to the function a or to the first letter in the alphabet? With regard to using inline functions, I don't know whether Octave supports this, but if you function is quite simple, it's easier to define an anonymous function, such as your example, by a = #(x)(x*x);. That is a construct that is supported by MATLAB, so that makes your code more portable to other environments (well, you'd still need to replace X *= A with X = X * A; to be MATLAB compatible). edit: Another possibility could be to just try out whether a form with multiple parameters works and fall back to the one parameter form when necessary: try (b-a)/2 * x(weight) + (a+b)/2; temp*=f((b-a)/2 * x(weight) + (a+b)/2,I,points); catch ME try disp('a'); temp*=c{fun}((b-a)/2 * x(weight) + (a+b)/2); catch ME end end You might want to check whether the returned error ME really states that a wrong number of arguments is used to allow other errors through. I do admit this is an ugly work-around, but since Octave apparently doesn't support function handles for nargin, it might be the only way you'd get what you want for inline functions.
Function definitions are not permitted in this context
Ok, I am new in Matlab and I am currently working on some econometric script. Before I move to real econometrics I have to create a function that selects the data that I'm interested in. Although I managed to get that script to work by writing at a very structural level, I would like this script to be as universal as possible and therefore would like to divide it into specific functions. However, when I converted all this to one function, I keep getting the error "Function definitions are not permitted in this context". Thanks in advance for your help. function [probingArray] = extractData (data, startValue, numberOfPeriods) arrayHeight=size(data,1); for i=1:arrayHeight if Date(i)==startValue datePosition=i; end end n=1; for i=(datePosition-numberOfPeriods):datePosition probingArray(n,1)=n; probingArray(n,2)=UK(i); n=n+1; end clear n i;
make sure you respect matlab conventions function [out1, out2, ...] = myfun(in1, in2, ...) declares the function myfun, and its inputs and outputs. The function declaration must be the first executable line of any MATLAB function. from http://www.mathworks.com/help/techdoc/ref/function.html