Exploring Wolfram Language V14.1

Stephen Wolfram demonstrates Wolfram Language version 14.1 (released as the 36th major release), highlighting major new and improved capabilities. Key additions in 14.1 include: a single unified Wolfram app install; semantic search and industrial-strength vector database support (with semantic indices, vector DB creation/use, and RAG/LLM prompt generator pipelines); expanded LLM integrations and benchmarking; a new symbolic arrays/tensors system for representing matrix/vector dimensions symbolically and performing symbolic differentiation; numerous mathematical, plotting, PDE, and differential-/difference-equation tools; biomolecule import/visualization and protein folding via ML; ML acceleration (CoreML/DirectML/GPU) for inference; richer video creation/processing utilities; historical-geography/time-aware country data and temporal/space-time visualizations; astronomy plotting and precise rise/set computations; AR publishing and geometry features; notebook UX improvements (cell-linked percent, typing affordances); freeform evaluation and better external-language encapsulation (Python environments, dependencies); diffing utilities for files/notebooks; compiler information and toolchain improvements; and mechanisms to build pruned standalone Wolfram-language libraries for embedding. The talk is a live demo with many interactive examples and occasional long-running computations.
Chapters
Hello, everyone. Welcome to something which seems to happen now about twice a year run through of our latest new versions of Orphan Language and Mathematica. So yesterday we released version 14.1, and for many companies, kind of a 0.1 release would be nothing terribly significant for us. 0.1 releases are big. Point X releases are big. We're kind of taking our whole kind of R and D pipeline and just twice a year taking the current state of it and releasing it as a new version. We try and make integer releases be kind of times when whole stories are finished. Pointx releases are times when we're releasing pieces of major new functionality, but it hasn't yet told a complete story. But often those pieces are very valuable and interesting in their own right, and that's what typically happens in our 0.1 releases, and that's what's happening in version 14.1. It's always exciting for me to see these versions come together. I use Wolfram language every day a lot, actually. I've been doing a lot of science, particularly recently, which has been making very intense kind of use of our technology. And I usually don't start using the latest and greatest version until it's passed pretty much all of its testing, because frankly, I'm in the middle of doing science and I don't want to be bothered with the some version which isn't really quite ready yet. So I don't get to see these versions much before all of you get to see them in their full final form. Of course, we've been poking at them and testing them for a long time before that. And in fact, one of the things we've been doing is live streaming most of the design reviews that lead up to these new versions of Wolfram language. So many of the things I'll show today people will have seen, and you'll be able to look at them in the archives when they were being designed in the process of our kind of open design mechanism. So actually this version 14.1 contains an unusually large number of very long requested kinds of feature additions. So that's kind of a nice thing to see, long requested by many people, including myself. So I'm pleased to see those things. Generally, some part of what we're doing is very sort of long gestation period, some part is shorter gestation period. There are things which are now being released in version 14.1 that we started working on many years ago, other things that we started working on only within the last six months. It's a mixture of those kinds of things. Actually, this version version 14.1 has I think 89 completely new functions that it's a bit more than any version for the last couple of years. So we're a little bit ahead of the curve there. It's also got a lot of updates and bug fixes and those kinds of things to other pieces of functionality. So there's a lot in version 14.1 I'm going to try and go through here fairly quickly, different features of 14.1. Hopefully we'll have time at the end for some Q and A about these kinds of things. It's worth also saying that some part of sort of what's new and exciting in version 14.1 has to do with kind of things that are out there in the world these days like LLMs and AI and so on. But there's a huge chunk of work that has to do with our kind of long term mission of kind of making the world computational. That has nothing specifically to do with kind of the latest excitements about AI and so on though those are useful to us both as things that we can make use of internally within our language and as a kind of new linguistic user interface that we'll be seeing more about actually in the next few months to our language. So. But the kind of, I would say one of the things that's happened as a result of kind of the world of AI is that not only now do we have lots of human users, I'm happy to say many of the kind of leaders of all sorts of computational X fields have been in many cases very long term users of our technology. I like to think that our technology is what's often enabled computational X for some X to come into existence. We've kind of tried to define a language for thinking about things computationally that's important for creating a computational X. But in addition to those human users, all sorts of human users, ranging from sort of the most advanced researchers to all sorts of fairly beginning students and so on, hobbyists, people in lots of kind of industrial and professional settings and so on. In addition to all of those human users, another category of users these days are AI users. Things like, well, LLMs calling Wolfram language as a tool. And the real challenge there is how well can the LLM kind of know how to take the chat that you're having with it and turn that into a piece of computational language that can then we can then kind of operate with and do precise computations on. And that's been getting progressively better. We'll probably see some advances in that in the near future. We've been working on that extensively, both ourselves and in collaboration with various producers of LLMs and so on. But the emerging model is you're using the AI, the LLM system as the kind of linguistic interface, the place where you're kind of chatting with something to kind of clarify your ideas once they're clarified to the point where the LLM can say, yes, that corresponds to this thing in computational language. I'm going to just write this Orphan language code for you. Then you can run it and you can do the operations you want to do. But more important, you can see in this kind of actual, this sort of box of solid computation where you're seeing kind of the input, the Wolfram language input, which you can read that the LLM wrote, and then you're seeing the kind of the solid output that follows from that. But in any case. So in addition to human users, we now have an increasing number of AI users who are an exacting group of users. They sort of, our human users have been exacting over the years. The AI users are exacting in slightly different ways. And I'm happy to say that we've been very much up to the task of providing what they need. Okay, so without further ado, let me go and start showing you some of what we have here. All right, let me see. Just go here. Well, I've kind of developed this tradition of writing posts about each new version as it comes out. And this. So here's the one for version 14.1, and you can see it has quite a long table of contents here. And I'll be going through all of that today. I might mention, by the way, that version 14.1 is the 36th version of orphan language and Mathematica that's come out since we first started in 1988 with version one. So it's been 36 years. And it so happens this is the 36th release. We've been speeding up our release schedule so that it's now about 2 per year. In the past, we were took longer between releases, but so for the 36th time, we get to try out all these cool new capabilities. All right, well, let's get started. So the first thing to talk about is what it is that we're actually running here. You know, in the beginning, we just had Mathematica. We called it a system for doing mathematics by computer. But the core of the system is a very general concept of transformations for symbolic expressions, always much broader than sort of mathematics on its own. And it wasn't long before sort of mathematics was an increasingly small part of the system we'd built. So we agonized for years about kind of how to rebrand things to better reflect what the system actually had become. And eventually, about a decade ago, we did the really obvious thing and named what we had the Wolfram language. But when it came to actual software products and executables, many people were familiar with kind of having a Mathematica icon on the desktop. We didn't want to change that. We introduced Wolfram 1 as a general product supporting Wolfram language across desktop and cloud, with Wolfram desktop being its desktop component. But sometimes people have found this a bit confusing and ultimately there's just one sort of bag of bits that implements the whole system we built, even though the different usage patterns, differently named products that system supports. So up until now, each of these products has been a different executable, separately downloaded. But Starting with version 14.1, we are unifying all of these things. So now there's just a single unified Wolfram app that I have here in my document. And you just go to this one page, that is this one download center that allows you to download the Wolfram app here that supports all of our different, all of our different systems and capabilities. See here. So. That's, that's the first thing that's new, something very infrastructural. All right, let's, let's go on. Let's talk about some, some capabilities. First of all, in the kind of LLM AI space. Important new area is vector databases and semantic search. So let's say you've got a million documents, there might be web pages, images, whatever, you want to find the ones that are closest to something. So now in version 14.1 there's a function semantics search that does this. And how does it work? Well, uses machine learning to find vectors, I.e. lists of numbers that somehow represent the meaning of, of each of your documents. Then you want to know which documents are closest to something. Semantic search computes the vector for the something, then sees which of the document vectors are closest to this vector. So in principle, one could use nearest to find these closest vectors. And that works just fine for small examples where one can readily store all the vectors in memory. But semantic search, the new semantic search in version 14.1 uses a full industrial strength approach that's based on the new vector database capabilities of 14.1, which can work with really huge collections of vectors stored in external files. So lots of ways to use both semantic search and vector databases on their own. You can Use them to find documents and snippets, images, sounds, whatever else whose meaning can somehow be captured by a vector of numbers. Sometimes the point is to retrieve content directly for human consumption. But a particularly strong modern use case is to set up so called retrieval augmented generation or rags for LLMs in which one finds content that's relevant with a directive database to provide a dynamic prompt for an LLM. And in version 14.1 we now have something I'll talk about later called LLM prompt generator that implements exactly this pipeline and it's something that we've been using a lot in the interaction between LLMs providing LLMs as linguistic user interfaces for Wolfram Language. Okay, so we're talking about semantic search. It's modeled after the function text search, which just searches for keywords. And although semantic search does work on many things other than text. Okay, so there's an analog of create search index that we have for text search. And that's. So let's make here we're going to make a semantic search index. So what we're going to do is a very trivial semantic index. We're going to make kind of an inverse dictionary. We're going to say these are little snippets that define dolphins and whales and sharks and so on. And now we want to say let's create an index that is a semantic search index that allows us, that gives us kind of vectors for each of those kind of descriptions of meaning of each of these kinds of critters. So there are three elements in our local search index. Here we have it. And now we can say something like, we could do something like semantic search of a very large sea mammal. So what we're doing here is effectively to make an inverse dictionary. We're doing something where we're saying this phrase a very large sea mammal. We turn that into a vector of numbers. What vector is that closest to relative to these vectors that correspond to the meanings of these three words up here? So let's see what it thinks here. Okay, so in this order, it seems to say that there's a, the closest one is a whale. Okay, that's fairly convincing. Then a dolphin. And then the shark is the loser being as it's not in fact a mammal. So it's further away and it knows it's kind of further away from this phrase, a very large sea mammal in the description we've given here. So let's do that for a. Let's start this off grinding away, creating a semantic search index for all 50,000 words or maybe it's 100,000 words in our word definition dictionary. Okay. It's doing its thing. It's grinding away. It's going to make an inverse dictionary. I don't know how many entries it'll have. Let's find out. All right, it's now computing the vector embeddings for all of those words. Computing, computing, computing. It's taking it a while, but it's got a lot of computations to do here. And now let's see what happens if we. Okay. Oh, my gosh. Really? Really? Is it really 10 minutes, 8 minutes? Okay. It's being, it's, it's being very conservative. It's. It was estimating larger times than it's actually going to take. In any case, let me remind you what this is doing. Taking a complete dictionary and it's finding the vectors that represent the meanings as described by various sentences in the dictionary, the meanings of all the words in the dictionary. So now we can do kind of an inverse dictionary lookup, kind of like a crossword puzzle to word lookup, to find which words are closest to a particular definition. Okay, let's see what this does. That's. Okay. We've computed the vector embeddings. Now what's happening? There we go. Okay. 39,000 entries in our semantic search index. And now let's redo our search for the closest vectors to a very large sea animal. And now we'll get, I think, by default, the. It produces 10 outputs and. Okay, whale cetacean. That's pretty good. The seahorse isn't so good. Let's look at the distances here. So that's both the label and the distances. Okay, so, wow. Seahorse is still. Oh, no, the distance is getting larger here, but it's not getting larger as quickly as I might have hoped. So given just the text we have here, we can't so well distinguish. A whale really is a sea mammal and a seahorse really isn't a mammal. Welcome to the world of machine learning and AI. It does what it can do given kind of the structure of the words and so on, but it can't go beyond that. So let's see if we make a plot here of these. Let's see. There we go. Okay, well, okay, a whale is the winner by a decent margin relative to these other things like crocodiles and so on. All right. Big subtlety when you are dealing with semantic search indexes is where to store them when they're small. You can just store them in memory or even in a notebook, but you'll usually want to store them in, in a separate file. And actually a little surprised that this isn't offering us a little raft here that says that we can store this in the cloud, for example. But we can certainly do that programmatically. Let's say we do this. Well, I'm not going to do this all again. Let's just take this. If I did this, it would immediately. Instead of storing this, if we look here, it's stored in a local object, which is a file on my computer, which is just fine for me, but it's not good if I want other people to also use this. So if I were to say cloud object, public, it will store it in my cloud area as a public cloud object that other people can also get access to. So that would allow one to just have semantic search index used by anybody. All right, well, semantic search is usually kind of the only thing you need. But let's see what happens if you kind of go below the semantic search level to look at specifically at vectors and so on. So we can always use nearest to find the nearest vectors to something we specify. But we can also, particularly when it gets really industrial strength and so on, we can create a vector database. This time it's not really industrial strength, it's just 10 little vectors. So we don't really need this, but we can go ahead and do it just to show how this works. And now we have a function, vector databasesearch, which takes this vector database object and does a search for what's nearest to a given specified vector. And so in this case, it's saying of the vectors that are here, it's the. We have. I'm actually a little confused about this vector. Well, it's saying Vector 3, 2, 2. What. What are the norm of those distances? Let's see, Norm 333. Of line nine. Oops. Oh, what do I want to do? I want to say Euclidean distance, perhaps. I think that's the norm I'm using. Oh, they're both the same. Okay, well, it was. So nearest gave us both of them. Vector database. Its mission is to just tell us the nearest one. Well, there was a tie and it just gave us that one in this case. So. Let's see, we can also use the whole vector database mechanism on things other than explicit vectors of numbers. For example, we could use it on images. There's a vector database storing the meaning vectors effectively for those things. And. The thing that. We want to do, let's see. Sorry, I'm just looking at a couple of Things here. Oh yes, I'm, I'm reminded here that, that on our word definition of, of, of seahorse, actually it's not as wrong as we thought because the first definition is the seahorse that we now know it to be. But it's apparently in times past walruses, which are mammals, were sometimes called seahorses. And needless to say, the definition as in this is the data the AI was fed type thing says that there are mammals that are seahorses. So we get what we get. All right. In any case here we can do a vector database search for a thing that's similar to that picture of a squirrel. And in this particular case the way that it has created meaning vectors for these images indeed concludes that this squirrel image is most similar to that squirrel picture there. Well, we can make vector databases for all kinds of things. Like for example, we could make it for graphs, we could do a vector database search for that graph. In each case we're using either implicitly or explicitly a feature extractor. Here we're using a feature extractor that's optimized for graphs and that's what gives us the vectors from these graphs that we can then find which is nearest and so on. Okay, so the idea is that create semantic search index, create vector database. Create vector databases from scratch using data you provide. There's also functions like update semanticsearchindex, add to vector database and so on that let you do things incrementally. But there's also, we've started putting populating the Wolfram data repository with vector databases. And so you'll find a category here for vector databases really that doesn't look like vector databases. That looks wrong. Well here there are semantic indices, there's. Let me make this bigger. There's a semantic index of e.g. function repository documentation. And here we've now got, we can now use that to. It's a pre created vector database that we can use for semantic searching. So for example, here we can do a semantic search against this resource of semantic index of orphan language documentation. I don't know why that's red, but we should be able to just say let's search for something that is similar to iterating functions. Oh, it's got to download that semantic search index. It's going to download it to now be a file on my computer system, 420 megabytes in this case of it. So this is a fairly large semantic index. And now it's after it's ground away for a little while it should start to Generate for me a list of the page titles of pages that might be relevant to this topic, of iterating functions. All right, and we can go ahead and not only do this, this is just going to generate. I think it gets its act together here. I think it has to initialize a bunch of things the first time this is used in general, things like this. There we go. Okay, so this is giving us names of possible functions that would be relevant or that might be relevant. I see. This is probably pages, actually. This is pages from the documentation that might be relevant to that topic. So we can do all kinds of things here. We might do this for. We can create a search index. Let's see, what are we creating here? We're creating a. Okay, we're creating a search index, semantic search index from the Wikipedia page for anteaters. Then we're summarizing what that page. This is a function, text summarize is a function that makes use of vector databases. And now we're summarizing what predators are discussed on the anteaters page of Wikipedia. And we're giving the result as bullet points. And apparently jaguars prey on both giant anteaters and southern tamanduas. So, okay, that's a little bit on the new feature of semantic search index and vector databases. Big use of these things is for prompting LLMs. So you might recall that we have had for a couple of versions now since the middle of 2023, we've had a lot of LLM capability built into Wolfram language right now still using external LLM APIs that probably won't continue for forever. But we can do things like say, synthesize LLM, synthesize something. This is a prompt coming from our prompt repository, a formal rephrase we're asking for. And let's see, where are we going here? Yes, formally make a formal rephrasing of my come to my party. And it does that in typical LLM style. And we can do other things. But LLM prompt typically adds a fixed pre prompt to our prompting. So for example, in this case it's adding a fixed pre prompt about translation here to French to the prompt that I'm giving to the LLM. But what if the LLM wants to be pre prompted in a way that depends on information that's only available once the user has asked their question. So for example, things like the text of the question itself or other kinds of dynamic content. So for instance, let's try something like this. This, let's say this is now using a new capability, LLM Prompt generator. So you might remember that LLM synthesize, just like when we evaluate 2:2, it's going through the standard Wolfram language evaluator. LLM synthesize allows us to specify an LLM evaluator, which is kind of the LLM that's going to be used to do the synthesizing to do the evaluation that we are asking for. So in this case here we're going to have part of that LLM evaluator is going to be to make a pre prompt and that pre prompt is going to be generated by an LLMPT generator. And in this case what's going to happen is the LLM is going to be pre prompted with username is and then it will be $registered username and $registered username is something that's evaluated at the time of where the. At the time when when this evaluation of when when the LLM when it's actually, when this is actually sent to the LLM, the pre prompt is evaluated and in this case so it knows. My name is Stephen. I. I am somewhat led to tell a story, just for a moment of something. When we first launched WolframAlpha, we wanted to have some kind of amusing screen to put up in cases where we didn't know what to do. And so we had the bright idea very soon before we launched, like within an hour or something before we launched WolframAlpha to the world back in 2009, that we would put up something that was kind of a throwback to the AI of 2001 A Space Odyssey. And we put up something with a red eye that said, I'm sorry, Dave, I can't do that. Dave being the name of the fictional astronaut in the 2001 movie. Well, that works fine until somebody sent in this comment that said, how did you know my name was Dave? Well, in those days we obviously didn't. It just was pure coincidence in these days, now the LLM can know that my name is Stephen. So, okay, here's another example of tell me yes or no, is the sun up? So now we're going to give the LLM some extra information. We're going to give it when was sunrise today? When was sun set today? What time is now? And what's it going to do here? It says yes. Okay, I can look out the window. It's true. The sun is up right now. The whole giant technology stack has worked. I could have gotten the same answer by looking out the window, but so it goes. All right, so now let's say that we had actually given some irrelevant information. We'd also told that the phase of the moon, well, it ignores that because it's really being asked is the sun up or not? So it says yes, but it's now part of its pre prompt now contains information about the phase of the moon, which doesn't happen to be relevant, by the way. If we just look at what the prompt generator would actually be sending here. We can take a look at that. There it is. And there's all the plumbing is such that it can understand all these date formats and all that sort of thing. Okay, so now let's say we do something like this. What is the street addressable from researchers hq. And here we are asking in the prompt generator, we're asking for a web search to be done on the question that we ask and to generate snippets. So let's go ahead and do that. Now it's going to do that web search and then it's going to summarize the web search in this way. So I don't know what it got back from that raw web search. It's probably a bunch of different snippets. But then the LLM took that as being as it is a linguistic user interface and was able to repackage that in this nice linguistic form. And maybe if we run it again. You see, this is the wonder of LLMs. If you run it again, it may or may not give the same answer. Let's see. Oh, look at that. Now it formats it in that form. Well, with a bit more pre prompting we could probably tell it which way to do that. So okay, often one doesn't just want to sort of search at random on the web. One wants to provide certain specified briefing material to the LLM. And that's what rags are all about. Retrieval, augmented generation. So the idea there is to use a semantic search with an LLM prompt generator to provide essentially briefing material about a particular thing. So for example, let's say I say I take this index, which is a semantic index of my various writings. Boy, only I'm so Sad. There's only 11,000 elements of, of things that I've written about. But so it goes. It's so now let me ask a question that you. That won't probably be known directly in the training for the LLM or whatever. When did I first see an eclipse? I'm going to use that. I'm going to use this prompt generator and it's by the way, and this will have prompted it with the semantic search index, we will Then be querying the semantic search index. See, I could do that here. I could just say semantic search. Actually, let me just do that here. If I just explicitly do the semantic search, I'll get all kinds of, oh, now I'm just going to get the index of the places where. That's just an index of the titles. I'm kind of thinking there is a little bit more here. Let's see. No, well, I'm surprised. I think it will have retrieved more than that because it's asked for that generator and it will have retrieved actual content from these items. And I'm really kind of surprised it did that in any case. All right, let's try something else. Let's say our briefing material comes from the function repository. So there's a bunch of, of semantic, a big semantic index of the function repository. And now we can ask a question like what is the resistance of a resistor colored red, red and blue? Okay, it's probably something known to Wolfram Alpha. But here it's just going to ask this LLM prompt generator and it's going to, oh, come now. It's going to generate the result by it's going to find the function probably from resistor color code from the function repository by using the rag here to figure out what function is relevant to asking about resistors. And then it should have just run that function using this Wolfram language evaluator tool. It should have just run that function and given us the result. Let's try it again. When in doubt, try it again. Well, that's, that's strange. It's. We can see the code here. I think this. Oh, wow, you can see the code. And if we, I'm sure if we say, oh my gosh, let's say two expression of that. No. Well, who knows the. Let's just check what. I should check what model I'm running because maybe I'm running the wrong model here. Let us go to the settings and let's go now to AI settings. And let's see, I am running GPT4 omni, which I think is probably a reasonable thing to be running. I think that that may be, I may have changed that. That might be a default, but I could try a different model here. I could try. Well, lots of models I could try. Anybody go to Suggestion. Well, who knows, I could be using. Those are OpenAI models. I could be using other models as well. Talk about that soon. All right, well, so I don't quite know what was going wrong here. Never trust the AI. It always needs A handler to do the right thing here. Okay, but let me just. For the heck of it, let me just go ahead and do this by hand just to show what it would have done from resistor color code of the list. Red, red, blue. And this will now call the function repository function to generate. What happened here? Did I ask the wrong thing? How is it a color code? Oh, oh, oh, oh, oh, oh, oh. I need to actually. I probably need to. Maybe I need to actually. Well, when in doubt, actually read. Why is this not coming up with a raft? That should come up with a raft. That's really odd. Oh, oh, oh. That's why. Because those are not strings. They should just be names of colors. So here I could, if I wanted to, I could just evaluate that and get these colors. And then I could just say that. And there we go. There's the resistance. And hopefully the LLM would have picked that up and been able to just return this 22 mega ohms result. Okay. One of the things I was actually just showing was the fact that we can now connect to a very large number of different, different LLMs and so on directly in wolven language. And we can also, if we go and we start a chat notebook. Here's a chat notebook. We can go ahead there. Let's make this a little bigger. We go ahead there and right here in the. In the settings for this chat notebook, we can go. And we can go ahead and see all kinds of different models that we can connect to in a high degree of detail. And we've been busily sort of connecting to lots of kinds of models. We can do that globally, you can do that locally. Let's try doing something like, let's do this. Let's try going here and let's just go and say, what is your name? And let's connect to an anthropic model. Great. Okay. Well, so goes it. How about another model? Let's try. Well, let's see what we got here. I can, if I want to, I can set up even my own kind of LLM here. But in general, there'll be an LLM evaluator that is. Has an LLM configuration that gives me the details of what model I'm connected to. It gets. There's quite a lot of plumbing here, but let's try something. Let's try this. This may be. Well, this may be a disaster because I may not have any accounts of any of these things. And. Oh, my. It's also launching a lot of parallel. Gosh, what am I doing here? This is launching parallel kernels. Probably it will launch them on all my machines, which is a little bit crazy and. Oh dear, dear, dear. Yes. I don't need hundreds of kernels here. But anyway, I think I didn't tell it to launch it, only on my local machine. Okay, it'll go for a little while, launching kernels. Maybe it'll be useful for something else we're doing. In a moment it'll go ahead and launch all these things and. Okay, come on, come on, come on, let's launch them. Yes, I've got lots of machines here with lots of kernels and how many more is it going to do? Seven of eight. Okay, come on, one more. I think. Okay, we got 228 kernels altogether, which we absolutely don't need because we're only parallelizing here across about eight things. But here we go. We're now in parallel. That's absolutely crazy. And. Okay, well, seems like everybody failed except the OpenAI system that I was already connected to and. Yeah, oh, I see. I know what happened. What happened there is that I don't want to parallelize. I'm just going to try this one more time because I don't want to parallelize across all my machines because these different machines don't have those credentials. I just want to parallelize across my local machines. And for that I think there's a way to do that with parallelize with parallel table. But I'm trying to remember how to do that. Well, let's not bother. Let's just say table here and that will now go. Ah, I see. Okay, that's what it's going to do for me. It's going to say that's what it was doing here. It was confused because these are random servers which have no interface capability. And I was trying to ask them and it was, it's going to give me these, these credential things, asking me for API keys for all of these systems, I think. Oh dear, oh dear. Well, let's see if I've got any of them. This wasn't set up very well, was it? I can see that this machine is. No, it's failing for all of them. Oh dear, oh dear, oh dear. Look at that. Failed. 100% failure. Okay, well, in any case, you see the point. If I had had my things, The, if I had had this correctly set up, I would have been able to get a nice set of results from all these different systems. I think I can just look at what I wrote in the blog here, and those are results gotten from running that function when this had been correctly set up with API keys for all of these different systems. This will be a lot easier when we have our own mechanisms for providing LLM access, which hopefully will be coming real soon. Okay, talking of LLMs, we've actually been, you know, we've been using them a bunch, and we've actually started a project to benchmark LLMs. This is a weekly project where we are just every week using my elementary Introduction to Wolfram language, which has a bunch of exercises which were intended for humans. But the exercises are of the form. Here's a piece of English that says write this piece of code that does this, and then you're supposed to write a piece of code. And we've had an autograding system that's been used a gazillion times by humans, and it's pretty robust autograding system. And now we're using it not just for humans who want to learn things, but in the online version of the elementary Introduction book, But also for AIs, as we see how well they do on these exercises. And we can see this week's ranking of different LLMs with respect to this test. So this is a thing that, at least for us, is useful as a way to sort of understand what's working and what's not in the world of LLMs. Okay, all right, we're done with the discussion of LLMs and AI for now. Let's turn to a completely different topic. And. Let's see. The. We are going to go a second topic here, something completely different. Symbolic arrays. The. This is about symbolic arrays. Okay, let's say you want capital A to be an N by N matrix. I'm not saying what N is, I'm just saying it's an N by N matrix. And how do you do that? Well, we've got a whole new system for representing symbolic arrays. Symbolic in the sense that not that they're components are symbolic, but that the whole structure of the array is specified symbolically. So this here is a representation of a matrix symbol that is a symbolic an N by N array A. And if we mouse over this, we'll see it says matrix symbols, dimensions N by N. And if we ask it, what are the tensor dimensions of A? Whoops, get my A again. Tensor dimensions of A. It's N by N. Okay, what's the inverse of A? Oh, it's a symbolic A inverse. If we say what are the tensor dimensions of the inverse of A? Yep, they're N by N. Okay, the what? Let's now define a vector which is a length N vector. So what are the tensor dimensions of? Now we can say what are the tensor dimensions of a dot V? So A was an N by N matrix, V was a length N vector. So the tensor dimensions of a dot V are that if we compute V dot A dot V we'll be able to do all kinds of things with it. So V a V should be a scalar. So we can say what's the gradient of that scalar with respect to the vector V? And so what we'll see here is this result that's multiplying by the rows and by the columns. That's that gradient symbolically represented there. And if we just said what's the derivative of V dot a dot B with respect to V? We'd find that same result. Let's say we do the second derivative. It's going to get more complicated. Oh, that's just a plus a transpose. I kind of wonder what happens if we ask for the fourth derivative or something. Ah, we'll have to come to that later. That's a tricky thing. Okay, let's say we ask for the derivative of V, the vector V symbolic vector V with respect to V. What is that? Well, that is an identity matrix which has. It's an N by n identity matrix. So we're representing that by that double struck I. If we ask the tensor dimensions of this, it's N by N. Okay, so we are. Okay, so let's say this thing I is a symbolic identity array. So a symbolic identity array of size N is represented that way. And again we can say. What are the. See, Yeah, what are the tensor dimensions of that symbolic identity array? It'll say it's N by N, et cetera. Okay, so now if we give N an explicit value, we just say with n equals 2, what is symbolic identity array of R in with n equals 2 it'll just be an ordinary 2x2 identity matrix. We could say 8 or whatever we want. It's then that identity matrix. Let's see. So the next thing we could try doing is to say what's the derivative of total of V with respect to V? Okay, that's another strange construct. That is a new kind of construct that comes from the world of symbolic arrays. So this is a symbolic ones array. So this is a symbolic identity array, an identity matrix or tensor with just ones on the leading diagonal. A symbolic ones array. Let's take a look at what a symbolic ones array is. N equals 10. Symbolic ones array is just A bunch of ones. It's a dimension N. Or it could be N by n by N if we wanted to array of ones. Okay, so if we now say what's the derivative of total? With the second derivative of total? That's yet another funky kind of thing. So that object is a symbolic zeros array, which is the same kind of thing as a ones array, but now it's just full of zeros. And so now if we say we could actually work that out, we could say again with that. With n equals 10. Trying to do here. We're trying to say that's a symbolic. What did I do here? That is a. Let's just look at the input form of that most recent line. A symbolic zeros array. An N by n symbolic zeros array. So let's say with n equals 10, n equals 5 for that. What's happening here? Why am I not seeing? What did I just do here? Did I just create a cell? That is not what I think it is. Symbolic zeros arrange. Okay, that's an n by N, one of those. And now I'm saying with n equals 4. Now it's working fine. What happened there? I think I created a cell that was. I told it to create some kind of text cell. Okay, so that's a lot. I would have expected this to become an explicit array. I'm not sure why it didn't. Probably if I ask it now, I'm now a curious to ask it for three. Three elements of this. And that's very odd. Okay, I don't know what happened here. Looks wrong to me. Let's see. So let's say that we are going to create a vector. Now when we create a vector of n length, N vector, we can also say things like it's a vector of reals. When we mouse over it, it'll say the domain is R to the N reals for the reals. So now if we say let's find the derivative of norm of VR, which is our vector of n reals with respect to VR, now we can compute this. We could compute the vector, the norm of VR three times. And it's pretty ornate. It's got all kinds of ones vectors and it's got the identity tensor, all kinds of other things like this. I just forgot. Just for the hell of it, I'm now curious to just do this for five. Okay. It gets pretty complicated pretty quickly. Welcome to the world of tensors and so on. And you'll see all kinds of elaborate things here. Like that T thing means It's a transpose, a 1, 3, 2 transpose of this Kronecker product of these things and so on. Okay, well, let's say we've got functions. Well, let's say we've just got these functions. A which is, remember was a matrix, a symbolic array. V is a symbolic vector. So here we've got these functions and we're now doing differentiation with these symbolic functions. Let's say we do this A of V of X. This is a chain rule story. We've got that V of A of X. We've got another, another piece of the chain rule. Now that dot there is another complicated construct that we have to introduce to represent these kinds of things. By the way, I mean, you know, the complexity here is not of our making, it's of maths making, so to speak. And I would say that what we managed to do is to remove a lot of the complexity and make it much more explicit. So this is, as I say, an array dot, which is a generalization of dot. So given two, let's say we've got these two matrices, U and V. The dot of U and V is just that standard dot product. But now we can have a different kind of dot product. We can have something which is. Well, we can have. That case is just the ordinary dot product where we're taking the second index of the first thing and the first index of the second, contracting them. But a two version of that does it. In this particular case it will just contract out all the indices well and we can go through and understand array.com. it's just taking different tensor indices and inner producting them together. And it's something that we need when we're dealing with these kind of operations on symbolic arrays. Okay, so let's say we can do things in quite a lot of generality here. So for example, here's an array B that is a P by Q by R array. So it gets to have that little three overscript there. That means that it's a rank three tensor object. And now we could say, well, let's say A, A, A. We get that. Now let's see what are we doing here, Right? I mean there's a lot of high dimension, high rank things here. So for example, that object there, if we say what are the tensor dimensions of that object? They will be N by N by N by N by N. So you end up with these very deeply nested tensor objects. So let's say we start off with a 3 by 3 by 3 tensor object T. And if we compute the derivative of the total of that, we end up with another funky object. See this? Symbolic arrays are full of funky objects. See that delta, delta thing? That is a rank 5 array. This thing is a rank 5 array that's a combination of two Kronecker delta objects. So it's a 3 by 3 by 3 by 3 by 3 tensor which has the feature that it is 1 whenever it's 1, 4 indices and it's 2, 5 indices. Agree. So for example, we can go ahead and compute, oops, let's take that and we can compute the normal of that. So that is a rank 5 object which has these ones in places that correspond to the 14 sort of direction and the 2, 5 direction. We can get some idea of what's going on here. We can make a graphics grid, we can just make a 3D array plot that shows this is not actually that illuminating, but it shows kind of the regions in which there are ones in that rank 5 tensor. And this is now showing an array, a two dimensional array of three dimensional objects, which gives us a five dimensional object altogether. Okay, so a little bit more here on symbolic arrays. It's a very powerful area that I have to say is one of these long requested, long desired features. It's probably been 30 years in gestation and we finally have been able to really do it right. And that's what's happened in version 14.1. So the. Let's see. So here we're going to talk a little bit about symbolic vectors and their relationship to listability. So if I say this, I get these lists are threaded into each other and I get that result if I do this, these are threaded together and the W is kind of copied across all the elements of that list. But now if I do this, we know that that vector symbol, which in this case is a dimension N doesn't agree with. We can't thread it through here, so we don't do that. So now if we say something like this, we're going to thread the W's, but we're going to keep the symbolic vector V as a separate object. So under the hood for those who are into these things, there's a new attribute called nonthreadable which specifies that things like array symbol are not threaded in listable functions. So and we've got, yeah, we have a whole bunch of things that we introduced a mechanism years ago in version nine for sort of a limited version of these kind of mechanism of symbolic vectors, using things like W as an element of vectors, three three dimensional vectors and all of that stuff interoperates with the new completely symbolic array mechanism. So let's just see an example here. The. Let's try and do a linear least squares problem using our new construct. So we've got a B, a B and X. So A is an N by M vector of reals. B is a length N. Sorry, N by a matrix of reals, B is a length N vector of reals, X is a length M vector of reals. Okay, so what is linear least squares? Well, linear least squares is something where we are taking the norm of a dot X minus B squared. Let's see what that is. Isn't that cool? We can just basically see it in pure math notation, but it means something. And so now we can take this and we take the derivative of it, we take that norm, we differentiate it, and by golly, we actually get something here. We can compute it, and we could go ahead and we can compute the second derivative as well, and we get that result. We could compute the third derivative if we want to. We get that result. We can just treat this kind of least squares object purely symbolically and do our operations on it. So, for example, we can look at, for example, a different norm here. If we look at this norm, we'll get a more complicated expression here. If we look at its second derivative, we'll get something more complicated here. But the whole point is it all just works. Symbolic vectors, symbolic arrays, symbolic tensors are now part of kind of the story of symbolic computation in Wolfram language. So it's taken a long time to be able to unravel quite how to do this, but we've done it. All. Right, new topic. We got a whole bunch of topics here. We're only a very small amount of the way through, about maybe a quarter of the way through this list here, I want to go through everything here, and we're just going to push on forward. Okay, I have a section here that was called Binomials and Pitchforks. And this has to do with subtle issues about mathematical conventions. And one might not have thought there would be a lot of pitchforks and sort of a vigorous activism around binomial coefficients. I think in the Sherlock Holmes books, there was a Professor Moriarty who was sort of a nemesis, had written supposedly, a treatise on the binomial theorem. But that's as close to activism around binomials as I think one had seen until recently. So in version 7 in 2008, we changed the definition of binomial. Not in the case where people would ordinarily use it, but in kind of an extension case. And ever since that time, my friend Don Knuth, author of Many Things, but notably his Art of Computer Programming series, started in the mid-1960s. Hopefully it will get finished. I think it's only partway through volume four out of eight volumes so far, but we'll hope for the best. Hopefully our technology will help it get written sooner. But Don has been complaining vociferously about binomial coefficients. What's he been complaining about? He's been complaining that binomial of minus one minus one gives one. Well, what should it give? Well, there's two different conventions. See, one thing that can happen is you can say, for example, binomial of N comma, N always gives one for any n. So that means binomial of minus one minus one better give one. But there's a different convention where binomial of minus one minus one gives zero. And so the issue has been, how do we have both of these conventions? Well, we can kind of see the conventions here. If I just take a picture here. Let's just do this. Everything. Oh, that's kind of complicated. But we can just compute it. There we go. These are the two conventions. This is what we made binomial coefficients do. They are symmetrical when you have negative values. And that's what we made them do back in 2008 in version seven, because we wanted consistency with other kinds of mathematical functions that behave in this kind of way when you extend them to different values. But other people wanted Pascal's identity, for example, that says a binomial is the sum of the things above it. They wanted that to always be true. And in that case, you get this asymmetric binomial coefficient which doesn't have. Which is zero for these negative values. Okay, so how do we achieve both of those things? Well, we really can't with binomial on its own. And so in version 14.1, we've introduced a new thing called Pascal binomial, which does follow Pascal's identity. We agonized greatly over what Pascal binomial should be called. We almost called it Knuth binomial, but that's a bit ahistorical because it had been discussed for quite a long time before Don started discussing it. But he almost got that function named named there in recognition of his activism for the behavior that it has. But in any case, with Pascal Binomial, it's no longer the case that binomial of nn gives just n. It gives just 1. It just stays unevaluated. If we really want to know what it is. We can say, use function expand, and we'll find out that it's a piecewise function that is 1 for n greater than 0 and 0 otherwise. Okay, so. Let's see the. Yeah, I mean, it all gets very subtle. We can, we can look at these. That's not what we want. We can look at these limits as. This is kind of the general mathematical form of binomial coefficient. And this is now looking at limits, this triple limit, as this in this case, and a triple limit in a different order with the epsilon going to zero first. With a different order of limits, we get the different result. So this one here is the Pascal binomial. This one here is our symmetric binomial. So I think we finally resolved this point of contention. I hope everybody will be happy with it. Another complicated convention type of thing is just trigonometric functions. Sine of PI over four. What is it? Well, PI over four, we assume is in radians. And if we want to say 45 degrees, we have the explicit symbol degree, which is formatted like that, that says 45 degrees. Okay, but sometimes you really want the function to be a degrees, a sine in degrees function. You know, back in the old days of calculators, they would have a physical switch that you would move to go from radians mode to degrees mode. Well, now we have a new function, sine degrees, which works with degrees like that. It's useful for geodesy, for example. Lots of subtle issues, you know, what does arcsine do? Well, it goes 45 degrees. And let's see. I think I have to clear some things here that I might have set earlier. Let's say we ask what's the period of the function sine degrees? Well, it's 360. And always when we knit new functions into the system, it's always complicated because they have to be supported in all these different ways. So if we integrate sine degrees over X, the indefinite integral is this thing here, because the thing that, where the integral of sine is cosine. That only works if the argument of the sine is in radians. Okay, let's go on to some more math. Let's talk about differential equations. We're going to talk about fixed points of differential equations. So the question is, if we have where is the fixed point of this equation, where is the place where the derivatives vanish. This gives us the fixed points of that equation. And if we wanted to, we could show that those are the fixed points because we could make A stream plot of that function. And we could show, we're just using an epilogue here to plot those fixed points in the stream, so to speak. And we can see, yes, those are the kind of stagnant points where the velocity field, if this was a velocity, is zero. Okay, Actually there are two different kinds of fixed points here. Here the fluid is kind of. If this was a fluid, is sort of swirling around and a little bit of a speck of whatever it is, plastic or something, will just get stuck here. But in this case here, it's an unstable fixed point, and it will tend to get pulled in and go with this flow and so on. So how do we tell that? How do we tell which is a stable fixed point, which is an unstable fixed point? We have destability conditions. And that tells us for each of the fixed points here, whether it is a stable or unstable fixed point. Okay, so we can have more elaborate things. These are the Lorentz equations, typical chaotic equations invented by a person I once knew, Ed Lorenz, in the early 1960s. And this shows a slightly more ornate result about stability and instability of fixed points. In Lorentz equations, you can also have stability conditions that depend on parameters. So here are some equations where the stability is dependent on that condition there, and so on. And so, for example, we could, given those conditions, we can say, make us a plot. Everything fits together very nicely here. Make us a plot of just that criterion, and show us where this equation is stable with respect to A and B. So lots of fields where this kind of stability analysis is important. Dynamical systems theory, control theory, celestial mechanics. Is this planet going to crash into another one? Computational ecology, lots of different areas. Okay, well, one could do stability analysis for differential equations. One can also do stability analysis for difference equations. So here's a classic difference equation, the logistic equation, and we're going to give the stability conditions for that difference equation. And that's going to give us these fixed points at 0 and here, and at what values of the parameter lambda do those fixed points? Are those fixed points stable? Okay, more on differential equations. We've been talking about ordinary differential equations. Let's turn now to partial differential equations. We've been spending, well, for like a decade and nearly two decades, we've been sort of steadily progressing our work on partial differential equations. Convenient models in lots of areas of large scale physics. We like to think that if you go to a small scale, we already know that, you know, fluids are made of molecules, and so it's really discrete there. But on a large scale, for many Engineering and in physics purposes, we can treat a fluid as continuous. There are other cases where we tend to think now everything is eventually discrete, including things like space. And so sort of underneath the Einstein equations is something discrete. But in any case, what we're interested in doing here is being able to solve these partial differential equations. And we can do that sometimes symbolically, but most of the time we're doing it numerically actually by discretizing them inside Wolfram language. Okay, well, one of the things we've been doing is to set up partial differential equations to have better and better kind of packaging to be able to deal with. It's just a big nuisance to set up the differential equations for an acoustics problem, or a heat transfer problem, or a solid mechanics problem, or a fluid dynamics problem, or quantum mechanics, for that matter. And what we've been doing is to set up functionality that kind of makes it easier to, to build the right the equations we need. So this is a region here. It is a weird little region here. And now let's start setting up some variables. Okay, we've got some variables, V of XYZ and just the list xyz. Now we can actually deal with, because we have a lot of real world data. We can deal with material. Copper. We're going to do an electrodynamic electromagnetics problem. This is going to be a conductor. It's going to be made of copper. And now we want to have a PDE. What does the PDE say? It says we've got an electric current PDE component. That's the electric current density at x equals 0, where the current is 1. And we've got an electric potential condition, et cetera, et cetera, et cetera. So this is setting up a pde. And we should see this here. Okay, that's setting up PDE in not really intended for human consumption there. What we want to do though is to solve the pde. So we're solving the PDE over this region. We could stick the region in explicitly here. We're solving that PDE for V of XYZ over the region. XYZ is in this copper conductor here. And the PDE contains information, these parameters which say what the material is and so on. So now we're going to grind away, we're going to solve that equation. And now let's get a function that is, for example, the gradient vector. So this is probably solving for the electric potential. This will be the electric field here. And now we can go and compute, I guess we're computing here. The norm of the electric field. And we're going to show that over. We're going to show that computed over in space. Actually, no, we're showing it over. Specifically over the region that corresponds to the region of this conductor. We're going to show that. Okay, there we go. So there's the magnitude of the electric field basically in that conductor. And we can see those little contour pieces there that. Yes, the corners are what you have to worry about. The corners are where that electric field has its either very small or very large values. And so if we were designing this thing for some antenna or something like that, that will be a thing we would care about. So it's rather impressive that all of this just works like this, that we can really specify differential equations as cleanly as this, solve them as easily as this, visualize them, and so on. It's a big pipeline of capability, and I think a lot of people are finding this very useful. And we are steadily implementing sort of more and more of the physical world and elsewhere as kind of characteristics of. Of this system. The. Let's see. All right, let's turn from the physical world to the biological world. So since version 12.2, actually, we've been able to represent and manipulate bio sequences of the kind that appear in DNA and RNA and proteins and so on. So we've been able to import things like PDB graphics. But now, okay, here's a biomolecule, Hepsin. Okay, so this is going to represent this biomolecule. Okay, blah, blah, blah, blah, blah. Let's load all this stuff up. By the way, if I was doing this directly in the cloud, if this notebook was directly in the cloud, that would happen immediately, but other things will be slower because I'd have to go back and forth to the cloud and so on. Okay, there's a biomolecule. Let me actually get the molecule version of that, which is going to resolve all of. Look at this horrifying thing with 5,985 atoms, which we can now decide to save in the notebook if we want to. Let's go ahead and save this in the notebook. Says embed inline in notebook. Okay, the molecule is now inline stored in this notebook. Okay, let's go ahead now. And that's sort of this biomolecule sprayed out into this 5000 molecule object. If I really were living dangerously, I would now say molecule plot 3D of that. And maybe I'm living too dangerously here because it's a very big molecule and it's got to do all kinds of force field computations and so on. But no, there it is. Hello, molecule. That's that molecule with all of its atoms explicitly shown, along with a little water over there. I wonder what that's doing there. Yes, it can be there. It must have been part of the specification of this. How fun. Okay, well, but often we really want something which is much more representing kind of the. Kind of the functional structure of something like a protein. So let's do that here. Let's take this biomolecule and let's ask for its biosequences. So this particular biomolecule has been tagged as having two different biosequences inside it. And in the end, it's just a bunch of atoms that look like this. So we can say, what are the helices? Well, these are presumably alpha helices, which somewhere are in the middle of that big mess. But now we can say, okay, let's make a biomolecule plot. 3D biomolecule plot, as opposed to a molecule plot plot, 3D. The biomolecule plot now shows us this kind of functional representation of the biomolecule with these kinds of conventions about the alpha helix here and the beta sheets here and all those kinds of things. Okay, so now there are different kind of themes you can use for how you actually want to display the biomolecule. I don't know quite why there's so much empty space there. I think it's waiting for the thing to be rotated around. Around. Okay, let's say we want to show this biomolecule not with this in this sort of schematic way, but rather explicitly, the solvent accessible surface. So this is saying where the waters can get into, so to speak. Or we could try. And again, this will be our raw atom view. I think this is a view tubes. Okay. So I think that's the same as. Or maybe not. That's maybe not quite the same as that raw atom view. In the raw atom view, we kind of broken everything apart. Oh, you know what? I don't know enough chemistry. Those things weren't waters. They were just things where we weren't explicitly displaying the hydrogens. And it's some kind of hydrogen bonded thing. I think, showing my lack of knowledge of chemistry. This is certainly going to. This is how I get to learn all this stuff. All right. In any case, we can also. Let's see, for example, we could look at these different kinds of visualizations altogether. Here they are. And we can also put axes on, and those axes are in angstroms. And so we can see the typical and actual biomolecule with the schematic form and the solvent surface and so on. Kind of cool, I think. All right, well, if we wanted to, we can, you know, if we're trying to draw this for some paper or something, we can give color rules that specify the different components of this biomolecule are specified in different colors. All those kinds of good things. Now, the thing that I think is really cool about all of this stuff is everything really interoperates. So this solvent accessible region is a region. It's the same kind of region as any other kind of computable symbolic region. So here we can take that region. Let's just evaluate it in place here. And there's our region. Come on, wake up. There's our region. Now we can just say what's the area of that region? We'll just compute it using our computational geometry capabilities. If we wanted to know sort of how much, how close can two objects of this shape get to each other? We can just compute that using our standard computational geometry capabilities because all of this stuff interoperates that way. Okay, so we have data on lots and lots of proteins. But you can also use the whole external identifier mechanism. This is PDB as an external identifier. We can say make a biomolecule plot of something that you get from PDB from this external identifier here it is nice. Cool looking object, quite what it is. But I'm guessing it's a transmembrane protein. But I might be wrong in any case. Now. All right, another thing that's new is let's say we specify a biosequence and all we know is, is the sequence of residues here. We just know the sequence of amino acids. What shape is this thing? Okay, well, we can say make a biomolecule picture of this and it'll just say it's a biomolecule. Okay, great. But now if we make a biomolecule 3D, it will actually go and try and fold that biomolecule. It will try and use modern machine learning methods to try and find an energy minimizing, or roughly energy minimizing kind of consistent with what's in the databases type folding of this kind of custom created biosequence. That whole mechanism is not perfect, but it gives one some kind of indication of the shapes of these kinds of sort of arbitrarily defined proteins or a protein that hasn't been seen before. All right, talking about machine Learning. Let's turn to something else. Optimizing neural nets for GPUs and NPUs. So lots of kinds of computers now come with various types of hardware accelerators for machine learning, like on Mac OS and Apple Silicon Windows machines have these things. One of the things that we've done now in version 14.1 is to make our built in machine learning functions like image identify and speech recognize automatically use CoreML, DirectML and so on with the result that they're two to ten times faster. We've always supported explicit CUDA GPU acceleration both for training and inference. In 14.1 we support CoreML and DirectML for inference, at least with explicitly specified neural nets. So we can do that. Let me just see here. Let's do this. Image identify. When we're doing this. With the image identify function, we're by default using GPUs. We're not by default using GPUs if you just specify a neural net explicitly. So here. That's pretty funny for some reason. I think it probably had to load a bunch of stuff into gpu. Yeah, look at that. Second time around with the GPU it's 0.03 seconds to do that image identification, whereas with the CPU and just let's check that that didn't take any. Okay, it had to load some stuff. So it's also got a bit faster, but it's still more than 10 times faster with. With using the GPU device. As I say, this is the default for our built in functions like image identify. Maybe it will be the default later for arbitrary. NET model functions. It isn't yet the default thread. I mean, if I look at what this thing actually is, that is a symbolically specified neural net. There it is. It's kind of a complicated thing. It isn't yet the default because of various issues to do with compatibility with different kinds of NPUs and so on. By the way, you might notice this is a more beautiful picture than it's been before as a kind of iconic representation of a piece of a neural net. Different topic. Well, we're always trying to sort of integrate things better and better. Here's an example of an integration statistics and date. So these dates are the dates of all of the releases of Wolfram language so far, including the one that happened just yesterday. I think there are better be. If I was telling you the truth earlier, which I certainly hope, There should be 36 of those releases. Okay, what's the median date when all those releases happened? So what's the definition of a Median for dates. Complicated. You have to worry about calendars and how things align and so on. The answer is the median was 2014. So we've really been speeding up in our release dates. And if we looked here at a date histogram of this, we can see this and we can now ask that's. Oh, that this is going to tell us of all functions. That's going to be a histogram of when all the functions in Wolfram language were introduced. So this gives us sort of a map of which year had which function. I guess our winning year is 2015 with the largest number of functions introduced. That's not always a sign of. Of more functions isn't necessarily a good thing, but there's a little bit of a trace of when I was working on a new kind of science back in the 90s here. Okay, so let's ask what's the median of all of this? Okay, we can get the results. Well, there's a lot of tricky things about dates. Maybe I shouldn't go through them all, but let's say we've got these dates now. Yesterday when Isaac Newton was born. It's not totally trivial to conform those dates because, for example, old Isaac was born. Well, he was actually born on Christmas Day, but it says he was born January 4th. That's because the calendar changed at that time. He was born when England was still in the Julian calendar and before it had switched to the Gregorian calendar. But as we conform these dates, we want them all to be on the Gregorian calendar so that we can actually do date differences and things like that and have them work. So another new idea related to dates new in 141 is date distributions. So this is a date distribution. There's a gamma distribution of dates where the granularity is today. And this allows us to, for example, get four random dates distributed according to a gamma distribution. And the. That. I'm. That's sorry, that that is the range of the distribution. So this is all within today, I think different times distributed in this way. Okay, different topic videos. Well, we've introduced all kinds of things for making videos. We've had manipulate since version 6 back in 2007. Very popular function. But. So what happens if we want to make a video from a manipulate. Here it is in version 14.1. This is directly generating from the specification of a manipulate. We're going to directly generate a video and we're going to specify here some keyframe points basically, and it's going to interpolate between those. It's now actually writing out video frames and it should generate. Da, da, da. There it is, video. So we can play this video and we'll see it's varying these parameters in the way that we specified here, sort of interpolating between those key points. We can take that video and if this was, and we can go ahead and export it, embed it anywhere and so on. So this is, I think, a very powerful thing. It will allow us to take, for example, lots of demonstrations that we have and immediately make videos from them directly using our video capabilities. And it will deal with any number of variables here. It's not just sort of animating across one variable. It's continuously. It's changing all of these. And it's doing that in a way where you can give time marks where the thing should have reached this set of parameters and so on. There are a couple of different ways to do it. Okay, so videos. So this is sort of a holistic way to make videos. A more, a more granular way to make videos is with reap video and so video. So the idea here is we're going to do a. Oh, I did it very quickly here. We're going to make a series of frames. We're going to get a series of frames here and we're going to sew those frames into something which can be picked up in sort of a bucket that is reaping the video. Or maybe I shouldn't say a bucket. I should know what, when you thresh corn or something, what is the sack that you put it into? I don't know. Sorry, but that's what I should have said. Instead of a bucket, we're putting the videos into that kind of sack. And now and then we're reaping them. And this is now making a video from the specific videos that we sowed here. And we're saying sew the video with each sewing video lasting one second. This, I think, is a super convenient way to kind of make videos where you're sort of. Every so often something's happened. You've got some, some checkpoint. You throw a, you, you sew a video at that checkpoint. And then at the end you can reap those videos and get the whole result back. Okay, let's say. Well, another thing you might do here is to do something like make. Okay, what this is going to do is it's going to take a video. Let's, let's look at this video here. Oh, no, that shouldn't be necessary. Okay, let's look at this video. Seems to have a little hummingbird that comes in every so often and goes to the feeder and then goes away again. Okay, so it's 10 seconds of hummingbird or no hummingbird in the picture. All right, what's this going to do? It's going to do a video map list and it's going to say if the image contains a bird, then sew the video, otherwise don't do it. And so otherwise do nothing. So what this is going to do is going to take every frame. It's going to see whether it has a bird in it. If it does have a bird, it's going to sow that frame and then it's going to reap the frames, the resulting frames, and that's going to hopefully give us a video which is a bird only video, so to speak. And let's see. Well, we could just kill it, but I'm going to wait for the 20 seconds. Let's take the break for the 20 seconds. 17, 16, until it launches. Okay, let's keep going here. Okay, let's see whether we got hummingbirds only. Okay, so this didn't. It just ignored the frames where the hummingbird wasn't in the picture. All right, there's another function, new function for videos. Kind of fun to see functional programming interact with videos. Here's a picture of a. Here's a butterfly picture. And this is going to compose the removed background. So what this is going to do, it's going to do a video frame fold. So what this is going to do is it's going to successively image compose the frames that we get. After removing the background, it's going to progressively compose the frames of something happening with this butterfly. So it's going to basically stack a bunch of frames on top of each other and get kind of a time lapse of the butterfly. Let's see whether we can get this to work. Well, you know what I'm going to, I'm going to just kill it. Let's see what we get. Okay, let's try running this video. Okay, it didn't get very far, but you can see the butterfly starting to kind of be repeated here. We removed the background so that we wouldn't sort of just overlay, overlay, overlay, background, but we're overlaying lots of butterflies. And that way we'll get sort of this, this trace of where the butterfly goes. Okay. There are lots of convenience functions that we've added for videos in version 14.1. So, for example, this is a standard video, but we've got a video summary plot. This is a Way where we're seeing the audio and some frames from the video here, we might be able to do that in a different way. Let's see that as a row. We could make that bigger. See kind of some frames from the video together with the sound that goes along with those. Another thing we can do is to do things like spectrograms directly from videos. So this is just taking the. Taking the audio track from this video of a chirping bird. And in general, we can just use a video as an audio. And we can, for example here say, identify what is in this audio. And it says a chirp. Great. There's a bird, it's chirping and we can kind of see the chirps in the spectrogram. Talking of recognizing things like that, another thing we have added is a very optimized version of speech recognized completely local. Doesn't send anything to the cloud. Let's see, what is this video? This might be a video that I made. There we go. Yeah, it's a video of me going yakity yak. Let's speech recognize that video. And let's see if I've downloaded the speech recognition stuff. Well, I. Not sure I download the. But it's very nice and fast. Maybe we can do that again now that it's been downloaded. There it is. Very nice. Fast speech recognition, all completely local. We can do. Okay, we can do this by sentences instead of by. You know what? I think I'm going to just copy that and add sentence to it. Otherwise we're going to have to download that whole. Download that whole video again. Okay, so this now does the recognition but breaks it into sentences. Or we could do something like, let's do this. Let's get our video again. And now let's say get the interval, the audio and the text. So this is going to tell us that. There it is. From 3 to 0 to 3.15 seconds. This is. Hello and welcome to version 14.1 and so on. Okay, let's turn to a different topic. Let's talk about something about data, historical geography. Okay, so we've had data countries as sort of a characteristic thing to have data about. But now we have data, systematic data on historical countries. We've had some of this in Wolframalpha for a long time. But let's see what happens here. If I say geolist plot of the Roman Empire historical country for the year 100 ADCE, that's a picture of the Roman Empire at that time. So the Roman Empire in 100 AD is now a computable entity. So, for example, we could ask something like, what was the area of the Roman Empire at that time? A million miles, 1.5 million square miles? Or if we want to be more ambitious, we could say, let's make a plot of the area of the Roman Empire as a function of time from 0 AD to 200 AD. So let's see how it may take a little while to compute this. It's got to figure out all these results. Let's see how long it takes. But we should get a plot of that area. We're kind of seeing. You know, every wiggle in this plot is huge amounts of human effort and probably bloodshed and so on. But the end result is hopefully a picture. Where is that picture? It took a long time for the Roman Empire to evolve over 200 years. So might take a little while to compute this. Why is it taking so long? Well, I can cheat and just show you the answer about that there. I've cheated. I've shown you. I've just shown you the answer. But it'll compute it in a little while. But you see these. You know, the expansion of the Roman Empire and its various adventures along the way here. Okay. Well, historical countries are a tremendously tricky thing. Not only history is hard and history is written by different people, but also just the concept of what it means. Like, let's identify what historical country Mexico City has been in ever. What historical countries overlap Mexico City? And the answer is, well, there are several. You know, there's the Toltecs, there's the Aztec Empire, the First Mexican Empire, and then from 1810 to the present, there's Mexico. So it's a tricky thing if we ask for. So in other words, those are all sort of things that existed in space and time that overlap the current position of Mexico City. So, for example, here we can probably ask for that. Here we go. So this is now the date intervals when Spain overlapped Mexico City, and so on. Now, notice the kingdom of Spain is listed as being 1479-1873, but it overlapped Mexico City only from 1521 to 1821. So it's a tricky thing. Now, I learned lots of history playing around with this. If we say, what are historical countries that overlap London? The answer is all kinds of things I'd never even heard of. And we can do, let's go to Oxford, for example. Let's say Oxford. Let's see if it picks the right Oxford. We could do that too. Let's do historical country that overlapped that and we'll see different things here. I suspect Kingdom of Wessex, we don't see Mercia, we see different things overlapping the region of that. So let's say, by the way, once we've got this historical country stuff, we can do things like make a timeline plot. So there's the timeline plot of the different countries that overlapped the location of London at different times here. So we can, for example, compute the longest duration thing that overlapped city of London from, let's see, it seems 928 AD to 1707. It was in the Kingdom of England. That's interesting, actually. Okay, well now let's say for example, for 800 AD, let's ask what are all the entities that were, what are the geo entities, the historical country geo entities that make up the United Kingdom in 800 AD? And I'm not quite sure why it's taking quite so long to figure this out, but let's go ahead and there we go. Oh, oh, come on, let's try it again. Yeah, it requires, I mean, what's happening here is a bunch of geodatabase activity that is trying to figure out what intersects with what, et cetera, et cetera, et cetera. Let's hope this works. Yeah. Okay, there we go. It worked this time. So now we can make a geolist plot of all those places and we see this nice map. Isn't it cool that we can do this? Of what the uk, who had different parts of the UK at different times. I didn't know Wessex went all the way down to Cornwall. Well, learn something new. Okay, so we've also got other kinds of historical data. We've had for a while we've had military conflicts. Now we can say, show us the geo entities of military conflicts between in France from 200 BC to 200 AD and hopefully we'll get this result back and we can then get this back. Oh, come on, what's happening here? Let's do this again and hope for less congestion. But any case, we should get back a list of, of all the battles that we know about over that 400 year period in the region of France. And we didn't. So I'm going to cheat again and show you the results. There we go. And we can then plot where were those battles and we find the answer. Here's the answer. It's kind of interesting. Computational history is sort of a new type of thing to really be doing and we now have very good tooling to be able to do that. So for example, here, let's do something similar, let's say military conflicts in the Atlantic in the period 1939 to 1945. Let's hope this works. This time is going to show us naval battles during the period of World War II, I hope. Oh, what's going on here? All right, well, there are lots of. Oh no. Drat. Okay, well, I'm going to show you the answer. I'm going to cheat again. Here it is. It's. And then maybe we could show a similar kind of thing for let's, let's say military conflicts around Carthage in 800 BC and so on. All of those are things we can compute. Okay, but again, let's do something. All of this stuff is now computable. So if we want to say this is kind of an interesting question over the period. So the Roman Empire was a space time region from 27 BC to 395 AD. The Han Dynasty was a space time region from 205 BC to 220 AD and the question is how close did they get ever? And. Oh no. Come on, let's try one more time. Okay, I'm going to cheat again. Here it is. So the answer is 1200 miles, which is kind of interesting. I had no idea. And we can, if we want to, we can go ahead and get a sense of that here. Sorry. We can, you know, we could compute, let's see. We could actually compute, make a geolist plot of the Roman Empire and the Han Dynasty. But there's a subtlety here because what we're showing when we ask for Roman Empire is the Roman Empire at its maximum extent and the Han Dynasty at its maximum extent. But there's no. That's different from the, from every region that was ever in the Roman Empire or ever in the Han Dynasty. We call that a geovariant, which is the Union area. So in other words, if something was, it could be the case that, you know, the Roman Empire couldn't hold on to England at the same time as they held on to Egypt. And so there would be a potentially different, you know, so we can see here going up in England, we can see it went a bit higher in the Union area. So at the time when the Roman Empire had the maximum overall extent, they'd kind of lost part of Scotland here, but at some time they'd had Scotland. So the union area of the Roman Empire included that part of Scotland because that's everything that ever was in the Roman Empire. And so when we were computing before the minimum distance between these empires that's in the space time region. So that's not the union region. That's at a particular slice in time, so to speak. Tricky business. So we can, for example, let's. Yeah, I mean, we can do all kinds of things here. Let's see. I don't know whether we can do this. This seems like a very challenging kind of thing to do. Hold on one second. Let's see. We could, if we really were ambitious, but I don't think we're going to wait long enough for this. We're going to get the list of polygons that are in the time series for the Roman Empire and we are going to make a slideshow video showing the development of the Roman Empire over that period of time with. Well, okay, then we managed to do that. Okay, let's see if we can do this. Let's see if we can make a slideshow of the evolution of the Roman Empire over that period of time and generating video frames. Okay, this is going. This is going on reasonable clip here. All right, let's see what we got. We're just going to show the coastlines because there's not much point in showing the modern countries. And let's make the show run the video. Okay, so we see the Roman Empire going and finding that it got up to Scotland, it retreated. It got down to different places, it retreated. We see it kind of flopping around in the Middle east here. And it's pretty cool that we can do this. And if we wanted to, we could even do things like make a 3D plot showing the kind of the space time object that is the Roman Empire. All right, let's go. Not just here on Earth, but let's go out into space and into astronomy and let's talk a little bit. We added a lot of capabilities in astronomy in recent versions. Let's take a look at the sky. It'll be from where it thinks I am with a. Oh, just probably not where I actually am. But anyway, it's. This is now showing with the background of white sky. This is showing a sky chart. And one of the things that's notable here is these axes. These axes are showing the. This is the horizon here and it's marked off in hours. This is the plane of the ecliptic, the orbit of the Earth around the sun. And it's marked off in months. And this is the galactic plane and it's just marked in degrees. So there's sort of three different kinds of axes that we might be using here. So that's a tricky business. And we're able to deal with these axes that can be any shape because in recent versions we've introduced this kind of notion of an axis object. So we can have a really funky axis. So this is an axis, that's a spiral axis. We don't have to get as elaborate as that for astronomy. But this capability to have these different kinds of axes are important. Now it can be kind of tricky because for example, here is that same sky chart but now in a mull wide projection rather than. I think this is ortho, this is. Oh my gosh, what's it called? Projection, where you're just looking a stereographic projection. And we could try, if we wanted to, we could try making a projection here where we actually show all directions. And then. Well, what's this? Well that's because you're looking into the ground there. So this is the sky and this is the ground and that's sort of looking underground in this projection. But you see that all these axes correctly track these projections and so on. And if we want to really see things a bit more elaborately, we can add here astro gridlines. We can add them according to the galactic coordinate system. And yeah, it gets pretty complicated here. That's all the deformation of the grid lines correctly represented in this different projection. I have to say I have half a mind to just try another projection just because it's so cool that these things work. What could we try? Let's try. Let's see what more exotic projections we have. Let's try Lambert Azimutal. Okay, that wasn't too exotic. We seem to be looking at. Where are we looking here? I have no idea. There's Polaris. That's the North Pole. I don't know where we're looking here, but in any case, that all just works. Now we can do things like we could make. This is now again the mullwide projection. But now we're going to actually display. Boy, it looked different when I made my, my post because I guess the time is different. So we could, we could tell at a different time of day. But this is projecting the, the Milky Way and projecting a picture of that onto here, onto that projection. Okay, well, in addition to visualizing things in astronomy, you can also compute things in astronomy. For example, let's ask when will Earth rise for the Perseverance rover, which is on Mars? And the answer is 8-2-330. Actually we say percent minus now it'll tell us that's 9.8 hours from now. The Persistence rover will rise. The Earth Will rise over the horizon for the Persistence rover. And we can ask for moon and rise and set times. By the way, let me just comment that this calculation is a. What it means to say 9.8 hours from now or 3:33am is tricky because Mars is. I don't know how far. Let's just find out. Astrodistance of Mars. Okay, 1.5 astronomical units. Let's say that divided by speed of light. And let's compute here. Okay, let's do a unit convert of this to minutes. 13 minutes right now is the light travel time to Mars. And so that means that when we say it's rising at 3:33am GMT time, there's a question of what that means. And for that we have to have all these elaborate coordinate systems in the solar system that take account of the kind of equal time simultaneity surfaces. And it's a big story of relativity to figure out what that means. I think this means, I think by default we're showing the time as it would be received at the Earth. So the time when, assuming the Perseverance rover, as soon as it saw the Earth come up over the horizon, it let out a big whoop. And we with in radio, so to speak. And this will be the time that we would receive that whoop from, from the Perseverance rover. Okay, so now we can ask for the things like the rise and set time of the Moon. We could ask for things like. This is just looking at the time differences of when the Moon will rise and set over the next week. We can see that it varies a little bit over time. We could see the same thing plotted over the course of a year. We could look at the rise and set times. And there's all kinds of astronomy associated with that. A lot of tricky things here. A lot of tricky issues. Like when the sun rises, what do we actually mean by sunrise? In other words, the sunrise is it when the first beginning part of the sun tips over the horizon? Is it when the bottom part of the sun goes over the horizon and There's a roughly 2 minute difference between those parts? 4 minutes across the whole sun. It's truly a fact. 3.6 minutes across the whole sun right now. So similarly. Well, okay, there's a lot of trickiness here because if we do the same thing for Venus, Venus is pretty tiny in the sky. And so we have to actually get the answer right to the millisecond. So this is again a story of a complicated story of the granularity of dates, the sort of analog of precision for dates. So that's kind of how that works. And there's a notion of a reference altitude, which is kind of what part of the object you're looking at. All right, that's a bit on astronomy. Let's turn to a completely different area. Let's talk about some things in geometry. Let's compute this. We're going to make a nice picture here, and there's a picture of some molecules. And let's now go ahead and say ar publish of that. So what that's going to do is export that model. And it's going to export it to the cloud, I hope, and we can go ahead, come on, come on, come on, export this. And why is this taking so long? I guess it's a lot of geometry here to export. But anyway, once this is exported, it will put up a QR code and you can hold up your phone, you probably hold it up to the QR code that gets generated here in a moment, and you can then see that object in VR in your phone. And the same works in things like the Apple Vision Pro. You can get this geometry right. Into the thing that you're looking at in VR. I don't know why this is not coming through. Well, we can. Let's be boring and. Okay, come on, interrupt. Stop, stop, stop. Ah, there we go. Something stopped. Oh, dear, dear, dear. Okay, all right, so we didn't get to show the queue. I'm going to cheat here again and I'm going to show you the, the QR code. And because you could go to that very QR code and you should be able to get the, the, that same image in VR on a phone or Vision Pro or something like that. Okay, well, all sorts of other things we've done in geometry, things like adding color to geometry. Like, for example, we can, let's say we make a region that is a purple cube, and then we say, let's go ahead and do some constructive solid geometry. Let's make the intersection of the blue cube. Reminds me of the skunk works of Lockheed from a long time ago and a yellow sphere. And now we've got this object that tracks those colors and is a geometrical object that's been created that way. Another piece of just sort of filling things in quite literally has to do with polar plots. We added the capability to make a filled polar curve. So now that fills that in. And we could say, for example, what's the area of that filled polar curve in the past, for a long time, for 30 years or so, We've been able to make the line that goes around here, but now this is knowing how to fill in the region inside that curve, and we can compute its area. 19 PI over 2 in this case. All right. Another thing we've done also in the sort of styling area is, well, finally, after a couple of thousand years, we managed to make Euclid computable. So this is a theorem from Euclid represented in computable form, where it's saying things like the midpoint of this is equal to that, and so on. And we've added the capability to style these diagrams as Euclid never could. He did draw diagrams, but they were, you know, the ones we have from those, roughly those times were, you know, black and white on papyrus, so to speak. Now we get to have a plot theme for the web of our Euclid thing. Let's see whether we can go, oh, I know. Don't know what we're doing here. We might be able to pick up one of those points and say, update scene. And it will go and find how to, you know, apply this theorem when that point has been moved and so on. So this is kind of a pretty elaborate. Okay, let's see if we can do that. This is. This is kind of geometry in action in color as Euclid never saw it. Okay, let's talk about another big, important change for people who use Wolfram language every day. It is what we call cell linked percent. All right, so let's see how I'm going to do these. Show these. Wonder if I'm going to be able to do this like this. Probably not. Okay, let me. Let me show it to you a different way. All right, let's say we say range of five. That's out seven and so on. Now we say median of that percent. Percent usually means the latest result. Okay, we get a result. It's all good. Okay, but let's say I had decided to do median of percent squared instead. I try reevaluating it and oops, doesn't work because percent refers to the most recent thing I generated. Not the most recent thing I can see on the screen, but the most recent thing I generated. Okay. I've been worrying about what to do with this forever. How to deal with this issue of. Oh, I can see it on the screen. But what is it? It's two steps back. Well, I can type percent. Seven. That will work. Fine, fine. Let me show you what we've now done. As soon as I type percent here, I get an autocomplete menu and my autocomplete menu shows me different previous results. So here I can just select the 1, 2, 3, 4, 5 result. What do I get? I get that little thing that says it's linked to line seven. I mouse over line seven. I see that it lights up line seven here. Now I compute this and it'll do the right thing. Give me three there. So in other words, this is a way of doing that. Now notice that that says. Okay, so let's say I Change this to eight here, 10, whatever. Okay, that will now become out 11. Now notice that this thing here updated itself to be a link to line 11. And now if I reevaluate this, that will now give me the median of this new list. So this has been permanently linked. It's a cell linked percent. It's something that's linked to this cell. It's not linked to something at a certain stage in the evaluation process. It's linked to that cell. Okay, so it's the. And so, by the way, there are a lot of tricky things here. So for example, I might have a cell that says random integer of 100, for example. And then I could say, for instance, you know, one over that. And now what's the that? Okay, one over? Well, I want to link it to this thing here. So that's linked to line 13. It's not actually linked to the 45, it's linked to line 13. So here I get one 45. But if I reevaluate this, I'll see that changes to 15, that changes to 72. I reevaluate it, I get one 72. So it's always cell linked. It's not evaluation sequence linked, it's cell linked. Okay, how does this work? Well, underneath, hidden underneath the cell is a cell id. And that cell ID is actually, you can't even see it. There is a unique identifier that's unique across sessions, actually that identifies that cell. It's a UUID for the cell. Now, by the way, if I were to quit the session, I would see that all of those things which say 11 and so on and so on and so on. Let me quit this session. Okay, so I'll now quit the kernel. And so now all those things become dotted. They actually know what cell they refer to because it's a cell linked thing, but they don't refer. The value of that cell hasn't been determined. Okay, so let's see what happens if I do this. Okay, so what's it going to do? Well, the answer is it's going to say I don't know what that value is, but I could try reconstructing it from the output cell I can see in the notebook or I can go to the input cell and you can reevaluate the input cell. But let's say reconstruct from output cell. Okay, that will now still it'll, it'll show that it's linked to that and it'll reconstruct it, but it won't say it's linked to a number. Now if I go back, I don't know how to do that actually if I go back here, I could link it instead. I could say reevaluate this input cell and link it to that input cell and it would show that up here. Well, let's see if we close this notebook open in a new session, we can do this and we get rid of and we just don't have that cell there. Let's see what happens if I. Let's go ahead and quit here again and I'm just going to delete this cell. Okay, and let's see what happens. Delete the cell. And now look at that, it's broken. The link is broken. So it says linked cell is missing. So now if I evaluate this. The reference cell does not exist in this notebook. Okay. Now it can be tricky because you can see things like it can exist but in another notebook. And it gives you a little sign that's kind of like a wifi sign that shows you, you can go to that other note. It's picking something up from another notebook. Okay, by the way, in this menu that you get, if you type percent, one of the things you get is that that dot, dot dot produces an iconized version of that output. That iconized version is permanently stored in the notebook. You've burnt in that output value. If I un iconize it, I'll see that output value burnt in as a part of the notebook. Okay, by the way, if I now say, let's say range of percent and I fill in that one there, there will be a right click menu that has all kinds of things about. I don't know why those are colored there, but that's kind of weird. Go to the input cell replaced with rolled up inputs. That's another kind of thing where if you've had a series of things that go this to this, to this to this to this. Let's say we say 67 F of percent, G of percent okay, and now we go H of percent and now we say here, okay, now we want to do this and now in that percent. Sorry, I'm not doing it the right way. I need to do this. Of percent five. And now I can go to this and I can say replace with rolled up inputs. Oh yeah, yeah, yeah, yeah. Right. That, that's. What's that doing? I think I have to evaluate that. I'm a little confused about what this is doing. But the idea is that it allows you to take a series of things that you've generated in this session and progressively kind of roll them up in, in place. Okay. All right, let's talk about other things to do with kind of smoothing the user interface for Wolfram language. We've got a bunch of things to do with typing. Let's see if I can show you these. I might need to go to even higher magnification. Let me do that so I can show you these a little bit more easily. If I say F of G of X, there's all kinds of questions about what is colored when and so on and when. Maybe this is, maybe this is too. It's one of these kinds of things where kind of. If you're actually doing it. So okay, there's this question of autotyping. If I type F bracket, it'll autotype the closed bracket. And the question is, if I type a closed bracket, do I type through that bracket? And the answer is if it's yellow, you type through it. If it isn't, you don't. So let's try this. Let's say F of g of a list 4, 5g6 comma. Okay, now that bracket is a type through bracket because it's yellow. But if I go back in here and I've got this bracket there, it's not a type through bracket because it's not yellow. And so if I were to type a bracket, I would explicitly get another bracket. So if it's yellow, it's type through is the basic, basic story. And this is just part of kind of making it so it's faster to type through things. It's a little bit tricky, but in a sense it just does the right thing. Okay. Another thing here is the ability. I need a big lump of code here. How do I get this? Oh, it's not put to copy, Humphrey. Humph. How can I get that? Ah, I'm not sure I can that. I just want a lump of code from somewhere. Okay, let me go find a lump of code from somewhere. Let's see. Gosh, lump of code. Let's get a lump of code. I'm not. No responsibility for what this code actually is. But I'm going to get a lump of code here. Actually, this code is sort of interesting, but. Okay, so now this code has all kinds of variables in it and so on. If I mouse over the. If I go to this variable ra row and I click it anywhere, it'll show me. It'll highlight the other instances of that variable. So not very exciting. Well, there I've got the function first, it's highlighting other instances of that. So this is something you find in lots of ides, but we have a more general version of this which deals with scoping all kinds of other good things, but generally lets you more easily navigate code. Let's see, some things to do with context completion. Let me not go into that. Here's a major new thing. So this is the ability to just plain type. Okay? So if you want to enter New York City, for example, you can type control equals. You get that kind of box, you type nyc. It does its thing. Okay, but let's say that there's now a new way to do that. Let's say you're saying a list and then you say just type equals bracket nyc. It'll just stay as equals bracket equals bracket la. Okay, this is a syntactic form that gives you free form input. It is the function. It is literally a function freeform. If we ask, what is that thing? Well, that thing will evaluate to New York City, but it is freeform evaluate of the string New York City. Okay, but that's an input form for freeform evaluate. Okay? And we can then say, you know, it's kind of nice to be able to just type these things in. It's. For example, we might type, you know, let's say we type geographics, just type in, you know, we just keep typing here, you know, Washington Monument, geo range, whatever. Now, of course, if there are multiple interpretations for one of these things, you're toast. This is kind of for the case where you've been explicit enough that you don't have multiple interpretations. You know, if I were to say brackets, London, for example, there are multiple interpretations of that. And I don't really know which London it's going to pick me. Okay, it's the one in the uk. But if I type control equals London, then I will get something which has that. And I can pick between these many different Londons that exist in the world, like the one in Arkansas that I'd never heard of before. Okay, let's see. You can also use freeform evaluate inside a program. So, for example, let's say I just join the string A to the string S and do that for S. Ranging over the Alphabet. I can see what is the default freeform interpretation for AA, AB, AC, AD, etc. Etc. Etc. And that's going to be grinding for a while because it's trying to go and find weird interpretations of things. But let's see if it can come back with some results here and then we'll go on and talk about some other things. We can also get freeform evaluate to return kind of held expressions where the evaluation hasn't yet happened. Okay, downloading metadata for taxonomic species. Okay, so there's a creature on the loose somewhere in the A star. Family. I wonder what creature it's going to be. What creature is this going to be? Okay, is there a creature that is of the. Whose name is a something or other? All right, we're about to find out. The suspense is perhaps not building, but the. Let me see. Come on, where is it? Where is it? Where is it? Where is it? I don't know why it's quite taking so long to download all these values, but let's see if it comes back here. Okay, wake up. Oh no. Well, this is what we get for just. Okay. All right. We didn't manage to get an M, an am, I guess it's a bit weird, but AI appears to be a pale throated sloth by default. Interesting. Okay, it has other interpretations, probably as capital letters and so on, but by default it's a pale slogan throated sloth. I wonder if we can get an image of the pale slo. There he is. Well, very jolly. Okay, maybe that should be an icon for some kind of AI system since there is a pale throated sloth that's called an AI. Huh, Interesting. All right, let's keep going here. I'm going to make this a bit smaller so we can see more. Okay, we're getting towards the end here. We're almost almost at the end. Let's talk about diff. And by diff I do not mean derivative, I mean diff in the computer science sense. How do I make a diff between two notebooks? Well, this will make a side by side diff of two notebooks showing which cell was removed, which cell was added, and so on. So we now have this function, very general function diff that diffs things. So for example, for notebooks we can make sort of an alignment chart of where did the cells. This is a cell level diff that shows us where did cells get deleted? Where did they get modified? Where did they get added? And so on. A diff is a symbolic expression. So we can have files and this shows the diff object between two files. And there are lots of ways to display a diff object. So for example, that's a summary box. But we could pick an array plot and that will show us kind of an array of the differences where the differences were between those files. Or we could pick for example an alignment chart. This is the thing we had before, and so on. These are different ways to show a diff, but ultimately it's a symbolic diff object. What can you do with a symbolic diff object? Well, let's look at a simpler form of diffusion. Just say we have the diff between those two lists and we can see here two was added, four was taken away, et cetera. That's the combined view. We could have as well. Had a side by side view. There it is. Let's go back to the combined view. It's easier to see what's going on. Okay, so we have a diff. This thing here is a symbolic diff. And now the question is what can we. Well, we can do this diff in many ways actually. Let's show some other diffs. This is just. What's this? Okay, that's a string with a unified view. We can have an expression. That's a view of the expression. That's a cell level view of an expression cell showing differences within the cell, differences of styles and so on. There's a lot of differencing to go on. So we can say what's the difference between the Spanish Alphabet and the Polish Alphabet? Some letters are added, some letters are removed. What's the differences between the Polish and Spanish with combined? And then let's give a unified summary. We can show that of Spanish and Polish, let's et cetera. Or we can do the same thing for genomic data. This is going to be the difference between two genomes with a lot of the diff is not shown because they're the same. But this is kind of the insertion and deletions indels for that genomic data. Okay, so let's see what happens if I do this. So if we do that, we take that symbolic diff object and we say show that with character alignment. That's going to show those SNPs and these overall insertions, deletions, et cetera. Okay, very convenient sort of machinery for dealing with diffs. If we did a sequence alignment on those sequences, we'd see this kind of thing, which is useful for programmatic purposes. But the whole point is we can also programmatically use these diffs. Okay, well there's two way diffs. We get more elaborate. There's three way diffs. Here's the three way diff between Latin, Spanish and Polish. In that view, we can give a unified view of those things. That's the unified summary of the three way diff. Or we could say let's show an array plot of the three way diff. Actually let's just show what is side by side. Okay, that was that. I'm now wondering what side by side summary is. Okay, that's this. Okay, so now let's say we've got a diff. Okay, there's our diff. Now we can ask things like let's make this diff with a. That's a character based diff. But the diff granularity could be words. And then anytime there's a word that's wrong, the whole thing gets picked out and highlighted. Okay, there's kind of an interactive form of a diff. This is between two files. This is making a report. This is a notebook. That is a diff report notebook. And here it is between these two files. This is the diff. And we can start opening things and looking at where those changes were and so on. Now, by the way, when it comes to. I wanted to show here. Did I not show this? I wanted to show how you apply a diff. You can take a diff and use and apply that diff to a notebook, for example. So let's do a simpler diff here. Let's take a diff between. Let's take this diff here between Spanish and Polish. And we can say there's the diff. Now we can say diff. Apply. Apply that diff to a list. Let's say A. Oh gosh, I have to type one of these letters. Hump. Well, I'm going to just put in some other Alphabet. Let's try the Latin Alphabet here, see if this is going to work. Oh, notice that nice lighting up of the Alphabet words. It's going to work. Oh right. Because it can't do that because it's an offset thing. But in any case, the idea is we're applying diffs here. And because diffs are represented symbolically, we can apply them symbolically and we can do that with notebooks as well. All of this stuff is very useful. If you're using Wolfram language with a source control system, for example, like git, you can start to use this to just apply. Do all kinds of diffing and so on. Another thing that we've added in this version function called notebook cell data. This is another thing that relates to notebooks. Let's see the. This is giving us a data set that has information about the 512. My gosh, I've really done 512 cells in this notebook, I guess. So the 512 and I mouse over that. It'll show me a form of that cell. Probably if I go to the bottom, I'll get to cells that are recent here. There they are. So this is kind of a computable version of the content of this notebook. A notebook is a computable object. But this is kind of showing me the summary data about this notebook, including the cell change times. That's a useful thing. So for example here I could make a date histogram of. Oh gosh, well. Oh, I see something must have been. I don't know why it did that. Something that I added here I pasted in something that came from sometime in July. But otherwise this notebook is all modified fresh for you before your eyes so to speak today. Okay, more things we've done. We're always tuning up the language. We're always a lot of little language tune ups. The function nest, one of my favorites, been there since version one. We've added a form of nest that is an operator form. So Nest G3 is an operator form that doesn't on its own do anything, but if we apply it to X it will nest like that. So it's a way of having composed functions where some of those functions are nested functions. It's like G to the function power 3, F to the function power 10 and so on composed together like this. So that's a small thing. Let's see what's this here? The. I'd forgotten what this is actually. This is applying. Okay. Oh yeah. Okay. You can apply this or to all of these things or you can do. This has been a thing we've had for a. A while. Are any of these true with respect to prime Q? Well, it's not that exciting, but we're also adding a thing called any match which is convenient if you have multiple patterns. And do any of them match? Are any of them matched by geoblank and so on. A similar thing is all same by. Are all these things here the same by this? It's kind of like a same queue with its own kind of function. Same test, lots of little detailed things. This is. Okay, talk about rounding things out. This is adding Features to the rounding radius option, allowing one to round it differently in different sides. That might seem like it's totally trivial and uninteresting, but if you're making things with a bunch of buttons, it matters. You're making nice elegant things with buttons, it matters which side you're rounded on. And you know, you can just go ahead and just round different amounts of rounding. Other things, things like string apply String apply takes a function that is normally applied to a list. So we can make a list of characters for hello there. This applies rotate left to the list of characters, but as a string. So again, I told you this was little tune ups. This is bit flip, a little bitwise function that's useful where we can see it. If we look at the integer digits here, we'll see it flipped one extra bit. Another tune up that I wanted has to do with Boolean conversion to nand. NAND is a functionally complete primitive for Boolean algebra. And I happened to find the very simplest axiom for it that gives all of Boolean algebra back 24 years ago now. But so I'm an enthusiast of NAND. And now you can do conversions not just to things like CNF and dnf, but to NAND in such a way that it doesn't simplify and it really just is nands. All right, let's dive into two or three last things. These are now getting a little bit more systems oriented. Let's talk about the compiler. We've been gradually developing a very sophisticated compiler for Wolfram language. That compiler is what we write lots of internal code in. We used to write code all the way down in C. We don't do that anymore. We write it in compilable Wolfram language code which compiles into LLVM and then into machine code targeted for each particular kind of machine. The compiler is a sophisticated thing and a lot of what's happening is it can be made faster when it makes certain assumptions. Typically when it makes assumptions about types like this thing, this variable I will pretty much always fit into a machine integer. Just encode it as a machine integer. If it doesn't, you can generate an exception. We'll go and do the full Wolfram language symbolic evaluation. But if it does, we'll can get something that's all the way down in the machine code and so on. Okay, so one thing we have with compiler information, this gives information on kind of what how the compiler sees a particular function. So for example, for dimensions, this says the Type signature is 4 dimension. It's a packed array of integer 64s. This is actually the code, it's open code that actually is the implementation code at low level inside the compiler of the function dimensions. I'm sure if I ask for a function, like, I don't know if I want to really do this, but let's say I ask for a function, let's ask for the function map here. Okay. The compiler information for map is much more complicated. There are many different cases, each one is some particular thing with streams and so on. This is a packable abstract type. I don't even know what that is. It's a whole elaborate thing. But this is the signature that shows you kind of what you know, how when can map be compiled? Most of the time you don't need to know that the system we're increasingly providing user assistance capabilities that sort of show you interactively what's compilable and what's not. But this is under the hood. This is what the compiler is thinking about, this is what it knows. And so, for example, if we look at something like integer64, we'll find that there's a type hierarchy. This is the hierarchy of types associated with Integer 64. There it is graphically. This is again, I told you, this is under the hood. Things are getting kind of complicated here. This is the hash table, data type, raw data type. And you can see kind of the fields that a hash table uses, unsigned integer 64s and so on, the abstract types that are involved and the operations that you can do on a hash table. So those are the things with the data structure object. Those are the things you can do. This is all stuff that in typical everyday usage of Wolfram language, you never have to worry about this internally. A bunch of our code is based on all of this stuff being used automatically to compile things to very efficient machine code. Let's see when you actually run the compiler, and it's not as fast as we hope it will be, where big challenges to compile the compiler. It's now doing a much better job of showing you what it's doing. I mean, you can see how much effort it had to go to to compile that very trivial problem thing. But that's what's going on there. Now let's say there's a problem. We're trying to compile a sin function and the types don't match. Okay. First thing is you can go to the source. You can see what happened here, that if this was a longer function, it's much more useful. You can see what didn't compile? Well, okay, what had this type problem and that's useful. So if you have many levels of definitions. So this is a thing where we've declared multiple functions. Now we can try and compile this function here we've defined another function, we try and compile it, we say where's the source? It'll show us. We go back here, that's in my one, and so on. We can show this. I, I think this will allow us. Okay, this is showing us where those errors occurred and maybe one more complicated version. Oops, that's not what I wanted, is it? Oh, there it is. Okay, this is a slightly more complicated example where again it's non trivial to see where the error occurs. And now this is showing us that. And that's very useful if you're trying to make compilable code. The typical thing is you'll write top level code without any of these type specifications. Then you'll start spraying type specifications and you'll keep on seeing does it work? Does it work? And, and that will, that will determine that. Well, ok, let's, let's see. We can, we can do other kinds of things. This is to do with exception handling. Maybe we don't need to talk about that. Things to do with compiler runtime, error handling and what the actions are and compiler runtime errors, et cetera. But in any case, the main point is this is an incredibly powerful way for us to write extremely efficient code and for people, for example, in projects I've been doing just recently, where we have sort of an inner loop that needs to be sort of right down to the metal. We first of all wrote it in top level orphan language. It was pretty efficient. But then we were like, let's get it all the way down to the metal and we put in compiler declarations and then we can compile it and it's really as efficient as it can be. Okay, let's talk about, we've got two more topics here. Let's talk about integration with external languages. So for example, let's say that we're trying to integrate with Python. We're trying to call a function in a Python package. It's a jungle out there. There's all these packages, they have all these dependencies. It's a mess. That's, you know, Wolfram language doesn't have any of those issues. That's one of the very powerful things about Wolfram languages. Everything is integrated. Also the amount that's integrated is vastly larger than elsewhere and sort of a more Powerful representation of things. But we don't have this kind of dependency hell. Well, let's see, we've now got a mechanism for encapsulating dependency hell, so you don't have to see it. And we can see here it's collecting all kinds of things, things. It's downloading weird packages and it now gets this result. But what we've done is we've created an external environment that is a Python environment with these dependencies already loaded into it. And so we. And that means that we can send this to somebody else. They don't have to. They don't. We don't have to tell them, oh, you need version three and this package loaded, and et cetera, et cetera, et cetera, etcetera. So just to show how that works, let's start a session. Start an external session that uses Python, again with an external evaluator with these dependencies and with that Prolog. Now we can start doing this. We actually have a bunch of this functionality directly in the language. But if we wanted to, we could define this using these Python functions. We can then go ahead. And it's really nice because we've integrated this. That thing that's an image from Python just comes right back as a Wolfram language image that we can do whatever we want with. We can just say, you know, colon negate of that image, and there it is. Now, there's some lots of tricky things here. We've got this object that's a board object, and this board here is, notice it's an external object that is a thing that lives inside the Python session, but we can now query it in a symbolic way. And we can even do things like we can say, apply this function to that external object. We get back this external object, it's got all kinds of things in it, but it's an external object. We can now go ahead and plot the new board configuration. Again, the board lives in the external Python session and we are now poking at it with this system. So, for example, we could say, what are the legal moves from that board? We get a bunch of external objects. We can say, what are the UCI representations of those? We're now calling into that external object. So we really have kind of symbolically encapsulated this external functionality, which is pretty useful thing. So here we can do. What's this doing? This is doing. What is this doing? This is doing. Oh, that's defining. Right, that's just defining a set of external operations to do. And now we can say external evaluate in the session those things. And that I think will be a sequence of moves that we, we made. So, okay, but the main big picture here is encapsulation. And this means that in the function repository, for example, we can have things that have external dependence on Python R. Also we can have actual dynamic libraries, C libraries and so on. All these things can be fully encapsulated so that you can have a function whose top level interface is pure Wolfram language. And it makes use of all of the capabilities of Wolfram language, but underneath it's implemented in some other way. So it's a very convenient way to encapsulate things. It's something you'll see many kind of encapsulations that are coming along those lines. Okay, last topic. Standalone Wolfram language applications. Okay, so let's say you want to write a program, an external program, and you want it to call Wolfram Language. Well, now it becomes quite easy to do that. This is, I mean, again, we're down in the entrails of the creature. But basically the point is, in version 14.1, we've introduced the capability to basically have C code that uses a thing we call the Expression API to call to a DLL that is a library version of Wolfram language. And more than that, we actually have the capability of pruning that library version so that it can get that pruned library can be much smaller than the standard wolfmlanguage executable and we can. Oh, I see a bug here and I'm just going to show you what I wrote about this. Although I see a bug that shouldn't be $1, it should just be a subscript. That whole thing should be a subscripted variable. But in any case, the basic point is there are C language functions, WLR functions that are able to build up expressions, manipulate expressions in the DLL that we are using. So, for example, we've built a version of this just to understand what's going on. We've built a version of this, for example, for language server protocol, where we're supporting things like Wolfram language syntax coloring in Visual Studio code. There is just a tiny C program that calls a Wolfram language program that is encapsulated in a standalone application version of Wolfram Language that is called from any Visual Studio code version. And that's something where there's a bunch of plumbing associated with being able to deliver kind of pruned Wolfram language standalone executables, and we're making those available in all sorts of places, including open source projects and things like this so that people can make use of Wolfram language capabilities all over the place. Now we've already had capabilities like that in, for example, the Python client library can call either in the cloud, call an API in the cloud, or it can call locally into a full Wolfram language system using WSTP server, Wolfram Symbolic Transfer Protocol Server. But this is kind of extending that story of how do you get to call Wolfram language from whatever you want to call it from? So that's that story. All right, well, so I think I am almost done here and just that was kind of the run through of what we've been up to. That's the latest output over the last six months from our research and development pipeline. I think it's rather impressive actually. It's just a snapshot during that six month period. We've also been working on the next version and the version after that. You'll see those versions as they come out. You can watch the live streams we've been doing of those systems and versions being designed. But that was kind of a look at version 14.1. I haven't been able to use this until recently, but I'm really enjoying a bunch of the features. I use the percent selling percent all the time. I'm using some of the typing affordances all the time. And some of the other features. Here are things which I'm expecting to have projects that will be dependent on those features that simply wouldn't have been possible without. Well, let's see. Maybe I have time for just one or two questions. I think I'm a little bit running out of time here, but perhaps we can. Let's see a couple of questions I see here. One is from Sleepy I that they noticed that there are more external services that cover a bunch of LLMs. And the question is, will there be okay? Will there be a local LLM for our system? Okay, there are going to be two things that happen. First, we have an LLM kit, which is kind of our prepackaged way of getting LLMs by hook or crook from wherever you can get them. And basically you get LLM kit and then from within the language you can just assume you have access to an LLM and that may be through an API or it might be sometime it might be local. It will depend on how powerful your computer is, it will depend on how much memory you have, how much GPU memory you have, et cetera, and you'll be able to make choices along those lines. Obviously there's a progression in the world towards local LLMs. And depending on the power of LLM you need for what you're doing, I think you can expect that that will be something available from us. There's a question here from Ethan about neural net framework improvements. Yes, big framework improvements are underway. We have been updating. There's pieces of this in version 14.1. The support for the built in support for NPUs and other built in GPUs is part of that process. But more generally we are setting things up so that our full neural net layer system, our full symbolic neural net system can support, can be based on, not can sort of live on top of different kinds of infrastructure. So we are now on our fourth infrastructure system called mxnet. We are generalizing our infrastructure so it can live on top of whatever infrastructure may arise in the future. Right now Pytorch is popular, but we don't expect that will necessarily be popular forever. But we're setting it up. We're sort of fed up by the time we're on the fourth one of these, it's time to make it completely general and that's what we're doing. And you will be able to do all our operations on any foundation you want, any of the supported foundations, and also within specific foundations that have particular extra features from specific hardware or something like this, you'll be able to make use of that. The question will modal logics be covered one day? Well, yes, actually, we actually have a package for temporal logic was built a number of years ago that we should expose, but we have a very general version of that type of thing that's coming as part of our Symbolic Discourse Language project. That's something to look forward to in the future. There's quite a bit of heavy lifting there to do with sort of trying to understand how to make other aspects of the world computable. Temporal logic, spatial logic, possibility logic, all these kinds of things. These are parts of sort of little calcul that logify pieces of the world. All right, well if that's it, thank you all very much for joining me and bye for now.
More from Guy

Cheryl Strauss Einhorn | The Human Edge: Smarter Decisions in the Age of AI | Talks at Google

Rachel Glennerster | Innovation and the Center for Global Development | Talks at Google

Rebecca Winthrop | Rethinking the Purpose of Education in the Age of AI | Talks at Google

Dr. Robert Wachter | A Giant Leap: How AI Is Transforming Healthcare... | Talks at Google






