text:
What is Nix and why you should try it 461 points by vletrmx on Oct 15, 2017 | hide | past | web | favorite | 193 comments

 I can vouch for the immense improvement Nix has made to my software development process. I use NixOS on my desktop and laptop. At the OS-level, it gets a lot of things right: reproducible, immutable system configs; lightweight containers; devops with declarative configs. At a software project level, nix-shell is an indispensible tool. Compilers and interpreters aren't even part of my system-wide config; instead each project has it's own shell.nix file that installs all dependencies I need on the fly without polluting system state or virtualization. Nix is a god-send, and the developers that contribute to it are nothing short of awesome!The area that needs improvement is the documentation. Once you learn the Nix language, reading the source code is pretty helpful, but it would be nice to make it more approachable. For example, the nixpkgs repo has a bunch of Nix helper functions that are useful to developers when writing their own packages, but these functions' documentation is either buried in a long manual, or non-existent.
 By reading your comment and a little bit of the package declarations in some nix packages, it seems like the software package system of nix is very similar to rez.Rez ( https://github.com/nerdvegas/rez ) is used by some visual effects companies (including mine) to manage software packages.It allows us to have great flexibility in the mix & match of software versions and runtime environments.
 Cool! Indeed, Rez does something similar on the package management side.For Nix, this is almost a side-effect, however. Nix's primary task is to describe how to build packages, and the entire OS is just another package that groups all dependencies. You can make a single change to a file everything depends on and it will result in a new OS.Nix can evaluate the entire system configuration in seconds, and build or download missing binaries in parallel.As a result you can e.g. have a complete OS based on a different glibc (maybe with some patch you like) installed and running alongside the normal OS without the glibc patch. Packages that do not use glibc are simply shared.
 Does rez handle having an environment with two apps in it that require differing versions of the same dependency?
 It takes a list of requested packages, does some dependency resolution to arrive at a matching package list, generates environment variable setting/exporting code (in Python, e.g. setting things like PYTHONPATH and MAYA_PLUGIN_PATH), then launches a new shell with that code. So, yes, you can have multiple shells with different packages in use simultaneously. I don't think it operates below the industry software package level, which makes sense, as most industry software is non-free, closed-source binaries. Each package has a package.py with its own list of dependencies, and code for things like manual tweaks to env vars.>"Using Rez you can create standalone environments configured for a given set of packages. However, unlike many other package managers, packages are not installed into these standalone environments. Instead, all package versions are installed into a central repository, and standalone environments reference these existing packages. This means that configured environments are lightweight, and very fast to create, often taking just a few seconds to configure despite containing hundreds of packages."
 I believe GP was asking if you could have packages A and B installed simultaneously if - A depended on version X of C - B depended on version Y of C - X != Y
 Yes you can because packages are not really installed at the system level. Those dependencies are all solved at runtime.You can't have A and B in a same runtime environment obviously.
 Um, just to be clear: can I write a program that depends on both A and B? Nix lets you do that.
 At the same runtime? No.At different runtimes (e.g: different package.py configurations) yes.I can have a software called my_application which has a version that uses A and another version that uses B.That differentiation can be a flag at runtime, a "variance" e.g: gcc-4 vs gcc-3 etc.How does nix allow you to do that? For example, say I am using library foo and it has the function barIn version 1bar definition isdef bar(a, b): return a + b  In version 2bar definition isdef bar(a): return a + 10  I don't understand how you can use v1 and v2 of foo at the same runtime? Unless nix does some namespacing based on the lib version invisibly for the enduser but that looks very prone to error...If you release them as separated libraries it won't complain, for example, shotgun API imports can be by versionimport shotgun3import shotgun2so theoretically you can release a rez package whose name is shotgun3 and another one whose name is shotgun2.That way you would effectively have shotgun2 and shotgun3 in a same runtime environment.
 I wasn't really thinking about language-level runtimes, like, I don't want to solve the problem of only having one global scope in python and running into module name collisions. I'm not sure how concerned rez is with shell environments beyond what (eg.) python packages are available in it, but I was wondering about having a shell where a program foo is available that, say, requires a lib compiled with gcc-4, and another program bar that requires the same lib at the same version but compiled with gcc-3.Nix expends a bunch of complexity into fucking with dynamic linking to make that work transparently most of the time and deploying wrapper scripts to cover other cases, so I was curious if rez has a cleverer solution there.
 Oh yeah, it is certainly possible.you have build_requires which you can list dependencies that you require at build time (e.g: gcc-3 vs gcc-4) but not at runtime.So you can have things that were built with gcc-3 and gcc-4 running side by side in a same shell environment without issues.gcc itself, in this case, would be a rez package that can have multiple versions installed in the system.
 Essentially, Nix treats every version of a package, or every "instance" of a package compiled with different flags, or different "build inputs", as a completely different dependency. So foo-1.0, foo-2.0, and foo-2.0-debug are all separate things you can depend on, from the POV of the package manager. A huge "symphony" (a friend's term) of symlinks holds it all together.
 Sounds like this solves a similar problem to Docker. Can you comment on what the differences are, and the relative strengths and weaknesses of each approach?
 I was confused by this first.So Nix is ultimately a tool for making and sharing reproducible package builds. It has a binary cache, but it's not necessary. Like Ports, packages get built by default.Docker, on the other hand, is a distribution and execution mechanism. It provides an abstract way to move around a fully assembled, ready-to-go service or application running in isolation.It's entirely reasonable to use both. You can use Nix to build and manage docker images and make extremely minimalist docker images. You can use Nix knowing that the entire process is perfectly reproducible, and the Docker containerization is only a final integration step.With this, you sorta get the best of both worlds. You get a reproducible build (and if done right, also a reproducible dev environment via nix-shell) and with Docker you get the ability to build and run a prepped copy with a well-defined interface.Docker really doesn't provide a way to reproduce a built image from scratch. You sort of have to trust and build on existing images, and most folks making bulk images appeal to external tooling outside docker files to do this.
 > Sounds like this solves a similar problem to Docker. Can you comment on what the differences are, and the relative strengths and weaknesses of each approach?NixOS committer here.Docker attempts to achieve reproducibility by capturing the entire state of a system in an image file. It also attempts to conserve space by taking a layered approach to images, so when you base your Dockerfile on some base image, your resulting image is the union of the base image's layers and your own changes.Here's where Docker's approach falls down, and how this could be fixed (and indeed is, by Nix).Flaw #1:Building an image from a given Dockerfile is not guaranteed to be reproducible. You can, for example, access a resource over the network in one of your build steps; if the contents of that resource changes between two docker builds (e.g. a new version of whatever you're downloading is released, or an attacker substitutes the resource), you'll silently get different resulting images, and very likely will run into "well, it works on my machine" issues.Solution:Prohibit any step of your build process from accessing the network, unless you've supplied the expected hash (say, sha256) of any resulting artifacts.For the projects I work on in my free time, using NixOS on my personal computers, I've never been bitten by nondetermism.I wish I could say the same about my work projects that use Docker. My team members and I have run into countless issues where our Dockerfiles stop working and then we have to drop everything and play detective so e.g. new hires can get to work, or put fires out in our C.I. env when the cached layers are flushed, etc. So many wasted hours.Flaw #2:What happens if you have two Dockerfiles that don't share the same lineage, but you install some of the same packages? You end up with multiples layers on your disk that contain the same contents. That's wasted space.Solution:I'll use NixOS as an example, again. In NixOS, you can look at any package and compute the entire dependency graph. It should be noted that this graph includes not only the names of the packages, but also precisely which version of each package was used as a build input. This goes for both build inputs and runtime dependencies.Note: by "version" I mean not only the version as listed in the release notes, but every detail of how the package was built: which version of Python was used? And then transitively: what version of C was used to compile that Python? etc, etc.NixOS exploits this by allowing you to share packages with the host machine, and then each NixOS container you spin up has the necessary runtime dependencies bind-mounted into the container's root file system. As a result, NixOS has better deduplication (read: zero). Also, by the same graph traversal mechanism, it's trivial to take any environment, serialize the runtime dependency graph, and send that graph to another machine, back it up somewhere, create a bootable ISO for CD/USB -- whatever you can dream up.Thanks to Nix's enforced determinism, you can trivially build container environments (and all of their required packages) in parallel across a fleet of build machines. In fact, Nix's superiority at building packages is so strong that people have gone so far as to build Docker images using Nix instead of docker (where they can't avoid Docker entirely for whatever reason): https://github.com/NixOS/nixpkgs/blob/2a036ca1a5eafdaed11be1...You can read more about the Docker image building support here (along with my own rationale for this in the comments): http://lethalman.blogspot.com/2016/04/cheap-docker-images-wi...I'm keeping things simple here and trying to address the most salient "Docker vs Nix" points, though I could continue talking about other strengths of NixOS outside of the scope of Docker/container tech, if desired.Docker's union filesystem approach is great in a world where you can't use a better package manager. For everyone else, there are package managers that obviate the need for such hacks, don't waste space, provide determinism at both runtime and build time, etc.
 these functions' documentation is either buried in a long manualThis is a problem with lots of feature-rich software, even with meticulously-documented APIs. What we need is reverse-indexed documentation. That is, an extensive API reference is only useful for someone who already knows what functions are in the API and just needs to remember how to use them. But even the most thorough API reference does nothing to promote discovering new functionality. This is often left to the authors, who then have to go about writing a User's Guide that gradually explains concepts, idioms, etc. in prose.Thorough User's Guides are rare because they are tough to write, and even tougher to write well. Users don't often have the time to read through potentially hundreds of pages of prose to find what they're looking for. We need a better way to let users search or browse for concepts, and then be given a list of the functions that implement each concept.That is, addition to documentation like: size_t strlen(const char * s); RETURN: Length of string s. size_t strnlen(const char * s, size_t maxlen); RETURN: Length of string s, or maxlen (whichever is smaller). NOTE: Stops reading after maxlen. char * stpcpy(char * dst, const char * src); Copy src to dst. RETURN: pointer to trailing '\0' of dst, or dst[n] if no trailing NUL. NOTE: Undefined behavior if dst and src overlap. char * stpncpy(char * dst, const char * src, size_t len); Copy up to len bytes from src to dst. RETURN: pointer to trailing '\0' of dst, or dst[n] if no trailing NUL. NOTE: Undefined behavior if dst and src overlap. char * strcpy(char * dst, const char * src); Copy src to dst. RETURN: dst. NOTE: Undefined behavior if dst and src overlap. char * strncpy(char * dst, const char * src, size_t len); Copy up to len bytes from src to dst RETURN: dst. NOTE: Undefined behavior if dst and src overlap.  We also need to be able to "tag" functions. So we might have the following tags that allow us to search for concepts: strcpy TAGS: "concept":"data type":"text", "concept":"attribute":"length", ".input":"array", ".input":"char", ".input":"pointer", ".return":"string", ".return":"pointer" strncpy TAGS: "concept":"data type":"text", "concept":"attribute":"length", "concept":"data type":"array":"max-length operator", ".input":"array", ".input":"char", ".input":"pointer", ".return":"array", ".return":"pointer"  And a tag browsing page that looks like concept └─ data type └─ text └─ array (conceptual) └─ max-length operator └─ attribute └─ length / size data structure └─ char └─ array (implementation) └─ pointer  Which the user could then scan, and identify keywords to search for: '"concept":"data type":"text" AND "concept":"attribute":"length"'  And be given "strlen" and "strnlen" as the top two hits, followed by "wcslen" and "wcsnlen".It seems like a PITA at first, but I'm pretty sure tagging functions in their docstrings is easier than writing a whole new User's Guide.
 One great approach is the Hoogle search engine for Haskell [1]. The idea with that is that you search by type, instead of name. So if you were looking for a function to take a item, and return a list with n copies of that item, you would search for a -> Int -> [a], which would give you back replicate.Looks like the Nix expression language is untyped, so this wouldn't work directly, but maybe adding a rough type signature in the docstring would get some of those benefits (and it should be a bit better for discover-ability, since you wouldn't need to guess the same tags/concept the author choose).
 Some Smalltalks (Squeak and Pharo) have a wonderful tool called a "Method Finder".The way it works is you write a sequence of arguments and an expected result, and it suggests a method to call.For example, I just now tried it, entering 3. 4. 7  in the input. It suggested the following methods: 3 + 4 --> 7 3 bitOr: 4 --> 7 3 bitXor: 4 --> 7  Clicking on any of these opens a browser on the class and method concerned.Another example: input of 'hello world'. #('hello' 'world')  yielded the single suggestion 'hello world' substrings --> #('hello' 'world')  Another: ' abc '. 'abc'  yields ' abc ' asLegalSelector --> 'abc' ' abc ' withBlanksTrimmed --> 'abc'  ;;--It's a total hack, of course, but none the less effective or useful for that.It has a list of methods marked "safe to experiment with", and simply tries them out.It gets a big boost from being able to evaluate the receiver (the first in the input list) to a concrete object, and then only consider methods on that object's class.
 I worked with Visual Smalltalk for years and early on I created my own tool which found all methods whose source-code contained a given string or string with wild-cards. It was surprisingly effective because it easily integrated into the Smalltalk browser-windows in general so rather than printing out the set of methods found it opened a list-browser with all the found methods in it, so I could then easily browse for their senders or methods called in them and so on.So how did you know what to search for? A simple case was to look up the ready-built application's GUI which usually always contains some strings. So if you wanted to change something in the system which would result in a change to its GUI just search for source-code with some of the words you saw in the GUI.
 That's pretty cool. Is the technique for this documented somewhere, or do I have to read the Squeak or Pharo source?
 I've looked into it a bit. Visualworks smalltalk documentation gave me an idea[1].In Smalltalk everything is an object, that is including numbers, characters etc. The standar method-lookup searches from the innermost class methods to the outermost class methods.The method finder could simply iteratively go through all applicable methods that return the class requested and match results.[1]: http://esug.org/data/Old/vw-tutorials/vw25/vw25ug.pdf (page 42 method-lookup)
 I don't recall reading about it anywhere, but I did once look at the implementation (it's wonderful having a reflective system where a single click gets you source of anything onscreen), and it's very straightforward but also kind of gross.One neat trick I'd forgotten is that if it doesn't find anything interesting with the inputs in the order written, it permutes them and tries again!
 This just looks like you missing things like classes, namespaces etc. in C. Classes, namespaces etc. are a natural way of making API discoverable (among other things). For example if you want to know how to search for a somthing in a string just look at the methods exposed by string.
 Then you just pass the buck over to classes and namespaces. You have the same fundamental problem in Ruby and Python, perhaps even worse for lack of typed function signatures.
 I think this is a great idea, and something that could hugely improve semi-automated documentation sites, man pages, etc.I also think that you could get a lot of people to agree that it is a great idea, and STILL have a lot of trouble enforcing it in a project without very rigid code review policies and very good linting rules.
 Naive question:Isn't all that also true for Guix?If so, why do your prefer Nix over Guix?
 Guix explicitly rejects non-free software.Unfortunately, that isn't workable for most of us.
 Note you can use any Nix package in Guix...
 Ouch. Is this at a legal or community level?
 Community.There may even be community-based sources for non-free packages, but they are explicitly ignored by the Guix project.
 Anybody can run guix publish however and self publish their own non-free substitutes if they wanted, plus there's all the existing non-free substitute servers around, and you can try your luck with guix import from nixpkgs. The community won't help anybody if they ask for help with non-free software though.I haven't missed any non-free packages since switching to Guix surprisingly, I always seem to find a free alternative though my daily req are pretty basic.
 > plus there's all the existing non-free substitute servers aroundWhere?> The community won't help anybody if they ask for help with non-free software though.This, specifically, is where Nix has the advantage.
 Not the grandparent, but from what i can see, grandparent compares Nix with traditional package managers like dpkg or RPM, rather than Guix.I cannot answer your question, but I think Nix has (for some reason) a lot more publicity than Guix at the moment.
 Guix is derived from Nix, so that might be why.
 If by "derived" you mean that it is another implementation of functional package management, then you are right.But if "derived" implies that Guix is a fork, then you are mistaken.Guix is not a fork of Nix.
 Guix is built on top of the nix daemon, so while it's not strictly a fork, derived seems fair.
 > some rando'sThis is a GNU-approved fork> weakly motivatedHas lots of strong motivation, like a stricter stance on non-free software, the usage of a "real", more expressive language (Guile) instead of a niche, poorly undocumented DSL (Nix), use of GNU Shepherd instead of SystemD for the init system, among other> niche NIH rehashIt shares most of the codebase with Nix, so to say it's NIH is missing the point. Nix improvements are shared with Guix, and Guix improvements are shared with Nix> unless you're already victim to lisp-induced stockholm syndromeDifferent lisp offer different syntaxes, features, and use-cases. That you cannot see it makes me think you didn't try too much, and are probably just trolling.
 Guix doesn't really share any of the codebase with Nix. Guix uses a modified version of the Nix daemon, but that is a tiny fraction of the total source code. Guix is an alternative implementation of the packaging model pioneered by Nix, plus additional features not found in Nix.
 > It shares most of the codebase with Nix, so to say it's NIH is missing the point. Nix improvements are shared with Guix, and Guix improvements are shared with Nix.In Guix, the only code from Nix is the Nix daemon. There is not really much code going back and forth, mostly just bug fixes.
 I'm curious if you'd like to elaborate on what makes Guile more expressive than Nix for writing package definitions.
 I’d just like to interject for a moment. What you’re refering to as Guix, is in fact, Nix/Guile, or as I’ve recently taken to calling it, Nix plus Guile.
 To me, when i look at new distro, i look for how well the repo covers binary packages, i have no time/resource to build compilers/big projects. Last time i checked nix, there aren't that many packages in repo to be usable on laptop.But the package manager itself might be a good idea for dev environments, but all the languages i use provide similar facility(not counting system-library dependencies).
 I'm confused by this statement. nixpkgs contains tens of thousands of packages, the majority of which have binary substitutions via the NixOS Hydra build farm. Usually the only time I build things from source on my NixOS laptop are when I override some package to use a patch of my own design. Hell, when I was using Arch Linux I found myself building things from source _way_ more often than after switching to NixOS.
 I use void-linux and the only thing that i am building from source(aside from language specific pkgs) are emacs-git and st(terminal emulator).At that time, most packages were old version on nixpkgs and some weren't available. I will look into it again, when i have the mood to switch distros.
 I don’t know when you were last looking but for as long as I’ve been using nix (since early 2015) nixpkgs has had definitions of the vast majority of commonly used software, and pre-built binaries of most of those. Definitely worth another look. Also note that you don’t have to switch distros as nix can be plugged into almost any Linux environment without conflicting with whatever else is there.
 I used Arch Linux for a while (~3 years) before making the jump to NixOS.Many things I got from AUR packages are binary-cached in stable Nixpkgs, not to mention "compilers" (GCC, clang, and various versions of GHC in my case). I don't know when you last tried it out, but binary availability isn't a problem now if you'd like to give NixOS a spin. The only thing I build from source is polybar[0].
 I very rarely run into packages that Nix doesn't have prebuilt binaries for.
 That article on "What is Nix and .. " does not contain the words "Nix is a..." A quick read gave a vague sense that it was about installs and file paths so maybe something package-related? Nothing definite.If you click through to https://nixos.org/nixos/nix-pills/why-you-should-give-it-a-t...you will see "Nix is a purely functional package manager and deployment system for POSIX"
 I get the feel that Nix does something like what virtualenv does for python, but more generalized to make that work for other software. Is that approximately right?
 Yes, I also was immediately reminded of Python's conda based environment management. E.g. 'source activate ' may have python3 but when used with will use python2 and different version of other libraries.
 Yes I recommend the nix pills they are really awesome and how I learned Nix!
 My experience with Nix was a real pleasure, and a complete failure.I set out with the goal of building a development environment for a software I was working on. I thought - Nix sounds like a better Docker, where it's possible to choose package versions independently of the rest of the system. It's perfect for testing!I found the package description language refreshing - it was powerful without getting too complicated. Over the course of a couple of days I was able to adapt a few packages and create my own too, with the build environment.It was almost finished, but the last problem remained: installing CUDA and the userspace portion of the Nvidia driver. It's not rocket science – I thought – all I need is a few .so's, it even works with Docker.Alas, after battling Nix for another couple of days, trying to use generic GL, installing the Nvidia one, ignoring it altogether or trying to using the host version - I gave up. I found no way to build a package linked against OpenGL that would actually work.Despite that, I hope to use Nix with a different project in the future.
 Here are some links that might help you to get OpenGL work with nix programs on non-NixOS machines:
 I have used NixOS. It's fustrations led me to develop this.https://github.com/pauldotknopf/darchIt is essentially Docker, but you can boot bare-metal with it. It even uses Docker under the hood.Every boot is a fresh boot. You can read-write during boot, but all changes are made to ram. You mount with fstab things you want persisted, like home.It uses very simply primitives, which makes it easy to use. Squashfs/grub-mkconfig/overlayfs/etc. Docker isn't exactly a "primitive", but it is easily reasoned with.
 I had a similar experience, although in my case the stumbling block was virtualenv. It needed to zip some .py files installed by nix and that totally failed because nix sets mtime to 0 on files it manages. I get why that's a thing they do but zip only allows file times after 1980 or so. NixOS is a really, really interesting project that I will be very interested in using once it's ready for prime time.
 This is very similar to my experience, as well. I tried Nix for over a year. It has excellent ideas and principles. In practice, though, I ran into so many bugs that were near impossible for me to figure out on my own. I personally didn't find the community all that helpful, either. YMMV.
 Hm, I'm using CUDA in production via Nix. When did you attempt this? It may be much easier now than it was before. If there's some particular technicality you need solved- like requiring a specific driver version- I can help.
 Although other people have different opinions to me, I don't really see Nix as something for the desktop, but for development, deployment and server software it's a killer solution for me.
 None of what he mentioned was desktop-specific. GPUs are useful, and if CUDA is involved then it's being used for acceleration of some kind, which can perfectly well be done on servers.I agree that Nix is hard to deal with when it comes to binary distributions of any kind, which includes CUDA.
 > I agree that Nix is hard to deal with when it comes to binary distributions of any kind, which includes CUDA.That's really interesting to me. Why is a binary package not considered a source package where "compiling" it is a no-op?
 It's a problem of altering the embedded paths to point at the nix store. There are some tools for doing that -- patchelf, etc. -- but it's far more difficult to get all that right than to compile from source.A source package using autoconf will, in general, just work. A binary package always needs extra work.
 Extremely happy user of NixOS on my laptop (Dell XPS) for 2.5 years chiming in to say that being able to share parameterized configuration modules between your laptop and your servers is ridiculously nice for a developer and admin!
 Gah! My story is pretty much exactly the same.
 I'm very excited about Nix and the possibilities that it opens.If you want to learn more about Nix, I suggest starting with this excellent article on InfoQ: https://www.infoq.com/articles/configuration-management-with...I also gave a talk about why I think Nix is so great: https://vimeo.com/album/4676161/video/223525975Finally, I highly recommend the PhD thesis that Nix is based on: https://nixos.org/~eelco/pubs/phd-thesis.pdf
 I recently wrote about my experience using NixOS on my VPS [1]; it's truly a very different way of approaching systems administration and Nix is at the heart of it. While I think the Nix expression language has a negative impact on usability, Nix still ends up being a net gain for not only entire OSs, but also reproducible environments for packages on many other OSs.
 Oooh! Thanks for linking this write-up. I've been thinking of playing around with Nix and basically only be able to do it on a VPS.Before I get started though, what things could I consider implicit prerequisites of running Nix? For example: I've never built a Debian or RPM package. Would I be better served gaining some background in OS package management before diving into this?
 Most of what you'd learn playing with other OSs, you'd need to unlrearn to work with Nix. So... nothing much really.Read the Nix Pills series, that'll teach you more than any amount of playing with non-Nix software.
 Thanks!https://nixos.org/nixos/nix-pills/ for others
 No: each package manager had its own strange rules and concepts. I’ve worked with deb packaging, and I wouldn’t say that experience transferred to working on Homebrew or Nix. You might as well start with what you want to use.
 This is good to know, though I continue to be sad that there isn't a general "design principles of package managers" knowledgebase.
 On my macOS work machine, Nix has replaced Homebrew. The ability to switch between generations of your system state [1] when a new install goes awry is underrated, IMO.
 I really think the biggest roadblock is the command line interface[1]. To replace Homebrew you only need like 3 or 4 commands. Right now, that means 3 or 4 different nix commands with weird arguments. The way Nix is currently set up is great and make sense for the OS, but Homebrew has a much simpler use-case (single-user, all user land packages, very low barrier to entry). I can't wait until that ticket is addressed.
 Why not both? Does Homebrew conflict with Nix in such a way that only one is possible at a time?I can definitely see giving Nix priority for work-related development, but I would like to know if Homebrew can still fill in as a backup option.
 I've installed both without issue. It might be a headache long-term because of libs and installing things in both systems, etc. Just make sure you know which comes first in PATH.
 We used Nix to vastly simplify the build process of Simula: https://github.com/SimulaVR/SimulaSimula is a bleeding edge VR Desktop project for Linux; virtually all of its dependencies are highly novel and require building from source for almost any distro. Nix allowed us to reduce the effort to building our project from 1hr of sifting through build documentation to a single build command.Nix's only issue is that it so far can't handle OpenGL dependencies very well. I'm not sure if this is something in principle it cannot handle, or if it just hasn't been done yet. I'm praying it's the latter.
 So, OpenGL is a bit of a weird case.Hardware is the one thing that actually varies between systems no matter how declarative your configuration is - this is normally not a problem, since the kernel abstracts it away.The problem with OpenGL, then, is that every graphics driver provides its own set of OpenGL libraries that is subtly different from all the others. This means that applications need to be built against a specific set of OpenGL libraries from a specific graphics driver, and the kernel is of no help here.That's fundamentally where the OpenGL issues come from; Nix packages typically expect the libraries to be semi-statefully provided in a /run directory. This gets especially hairy when targeting different distros.EDIT: And because the package doesn't know what graphics drivers it'll be running against on non-NixOS, it can't automatically build against a copy of the correct drivers in nixpkgs either.
 I agree that, given this description, it's a hard problem. But can Nix find a way to abstract away these difficulties?There are also bugs. For example, non-NixOS users of Simula are forced to run this script: https://github.com/SimulaVR/Simula/blob/master/swrast.shThis is because a nix package expects to find a driver in /run/opengl-driver, which isn't always present if you're not running NixOS.
 Does the Guix choice of a more expressive language for defining the packages help here?
 No. I think both languages are equally expressive in the end (though one will be a bit uglier than the other). But the problem is probably less big in Guix because only a few graphics drivers are actually supported due to the fact that all the drivers needs to be Free and free of binary blobs.
 > But the problem is probably less big in Guix because only a few graphics drivers are actually supported due to the fact that all the drivers needs to be Free and free of binary blobs.This is a property of Linux libre, not of Guix per se.
 I have recently started looking into Nix to solve the problem of dotfile deployment to new OSX workstations. When you get a new laptop, you clone your dotfiles, maybe symlink them to your home directory -- and then what? Nix solves this problem for me by coupling my dotfile deployment with the installation of the related software.The learning curve has been absolutely tremendous, however. That said, the support on Freenode has been some of the best I've encountered in more than a decade.
 Can you elaborate a bit on how Nix helps you set up your user space?Do you install software with "nix-env -i package" or do you have a declarative way of doing it? If you use nix-env, how is that better than "brew install package"?I'm not doubting your setup, I'm just trying to use nix for the same thing and am having a hard time finding the canonical way of doing a declarative user setup.
 For me the part that I'm saying nix-env -i rather than editing a config file and nix-whatever --read-the-config-file-again isn't really a big deal. It's just a cute tool to author and maintain user environments, I'm sure I could, like, define a single package that just depends on and exposes all the packages I actually want installed and call that my declarative user environment but I'm not sure what that's actually gaining me.Declarative or not, I'm still gonna get the advertised benefits of Nix like, say, having some confidence that I got all the dependencies specified properly if my stuff builds, easily customizing packages by overriding specific bits, and coping with arbitrary version requirements really easily.I'm sure someone who's more used to configuring homebrew has a different perspective there, but it definitely seems preferable to taking over /usr/local and rotating things in and out of there as I switch between projects or w/e.
 Nice. I started using macOS 5 months ago and it felt a bit as a step back coming from Linux.Does Nix work good with macOS?
 I should mention that on High Sierra there’s a bug with kill(-1, ...) that sometimes causes Nix builds to lock up the whole system.
 Also, the OS X windowmanager has a memory leak and you have to resart every so often. Yesterday mine was 22GB and after restart <100MB… Nothing to do with Nix, just venting ;-)
  you have to restart every so often  I've never had that happen. Maybe things that don't have to do with Nix... really just don't have to do with Nix ;-)
 get brew, iterm2, and zsh.
 Already got zsh and brew.Will look into iterm2, thx :)
 Yep
 I recently wrote a blog post about how we use Nix at Pinterest (just the package manager, not the OS). It helps us give all developers and CI an identical environment. On iOS, we run most build commands and other tools through the nix-shell. New engineers set up their environment by just running a script that installs nix and enters the shell.
 If you're using Arch Linux now, you may find this project useful: https://github.com/CyberShadow/aconfmgr
 Can I ask what your UEFI problem was? I run NixOS on a couple MacBook Pros using UEFI with systemd-boot (née gummiboot), and I haven't had any problems yet.
 I'm a big fan of Nix, but I really with there was a declarative way to define a user's environment similar to what NixOS has with /etc/nixos/configuration.nix.It seems a little strange to me to have a functional package manager, but an imperative package install process. I think there are a few projects like NixUP and home-manager that are looking to address this, but I'm hoping Nix will provide an official way to do it.
 It's coming: https://github.com/NixOS/nixpkgs/pull/9250
 That's a bit too strong a statement to make based on a two-year-old still-open PR with an uncertain future. It seems like it might be coming at some point in the future.
 No, there's actually a fair bit of activity around it, if you read through the comments in the pull request it has a fair bit of activity.They recently got a fair bit of interest on the mailing list https://goo.gl/kvNwC1 and raised some money for it as well https://github.com/NixOS/nixpkgs/pull/9250#issuecomment-3208....I'm pretty sure I read somewhere that it's planned to go in the next release.
 I do this without needing any extra tool[0].I basically define a custom meta-package with all the packages I want as dependencies and install it with nix-env -iA.
 Thanks for linking to this! Do you know of a way to get a list of installed packages then? "nix-env -q" lists the meta-package but not the packages installed within. Also, when you update packages, does the update propagate to the sub-packages?
 Yes, nix-env -iA always installs the latest of all the actual packages I have listed there.And as you can see you can also override their config.I don't know how to list installed packages, as I almost never feel like I need to know that (but if you find out how, I'd be happy to know!)
 I'd expect you list installed packages by pointing your text editor at the file where you defined which packages you want your meta-package to pull in, no?
 There's https://github.com/rycee/home-manager I haven't used it yet, but intent to try soon.
 Every problem in computer science can be solved by adding another layer of indirection. Except too many layers of indirection.
 For those new to NixOS, the default package installation method is through a concept called channels. It can be a bit confusing reconciling the nature of channels and the real strength of NixOS which is functional reproducibility. I wrote a blog post explaining what channels really are and an alternative which is to use Git commit hashes instead https://matrix.ai/2017/03/13/intro-to-nix-channels-and-repro...
 I do pretty much that using GNU Stow. Of course I then build packages and libraries on my own, in my \$HOME, because I don't have root access on that machine.I install any PACKAGE of version VERSION in: ~/stow/pkgs/PACKAGE/VERSION/  So taking nim for example, I'd have: ~/stow/pkgs/nim/0.17.1/  Under that, I'd have the whole FHS system for just nim 0.17.1: ~/stow/pkgs/nim/0.17.1/bin/ ~/stow/pkgs/nim/0.17.1/lib/ ~/stow/pkgs/nim/0.17.1/share/  I set ~/stowed/ as my STOW_TARGET. So on running stow, symlinks to all: ~/stow/pkgs/PACKAGE/VERSION/{bin,lib,share,..}/..  get created in: ~/stowed/{bin,lib,share,..}/..  I then have aliases set up to do something like "unstow PKG/OLD_VER" and "restow PKG/NEW_VER" when I want to change the package version.I skip the "restow" step if I just want to "soft uninstall" a package i.e. remove it from PATH, PKG_CONFIG_PATH, MAN_PATH, .. by removing it only from the STOW_TARGET ~/stowed."Hard uninstall" would be simply: \rm -rf ~/stow/pkgs/PACKAGE/VERSION_I_DONT_WANT/  Or even: \rm -rf ~/stow/pkgs/PACKAGE_I_DONT_WANT/
 A copy of what I commented on the blog:Nice post, and I'm glad you're enjoying NixOS!I'm a NixOS contributor/committer, and the principle author (and co-maintainer) of the Bundler-based packaging integration. If you or anyone reading this has any feedback and/or questions about NixOS and Ruby (or NixOS in general) feel free to shoot me a message. I idle on #nixos on Freenode (as cstrahan), and you can email me at charles {{at}} cstrahan.com.Cheers!-Charles Strahan (cstrahan)
 Recently, I got the opportunity to play with Nix. To me, it felt to be a very nice way to bundle the dependencies along with the application. But there are few questions which always come to my mind were - how people run it in production. Can they achieve all the things (eg monitoring, debugging..) easily just like the app hosted on a linux machine ?
 Sure? It’s still Linux underneath and all the same skills and strategies carry over.
 Thank you, I definitely need to play with it more to understand it better.
 RhodeCode is one of projects that build their installer on top of nix package manager. Check out this blog post: https://rhodecode.com/blog/61/rhodecode-and-nix-package-mana...
 what would happen if we want to install, for example, two different versions of ruby at the same time?This is treating the symptom instead of the root cause, that being ineptitude to design backward-compatible software. We as an industry should fight such band aids and take a stand. Yes, designing backwards compatible software is hard, but exactly that is the difference between engineering and amateurism. And if one is getting paid to program, I’m going so far as to argue that it’s one’s job to have their head hurt solving such difficult problems so that users of computers don’t have to.
 Sounds like a similar solution to gentoo's slotted ebuilds [0]. Switching the 'default' implementation system wide or per user (eselect) has the same issues discussed. Not sure if there is an existing utility (beyond your standard shell script) that can produce sane per-shell environments.
 Mhm, doesn't sound all that similar to me. This looks like something that needs to be maintained on a per-package basis as a fairly ad-hoc solution for different library versions, in Nix the whole thing just falls out of the way it's set up in general.
 Gobolinux does something similar, and has been around for years: https://www.gobolinux.org/
 Funnily enough, NixOS has had its initial release in the same year as Gobolinux, 2003.I'm not sure how Gobolinux organizes files exactly, but with NixOS, the hash in /nix/store/-packagename is produced by combining every input that might influence the package. By input I mean for example:- The source: git revision / source url / etc.- All dependencies, which means if a dependency of a dependency of this package changes, it gets a new hash- Build instructions, including build flagsThis wouldn't be possible with a more conventional file structure.
 It "does something similar" in the sense that it doesn't obey the FHS. NixOS is otherwise a pretty radically different approach AFAIK.
 Just a heads-up in case anyone is confused as I was: Nix is not 100% bit-for-bit deterministic/reproducible yet, though they do deliver functional equivalence.
 There are efforts to get deterministic builds in NixOS, but it comes with downsides like very high build times.
 Can you elaborate? I always thought deterministic builds would enable faster builds (because it would basically allow for downloading and verification of binaries).
 As an example, gcc includes code generators that try a few random things in order to optimize code. So two builds, on the same system, won't result in the same byte code.Also, build stamps like time, PID, path etc.
 Nix already does binary substitution. It just has the assumption baked in that builds don't do anything nondeterministic (and the Nix build sandbox removes a lot, but not all, of those opportunities; the ones remaining are things like threads, hence the slowdown).
 Software Collections (https://www.softwarecollections.org/en/) give you the power to build, install, and use multiple versions of software on the same system, without affecting system-wide installed packages. Is this what Nix OS is able to do? Install multiple versions of software and select which version to use before running?
 I have used NixOS. It's fustrations led me to develop this.https://github.com/pauldotknopf/darchIt is essentially Docker, but you can boot bare-metal with it. It even uses Docker under the hood.Every boot is a fresh boot. You can read-write during boot, but all changes are made to ram. You mount with fstab things you want persisted, like home.
 Interesting. Isn't that essentially a livecd? Have you considered using Archiso? If so, what do you see as the advantages of darch?
 Archiso/etc are similar, but that lack some things.---Layering----I can change my inherited build without rebuilding everything.For example: base > xorg-nvidia > plasma > homepc I can easily switch desktop environments by making "homepc" inherit "i3", or w/e.Each layer is essentially a "Dockerfile". If you understand docker, you understand how the images are built and managed.---Fast switching.---I can create images for different dev environemnts/clients. I can create an image purely for gaming. I can create an image steam.Darch integrates with grub, so entries will dynamically show up on boot.---Sharing with DockerHub.---Sharing with other machines (and other people).Since they are docker images, I can easily upload them to DockerHub.I can update my local build by doing "docker pull && darch extract && sudo darch stage".I will soon setup Travis-CI to auto build and push to DockerHub. Then, I never have to build locally. A cron job will queue a build every few days to make my image "rolling". I can easily revert back to previously working docker images (all tagged by date).
 Thanks!
 I'm gonna need a better reason to switch distros than that. I do think that is an improvement that needs to be adopted in the OS. But, I mean, it's not that much of a improvement over containers. I don't feel like it gives me, the user, that much more power over the OS and would be a feature that I would only use very rarely.
 The blogpost just highlights one nice aspect of it, there's more though:- The really powerful NixOS module system, which let's you specify your system declaratively and rather simply: Which programs should be installed, what systemd services should run, use grub for booting, allow this ssh key to login to this user, enable the IPFS daemon, etc. All options (for the 17.09 release) are available here: https://nixos.org/nixos/options.html- System generations: Upon changing an option in your system config, you run nixos-rebuild switch which will build, activate the new system and add it to the system generations. All of these are bootable from your bootloader! So if something breaks miserably, you can just rollback to a previous one that worked. New kernel breaks on your hardware? No problem, just roll back.- If you have a new nixos machine, you don't need to run a bunch of odd commands to have it set up. Since the config is declarative, everything you set up is right there, and all you need is a nixos-rebuild switch to make it work.- Wanna test some configuration but are too afraid to use your machine? Just build a VM with it by doing nixos-rebuild build-vm. Like with everything else with nix, this fetches all dependencies, no need to install them manually.
 Well, you don't have to use NixOS, you can just use NixPkgs either as a way to familiarize yourself or to manage a project--personally, I'm hoping after a few things get fixed I can replace Homebrew with it.Even though containers have had a lot of buzz and tooling built around them in the past few years, it's good to see how other approaches can solve similar problems with different pros and cons.
 That's a bit too strong a statement to make based on a two-year-old still-open PR with an uncertain future. https://socialworldblog.com/
 Is there a way to install nix into home folder (suppose I don't have sudo on server). I spend some time recently trying to setup nix in such environment and failed. I ended up compiling recent versions of neovim and tmux myself.
 Yes and no (mostly yes). Ideally, you have /nix/ where everything gets installed, then folders with symlinks in your homedir (one that builds your workspaces and another that versions them) with an environment variable in your bash_rc to hook you in.You can put that /nix folder anywhere, but you can no longer use their binary package caches and it will recompile everything. This is because they hard-code paths for dependencies during build time.
 If you can use it, https://github.com/lethalman/nix-user-chroot is the best way.But, it depends on user namespaces being enabled on your system. That may not be the case.
 Your best bet is proot or a user+mnt namespace.
 So, it's like virtualenv, but for all software and not just Python?
 Kind of. You can version your workspace, too. Updates are basically atomic. You build the new workspace (with updated versions), then under the hood it just moves a symlink to the new version.It's got some clever fundamentals that allow for really cool (and clean) features because of it.
 Nix is pretty cool but has some significant usability issues.
 Having never used Nix before, I would like to know what kind of usability issues it faces.For me, the biggest one is that I can't use it at clients running a Windows shop. That's a blocker.
 I think biggest ones are i) nix command is a bit complex, but it's getting redesigned [1] & ii) nixpkg definitions sometimes contain a lot of cruft.I've found Guix and GuixSD, which are a GNU-blessed Guile Scheme-based reimplementation of Nix and NixOS, more aesthetically pleasing. Quite simple and elegant in fact.The major differences are that Guix DSLs are implemented on top of Scheme, whereas Nix uses a custom DSL. Furthermore, Guix avoids systemd and uses GNU herd instead.
 One of the major turn-offs for me in regards to Nix was that it uses a ton of bash scripts.Guix's use of Scheme is a lot more elegant and powerful, and a lot less hacky than bash.
 You could use nix the same way guix uses scheme. The lowest level operation in nix is not "run-this-bash-script" but "run- this-executable-with-these-arguments".
 But even still you are mixing languages, so the problem remains. The issue is not that Nix uses Bash, but that Nix uses different languages for the host-side and build-side. AFAIK people aren't writing the build-side code in the Nix language, and I'm not sure if it even has the features necessary to do it. Guix unifies the different layers of code execution with a single language, and using a Lisp enabled that design.For a complete explanation of this design, see the "Code Staging in GNU Guix" paper: https://arxiv.org/abs/1709.00833
 > Nix uses different languages for the host-side and build-side.I'm not sure what you mean by that. Nix packages are Nix expressions.
 He is probably referring to the thing you see when you look into a .drv file, aka the immediate result of evaluating a derivation in nix. That language/datastructure is what nix-build evaluates to actually build things, otherwise the nix language itself is purely functional and cannot really do anything on it's own.I guess in guile/scheme the equivalent data structure happens to be an s-expression. Edit: except the paper actually describes that it's a g-expression.
 Those package expressions have Bash snippets embedded in them that run on the build daemon. The daemon doesn't evaluate Nix code.
 How is that a problem?
 The paper I linked to explains the drawbacks to such a design.
 Guix uses it’s own init system implemented in Scheme: Sheperd (https://www.gnu.org/software/shepherd/)Herd/Hurd is a kernel, not an init system, although since systemd is Linux only, using a different kernel implies using a non-systemd init system.
 Shepherd is not a kernel, Hurd is, and shepherd page mentions a relation, that dmd/shepherd was developped closely to Hurd but it not the same thing.
 Sure, I wrote herd not Hurd!herd is the commandname of Shepherd client:
 Ah — confusing as Herd is the second recursive acronym of Hurd... sorry to pedantic :-)
 Nitpick---but while we're here---Hurd technically refers to the set of (microkernel) servers. The microkernel itself is Mach. In spirit, Mach and the Hurd servers together provide what the Linux kernel provides monolithically.Anyway... :)
 For my practical reasons I can not use pure GNU distributions, I am not aware of easy community way to re use packages for other distro or something hacky like that. Not everyone have brainpower and time to build custom packages for rare distro, it is a shame, I really like Guix. NixOS got some recepies for using not 100% libre software.
 This is also what keeps me away from Guix. I get that there are third-party repos with non-free software, but using a fringe package of a fringe packager is too far for me.There’s no good choice here: Nix package definitions and tools are inscrutable and user-hostile; and the alternative Guix is burden with GNU/free software zealotry and GPL.A somewhat comparable third option is Habitat, from Chef. It also has a pure build system, a package source, and pure, discrete environments. But it’s also got a bunch of service orchestration parts...Hopefully the Nix redesign will make the tools more palatable for mortals.
 What kind of non-free tools are you missing from Guix?The only notable omission is linux, as Guix is based on linux-libre instead. But changing this is a matter of 1 LOC.
 > But changing this is a matter of 1 LOC.And how difficult is it for a new user to find that line?
 Including non-free software in Guix would defeat the goal of a 100% bit-for-bit reproducible distribution. Non-free software is incompatible with Guix both ethically and technically.
 I was told guix has some support for importing normal Nix packages, but I don't know how well it works in practice.
 There are repos around packaging tons of non-free (mainly scientific) software for Guix.
 When will the redesign be merged?It's over a year that I first read about Nix and they talked about the redesign.
 The redesign is merged and available via nix-shell -p nixUnstable. It isn't so much an issue of merging, but calling the new version stable. We're working on it. No definite timetable though.
 Ah, cool!Are there docs for the usage after "nix-shell -p nixUnstable"?
 Discoverability is a problem everywhere in Nix, from configuration options to documentation. Which makes it necessary to learn its weird poorly implemented functional programming language and read code. Then there is performance, it's very slow and uses a lot of memory making it impossible to use on a 512 MB vm, for example.If you just want a solution for your packaging management needs - Nix is definitely not it. Nix is more like a thing to get inspired by to make a package manager.
 > Then there is performance, it's very slow and uses a lot of memory making it impossible to use on a 512 MB vm, for example.No, this is just a side effect of the CLI user experience being garbage.nix-env -i  is almost never what you want, because its semantics are to evaluate everything in nixpkgs, find the set of packages whose name attribute is matched by the given regex, and install all of the packages in that set modulo the equivalence relation generated by package name equality ignoring version numbers.Instead, you should use nix-env -iA ., where  is the name of a Nix channel (viewable via nix-channel --list, usually it is nixos or nixpkgs) and  is a valid attribute path in the nixpkgs package set (these can be discovered by running nix-repl '' and tab-completing).
 That's nice to hear you say, because I am making a package manager, and I find nix inspiring :pI keep trying to convince myself that someone's already done it better, and there's no point, but then every solution I look at doesn't seem to be good enough.
 Agreed, it’s an area where nothing is quite there. Take a look at Habitat - another not quite there option, but one with interesting ideas.
 What's the downside of Habitat?
 I don’t know anyone using it.
 It apparently works in WSL [1], so Windows needn't be an issue.
 Do you use Windows 10 Creators Update on production? It needs to work on Windows Server 2012 or no dice. Maybe Nix will be an option in 5 years when companies upgrade their servers, but that's not an option now.
 You could say the same thing about Windows: Windows just isn’t an option yet.... maybe in 5 years when WSL is performant and MSFT has open-sourced enough to not be a threat to more cautious companies.
 No, I don't think you can say that. The point is that I have clients that use linux, clients that use windows, and clients that use both windows and linux which need to talk to each other. I need a solution that can factor out the operating system into a module and build packages that will work for both the quants and the servers. I don't get to tell my clients what operating systems to use. I must provide solutions that work on whatever they're running.
 Nix has facilities for creating Docker and Singularity containers from a nix expression, which lets you package up arbitrary environments. Does that satisfy your use-case?
 Primarily from my perspective... the entire package repo acts as one enormous program. Which is both good and bad. Its not that easy imo to create ad hoc packages or packaging scripts
 I strongly disagree. Creating a Nix package is significantly easier than creating, e.g.: an Arch package, from my experience. packageOverrides is really nice too.
 Try packaging a postgres extension :-)
 If you tell me which specific piece of software you tried to package, I can probably explain what is going on. I strongly suspect that it is either not Nix's fault, or an inherent tradeoff in packaging software (i.e.: not a design flaw, but simply a result of the correctness of package expressions being more tightly controlled in Nix than in other languages). The main exception to that statement that I've seen are cases where Nix works fine, but the Nix expression takes so long to build that iterating on it is very difficult. Luckily, there is a solution for that in the pipeline: "recursive Nix", which allows nix-build to be called _inside_ a Nix build sandbox, thus allowing safe memoization of things like gcc.
 What's the status of recursive nix / people's thinking about recursive nix?
 * is pretty cool but has some issues.
 Nix the package manager is great. Poorly documented, but it works as expected. I've also had uneventful experiences using NixOS on a server.On the other hand, trying to use NixOS on my laptop has been struggle after struggle. Every update breaks something. Many times updates cause the entire system to crash. Different combinations of display managers, window managers, and various system level daemons interact in complex ways.None of this is the fault of NixOS, really it is the fault of the Unix philosophy scaled to the level of the desktop Linux ecosystem, combined with the traditional assurance on upstream developers that packagers in distros like Ubuntu will fix their shit.What would be really great for NixOS would be a set of various well tested base configurations for the various DE/WM combos, like all the spinoff Ubuntu distros. These would fix the versions of all the fragile graphical components on some kind of release schedule, while probably still using nixos-unstable underneath for all the relatively reliable stuff like the kernel, emacs, vim, coreutils, etc.
 Yes, this is something that I think is really important in the future. NixOS really needs something like Ubuntu is to Debian or Manjaro is to Arch. Lots of polishing that a standard Linux user can start using out of the box (no instructions required).
 Python solves this problem with "virtualenv", where the user creates a virtual environment and installs all programs and libraries into that environment. The user can have multiple virtual environments, and it is easy to switch between environments.
 virtualenv solves virtual environment as much as pip solves OS package management. Not that it's not useful, but you see all over where you have little fiefdoms that work pretty well for their little ecosystem, but become a mess if you integrate stuff outside (virtualenv, rbenv or pip, npm, gem, rpm, apt or make, ant, scons, jam).A lot of these systems are just reimplementations tailored to language-X. Nix is pretty unique and clever. For example, you can effectively version control you virtual environment, it's at the OS level, and accommodates major languages and libraries (Python, Perl, Lua, Java, Go, Qt).
 Up to a point. You can't install the c (etc) compiler in the venv, so you end up with some dependencies on the external system.
 Every language has it's equivalent of virtualenv, and that's the problem: it only works for that language's tools and libraries. I don't use Nix, but I do hack on an alternative called GNU Guix sometimes, and I wrote a tool called 'guix environment' which is similar to virtualenv but applicable to any software. Having a generalized solution is much better than one virtualenv tool and package manager per programming language. In Nix the equivalent tool is called nix-shell.
 venv doesn't even handle environment variables. Some environment that is :p
 "To deal with this nix provides the nix-shell utility which constructs an environment on demand and runs a new shell based on that environment."I'm sure nix is cool but this sort of sounds like something we just end up using docker for these days (for better or worse).
 Yes, Docker is a competing solution. Hopefully in the future we will see a better one, more nix-like.
 Does Docker actually compete with Nix?It seems that Docker is more concerned with containment and Nix with packages. I would love to be able to use Nix to define my project+dependencies and Docker to run it.I'd be surprised if someone hasn't already made a baseline NixOS docker image to build off of.

Applications are open for YC Summer 2019

Search:


text:
If the constant term in the binomial expansion of (x^(2)-(1)/(x))^ | Filo

Class 12

Math

Algebra

Binomial Theorem

580
150

If the constant term in the binomial expansion of , is then the value of is equal to

580
150

Connecting you to a tutor in 60 seconds.

format: plain


text:
Simple Bus Network simulation

I am simulating a simple bus network (as shown in the picture) using event simulation. There are two buses running (starting at 1 and 4) and the travel time between nodes is 10 units. For now, I used the switch-cases to manage the event. However, if I need to expand the network, it might be very confusing to manage all the events with switch-cases technique.

Is there any solution to improve this code?

#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <queue>
#include <time.h>
#include <functional>
#include <vector>
#include <algorithm>

using namespace std;

double Clock, Travel_time_bw_block;

class Event
{

public:

enum EvtType {arrival_1, arrival_2, arrival_3, arrival_4, arrival_5, arrival_6};

Event(EvtType type = arrival_1, int bus_no = 0, double etime = 0.0):
_type(type),_bus_no(bus_no), _etime(etime) {}

EvtType get_type() const
{
return _type;
}
double get_bus_no() const
{
return _bus_no;
}
double get_time() const
{
return _etime;
}

protected:
EvtType _type;
int _bus_no;
double _etime;
};

struct EventLess
{
bool operator()(const Event& lhs, const Event& rhs) const
{
return (lhs.get_time() > rhs.get_time());
}
};

priority_queue <Event, vector<Event>, EventLess> FutureEventList;

void Initialization()
{
// initialize global variables
Clock = 0.0;

Travel_time_bw_block = 10.0;

Event evt1(Event::arrival_1, 1, 0.0);
Event evt2(Event::arrival_4, 2, 0.0);

FutureEventList.push(evt1);
FutureEventList.push(evt2);
}

int main(){

int Simulation_Time = 200;
Initialization();

while(Clock < Simulation_Time){

Event evt = FutureEventList.top();

FutureEventList.pop();
Clock = evt.get_time();

switch(evt.get_type()){

case Event::arrival_1:
{
cout << "bus " << evt.get_bus_no() << " arriving block 1 at: " << Clock << endl;
Event enter_1 = Event(Event::arrival_2, evt.get_bus_no(), Clock + Travel_time_bw_block);
FutureEventList.push(enter_1);
break;
}
case Event::arrival_2:
{
cout << "bus " << evt.get_bus_no() << " arriving block 2 at: " << Clock << endl;
Event enter_2 = Event(Event::arrival_3, evt.get_bus_no(), Clock + Travel_time_bw_block);
FutureEventList.push(enter_2);
break;
}
case Event::arrival_3:
{
cout << "bus " << evt.get_bus_no() << " arriving block 3 at: " << Clock << endl;
Event enter_3 = Event(Event::arrival_4, evt.get_bus_no(), Clock + Travel_time_bw_block);
FutureEventList.push(enter_3);
break;
}

case Event::arrival_4:
{
cout << "bus " << evt.get_bus_no() << " arriving block 4 at: " << Clock << endl;
Event enter_4 = Event(Event::arrival_5, evt.get_bus_no(), Clock + Travel_time_bw_block);
FutureEventList.push(enter_4);
break;
}

case Event::arrival_5:
{
cout << "bus " << evt.get_bus_no() << " arriving block 5 at: " << Clock << endl;
Event enter_5 = Event(Event::arrival_6, evt.get_bus_no(), Clock + Travel_time_bw_block);
FutureEventList.push(enter_5);
break;
}

case Event::arrival_6:
{
cout << "bus " << evt.get_bus_no() << " arriving block 6 at: " << Clock << endl;
Event enter_6 = Event(Event::arrival_1, evt.get_bus_no(), Clock + Travel_time_bw_block);
FutureEventList.push(enter_6);
break;
}

}
}
}

• If you have a long switch statement, replace it with a std::map. Simply you can reduce the size of your code. And your code will be more cleaner. – Tharindu Kumara Dec 20 '16 at 17:54

Don't abuse using namespace std

Putting using namespace std at the top of every program is a bad habit that you'd do well to avoid.

Avoid the use of global variables

I see that Clock is used only within main (and Initialization) but it's declared as s global variable. It's generally better to explicitly pass variables your function will need or declare them within the appropriately smallest possible scope rather than using the vague implicit linkage of a global variable. I'd recommend gathering these into a BusSim class instead.

Use standard templates

The priority queue is currently declared like this:

priority_queue <Event, vector<Event>, EventLess> FutureEventList;

This is very strange for several reasons. First EventLess is defined as a struct:

struct EventLess
{
bool operator()(const Event& lhs, const Event& rhs) const
{
return (lhs.get_time() > rhs.get_time());
}
};

Second, it has "less" in the name but uses ">" in the code. It would be an understatement to describe this as counterintuitive! Instead, I'd recommend creating a more typical operator function for the Event class:

bool operator>(const Event& lhs, const Event& rhs)
{
return lhs.get_time() > rhs.get_time();
}

Then declare the priority_queue like this:

std::priority_queue <Event, std::vector<Event>, std::greater<Event> > FutureEventList;

Don't use std::endl if you don't really need it

The difference betweeen std::endl and '\n' is that '\n' just emits a newline character, while std::endl actually flushes the stream. This can be time-consuming in a program with a lot of I/O and is rarely actually needed. It's best to only use std::endl when you have some good reason to flush the stream and it's not very often needed for simple programs such as this one. Avoiding the habit of using std::endl when '\n' will do will pay dividends in the future as you write more complex programs with more I/O and where performance needs to be maximized.

Use only required #includes

The code has a number of #includes that are not needed. This clutters the code and makes it more difficult to read and understand. Only include files that are actually needed. In this code, I believe these are the only ones required:

#include <iostream>
#include <queue>
#include <functional>
#include <vector>

Your comment about this design being confusing to manage is likely to be true the way it's currently written. Instead, I think I'd design things a little differently. In particular, I think I'd have a Bus object for each bus. Each Bus would contain its own collection of BusStops. Then I would have the whole thing encapsulated in a BusSim class. If that is done, the main could look like this:
int main(){


text:
# Why do I get different heteroscedasticity robust standard errors in R when using the plm package?

I am now writing my bachelors thesis and I have come across some difficulties. I am about to do some panel regressions with time and entity fixed effects and I would therefore like to use the plm package. But when I do add fixed effects and want to have heteroscedasticity robust standard errors they seem to be incorrect.

Does anyone know why the HC standard errors differ?

Here is my code

# Load data
attach(panel)

library(lmtest)
library(plm)

# Create two models. The lm.model is a linear model and as the
# LAND variable is a factor variable representing countries
# (Land = Country in Swedish) this model will have entity fixed
# effects. In the plm.model the plm package is used and
# individual effects and within model is turned on (which is
# the same as entity fixed effects)
lm.model<-lm(NETTOSPARANDE ~ EURO + LAND, data=panel)
plm.model<-plm(NETTOSPARANDE ~ EURO, index=c("LAND","ÅR"), effect="individual", model="within", data=panel)

# When looking at the coefficents without heteroscadisity robust
# standard errors they are identical. They do also have the same
# value in stata.
coeftest(lm.model)[1:2,]
coeftest(plm.model)

# But when looking at the coefficents using heteroscadisity
# robust standard errors the lm.model and the plm.model produces
# different standard errors.
coeftest(lm.model, vcov.=vcovHC(lm.model, method="white2", type="HC1"))[1:2,]
coeftest(plm.model, vcov.=vcovHC(plm.model, method="white2", type="HC1"))

If you want to test the data it can be found here (the panel file) [1]: https://sourceforge.net/projects/emumoralhazard/files/ R-data

And here is my output

1> # Load data

1> attach(panel)

1> library(lmtest)

1> library(plm)

1> # Create two models. The lm.model is a linear model and as the
1> # LAND variabel is a factor variable representing countries
1> # (Land = Country in swedish) this model will have entity fixed
1> # effects. In the plm.model the plm package is used and
1> # individual effects and within model is turned on (which is
1> # the same as entity fixed effects)
1> lm.model<-lm(NETTOSPARANDE ~ EURO + LAND, data=panel)

1> plm.model<-plm(NETTOSPARANDE ~ EURO, index=c("LAND","ÅR"), effect="individual", model="within", data=panel)

1> # When looking at the coefficients without heteroscedasticity robust
1> # standard errors they are identical. They do also have the same
1> # value in Stata.
1> coeftest(lm.model)[1:2,]
Estimate Std. Error   t value     Pr(>|t|)
(Intercept) -3.731024  0.7731778 -4.825570 1.726921e-06
EURO1        2.187170  0.4076720  5.365024 1.112984e-07

1> coeftest(plm.model)

t test of coefficients:

Estimate Std. Error t value  Pr(>|t|)
EURO1  2.18717    0.40767   5.365 1.113e-07 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

1> # But when looking at the coefficients using heteroscedasticity
1> # robust standard errors the lm.model and the plm.model produces
1> # different standard errors.
1> coeftest(lm.model, vcov.=vcovHC(lm.model, method="white2", type="HC1"))[1:2,]
Estimate Std. Error    t value     Pr(>|t|)
(Intercept) -3.731024  0.3551280 -10.506138 5.102122e-24
EURO1        2.187170  0.3386029   6.459395 2.009894e-10

1> coeftest(plm.model, vcov.=vcovHC(plm.model, method="white2", type="HC1"))

t test of coefficients:

Estimate Std. Error t value  Pr(>|t|)
EURO1  2.18717    0.33849  6.4615 1.983e-10 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Though numerically both of your model coefficients estimates coincide, you are actually fitting two different models: least square dummy variables and fixed effects. They differ on their assumptions, so the robust standard errors are calculated differently.

Function vcovHC is a wrapper function, different functions are actually used in case of lm model and plm. In the first case the function vcovHC comes from the sandwich package, in the second from the plm package.

The difference in results arises because vcovHC for lm object does not exploit panel data structure. Comparing

plm:::vcovHC.plm

and

vcovHC.default

reveals that for panel data there is additional argument cluster = c("group", "time").

Look into Wooldridge book for more explanation why least squares dummy variables and fixed effects regressions differ. It has whole chapter dedicated for that.

• Thank you for the answear. But is the first model pooled? I have added the LAND term wich is the entity dummy variable (as it's a facor variable. And as I can se the parameter estimates (EURO) are identical? – Skolnick Jan 10 '11 at 22:27
• @Skolnick, I've missed that at first, so I changed my answer accordingly – mpiktas Jan 10 '11 at 22:31
• I have tried to get reach of that book but the library has a copy that's not available for the moment. But I can perhaps ask which model that has the most accurate standard errors when HC-robust, LSDV or within? – Skolnick Jan 19 '11 at 9:32

@Skolnick - After an admittedly quick look at your problem, it seems that plm() truncates and/or rounds results to less digits than lm(). I think this is the most likely cause of the differences in your heteroscedasticity-robust standard error estimates. Explore summary(plm.model) and summary(lm.model) for differences in residual quantiles.


text:
## v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} Normal 0 false false false false EN-US X-NONE X-NONE /* St

v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} Normal 0 false false false false EN-US X-NONE X-NONE /* Style Definitions */ table.MsoNormalTable {mso-style-name:”Table Normal”; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-parent:””; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin:0in; line-height:115%; mso-pagination:widow-orphan; font-size:11.0pt; font-family:”Arial”,sans-serif; mso-ansi-language:EN-GB;} A: For each equation:

1. Solve for  in terms of .                                                                                (4)
2. Find the value of the ratio                                                                                (4)
3. Write the ratio  in decimal form, correct to three decimal places where possible.  (4)

B: For each pair of simultaneous equations:

and

and

1. Solve for  and                                                                                (3)
2. Find the ratio .                                                                                (4)
3. Write the ratio  in decimal form correct to three decimal places where possible. (1)

You may have noticed that the numbers 1, 2, 5, 8 and 13 have appeared as solutions in Task 1. These numbers form a sequence called the Fibonacci sequence.  In the Fibonacci sequence each number after the second term is the sum of the two before it. The table shows the first eight terms of the sequence (T1=term 1)

T1

T2

T3

T4

T5

T6

T7

T8

1

1

2

3

5

8

13

21

1. Write down the next three terms of the sequence.                                                (3)
2. Find a new sequence by finding the ratio.

up to                                                                                (2)

1. Find the ratios in Question 2 correct to three decimal places.                               (2)
2. Describe what you notice?                                                                                (1)

We can generate a sequence of numbers by continued square roots:

1. Use a calculator (or Excel) to find the first ten terms of this sequence for .    Give your answers correct to four decimal places.

Calculator tip:

For T1 press ; for T2 press ; for T3 press  and so on, for each successive term.

Write down each term’s value in a table.                                                                   (2)

1. Find the first 11 terms of the same sequence for  and .

Record these values in the same table.                                                                     (4)

1. Describe what you notice about the values of the terms.                                          (2)

We have seen the number 1,618 (1,61803398 to be more accurate), in three different situations

●     the ratio of the terms of the Fibonacci sequence

●     continued square roots

●     continued fractions.

This number is called ‘phi’ or .  It is an important number and is also called the Golden ratio.  has many special properties.  Let

1. Write down the value of                                                                            (1)
2. What do you notice?                                                                                (2)
3. Use the fact that  to solve for  and show that .          (3)

The Golden rectangle is a rectangle in which the ratio of the sides is  of approximately 1,618.

Throughout the ages this ratio has been recognised as aesthetically pleasing.  Many buildings and works of art have the Golden rectangle in them.  Two examples are the Parthenon in Greece and the United Nations building in New York, where the ratio of the width of the buildings compared with the height of every ten floors is the Golden ratio.

Rectangle 1 has sides  and  with the ratio of length to breadth of

Rectangle 2 is formed by creating a square of length  on the one side of Rectangle 1.  The remaining Rectangle 2 has sides of length and  with the ratio of length to breadth of ..  If the two rectangles have the same ratio of length to breadth, then they are Golden rectangles.  In other words .

1. Show that the equation is the same as                                      (2)
2. If , solve for  in the equation. Leave your answer in surd form.

(Why can we discard one of the values of ?)                                                         (3)


text:
# Python floats and other unusual things spotted in mpmath

September 10, 2009

I’ve just put up a branch (named “mp4″) containing changes to mpmath that I’ve been working on for several days now. This branch includes some rather large changes, including support for fixed-precision (machine-precision) arithmetic, and a new implementation of the multiprecision type. The code is a bit rough at the moment, and not all changes are final, so don’t expect this in a release in the immediate future.

#### New mpf implementation

The mp4 branch uses a new mpf type that handles both real and complex values. It makes complex arithmetic quite a bit faster (up to twice the speed), although real arithmetic is a little slower. Some of the slowdown is due to wrapping old-format functions instead of providing new ones, so there is a bit of unnecessary overhead. The biggest advantage is not that the implementation becomes faster, but that it becomes simpler. For example, a nice feature is that complex calculations that yield real results don’t need to be converted back to a real type manually. Unfortunately, writing code that also supports Python float and complex (see below) somewhat reduce the usefulness of such features.

Imaginary infinities are a little more well-behaved (i.e. j*(j*inf) gives -inf and not a complex NaN), and the representation is flexible enough that it might be possible to support unsigned infinities, infinities with an arbitrary complex sign, and possibly even zero with an arbitrary complex sign — hey, perhaps infinities and zeros with order and residue information attached to them so you can evaluate gamma(-3)**2 / gamma(-5) / gamma(-2) directly? (Well, I’m not sure if this is actually possible, and if it is, it’s probably way overkill :-)

This new implementation will not necessarily make it — it depends on whether the pros outweigh the cons. I would very much appreciate review by others. Regardless of the outcome, writing it has been very useful for identifying and fixing problems in the interface between “low level” and “high level” code in mpmath.

This should particularly simplify the future support for a C or Cython-based backend. In fact, the current fixed-precision backend (see below) only uses about 200 lines of code — and although it’s not complete yet, it handles a large set of calculations. Adding a fast multiprecision backend based on Sage or GMPY can probably be done in an evening now. I’m not going to do such a thing right now, as I want to fix up the existing code before adding anything new; should someone else be interested though, then by all means go ahead.

I’ve also inserted a few other optimizations. As noted before on this blog, many of the special functions in mpmath are evaluated as linear combinations of hypergeometric series. All those functions basically fall back to a single routine which sums hypergeometric series. The mp4 branch contains a new implementation of this routine that is up to about twice as fast as before. The speed is achieved by code generation: for every different “type” (degree, parameter types) of hypergeometric series, a specialized version is generated with various bookkeeping done in advance so it doesn’t have to be repeated in every iteration of the inner loop.

As an example, the following runs at 1.7x the speed:

>>> 1/timing(mpmath.hyp1f1, 1.5, 2.2, 1.35)5620.8844813722862>>> 1/timing(mp4.hyp1f1, 1.5, 2.2, 1.35)9653.1737629459149

Nearly all tests pass with the new mpf type used instead of the old one — the only significant missing piece is interval arithmetic.

#### Fixed-precision arithmetic

Several people have requested support for working with regular Python floats and complexes in mpmath. Often you only need a few digits of accuracy, and mpmath’s multiprecision arithmetic is unnecessarily slow. Many (though not all) of the algorithms in mpmath work well in fixed precision; the main problem with supporting this feature has been that of providing an appropriate interface that avoids cluttering the code.

In the mp4 branch, this is solved by adding a fixed-precision context. This context uses the same “high-level” methods for special functions, calculus, linear algebra, etc, as the multiprecision context, while low-level functions are replaced with fixed-precision versions. For example exp is just a wrapper around math.exp and cmath.exp.

While the default multiprecision context instance is called mp, the default fixed-precision context instance is called fp. So:

>>> from mp4 import mp, fp>>> mp.pretty = True>>> mp.sqrt(-5); type(_)2.23606797749979j<class 'mp4.ctx_mp.mpf'>>>> fp.sqrt(-5); type(_)2.2360679774997898j<type 'complex'>

The fixed-precision context is still missing a lot of low-level functions, so many things don’t work yet. Let’s try a couple of calculations that do work and see how they compare.

##### Lambert W function

The Lambert W function was the first nontrivial function I tried to get working, since it’s very useful in fixed precision and its calculation only requires simple functions. The lambertw method is the same for mp as for fp; the latter just uses float or complex for the arithmetic.

>>> mp.lambertw(7.5)1.56623095378239>>> mp.lambertw(3+4j)(1.28156180612378 + 0.533095222020971j)>>> fp.lambertw(7.5)1.5662309537823875>>> fp.lambertw(3+4j)(1.2815618061237759+0.53309522202097104j)

The fixed-precision results are very accurate, which is not surprising since the Lambert W function is implemented using a “self-correcting” convergent iteration. In fact, the multiprecision implementation could be sped up by using the fixed-precision version to generate the initial value. The speed difference is quite striking:

>>> 1/timing(mp.lambertw, 7.5)1249.5319808144905>>> 1/timing(mp.lambertw, 3+4j)603.49697841726618>>> 1/timing(fp.lambertw, 7.5)36095.559380378654>>> 1/timing(fp.lambertw, 3+4j)20281.934235976787

Both the real and complex versions are about 30x faster in fixed precision.

##### Hurwitz zeta function

The Hurwitz zeta function is implemented mainly using Euler-Maclaurin summation. The main ingredients are Bernoulli numbers and the powers in the truncated L-series. Bernoulli numbers are cached, and can be computed relatively quickly to begin with, so they’re not much to worry about. In fact, I implemented fixed-precision Bernoulli numbers by wrapping the arbitrary-precision routine for them, so they are available to full 53-bit accuracy. As it turns out, the fixed-precision evaluation achieves nearly full accuracy:

>>> mp.hurwitz(3.5, 2.25); fp.hurwitz(3.5, 2.25)0.08901224249238890.089012242492388816>>> t1=timing(mp.hurwitz,3.5,2.25); t2=timing(fp.hurwitz,3.5,2.25); 1/t1; 1/t2; t1/t2473.665047995482787008.026733500417314.7953216374269

There is a nice 15x speedup, and it gets even better if we try complex values. Let’s evaluate the the zeta function on the critical line 0.5+ti for increasing values of t:

>>> s=0.5+10j>>> mp.hurwitz(s); fp.hurwitz(s)(1.54489522029675 - 0.115336465271273j)(1.5448952202967554-0.11533646527127067j)>>> t1=timing(mp.hurwitz,s); t2=timing(fp.hurwitz,s); 1/t1; 1/t2; t1/t2213.378915987505484391.481520259658320.580672180923461>>> s=0.5+1000j>>> mp.hurwitz(s); fp.hurwitz(s)(0.356334367194396 + 0.931997831232994j)(0.35633436719476846+0.93199783123336344j)>>> t1=timing(mp.hurwitz,s); t2=timing(fp.hurwitz,s); 1/t1; 1/t2; t1/t28.1703453931669383352.5484361735212843.149759185011469>>> s = 0.5+100000j>>> mp.hurwitz(s); fp.hurwitz(s)(1.07303201485775 + 5.7808485443635j)(1.0730320148426455+5.7808485443942352j)>>> t1=timing(mp.hurwitz,s); t2=timing(fp.hurwitz,s); 1/t1; 1/t2; t1/t20.171252084559244439.275493595640789154.162806949260492

It’s definitely possible to go up to slightly larger heights still. The Euler-Maclaurin truncation in the Hurwitz zeta implementation is not really tuned, and certainly has not been tuned for fixed precision, so the speed can probably be improved.

##### Hypergeometric functions

Implementing hypergeometric series in fixed precision was trivial. That the multi-precision implementation is actually quite fast can be seen by comparing direct evaluations:

>>> mp.hyp1f1(2.5, 1.2, -4.5)-0.0164674858506064>>> fp.hyp1f1(2.5, 1.2, -4.5)-0.016467485850591584>>> 1/timing(mp.hyp1f1, 2.5, 1.2, -4.5)6707.6667199744124>>> 1/timing(fp.hyp1f1, 2.5, 1.2, -4.5)12049.135305946565

The float version is only about twice as fast. Unfortunately, hypergeometric series suffer from catastrophic cancellation in fixed precision, as can be seen by trying a larger argument:

>>> mp.hyp1f1(2.5, 1.2, -30.5)6.62762709628679e-5>>> fp.hyp1f1(2.5, 1.2, -30.5)-0.012819333651375751

Potentially, checks could be added so that the fixed-precision series raises an exception or falls back to arbitrary-precision arithmetic internally when catastrophic cancellation occurs. However, it turns out that this evaluation works for even larger arguments when the numerically stable asymptotic series kicks in:

>>> mp.hyp1f1(2.5, 1.2, -300.5)1.79669541078302e-7>>> fp.hyp1f1(2.5, 1.2, -300.5+0j)1.7966954107830195e-07

The reason I used a complex argument is that the asymptotic series uses complex arithmetic internally, and Python has an annoying habit of raising exceptions when performing complex-valued operations involving floats (a proper workaround will have to be added). In this case the speedup is close to an order of magnitude:

>>> 1/timing(mp.hyp1f1, 2.5, 1.2, -300.5)532.36666412814452>>> 1/timing(fp.hyp1f1, 2.5, 1.2, -300.5+0j)4629.4746136865342

Another example, a Bessel function. This function is calculated using a hypergeometric series and also a couple of additional factors, so the speedup is quite large:

>>> mp.besselk(2.5, 7.5)0.000367862846522012>>> fp.besselk(2.5, 7.5)0.00036786284652201188>>> 1/timing(mp.besselk, 2.5, 7.5)3410.5578142787444>>> 1/timing(fp.besselk, 2.5, 7.5)21879.520083463747

The fixed-precision context does not yet handle cancellation of singularities in hypergeometric functions. This can be implemented as in the multiprecision case by perturbing values, although accuracy will be quite low (at best 5-6 digits; sometimes an accurate result will be impossible to obtain).

##### Numerical calculus

Root-finding works, as does numerical integration, with nice speedups:

>>> fp.quad(lambda x: fp.cos(x), [2, 5])-1.8682217014888205>>> mp.quad(lambda x: mp.cos(x), [2, 5])-1.86822170148882>>> 1/timing(fp.quad, lambda x: fp.cos(x), [2, 5])1368.3622602114056>>> 1/timing(mp.quad, lambda x: mp.cos(x), [2, 5])55.480651962846274>>> fp.findroot(lambda x: fp.cos(x), 2)1.5707963267948966>>> mp.findroot(lambda x: mp.cos(x), 2)1.5707963267949>>> 1/timing(fp.findroot, lambda x: fp.cos(x), 2)19160.822293284604>>> 1/timing(mp.findroot, lambda x: mp.cos(x), 2)1039.4805452292442

The tests above use well-behaved object functions; some corner cases are likely fragile at this point. I also know, without having tried, that many other calculus functions utterly don’t work in fixed precision (not by algorithm, nor by implementation). Some work will be needed to support them even partially. At minimum, several functions will have to be changed to use an epsilon of 10-5 or so since full 15-16-digit accuracy requires extra working precision which just isn’t available.

##### Plotting

The plot methods work, and are of course way faster in fixed-precision mode. For your enjoyment, here is the gamma function in high resolution; the following image took only a few seconds to generate:

>>> fp.cplot(fp.gamma, points=400000)

With the default number of points (fp.cplot(fp.gamma)), it’s of course instantaneous.


text:
Browse Questions

# The number of octahedral and tetrahedral holes respectively present in a hexagonal close packed (hcp) crystal of 'X' atoms are :

$(a)\;X,2X \quad (b)\;X,X \quad (c)\;2X,X \quad (d)\;2X,2X$

(b) X,X


text:
Many random experiments that we carry have only two outcomes that are either failure or success. For example, a product can be defective or non-defective, etc. These types of independent trials which have only two possible outcomes are known as Bernoulli trials.

For the trials to be categorized as Bernoulli trials it must satisfy these conditions:

1. A number of trials should be finite.
2. The trials must be independent.
3. Each trial should have exactly two outcomes: success or failure.
4. The probability of success or failure remains does not change for each trial.

Example of Bernoulli Trials: Eight balls are drawn from a bag containing 10 white and 10 black balls. Predict whether the trials are Bernoulli trials, if the ball drawn are replaced and not replaced.

Solution:

(a) For the first case, when a ball is drawn with replacement, the probability of success (say, white ball) is $$p=\frac{10}{20}=\frac{1}{2}$$ which is same for all eight trials (draws). Hence, the trial involving drawing of balls with replacements are said to be Bernoulli trials.

(b) For the second case, when a ball is drawn without replacement, the probability of success (say, white ball) varies with number of trials. For example for first trial, probability of success, $$p=\frac{10}{20}$$ for second trial, probability of success, $$p=\frac{9}{19}$$ which is not equal the first trial. Hence, the trials involving drawing of balls without replacements are not Bernoulli trials.

### Binomial Distribution

Consider three Bernoulli trials for tossing a coin. Let obtaining head stand for success, S and tails for failure, F. There are three ways in which we can have one success in three trials, {SFF, FSF, FFS}. Similarly, two successes and one failure will have three ways. The general formula can be seen as $$^nC_r$$. Where ‘n’ stands for number of trials and ‘r’ stands for number of success or failures.

The number of success for above cases can take four values 0,1,2,3.

Let ‘a’ denote the probability of success and ‘b’ denote the probability of failure. Random variable $$\small X$$ denoting success can be given as:

$$\small P(X=0)=P({FFF})=P(F)\times P(F)\times P(F)$$

= $$\small b\times b \times b=b^3$$

$$\small P(X=1)=P({SFF, FSF, FFS})$$ $$\small = P(S)\times P(F)\times P(F)+P(F)×P(S)\times P(F)+P(F)\times P(F)\times P(S)$$ $$\small a\times b \times b+b \times a \times b+b \times b \times a =3ab^2$$

$$\small P(X=2)=P({SSF, SFS, FSS})$$ $$\small =P(S)\times P(S)\times P(F)+P(S)\times P(F)\times P(S)+P(F)\times P(S)\times P(S)$$ $$\small a\times a \times b+b \times a \times b+b \times b \times a=3a^2b$$

$$\small P(X=3)=P({SSS, SSS, SSS})=P(S)\times P(S)\times P(S)$$ $$\small a \times a \times a=a^3$$

The probability distribution is given as:

 X 0 1 2 3 $$P(X)$$ $$b^3$$ $$3ab^2$$ $$3a^2b$$ $$a^3$$

We can relate it with binomial expansion of $$\small (a + b)^3$$ for determining probability of 0,1,2,3 successes.

As, $$\small (a + b)^3=a^3+3ab^2+3a^2b+b^3$$

For $$\small n$$ trials, number of ways for $$\small x$$ successes, $$\small S$$ and $$(n-x)$$ failures, $$\small F$$ can be given as:

$$^nC_x=\frac{n!}{(n-x)!(x)!}$$

In each way, the probability of $$\small x$$ success and $$\small (n-x)$$ failures:

$$\small P(S)\; P(S)\times P(S)\times ….. \times P(S)\times P(F)\times ….. \times P(F)\times P(F)=a^x\: \: b^{(n-x)}$$

Thus the probability of $$\small x$$ successes in n-Bernoulli trials:

$$\small \frac{n!}{(n-x)!x!} \times a^{x}\; b^{(n-x)} = \; ^{n}C_{x} \; a_{x}b^{(n-x)}$$

Hence, $$\small P(x)$$ successes can be given by $$\small (x+1)^{th}$$ term in the binomial expansion of $$\small (a + b)^{x}$$

Probability distribution for above can be given as,

$$\small X( 0, 1, 2, 3….x), P(X) =\; ^{n}C_{0} \; a^{0}\; b^{(n)}$$

$$\small = \; ^{n}C_{1} \; a^{1} \; b^{(n-1)}$$

$$\small = \; ^{n}C_{2}\; a^{2}\; b^{(n-2)}$$

$$\small = \; ^{n}C_{3}\; a^{3}\;b^{(n-3)}$$

$$\small =\; ^{n}C_{x}\; a^{x}\; b^{(n-x)}$$

The above probability distribution is known as binomial distribution.

Example 2: If a fair coin is tossed 8 times, find the probability of:

Solution:

(a) Repeated tossing of coin is an example of Bernoulli trial. According to the problem:

Number of trials: $$\small n=8$$

Probability of head: $$\small a= \frac{1}{2}$$ and hence $$\small b=\frac{1}{2}$$

$$\small x=5,\; P(x=5) ^{8} C_{5}\; a^{5}\; b^{8-5}$$  $$\small =\frac{8!}{3!5!}\times\left ( \frac{1}{2} \right )^{5}\times\left ( \frac{1}{2} \right )^{3}$$

$$\small =\frac{8!}{3!5!}\times\left ( \frac{1}{2} \right )^{8}=\frac{7}{32}$$

(b) For at least five heads,

$$\small x>=5,\; P(x>=5)=P(x=5)+P(x=6)+P(x=7)+P(x=8)$$

$$\small =\; ^{8}C_{5}\; a^{5}\; b^{(8-5)} +\; ^{8}C_{6}\; a^{6}\; b^{(8-6)} +\; ^{8}C_{7}\; a^{7}\; b^{(8-7)} +\; ^{8}C_{8}\; a^{8}\; b^{(8-8)}$$

$$= \frac{8!}{3!.5!}. \left ( \frac{1}{2} \right )^{5}.\left ( \frac{1}{2} \right )^{3} + \frac{8!}{2!.6!}. \left ( \frac{1}{2} \right )^{6} . \left ( \frac{1}{2} \right )^{2} + \frac{8!}{1!.7!} \left ( \frac{1}{2} \right )^{7}.\left ( \frac{1}{2} \right )^{1} + \frac{8!}{0!.8!}\left ( \frac{1}{2} \right )^{8}. \left ( \frac{1}{2} \right )^{0}$$

$$=~\frac{7}{32}~+~\frac{7}{64}~+~\frac{1}{32}~+~\frac{1}{256}~=~\frac{93}{256}$$