1 // Copyright (C) 2004, 2007 International Business Machines and others. 2 // All Rights Reserved. 3 // This code is published under the Eclipse Public License. 4 // 5 // Authors: Carl Laird, Andreas Waechter IBM 2005-06-18 6 7 #ifndef __IPREGOPTIONS_HPP__ 8 #define __IPREGOPTIONS_HPP__ 9 10 #include "IpUtils.hpp" 11 #include "IpReferenced.hpp" 12 #include "IpException.hpp" 13 #include "IpSmartPtr.hpp" 14 15 #include <map> 16 17 namespace Ipopt 18 { 19 20 enum RegisteredOptionType 21 { 22 OT_Number, 23 OT_Integer, 24 OT_String, 25 OT_Unknown 26 }; 27 28 /** Base class for registered options. 29 * 30 * The derived types are more 31 * specific to a string option or a Number (real) option, etc. 32 */ 33 class IPOPTLIB_EXPORT RegisteredOption: public ReferencedObject 34 { 35 public: 36 /** class to hold the valid string settings for a string option */ 37 class string_entry 38 { 39 public: string_entry(const std::string & value,const std::string & description)40 string_entry( 41 const std::string& value, 42 const std::string& description 43 ) 44 : value_(value), 45 description_(description) 46 { } 47 48 std::string value_; 49 std::string description_; 50 }; 51 52 /** Constructors / Destructors */ 53 //@{ RegisteredOption(Index counter)54 RegisteredOption( 55 Index counter 56 ) 57 : type_(OT_Unknown), 58 has_lower_(false), 59 has_upper_(false), 60 counter_(counter) 61 { 62 } 63 RegisteredOption(const std::string & name,const std::string & short_description,const std::string & long_description,const std::string & registering_category,Index counter)64 RegisteredOption( 65 const std::string& name, 66 const std::string& short_description, 67 const std::string& long_description, 68 const std::string& registering_category, 69 Index counter 70 ) 71 : name_(name), 72 short_description_(short_description), 73 long_description_(long_description), 74 registering_category_(registering_category), 75 type_(OT_Unknown), 76 has_lower_(false), 77 has_upper_(false), 78 counter_(counter) 79 { 80 } 81 RegisteredOption(const RegisteredOption & copy)82 RegisteredOption( 83 const RegisteredOption& copy 84 ) 85 : name_(copy.name_), 86 short_description_(copy.short_description_), 87 long_description_(copy.long_description_), 88 registering_category_(copy.registering_category_), 89 type_(copy.type_), 90 has_lower_(copy.has_lower_), 91 lower_(copy.lower_), 92 has_upper_(copy.has_upper_), 93 upper_(copy.upper_), 94 valid_strings_(copy.valid_strings_), 95 counter_(copy.counter_) 96 { 97 } 98 ~RegisteredOption()99 virtual ~RegisteredOption() 100 { } 101 //@} 102 103 DECLARE_STD_EXCEPTION(ERROR_CONVERTING_STRING_TO_ENUM) 104 ; 105 106 /** Standard Get / Set Methods */ 107 //@{ 108 /** Get the option's name (tag in the input file) */ Name() const109 virtual const std::string& Name() const 110 { 111 return name_; 112 } 113 /** Set the option's name (tag in the input file) */ SetName(const std::string & name)114 virtual void SetName( 115 const std::string& name 116 ) 117 { 118 name_ = name; 119 } 120 /** Get the short description */ ShortDescription() const121 virtual const std::string& ShortDescription() const 122 { 123 return short_description_; 124 } 125 126 /** Get the long description */ LongDescription() const127 virtual const std::string& LongDescription() const 128 { 129 return long_description_; 130 } 131 132 /** Set the short description */ SetShortDescription(const std::string & short_description)133 virtual void SetShortDescription( 134 const std::string& short_description 135 ) 136 { 137 short_description_ = short_description; 138 } 139 140 /** Set the long description */ SetLongDescription(const std::string & long_description)141 virtual void SetLongDescription( 142 const std::string& long_description 143 ) 144 { 145 long_description_ = long_description; 146 } 147 148 /** Get the registering class */ RegisteringCategory() const149 virtual const std::string& RegisteringCategory() const 150 { 151 return registering_category_; 152 } 153 154 /** Set the registering class */ SetRegisteringCategory(const std::string & registering_category)155 virtual void SetRegisteringCategory( 156 const std::string& registering_category 157 ) 158 { 159 registering_category_ = registering_category; 160 } 161 162 /** Get the Option's type */ Type() const163 virtual const RegisteredOptionType& Type() const 164 { 165 return type_; 166 167 } 168 /** Get the Option's type */ SetType(const RegisteredOptionType & type)169 virtual void SetType( 170 const RegisteredOptionType& type 171 ) 172 { 173 type_ = type; 174 } 175 176 /** Counter */ Counter() const177 virtual Index Counter() const 178 { 179 return counter_; 180 } 181 //@} 182 183 /** @name Get / Set methods valid for specific types 184 * 185 * @note The Type must be set before calling these methods. 186 */ 187 //@{ 188 /** check if the option has a lower bound 189 * 190 * can be called for OT_Number & OT_Integer 191 */ HasLower() const192 virtual const bool& HasLower() const 193 { 194 DBG_ASSERT(type_ == OT_Number || type_ == OT_Integer); 195 return has_lower_; 196 } 197 198 /** check if the lower bound is strict 199 * 200 * can be called for OT_Number 201 */ LowerStrict() const202 virtual const bool& LowerStrict() const 203 { 204 DBG_ASSERT(type_ == OT_Number && has_lower_ == true); 205 return lower_strict_; 206 } 207 208 /** get the Number version of the lower bound 209 * 210 * can be called for OT_Number 211 */ LowerNumber() const212 virtual Number LowerNumber() const 213 { 214 DBG_ASSERT(has_lower_ == true && type_ == OT_Number); 215 return lower_; 216 } 217 218 /** set the Number version of the lower bound 219 * 220 * can be called for OT_Number 221 */ SetLowerNumber(const Number & lower,const bool & strict)222 virtual void SetLowerNumber( 223 const Number& lower, 224 const bool& strict 225 ) 226 { 227 DBG_ASSERT(type_ == OT_Number); 228 lower_ = lower; 229 lower_strict_ = strict, has_lower_ = true; 230 } 231 232 /** get the Integer version of the lower bound 233 * 234 * can be called for OT_Integer 235 */ LowerInteger() const236 virtual Index LowerInteger() const 237 { 238 DBG_ASSERT(has_lower_ == true && type_ == OT_Integer); 239 return (Index) lower_; 240 } 241 242 /** set the Integer version of the lower bound 243 * 244 * can be called for OT_Integer 245 */ SetLowerInteger(const Index & lower)246 virtual void SetLowerInteger( 247 const Index& lower 248 ) 249 { 250 DBG_ASSERT(type_ == OT_Integer); 251 lower_ = (Number) lower; 252 has_lower_ = true; 253 } 254 255 /** check if the option has an upper bound 256 * 257 * can be called for OT_Number & OT_Integer 258 */ HasUpper() const259 virtual const bool& HasUpper() const 260 { 261 DBG_ASSERT(type_ == OT_Number || type_ == OT_Integer); 262 return has_upper_; 263 } 264 265 /** check if the upper bound is strict 266 * 267 * can be called for OT_Number 268 */ UpperStrict() const269 virtual const bool& UpperStrict() const 270 { 271 DBG_ASSERT(type_ == OT_Number && has_upper_ == true); 272 return upper_strict_; 273 } 274 275 /** get the Number version of the upper bound 276 * 277 * can be called for OT_Number 278 */ UpperNumber() const279 virtual Number UpperNumber() const 280 { 281 DBG_ASSERT(has_upper_ == true && type_ == OT_Number); 282 return upper_; 283 } 284 285 /** set the Number version of the upper bound 286 * 287 * can be called for OT_Number 288 */ SetUpperNumber(const Number & upper,const bool & strict)289 virtual void SetUpperNumber( 290 const Number& upper, 291 const bool& strict 292 ) 293 { 294 DBG_ASSERT(type_ == OT_Number); 295 upper_ = upper; 296 upper_strict_ = strict; 297 has_upper_ = true; 298 } 299 300 /** get the Integer version of the upper bound 301 * 302 * can be called for OT_Integer 303 */ UpperInteger() const304 virtual Index UpperInteger() const 305 { 306 DBG_ASSERT(has_upper_ == true && type_ == OT_Integer); 307 return (Index) upper_; 308 } 309 310 /** set the Integer version of the upper bound 311 * 312 * can be called for OT_Integer 313 */ SetUpperInteger(const Index & upper)314 virtual void SetUpperInteger( 315 const Index& upper 316 ) 317 { 318 DBG_ASSERT(type_ == OT_Integer); 319 upper_ = (Number) upper; 320 has_upper_ = true; 321 } 322 323 /** method to add valid string entries 324 * 325 * can be called for OT_String 326 */ AddValidStringSetting(const std::string value,const std::string description)327 virtual void AddValidStringSetting( 328 const std::string value, 329 const std::string description) 330 { 331 DBG_ASSERT(type_ == OT_String); 332 valid_strings_.push_back(string_entry(value, description)); 333 } 334 335 /** get the default as a Number 336 * 337 * can be called for OT_Number 338 */ DefaultNumber() const339 virtual Number DefaultNumber() const 340 { 341 DBG_ASSERT(type_ == OT_Number); 342 return default_number_; 343 } 344 345 /** Set the default as a Number 346 * 347 * can be called for OT_Number 348 */ SetDefaultNumber(const Number & default_value)349 virtual void SetDefaultNumber( 350 const Number& default_value 351 ) 352 { 353 DBG_ASSERT(type_ == OT_Number); 354 default_number_ = default_value; 355 } 356 357 /** get the default as an Integer 358 * 359 * can be called for OT_Integer 360 */ DefaultInteger() const361 virtual Index DefaultInteger() const 362 { 363 DBG_ASSERT(type_ == OT_Integer); 364 return (Index) default_number_; 365 } 366 367 /** Set the default as an Integer 368 * 369 * can be called for OT_Integer 370 */ SetDefaultInteger(const Index & default_value)371 virtual void SetDefaultInteger( 372 const Index& default_value 373 ) 374 { 375 DBG_ASSERT(type_ == OT_Integer); 376 default_number_ = (Number) default_value; 377 } 378 379 /** get the default as a string 380 * 381 * can be called for OT_String 382 */ DefaultString() const383 virtual std::string DefaultString() const 384 { 385 DBG_ASSERT(type_ == OT_String); 386 return default_string_; 387 } 388 389 /** get the default as a string, but as the index of the string in the list 390 * 391 * helps map from a string to an enum 392 * 393 * can be called for OT_String 394 */ DefaultStringAsEnum() const395 virtual Index DefaultStringAsEnum() const 396 { 397 DBG_ASSERT(type_ == OT_String); 398 return MapStringSettingToEnum(default_string_); 399 } 400 401 /** Set the default as a string 402 * 403 * can be called for OT_String 404 */ SetDefaultString(const std::string & default_value)405 virtual void SetDefaultString( 406 const std::string& default_value 407 ) 408 { 409 DBG_ASSERT(type_ == OT_String); 410 default_string_ = default_value; 411 } 412 413 /** get the valid string settings 414 * 415 * can be called for OT_String 416 */ GetValidStrings() const417 virtual std::vector<string_entry> GetValidStrings() const 418 { 419 DBG_ASSERT(type_ == OT_String); 420 return valid_strings_; 421 } 422 423 /** Check if the Number value is a valid setting 424 * 425 * can be called for OT_Number 426 * */ IsValidNumberSetting(const Number & value) const427 virtual bool IsValidNumberSetting( 428 const Number& value 429 ) const 430 { 431 DBG_ASSERT(type_ == OT_Number); 432 if( has_lower_ && ((lower_strict_ == true && value <= lower_) || (lower_strict_ == false && value < lower_)) ) 433 { 434 return false; 435 } 436 if( has_upper_ && ((upper_strict_ == true && value >= upper_) || (upper_strict_ == false && value > upper_)) ) 437 { 438 return false; 439 } 440 return true; 441 } 442 443 /** Check if the Integer value is a valid setting 444 * 445 * can be called for OT_Integer 446 */ IsValidIntegerSetting(const Index & value) const447 virtual bool IsValidIntegerSetting( 448 const Index& value 449 ) const 450 { 451 DBG_ASSERT(type_ == OT_Integer); 452 if( has_lower_ && value < lower_ ) 453 { 454 return false; 455 } 456 if( has_upper_ && value > upper_ ) 457 { 458 return false; 459 } 460 return true; 461 } 462 463 /** Check if the String value is a valid setting 464 * 465 * can be called for OT_String 466 */ 467 virtual bool IsValidStringSetting( 468 const std::string& value 469 ) const; 470 471 /** Map a user setting (allowing any case) to the case used when 472 * the setting was registered. 473 */ 474 virtual std::string MapStringSetting( 475 const std::string& value 476 ) const; 477 478 /** Map a user setting (allowing any case) to the index of the 479 * matched setting in the list of string settings. 480 * 481 * Helps map a string setting to an enumeration. 482 */ 483 virtual Index MapStringSettingToEnum( 484 const std::string& value 485 ) const; 486 //@} 487 488 /** output a description of the option */ 489 virtual void OutputDescription( 490 const Journalist& jnlst 491 ) const; 492 493 /** output a more concise version */ 494 virtual void OutputShortDescription( 495 const Journalist& jnlst 496 ) const; 497 498 /** output a latex version */ 499 virtual void OutputLatexDescription( 500 const Journalist& jnlst 501 ) const; 502 503 /** output a doxygen version */ 504 virtual void OutputDoxygenDescription( 505 const Journalist& jnlst 506 ) const; 507 508 private: 509 std::string name_; 510 std::string short_description_; 511 std::string long_description_; 512 std::string registering_category_; 513 RegisteredOptionType type_; 514 515 bool has_lower_; 516 bool lower_strict_; 517 Number lower_; 518 bool has_upper_; 519 bool upper_strict_; 520 Number upper_; 521 Number default_number_; 522 523 void MakeValidLatexString( 524 std::string source, 525 std::string& dest 526 ) const; 527 528 std::string MakeValidLatexNumber( 529 Number value 530 ) const; 531 532 std::string MakeValidHTMLNumber( 533 Number value 534 ) const; 535 536 /** Compare two strings and return true if they are equal (case insensitive comparison) */ 537 bool string_equal_insensitive( 538 const std::string& s1, 539 const std::string& s2 540 ) const; 541 542 std::vector<string_entry> valid_strings_; 543 std::string default_string_; 544 545 /** Has the information as how many-th option this one was 546 * registered. */ 547 const Index counter_; 548 }; 549 550 /** Class for storing registered options. 551 * 552 * Used for validation and documentation. 553 */ 554 class IPOPTLIB_EXPORT RegisteredOptions: public ReferencedObject 555 { 556 public: 557 /** Constructors / Destructors */ 558 //@{ 559 /** Default Constructor */ RegisteredOptions()560 RegisteredOptions() 561 : next_counter_(0), 562 current_registering_category_("Uncategorized") 563 { } 564 565 /** Destructor */ ~RegisteredOptions()566 virtual ~RegisteredOptions() 567 { } 568 //@} 569 570 DECLARE_STD_EXCEPTION(OPTION_ALREADY_REGISTERED) 571 ; 572 573 /** Methods to interact with registered options */ 574 //@{ 575 /** set the registering class 576 * 577 * All subsequent options will be added with the registered class 578 */ SetRegisteringCategory(const std::string & registering_category)579 virtual void SetRegisteringCategory( 580 const std::string& registering_category 581 ) 582 { 583 current_registering_category_ = registering_category; 584 } 585 586 /** retrieve the value of the current registering category */ RegisteringCategory()587 virtual std::string RegisteringCategory() 588 { 589 return current_registering_category_; 590 } 591 592 /** Add a Number option (with no restrictions) */ 593 virtual void AddNumberOption( 594 const std::string& name, 595 const std::string& short_description, 596 Number default_value, 597 const std::string& long_description = "" 598 ); 599 600 /** Add a Number option (with a lower bound) */ 601 virtual void AddLowerBoundedNumberOption( 602 const std::string& name, 603 const std::string& short_description, 604 Number lower, 605 bool strict, 606 Number default_value, 607 const std::string& long_description = "" 608 ); 609 610 /** Add a Number option (with a upper bound) */ 611 virtual void AddUpperBoundedNumberOption( 612 const std::string& name, 613 const std::string& short_description, 614 Number upper, 615 bool strict, 616 Number default_value, 617 const std::string& long_description = "" 618 ); 619 620 /** Add a Number option (with a both bounds) */ 621 virtual void AddBoundedNumberOption( 622 const std::string& name, 623 const std::string& short_description, 624 Number lower, 625 bool lower_strict, 626 Number upper, 627 bool upper_strict, 628 Number default_value, 629 const std::string& long_description = "" 630 ); 631 632 /** Add a Integer option (with no restrictions) */ 633 virtual void AddIntegerOption( 634 const std::string& name, 635 const std::string& short_description, 636 Index default_value, 637 const std::string& long_description = "" 638 ); 639 640 /** Add a Integer option (with a lower bound) */ 641 virtual void AddLowerBoundedIntegerOption( 642 const std::string& name, 643 const std::string& short_description, 644 Index lower, 645 Index default_value, 646 const std::string& long_description = "" 647 ); 648 649 /** Add a Integer option (with a upper bound) */ 650 virtual void AddUpperBoundedIntegerOption( 651 const std::string& name, 652 const std::string& short_description, 653 Index upper, 654 Index default_value, 655 const std::string& long_description = "" 656 ); 657 658 /** Add a Integer option (with a both bounds) */ 659 virtual void AddBoundedIntegerOption( 660 const std::string& name, 661 const std::string& short_description, 662 Index lower, 663 Index upper, 664 Index default_value, 665 const std::string& long_description = "" 666 ); 667 668 /** Add a String option (with no restrictions) */ 669 virtual void AddStringOption( 670 const std::string& name, 671 const std::string& short_description, 672 const std::string& default_value, 673 const std::vector<std::string>& settings, 674 const std::vector<std::string>& descriptions, 675 const std::string& long_description = "" 676 ); 677 678 /** Methods that make adding string options with only a few entries easier */ 679 virtual void AddStringOption1( 680 const std::string& name, 681 const std::string& short_description, 682 const std::string& default_value, 683 const std::string& setting1, 684 const std::string& description1, 685 const std::string& long_description = "" 686 ); 687 688 virtual void AddStringOption2( 689 const std::string& name, 690 const std::string& short_description, 691 const std::string& default_value, 692 const std::string& setting1, 693 const std::string& description1, 694 const std::string& setting2, 695 const std::string& description2, 696 const std::string& long_description = "" 697 ); 698 699 virtual void AddStringOption3( 700 const std::string& name, 701 const std::string& short_description, 702 const std::string& default_value, 703 const std::string& setting1, 704 const std::string& description1, 705 const std::string& setting2, 706 const std::string& description2, 707 const std::string& setting3, 708 const std::string& description3, 709 const std::string& long_description = "" 710 ); 711 712 virtual void AddStringOption4( 713 const std::string& name, 714 const std::string& short_description, 715 const std::string& default_value, 716 const std::string& setting1, 717 const std::string& description1, 718 const std::string& setting2, 719 const std::string& description2, 720 const std::string& setting3, 721 const std::string& description3, 722 const std::string& setting4, 723 const std::string& description4, 724 const std::string& long_description = "" 725 ); 726 727 virtual void AddStringOption5( 728 const std::string& name, 729 const std::string& short_description, 730 const std::string& default_value, 731 const std::string& setting1, 732 const std::string& description1, 733 const std::string& setting2, 734 const std::string& description2, 735 const std::string& setting3, 736 const std::string& description3, 737 const std::string& setting4, 738 const std::string& description4, 739 const std::string& setting5, 740 const std::string& description5, 741 const std::string& long_description = "" 742 ); 743 744 virtual void AddStringOption6( 745 const std::string& name, 746 const std::string& short_description, 747 const std::string& default_value, 748 const std::string& setting1, 749 const std::string& description1, 750 const std::string& setting2, 751 const std::string& description2, 752 const std::string& setting3, 753 const std::string& description3, 754 const std::string& setting4, 755 const std::string& description4, 756 const std::string& setting5, 757 const std::string& description5, 758 const std::string& setting6, 759 const std::string& description6, 760 const std::string& long_description = "" 761 ); 762 763 virtual void AddStringOption7( 764 const std::string& name, 765 const std::string& short_description, 766 const std::string& default_value, 767 const std::string& setting1, 768 const std::string& description1, 769 const std::string& setting2, 770 const std::string& description2, 771 const std::string& setting3, 772 const std::string& description3, 773 const std::string& setting4, 774 const std::string& description4, 775 const std::string& setting5, 776 const std::string& description5, 777 const std::string& setting6, 778 const std::string& description6, 779 const std::string& setting7, 780 const std::string& description7, 781 const std::string& long_description = "" 782 ); 783 784 virtual void AddStringOption8( 785 const std::string& name, 786 const std::string& short_description, 787 const std::string& default_value, 788 const std::string& setting1, 789 const std::string& description1, 790 const std::string& setting2, 791 const std::string& description2, 792 const std::string& setting3, 793 const std::string& description3, 794 const std::string& setting4, 795 const std::string& description4, 796 const std::string& setting5, 797 const std::string& description5, 798 const std::string& setting6, 799 const std::string& description6, 800 const std::string& setting7, 801 const std::string& description7, 802 const std::string& setting8, 803 const std::string& description8, 804 const std::string& long_description = "" 805 ); 806 807 virtual void AddStringOption9( 808 const std::string& name, 809 const std::string& short_description, 810 const std::string& default_value, 811 const std::string& setting1, 812 const std::string& description1, 813 const std::string& setting2, 814 const std::string& description2, 815 const std::string& setting3, 816 const std::string& description3, 817 const std::string& setting4, 818 const std::string& description4, 819 const std::string& setting5, 820 const std::string& description5, 821 const std::string& setting6, 822 const std::string& description6, 823 const std::string& setting7, 824 const std::string& description7, 825 const std::string& setting8, 826 const std::string& description8, 827 const std::string& setting9, 828 const std::string& description9, 829 const std::string& long_description = "" 830 ); 831 832 virtual void AddStringOption10( 833 const std::string& name, 834 const std::string& short_description, 835 const std::string& default_value, 836 const std::string& setting1, 837 const std::string& description1, 838 const std::string& setting2, 839 const std::string& description2, 840 const std::string& setting3, 841 const std::string& description3, 842 const std::string& setting4, 843 const std::string& description4, 844 const std::string& setting5, 845 const std::string& description5, 846 const std::string& setting6, 847 const std::string& description6, 848 const std::string& setting7, 849 const std::string& description7, 850 const std::string& setting8, 851 const std::string& description8, 852 const std::string& setting9, 853 const std::string& description9, 854 const std::string& setting10, 855 const std::string& description10, 856 const std::string& long_description = "" 857 ); 858 859 /** Get a registered option 860 * 861 * @return NULL, if the option does not exist 862 */ 863 virtual SmartPtr<const RegisteredOption> GetOption( 864 const std::string& name 865 ); 866 867 /** Output documentation for the options - gives a description, etc. */ 868 virtual void OutputOptionDocumentation( 869 const Journalist& jnlst, 870 std::list<std::string>& categories 871 ); 872 873 /** Output documentation in Latex format to include in a latex file */ 874 virtual void OutputLatexOptionDocumentation( 875 const Journalist& jnlst, 876 std::list<std::string>& categories 877 ); 878 879 /** Output documentation in Doxygen format to include in doxygen documentation */ 880 virtual void OutputDoxygenOptionDocumentation( 881 const Journalist& jnlst, 882 std::list<std::string>& categories 883 ); 884 //@} 885 886 typedef std::map<std::string, SmartPtr<RegisteredOption> > RegOptionsList; 887 888 /** Giving access to iteratable representation of the registered options */ RegisteredOptionsList() const889 virtual const RegOptionsList& RegisteredOptionsList() const 890 { 891 return registered_options_; 892 } 893 894 private: 895 Index next_counter_; 896 std::string current_registering_category_; 897 std::map<std::string, SmartPtr<RegisteredOption> > registered_options_; 898 }; 899 900 } // namespace Ipopt 901 902 #endif 903