You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
how can i use integral function with vector limits by using another for loop ?
10 views (last 30 days)
Show older comments
% 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' ?
Answers (1)
Star Strider
on 3 Jul 2023
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 Comments
work wolf
on 4 Jul 2023
Edited: work wolf
on 4 Jul 2023
@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
on 4 Jul 2023
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
on 4 Jul 2023
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
on 4 Jul 2023
@Torsten thank you so much for your time, m(k-2) will be as weight. Now, i want alternatives to using a traditional for loop for iterative operations as Vectorization, Logical Indexing or Array Functions ....ect. please can you give same result without loop or symbolic 'int'.
work wolf
on 4 Jul 2023
@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
on 4 Jul 2023
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
on 4 Jul 2023
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
on 4 Jul 2023
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
on 4 Jul 2023
Edited: work wolf
on 4 Jul 2023
@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
on 4 Jul 2023
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
on 4 Jul 2023
Edited: work wolf
on 4 Jul 2023
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
on 4 Jul 2023
Edited: Torsten
on 4 Jul 2023
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
on 5 Jul 2023
@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
on 5 Jul 2023
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
work wolf
on 5 Jul 2023
@Torsten Thanks, that is okay. what about if we assume f depended on y as,
f=@(x,y) x.*y
and y is know just at initial value as
y(1)=0
. now, we need calculate other value of y if m:0:10 by using the following formual
k=1:numel(m)-1
y(k+1)=y(k)+ integral( @(x) f , m(k-1), m(k+1) )
See Also
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- 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)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)