A variety of maxima queries



Daniel Dalton <daniel.dalton47 at gmail.com> writes:

> On Tue, Oct 30, 2012 at 12:17:35PM +0000, Leo Butler wrote:
>> > I notice it does not really work with the trig equations
>> > though. Probably because solve () only gives one real solution and
>> > %solve gives a solution in the form of union. 
>> >
>> > Is it best for now just to sub values into those general solutions from
>> > %solve () by hand? 
>> 
>> This is difficult for me to say, partly because I don't use %solve,
>> partly because I think that the output of %solve is a little difficult
>> to manipulate. However, to my mind, it should be possible to handle most
>> cases programmatically.
>
> Hi Leo, 
>
> Yes, I understand - it does seem more difficult to manipulate. 
>
>> If you could give the list an example where the solution involves arbitary
>> parameters, maybe someone could pipe in.
>
> So do you mean something like this?
> %solve(sin(x)=1/2,x);
>
> (%o2) %union([x = 2*%pi*%z6+%pi/6],[x = 2*%pi*%z8+5*%pi/6])
> (%i3) f(%z6):=2*%pi*%z6+%pi/6;
>
> (%o3) f(%z6):=2*%pi*%z6+%pi/6
> (%i4) g(%z8):=2*%pi*%z8+5*%pi/6;
>
> (%o4) g(%z8):=2*%pi*%z8+5*%pi/6
> /* find solutions in the domain -2*%pi to 2*%pi */
> (%i6) f(-1);
>
> (%o6) -11*%pi/6
> (%i7) f(0);
>
> (%o7) %pi/6
> (%i10) g(-1);
>
> (%o10) -7*%pi/6
> (%i11) g(0);
>
> (%o11) 5*%pi/6
>
> Not really sure if this is what you meant though. I also sometimes sub
> values outside the domain into the functions such as -2 in f() to try
> and find the last solution. So if somehow there is a way to get this
> done automatically it would be quite handy. i.e. all real solutions
> between -2*%pi and 2*%pi.

Hi Dan,
Try the following. I have just extended solve_in_domain to make each
solution from %solve into a function, like you have done manually, then
evaluate that function on a list of candidate integers bounded by imin &
imax (default is 0 and 0; you can set them as arguments, see the last
example below).

Note the code will barf on solutions that have more than one arbitrary
parameter. I don't know how often that will arise for your problems.


indomain(d) ::= buildq([d:d], lambda([x],every(is,d)));

filter(x,p) := block([l:[]],for t in x do if p(t) then l:append([t],l),l);
solve:%solve;

solve_in_domain(eq,var,d,[bounds]) :=
block([f,s,sols,imin:0,imax:0,vars],
  vars:lambda([x],[first(append(listofvars(x),[%z]))]),
  for b in bounds do lhs(b) :: rhs(b),
  f:if listp(d) then apply(indomain,[d]) else d,
  s:map(rhs,flatten(args(apply(solve,[eq,var])))),
  s:map(lambda([x],apply(lambda,[vars(x),x])),s),
  sols:[],
  for t in s do
  sols:append(sols,filter(map(t,makelist(i,i,imin,imax)),f)),
  map(lambda([t],var=t),listify(setify(sols))));

solve_in_domain((x-2)*(x+1),x,[x<3,x>0]);
is(%=[x=2]);
solve_in_domain((x-2)*(x+1),x,lambda([x],is((x<0 and x>=-1) or (x<=3 and x>=0))));
is(%=[x=-1,x=1]);

solve_in_domain(sin(x)=1/2,x,[x<=%pi,x>-%pi]);

solve_in_domain(sin(x)=1/2,x,[x<=%pi,x>-10*%pi],imin=,imax=100);


-- 
Leo Butler                <l_butler at users.sourceforge.net>
SDF Public Access UNIX System -   http://sdf.lonestar.org