I too would like to know the answer to this -- how to get the volume of revolution to be solidly filled. Maybe there is some simple answer.
A good solution would be something that would truly look filled, were it transluscent. By that I mean that faking it (say, by assigning the VolumeOfRevolution plot to a variable and then displaying both that and two additional plots of the end-discs) would not always look truly filled.
I had first imagined that the following command might do it,
Student[Calculus1][VolumeOfRevolution](1/x, x=1 .. 2,axis= 'horizontal', volumeoptions=[filled=true], showfunction=false, 'distancefromaxis' = 0, 'output' = 'plot');
acer
It seems that there are restrictions here. I am able to add formatted 2D Math output to a plot caption, but not 2D Math *input*.
For example, suppose that I do as stated and enter the entire plot command as 2D math. I enter the rhs of caption=ZZZ as,
2 (x+y)
Can that be formatted in 2D Math (as it certainly is, as 2D Math input), without the full evaluation that then produces 2 x + 2 y in the caption? I can of course use name-quotes to fake this simple example, but that becomes problematic if the expression is not so simple.
There are other examples. In a Document, I can enter mathematical syntax that needn't neceesarily evaluate OK in Maple. One decent reason to do this is for the purpose of discussing mathematics outside of the limited scope of Maple. I can enter, as 2D math input surrounded by text, 1/0 and not get an evaluation and the subsequent division by zero exception. How can one get a 2D Math typeset 1/0 (not faked with name-quotes so it looks like lprint'd input)?
acer
That's not an unreasonable guess, that Array might be related to array in that way. But it's not the case. Indeed, calling Array() shows that it is not the inert form of array(). Since it "does" something, it's not inert.
An array is a table-based structure with the particular property of having the indices be integers. Maple tables, on the other hand, can be indexed by almost anything. So an array is a special kind of table.
The command matrix() and vector() are conveniences, to allow creation of 2D and 1D arrays whose index ranges start at 1. And since arrays are tables, then matrices and vectors are tables too.
In Maple, tables follow so-called last-name evaluation, see ?last_name_eval . This behaviour allows them to be passed as arguments to a procedure without having their contents be fully evaluated. This is quite useful. They are of course a mutable datastructure -- their contents can be changed in-place without effecting a full copy of the whole structure. (The Maple list is the opposite, and assigning "into" a list is very inefficient.)
So, tables, arrays, matrices, and vectors all have last-name-eval (as it's known for short...). This is why you'll often see somthing like eval(a) at the end of routines that deal with matrices and arrays, so that the actual table is returned (as opposed to, say, the local name which might actually be the "last name").
The last-name-eval property can sometimes cause some difficulties. There's even a joke name for some such situations, last-name-evaluation-disease (lned). On the other hand, last-name-eval solves some matters brilliantly.
See my
other reply, for a description of rtables, Arrays, Matrices, and Vectors. Those objects, in contrast to tables, do *not* have last-name-eval.
The older package linalg is for matrices and vectors, while LinearAlgebra is for Matrices and Vectors.
The difference in evaluation rules can make translating a linalg-based user-authored routine to be LinearAlgebra-based a bt tricky. See ?examples,LinearAlgebraMigration .
ps. No jokes about "ert" being the opposite of inert, thanks. :)
acer
There are several misunderstandings evident in that comment.
As a general rule, Maple evaluates arguments before passing them to procedures. That is, before they are bound to the procedure's formal parameters.
So this command solve(y = 1^(1/3), y) will receive y=1 as its first argument, because 1^(1/3) evaluates to simply 1.
Procedures in the Maple Library which delay this evaluation, by default, are said to have special evaluation rules. See ?spec_eval_rules for more details on that.
I don't know where in the help-pages the standard (non-special) evaluation rules are described.
But you example also has another problem. Let's change it slightly to solve(y = x^(1/3), y), to avoid the evaluation problem mentioned above. Look at it harder. The equation is already an explicit formula for y. It doesn't make sense to ask more of it.
And lastly, y^3=x is not the same as y=x^(1/3).
acer
There are several misunderstandings evident in that comment.
As a general rule, Maple evaluates arguments before passing them to procedures. That is, before they are bound to the procedure's formal parameters.
So this command solve(y = 1^(1/3), y) will receive y=1 as its first argument, because 1^(1/3) evaluates to simply 1.
Procedures in the Maple Library which delay this evaluation, by default, are said to have special evaluation rules. See ?spec_eval_rules for more details on that.
I don't know where in the help-pages the standard (non-special) evaluation rules are described.
But you example also has another problem. Let's change it slightly to solve(y = x^(1/3), y), to avoid the evaluation problem mentioned above. Look at it harder. The equation is already an explicit formula for y. It doesn't make sense to ask more of it.
And lastly, y^3=x is not the same as y=x^(1/3).
acer
There are some very nice routines in the ArrayTools package. Eg, DataTranspose, Permute, Reshape, etc.
But I would also say this: when it comes to permuting and reshaping and rearranging an Array (or rtable), always ask hard whether it really needs to be done. Do you really need the new object, since it takes up memory? Or can you just access the elements according to some formula. Don't transpose A if you can access the entries with the A[i,k,j] syntax in your code.
There will still be some situations where you want to actually produce the new transposed object. For example, to pass it externally. Or the decision might come down to how often you need to access the entries. If it's just for a few entries, just once, then access them "formulaically". If you need them all, many times, then creating the new object will remove the overhead of duplicated application of the transforming index forumla or indexing function.
It's a bit like rtable indexing functions with *no* (empty) storage. Such an Array or Matrix can have its entries computed only on demand. Which is cool, up to the point that the overhead of calling the indexing function swamps the performance. This is part of an age-old dichotomy, space vs speed.
On a related note, wouldn't it be nice if more LinearAlgebra commands accepted transposition flags on their rtable arguments. If so, then one could compute say, A^%T . B without having to actually form A^%T at all.
ps. For a lot of fun learning, try ?rtable_ and study the many help-pages for low-level rtable handling.
acer
There may be something even simpler, but,
A := Array(1..2,1..3,1..4,(i,j,k)->i*j-k^2);
B := Array(seq([rtable_dims(A)][i],i in [1,3,2]),(i,j,k)->A[i,k,j]);
acer
Array, Matrix, and Vector are the three flavours of rtable. They can also be formed using the rtable() constructor, see ?rtable . See also ?rtable_indexfcn for documentation of the indexing function capabilities.
An Array may have more than 2 dimensions, and its index ranges do not need to start from 1 (or even to be positive). Eg,
Array( -2..-1, 4..7, -3..3 );
Arrays are not accepted by LinearAlgebra routines. There are some useful commands for manipulating Arrays in the ArrayTools packages.
The arithmetic operators like `+` can handle them, but ther are some differences. For example, `.` will do an elementwise product rather than the usual 2D Matrix linear algebra multiplication. Eg, compare,
A := Array(1..2,1..2,(i,j)->i);
A.A;
A := Matrix(2,2,(i,j)->i);
A.A;
The Matrix and Vector (Vector[row] or Vector[column]) objects are accepted by LinearAlgebra routines. The ArrayTools package also works with these. (Maybe it should be called the RTableTools package..)
The `.` operator acts on these in the usual linear algebra senses. There is a distinction bewteen 1D Matrices and Vectors (unlike in Matlab). One way to consider them is to view Vectors as elements of vector spaces and to view Matrices as mappings (which is a rationale for that distinction). 1x1 Matrices and Vectors are not scalars (also unlike Matlab?).
Matrices and Vectors are for doing linear algebra. Arrays are useful as mutable datastructures with fixed sizes (and for which some top-level operators work nicely.) Some packages export their own versions of similar objects, eg. VectorCalculus exports its own Vector constructor, see ?VectorCalculus,Details .
The term `rtable` stands for "rectangular table". It was introduced in Maple 6 so that hardware precision rtables could have their data stored as contiguous arrays in memory. The purpose of that was to allow their data to be passed to external routines for computation with compiled code. (The address of the start of the data may be passed as a pointer, with no copying required.) Hence rtables with floating-point datatypes are used this way in much of LinearAlgebra and ArrayTools.
acer
Why not permute directly with the Array constructor?
B := Array(rtable_dims(A),(i,j,k)->A[i,k,j]);
acer
Just looking for clarification. Your post's title had the names capitalized, but the post did not.
acer
Thanks for those details. Do you suspect that, even if you find reasonably good defaults for those magic numbers, some user-based control via options may be necessary for some problems to be solved?
Will there be some mechanism for repeated solving using different RHS's (but *not* all done at once)? I ask because depending on the method this can require saving the factorization or preconditioning.
There is also a real floating-point sparse direct solver available from LinearAlgebra[LinearSolve] with the method=SparseLU option.
The userinfo messages indicate that this uses NAG routine
f01brf to factorize and routine
f04axf to do the subsequent solving for a given RHS.
There is an indication that the NAG f01brf approach is based upon the somewhat well-known MA28 FORTRAN code. I don't have much experience with either SuperLU or MA48 (the successor to MA28?).
acer
You can still access the global name using the :- notation, even when the "same" name is used as a procedure parameter. For example, to distiguish the local and global names,
p := proc(array::posint)
local f;
f := :-array(1..1,[p]);
end proc;
p(3);
p := proc(array::posint)
local f;
f := array(1..1,[p]);
end proc;
p(3);
It is certainly not wrong to code it as you did, and I didn't means to imply that. Some people will like the fact that the namespace can be used in this way, and that `array` is available for such use. Personally, I find it a bit unecessary, and suspect that it might confuse some other newer users.
acer
In the floating-point case, solving large sparse linear systems can be difficult. The existing solvers for such floating-point systems (hooked into LinearSolve) accept some options -- to control things like the choice of method, amount of fill-in, tolerances, etc. See ?IterativeSolver .
What sort of options do you expect that your rational solver implementation might need, if any?
ps. The documentation makes it appear that only symmetric/hermitian floating-point sparse systems can be solved with iterative methods. Yet trying it with real nonsymmetric float[8] sparse Matrices shows via userinfo that there are also distinct nonsymmetric solvers. All the sparse floating-point methods show NAG function names through userinfo, ie. with infolevel[LinearAlgebra] > 0 .
acer
You are right, of course, sorry. I was thrown by the use of protected top-level names as paramaters for your indexing functions.
acer
I would still prefer to use rtable_scanblock over `index/XXX`. The posted method using `index/makeIndex` produces an array, and an Array, and then finally a set. It may be that with rtable_scanblock one can produce only a table (array) and then finally a set. Both incur the cost of the function calls for each entry, of course, either of `index/makeIndex` or of checkindex.
FindIndex := proc(comparison, A)
local checkindex, G;
checkindex := proc (val, ind) if comparison(val) then G[ind] := ind end if; NULL; end proc;
rtable_scanblock(A,[rtable_dims(A)],checkindex,[]);
eval(G);
end proc:
A:=Array(1..3,1..4,(i,j)->i-j):
T:=FindIndex(x->type(x,nonnegint),A):
convert(T,set);
acer