Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 [ 171 ] 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239

1nt rna1n() {

Создание и инициализация массивов значений с девятью элементами valarray<double> va(9); for (1nt 1=0: 1<va.slze(): { va[i] = 1 * 1.1:

Вывод массива значений printValarray(va):

Удвоение элементов массива va 2.0;

Повторный вывод массива значений prlntValarrayCva):

Создание второго массива значений, инициализированного элементами первого массива, увеличенными на 10 valarray<double> vb(va+10.0);

Вывод второго массива значений prlntValarray(vb);

Создание третьего массива значений и его инициализация

результатом выполнения операций с обоими существующими массивами

valarray<double> vc;

vc = sqrt(va) + vb/2.0 - 1.0;

Вывод третьего массива значений printValarray(vc);

Результат выполнения программы выглядит так:

О 1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.В

О 2.2 4.4 6.6 8.8 11 13.2 15.4 17.6

10 12.2 14.4 16.6 18.8 21 23.2 25.4 27.6

4 6,5В324 8.29762 9.86905 11.2665 12.8166 14.2332 15,6243 16.9952

Подмножества элементов в массивах значений

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

Чтобы определить подмножество массива значений, достаточно указать вместо индекса соответствующее определение, например:

va[std::slice(2.4,3)] Четыре элемента на расстоянии 3.

начиная с индекса 2 va[va>7] Все злененты со значением, большим 7



Если определение подмножества (такое, как std::slice(2,4,3) или va>7) используется с константным массивом значений, то выражение возвращает новый массив значений с соответствующими элементами. Но если определение подмножества используется с неконстантным массивом значений, то выражение возвращает временный объект специального вспомогательного класса. Временный объект содержит не данные подмножества, а только его определение. Обработка выражений откладывается до того момента, когда для получения окончательного результата потребуются данные.

Подобный механизм называется отложенным вычислением.. Отказ от вычисления временных данных экономит время и память. Кроме того, отложенные вычисления обеспечивают ссылочную семантику, то есть подмножество пред-став.яяет собой логический набор ссылок на исходные данные. Это позволяет использовать его в качестве приемника команды (1-значения). Например, подмножеству массива значений можно присвоить результат умножения двух других подмножеств того же массива (примеры приводятся далее).

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

Хорошо продуманное определение подмножеств позволяет наделить массивы значений семантикой двух и более измерений. Это означает, что массивы значений могут использоваться в качестве многомерных массивов.

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

О срезы;

О обобщенные срезы;

О отбор по логическому признаку;

О перечисляемые подмножества.

Ниже мы рассмотрим все четыре способа с конкретными примерами.

Проблемы с подмножествами элементов массивов значений

Прежде чем переходить к рассмотрению вариантов определения подмножеств, следует упомянуть одну общую проблему. Работа с подмножествами элементов в массивах значений организована недостаточно хорошо. Вы легко можете создавать подмножества, но при их использовании вместе с другими подмножествами возникают трудности. К сожалению, практически всегда приходится выполнять явное преобразование типа к valarray. Дело в том, что в стандартной библиотеке С++ не указано, что подмножества поддерживают те же операции, что и массивы значений.

Предположим, нужно вычислить произведение двух подмножеств и присвоить результат третьему подмножеству. Следующее решение не подходит:

ОШИБКА: отсутствуют преобразования типов va[std;:slice(0,4.3)]

= va[std::slice(1.4,3)] * va[std::sl1ce(2,4.3)]:



Вместо этого приходится использовать новые операторы преобразования типа (см, с. 35):

va[std::slice(0.4,3)]

= stat1c cast<std::valarray<double> >(va[std::slice(1.4.3)]} * static cast<std::valarray<double> >(va[std::sl1ce(2.4.3)]);

Подойдет также старый механизм преобразования типа:

va[std::slice(0.4.3)]

- std;:valarray<double>(va[std::sl1ce(l.4.3)]) * std;:valarray<double>(va[std::sl1ce(2.4.3)]):

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

Следующая шаблонная функция несколько упрощает работу с подмножествами:

/* шаблон для преобразования подмножества элементов массива значений в массив значений

template <class Т> inline

std; :valarray<typenafTie Т: :value type> VA(const T& valarray subset) {

return std:;valarray<typena[ne T::value type>(valarray subset):

При использовании этого шаблона предыдущий пример выглядит так:

va[std:;sl1ce(0.4.3)] = VA(va[std;:slice(1.4.3)]) *

VACva[std;:slice(2.4.3)]); OK

Однако проб.яема снижения быстродействия остается.

При работе с элементами заданного типа также можно воспользоваться простым определением типа:

typedef valarray<double> VAD:

В этом случае запись выглядит так (при условии, что элементы va относятся к типу double):

va[std:;slice(0.4.3)] = VAD(va[std::slice(1.4.3)]) *

VAD(va[std;;slice(2.4.3)]); OK

Срезы

Срез определяется набором индексов, который характеризуется тремя свойствами:

О начальным индексом;

О количеством элементов (размером);

О расстоянием между элементами (шагом).



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 [ 171 ] 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239