-
Notifications
You must be signed in to change notification settings - Fork 0
/
matrix_constraint.go
147 lines (120 loc) · 2.9 KB
/
matrix_constraint.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package symbolic
import (
"fmt"
"github.com/MatProGo-dev/SymbolicMath.go/smErrors"
)
/*
matrix_constraint.go
Description:
Functions related to the matrix constraint object.
*/
type MatrixConstraint struct {
LeftHandSide MatrixExpression
RightHandSide MatrixExpression
Sense ConstrSense
}
func (mc MatrixConstraint) Left() Expression {
return mc.LeftHandSide
}
func (mc MatrixConstraint) Right() Expression {
return mc.RightHandSide
}
/*
ConstrSense
Description:
Returns the sense of the constraint.
*/
func (mc MatrixConstraint) ConstrSense() ConstrSense {
return mc.Sense
}
/*
Check
Description:
Verifies that:
- The left and right hand sides have matching dimensions,
- The sense is valid, (i.e., it is from the set of allowable senses defined in ConstrSense.
*/
func (mc MatrixConstraint) Check() error {
// Input Processing
// Check that the left and right hand sides are well formed.
err := mc.LeftHandSide.Check()
if err != nil {
return err
}
err = mc.RightHandSide.Check()
if err != nil {
return err
}
// Save the dimensions of the left and right hand sides.
leftDims := mc.LeftHandSide.Dims()
rightDims := mc.RightHandSide.Dims()
// Check that the dimensions of the left and right hand sides are the same.
if len(leftDims) != len(rightDims) {
return fmt.Errorf("left and right hand sides have different dimensions")
}
if leftDims[0] != rightDims[0] {
return fmt.Errorf(
"there are a different number of rows in the left (%v) and right (%v) sides of the constraint!",
leftDims[0],
rightDims[0],
)
}
if leftDims[1] != rightDims[1] {
return fmt.Errorf(
"there are a different number of columns in the left (%v) and right (%v) sides of the constraint!",
leftDims[1],
rightDims[1],
)
}
// Check that the sense is valid.
err = mc.Sense.Check()
if err != nil {
return err
}
// All checks passed
return nil
}
/*
Dims
Description:
The dimension of the matrix constraint (ideally this should be the same as the dimensions
of the left and right hand sides).
*/
func (mc MatrixConstraint) Dims() []int {
err := mc.Check()
if err != nil {
panic(err)
}
// Dimensions of right and left should be the same.
return mc.LeftHandSide.Dims()
}
/*
AtVec
Description:
Retrieves the constraint formed by one element of the "vector" constraint.
*/
func (mc MatrixConstraint) At(ii, jj int) ScalarConstraint {
// Input Processing
err := mc.Check()
if err != nil {
panic(err)
}
// Check to see whether or not the index is valid.
err = smErrors.CheckIndexOnMatrix(ii, jj, mc)
if err != nil {
panic(err)
}
// Algorithm
lhsAtIIJJ := mc.LeftHandSide.At(ii, jj)
rhsAtIIJJ := mc.RightHandSide.At(ii, jj)
return ScalarConstraint{lhsAtIIJJ, rhsAtIIJJ, mc.Sense}
}
/*
IsLinear
Description:
Describes whether a given matrix constraint is
linear or not.
*/
func (mc MatrixConstraint) IsLinear() bool {
return IsLinear(mc.RightHandSide) && IsLinear(mc.LeftHandSide)
}