Ask Dan and Mike - Macaulay2/Workshop-2015-Boise GitHub Wiki
Notes from Ask Dan and Mike Session on May 29th, 2015
Question session on Macaulay2 at Workshop at Boise State University.
Question 1: "How can I create a list with a LOT of variables, say indexed by a list of ordered pairs"
- Answer: Use a sequence rather than a list to have your variables print out nicely. Ring variables are one of the most tricky parts inside of Macaulay2, so keeping track of them is key.
- Example:
x_(0,0) .. x_(2,2)
or evenx_(0,0) .. z_(2,2)
Question 2: "How do I code up an algebra structure that includes a multiplication?"
- Answer: You can do that, but it's not well supported (and will be missing, for example, the ability to do matrix multiplication).
Question 3: "Are there packages that can handle algebras, e.g. DG-algebras?"
- Answer: Yes, and see Frank Moore's packages on DGalgebras and NGalgebras for more details on how to input type. Mike and Frank are currently working on integrating this multiplication into Macaulay2.
Question 4: "Is there a limit on how many arguments a method can take?"
- Answer: Yes, you can pass at most four arguments. To add additional optional arguments, use code such as:
foo = method( Options => {Limit=>4} )
foo(InputType,...,InputType) := Output => opts -> (
if opts.Limit === 4 then (
)
if opts.Limit =!= 4 then (
)
)
- Remark: If there's something you run into in Macaulay2 that you think is a bug/feature/problem, make an issue of it on GitHub! It's more likely that you'll receive a response/update there than if you just e-mail Mike or Dan and hope they remember. Go to the Issues page on the main Macaulay2 branch on GitHub to add details. Be sure to include your actual code (put it between a pair of markups "---" at the beginning and ending of your code.)
Question 5: "While Macaulay2 is running, can you change its working directory?"
- Answer: No, not exactly. You can however add a new directory to your path. To see what your path is, type:
path
And to add a new directory to your path, use code:
path = append(path,"/User/YourDirectory/foo")
- In particular, you should consider adding files that you want to use to your local directory, which should be the third or fourth link listed in your path. Also, if there are particular functions that you would like to always use in your sessions (for example, pre-loading packages), you can add functions to your "init.m2" file (which is one folder down) at:
Library/Application Support/Macaulay2/
Question 6: Is there some advantage when you are creating new types (or hash tables) of storing things as strings or numbers or whatever?
-
Answer: If you are planning on creating a package, you will need to export your symbols (e.g. "GroundSet" from Posets or "Graph" from Graphs), but be careful. If you use strings as part of your hash table, you will typically need to export them (and we recommend you document them, so that the user knows what's going on.)
If you aren't sure what symbols are floating around in your package, try using debug package.
Question 7: What about calling the name of a package?
- Answer: Use "toString PackageName" to refer to a package, and to see the list of loaded packages use "loadedPackages".
- The title as a string can also be retrieved via
package#"title"
(e.g.,loadPackage "FirstPackage"; FirstPackage#"title"
). (Similarly:"source file"
,"source directory"
, etc. Trykeys FirstPackage
to see what else is available.)
Question 8: When do you have to declare types of inputs/outputs of functions and when do you not?
- Answer: A basic function you do not need to really specify these things:
f = x -> x^3
- If you are making a method, however, you need to specify what the inputs are:
g = method()
g String := x-> x |"+1234"
g ZZ := x-> x + 1234
- This is (in a sense) a self-documenting way to create functions that will be part of a package.
Question 9: When you are applying a function to a list and want to calculate the "inverse image" of the function (e.g. the set of inputs to the function that map to a particular value), what's an efficient way to do that?
- Answer: One way is to use "partition":
i1: L = {1,2,4,6,15,3}
i2: partition(x -> even x,L)
o2 = HashTable{false => {1, 15, 3}}
true => {2, 4, 6}
Question 10: If I have a function that takes a ring and ring elements as inputs, how can I check inclusion/equality of rings/ring elements?
- Answer: This is something where there are tricky things going on with rings in the background. For example:
i1 : QQ[x] == QQ[x]
stdio:5:7:(3): error: no method for binary operator == applied to objects:
-- QQ[x] (of class PolynomialRing)
-- == QQ[x] (of class PolynomialRing)
i2 : QQ[x] === QQ[x]
o2 = false
i3 : 4.5
o3 = RR (of precision 53)
i4 : ring oo
o4 = RR_(53)
i5 : instance(4.5, ring 4.5)
o5 = false
Question 11: If I have a binary operator that is associative, is there a way to apply this to lists (e.g. if I have more than two inputs)?
- Answer: Yes, use the command "fold", e.g
i1 : L = {1,2,3,4}
i2 : fold(times,L)
o2 = 24
- It doesn't need to be associative. E.g.,
i1 : fold( (i,j) -> i-j , {1,2,3,4})
o1 = -8
Question 12: How do a find a smallest subring that contains a given ideal?
- Answer: Use "support", e.g.
i1 : R = QQ[a_1..a_10]
o1 = R
o1 : PolynomialRing
i2 : I = ideal(a_1,a_2,a_3+a_4,a_9^6)
6
o2 = ideal (a , a , a + a , a )
1 2 3 4 9
o2 : Ideal of R
i3 : support I
o3 = {a , a , a , a , a }
1 2 3 4 9
o3 : List
i4 : S = QQ[support I]
o4 = S
o4 : PolynomialRing
Question 13: How can I recover the variables that are created by functions, e.g. HilbertSeries, etc.?
- Answer: Use commands such as "peek" or "numerator"/"denominator" coupled with "ring", e.g.
i1 : R = QQ[x,y]
i2 : I = ideal(x^3,x*y^2)
i3 : H = hilbertSeries(I)
3 5
1 - 2T + T
o3 = ------------
2
(1 - T)
i4 : gens ring numerator H
o4 = ZZ[T]
o4 : PolynomialRing
-
Be careful when you're setting or using polynomial rings inside your package, and avoid commands such as "use R" for your ring (as that's going to globally set which ring Macaulay2 is using.) Assigning a global variable as the name of your ring is bad too -- polluting the global name space, etc.
You can see what your current private dictionary is using the command "dictionaryPath".
Question 14: Can you locally define a function inside another function? What about making that function available after the function finishes running?
-
Answer: Yes, and you can have it output functions. If you want to have the function available afterwards though, you should probably consider having it as a method. Check out Frank's NCAlgebras multiplication method for examples of this.
If you find something that's wrong/off/undocumented, etc., you should (if possible) fix it and submit a pull request.
Question 15: How do I submit a pull request?
- Answer: Add your package/code to your trunk, and make a separate branch with your development update.
git stash save
git pull demonstrate-pull-request
git status
git add DanPackage.m2
git commit
git push dan-ssh demonstrate-pull-request