def eval(guess, nam, x, y, ff, var, sigma): f = ff.copy() for g, n in zip(guess, nam): f = f.applyvar(n, fmath.value(g)) try: fx = [f.eval(**{var: xx}) for xx in x] except: return 1e100 ret = 0.0 for a, b in zip(fx, y): ret += (abs(a) - abs(b))**2 return ret / len(y)
def validsolution(q, var=None): if var is None: var = INPUT_VAR solvable = var in q.listvar() # print("isin lv?",solvable) try: # for w in range(1): solvable = solvable and q.solvable() # print("generally solvable?",solvable) #NEED TO DIFFERENTIATE BETWEEN VARIABLES IN SOLVABLE (x-1 ist nicht solvable, aber c*x schon und x-c*x auch (input variables and functional constants #This is a very crude try for j in range(10): solvable = solvable and q.applyvar(var, fmath.value( random.random())).solvable() # print("random try?",solvable,q.applyvar(var,fmath.value(random.random()))) except: solvable = False return solvable
def diff(s, by) -> 'mult': return s.q.diff(by) / fmath.sqrt(fmath.value(1) + fmath.square(s.q))
return v._copywithparam(*ret) return v def minpos(s) -> "float(possibly inf)": minq = s.q.minpos() maxq = s.q.maxpos() if abs(maxq - minq) > math.pi: return float(-1) minqs = minq % (2 * math.pi) maxqs = maxq % (2 * math.pi) minq = min(minqs, maxqs) maxq = max(minqs, maxqs) if minq < 3 * math.pi / 2 and maxq > 3 * math.pi / 2: return -1.0 return min(math.sin(minq), math.sin(maxq)) def maxpos(s) -> "float(possibly inf)": minq = s.q.minpos() maxq = s.q.maxpos() if abs(maxq - minq) > math.pi: return float(1) minqs = minq % (2 * math.pi) maxqs = maxq % (2 * math.pi) minq = min(minqs, maxqs) maxq = max(minqs, maxqs) if minq < math.pi / 2 and maxq > math.pi / 2: return 1.0 return max(math.sin(minq), math.sin(maxq)) addtrafo("*", test_sincos, apply_sincos) addtrafo("sin", lambda v: v.q.evaluable() and v.q.eval() == 0.0, lambda v: fmath.value(0.0))
def diff(s, by) -> 'divide': return -s.q.diff(by) / fmath.sqrt(fmath.value(1) - fmath.square(s.q))
def simplify(s)->'param2': ret= s._copywithparam(s.q1.simplify(),s.q2.simplify()) if ret.evaluable():return fmath.value(ret.eval()) return ret
def diff(s, by) -> 'divide': return s.q.diff(by) / (fmath.value(1) + fmath.square(s.q))
m = minimize(eval, [random.random() for vv in v], args=(v, x, y, f, INPUT_VAR, sigma)) else: return eval([], [], x, y, f, INPUT_VAR, sigma), {} return m.fun, {a: b for a, b in zip(v, m.x)} if __name__ == "__main__": from importall import * from transform import * import trigonometrics import fmath f = fmath.exp(fmath.variable("a") * fmath.variable("x")) fs = f.copy() fs = fs.applyvar("a", fmath.value(3.0)) x = [i / 15.0 for i in range(15)] y = [fs.eval(x=xx) for xx in x] print("fitting", f, "to find", fs) ret, fit = autofit(x=x, y=y, f=f) print(fit) exit()
def __add__(a, b): return evofit(x=a.x, y=a.y, sigma=a.sigma, price=a.price, f=(a.f + b.f) / fmath.value(2))
def diff(s, by) -> 'fobj': if by in s.listvar(): #require diff+ return fmath.diff(s.copy(), by) else: return fmath.value(0.0)
s.q1, s.q2 = q def diff(s, by) -> 'subtr': return subtr(s.q1.diff(by), s.q2.diff(by)) def eval(s, **v) -> float: return s.q1.eval(**v) - s.q2.eval(**v) def gettyp(s) -> str: return "-" def _copywithparam(s, p1, p2) -> "param2": return subtr(p1, p2) def __str__(s) -> str: return "(" + str(s.q1) + s.gettyp() + str(s.q2) + ")" def huntident(s) -> "fobj": if s.q2.evaluable() and s.q2.eval() == 0.0: return s.q1.huntident() return param2.huntident(s) def minpos(s) -> "float(possibly inf)": return s.q1.minpos() - s.q2.maxpos() def maxpos(s) -> "float(possibly inf)": return s.q1.maxpos() - s.q2.minpos() register(subtr(0, 0)) addtrafo("-", lambda v: v.q1 == v.q2, lambda v: fmath.value(0.0))
def simplify(s)->'fobj': if s.what.evaluable() and s.what==0.0:return fmath.value(0.0) if not s.by in s.what.listall(): return s.what*(s.too-s.fro) return s._copywithparam(s.what.simplify(),s.by,s.fro.simplify(),s.too.simplify())