Skip to content

Commit e2251ca

Browse files
authored
Merge pull request iiit-notebook#4 from iiit-notebook/master
Updating fork
2 parents 207f70e + 7ccc557 commit e2251ca

6 files changed

+255
-12
lines changed

2020-11-06-c-pro-lecture-22.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
title: C Pro Lecture 22
3+
author: Pratyaksh Gautam
4+
code: cs0.101
5+
number: 22
6+
---
7+
8+
## Preprocessor macros: conditionals
9+
10+
We can use conditionals even in the preprocessing stage by using macro conditionals:
11+
```c
12+
#ifdef DEBUG
13+
printf("We are debugging!\n");
14+
#endif
15+
```
16+
17+
If we either at a line at at the top, `#define DEBUG 1`, or if we compile using the following command then we the `printf` statement is executed and we get the output:
18+
```
19+
$ gcc -DDEBUG debug.c
20+
We are debugging!
21+
```
22+
23+
The code is replaced *before* compilation by the preprocessor, so if `DEBUG` is not defined, then the code sent to the compiler from the preprocessor does not have the line containing the `printf` statement at all.
24+
The inclusion of that line is a **compile-time decision**.
25+
This can be very convenient to manage debugging of the program while still keeping it production-ready.
26+
27+
## Loop invariants
28+
29+
Loop invariants refer to a 'property' of the code which is true for every iteration, and we maintain this throughout the successive iterations. What this means is that at the beginning of every iteration of the loop, we have a certain fact we know to be true, and we can use this for the logic of the loop.
30+
By the end of the iteration we ensure that the invariant will be true for the next iteration too, so we can use it again in the next iteration.
31+
32+
It is important to understand that loop invariants are not a feature of the C language, but just a concept that we use in order to keep better track of the logic of our code in a loop.
33+
34+
## More on assertions
35+
36+
We have seen assertions in the past and understand their use case. It is important to notice that assertions are **run-time decisions**.
37+
We can use assertions in conjunction with the concept of our loop invariants too, checking that the loop invariant is true at the beginning of every loop.
38+
Since the assertion fails and aborts the program telling us where we went wrong if our invariant is not valid, it can be very helpful in debugging.
39+
40+
*Note: If we wish, we can also disable assertions by defining the macro `NDEBUG`.*
41+
42+
## bitwise operators
43+
44+
At the hardware level, the smallest data size that we can read and write is 1 byte (8 bits).
45+
However there are also operations that we can and may want to conduct on individual bits, which are known as bitwise operations.
46+
These include bitwise `AND`, `OR`, `XOR`, etc. Their effects can be represented using familiar truth tables.
47+
48+
```
49+
10000100 AND 01000110 = 00000100
50+
10000100 OR 01000110 =
51+
10000100 XOR 01000110 =
52+
```
53+
54+
### bitwise shifts
55+
We can also shift the bits to the left or the right. Consider the left shift `<<` in the following situation
56+
```
57+
[ b7 b6 b5 b4 b3 b2 b1 b0 ]
58+
<< //shift by one
59+
[ b6 b5 b4 b3 b2 b1 b0 00 ] // b7 "falls off"
60+
61+
[ b7 b6 b5 b4 b3 b2 b1 b0 ]
62+
>> //shift by one
63+
[ 00 b7 b6 b5 b4 b3 b2 b1 ] // b7 "falls off"
64+
```
65+
66+
The above logic is perfectly valid for unsigned integers, but because of the way that we represent signed integers means that it isn't so clear cut for signed integers.
67+
68+
## A set of function to print the bit representation of a number
69+
70+
```c
71+
void readBit(int N, int pos)
72+
{
73+
unsigned int mask;
74+
mask = 1 << pos;
75+
return (N & mask)? 1: 0;
76+
}
77+
```
78+
The above functions takes a number `N` and returns its `pos`'th bit.
79+
Note that `mask = 1 << pos` gives a bitstring such that all its bits are `0` except the bit at the `pos`'th position.
80+
So when we do an `AND` operation against `mask`, all but the `pos`'th bit will definitely output a `0`, and the `pos`'th bit of N will output whatever its own value is.
81+
Thus, we just use the ternary operator to return `0` if that bit is `0`, and `1` otherwise.
82+
83+
```c
84+
void printBits(int N)
85+
{
86+
printf("(%d)_2 : ", N);
87+
for (int i = 8 * sizeof(int); i >= 0; --i) {
88+
printf("%d", readBit(N, i);
89+
}
90+
printf("\n");
91+
}
92+
```
93+
Now this function just calls the above function, and prints the relevant bits in order.

_posts/2020-09-22-ict-lecture-3.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,18 @@ For AC mains there are two popular standards, 220V/50Hz and 110V/60Hz, in India
2828

2929
*Why is AC mains a sinusoidally-varying wave?*
3030
AC Mains varies as a sinusoidal function, essentially because of the way it is commonly generated.
31-
We use turbines, which are rotated in some form or the other to generate our electricity, often by steam or falling water. Assuming an ideal case where we are able to rotate the turbines at a constant angular velocity $\omega$
32-
Then the magnetic flux through the coil which we use in the generator is given by $\phi = nAB\cos{\omega t}$, and by Faraday-Lens' Law, we have the induced potential difference,
31+
We use turbines, which are rotated in some form or the other to generate our electricity, often by steam or falling water. Assuming an ideal case where we are able to rotate the turbines at a constant angular velocity $\omega$
32+
Then the magnetic flux through the coil which we use in the generator is given by $\phi = nAB\cos{\omega t}$, and by Faraday-Lens' Law, we have the induced potential difference,
3333
$$E = - \frac{d\phi}{dt} = nAB\omega \sin{\omega t}$$
3434

35-
To get DC, we must first *rectify* the sine wave, so that it only has one polarity, and then we must *filter* it to smooth it out into a better, more stable current. These are our two main steps.
35+
To get DC, we must first *rectify* the sine wave, so that it only has one polarity, and then we must *filter* it to smooth it out into a better, more stable current. These are our two main steps.
3636

3737
We must also lower the voltage of the current with a *transformer*, since most household appliances run on around ~10V to ~24V. We can conveniently change the transformation ratio by changing the number of coils, since in a transformer
38-
$$\frac{V_P}{V_S} = \frac{N_P}{N_S}$$
38+
$$\frac{V_{ P }}{V_{ S }} = \frac{N_{ P }}{N_{ S }}$$
3939

40-
We also have to deal with varying load conditions. When a large current is drawn from a battery, in practical situations its peak voltage is reduced. This is a natural consequence of Ohm's Law when a battery has any internal resistance. We can calculate the terminal potential difference $V_0$ as
41-
$$V_0 = V_in - IR_in = \frac{R_load}{R_load + R_in}$$
42-
where $V_in$ is the EMF of the cell.
40+
We also have to deal with varying load conditions. When a large current is drawn from a battery, in practical situations its peak voltage is reduced. This is a natural consequence of Ohm's Law when a battery has any internal resistance. We can calculate the terminal potential difference $V_{ 0 }$ as
41+
$$V_{ 0 } = V_{ in } - IR_{ in } = \frac{R_{ load }}{R_{ load } + R_{ in }}$$
42+
where $V_{ in }$ is the EMF of the cell.
4343

4444
## Switching Mode Power Supply (SMPS)
4545

_posts/2020-10-08-ds-lecture-8.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Given an equivalence relation $R$ on a set $A$, the *equivalence class* of an ar
2828
The set of all equivalence classes of $A$ with respect to $R$ form a *partition* of $A$. A partition of a set $A$ is a collection of disjoint subsets $A_{i}$ (called *parts*) of $A$ whose union is $A$, *i.e.*, mutually exclusive and exhaustive.
2929

3030
Also, given a partition $P = \{A_{1}, A_{2},...,A_{k}\}$ of $A$, an equivalence relation can be defined on A as
31-
<div>$$R = \{(x,y) \in A \times A | x,y \in $A_{i}\}$$</div>
31+
<div>$$R = \{(x,y) \in A \times A | x,y \in A_{i}\}$$</div>
3232

3333
Thus, defining an equivalence relation on a set is precisely the same as partitioning it, since the equivalence classes form a partition, and any partition gives rise to an equivalence relation.
3434

@@ -65,11 +65,11 @@ Since $k$ ranges from 0 to $n$, we obtain the following recursion:
6565

6666
<div>
6767
$$
68-
\begin{align}
68+
\begin{aligned}
6969
B_{n+1} & = \sum_{k = 0}^{n} { {n} \choose {k} }{B_{n-k} } \\
7070
& = \sum_{k=0}^{n} { {n} \choose {n-k} }{B_{k} } \\
7171
& = \sum_{k=0}^{n} { {n} \choose {k} }{B_{k} }
72-
\end{align}
72+
\end{aligned}
7373
$$
7474
</div>
7575

@@ -83,7 +83,7 @@ Let $P(R)$ indicate that $R$ has a certain property $P$. Then, the closure of $R
8383
2. $R \subseteq R_{P}$.
8484
3. $R \subseteq R' \wedge P(R') \Rightarrow R_{P} \subseteq R'$, *i.e.*, $R_{P}$ is the smallest set satisfying (1) and (2).
8585

86-
The reflexive closure of a relation over a set $A$ is obtained by taking its union with the set <div>$$\Delta = \{(a,a)\, \vert \, a \in A\}$$</div>*i.e.*,
86+
The reflexive closure of a relation over a set $A$ is obtained by taking its union with the set $\Delta = \{(a,a)\, \vert \, a \in A\}$*i.e.*,
8787
<div>$$r(R) = R \cup \Delta$$</div>
8888

8989
The symmetric closure of a relation is obtained by taking its union with its inverse, *i.e.*,

_posts/2020-10-27-ds-lecture-18.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
title: DS lecture 18
3+
author: Shashwat Singh
4+
code: ma5.101
5+
number: 18
6+
---
7+
8+
# Mathematical induction
9+
## Peano's postulates on $\mathbb{N}$
10+
- **postulate 1**: $1 \in \mathbb{N}$ , that is 1 is a natural number.
11+
- **posulate 2**: for each $n \in \mathbb{N}$ , there exists a unique natural number $n^+ \in \mathbb{N}$ called the successor $| n^+ = n + 1$
12+
- **postulate 3**: $1$ is not the successor of any natural number.
13+
- **postulate 4**: if $m, n \in \mathbb{N}$ and $m = n$ then $m^+ = n^+$ i.e. each natural number if a successor is the successor of a unque natural number.
14+
- **postulate 5**: if $k \subseteq \mathbb{N}$ such that $1 \in K$ and $n \in K \implies n^+ \in K$ then $K = N$
15+
**Deduction 1**: Every element $n|n \in \mathbb{N}$ and $n \not=1$ is the successor of some other element in $\mathbb{N}$
16+
**Deduction 2**: $m^+ \not= m \forall m\in N$
17+
18+
## Order relations in the system of natural numbers
19+
- **Law of trichotomy**: if $m, n \in \mathbb{N}$, any of the following *must* hold:
20+
- $m > n$
21+
- $m = n$
22+
- $m < n$
23+
- **Law of transitivity**: if $m, n, p, \in \mathbb{N}$ then $(m > n) \land (n > p) \implies m > p$
24+
- **Monotone law of addition**: if $m, n, p \in \mathbb{N}$ then $m > n \implies m + p > n + p$
25+
- **Monotone law of multiplication**: if $m, n, p \in \mathbb{N}$ then $m > n \implies m.p > n.p$
26+
27+
## Well ordering principle
28+
The set of all natural numbers is said to be *well-ordered* that is, every non empty subset of $\mathbb{N}$ has a least element.
29+
30+
## First principle of Mathmatical induction
31+
For a given open open statement $P(n)$ involving $n|n \in \mathbb{N}$ *if* we can show that:
32+
1. $P(n_0)$ is true
33+
2. and $P(k+1)$ is true given for an **arbitrarily chosen but particular** $k$ $P(k)$ is true.
34+
Then we can conclude that $P(n)$ is true for all natural number $n \geq n_0$
35+
- First step is referred to as the basis of induction
36+
- Second step is referred to as the *induction step* and the assumption that $P(k)$ is true is referred to as the induction hypothesis.
37+
38+
**Proof**:
39+
Let $P(n)$ be an open statement satisfying conditions (1.) and (2.) and let $A = \{t \in \mathbb{N} \land t \geq n_0 | P(t) \text{is false}\}$ note that $A \subset \mathbb{N}$. We need to prove that $A = \phi$ and thus we assume the *contrary* that is $A \not= \phi$ and thus by the *well ordering principle* we can conclude that $A$ has a least number. Let $m$ be the least element of $A$, we know that $m \not= n_0$ because $P(n_0)$ is true by condition (1.) and thus $m > n_0$ . By our definition of $A$ we can also say that $P(m-1)$ is true and since $P(n)$ also adheres to condition (2.): if $P((m-1)+1)$is also true there will be a contradiction.
40+
Hence, by proof by contradiction, we can say that $A = \phi$ if 1. and 2. imply $A = \phi$ .
41+
or in other words $P(n)$ is true for all elements $n|n > n_0$
42+
43+
## Second principle of mathematical induction
44+
For a given statement $P(n)$ involving a natural number $n$ if we can show that:
45+
1. $P(n)$ is true for $n = n_0$
46+
2. The statement $P(n)$ is true for $n = k + 1$ assuming it is true for $n_0 \geq k \geq n$
47+
The we can conclude that $P(n)$ is true for all natural numbers $n \geq n_0$
48+
- The first step is called the basis of inductions
49+
- The second step is called the induction step and the assumption is called induction hypothesis.
50+
51+
This can be proved in a very similar way as the first principle.
52+
53+
## Tips and template for using Methematical induction
54+
- Express the statement that is to proved in the form "for all $n \geq b, P(n)$" for a particular integer $b$
55+
- We need to show $P(b)$ is true, this is the basis case.
56+
- Write out the inductive step, i.e. assuming $P(k)$, $k \geq b$ for an arbitrarily chosen particular $k$ is true.
57+
- Now show that $P(k+1$ ) is also true.
58+
- "$P(n)$ is true for all $n \geq b$"

_posts/2020-10-28-c-pro-lecture-20.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,3 @@ This means that if we cal `count()` twice, it will give values `1` and `2`.
8484

8585
Note that scope is enforced by the compiler, which limits the scope of `counter` to the scope of the function `count()`.
8686
The variable itself is stored in the data section of the program's memory, and it's lifetime is the whole program execution.
87-

_posts/2020-11-06-c-pro-lecture-22.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
title: C Pro Lecture 22
3+
author: Pratyaksh Gautam
4+
code: cs0.101
5+
number: 22
6+
---
7+
8+
## Preprocessor macros: conditionals
9+
10+
We can use conditionals even in the preprocessing stage by using macro conditionals:
11+
```c
12+
#ifdef DEBUG
13+
printf("We are debugging!\n");
14+
#endif
15+
```
16+
17+
If we either at a line at at the top, `#define DEBUG 1`, or if we compile using the following command then we the `printf` statement is executed and we get the output:
18+
```
19+
$ gcc -DDEBUG debug.c
20+
We are debugging!
21+
```
22+
23+
The code is replaced *before* compilation by the preprocessor, so if `DEBUG` is not defined, then the code sent to the compiler from the preprocessor does not have the line containing the `printf` statement at all.
24+
The inclusion of that line is a **compile-time decision**.
25+
This can be very convenient to manage debugging of the program while still keeping it production-ready.
26+
27+
## Loop invariants
28+
29+
Loop invariants refer to a 'property' of the code which is true for every iteration, and we maintain this throughout the successive iterations. What this means is that at the beginning of every iteration of the loop, we have a certain fact we know to be true, and we can use this for the logic of the loop.
30+
By the end of the iteration we ensure that the invariant will be true for the next iteration too, so we can use it again in the next iteration.
31+
32+
It is important to understand that loop invariants are not a feature of the C language, but just a concept that we use in order to keep better track of the logic of our code in a loop.
33+
34+
## More on assertions
35+
36+
We have seen assertions in the past and understand their use case. It is important to notice that assertions are **run-time decisions**.
37+
We can use assertions in conjunction with the concept of our loop invariants too, checking that the loop invariant is true at the beginning of every loop.
38+
Since the assertion fails and aborts the program telling us where we went wrong if our invariant is not valid, it can be very helpful in debugging.
39+
40+
*Note: If we wish, we can also disable assertions by defining the macro `NDEBUG`.*
41+
42+
## bitwise operators
43+
44+
At the hardware level, the smallest data size that we can read and write is 1 byte (8 bits).
45+
However there are also operations that we can and may want to conduct on individual bits, which are known as bitwise operations.
46+
These include bitwise `AND`, `OR`, `XOR`, etc. Their effects can be represented using familiar truth tables.
47+
48+
```
49+
10000100 AND 01000110 = 00000100
50+
10000100 OR 01000110 =
51+
10000100 XOR 01000110 =
52+
```
53+
54+
### bitwise shifts
55+
We can also shift the bits to the left or the right. Consider the left shift `<<` in the following situation
56+
```
57+
[ b7 b6 b5 b4 b3 b2 b1 b0 ]
58+
<< //shift by one
59+
[ b6 b5 b4 b3 b2 b1 b0 00 ] // b7 "falls off"
60+
61+
[ b7 b6 b5 b4 b3 b2 b1 b0 ]
62+
>> //shift by one
63+
[ 00 b7 b6 b5 b4 b3 b2 b1 ] // b7 "falls off"
64+
```
65+
66+
The above logic is perfectly valid for unsigned integers, but because of the way that we represent signed integers means that it isn't so clear cut for signed integers.
67+
68+
## A set of function to print the bit representation of a number
69+
70+
```c
71+
void readBit(int N, int pos)
72+
{
73+
unsigned int mask;
74+
mask = 1 << pos;
75+
return (N & mask)? 1: 0;
76+
}
77+
```
78+
The above functions takes a number `N` and returns its `pos`'th bit.
79+
Note that `mask = 1 << pos` gives a bitstring such that all its bits are `0` except the bit at the `pos`'th position.
80+
So when we do an `AND` operation against `mask`, all but the `pos`'th bit will definitely output a `0`, and the `pos`'th bit of N will output whatever its own value is.
81+
Thus, we just use the ternary operator to return `0` if that bit is `0`, and `1` otherwise.
82+
83+
```c
84+
void printBits(int N)
85+
{
86+
printf("(%d)_2 : ", N);
87+
for (int i = 8 * sizeof(int); i >= 0; --i) {
88+
printf("%d", readBit(N, i);
89+
}
90+
printf("\n");
91+
}
92+
```
93+
Now this function just calls the above function, and prints the relevant bits in order.

0 commit comments

Comments
 (0)