github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/num/quat/exp_test.go (about)

     1  // Copyright ©2018 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package quat
     6  
     7  import (
     8  	"math"
     9  	"testing"
    10  )
    11  
    12  var expTests = []struct {
    13  	q    Number
    14  	want Number
    15  }{
    16  	{q: Number{}, want: Number{Real: 1}},
    17  	// Expected velues below are from pyquaternion.
    18  	{
    19  		q:    Number{Real: 1, Imag: 1, Jmag: 1, Kmag: 1},
    20  		want: Number{Real: -0.43643792124786496, Imag: 1.549040352371697, Jmag: 1.549040352371697, Kmag: 1.549040352371697},
    21  	},
    22  	{
    23  		q:    Number{Real: 1, Imag: 0, Jmag: 1, Kmag: 1},
    24  		want: Number{Real: 0.42389891174348104, Imag: 0, Jmag: 1.8986002490721081, Kmag: 1.8986002490721081},
    25  	},
    26  	{
    27  		q:    Number{Real: 1, Imag: 0, Jmag: 0, Kmag: 1},
    28  		want: Number{Real: 1.4686939399158851, Imag: 0, Jmag: 0, Kmag: 2.2873552871788423},
    29  	},
    30  	{
    31  		q:    Number{Real: 0, Imag: 1, Jmag: 1, Kmag: 1},
    32  		want: Number{Real: -0.16055653857469052, Imag: 0.569860099182514, Jmag: 0.569860099182514, Kmag: 0.569860099182514},
    33  	},
    34  	{
    35  		q:    Number{Real: 0, Imag: 0, Jmag: 1, Kmag: 1},
    36  		want: Number{Real: 0.15594369476537437, Imag: 0, Jmag: 0.6984559986366083, Kmag: 0.6984559986366083},
    37  	},
    38  	{
    39  		q:    Number{Real: 0, Imag: 0, Jmag: 0, Kmag: 1},
    40  		want: Number{Real: 0.5403023058681398, Imag: 0, Jmag: 0, Kmag: 0.8414709848078965},
    41  	},
    42  }
    43  
    44  func TestExp(t *testing.T) {
    45  	t.Parallel()
    46  	const tol = 1e-14
    47  	for _, test := range expTests {
    48  		got := Exp(test.q)
    49  		if !equalApprox(got, test.want, tol) {
    50  			t.Errorf("unexpected result for Exp(%v): got:%v want:%v", test.q, got, test.want)
    51  		}
    52  	}
    53  }
    54  
    55  var logTests = []struct {
    56  	q    Number
    57  	want Number
    58  }{
    59  	{q: Number{}, want: Number{Real: -inf}},
    60  	// Expected velues below are from pyquaternion.
    61  	{
    62  		q:    Number{Real: 1, Imag: 1, Jmag: 1, Kmag: 1},
    63  		want: Number{Real: 0.6931471805599453, Imag: 0.6045997880780728, Jmag: 0.6045997880780728, Kmag: 0.6045997880780728},
    64  	},
    65  	{
    66  		q:    Number{Real: 1, Imag: 0, Jmag: 1, Kmag: 1},
    67  		want: Number{Real: 0.5493061443340548, Imag: 0, Jmag: 0.6755108588560398, Kmag: 0.6755108588560398},
    68  	},
    69  	{
    70  		q:    Number{Real: 1, Imag: 0, Jmag: 0, Kmag: 1},
    71  		want: Number{Real: 0.3465735902799727, Imag: 0, Jmag: 0, Kmag: 0.7853981633974484},
    72  	},
    73  	{
    74  		q:    Number{Real: 0, Imag: 1, Jmag: 1, Kmag: 1},
    75  		want: Number{Real: 0.5493061443340548, Imag: 0.906899682117109, Jmag: 0.906899682117109, Kmag: 0.906899682117109},
    76  	},
    77  	{
    78  		q:    Number{Real: 0, Imag: 0, Jmag: 1, Kmag: 1},
    79  		want: Number{Real: 0.3465735902799727, Imag: 0, Jmag: 1.1107207345395915, Kmag: 1.1107207345395915},
    80  	},
    81  	{
    82  		q:    Number{Real: 0, Imag: 0, Jmag: 0, Kmag: 1},
    83  		want: Number{Real: 0, Imag: 0, Jmag: 0, Kmag: 1.5707963267948966},
    84  	},
    85  }
    86  
    87  func TestLog(t *testing.T) {
    88  	t.Parallel()
    89  	const tol = 1e-14
    90  	for _, test := range logTests {
    91  		got := Log(test.q)
    92  		if !equalApprox(got, test.want, tol) {
    93  			t.Errorf("unexpected result for Log(%v): got:%v want:%v", test.q, got, test.want)
    94  		}
    95  	}
    96  }
    97  
    98  var powTests = []struct {
    99  	q, r Number
   100  	want Number
   101  }{
   102  	{q: Number{}, r: Number{}, want: Number{Real: 1}},
   103  	// Expected velues below are from pyquaternion.
   104  	// pyquaternion does not support quaternion powers.
   105  	// TODO(kortschak): Add non-real r cases.
   106  	{
   107  		q: Number{Real: 1, Imag: 1, Jmag: 1, Kmag: 1}, r: Number{Real: 2},
   108  		want: Number{Real: -2, Imag: 2, Jmag: 2, Kmag: 2},
   109  	},
   110  	{
   111  		q: Number{Real: 1, Imag: 0, Jmag: 1, Kmag: 1}, r: Number{Real: 2},
   112  		want: Number{Real: -1, Imag: 0, Jmag: 2, Kmag: 2},
   113  	},
   114  	{
   115  		q: Number{Real: 1, Imag: 0, Jmag: 0, Kmag: 1}, r: Number{Real: 2},
   116  		want: Number{Real: 0, Imag: 0, Jmag: 0, Kmag: 2},
   117  	},
   118  	{
   119  		q: Number{Real: 0, Imag: 1, Jmag: 1, Kmag: 1}, r: Number{Real: 2},
   120  		want: Number{Real: -3, Imag: 0, Jmag: 0, Kmag: 0},
   121  	},
   122  	{
   123  		q: Number{Real: 0, Imag: 0, Jmag: 1, Kmag: 1}, r: Number{Real: 2},
   124  		want: Number{Real: -2, Imag: 0, Jmag: 0, Kmag: 0},
   125  	},
   126  	{
   127  		q: Number{Real: 0, Imag: 0, Jmag: 0, Kmag: 1}, r: Number{Real: 2},
   128  		want: Number{Real: -1, Imag: 0, Jmag: 0, Kmag: 0},
   129  	},
   130  
   131  	{
   132  		q: Number{Real: 1, Imag: 1, Jmag: 1, Kmag: 1}, r: Number{Real: math.Pi},
   133  		want: Number{Real: -8.728144138959564, Imag: -0.7527136547040768, Jmag: -0.7527136547040768, Kmag: -0.7527136547040768},
   134  	},
   135  	{
   136  		q: Number{Real: 1, Imag: 0, Jmag: 1, Kmag: 1}, r: Number{Real: math.Pi},
   137  		want: Number{Real: -5.561182514695044, Imag: 0, Jmag: 0.5556661490713818, Kmag: 0.5556661490713818},
   138  	},
   139  	{
   140  		q: Number{Real: 1, Imag: 0, Jmag: 0, Kmag: 1}, r: Number{Real: math.Pi},
   141  		want: Number{Real: -2.320735561810013, Imag: 0, Jmag: 0, Kmag: 1.8544983901925216},
   142  	},
   143  	{
   144  		q: Number{Real: 0, Imag: 1, Jmag: 1, Kmag: 1}, r: Number{Real: math.Pi},
   145  		want: Number{Real: 1.2388947209955585, Imag: -3.162774128856231, Jmag: -3.162774128856231, Kmag: -3.162774128856231},
   146  	},
   147  	{
   148  		q: Number{Real: 0, Imag: 0, Jmag: 1, Kmag: 1}, r: Number{Real: math.Pi},
   149  		want: Number{Real: 0.6552860151073727, Imag: 0, Jmag: -2.0488506614051922, Kmag: -2.0488506614051922},
   150  	},
   151  	{
   152  		q: Number{Real: 0, Imag: 0, Jmag: 0, Kmag: 1}, r: Number{Real: math.Pi},
   153  		want: Number{Real: 0.22058404074969779, Imag: 0, Jmag: 0, Kmag: -0.9753679720836315},
   154  	},
   155  
   156  	{
   157  		q: Number{Real: 1, Imag: 1, Jmag: 1, Kmag: 1}, r: Number{Real: 3},
   158  		want: Number{Real: -8, Imag: 0, Jmag: 0, Kmag: 0},
   159  	},
   160  	{
   161  		q: Number{Real: 1, Imag: 0, Jmag: 1, Kmag: 1}, r: Number{Real: 3},
   162  		want: Number{Real: -5, Imag: 0, Jmag: 1, Kmag: 1},
   163  	},
   164  	{
   165  		q: Number{Real: 1, Imag: 0, Jmag: 0, Kmag: 1}, r: Number{Real: 3},
   166  		want: Number{Real: -2, Imag: 0, Jmag: 0, Kmag: 2},
   167  	},
   168  	{
   169  		q: Number{Real: 0, Imag: 1, Jmag: 1, Kmag: 1}, r: Number{Real: 3},
   170  		want: Number{Real: 0, Imag: -3, Jmag: -3, Kmag: -3},
   171  	},
   172  	{
   173  		q: Number{Real: 0, Imag: 0, Jmag: 1, Kmag: 1}, r: Number{Real: 3},
   174  		want: Number{Real: 0, Imag: 0, Jmag: -2, Kmag: -2},
   175  	},
   176  	{
   177  		q: Number{Real: 0, Imag: 0, Jmag: 0, Kmag: 1}, r: Number{Real: 3},
   178  		want: Number{Real: 0, Imag: 0, Jmag: 0, Kmag: -1},
   179  	},
   180  }
   181  
   182  func TestPow(t *testing.T) {
   183  	t.Parallel()
   184  	const tol = 1e-14
   185  	for _, test := range powTests {
   186  		got := Pow(test.q, test.r)
   187  		if !equalApprox(got, test.want, tol) {
   188  			t.Errorf("unexpected result for Pow(%v, %v): got:%v want:%v", test.q, test.r, got, test.want)
   189  		}
   190  	}
   191  }
   192  
   193  var sqrtTests = []struct {
   194  	q    Number
   195  	want Number
   196  }{
   197  	{q: Number{}, want: Number{}},
   198  	// Expected velues below are from pyquaternion.
   199  	{
   200  		q:    Number{Real: 1, Imag: 1, Jmag: 1, Kmag: 1},
   201  		want: Number{Real: 1.2247448713915892, Imag: 0.4082482904638631, Jmag: 0.4082482904638631, Kmag: 0.4082482904638631},
   202  	},
   203  	{
   204  		q:    Number{Real: 1, Imag: 0, Jmag: 1, Kmag: 1},
   205  		want: Number{Real: 1.1687708944803676, Imag: 0, Jmag: 0.42779983858367593, Kmag: 0.42779983858367593},
   206  	},
   207  	{
   208  		q:    Number{Real: 1, Imag: 0, Jmag: 0, Kmag: 1},
   209  		want: Number{Real: 1.0986841134678098, Imag: 0, Jmag: 0, Kmag: 0.45508986056222733},
   210  	},
   211  	{
   212  		q:    Number{Real: 0, Imag: 1, Jmag: 1, Kmag: 1},
   213  		want: Number{Real: 0.9306048591020996, Imag: 0.5372849659117709, Jmag: 0.5372849659117709, Kmag: 0.5372849659117709},
   214  	},
   215  	{
   216  		q:    Number{Real: 0, Imag: 0, Jmag: 1, Kmag: 1},
   217  		want: Number{Real: 0.8408964152537146, Imag: 0, Jmag: 0.5946035575013604, Kmag: 0.5946035575013604},
   218  	},
   219  	{
   220  		q:    Number{Real: 0, Imag: 0, Jmag: 0, Kmag: 1},
   221  		want: Number{Real: 0.7071067811865476, Imag: 0, Jmag: 0, Kmag: 0.7071067811865475},
   222  	},
   223  }
   224  
   225  func TestSqrt(t *testing.T) {
   226  	t.Parallel()
   227  	const tol = 1e-14
   228  	for _, test := range sqrtTests {
   229  		got := Sqrt(test.q)
   230  		if !equalApprox(got, test.want, tol) {
   231  			t.Errorf("unexpected result for Sqrt(%v): got:%v want:%v", test.q, got, test.want)
   232  		}
   233  	}
   234  }