@@ -580,7 +580,7 @@ Description:
580580 Then, we replace every instance of the original variable with the difference
581581 of the two new variables (x = x_+ - x_-).
582582*/
583- func (op * OptimizationProblem ) ToProblemWithAllPositiveVariables () (* OptimizationProblem , error ) {
583+ func (op * OptimizationProblem ) ToProblemWithAllPositiveVariables () (* OptimizationProblem , map [symbolic. Variable ]symbolic. Expression , error ) {
584584 // Setup
585585 newProblem := NewProblem (op .Name + " (All Positive Variables)" )
586586 epsMagic := 1e-8 // TODO(Kwesi): Make this a parameter OR a constant in the package.
@@ -620,7 +620,7 @@ func (op *OptimizationProblem) ToProblemWithAllPositiveVariables() (*Optimizatio
620620 }
621621
622622 // Set the original variable to be the difference of the two new variables
623- mapFromOriginalVariablesToNewExpressions [xII ] = expressionForReplacement
623+ mapFromOriginalVariablesToNewExpressions [xII ] = expressionForReplacement . AsSimplifiedExpression ()
624624 }
625625
626626 // Now, let's create the new constraints by replacing the variables in the
@@ -643,7 +643,7 @@ func (op *OptimizationProblem) ToProblemWithAllPositiveVariables() (*Optimizatio
643643 op .Objective .Sense ,
644644 )
645645
646- return newProblem , nil
646+ return newProblem , mapFromOriginalVariablesToNewExpressions , nil
647647}
648648
649649/*
@@ -668,22 +668,22 @@ Note:
668668 into a set of scalar constraints. Thus, the number of constraints in your problem may
669669 "seem" to change.
670670*/
671- func (problemIn * OptimizationProblem ) ToLPStandardForm1 () (* OptimizationProblem , []symbolic.Variable , error ) {
671+ func (problemIn * OptimizationProblem ) ToLPStandardForm1 () (* OptimizationProblem , []symbolic.Variable , map [symbolic. Variable ]symbolic. Expression , error ) {
672672 // Input Processing
673673 err := problemIn .Check ()
674674 if err != nil {
675- return nil , nil , problemIn .MakeNotWellDefinedError ()
675+ return nil , nil , nil , problemIn .MakeNotWellDefinedError ()
676676 }
677677
678678 // Check if the problem is linear
679679 if ! problemIn .IsLinear () {
680- return nil , nil , problemIn .CheckIfLinear ()
680+ return nil , nil , nil , problemIn .CheckIfLinear ()
681681 }
682682
683683 // Change the problem so that it is written in terms of strictly positive variables
684- problemWithAllPositiveVariables , err := problemIn .ToProblemWithAllPositiveVariables () // Note: This method may change the number of variables and constraints in the problem.
684+ problemWithAllPositiveVariables , originalVariablesToPositiveVariableExpressions , err := problemIn .ToProblemWithAllPositiveVariables () // Note: This method may change the number of variables and constraints in the problem.
685685 if err != nil {
686- return nil , nil , err
686+ return nil , nil , nil , err
687687 }
688688
689689 // Create a new problem
@@ -692,11 +692,11 @@ func (problemIn *OptimizationProblem) ToLPStandardForm1() (*OptimizationProblem,
692692 )
693693
694694 // Add all variables to the new problem
695- mapFromInToNewVariables := make (map [symbolic.Variable ]symbolic.Expression )
695+ mapFromPositiveToNewVariables := make (map [symbolic.Variable ]symbolic.Expression )
696696 for _ , varII := range problemWithAllPositiveVariables .Variables {
697697 problemInStandardForm .AddVariable ()
698698 nVariables := len (problemInStandardForm .Variables )
699- mapFromInToNewVariables [varII ] = problemInStandardForm .Variables [nVariables - 1 ]
699+ mapFromPositiveToNewVariables [varII ] = problemInStandardForm .Variables [nVariables - 1 ]
700700 }
701701
702702 // Add all constraints to the new problem
@@ -706,10 +706,10 @@ func (problemIn *OptimizationProblem) ToLPStandardForm1() (*OptimizationProblem,
706706 // Create a new expression by substituting the variables according
707707 // to the map we created above
708708 oldLHS := constraint .Left ()
709- newLHS := oldLHS .SubstituteAccordingTo (mapFromInToNewVariables )
709+ newLHS := oldLHS .SubstituteAccordingTo (mapFromPositiveToNewVariables )
710710
711711 oldRHS := constraint .Right ()
712- newRHS := oldRHS .SubstituteAccordingTo (mapFromInToNewVariables )
712+ newRHS := oldRHS .SubstituteAccordingTo (mapFromPositiveToNewVariables )
713713
714714 switch constraint .ConstrSense () {
715715 case symbolic .SenseEqual :
@@ -742,7 +742,7 @@ func (problemIn *OptimizationProblem) ToLPStandardForm1() (*OptimizationProblem,
742742 newLHS = newLHS .Plus (problemInStandardForm .Variables [nVariables - 1 ])
743743
744744 default :
745- return nil , nil , fmt .Errorf (
745+ return nil , nil , nil , fmt .Errorf (
746746 "Unknown constraint sense: " + constraint .ConstrSense ().String (),
747747 )
748748 }
@@ -762,7 +762,7 @@ func (problemIn *OptimizationProblem) ToLPStandardForm1() (*OptimizationProblem,
762762 // Now, let's create the new objective function by substituting the variables
763763 // according to the map we created above
764764 newObjectiveExpression := problemWithAllPositiveVariables .Objective .Expression .SubstituteAccordingTo (
765- mapFromInToNewVariables ,
765+ mapFromPositiveToNewVariables ,
766766 )
767767 problemInStandardForm .SetObjective (
768768 newObjectiveExpression ,
@@ -772,8 +772,16 @@ func (problemIn *OptimizationProblem) ToLPStandardForm1() (*OptimizationProblem,
772772 // Simplify The Constraints If Possible
773773 problemInStandardForm .SimplifyConstraints ()
774774
775+ // Create the map from the original variables to the new variables
776+ // by composing the two maps we created above
777+ originalVariablesToNewVariables := make (map [symbolic.Variable ]symbolic.Expression )
778+ for originalVar , positiveVarExpr := range originalVariablesToPositiveVariableExpressions {
779+ newVarExpr := positiveVarExpr .SubstituteAccordingTo (mapFromPositiveToNewVariables )
780+ originalVariablesToNewVariables [originalVar ] = newVarExpr
781+ }
782+
775783 // Return the new problem and the slack variables
776- return problemInStandardForm , slackVariables , nil
784+ return problemInStandardForm , slackVariables , originalVariablesToNewVariables , nil
777785}
778786
779787/*
@@ -795,17 +803,17 @@ Description:
795803 This method also returns the slack variables (i.e., the variables that
796804 are added to the problem to convert the inequalities into equalities).
797805*/
798- func (problemIn * OptimizationProblem ) ToLPStandardForm2 () (* OptimizationProblem , []symbolic.Variable , error ) {
806+ func (problemIn * OptimizationProblem ) ToLPStandardForm2 () (* OptimizationProblem , []symbolic.Variable , map [symbolic. Variable ]symbolic. Expression , error ) {
799807 // Input Processing
800808 err := problemIn .Check ()
801809 if err != nil {
802- return nil , nil , problemIn .MakeNotWellDefinedError ()
810+ return nil , nil , nil , problemIn .MakeNotWellDefinedError ()
803811 }
804812
805813 // Use the existing method to convert to standard form 1
806- problemInStandardForm , slackVariables , err := problemIn .ToLPStandardForm1 ()
814+ problemInStandardForm , slackVariables , originalVariablesToNewVariables , err := problemIn .ToLPStandardForm1 ()
807815 if err != nil {
808- return nil , nil , err
816+ return nil , nil , nil , err
809817 }
810818
811819 // Modify the objective function to be a maximization problem,
@@ -816,12 +824,12 @@ func (problemIn *OptimizationProblem) ToLPStandardForm2() (*OptimizationProblem,
816824 newObjectiveExpression := problemInStandardForm .Objective .Expression .Multiply (- 1.0 )
817825 err = problemInStandardForm .SetObjective (newObjectiveExpression , SenseMaximize )
818826 if err != nil {
819- return nil , nil , fmt .Errorf ("there was a problem setting the new objective function: %v" , err )
827+ return nil , nil , originalVariablesToNewVariables , fmt .Errorf ("there was a problem setting the new objective function: %v" , err )
820828 }
821829 }
822830
823831 // Return the new problem and the slack variables
824- return problemInStandardForm , slackVariables , nil
832+ return problemInStandardForm , slackVariables , originalVariablesToNewVariables , nil
825833}
826834
827835/*
0 commit comments