Skip to content

Commit 1684b74

Browse files
author
MK
committed
-
1 parent 636b5a3 commit 1684b74

File tree

2 files changed

+305
-0
lines changed

2 files changed

+305
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
# Chapter 10
2+
3+
Example 1
4+
5+
A line integral is an integral of a function along a curve in
6+
space. We usually represent the curve by a parametric equation,
7+
e.g. $\mathbf{r}(t) = [x(t), y(t), z(t)] = x(t)\mathbf{i} +
8+
y(t)\mathbf{j} + z(t)\mathbf{k}$. So, in general the curve will be a
9+
vector function, and the function we want to integrate will also be a
10+
vector function.
11+
12+
Then, we can write the line integral definition as:
13+
14+
$$
15+
\int_C \mathbf{F(r)}\cdot d\mathbf{r} =
16+
\int_a^b \mathbf{F}(\mathbf{r}(t)) \cdot \mathbf{r'}(t) dt
17+
$$
18+
19+
where $\mathbf{r'}(t) = \frac{d\mathbf{r}}{dt}$. This integrand is a
20+
scalar function, because of the dot product.
21+
22+
The following examples are adapted from Chapter 10 in Advanced
23+
Engineering Mathematics by Kreysig.
24+
25+
The first example is the evaluation of a line integral in the
26+
plane. We want to evaluate the integral of $\mathbf{F(r)}=[-y, -xy]$
27+
on the curve $\mathbf{r(t)}=[-sin(t), cos(t)]$ from t=0 to t =
28+
π/2. The answer in the book is given as 0.4521. Here we evaluate this
29+
numerically, using autograd for the relevant derivative. Since the
30+
curve has multiple outputs, we have to use the jacobian function to
31+
get the derivatives. After that, it is a simple bit of matrix
32+
multiplication, and a call to the quad function.
33+
34+
```python
35+
import autograd.numpy as np
36+
from autograd import jacobian
37+
from scipy.integrate import quad
38+
39+
def F(X):
40+
x, y = X
41+
return -y, -x * y
42+
43+
def r(t):
44+
return np.array([-np.sin(t), np.cos(t)])
45+
46+
drdt = jacobian(r)
47+
48+
def integrand(t):
49+
return F(r(t)) @ drdt(t)
50+
51+
I, e = quad(integrand, 0.0, np.pi / 2)
52+
print(f'The integral is {I:1.4f}.')
53+
```
54+
55+
```text
56+
The integral is 0.4521.
57+
```
58+
59+
We get the same result as the analytical solution.
60+
61+
The next example is in three dimensions. Find the line integral along
62+
$\mathbf{r}(t)=[cos(t), sin(t), 3t]$ of the function
63+
$\mathbf{F(r)}=[z, x, y]$ from t=0 to t=2 π. The solution is given as
64+
21.99.
65+
66+
```python
67+
import autograd.numpy as np
68+
from autograd import elementwise_grad, grad, jacobian
69+
70+
def F(X):
71+
x, y, z = X
72+
return [z, x, y]
73+
74+
def C(t):
75+
return np.array([np.cos(t), np.sin(t), 3 * t])
76+
77+
dCdt = jacobian(C, 0)
78+
79+
def integrand(t):
80+
return F(C(t)) @ dCdt(t)
81+
82+
I, e = quad(integrand, 0, 2 * np.pi)
83+
print(f'The integral is {I:1.2f}.')
84+
```
85+
86+
```text
87+
The integral is 21.99.
88+
```
89+
90+
That is also the same as the analytical solution. Note the real
91+
analytical solution was 7 π, which is nearly equivalent to our answer.
92+
93+
```python
94+
print (7 * np.pi - I)
95+
```
96+
97+
```text
98+
3.552713678800501e-15
99+
```
100+
101+
As a final example, we consider an alternate form of the line
102+
integral. In this form we do not use a dot product, so the integral
103+
results in a vector. This doesn't require anything from autograd, but
104+
does require us to be somewhat clever in how to do the integrals since
105+
quad can only integrate scalar functions. We need to integrate each
106+
component of the integrand independently. Here is one approach where
107+
we use lambda functions for each component. You could also manually
108+
separate the components.
109+
110+
```python
111+
def F(r):
112+
x, y, z = r
113+
return x * y, y * z, z
114+
115+
def r(t):
116+
return np.array([np.cos(t), np.sin(t), 3 * t])
117+
118+
def integrand(t):
119+
return F(r(t))
120+
121+
[quad(lambda t: integrand(t)[i], 0, 2 * np.pi)[0] for i in [0, 1, 2]]
122+
```
123+
124+
```text
125+
Out[1]: [-6.845005548807377e-17, -18.849555921538755, 59.21762640653615]
126+
```
127+
128+
```python
129+
[0, -6 * np.pi, 6 * np.pi**2]
130+
```
131+
132+
```text
133+
Out[1]: [0, -18.84955592153876, 59.21762640653615]
134+
```
135+
136+
which is evidently the same as our numerical solution.
137+
138+
Maybe an alternative, but more verbose is this vectorized integrate
139+
function. We still make temporary functions for integrating, and the
140+
vectorization is essentially like the list comprehension above, but we
141+
avoid the lambda functions.
142+
143+
```python
144+
@np.vectorize
145+
def integrate(i):
146+
def integrand(t):
147+
return F(r(t))[i]
148+
I, e = quad(integrand, 0, 2 * np.pi)
149+
return I
150+
151+
integrate([0, 1, 2])
152+
```
153+
154+
```text
155+
Out[1]: array([-6.84500555e-17, -1.88495559e+01, 5.92176264e+01])
156+
```
157+
158+
159+
160+
161+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
2+
<html>
3+
<head>
4+
<script type="text/x-mathjax-config">MathJax.Hub.Config({ tex2jax: {inlineMath: [["$","$"] ]}});</script>
5+
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS_HTML-full">
6+
</script>
7+
<meta charset='utf-8'>
8+
</head>
9+
<body>
10+
11+
<h1>Chapter 10</h1>
12+
<p>Example 1</p>
13+
<p>A line integral is an integral of a function along a curve in
14+
space. We usually represent the curve by a parametric equation,
15+
e.g. $\mathbf{r}(t) = [x(t), y(t), z(t)] = x(t)\mathbf{i} +
16+
y(t)\mathbf{j} + z(t)\mathbf{k}$. So, in general the curve will be a
17+
vector function, and the function we want to integrate will also be a
18+
vector function.</p>
19+
<p>Then, we can write the line integral definition as:</p>
20+
<p>$$
21+
\int_C \mathbf{F(r)}\cdot d\mathbf{r} =
22+
\int_a^b \mathbf{F}(\mathbf{r}(t)) \cdot \mathbf{r'}(t) dt
23+
$$</p>
24+
<p>where $\mathbf{r'}(t) = \frac{d\mathbf{r}}{dt}$. This integrand is a
25+
scalar function, because of the dot product.</p>
26+
<p>The following examples are adapted from Chapter 10 in Advanced
27+
Engineering Mathematics by Kreysig.</p>
28+
<p>The first example is the evaluation of a line integral in the
29+
plane. We want to evaluate the integral of $\mathbf{F(r)}=[-y, -xy]$
30+
on the curve $\mathbf{r(t)}=[-sin(t), cos(t)]$ from t=0 to t =
31+
π/2. The answer in the book is given as 0.4521. Here we evaluate this
32+
numerically, using autograd for the relevant derivative. Since the
33+
curve has multiple outputs, we have to use the jacobian function to
34+
get the derivatives. After that, it is a simple bit of matrix
35+
multiplication, and a call to the quad function.</p>
36+
<pre><code class="python">import autograd.numpy as np
37+
from autograd import jacobian
38+
from scipy.integrate import quad
39+
40+
def F(X):
41+
x, y = X
42+
return -y, -x * y
43+
44+
def r(t):
45+
return np.array([-np.sin(t), np.cos(t)])
46+
47+
drdt = jacobian(r)
48+
49+
def integrand(t):
50+
return F(r(t)) @ drdt(t)
51+
52+
I, e = quad(integrand, 0.0, np.pi / 2)
53+
print(f'The integral is {I:1.4f}.')
54+
</code></pre>
55+
56+
<pre><code class="text">The integral is 0.4521.
57+
</code></pre>
58+
59+
<p>We get the same result as the analytical solution.</p>
60+
<p>The next example is in three dimensions. Find the line integral along
61+
$\mathbf{r}(t)=[cos(t), sin(t), 3t]$ of the function
62+
$\mathbf{F(r)}=[z, x, y]$ from t=0 to t=2 π. The solution is given as
63+
21.99.</p>
64+
<pre><code class="python">import autograd.numpy as np
65+
from autograd import elementwise_grad, grad, jacobian
66+
67+
def F(X):
68+
x, y, z = X
69+
return [z, x, y]
70+
71+
def C(t):
72+
return np.array([np.cos(t), np.sin(t), 3 * t])
73+
74+
dCdt = jacobian(C, 0)
75+
76+
def integrand(t):
77+
return F(C(t)) @ dCdt(t)
78+
79+
I, e = quad(integrand, 0, 2 * np.pi)
80+
print(f'The integral is {I:1.2f}.')
81+
</code></pre>
82+
83+
<pre><code class="text">The integral is 21.99.
84+
</code></pre>
85+
86+
<p>That is also the same as the analytical solution. Note the real
87+
analytical solution was 7 π, which is nearly equivalent to our answer.</p>
88+
<pre><code class="python">print (7 * np.pi - I)
89+
</code></pre>
90+
91+
<pre><code class="text">3.552713678800501e-15
92+
</code></pre>
93+
94+
<p>As a final example, we consider an alternate form of the line
95+
integral. In this form we do not use a dot product, so the integral
96+
results in a vector. This doesn't require anything from autograd, but
97+
does require us to be somewhat clever in how to do the integrals since
98+
quad can only integrate scalar functions. We need to integrate each
99+
component of the integrand independently. Here is one approach where
100+
we use lambda functions for each component. You could also manually
101+
separate the components.</p>
102+
<pre><code class="python">def F(r):
103+
x, y, z = r
104+
return x * y, y * z, z
105+
106+
def r(t):
107+
return np.array([np.cos(t), np.sin(t), 3 * t])
108+
109+
def integrand(t):
110+
return F(r(t))
111+
112+
[quad(lambda t: integrand(t)[i], 0, 2 * np.pi)[0] for i in [0, 1, 2]]
113+
</code></pre>
114+
115+
<pre><code class="text">Out[1]: [-6.845005548807377e-17, -18.849555921538755, 59.21762640653615]
116+
</code></pre>
117+
118+
<pre><code class="python">[0, -6 * np.pi, 6 * np.pi**2]
119+
</code></pre>
120+
121+
<pre><code class="text">Out[1]: [0, -18.84955592153876, 59.21762640653615]
122+
</code></pre>
123+
124+
<p>which is evidently the same as our numerical solution.</p>
125+
<p>Maybe an alternative, but more verbose is this vectorized integrate
126+
function. We still make temporary functions for integrating, and the
127+
vectorization is essentially like the list comprehension above, but we
128+
avoid the lambda functions.</p>
129+
<pre><code class="python">@np.vectorize
130+
def integrate(i):
131+
def integrand(t):
132+
return F(r(t))[i]
133+
I, e = quad(integrand, 0, 2 * np.pi)
134+
return I
135+
136+
integrate([0, 1, 2])
137+
</code></pre>
138+
139+
<pre><code class="text">Out[1]: array([-6.84500555e-17, -1.88495559e+01, 5.92176264e+01])
140+
</code></pre>
141+
142+
</body>
143+
</html>
144+

0 commit comments

Comments
 (0)