Possibility of a generically sized vector of 1s and 0s similar to the UniformScalingOperator in Juila v0.7


#1

I love the generically sized I as the UniformScaling operator in Julia. It makes linear algebra code elegant (and I suspect either efficient now or in the future)

Another common element that comes up in linear algebra are vectors of 1s and vectors of 0s which you want to be generically sized. For a nice symbol people could add, the common \mathbf{1} or \mathbf{0} although sometimes \vec{1} and others are used and appear to be in https://docs.julialang.org/en/release-0.4/manual/unicode-input/

Written generically, a function that comes up in asset pricing of a discrete markov chain looks something like

n = 2
β = 0.9
A = rand(n,n)
onevec = ones(n,1)
inv(I - β *A) * onevec

This could be rewritten with something like this as

n = 2
β = 0.9
A = rand(n,n)
inv(I - β *A) * 𝟏

Not only is the size of the onevec unnecessary, but I can imagine there are behind-the-scenes optimizations that could happen with more complicated code than this.

Similarly, the 𝟏 and 𝟎 come up all the time when stacking up matrices. For example,

A = rand(2,2)
B = rand(3,1)
c = 4
zerovec = zeros(2,1)
onemat = ones(3,2)

D = [A zerovec;
      c zerovec';
      onemat B]

could become

A = rand(2,2)
B = rand(3,1)
c = 4

D = [  A 𝟎;
       c 𝟎;
       𝟏 B]

Any thoughts on whether this could be written and makes sense? I wasn’t sure if this was the sort of thing covered by https://github.com/JuliaLang/julia/issues/24595 althought I couldn’t tell if the oneunit was implemented (and it didn’t seem to be generically size).


Linear Algebra - Unit vectors e_i
#2

See https://github.com/JuliaArrays/FillArrays.jl


#3

FillArrays.jl doesn’t include generically sized vectors, but I’d happily accept a PR that adds thid


#4

Oh, I thought it did. Well, at least you can punch in the sizes and it’ll work


#5

No doubt the appropriate home for this sort of thing might make sense in FillArrays.jl.

Do you think that a generically shaped matrix/vector for this really feasible, or were there enormous hoops required to make the I operate with standard matrix multiplications, array concatenation, etc.? The other generic thing that I see all over the linear algebra I code is the zero vector with a 1 in a particular location. Usable denoted \mathbf{e}_{n} where it is [ 0 ... 0 1 0 ... 0] except at location n. It sure would be nice to hvae something like \mathbf{e}(n) as a function in julia for doing that sort of algebra.


#6

I think it’s pretty straightforward to implement: just copy-and-paste https://github.com/JuliaLang/julia/blob/master/stdlib/LinearAlgebra/src/uniformscaling.jl and make a few changes.

(Note UniformScaling isn’t even Base anymore.)


#7

If so, what name makes the most mathematical sense (and what unicode symbol could be exported) for the following:

  • Vector/matrix of 1s.
  • Vector/matrix of 0s
    • Same story. \bfzero looks great as 𝟎 but you can’t start with it.
  • Column Vector with a 1 in the n’th position (assuming that the size it stretches to is >= n)
    • Here, \bsanse looks nice as 𝗲(n::Int) and would work fine?

#8

Hmm, it looks like all numbers are forbidden. The best I could come up with is 𝐥 (\bfl, but looks like a 1) and 𝐎 (\bfO).


#9

They could be allowed—the reason they’re currently forbidden is that we didn’t have a good sense of how they should behave. Should “weird” numbers act like digits or like letters? This use case seems to argue for treating them as letters so that 𝟎 and 𝟏 are valid identifiers.


#10

Is there any downside to erring on the side of treating almost all unicode characters as valid identifiers? The only “number” specific parsing that came to my mind is the 2x parsing into 2 * x? If that is the main place it would matter? If so, then I think that 𝟏A is not really necessary and that this could be interpreted as a 2 character identifier.


#11

If you do that, then you can’t change it later without potentially breaking people’s code, which we’re committing to not doing in 1.x releases. So instead we’re erring on the side of being “conservative”—I put that in quotes because I think Julia allows you to use more Unicode operators and symbols than any other language that I’m aware of.


#12

OK. Sounds like a middle-ground may be to find a good type of “weird number” that makes sense to act as a letter and are available in enough unicode fonts that they could be displayed. If there are at least a single set of unicode numbers that work as identifiers, then that is enough for this version.

I will prepare an issue with a candidate set. Then, perhaps, we can try to find someone who might be interested in implementing this sort of thing in FillArrays.jl. If so, what are reasonable mathematical/Type names (as opposed to unicode aliases) for the 𝟏, 𝟎, and 𝗲(n) ? UniformOnes, UniformZeros, and UniformIndicator?


#13

I can understand the desire to be conservative about 𝟏, but also forbidding 1️⃣ seems excessive…


#14

The good thing is that there are a multiple sets of distinct unicode characters that look like 𝟏 . Maybe the set of Mathematical Sans-Serif Bold in https://docs.julialang.org/en/latest/manual/unicode-input/#Unicode-Input-1 for example could be identifiers, which leaves the others as is?

I have to admit, though, that it would be nice to have the Mathematical Double-Struck Digit as valid identifiers. Makes DSL for indicator functions (e.g. 𝟙(a >. b) ) possible, where they are not right now.


#15

This isn’t written in stone. Open an issue and make the case to add these characters as valid letters. Since we now have a use case there’s a discussion to be had. Previously we had no actual use cases, so we made the only choice that’s guaranteed not to prevent any future use case. I also don’t see how 1 in a box is particularly different than a double struck 1.


#16

Note that the symbol 𝟏 (math bold 1) usually represents the identity matrix, not a vector of 1.


#17

Haven’t seen that personally, but the suggestion here is not to force 𝟏 to be a vector of 1s, but rather to make it possible for a library to do so. In your case, if it was a valid identifier then you could just do

const 𝟏 = I

#18

Posted in https://github.com/JuliaLang/julia/issues/26808

Hopefully this can make it into v0.7 so that we can get RAs to play around with adding these features to FillArrays.jl.