Revisiting the Android, UserLAnd app.

One of the facts which I had reported some time ago was, that a handy, easy-to-use Android app exists, which is called ‘UserLAnd‘, and, that I had installed it on my Google Pixel C Tablet. As the tooltip suggests, this is an Android app that will allow people to install a basic Linux system, without requiring ‘root’. Therefore, it mounts the apparent, local Linux file system with ‘proot’ – which is similar in how it works to ‘chroot’, except that ‘proot’ does not require root by the host system to set up – and any attempts to obtain root within this Linux system really fail to change the userid, of the app that the files belong to, or of the processes running. Yet, becoming root within this sandboxed version of Linux will convince Linux, for the purpose of installing or removing packages via ‘apt-get’.

In the meantime, I have uninstalled the ‘UserLAnd’ Linux guest system from my Pixel C Tablet, in order to free up storage. But, I have set up something like this again, on my Samsung Galaxy Tab S6 Tablet, which has 256GB of internal storage. Therefore, I have a few observations to add, about how this app runs under Android 10.

Through no fault of the developer of this Android app, the user is more restricted in what he can run, because Android 10 places new restrictions on regular processes. Specifically, none of the major LISP Interpreters that were designed to run under Debian 10 / Buster will run. (:1) What the Linux developers did was, to make the garbage collection of their LISP Interpreters more aggressive, through a strategy that changes the memory protection bits of memory-maps, to read-only if they belong to the state of the machine, and then, ~to try deleting as much of the bytecode as can still be deleted~. Pardon me, if my oversimplification gets some of it wrong.

Well, Android 10 no longer allows regular apps to change the protected memory state of any pages of RAM, for which reason none of the affected LISP Interpreters will run. And for that reason, neither “Maxima” nor anything that depends on Maxima can be made to run.

Yet, certain other Linux applications, notably “LibreOffice” and “Inkscape”, run just fine… So does “GIMP”…

Screenshot_20200912-171020_VNC Viewer

Also, the way in which files can be shared between theĀ  Android Host and the Linux Guest System has been changed, as the following two screen-shots show:

Screenshot_20200912-155032_VNC Viewer

Screenshot_20200912-155144_File Manager

Here, the file ‘Text-File.txt’ has been shared between Android and Linux. Larger files can also be shared in the same way, and the folder bookmarked under Linux. (:2)

In many ways, the Linux applications behave as described before, with the unfortunate exceptions I just named, and I intend to keep using this app.

Technically, a Host app that just sandboxes a Guest Application in this way, does not count as a Virtual Machine. A real VM allows processes to obtain root within the Guest System, without endangering the Host System. Also, ‘a real VM’ provides binary emulation, that makes no specific assumptions about the Guest System, other than, usually, what CPU is being used. Emulation that includes non-native CPU emulation is still a somewhat special type of emulation.

Therefore, the ability of Debian 10 / Buster to run under ‘UserLAnd’ depends, in this case, on the Linux package maintainers having cross-compiled the packages, to run on an ‘ARM-64′ CPU…

 

(Updated 9/13/2020, 21h30… )

Continue reading Revisiting the Android, UserLAnd app.

An idiosyncrasy, in how Maxima evaluates parameters.

One of the facts which I had written about Maxima in an earlier posting was, that it seems to have a number of functions, the purpose of which in English seemed to be, ‘Take a parameter or expression as input, but give me the value of this parameter.’ And what I had actually written was, that this availability of more than one similar function, could confuse me at one point in time, into not actually knowing what one specific function does. Yet, reflecting on the question outside the exercise that I was doing, brought back the gist of what that function really does. In the previous context, it was the function ‘ev()’.

A context which some other people have noticed instead, is that they’d like to use the Maxima ‘tex()’ function, in order to convert some expression into LaTeX, for another application to typeset, but in some cases the other users wanted to use previous lines of input directly, rather than to use previous lines of output. And what they found was, that the LaTeX version of what they had input, was a ‘verbatim’ block, different according to LaTeX, from what needs to be typeset as Math.

Both issues arise somewhere, because Maxima itself has been programmed in the language LISP. And, most of the time, LISP just seems to produce correct results, according to the way some people tend to interpret the meaning of the LISP function call. But in certain cases, people who either program in, or use LISP, need to form a mental, step-by-step picture of what the LISP interpreter actually does. LISP evaluates both atoms and lists, the latter of which could represent Mathematical expressions, but the former of which represent variables, in situations where their values are being referred to, and not the atom itself. At any point in the computation, LISP will actually evaluate an atom or a list, according to the same semantics. Given an atom, its value is returned, which could be another atom as easily as a list. And, given a list, to return its value means, to execute that list once.

The modern way to refer to what I’ve called an Atom here, is as a “Symbol”, which is really the name of a (LISP) Variable, that also has a value, at a given instant in time.

The way LISP generally defines lists, each of their elements may either be an atom or another list, ‘nested’ within its parent list. In LISP, lists are slightly more common, the first element of which is an atom, just because in such a case, this first element states which function is to be called on the remaining elements. But, in LISP, data is also represented as either a list or an atom, and then, in the case of a list, there is no specific need for the first element to be an atom, or one that represents a defined LISP function. (:1)

Obviously, most other Computing languages, including the one which Maxima interprets, states the function-name first, followed by one set of parentheses, around any argument-list, or around a parameter-list, in the case where the function is being defined. Infix operators are usually also represented internally, as predicates, in whatever data-format those can be represented. One major exception to this takes the form of ‘stack-based languages’, such as ‘FORTH’, and another exception exists in Assembler.

Aside: ‘Prolog’ represents both data and programming as an n-graph, meaning that in this language, each node of a tree may have an arbitrary number of branches, including zero, but additionally, an atomic predicate, stating whichever relationship between the other branches is to be satisfied.

The total number of times LISP evaluates a parameter is tightly defined, so that, if an atom represents a variable, which in turn has a list as its value, that item will result, but not be executed, unless the command is given explicitly, to evaluate the result of the previous evaluation. In LISP, the function which gives such an explicit command, is called ‘EVAL’, and the way to give that instruction, in any context where the variable ‘X’ is instantiated, is like so:

(EVAL X)

Because of the way LISP generally evaluates lists, since ‘X’ does not have a tick – a single quote – in front of it, ‘X’ was already evaluated once, before being passed to ‘EVAL’. And then, ‘EVAL’ evaluates whatever value ‘X’ had, a second time. Even according to Human thought, the fact that ‘X’ represented a value, can seem to disappear, so that Humans will also think, ‘Whatever is being referred to as X, evaluate that.’

Well, the way this works can be revealed, in certain uses of Maxima, such as, if the ‘tex()’ function is being called on an input identifier, when most of the time, it was meant to be used either, on an expression that has been parsed into a LISP structure, or, on a variable, which already evaluated to such an expression, before ‘tex()’ went to work on it.

Yet, because some people want to obtain the LaTeX representation of text, which they previously input, from Maxima, the following text-log displays where an extra step needs to be inserted, in order to accomplish this:

(Updated 7/14/2020, 22h15… )

Continue reading An idiosyncrasy, in how Maxima evaluates parameters.

Cheating a little bit, and teasing a shaded surface, out of a Computer Algebra System.

One of the subjects which I posted about some time ago was, how easy it is for a Computer Algebra System – a CAS – to output a single variable, in order to colour an Iso-Surface, and how hard it is in contrast, to output a normal vector, from whatever Geometry Shader computes the Iso-Surface, such that this normal vector can be used to shade the surface, in a later Fragment Shader invocation.

What needs to be done in ‘3D Game Design’ and (other) ‘CGI’, is essentially that.

But, given that a CAS can be used both, to plot a 3D surface, as well as, to define what the colour-range of this surface is supposed to be, a bit of a trick can be used, to bypass the need actually to compute a normal vector, but to achieve an equivalent result. And this posting will begin with an example which is slightly simpler, than what my earlier posting had assumed. Iso-Surfaces tend to smack of ‘implicit’ functions, while this example is going to start with an ‘explicit’ plot, in which (X) and (Y) are parameters of the function, but where it was already easy to achieve, that a single (Z) value results, such that (X, Y, Z) are in fact the coordinates plotted.

Because we have a Computer Algebra System in the first place, for continuous functions, it’s easy to compute the derivative with respect to one of the parameters. That derivative can be used, just to modulate the brightness of the surface. The simplest example is shown blow:

 


 

(Updated 7/10/2020, 6h10… )


Continue reading Cheating a little bit, and teasing a shaded surface, out of a Computer Algebra System.

A simple 3D animation created with Maxima.

One of the things which I find myself doing quite often is, to be undertaking some sort of task on the computer(s), that I know is possible, but, not knowing in advance what the correct syntax and semantics are, to perform this task. This tends to take me on some sort of search on the Web, and I’ll find that other people have undertaken similar tasks, but not, a task with the same combination of parameters, as my task.

Thus, Web pages can be found according to which 2D animations have been created using a free, open-source Computer Algebra System named “Maxima”. Other Web pages may explain how to create various types of (static) 3D plots. But there may just be lacking examples out there, on how to create the 3D plot, but to animate it.

Using Maxima, there may be more than one way, such as, to keep refreshing the 3D plot over a time interval. But I find that such solutions tend to be second-rate, because of their use of busy-wait loops, as well as the possibility that they may otherwise be wasteful of computing power. I think that the best way, perhaps, to get Maxima to generate an animated 3D plot, could be, in the form of an animated GIF File (of course, as long as there isn’t an excess of frames to this animation).

Thus, the recipe that seems to work is as such:

 


load(draw)$

scenes: []$

for i thru 20 do (
    scenes: append(scenes,
            [gr3d(explicit(sin(%pi*(x+(i/10)))*cos(%pi*y),
                x, -1, 1, y, -1, 1))]
        )
)$

draw(
    delay = 10,
    file_name = "wavy",
    terminal = 'animated_gif,
    scenes
)$

 

The script outputs a file named ‘wavy.gif’ in the same folder, as whatever folder it was originally stored in. In some cases, the GIF File may appear in the user’s home directory, or even, in a temporary directory that’s difficult to find, unless the user also gives a full-path name for the file.

And, this is the GIF File that results:

wavy

 

Caution:

My most recent posting had to do, with a version of Maxima that had been ported to Android. The example above will not work with that version of Maxima. In fact, I can really only be sure that this feature works under Linux, which is the O/S that Maxima was mainly designed to run on. Any directives to ‘plot()’ or ‘draw()’ open a separate GNU-Plot window, which behaves in the predictable way under Linux, including the user’s ability to rotate the 3D plots interactively. AFAIK, commands to change to a non-default ‘terminal’ (for drawing and/or plotting) will fail on other platforms.

But, There is also a Windows or Mac alternative to using this platform, which mainly presents itself in the application ‘wxMaxima’. Here, the functions ‘wxdraw2d()’ and ‘wxdraw3d()’ replace those that open a separate window, and both embed their results in the wxMaxima worksheet. In order to make this more versatile, wxMaxima also offers the functions ‘with_slider_draw()’, ‘with_slider_draw3d()’, ‘wxanimate_draw()’, and ‘wxanimate_draw3d()’.

Potential ‘wxMaxima’ users will find the documentation for how to script that Here.

(Updated 7/06/2020, 15h35… )

Continue reading A simple 3D animation created with Maxima.