I created a function in Octave for which I, at this moment, only want one of the possible outputs displayed. The code:
function [pi, time, numiter] = PageRank(pi0,H,v,n,alpha,epsilon);
rowsumvector=ones(1,n)*H';
nonzerorows=find(rowsumvector);
zerorows=setdiff(1:n,nonzerorows); l=length(zerorows);
a=sparse(zerorows,ones(l,1),ones(l,1),n,1);
k=0;
residual=1;
pi=pi0;
tic;
while (residual >= epsilon)
prevpi=pi;
k=k+1;
pi=alpha*pi*H + (alpha*(pi*a)+1-alpha)*v;
residual = norm(pi-prevpi,1);
end
pi;
numiter=k
time=toc;
endfunction
Now I only want numiter returned, but it keeps giving me back pi as well, no matter whether I delete pi;, or not.
It returns it in the following format:
>> PageRank(pi0,H,v,length(H),0.9,epsilon)
numiter = 32
ans =
0.026867 0.157753 0.026867 0.133573 0.315385
To me it seems strange that the pi is not given with its variable, but merely as an ans.
Any suggestions?
I know the Octave documentation for this is not very extensive, but perhaps it gives enough hints to understand that how you think about output variables is wrong.
The call
PageRank(pi0,H,v,length(H),0.9,epsilon)
returns a single output argument, it is equivalent to
ans = PageRank(pi0,H,v,length(H),0.9,epsilon)
ans is always the implied output argument if none is explicitly given. ans will be assigned the value of pi, the first output argument of your function. The variable pi (nor time, nor numiter) in your workspace will be modified or assigned to. These are the names of local variables inside your function.
To obtain other output variables, do this:
[out1,out2,out3] = PageRank(pi0,H,v,length(H),0.9,epsilon)
Now, the variable out1 will be assigned the value that pi had inside your function. out2 will contain the value of time, and out3 the value of numiter,
If you don't want the first two output arguments, and only want the third one, do this:
[~,~,out3] = PageRank(pi0,H,v,length(H),0.9,epsilon)
The ~ indicates to Octave that you want to ignore that output argument.
Related
This function is supposed to return a function handle to the nested function inside, but if the variable x is set to a negative value in the outer function, it doesn't work.
The inner nested function is just a constant function returning the value of the variable x that is set in the outer function.
function t=test(x)
x=-1;
function y=f()
y=x;
endfunction
t=#f;
endfunction
If I try to evaluate the returned function, e.g. test()(3), I get an error about x being undefined. The same happens if x is defined as a vector with at least one negative entry or if x is argument of the function and a negative default value is used for evaluation. But if I instead define it as some nonnegative value
function t=test(x)
x=1;
function y=f()
y=x;
endfunction
t=#f;
endfunction,
then the returned function works just fine. Also if I remove the internal definition of x and give the value for x as an argument to the outer function (negative or not), like
function t=test(x)
function y=f()
y=x;
endfunction
t=#f;
endfunction
and then evaluate e.g. test(-1)(3), the error doesn't occur either. Is this a bug or am misunderstanding how function handles or nested functions work?
The Octave documentation recommends using subfunctions instead of nested functions, but they cannot access the local variables of their parent function and I need the returned function to depend on the input of the function returning it. Any ideas how to go about this?
This is a bug that was tracked here:
https://savannah.gnu.org/bugs/?func=detailitem&item_id=60137
Looks like it was fixed and will be gone in the next release.
Also, to explain the different behavior of negative and positive numbers: I experimented a bit, and no variable that is assigned a computed value is being captured:
function t=tst()
x = [5,3;0,0]; # captured
y = [5,3;0,0+1]; # not captured
z = x + 1; # not captured
function y=f()
endfunction
t=#f;
endfunction
>> functions(tst)
ans =
scalar structure containing the fields:
function = f
type = nested
file =
workspace =
{
[1,1] =
scalar structure containing the fields:
t = #f
x =
5 3
0 0
}
The different behavior of negative and positive numbers are probably caused by the minus sign - before the numbers being treated as a unary operator (uminus).
As of octave version 5.2.0 the nested function handles were not supported at all. I'm going to guess that is the novelty of the version 6.
In octave functions are not variables, the engine compiles\translates them at the moment of reading the file. My guess would be that behavior you are observing is influenced by your current workspace at the time of function loading.
The common way for doing what you are trying to do was to generate the anonymous (lambda) functions:
function t = test1(x=-1)
t = #()x;
end
function t = test2(x=-1)
function s = calc(y,z)
s = y + 2*z;
end
t = #(a=1)calc(a,x);
end
Note that default parameters for the generated function should be stated in lambda definition. Otherwise if you'd call it like test2()() it would not know what to put into a when calling calc(a,x).
If you are trying to create a closure (a function with associated state), octave has limited options for that. In such a case you could have a look at octave's object oriented functionality. Classdef might be useful for quick solutions.
I need to solve this differential equation using Runge-Kytta 4(5) on Scilab:
The initial conditions are above. The interval and the h-step are:
I don't need to implement Runge-Kutta. I just need to solve this and plot the result on the plane:
I tried to follow these instructions on the official "Scilab Help":
https://x-engineer.org/graduate-engineering/programming-languages/scilab/solve-second-order-ordinary-differential-equation-ode-scilab/
The suggested code is:
// Import the diagram and set the ending time
loadScicos();
loadXcosLibs();
importXcosDiagram("SCI/modules/xcos/examples/solvers/ODE_Example.zcos");
scs_m.props.tf = 5000;
// Select the solver Runge-Kutta and set the precision
scs_m.props.tol(6) = 6;
scs_m.props.tol(7) = 10^-2;
// Start the timer, launch the simulation and display time
tic();
try xcos_simulate(scs_m, 4); catch disp(lasterror()); end
t = toc();
disp(t, "Time for Runge-Kutta:");
However, it is not clear for me how I can change this for the specific differential equation that I showed above. I have a very basic knowledge of Scilab.
The final plot should be something like the picture bellow, an ellipse:
Just to provide some mathematical context, this is the differential equation that describes the pendulum problem.
Could someone help me, please?
=========
UPDATE
Based on #luizpauloml comments, I am updating this post.
I need to convert the second-order ODE into a system of first-order ODEs and then I need to write a function to represent such system.
So, I know how to do this on pen and paper. Hence, using z as a variable:
OK, but how do I write a normal script?
The Xcos is quite disposable. I only kept it because I was trying to mimic the example on the official Scilab page.
To solve this, you need to use ode(), which can employ many methods, Runge-Kutta included. First, you need to define a function to represent the system of ODEs, and Step 1 in the link you provided shows you what to do:
function z = f(t,y)
//f(t,z) represents the sysmte of ODEs:
// -the first argument should always be the independe variable
// -the second argument should always be the dependent variables
// -it may have more than two arguments
// -y is a vector 2x1: y(1) = theta, y(2) = theta'
// -z is a vector 2x1: z(1) = z , z(2) = z'
z(1) = y(2) //first equation: z = theta'
z(2) = 10*sin(y(1)) //second equation: z' = 10*sin(theta)
endfunction
Notice that even if t (the independent variable) does not explicitly appear in your system of ODEs, it still needs to be an argument of f(). Now you just use ode(), setting the flag 'rk' or 'rkf' to use either one of the available Runge-Kutta methods:
ts = linspace(0,3,200);
theta0 = %pi/4;
dtheta0 = 0;
y0 = [theta0; dtheta0];
t0 = 0;
thetas = ode('rk',y0, t0, ts, f); //the output have the same order
//as the argument `y` of f()
scf(1); clf();
plot2d(thetas(2,:),thetas(1,:),-5);
xtitle('Phase portrait', 'theta''(t)','theta(t)');
xgrid();
The output:
Unlike Matlab, Octave Symbolic has no piecewise function. Is there a work around? I would like to do something like this:
syms x
y = piecewise(x0, 1)
Relatedly, how does one get pieces of a piecewise function? I ran the following:
>> int (exp(-a*x), x, 0, t)
And got the following correct answer displayed and stored in a variable:
t for a = 0
-a*t
1 e
- - ----- otherwise
a a
But now I would like to access the "otherwise" part of the answer so I can factor it. How do I do that?
(Yes, I can factor it in my head, but I am practicing for when more complicated expressions come along. I am also only really looking for an approach using symbolic expressions -- even though in any single case numerics may work fine, I want to understand the symbolic approach.)
Thanks!
Matlab's piecewise function seems to be fairly new (introduced in 2016b), but it basically just looks like a glorified ternary operator. Unfortunately I don't have 2016 to check if it performs any checks on the inputs or not, but in general you can recreate a 'ternary' operator in octave by indexing into a cell using logical indexing. E.g.
{#() return_A(), #() return_B(), #() return_default()}([test1, test2, true]){1}()
Explanation:
Step 1: You put all the values of interest in a cell array. Wrap them in function handles if you want to prevent them being evaluated at the time of parsing (e.g. if you wanted the output of the ternary operator to be to produce an error)
Step 2: Index this cell array using logical indexing, where at each index you perform a logical test
Step 3: If you need a 'default' case, use a 'true' test for the last element.
Step 4: From the cell (sub)array that results from above, select the first element and 'run' the resulting function handle. Selecting the first element has the effect that if more than one tests succeed, you only pick the first result; given the 'default' test will always succeed, this also makes sure that this is not picked unless it's the first and only test that succeeds (which it does so by default).
Here are the above steps implemented into a function (appropriate sanity checks omitted here for brevity), following the same syntax as matlab's piecewise:
function Out = piecewise (varargin)
Conditions = varargin(1:2:end); % Select all 'odd' inputs
Values = varargin(2:2:end); % Select all 'even' inputs
N = length (Conditions);
if length (Values) ~= N % 'default' case has been provided
Values{end+1} = Conditions{end}; % move default return-value to 'Values'
Conditions{end} = true; % replace final (ie. default) test with true
end
% Wrap return-values into function-handles
ValFuncs = cell (1, N);
for n = 1 : N; ValFuncs{n} = #() Values{n}; end
% Grab funhandle for first successful test and call it to return its value
Out = ValFuncs([Conditions{:}]){1}();
end
Example use:
>> syms x t;
>> F = #(a) piecewise(a == 0, t, (1/a)*exp(-a*t)/a);
>> F(0)
ans = (sym) t
>> F(3)
ans = (sym)
-3⋅t
ℯ
─────
9
I have created a function that returns the magnitude of a vector.the output is 360x3 dimension matrix. the input is 360x2.
Everything works fine outside the function. how do i get it to work ?
clc
P_dot_ij_om_13= rand(360,2); // 360x2 values of omega in vectors i and j
//P_dot_ij_om_13(:,3)=0;
function [A]=mag_x(A)
//b="P_dot_ijOmag_"+ string(k);
//execstr(b+'=[]'); // declare indexed matrix P_dot_ijOmag_k
//disp(b)
for i=1:1:360
//funcprot(0);
A(i,3)=(A(i,2)^2+A(i,1)^2)^0.5; //calculates magnitude of i and j and adds 3rd column
disp(A(i,3),"vector magnitude")
end
funcprot(1);
return [A] // should return P_dot_ijOmag_k in the variable browser [360x3 dim]
endfunction
mag_x(P_dot_ij_om_13);
//i=1;
//P_dot_ij_om_13(i,3)= (P_dot_ij_om_13(i,2)^2+P_dot_ij_om_13(i,1)^2)^0.5;// example
You never assigned mag_x(P_dot_ij_om_13) to any variable, so the output of this function disappears into nowhere. The variable A is local to this function, it does not exist outside of it.
To have the result of calculation available, assign it to some variable:
res = mag_x(P_dot_ij_om_13)
or A = mag_x(P_dot_ij_om_13) if you want to use the same name outside of the function as was used inside of it.
By the way, the Scilab documentation discourages the use of return, as it leads to confusion. The Scilab / Matlab function syntax is different from the languages in which return specifies the output of a function:
function y = sq(x)
y = x^2
endfunction
disp(sq(3)) // displays 9
No need for return here.
This is a general question, not related to a particular operation. I would like to be able to write the results of an arbitrary function into elements of a cell array without regard for the data type the function returns. Consider this pseudocode:
zout = cell(n,m);
myfunc = str2func('inputname'); %assume myfunc puts out m values to match zout dimensions
zout(1,:) = myfunc(x,y);
That will work for "inputname" == "strcat" , for example, given that x and y are strings or cells of strings with appropriate dimension. But if "inputname" == "strcmp" then the output is a logical array, and Matlab throws an error. I'd need to do
zout(1,:) = num2cell(strcmp(x,y));
So my question is: is there a way to fill the cell array zout without having to test for the type of variable generated by myfunc(x,y ? Should I be using a struct in the first place (and if so, what's the best way to populate it)?
(I'm usually an R user, where I could just use a list variable without any pain)
Edit: To simplify the overall scope, add the following "requirement" :
Let's assume for now that, for a function which returns multiple outputs, only the first one need be captured in zout . But when this output is a vector of N values or a vector of cells (i.e. Nx1 cell array), these N values get mapped to zout(1,1:N) .
So my question is: is there a way to fill the cell array zout without having to test for the type of variable generated by myfunc(x,y) ? Should I be using a struct in the first place (and if so, what's the best way to populate it)?
The answer provided by #NotBoStyf is almost there, but not quite. Cell arrays are the right way to go. However, the answer very much depends on the number of outputs from the function.
Functions with only one output
The function strcmp has only one output, which is an array. The reason that
zout{1,:} = strcmp(x,y)
gives you an error message, when zout is dimensioned N x 2, is that the left-hand side (zout{1,:}) expects two outputs from the right-hand side. You can fix this with:
[zout{1,:}] = num2cell(strcmp(x,y)); % notice the square brackets on the LHS
However, there's really no reason to do this. You can simply define zout as an N x 1 cell array and capture the results:
zout = cell(1,1);
x = 'a';
y = { 'a', 'b' };
zout{1} = strcmp(x,y);
% Referring to the results:
x_is_y_1 = zout{1}(1);
x_is_y_2 = zout{1}(2);
There's one more case to consider...
Functions with multiple outputs
If your function produces multiple outputs (as opposed to a single output that is an array), then this will only capture the first output. Functions that produce multiple outputs are defined like this:
function [outA,outB] = do_something( a, b )
outA = a + 1;
outB = b + 2;
end
Here, you need to explicitly capture both output arguments. Otherwise, you just get a. For example:
outA = do_something( [1,2,3], [4,5,6] ); % outA is [2,3,4]
[outA,outB] = do_something( [1,2,3], [4,5,6] ); % outA is [2,3,4], outB is [6,7,8]
Z1 = cell(1,1);
Z1{1,1} = do_something( [1,2,3], [4,5,6] ); % Z1{1,1} is [2,3,4]
Z2 = cell(1,2);
Z2{1,1:2} = do_something( [1,2,3], [4,5,6] ); % Same error as above.
% NB: You really never want to have a cell expansion that is not surrounded
% by square brackets.
% Do this instead:
[Z2{1,1:2}] = do_something( [1,2,3], [4,5,6] ); % Z2{1,1} is [2,3,4], Z2{1,2} is [6,7,8]
This can also be done programmatically, with some limits. Let's say we're given function
func that takes one input and returns a constant (but unknown) number of outputs. We
have cell array inp that contains the inputs we want to process, and we want to collect the results in cell around outp:
N = numel(inp);
M = nargout(#func); % number of outputs produced by func
outp = cell(N,M);
for i=1:N
[ outp{i,:} ] = func( inp{i} );
end
This approach has a few caveats:
It captures all of the outputs. This is not always what you want.
Capturing all of the outputs can often change the behavior of the function. For example, the find function returns linear indices if only one output is used, row/column indices if two outputs are used, and row/column/value if three outputs are used.
It won't work for functions that have a variable number of outputs. These functions are defined as function [a,b,...,varargout] = func( ... ). nargout will return a negative number if the function has varargout declared in its output list, because there's no way for Matlab to know how many outputs will be produced.
Unpacking array and cell outputs into a cell
All true so far, but: what I am hoping for is a generic solution. I can't use num2cell if the function produces cell outputs. So what worked for strcmp will fail for strcat and vice versa. Let's assume for now that, for a function which returns multiple outputs, only the first one need be captured in zout – Carl Witthoft
To provide a uniform output syntax for all functions that return either a cell or an array, use an adapter function. Here is an example that handles numeric arrays and cells:
function [cellOut] = cellify(input)
if iscell(input)
cellOut = input;
elseif isnumeric(input)
cellOut = num2cell(input);
else
error('cellify currently does not support structs or objects');
end
end
To unpack the output into a 2-D cell array, the size of each output must be constant. Assuming M outputs:
N = numel(inp);
% M is known and constant
outp = cell(N,M);
for i=1:N
outp(i,:) = cellify( func( inp{i} ) ); % NB: parentheses instead of curlies on LHS
end
The output can then be addressed as outp{i,j}. An alternate approach allows the size of the output to vary:
N = numel(inp);
% M is not necessary here
outp = cell(N,1);
for i=1:N
outp{i} = cellify( func( inp{i} ) ); % NB: back to curlies on LHS
end
The output can then be addressed as outp{i}{j}, and the size of the output can vary.
A few things to keep in mind:
Matlab cells are basically inefficient pointers. The JIT compiler does not always optimize them as well as numeric arrays.
Splitting numeric arrays into cells can cost quite a bit of memory. Each split value is actually a numeric array, which has size and type information associated with it. In numeric array form, this occurs once for each array. When the array is split, this incurs once for each element.
Use curly braces instead when asigning a value.
Using
zout{1,:} = strcmp(x,y);
instead should work.