0

I have the code structure below. I would like to get some numerical results here.

import numpy as np
import scipy
from scipy import integrate

alpha = .99
t = np.linspace(0, .85, 5)
s = np.empty_like(t)
f = np.power(t - s, -alpha)
Int = integrate.simpson(f, s)
Int

I got the warnings below. I understand that the first term in t, that is t[0] causes the errors, particularly first two warnings. But I do not know how I can avoid these warnings. I cannot change the alpha,t or f.

<ipython-input-1-6b0d0757bfac>:8: RuntimeWarning: invalid value encountered in power
  f = np.power(t-s, -alpha)
/usr/local/lib/python3.8/dist-packages/scipy/integrate/_quadrature.py:414: RuntimeWarning: invalid value encountered in true_divide
  h0divh1 = h0 / h1
/usr/local/lib/python3.8/dist-packages/scipy/integrate/_quadrature.py:416: RuntimeWarning: invalid value encountered in true_divide
  y[slice1] * (hsum * hsum / hprod) +
nan

I tried to take t = np.linspace(1e-8, .85, 5). It did not work.

EDIT: The t is stable. I cannot change it. I need to derive s from t or find a new definition for s. So, I have

t = np.linspace(0, .85, 5)
array([0.    , 0.2125, 0.425 , 0.6375, 0.85  ])

Let us take the s as an array of zeros (array of ones also does not work for s)

s = np.zeros_like(t)
array([0., 0., 0., 0., 0.])

and add 1 to f to avoid the warning of RuntimeWarning: divide by zero encountered in power

f = (t1+1-s)** -.99
array([1.        , 0.82633295, 0.70424421, 0.61370619, 0.54387612])

After this when I used the simpson, it gives nan.

Int = integrate.simpson(f, s)
nan

Depending on the definition of s, I am constantly encountering a warning or an error .

The question is: What could be the right definition of s along with the t defined above?

Nurdan
  • 9
  • 4
  • What are you trying to achieve with that `s` array? – Guimoute Feb 26 '23 at 01:25
  • did you look at `s`? or `f` before calling `simpson`? – hpaulj Feb 26 '23 at 01:48
  • @hpaulj I have used `np.isfinite(f)`and it gave `False`. And `np.isfinite(s)` gave `True`. What did you mean by -did you look at-? Do I need to use another method to look at them? Thank you. – Nurdan Feb 26 '23 at 02:27
  • @hpaulj Oh `print(s)` also gives `nan` values as mentioned in Alexs answer. I was thinking `s` just an empty array and I aimed to overwrite it. – Nurdan Feb 26 '23 at 02:37
  • But you didn't overwrite it; you used it in `f` as is! Don't use `np.empty` unless you actually understand what it does. `np.zeros` is safer. `f` is an array, not a function. With other integrate functions you supply a function, for this you supply an array. – hpaulj Feb 26 '23 at 02:39
  • I wrote an answer showing the actual `s` and `f` produced by your code (at least for one run), and hopefully showed that this setup doesn't make sense. I won't suggest an fix, since I don't know what integral you are trying to calculate. – hpaulj Feb 26 '23 at 03:30
  • Also, you may notice that those are three warnings: you can only ever get one error, since that would imply a crash – Mad Physicist Feb 26 '23 at 03:51

2 Answers2

0

There is an issue when you are using s because you created it like this:

s = np.empty_like(t)

What you are doing here is creating an array that has the same properties as t but is uninitialised, meaning that its shape and type are the same as t but its values are not set (thus "random").

For example, when I print s I have:

array([inf, nan, nan, nan, nan])

And you could have basically any values here.

So, you need to provide values to s before using it.

If you want to initialise s to zeros, you should replace that line by:

s = np.zeros_like(t)
Alex
  • 1,368
  • 10
  • 20
0

Your first lines, and the results. With a size of 5, there's not excuse to not look at the arrays in full. No summary needed.

In [80]: alpha = .99
    ...: t = np.linspace(0, .85, 5)
    ...: s = np.empty_like(t)
    ...: f = np.power(t - s, -alpha)
C:\Users\paul\AppData\Local\Temp\ipykernel_2648\1323274646.py:4: RuntimeWarning: invalid value encountered in power
  f = np.power(t - s, -alpha)

5 equally space numbers:

In [81]: t
Out[81]: array([0.    , 0.2125, 0.425 , 0.6375, 0.85  ])

5 values as well; with empty they aren't predictable. sometimes I see 0s, but the is a good example of ridiculous "random" values. We don't want to use the s as is; it has to overwritten with something:

In [82]: s
Out[82]: 
array([6.36598737e-314, 1.90979621e-313, 8.48798317e-314, 1.69759663e-313,
       1.27319747e-313])

In [83]: f
Out[83]: array([       nan, 4.63355855, 2.33289375, 1.56158135, 1.17456015]

And the term that produced the warning (not error):

In [89]: (t[0]-s[0])
Out[89]: -6.365987374e-314
In [90]: (t[0]-s[0])**-.99
C:\Users\paul\AppData\Local\Temp\ipykernel_2648\147715877.py:1: RuntimeWarning: invalid value encountered in double_scalars
  (t[0]-s[0])**-.99
Out[90]: nan

Ekaba's suggestion:

In [91]: alpha = .99
    ...: t = np.linspace(0, .85, 5)
    ...: s = np.empty_like(t)
    ...: f = np.empty_like(t)
    ...: 
    ...: for i in range(1, len(t)):
    ...:     s[i] = t[i-1]
    ...:     f[i] = (t[i] - s[i])**(-alpha)
    ...:     

This overwrites s and f, but I'm not sure those are useful.

same 5 term t:

In [92]: t
Out[92]: array([0.    , 0.2125, 0.425 , 0.6375, 0.85  ])

s is now just t values, offset by 1. The first is still "random":

In [93]: s
Out[93]: 
array([-6.36598737e-314,  0.00000000e+000,  2.12500000e-001,
        4.25000000e-001,  6.37500000e-001])

And for f, again ignoring the first, the rest as the same:

In [94]: f
Out[94]: 
array([2.12199579e-314, 4.63355855e+000, 4.63355855e+000, 4.63355855e+000,
       4.63355855e+000])

The successive differences of t raised to -alpha:

In [96]: np.diff(t)
Out[96]: array([0.2125, 0.2125, 0.2125, 0.2125])    
In [97]: np.diff(t)**-.99
Out[97]: array([4.63355855, 4.63355855, 4.63355855, 4.63355855])

The integral is the area of a rectangle f[-1] high, and s[-1] wide:

In [104]: f[-1]*s[-1]
Out[104]: 2.953893574179393

I'm guessing the OP thought that he defined f as a function, that, simpson was going to pass successive values of s to it. Other integrate functions do take a function (e.g. quad), but this takes an array.

Simpson example

Here's an example that may be similar to what you want:

Specify an array of sample points:

In [109]: x = np.linspace(0,1,11)

and a t and f. Both are calculated from x. t adds a 1 to avoid the x=0 problem:

In [110]: t = (x+1)**2    
In [111]: f = (t-x)**-.99

Displaying the values:

In [112]: x,t,f
Out[112]: 
(array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ]),
 array([1.  , 1.21, 1.44, 1.69, 1.96, 2.25, 2.56, 2.89, 3.24, 3.61, 4.  ]),
 array([1.        , 0.90184157, 0.80818825, 0.72179746, 0.64388254,
        0.57463534, 0.51364905, 0.46021453, 0.41350815, 0.37270087,
        0.33701556]))

And the simpson integration:

In [113]: simpson(f,x)
Out[113]: 0.6073410199915571

Without plotting (or using sympy) I can only estimate whether that makes sense. The area under a curve that starts at 1 and decresses to .3, over the x range of 0 to 1 - .6 is a reasonable value.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • Thank you for the explanation. I am not looking for an area of `f[-1]*s[-1]`. It is clear that, I have been trying to calculate integrand `f`, that is, `f=(t-s)**(-alpha)` with respect to `s` (variable of the integration is `ds`) along with the `t`-dependent integration limits. On the other hand, since `t` is an array, `simpson` seems like a right choice for this calculation. I am not so sure, but I guess defining the `s` correctly is the source of the problem here. – Nurdan Feb 26 '23 at 18:12
  • I added a simpson example that is somewhat like what you describe. – hpaulj Feb 26 '23 at 21:40
  • Thank you, it was a helpful example. But you defined `x` and derived `t` from it. I have `t` and I need to derive `x` from `t` or make a new definition. I made an edit to the post about this issue. You can have an idea about the problem I encountered. – Nurdan Feb 27 '23 at 16:21
  • `t` is just an array. What's it's relation to the integration variable (`x` in my example, `s` in yours)? I don't give `simpson` `t`, I give it `f`. Abstractly, I am integrating `f(x)` over a range of values defined by `x`. `simpson` is used where that `f(x)` is defined for a discrete set of `x` values. `quad` can be used when `f` is a continuous function, that can be evaluated at any `x` in the range. In my example, `t` could have been pulled out of the air, but it still has to have one value for each `x` value. The real goal is to construct `f`, as array or function. – hpaulj Feb 27 '23 at 17:05
  • This is the point where I am stuck. What is the relationship between `t` and `s`? When expressing `s` in code, should a relationship be established between `t` and `s`, or should `s` be defined independently? If so, how should it be defined? – Nurdan Feb 27 '23 at 18:23
  • Forget about `t` for the moment. What is `f(x)`, the function that you want to integrate. Imagine for example, a graph with `x` values horizontally (between say 0 and 1). What are `y` axis values; the line that you plot? The integral is the area under that curve. It may help to imagine `t(x)`, as a continuous curve (or may piecewise linear). Defining the integration function is your job, not ours. – hpaulj Feb 27 '23 at 19:54
  • Someone else using `simpson`: https://stackoverflow.com/questions/75586614/different-results-when-computing-integral-analytically-with-scipy-vs-approximati – hpaulj Feb 28 '23 at 01:28
  • I was able to eliminate warnings and the error with a custom `s` definition. As I code the rest of my equation, I'll watch it to see if my choice for `s` is correct. Your explanations helped me a lot. Thank you. – Nurdan Feb 28 '23 at 20:11