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

x.apply(f);     // x[i] = f(x[i]) для каждого i

В результате a==b и x==y.

  В языке Fortran второй вариант функции apply называется функцией пересылки (“broadcast” function). В этом языке чаще пишут вызов f(x), а не apply(f,x). Для того чтобы эта возможность стала доступной для каждой функции f (а не только для отдельных функций, как в языке Fortran), мы должны присвоить операции пересылки конкретное имя, поэтому (повторно) использовали имя apply.

Кроме того, для того чтобы обеспечить соответствие с вариантом функции-члена apply, имеющим вид a.apply(f,x), мы пишем

b = apply(f,a,x); // b[i]=f(a[i],x) для каждого i

Рассмотрим пример.

double scale(double d, double s) { return d*s; }

b = apply(scale,a,7); // b[i] = a[i]*7 для каждого i

Обратите внимание на то, что “автономная” функция apply() принимает в качестве аргумента функцию, вычисляющую результат по ее аргументам, а затем использует этот результат для инициализации итогового объекта класса Matrix. Как правило, это не приводит к изменению объекта класса Matrix, к которому эта функция применяется. В то же время функция-член apply() отличается тем, что принимает в качестве аргумента функцию, модифицирующую ее аргументы; иначе говоря, она модифицирует элементы объекта класса Matrix, к которому применяется. Рассмотрим пример.

void scale_in_place(double& d, double s) { d *= s; }

b.apply(scale_in_place,7); // b[i] *= 7 для каждого i

В классе Matrix предусмотрено также много полезных функций из традиционных математических библиотек.

Matrix a3 = scale_and_add(a,8,a2); // объединенное умножение

                                        // и сложение

int r = dot_product(a3,a);              // скалярное произведение

  Операцию scale_and_add() часто называют объединенным умножением и сложением (fused multiply-add), или просто fma; ее определение выглядит так: result(i)=arg1(i)*arg2+arg3(i) для каждого i в объекте класса Matrix. Скалярное произведение также известно под именем inner_product и описано в разделе 21.5.3; ее определение выглядит так: result+=arg1(i)*arg2(i) для каждого i в объекте класса Matrix, где накопление объекта result начинается с нуля.

Одномерные массивы очень широко распространены; их можно представить как в виде встроенного массива, так и с помощью классов vector и Matrix. Класс Matrix следует применять тогда, когда необходимо выполнять матричные операции, такие как *=, или когда объект класса Matrix должен взаимодействовать с другими объектами этого класса, имеющими более высокую размерность.

  Полезность этой библиотеки можно объяснить тем, что она лучше согласована с математическими операциями, а также тем, что при ее использовании не приходится писать циклы для работы с каждым элементом матрицы. В любом случае в итоге мы получаем более короткий код и меньше возможностей сделать ошибку. Операции класса Matrix, например копирование, присваивание всем элементам и операции над всеми элементами, позволяют не использовать циклы (а значит, можно не беспокоиться о связанных с ними проблемах).

Класс Matrix имеет два конструктора для копирования данных из встроенных массивов в объект класса Matrix. Рассмотрим пример.

void some_function(double* p, int n)

{

  double val[] = { 1.2, 2.3, 3.4, 4.5 };

  Matrix data(p,n);

  Matrix constants(val);

  // ...

}

Это часто бывает полезным, когда мы получаем данные в виде обычных массивов или векторов, созданных в других частях программы, не использующих объекты класса Matrix.

Обратите внимание на то, что компилятор может самостоятельно определить количество элементов в инициализированном массиве, поэтому это число при определении объекта constants указывать не обязательно — оно равно — 4. С другой стороны, если элементы заданы всего лишь указателем, то компилятор не знает их количества, поэтому при определении объекта data мы должны задать как указатель p, так и количество элементов n.

<p id="AutBody_Root469"><strong>24.5.3. Двумерный объект класса Matrix</strong></p>

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

Перейти на страницу:

Похожие книги

Programming with POSIX® Threads
Programming with POSIX® Threads

With this practical book, you will attain a solid understanding of threads and will discover how to put this powerful mode of programming to work in real-world applications. The primary advantage of threaded programming is that it enables your applications to accomplish more than one task at the same time by using the number-crunching power of multiprocessor parallelism and by automatically exploiting I/O concurrency in your code, even on a single processor machine. The result: applications that are faster, more responsive to users, and often easier to maintain. Threaded programming is particularly well suited to network programming where it helps alleviate the bottleneck of slow network I/O. This book offers an in-depth description of the IEEE operating system interface standard, POSIX (Portable Operating System Interface) threads, commonly called Pthreads. Written for experienced C programmers, but assuming no previous knowledge of threads, the book explains basic concepts such as asynchronous programming, the lifecycle of a thread, and synchronization. You then move to more advanced topics such as attributes objects, thread-specific data, and realtime scheduling. An entire chapter is devoted to "real code," with a look at barriers, read/write locks, the work queue manager, and how to utilize existing libraries. In addition, the book tackles one of the thorniest problems faced by thread programmers-debugging-with valuable suggestions on how to avoid code errors and performance problems from the outset. Numerous annotated examples are used to illustrate real-world concepts. A Pthreads mini-reference and a look at future standardization are also included.

David Butenhof

Программирование, программы, базы данных