00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef WIN32
00021 #include <memory.h>
00022 #else
00023 #ifdef LINUX
00024 #include <string.h>
00025 #endif
00026 #endif
00027
00028 #include <iostream.h>
00029 #include <SYS/SYS_Align.h>
00030 #include <VM/VM_Math.h>
00031
00032 #include "UT_Math.h"
00033 #include "UT_Vector.h"
00034
00035 #include "UT_Vector2.h"
00036 #include "UT_Vector3.h"
00037 #include "UT_Vector4.h"
00038
00039 template <typename T>
00040 UT_VectorT<T>::UT_VectorT(int nl, int nh)
00041 {
00042 myVector = 0;
00043 myOwnData = 0;
00044 init(nl, nh);
00045 }
00046
00047 template <typename T>
00048 UT_VectorT<T>::UT_VectorT(const UT_VectorT<T> &v)
00049 {
00050 int i;
00051
00052 myVector = 0;
00053 myOwnData = 0;
00054 init(v.myNL, v.myNH);
00055 for (i = v.myNL; i <= v.myNH; i++)
00056 myVector[i] = v.myVector[i];
00057 }
00058
00059 template <typename T>
00060 UT_VectorT<T>::~UT_VectorT()
00061 {
00062 if (myOwnData && myVector)
00063 SYSafree(myVector + myNL);
00064 }
00065
00066 template <typename T>
00067 void
00068 UT_VectorT<T>::subvector(const UT_VectorT<T> &v, int nl, int nh)
00069 {
00070 int n = nh - nl + 1;
00071
00072 if (myOwnData && myVector)
00073 SYSafree(myVector + myNL);
00074 myOwnData = 0;
00075 myNL = 1;
00076 myNH = n;
00077 myVector = &v.myVector[nl] - 1;
00078 }
00079
00080
00081 template <typename T, typename S>
00082 static void
00083 utAssign(const T *data, S *vec, int nl, int nh)
00084 {
00085 const int n = nh - nl + 1;
00086 S *dst;
00087 int i;
00088
00089
00090
00091 dst = vec + nl;
00092 for (i = 0; i < n; i++)
00093 *dst++ = *data++;
00094 }
00095
00096 template <typename T>
00097 void
00098 UT_VectorT<T>::assign(const fpreal32 *data, int nl, int nh)
00099 {
00100 UT_ASSERT_P(nl >= myNL && nh <= myNH && (nh - nl + 1) >= 0);
00101 utAssign(data, myVector, nl, nh);
00102 }
00103
00104 template <typename T>
00105 void
00106 UT_VectorT<T>::assign(const fpreal64 *data, int nl, int nh)
00107 {
00108 UT_ASSERT_P(nl >= myNL && nh <= myNH && (nh - nl + 1) >= 0);
00109 utAssign(data, myVector, nl, nh);
00110 }
00111
00112 template <typename T>
00113 void
00114 UT_VectorT<T>::init(int nl, int nh)
00115 {
00116 UT_ASSERT((nh - nl + 1) >= 0);
00117
00118 if (myVector && myOwnData)
00119 {
00120 if (nh-nl > myNH-myNL)
00121 {
00122 myVector = (T *)SYSarealloc(myVector + myNL,
00123 (nh - nl + 1)*sizeof(T), 128);
00124 myVector = myVector - nl;
00125 }
00126 else
00127 {
00128 myVector = myVector + myNL - nl;
00129 }
00130 }
00131 else
00132 {
00133 myVector = (T *)SYSamalloc((nh - nl + 1)*sizeof(T), 128);
00134 myVector = myVector - nl;
00135 myOwnData = 1;
00136 }
00137
00138 myNL = nl;
00139 myNH = nh;
00140 }
00141
00142 template <typename T>
00143 void
00144 UT_VectorT<T>::getPartialRange(int &start, int &end, const UT_JobInfo &info) const
00145 {
00146 int units;
00147
00148 units = getNH() - getNL() + 1;
00149 info.divideWork(units, start, end);
00150 start += getNL();
00151 end += getNL();
00152 }
00153
00154 template <typename T>
00155 void
00156 UT_VectorT<T>::zero(int nl, int nh)
00157 {
00158 UT_ASSERT_P(nl >= myNL && nh <= myNH && (nh - nl + 1) >= 0);
00159 memset(myVector + nl, 0, (nh - nl + 1)*sizeof(T));
00160 }
00161
00162 template <typename T>
00163 void
00164 UT_VectorT<T>::getSubvector2(UT_Vector2 &v, int idx) const
00165 {
00166 v.x() = (*this)(idx);
00167 v.y() = (*this)(idx+1);
00168 }
00169
00170 template <typename T>
00171 void
00172 UT_VectorT<T>::setSubvector2(int idx, const UT_Vector2 &v)
00173 {
00174 (*this)(idx) = v.x();
00175 (*this)(idx+1) = v.y();
00176 }
00177
00178 template <typename T>
00179 void
00180 UT_VectorT<T>::getSubvector3(UT_Vector3 &v, int idx) const
00181 {
00182 v.x() = (*this)(idx);
00183 v.y() = (*this)(idx+1);
00184 v.z() = (*this)(idx+2);
00185 }
00186
00187 template <typename T>
00188 void
00189 UT_VectorT<T>::setSubvector3(int idx, const UT_Vector3 &v)
00190 {
00191 (*this)(idx) = v.x();
00192 (*this)(idx+1) = v.y();
00193 (*this)(idx+2) = v.z();
00194 }
00195
00196 template <typename T>
00197 void
00198 UT_VectorT<T>::getSubvector4(UT_Vector4 &v, int idx) const
00199 {
00200 v.x() = (*this)(idx);
00201 v.y() = (*this)(idx+1);
00202 v.z() = (*this)(idx+2);
00203 v.w() = (*this)(idx+3);
00204 }
00205
00206 template <typename T>
00207 void
00208 UT_VectorT<T>::setSubvector4(int idx, const UT_Vector4 &v)
00209 {
00210 (*this)(idx) = v.x();
00211 (*this)(idx+1) = v.y();
00212 (*this)(idx+2) = v.z();
00213 (*this)(idx+3) = v.w();
00214 }
00215
00216 template <typename T>
00217 void
00218 UT_VectorT<T>::changeNL(int nl)
00219 {
00220 int diff = myNL-nl;
00221
00222 myNL = nl;
00223 myNH -= diff;
00224 myVector += diff;
00225 }
00226
00227 template <typename T>
00228 T
00229 UT_VectorT<T>::norm(int type) const
00230 {
00231 fpreal64 result;
00232
00233 result = 0;
00234 normInternal(&result, type);
00235
00236
00237 if (type == 2)
00238 {
00239 result = SYSsqrt(result);
00240 }
00241
00242 return result;
00243 }
00244
00245
00246 template <typename T>
00247 T
00248 UT_VectorT<T>::norm2() const
00249 {
00250 fpreal64 sum = 0.0F;
00251
00252 normInternal(&sum, 2);
00253 return sum;
00254 }
00255
00256 template <typename T>
00257 void
00258 UT_VectorT<T>::normInternalPartial(fpreal64 *output, int type,
00259 const UT_JobInfo &info) const
00260 {
00261 fpreal64 result;
00262 int i, end;
00263
00264 getPartialRange(i, end, info);
00265
00266 if (type == 0)
00267 {
00268 result = SYSabs(myVector[i]);
00269 for (i++; i < end; i++)
00270 if (SYSabs(myVector[i]) > result)
00271 result = SYSabs(myVector[i]);
00272 }
00273 else if (type == 1)
00274 {
00275 result = 0.0F;
00276 for (; i < end; i++)
00277 result += SYSabs(myVector[i]);
00278 }
00279 else
00280 {
00281 result = 0.0F;
00282 for (; i < end; i++)
00283 result += myVector[i] * myVector[i];
00284 }
00285
00286 {
00287 UT_AutoJobInfoLock autolock(info);
00288
00289 if (type == 0)
00290 {
00291
00292 if (result > *output)
00293 *output = result;
00294 }
00295 else
00296 {
00297
00298 *output += result;
00299 }
00300 }
00301 }
00302
00303 template <typename T>
00304 T
00305 UT_VectorT<T>::distance2(const UT_VectorT<T> &v) const
00306 {
00307 fpreal64 sum = 0.0F;
00308
00309 distance2Internal(&sum, v);
00310 return sum;
00311 }
00312
00313 template <typename T>
00314 void
00315 UT_VectorT<T>::distance2InternalPartial(
00316 fpreal64 *output, const UT_VectorT<T> &v, const UT_JobInfo &info) const
00317 {
00318 fpreal64 result;
00319 int i, end;
00320
00321 getPartialRange(i, end, info);
00322
00323 result = 0.0F;
00324 for (; i < end; i++)
00325 {
00326 fpreal64 diff = myVector[i] - v(i);
00327 result += diff * diff;
00328 }
00329
00330
00331 {
00332 UT_AutoJobInfoLock autolock(info);
00333
00334 *output += result;
00335 }
00336 }
00337
00338 template <typename T>
00339 void
00340 UT_VectorT<T>::negPartial(const UT_JobInfo &info)
00341 {
00342 int i, end;
00343
00344 getPartialRange(i, end, info);
00345
00346 for (; i < end; i++)
00347 myVector[i] = -myVector[i];
00348 }
00349
00350 template <typename T>
00351 void
00352 UT_VectorT<T>::negPlusPartial(const UT_VectorT<T> &v, const UT_JobInfo &info)
00353 {
00354 int i, end;
00355
00356 getPartialRange(i, end, info);
00357
00358 for (; i < end; i++)
00359 myVector[i] = v.myVector[i] - myVector[i];
00360 }
00361
00362 template <typename T>
00363 void
00364 UT_VectorT<T>::addScaledVecPartial(T s, const UT_VectorT<T> &v,
00365 const UT_JobInfo &info)
00366 {
00367 int i, end;
00368
00369 getPartialRange(i, end, info);
00370
00371 for (; i < end; i++)
00372 myVector[i] += s * v.myVector[i];
00373 }
00374
00375 template <typename T>
00376 void
00377 UT_VectorT<T>::addScaledVecNorm2Partial(T s, const UT_VectorT<T> &v,
00378 fpreal64 *norm2,
00379 const UT_JobInfo &info)
00380 {
00381 int i, end;
00382 fpreal64 total = 0;
00383 T val;
00384
00385 getPartialRange(i, end, info);
00386
00387 for (; i < end; i++)
00388 {
00389 val = myVector[i];
00390 val += s * v.myVector[i];
00391 myVector[i] = val;
00392 total += val * val;
00393 }
00394
00395 {
00396 UT_AutoJobInfoLock autolock(info);
00397
00398 *norm2 += total;
00399 }
00400 }
00401
00402 template <typename T>
00403 void
00404 UT_VectorT<T>::scaleAddVecPartial(T s, const UT_VectorT<T> &v,
00405 const UT_JobInfo &info)
00406 {
00407 int i, end;
00408
00409 getPartialRange(i, end, info);
00410
00411 for (; i < end; i++)
00412 myVector[i] = s * myVector[i] + v.myVector[i];
00413 }
00414
00415 template <typename T>
00416 void
00417 UT_VectorT<T>::multAndSetPartial(const UT_VectorT<T> &a, const UT_VectorT<T> &b,
00418 const UT_JobInfo &info)
00419 {
00420 int i, end;
00421
00422 getPartialRange(i, end, info);
00423
00424 for (; i < end; i++)
00425 myVector[i] = a.myVector[i] * b.myVector[i];
00426 }
00427
00428 template <typename T>
00429 UT_VectorT<T> &
00430 UT_VectorT<T>::operator= (const UT_VectorT<T> &v)
00431 {
00432 UT_ASSERT_P(length() == v.length());
00433 memcpy(&myVector[myNL], &v.myVector[myNL],
00434 (myNH - myNL + 1) * sizeof(T));
00435 return *this;
00436 }
00437
00438 template <typename T>
00439 UT_VectorT<T> &
00440 UT_VectorT<T>::operator+= (const UT_VectorT<T> &v)
00441 {
00442 int i;
00443
00444 for (i=myNL; i<=myNH; i++)
00445 myVector[i] += v.myVector[i];
00446 return *this;
00447 }
00448
00449 template <typename T>
00450 UT_VectorT<T> &
00451 UT_VectorT<T>::operator-= (const UT_VectorT<T> &v)
00452 {
00453 int i;
00454
00455 for (i=myNL; i<=myNH; i++)
00456 myVector[i] -= v.myVector[i];
00457 return *this;
00458 }
00459
00460 template <typename T>
00461 UT_VectorT<T> &
00462 UT_VectorT<T>::operator*= (const UT_VectorT<T> &v)
00463 {
00464 int i;
00465
00466 for (i=myNL; i<=myNH; i++)
00467 myVector[i] *= v.myVector[i];
00468 return *this;
00469 }
00470
00471 template <typename T>
00472 UT_VectorT<T> &
00473 UT_VectorT<T>::operator/= (const UT_VectorT<T> &v)
00474 {
00475 int i;
00476
00477 for (i=myNL; i<=myNH; i++)
00478 myVector[i] /= v.myVector[i];
00479 return *this;
00480 }
00481
00482 template <typename T>
00483 UT_VectorT<T> &
00484 UT_VectorT<T>::operator*= (T scalar)
00485 {
00486 int i;
00487
00488 for (i=myNL; i<=myNH; i++)
00489 myVector[i] *= scalar;
00490 return *this;
00491 }
00492
00493
00494 template <typename T>
00495 UT_VectorT<T> &
00496 UT_VectorT<T>::operator/= (T scalar)
00497 {
00498 int i;
00499
00500 scalar = 1.0F / scalar;
00501 for (i=myNL; i<=myNH; i++)
00502 myVector[i] *= scalar;
00503 return *this;
00504 }
00505
00506
00507 template <typename T>
00508 T
00509 UT_VectorT<T>::dot(const UT_VectorT<T> &v) const
00510 {
00511 fpreal64 result;
00512
00513 result = 0;
00514 dotInternal(&result, v);
00515
00516 return result;
00517 }
00518
00519 template <typename T>
00520 void
00521 UT_VectorT<T>::dotInternalPartial(fpreal64 *result, const UT_VectorT<T> &v, const UT_JobInfo &info) const
00522 {
00523 int i, end;
00524 fpreal64 sum = 0.0F;
00525
00526 getPartialRange(i, end, info);
00527
00528 for (; i < end; i++)
00529 sum += (*this)(i) * v(i);
00530
00531
00532 {
00533 UT_AutoJobInfoLock autolock(info);
00534
00535 *result += sum;
00536 }
00537 }
00538
00539 template <typename T>
00540 ostream &
00541 UT_VectorT<T>::save(ostream &os) const
00542 {
00543 int i;
00544
00545 for (i=myNL; i<=myNH; i++)
00546 os << i << ": " << myVector[i] << endl;
00547
00548 return os;
00549 }
00550
00551 template <typename T>
00552 bool
00553 UT_VectorT<T>::isEqual(const UT_VectorT<T> &v, int64 ulps)
00554 {
00555 if (getNL() != v.getNL() || getNH() != v.getNH())
00556 return false;
00557 for (int i = getNL(); i < getNH(); i++)
00558 {
00559 if (!SYSalmostEqual((*this)(i), v(i), ulps))
00560 return false;
00561 }
00562 return true;
00563 }
00564
00565
00566
00567
00568
00569 #if 1
00570
00571 template <>
00572 inline void
00573 UT_VectorT<fpreal32>::negPartial(const UT_JobInfo &info)
00574 {
00575 int i, end;
00576
00577 getPartialRange(i, end, info);
00578
00579 VM_Math::negate(&myVector[i], &myVector[i], end-i);
00580 }
00581
00582 template <>
00583 inline void
00584 UT_VectorT<fpreal32>::negPlusPartial(const UT_VectorT<fpreal32> &v, const UT_JobInfo &info)
00585 {
00586 int i, end;
00587
00588 getPartialRange(i, end, info);
00589
00590 VM_Math::scaleoffset(&myVector[i], -1.0F, &v.myVector[i], end-i);
00591 }
00592
00593 template <>
00594 inline void
00595 UT_VectorT<fpreal32>::addScaledVecPartial(fpreal32 s,
00596 const UT_VectorT<fpreal32> &v,
00597 const UT_JobInfo &info)
00598 {
00599 int i, end;
00600
00601 getPartialRange(i, end, info);
00602
00603 VM_Math::madd(&myVector[i], &v.myVector[i], s, end-i);
00604 }
00605
00606 template <>
00607 inline void
00608 UT_VectorT<fpreal32>::addScaledVecNorm2Partial(fpreal32 s,
00609 const UT_VectorT<fpreal32> &v,
00610 fpreal64 *norm2,
00611 const UT_JobInfo &info)
00612 {
00613 int i, end;
00614 fpreal64 total = 0;
00615
00616 getPartialRange(i, end, info);
00617
00618 total = VM_Math::maddAndNorm(&myVector[i], &v.myVector[i], s, end-i);
00619
00620
00621 {
00622 UT_AutoJobInfoLock autolock(info);
00623
00624 *norm2 += total;
00625 }
00626 }
00627
00628 template <>
00629 inline void
00630 UT_VectorT<fpreal32>::scaleAddVecPartial(fpreal32 s,
00631 const UT_VectorT<fpreal32> &v,
00632 const UT_JobInfo &info)
00633 {
00634 int i, end;
00635
00636 getPartialRange(i, end, info);
00637
00638 VM_Math::scaleoffset(&myVector[i], s, &v.myVector[i], end-i);
00639 }
00640
00641
00642 template <>
00643 inline void
00644 UT_VectorT<fpreal32>::multAndSetPartial(const UT_VectorT<fpreal32> &a,
00645 const UT_VectorT<fpreal32> &b,
00646 const UT_JobInfo &info)
00647 {
00648 int i, end;
00649
00650 getPartialRange(i, end, info);
00651
00652 VM_Math::mul(&myVector[i], &a.myVector[i], &b.myVector[i], end-i);
00653 }
00654
00655 template <>
00656 inline UT_VectorT<fpreal32> &
00657 UT_VectorT<fpreal32>::operator+= (const UT_VectorT<fpreal32> &v)
00658 {
00659 VM_Math::add(&myVector[myNL], &myVector[myNL], &v.myVector[myNL], myNH-myNL+1);
00660 return *this;
00661 }
00662
00663 template <>
00664 inline UT_VectorT<fpreal32> &
00665 UT_VectorT<fpreal32>::operator-= (const UT_VectorT<fpreal32> &v)
00666 {
00667 VM_Math::sub(&myVector[myNL], &myVector[myNL], &v.myVector[myNL], myNH-myNL+1);
00668 return *this;
00669 }
00670
00671 template <>
00672 inline UT_VectorT<fpreal32> &
00673 UT_VectorT<fpreal32>::operator*= (const UT_VectorT<fpreal32> &v)
00674 {
00675 VM_Math::mul(&myVector[myNL], &myVector[myNL], &v.myVector[myNL], myNH-myNL+1);
00676 return *this;
00677 }
00678
00679 template <>
00680 inline UT_VectorT<fpreal32> &
00681 UT_VectorT<fpreal32>::operator/= (const UT_VectorT<fpreal32> &v)
00682 {
00683 VM_Math::div(&myVector[myNL], &myVector[myNL], &v.myVector[myNL], myNH-myNL+1);
00684 return *this;
00685 }
00686
00687 template <>
00688 inline UT_VectorT<fpreal32> &
00689 UT_VectorT<fpreal32>::operator*= (fpreal32 scalar)
00690 {
00691 VM_Math::mul(&myVector[myNL], &myVector[myNL], scalar, myNH-myNL+1);
00692 return *this;
00693 }
00694
00695 template <>
00696 inline UT_VectorT<fpreal32> &
00697 UT_VectorT<fpreal32>::operator/= (fpreal32 scalar)
00698 {
00699 VM_Math::div(&myVector[myNL], &myVector[myNL], scalar, myNH-myNL+1);
00700 return *this;
00701 }
00702
00703 template <>
00704 inline void
00705 UT_VectorT<fpreal32>::dotInternalPartial(fpreal64 *result, const UT_VectorT<fpreal32> &v, const UT_JobInfo &info) const
00706 {
00707 int i, end;
00708 fpreal64 sum = 0.0F;
00709
00710 getPartialRange(i, end, info);
00711
00712 sum = VM_Math::dot(&myVector[i], &v.myVector[i], end-i);
00713
00714
00715 {
00716 UT_AutoJobInfoLock autolock(info);
00717
00718 *result += sum;
00719 }
00720 }
00721
00722 template <>
00723 inline void
00724 UT_VectorT<fpreal32>::normInternalPartial(fpreal64 *output, int type,
00725 const UT_JobInfo &info) const
00726 {
00727 fpreal32 result;
00728 int i, end;
00729
00730 getPartialRange(i, end, info);
00731
00732 if (type == 0)
00733 {
00734 fpreal32 comp;
00735 result = SYSabs(myVector[i]);
00736 for (i++; i < end; i++)
00737 {
00738 comp = SYSabs(myVector[i]);
00739 if (comp > result)
00740 result = comp;
00741 }
00742 }
00743 else if (type == 1)
00744 {
00745 result = 0.0F;
00746 for (; i < end; i++)
00747 result += SYSabs(myVector[i]);
00748 }
00749 else
00750 {
00751 result = VM_Math::dot(&myVector[i], &myVector[i], end-i);
00752 }
00753
00754 {
00755 UT_AutoJobInfoLock autolock(info);
00756
00757 if (type == 0)
00758 {
00759
00760 if (result > *output)
00761 *output = result;
00762 }
00763 else
00764 {
00765
00766 *output += result;
00767 }
00768 }
00769 }
00770 #endif
00771
00772
00773
00774
00775
00776
00777
00778 template <typename T>
00779 UT_PermutationT<T>::UT_PermutationT(int nl, int nh)
00780 {
00781 myNL = nl;
00782 myNH = nh;
00783 myVector = (T *)SYSamalloc((nh - nl + 1)*sizeof(T));
00784 myVector = myVector - nl;
00785 }
00786
00787 template <typename T>
00788 UT_PermutationT<T>::~UT_PermutationT()
00789 {
00790 SYSafree(myVector + myNL);
00791 }
00792
00793 template <typename T>
00794 UT_PermutationT<T>::UT_PermutationT(const UT_PermutationT<T> &p)
00795 {
00796 clone(p);
00797 }
00798
00799 template <typename T>
00800 UT_PermutationT<T> &
00801 UT_PermutationT<T>::operator=(const UT_PermutationT<T> &p)
00802 {
00803 if (&p != this)
00804 {
00805 SYSafree(myVector + myNL);
00806 clone(p);
00807 }
00808 return *this;
00809 }
00810
00811 template <typename T>
00812 void
00813 UT_PermutationT<T>::clone(const UT_PermutationT<T> &p)
00814 {
00815 UT_ASSERT(&p != this);
00816 myNL = p.myNL;
00817 myNH = p.myNH;
00818 myVector = (T *)SYSamalloc((myNH - myNL + 1)*sizeof(T));
00819 myVector = myVector - myNL;
00820
00821 memcpy(myVector + myNL, p.myVector + myNL, (myNH - myNL + 1)*sizeof(T));
00822 }
00823
00824 template <typename T>
00825 void
00826 UT_PermutationT<T>::zero()
00827 {
00828 memset(myVector + myNL, 0, (myNH - myNL + 1)*sizeof(T));
00829 }
00830
00831 template <typename T>
00832 void
00833 UT_PermutationT<T>::changeNL(int nl)
00834 {
00835 int diff = myNL-nl;
00836
00837 myNL = nl;
00838 myNH -= diff;
00839 myVector += diff;
00840 }
00841
00842