Chronaxis用户手册English
本页目录

chronaxis.core.where_updates

源码基线:8904c2f744951857659abd40aaa3535d57faf53c

1"""按 where 当前选择判断某一组是否更新输出,独立于输出的数值是否改变。23输入是原子提交后的输入、同一时刻排除该组的旧输入,以及各别名的真实更新标志。4只在条件实际更新时比较前后选择;因此仅刷新有效条件不会采样,失效后恢复会采样。5普通算子取各参数更新并集,嵌套选择递归套用同一协议;不保存时间历史。6"""789def contains_where(root):10    """检查已编译 DAG 是否需要分支更新口径。参数: 根节点。返回: bool。异常: 非法节点。"""11    pending, seen = [root], set()12    while pending:13        node = pending.pop()14        if node.operator == 'where':15            return True16        if id(node) not in seen:17            seen.add(id(node))18            pending.extend(node.args)19    return False202122def reference_updates(root, current, before, updates):23    """按原子组计算标量更新标志。2425    参数: 根节点、当前/组前标量映射和真实更新标志;内部传 before=None 仅判断活动性。26    返回: 是否存在活动更新。异常: 输入/节点与绑定不符时沿用标量表达式核错误。27    """28    from .expression_reference import _evaluate2930    now_cache, old_cache, flags = {}, {}, {}3132    def visit(node):33        """判断当前活动路径。参数: 子树节点。返回: bool。异常: 同外层求值。"""34        if node not in flags:35            if node.operator == 'name':36                flag = updates[node.name]37            elif node.operator == 'where':38                condition, when_true, when_false = node.args39                now = _evaluate(condition, current, now_cache).value40                changed = visit(condition)41                if before is None:42                    flag = changed or (now.valid and visit(when_true if now.value else when_false))43                elif not now.valid:44                    flag = changed45                else:46                    # 当前分支即使数值相同也采样;条件刷新则须有切换或恢复。47                    flag = visit(when_true if now.value else when_false)48                    if changed and not flag:49                        old = _evaluate(condition, before, old_cache).value50                        flag = not old.valid or old.value != now.value51            else:52                flag = any(visit(arg) for arg in node.args)53            flags[node] = flag54        return flags[node]5556    return bool(visit(root))575859def numpy_updates(root, current, before, updates, size):60    """以 NumPy 活动子批检查整列更新证据,不逐点解释。6162    参数: 根节点、当前/组前列映射、别名的更新列、行数;内部 before=None 时仅判断活动性。63    返回: 一维布尔列。异常: 原数组布局/求值错误传播。64    """65    import numpy as np66    from .expression_numpy import _evaluate67    from .numeric_numpy import NumericArray6869    def condition_at(node, inputs, indices):70        """按活动行解释。参数: 条件子树、输入列及行号。返回: BOOL 列。异常: 数组求值错误。"""71        columns = {}72        for name in node.aliases:73            col = inputs[name]74            columns[name] = col.take(indices)75        return _evaluate(node, columns, len(indices), {}).value7677    def visit(node, indices, cache):78        """同一活动行集内复用证据。参数: 子树、行号、局部缓存。返回: 布尔列。异常: 数组错误。"""79        if node in cache:80            return cache[node]81        flag = np.zeros(len(indices), dtype=bool)82        if node.operator == 'name':83            flag = updates[node.name][indices]84        elif node.operator == 'where' and len(indices):85            condition, when_true, when_false = node.args86            now = condition_at(condition, current, indices)87            changed = visit(condition, indices, cache)88            flag |= changed if before is None else changed & ~now.valid89            for selected, branch in ((now.values, when_true), (~now.values, when_false)):90                rows = now.valid & selected91                if np.any(rows):92                    flag[rows] |= visit(branch, indices[rows], {})93            # 仅比较有效条件刷新且未被活动分支更新证明的剩余行。94            rows = changed & now.valid & ~flag95            if before is not None and np.any(rows):96                old = condition_at(condition, before, indices[rows])97                flag[rows] |= ~old.valid | (old.values != now.values[rows])98        else:99            for arg in node.args:100                flag |= visit(arg, indices, cache)101        cache[node] = flag102        return flag103104    return visit(root, np.arange(size), {})105106107def reference_active(root, current, flags):108    """只检查活动输入。参数: 根节点、当前标量、别名标志。返回: bool。异常: 标量求值错误。"""109    return reference_updates(root, current, None, flags)110111112def numpy_active(root, current, flags, size):113    """按活动子批检查输入。参数: 根节点、当前列、标志列、长度。返回: 布尔列。异常: 数组错误。"""114    return numpy_updates(root, current, None, flags, size)115
Chronaxis 用户手册 · 离线阅读