145 if (domain_size == 0) {
151 evaluator.
add(input_);
152 evaluator.
add(group_index_);
160 using T = decltype(dummy);
161 if constexpr (is_same_any_v<T, int, float, float3>) {
162 const VArraySpan<T> values = g_values.typed<T>();
164 if (operation_ == Operation::StdDev) {
165 if (group_indices.is_single()) {
166 const T mean = std::reduce(values.begin(), values.end(), T()) / domain_size;
167 const T sum_of_squared_diffs = std::reduce(
168 values.begin(), values.end(), T(), [mean](T accumulator, const T &value) {
169 T difference = mean - value;
170 return accumulator + difference * difference;
172 g_outputs = VArray<T>::from_single(math::sqrt(sum_of_squared_diffs / domain_size),
176 Map<int, std::pair<T, int>> sum_and_counts;
177 Map<int, T> deviations;
179 for (const int i : values.index_range()) {
180 auto &pair = sum_and_counts.lookup_or_add(group_indices[i], std::make_pair(T(), 0));
181 pair.first = pair.first + values[i];
182 pair.second = pair.second + 1;
185 for (const int i : values.index_range()) {
186 const auto &pair = sum_and_counts.lookup(group_indices[i]);
187 T mean = pair.first / pair.second;
188 T deviation = (mean - values[i]);
189 deviation = deviation * deviation;
191 T &dev_sum = deviations.lookup_or_add(group_indices[i], T());
192 dev_sum = dev_sum + deviation;
195 Array<T> outputs(domain_size);
196 for (const int i : values.index_range()) {
197 const auto &pair = sum_and_counts.lookup(group_indices[i]);
198 outputs[i] = math::sqrt(deviations.lookup(group_indices[i]) / pair.second);
200 g_outputs = VArray<T>::from_container(std::move(outputs));
204 if (group_indices.is_single()) {
205 const T mean = std::reduce(values.begin(), values.end(), T()) / domain_size;
206 const T sum_of_squared_diffs = std::reduce(
207 values.begin(), values.end(), T(), [mean](T accumulator, const T &value) {
208 T difference = mean - value;
209 return accumulator + difference * difference;
211 g_outputs = VArray<T>::from_single(sum_of_squared_diffs / domain_size, domain_size);
214 Map<int, std::pair<T, int>> sum_and_counts;
215 Map<int, T> deviations;
217 for (const int i : values.index_range()) {
218 auto &pair = sum_and_counts.lookup_or_add(group_indices[i], std::make_pair(T(), 0));
219 pair.first = pair.first + values[i];
220 pair.second = pair.second + 1;
223 for (const int i : values.index_range()) {
224 const auto &pair = sum_and_counts.lookup(group_indices[i]);
225 T mean = pair.first / pair.second;
226 T deviation = (mean - values[i]);
227 deviation = deviation * deviation;
229 T &dev_sum = deviations.lookup_or_add(group_indices[i], T());
230 dev_sum = dev_sum + deviation;
233 Array<T> outputs(domain_size);
234 for (const int i : values.index_range()) {
235 const auto &pair = sum_and_counts.lookup(group_indices[i]);
236 outputs[i] = deviations.lookup(group_indices[i]) / pair.second;
238 g_outputs = VArray<T>::from_container(std::move(outputs));
244 return attributes.adapt_domain(std::move(g_outputs), source_domain_, context.domain());