Use the Sequence* family of functions
list = {1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0}
SequenceCases[list, {0, 1, 0}, Overlaps -> True]
SequencePosition[list, {0, 1, 0}]
Overlaps -> True is the default for SequencePosition which is a little inconsistent
|
|
|
Great Rohit, this works very well. Thanks. In which sense is Overlaps -> True inconsistent?
I saw in the docs, that SequencePosition has the same Overlaps option. Is it also inconsistent there? Would you also have some suggestions for the following : This checks for 'repetitions'.
How could I test for mirror symmetry? E.g. {0,0,0,1,0,1,1,0,1}. here 1,0,1 is a symmetry as well as 1,0,1,1,0,1
How could I test for Permutations of the pattern? E.g. {1,0,1,x,x,x,x 0,1,1,x,x,x,x,1,1,0}. here are 3 permutations of {1,0,1} present. How to detect them?
|
|
|
Hi B.
In which sense is Overlaps -> True inconsistent? I saw in the docs,
that SequencePosition has the same Overlaps option. Is it also
inconsistent there?
What I meant is that the default value of Overlaps is True for SequencePosition and False for SequenceCases. That seems inconsistent to me. For symmetry something like this?
list = {0, 0, 0, 1, 0, 1, 1, 0, 1}
Subsequences[list, {3, Length@list}] // Select[PalindromeQ]
For permutations generate all of them and test each with SequencePosition?
perms = Permutations[{1, 0, 1}]
list = {1,0,1,x,x,x,x 0,1,1,x,x,x,x,1,1,0}
SequencePosition[list, #] & /@ perms
|
|
|
Thanks Rohit, i get the 'inconsistency' and I agree. Your solutions for Symmetry and Permutations work fine and I can extend on them :-)
|
|
|
Hi Rohit, I wanted to take your idea a little further, more general, but I run into a snag I do not understand.
SequenceCases[pattern1, {0, 1, 0}, Overlaps -> False] from your previous post. This works great :-) But now to find more general patterns :
list={0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1}
patternToFind = {x, y, x_}
SequenceCases[list, patternToFind, Overlaps -> False] I get {{1, 1, 1}, {1, 0, 1}, {1, 0, 1}} as result. Why is the [1,1,1} there? I specified the first and third to be the same, but the second element to be different. I expected to get {1,0,1} and {0,1,0}.
The result also misses the {0,1,0}. Any good ideas?
|
|
|
Hi B. In a pattern with a symbol, the symbol is what the match is set to. So {x_, y_, x_} matches something, x is set to that thing, followed by something, y is set to that thing, etc. The fact that the symbol is different does not mean the match has to be different.
MatchQ[{1, 1, 1}, {a_, b_, a_}]
(* True *)
You need to use Condition to ensure they are different
MatchQ[{1, 1, 1}, {a_, b_, a_} /; b != a]
(* False *)
The missing ones are because of Overlaps -> False
SequenceCases[list, {x_, y_, x_} /; x != y, Overlaps -> True]
(* {{1, 0, 1}, {0, 1, 0}, {1, 0, 1}, {1, 0, 1}, {0, 1, 0}} *)
The matching positions
SequencePosition[list, {x_, y_, x_} /; x != y, Overlaps -> True]
(* {{6, 8}, {7, 9}, {8, 10}, {11, 13}, {12, 14}} *)
|
|
|
Great Rohit, thanks. I had understood that {x,y,x} was different from {x,x,x} as a pattern . I had the 'Overlaps -> True' first, but as I did not have x != y , I got about way too much solutions. Now it works fine :-) Best , Bert
|
|
|
Hi Bert, They are not the same
MatchQ[{1, 2, 1}, {x_, x_, x_}]
(* False *)
MatchQ[{1, 2, 1}, {x_, y_, x_}]
(* True *)
The first pattern specifies that all elements must be the same. The second specifies that the first and third elements are the same. The second element can be anything, including the same as the first and third.
MatchQ[{1, 1, 1}, {x_, y_, x_}]
(* True *)
|
|
|
Precisely! When I talk about pattern matching, I always talk about x_ as "something—call it x" for exactly this reason.
|
|
|
Rohit & Arben, I get it. Great help.
Cheers , Bert
|
|
|
Is the 5th question in the level 1 exam :- "Beginning with
data = {{15000, , 89000,, ............" correct/valid ?
|
|
|
Questions are randomly (actually, pseudorandomly) selected from a pool; the odds that any person would have the same 5th question are rather low. I had a question on my L1 quiz where there were 3 possible answers, plus "all of the above". It turned out that 2 of the 3 were giving the correct response and one was giving a different response; none of the answers could possibly be right. I was running my quiz notebook off of the Wolfram Cloud; that appears to be the reason for the one buggy response. I answered the question as if the function was behaving correctly. I sent an e-mail to wolfram-u@wolfram.com noting the bad behavior and filed it as a bug in Mathematica. Here are my rules in taking a Wolfram quiz or cert test. It took me a while to figure these out...
Try as hard as you can on every single question.
Realize that you may still get some questions wrong no matter what you do or know. Don't sweat it.
Appreciate the difficulty in authoring a perfect quiz. There may be bugs, bugs may creep in over time, and you may get some "no win" questions. Flag questions you're pretty sure are buggy in e-mail to Wolfram U. Remember rules 1 and 2, and have fun.
|
|
|
Thanks Phil—no kidding on authoring assessments! It's difficult to write questions of the correct difficulty, the right amount of "almost, but not exactly, and wrong in an instructive way" answers, and account for possible bugs, input types, edge cases, and so on. Still, we're always looking to improve and always appreciate any bug reports or suggestions that come our way.
|
|
|
Hi Arben, I have another question about Manipulate and it ties in with my questions from 3 days ago about 'Stepping back' to previous settings in Manipulate. One has to be quite careful not to create a loop in a Manipulate construct.
E,g. a= a+2 gives already a loop. If done like aNew = a+ 2, then it's ok.
More 'funny things' might happen in a more complex Manipulate construction. My question is :
How is the order of the calculations in a Manipulate? Does it go from top to bottom, like line for line (and left to right)? Always?
What if I change a parameter (slider) whose appearance is only after 20 lines of code? Is still all the code run from the top, or does the re-calculation start where the changed value first appears (e.g. line 20)? How can I step through the code and watch the changing variables, like in 'Step-Debug'?
Thanks a lot, Bert
|
|
|
Hi Arben, I would really appreciate if you could shed some light on these questions of mine. I hope you find the time for it :-) I read through both "Dynamic & Manipulate Notes" and the "Advanced Dynamic & Manipulate Notes".
I could not find anything about the order of execution of the lines of code or step Debug in a Manipulate construct. Thanks a lot,
Beat
|
|
|
Hey Bert! I didn't know the answer to this one off the top of my head. After some investigation, I have to say "it's complicated." From the Advanced Dynamic Functionality Tutorial:
Dynamic expressions can be nested, and the system takes great care to update them only when necessary. Particularly when the contents of a Dynamic contain further interactive elements, it is important to keep track of what will stay static and what will update, when a given variable is changed.
It seems as if for any given dynamic expression, there's a step which involves "tracking down" what pieces of the expression can/will change when certain dynamic variables are updated, and it's those pieces which end up being reevaluated.
|
|
|
Thanks Arben, for your help and work. It certainly is quite complicated and I started wondering after I found that the code inside Manipulate is not necessarily executed from top to bottom. It is getting even more complicated if there are Dynamic functions explicit withing the Manipulate. Maybe I can come up with some Flags that get set when some line of code is re-executed. I'll have to try. I will read through the Advanced manipulate and Dynamic paper again :-) Best, Bert
|
|
|
Part of the issue here—and I think why you probably didn't think that the quoted section was useful when you first read it—is that Manipulate is making its own DynamicModule under the hood. This means that even if you're not typing Dynamic[x], the fact that you have (say) {x,1,10} as the second argument to Manipulate means that the constructed DynamicModule does have Dynamic[x] in there—which is why the quoted section is actually relevant, even if you aren't personally typing Dynamic[x].
|
|
|
Very good point, Arben :-)
|
|
|
I am having email problems. How do I join the class without today's link? Sorry about this!
|
|
|
@Paul Tikotin, we'll send your join link to your email, or you can contact us at wolfram-u@wolfram.com to provide a different address, if you're having trouble with gmail. You can also go to the webinar page to register and receive a join link using a different email address. Email communication of some sort will be needed.
|
|
|
I think I have just sorted the problem,...Thank you!
|
|
|
I am running Mathematica version 14 under Windows 11 on an HP Envy laptop. To compare AbsoluteTiming for 3 alternative instructions to do the same thing, I wrote the following code and was surprised to see that "Power" was not quite the fastest. (Timing[...] just showed 0. for all 3 instructions.) I'd appreciate an analysis of my findings.
In[104]:= listOfAssoc=Association@@@({"a"->#[[1]],"b"->#[[2]]}&/@Partition[Range[1000],2]);
tbl=listOfAssoc[[;;2]]
Out[105]= {<|a->1,b->2|>,<|a->3,b->4|>}
In[106]:= First@AbsoluteTiming[Power@@@listOfAssoc]
First@AbsoluteTiming[#a^#b&/@listOfAssoc]
First@AbsoluteTiming[#[[1]]^#[[2]]&/@listOfAssoc]
Out[106]= 0.0118669
Out[107]= 0.0107371
Out[108]= 0.0082883
|
|
|
As we're fleshing out project ideas for the level 2 certification, is there someone we can meet with to make sure we're on the right track?
|
|
|
How about a separate Wolfram Community discussion to speculate/brainstorm about L2 cert projects? Anyone can create a new discussion, but it might be good to have the "seal of approval" if @Arben Kalziqi or @Jamie Peterson were to create it. :) I am looking at a Wolfram Examples project showing muscle co-activation of hand flexors/extensors, arm flexors/extensors, and arm pronators/supinators. The beautiful Anatomy package has the ability to do color illustrations; I can graphically show the muscles involved in particular co-activations. Apparently, the Anatomy package also has identifiers for the antagonist pairs; I need to investigate that. Apologies if those words make no sense; it's better in pictures.
|
|
|
While I (hopefully clearly) do enjoy answering everybody's questions here, for something as involved as the Level 2 projects I'm afraid it's not really feasible from a time/involvement perspective. Like Jamie said, please do take advantage of office hours, and we may well offer more things like this in the future. (Actually, typing that reminds me that we have something in the cards for like, an "interesting example + office hour Fridays" series... we'll see if that comes to fruition!)
|
|
|
In that case, I support y'all wholeheartedly (imagine I could use emojis here and added a :sweat_smile: at the end there, okay).
|
|
|
Great, thank you! I did request registration for the office hours. And I agree that a L2 discussion board geared towards the participants is a great idea.
|
|
|
Hi Jamie, Cassidy, Abrita, Arben! Thank you for all your hard work that goes into making these study groups enjoyable. [big smiley] I enjoyed the fill-in-the-blank format of the Level 1 quiz. Keep that coming. The Level 2 Certificate is on my agenda (the Nutrition Report looks interesting) as are almost every new webinar and WSG. Artisinal Calculus, why, yes, I think I will! I'm sleeping in today but I will see y'all soon. Stay safe. Stay healthy.
Lori
|
|
|
Same! I can't get enough of these webinars and try to do every one that looks like it's even remotely related to something I might use. Or just looks particularly interesting.
|
|
|
Thanks Lori! We always enjoy having you with us. Hopefully you enjoy the review recording and notebook if you'd like to peruse them after sleeping in!
|
|
|
Aww, that's a very nice thing to say. Thank you, Arben!!! Will do! Have a fun weekend :D
|
|
|
Hi Philip, The code you posted is incomplete, there are several symbols that are not defined sEDNH, pressure, defGrad, .... I also don't understand what you are trying to accomplish with combined. It just adds an additional level of nesting to dgrad because names includes all of the elements in dgrad
dgrad == First /@ combined
(* True *)
If you just want to pick out the matches to names here is a functional way to do it. There is no need to initialize combined
combined = Select[dgrad, MemberQ[names, First@#] &]
|
|
|
Hey Philip—agree with Rohit here; I'm not sure what you're trying to do exactly. If you could upload a version of the notebook where you've defined everything that you're using and where you've explained what each "step" is supposed to do (like by saying "i have [input], and it does [xyz], resulting in [output]"), I'm sure I'd be able to help.
|
|
|
Hi Philip, I have modified your notebook and added a solution to the end. Light green cells are ones I added.
Attachments:
|
|
|
Rohit,
Thanks for the solution. It looks much better that the Do loop and gives me new avenues to explore.
Phil
|
|
|
Does the word "Private" have some particular significance. What would
be the problem with using some other word like [...]
"Private" has no significance. If you go to the Wolfram Language Documentation for Begin, you'll see the examples there use "MyContext`". "Private" is not a keyword in the WL, but [IMHO] the fact that it is a keyword in many programming languages means it should probably be avoided in examples in Wolfram courses. OTOH, "MyContext" is definitely un-keywordy. It's really helpful to use the Wolfram Language Documentation as the first place to go with questions like this. I don't think that Arben has emphasized the wonderful Wolfram documentation in this course. Docs are available on the web; they are also typically installed in a Mathematica install and can be accessed through a Mathematica window. Carpe documenta!
|
|
|
If there are bugs/shortcomings in the documentation, you can file a support ticket with Wolfram. As far as Private not being a keyword, I just looked up that word in the documentation. Simple. "Private" the String is used as an option in some functions, but that doesn't leak out and affect other things. If a word isn't mentioned in the doc entry for some function, it shouldn't have any magic way to affect that function. The other thing I noticed with your questions: if you're curious what happens when you do X, just try it. If the kernel behaves in some inexplicable way, that's the point in time to investigate further. I imagine Stephen Wolfram sitting (or standing) in his office in MA; I bet it's in his muscle memory just to try something about before looking it up in the docs or (gasp!) asking another staffer for clarification.
|
|
|
Is there any difference between
Proficiency in Wolfram Language Level 1 Certification
and
Proficiency in Mathematica Level 1 Certification ?
It seems that the requirements and the process are the same.
|
|
|
Hi there! I have a question about adding a new variable (Key-> Value) to a list of associations. For instance I recreate the following data
{V1, V2} = {RandomVariate[NormalDistribution[15, 4], 50],
RandomVariate[NormalDistribution[20, 7], 50]}; (*Create two random variables*)
data = AssociationThread[{"Diameter", "Height"} -> #] & /@ Thread[{V1, V2}];
(*Arrange a list of association*)
Suppose I want to add a new variable, for instance, the logarithm of Diameter variable, however, the only way I succed was using a implicit loop using the table function:
V3 = Log[data[[All, "Diameter"]]];
Table[Append[data[[i, All]], "LogDiameter" -> V3[[i]]], {i, 1,
Length[V3]}];
I would like to ask if I could add a variable to the association list avoiding the Table function? Thanks in advance!
|
|
|
Hi Andres, Here is one way to do it
augmentedData = <|#, "LogDiameter" -> Log[#Diameter]|> & /@ data
Dataset@augmentedData
This relies on the implicit addition of key/value pairs to an Association when wrapped in Association. E.g.
assoc = <|"a" -> 1, "b" -> 2|>
<|assoc, "c" -> 3|>
(* <|"a" -> 1, "b" -> 2, "c" -> 3|> *)
|
|
|
Hi Andres—here are a few implementations that should get your thoughts moving, If you have access to V1 and V2 directly, you can do:
new = AssociationThread[{"Diameter", "Height", "LogDiameter"} -> #] & /@
Transpose[{V1, V2, V3}];
If you only have direct access to data, you could do this (honestly, I'd do something like this anyway):
new = <|"Diameter" -> #Diameter, "Height" -> #Height,
"LogDiameter" -> Log@#Diameter|> & /@ data;
The fastest and shortest way has got to be something like:
new = Append[#, "LogDiameter" -> Log@#Diameter] & /@ data;
|
|
|
When I click on the Grading Rubric link on this page I get
HTTP Error Code 403 Sorry, you do not have permission to access this
item.
|
|
|
Hi Rohit, this should be fixed now—works for me, as well. You may need to clear cookies/cache to get it to work, though, as a version with the wrong permissions may be cached on your end.
|
|
|
How to create the association command, "<|", vertical bar?
|
|
|
It will depend on your keyboard layout, but a QWERTY layout should have the | accessible by pressing shift and . The < is just a less-than sign, so that's <|association here|>.
|
|
|
Arben The backslash needs to be escaped in the reply window. Shift \ Shift + \
|
|
|
Hello Arben: You are an excellent instructor and learning a lot. When I open your filled-out notebook file, the file shows up as the notebook, with nice colors. But when I open the file class file, it looks different. Why is that and how to get into a nice notebook format for your class notes?
|
|
|
Hey Taiboo—we have two versions of our notebooks, generally speaking. One is the instructor version, which I use when teaching live and which we use for making edits. Then, there's a more monochrome "handout" version which has some formatting changed for consistency's sake and to work nicely on the cloud.
|
|
|
Arben - Two questions:
1. On the Quiz, is there a way to find out which problem(s) we got wrong?
2. My "Day01-ListsAndAssociations-Filled.nb" is filled with NULLs. Is there a way to resolve this?
Thanks in advance,
|
|
|
- I don't think so, but if you have a question about a particular question you can ask me. (I also think that if you email us, we can manually pull your answers and which were correct.)
- No
Nulls for me. You might get them if you don't Enable Dynamics when prompted.
|
|
|
The quizzes used to indicate which ones were incorrect, but within the last year that was changed. I found the old method of indicating which answers were correct educational and the new method not so much. Thanks, Mitch Sandlin
|
|
|
I have some questions about the Manipulate construction:
I have a manipulate with let's say 4 adjustable parameters.
How can I make a button (Previous) to go to the previous values, without getting into an endless loop, which can easily happen in a Manipulate, as if one parameter is changed, everything is recalculated. I tried several ways, like putting the values in a nested list, but somehow there is always something that is not working.
Ideally, I want to be able to step back several steps and also forward again (up to the last values I had). I hope my explanation is clear enough :-)
How can I keep the last used values for the 4 parameters when I run the manipulate again?
I believe that in a DynamicModule construction, that goes by itself.
How can I easily save the values of the 4 params as a named Preset? Eg.: Preset1.
I know that I can do 'Paste snapshot, which gives me all of the original code with the values of the moment, along with the result. This takes a lot of Notebook space, especially when the Manipulate code is substantial.
I only want the values of the parameters, so I can load them back in later.
|
|
|
Great questions, B—any question I can't immediately answer must be pretty great ;). Let's see...
I think I see what you mean, but some clarification wouldn't hurt. Could you provide a working example of a Manipulate and the behavior you'd like for it to exhibit? The thing about Manipulate is that—unless you specify otherwise via TrackedSymbols, Refresh, and similar—it will simply check for any symbol updates and it will re-compute the result. There's no way that's clear to me to get around this; the thing you're manipulating could depend arbitrarily on these inputs and other things, so it sort of needs to be that way. That said, sometimes you have a Manipulate where there's a "constant" piece which is expensive to compute, and the "dynamic" piece lives on top of it and is generally faster to compute. I don't think that that's what you're talking about, but if so, you can use With and Show to great effect for responsiveness—see attached.
I have a kludgy solution for this and your third question. There's nothing stopping you from defining symbols within a Manipulate, so inside your manipulate you could say something like f[bValue=b,...] and then bValue would be Set to whatever the last value you used on your slider (or other interface element). You can use this as the starting point for the parameter too, so you'd simultaneously save all of your symbols and also be able to keep them as the starting point. Here's an example to get you going:
kValue = 1;
Manipulate[
Plot[Sin[(kValue = k) x], {x, 0, 2 \[Pi]}], {{k, kValue}, .5, 3}]
Dynamic@kValue
|
|
|
Somehow my post got posted under another name, so here I go again ; Thanks Arben for your answers and for the truly excellent teaching you do. You bring something extra to the table, sometimes very subtle. Your teachings are top on all levels :-) For the moment I reply to your answer to my questions 2+3. I had also come up with creating secondary variables for the adjustable parameters in the Manipulate and assign the these params to the secondary variables. This way They are remembered outside the Manipulate loop. Also handy for debugging. Building on your example, I came up with the following, which keeps the last used value when I run Manipulate again. (see code at end). I can also make presets this way and via a Button load them back into Manipulate. I had hoped that there might be an easier way (a Wolfram function) that would do the job, as sometimes I have quite a lot of adjustable parameters in my Manipulates. But it is doable this way. I'll post a Nb about my first question later.
Manipulate[ kValue = k; Plot[Sin[k x], {x, 0, 2 [Pi]}], {{k, kValue}, .5, 3, Appearance -> "Labeled"}]
|
|
|
Hi Arben,
I've come up with an example Nb.
It covers some of the 'Previous' and 'Next' possibilities, but not yet all.
And it keeps the values last used. Run the first cell before running the Manipulate, in order to provide initial values for the parameters inside Manipulate. What it does is :
1. It keeps it's last values when running the Manipulate again, except for the Random pointsXY, which are newly generated each time the Manipulate is run.
- It steps back and forward (Button 'Previous' and 'Next'). This only works so far for the position of the lines (pointXY).
Click 'Initialize X' and /or 'Initialize Y' buttons a couple of times and you can step back and forward.
I limited the stepping back and forward , so no errors can occur (like asking for the a step before the first or beyond the last step).
Now I will try to be able to step back also for the other parameters, but something does not pan out yet.
Attachments:
|
|
|
TOPICS It would be great if the following topics are covered, OR if there are other courses which cover them (I appreciate that some of these were touched on a bit): custom packages , non-trivial function bodies, ordinary looping (includingPython-type looping), IDEs which work well, custom types (as in OO programming), name spaces, enums. At least indicate what Wolfram language calls these structures, and where they are. For example, list indexing was covered to excess, but there was only just brief touches of defining complicated functions. Custom packages are crucial for organizing any but the simplest programs, and ditto for IDEs. Sometimes speed is not important but flexibility in looping might be needed. Etc. Thank you
|
|
|
Thanks for the suggestions, Steven—we'll cover some of this in the coming days, and the full course offers a bit more insight than the slightly condensed study group. Once the full course is out later this month, please feel free to attend and tell us directly what you thought, if you'd like!
|
|
|
Not in the file provided.
|
|
|
Doug, it would be great to have a 3D Slider.
Unfortunately that is not possible on a 2D screen. How would you want to adjust the 3rd (z) axis on a 2D surface?
I have been thinking more than 15 years about this and only have come up with complicated solutions, which are not truly 3D.
|
|
|
We Create 3D graphics on a 2D surface so we should be able to create a 3D slider . I have noticed recently how graphics programs use a 3 button mouse to allow 3D movement in a 3D graphic , Is this not a possibility
|
|
|
We create 3D images on a 2D surface by means of perspective.
To actually control 3 independent axes, you'll need 3 independent 'movements'.
Of course, with extra buttons or scroll-wheels, you can add 3 third dimension, but never with a onscreen 3D slider. What you could do, is assign the z direction to e.g. the y direction when ta button is pressed.
But again, this would not be a real 3D slider, more of a work around.
|
|
|
I also wanted to address Artur's question about @ vs. @* briefly. It's true that in some contexts they are the same:
f@*g@x === f@g@x === f[g[x]]
but this isn't really the point of Composition/@*. The real use of this (in my experience) is chaining functions together for use in Map or Apply. Consider a basic example:
In[716]:= N@*Mean /@ {{1, 2, 4}, {4, 8, 9}}
Out[716]= {2.33333, 7.}
Here, the @* lets you write a "single composite object" which is the composition of N and Mean. This composition function is then what is mapped across the lists. Simply using @ doesn't do this:
In[715]:= N@Mean /@ {{1, 2, 4}, {4, 8, 9}}
Out[715]= {7/3, 7}
Why? What's happening—visible through Trace, which I'm going to check after I type this side note to confirm my Vibes (they were correct)—is that N@Mean gets evaluated first, and N acting on Mean just provides Mean because there's nothing there to make numeric. So the idea is:
N@Mean /@ {{1, 2, 4}, {4, 8, 9}} = N[Mean] /@ {{1, 2, 4}, {4, 8, 9}} === Mean /@ {{1, 2, 4}, {4, 8, 9}} === {Mean@{1, 2, 4j}, Mean@{4, 8, 9}}
whereas
N@*Mean /@ {{1, 2, 4}, {4, 8, 9}} === {N@*Mean@{1, 2, 4j}], N@Mean@{4, 8, 9}} === {N@Mean@{1, 2, 4j}], N@Mean@{4, 8, 9}}
When composing functions, that's what you want. It can be really useful! Take the example from Good Coding Practices:
Framed@*Highlighted /@ {1, 2, 3} (* Unclear *)
(Framed@*Highlighted) /@ {1, 2, 3} (* Clearer *)
Map[Framed[Highlighted[#]] &, {1, 2, 3}] (* Clearest *)
You could rightfully argue that the first one is unclear, but if you understand how @* works it's very clear and very concise and very easy to write. You're taking the composed operation of "highlighting and then framing" and mapping it across the list {1,2,3}. It doesn't get better than that!
|
|
|
The email announcing the recording availability didn't send me to the recording, just to the materials folder (no video there). Also, there was a link to the Quiz, which I'm hesitant to try without watching what went on today. Help?
|
|
|
The e-mail announcing the availability of the recording of today's session was sent out at ~15:50 Eastern Standard Time today by the "Wolfram U Team". The subject is: "Recording available: Interfaces and Deployment". Search for "Wolfram U Team" in your inbox. The recording is accessed by clicking the "Watch The Recording" button in that e-mail. I called up the video; it is indeed today's recording. --phil
|
|
|
I did NOT receive this email.
|
|
|
Please contact our staff at wolfram-u@wolfram.com if you need assistance with webinar email notifications from bigmarker.com. This is the mechanism that is used to send Daily Study Group reminders and recording notifications.
|
|
|
Jamie, it would be cool if Wolfram Research could maintain a list of those BigMarker video archive links for each user in a particular WSG and have them accessible through a Wolfram-U portal in the Wolfram Cloud. All of the user's information for that particular WSG would be stored there. That would provide a reliable mechanism for all users to have the URLs -- and not worry about losing an e-mail through spam filters, force majeure, or whatever. It would also function as a beautiful professional archive for students to reference those training materials in the future. It would be an engaging example for how users can set up small programs establishing highly accessible live data using the Wolfram Language for their own customers. There's an expense setting this up, but a payout in reducing the day-to-day customer support and customer satisfaction. I bet there are staffers who could implement this as a one-liner. ;)
|
|
|
@Phil Earnhardt, I really like this idea! We have, in fact, had brainstorming sessions about building a Wolfram U portal that would help to archive links to past sessions and courses, certifications, and other useful information. It's good to be reminded there is interest out there. Thanks!
|
|
|
Well, good. The really interesting thing for me is having a cloud app that Wolfram U users would regularly be using -- and having some sense of what they could [cloud] deploy for themselves. One of the amazing bits of code that Wolfram U has is the grading engine for the Elementary Introduction to the Wolfram Language course. Anyone who goes through that course without being amazed what the grading engine is doing is just not conscious! Like many, It's tricky: you must have answers that are being produced computationally, but the implementors could not have anticipated everything users could possibly do. I found myself tweaking my answers -- just to see what the engine would judge as "correct" or "incorrect". IMHO, the only shortcoming with the EIWL grading engine is that the source code is not available. If/when you do this project, please design and implement it with the intention of making the Wolfram Language Notebook source publicly available. Students regularly using it should be curious about its implementation. And people will want to borrow/modify it for their own use; that's what you want. You may even want to do a BigMarker presentation where you walk through the source and explain what/why you do things (both for functionality and for code efficiency).
|
|
|
Trying to understand what Trace is telling me here. I have your words but still do not quite follow. Is it possible to step through this?
Attachments:
|
|
|
Sure—down the list:
- The input (with explicit parentheses on the composite function)
- The
Map having been applied takes the composition function and "distributes" it to each term in the nested list, at top level (just f/@{a,b} === {f[a],f[b]})
- The composite operation/function
(N@*Mean) is acting on the first list {1,2,4}, which means that it should be applied like N[Mean[{1,2,4}]]. This is because a composite function f@*g—"the pure operator form of taking g of a thing and then taking f of the result"—acts such that f@*g on a means f[g[a]]. This is the definition of function composition, generally speaking. It's just that in Wolfram Language, we don't write f ∘ g, but f@*g.
- The expression
N[Mean[{1,2,4}]] is evaluated in standard order, from the inside out—first, the Mean is taken, giving 7/3, then N of that result is taken, giving 2.333...
- The same series of operations is performed on the second list
- The two results are provided with a
List head/wrapper, as that's how Map works (cf. f/@(a+b) === f[a]+f[b] === Plus[f[a],f[b]])
Hopefully that helps, but let me know if not.
|
|
|
Hey Mitch—"pure" function! But the idea was primarily just to show the "spectrum" from a full, named function with named variables down to a function with no name and whose variables were unnamed. Function of any kind is technically a pure/anonymous function, even if you provide "dummy variable" names for the inputs just like you would in a definition like myNameFunc[x_]:=.... The progression I have in mind is:
mySineAdder[num_]:=num+Sin[num]
Function[num,num+Sin[num]]
Function[#+Sin[#]]
#+Sin[#]&
The first function is a named ("nonymous", you could say, had history taken a different turn). The last three are pure or "anonymous" functions.
|
|
|
Hi Arben and all, I have a question about the last lesson about complexity time on function definition.
I have done this notebook and I want to know if there is a simpler complexity way to code the problem.
PLEASE SEE THE NOTEBOOK ATTACHED TO THIS COMMENT
Thanks Mauro
Attachments:
|
|
|
Hey Mauro—while I could probably figure this out if I sat and looked at it for a bit of time, I think I need to set the precedent that I can't take arbitrary code and rewrite it for you. However, what I am happy to do is to take an explanation of what your code is actually doing, with some examples, and tell you how I'd write a function that performs the operation in question.
|
|
|
Ok, Arben.
I think to have understood where I have made a mistake. It's very fuzzy, how speak with someone change our prospective, by only to expose the problem.
Thanks
Mauro
|
|
|
This is basically it—there are two definitions here, and if one doesn't fit it will try the other. Still, Carl's question of precedence is valid, because ___ really means anything given that it's "zero or more things". The answer is: precedence is given in order from most to least specific definitions.
|
|
|
I had not picked up on that nuance even though I have used it (subconsciously?) as in the examples on recursion. I had not formally articulated in my head. WL does not pay attention to the sequence of definitions in code first, but yes to the hierarchy of precedence, which of course it does. Particular takes precedence over global. It's a grammar thing. But if definitions have equal precedence, then it picks the most recent one. (Correct?)
|
|
|
The documentation page linked by Rohit has this to say:
In the factorial function example used above, it is clear which rule is more general. Often, however, there is no definite ordering in generality of the rules you give. In such cases, the Wolfram System simply tries the rules in the order you give them.
You can check the order that definitions are stored—and tried—by evaluating ?func. (The fact that I had to check the documentation to be sure about this case should tell you something about its relative frequency, I hope!)
|
|
|
I wonder why the /@ stayed pupleRed in the last example of "Good Coding practices" (12. Pure Functions).
See attached screenshot
Attachments:
|
|
|
What I think happened is that he didn't put a space after the "/@" as he was doing it on the fly. It still ran on the fly. If you type it in yourself and put the space in there, it won't be red anymore. You might also see what happens to the # if you deleted the following &, it will turn red due to the syntax error.
|
|
|
The spaces are really just a visual choice made by some programmers—I tend not to use them, and it shouldn't have this effect. I'll try to remember to check the full cell expression after today's class and see if I can figure out what's going on—if you look at the recording, you may note that I didn't expect that to look like that and am messing with it a little to investigate! EDIT: Yeah, it's just written into the cell manually that that should have a particular background color. If you start typing into that space/editing it, you'll retain the color choice.
|
|
|
Hi Arben,
I do not understand what you mean by your last lines -after the EDIT: I want to use different text colors for the comments in one cell. But of course still bracketet by (.........) to indicate that it is a comment.
As some comments are temporarely (like (* FIX this later *) and other comments are permament, I would like different colors for the different kind of comments.
As everything is adjustable in Mathematica, I would be surprised if this is not possible.
Thanks, Bert
|
|
|
In that particular context, I meant that if you press (on mac) cmd + shift + e to see the full cell expression, you could see that the color was "baked in" there. I'd generally recommend only using this for clever little modifications, not as a "primary" means to do things (generally). But it can often provide some insight. As for coloring comments, I recommend just using the Style menu. (Maybe we already dismissed this for some reason, but if so I don't remember!)
|
|
|
What I discovered on the MAC is that if you highlight just the text in the comment, not the (* *) at the beginning and the end of the comment, you can then go to the FORMAT drop down menu and select "Text Color". That will change only the color of the comment you are highlighting.
|
|
|
I don't see an option to start a new Topic, so I just reply.
I just saw Ahmed Elbanna's post, 4 days ago, and I agree :-) Great webinars series. Arben is the absolute BEST presenter I have seen in all the webinars I have already watched. He does it just right on every level and in every detail.
Arben, you're a fantastic teacher. You opened my eyes & understanding to new levels in things I already knew.
I hope you'll be doing much more presentations. My question : Is there a way to change the default color of a comment (* Comment *)?
I can change the Size, Face, but not the color. This would be really convienient as to make an easy distinction between comments :
* Explaining the code and function
* Things that need repair, seriously
* Things that need brushing up or speed enhancement
* Alternative versions
* Spots in the code that need extensions in the future
* Etc. It would really be great to have this color function.
I know that I could do this with 'text' parts, but that will break the possibility to run the complete code with one Shift+ Enter.
|
|
|
Re. changing the default color of comments look at Preferences / Appearance 
|
|
|
Hi Rohit,
I just saw your answer to my first question a minute ago, while going through the list. I got a bit lost in the beginning.
I actually now remember having found that it is possible to change the color for the comments.
But what I am actually looking for is on the fly use different colors for different kind of comments.
E,g. color 1 for code annotation
Color 2 for alternatives
Color 3 for comments like "Can be done better and faster"
Etc.
|
|
|
Great course! (As usual from Wolfram). I really like the overall structure, the examples, the smaller checkpoints and the exercises at the end of each day. Here are some improvements for the 5th exercise of Day 4
txt = ExampleData[{"Text", "DeclarationOfIndependence"}]
(LetterCounts[txt, 2] // ReverseSort)[[;; 20]]
The solution provided uses Take[.., 20], this takes the first 20 elements. Not the 20 most frequent ones.
Adding ReverseSort post fix style, sorts the association biggest->smallest.
Similar with the second part.
((WordCounts[txt // DeleteStopwords] // ReverseSort))[[;; 20]]
|
|
|
Let me know if I have this wrong, but I believe that LetterCounts is always automatically reverse-sorted by value and thus the first n elements—as taken by Take, for example—should always be the 20 most frequent elements. Do you have a counterexample in mind? (Or perhaps this behavior was different on an older version, perhaps pre-13 or even pre-12?) EDIT: Oh, I see—there's an issue with the version where stopwords are deleted. Thanks for pointing that out; I'll fix it!
|
|
|
Arben, First thank you for teaching this class. This has been very helpful. I am running into some unexpected behavior. I just downloaded Version 14, and when I do TreeForm of a list I get: 
but when I do the same thing using Plus, I get: 
I was expecting to get the same thing but with List replaced with Plus. I am a bit puzzled. Many thanks for your help.
Michael O'Connor
|
|
|
Hey Michael! The reason this happens is the order of evaluation. I have two suggestions for you to try which I think will clarify this behavior:
Trace[TreeForm[Plus[1,2]]]
TreeForm[List[a,b]] (=== TreeForm[{a,b}])
Let me know if this illuminates the difference for you.
|
|
|
Also, Plus has the NumericFunction attribute whereas List does not.
Thus one sees the following behavior from TreeForm: 
|
|
|
Arben, this does help! Thank you very much!!!
|
|
|
From yesterday's lesson, does anyone understand why
larger[x_, y_] := If[x > y, x, y];
Fold[larger, {3, 1, 2, 6, 5}]
returns
larger[larger[larger[larger[3, 1], 2], 6], 5]
and not 6?
|
|
|
As do I. Coe, you might have given larger an incorrect definition that hasn't been overwritten for one reason or another—try restarting your kernel and running these two lines again? (Re: the new comment—the semicolon is fine. It's not necessary for SetDelayed definitions since the evaluation is, as claimed, delayed!)
|
|
|
Try removing the semicolon
|
|
|
map mystery Can someone explain what is going on in the expressions below the tree, or would this be too advanced for the level of this course (which, if it is, is OK with me)? (See attached png file)
Attachments:
|
|
|
Attachments:
|
|
|
We really do abhor a brute force solution. This is a fun little question; please see embedded response!
PLEASE SEE THE NOTEBOOK ATTACHED TO THIS COMMENT
Attachments:
|
|
|
Thank you, Arben!!! That's a really neat approach. Had not yet thought along the path of creating a list of all the terms. But entirely consistent with thinking about the heads and changing them. That's a powerful analytical tool. Your solution has a lot of pedagogical value. I am going to be staring at it a bit. If you are on a roll, I've got another one coming as soon as I can figure out how to ask it properly. Let me take a crack and if it needs more let me know:
It has to do with a problem in FM theory, where recognizing that
Cos (B Sin [w t])
can be expanded as a Fourier series whose coefficients are an ordinary Bessel Function of the first kind = Jo(B) + 2 Sum (J2n(B) Cos (2 n w t) ) Then you have to truncate the series to get the coefficients of interest. There is a similar expansion for Sin(B Sin (w t).
You can sample an FM signal and do an FFT and just see the spectrum, but recognizing the Bessel Function behavior provides an intuitive understanding of FM theory (bandwidth, mod index, S/N properties etc) that even when FM was really popular few people grasped. Now it's beginning to be a lost art.
What I never figured out how to do was use WL pattern matching and mapping tools to "recognize" and derive this classical solution. It has other analytical advantages for other problems too.
|
|
|
Thanks Arben, I will get back to you on that FM question. I have to find my notes on when I last tried to do it. "If I'm reading your (original) post correctly, you could also do pattern-matching or selection by going directly into the cosine terms, extracting the coefficients of the omegas with CoefficientList and grabbing only those cosine terms for which the absolute value of the difference is 1" That sounds kinda like what I was originally trying to do but unsuccessfully. Could you show an example?
|
|
|
Let's see:
PLEASE SEE THE NOTEBOOK ATTACHED TO THIS COMMENT
EDIT: Really better just to use Coefficient. I don't like CoefficientList anymore; it's dead to me. So this is probably the most efficiently and extensibly you could write it?
Cases[yexp,
c___*Cos[arg_] /;
Abs@Total@Coefficient[arg, {ω1, ω2}] == 1]
Attachments:
|
|
|
Delicious!!! Once again a pedagogical Rosetta Stone.
Thank you ,
Carl
|
|
|
Hey everyone, care to take a stab at explaining why:
Total[{{a, b, c}, {u, v, w}, {x, y, z}}]
returns
{a + u + x, b + v + y, c + w + z} (*One of our Day 4 "Check Your Understanding" questions*)
I've looked at the documentation for "Total" and still can't figure out how this result is obtained.
Thanks in advance,
|
|
|
Hey Coe, I can explain this. Total is documented to take the elements of a list and add them together. In other words:
Total[{a,b,c,...}] === Plus@@{a,b,c,...} === Plus[a,b,c,...]
In standard notation, that means that Total[{a,b,c,...}] just evaluates to a+b+c+.... Nothing too surprising here, I think. The misunderstanding likely comes from two places. Since Wolfram Language is fully symbolic by default, we never said what a, b, c and so on might be. They don't need to be reals or integers or even numbers—in fact, try this for me:
randomImages=Table[RandomImage[{0, 1}, {25, 25}], {2}]
Total@randomImages
If there is a sense in which the arguments inside the List fed to Total can be added, then Total will add them because it is very literally just performing the pattern-matching term-rewriting transformation rule I expressed above. Now that we know what Total does, if we want to understand the output of Total[{{a, b, c}, {u, v, w}, {x, y, z}}], we need to ask: what does Plus do when fed multiple List objects? You can try this out manually, but that's basically just rewriting the thing that we're not understanding in the first place. Instead, you might try Attributes[Plus]. You get back several attributes, but the important one here is Listable. If you check the documentation for that, you'll see examples which basically replicate the behavior that prompted this question:
In[1]:= {a, b, c} + {x, y, z}
Out[1]= {a + x, b + y, c + z}
This is to say: Listable functions automatically thread over their arguments when those arguments are lists. Most built-in mathematics functions are listable, and this attribute allows for highly optimized code compared to looping or even mapping. In the case of Plus, this behavior also happens to correspond to the standard mathematical operation of addition acting on vectors, matrices, and tensors more generally. After all, if you have the vectors a, b, and c, you find their sum by element-wise addition, right? The same is true for matrices and so on. (And in fact, people are often lazy and will "add" a scalar to a vector when what they really mean is that they want to add a constant vector to a vector. For example, somebody might say x = <1,2,3>, then say something like x + 1, when really they mean x + <1,1,1>. This is also automatically handled by Listable; feel free to evaluate {a,b,c}+1 and see the result, or even {{a,b},{c,d}}+1.)
|
|
|
Arben - Thank you very much for the detailed explanation. I am finding this material somewhat difficult but rich and rewarding when something sticks.
|
|
|
I don't think that this is an inconsistency: if you do extract a head with [[0]], that head does not have some internal structure that you can probe by asking to get its parts. What is the second part of Graphics?
|
|
|
It seems to me the Head is just a node. I don't understand why it should be different from any other node. If it doesn't have a structure, why should any other node have a structure? I suppose there is something in the engine which interprets the head node differently from other nodes.
|
|
|
I think I see what you mean; I think that that's fair enough if you're thinking about it in terms of TreeForm. The discrepancy, such as it is, exists because technically Part is always "reaching into" an expression (cf. the reason you can't [""] use Part on atoms is because they don't have an "inside" to reach into). That is: whenever you say expr[[n]], you are going into expr and extracting something. If you have not just a single n, but exprp[[m,n,...]] then the number of elements in that sequence specifies the Depth at which you are accessing the structure of expr. The issue here is that expr[[0]] does indeed not work like this: because indexing in Wolfram Language starts at 1, this is not "getting a part" of expr in the same sense that expr[[n]] for n≥1 is, but is "special case", manually-implemented extra behavior. I do see why one might consider this inconsistent, but my personal sense is that [[0]] is simply used as a convenient syntax shortcut for Head@. If we didn't have it, the behavior of Part would indeed be more consistent, but it would also be less functional for some particular uses... my perhaps-frustrating advice is to do a bit of compartmentalization about the meaning of Part, here. We're already doing that when using Part on SparseArray or Dataset atoms, so why not add one more case where Part is doing something which is maybe a little bit misleading... Finally, I do want to clarify something: because this [[0]] is a special behavior which does not give you the 0th part in the technical sense (as there is no 0th part in a language which indexes from 1), it is not the case that there is an implicit 0 which starts off any Part sequence. Moreover, there's nothing in any given expr that you cannot access because of this: the entirety of the internal structure of expr (if it has any) is accessible without making any reference to any 0th part. It's just that if you would like to get not the internal structure, but the thing that wraps around that internal structure—which in the strict sense is not a part—then we allow you to do that with Part[expr,0] as a convenience. The succinct version is maybe:
Part is really only intended to talk about the parts of a compound expression, and the "parts" of an expression are always internal to the expression.
- Because you could already access everything about an expression but its head with
Part, we added a special case of asking for """the zeroth part""" so that you could get that last bit of information without having to leave Part-world.
|
|
|
Thanks. That's really helpful.
|
|
|
Good catch! I've fixed this in our repo and it will be fixed in our next deployment.
|
|
|
I asked in the BigMarker Q&A panel how to upload a WL Notebook to my Wolfram Cloud account. The reply was to use the "upload" button in the upper right corner of the Wolfram Cloud window. This doesn't work; I get the error message, "To access this feature, subscribe to a plan." Apparently, the Basic plan isn't good enough. I can upload files through Mathematica on another machine through the File->Save to Cloud function. I don't understand why that works but simply doing an "upload" in cloud does not. Is there a good reason for keeping a random user from uploading any notebook to a Wolfram Cloud account through the web? If not, please file this as a bug. One note for the staff answering questions: when they are answering a question like this, they should try to perform the function with the same level of privilege/access as a normal customer. In this case, the Wolfram Cloud "upload" function should have been tried on a Basic plan.
|
|
|
Hello Phil, Thank you for letting me know. I apologize for the confusion created. Upon a detailed look, the behavior described seems to be related to the fact that Wolfram Cloud and Wolfram Desktop are two separate products. The basic plan for Cloud grants users the basic functionalities needed for a smooth Desktop operation, but it does not grant access to the Wolfram Cloud as a product in and of itself. Basic Plan restrictions This is why the direct dynamic interaction within Wolfram Cloud is not available but the use of CloudPublish from Desktop, either programmatically or through the menu tool, works as expected. I will try to improve my Q&A support with your feedback. I have already setup a basic account for testing of future questions. Thank you!
|
|
|
Hi Everybody! I would like to produce documents effectively (so programmatically) and I need to find help about producing cells, sometimes cells within cells (within cells?). Can anybody give a good reference? Such things as TextData, BoxData, ToBoxes, ToString and similar.
|
|
|
Yes, I also found that I couldn't use the code output by those boxes in situ. Entering it into a new code cell works fine.
|
|
|
To produce cells look at Cell, TextCell and ExpressionCell. Here's my little experiment on WolframCloud to programmatically produce Hierarchical Textcells with Section and Subsection styling and CellGroup function. 
and the result is this 
Cheers.
|
|
|
I'd highly recommend Professor Richard J. Gaylord's Wolfram Language Fundamentals
|
|
|
Hate to redundant, I still can't get by this. If this is a real error, other errors I get may be me or Mathematica - can't tell. Btw, $Version returns: 14.0.0 for Mac OS X ARM (64-bit) (December 13, 2023).

|
|
|
Please see the answers downthread—the easiest way I know to explain this is that if you say ax, how is Wolfram Language to know that you actually, truly, really meant a*x? It can't. If you were to type myVar^2, you ostensibly would not expect to get m^2 * y^2 * V^2 * a^2 * r^2, so why expect differently for ax^2? (Since tone is never conveyed well over text, I want to be clear that the intended tone here is "Socratic" rather than "snippy" ;).)
|
|
|
ax is on variable not two variables
a * x is and expression equal to a space x
|
|
|
I think the best way to see what is going on, on your own machine, is to look at y//FullForm and z//FullForm. They are quite different. 
However if you insert a space between a and x in your expression for z, then y and z should be the same. [If you are somehow stripping out spaces, then that will cause you problems. Mathematica really uses the spaces as Arben says. I am already finding that when I am getting odd results, using FullForm, TreeForm etc can make things clearer.
|
|
|
Perfect. I get it, thank you.
|
|
|
While working with the exercises for Day 3 (Syntax and Expressions), I got the following error message while attempting Exercise 4 (ListLinePlot for airline passenger data), namely
"An improperly formatted option was encountered. The left-hand side of the option was not a symbol or string*
My solution(s) worked fine initially, but then went wonky all of sudden. In fact every plot in the notebook threw the same error message, whether options were specified or not. (Also all of the dynamic Hints and Solutions boxes disappeared, but that's not my main concern right now). Please see attached notebook..
Attachments:
|
|
|
Hi Michael—I think the issue comes from the formatting that this notebook has for that ListLinePlot input. Ideally, it would just be an input... but when you click into it, you can see that there's a kind of yellow box around it. Basically, this is a text cell formatted as input and so it won't evaluate correctly, if we're seeing the same thing. (I think your specific errors with respect to Dynamic elements here are kernel-specific and thus not "carried with" the notebook that you uploaded when I open it on my end, so I can't see for sure what your issue was.) if you just start typing ListLinePlot in a new cell, you should be able to plot the data without issue. I think what's happening is that on our end, making the Hint/Solution buttons does something unfortunate to the formatting of code blocks that we had intended for you to type into. I'll look into this with our team.
|
|
|
Arben, Thanks, that makes a lot of sense since both errors occurred at the same time. I'll try out your suggestions and see what happens.
|
|
|
Yes, I also found that I couldn't use the code output by those boxes in situ. Entering it into a new code cell works fine.
|
|
|
Arben, Just to let you know I opened this notebook the next day in order to try your suggestions, and it had healed itself overnight. One of those situations you're glad it's fixed without any effort, but not quite sure why. Anyway, all is good for now, and everything is working again as expected. I even entered some new comments and code into the notebook, and nothing seemed to upset it again. Fingers crossed! :<) :<)
|
|
|
In[84]:= Clear[x, y, a, b, c]
In[85]:= y = a x^2 + b x + c
Out[85]= c + b x + a x^2
In[86]:= Expand[y^2]
Out[86]= c^2 + 2 b c x + b^2 x^2 + 2 a c x^2 + 2 a b x^3 + a^2 x^4
system: Apple M2 Ultra, 14.3 (23D56)
Mathematica: 14.0.0.0 Mac OS X ARM (64-bit)
|
|
|
Is anyone else experiencing problems with the question submission bar in bigmarker on Chrome? When I go to type, the text box turns white, with white text, rendering the text unreadable.
|
|
|
I know you touched on this, but in exp = 1 + x^2, exp[[2, 1]] returns x, yet exp[[1, 1]] is longer than the depth of the object, why again?
|
|
|
exp[[2, 2]] returns 2, the second part of the second part, I'd expect exp[[1, 1]] to return the first and only part of the first.
|
|
|
In Wolfram Language, the structure of expressions and how they are indexed can sometimes be counterintuitive if you're not familiar with the underlying representation. Let's break down your example to understand it better. Consider the expression exp = 1 + x^2. In Wolfram Language, this is internally represented as Plus[1, Power[x, 2]]. The head of this expression is Plus, and it has two arguments: 1 and Power[x, 2]. exp[[2, 1]] returns x because it's accessing the first part (x) of the second argument (Power[x, 2]) of exp.
exp[[2, 2]] returns 2 because it's accessing the second part (2) of the second argument (Power[x, 2]) of exp.
Now, regarding exp[[1, 1]], the confusion arises because 1 is an atomic expression in Wolfram Language (it does not have a head and arguments structure like Power[x, 2] does). Atomic expressions include things like numbers, symbols, and strings. When you try to access a part of an atomic expression, it results in an error or an unexpected result because atomic expressions are considered as having no parts. So, exp[[1, 1]] is trying to access a part of the atomic expression 1, which doesn't have any parts, hence the issue. In Wolfram Language, the parts of atomic expressions are not accessible in the same way as the parts of composite expressions.
|
|
|
AtomQ[#] & /@ {exp[[1]], exp[[2]]} returns {True, False}, and Atoms don't have parts (errrrrrr... it's counterintuitive).
|
|
|
...and this can be seen: AtomQ[exp[[1]]] returns true.
|
|
|
Yeah, it's just atoms have parts as far as atoms are concerned, as apposed to atomic expressions. The same signifier ("atom") points to different signified concepts depending on the context, hence counterintuitive. Essentially, atomic parts are not the same in the case of the fundamental concept in chemistry and physics and atomic expressions and therefore not covered by Part in the normative sense. So an error message is returned.
|
|
|
There are sub-atomic parts
|
|
|
Understanding this helps in navigating subjects that cross disciplinary boundaries.
- GPT4
|
|
|
Hi Lewis—I understand what you're saying abstractly, but am having trouble understanding how it applies into specific to the discussion of atoms today. Let me offer a few clarifying comments and we can go from there?
- Atoms are the fundamental building blocks of compound expressions in Wolfram Language.
- Any compound expression, when you get to "the bottom of it"—literally, in the sense of
TreeForm—is made up of atoms.
- "Atom", in the context of Wolfram Language, is meant in the original Greek sense: "a thing which cannot be cut". What we mean by "uncuttable" is that
Part/[[ ]] does not fundamentally work on atoms; various functions can pull things out of atomic objects (cf. Numerator and Denominator for Rational atoms, ReIm for Complex atoms, EdgeList for Graph atoms, and so on).
- However—and it's a big "however"—there are some cases where an atomic object might be expected to have its insides accessible via
Part (e.g. Dataset, SparseArray, NumericArray...). To that end, the front end will automatically "translate" a user request for Part into the correct underlying code to give the "expected" result. This lets you access the parts of a SparseArray "with" Part, for example.
- Ultimately, though, this is a syntactic convenience—just like, in a sense, being able to say
a+b rather than Plus[a,b] or {a,b,c} rather than List[a,b,c]. There exists an underlying "truth" and Part is not part of that truth when it comes to atoms.
|
|
|
Nice! I hadn't thought (until today!) about the derivation of the word atom. So, 'tom' as in 'tomography'.
|
|
|
Yes, the very same! It's from τόμος, which I think is from τέμνω, which is something like "to cut/slice/section/portion".
|
|
|
I think the apparent confusion regarding the word atom is as a result of an error in the evolution of our scientific knowledge. It is only relatively recently that we discovered that 'atoms' of, say, radium are not really atoms in the logical sense of the word. Then we repeated the mistake, calling some of the sub-atomic bits "fundamental" only to find... In a parallel universe where the Wolfram language was developed in 1880, the concepts of atoms in Mathematica and Chemistry would have been consistent. Although some physicists maintained that the atoms of the chemical elements were fictional conveniences for the sake of calculation and that, if they even existed they would be too small to ever be known. Then came 1905 and Einstein's analysis of Brownian motion.
|
|
|
One thing that really attracted me to Wolfram was how the expressions in a book I picked up published in 1988 still computed. Thankful, in this universe there is forward compatibility, even amongst changes in scientific knowledge.
|
|
|
I'm with you there—I immediately thought that the following image, from this blog post, was very striking: 
|
|
|
Although Show[Graphics3D[Stellate[ Icosahedron[ ]]]] wasn't forward compatible.
|
|
|
Heh, it's true :). At least in this case it's been superseded by something simpler and clearer!
|
|
|
I can heartily recommend this. While I am in no position to judge Wolfram's contribution to Physics, the ideas are fascinating and are something I would like to pursue. If I am hearing him correctly, he is attempting to make sense of Physics by looking at it as a system that is computable by the application of rules for re-writing. He seems to be saying the system evolves what look like small black holes and "elementary" particles from vacuum energy. Of course he is talking to a professional physicist here so we hear him respond to some good questions. I am stricken by the similarity of the method Wolfram is proposing and the spirit of the the approach we seem to be taking in grappling with Mathematica. Very stimulating! https://www.youtube.com/live/ITJ3AF3TK5M?si=rECCBuBAAVWa_Im4
|
|
|
Steven/Arben - I too am getting the INCORRECT result. I am also running Mathematica 14.0.0 on Mac silicon. (This might also explain some of the results I have been getting!)
I create a notebook and set y = ax^2 + bx + c. I then try Expand[y^2] and get the following:
ax^4 + 2 ax^2 bx + bx^2 + 2 ax^2 c + 2 bx c + c^2
I have attached my notebook and an image making it clear what element is incorrect in Mathematica's answer.
Attachments:
|
|
|
PROBLEM PROBLEM PROBLEM When I create a notebook and try y = ax^2 + bx + c, then Expand[y^2] gives ax^4 + 2 ax^2 bx + bx^2 + 2 ax^2 c + 2 bx c + c^2 in my notebook, which is incorrect, while yours has c^2 + 2 b c x + b^2 x^2 + 2 a c x^2 + 2 a b x^3 + a^2 x^4 which is correct. I'm, using Mathematica 14.0.0 on Mac silicon. Here is my notebook
|
|
|
More info:
When I do "y = ax^2 + bx + c", with explicit asterisk, then Expand[y^2] is correct
c^2 + 2 b c x + b^2 x^2 + 2 a c x^2 + 2 a b x^3 + a^2 x^4 Note: The preview removes the explicit asterisks. What works is
y = a asterisk x^2 + b asterisk x + c
|
|
|
Write "a x" with a space between a and x. Mathematica interprets the space as a multiplication.
|
|
|
Addendum to Lara's explanation: "ax" is read as one symbol, as opposed to "a x" which is read (in the example case) as two distinct symbols of a numeric type, so the space is interpreted by Mathematica as an implied multiplication.
|
|
|
I don't believe this is a space issue. The notebook shows input (w/o spaces) and the incorrect output.
|
|
|
Hey Coe—I'm not sure what you mean. The attached notebook is missing the spaces between the coefficients and thus produces the incorrect output. You want:
y=a x^2+b x+c
or, explicitly:
y=a*x^2+b*x+c
in order to get the correct polynomial expansion. @ Steve, you can type your code between two backticks to prevent it from formatting via markdown, which is why the asterisks are being used for formatting rather than displaying.
|
|
|
When I enter everything without spaces I get the wrong answer. When I enter WITH explicit asterisks, I get the right solution. The attached image shows what is entered and the result.
Attachments:
|
|
|
Steven - I get the correct answer when using explicit multiplication:
y = a*x^2 + b*x + c
Why is this? Arben?
|
|
|
To be absolutely clear: this is equivalent to asking why var^2 does not return v^2 a^2 r^2. If you don't type a space or an asterisk between two letters, there's no way for the system to know that you're talking about two separate symbols.
|
|
|
Bang head with hand. I forgot. Thanks.
|
|
|
It can happen even after a decade of using the language—I was once thwarted for an entire day by an errant curly/("""smart""") quote breaking a string expression when I first start working here!
|
|
|
Another way of saying the same thing: Mathematica is taking ax^2 to mean (ax)^2. This can be seen by asking for the FullForm. In terms of today's lesson: AtomQ[ax] returns True , AtomQ[a x] returns False.
|
|
|
Hi Arben, Would please clarify the following terms: vector, array, matrix, expression?
And regarding the docs, what's the difference between options and properties in a function?
|
|
|
When I'm using those terms, I mean:
- Vector: something that you can describe with 1 index. It could have a length of 2 or a million, but you could get any singular element out of it by doing
vec[[n]].
- Matrix: something that needs two indices to get any individual elements from: say, the element at the first row and third column could be accessed with
mat[[1,3]].
- Tensor: generic term for anything where you'd need more indices to describe the position of a single element. Note that this is not really an appropriate definition in the physics sense, but I'm being a little loose with it. You can think of them as the general case of the special "one-index" and "two-index" cases of "vector" and "matrix", respectively.
- Expression: any sort of singular "thing" in Wolfram Language—that is, anything that's not a sequence like
a,b. a is an expression, Plot[x,{x,0,5}] is an expression, and so on.
You can see more of the fun of conflicting definitions here.
|
|
|
I thought I understood this material during the lecture; most things made sense. Some parts of Problem 1 however just don't seem right. For example, why does pat3 give the following result?
exprs = {1, h[], h[a], h[b], h[a, b], h[a, a], h[a, b, c], g[h[a, b]]}
pat3 = x_
Cases[ exprs, pat3]
{1, h[], h[a], h[b], h[a, b], h[a, a], h[a, b, c], g[h[a, b]]}
I see no way to get this result. Thanks in advance,
|
|
|
pat3 is x_, which means "any one thing—call it x." Every element of exprs is just a single thing, so they all match. Because we're not using that x anywhere, this pattern is equivalent to just _, i.e. "any one thing".
We might see a named pattern like x_ in a standard function definition:
f[x_]:=x^3
The x on the LHS has nothing to do implicitly with the "any one thing" denoted by the _. The x is just a dummy name that we give to that one thing (the one thing that appears in f's brackets) so that we can refer to it on the RHS. Consider the example:
f[x_]:=5
There's no mention of x on the RHS, so it's pointless to even name it on the LHS (in some sense.) It would be exactly the same to instead say:
f[_]:=5
The point is that "f of any one thing" should be 5. We don't care about the input here, so why bother to name it if we're never going to use it? In this sense, we are saying that f is a transformation rule that takes anything of the form "f of any one input, and I don't care what that input is" and returns 5.
|
|
|
My apologies folks, I mis-wrote the equality that I am asking about. Again -
In today's post-lecture questions "pat2 = _h" Case tells me that pat2 matches the following elements in exprs:
{h[], h[a], h[b], h[a, b], h[a, a], h[a, b, c]}
Does this mean that **pat2 = _h = h_**? It seems like it, but this seems odd to me in that we are PATTERN MATCHING and, it seems to me, elements in one order should not necessarily be equivalent to elements in a different order.
Comment?
|
|
|
pat2 is _h, which explicitly means: "any one thing with head h". This is not the same as h_, which means "any one thing—call it h". It is (except for perhaps some pathological edge cases) the same as h[_], which is "h of any one thing."
|
|
|
In today's post-lecture questions "pat2 = _h"
Case tells me that pat2 matches the following elements in exprs:
{h[], h[a], h[b], h[a, b], h[a, a], h[a, b, c]}
Does this mean that pat2 = h = h? It seems like it, but this seems odd to me in that we are PATTERN MATCHING and, it seems to me, elements in one order should not necessarily be equivalent to elements in a different order. Comment?
|
|
|
question = "If Mathematica is a term rewriting system, when I write a programme in Mathematica, am I writing a term rewriting rule, and is the programme a function?"; If[question==={"yes", "yes"}, "At what point does a rule become a system?","Help!"]
|
|
|
Yes! The evaluation system is effectively a huge database of pattern-matching term-rewriting rules. For example, think about:
D[x^3,x]
We know that this is "the derivative of x cubed with respect to x", and we know that when we see this pattern—the derivative of x^n_, if you will—that we should take the power, drop it to the front, and then subtract 1 from the power. The Wolfram system is effectively doing the same thing: it sees that something matches the pattern D[x^n_,x] and says what we do: "I know what to do when I see that: D[x_n,x] :> n*x^(n-1) and that's what's returned to us. When you write your own functions, you are effectively adding to this database of term-rewriting rules (and are often using those rules as foundations for your own definition). In this way, any program you write is just about matching patterns and transforming the appropriate ones into something new.
|
|
|
Wonderful explanation! I'm going to give this more thought. I'm trying to get my head around Wolfram engine.
|
|
|
Anyone grok this list operation: Alphabet[][[;; 10 ;; 4]]
I understand Alphabet[]
I understand Alphabet[] [[;;10]]
I understand Alphabet[] [[;;4]]
I do not grok what's happening when the 2nd and 3rd statements are combined. I thought the ";;" operation acted like a pipe. The solution {a, e, i} isn't what I think a pipe should give.
|
|
|
Hey Coe, could you be a little clearer in your description of your inputs, their actual outputs, and the outputs you would expect? In the meantime, let me explain the meaning of each line you've included here.
Alphabet[][[;;10;;4]]
This is equivalent to Alphabet[][[1;;10;;4]]. This means "starting with the list of all of the letters in the (Latin) alphabet, take the first through the tenth elements in steps of 4." I.e., that's elements 1,1+4,1+4,+4===1,5,9. (You don't go to 13 since the initial list only has 10 elements.) And indeed, that's what this code does—cf. MapIndexed[#2[[1]] -> #1 &, Alphabet[]] or Thread[Range@26 -> Alphabet[]] to see it directly. Actually, I see what you were initially asking. I think the above sufficiently clarifies it, but "in order":
Alphabet[] provides a list containing the characters of the Latin alphabet
- Appending
[[;;10]] is the same as appending [[1;;10]] and is extracting the 1st through 10th parts of the list containing the alphabet
- Similarly, appending
[[;;4]] is equivalent to appending [[1;;4]] and is extracting the 1st through 4th parts of the list containing the alphabet
Doing [[a;;b;;c]] is not the same as doing [[a;;b]][[;;c]]. The "sandwich" construction specifically means "go from a to b in jumps of size c"; it's different from "chaining" ;;/Span commands through [[ ]]/Part.
|
|
|
Hello Coe! Arben's explanation made me want to see it in color. This is what came of it. I hope it helps.
PLEASE SEE THE NOTEBOOK ATTACHED TO THIS COMMENT
Have fun!
Attachments:
|
|
|
Hey Arben, I've not used associations before and I am trying to imagine what is their superpower. I'm not really a software writer, I just play one when I'm trying to study or solve engineering problems. One idea that jumps off the page is using a list of variable value assignments that can be summoned in a program without actually defining the variables outside of the context of the operation using them. That's kind of neat. I'd have to try that out and see if it makes a program easier to write or understand. But I suspect that's just the tip of the iceberg (as is everything else in the Wolfram language). What do you say is the superpower in using associations?
|
|
|
Hey Carl! Indeed, you can think of associations as constituting some "local map" between keys and values (and indeed, that might be part of the reason why they can be "indexed" with single brackets like functions can, though this is just a wild guess). The primary value of associations in my view comes from the the organizational structure. For example, suppose I have a nested association:
scores=<|"Bob"-><|"Geography"->100,"Mathematics"->80,"Chemistry"->90|>,
"Alice"-><|"Geography"->90,"Mathematics"->100,"Chemistry"->85|>,
"Carol"-><|"Geography"->Missing["Absent"],"Mathematics"->100,"Chemistry"->95|>|>,
Now, without needing to remember which student or score is where, I can do something like:
scores["Bob"]
or:
scores["Bob","Chemistry"]
or:
scores[[All,"Mathematics"]]
This can be very useful for obvious reasons, especially as datasets get larger and more complicated. We'll discuss this more later in the course, but you may recall that pure functions work with numbered, unnamed slots:
#1+#2&[a,b]
returns:
a+b
But this isn't the only way they can work—they can work with slots named by keys as well:
#cat+#dog&[<|"cat"->1,"dog"->2|>]
will return 3. This lets you write code that not only extracts the appropriate parts very easy, but performs various queries in a super readable and simple way. For example, the following code will select any students who have a chemistry score of 90 or higher:
Select[scores,#Chemistry≥90&]
Finally, from a technical perspective, it is faster to add or remove key-value pairs to an association than to add or remove elements with a list. This doesn't really crop up at the example scales we're talking about here, but can have an effect at larger sizes.
|
|
|
Hi arben,
Yes this is the tip of iceberg. I suggest you hash table as something to know. O(1) as a search algorithm. Hash tree and topology is a rich context to know
|
|
|
Hi everybody—I've added today's "filled-out" notebook to the materials folder. See you tomorrow!
|
|
|
The link in the email I received doesn't work. How do I navigate to the materials folder? I looked around and didn't see an obvious link.
|
|
|
Arben, how do I post without replying to someone else's post (like I am doing now)? I do have a question about Riffle[ ].
Riffle[{1,2,3}, {x, y}]
outputs {1,x,2,y,3}, understandably. But
Riffle[{x,y}, {1,2,3}]
outputs {x,1,y}. Why? I would have expected to get {x, 1, y, 2}. Thanks.
|
|
|
Daily recordings will be shared with the group each day, so you can catch up on any sessions you miss. Looking forward to it!
|
|
|
I can't make it at this time on MWF, but can on TTh.
|
|
|
Day 7: Found the notebook to download but not the "data" file. Where can I get this?
|
|
|
Almost missed this down at the bottom of the thread, but the amoeba folder should now have a data folder there!
|
|
|
Reply to this discussion
in reply to
|