Skip to content

Commit

Permalink
Added Tests for Variable.Power, Variable.SubstituteAccordingTo
Browse files Browse the repository at this point in the history
  • Loading branch information
Kwesi Rutledge committed May 21, 2024
1 parent 481ba92 commit bcb1529
Show file tree
Hide file tree
Showing 2 changed files with 325 additions and 5 deletions.
6 changes: 2 additions & 4 deletions symbolic/variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -448,16 +448,14 @@ Description:
Creates a new binary variable.
*/
func NewBinaryVariable(envs ...Environment) Variable {
func NewBinaryVariable(envs ...*Environment) Variable {
// Constants

// Input Processing
var currentEnv Environment
var currentEnv = &BackgroundEnvironment
switch len(envs) {
case 1:
currentEnv = envs[0]
default:
currentEnv = BackgroundEnvironment
}

// Get New Index
Expand Down
324 changes: 323 additions & 1 deletion testing/symbolic/variable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ Description:
*/
func TestVariable_Minus3(t *testing.T) {
// Constants
var x symbolic.Variable
x := symbolic.NewVariable()

// Test
defer func() {
Expand All @@ -620,6 +620,102 @@ func TestVariable_Minus3(t *testing.T) {
x.Minus("hello")
}

/*
TestVariable_Minus4
Description:
This tests that the Minus() function properly panics when called on a variable
that is not well-defined.
*/
func TestVariable_Minus4(t *testing.T) {
// Constants
var x symbolic.Variable

// Test
defer func() {
if r := recover(); r == nil {
t.Errorf("The code did not panic")
}
}()
x.Minus(3.4)
}

/*
TestVariable_Minus5
Description:
Verifies that the Minus() method properly panics when the
input to the Minus() method's input is not a well-expressed.
*/
func TestVariable_Minus5(t *testing.T) {
// Constants
x := symbolic.NewVariable()
badVar := symbolic.Variable{}

// Test
defer func() {
r := recover()
if r == nil {
t.Errorf("The code did not panic")
}

rAsErr := r.(error)
if !strings.Contains(
rAsErr.Error(),
badVar.Check().Error(),
) {
t.Errorf("Expected error message to contain %v; received %v", badVar.Check().Error(), rAsErr.Error())
}

}()
x.Minus(badVar)
}

/*
TestVariable_Minus6
Description:
Verifies that the Minus() method properly produces a polynomial
when you subtract a float64 from the target variable.
*/
func TestVariable_Minus6(t *testing.T) {
// Constants
x := symbolic.NewVariable()
f1 := 3.14

// Test
diff := x.Minus(f1)
if diff.(symbolic.ScalarExpression).Constant() != -f1 {
t.Errorf(
"expected %v - %v to have constant component %v; received %v",
x,
f1,
-f1,
diff.(symbolic.ScalarExpression).Constant(),
)
}

// Test that diff is a polynomial with 2 terms
diffAsPoly, tf := diff.(symbolic.Polynomial)
if !tf {
t.Errorf(
"expected %v - %v to be a polynomial; received %T",
x,
f1,
diff,
)
}

if len(diffAsPoly.Monomials) != 2 {
t.Errorf(
"expected %v - %v to have 2 terms; received %v",
x,
f1,
len(diffAsPoly.Monomials),
)
}
}

/*
TestVariable_LessEq1
Description:
Expand Down Expand Up @@ -1225,6 +1321,40 @@ func TestVariable_NewBinaryVariable1(t *testing.T) {
}
}

/*
TestVariable_NewBinaryVariable2
Description:
Tests that the NewBinaryVariable() method properly creates
a variable with a unique ID when an environment is provided.
*/
func TestVariable_NewBinaryVariable2(t *testing.T) {
// Constants
env := symbolic.Environment{
Name: "test-nbv2",
}
symbolic.NewVariable(&env)
x := symbolic.NewBinaryVariable(&env)

// Test that the ID is unique
if x.Type != symbolic.Binary {
t.Errorf(
"expected %v to be a binary variable; received %v",
x,
x.Type,
)
}

// Test that the ID is greater than 0
if x.ID <= 0 {
t.Errorf(
"expected %v to have a unique ID; received %v",
x,
x.ID,
)
}
}

/*
TestVariable_DerivativeWrt1
Description:
Expand Down Expand Up @@ -1255,6 +1385,14 @@ func TestVariable_DerivativeWrt1(t *testing.T) {
x.DerivativeWrt(x)
}

/*
TestVariable_DerivativeWrt2
Description:
Tests that the DerivativeWrt() method properly panics when a valid
variable is used to call it, but the input is not well-defined.
*/

/*
TestVariable_DerivativeWrt2
Description:
Expand Down Expand Up @@ -1524,3 +1662,187 @@ func TestVariable_Substitute5(t *testing.T) {
)
}
}

/*
TestVariable_SubstituteAccordingTo1
Description:
Tests that the SubstituteAccordingTo() method properly panics when called
on a variable that is not well-defined.
*/
func TestVariable_SubstituteAccordingTo1(t *testing.T) {
// Constants
var x symbolic.Variable

// Test
defer func() {
r := recover()
if r == nil {
t.Errorf("The code did not panic")
}

rAsE, tf := r.(error)
if !tf {
t.Errorf("The panic was not an error")
}

if !strings.Contains(rAsE.Error(), x.Check().Error()) {
t.Errorf("The panic was not due to a bad Variable")
}
}()
x.SubstituteAccordingTo(map[symbolic.Variable]symbolic.Expression{
x: x,
})
}

/*
TestVariable_SubstituteAccordingTo2
Description:
Tests that the SubstituteAccordingTo() method properly panics when called with a
map that contains a well-defined variable key and a value that is not well-defined.
*/
func TestVariable_SubstituteAccordingTo2(t *testing.T) {
// Constants
x := symbolic.NewVariable()
var uninit symbolic.Variable

// Test
defer func() {
r := recover()
if r == nil {
t.Errorf("The code did not panic")
}

rAsE, tf := r.(error)
if !tf {
t.Errorf("The panic was not an error")
}

if !strings.Contains(rAsE.Error(), uninit.Check().Error()) {
t.Errorf("The panic was not due to a bad Variable")
}
}()
x.SubstituteAccordingTo(map[symbolic.Variable]symbolic.Expression{
x: uninit,
})
}

/*
TestVariable_SubstituteAccordingTo3
Description:
Tests that the SubstituteAccordingTo() method properly returns a temporary
expression (a unique variable) when the input map contains a key that is
the same as the input variable (the receiver).
*/
func TestVariable_SubstituteAccordingTo3(t *testing.T) {
// Constants
x := symbolic.NewVariable()
y := symbolic.NewVariable()

// Test
sub := x.SubstituteAccordingTo(map[symbolic.Variable]symbolic.Expression{
x: y,
})

subAsV, tf := sub.(symbolic.Variable)
if !tf {
t.Errorf(
"expected %v.sub(%v, %v) to be a variable; received %T",
x,
x,
y,
sub,
)
}

if subAsV.ID != y.ID {
t.Errorf(
"expected %v.sub(%v, %v) to be a unique variable; received %v",
x,
x,
y,
sub,
)
}
}

/*
TestVariable_SubstituteAccordingTo4
Description:
Tests that the SubstituteAccordingTo() method properly returns a the same variable
when the input map DOES NOT contain a key that is
the same as the input variable (the receiver).
*/
func TestVariable_SubstituteAccordingTo4(t *testing.T) {
// Constants
x := symbolic.NewVariable()
y := symbolic.NewVariable()

// Test
sub := x.SubstituteAccordingTo(map[symbolic.Variable]symbolic.Expression{
y: x,
})

subAsV, tf := sub.(symbolic.Variable)
if !tf {
t.Errorf(
"expected %v.sub(%v, %v) to be a variable; received %T",
x,
x,
y,
sub,
)
}

if subAsV.ID != x.ID {
t.Errorf(
"expected %v.sub(%v, %v) to be a unique variable; received %v",
x,
x,
y,
sub,
)
}
}

/*
TestVariable_Power1
Description:
Tests that the variable correctly becomes a monomial when raised to a power
greater than 1.
*/
func TestVariable_Power1(t *testing.T) {
// Constants
x := symbolic.NewVariable()

// Test
pow := x.Power(3)
mon, tf := pow.(symbolic.Monomial)
if !tf {
t.Errorf(
"expected %v^3 to be a monomial; received %T",
x,
pow,
)
}

if mon.Exponents[0] != 3 {
t.Errorf(
"expected %v^3 to have an exponent of 3; received %v",
x,
mon.Exponents[0],
)
}

if mon.Coefficient != 1.0 {
t.Errorf(
"expected %v^3 to have a coefficient of 1.0; received %v",
x,
mon.Coefficient,
)
}
}

0 comments on commit bcb1529

Please sign in to comment.