Defining constants from multiple return values Racket - scheme

The matrix-qr function in Racket's math library outputs two values. I know about call-with-values to put both output values into the next function you want.
However, how can I take each individual output and put define some constant with that value? The QR function outputs a Q matrix and an R matrix. I need something like:
(define Q ...)
(define R ...)
Also, how could I just use one of the outputs from a function that outputs two values?

The usual way to create definitions for multiple values is to use define-values, which pretty much works like you’d expect.
(define-values (Q R) ; Q and R are defined
(matrix-qr (matrix [[12 -51 4]
[ 6 167 -68]
[-4 24 -41]])))
There is also a let equivalent for multiple values, called let-values (as well as let*-values and letrec-values).
Ignoring values is harder. There is no function like (first-value ...), for example, because ordinary function application does not produce a continuation that can accept multiple values. However, you can use something like match-define-values along with the _ “hole marker” to ignore values and simply not bind them.
(match-define-values (Q _) ; only Q is defined
(matrix-qr (matrix [[12 -51 4]
[ 6 167 -68]
[-4 24 -41]])))
It is theoretically possible to create a macro that could either convert multiple values to a list or simply only use a particular value, but in general this is avoided. Returning multiple values should not be done lightly, which is why, for almost all functions that return them, it wouldn’t usually make much sense to use one of the values but ignore the other.

Related

Seeded RNG in Distributions.jl

I have a module with functions where I need to ensure that all functions use the same random values. I currently have two solutions, resetting the seed at each call:
using Distributions
function random_values(n)
Random.seed!(1)
rand(Normal(), n)
end
or similarly, instantiating it directly:
using Distributions
function random_values(n)
rand(MersenneTwister(1), Normal(), n)
end
This works but I have several functions and the code becomes a bit verbose. I would rather set a seed at the module level so that all functions use the same. How can I best achieve this?
I believe that what you want is to have two or more functions (f1, f2, ...) that each call rand(). You want them in "sync" so that with a series of function calls each function gets the same series of values for each sequential call of each function (so that the third call to f2 uses the same rand() value as the third call to f1).
For this, you are best off explicitly passing a duplicated RNG object to each of your functions after initializing each to the same seed:
init = 1234
rngvector(n) = [MersenneTwister(init) for _ in 1:n]
RNG = rngvector(3)
function f1(rng, ...)
x = rand(rng, ...)
...
end
function f2(rng, ...)
x = rand(rng, ...)
...
end
f1(RNG[1], ...)
will then be in sync with
f2(RNG[2], ...).
This does mean more coding since you add one more argument to each function, but the flexibility and reproducibility that initial extra coding gives you with your Monte Carlo methods when coding the rest of what you do may make it very worthwhile.

Julia type instability: Array of LinearInterpolations

I am trying to improve the performance of my code by removing any sources of type instability.
For example, I have several instances of Array{Any} declarations, which I know generally destroy performance. Here is a minimal example (greatly simplified compared to my code) of a 2D Array of LinearInterpolation objects, i.e
n,m=5,5
abstract_arr=Array{Any}(undef,n+1,m+1)
arr_x=LinRange(1,10,100)
for l in 1:n
for alpha in 1:m
abstract_arr[l,alpha]=LinearInterpolation(arr_x,alpha.*arr_x.^n)
end
end
so that typeof(abstract_arr) gives Array{Any,2}.
How can I initialize abstract_arr to avoid using Array{Any} here?
And how can I do this in general for Arrays whose entries are structures like Dicts() where the Dicts() are dictionaries of 2-tuples of Float64?
If you make a comprehension, the type will be figured out for you:
arr = [LinearInterpolation(arr_x, ;alpha.*arr_x.^n) for l in 1:n, alpha in 1:m]
isconcretetype(eltype(arr)) # true
When it can predict the type & length, it will make the right array the first time. When it cannot, it will widen or extend it as necessary. So probably some of these will be Vector{Int}, and some Vector{Union{Nothing, Int}}:
[rand()>0.8 ? nothing : 0 for i in 1:3]
[rand()>0.8 ? nothing : 0 for i in 1:3]
[rand()>0.8 ? nothing : 0 for i in 1:10]
The main trick is that you just need to know the type of the object that is returned by LinearInterpolation, and then you can specify that instead of Any when constructing the array. To determine that, let's look at the typeof one of these objects
julia> typeof(LinearInterpolation(arr_x,arr_x.^2))
Interpolations.Extrapolation{Float64, 1, ScaledInterpolation{Float64, 1, Interpolations.BSplineInterpolation{Float64, 1, Vector{Float64}, BSpline{Linear{Throw{OnGrid}}}, Tuple{Base.OneTo{Int64}}}, BSpline{Linear{Throw{OnGrid}}}, Tuple{LinRange{Float64}}}, BSpline{Linear{Throw{OnGrid}}}, Throw{Nothing}}
This gives a fairly complicated type, but we don't necessarily need to use the whole thing (though in some cases it might be more efficient to). So for instance, we can say
using Interpolations
n,m=5,5
abstract_arr=Array{Interpolations.Extrapolation}(undef,n+1,m+1)
arr_x=LinRange(1,10,100)
for l in 1:n
for alpha in 1:m
abstract_arr[l,alpha]=LinearInterpolation(arr_x,alpha.*arr_x.^n)
end
end
which gives us a result of type
julia> typeof(abstract_arr)
Matrix{Interpolations.Extrapolation} (alias for Array{Interpolations.Extrapolation, 2})
Since the return type of this LinearInterpolation does not seem to be of known size, and
julia> isbitstype(typeof(LinearInterpolation(arr_x,arr_x.^2)))
false
each assignment to this array will still trigger allocations, and consequently there actually may not be much or any performance gain from the added type stability when it comes to filling the array. Nonetheless, there may still be performance gains down the line when it comes to using values stored in this array (depending on what is subsequently done with them).

How to acess argument from a function passed as argument in SML

I am new to coding SML and am still trying to understand pattern matching. I am trying to find out how to access an argument from a function passed as an argument in SML. For example, if a function takes 2 arguments, a function and an integer, how can I access the argument (for simplicity, assuming it only has one) that the argument function has. Does this question even make sense in SML? Here is some code, which doesn't work, but I think it illustrates what I am trying to do.
fun argumentExtraction (n,f) =
case f of
fn x => x
A function doesn't have arguments, it takes arguments. You give arguments to the function and you get a result back. You can't ask the function what its arguments are because it doesn't have them yet. You are supposed to give the arguments to the function.
To make this perhaps a bit clearer, let us consider an example. Let's take the following functions:
fun add x y = x + y
fun plus1 x = x + 1
fun applyTwice f x = f (f x)
Now applyTwice takes a function and an argument and applies the function to the argument twice. We can call it like this:
applyTwice plus1 40
or like this:
applyTwice (add 1) 40
and in both cases the answer is going to be 42 (because that's the value of plus1 (plus1 40) and of add 1 (add 1 40), add 1 really being the exact same function as plus1).
Now I'm not sure whether you want to be able to pass (plus1 40) as the value for f and then somehow get 40 from that or whether you want to pass (add 1) and then somehow get back the 1, but both are impossible.
In the case of (plus1 40) you can't even pass that as the value for f. f is supposed to be a function, but (plus1 40) is an integer (41), not a function.
(add 1) on the other hand is a function and you can indeed pass it as the value for f. In fact I did so in my example. But what you can't do is get the value 1 back from it. I mean, imagine there was a way that you could do that. What should then happen if you passed plus1 instead of (add 1). What should you get back from that? There is no value captured in plus1, so there's really nothing to get back, but clearly plus1 is just as valid an argument to applyTwice as (add 1).
The only way this could possibly make sense is if partially applied function had a different type from normal functions, allowing you to define a function that accepts (add 1) as one argument, but not plus1. However that's not the case ML and there's really not much benefit to that. Having different types of functions would just make the type system more complicated and make it more difficult to define higher order functions (as they'd have to be able to deal with both types of function). Nor do I see the use case where this ability would even be helpful.

Filter an collection of tuples

I'm playing with iterables and comprehension in Julia and tried to code simple problem: find all pairs of numbers less then 10 whose product is less then 10. This was my first try:
solution = filter((a,b)->a*b<10, product(1:10, 1:10))
collect(solution)
but I got error "wrong number of arguments". This is kind of expected because anonymous function inside filter expects two arguments but it gets one tuple.
I know I can do
solution = filter(p->p[1]*p[2]<10, product(1:10, 1:10))
but it doesn't look nice as the one above. Is there a way I can tell that (a,b) is argument of type tuple and use something similar to syntax in first example?
I don't think there's a way to do exactly as you'd like, but here are some alternatives you could consider for the anonymous function:
x->let (a,b)=x; a*b<10 end
x->((a,b)=x; a*b<10)
These can of course be made into macros if you like:
macro tup(ex)
#assert ex.head == :(->)
#assert ex.args[1].head == :tuple
arg = gensym()
quote
$arg -> ( $(ex.args[1]) = $arg; $(ex.args[2]) )
end
end
Then #tup (a, b) -> a * b < 10 will do as you like.
Metaprogramming in Julia is pretty useful and common for situations where you are doing something over and over and would like specialized syntax for it. But I would avoid this kind of metaprogramming if this were a one-off thing, because adding new syntax means learning new syntax and makes code harder to read.

How do I make a function use the altered version of a list in Mathematica?

I want to make a list with its elements representing the logic map given by
x_{n+1} = a*x_n(1-x_n)
I tried the following code (which adds stuff manually instead of a For loop):
x0 = Input["Enter x0"]
a = Input["a"]
M = {x0}
L[n_] := If[n < 1, x0, a*M[[n]]*(1 - M[[n]])]
Print[L[1]]
Append[M, L[1]]
Print[M]
Append[M, L[2]]
Print[M]
The output is as follows:
0.3
2
{0.3}
0.42
{0.3,0.42}
{0.3}
Part::partw: Part 2 of {0.3`} does not exist. >>
Part::partw: Part 2 of {0.3`} does not exist. >>
{0.3, 2 (1 - {0.3}[[2]]) {0.3}[[2]]}
{0.3}
It seems that, when the function definition is being called in Append[M,L[2]], L[2] is calling M[[2]] in the older definition of M, which clearly does not exist.
How can I make L use the newer, bigger version of M?
After doing this I could use a For loop to generate the entire list up to a certain index.
P.S. I apologise for the poor formatting but I could find out how to make Latex code work here.
Other minor question: What are the allowed names for functions and lists? Are underscores allowed in names?
It looks to me as if you are trying to compute the result of
FixedPointList[a*#*(1-#)&, x0]
Note:
Building lists element-by-element, whether you use a loop or some other construct, is almost always a bad idea in Mathematica. To use the system productively you need to learn some of the basic functional constructs, of which FixedPointList is one.
I'm not providing any explanation of the function I've used, nor of the interpretation of symbols such as # and &. This is all covered in the documentation which explains matters better than I can and with which you ought to become familiar.
Mathematica allows alphanumeric (only) names and they must start with a letter. Of course, Mathematic recognises many Unicode characters other than the 26 letters in the English alphabet as alphabetic. By convention (only) intrinsic names start with an upper-case letter and your own with a lower-case.
The underscore is most definitely not allowed in Mathematica names, it has a specific and widely-used interpretation as a short form of the Blank symbol.
Oh, LaTeX formatting doesn't work hereabouts, but Mathematica code is plenty readable enough.
It seems that, when the function definition is being called in
Append[M,L2], L2 is calling M[2] in the older definition of M,
which clearly does not exist.
How can I make L use the newer, bigger version of M?
M is never getting updated here. Append does not modify the parameters you pass to it; it returns the concatenated value of the arrays.
So, the following code:
A={1,2,3}
B=Append[A,5]
Will end up with B={1,2,3,5} and A={1,2,3}. A is not modfied.
To analyse your output,
0.3 // Output of x0 = Input["Enter x0"]. Note that the assignment operator returns the the assignment value.
2 // Output of a= Input["a"]
{0.3} // Output of M = {x0}
0.42 // Output of Print[L[1]]
{0.3,0.42} // Output of Append[M, L[1]]. This is the *return value*, not the new value of M
{0.3} // Output of Print[M]
Part::partw: Part 2 of {0.3`} does not exist. >> // M has only one element, so M[[2]] doesn't make sense
Part::partw: Part 2 of {0.3`} does not exist. >> // ditto
{0.3, 2 (1 - {0.3}[[2]]) {0.3}[[2]]} (* Output of Append[M, L[2]]. Again, *not* the new value of M *)
{0.3} // Output of Print[M]
The simple fix here is to use M=Append[M, L[1]].
To do it in a single for loop:
xn=x0;
For[i = 0, i < n, i++,
M = Append[M, xn];
xn = A*xn (1 - xn)
];
A faster method would be to use NestList[a*#*(1-#)&, x0,n] as a variation of the method mentioned by Mark above.
Here, the expression a*#*(1-#)& is basically an anonymous function (# is its parameter, the & is a shorthand for enclosing it in Function[]). The NestList method takes a function as one argument and recursively applies it starting with x0, for n iterations.
Other minor question: What are the allowed names for functions and lists? Are underscores allowed in names?
No underscores, they're used for pattern matching. Otherwise a variable can contain alphabets and special characters (like theta and all), but no characters that have a meaning in mathematica (parentheses/braces/brackets, the at symbol, the hash symbol, an ampersand, a period, arithmetic symbols, underscores, etc). They may contain a dollar sign but preferably not start with one (these are usually reserved for system variables and all, though you can define a variable starting with a dollar sign without breaking anything).

Resources