diff --git a/.gitignore b/.gitignore index 41c277a2..18a368ba 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ llgo_autogen.ll stories*.bin .DS_Store err.log +numpy.txt _go/ _runtime/ diff --git a/.gitmodules b/.gitmodules index 0f07cd1c..0f3ceb95 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "x/llama2/llama2.c"] path = x/llama2/llama2.c url = https://github.com/karpathy/llama2.c.git -[submodule "x/sqlite/sqlite"] - path = x/sqlite/sqlite - url = https://github.com/sqlite/sqlite.git diff --git a/README.md b/README.md index 0a23d509..1d891bea 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ llgo - A Go compiler based on LLVM [![GoDoc](https://pkg.go.dev/badge/github.com/goplus/llgo.svg)](https://pkg.go.dev/github.com/goplus/llgo) [![Language](https://img.shields.io/badge/language-Go+-blue.svg)](https://github.com/goplus/gop) -This is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python. It's a subproject of [the Go+ project](https://github.com/goplus/gop). +LLGo is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python. It's a subproject of [the Go+ project](https://github.com/goplus/gop). + ## C standard libary support @@ -22,14 +23,40 @@ func main() { } ``` -This is a simple example of calling the C `printf` function to print `Hello world`. Here, `c.Str` is not a function for converting a Go string to a C string, but a built-in instruction supported by llgo for generating a C string constant. +This is a simple example of calling the C `printf` function to print `Hello world`. Here, `c.Str` is not a function for converting a Go string to a C string, but a built-in instruction supported by `llgo` for generating a C string constant. + +The `_demo` directory contains some C standard libary related demos (it start with `_` to prevent the `go` command from compiling it): + +* [hello](_demo/hello/hello.go): call C `printf` to print `Hello world` +* [concat](_demo/concat/concat.go): call C `fprintf` with `stderr` +* [qsort](_demo/qsort/qsort.go): call C function with a callback (eg. `qsort`) + +To run these demos (If you haven't installed `llgo` yet, please refer to [How to install](#how-to-install)): + +```sh +export LLGOROOT=`pwd` +cd # eg. cd _demo/hello +llgo run . +``` See [github.com/goplus/llgo/c](https://pkg.go.dev/github.com/goplus/llgo/c) for more detials. ## Python support -You can import a Python library in llgo! For example: +You can import a Python library in LLGo! + +And you can import any Python library into `llgo` through a program called `llpyg` (See [Development tools](#development-tools)). The currently imported libraries include: + +* [sys](https://pkg.go.dev/github.com/goplus/llgo/py/sys) +* [os](https://pkg.go.dev/github.com/goplus/llgo/py/os) +* [math](https://pkg.go.dev/github.com/goplus/llgo/py/math) +* [json](https://pkg.go.dev/github.com/goplus/llgo/py/json) +* [inspect](https://pkg.go.dev/github.com/goplus/llgo/py/inspect) +* [statistics](https://pkg.go.dev/github.com/goplus/llgo/py/statistics) +* [numpy](https://pkg.go.dev/github.com/goplus/llgo/py/numpy) + +Here is an example using the Python `math` library: ```go package main @@ -48,12 +75,117 @@ func main() { Here, We call `py.Float(2)` to create a Python number 2, and pass it to Python’s `math.sqrt` to get `x`. Then use `x.Float64()` to convert x to Go's `float64` type, and print the value through the C `printf` function. +Let's look at a slightly more complex example. For example, we use `numpy` to calculate: + +```go +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/py" + "github.com/goplus/llgo/py/numpy" +) + +func main() { + a := py.List( + py.List(1.0, 2.0, 3.0), + py.List(4.0, 5.0, 6.0), + py.List(7.0, 8.0, 9.0), + ) + b := py.List( + py.List(9.0, 8.0, 7.0), + py.List(6.0, 5.0, 4.0), + py.List(3.0, 2.0, 1.0), + ) + x := numpy.Add(a, b) + c.Printf(c.Str("a+b = %s\n"), x.Str().CStr()) +} +``` + +Here we define two 3x3 matrices a and b, add them to get x, and then print the result. + +The `_pydemo` directory contains some python related demos: + +* [callpy](_pydemo/callpy/callpy.go): call Python standard library function `math.sqrt` +* [pi](_pydemo/pi/pi.go): print python constants `math.pi` +* [statistics](_pydemo/statistics/statistics.go): define a python list and call `statistics.mean` to get the mean +* [matrix](_pydemo/matrix/matrix.go): a basic `numpy` demo + +To run these demos, you need to set the `LLGO_LIB_PYTHON` environment variable first. + +If Python is in the search path for `clang` linking, then `LLGO_LIB_PYTHON` only needs to be set to the name of the Python library. For example: + +```sh +export LLGO_LIB_PYTHON=python3.12 +``` + +You can also specify the path to tell `llgo` where the Python library is located: + +```sh +export LLGO_LIB_PYTHON=/foo/bar/python3.12 +``` + +For example, `/opt/homebrew/Frameworks/Python.framework/Versions/3.12/libpython3.12.dylib` is a typical python library location under macOS. So we should set it like this: + +```sh +export LLGO_LIB_PYTHON=/opt/homebrew/Frameworks/Python.framework/Versions/3.12/python3.12 +``` + +Note that the file name must be written in a platform-independent format, using `python3.12` instead of `libpython3.12.dylib`. + +Then you can run the demos: + +```sh +export LLGOROOT=`pwd` +cd # eg. cd _pydemo/callpy +llgo run . +``` + See [github.com/goplus/llgo/py](https://pkg.go.dev/github.com/goplus/llgo/py) for more detials. ## Other frequently used libraries -TODO +LLGo can easily import any libraries from the C ecosystem. Currently, this import process is still manual, but in the future, it will be automated similar to Python library imports. + +The currently imported libraries include: + +* [llama2.c](https://pkg.go.dev/github.com/goplus/llgo/x/llama2) +* [cjson](https://pkg.go.dev/github.com/goplus/llgo/x/cjson) +* [sqlite](https://pkg.go.dev/github.com/goplus/llgo/x/sqlite) + +Here are some examples related to them: + +* [llama2-c](_demo/llama2-c): inference Llama 2 (It's the first llgo AI example) +* [mkjson](x/cjson/_demo/mkjson/mkjson.go): create a json object and print it +* [sqlitedemo](x/sqlite/_demo/sqlitedemo/demo.go): a basic sqlite demo + + +## Go syntax support + +The priority of `llgo` feature iteration is: + +* Popular C/Python libraries +* Full Go syntax +* Go standard libraries +* Popular Go packages + +Common Go syntax is already supported. Except for the following, which needs to be improved: + +* interface (Limited support) +* map (Very limited support) +* panic (Limited support) +* recover (Not supported yet) +* defer (Not supported yet) +* gc (Not supported yet) +* chan (Not supported yet) +* goroutine (Not supported yet) +* generics (Not supported yet) + +Here are some examples related to Go syntax: + +* [concat](_demo/concat/concat.go): define a variadic function +* [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function) ## How to install @@ -83,45 +215,25 @@ go install -v ./... TODO -## Demo +## Development tools -The `_demo` directory contains our demos (it start with `_` to prevent the `go` command from compiling it): +* [pydump](chore/_xtool/pydump): It's the first program compiled by `llgo` (NOT `go`) in a production environment. It outputs symbol information (functions, variables, and constants) from a Python library in JSON format, preparing for the generation of corresponding packages in `llgo`. +* [llpyg](chore/llpyg): It is used to automatically convert Python libraries into Go packages that `llgo` can import. It depends on `pydump` to accomplish the task. +* [llgen](chore/llgen): It is used to compile Go packages into LLVM IR files (*.ll). +* [ssadump](chore/ssadump): It is a Go SSA builder and interpreter. -* [hello](_demo/hello/hello.go): call C printf to print `Hello world` -* [concat](_demo/concat/concat.go): call C fprintf with stderr, and Go variadic function -* [qsort](_demo/qsort/qsort.go): call C function with a callback (eg. qsort) -* [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function) -* [llama2-c](_demo/llama2-c): inference Llama 2 (It's the first llgo AI example) - -And the `_pydemo` directory contains python related demos: - -* [callpy](_pydemo/callpy/callpy.go): call Python standard library function `math.sqrt` - - -### How to run demos - -To run the demos in directory `_demo`: +How do I generate these tools? ```sh -cd # eg. cd _demo/genints -llgo run . +go install -v ./... # compile all tools except pydump +cd chore/_xtool +llgo install ./... # compile pydump ``` -To run the demos in directory `_pydemo`, you need to set the `LLGO_LIB_PYTHON` environment variable first. Assuming you use Python 3.12, and the `libpython3.12.so` (or `libpython3.12.dylib` or `python3.12.lib`) file is in the /foo/bar directory, then you need to set `LLGO_LIB_PYTHON` to: +## Key modules -```sh -export LLGO_LIB_PYTHON=/foo/bar/python3.12 -``` +Below are the key modules for understanding the implementation principles of `llgo`: -For example, `/opt/homebrew/Frameworks/Python.framework/Versions/3.12/libpython3.12.dylib` is a typical python lib location under macOS. So we should set it like this: - -```sh -export LLGO_LIB_PYTHON=/opt/homebrew/Frameworks/Python.framework/Versions/3.12/python3.12 -``` - -Then you can run the demos in directory `_pydemo`: - -```sh -cd # eg. cd _pydemo/callpy -llgo run . -``` +* [llgo/ssa](https://pkg.go.dev/github.com/goplus/llgo/ssa): It generates LLVM IR files (LLVM SSA) using the semantics (interfaces) of Go SSA. Although `LLVM SSA` and `Go SSA` are both IR languages, they work at completely different levels. `LLVM SSA` is closer to machine code, which abstracts different instruction sets. While `Go SSA` is closer to a high-level language. We can think of it as the instruction set of the `Go computer`. `llgo/ssa` is not just limited to the `llgo` compiler. If we view it as the high-level expressive power of `LLVM`, you'll find it very useful. Prior to `llgo/ssa`, you had to operate `LLVM` using machine code semantics. But now, with the advanced SSA form (in the semantics of Go SSA), you can conveniently utilize `LLVM`. +* [llgo/cl](https://pkg.go.dev/github.com/goplus/llgo/cl): It is the core of the llgo compiler. It converts a Go package into LLVM IR files. It depends on `llgo/ssa`. +* [llgo/internal/build](https://pkg.go.dev/github.com/goplus/llgo/internal/build): It strings together the entire compilation process of `llgo`. It depends on `llgo/ssa` and `llgo/cl`. diff --git a/_pydemo/matrix/matrix.go b/_pydemo/matrix/matrix.go new file mode 100644 index 00000000..5567d172 --- /dev/null +++ b/_pydemo/matrix/matrix.go @@ -0,0 +1,22 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/py" + "github.com/goplus/llgo/py/numpy" +) + +func main() { + a := py.List( + py.List(1.0, 2.0, 3.0), + py.List(4.0, 5.0, 6.0), + py.List(7.0, 8.0, 9.0), + ) + b := py.List( + py.List(9.0, 8.0, 7.0), + py.List(6.0, 5.0, 4.0), + py.List(3.0, 2.0, 1.0), + ) + x := numpy.Add(a, b) + c.Printf(c.Str("a+b = %s\n"), x.Str().CStr()) +} diff --git a/_pydemo/pi/pi.go b/_pydemo/pi/pi.go new file mode 100644 index 00000000..239bc543 --- /dev/null +++ b/_pydemo/pi/pi.go @@ -0,0 +1,10 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/py/math" +) + +func main() { + c.Printf(c.Str("pi = %f\n"), math.Pi.Float64()) +} diff --git a/_pydemo/statistics/statistics.go b/_pydemo/statistics/statistics.go new file mode 100644 index 00000000..4936f752 --- /dev/null +++ b/_pydemo/statistics/statistics.go @@ -0,0 +1,13 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/py" + "github.com/goplus/llgo/py/statistics" +) + +func main() { + list := py.List(1.0, 2.0, 3.0, 4.0, 4.0) + mean := statistics.Mean(list) + c.Printf(c.Str("mean(1, 2, 3, 4, 4) = %f\n"), mean.Float64()) +} diff --git a/c/c.go b/c/c.go index 6db9e572..500d29fe 100644 --- a/c/c.go +++ b/c/c.go @@ -25,12 +25,16 @@ const ( ) type ( - Char = int8 - Int = C.int - Uint = C.uint - Float = float32 - Pointer = unsafe.Pointer - FilePtr = unsafe.Pointer + Char = int8 + Int = C.int + Uint = C.uint + Long = int32 + Ulong = uint32 + LongLong = int64 + UlongLong = uint64 + Float = float32 + Pointer = unsafe.Pointer + FilePtr = unsafe.Pointer ) type integer interface { diff --git a/_xtool/llpyg/llpyg.go b/chore/_xtool/pydump/pydump.go similarity index 55% rename from _xtool/llpyg/llpyg.go rename to chore/_xtool/pydump/pydump.go index 9dac48a5..bf712b0d 100644 --- a/_xtool/llpyg/llpyg.go +++ b/chore/_xtool/pydump/pydump.go @@ -20,32 +20,41 @@ import ( "github.com/goplus/llgo/c" "github.com/goplus/llgo/py" "github.com/goplus/llgo/py/inspect" + "github.com/goplus/llgo/x/cjson" ) func main() { if c.Argc < 2 { - c.Fprintf(c.Stderr, c.Str("Usage: llpyg []\n")) + c.Fprintf(c.Stderr, c.Str("Usage: pydump \n")) return } - pyLib := c.Index(c.Argv, 1) - destDir := c.Str(".") - if c.Argc > 2 { - destDir = c.Index(c.Argv, 2) - } - c.Fprintf(c.Stderr, c.Str("pyLib: %s, destDir: %s\n"), pyLib, destDir) py.Initialize() + + root := cjson.Object() + root.SetItem(c.Str("name"), cjson.String(pyLib)) + + items := cjson.Array() mod := py.ImportModule(pyLib) - dict := mod.ModuleGetDict() - items := dict.DictItems() - for i, n := uintptr(0), items.ListLen(); i < n; i++ { - item := items.ListItem(i) - key := item.TupleItem(0) - val := item.TupleItem(1) + keys := mod.ModuleGetDict().DictKeys() + for i, n := uintptr(0), keys.ListLen(); i < n; i++ { + key := keys.ListItem(i) + val := mod.GetAttr(key) + doc := val.GetAttrString(c.Str("__doc__")) + sym := cjson.Object() + sym.SetItem(c.Str("type"), cjson.String(val.Type().TypeName().CStr())) + sym.SetItem(c.Str("name"), cjson.String(key.CStr())) + if doc != nil { + sym.SetItem(c.Str("doc"), cjson.String(doc.CStr())) + } if val.Callable() != 0 { sig := inspect.Signature(val) - c.Fprintf(c.Stderr, c.Str("%s: %s\n"), key.CStr(), sig.Str().CStr()) + sym.SetItem(c.Str("sig"), cjson.String(sig.Str().CStr())) } + items.AddItem(sym) } + root.SetItem(c.Str("items"), items) + + c.Printf(c.Str("%s\n"), root.CStr()) } diff --git a/chore/llpyg/llpyg.go b/chore/llpyg/llpyg.go new file mode 100644 index 00000000..251b2961 --- /dev/null +++ b/chore/llpyg/llpyg.go @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * 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 main + +import ( + "bytes" + "encoding/json" + "fmt" + "go/ast" + "go/token" + "go/types" + "log" + "os" + "os/exec" + "strings" + + "github.com/goplus/gogen" + "github.com/goplus/llgo/ssa" +) + +type symbol struct { + Name string `json:"name"` + Type string `json:"type"` + Doc string `json:"doc"` + Sig string `json:"sig"` +} + +type module struct { + Name string `json:"name"` + Items []*symbol `json:"items"` +} + +func main() { + if len(os.Args) < 2 { + fmt.Fprintln(os.Stderr, "Usage: llpyg ") + return + } + pyLib := os.Args[1] + + var out bytes.Buffer + pydump := exec.Command("pydump", pyLib) + pydump.Stdout = &out + pydump.Run() + + var mod module + json.Unmarshal(out.Bytes(), &mod) + + modName := mod.Name + if modName == "" { + log.Printf("import module %s failed\n", pyLib) + os.Exit(1) + } + pkg := gogen.NewPackage("", modName, nil) + pkg.Import("unsafe").MarkForceUsed(pkg) // import _ "unsafe" + py := pkg.Import("github.com/goplus/llgo/py") // import "github.com/goplus/llgo/py" + + f := func(cb *gogen.CodeBuilder) int { + cb.Val("py." + modName) + return 1 + } + defs := pkg.NewConstDefs(pkg.Types.Scope()) + defs.New(f, 0, 0, nil, "LLGoPackage") + + obj := py.Ref("Object").(*types.TypeName).Type().(*types.Named) + objPtr := types.NewPointer(obj) + ret := types.NewTuple(pkg.NewParam(0, "", objPtr)) + + ctx := &context{pkg, obj, objPtr, ret, py} + for _, sym := range mod.Items { + switch sym.Type { + case "builtin_function_or_method", "function", "ufunc", "method-wrapper": + ctx.genFunc(pkg, sym) + case "str", "float", "bool", "type", "dict", "tuple", "list", "object", + "module", "int", "set", "frozenset", "flags", "bool_": // skip + default: + t := sym.Type + if len(t) > 0 && (t[0] >= 'a' && t[0] <= 'z') && !strings.HasSuffix(t, "_info") { + log.Panicln("unsupport type:", sym.Type) + } + } + } + pkg.WriteTo(os.Stdout) +} + +type context struct { + pkg *gogen.Package + obj *types.Named + objPtr *types.Pointer + ret *types.Tuple + py gogen.PkgRef +} + +func (ctx *context) genFunc(pkg *gogen.Package, sym *symbol) { + name, symSig := sym.Name, sym.Sig + if len(name) == 0 || name[0] == '_' { + return + } + params, variadic, skip := ctx.genParams(pkg, symSig) + if skip { + // TODO(xsw): don't skip any func + log.Println("skip func:", name, symSig) + return + } + name = genName(name, -1) + sig := types.NewSignatureType(nil, nil, nil, params, ctx.ret, variadic) + fn := pkg.NewFuncDecl(token.NoPos, name, sig) + list := ctx.genDoc(sym.Doc) + list = append(list, emptyCommentLine) + list = append(list, ctx.genLinkname(name, sym)) + fn.SetComments(pkg, &ast.CommentGroup{List: list}) + // fn.BodyStart(pkg).End() +} + +func (ctx *context) genParams(pkg *gogen.Package, sig string) (*types.Tuple, bool, bool) { + if sig == "" { + return nil, false, true + } + sig = strings.TrimSuffix(strings.TrimPrefix(sig, "("), ")") + if sig == "" { // empty params + return nil, false, false + } + parts := strings.Split(sig, ",") + n := len(parts) + objPtr := ctx.objPtr + list := make([]*types.Var, 0, n) + for i := 0; i < n; i++ { + part := strings.TrimSpace(parts[i]) + if part == "/" { + continue + } + if part == "*" { + break + } + if strings.HasPrefix(part, "*") { + if part[1] != '*' { + list = append(list, ssa.VArg()) + return types.NewTuple(list...), true, false + } + return types.NewTuple(list...), false, false + } + pos := strings.IndexByte(part, '=') + if pos >= 0 { + if strings.HasPrefix(part[pos+1:], "<") { // skip complex default value + return nil, false, true + } + part = part[:pos] + } + list = append(list, pkg.NewParam(0, genName(part, 0), objPtr)) + } + return types.NewTuple(list...), false, false +} + +func genName(name string, idxDontTitle int) string { + parts := strings.Split(name, "_") + for i, part := range parts { + if i != idxDontTitle && part != "" { + if c := part[0]; c >= 'a' && c <= 'z' { + part = string(c+'A'-'a') + part[1:] + } + parts[i] = part + } + } + name = strings.Join(parts, "") + switch name { + case "default", "func", "": + name += "_" + } + return name +} + +func (ctx *context) genLinkname(name string, sym *symbol) *ast.Comment { + return &ast.Comment{Text: "//go:linkname " + name + " py." + sym.Name} +} + +func (ctx *context) genDoc(doc string) []*ast.Comment { + lines := strings.Split(doc, "\n") + list := make([]*ast.Comment, len(lines), len(lines)+2) + for i, line := range lines { + list[i] = &ast.Comment{Text: "// " + line} + } + return list +} + +var ( + emptyCommentLine = &ast.Comment{Text: "//"} +) diff --git a/cl/_testdata/print/out.ll b/cl/_testdata/print/out.ll index af0ea398..2e91fdad 100644 --- a/cl/_testdata/print/out.ll +++ b/cl/_testdata/print/out.ll @@ -51,7 +51,7 @@ _llgo_0: define void @main.gwrite(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { _llgo_0: - %1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) + %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1 %2 = icmp eq i64 %1, 0 br i1 %2, label %_llgo_1, label %_llgo_2 @@ -680,7 +680,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 define void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { _llgo_0: - %1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) + %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1 br label %_llgo_1 _llgo_1: ; preds = %_llgo_5, %_llgo_0 @@ -690,7 +690,7 @@ _llgo_1: ; preds = %_llgo_5, %_llgo_0 br i1 %4, label %_llgo_2, label %_llgo_3 _llgo_2: ; preds = %_llgo_1 - %5 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) + %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0 %6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %5, i64 %3 %7 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, align 8 %8 = icmp ne i64 %3, 0 @@ -783,8 +783,6 @@ _llgo_0: declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) -declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice") - declare i32 @printf(ptr, ...) declare void @"github.com/goplus/llgo/internal/runtime.init"() @@ -802,5 +800,3 @@ declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llg declare { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr) declare { %"github.com/goplus/llgo/internal/runtime.String", i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2String"(%"github.com/goplus/llgo/internal/runtime.iface", ptr) - -declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice") diff --git a/cl/_testdata/vargs/out.ll b/cl/_testdata/vargs/out.ll index 56930b8e..4657338e 100644 --- a/cl/_testdata/vargs/out.ll +++ b/cl/_testdata/vargs/out.ll @@ -48,7 +48,7 @@ _llgo_0: define void @main.test(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { _llgo_0: - %1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) + %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1 br label %_llgo_1 _llgo_1: ; preds = %_llgo_2, %_llgo_0 @@ -58,7 +58,7 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0 br i1 %4, label %_llgo_2, label %_llgo_3 _llgo_2: ; preds = %_llgo_1 - %5 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) + %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0 %6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %5, i64 %3 %7 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, align 8 %8 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2) @@ -80,10 +80,6 @@ declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llg declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64) -declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice") - -declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice") - declare i64 @"github.com/goplus/llgo/internal/runtime.I2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr) declare i32 @printf(ptr, ...) diff --git a/cl/_testpy/gcd/in.go b/cl/_testpy/gcd/in.go new file mode 100644 index 00000000..309cdf3c --- /dev/null +++ b/cl/_testpy/gcd/in.go @@ -0,0 +1,12 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/py" + "github.com/goplus/llgo/py/math" +) + +func main() { + x := math.Gcd(py.Long(60), py.Long(20), py.Long(25)) + c.Printf(c.Str("gcd(60, 20, 25) = %d\n"), x.Long()) +} diff --git a/cl/_testpy/gcd/out.ll b/cl/_testpy/gcd/out.ll new file mode 100644 index 00000000..ccee1b2f --- /dev/null +++ b/cl/_testpy/gcd/out.ll @@ -0,0 +1,59 @@ +; ModuleID = 'main' +source_filename = "main" + +@"main.init$guard" = global ptr null +@__llgo_argc = global ptr null +@__llgo_argv = global ptr null +@__llgo_py.math.gcd = linkonce global ptr null +@0 = private unnamed_addr constant [22 x i8] c"gcd(60, 20, 25) = %d\0A\00", align 1 +@__llgo_py.math = external global ptr +@1 = private unnamed_addr constant [4 x i8] c"gcd\00", align 1 + +define void @main.init() { +_llgo_0: + %0 = load i1, ptr @"main.init$guard", align 1 + br i1 %0, label %_llgo_2, label %_llgo_1 + +_llgo_1: ; preds = %_llgo_0 + store i1 true, ptr @"main.init$guard", align 1 + call void @"github.com/goplus/llgo/py/math.init"() + %1 = load ptr, ptr @__llgo_py.math, align 8 + call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @1, ptr @__llgo_py.math.gcd, ptr null) + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +define void @main(i32 %0, ptr %1) { +_llgo_0: + call void @Py_Initialize() + store i32 %0, ptr @__llgo_argc, align 4 + store ptr %1, ptr @__llgo_argv, align 8 + call void @"github.com/goplus/llgo/internal/runtime.init"() + call void @main.init() + %2 = call ptr @PyLong_FromLong(i32 60) + %3 = call ptr @PyLong_FromLong(i32 20) + %4 = call ptr @PyLong_FromLong(i32 25) + %5 = load ptr, ptr @__llgo_py.math.gcd, align 8 + %6 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %5, ptr %2, ptr %3, ptr %4, ptr null) + %7 = call i32 @PyLong_AsLong(ptr %6) + %8 = call i32 (ptr, ...) @printf(ptr @0, i32 %7) + ret void +} + +declare void @"github.com/goplus/llgo/py/math.init"() + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +declare ptr @PyLong_FromLong(i32) + +declare ptr @PyObject_CallFunctionObjArgs(ptr, ...) + +declare i32 @PyLong_AsLong(ptr) + +declare i32 @printf(ptr, ...) + +declare void @llgoLoadPyModSyms(ptr, ...) + +declare void @Py_Initialize() diff --git a/cl/_testpy/math/out.ll b/cl/_testpy/math/out.ll index f5feead3..70bdd7e5 100644 --- a/cl/_testpy/math/out.ll +++ b/cl/_testpy/math/out.ll @@ -1,7 +1,6 @@ ; ModuleID = 'math' source_filename = "math" -@__llgo_py.math.sqrt = external global ptr @"math.init$guard" = global ptr null @__llgo_py.math = linkonce global ptr null @0 = private unnamed_addr constant [5 x i8] c"math\00", align 1 diff --git a/cl/_testpy/matrix/in.go b/cl/_testpy/matrix/in.go new file mode 100644 index 00000000..ceecb933 --- /dev/null +++ b/cl/_testpy/matrix/in.go @@ -0,0 +1,24 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/py" + "github.com/goplus/llgo/py/numpy" +) + +func main() { + a := py.List( + py.List(1.0, 2.0, 3.0), + py.List(4.0, 5.0, 6.0), + py.List(7.0, 8.0, 9.0), + ) + b := py.List( + py.List(9.0, 8.0, 7.0), + py.List(6.0, 5.0, 4.0), + py.List(3.0, 2.0, 1.0), + ) + x := numpy.Add(a, b) + c.Printf(c.Str("a = %s\n"), a.Str().CStr()) + c.Printf(c.Str("a = %s\n"), b.Str().CStr()) + c.Printf(c.Str("a+b = %s\n"), x.Str().CStr()) +} diff --git a/cl/_testpy/matrix/out.ll b/cl/_testpy/matrix/out.ll new file mode 100644 index 00000000..956009c4 --- /dev/null +++ b/cl/_testpy/matrix/out.ll @@ -0,0 +1,121 @@ +; ModuleID = 'main' +source_filename = "main" + +@"main.init$guard" = global ptr null +@__llgo_argc = global ptr null +@__llgo_argv = global ptr null +@__llgo_py.numpy.add = linkonce global ptr null +@0 = private unnamed_addr constant [8 x i8] c"a = %s\0A\00", align 1 +@1 = private unnamed_addr constant [8 x i8] c"a = %s\0A\00", align 1 +@2 = private unnamed_addr constant [10 x i8] c"a+b = %s\0A\00", align 1 +@__llgo_py.numpy = external global ptr +@3 = private unnamed_addr constant [4 x i8] c"add\00", align 1 + +define void @main.init() { +_llgo_0: + %0 = load i1, ptr @"main.init$guard", align 1 + br i1 %0, label %_llgo_2, label %_llgo_1 + +_llgo_1: ; preds = %_llgo_0 + store i1 true, ptr @"main.init$guard", align 1 + call void @"github.com/goplus/llgo/py/numpy.init"() + %1 = load ptr, ptr @__llgo_py.numpy, align 8 + call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @3, ptr @__llgo_py.numpy.add, ptr null) + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +define void @main(i32 %0, ptr %1) { +_llgo_0: + call void @Py_Initialize() + store i32 %0, ptr @__llgo_argc, align 4 + store ptr %1, ptr @__llgo_argv, align 8 + call void @"github.com/goplus/llgo/internal/runtime.init"() + call void @main.init() + %2 = call ptr @PyList_New(i64 3) + %3 = call ptr @PyFloat_FromDouble(double 1.000000e+00) + %4 = call i32 @PyList_SetItem(ptr %2, i64 0, ptr %3) + %5 = call ptr @PyFloat_FromDouble(double 2.000000e+00) + %6 = call i32 @PyList_SetItem(ptr %2, i64 1, ptr %5) + %7 = call ptr @PyFloat_FromDouble(double 3.000000e+00) + %8 = call i32 @PyList_SetItem(ptr %2, i64 2, ptr %7) + %9 = call ptr @PyList_New(i64 3) + %10 = call ptr @PyFloat_FromDouble(double 4.000000e+00) + %11 = call i32 @PyList_SetItem(ptr %9, i64 0, ptr %10) + %12 = call ptr @PyFloat_FromDouble(double 5.000000e+00) + %13 = call i32 @PyList_SetItem(ptr %9, i64 1, ptr %12) + %14 = call ptr @PyFloat_FromDouble(double 6.000000e+00) + %15 = call i32 @PyList_SetItem(ptr %9, i64 2, ptr %14) + %16 = call ptr @PyList_New(i64 3) + %17 = call ptr @PyFloat_FromDouble(double 7.000000e+00) + %18 = call i32 @PyList_SetItem(ptr %16, i64 0, ptr %17) + %19 = call ptr @PyFloat_FromDouble(double 8.000000e+00) + %20 = call i32 @PyList_SetItem(ptr %16, i64 1, ptr %19) + %21 = call ptr @PyFloat_FromDouble(double 9.000000e+00) + %22 = call i32 @PyList_SetItem(ptr %16, i64 2, ptr %21) + %23 = call ptr @PyList_New(i64 3) + %24 = call i32 @PyList_SetItem(ptr %23, i64 0, ptr %2) + %25 = call i32 @PyList_SetItem(ptr %23, i64 1, ptr %9) + %26 = call i32 @PyList_SetItem(ptr %23, i64 2, ptr %16) + %27 = call ptr @PyList_New(i64 3) + %28 = call ptr @PyFloat_FromDouble(double 9.000000e+00) + %29 = call i32 @PyList_SetItem(ptr %27, i64 0, ptr %28) + %30 = call ptr @PyFloat_FromDouble(double 8.000000e+00) + %31 = call i32 @PyList_SetItem(ptr %27, i64 1, ptr %30) + %32 = call ptr @PyFloat_FromDouble(double 7.000000e+00) + %33 = call i32 @PyList_SetItem(ptr %27, i64 2, ptr %32) + %34 = call ptr @PyList_New(i64 3) + %35 = call ptr @PyFloat_FromDouble(double 6.000000e+00) + %36 = call i32 @PyList_SetItem(ptr %34, i64 0, ptr %35) + %37 = call ptr @PyFloat_FromDouble(double 5.000000e+00) + %38 = call i32 @PyList_SetItem(ptr %34, i64 1, ptr %37) + %39 = call ptr @PyFloat_FromDouble(double 4.000000e+00) + %40 = call i32 @PyList_SetItem(ptr %34, i64 2, ptr %39) + %41 = call ptr @PyList_New(i64 3) + %42 = call ptr @PyFloat_FromDouble(double 3.000000e+00) + %43 = call i32 @PyList_SetItem(ptr %41, i64 0, ptr %42) + %44 = call ptr @PyFloat_FromDouble(double 2.000000e+00) + %45 = call i32 @PyList_SetItem(ptr %41, i64 1, ptr %44) + %46 = call ptr @PyFloat_FromDouble(double 1.000000e+00) + %47 = call i32 @PyList_SetItem(ptr %41, i64 2, ptr %46) + %48 = call ptr @PyList_New(i64 3) + %49 = call i32 @PyList_SetItem(ptr %48, i64 0, ptr %27) + %50 = call i32 @PyList_SetItem(ptr %48, i64 1, ptr %34) + %51 = call i32 @PyList_SetItem(ptr %48, i64 2, ptr %41) + %52 = load ptr, ptr @__llgo_py.numpy.add, align 8 + %53 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %52, ptr %23, ptr %48, ptr null) + %54 = call ptr @PyObject_Str(ptr %23) + %55 = call ptr @PyUnicode_AsUTF8(ptr %54) + %56 = call i32 (ptr, ...) @printf(ptr @0, ptr %55) + %57 = call ptr @PyObject_Str(ptr %48) + %58 = call ptr @PyUnicode_AsUTF8(ptr %57) + %59 = call i32 (ptr, ...) @printf(ptr @1, ptr %58) + %60 = call ptr @PyObject_Str(ptr %53) + %61 = call ptr @PyUnicode_AsUTF8(ptr %60) + %62 = call i32 (ptr, ...) @printf(ptr @2, ptr %61) + ret void +} + +declare void @"github.com/goplus/llgo/py/numpy.init"() + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +declare ptr @PyList_New(i64) + +declare ptr @PyFloat_FromDouble(double) + +declare i32 @PyList_SetItem(ptr, i64, ptr) + +declare ptr @PyObject_CallFunctionObjArgs(ptr, ...) + +declare ptr @PyObject_Str(ptr) + +declare ptr @PyUnicode_AsUTF8(ptr) + +declare i32 @printf(ptr, ...) + +declare void @llgoLoadPyModSyms(ptr, ...) + +declare void @Py_Initialize() diff --git a/cl/_testpy/pi/in.go b/cl/_testpy/pi/in.go new file mode 100644 index 00000000..239bc543 --- /dev/null +++ b/cl/_testpy/pi/in.go @@ -0,0 +1,10 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/py/math" +) + +func main() { + c.Printf(c.Str("pi = %f\n"), math.Pi.Float64()) +} diff --git a/cl/_testpy/pi/out.ll b/cl/_testpy/pi/out.ll new file mode 100644 index 00000000..696cb264 --- /dev/null +++ b/cl/_testpy/pi/out.ll @@ -0,0 +1,49 @@ +; ModuleID = 'main' +source_filename = "main" + +@"main.init$guard" = global ptr null +@__llgo_argc = global ptr null +@__llgo_argv = global ptr null +@0 = private unnamed_addr constant [9 x i8] c"pi = %f\0A\00", align 1 +@__llgo_py.math = external global ptr +@1 = private unnamed_addr constant [3 x i8] c"pi\00", align 1 + +define void @main.init() { +_llgo_0: + %0 = load i1, ptr @"main.init$guard", align 1 + br i1 %0, label %_llgo_2, label %_llgo_1 + +_llgo_1: ; preds = %_llgo_0 + store i1 true, ptr @"main.init$guard", align 1 + call void @"github.com/goplus/llgo/py/math.init"() + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +define void @main(i32 %0, ptr %1) { +_llgo_0: + call void @Py_Initialize() + store i32 %0, ptr @__llgo_argc, align 4 + store ptr %1, ptr @__llgo_argv, align 8 + call void @"github.com/goplus/llgo/internal/runtime.init"() + call void @main.init() + %2 = load ptr, ptr @__llgo_py.math, align 8 + %3 = call ptr @PyObject_GetAttrString(ptr %2, ptr @1) + %4 = call double @PyFloat_AsDouble(ptr %3) + %5 = call i32 (ptr, ...) @printf(ptr @0, double %4) + ret void +} + +declare void @"github.com/goplus/llgo/py/math.init"() + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +declare ptr @PyObject_GetAttrString(ptr, ptr) + +declare double @PyFloat_AsDouble(ptr) + +declare i32 @printf(ptr, ...) + +declare void @Py_Initialize() diff --git a/cl/_testpy/pow/in.go b/cl/_testpy/pow/in.go new file mode 100644 index 00000000..6dc98ead --- /dev/null +++ b/cl/_testpy/pow/in.go @@ -0,0 +1,12 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/py" + "github.com/goplus/llgo/py/math" +) + +func main() { + x := math.Pow(py.Float(2), py.Float(3)) + c.Printf(c.Str("pow(2, 3) = %f\n"), x.Float64()) +} diff --git a/cl/_testpy/pow/out.ll b/cl/_testpy/pow/out.ll new file mode 100644 index 00000000..e1bd0f04 --- /dev/null +++ b/cl/_testpy/pow/out.ll @@ -0,0 +1,58 @@ +; ModuleID = 'main' +source_filename = "main" + +@"main.init$guard" = global ptr null +@__llgo_argc = global ptr null +@__llgo_argv = global ptr null +@__llgo_py.math.pow = linkonce global ptr null +@0 = private unnamed_addr constant [16 x i8] c"pow(2, 3) = %f\0A\00", align 1 +@__llgo_py.math = external global ptr +@1 = private unnamed_addr constant [4 x i8] c"pow\00", align 1 + +define void @main.init() { +_llgo_0: + %0 = load i1, ptr @"main.init$guard", align 1 + br i1 %0, label %_llgo_2, label %_llgo_1 + +_llgo_1: ; preds = %_llgo_0 + store i1 true, ptr @"main.init$guard", align 1 + call void @"github.com/goplus/llgo/py/math.init"() + %1 = load ptr, ptr @__llgo_py.math, align 8 + call void (ptr, ...) @llgoLoadPyModSyms(ptr %1, ptr @1, ptr @__llgo_py.math.pow, ptr null) + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +define void @main(i32 %0, ptr %1) { +_llgo_0: + call void @Py_Initialize() + store i32 %0, ptr @__llgo_argc, align 4 + store ptr %1, ptr @__llgo_argv, align 8 + call void @"github.com/goplus/llgo/internal/runtime.init"() + call void @main.init() + %2 = call ptr @PyFloat_FromDouble(double 2.000000e+00) + %3 = call ptr @PyFloat_FromDouble(double 3.000000e+00) + %4 = load ptr, ptr @__llgo_py.math.pow, align 8 + %5 = call ptr (ptr, ...) @PyObject_CallFunctionObjArgs(ptr %4, ptr %2, ptr %3, ptr null) + %6 = call double @PyFloat_AsDouble(ptr %5) + %7 = call i32 (ptr, ...) @printf(ptr @0, double %6) + ret void +} + +declare void @"github.com/goplus/llgo/py/math.init"() + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +declare ptr @PyFloat_FromDouble(double) + +declare ptr @PyObject_CallFunctionObjArgs(ptr, ...) + +declare double @PyFloat_AsDouble(ptr) + +declare i32 @printf(ptr, ...) + +declare void @llgoLoadPyModSyms(ptr, ...) + +declare void @Py_Initialize() diff --git a/cl/_testrt/builtin/in.go b/cl/_testrt/builtin/in.go index a252a6d5..00857a49 100644 --- a/cl/_testrt/builtin/in.go +++ b/cl/_testrt/builtin/in.go @@ -1,7 +1,7 @@ package main import ( - "github.com/goplus/llgo/internal/runtime/c" + "unsafe" ) var a int64 = 1<<63 - 1 @@ -11,41 +11,19 @@ var n uint64 = 1<<64 - 1 func main() { var s = []int{1, 2, 3, 4} var a = [...]int{1, 2, 3, 4} + d := make([]byte, 4, 10) + println(s, len(s), cap(s)) + println(d, len(d), cap(d)) + println(len(a), cap(a), cap(&a), len(&a)) + println(len([]int{1, 2, 3, 4}), len([4]int{1, 2, 3, 4})) + println(len(s[1:]), cap(s[1:]), len(s[1:2]), cap(s[1:2]), len(s[1:2:2]), cap(s[1:2:2])) + println(len(a[1:]), cap(a[1:]), len(a[1:2]), cap(a[1:2]), len(a[1:2:2]), cap(a[1:2:2])) - out(len(s)) - out(len([]int{1, 2, 3, 4})) - out(len(a)) - out(len(&a)) - out(len([4]int{1, 2, 3, 4})) - - out(cap(s)) - out(cap(a)) - out(cap(&a)) - - out(len(s[1:])) - out(cap(s[1:])) - out(len(s[1:2])) - out(cap(s[1:2])) - out(len(s[1:2:2])) - out(cap(s[1:2:2])) - - out(len(a[1:])) - out(cap(a[1:])) - out(len(a[1:2])) - out(cap(a[1:2])) - out(len(a[1:2:2])) - out(cap(a[1:2:2])) - - string_len("hello") - string_len("hello"[1:]) - string_len("hello"[1:2]) - string_len("hello"[5:]) -} - -func string_len(s string) { - out(len(s)) -} - -func out(n int) { - c.Printf(c.Str("%d\n"), n) + println("hello", "hello"[1:], "hello"[1:2], len("hello"[5:])) + println(append(s, 5, 6, 7, 8)) + data := []byte{'a', 'b', 'c'} + data = append(data, "def"...) + println(data) + var i any = 100 + println(true, 100, -100, uint(100), int32(-100), 100.5, i, &i, uintptr(unsafe.Pointer(&i))) } diff --git a/cl/_testrt/builtin/out.ll b/cl/_testrt/builtin/out.ll index 9201f246..5cd53638 100644 --- a/cl/_testrt/builtin/out.ll +++ b/cl/_testrt/builtin/out.ll @@ -3,6 +3,7 @@ source_filename = "main" %"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 } %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } +%"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr } @main.a = global ptr null @main.b = global ptr null @@ -10,11 +11,50 @@ source_filename = "main" @main.n = global ptr null @__llgo_argc = global ptr null @__llgo_argv = global ptr null -@0 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 -@1 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 -@2 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 -@3 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 -@4 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 +@0 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@1 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@2 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 +@3 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@4 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@5 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 +@6 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@7 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@8 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@9 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 +@10 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@11 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 +@12 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@13 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@14 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@15 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@16 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@17 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 +@18 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@19 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@20 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@21 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@22 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@23 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 +@24 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 +@25 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 +@26 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 +@27 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 +@28 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@29 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@30 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@31 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 +@32 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 +@33 = private unnamed_addr constant [4 x i8] c"def\00", align 1 +@34 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 +@35 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@36 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@37 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@38 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@39 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@40 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@41 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@42 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@43 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 define void @main.init() { _llgo_0: @@ -57,103 +97,219 @@ _llgo_0: store i64 2, ptr %10, align 4 store i64 3, ptr %11, align 4 store i64 4, ptr %12, align 4 - %13 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - call void @main.out(i64 %13) - %14 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) - %15 = getelementptr inbounds i64, ptr %14, i64 0 - store i64 1, ptr %15, align 4 - %16 = getelementptr inbounds i64, ptr %14, i64 1 - store i64 2, ptr %16, align 4 - %17 = getelementptr inbounds i64, ptr %14, i64 2 - store i64 3, ptr %17, align 4 - %18 = getelementptr inbounds i64, ptr %14, i64 3 - store i64 4, ptr %18, align 4 - %19 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %14, i64 8, i64 4, i64 0, i64 4, i64 4) - %20 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %19) - call void @main.out(i64 %20) - call void @main.out(i64 4) - call void @main.out(i64 4) - call void @main.out(i64 4) - %21 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - call void @main.out(i64 %21) - call void @main.out(i64 4) - call void @main.out(i64 4) - %22 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - %23 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - %24 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - %25 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %24, i64 8, i64 %22, i64 1, i64 %23, i64 %22) - %26 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %25) - call void @main.out(i64 %26) - %27 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - %28 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - %29 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - %30 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %29, i64 8, i64 %27, i64 1, i64 %28, i64 %27) - %31 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %30) - call void @main.out(i64 %31) - %32 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - %33 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - %34 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %33, i64 8, i64 %32, i64 1, i64 2, i64 %32) - %35 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %34) - call void @main.out(i64 %35) - %36 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - %37 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - %38 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %37, i64 8, i64 %36, i64 1, i64 2, i64 %36) - %39 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %38) - call void @main.out(i64 %39) - %40 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - %41 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - %42 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %41, i64 8, i64 %40, i64 1, i64 2, i64 2) - %43 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %42) - call void @main.out(i64 %43) - %44 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - %45 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) - %46 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %45, i64 8, i64 %44, i64 1, i64 2, i64 2) - %47 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %46) - call void @main.out(i64 %47) - %48 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 4, i64 4) - %49 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %48) - call void @main.out(i64 %49) - %50 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 4, i64 4) - %51 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %50) - call void @main.out(i64 %51) - %52 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 4) - %53 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %52) - call void @main.out(i64 %53) - %54 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 4) - %55 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %54) - call void @main.out(i64 %55) - %56 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 2) - %57 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %56) - call void @main.out(i64 %57) - %58 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 2) - %59 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %58) - call void @main.out(i64 %59) - %60 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 5) - call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %60) - %61 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 5) - %62 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %61, 1 - %63 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %61, i64 1, i64 %62) - call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %63) - %64 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 5) - %65 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %64, i64 1, i64 2) - call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %65) - %66 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 5) - %67 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %66, 1 - %68 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %66, i64 5, i64 %67) - call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %68) - ret void -} - -define void @main.out(i64 %0) { -_llgo_0: - %1 = call i32 (ptr, ...) @printf(ptr @4, i64 %0) - ret void -} - -define void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %0) { -_llgo_0: - %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %0, 1 - call void @main.out(i64 %1) + %13 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 10) + %14 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %13, i64 1, i64 10, i64 0, i64 4, i64 10) + %15 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 1 + %16 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 + call void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) + %17 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %17) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %15) + %18 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %18) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %16) + %19 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %19) + %20 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %14, 1 + %21 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %14, 2 + call void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice" %14) + %22 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %22) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %20) + %23 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %23) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %21) + %24 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %24) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 4) + %25 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @6, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %25) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 4) + %26 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @7, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %26) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 4) + %27 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @8, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %27) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 4) + %28 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @9, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %28) + %29 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) + %30 = getelementptr inbounds i64, ptr %29, i64 0 + store i64 1, ptr %30, align 4 + %31 = getelementptr inbounds i64, ptr %29, i64 1 + store i64 2, ptr %31, align 4 + %32 = getelementptr inbounds i64, ptr %29, i64 2 + store i64 3, ptr %32, align 4 + %33 = getelementptr inbounds i64, ptr %29, i64 3 + store i64 4, ptr %33, align 4 + %34 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %29, i64 8, i64 4, i64 0, i64 4, i64 4) + %35 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %34, 1 + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %35) + %36 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @10, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %36) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 4) + %37 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @11, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %37) + %38 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 + %39 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 + %40 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0 + %41 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %40, i64 8, i64 %38, i64 1, i64 %39, i64 %38) + %42 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %41, 1 + %43 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 + %44 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 + %45 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0 + %46 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %45, i64 8, i64 %43, i64 1, i64 %44, i64 %43) + %47 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %46, 2 + %48 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 + %49 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0 + %50 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %49, i64 8, i64 %48, i64 1, i64 2, i64 %48) + %51 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %50, 1 + %52 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 + %53 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0 + %54 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %53, i64 8, i64 %52, i64 1, i64 2, i64 %52) + %55 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %54, 2 + %56 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 + %57 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0 + %58 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %57, i64 8, i64 %56, i64 1, i64 2, i64 2) + %59 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %58, 1 + %60 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2 + %61 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0 + %62 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %61, i64 8, i64 %60, i64 1, i64 2, i64 2) + %63 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %62, 2 + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %42) + %64 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @12, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %64) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %47) + %65 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @13, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %65) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %51) + %66 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @14, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %66) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %55) + %67 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @15, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %67) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %59) + %68 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @16, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %68) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %63) + %69 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @17, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %69) + %70 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 4, i64 4) + %71 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %70, 1 + %72 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 4, i64 4) + %73 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %72, 2 + %74 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 4) + %75 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %74, 1 + %76 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 4) + %77 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %76, 2 + %78 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 2) + %79 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %78, 1 + %80 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 2) + %81 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %80, 2 + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %71) + %82 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @18, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %82) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %73) + %83 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @19, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %83) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %75) + %84 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @20, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %84) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %77) + %85 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @21, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %85) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %79) + %86 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @22, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %86) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %81) + %87 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @23, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %87) + %88 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @24, i64 5) + %89 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %88, 1 + %90 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %88, i64 1, i64 %89) + %91 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @25, i64 5) + %92 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %91, i64 1, i64 2) + %93 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @26, i64 5) + %94 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %93, 1 + %95 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %93, i64 5, i64 %94) + %96 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %95, 1 + %97 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @27, i64 5) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %97) + %98 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @28, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %98) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %90) + %99 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @29, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %99) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %92) + %100 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @30, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %100) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %96) + %101 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @31, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %101) + %102 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) + %103 = getelementptr inbounds i64, ptr %102, i64 0 + store i64 5, ptr %103, align 4 + %104 = getelementptr inbounds i64, ptr %102, i64 1 + store i64 6, ptr %104, align 4 + %105 = getelementptr inbounds i64, ptr %102, i64 2 + store i64 7, ptr %105, align 4 + %106 = getelementptr inbounds i64, ptr %102, i64 3 + store i64 8, ptr %106, align 4 + %107 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %102, i64 8, i64 4, i64 0, i64 4, i64 4) + %108 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %107, 0 + %109 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %107, 1 + %110 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %7, ptr %108, i64 %109, i64 8) + call void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice" %110) + %111 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @32, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %111) + %112 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 3) + %113 = getelementptr inbounds i8, ptr %112, i64 0 + store i8 97, ptr %113, align 1 + %114 = getelementptr inbounds i8, ptr %112, i64 1 + store i8 98, ptr %114, align 1 + %115 = getelementptr inbounds i8, ptr %112, i64 2 + store i8 99, ptr %115, align 1 + %116 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %112, i64 1, i64 3, i64 0, i64 3, i64 3) + %117 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @33, i64 3) + %118 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %117, 0 + %119 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %117, 1 + %120 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %116, ptr %118, i64 %119, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice" %120) + %121 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @34, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %121) + %122 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 16) + %123 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2) + %124 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %123, i64 100) + store %"github.com/goplus/llgo/internal/runtime.iface" %124, ptr %122, align 8 + %125 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %122, align 8 + %126 = ptrtoint ptr %122 to i64 + call void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1 true) + %127 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @35, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %127) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 100) + %128 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @36, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %128) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 -100) + %129 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @37, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %129) + call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 100) + %130 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @38, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %130) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 -100) + %131 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @39, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %131) + call void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double 1.005000e+02) + %132 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @40, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %132) + call void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/goplus/llgo/internal/runtime.iface" %125) + %133 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @41, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %133) + call void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr %122) + %134 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @42, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %134) + call void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64 %126) + %135 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @43, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %135) ret void } @@ -163,14 +319,28 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64) -declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice") +declare void @"github.com/goplus/llgo/internal/runtime.PrintSlice"(%"github.com/goplus/llgo/internal/runtime.Slice") -declare i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice") - -declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice") +declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64) +declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64) + declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String", i64, i64) -declare i32 @printf(ptr, ...) +declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice", ptr, i64, i64) + +declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64) + +declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr, i64) + +declare void @"github.com/goplus/llgo/internal/runtime.PrintBool"(i1) + +declare void @"github.com/goplus/llgo/internal/runtime.PrintUint"(i64) + +declare void @"github.com/goplus/llgo/internal/runtime.PrintFloat"(double) + +declare void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/goplus/llgo/internal/runtime.iface") + +declare void @"github.com/goplus/llgo/internal/runtime.PrintPointer"(ptr) diff --git a/cl/_testrt/concat/in.go b/cl/_testrt/concat/in.go index 149bfbae..cb9b44b1 100644 --- a/cl/_testrt/concat/in.go +++ b/cl/_testrt/concat/in.go @@ -11,6 +11,10 @@ func concat(args ...string) (ret string) { return } +func info(s string) string { + return "" + s + "..." +} + func main() { result := concat("Hello", " ", "World") c.Fprintf(c.Stderr, c.Str("Hi, %s\n"), c.AllocaCStr(result)) diff --git a/cl/_testrt/concat/out.ll b/cl/_testrt/concat/out.ll index e775ef4f..af3e1e82 100644 --- a/cl/_testrt/concat/out.ll +++ b/cl/_testrt/concat/out.ll @@ -6,17 +6,19 @@ source_filename = "main" @"main.init$guard" = global ptr null @0 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 +@1 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 +@2 = private unnamed_addr constant [4 x i8] c"...\00", align 1 @__llgo_argc = global ptr null @__llgo_argv = global ptr null -@1 = private unnamed_addr constant [6 x i8] c"Hello\00", align 1 -@2 = private unnamed_addr constant [2 x i8] c" \00", align 1 -@3 = private unnamed_addr constant [6 x i8] c"World\00", align 1 +@3 = private unnamed_addr constant [6 x i8] c"Hello\00", align 1 +@4 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@5 = private unnamed_addr constant [6 x i8] c"World\00", align 1 @__stderrp = external global ptr -@4 = private unnamed_addr constant [8 x i8] c"Hi, %s\0A\00", align 1 +@6 = private unnamed_addr constant [8 x i8] c"Hi, %s\0A\00", align 1 define %"github.com/goplus/llgo/internal/runtime.String" @main.concat(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { _llgo_0: - %1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) + %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1 %2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 0) %3 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %2, 0 %4 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %2, 1 @@ -37,7 +39,7 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0 br i1 %13, label %_llgo_2, label %_llgo_3 _llgo_2: ; preds = %_llgo_1 - %14 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) + %14 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0 %15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %14, i64 %12 %16 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %15, align 8 %17 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %11, %"github.com/goplus/llgo/internal/runtime.String" %16) @@ -49,6 +51,15 @@ _llgo_3: ; preds = %_llgo_1 ret %"github.com/goplus/llgo/internal/runtime.String" %11 } +define %"github.com/goplus/llgo/internal/runtime.String" @main.info(%"github.com/goplus/llgo/internal/runtime.String" %0) { +_llgo_0: + %1 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 0) + %2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %1, %"github.com/goplus/llgo/internal/runtime.String" %0) + %3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 3) + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %2, %"github.com/goplus/llgo/internal/runtime.String" %3) + ret %"github.com/goplus/llgo/internal/runtime.String" %4 +} + define void @main.init() { _llgo_0: %0 = load i1, ptr @"main.init$guard", align 1 @@ -70,13 +81,13 @@ _llgo_0: call void @main.init() %2 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 48) %3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i64 0 - %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 5) + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 5) store %"github.com/goplus/llgo/internal/runtime.String" %4, ptr %3, align 8 %5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i64 1 - %6 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 1) + %6 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 1) store %"github.com/goplus/llgo/internal/runtime.String" %6, ptr %5, align 8 %7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i64 2 - %8 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 5) + %8 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 5) store %"github.com/goplus/llgo/internal/runtime.String" %8, ptr %7, align 8 %9 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %2, i64 16, i64 3, i64 0, i64 3, i64 3) %10 = call %"github.com/goplus/llgo/internal/runtime.String" @main.concat(%"github.com/goplus/llgo/internal/runtime.Slice" %9) @@ -85,14 +96,10 @@ _llgo_0: %13 = add i64 %12, 1 %14 = alloca i8, i64 %13, align 1 %15 = call ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %14, %"github.com/goplus/llgo/internal/runtime.String" %10) - %16 = call i32 (ptr, ptr, ...) @fprintf(ptr %11, ptr @4, ptr %15) + %16 = call i32 (ptr, ptr, ...) @fprintf(ptr %11, ptr @6, ptr %15) ret void } -declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice") - -declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice") - declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String") declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64) diff --git a/cl/_testrt/intgen/out.ll b/cl/_testrt/intgen/out.ll index e4ffe19d..8d91dd12 100644 --- a/cl/_testrt/intgen/out.ll +++ b/cl/_testrt/intgen/out.ll @@ -16,7 +16,7 @@ _llgo_0: %2 = mul i64 %0, 4 %3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 %2) %4 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr %3, i64 %0, i64 %0) - %5 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %4) + %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %4, 1 br label %_llgo_1 _llgo_1: ; preds = %_llgo_2, %_llgo_0 @@ -29,7 +29,7 @@ _llgo_2: ; preds = %_llgo_1 %9 = extractvalue { ptr, ptr } %1, 1 %10 = extractvalue { ptr, ptr } %1, 0 %11 = call i32 %10(ptr %9) - %12 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %4) + %12 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %4, 0 %13 = getelementptr inbounds i32, ptr %12, i64 %7 store i32 %11, ptr %13, align 4 br label %_llgo_1 @@ -76,7 +76,7 @@ _llgo_0: store ptr null, ptr %4, align 8 %5 = load { ptr, ptr }, ptr %2, align 8 %6 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %5) - %7 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %6) + %7 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %6, 1 br label %_llgo_1 _llgo_1: ; preds = %_llgo_2, %_llgo_0 @@ -86,7 +86,7 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0 br i1 %10, label %_llgo_2, label %_llgo_3 _llgo_2: ; preds = %_llgo_1 - %11 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %6) + %11 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %6, 0 %12 = getelementptr inbounds i32, ptr %11, i64 %9 %13 = load i32, ptr %12, align 4 %14 = call i32 (ptr, ...) @printf(ptr @0, i32 %13) @@ -105,7 +105,7 @@ _llgo_3: ; preds = %_llgo_1 store ptr %16, ptr %20, align 8 %21 = load { ptr, ptr }, ptr %18, align 8 %22 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %21) - %23 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %22) + %23 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %22, 1 br label %_llgo_4 _llgo_4: ; preds = %_llgo_5, %_llgo_3 @@ -115,7 +115,7 @@ _llgo_4: ; preds = %_llgo_5, %_llgo_3 br i1 %26, label %_llgo_5, label %_llgo_6 _llgo_5: ; preds = %_llgo_4 - %27 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %22) + %27 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %22, 0 %28 = getelementptr inbounds i32, ptr %27, i64 %25 %29 = load i32, ptr %28, align 4 %30 = call i32 (ptr, ...) @printf(ptr @1, i32 %29) @@ -135,7 +135,7 @@ _llgo_6: ; preds = %_llgo_4 store ptr %33, ptr %37, align 8 %38 = load { ptr, ptr }, ptr %35, align 8 %39 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %38) - %40 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %39) + %40 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %39, 1 br label %_llgo_7 _llgo_7: ; preds = %_llgo_8, %_llgo_6 @@ -145,7 +145,7 @@ _llgo_7: ; preds = %_llgo_8, %_llgo_6 br i1 %43, label %_llgo_8, label %_llgo_9 _llgo_8: ; preds = %_llgo_7 - %44 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %39) + %44 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %39, 0 %45 = getelementptr inbounds i32, ptr %44, i64 %42 %46 = load i32, ptr %45, align 4 %47 = call i32 (ptr, ...) @printf(ptr @2, i32 %46) @@ -159,10 +159,6 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr, i64, i64) -declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice") - -declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice") - declare void @"github.com/goplus/llgo/internal/runtime.init"() declare i32 @rand() diff --git a/cl/_testrt/mask/in.go b/cl/_testrt/mask/in.go new file mode 100644 index 00000000..18211c06 --- /dev/null +++ b/cl/_testrt/mask/in.go @@ -0,0 +1,8 @@ +package main + +func main() { + println(mask(1)) +} +func mask(x int8) int32 { + return int32(x) << 31 >> 31 +} diff --git a/cl/_testrt/mask/out.ll b/cl/_testrt/mask/out.ll new file mode 100644 index 00000000..bea4f657 --- /dev/null +++ b/cl/_testrt/mask/out.ll @@ -0,0 +1,52 @@ +; ModuleID = 'main' +source_filename = "main" + +%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } + +@"main.init$guard" = global ptr null +@__llgo_argc = global ptr null +@__llgo_argv = global ptr null +@0 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 + +define void @main.init() { +_llgo_0: + %0 = load i1, ptr @"main.init$guard", align 1 + br i1 %0, label %_llgo_2, label %_llgo_1 + +_llgo_1: ; preds = %_llgo_0 + store i1 true, ptr @"main.init$guard", align 1 + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +define void @main(i32 %0, ptr %1) { +_llgo_0: + store i32 %0, ptr @__llgo_argc, align 4 + store ptr %1, ptr @__llgo_argv, align 8 + call void @"github.com/goplus/llgo/internal/runtime.init"() + call void @main.init() + %2 = call i32 @main.mask(i8 1) + %3 = sext i32 %2 to i64 + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %3) + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 1) + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %4) + ret void +} + +define i32 @main.mask(i8 %0) { +_llgo_0: + %1 = sext i8 %0 to i32 + %2 = shl i32 %1, 31 + %3 = ashr i32 %2, 31 + ret i32 %3 +} + +declare void @"github.com/goplus/llgo/internal/runtime.init"() + +declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64) + +declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") + +declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64) diff --git a/cl/_testrt/sum/out.ll b/cl/_testrt/sum/out.ll index ed29adf4..e414fa91 100644 --- a/cl/_testrt/sum/out.ll +++ b/cl/_testrt/sum/out.ll @@ -44,7 +44,7 @@ _llgo_0: define i64 @main.sum(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { _llgo_0: - %1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) + %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1 br label %_llgo_1 _llgo_1: ; preds = %_llgo_2, %_llgo_0 @@ -55,7 +55,7 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0 br i1 %5, label %_llgo_2, label %_llgo_3 _llgo_2: ; preds = %_llgo_1 - %6 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) + %6 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0 %7 = getelementptr inbounds i64, ptr %6, i64 %4 %8 = load i64, ptr %7, align 4 %9 = add i64 %2, %8 @@ -72,7 +72,3 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64) declare i32 @printf(ptr, ...) - -declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice") - -declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice") diff --git a/cl/builtin_test.go b/cl/builtin_test.go index 30841981..160aa1b3 100644 --- a/cl/builtin_test.go +++ b/cl/builtin_test.go @@ -226,5 +226,5 @@ func TestErrVarOf(t *testing.T) { } ssaPkg := &ssa.Package{Pkg: pkgTypes} g := &ssa.Global{Pkg: ssaPkg} - ctx.varOf(g) + ctx.varOf(nil, g) } diff --git a/cl/compile.go b/cl/compile.go index b3edb38c..a1419c6a 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -180,7 +180,7 @@ func (p *context) compileMethods(pkg llssa.Package, typ types.Type) { for i, n := 0, mthds.Len(); i < n; i++ { mthd := mthds.At(i) if ssaMthd := prog.MethodValue(mthd); ssaMthd != nil { - p.compileFuncDecl(pkg, ssaMthd, false) + p.compileFuncDecl(pkg, ssaMthd) } } } @@ -189,7 +189,7 @@ func (p *context) compileMethods(pkg llssa.Package, typ types.Type) { func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) { typ := gbl.Type() name, vtype := p.varName(gbl.Pkg.Pkg, gbl) - if ignoreName(name) || checkCgo(gbl.Name()) { + if vtype == pyVar || ignoreName(name) || checkCgo(gbl.Name()) { return } if debugInstr { @@ -215,14 +215,16 @@ var ( argvTy = types.NewPointer(types.NewPointer(types.Typ[types.Int8])) ) -func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function, call bool) (llssa.Function, llssa.PyObjRef, int) { +func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Function, llssa.PyObjRef, int) { pkgTypes, name, ftype := p.funcName(f, true) if ftype != goFunc { - if ftype == pyFunc { - // TODO(xsw): pyMod == "" - fnName := pysymPrefix + p.pyMod + "." + name - return nil, pkg.NewPyFunc(fnName, f.Signature, call), pyFunc - } + /* + if ftype == pyFunc { + // TODO(xsw): pyMod == "" + fnName := pysymPrefix + p.pyMod + "." + name + return nil, pkg.NewPyFunc(fnName, f.Signature, call), pyFunc + } + */ return nil, nil, ignoredFunc } fn := pkg.FuncOf(name) @@ -239,8 +241,8 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function, call bool) ctx := makeClosureCtx(pkgTypes, f.FreeVars) sig = llssa.FuncAddCtx(ctx, sig) } else { - if debugInstr && sig != nil && sig.Recv() != nil { - log.Println("==> NewFunc", name, "type:", sig.Recv(), sig) + if debugInstr { + log.Println("==> NewFunc", name, "type:", sig.Recv(), sig, "ftype:", ftype) } } if fn == nil { @@ -298,7 +300,7 @@ func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyObj pkg := p.pkg fnName := pysymPrefix + mod + "." + name if pyFn = pkg.PyObjOf(fnName); pyFn == nil { - pyFn = pkg.NewPyFunc(fnName, fn.Signature, true) + pyFn = pkg.PyNewFunc(fnName, fn.Signature, true) return } } @@ -317,6 +319,8 @@ func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyObj ftype = llgoAllocaCStr case "stringData": ftype = llgoStringData + case "pyList": + ftype = llgoPyList case "unreachable": ftype = llgoUnreachable default: @@ -374,7 +378,7 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do b.SetBlockEx(ret, llssa.AfterInit) for _, modName := range modNames { objs := mods[modName] - b.LoadPyModSyms(modName, objs...) + b.PyLoadModSyms(modName, objs...) } } }) @@ -398,13 +402,13 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do jumpTo := p.jumpTo(jump) modPath := p.pyMod modName := pysymPrefix + modPath - modPtr := pkg.NewPyModVar(modName, true).Expr + modPtr := pkg.PyNewModVar(modName, true).Expr mod := b.Load(modPtr) cond := b.BinOp(token.NEQ, mod, prog.Null(mod.Type)) newBlk := p.fn.MakeBlock() b.If(cond, jumpTo, newBlk) b.SetBlock(newBlk) - b.Store(modPtr, b.ImportPyMod(modPath)) + b.Store(modPtr, b.PyImportMod(modPath)) b.Jump(jumpTo) } return ret @@ -607,6 +611,9 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue case pyFunc: args := p.compileValues(b, args, kind) ret = b.Call(pyFn.Expr, args...) + case llgoPyList: + args := p.compileValues(b, args, fnHasVArg) + ret = b.PyList(args...) case llgoCstr: ret = cstr(b, args) case llgoAdvance: @@ -808,7 +815,7 @@ func (p *context) compileFunction(v *ssa.Function) (goFn llssa.Function, pyFn ll // v.Pkg == nil: means auto generated function? if v.Pkg == p.goPkg || v.Pkg == nil { // function in this package - goFn, pyFn, kind = p.compileFuncDecl(p.pkg, v, true) + goFn, pyFn, kind = p.compileFuncDecl(p.pkg, v) if kind != ignoredFunc { return } @@ -835,8 +842,7 @@ func (p *context) compileValue(b llssa.Builder, v ssa.Value) llssa.Expr { } return pyFn.Expr case *ssa.Global: - g := p.varOf(v) - return g.Expr + return p.varOf(b, v) case *ssa.Const: t := types.Default(v.Type()) return b.Const(v.Value, p.prog.Type(t, llssa.InGo)) @@ -927,7 +933,7 @@ func NewPackage(prog llssa.Program, pkg *ssa.Package, files []*ast.File) (ret ll // Do not try to build generic (non-instantiated) functions. continue } - ctx.compileFuncDecl(ret, member, false) + ctx.compileFuncDecl(ret, member) case *ssa.Type: ctx.compileType(ret, member) case *ssa.Global: diff --git a/cl/compile_test.go b/cl/compile_test.go index 6f417cbe..6c9cf684 100644 --- a/cl/compile_test.go +++ b/cl/compile_test.go @@ -45,7 +45,7 @@ func TestFromTestdata(t *testing.T) { } func TestSqlite(t *testing.T) { - cltest.Pkg(t, "github.com/goplus/llgo/x/sqlite", "../x/sqlite/sqlite.ll") + cltest.Pkg(t, "github.com/goplus/llgo/x/sqlite", "../x/sqlite/llgo_autogen.ll") } func TestFromTestpymath(t *testing.T) { diff --git a/cl/import.go b/cl/import.go index 11c76ae6..f59f0ac6 100644 --- a/cl/import.go +++ b/cl/import.go @@ -318,6 +318,7 @@ const ( llgoAdvance = llgoInstrBase + 4 llgoIndex = llgoInstrBase + 5 llgoStringData = llgoInstrBase + 6 + llgoPyList = llgoInstrBase + 7 ) func (p *context) funcName(fn *ssa.Function, ignore bool) (*types.Package, string, int) { @@ -358,24 +359,35 @@ const ( ignoredVar = iota goVar = int(llssa.InGo) cVar = int(llssa.InC) + pyVar = int(llssa.InPython) ) func (p *context) varName(pkg *types.Package, v *ssa.Global) (vName string, vtype int) { name := llssa.FullName(pkg, v.Name()) if v, ok := p.link[name]; ok { + if strings.HasPrefix(v, "py.") { + return v[3:], pyVar + } return v, cVar } return name, goVar } -func (p *context) varOf(v *ssa.Global) (ret llssa.Global) { +func (p *context) varOf(b llssa.Builder, v *ssa.Global) llssa.Expr { pkgTypes := p.ensureLoaded(v.Pkg.Pkg) pkg := p.pkg name, vtype := p.varName(pkgTypes, v) - if ret = pkg.VarOf(name); ret == nil { + if vtype == pyVar { + if kind, mod := pkgKindByScope(pkgTypes.Scope()); kind == PkgPyModule { + return b.PyNewVar(pysymPrefix+mod, name).Expr + } + panic("unreachable") + } + ret := pkg.VarOf(name) + if ret == nil { ret = pkg.NewVar(name, v.Type(), llssa.Background(vtype)) } - return + return ret.Expr } func (p *context) ensureLoaded(pkgTypes *types.Package) *types.Package { diff --git a/internal/build/build.go b/internal/build/build.go index 5a834bc7..eceb0597 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -200,7 +200,9 @@ func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, ve if isPkgInLLGo(pkgPath) { pkg.ExportFile = concatPkgLinkFiles(pkgPath) } else { - panic("todo") + // panic("todo") + // TODO(xsw): support packages out of llgo + pkg.ExportFile = "" } if kind == cl.PkgLinkExtern { // need to be linked with external library linkFile := os.ExpandEnv(strings.TrimSpace(param)) @@ -209,10 +211,10 @@ func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, ve if dir != "" { command += " -L " + dir } - if isMultiLinkFiles(pkg.ExportFile) { - pkg.ExportFile = command + pkg.ExportFile - } else { + if isSingleLinkFile(pkg.ExportFile) { pkg.ExportFile = command + " " + pkg.ExportFile + } else { + pkg.ExportFile = command + pkg.ExportFile } } default: @@ -454,14 +456,14 @@ func llgoRoot() string { } func appendLinkFiles(args []string, file string) []string { - if isMultiLinkFiles(file) { - return append(args, strings.Split(file[1:], " ")...) + if isSingleLinkFile(file) { + return append(args, file) } - return append(args, file) + return append(args, strings.Split(file[1:], " ")...) } -func isMultiLinkFiles(ret string) bool { - return len(ret) > 0 && ret[0] == ' ' +func isSingleLinkFile(ret string) bool { + return len(ret) > 0 && ret[0] != ' ' } func concatPkgLinkFiles(pkgPath string) string { diff --git a/internal/llgen/llgenf.go b/internal/llgen/llgenf.go index e7f54dce..7459be55 100644 --- a/internal/llgen/llgenf.go +++ b/internal/llgen/llgenf.go @@ -103,8 +103,6 @@ func SmartDoFile(inFile string, pkgPath ...string) { fname := autgenFile if inCompilerDir(absDir) { fname = "out.ll" - } else if inSqlite(absDir) { - fname = "sqlite.ll" } outFile := dir + fname @@ -129,7 +127,3 @@ func genZip(dir string, outFile, inFile string) { func inCompilerDir(dir string) bool { return strings.Contains(dir, "/llgo/cl/") } - -func inSqlite(dir string) bool { - return strings.HasSuffix(dir, "/llgo/x/sqlite") -} diff --git a/internal/runtime/llgo_autogen.lla b/internal/runtime/llgo_autogen.lla index 452cc462..908e7b58 100644 Binary files a/internal/runtime/llgo_autogen.lla and b/internal/runtime/llgo_autogen.lla differ diff --git a/internal/runtime/print.go b/internal/runtime/print.go new file mode 100644 index 00000000..cc33fc4d --- /dev/null +++ b/internal/runtime/print.go @@ -0,0 +1,172 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime + +import ( + "unsafe" + + "github.com/goplus/llgo/c" +) + +// The compiler knows that a print of a value of this type +// should use printhex instead of printuint (decimal). +func bytes(s string) (ret []byte) { + rp := (*Slice)(unsafe.Pointer(&ret)) + sp := (*String)(unsafe.Pointer(&s)) + rp.data = sp.data + rp.len = sp.len + rp.cap = sp.len + return +} + +func gwrite(b []byte) { + if len(b) == 0 { + return + } + for _, v := range b { + c.Fprintf(c.Stderr, c.Str("%c"), v) + } +} + +func PrintBool(v bool) { + if v { + PrintString("true") + } else { + PrintString("false") + } +} + +func PrintFloat(v float64) { + switch { + case v != v: + PrintString("NaN") + return + case v+v == v && v > 0: + PrintString("+Inf") + return + case v+v == v && v < 0: + PrintString("-Inf") + return + } + + const n = 7 // digits printed + var buf [n + 7]byte + buf[0] = '+' + e := 0 // exp + if v == 0 { + if 1/v < 0 { + buf[0] = '-' + } + } else { + if v < 0 { + v = -v + buf[0] = '-' + } + + // normalize + for v >= 10 { + e++ + v /= 10 + } + for v < 1 { + e-- + v *= 10 + } + + // round + h := 5.0 + for i := 0; i < n; i++ { + h /= 10 + } + v += h + if v >= 10 { + e++ + v /= 10 + } + } + + // format +d.dddd+edd + for i := 0; i < n; i++ { + s := int(v) + buf[i+2] = byte(s + '0') + v -= float64(s) + v *= 10 + } + buf[1] = buf[2] + buf[2] = '.' + + buf[n+2] = 'e' + buf[n+3] = '+' + if e < 0 { + e = -e + buf[n+3] = '-' + } + + buf[n+4] = byte(e/100) + '0' + buf[n+5] = byte(e/10)%10 + '0' + buf[n+6] = byte(e%10) + '0' + gwrite(buf[:]) +} + +// func PrintComplex(c complex128) { +// print("(", real(c), imag(c), "i)") +// } + +func PrintUint(v uint64) { + var buf [100]byte + i := len(buf) + for i--; i > 0; i-- { + buf[i] = byte(v%10 + '0') + if v < 10 { + break + } + v /= 10 + } + gwrite(buf[i:]) +} + +func PrintInt(v int64) { + if v < 0 { + PrintString("-") + v = -v + } + PrintUint(uint64(v)) +} + +func PrintHex(v uint64) { + const dig = "0123456789abcdef" + var buf [100]byte + i := len(buf) + for i--; i > 0; i-- { + buf[i] = dig[v%16] + if v < 16 && len(buf)-i >= 0 { + break + } + v /= 16 + } + i-- + buf[i] = 'x' + i-- + buf[i] = '0' + gwrite(buf[i:]) +} + +func PrintPointer(p unsafe.Pointer) { + PrintHex(uint64(uintptr(p))) +} + +func PrintString(s string) { + gwrite(bytes(s)) +} + +func PrintSlice(s Slice) { + sp := (*Slice)(unsafe.Pointer(&s)) + print("[", s.len, "/", s.cap, "]") + PrintPointer(sp.data) +} + +func PrintIface(i iface) { + print("(", i.tab, ",", i.data, ")") +} diff --git a/internal/runtime/slice.go b/internal/runtime/slice.go new file mode 100644 index 00000000..d692a710 --- /dev/null +++ b/internal/runtime/slice.go @@ -0,0 +1,40 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime + +// nextslicecap computes the next appropriate slice length. +func nextslicecap(newLen, oldCap int) int { + newcap := oldCap + doublecap := newcap + newcap + if newLen > doublecap { + return newLen + } + + const threshold = 256 + if oldCap < threshold { + return doublecap + } + for { + // Transition from growing 2x for small slices + // to growing 1.25x for large slices. This formula + // gives a smooth-ish transition between the two. + newcap += (newcap + 3*threshold) >> 2 + + // We need to check `newcap >= newLen` and whether `newcap` overflowed. + // newLen is guaranteed to be larger than zero, hence + // when newcap overflows then `uint(newcap) > uint(newLen)`. + // This allows to check for both with the same comparison. + if uint(newcap) >= uint(newLen) { + break + } + } + + // Set newcap to the requested cap when + // the newcap calculation overflowed. + if newcap <= 0 { + return newLen + } + return newcap +} diff --git a/internal/runtime/z_slice.go b/internal/runtime/z_slice.go index f20924fb..e6f9845c 100644 --- a/internal/runtime/z_slice.go +++ b/internal/runtime/z_slice.go @@ -70,4 +70,25 @@ func SliceData(s Slice) unsafe.Pointer { return s.data } +// SliceAppend append elem data and returns a slice. +func SliceAppend(src Slice, data unsafe.Pointer, num, etSize int) Slice { + if etSize == 0 { + return src + } + oldLen := src.len + newLen := src.len + num + if newLen > src.cap { + newCap := nextslicecap(newLen, src.cap) + p := AllocZ(uintptr(newCap * etSize)) + if oldLen != 0 { + c.Memcpy(p, src.data, uintptr(oldLen*etSize)) + } + src.data = p + src.cap = newCap + } + src.len = newLen + c.Memcpy(c.Advance(src.data, oldLen*etSize), data, uintptr(num*etSize)) + return src +} + // ----------------------------------------------------------------------------- diff --git a/py/_pyg/llpyg/llpyg.c b/py/_pyg/llpyg/llpyg.c new file mode 100644 index 00000000..a2af9c44 --- /dev/null +++ b/py/_pyg/llpyg/llpyg.c @@ -0,0 +1,49 @@ +#include +#include + +typedef struct PyObject PyObject; + +void Py_Initialize(); + +PyObject* PyImport_ImportModule(const char* modName); +PyObject* PyModule_GetDict(PyObject* mod); +PyObject* PyObject_Str(PyObject* obj); +PyObject* PyDict_Keys(PyObject* dict); +PyObject* PyList_GetItem(PyObject* list, size_t index); +PyObject* PyTuple_GetItem(PyObject* tuple, size_t index); +PyObject* PyObject_GetAttr(PyObject* mod, PyObject* attrName); +PyObject* PyObject_GetAttrString(PyObject* mod, const char* attrName); +PyObject* PyObject_CallOneArg(PyObject* fn, PyObject* arg); + +const char* PyUnicode_AsUTF8(PyObject* str); + +size_t PyList_Size(PyObject* list); + +int PyCallable_Check(PyObject*); + +int main() { + Py_Initialize(); + PyObject* inspect = PyImport_ImportModule("inspect"); + PyObject* signature = PyObject_GetAttrString(inspect, "signature"); + PyObject* mod = PyImport_ImportModule("numpy"); + PyObject* dict = PyModule_GetDict(mod); + PyObject* keys = PyDict_Keys(dict); + size_t i, n; + n = PyList_Size(keys); + for (i = 0; i < n; i++) { + PyObject* key = PyList_GetItem(keys, i); + PyObject* val = PyObject_GetAttr(mod, key); + if (PyCallable_Check(val) != 0) { + PyObject* doc = PyObject_GetAttrString(val, "__doc__"); + PyObject* sig = PyObject_CallOneArg(signature, val); + printf("-----------------------------------\n"); + printf("sig: %p\n", sig); + printf("%s: %s\n", PyUnicode_AsUTF8(key), PyUnicode_AsUTF8(PyObject_Str(sig))); + printf("%s\n", PyUnicode_AsUTF8(key)); + if (doc != NULL) { + printf("%s\n", PyUnicode_AsUTF8(doc)); + } + } + } + return 0; +} diff --git a/py/_pyg/module.c b/py/_pyg/module.c index 7ce91821..571116d0 100644 --- a/py/_pyg/module.c +++ b/py/_pyg/module.c @@ -1,5 +1,6 @@ #include #include +#include // example: // llgoLoadPyModSyms(mod, "name1", &func1, "name2", &func2, NULL) @@ -23,3 +24,30 @@ void llgoLoadPyModSyms(PyObject* mod, ...) { } va_end(ap); } + +/* +wchar_t* toWcs(const char* str) { + size_t len = mbstowcs(NULL, str, 0); + wchar_t* wstr = (wchar_t*)malloc((len + 1) * sizeof(wchar_t)); + mbstowcs(wstr, str, len + 1); + return wstr; +} + +char* toMbs(const wchar_t* str) { + size_t len = wcstombs(NULL, str, 0); + char* mstr = (char*)malloc(len + 1); + wcstombs(mstr, str, len + 1); + return mstr; +} + +wchar_t *Py_GetPath(); + +void Py_SetPath(const wchar_t* path); +void Py_Initialize(); + +void llgoPyInitialize() { + setenv("PYTHONPATH", "/opt/homebrew/lib/python3.12/site-packages", 1); + Py_Initialize(); + printf("sys.path = %s\n", toMbs(Py_GetPath())); +} +*/ diff --git a/py/builtins/builtins.go b/py/builtins/builtins.go new file mode 100644 index 00000000..d425e862 --- /dev/null +++ b/py/builtins/builtins.go @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * 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 builtins + +import ( + _ "unsafe" + + "github.com/goplus/llgo/py" +) + +const ( + LLGoPackage = "py.inspect" +) + +// https://docs.python.org/3/library/functions.html +// https://docs.python.org/3/library/constants.html + +// print(*objects, sep=' ', end='\n', file=None, flush=False) +// +// Print objects to the text stream file, separated by sep and followed by +// end. sep, end, file, and flush, if present, must be given as keyword +// arguments. +// +// All non-keyword arguments are converted to strings like str() does and +// written to the stream, separated by sep and followed by end. Both sep +// and end must be strings; they can also be None, which means to use the +// default values. If no objects are given, print() will just write end. +// +//go:linkname Print py.print +func Print(objects ...*py.Object) + +//go:linkname PrintEx py.print +func PrintEx(__llgo_kwargs *py.Object, objects ...*py.Object) + +// Invoke the built-in help system. (This function is intended for interactive +// use.) If no argument is given, the interactive help system starts on the +// interpreter console. If the argument is a string, then the string is looked +// up as the name of a module, function, class, method, keyword, or documentation +// topic, and a help page is printed on the console. If the argument is any other +// kind of object, a help page on the object is generated. +// +// Note that if a slash(/) appears in the parameter list of a function when invoking +// help(), it means that the parameters prior to the slash are positional-only. For +// more info, see the FAQ entry on positional-only parameters. +// +//go:linkname Help py.help +func Help(object *py.Object) diff --git a/py/builtins/llgo_autogen.lla b/py/builtins/llgo_autogen.lla new file mode 100644 index 00000000..3169e152 Binary files /dev/null and b/py/builtins/llgo_autogen.lla differ diff --git a/py/call.go b/py/call.go index a54cf623..b2d425dc 100644 --- a/py/call.go +++ b/py/call.go @@ -71,7 +71,7 @@ func (o *Object) CallOneArg(arg *Object) *Object { return nil } // This is the equivalent of the Python expression: o(*args). // // llgo:link (*Object).CallObject C.PyObject_CallObject -func (o *Object) CallObject(callable, args *Object) *Object { return nil } +func (o *Object) CallObject(args *Object) *Object { return nil } // Call a callable Python object o, with a variable number of C arguments. The C // arguments are described using a py.BuildValue style format string. The format diff --git a/py/inspect/inspect.go b/py/exceptions.go similarity index 54% rename from py/inspect/inspect.go rename to py/exceptions.go index b9cb3324..cd9da49d 100644 --- a/py/inspect/inspect.go +++ b/py/exceptions.go @@ -14,29 +14,19 @@ * limitations under the License. */ -package inspect +package py import ( _ "unsafe" - - "github.com/goplus/llgo/py" ) -const ( - LLGoPackage = "py.inspect" -) +// https://docs.python.org/3/c-api/exceptions.html -// https://docs.python.org/3/library/inspect.html +// Clear the error indicator. If the error indicator is not set, there is +// no effect. +// +//go:linkname ErrClear C.PyErr_Clear +func ErrClear() -// Return a signature object for the given callable. -// -//go:linkname Signature py.signature -func Signature(callable *py.Object) *py.Object - -// Get the names and default values of a Python function’s parameters. A named -// tuple is returned: -// -// FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations) -// -//go:linkname Getfullargspec py.getfullargspec -func Getfullargspec(f *py.Object) *py.Object +//go:linkname ErrPrint C.PyErr_Print +func ErrPrint() diff --git a/py/inspect/doc.txt b/py/inspect/doc.txt new file mode 100644 index 00000000..1f24518d --- /dev/null +++ b/py/inspect/doc.txt @@ -0,0 +1,14 @@ +// https://docs.python.org/3/library/inspect.html + +// Return a signature object for the given callable. +// +//go:linkname Signature py.signature +func Signature(callable *py.Object) *py.Object + +// Get the names and default values of a Python function’s parameters. A named +// tuple is returned: +// +// FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations) +// +//go:linkname Getfullargspec py.getfullargspec +func Getfullargspec(f *py.Object) *py.Object diff --git a/py/inspect/gen.go b/py/inspect/gen.go new file mode 100644 index 00000000..bc33a183 --- /dev/null +++ b/py/inspect/gen.go @@ -0,0 +1,617 @@ +package inspect + +import ( + _ "unsafe" + + "github.com/goplus/llgo/py" +) + +const LLGoPackage = "py.inspect" + +// Compute the annotations dict for an object. +// +// obj may be a callable, class, or module. +// Passing in an object of any other type raises TypeError. +// +// Returns a dict. get_annotations() returns a new dict every time +// it's called; calling it twice on the same object will return two +// different but equivalent dicts. +// +// This function handles several details for you: +// +// * If eval_str is true, values of type str will +// be un-stringized using eval(). This is intended +// for use with stringized annotations +// ("from __future__ import annotations"). +// * If obj doesn't have an annotations dict, returns an +// empty dict. (Functions and methods always have an +// annotations dict; classes, modules, and other types of +// callables may not.) +// * Ignores inherited annotations on classes. If a class +// doesn't have its own annotations dict, returns an empty dict. +// * All accesses to object members and dict values are done +// using getattr() and dict.get() for safety. +// * Always, always, always returns a freshly-created dict. +// +// eval_str controls whether or not values of type str are replaced +// with the result of calling eval() on those values: +// +// * If eval_str is true, eval() is called on values of type str. +// * If eval_str is false (the default), values of type str are unchanged. +// +// globals and locals are passed in to eval(); see the documentation +// for eval() for more information. If either globals or locals is +// None, this function may replace that value with a context-specific +// default, contingent on type(obj): +// +// * If obj is a module, globals defaults to obj.__dict__. +// * If obj is a class, globals defaults to +// sys.modules[obj.__module__].__dict__ and locals +// defaults to the obj class namespace. +// * If obj is a callable, globals defaults to obj.__globals__, +// although if obj is a wrapped function (using +// functools.update_wrapper()) it is first unwrapped. +// +//go:linkname GetAnnotations py.get_annotations +func GetAnnotations(obj *py.Object) *py.Object + +// Return true if the object is a module. +// +//go:linkname Ismodule py.ismodule +func Ismodule(object *py.Object) *py.Object + +// Return true if the object is a class. +// +//go:linkname Isclass py.isclass +func Isclass(object *py.Object) *py.Object + +// Return true if the object is an instance method. +// +//go:linkname Ismethod py.ismethod +func Ismethod(object *py.Object) *py.Object + +// Return true if the object is a method descriptor. +// +// But not if ismethod() or isclass() or isfunction() are true. +// +// This is new in Python 2.2, and, for example, is true of int.__add__. +// An object passing this test has a __get__ attribute but not a __set__ +// attribute, but beyond that the set of attributes varies. __name__ is +// usually sensible, and __doc__ often is. +// +// Methods implemented via descriptors that also pass one of the other +// tests return false from the ismethoddescriptor() test, simply because +// the other tests promise more -- you can, e.g., count on having the +// __func__ attribute (etc) when an object passes ismethod(). +// +//go:linkname Ismethoddescriptor py.ismethoddescriptor +func Ismethoddescriptor(object *py.Object) *py.Object + +// Return true if the object is a data descriptor. +// +// Data descriptors have a __set__ or a __delete__ attribute. Examples are +// properties (defined in Python) and getsets and members (defined in C). +// Typically, data descriptors will also have __name__ and __doc__ attributes +// (properties, getsets, and members have both of these attributes), but this +// is not guaranteed. +// +//go:linkname Isdatadescriptor py.isdatadescriptor +func Isdatadescriptor(object *py.Object) *py.Object + +// Return true if the object is a member descriptor. +// +// Member descriptors are specialized descriptors defined in extension +// modules. +// +//go:linkname Ismemberdescriptor py.ismemberdescriptor +func Ismemberdescriptor(object *py.Object) *py.Object + +// Return true if the object is a getset descriptor. +// +// getset descriptors are specialized descriptors defined in extension +// modules. +// +//go:linkname Isgetsetdescriptor py.isgetsetdescriptor +func Isgetsetdescriptor(object *py.Object) *py.Object + +// Return true if the object is a user-defined function. +// +// Function objects provide these attributes: +// __doc__ documentation string +// __name__ name with which this function was defined +// __code__ code object containing compiled function bytecode +// __defaults__ tuple of any default values for arguments +// __globals__ global namespace in which this function was defined +// __annotations__ dict of parameter annotations +// __kwdefaults__ dict of keyword only parameters with defaults +// +//go:linkname Isfunction py.isfunction +func Isfunction(object *py.Object) *py.Object + +// Return true if the object is a user-defined generator function. +// +// Generator function objects provide the same attributes as functions. +// See help(isfunction) for a list of attributes. +// +//go:linkname Isgeneratorfunction py.isgeneratorfunction +func Isgeneratorfunction(obj *py.Object) *py.Object + +// Decorator to ensure callable is recognised as a coroutine function. +// +//go:linkname Markcoroutinefunction py.markcoroutinefunction +func Markcoroutinefunction(func_ *py.Object) *py.Object + +// Return true if the object is a coroutine function. +// +// Coroutine functions are normally defined with "async def" syntax, but may +// be marked via markcoroutinefunction. +// +//go:linkname Iscoroutinefunction py.iscoroutinefunction +func Iscoroutinefunction(obj *py.Object) *py.Object + +// Return true if the object is an asynchronous generator function. +// +// Asynchronous generator functions are defined with "async def" +// syntax and have "yield" expressions in their body. +// +//go:linkname Isasyncgenfunction py.isasyncgenfunction +func Isasyncgenfunction(obj *py.Object) *py.Object + +// Return true if the object is an asynchronous generator. +// +//go:linkname Isasyncgen py.isasyncgen +func Isasyncgen(object *py.Object) *py.Object + +// Return true if the object is a generator. +// +// Generator objects provide these attributes: +// __iter__ defined to support iteration over container +// close raises a new GeneratorExit exception inside the +// generator to terminate the iteration +// gi_code code object +// gi_frame frame object or possibly None once the generator has +// been exhausted +// gi_running set to 1 when generator is executing, 0 otherwise +// next return the next item from the container +// send resumes the generator and "sends" a value that becomes +// the result of the current yield-expression +// throw used to raise an exception inside the generator +// +//go:linkname Isgenerator py.isgenerator +func Isgenerator(object *py.Object) *py.Object + +// Return true if the object is a coroutine. +// +//go:linkname Iscoroutine py.iscoroutine +func Iscoroutine(object *py.Object) *py.Object + +// Return true if object can be passed to an “await“ expression. +// +//go:linkname Isawaitable py.isawaitable +func Isawaitable(object *py.Object) *py.Object + +// Return true if the object is a traceback. +// +// Traceback objects provide these attributes: +// tb_frame frame object at this level +// tb_lasti index of last attempted instruction in bytecode +// tb_lineno current line number in Python source code +// tb_next next inner traceback object (called by this level) +// +//go:linkname Istraceback py.istraceback +func Istraceback(object *py.Object) *py.Object + +// Return true if the object is a frame object. +// +// Frame objects provide these attributes: +// f_back next outer frame object (this frame's caller) +// f_builtins built-in namespace seen by this frame +// f_code code object being executed in this frame +// f_globals global namespace seen by this frame +// f_lasti index of last attempted instruction in bytecode +// f_lineno current line number in Python source code +// f_locals local namespace seen by this frame +// f_trace tracing function for this frame, or None +// +//go:linkname Isframe py.isframe +func Isframe(object *py.Object) *py.Object + +// Return true if the object is a code object. +// +// Code objects provide these attributes: +// co_argcount number of arguments (not including *, ** args +// or keyword only arguments) +// co_code string of raw compiled bytecode +// co_cellvars tuple of names of cell variables +// co_consts tuple of constants used in the bytecode +// co_filename name of file in which this code object was created +// co_firstlineno number of first line in Python source code +// co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg +// | 16=nested | 32=generator | 64=nofree | 128=coroutine +// | 256=iterable_coroutine | 512=async_generator +// co_freevars tuple of names of free variables +// co_posonlyargcount number of positional only arguments +// co_kwonlyargcount number of keyword only arguments (not including ** arg) +// co_lnotab encoded mapping of line numbers to bytecode indices +// co_name name with which this code object was defined +// co_names tuple of names other than arguments and function locals +// co_nlocals number of local variables +// co_stacksize virtual machine stack space required +// co_varnames tuple of names of arguments and local variables +// +//go:linkname Iscode py.iscode +func Iscode(object *py.Object) *py.Object + +// Return true if the object is a built-in function or method. +// +// Built-in functions and methods provide these attributes: +// __doc__ documentation string +// __name__ original name of this function or method +// __self__ instance to which a method is bound, or None +// +//go:linkname Isbuiltin py.isbuiltin +func Isbuiltin(object *py.Object) *py.Object + +// Return true if the object is a method wrapper. +// +//go:linkname Ismethodwrapper py.ismethodwrapper +func Ismethodwrapper(object *py.Object) *py.Object + +// Return true if the object is any kind of function or method. +// +//go:linkname Isroutine py.isroutine +func Isroutine(object *py.Object) *py.Object + +// Return true if the object is an abstract base class (ABC). +// +//go:linkname Isabstract py.isabstract +func Isabstract(object *py.Object) *py.Object + +// Return all members of an object as (name, value) pairs sorted by name. +// +// Optionally, only return members that satisfy a given predicate. +// +//go:linkname Getmembers py.getmembers +func Getmembers(object *py.Object, predicate *py.Object) *py.Object + +// Return all members of an object as (name, value) pairs sorted by name +// +// without triggering dynamic lookup via the descriptor protocol, +// __getattr__ or __getattribute__. Optionally, only return members that +// satisfy a given predicate. +// +// Note: this function may not be able to retrieve all members +// that getmembers can fetch (like dynamically created attributes) +// and may find members that getmembers can't (like descriptors +// that raise AttributeError). It can also return descriptor objects +// instead of instance members in some cases. +// +//go:linkname GetmembersStatic py.getmembers_static +func GetmembersStatic(object *py.Object, predicate *py.Object) *py.Object + +// Return list of attribute-descriptor tuples. +// +// For each name in dir(cls), the return list contains a 4-tuple +// with these elements: +// +// 0. The name (a string). +// +// 1. The kind of attribute this is, one of these strings: +// 'class method' created via classmethod() +// 'static method' created via staticmethod() +// 'property' created via property() +// 'method' any other flavor of method or descriptor +// 'data' not a method +// +// 2. The class which defined this attribute (a class). +// +// 3. The object as obtained by calling getattr; if this fails, or if the +// resulting object does not live anywhere in the class' mro (including +// metaclasses) then the object is looked up in the defining class's +// dict (found by walking the mro). +// +// If one of the items in dir(cls) is stored in the metaclass it will now +// be discovered and not have None be listed as the class in which it was +// defined. Any items whose home class cannot be discovered are skipped. +// +//go:linkname ClassifyClassAttrs py.classify_class_attrs +func ClassifyClassAttrs(cls *py.Object) *py.Object + +// Return tuple of base classes (including cls) in method resolution order. +// +//go:linkname Getmro py.getmro +func Getmro(cls *py.Object) *py.Object + +// Get the object wrapped by *func*. +// +// Follows the chain of :attr:`__wrapped__` attributes returning the last +// object in the chain. +// +// *stop* is an optional callback accepting an object in the wrapper chain +// as its sole argument that allows the unwrapping to be terminated early if +// the callback returns a true value. If the callback never returns a true +// value, the last object in the chain is returned as usual. For example, +// :func:`signature` uses this to stop unwrapping if any object in the +// chain has a ``__signature__`` attribute defined. +// +// :exc:`ValueError` is raised if a cycle is encountered. +// +//go:linkname Unwrap py.unwrap +func Unwrap(func_ *py.Object) *py.Object + +// Return the indent size, in spaces, at the start of a line of text. +// +//go:linkname Indentsize py.indentsize +func Indentsize(line *py.Object) *py.Object + +// Get the documentation string for an object. +// +// All tabs are expanded to spaces. To clean up docstrings that are +// indented to line up with blocks of code, any whitespace than can be +// uniformly removed from the second line onwards is removed. +// +//go:linkname Getdoc py.getdoc +func Getdoc(object *py.Object) *py.Object + +// Clean up indentation from docstrings. +// +// Any whitespace that can be uniformly removed from the second line +// onwards is removed. +// +//go:linkname Cleandoc py.cleandoc +func Cleandoc(doc *py.Object) *py.Object + +// Work out which source or compiled file an object was defined in. +// +//go:linkname Getfile py.getfile +func Getfile(object *py.Object) *py.Object + +// Return the module name for a given file, or None. +// +//go:linkname Getmodulename py.getmodulename +func Getmodulename(path *py.Object) *py.Object + +// Return the filename that can be used to locate an object's source. +// +// Return None if no way can be identified to get the source. +// +//go:linkname Getsourcefile py.getsourcefile +func Getsourcefile(object *py.Object) *py.Object + +// Return an absolute path to the source or compiled file for an object. +// +// The idea is for each object to have a unique origin, so this routine +// normalizes the result as much as possible. +// +//go:linkname Getabsfile py.getabsfile +func Getabsfile(object *py.Object, Filename *py.Object) *py.Object + +// Return the module an object was defined in, or None if not found. +// +//go:linkname Getmodule py.getmodule +func Getmodule(object *py.Object, Filename *py.Object) *py.Object + +// Return the entire source file and starting line number for an object. +// +// The argument may be a module, class, method, function, traceback, frame, +// or code object. The source code is returned as a list of all the lines +// in the file and the line number indexes a line in that list. An OSError +// is raised if the source code cannot be retrieved. +// +//go:linkname Findsource py.findsource +func Findsource(object *py.Object) *py.Object + +// Get lines of comments immediately preceding an object's source code. +// +// Returns None when source can't be found. +// +//go:linkname Getcomments py.getcomments +func Getcomments(object *py.Object) *py.Object + +// Extract the block of code at the top of the given list of lines. +// +//go:linkname Getblock py.getblock +func Getblock(lines *py.Object) *py.Object + +// Return a list of source lines and starting line number for an object. +// +// The argument may be a module, class, method, function, traceback, frame, +// or code object. The source code is returned as a list of the lines +// corresponding to the object and the line number indicates where in the +// original source file the first line of code was found. An OSError is +// raised if the source code cannot be retrieved. +// +//go:linkname Getsourcelines py.getsourcelines +func Getsourcelines(object *py.Object) *py.Object + +// Return the text of the source code for an object. +// +// The argument may be a module, class, method, function, traceback, frame, +// or code object. The source code is returned as a single string. An +// OSError is raised if the source code cannot be retrieved. +// +//go:linkname Getsource py.getsource +func Getsource(object *py.Object) *py.Object + +// Recursive helper function for getclasstree(). +// +//go:linkname Walktree py.walktree +func Walktree(classes *py.Object, children *py.Object, parent *py.Object) *py.Object + +// Arrange the given list of classes into a hierarchy of nested lists. +// +// Where a nested list appears, it contains classes derived from the class +// whose entry immediately precedes the list. Each entry is a 2-tuple +// containing a class and a tuple of its base classes. If the 'unique' +// argument is true, exactly one entry appears in the returned structure +// for each class in the given list. Otherwise, classes using multiple +// inheritance and their descendants will appear multiple times. +// +//go:linkname Getclasstree py.getclasstree +func Getclasstree(classes *py.Object, unique *py.Object) *py.Object + +// Get information about the arguments accepted by a code object. +// +// Three things are returned: (args, varargs, varkw), where +// 'args' is the list of argument names. Keyword-only arguments are +// appended. 'varargs' and 'varkw' are the names of the * and ** +// arguments or None. +// +//go:linkname Getargs py.getargs +func Getargs(co *py.Object) *py.Object + +// Get the names and default values of a callable object's parameters. +// +// A tuple of seven things is returned: +// (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations). +// 'args' is a list of the parameter names. +// 'varargs' and 'varkw' are the names of the * and ** parameters or None. +// 'defaults' is an n-tuple of the default values of the last n parameters. +// 'kwonlyargs' is a list of keyword-only parameter names. +// 'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults. +// 'annotations' is a dictionary mapping parameter names to annotations. +// +// Notable differences from inspect.signature(): +// - the "self" parameter is always reported, even for bound methods +// - wrapper chains defined by __wrapped__ *not* unwrapped automatically +// +//go:linkname Getfullargspec py.getfullargspec +func Getfullargspec(func_ *py.Object) *py.Object + +// Get information about arguments passed into a particular frame. +// +// A tuple of four things is returned: (args, varargs, varkw, locals). +// 'args' is a list of the argument names. +// 'varargs' and 'varkw' are the names of the * and ** arguments or None. +// 'locals' is the locals dictionary of the given frame. +// +//go:linkname Getargvalues py.getargvalues +func Getargvalues(frame *py.Object) *py.Object + +// Get the mapping of arguments to values. +// +// A dict is returned, with keys the function argument names (including the +// names of the * and ** arguments, if any), and values the respective bound +// values from 'positional' and 'named'. +// +//go:linkname Getcallargs py.getcallargs +func Getcallargs(func_ *py.Object, __llgo_va_list ...interface{}) *py.Object + +// Get the mapping of free variables to their current values. +// +// Returns a named tuple of dicts mapping the current nonlocal, global +// and builtin references as seen by the body of the function. A final +// set of unbound names that could not be resolved is also provided. +// +//go:linkname Getclosurevars py.getclosurevars +func Getclosurevars(func_ *py.Object) *py.Object + +// Get information about a frame or traceback object. +// +// A tuple of five things is returned: the filename, the line number of +// the current line, the function name, a list of lines of context from +// the source code, and the index of the current line within that list. +// The optional second argument specifies the number of lines of context +// to return, which are centered around the current line. +// +//go:linkname Getframeinfo py.getframeinfo +func Getframeinfo(frame *py.Object, context *py.Object) *py.Object + +// Get the line number from a frame object, allowing for optimization. +// +//go:linkname Getlineno py.getlineno +func Getlineno(frame *py.Object) *py.Object + +// Get a list of records for a frame and all higher (calling) frames. +// +// Each record contains a frame object, filename, line number, function +// name, a list of lines of context, and index within the context. +// +//go:linkname Getouterframes py.getouterframes +func Getouterframes(frame *py.Object, context *py.Object) *py.Object + +// Get a list of records for a traceback's frame and all lower frames. +// +// Each record contains a frame object, filename, line number, function +// name, a list of lines of context, and index within the context. +// +//go:linkname Getinnerframes py.getinnerframes +func Getinnerframes(tb *py.Object, context *py.Object) *py.Object + +// Return the frame of the caller or None if this is not possible. +// +//go:linkname Currentframe py.currentframe +func Currentframe() *py.Object + +// Return a list of records for the stack above the caller's frame. +// +//go:linkname Stack py.stack +func Stack(context *py.Object) *py.Object + +// Return a list of records for the stack below the current exception. +// +//go:linkname Trace py.trace +func Trace(context *py.Object) *py.Object + +// Get current state of a generator-iterator. +// +// Possible states are: +// GEN_CREATED: Waiting to start execution. +// GEN_RUNNING: Currently being executed by the interpreter. +// GEN_SUSPENDED: Currently suspended at a yield expression. +// GEN_CLOSED: Execution has completed. +// +//go:linkname Getgeneratorstate py.getgeneratorstate +func Getgeneratorstate(generator *py.Object) *py.Object + +// Get the mapping of generator local variables to their current values. +// +// A dict is returned, with the keys the local variable names and values the +// bound values. +// +//go:linkname Getgeneratorlocals py.getgeneratorlocals +func Getgeneratorlocals(generator *py.Object) *py.Object + +// Get current state of a coroutine object. +// +// Possible states are: +// CORO_CREATED: Waiting to start execution. +// CORO_RUNNING: Currently being executed by the interpreter. +// CORO_SUSPENDED: Currently suspended at an await expression. +// CORO_CLOSED: Execution has completed. +// +//go:linkname Getcoroutinestate py.getcoroutinestate +func Getcoroutinestate(coroutine *py.Object) *py.Object + +// Get the mapping of coroutine local variables to their current values. +// +// A dict is returned, with the keys the local variable names and values the +// bound values. +// +//go:linkname Getcoroutinelocals py.getcoroutinelocals +func Getcoroutinelocals(coroutine *py.Object) *py.Object + +// Get current state of an asynchronous generator object. +// +// Possible states are: +// AGEN_CREATED: Waiting to start execution. +// AGEN_RUNNING: Currently being executed by the interpreter. +// AGEN_SUSPENDED: Currently suspended at a yield expression. +// AGEN_CLOSED: Execution has completed. +// +//go:linkname Getasyncgenstate py.getasyncgenstate +func Getasyncgenstate(agen *py.Object) *py.Object + +// Get the mapping of asynchronous generator local variables to their current +// values. +// +// A dict is returned, with the keys the local variable names and values the +// bound values. +// +//go:linkname Getasyncgenlocals py.getasyncgenlocals +func Getasyncgenlocals(agen *py.Object) *py.Object + +// Get a signature object for the passed callable. +// +//go:linkname Signature py.signature +func Signature(obj *py.Object) *py.Object diff --git a/py/json/gen.go b/py/json/gen.go new file mode 100644 index 00000000..9015d8e7 --- /dev/null +++ b/py/json/gen.go @@ -0,0 +1,152 @@ +package json + +import ( + _ "unsafe" + + "github.com/goplus/llgo/py" +) + +const LLGoPackage = "py.json" + +// Serialize “obj“ as a JSON formatted stream to “fp“ (a +// +// ``.write()``-supporting file-like object). +// +// If ``skipkeys`` is true then ``dict`` keys that are not basic types +// (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped +// instead of raising a ``TypeError``. +// +// If ``ensure_ascii`` is false, then the strings written to ``fp`` can +// contain non-ASCII characters if they appear in strings contained in +// ``obj``. Otherwise, all such characters are escaped in JSON strings. +// +// If ``check_circular`` is false, then the circular reference check +// for container types will be skipped and a circular reference will +// result in an ``RecursionError`` (or worse). +// +// If ``allow_nan`` is false, then it will be a ``ValueError`` to +// serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) +// in strict compliance of the JSON specification, instead of using the +// JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). +// +// If ``indent`` is a non-negative integer, then JSON array elements and +// object members will be pretty-printed with that indent level. An indent +// level of 0 will only insert newlines. ``None`` is the most compact +// representation. +// +// If specified, ``separators`` should be an ``(item_separator, key_separator)`` +// tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and +// ``(',', ': ')`` otherwise. To get the most compact JSON representation, +// you should specify ``(',', ':')`` to eliminate whitespace. +// +// ``default(obj)`` is a function that should return a serializable version +// of obj or raise TypeError. The default simply raises TypeError. +// +// If *sort_keys* is true (default: ``False``), then the output of +// dictionaries will be sorted by key. +// +// To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the +// ``.default()`` method to serialize additional types), specify it with +// the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. +// +//go:linkname Dump py.dump +func Dump(obj *py.Object, fp *py.Object) *py.Object + +// Serialize “obj“ to a JSON formatted “str“. +// +// If ``skipkeys`` is true then ``dict`` keys that are not basic types +// (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped +// instead of raising a ``TypeError``. +// +// If ``ensure_ascii`` is false, then the return value can contain non-ASCII +// characters if they appear in strings contained in ``obj``. Otherwise, all +// such characters are escaped in JSON strings. +// +// If ``check_circular`` is false, then the circular reference check +// for container types will be skipped and a circular reference will +// result in an ``RecursionError`` (or worse). +// +// If ``allow_nan`` is false, then it will be a ``ValueError`` to +// serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in +// strict compliance of the JSON specification, instead of using the +// JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). +// +// If ``indent`` is a non-negative integer, then JSON array elements and +// object members will be pretty-printed with that indent level. An indent +// level of 0 will only insert newlines. ``None`` is the most compact +// representation. +// +// If specified, ``separators`` should be an ``(item_separator, key_separator)`` +// tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and +// ``(',', ': ')`` otherwise. To get the most compact JSON representation, +// you should specify ``(',', ':')`` to eliminate whitespace. +// +// ``default(obj)`` is a function that should return a serializable version +// of obj or raise TypeError. The default simply raises TypeError. +// +// If *sort_keys* is true (default: ``False``), then the output of +// dictionaries will be sorted by key. +// +// To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the +// ``.default()`` method to serialize additional types), specify it with +// the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. +// +//go:linkname Dumps py.dumps +func Dumps(obj *py.Object) *py.Object + +// Deserialize “fp“ (a “.read()“-supporting file-like object containing +// +// a JSON document) to a Python object. +// +// ``object_hook`` is an optional function that will be called with the +// result of any object literal decode (a ``dict``). The return value of +// ``object_hook`` will be used instead of the ``dict``. This feature +// can be used to implement custom decoders (e.g. JSON-RPC class hinting). +// +// ``object_pairs_hook`` is an optional function that will be called with the +// result of any object literal decoded with an ordered list of pairs. The +// return value of ``object_pairs_hook`` will be used instead of the ``dict``. +// This feature can be used to implement custom decoders. If ``object_hook`` +// is also defined, the ``object_pairs_hook`` takes priority. +// +// To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` +// kwarg; otherwise ``JSONDecoder`` is used. +// +//go:linkname Load py.load +func Load(fp *py.Object) *py.Object + +// Deserialize “s“ (a “str“, “bytes“ or “bytearray“ instance +// +// containing a JSON document) to a Python object. +// +// ``object_hook`` is an optional function that will be called with the +// result of any object literal decode (a ``dict``). The return value of +// ``object_hook`` will be used instead of the ``dict``. This feature +// can be used to implement custom decoders (e.g. JSON-RPC class hinting). +// +// ``object_pairs_hook`` is an optional function that will be called with the +// result of any object literal decoded with an ordered list of pairs. The +// return value of ``object_pairs_hook`` will be used instead of the ``dict``. +// This feature can be used to implement custom decoders. If ``object_hook`` +// is also defined, the ``object_pairs_hook`` takes priority. +// +// ``parse_float``, if specified, will be called with the string +// of every JSON float to be decoded. By default this is equivalent to +// float(num_str). This can be used to use another datatype or parser +// for JSON floats (e.g. decimal.Decimal). +// +// ``parse_int``, if specified, will be called with the string +// of every JSON int to be decoded. By default this is equivalent to +// int(num_str). This can be used to use another datatype or parser +// for JSON integers (e.g. float). +// +// ``parse_constant``, if specified, will be called with one of the +// following strings: -Infinity, Infinity, NaN. +// This can be used to raise an exception if invalid JSON numbers +// are encountered. +// +// To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` +// kwarg; otherwise ``JSONDecoder`` is used. +// +//go:linkname Loads py.loads +func Loads(s *py.Object) *py.Object diff --git a/py/json/llgo_autogen.lla b/py/json/llgo_autogen.lla new file mode 100644 index 00000000..930d9987 Binary files /dev/null and b/py/json/llgo_autogen.lla differ diff --git a/py/list.go b/py/list.go index 4a5297c9..de52d74d 100644 --- a/py/list.go +++ b/py/list.go @@ -18,10 +18,15 @@ package py import ( _ "unsafe" + + "github.com/goplus/llgo/c" ) // https://docs.python.org/3/c-api/list.html +//go:linkname List llgo.pyList +func List(__llgo_va_list ...any) *Object + // Return a new list of length len on success, or nil on failure. // //go:linkname NewList C.PyList_New @@ -39,3 +44,53 @@ func (l *Object) ListLen() uintptr { return 0 } // // llgo:link (*Object).ListItem C.PyList_GetItem func (l *Object) ListItem(index uintptr) *Object { return nil } + +// Set the item at index index in list to item. Return 0 on success. If index is out +// of bounds, return -1 and set an IndexError exception. +// +// llgo:link (*Object).ListSetItem C.PyList_SetItem +func (l *Object) ListSetItem(index uintptr, item *Object) c.Int { return 0 } + +// Insert the item item into list list in front of index index. Return 0 if successful; +// return -1 and set an exception if unsuccessful. Analogous to list.insert(index, item). +// +// llgo:link (*Object).ListInsert C.PyList_Insert +func (l *Object) ListInsert(index uintptr, item *Object) c.Int { return 0 } + +// Append the object item at the end of list list. Return 0 if successful; return -1 +// and set an exception if unsuccessful. Analogous to list.append(item). +// +// llgo:link (*Object).ListAppend C.PyList_Append +func (l *Object) ListAppend(item *Object) c.Int { return 0 } + +// Return a list of the objects in list containing the objects between low and high. +// Return nil and set an exception if unsuccessful. Analogous to list[low:high]. +// Indexing from the end of the list is not supported. +// +// llgo:link (*Object).ListSlice C.PyList_GetSlice +func (l *Object) ListSlice(low, high uintptr) *Object { return nil } + +// Set the slice of list between low and high to the contents of itemlist. Analogous +// to list[low:high] = itemlist. The itemlist may be NULL, indicating the assignment +// of an empty list (slice deletion). Return 0 on success, -1 on failure. Indexing +// from the end of the list is not supported. +// +// llgo:link (*Object).ListSetSlice C.PyList_SetSlice +func (l *Object) ListSetSlice(low, high uintptr, itemlist *Object) c.Int { return 0 } + +// Sort the items of list in place. Return 0 on success, -1 on failure. This is equivalent +// to list.sort(). +// +// llgo:link (*Object).ListSort C.PyList_Sort +func (l *Object) ListSort() c.Int { return 0 } + +// Reverse the items of list in place. Return 0 on success, -1 on failure. This is the +// equivalent of list.reverse(). +// +// llgo:link (*Object).ListReverse C.PyList_Reverse +func (l *Object) ListReverse() c.Int { return 0 } + +// Return a new tuple object containing the contents of list; equivalent to tuple(list). +// +// llgo:link (*Object).ListAsTuple C.PyList_AsTuple +func (l *Object) ListAsTuple() *Object { return nil } diff --git a/py/llgo_autogen.lla b/py/llgo_autogen.lla index 61233d79..f8013ee2 100644 Binary files a/py/llgo_autogen.lla and b/py/llgo_autogen.lla differ diff --git a/py/long.go b/py/long.go new file mode 100644 index 00000000..a68d8286 --- /dev/null +++ b/py/long.go @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * 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 py + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" +) + +// https://docs.python.org/3/c-api/long.html + +//go:linkname Long C.PyLong_FromLong +func Long(v c.Long) *Object + +//go:linkname LongLong C.PyLong_FromLongLong +func LongLong(v c.LongLong) *Object + +//go:linkname Ulong C.PyLong_FromUnsignedLong +func Ulong(v c.Ulong) *Object + +//go:linkname UlongLong C.PyLong_FromUnsignedLongLong +func UlongLong(v c.UlongLong) *Object + +//go:linkname Uintptr C.PyLong_FromSize_t +func Uintptr(v uintptr) *Object + +//go:linkname LongFromFloat64 C.PyLong_FromDouble +func LongFromFloat64(v float64) *Object + +//go:linkname LongFromVoidPtr C.PyLong_FromVoidPtr +func LongFromVoidPtr(v c.Pointer) *Object + +//go:linkname LongFromCStr C.PyLong_FromString +func LongFromCStr(v *c.Char, pend **c.Char, base c.Int) *Object + +//go:linkname LongFromUnicode C.PyLong_FromUnicodeObject +func LongFromUnicode(v *Object, base c.Int) *Object + +// llgo:link (*Object).Long C.PyLong_AsLong +func (l *Object) Long() c.Long { return 0 } + +// llgo:link (*Object).LongLong C.PyLong_AsLongLong +func (l *Object) LongLong() c.LongLong { return 0 } + +// llgo:link (*Object).Ulong C.PyLong_AsUnsignedLong +func (l *Object) Ulong() c.Ulong { return 0 } + +// llgo:link (*Object).UlongLong C.PyLong_AsUnsignedLongLong +func (l *Object) UlongLong() c.UlongLong { return 0 } + +// llgo:link (*Object).Uintptr C.PyLong_AsSize_t +func (l *Object) Uintptr() uintptr { return 0 } + +// llgo:link (*Object).LongAsFloat64 C.PyLong_AsDouble +func (l *Object) LongAsFloat64() float64 { return 0 } + +// llgo:link (*Object).LongAsVoidPtr C.PyLong_AsVoidPtr +func (l *Object) LongAsVoidPtr() c.Pointer { return nil } diff --git a/py/math/doc.txt b/py/math/doc.txt new file mode 100644 index 00000000..7ba48646 --- /dev/null +++ b/py/math/doc.txt @@ -0,0 +1,31 @@ +// Unlike the built-in ** operator, math.pow() converts both its arguments to type +// float. Use ** or the built-in pow() function for computing exact integer powers. +// +//go:linkname Pow py.pow +func Pow(x, y *py.Object) *py.Object + +// Return the sine of x radians. +// +//go:linkname Sin py.sin +func Sin(x *py.Object) *py.Object + +// Return the hyperbolic sine of x. +// +//go:linkname Sinh py.sinh +func Sinh(x *py.Object) *py.Object + +// Return the base-2 logarithm of x. This is usually more accurate than log(x, 2). +// +//go:linkname Log2 py.log2 +func Log2(x *py.Object) *py.Object + +// Return the base-10 logarithm of x. This is usually more accurate than log(x, 10). +// +//go:linkname Log10 py.log10 +func Log10(x *py.Object) *py.Object + +// Return the fractional and integer parts of x. Both results carry the sign of +// x and are floats. +// +//go:linkname Modf py.modf +func Modf(x *py.Object) *py.Object diff --git a/py/math/gen.go b/py/math/gen.go new file mode 100644 index 00000000..34315fdb --- /dev/null +++ b/py/math/gen.go @@ -0,0 +1,349 @@ +package math + +import ( + _ "unsafe" + + "github.com/goplus/llgo/py" +) + +const LLGoPackage = "py.math" + +// Return the arc cosine (measured in radians) of x. +// +// The result is between 0 and pi. +// +//go:linkname Acos py.acos +func Acos(x *py.Object) *py.Object + +// Return the inverse hyperbolic cosine of x. +// +//go:linkname Acosh py.acosh +func Acosh(x *py.Object) *py.Object + +// Return the arc sine (measured in radians) of x. +// +// The result is between -pi/2 and pi/2. +// +//go:linkname Asin py.asin +func Asin(x *py.Object) *py.Object + +// Return the inverse hyperbolic sine of x. +// +//go:linkname Asinh py.asinh +func Asinh(x *py.Object) *py.Object + +// Return the arc tangent (measured in radians) of x. +// +// The result is between -pi/2 and pi/2. +// +//go:linkname Atan py.atan +func Atan(x *py.Object) *py.Object + +// Return the arc tangent (measured in radians) of y/x. +// +// Unlike atan(y/x), the signs of both x and y are considered. +// +//go:linkname Atan2 py.atan2 +func Atan2(y *py.Object, x *py.Object) *py.Object + +// Return the inverse hyperbolic tangent of x. +// +//go:linkname Atanh py.atanh +func Atanh(x *py.Object) *py.Object + +// Return the cube root of x. +// +//go:linkname Cbrt py.cbrt +func Cbrt(x *py.Object) *py.Object + +// Return the ceiling of x as an Integral. +// +// This is the smallest integer >= x. +// +//go:linkname Ceil py.ceil +func Ceil(x *py.Object) *py.Object + +// Return a float with the magnitude (absolute value) of x but the sign of y. +// +// On platforms that support signed zeros, copysign(1.0, -0.0) +// returns -1.0. +// +//go:linkname Copysign py.copysign +func Copysign(x *py.Object, y *py.Object) *py.Object + +// Return the cosine of x (measured in radians). +// +//go:linkname Cos py.cos +func Cos(x *py.Object) *py.Object + +// Return the hyperbolic cosine of x. +// +//go:linkname Cosh py.cosh +func Cosh(x *py.Object) *py.Object + +// Convert angle x from radians to degrees. +// +//go:linkname Degrees py.degrees +func Degrees(x *py.Object) *py.Object + +// Return the Euclidean distance between two points p and q. +// +// The points should be specified as sequences (or iterables) of +// coordinates. Both inputs must have the same dimension. +// +// Roughly equivalent to: +// +// sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q))) +// +//go:linkname Dist py.dist +func Dist(p *py.Object, q *py.Object) *py.Object + +// Error function at x. +// +//go:linkname Erf py.erf +func Erf(x *py.Object) *py.Object + +// Complementary error function at x. +// +//go:linkname Erfc py.erfc +func Erfc(x *py.Object) *py.Object + +// Return e raised to the power of x. +// +//go:linkname Exp py.exp +func Exp(x *py.Object) *py.Object + +// Return 2 raised to the power of x. +// +//go:linkname Exp2 py.exp2 +func Exp2(x *py.Object) *py.Object + +// Return exp(x)-1. +// +// This function avoids the loss of precision involved in the direct evaluation of exp(x)-1 for small x. +// +//go:linkname Expm1 py.expm1 +func Expm1(x *py.Object) *py.Object + +// Return the absolute value of the float x. +// +//go:linkname Fabs py.fabs +func Fabs(x *py.Object) *py.Object + +// Find n!. +// +// Raise a ValueError if x is negative or non-integral. +// +//go:linkname Factorial py.factorial +func Factorial(n *py.Object) *py.Object + +// Return the floor of x as an Integral. +// +// This is the largest integer <= x. +// +//go:linkname Floor py.floor +func Floor(x *py.Object) *py.Object + +// Return fmod(x, y), according to platform C. +// +// x % y may differ. +// +//go:linkname Fmod py.fmod +func Fmod(x *py.Object, y *py.Object) *py.Object + +// Return the mantissa and exponent of x, as pair (m, e). +// +// m is a float and e is an int, such that x = m * 2.**e. +// If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0. +// +//go:linkname Frexp py.frexp +func Frexp(x *py.Object) *py.Object + +// Return an accurate floating point sum of values in the iterable seq. +// +// Assumes IEEE-754 floating point arithmetic. +// +//go:linkname Fsum py.fsum +func Fsum(seq *py.Object) *py.Object + +// Gamma function at x. +// +//go:linkname Gamma py.gamma +func Gamma(x *py.Object) *py.Object + +// Greatest Common Divisor. +// +//go:linkname Gcd py.gcd +func Gcd(__llgo_va_list ...interface{}) *py.Object + +// Return True if x is neither an infinity nor a NaN, and False otherwise. +// +//go:linkname Isfinite py.isfinite +func Isfinite(x *py.Object) *py.Object + +// Return True if x is a positive or negative infinity, and False otherwise. +// +//go:linkname Isinf py.isinf +func Isinf(x *py.Object) *py.Object + +// Return True if x is a NaN (not a number), and False otherwise. +// +//go:linkname Isnan py.isnan +func Isnan(x *py.Object) *py.Object + +// Return the integer part of the square root of the input. +// +//go:linkname Isqrt py.isqrt +func Isqrt(n *py.Object) *py.Object + +// Least Common Multiple. +// +//go:linkname Lcm py.lcm +func Lcm(__llgo_va_list ...interface{}) *py.Object + +// Return x * (2**i). +// +// This is essentially the inverse of frexp(). +// +//go:linkname Ldexp py.ldexp +func Ldexp(x *py.Object, i *py.Object) *py.Object + +// Natural logarithm of absolute value of Gamma function at x. +// +//go:linkname Lgamma py.lgamma +func Lgamma(x *py.Object) *py.Object + +// Return the base 10 logarithm of x. +// +//go:linkname Log10 py.log10 +func Log10(x *py.Object) *py.Object + +// Return the base 2 logarithm of x. +// +//go:linkname Log2 py.log2 +func Log2(x *py.Object) *py.Object + +// Return the fractional and integer parts of x. +// +// Both results carry the sign of x and are floats. +// +//go:linkname Modf py.modf +func Modf(x *py.Object) *py.Object + +// Return x**y (x to the power of y). +// +//go:linkname Pow py.pow +func Pow(x *py.Object, y *py.Object) *py.Object + +// Convert angle x from degrees to radians. +// +//go:linkname Radians py.radians +func Radians(x *py.Object) *py.Object + +// Difference between x and the closest integer multiple of y. +// +// Return x - n*y where n*y is the closest integer multiple of y. +// In the case where x is exactly halfway between two multiples of +// y, the nearest even value of n is used. The result is always exact. +// +//go:linkname Remainder py.remainder +func Remainder(x *py.Object, y *py.Object) *py.Object + +// Return the sine of x (measured in radians). +// +//go:linkname Sin py.sin +func Sin(x *py.Object) *py.Object + +// Return the hyperbolic sine of x. +// +//go:linkname Sinh py.sinh +func Sinh(x *py.Object) *py.Object + +// Return the square root of x. +// +//go:linkname Sqrt py.sqrt +func Sqrt(x *py.Object) *py.Object + +// Return the tangent of x (measured in radians). +// +//go:linkname Tan py.tan +func Tan(x *py.Object) *py.Object + +// Return the hyperbolic tangent of x. +// +//go:linkname Tanh py.tanh +func Tanh(x *py.Object) *py.Object + +// Return the sum of products of values from two iterables p and q. +// +// Roughly equivalent to: +// +// sum(itertools.starmap(operator.mul, zip(p, q, strict=True))) +// +// For float and mixed int/float inputs, the intermediate products +// and sums are computed with extended precision. +// +//go:linkname Sumprod py.sumprod +func Sumprod(p *py.Object, q *py.Object) *py.Object + +// Truncates the Real x to the nearest Integral toward 0. +// +// Uses the __trunc__ magic method. +// +//go:linkname Trunc py.trunc +func Trunc(x *py.Object) *py.Object + +// Calculate the product of all the elements in the input iterable. +// +// The default start value for the product is 1. +// +// When the iterable is empty, return the start value. This function is +// intended specifically for use with numeric values and may reject +// non-numeric types. +// +//go:linkname Prod py.prod +func Prod(iterable *py.Object) *py.Object + +// Number of ways to choose k items from n items without repetition and with order. +// +// Evaluates to n! / (n - k)! when k <= n and evaluates +// to zero when k > n. +// +// If k is not specified or is None, then k defaults to n +// and the function returns n!. +// +// Raises TypeError if either of the arguments are not integers. +// Raises ValueError if either of the arguments are negative. +// +//go:linkname Perm py.perm +func Perm(n *py.Object, k *py.Object) *py.Object + +// Number of ways to choose k items from n items without repetition and without order. +// +// Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates +// to zero when k > n. +// +// Also called the binomial coefficient because it is equivalent +// to the coefficient of k-th term in polynomial expansion of the +// expression (1 + x)**n. +// +// Raises TypeError if either of the arguments are not integers. +// Raises ValueError if either of the arguments are negative. +// +//go:linkname Comb py.comb +func Comb(n *py.Object, k *py.Object) *py.Object + +// Return the floating-point value the given number of steps after x towards y. +// +// If steps is not specified or is None, it defaults to 1. +// +// Raises a TypeError, if x or y is not a double, or if steps is not an integer. +// Raises ValueError if steps is negative. +// +//go:linkname Nextafter py.nextafter +func Nextafter(x *py.Object, y *py.Object) *py.Object + +// Return the value of the least significant bit of the float x. +// +//go:linkname Ulp py.ulp +func Ulp(x *py.Object) *py.Object diff --git a/py/math/llgo_autogen.lla b/py/math/llgo_autogen.lla index 44b7ad79..3e07c715 100644 Binary files a/py/math/llgo_autogen.lla and b/py/math/llgo_autogen.lla differ diff --git a/py/math/math.go b/py/math/math.go index 7bfd8ebe..452ff2c6 100644 --- a/py/math/math.go +++ b/py/math/math.go @@ -22,9 +22,30 @@ import ( "github.com/goplus/llgo/py" ) -const ( - LLGoPackage = "py.math" -) +// https://docs.python.org/3/library/math.html -//go:linkname Sqrt py.sqrt -func Sqrt(x *py.Object) *py.Object +//go:linkname Pi py.pi +var Pi *py.Object + +// With one argument, return the natural logarithm of x (to base e). +// +//go:linkname Log py.log +func Log(x *py.Object) *py.Object + +// With two arguments, return the logarithm of x to the given base, calculated +// as log(x)/log(base). +// +//go:linkname LogOf py.log +func LogOf(x, base *py.Object) *py.Object + +// Return the natural logarithm of 1+x (base e). The result is calculated in +// a way which is accurate for x near zero. +// +//go:linkname Log1p py.log1p +func Log1p(x *py.Object) *py.Object + +// Return the Euclidean norm, sqrt(sum(x**2 for x in coordinates)). This is the +// length of the vector from the origin to the point given by the coordinates. +// +//go:linkname Hypot py.hypot +func Hypot(coordinates ...*py.Object) *py.Object diff --git a/py/module.go b/py/module.go index 6f33cfaf..7166fd9d 100644 --- a/py/module.go +++ b/py/module.go @@ -22,8 +22,30 @@ import ( "github.com/goplus/llgo/c" ) +// https://docs.python.org/3/c-api/import.html // https://docs.python.org/3/c-api/module.html +/* +// llgo:type C +type ModuleDefBase struct { + Unused [8]byte // TODO(xsw) +} + +// llgo:type C +type ModuleDef struct { + Base ModuleDefBase + // TODO(xsw) +} +*/ + +// Return the module object corresponding to a module name. The name argument +// may be of the form package.module. First check the modules dictionary if +// there’s one there, and if not, create a new one and insert it in the modules +// dictionary. Return nil with an exception set on failure. +// +//go:linkname AddModule C.PyImport_AddModule +func AddModule(name *c.Char) *Object + // This is a wrapper around py.Import which takes a const char* as an argument // instead of an Object. // diff --git a/py/numpy/gen.go b/py/numpy/gen.go new file mode 100644 index 00000000..85d6a435 --- /dev/null +++ b/py/numpy/gen.go @@ -0,0 +1,10195 @@ +package numpy + +import ( + _ "unsafe" + + "github.com/goplus/llgo/py" +) + +const LLGoPackage = "py.numpy" + +// Show libraries and system information on which NumPy was built +// and is being used +// +// Parameters +// ---------- +// mode : {`'stdout'`, `'dicts'`}, optional. +// +// Indicates how to display the config information. +// `'stdout'` prints to console, `'dicts'` returns a dictionary +// of the configuration. +// +// Returns +// ------- +// out : {`dict`, `None`} +// +// If mode is `'dicts'`, a dict is returned, else None +// +// See Also +// -------- +// get_include : Returns the directory containing NumPy C +// +// header files. +// +// Notes +// ----- +// 1. The `'stdout'` mode will give more readable +// output if “pyyaml“ is installed +// +//go:linkname ShowConfig py.show_config +func ShowConfig(mode *py.Object) *py.Object + +// Check if the array is Fortran contiguous but *not* C contiguous. +// +// This function is obsolete and, because of changes due to relaxed stride +// checking, its return value for the same array may differ for versions +// of NumPy >= 1.10.0 and previous versions. If you only want to check if an +// array is Fortran contiguous use “a.flags.f_contiguous“ instead. +// +// Parameters +// ---------- +// a : ndarray +// +// Input array. +// +// Returns +// ------- +// isfortran : bool +// +// Returns True if the array is Fortran contiguous but *not* C contiguous. +// +// Examples +// -------- +// +// np.array allows to specify whether the array is written in C-contiguous +// order (last index varies the fastest), or FORTRAN-contiguous order in +// memory (first index varies the fastest). +// +// >>> a = np.array([[1, 2, 3], [4, 5, 6]], order='C') +// >>> a +// array([[1, 2, 3], +// +// [4, 5, 6]]) +// +// >>> np.isfortran(a) +// False +// +// >>> b = np.array([[1, 2, 3], [4, 5, 6]], order='F') +// >>> b +// array([[1, 2, 3], +// +// [4, 5, 6]]) +// +// >>> np.isfortran(b) +// True +// +// The transpose of a C-ordered array is a FORTRAN-ordered array. +// +// >>> a = np.array([[1, 2, 3], [4, 5, 6]], order='C') +// >>> a +// array([[1, 2, 3], +// +// [4, 5, 6]]) +// +// >>> np.isfortran(a) +// False +// >>> b = a.T +// >>> b +// array([[1, 4], +// +// [2, 5], +// [3, 6]]) +// +// >>> np.isfortran(b) +// True +// +// C-ordered arrays evaluate as False even if they are also FORTRAN-ordered. +// +// >>> np.isfortran(np.array([1, 2], order='F')) +// False +// +//go:linkname Isfortran py.isfortran +func Isfortran(a *py.Object) *py.Object + +// Construct an array by executing a function over each coordinate. +// +// The resulting array therefore has a value “fn(x, y, z)“ at +// coordinate “(x, y, z)“. +// +// Parameters +// ---------- +// function : callable +// +// The function is called with N parameters, where N is the rank of +// `shape`. Each parameter represents the coordinates of the array +// varying along a specific axis. For example, if `shape` +// were ``(2, 2)``, then the parameters would be +// ``array([[0, 0], [1, 1]])`` and ``array([[0, 1], [0, 1]])`` +// +// shape : (N,) tuple of ints +// +// Shape of the output array, which also determines the shape of +// the coordinate arrays passed to `function`. +// +// dtype : data-type, optional +// +// Data-type of the coordinate arrays passed to `function`. +// By default, `dtype` is float. +// +// like : array_like, optional +// +// Reference object to allow the creation of arrays which are not +// NumPy arrays. If an array-like passed in as ``like`` supports +// the ``__array_function__`` protocol, the result will be defined +// by it. In this case, it ensures the creation of an array object +// compatible with that passed in via this argument. +// +// .. versionadded:: 1.20.0 +// +// Returns +// ------- +// fromfunction : any +// +// The result of the call to `function` is passed back directly. +// Therefore the shape of `fromfunction` is completely determined by +// `function`. If `function` returns a scalar value, the shape of +// `fromfunction` would not match the `shape` parameter. +// +// See Also +// -------- +// indices, meshgrid +// +// Notes +// ----- +// Keywords other than `dtype` and `like` are passed to `function`. +// +// Examples +// -------- +// >>> np.fromfunction(lambda i, j: i, (2, 2), dtype=float) +// array([[0., 0.], +// +// [1., 1.]]) +// +// >>> np.fromfunction(lambda i, j: j, (2, 2), dtype=float) +// array([[0., 1.], +// +// [0., 1.]]) +// +// >>> np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int) +// array([[ True, False, False], +// +// [False, True, False], +// [False, False, True]]) +// +// >>> np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int) +// array([[0, 1, 2], +// +// [1, 2, 3], +// [2, 3, 4]]) +// +//go:linkname Fromfunction py.fromfunction +func Fromfunction(function *py.Object, shape *py.Object) *py.Object + +// Returns True if the type of `element` is a scalar type. +// +// Parameters +// ---------- +// element : any +// +// Input argument, can be of any type and shape. +// +// Returns +// ------- +// val : bool +// +// True if `element` is a scalar type, False if it is not. +// +// See Also +// -------- +// ndim : Get the number of dimensions of an array +// +// Notes +// ----- +// If you need a stricter way to identify a *numerical* scalar, use +// “isinstance(x, numbers.Number)“, as that returns “False“ for most +// non-numerical elements such as strings. +// +// In most cases “np.ndim(x) == 0“ should be used instead of this function, +// as that will also return true for 0d arrays. This is how numpy overloads +// functions in the style of the “dx“ arguments to `gradient` and the “bins“ +// argument to `histogram`. Some key differences: +// +// +--------------------------------------+---------------+-------------------+ +// | x |“isscalar(x)“|“np.ndim(x) == 0“| +// +======================================+===============+===================+ +// | PEP 3141 numeric objects (including | “True“ | “True“ | +// | builtins) | | | +// +--------------------------------------+---------------+-------------------+ +// | builtin string and buffer objects | “True“ | “True“ | +// +--------------------------------------+---------------+-------------------+ +// | other builtin objects, like | “False“ | “True“ | +// | `pathlib.Path`, `Exception`, | | | +// | the result of `re.compile` | | | +// +--------------------------------------+---------------+-------------------+ +// | third-party objects like | “False“ | “True“ | +// | `matplotlib.figure.Figure` | | | +// +--------------------------------------+---------------+-------------------+ +// | zero-dimensional numpy arrays | “False“ | “True“ | +// +--------------------------------------+---------------+-------------------+ +// | other numpy arrays | “False“ | “False“ | +// +--------------------------------------+---------------+-------------------+ +// | `list`, `tuple`, and other sequence | “False“ | “False“ | +// | objects | | | +// +--------------------------------------+---------------+-------------------+ +// +// Examples +// -------- +// >>> np.isscalar(3.1) +// True +// >>> np.isscalar(np.array(3.1)) +// False +// >>> np.isscalar([3.1]) +// False +// >>> np.isscalar(False) +// True +// >>> np.isscalar('numpy') +// True +// +// NumPy supports PEP 3141 numbers: +// +// >>> from fractions import Fraction +// >>> np.isscalar(Fraction(5, 17)) +// True +// >>> from numbers import Number +// >>> np.isscalar(Number()) +// True +// +//go:linkname Isscalar py.isscalar +func Isscalar(element *py.Object) *py.Object + +// Return the binary representation of the input number as a string. +// +// For negative numbers, if width is not given, a minus sign is added to the +// front. If width is given, the two's complement of the number is +// returned, with respect to that width. +// +// In a two's-complement system negative numbers are represented by the two's +// complement of the absolute value. This is the most common method of +// representing signed integers on computers [1]_. A N-bit two's-complement +// system can represent every integer in the range +// :math:`-2^{N-1}` to :math:`+2^{N-1}-1`. +// +// Parameters +// ---------- +// num : int +// +// Only an integer decimal number can be used. +// +// width : int, optional +// +// The length of the returned string if `num` is positive, or the length +// of the two's complement if `num` is negative, provided that `width` is +// at least a sufficient number of bits for `num` to be represented in the +// designated form. +// +// If the `width` value is insufficient, it will be ignored, and `num` will +// be returned in binary (`num` > 0) or two's complement (`num` < 0) form +// with its width equal to the minimum number of bits needed to represent +// the number in the designated form. This behavior is deprecated and will +// later raise an error. +// +// .. deprecated:: 1.12.0 +// +// Returns +// ------- +// bin : str +// +// Binary representation of `num` or two's complement of `num`. +// +// See Also +// -------- +// base_repr: Return a string representation of a number in the given base +// +// system. +// +// bin: Python's built-in binary representation generator of an integer. +// +// Notes +// ----- +// `binary_repr` is equivalent to using `base_repr` with base 2, but about 25x +// faster. +// +// References +// ---------- +// .. [1] Wikipedia, "Two's complement", +// +// https://en.wikipedia.org/wiki/Two's_complement +// +// Examples +// -------- +// >>> np.binary_repr(3) +// '11' +// >>> np.binary_repr(-3) +// '-11' +// >>> np.binary_repr(3, width=4) +// '0011' +// +// The two's complement is returned when the input number is negative and +// width is specified: +// +// >>> np.binary_repr(-3, width=3) +// '101' +// >>> np.binary_repr(-3, width=5) +// '11101' +// +//go:linkname BinaryRepr py.binary_repr +func BinaryRepr(num *py.Object, width *py.Object) *py.Object + +// Return a string representation of a number in the given base system. +// +// Parameters +// ---------- +// number : int +// +// The value to convert. Positive and negative values are handled. +// +// base : int, optional +// +// Convert `number` to the `base` number system. The valid range is 2-36, +// the default value is 2. +// +// padding : int, optional +// +// Number of zeros padded on the left. Default is 0 (no padding). +// +// Returns +// ------- +// out : str +// +// String representation of `number` in `base` system. +// +// See Also +// -------- +// binary_repr : Faster version of `base_repr` for base 2. +// +// Examples +// -------- +// >>> np.base_repr(5) +// '101' +// >>> np.base_repr(6, 5) +// '11' +// >>> np.base_repr(7, base=5, padding=3) +// '00012' +// +// >>> np.base_repr(10, base=16) +// 'A' +// >>> np.base_repr(32, base=16) +// '20' +// +//go:linkname BaseRepr py.base_repr +func BaseRepr(number *py.Object, base *py.Object, padding *py.Object) *py.Object + +// Return a new array of given shape and type, filled with ones. +// +// Parameters +// ---------- +// shape : int or sequence of ints +// +// Shape of the new array, e.g., ``(2, 3)`` or ``2``. +// +// dtype : data-type, optional +// +// The desired data-type for the array, e.g., `numpy.int8`. Default is +// `numpy.float64`. +// +// order : {'C', 'F'}, optional, default: C +// +// Whether to store multi-dimensional data in row-major +// (C-style) or column-major (Fortran-style) order in +// memory. +// +// like : array_like, optional +// +// Reference object to allow the creation of arrays which are not +// NumPy arrays. If an array-like passed in as ``like`` supports +// the ``__array_function__`` protocol, the result will be defined +// by it. In this case, it ensures the creation of an array object +// compatible with that passed in via this argument. +// +// .. versionadded:: 1.20.0 +// +// Returns +// ------- +// out : ndarray +// +// Array of ones with the given shape, dtype, and order. +// +// See Also +// -------- +// ones_like : Return an array of ones with shape and type of input. +// empty : Return a new uninitialized array. +// zeros : Return a new array setting values to zero. +// full : Return a new array of given shape filled with value. +// +// Examples +// -------- +// >>> np.ones(5) +// array([1., 1., 1., 1., 1.]) +// +// >>> np.ones((5,), dtype=int) +// array([1, 1, 1, 1, 1]) +// +// >>> np.ones((2, 1)) +// array([[1.], +// +// [1.]]) +// +// >>> s = (2,2) +// >>> np.ones(s) +// array([[1., 1.], +// +// [1., 1.]]) +// +//go:linkname Ones py.ones +func Ones(shape *py.Object, dtype *py.Object, order *py.Object) *py.Object + +// Return the identity array. +// +// The identity array is a square array with ones on +// the main diagonal. +// +// Parameters +// ---------- +// n : int +// +// Number of rows (and columns) in `n` x `n` output. +// +// dtype : data-type, optional +// +// Data-type of the output. Defaults to ``float``. +// +// like : array_like, optional +// +// Reference object to allow the creation of arrays which are not +// NumPy arrays. If an array-like passed in as ``like`` supports +// the ``__array_function__`` protocol, the result will be defined +// by it. In this case, it ensures the creation of an array object +// compatible with that passed in via this argument. +// +// .. versionadded:: 1.20.0 +// +// Returns +// ------- +// out : ndarray +// +// `n` x `n` array with its main diagonal set to one, +// and all other elements 0. +// +// Examples +// -------- +// >>> np.identity(3) +// array([[1., 0., 0.], +// +// [0., 1., 0.], +// [0., 0., 1.]]) +// +//go:linkname Identity py.identity +func Identity(n *py.Object, dtype *py.Object) *py.Object + +// invert(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Compute bit-wise inversion, or bit-wise NOT, element-wise. +// +// Computes the bit-wise NOT of the underlying binary representation of +// the integers in the input arrays. This ufunc implements the C/Python +// operator “~“. +// +// For signed integer inputs, the two's complement is returned. In a +// two's-complement system negative numbers are represented by the two's +// complement of the absolute value. This is the most common method of +// representing signed integers on computers [1]_. A N-bit +// two's-complement system can represent every integer in the range +// :math:`-2^{N-1}` to :math:`+2^{N-1}-1`. +// +// Parameters +// ---------- +// x : array_like +// +// Only integer and boolean types are handled. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Result. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// bitwise_and, bitwise_or, bitwise_xor +// logical_not +// binary_repr : +// +// Return the binary representation of the input number as a string. +// +// Notes +// ----- +// `bitwise_not` is an alias for `invert`: +// +// >>> np.bitwise_not is np.invert +// True +// +// References +// ---------- +// .. [1] Wikipedia, "Two's complement", +// +// https://en.wikipedia.org/wiki/Two's_complement +// +// Examples +// -------- +// We've seen that 13 is represented by “00001101“. +// The invert or bit-wise NOT of 13 is then: +// +// >>> x = np.invert(np.array(13, dtype=np.uint8)) +// >>> x +// 242 +// >>> np.binary_repr(x, width=8) +// '11110010' +// +// The result depends on the bit-width: +// +// >>> x = np.invert(np.array(13, dtype=np.uint16)) +// >>> x +// 65522 +// >>> np.binary_repr(x, width=16) +// '1111111111110010' +// +// When using signed integer types the result is the two's complement of +// the result for the unsigned type: +// +// >>> np.invert(np.array([13], dtype=np.int8)) +// array([-14], dtype=int8) +// >>> np.binary_repr(-14, width=8) +// '11110010' +// +// Booleans are accepted as well: +// +// >>> np.invert(np.array([True, False])) +// array([False, True]) +// +// The “~“ operator can be used as a shorthand for “np.invert“ on +// ndarrays. +// +// >>> x1 = np.array([True, False]) +// >>> ~x1 +// array([False, True]) +// +//go:linkname BitwiseNot py.bitwise_not +func BitwiseNot(__llgo_va_list ...interface{}) *py.Object + +// Return a new array of given shape and type, filled with `fill_value`. +// +// Parameters +// ---------- +// shape : int or sequence of ints +// +// Shape of the new array, e.g., ``(2, 3)`` or ``2``. +// +// fill_value : scalar or array_like +// +// Fill value. +// +// dtype : data-type, optional +// +// The desired data-type for the array The default, None, means +// ``np.array(fill_value).dtype``. +// +// order : {'C', 'F'}, optional +// +// Whether to store multidimensional data in C- or Fortran-contiguous +// (row- or column-wise) order in memory. +// +// like : array_like, optional +// +// Reference object to allow the creation of arrays which are not +// NumPy arrays. If an array-like passed in as ``like`` supports +// the ``__array_function__`` protocol, the result will be defined +// by it. In this case, it ensures the creation of an array object +// compatible with that passed in via this argument. +// +// .. versionadded:: 1.20.0 +// +// Returns +// ------- +// out : ndarray +// +// Array of `fill_value` with the given shape, dtype, and order. +// +// See Also +// -------- +// full_like : Return a new array with shape of input filled with value. +// empty : Return a new uninitialized array. +// ones : Return a new array setting values to one. +// zeros : Return a new array setting values to zero. +// +// Examples +// -------- +// >>> np.full((2, 2), np.inf) +// array([[inf, inf], +// +// [inf, inf]]) +// +// >>> np.full((2, 2), 10) +// array([[10, 10], +// +// [10, 10]]) +// +// >>> np.full((2, 2), [1, 2]) +// array([[1, 2], +// +// [1, 2]]) +// +//go:linkname Full py.full +func Full(shape *py.Object, fillValue *py.Object, dtype *py.Object, order *py.Object) *py.Object + +// matmul(x1, x2, /, out=None, *, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj, axes, axis]) +// +// Matrix product of two arrays. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Input arrays, scalars not allowed. +// +// out : ndarray, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that matches the signature `(n,k),(k,m)->(n,m)`. If not +// provided or None, a freshly-allocated array is returned. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// .. versionadded:: 1.16 +// Now handles ufunc kwargs +// +// Returns +// ------- +// y : ndarray +// +// The matrix product of the inputs. +// This is a scalar only when both x1, x2 are 1-d vectors. +// +// Raises +// ------ +// ValueError +// +// If the last dimension of `x1` is not the same size as +// the second-to-last dimension of `x2`. +// +// If a scalar value is passed in. +// +// See Also +// -------- +// vdot : Complex-conjugating dot product. +// tensordot : Sum products over arbitrary axes. +// einsum : Einstein summation convention. +// dot : alternative matrix product with different broadcasting rules. +// +// Notes +// ----- +// +// The behavior depends on the arguments in the following way. +// +// - If both arguments are 2-D they are multiplied like conventional +// matrices. +// - If either argument is N-D, N > 2, it is treated as a stack of +// matrices residing in the last two indexes and broadcast accordingly. +// - If the first argument is 1-D, it is promoted to a matrix by +// prepending a 1 to its dimensions. After matrix multiplication +// the prepended 1 is removed. +// - If the second argument is 1-D, it is promoted to a matrix by +// appending a 1 to its dimensions. After matrix multiplication +// the appended 1 is removed. +// +// “matmul“ differs from “dot“ in two important ways: +// +// - Multiplication by scalars is not allowed, use “*“ instead. +// +// - Stacks of matrices are broadcast together as if the matrices +// were elements, respecting the signature “(n,k),(k,m)->(n,m)“: +// +// >>> a = np.ones([9, 5, 7, 4]) +// >>> c = np.ones([9, 5, 4, 3]) +// >>> np.dot(a, c).shape +// (9, 5, 7, 9, 5, 3) +// >>> np.matmul(a, c).shape +// (9, 5, 7, 3) +// >>> # n is 7, k is 4, m is 3 +// +// The matmul function implements the semantics of the “@“ operator +// introduced in Python 3.5 following :pep:`465`. +// +// It uses an optimized BLAS library when possible (see `numpy.linalg`). +// +// Examples +// -------- +// For 2-D arrays it is the matrix product: +// +// >>> a = np.array([[1, 0], +// ... [0, 1]]) +// >>> b = np.array([[4, 1], +// ... [2, 2]]) +// >>> np.matmul(a, b) +// array([[4, 1], +// +// [2, 2]]) +// +// For 2-D mixed with 1-D, the result is the usual. +// +// >>> a = np.array([[1, 0], +// ... [0, 1]]) +// >>> b = np.array([1, 2]) +// >>> np.matmul(a, b) +// array([1, 2]) +// >>> np.matmul(b, a) +// array([1, 2]) +// +// # Broadcasting is conventional for stacks of arrays +// +// >>> a = np.arange(2 * 2 * 4).reshape((2, 2, 4)) +// >>> b = np.arange(2 * 2 * 4).reshape((2, 4, 2)) +// >>> np.matmul(a,b).shape +// (2, 2, 2) +// >>> np.matmul(a, b)[0, 1, 1] +// 98 +// >>> sum(a[0, 1, :] * b[0 , :, 1]) +// 98 +// +// Vector, vector returns the scalar inner product, but neither argument +// is complex-conjugated: +// +// >>> np.matmul([2j, 3j], [2j, 3j]) +// (-13+0j) +// +// Scalar multiplication raises an error. +// +// >>> np.matmul([1,2], 3) +// Traceback (most recent call last): +// ... +// ValueError: matmul: Input operand 1 does not have enough dimensions ... +// +// The “@“ operator can be used as a shorthand for “np.matmul“ on +// ndarrays. +// +// >>> x1 = np.array([2j, 3j]) +// >>> x2 = np.array([2j, 3j]) +// >>> x1 @ x2 +// (-13+0j) +// +// .. versionadded:: 1.10.0 +// +//go:linkname Matmul py.matmul +func Matmul(__llgo_va_list ...interface{}) *py.Object + +// absolute(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Calculate the absolute value element-wise. +// +// “np.abs“ is a shorthand for this function. +// +// Parameters +// ---------- +// x : array_like +// +// Input array. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// absolute : ndarray +// +// An ndarray containing the absolute value of +// each element in `x`. For complex input, ``a + ib``, the +// absolute value is :math:`\sqrt{ a^2 + b^2 }`. +// This is a scalar if `x` is a scalar. +// +// Examples +// -------- +// >>> x = np.array([-1.2, 1.2]) +// >>> np.absolute(x) +// array([ 1.2, 1.2]) +// >>> np.absolute(1.2 + 1j) +// 1.5620499351813308 +// +// Plot the function over “[-10, 10]“: +// +// >>> import matplotlib.pyplot as plt +// +// >>> x = np.linspace(start=-10, stop=10, num=101) +// >>> plt.plot(x, np.absolute(x)) +// >>> plt.show() +// +// Plot the function over the complex plane: +// +// >>> xx = x + 1j * x[:, np.newaxis] +// >>> plt.imshow(np.abs(xx), extent=[-10, 10, -10, 10], cmap='gray') +// >>> plt.show() +// +// The `abs` function can be used as a shorthand for “np.absolute“ on +// ndarrays. +// +// >>> x = np.array([-1.2, 1.2]) +// >>> abs(x) +// array([1.2, 1.2]) +// +//go:linkname Absolute py.absolute +func Absolute(__llgo_va_list ...interface{}) *py.Object + +// add(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Add arguments element-wise. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// The arrays to be added. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// add : ndarray or scalar +// +// The sum of `x1` and `x2`, element-wise. +// This is a scalar if both `x1` and `x2` are scalars. +// +// Notes +// ----- +// Equivalent to `x1` + `x2` in terms of array broadcasting. +// +// Examples +// -------- +// >>> np.add(1.0, 4.0) +// 5.0 +// >>> x1 = np.arange(9.0).reshape((3, 3)) +// >>> x2 = np.arange(3.0) +// >>> np.add(x1, x2) +// array([[ 0., 2., 4.], +// +// [ 3., 5., 7.], +// [ 6., 8., 10.]]) +// +// The “+“ operator can be used as a shorthand for “np.add“ on ndarrays. +// +// >>> x1 = np.arange(9.0).reshape((3, 3)) +// >>> x2 = np.arange(3.0) +// >>> x1 + x2 +// array([[ 0., 2., 4.], +// +// [ 3., 5., 7.], +// [ 6., 8., 10.]]) +// +//go:linkname Add py.add +func Add(__llgo_va_list ...interface{}) *py.Object + +// arccos(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Trigonometric inverse cosine, element-wise. +// +// The inverse of `cos` so that, if “y = cos(x)“, then “x = arccos(y)“. +// +// Parameters +// ---------- +// x : array_like +// +// `x`-coordinate on the unit circle. +// For real arguments, the domain is [-1, 1]. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// angle : ndarray +// +// The angle of the ray intersecting the unit circle at the given +// `x`-coordinate in radians [0, pi]. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// cos, arctan, arcsin, emath.arccos +// +// Notes +// ----- +// `arccos` is a multivalued function: for each `x` there are infinitely +// many numbers `z` such that “cos(z) = x“. The convention is to return +// the angle `z` whose real part lies in `[0, pi]`. +// +// For real-valued input data types, `arccos` always returns real output. +// For each value that cannot be expressed as a real number or infinity, +// it yields “nan“ and sets the `invalid` floating point error flag. +// +// For complex-valued input, `arccos` is a complex analytic function that +// has branch cuts “[-inf, -1]“ and `[1, inf]` and is continuous from +// above on the former and from below on the latter. +// +// The inverse `cos` is also known as `acos` or cos^-1. +// +// References +// ---------- +// M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions", +// 10th printing, 1964, pp. 79. +// https://personal.math.ubc.ca/~cbm/aands/page_79.htm +// +// Examples +// -------- +// We expect the arccos of 1 to be 0, and of -1 to be pi: +// +// >>> np.arccos([1, -1]) +// array([ 0. , 3.14159265]) +// +// Plot arccos: +// +// >>> import matplotlib.pyplot as plt +// >>> x = np.linspace(-1, 1, num=100) +// >>> plt.plot(x, np.arccos(x)) +// >>> plt.axis('tight') +// >>> plt.show() +// +//go:linkname Arccos py.arccos +func Arccos(__llgo_va_list ...interface{}) *py.Object + +// arccosh(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Inverse hyperbolic cosine, element-wise. +// +// Parameters +// ---------- +// x : array_like +// +// Input array. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// arccosh : ndarray +// +// Array of the same shape as `x`. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// +// cosh, arcsinh, sinh, arctanh, tanh +// +// Notes +// ----- +// `arccosh` is a multivalued function: for each `x` there are infinitely +// many numbers `z` such that `cosh(z) = x`. The convention is to return the +// `z` whose imaginary part lies in “[-pi, pi]“ and the real part in +// “[0, inf]“. +// +// For real-valued input data types, `arccosh` always returns real output. +// For each value that cannot be expressed as a real number or infinity, it +// yields “nan“ and sets the `invalid` floating point error flag. +// +// For complex-valued input, `arccosh` is a complex analytical function that +// has a branch cut `[-inf, 1]` and is continuous from above on it. +// +// References +// ---------- +// .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions", +// +// 10th printing, 1964, pp. 86. +// https://personal.math.ubc.ca/~cbm/aands/page_86.htm +// +// .. [2] Wikipedia, "Inverse hyperbolic function", +// +// https://en.wikipedia.org/wiki/Arccosh +// +// Examples +// -------- +// >>> np.arccosh([np.e, 10.0]) +// array([ 1.65745445, 2.99322285]) +// >>> np.arccosh(1) +// 0.0 +// +//go:linkname Arccosh py.arccosh +func Arccosh(__llgo_va_list ...interface{}) *py.Object + +// arcsin(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Inverse sine, element-wise. +// +// Parameters +// ---------- +// x : array_like +// +// `y`-coordinate on the unit circle. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// angle : ndarray +// +// The inverse sine of each element in `x`, in radians and in the +// closed interval ``[-pi/2, pi/2]``. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// sin, cos, arccos, tan, arctan, arctan2, emath.arcsin +// +// Notes +// ----- +// `arcsin` is a multivalued function: for each `x` there are infinitely +// many numbers `z` such that :math:`sin(z) = x`. The convention is to +// return the angle `z` whose real part lies in [-pi/2, pi/2]. +// +// For real-valued input data types, *arcsin* always returns real output. +// For each value that cannot be expressed as a real number or infinity, +// it yields “nan“ and sets the `invalid` floating point error flag. +// +// For complex-valued input, `arcsin` is a complex analytic function that +// has, by convention, the branch cuts [-inf, -1] and [1, inf] and is +// continuous from above on the former and from below on the latter. +// +// The inverse sine is also known as `asin` or sin^{-1}. +// +// References +// ---------- +// Abramowitz, M. and Stegun, I. A., *Handbook of Mathematical Functions*, +// 10th printing, New York: Dover, 1964, pp. 79ff. +// https://personal.math.ubc.ca/~cbm/aands/page_79.htm +// +// Examples +// -------- +// >>> np.arcsin(1) # pi/2 +// 1.5707963267948966 +// >>> np.arcsin(-1) # -pi/2 +// -1.5707963267948966 +// >>> np.arcsin(0) +// 0.0 +// +//go:linkname Arcsin py.arcsin +func Arcsin(__llgo_va_list ...interface{}) *py.Object + +// arcsinh(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Inverse hyperbolic sine element-wise. +// +// Parameters +// ---------- +// x : array_like +// +// Input array. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Array of the same shape as `x`. +// This is a scalar if `x` is a scalar. +// +// Notes +// ----- +// `arcsinh` is a multivalued function: for each `x` there are infinitely +// many numbers `z` such that `sinh(z) = x`. The convention is to return the +// `z` whose imaginary part lies in `[-pi/2, pi/2]`. +// +// For real-valued input data types, `arcsinh` always returns real output. +// For each value that cannot be expressed as a real number or infinity, it +// returns “nan“ and sets the `invalid` floating point error flag. +// +// For complex-valued input, `arccos` is a complex analytical function that +// has branch cuts `[1j, infj]` and `[-1j, -infj]` and is continuous from +// the right on the former and from the left on the latter. +// +// The inverse hyperbolic sine is also known as `asinh` or “sinh^-1“. +// +// References +// ---------- +// .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions", +// +// 10th printing, 1964, pp. 86. +// https://personal.math.ubc.ca/~cbm/aands/page_86.htm +// +// .. [2] Wikipedia, "Inverse hyperbolic function", +// +// https://en.wikipedia.org/wiki/Arcsinh +// +// Examples +// -------- +// >>> np.arcsinh(np.array([np.e, 10.0])) +// array([ 1.72538256, 2.99822295]) +// +//go:linkname Arcsinh py.arcsinh +func Arcsinh(__llgo_va_list ...interface{}) *py.Object + +// arctan(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Trigonometric inverse tangent, element-wise. +// +// The inverse of tan, so that if “y = tan(x)“ then “x = arctan(y)“. +// +// Parameters +// ---------- +// x : array_like +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Out has the same shape as `x`. Its real part is in +// ``[-pi/2, pi/2]`` (``arctan(+/-inf)`` returns ``+/-pi/2``). +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// arctan2 : The "four quadrant" arctan of the angle formed by (`x`, `y`) +// +// and the positive `x`-axis. +// +// angle : Argument of complex values. +// +// Notes +// ----- +// `arctan` is a multi-valued function: for each `x` there are infinitely +// many numbers `z` such that tan(`z`) = `x`. The convention is to return +// the angle `z` whose real part lies in [-pi/2, pi/2]. +// +// For real-valued input data types, `arctan` always returns real output. +// For each value that cannot be expressed as a real number or infinity, +// it yields “nan“ and sets the `invalid` floating point error flag. +// +// For complex-valued input, `arctan` is a complex analytic function that +// has [“1j, infj“] and [“-1j, -infj“] as branch cuts, and is continuous +// from the left on the former and from the right on the latter. +// +// The inverse tangent is also known as `atan` or tan^{-1}. +// +// References +// ---------- +// Abramowitz, M. and Stegun, I. A., *Handbook of Mathematical Functions*, +// 10th printing, New York: Dover, 1964, pp. 79. +// https://personal.math.ubc.ca/~cbm/aands/page_79.htm +// +// Examples +// -------- +// We expect the arctan of 0 to be 0, and of 1 to be pi/4: +// +// >>> np.arctan([0, 1]) +// array([ 0. , 0.78539816]) +// +// >>> np.pi/4 +// 0.78539816339744828 +// +// Plot arctan: +// +// >>> import matplotlib.pyplot as plt +// >>> x = np.linspace(-10, 10) +// >>> plt.plot(x, np.arctan(x)) +// >>> plt.axis('tight') +// >>> plt.show() +// +//go:linkname Arctan py.arctan +func Arctan(__llgo_va_list ...interface{}) *py.Object + +// arctan2(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Element-wise arc tangent of “x1/x2“ choosing the quadrant correctly. +// +// The quadrant (i.e., branch) is chosen so that “arctan2(x1, x2)“ is +// the signed angle in radians between the ray ending at the origin and +// passing through the point (1,0), and the ray ending at the origin and +// passing through the point (`x2`, `x1`). (Note the role reversal: the +// "`y`-coordinate" is the first function parameter, the "`x`-coordinate" +// is the second.) By IEEE convention, this function is defined for +// `x2` = +/-0 and for either or both of `x1` and `x2` = +/-inf (see +// Notes for specific values). +// +// This function is not defined for complex-valued arguments; for the +// so-called argument of complex values, use `angle`. +// +// Parameters +// ---------- +// x1 : array_like, real-valued +// +// `y`-coordinates. +// +// x2 : array_like, real-valued +// +// `x`-coordinates. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// angle : ndarray +// +// Array of angles in radians, in the range ``[-pi, pi]``. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// arctan, tan, angle +// +// Notes +// ----- +// *arctan2* is identical to the `atan2` function of the underlying +// C library. The following special values are defined in the C +// standard: [1]_ +// +// ====== ====== ================ +// `x1` `x2` `arctan2(x1,x2)` +// ====== ====== ================ +// +/- 0 +0 +/- 0 +// +/- 0 -0 +/- pi +// +// > 0 +/-inf +0 / +pi +// < 0 +/-inf -0 / -pi +// +// +/-inf +inf +/- (pi/4) +// +/-inf -inf +/- (3*pi/4) +// ====== ====== ================ +// +// Note that +0 and -0 are distinct floating point numbers, as are +inf +// and -inf. +// +// References +// ---------- +// .. [1] ISO/IEC standard 9899:1999, "Programming language C." +// +// Examples +// -------- +// Consider four points in different quadrants: +// +// >>> x = np.array([-1, +1, +1, -1]) +// >>> y = np.array([-1, -1, +1, +1]) +// >>> np.arctan2(y, x) * 180 / np.pi +// array([-135., -45., 45., 135.]) +// +// Note the order of the parameters. `arctan2` is defined also when `x2` = 0 +// and at several other special points, obtaining values in +// the range “[-pi, pi]“: +// +// >>> np.arctan2([1., -1.], [0., 0.]) +// array([ 1.57079633, -1.57079633]) +// >>> np.arctan2([0., 0., np.inf], [+0., -0., np.inf]) +// array([0. , 3.14159265, 0.78539816]) +// +//go:linkname Arctan2 py.arctan2 +func Arctan2(__llgo_va_list ...interface{}) *py.Object + +// arctanh(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Inverse hyperbolic tangent element-wise. +// +// Parameters +// ---------- +// x : array_like +// +// Input array. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Array of the same shape as `x`. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// emath.arctanh +// +// Notes +// ----- +// `arctanh` is a multivalued function: for each `x` there are infinitely +// many numbers `z` such that “tanh(z) = x“. The convention is to return +// the `z` whose imaginary part lies in `[-pi/2, pi/2]`. +// +// For real-valued input data types, `arctanh` always returns real output. +// For each value that cannot be expressed as a real number or infinity, +// it yields “nan“ and sets the `invalid` floating point error flag. +// +// For complex-valued input, `arctanh` is a complex analytical function +// that has branch cuts `[-1, -inf]` and `[1, inf]` and is continuous from +// above on the former and from below on the latter. +// +// The inverse hyperbolic tangent is also known as `atanh` or “tanh^-1“. +// +// References +// ---------- +// .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions", +// +// 10th printing, 1964, pp. 86. +// https://personal.math.ubc.ca/~cbm/aands/page_86.htm +// +// .. [2] Wikipedia, "Inverse hyperbolic function", +// +// https://en.wikipedia.org/wiki/Arctanh +// +// Examples +// -------- +// >>> np.arctanh([0, -0.5]) +// array([ 0. , -0.54930614]) +// +//go:linkname Arctanh py.arctanh +func Arctanh(__llgo_va_list ...interface{}) *py.Object + +// bitwise_and(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Compute the bit-wise AND of two arrays element-wise. +// +// Computes the bit-wise AND of the underlying binary representation of +// the integers in the input arrays. This ufunc implements the C/Python +// operator “&“. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Only integer and boolean types are handled. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Result. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// logical_and +// bitwise_or +// bitwise_xor +// binary_repr : +// +// Return the binary representation of the input number as a string. +// +// Examples +// -------- +// The number 13 is represented by “00001101“. Likewise, 17 is +// represented by “00010001“. The bit-wise AND of 13 and 17 is +// therefore “000000001“, or 1: +// +// >>> np.bitwise_and(13, 17) +// 1 +// +// >>> np.bitwise_and(14, 13) +// 12 +// >>> np.binary_repr(12) +// '1100' +// >>> np.bitwise_and([14,3], 13) +// array([12, 1]) +// +// >>> np.bitwise_and([11,7], [4,25]) +// array([0, 1]) +// >>> np.bitwise_and(np.array([2,5,255]), np.array([3,14,16])) +// array([ 2, 4, 16]) +// >>> np.bitwise_and([True, True], [False, True]) +// array([False, True]) +// +// The “&“ operator can be used as a shorthand for “np.bitwise_and“ on +// ndarrays. +// +// >>> x1 = np.array([2, 5, 255]) +// >>> x2 = np.array([3, 14, 16]) +// >>> x1 & x2 +// array([ 2, 4, 16]) +// +//go:linkname BitwiseAnd py.bitwise_and +func BitwiseAnd(__llgo_va_list ...interface{}) *py.Object + +// bitwise_or(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Compute the bit-wise OR of two arrays element-wise. +// +// Computes the bit-wise OR of the underlying binary representation of +// the integers in the input arrays. This ufunc implements the C/Python +// operator “|“. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Only integer and boolean types are handled. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Result. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// logical_or +// bitwise_and +// bitwise_xor +// binary_repr : +// +// Return the binary representation of the input number as a string. +// +// Examples +// -------- +// The number 13 has the binary representation “00001101“. Likewise, +// 16 is represented by “00010000“. The bit-wise OR of 13 and 16 is +// then “00011101“, or 29: +// +// >>> np.bitwise_or(13, 16) +// 29 +// >>> np.binary_repr(29) +// '11101' +// +// >>> np.bitwise_or(32, 2) +// 34 +// >>> np.bitwise_or([33, 4], 1) +// array([33, 5]) +// >>> np.bitwise_or([33, 4], [1, 2]) +// array([33, 6]) +// +// >>> np.bitwise_or(np.array([2, 5, 255]), np.array([4, 4, 4])) +// array([ 6, 5, 255]) +// >>> np.array([2, 5, 255]) | np.array([4, 4, 4]) +// array([ 6, 5, 255]) +// >>> np.bitwise_or(np.array([2, 5, 255, 2147483647], dtype=np.int32), +// ... np.array([4, 4, 4, 2147483647], dtype=np.int32)) +// array([ 6, 5, 255, 2147483647]) +// >>> np.bitwise_or([True, True], [False, True]) +// array([ True, True]) +// +// The “|“ operator can be used as a shorthand for “np.bitwise_or“ on +// ndarrays. +// +// >>> x1 = np.array([2, 5, 255]) +// >>> x2 = np.array([4, 4, 4]) +// >>> x1 | x2 +// array([ 6, 5, 255]) +// +//go:linkname BitwiseOr py.bitwise_or +func BitwiseOr(__llgo_va_list ...interface{}) *py.Object + +// bitwise_xor(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Compute the bit-wise XOR of two arrays element-wise. +// +// Computes the bit-wise XOR of the underlying binary representation of +// the integers in the input arrays. This ufunc implements the C/Python +// operator “^“. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Only integer and boolean types are handled. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Result. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// logical_xor +// bitwise_and +// bitwise_or +// binary_repr : +// +// Return the binary representation of the input number as a string. +// +// Examples +// -------- +// The number 13 is represented by “00001101“. Likewise, 17 is +// represented by “00010001“. The bit-wise XOR of 13 and 17 is +// therefore “00011100“, or 28: +// +// >>> np.bitwise_xor(13, 17) +// 28 +// >>> np.binary_repr(28) +// '11100' +// +// >>> np.bitwise_xor(31, 5) +// 26 +// >>> np.bitwise_xor([31,3], 5) +// array([26, 6]) +// +// >>> np.bitwise_xor([31,3], [5,6]) +// array([26, 5]) +// >>> np.bitwise_xor([True, True], [False, True]) +// array([ True, False]) +// +// The “^“ operator can be used as a shorthand for “np.bitwise_xor“ on +// ndarrays. +// +// >>> x1 = np.array([True, True]) +// >>> x2 = np.array([False, True]) +// >>> x1 ^ x2 +// array([ True, False]) +// +//go:linkname BitwiseXor py.bitwise_xor +func BitwiseXor(__llgo_va_list ...interface{}) *py.Object + +// cbrt(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the cube-root of an array, element-wise. +// +// .. versionadded:: 1.10.0 +// +// Parameters +// ---------- +// x : array_like +// +// The values whose cube-roots are required. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// An array of the same shape as `x`, containing the cube +// cube-root of each element in `x`. +// If `out` was provided, `y` is a reference to it. +// This is a scalar if `x` is a scalar. +// +// Examples +// -------- +// >>> np.cbrt([1,8,27]) +// array([ 1., 2., 3.]) +// +//go:linkname Cbrt py.cbrt +func Cbrt(__llgo_va_list ...interface{}) *py.Object + +// ceil(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the ceiling of the input, element-wise. +// +// The ceil of the scalar `x` is the smallest integer `i`, such that +// “i >= x“. It is often denoted as :math:`\lceil x \rceil`. +// +// Parameters +// ---------- +// x : array_like +// +// Input data. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or scalar +// +// The ceiling of each element in `x`, with `float` dtype. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// floor, trunc, rint, fix +// +// Examples +// -------- +// >>> a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]) +// >>> np.ceil(a) +// array([-1., -1., -0., 1., 2., 2., 2.]) +// +//go:linkname Ceil py.ceil +func Ceil(__llgo_va_list ...interface{}) *py.Object + +// conjugate(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the complex conjugate, element-wise. +// +// The complex conjugate of a complex number is obtained by changing the +// sign of its imaginary part. +// +// Parameters +// ---------- +// x : array_like +// +// Input value. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The complex conjugate of `x`, with same dtype as `y`. +// This is a scalar if `x` is a scalar. +// +// Notes +// ----- +// `conj` is an alias for `conjugate`: +// +// >>> np.conj is np.conjugate +// True +// +// Examples +// -------- +// >>> np.conjugate(1+2j) +// (1-2j) +// +// >>> x = np.eye(2) + 1j * np.eye(2) +// >>> np.conjugate(x) +// array([[ 1.-1.j, 0.-0.j], +// +// [ 0.-0.j, 1.-1.j]]) +// +//go:linkname Conj py.conj +func Conj(__llgo_va_list ...interface{}) *py.Object + +// conjugate(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the complex conjugate, element-wise. +// +// The complex conjugate of a complex number is obtained by changing the +// sign of its imaginary part. +// +// Parameters +// ---------- +// x : array_like +// +// Input value. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The complex conjugate of `x`, with same dtype as `y`. +// This is a scalar if `x` is a scalar. +// +// Notes +// ----- +// `conj` is an alias for `conjugate`: +// +// >>> np.conj is np.conjugate +// True +// +// Examples +// -------- +// >>> np.conjugate(1+2j) +// (1-2j) +// +// >>> x = np.eye(2) + 1j * np.eye(2) +// >>> np.conjugate(x) +// array([[ 1.-1.j, 0.-0.j], +// +// [ 0.-0.j, 1.-1.j]]) +// +//go:linkname Conjugate py.conjugate +func Conjugate(__llgo_va_list ...interface{}) *py.Object + +// copysign(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Change the sign of x1 to that of x2, element-wise. +// +// If `x2` is a scalar, its sign will be copied to all elements of `x1`. +// +// Parameters +// ---------- +// x1 : array_like +// +// Values to change the sign of. +// +// x2 : array_like +// +// The sign of `x2` is copied to `x1`. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// The values of `x1` with the sign of `x2`. +// This is a scalar if both `x1` and `x2` are scalars. +// +// Examples +// -------- +// >>> np.copysign(1.3, -1) +// -1.3 +// >>> 1/np.copysign(0, 1) +// inf +// >>> 1/np.copysign(0, -1) +// -inf +// +// >>> np.copysign([-1, 0, 1], -1.1) +// array([-1., -0., -1.]) +// >>> np.copysign([-1, 0, 1], np.arange(3)-1) +// array([-1., 0., 1.]) +// +//go:linkname Copysign py.copysign +func Copysign(__llgo_va_list ...interface{}) *py.Object + +// cos(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Cosine element-wise. +// +// Parameters +// ---------- +// x : array_like +// +// Input array in radians. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The corresponding cosine values. +// This is a scalar if `x` is a scalar. +// +// Notes +// ----- +// If `out` is provided, the function writes the result into it, +// and returns a reference to `out`. (See Examples) +// +// References +// ---------- +// M. Abramowitz and I. A. Stegun, Handbook of Mathematical Functions. +// New York, NY: Dover, 1972. +// +// Examples +// -------- +// >>> np.cos(np.array([0, np.pi/2, np.pi])) +// array([ 1.00000000e+00, 6.12303177e-17, -1.00000000e+00]) +// >>> +// >>> # Example of providing the optional output parameter +// >>> out1 = np.array([0], dtype='d') +// >>> out2 = np.cos([0.1], out1) +// >>> out2 is out1 +// True +// >>> +// >>> # Example of ValueError due to provision of shape mis-matched `out` +// >>> np.cos(np.zeros((3,3)),np.zeros((2,2))) +// Traceback (most recent call last): +// +// File "", line 1, in +// +// ValueError: operands could not be broadcast together with shapes (3,3) (2,2) +// +//go:linkname Cos py.cos +func Cos(__llgo_va_list ...interface{}) *py.Object + +// cosh(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Hyperbolic cosine, element-wise. +// +// Equivalent to “1/2 * (np.exp(x) + np.exp(-x))“ and “np.cos(1j*x)“. +// +// Parameters +// ---------- +// x : array_like +// +// Input array. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Output array of same shape as `x`. +// This is a scalar if `x` is a scalar. +// +// Examples +// -------- +// >>> np.cosh(0) +// 1.0 +// +// The hyperbolic cosine describes the shape of a hanging cable: +// +// >>> import matplotlib.pyplot as plt +// >>> x = np.linspace(-4, 4, 1000) +// >>> plt.plot(x, np.cosh(x)) +// >>> plt.show() +// +//go:linkname Cosh py.cosh +func Cosh(__llgo_va_list ...interface{}) *py.Object + +// deg2rad(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Convert angles from degrees to radians. +// +// Parameters +// ---------- +// x : array_like +// +// Angles in degrees. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The corresponding angle in radians. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// rad2deg : Convert angles from radians to degrees. +// unwrap : Remove large jumps in angle by wrapping. +// +// Notes +// ----- +// .. versionadded:: 1.3.0 +// +// “deg2rad(x)“ is “x * pi / 180“. +// +// Examples +// -------- +// >>> np.deg2rad(180) +// 3.1415926535897931 +// +//go:linkname Deg2rad py.deg2rad +func Deg2rad(__llgo_va_list ...interface{}) *py.Object + +// degrees(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Convert angles from radians to degrees. +// +// Parameters +// ---------- +// x : array_like +// +// Input array in radians. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray of floats +// +// The corresponding degree values; if `out` was supplied this is a +// reference to it. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// rad2deg : equivalent function +// +// Examples +// -------- +// Convert a radian array to degrees +// +// >>> rad = np.arange(12.)*np.pi/6 +// >>> np.degrees(rad) +// array([ 0., 30., 60., 90., 120., 150., 180., 210., 240., +// +// 270., 300., 330.]) +// +// >>> out = np.zeros((rad.shape)) +// >>> r = np.degrees(rad, out) +// >>> np.all(r == out) +// True +// +//go:linkname Degrees py.degrees +func Degrees(__llgo_va_list ...interface{}) *py.Object + +// divide(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Divide arguments element-wise. +// +// Parameters +// ---------- +// x1 : array_like +// +// Dividend array. +// +// x2 : array_like +// +// Divisor array. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or scalar +// +// The quotient ``x1/x2``, element-wise. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// seterr : Set whether to raise or warn on overflow, underflow and +// +// division by zero. +// +// Notes +// ----- +// Equivalent to “x1“ / “x2“ in terms of array-broadcasting. +// +// The “true_divide(x1, x2)“ function is an alias for +// “divide(x1, x2)“. +// +// Examples +// -------- +// >>> np.divide(2.0, 4.0) +// 0.5 +// >>> x1 = np.arange(9.0).reshape((3, 3)) +// >>> x2 = np.arange(3.0) +// >>> np.divide(x1, x2) +// array([[nan, 1. , 1. ], +// +// [inf, 4. , 2.5], +// [inf, 7. , 4. ]]) +// +// The “/“ operator can be used as a shorthand for “np.divide“ on +// ndarrays. +// +// >>> x1 = np.arange(9.0).reshape((3, 3)) +// >>> x2 = 2 * np.ones(3) +// >>> x1 / x2 +// array([[0. , 0.5, 1. ], +// +// [1.5, 2. , 2.5], +// [3. , 3.5, 4. ]]) +// +//go:linkname Divide py.divide +func Divide(__llgo_va_list ...interface{}) *py.Object + +// divmod(x1, x2[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return element-wise quotient and remainder simultaneously. +// +// .. versionadded:: 1.13.0 +// +// “np.divmod(x, y)“ is equivalent to “(x // y, x % y)“, but faster +// because it avoids redundant work. It is used to implement the Python +// built-in function “divmod“ on NumPy arrays. +// +// Parameters +// ---------- +// x1 : array_like +// +// Dividend array. +// +// x2 : array_like +// +// Divisor array. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out1 : ndarray +// +// Element-wise quotient resulting from floor division. +// This is a scalar if both `x1` and `x2` are scalars. +// +// out2 : ndarray +// +// Element-wise remainder from floor division. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// floor_divide : Equivalent to Python's “//“ operator. +// remainder : Equivalent to Python's “%“ operator. +// modf : Equivalent to “divmod(x, 1)“ for positive “x“ with the return +// +// values switched. +// +// Examples +// -------- +// >>> np.divmod(np.arange(5), 3) +// (array([0, 0, 0, 1, 1]), array([0, 1, 2, 0, 1])) +// +// The `divmod` function can be used as a shorthand for “np.divmod“ on +// ndarrays. +// +// >>> x = np.arange(5) +// >>> divmod(x, 3) +// (array([0, 0, 0, 1, 1]), array([0, 1, 2, 0, 1])) +// +//go:linkname Divmod py.divmod +func Divmod(__llgo_va_list ...interface{}) *py.Object + +// equal(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return (x1 == x2) element-wise. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Input arrays. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Output array, element-wise comparison of `x1` and `x2`. +// Typically of type bool, unless ``dtype=object`` is passed. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// not_equal, greater_equal, less_equal, greater, less +// +// Examples +// -------- +// >>> np.equal([0, 1, 3], np.arange(3)) +// array([ True, True, False]) +// +// What is compared are values, not types. So an int (1) and an array of +// length one can evaluate as True: +// +// >>> np.equal(1, np.ones(1)) +// array([ True]) +// +// The “==“ operator can be used as a shorthand for “np.equal“ on +// ndarrays. +// +// >>> a = np.array([2, 4, 6]) +// >>> b = np.array([2, 4, 2]) +// >>> a == b +// array([ True, True, False]) +// +//go:linkname Equal py.equal +func Equal(__llgo_va_list ...interface{}) *py.Object + +// exp(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Calculate the exponential of all elements in the input array. +// +// Parameters +// ---------- +// x : array_like +// +// Input values. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Output array, element-wise exponential of `x`. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// expm1 : Calculate “exp(x) - 1“ for all elements in the array. +// exp2 : Calculate “2**x“ for all elements in the array. +// +// Notes +// ----- +// The irrational number “e“ is also known as Euler's number. It is +// approximately 2.718281, and is the base of the natural logarithm, +// “ln“ (this means that, if :math:`x = \ln y = \log_e y`, +// then :math:`e^x = y`. For real input, “exp(x)“ is always positive. +// +// For complex arguments, “x = a + ib“, we can write +// :math:`e^x = e^a e^{ib}`. The first term, :math:`e^a`, is already +// known (it is the real argument, described above). The second term, +// :math:`e^{ib}`, is :math:`\cos b + i \sin b`, a function with +// magnitude 1 and a periodic phase. +// +// References +// ---------- +// .. [1] Wikipedia, "Exponential function", +// +// https://en.wikipedia.org/wiki/Exponential_function +// +// .. [2] M. Abramovitz and I. A. Stegun, "Handbook of Mathematical Functions +// +// with Formulas, Graphs, and Mathematical Tables," Dover, 1964, p. 69, +// https://personal.math.ubc.ca/~cbm/aands/page_69.htm +// +// Examples +// -------- +// Plot the magnitude and phase of “exp(x)“ in the complex plane: +// +// >>> import matplotlib.pyplot as plt +// +// >>> x = np.linspace(-2*np.pi, 2*np.pi, 100) +// >>> xx = x + 1j * x[:, np.newaxis] # a + ib over complex plane +// >>> out = np.exp(xx) +// +// >>> plt.subplot(121) +// >>> plt.imshow(np.abs(out), +// ... extent=[-2*np.pi, 2*np.pi, -2*np.pi, 2*np.pi], cmap='gray') +// >>> plt.title('Magnitude of exp(x)') +// +// >>> plt.subplot(122) +// >>> plt.imshow(np.angle(out), +// ... extent=[-2*np.pi, 2*np.pi, -2*np.pi, 2*np.pi], cmap='hsv') +// >>> plt.title('Phase (angle) of exp(x)') +// >>> plt.show() +// +//go:linkname Exp py.exp +func Exp(__llgo_va_list ...interface{}) *py.Object + +// exp2(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Calculate `2**p` for all `p` in the input array. +// +// Parameters +// ---------- +// x : array_like +// +// Input values. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Element-wise 2 to the power `x`. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// power +// +// Notes +// ----- +// .. versionadded:: 1.3.0 +// +// Examples +// -------- +// >>> np.exp2([2, 3]) +// array([ 4., 8.]) +// +//go:linkname Exp2 py.exp2 +func Exp2(__llgo_va_list ...interface{}) *py.Object + +// expm1(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Calculate “exp(x) - 1“ for all elements in the array. +// +// Parameters +// ---------- +// x : array_like +// +// Input values. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Element-wise exponential minus one: ``out = exp(x) - 1``. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// log1p : “log(1 + x)“, the inverse of expm1. +// +// Notes +// ----- +// This function provides greater precision than “exp(x) - 1“ +// for small values of “x“. +// +// Examples +// -------- +// The true value of “exp(1e-10) - 1“ is “1.00000000005e-10“ to +// about 32 significant digits. This example shows the superiority of +// expm1 in this case. +// +// >>> np.expm1(1e-10) +// 1.00000000005e-10 +// >>> np.exp(1e-10) - 1 +// 1.000000082740371e-10 +// +//go:linkname Expm1 py.expm1 +func Expm1(__llgo_va_list ...interface{}) *py.Object + +// fabs(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Compute the absolute values element-wise. +// +// This function returns the absolute values (positive magnitude) of the +// data in `x`. Complex values are not handled, use `absolute` to find the +// absolute values of complex data. +// +// Parameters +// ---------- +// x : array_like +// +// The array of numbers for which the absolute values are required. If +// `x` is a scalar, the result `y` will also be a scalar. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or scalar +// +// The absolute values of `x`, the returned values are always floats. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// absolute : Absolute values including `complex` types. +// +// Examples +// -------- +// >>> np.fabs(-1) +// 1.0 +// >>> np.fabs([-1.2, 1.2]) +// array([ 1.2, 1.2]) +// +//go:linkname Fabs py.fabs +func Fabs(__llgo_va_list ...interface{}) *py.Object + +// floor(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the floor of the input, element-wise. +// +// The floor of the scalar `x` is the largest integer `i`, such that +// `i <= x`. It is often denoted as :math:`\lfloor x \rfloor`. +// +// Parameters +// ---------- +// x : array_like +// +// Input data. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or scalar +// +// The floor of each element in `x`. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// ceil, trunc, rint, fix +// +// Notes +// ----- +// Some spreadsheet programs calculate the "floor-towards-zero", where +// “floor(-2.5) == -2“. NumPy instead uses the definition of +// `floor` where `floor(-2.5) == -3`. The "floor-towards-zero" +// function is called “fix“ in NumPy. +// +// Examples +// -------- +// >>> a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]) +// >>> np.floor(a) +// array([-2., -2., -1., 0., 1., 1., 2.]) +// +//go:linkname Floor py.floor +func Floor(__llgo_va_list ...interface{}) *py.Object + +// floor_divide(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the largest integer smaller or equal to the division of the inputs. +// It is equivalent to the Python “//“ operator and pairs with the +// Python “%“ (`remainder`), function so that “a = a % b + b * (a // b)“ +// up to roundoff. +// +// Parameters +// ---------- +// x1 : array_like +// +// Numerator. +// +// x2 : array_like +// +// Denominator. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// y = floor(`x1`/`x2`) +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// remainder : Remainder complementary to floor_divide. +// divmod : Simultaneous floor division and remainder. +// divide : Standard division. +// floor : Round a number to the nearest integer toward minus infinity. +// ceil : Round a number to the nearest integer toward infinity. +// +// Examples +// -------- +// >>> np.floor_divide(7,3) +// 2 +// >>> np.floor_divide([1., 2., 3., 4.], 2.5) +// array([ 0., 0., 1., 1.]) +// +// The “//“ operator can be used as a shorthand for “np.floor_divide“ +// on ndarrays. +// +// >>> x1 = np.array([1., 2., 3., 4.]) +// >>> x1 // 2.5 +// array([0., 0., 1., 1.]) +// +//go:linkname FloorDivide py.floor_divide +func FloorDivide(__llgo_va_list ...interface{}) *py.Object + +// float_power(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// First array elements raised to powers from second array, element-wise. +// +// Raise each base in `x1` to the positionally-corresponding power in `x2`. +// `x1` and `x2` must be broadcastable to the same shape. This differs from +// the power function in that integers, float16, and float32 are promoted to +// floats with a minimum precision of float64 so that the result is always +// inexact. The intent is that the function will return a usable result for +// negative powers and seldom overflow for positive powers. +// +// Negative values raised to a non-integral value will return “nan“. +// To get complex results, cast the input to complex, or specify the +// “dtype“ to be “complex“ (see the example below). +// +// .. versionadded:: 1.12.0 +// +// Parameters +// ---------- +// x1 : array_like +// +// The bases. +// +// x2 : array_like +// +// The exponents. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The bases in `x1` raised to the exponents in `x2`. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// power : power function that preserves type +// +// Examples +// -------- +// Cube each element in a list. +// +// >>> x1 = range(6) +// >>> x1 +// [0, 1, 2, 3, 4, 5] +// >>> np.float_power(x1, 3) +// array([ 0., 1., 8., 27., 64., 125.]) +// +// Raise the bases to different exponents. +// +// >>> x2 = [1.0, 2.0, 3.0, 3.0, 2.0, 1.0] +// >>> np.float_power(x1, x2) +// array([ 0., 1., 8., 27., 16., 5.]) +// +// The effect of broadcasting. +// +// >>> x2 = np.array([[1, 2, 3, 3, 2, 1], [1, 2, 3, 3, 2, 1]]) +// >>> x2 +// array([[1, 2, 3, 3, 2, 1], +// +// [1, 2, 3, 3, 2, 1]]) +// +// >>> np.float_power(x1, x2) +// array([[ 0., 1., 8., 27., 16., 5.], +// +// [ 0., 1., 8., 27., 16., 5.]]) +// +// Negative values raised to a non-integral value will result in “nan“ +// (and a warning will be generated). +// +// >>> x3 = np.array([-1, -4]) +// >>> with np.errstate(invalid='ignore'): +// ... p = np.float_power(x3, 1.5) +// ... +// >>> p +// array([nan, nan]) +// +// To get complex results, give the argument “dtype=complex“. +// +// >>> np.float_power(x3, 1.5, dtype=complex) +// array([-1.83697020e-16-1.j, -1.46957616e-15-8.j]) +// +//go:linkname FloatPower py.float_power +func FloatPower(__llgo_va_list ...interface{}) *py.Object + +// fmax(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Element-wise maximum of array elements. +// +// Compare two arrays and return a new array containing the element-wise +// maxima. If one of the elements being compared is a NaN, then the +// non-nan element is returned. If both elements are NaNs then the first +// is returned. The latter distinction is important for complex NaNs, +// which are defined as at least one of the real or imaginary parts being +// a NaN. The net effect is that NaNs are ignored when possible. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// The arrays holding the elements to be compared. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or scalar +// +// The maximum of `x1` and `x2`, element-wise. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// fmin : +// +// Element-wise minimum of two arrays, ignores NaNs. +// +// maximum : +// +// Element-wise maximum of two arrays, propagates NaNs. +// +// amax : +// +// The maximum value of an array along a given axis, propagates NaNs. +// +// nanmax : +// +// The maximum value of an array along a given axis, ignores NaNs. +// +// minimum, amin, nanmin +// +// Notes +// ----- +// .. versionadded:: 1.3.0 +// +// The fmax is equivalent to “np.where(x1 >= x2, x1, x2)“ when neither +// x1 nor x2 are NaNs, but it is faster and does proper broadcasting. +// +// Examples +// -------- +// >>> np.fmax([2, 3, 4], [1, 5, 2]) +// array([ 2., 5., 4.]) +// +// >>> np.fmax(np.eye(2), [0.5, 2]) +// array([[ 1. , 2. ], +// +// [ 0.5, 2. ]]) +// +// >>> np.fmax([np.nan, 0, np.nan],[0, np.nan, np.nan]) +// array([ 0., 0., nan]) +// +//go:linkname Fmax py.fmax +func Fmax(__llgo_va_list ...interface{}) *py.Object + +// fmin(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Element-wise minimum of array elements. +// +// Compare two arrays and return a new array containing the element-wise +// minima. If one of the elements being compared is a NaN, then the +// non-nan element is returned. If both elements are NaNs then the first +// is returned. The latter distinction is important for complex NaNs, +// which are defined as at least one of the real or imaginary parts being +// a NaN. The net effect is that NaNs are ignored when possible. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// The arrays holding the elements to be compared. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or scalar +// +// The minimum of `x1` and `x2`, element-wise. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// fmax : +// +// Element-wise maximum of two arrays, ignores NaNs. +// +// minimum : +// +// Element-wise minimum of two arrays, propagates NaNs. +// +// amin : +// +// The minimum value of an array along a given axis, propagates NaNs. +// +// nanmin : +// +// The minimum value of an array along a given axis, ignores NaNs. +// +// maximum, amax, nanmax +// +// Notes +// ----- +// .. versionadded:: 1.3.0 +// +// The fmin is equivalent to “np.where(x1 <= x2, x1, x2)“ when neither +// x1 nor x2 are NaNs, but it is faster and does proper broadcasting. +// +// Examples +// -------- +// >>> np.fmin([2, 3, 4], [1, 5, 2]) +// array([1, 3, 2]) +// +// >>> np.fmin(np.eye(2), [0.5, 2]) +// array([[ 0.5, 0. ], +// +// [ 0. , 1. ]]) +// +// >>> np.fmin([np.nan, 0, np.nan],[0, np.nan, np.nan]) +// array([ 0., 0., nan]) +// +//go:linkname Fmin py.fmin +func Fmin(__llgo_va_list ...interface{}) *py.Object + +// fmod(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Returns the element-wise remainder of division. +// +// This is the NumPy implementation of the C library function fmod, the +// remainder has the same sign as the dividend `x1`. It is equivalent to +// the Matlab(TM) “rem“ function and should not be confused with the +// Python modulus operator “x1 % x2“. +// +// Parameters +// ---------- +// x1 : array_like +// +// Dividend. +// +// x2 : array_like +// +// Divisor. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : array_like +// +// The remainder of the division of `x1` by `x2`. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// remainder : Equivalent to the Python “%“ operator. +// divide +// +// Notes +// ----- +// The result of the modulo operation for negative dividend and divisors +// is bound by conventions. For `fmod`, the sign of result is the sign of +// the dividend, while for `remainder` the sign of the result is the sign +// of the divisor. The `fmod` function is equivalent to the Matlab(TM) +// “rem“ function. +// +// Examples +// -------- +// >>> np.fmod([-3, -2, -1, 1, 2, 3], 2) +// array([-1, 0, -1, 1, 0, 1]) +// >>> np.remainder([-3, -2, -1, 1, 2, 3], 2) +// array([1, 0, 1, 1, 0, 1]) +// +// >>> np.fmod([5, 3], [2, 2.]) +// array([ 1., 1.]) +// >>> a = np.arange(-3, 3).reshape(3, 2) +// >>> a +// array([[-3, -2], +// +// [-1, 0], +// [ 1, 2]]) +// +// >>> np.fmod(a, [2,2]) +// array([[-1, 0], +// +// [-1, 0], +// [ 1, 0]]) +// +//go:linkname Fmod py.fmod +func Fmod(__llgo_va_list ...interface{}) *py.Object + +// frexp(x[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Decompose the elements of x into mantissa and twos exponent. +// +// Returns (`mantissa`, `exponent`), where “x = mantissa * 2**exponent“. +// The mantissa lies in the open interval(-1, 1), while the twos +// exponent is a signed integer. +// +// Parameters +// ---------- +// x : array_like +// +// Array of numbers to be decomposed. +// +// out1 : ndarray, optional +// +// Output array for the mantissa. Must have the same shape as `x`. +// +// out2 : ndarray, optional +// +// Output array for the exponent. Must have the same shape as `x`. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// mantissa : ndarray +// +// Floating values between -1 and 1. +// This is a scalar if `x` is a scalar. +// +// exponent : ndarray +// +// Integer exponents of 2. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// ldexp : Compute “y = x1 * 2**x2“, the inverse of `frexp`. +// +// Notes +// ----- +// Complex dtypes are not supported, they will raise a TypeError. +// +// Examples +// -------- +// >>> x = np.arange(9) +// >>> y1, y2 = np.frexp(x) +// >>> y1 +// array([ 0. , 0.5 , 0.5 , 0.75 , 0.5 , 0.625, 0.75 , 0.875, +// +// 0.5 ]) +// +// >>> y2 +// array([0, 1, 2, 2, 3, 3, 3, 3, 4]) +// >>> y1 * 2**y2 +// array([ 0., 1., 2., 3., 4., 5., 6., 7., 8.]) +// +//go:linkname Frexp py.frexp +func Frexp(__llgo_va_list ...interface{}) *py.Object + +// gcd(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Returns the greatest common divisor of “|x1|“ and “|x2|“ +// +// Parameters +// ---------- +// x1, x2 : array_like, int +// +// Arrays of values. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// Returns +// ------- +// y : ndarray or scalar +// +// The greatest common divisor of the absolute value of the inputs +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// lcm : The lowest common multiple +// +// Examples +// -------- +// >>> np.gcd(12, 20) +// 4 +// >>> np.gcd.reduce([15, 25, 35]) +// 5 +// >>> np.gcd(np.arange(6), 20) +// array([20, 1, 2, 1, 4, 5]) +// +//go:linkname Gcd py.gcd +func Gcd(__llgo_va_list ...interface{}) *py.Object + +// greater_equal(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the truth value of (x1 >= x2) element-wise. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Input arrays. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : bool or ndarray of bool +// +// Output array, element-wise comparison of `x1` and `x2`. +// Typically of type bool, unless ``dtype=object`` is passed. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// greater, less, less_equal, equal, not_equal +// +// Examples +// -------- +// >>> np.greater_equal([4, 2, 1], [2, 2, 2]) +// array([ True, True, False]) +// +// The “>=“ operator can be used as a shorthand for “np.greater_equal“ +// on ndarrays. +// +// >>> a = np.array([4, 2, 1]) +// >>> b = np.array([2, 2, 2]) +// >>> a >= b +// array([ True, True, False]) +// +//go:linkname GreaterEqual py.greater_equal +func GreaterEqual(__llgo_va_list ...interface{}) *py.Object + +// heaviside(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Compute the Heaviside step function. +// +// The Heaviside step function is defined as:: +// +// 0 if x1 < 0 +// heaviside(x1, x2) = x2 if x1 == 0 +// 1 if x1 > 0 +// +// where `x2` is often taken to be 0.5, but 0 and 1 are also sometimes used. +// +// Parameters +// ---------- +// x1 : array_like +// +// Input values. +// +// x2 : array_like +// +// The value of the function when x1 is 0. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// The output array, element-wise Heaviside step function of `x1`. +// This is a scalar if both `x1` and `x2` are scalars. +// +// Notes +// ----- +// .. versionadded:: 1.13.0 +// +// References +// ---------- +// .. Wikipedia, "Heaviside step function", +// +// https://en.wikipedia.org/wiki/Heaviside_step_function +// +// Examples +// -------- +// >>> np.heaviside([-1.5, 0, 2.0], 0.5) +// array([ 0. , 0.5, 1. ]) +// >>> np.heaviside([-1.5, 0, 2.0], 1) +// array([ 0., 1., 1.]) +// +//go:linkname Heaviside py.heaviside +func Heaviside(__llgo_va_list ...interface{}) *py.Object + +// hypot(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Given the "legs" of a right triangle, return its hypotenuse. +// +// Equivalent to “sqrt(x1**2 + x2**2)“, element-wise. If `x1` or +// `x2` is scalar_like (i.e., unambiguously cast-able to a scalar type), +// it is broadcast for use with each element of the other argument. +// (See Examples) +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Leg of the triangle(s). +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// z : ndarray +// +// The hypotenuse of the triangle(s). +// This is a scalar if both `x1` and `x2` are scalars. +// +// Examples +// -------- +// >>> np.hypot(3*np.ones((3, 3)), 4*np.ones((3, 3))) +// array([[ 5., 5., 5.], +// +// [ 5., 5., 5.], +// [ 5., 5., 5.]]) +// +// Example showing broadcast of scalar_like argument: +// +// >>> np.hypot(3*np.ones((3, 3)), [4]) +// array([[ 5., 5., 5.], +// +// [ 5., 5., 5.], +// [ 5., 5., 5.]]) +// +//go:linkname Hypot py.hypot +func Hypot(__llgo_va_list ...interface{}) *py.Object + +// invert(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Compute bit-wise inversion, or bit-wise NOT, element-wise. +// +// Computes the bit-wise NOT of the underlying binary representation of +// the integers in the input arrays. This ufunc implements the C/Python +// operator “~“. +// +// For signed integer inputs, the two's complement is returned. In a +// two's-complement system negative numbers are represented by the two's +// complement of the absolute value. This is the most common method of +// representing signed integers on computers [1]_. A N-bit +// two's-complement system can represent every integer in the range +// :math:`-2^{N-1}` to :math:`+2^{N-1}-1`. +// +// Parameters +// ---------- +// x : array_like +// +// Only integer and boolean types are handled. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Result. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// bitwise_and, bitwise_or, bitwise_xor +// logical_not +// binary_repr : +// +// Return the binary representation of the input number as a string. +// +// Notes +// ----- +// `bitwise_not` is an alias for `invert`: +// +// >>> np.bitwise_not is np.invert +// True +// +// References +// ---------- +// .. [1] Wikipedia, "Two's complement", +// +// https://en.wikipedia.org/wiki/Two's_complement +// +// Examples +// -------- +// We've seen that 13 is represented by “00001101“. +// The invert or bit-wise NOT of 13 is then: +// +// >>> x = np.invert(np.array(13, dtype=np.uint8)) +// >>> x +// 242 +// >>> np.binary_repr(x, width=8) +// '11110010' +// +// The result depends on the bit-width: +// +// >>> x = np.invert(np.array(13, dtype=np.uint16)) +// >>> x +// 65522 +// >>> np.binary_repr(x, width=16) +// '1111111111110010' +// +// When using signed integer types the result is the two's complement of +// the result for the unsigned type: +// +// >>> np.invert(np.array([13], dtype=np.int8)) +// array([-14], dtype=int8) +// >>> np.binary_repr(-14, width=8) +// '11110010' +// +// Booleans are accepted as well: +// +// >>> np.invert(np.array([True, False])) +// array([False, True]) +// +// The “~“ operator can be used as a shorthand for “np.invert“ on +// ndarrays. +// +// >>> x1 = np.array([True, False]) +// >>> ~x1 +// array([False, True]) +// +//go:linkname Invert py.invert +func Invert(__llgo_va_list ...interface{}) *py.Object + +// isfinite(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Test element-wise for finiteness (not infinity and not Not a Number). +// +// The result is returned as a boolean array. +// +// Parameters +// ---------- +// x : array_like +// +// Input values. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray, bool +// +// True where ``x`` is not positive infinity, negative infinity, +// or NaN; false otherwise. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// isinf, isneginf, isposinf, isnan +// +// Notes +// ----- +// Not a Number, positive infinity and negative infinity are considered +// to be non-finite. +// +// NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic +// (IEEE 754). This means that Not a Number is not equivalent to infinity. +// Also that positive infinity is not equivalent to negative infinity. But +// infinity is equivalent to positive infinity. Errors result if the +// second argument is also supplied when `x` is a scalar input, or if +// first and second arguments have different shapes. +// +// Examples +// -------- +// >>> np.isfinite(1) +// True +// >>> np.isfinite(0) +// True +// >>> np.isfinite(np.nan) +// False +// >>> np.isfinite(np.inf) +// False +// >>> np.isfinite(np.NINF) +// False +// >>> np.isfinite([np.log(-1.),1.,np.log(0)]) +// array([False, True, False]) +// +// >>> x = np.array([-np.inf, 0., np.inf]) +// >>> y = np.array([2, 2, 2]) +// >>> np.isfinite(x, y) +// array([0, 1, 0]) +// >>> y +// array([0, 1, 0]) +// +//go:linkname Isfinite py.isfinite +func Isfinite(__llgo_va_list ...interface{}) *py.Object + +// isinf(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Test element-wise for positive or negative infinity. +// +// Returns a boolean array of the same shape as `x`, True where “x == +// +/-inf“, otherwise False. +// +// Parameters +// ---------- +// x : array_like +// +// Input values +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : bool (scalar) or boolean ndarray +// +// True where ``x`` is positive or negative infinity, false otherwise. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// isneginf, isposinf, isnan, isfinite +// +// Notes +// ----- +// NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic +// (IEEE 754). +// +// Errors result if the second argument is supplied when the first +// argument is a scalar, or if the first and second arguments have +// different shapes. +// +// Examples +// -------- +// >>> np.isinf(np.inf) +// True +// >>> np.isinf(np.nan) +// False +// >>> np.isinf(np.NINF) +// True +// >>> np.isinf([np.inf, -np.inf, 1.0, np.nan]) +// array([ True, True, False, False]) +// +// >>> x = np.array([-np.inf, 0., np.inf]) +// >>> y = np.array([2, 2, 2]) +// >>> np.isinf(x, y) +// array([1, 0, 1]) +// >>> y +// array([1, 0, 1]) +// +//go:linkname Isinf py.isinf +func Isinf(__llgo_va_list ...interface{}) *py.Object + +// isnan(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Test element-wise for NaN and return result as a boolean array. +// +// Parameters +// ---------- +// x : array_like +// +// Input array. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or bool +// +// True where ``x`` is NaN, false otherwise. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// isinf, isneginf, isposinf, isfinite, isnat +// +// Notes +// ----- +// NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic +// (IEEE 754). This means that Not a Number is not equivalent to infinity. +// +// Examples +// -------- +// >>> np.isnan(np.nan) +// True +// >>> np.isnan(np.inf) +// False +// >>> np.isnan([np.log(-1.),1.,np.log(0)]) +// array([ True, False, False]) +// +//go:linkname Isnan py.isnan +func Isnan(__llgo_va_list ...interface{}) *py.Object + +// isnat(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Test element-wise for NaT (not a time) and return result as a boolean array. +// +// .. versionadded:: 1.13.0 +// +// Parameters +// ---------- +// x : array_like +// +// Input array with datetime or timedelta data type. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or bool +// +// True where ``x`` is NaT, false otherwise. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// isnan, isinf, isneginf, isposinf, isfinite +// +// Examples +// -------- +// >>> np.isnat(np.datetime64("NaT")) +// True +// >>> np.isnat(np.datetime64("2016-01-01")) +// False +// >>> np.isnat(np.array(["NaT", "2016-01-01"], dtype="datetime64[ns]")) +// array([ True, False]) +// +//go:linkname Isnat py.isnat +func Isnat(__llgo_va_list ...interface{}) *py.Object + +// lcm(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Returns the lowest common multiple of “|x1|“ and “|x2|“ +// +// Parameters +// ---------- +// x1, x2 : array_like, int +// +// Arrays of values. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// Returns +// ------- +// y : ndarray or scalar +// +// The lowest common multiple of the absolute value of the inputs +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// gcd : The greatest common divisor +// +// Examples +// -------- +// >>> np.lcm(12, 20) +// 60 +// >>> np.lcm.reduce([3, 12, 20]) +// 60 +// >>> np.lcm.reduce([40, 12, 20]) +// 120 +// >>> np.lcm(np.arange(6), 20) +// array([ 0, 20, 20, 60, 20, 20]) +// +//go:linkname Lcm py.lcm +func Lcm(__llgo_va_list ...interface{}) *py.Object + +// ldexp(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Returns x1 * 2**x2, element-wise. +// +// The mantissas `x1` and twos exponents `x2` are used to construct +// floating point numbers “x1 * 2**x2“. +// +// Parameters +// ---------- +// x1 : array_like +// +// Array of multipliers. +// +// x2 : array_like, int +// +// Array of twos exponents. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or scalar +// +// The result of ``x1 * 2**x2``. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// frexp : Return (y1, y2) from “x = y1 * 2**y2“, inverse to `ldexp`. +// +// Notes +// ----- +// Complex dtypes are not supported, they will raise a TypeError. +// +// `ldexp` is useful as the inverse of `frexp`, if used by itself it is +// more clear to simply use the expression “x1 * 2**x2“. +// +// Examples +// -------- +// >>> np.ldexp(5, np.arange(4)) +// array([ 5., 10., 20., 40.], dtype=float16) +// +// >>> x = np.arange(6) +// >>> np.ldexp(*np.frexp(x)) +// array([ 0., 1., 2., 3., 4., 5.]) +// +//go:linkname Ldexp py.ldexp +func Ldexp(__llgo_va_list ...interface{}) *py.Object + +// left_shift(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Shift the bits of an integer to the left. +// +// Bits are shifted to the left by appending `x2` 0s at the right of `x1`. +// Since the internal representation of numbers is in binary format, this +// operation is equivalent to multiplying `x1` by “2**x2“. +// +// Parameters +// ---------- +// x1 : array_like of integer type +// +// Input values. +// +// x2 : array_like of integer type +// +// Number of zeros to append to `x1`. Has to be non-negative. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : array of integer type +// +// Return `x1` with bits shifted `x2` times to the left. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// right_shift : Shift the bits of an integer to the right. +// binary_repr : Return the binary representation of the input number +// +// as a string. +// +// Examples +// -------- +// >>> np.binary_repr(5) +// '101' +// >>> np.left_shift(5, 2) +// 20 +// >>> np.binary_repr(20) +// '10100' +// +// >>> np.left_shift(5, [1,2,3]) +// array([10, 20, 40]) +// +// Note that the dtype of the second argument may change the dtype of the +// result and can lead to unexpected results in some cases (see +// :ref:`Casting Rules `): +// +// >>> a = np.left_shift(np.uint8(255), 1) # Expect 254 +// >>> print(a, type(a)) # Unexpected result due to upcasting +// 510 +// >>> b = np.left_shift(np.uint8(255), np.uint8(1)) +// >>> print(b, type(b)) +// 254 +// +// The “<<“ operator can be used as a shorthand for “np.left_shift“ on +// ndarrays. +// +// >>> x1 = 5 +// >>> x2 = np.array([1, 2, 3]) +// >>> x1 << x2 +// array([10, 20, 40]) +// +//go:linkname LeftShift py.left_shift +func LeftShift(__llgo_va_list ...interface{}) *py.Object + +// less(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the truth value of (x1 < x2) element-wise. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Input arrays. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Output array, element-wise comparison of `x1` and `x2`. +// Typically of type bool, unless ``dtype=object`` is passed. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// greater, less_equal, greater_equal, equal, not_equal +// +// Examples +// -------- +// >>> np.less([1, 2], [2, 2]) +// array([ True, False]) +// +// The “<“ operator can be used as a shorthand for “np.less“ on ndarrays. +// +// >>> a = np.array([1, 2]) +// >>> b = np.array([2, 2]) +// >>> a < b +// array([ True, False]) +// +//go:linkname Less py.less +func Less(__llgo_va_list ...interface{}) *py.Object + +// less_equal(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the truth value of (x1 <= x2) element-wise. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Input arrays. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Output array, element-wise comparison of `x1` and `x2`. +// Typically of type bool, unless ``dtype=object`` is passed. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// greater, less, greater_equal, equal, not_equal +// +// Examples +// -------- +// >>> np.less_equal([4, 2, 1], [2, 2, 2]) +// array([False, True, True]) +// +// The “<=“ operator can be used as a shorthand for “np.less_equal“ on +// ndarrays. +// +// >>> a = np.array([4, 2, 1]) +// >>> b = np.array([2, 2, 2]) +// >>> a <= b +// array([False, True, True]) +// +//go:linkname LessEqual py.less_equal +func LessEqual(__llgo_va_list ...interface{}) *py.Object + +// log(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Natural logarithm, element-wise. +// +// The natural logarithm `log` is the inverse of the exponential function, +// so that `log(exp(x)) = x`. The natural logarithm is logarithm in base +// `e`. +// +// Parameters +// ---------- +// x : array_like +// +// Input value. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The natural logarithm of `x`, element-wise. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// log10, log2, log1p, emath.log +// +// Notes +// ----- +// Logarithm is a multivalued function: for each `x` there is an infinite +// number of `z` such that `exp(z) = x`. The convention is to return the +// `z` whose imaginary part lies in `(-pi, pi]`. +// +// For real-valued input data types, `log` always returns real output. For +// each value that cannot be expressed as a real number or infinity, it +// yields “nan“ and sets the `invalid` floating point error flag. +// +// For complex-valued input, `log` is a complex analytical function that +// has a branch cut `[-inf, 0]` and is continuous from above on it. `log` +// handles the floating-point negative zero as an infinitesimal negative +// number, conforming to the C99 standard. +// +// In the cases where the input has a negative real part and a very small +// negative complex part (approaching 0), the result is so close to `-pi` +// that it evaluates to exactly `-pi`. +// +// References +// ---------- +// .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions", +// +// 10th printing, 1964, pp. 67. +// https://personal.math.ubc.ca/~cbm/aands/page_67.htm +// +// .. [2] Wikipedia, "Logarithm". https://en.wikipedia.org/wiki/Logarithm +// +// Examples +// -------- +// >>> np.log([1, np.e, np.e**2, 0]) +// array([ 0., 1., 2., -Inf]) +// +//go:linkname Log py.log +func Log(__llgo_va_list ...interface{}) *py.Object + +// log10(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the base 10 logarithm of the input array, element-wise. +// +// Parameters +// ---------- +// x : array_like +// +// Input values. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The logarithm to the base 10 of `x`, element-wise. NaNs are +// returned where x is negative. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// emath.log10 +// +// Notes +// ----- +// Logarithm is a multivalued function: for each `x` there is an infinite +// number of `z` such that `10**z = x`. The convention is to return the +// `z` whose imaginary part lies in `(-pi, pi]`. +// +// For real-valued input data types, `log10` always returns real output. +// For each value that cannot be expressed as a real number or infinity, +// it yields “nan“ and sets the `invalid` floating point error flag. +// +// For complex-valued input, `log10` is a complex analytical function that +// has a branch cut `[-inf, 0]` and is continuous from above on it. +// `log10` handles the floating-point negative zero as an infinitesimal +// negative number, conforming to the C99 standard. +// +// In the cases where the input has a negative real part and a very small +// negative complex part (approaching 0), the result is so close to `-pi` +// that it evaluates to exactly `-pi`. +// +// References +// ---------- +// .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions", +// +// 10th printing, 1964, pp. 67. +// https://personal.math.ubc.ca/~cbm/aands/page_67.htm +// +// .. [2] Wikipedia, "Logarithm". https://en.wikipedia.org/wiki/Logarithm +// +// Examples +// -------- +// >>> np.log10([1e-15, -3.]) +// array([-15., nan]) +// +//go:linkname Log10 py.log10 +func Log10(__llgo_va_list ...interface{}) *py.Object + +// log1p(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the natural logarithm of one plus the input array, element-wise. +// +// Calculates “log(1 + x)“. +// +// Parameters +// ---------- +// x : array_like +// +// Input values. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// Natural logarithm of `1 + x`, element-wise. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// expm1 : “exp(x) - 1“, the inverse of `log1p`. +// +// Notes +// ----- +// For real-valued input, `log1p` is accurate also for `x` so small +// that `1 + x == 1` in floating-point accuracy. +// +// Logarithm is a multivalued function: for each `x` there is an infinite +// number of `z` such that `exp(z) = 1 + x`. The convention is to return +// the `z` whose imaginary part lies in `[-pi, pi]`. +// +// For real-valued input data types, `log1p` always returns real output. +// For each value that cannot be expressed as a real number or infinity, +// it yields “nan“ and sets the `invalid` floating point error flag. +// +// For complex-valued input, `log1p` is a complex analytical function that +// has a branch cut `[-inf, -1]` and is continuous from above on it. +// `log1p` handles the floating-point negative zero as an infinitesimal +// negative number, conforming to the C99 standard. +// +// References +// ---------- +// .. [1] M. Abramowitz and I.A. Stegun, "Handbook of Mathematical Functions", +// +// 10th printing, 1964, pp. 67. +// https://personal.math.ubc.ca/~cbm/aands/page_67.htm +// +// .. [2] Wikipedia, "Logarithm". https://en.wikipedia.org/wiki/Logarithm +// +// Examples +// -------- +// >>> np.log1p(1e-99) +// 1e-99 +// >>> np.log(1 + 1e-99) +// 0.0 +// +//go:linkname Log1p py.log1p +func Log1p(__llgo_va_list ...interface{}) *py.Object + +// log2(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Base-2 logarithm of `x`. +// +// Parameters +// ---------- +// x : array_like +// +// Input values. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// Base-2 logarithm of `x`. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// log, log10, log1p, emath.log2 +// +// Notes +// ----- +// .. versionadded:: 1.3.0 +// +// Logarithm is a multivalued function: for each `x` there is an infinite +// number of `z` such that `2**z = x`. The convention is to return the `z` +// whose imaginary part lies in `(-pi, pi]`. +// +// For real-valued input data types, `log2` always returns real output. +// For each value that cannot be expressed as a real number or infinity, +// it yields “nan“ and sets the `invalid` floating point error flag. +// +// For complex-valued input, `log2` is a complex analytical function that +// has a branch cut `[-inf, 0]` and is continuous from above on it. `log2` +// handles the floating-point negative zero as an infinitesimal negative +// number, conforming to the C99 standard. +// +// In the cases where the input has a negative real part and a very small +// negative complex part (approaching 0), the result is so close to `-pi` +// that it evaluates to exactly `-pi`. +// +// Examples +// -------- +// >>> x = np.array([0, 1, 2, 2**4]) +// >>> np.log2(x) +// array([-Inf, 0., 1., 4.]) +// +// >>> xi = np.array([0+1.j, 1, 2+0.j, 4.j]) +// >>> np.log2(xi) +// array([ 0.+2.26618007j, 0.+0.j , 1.+0.j , 2.+2.26618007j]) +// +//go:linkname Log2 py.log2 +func Log2(__llgo_va_list ...interface{}) *py.Object + +// logaddexp(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Logarithm of the sum of exponentiations of the inputs. +// +// Calculates “log(exp(x1) + exp(x2))“. This function is useful in +// statistics where the calculated probabilities of events may be so small +// as to exceed the range of normal floating point numbers. In such cases +// the logarithm of the calculated probability is stored. This function +// allows adding probabilities stored in such a fashion. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Input values. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// result : ndarray +// +// Logarithm of ``exp(x1) + exp(x2)``. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// logaddexp2: Logarithm of the sum of exponentiations of inputs in base 2. +// +// Notes +// ----- +// .. versionadded:: 1.3.0 +// +// Examples +// -------- +// >>> prob1 = np.log(1e-50) +// >>> prob2 = np.log(2.5e-50) +// >>> prob12 = np.logaddexp(prob1, prob2) +// >>> prob12 +// -113.87649168120691 +// >>> np.exp(prob12) +// 3.5000000000000057e-50 +// +//go:linkname Logaddexp py.logaddexp +func Logaddexp(__llgo_va_list ...interface{}) *py.Object + +// logaddexp2(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Logarithm of the sum of exponentiations of the inputs in base-2. +// +// Calculates “log2(2**x1 + 2**x2)“. This function is useful in machine +// learning when the calculated probabilities of events may be so small as +// to exceed the range of normal floating point numbers. In such cases +// the base-2 logarithm of the calculated probability can be used instead. +// This function allows adding probabilities stored in such a fashion. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Input values. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// result : ndarray +// +// Base-2 logarithm of ``2**x1 + 2**x2``. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// logaddexp: Logarithm of the sum of exponentiations of the inputs. +// +// Notes +// ----- +// .. versionadded:: 1.3.0 +// +// Examples +// -------- +// >>> prob1 = np.log2(1e-50) +// >>> prob2 = np.log2(2.5e-50) +// >>> prob12 = np.logaddexp2(prob1, prob2) +// >>> prob1, prob2, prob12 +// (-166.09640474436813, -164.77447664948076, -164.28904982231052) +// >>> 2**prob12 +// 3.4999999999999914e-50 +// +//go:linkname Logaddexp2 py.logaddexp2 +func Logaddexp2(__llgo_va_list ...interface{}) *py.Object + +// logical_and(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Compute the truth value of x1 AND x2 element-wise. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Input arrays. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or bool +// +// Boolean result of the logical AND operation applied to the elements +// of `x1` and `x2`; the shape is determined by broadcasting. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// logical_or, logical_not, logical_xor +// bitwise_and +// +// Examples +// -------- +// >>> np.logical_and(True, False) +// False +// >>> np.logical_and([True, False], [False, False]) +// array([False, False]) +// +// >>> x = np.arange(5) +// >>> np.logical_and(x>1, x<4) +// array([False, False, True, True, False]) +// +// The “&“ operator can be used as a shorthand for “np.logical_and“ on +// boolean ndarrays. +// +// >>> a = np.array([True, False]) +// >>> b = np.array([False, False]) +// >>> a & b +// array([False, False]) +// +//go:linkname LogicalAnd py.logical_and +func LogicalAnd(__llgo_va_list ...interface{}) *py.Object + +// logical_not(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Compute the truth value of NOT x element-wise. +// +// Parameters +// ---------- +// x : array_like +// +// Logical NOT is applied to the elements of `x`. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : bool or ndarray of bool +// +// Boolean result with the same shape as `x` of the NOT operation +// on elements of `x`. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// logical_and, logical_or, logical_xor +// +// Examples +// -------- +// >>> np.logical_not(3) +// False +// >>> np.logical_not([True, False, 0, 1]) +// array([False, True, True, False]) +// +// >>> x = np.arange(5) +// >>> np.logical_not(x<3) +// array([False, False, False, True, True]) +// +//go:linkname LogicalNot py.logical_not +func LogicalNot(__llgo_va_list ...interface{}) *py.Object + +// logical_or(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Compute the truth value of x1 OR x2 element-wise. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Logical OR is applied to the elements of `x1` and `x2`. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or bool +// +// Boolean result of the logical OR operation applied to the elements +// of `x1` and `x2`; the shape is determined by broadcasting. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// logical_and, logical_not, logical_xor +// bitwise_or +// +// Examples +// -------- +// >>> np.logical_or(True, False) +// True +// >>> np.logical_or([True, False], [False, False]) +// array([ True, False]) +// +// >>> x = np.arange(5) +// >>> np.logical_or(x < 1, x > 3) +// array([ True, False, False, False, True]) +// +// The “|“ operator can be used as a shorthand for “np.logical_or“ on +// boolean ndarrays. +// +// >>> a = np.array([True, False]) +// >>> b = np.array([False, False]) +// >>> a | b +// array([ True, False]) +// +//go:linkname LogicalOr py.logical_or +func LogicalOr(__llgo_va_list ...interface{}) *py.Object + +// logical_xor(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Compute the truth value of x1 XOR x2, element-wise. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Logical XOR is applied to the elements of `x1` and `x2`. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : bool or ndarray of bool +// +// Boolean result of the logical XOR operation applied to the elements +// of `x1` and `x2`; the shape is determined by broadcasting. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// logical_and, logical_or, logical_not, bitwise_xor +// +// Examples +// -------- +// >>> np.logical_xor(True, False) +// True +// >>> np.logical_xor([True, True, False, False], [True, False, True, False]) +// array([False, True, True, False]) +// +// >>> x = np.arange(5) +// >>> np.logical_xor(x < 1, x > 3) +// array([ True, False, False, False, True]) +// +// # Simple example showing support of broadcasting +// +// >>> np.logical_xor(0, np.eye(2)) +// array([[ True, False], +// +// [False, True]]) +// +//go:linkname LogicalXor py.logical_xor +func LogicalXor(__llgo_va_list ...interface{}) *py.Object + +// maximum(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Element-wise maximum of array elements. +// +// Compare two arrays and return a new array containing the element-wise +// maxima. If one of the elements being compared is a NaN, then that +// element is returned. If both elements are NaNs then the first is +// returned. The latter distinction is important for complex NaNs, which +// are defined as at least one of the real or imaginary parts being a NaN. +// The net effect is that NaNs are propagated. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// The arrays holding the elements to be compared. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or scalar +// +// The maximum of `x1` and `x2`, element-wise. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// minimum : +// +// Element-wise minimum of two arrays, propagates NaNs. +// +// fmax : +// +// Element-wise maximum of two arrays, ignores NaNs. +// +// amax : +// +// The maximum value of an array along a given axis, propagates NaNs. +// +// nanmax : +// +// The maximum value of an array along a given axis, ignores NaNs. +// +// fmin, amin, nanmin +// +// Notes +// ----- +// The maximum is equivalent to “np.where(x1 >= x2, x1, x2)“ when +// neither x1 nor x2 are nans, but it is faster and does proper +// broadcasting. +// +// Examples +// -------- +// >>> np.maximum([2, 3, 4], [1, 5, 2]) +// array([2, 5, 4]) +// +// >>> np.maximum(np.eye(2), [0.5, 2]) # broadcasting +// array([[ 1. , 2. ], +// +// [ 0.5, 2. ]]) +// +// >>> np.maximum([np.nan, 0, np.nan], [0, np.nan, np.nan]) +// array([nan, nan, nan]) +// >>> np.maximum(np.Inf, 1) +// inf +// +//go:linkname Maximum py.maximum +func Maximum(__llgo_va_list ...interface{}) *py.Object + +// minimum(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Element-wise minimum of array elements. +// +// Compare two arrays and return a new array containing the element-wise +// minima. If one of the elements being compared is a NaN, then that +// element is returned. If both elements are NaNs then the first is +// returned. The latter distinction is important for complex NaNs, which +// are defined as at least one of the real or imaginary parts being a NaN. +// The net effect is that NaNs are propagated. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// The arrays holding the elements to be compared. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or scalar +// +// The minimum of `x1` and `x2`, element-wise. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// maximum : +// +// Element-wise maximum of two arrays, propagates NaNs. +// +// fmin : +// +// Element-wise minimum of two arrays, ignores NaNs. +// +// amin : +// +// The minimum value of an array along a given axis, propagates NaNs. +// +// nanmin : +// +// The minimum value of an array along a given axis, ignores NaNs. +// +// fmax, amax, nanmax +// +// Notes +// ----- +// The minimum is equivalent to “np.where(x1 <= x2, x1, x2)“ when +// neither x1 nor x2 are NaNs, but it is faster and does proper +// broadcasting. +// +// Examples +// -------- +// >>> np.minimum([2, 3, 4], [1, 5, 2]) +// array([1, 3, 2]) +// +// >>> np.minimum(np.eye(2), [0.5, 2]) # broadcasting +// array([[ 0.5, 0. ], +// +// [ 0. , 1. ]]) +// +// >>> np.minimum([np.nan, 0, np.nan],[0, np.nan, np.nan]) +// array([nan, nan, nan]) +// >>> np.minimum(-np.Inf, 1) +// -inf +// +//go:linkname Minimum py.minimum +func Minimum(__llgo_va_list ...interface{}) *py.Object + +// remainder(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Returns the element-wise remainder of division. +// +// Computes the remainder complementary to the `floor_divide` function. It is +// equivalent to the Python modulus operator“x1 % x2“ and has the same sign +// as the divisor `x2`. The MATLAB function equivalent to “np.remainder“ +// is “mod“. +// +// .. warning:: +// +// This should not be confused with: +// +// * Python 3.7's `math.remainder` and C's ``remainder``, which +// computes the IEEE remainder, which are the complement to +// ``round(x1 / x2)``. +// * The MATLAB ``rem`` function and or the C ``%`` operator which is the +// complement to ``int(x1 / x2)``. +// +// Parameters +// ---------- +// x1 : array_like +// +// Dividend array. +// +// x2 : array_like +// +// Divisor array. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The element-wise remainder of the quotient ``floor_divide(x1, x2)``. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// floor_divide : Equivalent of Python “//“ operator. +// divmod : Simultaneous floor division and remainder. +// fmod : Equivalent of the MATLAB “rem“ function. +// divide, floor +// +// Notes +// ----- +// Returns 0 when `x2` is 0 and both `x1` and `x2` are (arrays of) +// integers. +// “mod“ is an alias of “remainder“. +// +// Examples +// -------- +// >>> np.remainder([4, 7], [2, 3]) +// array([0, 1]) +// >>> np.remainder(np.arange(7), 5) +// array([0, 1, 2, 3, 4, 0, 1]) +// +// The “%“ operator can be used as a shorthand for “np.remainder“ on +// ndarrays. +// +// >>> x1 = np.arange(7) +// >>> x1 % 5 +// array([0, 1, 2, 3, 4, 0, 1]) +// +//go:linkname Mod py.mod +func Mod(__llgo_va_list ...interface{}) *py.Object + +// modf(x[, out1, out2], / [, out=(None, None)], *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the fractional and integral parts of an array, element-wise. +// +// The fractional and integral parts are negative if the given number is +// negative. +// +// Parameters +// ---------- +// x : array_like +// +// Input array. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y1 : ndarray +// +// Fractional part of `x`. +// This is a scalar if `x` is a scalar. +// +// y2 : ndarray +// +// Integral part of `x`. +// This is a scalar if `x` is a scalar. +// +// Notes +// ----- +// For integer input the return values are floats. +// +// See Also +// -------- +// divmod : “divmod(x, 1)“ is equivalent to “modf“ with the return values +// +// switched, except it always has a positive remainder. +// +// Examples +// -------- +// >>> np.modf([0, 3.5]) +// (array([ 0. , 0.5]), array([ 0., 3.])) +// >>> np.modf(-0.5) +// (-0.5, -0) +// +//go:linkname Modf py.modf +func Modf(__llgo_va_list ...interface{}) *py.Object + +// multiply(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Multiply arguments element-wise. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Input arrays to be multiplied. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The product of `x1` and `x2`, element-wise. +// This is a scalar if both `x1` and `x2` are scalars. +// +// Notes +// ----- +// Equivalent to `x1` * `x2` in terms of array broadcasting. +// +// Examples +// -------- +// >>> np.multiply(2.0, 4.0) +// 8.0 +// +// >>> x1 = np.arange(9.0).reshape((3, 3)) +// >>> x2 = np.arange(3.0) +// >>> np.multiply(x1, x2) +// array([[ 0., 1., 4.], +// +// [ 0., 4., 10.], +// [ 0., 7., 16.]]) +// +// The “*“ operator can be used as a shorthand for “np.multiply“ on +// ndarrays. +// +// >>> x1 = np.arange(9.0).reshape((3, 3)) +// >>> x2 = np.arange(3.0) +// >>> x1 * x2 +// array([[ 0., 1., 4.], +// +// [ 0., 4., 10.], +// [ 0., 7., 16.]]) +// +//go:linkname Multiply py.multiply +func Multiply(__llgo_va_list ...interface{}) *py.Object + +// negative(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Numerical negative, element-wise. +// +// Parameters +// ---------- +// x : array_like or scalar +// +// Input array. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or scalar +// +// Returned array or scalar: `y = -x`. +// This is a scalar if `x` is a scalar. +// +// Examples +// -------- +// >>> np.negative([1.,-1.]) +// array([-1., 1.]) +// +// The unary “-“ operator can be used as a shorthand for “np.negative“ on +// ndarrays. +// +// >>> x1 = np.array(([1., -1.])) +// >>> -x1 +// array([-1., 1.]) +// +//go:linkname Negative py.negative +func Negative(__llgo_va_list ...interface{}) *py.Object + +// nextafter(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the next floating-point value after x1 towards x2, element-wise. +// +// Parameters +// ---------- +// x1 : array_like +// +// Values to find the next representable value of. +// +// x2 : array_like +// +// The direction where to look for the next representable value of `x1`. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// The next representable values of `x1` in the direction of `x2`. +// This is a scalar if both `x1` and `x2` are scalars. +// +// Examples +// -------- +// >>> eps = np.finfo(np.float64).eps +// >>> np.nextafter(1, 2) == eps + 1 +// True +// >>> np.nextafter([1, 2], [2, 1]) == [eps + 1, 2 - eps] +// array([ True, True]) +// +//go:linkname Nextafter py.nextafter +func Nextafter(__llgo_va_list ...interface{}) *py.Object + +// not_equal(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return (x1 != x2) element-wise. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// Input arrays. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Output array, element-wise comparison of `x1` and `x2`. +// Typically of type bool, unless ``dtype=object`` is passed. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// equal, greater, greater_equal, less, less_equal +// +// Examples +// -------- +// >>> np.not_equal([1.,2.], [1., 3.]) +// array([False, True]) +// >>> np.not_equal([1, 2], [[1, 3],[1, 4]]) +// array([[False, True], +// +// [False, True]]) +// +// The “!=“ operator can be used as a shorthand for “np.not_equal“ on +// ndarrays. +// +// >>> a = np.array([1., 2.]) +// >>> b = np.array([1., 3.]) +// >>> a != b +// array([False, True]) +// +//go:linkname NotEqual py.not_equal +func NotEqual(__llgo_va_list ...interface{}) *py.Object + +// positive(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Numerical positive, element-wise. +// +// .. versionadded:: 1.13.0 +// +// Parameters +// ---------- +// x : array_like or scalar +// +// Input array. +// +// Returns +// ------- +// y : ndarray or scalar +// +// Returned array or scalar: `y = +x`. +// This is a scalar if `x` is a scalar. +// +// Notes +// ----- +// Equivalent to `x.copy()`, but only defined for types that support +// arithmetic. +// +// Examples +// -------- +// +// >>> x1 = np.array(([1., -1.])) +// >>> np.positive(x1) +// array([ 1., -1.]) +// +// The unary “+“ operator can be used as a shorthand for “np.positive“ on +// ndarrays. +// +// >>> x1 = np.array(([1., -1.])) +// >>> +x1 +// array([ 1., -1.]) +// +//go:linkname Positive py.positive +func Positive(__llgo_va_list ...interface{}) *py.Object + +// power(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// First array elements raised to powers from second array, element-wise. +// +// Raise each base in `x1` to the positionally-corresponding power in +// `x2`. `x1` and `x2` must be broadcastable to the same shape. +// +// An integer type raised to a negative integer power will raise a +// “ValueError“. +// +// Negative values raised to a non-integral value will return “nan“. +// To get complex results, cast the input to complex, or specify the +// “dtype“ to be “complex“ (see the example below). +// +// Parameters +// ---------- +// x1 : array_like +// +// The bases. +// +// x2 : array_like +// +// The exponents. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The bases in `x1` raised to the exponents in `x2`. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// float_power : power function that promotes integers to float +// +// Examples +// -------- +// Cube each element in an array. +// +// >>> x1 = np.arange(6) +// >>> x1 +// [0, 1, 2, 3, 4, 5] +// >>> np.power(x1, 3) +// array([ 0, 1, 8, 27, 64, 125]) +// +// Raise the bases to different exponents. +// +// >>> x2 = [1.0, 2.0, 3.0, 3.0, 2.0, 1.0] +// >>> np.power(x1, x2) +// array([ 0., 1., 8., 27., 16., 5.]) +// +// The effect of broadcasting. +// +// >>> x2 = np.array([[1, 2, 3, 3, 2, 1], [1, 2, 3, 3, 2, 1]]) +// >>> x2 +// array([[1, 2, 3, 3, 2, 1], +// +// [1, 2, 3, 3, 2, 1]]) +// +// >>> np.power(x1, x2) +// array([[ 0, 1, 8, 27, 16, 5], +// +// [ 0, 1, 8, 27, 16, 5]]) +// +// The “**“ operator can be used as a shorthand for “np.power“ on +// ndarrays. +// +// >>> x2 = np.array([1, 2, 3, 3, 2, 1]) +// >>> x1 = np.arange(6) +// >>> x1 ** x2 +// array([ 0, 1, 8, 27, 16, 5]) +// +// Negative values raised to a non-integral value will result in “nan“ +// (and a warning will be generated). +// +// >>> x3 = np.array([-1.0, -4.0]) +// >>> with np.errstate(invalid='ignore'): +// ... p = np.power(x3, 1.5) +// ... +// >>> p +// array([nan, nan]) +// +// To get complex results, give the argument “dtype=complex“. +// +// >>> np.power(x3, 1.5, dtype=complex) +// array([-1.83697020e-16-1.j, -1.46957616e-15-8.j]) +// +//go:linkname Power py.power +func Power(__llgo_va_list ...interface{}) *py.Object + +// rad2deg(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Convert angles from radians to degrees. +// +// Parameters +// ---------- +// x : array_like +// +// Angle in radians. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The corresponding angle in degrees. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// deg2rad : Convert angles from degrees to radians. +// unwrap : Remove large jumps in angle by wrapping. +// +// Notes +// ----- +// .. versionadded:: 1.3.0 +// +// rad2deg(x) is “180 * x / pi“. +// +// Examples +// -------- +// >>> np.rad2deg(np.pi/2) +// 90.0 +// +//go:linkname Rad2deg py.rad2deg +func Rad2deg(__llgo_va_list ...interface{}) *py.Object + +// radians(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Convert angles from degrees to radians. +// +// Parameters +// ---------- +// x : array_like +// +// Input array in degrees. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The corresponding radian values. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// deg2rad : equivalent function +// +// Examples +// -------- +// Convert a degree array to radians +// +// >>> deg = np.arange(12.) * 30. +// >>> np.radians(deg) +// array([ 0. , 0.52359878, 1.04719755, 1.57079633, 2.0943951 , +// +// 2.61799388, 3.14159265, 3.66519143, 4.1887902 , 4.71238898, +// 5.23598776, 5.75958653]) +// +// >>> out = np.zeros((deg.shape)) +// >>> ret = np.radians(deg, out) +// >>> ret is out +// True +// +//go:linkname Radians py.radians +func Radians(__llgo_va_list ...interface{}) *py.Object + +// reciprocal(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the reciprocal of the argument, element-wise. +// +// Calculates “1/x“. +// +// Parameters +// ---------- +// x : array_like +// +// Input array. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// Return array. +// This is a scalar if `x` is a scalar. +// +// Notes +// ----- +// .. note:: +// +// This function is not designed to work with integers. +// +// For integer arguments with absolute value larger than 1 the result is +// always zero because of the way Python handles integer division. For +// integer zero the result is an overflow. +// +// Examples +// -------- +// >>> np.reciprocal(2.) +// 0.5 +// >>> np.reciprocal([1, 2., 3.33]) +// array([ 1. , 0.5 , 0.3003003]) +// +//go:linkname Reciprocal py.reciprocal +func Reciprocal(__llgo_va_list ...interface{}) *py.Object + +// remainder(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Returns the element-wise remainder of division. +// +// Computes the remainder complementary to the `floor_divide` function. It is +// equivalent to the Python modulus operator“x1 % x2“ and has the same sign +// as the divisor `x2`. The MATLAB function equivalent to “np.remainder“ +// is “mod“. +// +// .. warning:: +// +// This should not be confused with: +// +// * Python 3.7's `math.remainder` and C's ``remainder``, which +// computes the IEEE remainder, which are the complement to +// ``round(x1 / x2)``. +// * The MATLAB ``rem`` function and or the C ``%`` operator which is the +// complement to ``int(x1 / x2)``. +// +// Parameters +// ---------- +// x1 : array_like +// +// Dividend array. +// +// x2 : array_like +// +// Divisor array. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The element-wise remainder of the quotient ``floor_divide(x1, x2)``. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// floor_divide : Equivalent of Python “//“ operator. +// divmod : Simultaneous floor division and remainder. +// fmod : Equivalent of the MATLAB “rem“ function. +// divide, floor +// +// Notes +// ----- +// Returns 0 when `x2` is 0 and both `x1` and `x2` are (arrays of) +// integers. +// “mod“ is an alias of “remainder“. +// +// Examples +// -------- +// >>> np.remainder([4, 7], [2, 3]) +// array([0, 1]) +// >>> np.remainder(np.arange(7), 5) +// array([0, 1, 2, 3, 4, 0, 1]) +// +// The “%“ operator can be used as a shorthand for “np.remainder“ on +// ndarrays. +// +// >>> x1 = np.arange(7) +// >>> x1 % 5 +// array([0, 1, 2, 3, 4, 0, 1]) +// +//go:linkname Remainder py.remainder +func Remainder(__llgo_va_list ...interface{}) *py.Object + +// right_shift(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Shift the bits of an integer to the right. +// +// Bits are shifted to the right `x2`. Because the internal +// representation of numbers is in binary format, this operation is +// equivalent to dividing `x1` by “2**x2“. +// +// Parameters +// ---------- +// x1 : array_like, int +// +// Input values. +// +// x2 : array_like, int +// +// Number of bits to remove at the right of `x1`. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray, int +// +// Return `x1` with bits shifted `x2` times to the right. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// left_shift : Shift the bits of an integer to the left. +// binary_repr : Return the binary representation of the input number +// +// as a string. +// +// Examples +// -------- +// >>> np.binary_repr(10) +// '1010' +// >>> np.right_shift(10, 1) +// 5 +// >>> np.binary_repr(5) +// '101' +// +// >>> np.right_shift(10, [1,2,3]) +// array([5, 2, 1]) +// +// The “>>“ operator can be used as a shorthand for “np.right_shift“ on +// ndarrays. +// +// >>> x1 = 10 +// >>> x2 = np.array([1,2,3]) +// >>> x1 >> x2 +// array([5, 2, 1]) +// +//go:linkname RightShift py.right_shift +func RightShift(__llgo_va_list ...interface{}) *py.Object + +// rint(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Round elements of the array to the nearest integer. +// +// Parameters +// ---------- +// x : array_like +// +// Input array. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Output array is same shape and type as `x`. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// fix, ceil, floor, trunc +// +// Notes +// ----- +// For values exactly halfway between rounded decimal values, NumPy +// rounds to the nearest even value. Thus 1.5 and 2.5 round to 2.0, +// -0.5 and 0.5 round to 0.0, etc. +// +// Examples +// -------- +// >>> a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]) +// >>> np.rint(a) +// array([-2., -2., -0., 0., 2., 2., 2.]) +// +//go:linkname Rint py.rint +func Rint(__llgo_va_list ...interface{}) *py.Object + +// signbit(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Returns element-wise True where signbit is set (less than zero). +// +// Parameters +// ---------- +// x : array_like +// +// The input value(s). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// result : ndarray of bool +// +// Output array, or reference to `out` if that was supplied. +// This is a scalar if `x` is a scalar. +// +// Examples +// -------- +// >>> np.signbit(-1.2) +// True +// >>> np.signbit(np.array([1, -2.3, 2.1])) +// array([False, True, False]) +// +//go:linkname Signbit py.signbit +func Signbit(__llgo_va_list ...interface{}) *py.Object + +// sin(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Trigonometric sine, element-wise. +// +// Parameters +// ---------- +// x : array_like +// +// Angle, in radians (:math:`2 \pi` rad equals 360 degrees). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : array_like +// +// The sine of each element of x. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// arcsin, sinh, cos +// +// Notes +// ----- +// The sine is one of the fundamental functions of trigonometry (the +// mathematical study of triangles). Consider a circle of radius 1 +// centered on the origin. A ray comes in from the :math:`+x` axis, makes +// an angle at the origin (measured counter-clockwise from that axis), and +// departs from the origin. The :math:`y` coordinate of the outgoing +// ray's intersection with the unit circle is the sine of that angle. It +// ranges from -1 for :math:`x=3\pi / 2` to +1 for :math:`\pi / 2.` The +// function has zeroes where the angle is a multiple of :math:`\pi`. +// Sines of angles between :math:`\pi` and :math:`2\pi` are negative. +// The numerous properties of the sine and related functions are included +// in any standard trigonometry text. +// +// Examples +// -------- +// Print sine of one angle: +// +// >>> np.sin(np.pi/2.) +// 1.0 +// +// Print sines of an array of angles given in degrees: +// +// >>> np.sin(np.array((0., 30., 45., 60., 90.)) * np.pi / 180. ) +// array([ 0. , 0.5 , 0.70710678, 0.8660254 , 1. ]) +// +// Plot the sine function: +// +// >>> import matplotlib.pylab as plt +// >>> x = np.linspace(-np.pi, np.pi, 201) +// >>> plt.plot(x, np.sin(x)) +// >>> plt.xlabel('Angle [rad]') +// >>> plt.ylabel('sin(x)') +// >>> plt.axis('tight') +// >>> plt.show() +// +//go:linkname Sin py.sin +func Sin(__llgo_va_list ...interface{}) *py.Object + +// sinh(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Hyperbolic sine, element-wise. +// +// Equivalent to “1/2 * (np.exp(x) - np.exp(-x))“ or +// “-1j * np.sin(1j*x)“. +// +// Parameters +// ---------- +// x : array_like +// +// Input array. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The corresponding hyperbolic sine values. +// This is a scalar if `x` is a scalar. +// +// Notes +// ----- +// If `out` is provided, the function writes the result into it, +// and returns a reference to `out`. (See Examples) +// +// References +// ---------- +// M. Abramowitz and I. A. Stegun, Handbook of Mathematical Functions. +// New York, NY: Dover, 1972, pg. 83. +// +// Examples +// -------- +// >>> np.sinh(0) +// 0.0 +// >>> np.sinh(np.pi*1j/2) +// 1j +// >>> np.sinh(np.pi*1j) # (exact value is 0) +// 1.2246063538223773e-016j +// >>> # Discrepancy due to vagaries of floating point arithmetic. +// +// >>> # Example of providing the optional output parameter +// >>> out1 = np.array([0], dtype='d') +// >>> out2 = np.sinh([0.1], out1) +// >>> out2 is out1 +// True +// +// >>> # Example of ValueError due to provision of shape mis-matched `out` +// >>> np.sinh(np.zeros((3,3)),np.zeros((2,2))) +// Traceback (most recent call last): +// +// File "", line 1, in +// +// ValueError: operands could not be broadcast together with shapes (3,3) (2,2) +// +//go:linkname Sinh py.sinh +func Sinh(__llgo_va_list ...interface{}) *py.Object + +// spacing(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the distance between x and the nearest adjacent number. +// +// Parameters +// ---------- +// x : array_like +// +// Values to find the spacing of. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// The spacing of values of `x`. +// This is a scalar if `x` is a scalar. +// +// Notes +// ----- +// It can be considered as a generalization of EPS: +// “spacing(np.float64(1)) == np.finfo(np.float64).eps“, and there +// should not be any representable number between “x + spacing(x)“ and +// x for any finite x. +// +// Spacing of +- inf and NaN is NaN. +// +// Examples +// -------- +// >>> np.spacing(1) == np.finfo(np.float64).eps +// True +// +//go:linkname Spacing py.spacing +func Spacing(__llgo_va_list ...interface{}) *py.Object + +// sqrt(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the non-negative square-root of an array, element-wise. +// +// Parameters +// ---------- +// x : array_like +// +// The values whose square-roots are required. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// An array of the same shape as `x`, containing the positive +// square-root of each element in `x`. If any element in `x` is +// complex, a complex array is returned (and the square-roots of +// negative reals are calculated). If all of the elements in `x` +// are real, so is `y`, with negative elements returning ``nan``. +// If `out` was provided, `y` is a reference to it. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// emath.sqrt +// +// A version which returns complex numbers when given negative reals. +// Note that 0.0 and -0.0 are handled differently for complex inputs. +// +// Notes +// ----- +// *sqrt* has--consistent with common convention--as its branch cut the +// real "interval" [`-inf`, 0), and is continuous from above on it. +// A branch cut is a curve in the complex plane across which a given +// complex function fails to be continuous. +// +// Examples +// -------- +// >>> np.sqrt([1,4,9]) +// array([ 1., 2., 3.]) +// +// >>> np.sqrt([4, -1, -3+4J]) +// array([ 2.+0.j, 0.+1.j, 1.+2.j]) +// +// >>> np.sqrt([4, -1, np.inf]) +// array([ 2., nan, inf]) +// +//go:linkname Sqrt py.sqrt +func Sqrt(__llgo_va_list ...interface{}) *py.Object + +// square(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the element-wise square of the input. +// +// Parameters +// ---------- +// x : array_like +// +// Input data. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// out : ndarray or scalar +// +// Element-wise `x*x`, of the same shape and dtype as `x`. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// numpy.linalg.matrix_power +// sqrt +// power +// +// Examples +// -------- +// >>> np.square([-1j, 1]) +// array([-1.-0.j, 1.+0.j]) +// +//go:linkname Square py.square +func Square(__llgo_va_list ...interface{}) *py.Object + +// subtract(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Subtract arguments, element-wise. +// +// Parameters +// ---------- +// x1, x2 : array_like +// +// The arrays to be subtracted from each other. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The difference of `x1` and `x2`, element-wise. +// This is a scalar if both `x1` and `x2` are scalars. +// +// Notes +// ----- +// Equivalent to “x1 - x2“ in terms of array broadcasting. +// +// Examples +// -------- +// >>> np.subtract(1.0, 4.0) +// -3.0 +// +// >>> x1 = np.arange(9.0).reshape((3, 3)) +// >>> x2 = np.arange(3.0) +// >>> np.subtract(x1, x2) +// array([[ 0., 0., 0.], +// +// [ 3., 3., 3.], +// [ 6., 6., 6.]]) +// +// The “-“ operator can be used as a shorthand for “np.subtract“ on +// ndarrays. +// +// >>> x1 = np.arange(9.0).reshape((3, 3)) +// >>> x2 = np.arange(3.0) +// >>> x1 - x2 +// array([[0., 0., 0.], +// +// [3., 3., 3.], +// [6., 6., 6.]]) +// +//go:linkname Subtract py.subtract +func Subtract(__llgo_va_list ...interface{}) *py.Object + +// tan(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Compute tangent element-wise. +// +// Equivalent to “np.sin(x)/np.cos(x)“ element-wise. +// +// Parameters +// ---------- +// x : array_like +// +// Input array. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The corresponding tangent values. +// This is a scalar if `x` is a scalar. +// +// Notes +// ----- +// If `out` is provided, the function writes the result into it, +// and returns a reference to `out`. (See Examples) +// +// References +// ---------- +// M. Abramowitz and I. A. Stegun, Handbook of Mathematical Functions. +// New York, NY: Dover, 1972. +// +// Examples +// -------- +// >>> from math import pi +// >>> np.tan(np.array([-pi,pi/2,pi])) +// array([ 1.22460635e-16, 1.63317787e+16, -1.22460635e-16]) +// >>> +// >>> # Example of providing the optional output parameter illustrating +// >>> # that what is returned is a reference to said parameter +// >>> out1 = np.array([0], dtype='d') +// >>> out2 = np.cos([0.1], out1) +// >>> out2 is out1 +// True +// >>> +// >>> # Example of ValueError due to provision of shape mis-matched `out` +// >>> np.cos(np.zeros((3,3)),np.zeros((2,2))) +// Traceback (most recent call last): +// +// File "", line 1, in +// +// ValueError: operands could not be broadcast together with shapes (3,3) (2,2) +// +//go:linkname Tan py.tan +func Tan(__llgo_va_list ...interface{}) *py.Object + +// tanh(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Compute hyperbolic tangent element-wise. +// +// Equivalent to “np.sinh(x)/np.cosh(x)“ or “-1j * np.tan(1j*x)“. +// +// Parameters +// ---------- +// x : array_like +// +// Input array. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray +// +// The corresponding hyperbolic tangent values. +// This is a scalar if `x` is a scalar. +// +// Notes +// ----- +// If `out` is provided, the function writes the result into it, +// and returns a reference to `out`. (See Examples) +// +// References +// ---------- +// .. [1] M. Abramowitz and I. A. Stegun, Handbook of Mathematical Functions. +// +// New York, NY: Dover, 1972, pg. 83. +// https://personal.math.ubc.ca/~cbm/aands/page_83.htm +// +// .. [2] Wikipedia, "Hyperbolic function", +// +// https://en.wikipedia.org/wiki/Hyperbolic_function +// +// Examples +// -------- +// >>> np.tanh((0, np.pi*1j, np.pi*1j/2)) +// array([ 0. +0.00000000e+00j, 0. -1.22460635e-16j, 0. +1.63317787e+16j]) +// +// >>> # Example of providing the optional output parameter illustrating +// >>> # that what is returned is a reference to said parameter +// >>> out1 = np.array([0], dtype='d') +// >>> out2 = np.tanh([0.1], out1) +// >>> out2 is out1 +// True +// +// >>> # Example of ValueError due to provision of shape mis-matched `out` +// >>> np.tanh(np.zeros((3,3)),np.zeros((2,2))) +// Traceback (most recent call last): +// +// File "", line 1, in +// +// ValueError: operands could not be broadcast together with shapes (3,3) (2,2) +// +//go:linkname Tanh py.tanh +func Tanh(__llgo_va_list ...interface{}) *py.Object + +// divide(x1, x2, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Divide arguments element-wise. +// +// Parameters +// ---------- +// x1 : array_like +// +// Dividend array. +// +// x2 : array_like +// +// Divisor array. +// If ``x1.shape != x2.shape``, they must be broadcastable to a common +// shape (which becomes the shape of the output). +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or scalar +// +// The quotient ``x1/x2``, element-wise. +// This is a scalar if both `x1` and `x2` are scalars. +// +// See Also +// -------- +// seterr : Set whether to raise or warn on overflow, underflow and +// +// division by zero. +// +// Notes +// ----- +// Equivalent to “x1“ / “x2“ in terms of array-broadcasting. +// +// The “true_divide(x1, x2)“ function is an alias for +// “divide(x1, x2)“. +// +// Examples +// -------- +// >>> np.divide(2.0, 4.0) +// 0.5 +// >>> x1 = np.arange(9.0).reshape((3, 3)) +// >>> x2 = np.arange(3.0) +// >>> np.divide(x1, x2) +// array([[nan, 1. , 1. ], +// +// [inf, 4. , 2.5], +// [inf, 7. , 4. ]]) +// +// The “/“ operator can be used as a shorthand for “np.divide“ on +// ndarrays. +// +// >>> x1 = np.arange(9.0).reshape((3, 3)) +// >>> x2 = 2 * np.ones(3) +// >>> x1 / x2 +// array([[0. , 0.5, 1. ], +// +// [1.5, 2. , 2.5], +// [3. , 3.5, 4. ]]) +// +//go:linkname TrueDivide py.true_divide +func TrueDivide(__llgo_va_list ...interface{}) *py.Object + +// trunc(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Return the truncated value of the input, element-wise. +// +// The truncated value of the scalar `x` is the nearest integer `i` which +// is closer to zero than `x` is. In short, the fractional part of the +// signed number `x` is discarded. +// +// Parameters +// ---------- +// x : array_like +// +// Input data. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// y : ndarray or scalar +// +// The truncated value of each element in `x`. +// This is a scalar if `x` is a scalar. +// +// See Also +// -------- +// ceil, floor, rint, fix +// +// Notes +// ----- +// .. versionadded:: 1.3.0 +// +// Examples +// -------- +// >>> a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]) +// >>> np.trunc(a) +// array([-1., -1., -0., 0., 1., 1., 2.]) +// +//go:linkname Trunc py.trunc +func Trunc(__llgo_va_list ...interface{}) *py.Object + +// Return the scalar dtype or NumPy equivalent of Python type of an object. +// +// Parameters +// ---------- +// rep : any +// +// The object of which the type is returned. +// +// default : any, optional +// +// If given, this is returned for objects whose types can not be +// determined. If not given, None is returned for those objects. +// +// Returns +// ------- +// dtype : dtype or Python type +// +// The data type of `rep`. +// +// See Also +// -------- +// sctype2char, issctype, issubsctype, issubdtype, maximum_sctype +// +// Examples +// -------- +// >>> np.obj2sctype(np.int32) +// +// >>> np.obj2sctype(np.array([1., 2.])) +// +// >>> np.obj2sctype(np.array([1.j])) +// +// +// >>> np.obj2sctype(dict) +// +// >>> np.obj2sctype('string') +// +// >>> np.obj2sctype(1, default=list) +// +// +//go:linkname Obj2sctype py.obj2sctype +func Obj2sctype(rep *py.Object, default_ *py.Object) *py.Object + +// Return the string representation of a scalar dtype. +// +// Parameters +// ---------- +// sctype : scalar dtype or object +// +// If a scalar dtype, the corresponding string character is +// returned. If an object, `sctype2char` tries to infer its scalar type +// and then return the corresponding string character. +// +// Returns +// ------- +// typechar : str +// +// The string character corresponding to the scalar type. +// +// Raises +// ------ +// ValueError +// +// If `sctype` is an object for which the type can not be inferred. +// +// See Also +// -------- +// obj2sctype, issctype, issubsctype, mintypecode +// +// Examples +// -------- +// >>> for sctype in [np.int32, np.double, np.complex_, np.string_, np.ndarray]: +// ... print(np.sctype2char(sctype)) +// l # may vary +// d +// D +// S +// O +// +// >>> x = np.array([1., 2-1.j]) +// >>> np.sctype2char(x) +// 'D' +// >>> np.sctype2char(list) +// 'O' +// +//go:linkname Sctype2char py.sctype2char +func Sctype2char(sctype *py.Object) *py.Object + +// Return the scalar type of highest precision of the same kind as the input. +// +// Parameters +// ---------- +// t : dtype or dtype specifier +// +// The input data type. This can be a `dtype` object or an object that +// is convertible to a `dtype`. +// +// Returns +// ------- +// out : dtype +// +// The highest precision data type of the same kind (`dtype.kind`) as `t`. +// +// See Also +// -------- +// obj2sctype, mintypecode, sctype2char +// dtype +// +// Examples +// -------- +// >>> np.maximum_sctype(int) +// +// >>> np.maximum_sctype(np.uint8) +// +// >>> np.maximum_sctype(complex) +// # may vary +// +// >>> np.maximum_sctype(str) +// +// +// >>> np.maximum_sctype('i2') +// +// >>> np.maximum_sctype('f4') +// # may vary +// +//go:linkname MaximumSctype py.maximum_sctype +func MaximumSctype(t *py.Object) *py.Object + +// Determines whether the given object represents a scalar data-type. +// +// Parameters +// ---------- +// rep : any +// +// If `rep` is an instance of a scalar dtype, True is returned. If not, +// False is returned. +// +// Returns +// ------- +// out : bool +// +// Boolean result of check whether `rep` is a scalar dtype. +// +// See Also +// -------- +// issubsctype, issubdtype, obj2sctype, sctype2char +// +// Examples +// -------- +// >>> np.issctype(np.int32) +// True +// >>> np.issctype(list) +// False +// >>> np.issctype(1.1) +// False +// +// Strings are also a scalar type: +// +// >>> np.issctype(np.dtype('str')) +// True +// +//go:linkname Issctype py.issctype +func Issctype(rep *py.Object) *py.Object + +// Determine common type following standard coercion rules. +// +// .. deprecated:: NumPy 1.25 +// +// This function is deprecated, use `numpy.promote_types` or +// `numpy.result_type` instead. To achieve semantics for the +// `scalar_types` argument, use `numpy.result_type` and pass the Python +// values `0`, `0.0`, or `0j`. +// This will give the same results in almost all cases. +// More information and rare exception can be found in the +// `NumPy 1.25 release notes `_. +// +// Parameters +// ---------- +// array_types : sequence +// +// A list of dtypes or dtype convertible objects representing arrays. +// +// scalar_types : sequence +// +// A list of dtypes or dtype convertible objects representing scalars. +// +// Returns +// ------- +// datatype : dtype +// +// The common data type, which is the maximum of `array_types` ignoring +// `scalar_types`, unless the maximum of `scalar_types` is of a +// different kind (`dtype.kind`). If the kind is not understood, then +// None is returned. +// +// See Also +// -------- +// dtype, common_type, can_cast, mintypecode +// +// Examples +// -------- +// >>> np.find_common_type([], [np.int64, np.float32, complex]) +// dtype('complex128') +// >>> np.find_common_type([np.int64, np.float32], []) +// dtype('float64') +// +// The standard casting rules ensure that a scalar cannot up-cast an +// array unless the scalar is of a fundamentally different kind of data +// (i.e. under a different hierarchy in the data type hierarchy) then +// the array: +// +// >>> np.find_common_type([np.float32], [np.int64, np.float64]) +// dtype('float32') +// +// Complex is of a different type, so it up-casts the float in the +// `array_types` argument: +// +// >>> np.find_common_type([np.float32], [complex]) +// dtype('complex128') +// +// Type specifier strings are convertible to dtypes and can therefore +// be used instead of dtypes: +// +// >>> np.find_common_type(['f4', 'f4', 'i4'], ['c8']) +// dtype('complex128') +// +//go:linkname FindCommonType py.find_common_type +func FindCommonType(arrayTypes *py.Object, scalarTypes *py.Object) *py.Object + +// Returns True if first argument is a typecode lower/equal in type hierarchy. +// +// This is like the builtin :func:`issubclass`, but for `dtype`\ s. +// +// Parameters +// ---------- +// arg1, arg2 : dtype_like +// +// `dtype` or object coercible to one +// +// Returns +// ------- +// out : bool +// +// See Also +// -------- +// :ref:`arrays.scalars` : Overview of the numpy type hierarchy. +// issubsctype, issubclass_ +// +// Examples +// -------- +// `issubdtype` can be used to check the type of arrays: +// +// >>> ints = np.array([1, 2, 3], dtype=np.int32) +// >>> np.issubdtype(ints.dtype, np.integer) +// True +// >>> np.issubdtype(ints.dtype, np.floating) +// False +// +// >>> floats = np.array([1, 2, 3], dtype=np.float32) +// >>> np.issubdtype(floats.dtype, np.integer) +// False +// >>> np.issubdtype(floats.dtype, np.floating) +// True +// +// Similar types of different sizes are not subdtypes of each other: +// +// >>> np.issubdtype(np.float64, np.float32) +// False +// >>> np.issubdtype(np.float32, np.float64) +// False +// +// but both are subtypes of `floating`: +// +// >>> np.issubdtype(np.float64, np.floating) +// True +// >>> np.issubdtype(np.float32, np.floating) +// True +// +// For convenience, dtype-like objects are allowed too: +// +// >>> np.issubdtype('S1', np.string_) +// True +// >>> np.issubdtype('i4', np.signedinteger) +// True +// +//go:linkname Issubdtype py.issubdtype +func Issubdtype(arg1 *py.Object, arg2 *py.Object) *py.Object + +// Set a Python function to be used when pretty printing arrays. +// +// Parameters +// ---------- +// f : function or None +// +// Function to be used to pretty print arrays. The function should expect +// a single array argument and return a string of the representation of +// the array. If None, the function is reset to the default NumPy function +// to print arrays. +// +// repr : bool, optional +// +// If True (default), the function for pretty printing (``__repr__``) +// is set, if False the function that returns the default string +// representation (``__str__``) is set. +// +// See Also +// -------- +// set_printoptions, get_printoptions +// +// Examples +// -------- +// >>> def pprint(arr): +// ... return 'HA! - What are you going to do now?' +// ... +// >>> np.set_string_function(pprint) +// >>> a = np.arange(10) +// >>> a +// HA! - What are you going to do now? +// >>> _ = a +// >>> # [0 1 2 3 4 5 6 7 8 9] +// +// We can reset the function to the default: +// +// >>> np.set_string_function(None) +// >>> a +// array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) +// +// `repr` affects either pretty printing or normal string representation. +// Note that “__repr__“ is still affected by setting “__str__“ +// because the width of each array element in the returned string becomes +// equal to the length of the result of “__str__()“. +// +// >>> x = np.arange(4) +// >>> np.set_string_function(lambda x:'random', repr=False) +// >>> x.__str__() +// 'random' +// >>> x.__repr__() +// 'array([0, 1, 2, 3])' +// +//go:linkname SetStringFunction py.set_string_function +func SetStringFunction(f *py.Object, repr *py.Object) *py.Object + +// Set printing options. +// +// These options determine the way floating point numbers, arrays and +// other NumPy objects are displayed. +// +// Parameters +// ---------- +// precision : int or None, optional +// +// Number of digits of precision for floating point output (default 8). +// May be None if `floatmode` is not `fixed`, to print as many digits as +// necessary to uniquely specify the value. +// +// threshold : int, optional +// +// Total number of array elements which trigger summarization +// rather than full repr (default 1000). +// To always use the full repr without summarization, pass `sys.maxsize`. +// +// edgeitems : int, optional +// +// Number of array items in summary at beginning and end of +// each dimension (default 3). +// +// linewidth : int, optional +// +// The number of characters per line for the purpose of inserting +// line breaks (default 75). +// +// suppress : bool, optional +// +// If True, always print floating point numbers using fixed point +// notation, in which case numbers equal to zero in the current precision +// will print as zero. If False, then scientific notation is used when +// absolute value of the smallest number is < 1e-4 or the ratio of the +// maximum absolute value to the minimum is > 1e3. The default is False. +// +// nanstr : str, optional +// +// String representation of floating point not-a-number (default nan). +// +// infstr : str, optional +// +// String representation of floating point infinity (default inf). +// +// sign : string, either '-', '+', or ' ', optional +// +// Controls printing of the sign of floating-point types. If '+', always +// print the sign of positive values. If ' ', always prints a space +// (whitespace character) in the sign position of positive values. If +// '-', omit the sign character of positive values. (default '-') +// +// formatter : dict of callables, optional +// +// If not None, the keys should indicate the type(s) that the respective +// formatting function applies to. Callables should return a string. +// Types that are not specified (by their corresponding keys) are handled +// by the default formatters. Individual types for which a formatter +// can be set are: +// +// - 'bool' +// - 'int' +// - 'timedelta' : a `numpy.timedelta64` +// - 'datetime' : a `numpy.datetime64` +// - 'float' +// - 'longfloat' : 128-bit floats +// - 'complexfloat' +// - 'longcomplexfloat' : composed of two 128-bit floats +// - 'numpystr' : types `numpy.bytes_` and `numpy.str_` +// - 'object' : `np.object_` arrays +// +// Other keys that can be used to set a group of types at once are: +// +// - 'all' : sets all types +// - 'int_kind' : sets 'int' +// - 'float_kind' : sets 'float' and 'longfloat' +// - 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat' +// - 'str_kind' : sets 'numpystr' +// +// floatmode : str, optional +// +// Controls the interpretation of the `precision` option for +// floating-point types. Can take the following values +// (default maxprec_equal): +// +// * 'fixed': Always print exactly `precision` fractional digits, +// even if this would print more or fewer digits than +// necessary to specify the value uniquely. +// * 'unique': Print the minimum number of fractional digits necessary +// to represent each value uniquely. Different elements may +// have a different number of digits. The value of the +// `precision` option is ignored. +// * 'maxprec': Print at most `precision` fractional digits, but if +// an element can be uniquely represented with fewer digits +// only print it with that many. +// * 'maxprec_equal': Print at most `precision` fractional digits, +// but if every element in the array can be uniquely +// represented with an equal number of fewer digits, use that +// many digits for all elements. +// +// legacy : string or `False`, optional +// +// If set to the string `'1.13'` enables 1.13 legacy printing mode. This +// approximates numpy 1.13 print output by including a space in the sign +// position of floats and different behavior for 0d arrays. This also +// enables 1.21 legacy printing mode (described below). +// +// If set to the string `'1.21'` enables 1.21 legacy printing mode. This +// approximates numpy 1.21 print output of complex structured dtypes +// by not inserting spaces after commas that separate fields and after +// colons. +// +// If set to `False`, disables legacy mode. +// +// Unrecognized strings will be ignored with a warning for forward +// compatibility. +// +// .. versionadded:: 1.14.0 +// .. versionchanged:: 1.22.0 +// +// See Also +// -------- +// get_printoptions, printoptions, set_string_function, array2string +// +// Notes +// ----- +// `formatter` is always reset with a call to `set_printoptions`. +// +// Use `printoptions` as a context manager to set the values temporarily. +// +// Examples +// -------- +// Floating point precision can be set: +// +// >>> np.set_printoptions(precision=4) +// >>> np.array([1.123456789]) +// [1.1235] +// +// Long arrays can be summarised: +// +// >>> np.set_printoptions(threshold=5) +// >>> np.arange(10) +// array([0, 1, 2, ..., 7, 8, 9]) +// +// Small results can be suppressed: +// +// >>> eps = np.finfo(float).eps +// >>> x = np.arange(4.) +// >>> x**2 - (x + eps)**2 +// array([-4.9304e-32, -4.4409e-16, 0.0000e+00, 0.0000e+00]) +// >>> np.set_printoptions(suppress=True) +// >>> x**2 - (x + eps)**2 +// array([-0., -0., 0., 0.]) +// +// A custom formatter can be used to display array elements as desired: +// +// >>> np.set_printoptions(formatter={'all':lambda x: 'int: '+str(-x)}) +// >>> x = np.arange(3) +// >>> x +// array([int: 0, int: -1, int: -2]) +// >>> np.set_printoptions() # formatter gets reset +// >>> x +// array([0, 1, 2]) +// +// To put back the default options, you can use: +// +// >>> np.set_printoptions(edgeitems=3, infstr='inf', +// ... linewidth=75, nanstr='nan', precision=8, +// ... suppress=False, threshold=1000, formatter=None) +// +// Also to temporarily override options, use `printoptions` as a context manager: +// +// >>> with np.printoptions(precision=2, suppress=True, threshold=5): +// ... np.linspace(0, 10, 10) +// array([ 0. , 1.11, 2.22, ..., 7.78, 8.89, 10. ]) +// +//go:linkname SetPrintoptions py.set_printoptions +func SetPrintoptions(precision *py.Object, threshold *py.Object, edgeitems *py.Object, linewidth *py.Object, suppress *py.Object, nanstr *py.Object, infstr *py.Object, formatter *py.Object, sign *py.Object, floatmode *py.Object) *py.Object + +// Return the current print options. +// +// Returns +// ------- +// print_opts : dict +// +// Dictionary of current print options with keys +// +// - precision : int +// - threshold : int +// - edgeitems : int +// - linewidth : int +// - suppress : bool +// - nanstr : str +// - infstr : str +// - formatter : dict of callables +// - sign : str +// +// For a full description of these options, see `set_printoptions`. +// +// See Also +// -------- +// set_printoptions, printoptions, set_string_function +// +//go:linkname GetPrintoptions py.get_printoptions +func GetPrintoptions() *py.Object + +// Context manager for setting print options. +// +// Set print options for the scope of the `with` block, and restore the old +// options at the end. See `set_printoptions` for the full description of +// available options. +// +// Examples +// -------- +// +// >>> from numpy.testing import assert_equal +// >>> with np.printoptions(precision=2): +// ... np.array([2.0]) / 3 +// array([0.67]) +// +// The `as`-clause of the `with`-statement gives the current print options: +// +// >>> with np.printoptions(precision=2) as opts: +// ... assert_equal(opts, np.get_printoptions()) +// +// See Also +// -------- +// set_printoptions, get_printoptions +// +//go:linkname Printoptions py.printoptions +func Printoptions(__llgo_va_list ...interface{}) *py.Object + +// Format a floating-point scalar as a decimal string in positional notation. +// +// Provides control over rounding, trimming and padding. Uses and assumes +// IEEE unbiased rounding. Uses the "Dragon4" algorithm. +// +// Parameters +// ---------- +// x : python float or numpy floating scalar +// +// Value to format. +// +// precision : non-negative integer or None, optional +// +// Maximum number of digits to print. May be None if `unique` is +// `True`, but must be an integer if unique is `False`. +// +// unique : boolean, optional +// +// If `True`, use a digit-generation strategy which gives the shortest +// representation which uniquely identifies the floating-point number from +// other values of the same type, by judicious rounding. If `precision` +// is given fewer digits than necessary can be printed, or if `min_digits` +// is given more can be printed, in which cases the last digit is rounded +// with unbiased rounding. +// If `False`, digits are generated as if printing an infinite-precision +// value and stopping after `precision` digits, rounding the remaining +// value with unbiased rounding +// +// fractional : boolean, optional +// +// If `True`, the cutoffs of `precision` and `min_digits` refer to the +// total number of digits after the decimal point, including leading +// zeros. +// If `False`, `precision` and `min_digits` refer to the total number of +// significant digits, before or after the decimal point, ignoring leading +// zeros. +// +// trim : one of 'k', '.', '0', '-', optional +// +// Controls post-processing trimming of trailing digits, as follows: +// +// * 'k' : keep trailing zeros, keep decimal point (no trimming) +// * '.' : trim all trailing zeros, leave decimal point +// * '0' : trim all but the zero before the decimal point. Insert the +// zero if it is missing. +// * '-' : trim trailing zeros and any trailing decimal point +// +// sign : boolean, optional +// +// Whether to show the sign for positive values. +// +// pad_left : non-negative integer, optional +// +// Pad the left side of the string with whitespace until at least that +// many characters are to the left of the decimal point. +// +// pad_right : non-negative integer, optional +// +// Pad the right side of the string with whitespace until at least that +// many characters are to the right of the decimal point. +// +// min_digits : non-negative integer or None, optional +// +// Minimum number of digits to print. Only has an effect if `unique=True` +// in which case additional digits past those necessary to uniquely +// identify the value may be printed, rounding the last additional digit. +// +// -- versionadded:: 1.21.0 +// +// Returns +// ------- +// rep : string +// +// The string representation of the floating point value +// +// See Also +// -------- +// format_float_scientific +// +// Examples +// -------- +// >>> np.format_float_positional(np.float32(np.pi)) +// '3.1415927' +// >>> np.format_float_positional(np.float16(np.pi)) +// '3.14' +// >>> np.format_float_positional(np.float16(0.3)) +// '0.3' +// >>> np.format_float_positional(np.float16(0.3), unique=False, precision=10) +// '0.3000488281' +// +//go:linkname FormatFloatPositional py.format_float_positional +func FormatFloatPositional(x *py.Object, precision *py.Object, unique *py.Object, fractional *py.Object, trim *py.Object, sign *py.Object, padLeft *py.Object, padRight *py.Object, minDigits *py.Object) *py.Object + +// Format a floating-point scalar as a decimal string in scientific notation. +// +// Provides control over rounding, trimming and padding. Uses and assumes +// IEEE unbiased rounding. Uses the "Dragon4" algorithm. +// +// Parameters +// ---------- +// x : python float or numpy floating scalar +// +// Value to format. +// +// precision : non-negative integer or None, optional +// +// Maximum number of digits to print. May be None if `unique` is +// `True`, but must be an integer if unique is `False`. +// +// unique : boolean, optional +// +// If `True`, use a digit-generation strategy which gives the shortest +// representation which uniquely identifies the floating-point number from +// other values of the same type, by judicious rounding. If `precision` +// is given fewer digits than necessary can be printed. If `min_digits` +// is given more can be printed, in which cases the last digit is rounded +// with unbiased rounding. +// If `False`, digits are generated as if printing an infinite-precision +// value and stopping after `precision` digits, rounding the remaining +// value with unbiased rounding +// +// trim : one of 'k', '.', '0', '-', optional +// +// Controls post-processing trimming of trailing digits, as follows: +// +// * 'k' : keep trailing zeros, keep decimal point (no trimming) +// * '.' : trim all trailing zeros, leave decimal point +// * '0' : trim all but the zero before the decimal point. Insert the +// zero if it is missing. +// * '-' : trim trailing zeros and any trailing decimal point +// +// sign : boolean, optional +// +// Whether to show the sign for positive values. +// +// pad_left : non-negative integer, optional +// +// Pad the left side of the string with whitespace until at least that +// many characters are to the left of the decimal point. +// +// exp_digits : non-negative integer, optional +// +// Pad the exponent with zeros until it contains at least this many digits. +// If omitted, the exponent will be at least 2 digits. +// +// min_digits : non-negative integer or None, optional +// +// Minimum number of digits to print. This only has an effect for +// `unique=True`. In that case more digits than necessary to uniquely +// identify the value may be printed and rounded unbiased. +// +// -- versionadded:: 1.21.0 +// +// Returns +// ------- +// rep : string +// +// The string representation of the floating point value +// +// See Also +// -------- +// format_float_positional +// +// Examples +// -------- +// >>> np.format_float_scientific(np.float32(np.pi)) +// '3.1415927e+00' +// >>> s = np.float32(1.23e24) +// >>> np.format_float_scientific(s, unique=False, precision=15) +// '1.230000071797338e+24' +// >>> np.format_float_scientific(s, exp_digits=4) +// '1.23e+0024' +// +//go:linkname FormatFloatScientific py.format_float_scientific +func FormatFloatScientific(x *py.Object, precision *py.Object, unique *py.Object, trim *py.Object, sign *py.Object, padLeft *py.Object, expDigits *py.Object, minDigits *py.Object) *py.Object + +// Return an ndarray of the provided type that satisfies requirements. +// +// This function is useful to be sure that an array with the correct flags +// is returned for passing to compiled code (perhaps through ctypes). +// +// Parameters +// ---------- +// a : array_like +// +// The object to be converted to a type-and-requirement-satisfying array. +// +// dtype : data-type +// +// The required data-type. If None preserve the current dtype. If your +// application requires the data to be in native byteorder, include +// a byteorder specification as a part of the dtype specification. +// +// requirements : str or sequence of str +// +// The requirements list can be any of the following +// +// * 'F_CONTIGUOUS' ('F') - ensure a Fortran-contiguous array +// * 'C_CONTIGUOUS' ('C') - ensure a C-contiguous array +// * 'ALIGNED' ('A') - ensure a data-type aligned array +// * 'WRITEABLE' ('W') - ensure a writable array +// * 'OWNDATA' ('O') - ensure an array that owns its own data +// * 'ENSUREARRAY', ('E') - ensure a base array, instead of a subclass +// +// like : array_like, optional +// +// Reference object to allow the creation of arrays which are not +// NumPy arrays. If an array-like passed in as ``like`` supports +// the ``__array_function__`` protocol, the result will be defined +// by it. In this case, it ensures the creation of an array object +// compatible with that passed in via this argument. +// +// .. versionadded:: 1.20.0 +// +// Returns +// ------- +// out : ndarray +// +// Array with specified requirements and type if given. +// +// See Also +// -------- +// asarray : Convert input to an ndarray. +// asanyarray : Convert to an ndarray, but pass through ndarray subclasses. +// ascontiguousarray : Convert input to a contiguous array. +// asfortranarray : Convert input to an ndarray with column-major +// +// memory order. +// +// ndarray.flags : Information about the memory layout of the array. +// +// Notes +// ----- +// The returned array will be guaranteed to have the listed requirements +// by making a copy if needed. +// +// Examples +// -------- +// >>> x = np.arange(6).reshape(2,3) +// >>> x.flags +// +// C_CONTIGUOUS : True +// F_CONTIGUOUS : False +// OWNDATA : False +// WRITEABLE : True +// ALIGNED : True +// WRITEBACKIFCOPY : False +// +// >>> y = np.require(x, dtype=np.float32, requirements=['A', 'O', 'W', 'F']) +// >>> y.flags +// +// C_CONTIGUOUS : False +// F_CONTIGUOUS : True +// OWNDATA : True +// WRITEABLE : True +// ALIGNED : True +// WRITEBACKIFCOPY : False +// +//go:linkname Require py.require +func Require(a *py.Object, dtype *py.Object, requirements *py.Object) *py.Object + +// Set how floating-point errors are handled. +// +// Note that operations on integer scalar types (such as `int16`) are +// handled like floating point, and are affected by these settings. +// +// Parameters +// ---------- +// all : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional +// +// Set treatment for all types of floating-point errors at once: +// +// - ignore: Take no action when the exception occurs. +// - warn: Print a `RuntimeWarning` (via the Python `warnings` module). +// - raise: Raise a `FloatingPointError`. +// - call: Call a function specified using the `seterrcall` function. +// - print: Print a warning directly to ``stdout``. +// - log: Record error in a Log object specified by `seterrcall`. +// +// The default is not to change the current behavior. +// +// divide : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional +// +// Treatment for division by zero. +// +// over : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional +// +// Treatment for floating-point overflow. +// +// under : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional +// +// Treatment for floating-point underflow. +// +// invalid : {'ignore', 'warn', 'raise', 'call', 'print', 'log'}, optional +// +// Treatment for invalid floating-point operation. +// +// Returns +// ------- +// old_settings : dict +// +// Dictionary containing the old settings. +// +// See also +// -------- +// seterrcall : Set a callback function for the 'call' mode. +// geterr, geterrcall, errstate +// +// Notes +// ----- +// The floating-point exceptions are defined in the IEEE 754 standard [1]_: +// +// - Division by zero: infinite result obtained from finite numbers. +// - Overflow: result too large to be expressed. +// - Underflow: result so close to zero that some precision +// was lost. +// - Invalid operation: result is not an expressible number, typically +// indicates that a NaN was produced. +// +// .. [1] https://en.wikipedia.org/wiki/IEEE_754 +// +// Examples +// -------- +// >>> old_settings = np.seterr(all='ignore') #seterr to known value +// >>> np.seterr(over='raise') +// {'divide': 'ignore', 'over': 'ignore', 'under': 'ignore', 'invalid': 'ignore'} +// >>> np.seterr(**old_settings) # reset to default +// {'divide': 'ignore', 'over': 'raise', 'under': 'ignore', 'invalid': 'ignore'} +// +// >>> np.int16(32000) * np.int16(3) +// 30464 +// >>> old_settings = np.seterr(all='warn', over='raise') +// >>> np.int16(32000) * np.int16(3) +// Traceback (most recent call last): +// +// File "", line 1, in +// +// FloatingPointError: overflow encountered in scalar multiply +// +// >>> old_settings = np.seterr(all='print') +// >>> np.geterr() +// {'divide': 'print', 'over': 'print', 'under': 'print', 'invalid': 'print'} +// >>> np.int16(32000) * np.int16(3) +// 30464 +// +//go:linkname Seterr py.seterr +func Seterr(all *py.Object, divide *py.Object, over *py.Object, under *py.Object, invalid *py.Object) *py.Object + +// Get the current way of handling floating-point errors. +// +// Returns +// ------- +// res : dict +// +// A dictionary with keys "divide", "over", "under", and "invalid", +// whose values are from the strings "ignore", "print", "log", "warn", +// "raise", and "call". The keys represent possible floating-point +// exceptions, and the values define how these exceptions are handled. +// +// See Also +// -------- +// geterrcall, seterr, seterrcall +// +// Notes +// ----- +// For complete documentation of the types of floating-point exceptions and +// treatment options, see `seterr`. +// +// Examples +// -------- +// >>> np.geterr() +// {'divide': 'warn', 'over': 'warn', 'under': 'ignore', 'invalid': 'warn'} +// >>> np.arange(3.) / np.arange(3.) +// array([nan, 1., 1.]) +// +// >>> oldsettings = np.seterr(all='warn', over='raise') +// >>> np.geterr() +// {'divide': 'warn', 'over': 'raise', 'under': 'warn', 'invalid': 'warn'} +// >>> np.arange(3.) / np.arange(3.) +// array([nan, 1., 1.]) +// +//go:linkname Geterr py.geterr +func Geterr() *py.Object + +// Set the size of the buffer used in ufuncs. +// +// Parameters +// ---------- +// size : int +// +// Size of buffer. +// +//go:linkname Setbufsize py.setbufsize +func Setbufsize(size *py.Object) *py.Object + +// Return the size of the buffer used in ufuncs. +// +// Returns +// ------- +// getbufsize : int +// +// Size of ufunc buffer in bytes. +// +//go:linkname Getbufsize py.getbufsize +func Getbufsize() *py.Object + +// Set the floating-point error callback function or log object. +// +// There are two ways to capture floating-point error messages. The first +// is to set the error-handler to 'call', using `seterr`. Then, set +// the function to call using this function. +// +// The second is to set the error-handler to 'log', using `seterr`. +// Floating-point errors then trigger a call to the 'write' method of +// the provided object. +// +// Parameters +// ---------- +// func : callable f(err, flag) or object with write method +// +// Function to call upon floating-point errors ('call'-mode) or +// object whose 'write' method is used to log such message ('log'-mode). +// +// The call function takes two arguments. The first is a string describing +// the type of error (such as "divide by zero", "overflow", "underflow", +// or "invalid value"), and the second is the status flag. The flag is a +// byte, whose four least-significant bits indicate the type of error, one +// of "divide", "over", "under", "invalid":: +// +// [0 0 0 0 divide over under invalid] +// +// In other words, ``flags = divide + 2*over + 4*under + 8*invalid``. +// +// If an object is provided, its write method should take one argument, +// a string. +// +// Returns +// ------- +// h : callable, log instance or None +// +// The old error handler. +// +// See Also +// -------- +// seterr, geterr, geterrcall +// +// Examples +// -------- +// Callback upon error: +// +// >>> def err_handler(type, flag): +// ... print("Floating point error (%s), with flag %s" % (type, flag)) +// ... +// +// >>> saved_handler = np.seterrcall(err_handler) +// >>> save_err = np.seterr(all='call') +// +// >>> np.array([1, 2, 3]) / 0.0 +// Floating point error (divide by zero), with flag 1 +// array([inf, inf, inf]) +// +// >>> np.seterrcall(saved_handler) +// +// >>> np.seterr(**save_err) +// {'divide': 'call', 'over': 'call', 'under': 'call', 'invalid': 'call'} +// +// Log error message: +// +// >>> class Log: +// ... def write(self, msg): +// ... print("LOG: %s" % msg) +// ... +// +// >>> log = Log() +// >>> saved_handler = np.seterrcall(log) +// >>> save_err = np.seterr(all='log') +// +// >>> np.array([1, 2, 3]) / 0.0 +// LOG: Warning: divide by zero encountered in divide +// array([inf, inf, inf]) +// +// >>> np.seterrcall(saved_handler) +// +// >>> np.seterr(**save_err) +// {'divide': 'log', 'over': 'log', 'under': 'log', 'invalid': 'log'} +// +//go:linkname Seterrcall py.seterrcall +func Seterrcall(func_ *py.Object) *py.Object + +// Return the current callback function used on floating-point errors. +// +// When the error handling for a floating-point error (one of "divide", +// "over", "under", or "invalid") is set to 'call' or 'log', the function +// that is called or the log instance that is written to is returned by +// `geterrcall`. This function or log instance has been set with +// `seterrcall`. +// +// Returns +// ------- +// errobj : callable, log instance or None +// +// The current error handler. If no handler was set through `seterrcall`, +// ``None`` is returned. +// +// See Also +// -------- +// seterrcall, seterr, geterr +// +// Notes +// ----- +// For complete documentation of the types of floating-point exceptions and +// treatment options, see `seterr`. +// +// Examples +// -------- +// >>> np.geterrcall() # we did not yet set a handler, returns None +// +// >>> oldsettings = np.seterr(all='call') +// >>> def err_handler(type, flag): +// ... print("Floating point error (%s), with flag %s" % (type, flag)) +// >>> oldhandler = np.seterrcall(err_handler) +// >>> np.array([1, 2, 3]) / 0.0 +// Floating point error (divide by zero), with flag 1 +// array([inf, inf, inf]) +// +// >>> cur_handler = np.geterrcall() +// >>> cur_handler is err_handler +// True +// +//go:linkname Geterrcall py.geterrcall +func Geterrcall() *py.Object + +// Return a description for the given data type code. +// +// Parameters +// ---------- +// char : str +// +// Data type code. +// +// Returns +// ------- +// out : str +// +// Description of the input data type code. +// +// See Also +// -------- +// dtype, typecodes +// +// Examples +// -------- +// >>> typechars = ['S1', '?', 'B', 'D', 'G', 'F', 'I', 'H', 'L', 'O', 'Q', +// ... 'S', 'U', 'V', 'b', 'd', 'g', 'f', 'i', 'h', 'l', 'q'] +// >>> for typechar in typechars: +// ... print(typechar, ' : ', np.typename(typechar)) +// ... +// S1 : character +// ? : bool +// B : unsigned char +// D : complex double precision +// G : complex long double precision +// F : complex single precision +// I : unsigned integer +// H : unsigned short +// L : unsigned long integer +// O : object +// Q : unsigned long long integer +// S : string +// U : unicode +// V : void +// b : signed char +// d : double precision +// g : long precision +// f : single precision +// i : integer +// h : short +// l : long integer +// q : long long integer +// +//go:linkname Typename py.typename +func Typename(char *py.Object) *py.Object + +// Return the character for the minimum-size type to which given types can +// be safely cast. +// +// The returned type character must represent the smallest size dtype such +// that an array of the returned type can handle the data from an array of +// all types in `typechars` (or if `typechars` is an array, then its +// dtype.char). +// +// Parameters +// ---------- +// typechars : list of str or array_like +// +// If a list of strings, each string should represent a dtype. +// If array_like, the character representation of the array dtype is used. +// +// typeset : str or list of str, optional +// +// The set of characters that the returned character is chosen from. +// The default set is 'GDFgdf'. +// +// default : str, optional +// +// The default character, this is returned if none of the characters in +// `typechars` matches a character in `typeset`. +// +// Returns +// ------- +// typechar : str +// +// The character representing the minimum-size type that was found. +// +// See Also +// -------- +// dtype, sctype2char, maximum_sctype +// +// Examples +// -------- +// >>> np.mintypecode(['d', 'f', 'S']) +// 'd' +// >>> x = np.array([1.1, 2-3.j]) +// >>> np.mintypecode(x) +// 'D' +// +// >>> np.mintypecode('abceh', default='G') +// 'G' +// +//go:linkname Mintypecode py.mintypecode +func Mintypecode(typechars *py.Object, typeset *py.Object, default_ *py.Object) *py.Object + +// Return the indices to access the main diagonal of an array. +// +// This returns a tuple of indices that can be used to access the main +// diagonal of an array `a` with “a.ndim >= 2“ dimensions and shape +// (n, n, ..., n). For “a.ndim = 2“ this is the usual diagonal, for +// “a.ndim > 2“ this is the set of indices to access “a[i, i, ..., i]“ +// for “i = [0..n-1]“. +// +// Parameters +// ---------- +// n : int +// +// The size, along each dimension, of the arrays for which the returned +// indices can be used. +// +// ndim : int, optional +// +// The number of dimensions. +// +// See Also +// -------- +// diag_indices_from +// +// Notes +// ----- +// .. versionadded:: 1.4.0 +// +// Examples +// -------- +// Create a set of indices to access the diagonal of a (4, 4) array: +// +// >>> di = np.diag_indices(4) +// >>> di +// (array([0, 1, 2, 3]), array([0, 1, 2, 3])) +// >>> a = np.arange(16).reshape(4, 4) +// >>> a +// array([[ 0, 1, 2, 3], +// +// [ 4, 5, 6, 7], +// [ 8, 9, 10, 11], +// [12, 13, 14, 15]]) +// +// >>> a[di] = 100 +// >>> a +// array([[100, 1, 2, 3], +// +// [ 4, 100, 6, 7], +// [ 8, 9, 100, 11], +// [ 12, 13, 14, 100]]) +// +// Now, we create indices to manipulate a 3-D array: +// +// >>> d3 = np.diag_indices(2, 3) +// >>> d3 +// (array([0, 1]), array([0, 1]), array([0, 1])) +// +// And use it to set the diagonal of an array of zeros to 1: +// +// >>> a = np.zeros((2, 2, 2), dtype=int) +// >>> a[d3] = 1 +// >>> a +// array([[[1, 0], +// +// [0, 0]], +// [[0, 0], +// [0, 1]]]) +// +//go:linkname DiagIndices py.diag_indices +func DiagIndices(n *py.Object, ndim *py.Object) *py.Object + +// Check whether or not an object can be iterated over. +// +// Parameters +// ---------- +// y : object +// +// Input object. +// +// Returns +// ------- +// b : bool +// +// Return ``True`` if the object has an iterator method or is a +// sequence and ``False`` otherwise. +// +// Examples +// -------- +// >>> np.iterable([1, 2, 3]) +// True +// >>> np.iterable(2) +// False +// +// Notes +// ----- +// In most cases, the results of “np.iterable(obj)“ are consistent with +// “isinstance(obj, collections.abc.Iterable)“. One notable exception is +// the treatment of 0-dimensional arrays:: +// +// >>> from collections.abc import Iterable +// >>> a = np.array(1.0) # 0-dimensional numpy array +// >>> isinstance(a, Iterable) +// True +// >>> np.iterable(a) +// False +// +//go:linkname Iterable py.iterable +func Iterable(y *py.Object) *py.Object + +// Display a message on a device. +// +// Parameters +// ---------- +// mesg : str +// +// Message to display. +// +// device : object +// +// Device to write message. If None, defaults to ``sys.stdout`` which is +// very similar to ``print``. `device` needs to have ``write()`` and +// ``flush()`` methods. +// +// linefeed : bool, optional +// +// Option whether to print a line feed or not. Defaults to True. +// +// Raises +// ------ +// AttributeError +// +// If `device` does not have a ``write()`` or ``flush()`` method. +// +// Examples +// -------- +// Besides “sys.stdout“, a file-like object can also be used as it has +// both required methods: +// +// >>> from io import StringIO +// >>> buf = StringIO() +// >>> np.disp(u'"Display" in a file', device=buf) +// >>> buf.getvalue() +// '"Display" in a file\n' +// +//go:linkname Disp py.disp +func Disp(mesg *py.Object, device *py.Object, linefeed *py.Object) *py.Object + +// Convert the input to an array, checking for NaNs or Infs. +// +// Parameters +// ---------- +// a : array_like +// Input data, in any form that can be converted to an array. This +// includes lists, lists of tuples, tuples, tuples of tuples, tuples +// of lists and ndarrays. Success requires no NaNs or Infs. +// dtype : data-type, optional +// By default, the data-type is inferred from the input data. +// order : {'C', 'F', 'A', 'K'}, optional +// Memory layout. 'A' and 'K' depend on the order of input array a. +// 'C' row-major (C-style), +// 'F' column-major (Fortran-style) memory representation. +// 'A' (any) means 'F' if `a` is Fortran contiguous, 'C' otherwise +// 'K' (keep) preserve input order +// Defaults to 'C'. +// +// Returns +// ------- +// out : ndarray +// Array interpretation of `a`. No copy is performed if the input +// is already an ndarray. If `a` is a subclass of ndarray, a base +// class ndarray is returned. +// +// Raises +// ------ +// ValueError +// Raises ValueError if `a` contains NaN (Not a Number) or Inf (Infinity). +// +// See Also +// -------- +// asarray : Create and array. +// asanyarray : Similar function which passes through subclasses. +// ascontiguousarray : Convert input to a contiguous array. +// asfarray : Convert input to a floating point ndarray. +// asfortranarray : Convert input to an ndarray with column-major +// memory order. +// fromiter : Create an array from an iterator. +// fromfunction : Construct an array by executing a function on grid +// positions. +// +// Examples +// -------- +// Convert a list into an array. If all elements are finite +// ``asarray_chkfinite`` is identical to ``asarray``. +// +// >>> a = [1, 2] +// >>> np.asarray_chkfinite(a, dtype=float) +// array([1., 2.]) +// +// Raises ValueError if array_like contains Nans or Infs. +// +// >>> a = [1, 2, np.inf] +// >>> try: +// ... np.asarray_chkfinite(a) +// ... except ValueError: +// ... print('ValueError') +// ... +// ValueError +// +//go:linkname AsarrayChkfinite py.asarray_chkfinite +func AsarrayChkfinite(a *py.Object, dtype *py.Object, order *py.Object) *py.Object + +// Return the Hamming window. +// +// The Hamming window is a taper formed by using a weighted cosine. +// +// Parameters +// ---------- +// M : int +// +// Number of points in the output window. If zero or less, an +// empty array is returned. +// +// Returns +// ------- +// out : ndarray +// +// The window, with the maximum value normalized to one (the value +// one appears only if the number of samples is odd). +// +// See Also +// -------- +// bartlett, blackman, hanning, kaiser +// +// Notes +// ----- +// The Hamming window is defined as +// +// .. math:: w(n) = 0.54 - 0.46\cos\left(\frac{2\pi{n}}{M-1}\right) +// +// \qquad 0 \leq n \leq M-1 +// +// The Hamming was named for R. W. Hamming, an associate of J. W. Tukey +// and is described in Blackman and Tukey. It was recommended for +// smoothing the truncated autocovariance function in the time domain. +// Most references to the Hamming window come from the signal processing +// literature, where it is used as one of many windowing functions for +// smoothing values. It is also known as an apodization (which means +// "removing the foot", i.e. smoothing discontinuities at the beginning +// and end of the sampled signal) or tapering function. +// +// References +// ---------- +// .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power +// +// spectra, Dover Publications, New York. +// +// .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The +// +// University of Alberta Press, 1975, pp. 109-110. +// +// .. [3] Wikipedia, "Window function", +// +// https://en.wikipedia.org/wiki/Window_function +// +// .. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling, +// +// "Numerical Recipes", Cambridge University Press, 1986, page 425. +// +// Examples +// -------- +// >>> np.hamming(12) +// array([ 0.08 , 0.15302337, 0.34890909, 0.60546483, 0.84123594, # may vary +// +// 0.98136677, 0.98136677, 0.84123594, 0.60546483, 0.34890909, +// 0.15302337, 0.08 ]) +// +// Plot the window and the frequency response: +// +// >>> import matplotlib.pyplot as plt +// >>> from numpy.fft import fft, fftshift +// >>> window = np.hamming(51) +// >>> plt.plot(window) +// [] +// >>> plt.title("Hamming window") +// Text(0.5, 1.0, 'Hamming window') +// >>> plt.ylabel("Amplitude") +// Text(0, 0.5, 'Amplitude') +// >>> plt.xlabel("Sample") +// Text(0.5, 0, 'Sample') +// >>> plt.show() +// +// >>> plt.figure() +//
+// >>> A = fft(window, 2048) / 25.5 +// >>> mag = np.abs(fftshift(A)) +// >>> freq = np.linspace(-0.5, 0.5, len(A)) +// >>> response = 20 * np.log10(mag) +// >>> response = np.clip(response, -100, 100) +// >>> plt.plot(freq, response) +// [] +// >>> plt.title("Frequency response of Hamming window") +// Text(0.5, 1.0, 'Frequency response of Hamming window') +// >>> plt.ylabel("Magnitude [dB]") +// Text(0, 0.5, 'Magnitude [dB]') +// >>> plt.xlabel("Normalized frequency [cycles per sample]") +// Text(0.5, 0, 'Normalized frequency [cycles per sample]') +// >>> plt.axis('tight') +// ... +// >>> plt.show() +// +//go:linkname Hamming py.hamming +func Hamming(M *py.Object) *py.Object + +// Return the Hanning window. +// +// The Hanning window is a taper formed by using a weighted cosine. +// +// Parameters +// ---------- +// M : int +// +// Number of points in the output window. If zero or less, an +// empty array is returned. +// +// Returns +// ------- +// out : ndarray, shape(M,) +// +// The window, with the maximum value normalized to one (the value +// one appears only if `M` is odd). +// +// See Also +// -------- +// bartlett, blackman, hamming, kaiser +// +// Notes +// ----- +// The Hanning window is defined as +// +// .. math:: w(n) = 0.5 - 0.5\cos\left(\frac{2\pi{n}}{M-1}\right) +// +// \qquad 0 \leq n \leq M-1 +// +// The Hanning was named for Julius von Hann, an Austrian meteorologist. +// It is also known as the Cosine Bell. Some authors prefer that it be +// called a Hann window, to help avoid confusion with the very similar +// Hamming window. +// +// Most references to the Hanning window come from the signal processing +// literature, where it is used as one of many windowing functions for +// smoothing values. It is also known as an apodization (which means +// "removing the foot", i.e. smoothing discontinuities at the beginning +// and end of the sampled signal) or tapering function. +// +// References +// ---------- +// .. [1] Blackman, R.B. and Tukey, J.W., (1958) The measurement of power +// +// spectra, Dover Publications, New York. +// +// .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", +// +// The University of Alberta Press, 1975, pp. 106-108. +// +// .. [3] Wikipedia, "Window function", +// +// https://en.wikipedia.org/wiki/Window_function +// +// .. [4] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling, +// +// "Numerical Recipes", Cambridge University Press, 1986, page 425. +// +// Examples +// -------- +// >>> np.hanning(12) +// array([0. , 0.07937323, 0.29229249, 0.57115742, 0.82743037, +// +// 0.97974649, 0.97974649, 0.82743037, 0.57115742, 0.29229249, +// 0.07937323, 0. ]) +// +// Plot the window and its frequency response: +// +// >>> import matplotlib.pyplot as plt +// >>> from numpy.fft import fft, fftshift +// >>> window = np.hanning(51) +// >>> plt.plot(window) +// [] +// >>> plt.title("Hann window") +// Text(0.5, 1.0, 'Hann window') +// >>> plt.ylabel("Amplitude") +// Text(0, 0.5, 'Amplitude') +// >>> plt.xlabel("Sample") +// Text(0.5, 0, 'Sample') +// >>> plt.show() +// +// >>> plt.figure() +//
+// >>> A = fft(window, 2048) / 25.5 +// >>> mag = np.abs(fftshift(A)) +// >>> freq = np.linspace(-0.5, 0.5, len(A)) +// >>> with np.errstate(divide='ignore', invalid='ignore'): +// ... response = 20 * np.log10(mag) +// ... +// >>> response = np.clip(response, -100, 100) +// >>> plt.plot(freq, response) +// [] +// >>> plt.title("Frequency response of the Hann window") +// Text(0.5, 1.0, 'Frequency response of the Hann window') +// >>> plt.ylabel("Magnitude [dB]") +// Text(0, 0.5, 'Magnitude [dB]') +// >>> plt.xlabel("Normalized frequency [cycles per sample]") +// Text(0.5, 0, 'Normalized frequency [cycles per sample]') +// >>> plt.axis('tight') +// ... +// >>> plt.show() +// +//go:linkname Hanning py.hanning +func Hanning(M *py.Object) *py.Object + +// Return the Bartlett window. +// +// The Bartlett window is very similar to a triangular window, except +// that the end points are at zero. It is often used in signal +// processing for tapering a signal, without generating too much +// ripple in the frequency domain. +// +// Parameters +// ---------- +// M : int +// +// Number of points in the output window. If zero or less, an +// empty array is returned. +// +// Returns +// ------- +// out : array +// +// The triangular window, with the maximum value normalized to one +// (the value one appears only if the number of samples is odd), with +// the first and last samples equal to zero. +// +// See Also +// -------- +// blackman, hamming, hanning, kaiser +// +// Notes +// ----- +// The Bartlett window is defined as +// +// .. math:: w(n) = \frac{2}{M-1} \left( +// +// \frac{M-1}{2} - \left|n - \frac{M-1}{2}\right| +// \right) +// +// Most references to the Bartlett window come from the signal processing +// literature, where it is used as one of many windowing functions for +// smoothing values. Note that convolution with this window produces linear +// interpolation. It is also known as an apodization (which means "removing +// the foot", i.e. smoothing discontinuities at the beginning and end of the +// sampled signal) or tapering function. The Fourier transform of the +// Bartlett window is the product of two sinc functions. Note the excellent +// discussion in Kanasewich [2]_. +// +// References +// ---------- +// .. [1] M.S. Bartlett, "Periodogram Analysis and Continuous Spectra", +// +// Biometrika 37, 1-16, 1950. +// +// .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", +// +// The University of Alberta Press, 1975, pp. 109-110. +// +// .. [3] A.V. Oppenheim and R.W. Schafer, "Discrete-Time Signal +// +// Processing", Prentice-Hall, 1999, pp. 468-471. +// +// .. [4] Wikipedia, "Window function", +// +// https://en.wikipedia.org/wiki/Window_function +// +// .. [5] W.H. Press, B.P. Flannery, S.A. Teukolsky, and W.T. Vetterling, +// +// "Numerical Recipes", Cambridge University Press, 1986, page 429. +// +// Examples +// -------- +// >>> import matplotlib.pyplot as plt +// >>> np.bartlett(12) +// array([ 0. , 0.18181818, 0.36363636, 0.54545455, 0.72727273, # may vary +// +// 0.90909091, 0.90909091, 0.72727273, 0.54545455, 0.36363636, +// 0.18181818, 0. ]) +// +// Plot the window and its frequency response (requires SciPy and matplotlib): +// +// >>> from numpy.fft import fft, fftshift +// >>> window = np.bartlett(51) +// >>> plt.plot(window) +// [] +// >>> plt.title("Bartlett window") +// Text(0.5, 1.0, 'Bartlett window') +// >>> plt.ylabel("Amplitude") +// Text(0, 0.5, 'Amplitude') +// >>> plt.xlabel("Sample") +// Text(0.5, 0, 'Sample') +// >>> plt.show() +// +// >>> plt.figure() +//
+// >>> A = fft(window, 2048) / 25.5 +// >>> mag = np.abs(fftshift(A)) +// >>> freq = np.linspace(-0.5, 0.5, len(A)) +// >>> with np.errstate(divide='ignore', invalid='ignore'): +// ... response = 20 * np.log10(mag) +// ... +// >>> response = np.clip(response, -100, 100) +// >>> plt.plot(freq, response) +// [] +// >>> plt.title("Frequency response of Bartlett window") +// Text(0.5, 1.0, 'Frequency response of Bartlett window') +// >>> plt.ylabel("Magnitude [dB]") +// Text(0, 0.5, 'Magnitude [dB]') +// >>> plt.xlabel("Normalized frequency [cycles per sample]") +// Text(0.5, 0, 'Normalized frequency [cycles per sample]') +// >>> _ = plt.axis('tight') +// >>> plt.show() +// +//go:linkname Bartlett py.bartlett +func Bartlett(M *py.Object) *py.Object + +// Return the Blackman window. +// +// The Blackman window is a taper formed by using the first three +// terms of a summation of cosines. It was designed to have close to the +// minimal leakage possible. It is close to optimal, only slightly worse +// than a Kaiser window. +// +// Parameters +// ---------- +// M : int +// +// Number of points in the output window. If zero or less, an empty +// array is returned. +// +// Returns +// ------- +// out : ndarray +// +// The window, with the maximum value normalized to one (the value one +// appears only if the number of samples is odd). +// +// See Also +// -------- +// bartlett, hamming, hanning, kaiser +// +// Notes +// ----- +// The Blackman window is defined as +// +// .. math:: w(n) = 0.42 - 0.5 \cos(2\pi n/M) + 0.08 \cos(4\pi n/M) +// +// Most references to the Blackman window come from the signal processing +// literature, where it is used as one of many windowing functions for +// smoothing values. It is also known as an apodization (which means +// "removing the foot", i.e. smoothing discontinuities at the beginning +// and end of the sampled signal) or tapering function. It is known as a +// "near optimal" tapering function, almost as good (by some measures) +// as the kaiser window. +// +// References +// ---------- +// Blackman, R.B. and Tukey, J.W., (1958) The measurement of power spectra, +// Dover Publications, New York. +// +// Oppenheim, A.V., and R.W. Schafer. Discrete-Time Signal Processing. +// Upper Saddle River, NJ: Prentice-Hall, 1999, pp. 468-471. +// +// Examples +// -------- +// >>> import matplotlib.pyplot as plt +// >>> np.blackman(12) +// array([-1.38777878e-17, 3.26064346e-02, 1.59903635e-01, # may vary +// +// 4.14397981e-01, 7.36045180e-01, 9.67046769e-01, +// 9.67046769e-01, 7.36045180e-01, 4.14397981e-01, +// 1.59903635e-01, 3.26064346e-02, -1.38777878e-17]) +// +// Plot the window and the frequency response: +// +// >>> from numpy.fft import fft, fftshift +// >>> window = np.blackman(51) +// >>> plt.plot(window) +// [] +// >>> plt.title("Blackman window") +// Text(0.5, 1.0, 'Blackman window') +// >>> plt.ylabel("Amplitude") +// Text(0, 0.5, 'Amplitude') +// >>> plt.xlabel("Sample") +// Text(0.5, 0, 'Sample') +// >>> plt.show() +// +// >>> plt.figure() +//
+// >>> A = fft(window, 2048) / 25.5 +// >>> mag = np.abs(fftshift(A)) +// >>> freq = np.linspace(-0.5, 0.5, len(A)) +// >>> with np.errstate(divide='ignore', invalid='ignore'): +// ... response = 20 * np.log10(mag) +// ... +// >>> response = np.clip(response, -100, 100) +// >>> plt.plot(freq, response) +// [] +// >>> plt.title("Frequency response of Blackman window") +// Text(0.5, 1.0, 'Frequency response of Blackman window') +// >>> plt.ylabel("Magnitude [dB]") +// Text(0, 0.5, 'Magnitude [dB]') +// >>> plt.xlabel("Normalized frequency [cycles per sample]") +// Text(0.5, 0, 'Normalized frequency [cycles per sample]') +// >>> _ = plt.axis('tight') +// >>> plt.show() +// +//go:linkname Blackman py.blackman +func Blackman(M *py.Object) *py.Object + +// Return the Kaiser window. +// +// The Kaiser window is a taper formed by using a Bessel function. +// +// Parameters +// ---------- +// M : int +// +// Number of points in the output window. If zero or less, an +// empty array is returned. +// +// beta : float +// +// Shape parameter for window. +// +// Returns +// ------- +// out : array +// +// The window, with the maximum value normalized to one (the value +// one appears only if the number of samples is odd). +// +// See Also +// -------- +// bartlett, blackman, hamming, hanning +// +// Notes +// ----- +// The Kaiser window is defined as +// +// .. math:: w(n) = I_0\left( \beta \sqrt{1-\frac{4n^2}{(M-1)^2}} +// +// \right)/I_0(\beta) +// +// with +// +// .. math:: \quad -\frac{M-1}{2} \leq n \leq \frac{M-1}{2}, +// +// where :math:`I_0` is the modified zeroth-order Bessel function. +// +// The Kaiser was named for Jim Kaiser, who discovered a simple +// approximation to the DPSS window based on Bessel functions. The Kaiser +// window is a very good approximation to the Digital Prolate Spheroidal +// Sequence, or Slepian window, which is the transform which maximizes the +// energy in the main lobe of the window relative to total energy. +// +// The Kaiser can approximate many other windows by varying the beta +// parameter. +// +// ==== ======================= +// beta Window shape +// ==== ======================= +// 0 Rectangular +// 5 Similar to a Hamming +// 6 Similar to a Hanning +// 8.6 Similar to a Blackman +// ==== ======================= +// +// A beta value of 14 is probably a good starting point. Note that as beta +// gets large, the window narrows, and so the number of samples needs to be +// large enough to sample the increasingly narrow spike, otherwise NaNs will +// get returned. +// +// Most references to the Kaiser window come from the signal processing +// literature, where it is used as one of many windowing functions for +// smoothing values. It is also known as an apodization (which means +// "removing the foot", i.e. smoothing discontinuities at the beginning +// and end of the sampled signal) or tapering function. +// +// References +// ---------- +// .. [1] J. F. Kaiser, "Digital Filters" - Ch 7 in "Systems analysis by +// +// digital computer", Editors: F.F. Kuo and J.F. Kaiser, p 218-285. +// John Wiley and Sons, New York, (1966). +// +// .. [2] E.R. Kanasewich, "Time Sequence Analysis in Geophysics", The +// +// University of Alberta Press, 1975, pp. 177-178. +// +// .. [3] Wikipedia, "Window function", +// +// https://en.wikipedia.org/wiki/Window_function +// +// Examples +// -------- +// >>> import matplotlib.pyplot as plt +// >>> np.kaiser(12, 14) +// +// array([7.72686684e-06, 3.46009194e-03, 4.65200189e-02, # may vary +// 2.29737120e-01, 5.99885316e-01, 9.45674898e-01, +// 9.45674898e-01, 5.99885316e-01, 2.29737120e-01, +// 4.65200189e-02, 3.46009194e-03, 7.72686684e-06]) +// +// Plot the window and the frequency response: +// +// >>> from numpy.fft import fft, fftshift +// >>> window = np.kaiser(51, 14) +// >>> plt.plot(window) +// [] +// >>> plt.title("Kaiser window") +// Text(0.5, 1.0, 'Kaiser window') +// >>> plt.ylabel("Amplitude") +// Text(0, 0.5, 'Amplitude') +// >>> plt.xlabel("Sample") +// Text(0.5, 0, 'Sample') +// >>> plt.show() +// +// >>> plt.figure() +//
+// >>> A = fft(window, 2048) / 25.5 +// >>> mag = np.abs(fftshift(A)) +// >>> freq = np.linspace(-0.5, 0.5, len(A)) +// >>> response = 20 * np.log10(mag) +// >>> response = np.clip(response, -100, 100) +// >>> plt.plot(freq, response) +// [] +// >>> plt.title("Frequency response of Kaiser window") +// Text(0.5, 1.0, 'Frequency response of Kaiser window') +// >>> plt.ylabel("Magnitude [dB]") +// Text(0, 0.5, 'Magnitude [dB]') +// >>> plt.xlabel("Normalized frequency [cycles per sample]") +// Text(0.5, 0, 'Normalized frequency [cycles per sample]') +// >>> plt.axis('tight') +// (-0.5, 0.5, -100.0, ...) # may vary +// >>> plt.show() +// +//go:linkname Kaiser py.kaiser +func Kaiser(M *py.Object, beta *py.Object) *py.Object + +// Add documentation to an existing object, typically one defined in C +// +// The purpose is to allow easier editing of the docstrings without requiring +// a re-compile. This exists primarily for internal use within numpy itself. +// +// Parameters +// ---------- +// place : str +// +// The absolute name of the module to import from +// +// obj : str +// +// The name of the object to add documentation to, typically a class or +// function name +// +// doc : {str, Tuple[str, str], List[Tuple[str, str]]} +// +// If a string, the documentation to apply to `obj` +// +// If a tuple, then the first element is interpreted as an attribute of +// `obj` and the second as the docstring to apply - ``(method, docstring)`` +// +// If a list, then each element of the list should be a tuple of length +// two - ``[(method1, docstring1), (method2, docstring2), ...]`` +// +// warn_on_python : bool +// +// If True, the default, emit `UserWarning` if this is used to attach +// documentation to a pure-python object. +// +// Notes +// ----- +// This routine never raises an error if the docstring can't be written, but +// will raise an error if the object being documented does not exist. +// +// This routine cannot modify read-only docstrings, as appear +// in new-style classes or built-in functions. Because this +// routine never raises an error the caller must check manually +// that the docstrings were changed. +// +// Since this function grabs the “char *“ from a c-level str object and puts +// it into the “tp_doc“ slot of the type of `obj`, it violates a number of +// C-API best-practices, by: +// +// - modifying a `PyTypeObject` after calling `PyType_Ready` +// - calling `Py_INCREF` on the str and losing the reference, so the str +// will never be released +// +// If possible it should be avoided. +// +//go:linkname AddNewdoc py.add_newdoc +func AddNewdoc(place *py.Object, obj *py.Object, doc *py.Object, warnOnPython *py.Object) *py.Object + +// Find the wrapper for the array with the highest priority. +// +// In case of ties, leftmost wins. If no wrapper is found, return None +// +//go:linkname GetArrayWrap py.get_array_wrap +func GetArrayWrap(__llgo_va_list ...interface{}) *py.Object + +// Broadcast the input shapes into a single shape. +// +// :ref:`Learn more about broadcasting here `. +// +// .. versionadded:: 1.20.0 +// +// Parameters +// ---------- +// `*args` : tuples of ints, or ints +// +// The shapes to be broadcast against each other. +// +// Returns +// ------- +// tuple +// +// Broadcasted shape. +// +// Raises +// ------ +// ValueError +// +// If the shapes are not compatible and cannot be broadcast according +// to NumPy's broadcasting rules. +// +// See Also +// -------- +// broadcast +// broadcast_arrays +// broadcast_to +// +// Examples +// -------- +// >>> np.broadcast_shapes((1, 2), (3, 1), (3, 2)) +// (3, 2) +// +// >>> np.broadcast_shapes((6, 7), (5, 6, 1), (7,), (5, 1, 7)) +// (5, 6, 7) +// +//go:linkname BroadcastShapes py.broadcast_shapes +func BroadcastShapes(__llgo_va_list ...interface{}) *py.Object + +// Return the indices to access (n, n) arrays, given a masking function. +// +// Assume `mask_func` is a function that, for a square array a of size +// “(n, n)“ with a possible offset argument `k`, when called as +// “mask_func(a, k)“ returns a new array with zeros in certain locations +// (functions like `triu` or `tril` do precisely this). Then this function +// returns the indices where the non-zero values would be located. +// +// Parameters +// ---------- +// n : int +// +// The returned indices will be valid to access arrays of shape (n, n). +// +// mask_func : callable +// +// A function whose call signature is similar to that of `triu`, `tril`. +// That is, ``mask_func(x, k)`` returns a boolean array, shaped like `x`. +// `k` is an optional argument to the function. +// +// k : scalar +// +// An optional argument which is passed through to `mask_func`. Functions +// like `triu`, `tril` take a second argument that is interpreted as an +// offset. +// +// Returns +// ------- +// indices : tuple of arrays. +// +// The `n` arrays of indices corresponding to the locations where +// ``mask_func(np.ones((n, n)), k)`` is True. +// +// See Also +// -------- +// triu, tril, triu_indices, tril_indices +// +// Notes +// ----- +// .. versionadded:: 1.4.0 +// +// Examples +// -------- +// These are the indices that would allow you to access the upper triangular +// part of any 3x3 array: +// +// >>> iu = np.mask_indices(3, np.triu) +// +// For example, if `a` is a 3x3 array: +// +// >>> a = np.arange(9).reshape(3, 3) +// >>> a +// array([[0, 1, 2], +// +// [3, 4, 5], +// [6, 7, 8]]) +// +// >>> a[iu] +// array([0, 1, 2, 4, 5, 8]) +// +// An offset can be passed also to the masking function. This gets us the +// indices starting on the first diagonal right of the main one: +// +// >>> iu1 = np.mask_indices(3, np.triu, 1) +// +// with which we now extract only three elements: +// +// >>> a[iu1] +// array([1, 2, 5]) +// +//go:linkname MaskIndices py.mask_indices +func MaskIndices(n *py.Object, maskFunc *py.Object, k *py.Object) *py.Object + +// Return the indices for the lower-triangle of an (n, m) array. +// +// Parameters +// ---------- +// n : int +// +// The row dimension of the arrays for which the returned +// indices will be valid. +// +// k : int, optional +// +// Diagonal offset (see `tril` for details). +// +// m : int, optional +// +// .. versionadded:: 1.9.0 +// +// The column dimension of the arrays for which the returned +// arrays will be valid. +// By default `m` is taken equal to `n`. +// +// Returns +// ------- +// inds : tuple of arrays +// +// The indices for the triangle. The returned tuple contains two arrays, +// each with the indices along one dimension of the array. +// +// See also +// -------- +// triu_indices : similar function, for upper-triangular. +// mask_indices : generic function accepting an arbitrary mask function. +// tril, triu +// +// Notes +// ----- +// .. versionadded:: 1.4.0 +// +// Examples +// -------- +// Compute two different sets of indices to access 4x4 arrays, one for the +// lower triangular part starting at the main diagonal, and one starting two +// diagonals further right: +// +// >>> il1 = np.tril_indices(4) +// >>> il2 = np.tril_indices(4, 2) +// +// Here is how they can be used with a sample array: +// +// >>> a = np.arange(16).reshape(4, 4) +// >>> a +// array([[ 0, 1, 2, 3], +// +// [ 4, 5, 6, 7], +// [ 8, 9, 10, 11], +// [12, 13, 14, 15]]) +// +// Both for indexing: +// +// >>> a[il1] +// array([ 0, 4, 5, ..., 13, 14, 15]) +// +// And for assigning values: +// +// >>> a[il1] = -1 +// >>> a +// array([[-1, 1, 2, 3], +// +// [-1, -1, 6, 7], +// [-1, -1, -1, 11], +// [-1, -1, -1, -1]]) +// +// These cover almost the whole array (two diagonals right of the main one): +// +// >>> a[il2] = -10 +// >>> a +// array([[-10, -10, -10, 3], +// +// [-10, -10, -10, -10], +// [-10, -10, -10, -10], +// [-10, -10, -10, -10]]) +// +//go:linkname TrilIndices py.tril_indices +func TrilIndices(n *py.Object, k *py.Object, m *py.Object) *py.Object + +// Return the indices for the upper-triangle of an (n, m) array. +// +// Parameters +// ---------- +// n : int +// +// The size of the arrays for which the returned indices will +// be valid. +// +// k : int, optional +// +// Diagonal offset (see `triu` for details). +// +// m : int, optional +// +// .. versionadded:: 1.9.0 +// +// The column dimension of the arrays for which the returned +// arrays will be valid. +// By default `m` is taken equal to `n`. +// +// Returns +// ------- +// inds : tuple, shape(2) of ndarrays, shape(`n`) +// +// The indices for the triangle. The returned tuple contains two arrays, +// each with the indices along one dimension of the array. Can be used +// to slice a ndarray of shape(`n`, `n`). +// +// See also +// -------- +// tril_indices : similar function, for lower-triangular. +// mask_indices : generic function accepting an arbitrary mask function. +// triu, tril +// +// Notes +// ----- +// .. versionadded:: 1.4.0 +// +// Examples +// -------- +// Compute two different sets of indices to access 4x4 arrays, one for the +// upper triangular part starting at the main diagonal, and one starting two +// diagonals further right: +// +// >>> iu1 = np.triu_indices(4) +// >>> iu2 = np.triu_indices(4, 2) +// +// Here is how they can be used with a sample array: +// +// >>> a = np.arange(16).reshape(4, 4) +// >>> a +// array([[ 0, 1, 2, 3], +// +// [ 4, 5, 6, 7], +// [ 8, 9, 10, 11], +// [12, 13, 14, 15]]) +// +// Both for indexing: +// +// >>> a[iu1] +// array([ 0, 1, 2, ..., 10, 11, 15]) +// +// And for assigning values: +// +// >>> a[iu1] = -1 +// >>> a +// array([[-1, -1, -1, -1], +// +// [ 4, -1, -1, -1], +// [ 8, 9, -1, -1], +// [12, 13, 14, -1]]) +// +// These cover only a small part of the whole array (two diagonals right +// of the main one): +// +// >>> a[iu2] = -10 +// >>> a +// array([[ -1, -1, -10, -10], +// +// [ 4, -1, -1, -10], +// [ 8, 9, -1, -1], +// [ 12, 13, 14, -1]]) +// +//go:linkname TriuIndices py.triu_indices +func TriuIndices(n *py.Object, k *py.Object, m *py.Object) *py.Object + +// Determine if a class is a subclass of a second class. +// +// `issubclass_` is equivalent to the Python built-in “issubclass“, +// except that it returns False instead of raising a TypeError if one +// of the arguments is not a class. +// +// Parameters +// ---------- +// arg1 : class +// +// Input class. True is returned if `arg1` is a subclass of `arg2`. +// +// arg2 : class or tuple of classes. +// +// Input class. If a tuple of classes, True is returned if `arg1` is a +// subclass of any of the tuple elements. +// +// Returns +// ------- +// out : bool +// +// Whether `arg1` is a subclass of `arg2` or not. +// +// See Also +// -------- +// issubsctype, issubdtype, issctype +// +// Examples +// -------- +// >>> np.issubclass_(np.int32, int) +// False +// >>> np.issubclass_(np.int32, float) +// False +// >>> np.issubclass_(np.float64, float) +// True +// +//go:linkname Issubclass py.issubclass_ +func Issubclass(arg1 *py.Object, arg2 *py.Object) *py.Object + +// Determine if the first argument is a subclass of the second argument. +// +// Parameters +// ---------- +// arg1, arg2 : dtype or dtype specifier +// +// Data-types. +// +// Returns +// ------- +// out : bool +// +// The result. +// +// See Also +// -------- +// issctype, issubdtype, obj2sctype +// +// Examples +// -------- +// >>> np.issubsctype('S8', str) +// False +// >>> np.issubsctype(np.array([1]), int) +// True +// >>> np.issubsctype(np.array([1]), float) +// False +// +//go:linkname Issubsctype py.issubsctype +func Issubsctype(arg1 *py.Object, arg2 *py.Object) *py.Object + +// Issues a DeprecationWarning, adds warning to `old_name`'s +// docstring, rebinds “old_name.__name__“ and returns the new +// function object. +// +// This function may also be used as a decorator. +// +// Parameters +// ---------- +// func : function +// +// The function to be deprecated. +// +// old_name : str, optional +// +// The name of the function to be deprecated. Default is None, in +// which case the name of `func` is used. +// +// new_name : str, optional +// +// The new name for the function. Default is None, in which case the +// deprecation message is that `old_name` is deprecated. If given, the +// deprecation message is that `old_name` is deprecated and `new_name` +// should be used instead. +// +// message : str, optional +// +// Additional explanation of the deprecation. Displayed in the +// docstring after the warning. +// +// Returns +// ------- +// old_func : function +// +// The deprecated function. +// +// Examples +// -------- +// Note that “olduint“ returns a value after printing Deprecation +// Warning: +// +// >>> olduint = np.deprecate(np.uint) +// DeprecationWarning: `uint64` is deprecated! # may vary +// >>> olduint(6) +// 6 +// +//go:linkname Deprecate py.deprecate +func Deprecate(__llgo_va_list ...interface{}) *py.Object + +// Deprecates a function and includes the deprecation in its docstring. +// +// This function is used as a decorator. It returns an object that can be +// used to issue a DeprecationWarning, by passing the to-be decorated +// function as argument, this adds warning to the to-be decorated function's +// docstring and returns the new function object. +// +// See Also +// -------- +// deprecate : Decorate a function such that it issues a `DeprecationWarning` +// +// Parameters +// ---------- +// msg : str +// +// Additional explanation of the deprecation. Displayed in the +// docstring after the warning. +// +// Returns +// ------- +// obj : object +// +//go:linkname DeprecateWithDoc py.deprecate_with_doc +func DeprecateWithDoc(msg *py.Object) *py.Object + +// Return the directory that contains the NumPy \*.h header files. +// +// Extension modules that need to compile against NumPy should use this +// function to locate the appropriate include directory. +// +// Notes +// ----- +// When using “distutils“, for example in “setup.py“:: +// +// import numpy as np +// ... +// Extension('extension_name', ... +// include_dirs=[np.get_include()]) +// ... +// +//go:linkname GetInclude py.get_include +func GetInclude() *py.Object + +// Get help information for an array, function, class, or module. +// +// Parameters +// ---------- +// object : object or str, optional +// +// Input object or name to get information about. If `object` is +// an `ndarray` instance, information about the array is printed. +// If `object` is a numpy object, its docstring is given. If it is +// a string, available modules are searched for matching objects. +// If None, information about `info` itself is returned. +// +// maxwidth : int, optional +// +// Printing width. +// +// output : file like object, optional +// +// File like object that the output is written to, default is +// ``None``, in which case ``sys.stdout`` will be used. +// The object has to be opened in 'w' or 'a' mode. +// +// toplevel : str, optional +// +// Start search at this level. +// +// See Also +// -------- +// source, lookfor +// +// Notes +// ----- +// When used interactively with an object, “np.info(obj)“ is equivalent +// to “help(obj)“ on the Python prompt or “obj?“ on the IPython +// prompt. +// +// Examples +// -------- +// >>> np.info(np.polyval) # doctest: +SKIP +// +// polyval(p, x) +// Evaluate the polynomial p at x. +// ... +// +// When using a string for `object` it is possible to get multiple results. +// +// >>> np.info('fft') # doctest: +SKIP +// +// *** Found in numpy *** +// +// Core FFT routines +// ... +// +// *** Found in numpy.fft *** +// fft(a, n=None, axis=-1) +// +// ... +// +// *** Repeat reference found in numpy.fft.fftpack *** +// *** Total of 3 references found. *** +// +// When the argument is an array, information about the array is printed. +// +// >>> a = np.array([[1 + 2j, 3, -4], [-5j, 6, 0]], dtype=np.complex64) +// >>> np.info(a) +// class: ndarray +// shape: (2, 3) +// strides: (24, 8) +// itemsize: 8 +// aligned: True +// contiguous: True +// fortran: False +// data pointer: 0x562b6e0d2860 # may vary +// byteorder: little +// byteswap: False +// type: complex64 +// +//go:linkname Info py.info +func Info(object *py.Object, maxwidth *py.Object, output *py.Object, toplevel *py.Object) *py.Object + +// Print the NumPy arrays in the given dictionary. +// +// If there is no dictionary passed in or `vardict` is None then returns +// NumPy arrays in the globals() dictionary (all NumPy arrays in the +// namespace). +// +// Parameters +// ---------- +// vardict : dict, optional +// +// A dictionary possibly containing ndarrays. Default is globals(). +// +// Returns +// ------- +// out : None +// +// Returns 'None'. +// +// Notes +// ----- +// Prints out the name, shape, bytes and type of all of the ndarrays +// present in `vardict`. +// +// Examples +// -------- +// >>> a = np.arange(10) +// >>> b = np.ones(20) +// >>> np.who() +// Name Shape Bytes Type +// =========================================================== +// a 10 80 int64 +// b 20 160 float64 +// Upper bound on total bytes = 240 +// +// >>> d = {'x': np.arange(2.0), 'y': np.arange(3.0), 'txt': 'Some str', +// ... 'idx':5} +// >>> np.who(d) +// Name Shape Bytes Type +// =========================================================== +// x 2 16 float64 +// y 3 24 float64 +// Upper bound on total bytes = 40 +// +//go:linkname Who py.who +func Who(vardict *py.Object) *py.Object + +// Do a keyword search on docstrings. +// +// A list of objects that matched the search is displayed, +// sorted by relevance. All given keywords need to be found in the +// docstring for it to be returned as a result, but the order does +// not matter. +// +// Parameters +// ---------- +// what : str +// +// String containing words to look for. +// +// module : str or list, optional +// +// Name of module(s) whose docstrings to go through. +// +// import_modules : bool, optional +// +// Whether to import sub-modules in packages. Default is True. +// +// regenerate : bool, optional +// +// Whether to re-generate the docstring cache. Default is False. +// +// output : file-like, optional +// +// File-like object to write the output to. If omitted, use a pager. +// +// See Also +// -------- +// source, info +// +// Notes +// ----- +// Relevance is determined only roughly, by checking if the keywords occur +// in the function name, at the start of a docstring, etc. +// +// Examples +// -------- +// >>> np.lookfor('binary representation') # doctest: +SKIP +// Search results for 'binary representation' +// ------------------------------------------ +// numpy.binary_repr +// +// Return the binary representation of the input number as a string. +// +// numpy.core.setup_common.long_double_representation +// +// Given a binary dump as given by GNU od -b, look for long double +// +// numpy.base_repr +// +// Return a string representation of a number in the given base system. +// +// ... +// +//go:linkname Lookfor py.lookfor +func Lookfor(what *py.Object, module *py.Object, importModules *py.Object, regenerate *py.Object, output *py.Object) *py.Object + +// Returns pointers to the end-points of an array. +// +// Parameters +// ---------- +// a : ndarray +// +// Input array. It must conform to the Python-side of the array +// interface. +// +// Returns +// ------- +// (low, high) : tuple of 2 integers +// +// The first integer is the first byte of the array, the second +// integer is just past the last byte of the array. If `a` is not +// contiguous it will not use every byte between the (`low`, `high`) +// values. +// +// Examples +// -------- +// >>> I = np.eye(2, dtype='f'); I.dtype +// dtype('float32') +// >>> low, high = np.byte_bounds(I) +// >>> high - low == I.size*I.itemsize +// True +// >>> I = np.eye(2); I.dtype +// dtype('float64') +// >>> low, high = np.byte_bounds(I) +// >>> high - low == I.size*I.itemsize +// True +// +//go:linkname ByteBounds py.byte_bounds +func ByteBounds(a *py.Object) *py.Object + +// Protected string evaluation. +// +// Evaluate a string containing a Python literal expression without +// allowing the execution of arbitrary non-literal code. +// +// .. warning:: +// +// This function is identical to :py:meth:`ast.literal_eval` and +// has the same security implications. It may not always be safe +// to evaluate large input strings. +// +// Parameters +// ---------- +// source : str +// +// The string to evaluate. +// +// Returns +// ------- +// obj : object +// +// The result of evaluating `source`. +// +// Raises +// ------ +// SyntaxError +// +// If the code has invalid Python syntax, or if it contains +// non-literal code. +// +// Examples +// -------- +// >>> np.safe_eval('1') +// 1 +// >>> np.safe_eval('[1, 2, 3]') +// [1, 2, 3] +// >>> np.safe_eval('{"foo": ("bar", 10.0)}') +// {'foo': ('bar', 10.0)} +// +// >>> np.safe_eval('import os') +// Traceback (most recent call last): +// +// ... +// +// SyntaxError: invalid syntax +// +// >>> np.safe_eval('open("/home/user/.ssh/id_dsa").read()') +// Traceback (most recent call last): +// +// ... +// +// ValueError: malformed node or string: <_ast.Call object at 0x...> +// +//go:linkname SafeEval py.safe_eval +func SafeEval(source *py.Object) *py.Object + +// Print information about various resources in the system +// including available intrinsic support and BLAS/LAPACK library +// in use +// +// .. versionadded:: 1.24.0 +// +// See Also +// -------- +// show_config : Show libraries in the system on which NumPy was built. +// +// Notes +// ----- +// 1. Information is derived with the help of `threadpoolctl `_ +// library if available. +// 2. SIMD related information is derived from “__cpu_features__“, +// “__cpu_baseline__“ and “__cpu_dispatch__“ +// +//go:linkname ShowRuntime py.show_runtime +func ShowRuntime() *py.Object + +// Load ASCII data from a file and return it in a record array. +// +// If “usemask=False“ a standard `recarray` is returned, +// if “usemask=True“ a MaskedRecords array is returned. +// +// Parameters +// ---------- +// fname, kwargs : For a description of input parameters, see `genfromtxt`. +// +// See Also +// -------- +// numpy.genfromtxt : generic function +// +// Notes +// ----- +// By default, `dtype` is None, which means that the data-type of the output +// array will be determined from the data. +// +//go:linkname Recfromtxt py.recfromtxt +func Recfromtxt(fname *py.Object) *py.Object + +// Load ASCII data stored in a comma-separated file. +// +// The returned array is a record array (if “usemask=False“, see +// `recarray`) or a masked record array (if “usemask=True“, +// see `ma.mrecords.MaskedRecords`). +// +// Parameters +// ---------- +// fname, kwargs : For a description of input parameters, see `genfromtxt`. +// +// See Also +// -------- +// numpy.genfromtxt : generic function to load ASCII data. +// +// Notes +// ----- +// By default, `dtype` is None, which means that the data-type of the output +// array will be determined from the data. +// +//go:linkname Recfromcsv py.recfromcsv +func Recfromcsv(fname *py.Object) *py.Object + +// Load arrays or pickled objects from “.npy“, “.npz“ or pickled files. +// +// .. warning:: Loading files that contain object arrays uses the “pickle“ +// +// module, which is not secure against erroneous or maliciously +// constructed data. Consider passing ``allow_pickle=False`` to +// load data that is known not to contain object arrays for the +// safer handling of untrusted sources. +// +// Parameters +// ---------- +// file : file-like object, string, or pathlib.Path +// +// The file to read. File-like objects must support the +// ``seek()`` and ``read()`` methods and must always +// be opened in binary mode. Pickled files require that the +// file-like object support the ``readline()`` method as well. +// +// mmap_mode : {None, 'r+', 'r', 'w+', 'c'}, optional +// +// If not None, then memory-map the file, using the given mode (see +// `numpy.memmap` for a detailed description of the modes). A +// memory-mapped array is kept on disk. However, it can be accessed +// and sliced like any ndarray. Memory mapping is especially useful +// for accessing small fragments of large files without reading the +// entire file into memory. +// +// allow_pickle : bool, optional +// +// Allow loading pickled object arrays stored in npy files. Reasons for +// disallowing pickles include security, as loading pickled data can +// execute arbitrary code. If pickles are disallowed, loading object +// arrays will fail. Default: False +// +// .. versionchanged:: 1.16.3 +// Made default False in response to CVE-2019-6446. +// +// fix_imports : bool, optional +// +// Only useful when loading Python 2 generated pickled files on Python 3, +// which includes npy/npz files containing object arrays. If `fix_imports` +// is True, pickle will try to map the old Python 2 names to the new names +// used in Python 3. +// +// encoding : str, optional +// +// What encoding to use when reading Python 2 strings. Only useful when +// loading Python 2 generated pickled files in Python 3, which includes +// npy/npz files containing object arrays. Values other than 'latin1', +// 'ASCII', and 'bytes' are not allowed, as they can corrupt numerical +// data. Default: 'ASCII' +// +// max_header_size : int, optional +// +// Maximum allowed size of the header. Large headers may not be safe +// to load securely and thus require explicitly passing a larger value. +// See :py:func:`ast.literal_eval()` for details. +// This option is ignored when `allow_pickle` is passed. In that case +// the file is by definition trusted and the limit is unnecessary. +// +// Returns +// ------- +// result : array, tuple, dict, etc. +// +// Data stored in the file. For ``.npz`` files, the returned instance +// of NpzFile class must be closed to avoid leaking file descriptors. +// +// Raises +// ------ +// OSError +// +// If the input file does not exist or cannot be read. +// +// UnpicklingError +// +// If ``allow_pickle=True``, but the file cannot be loaded as a pickle. +// +// ValueError +// +// The file contains an object array, but ``allow_pickle=False`` given. +// +// EOFError +// +// When calling ``np.load`` multiple times on the same file handle, +// if all data has already been read +// +// See Also +// -------- +// save, savez, savez_compressed, loadtxt +// memmap : Create a memory-map to an array stored in a file on disk. +// lib.format.open_memmap : Create or load a memory-mapped “.npy“ file. +// +// Notes +// ----- +// +// - If the file contains pickle data, then whatever object is stored +// in the pickle is returned. +// +// - If the file is a “.npy“ file, then a single array is returned. +// +// - If the file is a “.npz“ file, then a dictionary-like object is +// returned, containing “{filename: array}“ key-value pairs, one for +// each file in the archive. +// +// - If the file is a “.npz“ file, the returned value supports the +// context manager protocol in a similar fashion to the open function:: +// +// with load('foo.npz') as data: +// a = data['a'] +// +// The underlying file descriptor is closed when exiting the 'with' +// block. +// +// Examples +// -------- +// Store data to disk, and load it again: +// +// >>> np.save('/tmp/123', np.array([[1, 2, 3], [4, 5, 6]])) +// >>> np.load('/tmp/123.npy') +// array([[1, 2, 3], +// +// [4, 5, 6]]) +// +// Store compressed data to disk, and load it again: +// +// >>> a=np.array([[1, 2, 3], [4, 5, 6]]) +// >>> b=np.array([1, 2]) +// >>> np.savez('/tmp/123.npz', a=a, b=b) +// >>> data = np.load('/tmp/123.npz') +// >>> data['a'] +// array([[1, 2, 3], +// +// [4, 5, 6]]) +// +// >>> data['b'] +// array([1, 2]) +// >>> data.close() +// +// Mem-map the stored array, and then access the second row +// directly from disk: +// +// >>> X = np.load('/tmp/123.npy', mmap_mode='r') +// >>> X[1, :] +// memmap([4, 5, 6]) +// +//go:linkname Load py.load +func Load(file *py.Object, mmapMode *py.Object, allowPickle *py.Object, fixImports *py.Object, encoding *py.Object) *py.Object + +// Construct an array from a text file, using regular expression parsing. +// +// The returned array is always a structured array, and is constructed from +// all matches of the regular expression in the file. Groups in the regular +// expression are converted to fields of the structured array. +// +// Parameters +// ---------- +// file : path or file +// +// Filename or file object to read. +// +// .. versionchanged:: 1.22.0 +// Now accepts `os.PathLike` implementations. +// +// regexp : str or regexp +// +// Regular expression used to parse the file. +// Groups in the regular expression correspond to fields in the dtype. +// +// dtype : dtype or list of dtypes +// +// Dtype for the structured array; must be a structured datatype. +// +// encoding : str, optional +// +// Encoding used to decode the inputfile. Does not apply to input streams. +// +// .. versionadded:: 1.14.0 +// +// Returns +// ------- +// output : ndarray +// +// The output array, containing the part of the content of `file` that +// was matched by `regexp`. `output` is always a structured array. +// +// Raises +// ------ +// TypeError +// +// When `dtype` is not a valid dtype for a structured array. +// +// See Also +// -------- +// fromstring, loadtxt +// +// Notes +// ----- +// Dtypes for structured arrays can be specified in several forms, but all +// forms specify at least the data type and field name. For details see +// `basics.rec`. +// +// Examples +// -------- +// >>> from io import StringIO +// >>> text = StringIO("1312 foo\n1534 bar\n444 qux") +// +// >>> regexp = r"(\d+)\s+(...)" # match [digits, whitespace, anything] +// >>> output = np.fromregex(text, regexp, +// ... [('num', np.int64), ('key', 'S3')]) +// >>> output +// array([(1312, b'foo'), (1534, b'bar'), ( 444, b'qux')], +// +// dtype=[('num', '>> output['num'] +// array([1312, 1534, 444]) +// +//go:linkname Fromregex py.fromregex +func Fromregex(file *py.Object, regexp *py.Object, dtype *py.Object, encoding *py.Object) *py.Object + +// Build a matrix object from a string, nested sequence, or array. +// +// Parameters +// ---------- +// obj : str or array_like +// +// Input data. If a string, variables in the current scope may be +// referenced by name. +// +// ldict : dict, optional +// +// A dictionary that replaces local operands in current frame. +// Ignored if `obj` is not a string or `gdict` is None. +// +// gdict : dict, optional +// +// A dictionary that replaces global operands in current frame. +// Ignored if `obj` is not a string. +// +// Returns +// ------- +// out : matrix +// +// Returns a matrix object, which is a specialized 2-D array. +// +// See Also +// -------- +// block : +// +// A generalization of this function for N-d arrays, that returns normal +// ndarrays. +// +// Examples +// -------- +// >>> A = np.mat('1 1; 1 1') +// >>> B = np.mat('2 2; 2 2') +// >>> C = np.mat('3 4; 5 6') +// >>> D = np.mat('7 8; 9 0') +// +// All the following expressions construct the same block matrix: +// +// >>> np.bmat([[A, B], [C, D]]) +// matrix([[1, 1, 2, 2], +// +// [1, 1, 2, 2], +// [3, 4, 7, 8], +// [5, 6, 9, 0]]) +// +// >>> np.bmat(np.r_[np.c_[A, B], np.c_[C, D]]) +// matrix([[1, 1, 2, 2], +// +// [1, 1, 2, 2], +// [3, 4, 7, 8], +// [5, 6, 9, 0]]) +// +// >>> np.bmat('A,B; C,D') +// matrix([[1, 1, 2, 2], +// +// [1, 1, 2, 2], +// [3, 4, 7, 8], +// [5, 6, 9, 0]]) +// +//go:linkname Bmat py.bmat +func Bmat(obj *py.Object, ldict *py.Object, gdict *py.Object) *py.Object + +// Interpret the input as a matrix. +// +// Unlike `matrix`, `asmatrix` does not make a copy if the input is already +// a matrix or an ndarray. Equivalent to “matrix(data, copy=False)“. +// +// Parameters +// ---------- +// data : array_like +// +// Input data. +// +// dtype : data-type +// +// Data-type of the output matrix. +// +// Returns +// ------- +// mat : matrix +// +// `data` interpreted as a matrix. +// +// Examples +// -------- +// >>> x = np.array([[1, 2], [3, 4]]) +// +// >>> m = np.asmatrix(x) +// +// >>> x[0,0] = 5 +// +// >>> m +// matrix([[5, 2], +// +// [3, 4]]) +// +//go:linkname Mat py.mat +func Mat(data *py.Object, dtype *py.Object) *py.Object + +// Interpret the input as a matrix. +// +// Unlike `matrix`, `asmatrix` does not make a copy if the input is already +// a matrix or an ndarray. Equivalent to “matrix(data, copy=False)“. +// +// Parameters +// ---------- +// data : array_like +// +// Input data. +// +// dtype : data-type +// +// Data-type of the output matrix. +// +// Returns +// ------- +// mat : matrix +// +// `data` interpreted as a matrix. +// +// Examples +// -------- +// >>> x = np.array([[1, 2], [3, 4]]) +// +// >>> m = np.asmatrix(x) +// +// >>> x[0,0] = 5 +// +// >>> m +// matrix([[5, 2], +// +// [3, 4]]) +// +//go:linkname Asmatrix py.asmatrix +func Asmatrix(data *py.Object, dtype *py.Object) *py.Object + +// absolute(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature, extobj]) +// +// Calculate the absolute value element-wise. +// +// “np.abs“ is a shorthand for this function. +// +// Parameters +// ---------- +// x : array_like +// +// Input array. +// +// out : ndarray, None, or tuple of ndarray and None, optional +// +// A location into which the result is stored. If provided, it must have +// a shape that the inputs broadcast to. If not provided or None, +// a freshly-allocated array is returned. A tuple (possible only as a +// keyword argument) must have length equal to the number of outputs. +// +// where : array_like, optional +// +// This condition is broadcast over the input. At locations where the +// condition is True, the `out` array will be set to the ufunc result. +// Elsewhere, the `out` array will retain its original value. +// Note that if an uninitialized `out` array is created via the default +// ``out=None``, locations within it where the condition is False will +// remain uninitialized. +// +// **kwargs +// +// For other keyword-only arguments, see the +// :ref:`ufunc docs `. +// +// Returns +// ------- +// absolute : ndarray +// +// An ndarray containing the absolute value of +// each element in `x`. For complex input, ``a + ib``, the +// absolute value is :math:`\sqrt{ a^2 + b^2 }`. +// This is a scalar if `x` is a scalar. +// +// Examples +// -------- +// >>> x = np.array([-1.2, 1.2]) +// >>> np.absolute(x) +// array([ 1.2, 1.2]) +// >>> np.absolute(1.2 + 1j) +// 1.5620499351813308 +// +// Plot the function over “[-10, 10]“: +// +// >>> import matplotlib.pyplot as plt +// +// >>> x = np.linspace(start=-10, stop=10, num=101) +// >>> plt.plot(x, np.absolute(x)) +// >>> plt.show() +// +// Plot the function over the complex plane: +// +// >>> xx = x + 1j * x[:, np.newaxis] +// >>> plt.imshow(np.abs(xx), extent=[-10, 10, -10, 10], cmap='gray') +// >>> plt.show() +// +// The `abs` function can be used as a shorthand for “np.absolute“ on +// ndarrays. +// +// >>> x = np.array([-1.2, 1.2]) +// >>> abs(x) +// array([1.2, 1.2]) +// +//go:linkname Abs py.abs +func Abs(__llgo_va_list ...interface{}) *py.Object diff --git a/py/numpy/llgo_autogen.lla b/py/numpy/llgo_autogen.lla new file mode 100644 index 00000000..5333011b Binary files /dev/null and b/py/numpy/llgo_autogen.lla differ diff --git a/py/numpy/numpy.go b/py/numpy/numpy.go new file mode 100644 index 00000000..80c2528c --- /dev/null +++ b/py/numpy/numpy.go @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * 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 numpy + +import ( + _ "unsafe" + + "github.com/goplus/llgo/py" +) + +// https://numpy.org/doc/stable/reference/index.html#reference + +// Return evenly spaced values within a given interval. +// +// numpy.arange([start, ]stop, [step, ]dtype=None, *, like=None) +// +// See https://numpy.org/doc/stable/reference/generated/numpy.arange.html#numpy-arange +// +//go:linkname Arange py.arange +func Arange(start, stop, step, dtype *py.Object) *py.Object + +// Return a new array of given shape and type, without initializing entries. +// +// numpy.empty(shape, dtype=float, order='C', *, like=None) +// +// See https://numpy.org/doc/stable/reference/generated/numpy.empty.html#numpy-empty +// +//go:linkname Empty py.empty +func Empty(shape, dtype, order *py.Object) *py.Object + +// Return a 2-D array with ones on the diagonal and zeros elsewhere. +// +// numpy.eye(N, M=None, k=0, dtype=, order='C', *, like=None) +// +// See https://numpy.org/doc/stable/reference/generated/numpy.eye.html#numpy-eye +// +//go:linkname Eye py.eye +func Eye(N, M, k, dtype, order *py.Object) *py.Object + +// Return a new array of given shape and type, filled with zeros. +// +// numpy.zeros(shape, dtype=float, order='C', *, like=None) +// +// See https://numpy.org/doc/stable/reference/generated/numpy.zeros.html#numpy-zeros +// +//go:linkname Zeros py.zeros +func Zeros(shape, dtype, order *py.Object) *py.Object + +// Create an array. +// +// numpy.array(object, dtype=None, *, copy=True, order='K', subok=False, ndmin=0, like=None) +// +// See https://numpy.org/doc/stable/reference/generated/numpy.array.html#numpy-array +// +//go:linkname Array py.array +func Array(object, dtype *py.Object) *py.Object + +// Convert the input to an array. +// +// numpy.asarray(a, dtype=None, order=None, *, like=None) +// +// See https://numpy.org/doc/stable/reference/generated/numpy.asarray.html#numpy-asarray +// +//go:linkname AsArray py.asarray +func AsArray(a, dtype, order *py.Object) *py.Object diff --git a/py/object.go b/py/object.go index bfa1e04b..56309d72 100644 --- a/py/object.go +++ b/py/object.go @@ -22,6 +22,8 @@ import ( "github.com/goplus/llgo/c" ) +// https://docs.python.org/3/c-api/object.html + // Object represents a Python object. type Object struct { Unused [8]byte @@ -30,6 +32,9 @@ type Object struct { // llgo:link (*Object).DecRef C.Py_DecRef func (o *Object) DecRef() {} +// llgo:link (*Object).Type C.PyObject_Type +func (o *Object) Type() *Object { return nil } + // Compute a string representation of object o. Returns the string representation on // success, nil on failure. This is the equivalent of the Python expression str(o). // Called by the str() built-in function and, therefore, by the print() function. @@ -37,6 +42,18 @@ func (o *Object) DecRef() {} // llgo:link (*Object).Str C.PyObject_Str func (o *Object) Str() *Object { return nil } +// Returns 1 if the object o is considered to be true, and 0 otherwise. This is equivalent +// to the Python expression not not o. On failure, return -1. +// +// llgo:link (*Object).IsTrue C.PyObject_IsTrue +func (o *Object) IsTrue() c.Int { return -1 } + +// Returns 0 if the object o is considered to be true, and 1 otherwise. This is equivalent +// to the Python expression not o. On failure, return -1. +// +// llgo:link (*Object).NotTrue C.PyObject_Not +func (o *Object) NotTrue() c.Int { return -1 } + // ----------------------------------------------------------------------------- // Retrieve an attribute named attrName from object o. Returns the attribute value on success, diff --git a/py/os/gen.go b/py/os/gen.go new file mode 100644 index 00000000..8e3f3b68 --- /dev/null +++ b/py/os/gen.go @@ -0,0 +1,1429 @@ +package os + +import ( + _ "unsafe" + + "github.com/goplus/llgo/py" +) + +const LLGoPackage = "py.os" + +// Perform a stat system call on the given path. +// +// path +// Path to be examined; can be string, bytes, a path-like object or +// open-file-descriptor int. +// dir_fd +// If not None, it should be a file descriptor open to a directory, +// and path should be a relative string; path will then be relative to +// that directory. +// follow_symlinks +// If False, and the last element of the path is a symbolic link, +// stat will examine the symbolic link itself instead of the file +// the link points to. +// +// dir_fd and follow_symlinks may not be implemented +// +// on your platform. If they are unavailable, using them will raise a +// NotImplementedError. +// +// It's an error to use dir_fd or follow_symlinks when specifying path as +// +// an open file descriptor. +// +//go:linkname Stat py.stat +func Stat(path *py.Object) *py.Object + +// Use the real uid/gid to test for access to a path. +// +// path +// Path to be tested; can be string, bytes, or a path-like object. +// mode +// Operating-system mode bitfield. Can be F_OK to test existence, +// or the inclusive-OR of R_OK, W_OK, and X_OK. +// dir_fd +// If not None, it should be a file descriptor open to a directory, +// and path should be relative; path will then be relative to that +// directory. +// effective_ids +// If True, access will use the effective uid/gid instead of +// the real uid/gid. +// follow_symlinks +// If False, and the last element of the path is a symbolic link, +// access will examine the symbolic link itself instead of the file +// the link points to. +// +// dir_fd, effective_ids, and follow_symlinks may not be implemented +// +// on your platform. If they are unavailable, using them will raise a +// NotImplementedError. +// +// Note that most operations will use the effective uid/gid, therefore this +// +// routine can be used in a suid/sgid environment to test if the invoking user +// has the specified access to the path. +// +//go:linkname Access py.access +func Access(path *py.Object, mode *py.Object) *py.Object + +// Return the name of the terminal device connected to 'fd'. +// +// fd +// Integer file descriptor handle. +// +//go:linkname Ttyname py.ttyname +func Ttyname(fd *py.Object) *py.Object + +// Change the current working directory to the specified path. +// +// path may always be specified as a string. +// On some platforms, path may also be specified as an open file descriptor. +// +// If this functionality is unavailable, using it raises an exception. +// +//go:linkname Chdir py.chdir +func Chdir(path *py.Object) *py.Object + +// Set file flags. +// +// If follow_symlinks is False, and the last element of the path is a symbolic +// +// link, chflags will change flags on the symbolic link itself instead of the +// file the link points to. +// +// follow_symlinks may not be implemented on your platform. If it is +// unavailable, using it will raise a NotImplementedError. +// +//go:linkname Chflags py.chflags +func Chflags(path *py.Object, flags *py.Object, followSymlinks *py.Object) *py.Object + +// Change the access permissions of a file. +// +// path +// Path to be modified. May always be specified as a str, bytes, or a path-like object. +// On some platforms, path may also be specified as an open file descriptor. +// If this functionality is unavailable, using it raises an exception. +// mode +// Operating-system mode bitfield. +// Be careful when using number literals for *mode*. The conventional UNIX notation for +// numeric modes uses an octal base, which needs to be indicated with a ``0o`` prefix in +// Python. +// dir_fd +// If not None, it should be a file descriptor open to a directory, +// and path should be relative; path will then be relative to that +// directory. +// follow_symlinks +// If False, and the last element of the path is a symbolic link, +// chmod will modify the symbolic link itself instead of the file +// the link points to. +// +// It is an error to use dir_fd or follow_symlinks when specifying path as +// +// an open file descriptor. +// +// dir_fd and follow_symlinks may not be implemented on your platform. +// +// If they are unavailable, using them will raise a NotImplementedError. +// +//go:linkname Chmod py.chmod +func Chmod(path *py.Object, mode *py.Object) *py.Object + +// Change the access permissions of the file given by file descriptor fd. +// +// fd +// The file descriptor of the file to be modified. +// mode +// Operating-system mode bitfield. +// Be careful when using number literals for *mode*. The conventional UNIX notation for +// numeric modes uses an octal base, which needs to be indicated with a ``0o`` prefix in +// Python. +// +// Equivalent to os.chmod(fd, mode). +// +//go:linkname Fchmod py.fchmod +func Fchmod(fd *py.Object, mode *py.Object) *py.Object + +// Change the access permissions of a file, without following symbolic links. +// +// If path is a symlink, this affects the link itself rather than the target. +// Equivalent to chmod(path, mode, follow_symlinks=False)." +// +//go:linkname Lchmod py.lchmod +func Lchmod(path *py.Object, mode *py.Object) *py.Object + +// Change the owner and group id of path to the numeric uid and gid.\ +// +// path +// Path to be examined; can be string, bytes, a path-like object, or open-file-descriptor int. +// dir_fd +// If not None, it should be a file descriptor open to a directory, +// and path should be relative; path will then be relative to that +// directory. +// follow_symlinks +// If False, and the last element of the path is a symbolic link, +// stat will examine the symbolic link itself instead of the file +// the link points to. +// +// path may always be specified as a string. +// On some platforms, path may also be specified as an open file descriptor. +// +// If this functionality is unavailable, using it raises an exception. +// +// If dir_fd is not None, it should be a file descriptor open to a directory, +// +// and path should be relative; path will then be relative to that directory. +// +// If follow_symlinks is False, and the last element of the path is a symbolic +// +// link, chown will modify the symbolic link itself instead of the file the +// link points to. +// +// It is an error to use dir_fd or follow_symlinks when specifying path as +// +// an open file descriptor. +// +// dir_fd and follow_symlinks may not be implemented on your platform. +// +// If they are unavailable, using them will raise a NotImplementedError. +// +//go:linkname Chown py.chown +func Chown(path *py.Object, uid *py.Object, gid *py.Object) *py.Object + +// Change the owner and group id of the file specified by file descriptor. +// +// Equivalent to os.chown(fd, uid, gid). +// +//go:linkname Fchown py.fchown +func Fchown(fd *py.Object, uid *py.Object, gid *py.Object) *py.Object + +// Change the owner and group id of path to the numeric uid and gid. +// +// This function will not follow symbolic links. +// Equivalent to os.chown(path, uid, gid, follow_symlinks=False). +// +//go:linkname Lchown py.lchown +func Lchown(path *py.Object, uid *py.Object, gid *py.Object) *py.Object + +// Set file flags. +// +// This function will not follow symbolic links. +// Equivalent to chflags(path, flags, follow_symlinks=False). +// +//go:linkname Lchflags py.lchflags +func Lchflags(path *py.Object, flags *py.Object) *py.Object + +// Change root directory to path. +// +//go:linkname Chroot py.chroot +func Chroot(path *py.Object) *py.Object + +// Return the name of the controlling terminal for this process. +// +//go:linkname Ctermid py.ctermid +func Ctermid() *py.Object + +// Return a unicode string representing the current working directory. +// +//go:linkname Getcwd py.getcwd +func Getcwd() *py.Object + +// Return a bytes string representing the current working directory. +// +//go:linkname Getcwdb py.getcwdb +func Getcwdb() *py.Object + +// Create a hard link to a file. +// +// If either src_dir_fd or dst_dir_fd is not None, it should be a file +// +// descriptor open to a directory, and the respective path string (src or dst) +// should be relative; the path will then be relative to that directory. +// +// If follow_symlinks is False, and the last element of src is a symbolic +// +// link, link will create a link to the symbolic link itself instead of the +// file the link points to. +// +// src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your +// +// platform. If they are unavailable, using them will raise a +// NotImplementedError. +// +//go:linkname Link py.link +func Link(src *py.Object, dst *py.Object) *py.Object + +// Return a list containing the names of the files in the directory. +// +// path can be specified as either str, bytes, or a path-like object. If path is bytes, +// +// the filenames returned will also be bytes; in all other circumstances +// the filenames returned will be str. +// +// If path is None, uses the path='.'. +// +// On some platforms, path may also be specified as an open file descriptor;\ +// the file descriptor must refer to a directory. +// If this functionality is unavailable, using it raises NotImplementedError. +// +// The list is in arbitrary order. It does not include the special +// entries '.' and '..' even if they are present in the directory. +// +//go:linkname Listdir py.listdir +func Listdir(path *py.Object) *py.Object + +// Perform a stat system call on the given path, without following symbolic links. +// +// Like stat(), but do not follow symbolic links. +// Equivalent to stat(path, follow_symlinks=False). +// +//go:linkname Lstat py.lstat +func Lstat(path *py.Object) *py.Object + +// Create a directory. +// +// If dir_fd is not None, it should be a file descriptor open to a directory, +// +// and path should be relative; path will then be relative to that directory. +// +// dir_fd may not be implemented on your platform. +// +// If it is unavailable, using it will raise a NotImplementedError. +// +// The mode argument is ignored on Windows. Where it is used, the current umask +// value is first masked out. +// +//go:linkname Mkdir py.mkdir +func Mkdir(path *py.Object, mode *py.Object) *py.Object + +// Add increment to the priority of process and return the new priority. +// +//go:linkname Nice py.nice +func Nice(increment *py.Object) *py.Object + +// Return program scheduling priority. +// +//go:linkname Getpriority py.getpriority +func Getpriority(which *py.Object, who *py.Object) *py.Object + +// Set program scheduling priority. +// +//go:linkname Setpriority py.setpriority +func Setpriority(which *py.Object, who *py.Object, priority *py.Object) *py.Object + +// Remove a directory. +// +// If dir_fd is not None, it should be a file descriptor open to a directory, +// +// and path should be relative; path will then be relative to that directory. +// +// dir_fd may not be implemented on your platform. +// +// If it is unavailable, using it will raise a NotImplementedError. +// +//go:linkname Rmdir py.rmdir +func Rmdir(path *py.Object) *py.Object + +// Create a symbolic link pointing to src named dst. +// +// target_is_directory is required on Windows if the target is to be +// +// interpreted as a directory. (On Windows, symlink requires +// Windows 6.0 or greater, and raises a NotImplementedError otherwise.) +// target_is_directory is ignored on non-Windows platforms. +// +// If dir_fd is not None, it should be a file descriptor open to a directory, +// +// and path should be relative; path will then be relative to that directory. +// +// dir_fd may not be implemented on your platform. +// +// If it is unavailable, using it will raise a NotImplementedError. +// +//go:linkname Symlink py.symlink +func Symlink(src *py.Object, dst *py.Object, targetIsDirectory *py.Object) *py.Object + +// Execute the command in a subshell. +// +//go:linkname System py.system +func System(command *py.Object) *py.Object + +// Set the current numeric umask and return the previous umask. +// +//go:linkname Umask py.umask +func Umask(mask *py.Object) *py.Object + +// Return an object identifying the current operating system. +// +// The object behaves like a named tuple with the following fields: +// +// (sysname, nodename, release, version, machine) +// +//go:linkname Uname py.uname +func Uname() *py.Object + +// Remove a file (same as remove()). +// +// If dir_fd is not None, it should be a file descriptor open to a directory, +// +// and path should be relative; path will then be relative to that directory. +// +// dir_fd may not be implemented on your platform. +// +// If it is unavailable, using it will raise a NotImplementedError. +// +//go:linkname Unlink py.unlink +func Unlink(path *py.Object) *py.Object + +// Remove a file (same as unlink()). +// +// If dir_fd is not None, it should be a file descriptor open to a directory, +// +// and path should be relative; path will then be relative to that directory. +// +// dir_fd may not be implemented on your platform. +// +// If it is unavailable, using it will raise a NotImplementedError. +// +//go:linkname Remove py.remove +func Remove(path *py.Object) *py.Object + +// Return a collection containing process timing information. +// +// The object returned behaves like a named tuple with these fields: +// +// (utime, stime, cutime, cstime, elapsed_time) +// +// All fields are floating point numbers. +// +//go:linkname Times py.times +func Times() *py.Object + +// Execute an executable path with arguments, replacing current process. +// +// path +// Path of executable file. +// argv +// Tuple or list of strings. +// +//go:linkname Execv py.execv +func Execv(path *py.Object, argv *py.Object) *py.Object + +// Execute an executable path with arguments, replacing current process. +// +// path +// Path of executable file. +// argv +// Tuple or list of strings. +// env +// Dictionary of strings mapping to strings. +// +//go:linkname Execve py.execve +func Execve(path *py.Object, argv *py.Object, env *py.Object) *py.Object + +// Fork a child process. +// +// Return 0 to child process and PID of child to parent process. +// +//go:linkname Fork py.fork +func Fork() *py.Object + +// Get the minimum scheduling priority for policy. +// +//go:linkname SchedGetPriorityMin py.sched_get_priority_min +func SchedGetPriorityMin(policy *py.Object) *py.Object + +// Voluntarily relinquish the CPU. +// +//go:linkname SchedYield py.sched_yield +func SchedYield() *py.Object + +// Open a pseudo-terminal. +// +// Return a tuple of (master_fd, slave_fd) containing open file descriptors +// for both the master and slave ends. +// +//go:linkname Openpty py.openpty +func Openpty() *py.Object + +// Prepare the tty of which fd is a file descriptor for a new login session. +// +// Make the calling process a session leader; make the tty the +// controlling tty, the stdin, the stdout, and the stderr of the +// calling process; close fd. +// +//go:linkname LoginTty py.login_tty +func LoginTty(fd *py.Object) *py.Object + +// Fork a new process with a new pseudo-terminal as controlling tty. +// +// Returns a tuple of (pid, master_fd). +// Like fork(), return pid of 0 to the child process, +// and pid of child to the parent process. +// To both, return fd of newly opened pseudo-terminal. +// +//go:linkname Forkpty py.forkpty +func Forkpty() *py.Object + +// Return the current process's effective group id. +// +//go:linkname Getegid py.getegid +func Getegid() *py.Object + +// Return the current process's effective user id. +// +//go:linkname Geteuid py.geteuid +func Geteuid() *py.Object + +// Return the current process's group id. +// +//go:linkname Getgid py.getgid +func Getgid() *py.Object + +// Returns a list of groups to which a user belongs. +// +// user +// username to lookup +// group +// base group id of the user +// +//go:linkname Getgrouplist py.getgrouplist +func Getgrouplist(user *py.Object, group *py.Object) *py.Object + +// Return list of supplemental group IDs for the process. +// +//go:linkname Getgroups py.getgroups +func Getgroups() *py.Object + +// Return the current process id. +// +//go:linkname Getpid py.getpid +func Getpid() *py.Object + +// Return the current process group id. +// +//go:linkname Getpgrp py.getpgrp +func Getpgrp() *py.Object + +// Return the parent's process id. +// +// If the parent process has already exited, Windows machines will still +// return its id; others systems will return the id of the 'init' process (1). +// +//go:linkname Getppid py.getppid +func Getppid() *py.Object + +// Return the current process's user id. +// +//go:linkname Getuid py.getuid +func Getuid() *py.Object + +// Return the actual login name. +// +//go:linkname Getlogin py.getlogin +func Getlogin() *py.Object + +// Kill a process with a signal. +// +//go:linkname Kill py.kill +func Kill(pid *py.Object, signal *py.Object) *py.Object + +// Kill a process group with a signal. +// +//go:linkname Killpg py.killpg +func Killpg(pgid *py.Object, signal *py.Object) *py.Object + +// Set the current process's user id. +// +//go:linkname Setuid py.setuid +func Setuid(uid *py.Object) *py.Object + +// Set the current process's effective user id. +// +//go:linkname Seteuid py.seteuid +func Seteuid(euid *py.Object) *py.Object + +// Set the current process's real and effective user ids. +// +//go:linkname Setreuid py.setreuid +func Setreuid(ruid *py.Object, euid *py.Object) *py.Object + +// Set the current process's group id. +// +//go:linkname Setgid py.setgid +func Setgid(gid *py.Object) *py.Object + +// Set the current process's effective group id. +// +//go:linkname Setegid py.setegid +func Setegid(egid *py.Object) *py.Object + +// Set the current process's real and effective group ids. +// +//go:linkname Setregid py.setregid +func Setregid(rgid *py.Object, egid *py.Object) *py.Object + +// Set the groups of the current process to list. +// +//go:linkname Setgroups py.setgroups +func Setgroups(groups *py.Object) *py.Object + +// Initialize the group access list. +// +// Call the system initgroups() to initialize the group access list with all of +// the groups of which the specified username is a member, plus the specified +// group id. +// +//go:linkname Initgroups py.initgroups +func Initgroups(username *py.Object, gid *py.Object) *py.Object + +// Call the system call getpgid(), and return the result. +// +//go:linkname Getpgid py.getpgid +func Getpgid(pid *py.Object) *py.Object + +// Make the current process the leader of its process group. +// +//go:linkname Setpgrp py.setpgrp +func Setpgrp() *py.Object + +// Wait for completion of a child process. +// +// Returns a tuple of information about the child process: +// +// (pid, status) +// +//go:linkname Wait py.wait +func Wait() *py.Object + +// Wait for completion of a child process. +// +// Returns a tuple of information about the child process: +// +// (pid, status, rusage) +// +//go:linkname Wait3 py.wait3 +func Wait3(options *py.Object) *py.Object + +// Wait for completion of a specific child process. +// +// Returns a tuple of information about the child process: +// +// (pid, status, rusage) +// +//go:linkname Wait4 py.wait4 +func Wait4(pid *py.Object, options *py.Object) *py.Object + +// Wait for completion of a given child process. +// +// Returns a tuple of information regarding the child process: +// +// (pid, status) +// +// The options argument is ignored on Windows. +// +//go:linkname Waitpid py.waitpid +func Waitpid(pid *py.Object, options *py.Object) *py.Object + +// Call the system call getsid(pid) and return the result. +// +//go:linkname Getsid py.getsid +func Getsid(pid *py.Object) *py.Object + +// Call the system call setsid(). +// +//go:linkname Setsid py.setsid +func Setsid() *py.Object + +// Call the system call setpgid(pid, pgrp). +// +//go:linkname Setpgid py.setpgid +func Setpgid(pid *py.Object, pgrp *py.Object) *py.Object + +// Return the process group associated with the terminal specified by fd. +// +//go:linkname Tcgetpgrp py.tcgetpgrp +func Tcgetpgrp(fd *py.Object) *py.Object + +// Set the process group associated with the terminal specified by fd. +// +//go:linkname Tcsetpgrp py.tcsetpgrp +func Tcsetpgrp(fd *py.Object, pgid *py.Object) *py.Object + +// Open a file for low level IO. Returns a file descriptor (integer). +// +// If dir_fd is not None, it should be a file descriptor open to a directory, +// +// and path should be relative; path will then be relative to that directory. +// +// dir_fd may not be implemented on your platform. +// +// If it is unavailable, using it will raise a NotImplementedError. +// +//go:linkname Open py.open +func Open(path *py.Object, flags *py.Object, mode *py.Object) *py.Object + +// Close a file descriptor. +// +//go:linkname Close py.close +func Close(fd *py.Object) *py.Object + +// Closes all file descriptors in [fd_low, fd_high), ignoring errors. +// +//go:linkname Closerange py.closerange +func Closerange(fdLow *py.Object, fdHigh *py.Object) *py.Object + +// Return a string describing the encoding of a terminal's file descriptor. +// +// The file descriptor must be attached to a terminal. +// If the device is not a terminal, return None. +// +//go:linkname DeviceEncoding py.device_encoding +func DeviceEncoding(fd *py.Object) *py.Object + +// Return a duplicate of a file descriptor. +// +//go:linkname Dup py.dup +func Dup(fd *py.Object) *py.Object + +// Duplicate file descriptor. +// +//go:linkname Dup2 py.dup2 +func Dup2(fd *py.Object, fd2 *py.Object, inheritable *py.Object) *py.Object + +// Apply, test or remove a POSIX lock on an open file descriptor. +// +// fd +// An open file descriptor. +// command +// One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST. +// length +// The number of bytes to lock, starting at the current position. +// +//go:linkname Lockf py.lockf +func Lockf(fd *py.Object, command *py.Object, length *py.Object) *py.Object + +// Set the position of a file descriptor. Return the new position. +// +// fd +// An open file descriptor, as returned by os.open(). +// position +// Position, interpreted relative to 'whence'. +// whence +// The relative position to seek from. Valid values are: +// - SEEK_SET: seek from the start of the file. +// - SEEK_CUR: seek from the current file position. +// - SEEK_END: seek from the end of the file. +// +// The return value is the number of bytes relative to the beginning of the file. +// +//go:linkname Lseek py.lseek +func Lseek(fd *py.Object, position *py.Object, whence *py.Object) *py.Object + +// Read from a file descriptor. Returns a bytes object. +// +//go:linkname Read py.read +func Read(fd *py.Object, length *py.Object) *py.Object + +// Read from a file descriptor fd into an iterable of buffers. +// +// The buffers should be mutable buffers accepting bytes. +// readv will transfer data into each buffer until it is full +// and then move on to the next buffer in the sequence to hold +// the rest of the data. +// +// readv returns the total number of bytes read, +// which may be less than the total capacity of all the buffers. +// +//go:linkname Readv py.readv +func Readv(fd *py.Object, buffers *py.Object) *py.Object + +// Read a number of bytes from a file descriptor starting at a particular offset. +// +// Read length bytes from file descriptor fd, starting at offset bytes from +// the beginning of the file. The file offset remains unchanged. +// +//go:linkname Pread py.pread +func Pread(fd *py.Object, length *py.Object, offset *py.Object) *py.Object + +// Reads from a file descriptor into a number of mutable bytes-like objects. +// +// Combines the functionality of readv() and pread(). As readv(), it will +// transfer data into each buffer until it is full and then move on to the next +// buffer in the sequence to hold the rest of the data. Its fourth argument, +// specifies the file offset at which the input operation is to be performed. It +// will return the total number of bytes read (which can be less than the total +// capacity of all the objects). +// +// The flags argument contains a bitwise OR of zero or more of the following flags: +// +// - RWF_HIPRI +// - RWF_NOWAIT +// +// Using non-zero flags requires Linux 4.6 or newer. +// +//go:linkname Preadv py.preadv +func Preadv(fd *py.Object, buffers *py.Object, offset *py.Object, flags *py.Object) *py.Object + +// Write a bytes object to a file descriptor. +// +//go:linkname Write py.write +func Write(fd *py.Object, data *py.Object) *py.Object + +// Iterate over buffers, and write the contents of each to a file descriptor. +// +// Returns the total number of bytes written. +// buffers must be a sequence of bytes-like objects. +// +//go:linkname Writev py.writev +func Writev(fd *py.Object, buffers *py.Object) *py.Object + +// Write bytes to a file descriptor starting at a particular offset. +// +// Write buffer to fd, starting at offset bytes from the beginning of +// the file. Returns the number of bytes writte. Does not change the +// current file offset. +// +//go:linkname Pwrite py.pwrite +func Pwrite(fd *py.Object, buffer *py.Object, offset *py.Object) *py.Object + +// Writes the contents of bytes-like objects to a file descriptor at a given offset. +// +// Combines the functionality of writev() and pwrite(). All buffers must be a sequence +// of bytes-like objects. Buffers are processed in array order. Entire contents of first +// buffer is written before proceeding to second, and so on. The operating system may +// set a limit (sysconf() value SC_IOV_MAX) on the number of buffers that can be used. +// This function writes the contents of each object to the file descriptor and returns +// the total number of bytes written. +// +// The flags argument contains a bitwise OR of zero or more of the following flags: +// +// - RWF_DSYNC +// - RWF_SYNC +// - RWF_APPEND +// +// Using non-zero flags requires Linux 4.7 or newer. +// +//go:linkname Pwritev py.pwritev +func Pwritev(fd *py.Object, buffers *py.Object, offset *py.Object, flags *py.Object) *py.Object + +// Copy count bytes from file descriptor in_fd to file descriptor out_fd. +// +//go:linkname Sendfile py.sendfile +func Sendfile(outFd *py.Object, inFd *py.Object, offset *py.Object, count *py.Object, headers *py.Object, trailers *py.Object, flags *py.Object) *py.Object + +// Perform a stat system call on the given file descriptor. +// +// Like stat(), but for an open file descriptor. +// Equivalent to os.stat(fd). +// +//go:linkname Fstat py.fstat +func Fstat(fd *py.Object) *py.Object + +// Return True if the fd is connected to a terminal. +// +// Return True if the file descriptor is an open file descriptor +// connected to the slave end of a terminal. +// +//go:linkname Isatty py.isatty +func Isatty(fd *py.Object) *py.Object + +// Create a pipe. +// +// Returns a tuple of two file descriptors: +// +// (read_fd, write_fd) +// +//go:linkname Pipe py.pipe +func Pipe() *py.Object + +// Create a "fifo" (a POSIX named pipe). +// +// If dir_fd is not None, it should be a file descriptor open to a directory, +// +// and path should be relative; path will then be relative to that directory. +// +// dir_fd may not be implemented on your platform. +// +// If it is unavailable, using it will raise a NotImplementedError. +// +//go:linkname Mkfifo py.mkfifo +func Mkfifo(path *py.Object, mode *py.Object) *py.Object + +// Create a node in the file system. +// +// Create a node in the file system (file, device special file or named pipe) +// at path. mode specifies both the permissions to use and the +// type of node to be created, being combined (bitwise OR) with one of +// S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode, +// device defines the newly created device special file (probably using +// os.makedev()). Otherwise device is ignored. +// +// If dir_fd is not None, it should be a file descriptor open to a directory, +// +// and path should be relative; path will then be relative to that directory. +// +// dir_fd may not be implemented on your platform. +// +// If it is unavailable, using it will raise a NotImplementedError. +// +//go:linkname Mknod py.mknod +func Mknod(path *py.Object, mode *py.Object, device *py.Object) *py.Object + +// Extracts a device major number from a raw device number. +// +//go:linkname Major py.major +func Major(device *py.Object) *py.Object + +// Extracts a device minor number from a raw device number. +// +//go:linkname Minor py.minor +func Minor(device *py.Object) *py.Object + +// Composes a raw device number from the major and minor device numbers. +// +//go:linkname Makedev py.makedev +func Makedev(major *py.Object, minor *py.Object) *py.Object + +// Truncate a file, specified by file descriptor, to a specific length. +// +//go:linkname Ftruncate py.ftruncate +func Ftruncate(fd *py.Object, length *py.Object) *py.Object + +// Truncate a file, specified by path, to a specific length. +// +// On some platforms, path may also be specified as an open file descriptor. +// +// If this functionality is unavailable, using it raises an exception. +// +//go:linkname Truncate py.truncate +func Truncate(path *py.Object, length *py.Object) *py.Object + +// Change or add an environment variable. +// +//go:linkname Putenv py.putenv +func Putenv(name *py.Object, value *py.Object) *py.Object + +// Delete an environment variable. +// +//go:linkname Unsetenv py.unsetenv +func Unsetenv(name *py.Object) *py.Object + +// Translate an error code to a message string. +// +//go:linkname Strerror py.strerror +func Strerror(code *py.Object) *py.Object + +// Change to the directory of the given file descriptor. +// +// fd must be opened on a directory, not a file. +// Equivalent to os.chdir(fd). +// +//go:linkname Fchdir py.fchdir +func Fchdir(fd *py.Object) *py.Object + +// Force write of fd to disk. +// +//go:linkname Fsync py.fsync +func Fsync(fd *py.Object) *py.Object + +// Force write of everything to disk. +// +//go:linkname Sync py.sync +func Sync() *py.Object + +// Return True if the process returning status was dumped to a core file. +// +//go:linkname WCOREDUMP py.WCOREDUMP +func WCOREDUMP(status *py.Object) *py.Object + +// Return True if a particular process was continued from a job control stop. +// +// Return True if the process returning status was continued from a +// job control stop. +// +//go:linkname WIFCONTINUED py.WIFCONTINUED +func WIFCONTINUED(status *py.Object) *py.Object + +// Return True if the process returning status was stopped. +// +//go:linkname WIFSTOPPED py.WIFSTOPPED +func WIFSTOPPED(status *py.Object) *py.Object + +// Return True if the process returning status was terminated by a signal. +// +//go:linkname WIFSIGNALED py.WIFSIGNALED +func WIFSIGNALED(status *py.Object) *py.Object + +// Return True if the process returning status exited via the exit() system call. +// +//go:linkname WIFEXITED py.WIFEXITED +func WIFEXITED(status *py.Object) *py.Object + +// Return the process return code from status. +// +//go:linkname WEXITSTATUS py.WEXITSTATUS +func WEXITSTATUS(status *py.Object) *py.Object + +// Return the signal that terminated the process that provided the status value. +// +//go:linkname WTERMSIG py.WTERMSIG +func WTERMSIG(status *py.Object) *py.Object + +// Return the signal that stopped the process that provided the status value. +// +//go:linkname WSTOPSIG py.WSTOPSIG +func WSTOPSIG(status *py.Object) *py.Object + +// Perform an fstatvfs system call on the given fd. +// +// Equivalent to statvfs(fd). +// +//go:linkname Fstatvfs py.fstatvfs +func Fstatvfs(fd *py.Object) *py.Object + +// Perform a statvfs system call on the given path. +// +// path may always be specified as a string. +// On some platforms, path may also be specified as an open file descriptor. +// +// If this functionality is unavailable, using it raises an exception. +// +//go:linkname Statvfs py.statvfs +func Statvfs(path *py.Object) *py.Object + +// Return a string-valued system configuration variable. +// +//go:linkname Confstr py.confstr +func Confstr(name *py.Object) *py.Object + +// Return an integer-valued system configuration variable. +// +//go:linkname Sysconf py.sysconf +func Sysconf(name *py.Object) *py.Object + +// Return the configuration limit name for the file descriptor fd. +// +// If there is no limit, return -1. +// +//go:linkname Fpathconf py.fpathconf +func Fpathconf(fd *py.Object, name *py.Object) *py.Object + +// Return the configuration limit name for the file or directory path. +// +// If there is no limit, return -1. +// On some platforms, path may also be specified as an open file descriptor. +// +// If this functionality is unavailable, using it raises an exception. +// +//go:linkname Pathconf py.pathconf +func Pathconf(path *py.Object, name *py.Object) *py.Object + +// Abort the interpreter immediately. +// +// This function 'dumps core' or otherwise fails in the hardest way possible +// on the hosting operating system. This function never returns. +// +//go:linkname Abort py.abort +func Abort() *py.Object + +// Return average recent system load information. +// +// Return the number of processes in the system run queue averaged over +// the last 1, 5, and 15 minutes as a tuple of three floats. +// Raises OSError if the load average was unobtainable. +// +//go:linkname Getloadavg py.getloadavg +func Getloadavg() *py.Object + +// Return a bytes object containing random bytes suitable for cryptographic use. +// +//go:linkname Urandom py.urandom +func Urandom(size *py.Object) *py.Object + +// Return the number of CPUs in the system; return None if indeterminable. +// +// This number is not equivalent to the number of CPUs the current process can +// use. The number of usable CPUs can be obtained with +// “len(os.sched_getaffinity(0))“ +// +//go:linkname CpuCount py.cpu_count +func CpuCount() *py.Object + +// Get the close-on-exe flag of the specified file descriptor. +// +//go:linkname GetInheritable py.get_inheritable +func GetInheritable(fd *py.Object) *py.Object + +// Set the inheritable flag of the specified file descriptor. +// +//go:linkname SetInheritable py.set_inheritable +func SetInheritable(fd *py.Object, inheritable *py.Object) *py.Object + +// Get the blocking mode of the file descriptor. +// +// Return False if the O_NONBLOCK flag is set, True if the flag is cleared. +// +//go:linkname GetBlocking py.get_blocking +func GetBlocking(fd *py.Object) *py.Object + +// Set the blocking mode of the specified file descriptor. +// +// Set the O_NONBLOCK flag if blocking is False, +// clear the O_NONBLOCK flag otherwise. +// +//go:linkname SetBlocking py.set_blocking +func SetBlocking(fd *py.Object, blocking *py.Object) *py.Object + +// Return an iterator of DirEntry objects for given path. +// +// path can be specified as either str, bytes, or a path-like object. If path +// is bytes, the names of yielded DirEntry objects will also be bytes; in +// all other circumstances they will be str. +// +// If path is None, uses the path='.'. +// +//go:linkname Scandir py.scandir +func Scandir(path *py.Object) *py.Object + +// Return the file system path representation of the object. +// +// If the object is str or bytes, then allow it to pass through as-is. If the +// object defines __fspath__(), then return the result of that method. All other +// types raise a TypeError. +// +//go:linkname Fspath py.fspath +func Fspath(path *py.Object) *py.Object + +// Convert a wait status to an exit code. +// +// On Unix: +// +// * If WIFEXITED(status) is true, return WEXITSTATUS(status). +// * If WIFSIGNALED(status) is true, return -WTERMSIG(status). +// * Otherwise, raise a ValueError. +// +// On Windows, return status shifted right by 8 bits. +// +// On Unix, if the process is being traced or if waitpid() was called with +// WUNTRACED option, the caller must first check if WIFSTOPPED(status) is true. +// This function must not be called if WIFSTOPPED(status) is true. +// +//go:linkname WaitstatusToExitcode py.waitstatus_to_exitcode +func WaitstatusToExitcode(status *py.Object) *py.Object + +// makedirs(name [, mode=0o777][, exist_ok=False]) +// +// Super-mkdir; create a leaf directory and all intermediate ones. Works like +// mkdir, except that any intermediate path segment (not just the rightmost) +// will be created if it does not exist. If the target directory already +// exists, raise an OSError if exist_ok is False. Otherwise no exception is +// raised. This is recursive. +// +//go:linkname Makedirs py.makedirs +func Makedirs(name *py.Object, mode *py.Object, existOk *py.Object) *py.Object + +// removedirs(name) +// +// Super-rmdir; remove a leaf directory and all empty intermediate +// ones. Works like rmdir except that, if the leaf directory is +// successfully removed, directories corresponding to rightmost path +// segments will be pruned away until either the whole path is +// consumed or an error occurs. Errors during this latter phase are +// ignored -- they generally mean that a directory was not empty. +// +//go:linkname Removedirs py.removedirs +func Removedirs(name *py.Object) *py.Object + +// renames(old, new) +// +// Super-rename; create directories as necessary and delete any left +// empty. Works like rename, except creation of any intermediate +// directories needed to make the new pathname good is attempted +// first. After the rename, directories corresponding to rightmost +// path segments of the old name will be pruned until either the +// whole path is consumed or a nonempty directory is found. +// +// Note: this function can fail with the new directory structure made +// if you lack permissions needed to unlink the leaf directory or +// file. +// +//go:linkname Renames py.renames +func Renames(old *py.Object, new *py.Object) *py.Object + +// Directory tree generator. +// +// For each directory in the directory tree rooted at top (including top +// itself, but excluding '.' and '..'), yields a 3-tuple +// +// dirpath, dirnames, filenames +// +// dirpath is a string, the path to the directory. dirnames is a list of +// the names of the subdirectories in dirpath (including symlinks to directories, +// and excluding '.' and '..'). +// filenames is a list of the names of the non-directory files in dirpath. +// Note that the names in the lists are just names, with no path components. +// To get a full path (which begins with top) to a file or directory in +// dirpath, do os.path.join(dirpath, name). +// +// If optional arg 'topdown' is true or not specified, the triple for a +// directory is generated before the triples for any of its subdirectories +// (directories are generated top down). If topdown is false, the triple +// for a directory is generated after the triples for all of its +// subdirectories (directories are generated bottom up). +// +// When topdown is true, the caller can modify the dirnames list in-place +// (e.g., via del or slice assignment), and walk will only recurse into the +// subdirectories whose names remain in dirnames; this can be used to prune the +// search, or to impose a specific order of visiting. Modifying dirnames when +// topdown is false has no effect on the behavior of os.walk(), since the +// directories in dirnames have already been generated by the time dirnames +// itself is generated. No matter the value of topdown, the list of +// subdirectories is retrieved before the tuples for the directory and its +// subdirectories are generated. +// +// By default errors from the os.scandir() call are ignored. If +// optional arg 'onerror' is specified, it should be a function; it +// will be called with one argument, an OSError instance. It can +// report the error to continue with the walk, or raise the exception +// to abort the walk. Note that the filename is available as the +// filename attribute of the exception object. +// +// By default, os.walk does not follow symbolic links to subdirectories on +// systems that support them. In order to get this functionality, set the +// optional argument 'followlinks' to true. +// +// Caution: if you pass a relative pathname for top, don't change the +// current working directory between resumptions of walk. walk never +// changes the current directory, and assumes that the client doesn't +// either. +// +// Example: +// +// import os +// from os.path import join, getsize +// for root, dirs, files in os.walk('python/Lib/email'): +// print(root, "consumes ") +// print(sum(getsize(join(root, name)) for name in files), end=" ") +// print("bytes in", len(files), "non-directory files") +// if 'CVS' in dirs: +// dirs.remove('CVS') # don't visit CVS directories +// +//go:linkname Walk py.walk +func Walk(top *py.Object, topdown *py.Object, onerror *py.Object, followlinks *py.Object) *py.Object + +// Directory tree generator. +// +// This behaves exactly like walk(), except that it yields a 4-tuple +// +// dirpath, dirnames, filenames, dirfd +// +// `dirpath`, `dirnames` and `filenames` are identical to walk() output, +// and `dirfd` is a file descriptor referring to the directory `dirpath`. +// +// The advantage of fwalk() over walk() is that it's safe against symlink +// races (when follow_symlinks is False). +// +// If dir_fd is not None, it should be a file descriptor open to a directory, +// and top should be relative; top will then be relative to that directory. +// (dir_fd is always supported for fwalk.) +// +// Caution: +// Since fwalk() yields file descriptors, those are only valid until the +// next iteration step, so you should dup() them if you want to keep them +// for a longer period. +// +// Example: +// +// import os +// for root, dirs, files, rootfd in os.fwalk('python/Lib/email'): +// print(root, "consumes", end="") +// print(sum(os.stat(name, dir_fd=rootfd).st_size for name in files), +// end="") +// print("bytes in", len(files), "non-directory files") +// if 'CVS' in dirs: +// dirs.remove('CVS') # don't visit CVS directories +// +//go:linkname Fwalk py.fwalk +func Fwalk(top *py.Object, topdown *py.Object, onerror *py.Object) *py.Object + +// execl(file, *args) +// +// Execute the executable file with argument list args, replacing the +// current process. +// +//go:linkname Execl py.execl +func Execl(file *py.Object, __llgo_va_list ...interface{}) *py.Object + +// execle(file, *args, env) +// +// Execute the executable file with argument list args and +// environment env, replacing the current process. +// +//go:linkname Execle py.execle +func Execle(file *py.Object, __llgo_va_list ...interface{}) *py.Object + +// execlp(file, *args) +// +// Execute the executable file (which is searched for along $PATH) +// with argument list args, replacing the current process. +// +//go:linkname Execlp py.execlp +func Execlp(file *py.Object, __llgo_va_list ...interface{}) *py.Object + +// execlpe(file, *args, env) +// +// Execute the executable file (which is searched for along $PATH) +// with argument list args and environment env, replacing the current +// process. +// +//go:linkname Execlpe py.execlpe +func Execlpe(file *py.Object, __llgo_va_list ...interface{}) *py.Object + +// execvp(file, args) +// +// Execute the executable file (which is searched for along $PATH) +// with argument list args, replacing the current process. +// args may be a list or tuple of strings. +// +//go:linkname Execvp py.execvp +func Execvp(file *py.Object, args *py.Object) *py.Object + +// execvpe(file, args, env) +// +// Execute the executable file (which is searched for along $PATH) +// with argument list args and environment env, replacing the +// current process. +// args may be a list or tuple of strings. +// +//go:linkname Execvpe py.execvpe +func Execvpe(file *py.Object, args *py.Object, env *py.Object) *py.Object + +// Returns the sequence of directories that will be searched for the +// +// named executable (similar to a shell) when launching a process. +// +// *env* must be an environment variable dict or None. If *env* is None, +// os.environ will be used. +// +//go:linkname GetExecPath py.get_exec_path +func GetExecPath(env *py.Object) *py.Object + +// Get an environment variable, return None if it doesn't exist. +// +// The optional second argument can specify an alternate default. +// key, default and the result are str. +// +//go:linkname Getenv py.getenv +func Getenv(key *py.Object, default_ *py.Object) *py.Object + +// Get an environment variable, return None if it doesn't exist. +// +// The optional second argument can specify an alternate default. +// key, default and the result are bytes. +// +//go:linkname Getenvb py.getenvb +func Getenvb(key *py.Object, default_ *py.Object) *py.Object + +// Encode filename (an os.PathLike, bytes, or str) to the filesystem +// +// encoding with 'surrogateescape' error handler, return bytes unchanged. +// On Windows, use 'strict' error handler if the file system encoding is +// 'mbcs' (which is the default encoding). +// +//go:linkname Fsencode py.fsencode +func Fsencode(filename *py.Object) *py.Object + +// Decode filename (an os.PathLike, bytes, or str) from the filesystem +// +// encoding with 'surrogateescape' error handler, return str unchanged. On +// Windows, use 'strict' error handler if the file system encoding is +// 'mbcs' (which is the default encoding). +// +//go:linkname Fsdecode py.fsdecode +func Fsdecode(filename *py.Object) *py.Object + +// spawnv(mode, file, args) -> integer +// +// Execute file with arguments from args in a subprocess. +// If mode == P_NOWAIT return the pid of the process. +// If mode == P_WAIT return the process's exit code if it exits normally; +// otherwise return -SIG, where SIG is the signal that killed it. +// +//go:linkname Spawnv py.spawnv +func Spawnv(mode *py.Object, file *py.Object, args *py.Object) *py.Object + +// spawnve(mode, file, args, env) -> integer +// +// Execute file with arguments from args in a subprocess with the +// specified environment. +// If mode == P_NOWAIT return the pid of the process. +// If mode == P_WAIT return the process's exit code if it exits normally; +// otherwise return -SIG, where SIG is the signal that killed it. +// +//go:linkname Spawnve py.spawnve +func Spawnve(mode *py.Object, file *py.Object, args *py.Object, env *py.Object) *py.Object + +// spawnvp(mode, file, args) -> integer +// +// Execute file (which is looked for along $PATH) with arguments from +// args in a subprocess. +// If mode == P_NOWAIT return the pid of the process. +// If mode == P_WAIT return the process's exit code if it exits normally; +// otherwise return -SIG, where SIG is the signal that killed it. +// +//go:linkname Spawnvp py.spawnvp +func Spawnvp(mode *py.Object, file *py.Object, args *py.Object) *py.Object + +// spawnvpe(mode, file, args, env) -> integer +// +// Execute file (which is looked for along $PATH) with arguments from +// args in a subprocess with the supplied environment. +// If mode == P_NOWAIT return the pid of the process. +// If mode == P_WAIT return the process's exit code if it exits normally; +// otherwise return -SIG, where SIG is the signal that killed it. +// +//go:linkname Spawnvpe py.spawnvpe +func Spawnvpe(mode *py.Object, file *py.Object, args *py.Object, env *py.Object) *py.Object + +// spawnl(mode, file, *args) -> integer +// +// Execute file with arguments from args in a subprocess. +// If mode == P_NOWAIT return the pid of the process. +// If mode == P_WAIT return the process's exit code if it exits normally; +// otherwise return -SIG, where SIG is the signal that killed it. +// +//go:linkname Spawnl py.spawnl +func Spawnl(mode *py.Object, file *py.Object, __llgo_va_list ...interface{}) *py.Object + +// spawnle(mode, file, *args, env) -> integer +// +// Execute file with arguments from args in a subprocess with the +// supplied environment. +// If mode == P_NOWAIT return the pid of the process. +// If mode == P_WAIT return the process's exit code if it exits normally; +// otherwise return -SIG, where SIG is the signal that killed it. +// +//go:linkname Spawnle py.spawnle +func Spawnle(mode *py.Object, file *py.Object, __llgo_va_list ...interface{}) *py.Object + +// spawnlp(mode, file, *args) -> integer +// +// Execute file (which is looked for along $PATH) with arguments from +// args in a subprocess with the supplied environment. +// If mode == P_NOWAIT return the pid of the process. +// If mode == P_WAIT return the process's exit code if it exits normally; +// otherwise return -SIG, where SIG is the signal that killed it. +// +//go:linkname Spawnlp py.spawnlp +func Spawnlp(mode *py.Object, file *py.Object, __llgo_va_list ...interface{}) *py.Object + +// spawnlpe(mode, file, *args, env) -> integer +// +// Execute file (which is looked for along $PATH) with arguments from +// args in a subprocess with the supplied environment. +// If mode == P_NOWAIT return the pid of the process. +// If mode == P_WAIT return the process's exit code if it exits normally; +// otherwise return -SIG, where SIG is the signal that killed it. +// +//go:linkname Spawnlpe py.spawnlpe +func Spawnlpe(mode *py.Object, file *py.Object, __llgo_va_list ...interface{}) *py.Object diff --git a/py/os/llgo_autogen.lla b/py/os/llgo_autogen.lla index e88a4ffa..ddd1bf03 100644 Binary files a/py/os/llgo_autogen.lla and b/py/os/llgo_autogen.lla differ diff --git a/py/os/os.go b/py/os/os.go index 8a421dac..cbd2c72f 100644 --- a/py/os/os.go +++ b/py/os/os.go @@ -22,9 +22,21 @@ import ( "github.com/goplus/llgo/py" ) -const ( - LLGoPackage = "py.os" -) +// https://docs.python.org/3/library/os.html -//go:linkname Getcwd py.getcwd -func Getcwd() *py.Object +// Rename the file or directory src to dst. If dst exists, the operation will +// fail with an OSError subclass in a number of cases: +// +// On Windows, if dst exists a FileExistsError is always raised. The operation +// may fail if src and dst are on different filesystems. Use shutil.move() to +// support moves to a different filesystem. +// +// On Unix, if src is a file and dst is a directory or vice-versa, an IsADirectoryError +// or a NotADirectoryError will be raised respectively. If both are directories and dst +// is empty, dst will be silently replaced. If dst is a non-empty directory, an OSError +// is raised. If both are files, dst will be replaced silently if the user has permission. +// The operation may fail on some Unix flavors if src and dst are on different filesystems. +// If successful, the renaming will be an atomic operation (this is a POSIX requirement). +// +//go:linkname Rename py.rename +func Rename(src, dst *py.Object) *py.Object diff --git a/py/statistics/gen.go b/py/statistics/gen.go new file mode 100644 index 00000000..65e77046 --- /dev/null +++ b/py/statistics/gen.go @@ -0,0 +1,401 @@ +package statistics + +import ( + _ "unsafe" + + "github.com/goplus/llgo/py" +) + +const LLGoPackage = "py.statistics" + +// Error function at x. +// +//go:linkname Erf py.erf +func Erf(x *py.Object) *py.Object + +// Return the sample arithmetic mean of data. +// +// >>> mean([1, 2, 3, 4, 4]) +// 2.8 +// +// >>> from fractions import Fraction as F +// >>> mean([F(3, 7), F(1, 21), F(5, 3), F(1, 3)]) +// Fraction(13, 21) +// +// >>> from decimal import Decimal as D +// >>> mean([D("0.5"), D("0.75"), D("0.625"), D("0.375")]) +// Decimal('0.5625') +// +// If ``data`` is empty, StatisticsError will be raised. +// +//go:linkname Mean py.mean +func Mean(data *py.Object) *py.Object + +// Convert data to floats and compute the arithmetic mean. +// +// This runs faster than the mean() function and it always returns a float. +// If the input dataset is empty, it raises a StatisticsError. +// +// >>> fmean([3.5, 4.0, 5.25]) +// 4.25 +// +//go:linkname Fmean py.fmean +func Fmean(data *py.Object, weights *py.Object) *py.Object + +// Convert data to floats and compute the geometric mean. +// +// Raises a StatisticsError if the input dataset is empty, +// if it contains a zero, or if it contains a negative value. +// +// No special efforts are made to achieve exact results. +// (However, this may change in the future.) +// +// >>> round(geometric_mean([54, 24, 36]), 9) +// 36.0 +// +//go:linkname GeometricMean py.geometric_mean +func GeometricMean(data *py.Object) *py.Object + +// Return the harmonic mean of data. +// +// The harmonic mean is the reciprocal of the arithmetic mean of the +// reciprocals of the data. It can be used for averaging ratios or +// rates, for example speeds. +// +// Suppose a car travels 40 km/hr for 5 km and then speeds-up to +// 60 km/hr for another 5 km. What is the average speed? +// +// >>> harmonic_mean([40, 60]) +// 48.0 +// +// Suppose a car travels 40 km/hr for 5 km, and when traffic clears, +// speeds-up to 60 km/hr for the remaining 30 km of the journey. What +// is the average speed? +// +// >>> harmonic_mean([40, 60], weights=[5, 30]) +// 56.0 +// +// If ``data`` is empty, or any element is less than zero, +// ``harmonic_mean`` will raise ``StatisticsError``. +// +//go:linkname HarmonicMean py.harmonic_mean +func HarmonicMean(data *py.Object, weights *py.Object) *py.Object + +// Return the median (middle value) of numeric data. +// +// When the number of data points is odd, return the middle data point. +// When the number of data points is even, the median is interpolated by +// taking the average of the two middle values: +// +// >>> median([1, 3, 5]) +// 3 +// >>> median([1, 3, 5, 7]) +// 4.0 +// +//go:linkname Median py.median +func Median(data *py.Object) *py.Object + +// Return the low median of numeric data. +// +// When the number of data points is odd, the middle value is returned. +// When it is even, the smaller of the two middle values is returned. +// +// >>> median_low([1, 3, 5]) +// 3 +// >>> median_low([1, 3, 5, 7]) +// 3 +// +//go:linkname MedianLow py.median_low +func MedianLow(data *py.Object) *py.Object + +// Return the high median of data. +// +// When the number of data points is odd, the middle value is returned. +// When it is even, the larger of the two middle values is returned. +// +// >>> median_high([1, 3, 5]) +// 3 +// >>> median_high([1, 3, 5, 7]) +// 5 +// +//go:linkname MedianHigh py.median_high +func MedianHigh(data *py.Object) *py.Object + +// Estimates the median for numeric data binned around the midpoints +// +// of consecutive, fixed-width intervals. +// +// The *data* can be any iterable of numeric data with each value being +// exactly the midpoint of a bin. At least one value must be present. +// +// The *interval* is width of each bin. +// +// For example, demographic information may have been summarized into +// consecutive ten-year age groups with each group being represented +// by the 5-year midpoints of the intervals: +// +// >>> demographics = Counter({ +// ... 25: 172, # 20 to 30 years old +// ... 35: 484, # 30 to 40 years old +// ... 45: 387, # 40 to 50 years old +// ... 55: 22, # 50 to 60 years old +// ... 65: 6, # 60 to 70 years old +// ... }) +// +// The 50th percentile (median) is the 536th person out of the 1071 +// member cohort. That person is in the 30 to 40 year old age group. +// +// The regular median() function would assume that everyone in the +// tricenarian age group was exactly 35 years old. A more tenable +// assumption is that the 484 members of that age group are evenly +// distributed between 30 and 40. For that, we use median_grouped(). +// +// >>> data = list(demographics.elements()) +// >>> median(data) +// 35 +// >>> round(median_grouped(data, interval=10), 1) +// 37.5 +// +// The caller is responsible for making sure the data points are separated +// by exact multiples of *interval*. This is essential for getting a +// correct result. The function does not check this precondition. +// +// Inputs may be any numeric type that can be coerced to a float during +// the interpolation step. +// +//go:linkname MedianGrouped py.median_grouped +func MedianGrouped(data *py.Object, interval *py.Object) *py.Object + +// Return the most common data point from discrete or nominal data. +// +// ``mode`` assumes discrete data, and returns a single value. This is the +// standard treatment of the mode as commonly taught in schools: +// +// >>> mode([1, 1, 2, 3, 3, 3, 3, 4]) +// 3 +// +// This also works with nominal (non-numeric) data: +// +// >>> mode(["red", "blue", "blue", "red", "green", "red", "red"]) +// 'red' +// +// If there are multiple modes with same frequency, return the first one +// encountered: +// +// >>> mode(['red', 'red', 'green', 'blue', 'blue']) +// 'red' +// +// If *data* is empty, ``mode``, raises StatisticsError. +// +//go:linkname Mode py.mode +func Mode(data *py.Object) *py.Object + +// Return a list of the most frequently occurring values. +// +// Will return more than one result if there are multiple modes +// or an empty list if *data* is empty. +// +// >>> multimode('aabbbbbbbbcc') +// ['b'] +// >>> multimode('aabbbbccddddeeffffgg') +// ['b', 'd', 'f'] +// >>> multimode('') +// [] +// +//go:linkname Multimode py.multimode +func Multimode(data *py.Object) *py.Object + +// Divide *data* into *n* continuous intervals with equal probability. +// +// Returns a list of (n - 1) cut points separating the intervals. +// +// Set *n* to 4 for quartiles (the default). Set *n* to 10 for deciles. +// Set *n* to 100 for percentiles which gives the 99 cuts points that +// separate *data* in to 100 equal sized groups. +// +// The *data* can be any iterable containing sample. +// The cut points are linearly interpolated between data points. +// +// If *method* is set to *inclusive*, *data* is treated as population +// data. The minimum value is treated as the 0th percentile and the +// maximum value is treated as the 100th percentile. +// +//go:linkname Quantiles py.quantiles +func Quantiles(data *py.Object) *py.Object + +// Return the sample variance of data. +// +// data should be an iterable of Real-valued numbers, with at least two +// values. The optional argument xbar, if given, should be the mean of +// the data. If it is missing or None, the mean is automatically calculated. +// +// Use this function when your data is a sample from a population. To +// calculate the variance from the entire population, see ``pvariance``. +// +// Examples: +// +// >>> data = [2.75, 1.75, 1.25, 0.25, 0.5, 1.25, 3.5] +// >>> variance(data) +// 1.3720238095238095 +// +// If you have already calculated the mean of your data, you can pass it as +// the optional second argument ``xbar`` to avoid recalculating it: +// +// >>> m = mean(data) +// >>> variance(data, m) +// 1.3720238095238095 +// +// This function does not check that ``xbar`` is actually the mean of +// ``data``. Giving arbitrary values for ``xbar`` may lead to invalid or +// impossible results. +// +// Decimals and Fractions are supported: +// +// >>> from decimal import Decimal as D +// >>> variance([D("27.5"), D("30.25"), D("30.25"), D("34.5"), D("41.75")]) +// Decimal('31.01875') +// +// >>> from fractions import Fraction as F +// >>> variance([F(1, 6), F(1, 2), F(5, 3)]) +// Fraction(67, 108) +// +//go:linkname Variance py.variance +func Variance(data *py.Object, xbar *py.Object) *py.Object + +// Return the population variance of “data“. +// +// data should be a sequence or iterable of Real-valued numbers, with at least one +// value. The optional argument mu, if given, should be the mean of +// the data. If it is missing or None, the mean is automatically calculated. +// +// Use this function to calculate the variance from the entire population. +// To estimate the variance from a sample, the ``variance`` function is +// usually a better choice. +// +// Examples: +// +// >>> data = [0.0, 0.25, 0.25, 1.25, 1.5, 1.75, 2.75, 3.25] +// >>> pvariance(data) +// 1.25 +// +// If you have already calculated the mean of the data, you can pass it as +// the optional second argument to avoid recalculating it: +// +// >>> mu = mean(data) +// >>> pvariance(data, mu) +// 1.25 +// +// Decimals and Fractions are supported: +// +// >>> from decimal import Decimal as D +// >>> pvariance([D("27.5"), D("30.25"), D("30.25"), D("34.5"), D("41.75")]) +// Decimal('24.815') +// +// >>> from fractions import Fraction as F +// >>> pvariance([F(1, 4), F(5, 4), F(1, 2)]) +// Fraction(13, 72) +// +//go:linkname Pvariance py.pvariance +func Pvariance(data *py.Object, mu *py.Object) *py.Object + +// Return the square root of the sample variance. +// +// See ``variance`` for arguments and other details. +// +// >>> stdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75]) +// 1.0810874155219827 +// +//go:linkname Stdev py.stdev +func Stdev(data *py.Object, xbar *py.Object) *py.Object + +// Return the square root of the population variance. +// +// See ``pvariance`` for arguments and other details. +// +// >>> pstdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75]) +// 0.986893273527251 +// +//go:linkname Pstdev py.pstdev +func Pstdev(data *py.Object, mu *py.Object) *py.Object + +// Covariance +// +// Return the sample covariance of two inputs *x* and *y*. Covariance +// is a measure of the joint variability of two inputs. +// +// >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] +// >>> y = [1, 2, 3, 1, 2, 3, 1, 2, 3] +// >>> covariance(x, y) +// 0.75 +// >>> z = [9, 8, 7, 6, 5, 4, 3, 2, 1] +// >>> covariance(x, z) +// -7.5 +// >>> covariance(z, x) +// -7.5 +// +//go:linkname Covariance py.covariance +func Covariance(x *py.Object, y *py.Object) *py.Object + +// Pearson's correlation coefficient +// +// Return the Pearson's correlation coefficient for two inputs. Pearson's +// correlation coefficient *r* takes values between -1 and +1. It measures +// the strength and direction of a linear relationship. +// +// >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] +// >>> y = [9, 8, 7, 6, 5, 4, 3, 2, 1] +// >>> correlation(x, x) +// 1.0 +// >>> correlation(x, y) +// -1.0 +// +// If *method* is "ranked", computes Spearman's rank correlation coefficient +// for two inputs. The data is replaced by ranks. Ties are averaged +// so that equal values receive the same rank. The resulting coefficient +// measures the strength of a monotonic relationship. +// +// Spearman's rank correlation coefficient is appropriate for ordinal +// data or for continuous data that doesn't meet the linear proportion +// requirement for Pearson's correlation coefficient. +// +//go:linkname Correlation py.correlation +func Correlation(x *py.Object, y *py.Object) *py.Object + +// Slope and intercept for simple linear regression. +// +// Return the slope and intercept of simple linear regression +// parameters estimated using ordinary least squares. Simple linear +// regression describes relationship between an independent variable +// *x* and a dependent variable *y* in terms of a linear function: +// +// y = slope * x + intercept + noise +// +// where *slope* and *intercept* are the regression parameters that are +// estimated, and noise represents the variability of the data that was +// not explained by the linear regression (it is equal to the +// difference between predicted and actual values of the dependent +// variable). +// +// The parameters are returned as a named tuple. +// +// >>> x = [1, 2, 3, 4, 5] +// >>> noise = NormalDist().samples(5, seed=42) +// >>> y = [3 * x[i] + 2 + noise[i] for i in range(5)] +// >>> linear_regression(x, y) #doctest: +ELLIPSIS +// LinearRegression(slope=3.09078914170..., intercept=1.75684970486...) +// +// If *proportional* is true, the independent variable *x* and the +// dependent variable *y* are assumed to be directly proportional. +// The data is fit to a line passing through the origin. +// +// Since the *intercept* will always be 0.0, the underlying linear +// function simplifies to: +// +// y = slope * x + noise +// +// >>> y = [3 * x[i] + noise[i] for i in range(5)] +// >>> linear_regression(x, y, proportional=True) #doctest: +ELLIPSIS +// LinearRegression(slope=3.02447542484..., intercept=0.0) +// +//go:linkname LinearRegression py.linear_regression +func LinearRegression(x *py.Object, y *py.Object) *py.Object diff --git a/py/statistics/llgo_autogen.lla b/py/statistics/llgo_autogen.lla new file mode 100644 index 00000000..1f93ec45 Binary files /dev/null and b/py/statistics/llgo_autogen.lla differ diff --git a/py/sys/gen.go b/py/sys/gen.go new file mode 100644 index 00000000..943c67a1 --- /dev/null +++ b/py/sys/gen.go @@ -0,0 +1,220 @@ +package sys + +import ( + _ "unsafe" + + "github.com/goplus/llgo/py" +) + +const LLGoPackage = "py.sys" + +// Adds a new audit hook callback. +// +//go:linkname Addaudithook py.addaudithook +func Addaudithook(hook *py.Object) *py.Object + +// Print an object to sys.stdout and also save it in builtins._ +// +//go:linkname Displayhook py.displayhook +func Displayhook(object *py.Object) *py.Object + +// Return the current exception. +// +// Return the most recent exception caught by an except clause +// in the current stack frame or in an older stack frame, or None +// if no such exception exists. +// +//go:linkname Exception py.exception +func Exception() *py.Object + +// Return current exception information: (type, value, traceback). +// +// Return information about the most recent exception caught by an except +// clause in the current stack frame or in an older stack frame. +// +//go:linkname ExcInfo py.exc_info +func ExcInfo() *py.Object + +// Handle an exception by displaying it with a traceback on sys.stderr. +// +//go:linkname Excepthook py.excepthook +func Excepthook(exctype *py.Object, value *py.Object, traceback *py.Object) *py.Object + +// Exit the interpreter by raising SystemExit(status). +// +// If the status is omitted or None, it defaults to zero (i.e., success). +// If the status is an integer, it will be used as the system exit status. +// If it is another kind of object, it will be printed and the system +// exit status will be one (i.e., failure). +// +//go:linkname Exit py.exit +func Exit(status *py.Object) *py.Object + +// Return the current default encoding used by the Unicode implementation. +// +//go:linkname Getdefaultencoding py.getdefaultencoding +func Getdefaultencoding() *py.Object + +// Return the current value of the flags that are used for dlopen calls. +// +// The flag constants are defined in the os module. +// +//go:linkname Getdlopenflags py.getdlopenflags +func Getdlopenflags() *py.Object + +// Return the number of memory blocks currently allocated. +// +//go:linkname Getallocatedblocks py.getallocatedblocks +func Getallocatedblocks() *py.Object + +// Return the number of elements of the unicode interned dictionary +// +//go:linkname Getunicodeinternedsize py.getunicodeinternedsize +func Getunicodeinternedsize() *py.Object + +// Return the encoding used to convert Unicode filenames to OS filenames. +// +//go:linkname Getfilesystemencoding py.getfilesystemencoding +func Getfilesystemencoding() *py.Object + +// Return the error mode used Unicode to OS filename conversion. +// +//go:linkname Getfilesystemencodeerrors py.getfilesystemencodeerrors +func Getfilesystemencodeerrors() *py.Object + +// Return the reference count of object. +// +// The count returned is generally one higher than you might expect, +// because it includes the (temporary) reference as an argument to +// getrefcount(). +// +//go:linkname Getrefcount py.getrefcount +func Getrefcount(object *py.Object) *py.Object + +// Return the current value of the recursion limit. +// +// The recursion limit is the maximum depth of the Python interpreter +// stack. This limit prevents infinite recursion from causing an overflow +// of the C stack and crashing Python. +// +//go:linkname Getrecursionlimit py.getrecursionlimit +func Getrecursionlimit() *py.Object + +// “Intern” the given string. +// +// This enters the string in the (global) table of interned strings whose +// purpose is to speed up dictionary lookups. Return the string itself or +// the previously interned string object with the same value. +// +//go:linkname Intern py.intern +func Intern(string *py.Object) *py.Object + +// Return True if Python is exiting. +// +//go:linkname IsFinalizing py.is_finalizing +func IsFinalizing() *py.Object + +// Set the ideal thread switching delay inside the Python interpreter. +// +// The actual frequency of switching threads can be lower if the +// interpreter executes long sequences of uninterruptible code +// (this is implementation-specific and workload-dependent). +// +// The parameter must represent the desired switching delay in seconds +// A typical value is 0.005 (5 milliseconds). +// +//go:linkname Setswitchinterval py.setswitchinterval +func Setswitchinterval(interval *py.Object) *py.Object + +// Return the current thread switch interval; see sys.setswitchinterval(). +// +//go:linkname Getswitchinterval py.getswitchinterval +func Getswitchinterval() *py.Object + +// Set the flags used by the interpreter for dlopen calls. +// +// This is used, for example, when the interpreter loads extension +// modules. Among other things, this will enable a lazy resolving of +// symbols when importing a module, if called as sys.setdlopenflags(0). +// To share symbols across extension modules, call as +// sys.setdlopenflags(os.RTLD_GLOBAL). Symbolic names for the flag +// modules can be found in the os module (RTLD_xxx constants, e.g. +// os.RTLD_LAZY). +// +//go:linkname Setdlopenflags py.setdlopenflags +func Setdlopenflags(flags *py.Object) *py.Object + +// Set the maximum depth of the Python interpreter stack to n. +// +// This limit prevents infinite recursion from causing an overflow of the C +// stack and crashing Python. The highest possible limit is platform- +// dependent. +// +//go:linkname Setrecursionlimit py.setrecursionlimit +func Setrecursionlimit(limit *py.Object) *py.Object + +// Return the global debug tracing function set with sys.settrace. +// +// See the debugger chapter in the library manual. +// +//go:linkname Gettrace py.gettrace +func Gettrace() *py.Object + +// Call func(*args), while tracing is enabled. +// +// The tracing state is saved, and restored afterwards. This is intended +// to be called from a debugger from a checkpoint, to recursively debug +// some other code. +// +//go:linkname CallTracing py.call_tracing +func CallTracing(func_ *py.Object, args *py.Object) *py.Object + +// Enable or disable origin tracking for coroutine objects in this thread. +// +// Coroutine objects will track 'depth' frames of traceback information +// about where they came from, available in their cr_origin attribute. +// +// Set a depth of 0 to disable. +// +//go:linkname SetCoroutineOriginTrackingDepth py.set_coroutine_origin_tracking_depth +func SetCoroutineOriginTrackingDepth(depth *py.Object) *py.Object + +// Check status of origin tracking for coroutine objects in this thread. +// +//go:linkname GetCoroutineOriginTrackingDepth py.get_coroutine_origin_tracking_depth +func GetCoroutineOriginTrackingDepth() *py.Object + +// Deactivate the current stack profiler trampoline backend. +// +// If no stack profiler is activated, this function has no effect. +// +//go:linkname DeactivateStackTrampoline py.deactivate_stack_trampoline +func DeactivateStackTrampoline() *py.Object + +// Return *True* if a stack profiler trampoline is active. +// +//go:linkname IsStackTrampolineActive py.is_stack_trampoline_active +func IsStackTrampolineActive() *py.Object + +// Handle an unraisable exception. +// +// The unraisable argument has the following attributes: +// +// * exc_type: Exception type. +// * exc_value: Exception value, can be None. +// * exc_traceback: Exception traceback, can be None. +// * err_msg: Error message, can be None. +// * object: Object causing the exception, can be None. +// +//go:linkname Unraisablehook py.unraisablehook +func Unraisablehook(unraisable *py.Object) *py.Object + +// Return the maximum string digits limit for non-binary int<->str conversions. +// +//go:linkname GetIntMaxStrDigits py.get_int_max_str_digits +func GetIntMaxStrDigits() *py.Object + +// Set the maximum string digits limit for non-binary int<->str conversions. +// +//go:linkname SetIntMaxStrDigits py.set_int_max_str_digits +func SetIntMaxStrDigits(maxdigits *py.Object) *py.Object diff --git a/py/sys/llgo_autogen.lla b/py/sys/llgo_autogen.lla new file mode 100644 index 00000000..f9ffb364 Binary files /dev/null and b/py/sys/llgo_autogen.lla differ diff --git a/py/type.go b/py/type.go new file mode 100644 index 00000000..30b1fe54 --- /dev/null +++ b/py/type.go @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * 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 py + +import ( + _ "unsafe" +) + +// https://docs.python.org/3/c-api/type.html + +// Return the type’s name. Equivalent to getting the type’s __name__ attribute. +// +// llgo:link (*Object).TypeName C.PyType_GetName +func (t *Object) TypeName() *Object { return nil } + +// Return the tp_flags member of type. This function is primarily meant for use +// with Py_LIMITED_API; the individual flag bits are guaranteed to be stable across +// Python releases, but access to tp_flags itself is not part of the limited API. +// +// llgo:link (*Object).TypeFlags C.PyType_GetFlags +func (t *Object) TypeFlags() uint32 { return 0 } + +// Return the module object associated with the given type when the type was created +// using PyType_FromModuleAndSpec(). +// +// If no module is associated with the given type, sets TypeError and returns nil. +// +// This function is usually used to get the module in which a method is defined. Note +// that in such a method, Py_TYPE(self).Module() may not return the intended result. +// Py_TYPE(self) may be a subclass of the intended class, and subclasses are not +// necessarily defined in the same module as their superclass. See PyCMethod to get +// the class that defines the method. See ModuleByDef() for cases when PyCMethod +// cannot be used. +// +// llgo:link (*Object).TypeModule C.PyType_GetModule +func (t *Object) TypeModule() *Object { return nil } + +// llgo:link (*Object).TypeModuleByDef C.PyType_GetModuleByDef +// func (t *Object) TypeModuleByDef(def *ModuleDef) *Object { return nil } diff --git a/ssa/decl.go b/ssa/decl.go index ca857cb1..fd8ecefc 100644 --- a/ssa/decl.go +++ b/ssa/decl.go @@ -29,19 +29,16 @@ import ( const ( ClosureCtx = "__llgo_ctx" ClosureStub = "__llgo_stub." - NameValist = "__llgo_va_list" +) + +// ----------------------------------------------------------------------------- + +const ( + NameValist = "__llgo_va_list" ) func VArg() *types.Var { - return types.NewParam(0, nil, NameValist, types.Typ[types.Invalid]) -} - -func IsVArg(arg *types.Var) bool { - return arg.Name() == NameValist -} - -func HasVArg(t *types.Tuple, n int) bool { - return n > 0 && IsVArg(t.At(n-1)) + return types.NewParam(0, nil, NameValist, types.NewSlice(tyAny)) } // ----------------------------------------------------------------------------- @@ -196,7 +193,7 @@ func newParams(fn Type, prog Program) (params []Type, hasVArg bool) { sig := fn.raw.Type.(*types.Signature) in := sig.Params() if n := in.Len(); n > 0 { - if hasVArg = HasVArg(in, n); hasVArg { + if hasVArg = sig.Variadic(); hasVArg { n-- } params = make([]Type, n) @@ -285,6 +282,29 @@ func (p Function) Block(idx int) BasicBlock { // ----------------------------------------------------------------------------- +type aPyGlobal struct { + Expr +} + +type PyGlobal = *aPyGlobal + +// PyNewVar creates a Python variable. +func (b Builder) PyNewVar(modName, name string) PyGlobal { + pkg := b.Func.Pkg + modPtr := pkg.PyNewModVar(modName, false).Expr + mod := b.Load(modPtr) + return &aPyGlobal{pyVarExpr(mod, name)} +} + +func (b Builder) pyLoad(ptr Expr) Expr { + pkg := b.Func.Pkg + t := ptr.raw.Type.(*pyVarTy) + fn := pkg.pyFunc("PyObject_GetAttrString", b.Prog.tyGetAttrString()) + return b.Call(fn, t.mod, b.CStr(t.name)) +} + +// ----------------------------------------------------------------------------- + type aPyObjRef struct { Expr Obj Global @@ -293,8 +313,8 @@ type aPyObjRef struct { // PyObjRef represents a python object reference. type PyObjRef = *aPyObjRef -// NewPyFunc creates a new python function. -func (p Package) NewPyFunc(name string, sig *types.Signature, doInit bool) PyObjRef { +// PyNewFunc creates a new python function. +func (p Package) PyNewFunc(name string, sig *types.Signature, doInit bool) PyObjRef { if v, ok := p.pyobjs[name]; ok { return v } diff --git a/ssa/expr.go b/ssa/expr.go index 71921b5e..7dfa45a0 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -54,6 +54,26 @@ func (v Expr) Do(b Builder) Expr { // ----------------------------------------------------------------------------- +type pyVarTy struct { + mod Expr + name string +} + +func (p pyVarTy) Underlying() types.Type { + panic("don't call") +} + +func (p pyVarTy) String() string { + return "pyVar" +} + +func pyVarExpr(mod Expr, name string) Expr { + tvar := &aType{raw: rawType{&pyVarTy{mod, name}}, kind: vkPyVarRef} + return Expr{Type: tvar} +} + +// ----------------------------------------------------------------------------- + type phisExprTy struct { phis []llvm.Value Type @@ -68,7 +88,8 @@ func (p phisExprTy) String() string { } func phisExpr(t Type, phis []llvm.Value) Expr { - return Expr{Type: &aType{raw: rawType{&phisExprTy{phis, t}}, kind: vkPhisExpr}} + tphi := &aType{raw: rawType{&phisExprTy{phis, t}}, kind: vkPhisExpr} + return Expr{Type: tphi} } // ----------------------------------------------------------------------------- @@ -78,6 +99,11 @@ func (p Program) Null(t Type) Expr { return Expr{llvm.ConstNull(t.ll), t} } +// PyNull returns a null *PyObject constant expression. +func (p Program) PyNull() Expr { + return p.Null(p.PyObjectPtr()) +} + // BoolVal returns a boolean constant expression. func (p Program) BoolVal(v bool) Expr { t := p.Bool() @@ -284,7 +310,7 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr { case vkString: if op == token.ADD { pkg := b.Func.Pkg - return b.InlineCall(pkg.rtFunc("StringCat"), x, y) + return Expr{b.InlineCall(pkg.rtFunc("StringCat"), x, y).impl, x.Type} } case vkComplex: default: @@ -302,6 +328,11 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr { if op == token.SHR && kind == vkUnsigned { llop = llvm.LShr // Logical Shift Right } + if op == token.SHL || op == token.SHR { + if b.Prog.SizeOf(x.Type) != b.Prog.SizeOf(y.Type) { + y = b.Convert(x.Type, y) + } + } return Expr{llvm.CreateBinOp(b.impl, llop, x.impl, y.impl), x.Type} case isPredOp(op): // op: == != < <= < >= tret := b.Prog.Bool() @@ -508,6 +539,9 @@ func (b Builder) Load(ptr Expr) Expr { if debugInstr { log.Printf("Load %v\n", ptr.impl) } + if ptr.kind == vkPyVarRef { + return b.pyLoad(ptr) + } telem := b.Prog.Elem(ptr.Type) return Expr{llvm.CreateLoad(b.impl, telem.ll, ptr.impl), telem} } @@ -627,6 +661,36 @@ func (b Builder) StringLen(x Expr) Expr { return Expr{ptr, prog.Int()} } +// SliceData returns the data pointer of a slice. +func (b Builder) SliceData(x Expr) Expr { + if debugInstr { + log.Printf("SliceData %v\n", x.impl) + } + prog := b.Prog + ptr := llvm.CreateExtractValue(b.impl, x.impl, 0) + return Expr{ptr, prog.CStr()} +} + +// SliceLen returns the length of a slice. +func (b Builder) SliceLen(x Expr) Expr { + if debugInstr { + log.Printf("SliceLen %v\n", x.impl) + } + prog := b.Prog + ptr := llvm.CreateExtractValue(b.impl, x.impl, 1) + return Expr{ptr, prog.Int()} +} + +// SliceCap returns the length of a slice cap. +func (b Builder) SliceCap(x Expr) Expr { + if debugInstr { + log.Printf("SliceCap %v\n", x.impl) + } + prog := b.Prog + ptr := llvm.CreateExtractValue(b.impl, x.impl, 2) + return Expr{ptr, prog.Int()} +} + // The IndexAddr instruction yields the address of the element at // index `idx` of collection `x`. `idx` is an integer expression. // @@ -648,8 +712,7 @@ func (b Builder) IndexAddr(x, idx Expr) Expr { pt := prog.Pointer(telem) switch x.raw.Type.Underlying().(type) { case *types.Slice: - pkg := b.Func.Pkg - ptr := b.InlineCall(pkg.rtFunc("SliceData"), x) + ptr := b.SliceData(x) indices := []llvm.Value{idx.impl} return Expr{llvm.CreateInBoundsGEP(b.impl, telem.ll, ptr.impl, indices), pt} } @@ -752,12 +815,12 @@ func (b Builder) Slice(x, low, high, max Expr) (ret Expr) { return case *types.Slice: nEltSize = b.SizeOf(prog.Index(x.Type)) - nCap = b.InlineCall(pkg.rtFunc("SliceCap"), x) + nCap = b.SliceCap(x) if high.IsNil() { - high = b.InlineCall(pkg.rtFunc("SliceLen"), x) + high = b.SliceCap(x) } ret.Type = x.Type - base = b.InlineCall(pkg.rtFunc("SliceData"), x) + base = b.SliceData(x) case *types.Pointer: telem := t.Elem() switch te := telem.Underlying().(type) { @@ -1292,23 +1355,86 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) { case "len": if len(args) == 1 { arg := args[0] - switch t := arg.raw.Type.Underlying().(type) { - case *types.Slice: - return b.InlineCall(b.Func.Pkg.rtFunc("SliceLen"), arg) - case *types.Basic: - if t.Kind() == types.String { - return b.StringLen(arg) - } + switch arg.kind { + case vkSlice: + return b.SliceLen(arg) + case vkString: + return b.StringLen(arg) } } case "cap": if len(args) == 1 { arg := args[0] - switch arg.raw.Type.Underlying().(type) { - case *types.Slice: - return b.InlineCall(b.Func.Pkg.rtFunc("SliceCap"), arg) + switch arg.kind { + case vkSlice: + return b.SliceCap(arg) } } + case "append": + if len(args) == 2 { + src := args[0] + if src.kind == vkSlice { + elem := args[1] + switch elem.kind { + case vkSlice: + etSize := b.Prog.SizeOf(b.Prog.Elem(elem.Type)) + ret.Type = src.Type + ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("SliceAppend"), + src, b.SliceData(elem), b.SliceLen(elem), b.Prog.Val(int(etSize))).impl + return + case vkString: + etSize := b.Prog.SizeOf(b.Prog.Type(types.Typ[types.Byte], InGo)) + ret.Type = src.Type + ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("SliceAppend"), + src, b.StringData(elem), b.StringLen(elem), b.Prog.Val(int(etSize))).impl + return + } + } + } + case "print", "println": + ln := fn == "println" + ret.Type = b.Prog.Void() + for i, arg := range args { + if ln && i > 0 { + b.InlineCall(b.Func.Pkg.rtFunc("PrintString"), b.Str(" ")) + } + var fn string + var typ types.Type + switch arg.kind { + case vkBool: + fn = "PrintBool" + case vkSigned: + fn = "PrintInt" + typ = types.Typ[types.Int64] + case vkUnsigned: + fn = "PrintUint" + typ = types.Typ[types.Uint64] + case vkFloat: + fn = "PrintFloat" + typ = types.Typ[types.Float64] + case vkSlice: + fn = "PrintSlice" + case vkPtr, vkFuncPtr, vkFuncDecl, vkClosure, vkPyVarRef, vkPyFuncRef: + fn = "PrintPointer" + typ = types.Typ[types.UnsafePointer] + case vkString: + fn = "PrintString" + case vkInterface: + fn = "PrintIface" + // case vkComplex: + // fn = "PrintComplex" + default: + panic(fmt.Errorf("illegal types for operand: print %v", arg.RawType())) + } + if typ != nil && typ != arg.raw.Type { + arg = b.Convert(b.Prog.Type(typ, InGo), arg) + } + b.InlineCall(b.Func.Pkg.rtFunc(fn), arg) + } + if ln { + b.InlineCall(b.Func.Pkg.rtFunc("PrintString"), b.Str("\n")) + } + return } panic("todo") } diff --git a/ssa/package.go b/ssa/package.go index eeee0f24..bcfe246e 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -130,6 +130,7 @@ type aProgram struct { voidPtr Type boolTy Type cstrTy Type + cintTy Type stringTy Type uintptrTy Type intTy Type @@ -138,9 +139,16 @@ type aProgram struct { pyObjPPtr Type pyImpTy *types.Signature + pyNewList *types.Signature + pyListSetI *types.Signature + callArgs *types.Signature callNoArgs *types.Signature callOneArg *types.Signature + callFOArgs *types.Signature loadPyModS *types.Signature + getAttrStr *types.Signature + + paramObjPtr_ *types.Var NeedRuntime bool NeedPyInit bool @@ -328,6 +336,13 @@ func (p Program) Any() Type { return p.anyTy } +func (p Program) CInt() Type { + if p.cintTy == nil { // C.int + p.cintTy = p.rawType(types.Typ[types.Int32]) // TODO(xsw): support 64-bit + } + return p.cintTy +} + // Int returns int type. func (p Program) Int() Type { if p.intTy == nil { @@ -475,31 +490,38 @@ func (p *Package) WriteFile(file string) (err error) { // ----------------------------------------------------------------------------- +func (p Program) paramObjPtr() *types.Var { + if p.paramObjPtr_ == nil { + objPtr := p.PyObjectPtr().raw.Type + p.paramObjPtr_ = types.NewParam(token.NoPos, nil, "", objPtr) + } + return p.paramObjPtr_ +} + +// func(*char) *Object func (p Program) tyImportPyModule() *types.Signature { if p.pyImpTy == nil { charPtr := types.NewPointer(types.Typ[types.Int8]) - objPtr := p.PyObjectPtr().raw.Type params := types.NewTuple(types.NewParam(token.NoPos, nil, "", charPtr)) - results := types.NewTuple(types.NewParam(token.NoPos, nil, "", objPtr)) + results := types.NewTuple(p.paramObjPtr()) p.pyImpTy = types.NewSignatureType(nil, nil, nil, params, results, false) } return p.pyImpTy } +// func(*Object) *Object func (p Program) tyCallNoArgs() *types.Signature { if p.callNoArgs == nil { - objPtr := p.PyObjectPtr().raw.Type - paramObjPtr := types.NewParam(token.NoPos, nil, "", objPtr) - params := types.NewTuple(paramObjPtr) + params := types.NewTuple(p.paramObjPtr()) p.callNoArgs = types.NewSignatureType(nil, nil, nil, params, params, false) } return p.callNoArgs } +// func(*Object, *Object) *Object func (p Program) tyCallOneArg() *types.Signature { if p.callOneArg == nil { - objPtr := p.PyObjectPtr().raw.Type - paramObjPtr := types.NewParam(token.NoPos, nil, "", objPtr) + paramObjPtr := p.paramObjPtr() params := types.NewTuple(paramObjPtr, paramObjPtr) results := types.NewTuple(paramObjPtr) p.callOneArg = types.NewSignatureType(nil, nil, nil, params, results, false) @@ -507,29 +529,101 @@ func (p Program) tyCallOneArg() *types.Signature { return p.callOneArg } +// func(*Object, ...) *Object +func (p Program) tyCallFunctionObjArgs() *types.Signature { + if p.callFOArgs == nil { + paramObjPtr := p.paramObjPtr() + params := types.NewTuple(paramObjPtr, VArg()) + results := types.NewTuple(paramObjPtr) + p.callFOArgs = types.NewSignatureType(nil, nil, nil, params, results, true) + } + return p.callFOArgs +} + +/* +// func(*Object, *Object, *Object) *Object +func (p Program) tyCall() *types.Signature { + if p.callArgs == nil { + paramObjPtr := p.paramObjPtr() + params := types.NewTuple(paramObjPtr, paramObjPtr, paramObjPtr) + results := types.NewTuple(paramObjPtr) + p.callArgs = types.NewSignatureType(nil, nil, nil, params, results, false) + } + return p.callArgs +} +*/ + +// func(*Object, uintptr, *Object) cint +func (p Program) tyListSetItem() *types.Signature { + if p.pyListSetI == nil { + paramUintptr := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type) + paramCInt := types.NewParam(token.NoPos, nil, "", p.CInt().raw.Type) + paramObjPtr := p.paramObjPtr() + params := types.NewTuple(paramObjPtr, paramUintptr, paramObjPtr) + results := types.NewTuple(paramCInt) + p.pyListSetI = types.NewSignatureType(nil, nil, nil, params, results, false) + } + return p.pyListSetI +} + +// func(uintptr) *Object +func (p Program) tyNewList() *types.Signature { + if p.pyNewList == nil { + paramUintptr := types.NewParam(token.NoPos, nil, "", p.Uintptr().raw.Type) + params := types.NewTuple(paramUintptr) + results := types.NewTuple(p.paramObjPtr()) + p.pyNewList = types.NewSignatureType(nil, nil, nil, params, results, false) + } + return p.pyNewList +} + +// func(float64) *Object +func (p Program) tyFloatFromDouble() *types.Signature { + if p.callArgs == nil { + paramObjPtr := p.paramObjPtr() + paramFloat := types.NewParam(token.NoPos, nil, "", p.Float64().raw.Type) + params := types.NewTuple(paramFloat) + results := types.NewTuple(paramObjPtr) + p.callArgs = types.NewSignatureType(nil, nil, nil, params, results, false) + } + return p.callArgs +} + +// func(*Object, ...) func (p Program) tyLoadPyModSyms() *types.Signature { if p.loadPyModS == nil { - objPtr := p.PyObjectPtr().raw.Type - paramObjPtr := types.NewParam(token.NoPos, nil, "mod", objPtr) + paramObjPtr := p.paramObjPtr() params := types.NewTuple(paramObjPtr, VArg()) - p.loadPyModS = types.NewSignatureType(nil, nil, nil, params, nil, false) + p.loadPyModS = types.NewSignatureType(nil, nil, nil, params, nil, true) } return p.loadPyModS } +// func(*Objecg, *char) *Object +func (p Program) tyGetAttrString() *types.Signature { + if p.getAttrStr == nil { + charPtr := types.NewPointer(types.Typ[types.Int8]) + paramObjPtr := p.paramObjPtr() + params := types.NewTuple(paramObjPtr, types.NewParam(token.NoPos, nil, "", charPtr)) + results := types.NewTuple(paramObjPtr) + p.getAttrStr = types.NewSignatureType(nil, nil, nil, params, results, false) + } + return p.getAttrStr +} + // PyInit initializes Python for a main package. func (p Package) PyInit() bool { if fn := p.FuncOf("main"); fn != nil { b := fn.NewBuilder() - b.SetBlockEx(fn.Block(0), AtStart).CallPyInit() + b.SetBlockEx(fn.Block(0), AtStart).callPyInit() b.Dispose() return true } return false } -// NewPyModVar creates a new global variable for a Python module. -func (p Package) NewPyModVar(name string, doInit bool) Global { +// PyNewModVar creates a new global variable for a Python module. +func (p Package) PyNewModVar(name string, doInit bool) Global { if v, ok := p.pymods[name]; ok { return v } @@ -544,18 +638,18 @@ func (p Package) NewPyModVar(name string, doInit bool) Global { return g } -// ImportPyMod imports a Python module. -func (b Builder) ImportPyMod(path string) Expr { +// PyImportMod imports a Python module. +func (b Builder) PyImportMod(path string) Expr { pkg := b.Func.Pkg fnImp := pkg.pyFunc("PyImport_ImportModule", b.Prog.tyImportPyModule()) return b.Call(fnImp, b.CStr(path)) } -// LoadPyModSyms loads python objects from specified module. -func (b Builder) LoadPyModSyms(modName string, objs ...PyObjRef) Expr { +// PyLoadModSyms loads python objects from specified module. +func (b Builder) PyLoadModSyms(modName string, objs ...PyObjRef) Expr { pkg := b.Func.Pkg fnLoad := pkg.pyFunc("llgoLoadPyModSyms", b.Prog.tyLoadPyModSyms()) - modPtr := pkg.NewPyModVar(modName, false).Expr + modPtr := pkg.PyNewModVar(modName, false).Expr mod := b.Load(modPtr) args := make([]Expr, 1, len(objs)*2+2) args[0] = mod @@ -583,16 +677,76 @@ func (b Builder) pyCall(fn Expr, args []Expr) (ret Expr) { call := pkg.pyFunc("PyObject_CallNoArgs", prog.tyCallNoArgs()) ret = b.Call(call, fn) case 1: - call := pkg.pyFunc("PyObject_CallOneArg", prog.tyCallOneArg()) - ret = b.Call(call, fn, args[0]) + if !sig.Variadic() { + call := pkg.pyFunc("PyObject_CallOneArg", prog.tyCallOneArg()) + return b.Call(call, fn, args[0]) + } + fallthrough default: - panic("todo") + call := pkg.pyFunc("PyObject_CallFunctionObjArgs", prog.tyCallFunctionObjArgs()) + n = len(args) + callargs := make([]Expr, n+2) + callargs[0] = fn + copy(callargs[1:], args) + callargs[n+1] = prog.PyNull() + ret = b.Call(call, callargs...) } return } -// CallPyInit calls Py_Initialize. -func (b Builder) CallPyInit() (ret Expr) { +// PyNewList(n uintptr) *Object +func (b Builder) PyNewList(n Expr) (ret Expr) { + prog := b.Prog + pkg := b.Func.Pkg + fn := pkg.pyFunc("PyList_New", prog.tyNewList()) + return b.Call(fn, n) +} + +// PyListSetItem(list *Object, index uintptr, item *Object) c.Int +func (b Builder) PyListSetItem(list, index, item Expr) (ret Expr) { + prog := b.Prog + pkg := b.Func.Pkg + fn := pkg.pyFunc("PyList_SetItem", prog.tyListSetItem()) + return b.Call(fn, list, index, item) +} + +// PyList(args ...Expr) *Object +func (b Builder) PyList(args ...Expr) (ret Expr) { + prog := b.Prog + n := len(args) + uintPtr := prog.Uintptr() + list := b.PyNewList(prog.IntVal(uint64(n), uintPtr)) + for i, arg := range args { + b.PyListSetItem(list, prog.IntVal(uint64(i), uintPtr), b.PyVal(arg)) + } + return list +} + +// PyVal(v any) *Object +func (b Builder) PyVal(v Expr) (ret Expr) { + switch t := v.raw.Type.(type) { + case *types.Basic: + switch t.Kind() { + case types.Float64: + return b.PyFloat(v) + default: + panic("PyVal: todo") + } + default: + return v + } +} + +// PyFloat(fltVal float64) *Object +func (b Builder) PyFloat(fltVal Expr) (ret Expr) { + prog := b.Prog + pkg := b.Func.Pkg + fn := pkg.pyFunc("PyFloat_FromDouble", prog.tyFloatFromDouble()) + return b.Call(fn, fltVal) +} + +// callPyInit calls Py_Initialize. +func (b Builder) callPyInit() (ret Expr) { fn := b.Func.Pkg.pyFunc("Py_Initialize", NoArgsNoRet) return b.Call(fn) } diff --git a/ssa/ssa_test.go b/ssa/ssa_test.go index b2bfe311..13a98552 100644 --- a/ssa/ssa_test.go +++ b/ssa/ssa_test.go @@ -102,7 +102,9 @@ func TestCvtType(t *testing.T) { func TestUserdefExpr(t *testing.T) { b := &phisExprTy{} + c := &pyVarTy{} _ = b.String() + _ = c.String() test := func(a types.Type) { defer func() { if r := recover(); r == nil { @@ -112,6 +114,7 @@ func TestUserdefExpr(t *testing.T) { a.Underlying() } test(b) + test(c) } func TestAny(t *testing.T) { @@ -143,12 +146,12 @@ func TestPyFunc(t *testing.T) { prog.SetPython(py) pkg := prog.NewPackage("bar", "foo/bar") sig := types.NewSignatureType(nil, nil, nil, nil, nil, false) - a := pkg.NewPyFunc("a", sig, false) - if pkg.NewPyFunc("a", sig, false) != a { + a := pkg.PyNewFunc("a", sig, false) + if pkg.PyNewFunc("a", sig, false) != a { t.Fatal("NewPyFunc(a) failed") } - foo := pkg.NewPyModVar("foo", false) - if pkg.NewPyModVar("foo", false) != foo { + foo := pkg.PyNewModVar("foo", false) + if pkg.PyNewModVar("foo", false) != foo { t.Fatal("NewPyModVar(foo) failed") } } @@ -399,8 +402,8 @@ func TestPrintf(t *testing.T) { pchar := types.NewPointer(types.Typ[types.Int8]) params := types.NewTuple(types.NewVar(0, nil, "format", pchar), VArg()) rets := types.NewTuple(types.NewVar(0, nil, "", types.Typ[types.Int32])) - sig := types.NewSignatureType(nil, nil, nil, params, rets, false) - pkg.NewFunc("printf", sig, InGo) + sig := types.NewSignatureType(nil, nil, nil, params, rets, true) + pkg.NewFunc("printf", sig, InC) assertPkg(t, pkg, `; ModuleID = 'foo/bar' source_filename = "foo/bar" diff --git a/ssa/type.go b/ssa/type.go index 735a3d90..17f5bd07 100644 --- a/ssa/type.go +++ b/ssa/type.go @@ -44,7 +44,12 @@ const ( vkFuncPtr vkClosure vkPyFuncRef + vkPyVarRef vkTuple + vkSlice + vkArray + vkMap + vkInterface vkPhisExpr = -1 ) @@ -103,7 +108,10 @@ func (p Program) Pointer(typ Type) Type { } func (p Program) Elem(typ Type) Type { - elem := typ.raw.Type.(*types.Pointer).Elem() + elem := typ.raw.Type.(interface { + types.Type + Elem() types.Type + }).Elem() return p.rawType(elem) } @@ -235,11 +243,11 @@ func (p Program) toType(raw types.Type) Type { elem := p.rawType(t.Elem()) return &aType{llvm.PointerType(elem.ll, 0), typ, vkPtr} case *types.Interface: - return &aType{p.rtIface(), typ, vkInvalid} + return &aType{p.rtIface(), typ, vkInterface} case *types.Slice: - return &aType{p.rtSlice(), typ, vkInvalid} + return &aType{p.rtSlice(), typ, vkSlice} case *types.Map: - return &aType{p.rtMap(), typ, vkInvalid} + return &aType{p.rtMap(), typ, vkMap} case *types.Struct: ll, kind := p.toLLVMStruct(t) return &aType{ll, typ, kind} @@ -249,7 +257,7 @@ func (p Program) toType(raw types.Type) Type { return &aType{p.toLLVMFuncPtr(t), typ, vkFuncPtr} case *types.Array: elem := p.rawType(t.Elem()) - return &aType{llvm.ArrayType(elem.ll, int(t.Len())), typ, vkInvalid} + return &aType{llvm.ArrayType(elem.ll, int(t.Len())), typ, vkArray} case *types.Chan: } panic(fmt.Sprintf("toLLVMType: todo - %T\n", typ)) @@ -313,7 +321,7 @@ func (p Program) toLLVMTypes(t *types.Tuple, n int) (ret []llvm.Type) { func (p Program) toLLVMFunc(sig *types.Signature) llvm.Type { tParams := sig.Params() n := tParams.Len() - hasVArg := HasVArg(tParams, n) + hasVArg := sig.Variadic() if hasVArg { n-- } diff --git a/ssa/type_cvt.go b/ssa/type_cvt.go index e8bd1c3d..9bf505b6 100644 --- a/ssa/type_cvt.go +++ b/ssa/type_cvt.go @@ -66,6 +66,27 @@ func (p Program) FuncDecl(sig *types.Signature, bg Background) Type { return &aType{p.toLLVMFunc(sig), rawType{sig}, vkFuncDecl} } +/* +// cvtCxFunc converts a C extended function type into raw type. +func cvtCxFunc(sig *types.Signature, recv *types.Var) *types.Signature { + if sig.Variadic() { + // convert printf-like function type + tParams := sig.Params() + n := tParams.Len() + params := make([]*types.Var, n) + n-- + for i := 0; i < n; i++ { + params[i] = tParams.At(i) + } + params[n] = VArg() + sig = types.NewSignatureType(nil, nil, nil, types.NewTuple(params...), sig.Results(), true) + panic("todo") + } + sig = FuncAddCtx(recv, sig) + return sig +} +*/ + // Closure creates a closture type for a function. func (p Program) Closure(fn Type) Type { sig := fn.raw.Type.(*types.Signature) @@ -151,8 +172,9 @@ func (p goTypes) cvtFunc(sig *types.Signature, recv *types.Var) (raw *types.Sign } params, cvt1 := p.cvtTuple(sig.Params()) results, cvt2 := p.cvtTuple(sig.Results()) - if cvt1 || cvt2 { - return types.NewSignatureType(nil, nil, nil, params, results, sig.Variadic()) + if cvt1 || cvt2 || sig.Variadic() { + // variadic always is false in raw type for Go function + return types.NewSignatureType(nil, nil, nil, params, results, false) } return sig } diff --git a/x/cjson/README.md b/x/cjson/README.md new file mode 100644 index 00000000..b1326213 --- /dev/null +++ b/x/cjson/README.md @@ -0,0 +1,35 @@ +LLGo wrapper of DaveGamble/cJSON +===== +[![Build Status](https://github.com/goplus/cjson/actions/workflows/go.yml/badge.svg)](https://github.com/goplus/cjson/actions/workflows/go.yml) +[![GitHub release](https://img.shields.io/github/v/tag/goplus/cjson.svg?label=release)](https://github.com/goplus/cjson/releases) +[![GoDoc](https://pkg.go.dev/badge/github.com/goplus/cjson.svg)](https://pkg.go.dev/github.com/goplus/cjson) +[![Compiler](https://img.shields.io/badge/compiler-llgo-darkgreen.svg)](https://github.com/goplus/llgo) +[![Language](https://img.shields.io/badge/language-Go+-blue.svg)](https://github.com/goplus/gop) + +## How to install + +```sh +git clone https://github.com/goplus/cjson.git +cd cjson +git submodule init +git submodule update +mkdir build.dir +cd build.dir +cmake ../cJSON +sudo make install +``` + +## Demos + +The `_demo` directory contains our demos (it start with `_` to prevent the `go` command from compiling it): + +* [mkjson](_demo/mkjson/mkjson.go): create a json object and print it + +### How to run demos + +To run the demos in directory `_demo`: + +```sh +cd # eg. cd _demo/mkjson +llgo run . +``` diff --git a/x/cjson/_demo/mkjson/mkjson.go b/x/cjson/_demo/mkjson/mkjson.go new file mode 100644 index 00000000..68e08649 --- /dev/null +++ b/x/cjson/_demo/mkjson/mkjson.go @@ -0,0 +1,27 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/x/cjson" +) + +func main() { + mod := cjson.Object() + mod.SetItem(c.Str("name"), cjson.String(c.Str("math"))) + + syms := cjson.Array() + + fn := cjson.Object() + fn.SetItem(c.Str("name"), cjson.String(c.Str("sqrt"))) + fn.SetItem(c.Str("sig"), cjson.String(c.Str("(x, /)"))) + syms.AddItem(fn) + + v := cjson.Object() + v.SetItem(c.Str("name"), cjson.String(c.Str("pi"))) + syms.AddItem(v) + + mod.SetItem(c.Str("items"), syms) + + c.Printf(c.Str("%s\n"), mod.CStr()) + mod.Delete() +} diff --git a/x/cjson/cjson.go b/x/cjson/cjson.go new file mode 100644 index 00000000..e91e86c9 --- /dev/null +++ b/x/cjson/cjson.go @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * 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 cjson + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" +) + +const ( + LLGoPackage = "link: cjson" +) + +// llgo:type C +type JSON struct { + Unused [0]byte +} + +//go:linkname Null C.cJSON_CreateNull +func Null() *JSON + +//go:linkname True C.cJSON_CreateTrue +func True() *JSON + +//go:linkname False C.cJSON_CreateFalse +func False() *JSON + +//go:linkname Bool C.cJSON_CreateBool +func Bool(boolean c.Int) *JSON + +//go:linkname Number C.cJSON_CreateNumber +func Number(num float64) *JSON + +//go:linkname String C.cJSON_CreateString +func String(str *c.Char) *JSON + +//go:linkname Array C.cJSON_CreateArray +func Array() *JSON + +//go:linkname Object C.cJSON_CreateObject +func Object() *JSON + +// raw json +// +//go:linkname Raw C.cJSON_CreateRaw +func Raw(raw *c.Char) *JSON + +// Create a string where valuestring references a string so +// it will not be freed by Delete +// +//go:linkname StringRef C.cJSON_CreateStringReference +func StringRef(str *c.Char) *JSON + +// Create an object that only references it's elements so +// they will not be freed by Delete +// +//go:linkname ObjectRef C.cJSON_CreateObjectReference +func ObjectRef(child *JSON) *JSON + +// Create an array that only references it's elements so +// they will not be freed by Delete +// +//go:linkname ArrayRef C.cJSON_CreateArrayReference +func ArrayRef(child *JSON) *JSON + +// Delete a JSON entity and all subentities. +// +// llgo:link (*JSON).Delete C.cJSON_Delete +func (o *JSON) Delete() {} + +// Append item to the specified array. +// +// llgo:link (*JSON).AddItem C.cJSON_AddItemToArray +func (o *JSON) AddItem(item *JSON) c.Int { return 0 } + +// Append item to the specified object. +// +// llgo:link (*JSON).SetItem C.cJSON_AddItemToObject +func (o *JSON) SetItem(key *c.Char, item *JSON) c.Int { return 0 } + +// llgo:link (*JSON).CStr C.cJSON_PrintUnformatted +func (o *JSON) CStr() *c.Char { return nil } + +// Render a JSON entity to text for transfer/storage. +// +// llgo:link (*JSON).Print C.cJSON_Print +func (o *JSON) Print() *c.Char { return nil } + +// Render a JSON entity to text for transfer/storage without any formatting. +// +// llgo:link (*JSON).PrintUnformatted C.cJSON_PrintUnformatted +func (o *JSON) PrintUnformatted() *c.Char { return nil } + +// Render a JSON entity to text using a buffered strategy. +// +// prebuffer is a guess at the final size. guessing well reduces reallocation. +// +// fmt=0 gives unformatted, =1 gives formatted. +// +// llgo:link (*JSON).PrintBuffered C.cJSON_PrintBuffered +func (o *JSON) PrintBuffered(prebuffer c.Int, fmt c.Int) *c.Char { return nil } diff --git a/x/cjson/llgo_autogen.lla b/x/cjson/llgo_autogen.lla new file mode 100644 index 00000000..a5c17d01 Binary files /dev/null and b/x/cjson/llgo_autogen.lla differ diff --git a/x/sqlite/README.md b/x/sqlite/README.md new file mode 100644 index 00000000..f6e86dc2 --- /dev/null +++ b/x/sqlite/README.md @@ -0,0 +1,35 @@ +LLGo wrapper of sqlite +===== +[![Build Status](https://github.com/goplus/sqlite/actions/workflows/go.yml/badge.svg)](https://github.com/goplus/sqlite/actions/workflows/go.yml) +[![GitHub release](https://img.shields.io/github/v/tag/goplus/sqlite.svg?label=release)](https://github.com/goplus/sqlite/releases) +[![GoDoc](https://pkg.go.dev/badge/github.com/goplus/sqlite.svg)](https://pkg.go.dev/github.com/goplus/sqlite) +[![Compiler](https://img.shields.io/badge/compiler-llgo-darkgreen.svg)](https://github.com/goplus/llgo) +[![Language](https://img.shields.io/badge/language-Go+-blue.svg)](https://github.com/goplus/gop) + +## How to install + +```sh +git clone https://github.com/goplus/sqlite.git +cd sqlite +git submodule init +git submodule update +mkdir build.dir +cd build.dir +../sqlite/configure --enable-shared +sudo make install +``` + +## Demos + +The `_demo` directory contains our demos (it start with `_` to prevent the `go` command from compiling it): + +* [sqlitedemo](_demo/sqlitedemo/demo.go): a basic sqlite demo + +### How to run demos + +To run the demos in directory `_demo`: + +```sh +cd # eg. cd _demo/sqlitedemo +llgo run . +``` diff --git a/_demo/sqlite/sqlite.go b/x/sqlite/_demo/sqlitedemo/demo.go similarity index 100% rename from _demo/sqlite/sqlite.go rename to x/sqlite/_demo/sqlitedemo/demo.go diff --git a/x/sqlite/llgo.cfg b/x/sqlite/llgo.cfg deleted file mode 100644 index 3b457a74..00000000 --- a/x/sqlite/llgo.cfg +++ /dev/null @@ -1,12 +0,0 @@ -{ - "cl": [ - "mkdir build.dir", - "cd build.dir", - "../sqlite/configure", - "make", - "clang -emit-llvm -S -o ../llgo_autogen.ll -c sqlite3.c", - "cd ..", - "llgen .", - "rm llgo_autogen.lla; zip llgo_autogen.lla llgo_autogen.ll sqlite.ll", - ] -} diff --git a/x/sqlite/llgo_autogen.lla b/x/sqlite/llgo_autogen.lla index 6aa88aa4..64a7e929 100644 Binary files a/x/sqlite/llgo_autogen.lla and b/x/sqlite/llgo_autogen.lla differ diff --git a/x/sqlite/sqlite b/x/sqlite/sqlite deleted file mode 160000 index b74eb00e..00000000 --- a/x/sqlite/sqlite +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b74eb00e2cb05d9749859e6fbe77d229ad1dc1e1 diff --git a/x/sqlite/sqlite.go b/x/sqlite/sqlite.go index 275d8379..133a5b8f 100644 --- a/x/sqlite/sqlite.go +++ b/x/sqlite/sqlite.go @@ -29,15 +29,17 @@ type ( ) const ( - LLGoPackage = "link" + LLGoPackage = "link: sqlite3" ) // llgo:type C type Sqlite3 struct { + Unused [8]byte } // llgo:type C type Stmt struct { + Unused [8]byte } // ----------------------------------------------------------------------------- diff --git a/x/sqlite/sqlite.ll b/x/sqlite/sqlite.ll deleted file mode 100644 index d4bdb25a..00000000 --- a/x/sqlite/sqlite.ll +++ /dev/null @@ -1,99 +0,0 @@ -; ModuleID = 'github.com/goplus/llgo/x/sqlite' -source_filename = "github.com/goplus/llgo/x/sqlite" - -%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } - -@"github.com/goplus/llgo/x/sqlite.init$guard" = global ptr null - -define ptr @"(*github.com/goplus/llgo/x/sqlite.Errno).Errstr"(ptr %0) { -_llgo_0: - %1 = load i32, ptr %0, align 4 - %2 = call ptr @sqlite3_errstr(i32 %1) - ret ptr %2 -} - -define { ptr, i32 } @"github.com/goplus/llgo/x/sqlite.Open"(ptr %0) { -_llgo_0: - %1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8) - %2 = call i32 @sqlite3_open(ptr %0, ptr %1) - %3 = load ptr, ptr %1, align 8 - %mrv = insertvalue { ptr, i32 } poison, ptr %3, 0 - %mrv1 = insertvalue { ptr, i32 } %mrv, i32 %2, 1 - ret { ptr, i32 } %mrv1 -} - -define { ptr, i32 } @"github.com/goplus/llgo/x/sqlite.OpenV2"(ptr %0, i32 %1, ptr %2) { -_llgo_0: - %3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8) - %4 = call i32 @sqlite3_open_v2(ptr %0, ptr %3, i32 %1, ptr %2) - %5 = load ptr, ptr %3, align 8 - %mrv = insertvalue { ptr, i32 } poison, ptr %5, 0 - %mrv1 = insertvalue { ptr, i32 } %mrv, i32 %4, 1 - ret { ptr, i32 } %mrv1 -} - -define { ptr, i32 } @"(*github.com/goplus/llgo/x/sqlite.Sqlite3).Prepare"(ptr %0, %"github.com/goplus/llgo/internal/runtime.String" %1, ptr %2) { -_llgo_0: - %3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8) - %4 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %1, 0 - %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %1, 1 - %6 = trunc i64 %5 to i32 - %7 = call i32 @sqlite3_prepare(ptr %0, ptr %4, i32 %6, ptr %3, ptr %2) - %8 = load ptr, ptr %3, align 8 - %mrv = insertvalue { ptr, i32 } poison, ptr %8, 0 - %mrv1 = insertvalue { ptr, i32 } %mrv, i32 %7, 1 - ret { ptr, i32 } %mrv1 -} - -define { ptr, i32 } @"(*github.com/goplus/llgo/x/sqlite.Sqlite3).PrepareV2"(ptr %0, %"github.com/goplus/llgo/internal/runtime.String" %1, ptr %2) { -_llgo_0: - %3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8) - %4 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %1, 0 - %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %1, 1 - %6 = trunc i64 %5 to i32 - %7 = call i32 @sqlite3_prepare_v2(ptr %0, ptr %4, i32 %6, ptr %3, ptr %2) - %8 = load ptr, ptr %3, align 8 - %mrv = insertvalue { ptr, i32 } poison, ptr %8, 0 - %mrv1 = insertvalue { ptr, i32 } %mrv, i32 %7, 1 - ret { ptr, i32 } %mrv1 -} - -define { ptr, i32 } @"(*github.com/goplus/llgo/x/sqlite.Sqlite3).PrepareV3"(ptr %0, %"github.com/goplus/llgo/internal/runtime.String" %1, i32 %2, ptr %3) { -_llgo_0: - %4 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 8) - %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %1, 0 - %6 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %1, 1 - %7 = trunc i64 %6 to i32 - %8 = call i32 @sqlite3_prepare_v3(ptr %0, ptr %5, i32 %7, i32 %2, ptr %4, ptr %3) - %9 = load ptr, ptr %4, align 8 - %mrv = insertvalue { ptr, i32 } poison, ptr %9, 0 - %mrv1 = insertvalue { ptr, i32 } %mrv, i32 %8, 1 - ret { ptr, i32 } %mrv1 -} - -define void @"github.com/goplus/llgo/x/sqlite.init"() { -_llgo_0: - %0 = load i1, ptr @"github.com/goplus/llgo/x/sqlite.init$guard", align 1 - br i1 %0, label %_llgo_2, label %_llgo_1 - -_llgo_1: ; preds = %_llgo_0 - store i1 true, ptr @"github.com/goplus/llgo/x/sqlite.init$guard", align 1 - br label %_llgo_2 - -_llgo_2: ; preds = %_llgo_1, %_llgo_0 - ret void -} - -declare ptr @sqlite3_errstr(i32) - -declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) - -declare i32 @sqlite3_open(ptr, ptr) - -declare i32 @sqlite3_open_v2(ptr, ptr, i32, ptr) - -declare i32 @sqlite3_prepare(ptr, ptr, i32, ptr, ptr) - -declare i32 @sqlite3_prepare_v2(ptr, ptr, i32, ptr, ptr) - -declare i32 @sqlite3_prepare_v3(ptr, ptr, i32, i32, ptr, ptr)