4. Выполните программу исключения методом Гаусса, т.е. завершите ее, скомпилируйте и протестируйте на простом примере.
5. Примените программу исключения методом Гаусса к системе
A=={{0 1}{1 0}}
и
b=={5 6}
и убедитесь, что программа завершится крахом. Затем попробуйте вызвать функцию
elim_with_partial_pivot()
.
6. Замените циклами векторные операции
dot_product()
и
scale_and_add()
в программе исключения методом Гаусса. Протестируйте и прокомментируйте эту программу.
7. Перепишите программу исключения методом Гаусса без помощи библиотеки
Matrix
. Иначе говоря, используйте встроенные массивы или класс vector, а не класс
Matrix
.
8. Проиллюстрируйте метод исключения методом Гаусса.
9. Перепишите функцию
apply()
, не являющуюся членом класса
Matrix
, так, чтобы она возвращала объект класса
Matrix
, содержащий объекты, имеющие тип примененной функции. Иначе говоря, функция
apply(f,a)
должна возвращать объект класса
Matrix<R>
, где
R
— тип значения, возвращаемого функцией
f
. Предупреждение: это решение требует информации о шаблонах, которая не излагалась в этой книге.
10. Насколько случайной является функция
rand()
? Напишите программу, принимающую два целых числа
n
и
d
из потока ввода,
d
раз вызывающую функцию
randint(n)
и записывающую результат. Выведите на экран количество выпавших чисел из каждого диапазона
[0:n]
и оцените, насколько постоянным является их количество. Выполните программу с небольшими значениями
n
и небольшими значениями
d
, чтобы убедиться в том, что очевидные смещения возникают только при небольшом количестве испытаний.
11. Напишите функцию
swap_columns()
, аналогичную функции swap_rows() из раздела 24.5.3. Очевидно, что для этого необходимо изучить код библиотеки
Matrix
. Не беспокойтесь об эффективности своей программы: быстродействие функции
swap_columns()
в принципе не может превышать быстродействие функции
swap_rows()
.
12. Реализуйте операторы
Matrix<double> operator*(Matrix<double,2>&, Matrix<double>&);
и
Matrix<double,N> operator+(Matrix<double,N>&, Matrix<double,N>&).
При необходимости посмотрите их математические определения в учебниках.
Послесловие
Если вы не любите математику, то, возможно, вам не понравилась эта глава и вы выберете для себя область приложений, в которой изложенная выше информация не понадобится. С другой стороны, если вы любите математику, то мы надеемся, что вы оцените точность выражения математических понятий в представленном нами коде.
Глава 25
Программирование встроенных систем
“Слово “опасный ” означает, что кто-то может умереть”.
Сотрудник службы безопасности
В этой главе мы рассмотрим вопросы программирования встроенных систем; иначе говоря, обсудим темы, связанные в первую очередь с написанием программ для устройств, которые не являются традиционными компьютерами с экранами и клавиатурами. Основное внимание уделяется принципам и методам программирования таких устройств, языковым возможностям и стандартам кодирования, необходимым для непосредственной работы с аппаратным обеспечением. К этим темам относятся управление ресурсами и памятью, использование указателей и массивов, а также манипулирование битами. Главный акцент делается на безопасном использовании, а также на альтернативе использованию низкоуровневых средств. Мы не стремимся описывать специализированные архитектуры устройств или способы прямого доступа к памяти аппаратного обеспечения, для этого существует специализированная литература. В качестве иллюстрации мы выбрали реализацию алгоритма кодирования-декодирования.
25.1. Встроенные системы
Большая часть существующих компьютеров не выглядит как компьютеры. Они просто являются частью более крупной системы или устройства. Рассмотрим примеры.
• Автомобили. В современный автомобиль могут быть встроены десятки компьютеров, управляющих впрыскиванием топлива, следящих на работой двигателя, настраивающих радио, контролирующих тормоза, наблюдающих за давлением в шинах, управляющих дворниками на ветровом стекле и т.д.
• Телефоны. Мобильный телефон содержит как минимум два компьютера; один из них обычно специализируется на обработке сигналов.
• Самолеты. Современный самолет оснащен компьютерами, управляющими буквально всем: от системы развлечения пассажиров до закрылок, оптимизирующих подъемную силу крыла.
• Фотоаппараты. Существуют фотоаппараты с пятью процессорами, в которых каждый объектив имеет свой собственный процессор.
• Кредитные карточки (и все семейство карточек с микропроцессорами).
• Мониторы и контроллеры медицинского оборудования (например, сканеры для компьютерной томографии).
• Грузоподъемники (лифты).
• Карманные компьютеры.
• Кухонное оборудование (например, скороварки и хлебопечки).
• Телефонные коммутаторы (как правило, состоящие из тысяч специализированных компьютеров).
• Контроллеры насосов (например, водяных или нефтяных).
• Сварочные роботы, которые используются в труднодоступных или опасных местах, где человек работать не может.
• Ветряки. Некоторые из них способны вырабатывать мегаватты электроэнергии и имеют высоту до 70 метров.
• Контроллеры шлюзов на дамбах.
• Мониторы качества на конвейерах.
• Устройства считывания штриховых кодов.
• Автосборочные роботы.
• Контроллеры центрифуг (используемых во многих процессах медицинского анализа).
• Контроллеры дисководов.
Эти компьютеры являются частью более крупных систем, которые обычно не похожи на компьютеры и о которых мы никогда не думаем как о компьютерах. Когда мы видим автомобиль, проезжающий по улице, мы не говорим: “Смотрите, поехала распределенная компьютерная система!” И хотя автомобиль в том числе является и распределенной компьютерной системой, ее действия настолько тесно связаны с работой механической, электронной и электрической систем, что мы не можем считать ее изолированным компьютером. Ограничения, наложенные на работу этой системы (временные и пространственные), и понятие корректности ее программ не могут быть отделены от содержащей ее более крупной системы. Часто встроенный компьютер управляет физическим устройством, и корректное поведение компьютера определяется как корректное поведение самого физического устройства. Рассмотрим крупный дизельный судовой двигатель.