map function with multiple arguments to each row of Array in Julia - function

In an attempt to simplify my code in Julia, I have the following command:
L=rand(50,50)
function f(l)
n=mapslices(function g(x) partialsortperm(x,1:l,rev=true) end,L,dims=2)
return n
end
map(f,[34; 24 ;17])
This command is supposed to apply the function g to each row of the Array L, where at each time, the function is applied with 3 different values of the argument l. I attempted to create a unique function, to eliminate the function inside a function:
function f(A::Array,l::Int64)
partialsortperm(A,1:l,rev=true)
end
and tried to use map(f,eachrow(L),[34; 24; 17]) but not getting what I want, because the function f has now 2 arguments and I don't know how to use 2 arguments with map or mapslices.

Related

Differential equation; function in Octave

I try to solve a differential equation in Octave. In a first attempt, all my independent variables are set constant (n,y,w). This is my code:
function xdot= f(x,t);
% xdot=zeros(1,1);
X=1.44221E+12;
IO=5.318E+11;
GO=6.81E+11;
beta=0;
gamma=0;
y=58.5021088;
w= 31.29;
n=1363.5;
tw=0.4;
tp=0.3;
sw=0.07;
sp=0.25;
mw=0.593941689;
mp=0.593941689;
% aw=(1-tw)(sw+mw)
% ap=(1-tp)(sp+mp)
xdot=-(X+IO*(1+gamma*(diff(n)/n+diff(y)/y))+GO*beta(tw(diff(n)/n+diff(w)/w)+tp(diff(y)/y-diff(w)/w)-(x*n)/((y-w)((1-tp)(sp+mp)+tp)+((1-tw)(sw+mw)+tw)*w))*x)/(IO*gamma+GO*beta*tw);
endfunction
When I add
t = [0:(1/360):10]
x = lsode ("f", 39290000, t);
to solve the equation in the command line, I get this error:
error: index (0.843942): subscripts must be either integers 1 to (2^31)-1 or logicals
error: lsode: evaluation of user-supplied function failed
error: called from
f at line 23 column 7
It seems to me, in some way I misunderstood how to make the function.
Any help?
EDIT:
This is my new code:
function xdot= f(x,t);
X=1.44221E+12;
IO=5.318E+11;
GO=6.81E+11;
beta=0;
gamma=0;
y=58.5021088;
w= 31.29;
n=1363.5;
tw=0.4;
tp=0.3;
sw=0.07;
sp=0.25;
mw=0.593941689;
mp=0.593941689;
xdot=-X+IO-(x*n)/((y-w)*((1-tp)*(sp+mp)+tp)+w*(tw+(1-tp)*(sp+mp)))
endfunction
It does work if I copy it into the command line but if I start it as programm (f.m) and solve it then I get this error:
error: 'x' undefined near line 25 column 15
error: called from
f at line 25 column 7
From the documentation of lsode:
Syntax: [x, istate, msg] = lsode (fcn, x_0, t)
...
The first argument, fcn, is a string, inline, or function handle that names the function f to call to compute the vector of right hand sides for the set of equations. The function must have the form
xdot = f (x, t)
in which xdot and x are vectors and t is a scalar.
So firstly, your f function is of the wrong form to the one expected by lsode, since it takes 5 arguments as opposed to 2.
Secondly, inside your f function, the variables y, w, and n are overwritten, regardless of whether they were supplied, whereas t and x need to be supplied by the user.
When lsode calls the handle f, it calls it with two arguments as per its specification, which means it instantiates t and y, and calls the function with the remaining input arguments undefined. Of the remaining arguments, w and n are given values inside the function, as we pointed out above, but x remains undefined. So when you run the final calculation which relies on x, you get an error saying it has not yet been defined during the call to this function.
So, to fix this issue, rewrite your function such that its signature is f(x, t), which you can do so easily since y, w, and n are defined inside your function anyway, so they don't really need to be given as inputs.

Scilab not returning variables in variable window

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.

Lua - Higher-order Derivative function

How does returning functions work in Lua? I'm trying to wrap my head around this derivative function but I'm having trouble understanding it.
function derivative(f, delta)
delta = delta or 1e-4
return function(x)
return (f(x + delta) - f(x))/delta
end
end
Any help is appreciated, thanks.
First see here.
Shortly, functions are first-class citizens and you an store them in variable and return from functions.
Second. In your example there is a closure to be created. It will have upvalues f and delta, wich can be used in inner function.
So when you call your derivative function, new closure will be created with copy of f and delta. And you can call it later like any other function
local d = derivative(f, 1e-6)
d(10)
EDIT: "Answer on but I'm having trouble understanding how the x argument is treated in the anonymous function in my example"
Each function have a signature, number of formal attributes, it will get.
In Lua you can call function with any number of arguments. Let's consider an example.
local a = function(x1, x2) print(x1, x2) end
a(1) // 1, nil
a(1, 2) // 1, 2
a(1, 2, 3) // 1, 2
When you call function in variable a, each given argument value, one by one will be matched with function argumentList. In 3-rd example 1 will be assigned to x1, 2 to x2, 3 will be thrown away. In term's of vararg function smth like this will be performed.
function a(...)
local x1 = (...)[1]
local x2 = (...)[2]
// Body
end
In your example x is treated as inner function argument, will be visible inside it, and initialized when you call your inner function instance.
f and delta will be unique for each function instance, as I mentioned above.
Hope my clumsy explanations will hit their goal and help you a little.

MatLab - Applying a function to each row in a matrix

I have a matrix with rows of 4 integers, with an unspecified number of columns (depends on the text file).
I'm wanting to apply a function to each row of the matrix, independently. The function has 4 inputs, and 2 outputs.
I'm trying to use the arrayfun function to do this, but whenever I call the function, I get an error saying: "Not enough input arguments."
Here is the function call:
[gain,phase]=arrayfun(#(x) GainPhaseComp(B(x,1:4)), 1:size(B));
where b is an n by 4 matrix.
Here is the function:
function [gain,phase] = GainPhaseComp(InAmp,InPhase,OutAmp,OutPhase)
gain = 20*log10(OutAmp\InAmp);
phase = (OutPhase - InPhase);
end
Any help would be greatly appreciated!
Your function GainPhaseComp has 4 input arguments, but you pass only 1 row vector. Vector with 4 elements is still one variable, not 4. You need either to change the function definition or split the vector elements.
1st option:
function [gain,phase] = GainPhaseComp(inputvector)
% function body
2nd option:
[gain,phase]=arrayfun(#(x) GainPhaseComp(B(x,1),B(x,2),B(x,3),B(x,4)), 1:size(B,1));

Adding an arbitrary number of functions into a function handle MATLAB

I'm trying to generate .bmp graphics in MATLAB and I'm having trouble summing functions together. I'm designing my function such that given an arbitrary set of inputs, my function will add an arbitrary number of functions together and output a function handle. The inputs are coefficients to my general function so I can specify any number of functions (that only differ due to their coefficients) and then add them together into a function handle. What I've tried to do is create each function as a string and then concatenate them and then write them as a function handle. The main problem is that because x and y aren't defined (because I'm trying to create a function handle) MATLAB can't add them regularly. My current attempt:
function HGHG = anyHGadd(multi) %my array of inputs
m=length(multi);
for k=3:3:m;
m1=multi(k-2); %these three are the coefficients that I'd like to specify
n1=multi(k-1);
w1=multi(k);
HGarrm1=hermite(m1); %these generate arrays
HGarrn1=hermite(n1);
arrm1=[length(HGarrm1)-1:-1:0];%these generate arrays with the same length
arrn1=[length(HGarrn1)-1:-1:0];%the function below is the general form of my equation
t{k/3}=num2str(((sum(((sqrt(2)*x/w1).^arrm1).*HGarrm1))*(sum(((sqrt(2)*y/w1).^arrn1).*HGarrn1))*exp(-(x^2+y^2)/(w1^2))));
end
a=cell2mat(t(1:length(t)));
str2func(x,y)(a);
Any help would be much appreciated. I haven't seen much on here about this, and I'm not even sure this is entirely possible. If my question isn't clear, please say so and I'll try again.
Edit: The fourth from last line shouldn't produce a number because x and y aren't defined. They can't be because I need them to be preserved as a part of my function handle. As for a stripped down version of my code, hopefully this gets the point across:
function HGHG = anyHGadd(multi) %my array of inputs
m=length(multi);
for k=3:3:m;
m1=multi(k-2); %these three are the coefficients that I'd like to specify
n1=multi(k-1);
w1=multi(k);
t{k/3}=num2str(genericfunction(x,y,n1,m1,n1,w1); %where x and y are unspecified
end
a=cell2mat(t(1:length(t)));
str2func(x,y)(a);
Edit I am expecting this to output a single function handle that is the sum of an arbitrary number of my functions. However, I'm not sure if using strings would be the best method or not.
Your question is not very clear to me, but I think you are trying to create a function that generate output functions parametrized by some input.
One way is to use closures (nested function that access its parent function workspace). Let me illustrate with an example:
function fh = combineFunctions(funcHandles)
%# return a function handle
fh = #myGeneralFunction;
%# nested function. Implements the formula:
%# f(x) = cos( f1(x) + f2(x) + ... + fN(x) )
%# where f1,..,fN are the passed function handles
function y = myGeneralFunction(x)
%# evaluate all functions on the input x
y = cellfun(#(fcn) fcn(x), funcHandles);
%# apply cos(.) to the sum of all the previous results
%# (you can make this any formula you want)
y = cos( sum(y) );
end
end
Now say we wanted to create the function #(x) cos(sin(x)+sin(2x)+sin(5x)), we would call the above generator function, and give it three function handles as follows:
f = combineFunctions({#(x) sin(x), #(x) sin(2*x), #(x) sin(5*x)});
Now we can evaluate this created function given any input:
>> f(2*pi/5) %# evaluate f(x) at x=2*pi/5
ans =
0.031949
Note: The function returned will work on scalars and return a scalar value. If you want it vectorized (so that you can apply it on whole vector at once f(1:100)), you'll have to set UniformOutput to false in cellfun, then combine the vectors into a matrix, sum them along the correct dimension, and apply your formula to get a vector result.
If your goal is to create a function handle that sums the output of an arbitrary number functions, you can do the following:
n = 3; %# number of function handles
parameters = [1 2 4];
store = cell(2,3);
for i=1:n
store{1,i} = sprintf('sin(t/%i)',parameters(i));
store{2,i} = '+'; %# operator
end
%# combine such that we get
%# sin(t)+sin(t/2)+sin(t/4)
funStr = ['#(t)',store{1:end-1}]; %# ignore last operator
functionHandle = str2func(funStr)
functionHandle =
#(t)sin(t/1)+sin(t/2)+sin(t/4)