forked from lava/matplotlib-cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathalgo.cpp
More file actions
128 lines (104 loc) · 2.87 KB
/
algo.cpp
File metadata and controls
128 lines (104 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <iostream>
#include <vector>
#include <string>
#include <Python.h>
#include "matplotlibcpp.h"
#include <math.h>
#include <map>
namespace plt = matplotlibcpp;
// Parabola Function
double fx(double x, double y)
{
return -(pow(x, 2) + pow(y, 2));
}
// Gradient for dx
double dfx(double x, double y)
{
return -2.0*x;
}
// Gradient for dy
double dfy(double x, double y)
{
return -2.0*y;
}
// Plane Equation
double plane(double x, double y, double x0, double y0)
{
return dfx(x0, y0)*(x - x0) + dfy(x0, y0)*(y - y0) + fx(x0, y0);
}
// Generates a tangent plane
std::map<std::string, std::vector<std::vector<double>>> Tangent(double c, double x0, double y0)
{
// Setting grid bounds
double m0 = x0 - c, m1 = x0 + c;
double n0 = y0 - c, n1 = y0 + c;
int o = 60;
double dM = (m1 - m0)/(o - 1);
double dN = (n1 - n0)/(o - 1);
std::map<std::string, std::vector<std::vector<double>>> result;
std::vector<double> tx, ty, tz;
double rx, ry;
// Building the plane at a centered point (where the current gradient is)
for(int i = 0; i < o; ++i){
tx.clear();
ty.clear();
tz.clear();
rx = m0 + i*dM;
for(int j = 0; j < o; ++j){
ry = n0 + j*dM;
tx.push_back(rx);
ty.push_back(ry);
tz.push_back(plane(rx, ry, x0, y0));
}
result["x"].push_back(tx);
result["y"].push_back(ty);
result["z"].push_back(tz);
}
return result;
}
int main()
{
// Declare the plot
PyObject * ax = plt::chart(111);
plt::Clear3DChart(ax);
// Define range
int n = 60;
double t0 = -4.0, t1 = 4.0;
double dT = (t1 - t0)/(n - 1);
std::vector<std::vector<double>> x, y, z;
std::vector<double> tx, ty, tz;
double rx, ry;
// Build 3D graph for the parabola
for(int i = 0; i < n; ++i){
tx.clear();
ty.clear();
tz.clear();
rx = t0 + i*dT;
for(int j = 0; j < n; ++j){
ry = t0 + j*dT;
tx.push_back(rx);
ty.push_back(ry);
tz.push_back(fx(rx, ry));
}
x.push_back(tx);
y.push_back(ty);
z.push_back(tz);
}
// Build 3D animation for the gradient reaching its maximum and the plane centered around the gradient points
double Px = -3.5, Py = -3.5;
double learning = 0.15;
std::map<std::string, std::vector<std::vector<double>>> gd;
for(int i = 0; i < 100; ++i){
plt::Clear3DChart(ax);
gd = Tangent(2, Px, Py);
// Plots the parabola and gradient plane
plt::surface3D(ax, x, y, z, "red", 0.9);
plt::surface3D(ax, gd["x"], gd["y"], gd["z"], "green", 0.9);
// Updates the gradients in gradient descent
Px = Px + learning*dfx(Px, Py);
Py = Py + learning*dfy(Px, Py);
plt::pause(0.5);
}
plt::show();
return 0;
}