Skip to content

Commit dcd7701

Browse files
committed
PRML notes
1 parent 635d852 commit dcd7701

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1061026
-4
lines changed

Diff for: PRML/ch1.pdf

399 KB
Binary file not shown.

Diff for: PRML/ch1/figure/decision_boundary.png

47.8 KB
Loading

Diff for: PRML/ch1/figure/gaussian.png

29.8 KB
Loading

Diff for: PRML/ch1/figure/mle_bias.png

47.7 KB
Loading

Diff for: PRML/ch1/figure/probability_density.png

11.7 KB
Loading

Diff for: PRML/ch1/main.tex

+455
Large diffs are not rendered by default.

Diff for: README.md

+4
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,12 @@
2828
- [DDoS](./security/ddos/README.md)
2929
- [Security Cheatsheets](./security-cheatsheets)
3030
- [IoT](./security/iot-security.md)
31+
32+
## Machine Learning
3133
- [Machine Learning](./machine-learning/README.md)
3234
- [Maths](./maths/README.md)
35+
- Pattern_Recognition_And_Machine_Learning
36+
- [Ch1 Introduction](./PRML/ch1.pdf)
3337

3438

3539
## Resources

Diff for: algorithm/README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
* Backtracking
1616

1717
### 3. Sorting
18+
* [sort and scan](sort_and_scan)
19+
* [inverse quicksort](adversarial_input)
1820

1921
### 4. Binary Search
2022

@@ -27,5 +29,5 @@
2729
* Greedy algorithm
2830

2931
### 7. PageRank
30-
* [PageRank and Map-Reduce Implement (Chinese)](http://www.cnblogs.com/fengfenggirl/p/pagerank-introduction.html)
32+
* [mini web search engine](mini_web_search_engine)
3133

Diff for: algorithm/adversarial_input/.DS_Store

8 KB
Binary file not shown.

Diff for: algorithm/adversarial_input/abc.cpp

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#include <iostream>
2+
#include <fstream>
3+
#include <cstdlib>
4+
#include <algorithm>
5+
#include <assert.h>
6+
7+
using namespace std;
8+
9+
struct Node {
10+
int key;
11+
int size;
12+
Node *left;
13+
Node *right;
14+
Node (int k) { key = k; size = 1; left = right = NULL; }
15+
};
16+
17+
void fix_size(Node *T)
18+
{
19+
T->size = 1;
20+
if (T->left) T->size += T->left->size;
21+
if (T->right) T->size += T->right->size;
22+
}
23+
24+
// prints out the inorder traversal of T (i.e., the contents of T in sorted order)
25+
void print_inorder(Node *T)
26+
{
27+
if (T == NULL) return;
28+
print_inorder(T->left);
29+
cout << T->key << "\n";
30+
print_inorder(T->right);
31+
}
32+
33+
// Split tree T on rank r into tree L (containing ranks < r) and
34+
// a tree R (containing ranks >= r)
35+
void split(Node *T, int r, Node **L, Node **R)
36+
{
37+
if (T == NULL) {
38+
*L = NULL;
39+
*R = NULL;
40+
return;
41+
}
42+
int rank_of_root = T->left ? T->left->size : 0;
43+
if (r <= rank_of_root) {
44+
// recursively split left subtree
45+
split(T->left, r, L, &T->left);
46+
*R = T;
47+
} else {
48+
split(T->right, r-rank_of_root-1, &T->right, R);
49+
*L = T;
50+
}
51+
fix_size(T);
52+
}
53+
54+
// insert value v at rank r
55+
Node *insert_random(Node *T, int v, int r)
56+
{
57+
// If k is the Nth node inserted into T, then:
58+
// with probability 1/N, insert k at the root of T
59+
// otherwise, insert_random k recursively left or right of the root of T
60+
if (T == NULL) return new Node(v);
61+
if (rand() % (T->size + 1) == 0) {
62+
// insert at root
63+
Node *new_root = new Node(v);
64+
split(T, r, &new_root->left, &new_root->right);
65+
fix_size(new_root);
66+
return new_root;
67+
}
68+
int rank_of_root = T->left ? T->left->size : 0;
69+
if (r <= rank_of_root) T->left = insert_random(T->left, v, r);
70+
else T->right = insert_random(T->right, v, r - rank_of_root - 1);
71+
fix_size(T);
72+
return T;
73+
}
74+
75+
Node *T;
76+
77+
void generate(int N)
78+
{
79+
if (N==1) {
80+
T = insert_random(T, 1, 0);
81+
return;
82+
}
83+
generate(N-1);
84+
int pivot = 123456789%N;
85+
86+
// Old array-based solution:
87+
// for (int i=N-1; i>pivot; i--)
88+
// A[i] = A[i-1];
89+
// A[pivot] = N;
90+
91+
// Faster solution by encoding sequence in a balanced BST:
92+
T = insert_random(T, N, pivot);
93+
}
94+
95+
int main(int argc, char *argv[])
96+
{
97+
if (argc != 2) {
98+
cout << "Usage: bad1 <input size>\n";
99+
return 0;
100+
}
101+
102+
int N = atoi(argv[1]); // get first command-line argument
103+
if (N<1 || N>100000) {
104+
cout << "Invalid input size!\n";
105+
return 0;
106+
}
107+
108+
cout << N << "\n";
109+
generate(N);
110+
print_inorder(T);
111+
112+
return 0;
113+
}

Diff for: algorithm/adversarial_input/bad3.cpp

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#include <iostream>
2+
#include <algorithm>
3+
using namespace std;
4+
5+
// Generate a random number in the range 0..N-1
6+
int get_rand(int N)
7+
{
8+
// I forgot to attend the lecture where Prof Dean. explained how to generate
9+
// random numbers well, so hopefully this will work ok...
10+
// It looks like get_rand(N) always returns the same number if you call
11+
// it multiple times with the same value of N, but how could someone
12+
// possibly exploit that to make quicksort run slowly...
13+
return 123456789 % N;
14+
}
15+
16+
struct Node {
17+
int key;
18+
int size;
19+
Node *left;
20+
Node *right;
21+
Node (int k) { key = k; size = 1; left = right = NULL; }
22+
};
23+
24+
void fix_size(Node *T)
25+
{
26+
T->size = 1;
27+
if (T->left) T->size += T->left->size;
28+
if (T->right) T->size += T->right->size;
29+
}
30+
31+
// prints out the inorder traversal of T (i.e., the contents of T in sorted order)
32+
void print_inorder(Node *T)
33+
{
34+
if (T == NULL) return;
35+
print_inorder(T->left);
36+
cout << T->key << " ";
37+
print_inorder(T->right);
38+
}
39+
40+
// Split tree T on rank r into tree L (containing ranks < r) and
41+
// a tree R (containing ranks >= r)
42+
void split(Node *T, int r, Node **L, Node **R)
43+
{
44+
// TBD: please fill in this function appropriately
45+
if (T==NULL) {
46+
*L=NULL;
47+
*R=NULL;
48+
return;
49+
}
50+
int rank_of_root = T->left ? T->left->size : 0;
51+
if (r>rank_of_root) {
52+
split(T->right, r - rank_of_root - 1, &T->right, R);
53+
*L = T;
54+
} else {
55+
split(T->left, r, L, &T->left);
56+
*R = T;
57+
}
58+
fix_size(T);
59+
}
60+
61+
// insert value v at rank r
62+
Node *insert_keep_balanced(Node *T, int v, int r)
63+
{
64+
// TBD: fill this in
65+
if (T==NULL) return new Node(v);
66+
if (rand() % (T->size + 1) == 0) {
67+
Node *new_root = new Node(v);
68+
split(T, r, &new_root->left, &new_root->right);
69+
fix_size(new_root);
70+
return new_root;
71+
}
72+
int rank_of_root = T->left ? T->left->size : 0;
73+
if (r > rank_of_root) T->right = insert_keep_balanced(T->right, v, r - rank_of_root - 1);
74+
else T->left = insert_keep_balanced(T->left, v, r);
75+
fix_size(T);
76+
return T;
77+
}
78+
79+
// implement in a balanced BST
80+
void generate_adversarial(Node **T, int N)
81+
{
82+
if (N==1) {
83+
*T = insert_keep_balanced(*T, 1, 0);
84+
return;
85+
}
86+
generate_adversarial(T, N-1);
87+
int pivot = get_rand(N);
88+
89+
*T = insert_keep_balanced(*T, N, pivot);
90+
}
91+
92+
93+
int main(int argc, char *argv[])
94+
{
95+
if (argc != 2) {
96+
cout << "Usage: bad1 <input size>\n";
97+
return 0;
98+
}
99+
100+
int N = atoi(argv[1]); // get first command-line argument
101+
if (N<1 || N>100000) {
102+
cout << "Invalid input size!\n";
103+
return 0;
104+
}
105+
106+
// Generate and print bad input of size N for prog1
107+
// (currently just generates an input of N random numbers)
108+
cout << N << "\n";
109+
110+
//int *A = new int[N];
111+
//for (int i=0; i<N; i++)
112+
// A[i] = rand() % 1000000;
113+
114+
Node *T=NULL;
115+
generate_adversarial(&T, N);
116+
117+
print_inorder(T);
118+
//for (int i=0; i<N; i++)
119+
// cout << A[i] << "\n";
120+
121+
return 0;
122+
}

Diff for: algorithm/adversarial_input/hw2.pdf

77.6 KB
Binary file not shown.

Diff for: algorithm/adversarial_input/prog1.cpp

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#include <iostream>
2+
#include <algorithm>
3+
using namespace std;
4+
5+
// Solve the "longest line of sight" problem from lecture...
6+
7+
int main(void)
8+
{
9+
int N; // size of input
10+
if (!(cin >> N) || N < 1 || N > 100000) {
11+
cout << "Invalid input size!\n";
12+
return 0;
13+
}
14+
15+
// read input
16+
int *A = new int[N];
17+
for (int i=0; i<N; i++)
18+
if (!(cin >> A[i]) || A[i]<0) {
19+
cout << "Invalid input!\n";
20+
return 0;
21+
}
22+
23+
// compute max to left and max to right from each point
24+
int *max_to_left = new int[N];
25+
int *max_to_right = new int[N];
26+
max_to_left[1] = A[0];
27+
for (int i=2; i<N; i++)
28+
max_to_left[i] = max(A[i-1], max_to_left[i-1]);
29+
max_to_right[N-2] = A[N-1];
30+
for (int i=N-3; i>=0; i--)
31+
max_to_right[i] = max(A[i+1], max_to_right[i+1]);
32+
33+
// now find the longest line of sight:
34+
// for each element, scan left and right until we reach the
35+
// first larger element; record farthest such element found.
36+
int best = -1;
37+
for (int i=0; i<N; i++) {
38+
if (i>0 && max_to_left[i] >= A[i]) // is there someone larger on left?
39+
for (int j=i-1; j>=0; j--) // scan left until we reach someone larger
40+
if (A[j] >= A[i]) { best = max(best, i-j); break; }
41+
if (i<N-1 && max_to_right[i] >= A[i]) // is there someone larger on right?
42+
for (int j=i+1; j<N; j++) // scan right until we reach someone larger
43+
if (A[j] >= A[i]) { best = max(best, j-i); break; }
44+
}
45+
46+
cout << "Longest line of sight: " << best << "\n";
47+
return 0;
48+
}

Diff for: algorithm/adversarial_input/prog2.cpp

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#include <iostream>
2+
#include <algorithm>
3+
using namespace std;
4+
5+
// Find number of distinct elements using a hash table
6+
7+
struct Node {
8+
int val;
9+
Node *next;
10+
Node (int v, Node *n) { val = v; next = n; }
11+
};
12+
13+
Node **T; // array of Node *s for hash table
14+
int table_size = 10000;
15+
16+
// check out this awesome hash function!
17+
int hash(int x)
18+
{
19+
return ((unsigned int)x * 3 + 17) % table_size;
20+
}
21+
22+
bool find(int x)
23+
{
24+
for (Node *n = T[hash(x)]; n != NULL; n = n->next)
25+
if (n->val == x) return true;
26+
return false;
27+
}
28+
29+
void insert(int x)
30+
{
31+
int index = hash(x);
32+
T[index] = new Node(x, T[index]);
33+
}
34+
35+
int main(void)
36+
{
37+
int N; // size of input
38+
if (!(cin >> N) || N < 1 || N > 100000) {
39+
cout << "Invalid input size!\n";
40+
return 0;
41+
}
42+
43+
// read input
44+
int *A = new int[N];
45+
for (int i=0; i<N; i++)
46+
if (!(cin >> A[i]) || A[i]<0) {
47+
cout << "Invalid input!\n";
48+
return 0;
49+
}
50+
51+
// initialize hash table -- if I make it have size 10,000, then the
52+
// average length of a linked list should be small...
53+
T = new Node *[table_size];
54+
for (int i=0; i<table_size; i++)
55+
T[i] = NULL;
56+
57+
int count = 0;
58+
for (int i=0; i<N; i++)
59+
if (!find(A[i])) {
60+
count++;
61+
insert(A[i]);
62+
}
63+
64+
cout << "The input contains " << count << " distinct integers.\n";
65+
66+
return 0;
67+
}

0 commit comments

Comments
 (0)