Skip to content

Commit 19dfe12

Browse files
- support ParseComplex from go1.15
1 parent b891ce4 commit 19dfe12

File tree

3 files changed

+137
-121
lines changed

3 files changed

+137
-121
lines changed

xseries/parse_complex.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2019-20 PJ Engineering and Business Solutions Pty. Ltd. All rights reserved.
2+
3+
// +build go1.15
4+
5+
package xseries
6+
7+
import "strconv"
8+
9+
func parseComplex(s string) (complex128, error) {
10+
return strconv.ParseComplex(s, 128)
11+
}

xseries/parse_complex_legacy.go

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Copyright 2019-20 PJ Engineering and Business Solutions Pty. Ltd. All rights reserved.
2+
3+
// +build !go1.15
4+
5+
package xseries
6+
7+
import "strconv"
8+
9+
func convErr(err error, s string) error {
10+
if x, ok := err.(*strconv.NumError); ok {
11+
x.Func = "ParseComplex"
12+
x.Num = s
13+
}
14+
return err
15+
}
16+
17+
func parseComplex(s string) (complex128, error) {
18+
19+
orig := s
20+
21+
if len(s) == 0 {
22+
err := &strconv.NumError{
23+
Func: "ParseComplex",
24+
Num: orig,
25+
Err: strconv.ErrSyntax,
26+
}
27+
return 0, err
28+
}
29+
30+
lastChar := s[len(s)-1:]
31+
32+
// Remove brackets
33+
if len(s) > 1 && s[0:1] == "(" && lastChar == ")" {
34+
s = s[1 : len(s)-1]
35+
lastChar = s[len(s)-1:]
36+
}
37+
38+
// Is last character an i?
39+
if lastChar != "i" {
40+
// The last character is not an i so there is only a real component.
41+
real, err := strconv.ParseFloat(s, 64)
42+
if err != nil {
43+
return 0, convErr(err, orig)
44+
}
45+
return complex(real, 0), nil
46+
}
47+
48+
// Remove last char which is an i
49+
s = s[0 : len(s)-1]
50+
51+
// Count how many ± exist.
52+
pos := []int{}
53+
54+
for idx, rune := range s {
55+
if rune == '+' || rune == '-' {
56+
pos = append(pos, idx)
57+
}
58+
}
59+
60+
if len(pos) == 0 {
61+
// There is only an imaginary component
62+
63+
if s == "" {
64+
s = s + "1"
65+
}
66+
67+
imag, err := strconv.ParseFloat(s, 64)
68+
if err != nil {
69+
return 0, convErr(err, orig)
70+
}
71+
return complex(0, imag), nil
72+
73+
} else if len(pos) > 4 {
74+
// Too many ± exists for a valid complex number
75+
err := &strconv.NumError{
76+
Func: "ParseComplex",
77+
Num: orig,
78+
Err: strconv.ErrSyntax,
79+
}
80+
return 0, err
81+
}
82+
83+
/* From here onwards, it is either a complex number with both a real and imaginary component OR a pure imaginary number in exponential form. */
84+
85+
// Loop through pos from middle of slice, outwards
86+
mid := (len(pos) - 1) >> 1
87+
for j := 0; j < len(pos); j++ {
88+
var idx int
89+
if j%2 == 0 {
90+
idx = mid - j/2
91+
} else {
92+
idx = mid + (j/2 + 1)
93+
}
94+
95+
left := s[0:pos[idx]]
96+
right := s[pos[idx]:]
97+
98+
if left == "" {
99+
left = left + "0"
100+
}
101+
102+
// Check if left and right are valid float64
103+
real, err := strconv.ParseFloat(left, 64)
104+
if err != nil {
105+
continue
106+
}
107+
108+
if right == "+" || right == "-" {
109+
right = right + "1"
110+
}
111+
112+
imag, err := strconv.ParseFloat(right, 64)
113+
if err != nil {
114+
continue
115+
}
116+
117+
return complex(real, imag), nil
118+
}
119+
120+
// Pure imaginary number in exponential form
121+
imag, err := strconv.ParseFloat(s, 64)
122+
if err != nil {
123+
return 0, convErr(err, orig)
124+
}
125+
return complex(0, imag), nil
126+
}

xseries/series_complex128.go

Lines changed: 0 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"math"
1212
"math/cmplx"
1313
"sort"
14-
"strconv"
1514
"strings"
1615
"sync"
1716

@@ -887,126 +886,6 @@ func (s *SeriesComplex128) ToSeriesMixed(ctx context.Context, removeNil bool, co
887886
return ss, nil
888887
}
889888

890-
func convErr(err error, s string) error {
891-
if x, ok := err.(*strconv.NumError); ok {
892-
x.Func = "ParseComplex"
893-
x.Num = s
894-
}
895-
return err
896-
}
897-
898-
// Remove this function if https://github.com/golang/go/issues/36771 is approved
899-
func parseComplex(s string) (complex128, error) {
900-
901-
orig := s
902-
903-
if len(s) == 0 {
904-
err := &strconv.NumError{
905-
Func: "ParseComplex",
906-
Num: orig,
907-
Err: strconv.ErrSyntax,
908-
}
909-
return 0, err
910-
}
911-
912-
lastChar := s[len(s)-1:]
913-
914-
// Remove brackets
915-
if len(s) > 1 && s[0:1] == "(" && lastChar == ")" {
916-
s = s[1 : len(s)-1]
917-
lastChar = s[len(s)-1:]
918-
}
919-
920-
// Is last character an i?
921-
if lastChar != "i" {
922-
// The last character is not an i so there is only a real component.
923-
real, err := strconv.ParseFloat(s, 64)
924-
if err != nil {
925-
return 0, convErr(err, orig)
926-
}
927-
return complex(real, 0), nil
928-
}
929-
930-
// Remove last char which is an i
931-
s = s[0 : len(s)-1]
932-
933-
// Count how many ± exist.
934-
pos := []int{}
935-
936-
for idx, rune := range s {
937-
if rune == '+' || rune == '-' {
938-
pos = append(pos, idx)
939-
}
940-
}
941-
942-
if len(pos) == 0 {
943-
// There is only an imaginary component
944-
945-
if s == "" {
946-
s = s + "1"
947-
}
948-
949-
imag, err := strconv.ParseFloat(s, 64)
950-
if err != nil {
951-
return 0, convErr(err, orig)
952-
}
953-
return complex(0, imag), nil
954-
955-
} else if len(pos) > 4 {
956-
// Too many ± exists for a valid complex number
957-
err := &strconv.NumError{
958-
Func: "ParseComplex",
959-
Num: orig,
960-
Err: strconv.ErrSyntax,
961-
}
962-
return 0, err
963-
}
964-
965-
/* From here onwards, it is either a complex number with both a real and imaginary component OR a pure imaginary number in exponential form. */
966-
967-
// Loop through pos from middle of slice, outwards
968-
mid := (len(pos) - 1) >> 1
969-
for j := 0; j < len(pos); j++ {
970-
var idx int
971-
if j%2 == 0 {
972-
idx = mid - j/2
973-
} else {
974-
idx = mid + (j/2 + 1)
975-
}
976-
977-
left := s[0:pos[idx]]
978-
right := s[pos[idx]:]
979-
980-
if left == "" {
981-
left = left + "0"
982-
}
983-
984-
// Check if left and right are valid float64
985-
real, err := strconv.ParseFloat(left, 64)
986-
if err != nil {
987-
continue
988-
}
989-
990-
if right == "+" || right == "-" {
991-
right = right + "1"
992-
}
993-
994-
imag, err := strconv.ParseFloat(right, 64)
995-
if err != nil {
996-
continue
997-
}
998-
999-
return complex(real, imag), nil
1000-
}
1001-
1002-
// Pure imaginary number in exponential form
1003-
imag, err := strconv.ParseFloat(s, 64)
1004-
if err != nil {
1005-
return 0, convErr(err, orig)
1006-
}
1007-
return complex(0, imag), nil
1008-
}
1009-
1010889
// FillRand will fill a Series with random data. probNil is a value between between 0 and 1 which
1011890
// determines if a row is given a nil value.
1012891
func (s *SeriesComplex128) FillRand(src rand.Source, probNil float64, rander dataframe.Rander, opts ...dataframe.FillRandOptions) {

0 commit comments

Comments
 (0)