how can i use integral function with vector limits by using another for loop ?
10 次查看(过去 30 天)
显示 更早的评论
work wolf
2023-7-3
% Define the function for integration
f = @(t, y,m) y + (t-m);
% Create sample data
m=[0 0.2 0.3 0.4 ];
datalower = [0.1 0.5 0.6];
dataupper = [0.9 2 0.5];
% Define the integral function handle
IntV = @(y,k,m, lower, upper) integral(@(t) f(t, y(k),m(k)), lower(k), upper(k));
% To use it within a a recursive formula without using for loop as follows:
k = 1:numel(m)-1;
y(1)=0;
y(k+1) = y(k) + IntV(y,k,m, lower, upper)./m(k-2) ;
by looking for integral function, it's not accept vector limitis, Thus can i convert integral to matrix or summations ( with respect to same result) to aviod using for loop or symbolic 'int' ?
回答(1 个)
Star Strider
2023-7-3
All the vectors have to be the same size ()so I shortened ‘m’ here), then arrayfun works (and so would a loop, indexing each vector) —
% Define the function for integration
f = @(t, y,m) y + (t-m);
% Create sample data
m=[0 0.2 0.3];
datalower = [0.1 0.5 0.6];
dataupper = [0.9 2 0.5];
% Define the integral function handle
IntV = @(y,m, lower, upper) integral(@(t) f(t, y,m), lower, upper);
% To use it within a a recursive formula without using for loop as follows:
% k = 1:numel(m)-1;
% y(1)=0;
% y(k+1) = y(k) + IntV(y,k,m, lower, upper)./m(k-2) ;
y = randn(size(m));
y = arrayfun(IntV,y,m,datalower,dataupper)
.
17 个评论
work wolf
2023-7-4
编辑:work wolf
2023-7-4
@Star Strider thank you so much . The problem when i apply it inside a recursive formula, becasue y is not previously known, but by a recursive formula with initial value and fill gradually according to previous value.
% Define the function for integration
f = @(t, y,m) y + (t-m);
% Create sample data
m=[0 0.2 0.3];
datalower = [0.1 0.5 0.6];
dataupper = [0.9 2 0.5];
% Define the integral function handle
IntV = @(y,m, lower, upper) integral(@(t) f(t, y,m), lower, upper);
% Define the function handle dep. on y to use in a recursive formula by using arrayfun
intV_Fun = @(y) arrayfun(IntV,y,m,datalower,dataupper); %y = datalower; %randn(size(m)); test
%-------------------------------------------------------------------------------------------------
% IntV_Fun = @(y) splitapply(@(k) IntV(y(k),m(k),datalower(k),dataupper(k)), k, k);
% IntV_Fun = @(y) cell2mat(arrayfun(@(k) IntV(y(k),m(k),datalower(k),dataupper(k)), k,'UniformOutput', false) );
% IntV_Fun = @(y) accumarray(k.', k, [], @(k) IntV(y(k),m(k),datalower(k),dataupper(k) ) );
% IntV_Fun = @(y) groupsummary(k, k, @(k) IntV(y(k),m(k),datalower(k),dataupper(k) ) );
% IntV_Fun = @(y) groupsummary(k', k', @(k) IntV(y(k),m(k),datalower(k),dataupper(k) ) );
% IntV_Fun = @(y) groupsummary({y,m,datalower,dataupper}, k,...
% @(y,m,datalower,dataupper) IntV(y,m,datalower,dataupper) ) ;
% IntV_Fun = @(y) groupsummary({y' , m', datalower', dataupper'}, k',...
% @(y,m,datalower,dataupper) IntV(y,m,datalower,dataupper ) );
%
% all gives 1x3 vector when y previously known for example y =y = datalower; (!).
% ** The problem when i apply integral inside a recursive formula,
% becasue y is not previously known, but by a recursive formula with
% initial value and fill gradually according to previous value.
% y(k+1) = y(k) + intV_Fun(y(k))./m(k-2) ;
%---------------------------------------------------------------------------------------------------------------------------
% To use it within a a recursive formula without using for loop as follows:
k = 1:numel(m)-1; % k = 1:numel(m); same Error
y(1)=0;
y(k+1) = y(k) + intV_Fun(y(k))./m(k-2) ;
% gives same Error in all cases, i.e, splitapply, accumarray & groupsummary
Error : Index exceeds the number of array elements. Index must not exceed 1.
please , can you help me ! ^_^
Torsten
2023-7-4
I don't know how you want to divide by m(k-2) since you will reference m(-1) and m(0) which do not exist. But maybe something like this ?
% Define the function for integration
f = @(t,y,m) y + (t-m);
% Create sample data
m=[0 0.2 0.3 0.4 ];
datalower = [0.1 0.5 0.6];
dataupper = [0.9 2 0.5];
% Define the integral function handle
IntV = @(y,m,lower, upper) integral(@(t) f(t,y,m), lower, upper);
y(1) = 0;
for k = 1:numel(m)-1
y(k+1) = y(k) + IntV(y(k),m(k),datalower(k),dataupper(k));
end
y
y = 1×4
0 0.4000 2.5750 2.2925
Star Strider
2023-7-4
My pleasure!
I cannot help because what you want to do does not make sense.
As in my code, ‘y’ must be the same size as the other elements.
% Define the function for integration
f = @(t, y,m) y + (t-m);
% Create sample data
m=[0 0.2 0.3];
datalower = [0.1 0.5 0.6];
dataupper = [0.9 2 0.5];
% Define the integral function handle
IntV = @(y,m, lower, upper) integral(@(t) f(t, y,m), lower, upper);
% Define the function handle dep. on y to use in a recursive formula by using arrayfun
intV_Fun = @(y) arrayfun(IntV,y,m,datalower,dataupper); %y = datalower; %randn(size(m)); test
%-------------------------------------------------------------------------------------------------
% IntV_Fun = @(y) splitapply(@(k) IntV(y(k),m(k),datalower(k),dataupper(k)), k, k);
% IntV_Fun = @(y) cell2mat(arrayfun(@(k) IntV(y(k),m(k),datalower(k),dataupper(k)), k,'UniformOutput', false) );
% IntV_Fun = @(y) accumarray(k.', k, [], @(k) IntV(y(k),m(k),datalower(k),dataupper(k) ) );
% IntV_Fun = @(y) groupsummary(k, k, @(k) IntV(y(k),m(k),datalower(k),dataupper(k) ) );
% IntV_Fun = @(y) groupsummary(k', k', @(k) IntV(y(k),m(k),datalower(k),dataupper(k) ) );
% IntV_Fun = @(y) groupsummary({y,m,datalower,dataupper}, k,...
% @(y,m,datalower,dataupper) IntV(y,m,datalower,dataupper) ) ;
% IntV_Fun = @(y) groupsummary({y' , m', datalower', dataupper'}, k',...
% @(y,m,datalower,dataupper) IntV(y,m,datalower,dataupper ) );
%
% all gives 1x3 vector when y know for example y =y = datalower; (!)
%---------------------------------------------------------------------------------------------------------------------------
% To use it within a a recursive formula without using for loop as follows:
% I can make this work (sort of) however nothing further —
k = 3;
y(3) = 0;
intV_Fun(y(k)*ones(size(m)))./m(k-2)
ans = 1×3
Inf Inf -Inf
% NOTE — It expands the scalar value for 'y' to a vector to match the sizes of the rest
% of the arguments.
% This is not recursive because there is no recursion of any kind —
k = 1:numel(m)-1; % k = 1:numel(m); same Error
y(1)=0;
y(k+1) = y(k) + intV_Fun(y(k)*ones(size(m)))./m(k-2) ;
Error using *
Incorrect dimensions for matrix multiplication. Check that the number of columns in the first matrix matches the number of rows in the second matrix. To operate on each element of the matrix individually, use TIMES (.*) for elementwise multiplication.
Incorrect dimensions for matrix multiplication. Check that the number of columns in the first matrix matches the number of rows in the second matrix. To operate on each element of the matrix individually, use TIMES (.*) for elementwise multiplication.
% gives same Error in all cases, i.e, splitapply, accumarray & groupsummary
% Error : Index exceeds the number of array elements. Index must not exceed 1.
Describe what you want to do and it may be possible to do it (no promises). I cannot figure it out from the code.
.
work wolf
2023-7-4
@Star Strider My regards, thank you so much for your time. I modified the code within your answers and m(k) insted of m(k-2) to avoid Inf, but problem it's not gives same results as follows:
clear
clc
% Define the function for integration
f = @(t,y,m) y + (t-m);
% Create sample data
m=[0.2 0.3 0.4 ];
datalower = [0.1 0.5 0.6];
dataupper = [0.9 2 0.5];
% Define the integral function handle
IntV = @(y,m,lower, upper) integral(@(t) f(t,y,m), lower, upper);
%---------------------------------------------------------
y1(1) = 0;
for k = 1:numel(m)-1
y1(k+1) = y1(k) + IntV(y1(k),m(k),datalower(k),dataupper(k))/m(k); % /m(k-1+(k==1));
end
y1 % with m(k)
%----------------------------------------------------------
intV_Fun = @(y) arrayfun(IntV,y,m,datalower,dataupper);
y2=zeros(size(m));
y2(1) = 0;
k = 1:numel(m);
y2 (k+1)= y2(k) + intV_Fun(y2(k))/m(k);
y2=y2(1:end-1)
%-------------------------------------------------------
y3(1) = 0;
for k = 1:numel(m)-1
y3(k+1) = y3(k) + IntV(y3(k),m(k),datalower(k),dataupper(k)); % /m(k-1+(k==1));
end
y3
%----------------------------------------------------------
intV_Fun = @(y) arrayfun(IntV,y,m,datalower,dataupper);
y4=zeros(size(m));
y4(1) = 0;
k = 1:numel(m);
y4 (k+1)= y4(k) + intV_Fun(y4(k));
y4=y4(1:end-1)
%-------------
% result
%------------
y1 =
0 1.2000 11.9500
y2 =
0 1.6190 1.6190
%------------------------------------
y3 =
0 0.2400 2.0250
y4 =
0 0.2400 1.4250
Star Strider
2023-7-4
I am lost. We now have ‘y1(k)’ through ‘y4(k)’ which seems to be diverging from anything reasonable.
What do you want to do? What problem do you want to solve? What is the objective?
work wolf
2023-7-4
this is by using loop, i want another code give me same result without using for loop or "int"
%---------------------------------------------------------
y1(1) = 0;
for k = 1:numel(m)-1
y1(k+1) = y1(k) + IntV(y1(k),m(k),datalower(k),dataupper(k))/m(k); % /m(k-1+(k==1));
end
y1 % with m(k)
i hope you are get my idea!
Star Strider
2023-7-4
There is a limit to what you can do efficiently with vectorisation, and sometimes it is indeed preferable. For some problems however, loops are more efficient.
If a loop works (and seems to make the problem easier, as it does here), just use a loop.
Vectorisation is not actually ‘loop-free’. In most instances, the loops are there (as they muxt be), simply not visible, and hidden in the vectorisation code.
.
work wolf
2023-7-4
编辑:work wolf
2023-7-4
@Star Strider you're right. As arrayfun have the implicit loop. it may have performance overhead due to the loop and array creation. Can be slower when dealing with a large number of intervals due to its individual function calls for each interval. So, Vectorisation take less time and fit for me more than loop.
Star Strider
2023-7-4
Not every operation can be efficiently vectorised. Sometimes, a loop is more efficient. Creating complicated vectorised code may be less efficient that just using a loop.
In any event, I do not understand what you want to do. If you describe what you want to do, and the problem you want to solve, I may be able to help.
work wolf
2023-7-4
编辑:work wolf
2023-7-4
First and foremost, I would like to express my sincere gratitude to you for your attention and insightful words, especially considering that each problem is unique and requires a different approach.
The crux of the matter lies in how to convert the "for loop" system into the array system, which significantly simplifies the process for me, particularly in terms of time. Hence, I kindly request your collaboration in assisting me with this conversion, as your extensive expertise in MATLAB makes it a straightforward task, rather than a major challenge.
Despite my exhaustive efforts and attempts, I still encounter a predicament: how to make the "integral" function accept integration limits in the form of an array. As you may have noticed, I have experimented with various functions such as "arrayfun", "splitapply", "accumarray" and "groupsummary" However, they pose challenges regarding the size of arrays when applied within a recursive formula.
Consequently, I have resorted to posing my question here and seeking advice from experts like yourself. Please note that I have summarized my attempts here through these observations:
Summary of Issues:
1. The "integral" function does not accept integration limits as an array.
2. The size of arrays poses challenges when using the following functions:"arrayfun", "splitapply", "accumarray" and "groupsummary" within a recursive formula.
The issue lies in the application of intervals. Each partial interval requires a distinct "for loop" which is illogical to apply each step using a separate "for loop." This approach consumes time during implementation and impacts performance. Although it resolves the problem, it resembles a manual solution.
For instance, in the case of partial intervals, when obtaining the value for each iteration before integration:
1. 1/2 integral(f, m(1), m(2)) when k == 1
2. 1/3 integral(f, m(k-1), m(k+1)) when k = 2:numel(m)-1
3. 1/2 integral(f, m(end-1), m(end)) when k = numel(m)
Using arrays or logical inference alone requires only one definition, whereas employing a "for loop" necessitates three definitions due to the varying pre-integration values and integration limits for each interval.
I apologize for the lengthy message; however, I wanted to convey the information accurately in written form.
I hope I don't confuse the ideas because I feel a bit lost in explaining the problem, especially through writing.
I sincerely hope that you will assist me and take an interest in this issue, even if it may not seem important to you. In any case, I appreciate any help you can provide, regardless of the approach. Really, i need it so much.
In short, , it seems impossible to convert the previous system into the array system without resorting to some form of "for loop".
%---------------------------------------------------------
y1(1) = 0;
for k = 1:numel(m)-1
y1(k+1) = y1(k) + IntV(y1(k), m(k), datalower(k), dataupper(k))/m(k); % /m(k-1+(k==1));
end
y1
The conversion to the array system by any ways to avoid "for loop".
Torsten
2023-7-4
编辑:Torsten
2023-7-4
Recursive systems are not suited to be vectorized. And to be honest: I don't know how it could be achieved for your case. A simple for-loop is easy to understand and adequate here.
Jan's answer might be of interest for you:
And it's no problem to vectorize these steps
1. 1/2 integral(f, m(1), m(2)) when k == 1
2. 1/3 integral(f, m(k-1), m(k+1)) when k = 2:numel(m)-1
3. 1/2 integral(f, m(end-1), m(end)) when k = numel(m)
but according to what you wrote before, f changes with k - and that's the problem.
work wolf
2023-7-5
@Torsten Thanks for your comment. it's useful. okay, how can you vectorize these steps
1. 1/2 integral(f, m(1), m(2)) when k == 1
2. 1/3 integral(f, m(k-1), m(k+1)) when k = 2:numel(m)-1
3. 1/2 integral(f, m(end-1), m(end)) when k = numel(m)
Assume, f is not change with k , then use it within the following formula
y=zeros(size(m));
y(1)=0;
y(2:end) = y(1:end-1) + ( (1/2 *integral(f, m(1), m(2))+1/3* integral(f, m(1:end-2), m(3:end))+...
1/2 * integral(f, m(end-1), m(end)) )/m(1:end-1));
Note: by any way, you can modified any conditions to vectorize approach. I appreciate any help you can provide and useful for me. ^_^
Torsten
2023-7-5
You didn't write anything about a recursion - "array" is just made up of the numel(m) terms in your list:
f = @(x)x.^2;
m = 0:10;
array = [1/2*integral(f,m(1),m(2)),1/3*arrayfun(@(mkm1,mkp1)integral(f,mkm1,mkp1),1:numel(m)-2,3:numel(m)),1/2*integral(f,m(end-1),m(end))]
array = 1×11
0.1667 2.8889 6.2222 10.8889 16.8889 24.2222 32.8889 42.8889 54.2222 66.8889 45.1667
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Matrix Indexing 的更多信息
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 (한국어)