What is the correct way to select real solutions? - maple

Suppose one needs to select the real solutions after solving some equation.
Is this the correct and optimal way to do it, or is there a better one?
restart;
mu := 3.986*10^5; T:= 8*60*60:
eq := T = 2*Pi*sqrt(a^3/mu):
sol := solve(eq,a);
select(x->type(x,'realcons'),[sol]);
I could not find real as type. So I used realcons. At first I did this:
select(x->not(type(x,'complex')),[sol]);
which did not work, since in Maple 5 is considered complex! So ended up with no solutions.
type(5,'complex');
(* true *)
Also I could not find an isreal() type of function. (unless I missed one)
Is there a better way to do this that one should use?
update:
To answer the comment below about 5 not supposed to be complex in maple.
restart;
type(5,complex);
true
type(5,'complex');
true
interface(version);
Standard Worksheet Interface, Maple 18.00, Windows 7, February
From help
The type(x, complex) function returns true if x is an expression of the form
a + I b, where a (if present) and b (if present) are finite and of type realcons.

Your solutions sol are all of type complex(numeric). You can select only the real ones with type,numeric, ie.
restart;
mu := 3.986*10^5: T:= 8*60*60:
eq := T = 2*Pi*sqrt(a^3/mu):
sol := solve(eq,a);
20307.39319, -10153.69659 + 17586.71839 I, -10153.69659 - 17586.71839 I
select( type, [sol], numeric );
[20307.39319]
By using the multiple argument calling form of the select command we here can avoid using a custom operator as the first argument. You won't notice it for your small example, but it should be more efficient to do so. Other commands such as map perform similarly, to avoid having to make an additional function call for each individual test.
The types numeric and complex(numeric) cover real and complex integers, rationals, and floats.
The types realcons and complex(realcons) includes the previous, but also allow for an application of evalf done during the test. So Int(sin(x),x=1..3) and Pi and sqrt(2) are all of type realcons since following an application of evalf they become floats of type numeric.
The above is about types. There are also properties to consider. Types are properties, but not necessarily vice versa. There is a real property, but no real type. The is command can test for a property, and while it is often used for mixed numeric-symbolic tests under assumptions (on the symbols) it can also be used in tests like yours.
select( is, [sol], real );
[20307.39319]
It is less efficient to use is for your example. If you know that you have a collection of (possibly non-real) floats then type,numeric should be an efficient test.
And, just to muddy the waters... there is a type nonreal.
remove( type, [sol], nonreal );
[20307.39319]

The one possibility is to restrict the domain before the calculation takes place.
Here is an explanation on the Maplesoft website regarding restricting the domain:
4 Basic Computation
UPD: Basically, according to this and that, 5 is NOT considered complex in Maple, so there might be some bug/error/mistake (try checking what may be wrong there).
For instance, try putting complex without quotes.
Your way seems very logical according to this.
UPD2: According to the Maplesoft Website, all the type checks are done with type() function, so there is rather no isreal() function.

Related

Access variable after its assumptions are cleared

After this
restart; about(x); assume(x>0); f:=3*x; x:='x': about(x);
Originally x, renamed x~:
is assumed to be: RealRange(Open(0),infinity)
f := 3*x~
x:
nothing known about this object
I can use indets to access the variable x (looks like it's still x~ in f), for example
eval(f,indets(f)[1]=2);
6
but it's not efficient when f has many variables. I've tried to access variable x (or x~) directly, but it didn't work:
eval(f,x=2);
eval(f,x~=2);
eval(f,'x'=2);
eval(f,'x~'=2);
eval(f,`x`=2);
eval(f,`x~`=2);
eval(f,cat(x,`~`)=2);
since the result in all those cases was 3*x~ (not 6).
Is there a way to access a specific variable directly (i.e. without using indets) after its assumptions are cleared?
There is no direct way, if utilizing assume, without programatically extracting/converting/replacing the assumed names in the previously assigned expression.
You can store the (assumed) name in another variable, and utilize that -- even after unassigning x.
Or you can pick off the names (including previously assumed names) from f using indets -- even after unassigning x.
But both of those are awkward, and it gets more cumbersome if there are many such names.
That is one reason why some people prefer to utilize assuming instead of the assume facility.
You can construct lists/sets/sequences of the relevant assumptions, and then re-utilize those in multiple assuming instances. But the global names are otherwise left alone, and your problematic mismatch situation avoided.
Another alternative is to utilize the command Physics:-assume instead of assume.
Here's an example. Notice that the assumption that x is positive still allows some simplification that depend upon it.
restart;
Physics:-Assume(x>0);
{x::(RealRange(Open(0),
infinity))}
about(x);
Originally x, renamed x:
is assumed to be:
RealRange(Open(0),infinity)
f:=3*x;
f := 3 x
simplify(sqrt(x^2));
x
Physics:-Assume('clear'={x});
{}
about(x);
x:
nothing known about this object
eval(f, [x=2]);
6
As for handling the original example utilizing assume, and substituting in f for the (still present, assumed names), it can be done programmatically to alleviate some awkwardness with, say, a larger set of assumptions. For example,
restart;
# re-usable utility
K:=(e,p)->eval(e,
eval(map(nm->nm=parse(sprintf("%a",nm)),
indets(e,And(name,
satisfies(hasassumptions)))),
p)):
assume(x>0, y>0, t<z);
f:=3*x;
f := 3 x
g:=3*x+y-sin(t);
g := 3 x + y - sin(t)
x:='x': y:='y': t:='t':
K(f,[x=2]);
6
K(g,[x=2,y=sqrt(2),t=11]);
(1/2)
6 + 2 - sin(11)

Julia: Macros for vector aliasing

I want to be able to allow users of my package to define functions in a more mathematical manner, and I think a macro is the right direction. The problem is as follows. The code allows the users to define functions which are then used in specialized solvers to solve PDEs. However, to make things easier for the solver, some of the inputs are "matrices" in ways that you wouldn't normally wouldn't think they would be. For example, the solvers can take in functions f(x,t), but x[:,1] is what you'd think of as x and x[:,2] is what you'd think of as y (and sometimes it is 3D).
The bigger issues is that when the PDE is nonlinear, I place everything in a u vector, when in many cases (like Reaction-Diffusion equations) these things are named. So in this general case, I'd like to be able to write
#mathdefine f(RA,RABP,RAR,x,y,t) = RA*RABP + RA*x + RAR*t
and have it translate to
f(u,x,t) = u[:,1].*u[:,2] + u[:,1].*x[:,1] + u[:,3]*t
I am not up to snuff on my macro-foo, so I was hoping someone could get me started (or if macros are not the right way to approach this, explain why).
It's not too hard if the user has to give what is being translated to what, but I'd like to have it be as clean to use as possible, so somehow know that it's to the spatial variables and so everything before is part of a u, but after is part of x.
The trick to macro "find/replace" is just to pass off processing to a recursive function that updates the expression args. Your signature will come in as a bunch of symbols, so you can loop through the call signature and add to two dicts, mapping variable name to column index. Then recursively replace the arg tree when you see any of the variables. This is untested:
function replace_vars!(expr::Expr, xd::Dict{Symbol,Int}, ud::Dict{Symbol,Int})
for (i,arg) in enumerate(expr.args)
if haskey(xd, arg)
expr.arg[i] = :(x[:,$(xd[arg])])
elseif haskey(ud, arg)
expr.arg[i] = :(u[:,$(ud[arg])])
elseif isa(arg,Expr)
replace_vars!(arg, xd, ud)
end
end
end
macro mathdefine(expr)
# todo: loop through function signature (expr.args[1]?) to build xd/ud
replace_vars!(expr)
expr
end
I left a little homework for you, but this should get you started.

How do I get MuPAD to stop using placeholders for matrix elements?

I'm trying to evaluate some matrix multiplications in MuPAD. The output is using sigmas as placeholders for the matrix elements since they are long expressions (I assume that's the reason). Is there a way to get MuPAD to display the individual matrix elements as (in my case) the exponential functions that they really are, regardless of the length of the expression?
Below is an example of a case where MuPAD is using sigmas instead of the actual exponential functions. I would like to be able to see what the individual matrix elements of TotT^4 really are.
The commands I executed in the MuPAD interface that lead up to TotT^4 are:
T1 := matrix([[exp((J+B/2)/T),exp(-(J+B/6)/T)],[exp((-J+B/6)/T),exp((J-B/2)/T)]])
T2 := matrix([[exp((J1+B/2)/T),exp(-(J1+B/6)/T)],[exp((-J1+B/6)/T),exp((J1-B/2)/T)]])
T1d := linalg::transpose(T1)
TotT := T1d*T2
The class of your variable can be obtain via type(totT): Dom::Matrix. You may want to look at the many methods of this class in the documentation. As far as I can tell, this issue has something to do with the pretty printing of the class's print method. Other classes exhibit this same substitution, so it may be a function of the overloaded print. I was not able to change the behavior by adjusting setPrintMaxSize, PRETTYPRINT, TEXTWIDTH, or any of the optional arguments to print. You might still try yourself as there are many permutations.
I also tried using the expand function. expand(TotT,IgnoreAnalyticConstraints) nearly works though it could have undesirable effects in some cases if things were expanded too much. Calling simplify does get rid go the substitutions, but it also changes the nature of some of the entries by simplifying. It is probably also not a general solution to this issue.
One way that does work, but is ugly, is to use the expr2text method, which returns a result as a string:
expr2text(TotT)
which returns
"matrix([[exp((B/6 - J)/T)*exp((B/6 - J1)/T) + exp((B/2 + J)/T)*exp((B/2 + J1)/T), ...
exp(-(B/2 - J1)/T)*exp((B/6 - J)/T) + exp((B/2 + J)/T)*exp(-(B/6 + J1)/T)], ...
[exp(-(B/2 - J)/T)*exp((B/6 - J1)/T) + exp((B/2 + J1)/T)*exp(-(B/6 + J)/T), ...
exp(-(B/2 - J)/T)*exp(-(B/2 - J1)/T) + exp(-(B/6 + J)/T)*exp(-(B/6 + J1)/T)]])"
I think that this question would be a good one to ask over at Matlab Central or by filing a service request if you have a license with support.

Simplify boolean expression i.t.o variable occurrence

How to simplify a given boolean expression with many variables (>10) so that the number of occurrences of each variable is minimized?
In my scenario, the value of a variable has to be considered ephemeral, that is, has to recomputed for each access (while still being static of course). I therefor need to minimize the number of times a variable has to be evaluated before trying to solve the function.
Consider the function
f(A,B,C,D,E,F) = (ABC)+(ABCD)+(ABEF)
Recursively using the distributive and absorption law one comes up with
f'(A,B,C,E,F) = AB(C+(EF))
I'm now wondering if there is an algorithm or method to solve this task in minimal runtime.
Using only Quine-McCluskey in the example above gives
f'(A,B,C,E,F) = (ABEF) + (ABC)
which is not optimal for my case. Is it save to assume that simplifying with QM first and then use algebra like above to reduce further is optimal?
I usually use Wolfram Alpha for this sort of thing.
Try Logic Friday 1
It features multi-level design of boolean circuits.
For your example, input and output look as follows:
You can use an online boolean expression calculator like https://www.dcode.fr/boolean-expressions-calculator
You can refer to Any good boolean expression simplifiers out there? it will definitely help.

How to check if the value is a number in Prolog manually?

How to check if the given value is a number in Prolog without using built-in predicates like number?
Let's say I have a list [a, 1, 2, 3]. I need a way to check if every element within this list is a number. The only part of the problem that bothers me is how to do the check itself without using the number predicate.
The reason why I'm trying to figure this out is that I've got a college assignment where it's specifically said not to use any of the built-in predicates.
You need some built-in predicate to solve this problem - unless you enumerate all numbers explicitly (which is not practical since there are infinitely many of them).
1
The most straight-forward would be:
maplist(number, L).
Or, recursively
allnumbers([]).
allnumbers([N|Ns]) :-
number(N),
allnumbers(Ns).
2
In a comment you say that "the value is given as an atom". That could mean that you get either [a, '1', '2'] or '[a, 1, 2]`. I assume the first. Here again, you need a built-in predicate to analyze the name. Relying on ISO-Prolog's errors we write:
numberatom(Atom) :-
atom_chars(Atom, Chs),
catch(number_chars(_, Chs), error(syntax_error(_),_), false).
Use numberatom/1 in place of number/1, So write a recurse rule or use maplist/2
3
You might want to write a grammar instead of the catch... goal. There have been many such definitions recently, you may look at this question.
4
If the entire "value" is given as an atom, you will need again atom_chars/2or you might want some implementation specific solution like atom_to_term/3 and then apply one of the solutions above.