Effacer les filtres
Effacer les filtres

Error in cumtrapz. Input arguments to function include colon operator. To input the colon character, use ':' instead.

3 vues (au cours des 30 derniers jours)
Hi
I would like to use the cumulative trapezoidal method to obtain the integral of function f with a domain [0.2, 1] with regards to x. However, it is showing errors in cumtrapz.
Any help is much appreciated! Thank you
This is my code:
syms Swi kmin kmax D muyg muyw Krgwi sat x
Swi = 0.2;
kmin = 0.1;
kmax = 1;
D = 1;
muyg = 0.1;
muyw = 1;
Krgwi = 0.7;
sat = linspace(Swi,1,100);
f =@(x)(0.5.*(kmin - kmax) + kmax - 0.5.*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi)).*(0.5.*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi))./(((muyw*Krgwi*D./muyg) .* 0.5.*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi)) + (0.5.*(kmin - kmax) + kmax -0.5.*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi))) .* (kmax - kmin)./((kmax + kmin).*(Swi - 1)*((2.*kmax - (2.*(kmax - kmin).*(sat - 1))./(Swi - 1))./(kmax + kmin)).^(3/2))./((Swi - x)./(1-Swi)) + (0.5.*(kmin - kmax) + kmax-0.5.*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi))./(((muyw*Krgwi*D./muyg).*0.5.*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi)) + (0.5.*(kmin - kmax) + kmax-0.5.*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi)));
cumtrapz(f,sat)
UPDATED: Thanks for all your help.
I'm given the function f and the goal is to take the integral of f in the domain of [0.2, 1], denoted as ksi
my goal is to plot the result of ksi in terms of x, with x ranges from 0.2 to 1. Initially I thought of the cumtrapz as the function seems difficult to perform analytically. Please correct me if I'm wrong.
  9 commentaires
Sam Chak
Sam Chak le 6 Oct 2023
Since you are working in the symbolic realm, try using int(). Let us know the result.
https://www.mathworks.com/help/symbolic/sym.int.html
Walter Roberson
Walter Roberson le 6 Oct 2023
Q = @(v) sym(v);
syms Swi kmin kmax D muyg muyw Krgwi sat f(x)
Swi = Q(0.2);
kmin = Q(0.1);
kmax = Q(1);
D = Q(1);
muyg = Q(0.1);
muyw = Q(1);
Krgwi = Q(0.7);
% sat = linspace(Swi, 1, 100);
sat = x; % assumed that "sat" is, in fact, the variable "x"
f = (Q(0.5).*(kmin - kmax) + kmax - Q(0.5).*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi)).*(Q(0.5).*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi))./(((muyw*Krgwi*D./muyg) .* Q(0.5).*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi)) + (Q(0.5).*(kmin - kmax) + kmax - Q(0.5).*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi))) .* (kmax - kmin)./((kmax + kmin).*(Swi - 1)*((Q(2).*kmax - (Q(2).*(kmax - kmin).*(sat - 1))./(Swi - 1))./(kmax + kmin)).^(Q(3)/2))./((Swi - x)./(1-Swi)) + (Q(0.5).*(kmin - kmax) + kmax-Q(0.5).*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi))./(((muyw*Krgwi*D./muyg).*Q(0.5).*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi)) + (Q(0.5).*(kmin - kmax) + kmax-Q(0.5).*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi)))
f = 
T = linspace(Swi+eps, 1, 150);
F = double(subs(f, x, T));
plot(T, F)
limit(f, x, Swi)
ans = 
NaN
vpaintegral(f, x, Swi, 1, 'MaxFunctionCalls', 1e9)
Error using sym/vpaintegral
Failed precision goal. Try using 'MaxFunctionCalls'.
At the lower end of the range, there is a 0/0 in an area that is otherwise headed to -infinity. Numeric integration is not able to get a solution with a reasonable number of calls.

Connectez-vous pour commenter.

Réponses (2)

Walter Roberson
Walter Roberson le 5 Oct 2023
Change
cumtrapz(f,sat)
to
cumtrapz(sat, f(sat))
  4 commentaires
Ivan
Ivan le 6 Oct 2023
Thank you Walter, the term sat is indeed x. Sorry as I didn't double-check it sooner
Walter Roberson
Walter Roberson le 7 Oct 2023
By the way, if you simplify(expand(f)) then you get out a notably shorter expression . However it still has the same integration characteristics. Maple says that if you start from Swi that both versions are undefined. Probably because of the singularity at 19/27 - (2*sqrt(994))/135

Connectez-vous pour commenter.


Sam Chak
Sam Chak le 5 Oct 2023
Perhaps you can learn from this example to compute the cumulative integral of univariate function, .
x = linspace(-4, 4, 8001);
f = 1./cosh(x).^2; % contains function values for f(x) = 1/cosh²(x) in the domain [-4, 4].
plot(x, f), grid on
xlabel('x'), ylabel('f(x)')
title({'$f(x) = \frac{1}{\cosh^{2}(x)}$'}, 'interpreter', 'latex', 'fontsize', 16)
g = cumtrapz(x, f); % g(x) = tanh(x) + 1
plot(x, g), grid on
xlabel('x'), ylabel('g(x)')
title({'Cumulative distribution function of $f(x)$'}, 'interpreter', 'latex', 'fontsize', 16)
  2 commentaires
Sam Chak
Sam Chak le 6 Oct 2023
As you probably already know, the function has two singularities over [0.2, 1.0]. MATLAB's integral() can evaluate and return some value. However, I am unsure whether the integral is convergent or divergent.
Swi = 0.2;
kmin = 0.1;
kmax = 1;
D = 1;
muyg = 0.1;
muyw = 1;
Krgwi = 0.7;
f = @(x) ( 0.5*(kmin - kmax) + kmax - 0.5*(kmin - kmax)*((1 - x)/(1 - Swi)).^2 + kmax*(1 - x)/(1 - Swi)).*(0.5*(kmin - kmax)*((1 - x)/(1 - Swi)).^2 + kmax*(1 - x)/(1 - Swi))./(( (muyw*Krgwi*D/muyg)*0.5*(kmin - kmax)*((1 - x)/(1 - Swi)).^2 + kmax*(1 - x)/(1 - Swi)) + (0.5*(kmin - kmax) + kmax - 0.5*(kmin - kmax)*((1 - x)/(1 - Swi)).^2 + kmax*(1 - x)/(1-Swi))) .* (kmax - kmin)./((kmax + kmin).*(Swi - 1)*((2*kmax - (2*(kmax - kmin)*(x - 1))/(Swi - 1))/(kmax + kmin)).^(3/2))./((Swi - x)/(1 - Swi)) + (0.5*(kmin - kmax) + kmax-0.5.*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax*(1 - x)./(1 - Swi))./( ( (muyw*Krgwi*D/muyg)*0.5*(kmin - kmax) .* ( (1 - x)./(1 - Swi) ).^2 + kmax*(1 - x)./(1 - Swi) ) + ( 0.5*(kmin - kmax) + kmax - 0.5*(kmin - kmax)*((1 - x)./(1 - Swi)).^2 + kmax*(1 - x)./(1 - Swi) ) );
q = integral(f, 0.2, 1.0)
Warning: Minimum step size reached near x = 0.2. There may be a singularity, or the tolerances may be too tight for this problem.
q = -1.9936e+03
x = linspace(0.2, 1.0, 801);
plot(x, f(x), 'linewidth', 1.5, 'Color', "#0437F2"), grid on
xlabel('x'), ylabel('f(x)')
Sam Chak
Sam Chak le 7 Oct 2023
The following approach employs numerical integration using vpintegral() as demonstrated by @Walter Roberson in the comment. What distinguishes it is that this variable precision-based integration evaluates from 0.2+ε to 1.0, yielding a finite value. Nevertheless, I have reservations about the accuracy of the result, given the presence of a singularity at .
Q = @(v) sym(v);
syms Swi kmin kmax D muyg muyw Krgwi sat f(x)
Swi = Q(0.2);
kmin = Q(0.1);
kmax = Q(1);
D = Q(1);
muyg = Q(0.1);
muyw = Q(1);
Krgwi = Q(0.7);
% sat = linspace(Swi, 1, 100);
sat = x; % assumed that "sat" is, in fact, the variable "x"
f = (Q(0.5).*(kmin - kmax) + kmax - Q(0.5).*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi)).*(Q(0.5).*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi))./(((muyw*Krgwi*D./muyg) .* Q(0.5).*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi)) + (Q(0.5).*(kmin - kmax) + kmax - Q(0.5).*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi))) .* (kmax - kmin)./((kmax + kmin).*(Swi - 1)*((Q(2).*kmax - (Q(2).*(kmax - kmin).*(sat - 1))./(Swi - 1))./(kmax + kmin)).^(Q(3)/2))./((Swi - x)./(1-Swi)) + (Q(0.5).*(kmin - kmax) + kmax-Q(0.5).*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi))./(((muyw*Krgwi*D./muyg).*Q(0.5).*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi)) + (Q(0.5).*(kmin - kmax) + kmax-Q(0.5).*(kmin - kmax) .* ((1 - x)./(1 - Swi)).^2 + kmax .* (1-x)./(1-Swi)))
f = 
% locating the singularities
den1 = 45/22*x - 5/22 == 0;
xs1 = vpasolve(den1) % singularity point #1
xs1 = 
0.11111111111111111111111111111111
den2 = 5/4*x - 1/4 == 0;
xs2 = vpasolve(den2) % singularity point #2
xs2 = 
0.2
den3 = 5/2*x + 27/10*(5/4*x - 5/4).^2 - 61/20 == 0;
xs3 = vpasolve(den3) % singularity point #3 & #4
xs3 = 
% plot of f(x) showing the singularities at 4 locations
fplot(f, [0 1.2])
xlabel('x'), ylabel('f(x)')
% check if limits exist near the singularities xs2 and xs3
Lxs2 = limit(f, x, xs2+eps)
Lxs2 = 
Lxs3 = limit(f, x, xs3(1))
Lxs3 = 
% numerical integration from 0.2+eps to 1.0
vpaintegral(f, x, xs2+eps, 1, 'MaxFunctionCalls', 1e9)
ans = 
Looking at the previous approach, integral(f) returns .

Connectez-vous pour commenter.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by