Skip to content

Commit 2042881

Browse files
committed
Start from materials of past years
1 parent 75d8f9a commit 2042881

26 files changed

+2328
-0
lines changed

.gitignore

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
*.aux
2+
/*.fdb_latexmk
3+
/*.log
4+
/*.fls
5+
/*.out
6+
/*.run.xml
7+
/*.toc
8+
/*.bbl
9+
/*.bcf
10+
/*.blg
11+
/*.synctex.gz
12+
/*.pytxcode
13+
_minted-*/
14+
pythontex-files-*/
15+
16+
17+
*.pdf
18+
!images/*.pdf

01/hello_world.tex

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
% !TEX encoding = UTF8
2+
% !TEX spellcheck = ru_RU
3+
% !TEX root = ../../seminars.tex
4+
5+
%%=====================
6+
\chapter{Hello, World!}\label{chap:helloworld}
7+
%%=====================
8+
9+
%%==================================================
10+
\section{Архитектура Фон-Неймана, уровни абстракции}
11+
%%==================================================
12+
Схематическое устройство компьютера. Алгоритмы и языки программирования. Абстракция от реального <<железа>>.
13+
14+
15+
16+
%%=================
17+
\section{Программы}
18+
%%=================
19+
\lang{С++}\footcite{Stroustrup:2019:ru} является компилируемым языком. Для работы программы её исходный текст должен быть обработан с помощью компилятора, который создаёт объектные файлы, объединяемые компоновщиком в выполнимую программу. Обычно программы на языке \lang{С++} состоят из многих файлов с исходными текстами (именуемыми просто \textit{исходными файлами}).
20+
21+
\begin{center}\begin{tikzpicture}[node font=\small, >=Stealth, line width=1pt]
22+
\graph [grow right sep, left anchor=east, right anchor=west, nodes=draw] {
23+
"файл1.cpp" -> c1/{компиляция} [ellipse] -> "файл1.o" ->[right anchor=north west] "компоновка" [ellipse, yshift=-2.5ex] -> "выполнимый файл"[yshift=-2.5ex];
24+
"файл2.cpp" -> c2/{компиляция} [ellipse] -> "файл2.o" ->[right anchor=south west] "компоновка";
25+
};
26+
\end{tikzpicture}\end{center}
27+
28+
Выполнимая программа создаётся для определённой комбинации аппаратного обеспечения и операционной системы; её нельзя просто перенести, скажем, из компьютера \name{Мac} в компьютер с \name{Windows}. Говоря о переносимости программ \lang{С++}, мы обычно имеем в виду переносимость исходного кода, т.\,е. исходный код может быть успешно скомпилирован и выполняться в разных
29+
системах.
30+
31+
Стандарт \name{ISO} \lang{С++} определяет два типа сущностей.
32+
\begin{itemize}
33+
\item \textit{Фундаментальные возможности языка}, такие как встроенные типы (например, \code{char} и \code{int}) или циклы (например, инструкции \code{for} и \code{while}).
34+
35+
\item \textit{Компоненты стандартных библиотек}, такие как контейнеры (например, \code{vector}, и \code{map}) или операции ввода--вывода (например, \code{<<} и \code{getline()}).
36+
\end{itemize}
37+
38+
Компоненты стандартной библиотеки представляют собой совершенно обычный код \code{С++}, предоставляемый каждой реализацией языка. То есть стандартная библиотека \code{С++} может быть реализована в самом \code{С++} (и реализуется "--- с очень небольшим использованием машинного кода для таких вещей, как переключение контекста потока). Это означает, что \code{С++} достаточно выразителен и эффективен для самых сложных задач системного программирования.
39+
40+
\code{С++} является статически типизированным языком, т.е. тип каждой сущности (например, объекта, значения, имени или выражения) должен быть известен компилятору в точке использования. Тип объекта определяет набор применимых к нему операций.
41+
42+
43+
44+
%%==================================
45+
\section{Метод наименьших квадратов}
46+
%%==================================
47+
48+
%%===============================
49+
\subparagraph{Постановка задачи.}
50+
%%===============================
51+
Рассмотрим регрессию (зависимость) следующего вида:
52+
\begingroup
53+
\newcommand{\SumN}{\ensuremath{\sum\limits_{i=1}^{N}}}
54+
\[
55+
y_i = a + b x_i + \varepsilon_i,\quad i = \overline{1, N}.
56+
\]
57+
Среди всевозможных значений \(\{ a, b \}\) будем искать такие, которые приводят к минимальной сумме квадратов отклонений (ошибок):
58+
\[
59+
S_{\varepsilon} = \SumN \varepsilon_i^2 = \SumN (y_i - a - b x_i)^2\quad\rightarrow\quad \min\limits_{a, b}.
60+
\]
61+
Запишем условие существования экстремума:
62+
\[
63+
\begin{array}{l}
64+
\dfrac{\partial}{\partial a} S_{\varepsilon} = -2 \SumN (y_i - a - b x_i) = 0, \\[2ex]
65+
\dfrac{\partial}{\partial b} S_{\varepsilon} = -2 \SumN (y_i - a - b x_i) x_i = 0, \\
66+
\end{array}
67+
\]
68+
откуда получим систему линейных уравнений:
69+
\[
70+
\left\{ \begin{array}{l}
71+
\SumN y_i - N a - b\SumN x_i = 0, \\[2ex]
72+
\SumN x_i y_i - a\SumN x_i - b\SumN x_i^2 = 0. \\
73+
\end{array} \right.
74+
\]
75+
Вводя обозначение для среднего арифметического множества значений некоторой величины \(f\):
76+
\[
77+
\bar f = \dfrac{1}{N}\SumN f_i,
78+
\]
79+
перепишем систему в виде:
80+
\[
81+
\left\{ \begin{array}{l}
82+
\bar y - a - b\bar x = 0, \\
83+
\overline{x y} - a\bar x - b\overline{x^2} = 0, \\
84+
\end{array} \right.
85+
\]
86+
и получим искомое решение:
87+
\[
88+
\boxed{\begin{array}{l}
89+
a = \bar y - b\bar x, \\
90+
b = \dfrac{\overline{x y} - \bar x\bar y}{\overline{x^2} - \bar x^2}. \\
91+
\end{array}}
92+
\]
93+
\endgroup
94+
95+
96+
97+
%%====================================
98+
\subparagraph{Программная реализация.}
99+
%%====================================
100+
Решение этой задачи может быть выражено на языке \lang{C++} следующим образом:\label{code:lsm}
101+
102+
\cppfile{01/src/least_squares.cpp}
103+
104+
105+
106+
%%================
107+
\WhatToReadSection
108+
%%================
109+
\textcite{Stroustrup:2016:ru}: \textbf{главы~0, 1 и~2}
110+
111+
112+
113+
%%===============
114+
\ExercisesSection
115+
%%===============
116+
\begin{exercise}
117+
\item Настройте среду разработки программ на языке \lang{C++} (см. страницу \pageref{sect:workEnv}).
118+
119+
120+
\item Создайте свой первый проект с традиционной программой \textenglish{Hello, World!}.
121+
122+
\smallskip
123+
\emph{Совет}: воспользуйтесь графическими инструкциями из архива
124+
\begin{flushleft}
125+
\yadisk{cpp-seminars/how-to-s/how-to\_create-project.zip}.
126+
\end{flushleft}
127+
128+
Заголовочный файл \code{std\_lib\_facilities.h} из книги Страуструпа размещён в директории \yadisk{cpp-seminars/libraries}.
129+
130+
131+
\item \textbf{NB!} Внимательно изучите и возьмите на вооружение <<горячие клавиши>> среды разработки. Начните осваивать печать вслепую.
132+
133+
\smallskip
134+
\emph{Совет}: воспользуйтесь информацией из раздела на странице~\pageref{sect:typing}.
135+
\end{exercise}

01/src/empty.txt

Whitespace-only changes.

01/src/gen.py

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/python3
2+
3+
import argparse, random
4+
5+
parser = argparse.ArgumentParser (description = "Generate test data for the least "
6+
"squares method: yi = a + b*xi + epsi")
7+
parser.add_argument ("a", type=float,
8+
help="Constant coefficient in regression model")
9+
parser.add_argument ("b", type=float,
10+
help="Linear coefficient in regression model")
11+
parser.add_argument ("-o", "--output", type=str, default="data.out",
12+
help="Output filename [default: %(default)s]")
13+
parser.add_argument ("-e","--epsilon", type=float, default=0.1,
14+
help="Standard deviation of experiment error [default: %(default)s]")
15+
parser.add_argument ("-n", type=int, default=50,
16+
help="Number of experiment points [default: %(default)s]")
17+
parser.add_argument ("--x-range", nargs=2, type=float, default=[1.05, 2.95],
18+
help="X-axis data range [default: %(default)s]")
19+
20+
args = parser.parse_args()
21+
22+
23+
y = lambda x : args.a + args.b*x + random.gauss (0., args.epsilon)
24+
25+
def my_range (x_range, n) :
26+
h = (x_range[1] - x_range[0]) / n
27+
x = x_range[0]
28+
for i in range (n) :
29+
yield x
30+
x += h
31+
32+
33+
data = ["{0:.6} {1:.6}".format (x, y(x)) for x in my_range (args.x_range, args.n)]
34+
35+
with open (args.output, "w") as f :
36+
f.write ("\n".join (data))

01/src/least_squares.cpp

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Read data of an experiment from file given as command
2+
// line argument and having the following format:
3+
// x1 y1
4+
// ...
5+
// xN yN
6+
// Compute linear regression [y = a + b*x] coefficients
7+
// using the least squares method.
8+
9+
#include <iostream>
10+
#include <fstream>
11+
#include <iterator>
12+
#include <vector>
13+
#include <tuple>
14+
#include <string>
15+
#include <cmath>
16+
#include <stdexcept>
17+
18+
19+
struct Point
20+
{
21+
double x, y;
22+
23+
Point () = default;
24+
Point (double xx, double yy) : x{ xx }, y{ yy } {/* empty body */}
25+
};
26+
27+
std::istream& operator >> (std::istream& is, Point& rhs)
28+
{
29+
return is >> rhs.x >> rhs.y;
30+
}
31+
32+
std::ostream& operator << (std::ostream& os, const Point& rhs)
33+
{
34+
return os << rhs.x <<" "<< rhs.y;
35+
}
36+
37+
38+
auto read (const std::string& filename)
39+
{
40+
std::ifstream ifs{ filename };
41+
if (!ifs)
42+
throw std::runtime_error{"can't open file '"+ filename +"'"};
43+
44+
return std::vector<Point>{ std::istream_iterator<Point>{ ifs }
45+
, std::istream_iterator<Point>{} };
46+
}
47+
48+
49+
struct Coeff
50+
{
51+
double value; // coefficient estimate
52+
double delta; // confidence band
53+
54+
Coeff (double v, double d) : value{ v }, delta{ d } {/* empty body */}
55+
};
56+
57+
58+
auto least_squares (const std::vector<Point>& points)
59+
{
60+
// compute average values
61+
size_t N = points.size();
62+
double x_ave = 0., x2_ave = 0.;
63+
double y_ave = 0., xy_ave = 0.;
64+
65+
for (const auto& p : points)
66+
{
67+
x_ave += p.x; x2_ave += p.x*p.x;
68+
y_ave += p.y; xy_ave += p.x*p.y;
69+
}
70+
x_ave /= N; x2_ave /= N;
71+
y_ave /= N; xy_ave /= N;
72+
73+
74+
// compute linear coefficient estimate
75+
double b = (xy_ave - x_ave*y_ave) / (x2_ave - x_ave*x_ave);
76+
77+
if (!std::isfinite(b))
78+
throw std::overflow_error{"division by zero"};
79+
80+
81+
// compute constant coefficient estimate
82+
double a = y_ave - b*x_ave;
83+
84+
85+
return std::make_tuple (Coeff{ a, 0. }, Coeff{ b, 0. });
86+
}
87+
88+
89+
int main (int argc, char *argv[])
90+
{
91+
if (argc != 2)
92+
{
93+
std::cerr <<"usage: "<< argv[0] <<" file_with_data"<< std::endl;
94+
return 2;
95+
}
96+
97+
try
98+
{
99+
std::string datafile{ argv[1] };
100+
101+
auto [a, b] = least_squares (read (datafile)); // C++17
102+
103+
std::cout << datafile <<" "
104+
<< a.value <<" "<< a.delta <<" "
105+
<< b.value <<" "<< b.delta << std::endl;
106+
}
107+
catch (std::exception& e)
108+
{
109+
std::cerr <<"error: "<< e.what() << std::endl;
110+
return 1;
111+
}
112+
}

01/src/line_approx.txt

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
1.05 1.16584
2+
1.088 1.11605
3+
1.126 1.2191
4+
1.164 1.4373
5+
1.202 1.21263
6+
1.24 1.35302
7+
1.278 1.44812
8+
1.316 1.36983
9+
1.354 1.33221
10+
1.392 1.47139
11+
1.43 1.649
12+
1.468 1.56803
13+
1.506 1.45574
14+
1.544 1.74951
15+
1.582 1.77343
16+
1.62 1.73866
17+
1.658 1.76827
18+
1.696 1.4907
19+
1.734 1.68424
20+
1.772 1.91371
21+
1.81 1.72872
22+
1.848 1.87495
23+
1.886 2.04228
24+
1.924 1.94713
25+
1.962 1.98993
26+
2.0 2.05464
27+
2.038 2.09528
28+
2.076 2.01542
29+
2.114 2.28125
30+
2.152 2.27558
31+
2.19 2.09072
32+
2.228 1.93575
33+
2.266 2.16868
34+
2.304 2.16922
35+
2.342 2.14464
36+
2.38 2.30142
37+
2.418 2.29239
38+
2.456 2.59694
39+
2.494 2.4786
40+
2.532 2.55541
41+
2.57 2.61125
42+
2.608 2.60551
43+
2.646 2.44908
44+
2.684 2.75193
45+
2.722 2.54662
46+
2.76 2.67688
47+
2.798 2.68425
48+
2.836 2.81591
49+
2.874 2.78243
50+
2.912 2.71886

0 commit comments

Comments
 (0)