Functions as first class objects in SageMath - sage

How in SageMath to represent a function from a set X to a set Y?
I want to enumerate all functions from a set X to a set Y. How to represent the values of the iterator which enumerates them?
I know I can just make a Python hash, but maybe there is already a more suitable object in Sage? (which would be internally represented as a hash but work as a function when applied to an argument)

Related

Type declaration in Julia for function argument that can be both array and scalar

What type should I specify in Julia for function arguments that can be either scalars or arrays? For instance, in the function below x and y could be e.g. Float64 or Array{Float64}.
function myfun(x, y)
return x .+ y
end
Is there an appropriate type declaration for such variables? Or should I just refrain from declaring the type there (or writing functions that are that generic)?
You can safely refrain from specifying types. This will not have an impact on performance of your code.
However, if you want to explicitly specify the type restriction you provided do (this is mostly useful to make sure your function is called with proper arguments and fail fast if it is not):
function myfun(x::Union{Float64, Array{Float64}},
y::Union{Float64, Array{Float64}})
return x .+ y
end
However, most likely you will rather want the following signature:
function myfun(x::Union{AbstractFloat, AbstractArray{<:AbstractFloat}},
y::Union{AbstractFloat, AbstractArray{<:AbstractFloat}})
return x .+ y
end
which says you accept any scalar float or any array of floats (not necessarily only Float64 and Array). This is more flexible, as e.g. you can accept views then or other floats (BigFloat or Float32) if you prefer to switch precision of your computations. Such a signature clearly signals your users what types of inputs you expect them to pass to myfun while remaining flexible.
I recommend this as being overly restrictive (Union{Float64, Array{Float64}}), while accepted by the compiler, usually leads to problems later when you start using your function with various input types.

How to check if a variable is scalar in julia

I would like to check if a variable is scalar in julia, such as Integer, String, Number, but not AstractArray, Tuple, type, struct, etc. Is there a simple method to do this (i.e. isscalar(x))
The notion of what is, or is not a scalar is under-defined without more context.
Mathematically, a scalar is defined; (Wikipedia)
A scalar is an element of a field which is used to define a vector space.
That is to say, you need to define a vector space, based on a field, before you can determine if something is, or is not a scalar (relative to that vector space.).
For the right vector space, tuples could be a scalar.
Of-course we are not looking for a mathematically rigorous definition.
Just a pragmatic one.
Base it off what Broadcasting considers to be scalar
I suggest that the only meaningful way in which a scalar can be defined in julia, is of the behavior of broadcast.
As of Julia 1:
using Base.Broadcast
isscalar(x::T) where T = isscalar(T)
isscalar(::Type{T}) where T = BroadcastStyle(T) isa Broadcast.DefaultArrayStyle{0}
See the docs for Broadcast.
In julia 0.7, Scalar is the default. So it is basically anything that doesn't have specific broadcasting behavior, i.e. it knocks out things like array and tuples etc.:
using Base.Broadcast
isscalar(x::T) where T = isscalar(T)
isscalar(::Type{T}) where T = BroadcastStyle(T) isa Broadcast.Scalar
In julia 0.6 this is a bit more messy, but similar:
isscalar(x::T) where T = isscalar(T)
isscalar(::Type{T}) where T = Base.Broadcast._containertype(T)===Any
The advantage of using the methods for Broadcast to determine if something is scalar, over using your own methods, is that anyone making a new type that is going to act in a scalar way must make sure it works with those methods correctly
(or actually nonscalar since scalar is the default.)
Structs are not not scalar
That is to say: sometimes structs are scalar and sometimes they are not and it depends on the struct.
Note however that these methods do not consider struct to be non-scalar.
I think you are mistaken in your desire to.
Julia structs are not (necessarily or usually) a collection type.
Consider that: BigInteger, BigFloat, Complex128 etc etc
are all defined using structs
I was tempted to say that having a start method makes a type nonscalar, but that would be incorrect as start(::Number) is defined.
(This has been debated a few times)
For completeness, I am copying Tasos Papastylianou's answer from the comments to here. If all you want to do is distinguish scalars from arrays you can use:
isa(x, Number)
This will output true if x is a Number (like a float or an int), and output false if x is an Array (vector, matrix, etc.)
I found myself needing to capture the notion of if something was scalar or not recently in MultiResolutionIterators.jl.
I found the boardcasting based rules from the other answer,
did not meet my needs.
In particular I wanted to consider strings as nonscalar.
I defined a trait,
bases on method_exists(start, (T,)),
with some exceptions as mentioned e.g. for Number.
abstract type Scalarness end
struct Scalar <: Scalarness end
struct NotScalar <: Scalarness end
isscalar(::Type{Any}) = NotScalar() # if we don't know the type we can't really know if scalar or not
isscalar(::Type{<:AbstractString}) = NotScalar() # We consider strings to be nonscalar
isscalar(::Type{<:Number}) = Scalar() # We consider Numbers to be scalar
isscalar(::Type{Char}) = Scalar() # We consider Sharacter to be scalar
isscalar(::Type{T}) where T = method_exists(start, (T,)) ? NotScalar() : Scalar()
Something similar is also done by AbstractTrees.jl
isscalar(x) == applicable(start, x) && !isa(x, Integer) && !isa(x, Char) && !isa(x, Task)

Hash functions in R: keys and values as doubles?

I'm fairly new to R. I want to use a hash function to hold key-value pairs as doubles/numerics.
I have a function f(x) = y where the function f takes the input x as a double and returns y as a double. I use this function f(x) over 10^8 times in my code (and I would like to use it much more often), and 99% of the time f(x) has been computed once already. I would like to store my answers as key-value pairs, so I can find them instead of calculating them again.
I read the article below about using environments as hash tables, but I cannot figure out how to use doubles as key-value pairs.
https://www.r-bloggers.com/hash-table-performance-in-r-part-i/
How do I use doubles as key-value pairs in a hash function in R?

Tensorflow Graphs : Are Tensorflow graphs DAG? What happens in assignAdd operations in tensor Variables

How is this graph acyclic? assign add op adds x to itself.
import tensorflow as tf
sess = tf.Session()
x = tf.Variable(1300,name="x")
y = tf.Variable(200, name="y")
z = tf.add(x, y,name="z")
b = x.assign_add(z)
init = tf.initialize_all_variables()
writer = tf.train.SummaryWriter("/tmp/logdir", sess.graph)
sess.run(init)
print(sess.run(b))
Clearly there is a bi-directional edge between AssignAdd and X.
Why is X depicted twice as a variable?
As Olivier points out, the graph for your program is a DAG. The graph visualizer takes some liberties when rendering the graph to make it easier to understand. In particular, there are no "bidirectional" edges in the runtime itself, but instead TensorFlow includes "reference edges" for variables, which are like passing a mutable value (like a pointer or a mutable reference) into a C/C++ function, as they allow the recipient to modify the same underlying storage used for the variable.
Note that it is legal for TensorFlow graphs to contain one or more cycles, or even nested cycles. The tf.while_loop() function provides a means of creating structured cycles to represent iterative computations, for which TensorFlow can compute gradients. However, for your use with a simple variable, you do not need a cycle.
Clearly there is a bi-directional edge between AssignAdd and X.
Each operation Assign or AssignAdd has two inputs and no output:
a tf.Variable: the variable to which we assign a value. Here you can see a bidirectional edge because the operation reads the old value from x and then writes back the new value
a tf.Tensor: the value assigned to the variable (or added to the variable)
Why is X depicted twice as a variable?
The variable x appears once in the graph in the big block named X, but is used twice:
in the operation tf.add(x, y): the graph reads the value of x as an input
in the AssignAdd operation: as said before, x is the tf.Variable input of the operation AssignAdd.
Conclusion
The graph is made acyclic because each operation wanting to update the value of x has the variable x as input, but not output. If the operation Assign had a variable as output, it would indeed lead to cycles.

New to OCaml: How would I go about implementing Gaussian Elimination?

I'm new to OCaml, and I'd like to implement Gaussian Elimination as an exercise. I can easily do it with a stateful algorithm, meaning keep a matrix in memory and recursively operating on it by passing around a reference to it.
This statefulness, however, smacks of imperative programming. I know there are capabilities in OCaml to do this, but I'd like to ask if there is some clever functional way I haven't thought of first.
OCaml arrays are mutable, and it's hard to avoid treating them just like arrays in an imperative language.
Haskell has immutable arrays, but from my (limited) experience with Haskell, you end up switching to monadic, mutable arrays in most cases. Immutable arrays are probably amazing for certain specific purposes. I've always imagined you could write a beautiful implementation of dynamic programming in Haskell, where the dependencies among array entries are defined entirely by the expressions in them. The key is that you really only need to specify the contents of each array entry one time. I don't think Gaussian elimination follows this pattern, and so it seems it might not be a good fit for immutable arrays. It would be interesting to see how it works out, however.
You can use a Map to emulate a matrix. The key would be a pair of integers referencing the row and column. You'll want to use your own get x y function to ensure x < n and y < n though, instead of accessing the Map directly. (edit) You can use the compare function in Pervasives directly.
module OrderedPairs = struct
type t = int * int
let compare = Pervasives.compare
end
module Pairs = Map.Make (OrderedPairs)
let get_ n set x y =
assert( x < n && y < n );
Pairs.find (x,y) set
let set_ n set x y v =
assert( x < n && y < n );
Pairs.add (x,y) set v
Actually, having a general set of functions (get x y and set x y at a minimum), without specifying the implementation, would be an even better option. The functions then can be passed to the function, or be implemented in a module through a functor (a better solution, but having a set of functions just doing what you need would be a first step since you're new to OCaml). In this way you can use a Map, Array, Hashtbl, or a set of functions to access a file on the hard-drive to implement the matrix if you wanted. This is the really important aspect of functional programming; that you trust the interface over exploiting the side-effects, and not worry about the underlying implementation --since it's presumed to be pure.
The answers so far are using/emulating mutable data-types, but what does a functional approach look like?
To see, let's decompose the problem into some functional components:
Gaussian elimination involves a sequence of row operations, so it is useful first to define a function taking 2 rows and scaling factors, and returning the resultant row operation result.
The row operations we want should eliminate a variable (column) from a particular row, so lets define a function which takes a pair of rows and a column index and uses the previously defined row operation to return the modified row with that column entry zero.
Then we define two functions, one to convert a matrix into triangular form, and another to back-substitute a triangular matrix to the diagonal form (using the previously defined functions) by eliminating each column in turn. We could iterate or recurse over the columns, and the matrix could be defined as a list, vector or array of lists, vectors or arrays. The input is not changed, but a modified matrix is returned, so we can finally do:
let out_matrix = to_diagonal (to_triangular in_matrix);
What makes it functional is not whether the data-types (array or list) are mutable, but how they they are used. This approach may not be particularly 'clever' or be the most efficient way to do Gaussian eliminations in OCaml, but using pure functions lets you express the algorithm cleanly.

Resources