GithubHelp home page GithubHelp logo

ivy's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ivy's Issues

Which version of Go is ivy compatible with?

I'm trying to simply run, go get github.com/robpike/ivy, but get the following errors:

# robpike.io/ivy/value
value/asin.go:22: undefined: big.Float
value/asin.go:44: undefined: big.Float
value/asin.go:53: undefined: big.Float
value/asin.go:136: undefined: big.Float
value/bigfloat.go:14: undefined: big.Float

When checking https://golang.org/pkg/math/big/ I don't see anything documented for big.Float

inverted arithmetic in matrix op vector

Been staring at this for a while and I think it must be a bug.
A surprising one, but either that or I've missed something quite fundamental.

(2 2 rho 2 3 5 7) / (11 13)
11/2 13/3
11/5 13/7

vector-indexed indexing and assignment don't generalize

Consider:

% ivy
x = 3 4 rho iota 9

x[2][2 3]
6 7

This works fine today. But now consider

x[2 3]
5 6 7 8
9 1 2 3

x[2 3][1 4]
index 4 out of range (shape (2 4))

y=x[2 3]; y[1 4]
index 4 out of range (shape (2 4))

Here, x[2 3][1 4] is being treated the same as the y= version,
just without the y.

There is no way in Ivy today to extract a sub-shape of a matrix,
what in APL would be x[2 3; 1 4].

I started working on making vector-indexed assignment work,
so that things like APL's (from tryapl.org):

      x ← 3 4 ⍴⍳9
      x[2 3; 1 4] ← 0
      x
1 2 3 4
0 6 7 0
0 1 2 0

or

      x ← 3 4 ⍴⍳12
      x[2 3; 1 4] ← -2 2 ⍴⍳4
      x
 1  2  3  4
¯1  6  7 ¯2
¯3 10 11 ¯4

would work. Those both work (in Ivy syntax) in my copy now,
but then I noticed that x[2 3][1 4] = x[2 3][1 4] does not,
because x[2 3][1 4] didn't mean what I expected it to.

I see three possible options:

  1. Do nothing, just don't provide that functionality.

  2. Switch to ; for separating indexes, like APL.

  3. Define that x[i][j][k] is processing 3 dimensions of x, not ((x[i])[j])[k]. Perhaps code that wants the latter interpretation can add parens.

Perhaps there are more.

demo: crash since Config.bigOrigin is nil

Reproducer:

) demo
# This is a demo of ivy. Type a newline to advance to each new step. Type one now.
? 2 ** 32
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x49ace4]

goroutine 6 [running]:
robpike.io/ivy/parse.(*Parser).runFromReader.func1()
        /home/aurelien/godev/pkg/mod/robpike.io/[email protected]/parse/special.go:358 +0x1ea
panic({0x4fa4e0, 0x5fbc80})
        /home/aurelien/sdk/go1.17.4/src/runtime/panic.go:1038 +0x215
robpike.io/ivy/parse.(*Parser).runUntilError.func1()
        /home/aurelien/godev/pkg/mod/robpike.io/[email protected]/parse/special.go:384 +0x1ea
panic({0x4fa4e0, 0x5fbc80})
        /home/aurelien/sdk/go1.17.4/src/runtime/panic.go:1038 +0x215
math/big.(*Int).Add(0xc0000a8080, 0x49a93f, 0x0)
        /home/aurelien/sdk/go1.17.4/src/math/big/int.go:118 +0x24
robpike.io/ivy/value.bigIntRand({0x544d70, 0xc0000753e0}, 0xffffffffffffffff, 0x4108b7)
        /home/aurelien/godev/pkg/mod/robpike.io/[email protected]/value/unary.go:56 +0x77
robpike.io/ivy/value.unaryBigIntOp({0x544d70, 0xc0000753e0}, 0x5201e0, {0x544eb0, 0xc0000a8060})
        /home/aurelien/godev/pkg/mod/robpike.io/[email protected]/value/unary.go:21 +0x8d
robpike.io/ivy/value.init.1.func2({0x544d70, 0xc0000753e0}, {0x544eb0, 0xc0000a8060})
        /home/aurelien/godev/pkg/mod/robpike.io/[email protected]/value/unary.go:137 +0x71
robpike.io/ivy/value.(*unaryOp).EvalUnary(0xc00007e050, {0x544d70, 0xc0000753e0}, {0x544eb0, 0xc0000a8060})
        /home/aurelien/godev/pkg/mod/robpike.io/[email protected]/value/eval.go:52 +0x119
robpike.io/ivy/exec.(*Context).EvalUnary(0xc0000753e0, {0xc0000a2020, 0x1}, {0x544eb0, 0xc0000a8060})
        /home/aurelien/godev/pkg/mod/robpike.io/[email protected]/exec/context.go:138 +0x128
robpike.io/ivy/parse.(*unary).Eval(0xc0000a8000, {0x544d70, 0xc0000753e0})
        /home/aurelien/godev/pkg/mod/robpike.io/[email protected]/parse/parse.go:193 +0x62
robpike.io/ivy/parse.(*Parser).runUntilError(0xc00009c000, {0x50f24a, 0x0})
        /home/aurelien/godev/pkg/mod/robpike.io/[email protected]/parse/special.go:389 +0x113
robpike.io/ivy/parse.(*Parser).runFromReader(0xc000154d80, {0x544d70, 0xc0000753e0}, {0x50f24a, 0x0}, {0x541ca0, 0xc000176d80}, 0x0)
        /home/aurelien/godev/pkg/mod/robpike.io/[email protected]/parse/special.go:362 +0x3ca
created by robpike.io/ivy/parse.DemoRunner
        /home/aurelien/godev/pkg/mod/robpike.io/[email protected]/parse/special.go:434 +0x1ef

The fix is easy but since this is relatively minor (only happens during demo) and since there are different ways to fix it I'm not opening a PR, preferring to check if you're interested to fix this, and how.

When the demo starts, DemoRunner is provided a zero-valued default config.Config. Config.bigOrigin is a nil big.Int. Also, Config.BigOrigin() doesn't call Config.init(). Finally, Config.init doesn't initialize Config.bigOrigin.

One possible fix:

diff --git a/config/config.go b/config/config.go
index 74b2a8e..4c210d3 100644
--- a/config/config.go
+++ b/config/config.go
@@ -57,6 +57,7 @@ func (c *Config) init() {
 		c.output = os.Stdout
 		c.errOutput = os.Stderr
 		c.origin = 1
+		c.bigOrigin = big.NewInt(1)
 		c.seed = time.Now().UnixNano()
 		c.source = rand.NewSource(c.seed)
 		c.random = rand.New(c.source)
@@ -171,6 +172,7 @@ func (c *Config) Origin() int {
 
 // BigOrigin returns the index origin as a *big.Int.
 func (c *Config) BigOrigin() *big.Int {
+	c.init()
 	return c.bigOrigin
 }

Inconsistent order of operations?

Given that "binary operators apply to the operand immediately to the left and to everything to the right", I was expecting:

(2/3**2) == (2/(3**2)) , and not (2/3**2) == ((2/3)**2)) as it seems to be.

And fwiw, if one replaces division with multiplication, one gets as expected:

(2*3**2) == (2*(3**2)) ( and not (2*3**2) == ((2*3)**2) )

I did not find any explanation for this behavior either on https://godoc.org/robpike.io/ivy or on https://en.wikipedia.org/wiki/APL_syntax_and_symbols.

What am I missing please?

WebAssembly port

Go 1.11 has added an experimental port to WebAssembly. ivy already supports iOS and Android via x/mobile, and if I'm not mistaken, the code for that lives in this repository.

@robpike, are you interested in a WebAssembly port being added to this repository?

I've ported ivy to run in a browser via GopherJS in the past, see demo at https://dmitri.shuralyov.com/projects/ivy/. It was very easy to port it to use syscall/js package and compile with GOOS=js GOARCH=wasm. See shurcooL/ivybrowser@44e3bb3.

If you choose to accept it, I'm happy to help maintain it. If you'd rather not, that's fine, I will just keep it in my fork then.

op on a vector using text

op pal x = t = '%d' text x; (rot t) *.== t

Is an attempt at palindrome, and it almost works:

pal 1001
1

pal 98
0

I expected:

pal 1001 1002
1 0

But I get

pal 1001 1002
0

The text operator seems to include spaces, so maybe that's part of the problem?

rho "%d" text 1 2 3
5

Arithmetic operator precedence

Since Ivy is a calculator, I would expect it honours conventional precedence of arithmetic operators. However, 2-1-1 gives 2 (instead of 0), and 2-1+1 gives 0 (instead of 2).

OS: iOS 9.1

value: binary iota is incorrect

Given

scalar binop vector

the scalar will be promoted to vector; that's how ivy works. But it's not how APL works. It usually doesn't matter, but for binary iota (index) it does. 3 iota 3 should yield 3, not 1. It yields 1 because the LHS becomes 3 3 3.

Access last result

For interactive use, it would be nice if the last result could be accessed somehow (e.g. via a variable "ans" or similar that is set in the repl).

loop termination condition seems wrong

Unless I am missing something, the termination condition for the loop seems incorrect:

if l.delta.Cmp(l.prevDelta) == 0

https://github.com/robpike/ivy/blob/master/value/loop.go#L53

delta is the delta between the current estimate and the previous estimate
prevDelta is the delta between the previous estimate and the one before that

Why should we stop if the deltas are the same? If my iterative method happens to generate estimates 0, 10, 20, 30, 33, 35, 34, why should we stop at 30?

Seems like the correct thing to check is if delta is 0? I am guessing that this is how this condition ends up working in practice (it detects a string of 0s), as it's highly unlikely to actually see a string of equal but non-zero deltas.

@robpike @mjibson

Ivy seems to "crash" on latest iOS

After updating my iPhone 5s to the latest iOS release (10.0.1, 14A403), Ivy briefly comes up but then disappears (crashes?) and I'm back at the home screen.

Double-clicking the Home button to look at all running apps shows Ivy running, with its last result showing, but clicking on it results in the same crash again.

Probably not Ivy- but x/mobile specific.

possible order of evaluation bug

Here is a way to test order of evaluation.

# Order of evaluation
tags = 0 rho 0
op f tag = tags; tags = tags, tag; 1
op order x = x = tags; tags = 0 rho 0; x
m = 1 1 rho 0
order (f 1) + (f 2)
order m[f 1; f 2]
order +/ (f 1) (f 2)
	2 1
	2 1
	1 2

It shows that in (f 1) + (f 2), (f 2) runs first.
And in m[f 1; f 2], f 2 runs first, which I preserved from the binary case.
But it also shows that in +/ (f 1) (f 2) and g (f 1) (f 2), (f 1) runs first.

This confused me because to use a complex
expression multiple times,
the idiom from APL is something like

m+m=complex thing

but it turns out to use it multiple times in a vector its the other way around:

+/ (m=complex thing) m 

Is this correct?
Is it documented somewhere?

locals vs globals is unclear and can change unexpectedly

What does the variable name x mean in a function (user-defined operator) body?
Right now the rule in function f is:
(1) if x is the name of one of f's argument, then x refers to that local variable.
(2) if x is the name of a global, then x refers to that global.
(3) otherwise, x refers to a local variable (possibly not yet created).

I sent PR #81 to fix a bug where Ivy wasn't respecting these rules (a definite bug fix),
but I wonder whether the rules should be changed anyway.
Consider some function that uses (intended as local) variables in its implementation,
like this not-very-good Fibonacci function:

% ivy
op fib n =
	n <= 1: n
	a = fib n-1
	b = fib n-2
	a + b


fib 10
55

Now suppose that is loaded from a library and we don't know how its implemented.
And we are playing around:

% ivy -f fib.ivy
fib 10
55

a
undefined variable "a"

a = 1

fib 10
5

Creating the global named 'a' changes the meaning of the fib function:
what used to be a local variable becomes a global variable.
This means that functions using local variables aren't robust
against the creation of globals that happen to use the same names.
I think probably something should be done about that.

Python has this problem too, and solves it by saying that the first
use of a variable in the function determines what it is.
If the first use is a write, then the name refers to a new local.
If the first use is a read, then the name can refer to a global.
If you want to override this, the special statement 'global x'
forces the name to refer to a global.
Use is not strictly in writing-code order: x = x+1 reads x before writing it,
so it refers to a global if one exists.
Ivy could adopt this rule too, but in Python, I have a hard time remembering it,
and while it usually does the right thing, it's mysterious when it doesn't.
Definitely one option though.

Another option would be to require saying 'global x' any time you
want to refer to a global. That would be easier to remember at least.
but maybe a bit too annoying.

A third option would be, in a nod to Go's export rule, to say that
inside functions, capitalized variables are always globals,
while lowercase variables are always locals.
This would make it very clear at all mentions of a variable
whether it was private to the function or not.
You could still manipulate lowercase globals in the interactive loop,
but those would not be available to functions.
Lowercase globals would essentially be the local variables for the interactive loop.

Not sure what the right answer is here.

Infinity crashes / hangs

In #97 there's a way to return infinity but there may be other ways. Is it expected to have an infinity float within Ivy? Many operations work correctly, with some exceptions:

1 log 2
+Inf

# Exits with stack trace
(1 log 2) - 1 log 2
panic: subtraction of infinities with equal signs

# Hangs, same for 'cos' and 'tan'
sin 1 log 2

There are similar issues with +, /, unary **, cos, and tan. Some others such as log and binary ** don't converge.

Monadic Flip and rot destructrively modify their input, Matrix product

Hi,

The monadic 'flip' and 'rot' operators destructrively modify their input. That doesn't look right to me. The matrix product +.* only works for square matrices.

See attached session transcript:

term% ivy
a=(2,3) rho iota 6

b=(2,2) rho 4 -1 -1 4

c=(2,2) rho iota 4

a
1 2 3
4 5 6

b
4 -1
-1 4

c
1 2
3 4

flip a
4 5 6
1 2 3

a
4 5 6
1 2 3

flip a
1 2 3
4 5 6

a
1 2 3
4 5 6

a +.* b
shape mismatch for inner product (2 3) times (2 2)

b +.* c
1 4
11 14

b
4 -1
-1 4

c
1 2
3 4

go get ivy fails: expects import "robpike.io/ivy"

go get github.com/robpike/ivy
generates the error:
package github.com/robpike/ivy: code in directory /home/gcloud/work/src/github.com /robpike/ivy expects import "robpike.io/ivy"

I'm wondering if this could be fixed by replacing all robpike.io/ivy/ with github.com/robpike/ivy/.

The weird thing is that go get robpike.io/ivy works, but somehow the import renders github.com/robpike/ivy un-go-get-able.

cannot get

when i get the source code by the command: go get github.com/robpike/ivy
it print: can't load package: package github.com/robpike/ivy: code in directory D:\gocode\src\github.com\robpike\ivy expects import "robpike.io/ivy"

could you get me a hand!

Possible base 1 log issue

Base 1 logs give results that I didn't expect. I compared with a couple of other sources:

              Ivy        tryapl.org      WolframAlpha
          -----------  -------------   ----------------
1 log .5 |    -Inf      DOMAIN ERROR   complex infinity
         |
1 log 1  |    0         1              (undefined)
         |
1 log 2  |    +Inf      DOMAIN ERROR   complex infinity

Perhaps all three should report a base error?

Inversed Residue Arguments

In contrast to all other commands, residue argument order is inconsistent with APL syntax.

I would like to propose to swap them, as it would then simplify porting of APL algorithms to Ivy.

Documentation excerpt:

Residue               A∣B           B modulo A
                            mod     A modulo B (Euclidean)
                            imod    A modulo B (Go)

Should read:

Residue               A∣B           B modulo A
                            mod     B modulo A (Euclidean)
                            imod    B modulo A (Go)

text needs to understand formats

"%x" text 1

does not produce what you'd expect. The problem is that formatOne assumes that the argument should be converted to float first. Instead, it should find the verb in the format and convert the argument according to that verb. For instance "%d" should be print 1/2 as 1/2, not %!d(*big.Float=0.5).

) help should print godoc content

The special command ) help print the special command list, but the mobile version prints the hole godoc content. I find it very useful to see the supported APL operators inside ivy.

missing each/map (¨)

It might be that I'm missing something, but mapping an operator over a vector is super useful and I had to jump through some hoops to do it.

Given a vector, compute the triangle number for each element (but any function would apply). I ended up defining the function as an operator that ignored one of its args. then reducing over a vector of pairs...

op a triangle b = (b * (b + 1)) / 2                                                                                    

op trianglevs vs = triangle/ (rho vs) 2 rho ((rho vs) rho 2) sel vs

Is a map / each syntactically difficult to support though, feels like it should be similar to reduce?

comment in eval.go

In binaryMatrixOp (eval.go):

// Vector op Matrix.

I believe this comment is backwards and this is actually the Matrix op Vector case. (Both this case and the previous one are labeled Vector op Matrix)

Working Recursive Function

Just thought you might want to see this:

op recursive x =
ivy (((x==0) sel '__=0'),((x==1) sel '__=1'),((x>=2) sel ('__=(recursive ',(text x-2),')+(recursive ',(text x-1),')')))
__

It uses the 'ivy' operator to run a command that sets '__' to a different type of value based on one of three conditions:

  1. if x==0, run __=0
  2. if x==1, run __=1
  3. if x>=2, run __=(recursive x-2)+(recursive x-1) (x-2 and x-1 are calculated first, then converted to text format and added to the string)

If you haven't noticed yet, this is a recursive implementation of the Fibonacci Sequence.
The command selector utilizes two properties I noticed in the 'sel' operator:

  • (0 sel x) is an empty vector
  • (1 sel x) is equivalent to x

The only other thing you need to do is concatenate the strings and execute the result. The output value gets stored in __, which can then easily be returned by the function.

Unary exp(-1) returns zero

Values close to -1 are correct, but **-1 returns zero:

**-.9999999999999
0.367879441171

**-1
0

**-1.000000000001
0.367879441171

Running "ivy" with empty vectors...

The 'ivy' operation returns the result of a given expression. This is usually perfectly fine, but becomes an issue when given an empty vector:

ivy ''

The above code returns nil. Not a vector, or a number. Just nil. This isn't enough to crash ivy on its own. However, when attempting to use it in an operation... things break. Attempting to run ivy ivy '' will cause Go to fully crash, returning the following error:

panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x503e46]

goroutine 1 [running]:
robpike.io/ivy/run.Run.func1(0x623ba0, 0xc4200ee000, 0xc42004fd01, 0x57a340, 0xc42009a008, 0xc42004fe48)
	/home/joey/go/src/robpike.io/ivy/run/run.go:58 +0x270
panic(0x532aa0, 0x61b3c0)
	/usr/lib/go-1.10/src/runtime/panic.go:502 +0x229
robpike.io/ivy/parse.(*unary).Eval(0xc42008c2a0, 0x57ae20, 0xc42009f0e0, 0x499607, 0xc4200f4000)
	/home/joey/go/src/robpike.io/ivy/parse/parse.go:186 +0x56
robpike.io/ivy/exec.(*Context).Eval(0xc42009f0e0, 0xc420082370, 0x1, 0x1, 0x1, 0x0, 0x0)
	/home/joey/go/src/robpike.io/ivy/exec/context.go:116 +0xa1
robpike.io/ivy/run.Run(0xc4200ee000, 0x57ae20, 0xc42009f0e0, 0xc4200ea001, 0x1000)
	/home/joey/go/src/robpike.io/ivy/run/run.go:69 +0x1a1
main.main()
	/home/joey/go/src/robpike.io/ivy/ivy.go:101 +0x584

As far as I can tell, the same problem occurs when ivy '' is passed as an argument to any operation.

Possible fixes:

  • Make ivy x return the text result of an expression
    • Possibly also create a val x (or value x) operation that returns the actual value of an expression
  • Remove ivy x
  • Change nil values to empty vectors

The scan operator (\) gets lost

OS: Android.

Input: +\1,2,3.

Result: the output is correct (1 3 6), but the prompt looks like

> +,2,3
1 3 6

instead of

> +\1,2,3
1 3 6

It looks like something somewhere escapes the backslash and the character after it.


EDIT: Now that I think of it, shouldn't this issue really be an issue on the github.com/golang/go tracker?

adding to a function issue

Not sure whats going on, but when I try this on Android:

((sqrt(5)+1.0)/2.0)==((1.0+sqrt(5))/2.0)
0

(1.0+sqrt(5))/2.0
1.61803398875

((sqrt(5)+1.0)/2.0)
1.22474487139

It seems that if the left side is a constant, then it works, but if the left side is a function then it doesn't. Am I using it wrong?

Big Numbers require a huge screen

It says "Prototype apps for iPhone, iPad, and Android"

Okay but I am working with the types of numbers that will fill up a 19 inch screen multiplied by hundreds of screens....

Are there any demos for: Mac laptops, Windows.

The big numbers will have trouble fitting on a cell phone screen. iPad indeed comes close since it is a 10 inch screen or so.

If there are no Windows/macOS compiled demos, I might just be the one to create one.

parse: parentheses for indexing get dropped when printing

For a compound expression to the left of indexing operator, when it is printed, its parentheses get dropped. e.g.

op f x = (iota x)[1]

)op f
op f x = iota x[1]

also when saving to file (f defined as above)

f 3
1

)save "/tmp/1.ivy"

)get "/tmp/1.ivy"

f 3
binary [] not implemented on type int

A possible fix might be

--- a/parse/parse.go
+++ b/parse/parse.go
@@ -204,7 +204,11 @@ type binary struct {
 func (b *binary) ProgString() string {
        // Special case for indexing.
        if b.op == "[]" {
-               return fmt.Sprintf("%s[%s]", b.left.ProgString(), b.right.ProgString())
+               if isCompound(b.left) {
+                       return fmt.Sprintf("(%s)[%s]", b.left.ProgString(), b.right.ProgString())
+               } else {
+                       return fmt.Sprintf("%s[%s]", b.left.ProgString(), b.right.ProgString())
+               }
        }
        if isCompound(b.left) {
                return fmt.Sprintf("(%s) %s %s", b.left.ProgString(), b.op, b.right.ProgString())

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.