1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2 /* */ 3 /* This file is part of the class library */ 4 /* SoPlex --- the Sequential object-oriented simPlex. */ 5 /* */ 6 /* Copyright (c) 1996-2023 Zuse Institute Berlin (ZIB) */ 7 /* */ 8 /* Licensed under the Apache License, Version 2.0 (the "License"); */ 9 /* you may not use this file except in compliance with the License. */ 10 /* You may obtain a copy of the License at */ 11 /* */ 12 /* http://www.apache.org/licenses/LICENSE-2.0 */ 13 /* */ 14 /* Unless required by applicable law or agreed to in writing, software */ 15 /* distributed under the License is distributed on an "AS IS" BASIS, */ 16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ 17 /* See the License for the specific language governing permissions and */ 18 /* limitations under the License. */ 19 /* */ 20 /* You should have received a copy of the Apache-2.0 license */ 21 /* along with SoPlex; see the file LICENSE. If not email to soplex@zib.de. */ 22 /* */ 23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 24 25 /**@file ssvectorbase.h 26 * @brief Semi sparse vector. 27 */ 28 #ifndef _SSVECTORBASE_H_ 29 #define _SSVECTORBASE_H_ 30 31 #include <assert.h> 32 33 #include "soplex/spxdefines.h" 34 #include "soplex/vectorbase.h" 35 #include "soplex/idxset.h" 36 #include "soplex/spxalloc.h" 37 #include "soplex/timer.h" 38 #include "soplex/stablesum.h" 39 40 namespace soplex 41 { 42 template < class R > class SVectorBase; 43 template < class R > class SVSetBase; 44 45 /**@brief Semi sparse vector. 46 * @ingroup Algebra 47 * 48 * This class implements semi-sparse vectors. Such are #VectorBase%s where the indices of its nonzero elements can be 49 * stored in an extra IdxSet. Only elements with absolute value > #epsilon are considered to be nonzero. Since really 50 * storing the nonzeros is not always convenient, an SSVectorBase provides two different stati: setup and not setup. 51 * An SSVectorBase being setup means that the nonzero indices are available, otherwise an SSVectorBase is just an 52 * ordinary VectorBase with an empty IdxSet. Note that due to arithmetic operation, zeros can slip in, i.e., it is 53 * only guaranteed that at least every non-zero is in the IdxSet. 54 */ 55 template < class R > 56 class SSVectorBase : public VectorBase<R>, protected IdxSet 57 { 58 private: 59 60 friend class VectorBase<R>; 61 template < class S > friend class DSVectorBase; 62 63 // ------------------------------------------------------------------------------------------------------------------ 64 /**@name Data */ 65 ///@{ 66 67 /// Is the SSVectorBase set up? 68 bool setupStatus; 69 70 /// Allocates enough space to accommodate \p newmax values. 71 void setMax(int newmax) 72 { 73 assert(idx != 0); 74 assert(newmax != 0); 75 assert(newmax >= IdxSet::size()); 76 77 len = newmax; 78 spx_realloc(idx, len); 79 } 80 81 ///@} 82 83 protected: 84 std::shared_ptr<Tolerances> _tolerances; 85 86 public: 87 88 // ------------------------------------------------------------------------------------------------------------------ 89 /**@name Status of an SSVectorBase 90 * 91 * An SSVectorBase can be set up or not. In case it is set up, its IdxSet correctly contains all indices of nonzero 92 * elements of the SSVectorBase. Otherwise, it does not contain any useful data. Whether or not an SSVectorBase is 93 * setup can be determined with the method \ref soplex::SSVectorBase::isSetup() "isSetup()". 94 * 95 * There are three methods for directly affecting the setup status of an SSVectorBase: 96 * 97 * - unSetup(): This method sets the status to ``not setup''. 98 * 99 * - setup(): This method initializes the IdxSet to the SSVectorBase's nonzero indices and sets the status to 100 * ``setup''. 101 * 102 * - forceSetup(): This method sets the status to ``setup'' without verifying that the IdxSet correctly contains all 103 * nonzero indices. It may be used when the nonzero indices have been computed externally. 104 */ 105 ///@{ 106 107 /// Only used in slufactor.hpp. 108 R* get_ptr() 109 { 110 return VectorBase<R>::get_ptr(); 111 } 112 113 /// set the _tolerances member variable 114 virtual void setTolerances(std::shared_ptr<Tolerances> newTolerances) 115 { 116 this->_tolerances = newTolerances; 117 } 118 119 /// returns current tolerances 120 const std::shared_ptr<Tolerances>& tolerances() const 121 { 122 assert(this->_tolerances != nullptr); 123 return this->_tolerances; 124 } 125 126 /// Returns setup status. 127 bool isSetup() const 128 { 129 return setupStatus; 130 } 131 132 R getEpsilon() const 133 { 134 assert(this->_tolerances != nullptr); 135 return this->_tolerances == nullptr ? R(0) : R(this->tolerances()->epsilon()); 136 } 137 138 /// Makes SSVectorBase not setup. 139 void unSetup() 140 { 141 setupStatus = false; 142 } 143 144 /// Initializes nonzero indices for elements with absolute values above #epsilon and sets all other elements to 0. 145 void setup() 146 { 147 if(!isSetup()) 148 { 149 IdxSet::clear(); 150 151 int d = dim(); 152 num = 0; 153 154 for(int i = 0; i < d; ++i) 155 { 156 if(VectorBase<R>::val[i] != R(0)) 157 { 158 if(spxAbs(VectorBase<R>::val[i]) <= this->getEpsilon()) 159 VectorBase<R>::val[i] = R(0); 160 else 161 { 162 idx[num] = i; 163 num++; 164 } 165 } 166 } 167 168 setupStatus = true; 169 170 assert(isConsistent()); 171 } 172 } 173 174 /// Forces setup status. 175 void forceSetup() 176 { 177 setupStatus = true; 178 } 179 180 ///@} 181 182 // ------------------------------------------------------------------------------------------------------------------ 183 /**@name Methods for setup SSVectorBases */ 184 ///@{ 185 186 /// Returns index of the \p n 'th nonzero element. 187 int index(int n) const 188 { 189 assert(isSetup()); 190 191 return IdxSet::index(n); 192 } 193 194 /// Returns value of the \p n 'th nonzero element. 195 R value(int n) const 196 { 197 assert(isSetup()); 198 assert(n >= 0 && n < size()); 199 200 return VectorBase<R>::val[idx[n]]; 201 } 202 203 /// Finds the position of index \p i in the #IdxSet, or -1 if \p i doesn't exist. 204 int pos(int i) const 205 { 206 assert(isSetup()); 207 208 return IdxSet::pos(i); 209 } 210 211 /// Returns the number of nonzeros. 212 int size() const 213 { 214 assert(isSetup()); 215 216 return IdxSet::size(); 217 } 218 219 /// Adds nonzero (\p i, \p x) to SSVectorBase. 220 /** No nonzero with index \p i must exist in the SSVectorBase. */ 221 void add(int i, R x) 222 { 223 assert(VectorBase<R>::val[i] == R(0)); 224 assert(pos(i) < 0); 225 226 addIdx(i); 227 VectorBase<R>::val[i] = x; 228 } 229 230 /// Sets \p i 'th element to \p x. 231 void setValue(int i, R x) 232 { 233 assert(i >= 0); 234 assert(i < VectorBase<R>::dim()); 235 236 if(isSetup()) 237 { 238 int n = pos(i); 239 240 if(n < 0) 241 { 242 if(spxAbs(x) > this->getEpsilon()) 243 IdxSet::add(1, &i); 244 } 245 else if(x == R(0)) 246 clearNum(n); 247 } 248 249 VectorBase<R>::val[i] = x; 250 251 assert(isConsistent()); 252 } 253 254 /// Scale \p i 'th element by a 255 void scaleValue(int i, int scaleExp) 256 { 257 assert(i >= 0); 258 assert(i < VectorBase<R>::dim()); 259 260 VectorBase<R>::val[i] = spxLdexp(VectorBase<R>::val[i], scaleExp); 261 262 assert(isConsistent()); 263 } 264 265 /// Clears element \p i. 266 void clearIdx(int i) 267 { 268 if(isSetup()) 269 { 270 int n = pos(i); 271 272 if(n >= 0) 273 remove(n); 274 } 275 276 VectorBase<R>::val[i] = 0; 277 278 assert(isConsistent()); 279 } 280 281 /// Sets \p n 'th nonzero element to 0 (index \p n must exist). 282 void clearNum(int n) 283 { 284 assert(isSetup()); 285 assert(index(n) >= 0); 286 287 VectorBase<R>::val[index(n)] = 0; 288 remove(n); 289 290 assert(isConsistent()); 291 } 292 293 ///@} 294 295 // ------------------------------------------------------------------------------------------------------------------ 296 /**@name Methods independent of the Status */ 297 ///@{ 298 299 /// Returns \p i 'th value. 300 R operator[](int i) const 301 { 302 return VectorBase<R>::val[i]; 303 } 304 305 /// Returns array indices. 306 const int* indexMem() const 307 { 308 return idx; 309 } 310 311 /// Returns array values. 312 const R* values() const 313 { 314 return VectorBase<R>::val.data(); 315 } 316 317 /// Returns indices. 318 const IdxSet& indices() const 319 { 320 return *this; 321 } 322 323 /// Returns array indices. 324 int* altIndexMem() 325 { 326 unSetup(); 327 return idx; 328 } 329 330 /// Returns array values. 331 R* altValues() 332 { 333 unSetup(); 334 return VectorBase<R>::val.data(); 335 } 336 337 /// Returns indices. 338 IdxSet& altIndices() 339 { 340 unSetup(); 341 return *this; 342 } 343 344 ///@} 345 346 // ------------------------------------------------------------------------------------------------------------------ 347 /**@name Arithmetic operations */ 348 ///@{ 349 350 /// Addition. 351 template < class S > 352 SSVectorBase<R>& operator+=(const VectorBase<S>& vec) 353 { 354 VectorBase<S>::operator+=(vec); 355 356 if(isSetup()) 357 { 358 setupStatus = false; 359 setup(); 360 } 361 362 return *this; 363 } 364 365 /// Addition. 366 template < class S > 367 SSVectorBase<R>& operator+=(const SVectorBase<S>& vec); 368 369 /// Addition. 370 template < class S > 371 SSVectorBase<R>& operator+=(const SSVectorBase<S>& vec) 372 { 373 assert(vec.isSetup()); 374 375 for(int i = vec.size() - 1; i >= 0; --i) 376 VectorBase<R>::val[vec.index(i)] += vec.value(i); 377 378 if(isSetup()) 379 { 380 setupStatus = false; 381 setup(); 382 } 383 384 return *this; 385 } 386 387 /// Subtraction. 388 template < class S > 389 SSVectorBase<R>& operator-=(const VectorBase<S>& vec) 390 { 391 VectorBase<R>::operator-=(vec); 392 393 if(isSetup()) 394 { 395 setupStatus = false; 396 setup(); 397 } 398 399 return *this; 400 } 401 402 /// Subtraction. 403 template < class S > 404 SSVectorBase<R>& operator-=(const SVectorBase<S>& vec); 405 406 /// Subtraction. 407 template < class S > 408 SSVectorBase<R>& operator-=(const SSVectorBase<S>& vec) 409 { 410 if(vec.isSetup()) 411 { 412 for(int i = vec.size() - 1; i >= 0; --i) 413 VectorBase<R>::val[vec.index(i)] -= vec.value(i); 414 } 415 else 416 VectorBase<R>::operator-=(VectorBase<S>(vec)); 417 418 if(isSetup()) 419 { 420 setupStatus = false; 421 setup(); 422 } 423 424 return *this; 425 } 426 427 /// Scaling. 428 template < class S > 429 SSVectorBase<R>& operator*=(S x) 430 { 431 assert(isSetup()); 432 assert(x != S(0)); 433 434 for(int i = size() - 1; i >= 0; --i) 435 VectorBase<R>::val[index(i)] *= x; 436 437 assert(isConsistent()); 438 439 return *this; 440 } 441 442 // Inner product. 443 template < class S > 444 R operator*(const SSVectorBase<S>& w) 445 { 446 setup(); 447 448 StableSum<R> x; 449 int i = size() - 1; 450 int j = w.size() - 1; 451 452 // both *this and w non-zero vectors? 453 if(i >= 0 && j >= 0) 454 { 455 int vi = index(i); 456 int wj = w.index(j); 457 458 while(i != 0 && j != 0) 459 { 460 if(vi == wj) 461 { 462 x += VectorBase<R>::val[vi] * R(w.val[wj]); 463 vi = index(--i); 464 wj = w.index(--j); 465 } 466 else if(vi > wj) 467 vi = index(--i); 468 else 469 wj = w.index(--j); 470 } 471 472 /* check remaining indices */ 473 474 while(i != 0 && vi != wj) 475 vi = index(--i); 476 477 while(j != 0 && vi != wj) 478 wj = w.index(--j); 479 480 if(vi == wj) 481 x += VectorBase<R>::val[vi] * R(w.val[wj]); 482 } 483 484 return x; 485 } 486 487 /// Addition of a scaled vector. 488 ///@todo SSVectorBase::multAdd() should be rewritten without pointer arithmetic. 489 template < class S, class T > 490 SSVectorBase<R>& multAdd(S xx, const SVectorBase<T>& vec); 491 492 /// Addition of a scaled vector. 493 template < class S, class T > 494 SSVectorBase<R>& multAdd(S x, const VectorBase<T>& vec) 495 { 496 VectorBase<R>::multAdd(x, vec); 497 498 if(isSetup()) 499 { 500 setupStatus = false; 501 setup(); 502 } 503 504 return *this; 505 } 506 507 /// Assigns pair wise vector product to SSVectorBase. 508 template < class S, class T > 509 SSVectorBase<R>& assignPWproduct4setup(const SSVectorBase<S>& x, const SSVectorBase<T>& y); 510 511 /// Assigns \f$x^T \cdot A\f$ to SSVectorBase. 512 template < class S, class T > 513 SSVectorBase<R>& assign2product(const SSVectorBase<S>& x, const SVSetBase<T>& A); 514 515 /// Assigns SSVectorBase to \f$A \cdot x\f$ for a setup \p x. 516 template < class S, class T > 517 SSVectorBase<R>& assign2product4setup(const SVSetBase<S>& A, const SSVectorBase<T>& x, 518 Timer* timeSparse, Timer* timeFull, int& nCallsSparse, int& nCallsFull); 519 520 public: 521 522 /// Assigns SSVectorBase to \f$A \cdot x\f$ thereby setting up \p x. 523 template < class S, class T > 524 SSVectorBase<R>& assign2productAndSetup(const SVSetBase<S>& A, SSVectorBase<T>& x); 525 526 /// Maximum absolute value, i.e., infinity norm. 527 R maxAbs() const 528 { 529 if(isSetup()) 530 { 531 R maxabs = 0; 532 533 for(int i = 0; i < num; ++i) 534 { 535 R x = spxAbs(VectorBase<R>::val[idx[i]]); 536 537 if(x > maxabs) 538 maxabs = x; 539 } 540 541 return maxabs; 542 } 543 else 544 return VectorBase<R>::maxAbs(); 545 } 546 547 /// Squared euclidian norm. 548 R length2() const 549 { 550 R x = 0; 551 552 if(isSetup()) 553 { 554 for(int i = 0; i < num; ++i) 555 x += VectorBase<R>::val[idx[i]] * VectorBase<R>::val[idx[i]]; 556 } 557 else 558 x = VectorBase<R>::length2(); 559 560 return x; 561 } 562 563 /// Floating point approximation of euclidian norm (without any approximation guarantee). 564 R length() const 565 { 566 return spxSqrt(R(length2())); 567 } 568 569 ///@} 570 571 // ------------------------------------------------------------------------------------------------------------------ 572 /**@name Miscellaneous */ 573 ///@{ 574 575 /// Dimension of VectorBase. 576 int dim() const 577 { 578 return VectorBase<R>::dim(); 579 } 580 581 /// Resets dimension to \p newdim. 582 void reDim(int newdim) 583 { 584 for(int i = IdxSet::size() - 1; i >= 0; --i) 585 { 586 if(index(i) >= newdim) 587 remove(i); 588 } 589 590 VectorBase<R>::reDim(newdim); 591 setMax(VectorBase<R>::memSize() + 1); 592 593 assert(isConsistent()); 594 } 595 596 /// Sets number of nonzeros (thereby unSetup SSVectorBase). 597 void setSize(int n) 598 { 599 assert(n >= 0); 600 assert(n <= IdxSet::max()); 601 602 unSetup(); 603 num = n; 604 } 605 606 /// Resets memory consumption to \p newsize. 607 void reMem(int newsize) 608 { 609 VectorBase<R>::reSize(newsize); 610 assert(isConsistent()); 611 612 setMax(VectorBase<R>::memSize() + 1); 613 } 614 615 /// Clears vector. 616 void clear() 617 { 618 if(isSetup()) 619 { 620 for(int i = 0; i < num; ++i) 621 VectorBase<R>::val[idx[i]] = 0; 622 } 623 else 624 VectorBase<R>::clear(); 625 626 IdxSet::clear(); 627 setupStatus = true; 628 629 assert(isConsistent()); 630 } 631 632 /// consistency check. 633 bool isConsistent() const 634 { 635 #ifdef ENABLE_CONSISTENCY_CHECKS 636 637 if(VectorBase<R>::dim() > IdxSet::max()) 638 return SPX_MSG_INCONSISTENT("SSVectorBase"); 639 640 if(VectorBase<R>::dim() < IdxSet::dim()) 641 return SPX_MSG_INCONSISTENT("SSVectorBase"); 642 643 if(isSetup()) 644 { 645 for(int i = 0; i < VectorBase<R>::dim(); ++i) 646 { 647 int j = pos(i); 648 649 if(j < 0 && spxAbs(VectorBase<R>::val[i]) > 0) 650 { 651 SPX_MSG_ERROR(std::cerr << "ESSVEC01 i = " << i 652 << "\tidx = " << j 653 << "\tval = " << std::setprecision(16) << VectorBase<R>::val[i] 654 << std::endl;) 655 656 return SPX_MSG_INCONSISTENT("SSVectorBase"); 657 } 658 } 659 } 660 661 return VectorBase<R>::isConsistent() && IdxSet::isConsistent(); 662 #else 663 return true; 664 #endif 665 } 666 667 ///@} 668 669 // ------------------------------------------------------------------------------------------------------------------ 670 /**@name Constructors / Destructors */ 671 ///@{ 672 673 /// Default constructor. 674 explicit SSVectorBase<R>(int p_dim, std::shared_ptr<Tolerances> tol = nullptr) 675 : VectorBase<R>(p_dim) 676 , IdxSet() 677 , setupStatus(true) 678 { 679 len = (p_dim < 1) ? 1 : p_dim; 680 spx_alloc(idx, len); 681 VectorBase<R>::clear(); 682 _tolerances = tol; 683 684 assert(isConsistent()); 685 } 686 687 /// Copy constructor. 688 template < class S > 689 SSVectorBase(const SSVectorBase<S>& vec) 690 : VectorBase<R>(vec) 691 , IdxSet() 692 , setupStatus(vec.setupStatus) 693 { 694 len = (vec.dim() < 1) ? 1 : vec.dim(); 695 spx_alloc(idx, len); 696 IdxSet::operator=(vec); 697 _tolerances = vec._tolerances; 698 699 assert(isConsistent()); 700 } 701 702 /// Copy constructor. 703 /** The redundancy with the copy constructor below is necessary since otherwise the compiler doesn't realize that it 704 * could use the more general one with S = R and generates a shallow copy constructor. 705 */ 706 SSVectorBase(const SSVectorBase<R>& vec) 707 : VectorBase<R>(vec) 708 , IdxSet() 709 , setupStatus(vec.setupStatus) 710 { 711 len = (vec.dim() < 1) ? 1 : vec.dim(); 712 spx_alloc(idx, len); 713 IdxSet::operator=(vec); 714 _tolerances = vec._tolerances; 715 716 assert(isConsistent()); 717 } 718 719 /// Constructs nonsetup copy of \p vec. 720 template < class S > 721 explicit SSVectorBase<R>(const VectorBase<S>& vec) 722 : VectorBase<R>(vec) 723 , IdxSet() 724 , setupStatus(false) 725 { 726 len = (vec.dim() < 1) ? 1 : vec.dim(); 727 spx_alloc(idx, len); 728 729 assert(isConsistent()); 730 } 731 732 /// Sets up \p rhs vector, and assigns it. 733 template < class S > 734 void setup_and_assign(SSVectorBase<S>& rhs) 735 { 736 clear(); 737 setMax(rhs.max()); 738 VectorBase<R>::reDim(rhs.dim()); 739 _tolerances = rhs.tolerances(); 740 741 if(rhs.isSetup()) 742 { 743 IdxSet::operator=(rhs); 744 745 for(int i = size() - 1; i >= 0; --i) 746 { 747 int j = index(i); 748 VectorBase<R>::val[j] = rhs.val[j]; 749 } 750 } 751 else 752 { 753 int d = rhs.dim(); 754 num = 0; 755 756 for(int i = 0; i < d; ++i) 757 { 758 if(rhs.val[i] != 0) 759 { 760 if(spxAbs(rhs.val[i]) > this->getEpsilon()) 761 { 762 rhs.idx[num] = i; 763 idx[num] = i; 764 VectorBase<R>::val[i] = rhs.val[i]; 765 num++; 766 } 767 else 768 rhs.val[i] = 0; 769 } 770 } 771 772 rhs.num = num; 773 rhs.setupStatus = true; 774 } 775 776 setupStatus = true; 777 778 assert(rhs.isConsistent()); 779 assert(isConsistent()); 780 } 781 782 /// Assigns only the elements of \p rhs. 783 template < class S > 784 SSVectorBase<R>& assign(const SVectorBase<S>& rhs); 785 786 /// Assignment operator. 787 template < class S > 788 SSVectorBase<R>& operator=(const SSVectorBase<S>& rhs) 789 { 790 assert(rhs.isConsistent()); 791 792 if(this != &rhs) 793 { 794 clear(); 795 _tolerances = rhs._tolerances; 796 setMax(rhs.max()); 797 VectorBase<R>::reDim(rhs.dim()); 798 799 if(rhs.isSetup()) 800 { 801 IdxSet::operator=(rhs); 802 803 for(int i = size() - 1; i >= 0; --i) 804 { 805 int j = index(i); 806 VectorBase<R>::val[j] = rhs.val[j]; 807 } 808 } 809 else 810 { 811 int d = rhs.dim(); 812 num = 0; 813 814 for(int i = 0; i < d; ++i) 815 { 816 if(spxAbs(rhs.val[i]) > this->getEpsilon()) 817 { 818 VectorBase<R>::val[i] = rhs.val[i]; 819 idx[num] = i; 820 num++; 821 } 822 } 823 } 824 825 setupStatus = true; 826 } 827 828 assert(isConsistent()); 829 830 return *this; 831 } 832 833 /// Assignment operator. 834 SSVectorBase<R>& operator=(const SSVectorBase<R>& rhs) 835 { 836 assert(rhs.isConsistent()); 837 838 if(this != &rhs) 839 { 840 clear(); 841 _tolerances = rhs._tolerances; 842 setMax(rhs.max()); 843 VectorBase<R>::reDim(rhs.dim()); 844 845 if(rhs.isSetup()) 846 { 847 IdxSet::operator=(rhs); 848 849 for(int i = size() - 1; i >= 0; --i) 850 { 851 int j = index(i); 852 VectorBase<R>::val[j] = rhs.val[j]; 853 } 854 } 855 else 856 { 857 num = 0; 858 859 for(int i = 0; i < rhs.dim(); ++i) 860 { 861 if(spxAbs(rhs.val[i]) > this->getEpsilon()) 862 { 863 VectorBase<R>::val[i] = rhs.val[i]; 864 idx[num] = i; 865 num++; 866 } 867 } 868 } 869 870 setupStatus = true; 871 } 872 873 assert(isConsistent()); 874 875 return *this; 876 } 877 878 /// Assignment operator. 879 template < class S > 880 SSVectorBase<R>& operator=(const SVectorBase<S>& rhs); 881 882 /// Assignment operator. 883 template < class S > 884 SSVectorBase<R>& operator=(const VectorBase<S>& rhs) 885 { 886 unSetup(); 887 VectorBase<R>::operator=(rhs); 888 889 assert(isConsistent()); 890 891 return *this; 892 } 893 894 /// destructor 895 ~SSVectorBase() 896 { 897 if(idx) 898 spx_free(idx); 899 } 900 901 ///@} 902 903 private: 904 905 // ------------------------------------------------------------------------------------------------------------------ 906 /**@name Private helpers */ 907 ///@{ 908 909 /// Assignment helper. 910 template < class S, class T > 911 SSVectorBase<R>& assign2product1(const SVSetBase<S>& A, const SSVectorBase<T>& x); 912 913 /// Assignment helper. 914 template < class S, class T > 915 SSVectorBase<R>& assign2productShort(const SVSetBase<S>& A, const SSVectorBase<T>& x); 916 917 /// Assignment helper. 918 template < class S, class T > 919 SSVectorBase<R>& assign2productFull(const SVSetBase<S>& A, const SSVectorBase<T>& x); 920 921 ///@} 922 }; 923 924 } // namespace soplex 925 #endif // _SSVECTORBASE_H_ 926