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