Aligned Induction

Transforms

Python implementation of the Overview/Transforms

Sections

Definition

Formal and Abstract

Functional transforms

Application to history

Partition transforms

Natural converse

Sample converse

Actual converse

Independent converse

Transforms as models

Example - a weather forecast

Definition

Given a histogram $X \in \mathcal{A}$ and a subset of its variables $W \subseteq \mathrm{vars}(X)$, the pair $T = (X,W)$ forms a transform. The Transform type is defined with a pair of a Histogram and a Variable set,

newtype Transform = Transform (Histogram, (Set.Set Variable))

A Transform is constructed from a Histogram and a set of Variable,

histogramsSetVarsTransform :: Histogram -> Set.Set Variable -> Maybe Transform

Consider the deck of cards example,

def lluu(ll):
return listsSystem([(v,sset(ww)) for (v,ww) in ll])

[suit,rank] = map(VarStr, ["suit","rank"])
[jack,queen,king,ace] = map(ValStr, ["J","Q","K","A"])

uu = lluu([
(rank, [jack,queen,king,ace] + list(map(ValInt,range(2,10+1))))])

vv = sset([suit, rank])

uu
# {(rank, {A, J, K, Q, 2, 3, 4, 5, 6, 7, 8, 9, 10}), (suit, {clubs, diamonds, hearts, spades})}

vv
# {rank, suit}

aa = unit(cart(uu,vv))

rpln(aall(aa))
# ({(rank, A), (suit, clubs)}, 1 % 1)
# ({(rank, A), (suit, diamonds)}, 1 % 1)
# ({(rank, A), (suit, hearts)}, 1 % 1)
# ({(rank, A), (suit, spades)}, 1 % 1)
# ({(rank, J), (suit, clubs)}, 1 % 1)
# ({(rank, J), (suit, diamonds)}, 1 % 1)
# ...
# ({(rank, 9), (suit, hearts)}, 1 % 1)
# ({(rank, 9), (suit, spades)}, 1 % 1)
# ({(rank, 10), (suit, clubs)}, 1 % 1)
# ({(rank, 10), (suit, diamonds)}, 1 % 1)
# ({(rank, 10), (suit, hearts)}, 1 % 1)
# ({(rank, 10), (suit, spades)}, 1 % 1)

A transform can be constructed from a histogram $X$ relating the suit to the colour,

colour = VarStr("colour")
red = ValStr("red")
black = ValStr("black")

xx = llaa([(llss([(suit, u),(colour, w)]),1) for (u,w) in [(hearts, red), (clubs, black), (diamonds, red), (spades, black)]])

rpln(aall(xx))
# ({(colour, black), (suit, clubs)}, 1 % 1)
# ({(colour, black), (suit, spades)}, 1 % 1)
# ({(colour, red), (suit, diamonds)}, 1 % 1)
# ({(colour, red), (suit, hearts)}, 1 % 1)

ww = sset([colour])

trans = histogramsSetVarsTransform

trans(xx,ww)
# ({({(colour, black), (suit, clubs)}, 1 % 1), ({(colour, black), (suit, spades)}, 1 % 1), ({(colour, red), (suit, diamonds)}, 1 % 1), ({(colour, red), (suit, hearts)}, 1 % 1)}, {colour})

The variables, $W$, are the derived variables. The complement $K = \mathrm{vars}(X) \setminus W$ are the underlying variables,

ww
# {colour}

kk = vars(xx) - ww

kk
# {suit}

The set of all transforms is $\begin{eqnarray} \mathcal{T} &:=& \{(X,W) : X \in \mathcal{A},~W \subseteq \mathrm{vars}(X)\} \end{eqnarray}$ The transform histogram is $X = \mathrm{his}(T)$. The transform derived is $W = \mathrm{der}(T)$. The transform underlying is $K = \mathrm{und}(T)$,

transformsHistogram :: Transform -> Histogram
transformsUnderlying :: Transform -> Set.Set Variable
transformsDerived :: Transform -> Set.Set Variable

For example,

ttaa = transformsHistogram
und = transformsUnderlying
der = transformsDerived

tt = trans(xx,ww)

ttaa(tt) == xx
# True

und(tt) == kk
# True

der(tt) == ww
# True

The null transform is $(X,\emptyset)$,

histogramsTransformNull :: Histogram -> Transform

For example,

null = histogramsTransformNull

ttaa(null(aa)) == aa
# True

und(null(aa)) == vars(aa)
# True

der(null(aa)) == sset()
# True

The full transform is $(X,\mathrm{vars}(X))$,

histogramsTransformDisjoint :: Histogram -> Transform

For example,

full = histogramsTransformDisjoint

ttaa(full(aa)) == aa
# True

und(full(aa)) == sset()
# True

der(full(aa)) == vars(aa)
# True

Given a histogram $A \in \mathcal{A}$, the multiplication of the histogram, $A$, by the transform $T \in \mathcal{T}$ equals the multiplication of the histogram, $A$, by the transform histogram $X = \mathrm{his}(T)$ followed by the reduction to the derived variables $W = \mathrm{der}(T)$, $\begin{eqnarray} A * T~=~A * (X,W) &:=& A * X~\%~W \end{eqnarray}$

transformsHistogramsApply :: Transform -> Histogram -> Histogram

For example,

def tmul(aa,tt):
return transformsHistogramsApply(tt,aa)

rpln(aall(tmul(aa,tt)))
# ({(colour, black)}, 26 % 1)
# ({(colour, red)}, 26 % 1)

tmul(aa,tt) == ared(mul(aa,xx),ww)
# True

If the histogram variables are a superset of the underlying variables, $\mathrm{und}(T) \subseteq \mathrm{vars}(A)$,

und(tt).issubset(vars(aa))
# True

then the histogram, $A$, is called the underlying histogram and the multiplication, $A * T$, is called the derived histogram. The derived histogram variables equals the derived variables, $\mathrm{vars}(A*T) = \mathrm{der}(T)$.

If the set of underlying variables of a transform is a proper subset of the set of histogram variables, $K \subset V$, the transform can be expanded by multiplying its histogram by the cartesian histogram of the set of remaining variables, $V \setminus K$. In the deck of cards example, the set of underlying variables, $K$, is a singleton consisting of the suit,

und(tt)
# {suit}

The transform is expanded to the histogram variables, $V$, by multiplying by the cartesian histogram for the rank,

vk = vv - kk

vk
# {rank}

ttv = trans(mul(ttaa(tt),unit(cart(uu,vk))), der(tt))

und(ttv)
# {rank, suit}

und(ttv) == vv
# True

The set of derived variables of the expanded transform is unchanged, so the derived histogram is unchanged,

der(ttv) == der(tt)
# True

tmul(aa,ttv) == tmul(aa,tt)
# True

The application of the null transform of the cartesian is the scalar, $A * (V^{\mathrm{C}},\emptyset) = A \% \emptyset = \mathrm{scalar}(\mathrm{size}(A))$, where $V = \mathrm{vars}(A)$,

vvc = unit(cart(uu,vv))

tmul(aa,null(vvc)) == ared(aa,sset())
# True

The application of the full transform of the cartesian is the histogram, $A * (V^{\mathrm{C}},V) = A \% V = A$,

tmul(aa,full(vvc)) == aa
# True

Formal and Abstract

Given a histogram $A \in \mathcal{A}$ and a transform $T \in \mathcal{T}$, the formal histogram is defined as the independent derived, $A^{\mathrm{X}} * T$. In the case of the deck of cards example, the histogram, $A$, is just the cartesian and is already independent. So the formal histogram equals the derived histogram,

rpln(aall(tmul(ind(aa),tt)))
# ({(colour, black)}, 26 % 1)
# ({(colour, red)}, 26 % 1)

tmul(ind(aa),tt) == tmul(aa,tt)
# True

Consider a transform $T’$ with two derived variables constructed on two underlying variables as follows,

tt1 = trans(cdaa([[1,1,1,2],[1,2,1,1],[1,3,1,1],[2,1,2,1],[2,2,2,2],[2,3,2,1],[3,1,2,1],[3,2,2,1],[3,3,1,2]]), sset([VarInt(3), VarInt(4)]))

rpln(aall(ttaa(tt1)))
# ({(1, 1), (2, 1), (3, 1), (4, 2)}, 1 % 1)
# ({(1, 1), (2, 2), (3, 1), (4, 1)}, 1 % 1)
# ({(1, 1), (2, 3), (3, 1), (4, 1)}, 1 % 1)
# ({(1, 2), (2, 1), (3, 2), (4, 1)}, 1 % 1)
# ({(1, 2), (2, 2), (3, 2), (4, 2)}, 1 % 1)
# ({(1, 2), (2, 3), (3, 2), (4, 1)}, 1 % 1)
# ({(1, 3), (2, 1), (3, 2), (4, 1)}, 1 % 1)
# ({(1, 3), (2, 2), (3, 2), (4, 1)}, 1 % 1)
# ({(1, 3), (2, 3), (3, 1), (4, 2)}, 1 % 1)

und(tt1)
# {1, 2}

der(tt1)
# {3, 4}

rpln(aall(tmul(regcart(3,2),tt1)))
# ({(3, 1), (4, 1)}, 2 % 1)
# ({(3, 1), (4, 2)}, 2 % 1)
# ({(3, 2), (4, 1)}, 4 % 1)
# ({(3, 2), (4, 2)}, 1 % 1)

rpln(aall(tmul(regdiag(3,2),tt1)))
# ({(3, 1), (4, 2)}, 2 % 1)
# ({(3, 2), (4, 2)}, 1 % 1)

Now the formal histogram of a regular diagonal underlying differs from the derived histogram,

rpln(aall(tmul(ind(regdiag(3,2)),tt1)))
# ({(3, 1), (4, 1)}, 2 % 3)
# ({(3, 1), (4, 2)}, 2 % 3)
# ({(3, 2), (4, 1)}, 4 % 3)
# ({(3, 2), (4, 2)}, 1 % 3)

tmul(ind(regdiag(3,2)),tt1) == tmul(regdiag(3,2),tt1)
# False

tmul(ind(regcart(3,2)),tt1) == tmul(regcart(3,2),tt1)
# True

The abstract histogram is defined as the derived independent, $(A * T)^{\mathrm{X}}$. In the case of the deck of cards example, the transform, $T$, has only one derived variable and so the derived histogram is already independent,

rpln(aall(ind(tmul(aa,tt))))
# ({(colour, black)}, 26 % 1)
# ({(colour, red)}, 26 % 1)

ind(tmul(aa,tt)) == tmul(aa,tt)
# True

In the case of transform $T’$, however, the abstract histogram of a regular cartesian underlying differs from the derived histogram,

rpln(aall(ind(tmul(regcart(3,2),tt1))))
# ({(3, 1), (4, 1)}, 8 % 3)
# ({(3, 1), (4, 2)}, 4 % 3)
# ({(3, 2), (4, 1)}, 10 % 3)
# ({(3, 2), (4, 2)}, 5 % 3)

ind(tmul(regcart(3,2),tt1)) == tmul(regcart(3,2),tt1)
# False

ind(tmul(regdiag(3,2),tt1)) == tmul(regdiag(3,2),tt1)
# True

In the case where the formal and abstract are equal, $A^{\mathrm{X}} * T = (A * T)^{\mathrm{X}}$, the abstract equals the independent abstract, $(A * T)^{\mathrm{X}} = A^{\mathrm{X}} * T = (A^{\mathrm{X}} * T)^{\mathrm{X}}$, and so only depends on the independent, $A^{\mathrm{X}}$, not on the histogram, $A$. The formal equals the formal independent, $A^{\mathrm{X}} * T = (A * T)^{\mathrm{X}} = (A^{\mathrm{X}} * T)^{\mathrm{X}}$, and so is itself independent. For example, when the transform $T’$ has only one derived variable and varies with only one of the underlying variables,

tt1 = trans(cdaa([[1,1,1],[1,2,1],[1,3,1],[2,1,2],[2,2,2],[2,3,2],[3,1,2],[3,2,2],[3,3,2]]), sset([VarInt(3)]))

rpln(aall(ttaa(tt1)))
# ({(1, 1), (2, 1), (3, 1)}, 1 % 1)
# ({(1, 1), (2, 2), (3, 1)}, 1 % 1)
# ({(1, 1), (2, 3), (3, 1)}, 1 % 1)
# ({(1, 2), (2, 1), (3, 2)}, 1 % 1)
# ({(1, 2), (2, 2), (3, 2)}, 1 % 1)
# ({(1, 2), (2, 3), (3, 2)}, 1 % 1)
# ({(1, 3), (2, 1), (3, 2)}, 1 % 1)
# ({(1, 3), (2, 2), (3, 2)}, 1 % 1)
# ({(1, 3), (2, 3), (3, 2)}, 1 % 1)

rpln(aall(tmul(regcart(3,2),tt1)))
# ({(3, 1)}, 3 % 1)
# ({(3, 2)}, 6 % 1)

tmul(ind(regcart(3,2)),tt1) == ind(tmul(regcart(3,2),tt1))
# True

rpln(aall(tmul(regdiag(3,2),tt1)))
# ({(3, 1)}, 1 % 1)
# ({(3, 2)}, 2 % 1)

tmul(ind(regdiag(3,2)),tt1) == ind(tmul(regdiag(3,2),tt1))
# True

In the case where $T’$ varies with both of the underlying variables, formal-abstract equivalence holds only for the cartesian,

tt1 = trans(cdaa([[1,1,1],[1,2,1],[1,3,1],[2,1,2],[2,2,2],[2,3,2],[3,1,2],[3,2,2],[3,3,1]]), sset([VarInt(3)]))

rpln(aall(ttaa(tt1)))
# ({(1, 1), (2, 1), (3, 1)}, 1 % 1)
# ({(1, 1), (2, 2), (3, 1)}, 1 % 1)
# ({(1, 1), (2, 3), (3, 1)}, 1 % 1)
# ({(1, 2), (2, 1), (3, 2)}, 1 % 1)
# ({(1, 2), (2, 2), (3, 2)}, 1 % 1)
# ({(1, 2), (2, 3), (3, 2)}, 1 % 1)
# ({(1, 3), (2, 1), (3, 2)}, 1 % 1)
# ({(1, 3), (2, 2), (3, 2)}, 1 % 1)
# ({(1, 3), (2, 3), (3, 1)}, 1 % 1)

tmul(ind(regcart(3,2)),tt1) == ind(tmul(regcart(3,2),tt1))
# True

tmul(ind(regdiag(3,2)),tt1) == ind(tmul(regdiag(3,2),tt1))
# False

Functional transforms

A transform $T \in \mathcal{T}$ is functional if there is a causal relation between the underlying variables $K = \mathrm{und}(T)$ and the derived variables $W = \mathrm{der}(T)$, $\begin{eqnarray} \mathrm{split}(K,X^{\mathrm{FS}}) &\in& K^{\mathrm{CS}} \to W^{\mathrm{CS}} \end{eqnarray}$ where $X=\mathrm{his}(T)$. In the deck of cards example,

xx == ttaa(tt)
# True

rpln(aall(xx))
# ({(colour, black), (suit, clubs)}, 1 % 1)
# ({(colour, black), (suit, spades)}, 1 % 1)
# ({(colour, red), (suit, diamonds)}, 1 % 1)
# ({(colour, red), (suit, hearts)}, 1 % 1)

kk
# {suit}

ww
# {colour}

rpln(ssplit(kk,(states(xx))))
# ({(suit, clubs)}, {(colour, black)})
# ({(suit, diamonds)}, {(colour, red)})
# ({(suit, hearts)}, {(colour, red)})

iscausal = histogramsIsCausal

iscausal(xx)
# True

The expanded transform is still causal,

rpln(ssplit(vv,(states(ttaa(ttv)))))
# ({(rank, A), (suit, clubs)}, {(colour, black)})
# ({(rank, A), (suit, diamonds)}, {(colour, red)})
# ({(rank, A), (suit, hearts)}, {(colour, red)})
# ({(rank, A), (suit, spades)}, {(colour, black)})
# ({(rank, J), (suit, clubs)}, {(colour, black)})
# ({(rank, J), (suit, diamonds)}, {(colour, red)})
# ...
# ({(rank, 9), (suit, hearts)}, {(colour, red)})
# ({(rank, 9), (suit, spades)}, {(colour, black)})
# ({(rank, 10), (suit, clubs)}, {(colour, black)})
# ({(rank, 10), (suit, diamonds)}, {(colour, red)})
# ({(rank, 10), (suit, hearts)}, {(colour, red)})
# ({(rank, 10), (suit, spades)}, {(colour, black)})

iscausal(ttaa(ttv))
# True

The set of functional transforms $\mathcal{T}_{\mathrm{f}} \subset \mathcal{T}$ is the subset of all transforms that are causal.

A functional transform $T \in \mathcal{T}_{\mathrm{f}}$ has an inverse, $\begin{eqnarray} T^{-1} &:=& \{((S\%K,c), S\%W) : (S,c) \in X\}^{-1} \end{eqnarray}$

transformsInverse :: Transform -> Map.Map State Histogram

For example,

inv = transformsInverse

rpln(inv(tt))
# ({(colour, black)}, {({(suit, clubs)}, 1 % 1), ({(suit, spades)}, 1 % 1)})
# ({(colour, red)}, {({(suit, diamonds)}, 1 % 1), ({(suit, hearts)}, 1 % 1)})

rpln(inv(ttv))
# ({(colour, black)}, {({(rank, A), (suit, clubs)}, 1 % 1), ..., ({(rank, 10), (suit, spades)}, 1 % 1)})
# ({(colour, red)}, {({(rank, A), (suit, diamonds)}, 1 % 1), ..., ({(rank, 10), (suit, hearts)}, 1 % 1)})

A transform $T$ is one functional in system $U$ if the reduction of the transform histogram to the underlying variables equals the cartesian histogram, $X\%K = K^{\mathrm{C}}$,

ared(xx,kk) == unit(cart(uu,kk))
# True

ared(ttaa(ttv),vv) == unit(cart(uu,vv))
# True

So the causal relation is a derived state valued left total function of underlying state, $\mathrm{split}(K,X^{\mathrm{S}}) \in K^{\mathrm{CS}} :\to W^{\mathrm{CS}}$. The set of one functional transforms $\mathcal{T}_{U,\mathrm{f},1} \subset \mathcal{T}_{\mathrm{f}}$ is $\begin{eqnarray} \mathcal{T}_{U,\mathrm{f},1} &=& \{ (\{(S \cup R,1) : (S,R) \in Q\},W) : \\ &&\hspace{5em}K,W \subseteq \mathrm{vars}(U),~K \cap W = \emptyset, ~Q \in K^{\mathrm{CS}} :\to W^{\mathrm{CS}}\} \end{eqnarray}$ The application of a one functional transform to an underlying histogram preserves the size, $\mathrm{size}(A * T) = \mathrm{size}(A)$,

size(tmul(aa,tt)) == size(aa)
# True

size(tmul(aa,ttv)) == size(aa)
# True

The one functional transform inverse is a unit component valued function of derived state, $T^{-1} \in W^{\mathrm{CS}} \to \mathrm{P}(K^{\mathrm{C}})$. That is, the range of the inverse corresponds to a partition of the cartesian states into components, $\mathrm{ran}(T^{-1}) \in \mathrm{B}(K^{\mathrm{C}})$,

[(ss,cc),(rr,dd)] = list(inv(tt).items())

rpln(aall(cc))
# ({(suit, clubs)}, 1 % 1)
# ({(suit, spades)}, 1 % 1)

rpln(aall(dd))
# ({(suit, diamonds)}, 1 % 1)
# ({(suit, hearts)}, 1 % 1)

# True

and

[(ss,cc),(rr,dd)] = list(inv(ttv).items())

rpln(aall(cc))
# ({(rank, A), (suit, clubs)}, 1 % 1)
# ({(rank, A), (suit, spades)}, 1 % 1)
# ({(rank, J), (suit, clubs)}, 1 % 1)
# ...
# ({(rank, 9), (suit, spades)}, 1 % 1)
# ({(rank, 10), (suit, clubs)}, 1 % 1)
# ({(rank, 10), (suit, spades)}, 1 % 1)

rpln(aall(dd))
# ({(rank, A), (suit, diamonds)}, 1 % 1)
# ({(rank, A), (suit, hearts)}, 1 % 1)
# ({(rank, J), (suit, diamonds)}, 1 % 1)
# ...
# ({(rank, 9), (suit, hearts)}, 1 % 1)
# ({(rank, 10), (suit, diamonds)}, 1 % 1)
# ({(rank, 10), (suit, hearts)}, 1 % 1)

# True

The application of a one functional transform $T$ to its underlying cartesian $K^{\mathrm{C}}$ is the component cardinality histogram, $K^{\mathrm{C}} * T = \{(R,|C|) : (R,C) \in T^{-1}\}$,

rpln(aall(tmul(unit(cart(uu,kk)),tt)))
# ({(colour, black)}, 2 % 1)
# ({(colour, red)}, 2 % 1)

rpln(aall(tmul(unit(cart(uu,vv)),ttv)))
# ({(colour, black)}, 26 % 1)
# ({(colour, red)}, 26 % 1)

The effective cartesian derived volume is less than or equal to the derived volume, $|(K^{\mathrm{C}} * T)^{\mathrm{F}}| = |T^{-1}| \leq |W^{\mathrm{C}}|$,

len(states(eff(tmul(unit(cart(uu,kk)),tt))))
# 2

len(states(eff(tmul(unit(cart(uu,vv)),ttv))))
# 2

Application to history

A one functional transform $T \in \mathcal{T}_{U,\mathrm{f},1}$ may be applied to a history $H \in \mathcal{H}$ in the underlying variables of the transform, $\mathrm{vars}(H) \supseteq \mathrm{und}(T)$, to construct a derived history, $\begin{eqnarray} H * T &:=& \{(x,R) : (x,S) \in H,~\{R\} = (\{S\}^{\mathrm{U}} * T)^{\mathrm{FS}}\} \end{eqnarray}$ The size is unchanged, $|H * T| = |H|$, and the event identifiers are conserved, $\mathrm{dom}(H * T) = \mathrm{dom}(H)$.

transformsHistoriesApply :: Transform -> History -> History

For example,

llhh = listsHistory
hhll = historyToList

hh = llhh([(IdInt(i+1),ss) for (i,ss) in enumerate(cart(uu, vv))])

rpln(hhll(hh))
# (1, {(rank, A), (suit, clubs)})
# (2, {(rank, A), (suit, diamonds)})
# (3, {(rank, A), (suit, hearts)})
# (4, {(rank, A), (suit, spades)})
# (5, {(rank, J), (suit, clubs)})
# (6, {(rank, J), (suit, diamonds)})
# ...
# (47, {(rank, 9), (suit, hearts)})
# (48, {(rank, 9), (suit, spades)})
# (49, {(rank, 10), (suit, clubs)})
# (50, {(rank, 10), (suit, diamonds)})
# (51, {(rank, 10), (suit, hearts)})
# (52, {(rank, 10), (suit, spades)})

def htmul(hh,tt):
return transformsHistoriesApply(tt,hh)

rpln(hhll(htmul(hh,tt)))
# (1, {(colour, black)})
# (2, {(colour, red)})
# (3, {(colour, red)})
# (4, {(colour, black)})
# (5, {(colour, black)})
# (6, {(colour, red)})
# ...
# (47, {(colour, red)})
# (48, {(colour, black)})
# (49, {(colour, black)})
# (50, {(colour, red)})
# (51, {(colour, red)})
# (52, {(colour, black)})

Partition transforms

Given a partition $P \in \mathrm{B}(V^{\mathrm{CS}})$ of the cartesian states of variables $V$, a one functional transform can be constructed. The partition transform is $\begin{eqnarray} P^{\mathrm{T}} &:=& (\{(S \cup \{(P,C)\}, 1) : C \in P,~S \in C \}, \{P\}) \end{eqnarray}$

partitionsTransformVarPartition :: Partition -> Transform

The set of derived variables of the partition transform is a singleton of the partition variable, $\mathrm{der}(P^{\mathrm{T}}) = \{P\}$. The derived volume is the component cardinality, $|\{P\}^{\mathrm{C}}| = |P|$. The underlying variables are the given variables, $\mathrm{und}(P^{\mathrm{T}}) = V$. For example, consider a partition of the deck of cards,

qqpp = setComponentsPartition
ppqq = partitionsSetComponent

c = sset(list(states(vvc))[0:13])

d = sset(list(states(vvc))[13:])

pp = qqpp(sset([c,d]))

len(ppqq(pp))
# 2

[len(ee) for ee in ppqq(pp)]
# [13, 39]

pptt = partitionsTransformVarPartition

und(pptt(pp))
# {rank, suit}

rpln(aall(ared(ttaa(pptt(pp)),und(pptt(pp)))))
# ({(rank, A), (suit, clubs)}, 1 % 1)
# ({(rank, A), (suit, diamonds)}, 1 % 1)
# ({(rank, A), (suit, hearts)}, 1 % 1)
# ({(rank, A), (suit, spades)}, 1 % 1)
# ({(rank, J), (suit, clubs)}, 1 % 1)
# ({(rank, J), (suit, diamonds)}, 1 % 1)
# ...
# ({(rank, 9), (suit, hearts)}, 1 % 1)
# ({(rank, 9), (suit, spades)}, 1 % 1)
# ({(rank, 10), (suit, clubs)}, 1 % 1)
# ({(rank, 10), (suit, diamonds)}, 1 % 1)
# ({(rank, 10), (suit, hearts)}, 1 % 1)
# ({(rank, 10), (suit, spades)}, 1 % 1)

der(pptt(pp)) == sset([VarPartition(pp)])
# True

[q for (ss,q) in aall(tmul(aa,pptt(pp)))]
# [13 % 1, 39 % 1]

The expanded transform in the deck of cards example partitions the cartesian set of states,

[(ss,cc),(rr,dd)] = list(inv(ttv).items())

pp = qqpp(sset([states(cc),states(dd)]))

len(ppqq(pp))
# 2

[len(ee) for ee in ppqq(pp)]
# [26, 26]

und(pptt(pp))
# {rank, suit}

rpln(aall(ared(ttaa(pptt(pp)),und(pptt(pp)))))
# ({(rank, A), (suit, clubs)}, 1 % 1)
# ({(rank, A), (suit, diamonds)}, 1 % 1)
# ({(rank, A), (suit, hearts)}, 1 % 1)
# ({(rank, A), (suit, spades)}, 1 % 1)
# ({(rank, J), (suit, clubs)}, 1 % 1)
# ({(rank, J), (suit, diamonds)}, 1 % 1)
# ...
# ({(rank, 9), (suit, hearts)}, 1 % 1)
# ({(rank, 9), (suit, spades)}, 1 % 1)
# ({(rank, 10), (suit, clubs)}, 1 % 1)
# ({(rank, 10), (suit, diamonds)}, 1 % 1)
# ({(rank, 10), (suit, hearts)}, 1 % 1)
# ({(rank, 10), (suit, spades)}, 1 % 1)

der(pptt(pp)) == sset([VarPartition(pp)])
# True

[q for (ss,q) in aall(tmul(aa,pptt(pp)))]
# [26 % 1, 26 % 1]

The unary partition transform is $T_{\mathrm{u}} = \{V^{\mathrm{CS}}\}^{\mathrm{T}}$,

unary = systemsSetVarsPartitionUnary

uu1 = sysreg(2,2)

pp = unary(uu1,uvars(uu1))

len(ppqq(pp))
# 1

[len(ee) for ee in ppqq(pp)]
# [4]

und(pptt(pp))
# {1, 2}

der(pptt(pp))
# { { { {(1, 1), (2, 1)}, {(1, 1), (2, 2)}, {(1, 2), (2, 1)}, {(1, 2), (2, 2)} } } }

rpln(aall(ared(ttaa(pptt(pp)),und(pptt(pp)))))
# ({(1, 1), (2, 1)}, 1 % 1)
# ({(1, 1), (2, 2)}, 1 % 1)
# ({(1, 2), (2, 1)}, 1 % 1)
# ({(1, 2), (2, 2)}, 1 % 1)

rpln(aall(ttaa(pptt(pp))))
# ({(1, 1), (2, 1), ({ { {(1, 1), (2, 1)}, {(1, 1), (2, 2)}, {(1, 2), (2, 1)}, {(1, 2), (2, 2)} } }, { {(1, 1), (2, 1)}, {(1, 1), (2, 2)}, {(1, 2), (2, 1)}, {(1, 2), (2, 2)} })}, 1 % 1)
# ({(1, 1), (2, 2), ({ { {(1, 1), (2, 1)}, {(1, 1), (2, 2)}, {(1, 2), (2, 1)}, {(1, 2), (2, 2)} } }, { {(1, 1), (2, 1)}, {(1, 1), (2, 2)}, {(1, 2), (2, 1)}, {(1, 2), (2, 2)} })}, 1 % 1)
# ({(1, 2), (2, 1), ({ { {(1, 1), (2, 1)}, {(1, 1), (2, 2)}, {(1, 2), (2, 1)}, {(1, 2), (2, 2)} } }, { {(1, 1), (2, 1)}, {(1, 1), (2, 2)}, {(1, 2), (2, 1)}, {(1, 2), (2, 2)} })}, 1 % 1)
# ({(1, 2), (2, 2), ({ { {(1, 1), (2, 1)}, {(1, 1), (2, 2)}, {(1, 2), (2, 1)}, {(1, 2), (2, 2)} } }, { {(1, 1), (2, 1)}, {(1, 1), (2, 2)}, {(1, 2), (2, 1)}, {(1, 2), (2, 2)} })}, 1 % 1)

The self partition transform is $T_{\mathrm{s}} = V^{\mathrm{CS}\{\}\mathrm{T}}$,

self = systemsSetVarsPartitionSelf

uu1 = sysreg(2,2)

pp = self(uu1,uvars(uu1))

len(ppqq(pp))
# 4

[len(ee) for ee in ppqq(pp)]
# [1, 1, 1, 1]

und(pptt(pp))
# {1, 2}

der(pptt(pp))
# { { { {(1, 1), (2, 1)} }, { {(1, 1), (2, 2)} }, { {(1, 2), (2, 1)} }, { {(1, 2), (2, 2)} } } }

rpln(aall(ared(ttaa(pptt(pp)),und(pptt(pp)))))
# ({(1, 1), (2, 1)}, 1 % 1)
# ({(1, 1), (2, 2)}, 1 % 1)
# ({(1, 2), (2, 1)}, 1 % 1)
# ({(1, 2), (2, 2)}, 1 % 1)

rpln(aall(ttaa(pptt(pp))))
# ({(1, 1), (2, 1), ({ { {(1, 1), (2, 1)} }, { {(1, 1), (2, 2)} }, { {(1, 2), (2, 1)} }, { {(1, 2), (2, 2)} } }, { {(1, 1), (2, 1)} })}, 1 % 1)
# ({(1, 1), (2, 2), ({ { {(1, 1), (2, 1)} }, { {(1, 1), (2, 2)} }, { {(1, 2), (2, 1)} }, { {(1, 2), (2, 2)} } }, { {(1, 1), (2, 2)} })}, 1 % 1)
# ({(1, 2), (2, 1), ({ { {(1, 1), (2, 1)} }, { {(1, 1), (2, 2)} }, { {(1, 2), (2, 1)} }, { {(1, 2), (2, 2)} } }, { {(1, 2), (2, 1)} })}, 1 % 1)
# ({(1, 2), (2, 2), ({ { {(1, 1), (2, 1)} }, { {(1, 1), (2, 2)} }, { {(1, 2), (2, 1)} }, { {(1, 2), (2, 2)} } }, { {(1, 2), (2, 2)} })}, 1 % 1)

Natural converse

Given a one functional transform $T \in \mathcal{T}_{U,\mathrm{f},1}$, the natural converse is $\begin{eqnarray} T^{\dagger} &:=& (X/(X\%W),V) \end{eqnarray}$ where $(X,W) = T$ and $V = \mathrm{und}(T)$,

transformsConverseNatural :: Transform -> Transform

In the deck of cards example, the natural converse of the expanded suit-colour transform is

nat = transformsConverseNatural

rpln(aall(ttaa(ttv)))
# ({(colour, black), (rank, A), (suit, clubs)}, 1 % 1)
# ({(colour, black), (rank, A), (suit, spades)}, 1 % 1)
# ({(colour, black), (rank, J), (suit, clubs)}, 1 % 1)
# ...
# ({(colour, red), (rank, 9), (suit, hearts)}, 1 % 1)
# ({(colour, red), (rank, 10), (suit, diamonds)}, 1 % 1)
# ({(colour, red), (rank, 10), (suit, hearts)}, 1 % 1)

der(ttv)
# {colour}

und(ttv)
rp $und ttv # {rank, suit} rpln(aall(ttaa(nat(ttv)))) # ({(colour, black), (rank, A), (suit, clubs)}, 1 % 26) # ({(colour, black), (rank, A), (suit, spades)}, 1 % 26) # ({(colour, black), (rank, J), (suit, clubs)}, 1 % 26) # ... # ({(colour, red), (rank, 9), (suit, hearts)}, 1 % 26) # ({(colour, red), (rank, 10), (suit, diamonds)}, 1 % 26) # ({(colour, red), (rank, 10), (suit, hearts)}, 1 % 26) der(nat(ttv)) # {rank, suit} und(nat(ttv)) # {colour} Another example is$T’$, def cdtt(pp,ll): return trans(cdtp(cdaa(ll),pp), sset([VarInt(pp[-1])])) tt1 = cdtt([1,2,3],[[1,1,1],[1,2,1],[1,3,1],[2,1,2],[2,2,2],[2,3,2],[3,1,2],[3,2,2],[3,3,1]]) rpln(aall(ttaa(tt1))) # ({(1, 1), (2, 1), (3, 1)}, 1 % 1) # ({(1, 1), (2, 2), (3, 1)}, 1 % 1) # ({(1, 1), (2, 3), (3, 1)}, 1 % 1) # ({(1, 2), (2, 1), (3, 2)}, 1 % 1) # ({(1, 2), (2, 2), (3, 2)}, 1 % 1) # ({(1, 2), (2, 3), (3, 2)}, 1 % 1) # ({(1, 3), (2, 1), (3, 2)}, 1 % 1) # ({(1, 3), (2, 2), (3, 2)}, 1 % 1) # ({(1, 3), (2, 3), (3, 1)}, 1 % 1) der(tt1) # {3} rpln(aall(ttaa(nat(tt1)))) # ({(1, 1), (2, 1), (3, 1)}, 1 % 4) # ({(1, 1), (2, 2), (3, 1)}, 1 % 4) # ({(1, 1), (2, 3), (3, 1)}, 1 % 4) # ({(1, 2), (2, 1), (3, 2)}, 1 % 5) # ({(1, 2), (2, 2), (3, 2)}, 1 % 5) # ({(1, 2), (2, 3), (3, 2)}, 1 % 5) # ({(1, 3), (2, 1), (3, 2)}, 1 % 5) # ({(1, 3), (2, 2), (3, 2)}, 1 % 5) # ({(1, 3), (2, 3), (3, 1)}, 1 % 4) der(nat(tt1)) # {1, 2} The natural converse may be expressed in terms of components, $T^{\dagger}~:=~(\sum_{(R,C) \in T^{-1}} \{R\}^{\mathrm{U}} * \hat{C},~V)$ def inv(tt): return list(transformsInverse(tt).items()) def sunit(ss): return setStatesHistogramUnit(sset([ss])) rpln(inv(ttv)) # ({(colour, black)}, {({(rank, A), (suit, clubs)}, 1 % 1), ..., ({(rank, 10), (suit, spades)}, 1 % 1)}) # ({(colour, red)}, {({(rank, A), (suit, diamonds)}, 1 % 1), ..., ({(rank, 10), (suit, hearts)}, 1 % 1)}) ee = histogramEmpty() for (rr,cc) in inv(ttv): ee = add(ee,mul(sunit(rr),norm(cc))) rpln(aall(ee)) # ({(colour, black), (rank, A), (suit, clubs)}, 1 % 26) # ({(colour, black), (rank, A), (suit, spades)}, 1 % 26) # ({(colour, black), (rank, J), (suit, clubs)}, 1 % 26) # ... # ({(colour, red), (rank, 9), (suit, hearts)}, 1 % 26) # ({(colour, red), (rank, 10), (suit, diamonds)}, 1 % 26) # ({(colour, red), (rank, 10), (suit, hearts)}, 1 % 26) rpln(inv(tt1)) # ({(3, 1)}, {({(1, 1), (2, 1)}, 1 % 1), ({(1, 1), (2, 2)}, 1 % 1), ({(1, 1), (2, 3)}, 1 % 1), ({(1, 3), (2, 3)}, 1 % 1)}) # ({(3, 2)}, {({(1, 2), (2, 1)}, 1 % 1), ({(1, 2), (2, 2)}, 1 % 1), ({(1, 2), (2, 3)}, 1 % 1), ({(1, 3), (2, 1)}, 1 % 1), ({(1, 3),(2, 2)}, 1 % 1)}) ee = histogramEmpty() for (rr,cc) in inv(tt1): ee = add(ee,mul(sunit(rr),norm(cc))) rpln(aall(ee)) # ({(1, 1), (2, 1), (3, 1)}, 1 % 4) # ({(1, 1), (2, 2), (3, 1)}, 1 % 4) # ({(1, 1), (2, 3), (3, 1)}, 1 % 4) # ({(1, 2), (2, 1), (3, 2)}, 1 % 5) # ({(1, 2), (2, 2), (3, 2)}, 1 % 5) # ({(1, 2), (2, 3), (3, 2)}, 1 % 5) # ({(1, 3), (2, 1), (3, 2)}, 1 % 5) # ({(1, 3), (2, 2), (3, 2)}, 1 % 5) # ({(1, 3), (2, 3), (3, 1)}, 1 % 4) Given a histogram$A \in \mathcal{A}$in the underlying variables,$\mathrm{vars}(A) = V$, the naturalisation is the application of the natural converse transform to the derived histogram,$A * T * T^{\dagger}$, rpln(aall(tmul(tmul(aa,ttv),nat(ttv)))) # ({(rank, A), (suit, clubs)}, 1 % 1) # ({(rank, A), (suit, diamonds)}, 1 % 1) # ({(rank, A), (suit, hearts)}, 1 % 1) # ({(rank, A), (suit, spades)}, 1 % 1) # ({(rank, J), (suit, clubs)}, 1 % 1) # ({(rank, J), (suit, diamonds)}, 1 % 1) # ... # ({(rank, 9), (suit, hearts)}, 1 % 1) # ({(rank, 9), (suit, spades)}, 1 % 1) # ({(rank, 10), (suit, clubs)}, 1 % 1) # ({(rank, 10), (suit, diamonds)}, 1 % 1) # ({(rank, 10), (suit, hearts)}, 1 % 1) # ({(rank, 10), (suit, spades)}, 1 % 1) A histogram is natural when it equals its naturalisation,$A = A * T * T^{\dagger}$, so the deck of cards histogram is natural, tmul(tmul(aa,ttv),nat(ttv)) == aa # True The cartesian is always natural,$V^{\mathrm{C}} = V^{\mathrm{C}} * T * T^{\dagger}$, so$T’$applied to the cartesian is natural, rpln(aall(tmul(tmul(regcart(3,2),tt1),nat(tt1)))) # ({(1, 1), (2, 1)}, 1 % 1) # ({(1, 1), (2, 2)}, 1 % 1) # ({(1, 1), (2, 3)}, 1 % 1) # ({(1, 2), (2, 1)}, 1 % 1) # ({(1, 2), (2, 2)}, 1 % 1) # ({(1, 2), (2, 3)}, 1 % 1) # ({(1, 3), (2, 1)}, 1 % 1) # ({(1, 3), (2, 2)}, 1 % 1) # ({(1, 3), (2, 3)}, 1 % 1) tmul(tmul(regcart(3,2),tt1),nat(tt1)) == regcart(3,2) # True but$T’$applied to the diagonal is not, rpln(aall(tmul(tmul(regdiag(3,2),tt1),nat(tt1)))) # ({(1, 1), (2, 1)}, 1 % 2) # ({(1, 1), (2, 2)}, 1 % 2) # ({(1, 1), (2, 3)}, 1 % 2) # ({(1, 2), (2, 1)}, 1 % 5) # ({(1, 2), (2, 2)}, 1 % 5) # ({(1, 2), (2, 3)}, 1 % 5) # ({(1, 3), (2, 1)}, 1 % 5) # ({(1, 3), (2, 2)}, 1 % 5) # ({(1, 3), (2, 3)}, 1 % 2) tmul(tmul(regdiag(3,2),tt1),nat(tt1)) == regdiag(3,2) # False The naturalisation can be rewritten$A * X~\%~W * X~/~(X\%W)~\%~V$, ared(divide(mul(ared(mul(aa,ttaa(ttv)),der(ttv)),ttaa(ttv)),ared(ttaa(ttv),der(ttv))),vv) == tmul(tmul(aa,ttv),nat(ttv)) # True The naturalisation is in the underlying variables,$\mathrm{vars}(A * T * T^{\dagger}) = V$, vars(tmul(tmul(aa,ttv),nat(ttv))) # {rank, suit} The size is conserved,$\mathrm{size}(A * T * T^{\dagger}) = \mathrm{size}(A)$, size(tmul(tmul(aa,ttv),nat(ttv))) == size(aa) # True The naturalisation derived equals the derived,$A * T * T^{\dagger} * T = A * T$, tmul(tmul(tmul(aa,ttv),nat(ttv)),ttv) == tmul(aa,ttv) # True The naturalisation equals the sum of the scaled components, $\begin{eqnarray} A * T * T^{\dagger} &=& \sum_{(R,C) \in T^{-1}} \mathrm{scalar}( (A * T)_R) * \hat{C} \\ &=& \sum_{(R,C) \in T^{-1}} A * T * \{R\}^{\mathrm{U}} * \hat{C}~\%~V \end{eqnarray}$ ee = histogramEmpty() for (rr,cc) in inv(ttv): ee = add(ee,mul(scalar(aat(tmul(aa,ttv),rr)),norm(cc))) tmul(tmul(aa,ttv),nat(ttv)) == ee # True ee = histogramEmpty() for (rr,cc) in inv(ttv): ee = add(ee,ared(mul(mul(tmul(aa,ttv),sunit(rr)),norm(cc)),vv)) tmul(tmul(aa,ttv),nat(ttv)) == ee # True So each component is uniform, $\forall (R,C) \in T^{-1}~(|\mathrm{ran}(A * T * T^{\dagger} * C)| ~=~ 1)$ isunif = histogramsIsUniform [isunif(mul(tmul(tmul(aa,ttv),nat(ttv)),cc)) for (rr,cc) in inv(ttv)] # [True, True] The naturalisation of the unary partition transform,$T_{\mathrm{u}} = \{V^{\mathrm{CS}}\}^{\mathrm{T}}$, is the sized cartesian,$A * T_{\mathrm{u}} * T_{\mathrm{u}}^{\dagger} = V_z^{\mathrm{C}}$, where$z=\mathrm{size}(A)$, pptt = partitionsTransformVarPartition def unary(uu,vv): return pptt(systemsSetVarsPartitionUnary(uu,vv)) tmul(tmul(aa,unary(uu,vv)),nat(unary(uu,vv))) == resize(size(aa),unit(cart(uu,vv))) # True The naturalisation of the self partition transform,$T_{\mathrm{s}} = V^{\mathrm{CS}\{\}\mathrm{T}}$, is the histogram,$A * T_{\mathrm{s}} * T_{\mathrm{s}}^{\dagger} = A$, def self(uu,vv): return pptt(systemsSetVarsPartitionSelf(uu,vv)) tmul(tmul(aa,self(uu,vv)),nat(self(uu,vv))) == aa # True Sample converse Given a one functional transform$T \in \mathcal{T}_{U,\mathrm{f},1}$with underlying variables$V = \mathrm{und}(T)$, and a histogram$A \in \mathcal{A}$in the same variables,$\mathrm{vars}(A) = V$, the sample converse is $\begin{eqnarray} (\hat{A} * X,V) \end{eqnarray}$ where$X = \mathrm{his}(T)$. The sample converse for the deck of cards example is tta = trans(mul(norm(aa),ttaa(ttv)),vars(aa)) rpln(aall(ttaa(tta))) rpln$ aall $ttaa tta # ({(colour, black), (rank, A), (suit, clubs)}, 1 % 52) # ({(colour, black), (rank, A), (suit, spades)}, 1 % 52) # ({(colour, black), (rank, J), (suit, clubs)}, 1 % 52) # ({(colour, black), (rank, J), (suit, spades)}, 1 % 52) # ({(colour, black), (rank, K), (suit, clubs)}, 1 % 52) # ({(colour, black), (rank, K), (suit, spades)}, 1 % 52) # ... # ({(colour, red), (rank, 8), (suit, diamonds)}, 1 % 52) # ({(colour, red), (rank, 8), (suit, hearts)}, 1 % 52) # ({(colour, red), (rank, 9), (suit, diamonds)}, 1 % 52) # ({(colour, red), (rank, 9), (suit, hearts)}, 1 % 52) # ({(colour, red), (rank, 10), (suit, diamonds)}, 1 % 52) # ({(colour, red), (rank, 10), (suit, hearts)}, 1 % 52) der(tta) # {rank, suit} und(tta) # {colour} Actual converse Related to the sample converse, the actual converse is defined as the summed normalised application of the components to the sample histogram, $\begin{eqnarray} T^{\odot A} &:=& (\sum_{(R,C) \in T^{-1}} {R}^{\mathrm{U}} * (A * C)^{\wedge},~V) \end{eqnarray}$ histogramsTransformsConverseActual :: Histogram -> Transform -> Maybe Transform In the deck of cards example, the actual converse of the expanded suit-colour transform is def act(tt,aa): return histogramsTransformsConverseActual(aa,tt) rpln(aall(ttaa(act(ttv,aa)))) # ({(colour, black), (rank, A), (suit, clubs)}, 1 % 26) # ({(colour, black), (rank, A), (suit, spades)}, 1 % 26) # ({(colour, black), (rank, J), (suit, clubs)}, 1 % 26) # ... # ({(colour, red), (rank, 9), (suit, hearts)}, 1 % 26) # ({(colour, red), (rank, 10), (suit, diamonds)}, 1 % 26) # ({(colour, red), (rank, 10), (suit, hearts)}, 1 % 26) der(act(ttv,aa)) # {rank, suit} und(act(ttv,aa)) # {colour} Another example is$T’$, tt1 = cdtt([1,2,3],[[1,1,1],[1,2,1],[1,3,1],[2,1,2],[2,2,2],[2,3,2],[3,1,2],[3,2,2],[3,3,1]]) rpln(aall(ttaa(act(tt1,regcart(3,2))))) # ({(1, 1), (2, 1), (3, 1)}, 1 % 4) # ({(1, 1), (2, 2), (3, 1)}, 1 % 4) # ({(1, 1), (2, 3), (3, 1)}, 1 % 4) # ({(1, 2), (2, 1), (3, 2)}, 1 % 5) # ({(1, 2), (2, 2), (3, 2)}, 1 % 5) # ({(1, 2), (2, 3), (3, 2)}, 1 % 5) # ({(1, 3), (2, 1), (3, 2)}, 1 % 5) # ({(1, 3), (2, 2), (3, 2)}, 1 % 5) # ({(1, 3), (2, 3), (3, 1)}, 1 % 4) der(act(tt1,regcart(3,2))) # {1, 2} rpln(aall(ttaa(act(tt1,regdiag(3,2))))) # ({(1, 1), (2, 1), (3, 1)}, 1 % 2) # ({(1, 2), (2, 2), (3, 2)}, 1 % 1) # ({(1, 3), (2, 3), (3, 1)}, 1 % 2) der(act(tt1,regdiag(3,2))) # {1, 2} The actual converse may be expressed in terms of components, ee = histogramEmpty() for (rr,cc) in inv(ttv): ee = add(ee,mul(sunit(rr),norm(mul(aa,cc)))) rpln(aall(ee)) # ({(colour, black), (rank, A), (suit, clubs)}, 1 % 26) # ({(colour, black), (rank, A), (suit, spades)}, 1 % 26) # ({(colour, black), (rank, J), (suit, clubs)}, 1 % 26) # ... # ({(colour, red), (rank, 9), (suit, hearts)}, 1 % 26) # ({(colour, red), (rank, 10), (suit, diamonds)}, 1 % 26) # ({(colour, red), (rank, 10), (suit, hearts)}, 1 % 26) ee = histogramEmpty() for (rr,cc) in inv(tt1): ee = add(ee,mul(sunit(rr),norm(mul(regcart(3,2),cc)))) rpln(aall(ee)) # ({(1, 1), (2, 1), (3, 1)}, 1 % 4) # ({(1, 1), (2, 2), (3, 1)}, 1 % 4) # ({(1, 1), (2, 3), (3, 1)}, 1 % 4) # ({(1, 2), (2, 1), (3, 2)}, 1 % 5) # ({(1, 2), (2, 2), (3, 2)}, 1 % 5) # ({(1, 2), (2, 3), (3, 2)}, 1 % 5) # ({(1, 3), (2, 1), (3, 2)}, 1 % 5) # ({(1, 3), (2, 2), (3, 2)}, 1 % 5) # ({(1, 3), (2, 3), (3, 1)}, 1 % 4) ee = histogramEmpty() for (rr,cc) in inv(tt1): ee = add(ee,mul(sunit(rr),norm(mul(regdiag(3,2),cc)))) rpln(aall(ee)) # ({(1, 1), (2, 1), (3, 1)}, 1 % 2) # ({(1, 2), (2, 2), (3, 2)}, 1 % 1) # ({(1, 3), (2, 3), (3, 1)}, 1 % 2) The application of the actual converse transform to the derived histogram equals the histogram,$A * T * T^{\odot A} = A$, tmul(tmul(aa,ttv),act(ttv,aa)) == aa # True tmul(tmul(regcart(3,2),tt1),act(tt1,regcart(3,2))) == regcart(3,2) # True tmul(tmul(regdiag(3,2),tt1),act(tt1,regdiag(3,2))) == regdiag(3,2) # True Independent converse Given a one functional transform$T \in \mathcal{T}_{U,\mathrm{f},1}$with underlying variables$V = \mathrm{und}(T)$, and a histogram$A \in \mathcal{A}$in the same variables,$\mathrm{vars}(A) = V$, the independent converse is defined as the summed normalised independent application of the components to the sample histogram, $\begin{eqnarray} T^{\dagger A} &:=& (\sum_{(R,C) \in T^{-1}} \{R\}^{\mathrm{U}} * (A * C)^{\wedge\mathrm{X}},~V) \end{eqnarray}$ histogramsTransformsConverseIndependent :: Histogram -> Transform -> Maybe Transform In the deck of cards example, the independent converse of the expanded suit-colour transform is def idl(tt,aa): return histogramsTransformsConverseIndependent(aa,tt) rpln(aall(ttaa(idl(ttv,aa)))) # ({(colour, black), (rank, A), (suit, clubs)}, 1 % 26) # ({(colour, black), (rank, A), (suit, spades)}, 1 % 26) # ({(colour, black), (rank, J), (suit, clubs)}, 1 % 26) # ... # ({(colour, red), (rank, 9), (suit, hearts)}, 1 % 26) # ({(colour, red), (rank, 10), (suit, diamonds)}, 1 % 26) # ({(colour, red), (rank, 10), (suit, hearts)}, 1 % 26) der(idl(ttv,aa)) # {rank, suit} und(idl(ttv,aa)) # {colour} Another example is$T’$, tt1 = cdtt([1,2,3],[[1,1,1],[1,2,1],[1,3,1],[2,1,2],[2,2,2],[2,3,2],[3,1,2],[3,2,2],[3,3,1]]) rpln(aall(ttaa(idl(tt1,regcart(3,2))))) # ({(1, 1), (2, 1), (3, 1)}, 3 % 16) # ({(1, 1), (2, 2), (3, 1)}, 3 % 16) # ({(1, 1), (2, 3), (3, 1)}, 3 % 8) # ({(1, 2), (2, 1), (3, 2)}, 6 % 25) # ({(1, 2), (2, 2), (3, 2)}, 6 % 25) # ({(1, 2), (2, 3), (3, 2)}, 3 % 25) # ({(1, 3), (2, 1), (3, 1)}, 1 % 16) # ({(1, 3), (2, 1), (3, 2)}, 4 % 25) # ({(1, 3), (2, 2), (3, 1)}, 1 % 16) # ({(1, 3), (2, 2), (3, 2)}, 4 % 25) # ({(1, 3), (2, 3), (3, 1)}, 1 % 8) # ({(1, 3), (2, 3), (3, 2)}, 2 % 25) der(idl(tt1,regcart(3,2))) # {1, 2} rpln(aall(ttaa(idl(tt1,regdiag(3,2))))) # ({(1, 1), (2, 1), (3, 1)}, 1 % 4) # ({(1, 1), (2, 3), (3, 1)}, 1 % 4) # ({(1, 2), (2, 2), (3, 2)}, 1 % 1) # ({(1, 3), (2, 1), (3, 1)}, 1 % 4) # ({(1, 3), (2, 3), (3, 1)}, 1 % 4) der(idl(tt1,regdiag(3,2))) # {1, 2} The independent converse may be expressed in terms of components, ee = histogramEmpty() for (rr,cc) in inv(ttv): ee = add(ee,mul(sunit(rr),ind(norm(mul(aa,cc))))) rpln(aall(ee)) # ({(colour, black), (rank, A), (suit, clubs)}, 1 % 26) # ({(colour, black), (rank, A), (suit, spades)}, 1 % 26) # ({(colour, black), (rank, J), (suit, clubs)}, 1 % 26) # ... # ({(colour, red), (rank, 9), (suit, hearts)}, 1 % 26) # ({(colour, red), (rank, 10), (suit, diamonds)}, 1 % 26) # ({(colour, red), (rank, 10), (suit, hearts)}, 1 % 26) ee = histogramEmpty() for (rr,cc) in inv(tt1): ee = add(ee,mul(sunit(rr),ind(norm(mul(regcart(3,2),cc))))) rpln(aall(ee)) # ({(1, 1), (2, 1), (3, 1)}, 3 % 16) # ({(1, 1), (2, 2), (3, 1)}, 3 % 16) # ({(1, 1), (2, 3), (3, 1)}, 3 % 8) # ({(1, 2), (2, 1), (3, 2)}, 6 % 25) # ({(1, 2), (2, 2), (3, 2)}, 6 % 25) # ({(1, 2), (2, 3), (3, 2)}, 3 % 25) # ({(1, 3), (2, 1), (3, 1)}, 1 % 16) # ({(1, 3), (2, 1), (3, 2)}, 4 % 25) # ({(1, 3), (2, 2), (3, 1)}, 1 % 16) # ({(1, 3), (2, 2), (3, 2)}, 4 % 25) # ({(1, 3), (2, 3), (3, 1)}, 1 % 8) # ({(1, 3), (2, 3), (3, 2)}, 2 % 25) ee = histogramEmpty() for (rr,cc) in inv(tt1): ee = add(ee,mul(sunit(rr),ind(norm(mul(regdiag(3,2),cc))))) rpln(aall(ee)) # ({(1, 1), (2, 1), (3, 1)}, 1 % 4) # ({(1, 1), (2, 3), (3, 1)}, 1 % 4) # ({(1, 2), (2, 2), (3, 2)}, 1 % 1) # ({(1, 3), (2, 1), (3, 1)}, 1 % 4) # ({(1, 3), (2, 3), (3, 1)}, 1 % 4) The idealisation is the application of the independent converse transform to the derived histogram,$A * T * T^{\dagger A}$, rpln(aall(tmul(tmul(aa,ttv),idl(ttv,aa)))) # ({(rank, A), (suit, clubs)}, 1 % 1) # ({(rank, A), (suit, diamonds)}, 1 % 1) # ({(rank, A), (suit, hearts)}, 1 % 1) # ({(rank, A), (suit, spades)}, 1 % 1) # ({(rank, J), (suit, clubs)}, 1 % 1) # ({(rank, J), (suit, diamonds)}, 1 % 1) # ... # ({(rank, 9), (suit, hearts)}, 1 % 1) # ({(rank, 9), (suit, spades)}, 1 % 1) # ({(rank, 10), (suit, clubs)}, 1 % 1) # ({(rank, 10), (suit, diamonds)}, 1 % 1) # ({(rank, 10), (suit, hearts)}, 1 % 1) # ({(rank, 10), (suit, spades)}, 1 % 1) rpln(aall(tmul(tmul(regcart(3,2),tt1),idl(tt1,regcart(3,2))))) # ({(1, 1), (2, 1)}, 3 % 4) # ({(1, 1), (2, 2)}, 3 % 4) # ({(1, 1), (2, 3)}, 3 % 2) # ({(1, 2), (2, 1)}, 6 % 5) # ({(1, 2), (2, 2)}, 6 % 5) # ({(1, 2), (2, 3)}, 3 % 5) # ({(1, 3), (2, 1)}, 21 % 20) # ({(1, 3), (2, 2)}, 21 % 20) # ({(1, 3), (2, 3)}, 9 % 10) rpln(aall(tmul(tmul(regdiag(3,2),tt1),idl(tt1,regdiag(3,2))))) # ({(1, 1), (2, 1)}, 1 % 2) # ({(1, 1), (2, 3)}, 1 % 2) # ({(1, 2), (2, 2)}, 1 % 1) # ({(1, 3), (2, 1)}, 1 % 2) # ({(1, 3), (2, 3)}, 1 % 2) A histogram is ideal when it equals its idealisation,$A = A * T * T^{\dagger A}$, so the deck of cards histogram is ideal, tmul(tmul(aa,ttv),idl(ttv,aa)) == aa # True$T’$applied to the cartesian is not ideal, tmul(tmul(regcart(3,2),tt1),idl(tt1,regcart(3,2))) == regcart(3,2) # False nor is the application to the diagonal, tmul(tmul(regdiag(3,2),tt1),idl(tt1,regdiag(3,2))) == regdiag(3,2) # False The idealisation is in the underlying variables,$\mathrm{vars}(A * T * T^{\dagger A}) = V$, vars(tmul(tmul(aa,ttv),idl(ttv,aa))) == vv # True The size is conserved,$\mathrm{size}(A * T * T^{\dagger A}) = \mathrm{size}(A)$, size(tmul(tmul(aa,ttv),idl(ttv,aa))) == size(aa) # True The idealisation derived equals the derived,$A * T * T^{\dagger A} * T = A * T$, tmul(tmul(tmul(aa,ttv),idl(ttv,aa)),ttv) == tmul(aa,ttv) # True The idealisation equals the sum of the independent components, $\begin{eqnarray} A * T * T^{\dagger A} &=& \sum_{(R,C) \in T^{-1}} (A * C)^{\mathrm{X}} \\ &=& \sum_{(R,C) \in T^{-1}} A * T * \{R\}^{\mathrm{U}} * (A * C)^{\wedge\mathrm{X}}~\%~V \end{eqnarray}$ ee = histogramEmpty() for (rr,cc) in inv(ttv): ee = add(ee,ind(mul(aa,cc))) tmul(tmul(aa,ttv),idl(ttv,aa)) == ee # True ee = histogramEmpty() for (rr,cc) in inv(ttv): ee = add(ee,ared(mul(mul(tmul(aa,ttv),sunit(rr)),norm(ind(mul(aa,cc)))),vv)) tmul(tmul(aa,ttv),idl(ttv,aa)) == ee # True So each component is independent, $\forall (R,C) \in T^{-1}~(A * T * T^{\dagger A} * C = (A * T * T^{\dagger A} * C)^{\mathrm{X}} = (A * C)^{\mathrm{X}})$ [mul(tmul(tmul(aa,ttv),idl(ttv,aa)),cc) == ind(mul(aa,cc)) for (rr,cc) in inv(ttv)] # [True, True] The idealisation of the unary partition transform,$T_{\mathrm{u}} = \{V^{\mathrm{CS}}\}^{\mathrm{T}}$, is the sized cartesian,$A * T_{\mathrm{u}} * T_{\mathrm{u}}^{\dagger A} = V_z^{\mathrm{C}}$, pptt = partitionsTransformVarPartition def unary(uu,vv): return pptt(systemsSetVarsPartitionUnary(uu,vv)) tmul(tmul(aa,unary(uu,vv)),idl(unary(uu,vv),aa)) == resize(size(aa),unit(cart(uu,vv))) # True The idealisation of the self partition transform,$T_{\mathrm{s}} = V^{\mathrm{CS}\{\}\mathrm{T}}$, is the histogram,$A * T_{\mathrm{s}} * T_{\mathrm{s}}^{\dagger A} = A$, def self(uu,vv): return pptt(systemsSetVarsPartitionSelf(uu,vv)) tmul(tmul(aa,self(uu,vv)),idl(self(uu,vv),aa)) == aa # True The idealisation independent equals the independent,$(A * T * T^{\dagger A})^{\mathrm{X}} = A^{\mathrm{X}}$, ind(tmul(tmul(aa,ttv),idl(ttv,aa))) == ind(aa) # True ind(tmul(tmul(regcart(3,2),tt1),idl(tt1,regcart(3,2)))) == ind(regcart(3,2)) # True ind(tmul(tmul(regdiag(3,2),tt1),idl(tt1,regdiag(3,2)))) == ind(regdiag(3,2)) # True The idealisation formal equals the formal,$(A * T * T^{\dagger A})^{\mathrm{X}} * T = A^{\mathrm{X}} * T$, tmul(ind(tmul(tmul(aa,ttv),idl(ttv,aa))),ttv) == tmul(ind(aa),ttv) # True tmul(ind(tmul(tmul(regcart(3,2),tt1),idl(tt1,regcart(3,2)))),tt1) == tmul(ind(regcart(3,2)),tt1) # True tmul(ind(tmul(tmul(regdiag(3,2),tt1),idl(tt1,regdiag(3,2)))),tt1) == tmul(ind(regdiag(3,2)),tt1) # True Transforms as models The sense in which a transform is a simple model can be seen by considering queries on a sample histogram. Let histogram$A$have a set of variables$V = \mathrm{vars}(A)$which is partitioned into query variables$K \subset V$and label variables$V \setminus K$. Let$T = (X,W)$be a one functional transform having underlying variables equal to the query variables,$\mathrm{und}(T) = K$. Given a query state$Q \in K^{\mathrm{CS}}$that may be ineffective in the sample,$Q \notin (A\%K)^{\mathrm{FS}}$, but is effective in the sample derived,$R \in (A * T)^{\mathrm{FS}}$where$\{R\} = (\{Q\}^{\mathrm{U}} * T)^{\mathrm{FS}}$, the probability histogram for the label is $\begin{eqnarray} (\{Q\}^{\mathrm{U}} * T * (\hat{A} * X,V))^{\wedge}~\%~(V \setminus K) &\in& \mathcal{A} \cap \mathcal{P} \end{eqnarray}$ where the sample converse transform is$(\hat{A} * X,V)$. This can be expressed more simply in terms of the actual converse, $\begin{eqnarray} \{Q\}^{\mathrm{U}} * T * T^{\odot A}~\%~(V \setminus K) &\in& \mathcal{A} \cap \mathcal{P} \end{eqnarray}$ The query of the sample via model can also be written without the transforms,$(\{Q\}^{\mathrm{U}} * X~\%~W * X * A)^{\wedge}~\%~(V \setminus K). In the deck of cards example, the model of the colours of the suits does not tell us anything about the rank given the suit in the case where the histogram is the entire deck, qq = unit(sset([llss([(suit,clubs)])])) vk = sset([rank]) rpln(aall(norm(ared(mul(mul(tmul(qq,tt),xx),aa),vk)))) # ({(rank, A)}, 1 % 13) # ({(rank, J)}, 1 % 13) # ({(rank, K)}, 1 % 13) # ({(rank, Q)}, 1 % 13) # ({(rank, 2)}, 1 % 13) # ({(rank, 3)}, 1 % 13) # ({(rank, 4)}, 1 % 13) # ({(rank, 5)}, 1 % 13) # ({(rank, 6)}, 1 % 13) # ({(rank, 7)}, 1 % 13) # ({(rank, 8)}, 1 % 13) # ({(rank, 9)}, 1 % 13) # ({(rank, 10)}, 1 % 13) If, however, we consider a game of cards which has a special deck such that spades and clubs are pip cards and hearts and diamonds are face cards, the suit and the rank are no longer independent, bb = unit(sset( [llss([(suit,s),(rank,r)]) for s in [spades,clubs] for r in [ace] + list(map(ValInt,range(2,10+1)))] + [llss([(suit,s),(rank,r)]) for s in [hearts,diamonds] for r in [jack,queen,king]])) rpln(aall(bb)) # ({(rank, A), (suit, clubs)}, 1 % 1) # ({(rank, A), (suit, spades)}, 1 % 1) # ({(rank, J), (suit, diamonds)}, 1 % 1) # ({(rank, J), (suit, hearts)}, 1 % 1) # ({(rank, K), (suit, diamonds)}, 1 % 1) # ({(rank, K), (suit, hearts)}, 1 % 1) # ({(rank, Q), (suit, diamonds)}, 1 % 1) # ({(rank, Q), (suit, hearts)}, 1 % 1) # ({(rank, 2), (suit, clubs)}, 1 % 1) # ({(rank, 2), (suit, spades)}, 1 % 1) # ({(rank, 3), (suit, clubs)}, 1 % 1) # ({(rank, 3), (suit, spades)}, 1 % 1) # ({(rank, 4), (suit, clubs)}, 1 % 1) # ({(rank, 4), (suit, spades)}, 1 % 1) # ({(rank, 5), (suit, clubs)}, 1 % 1) # ({(rank, 5), (suit, spades)}, 1 % 1) # ({(rank, 6), (suit, clubs)}, 1 % 1) # ({(rank, 6), (suit, spades)}, 1 % 1) # ({(rank, 7), (suit, clubs)}, 1 % 1) # ({(rank, 7), (suit, spades)}, 1 % 1) # ({(rank, 8), (suit, clubs)}, 1 % 1) # ({(rank, 8), (suit, spades)}, 1 % 1) # ({(rank, 9), (suit, clubs)}, 1 % 1) # ({(rank, 9), (suit, spades)}, 1 % 1) # ({(rank, 10), (suit, clubs)}, 1 % 1) # ({(rank, 10), (suit, spades)}, 1 % 1) algn(bb) # 4.502579806192693 Now our model aligns the suit to the rank via colour, so a query on clubs is always a pip card, rpln(aall(norm(ared(mul(mul(tmul(qq,tt),xx),bb),vk)))) # ({(rank, A)}, 1 % 10) # ({(rank, 2)}, 1 % 10) # ({(rank, 3)}, 1 % 10) # ({(rank, 4)}, 1 % 10) # ({(rank, 5)}, 1 % 10) # ({(rank, 6)}, 1 % 10) # ({(rank, 7)}, 1 % 10) # ({(rank, 8)}, 1 % 10) # ({(rank, 9)}, 1 % 10) # ({(rank, 10)}, 1 % 10) A query on hearts is always a face card, qq = unit(sset([llss([(suit,hearts)])])) rpln(aall(norm(ared(mul(mul(tmul(qq,tt),xx),bb),vk)))) # ({(rank, J)}, 1 % 3) # ({(rank, K)}, 1 % 3) # ({(rank, Q)}, 1 % 3) Of course, in this example the model is not very interesting because we can simply query the sample directly, rpln(aall(norm(ared(mul(qq,bb),vk)))) # ({(rank, J)}, 1 % 3) # ({(rank, K)}, 1 % 3) # ({(rank, Q)}, 1 % 3) Usually models are more useful when the size of the sample is much smaller than the underlying volume,z \ll v$, where$z = \mathrm{size}(A)$and$v = |V^{\mathrm{C}}|$, but not the derived volume,$z \ge w$, where$w = |W^{\mathrm{C}}|$. In these cases the sample itself does not contain the query,$\{Q\}^{\mathrm{U}} * A = \emptyset$, but the sample derived does contain the query derived,$\{R\}^{\mathrm{U}} * (A * T) \neq \emptyset$, and so the resultant labels are those of the corresponding effective component,$A * C~\%~(V \setminus K)$, where$(R,C) \in T^{-1}$. Example - a weather forecast Some of the concepts above regarding transforms can be demonstrated with the sample of some weather measurements created in States, histories and histograms, def lluu(ll): return listsSystem([(v,sset(ww)) for (v,ww) in ll]) def llhh(vv,ev): return listsHistory([(IdInt(i), llss(zip(vv,ll))) for (i,ll) in ev]) def red(aa,ll): return setVarsHistogramsReduce(sset(ll),aa) def ssplit(ll,aa): return setVarsSetStatesSplit(sset(ll),states(aa)) [pressure,cloud,wind,rain] = map(VarStr,["pressure","cloud","wind","rain"]) [low,medium,high,none,light,heavy,strong] = map(ValStr,["low","medium","high","none","light","heavy","strong"]) uu = lluu([ (pressure, [low,medium,high]), (cloud, [none,light,heavy]), (wind, [none,light,strong]), (rain, [none,light,heavy])]) vv = uvars(uu) hh = llhh([pressure,cloud,wind,rain],[ (1,[high,none,none,none]), (2,[medium,light,none,light]), (3,[high,none,light,none]), (4,[low,heavy,strong,heavy]), (5,[low,none,light,light]), (6,[medium,none,light,light]), (7,[low,heavy,light,heavy]), (8,[high,none,light,none]), (9,[medium,light,strong,heavy]), (10,[medium,light,light,light]), (11,[high,light,light,heavy]), (12,[medium,none,none,none]), (13,[medium,light,none,none]), (14,[high,light,strong,light]), (15,[medium,none,light,light]), (16,[low,heavy,strong,heavy]), (17,[low,heavy,light,heavy]), (18,[high,none,none,none]), (19,[low,light,none,light]), (20,[high,none,none,none])]) aa = hhaa(hh) uu # {(cloud, {heavy, light, none}), (pressure, {high, low, medium}), (rain, {heavy, light, none}), (wind, {light, none, strong})} vv # {cloud, pressure, rain, wind} rpln(aall(aa)) # ({(cloud, heavy), (pressure, low), (rain, heavy), (wind, light)}, 2 % 1) # ({(cloud, heavy), (pressure, low), (rain, heavy), (wind, strong)}, 2 % 1) # ({(cloud, light), (pressure, high), (rain, heavy), (wind, light)}, 1 % 1) # ({(cloud, light), (pressure, high), (rain, light), (wind, strong)}, 1 % 1) # ({(cloud, light), (pressure, low), (rain, light), (wind, none)}, 1 % 1) # ({(cloud, light), (pressure, medium), (rain, heavy), (wind, strong)}, 1 % 1) # ({(cloud, light), (pressure, medium), (rain, light), (wind, light)}, 1 % 1) # ({(cloud, light), (pressure, medium), (rain, light), (wind, none)}, 1 % 1) # ({(cloud, light), (pressure, medium), (rain, none), (wind, none)}, 1 % 1) # ({(cloud, none), (pressure, high), (rain, none), (wind, light)}, 2 % 1) # ({(cloud, none), (pressure, high), (rain, none), (wind, none)}, 3 % 1) # ({(cloud, none), (pressure, low), (rain, light), (wind, light)}, 1 % 1) # ({(cloud, none), (pressure, medium), (rain, light), (wind, light)}, 2 % 1) # ({(cloud, none), (pressure, medium), (rain, none), (wind, none)}, 1 % 1) size(aa) # 20 % 1 Consider the case where we know the pressure, cloud and wind, and wish to predict the rain. That is, the singleton set of rain is set of the label variables,$V \setminus K$, and pressure, cloud and wind together form the query variables,$K. In Entropy and alignment the alignments of various reductions were calculated, algn(resize(20,regdiag(3,4))) # 31.485060233928998 algn(aa) # 11.85085227502473 algn(red(aa,[pressure,rain])) # 4.278766678519384 algn(red(aa,[cloud,rain])) # 6.4150379630063465 algn(red(aa,[wind,rain])) # 3.930131313218345 algn(red(aa,[cloud,wind,rain])) # 8.935048311238008 We can see that pressure and rain are aligned but not causal, algn(red(aa,[pressure,rain])) # 4.278766678519384 rpln(ssplit([pressure],red(aa,[pressure,rain]))) # ({(pressure, high)}, {(rain, heavy)}) # ({(pressure, high)}, {(rain, light)}) # ({(pressure, high)}, {(rain, none)}) # ({(pressure, low)}, {(rain, heavy)}) # ({(pressure, low)}, {(rain, light)}) # ({(pressure, medium)}, {(rain, heavy)}) # ({(pressure, medium)}, {(rain, light)}) # ({(pressure, medium)}, {(rain, none)}) histogramsIsCausal(red(aa,[pressure,rain])) # False cloud and rain are more aligned, algn(red(aa,[cloud,rain])) # 6.4150379630063465 rpln(ssplit([cloud],red(aa,[cloud,rain]))) # ({(cloud, heavy)}, {(rain, heavy)}) # ({(cloud, light)}, {(rain, heavy)}) # ({(cloud, light)}, {(rain, light)}) # ({(cloud, light)}, {(rain, none)}) # ({(cloud, none)}, {(rain, light)}) # ({(cloud, none)}, {(rain, none)}) but cloud, wind and rain are still more aligned, algn(red(aa,[cloud,wind,rain])) # 8.935048311238008 rpln(ssplit([cloud,wind],red(aa,[cloud,wind,rain]))) # ({(cloud, heavy), (wind, light)}, {(rain, heavy)}) # ({(cloud, heavy), (wind, strong)}, {(rain, heavy)}) # ({(cloud, light), (wind, light)}, {(rain, heavy)}) # ({(cloud, light), (wind, light)}, {(rain, light)}) # ({(cloud, light), (wind, none)}, {(rain, light)}) # ({(cloud, light), (wind, none)}, {(rain, none)}) # ({(cloud, light), (wind, strong)}, {(rain, heavy)}) # ({(cloud, light), (wind, strong)}, {(rain, light)}) # ({(cloud, none), (wind, light)}, {(rain, light)}) # ({(cloud, none), (wind, light)}, {(rain, none)}) # ({(cloud, none), (wind, none)}, {(rain, none)}) histogramsIsCausal(red(aa,[cloud,wind,rain])) # False So consider a simple model consisting of a one functional transformT \in \mathcal{T}_{U,\mathrm{f},1}with underlying variables cloud and wind and a derived variable of cloud_and_wind with this relation - cloud wind cloud and wind none none none none light light none strong light light none light light light light light strong light heavy none strong heavy light strong heavy strong strong cloud_and_wind = VarStr("cloud_and_wind") def lltt(kk,ww,qq): return trans(unit(sset([llss(zip(kk + ww,ll)) for ll in qq])),sset(ww)) tt = lltt([cloud,wind],[cloud_and_wind],[ [none, none, none], [none, light, light], [none, strong, light], [light, none, light], [light, light, light], [light, strong, light], [heavy, none, strong], [heavy, light, strong], [heavy, strong, strong]]) rpln(aall(ttaa(tt))) # ({(cloud, heavy), (cloud_and_wind, strong), (wind, light)}, 1 % 1) # ({(cloud, heavy), (cloud_and_wind, strong), (wind, none)}, 1 % 1) # ({(cloud, heavy), (cloud_and_wind, strong), (wind, strong)}, 1 % 1) # ({(cloud, light), (cloud_and_wind, light), (wind, light)}, 1 % 1) # ({(cloud, light), (cloud_and_wind, light), (wind, none)}, 1 % 1) # ({(cloud, light), (cloud_and_wind, light), (wind, strong)}, 1 % 1) # ({(cloud, none), (cloud_and_wind, light), (wind, light)}, 1 % 1) # ({(cloud, none), (cloud_and_wind, light), (wind, strong)}, 1 % 1) # ({(cloud, none), (cloud_and_wind, none), (wind, none)}, 1 % 1) rpln(ssplit([cloud,wind],ttaa(tt))) # ({(cloud, heavy), (wind, light)}, {(cloud_and_wind, strong)}) # ({(cloud, heavy), (wind, none)}, {(cloud_and_wind, strong)}) # ({(cloud, heavy), (wind, strong)}, {(cloud_and_wind, strong)}) # ({(cloud, light), (wind, light)}, {(cloud_and_wind, light)}) # ({(cloud, light), (wind, none)}, {(cloud_and_wind, light)}) # ({(cloud, light), (wind, strong)}, {(cloud_and_wind, light)}) # ({(cloud, none), (wind, light)}, {(cloud_and_wind, light)}) # ({(cloud, none), (wind, none)}, {(cloud_and_wind, none)}) # ({(cloud, none), (wind, strong)}, {(cloud_and_wind, light)}) und(tt) # {cloud, wind} der(tt) # {cloud_and_wind} histogramsIsCausal(ttaa(tt)) # True rpln(aall(tmul(aa,tt))) # ({(cloud_and_wind, light)}, 12 % 1) # ({(cloud_and_wind, none)}, 4 % 1) # ({(cloud_and_wind, strong)}, 4 % 1) Now we calculate the alignment between the derived variable, cloud_and_wind, and the rain, algn(red(mul(aa,ttaa(tt)),[cloud_and_wind,rain])) # 6.743705969634357 rpln(ssplit([cloud_and_wind],red(mul(aa,ttaa(tt)),[cloud_and_wind,rain]))) # ({(cloud_and_wind, light)}, {(rain, heavy)}) # ({(cloud_and_wind, light)}, {(rain, light)}) # ({(cloud_and_wind, light)}, {(rain, none)}) # ({(cloud_and_wind, none)}, {(rain, none)}) # ({(cloud_and_wind, strong)}, {(rain, heavy)}) So cloud_and_wind is more aligned with rain than any of cloud, wind or pressure. Now consider a query which is ineffective in the sample,Q \notin (A\%K)^{\mathrm{FS}}$, but is effective in the sample derived,$R \in (A * T)^{\mathrm{FS}}$where$\{R\} = (\{Q\}^{\mathrm{U}} * T)^{\mathrm{FS}}$, qq = hhaa(llhh([pressure,cloud,wind],[(1,[medium,heavy,light])])) leq(qq,eff(red(aa,[pressure,cloud,wind]))) # False rpln(aall(tmul(qq,tt))) # ({(cloud_and_wind, strong)}, 1 % 1) rr = hhaa(llhh([cloud_and_wind],[(1,[strong])])) leq(rr,eff(tmul(aa,tt))) # True The forecast for rain is heavy, def aarr(aa): return [(ss,float(q)) for (ss,q) in aall(aa)] def query(qq,tt,aa,ll): return norm(red(mul(mul(tmul(qq,tt),ttaa(tt)),aa),ll)) rpln(aarr(query(qq,tt,aa,[rain]))) # ({(rain, heavy)}, 1.0) We can calculate the resultant label histogram for all$3^3 = 27\$ queries,

kk = sset([pressure,cloud,wind])

rpln([(ss, query(unit(sset([ss])),tt,aa,[rain])) for ss in cart(uu,kk)])
# ({(cloud, heavy), (pressure, high), (wind, light)}, {({(rain, heavy)}, 1 % 1)})
# ({(cloud, heavy), (pressure, high), (wind, none)}, {({(rain, heavy)}, 1 % 1)})
# ({(cloud, heavy), (pressure, high), (wind, strong)}, {({(rain, heavy)}, 1 % 1)})
# ({(cloud, heavy), (pressure, low), (wind, light)}, {({(rain, heavy)}, 1 % 1)})
# ({(cloud, heavy), (pressure, low), (wind, none)}, {({(rain, heavy)}, 1 % 1)})
# ({(cloud, heavy), (pressure, low), (wind, strong)}, {({(rain, heavy)}, 1 % 1)})
# ({(cloud, heavy), (pressure, medium), (wind, light)}, {({(rain, heavy)}, 1 % 1)})
# ({(cloud, heavy), (pressure, medium), (wind, none)}, {({(rain, heavy)}, 1 % 1)})
# ({(cloud, heavy), (pressure, medium), (wind, strong)}, {({(rain, heavy)}, 1 % 1)})
# ({(cloud, light), (pressure, high), (wind, light)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})
# ({(cloud, light), (pressure, high), (wind, none)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})
# ({(cloud, light), (pressure, high), (wind, strong)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})
# ({(cloud, light), (pressure, low), (wind, light)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})
# ({(cloud, light), (pressure, low), (wind, none)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})
# ({(cloud, light), (pressure, low), (wind, strong)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})
# ({(cloud, light), (pressure, medium), (wind, light)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})
# ({(cloud, light), (pressure, medium), (wind, none)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})
# ({(cloud, light), (pressure, medium), (wind, strong)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})
# ({(cloud, none), (pressure, high), (wind, light)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})
# ({(cloud, none), (pressure, high), (wind, none)}, {({(rain, none)}, 1 % 1)})
# ({(cloud, none), (pressure, high), (wind, strong)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})
# ({(cloud, none), (pressure, low), (wind, light)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})
# ({(cloud, none), (pressure, low), (wind, none)}, {({(rain, none)}, 1 % 1)})
# ({(cloud, none), (pressure, low), (wind, strong)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})
# ({(cloud, none), (pressure, medium), (wind, light)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})
# ({(cloud, none), (pressure, medium), (wind, none)}, {({(rain, none)}, 1 % 1)})
# ({(cloud, none), (pressure, medium), (wind, strong)}, {({(rain, heavy)}, 1 % 6), ({(rain, light)}, 7 % 12), ({(rain, none)}, 1 % 4)})

For some queries the model is ambiguous. For example, when the pressure is low, but there is no cloud and winds are light, the forecast is usually for light rain, but not always,

qq2 = hhaa(llhh([pressure,cloud,wind],[(1,[low,none,light])]))

rpln(aarr(query(qq2,tt,aa,[rain])))
# ({(rain, heavy)}, 0.16666666666666666)
# ({(rain, light)}, 0.5833333333333334)
# ({(rain, none)}, 0.25)

The weather forecast example continues in Transform entropy.

top