File indexing completed on 2025-03-09 03:55:00
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 16/08/2016 0007 * Description : Vector operations methods for red eyes detection. 0008 * 0009 * SPDX-FileCopyrightText: 2016 by Omar Amin <Omar dot moh dot amin at gmail dot com> 0010 * SPDX-FileCopyrightText: 2016-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #ifndef DIGIKAM_VECTOR_OPERATIONS_H 0017 #define DIGIKAM_VECTOR_OPERATIONS_H 0018 0019 // C++ includes 0020 0021 #include <vector> 0022 0023 // Qt includes 0024 0025 #include <QtGlobal> 0026 0027 namespace Digikam 0028 { 0029 0030 template<class T> 0031 inline T length_squared(const std::vector<T>& diff) 0032 { 0033 T sum = 0; 0034 0035 for (unsigned int i = 0 ; i < diff.size() ; ++i) 0036 { 0037 sum += diff[i] * diff[i]; 0038 } 0039 0040 return sum; 0041 } 0042 0043 template<class T> 0044 std::vector<T> operator-(const std::vector<T>& v1, const std::vector<T>& v2) 0045 { 0046 Q_ASSERT(v1.size() == v2.size()); 0047 0048 std::vector<T> result(v1.size()); 0049 0050 for (unsigned int i = 0 ; i < v1.size() ; ++i) 0051 { 0052 result[i] = v1[i] - v2[i]; 0053 } 0054 0055 return result; 0056 } 0057 0058 template<class T> 0059 std::vector<T> operator-(const std::vector<T>& v1) 0060 { 0061 std::vector<T> result(v1.size()); 0062 0063 for (unsigned int i = 0 ; i < v1.size() ; ++i) 0064 { 0065 result[i] = -v1[i]; 0066 } 0067 0068 return result; 0069 } 0070 0071 template<class T> 0072 std::vector<T> operator/(const std::vector<T>& v1, int divisor) 0073 { 0074 std::vector<T> result(v1.size()); 0075 0076 for (unsigned int i = 0 ; i < v1.size() ; ++i) 0077 { 0078 result[i] = v1[i] / divisor; 0079 } 0080 0081 return result; 0082 } 0083 0084 template<class T> 0085 std::vector<std::vector<T> > operator/(const std::vector<std::vector<T> >& v1, int divisor) 0086 { 0087 /* 0088 Q_ASSERT(v1[0].size() != v2.size()); 0089 */ 0090 std::vector<std::vector<T> > result(v1.size(),std::vector<T>(v1[0].size(),0)); 0091 0092 for (unsigned int i = 0 ; i < v1.size() ; ++i) 0093 { 0094 for (unsigned int j = 0 ; j < v1[0].size() ; ++j) 0095 { 0096 result[i][j] = v1[i][j] / divisor; 0097 } 0098 } 0099 0100 return result; 0101 } 0102 0103 template<class T> 0104 std::vector<T> operator+(const std::vector<T>& v1, const std::vector<T>& v2) 0105 { 0106 Q_ASSERT(v1.size() == v2.size()); 0107 0108 std::vector<T> result(v1.size()); 0109 0110 for (unsigned int i = 0 ; i < v1.size() ; ++i) 0111 { 0112 result[i] = v1[i] + v2[i]; 0113 } 0114 0115 return result; 0116 } 0117 0118 template<class T> 0119 std::vector<std::vector<T> > operator+(const std::vector<std::vector<T> >& v1, 0120 const std::vector<std::vector<T> >& v2) 0121 { 0122 Q_ASSERT((v1.size() == v2.size()) && 0123 (v1[0].size() == v2[0].size())); 0124 0125 std::vector<std::vector<T> > result(v1.size(), std::vector<T>(v1[0].size(),0)); 0126 0127 for (unsigned int i = 0 ; i < v1.size() ; ++i) 0128 { 0129 for (unsigned int j = 0 ; j < v2[0].size() ; ++j) 0130 { 0131 result[i][j] += v1[i][j] + v2[i][j]; 0132 } 0133 0134 } 0135 0136 return result; 0137 } 0138 0139 template<class T> 0140 std::vector<T> operator*(const std::vector<std::vector<T> >& v1, 0141 const std::vector<T>& v2) 0142 { 0143 Q_ASSERT(v1[0].size() == v2.size()); 0144 0145 std::vector<T> result(v1.size()); 0146 0147 for (unsigned int i = 0 ; i < v1.size() ; ++i) 0148 { 0149 result[i] = 0; 0150 0151 for (unsigned int j = 0 ; j < v1[0].size() ; ++j) 0152 { 0153 result[i] += v1[i][j] * v2[j]; 0154 } 0155 } 0156 0157 return result; 0158 } 0159 0160 template<class T> 0161 std::vector<std::vector<T> > operator*(const std::vector<std::vector<T> >& v1, 0162 const std::vector<std::vector<T> >& v2) 0163 { 0164 Q_ASSERT(v1[0].size() == v2.size()); 0165 0166 std::vector<std::vector<T> > result(v1.size(), std::vector<T>(v2[0].size(),0)); 0167 0168 for (unsigned int i = 0 ; i < v1.size() ; ++i) 0169 { 0170 for (unsigned int k = 0 ; k < v1[0].size() ; ++k) 0171 { 0172 // swapping j and k loops for cache optimization 0173 0174 for (unsigned int j = 0 ; j < v2[0].size() ; ++j) 0175 { 0176 0177 result[i][j] += v1[i][k] * v2[k][j]; 0178 } 0179 } 0180 } 0181 0182 return result; 0183 } 0184 0185 0186 template<class T> 0187 std::vector<std::vector<T> > operator*(const std::vector<T>& v1, 0188 const std::vector<T>& v2) 0189 { 0190 Q_ASSERT(v1.size() == v2.size()); 0191 0192 std::vector<std::vector<T> > result(v1.size(), std::vector<T>(v2.size(), 0)); 0193 0194 for (unsigned int i = 0 ; i < v1.size() ; ++i) 0195 { 0196 for (unsigned int j = 0 ; j < v1.size() ; ++j) 0197 { 0198 result[i][j] = v1[i] * v2[j]; 0199 } 0200 } 0201 0202 return result; 0203 } 0204 0205 template<class T> 0206 std::vector<std::vector<T> > operator+(const std::vector<std::vector<T> >& v1, 0207 float d) 0208 { 0209 /* 0210 Q_ASSERT((v1.size() == v2.size()) && 0211 (v1[0].size() == v2[0].size())); 0212 */ 0213 std::vector<std::vector<T> > result(v1.size(), std::vector<T>(v1[0].size(), 0)); 0214 0215 for (unsigned int i = 0 ; i < v1.size() ; ++i) 0216 { 0217 for (unsigned int j = 0 ; j < v1[0].size() ; ++j) 0218 { 0219 result[i][j] = v1[i][j] * d; 0220 } 0221 0222 } 0223 0224 return result; 0225 } 0226 0227 template<class T> 0228 std::vector<T> operator*(const std::vector<T>& v1, 0229 float d) 0230 { 0231 /* 0232 Q_ASSERT((v1.size() == v2.size()) && 0233 (v1[0].size() == v2[0].size())); 0234 */ 0235 std::vector<T> result(v1.size()); 0236 0237 for (unsigned int i = 0 ; i < v1.size() ; ++i) 0238 { 0239 result[i] = v1[i] * d; 0240 0241 } 0242 0243 return result; 0244 } 0245 0246 } // namespace Digikam 0247 0248 #endif // DIGIKAM_VECTOR_OPERATIONS_H