Cell array of anonymous functions to vector anonymous function
4 次查看(过去 30 天)
显示 更早的评论
I have the following problem: Let's say I have a 1xn cell array called f, that means f{i}(x)=fi(x) gives a function of x for each index i. Is there a way other than using arrayfun to make a vector function out of this, that means to get an anonymous function like f2=@(x) [f{1}(x) f{2}(x) ... f{n}(x)] without having to type it manually? I managed that with arrayfun, but as I use this function a lot, arrayfun takes way too long compared to typing it out manually as I did for f2.
7 个评论
Jan
2020-9-3
Can you post an explicit example? Currently it sounds like a too complicated approach compared to a simple vectorized function.
P.C.
2020-9-3
Sure, a simple example for n=3 (with simple functions just for demonstration):
f{1}=@(x) x^1
f{2}=@(x) x^2
f{3}=@(x) x^3
What I want is a function f2 which gives me a vector like this:
f2=@(x) [f{1}(x) f{2}(x) f{3}(x)]
without having to type it manually like this, as n is variable and large. I did try arrayfun, but it is way slower than typing it out manually like I did in the line above, so I cannot use it. There must be an easy way to do this, right?
Dana
2020-9-3
Can you post code doing this with arrayfun? I'm not entirely clear on what the inptus/output here all are.
采纳的回答
Matt J
2020-9-3
The functions I had above were just for demonstration and for n=3, so this does not really work for say n=100.
In situations where you have hundereds of functions, it is normally because you have overlooked vector-valued, vectorized alternatives. For example, instead of
f{1}=@(x) x^1
f{2}=@(x) x^2
f{3}=@(x) x^3
...
f{100}=@(x) x^100
you should really have a single vectorized function,
f=@(x) x.^(1:100)
23 个评论
P.C.
2020-9-3
I would do that if I had analytical functions, but I do not. They are obtained from an interpolation of data (using griddedInterpolant), thats why I cannot have a simple vector function in the beginning. The only thing I have are these single anonymous functions in a cell array, and I thought there has to be an easy way of doing what I did manually without sacrificing too much speed. Or is what I am trying to do not possible in Matlab?
Matt J
2020-9-3
编辑:Matt J
2020-9-3
The fact that you have multiple griddedInterpolant operations to do does not explain why you absolutely must have multiple anonymous function instances. griddedInterpolant is a very well-vectorized Matlab tool. You should be able to perform many interpolations in a single function call.
P.C.
2020-9-3
I tried reading into griddedInterpolant, but I did not see how I could do that. The function I am interpolating has a certain number of lines (for the data points) and n columns. Is it possible to get a 1xn griddedInterpolant "function handle", where each component is an interpolation from the respective column of my data points?
Bruno Luong
2020-9-3
Please provide us an example of two functions f1 and f2 using griddedInterpolant and show us why they are different (lines+colums whatever, no idea what argument you are talking about), but please show a specific example instead of a verbal description.
Matt J
2020-9-3
编辑:Matt J
2020-9-3
Like Bruno, I encourage you to provide a small example involving the griddedInterpolant operations you are actually doing. But note that if, for example, if you have a 200x100 data matrix
data=rand(200,100);
and you want to interpolate each column data(:,i) at a common set of 50 locations, t
t=sort( rand(50,1)*199+1);
you can do that in a single call using interp1,
dataInterpolated = interp1(data,t)
and you can also wrap this in a single anonymous function, if it is convenient for you for whatever reason,
f=@(t) interp1(data,t)
P.C.
2020-9-3
编辑:P.C.
2020-9-3
I am not sure if what you described is what I want to do, but I can show you what I am doing. Let's assume my data c is given in the form of a 1000xn matrix, and the 1000 data points correspond to the locations t. What I am doing is the following:
for k=1:n
cInterpolation{k}= griddedInterpolant(t,c(:,k),'linear');
end
From this I get these n function handles I was talking about and which I want in a form of a 1xn vector.
Bruno Luong
2020-9-3
编辑:Bruno Luong
2020-9-3
Indeed there is no shortcut if you change the sample data values at the grid point.
However if you intend later to apply cInterpolation{k} on the same known query points; I can offer the method to build a sparse matrix that when multiplied with c(:,:) will return the interpolation values at the query points.
No need for a list of function handles.
P.C.
2020-9-3
编辑:P.C.
2020-9-3
Yes, I do want to apply cInterpolation{k}(t) at the same t for all k later. Is your method faster than using the arrayfun function? Because I tried it and it is way slower than manually typing it out, which is not possible for large n of course.
Edit: I am not changing the sample points, the sample points are inside of t and c(:,k) are the corresponding values I want to interpolate. Thats the order of griddedInterpolant in the matlab documentation.
Bruno Luong
2020-9-3
You can't do faster than sparse-matrix multiplication. Now it might take time to build the matrix but I think it's faster than loop with griddedInterpolant() construction.
Bruno Luong
2020-9-3
编辑:Bruno Luong
2020-9-3
Wait a minute, if it's 1D interpolation why don't you just simply do
cInterpolation = interp1(t,c,ti);
? where
t: is m x 1 % grid sample points
c: is m x n % data value
ti: is p x 1 % query points
The result cInterpolation will be size (p x n), each column is the interpolation using the correponding column of c..
Matt J
2020-9-3
Here is an example
>> t=(1:6).'; c=t+(0:5)
c =
1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7 8
4 5 6 7 8 9
5 6 7 8 9 10
6 7 8 9 10 11
>> cInterpolation = @(tq) interp1(t,c,tq);
>> cInterpolation([1.5, 2.7, 3.8])
ans =
1.5000 2.5000 3.5000 4.5000 5.5000 6.5000
2.7000 3.7000 4.7000 5.7000 6.7000 7.7000
3.8000 4.8000 5.8000 6.8000 7.8000 8.8000
Bruno Luong
2020-9-3
Yes I think Matt and I show you the same solution, much simpler and straighforward.
P.C.
2020-9-3
Yes this seems to work, but it looks to be quite a bit slower than the griddedInterpolant function I was using. The same must be possible with the griddedInterpolant function, or not?
Bruno Luong
2020-9-3
编辑:Bruno Luong
2020-9-3
No, griddedInterpolant can't deal with array of values in 1D (pitty TMW).
Are you sure it's slower? Do you compare inte INTERP1 solution with or without the step of construct your anonymous functions using griddedInterpolant?
P.C.
2020-9-3
编辑:P.C.
2020-9-3
It does look like it, yes. What I tried is replacing the for-loop you saw above and the function call with arrayfun with the one line you and Matt showed, so there is no griddedInterpolant involved at all. The one with griddedInterpolant finishes in about 420 seconds (from tic and toc), and the interp1 interpolation did not finish within 15 minutes.Should they work as fast as each other, or are these functions working differently? I am just wondering, because even the documentation for interp1 says "This syntax is not recommended. Use griddedInterpolant instead."
Bruno Luong
2020-9-3
编辑:Bruno Luong
2020-9-3
Something very odd it takes 78 ms on my computer, not 15 minutes.
m = 10000;
n = 100;
p = 45000;
t = sort(rand(m,1));
tq = rand(p,1);
c = rand(m,n);
tic
ci2 = interp1(t,c,tq);
toc % Elapsed time is 0.077927 seconds.
Unless your computer has tiny RAM
P.C.
2020-9-3
I did use it as an anonymous function though like in Matt's code. Does it make a difference if you call the tq separately one by one instead of all in one call? Maybe I did something wrong, but I pretty much just replaced my loop with the one line.
Bruno Luong
2020-9-3
编辑:Bruno Luong
2020-9-3
The difference is noise
tic
interfun = @(tq) interp1(t,c,tq);
ci2 = interfun(tq);
toc % Elapsed time is 0.063195 seconds.
Why you want to call one by one? Do you prefer to get your result in 70 ms or 15 minutes?
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Performance and Memory 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)