text:
Calculus/Vector Functions

Introduction
If we have a function $$\vec{f}:\R\to\R^n$$, we say that $$\vec{f}$$'s image (the set $$\Big\{\vec{f}(t)\Big|t\in\R\Big\}$$ - or some subset of $$\R$$) is a curve in $$\R^n$$ and $$\vec{f}$$ is its parametrization.

Parameterizations are not necessarily unique - for example, $$\vec{f}(t)=(\cos(t),\sin(t))$$ such that $$t\in[0,2\pi)$$ is one parametrization of the unit circle, and $$\vec{g}(t)=(\cos(at),\sin(at))$$ such that $$t\in\left[0,\frac{2\pi}{a}\right)$$ is a whole family of parameterizations of that circle.

Collision and intersection points
Say we have two different curves. It may be important to consider
 * points the two curves share - where they intersect
 * intersections which occur for the same value of $$t$$ - where they collide.

Intersection points
Firstly, we have two parameterizations $$\vec{f}(t)$$ and $$\vec{g}(t)$$, and we want to find out when they intersect, this means that we want to know when the function values of each parametrization are the same. This means that we need to solve
 * $$\vec{f}(t)=\vec{g}(s)$$

because we're seeking the function values independent of the times they intersect.

For example, if we have $$\vec{f}(t)=(t,3t)$$ and $$\vec{g}(t)=(t,t^2)$$, and we want to find intersection points:
 * $$\vec{f}(t)=\vec{g}(s)$$
 * $$(t,3t)=(s,s^2)$$
 * $$t=s\ ,\ 3t=s^2$$

with solutions $$(t,s)=(0,0)\ ,\ (3,9)$$

So, the two curves intersect at the points $$(0,0)\ ,\ (3,9)$$.

Collision points
However, if we want to know when the points "collide", with $$\vec{f}(t)$$ and $$\vec{g}(t)$$, we need to know when both the function values and the times are the same, so we need to solve instead
 * $$\vec{f}(t)=\vec{g}(t)$$

For example, using the same functions as before, $$\vec{f}(t)=(t, 3t)$$ and $$\vec{g}(t)=(t,t^2)$$, and we want to find collision points:
 * $$\vec{f}(t)=\vec{g}(t)$$
 * $$(t,3t)=(t,t^2)$$
 * $$t=t\ ,\ 3t=t^2$$

which gives solutions $$t=0,3$$ So the collision points are $$(0,0)\ ,\ (3,9)$$.

We may want to do this to actually model physical problems, such as in ballistics.

Intersection vector functions
We can also use vector functions to represent the curve of intersection of two surfaces. For example, we want to know the curve of intersection of the cylinder $$x^2+y^2=1$$ and the plane $$y+z=2$$. Vector functions rely on parameterizations, so we can rewrite the equation of the cylinder into: $$\cos^2 t+\sin^2 t=1$$, where $$x=\cos t,y=\sin t$$.

From the equation of the plane, we know that $$z=2-y=2-\sin t$$. Thus the corresponding vector equation is:

$$\mathbf{r}(t)=\langle \cos t,\sin t,2-\sin t\rangle$$

Limits and Continuity
The limit of a vector function $$\mathbf{r}$$ is defined by taking the limits of its component functions.

And the requirement for continuity is also simple:"A vector function $\mathbf{r}$ is continuous at $a$ if $\lim_{t\rightarrow a}\mathbf{r}(t)=\mathbf{r}(a)$."

Differentiation
Recall that the first derivative of a scalar function $$f(x)$$ is defined as:"$f'(x)=\lim_{\Delta x\rightarrow 0}\frac{f(x+\Delta x)-f(x)}{\Delta x}$"The first derivative of a vector function $$\mathbf{r}(t)$$ is defined in much the same way:"$\mathbf{r}'(t)=\lim_{\Delta t\rightarrow 0}\frac{\mathbf{r}(t+\Delta t)-\mathbf{r}(t)}{\Delta t}$"We can use this definition to prove that the derivative of a vector function can be presented as the derivative of its component functions. $$\begin{align} \mathbf{r}'(t) & = \lim_{\Delta t\rightarrow 0}\frac{1}{\Delta t}[\mathbf{r}(t+\Delta t)-\mathbf{r}(t)] \quad \text{definition}\\ & = \lim_{\Delta t\rightarrow 0}\frac{1}{\Delta t}[\langle f(t+\Delta t),g(t+\Delta t),h(t+\Delta t)\rangle-\langle f(t),g(t),h(t) \rangle] \quad \text{component form}\\ & = \lim_{\Delta t\rightarrow 0}\langle \frac{f(t+\Delta t)-f(t)}{\Delta t},\frac{g(t+\Delta t)-g(t)}{\Delta t},\frac{h(t+\Delta t)-h(t)}{\Delta t}\rangle \quad\text{vector addition and multiplication}\\ & = \langle \lim_{\Delta t\rightarrow 0}\frac{f(t+\Delta t)-f(t)}{\Delta t},\lim_{\Delta t\rightarrow 0}\frac{g(t+\Delta t)-g(t)}{\Delta t},\lim_{\Delta t\rightarrow 0}\frac{h(t+\Delta t)-h(t)}{\Delta t}\rangle\quad\text{definition}\\ & = \langle f'(t),g'(t),h'(t)\rangle \quad\text{definition}\\ \end{align} $$ Thus, using the same method, we can derive the second derivative and so on. So the $$n$$th-order derivative should look like this:"$\mathbf{r}^{(n)}(t)=\langle f^{(n)}(t),g^{(n)}(t),h^{(n)}(t)\rangle$"

Differentiation rules
Just like real-valued functions, there are some differentiation rules in the world of vector functions. The factor that makes vector differentiation rules slight more complicated is the product rule because there are two kinds of multiplication in vectors: dot product and cross product.

Naturally, we will prove that those rules are correct. Let us assume that $$\mathbf{u}(t)=\langle f_1(t),f_2(t),f_3(t)\rangle$$ and $$\mathbf{v}(t)=\langle g_1(t),g_2(t),g_3(t)\rangle$$.

Rule 1: the addition rule $$\begin{align} \frac{d}{dt}[\mathbf{u}(t)+\mathbf{v}(t)] & = \frac{d}{dt}[\langle f_1(t),f_2(t),f_3(t)\rangle+\langle g_1(t),g_2(t),g_3(t)\rangle]\quad \text{component form} \\ & = \frac{d}{dt}\langle f_1(t)+g_1(t),f_2(t)+g_2(t),f_3(t)+g_3(t)\rangle \quad \text{vector addition}\\ & = \langle \frac{d}{dt}(f_1(t)+g_1(t)),\frac{d}{dt}(f_2(t)+g_2(t)),\frac{d}{dt}(f_3(t)+g_3(t))\rangle \quad\text{distribution}\\ & = \langle f_1'(t)+g_1'(t),f_2'(t)+g_2'(t),f_3'(t)+g_3'(t)\rangle\quad\text{addition rule for real-valued functions}\\ & = \langle f_1'(t),f_2'(t),f_3'(t)\rangle+\langle g_1'(t),g_2'(t),g_3'(t)\rangle\quad\text{vector addition}\\ & = \mathbf{u}'(t)+\mathbf{v}'(t)\quad\text{vector form}\\ \end{align}$$ Rule 2: the scalar multiplication rule $$\begin{align} \frac{d}{dt}[f(t)\mathbf{u}(t)] & = \frac{d}{dt}[f(t)\begin{pmatrix} f_1(t)\\f_2(t)\\f_3(t)\end{pmatrix}]\quad\text{component form}\\ & = \frac{d}{dt}\begin{pmatrix} f(t)f_1(t)\\f(t)f_2(t)\\f(t)f_3(t)\end{pmatrix}\quad\text{scalar multiplication}\\ & = \begin{pmatrix} \frac{d}{dt}(f(t)f_1(t))\\ \frac{d}{dt}(f(t)f_2(t))\\ \frac{d}{dt}(f(t)f_3(t))\\ \end{pmatrix}\quad\text{distribution}\\ & = \begin{pmatrix} f'(t)f_1(t)+f(t)f_1'(t)\\ f'(t)f_2(t)+f(t)f_2'(t)\\ f'(t)f_3(t)+f(t)f_3'(t)\\ \end{pmatrix}\quad\text{multiplication rule for real-valued functions}\\ & = \begin{pmatrix} f'(t)f_1(t)\\f'(t)f_2(t)\\f'(t)f_3(t)\end{pmatrix}+ \begin{pmatrix} f(t)f_1'(t)\\f(t)f_2'(t)\\f(t)f_3'(t)\end{pmatrix}\quad\text{vector addition}\\ & = f'(t)\begin{pmatrix} f_1(t)\\f_2(t)\\f_3(t)\end{pmatrix}+f(t)\begin{pmatrix} f_1'(t)\\f_2'(t)\\f_3'(t)\end{pmatrix}\quad\text{scalar multiplication}\\ & = f'(t)\mathbf{u}(t)+f(t)\mathbf{u}'(t)\quad\text{vector form}\\ \end{align}$$ Rule 3: the dot product rule $$\begin{align} \frac{d}{dt}[\mathbf{u}(t)\cdot\mathbf{v}(t)] & = \frac{d}{dt}[\langle f_1(t),f_2(t),f_3(t)\rangle \cdot \langle g_1(t),g_2(t),g_3(t)\rangle]\quad\text{component form}\\ & = \frac{d}{dt}(f_1(t)g_1(t)+f_2(t)g_2(t)+f_3(t)g_3(t))\quad\text{dot product}\\ & = \frac{d}{dt}\sum_{i=1}^3f_i(t)g_i(t)\quad\text{simplification}\\ & = \sum_{i=1}^3\frac{d}{dt}f_i(t)g_i(t)\quad\text{distribution}\\ & = \sum_{i=1}^3[f_i'(t)g_i(t)+f_i(t)g_i'(t)]\quad\text{multiplication rule for real-valued functions}\\ & = \sum_{i=1}^3f_i(t)g_i(t)+\sum_{i=1}^3f_i(t)g_i'(t)\quad\text{vector addition}\\ & = \mathbf{u}'(t)\cdot\mathbf{v}(t)+\mathbf{u}(t)\cdot\mathbf{v}'(t)\quad\text{vector form}\\ \end{align}$$ Rule 4: the cross product rule $$\begin{align} \frac{d}{dt}[\mathbf{u}(t)\times\mathbf{v}(t)] & = \frac{d}{dt}[\langle f_1(t),f_2(t),f_3(t)\rangle\times\langle g_1(t),g_2(t),g_3(t)\rangle]\quad\text{component form}\\ & = \frac{d}{dt}\begin{vmatrix} \mathbf{\hat{i}} & \mathbf{\hat{j}} & \mathbf{\hat{k}} \\ f_1(t) & f_2(t) & f_3(t) \\ g_1(t) & g_2(t) & g_3(t) \\ \end{vmatrix}\quad\text{cross product}\\ & = \frac{d}{dt}\begin{pmatrix} f_2(t)g_3(t)-f_3(t)g_2(t)\\ f_3(t)g_1(t)-f_1(t)g_3(t)\\ f_1(t)g_2(t)-f_2(t)g_1(t)\\ \end{pmatrix}\quad\\ & = \begin{pmatrix} \frac{d}{dt}(f_2(t)g_3(t)-f_3(t)g_2(t))\\ \frac{d}{dt}(f_3(t)g_1(t)-f_1(t)g_3(t))\\ \frac{d}{dt}(f_1(t)g_2(t)-f_2(t)g_1(t))\\ \end{pmatrix}\quad\text{distribution}\\ & = \begin{pmatrix} f_2'(t)g_3(t)+f_2(t)g_3'(t)-f_3'(t)g_2(t)-f_3(t)g_2'(t)\\ f_3'(t)g_1(t)+f_3(t)g_1'(t)-f_1'(t)g_3(t)-f_1(t)g_3'(t)\\ f_2'(t)g_3(t)+f_2(t)g_3'(t)-f_3'(t)g_2(t)-f_3(t)g_2'(t)\\ \end{pmatrix}\quad\text{multiplication rule for real-valued functions}\\ & = \begin{pmatrix} f_2'(t)g_3(t)-f_3'(t)g_2(t)+f_2(t)g_3'(t)-f_3(t)g_2'(t)\\ f_3'(t)g_1(t)-f_1'(t)g_3(t)+f_3(t)g_1'(t)-f_1(t)g_3'(t)\\ f_2'(t)g_3(t)-f_3'(t)g_2(t)+f_2(t)g_3'(t)-f_3(t)g_2'(t)\\ \end{pmatrix}\quad\text{rearrangement}\\ & = \begin{pmatrix} f_2'(t)g_3(t)-f_3'(t)g_2(t)\\f_3'(t)g_1(t)-f_1'(t)g_3(t)\\f_2'(t)g_3(t)-f_3'(t)g_2(t)\\\end{pmatrix}+ \begin{pmatrix} f_2(t)g_3'(t)-f_3(t)g_2'(t)\\f_3(t)g_1'(t)-f_1(t)g_3'(t)\\f_2(t)g_3'(t)-f_3(t)g_2'(t)\\\end{pmatrix}\quad\text{vector addtion}\\ & = \begin{vmatrix} \mathbf{\hat{i}} & \mathbf{\hat{j}} & \mathbf{\hat{k}} \\ f_1'(t) & f_2'(t) & f_3'(t) \\ g_1(t) & g_2(t) & g_3(t) \\\end{vmatrix}+\begin{vmatrix} \mathbf{\hat{i}} & \mathbf{\hat{j}} & \mathbf{\hat{k}} \\ f_1(t) & f_2(t) & f_3(t) \\ g_1'(t) & g_2'(t) & g_3'(t) \\ \end{vmatrix}\quad\text{cross product}\\ & = \begin{pmatrix} f_1'(t) \\ f_2'(t) \\ f_3'(t)\\\end{pmatrix}\times\begin{pmatrix} g_1(t) \\ g_2(t) \\ g_3(t) \\\end{pmatrix}+ \begin{pmatrix} f_1(t) \\ f_2(t) \\ f_3(t)\\\end{pmatrix}\times\begin{pmatrix} g_1'(t) \\ g_2'(t) \\ g_3'(t) \\\end{pmatrix}\quad\\ & = \mathbf{u}'(t)\times\mathbf{v}(t)+\mathbf{u}(t)\times\mathbf{v}'(t)\quad\text{vector form}\\ \end{align}$$ Rule 5: the chain rule $$\begin{align} \frac{d}{dt}[\mathbf{u}(f(t))] & = \frac{d}{dt}\begin{pmatrix} f_1(f(t)) \\ f_2(f(t)) \\ f_3(f(t)) \\\end{pmatrix}\quad\text{component form}\\ & = \begin{pmatrix} \frac{d}{dt}f_1(f(t)) \\ \frac{d}{dt}f_2(f(t)) \\ \frac{d}{dt}f_3(f(t)) \\\end{pmatrix}\quad\text{distribution}\\ & = \begin{pmatrix} f'(t)f_1'(f(t)) \\ f'(t)f_2'(f(t)) \\ f'(t)f_3'(f(t)) \\\end{pmatrix}\quad \text{chain rule for real-valued functions}\\ & = f'(t)\begin{pmatrix} f_1'(f(t)) \\ f_2'(f(t)) \\ f_3'(f(t)) \\\end{pmatrix}\quad\text{scalar multiplication}\\ & = f'(t)\mathbf{u}'(f(t))\quad\text{vector form}\\ \end{align}$$ $$\blacksquare$$

Angle between curves
We can then formulate the concept of the angle between two curves by considering the angle between the two tangent vectors. If two curves, parametrized by $$\vec{f_1}$$ and $$\vec{f_2}$$ intersect at some point, which means that
 * $$\vec{f_1}(s)=\vec{f_2}(t)=c$$

the angle between these two curves at $$c$$ is the angle between the tangent vectors $$\vec{f_1'}(s)$$ and $$\vec{f_2'}(t)$$, using the dot product, is given by
 * $$\arccos\left(\frac{\vec{f_1'}(s)\cdot\vec{f_2'}(t)}{\Big\|\vec{f_1'}(s)\Big\|\Big\|\vec{f_2'}(t)\Big\|}\right)$$

Integration
Similar to real-valued functions, the definite integral of a vector function $$\mathbf{r}(t)$$ is defined as: $$\begin{align} \int_a^b\mathbf{r}(t)dt & = \lim_{n\rightarrow\infty}\sum_{i=1}^n\mathbf{r}(t_i^*)\Delta t \\ & = \lim_{n\rightarrow\infty}\biggl[\biggl(\sum_{i=1}^nf(t_i^*)\Delta t\biggr)\mathbf{i}+\biggl(\sum_{i=1}^ng(t_i^*)\Delta t\biggr)\mathbf{j}+\biggl(\sum_{i=1}^nh(t_i^*)\Delta t\biggr)\mathbf{k}\biggr]\\ & = \biggl(\int_a^bf(t)dt\biggr)\mathbf{i}+\biggl(\int_a^bg(t)dt\biggr)\mathbf{j}+\biggl(\int_a^bh(t)dt\biggr)\mathbf{k} \end{align} $$ We can extend the Fundamental Theorem of Calculus to continuous vector functions as follows:

For indefinite integrals, the definition is:"$\int\mathbf{r}(t)dt=\biggl(\int f(t)dt\biggr)\mathbf{i}+\biggl(\int g(t)dt\biggr)\mathbf{j}+\biggl(\int h(t)dt\biggr)\mathbf{k}+\mathbf{C} $"

Arc length
Recall that in Chapter, we deduced the length of a curve with parametric equations $$\begin{cases} x=f(t) \\ y=g(t) \end{cases} $$, $$a\le t\le b $$ should be:"$L=\int_a^b\sqrt{\biggl(\frac{dx}{dt}\biggr)^2+\biggl(\frac{dy}{dt}\biggr)^2}dt $"Since vector functions are fundamentally parametric equations with directions, we can utilize the formula above into the length of a space curve.

For those who prefer simplicity, the formula can be rewritten into:"\mathbf{r}'(t)"

Reparametrization
Suppose that there is a vector function which describes the displacement of a particle with respect to time and has the equation:"$\mathbf{r}(t)=\cos t\ \mathbf{i}+\sin t\ \mathbf{j}+t\ \mathbf{k} $"However, for some reason, we do not want to know the displacement of this particle with respect to time. Instead, we want to know its displacement with respect to its traveled distance ($$s $$) from $$(1,0,0) $$ in the direction of increasing $$t $$. In order to do so, we need to find a way to describe time as a function of distance. In other words, we need to find $$t=t(s) $$. We can use the formula for the arc length to establish the relationship between time and distance because arc length in this case describes the distance traveled by the particle.

Before we start calculating, we need to introduce the arc length function.

According to the definition, the arc length function for our curve $$\mathbf{r}(t) $$ should be $$s(t)=\int_0^t|\mathbf{r}'(u)|du=\int_0^t\sqrt{(-\sin u)^2+(\cos u)^2+1^2}du=\sqrt{2}u\bigg]_0^t=\sqrt{2}t $$

Note that $$a=0 $$ because the initial point $$(1,0,0) $$ corresponds to the parameter value $$t=0 $$. Since it is in the direction of increasing $$t $$, the integration direction should be from $$0 $$ to $$t $$.

$$t(s)=\frac{s}{\sqrt{2}} $$ Then we substitute the original function and get the answer:"$\mathbf{r}(s)=\cos \frac{s}{\sqrt{2}}\ \mathbf{i}+\sin \frac{s}{\sqrt{2}}\ \mathbf{j}+\frac{s}{\sqrt{2}}\ \mathbf{k} $|undefined"Reparametrization has important applications in real life because sometimes we want to know a value with respect to different variables. In this case, instead of describing the path of a particle with respect to time, we described its path with respect to its distance, which will be very useful in certain situations.

Terminology
Before we start discussing curvature, there are some important vectors and concepts we need to be at least aware of.

The unit tangent vector
In the differentiation section of this chapter, we discussed the derivatives of a vector function. We know that $$\mathbf{v}(t)=\mathbf{r}'(t)$$ at $$t=t_0$$ is tangent to the curve $$\mathbf{r}(t)$$ at $$t=t_0$$. $$\mathbf{r}'(t)$$ is called the tangent vector. The unit tangent vector, however, eliminates the aspect of magnitude because it is defined as:"\mathbf{r}'(t)"As we can see, the magnitude of the unit tangent vector is always $$1$$. We can imagine that $$\mathbf{r}(t)$$ as the displacement of a particle with respect to time. So, the unit tangent vector can be perceived as the direction of the velocity of the particle with respect to time. It can also be perceived as the direction of the tangential acceleration of the particle with respect to time. We will discuss motion in space in the next section, but this is a useful method to intuitively understand some vectors.

The unit normal vector
The unit normal vector is defined as"\mathbf{T}'(t)"The unit normal is orthogonal to the unit tangent because since $$|\mathbf{T}(t)|=1$$, we can get that: $$\frac{d}{dt}|\mathbf{T}(t)|^2=0=\frac{d}{dt}[\mathbf{T}(t)\cdot\mathbf{T}(t)]=2\mathbf{T}'(t)\cdot\mathbf{T}(t)$$

$$\Leftrightarrow \mathbf{T}'(t)\cdot\mathbf{T}(t)=0$$ This means that $$\mathbf{T}'(t)$$ is orthogonal to $$\mathbf{T}(t)$$. Therefore, $$\mathbf{N}(t)$$ is orthogonal to $$\mathbf{T}(t)$$. We can imagine that the unit normal vector is the direction of the normal acceleration of the particle with respect to time.

The binormal vector
The binormal vector is defined as"$\mathbf{B}(t)=\mathbf{T}(t)\times\mathbf{N}(t)$"The binormal vector is perpendicular to both the unit tangent and the unit normal because of the properties of the cross product. The magnitude of the binormal is always 1 because"\mathbf{B}(t)"

The normal plane, osculating plane, and the osculating circle
These concepts are very important in the branch of differential geometry and in its applications to the motion of spacecraft.
 * The normal plane is the plane determined by the normal and binormal vectors $$\mathbf{N}\text{ and }\mathbf{B}$$. The normal plane consists of all lines that are orthogonal to the tangent vector $$\mathbf{T}$$.
 * The osculating plane is the plane determined by the unit tangent and unit normal $$\mathbf{T}\text{ and }\mathbf{N}$$. It is the plane that comes closest to containing the part of the curve near a point where $$t=t_0$$.
 * The osculating circle is the circle that lies in the osculating plane towards the direction of $$\mathbf{N}$$ with a radius $$r=\frac{1}{\kappa}$$ (the inverse of the curvature, which we will immediately discuss after this). It best describes how the curve behaves near the point where $$t=t_0$$ because it shares the same tangent, normal, and curvature at that point.

Curvature
The curvature of a curve at a given point is a measure of how quickly the curve changes direction at that point. We define it to be the magnitude of the rate of change of the unit tangent with respect to arc length. We use arc length so that the curvature will be independent of parametrization."\frac{d\mathbf{T}(s)}{ds}\biggr"There are two other ways to express the curvature. We can express curvature in terms of $$t$$ instead of $$s$$ by utilizing the chain rule (recall that $$\frac{dL}{dt}=|\mathbf{r}'(t)|$$):"\frac{d\mathbf{T}}{ds}\biggr|=\Biggl|\frac{\frac{d\mathbf{T}}{ds}\frac{ds}{dt}}{\frac{ds}{dt}}\Biggr|=\Biggl|\frac{\frac{d\mathbf{T}(t)}{dt}}{\frac{ds}{dt}}\Biggr|=\frac{|\mathbf{T}'(t)|}{|\mathbf{r}'(t)|}$|undefined"The third way is more complicated to deduce, but it is often more convenient to apply because it only requires $$\mathbf{r}(t)$$ and its derivatives."\mathbf{r}'(t)\times\mathbf{r}''(t)"And now for the proof for this theorem: According to the definition of the unit tangent vector, we know that $$\mathbf{r}'=|\mathbf{r}'|\mathbf{T}$$. So the second derivative of $$\mathbf{r}$$ should be: $$\begin{align} \mathbf{r}'' & = (|\mathbf{r}'|\ \mathbf{T})' \\ & = |\mathbf{r}''|\ \mathbf{T}+|\mathbf{r}'|\ \mathbf{T}' \quad\text{the product rule}\\ \end{align}$$ Now we calculate $$\mathbf{r}'\times\mathbf{r}''$$. $$\begin{align} \mathbf{r}'\times\mathbf{r} & = \bigl(|\mathbf{r}'|\mathbf{T}\bigr)\times\bigl(|\mathbf{r}|\ \mathbf{T}+|\mathbf{r}'|\ \mathbf{T}' \bigr)\quad\text{substitution} \\ & = \bigl(|\mathbf{r}'|\mathbf{T}\times|\mathbf{r}''|\mathbf{T}\bigr)+\bigl(|\mathbf{r}'|\mathbf{T}\times|\mathbf{r}'|\mathbf{T}'\bigr)\quad\text{distribution} \\ & = |\mathbf{r}'||\mathbf{r}''|(\mathbf{T}\times\mathbf{T})+|\mathbf{r}'|^2(\mathbf{T}\times\mathbf{T}')\quad\text{rearrangement} \\ & = |\mathbf{r}'|^2(\mathbf{T}\times\mathbf{T}') \quad\text{realizing that }\mathbf{T}\times\mathbf{T}=0 \\ \end{align}$$ And then we calculate $$|\mathbf{r}'\times\mathbf{r}''|$$. $$\begin{align} & = |\mathbf{r}'|^2|\mathbf{T}||\mathbf{T}'|\sin\theta \quad\text{the magnitude for the cross product} \\ & = |\mathbf{r}'|^2|\mathbf{T}'| \quad\text{when you realize }|\mathbf{T}|=1\text{ and }\mathbf{T}\perp\mathbf{T}' \\ \end{align}$$ We rearrange the equation into:"\mathbf{T}'"Since $$\kappa=\frac{|\mathbf{T}'|}{|\mathbf{r}'|}$$, we can substitute $$|\mathbf{T}'|$$ with $$\frac{|\mathbf{r}'\times\mathbf{r}|}{|\mathbf{r}'|^2}$$ and get: $$\kappa=\frac{|\mathbf{r}'\times\mathbf{r}|}{|\mathbf{r}'|^3}$$ Here is a little summary on ways to calculate the curvature.
 * \mathbf{r}'\times\mathbf{r}''| & = |\mathbf{r}'|^2|\mathbf{T}\times\mathbf{T}'|\quad\text{substitution} \\

Velocity and acceleration
Remember in 2-dimensional calculus, we mentioned that a particle with displacement function $$f(x)$$ has velocity $$f'(x)$$ and acceleration $$f''(x)$$. In vector functions, the definition is basically the same. Suppose a particle moves through space so that its position vector at time $$t$$ is $$\mathbf{r}(t)$$, its velocity function and acceleration function are:"$\mathbf{v}(t)=\lim_{h\rightarrow 0}\frac{\mathbf{r}(t+h)-\mathbf{r}(t)}{h}=\mathbf{r}'(t)\quad$ and $\quad\mathbf{a}(t)=\lim_{h\rightarrow 0}\frac{\mathbf{v}(t+h)-\mathbf{v}(t)}{h}=\mathbf{v}'(t)=\mathbf{r}(t)$"Simply put: $$\mathbf{r}(t)=\mathbf{v}'(t)=\mathbf{a}(t)$$.

The speed of the particle ignores the direction. It is the magnitude of the velocity vector: $$|\mathbf{v}(t)|$$. The distance traveled by the particle from $$t=a \text{ to } b$$ is $$\int_a^b|\mathbf{v}(t)|dt$$, which is also the formula for the arc length.

With the help of the Fundamental Theorem of Calculus, we can deduce the velocity function and position function when we know the particle's acceleration."$\mathbf{v}(t)=\mathbf{v}(t_0)+\int_{t_0}^t\mathbf{a}(u)du\quad$ and $\quad\mathbf{r}(t)=\mathbf{r}(t_0)+\int_{t_0}^t\mathbf{v}(u)du$"

Tangential and normal acceleration
We can split the acceleration vector into two components: the tangential acceleration $$a_T$$ and the normal acceleration $$a_N$$. The tangential acceleration faces the same direction as the unit tangent vector ($$\mathbf{T}$$), and the normal acceleration faces the same direction as the unit normal vector ($$\mathbf{N}$$). Since both $$\mathbf{T}$$ and $$\mathbf{N}$$ are unit vectors, the acceleration vector can be written as the sum of two vectors:"$\mathbf{a}=a_T\mathbf{T}+a_N\mathbf{N}$"Our goal is to figure out how to describe the two components."Recall that $\mathbf{T}=\frac{\mathbf{v}}{|\mathbf{v}|}$, thus $\mathbf{v}=|\mathbf{v}|\mathbf{T}$|undefined"Now we differentiate both sides of the equation, $$\begin{align} \mathbf{v}' & = \bigl(|\mathbf{v}|\mathbf{T}\bigr)' \\ & = |\mathbf{v}|'\mathbf{T}+|\mathbf{v}|\mathbf{T}'\\ \end{align}$$ So we get $$\mathbf{a}=|\mathbf{v}|'\mathbf{T}+|\mathbf{v}|\mathbf{T}'$$. "\mathbf{T}'\big""\mathbf{T}'\big"We substitute $$\mathbf{T}'$$ for $$\kappa|\mathbf{v}|\mathbf{N}$$ to yield: $$\mathbf{a}=|\mathbf{v}|'\mathbf{T}+\kappa|\mathbf{v}|^2\mathbf{N}$$ That leaves us with:"\mathbf{v}"

$$\blacksquare$$

Of course, it will be more convenient if those components can be written in terms if $$\mathbf{r}(t)$$ and its derivatives. Suppose that $$\theta$$ is the angle between $$\mathbf{T}$$ and $$\mathbf{a}$$, then we can write $$a_T,a_N$$ like this: $$\begin{align} a_T & = |\mathbf{a}(t)|\cos\theta \\ & = \frac{|\mathbf{v}(t)||\mathbf{a}(t)|\cos\theta}{|\mathbf{v}(t)|} \quad\text{algebraic manipulation}\\ & = \frac{\mathbf{v}(t)\cdot\mathbf{a}(t)}{|\mathbf{v}(t)|}\quad\text{dot product}\\ & = \frac{\mathbf{r}'(t)\cdot\mathbf{r}''(t)}{|\mathbf{r}'(t)|}\quad\text{in terms of }\mathbf{r}(t)\text{ and its derivatives}\\ \end{align}$$$$\begin{align} a_N & = |\mathbf{a}(t)|\sin\theta \\ & = \frac{|\mathbf{v}(t)||\mathbf{a}(t)|\sin\theta}{|\mathbf{v}(t)|} \quad\text{algebraic manipulation}\\ & = \frac{|\mathbf{v}(t)\times\mathbf{a}(t)|}{|\mathbf{v}(t)|}\quad\text{cross product}\\ & = \frac{|\mathbf{r}'(t)\times\mathbf{r}''(t)|}{|\mathbf{r}'(t)|}\quad\text{in terms of }\mathbf{r}(t)\text{ and its derivatives}\\ \end{align}$$

$$\blacksquare$$

To sum it up:"\mathbf{v}"

Expansion
We only discussed vector functions with three variables $$\mathbf{r}(t)=\langle f(t),g(t),h(t)\rangle$$. How about expanding our understanding of vector functions into $$n$$ variables? Suppose we have a curve with vector function: $$\mathbf{r}(t)= \begin{pmatrix} f_1(t) \\ f_2(t) \\ \vdots \\ f_n(t) \\ \end{pmatrix}$$

Limits
The limit of a vector function is defined as: $$\lim_{t\rightarrow c} \mathbf{r}(t)= \begin{pmatrix} \lim_{t\rightarrow c} f_1(t) \\ \lim_{t\rightarrow c} f_2(t) \\ \vdots \\ \lim_{t\rightarrow c} f_n(t) \\ \end{pmatrix}$$

Differentiation and integration
The derivative of a vector function is defined as: $$\mathbf{r}'(t)=\lim_{\Delta t\rightarrow 0}\frac{\mathbf{r}(t+\Delta t)-\mathbf{r}(t)}{\Delta t}$$, thus $$\quad\mathbf{r}'(t)= \begin{pmatrix} f_1'(t) \\ f_2'(t) \\ \vdots \\ f_n'(t) \\ \end{pmatrix}$$ All differentiation rules apply.

We can expand integration into: $$\int\mathbf{r}(t)dt= \begin{pmatrix} \int f_1(t)dt \\ \int f_2(t)dt \\ \vdots \\ \int f_n(t)dt \\ \end{pmatrix} +\mathbf{C} $$ Then, the arc length will become:"\mathbf{r}'(t)"

title: Calculus/Vector Functions


text:
Calculus/Multivariable Calculus/Limits and Continuity

Limits and continuity
Before we can look at derivatives of multivariate functions, we need to look at how limits work with functions of several variables first, just like in the single variable case.

If we have a function f : Rm → Rn, we say that f(x) approaches b (in Rn) as x approaches a (in Rm) if, for all positive ε, there is a corresponding positive number δ, |f(x)-b| < ε whenever |x-a| < δ, with x ≠ a.

This means that by making the difference between x and a smaller, we can make the difference between f(x) and b as small as we want.

If the above is true, we say
 * f(x) has limit b at a
 * $$\lim_{\mathbf{x}\rightarrow\mathbf{a}} \mathbf{f}(\mathbf{x}) = \mathbf{b}$$
 * f(x) approaches b as x approaches a
 * f(x) → b as x → a

These four statements are all equivalent.

Rules
Since this is an almost identical formulation of limits in the single variable case, many of the limit rules in the one variable case are the same as in the multivariate case.

For f and g, mapping Rm to Rn, and h(x) a scalar function mapping Rm to R, with then: and consequently
 * f(x) → b as x → a
 * g(x) → c as x → a
 * h(x) → H as x → a
 * $$\lim_{\mathbf{x}\rightarrow\mathbf{a}} (\mathbf{f} + \mathbf{g}) = \mathbf{b} + \mathbf{c}$$
 * $$\lim_{\mathbf{x}\rightarrow\mathbf{a}} (h\mathbf{f}) = H\mathbf{b}$$
 * $$\lim_{\mathbf{x}\rightarrow\mathbf{a}} (\mathbf{f}\cdot\mathbf{g}) = \mathbf{b}\cdot\mathbf{c}$$
 * $$\lim_{\mathbf{x}\rightarrow\mathbf{a}} (\mathbf{f}\times\mathbf{g}) = \mathbf{b}\times\mathbf{c}$$

when H≠0
 * $$\lim_{\mathbf{x}\rightarrow\mathbf{a}} ({\mathbf{f}\over h}) = {\mathbf{b}\over H}$$

Continuity
Again, we can use a similar definition to the one variable case to formulate a definition of continuity for multiple variables.

If f : Rm → Rn, f is continuous at a point a in Rm if f(a) is defined and
 * $$\lim_{\mathbf{x}\rightarrow\mathbf{a}} \mathbf{f}(\mathbf{x}) = \mathbf{f}(\mathbf{a})$$

Just as for functions of one dimension, if f, g are both continuous at p, f+g, λf (for a scalar λ), f·g, and f×g are continuous also. If φ : Rm → R is continus at p, φf, f/φ are too if φ is never zero.

From these facts we also have that if A is some matrix which is n×m in size, with x in Rm, a function f(x)=A x is continuous in that the function can be expanded in the form x1a1+...+xmam, which can be easily verified from the points above.

If f : Rm → Rn which is in the form f(x) = (f1(x),...,fn(x) is continuous if and only if each of its component functions are a polynomial or rational function, whenever they are defined.

Finally, if f is continuous at p, g is continuous at f(p), g(f(x)) is continuous at p.

Special note about limits
It is important to note that we can approach a point in more than one direction, and thus, the direction that we approach that point counts in our evaluation of the limit. It may be the case that a limit may exist moving in one direction, but not in another.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Calculus/Multivariable Calculus/Partial Derivatives

Differentiable functions
We will start from the one-variable definition of the derivative at a point p, namely
 * $$\lim_{x\rightarrow p} {f(x)-f(p) \over x-p} = f'(p)$$

Let's change above to equivalent form of
 * $$\lim_{x\rightarrow p} {f(x)-f(p)-f'(p)(x-p) \over x-p} = 0$$

which achieved after pulling f'(p) inside and putting it over a common denominator.

We can't divide by vectors, so this definition can't be immediately extended to the multiple variable case. Nonetheless, we don't have to: the thing we took interest in was the quotient of two small distances (magnitudes), not their other properties (like sign). It's worth noting that 'other' property of vector neglected is its direction. Now we can divide by the absolute value of a vector, so lets rewrite this definition in terms of absolute values
 * $$\lim_{x\rightarrow p} \frac{\left|f(x)-f(p)-f'(p)(x-p)\right|}{\left| x-p\right|} = 0$$

Another form of formula above is obtained by letting $$h=x-p$$ we have $$x=p+h$$ and if $$x \rightarrow p$$, the $$h = x - p \rightarrow 0$$, so
 * $$\lim_{h\rightarrow 0} \frac{\left|f(p+h)-f(p)-f'(p)h\right|}{\left| h\right|} = 0$$,

where $$h$$ can be thought of as a 'small change'.

So, how can we use this for the several-variable case?

If we switch all the variables over to vectors and replace the constant (which performs a linear map in one dimension) with a matrix (which denotes also a linear map), we have
 * $$\lim_{\mathbf{x}\rightarrow\mathbf{p}} {|\mathbf{f}(\mathbf{x})-\mathbf{f}(\mathbf{p})-\mathbf{A}(\mathbf{x}-\mathbf{p})| \over |\mathbf{x}-\mathbf{p}|} = 0$$

or
 * $$\lim_{\mathbf{h}\rightarrow\mathbf{0}} {|\mathbf{f}(\mathbf{p}+\mathbf{h})-\mathbf{f}(\mathbf{p})-\mathbf{A}\mathbf{h}| \over |\mathbf{h}|} = 0$$

If this limit exists for some f : Rm → Rn, and there is a linear map A : Rm → Rn (denoted by matrix A which is m×n), we refer to this map as being the derivative and we write it as Dp f.

A point on terminology - in referring to the action of taking the derivative (giving the linear map A), we write Dp f, but in referring to the matrix A itself, it is known as the Jacobian matrix and is also written Jp f. More on the Jacobian later.

Properties
There are a number of important properties of this formulation of the derivative.

Affine approximations
If f is differentiable at p for x close to p, |f(x)-(f(p)+A(x-p))| is small compared to |x-p|, which means that f(x) is approximately equal to f(p)+A(x-p).

We call an expression of the form g(x)+c affine, when g(x) is linear and c is a constant. f(p)+A(x-p) is an affine approximation to f(x).

Jacobian matrix and partial derivatives
The Jacobian matrix of a function is in the form
 * $$\left(J_\mathbf{p} \mathbf{f}\right)_{ij} = \left.{\partial f_i \over \partial x_j}\right|_\mathbf{p}$$

for a f : Rm → Rn, Jp f is a n×m matrix.

The consequence of this is that if f is differentiable at p, all the partial derivatives of f exist at p.

However, it is possible that all the partial derivatives of a function exist at some point yet that function is not differentiable there, so it is very important not to mix derivative (linear map) with the Jacobian (matrix) especially in situations akin to the one cited.

Continuity and differentiability
Furthermore, if all the partial derivatives exist, and are continuous in some neighbourhood of a point p, then f is differentiable at p. This has the consequence that for a function f which has its component functions built from continuous functions (such as rational functions, differentiable functions or otherwise), f is differentiable everywhere f is defined.

We use the terminology continuously differentiable for a function differentiable at p which has all its partial derivatives existing and are continuous in some neighbourhood at p.


text:
Calculus/Multivariable Calculus/Chain Rule

Rules of taking Jacobians
If f : Rm → Rn, and h(x) : Rm → R are differentiable at 'p': Important: make sure the order is right - matrix multiplication is not commutative!
 * $$J_\mathbf{p} (\mathbf{f}+\mathbf{g}) = J_\mathbf{p} \mathbf{f} + J_\mathbf{p} \mathbf{g}$$
 * $$J_\mathbf{p} (h\mathbf{f}) = hJ_\mathbf{p} \mathbf{f} + \mathbf{f}(\mathbf{p}) J_\mathbf{p} h$$
 * $$J_\mathbf{p} (\mathbf{f}\cdot \mathbf{g}) = \mathbf{g}^T J_\mathbf{p} \mathbf{f} + \mathbf{f}^T J_\mathbf{p}\mathbf{g}$$

Chain rule
The chain rule for functions of several variables is as follows. For f : Rm → Rn and g : Rn → Rp, and g o f differentiable at p, then the Jacobian is given by
 * $$\left( J_{\mathbf{f}(\mathbf{p})} \mathbf{g}\right) \left( J_\mathbf{p} \mathbf{f}\right)$$

Again, we have matrix multiplication, so one must preserve this exact order. Compositions in one order may be defined, but not necessarily in the other way.


text:
Calculus/Directional derivatives and the gradient vector

Directional derivatives
Normally, a partial derivative of a function with respect to one of its variables, say, xj, takes the derivative of that "slice" of that function parallel to the xj'th axis.

More precisely, we can think of cutting a function f(x1,...,xn) in space along the xj'th axis, with keeping everything but the xj variable constant.

From the definition, we have the partial derivative at a point p of the function along this slice as
 * $${\partial \mathbf{f} \over \partial x_j} = \lim_{t\rightarrow 0} {\mathbf{f}(\mathbf{p}+t\mathbf{e}_j) - \mathbf{f}(\mathbf{p}) \over t}$$

provided this limit exists.

Instead of the basis vector, which corresponds to taking the derivative along that axis, we can pick a vector in any direction (which we usually take as being a unit vector), and we take the directional derivative of a function as
 * $${\partial \mathbf{f} \over \partial \mathbf{d}} = \lim_{t\rightarrow 0} {\mathbf{f}(\mathbf{p}+t\mathbf{d}) - \mathbf{f}(\mathbf{p}) \over t}$$

where d is the direction vector.

If we want to calculate directional derivatives, calculating them from the limit definition is rather painful, but, we have the following: if f : Rn → R is differentiable at a point p, |p|=1,
 * $${\partial \mathbf{f} \over \partial \mathbf{d}} = D_\mathbf{p} \mathbf{f}(\mathbf{d})$$

There is a closely related formulation which we'll look at in the next section.

Gradient vectors
The partial derivatives of a scalar tell us how much it changes if we move along one of the axes. What if we move in a different direction?

We'll call the scalar f, and consider what happens if we move an infintesimal direction dr=(dx,dy,dz), using the chain rule.
 * $$\mathbf{df}=dx\frac{\partial f}{\partial x} +

dy\frac{\partial f}{\partial y}+dz\frac{\partial f}{\partial z}$$

This is the dot product of dr with a vector whose components are the partial derivatives of f, called the gradient of f

$$\operatorname{grad} \mathbf{f} = \nabla \mathbf{f} = \left(\frac{\partial \mathbf{f}(\mathbf{p})}{\partial x_1},\cdots, \frac{\partial \mathbf{f}(\mathbf{p})}{\partial x_n}\right)$$

We can form directional derivatives at a point p, in the direction d then by taking the dot product of the gradient with d
 * $${\partial \mathbf{f}(\mathbf{p}) \over \partial \mathbf{d}} =\mathbf{d} \cdot \nabla \mathbf{f}(\mathbf{p})$$.

Notice that grad f looks like a vector multiplied by a scalar. This particular combination of partial derivatives is commonplace, so we abbreviate it to
 * $$\nabla = \left( \frac{\partial }{\partial x},

\frac{\partial }{\partial y}, \frac{\partial }{\partial z}\right) $$

We can write the action of taking the gradient vector by writing this as an operator. Recall that in the one-variable case we can write d/dx for the action of taking the derivative with respect to x. This case is similar, but ∇ acts like a vector.

We can also write the action of taking the gradient vector as:
 * $$\nabla = \left( \frac{\partial }{\partial x_1},

\frac{\partial }{\partial x_2}, \cdots \frac{\partial }{\partial x_n}\right) $$

Geometry

 * Grad f(p) is a vector pointing in the direction of steepest slope of f. |grad f(p)| is the rate of change of that slope at that point.

For example, if we consider h(x, y)=x2+y2. The level sets of h are concentric circles, centred on the origin, and
 * $$ \nabla h = (h_x,h_y) = 2(x,y)= 2 \mathbf{r}$$

grad h points directly away from the origin, at right angles to the contours.

 * Along a level set, (∇f)(p) is perpendicular to the level set {x|f(x)=f(p) at x=p}.

If dr points along the contours of f, where the function is constant, then df will be zero. Since df is a dot product, that means that the two vectors, df and grad f, must be at right angles, i.e. the gradient is at right angles to the contours.

Algebraic properties
Like d/dx, ∇ is linear. For any pair of constants, a and b, and any pair of scalar functions, f and g
 * $$\frac{d}{dx} (af+bg)= a\frac{d}{dx}f + b\frac{d}{dx}g

\quad \nabla (af+bg) = a \nabla f + b \nabla g$$

Since it's a vector, we can try taking its dot and cross product with other vectors, and with itself.


text:
Calculus/Multiple integration

Double integration
For (Riemann) integrals, we consider the Riemann sum. Recall in the one-variable case, we partition an interval into more and more subintervals with smaller and smaller width, and we are integrating over the interval by summing the areas of corresponding rectangles for each subinterval. For the multivariable case, we need to do something similar, but the problem arises when we need to partition 'interval' in $$\mathbb R^2,\mathbb R^3$$ or $$\mathbb R^n$$ in general. (Actually, we only have the term interval in $$\mathbb R$$.)

In multivariable case, we need to consider not just 'interval' itself (which is undefined in multivariable case), but Cartesian product over intervals for $$\mathbb R^2$$, and more generally n-ary Cartesian product over intervals for $$\mathbb R^n$$.

Area (for $$n=2$$), volume (for $$n=3$$) or measure (for each positive number $$n$$) of geometric objects (e.g. rectangles in $$\mathbb R^2$$ and cubes in $$\mathbb R^3$$) in $$\mathbb R^n$$ is the product of the lengths of all its sides (in different dimensions).

Now, we are ready to define multiple integral in an analogous way compared with single integral. For simplicity, let us first discuss double integral, and then generalize it to multiple integral in an analogous way.

A physical meaning of double integration is computing volume.

Let's also introduce some properties of double integral to ease computation of double integral.

Iterated integrals
Thankfully, we need not always work with Riemann sums every time we want to calculate an integral in more than one variable. There are some results that make life a bit easier for us. Before stating the result, we need to define iterated integral, which is used in the results.

Computation of iterated integrals is generally much easier than computing the double integral directly using Riemann sum. So, it will be nice if we have some relationships between iterated integral and double integral for us to compute double integral with the help of iterated integral. It is indeed the case and the following theorem is the bridge between iterated integral and double integral.

{ Example. }

{Choose the correct expression(s) for the integral $$\iint_{[1,3]\times[2,4]}x^2y\,dx\,dy$$. + $$\int_1^3\int_2^4x^2y\,dy\,dx$$ + $$\int_2^4\int_1^3x^2y\,dx\,dy$$ - $$\int_2^4\int_1^3x^2y\,dy\,dx$$ - $$\int_1^3\int_2^4x^2y\,dx\,dy$$
 * type="[]"}
 * This is correct by Fubini's theorem.
 * This is correct by Fubini's theorem.
 * Be careful about the change of bounds.
 * Be careful about the change of bounds.

{Choose the correct expression(s) for the integral $$\iint_{[-1,1]\times [3,7]}y^2e^x\,dx\,dy$$. + $$\int_{-1}^1\left(e^7-e^3\right)y^2\,dy$$ - $$\int_{-1}^1 \frac{316}{3}e^x\,dy$$ - $$\int_{3}^7\left(e^7-e^3\right)y^2\,dx$$ - $$\int_{3}^7\left(e^7-e^3\right)y^2\,dy$$ + $$\int_{-1}^1 \frac{316}{3}e^x\,dx$$
 * type="[]"}

Double integrals over more general regions in R2
We have defined double integrals over rectangles in $$\mathbb R^2$$. However, we often want to compute double integral over regions with shape other than rectangle, e.g. circle, triangle, etc. Therefore, we will discuss an approach to compute double integrals over more general regions reasonably, without altering the definition of double integrals.

Consider a function $$f:D\to\mathbb R$$ in which $$D\subseteq \mathbb R^2$$ is a general region. To apply the definition of double integrals, we need to transform the general region $$D$$ to a rectangle (say $$R$$). An approach is finding a rectangle $$R$$ containing $$D$$ (i.e., $$R\supseteq D$$), and let $$f(x,y)=0$$ for each $$(x,y)\in R$$ lying outside $$D$$ (i.e., for each $$(x,y)\in R\setminus D$$ ). Because the value of the function is zero outside the region we are integrating over, this does not change the volume under the graph of $$f$$ over $$D$$, so this way is a good way to define such double integrals. Let's define such double integrals formally in the following.

However, this way of computation (by computing Riemann sum) is generally very difficult, and usually we use a generalized version of Fubini's theorem to compute such integrals. It will be discussed in the following.

Triple integration
The concepts in the section of double integrals apply to triple integrals (and also multiple integrals generally) analogously. We will give several examples for triple integrals in this section.

title: Calculus/Multiple integration


text:
Calculus/Multivariable Calculus/Double Integrals

Order of integration
In some cases the first integral of the entire iterated integral is difficult or impossible to solve, therefore, it can be to our advantage to change the order of integration.

$$\int_a^b\,\int_{f(x)}^{g(x)} h(x,y)\,dx dy$$

$$\int_c^d\,\int_{e(y)}^{f(y)} h(x,y)\,dy dx$$

As of the writing of this, there is no set method to change an order of integration from dxdy to dydx or some other variable. Although, it is possible to change the order of integration in an x and y simple integration by simply switching the limits of integration around also, in non-simple x and y integrations the best method as of yet is to recreate the limits of the integration from the graph of the limits of integration.

In higher order integration that can't be graphed, the process can be very tedious. For example, dxdydz can be written into dzdydx, but first dxdydz must be switched to dydxdz and then to dydzdx and then to dzdydx (as 3-dimensional cases can be graphed, this method would lack parsimony).


text:
Oberon/V2/System

MODULE System; (*JG 3.10.90*) IMPORT Viewers, MenuViewers, Oberon, Texts, TextFrames; CONST StandardMenu = "System.Close System.Copy System.Grow Edit.Search Edit.Store"; LogMenu = "System.Close System.Grow Edit.Locate Edit.Store"; VAR W: Texts.Writer; PROCEDURE Max (i, j: LONGINT): LONGINT; BEGIN IF i >= j THEN RETURN i ELSE RETURN j END END Max; (* - Toolbox for standard display ---*) PROCEDURE Open*; VAR par: Oberon.ParList; V: Viewers.Viewer; T: Texts.Text; S: Texts.Scanner; X, Y: INTEGER; beg, end, time: LONGINT; BEGIN par := Oberon.Par; Texts.OpenScanner(S, par.text, par.pos); Texts.Scan(S); IF (S.class = Texts.Char) & (S.c = "^") OR (S.line # 0) THEN Oberon.GetSelection(T, beg, end, time); IF time >= 0 THEN Texts.OpenScanner(S, T, beg); Texts.Scan(S) END END; IF S.class = Texts.Name THEN Oberon.AllocateSystemViewer(par.vwr.X, X, Y); V := MenuViewers.New( 				TextFrames.NewMenu(S.s, StandardMenu), 				TextFrames.NewText(TextFrames.Text(S.s), 0), 				TextFrames.menuH, 				X, Y) 		END END Open; PROCEDURE OpenLog*; VAR V: Viewers.Viewer; X, Y: INTEGER; BEGIN Oberon.AllocateSystemViewer(Oberon.Par.vwr.X, X, Y); V := MenuViewers.New( 			TextFrames.NewMenu("System.Log", LogMenu), 			TextFrames.NewText(Oberon.Log, Max(0, Oberon.Log.len - 200)), 			TextFrames.menuH, 			X, Y) 	END OpenLog; PROCEDURE Close*; VAR par: Oberon.ParList; V: Viewers.Viewer; BEGIN par := Oberon.Par; IF par.frame = par.vwr.dsc THEN V := par.vwr ELSE V := Oberon.MarkedViewer END; Viewers.Close(V) END Close; PROCEDURE CloseTrack*; VAR V: Viewers.Viewer; BEGIN V := Oberon.MarkedViewer; Viewers.CloseTrack(V.X) 	END CloseTrack; PROCEDURE Recall*; VAR V: Viewers.Viewer; M: Viewers.ViewerMsg; BEGIN Viewers.Recall(V); IF V.state = 0 THEN Viewers.Open(V, V.X, V.Y + V.H); M.id := Viewers.restore; V.handle(V, M) 		END END Recall; PROCEDURE Copy*; VAR V, V1: Viewers.Viewer; M: Oberon.CopyMsg; N: Viewers.ViewerMsg; BEGIN V := Oberon.Par.vwr; V.handle(V, M); V1 := M.F(Viewers.Viewer); Viewers.Open(V1, V.X, V.Y + V.H DIV 2); N.id := Viewers.restore; V1.handle(V1, N) 	END Copy; PROCEDURE Grow*; VAR V, V1: Viewers.Viewer; M: Oberon.CopyMsg; N: Viewers.ViewerMsg; DW, DH: INTEGER; BEGIN V := Oberon.Par.vwr; DW := Oberon.DisplayWidth(V.X); DH := Oberon.DisplayHeight(V.X); IF V.H < DH - Viewers.minH THEN Oberon.OpenTrack(V.X, V.W) 		ELSIF V.W < DW THEN Oberon.OpenTrack(Oberon.UserTrack(V.X), DW) END; IF (V.H < DH - Viewers.minH) OR (V.W < DW) THEN V.handle(V, M); V1 := M.F(Viewers.Viewer); Viewers.Open(V1, V.X, DH); N.id := Viewers.restore; V1.handle(V1, N) 		END END Grow; PROCEDURE OpenViewers; VAR V: Viewers.Viewer; t, d: LONGINT; X, Y: INTEGER; BEGIN Oberon.GetClock(t, d); Texts.WriteString(W, "System.Time"); Texts.WriteDate(W, t, d); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); Oberon.AllocateSystemViewer(0, X, Y); V := MenuViewers.New( 			TextFrames.NewMenu("System.Log", LogMenu), 			TextFrames.NewText(Oberon.Log, 0), 			TextFrames.menuH, 			X, Y); Oberon.AllocateSystemViewer(0, X, Y); V := MenuViewers.New( 			TextFrames.NewMenu("System.Tool", StandardMenu), 			TextFrames.NewText(TextFrames.Text("System.Tool"), 0), 			TextFrames.menuH, 			X, Y) 	END OpenViewers; BEGIN Texts.OpenWriter(W); Oberon.Log := TextFrames.Text(""); OpenViewers END System.

title: Oberon/V2/System


text:
Oberon/V2/Viewers

MODULE Viewers; (*JG 14.9.90*) IMPORT Display; CONST restore* = 0; modify* = 1; suspend* = 2; (*message id*) inf = MAX(INTEGER); TYPE Viewer* = POINTER TO ViewerDesc; ViewerDesc* = RECORD (Display.FrameDesc) state*: INTEGER END; (*state > 1: displayed 			state = 1: filler 			state = 0: closed 			state < 0: suspended*) ViewerMsg* = RECORD (Display.FrameMsg) id*: INTEGER; X*, Y*, W*, H*: INTEGER; state*: INTEGER END; Track = POINTER TO TrackDesc; TrackDesc = RECORD (ViewerDesc) under: Display.Frame END; VAR curW*, minH*, DW, DH: INTEGER; FillerTrack: Track; FillerViewer, buf: Viewer; (*for closed viewers*) PROCEDURE Open* (V: Viewer; X, Y: INTEGER); VAR T, u, v: Display.Frame; M: ViewerMsg; BEGIN IF (V.state = 0) & (X < inf) THEN IF Y > DH THEN Y := DH END; T := FillerTrack.next; WHILE X >= T.X + T.W DO T := T.next END; u := T.dsc; v := u.next; WHILE Y > v.Y + v.H DO u := v; v := u.next END; IF Y < v.Y + minH THEN Y := v.Y + minH END; IF (v.next.Y # 0) & (Y > v.Y + v.H - minH) THEN WITH v: Viewer DO 					V.X := T.X; V.W := T.W; V.Y := v.Y; V.H := v.H; 					M.id := suspend; M.state := 0; v.handle(v, M); v.state := 0; buf := v; 					V.next := v.next; u.next := V; 					V.state := 2 END ELSE V.X := T.X; V.W := T.W; V.Y := v.Y; V.H := Y - v.Y; 				M.id := modify; M.Y := Y; M.H := v.Y + v.H - Y; 				v.handle(v, M); v.Y := M.Y; v.H := M.H; 				V.next := v; u.next := V; 				V.state := 2 END END END Open; PROCEDURE Change* (V: Viewer; Y: INTEGER); VAR v: Display.Frame; M: ViewerMsg; BEGIN IF V.state > 1 THEN IF Y > DH THEN Y := DH END; v := V.next; IF (v.next.Y # 0) & (Y > v.Y + v.H - minH) THEN Y := v.Y + v.H - minH END; IF Y >= V.Y + minH THEN M.id := modify; M.Y := Y; M.H := v.Y + v.H - Y; 				v.handle(v, M); v.Y := M.Y; v.H := M.H; 				V.H := Y - V.Y 			END END END Change; PROCEDURE RestoreTrack (S: Display.Frame); VAR T, t, v: Display.Frame; M: ViewerMsg; BEGIN WITH S: Track DO 			t := S.next; WHILE t.next.X # S.X DO t := t.next END; T := S.under; WHILE T.next # NIL DO T := T.next END; t.next := S.under; T.next := S.next; M.id := restore; REPEAT t := t.next; v := t.dsc; REPEAT v := v.next; v.handle(v, M); WITH v: Viewer DO v.state := - v.state END UNTIL v = t.dsc UNTIL t = T 		END END RestoreTrack; PROCEDURE Close* (V: Viewer); VAR T, U: Display.Frame; M: ViewerMsg; BEGIN IF V.state > 1 THEN U := V.next; T := FillerTrack; REPEAT T := T.next UNTIL V.X < T.X + T.W; 			IF (T(Track).under = NIL) OR (U.next # V) THEN M.id := suspend; M.state := 0; V.handle(V, M); V.state := 0; buf := V; 				M.id := modify; M.Y := V.Y; M.H := V.H + U.H; 				U.handle(U, M); U.Y := M.Y; U.H := M.H; 				WHILE U.next # V DO U := U.next END; U.next := V.next ELSE (*close track*) M.id := suspend; M.state := 0; V.handle(V, M); V.state := 0; buf := V; 				U.handle(U, M); U(Viewer).state := 0; RestoreTrack(T) END END END Close; PROCEDURE Recall* ( VAR V: Viewer); BEGIN V := buf END Recall; PROCEDURE This* (X, Y: INTEGER): Viewer; VAR T, V: Display.Frame; BEGIN IF (X < inf) & (Y < DH) THEN T := FillerTrack; REPEAT T := T.next UNTIL X < T.X + T.W; 			V := T.dsc; REPEAT V := V.next UNTIL Y < V.Y + V.H; 			RETURN V(Viewer) ELSE RETURN NIL END END This; PROCEDURE Next* (V: Viewer): Viewer; BEGIN RETURN V.next(Viewer) END Next; PROCEDURE Locate* (X, H: INTEGER; VAR fil, bot, alt, max: Display.Frame); VAR T, V: Display.Frame; BEGIN IF X < inf THEN T := FillerTrack; REPEAT T := T.next UNTIL X < T.X + T.W; 			fil := T.dsc; bot := fil.next; IF bot.next # fil THEN alt := bot.next; V := alt.next; WHILE (V # fil) & (alt.H < H) DO 					IF V.H > alt.H THEN alt := V END; V := V.next END ELSE alt := bot END; max := T.dsc; V := max.next; WHILE V # fil DO 				IF V.H > max.H THEN max := V END; V := V.next END END END Locate; PROCEDURE InitTrack* (W, H: INTEGER; Filler: Viewer); VAR S: Display.Frame; T: Track; BEGIN IF Filler.state = 0 THEN Filler.X := curW; Filler.W := W; Filler.Y := 0; Filler.H := H; 			Filler.state := 1; Filler.next := Filler; NEW(T); T.X := curW; T.W := W; T.Y := 0; T.H := H; 			T.dsc := Filler; T.under := NIL; FillerViewer.X := curW + W; FillerViewer.W := inf - FillerViewer.X; 			FillerTrack.X := FillerViewer.X; FillerTrack.W := FillerViewer.W; 			S := FillerTrack; WHILE S.next # FillerTrack DO S := S.next END; S.next := T; T.next := FillerTrack; curW := curW + W 		END END InitTrack; PROCEDURE OpenTrack* (X, W: INTEGER; Filler: Viewer); VAR newT: Track; S, T, t, v: Display.Frame; M: ViewerMsg; BEGIN IF (X < inf) & (Filler.state = 0) THEN S := FillerTrack; T := S.next; WHILE X >= T.X + T.W DO S := T; T := S.next END; WHILE X + W > T.X + T.W DO T := T.next END; M.id := suspend; t := S; 			REPEAT t := t.next; v := t.dsc; REPEAT v := v.next; WITH v: Viewer DO 						M.state := -v.state; v.handle(v, M); v.state := M.state END UNTIL v = t.dsc UNTIL t = T; 			Filler.X := S.next.X; Filler.W := T.X + T.W - S.next.X; Filler.Y := 0; Filler.H := DH; Filler.state := 1; Filler.next := Filler; NEW(newT); newT.X := Filler.X; newT.W := Filler.W; newT.Y := 0; newT.H := DH; newT.dsc := Filler; newT.under := S.next; S.next := newT; newT.next := T.next; T.next := NIL END END OpenTrack; PROCEDURE CloseTrack* (X: INTEGER); VAR T, V: Display.Frame; M: ViewerMsg; BEGIN IF X < inf THEN T := FillerTrack; REPEAT T := T.next UNTIL X < T.X + T.W; 			IF T(Track).under # NIL THEN M.id := suspend; M.state := 0; V := T.dsc; REPEAT V := V.next; V.handle(V, M); V(Viewer).state := 0 UNTIL V = T.dsc; RestoreTrack(T) END END END CloseTrack; PROCEDURE Broadcast* (VAR M: Display.FrameMsg); VAR T, V: Display.Frame; BEGIN T := FillerTrack.next; WHILE T # FillerTrack DO 			V := T.dsc; REPEAT V := V.next; V.handle(V, M) UNTIL V = T.dsc; T := T.next END END Broadcast; BEGIN buf := NIL; NEW(FillerViewer); FillerViewer.X := 0; FillerViewer.W := inf; FillerViewer.Y := 0; FillerViewer.H := DH; FillerViewer.next := FillerViewer; NEW(FillerTrack); FillerTrack.X := 0; FillerTrack.W := inf; FillerTrack.Y := 0; FillerTrack.H := DH; FillerTrack.dsc := FillerViewer; FillerTrack.next := FillerTrack; curW := 0; minH := 1; DW := Display.Width; DH := Display.Height END Viewers.

title: Oberon/V2/Viewers


text:
Oberon/V2/MenuViewers

MODULE MenuViewers; (*JG 26.8.90*) IMPORT Input, Display, Texts, Viewers, Oberon; CONST extend* = 0; reduce* = 1; TYPE Viewer* = POINTER TO ViewerDesc; ViewerDesc* = RECORD (Viewers.ViewerDesc) menuH*: INTEGER END; ModifyMsg* = RECORD (Display.FrameMsg) id*: INTEGER; dY*, Y*, H*: INTEGER END; PROCEDURE Copy (V: Viewer; VAR V1: Viewer); VAR Menu, Main: Display.Frame; M: Oberon.CopyMsg; BEGIN Menu := V.dsc; Main := V.dsc.next; NEW(V1); V1^ := V^; V1.state := 0; Menu.handle(Menu, M); V1.dsc := M.F; 		Main.handle(Main, M); V1.dsc.next := M.F 	END Copy; PROCEDURE Draw (V: Viewers.Viewer); BEGIN Display.ReplConst(Display.white, V.X, V.Y, 1, V.H, 0); Display.ReplConst(Display.white, V.X + V.W - 1, V.Y, 1, V.H, 0); Display.ReplConst(Display.white, V.X + 1, V.Y, V.W - 2, 1, 0); Display.ReplConst(Display.white, V.X + 1, V.Y + V.H - 1, V.W - 2, 1, 0) END Draw; PROCEDURE Extend (V: Viewer; newY: INTEGER); VAR dH: INTEGER; BEGIN dH := V.Y - newY; IF dH > 0 THEN Display.ReplConst(Display.black, V.X + 1, newY + 1, V.W - 2, dH, 0); Display.ReplConst(Display.white, V.X, newY, 1, dH, 0); Display.ReplConst(Display.white, V.X + V.W - 1, newY, 1, dH, 0); Display.ReplConst(Display.white, V.X + 1, newY, V.W - 2, 1, 0) END END Extend; PROCEDURE Reduce (V: Viewer; newY: INTEGER); BEGIN Display.ReplConst(Display.white, V.X + 1, newY, V.W - 2, 1, 0) END Reduce; PROCEDURE Grow (V: Viewer; oldH: INTEGER); VAR dH: INTEGER; BEGIN dH := V.H - oldH; IF dH > 0 THEN Display.ReplConst(Display.white, V.X, V.Y + oldH, 1, dH, 0); Display.ReplConst(Display.white, V.X + V.W - 1, V.Y + oldH, 1, dH, 0); Display.ReplConst(Display.white, V.X + 1, V.Y + V.H - 1, V.W - 2, 1, 0) END END Grow; PROCEDURE Shrink (V: Viewer; newH: INTEGER); BEGIN Display.ReplConst(Display.white, V.X + 1, V.Y + newH - 1, V.W - 2, 1, 0) END Shrink; PROCEDURE Adjust (F: Display.Frame; id, dY, Y, H: INTEGER); VAR M: ModifyMsg; BEGIN M.id := id; M.dY := dY; M.Y := Y; M.H := H; F.handle(F, M); F.Y := Y; F.H := H 	END Adjust; PROCEDURE Restore (V: Viewer); VAR Menu, Main: Display.Frame; BEGIN Menu := V.dsc; Main := V.dsc.next; Oberon.RemoveMarks(V.X, V.Y, V.W, V.H); Draw(V); Menu.X := V.X + 1; Menu.Y := V.Y + V.H - 1; Menu.W := V.W - 2; Menu.H := 0; Main.X := V.X + 1; Main.Y := V.Y + V.H - V.menuH; Main.W := V.W - 2; Main.H := 0; IF V.H > V.menuH + 1 THEN Adjust(Menu, extend, 0, V.Y + V.H - V.menuH, V.menuH - 1); Adjust( Main, extend, 0, V.Y + 1, V.H - V.menuH - 1) ELSE Adjust(Menu, extend, 0, V.Y + 1, V.H - 2) END END Restore; PROCEDURE Modify (V: Viewer; Y, H: INTEGER); VAR Menu, Main: Display.Frame; BEGIN Menu := V.dsc; Main := V.dsc.next; IF Y < V.Y THEN (*extend*) Oberon.RemoveMarks(V.X, Y, V.W, V.Y - Y); Extend(V, Y); IF H > V.menuH + 1 THEN Adjust(Menu, extend, 0, Y + H - V.menuH, V.menuH - 1); Adjust(Main, extend, 0, Y + 1, H - V.menuH - 1) ELSE Adjust(Menu, extend, 0, Y + 1, H - 2) END ELSIF Y > V.Y THEN (*reduce*) Oberon.RemoveMarks(V.X, V.Y, V.W, V.H); IF H > V.menuH + 1 THEN Adjust(Main, reduce, 0, Y + 1, H - V.menuH - 1); Adjust(Menu, reduce, 0, Y + H - V.menuH, V.menuH - 1) ELSE Adjust(Main, reduce, 0, Y + H - V.menuH, 0); Adjust(Menu, reduce, 0, Y + 1, H - 2) END; Reduce(V, Y) 		END END Modify; PROCEDURE Change (V: Viewer; X, Y: INTEGER; Keys: SET); VAR Menu, Main: Display.Frame; V1: Viewers.Viewer; keysum: SET; Y0, dY, H: INTEGER; BEGIN (*Keys # {}*) Menu := V.dsc; Main := V.dsc.next; Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, X, Y); Display.ReplConst(Display.white, V.X + 1, V.Y + V.H - 1 - V.dsc.H, V.W - 2, V.dsc.H, 2); Y0 := Y; 		keysum := Keys; LOOP Input.Mouse(Keys, X, Y); IF Keys = {} THEN EXIT END; keysum := keysum + Keys; Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, X, Y) 		END; Display.ReplConst(Display.white, V.X + 1, V.Y + V.H - 1 - V.dsc.H, V.W - 2, V.dsc.H, 2); IF ~(0 IN keysum) THEN IF 1 IN keysum THEN V1 := Viewers.This(X, Y); IF Y < V1.Y + V.menuH + 2 THEN Y := V1.Y + V.menuH + 2 END; Viewers.Close(V); Viewers.Open(V, X, Y); Restore(V) ELSE IF Y > Y0 THEN (*extend*) dY := Y - Y0; V1 := Viewers.Next(V); IF V1.state > 1 THEN IF (V1 IS Viewer) & (V1.H >= V1(Viewer).menuH + 2) THEN IF dY > V1.H - V1(Viewer).menuH - 2 THEN dY := V1.H - V1(Viewer).menuH - 2 END ELSIF dY > V1.H - Viewers.minH THEN dY := V1.H - Viewers.minH END ELSIF dY > V1.H THEN dY := V1.H 					END; Viewers.Change(V, V.Y + V.H + dY); Oberon.RemoveMarks(V.X, V.Y, V.W, V.H); Grow(V, V.H - dY); IF V.H > V.menuH + 1 THEN Adjust(Menu, extend, dY, V.Y + V.H - V.menuH, V.menuH - 1); Adjust(Main, extend, dY, V.Y + 1, V.H - V.menuH - 1) ELSE Adjust(Menu, extend, dY, V.Y + 1, V.H - 2) END ELSIF Y < Y0 THEN (*reduce*) dY := Y0 - Y; 					IF dY > V.H - V(Viewer).menuH - 2 THEN dY := V.H - V(Viewer).menuH - 2 END; Oberon.RemoveMarks(V.X, V.Y, V.W, V.H); H := V.H - dY; IF H > V.menuH + 1 THEN Adjust(Main, reduce, dY, V.Y + 1, H - V.menuH - 1); Adjust(Menu, reduce, dY, V.Y + H - V.menuH, V.menuH - 1) ELSE Adjust(Main, reduce, dY, V.Y + H - V.menuH, 0); Adjust(Menu, reduce, dY, V.Y + 1, H - 2) END; Shrink(V, H); Viewers.Change(V, V.Y + H) 				END END END END Change; PROCEDURE Suspend (V: Viewer); VAR Menu, Main: Display.Frame; BEGIN Menu := V.dsc; Main := V.dsc.next; Adjust(Main, reduce, 0, V.Y + V.H - V.menuH, 0); Adjust(Menu, reduce, 0, V.Y + V.H - 1, 0) END Suspend; PROCEDURE Handle* (V: Display.Frame; VAR M: Display.FrameMsg); VAR Menu, Main: Display.Frame; V1: Viewer; BEGIN WITH V: Viewer DO 			Menu := V.dsc; Main := V.dsc.next; IF M IS Oberon.InputMsg THEN WITH M: Oberon.InputMsg DO 					IF M.id = Oberon.track THEN IF M.Y < V.Y + 1 THEN Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, M.X, M.Y) 						ELSIF M.Y < V.Y + V.H - V.menuH THEN Main.handle(Main, M) 						ELSIF M.Y < V.Y + V.H - V.menuH + 2 THEN Menu.handle(Menu, M) 						ELSIF M.Y < V.Y + V.H - 1 THEN IF 2 IN M.keys THEN Change(V, M.X, M.Y, M.keys) ELSE Menu.handle(Menu, M) 							END ELSE Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, M.X, M.Y) 						END ELSE Menu.handle(Menu, M); Main.handle(Main, M) 					END END ELSIF M IS Oberon.ControlMsg THEN WITH M: Oberon.ControlMsg DO 					IF M.id = Oberon.mark THEN Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, M.X, M.Y); Oberon.DrawCursor(Oberon.Pointer, Oberon.Star, M.X, M.Y) 					ELSE Menu.handle(Menu, M); Main.handle(Main, M) 					END END ELSIF M IS Oberon.CopyMsg THEN WITH M: Oberon.CopyMsg DO Copy(V(Viewer), V1); M.F := V1 END ELSIF M IS Viewers.ViewerMsg THEN WITH M: Viewers.ViewerMsg DO 					IF M.id = Viewers.restore THEN Restore(V) ELSIF M.id = Viewers.modify THEN Modify(V, M.Y, M.H) 					ELSIF M.id = Viewers.suspend THEN Suspend(V) END END ELSE Menu.handle(Menu, M); Main.handle(Main, M) 			END END END Handle; PROCEDURE New* (Menu, Main: Display.Frame; menuH, X, Y: INTEGER): Viewer; VAR V: Viewer; BEGIN NEW(V); V.handle := Handle; V.dsc := Menu; V.dsc.next := Main; V.menuH := menuH; Viewers.Open(V, X, Y); Restore(V); RETURN V 	END New; END MenuViewers.

title: Oberon/V2/MenuViewers


text:
Oberon/V2/Oberon

MODULE Oberon; (*JG 6.9.90*) IMPORT Kernel, Modules, Input, Display, Fonts, Viewers, Texts; CONST consume* = 0; track* = 1; (*input message id*) defocus* = 0; neutralize* = 1; mark* = 2; (*control message id*) BasicCycle = 20; ESC = 1BX; SETUP = 0A4X; TYPE Painter* = PROCEDURE (x, y: INTEGER); Marker* = RECORD Fade*, Draw*: Painter END; Cursor* = RECORD marker*: Marker; on*: BOOLEAN; X*, Y*: INTEGER END; ParList* = POINTER TO ParRec; ParRec* = RECORD vwr*: Viewers.Viewer; frame*: Display.Frame; text*: Texts.Text; pos*: LONGINT END; InputMsg* = RECORD (Display.FrameMsg) id*: INTEGER; keys*: SET; X*, Y*: INTEGER; ch*: CHAR; fnt*: Fonts.Font; col*, voff*: SHORTINT END; SelectionMsg* = RECORD (Display.FrameMsg) time*: LONGINT; text*: Texts.Text; beg*, end*: LONGINT END; ControlMsg* = RECORD (Display.FrameMsg) id*, X*, Y*: INTEGER END; CopyOverMsg* = RECORD (Display.FrameMsg) text*: Texts.Text; beg*, end*: LONGINT END; CopyMsg* = RECORD (Display.FrameMsg) F*: Display.Frame END; Task* = POINTER TO TaskDesc; TaskDesc* = RECORD next: Task; safe*: BOOLEAN; handle*: PROCEDURE END; VAR User*: ARRAY 8 OF CHAR; Password*: LONGINT; Arrow*, Star*: Marker; Mouse*, Pointer*: Cursor; FocusViewer*: Viewers.Viewer; Log*: Texts.Text; Par*: ParList; (*actual parameters*) CurTask*, PrevTask: Task; CurFnt*: Fonts.Font; CurCol*, CurOff*: SHORTINT; DW, DH, CL, H0, H1, H2, H3: INTEGER; ActCnt: INTEGER; (*action count for GC*) Mod: Modules.Module; PROCEDURE Min (i, j: INTEGER): INTEGER; BEGIN IF i <= j THEN RETURN i ELSE RETURN j END END Min; (*user identification*) PROCEDURE Code(VAR s: ARRAY OF CHAR): LONGINT; VAR i: INTEGER; a, b, c: LONGINT; BEGIN a := 0; b := 0; i := 0; WHILE s[i] # 0X DO 			c := b; b := a; a := (c MOD 509 + 1) * 127 + ORD(s[i]); INC(i) END; IF b >= 32768 THEN b := b - 65536 END; RETURN b * 65536 + a 	END Code; PROCEDURE SetUser* (VAR user, password: ARRAY OF CHAR); BEGIN COPY(user, User); Password := Code(password) END SetUser; (*clocks*) PROCEDURE GetClock* (VAR t, d: LONGINT); BEGIN Kernel.GetClock(t, d) 	END GetClock; PROCEDURE SetClock* (t, d: LONGINT); BEGIN Kernel.SetClock(t, d) 	END SetClock; PROCEDURE Time* : LONGINT; BEGIN RETURN Input.Time END Time; (*cursor handling*) PROCEDURE* FlipArrow (X, Y: INTEGER); BEGIN IF X < CL THEN IF X > DW - 15 THEN X := DW - 15 END ELSE IF X > CL + DW - 15 THEN X := CL + DW - 15 END END; IF Y < 15 THEN Y := 15 ELSIF Y > DH THEN Y := DH END; Display.CopyPattern(Display.white, Display.arrow, X, Y - 15, 2) END FlipArrow; PROCEDURE* FlipStar (X, Y: INTEGER); BEGIN IF X < CL THEN IF X < 7 THEN X := 7 ELSIF X > DW - 8 THEN X := DW - 8 END ELSE IF X < CL + 7 THEN X := CL + 7 ELSIF X > CL + DW - 8 THEN X := CL + DW – 8 END END ; IF Y < 7 THEN Y := 7 ELSIF Y > DH - 8 THEN Y := DH - 8 END; Display.CopyPattern(Display.white, Display.star, X - 7, Y - 7, 2) END FlipStar; PROCEDURE OpenCursor* (VAR c: Cursor); BEGIN c.on := FALSE; c.X := 0; c.Y := 0 END OpenCursor; PROCEDURE FadeCursor* (VAR c: Cursor); BEGIN IF c.on THEN c.marker.Fade(c.X, c.Y); c.on := FALSE END END FadeCursor; PROCEDURE DrawCursor* (VAR c: Cursor; VAR m: Marker; X, Y: INTEGER); BEGIN IF c.on & ((X # c.X) OR (Y # c.Y) OR (m.Draw # c.marker.Draw)) THEN c.marker.Fade(c.X, c.Y); c.on := FALSE END; IF ~c.on THEN m.Draw(X, Y); c.marker := m; c.X := X; c.Y := Y; c.on := TRUE END END DrawCursor; (*display management*) PROCEDURE RemoveMarks* (X, Y, W, H: INTEGER); BEGIN IF (Mouse.X > X - 16) & (Mouse.X < X + W + 16) & (Mouse.Y > Y - 16) & (Mouse.Y < Y + H + 16) THEN FadeCursor(Mouse) END; IF (Pointer.X > X - 8) & (Pointer.X < X + W + 8) & (Pointer.Y > Y - 8) & (Pointer.Y < Y + H + 8) THEN FadeCursor(Pointer) END END RemoveMarks; PROCEDURE* HandleFiller (V: Display.Frame; VAR M: Display.FrameMsg); BEGIN WITH V: Viewers.Viewer DO 			IF M IS InputMsg THEN WITH M: InputMsg DO 					IF M.id = track THEN DrawCursor(Mouse, Arrow, M.X, M.Y) END END; ELSIF M IS ControlMsg THEN WITH M: ControlMsg DO 					IF M.id = mark THEN DrawCursor(Pointer, Star, M.X, M.Y) END END ELSIF M IS Viewers.ViewerMsg THEN WITH M: Viewers.ViewerMsg DO 					IF (M.id = Viewers.restore) & (V.W > 0) & (V.H > 0) THEN RemoveMarks(V.X, V.Y, V.W, V.H); Display.ReplConst(Display.black, V.X, V.Y, V.W, V.H, 0) ELSIF (M.id = Viewers.modify) & (M.Y < V.Y) THEN RemoveMarks(V.X, M.Y, V.W, V.Y - M.Y); Display.ReplConst(Display.black, V.X, M.Y, V.W, V.Y - M.Y, 0) END END END END END HandleFiller; PROCEDURE OpenDisplay* (UW, SW, H: INTEGER); VAR Filler: Viewers.Viewer; BEGIN Input.SetMouseLimits(Viewers.curW + UW + SW, H); Display.ReplConst(Display.black, Viewers.curW, 0, UW + SW, H, 0); NEW(Filler); Filler.handle := HandleFiller; Viewers.InitTrack(UW, H, Filler); (*init user track*) NEW(Filler); Filler.handle := HandleFiller; Viewers.InitTrack(SW, H, Filler) (*init system track*) END OpenDisplay; PROCEDURE DisplayWidth* (X: INTEGER): INTEGER; BEGIN RETURN DW 	END DisplayWidth; PROCEDURE DisplayHeight* (X: INTEGER): INTEGER; BEGIN RETURN DH 	END DisplayHeight; PROCEDURE OpenTrack* (X, W: INTEGER); VAR Filler: Viewers.Viewer; BEGIN NEW(Filler); Filler.handle := HandleFiller; Viewers.OpenTrack(X, W, Filler) END OpenTrack; PROCEDURE UserTrack* (X: INTEGER): INTEGER; BEGIN RETURN X DIV DW * DW 	END UserTrack; PROCEDURE SystemTrack* (X: INTEGER): INTEGER; BEGIN RETURN X DIV DW * DW + DW DIV 8 * 5 END SystemTrack; PROCEDURE UY (X: INTEGER): INTEGER; VAR fil, bot, alt, max: Display.Frame; BEGIN Viewers.Locate(X, 0, fil, bot, alt, max); IF fil.H >= DH DIV 8 THEN RETURN DH END; RETURN max.Y + max.H DIV 2 END UY; PROCEDURE AllocateUserViewer* (DX: INTEGER; VAR X, Y: INTEGER); BEGIN IF Pointer.on THEN X := Pointer.X; Y := Pointer.Y 		ELSE X := DX DIV DW * DW; Y := UY(X) END END AllocateUserViewer; PROCEDURE SY (X: INTEGER): INTEGER; VAR fil, bot, alt, max: Display.Frame; BEGIN Viewers.Locate(X, DH, fil, bot, alt, max); IF fil.H >= DH DIV 8 THEN RETURN DH END; IF max.H >= DH - H0 THEN RETURN max.Y + H3 END; IF max.H >= H3 - H0 THEN RETURN max.Y + H2 END; IF max.H >= H2 - H0 THEN RETURN max.Y + H1 END; IF max # bot THEN RETURN max.Y + max.H DIV 2 END; IF bot.H >= H1 THEN RETURN bot.H DIV 2 END; RETURN alt.Y + alt.H DIV 2 END SY; PROCEDURE AllocateSystemViewer* (DX: INTEGER; VAR X, Y: INTEGER); BEGIN IF Pointer.on THEN X := Pointer.X; Y := Pointer.Y 			ELSE X := DX DIV DW * DW + DW DIV 8 * 5; Y := SY(X) END END AllocateSystemViewer; PROCEDURE MarkedViewer* : Viewers.Viewer; BEGIN RETURN Viewers.This(Pointer.X, Pointer.Y) 	END MarkedViewer; PROCEDURE PassFocus* (V: Viewers.Viewer); VAR M: ControlMsg; BEGIN M.id := defocus; FocusViewer.handle(FocusViewer, M); FocusViewer := V 	END PassFocus; (*command interpretation*) PROCEDURE Call* (VAR name: ARRAY OF CHAR; par: ParList; new: BOOLEAN; 		VAR res: INTEGER); VAR Mod: Modules.Module; P: Modules.Command; i, j: INTEGER; BEGIN res := 1; i := 0; j := 0; WHILE name[j] # 0X DO IF name[j] = "." THEN i := j END; INC(j) END; IF i > 0 THEN name[i] := 0X; IF new THEN Modules.Free(name, FALSE) END; Mod := Modules.ThisMod(name); IF Modules.res = 0 THEN INC(i); j := i; 				WHILE name[j] # 0X DO name[j - i] := name[j]; INC(j) END; name[j - i] := 0X; P := Modules.ThisCommand(Mod, name); IF Modules.res = 0 THEN Par := par; Par.vwr := Viewers.This(par.frame.X, par.frame.Y); P; res := 0 END ELSE res := Modules.res END END END Call; PROCEDURE GetSelection* (VAR text: Texts.Text; VAR beg, end, time: LONGINT); VAR M: SelectionMsg; BEGIN M.time := -1; Viewers.Broadcast(M); text := M.text; beg := M.beg; end := M.end; time := M.time END GetSelection; PROCEDURE* GC; VAR x: LONGINT; BEGIN IF ActCnt <= 0 THEN Kernel.GC; ActCnt := BasicCycle END END GC; PROCEDURE Install* (T: Task); VAR t: Task; BEGIN t := PrevTask; WHILE (t.next # PrevTask) & (t.next # T) DO t := t.next END; IF t.next = PrevTask THEN T.next := PrevTask; t.next := T END END Install; PROCEDURE Remove* (T: Task); VAR t: Task; BEGIN t := PrevTask; WHILE (t.next # T) & (t.next # PrevTask) DO t := t.next END; IF t.next = T THEN t.next := t.next.next; PrevTask := t.next END; IF CurTask = T THEN CurTask := PrevTask.next END END Remove; PROCEDURE Collect* (count: INTEGER); BEGIN ActCnt := count END Collect; PROCEDURE SetFont* (fnt: Fonts.Font); BEGIN CurFnt := fnt END SetFont; PROCEDURE SetColor* (col: SHORTINT); BEGIN CurCol := col END SetColor; PROCEDURE SetOffset* (voff: SHORTINT); BEGIN CurOff := voff END SetOffset; PROCEDURE Loop*; VAR V: Viewers.Viewer; M: InputMsg; N: ControlMsg; prevX, prevY, X, Y: INTEGER; keys: SET; ch: CHAR; BEGIN LOOP Input.Mouse(keys, X, Y); IF Input.Available > 0 THEN Input.Read(ch); IF ch < 0F0X THEN IF ch = ESC THEN N.id := neutralize; Viewers.Broadcast(N); FadeCursor(Pointer) ELSIF ch = SETUP THEN N.id := mark; N.X := X; N.Y := Y; V := Viewers.This(X, Y); V.handle(V, N) 					ELSE IF ch < " " THEN IF ch = 1X THEN ch := 83X (*ƒ*) ELSIF ch = 0FX THEN ch := 84X (*„*) ELSIF ch = 15X THEN ch := 85X (*...*) END ELSIF ch > "~" THEN IF ch = 81X THEN ch := 80X (*€*) ELSIF ch = 8FX THEN ch := 81X (* *) ELSIF ch = 95X THEN ch := 82X (*‚*) END END; M.id := consume; M.ch := ch; M.fnt := CurFnt; M.col := CurCol; M.voff := CurOff; FocusViewer.handle(FocusViewer, M); DEC(ActCnt) END ELSIF ch = 0F1X THEN Display.SetMode(0, {}) (*on*) ELSIF ch = 0F2X THEN Display.SetMode(0, {0}) (*off*) ELSIF ch = 0F3X THEN Display.SetMode(0, {2}) (*inv*) END ELSIF keys # {} THEN M.id := track; M.X := X; M.Y := Y; M.keys := keys; REPEAT V := Viewers.This(M.X, M.Y); V.handle(V, M); Input.Mouse(M.keys, M.X, M.Y) 				UNTIL M.keys = {}; DEC(ActCnt) ELSE IF (X # prevX) OR (Y # prevY) OR ~Mouse.on THEN M.id := track; M.X := X; M.Y := Y; M.keys := keys; V := Viewers.This(X, Y); V.handle(V, M); prevX := X; prevY := Y 				END; CurTask := PrevTask.next; IF ~CurTask.safe THEN PrevTask.next := CurTask.next END; CurTask.handle; PrevTask.next := CurTask; PrevTask := CurTask END END END Loop; BEGIN User[0] := 0X; Arrow.Fade := FlipArrow; Arrow.Draw := FlipArrow; Star.Fade := FlipStar; Star.Draw := FlipStar; OpenCursor(Mouse); OpenCursor(Pointer); DW := Display.Width; DH := Display.Height; CL := Display.ColLeft; H3 := DH - DH DIV 3; H2 := H3 - H3 DIV 2; H1 := DH DIV 5; H0 := DH DIV 10; OpenDisplay(DW DIV 8 * 5, DW DIV 8 * 3, DH); FocusViewer := Viewers.This(0, 0); CurFnt := Fonts.Default; CurCol := Display.white; CurOff := 0; Collect(BasicCycle); NEW(PrevTask); PrevTask.handle := GC; PrevTask.safe := TRUE; PrevTask.next := PrevTask; Mod := Modules.ThisMod("System"); Display.SetMode(0, {}) END Oberon.

title: Oberon/V2/Oberon


text:
User talk:Lli7

Welcome
Welcome to Wikibooks, Lli7!

 First steps tutorial Wikibooks is for collaborative development of free textbooks.

You do not need technical skills to contribute. You can easily change most books. Please introduce yourself, and let us know what interests you.

If you already contribute at other Wikimedia projects, our Wikimedia Orientation should quickly get you started. (Would you like to provide feedback on this message?)

  Getting help   Made a mistake?   Goodies, tips and tricks
 * Read the Using Wikibooks book for a friendly introduction to the project, or our help pages for more information.
 * You can get friendly help from the community in the user assistance room or our IRC channel.
 * Upload freely licensed files to Wikimedia Commons. You may request permission to upload fair use files locally. Please include author and source information and a non-free use rationale for non-free files.
 * You can restore a previously saved version.
 * Pages should follow the  naming convention.
 * Need to rename a page? Use the move tab (is available once your account is 4 days old - until then, ask for help).
 * To request a page be deleted, add to the top of the page.
 * Was a page you made deleted? Please read the deletion policy, and check the deletion log to find out why. Also check the RFD archives if applicable. You can request undeletion at WB:RFU, or ask the administrator who deleted the page.
 * Please fill in the edit summary and preview your edits before saving.
 * Sign your name on discussion pages by typing ~~~~
 * User scripts can make many tasks easier. Look at the Gadgets tab of my preferences; check off the boxes for the scripts you want, and hit save!

--Pi zero (discuss • contribs) 22:04, 27 January 2021 (UTC)

title: User talk:Lli7


text:
User talk:Tapsevarg

Welcome
Welcome to Wikibooks, Tapsevarg!

 First steps tutorial Wikibooks is for collaborative development of free textbooks.

You do not need technical skills to contribute. You can easily change most books. Please introduce yourself, and let us know what interests you.

If you already contribute at other Wikimedia projects, our Wikimedia Orientation should quickly get you started. (Would you like to provide feedback on this message?)

  Getting help   Made a mistake?   Goodies, tips and tricks
 * Read the Using Wikibooks book for a friendly introduction to the project, or our help pages for more information.
 * You can get friendly help from the community in the user assistance room or our IRC channel.
 * Upload freely licensed files to Wikimedia Commons. You may request permission to upload fair use files locally. Please include author and source information and a non-free use rationale for non-free files.
 * You can restore a previously saved version.
 * Pages should follow the  naming convention.
 * Need to rename a page? Use the move tab (is available once your account is 4 days old - until then, ask for help).
 * To request a page be deleted, add to the top of the page.
 * Was a page you made deleted? Please read the deletion policy, and check the deletion log to find out why. Also check the RFD archives if applicable. You can request undeletion at WB:RFU, or ask the administrator who deleted the page.
 * Please fill in the edit summary and preview your edits before saving.
 * Sign your name on discussion pages by typing ~~~~
 * User scripts can make many tasks easier. Look at the Gadgets tab of my preferences; check off the boxes for the scripts you want, and hit save!

--Pi zero (discuss • contribs) 22:07, 27 January 2021 (UTC)

title: User talk:Tapsevarg


text:
History of video games/Platforms/Tesla Arcade

Introduction
In the 2010s in car entertainment systems had a reputation for using poorly thought out designs in conjunction with sluggish software, with the design used on Tesla automobiles being somewhat better received then most of its competitors. To extend the potential of this system to include gaming as a function is an obvious progression. The Tesla Arcade was not the first attempt by an automaker to integrate a gaming system into a automobile, but it was one of the earliest serious attempts to offer an integrated game platform onboard the vehicle.

History
Gaming in automobiles has traditionally consisted of either simply using a portable system, or hooking up a separate dedicated console to an in car entertainment system through simple AV jacks.

On June 18th, 2019 Tesla launched the Tesla Arcade gaming service for its electric automobiles through a software update, using the existing steering wheel, infotainment screen, and compute resources of the car to create an impromptu game console out of existing hardware.

On January 27th, 2021 it was announced that the refreshed Model S would have a compute upgrade to allow play of more intensive games.

A Summer 2021 an update allowing for games to be played while the automobile is in motion later attracted the attention of news outlets and regulators.

In February of 2022 it was indicated that compatibility with Valve's Steam gaming service was a goal.

Technology
The 2021 refreshed Model S has a compute performance of about 10 teraflops.

Games

 * The Witcher 3
 * Cuphead


text:
User talk:Dpprog

Welcome
Welcome to Wikibooks, Dpprog!

 First steps tutorial Wikibooks is for collaborative development of free textbooks.

You do not need technical skills to contribute. You can easily change most books. Please introduce yourself, and let us know what interests you.

If you already contribute at other Wikimedia projects, our Wikimedia Orientation should quickly get you started. (Would you like to provide feedback on this message?)

  Getting help   Made a mistake?   Goodies, tips and tricks
 * Read the Using Wikibooks book for a friendly introduction to the project, or our help pages for more information.
 * You can get friendly help from the community in the user assistance room or our IRC channel.
 * Upload freely licensed files to Wikimedia Commons. You may request permission to upload fair use files locally. Please include author and source information and a non-free use rationale for non-free files.
 * You can restore a previously saved version.
 * Pages should follow the  naming convention.
 * Need to rename a page? Use the move tab (is available once your account is 4 days old - until then, ask for help).
 * To request a page be deleted, add to the top of the page.
 * Was a page you made deleted? Please read the deletion policy, and check the deletion log to find out why. Also check the RFD archives if applicable. You can request undeletion at WB:RFU, or ask the administrator who deleted the page.
 * Please fill in the edit summary and preview your edits before saving.
 * Sign your name on discussion pages by typing ~~~~
 * User scripts can make many tasks easier. Look at the Gadgets tab of my preferences; check off the boxes for the scripts you want, and hit save!

--Pi zero (discuss • contribs) 02:20, 28 January 2021 (UTC)

title: User talk:Dpprog


text:
User:Writetomithlesh

A book reader, reviewer and publisher who help writers to publish and list there's book, working with Authors Tree Publishing.

title: User:Writetomithlesh


text: Category:Book:Tyap

title: Category:Book:Tyap


text:
User:Steve M/huggle.yaml.js

--- enable: true version: "3.4.10 build: 3880 3.4.10" report-summary: "Reporting $1" confirm-multiple: false confirm-talk: true confirm-self-revert: true confirm-whitelist: true revert-on-multiple-edits: true automatically-resolve-conflicts: true software-rollback: false enforce-months-as-headers: true history-load: true on-next: 1 delete-edits-after-revert: true skip-to-last-edit: false preferred-provider: 2 remove-oldest-queue-edits: false truncate-edits: false talkpage-freshness: 20 remove-after-trusted-edit: true retrieve-founder: false display-title: false check-tp: true manual-warning: false summary-mode: false automatic-reports: false han-html: false han-display-user-talk: true han-display-bots: false han-display-user: true watchlist: "watch" automatically-group: false queue-id: "default" page-empty-queue: "" enable-max-score: false max-score: 0 enable-min-score: false min-score: 0 automatic-refresh: true automatically-watchlist-warned-users: false shortcut-hash: "" show-warning-if-not-on-last-revision: true number-dropdown-menu-items: true insert-edits-of-rolled-user-to-queue: true confirm-on-recent-warning: true recent-warning-time-span: 120 confirm-warning-on-very-old-edits: true skip-warning-on-confirm: true queues:
 * 1) // This is a configuration of huggle, do not change it unless you know what you are doing.
 * 1) // Last version of huggle that wrote into this configuration file (sanity check)
 * 1) // This option will change the behaviour of automatic resolution, be carefull
 * 1) // Get original creator of every page so that you can G7 instead of reverting the page
 * 1) // Periodically check if you received new messages and display a notification box if you get them
 * 1) // HAN
 * 1) // Whether edits made by same user should be grouped up together in page
 * 1) // Location of page (wiki page name, for example WP:Huggle) that should be displayed when you hit next and queue is empty. Leave empty for default page.
 * 1) // If true you will not warn users who received a warning recently
 * 1) // If warning was sent less than N seconds ago it's considered too recent
 * 1) // If true, the options above will not generate confirmation, but instead will be silently accepted (warning will not be sent)

title: User:Steve M/huggle.yaml.js


text:
Hacking/Background knowledge/Computer architecture/Python

Python is a dynamically-typed and garbage-collected structured, high-level and general-purpose programming language.There are excellent python pre-built libraries that can be used for both hacking or writing traditional programs.

At Centrum Wiskunde & Informatica (CWI) in the Netherlands, Guido van Rossum conceived Python in the late 1980s as a successor to the ABC programming language, which was inspired by SETL, capable of managing exceptions and interfacing with the Amoeba operating system.

The Basic Syntax Of Python3 Is :

There Are Hundreds Of Cyber Security Tools Written In Python.The basic Python library and modules provide a broad variety of functionality including built-in data types handling of exceptions,arithmetic modules etc.


text:
Hacking/Background knowledge/Ethernet/IPv4

The TCP/IP Is A collection of general conception instructions and specifications of particular networking protocols which is outlined in the TCP/IP model for the communication by computers over a network.

TCP/IP offers end-to-end communication that defines the encoding, address, transmission, routing and receiving of the data at the destination. The TCP / IP model is not equal to the OSI model, however the model has been influenced.

TCP/IP is essential to the Internet Protocol suite because Transmission Control Protocol (TCP) and internet protocol are the basic protocols of the suite (IP).TCP & IP Are Different Protocols But Commonly Referred To As "TCP/IP".

In Layman's Terms, IP is responsible for knowing where the information is supposed to go, Once the IP address has been identified, TCP is charged for sending that Information.

The Internet Protocol Suite offers end-to-end data processing showing how information is to be packed, addressed, transmitted, routed and received. This feature is organized into four layers of abstraction, which define each protocol by the networking sphere involved.