Re: Help! How to calculate additive partitions?
- To: mathgroup at smc.vnet.net
- Subject: [mg34589] Re: Help! How to calculate additive partitions?
- From: "Allan Hayes" <hay at haystack.demon.co.uk>
- Date: Wed, 29 May 2002 02:44:44 -0400 (EDT)
- References: <acshg9$kea$1@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
Bobby, Hartmut,
Dear Bobby, Hartmut,
Here is my attempt to get to grips with Inner, by trying to describe its
behaviour and by simulating it with my own code.
I find that Array is the tool to use in understanding Inner, and Transpose.
In the course of working this out I found that I needed an extension of
Array:
Array[fn_, {}, {}, h_]:= fn[]
The evaluation that gave Bobby trouble ( Inner[f,{a},{{}},g] --> {} ) comes
from Array[f,{}] -->{}.
? Description
Dimensions[a]={d1,d2,...,dp}
Dimensions[b]={e1,e2,...,eq}
We have, where (Plus), (p) indcate default values,
Inner[f, a, b, g(Plus), n(p)] =
Array[
g[
f[a[[#1, .., #(n - 1), 1, #(n + 1) .., #(p - 1)]],
b[[1, #p, ..., #p + q - 2]]
],
.
.
f[a[[#1, .., #(n - 1), e1, #(n + 1) .., #(p - 1)]],
b[[e1, #p, ..., #p + q - 2]]
]
] &,
{d1, ..., d(n - 1), d(n + 1), ..., dp, e2, ..., eq},
{1, ..., 1, 1, ..., 1, 1, ..., 1 },
Head[a]
]
? Simulation
You will see that some generalization is possible (for example to more than
two tensor inputs).
General case
innr[f_, a:(h_)[___], b:(h_)[___], g_, n_Integer] /; 1 <= n <= TensorRank[a]
:=
Block[
{ff = f, gg = g, i, res,
ra = TensorRank[a], rb = TensorRank[b],
da = Dimensions[a], db = Dimensions[b]
},
With[
{sa = Sequence @@ Insert[Slot /@ Range[ra - 1], i, n],
sb = Sequence @@ Insert[Slot /@ Range[ra, ra + rb - 2], i, 1],
d = First[db],
dims = Join[Drop[da, {n}], Rest[db]],
origin = Table[1, {ra + rb - 2}]
},
Unprotect[Array]; Array[fn_, {}, {}, h] := fn[];
res =
Block[{Part, ff, gg},
Array[
Evaluate[gg @@ Table[ff[a[[sa]], b[[sb]]], {i, 1, d}]] & ,
dims,
origin,
h
]]];
Array[fn_, {}, {}, h] =. ;
Protect[Array];
res
];
Special cases
innr[f_, a:(h_)[___], b:(h_)[___]] := innr[f, a, b, Plus, TensorRank[a]];
innr[f_, a:(h_)[___], b:(h_)[___], g_] := innr[f, a, b, g, TensorRank[a]];
? Check
innr[f,{a},{{}},g]
{}
Allan
---------------------
Allan Hayes
Mathematica Training and Consulting
Leicester UK
www.haystack.demon.co.uk
hay at haystack.demon.co.uk
Voice: +44 (0)116 271 4198
Fax: +44 (0)870 164 0565
"DrBob" <majort at cox-internet.com> wrote in message
news:acshg9$kea$1 at smc.vnet.net...
> >>consequently
>
> >>In[12]:= Inner[f, {a}, {{}}, g]
> >>Out[12]= {}
>
> >>That kills your algorithm. What do you need instead?
>
> Not so fast. Maybe you're right, but your explanation in terms of
> tensors leaves me blank... as I'm not a tensor calculus expert. Is
> there an explanation that I might understand, here?
>
> OH! I think it just came to me, as if in a vision:
>
> TensorRank[f1[#]] & /@ Range[0, 10]
>
> {2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1}
>
> That is, f1[0] and f1[1] are tensors of rank 2, but all the others have
> rank 1. That's why the method doesn't work for m=1 and m=2! Inner
> treats 2-tensors differently than 1-tensors. (The same in terms of your
> explanation, perhaps, but...) That is, it doesn't treat a 2-tensor as a
> list of 1-tensors.
>
> Huh! I learn something new every day.
>
> However... what's a 2-tensor with a missing element DO?
>
> And why do these lists have different TensorRank at all?
>
> TensorRank[{{{}}, {{}}}]
> TensorRank[{{{}}, {{1}}}]
> TensorRank[{{{1}}, {{1}}}]
>
> 3
> 2
> 3
>
> It looks as if I need to study up.
>
> Bobby
>