diff --git a/include/ui/scalar.h b/include/ui/scalar.h
new file mode 100644
index 0000000..c938d5c
--- /dev/null
+++ b/include/ui/scalar.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef UI_SCALAR_H
+#define UI_SCALAR_H
+
+#include <algorithm>
+#include <cmath>
+
+namespace android {
+
+template<typename T>
+static constexpr T saturate(T v) noexcept {
+    return T(std::min(T(1), std::max(T(0), v)));
+}
+
+template<typename T>
+static constexpr T clamp(T v, T min, T max) noexcept {
+    return T(std::min(max, std::max(min, v)));
+}
+
+template<typename T>
+static constexpr T mix(T x, T y, T a) noexcept {
+    return x * (T(1) - a) + y * a;
+}
+
+template<typename T>
+static constexpr T lerp(T x, T y, T a) noexcept {
+    return mix(x, y, a);
+}
+
+namespace details {
+    static int asInt(float x) {
+        return *reinterpret_cast<int*>(&x);
+    }
+
+    static float asFloat(int x) {
+        return *reinterpret_cast<float*>(&x);
+    }
+
+    static constexpr float inversesqrtNewtonRaphson(float x, float inverseSqrtX) {
+        return inverseSqrtX * (-x * 0.5f * (inverseSqrtX * inverseSqrtX) + 1.5f);
+    }
+
+    static constexpr float rcpNewtonRaphson(float x, float rcpX) {
+        return rcpX * (-rcpX * x + 2.0f);
+    }
+
+    static const float inverseSqrtFast(float f, int c) {
+        int v = details::asInt(f);
+        v = c - (v >> 1);
+        return details::asFloat(v);
+    }
+
+    static const float rcpFast(float f, int c) {
+        int v = details::asInt(f);
+        v = c - v;
+        return details::asFloat(v);
+    }
+} // namespace details
+
+/**
+ * Approximates an inverse square root using a specified
+ * number of Newton-Raphson iterations. The number of iterations
+ * can be:
+ *
+ * - 0, with a precision of ~3.4% over the full range
+ * - 1, with a precision of ~0.2% over the full range
+ * - 2, with a precision of ~4e-4% over the full range
+ */
+template<int>
+static float inversesqrtFast(float f) noexcept;
+
+template<>
+float inversesqrtFast<0>(float f) noexcept {
+    return details::inverseSqrtFast(f, 0x5f3759df);
+}
+
+template<>
+float inversesqrtFast<1>(float f) noexcept {
+    float x = details::inverseSqrtFast(f, 0x5f375a86);
+    return details::inversesqrtNewtonRaphson(f, x);
+}
+
+template<>
+float inversesqrtFast<2>(float f) noexcept {
+    float x = details::inverseSqrtFast(f, 0x5f375a86);
+    x = details::inversesqrtNewtonRaphson(f, x);
+    x = details::inversesqrtNewtonRaphson(f, x);
+    return x;
+}
+
+/**
+ * Approximates a square root using a specified number of
+ * Newton-Raphson iterations. The number of iterations can be:
+ *
+ * - 0, with a precision of ~0.7% over the full range
+ * - 1, with a precision of ~0.2% over the full range
+ * - 2, with a precision of ~4e-4% over the full range
+ */
+template<int>
+static float sqrtFast(float f) noexcept;
+
+template<>
+float sqrtFast<0>(float f) noexcept {
+    int v = details::asInt(f);
+    v = 0x1fbd1df5 + (v >> 1);
+    return details::asFloat(v);
+}
+
+template<>
+float sqrtFast<1>(float f) noexcept {
+    return f * inversesqrtFast<1>(f);
+}
+
+template<>
+float sqrtFast<2>(float f) noexcept {
+    return f * inversesqrtFast<2>(f);
+}
+
+/**
+ * Approximates a reciprocal using a specified number
+ * of Newton-Raphson iterations. The number of iterations
+ * can be:
+ *
+ * - 0, with a precision of ~0.4% over the full range
+ * - 1, with a precision of ~0.02% over the full range
+ * - 2, with a precision of ~5e-5% over the full range
+ */
+template<int>
+static float rcpFast(float f) noexcept;
+
+template<>
+float rcpFast<0>(float f) noexcept {
+    return details::rcpFast(f, 0x7ef311c2);
+}
+
+template<>
+float rcpFast<1>(float f) noexcept {
+    float x = details::rcpFast(f, 0x7ef311c3);
+    return details::rcpNewtonRaphson(f, x);
+}
+
+template<>
+float rcpFast<2>(float f) noexcept {
+    float x = details::rcpFast(f, 0x7ef312ac);
+    x = details::rcpNewtonRaphson(f, x);
+    x = details::rcpNewtonRaphson(f, x);
+    return x;
+}
+
+} // namespace std
+
+#endif // UI_SCALAR_H
