I have 2 types of fuzzy function => triangle and trapazoid .. the triangle function take value and 3 points ( a,b,c's of triangle) and the trapazoid take value and 4 points ( a,b,c,d's of trapazoid )
i use the line equation to calculate the fuzzy value but the problem here is that function work if the points of set is like that [0,10,20,30] or [10,20,30,40] but when the set is [0,0,10,20] i got error cause of dividing on zero so it is possible to solve this problem using this equations This is triangle equation
def triangular(x, a, b, c):
return max(min((x - a) / (b - a), (c - x) / (c - b)), 0)
def trap(x, a, b, c, d):
return max(min((x - a) / (b - a), 1, (d - x) / (d - c)), 0)
Instead of using one mathematical expression, it may be easier to implement such membership functions using conditionals, and check for such conditions explicitly. It might also make sense to "sanity check" the incoming parameters, for example to make sure that they are strictly increasing.
Related
I'm trying to simplify some expressions of positive odd integers with sympy. But sympy refuses to expand floor, making the simplification hard to proceed.
To be specific, x is a positive odd integer (actually in my particular use case, the constraint is even stricter. But sympy can only do odd and positive, which is fine). x // 2 should be always equal to (x - 1) / 2. Example code here:
from sympy import Symbol, simplify
x = Symbol('x', odd=True, positive=True)
expr = x // 2 - (x - 1) / 2
print(simplify(expr))
prints -x/2 + floor(x/2) + 1/2. Ideally it should print 0.
What I've tried so far:
Simplify (x - 1) // 2 - (x - 1) / 2. Turns out to be 0.
Multiply the whole thing by 2: 2 * (x // 2 - (x - 1) / 2). Gives me: -x + 2*floor(x/2) + 1.
Try to put more weights on the FLOOR op by customizing the measure. No luck.
Use sympy.core.evaluate(False) context when creating the expression. Nuh.
Tune other parameters like ratio, rational, and play with other function like expand, factor, collect. Doesn't work either.
EDIT: Wolfram alpha can do this.
I tried to look like the assumptions of x along with some expressions. It surprises me that (x - 1) / 2).is_integer returns None, which means unknown.
I'm running out of clues. I'm even looking for alternativese of sympy. Any ideas guys?
I fail to see why sympy can't simplify that.
But, on another hand, I've discovered the existence of odd parameter just now, with your question.
What I would have done, without the knowledge of odd is
k = Symbol('k', positive=True, integer=True)
x = 2*k-1
expr = x // 2 - (x - 1) / 2
Then, expr is 0, without even the need to simplify.
So, can't say why you way doesn't work (and why that odd parameter exists if it is not used correctly to guess that x-1 is even, and therefore (x-1)/2 integer). But, in the meantime, my way of defining an odd integer x works.
There is some reluctance to make too much automatic in SymPy, but this seems like a case that could be addressed (since (x-1)/2 is simpler than floor(x/2). Until then, however, you can run a replacement on your expression which makes this transformation for you.
Let's define a preferred version of floor:
def _floor(x):
n, d = x.as_numer_denom()
if d == 2:
if n.is_odd:
return (n - 1)/2
if n.is_even:
return n/2
return floor(x)
When you have an expression with floor that you want to evaluate, replace floor with _floor:
>>> x = Symbol('x', odd=True)
>>> eq=x // 2 - (x - 1) / 2
>>> eq.replace(floor, _floor)
0
Given a SymPy function f(x) and values a, b (a != b), is there a way to find the minimum and maximum value of f(x) on this interval? I’ve found some code for finding extremums that can be adapted for this purpose (split them into a min and max array, find lowest and highest respectively values with lambdify and use them), but surely there must be an easier way?
An alternative option would be using a np.linspace, but then I might miss out on exact values, which would be bad for things I have to do with them next.
As now noted in the cited page, since this PR you should be able to do the following:
from sympy.calculus.util import *
f = (x**3 / 3) - (2 * x**2) - 3 * x + 1
ivl = Interval(0, 3) # e.g. your (a, b)
print(minimum(f, ivl))
print(maximum(f, ivl))
We can easily find:
a=7
b=8
c=a|b
Then c comes out to be: 15
Now can we find a if c is given?
For example:
b=8
c=15
c=a|b
Find a?
And also if x=2<<1 is given, then we can get x=4. But if 4=y<<1 is given Can we get y?
To begin with, these are just my observations and I have no sources to back them up. There are better ways, but the Wikipedia pages were really long and confusing so I hacked together this method.
Yes, you can, but you need more context (other equations to solve in reference to) and a lot more parsing. This is the method I came up with for doing this, but there are better ways to approach this problem. This was just conceptually easier for me.
Numbers
You can't just put an integer into an equation and have it work. Bitwise operators refer only refer to booleans, we just treat them as if they are meant for integers. In order to simplify an equation, we have to look at it as an array of booleans.
Taking for example an unsigned 8 bit integer:
a = 0b10111001
Now becomes:
a = {1, 0, 1, 1, 1, 0, 0, 1}
Parsing
Once you can get your equations to just booleans, then you can apply the actual bitwise operators to simple 1s and 0s. But you can take it one step further now, at this all bitwise equations can be written in terms of just AND, OR, and NOT. Addition, subtraction and multiplication can also be represented this way, but you need to manually write out the steps taken.
A ^ B = ~( ( A & B ) | ( (~A) & (~B) ) )
This includes bitshifts, but instead of expanding to other bitwise operators, they act as an assignment.
A = 0b10111001
B = 0b10100110
C = (A >> 2) ^ B
This then expands to 8 equations, one for each bit.
C[0] = A[2] ^ B[0]
C[1] = A[3] ^ B[1]
C[2] = A[4] ^ B[2]
C[3] = A[5] ^ B[3]
C[4] = A[6] ^ B[4]
C[5] = A[7] ^ B[5]
C[6] = 0 ^ B[6]
C[7] = 0 ^ B[7]
C[6] and C[7] can then be reduced to just B[6] and B[7] respectively.
Algebra
Now that you have an equation consisting of only AND, OR, and NOT, you can represent them using traditional algebra. In this step, they are no longer treated as bits, but instead as real numbers which just happen to be 0 or 1.
A | B => A + B - AB
A & B => AB
~A => 1 - A
Note that when plugging in 1 and 0, all of these remain true.
For this example, I will be using the Majority function as an example. It's job is to take in three bits and return 1 if there are more 1s than 0s.
It is defined as:
f(a, b, c) = ((a & b) | (a & c) | (b & c))
which becomes
f(a, b, c) = (ab + ac - (ab * ac)) + bc - (ab + ac - (ab * ac) * bc
f(a, b, c) = ab + ac + bc - a2bc - ab2c - abc2 + a2b2c2
And now that you have this information, you can easily combine it with your other equations using standard algebra in order to get a solution. Any non 1 or 0 solution is extraneous.
A solution (if it exists) of such equation can be considered "unique" provided that you allow three states for each bit:
bit is 0
bit is 1
does not matter X
E.g. 7 | 00001XXX(binary) = 15
Of course, such result cannot be converted to decimal.
For some operations it may be necessary to specify the bit width.
For your particular cases, the answer is no, you cannot solve or 'undo' the OR-operation (|) and shifting left or right (<<, >>) since in both cases information is lost by applying the operation. For example, 8|7=15 and 12|7=15, thus given the 7 and 15 it is not possible to obtain a unique solution.
An exception is the XOR operation, for which does hold that when a^b=c, then b^c=a and a^c=b.
you can find an a that solves the equation, but it will not be unique. assume b=c=1 then a=0 and a=1 are solutions. for c=1, b=0 there will be no solution. this is valid for all the bits in the numbers you consider. if the equation is solvable a=c will be (one of the) solution(s).
and left-shifting an integer will always result in an even integer (the least-significant bit is zero). so this only works for even itegers. in that case you can invert the operation by applying a right-shift (>>).
I am using the sympy library for python3, and I am handling equations, such as the following one:
a, b = symbols('a b', positive = True)
my_equation = Eq((2 * a + b) * (a - b) / 2, 0)
my_equations gets printed exactly as I have defined it ((2 * a + b) * (a - b) / 2 == 0, that is), and I am unable to reduce it even using simplify or similar functions.
What I am trying to achieve is simplifying the nonzero factors from the equation (2 * a + b and 1 / 2); ideally, I'd want to be able to simplify a - b as well, if I am sure that a != b.
Is there any way I can reach this goal?
The point is that simplify() is not capable (yet) of complex reasoning about assumptions. I tested it on Wolfram Mathematica's simplify, and it works. It looks like it's a missing feature in SymPy.
Anyway, I propose a function to do what you're looking for.
Define this function:
def simplify_eq_with_assumptions(eq):
assert eq.rhs == 0 # assert that right-hand side is zero
assert type(eq.lhs) == Mul # assert that left-hand side is a multipl.
newargs = [] # define a list of new multiplication factors.
for arg in eq.lhs.args:
if arg.is_positive:
continue # arg is positive, let's skip it.
newargs.append(arg)
# rebuild the equality with the new arguments:
return Eq(eq.lhs.func(*newargs), 0)
Now you can call:
In [5]: simplify_eq_with_assumptions(my_equation)
Out[5]: a - b = 0
You can easily adapt this function to your needs. Hopefully, in some future version of SymPy it will be sufficient to call simplify.
I am trying to use negative of scipy.optimize.minimize to maximize a function f (a, b, c, d). d is a numpy.array of guess variables.
I am trying to put some bounds on each d. And also a constraint on each d such that (d1 * a1 + d2 * a2 + ... + d3 * a3) < some_Value (a being the other argument to the subject function f).
My problem is how do I define this constraint as an argument to the maximize function.
I could not find any maximize function in the library so we're using the negative of minimize with minimize documentation over here.
Please consider asking for clarifications if the question is not clear enough.
It's not totally clear from your description which of the parameters of f you are optimizing over. For the purposes of this example I'm going to use x to refer to the vector of parameters you are optimizing over, and a to refer to another parameter vector of the same length which is held constant.
Now let's suppose you wanted to enforce the following inequality constraint:
10 <= x[0] * a[0] + x[1] * a[1] + ... + x[n] * a[n]
First you must define a function that accepts x and a and returns a value that is non-negative when the constraint is met. In this case we could use:
lambda x, a: (x * a).sum() - 10
or equivalently:
lambda x, a: x.dot(a) - 10
Constraints are passed to minimize in a dict (or a sequence of dicts if you have multiple constraints to apply):
con = {'type': 'ineq',
'fun': lambda x, a: a.dot(x) - 10,
'jac': lambda x, a: a,
'args': (a,)}
For greater efficiency I've also defined a function that returns the Jacobian (the sequence of partial derivatives of the constraint function w.r.t. each parameter in x), although this is not essential - if unspecified it will be estimated via first-order finite differences.
Your call to minimize would then look something like:
res = minimize(f, x0, args=(a,), method='SLSQP', constraints=con)
You can find another complete example of constrained optimization using SLSQP in the official documentation here.