Home | History | Annotate | Download | only in math
      1 /*
      2  * Copyright (C) 2016 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 #include "common/math/vec.h"
     18 #include "common/math/macros.h"
     19 
     20 void findOrthogonalVector(float inX, float inY, float inZ, float *outX,
     21                           float *outY, float *outZ) {
     22   ASSERT_NOT_NULL(outX);
     23   ASSERT_NOT_NULL(outY);
     24   ASSERT_NOT_NULL(outZ);
     25   float x, y, z;
     26 
     27   // discard the one with the smallest absolute value
     28   if (fabsf(inX) <= fabsf(inY) && fabsf(inX) <= fabsf(inZ)) {
     29     x = 0.0f;
     30     y = inZ;
     31     z = -inY;
     32   } else if (fabsf(inY) <= fabsf(inZ)) {
     33     x = inZ;
     34     y = 0.0f;
     35     z = -inX;
     36   } else {
     37     x = inY;
     38     y = -inX;
     39     z = 0.0f;
     40   }
     41 
     42   float magSquared = x * x + y * y + z * z;
     43   ASSERT(magSquared > 0);
     44   // Only set invMag if magSquared is non-zero.
     45   float invMag = 1.0f;
     46   if (magSquared > 0) {
     47     invMag = 1.0f / sqrtf(magSquared);
     48   }
     49   *outX = x * invMag;
     50   *outY = y * invMag;
     51   *outZ = z * invMag;
     52 }
     53 
     54 void vecAdd(float *u, const float *v, const float *w, size_t dim) {
     55   ASSERT_NOT_NULL(u);
     56   ASSERT_NOT_NULL(v);
     57   ASSERT_NOT_NULL(w);
     58   size_t i;
     59   for (i = 0; i < dim; i++) {
     60     u[i] = v[i] + w[i];
     61   }
     62 }
     63 
     64 void vecAddInPlace(float *v, const float *w, size_t dim) {
     65   ASSERT_NOT_NULL(v);
     66   ASSERT_NOT_NULL(w);
     67   size_t i;
     68   for (i = 0; i < dim; i++) {
     69     v[i] += w[i];
     70   }
     71 }
     72 
     73 void vecSub(float *u, const float *v, const float *w, size_t dim) {
     74   ASSERT_NOT_NULL(u);
     75   ASSERT_NOT_NULL(v);
     76   ASSERT_NOT_NULL(w);
     77   size_t i;
     78   for (i = 0; i < dim; i++) {
     79     u[i] = v[i] - w[i];
     80   }
     81 }
     82 
     83 void vecScalarMul(float *u, const float *v, float c, size_t dim) {
     84   ASSERT_NOT_NULL(u);
     85   ASSERT_NOT_NULL(v);
     86   size_t i;
     87   for (i = 0; i < dim; i++) {
     88     u[i] = c * v[i];
     89   }
     90 }
     91 
     92 void vecScalarMulInPlace(float *v, float c, size_t dim) {
     93   ASSERT_NOT_NULL(v);
     94   size_t i;
     95   for (i = 0; i < dim; i++) {
     96     v[i] *= c;
     97   }
     98 }
     99 
    100 float vecNorm(const float *v, size_t dim) {
    101   ASSERT_NOT_NULL(v);
    102   float norm_sq = vecNormSquared(v, dim);
    103   return sqrtf(norm_sq);
    104 }
    105 
    106 float vecNormSquared(const float *v, size_t dim) {
    107   ASSERT_NOT_NULL(v);
    108   return vecDot(v, v, dim);
    109 }
    110 
    111 float vecDot(const float *v, const float *w, size_t dim) {
    112   ASSERT_NOT_NULL(v);
    113   ASSERT_NOT_NULL(w);
    114   size_t i;
    115   float result = 0;
    116   for (i = 0; i < dim; ++i) {
    117     result += v[i] * w[i];
    118   }
    119   return result;
    120 }
    121 
    122 float vecMaxAbsoluteValue(const float *v, size_t dim) {
    123   ASSERT_NOT_NULL(v);
    124   float max = NANO_ABS(v[0]);
    125   float tmp;
    126   size_t i;
    127   for (i = 1; i < dim; ++i) {
    128     tmp = NANO_ABS(v[i]);
    129     if(tmp > max) {
    130       max = tmp;
    131     }
    132   }
    133   return max;
    134 }
    135