blob: 79942d8f1908d6e0d3d8de06979ab879a5b37d89 [file] [log] [blame]
 // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "common/vector.h" #include #include #include "common/alog.h" #include "common/matrix.h" namespace arc { float Vector::GetDotProduct(const Vector& v) const { float dp = 0; for (size_t i = 0; i < kEntries; ++i) dp += entries_[i] * v.entries_[i]; return dp; } void Vector::AssignMatrixMultiply(const Matrix& a, const Vector& b) { const Vector r0(a.Get(0, 0), a.Get(0, 1), a.Get(0, 2), a.Get(0, 3)); const Vector r1(a.Get(1, 0), a.Get(1, 1), a.Get(1, 2), a.Get(1, 3)); const Vector r2(a.Get(2, 0), a.Get(2, 1), a.Get(2, 2), a.Get(2, 3)); const Vector r3(a.Get(3, 0), a.Get(3, 1), a.Get(3, 2), a.Get(3, 3)); const float x = r0.GetDotProduct(b); const float y = r1.GetDotProduct(b); const float z = r2.GetDotProduct(b); const float w = r3.GetDotProduct(b); entries_[0] = x; entries_[1] = y; entries_[2] = z; entries_[3] = w; } void Vector::AssignLinearMapping(const float* params, size_t count) { LOG_ALWAYS_FATAL_IF(count > kEntries); for (size_t i = 0; i < count; i++) entries_[i] = params[i]; } void Vector::AssignLinearMapping(const int32_t* params, size_t count) { LOG_ALWAYS_FATAL_IF(count > kEntries); AssignLinearMappingHelper(params, count); } void Vector::AssignLinearMapping(const int16_t* params, size_t count) { LOG_ALWAYS_FATAL_IF(count > kEntries); AssignLinearMappingHelper(params, count); } void Vector::AssignLinearMapping(const int8_t* params, size_t count) { LOG_ALWAYS_FATAL_IF(count > kEntries); AssignLinearMappingHelper(params, count); } void Vector::AssignLinearMapping(const uint16_t* params, size_t count) { LOG_ALWAYS_FATAL_IF(count > kEntries); AssignLinearMappingHelper(params, count); } void Vector::AssignLinearMapping(const uint8_t* params, size_t count) { LOG_ALWAYS_FATAL_IF(count > kEntries); AssignLinearMappingHelper(params, count); } void Vector::GetLinearMapping(float* params, size_t count) const { LOG_ALWAYS_FATAL_IF(count > kEntries); for (size_t i = 0; i < count; i++) params[i] = entries_[i]; } void Vector::GetLinearMapping(int32_t* params, size_t count) const { LOG_ALWAYS_FATAL_IF(count > kEntries); GetLinearMappingHelper(params, count); } void Vector::Clamp(float minv, float maxv) { for (size_t i = 0; i < kEntries; i++) entries_[i] = std::min(std::max(entries_[i], minv), maxv); } template void Vector::AssignLinearMappingHelper(const T* params, size_t count) { // Maps integer values to floating point. // If the integer type is signed, the output floating point values will be // in the range [-1.0, +1.0]. Otherwise the output floating point values // will be in the range [0.0, +1.0]. // An alias is convenient. typedef std::numeric_limits Limits; // We only expect integers here. LOG_ALWAYS_FATAL_IF(!Limits::is_integer); // Note: We use double precision here the limits of a 32 bit integer cannot be // accurately represented in a single precision floating point number. // Get the range of the integer const double mini = static_cast(Limits::min()); const double maxi = static_cast(Limits::max()); // Get the range of the floating point output. const double minf = Limits::is_signed ? -1.f : 0.f; const double maxf = +1.f; for (size_t i = 0; i < count; i++) { double v = static_cast(params[i]); entries_[i] = (v - mini) * (maxf - minf) / (maxi - mini) + minf; } } template void Vector::GetLinearMappingHelper(T* params, size_t count) const { // Maps floating point values to integers. // If the integer type is signed, then the floating point values will be // assumed to lie in the range [-1.0, +1.0], otherwise they will be assumed // to lie in the range [0.0, +1.0]. Numbers outside of this range will be // clamped to the boundary. The integers will be mapped such that the minimum // floating point value becomes the minimum integer value, and likewise with // the maximum value. // An alias is convenient. typedef std::numeric_limits Limits; // We only expect integers here. LOG_ALWAYS_FATAL_IF(!Limits::is_integer); // Note: We use double precision here the limits of a 32 bit integer cannot be // accurately represented in a single precision floating point number. // Get the range of the integer const double mini = static_cast(Limits::min()); const double maxi = static_cast(Limits::max()); // Get the range of the floating point output. const double minf = Limits::is_signed ? -1. : 0.; const double maxf = +1.; for (size_t i = 0; i < count; i++) { double v = entries_[i]; v = (v - minf) * (maxi - mini) / (maxf - minf) + mini; v = std::min(std::max(v, mini), maxi); params[i] = static_cast(v); } } } // namespace arc