3

如果你们中的某个人可以帮助我或指出我正确的方向,那就太好了。

我有以下公式,其中每个主题有 8 个不同的参数。该等式描述了一种增长模式,即t时间和y增长。m1tom8是每个主题的不同参数

y = m1*(1-1/(1+(m2*(t+m8))^m5+(m3*(t+m8))^m6+(m4*(t+m8))^m7))

我想做的是插入这个公式并计算(数字)速度曲线。从这些信息中,我想获得以下信息

  • 当时的最大速度和相应的年龄和身高
  • 达到最大速度之前的最小速度。

这样我就可以列出我所有的科目及其参数,然后就可以收到我的结果了?

我完全没有编程和数学方面的背景,但我希望能够做到这一点。我有 matlab 供我使用。我试图弄清楚事情是如何运作的,但我无法抓住它。作为一名生物学家,我明年将学习编程课程;-)

你们中的任何人都可以帮助我吗?

谢谢

更新但仍然不存在(感谢你们:-))

-我制作了一个从 excel 派生的制表符分隔文件,并具有以下结构列 A:主题 B 到 I 列的 ID:不同参数 m1 ... m8 的值(如等式中)每行是一个不同的主题有不同的参数

  • 我选择了导入选择和下一个生成功能(或者我应该选择生成脚本)。

  • 如果我打开它,我会看到一个新的编号选项卡出现。第一行是 afunction[ID,m1,...,m8]=importfile。然后按照 112 行。

  • 我已经复制了 dan 从第 113 行开始给出的文本(感谢 dan)。

    tmin=0;tmax=20;dt=1/12;t=timn:dt:tmax;y = m1。( 1-1./(1+(m2.(t+m8)).^m5+(m3.(t+m8)).^m6+(m4.(t+m8)).^m7 ) );dy=diff(y)./dt; 最大(dy);分钟(dy);imax=find(dy==max(dy))+1; imin=find(dy==min(dy))+1; t(最大);t(最小);y(imax); y(imin);

    • 接下来我点击运行并被要求保存我已经完成的文件。
    • 现在我再次单击运行,但出现错误

谁能指出我正确的方向?非常感谢

问候

4

3 回答 3

1

First, here's a copy-pastable solution. The rest of my answer is the explanation :)

(You'll need FindRealRoots from the FEX to run this).

trange = [tstart tend] % <your range in t>

% define all intermediate functions
a = m2^m5;
b = m3^m6;
c = m4^m7;
X = @(t) t(:).' + m8;

g   = @(t) 1 + [a b c] * bsxfun(@power, X(t), [m5; m6; m7]);
gp  = @(t) ([m5 m6 m7].*[a b c]) * bsxfun(@power, X(t), [m5-1; m6-1; m7-1]);
gpp = @(t) (([m5 m6 m7]-1).*[m5 m6 m7].*[a b c]) * ...
           bsxfun(@power, X(t), [m5-1; m6-1; m7-1]);
sgn = @(t) m1*(2*(gp(t)).^2 - g(t).^2*gpp(t) );

y   = @(t) m1*(1 + 1./g(t));   
yp  = @(t) -m1*gp(t) ./ g(t).^2;

% Find the roots of the derivative
R = FindRealRoots(gp, tstart , tend, 2*ceil(max([m5 m6 m7])));

% values at end-points
y0   = y(tstart);
yend = y(tend);

% if we have some roots, separate minima/maxima and sort
if ~isempty(R)

    extrema = y(R);
    signs   = sgn(R);

    % Find maximum
    [maximum, Imax] = max(extrema(signs < 0));
    tmax = R(Imax);

    if isempty(tmax) % no maximum in interval; use endpoint
        [~,ind] = max([y0, yend]);
        tmax = trange(ind);
    end

    ymax = y(tmax);


    % Find minimum *before* maximum
    [minima, Imin] = extrema(signs > 0); 
    tmin = R(Imin);

    if isempty(tmin) % no minimum on interval; use endpoint
        [~,ind] = min([y0, yend]);
        tmin = trange(ind);
    end

    if any(tmin < tmax)
        % make sure to take only one minimum; the one 
        % just before the maximum
        tmin = tmin(find(tmin < tmax, 1, 'last')); 
    else
        [~,ind] = min([y0, yend]);  % no minima before the maximum; use end-point
        tmin = trange(ind);
    end

    ymin = y(tmin);


else % no roots found; just order the end-points

    [ymax,ind] = max([y0, yend]); 
    tmax = trange(ind);

    [ymin,ind] = min([y0, yend]); 
    tmin = trange(ind);

end

Now, the explanation.

While the answer by Dan is a nice first step, I feel I must correct it in a few places.

For starters, numerical derivatives are computed as Dan describes them only when

  • you have gridded data (the value of y(t) at a number of distinct points t)
  • It is known that the underlying model function y(t) does not allow for interpolation

And this is simply not true in your case. When you have an explicit function that you can evaluate at any arbitrary point, numerical derivatives are best computed using finite differences, and normally only when explicit derivatives cannot be found analytically.

As an example, the numerical derivative of z = cos(x) at x = π/4 (using central differences with h = 0.001):

  z'(π/4) ≅ ( z(x+h)-z(x-h) ) / 2h                      
          = ( cos(π/4 + 0.001) - cos(π/4 - 0.001) ) / 0.002
          = -0.7071066633353995...
-sin(π/4) = -0.7071067811865475...   (value of analytical derivative)

Having said that, we move on to the more important point; the mathematics can be progressed way further than Dan did, before you have to resort to numerical methods. Doing so will perhaps be more tedious, but it will improve your understanding of the problem, of MATLAB, mathematics, and it will improve the accuracy and robustness of the outcomes.

For your function y = f(t), you state you have 3 objectives:

  1. Find the velocity curve
  2. Find the maximum y(tmax) = ymax
  3. Find the minimum ymin, tmin that occurs before the maximum ymax

When translated into mathematical lingo:

  1. Find the derivative y' = dy/dt
  2. (and 3.) Find all roots R of y' and evaluate y and y'' at all R, and also y at the initial time t0.

Let's start with objective 1. You have an explicit function of time y = f(t), which is basically a variant form of a rational function,

    y(t) = a + f(t)/g(t)  

For brevity, let's just drop the (t)-part. That's much easier to write, and it's understood that y, f and g all depend on t. So,

y = a + f/g

You have the advantage that f(t) = <constant> = a = m1, which facilitates things later on. The expression for the derivative of this kind of function takes this form (which is the quotient rule):

y' = (f'·g - f·g') / g²

and, since f(t) = m1 = <constant>, its derivative with respect to time is zero:

y' = -m1·g' / g²

Now, we need to find the derivative of g. The function g is the polynomial

g = 1 + (m2·(t+m8))m5+ (m3·(t+m8))m6+ (m4·(t+m8))m7

Let's define X = t + m8, a = m2m5, b = m3m6 and c = m4m7. With this, g will look a lot less scary:

g = 1 + a·Xm5+ b·Xm6+ c·Xm7

Differentiation of polynomials follows the elementary power rule (and chain rule, but that's not really relevant here because X' = 1):

g' = m5·a·Xm5-1+ m6·b·Xm6-1+ m7·c·Xm7-1

and therefore,

y' = -m1·g' / g² = -m1 · (m5·a·Xm5-1+ m6·b·Xm6-1+ m7·c·Xm7-1) / (1 + a·Xm5+ b·Xm6+ c·Xm7

Objective 1 accomplished! You can now evaluate the velocity curve anywhere with full accuracy. Here's how to implement this function in MATLAB:

a = m2^m5;
b = m3^m6;
c = m4^m7;
X = @(t) t + m8;
dydt = @(t) -m1*( [m5*a m6*b m7*c]*X(t).^[m5-1; m6-1; m7-1] ) ./ ...
            ( 1 + [a b c]*X(t).^[m5; m6; m7] ).^2;

Now objective 2:

  1. find all the roots of y' = 0.
  2. evaluate y on these roots
  3. evalate y'' on these roots
  4. evaluate y on the end-points of the t-interval

Step 3. is necessary to determine whether a root R of y' = 0 describes a maximum or a minimum of y. In case y''(R) < 0, you are dealing with a maximum, in case y'' > 0, a minimum, and y''(R) = 0 you are dealing with an inflection point, which you may safely ignore for this problem.

Step 4. is necessary, because there may be cases where before the maximum, there is no minimum in the function, until way beyond the end point. in that case, the end point itself is the minimum you should use.

Now, step 1. If you look at the general shape of this equation,

y' = -m1·g' / g² = 0

it should be obvious that this is only possible if g' = 0. Therefore, we have to solve

g' = 0  => 

m5·a·Xm5-1+ m6·b·Xm6-1+ m7·c·Xm7-1= 0

And it is only now that we are getting stuck with our mathematical progress. There is one trivial solution to this equation (X = 0 (t = -m8)). However, there is only a general solution for specific values of the parameters m5-7. For all the other values of those parameters, no general solution exists and you'll have to find solutions numerically.

Therefore, I will recommend you to use

For step 3, you repeat the process of taking derivatives one more time;

   y'  = -m1·g' / g²
=> y'' = m1·( 2·(g')² - g²·g'' ) / (g²)²

where

g'' = (m5-1)·m5·a·Xm5-2+ (m6-1)·m6·b·Xm6-2+ (m7-1)·m7·c·Xm7-2. Note that you just need the sign of this, so only the numerator will suffice),

sgn(y'') = sgn( m1·( 2·(g')² - g²·g'' ) )

Here's how to do that in MATLAB:

g   = @(t) 1 + [a b c]*X(t).^[m5; m6; m7];
gp  = @(t) ([m5 m6 m7].*[a b c]) * X(t).^[m5-1; m6-1; m7-1];
gpp = @(t) (([m5 m6 m7]-1).*[m5 m6 m7].*[a b c]) * X(t).^[m5-1; m6-1; m7-1];
sgn = @(t) m1*(2*(gp(t)).^2 - g(t).^2*gpp(t) );

Then, with all roots R found previously, you just evaluate everything:

extrema = y(R);
signs   = sgn(R);
y0      = y(t0);

Now that you have all roots, all values of y at the roots and end-points, and all signs of the second derivative as well....

Objective 2 accomplished!

于 2013-06-06T06:56:03.533 回答
1

如果你的方程是这样的形式:y = f(t,...,... ...)并且所有其他参数在每个主题的所有时间内都保持不变,那么你可以这样做。

首先确定一个时间范围(所以我会选择 10 年,但这完全取决于你的工作):

tmin = 0;
tmax = 10;

然后你必须选择一个时间分辨率(我已经选择了每月,但你可能想要更好的东西):

dt = 1/12;

现在创建一个t向量并以数字方式求解y

t = timn:dt:tmax;
y = m1.*(1-1./(1+(m2.*(t+m8)).^m5+(m3.*(t+m8)).^m6+(m4.*(t+m8)).^m7));

一阶数值微分只是找到 的每两个连续点之间的斜率y。IE(y(i) - y(i - 1)) / (t(i) - t(i - 1))并注意t(i) - t(i - 1)始终等于dt. 所以在matlab中我们可以这样做:

dy = diff(y)./dt;

但现在dy比现在少了一个元素dt。请记住这一点。

所以要找到最大和最小速度:

max(dy);
min(dy);

并找到相应的时间和高度:

imax = find(dy==max(dy)) + 1;
imin = find(dy==min(dy)) + 1;

t(imax);
t(imin);
y(imax);
y(imin);
于 2013-06-05T14:31:47.323 回答
1

以及你的问题有点笼统,我只能提供一些在哪里看的指针。

  • 对于您可以存储在[function][1]或中的公式[function handle][2] - 还有一个您可以使用的符号数学工具箱(在这种情况下,您可以使用符号微分来查找极值)

  • 接下来基本上是循环(请参阅forwhile) - 将取决于您如何将数据读入 matlab。

  • 最后是找到极值(我想你不知道它们的确切时间) - 查找fmin数字最小化的命令(用于最小值 - 但对于最大值,只需使用-你的函数作为目标) - 如果有几个你可能需要玩一下它的设置。

  • 不要忘记一些输出。我觉得xlswrite最舒服。但是帮助会为您指出替代方案。


作为旁注,您应该尝试手动进行区分以检查您应该期望多少解决方案。

于 2013-06-05T14:38:31.257 回答