Skip to content

Commit

Permalink
Start from materials of past years
Browse files Browse the repository at this point in the history
  • Loading branch information
vpodaruev committed Aug 22, 2023
1 parent 75d8f9a commit 2042881
Show file tree
Hide file tree
Showing 26 changed files with 2,328 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
*.aux
/*.fdb_latexmk
/*.log
/*.fls
/*.out
/*.run.xml
/*.toc
/*.bbl
/*.bcf
/*.blg
/*.synctex.gz
/*.pytxcode
_minted-*/
pythontex-files-*/


*.pdf
!images/*.pdf
135 changes: 135 additions & 0 deletions 01/hello_world.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
% !TEX encoding = UTF8
% !TEX spellcheck = ru_RU
% !TEX root = ../../seminars.tex

%%=====================
\chapter{Hello, World!}\label{chap:helloworld}
%%=====================

%%==================================================
\section{Архитектура Фон-Неймана, уровни абстракции}
%%==================================================
Схематическое устройство компьютера. Алгоритмы и языки программирования. Абстракция от реального <<железа>>.



%%=================
\section{Программы}
%%=================
\lang{С++}\footcite{Stroustrup:2019:ru} является компилируемым языком. Для работы программы её исходный текст должен быть обработан с помощью компилятора, который создаёт объектные файлы, объединяемые компоновщиком в выполнимую программу. Обычно программы на языке \lang{С++} состоят из многих файлов с исходными текстами (именуемыми просто \textit{исходными файлами}).

\begin{center}\begin{tikzpicture}[node font=\small, >=Stealth, line width=1pt]
\graph [grow right sep, left anchor=east, right anchor=west, nodes=draw] {
"файл1.cpp" -> c1/{компиляция} [ellipse] -> "файл1.o" ->[right anchor=north west] "компоновка" [ellipse, yshift=-2.5ex] -> "выполнимый файл"[yshift=-2.5ex];
"файл2.cpp" -> c2/{компиляция} [ellipse] -> "файл2.o" ->[right anchor=south west] "компоновка";
};
\end{tikzpicture}\end{center}

Выполнимая программа создаётся для определённой комбинации аппаратного обеспечения и операционной системы; её нельзя просто перенести, скажем, из компьютера \name{Мac} в компьютер с \name{Windows}. Говоря о переносимости программ \lang{С++}, мы обычно имеем в виду переносимость исходного кода, т.\,е. исходный код может быть успешно скомпилирован и выполняться в разных
системах.

Стандарт \name{ISO} \lang{С++} определяет два типа сущностей.
\begin{itemize}
\item \textit{Фундаментальные возможности языка}, такие как встроенные типы (например, \code{char} и \code{int}) или циклы (например, инструкции \code{for} и \code{while}).

\item \textit{Компоненты стандартных библиотек}, такие как контейнеры (например, \code{vector}, и \code{map}) или операции ввода--вывода (например, \code{<<} и \code{getline()}).
\end{itemize}

Компоненты стандартной библиотеки представляют собой совершенно обычный код \code{С++}, предоставляемый каждой реализацией языка. То есть стандартная библиотека \code{С++} может быть реализована в самом \code{С++} (и реализуется "--- с очень небольшим использованием машинного кода для таких вещей, как переключение контекста потока). Это означает, что \code{С++} достаточно выразителен и эффективен для самых сложных задач системного программирования.

\code{С++} является статически типизированным языком, т.е. тип каждой сущности (например, объекта, значения, имени или выражения) должен быть известен компилятору в точке использования. Тип объекта определяет набор применимых к нему операций.



%%==================================
\section{Метод наименьших квадратов}
%%==================================

%%===============================
\subparagraph{Постановка задачи.}
%%===============================
Рассмотрим регрессию (зависимость) следующего вида:
\begingroup
\newcommand{\SumN}{\ensuremath{\sum\limits_{i=1}^{N}}}
\[
y_i = a + b x_i + \varepsilon_i,\quad i = \overline{1, N}.
\]
Среди всевозможных значений \(\{ a, b \}\) будем искать такие, которые приводят к минимальной сумме квадратов отклонений (ошибок):
\[
S_{\varepsilon} = \SumN \varepsilon_i^2 = \SumN (y_i - a - b x_i)^2\quad\rightarrow\quad \min\limits_{a, b}.
\]
Запишем условие существования экстремума:
\[
\begin{array}{l}
\dfrac{\partial}{\partial a} S_{\varepsilon} = -2 \SumN (y_i - a - b x_i) = 0, \\[2ex]
\dfrac{\partial}{\partial b} S_{\varepsilon} = -2 \SumN (y_i - a - b x_i) x_i = 0, \\
\end{array}
\]
откуда получим систему линейных уравнений:
\[
\left\{ \begin{array}{l}
\SumN y_i - N a - b\SumN x_i = 0, \\[2ex]
\SumN x_i y_i - a\SumN x_i - b\SumN x_i^2 = 0. \\
\end{array} \right.
\]
Вводя обозначение для среднего арифметического множества значений некоторой величины \(f\):
\[
\bar f = \dfrac{1}{N}\SumN f_i,
\]
перепишем систему в виде:
\[
\left\{ \begin{array}{l}
\bar y - a - b\bar x = 0, \\
\overline{x y} - a\bar x - b\overline{x^2} = 0, \\
\end{array} \right.
\]
и получим искомое решение:
\[
\boxed{\begin{array}{l}
a = \bar y - b\bar x, \\
b = \dfrac{\overline{x y} - \bar x\bar y}{\overline{x^2} - \bar x^2}. \\
\end{array}}
\]
\endgroup



%%====================================
\subparagraph{Программная реализация.}
%%====================================
Решение этой задачи может быть выражено на языке \lang{C++} следующим образом:\label{code:lsm}

\cppfile{01/src/least_squares.cpp}



%%================
\WhatToReadSection
%%================
\textcite{Stroustrup:2016:ru}: \textbf{главы~0, 1 и~2}



%%===============
\ExercisesSection
%%===============
\begin{exercise}
\item Настройте среду разработки программ на языке \lang{C++} (см. страницу \pageref{sect:workEnv}).


\item Создайте свой первый проект с традиционной программой \textenglish{Hello, World!}.

\smallskip
\emph{Совет}: воспользуйтесь графическими инструкциями из архива
\begin{flushleft}
\yadisk{cpp-seminars/how-to-s/how-to\_create-project.zip}.
\end{flushleft}

Заголовочный файл \code{std\_lib\_facilities.h} из книги Страуструпа размещён в директории \yadisk{cpp-seminars/libraries}.


\item \textbf{NB!} Внимательно изучите и возьмите на вооружение <<горячие клавиши>> среды разработки. Начните осваивать печать вслепую.

\smallskip
\emph{Совет}: воспользуйтесь информацией из раздела на странице~\pageref{sect:typing}.
\end{exercise}
Empty file added 01/src/empty.txt
Empty file.
36 changes: 36 additions & 0 deletions 01/src/gen.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/python3

import argparse, random

parser = argparse.ArgumentParser (description = "Generate test data for the least "
"squares method: yi = a + b*xi + epsi")
parser.add_argument ("a", type=float,
help="Constant coefficient in regression model")
parser.add_argument ("b", type=float,
help="Linear coefficient in regression model")
parser.add_argument ("-o", "--output", type=str, default="data.out",
help="Output filename [default: %(default)s]")
parser.add_argument ("-e","--epsilon", type=float, default=0.1,
help="Standard deviation of experiment error [default: %(default)s]")
parser.add_argument ("-n", type=int, default=50,
help="Number of experiment points [default: %(default)s]")
parser.add_argument ("--x-range", nargs=2, type=float, default=[1.05, 2.95],
help="X-axis data range [default: %(default)s]")

args = parser.parse_args()


y = lambda x : args.a + args.b*x + random.gauss (0., args.epsilon)

def my_range (x_range, n) :
h = (x_range[1] - x_range[0]) / n
x = x_range[0]
for i in range (n) :
yield x
x += h


data = ["{0:.6} {1:.6}".format (x, y(x)) for x in my_range (args.x_range, args.n)]

with open (args.output, "w") as f :
f.write ("\n".join (data))
112 changes: 112 additions & 0 deletions 01/src/least_squares.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Read data of an experiment from file given as command
// line argument and having the following format:
// x1 y1
// ...
// xN yN
// Compute linear regression [y = a + b*x] coefficients
// using the least squares method.

#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
#include <tuple>
#include <string>
#include <cmath>
#include <stdexcept>


struct Point
{
double x, y;

Point () = default;
Point (double xx, double yy) : x{ xx }, y{ yy } {/* empty body */}
};

std::istream& operator >> (std::istream& is, Point& rhs)
{
return is >> rhs.x >> rhs.y;
}

std::ostream& operator << (std::ostream& os, const Point& rhs)
{
return os << rhs.x <<" "<< rhs.y;
}


auto read (const std::string& filename)
{
std::ifstream ifs{ filename };
if (!ifs)
throw std::runtime_error{"can't open file '"+ filename +"'"};

return std::vector<Point>{ std::istream_iterator<Point>{ ifs }
, std::istream_iterator<Point>{} };
}


struct Coeff
{
double value; // coefficient estimate
double delta; // confidence band

Coeff (double v, double d) : value{ v }, delta{ d } {/* empty body */}
};


auto least_squares (const std::vector<Point>& points)
{
// compute average values
size_t N = points.size();
double x_ave = 0., x2_ave = 0.;
double y_ave = 0., xy_ave = 0.;

for (const auto& p : points)
{
x_ave += p.x; x2_ave += p.x*p.x;
y_ave += p.y; xy_ave += p.x*p.y;
}
x_ave /= N; x2_ave /= N;
y_ave /= N; xy_ave /= N;


// compute linear coefficient estimate
double b = (xy_ave - x_ave*y_ave) / (x2_ave - x_ave*x_ave);

if (!std::isfinite(b))
throw std::overflow_error{"division by zero"};


// compute constant coefficient estimate
double a = y_ave - b*x_ave;


return std::make_tuple (Coeff{ a, 0. }, Coeff{ b, 0. });
}


int main (int argc, char *argv[])
{
if (argc != 2)
{
std::cerr <<"usage: "<< argv[0] <<" file_with_data"<< std::endl;
return 2;
}

try
{
std::string datafile{ argv[1] };

auto [a, b] = least_squares (read (datafile)); // C++17

std::cout << datafile <<" "
<< a.value <<" "<< a.delta <<" "
<< b.value <<" "<< b.delta << std::endl;
}
catch (std::exception& e)
{
std::cerr <<"error: "<< e.what() << std::endl;
return 1;
}
}
50 changes: 50 additions & 0 deletions 01/src/line_approx.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
1.05 1.16584
1.088 1.11605
1.126 1.2191
1.164 1.4373
1.202 1.21263
1.24 1.35302
1.278 1.44812
1.316 1.36983
1.354 1.33221
1.392 1.47139
1.43 1.649
1.468 1.56803
1.506 1.45574
1.544 1.74951
1.582 1.77343
1.62 1.73866
1.658 1.76827
1.696 1.4907
1.734 1.68424
1.772 1.91371
1.81 1.72872
1.848 1.87495
1.886 2.04228
1.924 1.94713
1.962 1.98993
2.0 2.05464
2.038 2.09528
2.076 2.01542
2.114 2.28125
2.152 2.27558
2.19 2.09072
2.228 1.93575
2.266 2.16868
2.304 2.16922
2.342 2.14464
2.38 2.30142
2.418 2.29239
2.456 2.59694
2.494 2.4786
2.532 2.55541
2.57 2.61125
2.608 2.60551
2.646 2.44908
2.684 2.75193
2.722 2.54662
2.76 2.67688
2.798 2.68425
2.836 2.81591
2.874 2.78243
2.912 2.71886
Loading

0 comments on commit 2042881

Please sign in to comment.