Why is the sum of the absolute values of np.sin(x) and np.cos(x) from 0 to 2*pi not the same?

Question:

I am trying to compute the sum of the absolute values of these two expressions, and I am somehow confused, since the sum should be the same, right?

Consider the integrals:

Integral of abs(sin(x))dx

Integral of abs(cos(x))dx

It’s easy to see, that the area underneath them is the same, and indeed both integrals return 4.

I wrote a simple script to evenly sample those functions and add all the sampled values together. Scaling aside, both expressions should yield the same result, but they dont. Here is the code:

import numpy as np
angles = np.linspace(0, 2*np.pi, 1000)
line1, line2= [], []

for n in angles:
    line1.append(np.abs(np.cos(n)))
    line2.append(np.abs(np.sin(n)))

print(sum(line1), sum(line2))

The result is the following:

636.983414656738 635.9826284722284

The sums are off by almost exactly 1. I know that they are not 4, because there is some constant factor missing, but the point is, that the values should be the same. Am I completly missing something here or is this a bug?

Asked By: Simon

||

Answers:

Because your integral method, a simple "sum", has systematic errors that cannot be ignored for this case.

Now try this:

import numpy as np
angles = np.linspace(0, 2*np.pi, 1000)
line1, line2= [], []

for n in angles:
    line1.append(np.abs(np.cos(n)))
    line2.append(np.abs(np.sin(n)))

i1=np.trapz(line1,angles)
i2=np.trapz(line2,angles)
print(i1,i2,abs(2*(i1-i2)/(i1+i2)))

The result is:

4.000001648229352 3.9999967035417043 1.2361721666315376e-06
Answered By: Ligon Liu

Consider the extreme case of reducing the samples to 3:

In [93]: angles = np.linspace(0, 2*np.pi, 3)
In [94]: angles
Out[94]: array([0.        , 3.14159265, 6.28318531])
In [95]: np.cos(angles)
Out[95]: array([ 1., -1.,  1.])
In [96]: np.sin(angles)
Out[96]: array([ 0.0000000e+00,  1.2246468e-16, -2.4492936e-16])

The extra 1 for cos persists for larger samples.

In [97]: angles = np.linspace(0, 2*np.pi, 1001)
In [98]: np.sum(np.abs(np.cos(angles)))
Out[98]: 637.6176779711009
In [99]: np.sum(np.abs(np.sin(angles)))
Out[99]: 636.6176779711009

But if we tell it to skip the 2*np.pi end point, the values match:

In [100]: angles = np.linspace(0, 2*np.pi, 1001, endpoint=False)
In [101]: np.sum(np.abs(np.cos(angles)))
Out[101]: 637.256653677874
In [102]: np.sum(np.abs(np.sin(angles)))
Out[102]: 637.2558690641631
Answered By: hpaulj