I would like to build a block that outputs a pure function. Something like:
createfunction[data_]:= Block[{parameter,function},
parameter = data^2;
function = Function[x,x + parameter];
Return[function];
];
I would like to use this module in another part of my notebook as
g = createfunction[data];
The problem is that if I do so, then I would get
In[1]:= g[x];
Out[1]:= x + a
I guess that the problem is something like: a is a local variable for block, Function[x, x + a ], does not actually substitute for a the value computed in the block (data^2), but wait till its called to do so, and since it is called after the block ran it will not work.
How to solve the problem?
_______________________________________________________________-
Update
A couple of answers were given that work for the current example, but not for the full problem I am working on, so I will post here a more dressed up example.
My problem is the following: given a set of points P_i in the xy-plane, compute the x mean $\mu_x$ and variance $\sigma_x$ , the y mean $\mu_y$ and variance $\sigma_y$, and output the multi-variate normal distribution p({x,y},$\mu_x$,$\sigma_x$,$\mu_y$,$\sigma_y$). Later I will want to work with function p in many ways.
I decided to solve this problem creating a function "train" that takes the list {P_1,...,P_m} and outputs p as a pure function. What train does is to compute the parameters:
train[data_] :=
Block[{m = data // Length, i, j, density, \[Mu], \[Sigma]},
\[Mu] =
1/m Table[Sum[data[[i, j]], {j, 1, data // Length}], {i, 1, 2}];
\[Sigma] =
1/m Table[
Sum[(data[[i, j]] - \[Mu][[i]])^2, {j, 1, m}], {i, 1, 2}];
density =
Function[x,
Product[1/(Sqrt[
2 \[Pi]] \[Sigma][[i]]) Exp[-(x[[i]] - \[Mu][[i]])^2/(2 (\
\[Sigma][[i]])^2)], {i, 1, 2}]];
Return[density];
];
Now, it is difficult for me to see how to address this problem using With. I am not an expert in scoping with mathematica, but With seems to me as something you use when you want to use some constants, I would say something already known or quickly computed (as the lenght of data in my prievous example), whilst here mu and sigma are obtained in a "complicate" way, which involves using tables as well.
In general, if you have a situation where you want to build a pure function whose "form" you already know, but that depends on certain parameters which you obtain doing some complicate at will operations on certain input data, how would you set up the scoping?
Return
and extra semicolons when they are not necessary (even even hurt performance)? UseBlock[{}, ...; result]
, notBlock[{}, ...; x = result; Return[x];]
. $\endgroup$mu0
andsigma0
, useWith
to inject them.With[{mu = mu0, sigma = sigma0}, Function[..., ... mu ... sigma ...]]
. In fact you can even just usemu
andsigma
throughout (notmu0
) and doWith[{mu=mu, sigma=sigma}, ...]
. If this is confusing to you, stick to separate names (mu
andmu0
). $\endgroup$Block
here because the results will be messed up ifdata
contains\[Mu]
(or eveni
). Generally, stick toModule
unless you know that you needBlock
. If you useModule
, you will need separatemu
andmu0
due toModule
's symbol renaming. $\endgroup$data
? Judging fromm=data//Length
,data
seems to be a $n\times 2$ array, but later you're accessing it withi
as first index, with $i\in\{1,2\}$ $\endgroup$