One way to experiment with whether the extra time may be due to garbage collection (gc), is to increase the limit that controls gc frequency.
For example, set,
> kernelopts(gcfreq=10^8):
and then see what efect that has on the repeated loop timings.
acer

The original example is covered by its own explanatory paragraph in the help-page ?sign .
There is also sometimes confusion between the functions sign() and signum().
Consider this below, where no quoting is necessary,
plot([signum(x)],x=-1..1);
and see ?signum .
acer

Hello again,
The Matrix ls_m is currently set up as 6x9. So, assuming that the extra 3 columns of ls_m actually contain pertinent and meaningful data, the system appears underdetermined. Presumably, this is why you've supplied a name for the generation of the free variables to appear in any solution, by supplying the option free='t'.
What might not be made clear enough in the help-pages ?LinearSolve and ?IterativeSolver is that the underlying sparse solvers are not designed for producing symbolically parametrized solutions of underdetermined systems. They are purely numerical, and can by nature only ever generate a purely floating-point solution with no free variables. (Such iterative methods generally use some form of Matrix-Vector multiplication, or a related way to "iteratively" get closer to an answer. There's no room in that for supplying any symbolic piece to the result.)
If ls_m were 6x6 (or 9x9) and had datatype=float[8], with B of corresponding size, then that should work with the sparse method, I believe. You might even be able to pad out the data so as to get the a (single, purely numeric) sol which approximately satisfied the original system. But the current sparse solvers are purely numeric, and can't get you a parametrized solution, I don't think.
As you've pointed out, though, this below does produce a solution to the problem (sized, as stated), as long as ls_m and B don't contain floats,
sol := LinearSolve(ls_m, B, free='t');
So perhaps you could just use that, then, and conclude that the sparse solver is float-based and not appropriate here?
acer

Hello again,
The Matrix ls_m is currently set up as 6x9. So, assuming that the extra 3 columns of ls_m actually contain pertinent and meaningful data, the system appears underdetermined. Presumably, this is why you've supplied a name for the generation of the free variables to appear in any solution, by supplying the option free='t'.
What might not be made clear enough in the help-pages ?LinearSolve and ?IterativeSolver is that the underlying sparse solvers are not designed for producing symbolically parametrized solutions of underdetermined systems. They are purely numerical, and can by nature only ever generate a purely floating-point solution with no free variables. (Such iterative methods generally use some form of Matrix-Vector multiplication, or a related way to "iteratively" get closer to an answer. There's no room in that for supplying any symbolic piece to the result.)
If ls_m were 6x6 (or 9x9) and had datatype=float[8], with B of corresponding size, then that should work with the sparse method, I believe. You might even be able to pad out the data so as to get the a (single, purely numeric) sol which approximately satisfied the original system. But the current sparse solvers are purely numeric, and can't get you a parametrized solution, I don't think.
As you've pointed out, though, this below does produce a solution to the problem (sized, as stated), as long as ls_m and B don't contain floats,
sol := LinearSolve(ls_m, B, free='t');
So perhaps you could just use that, then, and conclude that the sparse solver is float-based and not appropriate here?
acer

You wrote of transmission0 and reflection0, that, "all they contain are simple floats."
As described, however, the code is generating a great many so-called software floats. Maple will dispose of those, once no longer needed, during garbage collection. But that extra garbage collection adds to the total overhead. If you really just need the Matrices to store floating-point numbers, and if hardware double-precision is sufficient, then consider placing an appropriate datatype on the Matrices.
For example,
> transmission0:=Matrix(1200,2,datatype=float[8]):
and similarly for reflection0, re, and te.
You might also be able to fill the first column of both transmission0 and reflection0 more quickly, by pulling the assignments (into their first columns) out of the loop. Completely outside of the loop, create a Vector,
> firstcol := Vector(1200,(j)->0.0416666666*j,datatype=float[8]):
and also do, outside the loop,
> transmission0[1..1200,1] := firstcol:
> reflection0[1..1200,1] := firstcol:
I hope I got that right.
There might be more efficient ways to initialize the second column too, but it's not possible to say without knowing how rcwa writes to te and re depending on M and how M changes with m.
Also, if you made rcwa accept re and te as parameters (it should still be able to update them efficiently, inplace, if they had float[8] datatype), while also making rcwa return M instead of writing to it as a global, then perhaps you could then run rcwa under the faster purely floating-point evalhf interpreter. See the help-page ?evalhf for details.
acer

I am curious why there is interest shown here in speed performance but not in memory performance. For example, how do the various techniques differ in terms of how much extra memory they allocate? I find that Maple performance discussions tend in general to have an emphasis about speed of execution. Isn't a performance metric which combines both speed and memory allocation just as valuable, and perhaps more valuable in general?
I have seen a few different performance metrics commonly used in the past. One is time_duration*allocation_increase, and another is time_duration*(allocation_increase^2).
I prefer the technique Roman used here, to have restarts between comparisons of various methods. For, even if one is not measuring memory allocation as part of the performance metric, there can be a penalty for garbage collection which changes with ongoing differences in memory allocation. So it can happen that the order of tests affects how they perform. Putting distinct tests into distinct Maple runs can alleviate such obscuring interference. (As we know, it was not always true as it is in Maple 10 that memory would be completely freed upon restart. So multiple sessions for distinct tests is cleaner all round.)
acer

Despite the fact that eq contains coefficients whose exponents grow (exponent of 10) with respect to evaluation at Digits precision, the numerical solution appears to remain stably computed. So perhaps the solution is accurate.
The left-hand-side of eq appears to be monotonic and continuous from -10^8 to 10^3. (Wouldn't it be mildly surprising if the *exact* solution of equations which well-represent beam mechanics not at least be continuous?) You mentioned that you had a class of equations to handle. Will they all be monotonic, or at least continuous? If so, maybe it could suffice to find a value of N which makes lhs(eq) positive and another which makes it negative, in which case you know that there must exist a value between them which satisfies eq. You could try peppering a numeric range for N, in an attempt to find such a pair of values of N. That'd save the effort of asking fsolve to locate and closely approximate an actual root.
As far as the code goes, the final eq and solution appear to remain unchanged if you do the following:
- replace the subs() calls with eval() calls
- replace the evalf(...int()) calls with evalf(...Int()) calls
- replace the int() call when assigning to f by an Int() call
This seems to speed it up.
acer

Despite the fact that eq contains coefficients whose exponents grow (exponent of 10) with respect to evaluation at Digits precision, the numerical solution appears to remain stably computed. So perhaps the solution is accurate.
The left-hand-side of eq appears to be monotonic and continuous from -10^8 to 10^3. (Wouldn't it be mildly surprising if the *exact* solution of equations which well-represent beam mechanics not at least be continuous?) You mentioned that you had a class of equations to handle. Will they all be monotonic, or at least continuous? If so, maybe it could suffice to find a value of N which makes lhs(eq) positive and another which makes it negative, in which case you know that there must exist a value between them which satisfies eq. You could try peppering a numeric range for N, in an attempt to find such a pair of values of N. That'd save the effort of asking fsolve to locate and closely approximate an actual root.
As far as the code goes, the final eq and solution appear to remain unchanged if you do the following:
- replace the subs() calls with eval() calls
- replace the evalf(...int()) calls with evalf(...Int()) calls
- replace the int() call when assigning to f by an Int() call
This seems to speed it up.
acer

What does LinearAlgebra[ConditionNumber]() give, for your large Matrix?
See ?conditionnumber,Definition
Ill-conditioning can account for no digits of accuracy in the forward-error result (which you seem to be computing by local_A . sol ).
What happens if you increase Digits and repeat the calculations?
See the Hilbert Matrix example in the LinearAlgebra tutorial. It's supposed to illustrate the effect of very poor conditioning of a linear system.
acer

What does LinearAlgebra[ConditionNumber]() give, for your large Matrix?
See ?conditionnumber,Definition
Ill-conditioning can account for no digits of accuracy in the forward-error result (which you seem to be computing by local_A . sol ).
What happens if you increase Digits and repeat the calculations?
See the Hilbert Matrix example in the LinearAlgebra tutorial. It's supposed to illustrate the effect of very poor conditioning of a linear system.
acer

How big are C and gmat? Ie, what is numdata? Is the data all purely numeric, that ends up in C and gmat? If so, what is Digits at the point that DIFFERENCE is assigned??
Are *all* the evalf calls in the line that assigns to DIFFERENCE really necessary?
Also, could you not replace the complicated and expensive assignment to DIFFERENCE with simply,
LinearSolve( C, g ); # possibly with evalf
? You'll want to work it out, to see if that is valid. At first glance, the formulation you have looks equivalent to C^(-1).g but I could be wrong.
You mentioned that it ran in MapleV R4. Does that mean that the original version used linalg instead of LinearAlgebra? What happens if you try to run the original code in Maple 10?
Can you check kernelopts(bytesalloc) at key points in the code? Does that seem to agree roughly with Windows' Task Manager's showing of consumed memory resources?
acer

Why did you replace the bundled jre.XXX with links to a newer version?
Did you try it with the installed (Blackdown-1.4.2) version?
acer

Here's another one that's wrong. This one goes wrong on the diagonal as well as on the opposing elements. The diagonal should of course be purely real.
> m := Matrix(2,3*I,shape=hermitian,storage=rectangular);
[ 0 -3 I]
m := [ ]
[3 I 0 ]
> map(x->x+2*I,m);
[2 I -I ]
[ ]
[5 I 2 I]
> lprint(%);
Matrix(2,2,{(1, 1) = 2*I, (1, 2) = -I, (2, 1) = 5*I, (2, 2) = 2*I}, datatype = anything,storage = rectangular,order = Fortran_order,shape = [hermitian])
acer

Yes, I had noticed that the default triangular storage was ok, as far as mapping went. But surely it's an outright bug that the shape=skewsymmetric and storage=rectangular pair in a Matrix is something that map mishandles. It produces a Matrix which has 'skewsymmetric' indexing function but whose stored entries are not such that it is actually skew-symmetric! The resulting object seems illegal, in a sense, and I cannot see how else it might be constructed since its contents violate its indexing function.
I also consider it an issue that the new functionality, that map now produces copies of rtables which retain the indexing function and storage of the original, is not clearly documented as a new feature. It was behaviour that some of my code relied upon.
I didn't consider the old behaviour wrong and in need of fixing, for it was very easy to understand and contrasted with LinearAlgebra:-Map's, ie. rectangular storage rtables with no indexing function were always produced, and the mapping requested would always occur. Now it's more complicated, so it ought to have been documented in the ?updates,Maple10,compatibility help-page. The new behaviour seems complicated enough that I'm not sure how useful it is. Maybe it just takes getting used to.
It's also an issue that the map help-page isn't clear enough (I think) about the way that it will silently fail to actually do the map over all elements of Matrices with certain shapes and empty storage.
acer

This functionality appears to be new to Maple 10. I didn't find it under the ?updates help-pages.
Previously, map() would return a new object that had no indexing function. And so it given a Matrix created with shape=identity it would return a new Matrix with no such indexing function and would do the mapping as requested.
It's clearly tricky to get this functionality just right, so that everyone's happy. For example one might not want the idiosyncratic behaviour of LinearAlgebra:-Map, which can act twice as it walks the elements of a Matrix with symmetric indexing function. And it seems that map is now aware of the symmetric indexing function, and only operates once per pair of symmetrically equal entries.
But is map aware of all built-in system indexing functions? For example, is this right below?
> m := Matrix(2,2,[[0,2],[-2,0]],shape=skewsymmetric,storage=rectangular);
[ 0 2]
m := [ ]
[-2 0]
> newm := map(x->x+1,m);
[ 0 3]
newm := [ ]
[-1 0]
> lprint(newm);
Matrix(2,2,{(1, 2) = 3, (2, 1) = -1},datatype = anything,storage = rectangular, order = Fortran_order,shape = [skewsymmetric])
And surely map will not know what to do with user-defined indexing functions. So it may not just be empty-storage indexing functions which give strange results.
Is it inconsistent for map to be clever about the symmetric indexing function but not about the identity?
acer