epostma

1579 Reputation

19 Badges

17 years, 49 days
Maplesoft

Social Networks and Content at Maplesoft.com

Maple Application Center
I am the manager of the Mathematical Software Group, working mostly on the Maple library. I have been working at Maplesoft since 2007, mostly on the Statistics and Units packages and on contract work with industry users. My background is in abstract algebra, in which I completed a PhD at Eindhoven University of Technology. During my studies I was always searching for interesting questions at the crossroads of math and computer science. When I came to Canada in 2007, I had nothing but a work permit, some contacts at Maplesoft (whom I had met at a computer algebra conference a year earlier), and a plan to travel around beautiful Canada for a few months. Since Maplesoft is a company that solves more interesting math and computer science related questions than just about anywhere else, I was quite eager to join them, and after about three months, I could start.

MaplePrimes Activity


These are replies submitted by epostma

By the way, to obtain the plot that you draw, another option would be to do this:

points := PointPlot(Y, xcoords = convert(X, list));
curve := plot(Q, x = 0 .. 115);
plots[display]([points, curve], title="Mexican Population Growth");

Of course you can set thickness, style etc. either individually for points or curves, or for both of them together by specifying the argument with the display command.

Erik.

By the way, to obtain the plot that you draw, another option would be to do this:

points := PointPlot(Y, xcoords = convert(X, list));
curve := plot(Q, x = 0 .. 115);
plots[display]([points, curve], title="Mexican Population Growth");

Of course you can set thickness, style etc. either individually for points or curves, or for both of them together by specifying the argument with the display command.

Erik.

I agree with Alec -- this is the correct solution. Thanks Robert!

Erik Postma
Maplesoft

I agree with Alec -- this is the correct solution. Thanks Robert!

Erik Postma
Maplesoft

Hi protrader,

I can see a nice way to set the number of components to a fixed value, and a different way to bound the step size to a maximum, but I'm not sure if there's an elegant way to do both. I won't post any ready-made procedures, because there's too many options currently.

If you want to fix the number of components, then don't add the numbers in between in order: just pick a number that you haven't picked before in each iteration of a loop. How to go about this depends on the required efficiency and the problem size you expect to be typical.

If you want to bound the step size, do pick the numbers in order, like Doug does. Every time pick a number in the range [1 .. your upper bound] and add that to the end of your list, unless it would be at least your upper bound minus one, in which case you are done.

Hmmm... I guess you could combine these ideas by always splitting a long interval with a random point in its interior. However, with a few unlucky picks of the random generator, you might not get a solution whereas there does exist a solution; e.g., if you want to split the interval [0..100] into four parts (so with three numbers in between), each of which is at most 26 units long, and the random number generator picks the number 99 as your first boundary, then you're toast.

Another approach would be to "seed" the process by initially picking maximum-size intervals, then later splitting them further if you have extra intervals "left over". But this would give a pretty nonrandom result for some inputs.

 

I'll think about this a bit more in the next couple of days, and if I come up with something I'll post it here.

Erik Postma
Maplesoft.

Hi protrader,

I can see a nice way to set the number of components to a fixed value, and a different way to bound the step size to a maximum, but I'm not sure if there's an elegant way to do both. I won't post any ready-made procedures, because there's too many options currently.

If you want to fix the number of components, then don't add the numbers in between in order: just pick a number that you haven't picked before in each iteration of a loop. How to go about this depends on the required efficiency and the problem size you expect to be typical.

If you want to bound the step size, do pick the numbers in order, like Doug does. Every time pick a number in the range [1 .. your upper bound] and add that to the end of your list, unless it would be at least your upper bound minus one, in which case you are done.

Hmmm... I guess you could combine these ideas by always splitting a long interval with a random point in its interior. However, with a few unlucky picks of the random generator, you might not get a solution whereas there does exist a solution; e.g., if you want to split the interval [0..100] into four parts (so with three numbers in between), each of which is at most 26 units long, and the random number generator picks the number 99 as your first boundary, then you're toast.

Another approach would be to "seed" the process by initially picking maximum-size intervals, then later splitting them further if you have extra intervals "left over". But this would give a pretty nonrandom result for some inputs.

 

I'll think about this a bit more in the next couple of days, and if I come up with something I'll post it here.

Erik Postma
Maplesoft.

For the record: your fragment runs fine and with the right result on my four-core linux64 machine.

Erik Postma
Maplesoft.

For the record: your fragment runs fine and with the right result on my four-core linux64 machine.

Erik Postma
Maplesoft.

Much more elegant idea than my procedure. Thanks Joe!

Erik.

Much more elegant idea than my procedure. Thanks Joe!

Erik.

Ah -- thanks for that, I didn't realize that. It seems that it does work if you use table index referencing:

p := proc(V::Vector(datatype=float[8]))
  eval(Statistics['Mean'](V));
end proc:
V := Vector[row]([1, 2, 3], datatype=float[8]):
evalhf(p(V));

returns 2.

Erik Postma
Maplesoft

Ah -- thanks for that, I didn't realize that. It seems that it does work if you use table index referencing:

p := proc(V::Vector(datatype=float[8]))
  eval(Statistics['Mean'](V));
end proc:
V := Vector[row]([1, 2, 3], datatype=float[8]):
evalhf(p(V));

returns 2.

Erik Postma
Maplesoft

Thanks Acer, you seem to have nailed it.

One minor addition, though I'm sure the Compiler:-Compile solution is still the best: you can actually call module exports from within evalhf, you just have to wrap the call in eval (which calls into regular Maple). There is a speed penalty for that, but it's not huge I think. This is often useful if you can do the majority of the work in evalhf and just need a few library calls.

Here's a quick illustration:

evalhf(rand());

gives an error message: "Error, module member referencing is not supported in evalhf". However,

evalhf(eval(rand()));

returns 0.193139816415E12 (in my case).

Erik Postma
Maplesoft

Thanks Acer, you seem to have nailed it.

One minor addition, though I'm sure the Compiler:-Compile solution is still the best: you can actually call module exports from within evalhf, you just have to wrap the call in eval (which calls into regular Maple). There is a speed penalty for that, but it's not huge I think. This is often useful if you can do the majority of the work in evalhf and just need a few library calls.

Here's a quick illustration:

evalhf(rand());

gives an error message: "Error, module member referencing is not supported in evalhf". However,

evalhf(eval(rand()));

returns 0.193139816415E12 (in my case).

Erik Postma
Maplesoft

Hi Willie,

Sorry for the delay in my reply. I only just saw your message.

It turns out that my initial advice was actually not the best. The situation where some of the variables represent real quantities and some are complex is actually not very common, and the way to solve this in Maple is not very straightforward (although it is quite possible).

The best approach is to split U, the complex variable, into UR + I * UI, where UR and UI are real numbers representing the real and imaginary parts of U. Then we can transform the problem into one that has only real variables, and solve that using the routines for real solving. This would work as follows; I'm including your problem definition as well:

> a := 0.5;

> alph := U -> U^2*(a-(1-U^2)^2);

> dadU := D(alph); # Let Maple do the work of determining the derivative! :)

> equations := {Re(I*U*V + alph(U)) = 0, -V+I*dadU(U)=0};

> equations := eval(equations, U = UR + I * UI); # Split U into real and imaginary parts

> equations := map(Re, eqns) union map(Im, eqns); # Equate real and imaginary parts of right- and lefthand sides

> equations := evalc(equations); # Simplify the equations assuming that all occurring *variables* are real (which they are, now)

> solutions := {RealDomain[solve](equations)}; # Use Maple's real domain solver explicitly. (Note there is a double root at the origin.)

> solutions := map2(s -> {U = eval(UR + I*UI, s), V = eval(V, s)}, solutions); # 'Reassemble' the complex value for U

> KfValues := map(s -> eval(Im(I*U*V + alph(U))/V, s), solutions);

You also asked three specific questions in your last email. I think the answer to the first two lies in this being an artifact of Maple's solve command not using the assumptions placed on variables in an optimal way, and not really having an automatic solution for the case where some variables are complex and others are real. I added the answer to the second one to the program listing above.

One more note. I saw that you chose to use floating point numbers in some places; one for a := 0.5 and one in the definition of dadU. That means that you get floating point answers. I already removed the one in dadU; if you replace the definition of a by a := 1/2, you will get exact answers. I wouldn't recommend it for this problem, though; the answers are very long (on the order of a page or so).

I hope this helps! I'll check here again in the next couple of days to see if you have any more questions.

 

Erik Postma
Maplesoft

First 19 20 21 22 Page 21 of 22