Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #184 from corywalker/corywalker
Refactor code into packages
- Loading branch information
Showing
95 changed files
with
6,469 additions
and
5,821 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,8 +4,6 @@ os: | |
language: go | ||
|
||
go: | ||
- "1.6" | ||
- "1.7" | ||
- "1.8" | ||
- "1.9" | ||
- "1.10" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
package atoms | ||
|
||
import "github.com/corywalker/expreduce/pkg/expreduceapi" | ||
|
||
type foldFn int | ||
|
||
const ( | ||
// FoldFnAdd designates that values should be added. | ||
FoldFnAdd foldFn = iota | ||
// FoldFnMul designates that values should be multiplied. | ||
FoldFnMul | ||
) | ||
|
||
func typedRealPart(fn foldFn, i *Integer, r *Rational, f *Flt, c *Complex) expreduceapi.Ex { | ||
if c != nil { | ||
toReturn := c | ||
if f != nil { | ||
if fn == FoldFnAdd { | ||
toReturn.addF(f) | ||
} else if fn == FoldFnMul { | ||
toReturn.mulF(f) | ||
} | ||
} | ||
if r != nil { | ||
if fn == FoldFnAdd { | ||
toReturn.addR(r) | ||
} else if fn == FoldFnMul { | ||
toReturn.mulR(r) | ||
} | ||
} | ||
if i != nil { | ||
if fn == FoldFnAdd { | ||
toReturn.addI(i) | ||
} else if fn == FoldFnMul { | ||
toReturn.mulI(i) | ||
} | ||
} | ||
return toReturn | ||
} | ||
if f != nil { | ||
toReturn := f | ||
if r != nil { | ||
if fn == FoldFnAdd { | ||
toReturn.addR(r) | ||
} else if fn == FoldFnMul { | ||
toReturn.mulR(r) | ||
} | ||
} | ||
if i != nil { | ||
if fn == FoldFnAdd { | ||
toReturn.addI(i) | ||
} else if fn == FoldFnMul { | ||
toReturn.mulI(i) | ||
} | ||
} | ||
return toReturn | ||
} | ||
if r != nil { | ||
toReturn := r | ||
if i != nil { | ||
if fn == FoldFnAdd { | ||
toReturn.addI(i) | ||
} else if fn == FoldFnMul { | ||
toReturn.mulI(i) | ||
} | ||
} | ||
return toReturn | ||
} | ||
if i != nil { | ||
return i | ||
} | ||
return nil | ||
} | ||
|
||
func ComputeNumericPart(fn foldFn, e expreduceapi.ExpressionInterface) (expreduceapi.Ex, int) { | ||
var foldedInt *Integer | ||
var foldedRat *Rational | ||
var foldedFlt *Flt | ||
var foldedComp *Complex | ||
for i := 1; i < len(e.GetParts()); i++ { | ||
// TODO: implement short circuiting if we encounter a zero while | ||
// multiplying. | ||
asInt, isInt := e.GetParts()[i].(*Integer) | ||
if isInt { | ||
if foldedInt == nil { | ||
// Try deepcopy if problems. I think this does not cause | ||
// problems now because we will only modify the value if we end | ||
// up creating an entirely new expression. | ||
foldedInt = asInt.DeepCopy().(*Integer) | ||
continue | ||
} | ||
if fn == FoldFnAdd { | ||
foldedInt.addI(asInt) | ||
} else if fn == FoldFnMul { | ||
foldedInt.mulI(asInt) | ||
} | ||
continue | ||
} | ||
asRat, isRat := e.GetParts()[i].(*Rational) | ||
if isRat { | ||
if foldedRat == nil { | ||
foldedRat = asRat.DeepCopy().(*Rational) | ||
continue | ||
} | ||
if fn == FoldFnAdd { | ||
foldedRat.addR(asRat) | ||
} else if fn == FoldFnMul { | ||
foldedRat.mulR(asRat) | ||
} | ||
continue | ||
} | ||
asFlt, isFlt := e.GetParts()[i].(*Flt) | ||
if isFlt { | ||
if foldedFlt == nil { | ||
foldedFlt = asFlt.DeepCopy().(*Flt) | ||
continue | ||
} | ||
if fn == FoldFnAdd { | ||
foldedFlt.addF(asFlt) | ||
} else if fn == FoldFnMul { | ||
foldedFlt.mulF(asFlt) | ||
} | ||
continue | ||
} | ||
asComp, isComp := e.GetParts()[i].(*Complex) | ||
if isComp { | ||
if foldedComp == nil { | ||
foldedComp = asComp.DeepCopy().(*Complex) | ||
continue | ||
} | ||
if fn == FoldFnAdd { | ||
foldedComp.addC(asComp) | ||
} else if fn == FoldFnMul { | ||
foldedComp.mulC(asComp) | ||
} | ||
continue | ||
} | ||
return typedRealPart(fn, foldedInt, foldedRat, foldedFlt, foldedComp), i | ||
} | ||
return typedRealPart(fn, foldedInt, foldedRat, foldedFlt, foldedComp), -1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package atoms | ||
|
||
import ( | ||
"encoding/binary" | ||
"fmt" | ||
"hash/fnv" | ||
|
||
"github.com/corywalker/expreduce/pkg/expreduceapi" | ||
) | ||
|
||
type Complex struct { | ||
Re expreduceapi.Ex | ||
Im expreduceapi.Ex | ||
needsEval bool | ||
} | ||
|
||
func (cmplx *Complex) StringForm(p expreduceapi.ToStringParams) string { | ||
if p.Form == "FullForm" { | ||
return fmt.Sprintf("Complex[%v, %v]", cmplx.Re, cmplx.Im) | ||
} | ||
reInt, reIsInt := cmplx.Re.(*Integer) | ||
imInt, imIsInt := cmplx.Im.(*Integer) | ||
if reIsInt && reInt.Val.Sign() == 0 { | ||
if imIsInt && imInt.Val.Int64() == 1 { | ||
return "I" | ||
} | ||
p.PreviousHead = "System`Times" | ||
return fmt.Sprintf("(%v*I)", cmplx.Im.StringForm(p)) | ||
} | ||
p.PreviousHead = "System`Plus" | ||
return fmt.Sprintf("(%v + %v*I)", cmplx.Re.StringForm(p), cmplx.Im.StringForm(p)) | ||
} | ||
|
||
func (cmplx *Complex) IsEqual(other expreduceapi.Ex) string { | ||
otherConv, otherIsComplex := other.(*Complex) | ||
if !otherIsComplex { | ||
return "EQUAL_FALSE" | ||
} | ||
if (cmplx.Re.IsEqual(otherConv.Re) != "EQUAL_TRUE") || (cmplx.Im.IsEqual(otherConv.Im) != "EQUAL_TRUE") { | ||
return "EQUAL_FALSE" | ||
} | ||
return "EQUAL_TRUE" | ||
} | ||
|
||
func (cmplx *Complex) DeepCopy() expreduceapi.Ex { | ||
return &Complex{cmplx.Re.DeepCopy(), cmplx.Im.DeepCopy(), cmplx.needsEval} | ||
} | ||
|
||
func (cmplx *Complex) Copy() expreduceapi.Ex { | ||
return cmplx.DeepCopy() | ||
} | ||
|
||
func (cmplx *Complex) NeedsEval() bool { | ||
return cmplx.needsEval | ||
} | ||
|
||
func NewComplex(r expreduceapi.Ex, i expreduceapi.Ex) *Complex { | ||
return &Complex{r, i, true} | ||
} | ||
|
||
func (cmplx *Complex) Hash() uint64 { | ||
h := fnv.New64a() | ||
h.Write([]byte{82, 226, 223, 39, 113, 26, 149, 249}) | ||
b := make([]byte, 8) | ||
binary.LittleEndian.PutUint64(b, cmplx.Re.Hash()) | ||
h.Write(b) | ||
binary.LittleEndian.PutUint64(b, cmplx.Im.Hash()) | ||
h.Write(b) | ||
return h.Sum64() | ||
} | ||
|
||
func (cmplx *Complex) addReal(e expreduceapi.Ex) { | ||
a, _ := ComputeNumericPart(FoldFnAdd, E(S("Dummy"), cmplx.Re, e)) | ||
cmplx.Re = a | ||
cmplx.needsEval = true | ||
} | ||
|
||
func (cmplx *Complex) addI(i *Integer) { | ||
cmplx.addReal(i) | ||
} | ||
|
||
func (cmplx *Complex) addF(f *Flt) { | ||
cmplx.addReal(f) | ||
} | ||
|
||
func (cmplx *Complex) addR(r *Rational) { | ||
cmplx.addReal(r) | ||
} | ||
|
||
func (cmplx *Complex) addC(c *Complex) { | ||
a, _ := ComputeNumericPart(FoldFnAdd, E(S("Dummy"), cmplx.Re, c.Re)) | ||
b, _ := ComputeNumericPart(FoldFnAdd, E(S("Dummy"), cmplx.Im, c.Im)) | ||
cmplx.Re = a | ||
cmplx.Im = b | ||
cmplx.needsEval = true | ||
} | ||
|
||
func (cmplx *Complex) mulReal(e expreduceapi.Ex) { | ||
a, _ := ComputeNumericPart(FoldFnMul, E(S("Dummy"), cmplx.Re, e)) | ||
b, _ := ComputeNumericPart(FoldFnMul, E(S("Dummy"), cmplx.Im, e)) | ||
cmplx.Re = a | ||
cmplx.Im = b | ||
cmplx.needsEval = true | ||
} | ||
|
||
func (cmplx *Complex) mulI(i *Integer) { | ||
cmplx.mulReal(i) | ||
} | ||
|
||
func (cmplx *Complex) mulF(f *Flt) { | ||
cmplx.mulReal(f) | ||
} | ||
|
||
func (cmplx *Complex) mulR(r *Rational) { | ||
cmplx.mulReal(r) | ||
} | ||
|
||
func (cmplx *Complex) mulC(c *Complex) { | ||
// HoldPattern[Complex[x_, y_]*Complex[u_, v_]*rest___] -> Complex[x*u + (y*v)*(-1), x*v + y*u]*rest) | ||
// cmplx is ugly. Need to refactor. | ||
// Perhaps create "Calculator" utility?? | ||
// TODO(corywalker) Remove the definition that cmplx implements in code. | ||
a, _ := ComputeNumericPart(FoldFnMul, E(S("Dummy"), cmplx.Re, c.Re)) | ||
b, _ := ComputeNumericPart(FoldFnMul, E(S("Dummy"), NewInt(-1), cmplx.Im, c.Im)) | ||
cc, _ := ComputeNumericPart(FoldFnMul, E(S("Dummy"), cmplx.Re, c.Im)) | ||
d, _ := ComputeNumericPart(FoldFnMul, E(S("Dummy"), cmplx.Im, c.Re)) | ||
e, _ := ComputeNumericPart(FoldFnAdd, E(S("Dummy"), a, b)) | ||
f, _ := ComputeNumericPart(FoldFnAdd, E(S("Dummy"), cc, d)) | ||
cmplx.Re = e | ||
cmplx.Im = f | ||
cmplx.needsEval = true | ||
} | ||
|
||
func (cmplx *Complex) SetNeedsEval(newVal bool) { | ||
cmplx.needsEval = newVal | ||
} |
Oops, something went wrong.