def search_param_(param_name, param):

    ddert_, mdert_ = [], []  # line-wide (i, p, d, m)_, + (negL, negM) in mdert: variable-range search
    rdn = param[1]
    param_ = param[0]
    _param, _L, _x0 = param_[0]

    for i, (param, L, x0) in enumerate(param_[1:], start=1):
        dert = comp_param(_param, param, param_name, ave/rdn)  # param is compared to prior-P param

        ddert_.append(dert)
        negL = negM = 0
        comb_M = dert.m
        j = i
        while comb_M > 0 and j+1 < len(param_):
            j += 1
            ext_param, ext_L, ext_x0 = param_[j]  # extend search beyond next param
            dert = comp_param(param, ext_param, param_name, ave)
            comb_M = dert.m + negM - ave / (1 - (negL / (negL + L + _L)))
            negM += dert.m
            negL += ext_L
        # after extended search, if any:
        mdert_.append( Cmdert( i=dert.i, p=dert.p, d=dert.d, m=dert.m, negL=negL, negM=negM))

        _param = param

    # Ppm_ = form_Pp_(mdert_)
    # Ppd_ = form_Pp_(ddert_

    param[0].append(([],[]))  # replace with ((Ppm_, Ppd_))
Exemple #2
0
def search_param_(param_name, iparam):

    ddert_, mdert_ = [], []  # line-wide (i, p, d, m)_, + (negL, negM) in mdert: variable-range search
    rdn = iparam[1]  # iparam = (param_, P.L, P.x0), rdn
    param_ = iparam[0]
    _param, _L, _x0 = param_[0]

    for i, (param, L, x0) in enumerate(param_[1:], start=1):
        # param is compared to prior-P param:
        dert = comp_param(_param, param, param_name, ave/rdn)
        # or div_comp(L), norm_comp(I, D, M): value conserve, mean doesn't?
        # -> splice or higher composition: preserve inputs?
        ddert_.append( Cpdert( i=dert.i, p=dert.p, d=dert.d, m=dert.m, x0=x0, L=L) )
        negL=negM=0  # comp next only
        comb_M = dert.m
        j = i
        while comb_M > 0 and j+1 < len(param_):
            j += 1
            ext_param, ext_L, ext_x0 = param_[j]  # extend search beyond next param
            dert = comp_param(param, ext_param, param_name, ave)
            if dert.m > 0:
                break  # 1st matching param takes over connectivity search from _param, in the next loop
            else:
                comb_M = dert.m + negM - ave_M  # adjust ave_M for relative continuity and similarity?
                negM += dert.m
                negL += ext_L
        # after extended search, if any:
        mdert_.append( Cpdert( i=dert.i, p=dert.p, d=dert.d, m=dert.m, x0=x0, L=L, negL=negL, negM=negM))
        _param = param

    Ppm_ = form_Pp_(mdert_, param_name, rdn, fPd=0)
    Ppd_ = form_Pp_(ddert_, param_name, rdn, fPd=1)

    iparam[0] = (Ppm_, Ppd_)
Exemple #3
0
def sub_search_param_(_P_, P_, ipdert):  # variable-range search
    # this is for single param only, most likely incorrect
    rave = 1
    for i, _P in enumerate(_P_):
        negM = 0  # per _P

        for j, P in enumerate(P_):
            if (_P.M + P.M) / 2 + ipdert.m + negM > ave_M:
                _pI = _P.I - (_P.D / 2)  # forward project by _D
                pI = P.I + (P.D / 2)  # backward project by D
                dert = comp_param(
                    _pI, pI, "I_",
                    ave_mI)  # param is compared to prior-P _param
                pdert = Cpdert(i=dert.i, p=dert.p, d=dert.d,
                               m=dert.m)  # convert Cdert to Cpdert
                ipdert.accumulate(sub_M=pdert.m, sub_D=pdert.d)

                curr_M = pdert.m * rave + (
                    _P.M + P.M) / 2  # P.M is bidirectional (include ipdert.m?)

                if curr_M > ave_sub:  # comp all sub_P_ params, for core I only?
                    comp_sublayers_draft(_P, P, pdert)  # should set dert.sub_M
                if curr_M + pdert.sub_M > ave_M:  # match between sublayers; or > ave_cM?
                    break  # 1st match takes over connectivity search in the next loop
                else:
                    pdert.negM += curr_M - ave_M  # known to be negative, accum per dert
                    pdert.negiL += P.L
                    pdert.negL += 1
                    negM = pdert.negM
Exemple #4
0
def form_comp_Derts(_P, P, root_v):

    subDertt_t = [[],
                  []]  # two comparands, each preserved for future processing
    # form Derts:
    for _sublayer, sublayer in zip(_P.sublayers, P.sublayers):
        for i, isublayer in enumerate([
                _sublayer, sublayer
        ]):  # list of subsets: index 0 = _P.sublayers, index 1 = P.sublayers
            nsub = 0
            for subset in isublayer:
                nsub += len(subset[2]) + len(
                    subset[3]
                )  # or nsub_t, for separate form mDert | dDert eval?
            if root_v * nsub > ave_M * 5:  # ave_Dert, separate eval for m and d?
                subDertt = [[0, 0, 0, 0],
                            [0, 0, 0, 0]]  # Pm,Pd' L,I,D,M summed in sublayer
                for rdn, rng, sub_rval_Pm_, sub_rval_Pd_, xsub_pmdertt_, xsub_pddertt_, _, _ in isublayer:  # current layer subsets
                    for j, sub_rval_P__ in enumerate(
                        [sub_rval_Pm_, sub_rval_Pd_]):  # j: Pm | Pd
                        for Rval, sub_rval_P_ in sub_rval_P__:
                            for rval, sub_rval_P in sub_rval_P_:
                                subDertt[j][0] += sub_rval_P.L
                                subDertt[j][1] += sub_rval_P.I
                                subDertt[j][2] += sub_rval_P.D
                                subDertt[j][3] += sub_rval_P.M
                subDertt_t[i].append(
                    subDertt)  # 2-tuple, index 0 = _P, index 1 = P
            else:
                break  # deeper Derts are not formed
    _P.subDertt_ = subDertt_t[0]
    P.subDertt_ = subDertt_t[1]
    # comp Derts, sum xlayer:
    xDert_vt = [0, 0]
    derDertt = [[], []]
    for (_mDert, _dDert), (mDert, dDert) in zip(subDertt_t[0], subDertt_t[1]):
        for i, (_iDert,
                iDert) in enumerate(zip((_mDert, _dDert), (mDert, dDert))):
            derDert = []
            for _param, param, param_name, ave in zip(_iDert, iDert,
                                                      param_names, aves):
                dert = comp_param(_param, param, param_name, ave)
                if i:  # higher value for L?
                    vd = abs(dert.d) - ave_d
                    if vd > 0:
                        xDert_vt[
                            i] += vd  # no neg value sum: -Ps won't be processed
                elif dert.m > 0:
                    xDert_vt[i] += dert.m
                derDert.append(
                    dert
                )  # dert per param, derDert_ per _subDert, copy in subDert?
            derDertt[i].append(derDert)  # m, d derDerts per sublayer

        _P.derDertt_.append(derDertt)  # derDert_ per _P, P pair
        P.derDertt_.append(derDertt)  # bilateral assignment?

    return xDert_vt
Exemple #5
0
def merge_comp_P(
        P_, _P, P, i, j, neg_M, neg_L,
        remove_index):  # multi-variate cross-comp, _smP = 0 in line_patterns

    mP = dP = 0
    layer1 = dict({'L': .0, 'I': .0, 'D': .0, 'M': .0})
    dist_coef = ave_rM**(
        1 + neg_L / _P.L
    )  # average match projected at current distance from P: neg_L, separate for min_match, add coef / var?

    for param_name in layer1:
        if param_name == "I":
            dist_ave = ave_inv * dist_coef
        else:
            dist_ave = ave_min * dist_coef
        param = getattr(
            _P, param_name
        ) / _P.L  # swap _ convention here, it's different in search
        _param = getattr(P, param_name) / P.L
        dm = comp_param(_param, param, [], dist_ave)
        rdn = layer0_rdn[param_name]
        mP += dm.m * rdn
        dP += dm.d * rdn
        layer1[param_name] = dm

    if neg_L == 0:
        mP += _P.dert_[0].m
        dP += _P.dert_[0].d

    rel_distance = neg_L / _P.L

    if mP / max(
            rel_distance, 1
    ) > ave_merge:  # merge(_P, P): splice proximate and param/L- similar Ps:
        _P.accum_from(P)
        _P.dert_ += P.dert_
        remove_index.append(j)
        if _P.fPd: _P.sign = P.D > 0
        else: P.sign = P.M > 0

        if (i - 1) >= 0 and (i - 1) not in remove_index and (
                i) not in remove_index:
            derP, _L, _smP = merge_comp_P(P_, P_[i - 1], _P, i - 1, i, neg_M,
                                          neg_L,
                                          remove_index)  # backward re-comp_P

        elif (j + 1) <= len(P_) - 1 and (j + 1) not in remove_index and (
                i) not in remove_index:
            derP, _L, _smP = merge_comp_P(P_, _P, P_[j + 1], i, j + 1, neg_M,
                                          neg_L,
                                          remove_index)  # forward comp_P
        else:
            derP = None

    else:  # form derP:
        derP, L, _smP = comp_P(_P, P, neg_L, neg_M)

    return derP, _P.L, _P.sign
Exemple #6
0
    def comp_Pp(_Pp, Pp, layer0):
        '''
        next level line_PPPs:
        PPm_ = search_Pp_(layer0, fPd=0)  # calls comp_Pp_ and form_PP_ per param
        PPd_ = search_Pp_(layer0, fPd=1)
        '''
        mPp = dPp = 0
        layer1 = dict({'L': .0, 'I': .0, 'D': .0, 'M': .0})
        dist_coef = ave_rM * (1 + _Pp.negL / _Pp.L)
        # average match projected at current distance, needs a review
        for param_name in layer1:
            if param_name == "I":
                ave = ave_inv  # * dist_coef
            else:
                ave = ave_min  # * dist_coef
            param = getattr(_Pp, param_name)
            _param = getattr(Pp, param_name)
            dert = comp_param(_param, param, [], ave)
            rdn = layer0[param_name + '_'][1]  # index 1 =rdn
            mPp += dert.m * rdn
            dPp += dert.d * rdn
            layer1[param_name] = dert

        negM = _Pp.negM - Pp.negM
        negL = _Pp.L - Pp.negL
        negiL = _Pp.iL - Pp.negiL
        '''
        options for div_comp, etc.    
        if P.sign == _P.sign: mP *= 2  # sign is MSB, value of sign match = full magnitude match?
        if mP > 0
            # positive forward match, compare sublayers between P.sub_H and _P.sub_H:
           comp_sublayers(_P, P, mP)
        if isinstance(_P.derP, CderP):  # derP is created in comp_sublayers
            _P.derP.sign = sign
            _P.derP.layer1 = layer1
            _P.derP.accumulate(mP=mP, neg_M=neg_M, neg_L=neg_L, P=_P)
            derP = _P.derP
        else:
            derP = CderP(sign=sign, mP=mP, neg_M=neg_M, neg_L=neg_L, P=_P, layer1=layer1)
            _P.derP = derP
        '''
        derPp = CderPp(mPp=mPp,
                       dPp=dPp,
                       negM=negM,
                       negL=negL,
                       negiL=negiL,
                       _Pp=_Pp,
                       Pp=Pp,
                       layer1=layer1)

        return derPp
Exemple #7
0
def search(P_, fPd):  # cross-compare patterns within horizontal line

    Ldert_, Idert_, Ddert_, Mdert_, dert1_, dert2_, LP_, IP_, DP_, MP_ = [], [], [], [], [], [], [], [], [], []

    for _P, P, P2 in zip(P_, P_[1:], P_[2:] +
                         [CP()]):  # for P_ cross-comp over step=1 and step=2
        _L, _I, _D, _M, *_ = _P.unpack()  # *_: skip remaining params
        L, I, D, M, *_ = P.unpack()
        D2, M2 = P2.D, P2.M
        # div_comp for L:
        rL = L / _L  # higher order of scale, not accumulated: no search, rL is directional
        int_rL = int(max(rL, 1 / rL))
        frac_rL = max(rL, 1 / rL) - int_rL
        mL = int_rL * min(L, _L) - (
            int_rL * frac_rL
        ) / 2 - ave_mL  # div_comp match is additive compression: +=min, not directional
        Ldert_.append(Cdert(i=L, p=L + _L, d=rL,
                            m=mL))  # add mrdn if default form Pd?
        # summed params comp:
        if fPd:
            Idert_ += [comp_param(_I, I, "I_", ave_mI)]
            Ddert = comp_param(_D, D2, "D_",
                               ave_mD)  # step=2 for same-D-sign comp
            Ddert_ += [Ddert]
            dert2_ += [Ddert.copy()]
            dert1_ += [comp_param(_D, D, "D_", ave_mD)]  # to splice Pds
            Mdert_ += [comp_param(_M, M, "M_", ave_mM)]
        else:
            Ddert_ += [comp_param(_D, D, "D_", ave_mD)]
            Mdert = comp_param(_M, M2, "M_",
                               ave_mM)  # step=2 for same-M-sign comp
            Mdert_ += [Mdert]
            dert2_ += [Mdert.copy()]
            dert1_ += [comp_param(_M, M, "M_", ave_mM)]  # to splice Pms
        _L, _I, _D, _M = L, I, D, M

    LP_ = P_[:-1]
    dert2_ = dert2_[:-1]  # due to filled CP() in P2 ( for loop above )
    if not fPd:
        Idert_, IP_ = search_param_(
            P_, ave_mI, rave=1)  # comp x variable range, depending on M of Is
        Mdert_ = Mdert_[:-1]  # due to filled CP() in P2 ( for loop above )
        DP_, MP_ = P_[:-1], P_[:-2]
    else:
        IP_, DP_, MP_ = P_[:-1], P_[:-2], P_[:-1]

    # comp x variable range, depending on M of Is
    if not fPd: Idert_, IP_ = search_param_(P_, ave_mI, rave=1)

    Pdert_t = (Ldert_, LP_), (Idert_, IP_), (Ddert_, DP_), (Mdert_, MP_)

    return Pdert_t, dert1_, dert2_
Exemple #8
0
def comp_P(_P, P, neg_L,
           neg_M):  # multi-variate cross-comp, _smP = 0 in line_patterns

    mP = dP = 0
    layer1 = dict({'L': .0, 'I': .0, 'D': .0, 'M': .0})
    dist_coef = ave_rM**(1 + neg_L / _P.L
                         )  # average match projected at current distance:

    for param_name in layer1:
        if param_name == "I":
            dist_ave = ave_inv * dist_coef
        else:
            dist_ave = ave_min * dist_coef
        param = getattr(_P, param_name)
        _param = getattr(P, param_name)
        dm = comp_param(_param, param, [], dist_ave)
        rdn = layer0_rdn[param_name]
        mP += dm.m * rdn
        dP += dm.d * rdn
        layer1[param_name] = dm
        '''
        main comp is between summed params, with an option for div_comp, etc.
        mP -= ave_M * ave_rM ** (1 + neg_L / P.L)  # average match projected at current distance: neg_L, add coef / var?
        match(P,_P), ave_M is addition to ave? or abs for projection in search?
        '''
        if P.sign == _P.sign:
            mP *= 2  # sign is MSB, value of sign match = full magnitude match?
        sign = mP > 0
        if sign:  # positive forward match, compare sublayers between P.sub_H and _P.sub_H:
            comp_sublayers(_P, P, mP)

        if isinstance(_P.derP, CderP):  # derP is created in comp_sublayers
            _P.derP.sign = sign
            _P.derP.layer1 = layer1
            _P.derP.accumulate(mP=mP, neg_M=neg_M, neg_L=neg_L, P=_P)
            derP = _P.derP
        else:
            derP = CderP(sign=sign,
                         mP=mP,
                         neg_M=neg_M,
                         neg_L=neg_L,
                         P=_P,
                         layer1=layer1)
            _P.derP = derP

    return derP, _P.L, _P.sign
Exemple #9
0
def search_param_(
        P_, ave,
        rave):  # variable-range search in mdert_, only if param is core param?

    # higher local ave for extended rng: -> lower m and term by match, and higher proj_M?
    Idert_, _P_ = [], []  # line-wide (i, p, d, m, negL, negM, negiL)

    for i, _P in enumerate(P_[:-1]):
        negM = 0
        _pI = _P.I - (_P.D / 2)  # forward project by _D
        j = i + 1  # init with positive-M Is only: internal match projects xP I match:

        while _P.M + negM > ave_M and j < len(
                P_
        ):  # starts with positive _P.Ms, but continues over negM if > ave
            P = P_[j]
            pI = P.I + (P.D / 2)  # backward project by D
            dert = comp_param(_pI, pI, "I_",
                              ave)  # param is compared to prior-P _param
            pdert = Cpdert(i=dert.i, p=dert.p, d=dert.d,
                           m=dert.m)  # convert Cdert to Cpdert
            curr_M = pdert.m * rave + (
                _P.M + P.M) / 2  # P.M is bilateral, no fPd in search_param

            if curr_M > ave_sub and (_P.sublayers and P.sublayers
                                     ):  # comp sub_P_s, for core I only?
                comp_sublayers(
                    P_[i], P_[j],
                    pdert.m)  # between sublayers[0], forms pdert.sub_M:
            if curr_M + pdert.sub_M > ave_M * 4:  # 4 = ave_cM coef
                break  # 1st match takes over connectivity search in the next loop
            else:
                pdert.negM += curr_M - ave_M  # known to be negative, accum per dert
                pdert.negiL += P.L
                pdert.negL += 1
                negM = pdert.negM
                j += 1

        if "pdert" in locals():  # after extended search, if any:
            Idert_.append(pdert)
            _P_.append(_P)
            del pdert  # prevent reuse of same pdert in multiple loops

    return Idert_, _P_
Exemple #10
0
def search_param_(
        I_, D_, P_, ave,
        rave):  # variable-range search in mdert_, only if param is core param?

    # higher local ave for extended rng: -> lower m and term by match, and higher proj_M?
    mdert_ = []  # line-wide (i, p, d, m, negL, negM, negiL)

    for i, (_I, _D, _P) in enumerate(zip(I_[:-1], D_[:-1], P_[:-1])):
        proj_M = 1
        negiL = negL = negM = 0
        _pI = _I - (_D / 2)  # forward project by _D
        j = i + 1

        while proj_M > 0 and j < len(I_):
            I = I_[j]
            D = D_[j]
            P = P_[j]
            pI = I - (D / 2)  # backward project by D
            dert = comp_param(_pI, pI, "I_",
                              ave)  # param is compared to prior-P _param
            if dert.m > 0:
                if dert.m + _P.M > 0:
                    comp_sublayers(P_[i], P_[j], dert.m, dert.d)
                break  # 1st matching param takes over connectivity search from _param, in the next loop
            else:
                proj_M = dert.m * rave + negM - ave_M  # lower ave_M instead of projection?
                negM += dert.m * rave  # or abs m only?
                negiL += P.L
                negL += 1
                j += 1

        # after extended search, if any:
        mdert_.append(
            Cpdert(i=dert.i,
                   p=dert.p,
                   d=dert.d,
                   m=dert.m,
                   negiL=negiL,
                   negL=negL,
                   negM=negM))

    return mdert_
Exemple #11
0
def comp_sublayers(_P, P, mP, dP):  # not revised; also add dP?

    if P.sublayers and _P.sublayers:  # not empty sub layers
        for _sub_layer, sub_layer in zip(_P.sublayers[0], P.sublayers[0]):

            if _sub_layer and sub_layer:
                _fPd, _rdn, _rng, _sub_P_, _sub_Pp__, = _sub_layer
                fPd, rdn, rng, sub_P_, sub_Pp__ = sub_layer
                # fork comparison:
                if fPd == _fPd and rng == _rng and min(_P.L, P.L) > ave_Ls:
                    sub_mP = sub_dP = 0
                    # compare all sub_Ps to each _sub_P:
                    for _sub_P in _sub_P_:
                        for sub_P in sub_P_:
                            sub_dert = comp_param(_sub_P.I, sub_P.I, "I_", ave)
                    sub_mP += sub_dert.m  # of compared H, no specific mP?
                    sub_dP += sub_dert.d
                    if sub_mP + mP < ave_sub_M:
                        # potentially mH: trans-layer induction: if mP + sub_mP < ave_sub_M: both local and global values of mP.
                        break  # low vertical induction, deeper sublayers are not compared
                else:
                    break  # deeper P and _P sublayers are from different intra_comp forks, not comparable?
Exemple #12
0
def comp_sub_P(_sub_P, sub_P, xsub_pdertt, P_, root_v, fPd):
    fbreak = 0
    xsub_P_vt = [0, 0]  # vm,vd combined across params
    dist_decay = 2  # decay of projected match with relative distance between sub_Ps

    distance = (sub_P.x0 + sub_P.L / 2) - (_sub_P.x0 + _sub_P.L / 2
                                           )  # distance between mean xs
    mean_L = (_sub_P.L + sub_P.L) / 2
    rel_distance = distance / mean_L  # not gap and overlap: edge-specific?
    if fPd:
        sub_V = abs((_sub_P.D + sub_P.D) / 2) - ave_d * mean_L
    else:
        sub_V = (_sub_P.M + sub_P.M) / 2
    V = sub_V + root_v
    # or comp all, then filter by distance?
    if V * rel_distance * dist_decay > ave_M * (fPd * ave_D):
        # 1x1 comp:
        for i, (param_name, ave) in enumerate(zip(param_names, aves)):
            _param = getattr(_sub_P, param_name[0])  # can be simpler?
            param = getattr(sub_P, param_name[0])
            dert = comp_param(_param, param, param_name, ave)
            sub_pdert = Cpdert(i=dert.i, p=dert.p, d=dert.d,
                               m=dert.m)  # convert Cdert to Cpdert
            # no negative-value sum: -Ps won't be processed:
            if dert.m > 0: xsub_P_vt[0] += dert.m
            vd = abs(dert.d) - ave_d  # convert to coef
            if vd > 0: xsub_P_vt[1] += vd
            xsub_pdertt[i].append(sub_pdert)  # per L, I, D, M' xsub_pdert
            P_.append(sub_P)  # same sub_P for all xsub_Pps

        V += xsub_P_vt[0] + xsub_P_vt[
            1]  # or two separate values for comp_sublayers?
        if V > ave_M * 4 and _sub_P.sublayers and sub_P.sublayers:  # 4: ave_comp_sublayers coef
            comp_sublayers(_sub_P, sub_P, V)  # recursion for deeper layers
    else:
        fbreak = 1  # only sub_Ps with relatively proximate position in sub_P_|_sub_P_ are compared

    return fbreak
Exemple #13
0
def intra_Pp_(
        rootPp, rval_Pp, param_name, fPd
):  # evaluate for sub-recursion in line Pm_, pack results into sub_Pm_

    comb_sublayers = []  # combine into root P sublayers[1:]
    # each Pp may be compared over incremental range and derivation, as in line_patterns but with local aves

    for rval, Pp in rval_Pp:  # each sub_layer is nested to depth = sublayers[n]
        if Pp.L > 2:
            mean_M = Pp.M / Pp.L  # for internal Pd eval, +opposite-side mean_M?
            # all params norm?
            if fPd:  # Pp is Ppd
                if abs(
                        Pp.D
                ) * mean_M > ave_D * Pp.Rdn and Pp.L > 3:  # mean_M from adjacent +ve Ppms
                    # search in top sublayer, eval by pdert.d:
                    sub_search_draft(Pp.P_, fPd)
                    rdn_ = [rdn + 1 for rdn in Pp.rdn_[:-1]]

                    sub_Ppm_, sub_Ppd_ = [], []
                    Pp.sublayers = [[(fPd, sub_Ppm_, sub_Ppd_)]]
                    ddert_ = []
                    # higher derivation comp, if sublayers.D?
                    for _pdert, pdert in zip(
                            Pp.pdert_[:-1],
                            Pp.pdert_[1:]):  # Pd.pdert_ is dert1_
                        _param = _pdert.d
                        param = pdert.d
                        dert = comp_param(
                            _param, param, param_name[0], ave
                        )  # cross-comp of ds in dert1_, !search, local aves?
                        ddert_ += [
                            Cdert(i=dert.i, p=dert.p, d=dert.d, m=dert.m)
                        ]
                    # cluster Pd derts by md sign:
                    sub_Ppm_[:] = form_Pp_(Pp,
                                           ddert_, [], [],
                                           param_name,
                                           rdn_,
                                           Pp.P_,
                                           fPd=False)
                    sub_Ppd_[:] = form_Pp_(Pp,
                                           ddert_, [], [],
                                           param_name,
                                           rdn_,
                                           Pp.P_,
                                           fPd=True)

            else:  # Pp is Ppm
                if Pp.M > 0 and Pp.M > ave_M * Pp.Rdn and param_name == "I_":  # and if variable cost: Pp.M / Pp.L? -lend to contrast?
                    # search in top sublayer, eval by pdert.m:
                    sub_search_draft(Pp.P_, fPd)
                    # +Ppm -> sub_Ppm_: low-variation span, eval rng_comp:
                    rdn_ = [rdn + 1 for rdn in Pp.rdn_[:-1]]

                    sub_Ppm_, sub_Ppd_ = [], []
                    Pp.sublayers = [[(fPd, sub_Ppm_, sub_Ppd_)]]
                    # range extended by incr ave: less term by match, and decr proj_P = dert.m * rave ((M/L) / ave): less term by miss
                    rpdert_, rP_ = search_param_(
                        Pp.P_, (ave + Pp.M) / 2,
                        rave=Pp.M / ave)  # rpdert_len-=1 in search_param:
                    sub_Ppm_[:] = form_Pp_(
                        Pp,
                        rpdert_, [], [],
                        param_name,
                        rdn_[:-1],
                        rP_,
                        fPd=False)  # cluster by m sign, eval intra_Pm_
                    sub_Ppd_[:] = form_Pp_(
                        Pp,
                        Pp.pdert_, [], [],
                        param_name,
                        rdn_,
                        Pp.P_,
                        fPd=True
                    )  # cluster by d sign: partial d match, eval intra_Pm_(Pdm_)

            if rootPp and Pp.sublayers:
                comb_sublayers = [
                    comb_subset_ + subset_ for comb_subset_, subset_ in
                    zip_longest(comb_sublayers, Pp.sublayers, fillvalue=[])
                ]
    if rootPp:
        return comb_sublayers
    else:
        return rval_Pp
Exemple #14
0
def search(P_, fPd):  # cross-compare patterns within horizontal line

    sub_search_recursive(
        P_, fPd)  # search with incremental distance: first inside sublayers?
    layer0 = {
        'L_': [],
        'I_': [],
        'D_': [],
        'M_': []
    }  # param_name: [param values]

    Ldert_ = []
    for P in P_:  # unpack P params
        L = P.L
        if "_P" in locals():  # not the 1st P
            _L = _P.L
            rL = L / _L  # div_comp L: higher-scale, not accumulated: no search
            # add ave_Ls to L param match computation?
            mL = int(max(rL, 1 / rL)) * min(
                L, _L
            ) - ave_mL  # div_comp match is additive compression, not directional
            Ldert_.append(Cdert(i=L, p=L + _L, d=rL, m=mL))
        _P = P
        layer0['I_'].append(P.I / L)  # mean values for comp_param
        layer0['D_'].append(P.D / L)
        layer0['M_'].append(P.M / L)
    Pdert__ = [Ldert_]  # no search for L, step=1 only

    if fPd:  # comp | search per param type, separate dert1_ and dert2_ (step=1 and step=2 comp) for P splice only
        # I
        dert1_I = [
            comp_param(_par, par, "I_", ave_mI)
            for _par, par in zip(layer0["I_"][:-1], layer0["I_"][1:])
        ]
        # D: Pd-defining param
        dert1_D = [
            comp_param(_par, par, "D_", ave_mD)
            for _par, par in zip(layer0["D_"][:-1], layer0["D_"][1:])
        ]
        dert2_D = [
            comp_param(_par, par, "D_", ave_mD)
            for _par, par in zip(layer0["D_"][:-2], layer0["D_"][2:])
        ]
        # M
        dert1_M = [
            comp_param(_par, par, "M_", ave_mM)
            for _par, par in zip(layer0["M_"][:-1], layer0["M_"][1:])
        ]
        # generic
        Pdert__ += [dert1_I, dert1_D, dert1_M]
        dert1_ = dert1_D  # for Pd splicing
        dert2_ = dert2_D
    else:
        # I: Pm-defining param
        pdert_I = search_param_(layer0["I_"], layer0["D_"], P_, ave_mI,
                                rave=1)  # forms variable-negL pderts
        dert1_I = [
            comp_param(__par, par, "I_", ave_mI)
            for __par, par in zip(layer0["I_"][:-1], layer0["I_"][1:])
        ]
        dert2_I = [
            comp_param(__par, par, "I_", ave_mI)
            for __par, par in zip(layer0["I_"][:-2], layer0["I_"][2:])
        ]
        # D
        dert1_D = [
            comp_param(_par, par, "D_", ave_mD)
            for _par, par in zip(layer0["D_"][:-1], layer0["D_"][1:])
        ]
        # M
        dert2_M = [
            comp_param(_par, par, "M_", ave_mM)
            for _par, par in zip(layer0["M_"][:-2], layer0["M_"][2:])
        ]
        # generic
        Pdert__ += [pdert_I, dert1_D, dert2_M]
        dert1_ = dert1_I  # for Pm splicing
        dert2_ = dert2_I
    '''
    old:
    for param_name in ["I_", "D_", "M_"]:
        param_ = layer0[param_name]  # param values
        # if dert-level P-defining param:
        if ((param_name == "I_") and not fPd) or ((param_name == "D_") and fPd):
            if not fPd:
                Pdert__ += [search_param_(param_, layer0["D_"], P_, ave_mI, rave=1)]  # pdert_ if "I_"
            # step=2 comp for P splice only:
            dert2_ = [comp_param(__par, par, param_name[0], ave) for __par, par in zip( param_[:-2], param_[2:])]
        # else step=1 per param only:
        dert1_ = [comp_param(_par, par, param_name[0], ave) for _par, par in zip( param_[:-1], param_[1:])]
        dert1__ += [dert1_]
        if not param_name == "I_":
            Pdert__ += [dert1_]  # clustered into Pps in form_Pp_
    '''

    rdn__ = sum_rdn_(
        layer0, Pdert__, fPd=1
    )  # assign redundancy to lesser-magnitude m|d in param pair for same-_P Pderts
    rval_Pp__ = []
    Ppm__ = []  # for visualization

    for param_name, Pdert_, rdn_ in zip(layer0, Pdert__,
                                        rdn__):  # segment Pdert__ into Pps
        if param_name == "I_" and not fPd:
            Ppm_ = form_Pp_rng(None, Pdert_, rdn_, P_)
        else:
            Ppm_ = form_Pp_(
                None, Pdert_, param_name, rdn_, P_,
                fPd=0)  # Ppd_ is formed in -Ppms only, in intra_Ppm_
        # rval_Pp_s per param:
        rval_Pp__ += [form_rval_Pp_(Ppm_, param_name, dert1_, dert2_,
                                    fPd=0)]  # evaluates for compact()
        Ppm__ += [Ppm_]

    return rval_Pp__, Ppm__
Exemple #15
0
def intra_Pp_(
        Pp_, param_name, rdn_, fPd
):  # evaluate for sub-recursion in line Pm_, pack results into sub_Pm_

    comb_layers = []  # combine into root P sublayers[1:]
    # each Pp is evaluated for incremental range and derivation xcomp, as in line_patterns but with local aves

    for Pp, rdn in zip(
            Pp_, rdn_):  # each sub_layer is nested to depth = sublayers[n]
        if Pp.L > 2:  # no rel_adj_M = adj_M / -P.M: discontinuous search?
            mean_M = Pp.M / Pp.L  # for internal Pd eval, +opposite-side mean_M?

            if fPd:  # Pp is Ppd
                if abs(
                        Pp.D
                ) * mean_M > ave_D * rdn and Pp.L > 3:  # mean_M from adjacent +ve Ppms
                    rdn_ = [rdn + 1 for rdn in rdn_]
                    ddert_ = []
                    for _pdert, pdert in zip(
                            Pp.pdert_[:-1],
                            Pp.pdert_[1:]):  # Pd.pdert_ is dert1_
                        _param = _pdert.d
                        param = pdert.d
                        dert = comp_param(
                            _param, param, param_name[0], ave
                        )  # cross-comp of ds in dert1_, !search, local aves?
                        ddert_ += [
                            Cdert(i=dert.i, p=dert.p, d=dert.d, m=dert.m)
                        ]
                    # cluster Pd derts by md sign:
                    form_Pp_(Pp, ddert_, param_name, rdn_, Pp.P_, fPd=True)
            else:  # Pp is Ppm
                # +Ppm -> sub_Ppm_: low-variation span, eval rng_comp:
                if Pp.M > 0 and Pp.M > ave_M * rdn and param_name == "I_":  # and if variable cost: Pp.M / Pp.L? -lend to contrast?
                    rdn_ = [rdn + 1 for rdn in rdn_]
                    I_ = [pdert.i for pdert in (Pp.pdert_[:-1])]
                    D_ = [pdert.d for pdert in (Pp.pdert_[:-1])]
                    # search range is extended by higher ave: less replacing by match,
                    # and by higher proj_P = dert.m * rave ((Pp.M / Pp.L) / ave): less term by miss:
                    P_ave = Pp.M / Pp.L
                    rpdert_ = search_param_(I_,
                                            D_,
                                            Pp.P_, (ave + P_ave) / 2,
                                            rave=P_ave / ave)
                    form_Pp_(Pp, rpdert_, param_name, rdn_, Pp.P_,
                             fPd=False)  # cluster by m sign, eval intra_Pm_
                # -Ppm -> sub_Ppd:
                elif -Pp.M > ave_D * rdn:  # high-variation span, -M is contrast borrowed from adjacent +Ppms: or abs D: likely sign match span?
                    rdn_ = [rdn + 1 for rdn in rdn_]
                    form_Pp_(
                        Pp, Pp.pdert_, param_name, rdn_, Pp.P_, fPd=True
                    )  # cluster by d sign: partial d match, eval intra_Pm_(Pdm_)

            if Pp.sublayers:  # splice sublayers from all sub_Pp calls in Pp:
                comb_layers = [
                    comb_layer + sublayer for comb_layer, sublayer in
                    zip_longest(comb_layers, Pp.sublayers, fillvalue=[])
                ]
                ''' list comprehension:
                            if P.sublayers:  # combine sublayers of all sub_Ps:
                comb_layers = [([(comb_param + param)       # \
                                 for comb_param, param      #  } Accumulated Dert
                                 in zip(comb_Dert, Dert)],  # /
                                comb_subset_ + subset_)     # Accumulated subset_
                               for (comb_Dert, comb_subset_), (Dert, subset_)   # zipped Dert and subset_ from 2 layer lists
                               in zip_longest(comb_layers, P.sublayers, fillvalue=([0,0,0,0], []))]
                '''
                # old:
                if P.sublayers:  # combine sublayers of all sub_Ps:
                    for comb_layer, sublayer in zip_longest(
                            comb_layers, P.sublayers, fillvalue=([0, 0, 0,
                                                                  0], [])):
                        if sublayer[
                                1]:  # sublayer (Dert, subset_) is not empty
                            if not comb_layer[1]:
                                comb_layers.append(
                                    comb_layer)  # initialized ([0,0,0,0], [])
                            # accumulate combined Dert:
                            for i, param_value in enumerate(sublayer[0]):
                                comb_layer[0][i] += param_value
                            # append combined subset_ (array of sub_P_ param sets):
                            comb_layer[1].extend(
                                sublayer[1])  # append would increase nesting

                comb_layers = []
                if P.sublayers:
                    new_sublayers = []
                    for comb_subset_, subset_ in zip_longest(comb_layers,
                                                             P.sublayers,
                                                             fillvalue=([])):
                        # append combined subset_ (array of sub_P_ param sets):
                        new_sublayers += [comb_subset_.extend(subset_)]
                    comb_layers = [new_sublayers]

                    # to be used de novo in line_PPs, depending on pdert.m, sub_M, and rdn,
                    # line_patterns should only form sublayers?
                    comb_subDerts = []
                    for comb_subset_ in comb_layers:
                        if P.M * len(
                                comb_subset_
                        ) > ave_M * 5:  # 5 is a placeholder, form subDert:
                            new_subDerts = []
                            for comb_Dert, subset_ in zip_longest(
                                    comb_subDerts, comb_subset_,
                                    fillvalue=([])):
                                if subset_:
                                    if not comb_Dert: comb_Dert = [0, 0, 0, 0]
                                    for subset in subset_:
                                        for sub_P in subset[
                                                3]:  # accumulate combined Dert:
                                            comb_Dert[0] += sub_P.L
                                            comb_Dert[1] += sub_P.I
                                            comb_Dert[2] += sub_P.D
                                            comb_Dert[3] += sub_P.M
                                new_subDerts += comb_Dert
                            comb_subDerts = new_subDerts
                        else:
                            break  # no skip to deeper layers

    return comb_layers
Exemple #16
0
def div_comp_P(PP_):  # draft, check all PPs for x-param comp by division between element Ps
    '''
    div x param if projected div match: compression per PP, no internal range for ind eval.
    ~ (L*D + L*M) * rm: L=min, positive if same-sign L & S, proportional to both but includes fractional miss
    + PPm' DL * DS: xP difference compression, additive to x param (intra) compression: S / L -> comp rS
    also + ML * MS: redundant unless min or converted?
    vs. norm param: Var*rL-> comp norm param, simpler but diffs are not L-proportional?
    '''
    for PP in PP_:
        vdP = (PP.adj_mP + PP.P.M) * abs(PP.dP) - ave_div
        if vdP > 0:
            # if irM * D_vars: match rate projects der and div match,
            # div if scale invariance: comp x dVars, signed
            ''' 
            | abs(dL + dI + dD + dM): div value ~= L, Vars correlation: stability of density, opposite signs cancel-out?
            | div_comp value is match: min(dL, dI, dD, dM) * 4, | sum of pairwise mins?
            '''
            _derP = PP.derP_[0]
            # smP, vmP, neg_M, neg_L, iP, mL, dL, mI, dI, mD, dD, mM, dM = P,
            #_sign, _L, _I, _D, _M, _dert_, _sub_H, __smP = _derP.P
            _P = _derP.P
            for i, derP in enumerate(PP.derP_[1:]):
                P = derP.P
                # DIV comp L, SUB comp (summed param * rL) -> scale-independent d, neg if cross-sign:
                rL = P.L / _P.L
                # mL = whole_rL * min_L?
                '''
                dI = I * rL - _I  # rL-normalized dI, vs. nI = dI * rL or aI = I / L
                mI = ave - abs(dI)  # I is not derived, match is inverse deviation of miss
                dD = D * rL - _D  # sum if opposite-sign
                mD = min(D, _D)   # same-sign D in dP?
                dM = M * rL - _M  # sum if opposite-sign
                mM = min(M, _M)   # - ave_rM * M?  negative if x-sign, M += adj_M + deep_M: P value before layer value?
                mP = mI + mM + mD  # match(P, _P) for derived vars, defines norm_PPm, no ndx: single, but nmx is summed
                '''
                for (param, _param) in zip([P.I, P.D, P.M], [_P.I, _P.D, _P.M]):
                    dm = comp_param(param, _param, [], ave, rL)
                    layer1.append([dm.d, dm.m])
                    mP += dm.m; dP += dm.d

                if dP > P.derP.dP:
                    ndP_rdn = 1; dP_rdn = 0  #Not sure what to do with these
                else:
                    dP_rdn = 1; ndP_rdn = 0

                if mP > derP.mP:
                    rrdn = 1  # added to rdn, or diff alt, olp, div rdn?
                else:
                    rrdn = 2
                if mP > ave * 3 * rrdn:
                    #rvars = mP, mI, mD, mM, dI, dD, dM  # redundant vars: dPP_rdn, ndPP_rdn, assigned in each fork?
                    rvars = layer1
                else:
                    rvars = []
                # append rrdn and ratio variables to current derP:
                #PP.derP_[i] += [rrdn, rvars]
                PP.derP_[i].rrdn = rrdn; PP.derP_[i].layer1 = rvars
                # P vars -> _P vars:
                _P = P
                '''
                m and d from comp_rate is more accurate than comp_norm?
                rm, rd: rate value is relative? 
                also define Pd, if strongly directional? 
                if dP > ndP: ndPP_rdn = 1; dPP_rdn = 0  # value = D | nD
                else:        dPP_rdn = 1; ndPP_rdn = 0
                '''
    return PP_
Exemple #17
0
    def search_old(P_, fPd):  # cross-compare patterns within horizontal line

        sub_search_recursive(P_, fPd)  # search with incremental distance: first inside sublayers
        layer0 = {'L_': [], 'I_': [], 'D_': [], 'M_': []}  # param_name: [params]

        if len(P_) > 1:  # at least 2 comparands
            Ldert_ = []; rL_ = []
            # unpack Ps:
            for P in P_:
                if "_P" in locals():  # not the 1st P
                    L = P.L; _L = _P.L
                    rL = L / _L  # div_comp L: higher-scale, not accumulated: no search
                    mL = int(max(rL, 1 / rL)) * min(L, _L)  # match in comp by division as additive compression, not directional
                    Ldert_.append(Cdert(i=L, p=L + _L, d=rL, m=mL))
                    rL_.append(rL)
                _P = P
                layer0['I_'].append([P.I, P.L, P.x0])  # I tuple
                layer0['D_'].append([P.D, P.L, P.x0])  # D tuple
                layer0['M_'].append([P.M, P.L, P.x0])  # M tuple

            dert1__ = [Ldert_]  # no search for L, step=1 only, contains derts vs. pderts
            Pdert__ = [Ldert_]  # Pp elements: pderts if param is core m, else derts

            for param_name in ["I_", "D_", "M_"]:
                param_ = layer0[param_name]  # param values
                par_ = param_[1:]  # compared vectors:
                _par_ = [[_par * rL, L, x0] for [_par, L, x0], rL in zip(param_[:-1], rL_)]  # normalize by rL

                if ((param_name == "I_") and not fPd) or ((param_name == "D_") and fPd):  # dert-level P-defining params
                    if not fPd:
                        # project I by D, or D by Dd in deriv_comp sub_Ps:
                        _par_ = [[_par - (D / 2), L, x0] for [_par, L, x0], [D, _, _] in zip(_par_, layer0["D_"][:-1])]
                        # _I in (I,L,x0) is  - (D / 2): forward projected by _D in (D,L,x0)
                        par_ = [[par + (D / 2), L, x0] for [par, L, x0], [D, _, _] in zip(par_, layer0["D_"][1:])]
                        # I in (I,L,x0) is backward projected by D in (D,L,x0)
                        Pdert__ += [search_param_(_par_, par_, P_[:-1], ave, rave=1)]  # pdert_ if "I_"
                    del _P
                    _rL_ = []
                    for P in P_:  # form rLs to normalize cross-comp of same-M-sign Ps in pdert2_
                        if "_P" in locals():  # not the 1st P
                            if "__P" in locals():  # not the 2nd P
                                _rL_.append(P.L / __P.L)
                            __P = _P
                        _P = P
                    __par_ = [[__par * _rL, L, x0] for [__par, L, x0], _rL in zip(param_[:-2], _rL_)]  # normalize by _rL
                    # step=2 comp for P splice, one param: (I and not fPd) or (D and fPd):
                    dert2_ = [comp_param(__par, par, param_name[0], ave) for __par, par in zip(__par_, par_[1:])]
                # else step=1 only:

                dert1_ = [comp_param(_par, par, param_name[0], ave) for _par, par in zip(_par_, par_)]  # append pdert1_ per param_
                dert1__ += [dert1_]
                if not param_name == "I_": Pdert__ += [dert1_]  # dert_ = comp_param_

            rdn__ = sum_rdn_(layer0, Pdert__, fPd=1)  # assign redundancy to lesser-magnitude m|d in param pair for same-_P Pderts
            rdn_Ppm__ = []

            for param_name, Pdert_, rdn_ in zip(layer0, Pdert__, rdn__):  # segment Pdert__ into Pps
                if param_name == "I_" and not fPd:  # = isinstance(Pdert_[0], Cpdert)
                    Ppm_ = form_Pp_rng(Pdert_, rdn_, P_)
                else:
                    Ppm_ = form_Pp_(Pdert_, param_name, rdn_, P_, fPd=0)  # Ppd_ is formed in -Ppms only, in intra_Ppm_
                # list of param rdn_Ppm_s:
                rdn_Ppm__ += [form_rdn_Pp_(Ppm_, param_name, dert1__, dert2_, fPd=0)]

        return rdn_Ppm__
Exemple #18
0
def comp_sublayers(
        _P, P,
        root_m):  # if pdert.m -> if summed params m -> if positional m: mx0?
    # comp subDerts:
    subDertt_ = []  # preserved for future processing
    # form Derts:
    for _sublayer, sublayer in zip(_P.sublayers, P.sublayers):
        subDertt_s = [[], []]  # preserved for future processing
        for i, isublayer in enumerate(_sublayer, sublayer):  # list of subsets:
            if root_m * len(
                    isublayer
            ) > ave_M * 5:  # won't work, first len(isublayer) = 1, need to think about it
                subDertt = []
                for fPd, rdn, rng, sub_Pm_, xsub_pmdertt_, sub_Pd_, xsub_pddertt_ in sublayer:
                    for isub_P_ in sub_Pm_, sub_Pd_:
                        Dert = [0, 0, 0,
                                0]  # P. L, I, D, M summed within sublayer
                        for sub_P in isub_P_:
                            Dert[0] += sub_P.L
                            Dert[1] += sub_P.I
                            Dert[2] += sub_P.D
                            Dert[3] += sub_P.M
                    subDertt.append(Dert)
                subDertt_.append(subDertt)  # 2tuple
            else:
                break  # deeper Derts are not formed
            subDertt_s[i] = subDertt_

        _P.subDertt_ = subDertt_s[0]
        P.subDertt_ = subDertt_s[1]

    # comp Derts, sum cross-layer:
    if not _P.derDertt_: _P.derDertt_ = []
    xDert_mt = [0, 0]
    derDertt = []
    for (_mDert, _dDert), (mDert, dDert) in zip(subDertt_, subDertt_):
        for i, _iDert, iDert in enumerate(zip((_mDert, mDert),
                                              (_dDert, dDert))):
            derDert = []
            for _param, param, param_name, ave in zip(_iDert, iDert,
                                                      param_names, aves):
                dert = comp_param(_param, param, param_name, ave)
                if dert.m > 0:
                    xDert_mt[
                        i] += dert.m  # pdert is higher-layer, also higher-value mL? no -m sum: won't be processed
                derDert.append(
                    dert
                )  # dert per param, derDert_ per _subDert, a copy for subDert?
            derDertt[i].append(derDert)  # m, d derDerts per sublayer

        _P.derDertt_.append(derDertt)  # derDert_ per _P and P pair
        P.derDertt_.append(derDertt)  # bilateral assignment?

    # comp sub_Ps:
    if xDert_mt[
            i] + root_m > ave_M * 4 and _P.sublayers and P.sublayers:  # or pdert.sub_M + pdert.m + P.M?
        # comp sub_Ps between sub_P_s in 1st sublayer:
        _fPd, _rdn, _rng, _sub_P_, _xsub_pdertt_, _sub_Pp__ = _P.sublayers[0][
            0]  # 2nd [0] is the 1st and only subset
        fPd, rdn, rng, sub_P_, xsub_pdertt_, sub_Pp__ = P.sublayers[0][0]
        # if same intra_comp fork, else not comparable:
        if fPd == _fPd and rng == _rng and min(_P.L,
                                               P.L) > ave_Ls and root_m > 0:
            # compare sub_Ps to each _sub_P within max relative distance, comb_M- proportional:
            _SL = SL = 0  # summed Ls
            start_index = next_index = 0  # index of starting sub_P for current _sub_P
            _xsub_pdertt_ += [
                []
            ]  # array of cross-sub_P pdert tuples: inner brackets, per sub_P_
            xsub_pdertt_ += [
                []
            ]  # append xsub_dertt per _sub_P_ and sub_P_, sparse?

            for _sub_P in _sub_P_:  # form xsub_pdertt_[ xsub_dertt [ xsub_pdert_[ sub_pdert]]]: each bracket is level of nesting
                P_ = []  # to form xsub_Pps
                _xsub_pdertt = [[], [], [],
                                []]  # tuple of L, I, D, M xsub_pderts
                _SL += _sub_P.L  # ix0 of next _sub_P
                # search right:
                for sub_P in sub_P_[
                        start_index:]:  # index_ix0 > _ix0, only sub_Ps at proximate relative positions in sub_P_ are compared
                    if comp_sub_P(_sub_P, sub_P, _xsub_pdertt, P_, root_m):
                        break
                    # if next ix overlap: ix0 of next _sub_P < ix0 of current sub_P
                    if SL < _SL: next_index += 1
                    SL += sub_P.L  # ix0 of next sub_P
                # search left:
                for sub_P in reversed(
                        sub_P_[len(sub_P_) - start_index:]
                ):  # index_ix0 <= _ix0, invert positions of sub_P and _sub_P:
                    if comp_sub_P(sub_P, _sub_P, _xsub_pdertt, P_, root_m):
                        break
                # not implemented: if param_name == "I_" and not fPd: sub_pdert = search_param_(param_)
                # for next _sub_P:
                start_index = next_index

                if _xsub_pdertt[
                        0]:  # at least 1 sub_pdert, real min length ~ 8, very unlikely
                    sub_Pdertt_ = [
                        (_xsub_pdertt[0], P_), (_xsub_pdertt[1], P_),
                        (_xsub_pdertt[2], P_), (_xsub_pdertt[3], P_)
                    ]
                    # form 4-tuple of xsub_Pp_s:
                    xsub_rval_Pp_t, sub_Ppm__ = form_Pp_root(sub_Pdertt_, [],
                                                             [],
                                                             fPd=0)
                    _xsub_pdertt_[-1][:] = xsub_rval_Pp_t
                    xsub_pdertt_[-1][:] = _xsub_pdertt_[
                        -1]  # bilateral assignment

                else:
                    _xsub_pdertt_[-1].append(_xsub_pdertt)  # preserve nesting