-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
50 changed files
with
3,406 additions
and
2,343 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 |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Copyright 2023 Matrix Origin | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package assertx | ||
|
||
import ( | ||
"math" | ||
) | ||
|
||
// Float64 values have minor numerical differences between Apple M2 and Linux EC2, | ||
// so we use an epsilon value to compare them in UT. We could not use reflect.DeepEqual because | ||
// of these minor differences. We cannot use assert.InEpsilon because it requires the first | ||
// argument to be non-zero. | ||
// | ||
// The epsilon 1e-9 epsilon is based on the following observation: | ||
// - `strconv.FormatFloat(float64(value), 'f', -1, 64)` we use for outputting float64 values. | ||
// - precision difference between Apple M2 and Linux EC2 float64 results (approx 1e-13) | ||
// - service_weaver: https://github.com/ServiceWeaver/weaver/blob/8e7c225542b8f8267ec0da3e01a098366b6f8daf/internal/weaver/load.go#L31 | ||
// - google lib: https://github.com/google/differential-privacy/blob/91b4ecebf33e71b8a215b7ea8325fb5e47b12671/privacy-on-beam/pbeam/pbeamtest/pbeamtest_test.go#L1406 | ||
const float64EqualityThreshold = 1e-9 | ||
|
||
// InEpsilonF64Slices returns true if all the elements in v1 and v2 are within epsilon of each other. | ||
func InEpsilonF64Slices(want, got [][]float64) bool { | ||
if len(want) != len(got) { | ||
return false | ||
} | ||
|
||
for i := 0; i < len(want); i++ { | ||
if !InEpsilonF64Slice(want[i], got[i]) { | ||
return false | ||
} | ||
} | ||
return true | ||
} | ||
|
||
// InEpsilonF64Slice returns true if all the elements in v1 and v2 are within epsilon of each other. | ||
// assert.InEpsilonSlice requires v1 to be non-zero. | ||
func InEpsilonF64Slice(want, got []float64) bool { | ||
if len(want) != len(got) { | ||
return false | ||
} | ||
|
||
for i := 0; i < len(want); i++ { | ||
if !InEpsilonF64(want[i], got[i]) { | ||
return false | ||
} | ||
} | ||
return true | ||
} | ||
|
||
// InEpsilonF64 returns true if v1 and v2 are within epsilon of each other. | ||
// assert.InEpsilon requires v1 to be non-zero. | ||
func InEpsilonF64(want, got float64) bool { | ||
return want == got || math.Abs(want-got) < float64EqualityThreshold || (math.IsNaN(want) && math.IsNaN(got)) | ||
} |
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,166 @@ | ||
// Copyright 2023 Matrix Origin | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package assertx | ||
|
||
import "testing" | ||
|
||
func TestInEpsilonF64(t *testing.T) { | ||
type args struct { | ||
want float64 | ||
got float64 | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want bool | ||
}{ | ||
|
||
{ | ||
name: "Test 1 - difference is epsilon", | ||
args: args{ | ||
want: 2.0, | ||
got: 2.0 + float64EqualityThreshold, | ||
}, | ||
want: false, | ||
}, | ||
{ | ||
name: "Test 2.a - difference is less than epsilon", | ||
args: args{ | ||
want: 2.0, | ||
got: 2.0 + 0.5*float64EqualityThreshold, | ||
}, | ||
want: true, | ||
}, | ||
{ | ||
name: "Test 2.b - difference is more than epsilon", | ||
args: args{ | ||
want: 2.0, | ||
got: 2.0 + 2*float64EqualityThreshold, | ||
}, | ||
want: false, | ||
}, | ||
{ | ||
name: "Test 2.c - difference is -ve of epsilon", | ||
args: args{ | ||
want: 2.0, | ||
got: 2.0 - float64EqualityThreshold, | ||
}, | ||
want: false, | ||
}, | ||
{ | ||
name: "Test 3 - till 9th digit is same, 10th digit is different", | ||
args: args{ | ||
want: 1.732050800_0, | ||
got: 1.732050800_9, | ||
}, | ||
want: true, | ||
}, | ||
{ | ||
name: "Test 4 - 9th digit is different", | ||
args: args{ | ||
want: 1.73205080_0, | ||
got: 1.73205080_9, | ||
}, | ||
want: false, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := InEpsilonF64(tt.args.want, tt.args.got); got != tt.want { | ||
t.Errorf("%s InEpsilonF64() = %v, want %v", tt.name, got, tt.want) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestInEpsilonF64Slice(t *testing.T) { | ||
type args struct { | ||
want []float64 | ||
got []float64 | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want bool | ||
}{ | ||
{ | ||
name: "Test 1 - difference is epsilon", | ||
args: args{ | ||
want: []float64{2.0, 3.0}, | ||
got: []float64{2.0 + float64EqualityThreshold, 3.0 + float64EqualityThreshold}, | ||
}, | ||
want: false, | ||
}, | ||
{ | ||
name: "Test 2 - till 9th digit is same, 10th digit is different)", | ||
args: args{ | ||
want: []float64{1.732050800_0}, | ||
got: []float64{1.732050800_9}, | ||
}, | ||
want: true, | ||
}, | ||
{ | ||
name: "Test 3 - 9th digit is different", | ||
args: args{ | ||
want: []float64{1.73205080_0}, | ||
got: []float64{1.73205080_9}, | ||
}, | ||
want: false, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := InEpsilonF64Slice(tt.args.want, tt.args.got); got != tt.want { | ||
t.Errorf("InEpsilonF64Slice() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestInEpsilonF64Slices(t *testing.T) { | ||
type args struct { | ||
want [][]float64 | ||
got [][]float64 | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want bool | ||
}{ | ||
{ | ||
name: "Test 1 - difference is epsilon", | ||
args: args{ | ||
want: [][]float64{{2.0, 3.0}, {4.0}}, | ||
got: [][]float64{{2.0 + float64EqualityThreshold, 3.0 + float64EqualityThreshold}, {4.0}}, | ||
}, | ||
want: false, | ||
}, | ||
{ | ||
name: "Test 2 - difference is less than epsilon (next neg-power of epsilon & epsilon/2)", | ||
args: args{ | ||
want: [][]float64{{2.0, 3.0}, {4.0}}, | ||
got: [][]float64{{2.0 + 1e-1*float64EqualityThreshold, 3.0 + float64EqualityThreshold/2}, {4.0}}, | ||
}, | ||
want: true, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
if got := InEpsilonF64Slices(tt.args.want, tt.args.got); got != tt.want { | ||
t.Errorf("InEpsilonF64Slices() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.