Чтение онлайн

на главную - закладки

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

На первом этапе мы получаем окно, в котором нарисованы оси и “настоящая” экспонента (синий цвет).

Как видим, значение

exp(0)
равно
1
, поэтому наш синий график “настоящей” экспоненты пересекает ось y в точке
(0,1)
. Если присмотреться повнимательнее, то видно, что на самом деле мы нарисовали первое приближение
(exp0(x)==0)
черным цветом поверх оси x. Кнопка Next позволяет получить аппроксимацию, содержащую один член степенного ряда. Обратите внимание на
то, что мы показываем количество сленгов ряда, использованного для приближения экспоненты, как часть метки окна.

Это функция

exp1(x)==1
, представляющая собой аппроксимацию экспоненты с помощью только одного члена степенного ряда. Она точно совпадает с экспонентой в точке
(0,1)
, но мы можем построить более точную аппроксимацию.

Используя два члена разложения

(1+x)
, получаем диагональ, пересекающую ось y в точке
(0,1)
. С помощью трех членов разложения
(1+x+pow(x,2)/fac(2))
можем обнаружить признаки сходимости.

Десять членов приближения дают очень хорошее приближение, особенно для значений

x
, превышающих
–3
.

На первый взгляд, мы могли бы получать все более точные аппроксимации, постоянно увеличивая количество членов степенного ряда. Однако существует предел, и после тринадцати членов происходит нечто странное: аппроксимация ухудшается, а после вычисления восемнадцати членов на рисунке появляются вертикальные линии.

Помните, что арифметика чисел с плавающей точкой — это не чистая математика. Числа с плавающей точкой просто хорошо приближают действительные числа, поскольку для их представления можно использовать лишь ограниченное количество бит. С определенного момента наши вычисления стали порождать числа, которые невозможно точно представить в виде переменных типа
double
, и наши результаты стали отклоняться от правильного ответа. Более подробная информация на эту тему приведена в главе 24.

Последний рисунок представляет собой хорошую иллюстрацию следующего принципа: если ответ выглядит хорошо, еще не значит, что программа работает правильно. Если программа проработает немного дольше или на несколько других данных, то может возникнуть настоящая путаница, как это произошло в данном примере.

15.6. Графические данные

Изображение данных требует большой подготовки и опыта. Хорошо представленные данные сочетают технические и художественные факторы и могут существенно облегчить анализ сложных явлений. В то же время эти обстоятельства делают графическое представление данных необъятной областью приложений, в которой применяется множество никак не связанных друг с другом приемов программирования. Здесь мы ограничимся простым примером изображения данных, считанных из файла. Эти данные характеризуют состав возрастных групп населения Японии на протяжении почти столетия. Данные справа от вертикальной линии 2008 являются результатом экстраполяции.

С

помощью этого примера мы обсудим следующие проблемы программирования, связанные с представлением данных:

• чтение файла;

• масштабирование данных для подгонки к окну;

• отображение данных;

• разметка графика.

Мы не будем вдаваться в художественные аспекты этой проблемы. В принципе мы строим “график для идиотов”, а не для художественной галереи. Очевидно, что вы сможете построить его намного более красиво, чем это нужно.

Имея набор данных, мы должны подумать о том, как их получше изобразить на экране. Для простоты ограничимся только данными, которые легко изобразить на плоскости, ведь именно такие данные образуют огромный массив приложений, с которыми работают большинство людей. Обратите внимание на то, что гистограммы, секторные диаграммы и другие популярные виды диаграмм на самом деле просто причудливо отображают двумерные данные. Трехмерные данные часто возникают при обработке серии двумерных изображений, при наложении нескольких двумерных графиков в одном окне (как в примере “Возраст населения Японии”) или при разметке отдельных точек. Если бы мы хотели реализовать такие приложения, то должны были бы написать новые графические классы или адаптировать другую графическую библиотеку.

Итак, наши данные представляют собой пары точек, такие как (

year,number of children
). Если у нас есть больше данных, например (
year,number of children,number of adults,number of elderly
), то мы должны просто решить, какую пару или пары чисел хотим изобразить. В нашем примере мы рисуем пары (
year,number of children
), (
year,number of adults
) и (
year,number of elderly
).

Существует много способов интерпретации пар (
x,y
). Решая, как изобразить эти данные, важно понять, можно ли их представить в виде функции. Например, для пары (
year,steel production
) разумно предположить, что производство стали (
steel_production
) является функцией, зависящей от года (
year
), и изобразить данные в виде непрерывной линии. Для изображения таких данных хорошо подходит класс
Open_polyline
(см. раздел 13.6). Если переменная
y
не является функцией, зависящей от переменной
x
, например в паре (
gross domestic product per person,population of country
), то для их изображения в виде разрозненных точек можно использовать класс
Marks
(см. раздел 13.15).

Вернемся теперь к нашему примеру, посвященному распределению населения Японии по возрастным группам.

15.6.1. Чтение файла

Файл с возрастным распределением состоит из следующих записей:

(1960 : 30 64 6)

(1970 : 24 69 7)

(1980 : 23 68 9)

Первое число после двоеточия — это процент детей (возраст 0–15) среди населения, второе — процент взрослых (возраст 15–64), а третье — процент пожилых людей (возраст 65+). Наша задача — прочитать эти данные из файла. Обратите внимание на то, что форматирование этих данных носит довольно нерегулярный характер. Как обычно, мы должны уделить внимание таким деталям.

Для того чтобы упростить задачу, сначала определим тип

Distribution
, в котором будем хранить данные и оператор ввода этих данных.

struct Distribution {

int year, young, middle, old;

};

istream& operator>>(istream& is, Distribution& d)

// предполагаемый формат: (год: дети взрослые старики)

{

char ch1 = 0;

Поделиться:
Популярные книги

Волк: лихие 90-е

Киров Никита
1. Волков
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Волк: лихие 90-е

Пустоцвет

Зика Натаэль
Любовные романы:
современные любовные романы
7.73
рейтинг книги
Пустоцвет

Опер. Девочка на спор

Бигси Анна
5. Опасная работа
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Опер. Девочка на спор

Деспот

Шагаева Наталья
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Деспот

Измена. Ребёнок от бывшего мужа

Стар Дана
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Ребёнок от бывшего мужа

Релокант

Ascold Flow
1. Релокант в другой мир
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Релокант

Не грози Дубровскому! Том III

Панарин Антон
3. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому! Том III

Внешняя Зона

Жгулёв Пётр Николаевич
8. Real-Rpg
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Внешняя Зона

Черный Маг Императора 7 (CИ)

Герда Александр
7. Черный маг императора
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Черный Маг Императора 7 (CИ)

Адмирал южных морей

Каменистый Артем
4. Девятый
Фантастика:
фэнтези
8.96
рейтинг книги
Адмирал южных морей

Бальмануг. (не) Баронесса

Лашина Полина
1. Мир Десяти
Фантастика:
юмористическое фэнтези
попаданцы
5.00
рейтинг книги
Бальмануг. (не) Баронесса

Идеальный мир для Лекаря 8

Сапфир Олег
8. Лекарь
Фантастика:
юмористическое фэнтези
аниме
7.00
рейтинг книги
Идеальный мир для Лекаря 8

Возвышение Меркурия. Книга 7

Кронос Александр
7. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 7

Девяностые приближаются

Иванов Дмитрий
3. Девяностые
Фантастика:
попаданцы
альтернативная история
7.33
рейтинг книги
Девяностые приближаются