github.com/wzzhu/tensor@v0.9.24/genlib2/generic_utils.go (about)

     1  package main
     2  
     3  import (
     4  	"io"
     5  	"text/template"
     6  )
     7  
     8  const rangeRaw = `// Range creates a ranged array with a given type. It panics if the Dtype is not supported or does not represent a naturally orderable type (strings, pointers etc)
     9  // Do note that the range algorithm is very simple, and simply does increments or decrements of 1. This means for floating point types
    10  // you're not able to create a range with a 0.1 increment step, and for complex number types, the imaginary part will always be 0i
    11  func Range(dt Dtype, start, end int) interface{} {
    12  	size := end - start
    13  	incr := true
    14  	if start > end {
    15  		incr = false
    16  		size = start - end
    17  	}
    18  
    19  	if size < 0 {
    20  		panic("Cannot create a range that is negative in size")
    21  	}
    22  	switch dt.Kind(){
    23  	{{range .Kinds -}}
    24  		{{if isParameterized . -}}
    25  		{{else -}}
    26  		{{if isRangeable . -}}
    27  	case reflect.{{reflectKind .}}:
    28  		{{if hasPrefix .String "float" -}}
    29  			return vec{{short . | lower}}.Range(start, end)
    30  		{{else -}}
    31  			retVal := make([]{{asType .}}, size)
    32  			{{if eq .String "complex64" -}}
    33  			for i, v := 0, complex(float32(start), float32(0.0)); i < size; i++ {
    34  			{{else if eq .String "complex128" -}}
    35  			for i, v := 0, complex(float64(start), float64(0.0)); i < size; i++ {
    36  			{{else -}}
    37  			for i, v := 0, {{asType .}}(start); i < size; i++ {
    38  			{{end -}}
    39  				retVal[i] = v
    40  				if incr {
    41  					v++
    42  				} else{
    43  					v--
    44  				}
    45  			}
    46  			return retVal
    47  		{{end -}}
    48  		{{end -}}
    49  		{{end -}}
    50  	{{end -}}
    51  	default:
    52  		err := errors.Errorf("Unrangeable Type %v", dt)
    53  		panic(err)
    54  	}
    55  }
    56  `
    57  
    58  const randomRaw = `// Random creates an array of random numbers of the given type.
    59  // For complex Dtypes, the imaginary component will be 0.
    60  //
    61  // This function is only useful in cases where the randomness is not vital. 
    62  func Random(dt Dtype, size int) interface{} {
    63  	r := rand.New(rand.NewSource(1337))
    64  	switch dt.Kind() {
    65  	{{range .Kinds -}}
    66  	{{if isNumber . -}}
    67  	case reflect.{{reflectKind .}}:
    68  		retVal := make([]{{asType .}}, size)
    69  		for i := range retVal {
    70  			retVal[i] = {{if hasPrefix .String "int" -}}
    71  				{{asType .}}(r.Int())
    72  			{{else if hasPrefix .String "uint" -}}
    73  				{{asType .}}(r.Uint32())
    74  			{{else if hasPrefix .String "complex64" -}}
    75  				complex(r.Float32(), float32(0))
    76  			{{else if hasPrefix .String "complex128" -}}
    77  				complex(r.Float64(), float64(0))
    78  			{{else if eq .String "float64" -}}
    79  				rand.NormFloat64()
    80  			{{else if eq .String "float32" -}}
    81  				float32(r.NormFloat64())
    82  			{{end -}}
    83  		}
    84  		return retVal
    85  	{{end -}}
    86  	{{end -}}
    87  	}
    88  	panic("unreachable")
    89  }
    90  `
    91  
    92  var (
    93  	Range  *template.Template
    94  	Random *template.Template
    95  )
    96  
    97  func init() {
    98  	Range = template.Must(template.New("Range").Funcs(funcs).Parse(rangeRaw))
    99  	Random = template.Must(template.New("Random").Funcs(funcs).Parse(randomRaw))
   100  }
   101  
   102  func generateUtils(f io.Writer, generic Kinds) {
   103  	Range.Execute(f, generic)
   104  	Random.Execute(f, generic)
   105  }