Skip to content

Added the Substitute() and SubstituteAccordingTo() methods for constr… #18

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/coverage1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
go: [1.19]
go: [1.23]
permissions:
# Give the default GITHUB_TOKEN write permission to commit and push the
# added or changed files to the repository.
Expand Down
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module github.com/MatProGo-dev/SymbolicMath.go

go 1.21
go 1.23.0

require gonum.org/v1/gonum v0.14.0
toolchain go1.23.8

require gonum.org/v1/gonum v0.16.0
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0=
gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
2 changes: 2 additions & 0 deletions symbolic/constraint.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ type Constraint interface {
ConstrSense() ConstrSense
Check() error
IsLinear() bool
Substitute(vIn Variable, seIn ScalarExpression) Constraint
SubstituteAccordingTo(subMap map[Variable]Expression) Constraint
}

func IsConstraint(c interface{}) bool {
Expand Down
46 changes: 46 additions & 0 deletions symbolic/matrix_constraint.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package symbolic

import (
"fmt"

"github.com/MatProGo-dev/SymbolicMath.go/smErrors"
)

Expand Down Expand Up @@ -145,3 +146,48 @@ Description:
func (mc MatrixConstraint) IsLinear() bool {
return IsLinear(mc.RightHandSide) && IsLinear(mc.LeftHandSide)
}

/*
Substitute
Description:

Substitutes the variable vIn with the scalar expression seIn
*/
func (mc MatrixConstraint) Substitute(vIn Variable, seIn ScalarExpression) Constraint {
// Check that the constraint is well formed.
err := mc.Check()
if err != nil {
panic(err)
}

// Substitute the variable in the left hand side
newLHS := mc.LeftHandSide.Substitute(vIn, seIn).(MatrixExpression)

// Substitute the variable in the right hand side
newRHS := mc.RightHandSide.Substitute(vIn, seIn).(MatrixExpression)

return MatrixConstraint{newLHS, newRHS, mc.Sense}
}

/*
SubstituteAccordingTo
Description:

Substitutes the variables in the map with the corresponding expressions
in the given scalar constraint.
*/
func (mc MatrixConstraint) SubstituteAccordingTo(subMap map[Variable]Expression) Constraint {
// Check that the constraint is well formed.
err := mc.Check()
if err != nil {
panic(err)
}

// Substitute the variable in the left hand side
newLHS := mc.LeftHandSide.SubstituteAccordingTo(subMap).(MatrixExpression)

// Substitute the variable in the right hand side
newRHS := mc.RightHandSide.SubstituteAccordingTo(subMap).(MatrixExpression)

return MatrixConstraint{newLHS, newRHS, mc.Sense}
}
8 changes: 5 additions & 3 deletions symbolic/monomial.go
Original file line number Diff line number Diff line change
Expand Up @@ -727,11 +727,13 @@ func (m Monomial) SubstituteAccordingTo(subMap map[Variable]Expression) Expressi

// Algorithm
// Create the monomial
var out Expression = K(0.0)
var out Expression = K(m.Coefficient)

// Iterate through each variable in the monomial
for tempVar, tempExp := range subMap {
out = out.Substitute(tempVar, tempExp.(ScalarExpression))
for ii, varII := range m.VariableFactors {
out = out.Multiply(
varII.SubstituteAccordingTo(subMap).Power(m.Exponents[ii]),
)
}

// Return
Expand Down
73 changes: 73 additions & 0 deletions symbolic/scalar_constraint.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,76 @@
// Return
return C, d
}

/*
Substitute
Description:

Substitutes the variable vIn with the scalar expression seIn in the
given scalar constraint.
*/
func (sc ScalarConstraint) Substitute(vIn Variable, seIn ScalarExpression) Constraint {
// Check that the constraint is well formed.
err := sc.Check()
if err != nil {
panic(err)
}

// Substitute the variable in the left hand side
newLHS := sc.LeftHandSide.Substitute(vIn, seIn).(ScalarExpression)

// Substitute the variable in the right hand side
newRHS := sc.RightHandSide.Substitute(vIn, seIn).(ScalarExpression)

// Return the new constraint
return ScalarConstraint{
LeftHandSide: newLHS,
RightHandSide: newRHS,
Sense: sc.Sense,
}
}

/*
SubstituteAccordingTo
Description:

Substitutes the variables in the map with the corresponding expressions
in the given scalar constraint.
*/
func (sc ScalarConstraint) SubstituteAccordingTo(subMap map[Variable]Expression) Constraint {
// Check that the constraint is well formed.
err := sc.Check()
if err != nil {
panic(err)
}

// Substitute the variable in the left hand side
newLHS := sc.LeftHandSide.SubstituteAccordingTo(subMap).(ScalarExpression)

// Substitute the variable in the right hand side
newRHS := sc.RightHandSide.SubstituteAccordingTo(subMap).(ScalarExpression)

// Return the new constraint
return ScalarConstraint{
LeftHandSide: newLHS,
RightHandSide: newRHS,
Sense: sc.Sense,
}
}

/*
String
Description:

Returns a string representation of the scalar constraint.
*/
func (sc ScalarConstraint) String() string {
// Check that the constraint is well formed.
err := sc.Check()
if err != nil {
panic(err)

Check warning on line 278 in symbolic/scalar_constraint.go

View check run for this annotation

Codecov / codecov/patch

symbolic/scalar_constraint.go#L278

Added line #L278 was not covered by tests
}

// Create the string representation
return sc.LeftHandSide.String() + " " + sc.Sense.String() + " " + sc.RightHandSide.String()
}
59 changes: 59 additions & 0 deletions symbolic/vector_constraint.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,62 @@
// Return the tuple
return C, d
}

/*
Substitute
Description:

Substitutes the variable vIn with the scalar expression seIn in the vector constraint.
*/
func (vc VectorConstraint) Substitute(vIn Variable, seIn ScalarExpression) Constraint {
// Check that the constraint is well formed.
err := vc.Check()
if err != nil {
panic(err)
}

// Substitute the variable in the left and right hand sides.
newLHS := vc.LeftHandSide.Substitute(vIn, seIn).(VectorExpression)
newRHS := vc.RightHandSide.Substitute(vIn, seIn).(VectorExpression)

// Return the new constraint
return VectorConstraint{newLHS, newRHS, vc.Sense}
}

/*
SubstituteAccordingTo
Description:

Substitutes the variables in the map with the corresponding expressions
*/
func (vc VectorConstraint) SubstituteAccordingTo(subMap map[Variable]Expression) Constraint {
// Check that the constraint is well formed.
err := vc.Check()
if err != nil {
panic(err)
}

// Substitute the variable in the left and right hand sides.
newLHS := vc.LeftHandSide.SubstituteAccordingTo(subMap).(VectorExpression)
newRHS := vc.RightHandSide.SubstituteAccordingTo(subMap).(VectorExpression)

// Return the new constraint
return VectorConstraint{newLHS, newRHS, vc.Sense}
}

/*
Len
Description:

Returns the length of the vector constraint.
*/
func (vc VectorConstraint) Len() int {
// Check that the constraint is well formed.
err := vc.Check()
if err != nil {
panic(err)

Check warning on line 313 in symbolic/vector_constraint.go

View check run for this annotation

Codecov / codecov/patch

symbolic/vector_constraint.go#L309-L313

Added lines #L309 - L313 were not covered by tests
}

// Return the length of the vector constraint.
return vc.LeftHandSide.Len()

Check warning on line 317 in symbolic/vector_constraint.go

View check run for this annotation

Codecov / codecov/patch

symbolic/vector_constraint.go#L317

Added line #L317 was not covered by tests
}
Loading