Home | History | Annotate | Download | only in math
      1 /*
      2  * Copyright 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 
     18 #pragma once
     19 
     20 #include <math.h>
     21 #include <stdint.h>
     22 #include <sys/types.h>
     23 
     24 #include <cmath>
     25 #include <limits>
     26 #include <iostream>
     27 
     28 #define PURE __attribute__((pure))
     29 
     30 #if __cplusplus >= 201402L
     31 #define CONSTEXPR constexpr
     32 #else
     33 #define CONSTEXPR
     34 #endif
     35 
     36 namespace android {
     37 namespace details {
     38 // -------------------------------------------------------------------------------------
     39 
     40 /*
     41  * No user serviceable parts here.
     42  *
     43  * Don't use this file directly, instead include ui/vec{2|3|4}.h
     44  */
     45 
     46 /*
     47  * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments
     48  * operators on a vector of type BASE<T>.
     49  *
     50  * BASE only needs to implement operator[] and size().
     51  * By simply inheriting from TVec{Add|Product}Operators<BASE, T> BASE will automatically
     52  * get all the functionality here.
     53  */
     54 
     55 template <template<typename T> class VECTOR, typename T>
     56 class TVecAddOperators {
     57 public:
     58     /* compound assignment from a another vector of the same size but different
     59      * element type.
     60      */
     61     template<typename OTHER>
     62     VECTOR<T>& operator +=(const VECTOR<OTHER>& v) {
     63         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
     64         for (size_t i = 0; i < lhs.size(); i++) {
     65             lhs[i] += v[i];
     66         }
     67         return lhs;
     68     }
     69     template<typename OTHER>
     70     VECTOR<T>& operator -=(const VECTOR<OTHER>& v) {
     71         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
     72         for (size_t i = 0; i < lhs.size(); i++) {
     73             lhs[i] -= v[i];
     74         }
     75         return lhs;
     76     }
     77 
     78     /* compound assignment from a another vector of the same type.
     79      * These operators can be used for implicit conversion and  handle operations
     80      * like "vector *= scalar" by letting the compiler implicitly convert a scalar
     81      * to a vector (assuming the BASE<T> allows it).
     82      */
     83     VECTOR<T>& operator +=(const VECTOR<T>& v) {
     84         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
     85         for (size_t i = 0; i < lhs.size(); i++) {
     86             lhs[i] += v[i];
     87         }
     88         return lhs;
     89     }
     90     VECTOR<T>& operator -=(const VECTOR<T>& v) {
     91         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
     92         for (size_t i = 0; i < lhs.size(); i++) {
     93             lhs[i] -= v[i];
     94         }
     95         return lhs;
     96     }
     97 
     98     /*
     99      * NOTE: the functions below ARE NOT member methods. They are friend functions
    100      * with they definition inlined with their declaration. This makes these
    101      * template functions available to the compiler when (and only when) this class
    102      * is instantiated, at which point they're only templated on the 2nd parameter
    103      * (the first one, BASE<T> being known).
    104      */
    105 
    106     /* The operators below handle operation between vectors of the same size
    107      * but of a different element type.
    108      */
    109     template<typename RT>
    110     friend inline constexpr VECTOR<T> PURE operator +(VECTOR<T> lv, const VECTOR<RT>& rv) {
    111         // don't pass lv by reference because we need a copy anyways
    112         return lv += rv;
    113     }
    114     template<typename RT>
    115     friend inline constexpr VECTOR<T> PURE operator -(VECTOR<T> lv, const VECTOR<RT>& rv) {
    116         // don't pass lv by reference because we need a copy anyways
    117         return lv -= rv;
    118     }
    119 
    120     /* The operators below (which are not templates once this class is instanced,
    121      * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
    122      * These handle operations like "vector + scalar" and "scalar + vector" by
    123      * letting the compiler implicitly convert a scalar to a vector (assuming
    124      * the BASE<T> allows it).
    125      */
    126     friend inline constexpr VECTOR<T> PURE operator +(VECTOR<T> lv, const VECTOR<T>& rv) {
    127         // don't pass lv by reference because we need a copy anyways
    128         return lv += rv;
    129     }
    130     friend inline constexpr VECTOR<T> PURE operator -(VECTOR<T> lv, const VECTOR<T>& rv) {
    131         // don't pass lv by reference because we need a copy anyways
    132         return lv -= rv;
    133     }
    134 };
    135 
    136 template<template<typename T> class VECTOR, typename T>
    137 class TVecProductOperators {
    138 public:
    139     /* compound assignment from a another vector of the same size but different
    140      * element type.
    141      */
    142     template<typename OTHER>
    143     VECTOR<T>& operator *=(const VECTOR<OTHER>& v) {
    144         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
    145         for (size_t i = 0; i < lhs.size(); i++) {
    146             lhs[i] *= v[i];
    147         }
    148         return lhs;
    149     }
    150     template<typename OTHER>
    151     VECTOR<T>& operator /=(const VECTOR<OTHER>& v) {
    152         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
    153         for (size_t i = 0; i < lhs.size(); i++) {
    154             lhs[i] /= v[i];
    155         }
    156         return lhs;
    157     }
    158 
    159     /* compound assignment from a another vector of the same type.
    160      * These operators can be used for implicit conversion and  handle operations
    161      * like "vector *= scalar" by letting the compiler implicitly convert a scalar
    162      * to a vector (assuming the BASE<T> allows it).
    163      */
    164     VECTOR<T>& operator *=(const VECTOR<T>& v) {
    165         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
    166         for (size_t i = 0; i < lhs.size(); i++) {
    167             lhs[i] *= v[i];
    168         }
    169         return lhs;
    170     }
    171     VECTOR<T>& operator /=(const VECTOR<T>& v) {
    172         VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
    173         for (size_t i = 0; i < lhs.size(); i++) {
    174             lhs[i] /= v[i];
    175         }
    176         return lhs;
    177     }
    178 
    179     /*
    180      * NOTE: the functions below ARE NOT member methods. They are friend functions
    181      * with they definition inlined with their declaration. This makes these
    182      * template functions available to the compiler when (and only when) this class
    183      * is instantiated, at which point they're only templated on the 2nd parameter
    184      * (the first one, BASE<T> being known).
    185      */
    186 
    187     /* The operators below handle operation between vectors of the same size
    188      * but of a different element type.
    189      */
    190     template<typename RT>
    191     friend inline constexpr VECTOR<T> PURE operator *(VECTOR<T> lv, const VECTOR<RT>& rv) {
    192         // don't pass lv by reference because we need a copy anyways
    193         return lv *= rv;
    194     }
    195     template<typename RT>
    196     friend inline constexpr VECTOR<T> PURE operator /(VECTOR<T> lv, const VECTOR<RT>& rv) {
    197         // don't pass lv by reference because we need a copy anyways
    198         return lv /= rv;
    199     }
    200 
    201     /* The operators below (which are not templates once this class is instanced,
    202      * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
    203      * These handle operations like "vector * scalar" and "scalar * vector" by
    204      * letting the compiler implicitly convert a scalar to a vector (assuming
    205      * the BASE<T> allows it).
    206      */
    207     friend inline constexpr VECTOR<T> PURE operator *(VECTOR<T> lv, const VECTOR<T>& rv) {
    208         // don't pass lv by reference because we need a copy anyways
    209         return lv *= rv;
    210     }
    211     friend inline constexpr VECTOR<T> PURE operator /(VECTOR<T> lv, const VECTOR<T>& rv) {
    212         // don't pass lv by reference because we need a copy anyways
    213         return lv /= rv;
    214     }
    215 };
    216 
    217 /*
    218  * TVecUnaryOperators implements unary operators on a vector of type BASE<T>.
    219  *
    220  * BASE only needs to implement operator[] and size().
    221  * By simply inheriting from TVecUnaryOperators<BASE, T> BASE will automatically
    222  * get all the functionality here.
    223  *
    224  * These operators are implemented as friend functions of TVecUnaryOperators<BASE, T>
    225  */
    226 template<template<typename T> class VECTOR, typename T>
    227 class TVecUnaryOperators {
    228 public:
    229     VECTOR<T>& operator ++() {
    230         VECTOR<T>& rhs = static_cast<VECTOR<T>&>(*this);
    231         for (size_t i = 0; i < rhs.size(); i++) {
    232             ++rhs[i];
    233         }
    234         return rhs;
    235     }
    236 
    237     VECTOR<T>& operator --() {
    238         VECTOR<T>& rhs = static_cast<VECTOR<T>&>(*this);
    239         for (size_t i = 0; i < rhs.size(); i++) {
    240             --rhs[i];
    241         }
    242         return rhs;
    243     }
    244 
    245     CONSTEXPR VECTOR<T> operator -() const {
    246         VECTOR<T> r(VECTOR<T>::NO_INIT);
    247         VECTOR<T> const& rv(static_cast<VECTOR<T> const&>(*this));
    248         for (size_t i = 0; i < r.size(); i++) {
    249             r[i] = -rv[i];
    250         }
    251         return r;
    252     }
    253 };
    254 
    255 /*
    256  * TVecComparisonOperators implements relational/comparison operators
    257  * on a vector of type BASE<T>.
    258  *
    259  * BASE only needs to implement operator[] and size().
    260  * By simply inheriting from TVecComparisonOperators<BASE, T> BASE will automatically
    261  * get all the functionality here.
    262  */
    263 template<template<typename T> class VECTOR, typename T>
    264 class TVecComparisonOperators {
    265 public:
    266     /*
    267      * NOTE: the functions below ARE NOT member methods. They are friend functions
    268      * with they definition inlined with their declaration. This makes these
    269      * template functions available to the compiler when (and only when) this class
    270      * is instantiated, at which point they're only templated on the 2nd parameter
    271      * (the first one, BASE<T> being known).
    272      */
    273     template<typename RT>
    274     friend inline
    275     bool PURE operator ==(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    276         for (size_t i = 0; i < lv.size(); i++)
    277             if (lv[i] != rv[i])
    278                 return false;
    279         return true;
    280     }
    281 
    282     template<typename RT>
    283     friend inline
    284     bool PURE operator !=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    285         return !operator ==(lv, rv);
    286     }
    287 
    288     template<typename RT>
    289     friend inline
    290     bool PURE operator >(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    291         for (size_t i = 0; i < lv.size(); i++) {
    292             if (lv[i] == rv[i]) {
    293                 continue;
    294             }
    295             return lv[i] > rv[i];
    296         }
    297         return false;
    298     }
    299 
    300     template<typename RT>
    301     friend inline
    302     constexpr bool PURE operator <=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    303         return !(lv > rv);
    304     }
    305 
    306     template<typename RT>
    307     friend inline
    308     bool PURE operator <(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    309         for (size_t i = 0; i < lv.size(); i++) {
    310             if (lv[i] == rv[i]) {
    311                 continue;
    312             }
    313             return lv[i] < rv[i];
    314         }
    315         return false;
    316     }
    317 
    318     template<typename RT>
    319     friend inline
    320     constexpr bool PURE operator >=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    321         return !(lv < rv);
    322     }
    323 
    324     template<typename RT>
    325     friend inline
    326     CONSTEXPR VECTOR<bool> PURE equal(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    327         VECTOR<bool> r;
    328         for (size_t i = 0; i < lv.size(); i++) {
    329             r[i] = lv[i] == rv[i];
    330         }
    331         return r;
    332     }
    333 
    334     template<typename RT>
    335     friend inline
    336     CONSTEXPR VECTOR<bool> PURE notEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    337         VECTOR<bool> r;
    338         for (size_t i = 0; i < lv.size(); i++) {
    339             r[i] = lv[i] != rv[i];
    340         }
    341         return r;
    342     }
    343 
    344     template<typename RT>
    345     friend inline
    346     CONSTEXPR VECTOR<bool> PURE lessThan(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    347         VECTOR<bool> r;
    348         for (size_t i = 0; i < lv.size(); i++) {
    349             r[i] = lv[i] < rv[i];
    350         }
    351         return r;
    352     }
    353 
    354     template<typename RT>
    355     friend inline
    356     CONSTEXPR VECTOR<bool> PURE lessThanEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    357         VECTOR<bool> r;
    358         for (size_t i = 0; i < lv.size(); i++) {
    359             r[i] = lv[i] <= rv[i];
    360         }
    361         return r;
    362     }
    363 
    364     template<typename RT>
    365     friend inline
    366     CONSTEXPR VECTOR<bool> PURE greaterThan(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    367         VECTOR<bool> r;
    368         for (size_t i = 0; i < lv.size(); i++) {
    369             r[i] = lv[i] > rv[i];
    370         }
    371         return r;
    372     }
    373 
    374     template<typename RT>
    375     friend inline
    376     CONSTEXPR VECTOR<bool> PURE greaterThanEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    377         VECTOR<bool> r;
    378         for (size_t i = 0; i < lv.size(); i++) {
    379             r[i] = lv[i] >= rv[i];
    380         }
    381         return r;
    382     }
    383 };
    384 
    385 /*
    386  * TVecFunctions implements functions on a vector of type BASE<T>.
    387  *
    388  * BASE only needs to implement operator[] and size().
    389  * By simply inheriting from TVecFunctions<BASE, T> BASE will automatically
    390  * get all the functionality here.
    391  */
    392 template<template<typename T> class VECTOR, typename T>
    393 class TVecFunctions {
    394 public:
    395     /*
    396      * NOTE: the functions below ARE NOT member methods. They are friend functions
    397      * with they definition inlined with their declaration. This makes these
    398      * template functions available to the compiler when (and only when) this class
    399      * is instantiated, at which point they're only templated on the 2nd parameter
    400      * (the first one, BASE<T> being known).
    401      */
    402     template<typename RT>
    403     friend inline CONSTEXPR T PURE dot(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    404         T r(0);
    405         for (size_t i = 0; i < lv.size(); i++) {
    406             //r = std::fma(lv[i], rv[i], r);
    407             r += lv[i] * rv[i];
    408         }
    409         return r;
    410     }
    411 
    412     friend inline constexpr T PURE norm(const VECTOR<T>& lv) {
    413         return std::sqrt(dot(lv, lv));
    414     }
    415 
    416     friend inline constexpr T PURE length(const VECTOR<T>& lv) {
    417         return norm(lv);
    418     }
    419 
    420     friend inline constexpr T PURE norm2(const VECTOR<T>& lv) {
    421         return dot(lv, lv);
    422     }
    423 
    424     friend inline constexpr T PURE length2(const VECTOR<T>& lv) {
    425         return norm2(lv);
    426     }
    427 
    428     template<typename RT>
    429     friend inline constexpr T PURE distance(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    430         return length(rv - lv);
    431     }
    432 
    433     template<typename RT>
    434     friend inline constexpr T PURE distance2(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
    435         return length2(rv - lv);
    436     }
    437 
    438     friend inline constexpr VECTOR<T> PURE normalize(const VECTOR<T>& lv) {
    439         return lv * (T(1) / length(lv));
    440     }
    441 
    442     friend inline constexpr VECTOR<T> PURE rcp(VECTOR<T> v) {
    443         return T(1) / v;
    444     }
    445 
    446     friend inline CONSTEXPR VECTOR<T> PURE abs(VECTOR<T> v) {
    447         for (size_t i = 0; i < v.size(); i++) {
    448             v[i] = std::abs(v[i]);
    449         }
    450         return v;
    451     }
    452 
    453     friend inline CONSTEXPR VECTOR<T> PURE floor(VECTOR<T> v) {
    454         for (size_t i = 0; i < v.size(); i++) {
    455             v[i] = std::floor(v[i]);
    456         }
    457         return v;
    458     }
    459 
    460     friend inline CONSTEXPR VECTOR<T> PURE ceil(VECTOR<T> v) {
    461         for (size_t i = 0; i < v.size(); i++) {
    462             v[i] = std::ceil(v[i]);
    463         }
    464         return v;
    465     }
    466 
    467     friend inline CONSTEXPR VECTOR<T> PURE round(VECTOR<T> v) {
    468         for (size_t i = 0; i < v.size(); i++) {
    469             v[i] = std::round(v[i]);
    470         }
    471         return v;
    472     }
    473 
    474     friend inline CONSTEXPR VECTOR<T> PURE inversesqrt(VECTOR<T> v) {
    475         for (size_t i = 0; i < v.size(); i++) {
    476             v[i] = T(1) / std::sqrt(v[i]);
    477         }
    478         return v;
    479     }
    480 
    481     friend inline CONSTEXPR VECTOR<T> PURE sqrt(VECTOR<T> v) {
    482         for (size_t i = 0; i < v.size(); i++) {
    483             v[i] = std::sqrt(v[i]);
    484         }
    485         return v;
    486     }
    487 
    488     friend inline CONSTEXPR VECTOR<T> PURE pow(VECTOR<T> v, T p) {
    489         for (size_t i = 0; i < v.size(); i++) {
    490             v[i] = std::pow(v[i], p);
    491         }
    492         return v;
    493     }
    494 
    495     friend inline CONSTEXPR VECTOR<T> PURE saturate(const VECTOR<T>& lv) {
    496         return clamp(lv, T(0), T(1));
    497     }
    498 
    499     friend inline CONSTEXPR VECTOR<T> PURE clamp(VECTOR<T> v, T min, T max) {
    500         for (size_t i = 0; i< v.size(); i++) {
    501             v[i] = std::min(max, std::max(min, v[i]));
    502         }
    503         return v;
    504     }
    505 
    506     friend inline CONSTEXPR VECTOR<T> PURE fma(const VECTOR<T>& lv, const VECTOR<T>& rv, VECTOR<T> a) {
    507         for (size_t i = 0; i<lv.size(); i++) {
    508             //a[i] = std::fma(lv[i], rv[i], a[i]);
    509             a[i] += (lv[i] * rv[i]);
    510         }
    511         return a;
    512     }
    513 
    514     friend inline CONSTEXPR VECTOR<T> PURE min(const VECTOR<T>& u, VECTOR<T> v) {
    515         for (size_t i = 0; i < v.size(); i++) {
    516             v[i] = std::min(u[i], v[i]);
    517         }
    518         return v;
    519     }
    520 
    521     friend inline CONSTEXPR VECTOR<T> PURE max(const VECTOR<T>& u, VECTOR<T> v) {
    522         for (size_t i = 0; i < v.size(); i++) {
    523             v[i] = std::max(u[i], v[i]);
    524         }
    525         return v;
    526     }
    527 
    528     friend inline CONSTEXPR T PURE max(const VECTOR<T>& v) {
    529         T r(std::numeric_limits<T>::lowest());
    530         for (size_t i = 0; i < v.size(); i++) {
    531             r = std::max(r, v[i]);
    532         }
    533         return r;
    534     }
    535 
    536     friend inline CONSTEXPR T PURE min(const VECTOR<T>& v) {
    537         T r(std::numeric_limits<T>::max());
    538         for (size_t i = 0; i < v.size(); i++) {
    539             r = std::min(r, v[i]);
    540         }
    541         return r;
    542     }
    543 
    544     friend inline CONSTEXPR VECTOR<T> PURE apply(VECTOR<T> v, const std::function<T(T)>& f) {
    545         for (size_t i = 0; i < v.size(); i++) {
    546             v[i] = f(v[i]);
    547         }
    548         return v;
    549     }
    550 
    551     friend inline CONSTEXPR bool PURE any(const VECTOR<T>& v) {
    552         for (size_t i = 0; i < v.size(); i++) {
    553             if (v[i] != T(0)) return true;
    554         }
    555         return false;
    556     }
    557 
    558     friend inline CONSTEXPR bool PURE all(const VECTOR<T>& v) {
    559         bool result = true;
    560         for (size_t i = 0; i < v.size(); i++) {
    561             result &= (v[i] != T(0));
    562         }
    563         return result;
    564     }
    565 
    566     template<typename R>
    567     friend inline CONSTEXPR VECTOR<R> PURE map(VECTOR<T> v, const std::function<R(T)>& f) {
    568         VECTOR<R> result;
    569         for (size_t i = 0; i < v.size(); i++) {
    570             result[i] = f(v[i]);
    571         }
    572         return result;
    573     }
    574 };
    575 
    576 /*
    577  * TVecDebug implements functions on a vector of type BASE<T>.
    578  *
    579  * BASE only needs to implement operator[] and size().
    580  * By simply inheriting from TVecDebug<BASE, T> BASE will automatically
    581  * get all the functionality here.
    582  */
    583 template<template<typename T> class VECTOR, typename T>
    584 class TVecDebug {
    585 public:
    586     /*
    587      * NOTE: the functions below ARE NOT member methods. They are friend functions
    588      * with they definition inlined with their declaration. This makes these
    589      * template functions available to the compiler when (and only when) this class
    590      * is instantiated, at which point they're only templated on the 2nd parameter
    591      * (the first one, BASE<T> being known).
    592      */
    593     friend std::ostream& operator<<(std::ostream& stream, const VECTOR<T>& v) {
    594         stream << "< ";
    595         for (size_t i = 0; i < v.size() - 1; i++) {
    596             stream << T(v[i]) << ", ";
    597         }
    598         stream << T(v[v.size() - 1]) << " >";
    599         return stream;
    600     }
    601 };
    602 
    603 #undef CONSTEXPR
    604 #undef PURE
    605 
    606 // -------------------------------------------------------------------------------------
    607 }  // namespace details
    608 }  // namespace android
    609