Simplify boolean expression i.t.o variable occurrence - boolean

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.

Related

Julia - n-nested loops

Im trying to make a n-nested loop method in Julia
function fun(n::Int64)
#nloops n i d->1:3 begin\n
#nexprs n j->(print(i_j))\n
end
end
But the #nloops definition is limited to
_nloops(::Int64, ::Symbol, ::Expr, ::Expr...)
and I get the error
_nloops(::Symbol, ::Symbol, ::Expr, ::Expr)
Is there any way to make this work? Any help greatly appreciated
EDIT:
What I ended up doing was using the combinations method
For my problem, I needed to get all k-combinations of indices to pull values from an array, so the loops would had to look like
for i_1 in 1:100
for i_2 in i_1:100
...
for i_k in i_[k-1]:100
The number of loops needs to be a compile-time constant – a numeric literal, in fact: the code generated for the function body cannot depend on a function argument. Julia's generated functions won't help either since n is just a plain value and not part of the type of any argument. Your best bet for having the number of nested loops depend on a runtime value like n is to use recursion.
In julia-0.4 and above, you can now do this:
function fun(n::Int)
for I in CartesianRange(ntuple(d->1:3, n))
#show I
end
end
In most cases you don't need the Base.Cartesian macros anymore (although there are still some exceptions). It's worth noting that, just as described in StefanKarpinski's answer, this loop will not be "type stable" because n is not a compile-time constant; if performance matters, you can use the "function barrier technique." See http://julialang.org/blog/2016/02/iteration for more information about all topics related to these matters.

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 single and double type variables work in the same copy of code in Matlab like template in C++

I am writing a signal processing program using matlab. I know there are two types of float-pointing variables, single and double. Considering the memory usage, I want my code to work with only single type variable when the system's memory is not large, while it can also be adapted to work with double type variables when necessary, without significant modification (simple and light modification before running is OK, i.e., I don't need runtime-check technique). I know this can be done by macro in C and by template in C++. I don't find practical techniques which can do this in matlab. Do you have any experience with this?
I have a simple idea that I define a global string containing "single" or "double", then I pass this string to any memory allocation method called in my code to indicate what type I need. I think this can work, I just want to know which technique you guys use and is widely accepted.
I cannot see how a template would help here. The type of c++ templates are still determined in compile time (std::vector vec ...). Also note that Matlab defines all variables as double by default unless something else is stated. You basically want runtime checks for your code. I can think of one solution as using a function with a persistent variable. The variable is set once per run. When you generate variables you would then have to generate all variables you want to have as float through this function. This will slow down assignment though, since you have to call a function to assign variables.
This example is somehow an implementation of the singleton pattern (but not exactly). The persistent variable type is set at the first use and cannot change later in the program (assuming that you do not do anything stupid as clearing the variable explicitly). I would recommend to go for hardcoding single in case performance is an issue, instead of having runtime checks or assignment functions or classes or what you can come up with.
function c = assignFloat(a,b)
persistent type;
if (isempty(type) & nargin==2)
type = b;
elseif (isempty(type))
type = 'single';
% elseif(nargin==2), error('Do not set twice!') % Optional code, imo unnecessary.
end
if (strcmp(type,'single'))
c = single(a);
return;
end
c = double(a);
end

What is the correct way to select real solutions?

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.

How can I make the value of an expression equal to a second return value of another expression

Is there an idiomatic way in Matlab to bind the value of an expression to the nth return value of another expression?
For example, say I want an array of indices corresponding to the maximum value of a number of vectors stored in a cell array. I can do that by
function I = max_index(varargin)
[~,I]=max(varargin{:});
cellfun(#max_index, my_data);
But this requires one to define a function (max_index) specific for each case one wants to select a particular return value in an expression. I can of course define a generic function that does what I want:
function y = nth_return(n,fun,varargin)
[vals{1:n}] = fun(varargin{:});
y = vals{n};
And call it like:
cellfun(#(x) nth_return(2,#max,x), my_data)
Adding such functions, however, makes code snippets less portable and harder to understand. Is there an idiomatic to achieve the same result without having to rely on the custom nth_return function?
This is as far as I know not possible in another way as with the solutions you mention. So just use the syntax:
[~,I]=max(var);
Or indeed create an extra function. But I would also suggest against this. Just write the extra line of code, in case you want to use the output in another function. I found two earlier questions on stackoverflow, which adress the same topic, and seem to confirm that this is not possible.
Skipping outputs with anonymous function in MATLAB
How to elegantly ignore some return values of a MATLAB function?
The reason why the ~ operator was added to MATLAB some versions ago was to prevent you from saving variables you do not need. If there would be a syntax like the one you are searching for, this would not have been necessary.